qs 6.2.2 → 6.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +15 -15
- package/CHANGELOG.md +25 -2
- package/README.md +59 -4
- package/dist/qs.js +148 -47
- package/lib/formats.js +18 -0
- package/lib/index.js +6 -4
- package/lib/parse.js +12 -12
- package/lib/stringify.js +83 -20
- package/lib/utils.js +23 -7
- package/package.json +12 -11
- package/test/.eslintrc +10 -0
- package/test/index.js +2 -0
- package/test/parse.js +48 -40
- package/test/stringify.js +261 -28
- package/test/utils.js +13 -0
- package/CONTRIBUTING.md +0 -1
package/.eslintrc
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
2
|
+
"root": true,
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
"extends": "@ljharb",
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
"rules": {
|
|
7
|
+
"complexity": [2, 25],
|
|
8
|
+
"consistent-return": 1,
|
|
9
|
+
"id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
|
|
10
|
+
"indent": [2, 4],
|
|
11
|
+
"max-params": [2, 11],
|
|
12
|
+
"max-statements": [2, 42],
|
|
13
|
+
"no-extra-parens": 1,
|
|
14
|
+
"no-continue": 1,
|
|
15
|
+
"no-magic-numbers": 0,
|
|
16
|
+
"no-restricted-syntax": [2, "BreakStatement", "DebuggerStatement", "ForInStatement", "LabeledStatement", "WithStatement"],
|
|
17
|
+
"operator-linebreak": 1
|
|
18
|
+
}
|
|
19
19
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
|
-
## **6.
|
|
2
|
-
- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
|
|
1
|
+
## **6.3.1**
|
|
2
|
+
- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties (thanks, @snyk!)
|
|
3
|
+
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `iconv-lite`, `qs-iconv`, `tape`
|
|
4
|
+
- [Tests] on all node minors; improve test matrix
|
|
5
|
+
- [Docs] document stringify option `allowDots` (#195)
|
|
6
|
+
- [Docs] add empty object and array values example (#195)
|
|
7
|
+
- [Docs] Fix minor inconsistency/typo (#192)
|
|
8
|
+
- [Docs] document stringify option `sort` (#191)
|
|
9
|
+
- [Refactor] `stringify`: throw faster with an invalid encoder
|
|
10
|
+
- [Refactor] remove unnecessary escapes (#184)
|
|
11
|
+
- Remove contributing.md, since `qs` is no longer part of `hapi` (#183)
|
|
12
|
+
|
|
13
|
+
## **6.3.0**
|
|
14
|
+
- [New] Add support for RFC 1738 (#174, #173)
|
|
15
|
+
- [New] `stringify`: Add `serializeDate` option to customize Date serialization (#159)
|
|
16
|
+
- [Fix] ensure `utils.merge` handles merging two arrays
|
|
17
|
+
- [Refactor] only constructors should be capitalized
|
|
18
|
+
- [Refactor] capitalized var names are for constructors only
|
|
19
|
+
- [Refactor] avoid using a sparse array
|
|
20
|
+
- [Robustness] `formats`: cache `String#replace`
|
|
21
|
+
- [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`; add `safe-publish-latest`
|
|
22
|
+
- [Tests] up to `node` `v6.8`, `v4.6`; improve test matrix
|
|
23
|
+
- [Tests] flesh out arrayLimit/arrayFormat tests (#107)
|
|
24
|
+
- [Tests] skip Object.create tests when null objects are not available
|
|
25
|
+
- [Tests] Turn on eslint for test files (#175)
|
|
3
26
|
|
|
4
27
|
## **6.2.1**
|
|
5
28
|
- [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values
|
package/README.md
CHANGED
|
@@ -39,11 +39,11 @@ assert.deepEqual(qs.parse('foo[bar]=baz'), {
|
|
|
39
39
|
});
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
When using the `plainObjects` option the parsed value is returned as a
|
|
42
|
+
When using the `plainObjects` option the parsed value is returned as a null object, created via `Object.create(null)` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
|
|
43
43
|
|
|
44
44
|
```javascript
|
|
45
|
-
var
|
|
46
|
-
assert.deepEqual(
|
|
45
|
+
var nullObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true });
|
|
46
|
+
assert.deepEqual(nullObject, { a: { hasOwnProperty: 'b' } });
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
By default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use `plainObjects` as mentioned above, or set `allowPrototypes` to `true` which will allow user input to overwrite those properties. *WARNING* It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. Always be careful with this option.
|
|
@@ -261,7 +261,7 @@ qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
|
|
|
261
261
|
// 'a=b&a=c&a=d'
|
|
262
262
|
```
|
|
263
263
|
|
|
264
|
-
You may use the `arrayFormat` option to specify the format of the output array
|
|
264
|
+
You may use the `arrayFormat` option to specify the format of the output array:
|
|
265
265
|
|
|
266
266
|
```javascript
|
|
267
267
|
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
|
|
@@ -272,12 +272,36 @@ qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
|
|
|
272
272
|
// 'a=b&a=c'
|
|
273
273
|
```
|
|
274
274
|
|
|
275
|
+
When objects are stringified, by default they use bracket notation:
|
|
276
|
+
|
|
277
|
+
```javascript
|
|
278
|
+
qs.stringify({ a: { b: { c: 'd', e: 'f' } } });
|
|
279
|
+
// 'a[b][c]=d&a[b][e]=f'
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
You may override this to use dot notation by setting the `allowDots` option to `true`:
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { allowDots: true });
|
|
286
|
+
// 'a.b.c=d&a.b.e=f'
|
|
287
|
+
```
|
|
288
|
+
|
|
275
289
|
Empty strings and null values will omit the value, but the equals sign (=) remains in place:
|
|
276
290
|
|
|
277
291
|
```javascript
|
|
278
292
|
assert.equal(qs.stringify({ a: '' }), 'a=');
|
|
279
293
|
```
|
|
280
294
|
|
|
295
|
+
Key with no values (such as an empty object or array) will return nothing:
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
assert.equal(qs.stringify({ a: [] }), '');
|
|
299
|
+
assert.equal(qs.stringify({ a: {} }), '');
|
|
300
|
+
assert.equal(qs.stringify({ a: [{}] }), '');
|
|
301
|
+
assert.equal(qs.stringify({ a: { b: []} }), '');
|
|
302
|
+
assert.equal(qs.stringify({ a: { b: {}} }), '');
|
|
303
|
+
```
|
|
304
|
+
|
|
281
305
|
Properties that are set to `undefined` will be omitted entirely:
|
|
282
306
|
|
|
283
307
|
```javascript
|
|
@@ -290,6 +314,26 @@ The delimiter may be overridden with stringify as well:
|
|
|
290
314
|
assert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d');
|
|
291
315
|
```
|
|
292
316
|
|
|
317
|
+
If you only want to override the serialization of `Date` objects, you can provide a `serializeDate` option:
|
|
318
|
+
|
|
319
|
+
```javascript
|
|
320
|
+
var date = new Date(7);
|
|
321
|
+
assert.equal(qs.stringify({ a: date }), 'a=1970-01-01T00:00:00.007Z'.replace(/:/g, '%3A'));
|
|
322
|
+
assert.equal(
|
|
323
|
+
qs.stringify({ a: date }, { serializeDate: function (d) { return d.getTime(); } }),
|
|
324
|
+
'a=7'
|
|
325
|
+
);
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
You may use the `sort` option to affect the order of parameter keys:
|
|
329
|
+
|
|
330
|
+
```javascript
|
|
331
|
+
function alphabeticalSort(a, b) {
|
|
332
|
+
return a.localeCompare(b);
|
|
333
|
+
}
|
|
334
|
+
assert.equal(qs.stringify({ a: 'c', z: 'y', b : 'f' }, { sort: alphabeticalSort }), 'a=c&b=f&z=y');
|
|
335
|
+
```
|
|
336
|
+
|
|
293
337
|
Finally, you can use the `filter` option to restrict which keys will be included in the stringified output.
|
|
294
338
|
If you pass a function, it will be called for each key to obtain the replacement value. Otherwise, if you
|
|
295
339
|
pass an array, it will be used to select properties and array indices for stringification:
|
|
@@ -374,3 +418,14 @@ var decoder = require('qs-iconv/decoder')('shift_jis');
|
|
|
374
418
|
var obj = qs.parse('a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I', { decoder: decoder });
|
|
375
419
|
assert.deepEqual(obj, { a: 'こんにちは!' });
|
|
376
420
|
```
|
|
421
|
+
|
|
422
|
+
### RFC 3986 and RFC 1738 space encoding
|
|
423
|
+
|
|
424
|
+
RFC3986 used as default option and encodes ' ' to *%20* which is backward compatible.
|
|
425
|
+
In the same time, output can be stringified as per RFC1738 with ' ' equal to '+'.
|
|
426
|
+
|
|
427
|
+
```
|
|
428
|
+
assert.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
|
|
429
|
+
assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c');
|
|
430
|
+
assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');
|
|
431
|
+
```
|
package/dist/qs.js
CHANGED
|
@@ -1,34 +1,56 @@
|
|
|
1
1
|
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Qs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var replace = String.prototype.replace;
|
|
5
|
+
var percentTwenties = /%20/g;
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
'default': 'RFC3986',
|
|
9
|
+
formatters: {
|
|
10
|
+
RFC1738: function (value) {
|
|
11
|
+
return replace.call(value, percentTwenties, '+');
|
|
12
|
+
},
|
|
13
|
+
RFC3986: function (value) {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
RFC1738: 'RFC1738',
|
|
18
|
+
RFC3986: 'RFC3986'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
},{}],2:[function(require,module,exports){
|
|
22
|
+
'use strict';
|
|
23
|
+
|
|
24
|
+
var stringify = require('./stringify');
|
|
25
|
+
var parse = require('./parse');
|
|
26
|
+
var formats = require('./formats');
|
|
27
|
+
|
|
28
|
+
module.exports = {
|
|
29
|
+
formats: formats,
|
|
30
|
+
parse: parse,
|
|
31
|
+
stringify: stringify
|
|
10
32
|
};
|
|
11
33
|
|
|
12
|
-
},{"./parse":
|
|
34
|
+
},{"./formats":1,"./parse":3,"./stringify":4}],3:[function(require,module,exports){
|
|
13
35
|
'use strict';
|
|
14
36
|
|
|
15
|
-
var
|
|
37
|
+
var utils = require('./utils');
|
|
16
38
|
|
|
17
39
|
var has = Object.prototype.hasOwnProperty;
|
|
18
40
|
|
|
19
41
|
var defaults = {
|
|
42
|
+
allowDots: false,
|
|
43
|
+
allowPrototypes: false,
|
|
44
|
+
arrayLimit: 20,
|
|
45
|
+
decoder: utils.decode,
|
|
20
46
|
delimiter: '&',
|
|
21
47
|
depth: 5,
|
|
22
|
-
arrayLimit: 20,
|
|
23
48
|
parameterLimit: 1000,
|
|
24
|
-
strictNullHandling: false,
|
|
25
49
|
plainObjects: false,
|
|
26
|
-
|
|
27
|
-
allowDots: false,
|
|
28
|
-
decoder: Utils.decode
|
|
50
|
+
strictNullHandling: false
|
|
29
51
|
};
|
|
30
52
|
|
|
31
|
-
var parseValues = function
|
|
53
|
+
var parseValues = function parseQueryStringValues(str, options) {
|
|
32
54
|
var obj = {};
|
|
33
55
|
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
|
|
34
56
|
|
|
@@ -54,7 +76,7 @@ var parseValues = function parseValues(str, options) {
|
|
|
54
76
|
return obj;
|
|
55
77
|
};
|
|
56
78
|
|
|
57
|
-
var parseObject = function
|
|
79
|
+
var parseObject = function parseObjectRecursive(chain, val, options) {
|
|
58
80
|
if (!chain.length) {
|
|
59
81
|
return val;
|
|
60
82
|
}
|
|
@@ -86,7 +108,7 @@ var parseObject = function parseObject(chain, val, options) {
|
|
|
86
108
|
return obj;
|
|
87
109
|
};
|
|
88
110
|
|
|
89
|
-
var parseKeys = function
|
|
111
|
+
var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
90
112
|
if (!givenKey) {
|
|
91
113
|
return;
|
|
92
114
|
}
|
|
@@ -147,7 +169,7 @@ module.exports = function (str, opts) {
|
|
|
147
169
|
throw new TypeError('Decoder has to be a function.');
|
|
148
170
|
}
|
|
149
171
|
|
|
150
|
-
options.delimiter = typeof options.delimiter === 'string' ||
|
|
172
|
+
options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
|
|
151
173
|
options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
|
|
152
174
|
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
|
|
153
175
|
options.parseArrays = options.parseArrays !== false;
|
|
@@ -171,43 +193,61 @@ module.exports = function (str, opts) {
|
|
|
171
193
|
for (var i = 0; i < keys.length; ++i) {
|
|
172
194
|
var key = keys[i];
|
|
173
195
|
var newObj = parseKeys(key, tempObj[key], options);
|
|
174
|
-
obj =
|
|
196
|
+
obj = utils.merge(obj, newObj, options);
|
|
175
197
|
}
|
|
176
198
|
|
|
177
|
-
return
|
|
199
|
+
return utils.compact(obj);
|
|
178
200
|
};
|
|
179
201
|
|
|
180
|
-
},{"./utils":
|
|
202
|
+
},{"./utils":5}],4:[function(require,module,exports){
|
|
181
203
|
'use strict';
|
|
182
204
|
|
|
183
|
-
var
|
|
205
|
+
var utils = require('./utils');
|
|
206
|
+
var formats = require('./formats');
|
|
184
207
|
|
|
185
208
|
var arrayPrefixGenerators = {
|
|
186
|
-
brackets: function brackets(prefix) {
|
|
209
|
+
brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
|
|
187
210
|
return prefix + '[]';
|
|
188
211
|
},
|
|
189
|
-
indices: function indices(prefix, key) {
|
|
212
|
+
indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
|
|
190
213
|
return prefix + '[' + key + ']';
|
|
191
214
|
},
|
|
192
|
-
repeat: function repeat(prefix) {
|
|
215
|
+
repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
|
|
193
216
|
return prefix;
|
|
194
217
|
}
|
|
195
218
|
};
|
|
196
219
|
|
|
220
|
+
var toISO = Date.prototype.toISOString;
|
|
221
|
+
|
|
197
222
|
var defaults = {
|
|
198
223
|
delimiter: '&',
|
|
199
|
-
strictNullHandling: false,
|
|
200
|
-
skipNulls: false,
|
|
201
224
|
encode: true,
|
|
202
|
-
encoder:
|
|
225
|
+
encoder: utils.encode,
|
|
226
|
+
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
|
|
227
|
+
return toISO.call(date);
|
|
228
|
+
},
|
|
229
|
+
skipNulls: false,
|
|
230
|
+
strictNullHandling: false
|
|
203
231
|
};
|
|
204
232
|
|
|
205
|
-
var stringify = function stringify(
|
|
233
|
+
var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
234
|
+
object,
|
|
235
|
+
prefix,
|
|
236
|
+
generateArrayPrefix,
|
|
237
|
+
strictNullHandling,
|
|
238
|
+
skipNulls,
|
|
239
|
+
encoder,
|
|
240
|
+
filter,
|
|
241
|
+
sort,
|
|
242
|
+
allowDots,
|
|
243
|
+
serializeDate,
|
|
244
|
+
formatter
|
|
245
|
+
) {
|
|
206
246
|
var obj = object;
|
|
207
247
|
if (typeof filter === 'function') {
|
|
208
248
|
obj = filter(prefix, obj);
|
|
209
249
|
} else if (obj instanceof Date) {
|
|
210
|
-
obj = obj
|
|
250
|
+
obj = serializeDate(obj);
|
|
211
251
|
} else if (obj === null) {
|
|
212
252
|
if (strictNullHandling) {
|
|
213
253
|
return encoder ? encoder(prefix) : prefix;
|
|
@@ -216,11 +256,11 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
|
|
|
216
256
|
obj = '';
|
|
217
257
|
}
|
|
218
258
|
|
|
219
|
-
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' ||
|
|
259
|
+
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
|
|
220
260
|
if (encoder) {
|
|
221
|
-
return [encoder(prefix) + '=' + encoder(obj)];
|
|
261
|
+
return [formatter(encoder(prefix)) + '=' + formatter(encoder(obj))];
|
|
222
262
|
}
|
|
223
|
-
return [prefix + '=' + String(obj)];
|
|
263
|
+
return [formatter(prefix) + '=' + formatter(String(obj))];
|
|
224
264
|
}
|
|
225
265
|
|
|
226
266
|
var values = [];
|
|
@@ -245,9 +285,33 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
|
|
|
245
285
|
}
|
|
246
286
|
|
|
247
287
|
if (Array.isArray(obj)) {
|
|
248
|
-
values = values.concat(stringify(
|
|
288
|
+
values = values.concat(stringify(
|
|
289
|
+
obj[key],
|
|
290
|
+
generateArrayPrefix(prefix, key),
|
|
291
|
+
generateArrayPrefix,
|
|
292
|
+
strictNullHandling,
|
|
293
|
+
skipNulls,
|
|
294
|
+
encoder,
|
|
295
|
+
filter,
|
|
296
|
+
sort,
|
|
297
|
+
allowDots,
|
|
298
|
+
serializeDate,
|
|
299
|
+
formatter
|
|
300
|
+
));
|
|
249
301
|
} else {
|
|
250
|
-
values = values.concat(stringify(
|
|
302
|
+
values = values.concat(stringify(
|
|
303
|
+
obj[key],
|
|
304
|
+
prefix + (allowDots ? '.' + key : '[' + key + ']'),
|
|
305
|
+
generateArrayPrefix,
|
|
306
|
+
strictNullHandling,
|
|
307
|
+
skipNulls,
|
|
308
|
+
encoder,
|
|
309
|
+
filter,
|
|
310
|
+
sort,
|
|
311
|
+
allowDots,
|
|
312
|
+
serializeDate,
|
|
313
|
+
formatter
|
|
314
|
+
));
|
|
251
315
|
}
|
|
252
316
|
}
|
|
253
317
|
|
|
@@ -257,6 +321,11 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
|
|
|
257
321
|
module.exports = function (object, opts) {
|
|
258
322
|
var obj = object;
|
|
259
323
|
var options = opts || {};
|
|
324
|
+
|
|
325
|
+
if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
|
|
326
|
+
throw new TypeError('Encoder has to be a function.');
|
|
327
|
+
}
|
|
328
|
+
|
|
260
329
|
var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
|
|
261
330
|
var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
|
|
262
331
|
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
|
|
@@ -264,18 +333,22 @@ module.exports = function (object, opts) {
|
|
|
264
333
|
var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
|
|
265
334
|
var sort = typeof options.sort === 'function' ? options.sort : null;
|
|
266
335
|
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
|
|
336
|
+
var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
|
|
337
|
+
if (typeof options.format === 'undefined') {
|
|
338
|
+
options.format = formats.default;
|
|
339
|
+
} else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
|
|
340
|
+
throw new TypeError('Unknown format option provided.');
|
|
341
|
+
}
|
|
342
|
+
var formatter = formats.formatters[options.format];
|
|
267
343
|
var objKeys;
|
|
268
344
|
var filter;
|
|
269
345
|
|
|
270
|
-
if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
|
|
271
|
-
throw new TypeError('Encoder has to be a function.');
|
|
272
|
-
}
|
|
273
|
-
|
|
274
346
|
if (typeof options.filter === 'function') {
|
|
275
347
|
filter = options.filter;
|
|
276
348
|
obj = filter('', obj);
|
|
277
349
|
} else if (Array.isArray(options.filter)) {
|
|
278
|
-
|
|
350
|
+
filter = options.filter;
|
|
351
|
+
objKeys = filter;
|
|
279
352
|
}
|
|
280
353
|
|
|
281
354
|
var keys = [];
|
|
@@ -310,26 +383,40 @@ module.exports = function (object, opts) {
|
|
|
310
383
|
continue;
|
|
311
384
|
}
|
|
312
385
|
|
|
313
|
-
keys = keys.concat(stringify(
|
|
386
|
+
keys = keys.concat(stringify(
|
|
387
|
+
obj[key],
|
|
388
|
+
key,
|
|
389
|
+
generateArrayPrefix,
|
|
390
|
+
strictNullHandling,
|
|
391
|
+
skipNulls,
|
|
392
|
+
encoder,
|
|
393
|
+
filter,
|
|
394
|
+
sort,
|
|
395
|
+
allowDots,
|
|
396
|
+
serializeDate,
|
|
397
|
+
formatter
|
|
398
|
+
));
|
|
314
399
|
}
|
|
315
400
|
|
|
316
401
|
return keys.join(delimiter);
|
|
317
402
|
};
|
|
318
403
|
|
|
319
|
-
},{"./utils":
|
|
404
|
+
},{"./formats":1,"./utils":5}],5:[function(require,module,exports){
|
|
320
405
|
'use strict';
|
|
321
406
|
|
|
407
|
+
var has = Object.prototype.hasOwnProperty;
|
|
408
|
+
|
|
322
409
|
var hexTable = (function () {
|
|
323
|
-
var array =
|
|
410
|
+
var array = [];
|
|
324
411
|
for (var i = 0; i < 256; ++i) {
|
|
325
|
-
array
|
|
412
|
+
array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
|
|
326
413
|
}
|
|
327
414
|
|
|
328
415
|
return array;
|
|
329
416
|
}());
|
|
330
417
|
|
|
331
418
|
exports.arrayToObject = function (source, options) {
|
|
332
|
-
var obj = options.plainObjects ? Object.create(null) : {};
|
|
419
|
+
var obj = options && options.plainObjects ? Object.create(null) : {};
|
|
333
420
|
for (var i = 0; i < source.length; ++i) {
|
|
334
421
|
if (typeof source[i] !== 'undefined') {
|
|
335
422
|
obj[i] = source[i];
|
|
@@ -365,6 +452,21 @@ exports.merge = function (target, source, options) {
|
|
|
365
452
|
mergeTarget = exports.arrayToObject(target, options);
|
|
366
453
|
}
|
|
367
454
|
|
|
455
|
+
if (Array.isArray(target) && Array.isArray(source)) {
|
|
456
|
+
source.forEach(function (item, i) {
|
|
457
|
+
if (has.call(target, i)) {
|
|
458
|
+
if (target[i] && typeof target[i] === 'object') {
|
|
459
|
+
target[i] = exports.merge(target[i], item, options);
|
|
460
|
+
} else {
|
|
461
|
+
target.push(item);
|
|
462
|
+
}
|
|
463
|
+
} else {
|
|
464
|
+
target[i] = item;
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
return target;
|
|
468
|
+
}
|
|
469
|
+
|
|
368
470
|
return Object.keys(source).reduce(function (acc, key) {
|
|
369
471
|
var value = source[key];
|
|
370
472
|
|
|
@@ -428,7 +530,7 @@ exports.encode = function (str) {
|
|
|
428
530
|
|
|
429
531
|
i += 1;
|
|
430
532
|
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
|
431
|
-
out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
|
|
533
|
+
out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; // eslint-disable-line max-len
|
|
432
534
|
}
|
|
433
535
|
|
|
434
536
|
return out;
|
|
@@ -462,10 +564,9 @@ exports.compact = function (obj, references) {
|
|
|
462
564
|
}
|
|
463
565
|
|
|
464
566
|
var keys = Object.keys(obj);
|
|
465
|
-
|
|
466
|
-
var key = keys[j];
|
|
567
|
+
keys.forEach(function (key) {
|
|
467
568
|
obj[key] = exports.compact(obj[key], refs);
|
|
468
|
-
}
|
|
569
|
+
});
|
|
469
570
|
|
|
470
571
|
return obj;
|
|
471
572
|
};
|
|
@@ -482,5 +583,5 @@ exports.isBuffer = function (obj) {
|
|
|
482
583
|
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
|
|
483
584
|
};
|
|
484
585
|
|
|
485
|
-
},{}]},{},[
|
|
586
|
+
},{}]},{},[2])(2)
|
|
486
587
|
});
|
package/lib/formats.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var replace = String.prototype.replace;
|
|
4
|
+
var percentTwenties = /%20/g;
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
'default': 'RFC3986',
|
|
8
|
+
formatters: {
|
|
9
|
+
RFC1738: function (value) {
|
|
10
|
+
return replace.call(value, percentTwenties, '+');
|
|
11
|
+
},
|
|
12
|
+
RFC3986: function (value) {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
RFC1738: 'RFC1738',
|
|
17
|
+
RFC3986: 'RFC3986'
|
|
18
|
+
};
|
package/lib/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var stringify = require('./stringify');
|
|
4
|
+
var parse = require('./parse');
|
|
5
|
+
var formats = require('./formats');
|
|
5
6
|
|
|
6
7
|
module.exports = {
|
|
7
|
-
|
|
8
|
-
parse:
|
|
8
|
+
formats: formats,
|
|
9
|
+
parse: parse,
|
|
10
|
+
stringify: stringify
|
|
9
11
|
};
|
package/lib/parse.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var utils = require('./utils');
|
|
4
4
|
|
|
5
5
|
var has = Object.prototype.hasOwnProperty;
|
|
6
6
|
|
|
7
7
|
var defaults = {
|
|
8
|
+
allowDots: false,
|
|
9
|
+
allowPrototypes: false,
|
|
10
|
+
arrayLimit: 20,
|
|
11
|
+
decoder: utils.decode,
|
|
8
12
|
delimiter: '&',
|
|
9
13
|
depth: 5,
|
|
10
|
-
arrayLimit: 20,
|
|
11
14
|
parameterLimit: 1000,
|
|
12
|
-
strictNullHandling: false,
|
|
13
15
|
plainObjects: false,
|
|
14
|
-
|
|
15
|
-
allowDots: false,
|
|
16
|
-
decoder: Utils.decode
|
|
16
|
+
strictNullHandling: false
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
var parseValues = function
|
|
19
|
+
var parseValues = function parseQueryStringValues(str, options) {
|
|
20
20
|
var obj = {};
|
|
21
21
|
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
|
|
22
22
|
|
|
@@ -42,7 +42,7 @@ var parseValues = function parseValues(str, options) {
|
|
|
42
42
|
return obj;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
var parseObject = function
|
|
45
|
+
var parseObject = function parseObjectRecursive(chain, val, options) {
|
|
46
46
|
if (!chain.length) {
|
|
47
47
|
return val;
|
|
48
48
|
}
|
|
@@ -74,7 +74,7 @@ var parseObject = function parseObject(chain, val, options) {
|
|
|
74
74
|
return obj;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
var parseKeys = function
|
|
77
|
+
var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
78
78
|
if (!givenKey) {
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
@@ -135,7 +135,7 @@ module.exports = function (str, opts) {
|
|
|
135
135
|
throw new TypeError('Decoder has to be a function.');
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
options.delimiter = typeof options.delimiter === 'string' ||
|
|
138
|
+
options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
|
|
139
139
|
options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
|
|
140
140
|
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
|
|
141
141
|
options.parseArrays = options.parseArrays !== false;
|
|
@@ -159,8 +159,8 @@ module.exports = function (str, opts) {
|
|
|
159
159
|
for (var i = 0; i < keys.length; ++i) {
|
|
160
160
|
var key = keys[i];
|
|
161
161
|
var newObj = parseKeys(key, tempObj[key], options);
|
|
162
|
-
obj =
|
|
162
|
+
obj = utils.merge(obj, newObj, options);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
return
|
|
165
|
+
return utils.compact(obj);
|
|
166
166
|
};
|