qs 6.1.2 → 6.2.0

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 CHANGED
@@ -4,10 +4,12 @@
4
4
  "extends": "@ljharb",
5
5
 
6
6
  "rules": {
7
- "complexity": [2, 19],
7
+ "complexity": [2, 22],
8
8
  "consistent-return": [1],
9
+ "id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
10
+ "indent": [2, 4],
9
11
  "max-params": [2, 9],
10
- "max-statements": [2, 33],
12
+ "max-statements": [2, 36],
11
13
  "no-extra-parens": [1],
12
14
  "no-continue": [1],
13
15
  "no-magic-numbers": 0,
package/.jscs.json ADDED
@@ -0,0 +1,176 @@
1
+ {
2
+ "es3": true,
3
+
4
+ "additionalRules": [],
5
+
6
+ "requireSemicolons": true,
7
+
8
+ "disallowMultipleSpaces": true,
9
+
10
+ "disallowIdentifierNames": [],
11
+
12
+ "requireCurlyBraces": {
13
+ "allExcept": [],
14
+ "keywords": ["if", "else", "for", "while", "do", "try", "catch"]
15
+ },
16
+
17
+ "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"],
18
+
19
+ "disallowSpaceAfterKeywords": [],
20
+
21
+ "disallowSpaceBeforeComma": true,
22
+ "disallowSpaceAfterComma": false,
23
+ "disallowSpaceBeforeSemicolon": true,
24
+
25
+ "disallowNodeTypes": [
26
+ "DebuggerStatement",
27
+ "ForInStatement",
28
+ "LabeledStatement",
29
+ "SwitchCase",
30
+ "SwitchStatement",
31
+ "WithStatement"
32
+ ],
33
+
34
+ "requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] },
35
+
36
+ "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true },
37
+ "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
38
+ "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
39
+ "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
40
+ "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true },
41
+
42
+ "requireSpaceBetweenArguments": true,
43
+
44
+ "disallowSpacesInsideParentheses": true,
45
+
46
+ "disallowSpacesInsideArrayBrackets": true,
47
+
48
+ "disallowQuotedKeysInObjects": { "allExcept": ["reserved"] },
49
+
50
+ "disallowSpaceAfterObjectKeys": true,
51
+
52
+ "requireCommaBeforeLineBreak": true,
53
+
54
+ "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
55
+ "requireSpaceAfterPrefixUnaryOperators": [],
56
+
57
+ "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
58
+ "requireSpaceBeforePostfixUnaryOperators": [],
59
+
60
+ "disallowSpaceBeforeBinaryOperators": [],
61
+ "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
62
+
63
+ "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
64
+ "disallowSpaceAfterBinaryOperators": [],
65
+
66
+ "disallowImplicitTypeConversion": ["binary", "string"],
67
+
68
+ "disallowKeywords": ["with", "eval"],
69
+
70
+ "requireKeywordsOnNewLine": [],
71
+ "disallowKeywordsOnNewLine": ["else"],
72
+
73
+ "requireLineFeedAtFileEnd": true,
74
+
75
+ "disallowTrailingWhitespace": true,
76
+
77
+ "disallowTrailingComma": true,
78
+
79
+ "excludeFiles": ["node_modules/**", "vendor/**"],
80
+
81
+ "disallowMultipleLineStrings": true,
82
+
83
+ "requireDotNotation": { "allExcept": ["keywords"] },
84
+
85
+ "requireParenthesesAroundIIFE": true,
86
+
87
+ "validateLineBreaks": "LF",
88
+
89
+ "validateQuoteMarks": {
90
+ "escape": true,
91
+ "mark": "'"
92
+ },
93
+
94
+ "disallowOperatorBeforeLineBreak": [],
95
+
96
+ "requireSpaceBeforeKeywords": [
97
+ "do",
98
+ "for",
99
+ "if",
100
+ "else",
101
+ "switch",
102
+ "case",
103
+ "try",
104
+ "catch",
105
+ "finally",
106
+ "while",
107
+ "with",
108
+ "return"
109
+ ],
110
+
111
+ "validateAlignedFunctionParameters": {
112
+ "lineBreakAfterOpeningBraces": true,
113
+ "lineBreakBeforeClosingBraces": true
114
+ },
115
+
116
+ "requirePaddingNewLinesBeforeExport": true,
117
+
118
+ "validateNewlineAfterArrayElements": {
119
+ "maximum": 1
120
+ },
121
+
122
+ "requirePaddingNewLinesAfterUseStrict": true,
123
+
124
+ "disallowArrowFunctions": true,
125
+
126
+ "disallowMultiLineTernary": true,
127
+
128
+ "validateOrderInObjectKeys": "asc-insensitive",
129
+
130
+ "disallowIdenticalDestructuringNames": true,
131
+
132
+ "disallowNestedTernaries": { "maxLevel": 1 },
133
+
134
+ "requireSpaceAfterComma": { "allExcept": ["trailing"] },
135
+ "requireAlignedMultilineParams": false,
136
+
137
+ "requireSpacesInGenerator": {
138
+ "afterStar": true
139
+ },
140
+
141
+ "disallowSpacesInGenerator": {
142
+ "beforeStar": true
143
+ },
144
+
145
+ "disallowVar": false,
146
+
147
+ "requireArrayDestructuring": false,
148
+
149
+ "requireEnhancedObjectLiterals": false,
150
+
151
+ "requireObjectDestructuring": false,
152
+
153
+ "requireEarlyReturn": false,
154
+
155
+ "requireCapitalizedConstructorsNew": {
156
+ "allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"]
157
+ },
158
+
159
+ "requireImportAlphabetized": false,
160
+
161
+ "requireSpaceBeforeObjectValues": true,
162
+ "requireSpaceBeforeDestructuredValues": true,
163
+
164
+ "disallowSpacesInsideTemplateStringPlaceholders": true,
165
+
166
+ "disallowArrayDestructuringReturn": false,
167
+
168
+ "requireNewlineBeforeSingleStatementsInIf": false,
169
+
170
+ "disallowUnusedVariables": true,
171
+
172
+ "requireSpacesInsideImportedObjectBraces": true,
173
+
174
+ "requireUseStrict": true
175
+ }
176
+
package/CHANGELOG.md CHANGED
@@ -1,13 +1,9 @@
1
- ## **6.1.2**
2
- - [Fix] follow `allowPrototypes` option during merge (#201, #200)
3
- - [Fix] chmod a-x
4
- - [Fix] support keys starting with brackets (#202, #200)
5
- - [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
1
+ ## [**6.2.0**](https://github.com/ljharb/qs/issues?milestone=36&state=closed)
2
+ - [New] pass Buffers to the encoder/decoder directly (#161)
3
+ - [New] add "encoder" and "decoder" options, for custom param encoding/decoding (#160)
4
+ - [Fix] fix compacting of nested sparse arrays (#150)
6
5
 
7
- ## **6.1.1**
8
- - [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
9
-
10
- ## [**6.1.0**](https://github.com/ljharb/qs/issues?milestone=34&state=closed)
6
+ ## [**6.1.0**](https://github.com/ljharb/qs/issues?milestone=35&state=closed)
11
7
  - [New] allowDots option for `stringify` (#151)
12
8
  - [Fix] "sort" option should work at a depth of 3 or more (#151)
13
9
  - [Fix] Restore `dist` directory; will be removed in v7 (#148)
package/dist/qs.js CHANGED
@@ -14,7 +14,7 @@ module.exports = {
14
14
 
15
15
  var Utils = require('./utils');
16
16
 
17
- var internals = {
17
+ var defaults = {
18
18
  delimiter: '&',
19
19
  depth: 5,
20
20
  arrayLimit: 20,
@@ -22,12 +22,11 @@ var internals = {
22
22
  strictNullHandling: false,
23
23
  plainObjects: false,
24
24
  allowPrototypes: false,
25
- allowDots: false
25
+ allowDots: false,
26
+ decoder: Utils.decode
26
27
  };
27
28
 
28
- var has = Object.prototype.hasOwnProperty;
29
-
30
- internals.parseValues = function (str, options) {
29
+ var parseValues = function parseValues(str, options) {
31
30
  var obj = {};
32
31
  var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
33
32
 
@@ -36,16 +35,16 @@ internals.parseValues = function (str, options) {
36
35
  var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
37
36
 
38
37
  if (pos === -1) {
39
- obj[Utils.decode(part)] = '';
38
+ obj[options.decoder(part)] = '';
40
39
 
41
40
  if (options.strictNullHandling) {
42
- obj[Utils.decode(part)] = null;
41
+ obj[options.decoder(part)] = null;
43
42
  }
44
43
  } else {
45
- var key = Utils.decode(part.slice(0, pos));
46
- var val = Utils.decode(part.slice(pos + 1));
44
+ var key = options.decoder(part.slice(0, pos));
45
+ var val = options.decoder(part.slice(pos + 1));
47
46
 
48
- if (has.call(obj, key)) {
47
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
49
48
  obj[key] = [].concat(obj[key]).concat(val);
50
49
  } else {
51
50
  obj[key] = val;
@@ -56,7 +55,7 @@ internals.parseValues = function (str, options) {
56
55
  return obj;
57
56
  };
58
57
 
59
- internals.parseObject = function (chain, val, options) {
58
+ var parseObject = function parseObject(chain, val, options) {
60
59
  if (!chain.length) {
61
60
  return val;
62
61
  }
@@ -66,10 +65,10 @@ internals.parseObject = function (chain, val, options) {
66
65
  var obj;
67
66
  if (root === '[]') {
68
67
  obj = [];
69
- obj = obj.concat(internals.parseObject(chain, val, options));
68
+ obj = obj.concat(parseObject(chain, val, options));
70
69
  } else {
71
70
  obj = options.plainObjects ? Object.create(null) : {};
72
- var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
71
+ var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
73
72
  var index = parseInt(cleanRoot, 10);
74
73
  if (
75
74
  !isNaN(index) &&
@@ -79,16 +78,16 @@ internals.parseObject = function (chain, val, options) {
79
78
  (options.parseArrays && index <= options.arrayLimit)
80
79
  ) {
81
80
  obj = [];
82
- obj[index] = internals.parseObject(chain, val, options);
81
+ obj[index] = parseObject(chain, val, options);
83
82
  } else {
84
- obj[cleanRoot] = internals.parseObject(chain, val, options);
83
+ obj[cleanRoot] = parseObject(chain, val, options);
85
84
  }
86
85
  }
87
86
 
88
87
  return obj;
89
88
  };
90
89
 
91
- internals.parseKeys = function (givenKey, val, options) {
90
+ var parseKeys = function parseKeys(givenKey, val, options) {
92
91
  if (!givenKey) {
93
92
  return;
94
93
  }
@@ -98,27 +97,26 @@ internals.parseKeys = function (givenKey, val, options) {
98
97
 
99
98
  // The regex chunks
100
99
 
101
- var brackets = /(\[[^[\]]*])/;
102
- var child = /(\[[^[\]]*])/g;
100
+ var parent = /^([^\[\]]*)/;
101
+ var child = /(\[[^\[\]]*\])/g;
103
102
 
104
103
  // Get the parent
105
104
 
106
- var segment = brackets.exec(key);
107
- var parent = segment ? key.slice(0, segment.index) : key;
105
+ var segment = parent.exec(key);
108
106
 
109
107
  // Stash the parent if it exists
110
108
 
111
109
  var keys = [];
112
- if (parent) {
110
+ if (segment[1]) {
113
111
  // If we aren't using plain objects, optionally prefix keys
114
112
  // that would overwrite object prototype properties
115
- if (!options.plainObjects && has.call(Object.prototype, parent)) {
113
+ if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
116
114
  if (!options.allowPrototypes) {
117
115
  return;
118
116
  }
119
117
  }
120
118
 
121
- keys.push(parent);
119
+ keys.push(segment[1]);
122
120
  }
123
121
 
124
122
  // Loop through children appending to the array until we hit depth
@@ -126,9 +124,9 @@ internals.parseKeys = function (givenKey, val, options) {
126
124
  var i = 0;
127
125
  while ((segment = child.exec(key)) !== null && i < options.depth) {
128
126
  i += 1;
129
- if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
127
+ if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
130
128
  if (!options.allowPrototypes) {
131
- return;
129
+ continue;
132
130
  }
133
131
  }
134
132
  keys.push(segment[1]);
@@ -140,30 +138,32 @@ internals.parseKeys = function (givenKey, val, options) {
140
138
  keys.push('[' + key.slice(segment.index) + ']');
141
139
  }
142
140
 
143
- return internals.parseObject(keys, val, options);
141
+ return parseObject(keys, val, options);
144
142
  };
145
143
 
146
144
  module.exports = function (str, opts) {
147
145
  var options = opts || {};
148
- options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
149
- options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
150
- options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
146
+
147
+ if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') {
148
+ throw new TypeError('Decoder has to be a function.');
149
+ }
150
+
151
+ options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
152
+ options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
153
+ options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
151
154
  options.parseArrays = options.parseArrays !== false;
152
- options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : internals.allowDots;
153
- options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : internals.plainObjects;
154
- options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : internals.allowPrototypes;
155
- options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
156
- options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
157
-
158
- if (
159
- str === '' ||
160
- str === null ||
161
- typeof str === 'undefined'
162
- ) {
155
+ options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder;
156
+ options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots;
157
+ options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects;
158
+ options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes;
159
+ options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit;
160
+ options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
161
+
162
+ if (str === '' || str === null || typeof str === 'undefined') {
163
163
  return options.plainObjects ? Object.create(null) : {};
164
164
  }
165
165
 
166
- var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
166
+ var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
167
167
  var obj = options.plainObjects ? Object.create(null) : {};
168
168
 
169
169
  // Iterate over the keys and setup the new object
@@ -171,7 +171,7 @@ module.exports = function (str, opts) {
171
171
  var keys = Object.keys(tempObj);
172
172
  for (var i = 0; i < keys.length; ++i) {
173
173
  var key = keys[i];
174
- var newObj = internals.parseKeys(key, tempObj[key], options);
174
+ var newObj = parseKeys(key, tempObj[key], options);
175
175
  obj = Utils.merge(obj, newObj, options);
176
176
  }
177
177
 
@@ -183,45 +183,45 @@ module.exports = function (str, opts) {
183
183
 
184
184
  var Utils = require('./utils');
185
185
 
186
- var internals = {
187
- delimiter: '&',
188
- arrayPrefixGenerators: {
189
- brackets: function (prefix) {
190
- return prefix + '[]';
191
- },
192
- indices: function (prefix, key) {
193
- return prefix + '[' + key + ']';
194
- },
195
- repeat: function (prefix) {
196
- return prefix;
197
- }
186
+ var arrayPrefixGenerators = {
187
+ brackets: function brackets(prefix) {
188
+ return prefix + '[]';
189
+ },
190
+ indices: function indices(prefix, key) {
191
+ return prefix + '[' + key + ']';
198
192
  },
193
+ repeat: function repeat(prefix) {
194
+ return prefix;
195
+ }
196
+ };
197
+
198
+ var defaults = {
199
+ delimiter: '&',
199
200
  strictNullHandling: false,
200
201
  skipNulls: false,
201
- encode: true
202
+ encode: true,
203
+ encoder: Utils.encode
202
204
  };
203
205
 
204
- internals.stringify = function (object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots) {
206
+ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
205
207
  var obj = object;
206
208
  if (typeof filter === 'function') {
207
209
  obj = filter(prefix, obj);
208
- } else if (Utils.isBuffer(obj)) {
209
- obj = String(obj);
210
210
  } else if (obj instanceof Date) {
211
211
  obj = obj.toISOString();
212
212
  } else if (obj === null) {
213
213
  if (strictNullHandling) {
214
- return encode ? Utils.encode(prefix) : prefix;
214
+ return encoder ? encoder(prefix) : prefix;
215
215
  }
216
216
 
217
217
  obj = '';
218
218
  }
219
219
 
220
- if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean') {
221
- if (encode) {
222
- return [Utils.encode(prefix) + '=' + Utils.encode(obj)];
220
+ if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
221
+ if (encoder) {
222
+ return [encoder(prefix) + '=' + encoder(obj)];
223
223
  }
224
- return [prefix + '=' + obj];
224
+ return [prefix + '=' + String(obj)];
225
225
  }
226
226
 
227
227
  var values = [];
@@ -246,9 +246,9 @@ internals.stringify = function (object, prefix, generateArrayPrefix, strictNullH
246
246
  }
247
247
 
248
248
  if (Array.isArray(obj)) {
249
- values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
249
+ values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
250
250
  } else {
251
- values = values.concat(internals.stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
251
+ values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
252
252
  }
253
253
  }
254
254
 
@@ -258,14 +258,20 @@ internals.stringify = function (object, prefix, generateArrayPrefix, strictNullH
258
258
  module.exports = function (object, opts) {
259
259
  var obj = object;
260
260
  var options = opts || {};
261
- var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
262
- var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
263
- var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
264
- var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
261
+ var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
262
+ var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
263
+ var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
264
+ var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
265
+ var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
265
266
  var sort = typeof options.sort === 'function' ? options.sort : null;
266
267
  var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
267
268
  var objKeys;
268
269
  var filter;
270
+
271
+ if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
272
+ throw new TypeError('Encoder has to be a function.');
273
+ }
274
+
269
275
  if (typeof options.filter === 'function') {
270
276
  filter = options.filter;
271
277
  obj = filter('', obj);
@@ -280,7 +286,7 @@ module.exports = function (object, opts) {
280
286
  }
281
287
 
282
288
  var arrayFormat;
283
- if (options.arrayFormat in internals.arrayPrefixGenerators) {
289
+ if (options.arrayFormat in arrayPrefixGenerators) {
284
290
  arrayFormat = options.arrayFormat;
285
291
  } else if ('indices' in options) {
286
292
  arrayFormat = options.indices ? 'indices' : 'repeat';
@@ -288,7 +294,7 @@ module.exports = function (object, opts) {
288
294
  arrayFormat = 'indices';
289
295
  }
290
296
 
291
- var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
297
+ var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
292
298
 
293
299
  if (!objKeys) {
294
300
  objKeys = Object.keys(obj);
@@ -305,7 +311,7 @@ module.exports = function (object, opts) {
305
311
  continue;
306
312
  }
307
313
 
308
- keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
314
+ keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
309
315
  }
310
316
 
311
317
  return keys.join(delimiter);
@@ -323,8 +329,6 @@ var hexTable = (function () {
323
329
  return array;
324
330
  }());
325
331
 
326
- var has = Object.prototype.hasOwnProperty;
327
-
328
332
  exports.arrayToObject = function (source, options) {
329
333
  var obj = options.plainObjects ? Object.create(null) : {};
330
334
  for (var i = 0; i < source.length; ++i) {
@@ -345,9 +349,7 @@ exports.merge = function (target, source, options) {
345
349
  if (Array.isArray(target)) {
346
350
  target.push(source);
347
351
  } else if (typeof target === 'object') {
348
- if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
349
- target[source] = true;
350
- }
352
+ target[source] = true;
351
353
  } else {
352
354
  return [target, source];
353
355
  }
@@ -364,15 +366,15 @@ exports.merge = function (target, source, options) {
364
366
  mergeTarget = exports.arrayToObject(target, options);
365
367
  }
366
368
 
367
- return Object.keys(source).reduce(function (acc, key) {
369
+ return Object.keys(source).reduce(function (acc, key) {
368
370
  var value = source[key];
369
371
 
370
- if (has.call(acc, key)) {
372
+ if (Object.prototype.hasOwnProperty.call(acc, key)) {
371
373
  acc[key] = exports.merge(acc[key], value, options);
372
374
  } else {
373
375
  acc[key] = value;
374
376
  }
375
- return acc;
377
+ return acc;
376
378
  }, mergeTarget);
377
379
  };
378
380
 
@@ -427,7 +429,7 @@ exports.encode = function (str) {
427
429
 
428
430
  i += 1;
429
431
  c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
430
- out += (hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
432
+ out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
431
433
  }
432
434
 
433
435
  return out;
@@ -450,7 +452,9 @@ exports.compact = function (obj, references) {
450
452
  var compacted = [];
451
453
 
452
454
  for (var i = 0; i < obj.length; ++i) {
453
- if (typeof obj[i] !== 'undefined') {
455
+ if (obj[i] && typeof obj[i] === 'object') {
456
+ compacted.push(exports.compact(obj[i], refs));
457
+ } else if (typeof obj[i] !== 'undefined') {
454
458
  compacted.push(obj[i]);
455
459
  }
456
460
  }
package/lib/index.js CHANGED
File without changes