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:
Simon Priet
2021-09-08 14:01:19 +02:00
parent 5fbd7c88fa
commit e69a613a37
5610 changed files with 740417 additions and 3 deletions

293
node_modules/postman-url-encoder/parser/index.js generated vendored Normal file
View 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
};

View 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;