@thi.ng/file-io 1.0.4 → 1.0.5
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 +1 -1
- package/delete.js +8 -14
- package/dir.js +8 -21
- package/ext.js +6 -8
- package/file-chunks.js +34 -44
- package/files.js +35 -71
- package/hash.js +16 -12
- package/json.js +11 -17
- package/mask.js +4 -8
- package/package.json +11 -8
- package/read.js +7 -10
- package/temp.js +11 -7
- package/text.js +14 -22
- package/write.js +9 -17
package/CHANGELOG.md
CHANGED
package/delete.js
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { unlinkSync } from "fs";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
export const deleteFile = (path, logger, dryRun = false) => {
|
|
12
|
-
logger && logger.info(`${dryRun ? "[dryrun] " : ""}deleting file: ${path}`);
|
|
13
|
-
if (dryRun)
|
|
14
|
-
return;
|
|
15
|
-
unlinkSync(path);
|
|
2
|
+
const deleteFile = (path, logger, dryRun = false) => {
|
|
3
|
+
logger && logger.info(`${dryRun ? "[dryrun] " : ""}deleting file: ${path}`);
|
|
4
|
+
if (dryRun)
|
|
5
|
+
return;
|
|
6
|
+
unlinkSync(path);
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
deleteFile
|
|
16
10
|
};
|
package/dir.js
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, statSync } from "fs";
|
|
2
2
|
import { sep } from "path";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* @param path
|
|
12
|
-
*/
|
|
13
|
-
export const ensureDirForFile = (path) => {
|
|
14
|
-
const dir = path.substring(0, path.lastIndexOf(sep));
|
|
15
|
-
return dir.length > 0 && !existsSync(dir)
|
|
16
|
-
? (mkdirSync(dir, { recursive: true }), true)
|
|
17
|
-
: false;
|
|
3
|
+
const ensureDirForFile = (path) => {
|
|
4
|
+
const dir = path.substring(0, path.lastIndexOf(sep));
|
|
5
|
+
return dir.length > 0 && !existsSync(dir) ? (mkdirSync(dir, { recursive: true }), true) : false;
|
|
6
|
+
};
|
|
7
|
+
const isDirectory = (path) => statSync(path).isDirectory();
|
|
8
|
+
export {
|
|
9
|
+
ensureDirForFile,
|
|
10
|
+
isDirectory
|
|
18
11
|
};
|
|
19
|
-
/**
|
|
20
|
-
* Returns true if `path` is a directory (assumes path exists).
|
|
21
|
-
*
|
|
22
|
-
* @param path
|
|
23
|
-
*/
|
|
24
|
-
export const isDirectory = (path) => statSync(path).isDirectory();
|
package/ext.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const match = /\.(\w+)$/.exec(path);
|
|
8
|
-
return match ? match[1].toLowerCase() : "";
|
|
1
|
+
const fileExt = (path) => {
|
|
2
|
+
const match = /\.(\w+)$/.exec(path);
|
|
3
|
+
return match ? match[1].toLowerCase() : "";
|
|
4
|
+
};
|
|
5
|
+
export {
|
|
6
|
+
fileExt
|
|
9
7
|
};
|
package/file-chunks.js
CHANGED
|
@@ -1,48 +1,38 @@
|
|
|
1
1
|
import { U32 } from "@thi.ng/hex";
|
|
2
2
|
import { open } from "fs/promises";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
logger.debug(`reading chunk: 0x${U32(start)} - 0x${U32(start + size - 1)} (${path})`);
|
|
32
|
-
const { buffer, bytesRead } = await fd.read({
|
|
33
|
-
buffer: Buffer.alloc(size),
|
|
34
|
-
length: size,
|
|
35
|
-
position: start,
|
|
36
|
-
});
|
|
37
|
-
if (bytesRead === 0)
|
|
38
|
-
break;
|
|
39
|
-
yield buffer;
|
|
40
|
-
if (bytesRead < size)
|
|
41
|
-
break;
|
|
42
|
-
start += bytesRead;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
finally {
|
|
46
|
-
await fd?.close();
|
|
3
|
+
async function* fileChunks(path, opts) {
|
|
4
|
+
let { logger, size, start, end } = {
|
|
5
|
+
size: 1024,
|
|
6
|
+
start: 0,
|
|
7
|
+
end: Infinity,
|
|
8
|
+
...opts
|
|
9
|
+
};
|
|
10
|
+
logger && logger.debug(`start reading file chunks (size: 0x${size}): ${path}`);
|
|
11
|
+
let fd = void 0;
|
|
12
|
+
try {
|
|
13
|
+
fd = await open(path, "r");
|
|
14
|
+
while (start < end) {
|
|
15
|
+
logger && logger.debug(
|
|
16
|
+
`reading chunk: 0x${U32(start)} - 0x${U32(
|
|
17
|
+
start + size - 1
|
|
18
|
+
)} (${path})`
|
|
19
|
+
);
|
|
20
|
+
const { buffer, bytesRead } = await fd.read({
|
|
21
|
+
buffer: Buffer.alloc(size),
|
|
22
|
+
length: size,
|
|
23
|
+
position: start
|
|
24
|
+
});
|
|
25
|
+
if (bytesRead === 0)
|
|
26
|
+
break;
|
|
27
|
+
yield buffer;
|
|
28
|
+
if (bytesRead < size)
|
|
29
|
+
break;
|
|
30
|
+
start += bytesRead;
|
|
47
31
|
}
|
|
32
|
+
} finally {
|
|
33
|
+
await fd?.close();
|
|
34
|
+
}
|
|
48
35
|
}
|
|
36
|
+
export {
|
|
37
|
+
fileChunks
|
|
38
|
+
};
|
package/files.js
CHANGED
|
@@ -3,81 +3,45 @@ import { isString } from "@thi.ng/checks/is-string";
|
|
|
3
3
|
import { readdirSync, statSync } from "fs";
|
|
4
4
|
import { sep } from "path";
|
|
5
5
|
import { isDirectory } from "./dir.js";
|
|
6
|
-
|
|
7
|
-
* Recursively reads given directory (up to given max. depth, default: infinite)
|
|
8
|
-
* and yields sequence of file names matching given extension (or regexp or
|
|
9
|
-
* predicate).
|
|
10
|
-
*
|
|
11
|
-
* @remarks
|
|
12
|
-
* Files will be matched using their _full_ relative sub-path (starting with
|
|
13
|
-
* given `dir`). If NO `match` is given, all files will be matched. Directories
|
|
14
|
-
* will *not* be tested and are always traversed (up to given `maxDepth`).
|
|
15
|
-
*
|
|
16
|
-
* The optional `logger` is only used to log errors for files which couldn't be
|
|
17
|
-
* accessed.
|
|
18
|
-
*
|
|
19
|
-
* @param dir
|
|
20
|
-
* @param match
|
|
21
|
-
* @param maxDepth
|
|
22
|
-
* @param logger
|
|
23
|
-
*/
|
|
24
|
-
export const files = (dir, match = "", maxDepth = Infinity, logger) => __files(dir, match, logger, maxDepth, 0);
|
|
6
|
+
const files = (dir, match = "", maxDepth = Infinity, logger) => __files(dir, match, logger, maxDepth, 0);
|
|
25
7
|
function* __files(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
catch (e) {
|
|
40
|
-
logger &&
|
|
41
|
-
logger.warn(`ignoring file: ${f} (${e.message})`);
|
|
42
|
-
}
|
|
8
|
+
if (depth >= maxDepth)
|
|
9
|
+
return;
|
|
10
|
+
const pred = __ensurePred(match);
|
|
11
|
+
for (let f of readdirSync(dir).sort()) {
|
|
12
|
+
const curr = dir + sep + f;
|
|
13
|
+
try {
|
|
14
|
+
if (isDirectory(curr)) {
|
|
15
|
+
yield* __files(curr, match, logger, maxDepth, depth + 1);
|
|
16
|
+
} else if (pred(curr)) {
|
|
17
|
+
yield curr;
|
|
18
|
+
}
|
|
19
|
+
} catch (e) {
|
|
20
|
+
logger && logger.warn(`ignoring file: ${f} (${e.message})`);
|
|
43
21
|
}
|
|
22
|
+
}
|
|
44
23
|
}
|
|
45
|
-
|
|
46
|
-
* Similar to {@link files}, however yields iterator of only matching
|
|
47
|
-
* sub-directories in given `dir`. Normal files are being ignored.
|
|
48
|
-
*
|
|
49
|
-
* @remarks
|
|
50
|
-
* Like the matcher in {@link files}, the regex or predicate will be applied to
|
|
51
|
-
* the _full_ sub-path (starting with `dir`) in order to determine a match.
|
|
52
|
-
*
|
|
53
|
-
* @param dir
|
|
54
|
-
* @param match
|
|
55
|
-
* @param maxDepth
|
|
56
|
-
* @param logger
|
|
57
|
-
*/
|
|
58
|
-
export const dirs = (dir, match = "", maxDepth = Infinity, logger) => __dirs(dir, match, logger, maxDepth, 0);
|
|
24
|
+
const dirs = (dir, match = "", maxDepth = Infinity, logger) => __dirs(dir, match, logger, maxDepth, 0);
|
|
59
25
|
function* __dirs(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
logger &&
|
|
74
|
-
logger.warn(`ignoring file/dir: ${f} (${e.message})`);
|
|
75
|
-
}
|
|
26
|
+
if (depth >= maxDepth)
|
|
27
|
+
return;
|
|
28
|
+
const pred = __ensurePred(match);
|
|
29
|
+
for (let f of readdirSync(dir).sort()) {
|
|
30
|
+
const curr = dir + sep + f;
|
|
31
|
+
try {
|
|
32
|
+
if (statSync(curr).isDirectory()) {
|
|
33
|
+
if (pred(curr))
|
|
34
|
+
yield curr;
|
|
35
|
+
yield* __dirs(curr, match, logger, maxDepth, depth + 1);
|
|
36
|
+
}
|
|
37
|
+
} catch (e) {
|
|
38
|
+
logger && logger.warn(`ignoring file/dir: ${f} (${e.message})`);
|
|
76
39
|
}
|
|
40
|
+
}
|
|
77
41
|
}
|
|
78
|
-
/** @internal */
|
|
79
42
|
const __ensureRegEx = (match) => isString(match) ? new RegExp(`${match.replace(/\./g, "\\.")}$`) : match;
|
|
80
|
-
const __ensurePred = (match) => isFunction(match)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
43
|
+
const __ensurePred = (match) => isFunction(match) ? match : (match = __ensureRegEx(match), (x) => match.test(x));
|
|
44
|
+
export {
|
|
45
|
+
dirs,
|
|
46
|
+
files
|
|
47
|
+
};
|
package/hash.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { createHash } from "crypto";
|
|
2
2
|
import { readFileSync } from "fs";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const fileHash = (path, logger, algo = "sha256") => {
|
|
4
|
+
const sum = createHash(algo);
|
|
5
|
+
sum.update(readFileSync(path));
|
|
6
|
+
const hash = sum.digest("hex");
|
|
7
|
+
logger && logger.info(`${algo} hash for ${path}: ${hash}`);
|
|
8
|
+
return hash;
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const stringHash = (src, logger, algo = "sha256") => {
|
|
11
|
+
const sum = createHash(algo);
|
|
12
|
+
sum.update(src);
|
|
13
|
+
const hash = sum.digest("hex");
|
|
14
|
+
logger && logger.info(`${algo} hash for string: ${hash}`);
|
|
15
|
+
return hash;
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
fileHash,
|
|
19
|
+
stringHash
|
|
16
20
|
};
|
package/json.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { readText, writeText } from "./text.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* @param replacer
|
|
14
|
-
* @param space
|
|
15
|
-
* @param logger
|
|
16
|
-
* @param dryRun
|
|
17
|
-
*/
|
|
18
|
-
export const writeJSON = (path, obj, replacer, space, logger, dryRun = false) => writeText(path, JSON.stringify(obj, replacer, space) + "\n", logger, dryRun);
|
|
2
|
+
const readJSON = (path, logger) => JSON.parse(readText(path, logger));
|
|
3
|
+
const writeJSON = (path, obj, replacer, space, logger, dryRun = false) => writeText(
|
|
4
|
+
path,
|
|
5
|
+
JSON.stringify(obj, replacer, space) + "\n",
|
|
6
|
+
logger,
|
|
7
|
+
dryRun
|
|
8
|
+
);
|
|
9
|
+
export {
|
|
10
|
+
readJSON,
|
|
11
|
+
writeJSON
|
|
12
|
+
};
|
package/mask.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* @param path
|
|
6
|
-
* @param home
|
|
7
|
-
*/
|
|
8
|
-
export const maskHomeDir = (path, home = process.env.HOME, mask = "~") => (home ? path.replace(home, mask) : path);
|
|
1
|
+
const maskHomeDir = (path, home = process.env.HOME, mask = "~") => home ? path.replace(home, mask) : path;
|
|
2
|
+
export {
|
|
3
|
+
maskHomeDir
|
|
4
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/file-io",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Assorted file I/O utils (with logging support) for NodeJS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "yarn
|
|
27
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
28
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
29
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
28
30
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
|
|
29
31
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
30
32
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -33,14 +35,15 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@thi.ng/api": "^8.9.
|
|
37
|
-
"@thi.ng/checks": "^3.4.
|
|
38
|
-
"@thi.ng/hex": "^2.3.
|
|
39
|
-
"@thi.ng/logger": "^2.0.
|
|
40
|
-
"@thi.ng/random": "^3.6.
|
|
38
|
+
"@thi.ng/api": "^8.9.12",
|
|
39
|
+
"@thi.ng/checks": "^3.4.12",
|
|
40
|
+
"@thi.ng/hex": "^2.3.24",
|
|
41
|
+
"@thi.ng/logger": "^2.0.2",
|
|
42
|
+
"@thi.ng/random": "^3.6.18"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@microsoft/api-extractor": "^7.38.3",
|
|
46
|
+
"esbuild": "^0.19.8",
|
|
44
47
|
"rimraf": "^5.0.5",
|
|
45
48
|
"tools": "^0.0.1",
|
|
46
49
|
"typedoc": "^0.25.4",
|
|
@@ -114,5 +117,5 @@
|
|
|
114
117
|
"status": "stable",
|
|
115
118
|
"year": 2022
|
|
116
119
|
},
|
|
117
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
|
|
118
121
|
}
|
package/read.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { readFileSync } from "fs";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
logger && logger.debug("reading file:", path);
|
|
10
|
-
const buf = readFileSync(path);
|
|
11
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
2
|
+
const readBinary = (path, logger) => {
|
|
3
|
+
logger && logger.debug("reading file:", path);
|
|
4
|
+
const buf = readFileSync(path);
|
|
5
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
6
|
+
};
|
|
7
|
+
export {
|
|
8
|
+
readBinary
|
|
12
9
|
};
|
package/temp.js
CHANGED
|
@@ -4,11 +4,15 @@ import { realpathSync, writeFileSync } from "fs";
|
|
|
4
4
|
import { tmpdir } from "os";
|
|
5
5
|
import { sep } from "path";
|
|
6
6
|
import { ensureDirForFile } from "./dir.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
const createTempFile = (body, logger, name) => {
|
|
8
|
+
const path = tempFilePath(name);
|
|
9
|
+
logger && logger.debug("creating temp file:", path);
|
|
10
|
+
ensureDirForFile(path);
|
|
11
|
+
writeFileSync(path, body, isString(body) ? "utf-8" : void 0);
|
|
12
|
+
return path;
|
|
13
|
+
};
|
|
14
|
+
const tempFilePath = (name) => realpathSync(tmpdir()) + sep + (name || randomID(16, "tmp-"));
|
|
15
|
+
export {
|
|
16
|
+
createTempFile,
|
|
17
|
+
tempFilePath
|
|
13
18
|
};
|
|
14
|
-
export const tempFilePath = (name) => realpathSync(tmpdir()) + sep + (name || randomID(16, "tmp-"));
|
package/text.js
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
import { isArray } from "@thi.ng/checks/is-array";
|
|
2
2
|
import { readFileSync } from "fs";
|
|
3
3
|
import { writeFile } from "./write.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
const readText = (path, logger, encoding = "utf-8") => {
|
|
5
|
+
logger && logger.debug("reading file:", path);
|
|
6
|
+
return readFileSync(path, encoding);
|
|
7
|
+
};
|
|
8
|
+
const writeText = (path, body, logger, dryRun = false) => writeFile(
|
|
9
|
+
path,
|
|
10
|
+
isArray(body) ? body.join("\n") : body,
|
|
11
|
+
"utf-8",
|
|
12
|
+
logger,
|
|
13
|
+
dryRun
|
|
14
|
+
);
|
|
15
|
+
export {
|
|
16
|
+
readText,
|
|
17
|
+
writeText
|
|
15
18
|
};
|
|
16
|
-
/**
|
|
17
|
-
* Writes `body` as UTF-8 file to given `path`. If `dryRun` is true (default:
|
|
18
|
-
* false), the file WON'T be written, however if a `logger` is provided then at
|
|
19
|
-
* least a dry-run log message will be emitted.
|
|
20
|
-
*
|
|
21
|
-
* @param path
|
|
22
|
-
* @param body
|
|
23
|
-
* @param logger
|
|
24
|
-
* @param dryRun
|
|
25
|
-
*/
|
|
26
|
-
export const writeText = (path, body, logger, dryRun = false) => writeFile(path, isArray(body) ? body.join("\n") : body, "utf-8", logger, dryRun);
|
package/write.js
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
import { isString } from "@thi.ng/checks/is-string";
|
|
2
2
|
import { writeFileSync } from "fs";
|
|
3
3
|
import { ensureDirForFile } from "./dir.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* @param dryRun
|
|
14
|
-
*/
|
|
15
|
-
export const writeFile = (path, body, opts, logger, dryRun = false) => {
|
|
16
|
-
logger && logger.info(`${dryRun ? "[dryrun] " : ""}writing file: ${path}`);
|
|
17
|
-
if (dryRun)
|
|
18
|
-
return;
|
|
19
|
-
ensureDirForFile(path);
|
|
20
|
-
writeFileSync(path, body, !opts && isString(body) ? "utf-8" : opts);
|
|
4
|
+
const writeFile = (path, body, opts, logger, dryRun = false) => {
|
|
5
|
+
logger && logger.info(`${dryRun ? "[dryrun] " : ""}writing file: ${path}`);
|
|
6
|
+
if (dryRun)
|
|
7
|
+
return;
|
|
8
|
+
ensureDirForFile(path);
|
|
9
|
+
writeFileSync(path, body, !opts && isString(body) ? "utf-8" : opts);
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
writeFile
|
|
21
13
|
};
|