Socket
Socket
Sign inDemoInstall

json-placeholder-replacer

Package Overview
Dependencies
0
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.37 to 2.0.0

cc-test-reporter

21

dist/json-placeholder-replacer.d.ts

@@ -1,2 +0,2 @@

export type DelimiterTag = {
export interface DelimiterTag {
begin: string;

@@ -6,14 +6,21 @@ end: string;

escapedEnding?: string;
};
}
export interface Configuration {
delimiterTags: DelimiterTag[];
defaultValueSeparator: string;
}
export declare class JsonPlaceholderReplacer {
private variablesMap;
private readonly delimiterTags;
constructor(...delimiterTags: DelimiterTag[]);
addVariableMap(variableMap: object | string): JsonPlaceholderReplacer;
replace(json: object): {};
private readonly variablesMap;
private readonly configuration;
private readonly delimiterTagsRegex;
constructor(options?: Partial<Configuration>);
addVariableMap(variableMap: Record<string, unknown> | string): JsonPlaceholderReplacer;
replace(json: object): object;
private initializeOptions;
private replaceChildren;
private replaceValue;
private replacer;
private parseTag;
private checkInEveryMap;
private navigateThroughMap;
}

@@ -6,21 +6,24 @@ "use strict";

{
begin: '{{',
end: '}}'
begin: "{{",
end: "}}",
},
{
begin: '<<',
end: '>>'
}
begin: "<<",
end: ">>",
},
];
const defaultSeparator = ":";
class JsonPlaceholderReplacer {
constructor(...delimiterTags) {
constructor(options) {
this.variablesMap = [];
if (delimiterTags.length === 0) {
delimiterTags = defaultDelimiterTags;
}
const escapeRegExp = (text) => text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
this.delimiterTags = delimiterTags.map(tag => (Object.assign(Object.assign({}, tag), { escapedBeginning: escapeRegExp(tag.begin), escapedEnding: escapeRegExp(tag.end) })));
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') {
if (typeof variableMap === "string") {
this.variablesMap.push(JSON.parse(variableMap));

@@ -36,6 +39,20 @@ }

}
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') {
if (typeof attribute === "object") {
node[key] = this.replaceChildren(attribute);

@@ -50,9 +67,5 @@ }

replaceValue(node) {
const delimiterTagRegex = this.delimiterTags
.map(delimiterTag => `^${delimiterTag.begin}[^${delimiterTag.end}]+${delimiterTag.end}$`).join('|');
const regExp = new RegExp(delimiterTagRegex);
const placeHolderIsInsideStringContext = !regExp.test(node);
const output = this.delimiterTags
.reduce((acc, delimiterTag) => {
const regex = new RegExp(`(${delimiterTag.escapedBeginning}[^${delimiterTag.escapedEnding}]+${delimiterTag.escapedEnding})`, 'g');
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));

@@ -69,5 +82,8 @@ }, node);

return (delimiterTag) => (placeHolder) => {
const path = placeHolder.substr(delimiterTag.begin.length, placeHolder.length - (delimiterTag.begin.length + delimiterTag.end.length));
const mapCheckResult = this.checkInEveryMap(path);
const { tag, defaultValue } = this.parseTag(placeHolder, delimiterTag);
const mapCheckResult = this.checkInEveryMap(tag);
if (mapCheckResult === undefined) {
if (defaultValue !== undefined) {
return defaultValue;
}
return placeHolder;

@@ -79,3 +95,3 @@ }

const parsed = JSON.parse(mapCheckResult);
if (typeof parsed === 'object') {
if (typeof parsed === "object") {
return JSON.stringify(parsed);

@@ -86,5 +102,16 @@ }

}
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 + 1);
}
return { tag, defaultValue };
}
checkInEveryMap(path) {
let result = undefined;
this.variablesMap.forEach(map => result = this.navigateThroughMap(map, path));
let result;
this.variablesMap.forEach((map) => (result = this.navigateThroughMap(map, path)));
return result;

@@ -100,8 +127,8 @@ }

}
let keys = path.split('.');
const keys = path.split(".");
const key = keys[0];
keys.shift();
return this.navigateThroughMap(map[key], keys.join('.'));
return this.navigateThroughMap(map[key], keys.join("."));
}
}
exports.JsonPlaceholderReplacer = JsonPlaceholderReplacer;
{
"name": "json-placeholder-replacer",
"version": "1.0.37",
"version": "2.0.0",
"description": "Javascript/Typescript library/cli to replace placeholders in an javascript object",

@@ -10,5 +10,6 @@ "main": "dist/index.js",

"codeCoverage": "node_modules/.bin/jest --silent --coverage",
"lint": "node_modules/.bin/tslint --project tsconfig.json",
"build": "tsc",
"all": "npm run lint && npm run build && npm run codeCoverage && npm run test"
"lint": "node_modules/.bin/tslint --project tsconfig.json --force",
"build": "tsc --project tsconfig.build.json",
"all": "npm run lint && npm run build && npm run codeCoverage && npm run test",
"prepare": "husky install"
},

@@ -37,3 +38,3 @@ "repository": {

"*": "prettier --write",
"*.ts": "eslint --fix"
"*.ts": "npm run lint --fix"
},

@@ -70,10 +71,8 @@ "homepage": "https://github.com/virgs/jsonPlaceholderReplacer#readme",

"devDependencies": {
"@types/jest": "^29.5.4",
"@types/node": "^20.5.7",
"husky": "^8.0.3",
"jest": "^29.6.4",
"lint-staged": "^13.2.2",
"prettier": "^2.8.8",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"@types/jest": "^29.5.4",
"@types/node": "^20.5.7",
"jest": "^29.6.4",
"ts-jest": "^29.1.1",

@@ -80,0 +79,0 @@ "ts-node": "^10.9.1",

# jsonPlaceholderReplacer
[![npm version](https://badge.fury.io/js/json-placeholder-replacer.svg)](https://badge.fury.io/js/json-placeholder-replacer)
[![npm version](https://badge.fury.io/js/json-placeholder-replacer.svg)](https://badge.fury.io/js/json-placeholder-replacer)
[![build status](https://circleci.com/gh/virgs/jsonPlaceholderReplacer.svg?style=shield)](https://app.circleci.com/pipelines/github/virgs/jsonPlaceholderReplacer)
[![Maintainability](https://api.codeclimate.com/v1/badges/6e586ff6eb12a67da08e/maintainability)](https://codeclimate.com/github/lopidio/jsonPlaceholderReplacer/maintainability)
[![Maintainability](https://api.codeclimate.com/v1/badges/6e586ff6eb12a67da08e/maintainability)](https://codeclimate.com/github/lopidio/jsonPlaceholderReplacer/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/6e586ff6eb12a67da08e/test_coverage)](https://codeclimate.com/github/lopidio/jsonPlaceholderReplacer/test_coverage)
[![Known Vulnerabilities](https://snyk.io/test/github/virgs/jsonPlaceholderReplacer/badge.svg)](https://app.snyk.io/)
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.
Don't worry, if you don't like these default placeholders you can create your own.
## CLI usage
```shell
json-placeholder-replacer replaceableFilename [...variableMaps]
```
$ json-placeholder-replacer replaceableFilename [...variableMaps]
### Example
```shell
json-placeholder-replacer [replaceable.json](/rep) [variable.map](/map)
```
Example:
```$ json-placeholder-replacer ```[replaceable.json](/rep) [variable.map](/map)
Would result:
### Would result
```shell
cat replaceable.json
# {
# "curly": "{{key}}",
# "angle": "<<key>>"
# }
cat variable.map:
# {
# "key": 10,
# "not-mapped": 20
# }
json-placeholder-replacer replaceable.json variable.map
# {
# "curly": 10,
# "angle": 10,
# "not-mapped": 20
# }
```
replaceable.json:
{
"curly": "{{key}}",
"angle": "<<key>>"
}
variable.map:
{
"key": 10
}
result:
{
"curly": 10,
"angle": 10
}
```
## Library usage
## Library usage:
As simples as:
```
import {JsonPlaceholderReplacer} from "json-placeholder-replacer";
```typescript
import { JsonPlaceholderReplacer } from "json-placeholder-replacer";
const placeHolderReplacer = new JsonPlaceholderReplacer();
placeHolderReplacer.addVariableMap({
key: 100,
otherKey: 200
key: 100,
otherKey: 200,
});
const afterReplace = placeHolderReplacer.replace({
replaceable: "{{key}}",
otherReplaceableWithSameKey: "<<key>>",
otherReplaceable: "{{otherKey}}"
})
replaceable: "{{key}}",
otherReplaceableWithSameKey: "<<key>>",
otherReplaceable: "{{otherKey}}",
});

@@ -66,11 +71,14 @@ // afterReplace = {

It's possible to replace the default placeholders with some as cool as you want.
```
const placeHolderReplacer = new JsonPlaceholderReplacer({begin: '@{{-', end: '-}}@'});
### You can replace the default placeholders with some as cool as you want
```typescript
const placeHolderReplacer = new JsonPlaceholderReplacer({
delimiterTags: [{ begin: "@{{-", end: "-}}@" }],
});
placeHolderReplacer.addVariableMap({
key: "nice"
key: "nice",
});
const afterReplace = placeHolderReplacer.replace({
replaceable: "@{{-key-}}@",
})
replaceable: "@{{-key-}}@",
});

@@ -82,14 +90,15 @@ // afterReplace = {

It's possible to add more than one variables map.
```
### It's also possible to add more than one variables map
```typescript
placeHolderReplacer.addVariableMap({
firstMapKey: "1"
firstMapKey: "1",
});
placeHolderReplacer.addVariableMap({
secondMapKey: 2
secondMapKey: 2,
});
const afterReplace = placeHolderReplacer.replace({
replaceable: "{{firstMapKey}}",
otherReplaceable: "<<secondMapKey>>"
})
replaceable: "{{firstMapKey}}",
otherReplaceable: "<<secondMapKey>>",
});

@@ -102,13 +111,14 @@ // afterReplace = {

And the last added maps have higher priority, so:
```
### And the last added maps have higher priority, so
```typescript
placeHolderReplacer.addVariableMap({
id: "lowerPriority"
id: "lowerPriority",
});
placeHolderReplacer.addVariableMap({
   id: "higherPriority"
id: "higherPriority",
});
const afterReplace = placeHolderReplacer.replace({
replaceable: "{{id}}"
})
replaceable: "{{id}}",
});

@@ -119,18 +129,20 @@ // afterReplace = {

```
It keeps original variable types. So, if, in the map, a variable is boolean/string/number/object when it's replaced, it remains as boolean/string/number/object:
```
### It keeps original variable types. So, if, in the map, a variable is boolean/string/number/object when it's replaced, it remains as boolean/string/number/object
```typescript
placeHolderReplacer.addVariableMap({
booleanKey: true,
   stringKey: "string",
numberKey: 10,
objectKey: {
     inner: "inner"
}
booleanKey: true,
stringKey: "string",
numberKey: 10,
objectKey: {
inner: "inner",
},
});
const afterReplace = placeHolderReplacer.replace({
booleanReplaceable: "{{booleanKey}}",
stringReplaceable: "{{stringKey}}",
numberReplaceable: "{{numberKey}}",
objectReplaceable: "{{objectKey}}"
})
booleanReplaceable: "{{booleanKey}}",
stringReplaceable: "{{stringKey}}",
numberReplaceable: "{{numberKey}}",
objectReplaceable: "{{objectKey}}",
});

@@ -145,13 +157,13 @@ // afterReplace = {

// }
```
Just to make it clearer, it does not replace the placeholder Key:
```
### Just to make it clearer, it does not replace the placeholder Key
```typescript
placeHolderReplacer.addVariableMap({
key: "someValue"
key: "someValue",
});
const afterReplace = placeHolderReplacer.replace({
"{{key}}": "value"
})
"{{key}}": "value",
});
// afterReplace = {

@@ -162,4 +174,5 @@ //   "{{key}}": "value"

And, of course, it handles array substitution as well:
```
### And, of course, it handles array substitution as well
```typescript
placeHolderReplacer.addVariableMap({

@@ -182,11 +195,12 @@ key: 987,

Want to get nested elements? Go for it!
```
### Want to get nested elements? Go for it
```typescript
placeHolderReplacer.addVariableMap({
key: {
nested: "value"
}
key: {
nested: "value",
},
});
const afterReplace: any = placeHolderReplacer.replace({
replaceable: "<<key.nested>>"
replaceable: "<<key.nested>>",
});

@@ -197,3 +211,36 @@

// }
```
### This feature allows you to have default values in case you don't have them mapped
```typescript
placeHolderReplacer.addVariableMap({
key: "value",
});
const afterReplace: any = placeHolderReplacer.replace({
replaceable: "<<not-found-key:default-value>>",
});
// afterReplace = {
// replaceable: "default-value"
// }
```
### Of course, you can also change what is the default value separator (defaults to ':')
```typescript
const placeHolderReplacer = new JsonPlaceholderReplacer({
defaultValueSeparator: "=",
});
placeHolderReplacer.addVariableMap({
key: "value",
});
const afterReplace: any = placeHolderReplacer.replace({
replaceable: "<<not-found-key=default-value>>", // Note the '=' character here
});
// afterReplace = {
// replaceable: "default-value"
// }
```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc