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:
293
node_modules/postman-url-encoder/parser/index.js
generated
vendored
Normal file
293
node_modules/postman-url-encoder/parser/index.js
generated
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* This module helps to break URL strings up into components
|
||||
* (protocol, auth, host, port, path, query, and hash) keeping the variables
|
||||
* intact.
|
||||
*
|
||||
* @example
|
||||
* const parser = require('postman-url-encoder/parser')
|
||||
*
|
||||
* // returns
|
||||
* // {
|
||||
* // raw: 'protocol://{{user}}:{{p@ssw?rd}}@{{host.name}}.com:{{#port}}/p/a/t/h?q=query#hash',
|
||||
* // protocol: 'protocol',
|
||||
* // auth: [ '{{user}}', '{{p@ssw?rd}}' ],
|
||||
* // host: [ '{{host.name}}', 'com' ],
|
||||
* // port: '{{#port}}',
|
||||
* // path: [ 'p', 'a', 't', 'h' ],
|
||||
* // query: [ 'q=query' ],
|
||||
* // hash: 'hash'
|
||||
* // }
|
||||
* parser.parse('protocol://{{user}}:{{p@ssw?rd}}@{{host.name}}.com:{{#port}}/p/a/t/h?q=query#hash')
|
||||
*
|
||||
* @module postman-url-encoder/parser
|
||||
*/
|
||||
|
||||
const ReplacementTracker = require('./replacement-tracker'),
|
||||
|
||||
REGEX_ALL_BACKSLASHES = /\\/g,
|
||||
REGEX_LEADING_SLASHES = /^\/+/,
|
||||
REGEX_ALL_VARIABLES = /{{[^{}]*[.:/?#@&\]][^{}]*}}/g,
|
||||
|
||||
HASH_SEPARATOR = '#',
|
||||
PATH_SEPARATOR = '/',
|
||||
PORT_SEPARATOR = ':',
|
||||
AUTH_SEPARATOR = '@',
|
||||
QUERY_SEPARATOR = '?',
|
||||
DOMAIN_SEPARATOR = '.',
|
||||
PROTOCOL_SEPARATOR = '://',
|
||||
AUTH_SEGMENTS_SEPARATOR = ':',
|
||||
QUERY_SEGMENTS_SEPARATOR = '&',
|
||||
|
||||
E = '',
|
||||
STRING = 'string',
|
||||
FILE_PROTOCOL = 'file',
|
||||
SAFE_REPLACE_CHAR = '_',
|
||||
CLOSING_SQUARE_BRACKET = ']',
|
||||
URL_PROPERTIES_ORDER = ['protocol', 'auth', 'host', 'port', 'path', 'query', 'hash'];
|
||||
|
||||
/**
|
||||
* Normalize the given string by replacing the variables which includes
|
||||
* reserved characters in its name.
|
||||
* The replaced characters are added to the given replacement tracker instance.
|
||||
*
|
||||
* @private
|
||||
* @param {String} str String to normalize
|
||||
* @param {ReplacementTracker} replacements ReplacementTracker instance
|
||||
* @returns {String} Normalized string
|
||||
*/
|
||||
function normalizeVariables (str, replacements) {
|
||||
let normalizedString = E,
|
||||
pointer = 0, // pointer till witch the string is normalized
|
||||
variable,
|
||||
match,
|
||||
index;
|
||||
|
||||
// find all the instances of {{<variable>}} which includes reserved chars
|
||||
// "Hello {{user#name}}!!!"
|
||||
// ↑ (pointer = 0)
|
||||
while ((match = REGEX_ALL_VARIABLES.exec(str)) !== null) {
|
||||
// {{user#name}}
|
||||
variable = match[0];
|
||||
|
||||
// starting index of the {{variable}} in the string
|
||||
// "Hello {{user#name}}!!!"
|
||||
// ↑ (index = 6)
|
||||
index = match.index;
|
||||
|
||||
// [pointer, index) string is normalized + the safe replacement character
|
||||
// "Hello " + "_"
|
||||
normalizedString += str.slice(pointer, index) + SAFE_REPLACE_CHAR;
|
||||
|
||||
// track the replacement done for the {{variable}}
|
||||
replacements.add(variable, index);
|
||||
|
||||
// update the pointer
|
||||
// "Hello {{user#name}}!!!"
|
||||
// ↑ (pointer = 19)
|
||||
pointer = index + variable.length;
|
||||
}
|
||||
|
||||
// avoid slicing the string in case of no matches
|
||||
if (pointer === 0) {
|
||||
return str;
|
||||
}
|
||||
|
||||
// whatever left in the string is normalized as well
|
||||
/* istanbul ignore else */
|
||||
if (pointer < str.length) {
|
||||
// "Hello _" + "!!!"
|
||||
normalizedString += str.slice(pointer);
|
||||
}
|
||||
|
||||
return normalizedString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update replaced characters in the URL object with its original value.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} url URL tracker object
|
||||
* @param {ReplacementTracker} replacements ReplacementTracker instance
|
||||
*/
|
||||
function applyReplacements (url, replacements) {
|
||||
let i,
|
||||
ii,
|
||||
prop;
|
||||
|
||||
// traverse each URL property in the given order
|
||||
for (i = 0, ii = URL_PROPERTIES_ORDER.length; i < ii; ++i) {
|
||||
prop = url[URL_PROPERTIES_ORDER[i]];
|
||||
|
||||
// bail out if the given property is not set (undefined or '')
|
||||
if (!(prop && prop.value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
prop.value = replacements.apply(prop.value, prop.beginIndex, prop.endIndex);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the input string by decomposing the URL into constituent parts,
|
||||
* such as path, host, port, etc.
|
||||
*
|
||||
* @param {String} urlString The URL string to parse
|
||||
* @returns {Object} Parsed URL object
|
||||
*/
|
||||
function parse (urlString) {
|
||||
let url = {
|
||||
protocol: { value: undefined, beginIndex: 0, endIndex: 0 },
|
||||
auth: { value: undefined, beginIndex: 0, endIndex: 0 },
|
||||
host: { value: undefined, beginIndex: 0, endIndex: 0 },
|
||||
port: { value: undefined, beginIndex: 0, endIndex: 0 },
|
||||
path: { value: undefined, beginIndex: 0, endIndex: 0 },
|
||||
query: { value: undefined, beginIndex: 0, endIndex: 0 },
|
||||
hash: { value: undefined, beginIndex: 0, endIndex: 0 }
|
||||
},
|
||||
parsedUrl = {
|
||||
raw: urlString,
|
||||
protocol: undefined,
|
||||
auth: undefined,
|
||||
host: undefined,
|
||||
port: undefined,
|
||||
path: undefined,
|
||||
query: undefined,
|
||||
hash: undefined
|
||||
},
|
||||
replacements = new ReplacementTracker(),
|
||||
pointer = 0,
|
||||
_length,
|
||||
length,
|
||||
index,
|
||||
port;
|
||||
|
||||
// bail out if input string is empty
|
||||
if (!(urlString && typeof urlString === STRING)) {
|
||||
return parsedUrl;
|
||||
}
|
||||
|
||||
// trim leading whitespace characters
|
||||
parsedUrl.raw = urlString = urlString.trimLeft();
|
||||
|
||||
// normalize the given string
|
||||
urlString = normalizeVariables(urlString, replacements);
|
||||
length = urlString.length;
|
||||
|
||||
// 1. url.hash
|
||||
if ((index = urlString.indexOf(HASH_SEPARATOR)) !== -1) {
|
||||
// extract from the back
|
||||
url.hash.value = urlString.slice(index + 1);
|
||||
url.hash.beginIndex = pointer + index + 1;
|
||||
url.hash.endIndex = pointer + length;
|
||||
|
||||
urlString = urlString.slice(0, (length = index));
|
||||
}
|
||||
|
||||
// 2. url.query
|
||||
if ((index = urlString.indexOf(QUERY_SEPARATOR)) !== -1) {
|
||||
// extract from the back
|
||||
url.query.value = urlString.slice(index + 1).split(QUERY_SEGMENTS_SEPARATOR);
|
||||
url.query.beginIndex = pointer + index + 1;
|
||||
url.query.endIndex = pointer + length;
|
||||
|
||||
urlString = urlString.slice(0, (length = index));
|
||||
}
|
||||
|
||||
// 3. url.protocol
|
||||
urlString = urlString.replace(REGEX_ALL_BACKSLASHES, PATH_SEPARATOR); // sanitize slashes
|
||||
|
||||
// @todo support `protocol:host/path` and `protocol:/host/path`
|
||||
if ((index = urlString.indexOf(PROTOCOL_SEPARATOR)) !== -1) {
|
||||
// extract from the front
|
||||
url.protocol.value = urlString.slice(0, index);
|
||||
url.protocol.beginIndex = pointer;
|
||||
url.protocol.endIndex = pointer + index;
|
||||
|
||||
urlString = urlString.slice(index + 3);
|
||||
length -= index + 3;
|
||||
pointer += index + 3;
|
||||
|
||||
// special handling for extra slashes in protocol e.g, http:///example.com
|
||||
_length = length; // length with leading slashes
|
||||
|
||||
urlString = urlString.replace(REGEX_LEADING_SLASHES,
|
||||
(url.protocol.value.toLowerCase() === FILE_PROTOCOL) ?
|
||||
// file:////path -> file:///path
|
||||
PATH_SEPARATOR :
|
||||
// protocol:////host/path -> protocol://host/path
|
||||
E);
|
||||
|
||||
length = urlString.length; // length without slashes
|
||||
pointer += _length - length; // update pointer
|
||||
}
|
||||
|
||||
// 4. url.path
|
||||
if ((index = urlString.indexOf(PATH_SEPARATOR)) !== -1) {
|
||||
// extract from the back
|
||||
url.path.value = urlString.slice(index + 1).split(PATH_SEPARATOR);
|
||||
url.path.beginIndex = pointer + index + 1;
|
||||
url.path.endIndex = pointer + length;
|
||||
|
||||
urlString = urlString.slice(0, (length = index));
|
||||
}
|
||||
|
||||
// 5. url.auth
|
||||
if ((index = urlString.lastIndexOf(AUTH_SEPARATOR)) !== -1) {
|
||||
// extract from the front
|
||||
url.auth.value = urlString.slice(0, index);
|
||||
url.auth.beginIndex = pointer;
|
||||
url.auth.endIndex = pointer + index;
|
||||
|
||||
urlString = urlString.slice(index + 1);
|
||||
length -= index + 1;
|
||||
pointer += index + 1;
|
||||
|
||||
// separate username:password
|
||||
if ((index = url.auth.value.indexOf(AUTH_SEGMENTS_SEPARATOR)) !== -1) {
|
||||
url.auth.value = [url.auth.value.slice(0, index), url.auth.value.slice(index + 1)];
|
||||
}
|
||||
else {
|
||||
url.auth.value = [url.auth.value];
|
||||
}
|
||||
}
|
||||
|
||||
// 6. url.port
|
||||
if ((index = urlString.lastIndexOf(PORT_SEPARATOR)) !== -1 &&
|
||||
// eslint-disable-next-line lodash/prefer-includes
|
||||
(port = urlString.slice(index + 1)).indexOf(CLOSING_SQUARE_BRACKET) === -1
|
||||
) {
|
||||
// extract from the back
|
||||
url.port.value = port;
|
||||
url.port.beginIndex = pointer + index + 1;
|
||||
url.port.endIndex = pointer + length;
|
||||
|
||||
urlString = urlString.slice(0, (length = index));
|
||||
}
|
||||
|
||||
// 7. url.host
|
||||
if (urlString) {
|
||||
url.host.value = urlString.split(DOMAIN_SEPARATOR);
|
||||
url.host.beginIndex = pointer;
|
||||
url.host.endIndex = pointer + length;
|
||||
}
|
||||
|
||||
// apply replacements back, if any
|
||||
replacements.count() && applyReplacements(url, replacements);
|
||||
|
||||
// finally, prepare parsed url
|
||||
parsedUrl.protocol = url.protocol.value;
|
||||
parsedUrl.auth = url.auth.value;
|
||||
parsedUrl.host = url.host.value;
|
||||
parsedUrl.port = url.port.value;
|
||||
parsedUrl.path = url.path.value;
|
||||
parsedUrl.query = url.query.value;
|
||||
parsedUrl.hash = url.hash.value;
|
||||
|
||||
return parsedUrl;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parse
|
||||
};
|
151
node_modules/postman-url-encoder/parser/replacement-tracker.js
generated
vendored
Normal file
151
node_modules/postman-url-encoder/parser/replacement-tracker.js
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
/**
|
||||
* Tracks replacements done on a string and expose utility to patch replacements.
|
||||
*
|
||||
* @note due to performance reasons, it doesn't store the original string or
|
||||
* perform ops on the string.
|
||||
*
|
||||
* @private
|
||||
* @constructor
|
||||
*/
|
||||
class ReplacementTracker {
|
||||
constructor () {
|
||||
this.replacements = [];
|
||||
this._offset = 0;
|
||||
this._length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new replacement to track.
|
||||
*
|
||||
* @param {String} value -
|
||||
* @param {Number} index -
|
||||
*/
|
||||
add (value, index) {
|
||||
this.replacements.push({
|
||||
value: value,
|
||||
index: index - this._offset
|
||||
});
|
||||
|
||||
this._offset += value.length - 1; // - 1 replaced character
|
||||
this._length++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of replacements.
|
||||
*
|
||||
* @returns {Number}
|
||||
*/
|
||||
count () {
|
||||
return this._length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the lower index of replacement position for a given value using inexact
|
||||
* binary search.
|
||||
*
|
||||
* @private
|
||||
* @param {Number} index -
|
||||
* @returns {Number}
|
||||
*/
|
||||
_findLowerIndex (index) {
|
||||
let length = this.count(),
|
||||
start = 0,
|
||||
end = length - 1,
|
||||
mid;
|
||||
|
||||
while (start <= end) {
|
||||
mid = (start + end) >> 1; // divide by 2
|
||||
|
||||
if (this.replacements[mid].index >= index) {
|
||||
end = mid - 1;
|
||||
}
|
||||
else {
|
||||
start = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return start >= length ? -1 : start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patches a given string by apply all the applicable replacements done in the
|
||||
* given range.
|
||||
*
|
||||
* @private
|
||||
* @param {String} input -
|
||||
* @param {Number} beginIndex -
|
||||
* @param {Number} endIndex -
|
||||
* @returns {String}
|
||||
*/
|
||||
_applyInString (input, beginIndex, endIndex) {
|
||||
let index,
|
||||
replacement,
|
||||
replacementIndex,
|
||||
replacementValue,
|
||||
offset = 0,
|
||||
length = this.count();
|
||||
|
||||
// bail out if no replacements are done in the given range OR empty string
|
||||
if (!input || (index = this._findLowerIndex(beginIndex)) === -1) {
|
||||
return input;
|
||||
}
|
||||
|
||||
do {
|
||||
replacement = this.replacements[index];
|
||||
replacementIndex = replacement.index;
|
||||
replacementValue = replacement.value;
|
||||
|
||||
// bail out if all the replacements are done in the given range
|
||||
if (replacementIndex >= endIndex) {
|
||||
break;
|
||||
}
|
||||
|
||||
replacementIndex = offset + replacementIndex - beginIndex;
|
||||
input = input.slice(0, replacementIndex) + replacementValue + input.slice(replacementIndex + 1);
|
||||
offset += replacementValue.length - 1;
|
||||
} while (++index < length);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patches a given string or array of strings by apply all the applicable
|
||||
* replacements done in the given range.
|
||||
*
|
||||
* @param {String|String[]} input -
|
||||
* @param {Number} beginIndex -
|
||||
* @param {Number} endIndex -
|
||||
* @returns {String|String[]}
|
||||
*/
|
||||
apply (input, beginIndex, endIndex) {
|
||||
let i,
|
||||
ii,
|
||||
length,
|
||||
_endIndex,
|
||||
_beginIndex,
|
||||
value = input;
|
||||
|
||||
// apply replacements in string
|
||||
if (typeof input === 'string') {
|
||||
return this._applyInString(input, beginIndex, endIndex);
|
||||
}
|
||||
|
||||
// apply replacements in the splitted string (Array)
|
||||
_beginIndex = beginIndex;
|
||||
|
||||
// traverse all the segments until all the replacements are patched
|
||||
for (i = 0, ii = input.length; i < ii; ++i) {
|
||||
value = input[i];
|
||||
_endIndex = _beginIndex + (length = value.length);
|
||||
|
||||
// apply replacements applicable for individual segment
|
||||
input[i] = this._applyInString(value, _beginIndex, _endIndex);
|
||||
_beginIndex += length + 1; // + 1 separator
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ReplacementTracker;
|
Reference in New Issue
Block a user