szwacz / fs-jetpack

Better file system API for Node.js
MIT License
777 stars 41 forks source link

Pluggable serializers #120

Open eaton opened 1 year ago

eaton commented 1 year ago

As briefly discussed in #116, this pull request adds the concept of pluggable serializers to fs-jetpack's read and write operations. Currently, JSON and JSON with dates are treated as special conveniences. This patch allows any object with parse() and stringily() functions to be assigned as the serializer for a particular file extension.

Usage example:

const NdJson: Serializer<any[], any[]> = {
  validate: (input: unknown) => Array.isArray(input),
  parse: function (data: string) {
    const lines = data.split('\n');
    return lines.map((line) => JSON.parse(line));
  },
  stringify: function (data: any[]): string {
    return data.map((item) => JSON.stringify(item, undefined, 0)).join('\n');
  },
};

const obj = [
  { utf8: "ąćłźż" },
  { utf8: "☃" }
];

jetpack.setSerializer('.ndjson', NdJson);
jetpack.write("file.ndjson", obj);
const raw = jetpack.read("file.ndjson"); // '{"utf8":"ąćłźż"}\n{"utf8":"☃"}'
const output = jetpack.read("file.ndjson", "auto"); // [{ utf8: "ąćłźż" }, { utf8: "☃" }]

While I'm relatively new to the fs-jetpack codebase, I've tried to follow its conventions as closely as possible and avoid any unnecessary side effects in how other functions work. A handful of updates to the read() and write() tests have been made to account for the new option properties, but other than that all other tests are unchanged and passing.

Potential areas for improvement:

I've been using the code in this patch on my own projects for a bit to simplify reading/writing NDJSON, JSON5, and yaml configuration files. Adding other formats like TOML, INI, and even goofy stuff like MacOS .plist files is pretty easy. I'm curious if the general approach is appealing as a potential addition to fsJetpack, if a different way of solving the problem would be better, or if it feels altogether out of scope for the library. In any case, thanks for the great work you've done on fsJetpack! It's been a great time saver.

szwacz commented 11 months ago

Thank you @eaton! I'm pretty busy now. Promise to review it soon.

eaton commented 11 months ago

No worries — as you said, you're not working on this project as part of your job now, so no expectations. Just wanted to be sure I got this tidied up as an official PR rather than just playing in my own fork!