npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

modify-json-file

v1.2.2

Published

Simple and modern way to modify JSON files

Downloads

305

Readme

Modify JSON

Simplest way to modify JSON files

API

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:

// 📁package.json
{
    "name": "package",
    "main": "index.js",
    "author": "eldar",
    "files": [ "build" ],
    "dependencies": {
        "type-fest": "*",
        "fdir": ">=2"
    }
}

And this code:

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:

{
    "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:

import { modifyJsonFile } from "modify-json-file";

// telling that root type is number (in this case it's obligatory)
await modifyJsonFile<number>("package.json", n => n + 1);

Expected JSON:

// 📁someNumber.json
5

Actual JSON:

// 📁someNumber.json
{
    "retries": 5
}

After running the code above, without any warnings you will get this:

// 📁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) for objects.

Formatting

By default, it will preserve tab size (thanks to detect-indent), but you can control this by overriding tabSize option. For example, we can use it to just format the file:

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:

  • [ ] Helper exports section

  • [ ] Extend package.json typings

  • [ ] Examples with immer

  • [ ] Make usage more clear

  • [ ] Fix auto generated docs

  • [ ] 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

  • [ ] Performance investigation (issues welcome)

  • [ ] Strip bom option

  • [ ] Fix double tsc compilation (and test actual build/)

  • [ ] transformer for paths (most likely babel plugin):

await fs.promises.readFile(./package.json, "utf8");

Into this:

await fs.promises.readFile(path.join(__dirname, "package.json"), "utf8");
  • [ ] find a way to use FS in builder-way (like fdir does) and deprecate this module

Related

  • jsonfile: simple reading / writing for json files
  • immer ?

Other cool modules for working with JSON