qs 3.1.0 → 5.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/lib/parse.js CHANGED
@@ -10,7 +10,10 @@ var internals = {
10
10
  depth: 5,
11
11
  arrayLimit: 20,
12
12
  parameterLimit: 1000,
13
- strictNullHandling: false
13
+ strictNullHandling: false,
14
+ plainObjects: false,
15
+ allowPrototypes: false,
16
+ allowDots: false
14
17
  };
15
18
 
16
19
 
@@ -61,7 +64,7 @@ internals.parseObject = function (chain, val, options) {
61
64
  obj = obj.concat(internals.parseObject(chain, val, options));
62
65
  }
63
66
  else {
64
- obj = Object.create(null);
67
+ obj = options.plainObjects ? Object.create(null) : {};
65
68
  var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
66
69
  var index = parseInt(cleanRoot, 10);
67
70
  var indexString = '' + index;
@@ -109,6 +112,16 @@ internals.parseKeys = function (key, val, options) {
109
112
 
110
113
  var keys = [];
111
114
  if (segment[1]) {
115
+ // If we aren't using plain objects, optionally prefix keys
116
+ // that would overwrite object prototype properties
117
+ if (!options.plainObjects &&
118
+ Object.prototype.hasOwnProperty(segment[1])) {
119
+
120
+ if (!options.allowPrototypes) {
121
+ return;
122
+ }
123
+ }
124
+
112
125
  keys.push(segment[1]);
113
126
  }
114
127
 
@@ -118,6 +131,13 @@ internals.parseKeys = function (key, val, options) {
118
131
  while ((segment = child.exec(key)) !== null && i < options.depth) {
119
132
 
120
133
  ++i;
134
+ if (!options.plainObjects &&
135
+ Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
136
+
137
+ if (!options.allowPrototypes) {
138
+ continue;
139
+ }
140
+ }
121
141
  keys.push(segment[1]);
122
142
  }
123
143
 
@@ -133,25 +153,26 @@ internals.parseKeys = function (key, val, options) {
133
153
 
134
154
  module.exports = function (str, options) {
135
155
 
136
- if (str === '' ||
137
- str === null ||
138
- typeof str === 'undefined') {
139
-
140
- return Object.create(null);
141
- }
142
-
143
156
  options = options || {};
144
157
  options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
145
158
  options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
146
159
  options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
147
160
  options.parseArrays = options.parseArrays !== false;
148
- options.allowDots = options.allowDots !== false;
161
+ options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : internals.allowDots;
162
+ options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : internals.plainObjects;
163
+ options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : internals.allowPrototypes;
149
164
  options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
150
165
  options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
151
166
 
167
+ if (str === '' ||
168
+ str === null ||
169
+ typeof str === 'undefined') {
170
+
171
+ return options.plainObjects ? Object.create(null) : {};
172
+ }
152
173
 
153
174
  var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
154
- var obj = Object.create(null);
175
+ var obj = options.plainObjects ? Object.create(null) : {};
155
176
 
156
177
  // Iterate over the keys and setup the new object
157
178
 
@@ -159,7 +180,7 @@ module.exports = function (str, options) {
159
180
  for (var i = 0, il = keys.length; i < il; ++i) {
160
181
  var key = keys[i];
161
182
  var newObj = internals.parseKeys(key, tempObj[key], options);
162
- obj = Utils.merge(obj, newObj);
183
+ obj = Utils.merge(obj, newObj, options);
163
184
  }
164
185
 
165
186
  return Utils.compact(obj);
package/lib/stringify.js CHANGED
@@ -21,11 +21,13 @@ var internals = {
21
21
  return prefix;
22
22
  }
23
23
  },
24
- strictNullHandling: false
24
+ strictNullHandling: false,
25
+ skipNulls: false,
26
+ encode: true
25
27
  };
26
28
 
27
29
 
28
- internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling, filter) {
30
+ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort) {
29
31
 
30
32
  if (typeof filter === 'function') {
31
33
  obj = filter(prefix, obj);
@@ -38,7 +40,7 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
38
40
  }
39
41
  else if (obj === null) {
40
42
  if (strictNullHandling) {
41
- return Utils.encode(prefix);
43
+ return encode ? Utils.encode(prefix) : prefix;
42
44
  }
43
45
 
44
46
  obj = '';
@@ -48,7 +50,10 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
48
50
  typeof obj === 'number' ||
49
51
  typeof obj === 'boolean') {
50
52
 
51
- return [Utils.encode(prefix) + '=' + Utils.encode(obj)];
53
+ if (encode) {
54
+ return [Utils.encode(prefix) + '=' + Utils.encode(obj)];
55
+ }
56
+ return [prefix + '=' + obj];
52
57
  }
53
58
 
54
59
  var values = [];
@@ -57,15 +62,28 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
57
62
  return values;
58
63
  }
59
64
 
60
- var objKeys = Array.isArray(filter) ? filter : Object.keys(obj);
65
+ var objKeys;
66
+ if (Array.isArray(filter)) {
67
+ objKeys = filter;
68
+ } else {
69
+ var keys = Object.keys(obj);
70
+ objKeys = sort ? keys.sort(sort) : keys;
71
+ }
72
+
61
73
  for (var i = 0, il = objKeys.length; i < il; ++i) {
62
74
  var key = objKeys[i];
63
75
 
76
+ if (skipNulls &&
77
+ obj[key] === null) {
78
+
79
+ continue;
80
+ }
81
+
64
82
  if (Array.isArray(obj)) {
65
- values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, filter));
83
+ values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
66
84
  }
67
85
  else {
68
- values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, filter));
86
+ values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
69
87
  }
70
88
  }
71
89
 
@@ -78,6 +96,9 @@ module.exports = function (obj, options) {
78
96
  options = options || {};
79
97
  var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
80
98
  var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
99
+ var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
100
+ var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
101
+ var sort = typeof options.sort === 'function' ? options.sort : null;
81
102
  var objKeys;
82
103
  var filter;
83
104
  if (typeof options.filter === 'function') {
@@ -112,9 +133,21 @@ module.exports = function (obj, options) {
112
133
  if (!objKeys) {
113
134
  objKeys = Object.keys(obj);
114
135
  }
136
+
137
+ if (sort) {
138
+ objKeys.sort(sort);
139
+ }
140
+
115
141
  for (var i = 0, il = objKeys.length; i < il; ++i) {
116
142
  var key = objKeys[i];
117
- keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, filter));
143
+
144
+ if (skipNulls &&
145
+ obj[key] === null) {
146
+
147
+ continue;
148
+ }
149
+
150
+ keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort));
118
151
  }
119
152
 
120
153
  return keys.join(delimiter);
package/lib/utils.js CHANGED
@@ -5,14 +5,14 @@
5
5
 
6
6
  var internals = {};
7
7
  internals.hexTable = new Array(256);
8
- for (var i = 0; i < 256; ++i) {
9
- internals.hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
8
+ for (var h = 0; h < 256; ++h) {
9
+ internals.hexTable[h] = '%' + ((h < 16 ? '0' : '') + h.toString(16)).toUpperCase();
10
10
  }
11
11
 
12
12
 
13
- exports.arrayToObject = function (source) {
13
+ exports.arrayToObject = function (source, options) {
14
14
 
15
- var obj = Object.create(null);
15
+ var obj = options.plainObjects ? Object.create(null) : {};
16
16
  for (var i = 0, il = source.length; i < il; ++i) {
17
17
  if (typeof source[i] !== 'undefined') {
18
18
 
@@ -24,7 +24,7 @@ exports.arrayToObject = function (source) {
24
24
  };
25
25
 
26
26
 
27
- exports.merge = function (target, source) {
27
+ exports.merge = function (target, source, options) {
28
28
 
29
29
  if (!source) {
30
30
  return target;
@@ -52,7 +52,7 @@ exports.merge = function (target, source) {
52
52
  if (Array.isArray(target) &&
53
53
  !Array.isArray(source)) {
54
54
 
55
- target = exports.arrayToObject(target);
55
+ target = exports.arrayToObject(target, options);
56
56
  }
57
57
 
58
58
  var keys = Object.keys(source);
@@ -60,11 +60,11 @@ exports.merge = function (target, source) {
60
60
  var key = keys[k];
61
61
  var value = source[key];
62
62
 
63
- if (!target[key]) {
63
+ if (!Object.prototype.hasOwnProperty.call(target, key)) {
64
64
  target[key] = value;
65
65
  }
66
66
  else {
67
- target[key] = exports.merge(target[key], value);
67
+ target[key] = exports.merge(target[key], value, options);
68
68
  }
69
69
  }
70
70
 
package/package.json CHANGED
@@ -1,26 +1,29 @@
1
1
  {
2
2
  "name": "qs",
3
- "version": "3.1.0",
4
3
  "description": "A querystring parser that supports nesting and arrays, with a depth limit",
5
4
  "homepage": "https://github.com/hapijs/qs",
6
- "main": "index.js",
7
- "dependencies": {},
8
- "devDependencies": {
9
- "browserify": "^10.2.1",
10
- "code": "1.x.x",
11
- "lab": "5.x.x"
12
- },
13
- "scripts": {
14
- "test": "make test-cov",
15
- "dist": "browserify --standalone Qs index.js > dist/qs.js"
16
- },
5
+ "version": "5.2.0",
17
6
  "repository": {
18
7
  "type": "git",
19
8
  "url": "https://github.com/hapijs/qs.git"
20
9
  },
10
+ "main": "lib/index.js",
21
11
  "keywords": [
22
12
  "querystring",
23
13
  "qs"
24
14
  ],
15
+ "engines": ">=0.10.40",
16
+ "dependencies": {},
17
+ "devDependencies": {
18
+ "browserify": "^10.2.1",
19
+ "code": "1.x.x",
20
+ "lab": "5.x.x"
21
+ },
22
+ "scripts": {
23
+ "test": "lab -a code -t 100 -L",
24
+ "test-tap": "lab -a code -r tap -o tests.tap",
25
+ "test-cov-html": "lab -a code -r html -o coverage.html",
26
+ "dist": "browserify --standalone Qs lib/index.js > dist/qs.js"
27
+ },
25
28
  "license": "BSD-3-Clause"
26
29
  }