@naturalcycles/nodejs-lib 13.5.0 → 13.6.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 +8 -13
- package/dist/fs/fs2.d.ts +79 -0
- package/dist/fs/fs2.js +267 -0
- package/dist/fs/json2env.js +4 -4
- package/dist/fs/kpy.js +6 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/secret/secrets-decrypt.util.js +2 -2
- package/dist/secret/secrets-encrypt.util.js +2 -2
- package/dist/stream/ndjson/pipelineToNDJsonFile.js +2 -2
- package/dist/util/buildInfo.util.js +3 -3
- package/dist/validation/ajv/ajv.util.js +1 -1
- package/dist/validation/ajv/ajvSchema.js +1 -1
- package/package.json +3 -1
- package/src/fs/del.ts +9 -20
- package/src/fs/fs2.ts +303 -0
- package/src/fs/json2env.ts +4 -4
- package/src/fs/kpy.ts +7 -15
- package/src/index.ts +1 -1
- package/src/secret/secrets-decrypt.util.ts +3 -3
- package/src/secret/secrets-encrypt.util.ts +3 -3
- package/src/slack/slack.service.ts +1 -1
- package/src/stream/ndjson/pipelineToNDJsonFile.ts +3 -3
- package/src/util/buildInfo.util.ts +3 -3
- package/src/validation/ajv/ajv.util.ts +2 -2
- package/src/validation/ajv/ajvSchema.ts +2 -2
- package/dist/fs/fs.util.d.ts +0 -184
- package/dist/fs/fs.util.js +0 -287
- package/src/fs/fs.util.ts +0 -287
package/dist/fs/del.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.delSync = exports.del = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
6
|
-
const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
|
|
7
4
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
8
5
|
const colors_1 = require("../colors/colors");
|
|
9
6
|
const index_1 = require("../index");
|
|
@@ -44,9 +41,7 @@ async function del(_opt) {
|
|
|
44
41
|
}
|
|
45
42
|
if (dry)
|
|
46
43
|
return;
|
|
47
|
-
await (0, js_lib_1.pMap)(filenames, filepath =>
|
|
48
|
-
force: true,
|
|
49
|
-
}), { concurrency });
|
|
44
|
+
await (0, js_lib_1.pMap)(filenames, filepath => index_1.fs2.removePath(filepath), { concurrency });
|
|
50
45
|
// 2. glob only dirs, expand, delete only empty!
|
|
51
46
|
let dirnames = await (0, index_1.globby)(patterns, {
|
|
52
47
|
dot: true,
|
|
@@ -55,7 +50,7 @@ async function del(_opt) {
|
|
|
55
50
|
});
|
|
56
51
|
// Add original patterns (if any of them are dirs)
|
|
57
52
|
dirnames = dirnames.concat(await (0, js_lib_1.pFilter)(patterns, async (pattern) => {
|
|
58
|
-
return (await
|
|
53
|
+
return (await index_1.fs2.pathExistsAsync(pattern)) && (await index_1.fs2.lstatAsync(pattern)).isDirectory();
|
|
59
54
|
}));
|
|
60
55
|
const dirnamesSorted = dirnames.sort().reverse();
|
|
61
56
|
// console.log({ dirnamesSorted })
|
|
@@ -63,7 +58,7 @@ async function del(_opt) {
|
|
|
63
58
|
for await (const dirpath of dirnamesSorted) {
|
|
64
59
|
if (await isEmptyDir(dirpath)) {
|
|
65
60
|
// console.log(`empty dir: ${dirpath}`)
|
|
66
|
-
await
|
|
61
|
+
await index_1.fs2.removePathAsync(dirpath);
|
|
67
62
|
deletedDirs.push(dirpath);
|
|
68
63
|
}
|
|
69
64
|
}
|
|
@@ -101,7 +96,7 @@ function delSync(_opt) {
|
|
|
101
96
|
}
|
|
102
97
|
if (dry)
|
|
103
98
|
return;
|
|
104
|
-
filenames.forEach(filepath =>
|
|
99
|
+
filenames.forEach(filepath => index_1.fs2.removePath(filepath));
|
|
105
100
|
// 2. glob only dirs, expand, delete only empty!
|
|
106
101
|
let dirnames = index_1.globby.sync(patterns, {
|
|
107
102
|
dot: true,
|
|
@@ -109,14 +104,14 @@ function delSync(_opt) {
|
|
|
109
104
|
onlyDirectories: true,
|
|
110
105
|
});
|
|
111
106
|
// Add original patterns (if any of them are dirs)
|
|
112
|
-
dirnames = dirnames.concat(patterns.filter(p =>
|
|
107
|
+
dirnames = dirnames.concat(patterns.filter(p => index_1.fs2.pathExists(p) && index_1.fs2.lstat(p).isDirectory()));
|
|
113
108
|
const dirnamesSorted = dirnames.sort().reverse();
|
|
114
109
|
// console.log({ dirnamesSorted })
|
|
115
110
|
const deletedDirs = [];
|
|
116
111
|
for (const dirpath of dirnamesSorted) {
|
|
117
112
|
if (isEmptyDirSync(dirpath)) {
|
|
118
113
|
// console.log(`empty dir: ${dirpath}`)
|
|
119
|
-
|
|
114
|
+
index_1.fs2.removePath(dirpath);
|
|
120
115
|
deletedDirs.push(dirpath);
|
|
121
116
|
}
|
|
122
117
|
}
|
|
@@ -132,8 +127,8 @@ exports.delSync = delSync;
|
|
|
132
127
|
// 2. glob only dirs, expand, delete only empty!
|
|
133
128
|
// 3. test each original pattern, if it exists and is directory and is empty - delete
|
|
134
129
|
async function isEmptyDir(dir) {
|
|
135
|
-
return (await
|
|
130
|
+
return (await index_1.fs2.readdirAsync(dir)).length === 0;
|
|
136
131
|
}
|
|
137
132
|
function isEmptyDirSync(dir) {
|
|
138
|
-
return
|
|
133
|
+
return index_1.fs2.readdir(dir).length === 0;
|
|
139
134
|
}
|
package/dist/fs/fs2.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
import type { RmOptions } from 'node:fs';
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import { DumpOptions } from 'js-yaml';
|
|
7
|
+
/**
|
|
8
|
+
* fs2 conveniently groups filesystem functions together.
|
|
9
|
+
* Supposed to be almost a drop-in replacement for these things together:
|
|
10
|
+
*
|
|
11
|
+
* 1. node:fs
|
|
12
|
+
* 2. node:fs/promises
|
|
13
|
+
* 3. fs-extra
|
|
14
|
+
*/
|
|
15
|
+
declare class FS2 {
|
|
16
|
+
/**
|
|
17
|
+
* Convenience wrapper that defaults to utf-8 string output.
|
|
18
|
+
*/
|
|
19
|
+
readText(filePath: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Convenience wrapper that defaults to utf-8 string output.
|
|
22
|
+
*/
|
|
23
|
+
readTextAsync(filePath: string): Promise<string>;
|
|
24
|
+
readBuffer(filePath: string): Buffer;
|
|
25
|
+
readBufferAsync(filePath: string): Promise<Buffer>;
|
|
26
|
+
readJson<T = unknown>(filePath: string): T;
|
|
27
|
+
readJsonAsync<T = unknown>(filePath: string): Promise<T>;
|
|
28
|
+
readYaml<T = unknown>(filePath: string): T;
|
|
29
|
+
readYamlAsync<T = unknown>(filePath: string): Promise<T>;
|
|
30
|
+
writeFile(filePath: string, data: string | Buffer): void;
|
|
31
|
+
writeFileAsync(filePath: string, data: string | Buffer): Promise<void>;
|
|
32
|
+
writeJson(filePath: string, data: any, opt?: JsonOptions): void;
|
|
33
|
+
writeJsonAsync(filePath: string, data: any, opt?: JsonOptions): Promise<void>;
|
|
34
|
+
writeYaml(filePath: string, data: any, opt?: DumpOptions): void;
|
|
35
|
+
writeYamlAsync(filePath: string, data: any, opt?: DumpOptions): Promise<void>;
|
|
36
|
+
outputJson(filePath: string, data: any, opt?: JsonOptions): void;
|
|
37
|
+
outputJsonAsync(filePath: string, data: any, opt?: JsonOptions): Promise<void>;
|
|
38
|
+
outputYaml(filePath: string, data: any, opt?: DumpOptions): void;
|
|
39
|
+
outputYamlAsync(filePath: string, data: any, opt?: DumpOptions): Promise<void>;
|
|
40
|
+
outputFile(filePath: string, data: string | Buffer): void;
|
|
41
|
+
outputFileAsync(filePath: string, data: string | Buffer): Promise<void>;
|
|
42
|
+
pathExists(filePath: string): boolean;
|
|
43
|
+
pathExistsAsync(filePath: string): Promise<boolean>;
|
|
44
|
+
ensureDir(dirPath: string): void;
|
|
45
|
+
ensureDirAsync(dirPath: string): Promise<void>;
|
|
46
|
+
ensureFile(filePath: string): void;
|
|
47
|
+
ensureFileAsync(filePath: string): Promise<void>;
|
|
48
|
+
removePath(fileOrDirPath: string, opt?: RmOptions): void;
|
|
49
|
+
removePathAsync(fileOrDirPath: string, opt?: RmOptions): Promise<void>;
|
|
50
|
+
emptyDir(dirPath: string): void;
|
|
51
|
+
emptyDirAsync(dirPath: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
54
|
+
*/
|
|
55
|
+
copyPath(src: string, dest: string, opt?: fs.CopySyncOptions): void;
|
|
56
|
+
/**
|
|
57
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
58
|
+
*/
|
|
59
|
+
copyPathAsync(src: string, dest: string, opt?: fs.CopyOptions): Promise<void>;
|
|
60
|
+
movePath(src: string, dest: string, opt?: fs.CopySyncOptions): void;
|
|
61
|
+
movePathAsync(src: string, dest: string, opt?: fs.CopyOptions): Promise<void>;
|
|
62
|
+
fs: typeof fs;
|
|
63
|
+
fsp: typeof fs.promises;
|
|
64
|
+
lstat: fs.StatSyncFn;
|
|
65
|
+
lstatAsync: typeof fs.promises.lstat;
|
|
66
|
+
stat: fs.StatSyncFn;
|
|
67
|
+
statAsync: typeof fs.promises.stat;
|
|
68
|
+
mkdir: typeof fs.mkdirSync;
|
|
69
|
+
mkdirAsync: typeof fs.promises.mkdir;
|
|
70
|
+
readdir: typeof fs.readdirSync;
|
|
71
|
+
readdirAsync: typeof fs.promises.readdir;
|
|
72
|
+
createWriteStream: typeof fs.createWriteStream;
|
|
73
|
+
createReadStream: typeof fs.createReadStream;
|
|
74
|
+
}
|
|
75
|
+
export declare const fs2: FS2;
|
|
76
|
+
export interface JsonOptions {
|
|
77
|
+
spaces?: number;
|
|
78
|
+
}
|
|
79
|
+
export {};
|
package/dist/fs/fs2.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
|
|
4
|
+
Why?
|
|
5
|
+
|
|
6
|
+
Convenience re-export/re-implementation of most common fs functions from
|
|
7
|
+
node:fs, node:fs/promises and fs-extra
|
|
8
|
+
|
|
9
|
+
Defaults to string input/output, as it's used in 80% of time. For the rest - you can use native fs.
|
|
10
|
+
|
|
11
|
+
Allows to import it easier, so you don't have to choose between the 3 import locations.
|
|
12
|
+
That's why function names are slightly renamed, to avoid conflict.
|
|
13
|
+
|
|
14
|
+
Credit to: fs-extra (https://github.com/jprichardson/node-fs-extra)
|
|
15
|
+
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.fs2 = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
21
|
+
const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
|
|
22
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
23
|
+
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
24
|
+
const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
|
|
25
|
+
/**
|
|
26
|
+
* fs2 conveniently groups filesystem functions together.
|
|
27
|
+
* Supposed to be almost a drop-in replacement for these things together:
|
|
28
|
+
*
|
|
29
|
+
* 1. node:fs
|
|
30
|
+
* 2. node:fs/promises
|
|
31
|
+
* 3. fs-extra
|
|
32
|
+
*/
|
|
33
|
+
class FS2 {
|
|
34
|
+
constructor() {
|
|
35
|
+
// Naming convention is:
|
|
36
|
+
// - async function has Async in the name, e.g readTextAsync
|
|
37
|
+
// - sync function has postfix in the name, e.g readText
|
|
38
|
+
// Re-export the whole fs/fsp, for the edge cases where they are needed
|
|
39
|
+
this.fs = node_fs_1.default;
|
|
40
|
+
this.fsp = promises_1.default;
|
|
41
|
+
// Re-export existing fs/fsp functions
|
|
42
|
+
// rm/rmAsync are replaced with removePath/removePathAsync
|
|
43
|
+
this.lstat = node_fs_1.default.lstatSync;
|
|
44
|
+
this.lstatAsync = promises_1.default.lstat;
|
|
45
|
+
this.stat = node_fs_1.default.statSync;
|
|
46
|
+
this.statAsync = promises_1.default.stat;
|
|
47
|
+
this.mkdir = node_fs_1.default.mkdirSync;
|
|
48
|
+
this.mkdirAsync = promises_1.default.mkdir;
|
|
49
|
+
this.readdir = node_fs_1.default.readdirSync;
|
|
50
|
+
this.readdirAsync = promises_1.default.readdir;
|
|
51
|
+
this.createWriteStream = node_fs_1.default.createWriteStream;
|
|
52
|
+
this.createReadStream = node_fs_1.default.createReadStream;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Convenience wrapper that defaults to utf-8 string output.
|
|
56
|
+
*/
|
|
57
|
+
readText(filePath) {
|
|
58
|
+
return node_fs_1.default.readFileSync(filePath, 'utf8');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Convenience wrapper that defaults to utf-8 string output.
|
|
62
|
+
*/
|
|
63
|
+
async readTextAsync(filePath) {
|
|
64
|
+
return await promises_1.default.readFile(filePath, 'utf8');
|
|
65
|
+
}
|
|
66
|
+
readBuffer(filePath) {
|
|
67
|
+
return node_fs_1.default.readFileSync(filePath);
|
|
68
|
+
}
|
|
69
|
+
async readBufferAsync(filePath) {
|
|
70
|
+
return await promises_1.default.readFile(filePath);
|
|
71
|
+
}
|
|
72
|
+
readJson(filePath) {
|
|
73
|
+
const str = node_fs_1.default.readFileSync(filePath, 'utf8');
|
|
74
|
+
return (0, js_lib_1._jsonParse)(str);
|
|
75
|
+
}
|
|
76
|
+
async readJsonAsync(filePath) {
|
|
77
|
+
const str = await promises_1.default.readFile(filePath, 'utf8');
|
|
78
|
+
return (0, js_lib_1._jsonParse)(str);
|
|
79
|
+
}
|
|
80
|
+
readYaml(filePath) {
|
|
81
|
+
return js_yaml_1.default.load(node_fs_1.default.readFileSync(filePath, 'utf8'));
|
|
82
|
+
}
|
|
83
|
+
async readYamlAsync(filePath) {
|
|
84
|
+
return js_yaml_1.default.load(await promises_1.default.readFile(filePath, 'utf8'));
|
|
85
|
+
}
|
|
86
|
+
writeFile(filePath, data) {
|
|
87
|
+
node_fs_1.default.writeFileSync(filePath, data);
|
|
88
|
+
}
|
|
89
|
+
async writeFileAsync(filePath, data) {
|
|
90
|
+
await promises_1.default.writeFile(filePath, data);
|
|
91
|
+
}
|
|
92
|
+
writeJson(filePath, data, opt) {
|
|
93
|
+
const str = stringify(data, opt);
|
|
94
|
+
node_fs_1.default.writeFileSync(filePath, str);
|
|
95
|
+
}
|
|
96
|
+
async writeJsonAsync(filePath, data, opt) {
|
|
97
|
+
const str = stringify(data, opt);
|
|
98
|
+
await promises_1.default.writeFile(filePath, str);
|
|
99
|
+
}
|
|
100
|
+
writeYaml(filePath, data, opt) {
|
|
101
|
+
const str = js_yaml_1.default.dump(data, opt);
|
|
102
|
+
node_fs_1.default.writeFileSync(filePath, str);
|
|
103
|
+
}
|
|
104
|
+
async writeYamlAsync(filePath, data, opt) {
|
|
105
|
+
const str = js_yaml_1.default.dump(data, opt);
|
|
106
|
+
await promises_1.default.writeFile(filePath, str);
|
|
107
|
+
}
|
|
108
|
+
outputJson(filePath, data, opt) {
|
|
109
|
+
const str = stringify(data, opt);
|
|
110
|
+
this.outputFile(filePath, str);
|
|
111
|
+
}
|
|
112
|
+
async outputJsonAsync(filePath, data, opt) {
|
|
113
|
+
const str = stringify(data, opt);
|
|
114
|
+
await this.outputFileAsync(filePath, str);
|
|
115
|
+
}
|
|
116
|
+
outputYaml(filePath, data, opt) {
|
|
117
|
+
const str = js_yaml_1.default.dump(data, opt);
|
|
118
|
+
this.outputFile(filePath, str);
|
|
119
|
+
}
|
|
120
|
+
async outputYamlAsync(filePath, data, opt) {
|
|
121
|
+
const str = js_yaml_1.default.dump(data, opt);
|
|
122
|
+
await this.outputFileAsync(filePath, str);
|
|
123
|
+
}
|
|
124
|
+
outputFile(filePath, data) {
|
|
125
|
+
const dirPath = node_path_1.default.dirname(filePath);
|
|
126
|
+
if (!node_fs_1.default.existsSync(dirPath)) {
|
|
127
|
+
this.ensureDir(dirPath);
|
|
128
|
+
}
|
|
129
|
+
node_fs_1.default.writeFileSync(filePath, data);
|
|
130
|
+
}
|
|
131
|
+
async outputFileAsync(filePath, data) {
|
|
132
|
+
const dirPath = node_path_1.default.dirname(filePath);
|
|
133
|
+
if (!(await this.pathExistsAsync(dirPath))) {
|
|
134
|
+
await this.ensureDirAsync(dirPath);
|
|
135
|
+
}
|
|
136
|
+
await promises_1.default.writeFile(filePath, data);
|
|
137
|
+
}
|
|
138
|
+
pathExists(filePath) {
|
|
139
|
+
return node_fs_1.default.existsSync(filePath);
|
|
140
|
+
}
|
|
141
|
+
async pathExistsAsync(filePath) {
|
|
142
|
+
try {
|
|
143
|
+
await promises_1.default.access(filePath);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
ensureDir(dirPath) {
|
|
151
|
+
node_fs_1.default.mkdirSync(dirPath, {
|
|
152
|
+
mode: 0o777,
|
|
153
|
+
recursive: true,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
async ensureDirAsync(dirPath) {
|
|
157
|
+
await promises_1.default.mkdir(dirPath, {
|
|
158
|
+
mode: 0o777,
|
|
159
|
+
recursive: true,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
ensureFile(filePath) {
|
|
163
|
+
let stats;
|
|
164
|
+
try {
|
|
165
|
+
stats = node_fs_1.default.statSync(filePath);
|
|
166
|
+
}
|
|
167
|
+
catch { }
|
|
168
|
+
if (stats?.isFile())
|
|
169
|
+
return;
|
|
170
|
+
const dir = node_path_1.default.dirname(filePath);
|
|
171
|
+
try {
|
|
172
|
+
if (!node_fs_1.default.statSync(dir).isDirectory()) {
|
|
173
|
+
// parent is not a directory
|
|
174
|
+
// This is just to cause an internal ENOTDIR error to be thrown
|
|
175
|
+
node_fs_1.default.readdirSync(dir);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
// If the stat call above failed because the directory doesn't exist, create it
|
|
180
|
+
if (err?.code === 'ENOENT')
|
|
181
|
+
return this.ensureDir(dir);
|
|
182
|
+
throw err;
|
|
183
|
+
}
|
|
184
|
+
node_fs_1.default.writeFileSync(filePath, '');
|
|
185
|
+
}
|
|
186
|
+
async ensureFileAsync(filePath) {
|
|
187
|
+
let stats;
|
|
188
|
+
try {
|
|
189
|
+
stats = await promises_1.default.stat(filePath);
|
|
190
|
+
}
|
|
191
|
+
catch { }
|
|
192
|
+
if (stats?.isFile())
|
|
193
|
+
return;
|
|
194
|
+
const dir = node_path_1.default.dirname(filePath);
|
|
195
|
+
try {
|
|
196
|
+
if (!(await promises_1.default.stat(dir)).isDirectory()) {
|
|
197
|
+
// parent is not a directory
|
|
198
|
+
// This is just to cause an internal ENOTDIR error to be thrown
|
|
199
|
+
await promises_1.default.readdir(dir);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
// If the stat call above failed because the directory doesn't exist, create it
|
|
204
|
+
if (err?.code === 'ENOENT')
|
|
205
|
+
return await this.ensureDirAsync(dir);
|
|
206
|
+
throw err;
|
|
207
|
+
}
|
|
208
|
+
await promises_1.default.writeFile(filePath, '');
|
|
209
|
+
}
|
|
210
|
+
removePath(fileOrDirPath, opt) {
|
|
211
|
+
node_fs_1.default.rmSync(fileOrDirPath, { recursive: true, force: true, ...opt });
|
|
212
|
+
}
|
|
213
|
+
async removePathAsync(fileOrDirPath, opt) {
|
|
214
|
+
await promises_1.default.rm(fileOrDirPath, { recursive: true, force: true, ...opt });
|
|
215
|
+
}
|
|
216
|
+
emptyDir(dirPath) {
|
|
217
|
+
let items;
|
|
218
|
+
try {
|
|
219
|
+
items = node_fs_1.default.readdirSync(dirPath);
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
return this.ensureDir(dirPath);
|
|
223
|
+
}
|
|
224
|
+
items.forEach(item => this.removePath(node_path_1.default.join(dirPath, item)));
|
|
225
|
+
}
|
|
226
|
+
async emptyDirAsync(dirPath) {
|
|
227
|
+
let items;
|
|
228
|
+
try {
|
|
229
|
+
items = await promises_1.default.readdir(dirPath);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
return await this.ensureDirAsync(dirPath);
|
|
233
|
+
}
|
|
234
|
+
await Promise.all(items.map(item => this.removePathAsync(node_path_1.default.join(dirPath, item))));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
238
|
+
*/
|
|
239
|
+
copyPath(src, dest, opt) {
|
|
240
|
+
node_fs_1.default.cpSync(src, dest, {
|
|
241
|
+
recursive: true,
|
|
242
|
+
...opt,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Cautious, underlying Node function is currently Experimental.
|
|
247
|
+
*/
|
|
248
|
+
async copyPathAsync(src, dest, opt) {
|
|
249
|
+
await promises_1.default.cp(src, dest, {
|
|
250
|
+
recursive: true,
|
|
251
|
+
...opt,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
movePath(src, dest, opt) {
|
|
255
|
+
this.copyPath(src, dest, opt);
|
|
256
|
+
this.removePath(src);
|
|
257
|
+
}
|
|
258
|
+
async movePathAsync(src, dest, opt) {
|
|
259
|
+
await this.copyPathAsync(src, dest, opt);
|
|
260
|
+
await this.removePathAsync(src);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
exports.fs2 = new FS2();
|
|
264
|
+
function stringify(data, opt) {
|
|
265
|
+
// If pretty-printing is enabled (spaces) - also add a newline at the end (to match our prettier config)
|
|
266
|
+
return JSON.stringify(data, null, opt?.spaces) + (opt?.spaces ? '\n' : '');
|
|
267
|
+
}
|
package/dist/fs/json2env.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.objectToGithubActionsEnv = exports.objectToShellExport = exports.appendT
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
6
6
|
const colors_1 = require("../colors/colors");
|
|
7
|
-
const
|
|
7
|
+
const fs2_1 = require("./fs2");
|
|
8
8
|
const JSON2ENV_OPT_DEF = {
|
|
9
9
|
saveEnvFile: true,
|
|
10
10
|
bashEnv: true,
|
|
@@ -16,7 +16,7 @@ function json2env(opt) {
|
|
|
16
16
|
...JSON2ENV_OPT_DEF,
|
|
17
17
|
...opt,
|
|
18
18
|
};
|
|
19
|
-
if (!
|
|
19
|
+
if (!fs2_1.fs2.pathExists(jsonPath)) {
|
|
20
20
|
if (fail) {
|
|
21
21
|
throw new Error(`Path doesn't exist: ${jsonPath}`);
|
|
22
22
|
}
|
|
@@ -29,14 +29,14 @@ function json2env(opt) {
|
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
// read file
|
|
32
|
-
const json =
|
|
32
|
+
const json = fs2_1.fs2.readJson(jsonPath);
|
|
33
33
|
if (debug) {
|
|
34
34
|
console.log(json);
|
|
35
35
|
}
|
|
36
36
|
if (saveEnvFile) {
|
|
37
37
|
const shPath = `${jsonPath}.sh`;
|
|
38
38
|
const exportStr = objectToShellExport(json, prefix);
|
|
39
|
-
|
|
39
|
+
fs2_1.fs2.writeFile(shPath, exportStr);
|
|
40
40
|
if (!silent) {
|
|
41
41
|
console.log(`json2env created ${(0, colors_1.dimGrey)(shPath)}:`);
|
|
42
42
|
console.log(exportStr);
|
package/dist/fs/kpy.js
CHANGED
|
@@ -21,12 +21,12 @@ async function kpy(opt) {
|
|
|
21
21
|
const destFilename = node_path_1.default.resolve(opt.outputDir, opt.flat ? basename : filename);
|
|
22
22
|
if (!opt.dry) {
|
|
23
23
|
if (opt.move) {
|
|
24
|
-
await
|
|
24
|
+
await index_1.fs2.movePathAsync(srcFilename, destFilename, {
|
|
25
25
|
force: overwrite,
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
29
|
-
await
|
|
29
|
+
await index_1.fs2.copyPathAsync(srcFilename, destFilename, { force: overwrite });
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
if (opt.verbose) {
|
|
@@ -51,10 +51,10 @@ function kpySync(opt) {
|
|
|
51
51
|
const destFilename = node_path_1.default.resolve(opt.outputDir, opt.flat ? basename : filename);
|
|
52
52
|
if (!opt.dry) {
|
|
53
53
|
if (opt.move) {
|
|
54
|
-
|
|
54
|
+
index_1.fs2.movePath(srcFilename, destFilename, { force: overwrite });
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
|
-
|
|
57
|
+
index_1.fs2.copyPath(srcFilename, destFilename, { force: overwrite });
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
if (opt.verbose) {
|
|
@@ -71,11 +71,11 @@ function kpyPrepare(opt) {
|
|
|
71
71
|
// default to cwd
|
|
72
72
|
opt.baseDir ||= '.';
|
|
73
73
|
opt.outputDir ||= '.';
|
|
74
|
-
if (!
|
|
74
|
+
if (!index_1.fs2.pathExists(opt.baseDir)) {
|
|
75
75
|
console.log(`kpy: baseDir doesn't exist: ${(0, colors_1.boldWhite)(opt.baseDir)}`);
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
index_1.fs2.ensureDir(opt.outputDir);
|
|
79
79
|
}
|
|
80
80
|
function kpyLogFilenames(opt, filenames) {
|
|
81
81
|
if (opt.silent)
|
package/dist/index.d.ts
CHANGED
|
@@ -76,7 +76,7 @@ export * from './validation/joi/joi.validation.error';
|
|
|
76
76
|
export * from './validation/joi/joi.validation.util';
|
|
77
77
|
export * from './script/runScript';
|
|
78
78
|
export * from './jwt/jwt.service';
|
|
79
|
-
export * from './fs/
|
|
79
|
+
export * from './fs/fs2';
|
|
80
80
|
export * from './fs/del';
|
|
81
81
|
export * from './fs/json2env';
|
|
82
82
|
export * from './fs/kpy';
|
package/dist/index.js
CHANGED
|
@@ -80,7 +80,7 @@ tslib_1.__exportStar(require("./validation/joi/joi.validation.error"), exports);
|
|
|
80
80
|
tslib_1.__exportStar(require("./validation/joi/joi.validation.util"), exports);
|
|
81
81
|
tslib_1.__exportStar(require("./script/runScript"), exports);
|
|
82
82
|
tslib_1.__exportStar(require("./jwt/jwt.service"), exports);
|
|
83
|
-
tslib_1.__exportStar(require("./fs/
|
|
83
|
+
tslib_1.__exportStar(require("./fs/fs2"), exports);
|
|
84
84
|
tslib_1.__exportStar(require("./fs/del"), exports);
|
|
85
85
|
tslib_1.__exportStar(require("./fs/json2env"), exports);
|
|
86
86
|
tslib_1.__exportStar(require("./fs/kpy"), exports);
|
|
@@ -27,8 +27,8 @@ function secretsDecrypt(dir, file, encKeyBuffer, del = false, jsonMode = false)
|
|
|
27
27
|
(0, js_lib_1._assert)(filename.endsWith('.json'), `${node_path_1.default.basename(filename)} MUST end with '.json'`);
|
|
28
28
|
(0, js_lib_1._assert)(!filename.endsWith('.plain.json'), `${node_path_1.default.basename(filename)} MUST NOT end with '.plain.json'`);
|
|
29
29
|
plainFilename = filename.replace('.json', '.plain.json');
|
|
30
|
-
const json = (0, crypto_util_1.decryptObject)(
|
|
31
|
-
|
|
30
|
+
const json = (0, crypto_util_1.decryptObject)(index_1.fs2.readJson(filename), encKeyBuffer);
|
|
31
|
+
index_1.fs2.writeJson(plainFilename, json, { spaces: 2 });
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
34
|
const enc = node_fs_1.default.readFileSync(filename);
|
|
@@ -25,8 +25,8 @@ function secretsEncrypt(pattern, file, encKeyBuffer, del = false, jsonMode = fal
|
|
|
25
25
|
if (jsonMode) {
|
|
26
26
|
(0, js_lib_1._assert)(filename.endsWith('.plain.json'), `${node_path_1.default.basename(filename)} MUST end with '.plain.json'`);
|
|
27
27
|
encFilename = filename.replace('.plain', '');
|
|
28
|
-
const json = (0, crypto_util_1.encryptObject)(
|
|
29
|
-
|
|
28
|
+
const json = (0, crypto_util_1.encryptObject)(index_1.fs2.readJson(filename), encKeyBuffer);
|
|
29
|
+
index_1.fs2.writeJson(encFilename, json, { spaces: 2 });
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
32
32
|
const plain = node_fs_1.default.readFileSync(filename);
|
|
@@ -16,12 +16,12 @@ const transformToNDJson_1 = require("./transformToNDJson");
|
|
|
16
16
|
*/
|
|
17
17
|
async function pipelineToNDJsonFile(streams, opt) {
|
|
18
18
|
const { filePath, gzip, protectFromOverwrite = false } = opt;
|
|
19
|
-
if (protectFromOverwrite &&
|
|
19
|
+
if (protectFromOverwrite && __1.fs2.pathExists(filePath)) {
|
|
20
20
|
throw new js_lib_1.AppError(`pipelineToNDJsonFile: output file exists: ${filePath}`);
|
|
21
21
|
}
|
|
22
22
|
const started = Date.now();
|
|
23
23
|
let rows = 0;
|
|
24
|
-
|
|
24
|
+
__1.fs2.ensureFile(filePath);
|
|
25
25
|
console.log(`>> ${(0, colors_1.grey)(filePath)} started...`);
|
|
26
26
|
await (0, __1._pipeline)([
|
|
27
27
|
...streams,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateBuildInfo = void 0;
|
|
4
4
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
|
-
const
|
|
5
|
+
const fs2_1 = require("../fs/fs2");
|
|
6
6
|
const git_util_1 = require("./git.util");
|
|
7
7
|
function generateBuildInfo(opt = {}) {
|
|
8
8
|
const now = (0, js_lib_1.localTimeOrNow)(opt.overrideTimestamp);
|
|
@@ -16,8 +16,8 @@ function generateBuildInfo(opt = {}) {
|
|
|
16
16
|
if (!env) {
|
|
17
17
|
// Attempt to read `envByBranch` from package.json root
|
|
18
18
|
try {
|
|
19
|
-
if (
|
|
20
|
-
const packageJson =
|
|
19
|
+
if (fs2_1.fs2.pathExists('package.json')) {
|
|
20
|
+
const packageJson = fs2_1.fs2.readJson('package.json');
|
|
21
21
|
env = packageJson?.['envByBranch']?.[branchName] || packageJson?.['envByBranch']?.['*'];
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -12,7 +12,7 @@ const ajvSchema_1 = require("./ajvSchema");
|
|
|
12
12
|
* @experimental
|
|
13
13
|
*/
|
|
14
14
|
function readJsonSchemas(patterns, opt) {
|
|
15
|
-
return __1.fastGlob.sync(patterns, opt).map(fileName =>
|
|
15
|
+
return __1.fastGlob.sync(patterns, opt).map(fileName => __1.fs2.readJson(fileName));
|
|
16
16
|
}
|
|
17
17
|
exports.readJsonSchemas = readJsonSchemas;
|
|
18
18
|
/**
|
|
@@ -59,7 +59,7 @@ class AjvSchema {
|
|
|
59
59
|
*/
|
|
60
60
|
static readJsonSync(filePath, cfg = {}) {
|
|
61
61
|
(0, index_1.requireFileToExist)(filePath);
|
|
62
|
-
const schema =
|
|
62
|
+
const schema = index_1.fs2.readJson(filePath);
|
|
63
63
|
return new AjvSchema(schema, cfg);
|
|
64
64
|
}
|
|
65
65
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/nodejs-lib",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.6.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky install",
|
|
6
6
|
"docs-serve": "vuepress dev docs",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@naturalcycles/js-lib": "^14.0.0",
|
|
18
|
+
"@types/js-yaml": "^4.0.9",
|
|
18
19
|
"@types/jsonwebtoken": "^9.0.0",
|
|
19
20
|
"@types/through2-concurrent": "^2.0.0",
|
|
20
21
|
"ajv": "^8.6.2",
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
"fast-glob": "^3.2.11",
|
|
28
29
|
"globby": "^11.0.0",
|
|
29
30
|
"joi": "^17.9.2",
|
|
31
|
+
"js-yaml": "^4.1.0",
|
|
30
32
|
"jsonwebtoken": "^9.0.0",
|
|
31
33
|
"lru-cache": "^10.0.0",
|
|
32
34
|
"through2-concurrent": "^2.0.0",
|