request-mocking-protocol
Version:
A protocol for declarative mocking of HTTP requests
66 lines • 2.48 kB
JavaScript
;
/**
* A module to replace placeholders {{var}} in the string.
* Can be also used for objects within JSON.stringify replacer.
* Supports type hints, see tests.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.cloneWithPlaceholders = cloneWithPlaceholders;
exports.stringifyWithPlaceholders = stringifyWithPlaceholders;
exports.replacePlaceholders = replacePlaceholders;
/* eslint-disable visual/complexity */
function cloneWithPlaceholders(obj, variables = {}) {
return JSON.parse(stringifyWithPlaceholders(obj, variables));
}
function stringifyWithPlaceholders(obj, variables = {}) {
return JSON.stringify(obj, (_, value) => {
return typeof value === 'string'
? replacePlaceholders(value, variables, { useTypes: true })
: value;
});
}
function replacePlaceholders(value, variables, opts) {
if (Object.keys(variables).length === 0)
return value;
// Find all placeholder matches
const matches = [...value.matchAll(/\{\{\s*(\w+)(?::\s*(number|boolean))?\s*\}\}/g)];
const firstMatch = matches[0];
// No placeholders found
if (!firstMatch)
return value;
// Example: { value: '{{id}}' }
const isOnlyPlaceholder = matches.length === 1 && value.trim() === firstMatch[0];
// If the whole value is a single placeholder, apply type conversion
// Multiple placeholders -> always replace with string
return opts?.useTypes && isOnlyPlaceholder
? replaceSinglePlaceholder(firstMatch, value, variables)
: replaceMultiplePlaceholders(matches, value, variables);
}
function replaceSinglePlaceholder(match, value, variables) {
const [, key, typeHint] = match;
if (!key)
return value;
const replacement = variables[key];
if (replacement === undefined)
return value;
if (typeHint === 'number') {
const number = Number(replacement);
if (!Number.isNaN(number))
return number;
}
if (typeHint === 'boolean') {
if (replacement === '' || replacement.toLowerCase() === 'false')
return false;
return true;
}
return replacement ?? value;
}
function replaceMultiplePlaceholders(matches, value, variables) {
for (const [match, key] of matches) {
if (!key || variables[key] === undefined)
continue;
value = value.replaceAll(match, variables[key]);
}
return value;
}
//# sourceMappingURL=placeholders.js.map