@metamask/utils 8.3.0 → 8.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -1
- package/dist/assert.cjs +127 -0
- package/dist/assert.cjs.map +1 -0
- package/dist/{types/assert.d.ts → assert.d.cts} +3 -3
- package/dist/assert.d.cts.map +1 -0
- package/dist/assert.d.mts +61 -0
- package/dist/assert.d.mts.map +1 -0
- package/dist/assert.mjs +119 -15
- package/dist/assert.mjs.map +1 -1
- package/dist/base64.cjs +34 -0
- package/dist/base64.cjs.map +1 -0
- package/dist/{types/base64.d.ts → base64.d.cts} +3 -3
- package/dist/base64.d.cts.map +1 -0
- package/dist/base64.d.mts +25 -0
- package/dist/base64.d.mts.map +1 -0
- package/dist/base64.mjs +28 -9
- package/dist/base64.mjs.map +1 -1
- package/dist/bytes.cjs +400 -0
- package/dist/{chunk-QEPVHEP7.js.map → bytes.cjs.map} +1 -1
- package/dist/{types/bytes.d.ts → bytes.d.cts} +3 -3
- package/dist/bytes.d.cts.map +1 -0
- package/dist/bytes.d.mts +183 -0
- package/dist/bytes.d.mts.map +1 -0
- package/dist/bytes.mjs +379 -42
- package/dist/bytes.mjs.map +1 -1
- package/dist/caip-types.cjs +151 -0
- package/dist/caip-types.cjs.map +1 -0
- package/dist/{types/caip-types.d.ts → caip-types.d.cts} +33 -12
- package/dist/caip-types.d.cts.map +1 -0
- package/dist/caip-types.d.mts +114 -0
- package/dist/caip-types.d.mts.map +1 -0
- package/dist/caip-types.mjs +139 -39
- package/dist/caip-types.mjs.map +1 -1
- package/dist/checksum.cjs +7 -0
- package/dist/checksum.cjs.map +1 -0
- package/dist/checksum.d.cts +2 -0
- package/dist/checksum.d.cts.map +1 -0
- package/dist/checksum.d.mts +2 -0
- package/dist/checksum.d.mts.map +1 -0
- package/dist/checksum.mjs +3 -11
- package/dist/checksum.mjs.map +1 -1
- package/dist/coercers.cjs +162 -0
- package/dist/coercers.cjs.map +1 -0
- package/dist/{types/coercers.d.ts → coercers.d.cts} +7 -7
- package/dist/coercers.d.cts.map +1 -0
- package/dist/coercers.d.mts +97 -0
- package/dist/coercers.d.mts.map +1 -0
- package/dist/coercers.mjs +154 -17
- package/dist/coercers.mjs.map +1 -1
- package/dist/collections.cjs +109 -0
- package/dist/collections.cjs.map +1 -0
- package/dist/{types/collections.d.ts → collections.d.cts} +1 -1
- package/dist/collections.d.cts.map +1 -0
- package/dist/collections.d.mts +39 -0
- package/dist/collections.d.mts.map +1 -0
- package/dist/collections.mjs +103 -8
- package/dist/collections.mjs.map +1 -1
- package/dist/encryption-types.cjs +3 -0
- package/dist/encryption-types.cjs.map +1 -0
- package/dist/{types/encryption-types.d.ts → encryption-types.d.cts} +2 -2
- package/dist/encryption-types.d.cts.map +1 -0
- package/dist/encryption-types.d.mts +7 -0
- package/dist/encryption-types.d.mts.map +1 -0
- package/dist/encryption-types.mjs +1 -1
- package/dist/encryption-types.mjs.map +1 -1
- package/dist/errors.cjs +111 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/{types/errors.d.ts → errors.d.cts} +1 -1
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.mts +58 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +102 -16
- package/dist/errors.mjs.map +1 -1
- package/dist/fs.cjs +248 -0
- package/dist/fs.cjs.map +1 -0
- package/dist/{types/fs.d.ts → fs.d.cts} +3 -3
- package/dist/fs.d.cts.map +1 -0
- package/dist/fs.d.mts +133 -0
- package/dist/fs.d.mts.map +1 -0
- package/dist/fs.mjs +209 -25
- package/dist/fs.mjs.map +1 -1
- package/dist/hex.cjs +134 -0
- package/dist/hex.cjs.map +1 -0
- package/dist/{types/hex.d.ts → hex.d.cts} +3 -3
- package/dist/hex.d.cts.map +1 -0
- package/dist/hex.d.mts +77 -0
- package/dist/hex.d.mts.map +1 -0
- package/dist/hex.mjs +121 -34
- package/dist/hex.mjs.map +1 -1
- package/dist/index.cjs +37 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +20 -292
- package/dist/index.mjs.map +1 -1
- package/dist/json.cjs +413 -0
- package/dist/json.cjs.map +1 -0
- package/dist/{types/json.d.ts → json.d.cts} +21 -22
- package/dist/json.d.cts.map +1 -0
- package/dist/json.d.mts +383 -0
- package/dist/json.d.mts.map +1 -0
- package/dist/json.mjs +389 -74
- package/dist/json.mjs.map +1 -1
- package/dist/keyring.cjs +3 -0
- package/dist/keyring.cjs.map +1 -0
- package/dist/{types/keyring.d.ts → keyring.d.cts} +7 -7
- package/dist/keyring.d.cts.map +1 -0
- package/dist/keyring.d.mts +224 -0
- package/dist/keyring.d.mts.map +1 -0
- package/dist/keyring.mjs +1 -1
- package/dist/keyring.mjs.map +1 -1
- package/dist/logging.cjs +43 -0
- package/dist/logging.cjs.map +1 -0
- package/dist/{types/logging.d.ts → logging.d.cts} +2 -2
- package/dist/logging.d.cts.map +1 -0
- package/dist/logging.d.mts +30 -0
- package/dist/logging.d.mts.map +1 -0
- package/dist/logging.mjs +34 -9
- package/dist/logging.mjs.map +1 -1
- package/dist/misc.cjs +149 -0
- package/dist/misc.cjs.map +1 -0
- package/dist/{types/misc.d.ts → misc.d.cts} +6 -6
- package/dist/misc.d.cts.map +1 -0
- package/dist/misc.d.mts +119 -0
- package/dist/misc.d.mts.map +1 -0
- package/dist/misc.mjs +136 -27
- package/dist/misc.mjs.map +1 -1
- package/dist/node.cjs +19 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +3 -0
- package/dist/node.d.cts.map +1 -0
- package/dist/node.d.mts +3 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +2 -312
- package/dist/node.mjs.map +1 -1
- package/dist/number.cjs +102 -0
- package/dist/number.cjs.map +1 -0
- package/dist/{types/number.d.ts → number.d.cts} +1 -1
- package/dist/number.d.cts.map +1 -0
- package/dist/number.d.mts +73 -0
- package/dist/number.d.mts.map +1 -0
- package/dist/number.mjs +93 -16
- package/dist/number.mjs.map +1 -1
- package/dist/opaque.cjs +3 -0
- package/dist/opaque.cjs.map +1 -0
- package/dist/opaque.d.cts +6 -0
- package/dist/opaque.d.cts.map +1 -0
- package/dist/opaque.d.mts +6 -0
- package/dist/opaque.d.mts.map +1 -0
- package/dist/opaque.mjs +1 -1
- package/dist/opaque.mjs.map +1 -1
- package/dist/promise.cjs +40 -0
- package/dist/promise.cjs.map +1 -0
- package/dist/{types/promise.d.ts → promise.d.cts} +12 -2
- package/dist/promise.d.cts.map +1 -0
- package/dist/promise.d.mts +45 -0
- package/dist/promise.d.mts.map +1 -0
- package/dist/promise.mjs +35 -7
- package/dist/promise.mjs.map +1 -1
- package/dist/time.cjs +67 -0
- package/dist/time.cjs.map +1 -0
- package/dist/{types/time.d.ts → time.d.cts} +1 -1
- package/dist/time.d.cts.map +1 -0
- package/dist/time.d.mts +49 -0
- package/dist/time.d.mts.map +1 -0
- package/dist/time.mjs +60 -10
- package/dist/time.mjs.map +1 -1
- package/dist/transaction-types.cjs +3 -0
- package/dist/transaction-types.cjs.map +1 -0
- package/dist/{types/transaction-types.d.ts → transaction-types.d.cts} +11 -11
- package/dist/transaction-types.d.cts.map +1 -0
- package/dist/transaction-types.d.mts +117 -0
- package/dist/transaction-types.d.mts.map +1 -0
- package/dist/transaction-types.mjs +1 -1
- package/dist/transaction-types.mjs.map +1 -1
- package/dist/versions.cjs +95 -0
- package/dist/versions.cjs.map +1 -0
- package/dist/{types/versions.d.ts → versions.d.cts} +5 -5
- package/dist/versions.d.cts.map +1 -0
- package/dist/versions.d.mts +101 -0
- package/dist/versions.d.mts.map +1 -0
- package/dist/versions.mjs +85 -26
- package/dist/versions.mjs.map +1 -1
- package/package.json +28 -17
- package/dist/assert.js +0 -16
- package/dist/assert.js.map +0 -1
- package/dist/base64.js +0 -11
- package/dist/base64.js.map +0 -1
- package/dist/bytes.js +0 -43
- package/dist/bytes.js.map +0 -1
- package/dist/caip-types.js +0 -40
- package/dist/caip-types.js.map +0 -1
- package/dist/checksum.js +0 -12
- package/dist/checksum.js.map +0 -1
- package/dist/chunk-2LBGT4GH.js +0 -15
- package/dist/chunk-2LBGT4GH.js.map +0 -1
- package/dist/chunk-3W5G4CYI.js +0 -25
- package/dist/chunk-3W5G4CYI.js.map +0 -1
- package/dist/chunk-4D6XQBHA.js +0 -69
- package/dist/chunk-4D6XQBHA.js.map +0 -1
- package/dist/chunk-4NIRTM4M.js +0 -23
- package/dist/chunk-4NIRTM4M.js.map +0 -1
- package/dist/chunk-4RMX5YWE.js +0 -34
- package/dist/chunk-4RMX5YWE.js.map +0 -1
- package/dist/chunk-52OU772R.mjs +0 -122
- package/dist/chunk-52OU772R.mjs.map +0 -1
- package/dist/chunk-5AVWINSB.js +0 -1
- package/dist/chunk-5AVWINSB.js.map +0 -1
- package/dist/chunk-622IOGVI.mjs +0 -1
- package/dist/chunk-622IOGVI.mjs.map +0 -1
- package/dist/chunk-6C35XQOF.mjs +0 -257
- package/dist/chunk-6C35XQOF.mjs.map +0 -1
- package/dist/chunk-6NZW4WK4.js +0 -35
- package/dist/chunk-6NZW4WK4.js.map +0 -1
- package/dist/chunk-6ZDHSOUV.js +0 -59
- package/dist/chunk-6ZDHSOUV.js.map +0 -1
- package/dist/chunk-74DGVJVE.mjs +0 -59
- package/dist/chunk-74DGVJVE.mjs.map +0 -1
- package/dist/chunk-AY6FDCBT.mjs +0 -1
- package/dist/chunk-AY6FDCBT.mjs.map +0 -1
- package/dist/chunk-B7LIM2PK.mjs +0 -23
- package/dist/chunk-B7LIM2PK.mjs.map +0 -1
- package/dist/chunk-BFQDMI3M.js +0 -122
- package/dist/chunk-BFQDMI3M.js.map +0 -1
- package/dist/chunk-DHVKFDHQ.js +0 -95
- package/dist/chunk-DHVKFDHQ.js.map +0 -1
- package/dist/chunk-E4C7EW4R.js +0 -16
- package/dist/chunk-E4C7EW4R.js.map +0 -1
- package/dist/chunk-EQMZL4XU.js +0 -1
- package/dist/chunk-EQMZL4XU.js.map +0 -1
- package/dist/chunk-GZS3IQBZ.mjs +0 -16
- package/dist/chunk-GZS3IQBZ.mjs.map +0 -1
- package/dist/chunk-H4YFDLB7.mjs +0 -70
- package/dist/chunk-H4YFDLB7.mjs.map +0 -1
- package/dist/chunk-I575FZFH.mjs +0 -1
- package/dist/chunk-I575FZFH.mjs.map +0 -1
- package/dist/chunk-IZC266HS.js +0 -55
- package/dist/chunk-IZC266HS.js.map +0 -1
- package/dist/chunk-JPAL7Q5S.mjs +0 -90
- package/dist/chunk-JPAL7Q5S.mjs.map +0 -1
- package/dist/chunk-LC2CRSWD.js +0 -1
- package/dist/chunk-LC2CRSWD.js.map +0 -1
- package/dist/chunk-NQMRFZHB.mjs +0 -35
- package/dist/chunk-NQMRFZHB.mjs.map +0 -1
- package/dist/chunk-O3EIM33O.mjs +0 -95
- package/dist/chunk-O3EIM33O.mjs.map +0 -1
- package/dist/chunk-OLLG4H35.js +0 -257
- package/dist/chunk-OLLG4H35.js.map +0 -1
- package/dist/chunk-QEPVHEP7.js +0 -273
- package/dist/chunk-QVEKZRZ2.js +0 -70
- package/dist/chunk-QVEKZRZ2.js.map +0 -1
- package/dist/chunk-RIRDOQPX.mjs +0 -15
- package/dist/chunk-RIRDOQPX.mjs.map +0 -1
- package/dist/chunk-RKRGAFXY.js +0 -1
- package/dist/chunk-RKRGAFXY.js.map +0 -1
- package/dist/chunk-ROQSKDP5.mjs +0 -69
- package/dist/chunk-ROQSKDP5.mjs.map +0 -1
- package/dist/chunk-RRYOWRCV.mjs +0 -1
- package/dist/chunk-RRYOWRCV.mjs.map +0 -1
- package/dist/chunk-S3UHBN2Z.mjs +0 -44
- package/dist/chunk-S3UHBN2Z.mjs.map +0 -1
- package/dist/chunk-TGOMTREC.mjs +0 -75
- package/dist/chunk-TGOMTREC.mjs.map +0 -1
- package/dist/chunk-THNLGEXV.mjs +0 -34
- package/dist/chunk-THNLGEXV.mjs.map +0 -1
- package/dist/chunk-U7ZUGCE7.js +0 -75
- package/dist/chunk-U7ZUGCE7.js.map +0 -1
- package/dist/chunk-UOTVU7OQ.js +0 -1
- package/dist/chunk-UOTVU7OQ.js.map +0 -1
- package/dist/chunk-VA2DRBDE.mjs +0 -273
- package/dist/chunk-VA2DRBDE.mjs.map +0 -1
- package/dist/chunk-VFXTVNXN.js +0 -44
- package/dist/chunk-VFXTVNXN.js.map +0 -1
- package/dist/chunk-WA4DHIND.mjs +0 -1
- package/dist/chunk-WA4DHIND.mjs.map +0 -1
- package/dist/chunk-X66SUIEF.mjs +0 -25
- package/dist/chunk-X66SUIEF.mjs.map +0 -1
- package/dist/chunk-XYGUOY6N.mjs +0 -55
- package/dist/chunk-XYGUOY6N.mjs.map +0 -1
- package/dist/chunk-Z2RGWDD7.js +0 -90
- package/dist/chunk-Z2RGWDD7.js.map +0 -1
- package/dist/coercers.js +0 -18
- package/dist/coercers.js.map +0 -1
- package/dist/collections.js +0 -10
- package/dist/collections.js.map +0 -1
- package/dist/encryption-types.js +0 -2
- package/dist/encryption-types.js.map +0 -1
- package/dist/errors.js +0 -17
- package/dist/errors.js.map +0 -1
- package/dist/fs.js +0 -26
- package/dist/fs.js.map +0 -1
- package/dist/hex.js +0 -35
- package/dist/hex.js.map +0 -1
- package/dist/index.js +0 -293
- package/dist/index.js.map +0 -1
- package/dist/json.js +0 -75
- package/dist/json.js.map +0 -1
- package/dist/keyring.js +0 -2
- package/dist/keyring.js.map +0 -1
- package/dist/logging.js +0 -10
- package/dist/logging.js.map +0 -1
- package/dist/misc.js +0 -28
- package/dist/misc.js.map +0 -1
- package/dist/node.js +0 -313
- package/dist/node.js.map +0 -1
- package/dist/number.js +0 -18
- package/dist/number.js.map +0 -1
- package/dist/opaque.js +0 -2
- package/dist/opaque.js.map +0 -1
- package/dist/promise.js +0 -8
- package/dist/promise.js.map +0 -1
- package/dist/time.js +0 -12
- package/dist/time.js.map +0 -1
- package/dist/transaction-types.js +0 -2
- package/dist/transaction-types.js.map +0 -1
- package/dist/types/assert.d.ts.map +0 -1
- package/dist/types/base64.d.ts.map +0 -1
- package/dist/types/bytes.d.ts.map +0 -1
- package/dist/types/caip-types.d.ts.map +0 -1
- package/dist/types/checksum.d.ts +0 -2
- package/dist/types/checksum.d.ts.map +0 -1
- package/dist/types/coercers.d.ts.map +0 -1
- package/dist/types/collections.d.ts.map +0 -1
- package/dist/types/encryption-types.d.ts.map +0 -1
- package/dist/types/errors.d.ts.map +0 -1
- package/dist/types/fs.d.ts.map +0 -1
- package/dist/types/hex.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -21
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/json.d.ts.map +0 -1
- package/dist/types/keyring.d.ts.map +0 -1
- package/dist/types/logging.d.ts.map +0 -1
- package/dist/types/misc.d.ts.map +0 -1
- package/dist/types/node.d.ts +0 -3
- package/dist/types/node.d.ts.map +0 -1
- package/dist/types/number.d.ts.map +0 -1
- package/dist/types/opaque.d.ts +0 -6
- package/dist/types/opaque.d.ts.map +0 -1
- package/dist/types/promise.d.ts.map +0 -1
- package/dist/types/time.d.ts.map +0 -1
- package/dist/types/transaction-types.d.ts.map +0 -1
- package/dist/types/versions.d.ts.map +0 -1
- package/dist/versions.js +0 -27
- package/dist/versions.js.map +0 -1
package/dist/fs.cjs
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// This file is intended to be used only in a Node.js context.
|
|
3
|
+
/* eslint-disable import/no-nodejs-modules */
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
+
}) : function(o, v) {
|
|
18
|
+
o["default"] = v;
|
|
19
|
+
});
|
|
20
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
21
|
+
if (mod && mod.__esModule) return mod;
|
|
22
|
+
var result = {};
|
|
23
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
24
|
+
__setModuleDefault(result, mod);
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
27
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
28
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.createSandbox = exports.forceRemove = exports.ensureDirectoryStructureExists = exports.directoryExists = exports.fileExists = exports.writeJsonFile = exports.readJsonFile = exports.writeFile = exports.readFile = void 0;
|
|
32
|
+
const fs_1 = __importDefault(require("fs"));
|
|
33
|
+
const os_1 = __importDefault(require("os"));
|
|
34
|
+
const path_1 = __importDefault(require("path"));
|
|
35
|
+
const uuid = __importStar(require("uuid"));
|
|
36
|
+
const errors_1 = require("./errors.cjs");
|
|
37
|
+
/**
|
|
38
|
+
* Read the file at the given path, assuming its content is encoded as UTF-8.
|
|
39
|
+
*
|
|
40
|
+
* @param filePath - The path to the file.
|
|
41
|
+
* @returns The content of the file.
|
|
42
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
43
|
+
*/
|
|
44
|
+
async function readFile(filePath) {
|
|
45
|
+
try {
|
|
46
|
+
return await fs_1.default.promises.readFile(filePath, 'utf8');
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw (0, errors_1.wrapError)(error, `Could not read file '${filePath}'`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.readFile = readFile;
|
|
53
|
+
/**
|
|
54
|
+
* Write content to the file at the given path, creating the directory structure
|
|
55
|
+
* for the file automatically if necessary.
|
|
56
|
+
*
|
|
57
|
+
* @param filePath - The path to the file.
|
|
58
|
+
* @param content - The new content of the file.
|
|
59
|
+
* @throws An error with a stack trace if writing fails in any way.
|
|
60
|
+
*/
|
|
61
|
+
async function writeFile(filePath, content) {
|
|
62
|
+
try {
|
|
63
|
+
await fs_1.default.promises.mkdir(path_1.default.dirname(filePath), { recursive: true });
|
|
64
|
+
await fs_1.default.promises.writeFile(filePath, content);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
throw (0, errors_1.wrapError)(error, `Could not write file '${filePath}'`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.writeFile = writeFile;
|
|
71
|
+
/**
|
|
72
|
+
* Read the assumed JSON file at the given path, attempts to parse it, and
|
|
73
|
+
* get the resulting object. Supports a custom parser (in case you want to
|
|
74
|
+
* use the [JSON5](https://www.npmjs.com/package/json5) package instead).
|
|
75
|
+
*
|
|
76
|
+
* @param filePath - The path segments pointing to the JSON file. Will be passed
|
|
77
|
+
* to path.join().
|
|
78
|
+
* @param options - Options to this function.
|
|
79
|
+
* @param options.parser - The parser object to use. Defaults to `JSON`.
|
|
80
|
+
* @param options.parser.parse - A function that parses JSON data.
|
|
81
|
+
* @returns The object corresponding to the parsed JSON file, typed against the
|
|
82
|
+
* struct.
|
|
83
|
+
* @throws An error with a stack trace if reading fails in any way, or if the
|
|
84
|
+
* parsed value is not a plain object.
|
|
85
|
+
*/
|
|
86
|
+
async function readJsonFile(filePath, { parser = JSON, } = {}) {
|
|
87
|
+
try {
|
|
88
|
+
const content = await fs_1.default.promises.readFile(filePath, 'utf8');
|
|
89
|
+
return parser.parse(content);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
throw (0, errors_1.wrapError)(error, `Could not read JSON file '${filePath}'`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.readJsonFile = readJsonFile;
|
|
96
|
+
/**
|
|
97
|
+
* Attempt to write the given JSON-like value to the file at the given path,
|
|
98
|
+
* creating the directory structure for the file automatically if necessary.
|
|
99
|
+
* Adds a newline to the end of the file. Supports a custom parser (in case you
|
|
100
|
+
* want to use the [JSON5](https://www.npmjs.com/package/json5) package
|
|
101
|
+
* instead).
|
|
102
|
+
*
|
|
103
|
+
* @param filePath - The path to write the JSON file to, including the file
|
|
104
|
+
* itself.
|
|
105
|
+
* @param jsonValue - The JSON-like value to write to the file. Make sure that
|
|
106
|
+
* JSON.stringify can handle it.
|
|
107
|
+
* @param options - The options to this function.
|
|
108
|
+
* @param options.prettify - Whether to format the JSON as it is turned into a
|
|
109
|
+
* string such that it is broken up into separate lines (using 2 spaces as
|
|
110
|
+
* indentation).
|
|
111
|
+
* @param options.stringifier - The stringifier to use. Defaults to `JSON`.
|
|
112
|
+
* @param options.stringifier.stringify - A function that stringifies JSON.
|
|
113
|
+
* @returns The object corresponding to the parsed JSON file, typed against the
|
|
114
|
+
* struct.
|
|
115
|
+
* @throws An error with a stack trace if writing fails in any way.
|
|
116
|
+
*/
|
|
117
|
+
async function writeJsonFile(filePath, jsonValue, { stringifier = JSON, prettify = false, } = {}) {
|
|
118
|
+
try {
|
|
119
|
+
await fs_1.default.promises.mkdir(path_1.default.dirname(filePath), { recursive: true });
|
|
120
|
+
const json = prettify
|
|
121
|
+
? stringifier.stringify(jsonValue, null, ' ')
|
|
122
|
+
: stringifier.stringify(jsonValue);
|
|
123
|
+
await fs_1.default.promises.writeFile(filePath, json);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
throw (0, errors_1.wrapError)(error, `Could not write JSON file '${filePath}'`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.writeJsonFile = writeJsonFile;
|
|
130
|
+
/**
|
|
131
|
+
* Test the given path to determine whether it represents a file.
|
|
132
|
+
*
|
|
133
|
+
* @param filePath - The path to a (supposed) file on the filesystem.
|
|
134
|
+
* @returns A promise for true if the file exists or false otherwise.
|
|
135
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
136
|
+
*/
|
|
137
|
+
async function fileExists(filePath) {
|
|
138
|
+
try {
|
|
139
|
+
const stats = await fs_1.default.promises.stat(filePath);
|
|
140
|
+
return stats.isFile();
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if ((0, errors_1.isErrorWithCode)(error) && error.code === 'ENOENT') {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
throw (0, errors_1.wrapError)(error, `Could not determine if file exists '${filePath}'`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
exports.fileExists = fileExists;
|
|
150
|
+
/**
|
|
151
|
+
* Test the given path to determine whether it represents a directory.
|
|
152
|
+
*
|
|
153
|
+
* @param directoryPath - The path to a (supposed) directory on the filesystem.
|
|
154
|
+
* @returns A promise for true if the file exists or false otherwise.
|
|
155
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
156
|
+
*/
|
|
157
|
+
async function directoryExists(directoryPath) {
|
|
158
|
+
try {
|
|
159
|
+
const stats = await fs_1.default.promises.stat(directoryPath);
|
|
160
|
+
return stats.isDirectory();
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if ((0, errors_1.isErrorWithCode)(error) && error.code === 'ENOENT') {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
throw (0, errors_1.wrapError)(error, `Could not determine if directory exists '${directoryPath}'`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.directoryExists = directoryExists;
|
|
170
|
+
/**
|
|
171
|
+
* Create the given directory along with any directories leading up to the
|
|
172
|
+
* directory, or do nothing if the directory already exists.
|
|
173
|
+
*
|
|
174
|
+
* @param directoryPath - The path to the desired directory.
|
|
175
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
176
|
+
*/
|
|
177
|
+
async function ensureDirectoryStructureExists(directoryPath) {
|
|
178
|
+
try {
|
|
179
|
+
await fs_1.default.promises.mkdir(directoryPath, { recursive: true });
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
throw (0, errors_1.wrapError)(error, `Could not create directory structure '${directoryPath}'`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.ensureDirectoryStructureExists = ensureDirectoryStructureExists;
|
|
186
|
+
/**
|
|
187
|
+
* Remove the given file or directory if it exists, or do nothing if it does
|
|
188
|
+
* not.
|
|
189
|
+
*
|
|
190
|
+
* @param entryPath - The path to the file or directory.
|
|
191
|
+
* @throws An error with a stack trace if removal fails in any way.
|
|
192
|
+
*/
|
|
193
|
+
async function forceRemove(entryPath) {
|
|
194
|
+
try {
|
|
195
|
+
return await fs_1.default.promises.rm(entryPath, {
|
|
196
|
+
recursive: true,
|
|
197
|
+
force: true,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
throw (0, errors_1.wrapError)(error, `Could not remove file or directory '${entryPath}'`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.forceRemove = forceRemove;
|
|
205
|
+
/**
|
|
206
|
+
* Construct a sandbox object which can be used in tests that need temporary
|
|
207
|
+
* access to the filesystem.
|
|
208
|
+
*
|
|
209
|
+
* @param projectName - The name of the project.
|
|
210
|
+
* @returns The sandbox object. This contains a `withinSandbox` function which
|
|
211
|
+
* can be used in tests (see example).
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const { withinSandbox } = createSandbox('utils');
|
|
215
|
+
*
|
|
216
|
+
* // ... later ...
|
|
217
|
+
*
|
|
218
|
+
* it('does something with the filesystem', async () => {
|
|
219
|
+
* await withinSandbox(async ({ directoryPath }) => {
|
|
220
|
+
* await fs.promises.writeFile(
|
|
221
|
+
* path.join(directoryPath, 'some-file'),
|
|
222
|
+
* 'some content',
|
|
223
|
+
* 'utf8'
|
|
224
|
+
* );
|
|
225
|
+
* })
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
function createSandbox(projectName) {
|
|
230
|
+
const directoryPath = path_1.default.join(os_1.default.tmpdir(), projectName, uuid.v4());
|
|
231
|
+
return {
|
|
232
|
+
directoryPath,
|
|
233
|
+
async withinSandbox(test) {
|
|
234
|
+
if (await directoryExists(directoryPath)) {
|
|
235
|
+
throw new Error(`${directoryPath} already exists. Cannot continue.`);
|
|
236
|
+
}
|
|
237
|
+
await ensureDirectoryStructureExists(directoryPath);
|
|
238
|
+
try {
|
|
239
|
+
await test({ directoryPath });
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
await forceRemove(directoryPath);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
exports.createSandbox = createSandbox;
|
|
248
|
+
//# sourceMappingURL=fs.cjs.map
|
package/dist/fs.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.cjs","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"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","sourcesContent":["// This file is intended to be used only in a Node.js context.\n/* eslint-disable import/no-nodejs-modules */\n\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport * as uuid from 'uuid';\n\nimport { isErrorWithCode, wrapError } from './errors';\nimport type { Json } from './json';\n\n/**\n * Information about the file sandbox provided to tests that need temporary\n * access to the filesystem.\n */\nexport type FileSandbox = {\n directoryPath: string;\n withinSandbox: (\n test: (args: { directoryPath: string }) => Promise<void>,\n ) => Promise<void>;\n};\n\n/**\n * Read the file at the given path, assuming its content is encoded as UTF-8.\n *\n * @param filePath - The path to the file.\n * @returns The content of the file.\n * @throws An error with a stack trace if reading fails in any way.\n */\nexport async function readFile(filePath: string): Promise<string> {\n try {\n return await fs.promises.readFile(filePath, 'utf8');\n } catch (error) {\n throw wrapError(error, `Could not read file '${filePath}'`);\n }\n}\n\n/**\n * Write content to the file at the given path, creating the directory structure\n * for the file automatically if necessary.\n *\n * @param filePath - The path to the file.\n * @param content - The new content of the file.\n * @throws An error with a stack trace if writing fails in any way.\n */\nexport async function writeFile(\n filePath: string,\n content: string,\n): Promise<void> {\n try {\n await fs.promises.mkdir(path.dirname(filePath), { recursive: true });\n await fs.promises.writeFile(filePath, content);\n } catch (error) {\n throw wrapError(error, `Could not write file '${filePath}'`);\n }\n}\n\n/**\n * Read the assumed JSON file at the given path, attempts to parse it, and\n * get the resulting object. Supports a custom parser (in case you want to\n * use the [JSON5](https://www.npmjs.com/package/json5) package instead).\n *\n * @param filePath - The path segments pointing to the JSON file. Will be passed\n * to path.join().\n * @param options - Options to this function.\n * @param options.parser - The parser object to use. Defaults to `JSON`.\n * @param options.parser.parse - A function that parses JSON data.\n * @returns The object corresponding to the parsed JSON file, typed against the\n * struct.\n * @throws An error with a stack trace if reading fails in any way, or if the\n * parsed value is not a plain object.\n */\nexport async function readJsonFile<Value extends Json>(\n filePath: string,\n {\n parser = JSON,\n }: {\n parser?: {\n parse: (\n text: Parameters<typeof JSON.parse>[0],\n ) => ReturnType<typeof JSON.parse>;\n };\n } = {},\n): Promise<Value> {\n try {\n const content = await fs.promises.readFile(filePath, 'utf8');\n return parser.parse(content);\n } catch (error) {\n throw wrapError(error, `Could not read JSON file '${filePath}'`);\n }\n}\n\n/**\n * Attempt to write the given JSON-like value to the file at the given path,\n * creating the directory structure for the file automatically if necessary.\n * Adds a newline to the end of the file. Supports a custom parser (in case you\n * want to use the [JSON5](https://www.npmjs.com/package/json5) package\n * instead).\n *\n * @param filePath - The path to write the JSON file to, including the file\n * itself.\n * @param jsonValue - The JSON-like value to write to the file. Make sure that\n * JSON.stringify can handle it.\n * @param options - The options to this function.\n * @param options.prettify - Whether to format the JSON as it is turned into a\n * string such that it is broken up into separate lines (using 2 spaces as\n * indentation).\n * @param options.stringifier - The stringifier to use. Defaults to `JSON`.\n * @param options.stringifier.stringify - A function that stringifies JSON.\n * @returns The object corresponding to the parsed JSON file, typed against the\n * struct.\n * @throws An error with a stack trace if writing fails in any way.\n */\nexport async function writeJsonFile(\n filePath: string,\n jsonValue: Json,\n {\n stringifier = JSON,\n prettify = false,\n }: {\n stringifier?: {\n stringify: typeof JSON.stringify;\n };\n prettify?: boolean;\n } = {},\n): Promise<void> {\n try {\n await fs.promises.mkdir(path.dirname(filePath), { recursive: true });\n const json = prettify\n ? stringifier.stringify(jsonValue, null, ' ')\n : stringifier.stringify(jsonValue);\n await fs.promises.writeFile(filePath, json);\n } catch (error) {\n throw wrapError(error, `Could not write JSON file '${filePath}'`);\n }\n}\n\n/**\n * Test the given path to determine whether it represents a file.\n *\n * @param filePath - The path to a (supposed) file on the filesystem.\n * @returns A promise for true if the file exists or false otherwise.\n * @throws An error with a stack trace if reading fails in any way.\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const stats = await fs.promises.stat(filePath);\n return stats.isFile();\n } catch (error) {\n if (isErrorWithCode(error) && error.code === 'ENOENT') {\n return false;\n }\n\n throw wrapError(error, `Could not determine if file exists '${filePath}'`);\n }\n}\n\n/**\n * Test the given path to determine whether it represents a directory.\n *\n * @param directoryPath - The path to a (supposed) directory on the filesystem.\n * @returns A promise for true if the file exists or false otherwise.\n * @throws An error with a stack trace if reading fails in any way.\n */\nexport async function directoryExists(directoryPath: string): Promise<boolean> {\n try {\n const stats = await fs.promises.stat(directoryPath);\n return stats.isDirectory();\n } catch (error) {\n if (isErrorWithCode(error) && error.code === 'ENOENT') {\n return false;\n }\n\n throw wrapError(\n error,\n `Could not determine if directory exists '${directoryPath}'`,\n );\n }\n}\n\n/**\n * Create the given directory along with any directories leading up to the\n * directory, or do nothing if the directory already exists.\n *\n * @param directoryPath - The path to the desired directory.\n * @throws An error with a stack trace if reading fails in any way.\n */\nexport async function ensureDirectoryStructureExists(\n directoryPath: string,\n): Promise<void> {\n try {\n await fs.promises.mkdir(directoryPath, { recursive: true });\n } catch (error) {\n throw wrapError(\n error,\n `Could not create directory structure '${directoryPath}'`,\n );\n }\n}\n\n/**\n * Remove the given file or directory if it exists, or do nothing if it does\n * not.\n *\n * @param entryPath - The path to the file or directory.\n * @throws An error with a stack trace if removal fails in any way.\n */\nexport async function forceRemove(entryPath: string): Promise<void> {\n try {\n return await fs.promises.rm(entryPath, {\n recursive: true,\n force: true,\n });\n } catch (error) {\n throw wrapError(error, `Could not remove file or directory '${entryPath}'`);\n }\n}\n\n/**\n * Construct a sandbox object which can be used in tests that need temporary\n * access to the filesystem.\n *\n * @param projectName - The name of the project.\n * @returns The sandbox object. This contains a `withinSandbox` function which\n * can be used in tests (see example).\n * @example\n * ```typescript\n * const { withinSandbox } = createSandbox('utils');\n *\n * // ... later ...\n *\n * it('does something with the filesystem', async () => {\n * await withinSandbox(async ({ directoryPath }) => {\n * await fs.promises.writeFile(\n * path.join(directoryPath, 'some-file'),\n * 'some content',\n * 'utf8'\n * );\n * })\n * });\n * ```\n */\nexport function createSandbox(projectName: string): FileSandbox {\n const directoryPath = path.join(os.tmpdir(), projectName, uuid.v4());\n\n return {\n directoryPath,\n async withinSandbox(\n test: (args: { directoryPath: string }) => Promise<void>,\n ) {\n if (await directoryExists(directoryPath)) {\n throw new Error(`${directoryPath} already exists. Cannot continue.`);\n }\n\n await ensureDirectoryStructureExists(directoryPath);\n\n try {\n await test({ directoryPath });\n } finally {\n await forceRemove(directoryPath);\n }\n },\n };\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Json } from
|
|
1
|
+
import type { Json } from "./json.cjs";
|
|
2
2
|
/**
|
|
3
3
|
* Information about the file sandbox provided to tests that need temporary
|
|
4
4
|
* access to the filesystem.
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
6
|
+
export type FileSandbox = {
|
|
7
7
|
directoryPath: string;
|
|
8
8
|
withinSandbox: (test: (args: {
|
|
9
9
|
directoryPath: string;
|
|
@@ -130,4 +130,4 @@ export declare function forceRemove(entryPath: string): Promise<void>;
|
|
|
130
130
|
* ```
|
|
131
131
|
*/
|
|
132
132
|
export declare function createSandbox(projectName: string): FileSandbox;
|
|
133
|
-
//# sourceMappingURL=fs.d.
|
|
133
|
+
//# sourceMappingURL=fs.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.d.cts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAE,mBAAe;AAEnC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CACb,IAAI,EAAE,CAAC,IAAI,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KACrD,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMhE;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAAC,KAAK,SAAS,IAAI,EACnD,QAAQ,EAAE,MAAM,EAChB,EACE,MAAa,GACd,GAAE;IACD,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,CACL,IAAI,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KACnC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;KACpC,CAAC;CACE,GACL,OAAO,CAAC,KAAK,CAAC,CAOhB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,IAAI,EACf,EACE,WAAkB,EAClB,QAAgB,GACjB,GAAE;IACD,WAAW,CAAC,EAAE;QACZ,SAAS,EAAE,OAAO,IAAI,CAAC,SAAS,CAAC;KAClC,CAAC;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACf,GACL,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnE;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAc7E;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASlE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAqB9D"}
|
package/dist/fs.d.mts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { Json } from "./json.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* Information about the file sandbox provided to tests that need temporary
|
|
4
|
+
* access to the filesystem.
|
|
5
|
+
*/
|
|
6
|
+
export type FileSandbox = {
|
|
7
|
+
directoryPath: string;
|
|
8
|
+
withinSandbox: (test: (args: {
|
|
9
|
+
directoryPath: string;
|
|
10
|
+
}) => Promise<void>) => Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Read the file at the given path, assuming its content is encoded as UTF-8.
|
|
14
|
+
*
|
|
15
|
+
* @param filePath - The path to the file.
|
|
16
|
+
* @returns The content of the file.
|
|
17
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readFile(filePath: string): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Write content to the file at the given path, creating the directory structure
|
|
22
|
+
* for the file automatically if necessary.
|
|
23
|
+
*
|
|
24
|
+
* @param filePath - The path to the file.
|
|
25
|
+
* @param content - The new content of the file.
|
|
26
|
+
* @throws An error with a stack trace if writing fails in any way.
|
|
27
|
+
*/
|
|
28
|
+
export declare function writeFile(filePath: string, content: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Read the assumed JSON file at the given path, attempts to parse it, and
|
|
31
|
+
* get the resulting object. Supports a custom parser (in case you want to
|
|
32
|
+
* use the [JSON5](https://www.npmjs.com/package/json5) package instead).
|
|
33
|
+
*
|
|
34
|
+
* @param filePath - The path segments pointing to the JSON file. Will be passed
|
|
35
|
+
* to path.join().
|
|
36
|
+
* @param options - Options to this function.
|
|
37
|
+
* @param options.parser - The parser object to use. Defaults to `JSON`.
|
|
38
|
+
* @param options.parser.parse - A function that parses JSON data.
|
|
39
|
+
* @returns The object corresponding to the parsed JSON file, typed against the
|
|
40
|
+
* struct.
|
|
41
|
+
* @throws An error with a stack trace if reading fails in any way, or if the
|
|
42
|
+
* parsed value is not a plain object.
|
|
43
|
+
*/
|
|
44
|
+
export declare function readJsonFile<Value extends Json>(filePath: string, { parser, }?: {
|
|
45
|
+
parser?: {
|
|
46
|
+
parse: (text: Parameters<typeof JSON.parse>[0]) => ReturnType<typeof JSON.parse>;
|
|
47
|
+
};
|
|
48
|
+
}): Promise<Value>;
|
|
49
|
+
/**
|
|
50
|
+
* Attempt to write the given JSON-like value to the file at the given path,
|
|
51
|
+
* creating the directory structure for the file automatically if necessary.
|
|
52
|
+
* Adds a newline to the end of the file. Supports a custom parser (in case you
|
|
53
|
+
* want to use the [JSON5](https://www.npmjs.com/package/json5) package
|
|
54
|
+
* instead).
|
|
55
|
+
*
|
|
56
|
+
* @param filePath - The path to write the JSON file to, including the file
|
|
57
|
+
* itself.
|
|
58
|
+
* @param jsonValue - The JSON-like value to write to the file. Make sure that
|
|
59
|
+
* JSON.stringify can handle it.
|
|
60
|
+
* @param options - The options to this function.
|
|
61
|
+
* @param options.prettify - Whether to format the JSON as it is turned into a
|
|
62
|
+
* string such that it is broken up into separate lines (using 2 spaces as
|
|
63
|
+
* indentation).
|
|
64
|
+
* @param options.stringifier - The stringifier to use. Defaults to `JSON`.
|
|
65
|
+
* @param options.stringifier.stringify - A function that stringifies JSON.
|
|
66
|
+
* @returns The object corresponding to the parsed JSON file, typed against the
|
|
67
|
+
* struct.
|
|
68
|
+
* @throws An error with a stack trace if writing fails in any way.
|
|
69
|
+
*/
|
|
70
|
+
export declare function writeJsonFile(filePath: string, jsonValue: Json, { stringifier, prettify, }?: {
|
|
71
|
+
stringifier?: {
|
|
72
|
+
stringify: typeof JSON.stringify;
|
|
73
|
+
};
|
|
74
|
+
prettify?: boolean;
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Test the given path to determine whether it represents a file.
|
|
78
|
+
*
|
|
79
|
+
* @param filePath - The path to a (supposed) file on the filesystem.
|
|
80
|
+
* @returns A promise for true if the file exists or false otherwise.
|
|
81
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
82
|
+
*/
|
|
83
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* Test the given path to determine whether it represents a directory.
|
|
86
|
+
*
|
|
87
|
+
* @param directoryPath - The path to a (supposed) directory on the filesystem.
|
|
88
|
+
* @returns A promise for true if the file exists or false otherwise.
|
|
89
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
90
|
+
*/
|
|
91
|
+
export declare function directoryExists(directoryPath: string): Promise<boolean>;
|
|
92
|
+
/**
|
|
93
|
+
* Create the given directory along with any directories leading up to the
|
|
94
|
+
* directory, or do nothing if the directory already exists.
|
|
95
|
+
*
|
|
96
|
+
* @param directoryPath - The path to the desired directory.
|
|
97
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
98
|
+
*/
|
|
99
|
+
export declare function ensureDirectoryStructureExists(directoryPath: string): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Remove the given file or directory if it exists, or do nothing if it does
|
|
102
|
+
* not.
|
|
103
|
+
*
|
|
104
|
+
* @param entryPath - The path to the file or directory.
|
|
105
|
+
* @throws An error with a stack trace if removal fails in any way.
|
|
106
|
+
*/
|
|
107
|
+
export declare function forceRemove(entryPath: string): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Construct a sandbox object which can be used in tests that need temporary
|
|
110
|
+
* access to the filesystem.
|
|
111
|
+
*
|
|
112
|
+
* @param projectName - The name of the project.
|
|
113
|
+
* @returns The sandbox object. This contains a `withinSandbox` function which
|
|
114
|
+
* can be used in tests (see example).
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const { withinSandbox } = createSandbox('utils');
|
|
118
|
+
*
|
|
119
|
+
* // ... later ...
|
|
120
|
+
*
|
|
121
|
+
* it('does something with the filesystem', async () => {
|
|
122
|
+
* await withinSandbox(async ({ directoryPath }) => {
|
|
123
|
+
* await fs.promises.writeFile(
|
|
124
|
+
* path.join(directoryPath, 'some-file'),
|
|
125
|
+
* 'some content',
|
|
126
|
+
* 'utf8'
|
|
127
|
+
* );
|
|
128
|
+
* })
|
|
129
|
+
* });
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export declare function createSandbox(projectName: string): FileSandbox;
|
|
133
|
+
//# sourceMappingURL=fs.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.d.mts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAE,mBAAe;AAEnC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CACb,IAAI,EAAE,CAAC,IAAI,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KACrD,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMhE;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAAC,KAAK,SAAS,IAAI,EACnD,QAAQ,EAAE,MAAM,EAChB,EACE,MAAa,GACd,GAAE;IACD,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,CACL,IAAI,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KACnC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;KACpC,CAAC;CACE,GACL,OAAO,CAAC,KAAK,CAAC,CAOhB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,IAAI,EACf,EACE,WAAkB,EAClB,QAAgB,GACjB,GAAE;IACD,WAAW,CAAC,EAAE;QACZ,SAAS,EAAE,OAAO,IAAI,CAAC,SAAS,CAAC;KAClC,CAAC;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACf,GACL,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnE;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAc7E;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASlE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAqB9D"}
|
package/dist/fs.mjs
CHANGED
|
@@ -1,26 +1,210 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
// This file is intended to be used only in a Node.js context.
|
|
2
|
+
/* eslint-disable import/no-nodejs-modules */
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import os from "os";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import * as uuid from "uuid";
|
|
7
|
+
import { isErrorWithCode, wrapError } from "./errors.mjs";
|
|
8
|
+
/**
|
|
9
|
+
* Read the file at the given path, assuming its content is encoded as UTF-8.
|
|
10
|
+
*
|
|
11
|
+
* @param filePath - The path to the file.
|
|
12
|
+
* @returns The content of the file.
|
|
13
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
14
|
+
*/
|
|
15
|
+
export async function readFile(filePath) {
|
|
16
|
+
try {
|
|
17
|
+
return await fs.promises.readFile(filePath, 'utf8');
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
throw wrapError(error, `Could not read file '${filePath}'`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Write content to the file at the given path, creating the directory structure
|
|
25
|
+
* for the file automatically if necessary.
|
|
26
|
+
*
|
|
27
|
+
* @param filePath - The path to the file.
|
|
28
|
+
* @param content - The new content of the file.
|
|
29
|
+
* @throws An error with a stack trace if writing fails in any way.
|
|
30
|
+
*/
|
|
31
|
+
export async function writeFile(filePath, content) {
|
|
32
|
+
try {
|
|
33
|
+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
34
|
+
await fs.promises.writeFile(filePath, content);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw wrapError(error, `Could not write file '${filePath}'`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Read the assumed JSON file at the given path, attempts to parse it, and
|
|
42
|
+
* get the resulting object. Supports a custom parser (in case you want to
|
|
43
|
+
* use the [JSON5](https://www.npmjs.com/package/json5) package instead).
|
|
44
|
+
*
|
|
45
|
+
* @param filePath - The path segments pointing to the JSON file. Will be passed
|
|
46
|
+
* to path.join().
|
|
47
|
+
* @param options - Options to this function.
|
|
48
|
+
* @param options.parser - The parser object to use. Defaults to `JSON`.
|
|
49
|
+
* @param options.parser.parse - A function that parses JSON data.
|
|
50
|
+
* @returns The object corresponding to the parsed JSON file, typed against the
|
|
51
|
+
* struct.
|
|
52
|
+
* @throws An error with a stack trace if reading fails in any way, or if the
|
|
53
|
+
* parsed value is not a plain object.
|
|
54
|
+
*/
|
|
55
|
+
export async function readJsonFile(filePath, { parser = JSON, } = {}) {
|
|
56
|
+
try {
|
|
57
|
+
const content = await fs.promises.readFile(filePath, 'utf8');
|
|
58
|
+
return parser.parse(content);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw wrapError(error, `Could not read JSON file '${filePath}'`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Attempt to write the given JSON-like value to the file at the given path,
|
|
66
|
+
* creating the directory structure for the file automatically if necessary.
|
|
67
|
+
* Adds a newline to the end of the file. Supports a custom parser (in case you
|
|
68
|
+
* want to use the [JSON5](https://www.npmjs.com/package/json5) package
|
|
69
|
+
* instead).
|
|
70
|
+
*
|
|
71
|
+
* @param filePath - The path to write the JSON file to, including the file
|
|
72
|
+
* itself.
|
|
73
|
+
* @param jsonValue - The JSON-like value to write to the file. Make sure that
|
|
74
|
+
* JSON.stringify can handle it.
|
|
75
|
+
* @param options - The options to this function.
|
|
76
|
+
* @param options.prettify - Whether to format the JSON as it is turned into a
|
|
77
|
+
* string such that it is broken up into separate lines (using 2 spaces as
|
|
78
|
+
* indentation).
|
|
79
|
+
* @param options.stringifier - The stringifier to use. Defaults to `JSON`.
|
|
80
|
+
* @param options.stringifier.stringify - A function that stringifies JSON.
|
|
81
|
+
* @returns The object corresponding to the parsed JSON file, typed against the
|
|
82
|
+
* struct.
|
|
83
|
+
* @throws An error with a stack trace if writing fails in any way.
|
|
84
|
+
*/
|
|
85
|
+
export async function writeJsonFile(filePath, jsonValue, { stringifier = JSON, prettify = false, } = {}) {
|
|
86
|
+
try {
|
|
87
|
+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
88
|
+
const json = prettify
|
|
89
|
+
? stringifier.stringify(jsonValue, null, ' ')
|
|
90
|
+
: stringifier.stringify(jsonValue);
|
|
91
|
+
await fs.promises.writeFile(filePath, json);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
throw wrapError(error, `Could not write JSON file '${filePath}'`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Test the given path to determine whether it represents a file.
|
|
99
|
+
*
|
|
100
|
+
* @param filePath - The path to a (supposed) file on the filesystem.
|
|
101
|
+
* @returns A promise for true if the file exists or false otherwise.
|
|
102
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
103
|
+
*/
|
|
104
|
+
export async function fileExists(filePath) {
|
|
105
|
+
try {
|
|
106
|
+
const stats = await fs.promises.stat(filePath);
|
|
107
|
+
return stats.isFile();
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (isErrorWithCode(error) && error.code === 'ENOENT') {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
throw wrapError(error, `Could not determine if file exists '${filePath}'`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Test the given path to determine whether it represents a directory.
|
|
118
|
+
*
|
|
119
|
+
* @param directoryPath - The path to a (supposed) directory on the filesystem.
|
|
120
|
+
* @returns A promise for true if the file exists or false otherwise.
|
|
121
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
122
|
+
*/
|
|
123
|
+
export async function directoryExists(directoryPath) {
|
|
124
|
+
try {
|
|
125
|
+
const stats = await fs.promises.stat(directoryPath);
|
|
126
|
+
return stats.isDirectory();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (isErrorWithCode(error) && error.code === 'ENOENT') {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
throw wrapError(error, `Could not determine if directory exists '${directoryPath}'`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create the given directory along with any directories leading up to the
|
|
137
|
+
* directory, or do nothing if the directory already exists.
|
|
138
|
+
*
|
|
139
|
+
* @param directoryPath - The path to the desired directory.
|
|
140
|
+
* @throws An error with a stack trace if reading fails in any way.
|
|
141
|
+
*/
|
|
142
|
+
export async function ensureDirectoryStructureExists(directoryPath) {
|
|
143
|
+
try {
|
|
144
|
+
await fs.promises.mkdir(directoryPath, { recursive: true });
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
throw wrapError(error, `Could not create directory structure '${directoryPath}'`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Remove the given file or directory if it exists, or do nothing if it does
|
|
152
|
+
* not.
|
|
153
|
+
*
|
|
154
|
+
* @param entryPath - The path to the file or directory.
|
|
155
|
+
* @throws An error with a stack trace if removal fails in any way.
|
|
156
|
+
*/
|
|
157
|
+
export async function forceRemove(entryPath) {
|
|
158
|
+
try {
|
|
159
|
+
return await fs.promises.rm(entryPath, {
|
|
160
|
+
recursive: true,
|
|
161
|
+
force: true,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
throw wrapError(error, `Could not remove file or directory '${entryPath}'`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Construct a sandbox object which can be used in tests that need temporary
|
|
170
|
+
* access to the filesystem.
|
|
171
|
+
*
|
|
172
|
+
* @param projectName - The name of the project.
|
|
173
|
+
* @returns The sandbox object. This contains a `withinSandbox` function which
|
|
174
|
+
* can be used in tests (see example).
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const { withinSandbox } = createSandbox('utils');
|
|
178
|
+
*
|
|
179
|
+
* // ... later ...
|
|
180
|
+
*
|
|
181
|
+
* it('does something with the filesystem', async () => {
|
|
182
|
+
* await withinSandbox(async ({ directoryPath }) => {
|
|
183
|
+
* await fs.promises.writeFile(
|
|
184
|
+
* path.join(directoryPath, 'some-file'),
|
|
185
|
+
* 'some content',
|
|
186
|
+
* 'utf8'
|
|
187
|
+
* );
|
|
188
|
+
* })
|
|
189
|
+
* });
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
export function createSandbox(projectName) {
|
|
193
|
+
const directoryPath = path.join(os.tmpdir(), projectName, uuid.v4());
|
|
194
|
+
return {
|
|
195
|
+
directoryPath,
|
|
196
|
+
async withinSandbox(test) {
|
|
197
|
+
if (await directoryExists(directoryPath)) {
|
|
198
|
+
throw new Error(`${directoryPath} already exists. Cannot continue.`);
|
|
199
|
+
}
|
|
200
|
+
await ensureDirectoryStructureExists(directoryPath);
|
|
201
|
+
try {
|
|
202
|
+
await test({ directoryPath });
|
|
203
|
+
}
|
|
204
|
+
finally {
|
|
205
|
+
await forceRemove(directoryPath);
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
26
210
|
//# sourceMappingURL=fs.mjs.map
|