@datatruck/cli 0.31.0 → 0.32.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/Action/BackupAction.js +4 -8
- package/Action/ConfigAction.d.ts +1 -0
- package/Action/ConfigAction.js +8 -7
- package/Action/CopyAction.js +1 -1
- package/Action/RestoreAction.js +1 -1
- package/CHANGELOG.md +14 -0
- package/Command/StartServerCommand.js +1 -0
- package/Task/ScriptTask.d.ts +2 -11
- package/Task/ScriptTask.js +27 -33
- package/config.schema.json +38 -1
- package/package.json +4 -4
- package/pkg.d.ts +6 -0
- package/pkg.js +10 -0
- package/utils/cli.d.ts +1 -1
- package/utils/cli.js +2 -2
- package/utils/datatruck/paths.js +4 -6
- package/utils/datatruck/repository-server.d.ts +2 -1
- package/utils/datatruck/repository-server.js +6 -1
- package/utils/fs.js +19 -18
- package/utils/steps.d.ts +10 -10
- package/utils/steps.js +22 -8
- package/utils/string.js +21 -5
package/Action/BackupAction.js
CHANGED
|
@@ -117,7 +117,7 @@ class BackupAction {
|
|
|
117
117
|
backups: result.filter((r) => !r.error && r.key === "backup")
|
|
118
118
|
.length,
|
|
119
119
|
copies: result.filter((r) => !r.error && r.key === "copy").length,
|
|
120
|
-
})
|
|
120
|
+
}, color)
|
|
121
121
|
: item.key === "report"
|
|
122
122
|
? item.data.type
|
|
123
123
|
: "";
|
|
@@ -312,14 +312,10 @@ class BackupAction {
|
|
|
312
312
|
return task.skip(`Report send skipped: ${reportIndex}`);
|
|
313
313
|
const text = this.dataFormat(result).format(report.format ?? "list");
|
|
314
314
|
await (0, steps_1.runSteps)(report.run, {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
telegram: { vars: { TEXT: text } },
|
|
318
|
-
node: {
|
|
319
|
-
vars: {
|
|
320
|
-
dtt: { report: text, result },
|
|
321
|
-
},
|
|
315
|
+
vars: {
|
|
316
|
+
dtt: { title: "DTT Backup", text, result, success },
|
|
322
317
|
},
|
|
318
|
+
verbose: this.options.verbose,
|
|
323
319
|
});
|
|
324
320
|
},
|
|
325
321
|
});
|
package/Action/ConfigAction.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare class ConfigAction<TRequired extends boolean = true> {
|
|
|
11
11
|
static validate(config: ConfigType): void;
|
|
12
12
|
static check(config: ConfigType): void;
|
|
13
13
|
static normalize(config: ConfigType): ConfigType;
|
|
14
|
+
static parseFile(path: string): Promise<ConfigType>;
|
|
14
15
|
static fromGlobalOptionsWithPath(globalOptions: GlobalOptions<true>): Promise<{
|
|
15
16
|
path: string;
|
|
16
17
|
data: ConfigType;
|
package/Action/ConfigAction.js
CHANGED
|
@@ -63,6 +63,12 @@ class ConfigAction {
|
|
|
63
63
|
});
|
|
64
64
|
return config;
|
|
65
65
|
}
|
|
66
|
+
static async parseFile(path) {
|
|
67
|
+
const config = await (0, fs_1.parseFile)(path, "config");
|
|
68
|
+
ConfigAction.validate(config);
|
|
69
|
+
ConfigAction.check(config);
|
|
70
|
+
return ConfigAction.normalize(config);
|
|
71
|
+
}
|
|
66
72
|
static async fromGlobalOptionsWithPath(globalOptions) {
|
|
67
73
|
if (typeof globalOptions.config !== "string")
|
|
68
74
|
return {
|
|
@@ -81,13 +87,8 @@ class ConfigAction {
|
|
|
81
87
|
}
|
|
82
88
|
async exec() {
|
|
83
89
|
const path = await (0, fs_1.findFile)(this.options.path, "datatruck.config", fs_1.parseFileExtensions, "Config path not found");
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
ConfigAction.check(config);
|
|
87
|
-
return {
|
|
88
|
-
path,
|
|
89
|
-
data: ConfigAction.normalize(config),
|
|
90
|
-
};
|
|
90
|
+
const data = await ConfigAction.parseFile(path);
|
|
91
|
+
return { path, data };
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
exports.ConfigAction = ConfigAction;
|
package/Action/CopyAction.js
CHANGED
|
@@ -40,7 +40,7 @@ class CopyAction {
|
|
|
40
40
|
errors: item.data.errors,
|
|
41
41
|
copied: items.filter((i) => i.key === "copy" && !i.error && !i.data.skipped).length,
|
|
42
42
|
skipped: items.filter((i) => i.key === "copy" && !i.error && i.data.skipped).length,
|
|
43
|
-
})
|
|
43
|
+
}, color)
|
|
44
44
|
: "";
|
|
45
45
|
};
|
|
46
46
|
return new DataFormat_1.DataFormat({
|
package/Action/RestoreAction.js
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @datatruck/cli
|
|
2
2
|
|
|
3
|
+
## 0.32.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`7d755ba`](https://github.com/swordev/datatruck/commit/7d755bac0edf7aea719446f6bfcee5bea0fe9a90) Thanks [@juanrgm](https://github.com/juanrgm)! - Reload repository server config
|
|
8
|
+
|
|
9
|
+
- [`9dba106`](https://github.com/swordev/datatruck/commit/9dba106865da2d4327282d65deecee5a03e49b49) Thanks [@juanrgm](https://github.com/juanrgm)! - Update to Node.js 20
|
|
10
|
+
|
|
11
|
+
- [`113ee82`](https://github.com/swordev/datatruck/commit/113ee8258951028d54b798eaaa813982222c20e8) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `ntfy` step
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`c24eea2`](https://github.com/swordev/datatruck/commit/c24eea21b41d78451d5eabd65923daa26dcad78a) Thanks [@juanrgm](https://github.com/juanrgm)! - Simplify step configs
|
|
16
|
+
|
|
3
17
|
## 0.31.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -17,6 +17,7 @@ class StartServerCommand extends CommandAbstract_1.CommandAbstract {
|
|
|
17
17
|
if (repositoryOptions.enabled ?? true) {
|
|
18
18
|
const server = (0, repository_server_1.createDatatruckRepositoryServer)(repositoryOptions, {
|
|
19
19
|
log,
|
|
20
|
+
configPath: this.configPath,
|
|
20
21
|
});
|
|
21
22
|
const port = repositoryOptions.listen?.port ?? 8888;
|
|
22
23
|
const address = repositoryOptions.listen?.address ?? "127.0.0.1";
|
package/Task/ScriptTask.d.ts
CHANGED
|
@@ -20,22 +20,13 @@ export declare enum ScriptTaskDefinitionEnum {
|
|
|
20
20
|
step = "step",
|
|
21
21
|
processStepConfig = "processStepConfig",
|
|
22
22
|
nodeStepConfig = "nodeStepConfig",
|
|
23
|
-
telegramMessageStepConfig = "telegramMessageStepConfig"
|
|
23
|
+
telegramMessageStepConfig = "telegramMessageStepConfig",
|
|
24
|
+
ntfyStepConfig = "ntfyStepConfig"
|
|
24
25
|
}
|
|
25
26
|
export declare const scriptTaskName = "script";
|
|
26
27
|
export declare const scriptTaskDefinition: JSONSchema7;
|
|
27
28
|
export declare class ScriptTask extends TaskAbstract<ScriptTaskConfigType> {
|
|
28
29
|
protected verbose?: boolean;
|
|
29
|
-
protected getVars(data: TaskBackupData | TaskRestoreData): {
|
|
30
|
-
process: {
|
|
31
|
-
DTT_SNAPSHOT_ID: string;
|
|
32
|
-
DTT_SNAPSHOT_DATE: string;
|
|
33
|
-
DTT_PACKAGE_NAME: string;
|
|
34
|
-
DTT_PACKAGE_PATH: string | undefined;
|
|
35
|
-
DTT_SNAPSHOT_PATH: string | undefined;
|
|
36
|
-
};
|
|
37
|
-
node: NodeVars;
|
|
38
|
-
};
|
|
39
30
|
backup(data: TaskBackupData): Promise<{
|
|
40
31
|
snapshotPath: string;
|
|
41
32
|
}>;
|
package/Task/ScriptTask.js
CHANGED
|
@@ -15,11 +15,13 @@ var ScriptTaskDefinitionEnum;
|
|
|
15
15
|
ScriptTaskDefinitionEnum["processStepConfig"] = "processStepConfig";
|
|
16
16
|
ScriptTaskDefinitionEnum["nodeStepConfig"] = "nodeStepConfig";
|
|
17
17
|
ScriptTaskDefinitionEnum["telegramMessageStepConfig"] = "telegramMessageStepConfig";
|
|
18
|
+
ScriptTaskDefinitionEnum["ntfyStepConfig"] = "ntfyStepConfig";
|
|
18
19
|
})(ScriptTaskDefinitionEnum || (exports.ScriptTaskDefinitionEnum = ScriptTaskDefinitionEnum = {}));
|
|
19
20
|
const stepTypes = {
|
|
20
21
|
process: ScriptTaskDefinitionEnum.processStepConfig,
|
|
21
22
|
node: ScriptTaskDefinitionEnum.nodeStepConfig,
|
|
22
23
|
"telegram-message": ScriptTaskDefinitionEnum.telegramMessageStepConfig,
|
|
24
|
+
ntfy: ScriptTaskDefinitionEnum.ntfyStepConfig,
|
|
23
25
|
};
|
|
24
26
|
exports.scriptTaskName = "script";
|
|
25
27
|
exports.scriptTaskDefinition = {
|
|
@@ -85,6 +87,15 @@ exports.scriptTaskDefinition = {
|
|
|
85
87
|
text: { type: "string" },
|
|
86
88
|
},
|
|
87
89
|
},
|
|
90
|
+
ntfyStepConfig: {
|
|
91
|
+
type: "object",
|
|
92
|
+
required: ["token"],
|
|
93
|
+
properties: {
|
|
94
|
+
token: { type: "string" },
|
|
95
|
+
topic: { type: "string" },
|
|
96
|
+
text: { type: "string" },
|
|
97
|
+
},
|
|
98
|
+
},
|
|
88
99
|
},
|
|
89
100
|
type: "object",
|
|
90
101
|
additionalProperties: false,
|
|
@@ -108,41 +119,22 @@ exports.scriptTaskDefinition = {
|
|
|
108
119
|
};
|
|
109
120
|
class ScriptTask extends TaskAbstract_1.TaskAbstract {
|
|
110
121
|
verbose;
|
|
111
|
-
getVars(data) {
|
|
112
|
-
return {
|
|
113
|
-
process: {
|
|
114
|
-
DTT_SNAPSHOT_ID: data.snapshot.id,
|
|
115
|
-
DTT_SNAPSHOT_DATE: data.snapshot.date,
|
|
116
|
-
DTT_PACKAGE_NAME: data.package.name,
|
|
117
|
-
DTT_PACKAGE_PATH: data.package.path,
|
|
118
|
-
DTT_SNAPSHOT_PATH: data.snapshotPath,
|
|
119
|
-
},
|
|
120
|
-
node: {
|
|
121
|
-
dtt: {
|
|
122
|
-
snapshot: data.snapshot,
|
|
123
|
-
package: data.package,
|
|
124
|
-
snapshotPath: data.snapshotPath,
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
122
|
async backup(data) {
|
|
130
123
|
const config = this.config;
|
|
131
124
|
const snapshotPath = data.package.path ??
|
|
132
125
|
(await (0, temp_1.mkTmpDir)(exports.scriptTaskName, "task", "backup", "snapshot"));
|
|
133
|
-
const vars = this.getVars({
|
|
134
|
-
...data,
|
|
135
|
-
snapshotPath,
|
|
136
|
-
});
|
|
137
126
|
await (0, steps_1.runSteps)(config.backupSteps, {
|
|
138
127
|
env: config.env,
|
|
128
|
+
vars: {
|
|
129
|
+
dtt: {
|
|
130
|
+
snapshot: data.snapshot,
|
|
131
|
+
snapshotPath: snapshotPath,
|
|
132
|
+
package: data.package,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
139
135
|
cwd: snapshotPath,
|
|
140
136
|
verbose: data.options.verbose,
|
|
141
|
-
|
|
142
|
-
node: {
|
|
143
|
-
tempDir: () => (0, temp_1.mkTmpDir)(exports.scriptTaskName, "task", "backup", "nodeStep"),
|
|
144
|
-
vars: vars.node,
|
|
145
|
-
},
|
|
137
|
+
tempDir: () => (0, temp_1.mkTmpDir)(exports.scriptTaskName, "task", "backup", "nodeStep"),
|
|
146
138
|
});
|
|
147
139
|
return { snapshotPath };
|
|
148
140
|
}
|
|
@@ -154,15 +146,17 @@ class ScriptTask extends TaskAbstract_1.TaskAbstract {
|
|
|
154
146
|
}
|
|
155
147
|
async restore(data) {
|
|
156
148
|
const config = this.config;
|
|
157
|
-
const vars = this.getVars(data);
|
|
158
149
|
await (0, steps_1.runSteps)(config.restoreSteps, {
|
|
159
150
|
env: config.env,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
151
|
+
vars: {
|
|
152
|
+
dtt: {
|
|
153
|
+
snapshot: data.snapshot,
|
|
154
|
+
snapshotPath: data.snapshotPath,
|
|
155
|
+
package: data.package,
|
|
156
|
+
},
|
|
165
157
|
},
|
|
158
|
+
verbose: data.options.verbose,
|
|
159
|
+
tempDir: () => (0, temp_1.mkTmpDir)(exports.scriptTaskName, "task", "restore", "nodeStep"),
|
|
166
160
|
});
|
|
167
161
|
}
|
|
168
162
|
}
|
package/config.schema.json
CHANGED
|
@@ -1346,7 +1346,8 @@
|
|
|
1346
1346
|
"enum": [
|
|
1347
1347
|
"process",
|
|
1348
1348
|
"node",
|
|
1349
|
-
"telegram-message"
|
|
1349
|
+
"telegram-message",
|
|
1350
|
+
"ntfy"
|
|
1350
1351
|
]
|
|
1351
1352
|
},
|
|
1352
1353
|
"config": {}
|
|
@@ -1408,6 +1409,25 @@
|
|
|
1408
1409
|
}
|
|
1409
1410
|
},
|
|
1410
1411
|
"else": false
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
"if": {
|
|
1415
|
+
"type": "object",
|
|
1416
|
+
"properties": {
|
|
1417
|
+
"type": {
|
|
1418
|
+
"const": "ntfy"
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
},
|
|
1422
|
+
"then": {
|
|
1423
|
+
"type": "object",
|
|
1424
|
+
"properties": {
|
|
1425
|
+
"config": {
|
|
1426
|
+
"$ref": "#/definitions/script-task_ntfyStepConfig"
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
},
|
|
1430
|
+
"else": false
|
|
1411
1431
|
}
|
|
1412
1432
|
]
|
|
1413
1433
|
},
|
|
@@ -1482,6 +1502,23 @@
|
|
|
1482
1502
|
"type": "string"
|
|
1483
1503
|
}
|
|
1484
1504
|
}
|
|
1505
|
+
},
|
|
1506
|
+
"script-task_ntfyStepConfig": {
|
|
1507
|
+
"type": "object",
|
|
1508
|
+
"required": [
|
|
1509
|
+
"token"
|
|
1510
|
+
],
|
|
1511
|
+
"properties": {
|
|
1512
|
+
"token": {
|
|
1513
|
+
"type": "string"
|
|
1514
|
+
},
|
|
1515
|
+
"topic": {
|
|
1516
|
+
"type": "string"
|
|
1517
|
+
},
|
|
1518
|
+
"text": {
|
|
1519
|
+
"type": "string"
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1485
1522
|
}
|
|
1486
1523
|
},
|
|
1487
1524
|
"$ref": "#/definitions/config"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datatruck/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@supercharge/promise-pool": "^3.1.0",
|
|
6
6
|
"ajv": "^8.12.0",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
"listr2": "^7.0.1",
|
|
15
15
|
"micromatch": "^4.0.5",
|
|
16
16
|
"mysql2": "^3.6.1",
|
|
17
|
-
"tty-table": "^4.2.2"
|
|
17
|
+
"tty-table": "^4.2.2",
|
|
18
|
+
"yaml": "^2.3.2"
|
|
18
19
|
},
|
|
19
20
|
"optionalDependencies": {
|
|
20
|
-
"ts-node": "^10.9.1"
|
|
21
|
-
"yaml": "^2.3.2"
|
|
21
|
+
"ts-node": "^10.9.1"
|
|
22
22
|
},
|
|
23
23
|
"engine": {
|
|
24
24
|
"node": ">=16.0.0"
|
package/pkg.d.ts
ADDED
package/pkg.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.pkg = void 0;
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
const package_json_1 = __importDefault(require("./../package.json"));
|
|
9
|
+
const pkg = package_json_1.default;
|
|
10
|
+
exports.pkg = pkg;
|
package/utils/cli.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare function renderProgressBar(progress: number, size?: number, subpr
|
|
|
4
4
|
export declare function logExec(command: string, argv?: string[], env?: NodeJS.ProcessEnv, logToStderr?: boolean): void;
|
|
5
5
|
export declare function renderResult(error: Error | null | string | boolean | undefined, color?: boolean): string;
|
|
6
6
|
export declare function renderError(error: Error | null | string | undefined, verbose?: number): string;
|
|
7
|
-
export declare function renderObject(object: Record<string, any
|
|
7
|
+
export declare function renderObject(object: Record<string, any>, color?: boolean): string;
|
|
8
8
|
export type OptionsType<T1, T2 extends {
|
|
9
9
|
[K in keyof T1]: unknown;
|
|
10
10
|
}> = {
|
package/utils/cli.js
CHANGED
|
@@ -75,10 +75,10 @@ function renderError(error, verbose) {
|
|
|
75
75
|
return chalk_1.default.red(message.trim());
|
|
76
76
|
}
|
|
77
77
|
exports.renderError = renderError;
|
|
78
|
-
function renderObject(object) {
|
|
78
|
+
function renderObject(object, color) {
|
|
79
79
|
const values = [];
|
|
80
80
|
for (const key in object)
|
|
81
|
-
values.push(`${key}: ${(0, chalk_2.grey)(object[key])}`);
|
|
81
|
+
values.push(`${key}: ${color ? (0, chalk_2.grey)(object[key]) : object[key]}`);
|
|
82
82
|
return values.join(` `);
|
|
83
83
|
}
|
|
84
84
|
exports.renderObject = renderObject;
|
package/utils/datatruck/paths.js
CHANGED
|
@@ -10,7 +10,7 @@ async function parsePaths(values, options) {
|
|
|
10
10
|
}
|
|
11
11
|
else {
|
|
12
12
|
await (0, steps_1.runSteps)(value, {
|
|
13
|
-
|
|
13
|
+
tempDir: options.tempDir,
|
|
14
14
|
verbose: options.verbose,
|
|
15
15
|
onLine: (path) => paths.push(path),
|
|
16
16
|
});
|
|
@@ -24,11 +24,9 @@ async function parseBackupPaths(paths, options) {
|
|
|
24
24
|
cwd: options.path,
|
|
25
25
|
verbose: options.verbose,
|
|
26
26
|
vars: {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
path: options.path,
|
|
31
|
-
},
|
|
27
|
+
package: options.package,
|
|
28
|
+
snapshot: options.snapshot,
|
|
29
|
+
path: options.path,
|
|
32
30
|
},
|
|
33
31
|
});
|
|
34
32
|
}
|
|
@@ -31,7 +31,8 @@ export declare const headerKey: {
|
|
|
31
31
|
user: string;
|
|
32
32
|
password: string;
|
|
33
33
|
};
|
|
34
|
-
export declare function createDatatruckRepositoryServer(
|
|
34
|
+
export declare function createDatatruckRepositoryServer(inOptions: Omit<DatatruckRepositoryServerOptions, "listen">, config?: {
|
|
35
35
|
log?: boolean;
|
|
36
|
+
configPath?: string;
|
|
36
37
|
}): import("node:http").Server<typeof IncomingMessage, typeof import("node:http").ServerResponse>;
|
|
37
38
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createDatatruckRepositoryServer = exports.headerKey = void 0;
|
|
4
|
+
const ConfigAction_1 = require("../../Action/ConfigAction");
|
|
4
5
|
const http_1 = require("../http");
|
|
5
6
|
const virtual_fs_1 = require("../virtual-fs");
|
|
6
7
|
const fs_1 = require("fs");
|
|
@@ -55,7 +56,7 @@ const getRemoteAddress = (req, options) => {
|
|
|
55
56
|
: req.headers[options.trustProxy.remoteAddressHeader]?.toString()
|
|
56
57
|
: undefined) ?? req.socket.remoteAddress);
|
|
57
58
|
};
|
|
58
|
-
function createDatatruckRepositoryServer(
|
|
59
|
+
function createDatatruckRepositoryServer(inOptions, config = {}) {
|
|
59
60
|
return (0, http_2.createServer)(async (req, res) => {
|
|
60
61
|
try {
|
|
61
62
|
if (req.url === "/" || req.url === "/favicon.ico")
|
|
@@ -65,6 +66,10 @@ function createDatatruckRepositoryServer(options, config = {}) {
|
|
|
65
66
|
res.statusCode = 404;
|
|
66
67
|
return res.end();
|
|
67
68
|
}
|
|
69
|
+
const fileOptions = config.configPath
|
|
70
|
+
? (await ConfigAction_1.ConfigAction.parseFile(config.configPath)).server?.repository
|
|
71
|
+
: undefined;
|
|
72
|
+
const options = fileOptions ?? inOptions;
|
|
68
73
|
const backend = findRepositoryBackend(req, repository, options);
|
|
69
74
|
if (!backend) {
|
|
70
75
|
res.statusCode = 401;
|
package/utils/fs.js
CHANGED
|
@@ -4,9 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.asFile = exports.groupFiles = exports.ensureFreeDiskSpace = exports.checkFreeDiskSpace = exports.fetchDiskStats = exports.initEmptyDir = exports.tryRm = exports.safeRename = exports.fetchData = exports.countFileLines = exports.createWriteStreamPool = exports.createFileScanner = exports.createProgress = exports.cpy = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.waitForClose = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.readPartialFile = exports.fastFolderSizeAsync = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.parseFileExtensions = exports.writeJSONFile = exports.existsFile = exports.existsDir = exports.safeStat = exports.ensureExistsDir = exports.ensureSingleFile = exports.ensureEmptyDir = exports.mkdirIfNotExists = exports.isLocalDir = exports.isEmptyDir = exports.isWSLSystem = void 0;
|
|
7
|
+
const pkg_1 = require("../pkg");
|
|
7
8
|
const bytes_1 = require("./bytes");
|
|
8
9
|
const math_1 = require("./math");
|
|
9
|
-
const path_1 = require("./path");
|
|
10
10
|
const string_1 = require("./string");
|
|
11
11
|
const temp_1 = require("./temp");
|
|
12
12
|
const async_1 = require("async");
|
|
@@ -16,8 +16,8 @@ const fs_1 = require("fs");
|
|
|
16
16
|
const fs_2 = require("fs");
|
|
17
17
|
const promises_1 = require("fs/promises");
|
|
18
18
|
const os_1 = require("os");
|
|
19
|
+
const path_1 = require("path");
|
|
19
20
|
const path_2 = require("path");
|
|
20
|
-
const path_3 = require("path");
|
|
21
21
|
const readline_1 = require("readline");
|
|
22
22
|
const util_1 = require("util");
|
|
23
23
|
exports.isWSLSystem = (0, os_1.release)().includes("microsoft-standard-WSL");
|
|
@@ -59,12 +59,12 @@ async function ensureSingleFile(path) {
|
|
|
59
59
|
if (files.length !== 1)
|
|
60
60
|
throw new Error(`Dir has not one file: ${files.length}`);
|
|
61
61
|
const [file] = files;
|
|
62
|
-
return (0,
|
|
62
|
+
return (0, path_1.join)(path, file);
|
|
63
63
|
}
|
|
64
64
|
exports.ensureSingleFile = ensureSingleFile;
|
|
65
65
|
async function ensureExistsDir(path) {
|
|
66
66
|
if (!(await existsDir(path)))
|
|
67
|
-
throw new Error(`Dir is not
|
|
67
|
+
throw new Error(`Dir is not created: ${path}`);
|
|
68
68
|
}
|
|
69
69
|
exports.ensureExistsDir = ensureExistsDir;
|
|
70
70
|
async function safeStat(path) {
|
|
@@ -88,10 +88,11 @@ async function writeJSONFile(path, json) {
|
|
|
88
88
|
exports.writeJSONFile = writeJSONFile;
|
|
89
89
|
exports.parseFileExtensions = ["json", "js", "ts", "yaml", "yml"];
|
|
90
90
|
async function parseFile(path, jsKey) {
|
|
91
|
-
if (!(0,
|
|
92
|
-
path = (0,
|
|
91
|
+
if (!(0, path_2.isAbsolute)(path))
|
|
92
|
+
path = (0, path_1.join)(process.cwd(), path);
|
|
93
|
+
const $require = require;
|
|
93
94
|
if (path.endsWith(".ts"))
|
|
94
|
-
require("ts-node").register();
|
|
95
|
+
$require("ts-node").register();
|
|
95
96
|
if (path.endsWith(".yaml") || path.endsWith("yml")) {
|
|
96
97
|
const contents = await (0, promises_1.readFile)(path);
|
|
97
98
|
return require("yaml").parse(contents.toString());
|
|
@@ -107,7 +108,7 @@ async function parseFile(path, jsKey) {
|
|
|
107
108
|
}
|
|
108
109
|
exports.parseFile = parseFile;
|
|
109
110
|
function parsePackageFile() {
|
|
110
|
-
return
|
|
111
|
+
return pkg_1.pkg;
|
|
111
112
|
}
|
|
112
113
|
exports.parsePackageFile = parsePackageFile;
|
|
113
114
|
async function findFile(sourcePath, baseName, extensions, errorMessage = "Path not found") {
|
|
@@ -115,7 +116,7 @@ async function findFile(sourcePath, baseName, extensions, errorMessage = "Path n
|
|
|
115
116
|
let path;
|
|
116
117
|
if (info.isDirectory()) {
|
|
117
118
|
for (const ext of extensions) {
|
|
118
|
-
const extPath = (0,
|
|
119
|
+
const extPath = (0, path_1.join)(sourcePath, baseName) + "." + ext;
|
|
119
120
|
if (await existsFile(extPath)) {
|
|
120
121
|
path = extPath;
|
|
121
122
|
break;
|
|
@@ -183,7 +184,7 @@ exports.readDir = readDir;
|
|
|
183
184
|
async function forEachFile(dirPath, cb, includeDir) {
|
|
184
185
|
const files = await readDir(dirPath);
|
|
185
186
|
for (const file of files) {
|
|
186
|
-
const filePath = (0,
|
|
187
|
+
const filePath = (0, path_1.join)(dirPath, file);
|
|
187
188
|
if ((await (0, promises_1.stat)(filePath)).isDirectory()) {
|
|
188
189
|
if (includeDir)
|
|
189
190
|
cb(filePath, true);
|
|
@@ -206,12 +207,12 @@ function fastglobToGitIgnore(patterns, baseDir) {
|
|
|
206
207
|
exports.fastglobToGitIgnore = fastglobToGitIgnore;
|
|
207
208
|
async function writeGitIgnoreList(options) {
|
|
208
209
|
const { outDir } = options;
|
|
209
|
-
const path = (0,
|
|
210
|
+
const path = (0, path_1.join)(outDir, `.gitignore`);
|
|
210
211
|
const stream = (0, fs_2.createWriteStream)(path);
|
|
211
212
|
const dirs = new Set();
|
|
212
213
|
stream.write("*\n");
|
|
213
214
|
for await (const value of options.paths) {
|
|
214
|
-
const dir = (0,
|
|
215
|
+
const dir = (0, path_1.dirname)(value.toString());
|
|
215
216
|
if (dir !== ".") {
|
|
216
217
|
let parentPath;
|
|
217
218
|
for (const value of dir.split("/")) {
|
|
@@ -290,9 +291,9 @@ async function cpy(options) {
|
|
|
290
291
|
const task = async (rawEntryPath, basePath) => {
|
|
291
292
|
[rawEntryPath] = rawEntryPath.split(":");
|
|
292
293
|
const isDir = rawEntryPath.endsWith("/");
|
|
293
|
-
const entryPath = (0,
|
|
294
|
-
const entrySourcePath = (0,
|
|
295
|
-
const entryTargetPath = (0,
|
|
294
|
+
const entryPath = (0, path_1.normalize)(rawEntryPath);
|
|
295
|
+
const entrySourcePath = (0, path_1.resolve)((0, path_1.join)(basePath, rawEntryPath));
|
|
296
|
+
const entryTargetPath = (0, path_1.resolve)((0, path_1.join)(options.outPath, rawEntryPath));
|
|
296
297
|
const onPathResult = await options?.onPath?.({
|
|
297
298
|
isDir,
|
|
298
299
|
entryPath,
|
|
@@ -307,7 +308,7 @@ async function cpy(options) {
|
|
|
307
308
|
await makeRecursiveDir(entryTargetPath);
|
|
308
309
|
}
|
|
309
310
|
else {
|
|
310
|
-
const dir = (0,
|
|
311
|
+
const dir = (0, path_1.dirname)(entryTargetPath);
|
|
311
312
|
await makeRecursiveDir(dir);
|
|
312
313
|
await options.onProgress?.({
|
|
313
314
|
current: stats.files,
|
|
@@ -447,7 +448,7 @@ function createWriteStreamPool(options) {
|
|
|
447
448
|
const item = {
|
|
448
449
|
key,
|
|
449
450
|
lines: 0,
|
|
450
|
-
stream: (0, fs_2.createWriteStream)((0,
|
|
451
|
+
stream: (0, fs_2.createWriteStream)((0, path_1.join)(options.path, options.onStreamPath ? options.onStreamPath(key) : key)),
|
|
451
452
|
finished: false,
|
|
452
453
|
};
|
|
453
454
|
item.stream
|
|
@@ -612,7 +613,7 @@ exports.groupFiles = groupFiles;
|
|
|
612
613
|
async function asFile(input) {
|
|
613
614
|
if (typeof input === "string") {
|
|
614
615
|
const dir = await (0, temp_1.mkTmpDir)("text-as-file");
|
|
615
|
-
const path = (0,
|
|
616
|
+
const path = (0, path_1.join)(dir, "contents.txt");
|
|
616
617
|
await (0, promises_1.writeFile)(path, input);
|
|
617
618
|
return [
|
|
618
619
|
path,
|
package/utils/steps.d.ts
CHANGED
|
@@ -14,6 +14,11 @@ export type TelegramMessageStepConfig = {
|
|
|
14
14
|
chatId: number;
|
|
15
15
|
text?: string;
|
|
16
16
|
};
|
|
17
|
+
export type NtfyStepConfig = {
|
|
18
|
+
token: string;
|
|
19
|
+
topic?: string;
|
|
20
|
+
text?: string;
|
|
21
|
+
};
|
|
17
22
|
export type Step = {
|
|
18
23
|
type: "process";
|
|
19
24
|
config: ProcessStepConfig;
|
|
@@ -23,20 +28,15 @@ export type Step = {
|
|
|
23
28
|
} | {
|
|
24
29
|
type: "telegram-message";
|
|
25
30
|
config: TelegramMessageStepConfig;
|
|
31
|
+
} | {
|
|
32
|
+
type: "ntfy";
|
|
33
|
+
config: NtfyStepConfig;
|
|
26
34
|
};
|
|
27
35
|
export type StepOptions = {
|
|
28
36
|
env?: Record<string, string | undefined>;
|
|
29
|
-
|
|
30
|
-
vars?: Record<string, string | undefined>;
|
|
31
|
-
};
|
|
32
|
-
node?: {
|
|
33
|
-
vars?: Record<string, any>;
|
|
34
|
-
tempDir?: () => Promise<string>;
|
|
35
|
-
};
|
|
36
|
-
telegram?: {
|
|
37
|
-
vars?: Record<string, string>;
|
|
38
|
-
};
|
|
37
|
+
vars?: Record<string, any>;
|
|
39
38
|
cwd?: string;
|
|
39
|
+
tempDir?: () => Promise<string>;
|
|
40
40
|
onLine?: (p: string) => any;
|
|
41
41
|
verbose?: boolean;
|
|
42
42
|
};
|
package/utils/steps.js
CHANGED
|
@@ -9,9 +9,10 @@ const promises_1 = require("fs/promises");
|
|
|
9
9
|
const path_1 = require("path");
|
|
10
10
|
async function runSteps(input, options) {
|
|
11
11
|
const steps = Array.isArray(input) ? input : [input];
|
|
12
|
+
const vars = options?.vars || {};
|
|
12
13
|
for (const step of steps) {
|
|
13
14
|
if (step.type === "process") {
|
|
14
|
-
await (0, process_1.exec)(step.config.command, (step.config.args || []).map((v) => (0, string_1.render)(v,
|
|
15
|
+
await (0, process_1.exec)(step.config.command, (step.config.args || []).map((v) => (0, string_1.render)(v, vars)), {
|
|
15
16
|
cwd: options.cwd,
|
|
16
17
|
env: {
|
|
17
18
|
...process.env,
|
|
@@ -30,19 +31,19 @@ async function runSteps(input, options) {
|
|
|
30
31
|
}
|
|
31
32
|
else if (step.type === "node") {
|
|
32
33
|
let tempDir;
|
|
33
|
-
if (options
|
|
34
|
-
tempDir = await options.
|
|
34
|
+
if (options?.tempDir) {
|
|
35
|
+
tempDir = await options.tempDir();
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
37
38
|
tempDir = await (0, temp_1.mkTmpDir)("node-step");
|
|
38
39
|
}
|
|
39
40
|
const scriptPath = (0, path_1.join)(tempDir, "script.js");
|
|
40
|
-
const
|
|
41
|
+
const nodeVars = {
|
|
41
42
|
...step.config.vars,
|
|
42
|
-
...
|
|
43
|
+
...vars,
|
|
43
44
|
};
|
|
44
|
-
const varKeys = Object.keys(
|
|
45
|
-
const varJson = JSON.stringify(
|
|
45
|
+
const varKeys = Object.keys(nodeVars);
|
|
46
|
+
const varJson = JSON.stringify(nodeVars);
|
|
46
47
|
const code = Array.isArray(step.config.code)
|
|
47
48
|
? [...step.config.code].join(";\n")
|
|
48
49
|
: step.config.code;
|
|
@@ -67,7 +68,7 @@ async function runSteps(input, options) {
|
|
|
67
68
|
else if (step.type === "telegram-message") {
|
|
68
69
|
await (0, http_1.post)(`https://api.telegram.org/bot${step.config.bot}/sendMessage`, JSON.stringify({
|
|
69
70
|
chat_id: step.config.chatId.toString(),
|
|
70
|
-
text: (0, string_1.render)(step.config.text ?? `{
|
|
71
|
+
text: (0, string_1.render)(step.config.text ?? `{dtt.text}`, vars),
|
|
71
72
|
disable_notification: true,
|
|
72
73
|
}), {
|
|
73
74
|
headers: {
|
|
@@ -75,6 +76,19 @@ async function runSteps(input, options) {
|
|
|
75
76
|
},
|
|
76
77
|
});
|
|
77
78
|
}
|
|
79
|
+
else if (step.type === "ntfy") {
|
|
80
|
+
const topic = [step.config.token, step.config.topic]
|
|
81
|
+
.filter(Boolean)
|
|
82
|
+
.join("-");
|
|
83
|
+
if (topic.length < 32)
|
|
84
|
+
throw new Error(`Topic is less than 32 characters: ${topic}`);
|
|
85
|
+
await (0, http_1.post)(`https://ntfy.sh/${topic}`, (0, string_1.render)(step.config.text ?? `{dtt.text}`, vars), {
|
|
86
|
+
headers: {
|
|
87
|
+
Title: (0, string_1.render)("{dtt.title}", vars),
|
|
88
|
+
Priority: vars.success ? "default" : "high",
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
78
92
|
else {
|
|
79
93
|
throw new Error(`Invalid step type: ${step.type}`);
|
|
80
94
|
}
|
package/utils/string.js
CHANGED
|
@@ -8,17 +8,33 @@ function snakeCase(value, char = "_") {
|
|
|
8
8
|
}
|
|
9
9
|
exports.snakeCase = snakeCase;
|
|
10
10
|
function render(subject, vars) {
|
|
11
|
-
return subject.replace(/{([\w
|
|
11
|
+
return subject.replace(/{([\w\./]*)}/g, function (match, name) {
|
|
12
12
|
if (!name.length) {
|
|
13
13
|
return "{";
|
|
14
14
|
}
|
|
15
15
|
else if (name === "/") {
|
|
16
16
|
return "}";
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
let ref = vars;
|
|
19
|
+
for (const key of name.split(".")) {
|
|
20
|
+
if (!!ref && typeof ref === "object") {
|
|
21
|
+
ref = ref[key];
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
ref = undefined;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (typeof ref !== "string" &&
|
|
29
|
+
typeof ref !== "number" &&
|
|
30
|
+
typeof ref !== "boolean")
|
|
31
|
+
throw new Error(`Variable is not valid: ${name}`, {
|
|
32
|
+
cause: {
|
|
33
|
+
vars,
|
|
34
|
+
value: ref,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
return ref.toString();
|
|
22
38
|
});
|
|
23
39
|
}
|
|
24
40
|
exports.render = render;
|