qs 3.0.0 → 5.1.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;
@@ -92,7 +95,9 @@ internals.parseKeys = function (key, val, options) {
92
95
 
93
96
  // Transform dot notation to bracket notation
94
97
 
95
- key = key.replace(/\.([^\.\[]+)/g, '[$1]');
98
+ if (options.allowDots) {
99
+ key = key.replace(/\.([^\.\[]+)/g, '[$1]');
100
+ }
96
101
 
97
102
  // The regex chunks
98
103
 
@@ -107,6 +112,16 @@ internals.parseKeys = function (key, val, options) {
107
112
 
108
113
  var keys = [];
109
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
+
110
125
  keys.push(segment[1]);
111
126
  }
112
127
 
@@ -116,6 +131,13 @@ internals.parseKeys = function (key, val, options) {
116
131
  while ((segment = child.exec(key)) !== null && i < options.depth) {
117
132
 
118
133
  ++i;
134
+ if (!options.plainObjects &&
135
+ Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
136
+
137
+ if (!options.allowPrototypes) {
138
+ continue;
139
+ }
140
+ }
119
141
  keys.push(segment[1]);
120
142
  }
121
143
 
@@ -131,24 +153,26 @@ internals.parseKeys = function (key, val, options) {
131
153
 
132
154
  module.exports = function (str, options) {
133
155
 
134
- if (str === '' ||
135
- str === null ||
136
- typeof str === 'undefined') {
137
-
138
- return Object.create(null);
139
- }
140
-
141
156
  options = options || {};
142
157
  options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
143
158
  options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
144
159
  options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
145
160
  options.parseArrays = options.parseArrays !== 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;
146
164
  options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
147
165
  options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
148
166
 
167
+ if (str === '' ||
168
+ str === null ||
169
+ typeof str === 'undefined') {
170
+
171
+ return options.plainObjects ? Object.create(null) : {};
172
+ }
149
173
 
150
174
  var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
151
- var obj = Object.create(null);
175
+ var obj = options.plainObjects ? Object.create(null) : {};
152
176
 
153
177
  // Iterate over the keys and setup the new object
154
178
 
@@ -156,7 +180,7 @@ module.exports = function (str, options) {
156
180
  for (var i = 0, il = keys.length; i < il; ++i) {
157
181
  var key = keys[i];
158
182
  var newObj = internals.parseKeys(key, tempObj[key], options);
159
- obj = Utils.merge(obj, newObj);
183
+ obj = Utils.merge(obj, newObj, options);
160
184
  }
161
185
 
162
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) {
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 = [];
@@ -61,11 +66,17 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
61
66
  for (var i = 0, il = objKeys.length; i < il; ++i) {
62
67
  var key = objKeys[i];
63
68
 
69
+ if (skipNulls &&
70
+ obj[key] === null) {
71
+
72
+ continue;
73
+ }
74
+
64
75
  if (Array.isArray(obj)) {
65
- values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, filter));
76
+ values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
66
77
  }
67
78
  else {
68
- values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, filter));
79
+ values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
69
80
  }
70
81
  }
71
82
 
@@ -78,6 +89,8 @@ module.exports = function (obj, options) {
78
89
  options = options || {};
79
90
  var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
80
91
  var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
92
+ var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
93
+ var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
81
94
  var objKeys;
82
95
  var filter;
83
96
  if (typeof options.filter === 'function') {
@@ -112,9 +125,17 @@ module.exports = function (obj, options) {
112
125
  if (!objKeys) {
113
126
  objKeys = Object.keys(obj);
114
127
  }
128
+
115
129
  for (var i = 0, il = objKeys.length; i < il; ++i) {
116
130
  var key = objKeys[i];
117
- keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, filter));
131
+
132
+ if (skipNulls &&
133
+ obj[key] === null) {
134
+
135
+ continue;
136
+ }
137
+
138
+ keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
118
139
  }
119
140
 
120
141
  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.0.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.1.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
  }