json-placeholder-replacer
Version:
Javascript/Typescript library/cli to replace placeholders in an javascript object
129 lines (128 loc) • 4.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonPlaceholderReplacer = void 0;
const defaultDelimiterTags = [
{
begin: "{{",
end: "}}",
},
{
begin: "<<",
end: ">>",
},
];
const defaultSeparator = ":";
class JsonPlaceholderReplacer {
constructor(options) {
this.variablesMap = [];
this.configuration = this.initializeOptions(options);
const escapeRegExp = (text) => text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
this.configuration.delimiterTags = this.configuration.delimiterTags.map((tag) => (Object.assign(Object.assign({}, tag), { escapedBeginning: escapeRegExp(tag.begin), escapedEnding: escapeRegExp(tag.end) })));
const delimiterTagsRegexes = this.configuration.delimiterTags
.map((delimiterTag) => `^${delimiterTag.begin}[^${delimiterTag.end}]+${delimiterTag.end}$`)
.join("|");
this.delimiterTagsRegex = new RegExp(delimiterTagsRegexes);
}
addVariableMap(variableMap) {
if (typeof variableMap === "string") {
this.variablesMap.push(JSON.parse(variableMap));
}
else {
this.variablesMap.push(variableMap);
}
return this;
}
replace(json) {
return this.replaceChildren(json);
}
initializeOptions(options) {
let delimiterTags = defaultDelimiterTags;
let defaultValueSeparator = defaultSeparator;
if (options !== undefined) {
if (options.delimiterTags !== undefined &&
options.delimiterTags.length > 0) {
delimiterTags = options.delimiterTags;
}
if (options.defaultValueSeparator !== undefined) {
defaultValueSeparator = options.defaultValueSeparator;
}
}
return { defaultValueSeparator, delimiterTags };
}
replaceChildren(node) {
for (const key in node) {
const attribute = node[key];
if (typeof attribute === "object") {
node[key] = this.replaceChildren(attribute);
}
else if (attribute !== undefined) {
node[key] = this.replaceValue(attribute.toString());
}
}
return node;
}
replaceValue(node) {
const placeHolderIsInsideStringContext = !this.delimiterTagsRegex.test(node);
const output = this.configuration.delimiterTags.reduce((acc, delimiterTag) => {
const regex = new RegExp(`(${delimiterTag.escapedBeginning}[^${delimiterTag.escapedEnding}]+${delimiterTag.escapedEnding})`, "g");
return acc.replace(regex, this.replacer(placeHolderIsInsideStringContext)(delimiterTag));
}, node);
try {
return JSON.parse(output);
}
catch (exc) {
return output;
}
}
replacer(placeHolderIsInsideStringContext) {
return (delimiterTag) => (placeHolder) => {
const { tag, defaultValue } = this.parseTag(placeHolder, delimiterTag);
const mapCheckResult = this.checkInEveryMap(tag);
if (mapCheckResult === undefined) {
if (defaultValue !== undefined) {
return defaultValue;
}
return placeHolder;
}
if (!placeHolderIsInsideStringContext) {
return mapCheckResult;
}
const parsed = JSON.parse(mapCheckResult);
if (typeof parsed === "object") {
return JSON.stringify(parsed);
}
return parsed;
};
}
parseTag(placeHolder, delimiterTag) {
const path = placeHolder.substring(delimiterTag.begin.length, placeHolder.length - delimiterTag.begin.length);
let tag = path;
let defaultValue;
const defaultValueSeparatorIndex = path.indexOf(this.configuration.defaultValueSeparator);
if (defaultValueSeparatorIndex > 0) {
tag = path.substring(0, defaultValueSeparatorIndex);
defaultValue = path.substring(defaultValueSeparatorIndex +
this.configuration.defaultValueSeparator.length);
}
return { tag, defaultValue };
}
checkInEveryMap(path) {
let result;
this.variablesMap.forEach((map) => (result = this.navigateThroughMap(map, path)));
return result;
}
navigateThroughMap(map, path) {
if (map === undefined) {
return;
}
const shortCircuit = map[path];
if (shortCircuit !== undefined) {
return JSON.stringify(shortCircuit);
}
const keys = path.split(".");
const key = keys[0];
keys.shift();
return this.navigateThroughMap(map[key], keys.join("."));
}
}
exports.JsonPlaceholderReplacer = JsonPlaceholderReplacer;