query-string 4.2.2 → 4.3.2

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.
Files changed (3) hide show
  1. package/index.js +121 -16
  2. package/package.json +3 -3
  3. package/readme.md +68 -3
package/index.js CHANGED
@@ -2,6 +2,92 @@
2
2
  var strictUriEncode = require('strict-uri-encode');
3
3
  var objectAssign = require('object-assign');
4
4
 
5
+ function encoderForArrayFormat(opts) {
6
+ switch (opts.arrayFormat) {
7
+ case 'index':
8
+ return function (key, value, index) {
9
+ return value === null ? [
10
+ encode(key, opts),
11
+ '[',
12
+ index,
13
+ ']'
14
+ ].join('') : [
15
+ encode(key, opts),
16
+ '[',
17
+ encode(index, opts),
18
+ ']=',
19
+ encode(value, opts)
20
+ ].join('');
21
+ };
22
+
23
+ case 'bracket':
24
+ return function (key, value) {
25
+ return value === null ? encode(key, opts) : [
26
+ encode(key, opts),
27
+ '[]=',
28
+ encode(value, opts)
29
+ ].join('');
30
+ };
31
+
32
+ default:
33
+ return function (key, value) {
34
+ return value === null ? encode(key, opts) : [
35
+ encode(key, opts),
36
+ '=',
37
+ encode(value, opts)
38
+ ].join('');
39
+ };
40
+ }
41
+ }
42
+
43
+ function parserForArrayFormat(opts) {
44
+ var result;
45
+
46
+ switch (opts.arrayFormat) {
47
+ case 'index':
48
+ return function (key, value, accumulator) {
49
+ result = /\[(\d*)\]$/.exec(key);
50
+
51
+ key = key.replace(/\[\d*\]$/, '');
52
+
53
+ if (!result) {
54
+ accumulator[key] = value;
55
+ return;
56
+ }
57
+
58
+ if (accumulator[key] === undefined) {
59
+ accumulator[key] = {};
60
+ }
61
+
62
+ accumulator[key][result[1]] = value;
63
+ };
64
+
65
+ case 'bracket':
66
+ return function (key, value, accumulator) {
67
+ result = /(\[\])$/.exec(key);
68
+
69
+ key = key.replace(/\[\]$/, '');
70
+
71
+ if (!result || accumulator[key] === undefined) {
72
+ accumulator[key] = value;
73
+ return;
74
+ }
75
+
76
+ accumulator[key] = [].concat(accumulator[key], value);
77
+ };
78
+
79
+ default:
80
+ return function (key, value, accumulator) {
81
+ if (accumulator[key] === undefined) {
82
+ accumulator[key] = value;
83
+ return;
84
+ }
85
+
86
+ accumulator[key] = [].concat(accumulator[key], value);
87
+ };
88
+ }
89
+ }
90
+
5
91
  function encode(value, opts) {
6
92
  if (opts.encode) {
7
93
  return opts.strict ? strictUriEncode(value) : encodeURIComponent(value);
@@ -10,11 +96,29 @@ function encode(value, opts) {
10
96
  return value;
11
97
  }
12
98
 
99
+ function keysSorter(input) {
100
+ if (Array.isArray(input)) {
101
+ return input.sort();
102
+ } else if (typeof input === 'object') {
103
+ return keysSorter(Object.keys(input)).sort(function (a, b) {
104
+ return Number(a) - Number(b);
105
+ }).map(function (key) {
106
+ return input[key];
107
+ });
108
+ }
109
+
110
+ return input;
111
+ }
112
+
13
113
  exports.extract = function (str) {
14
114
  return str.split('?')[1] || '';
15
115
  };
16
116
 
17
- exports.parse = function (str) {
117
+ exports.parse = function (str, opts) {
118
+ opts = objectAssign({arrayFormat: 'none'}, opts);
119
+
120
+ var formatter = parserForArrayFormat(opts);
121
+
18
122
  // Create an object with no prototype
19
123
  // https://github.com/sindresorhus/query-string/issues/47
20
124
  var ret = Object.create(null);
@@ -36,32 +140,37 @@ exports.parse = function (str) {
36
140
  var key = parts.shift();
37
141
  var val = parts.length > 0 ? parts.join('=') : undefined;
38
142
 
39
- key = decodeURIComponent(key);
40
-
41
143
  // missing `=` should be `null`:
42
144
  // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
43
145
  val = val === undefined ? null : decodeURIComponent(val);
44
146
 
45
- if (ret[key] === undefined) {
46
- ret[key] = val;
47
- } else if (Array.isArray(ret[key])) {
48
- ret[key].push(val);
147
+ formatter(decodeURIComponent(key), val, ret);
148
+ });
149
+
150
+ return Object.keys(ret).sort().reduce(function (result, key) {
151
+ var val = ret[key];
152
+ if (Boolean(val) && typeof val === 'object' && !Array.isArray(val)) {
153
+ // Sort object keys, not values
154
+ result[key] = keysSorter(val);
49
155
  } else {
50
- ret[key] = [ret[key], val];
156
+ result[key] = val;
51
157
  }
52
- });
53
158
 
54
- return ret;
159
+ return result;
160
+ }, Object.create(null));
55
161
  };
56
162
 
57
163
  exports.stringify = function (obj, opts) {
58
164
  var defaults = {
59
165
  encode: true,
60
- strict: true
166
+ strict: true,
167
+ arrayFormat: 'none'
61
168
  };
62
169
 
63
170
  opts = objectAssign(defaults, opts);
64
171
 
172
+ var formatter = encoderForArrayFormat(opts);
173
+
65
174
  return obj ? Object.keys(obj).sort().map(function (key) {
66
175
  var val = obj[key];
67
176
 
@@ -81,11 +190,7 @@ exports.stringify = function (obj, opts) {
81
190
  return;
82
191
  }
83
192
 
84
- if (val2 === null) {
85
- result.push(encode(key, opts));
86
- } else {
87
- result.push(encode(key, opts) + '=' + encode(val2, opts));
88
- }
193
+ result.push(formatter(key, val2, result.length));
89
194
  });
90
195
 
91
196
  return result.join('&');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "query-string",
3
- "version": "4.2.2",
3
+ "version": "4.3.2",
4
4
  "description": "Parse and stringify URL query strings",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/query-string",
@@ -38,7 +38,7 @@
38
38
  "strict-uri-encode": "^1.0.0"
39
39
  },
40
40
  "devDependencies": {
41
- "ava": "*",
42
- "xo": "*"
41
+ "ava": "^0.17.0",
42
+ "xo": "^0.16.0"
43
43
  }
44
44
  }
package/readme.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  > Parse and stringify URL [query strings](http://en.wikipedia.org/wiki/Query_string)
4
4
 
5
+ ---
6
+
7
+ <p align="center"><b>🔥 Want to strengthen your core JavaScript skills and master ES6?</b><br>I would personally recommend this awesome <a href="https://ES6.io/friend/AWESOME">ES6 course</a> by Wes Bos. You might also like his <a href="https://ReactForBeginners.com/friend/AWESOME">React course</a>.</p>
8
+
9
+ ---
10
+
5
11
 
6
12
  ## Install
7
13
 
@@ -32,8 +38,11 @@ console.log(parsedHash);
32
38
  parsed.foo = 'unicorn';
33
39
  parsed.ilike = 'pizza';
34
40
 
35
- location.search = queryString.stringify(parsed);
41
+ const stringified = queryString.stringify(parsed);
42
+ //=> 'foo=unicorn&ilike=pizza'
36
43
 
44
+ location.search = stringified;
45
+ // note that `location.search` automatically prepends a question mark
37
46
  console.log(location.search);
38
47
  //=> '?foo=unicorn&ilike=pizza'
39
48
  ```
@@ -41,19 +50,47 @@ console.log(location.search);
41
50
 
42
51
  ## API
43
52
 
44
- ### .parse(*string*)
53
+ ### .parse(*string*, *[options]*)
45
54
 
46
55
  Parse a query string into an object. Leading `?` or `#` are ignored, so you can pass `location.search` or `location.hash` directly.
47
56
 
48
57
  The returned object is created with [`Object.create(null)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) and thus does not have a `prototype`.
49
58
 
59
+ #### arrayFormat
60
+
61
+ Type: `string`<br>
62
+ Default: `'none'`
63
+
64
+ Supports both `index` for an indexed array representation or `bracket` for a *bracketed* array representation.
65
+
66
+ - `bracket`: stands for parsing correctly arrays with bracket representation on the query string, such as:
67
+
68
+ ```js
69
+ queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
70
+ //=> foo: [1,2,3]
71
+ ```
72
+
73
+ - `index`: stands for parsing taking the index into account, such as:
74
+
75
+ ```js
76
+ queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
77
+ //=> foo: [1,2,3]
78
+ ```
79
+
80
+ - `none`: is the **default** option and removes any bracket representation, such as:
81
+
82
+ ```js
83
+ queryString.parse('foo=1&foo=2&foo=3');
84
+ //=> foo: [1,2,3]
85
+ ```
86
+
50
87
  ### .stringify(*object*, *[options]*)
51
88
 
52
89
  Stringify an object into a query string, sorting the keys.
53
90
 
54
91
  #### strict
55
92
 
56
- Type: `boolean`<br />
93
+ Type: `boolean`<br>
57
94
  Default: `true`
58
95
 
59
96
  Strictly encode URI components with [strict-uri-encode](https://github.com/kevva/strict-uri-encode). It uses [encodeURIComponent](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent)
@@ -66,6 +103,34 @@ Default: `true`
66
103
 
67
104
  [URL encode](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) the keys and values.
68
105
 
106
+ #### arrayFormat
107
+
108
+ Type: `string`<br>
109
+ Default: `'none'`
110
+
111
+ Supports both `index` for an indexed array representation or `bracket` for a *bracketed* array representation.
112
+
113
+ - `bracket`: stands for parsing correctly arrays with bracket representation on the query string, such as:
114
+
115
+ ```js
116
+ queryString.stringify({foo: [1,2,3]}, {arrayFormat: 'bracket'});
117
+ // => foo[]=1&foo[]=2&foo[]=3
118
+ ```
119
+
120
+ - `index`: stands for parsing taking the index into account, such as:
121
+
122
+ ```js
123
+ queryString.stringify({foo: [1,2,3]}, {arrayFormat: 'index'});
124
+ // => foo[0]=1&foo[1]=2&foo[3]=3
125
+ ```
126
+
127
+ - `none`: is the __default__ option and removes any bracket representation, such as:
128
+
129
+ ```js
130
+ queryString.stringify({foo: [1,2,3]});
131
+ // => foo=1&foo=2&foo=3
132
+ ```
133
+
69
134
  ### .extract(*string*)
70
135
 
71
136
  Extract a query string from a URL that can be passed into `.parse()`.