{"id":16077744,"url":"https://github.com/virgs/jsonPlaceholderReplacer","last_synced_at":"2025-10-22T20:30:45.651Z","repository":{"id":44175024,"uuid":"130083482","full_name":"virgs/jsonPlaceholderReplacer","owner":"virgs","description":"Typescript library/cli to replace placeholders in json","archived":false,"fork":false,"pushed_at":"2025-02-03T17:10:05.000Z","size":1717,"stargazers_count":10,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-03T18:25:24.685Z","etag":null,"topics":["cli","javascript","javascript-library","json","library","placeholder","replacer","substitution","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/json-placeholder-replacer","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/virgs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-18T15:28:12.000Z","updated_at":"2025-02-03T17:10:07.000Z","dependencies_parsed_at":"2023-09-29T19:30:38.233Z","dependency_job_id":"84c9b170-b6d5-4919-96e3-4fef7b0f0394","html_url":"https://github.com/virgs/jsonPlaceholderReplacer","commit_stats":{"total_commits":345,"total_committers":6,"mean_commits":57.5,"dds":0.7246376811594203,"last_synced_commit":"e452d8479ff5b5849e4f2a3a7651f5ce04961e44"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virgs%2FjsonPlaceholderReplacer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virgs%2FjsonPlaceholderReplacer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virgs%2FjsonPlaceholderReplacer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virgs%2FjsonPlaceholderReplacer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/virgs","download_url":"https://codeload.github.com/virgs/jsonPlaceholderReplacer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237739846,"owners_count":19358624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","javascript","javascript-library","json","library","placeholder","replacer","substitution","typescript"],"created_at":"2024-10-09T10:02:36.696Z","updated_at":"2025-10-22T20:30:45.646Z","avatar_url":"https://github.com/virgs.png","language":"TypeScript","funding_links":[],"categories":["cli"],"sub_categories":[],"readme":"# jsonPlaceholderReplacer\n\n[![npm version](https://badge.fury.io/js/json-placeholder-replacer.svg)](https://badge.fury.io/js/json-placeholder-replacer)\n[![build status](https://circleci.com/gh/virgs/jsonPlaceholderReplacer.svg?style=shield)](https://app.circleci.com/pipelines/github/virgs/jsonPlaceholderReplacer)\n[![Maintainability](https://api.codeclimate.com/v1/badges/6e586ff6eb12a67da08e/maintainability)](https://codeclimate.com/github/lopidio/jsonPlaceholderReplacer/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/6e586ff6eb12a67da08e/test_coverage)](https://codeclimate.com/github/lopidio/jsonPlaceholderReplacer/test_coverage)\n[![Known Vulnerabilities](https://snyk.io/test/github/virgs/jsonPlaceholderReplacer/badge.svg)](https://app.snyk.io/)\n\nLightweight yet really powerful typescript library/cli to replace placeholders in an javascript object/JSON.\nBy default, all you have to do is to use double curly brackets **{{**placeholderKey**}}** or angle brackets **\u003c\u003c**placeholderKey**\u003e\u003e**, interchangeably, to identify the placeholder.\nDon't worry, if you don't like these default placeholders you can create your own.\n\n## CLI usage\n\n```shell\njson-placeholder-replacer annotetad-json.json [...variableMaps]\n```\n\n### Example\n\n$ json-placeholder-replacer [annotated.json](/annotated.json) [variable_map.json](/variable_map.json)\n$ jpr [variable_map.json](/variable_map.json) \u003c [annotated.json](/annotated.json)\n$ cat [annotated.json](/annotated.json) | jpr [variable_map.json](/variable_map.json)\n$ echo '{\"curly\": \"{{key}}\", \"angle\": \"\u003c\u003ckey\u003e\u003e\"}' | jpr variable_maps\n\n### Would result\n\n```shell\ncat replaceable.json\n        # {\n        #  \"curly\": \"{{key}}\",\n        #  \"angle\": \"\u003c\u003ckey\u003e\u003e\"\n        # }\ncat variable.map:\n        # {\n        #         \"key\": 10,\n        #         \"not-mapped\": 20\n        # }\njson-placeholder-replacer replaceable.json variable.map\n        # {\n        #         \"curly\": 10,\n        #         \"angle\": 10,\n        #         \"not-mapped\": 20\n        # }\n```\n\n## Library usage\n\n```typescript\nimport { JsonPlaceholderReplacer } from \"json-placeholder-replacer\";\nconst placeHolderReplacer = new JsonPlaceholderReplacer();\n\nplaceHolderReplacer.addVariableMap({\n  key: 100,\n  otherKey: 200,\n});\nconst afterReplace = placeHolderReplacer.replace({\n  replaceable: \"{{key}}\",\n  otherReplaceableWithSameKey: \"\u003c\u003ckey\u003e\u003e\",\n  otherReplaceable: \"{{otherKey}}\",\n});\n\n// afterReplace = {\n//    replaceable: 100,\n//    otherReplaceableWithSameKey: 100,\n//    otherReplaceable: 200\n// }\n```\n\n\u003e [!NOTE]\n\u003e An object passed to `.replace()` is mutated in-place:\n\u003e\n\u003e ```ts\n\u003e const beforeReplace = { some: \"{{placeholder}}\" };\n\u003e const afterReplace = placeHolderReplacer.replace(beforeReplace);\n\u003e // beforeReplace === afterReplace\n\u003e ```\n\n### You can replace the default placeholders with some as cool as you want\n\n```typescript\nconst placeHolderReplacer = new JsonPlaceholderReplacer({\n  delimiterTags: [{ begin: \"@{{-\", end: \"-}}@\" }],\n});\nplaceHolderReplacer.addVariableMap({\n  key: \"nice\",\n});\nconst afterReplace = placeHolderReplacer.replace({\n  replaceable: \"@{{-key-}}@\",\n});\n\n// afterReplace = {\n//    replaceable: \"nice\",\n// }\n```\n\n### It's also possible to add more than one variables map\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  firstMapKey: \"1\",\n});\nplaceHolderReplacer.addVariableMap({\n  secondMapKey: 2,\n});\nconst afterReplace = placeHolderReplacer.replace({\n  replaceable: \"{{firstMapKey}}\",\n  otherReplaceable: \"\u003c\u003csecondMapKey\u003e\u003e\",\n});\n\n// afterReplace = {\n//    replaceable: \"1\",\n//    otherReplaceable: 2\n// }\n```\n\n### And the last added maps have higher priority (but non-nullish values will be preserved from previous map)\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  id: \"lowerPriority\",\n  name: \"Name\",\n});\nplaceHolderReplacer.addVariableMap({\n  id: \"higherPriority\",\n  name: undefined,\n});\nconst afterReplace = placeHolderReplacer.replace({\n  id: \"{{id}}\",\n  name: \"{{name}}\",\n});\n\n// afterReplace = {\n//    id: \"higherPriority\"\n//    name: \"Name\"\n// }\n```\n\n### It's possible to override global values map with `.setVariableMap()`\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  id: \"Id\",\n  name: \"Name\",\n});\nplaceHolderReplacer.setVariableMap({\n  // \u003c- note setVariableMap() here\n  id: \"New Id\",\n  name: undefined,\n});\nconst afterReplace = placeHolderReplacer.replace({\n  id: \"{{id}}\",\n  name: \"{{name}}\",\n});\n\n// afterReplace = {\n//    id: \"New Id\"\n//    name: \"{{name}}\"\n// }\n```\n\n### It's possible to override global maps with local by `.replaceWith()`\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  id: \"Id\",\n  name: \"Name\",\n});\nconst afterReplace = placeHolderReplacer.replaceWith(\n  {\n    id: \"{{id}}\",\n    name: \"{{name}}\",\n  },\n  { name: \"New Name\" },\n);\n\n// afterReplace = {\n//    id: \"{{id}}\"\n//    name: \"New Name\"\n// }\n```\n\n### It keeps original variable types\n\nIf a variable in the map is boolean/string/number/object, it remains as boolean/string/number/object when it's replaced\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  booleanKey: true,\n  stringKey: \"string\",\n  numberKey: 10,\n  objectKey: {\n    inner: \"inner\",\n  },\n});\nconst afterReplace = placeHolderReplacer.replace({\n  booleanReplaceable: \"{{booleanKey}}\",\n  stringReplaceable: \"{{stringKey}}\",\n  numberReplaceable: \"{{numberKey}}\",\n  objectReplaceable: \"{{objectKey}}\",\n});\n\n// afterReplace = {\n//    booleanReplaceable: true,\n//    stringReplaceable: \"string\",\n//    numberReplaceable: 10,\n//    objectReplaceable: {\n//      inner: \"inner\"\n//    }\n// }\n```\n\n### Just to make it clearer, it does not replace the placeholder Key\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  key: \"someValue\",\n});\nconst afterReplace = placeHolderReplacer.replace({\n  \"{{key}}\": \"value\",\n});\n// afterReplace = {\n//    \"{{key}}\": \"value\"\n// }\n```\n\n### And, of course, it handles array substitution as well\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  key: 987,\n  objectReplaceable: {\n    inner: \"inner\",\n  },\n});\nconst afterReplace = placeHolderReplacer.replace({\n  array: [\"string\", \"{{objectReplaceable}}\", \"{{key}}\"],\n});\n\n// afterReplace = {\n//    array: [\"string\", { inner: \"inner\" }, 987]\n// }\n```\n\n### Want to get nested elements? Go for it\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  key: {\n    nested: \"value\",\n  },\n});\nconst afterReplace: any = placeHolderReplacer.replace({\n  replaceable: \"\u003c\u003ckey.nested\u003e\u003e\",\n});\n\n// afterReplace = {\n//    replaceable: \"value\"\n// }\n```\n\n### This feature allows you to have default values in case you don't have them mapped\n\n```typescript\nplaceHolderReplacer.addVariableMap({\n  key: \"value\",\n});\nconst afterReplace: any = placeHolderReplacer.replace({\n  replaceable: \"\u003c\u003cnot-found-key:default-value\u003e\u003e\",\n});\n\n// afterReplace = {\n//    replaceable: \"default-value\"\n// }\n```\n\n### Of course, you can also change what is the default value separator (defaults to ':')\n\n```typescript\nconst placeHolderReplacer = new JsonPlaceholderReplacer({\n  defaultValueSeparator: \":=:\",\n});\n\nplaceHolderReplacer.addVariableMap({\n  key: \"value\",\n});\nconst afterReplace: any = placeHolderReplacer.replace({\n  replaceable: \"\u003c\u003cnot-found-key:=:default-value\u003e\u003e\", // Note the ':=:'\n});\n\n// afterReplace = {\n//    replaceable: \"default-value\"\n// }\n```\n\n### Lastly, cyclic objects are also accepted\n\n```typescript\nconst placeHolderReplacer = new JsonPlaceholderReplacer();\n\nconst cyclicObject: any = {\n  key: \"{{key1}}\",\n  deep: {\n    nested: \"{{key2}}\",\n  },\n};\ncyclicObject.deep.circular = cyclicObject;\nplaceHolderReplacer.addVariableMap({ key1: \"value1\", key2: \"value2\" });\n\nconst afterReplace: any = placeHolderReplacer.replace(cyclicObject);\n\n// afterReplace = {\n//    key: \"value1\",\n//    deep: {\n//      nested: \"value2\",\n//      circular: {\n//        key: \"value1\",\n//        deep: {\n//          nested: \"value2\",\n//          circular: [CYCLE...]\n//        }\n//      }\n//    }\n// }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirgs%2FjsonPlaceholderReplacer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvirgs%2FjsonPlaceholderReplacer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirgs%2FjsonPlaceholderReplacer/lists"}