@naturalcycles/nodejs-lib 12.91.1 → 12.93.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/dist/fs/del.js +9 -8
- package/dist/fs/fs.util.d.ts +13 -5
- package/dist/fs/fs.util.js +44 -8
- package/dist/fs/json2env.js +5 -4
- package/dist/fs/kpy.js +6 -4
- package/dist/secret/secrets-decrypt.util.js +3 -3
- package/dist/secret/secrets-encrypt.util.js +3 -3
- package/dist/stream/ndjson/pipelineFromNDJsonFile.js +1 -1
- package/dist/stream/ndjson/pipelineToNDJsonFile.js +3 -3
- package/package.json +1 -3
- package/src/fs/del.ts +10 -9
- package/src/fs/fs.util.ts +44 -13
- package/src/fs/json2env.ts +5 -4
- package/src/fs/kpy.ts +6 -4
- package/src/secret/secrets-decrypt.util.ts +4 -4
- package/src/secret/secrets-encrypt.util.ts +4 -4
- package/src/security/secret.util.ts +1 -1
- package/src/stream/ndjson/pipelineFromNDJsonFile.ts +1 -1
- package/src/stream/ndjson/pipelineToNDJsonFile.ts +4 -4
package/dist/fs/del.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.delSync = exports.del = void 0;
|
|
4
|
+
const fs = require("node:fs");
|
|
5
|
+
const fsp = require("node:fs/promises");
|
|
4
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
|
-
const fs = require("fs-extra");
|
|
6
7
|
const colors_1 = require("../colors");
|
|
7
8
|
const index_1 = require("../index");
|
|
8
9
|
const DEF_OPT = {
|
|
@@ -42,7 +43,7 @@ async function del(_opt) {
|
|
|
42
43
|
}
|
|
43
44
|
if (dry)
|
|
44
45
|
return;
|
|
45
|
-
await (0, js_lib_1.pMap)(filenames, filepath =>
|
|
46
|
+
await (0, js_lib_1.pMap)(filenames, filepath => fsp.unlink(filepath), { concurrency });
|
|
46
47
|
// 2. glob only dirs, expand, delete only empty!
|
|
47
48
|
let dirnames = await (0, index_1.globby)(patterns, {
|
|
48
49
|
dot: true,
|
|
@@ -51,7 +52,7 @@ async function del(_opt) {
|
|
|
51
52
|
});
|
|
52
53
|
// Add original patterns (if any of them are dirs)
|
|
53
54
|
dirnames = dirnames.concat(await (0, js_lib_1.pFilter)(patterns, async (pattern) => {
|
|
54
|
-
return (await
|
|
55
|
+
return (await (0, index_1._pathExists)(pattern)) && (await fsp.lstat(pattern)).isDirectory();
|
|
55
56
|
}));
|
|
56
57
|
const dirnamesSorted = dirnames.sort().reverse();
|
|
57
58
|
// console.log({ dirnamesSorted })
|
|
@@ -59,7 +60,7 @@ async function del(_opt) {
|
|
|
59
60
|
for await (const dirpath of dirnamesSorted) {
|
|
60
61
|
if (await isEmptyDir(dirpath)) {
|
|
61
62
|
// console.log(`empty dir: ${dirpath}`)
|
|
62
|
-
await
|
|
63
|
+
await fsp.unlink(dirpath);
|
|
63
64
|
deletedDirs.push(dirpath);
|
|
64
65
|
}
|
|
65
66
|
}
|
|
@@ -97,7 +98,7 @@ function delSync(_opt) {
|
|
|
97
98
|
}
|
|
98
99
|
if (dry)
|
|
99
100
|
return;
|
|
100
|
-
filenames.forEach(filepath => fs.
|
|
101
|
+
filenames.forEach(filepath => fs.unlinkSync(filepath));
|
|
101
102
|
// 2. glob only dirs, expand, delete only empty!
|
|
102
103
|
let dirnames = index_1.globby.sync(patterns, {
|
|
103
104
|
dot: true,
|
|
@@ -105,14 +106,14 @@ function delSync(_opt) {
|
|
|
105
106
|
onlyDirectories: true,
|
|
106
107
|
});
|
|
107
108
|
// Add original patterns (if any of them are dirs)
|
|
108
|
-
dirnames = dirnames.concat(patterns.filter(p =>
|
|
109
|
+
dirnames = dirnames.concat(patterns.filter(p => (0, index_1._pathExistsSync)(p) && fs.lstatSync(p).isDirectory()));
|
|
109
110
|
const dirnamesSorted = dirnames.sort().reverse();
|
|
110
111
|
// console.log({ dirnamesSorted })
|
|
111
112
|
const deletedDirs = [];
|
|
112
113
|
for (const dirpath of dirnamesSorted) {
|
|
113
114
|
if (isEmptyDirSync(dirpath)) {
|
|
114
115
|
// console.log(`empty dir: ${dirpath}`)
|
|
115
|
-
fs.
|
|
116
|
+
fs.unlinkSync(dirpath);
|
|
116
117
|
deletedDirs.push(dirpath);
|
|
117
118
|
}
|
|
118
119
|
}
|
|
@@ -128,7 +129,7 @@ exports.delSync = delSync;
|
|
|
128
129
|
// 2. glob only dirs, expand, delete only empty!
|
|
129
130
|
// 3. test each original pattern, if it exists and is directory and is empty - delete
|
|
130
131
|
async function isEmptyDir(dir) {
|
|
131
|
-
return (await
|
|
132
|
+
return (await fsp.readdir(dir)).length === 0;
|
|
132
133
|
}
|
|
133
134
|
function isEmptyDirSync(dir) {
|
|
134
135
|
return fs.readdirSync(dir).length === 0;
|
package/dist/fs/fs.util.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import * as fs from 'node:fs';
|
|
3
4
|
export interface JsonOptions {
|
|
4
5
|
spaces?: number;
|
|
5
6
|
}
|
|
@@ -25,12 +26,19 @@ export declare function _pathExists(filePath: string): Promise<boolean>;
|
|
|
25
26
|
export declare function _pathExistsSync(filePath: string): boolean;
|
|
26
27
|
export declare function _ensureDir(dirPath: string): Promise<void>;
|
|
27
28
|
export declare function _ensureDirSync(dirPath: string): void;
|
|
29
|
+
export declare function _ensureFile(filePath: string): Promise<void>;
|
|
28
30
|
export declare function _ensureFileSync(filePath: string): void;
|
|
29
31
|
export declare function _removePath(fileOrDirPath: string): Promise<void>;
|
|
30
32
|
export declare function _removePathSync(fileOrDirPath: string): void;
|
|
31
33
|
export declare function _emptyDir(dirPath: string): Promise<void>;
|
|
32
34
|
export declare function _emptyDirSync(dirPath: string): void;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export declare function
|
|
35
|
+
/**
|
|
36
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
37
|
+
*/
|
|
38
|
+
export declare function _copyPath(src: string, dest: string, opt?: fs.CopyOptions): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
41
|
+
*/
|
|
42
|
+
export declare function _copyPathSync(src: string, dest: string, opt?: fs.CopySyncOptions): void;
|
|
43
|
+
export declare function _movePath(src: string, dest: string, opt?: fs.CopyOptions): Promise<void>;
|
|
44
|
+
export declare function _movePathSync(src: string, dest: string, opt?: fs.CopySyncOptions): void;
|
package/dist/fs/fs.util.js
CHANGED
|
@@ -15,12 +15,11 @@ Credit to: fs-extra (https://github.com/jprichardson/node-fs-extra)
|
|
|
15
15
|
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports._movePathSync = exports._movePath = exports._copyPathSync = exports._copyPath = exports._emptyDirSync = exports._emptyDir = exports._removePathSync = exports._removePath = exports._ensureFileSync = exports._ensureDirSync = exports._ensureDir = exports._pathExistsSync = exports._pathExists = exports._outputJsonFileSync = exports._outputJsonFile = exports._writeJsonFileSync = exports._writeJsonFile = exports._outputFileSync = exports._outputFile = exports._writeFileSync = exports._writeFile = exports._readJsonFileSync = exports._readJsonFile = exports._readFileSync = exports._readFile = void 0;
|
|
18
|
+
exports._movePathSync = exports._movePath = exports._copyPathSync = exports._copyPath = exports._emptyDirSync = exports._emptyDir = exports._removePathSync = exports._removePath = exports._ensureFileSync = exports._ensureFile = exports._ensureDirSync = exports._ensureDir = exports._pathExistsSync = exports._pathExists = exports._outputJsonFileSync = exports._outputJsonFile = exports._writeJsonFileSync = exports._writeJsonFile = exports._outputFileSync = exports._outputFile = exports._writeFileSync = exports._writeFile = exports._readJsonFileSync = exports._readJsonFile = exports._readFileSync = exports._readFile = void 0;
|
|
19
19
|
const fs = require("node:fs");
|
|
20
20
|
const fsp = require("node:fs/promises");
|
|
21
21
|
const path = require("node:path");
|
|
22
22
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
23
|
-
const fse = require("fs-extra");
|
|
24
23
|
/**
|
|
25
24
|
* Convenience wrapper that defaults to utf-8 string output.
|
|
26
25
|
*/
|
|
@@ -117,7 +116,31 @@ function _ensureDirSync(dirPath) {
|
|
|
117
116
|
});
|
|
118
117
|
}
|
|
119
118
|
exports._ensureDirSync = _ensureDirSync;
|
|
120
|
-
|
|
119
|
+
async function _ensureFile(filePath) {
|
|
120
|
+
let stats;
|
|
121
|
+
try {
|
|
122
|
+
stats = await fsp.stat(filePath);
|
|
123
|
+
}
|
|
124
|
+
catch { }
|
|
125
|
+
if (stats?.isFile())
|
|
126
|
+
return;
|
|
127
|
+
const dir = path.dirname(filePath);
|
|
128
|
+
try {
|
|
129
|
+
if (!(await fsp.stat(dir)).isDirectory()) {
|
|
130
|
+
// parent is not a directory
|
|
131
|
+
// This is just to cause an internal ENOTDIR error to be thrown
|
|
132
|
+
await fsp.readdir(dir);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
// If the stat call above failed because the directory doesn't exist, create it
|
|
137
|
+
if (err?.code === 'ENOENT')
|
|
138
|
+
return await _ensureDir(dir);
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
await fsp.writeFile(filePath, '');
|
|
142
|
+
}
|
|
143
|
+
exports._ensureFile = _ensureFile;
|
|
121
144
|
function _ensureFileSync(filePath) {
|
|
122
145
|
let stats;
|
|
123
146
|
try {
|
|
@@ -173,20 +196,33 @@ function _emptyDirSync(dirPath) {
|
|
|
173
196
|
items.forEach(item => _removePathSync(path.join(dirPath, item)));
|
|
174
197
|
}
|
|
175
198
|
exports._emptyDirSync = _emptyDirSync;
|
|
176
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
201
|
+
*/
|
|
177
202
|
async function _copyPath(src, dest, opt) {
|
|
178
|
-
await
|
|
203
|
+
await fsp.cp(src, dest, {
|
|
204
|
+
recursive: true,
|
|
205
|
+
...opt,
|
|
206
|
+
});
|
|
179
207
|
}
|
|
180
208
|
exports._copyPath = _copyPath;
|
|
209
|
+
/**
|
|
210
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
211
|
+
*/
|
|
181
212
|
function _copyPathSync(src, dest, opt) {
|
|
182
|
-
|
|
213
|
+
fs.cpSync(src, dest, {
|
|
214
|
+
recursive: true,
|
|
215
|
+
...opt,
|
|
216
|
+
});
|
|
183
217
|
}
|
|
184
218
|
exports._copyPathSync = _copyPathSync;
|
|
185
219
|
async function _movePath(src, dest, opt) {
|
|
186
|
-
await
|
|
220
|
+
await _copyPath(src, dest, opt);
|
|
221
|
+
await _removePath(src);
|
|
187
222
|
}
|
|
188
223
|
exports._movePath = _movePath;
|
|
189
224
|
function _movePathSync(src, dest, opt) {
|
|
190
|
-
|
|
225
|
+
_copyPathSync(src, dest, opt);
|
|
226
|
+
_removePathSync(src);
|
|
191
227
|
}
|
|
192
228
|
exports._movePathSync = _movePathSync;
|
package/dist/fs/json2env.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.objectToGithubActionsEnv = exports.objectToShellExport = exports.json2env = void 0;
|
|
4
|
-
const fs = require("fs
|
|
4
|
+
const fs = require("node:fs");
|
|
5
5
|
const colors_1 = require("../colors");
|
|
6
|
+
const fs_util_1 = require("./fs.util");
|
|
6
7
|
const JSON2ENV_OPT_DEF = {
|
|
7
8
|
saveEnvFile: true,
|
|
8
9
|
bashEnv: true,
|
|
@@ -14,7 +15,7 @@ function json2env(opt) {
|
|
|
14
15
|
...JSON2ENV_OPT_DEF,
|
|
15
16
|
...opt,
|
|
16
17
|
};
|
|
17
|
-
if (!
|
|
18
|
+
if (!(0, fs_util_1._pathExistsSync)(jsonPath)) {
|
|
18
19
|
if (fail) {
|
|
19
20
|
throw new Error(`Path doesn't exist: ${jsonPath}`);
|
|
20
21
|
}
|
|
@@ -27,7 +28,7 @@ function json2env(opt) {
|
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
// read file
|
|
30
|
-
const json =
|
|
31
|
+
const json = (0, fs_util_1._readJsonFileSync)(jsonPath);
|
|
31
32
|
const exportStr = objectToShellExport(json, prefix);
|
|
32
33
|
const githubStr = objectToGithubActionsEnv(json, prefix);
|
|
33
34
|
if (debug) {
|
|
@@ -35,7 +36,7 @@ function json2env(opt) {
|
|
|
35
36
|
}
|
|
36
37
|
if (saveEnvFile) {
|
|
37
38
|
const shPath = `${jsonPath}.sh`;
|
|
38
|
-
|
|
39
|
+
(0, fs_util_1._writeFileSync)(shPath, exportStr);
|
|
39
40
|
if (!silent) {
|
|
40
41
|
console.log(`json2env created ${(0, colors_1.dimGrey)(shPath)}:`);
|
|
41
42
|
console.log(exportStr);
|
package/dist/fs/kpy.js
CHANGED
|
@@ -20,10 +20,12 @@ async function kpy(opt) {
|
|
|
20
20
|
const destFilename = path.resolve(opt.outputDir, opt.flat ? basename : filename);
|
|
21
21
|
if (!opt.dry) {
|
|
22
22
|
if (opt.move) {
|
|
23
|
-
await (0, index_1._movePath)(srcFilename, destFilename, {
|
|
23
|
+
await (0, index_1._movePath)(srcFilename, destFilename, {
|
|
24
|
+
force: overwrite,
|
|
25
|
+
});
|
|
24
26
|
}
|
|
25
27
|
else {
|
|
26
|
-
await (0, index_1._copyPath)(srcFilename, destFilename, { overwrite });
|
|
28
|
+
await (0, index_1._copyPath)(srcFilename, destFilename, { force: overwrite });
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
if (opt.verbose) {
|
|
@@ -48,10 +50,10 @@ function kpySync(opt) {
|
|
|
48
50
|
const destFilename = path.resolve(opt.outputDir, opt.flat ? basename : filename);
|
|
49
51
|
if (!opt.dry) {
|
|
50
52
|
if (opt.move) {
|
|
51
|
-
(0, index_1._movePathSync)(srcFilename, destFilename, { overwrite });
|
|
53
|
+
(0, index_1._movePathSync)(srcFilename, destFilename, { force: overwrite });
|
|
52
54
|
}
|
|
53
55
|
else {
|
|
54
|
-
(0, index_1._copyPathSync)(srcFilename, destFilename, { overwrite });
|
|
56
|
+
(0, index_1._copyPathSync)(srcFilename, destFilename, { force: overwrite });
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
if (opt.verbose) {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.secretsDecrypt = void 0;
|
|
4
4
|
const path = require("node:path");
|
|
5
|
+
const fs = require("node:fs");
|
|
5
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
|
-
const fs = require("fs-extra");
|
|
7
7
|
const colors_1 = require("../colors");
|
|
8
8
|
const index_1 = require("../index");
|
|
9
9
|
const crypto_util_1 = require("../security/crypto.util");
|
|
@@ -24,8 +24,8 @@ function secretsDecrypt(dir, file, encKey, del = false, jsonMode = false) {
|
|
|
24
24
|
(0, js_lib_1._assert)(filename.endsWith('.json'), `${path.basename(filename)} MUST end with '.json'`);
|
|
25
25
|
(0, js_lib_1._assert)(!filename.endsWith('.plain.json'), `${path.basename(filename)} MUST NOT end with '.plain.json'`);
|
|
26
26
|
plainFilename = filename.replace('.json', '.plain.json');
|
|
27
|
-
const json = (0, crypto_util_1.decryptObject)(
|
|
28
|
-
|
|
27
|
+
const json = (0, crypto_util_1.decryptObject)((0, index_1._readJsonFileSync)(filename), encKey);
|
|
28
|
+
(0, index_1._writeJsonFileSync)(plainFilename, json, { spaces: 2 });
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
31
|
const enc = fs.readFileSync(filename);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.secretsEncrypt = void 0;
|
|
4
|
+
const fs = require("node:fs");
|
|
4
5
|
const path = require("node:path");
|
|
5
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
|
-
const fs = require("fs-extra");
|
|
7
7
|
const colors_1 = require("../colors");
|
|
8
8
|
const index_1 = require("../index");
|
|
9
9
|
const crypto_util_1 = require("../security/crypto.util");
|
|
@@ -24,8 +24,8 @@ function secretsEncrypt(pattern, file, encKey, del = false, jsonMode = false) {
|
|
|
24
24
|
if (jsonMode) {
|
|
25
25
|
(0, js_lib_1._assert)(filename.endsWith('.plain.json'), `${path.basename(filename)} MUST end with '.plain.json'`);
|
|
26
26
|
encFilename = filename.replace('.plain', '');
|
|
27
|
-
const json = (0, crypto_util_1.encryptObject)(
|
|
28
|
-
|
|
27
|
+
const json = (0, crypto_util_1.encryptObject)((0, index_1._readJsonFileSync)(filename), encKey);
|
|
28
|
+
(0, index_1._writeJsonFileSync)(encFilename, json, { spaces: 2 });
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
31
|
const plain = fs.readFileSync(filename);
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pipelineFromNDJsonFile = void 0;
|
|
4
4
|
const node_zlib_1 = require("node:zlib");
|
|
5
|
+
const fs = require("node:fs");
|
|
5
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
|
-
const fs = require("fs-extra");
|
|
7
7
|
const __1 = require("../..");
|
|
8
8
|
const colors_1 = require("../../colors");
|
|
9
9
|
const ndjson_model_1 = require("./ndjson.model");
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pipelineToNDJsonFile = void 0;
|
|
4
4
|
const node_zlib_1 = require("node:zlib");
|
|
5
|
+
const fs = require("node:fs");
|
|
5
6
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
|
-
const fs = require("fs-extra");
|
|
7
7
|
const __1 = require("../..");
|
|
8
8
|
const colors_1 = require("../../colors");
|
|
9
9
|
const ndjson_model_1 = require("./ndjson.model");
|
|
@@ -15,12 +15,12 @@ const transformToNDJson_1 = require("./transformToNDJson");
|
|
|
15
15
|
*/
|
|
16
16
|
async function pipelineToNDJsonFile(streams, opt) {
|
|
17
17
|
const { filePath, gzip, protectFromOverwrite = false } = opt;
|
|
18
|
-
if (protectFromOverwrite &&
|
|
18
|
+
if (protectFromOverwrite && (0, __1._pathExistsSync)(filePath)) {
|
|
19
19
|
throw new js_lib_1.AppError(`pipelineToNDJsonFile: output file exists: ${filePath}`);
|
|
20
20
|
}
|
|
21
21
|
const started = Date.now();
|
|
22
22
|
let rows = 0;
|
|
23
|
-
|
|
23
|
+
(0, __1._ensureFileSync)(filePath);
|
|
24
24
|
console.log(`>> ${(0, colors_1.grey)(filePath)} started...`);
|
|
25
25
|
await (0, __1._pipeline)([
|
|
26
26
|
...streams,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/nodejs-lib",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.93.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky install",
|
|
6
6
|
"docs-serve": "vuepress dev docs",
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@naturalcycles/js-lib": "^14.0.0",
|
|
18
|
-
"@types/fs-extra": "^11.0.1",
|
|
19
18
|
"@types/jsonwebtoken": "^9.0.0",
|
|
20
19
|
"@types/through2-concurrent": "^2.0.0",
|
|
21
20
|
"ajv": "^8.6.2",
|
|
@@ -28,7 +27,6 @@
|
|
|
28
27
|
"dotenv": "^16.0.0",
|
|
29
28
|
"execa": "^5.0.0",
|
|
30
29
|
"fast-glob": "^3.2.11",
|
|
31
|
-
"fs-extra": "^11.0.0",
|
|
32
30
|
"globby": "^11.0.0",
|
|
33
31
|
"got": "^11.0.1",
|
|
34
32
|
"joi": "17.4.2",
|
package/src/fs/del.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as fsp from 'node:fs/promises'
|
|
1
3
|
import { pFilter, pMap, _since } from '@naturalcycles/js-lib'
|
|
2
|
-
import * as fs from 'fs-extra'
|
|
3
4
|
import { dimGrey, yellow } from '../colors'
|
|
4
|
-
import { globby } from '../index'
|
|
5
|
+
import { _pathExists, _pathExistsSync, globby } from '../index'
|
|
5
6
|
|
|
6
7
|
export interface DelOptions {
|
|
7
8
|
/**
|
|
@@ -70,7 +71,7 @@ export async function del(_opt: DelOptions | DelSingleOption): Promise<void> {
|
|
|
70
71
|
|
|
71
72
|
if (dry) return
|
|
72
73
|
|
|
73
|
-
await pMap(filenames, filepath =>
|
|
74
|
+
await pMap(filenames, filepath => fsp.unlink(filepath), { concurrency })
|
|
74
75
|
|
|
75
76
|
// 2. glob only dirs, expand, delete only empty!
|
|
76
77
|
let dirnames = await globby(patterns, {
|
|
@@ -82,7 +83,7 @@ export async function del(_opt: DelOptions | DelSingleOption): Promise<void> {
|
|
|
82
83
|
// Add original patterns (if any of them are dirs)
|
|
83
84
|
dirnames = dirnames.concat(
|
|
84
85
|
await pFilter(patterns, async pattern => {
|
|
85
|
-
return (await
|
|
86
|
+
return (await _pathExists(pattern)) && (await fsp.lstat(pattern)).isDirectory()
|
|
86
87
|
}),
|
|
87
88
|
)
|
|
88
89
|
|
|
@@ -94,7 +95,7 @@ export async function del(_opt: DelOptions | DelSingleOption): Promise<void> {
|
|
|
94
95
|
for await (const dirpath of dirnamesSorted) {
|
|
95
96
|
if (await isEmptyDir(dirpath)) {
|
|
96
97
|
// console.log(`empty dir: ${dirpath}`)
|
|
97
|
-
await
|
|
98
|
+
await fsp.unlink(dirpath)
|
|
98
99
|
deletedDirs.push(dirpath)
|
|
99
100
|
}
|
|
100
101
|
}
|
|
@@ -144,7 +145,7 @@ export function delSync(_opt: DelOptions | DelSingleOption): void {
|
|
|
144
145
|
|
|
145
146
|
if (dry) return
|
|
146
147
|
|
|
147
|
-
filenames.forEach(filepath => fs.
|
|
148
|
+
filenames.forEach(filepath => fs.unlinkSync(filepath))
|
|
148
149
|
|
|
149
150
|
// 2. glob only dirs, expand, delete only empty!
|
|
150
151
|
let dirnames = globby.sync(patterns, {
|
|
@@ -155,7 +156,7 @@ export function delSync(_opt: DelOptions | DelSingleOption): void {
|
|
|
155
156
|
|
|
156
157
|
// Add original patterns (if any of them are dirs)
|
|
157
158
|
dirnames = dirnames.concat(
|
|
158
|
-
patterns.filter(p =>
|
|
159
|
+
patterns.filter(p => _pathExistsSync(p) && fs.lstatSync(p).isDirectory()),
|
|
159
160
|
)
|
|
160
161
|
|
|
161
162
|
const dirnamesSorted = dirnames.sort().reverse()
|
|
@@ -166,7 +167,7 @@ export function delSync(_opt: DelOptions | DelSingleOption): void {
|
|
|
166
167
|
for (const dirpath of dirnamesSorted) {
|
|
167
168
|
if (isEmptyDirSync(dirpath)) {
|
|
168
169
|
// console.log(`empty dir: ${dirpath}`)
|
|
169
|
-
fs.
|
|
170
|
+
fs.unlinkSync(dirpath)
|
|
170
171
|
deletedDirs.push(dirpath)
|
|
171
172
|
}
|
|
172
173
|
}
|
|
@@ -188,7 +189,7 @@ export function delSync(_opt: DelOptions | DelSingleOption): void {
|
|
|
188
189
|
// 3. test each original pattern, if it exists and is directory and is empty - delete
|
|
189
190
|
|
|
190
191
|
async function isEmptyDir(dir: string): Promise<boolean> {
|
|
191
|
-
return (await
|
|
192
|
+
return (await fsp.readdir(dir)).length === 0
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
function isEmptyDirSync(dir: string): boolean {
|
package/src/fs/fs.util.ts
CHANGED
|
@@ -18,8 +18,6 @@ import * as fs from 'node:fs'
|
|
|
18
18
|
import * as fsp from 'node:fs/promises'
|
|
19
19
|
import * as path from 'node:path'
|
|
20
20
|
import { _jsonParse } from '@naturalcycles/js-lib'
|
|
21
|
-
import type { CopyOptions, CopyOptionsSync, MoveOptions } from 'fs-extra'
|
|
22
|
-
import * as fse from 'fs-extra'
|
|
23
21
|
|
|
24
22
|
export interface JsonOptions {
|
|
25
23
|
spaces?: number
|
|
@@ -130,7 +128,28 @@ export function _ensureDirSync(dirPath: string): void {
|
|
|
130
128
|
})
|
|
131
129
|
}
|
|
132
130
|
|
|
133
|
-
|
|
131
|
+
export async function _ensureFile(filePath: string): Promise<void> {
|
|
132
|
+
let stats
|
|
133
|
+
try {
|
|
134
|
+
stats = await fsp.stat(filePath)
|
|
135
|
+
} catch {}
|
|
136
|
+
if (stats?.isFile()) return
|
|
137
|
+
|
|
138
|
+
const dir = path.dirname(filePath)
|
|
139
|
+
try {
|
|
140
|
+
if (!(await fsp.stat(dir)).isDirectory()) {
|
|
141
|
+
// parent is not a directory
|
|
142
|
+
// This is just to cause an internal ENOTDIR error to be thrown
|
|
143
|
+
await fsp.readdir(dir)
|
|
144
|
+
}
|
|
145
|
+
} catch (err) {
|
|
146
|
+
// If the stat call above failed because the directory doesn't exist, create it
|
|
147
|
+
if ((err as any)?.code === 'ENOENT') return await _ensureDir(dir)
|
|
148
|
+
throw err
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
await fsp.writeFile(filePath, '')
|
|
152
|
+
}
|
|
134
153
|
|
|
135
154
|
export function _ensureFileSync(filePath: string): void {
|
|
136
155
|
let stats
|
|
@@ -185,20 +204,32 @@ export function _emptyDirSync(dirPath: string): void {
|
|
|
185
204
|
items.forEach(item => _removePathSync(path.join(dirPath, item)))
|
|
186
205
|
}
|
|
187
206
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
209
|
+
*/
|
|
210
|
+
export async function _copyPath(src: string, dest: string, opt?: fs.CopyOptions): Promise<void> {
|
|
211
|
+
await fsp.cp(src, dest, {
|
|
212
|
+
recursive: true,
|
|
213
|
+
...opt,
|
|
214
|
+
})
|
|
192
215
|
}
|
|
193
216
|
|
|
194
|
-
|
|
195
|
-
|
|
217
|
+
/**
|
|
218
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
219
|
+
*/
|
|
220
|
+
export function _copyPathSync(src: string, dest: string, opt?: fs.CopySyncOptions): void {
|
|
221
|
+
fs.cpSync(src, dest, {
|
|
222
|
+
recursive: true,
|
|
223
|
+
...opt,
|
|
224
|
+
})
|
|
196
225
|
}
|
|
197
226
|
|
|
198
|
-
export async function _movePath(src: string, dest: string, opt?:
|
|
199
|
-
await
|
|
227
|
+
export async function _movePath(src: string, dest: string, opt?: fs.CopyOptions): Promise<void> {
|
|
228
|
+
await _copyPath(src, dest, opt)
|
|
229
|
+
await _removePath(src)
|
|
200
230
|
}
|
|
201
231
|
|
|
202
|
-
export function _movePathSync(src: string, dest: string, opt?:
|
|
203
|
-
|
|
232
|
+
export function _movePathSync(src: string, dest: string, opt?: fs.CopySyncOptions): void {
|
|
233
|
+
_copyPathSync(src, dest, opt)
|
|
234
|
+
_removePathSync(src)
|
|
204
235
|
}
|
package/src/fs/json2env.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import * as fs from 'fs
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
2
|
import { dimGrey } from '../colors'
|
|
3
|
+
import { _pathExistsSync, _readJsonFileSync, _writeFileSync } from './fs.util'
|
|
3
4
|
|
|
4
5
|
export interface Json2EnvOptions {
|
|
5
6
|
jsonPath: string
|
|
@@ -42,7 +43,7 @@ export function json2env(opt: Json2EnvOptions): void {
|
|
|
42
43
|
...opt,
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
if (!
|
|
46
|
+
if (!_pathExistsSync(jsonPath)) {
|
|
46
47
|
if (fail) {
|
|
47
48
|
throw new Error(`Path doesn't exist: ${jsonPath}`)
|
|
48
49
|
}
|
|
@@ -59,7 +60,7 @@ export function json2env(opt: Json2EnvOptions): void {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
// read file
|
|
62
|
-
const json =
|
|
63
|
+
const json = _readJsonFileSync(jsonPath)
|
|
63
64
|
|
|
64
65
|
const exportStr = objectToShellExport(json, prefix)
|
|
65
66
|
const githubStr = objectToGithubActionsEnv(json, prefix)
|
|
@@ -70,7 +71,7 @@ export function json2env(opt: Json2EnvOptions): void {
|
|
|
70
71
|
|
|
71
72
|
if (saveEnvFile) {
|
|
72
73
|
const shPath = `${jsonPath}.sh`
|
|
73
|
-
|
|
74
|
+
_writeFileSync(shPath, exportStr)
|
|
74
75
|
|
|
75
76
|
if (!silent) {
|
|
76
77
|
console.log(`json2env created ${dimGrey(shPath)}:`)
|
package/src/fs/kpy.ts
CHANGED
|
@@ -72,9 +72,11 @@ export async function kpy(opt: KpyOptions): Promise<void> {
|
|
|
72
72
|
|
|
73
73
|
if (!opt.dry) {
|
|
74
74
|
if (opt.move) {
|
|
75
|
-
await _movePath(srcFilename, destFilename, {
|
|
75
|
+
await _movePath(srcFilename, destFilename, {
|
|
76
|
+
force: overwrite,
|
|
77
|
+
})
|
|
76
78
|
} else {
|
|
77
|
-
await _copyPath(srcFilename, destFilename, { overwrite })
|
|
79
|
+
await _copyPath(srcFilename, destFilename, { force: overwrite })
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
|
|
@@ -108,9 +110,9 @@ export function kpySync(opt: KpyOptions): void {
|
|
|
108
110
|
|
|
109
111
|
if (!opt.dry) {
|
|
110
112
|
if (opt.move) {
|
|
111
|
-
_movePathSync(srcFilename, destFilename, { overwrite })
|
|
113
|
+
_movePathSync(srcFilename, destFilename, { force: overwrite })
|
|
112
114
|
} else {
|
|
113
|
-
_copyPathSync(srcFilename, destFilename, { overwrite })
|
|
115
|
+
_copyPathSync(srcFilename, destFilename, { force: overwrite })
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as path from 'node:path'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
2
3
|
import { _assert } from '@naturalcycles/js-lib'
|
|
3
|
-
import * as fs from 'fs-extra'
|
|
4
4
|
import { dimGrey, yellow } from '../colors'
|
|
5
|
-
import { fastGlob } from '../index'
|
|
5
|
+
import { _readJsonFileSync, _writeJsonFileSync, fastGlob } from '../index'
|
|
6
6
|
import { decryptObject, decryptRandomIVBuffer } from '../security/crypto.util'
|
|
7
7
|
|
|
8
8
|
export interface DecryptCLIOptions {
|
|
@@ -44,9 +44,9 @@ export function secretsDecrypt(
|
|
|
44
44
|
)
|
|
45
45
|
plainFilename = filename.replace('.json', '.plain.json')
|
|
46
46
|
|
|
47
|
-
const json = decryptObject(
|
|
47
|
+
const json = decryptObject(_readJsonFileSync(filename), encKey)
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
_writeJsonFileSync(plainFilename, json, { spaces: 2 })
|
|
50
50
|
} else {
|
|
51
51
|
const enc = fs.readFileSync(filename)
|
|
52
52
|
const plain = decryptRandomIVBuffer(enc, encKey)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
1
2
|
import * as path from 'node:path'
|
|
2
3
|
import { _assert } from '@naturalcycles/js-lib'
|
|
3
|
-
import * as fs from 'fs-extra'
|
|
4
4
|
import { dimGrey, yellow } from '../colors'
|
|
5
|
-
import { fastGlob } from '../index'
|
|
5
|
+
import { _readJsonFileSync, _writeJsonFileSync, fastGlob } from '../index'
|
|
6
6
|
import { encryptObject, encryptRandomIVBuffer } from '../security/crypto.util'
|
|
7
7
|
|
|
8
8
|
export interface EncryptCLIOptions {
|
|
@@ -41,9 +41,9 @@ export function secretsEncrypt(
|
|
|
41
41
|
)
|
|
42
42
|
encFilename = filename.replace('.plain', '')
|
|
43
43
|
|
|
44
|
-
const json = encryptObject(
|
|
44
|
+
const json = encryptObject(_readJsonFileSync(filename), encKey)
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
_writeJsonFileSync(encFilename, json, { spaces: 2 })
|
|
47
47
|
} else {
|
|
48
48
|
const plain = fs.readFileSync(filename)
|
|
49
49
|
const enc = encryptRandomIVBuffer(plain, encKey)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createUnzip, ZlibOptions } from 'node:zlib'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
2
3
|
import { _hb } from '@naturalcycles/js-lib'
|
|
3
|
-
import * as fs from 'fs-extra'
|
|
4
4
|
import { transformTap, _pipeline, transformSplit } from '../..'
|
|
5
5
|
import { dimWhite, grey } from '../../colors'
|
|
6
6
|
import { NDJsonStats } from './ndjson.model'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createGzip, ZlibOptions } from 'node:zlib'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
2
3
|
import { AppError } from '@naturalcycles/js-lib'
|
|
3
|
-
import
|
|
4
|
-
import { transformTap, _pipeline } from '../..'
|
|
4
|
+
import { transformTap, _pipeline, _pathExistsSync, _ensureFileSync } from '../..'
|
|
5
5
|
import { grey } from '../../colors'
|
|
6
6
|
import { NDJsonStats } from './ndjson.model'
|
|
7
7
|
import { transformToNDJson, TransformToNDJsonOptions } from './transformToNDJson'
|
|
@@ -37,14 +37,14 @@ export async function pipelineToNDJsonFile(
|
|
|
37
37
|
): Promise<NDJsonStats> {
|
|
38
38
|
const { filePath, gzip, protectFromOverwrite = false } = opt
|
|
39
39
|
|
|
40
|
-
if (protectFromOverwrite &&
|
|
40
|
+
if (protectFromOverwrite && _pathExistsSync(filePath)) {
|
|
41
41
|
throw new AppError(`pipelineToNDJsonFile: output file exists: ${filePath}`)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const started = Date.now()
|
|
45
45
|
let rows = 0
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
_ensureFileSync(filePath)
|
|
48
48
|
|
|
49
49
|
console.log(`>> ${grey(filePath)} started...`)
|
|
50
50
|
|