diff --git a/CHANGELOG.md b/CHANGELOG.md index 017c2b3b..37b1d3f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## **6.11.0 +- [New] [Fix] `stringify`: revert 0e903c0; add `commaRoundTrip` option (#442) +- [readme] fix version badge + ## **6.10.5** - [Fix] `stringify`: with `arrayFormat: comma`, properly include an explicit `[]` on a single-item array (#434) diff --git a/dist/qs.js b/dist/qs.js index 94baf8ff..1c620a48 100644 --- a/dist/qs.js +++ b/dist/qs.js @@ -366,6 +366,7 @@ var stringify = function stringify( object, prefix, generateArrayPrefix, + commaRoundTrip, strictNullHandling, skipNulls, encoder, @@ -430,7 +431,7 @@ var stringify = function stringify( for (var i = 0; i < valuesArray.length; ++i) { valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format)); } - return [formatter(keyValue) + '=' + valuesJoined]; + return [formatter(keyValue) + (commaRoundTrip && isArray(obj) && valuesArray.length === 1 ? '[]' : '') + '=' + valuesJoined]; } return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; } @@ -454,6 +455,8 @@ var stringify = function stringify( objKeys = sort ? keys.sort(sort) : keys; } + var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? prefix + '[]' : prefix; + for (var j = 0; j < objKeys.length; ++j) { var key = objKeys[j]; var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key]; @@ -463,8 +466,8 @@ var stringify = function stringify( } var keyPrefix = isArray(obj) - ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix - : prefix + (allowDots ? '.' + key : '[' + key + ']'); + ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, key) : adjustedPrefix + : adjustedPrefix + (allowDots ? '.' + key : '[' + key + ']'); sideChannel.set(object, step); var valueSideChannel = getSideChannel(); @@ -473,6 +476,7 @@ var stringify = function stringify( value, keyPrefix, generateArrayPrefix, + commaRoundTrip, strictNullHandling, skipNulls, encoder, @@ -569,6 +573,10 @@ module.exports = function (object, opts) { } var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; + if (opts && 'commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') { + throw new TypeError('`commaRoundTrip` must be a boolean, or absent'); + } + var commaRoundTrip = generateArrayPrefix === 'comma' && opts && opts.commaRoundTrip; if (!objKeys) { objKeys = Object.keys(obj); @@ -589,6 +597,7 @@ module.exports = function (object, opts) { obj[key], key, generateArrayPrefix, + commaRoundTrip, options.strictNullHandling, options.skipNulls, options.encode ? options.encoder : null, @@ -1469,8 +1478,9 @@ function addNumericSeparator(num, str) { return $replace.call(str, sepRegex, '$&_'); } -var inspectCustom = require('./util.inspect').custom; -var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null; +var utilInspect = require('./util.inspect'); +var inspectCustom = utilInspect.custom; +var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null; module.exports = function inspect_(obj, options, depth, seen) { var opts = options || {}; @@ -1560,7 +1570,7 @@ module.exports = function inspect_(obj, options, depth, seen) { return inspect_(value, opts, depth + 1, seen); } - if (typeof obj === 'function') { + if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable var name = nameOf(obj); var keys = arrObjKeys(obj, inspect); return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : ''); @@ -1590,15 +1600,15 @@ module.exports = function inspect_(obj, options, depth, seen) { } if (isError(obj)) { var parts = arrObjKeys(obj, inspect); - if ('cause' in obj && !isEnumerable.call(obj, 'cause')) { + if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) { return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }'; } if (parts.length === 0) { return '[' + String(obj) + ']'; } return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }'; } if (typeof obj === 'object' && customInspect) { - if (inspectSymbol && typeof obj[inspectSymbol] === 'function') { - return obj[inspectSymbol](); + if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) { + return utilInspect(obj, { depth: maxDepth - depth }); } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') { return obj.inspect(); } diff --git a/package.json b/package.json index d07ebd9b..2ff42f37 100644 --- a/package.json +++ b/package.json @@ -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.10.5", + "version": "6.11.0", "repository": { "type": "git", "url": "https://github.com/ljharb/qs.git"