qs 6.6.1 → 6.7.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/.editorconfig +0 -13
- package/.eslintignore +1 -0
- package/.eslintrc +2 -19
- package/CHANGELOG.md +8 -20
- package/LICENSE +28 -0
- package/README.md +27 -53
- package/dist/qs.js +30 -30
- package/lib/formats.js +10 -18
- package/lib/parse.js +8 -1
- package/lib/stringify.js +11 -10
- package/package.json +21 -19
- package/test/.eslintrc +17 -0
- package/test/parse.js +9 -60
- package/test/stringify.js +16 -11
- package/.github/FUNDING.yml +0 -12
- package/.nycrc +0 -13
- package/LICENSE.md +0 -29
package/.editorconfig
CHANGED
|
@@ -8,14 +8,10 @@ charset = utf-8
|
|
|
8
8
|
trim_trailing_whitespace = true
|
|
9
9
|
insert_final_newline = true
|
|
10
10
|
max_line_length = 160
|
|
11
|
-
quote_type = single
|
|
12
11
|
|
|
13
12
|
[test/*]
|
|
14
13
|
max_line_length = off
|
|
15
14
|
|
|
16
|
-
[LICENSE.md]
|
|
17
|
-
indent_size = off
|
|
18
|
-
|
|
19
15
|
[*.md]
|
|
20
16
|
max_line_length = off
|
|
21
17
|
|
|
@@ -32,12 +28,3 @@ indent_size = 2
|
|
|
32
28
|
[LICENSE]
|
|
33
29
|
indent_size = 2
|
|
34
30
|
max_line_length = off
|
|
35
|
-
|
|
36
|
-
[coverage/**/*]
|
|
37
|
-
indent_size = off
|
|
38
|
-
indent_style = off
|
|
39
|
-
indent = off
|
|
40
|
-
max_line_length = off
|
|
41
|
-
|
|
42
|
-
[.nycrc]
|
|
43
|
-
indent_style = tab
|
package/.eslintignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dist
|
package/.eslintrc
CHANGED
|
@@ -3,14 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
"extends": "@ljharb",
|
|
5
5
|
|
|
6
|
-
"ignorePatterns": [
|
|
7
|
-
"dist/",
|
|
8
|
-
],
|
|
9
|
-
|
|
10
6
|
"rules": {
|
|
11
7
|
"complexity": 0,
|
|
12
8
|
"consistent-return": 1,
|
|
13
|
-
|
|
9
|
+
"func-name-matching": 0,
|
|
14
10
|
"id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
|
|
15
11
|
"indent": [2, 4],
|
|
16
12
|
"max-lines-per-function": [2, { "max": 150 }],
|
|
@@ -19,20 +15,7 @@
|
|
|
19
15
|
"multiline-comment-style": 0,
|
|
20
16
|
"no-continue": 1,
|
|
21
17
|
"no-magic-numbers": 0,
|
|
22
|
-
"no-param-reassign": 1,
|
|
23
18
|
"no-restricted-syntax": [2, "BreakStatement", "DebuggerStatement", "ForInStatement", "LabeledStatement", "WithStatement"],
|
|
24
19
|
"operator-linebreak": [2, "before"],
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
"overrides": [
|
|
28
|
-
{
|
|
29
|
-
"files": "test/**",
|
|
30
|
-
"rules": {
|
|
31
|
-
"max-lines-per-function": 0,
|
|
32
|
-
"max-statements": 0,
|
|
33
|
-
"no-extend-native": 0,
|
|
34
|
-
"function-paren-newline": 0,
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
],
|
|
20
|
+
}
|
|
38
21
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,28 +1,16 @@
|
|
|
1
|
-
## **6.
|
|
2
|
-
- [
|
|
3
|
-
- [Fix]
|
|
4
|
-
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
|
|
5
|
-
- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
|
6
|
-
- [Fix] correctly parse nested arrays
|
|
7
|
-
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
1
|
+
## **6.7.0**
|
|
2
|
+
- [New] `stringify`/`parse`: add `comma` as an `arrayFormat` option (#276, #219)
|
|
3
|
+
- [Fix] correctly parse nested arrays (#212)
|
|
4
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source, also with an array source
|
|
8
5
|
- [Robustness] `stringify`: cache `Object.prototype.hasOwnProperty`
|
|
9
|
-
- [Refactor] `formats`: tiny bit of cleanup.
|
|
10
6
|
- [Refactor] `utils`: `isBuffer`: small tweak; add tests
|
|
11
|
-
- [Refactor]: `stringify`/`utils`: cache `Array.isArray`
|
|
12
|
-
- [Refactor] `utils`: reduce observable [[Get]]s
|
|
13
7
|
- [Refactor] use cached `Array.isArray`
|
|
14
8
|
- [Refactor] `parse`/`stringify`: make a function to normalize the options
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [meta] fix README.md (#399)
|
|
18
|
-
- [meta] do not publish workflow files
|
|
19
|
-
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
|
|
20
|
-
- [meta] add FUNDING.yml
|
|
21
|
-
- [meta] Fixes typo in CHANGELOG.md
|
|
22
|
-
- [actions] backport actions from main
|
|
23
|
-
- [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10
|
|
9
|
+
- [Refactor] `utils`: reduce observable [[Get]]s
|
|
10
|
+
- [Refactor] `stringify`/`utils`: cache `Array.isArray`
|
|
24
11
|
- [Tests] always use `String(x)` over `x.toString()`
|
|
25
|
-
- [
|
|
12
|
+
- [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10
|
|
13
|
+
- [Tests] temporarily allow coverage to fail
|
|
26
14
|
|
|
27
15
|
## **6.6.0**
|
|
28
16
|
- [New] Add support for iso-8859-1, utf8 "sentinel" and numeric entities (#268)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Copyright (c) 2014 Nathan LaFreniere and other contributors.
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
* Redistributions of source code must retain the above copyright
|
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
|
10
|
+
documentation and/or other materials provided with the distribution.
|
|
11
|
+
* The names of any contributors may not be used to endorse or promote
|
|
12
|
+
products derived from this software without specific prior written
|
|
13
|
+
permission.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
|
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
|
+
|
|
26
|
+
* * *
|
|
27
|
+
|
|
28
|
+
The complete list of contributors can be found at: https://github.com/hapijs/qs/graphs/contributors
|
package/README.md
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# qs <sup>[![Version Badge][2]][1]</sup>
|
|
2
2
|
|
|
3
|
-
[![
|
|
4
|
-
[![
|
|
5
|
-
[![dependency status][
|
|
6
|
-
[![dev dependency status][dev-deps-svg]][dev-deps-url]
|
|
3
|
+
[![Build Status][3]][4]
|
|
4
|
+
[![dependency status][5]][6]
|
|
5
|
+
[![dev dependency status][7]][8]
|
|
7
6
|
[![License][license-image]][license-url]
|
|
8
7
|
[![Downloads][downloads-image]][downloads-url]
|
|
9
8
|
|
|
10
|
-
[![npm badge][
|
|
9
|
+
[![npm badge][11]][1]
|
|
11
10
|
|
|
12
11
|
A querystring parsing and stringifying library with some added security.
|
|
13
12
|
|
|
@@ -274,6 +273,13 @@ var arraysOfObjects = qs.parse('a[][b]=c');
|
|
|
274
273
|
assert.deepEqual(arraysOfObjects, { a: [{ b: 'c' }] });
|
|
275
274
|
```
|
|
276
275
|
|
|
276
|
+
Some people use comma to join array, **qs** can parse it:
|
|
277
|
+
```javascript
|
|
278
|
+
var arraysOfObjects = qs.parse('a=b,c', { comma: true })
|
|
279
|
+
assert.deepEqual(arraysOfObjects, { a: ['b', 'c'] })
|
|
280
|
+
```
|
|
281
|
+
(_this cannot convert nested objects, such as `a={b:1},{c:d}`_)
|
|
282
|
+
|
|
277
283
|
### Stringifying
|
|
278
284
|
|
|
279
285
|
[](#preventEval)
|
|
@@ -324,30 +330,6 @@ var decoded = qs.parse('x=z', { decoder: function (str) {
|
|
|
324
330
|
}})
|
|
325
331
|
```
|
|
326
332
|
|
|
327
|
-
You can encode keys and values using different logic by using the type argument provided to the encoder:
|
|
328
|
-
|
|
329
|
-
```javascript
|
|
330
|
-
var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) {
|
|
331
|
-
if (type === 'key') {
|
|
332
|
-
return // Encoded key
|
|
333
|
-
} else if (type === 'value') {
|
|
334
|
-
return // Encoded value
|
|
335
|
-
}
|
|
336
|
-
}})
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
The type argument is also provided to the decoder:
|
|
340
|
-
|
|
341
|
-
```javascript
|
|
342
|
-
var decoded = qs.parse('x=z', { decoder: function (str, defaultDecoder, charset, type) {
|
|
343
|
-
if (type === 'key') {
|
|
344
|
-
return // Decoded key
|
|
345
|
-
} else if (type === 'value') {
|
|
346
|
-
return // Decoded value
|
|
347
|
-
}
|
|
348
|
-
}})
|
|
349
|
-
```
|
|
350
|
-
|
|
351
333
|
Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.
|
|
352
334
|
|
|
353
335
|
When arrays are stringified, by default they are given explicit indices:
|
|
@@ -373,6 +355,8 @@ qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
|
|
|
373
355
|
// 'a[]=b&a[]=c'
|
|
374
356
|
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
|
|
375
357
|
// 'a=b&a=c'
|
|
358
|
+
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' })
|
|
359
|
+
// 'a=b,c'
|
|
376
360
|
```
|
|
377
361
|
|
|
378
362
|
When objects are stringified, by default they use bracket notation:
|
|
@@ -569,28 +553,18 @@ assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c');
|
|
|
569
553
|
assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');
|
|
570
554
|
```
|
|
571
555
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
[
|
|
583
|
-
[
|
|
584
|
-
[deps-svg]: https://david-dm.org/ljharb/qs.svg
|
|
585
|
-
[deps-url]: https://david-dm.org/ljharb/qs
|
|
586
|
-
[dev-deps-svg]: https://david-dm.org/ljharb/qs/dev-status.svg
|
|
587
|
-
[dev-deps-url]: https://david-dm.org/ljharb/qs#info=devDependencies
|
|
588
|
-
[npm-badge-png]: https://nodei.co/npm/qs.png?downloads=true&stars=true
|
|
589
|
-
[license-image]: https://img.shields.io/npm/l/qs.svg
|
|
556
|
+
[1]: https://npmjs.org/package/qs
|
|
557
|
+
[2]: http://versionbadg.es/ljharb/qs.svg
|
|
558
|
+
[3]: https://api.travis-ci.org/ljharb/qs.svg
|
|
559
|
+
[4]: https://travis-ci.org/ljharb/qs
|
|
560
|
+
[5]: https://david-dm.org/ljharb/qs.svg
|
|
561
|
+
[6]: https://david-dm.org/ljharb/qs
|
|
562
|
+
[7]: https://david-dm.org/ljharb/qs/dev-status.svg
|
|
563
|
+
[8]: https://david-dm.org/ljharb/qs?type=dev
|
|
564
|
+
[9]: https://ci.testling.com/ljharb/qs.png
|
|
565
|
+
[10]: https://ci.testling.com/ljharb/qs
|
|
566
|
+
[11]: https://nodei.co/npm/qs.png?downloads=true&stars=true
|
|
567
|
+
[license-image]: http://img.shields.io/npm/l/qs.svg
|
|
590
568
|
[license-url]: LICENSE
|
|
591
|
-
[downloads-image]:
|
|
592
|
-
[downloads-url]:
|
|
593
|
-
[codecov-image]: https://codecov.io/gh/ljharb/qs/branch/main/graphs/badge.svg
|
|
594
|
-
[codecov-url]: https://app.codecov.io/gh/ljharb/qs/
|
|
595
|
-
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/qs
|
|
596
|
-
[actions-url]: https://github.com/ljharb/qs/actions
|
|
569
|
+
[downloads-image]: http://img.shields.io/npm/dm/qs.svg
|
|
570
|
+
[downloads-url]: http://npm-stat.com/charts.html?package=qs
|
package/dist/qs.js
CHANGED
|
@@ -4,29 +4,21 @@
|
|
|
4
4
|
var replace = String.prototype.replace;
|
|
5
5
|
var percentTwenties = /%20/g;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
module.exports = {
|
|
8
|
+
'default': 'RFC3986',
|
|
9
|
+
formatters: {
|
|
10
|
+
RFC1738: function (value) {
|
|
11
|
+
return replace.call(value, percentTwenties, '+');
|
|
12
|
+
},
|
|
13
|
+
RFC3986: function (value) {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
},
|
|
10
17
|
RFC1738: 'RFC1738',
|
|
11
18
|
RFC3986: 'RFC3986'
|
|
12
19
|
};
|
|
13
20
|
|
|
14
|
-
module
|
|
15
|
-
{
|
|
16
|
-
'default': Format.RFC3986,
|
|
17
|
-
formatters: {
|
|
18
|
-
RFC1738: function (value) {
|
|
19
|
-
return replace.call(value, percentTwenties, '+');
|
|
20
|
-
},
|
|
21
|
-
RFC3986: function (value) {
|
|
22
|
-
return String(value);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
Format
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
},{"./utils":5}],2:[function(require,module,exports){
|
|
21
|
+
},{}],2:[function(require,module,exports){
|
|
30
22
|
'use strict';
|
|
31
23
|
|
|
32
24
|
var stringify = require('./stringify');
|
|
@@ -52,6 +44,7 @@ var defaults = {
|
|
|
52
44
|
arrayLimit: 20,
|
|
53
45
|
charset: 'utf-8',
|
|
54
46
|
charsetSentinel: false,
|
|
47
|
+
comma: false,
|
|
55
48
|
decoder: utils.decode,
|
|
56
49
|
delimiter: '&',
|
|
57
50
|
depth: 5,
|
|
@@ -123,6 +116,11 @@ var parseValues = function parseQueryStringValues(str, options) {
|
|
|
123
116
|
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
|
|
124
117
|
val = interpretNumericEntities(val);
|
|
125
118
|
}
|
|
119
|
+
|
|
120
|
+
if (val && options.comma && val.indexOf(',') > -1) {
|
|
121
|
+
val = val.split(',');
|
|
122
|
+
}
|
|
123
|
+
|
|
126
124
|
if (has.call(obj, key)) {
|
|
127
125
|
obj[key] = utils.combine(obj[key], val);
|
|
128
126
|
} else {
|
|
@@ -157,7 +155,7 @@ var parseObject = function (chain, val, options) {
|
|
|
157
155
|
) {
|
|
158
156
|
obj = [];
|
|
159
157
|
obj[index] = leaf;
|
|
160
|
-
} else
|
|
158
|
+
} else {
|
|
161
159
|
obj[cleanRoot] = leaf;
|
|
162
160
|
}
|
|
163
161
|
}
|
|
@@ -242,6 +240,7 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
|
|
|
242
240
|
arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
|
|
243
241
|
charset: charset,
|
|
244
242
|
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
|
243
|
+
comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
|
|
245
244
|
decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
|
|
246
245
|
delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
|
|
247
246
|
depth: typeof opts.depth === 'number' ? opts.depth : defaults.depth,
|
|
@@ -284,13 +283,14 @@ var formats = require('./formats');
|
|
|
284
283
|
var has = Object.prototype.hasOwnProperty;
|
|
285
284
|
|
|
286
285
|
var arrayPrefixGenerators = {
|
|
287
|
-
brackets: function brackets(prefix) {
|
|
286
|
+
brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
|
|
288
287
|
return prefix + '[]';
|
|
289
288
|
},
|
|
290
|
-
|
|
289
|
+
comma: 'comma',
|
|
290
|
+
indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
|
|
291
291
|
return prefix + '[' + key + ']';
|
|
292
292
|
},
|
|
293
|
-
repeat: function repeat(prefix) {
|
|
293
|
+
repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
|
|
294
294
|
return prefix;
|
|
295
295
|
}
|
|
296
296
|
};
|
|
@@ -303,7 +303,6 @@ var pushToArray = function (arr, valueOrArray) {
|
|
|
303
303
|
|
|
304
304
|
var toISO = Date.prototype.toISOString;
|
|
305
305
|
|
|
306
|
-
var defaultFormat = formats['default'];
|
|
307
306
|
var defaults = {
|
|
308
307
|
addQueryPrefix: false,
|
|
309
308
|
allowDots: false,
|
|
@@ -313,18 +312,17 @@ var defaults = {
|
|
|
313
312
|
encode: true,
|
|
314
313
|
encoder: utils.encode,
|
|
315
314
|
encodeValuesOnly: false,
|
|
316
|
-
|
|
317
|
-
formatter: formats.formatters[defaultFormat],
|
|
315
|
+
formatter: formats.formatters[formats['default']],
|
|
318
316
|
// deprecated
|
|
319
317
|
indices: false,
|
|
320
|
-
serializeDate: function serializeDate(date) {
|
|
318
|
+
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
|
|
321
319
|
return toISO.call(date);
|
|
322
320
|
},
|
|
323
321
|
skipNulls: false,
|
|
324
322
|
strictNullHandling: false
|
|
325
323
|
};
|
|
326
324
|
|
|
327
|
-
var stringify = function stringify(
|
|
325
|
+
var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
328
326
|
object,
|
|
329
327
|
prefix,
|
|
330
328
|
generateArrayPrefix,
|
|
@@ -344,6 +342,8 @@ var stringify = function stringify(
|
|
|
344
342
|
obj = filter(prefix, obj);
|
|
345
343
|
} else if (obj instanceof Date) {
|
|
346
344
|
obj = serializeDate(obj);
|
|
345
|
+
} else if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
|
346
|
+
obj = obj.join(',');
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
if (obj === null) {
|
|
@@ -386,7 +386,7 @@ var stringify = function stringify(
|
|
|
386
386
|
if (isArray(obj)) {
|
|
387
387
|
pushToArray(values, stringify(
|
|
388
388
|
obj[key],
|
|
389
|
-
generateArrayPrefix(prefix, key),
|
|
389
|
+
typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix,
|
|
390
390
|
generateArrayPrefix,
|
|
391
391
|
strictNullHandling,
|
|
392
392
|
skipNulls,
|
|
@@ -426,7 +426,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
|
|
426
426
|
return defaults;
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
if (opts.encoder !== null &&
|
|
429
|
+
if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
|
|
430
430
|
throw new TypeError('Encoder has to be a function.');
|
|
431
431
|
}
|
|
432
432
|
|
package/lib/formats.js
CHANGED
|
@@ -3,24 +3,16 @@
|
|
|
3
3
|
var replace = String.prototype.replace;
|
|
4
4
|
var percentTwenties = /%20/g;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
module.exports = {
|
|
7
|
+
'default': 'RFC3986',
|
|
8
|
+
formatters: {
|
|
9
|
+
RFC1738: function (value) {
|
|
10
|
+
return replace.call(value, percentTwenties, '+');
|
|
11
|
+
},
|
|
12
|
+
RFC3986: function (value) {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
},
|
|
9
16
|
RFC1738: 'RFC1738',
|
|
10
17
|
RFC3986: 'RFC3986'
|
|
11
18
|
};
|
|
12
|
-
|
|
13
|
-
module.exports = util.assign(
|
|
14
|
-
{
|
|
15
|
-
'default': Format.RFC3986,
|
|
16
|
-
formatters: {
|
|
17
|
-
RFC1738: function (value) {
|
|
18
|
-
return replace.call(value, percentTwenties, '+');
|
|
19
|
-
},
|
|
20
|
-
RFC3986: function (value) {
|
|
21
|
-
return String(value);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
Format
|
|
26
|
-
);
|
package/lib/parse.js
CHANGED
|
@@ -10,6 +10,7 @@ var defaults = {
|
|
|
10
10
|
arrayLimit: 20,
|
|
11
11
|
charset: 'utf-8',
|
|
12
12
|
charsetSentinel: false,
|
|
13
|
+
comma: false,
|
|
13
14
|
decoder: utils.decode,
|
|
14
15
|
delimiter: '&',
|
|
15
16
|
depth: 5,
|
|
@@ -81,6 +82,11 @@ var parseValues = function parseQueryStringValues(str, options) {
|
|
|
81
82
|
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
|
|
82
83
|
val = interpretNumericEntities(val);
|
|
83
84
|
}
|
|
85
|
+
|
|
86
|
+
if (val && options.comma && val.indexOf(',') > -1) {
|
|
87
|
+
val = val.split(',');
|
|
88
|
+
}
|
|
89
|
+
|
|
84
90
|
if (has.call(obj, key)) {
|
|
85
91
|
obj[key] = utils.combine(obj[key], val);
|
|
86
92
|
} else {
|
|
@@ -115,7 +121,7 @@ var parseObject = function (chain, val, options) {
|
|
|
115
121
|
) {
|
|
116
122
|
obj = [];
|
|
117
123
|
obj[index] = leaf;
|
|
118
|
-
} else
|
|
124
|
+
} else {
|
|
119
125
|
obj[cleanRoot] = leaf;
|
|
120
126
|
}
|
|
121
127
|
}
|
|
@@ -200,6 +206,7 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
|
|
|
200
206
|
arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
|
|
201
207
|
charset: charset,
|
|
202
208
|
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
|
209
|
+
comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
|
|
203
210
|
decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
|
|
204
211
|
delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
|
|
205
212
|
depth: typeof opts.depth === 'number' ? opts.depth : defaults.depth,
|
package/lib/stringify.js
CHANGED
|
@@ -5,13 +5,14 @@ var formats = require('./formats');
|
|
|
5
5
|
var has = Object.prototype.hasOwnProperty;
|
|
6
6
|
|
|
7
7
|
var arrayPrefixGenerators = {
|
|
8
|
-
brackets: function brackets(prefix) {
|
|
8
|
+
brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
|
|
9
9
|
return prefix + '[]';
|
|
10
10
|
},
|
|
11
|
-
|
|
11
|
+
comma: 'comma',
|
|
12
|
+
indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
|
|
12
13
|
return prefix + '[' + key + ']';
|
|
13
14
|
},
|
|
14
|
-
repeat: function repeat(prefix) {
|
|
15
|
+
repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
|
|
15
16
|
return prefix;
|
|
16
17
|
}
|
|
17
18
|
};
|
|
@@ -24,7 +25,6 @@ var pushToArray = function (arr, valueOrArray) {
|
|
|
24
25
|
|
|
25
26
|
var toISO = Date.prototype.toISOString;
|
|
26
27
|
|
|
27
|
-
var defaultFormat = formats['default'];
|
|
28
28
|
var defaults = {
|
|
29
29
|
addQueryPrefix: false,
|
|
30
30
|
allowDots: false,
|
|
@@ -34,18 +34,17 @@ var defaults = {
|
|
|
34
34
|
encode: true,
|
|
35
35
|
encoder: utils.encode,
|
|
36
36
|
encodeValuesOnly: false,
|
|
37
|
-
|
|
38
|
-
formatter: formats.formatters[defaultFormat],
|
|
37
|
+
formatter: formats.formatters[formats['default']],
|
|
39
38
|
// deprecated
|
|
40
39
|
indices: false,
|
|
41
|
-
serializeDate: function serializeDate(date) {
|
|
40
|
+
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
|
|
42
41
|
return toISO.call(date);
|
|
43
42
|
},
|
|
44
43
|
skipNulls: false,
|
|
45
44
|
strictNullHandling: false
|
|
46
45
|
};
|
|
47
46
|
|
|
48
|
-
var stringify = function stringify(
|
|
47
|
+
var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
49
48
|
object,
|
|
50
49
|
prefix,
|
|
51
50
|
generateArrayPrefix,
|
|
@@ -65,6 +64,8 @@ var stringify = function stringify(
|
|
|
65
64
|
obj = filter(prefix, obj);
|
|
66
65
|
} else if (obj instanceof Date) {
|
|
67
66
|
obj = serializeDate(obj);
|
|
67
|
+
} else if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
|
68
|
+
obj = obj.join(',');
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
if (obj === null) {
|
|
@@ -107,7 +108,7 @@ var stringify = function stringify(
|
|
|
107
108
|
if (isArray(obj)) {
|
|
108
109
|
pushToArray(values, stringify(
|
|
109
110
|
obj[key],
|
|
110
|
-
generateArrayPrefix(prefix, key),
|
|
111
|
+
typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix,
|
|
111
112
|
generateArrayPrefix,
|
|
112
113
|
strictNullHandling,
|
|
113
114
|
skipNulls,
|
|
@@ -147,7 +148,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
|
|
147
148
|
return defaults;
|
|
148
149
|
}
|
|
149
150
|
|
|
150
|
-
if (opts.encoder !== null &&
|
|
151
|
+
if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
|
|
151
152
|
throw new TypeError('Encoder has to be a function.');
|
|
152
153
|
}
|
|
153
154
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "qs",
|
|
3
3
|
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
|
4
4
|
"homepage": "https://github.com/ljharb/qs",
|
|
5
|
-
"version": "6.
|
|
5
|
+
"version": "6.7.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -17,39 +17,41 @@
|
|
|
17
17
|
],
|
|
18
18
|
"keywords": [
|
|
19
19
|
"querystring",
|
|
20
|
-
"qs"
|
|
20
|
+
"qs",
|
|
21
|
+
"query",
|
|
22
|
+
"url",
|
|
23
|
+
"parse",
|
|
24
|
+
"stringify"
|
|
21
25
|
],
|
|
22
26
|
"engines": {
|
|
23
27
|
"node": ">=0.6"
|
|
24
28
|
},
|
|
29
|
+
"dependencies": {},
|
|
25
30
|
"devDependencies": {
|
|
26
|
-
"@ljharb/eslint-config": "^
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"eslint": "^
|
|
31
|
+
"@ljharb/eslint-config": "^13.1.1",
|
|
32
|
+
"browserify": "^16.2.3",
|
|
33
|
+
"covert": "^1.1.1",
|
|
34
|
+
"editorconfig-tools": "^0.1.1",
|
|
35
|
+
"eslint": "^5.15.3",
|
|
31
36
|
"evalmd": "^0.0.17",
|
|
32
37
|
"for-each": "^0.3.3",
|
|
33
38
|
"iconv-lite": "^0.4.24",
|
|
34
|
-
"in-publish": "^2.0.1",
|
|
35
39
|
"mkdirp": "^0.5.1",
|
|
36
|
-
"
|
|
37
|
-
"object-inspect": "^1.12.0",
|
|
40
|
+
"object-inspect": "^1.6.0",
|
|
38
41
|
"qs-iconv": "^1.0.4",
|
|
39
|
-
"safe-publish-latest": "^
|
|
42
|
+
"safe-publish-latest": "^1.1.2",
|
|
40
43
|
"safer-buffer": "^2.1.2",
|
|
41
|
-
"tape": "^4.
|
|
44
|
+
"tape": "^4.10.1"
|
|
42
45
|
},
|
|
43
46
|
"scripts": {
|
|
44
|
-
"
|
|
45
|
-
"prepublish": "not-in-publish || npm run prepublishOnly",
|
|
47
|
+
"prepublish": "safe-publish-latest && npm run dist",
|
|
46
48
|
"pretest": "npm run --silent readme && npm run --silent lint",
|
|
47
|
-
"test": "npm run --silent
|
|
48
|
-
"tests-only": "
|
|
49
|
-
"posttest": "aud --production",
|
|
49
|
+
"test": "npm run --silent coverage",
|
|
50
|
+
"tests-only": "node test",
|
|
50
51
|
"readme": "evalmd README.md",
|
|
51
|
-
"postlint": "
|
|
52
|
-
"lint": "eslint
|
|
52
|
+
"postlint": "editorconfig-tools check * lib/* test/*",
|
|
53
|
+
"lint": "eslint lib/*.js test/*.js",
|
|
54
|
+
"coverage": "covert test",
|
|
53
55
|
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
54
56
|
},
|
|
55
57
|
"license": "BSD-3-Clause"
|
package/test/.eslintrc
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rules": {
|
|
3
|
+
"array-bracket-newline": 0,
|
|
4
|
+
"array-element-newline": 0,
|
|
5
|
+
"consistent-return": 2,
|
|
6
|
+
"function-paren-newline": 0,
|
|
7
|
+
"max-lines": 0,
|
|
8
|
+
"max-lines-per-function": 0,
|
|
9
|
+
"max-nested-callbacks": [2, 3],
|
|
10
|
+
"max-statements": 0,
|
|
11
|
+
"no-buffer-constructor": 0,
|
|
12
|
+
"no-extend-native": 0,
|
|
13
|
+
"no-magic-numbers": 0,
|
|
14
|
+
"object-curly-newline": 0,
|
|
15
|
+
"sort-keys": 0
|
|
16
|
+
}
|
|
17
|
+
}
|
package/test/parse.js
CHANGED
|
@@ -347,6 +347,15 @@ test('parse()', function (t) {
|
|
|
347
347
|
st.end();
|
|
348
348
|
});
|
|
349
349
|
|
|
350
|
+
t.test('parses string with comma as array divider', function (st) {
|
|
351
|
+
st.deepEqual(qs.parse('foo=bar,tee', { comma: true }), { foo: ['bar', 'tee'] });
|
|
352
|
+
st.deepEqual(qs.parse('foo[bar]=coffee,tee', { comma: true }), { foo: { bar: ['coffee', 'tee'] } });
|
|
353
|
+
st.deepEqual(qs.parse('foo=', { comma: true }), { foo: '' });
|
|
354
|
+
st.deepEqual(qs.parse('foo', { comma: true }), { foo: '' });
|
|
355
|
+
st.deepEqual(qs.parse('foo', { comma: true, strictNullHandling: true }), { foo: null });
|
|
356
|
+
st.end();
|
|
357
|
+
});
|
|
358
|
+
|
|
350
359
|
t.test('parses an object in dot notation', function (st) {
|
|
351
360
|
var input = {
|
|
352
361
|
'user.name': { 'pop[bob]': 3 },
|
|
@@ -530,66 +539,6 @@ test('parse()', function (t) {
|
|
|
530
539
|
st.end();
|
|
531
540
|
});
|
|
532
541
|
|
|
533
|
-
t.test('dunder proto is ignored', function (st) {
|
|
534
|
-
var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42';
|
|
535
|
-
var result = qs.parse(payload, { allowPrototypes: true });
|
|
536
|
-
|
|
537
|
-
st.deepEqual(
|
|
538
|
-
result,
|
|
539
|
-
{
|
|
540
|
-
categories: {
|
|
541
|
-
length: '42'
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
'silent [[Prototype]] payload'
|
|
545
|
-
);
|
|
546
|
-
|
|
547
|
-
var plainResult = qs.parse(payload, { allowPrototypes: true, plainObjects: true });
|
|
548
|
-
|
|
549
|
-
st.deepEqual(
|
|
550
|
-
plainResult,
|
|
551
|
-
{
|
|
552
|
-
__proto__: null,
|
|
553
|
-
categories: {
|
|
554
|
-
__proto__: null,
|
|
555
|
-
length: '42'
|
|
556
|
-
}
|
|
557
|
-
},
|
|
558
|
-
'silent [[Prototype]] payload: plain objects'
|
|
559
|
-
);
|
|
560
|
-
|
|
561
|
-
var query = qs.parse('categories[__proto__]=cats&categories[__proto__]=dogs&categories[some][json]=toInject', { allowPrototypes: true });
|
|
562
|
-
|
|
563
|
-
st.notOk(Array.isArray(query.categories), 'is not an array');
|
|
564
|
-
st.notOk(query.categories instanceof Array, 'is not instanceof an array');
|
|
565
|
-
st.deepEqual(query.categories, { some: { json: 'toInject' } });
|
|
566
|
-
st.equal(JSON.stringify(query.categories), '{"some":{"json":"toInject"}}', 'stringifies as a non-array');
|
|
567
|
-
|
|
568
|
-
st.deepEqual(
|
|
569
|
-
qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true }),
|
|
570
|
-
{
|
|
571
|
-
foo: {
|
|
572
|
-
bar: 'stuffs'
|
|
573
|
-
}
|
|
574
|
-
},
|
|
575
|
-
'hidden values'
|
|
576
|
-
);
|
|
577
|
-
|
|
578
|
-
st.deepEqual(
|
|
579
|
-
qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true, plainObjects: true }),
|
|
580
|
-
{
|
|
581
|
-
__proto__: null,
|
|
582
|
-
foo: {
|
|
583
|
-
__proto__: null,
|
|
584
|
-
bar: 'stuffs'
|
|
585
|
-
}
|
|
586
|
-
},
|
|
587
|
-
'hidden values: plain objects'
|
|
588
|
-
);
|
|
589
|
-
|
|
590
|
-
st.end();
|
|
591
|
-
});
|
|
592
|
-
|
|
593
542
|
t.test('can return null objects', { skip: !Object.create }, function (st) {
|
|
594
543
|
var expected = Object.create(null);
|
|
595
544
|
expected.a = Object.create(null);
|
package/test/stringify.js
CHANGED
|
@@ -68,6 +68,11 @@ test('stringify()', function (t) {
|
|
|
68
68
|
'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d',
|
|
69
69
|
'brackets => brackets'
|
|
70
70
|
);
|
|
71
|
+
st.equal(
|
|
72
|
+
qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma' }),
|
|
73
|
+
'a=b%2Cc%2Cd',
|
|
74
|
+
'comma => comma'
|
|
75
|
+
);
|
|
71
76
|
st.equal(
|
|
72
77
|
qs.stringify({ a: ['b', 'c', 'd'] }),
|
|
73
78
|
'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
|
|
@@ -94,6 +99,7 @@ test('stringify()', function (t) {
|
|
|
94
99
|
t.test('stringifies a nested array value', function (st) {
|
|
95
100
|
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
|
|
96
101
|
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a%5Bb%5D%5B%5D=c&a%5Bb%5D%5B%5D=d');
|
|
102
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'comma' }), 'a%5Bb%5D=c%2Cd'); // a[b]=c,d
|
|
97
103
|
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
|
|
98
104
|
st.end();
|
|
99
105
|
});
|
|
@@ -115,6 +121,14 @@ test('stringify()', function (t) {
|
|
|
115
121
|
'a.b[]=c&a.b[]=d',
|
|
116
122
|
'brackets: stringifies with dots + brackets'
|
|
117
123
|
);
|
|
124
|
+
st.equal(
|
|
125
|
+
qs.stringify(
|
|
126
|
+
{ a: { b: ['c', 'd'] } },
|
|
127
|
+
{ allowDots: true, encode: false, arrayFormat: 'comma' }
|
|
128
|
+
),
|
|
129
|
+
'a.b=c,d',
|
|
130
|
+
'comma: stringifies with dots + comma'
|
|
131
|
+
);
|
|
118
132
|
st.equal(
|
|
119
133
|
qs.stringify(
|
|
120
134
|
{ a: { b: ['c', 'd'] } },
|
|
@@ -129,12 +143,12 @@ test('stringify()', function (t) {
|
|
|
129
143
|
t.test('stringifies an object inside an array', function (st) {
|
|
130
144
|
st.equal(
|
|
131
145
|
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices' }),
|
|
132
|
-
'a%5B0%5D%5Bb%5D=c',
|
|
146
|
+
'a%5B0%5D%5Bb%5D=c', // a[0][b]=c
|
|
133
147
|
'indices => brackets'
|
|
134
148
|
);
|
|
135
149
|
st.equal(
|
|
136
150
|
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets' }),
|
|
137
|
-
'a%5B%5D%5Bb%5D=c',
|
|
151
|
+
'a%5B%5D%5Bb%5D=c', // a[][b]=c
|
|
138
152
|
'brackets => brackets'
|
|
139
153
|
);
|
|
140
154
|
st.equal(
|
|
@@ -506,12 +520,6 @@ test('stringify()', function (t) {
|
|
|
506
520
|
return String.fromCharCode(buffer.readUInt8(0) + 97);
|
|
507
521
|
}
|
|
508
522
|
}), 'a=b');
|
|
509
|
-
|
|
510
|
-
st.equal(qs.stringify({ a: SaferBuffer.from('a b') }, {
|
|
511
|
-
encoder: function (buffer) {
|
|
512
|
-
return buffer;
|
|
513
|
-
}
|
|
514
|
-
}), 'a=a b');
|
|
515
523
|
st.end();
|
|
516
524
|
});
|
|
517
525
|
|
|
@@ -552,20 +560,17 @@ test('stringify()', function (t) {
|
|
|
552
560
|
t.test('RFC 1738 spaces serialization', function (st) {
|
|
553
561
|
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c');
|
|
554
562
|
st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d');
|
|
555
|
-
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC1738 }), 'a+b=a+b');
|
|
556
563
|
st.end();
|
|
557
564
|
});
|
|
558
565
|
|
|
559
566
|
t.test('RFC 3986 spaces serialization', function (st) {
|
|
560
567
|
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c');
|
|
561
568
|
st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d');
|
|
562
|
-
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC3986 }), 'a%20b=a%20b');
|
|
563
569
|
st.end();
|
|
564
570
|
});
|
|
565
571
|
|
|
566
572
|
t.test('Backward compatibility to RFC 3986', function (st) {
|
|
567
573
|
st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
|
|
568
|
-
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }), 'a%20b=a%20b');
|
|
569
574
|
st.end();
|
|
570
575
|
});
|
|
571
576
|
|
package/.github/FUNDING.yml
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# These are supported funding model platforms
|
|
2
|
-
|
|
3
|
-
github: [ljharb]
|
|
4
|
-
patreon: # Replace with a single Patreon username
|
|
5
|
-
open_collective: # Replace with a single Open Collective username
|
|
6
|
-
ko_fi: # Replace with a single Ko-fi username
|
|
7
|
-
tidelift: npm/qs
|
|
8
|
-
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
-
liberapay: # Replace with a single Liberapay username
|
|
10
|
-
issuehunt: # Replace with a single IssueHunt username
|
|
11
|
-
otechie: # Replace with a single Otechie username
|
|
12
|
-
custom: # Replace with a single custom sponsorship URL
|
package/.nycrc
DELETED
package/LICENSE.md
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
BSD 3-Clause License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2014, Nathan LaFreniere and other [contributors](https://github.com/ljharb/qs/graphs/contributors)
|
|
4
|
-
All rights reserved.
|
|
5
|
-
|
|
6
|
-
Redistribution and use in source and binary forms, with or without
|
|
7
|
-
modification, are permitted provided that the following conditions are met:
|
|
8
|
-
|
|
9
|
-
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
-
list of conditions and the following disclaimer.
|
|
11
|
-
|
|
12
|
-
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
-
this list of conditions and the following disclaimer in the documentation
|
|
14
|
-
and/or other materials provided with the distribution.
|
|
15
|
-
|
|
16
|
-
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
-
contributors may be used to endorse or promote products derived from
|
|
18
|
-
this software without specific prior written permission.
|
|
19
|
-
|
|
20
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|