feat: ✨ Created a mini nodeJS server with NewMan for testing without PostMan GUI.
This will mimic a run in a CD/CI environment or docker container.
This commit is contained in:
341
node_modules/postman-url-encoder/encoder/encode-set.js
generated
vendored
Normal file
341
node_modules/postman-url-encoder/encoder/encode-set.js
generated
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* An EncodeSet represents a set of characters that should be percent-encoded.
|
||||
*
|
||||
* Different characters need to be encoded in different parts of an URL.
|
||||
* For example, a literal ? question mark in an URL’s path would indicate the
|
||||
* start of the query string. A question mark meant to be part of the path
|
||||
* therefore needs to be percent-encoded.
|
||||
* In the query string however, a question mark does not have any special
|
||||
* meaning and does not need to be percent-encoded.
|
||||
*
|
||||
* A few sets are defined in this module.
|
||||
* Use the {@link EncodeSet} class to define different ones.
|
||||
*
|
||||
* @see {@link https://url.spec.whatwg.org/#simple-encode-set}
|
||||
*/
|
||||
|
||||
/**
|
||||
* A character (String), or character code (Number).
|
||||
*
|
||||
* @typedef {String|Number} Char
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Set or Array of {@link Char}(s).
|
||||
*
|
||||
* @typedef {Set.<Char>|Array.<Char>} CharSet
|
||||
*/
|
||||
|
||||
const QUERY_ENCODE_CHARS = [' ', '"', '#', '\'', '<', '>'],
|
||||
FRAGMENT_EXTEND_CHARS = [' ', '"', '<', '>', '`'],
|
||||
PATH_EXTEND_CHARS = ['#', '?', '{', '}'],
|
||||
USERINFO_EXTEND_CHARS = ['/', ':', ';', '=', '@', '[', '\\', ']', '^', '|'];
|
||||
|
||||
/**
|
||||
* Returns a number representing the UTF-16 code unit value of the character.
|
||||
*
|
||||
* @private
|
||||
* @param {Char} char Character or character code
|
||||
* @returns {Number} Character code
|
||||
*/
|
||||
function charCode (char) {
|
||||
const code = (typeof char === 'string') ?
|
||||
// get char code from string
|
||||
char.charCodeAt(0) :
|
||||
// or, normalize char code using double Bitwise NOT
|
||||
// Refer: https://jsperf.com/truncating-decimals
|
||||
~~char;
|
||||
|
||||
// ensure UTF-16 range [0, 0xFFFF]
|
||||
return (code >= 0 && code <= 0xFFFF) ? code : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the EncodeSet with the given characters.
|
||||
*
|
||||
* @note Mutates the input EncodeSet.
|
||||
*
|
||||
* @private
|
||||
* @param {EncodeSet} encodeSet Instance of EncodeSet
|
||||
* @param {CharSet} chars Character set to extend
|
||||
* @returns {EncodeSet} Given EncodeSet
|
||||
*/
|
||||
function extendEncodeSet (encodeSet, chars) {
|
||||
// special handling for Uint8Array chars which signify an existing encode
|
||||
// set used to extend the given encodeSet.
|
||||
if (chars instanceof Uint8Array) {
|
||||
// iterate over fixed / known size set
|
||||
encodeSet._set.forEach((encoded, index) => {
|
||||
if (!encoded && chars[index]) {
|
||||
// encode charCodeAt(index)
|
||||
encodeSet._set[index] = 1;
|
||||
}
|
||||
});
|
||||
|
||||
return encodeSet;
|
||||
}
|
||||
|
||||
// check if the input characters are iterable or not
|
||||
if (!(chars && typeof chars.forEach === 'function')) {
|
||||
return encodeSet;
|
||||
}
|
||||
|
||||
chars.forEach((char) => {
|
||||
encodeSet.add(char);
|
||||
});
|
||||
|
||||
return encodeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a set of characters / bytes that should be percent-encoded.
|
||||
*/
|
||||
class EncodeSet {
|
||||
/**
|
||||
* @param {CharSet} chars Character set to encode
|
||||
*/
|
||||
constructor (chars) {
|
||||
/**
|
||||
* Indexes in Uint8Array represents char codes for characters to encode.
|
||||
*
|
||||
* Size: 128, ASCII range [0, 0x7F]
|
||||
*
|
||||
* where,
|
||||
* 1 -> encode
|
||||
* 0 -> don't encode
|
||||
*
|
||||
* @private
|
||||
* @type {Uint8Array}
|
||||
*/
|
||||
this._set = new Uint8Array(0x80);
|
||||
|
||||
// encode C0 control codes [00, 0x1F] AND 0x7F
|
||||
this._set.fill(1, 0, 0x20); // 0 to 31
|
||||
this._set[0x7F] = 1; // 127
|
||||
|
||||
/**
|
||||
* A Boolean indicating whether or not this EncodeSet is sealed.
|
||||
*
|
||||
* @private
|
||||
* @type {Boolean}
|
||||
*/
|
||||
this._sealed = false;
|
||||
|
||||
// extend this set with input characters
|
||||
extendEncodeSet(this, chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a new character to the EncodeSet.
|
||||
*
|
||||
* @example
|
||||
* var xyzEncodeSet = new EncodeSet(['x', 'y', 'z'])
|
||||
*
|
||||
* xyzEncodeSet
|
||||
* .add('X')
|
||||
* .add(89) // Y
|
||||
* .add(0x5a) // Z
|
||||
*
|
||||
* @param {Char} char Character or character code
|
||||
* @returns {EncodeSet} Current EncodeSet
|
||||
*/
|
||||
add (char) {
|
||||
// bail out if the EncodeSet is sealed
|
||||
if (this._sealed) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const code = charCode(char);
|
||||
|
||||
// ensure ASCII range
|
||||
if (code < 0x80) {
|
||||
this._set[code] = 1;
|
||||
}
|
||||
|
||||
// chaining
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean asserting whether the given char code will be encoded in
|
||||
* the EncodeSet or not.
|
||||
*
|
||||
* @note Always encode C0 control codes in the range U+0000 to U+001F and U+007F
|
||||
* Refer: https://infra.spec.whatwg.org/#c0-control
|
||||
*
|
||||
* @example
|
||||
* var tildeEncodeSet = new EncodeSet(['~'])
|
||||
*
|
||||
* // returns true
|
||||
* tildeEncodeSet.has('~'.charCodeAt(0))
|
||||
*
|
||||
* // returns false
|
||||
* tildeEncodeSet.has(65) // A
|
||||
*
|
||||
* // returns true
|
||||
* tildeEncodeSet.has(31) // \u001f (control character)
|
||||
*
|
||||
* @param {Number} code Character code
|
||||
* @returns {Boolean} Returns true if the character with the specified char code
|
||||
* exists in the EncodeSet; otherwise false
|
||||
*/
|
||||
has (code) {
|
||||
// encode if not in ASCII range (-∞, 0) OR (127, ∞)
|
||||
if (code < 0 || code > 0x7F) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// encode if present in the set
|
||||
return Boolean(this._set[code]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the current EncodeSet.
|
||||
*
|
||||
* @example
|
||||
* var set1 = new EncodeSet(['<', '>'])
|
||||
* var set1Copy = set1.clone().add('=')
|
||||
*
|
||||
* @returns {EncodeSet} New EncodeSet instance
|
||||
*/
|
||||
clone () {
|
||||
return new EncodeSet(this._set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seals the current EncodeSet to prevent new characters being added to it.
|
||||
*
|
||||
* @example
|
||||
* var set = new EncodeSet()
|
||||
*
|
||||
* set.add(95)
|
||||
* set.has(95) // returns true
|
||||
*
|
||||
* set.seal()
|
||||
* set.add(100)
|
||||
* set.has(100) // returns false
|
||||
*
|
||||
* @returns {EncodeSet} Current EncodeSet
|
||||
*/
|
||||
seal () {
|
||||
this._sealed = true;
|
||||
|
||||
try {
|
||||
// @note Cannot freeze array buffer views with elements.
|
||||
// So, rely upon the alternative `Object.seal` method and avoid mutations
|
||||
// via EncodeSet~add method.
|
||||
// Also, sealed Uint8Array enumerates faster in V8!
|
||||
Object.seal(this._set);
|
||||
}
|
||||
catch (_) {
|
||||
// silently swallow exceptions
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new EncodeSet by extending the input EncodeSet with additional
|
||||
* characters.
|
||||
*
|
||||
* @example
|
||||
* var fooEncodeSet = new EncodeSet(['f', 'o'])
|
||||
* var foobarEncodeSet = EncodeSet.extend(fooEncodeSet, new Set(['b', 'a', 'r']))
|
||||
*
|
||||
* @param {EncodeSet} encodeSet Instance of EncodeSet
|
||||
* @param {CharSet} chars Character set to encode
|
||||
* @returns {EncodeSet} Copy of given `encodeSet` with extended `chars`
|
||||
* @throws {TypeError} Argument `encodeSet` must be of type {@link EncodeSet}
|
||||
*/
|
||||
static extend (encodeSet, chars) {
|
||||
if (!EncodeSet.isEncodeSet(encodeSet)) {
|
||||
throw new TypeError('Argument `encodeSet` must be EncodeSet');
|
||||
}
|
||||
|
||||
// extend the cloned encodeSet to avoid mutations
|
||||
return extendEncodeSet(encodeSet.clone(), chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the input value is an EncodeSet or not.
|
||||
*
|
||||
* @example
|
||||
* // returns true
|
||||
* EncodeSet.isEncodeSet(new EncodeSet([40, 41]))
|
||||
*
|
||||
* // returns false
|
||||
* EncodeSet.isEncodeSet(new Set([28, 05]))
|
||||
*
|
||||
* @param {*} value The value to be tested
|
||||
* @returns {Boolean} true if the given value is an EncodeSet; otherwise, false
|
||||
*/
|
||||
static isEncodeSet (value) {
|
||||
return Boolean(value) && (value instanceof EncodeSet);
|
||||
}
|
||||
}
|
||||
|
||||
const // eslint-disable-line one-var
|
||||
|
||||
/**
|
||||
* The C0 control percent-encode set are the C0 controls and all code points
|
||||
* greater than U+007E (~).
|
||||
*
|
||||
* @const
|
||||
* @type {EncodeSet}
|
||||
* @see {@link https://url.spec.whatwg.org/#c0-control-percent-encode-set}
|
||||
*/
|
||||
C0_CONTROL_ENCODE_SET = new EncodeSet().seal(),
|
||||
|
||||
/**
|
||||
* The fragment percent-encode set is the C0 control percent-encode set and
|
||||
* U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), and U+0060 (`).
|
||||
*
|
||||
* @const
|
||||
* @type {EncodeSet}
|
||||
* @see {@link https://url.spec.whatwg.org/#fragment-percent-encode-set}
|
||||
*/
|
||||
FRAGMENT_ENCODE_SET = EncodeSet.extend(C0_CONTROL_ENCODE_SET, FRAGMENT_EXTEND_CHARS).seal(),
|
||||
|
||||
/**
|
||||
* The path percent-encode set is the fragment percent-encode set and
|
||||
* U+0023 (#), U+003F (?), U+007B ({), and U+007D (}).
|
||||
*
|
||||
* @const
|
||||
* @type {EncodeSet}
|
||||
* @see {@link https://url.spec.whatwg.org/#path-percent-encode-set}
|
||||
*/
|
||||
PATH_ENCODE_SET = EncodeSet.extend(FRAGMENT_ENCODE_SET, PATH_EXTEND_CHARS).seal(),
|
||||
|
||||
/**
|
||||
* The userinfo percent-encode set is the path percent-encode set and
|
||||
* U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), U+005B ([),
|
||||
* U+005C (\), U+005D (]), U+005E (^), and U+007C (|).
|
||||
*
|
||||
* @const
|
||||
* @type {EncodeSet}
|
||||
* @see {@link https://url.spec.whatwg.org/#userinfo-percent-encode-set}
|
||||
*/
|
||||
USERINFO_ENCODE_SET = EncodeSet.extend(PATH_ENCODE_SET, USERINFO_EXTEND_CHARS).seal(),
|
||||
|
||||
/**
|
||||
* The query percent-encode set is the C0 control percent-encode set and
|
||||
* U+0020 SPACE, U+0022 ("), U+0023 (#), U+0027 ('), U+003C (<), and U+003E (>).
|
||||
*
|
||||
* @const
|
||||
* @type {EncodeSet}
|
||||
* @see {@link https://url.spec.whatwg.org/#query-state}
|
||||
*/
|
||||
QUERY_ENCODE_SET = new EncodeSet(QUERY_ENCODE_CHARS).seal();
|
||||
|
||||
module.exports = {
|
||||
// EncodeSet class
|
||||
EncodeSet,
|
||||
|
||||
// Constants
|
||||
PATH_ENCODE_SET,
|
||||
QUERY_ENCODE_SET,
|
||||
FRAGMENT_ENCODE_SET,
|
||||
USERINFO_ENCODE_SET,
|
||||
C0_CONTROL_ENCODE_SET
|
||||
};
|
366
node_modules/postman-url-encoder/encoder/index.js
generated
vendored
Normal file
366
node_modules/postman-url-encoder/encoder/index.js
generated
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
* This module helps to encode different URL components and expose utility
|
||||
* methods to percent-encode a given string using an {@link EncodeSet}.
|
||||
*
|
||||
* @example
|
||||
* const encoder = require('postman-url-encoder/encoder')
|
||||
*
|
||||
* // returns 'xn--48jwgn17gdel797d.com'
|
||||
* encoder.encodeHost('郵便屋さん.com')
|
||||
*
|
||||
* @example <caption>Using EncodeSet</caption>
|
||||
* var EncodeSet = require('postman-url-encoder/encoder').EncodeSet
|
||||
*
|
||||
* var fragmentEncodeSet = new EncodeSet([' ', '"', '<', '>', '`'])
|
||||
*
|
||||
* // returns false
|
||||
* fragmentEncodeSet.has('['.charCodeAt(0))
|
||||
*
|
||||
* // returns true
|
||||
* fragmentEncodeSet.has('<'.charCodeAt(0))
|
||||
*
|
||||
* @module postman-url-encoder/encoder
|
||||
* @see {@link https://url.spec.whatwg.org/#url-representation}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
* This module determines which of the reserved characters in the different
|
||||
* URL components should be percent-encoded and which can be safely used.
|
||||
*
|
||||
* The generic URI syntax consists of a hierarchical sequence of components
|
||||
* referred to as the scheme, authority, path, query, and fragment.
|
||||
*
|
||||
* URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
||||
*
|
||||
* hier-part = "//" authority path-abempty
|
||||
* / path-absolute
|
||||
* / path-rootless
|
||||
* / path-empty
|
||||
*
|
||||
* authority = [ userinfo "@" ] host [ ":" port ]
|
||||
*
|
||||
* @see {@link https://tools.ietf.org/html/rfc3986#section-2}
|
||||
* @see {@link https://tools.ietf.org/html/rfc3986#section-3}
|
||||
*/
|
||||
|
||||
const encodeSet = require('./encode-set'),
|
||||
|
||||
_percentEncode = require('./percent-encode').encode,
|
||||
_percentEncodeCharCode = require('./percent-encode').encodeCharCode,
|
||||
|
||||
EncodeSet = encodeSet.EncodeSet,
|
||||
|
||||
PATH_ENCODE_SET = encodeSet.PATH_ENCODE_SET,
|
||||
QUERY_ENCODE_SET = encodeSet.QUERY_ENCODE_SET,
|
||||
USERINFO_ENCODE_SET = encodeSet.USERINFO_ENCODE_SET,
|
||||
FRAGMENT_ENCODE_SET = encodeSet.FRAGMENT_ENCODE_SET,
|
||||
C0_CONTROL_ENCODE_SET = encodeSet.C0_CONTROL_ENCODE_SET,
|
||||
|
||||
PARAM_VALUE_ENCODE_SET = EncodeSet.extend(QUERY_ENCODE_SET, ['&']).seal(),
|
||||
PARAM_KEY_ENCODE_SET = EncodeSet.extend(QUERY_ENCODE_SET, ['&', '=']).seal(),
|
||||
|
||||
E = '',
|
||||
EQUALS = '=',
|
||||
AMPERSAND = '&',
|
||||
STRING = 'string',
|
||||
OBJECT = 'object',
|
||||
|
||||
PATH_SEPARATOR = '/',
|
||||
DOMAIN_SEPARATOR = '.',
|
||||
|
||||
/**
|
||||
* Returns the Punycode ASCII serialization of the domain.
|
||||
*
|
||||
* @private
|
||||
* @function
|
||||
* @param {String} domain domain name
|
||||
* @returns {String} punycode encoded domain name
|
||||
*/
|
||||
domainToASCII = (function () {
|
||||
// @note `url.domainToASCII` returns empty string for invalid domain.
|
||||
const domainToASCII = require('url').domainToASCII;
|
||||
|
||||
// use faster native `url` method in Node.js
|
||||
/* istanbul ignore next */
|
||||
if (typeof domainToASCII === 'function') {
|
||||
return domainToASCII;
|
||||
}
|
||||
|
||||
// else, lazy load `punycode` dependency in browser
|
||||
/* istanbul ignore next */
|
||||
return require('punycode').toASCII;
|
||||
}());
|
||||
|
||||
/**
|
||||
* Returns the Punycode ASCII serialization of the domain.
|
||||
*
|
||||
* @note Returns input hostname on invalid domain.
|
||||
*
|
||||
* @example
|
||||
* // returns 'xn--fiq228c.com'
|
||||
* encodeHost('中文.com')
|
||||
*
|
||||
* // returns 'xn--48jwgn17gdel797d.com'
|
||||
* encodeHost(['郵便屋さん', 'com'])
|
||||
*
|
||||
* // returns '127.0.0.1'
|
||||
* encodeHost('127.1')
|
||||
*
|
||||
* // returns 'xn--iñvalid.com'
|
||||
* encodeHost('xn--iñvalid.com')
|
||||
*
|
||||
* @param {String|String[]} hostName host or domain name
|
||||
* @returns {String} Punycode-encoded hostname
|
||||
*/
|
||||
function encodeHost (hostName) {
|
||||
if (Array.isArray(hostName)) {
|
||||
hostName = hostName.join(DOMAIN_SEPARATOR);
|
||||
}
|
||||
|
||||
if (typeof hostName !== STRING) {
|
||||
return E;
|
||||
}
|
||||
|
||||
// return input host name if `domainToASCII` returned an empty string
|
||||
return domainToASCII(hostName) || hostName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes URL path or individual path segments.
|
||||
*
|
||||
* @example
|
||||
* // returns 'foo/bar&baz'
|
||||
* encodePath('foo/bar&baz')
|
||||
*
|
||||
* // returns 'foo/bar/%20%22%3C%3E%60%23%3F%7B%7D'
|
||||
* encodePath(['foo', 'bar', ' "<>\`#?{}'])
|
||||
*
|
||||
* @param {String|String[]} path Path or path segments
|
||||
* @returns {String} Percent-encoded path
|
||||
*/
|
||||
function encodePath (path) {
|
||||
if (Array.isArray(path) && path.length) {
|
||||
path = path.join(PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
if (typeof path !== STRING) {
|
||||
return E;
|
||||
}
|
||||
|
||||
return _percentEncode(path, PATH_ENCODE_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes URL userinfo (username / password) fields.
|
||||
*
|
||||
* @example
|
||||
* // returns 'info~%20%22%3C%3E%60%23%3F%7B%7D%2F%3A%3B%3D%40%5B%5C%5D%5E%7C'
|
||||
* encodeAuth('info~ "<>`#?{}/:;=@[\\]^|')
|
||||
*
|
||||
* @param {String} param Parameter to encode
|
||||
* @returns {String} Percent-encoded parameter
|
||||
*/
|
||||
function encodeUserInfo (param) {
|
||||
if (typeof param !== STRING) {
|
||||
return E;
|
||||
}
|
||||
|
||||
return _percentEncode(param, USERINFO_ENCODE_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes URL fragment identifier or hash.
|
||||
*
|
||||
* @example
|
||||
* // returns 'fragment#%20%22%3C%3E%60'
|
||||
* encodeHash('fragment# "<>`')
|
||||
*
|
||||
* @param {String} fragment Hash or fragment identifier to encode
|
||||
* @returns {String} Percent-encoded fragment
|
||||
*/
|
||||
function encodeFragment (fragment) {
|
||||
if (typeof fragment !== STRING) {
|
||||
return E;
|
||||
}
|
||||
|
||||
return _percentEncode(fragment, FRAGMENT_ENCODE_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes single query parameter and returns as a string.
|
||||
*
|
||||
* @example
|
||||
* // returns 'param%20%22%23%27%3C%3E'
|
||||
* encodeQueryParam('param "#\'<>')
|
||||
*
|
||||
* // returns 'foo=bar'
|
||||
* encodeQueryParam({ key: 'foo', value: 'bar' })
|
||||
*
|
||||
* @param {Object|String} param Query param to encode
|
||||
* @returns {String} Percent-encoded query param
|
||||
*/
|
||||
function encodeQueryParam (param) {
|
||||
if (!param) {
|
||||
return E;
|
||||
}
|
||||
|
||||
if (typeof param === STRING) {
|
||||
return _percentEncode(param, QUERY_ENCODE_SET);
|
||||
}
|
||||
|
||||
let key = param.key,
|
||||
value = param.value,
|
||||
result;
|
||||
|
||||
if (typeof key === STRING) {
|
||||
result = _percentEncode(key, PARAM_KEY_ENCODE_SET);
|
||||
}
|
||||
else {
|
||||
result = E;
|
||||
}
|
||||
|
||||
if (typeof value === STRING) {
|
||||
result += EQUALS + _percentEncode(value, PARAM_VALUE_ENCODE_SET);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes list of query parameters and returns encoded query string.
|
||||
*
|
||||
* @example
|
||||
* // returns 'foo=bar&=foo%26bar'
|
||||
* encodeQueryParams([{ key: 'foo', value: 'bar' }, { value: 'foo&bar' }])
|
||||
*
|
||||
* // returns 'q1=foo&q2=bar&q2=baz'
|
||||
* encodeQueryParams({ q1: 'foo', q2: ['bar', 'baz'] })
|
||||
*
|
||||
* @param {Object|Object[]} params Query params to encode
|
||||
* @returns {String} Percent-encoded query string
|
||||
*/
|
||||
function encodeQueryParams (params) {
|
||||
let i,
|
||||
j,
|
||||
ii,
|
||||
jj,
|
||||
paramKey,
|
||||
paramKeys,
|
||||
paramValue,
|
||||
result = E,
|
||||
notFirstParam = false;
|
||||
|
||||
if (!(params && typeof params === OBJECT)) {
|
||||
return E;
|
||||
}
|
||||
|
||||
// handle array of query params
|
||||
if (Array.isArray(params)) {
|
||||
for (i = 0, ii = params.length; i < ii; i++) {
|
||||
// @todo Add helper in PropertyList to filter disabled QueryParam
|
||||
if (!params[i] || params[i].disabled === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't add '&' for the very first enabled param
|
||||
notFirstParam && (result += AMPERSAND);
|
||||
notFirstParam = true;
|
||||
|
||||
result += encodeQueryParam(params[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// handle object with query params
|
||||
paramKeys = Object.keys(params);
|
||||
|
||||
for (i = 0, ii = paramKeys.length; i < ii; i++) {
|
||||
paramKey = paramKeys[i];
|
||||
paramValue = params[paramKey];
|
||||
|
||||
// { key: ['value1', 'value2', 'value3'] }
|
||||
if (Array.isArray(paramValue)) {
|
||||
for (j = 0, jj = paramValue.length; j < jj; j++) {
|
||||
notFirstParam && (result += AMPERSAND);
|
||||
notFirstParam = true;
|
||||
|
||||
result += encodeQueryParam({ key: paramKey, value: paramValue[j] });
|
||||
}
|
||||
}
|
||||
// { key: 'value' }
|
||||
else {
|
||||
notFirstParam && (result += AMPERSAND);
|
||||
notFirstParam = true;
|
||||
|
||||
result += encodeQueryParam({ key: paramKey, value: paramValue });
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Percent-encode the given string with the given {@link EncodeSet}.
|
||||
*
|
||||
* @example <caption>Defaults to C0_CONTROL_ENCODE_SET</caption>
|
||||
* // returns 'foo %00 bar'
|
||||
* percentEncode('foo \u0000 bar')
|
||||
*
|
||||
* @example <caption>Encode literal @ using custom EncodeSet</caption>
|
||||
* // returns 'foo%40bar'
|
||||
* percentEncode('foo@bar', new EncodeSet(['@']))
|
||||
*
|
||||
* @param {String} value String to percent-encode
|
||||
* @param {EncodeSet} [encodeSet=C0_CONTROL_ENCODE_SET] EncodeSet to use for encoding
|
||||
* @returns {String} Percent-encoded string
|
||||
*/
|
||||
function percentEncode (value, encodeSet) {
|
||||
if (!(value && typeof value === STRING)) {
|
||||
return E;
|
||||
}
|
||||
|
||||
// defaults to C0_CONTROL_ENCODE_SET
|
||||
if (!EncodeSet.isEncodeSet(encodeSet)) {
|
||||
encodeSet = C0_CONTROL_ENCODE_SET;
|
||||
}
|
||||
|
||||
return _percentEncode(value, encodeSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Percent encode a character with given code.
|
||||
*
|
||||
* @example
|
||||
* // returns '%20'
|
||||
* percentEncodeCharCode(32)
|
||||
*
|
||||
* @param {Number} code Character code
|
||||
* @returns {String} Percent-encoded character
|
||||
*/
|
||||
function percentEncodeCharCode (code) {
|
||||
// ensure [0x00, 0xFF] range
|
||||
if (!(Number.isInteger(code) && code >= 0 && code <= 0xFF)) {
|
||||
return E;
|
||||
}
|
||||
|
||||
return _percentEncodeCharCode(code);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
// URL components
|
||||
encodeHost,
|
||||
encodePath,
|
||||
encodeUserInfo,
|
||||
encodeFragment,
|
||||
encodeQueryParam,
|
||||
encodeQueryParams,
|
||||
|
||||
/** @type EncodeSet */
|
||||
EncodeSet,
|
||||
|
||||
// Utilities
|
||||
percentEncode,
|
||||
percentEncodeCharCode
|
||||
};
|
118
node_modules/postman-url-encoder/encoder/percent-encode.js
generated
vendored
Normal file
118
node_modules/postman-url-encoder/encoder/percent-encode.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* This modules provides simple percent (URI) encoding.
|
||||
*
|
||||
* @note Safety check for input types is not done intentionally as these
|
||||
* functions are invoked in the hot code path.
|
||||
*
|
||||
* @private
|
||||
* @module postman-url-encoder/encoder/percent-encode
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
* A percent-encoding mechanism is used to represent a data octet in a component
|
||||
* when that octet's corresponding character is outside the allowed set or is
|
||||
* being used as a delimiter of, or within, the component.
|
||||
* A percent-encoded octet is encoded as a character triplet, consisting of the
|
||||
* percent character "%" followed by the two hexadecimal digits representing
|
||||
* that octet's numeric value.
|
||||
*
|
||||
* For example, "%20" is the percent-encoding for the binary octet "00100000"
|
||||
* (ABNF: %x20), which in US-ASCII corresponds to the space character (SP).
|
||||
*
|
||||
* @see {@link https://en.wikipedia.org/wiki/Percent-encoding}
|
||||
* @see {@link https://tools.ietf.org/html/rfc3986#section-2.1}
|
||||
*/
|
||||
|
||||
const E = '',
|
||||
ZERO = '0',
|
||||
PERCENT = '%';
|
||||
|
||||
/**
|
||||
* Checks if character with given code is valid hexadecimal digit or not.
|
||||
*
|
||||
* @private
|
||||
* @param {Number} byte Byte
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function isPreEncodedCharacter (byte) {
|
||||
return (byte >= 0x30 && byte <= 0x39) || // 0-9
|
||||
(byte >= 0x41 && byte <= 0x46) || // A-F
|
||||
(byte >= 0x61 && byte <= 0x66); // a-f
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if character at given index in the buffer is already percent encoded or not.
|
||||
*
|
||||
* @private
|
||||
* @param {Buffer} buffer Buffer to check the character from
|
||||
* @param {Number} i Index of the character to check
|
||||
* @returns {Boolean} true if the character is encoded, false otherwise
|
||||
*/
|
||||
function isPreEncoded (buffer, i) {
|
||||
// if it is % check next two bytes for percent encode characters
|
||||
// looking for pattern %00 - %FF
|
||||
return buffer[i] === 0x25 && // %
|
||||
isPreEncodedCharacter(buffer[i + 1]) &&
|
||||
isPreEncodedCharacter(buffer[i + 2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Percent encode a character with given code.
|
||||
*
|
||||
* @example
|
||||
* // returns '%20'
|
||||
* encodeCharCode(32)
|
||||
*
|
||||
* @param {Number} code Character code
|
||||
* @returns {String} Percent-encoded character
|
||||
*/
|
||||
function encodeCharCode (code) {
|
||||
let hex = code.toString(16).toUpperCase();
|
||||
|
||||
(hex.length === 1) && (hex = ZERO + hex);
|
||||
|
||||
return PERCENT + hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Percent-encode the given string with the given {@link EncodeSet}.
|
||||
*
|
||||
* @example
|
||||
* // returns 'foo%40bar'
|
||||
* encode('foo@bar', new EncodeSet(['@']))
|
||||
*
|
||||
* @param {String} value String to percent-encode
|
||||
* @param {EncodeSet} encodeSet EncodeSet to use for encoding
|
||||
* @returns {String} Percent-encoded string
|
||||
*/
|
||||
function encode (value, encodeSet) {
|
||||
let i,
|
||||
ii,
|
||||
charCode,
|
||||
encoded = E,
|
||||
buffer = Buffer.from(value);
|
||||
|
||||
for (i = 0, ii = buffer.length; i < ii; ++i) {
|
||||
// avoid double encoding
|
||||
if (i < ii - 2 && isPreEncoded(buffer, i)) {
|
||||
encoded += PERCENT + String.fromCharCode(buffer[++i], buffer[++i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
charCode = buffer[i];
|
||||
|
||||
encoded += encodeSet.has(charCode) ?
|
||||
// encode if char code present in encodeSet
|
||||
encodeCharCode(charCode) :
|
||||
// or, append string from char code
|
||||
String.fromCharCode(charCode);
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
encode,
|
||||
encodeCharCode
|
||||
};
|
Reference in New Issue
Block a user