Skip to content

Commit

Permalink
Add filesystem utils (#148)
Browse files Browse the repository at this point in the history
This commit adds several utility functions that are related to the
filesystem in some way.

- Most of the functions here are wrappers around basic filesystem
  operations with better error handling. Node's `fs.promises` module is
  somewhat difficult to work with because [the errors it produces lack
  proper stacktraces][1]. The functions that directly use `fs.promises`
  wrap caught errors in order to supply the missing stacktraces.
- Two functions make it easier to read and write JSON files (with support
  for JSON-compatible interfaces, such as [JSON5][2]).
- One function, `createSandbox`, is designed to wrap tests that need
  a temporary directory to work within, such as those for a command-line
  tool that makes changes to the filesystem.

Here are places where we currently use these utilities (or something
like them):

- https://github.com/MetaMask/action-utils/blob/54ddd730746668cb4c1c88b4edfa720cbecf5e32/src/file-utils.ts
- https://github.com/MetaMask/create-release-branch/blob/3556dee47163c921186051be7a1f3c98e2049db9/src/fs.ts
- https://github.com/MetaMask/create-release-branch/blob/3556dee47163c921186051be7a1f3c98e2049db9/tests/helpers.ts

One note about these utilities is that they require Node to use and will
not work in the browser. Because we already create two kinds of bundles,
one for CommonJS and another ESM, it would be difficult to create a
second level of bundles, one for Node and another for the browser.
Instead of requiring more complexity around the bundle configuration,
this commit instead introduces another way to import the package.

By default, you'll get all exports that are guaranteed to be
cross-platform. That means that the file utilities won't show up:

``` typescript
// ❌
import { readFile } from "@metamask/utils";
```

If you want all of the cross-platform exports plus the Node-specific
ones, you will have to import "@metamask/utils/node". For instance:

``` typescript
// ✅
import { readFile } from "@metamask/utils/node";
```

Note that you will need to use a `moduleResolution` of `nodenext`
(and not `node`) in your TypeScript project in order to take advantage
of this.

[1]: nodejs/node#30944
[2]: https://www.npmjs.com/package/json5

---

Co-authored-by: Maarten Zuidhoorn <[email protected]>
Co-authored-by: legobeat <[email protected]>
  • Loading branch information
3 people authored Oct 17, 2023
1 parent d0db51f commit 12b5003
Show file tree
Hide file tree
Showing 7 changed files with 1,387 additions and 62 deletions.
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
"require": "./dist/index.js",
"types": "./dist/types/index.d.ts"
},
"./node": {
"import": "./dist/node.mjs",
"require": "./dist/node.js",
"types": "./dist/types/node.d.ts"
},
"./package.json": "./package.json"
},
"main": "./dist/index.js",
Expand Down Expand Up @@ -65,6 +70,7 @@
"@metamask/eslint-config-nodejs": "^12.0.0",
"@metamask/eslint-config-typescript": "^12.0.0",
"@types/jest": "^28.1.7",
"@types/jest-when": "^3.5.3",
"@types/node": "^17.0.23",
"@typescript-eslint/eslint-plugin": "^5.43.0",
"@typescript-eslint/parser": "^5.43.0",
Expand All @@ -79,6 +85,7 @@
"eslint-plugin-promise": "^6.1.1",
"jest": "^29.2.2",
"jest-it-up": "^2.0.2",
"jest-when": "^3.6.0",
"prettier": "^2.7.1",
"prettier-plugin-packagejson": "^2.3.0",
"stdio-mock": "^1.2.0",
Expand Down
Loading

0 comments on commit 12b5003

Please sign in to comment.