UNPKG

json-placeholder-replacer

Version:

Javascript/Typescript library/cli to replace placeholders in an javascript object

129 lines (128 loc) 4.91 kB
"use strict"; 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;