|
|
'use strict'; var strictUriEncode = require('strict-uri-encode'); var objectAssign = require('object-assign');
function encoderForArrayFormat(opts) { switch (opts.arrayFormat) { case 'index': return function (key, value, index) { return value === null ? [ encode(key, opts), '[', index, ']' ].join('') : [ encode(key, opts), '[', encode(index, opts), ']=', encode(value, opts) ].join(''); };
case 'bracket': return function (key, value) { return value === null ? encode(key, opts) : [ encode(key, opts), '[]=', encode(value, opts) ].join(''); };
default: return function (key, value) { return value === null ? encode(key, opts) : [ encode(key, opts), '=', encode(value, opts) ].join(''); }; } }
function parserForArrayFormat(opts) { var result;
switch (opts.arrayFormat) { case 'index': return function (key, value, accumulator) { result = /\[(\d*)\]$/.exec(key);
key = key.replace(/\[\d*\]$/, '');
if (!result) { accumulator[key] = value; return; }
if (accumulator[key] === undefined) { accumulator[key] = {}; }
accumulator[key][result[1]] = value; };
case 'bracket': return function (key, value, accumulator) { result = /(\[\])$/.exec(key); key = key.replace(/\[\]$/, '');
if (!result) { accumulator[key] = value; return; } else if (accumulator[key] === undefined) { accumulator[key] = [value]; return; }
accumulator[key] = [].concat(accumulator[key], value); };
default: return function (key, value, accumulator) { if (accumulator[key] === undefined) { accumulator[key] = value; return; }
accumulator[key] = [].concat(accumulator[key], value); }; } }
function encode(value, opts) { if (opts.encode) { return opts.strict ? strictUriEncode(value) : encodeURIComponent(value); }
return value; }
function keysSorter(input) { if (Array.isArray(input)) { return input.sort(); } else if (typeof input === 'object') { return keysSorter(Object.keys(input)).sort(function (a, b) { return Number(a) - Number(b); }).map(function (key) { return input[key]; }); }
return input; }
exports.extract = function (str) { return str.split('?')[1] || ''; };
exports.parse = function (str, opts) { opts = objectAssign({arrayFormat: 'none'}, opts);
var formatter = parserForArrayFormat(opts);
// Create an object with no prototype
// https://github.com/sindresorhus/query-string/issues/47
var ret = Object.create(null);
if (typeof str !== 'string') { return ret; }
str = str.trim().replace(/^(\?|#|&)/, '');
if (!str) { return ret; }
str.split('&').forEach(function (param) { var parts = param.replace(/\+/g, ' ').split('='); // Firefox (pre 40) decodes `%3D` to `=`
// https://github.com/sindresorhus/query-string/pull/37
var key = parts.shift(); var val = parts.length > 0 ? parts.join('=') : undefined;
// missing `=` should be `null`:
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
val = val === undefined ? null : decodeURIComponent(val);
formatter(decodeURIComponent(key), val, ret); });
return Object.keys(ret).sort().reduce(function (result, key) { var val = ret[key]; if (Boolean(val) && typeof val === 'object' && !Array.isArray(val)) { // Sort object keys, not values
result[key] = keysSorter(val); } else { result[key] = val; }
return result; }, Object.create(null)); };
exports.stringify = function (obj, opts) { var defaults = { encode: true, strict: true, arrayFormat: 'none' };
opts = objectAssign(defaults, opts);
var formatter = encoderForArrayFormat(opts);
return obj ? Object.keys(obj).sort().map(function (key) { var val = obj[key];
if (val === undefined) { return ''; }
if (val === null) { return encode(key, opts); }
if (Array.isArray(val)) { var result = [];
val.slice().forEach(function (val2) { if (val2 === undefined) { return; }
result.push(formatter(key, val2, result.length)); });
return result.join('&'); }
return encode(key, opts) + '=' + encode(val, opts); }).filter(function (x) { return x.length > 0; }).join('&') : ''; };
|