feat(planning): grille hebdomadaire complète avec API et filtres
- Connexion API via proxy Angular (résolution CORS, base path /api) - Import CSS ng-zorro global pour les modales et composants - Filtres Camion/Show câblés sur l'affichage de la grille - Camions affichés via TrucksService (linkés au show du même créneau) - Panneau de détails : spectacles + camions du jour sélectionné - Modale de création de spectacle stylisée avec fond et centrage - Positionnement précis des events à la minute dans leur créneau - Auto-scroll vers l'heure courante au chargement - Ligne "maintenant" sur la colonne du jour actuel - Régénération des services OpenAPI (nouveaux noms de types) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@ end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 180
|
||||
max_line_length = 160
|
||||
quote_type = single
|
||||
|
||||
[test/*]
|
||||
|
||||
-200
@@ -1,45 +1,3 @@
|
||||
## **6.15.2**
|
||||
- [Fix] `stringify`: skip null/undefined entries in `arrayFormat: 'comma'` + `encodeValuesOnly` instead of crashing in `encoder`
|
||||
- [Fix] `stringify`: use configured `delimiter` after `charsetSentinel` (#555)
|
||||
- [Fix] `stringify`: apply `formatter` to encoded key under `strictNullHandling` (#554)
|
||||
- [Fix] `stringify`: skip null/undefined filter-array entries instead of crashing in `encoder` (#551)
|
||||
- [Fix] `parse`: handle nested bracket groups and add regression tests (#530)
|
||||
- [readme] fix grammar (#550)
|
||||
- [Dev Deps] update `@ljharb/eslint-config`
|
||||
- [Tests] add regression tests for keys containing percent-encoded bracket text
|
||||
|
||||
## **6.15.1**
|
||||
- [Fix] `parse`: `parameterLimit: Infinity` with `throwOnLimitExceeded: true` silently drops all parameters
|
||||
- [Deps] update `@ljharb/eslint-config`
|
||||
- [Dev Deps] update `@ljharb/eslint-config`, `iconv-lite`
|
||||
- [Tests] increase coverage
|
||||
|
||||
## **6.15.0**
|
||||
- [New] `parse`: add `strictMerge` option to wrap object/primitive conflicts in an array (#425, #122)
|
||||
- [Fix] `duplicates` option should not apply to bracket notation keys (#514)
|
||||
|
||||
## **6.14.2**
|
||||
- [Fix] `parse`: mark overflow objects for indexed notation exceeding `arrayLimit` (#546)
|
||||
- [Fix] `arrayLimit` means max count, not max index, in `combine`/`merge`/`parseArrayValue`
|
||||
- [Fix] `parse`: throw on `arrayLimit` exceeded with indexed notation when `throwOnLimitExceeded` is true (#529)
|
||||
- [Fix] `parse`: enforce `arrayLimit` on `comma`-parsed values
|
||||
- [Fix] `parse`: fix error message to reflect arrayLimit as max index; remove extraneous comments (#545)
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [meta] fix changelog typo (`arrayLength` → `arrayLimit`)
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.14.1**
|
||||
- [Fix] ensure `arrayLimit` applies to `[]` notation as well
|
||||
- [Fix] `parse`: when a custom decoder returns `null` for a key, ignore that key
|
||||
- [Refactor] `parse`: extract key segment splitting helper
|
||||
- [meta] add threat model
|
||||
- [actions] add workflow permissions
|
||||
- [Tests] `stringify`: increase coverage
|
||||
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `npmignore`, `es-value-fixtures`, `for-each`, `object-inspect`
|
||||
|
||||
## **6.14.0**
|
||||
- [New] `parse`: add `throwOnParameterLimitExceeded` option (#517)
|
||||
- [Refactor] `parse`: use `utils.combine` more
|
||||
@@ -50,17 +8,6 @@
|
||||
- [Dev Deps] update `es-value-fixtures`, `has-bigints`, `has-proto`, `has-symbols`
|
||||
- [Tests] increase coverage
|
||||
|
||||
## **6.13.3**
|
||||
[Fix] fix regressions from robustness refactor
|
||||
[actions] update reusable workflows
|
||||
|
||||
## **6.13.2**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.13.1**
|
||||
- [Fix] `stringify`: avoid a crash when a `filter` key is `null`
|
||||
- [Fix] `utils.merge`: functions should not be stringified into keys
|
||||
@@ -77,17 +24,6 @@
|
||||
- [New] `parse`: add `strictDepth` option (#511)
|
||||
- [Tests] use `npm audit` instead of `aud`
|
||||
|
||||
## **6.12.5**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.12.4**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.12.3**
|
||||
- [Fix] `parse`: properly account for `strictNullHandling` when `allowEmptyArrays`
|
||||
- [meta] fix changelog indentation
|
||||
@@ -125,17 +61,6 @@
|
||||
- [Dev Deps] pin `glob`, since v10.3.8+ requires a broken `jackspeak`
|
||||
- [Dev Deps] pin `jackspeak` since 2.1.2+ depends on npm aliases, which kill the install process in npm < 6
|
||||
|
||||
## **6.11.4**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.11.3**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.11.2**
|
||||
- [Fix] `parse`: Fix parsing when the global Object prototype is frozen (#473)
|
||||
- [Tests] add passing test cases with empty keys (#473)
|
||||
@@ -153,17 +78,6 @@
|
||||
- [New] [Fix] `stringify`: revert 0e903c0; add `commaRoundTrip` option (#442)
|
||||
- [readme] fix version badge
|
||||
|
||||
## **6.10.7**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.10.6**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.10.5**
|
||||
- [Fix] `stringify`: with `arrayFormat: comma`, properly include an explicit `[]` on a single-item array (#434)
|
||||
|
||||
@@ -201,18 +115,6 @@
|
||||
- [Tests] use `ljharb/actions/node/install` instead of `ljharb/actions/node/run`
|
||||
- [Tests] Revert "[meta] ignore eclint transitive audit warning"
|
||||
|
||||
## **6.9.9**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.9.8**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.9.7**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
|
||||
@@ -273,18 +175,6 @@
|
||||
- [Tests] up to `node` `v12.10`, `v11.15`, `v10.16`, `v8.16`
|
||||
- [Tests] `Buffer.from` in node v5.0-v5.9 and v4.0-v4.4 requires a TypedArray
|
||||
|
||||
## **6.8.5**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.8.4**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.8.3**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
||||
@@ -329,18 +219,6 @@
|
||||
- [meta] add FUNDING.yml
|
||||
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
|
||||
|
||||
## **6.7.5**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.7.4**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.7.3**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
|
||||
@@ -392,18 +270,6 @@
|
||||
- [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10
|
||||
- [Tests] temporarily allow coverage to fail
|
||||
|
||||
## **6.6.3**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.6.2**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.6.1**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
|
||||
@@ -446,18 +312,6 @@
|
||||
- [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`, `iconv-lite`, `safe-publish-latest`, `tape`
|
||||
- [Tests] up to `node` `v10.10`, `v9.11`, `v8.12`, `v6.14`, `v4.9`; pin included builds to LTS
|
||||
|
||||
## **6.5.5**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.5.4**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.5.3**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
||||
@@ -508,18 +362,6 @@
|
||||
- [Tests] up to `node` `v8.1`, `v7.10`, `v6.11`; npm v4.6 breaks on node < v1; npm v5+ breaks on node < v4
|
||||
- [Tests] add `editorconfig-tools`
|
||||
|
||||
## **6.4.3**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.4.2**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] replace runkit CI badge with shields.io check-runs badge
|
||||
- [readme] replace travis CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.4.1**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
|
||||
@@ -550,17 +392,6 @@
|
||||
- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
|
||||
- [eslint] reduce warnings
|
||||
|
||||
## **6.3.5**
|
||||
- [Fix] fix regressions from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.3.4**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] replace travis CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.3.3**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
|
||||
@@ -614,17 +445,6 @@
|
||||
- [Tests] skip Object.create tests when null objects are not available
|
||||
- [Tests] Turn on eslint for test files (#175)
|
||||
|
||||
## **6.2.6**
|
||||
- [Fix] fix regression from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.2.5**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] replace travis CI badge with shields.io check-runs badge
|
||||
- [actions] fix rebase workflow permissions
|
||||
|
||||
## **6.2.4**
|
||||
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
||||
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
|
||||
@@ -663,16 +483,6 @@
|
||||
- [New] add "encoder" and "decoder" options, for custom param encoding/decoding (#160)
|
||||
- [Fix] fix compacting of nested sparse arrays (#150)
|
||||
|
||||
## **6.1.4**
|
||||
- [Fix] fix regression from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.1.3**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] replace travis CI badge with shields.io check-runs badge
|
||||
|
||||
## **6.1.2**
|
||||
- [Fix] follow `allowPrototypes` option during merge (#201, #200)
|
||||
- [Fix] chmod a-x
|
||||
@@ -687,16 +497,6 @@
|
||||
- [Fix] "sort" option should work at a depth of 3 or more (#151)
|
||||
- [Fix] Restore `dist` directory; will be removed in v7 (#148)
|
||||
|
||||
## **6.0.6**
|
||||
- [Fix] fix regression from robustness refactor
|
||||
- [meta] add `npmignore` to autogenerate an npmignore file
|
||||
- [actions] update reusable workflows
|
||||
|
||||
## **6.0.5**
|
||||
- [Robustness] avoid `.push`, use `void`
|
||||
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
||||
- [readme] replace travis CI badge with shields.io check-runs badge
|
||||
|
||||
## **6.0.4**
|
||||
- [Fix] follow `allowPrototypes` option during merge (#201, #200)
|
||||
- [Fix] chmod a-x
|
||||
|
||||
+5
-30
@@ -183,7 +183,7 @@ var withDots = qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { decod
|
||||
assert.deepEqual(withDots, { 'name.obj': { first: 'John', last: 'Doe' }});
|
||||
```
|
||||
|
||||
Option `allowEmptyArrays` can be used to allow empty array values in an object
|
||||
Option `allowEmptyArrays` can be used to allowing empty array values in object
|
||||
```javascript
|
||||
var withEmptyArrays = qs.parse('foo[]&bar=baz', { allowEmptyArrays: true });
|
||||
assert.deepEqual(withEmptyArrays, { foo: [], bar: 'baz' });
|
||||
@@ -197,11 +197,6 @@ assert.deepEqual(qs.parse('foo=bar&foo=baz', { duplicates: 'first' }), { foo: 'b
|
||||
assert.deepEqual(qs.parse('foo=bar&foo=baz', { duplicates: 'last' }), { foo: 'baz' });
|
||||
```
|
||||
|
||||
Note that keys with bracket notation (`[]`) always combine into arrays, regardless of the `duplicates` setting:
|
||||
```javascript
|
||||
assert.deepEqual(qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'last' }), { a: '2', b: ['1', '2'] });
|
||||
```
|
||||
|
||||
If you have to deal with legacy browsers or services, there's also support for decoding percent-encoded octets as iso-8859-1:
|
||||
|
||||
```javascript
|
||||
@@ -287,8 +282,8 @@ var withIndexedEmptyString = qs.parse('a[0]=b&a[1]=&a[2]=c');
|
||||
assert.deepEqual(withIndexedEmptyString, { a: ['b', '', 'c'] });
|
||||
```
|
||||
|
||||
**qs** will also limit arrays to a maximum of `20` elements.
|
||||
Any array members with an index of `20` or greater will instead be converted to an object with the index as the key.
|
||||
**qs** will also limit specifying indices in an array to a maximum index of `20`.
|
||||
Any array members with an index of greater than `20` will instead be converted to an object with the index as the key.
|
||||
This is needed to handle cases when someone sent, for example, `a[999999999]` and it will take significant time to iterate over this huge array.
|
||||
|
||||
```javascript
|
||||
@@ -315,8 +310,7 @@ try {
|
||||
|
||||
When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `arrayLimit` and if the limit is exceeded, the array will instead be converted to an object with the index as the key
|
||||
|
||||
To prevent array syntax (`a[]`, `a[0]`) from being parsed as arrays, set `parseArrays` to `false`.
|
||||
Note that duplicate keys (e.g. `a=b&a=c`) may still produce arrays when `duplicates` is `'combine'` (the default).
|
||||
To disable array parsing entirely, set `parseArrays` to `false`.
|
||||
|
||||
```javascript
|
||||
var noParsingArrays = qs.parse('a[]=b', { parseArrays: false });
|
||||
@@ -330,19 +324,6 @@ var mixedNotation = qs.parse('a[0]=b&a[b]=c');
|
||||
assert.deepEqual(mixedNotation, { a: { '0': 'b', b: 'c' } });
|
||||
```
|
||||
|
||||
When a key appears as both a plain value and an object, **qs** will by default wrap the conflicting values in an array (`strictMerge` defaults to `true`):
|
||||
|
||||
```javascript
|
||||
assert.deepEqual(qs.parse('a[b]=c&a=d'), { a: [{ b: 'c' }, 'd'] });
|
||||
assert.deepEqual(qs.parse('a=d&a[b]=c'), { a: ['d', { b: 'c' }] });
|
||||
```
|
||||
|
||||
To restore the legacy behavior (where the primitive is used as a key with value `true`), set `strictMerge` to `false`:
|
||||
|
||||
```javascript
|
||||
assert.deepEqual(qs.parse('a[b]=c&a=d', { strictMerge: false }), { a: { b: 'c', d: true } });
|
||||
```
|
||||
|
||||
You can also create arrays of objects:
|
||||
|
||||
```javascript
|
||||
@@ -531,12 +512,6 @@ The query string may optionally be prepended with a question mark:
|
||||
assert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d');
|
||||
```
|
||||
|
||||
Note that when the output is an empty string, the prefix will not be added:
|
||||
|
||||
```javascript
|
||||
assert.equal(qs.stringify({}, { addQueryPrefix: true }), '');
|
||||
```
|
||||
|
||||
The delimiter may be overridden with stringify as well:
|
||||
|
||||
```javascript
|
||||
@@ -748,7 +723,7 @@ Save time, reduce risk, and improve code health, while paying the maintainers of
|
||||
[downloads-url]: https://npm-stat.com/charts.html?package=qs
|
||||
[codecov-image]: https://codecov.io/gh/ljharb/qs/branch/main/graphs/badge.svg
|
||||
[codecov-url]: https://app.codecov.io/gh/ljharb/qs/
|
||||
[actions-image]: https://img.shields.io/github/check-runs/ljharb/qs/main
|
||||
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/qs
|
||||
[actions-url]: https://github.com/ljharb/qs/actions
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
+21
-21
File diff suppressed because one or more lines are too long
+59
-134
@@ -25,7 +25,6 @@ var defaults = {
|
||||
parseArrays: true,
|
||||
plainObjects: false,
|
||||
strictDepth: false,
|
||||
strictMerge: true,
|
||||
strictNullHandling: false,
|
||||
throwOnLimitExceeded: false
|
||||
};
|
||||
@@ -64,13 +63,13 @@ var parseValues = function parseQueryStringValues(str, options) {
|
||||
var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
|
||||
cleanStr = cleanStr.replace(/%5B/gi, '[').replace(/%5D/gi, ']');
|
||||
|
||||
var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;
|
||||
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
|
||||
var parts = cleanStr.split(
|
||||
options.delimiter,
|
||||
options.throwOnLimitExceeded && typeof limit !== 'undefined' ? limit + 1 : limit
|
||||
options.throwOnLimitExceeded ? limit + 1 : limit
|
||||
);
|
||||
|
||||
if (options.throwOnLimitExceeded && typeof limit !== 'undefined' && parts.length > limit) {
|
||||
if (options.throwOnLimitExceeded && parts.length > limit) {
|
||||
throw new RangeError('Parameter limit exceeded. Only ' + limit + ' parameter' + (limit === 1 ? '' : 's') + ' allowed.');
|
||||
}
|
||||
|
||||
@@ -109,18 +108,16 @@ var parseValues = function parseQueryStringValues(str, options) {
|
||||
} else {
|
||||
key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
|
||||
|
||||
if (key !== null) {
|
||||
val = utils.maybeMap(
|
||||
parseArrayValue(
|
||||
part.slice(pos + 1),
|
||||
options,
|
||||
isArray(obj[key]) ? obj[key].length : 0
|
||||
),
|
||||
function (encodedVal) {
|
||||
return options.decoder(encodedVal, defaults.decoder, charset, 'value');
|
||||
}
|
||||
);
|
||||
}
|
||||
val = utils.maybeMap(
|
||||
parseArrayValue(
|
||||
part.slice(pos + 1),
|
||||
options,
|
||||
isArray(obj[key]) ? obj[key].length : 0
|
||||
),
|
||||
function (encodedVal) {
|
||||
return options.decoder(encodedVal, defaults.decoder, charset, 'value');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
|
||||
@@ -131,25 +128,11 @@ var parseValues = function parseQueryStringValues(str, options) {
|
||||
val = isArray(val) ? [val] : val;
|
||||
}
|
||||
|
||||
if (options.comma && isArray(val) && val.length > options.arrayLimit) {
|
||||
if (options.throwOnLimitExceeded) {
|
||||
throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
|
||||
}
|
||||
val = utils.combine([], val, options.arrayLimit, options.plainObjects);
|
||||
}
|
||||
|
||||
if (key !== null) {
|
||||
var existing = has.call(obj, key);
|
||||
if (existing && (options.duplicates === 'combine' || part.indexOf('[]=') > -1)) {
|
||||
obj[key] = utils.combine(
|
||||
obj[key],
|
||||
val,
|
||||
options.arrayLimit,
|
||||
options.plainObjects
|
||||
);
|
||||
} else if (!existing || options.duplicates === 'last') {
|
||||
obj[key] = val;
|
||||
}
|
||||
var existing = has.call(obj, key);
|
||||
if (existing && options.duplicates === 'combine') {
|
||||
obj[key] = utils.combine(obj[key], val);
|
||||
} else if (!existing || options.duplicates === 'last') {
|
||||
obj[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,39 +153,25 @@ var parseObject = function (chain, val, options, valuesParsed) {
|
||||
var root = chain[i];
|
||||
|
||||
if (root === '[]' && options.parseArrays) {
|
||||
if (utils.isOverflow(leaf)) {
|
||||
// leaf is already an overflow object, preserve it
|
||||
obj = leaf;
|
||||
} else {
|
||||
obj = options.allowEmptyArrays && (leaf === '' || (options.strictNullHandling && leaf === null))
|
||||
? []
|
||||
: utils.combine(
|
||||
[],
|
||||
leaf,
|
||||
options.arrayLimit,
|
||||
options.plainObjects
|
||||
);
|
||||
}
|
||||
obj = options.allowEmptyArrays && (leaf === '' || (options.strictNullHandling && leaf === null))
|
||||
? []
|
||||
: utils.combine([], leaf);
|
||||
} else {
|
||||
obj = options.plainObjects ? { __proto__: null } : {};
|
||||
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
|
||||
var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, '.') : cleanRoot;
|
||||
var index = parseInt(decodedRoot, 10);
|
||||
var isValidArrayIndex = !isNaN(index)
|
||||
if (!options.parseArrays && decodedRoot === '') {
|
||||
obj = { 0: leaf };
|
||||
} else if (
|
||||
!isNaN(index)
|
||||
&& root !== decodedRoot
|
||||
&& String(index) === decodedRoot
|
||||
&& index >= 0
|
||||
&& options.parseArrays;
|
||||
if (!options.parseArrays && decodedRoot === '') {
|
||||
obj = { 0: leaf };
|
||||
} else if (isValidArrayIndex && index < options.arrayLimit) {
|
||||
&& (options.parseArrays && index <= options.arrayLimit)
|
||||
) {
|
||||
obj = [];
|
||||
obj[index] = leaf;
|
||||
} else if (isValidArrayIndex && options.throwOnLimitExceeded) {
|
||||
throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
|
||||
} else if (isValidArrayIndex) {
|
||||
obj[index] = leaf;
|
||||
utils.markOverflow(obj, index);
|
||||
} else if (decodedRoot !== '__proto__') {
|
||||
obj[decodedRoot] = leaf;
|
||||
}
|
||||
@@ -214,101 +183,58 @@ var parseObject = function (chain, val, options, valuesParsed) {
|
||||
return leaf;
|
||||
};
|
||||
|
||||
// Split a key like "a[b][c[]]" into ['a', '[b]', '[c[]]'] while preserving
|
||||
// qs parse semantics for depth/prototype guards.
|
||||
var splitKeyIntoSegments = function splitKeyIntoSegments(originalKey, options) {
|
||||
var key = options.allowDots ? originalKey.replace(/\.([^.[]+)/g, '[$1]') : originalKey;
|
||||
|
||||
// depth <= 0 keeps the whole key as one segment
|
||||
if (options.depth <= 0) {
|
||||
if (!options.plainObjects && has.call(Object.prototype, key)) {
|
||||
if (!options.allowPrototypes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return [key];
|
||||
var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
|
||||
if (!givenKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
var segments = [];
|
||||
// Transform dot notation to bracket notation
|
||||
var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
|
||||
|
||||
// parent before the first '[' (may be empty if key starts with '[')
|
||||
var first = key.indexOf('[');
|
||||
var parent = first >= 0 ? key.slice(0, first) : key;
|
||||
// The regex chunks
|
||||
|
||||
var brackets = /(\[[^[\]]*])/;
|
||||
var child = /(\[[^[\]]*])/g;
|
||||
|
||||
// Get the parent
|
||||
|
||||
var segment = options.depth > 0 && brackets.exec(key);
|
||||
var parent = segment ? key.slice(0, segment.index) : key;
|
||||
|
||||
// Stash the parent if it exists
|
||||
|
||||
var keys = [];
|
||||
if (parent) {
|
||||
// If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
|
||||
if (!options.plainObjects && has.call(Object.prototype, parent)) {
|
||||
if (!options.allowPrototypes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
segments[segments.length] = parent;
|
||||
keys.push(parent);
|
||||
}
|
||||
|
||||
var n = key.length;
|
||||
var open = first;
|
||||
var collected = 0;
|
||||
// Loop through children appending to the array until we hit depth
|
||||
|
||||
while (open >= 0 && collected < options.depth) {
|
||||
var level = 1;
|
||||
var i = open + 1;
|
||||
var close = -1;
|
||||
|
||||
// balance nested '[' and ']' inside this bracket group using a nesting level counter
|
||||
while (i < n && close < 0) {
|
||||
var cu = key.charCodeAt(i);
|
||||
if (cu === 0x5B) { // '['
|
||||
level += 1;
|
||||
} else if (cu === 0x5D) { // ']'
|
||||
level -= 1;
|
||||
if (level === 0) {
|
||||
close = i; // found matching close; loop will exit by condition
|
||||
}
|
||||
var i = 0;
|
||||
while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
|
||||
i += 1;
|
||||
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
|
||||
if (!options.allowPrototypes) {
|
||||
return;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (close < 0) {
|
||||
// Unterminated group: wrap the raw remainder in one bracket pair so it stays
|
||||
// a single literal segment (e.g. "[[]b" -> "[[]b]"); we do not infer missing ']'.
|
||||
segments[segments.length] = '[' + key.slice(open) + ']';
|
||||
return segments;
|
||||
}
|
||||
|
||||
var seg = key.slice(open, close + 1);
|
||||
// prototype guard for the content of this group
|
||||
var content = seg.slice(1, -1);
|
||||
if (!options.plainObjects && has.call(Object.prototype, content) && !options.allowPrototypes) {
|
||||
return;
|
||||
}
|
||||
|
||||
segments[segments.length] = seg;
|
||||
collected += 1;
|
||||
|
||||
// find the next '[' after this balanced group
|
||||
open = key.indexOf('[', close + 1);
|
||||
keys.push(segment[1]);
|
||||
}
|
||||
|
||||
if (open >= 0) {
|
||||
// If there's a remainder, check strictDepth option for throw, else just add whatever is left
|
||||
|
||||
if (segment) {
|
||||
if (options.strictDepth === true) {
|
||||
throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true');
|
||||
}
|
||||
|
||||
segments[segments.length] = '[' + key.slice(open) + ']';
|
||||
}
|
||||
|
||||
return segments;
|
||||
};
|
||||
|
||||
var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
|
||||
if (!givenKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
var keys = splitKeyIntoSegments(givenKey, options);
|
||||
|
||||
if (!keys) {
|
||||
return;
|
||||
keys.push('[' + key.slice(segment.index) + ']');
|
||||
}
|
||||
|
||||
return parseObject(keys, val, options, valuesParsed);
|
||||
@@ -370,7 +296,6 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
|
||||
parseArrays: opts.parseArrays !== false,
|
||||
plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
|
||||
strictDepth: typeof opts.strictDepth === 'boolean' ? !!opts.strictDepth : defaults.strictDepth,
|
||||
strictMerge: typeof opts.strictMerge === 'boolean' ? !!opts.strictMerge : defaults.strictMerge,
|
||||
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling,
|
||||
throwOnLimitExceeded: typeof opts.throwOnLimitExceeded === 'boolean' ? opts.throwOnLimitExceeded : false
|
||||
};
|
||||
|
||||
+4
-11
@@ -118,7 +118,7 @@ var stringify = function stringify(
|
||||
|
||||
if (obj === null) {
|
||||
if (strictNullHandling) {
|
||||
return formatter(encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix);
|
||||
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;
|
||||
}
|
||||
|
||||
obj = '';
|
||||
@@ -142,9 +142,7 @@ var stringify = function stringify(
|
||||
if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
||||
// we need to join elements in
|
||||
if (encodeValuesOnly && encoder) {
|
||||
obj = utils.maybeMap(obj, function (v) {
|
||||
return v == null ? v : encoder(v);
|
||||
});
|
||||
obj = utils.maybeMap(obj, encoder);
|
||||
}
|
||||
objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
|
||||
} else if (isArray(filter)) {
|
||||
@@ -314,11 +312,6 @@ module.exports = function (object, opts) {
|
||||
var sideChannel = getSideChannel();
|
||||
for (var i = 0; i < objKeys.length; ++i) {
|
||||
var key = objKeys[i];
|
||||
|
||||
if (typeof key === 'undefined' || key === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = obj[key];
|
||||
|
||||
if (options.skipNulls && value === null) {
|
||||
@@ -352,10 +345,10 @@ module.exports = function (object, opts) {
|
||||
if (options.charsetSentinel) {
|
||||
if (options.charset === 'iso-8859-1') {
|
||||
// encodeURIComponent('✓'), the "numeric entity" representation of a checkmark
|
||||
prefix += 'utf8=%26%2310003%3B' + options.delimiter;
|
||||
prefix += 'utf8=%26%2310003%3B&';
|
||||
} else {
|
||||
// encodeURIComponent('✓')
|
||||
prefix += 'utf8=%E2%9C%93' + options.delimiter;
|
||||
prefix += 'utf8=%E2%9C%93&';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-85
@@ -1,36 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
var formats = require('./formats');
|
||||
var getSideChannel = require('side-channel');
|
||||
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
var isArray = Array.isArray;
|
||||
|
||||
// Track objects created from arrayLimit overflow using side-channel
|
||||
// Stores the current max numeric index for O(1) lookup
|
||||
var overflowChannel = getSideChannel();
|
||||
|
||||
var markOverflow = function markOverflow(obj, maxIndex) {
|
||||
overflowChannel.set(obj, maxIndex);
|
||||
return obj;
|
||||
};
|
||||
|
||||
var isOverflow = function isOverflow(obj) {
|
||||
return overflowChannel.has(obj);
|
||||
};
|
||||
|
||||
var getMaxIndex = function getMaxIndex(obj) {
|
||||
return overflowChannel.get(obj);
|
||||
};
|
||||
|
||||
var setMaxIndex = function setMaxIndex(obj, maxIndex) {
|
||||
overflowChannel.set(obj, maxIndex);
|
||||
};
|
||||
|
||||
var hexTable = (function () {
|
||||
var array = [];
|
||||
for (var i = 0; i < 256; ++i) {
|
||||
array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
|
||||
array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
|
||||
}
|
||||
|
||||
return array;
|
||||
@@ -46,7 +24,7 @@ var compactQueue = function compactQueue(queue) {
|
||||
|
||||
for (var j = 0; j < obj.length; ++j) {
|
||||
if (typeof obj[j] !== 'undefined') {
|
||||
compacted[compacted.length] = obj[j];
|
||||
compacted.push(obj[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,20 +52,9 @@ var merge = function merge(target, source, options) {
|
||||
|
||||
if (typeof source !== 'object' && typeof source !== 'function') {
|
||||
if (isArray(target)) {
|
||||
var nextIndex = target.length;
|
||||
if (options && typeof options.arrayLimit === 'number' && nextIndex > options.arrayLimit) {
|
||||
return markOverflow(arrayToObject(target.concat(source), options), nextIndex);
|
||||
}
|
||||
target[nextIndex] = source;
|
||||
target.push(source);
|
||||
} else if (target && typeof target === 'object') {
|
||||
if (isOverflow(target)) {
|
||||
// Add at next numeric index for overflow objects
|
||||
var newIndex = getMaxIndex(target) + 1;
|
||||
target[newIndex] = source;
|
||||
setMaxIndex(target, newIndex);
|
||||
} else if (options && options.strictMerge) {
|
||||
return [target, source];
|
||||
} else if (
|
||||
if (
|
||||
(options && (options.plainObjects || options.allowPrototypes))
|
||||
|| !has.call(Object.prototype, source)
|
||||
) {
|
||||
@@ -101,23 +68,7 @@ var merge = function merge(target, source, options) {
|
||||
}
|
||||
|
||||
if (!target || typeof target !== 'object') {
|
||||
if (isOverflow(source)) {
|
||||
// Create new object with target at 0, source values shifted by 1
|
||||
var sourceKeys = Object.keys(source);
|
||||
var result = options && options.plainObjects
|
||||
? { __proto__: null, 0: target }
|
||||
: { 0: target };
|
||||
for (var m = 0; m < sourceKeys.length; m++) {
|
||||
var oldKey = parseInt(sourceKeys[m], 10);
|
||||
result[oldKey + 1] = source[sourceKeys[m]];
|
||||
}
|
||||
return markOverflow(result, getMaxIndex(source) + 1);
|
||||
}
|
||||
var combined = [target].concat(source);
|
||||
if (options && typeof options.arrayLimit === 'number' && combined.length > options.arrayLimit) {
|
||||
return markOverflow(arrayToObject(combined, options), combined.length - 1);
|
||||
}
|
||||
return combined;
|
||||
return [target].concat(source);
|
||||
}
|
||||
|
||||
var mergeTarget = target;
|
||||
@@ -132,7 +83,7 @@ var merge = function merge(target, source, options) {
|
||||
if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
|
||||
target[i] = merge(targetItem, item, options);
|
||||
} else {
|
||||
target[target.length] = item;
|
||||
target.push(item);
|
||||
}
|
||||
} else {
|
||||
target[i] = item;
|
||||
@@ -149,17 +100,6 @@ var merge = function merge(target, source, options) {
|
||||
} else {
|
||||
acc[key] = value;
|
||||
}
|
||||
|
||||
if (isOverflow(source) && !isOverflow(acc)) {
|
||||
markOverflow(acc, getMaxIndex(source));
|
||||
}
|
||||
if (isOverflow(acc)) {
|
||||
var keyNum = parseInt(key, 10);
|
||||
if (String(keyNum) === key && keyNum >= 0 && keyNum > getMaxIndex(acc)) {
|
||||
setMaxIndex(acc, keyNum);
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, mergeTarget);
|
||||
};
|
||||
@@ -276,8 +216,8 @@ var compact = function compact(value) {
|
||||
var key = keys[j];
|
||||
var val = obj[key];
|
||||
if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
|
||||
queue[queue.length] = { obj: obj, prop: key };
|
||||
refs[refs.length] = val;
|
||||
queue.push({ obj: obj, prop: key });
|
||||
refs.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,27 +239,15 @@ var isBuffer = function isBuffer(obj) {
|
||||
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
|
||||
};
|
||||
|
||||
var combine = function combine(a, b, arrayLimit, plainObjects) {
|
||||
// If 'a' is already an overflow object, add to it
|
||||
if (isOverflow(a)) {
|
||||
var newIndex = getMaxIndex(a) + 1;
|
||||
a[newIndex] = b;
|
||||
setMaxIndex(a, newIndex);
|
||||
return a;
|
||||
}
|
||||
|
||||
var result = [].concat(a, b);
|
||||
if (result.length > arrayLimit) {
|
||||
return markOverflow(arrayToObject(result, { plainObjects: plainObjects }), result.length - 1);
|
||||
}
|
||||
return result;
|
||||
var combine = function combine(a, b) {
|
||||
return [].concat(a, b);
|
||||
};
|
||||
|
||||
var maybeMap = function maybeMap(val, fn) {
|
||||
if (isArray(val)) {
|
||||
var mapped = [];
|
||||
for (var i = 0; i < val.length; i += 1) {
|
||||
mapped[mapped.length] = fn(val[i]);
|
||||
mapped.push(fn(val[i]));
|
||||
}
|
||||
return mapped;
|
||||
}
|
||||
@@ -334,9 +262,7 @@ module.exports = {
|
||||
decode: decode,
|
||||
encode: encode,
|
||||
isBuffer: isBuffer,
|
||||
isOverflow: isOverflow,
|
||||
isRegExp: isRegExp,
|
||||
markOverflow: markOverflow,
|
||||
maybeMap: maybeMap,
|
||||
merge: merge
|
||||
};
|
||||
|
||||
+9
-10
@@ -2,7 +2,7 @@
|
||||
"name": "qs",
|
||||
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
||||
"homepage": "https://github.com/ljharb/qs",
|
||||
"version": "6.15.2",
|
||||
"version": "6.14.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ljharb/qs.git"
|
||||
@@ -36,31 +36,30 @@
|
||||
"devDependencies": {
|
||||
"@browserify/envify": "^6.0.0",
|
||||
"@browserify/uglifyify": "^6.0.0",
|
||||
"@ljharb/eslint-config": "^22.2.3",
|
||||
"@ljharb/eslint-config": "^21.1.1",
|
||||
"browserify": "^16.5.2",
|
||||
"bundle-collapser": "^1.4.0",
|
||||
"common-shakeify": "~1.0.0",
|
||||
"eclint": "^2.8.1",
|
||||
"es-value-fixtures": "^1.7.1",
|
||||
"eslint": "^9.39.2",
|
||||
"es-value-fixtures": "^1.7.0",
|
||||
"eslint": "=8.8.0",
|
||||
"evalmd": "^0.0.19",
|
||||
"for-each": "^0.3.5",
|
||||
"for-each": "^0.3.3",
|
||||
"glob": "=10.3.7",
|
||||
"has-bigints": "^1.1.0",
|
||||
"has-override-mistake": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2",
|
||||
"has-proto": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"iconv-lite": "^0.5.2",
|
||||
"iconv-lite": "^0.5.1",
|
||||
"in-publish": "^2.0.1",
|
||||
"jackspeak": "=2.1.1",
|
||||
"jiti": "^0.0.0",
|
||||
"mkdirp": "^0.5.5",
|
||||
"mock-property": "^1.1.0",
|
||||
"module-deps": "^6.2.3",
|
||||
"npmignore": "^0.3.5",
|
||||
"npmignore": "^0.3.1",
|
||||
"nyc": "^10.3.2",
|
||||
"object-inspect": "^1.13.4",
|
||||
"object-inspect": "^1.13.3",
|
||||
"qs-iconv": "^1.0.4",
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"safer-buffer": "^2.1.2",
|
||||
@@ -77,7 +76,7 @@
|
||||
"posttest": "npx npm@'>=10.2' audit --production",
|
||||
"readme": "evalmd README.md",
|
||||
"postlint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)",
|
||||
"lint": "eslint .",
|
||||
"lint": "eslint --ext=js,mjs .",
|
||||
"dist": "mkdirp dist && browserify --standalone Qs -g unassertify -g @browserify/envify -g [@browserify/uglifyify --mangle.keep_fnames --compress.keep_fnames --format.indent_level=1 --compress.arrows=false --compress.passes=4 --compress.typeofs=false] -p common-shakeify -p bundle-collapser/plugin lib/index.js > dist/qs.js"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
|
||||
+13
-440
@@ -210,21 +210,6 @@ test('parse()', function (t) {
|
||||
t.test('uses original key when depth = 0', function (st) {
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { depth: 0 }), { 'a[0]': 'b', 'a[1]': 'c' });
|
||||
st.deepEqual(qs.parse('a[0][0]=b&a[0][1]=c&a[1]=d&e=2', { depth: 0 }), { 'a[0][0]': 'b', 'a[0][1]': 'c', 'a[1]': 'd', e: '2' });
|
||||
st.deepEqual(qs.parse('a.b=c', { depth: 0, allowDots: true }), { 'a[b]': 'c' }, 'normalizes dots before applying depth-0 behavior');
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0 }), {}, 'respects prototype guard at depth 0');
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0, allowPrototypes: true }), { toString: 'foo' }, 'allows prototypes at depth 0 when enabled');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('ignores prototype keys when depth = 0 and allowPrototypes is false', function (st) {
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0 }), {});
|
||||
st.deepEqual(qs.parse('hasOwnProperty=bar', { depth: 0 }), {});
|
||||
st.deepEqual(qs.parse('toString=foo&a=b', { depth: 0 }), { a: 'b' });
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allows prototype keys when depth = 0 and allowPrototypes is true', function (st) {
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0, allowPrototypes: true }), { toString: 'foo' });
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -250,11 +235,11 @@ test('parse()', function (t) {
|
||||
st.deepEqual(qs.parse('a=b&a[0]=c'), { a: ['b', 'c'] });
|
||||
|
||||
st.deepEqual(qs.parse('a[1]=b&a=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } });
|
||||
st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
|
||||
|
||||
st.deepEqual(qs.parse('a=b&a[1]=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } });
|
||||
st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] });
|
||||
|
||||
st.end();
|
||||
@@ -266,52 +251,6 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('parses keys with literal [] inside a bracket group (#493)', function (st) {
|
||||
// A bracket pair inside a bracket group should be treated literally as part of the key
|
||||
st.deepEqual(
|
||||
qs.parse('search[withbracket[]]=foobar'),
|
||||
{ search: { 'withbracket[]': 'foobar' } },
|
||||
'treats inner [] literally when inside a bracket group'
|
||||
);
|
||||
|
||||
// Single-level variant
|
||||
st.deepEqual(
|
||||
qs.parse('a[b[]]=c'),
|
||||
{ a: { 'b[]': 'c' } },
|
||||
'keeps "b[]" as a literal key'
|
||||
);
|
||||
|
||||
// Nested with an array push on the outer level
|
||||
st.deepEqual(
|
||||
qs.parse('list[][x[]]=y'),
|
||||
{ list: [{ 'x[]': 'y' }] },
|
||||
'preserves inner [] while still treating outer [] as array push'
|
||||
);
|
||||
|
||||
// Multiple nested bracket pairs: inner [] remains literal as part of the key
|
||||
st.deepEqual(
|
||||
qs.parse('a[b[c[]]]=d'),
|
||||
{ a: { 'b[c[]]': 'd' } },
|
||||
'treats "b[c[]]" as a literal key inside the bracket group'
|
||||
);
|
||||
|
||||
// Depth limits with literal brackets: preserve inner [] while limiting bracket-group parsing
|
||||
st.deepEqual(
|
||||
qs.parse('a[b[c[]]][d]=e', { depth: 1 }),
|
||||
{ a: { 'b[c[]]': { '[d]': 'e' } } },
|
||||
'respects depth: 1 and preserves literal inner [] in the parsed key'
|
||||
);
|
||||
|
||||
// Unterminated inner bracket group is wrapped as a literal remainder segment
|
||||
st.deepEqual(
|
||||
qs.parse('a[[]b=c'),
|
||||
{ a: { '[[]b': 'c' } },
|
||||
'handles unterminated inner bracket groups without throwing'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allows to specify array indices', function (st) {
|
||||
st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] });
|
||||
st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] });
|
||||
@@ -322,11 +261,11 @@ test('parse()', function (t) {
|
||||
});
|
||||
|
||||
t.test('limits specific array indices to arrayLimit', function (st) {
|
||||
st.deepEqual(qs.parse('a[19]=a', { arrayLimit: 20 }), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: { 20: 'a' } });
|
||||
st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[21]=a', { arrayLimit: 20 }), { a: { 21: 'a' } });
|
||||
|
||||
st.deepEqual(qs.parse('a[19]=a'), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[20]=a'), { a: { 20: 'a' } });
|
||||
st.deepEqual(qs.parse('a[20]=a'), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[21]=a'), { a: { 21: 'a' } });
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -425,7 +364,7 @@ test('parse()', function (t) {
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[]&a[]=c&a[]=', { strictNullHandling: true, arrayLimit: 0 }),
|
||||
{ a: { 0: 'b', 1: null, 2: 'c', 3: '' } },
|
||||
{ a: ['b', null, 'c', ''] },
|
||||
'with arrayLimit 0 + array brackets: null then empty string works'
|
||||
);
|
||||
|
||||
@@ -436,7 +375,7 @@ test('parse()', function (t) {
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[]=&a[]=c&a[]', { strictNullHandling: true, arrayLimit: 0 }),
|
||||
{ a: { 0: 'b', 1: '', 2: 'c', 3: null } },
|
||||
{ a: ['b', '', 'c', null] },
|
||||
'with arrayLimit 0 + array brackets: empty string then null works'
|
||||
);
|
||||
|
||||
@@ -544,7 +483,7 @@ test('parse()', function (t) {
|
||||
|
||||
t.test('allows overriding array limit', function (st) {
|
||||
st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { 0: 'b' } });
|
||||
st.deepEqual(qs.parse('a[0]=b', { arrayLimit: 0 }), { a: { 0: 'b' } });
|
||||
st.deepEqual(qs.parse('a[0]=b', { arrayLimit: 0 }), { a: ['b'] });
|
||||
|
||||
st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: -1 }), { a: { '-1': 'b' } });
|
||||
st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: 0 }), { a: { '-1': 'b' } });
|
||||
@@ -845,25 +784,25 @@ test('parse()', function (t) {
|
||||
|
||||
t.test('add keys to objects', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=d', { strictMerge: false }),
|
||||
qs.parse('a[b]=c&a=d'),
|
||||
{ a: { b: 'c', d: true } },
|
||||
'can add keys to objects'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { strictMerge: false }),
|
||||
qs.parse('a[b]=c&a=toString'),
|
||||
{ a: { b: 'c' } },
|
||||
'can not overwrite prototype'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { strictMerge: false, allowPrototypes: true }),
|
||||
qs.parse('a[b]=c&a=toString', { allowPrototypes: true }),
|
||||
{ a: { b: 'c', toString: true } },
|
||||
'can overwrite prototype with allowPrototypes true'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { strictMerge: false, plainObjects: true }),
|
||||
qs.parse('a[b]=c&a=toString', { plainObjects: true }),
|
||||
{ __proto__: null, a: { __proto__: null, b: 'c', toString: true } },
|
||||
'can overwrite prototype with plainObjects true'
|
||||
);
|
||||
@@ -871,34 +810,6 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('strictMerge wraps object and primitive into an array', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=d'),
|
||||
{ a: [{ b: 'c' }, 'd'] },
|
||||
'object then primitive produces array'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a=d&a[b]=c'),
|
||||
{ a: ['d', { b: 'c' }] },
|
||||
'primitive then object produces array'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString'),
|
||||
{ a: [{ b: 'c' }, 'toString'] },
|
||||
'prototype-colliding value is preserved in array'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { plainObjects: true }),
|
||||
{ __proto__: null, a: [{ __proto__: null, b: 'c' }, 'toString'] },
|
||||
'plainObjects preserved in array wrapping'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('dunder proto is ignored', function (st) {
|
||||
var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42';
|
||||
var result = qs.parse(payload, { allowPrototypes: true });
|
||||
@@ -1085,20 +996,6 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('handles a custom decoder returning `null`, with a string key of `null`', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('null=1&ToNull=2', {
|
||||
decoder: function (str, defaultDecoder, charset) {
|
||||
return str === 'ToNull' ? null : defaultDecoder(str, defaultDecoder, charset);
|
||||
}
|
||||
}),
|
||||
{ 'null': '1' },
|
||||
'"null" key is not overridden by `null` decoder result'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('does not interpret numeric entities in iso-8859-1 when `interpretNumericEntities` is absent', function (st) {
|
||||
st.deepEqual(qs.parse('foo=' + urlEncodedNumSmiley, { charset: 'iso-8859-1' }), { foo: '☺' });
|
||||
st.end();
|
||||
@@ -1135,15 +1032,6 @@ test('parse()', function (t) {
|
||||
};
|
||||
|
||||
st.deepEqual(qs.parse('KeY=vAlUe', { decoder: decoder }), { key: 'VALUE' });
|
||||
|
||||
var noopDecoder = function () { return 'x'; };
|
||||
noopDecoder();
|
||||
st['throws'](
|
||||
function () { decoder('x', noopDecoder, 'utf-8', 'unknown'); },
|
||||
'this should never happen! type: unknown',
|
||||
'decoder throws for unexpected type'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1173,14 +1061,6 @@ test('parse()', function (t) {
|
||||
new RangeError('Parameter limit exceeded. Only 3 parameters allowed.'),
|
||||
'throws error when parameter limit is exceeded'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a=1&b=2', { parameterLimit: 1, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Parameter limit exceeded. Only 1 parameter allowed.'),
|
||||
'throws error with singular "parameter" when parameterLimit is 1'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
@@ -1202,12 +1082,6 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('allows unlimited parameters when parameterLimit is Infinity and throwOnLimitExceeded is true', function (sst) {
|
||||
var result = qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: Infinity, throwOnLimitExceeded: true });
|
||||
sst.deepEqual(result, { a: '1', b: '2', c: '3', d: '4', e: '5', f: '6' }, 'parses all parameters without truncation or throwing');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1230,7 +1104,6 @@ test('parse()', function (t) {
|
||||
});
|
||||
|
||||
st.test('throws error when array limit exceeded', function (sst) {
|
||||
// 4 elements exceeds limit of 3
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
@@ -1241,14 +1114,6 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('does not throw when at limit', function (sst) {
|
||||
// 3 elements = limit of 3, should not throw
|
||||
var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
sst.ok(Array.isArray(result.a), 'result is an array');
|
||||
sst.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('converts array to object if length is greater than limit', function (sst) {
|
||||
var result = qs.parse('a[1]=1&a[2]=2&a[3]=3&a[4]=4&a[5]=5&a[6]=6', { arrayLimit: 5 });
|
||||
|
||||
@@ -1256,59 +1121,6 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('throws error when indexed notation exceeds arrayLimit with throwOnLimitExceeded', function (sst) {
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[1001]=b', { arrayLimit: 1000, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1000 elements allowed in an array.'),
|
||||
'throws error for a single index exceeding arrayLimit'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[0]=1&a[1]=2&a[2]=3&a[10]=4', { arrayLimit: 6, throwOnLimitExceeded: true, allowSparse: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 6 elements allowed in an array.'),
|
||||
'throws error when a sparse index exceeds arrayLimit'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[2]=b', { arrayLimit: 1, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
|
||||
'throws error with singular "element" when arrayLimit is 1'
|
||||
);
|
||||
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('does not throw for indexed notation within arrayLimit with throwOnLimitExceeded', function (sst) {
|
||||
var result = qs.parse('a[4]=b', { arrayLimit: 5, throwOnLimitExceeded: true, allowSparse: true });
|
||||
sst.ok(Array.isArray(result.a), 'result is an array');
|
||||
sst.equal(result.a.length, 5, 'array has correct length');
|
||||
sst.equal(result.a[4], 'b', 'value at index 4 is correct');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('silently converts to object for indexed notation exceeding arrayLimit without throwOnLimitExceeded', function (sst) {
|
||||
var result = qs.parse('a[1001]=b', { arrayLimit: 1000 });
|
||||
sst.deepEqual(result, { a: { 1001: 'b' } }, 'converts to object without throwing');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('throws when duplicate bracket keys exceed arrayLimit with throwOnLimitExceeded', function (sst) {
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1&a[]=2&a[]=3&a[]=4&a[]=5&a[]=6', { arrayLimit: 5, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'),
|
||||
'throws error when duplicate bracket notation exceeds array limit'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1360,34 +1172,6 @@ test('`duplicates` option', function (t) {
|
||||
'duplicates: last'
|
||||
);
|
||||
|
||||
t.test('bracket notation always combines regardless of duplicates', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'last' }),
|
||||
{ a: '2', b: ['1', '2'] },
|
||||
'duplicates last: unbracketed takes last, bracketed combines'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('b[]=1&b[]=2', { duplicates: 'last' }),
|
||||
{ b: ['1', '2'] },
|
||||
'duplicates last: bracketed always combines'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('b[]=1&b[]=2', { duplicates: 'first' }),
|
||||
{ b: ['1', '2'] },
|
||||
'duplicates first: bracketed always combines'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'first' }),
|
||||
{ a: '1', b: ['1', '2'] },
|
||||
'duplicates first: unbracketed takes first, bracketed combines'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -1490,214 +1274,3 @@ test('qs strictDepth option - non-throw cases', function (t) {
|
||||
st.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('DOS', function (t) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < 105; i++) {
|
||||
arr[arr.length] = 'x';
|
||||
}
|
||||
var attack = 'a[]=' + arr.join('&a[]=');
|
||||
var result = qs.parse(attack, { arrayLimit: 100 });
|
||||
|
||||
t.notOk(Array.isArray(result.a), 'arrayLimit is respected: result is an object, not an array');
|
||||
t.equal(Object.keys(result.a).length, 105, 'all values are preserved');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('arrayLimit boundary conditions', function (t) {
|
||||
// arrayLimit is the max number of elements allowed in an array
|
||||
t.test('exactly at the limit stays as array', function (st) {
|
||||
// 3 elements = limit of 3
|
||||
var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 3 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array when count equals limit');
|
||||
st.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('one over the limit converts to object', function (st) {
|
||||
// 4 elements exceeds limit of 3
|
||||
var result = qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3 });
|
||||
st.notOk(Array.isArray(result.a), 'result is not an array when over limit');
|
||||
st.deepEqual(result.a, { 0: '1', 1: '2', 2: '3', 3: '4' }, 'all values preserved as object');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayLimit 1 with one value', function (st) {
|
||||
// 1 element = limit of 1
|
||||
var result = qs.parse('a[]=1', { arrayLimit: 1 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array when count equals limit');
|
||||
st.deepEqual(result.a, ['1'], 'value preserved as array');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayLimit 1 with two values converts to object', function (st) {
|
||||
// 2 elements exceeds limit of 1
|
||||
var result = qs.parse('a[]=1&a[]=2', { arrayLimit: 1 });
|
||||
st.notOk(Array.isArray(result.a), 'result is not an array');
|
||||
st.deepEqual(result.a, { 0: '1', 1: '2' }, 'all values preserved as object');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('comma + arrayLimit', function (t) {
|
||||
t.test('comma-separated values within arrayLimit stay as array', function (st) {
|
||||
var result = qs.parse('a=1,2,3', { comma: true, arrayLimit: 5 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array');
|
||||
st.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('comma-separated values exceeding arrayLimit convert to object', function (st) {
|
||||
var result = qs.parse('a=1,2,3,4', { comma: true, arrayLimit: 3 });
|
||||
st.notOk(Array.isArray(result.a), 'result is not an array when over limit');
|
||||
st.deepEqual(result.a, { 0: '1', 1: '2', 2: '3', 3: '4' }, 'all values preserved as object');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('comma-separated values exceeding arrayLimit with throwOnLimitExceeded throws', function (st) {
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'throws error when comma-split exceeds array limit'
|
||||
);
|
||||
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a=1,2,3', { comma: true, arrayLimit: 1, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
|
||||
'throws error with singular "element" when arrayLimit is 1'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('comma-separated values at exactly arrayLimit stay as array', function (st) {
|
||||
var result = qs.parse('a=1,2,3', { comma: true, arrayLimit: 3 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array when exactly at limit');
|
||||
st.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('mixed array and object notation', function (t) {
|
||||
t.test('array brackets with object key - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[c]=d'),
|
||||
{ a: { 0: 'b', c: 'd' } },
|
||||
'mixing [] and [key] converts to object'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('array index with object key - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[0]=b&a[c]=d'),
|
||||
{ a: { 0: 'b', c: 'd' } },
|
||||
'mixing [0] and [key] produces object'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('plain value with array brackets - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a[]=c', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c'] },
|
||||
'plain value combined with [] stays as array under limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('array brackets with plain value - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a=c', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c'] },
|
||||
'[] combined with plain value stays as array under limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('plain value with array index - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a[0]=c', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c'] },
|
||||
'plain value combined with [0] stays as array under limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('multiple plain values with duplicates combine', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a=c&a=d', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c', 'd'] },
|
||||
'duplicate plain keys combine into array'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('multiple plain values exceeding limit', function (st) {
|
||||
// 3 elements (indices 0-2), max index 2 > limit 1
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a=c&a=d', { arrayLimit: 1 }),
|
||||
{ a: { 0: 'b', 1: 'c', 2: 'd' } },
|
||||
'duplicate plain keys convert to object when exceeding limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('mixed notation produces consistent results when arrayLimit is exceeded', function (st) {
|
||||
var expected = { a: { 0: 'b', 1: 'c', 2: 'd' } };
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: -1 }),
|
||||
expected,
|
||||
'arrayLimit -1'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: 0 }),
|
||||
expected,
|
||||
'arrayLimit 0'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: 1 }),
|
||||
expected,
|
||||
'arrayLimit 1'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('uses existing array length for currentArrayLength when parsing object input with bracket keys', function (st) {
|
||||
var input = {};
|
||||
var arr = ['x', 'y'];
|
||||
arr.a = ['z', 'w'];
|
||||
input['a[]'] = arr;
|
||||
st.deepEqual(qs.parse(input), { a: ['x', 'y'] }, 'parses object input with bracket keys using existing array values');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('throws with singular message when object input bracket key exceeds arrayLimit of 1', function (st) {
|
||||
var input = {};
|
||||
var arr = ['x'];
|
||||
arr.a = ['z', 'w'];
|
||||
input['a[]'] = arr;
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse(input, { throwOnLimitExceeded: true, arrayLimit: 1 });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
|
||||
'throws singular error for object input exceeding arrayLimit 1'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
+3
-145
@@ -651,49 +651,6 @@ test('stringify()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('does not crash on null/undefined entries in arrayFormat=comma with encodeValuesOnly', function (st) {
|
||||
st.doesNotThrow(
|
||||
function () { qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); },
|
||||
'does not pass a raw null array entry to the encoder'
|
||||
);
|
||||
st.doesNotThrow(
|
||||
function () { qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }); },
|
||||
'does not pass a raw undefined array entry to the encoder'
|
||||
);
|
||||
st.doesNotThrow(
|
||||
function () { qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }); },
|
||||
'does not crash on a single-null array'
|
||||
);
|
||||
|
||||
st.equal(
|
||||
qs.stringify({ a: [null, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }),
|
||||
'a=,b',
|
||||
'null entry joins as empty, comma stays unencoded under encodeValuesOnly'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: [undefined, 'b'] }, { arrayFormat: 'comma', encodeValuesOnly: true }),
|
||||
'a=,b',
|
||||
'undefined entry joins as empty, comma stays unencoded under encodeValuesOnly'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true }),
|
||||
'a=',
|
||||
'single-null array stringifies as empty value'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true, strictNullHandling: true }),
|
||||
'a',
|
||||
'strictNullHandling drops the equals sign for a single-null array'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: [null] }, { arrayFormat: 'comma', encodeValuesOnly: true, skipNulls: true }),
|
||||
'',
|
||||
'skipNulls drops a single-null array entirely'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('stringifies a null object', { skip: !hasProto }, function (st) {
|
||||
st.equal(qs.stringify({ __proto__: null, a: 'b' }), 'a=b');
|
||||
st.end();
|
||||
@@ -868,35 +825,6 @@ test('stringify()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('skips null/undefined entries in filter=array', function (st) {
|
||||
st.doesNotThrow(
|
||||
function () { qs.stringify({ a: 'b', undefined: 'x' }, { filter: ['a', undefined] }); },
|
||||
'does not pass a raw undefined filter entry to the encoder'
|
||||
);
|
||||
st.doesNotThrow(
|
||||
function () { qs.stringify({ a: 'b', 'null': 'x' }, { filter: ['a', null] }); },
|
||||
'does not pass a raw null filter entry to the encoder'
|
||||
);
|
||||
|
||||
st.equal(
|
||||
qs.stringify({ a: 'b', undefined: 'x', c: 'd' }, { filter: ['a', undefined, 'c'] }),
|
||||
'a=b&c=d',
|
||||
'undefined filter entry is skipped, remaining keys are kept'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: 'b', 'null': 'x', c: 'd' }, { filter: ['a', null, 'c'] }),
|
||||
'a=b&c=d',
|
||||
'null filter entry is skipped, remaining keys are kept'
|
||||
);
|
||||
st.equal(
|
||||
qs.stringify({ a: 'b', 'null': 'x' }, { filter: [null] }),
|
||||
'',
|
||||
'filter array containing only null yields empty string'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('supports custom representations when filter=function', function (st) {
|
||||
var calls = 0;
|
||||
var obj = { a: 'b', c: 'd', e: { f: new Date(1257894000000) } };
|
||||
@@ -1183,28 +1111,6 @@ test('stringify()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('strictNullHandling: applies the formatter to the encoded key (RFC1738)', function (st) {
|
||||
st.equal(
|
||||
qs.stringify(
|
||||
{ 'a b': null, 'c d': 'e f' },
|
||||
{ strictNullHandling: false, format: 'RFC1738' }
|
||||
),
|
||||
'a+b=&c+d=e+f',
|
||||
'without: as expected'
|
||||
);
|
||||
|
||||
st.equal(
|
||||
qs.stringify(
|
||||
{ 'a b': null, 'c d': 'e f' },
|
||||
{ strictNullHandling: true, format: 'RFC1738' }
|
||||
),
|
||||
'a+b&c+d=e+f',
|
||||
'with: as expected'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('throws if an invalid charset is specified', function (st) {
|
||||
st['throws'](function () {
|
||||
qs.stringify({ a: 'b' }, { charset: 'foobar' });
|
||||
@@ -1240,12 +1146,6 @@ test('stringify()', function (t) {
|
||||
'adds the right sentinel when instructed to and the charset is iso-8859-1'
|
||||
);
|
||||
|
||||
st.equal(
|
||||
qs.stringify({ a: 1, b: 2 }, { charsetSentinel: true, delimiter: ';' }),
|
||||
'utf8=%E2%9C%93;a=1;b=2',
|
||||
'uses the configured delimiter after the sentinel'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1288,15 +1188,6 @@ test('stringify()', function (t) {
|
||||
};
|
||||
|
||||
st.deepEqual(qs.stringify({ KeY: 'vAlUe' }, { encoder: encoder }), 'key=VALUE');
|
||||
|
||||
var noopEncoder = function () { return 'x'; };
|
||||
noopEncoder();
|
||||
st['throws'](
|
||||
function () { encoder('x', noopEncoder, 'utf-8', 'unknown'); },
|
||||
'this should never happen! type: unknown',
|
||||
'encoder throws for unexpected type'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1402,46 +1293,13 @@ test('stringifies empty keys', function (t) {
|
||||
});
|
||||
|
||||
t.test('stringifies non-string keys', function (st) {
|
||||
var S = Object('abc');
|
||||
S.toString = function () {
|
||||
return 'd';
|
||||
};
|
||||
var actual = qs.stringify({ a: 'b', 'false': {}, 1e+22: 'c', d: 'e' }, {
|
||||
filter: ['a', false, null, 10000000000000000000000, S],
|
||||
var actual = qs.stringify({ a: 'b', 'false': {} }, {
|
||||
filter: ['a', false, null],
|
||||
allowDots: true,
|
||||
encodeDotInKeys: true
|
||||
});
|
||||
|
||||
st.equal(actual, 'a=b&1e%2B22=c&d=e', 'stringifies correctly');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('round-trips keys containing percent-encoded bracket text', function (st) {
|
||||
var cases = [
|
||||
{ 'a%5Bb': 'c' },
|
||||
{ 'a%5Db': 'c' },
|
||||
{ 'a%255Bb': 'c' },
|
||||
{ 'a%255Db': 'c' },
|
||||
{ a: { 'b%5Bc': 'd' } },
|
||||
{ a: { 'b%255Bc': 'd' } },
|
||||
{ 'a%5B%255Bb': 'c' }
|
||||
];
|
||||
for (var i = 0; i < cases.length; i++) {
|
||||
st.deepEqual(
|
||||
qs.parse(qs.stringify(cases[i])),
|
||||
cases[i],
|
||||
'round-trips ' + JSON.stringify(cases[i])
|
||||
);
|
||||
}
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('parses input containing percent-encoded bracket text without mangling', function (st) {
|
||||
st.deepEqual(qs.parse('a%25255Bb=c'), { 'a%255Bb': 'c' }, 'a%25255Bb decodes to a%255Bb, not a%5Bb');
|
||||
st.deepEqual(qs.parse('a%25255Db=c'), { 'a%255Db': 'c' }, 'a%25255Db decodes to a%255Db, not a%5Db');
|
||||
st.deepEqual(qs.parse('a%5Bb%25255Bc%5D=d'), { a: { 'b%255Bc': 'd' } }, 'nested %25255B decodes to %255B inside segment, not %5B');
|
||||
st.equal(actual, 'a=b', 'stringifies correctly');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
+3
-173
@@ -31,7 +31,6 @@ test('merge()', function (t) {
|
||||
t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true });
|
||||
|
||||
var func = function f() {};
|
||||
func();
|
||||
t.deepEqual(
|
||||
utils.merge(func, { foo: 'bar' }),
|
||||
[func, { foo: 'bar' }],
|
||||
@@ -69,93 +68,6 @@ test('merge()', function (t) {
|
||||
}
|
||||
);
|
||||
|
||||
t.test('with overflow objects (from arrayLimit)', function (st) {
|
||||
// arrayLimit is max index, so with limit 0, max index 0 is allowed (1 element)
|
||||
// To create overflow, need 2+ elements with limit 0, or 3+ with limit 1, etc.
|
||||
st.test('merges primitive into overflow object at next index', function (s2t) {
|
||||
// Create an overflow object via combine: 3 elements (indices 0-2) with limit 0
|
||||
var overflow = utils.combine(['a', 'b'], 'c', 0, false);
|
||||
s2t.ok(utils.isOverflow(overflow), 'overflow object is marked');
|
||||
var merged = utils.merge(overflow, 'd');
|
||||
s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'adds primitive at next numeric index');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges primitive into regular object with numeric keys normally', function (s2t) {
|
||||
var obj = { 0: 'a', 1: 'b' };
|
||||
s2t.notOk(utils.isOverflow(obj), 'plain object is not marked as overflow');
|
||||
var merged = utils.merge(obj, 'c');
|
||||
s2t.deepEqual(merged, { 0: 'a', 1: 'b', c: true }, 'adds primitive as key (not at next index)');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges primitive into object with non-numeric keys normally', function (s2t) {
|
||||
var obj = { foo: 'bar' };
|
||||
var merged = utils.merge(obj, 'baz');
|
||||
s2t.deepEqual(merged, { foo: 'bar', baz: true }, 'adds primitive as key with value true');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('with strictMerge, wraps object and primitive in array', function (s2t) {
|
||||
var obj = { foo: 'bar' };
|
||||
var merged = utils.merge(obj, 'baz', { strictMerge: true });
|
||||
s2t.deepEqual(merged, [{ foo: 'bar' }, 'baz'], 'wraps in array with strictMerge');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges overflow object into primitive', function (s2t) {
|
||||
// Create an overflow object via combine: 2 elements (indices 0-1) with limit 0
|
||||
var overflow = utils.combine(['a'], 'b', 0, false);
|
||||
s2t.ok(utils.isOverflow(overflow), 'overflow object is marked');
|
||||
var merged = utils.merge('c', overflow);
|
||||
s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow');
|
||||
s2t.deepEqual(merged, { 0: 'c', 1: 'a', 2: 'b' }, 'creates object with primitive at 0, source values shifted');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges overflow object into primitive with plainObjects', function (s2t) {
|
||||
var overflow = utils.combine(['a'], 'b', 0, false);
|
||||
s2t.ok(utils.isOverflow(overflow), 'overflow object is marked');
|
||||
var merged = utils.merge('c', overflow, { plainObjects: true });
|
||||
s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow');
|
||||
s2t.deepEqual(merged, { __proto__: null, 0: 'c', 1: 'a', 2: 'b' }, 'creates null-proto object with primitive at 0');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges overflow object with multiple values into primitive', function (s2t) {
|
||||
// Create an overflow object via combine: 3 elements (indices 0-2) with limit 0
|
||||
var overflow = utils.combine(['b', 'c'], 'd', 0, false);
|
||||
s2t.ok(utils.isOverflow(overflow), 'overflow object is marked');
|
||||
var merged = utils.merge('a', overflow);
|
||||
s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'shifts all source indices by 1');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges regular object into primitive as array', function (s2t) {
|
||||
var obj = { foo: 'bar' };
|
||||
var merged = utils.merge('a', obj);
|
||||
s2t.deepEqual(merged, ['a', { foo: 'bar' }], 'creates array with primitive and object');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges primitive into array that exceeds arrayLimit', function (s2t) {
|
||||
var arr = ['a', 'b', 'c'];
|
||||
var merged = utils.merge(arr, 'd', { arrayLimit: 1 });
|
||||
s2t.ok(utils.isOverflow(merged), 'result is marked as overflow');
|
||||
s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'converts to overflow object with primitive appended');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('merges array into primitive that exceeds arrayLimit', function (s2t) {
|
||||
var merged = utils.merge('a', ['b', 'c'], { arrayLimit: 1 });
|
||||
s2t.ok(utils.isOverflow(merged), 'result is marked as overflow');
|
||||
s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c' }, 'converts to overflow object');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -220,85 +132,6 @@ test('combine()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('with arrayLimit', function (st) {
|
||||
st.test('under the limit', function (s2t) {
|
||||
var combined = utils.combine(['a', 'b'], 'c', 10, false);
|
||||
s2t.deepEqual(combined, ['a', 'b', 'c'], 'returns array when under limit');
|
||||
s2t.ok(Array.isArray(combined), 'result is an array');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('exactly at the limit stays as array', function (s2t) {
|
||||
var combined = utils.combine(['a', 'b'], 'c', 3, false);
|
||||
s2t.deepEqual(combined, ['a', 'b', 'c'], 'stays as array when count equals limit');
|
||||
s2t.ok(Array.isArray(combined), 'result is an array');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('over the limit', function (s2t) {
|
||||
var combined = utils.combine(['a', 'b', 'c'], 'd', 3, false);
|
||||
s2t.deepEqual(combined, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'converts to object when over limit');
|
||||
s2t.notOk(Array.isArray(combined), 'result is not an array');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('with arrayLimit 1', function (s2t) {
|
||||
var combined = utils.combine([], 'a', 1, false);
|
||||
s2t.deepEqual(combined, ['a'], 'stays as array when count equals limit');
|
||||
s2t.ok(Array.isArray(combined), 'result is an array');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('with arrayLimit 0 converts single element to object', function (s2t) {
|
||||
var combined = utils.combine([], 'a', 0, false);
|
||||
s2t.deepEqual(combined, { 0: 'a' }, 'converts to object when count exceeds limit');
|
||||
s2t.notOk(Array.isArray(combined), 'result is not an array');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('with arrayLimit 0 and two elements converts to object', function (s2t) {
|
||||
var combined = utils.combine(['a'], 'b', 0, false);
|
||||
s2t.deepEqual(combined, { 0: 'a', 1: 'b' }, 'converts to object when count exceeds limit');
|
||||
s2t.notOk(Array.isArray(combined), 'result is not an array');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('with plainObjects option', function (s2t) {
|
||||
var combined = utils.combine(['a', 'b'], 'c', 1, true);
|
||||
var expected = { __proto__: null, 0: 'a', 1: 'b', 2: 'c' };
|
||||
s2t.deepEqual(combined, expected, 'converts to object with null prototype');
|
||||
s2t.equal(Object.getPrototypeOf(combined), null, 'result has null prototype when plainObjects is true');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('with existing overflow object', function (st) {
|
||||
st.test('adds to existing overflow object at next index', function (s2t) {
|
||||
// Create overflow object first via combine: 3 elements (indices 0-2) with limit 0
|
||||
var overflow = utils.combine(['a', 'b'], 'c', 0, false);
|
||||
s2t.ok(utils.isOverflow(overflow), 'initial object is marked as overflow');
|
||||
|
||||
var combined = utils.combine(overflow, 'd', 10, false);
|
||||
s2t.equal(combined, overflow, 'returns the same object (mutated)');
|
||||
s2t.deepEqual(combined, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'adds value at next numeric index');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.test('does not treat plain object with numeric keys as overflow', function (s2t) {
|
||||
var plainObj = { 0: 'a', 1: 'b' };
|
||||
s2t.notOk(utils.isOverflow(plainObj), 'plain object is not marked as overflow');
|
||||
|
||||
// combine treats this as a regular value, not an overflow object to append to
|
||||
var combined = utils.combine(plainObj, 'c', 10, false);
|
||||
s2t.deepEqual(combined, [{ 0: 'a', 1: 'b' }, 'c'], 'concatenates as regular values');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -401,9 +234,7 @@ test('encode', function (t) {
|
||||
});
|
||||
|
||||
test('isBuffer()', function (t) {
|
||||
var fn = function () {};
|
||||
fn();
|
||||
forEach([null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], fn, /a/g], function (x) {
|
||||
forEach([null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], function () {}, /a/g], function (x) {
|
||||
t.equal(utils.isBuffer(x), false, inspect(x) + ' is not a buffer');
|
||||
});
|
||||
|
||||
@@ -413,9 +244,8 @@ test('isBuffer()', function (t) {
|
||||
var saferBuffer = SaferBuffer.from('abc');
|
||||
t.equal(utils.isBuffer(saferBuffer), true, 'SaferBuffer instance is a buffer');
|
||||
|
||||
var buffer = SaferBuffer.from('abc');
|
||||
t.notEqual(saferBuffer, buffer, 'different buffer instances');
|
||||
t.equal(utils.isBuffer(buffer), true, 'another Buffer instance is a buffer');
|
||||
var buffer = Buffer.from && Buffer.alloc ? Buffer.from('abc') : new Buffer('abc');
|
||||
t.equal(utils.isBuffer(buffer), true, 'real Buffer instance is a buffer');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user