Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/query-string/index.js')
-rw-r--r--node_modules/query-string/index.js144
1 files changed, 122 insertions, 22 deletions
diff --git a/node_modules/query-string/index.js b/node_modules/query-string/index.js
index 35c13e1a6..de1d7b182 100644
--- a/node_modules/query-string/index.js
+++ b/node_modules/query-string/index.js
@@ -3,12 +3,19 @@ const strictUriEncode = require('strict-uri-encode');
const decodeComponent = require('decode-uri-component');
const splitOnFirst = require('split-on-first');
+const isNullOrUndefined = value => value === null || value === undefined;
+
function encoderForArrayFormat(options) {
switch (options.arrayFormat) {
case 'index':
return key => (result, value) => {
const index = result.length;
- if (value === undefined) {
+
+ if (
+ value === undefined ||
+ (options.skipNull && value === null) ||
+ (options.skipEmptyString && value === '')
+ ) {
return result;
}
@@ -24,7 +31,11 @@ function encoderForArrayFormat(options) {
case 'bracket':
return key => (result, value) => {
- if (value === undefined) {
+ if (
+ value === undefined ||
+ (options.skipNull && value === null) ||
+ (options.skipEmptyString && value === '')
+ ) {
return result;
}
@@ -36,21 +47,26 @@ function encoderForArrayFormat(options) {
};
case 'comma':
- return key => (result, value, index) => {
+ case 'separator':
+ return key => (result, value) => {
if (value === null || value === undefined || value.length === 0) {
return result;
}
- if (index === 0) {
+ if (result.length === 0) {
return [[encode(key, options), '=', encode(value, options)].join('')];
}
- return [[result, encode(value, options)].join(',')];
+ return [[result, encode(value, options)].join(options.arrayFormatSeparator)];
};
default:
return key => (result, value) => {
- if (value === undefined) {
+ if (
+ value === undefined ||
+ (options.skipNull && value === null) ||
+ (options.skipEmptyString && value === '')
+ ) {
return result;
}
@@ -104,9 +120,10 @@ function parserForArrayFormat(options) {
};
case 'comma':
+ case 'separator':
return (key, value, accumulator) => {
- const isArray = typeof value === 'string' && value.split('').indexOf(',') > -1;
- const newValue = isArray ? value.split(',') : value;
+ const isArray = typeof value === 'string' && value.split('').indexOf(options.arrayFormatSeparator) > -1;
+ const newValue = isArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : value === null ? value : decode(value, options);
accumulator[key] = newValue;
};
@@ -122,6 +139,12 @@ function parserForArrayFormat(options) {
}
}
+function validateArrayFormatSeparator(value) {
+ if (typeof value !== 'string' || value.length !== 1) {
+ throw new TypeError('arrayFormatSeparator must be single character string');
+ }
+}
+
function encode(value, options) {
if (options.encode) {
return options.strict ? strictUriEncode(value) : encodeURIComponent(value);
@@ -161,6 +184,16 @@ function removeHash(input) {
return input;
}
+function getHash(url) {
+ let hash = '';
+ const hashStart = url.indexOf('#');
+ if (hashStart !== -1) {
+ hash = url.slice(hashStart);
+ }
+
+ return hash;
+}
+
function extract(input) {
input = removeHash(input);
const queryStart = input.indexOf('?');
@@ -171,15 +204,28 @@ function extract(input) {
return input.slice(queryStart + 1);
}
+function parseValue(value, options) {
+ if (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {
+ value = Number(value);
+ } else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {
+ value = value.toLowerCase() === 'true';
+ }
+
+ return value;
+}
+
function parse(input, options) {
options = Object.assign({
decode: true,
sort: true,
arrayFormat: 'none',
+ arrayFormatSeparator: ',',
parseNumbers: false,
parseBooleans: false
}, options);
+ validateArrayFormatSeparator(options.arrayFormatSeparator);
+
const formatter = parserForArrayFormat(options);
// Create an object with no prototype
@@ -196,19 +242,23 @@ function parse(input, options) {
}
for (const param of input.split('&')) {
- let [key, value] = splitOnFirst(param.replace(/\+/g, ' '), '=');
+ let [key, value] = splitOnFirst(options.decode ? param.replace(/\+/g, ' ') : param, '=');
// Missing `=` should be `null`:
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
- value = value === undefined ? null : decode(value, options);
+ value = value === undefined ? null : ['comma', 'separator'].includes(options.arrayFormat) ? value : decode(value, options);
+ formatter(decode(key, options), value, ret);
+ }
- if (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {
- value = Number(value);
- } else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {
- value = value.toLowerCase() === 'true';
+ for (const key of Object.keys(ret)) {
+ const value = ret[key];
+ if (typeof value === 'object' && value !== null) {
+ for (const k of Object.keys(value)) {
+ value[k] = parseValue(value[k], options);
+ }
+ } else {
+ ret[key] = parseValue(value, options);
}
-
- formatter(decode(key, options), value, ret);
}
if (options.sort === false) {
@@ -239,11 +289,28 @@ exports.stringify = (object, options) => {
options = Object.assign({
encode: true,
strict: true,
- arrayFormat: 'none'
+ arrayFormat: 'none',
+ arrayFormatSeparator: ','
}, options);
+ validateArrayFormatSeparator(options.arrayFormatSeparator);
+
+ const shouldFilter = key => (
+ (options.skipNull && isNullOrUndefined(object[key])) ||
+ (options.skipEmptyString && object[key] === '')
+ );
+
const formatter = encoderForArrayFormat(options);
- const keys = Object.keys(object);
+
+ const objectCopy = {};
+
+ for (const key of Object.keys(object)) {
+ if (!shouldFilter(key)) {
+ objectCopy[key] = object[key];
+ }
+ }
+
+ const keys = Object.keys(objectCopy);
if (options.sort !== false) {
keys.sort(options.sort);
@@ -271,8 +338,41 @@ exports.stringify = (object, options) => {
};
exports.parseUrl = (input, options) => {
- return {
- url: removeHash(input).split('?')[0] || '',
- query: parse(extract(input), options)
- };
+ options = Object.assign({
+ decode: true
+ }, options);
+
+ const [url, hash] = splitOnFirst(input, '#');
+
+ return Object.assign(
+ {
+ url: url.split('?')[0] || '',
+ query: parse(extract(input), options)
+ },
+ options && options.parseFragmentIdentifier && hash ? {fragmentIdentifier: decode(hash, options)} : {}
+ );
+};
+
+exports.stringifyUrl = (input, options) => {
+ options = Object.assign({
+ encode: true,
+ strict: true
+ }, options);
+
+ const url = removeHash(input.url).split('?')[0] || '';
+ const queryFromUrl = exports.extract(input.url);
+ const parsedQueryFromUrl = exports.parse(queryFromUrl, {sort: false});
+
+ const query = Object.assign(parsedQueryFromUrl, input.query);
+ let queryString = exports.stringify(query, options);
+ if (queryString) {
+ queryString = `?${queryString}`;
+ }
+
+ let hash = getHash(input.url);
+ if (input.fragmentIdentifier) {
+ hash = `#${encode(input.fragmentIdentifier, options)}`;
+ }
+
+ return `${url}${queryString}${hash}`;
};