Skip to content

Commit 8aa9c26

Browse files
committed
v6.3.0
1 parent d4fb8e2 commit 8aa9c26

File tree

4 files changed

+140
-38
lines changed

4 files changed

+140
-38
lines changed

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## **6.3.0**
2+
- [New] Add support for RFC 1738 (#174, #173)
3+
- [New] `stringify`: Add `serializeDate` option to customize Date serialization (#159)
4+
- [Fix] ensure `utils.merge` handles merging two arrays
5+
- [Refactor] only constructors should be capitalized
6+
- [Refactor] capitalized var names are for constructors only
7+
- [Refactor] avoid using a sparse array
8+
- [Robustness] `formats`: cache `String#replace`
9+
- [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`; add `safe-publish-latest`
10+
- [Tests] up to `node` `v6.8`, `v4.6`; improve test matrix
11+
- [Tests] flesh out arrayLimit/arrayFormat tests (#107)
12+
- [Tests] skip Object.create tests when null objects are not available
13+
- [Tests] Turn on eslint for test files (#175)
14+
115
## **6.2.1**
216
- [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values
317
- [Refactor] Be explicit and use `Object.prototype.hasOwnProperty.call`

component.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "qs",
33
"repository": "hapijs/qs",
44
"description": "query-string parser / stringifier with nesting support",
5-
"version": "6.1.0",
5+
"version": "6.3.0",
66
"keywords": ["querystring", "query", "parser"],
77
"main": "lib/index.js",
88
"scripts": [

dist/qs.js

+124-36
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,53 @@
11
(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){
22
'use strict';
33

4-
var Stringify = require('./stringify');
5-
var Parse = require('./parse');
4+
var replace = String.prototype.replace;
5+
var percentTwenties = /%20/g;
66

77
module.exports = {
8-
stringify: Stringify,
9-
parse: Parse
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
1032
};
1133

12-
},{"./parse":2,"./stringify":3}],2:[function(require,module,exports){
34+
},{"./formats":1,"./parse":3,"./stringify":4}],3:[function(require,module,exports){
1335
'use strict';
1436

15-
var Utils = require('./utils');
37+
var utils = require('./utils');
1638

1739
var has = Object.prototype.hasOwnProperty;
1840

1941
var defaults = {
42+
allowDots: false,
43+
allowPrototypes: false,
44+
arrayLimit: 20,
45+
decoder: utils.decode,
2046
delimiter: '&',
2147
depth: 5,
22-
arrayLimit: 20,
2348
parameterLimit: 1000,
24-
strictNullHandling: false,
2549
plainObjects: false,
26-
allowPrototypes: false,
27-
allowDots: false,
28-
decoder: Utils.decode
50+
strictNullHandling: false
2951
};
3052

3153
var parseValues = function parseValues(str, options) {
@@ -147,7 +169,7 @@ module.exports = function (str, opts) {
147169
throw new TypeError('Decoder has to be a function.');
148170
}
149171

150-
options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
172+
options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
151173
options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
152174
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
153175
options.parseArrays = options.parseArrays !== false;
@@ -171,16 +193,17 @@ module.exports = function (str, opts) {
171193
for (var i = 0; i < keys.length; ++i) {
172194
var key = keys[i];
173195
var newObj = parseKeys(key, tempObj[key], options);
174-
obj = Utils.merge(obj, newObj, options);
196+
obj = utils.merge(obj, newObj, options);
175197
}
176198

177-
return Utils.compact(obj);
199+
return utils.compact(obj);
178200
};
179201

180-
},{"./utils":4}],3:[function(require,module,exports){
202+
},{"./utils":5}],4:[function(require,module,exports){
181203
'use strict';
182204

183-
var Utils = require('./utils');
205+
var utils = require('./utils');
206+
var formats = require('./formats');
184207

185208
var arrayPrefixGenerators = {
186209
brackets: function brackets(prefix) {
@@ -194,20 +217,25 @@ var arrayPrefixGenerators = {
194217
}
195218
};
196219

220+
var toISO = Date.prototype.toISOString;
221+
197222
var defaults = {
198223
delimiter: '&',
199-
strictNullHandling: false,
200-
skipNulls: false,
201224
encode: true,
202-
encoder: Utils.encode
225+
encoder: utils.encode,
226+
serializeDate: function serializeDate(date) {
227+
return toISO.call(date);
228+
},
229+
skipNulls: false,
230+
strictNullHandling: false
203231
};
204232

205-
var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
233+
var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots, serializeDate, formatter) {
206234
var obj = object;
207235
if (typeof filter === 'function') {
208236
obj = filter(prefix, obj);
209237
} else if (obj instanceof Date) {
210-
obj = obj.toISOString();
238+
obj = serializeDate(obj);
211239
} else if (obj === null) {
212240
if (strictNullHandling) {
213241
return encoder ? encoder(prefix) : prefix;
@@ -216,11 +244,11 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
216244
obj = '';
217245
}
218246

219-
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
247+
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
220248
if (encoder) {
221-
return [encoder(prefix) + '=' + encoder(obj)];
249+
return [formatter(encoder(prefix)) + '=' + formatter(encoder(obj))];
222250
}
223-
return [prefix + '=' + String(obj)];
251+
return [formatter(prefix) + '=' + formatter(String(obj))];
224252
}
225253

226254
var values = [];
@@ -245,9 +273,33 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
245273
}
246274

247275
if (Array.isArray(obj)) {
248-
values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
276+
values = values.concat(stringify(
277+
obj[key],
278+
generateArrayPrefix(prefix, key),
279+
generateArrayPrefix,
280+
strictNullHandling,
281+
skipNulls,
282+
encoder,
283+
filter,
284+
sort,
285+
allowDots,
286+
serializeDate,
287+
formatter
288+
));
249289
} else {
250-
values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
290+
values = values.concat(stringify(
291+
obj[key],
292+
prefix + (allowDots ? '.' + key : '[' + key + ']'),
293+
generateArrayPrefix,
294+
strictNullHandling,
295+
skipNulls,
296+
encoder,
297+
filter,
298+
sort,
299+
allowDots,
300+
serializeDate,
301+
formatter
302+
));
251303
}
252304
}
253305

@@ -264,6 +316,13 @@ module.exports = function (object, opts) {
264316
var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
265317
var sort = typeof options.sort === 'function' ? options.sort : null;
266318
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
319+
var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
320+
if (typeof options.format === 'undefined') {
321+
options.format = formats.default;
322+
} else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
323+
throw new TypeError('Unknown format option provided.');
324+
}
325+
var formatter = formats.formatters[options.format];
267326
var objKeys;
268327
var filter;
269328

@@ -275,7 +334,8 @@ module.exports = function (object, opts) {
275334
filter = options.filter;
276335
obj = filter('', obj);
277336
} else if (Array.isArray(options.filter)) {
278-
objKeys = filter = options.filter;
337+
filter = options.filter;
338+
objKeys = filter;
279339
}
280340

281341
var keys = [];
@@ -310,26 +370,40 @@ module.exports = function (object, opts) {
310370
continue;
311371
}
312372

313-
keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
373+
keys = keys.concat(stringify(
374+
obj[key],
375+
key,
376+
generateArrayPrefix,
377+
strictNullHandling,
378+
skipNulls,
379+
encoder,
380+
filter,
381+
sort,
382+
allowDots,
383+
serializeDate,
384+
formatter
385+
));
314386
}
315387

316388
return keys.join(delimiter);
317389
};
318390

319-
},{"./utils":4}],4:[function(require,module,exports){
391+
},{"./formats":1,"./utils":5}],5:[function(require,module,exports){
320392
'use strict';
321393

394+
var has = Object.prototype.hasOwnProperty;
395+
322396
var hexTable = (function () {
323-
var array = new Array(256);
397+
var array = [];
324398
for (var i = 0; i < 256; ++i) {
325-
array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
399+
array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
326400
}
327401

328402
return array;
329403
}());
330404

331405
exports.arrayToObject = function (source, options) {
332-
var obj = options.plainObjects ? Object.create(null) : {};
406+
var obj = options && options.plainObjects ? Object.create(null) : {};
333407
for (var i = 0; i < source.length; ++i) {
334408
if (typeof source[i] !== 'undefined') {
335409
obj[i] = source[i];
@@ -365,6 +439,21 @@ exports.merge = function (target, source, options) {
365439
mergeTarget = exports.arrayToObject(target, options);
366440
}
367441

442+
if (Array.isArray(target) && Array.isArray(source)) {
443+
source.forEach(function (item, i) {
444+
if (has.call(target, i)) {
445+
if (target[i] && typeof target[i] === 'object') {
446+
target[i] = exports.merge(target[i], item, options);
447+
} else {
448+
target.push(item);
449+
}
450+
} else {
451+
target[i] = item;
452+
}
453+
});
454+
return target;
455+
}
456+
368457
return Object.keys(source).reduce(function (acc, key) {
369458
var value = source[key];
370459

@@ -462,10 +551,9 @@ exports.compact = function (obj, references) {
462551
}
463552

464553
var keys = Object.keys(obj);
465-
for (var j = 0; j < keys.length; ++j) {
466-
var key = keys[j];
554+
keys.forEach(function (key) {
467555
obj[key] = exports.compact(obj[key], refs);
468-
}
556+
});
469557

470558
return obj;
471559
};
@@ -482,5 +570,5 @@ exports.isBuffer = function (obj) {
482570
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
483571
};
484572

485-
},{}]},{},[1])(1)
573+
},{}]},{},[2])(2)
486574
});

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "qs",
33
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
44
"homepage": "https://github.com/ljharb/qs",
5-
"version": "6.2.1",
5+
"version": "6.3.0",
66
"repository": {
77
"type": "git",
88
"url": "https://github.com/ljharb/qs.git"

0 commit comments

Comments
 (0)