https://github.com/zardoy/modify-json-file
Simple module for modifying fields in JSON files
https://github.com/zardoy/modify-json-file
json json-file jsonc modify-json nodejs package-json
Last synced: 5 months ago
JSON representation
Simple module for modifying fields in JSON files
- Host: GitHub
- URL: https://github.com/zardoy/modify-json-file
- Owner: zardoy
- License: mit
- Created: 2021-06-09T11:23:40.000Z (about 5 years ago)
- Default Branch: next
- Last Pushed: 2021-11-20T17:23:32.000Z (over 4 years ago)
- Last Synced: 2025-09-21T21:43:21.568Z (9 months ago)
- Topics: json, json-file, jsonc, modify-json, nodejs, package-json
- Language: TypeScript
- Homepage: http://npmjs.com/modify-json-file
- Size: 296 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
Awesome Lists containing this project
README
# Modify JSON
Simplest way to modify JSON files
[API](https://paka.dev/npm/modify-json-file)
## Why?
Becaues I got tired of writing `read`/`write` functions for JSON files, especially when I need to change dozens of files.
## Usage
- Only async use
### Basic Example
Let's start with *package.json* file:
```json
// 📁package.json
{
"name": "package",
"main": "index.js",
"author": "eldar",
"files": [ "build" ],
"dependencies": {
"type-fest": "*",
"fdir": ">=2"
}
}
```
And this code:
```ts
import { modifyJsonFile } from "modify-json-file";
// modify package.json in the same dir
await modifyJsonFile(
path.join(__dirname, "package.json"),
{
name: s => `super ${s}`,
main: "build/electron.js",
files: undefined, // removing the property
dependencies: {
"type-fest": "^1.0.0"
}
}
)
```
After running the code, *package.json* will be:
```json
{
"name": "super package",
"main": "build/electron.js",
"author": "eldar",
"dependencies": {
"type-fest": "^1.0.0"
}
}
```
As you can see above, `modifyJsonFile` only merges **only on top level** properties. Currently, there is no support for nested property merging.
Note that to simplify docs I won't use `path` module here, but you should use it everywhere.
> In example above, `modifyPackageJson` should be used to provider typing for you
As always, for more usage examples you can look into `test-d/index.test-d.ts` or `tests` files.
### Non-object root value
> Remember, that at root level value can be any valid JSON value: `string`, `number`, `boolean`, `null`, `object` or `array`.
Be aware of modifying non object JSON files (where root type is not an object). For example:
Our code:
```ts
import { modifyJsonFile } from "modify-json-file";
// telling that root type is number (in this case it's obligatory)
await modifyJsonFile("package.json", n => n + 1);
```
Expected JSON:
```json
// 📁someNumber.json
5
```
Actual JSON:
```json
// 📁someNumber.json
{
"retries": 5
}
```
After running the code above, without any warnings you will get this:
```json
// 📁someNumber.json
"[object Object]1"
```
That's because callback `n => n + 1` has transformed `n` (object) into string.
Here, despite of the TS type (number), `n` is object in runtime, so `n + 1` just stringified `n` and returned `[object Object]1`.
Then this module just stringified the string to store output as valid JSON string in file.
Remember, **this module doesn't do any type checking in runtime**, you need to use `typeof` in callback for checking root types or schema validators (like [ajv](http://npmjs.com/ajv)) for objects.
### Formatting
By default, it will preserve tab size (thanks to [detect-indent](https://www.npmjs.com/package/detect-indent)), but you can control this by overriding `tabSize` option. For example, we can use it to just format the file:
```ts
import { modifyJsonFile } from "modify-json-file";
// this will format file to use \t (hard tabs)
await modifyJsonFile("someFile.json", {}, { tabSize: "hard" });
```
## JSONC
Pass `{ removeJsonc: true }` option to enable processing `jsonc` files.
**WARNING**, this option will remove comments and trailing commas forever!
This is temporary limitation and the option will be renamed to `jsonc` once limitation is removed.
> `modifyTsConfigJsonFile` has this option enabled by default
## TODO
Docs:
- [ ] Custom parser / stringifer (look at quicktype issue) to save property order
- [ ] Helper exports section
- [ ] Extend package.json typings
- [ ] Examples with immer
- [ ] Fix auto generated docs
- [ ] Runtypes?
- [ ] Describe all possible usage cases
- [ ] Give a hint, that it doesn't perform schema checking again actual file contents when type is passed into generic function `modifyJsonFile`
- [ ] Strip bom option
```ts
await fs.promises.readFile(./package.json, "utf8");
```
Into this:
```ts
await fs.promises.readFile(path.join(__dirname, "package.json"), "utf8");
```
- [ ] find a way to use FS in builder-way (like [fdir](https://www.npmjs.com/package/fdir) does) and deprecate this module
## Related
- [jsonfile](https://npmjs.com/jsonfile): simple reading / writing for json files
- immer ?
[Other cool modules for working with JSON](https://github.com/search?q=user%3Asindresorhus+json)