Javascript/Typescript library/cli to replace placeholders in an javascript object
npm install json-placeholder-replacer




Lightweight yet really powerful typescript library/cli to replace placeholders in an javascript object/JSON.
By default, all you have to do is to use double curly brackets {{placeholderKey}} or angle brackets <<placeholderKey>>, interchangeably, to identify the placeholder.
Don't worry, if you don't like these default placeholders you can create your own.
``shell`
json-placeholder-replacer annotetad-json.json [...variableMaps]
$ json-placeholder-replacer annotated.json variable_map.json
$ jpr variable_map.json < annotated.json
$ cat annotated.json | jpr variable_map.json
$ echo '{"curly": "{{key}}", "angle": "<
`shell`
cat replaceable.json
# {
# "curly": "{{key}}",
# "angle": "<
# }
cat variable.map:
# {
# "key": 10,
# "not-mapped": 20
# }
json-placeholder-replacer replaceable.json variable.map
# {
# "curly": 10,
# "angle": 10,
# "not-mapped": 20
# }
`typescript
import { JsonPlaceholderReplacer } from "json-placeholder-replacer";
const placeHolderReplacer = new JsonPlaceholderReplacer();
placeHolderReplacer.addVariableMap({
key: 100,
otherKey: 200,
});
const afterReplace = placeHolderReplacer.replace({
replaceable: "{{key}}",
otherReplaceableWithSameKey: "<
otherReplaceable: "{{otherKey}}",
});
// afterReplace = {
// replaceable: 100,
// otherReplaceableWithSameKey: 100,
// otherReplaceable: 200
// }
`
> [!NOTE]
> An object passed to .replace() is mutated in-place:`
>
> ts`
> const beforeReplace = { some: "{{placeholder}}" };
> const afterReplace = placeHolderReplacer.replace(beforeReplace);
> // beforeReplace === afterReplace
>
`typescript
const placeHolderReplacer = new JsonPlaceholderReplacer({
delimiterTags: [{ begin: "@{{-", end: "-}}@" }],
});
placeHolderReplacer.addVariableMap({
key: "nice",
});
const afterReplace = placeHolderReplacer.replace({
replaceable: "@{{-key-}}@",
});
// afterReplace = {
// replaceable: "nice",
// }
`
`typescript
placeHolderReplacer.addVariableMap({
firstMapKey: "1",
});
placeHolderReplacer.addVariableMap({
secondMapKey: 2,
});
const afterReplace = placeHolderReplacer.replace({
replaceable: "{{firstMapKey}}",
otherReplaceable: "<
});
// afterReplace = {
// replaceable: "1",
// otherReplaceable: 2
// }
`
`typescript
placeHolderReplacer.addVariableMap({
id: "lowerPriority",
name: "Name",
});
placeHolderReplacer.addVariableMap({
id: "higherPriority",
name: undefined,
});
const afterReplace = placeHolderReplacer.replace({
id: "{{id}}",
name: "{{name}}",
});
// afterReplace = {
// id: "higherPriority"
// name: "Name"
// }
`
`typescript
placeHolderReplacer.addVariableMap({
id: "Id",
name: "Name",
});
placeHolderReplacer.setVariableMap({
// <- note setVariableMap() here
id: "New Id",
name: undefined,
});
const afterReplace = placeHolderReplacer.replace({
id: "{{id}}",
name: "{{name}}",
});
// afterReplace = {
// id: "New Id"
// name: "{{name}}"
// }
`
`typescript
placeHolderReplacer.addVariableMap({
id: "Id",
name: "Name",
});
const afterReplace = placeHolderReplacer.replaceWith(
{
id: "{{id}}",
name: "{{name}}",
},
{ name: "New Name" },
);
// afterReplace = {
// id: "{{id}}"
// name: "New Name"
// }
`
If a variable in the map is boolean/string/number/object, it remains as boolean/string/number/object when it's replaced
`typescript
placeHolderReplacer.addVariableMap({
booleanKey: true,
stringKey: "string",
numberKey: 10,
objectKey: {
inner: "inner",
},
});
const afterReplace = placeHolderReplacer.replace({
booleanReplaceable: "{{booleanKey}}",
stringReplaceable: "{{stringKey}}",
numberReplaceable: "{{numberKey}}",
objectReplaceable: "{{objectKey}}",
});
// afterReplace = {
// booleanReplaceable: true,
// stringReplaceable: "string",
// numberReplaceable: 10,
// objectReplaceable: {
// inner: "inner"
// }
// }
`
`typescript`
placeHolderReplacer.addVariableMap({
key: "someValue",
});
const afterReplace = placeHolderReplacer.replace({
"{{key}}": "value",
});
// afterReplace = {
// "{{key}}": "value"
// }
`typescript
placeHolderReplacer.addVariableMap({
key: 987,
objectReplaceable: {
inner: "inner",
},
});
const afterReplace = placeHolderReplacer.replace({
array: ["string", "{{objectReplaceable}}", "{{key}}"],
});
// afterReplace = {
// array: ["string", { inner: "inner" }, 987]
// }
`
`typescript
placeHolderReplacer.addVariableMap({
key: {
nested: "value",
},
});
const afterReplace: any = placeHolderReplacer.replace({
replaceable: "<
});
// afterReplace = {
// replaceable: "value"
// }
`
`typescript
placeHolderReplacer.addVariableMap({
key: "value",
});
const afterReplace: any = placeHolderReplacer.replace({
replaceable: "<
});
// afterReplace = {
// replaceable: "default-value"
// }
`
`typescript
const placeHolderReplacer = new JsonPlaceholderReplacer({
defaultValueSeparator: ":=:",
});
placeHolderReplacer.addVariableMap({
key: "value",
});
const afterReplace: any = placeHolderReplacer.replace({
replaceable: "<
});
// afterReplace = {
// replaceable: "default-value"
// }
`
`typescript
const placeHolderReplacer = new JsonPlaceholderReplacer();
const cyclicObject: any = {
key: "{{key1}}",
deep: {
nested: "{{key2}}",
},
};
cyclicObject.deep.circular = cyclicObject;
placeHolderReplacer.addVariableMap({ key1: "value1", key2: "value2" });
const afterReplace: any = placeHolderReplacer.replace(cyclicObject);
// afterReplace = {
// key: "value1",
// deep: {
// nested: "value2",
// circular: {
// key: "value1",
// deep: {
// nested: "value2",
// circular: [CYCLE...]
// }
// }
// }
// }
``