qs 6.2.4 → 6.3.3

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/lib/parse.js CHANGED
@@ -1,22 +1,22 @@
1
1
  'use strict';
2
2
 
3
- var Utils = require('./utils');
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
- allowPrototypes: false,
15
- allowDots: false,
16
- decoder: Utils.decode
16
+ strictNullHandling: false
17
17
  };
18
18
 
19
- var parseValues = function parseValues(str, options) {
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 parseObject(chain, val, options) {
45
+ var parseObject = function parseObjectRecursive(chain, val, options) {
46
46
  if (!chain.length) {
47
47
  return val;
48
48
  }
@@ -76,7 +76,7 @@ var parseObject = function parseObject(chain, val, options) {
76
76
  return obj;
77
77
  };
78
78
 
79
- var parseKeys = function parseKeys(givenKey, val, options) {
79
+ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
80
80
  if (!givenKey) {
81
81
  return;
82
82
  }
@@ -137,7 +137,7 @@ module.exports = function (str, opts) {
137
137
  throw new TypeError('Decoder has to be a function.');
138
138
  }
139
139
 
140
- options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
140
+ options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
141
141
  options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
142
142
  options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
143
143
  options.parseArrays = options.parseArrays !== false;
@@ -161,8 +161,8 @@ module.exports = function (str, opts) {
161
161
  for (var i = 0; i < keys.length; ++i) {
162
162
  var key = keys[i];
163
163
  var newObj = parseKeys(key, tempObj[key], options);
164
- obj = Utils.merge(obj, newObj, options);
164
+ obj = utils.merge(obj, newObj, options);
165
165
  }
166
166
 
167
- return Utils.compact(obj);
167
+ return utils.compact(obj);
168
168
  };
package/lib/stringify.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var Utils = require('./utils');
3
+ var utils = require('./utils');
4
+ var formats = require('./formats');
4
5
 
5
6
  var arrayPrefixGenerators = {
6
7
  brackets: function brackets(prefix) {
@@ -14,15 +15,25 @@ var arrayPrefixGenerators = {
14
15
  }
15
16
  };
16
17
 
18
+ var isArray = Array.isArray;
19
+ var push = Array.prototype.push;
20
+ var pushToArray = function (arr, valueOrArray) {
21
+ push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
22
+ };
23
+
24
+ var toISO = Date.prototype.toISOString;
25
+
17
26
  var defaults = {
18
27
  delimiter: '&',
19
- strictNullHandling: false,
20
- skipNulls: false,
21
28
  encode: true,
22
- encoder: Utils.encode
29
+ encoder: utils.encode,
30
+ serializeDate: function serializeDate(date) {
31
+ return toISO.call(date);
32
+ },
33
+ skipNulls: false,
34
+ strictNullHandling: false
23
35
  };
24
36
 
25
- var isArray = Array.isArray;
26
37
  var stringify = function stringify(
27
38
  object,
28
39
  prefix,
@@ -32,14 +43,18 @@ var stringify = function stringify(
32
43
  encoder,
33
44
  filter,
34
45
  sort,
35
- allowDots
46
+ allowDots,
47
+ serializeDate,
48
+ formatter
36
49
  ) {
37
50
  var obj = object;
38
51
  if (typeof filter === 'function') {
39
52
  obj = filter(prefix, obj);
40
53
  } else if (obj instanceof Date) {
41
- obj = obj.toISOString();
42
- } else if (obj === null) {
54
+ obj = serializeDate(obj);
55
+ }
56
+
57
+ if (obj === null) {
43
58
  if (strictNullHandling) {
44
59
  return encoder ? encoder(prefix) : prefix;
45
60
  }
@@ -47,11 +62,11 @@ var stringify = function stringify(
47
62
  obj = '';
48
63
  }
49
64
 
50
- if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
65
+ if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
51
66
  if (encoder) {
52
- return [encoder(prefix) + '=' + encoder(obj)];
67
+ return [formatter(encoder(prefix)) + '=' + formatter(encoder(obj))];
53
68
  }
54
- return [prefix + '=' + String(obj)];
69
+ return [formatter(prefix) + '=' + formatter(String(obj))];
55
70
  }
56
71
 
57
72
  var values = [];
@@ -76,7 +91,7 @@ var stringify = function stringify(
76
91
  }
77
92
 
78
93
  if (isArray(obj)) {
79
- values = values.concat(stringify(
94
+ pushToArray(values, stringify(
80
95
  obj[key],
81
96
  generateArrayPrefix(prefix, key),
82
97
  generateArrayPrefix,
@@ -85,10 +100,12 @@ var stringify = function stringify(
85
100
  encoder,
86
101
  filter,
87
102
  sort,
88
- allowDots
103
+ allowDots,
104
+ serializeDate,
105
+ formatter
89
106
  ));
90
107
  } else {
91
- values = values.concat(stringify(
108
+ pushToArray(values, stringify(
92
109
  obj[key],
93
110
  prefix + (allowDots ? '.' + key : '[' + key + ']'),
94
111
  generateArrayPrefix,
@@ -97,7 +114,9 @@ var stringify = function stringify(
97
114
  encoder,
98
115
  filter,
99
116
  sort,
100
- allowDots
117
+ allowDots,
118
+ serializeDate,
119
+ formatter
101
120
  ));
102
121
  }
103
122
  }
@@ -108,6 +127,11 @@ var stringify = function stringify(
108
127
  module.exports = function (object, opts) {
109
128
  var obj = object;
110
129
  var options = opts || {};
130
+
131
+ if (options.encoder !== null && typeof options.encoder !== 'undefined' && typeof options.encoder !== 'function') {
132
+ throw new TypeError('Encoder has to be a function.');
133
+ }
134
+
111
135
  var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
112
136
  var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
113
137
  var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
@@ -115,19 +139,22 @@ module.exports = function (object, opts) {
115
139
  var encoder = encode ? typeof options.encoder === 'function' ? options.encoder : defaults.encoder : null;
116
140
  var sort = typeof options.sort === 'function' ? options.sort : null;
117
141
  var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
142
+ var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
143
+ if (typeof options.format === 'undefined') {
144
+ options.format = formats['default'];
145
+ } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
146
+ throw new TypeError('Unknown format option provided.');
147
+ }
148
+ var formatter = formats.formatters[options.format];
118
149
  var objKeys;
119
150
  var filter;
120
151
 
121
- if (options.encoder !== null && typeof options.encoder !== 'undefined' && typeof options.encoder !== 'function') {
122
- throw new TypeError('Encoder has to be a function.');
123
- }
124
-
125
152
  if (typeof options.filter === 'function') {
126
153
  filter = options.filter;
127
154
  obj = filter('', obj);
128
155
  } else if (isArray(options.filter)) {
129
- objKeys = options.filter;
130
156
  filter = options.filter;
157
+ objKeys = filter;
131
158
  }
132
159
 
133
160
  var keys = [];
@@ -161,8 +188,7 @@ module.exports = function (object, opts) {
161
188
  if (skipNulls && obj[key] === null) {
162
189
  continue;
163
190
  }
164
-
165
- keys = keys.concat(stringify(
191
+ pushToArray(keys, stringify(
166
192
  obj[key],
167
193
  key,
168
194
  generateArrayPrefix,
@@ -171,7 +197,9 @@ module.exports = function (object, opts) {
171
197
  encoder,
172
198
  filter,
173
199
  sort,
174
- allowDots
200
+ allowDots,
201
+ serializeDate,
202
+ formatter
175
203
  ));
176
204
  }
177
205
 
package/lib/utils.js CHANGED
@@ -1,16 +1,16 @@
1
1
  'use strict';
2
2
 
3
+ var has = Object.prototype.hasOwnProperty;
4
+
3
5
  var hexTable = (function () {
4
- var array = new Array(256);
6
+ var array = [];
5
7
  for (var i = 0; i < 256; ++i) {
6
- array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
8
+ array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
7
9
  }
8
10
 
9
11
  return array;
10
12
  }());
11
13
 
12
- var has = Object.prototype.hasOwnProperty;
13
-
14
14
  exports.arrayToObject = function (source, options) {
15
15
  var obj = options && options.plainObjects ? Object.create(null) : {};
16
16
  for (var i = 0; i < source.length; ++i) {
@@ -22,27 +22,13 @@ exports.arrayToObject = function (source, options) {
22
22
  return obj;
23
23
  };
24
24
 
25
- var isArray = Array.isArray;
26
-
27
- var arrayToObject = function arrayToObject(source, options) {
28
- var obj = options && options.plainObjects ? Object.create(null) : {};
29
- for (var i = 0; i < source.length; ++i) {
30
- if (typeof source[i] !== 'undefined') {
31
- obj[i] = source[i];
32
- }
33
- }
34
-
35
- return obj;
36
- };
37
-
38
- exports.merge = function merge(target, source, options) {
39
- /* eslint no-param-reassign: 0 */
25
+ exports.merge = function (target, source, options) {
40
26
  if (!source) {
41
27
  return target;
42
28
  }
43
29
 
44
30
  if (typeof source !== 'object') {
45
- if (isArray(target)) {
31
+ if (Array.isArray(target)) {
46
32
  target.push(source);
47
33
  } else if (target && typeof target === 'object') {
48
34
  if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
@@ -60,16 +46,15 @@ exports.merge = function merge(target, source, options) {
60
46
  }
61
47
 
62
48
  var mergeTarget = target;
63
- if (isArray(target) && !isArray(source)) {
64
- mergeTarget = arrayToObject(target, options);
49
+ if (Array.isArray(target) && !Array.isArray(source)) {
50
+ mergeTarget = exports.arrayToObject(target, options);
65
51
  }
66
52
 
67
- if (isArray(target) && isArray(source)) {
53
+ if (Array.isArray(target) && Array.isArray(source)) {
68
54
  source.forEach(function (item, i) {
69
55
  if (has.call(target, i)) {
70
- var targetItem = target[i];
71
- if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
72
- target[i] = merge(targetItem, item, options);
56
+ if (target[i] && typeof target[i] === 'object') {
57
+ target[i] = exports.merge(target[i], item, options);
73
58
  } else {
74
59
  target.push(item);
75
60
  }
@@ -83,8 +68,8 @@ exports.merge = function merge(target, source, options) {
83
68
  return Object.keys(source).reduce(function (acc, key) {
84
69
  var value = source[key];
85
70
 
86
- if (has.call(acc, key)) {
87
- acc[key] = merge(acc[key], value, options);
71
+ if (Object.prototype.hasOwnProperty.call(acc, key)) {
72
+ acc[key] = exports.merge(acc[key], value, options);
88
73
  } else {
89
74
  acc[key] = value;
90
75
  }
@@ -166,7 +151,7 @@ exports.compact = function (obj, references) {
166
151
 
167
152
  refs.push(obj);
168
153
 
169
- if (isArray(obj)) {
154
+ if (Array.isArray(obj)) {
170
155
  var compacted = [];
171
156
 
172
157
  for (var i = 0; i < obj.length; ++i) {
@@ -181,10 +166,9 @@ exports.compact = function (obj, references) {
181
166
  }
182
167
 
183
168
  var keys = Object.keys(obj);
184
- for (var j = 0; j < keys.length; ++j) {
185
- var key = keys[j];
169
+ keys.forEach(function (key) {
186
170
  obj[key] = exports.compact(obj[key], refs);
187
- }
171
+ });
188
172
 
189
173
  return obj;
190
174
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "qs",
3
3
  "description": "A querystring parser that supports nesting and arrays, with a depth limit",
4
4
  "homepage": "https://github.com/ljharb/qs",
5
- "version": "6.2.4",
5
+ "version": "6.3.3",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/ljharb/qs.git"
package/test/parse.js CHANGED
@@ -65,8 +65,15 @@ test('parse()', function (t) {
65
65
  st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
66
66
  st.deepEqual(qs.parse('a[0]=b&a=c'), { a: ['b', 'c'] });
67
67
  st.deepEqual(qs.parse('a=b&a[0]=c'), { a: ['b', 'c'] });
68
- st.deepEqual(qs.parse('a[1]=b&a=c'), { a: ['b', 'c'] });
69
- st.deepEqual(qs.parse('a=b&a[1]=c'), { a: ['b', 'c'] });
68
+
69
+ st.deepEqual(qs.parse('a[1]=b&a=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
70
+ st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
71
+ st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
72
+
73
+ st.deepEqual(qs.parse('a=b&a[1]=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
74
+ st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
75
+ st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] });
76
+
70
77
  st.end();
71
78
  });
72
79
 
@@ -79,13 +86,15 @@ test('parse()', function (t) {
79
86
  t.test('allows to specify array indices', function (st) {
80
87
  st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] });
81
88
  st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] });
89
+ st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 20 }), { a: ['c'] });
90
+ st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 0 }), { a: { 1: 'c' } });
82
91
  st.deepEqual(qs.parse('a[1]=c'), { a: ['c'] });
83
92
  st.end();
84
93
  });
85
94
 
86
- t.test('limits specific array indices to 20', function (st) {
87
- st.deepEqual(qs.parse('a[20]=a'), { a: ['a'] });
88
- st.deepEqual(qs.parse('a[21]=a'), { a: { 21: 'a' } });
95
+ t.test('limits specific array indices to arrayLimit', function (st) {
96
+ st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: ['a'] });
97
+ st.deepEqual(qs.parse('a[21]=a', { arrayLimit: 20 }), { a: { 21: 'a' } });
89
98
  st.end();
90
99
  });
91
100
 
@@ -208,10 +217,10 @@ test('parse()', function (t) {
208
217
  });
209
218
 
210
219
  t.test('compacts sparse arrays', function (st) {
211
- st.deepEqual(qs.parse('a[10]=1&a[2]=2'), { a: ['2', '1'] });
212
- st.deepEqual(qs.parse('a[1][b][2][c]=1'), { a: [{ b: [{ c: '1' }] }] });
213
- st.deepEqual(qs.parse('a[1][2][3][c]=1'), { a: [[[{ c: '1' }]]] });
214
- st.deepEqual(qs.parse('a[1][2][3][c][1]=1'), { a: [[[{ c: ['1'] }]]] });
220
+ st.deepEqual(qs.parse('a[10]=1&a[2]=2', { arrayLimit: 20 }), { a: ['2', '1'] });
221
+ st.deepEqual(qs.parse('a[1][b][2][c]=1', { arrayLimit: 20 }), { a: [{ b: [{ c: '1' }] }] });
222
+ st.deepEqual(qs.parse('a[1][2][3][c]=1', { arrayLimit: 20 }), { a: [[[{ c: '1' }]]] });
223
+ st.deepEqual(qs.parse('a[1][2][3][c][1]=1', { arrayLimit: 20 }), { a: [[[{ c: ['1'] }]]] });
215
224
  st.end();
216
225
  });
217
226
 
@@ -240,7 +249,9 @@ test('parse()', function (t) {
240
249
  str = str + '&' + str;
241
250
  }
242
251
 
243
- st.doesNotThrow(function () { qs.parse(str); });
252
+ st.doesNotThrow(function () {
253
+ qs.parse(str);
254
+ });
244
255
 
245
256
  st.end();
246
257
  });
@@ -385,7 +396,7 @@ test('parse()', function (t) {
385
396
  st.end();
386
397
  });
387
398
 
388
- t.test('parses plain objects correctly', function (st) {
399
+ t.test('parses null objects correctly', { skip: !Object.create }, function (st) {
389
400
  var a = Object.create(null);
390
401
  a.b = 'c';
391
402
 
@@ -545,7 +556,7 @@ test('parse()', function (t) {
545
556
  st.deepEqual(qs.parse(null, { plainObjects: true }), Object.create(null));
546
557
  var expectedArray = Object.create(null);
547
558
  expectedArray.a = Object.create(null);
548
- expectedArray.a['0'] = 'b';
559
+ expectedArray.a[0] = 'b';
549
560
  expectedArray.a.c = 'd';
550
561
  st.deepEqual(qs.parse('a[]=b&a[c]=d', { plainObjects: true }), expectedArray);
551
562
  st.end();
@@ -556,11 +567,10 @@ test('parse()', function (t) {
556
567
  decoder: function (str) {
557
568
  var reg = /%([0-9A-F]{2})/ig;
558
569
  var result = [];
559
- var parts;
560
- // var last = 0;
561
- while ((parts = reg.exec(str))) {
570
+ var parts = reg.exec(str);
571
+ while (parts) {
562
572
  result.push(parseInt(parts[1], 16));
563
- // last = parts.index + parts[0].length;
573
+ parts = reg.exec(str);
564
574
  }
565
575
  return iconv.decode(SaferBuffer.from(result), 'shift_jis').toString();
566
576
  }