@datatruck/cli 0.23.2 → 0.24.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/Factory/CommandFactory.d.ts +7 -0
- package/Factory/CommandFactory.js +39 -1
- package/Repository/DatatruckRepository.d.ts +1 -1
- package/Repository/DatatruckRepository.js +7 -3
- package/Task/ScriptTask.d.ts +20 -25
- package/Task/ScriptTask.js +42 -64
- package/Task/TaskAbstract.d.ts +7 -6
- package/Task/TaskAbstract.js +2 -6
- package/config.schema.json +6 -3
- package/package.json +1 -1
- package/utils/cli.js +2 -0
- package/utils/steps.d.ts +30 -0
- package/utils/steps.js +59 -0
- package/utils/string.d.ts +3 -1
- package/utils/string.js +3 -2
|
@@ -38,5 +38,12 @@ export type LogMapType = {
|
|
|
38
38
|
};
|
|
39
39
|
export declare function CommandFactory<TCommand extends keyof OptionsMapType>(type: TCommand, globalOptions: GlobalOptionsType<false>, options: OptionsMapType[TCommand]): CleanCacheCommand;
|
|
40
40
|
export declare function exec<TCommand extends keyof OptionsMapType>(type: TCommand, globalOptions: GlobalOptionsType<false>, options: OptionsMapType[TCommand]): Promise<number>;
|
|
41
|
+
export declare function createActionInterface(globalOptions: GlobalOptionsType<false>): {
|
|
42
|
+
[K in keyof OptionsMapType as `${K}`]: (options: OptionsMapType[K]) => Promise<K extends keyof LogMapType ? LogMapType[K] : never>;
|
|
43
|
+
};
|
|
44
|
+
export declare function runAndParse<TCommand extends keyof LogMapType>(type: TCommand, run: () => Promise<any>): Promise<{
|
|
45
|
+
exitCode: any;
|
|
46
|
+
log: LogMapType[TCommand];
|
|
47
|
+
}>;
|
|
41
48
|
export declare function makeParseLog<TCommand extends keyof LogMapType>(type: TCommand): () => LogMapType[TCommand];
|
|
42
49
|
export declare function CommandConstructorFactory(type: CommandEnum): typeof CleanCacheCommand;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CommandConstructorFactory = exports.makeParseLog = exports.exec = exports.CommandFactory = exports.CommandEnum = void 0;
|
|
3
|
+
exports.CommandConstructorFactory = exports.makeParseLog = exports.runAndParse = exports.createActionInterface = exports.exec = exports.CommandFactory = exports.CommandEnum = void 0;
|
|
4
4
|
const BackupCommand_1 = require("../Command/BackupCommand");
|
|
5
5
|
const BackupSessionsCommand_1 = require("../Command/BackupSessionsCommand");
|
|
6
6
|
const CleanCacheCommand_1 = require("../Command/CleanCacheCommand");
|
|
@@ -32,6 +32,44 @@ async function exec(type, globalOptions, options) {
|
|
|
32
32
|
return await CommandFactory(type, globalOptions, options).onExec();
|
|
33
33
|
}
|
|
34
34
|
exports.exec = exec;
|
|
35
|
+
function createActionInterface(globalOptions) {
|
|
36
|
+
const object = {};
|
|
37
|
+
for (const type of Object.values(CommandEnum)) {
|
|
38
|
+
object[type] = async (options) => {
|
|
39
|
+
const run = () => exec(type, { ...globalOptions, outputFormat: "json", verbose: 1 }, options);
|
|
40
|
+
let exitCode;
|
|
41
|
+
let log;
|
|
42
|
+
if (["config", "init", "snapshots"].includes(type)) {
|
|
43
|
+
const parsed = await runAndParse(type, run);
|
|
44
|
+
exitCode = parsed.exitCode;
|
|
45
|
+
log = parsed.log;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
exitCode = await run();
|
|
49
|
+
}
|
|
50
|
+
if (exitCode !== 0)
|
|
51
|
+
throw new Error(`Invalid exit code: ${exitCode}`);
|
|
52
|
+
return log;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return object;
|
|
56
|
+
}
|
|
57
|
+
exports.createActionInterface = createActionInterface;
|
|
58
|
+
async function runAndParse(type, run) {
|
|
59
|
+
const parseLog = makeParseLog(type);
|
|
60
|
+
try {
|
|
61
|
+
const exitCode = await run();
|
|
62
|
+
return { exitCode, log: parseLog() };
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
try {
|
|
66
|
+
parseLog();
|
|
67
|
+
}
|
|
68
|
+
catch (_) { }
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.runAndParse = runAndParse;
|
|
35
73
|
function makeParseLog(type) {
|
|
36
74
|
const data = [];
|
|
37
75
|
const consoleLog = console.log;
|
|
@@ -37,7 +37,6 @@ exports.datatruckPackageRepositoryDefinition = {
|
|
|
37
37
|
items: {
|
|
38
38
|
type: "object",
|
|
39
39
|
additionalProperties: false,
|
|
40
|
-
required: ["include"],
|
|
41
40
|
properties: {
|
|
42
41
|
name: { type: "string" },
|
|
43
42
|
compress: {
|
|
@@ -184,14 +183,15 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
184
183
|
const defaultsPack = {
|
|
185
184
|
name: "defaults",
|
|
186
185
|
compress: data.packageConfig?.compress ?? this.config.compress,
|
|
187
|
-
include: [],
|
|
188
186
|
};
|
|
189
|
-
const packs = [...configPacks
|
|
187
|
+
const packs = [defaultsPack, ...configPacks];
|
|
190
188
|
const defaultsPackIndex = packs.findIndex((p) => p === defaultsPack);
|
|
191
189
|
const stream = (0, fs_1.createWriteStreamPool)({
|
|
192
190
|
path: await this.mkTmpDir("files"),
|
|
193
191
|
onStreamPath: (key) => `files-${key}.txt`,
|
|
194
192
|
});
|
|
193
|
+
scanner.total++;
|
|
194
|
+
stream.writeLine(defaultsPackIndex, ".");
|
|
195
195
|
await scanner.start(async (entry) => {
|
|
196
196
|
let packIndex = configPacks.findIndex((pack) => (0, string_1.match)(entry.path, pack.include, pack.exclude));
|
|
197
197
|
if (packIndex === -1)
|
|
@@ -205,6 +205,10 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
205
205
|
});
|
|
206
206
|
packIndex = packs.length - 1;
|
|
207
207
|
}
|
|
208
|
+
if (!stream.lines(packIndex)) {
|
|
209
|
+
scanner.total++;
|
|
210
|
+
stream.writeLine(packIndex, ".");
|
|
211
|
+
}
|
|
208
212
|
stream.writeLine(packIndex, entry.path);
|
|
209
213
|
return true;
|
|
210
214
|
});
|
package/Task/ScriptTask.d.ts
CHANGED
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Step } from "../utils/steps";
|
|
2
|
+
import { BackupDataType, BeforeBackupDataType, BeforeRestoreDataType, RestoreDataType, TaskAbstract } from "./TaskAbstract";
|
|
2
3
|
import { JSONSchema7 } from "json-schema";
|
|
3
|
-
export type ProcessStepConfig = {
|
|
4
|
-
command: string;
|
|
5
|
-
env?: Record<string, string>;
|
|
6
|
-
args?: string[];
|
|
7
|
-
};
|
|
8
|
-
export type NodeStepConfig = {
|
|
9
|
-
env?: Record<string, string>;
|
|
10
|
-
code: string | string[];
|
|
11
|
-
};
|
|
12
|
-
export type Step = {
|
|
13
|
-
type: "process";
|
|
14
|
-
config: ProcessStepConfig;
|
|
15
|
-
} | {
|
|
16
|
-
type: "node";
|
|
17
|
-
config: NodeStepConfig;
|
|
18
|
-
};
|
|
19
4
|
export type ScriptTaskConfigType = {
|
|
20
5
|
env?: Record<string, string | undefined>;
|
|
21
6
|
backupSteps: Step[];
|
|
@@ -25,17 +10,27 @@ export declare const scriptTaskName = "script";
|
|
|
25
10
|
export declare const scriptTaskDefinition: JSONSchema7;
|
|
26
11
|
export declare class ScriptTask extends TaskAbstract<ScriptTaskConfigType> {
|
|
27
12
|
protected verbose?: boolean;
|
|
28
|
-
onBeforeBackup(): Promise<{
|
|
13
|
+
onBeforeBackup(data: BeforeBackupDataType): Promise<{
|
|
29
14
|
targetPath: string;
|
|
30
15
|
}>;
|
|
31
|
-
protected getVars(data: BackupDataType | RestoreDataType):
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
16
|
+
protected getVars(data: BackupDataType | RestoreDataType): {
|
|
17
|
+
process: {
|
|
18
|
+
DTT_SNAPSHOT_ID: string;
|
|
19
|
+
DTT_SNAPSHOT_DATE: string;
|
|
20
|
+
DTT_PACKAGE_NAME: string;
|
|
21
|
+
DTT_PACKAGE_PATH: string | undefined;
|
|
22
|
+
DTT_TARGET_PATH: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
node: {
|
|
25
|
+
dtt: {
|
|
26
|
+
snapshot: import("../Repository/RepositoryAbstract").SnapshotType;
|
|
27
|
+
package: import("../Config/PackageConfig").PackageConfigType;
|
|
28
|
+
targetPath: string | undefined;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
37
32
|
onBackup(data: BackupDataType): Promise<void>;
|
|
38
|
-
onBeforeRestore(): Promise<{
|
|
33
|
+
onBeforeRestore(data: BeforeRestoreDataType): Promise<{
|
|
39
34
|
targetPath: string;
|
|
40
35
|
}>;
|
|
41
36
|
onRestore(data: RestoreDataType): Promise<void>;
|
package/Task/ScriptTask.js
CHANGED
|
@@ -3,12 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ScriptTask = exports.scriptTaskDefinition = exports.scriptTaskName = void 0;
|
|
4
4
|
const DefinitionEnum_1 = require("../JsonSchema/DefinitionEnum");
|
|
5
5
|
const fs_1 = require("../utils/fs");
|
|
6
|
-
const
|
|
7
|
-
const string_1 = require("../utils/string");
|
|
6
|
+
const steps_1 = require("../utils/steps");
|
|
8
7
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
9
8
|
const assert_1 = require("assert");
|
|
10
|
-
const promises_1 = require("fs/promises");
|
|
11
|
-
const path_1 = require("path");
|
|
12
9
|
var ScriptTaskDefinitionEnum;
|
|
13
10
|
(function (ScriptTaskDefinitionEnum) {
|
|
14
11
|
ScriptTaskDefinitionEnum["step"] = "step";
|
|
@@ -64,6 +61,10 @@ exports.scriptTaskDefinition = {
|
|
|
64
61
|
code: {
|
|
65
62
|
anyOf: [{ type: "string" }, (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil)],
|
|
66
63
|
},
|
|
64
|
+
vars: {
|
|
65
|
+
type: "object",
|
|
66
|
+
patternProperties: { ".+": {} },
|
|
67
|
+
},
|
|
67
68
|
env: {
|
|
68
69
|
type: "object",
|
|
69
70
|
patternProperties: { ".+": { type: "string" } },
|
|
@@ -93,88 +94,65 @@ exports.scriptTaskDefinition = {
|
|
|
93
94
|
};
|
|
94
95
|
class ScriptTask extends TaskAbstract_1.TaskAbstract {
|
|
95
96
|
verbose;
|
|
96
|
-
async onBeforeBackup() {
|
|
97
|
+
async onBeforeBackup(data) {
|
|
97
98
|
return {
|
|
98
|
-
targetPath: await this.mkTmpDir(
|
|
99
|
+
targetPath: data.package.path ?? (await this.mkTmpDir(`script-task_backup_target`)),
|
|
99
100
|
};
|
|
100
101
|
}
|
|
101
102
|
getVars(data) {
|
|
102
103
|
return {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
process: {
|
|
105
|
+
DTT_SNAPSHOT_ID: data.snapshot.id,
|
|
106
|
+
DTT_SNAPSHOT_DATE: data.snapshot.date,
|
|
107
|
+
DTT_PACKAGE_NAME: data.package.name,
|
|
108
|
+
DTT_PACKAGE_PATH: data.package.path,
|
|
109
|
+
DTT_TARGET_PATH: data.targetPath,
|
|
110
|
+
},
|
|
111
|
+
node: {
|
|
112
|
+
dtt: {
|
|
113
|
+
snapshot: data.snapshot,
|
|
114
|
+
package: data.package,
|
|
115
|
+
targetPath: data.targetPath,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
108
118
|
};
|
|
109
119
|
}
|
|
110
|
-
async processSteps(input, options) {
|
|
111
|
-
const steps = Array.isArray(input) ? input : [input];
|
|
112
|
-
for (const step of steps) {
|
|
113
|
-
if (step.type === "process") {
|
|
114
|
-
await (0, process_1.exec)(step.config.command, (step.config.args || []).map((v) => (0, string_1.render)(v, options.vars)), {
|
|
115
|
-
env: {
|
|
116
|
-
...process.env,
|
|
117
|
-
...options.vars,
|
|
118
|
-
...options.env,
|
|
119
|
-
...step.config.env,
|
|
120
|
-
},
|
|
121
|
-
}, {
|
|
122
|
-
log: options.verbose,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
else if (step.type === "node") {
|
|
126
|
-
const tempDir = await this.mkTmpDir("script-task-node-step");
|
|
127
|
-
const scriptPath = (0, path_1.join)(tempDir, "script.js");
|
|
128
|
-
await (0, promises_1.writeFile)(scriptPath, Array.isArray(step.config.code)
|
|
129
|
-
? step.config.code.join("\n")
|
|
130
|
-
: step.config.code);
|
|
131
|
-
await (0, process_1.exec)("node", [scriptPath], {
|
|
132
|
-
env: {
|
|
133
|
-
...process.env,
|
|
134
|
-
...options.vars,
|
|
135
|
-
...options.env,
|
|
136
|
-
...step.config.env,
|
|
137
|
-
},
|
|
138
|
-
}, {
|
|
139
|
-
log: options.verbose,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
throw new Error(`Invalid step type: ${step.type}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
120
|
async onBackup(data) {
|
|
148
|
-
this.verbose = data.options.verbose;
|
|
149
121
|
const config = this.config;
|
|
150
|
-
const path = data.package.path;
|
|
151
122
|
const targetPath = data.targetPath;
|
|
152
|
-
(0, assert_1.ok)(typeof path === "string");
|
|
153
123
|
(0, assert_1.ok)(typeof targetPath === "string");
|
|
154
|
-
|
|
124
|
+
const vars = this.getVars(data);
|
|
125
|
+
await (0, fs_1.mkdirIfNotExists)(targetPath);
|
|
126
|
+
await (0, steps_1.runSteps)(config.backupSteps, {
|
|
155
127
|
env: config.env,
|
|
156
|
-
|
|
157
|
-
|
|
128
|
+
verbose: data.options.verbose,
|
|
129
|
+
process: { vars: vars.process },
|
|
130
|
+
node: {
|
|
131
|
+
tempDir: () => this.mkTmpDir("script-task_backup_node-step"),
|
|
132
|
+
vars: vars.node,
|
|
133
|
+
},
|
|
158
134
|
});
|
|
159
135
|
}
|
|
160
|
-
async onBeforeRestore() {
|
|
136
|
+
async onBeforeRestore(data) {
|
|
161
137
|
return {
|
|
162
|
-
targetPath:
|
|
138
|
+
targetPath: data.package.restorePath ??
|
|
139
|
+
(await this.mkTmpDir(`script-task_restore_target`)),
|
|
163
140
|
};
|
|
164
141
|
}
|
|
165
142
|
async onRestore(data) {
|
|
166
|
-
this.verbose = data.options.verbose;
|
|
167
143
|
const config = this.config;
|
|
168
|
-
const restorePath = data.package.restorePath;
|
|
169
144
|
const targetPath = data.targetPath;
|
|
170
|
-
(0, assert_1.ok)(typeof restorePath === "string");
|
|
171
145
|
(0, assert_1.ok)(typeof targetPath === "string");
|
|
172
|
-
await (0, fs_1.mkdirIfNotExists)(
|
|
173
|
-
|
|
174
|
-
await
|
|
146
|
+
await (0, fs_1.mkdirIfNotExists)(targetPath);
|
|
147
|
+
const vars = this.getVars(data);
|
|
148
|
+
await (0, steps_1.runSteps)(config.restoreSteps, {
|
|
175
149
|
env: config.env,
|
|
176
|
-
|
|
177
|
-
|
|
150
|
+
verbose: data.options.verbose,
|
|
151
|
+
process: { vars: vars.process },
|
|
152
|
+
node: {
|
|
153
|
+
tempDir: () => this.mkTmpDir("script-task_restore_node-step"),
|
|
154
|
+
vars: vars.node,
|
|
155
|
+
},
|
|
178
156
|
});
|
|
179
157
|
}
|
|
180
158
|
}
|
package/Task/TaskAbstract.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type BackupDataType = {
|
|
|
10
10
|
targetPath: string | undefined;
|
|
11
11
|
snapshot: SnapshotType;
|
|
12
12
|
};
|
|
13
|
+
export type BeforeBackupDataType = Omit<BackupDataType, "onProgress" | "targetPath">;
|
|
13
14
|
export type RestoreDataType = {
|
|
14
15
|
onProgress: (data: Progress) => Promise<void>;
|
|
15
16
|
options: RestoreActionOptionsType;
|
|
@@ -17,17 +18,17 @@ export type RestoreDataType = {
|
|
|
17
18
|
targetPath: string | undefined;
|
|
18
19
|
snapshot: SnapshotType;
|
|
19
20
|
};
|
|
21
|
+
export type BeforeRestoreDataType = Omit<RestoreDataType, "onProgress" | "targetPath">;
|
|
22
|
+
export type BeforeReturn = Promise<{
|
|
23
|
+
targetPath?: string;
|
|
24
|
+
} | undefined | void>;
|
|
20
25
|
export declare abstract class TaskAbstract<TConfig = any> {
|
|
21
26
|
readonly config: TConfig;
|
|
22
27
|
readonly tmpDirs: string[];
|
|
23
28
|
constructor(config: TConfig);
|
|
24
29
|
mkTmpDir(prefix: string, id?: string): Promise<string>;
|
|
25
|
-
onBeforeBackup(data:
|
|
26
|
-
targetPath?: string;
|
|
27
|
-
} | undefined>;
|
|
30
|
+
onBeforeBackup(data: BeforeBackupDataType): BeforeReturn;
|
|
28
31
|
onBackup(data: BackupDataType): Promise<void>;
|
|
29
|
-
onBeforeRestore(data:
|
|
30
|
-
targetPath?: string;
|
|
31
|
-
} | undefined>;
|
|
32
|
+
onBeforeRestore(data: BeforeRestoreDataType): BeforeReturn;
|
|
32
33
|
onRestore(data: RestoreDataType): Promise<void>;
|
|
33
34
|
}
|
package/Task/TaskAbstract.js
CHANGED
|
@@ -13,13 +13,9 @@ class TaskAbstract {
|
|
|
13
13
|
this.tmpDirs.push(dir);
|
|
14
14
|
return dir;
|
|
15
15
|
}
|
|
16
|
-
async onBeforeBackup(data) {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
16
|
+
async onBeforeBackup(data) { }
|
|
19
17
|
async onBackup(data) { }
|
|
20
|
-
async onBeforeRestore(data) {
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
18
|
+
async onBeforeRestore(data) { }
|
|
23
19
|
async onRestore(data) { }
|
|
24
20
|
}
|
|
25
21
|
exports.TaskAbstract = TaskAbstract;
|
package/config.schema.json
CHANGED
|
@@ -479,9 +479,6 @@
|
|
|
479
479
|
"items": {
|
|
480
480
|
"type": "object",
|
|
481
481
|
"additionalProperties": false,
|
|
482
|
-
"required": [
|
|
483
|
-
"include"
|
|
484
|
-
],
|
|
485
482
|
"properties": {
|
|
486
483
|
"name": {
|
|
487
484
|
"type": "string"
|
|
@@ -1197,6 +1194,12 @@
|
|
|
1197
1194
|
}
|
|
1198
1195
|
]
|
|
1199
1196
|
},
|
|
1197
|
+
"vars": {
|
|
1198
|
+
"type": "object",
|
|
1199
|
+
"patternProperties": {
|
|
1200
|
+
".+": {}
|
|
1201
|
+
}
|
|
1202
|
+
},
|
|
1200
1203
|
"env": {
|
|
1201
1204
|
"type": "object",
|
|
1202
1205
|
"patternProperties": {
|
package/package.json
CHANGED
package/utils/cli.js
CHANGED
|
@@ -21,6 +21,8 @@ function renderSpinner(counter) {
|
|
|
21
21
|
}
|
|
22
22
|
exports.renderSpinner = renderSpinner;
|
|
23
23
|
function renderProgressBar(progress, size = 10, subprogress) {
|
|
24
|
+
if (progress > 100)
|
|
25
|
+
throw new Error(`Invalid progress value: ${progress}`);
|
|
24
26
|
const completeChar = "\u2588";
|
|
25
27
|
const incompleteChar = "\u2591";
|
|
26
28
|
const completedSize = Math.round((progress * size) / 100);
|
package/utils/steps.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type StepEnv = Record<string, string>;
|
|
2
|
+
export type ProcessStepConfig = {
|
|
3
|
+
command: string;
|
|
4
|
+
env?: StepEnv;
|
|
5
|
+
args?: string[];
|
|
6
|
+
};
|
|
7
|
+
export type NodeStepConfig = {
|
|
8
|
+
env?: StepEnv;
|
|
9
|
+
vars?: Record<string, any>;
|
|
10
|
+
code: string | string[];
|
|
11
|
+
};
|
|
12
|
+
export type Step = {
|
|
13
|
+
type: "process";
|
|
14
|
+
config: ProcessStepConfig;
|
|
15
|
+
} | {
|
|
16
|
+
type: "node";
|
|
17
|
+
config: NodeStepConfig;
|
|
18
|
+
};
|
|
19
|
+
export type StepOptions = {
|
|
20
|
+
env?: Record<string, string | undefined>;
|
|
21
|
+
process?: {
|
|
22
|
+
vars?: Record<string, string | undefined>;
|
|
23
|
+
};
|
|
24
|
+
node?: {
|
|
25
|
+
vars?: Record<string, any>;
|
|
26
|
+
tempDir?: () => Promise<string>;
|
|
27
|
+
};
|
|
28
|
+
verbose?: boolean;
|
|
29
|
+
};
|
|
30
|
+
export declare function runSteps(input: Step[] | Step, options: StepOptions): Promise<void>;
|
package/utils/steps.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runSteps = void 0;
|
|
4
|
+
const process_1 = require("./process");
|
|
5
|
+
const string_1 = require("./string");
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
7
|
+
const promises_1 = require("fs/promises");
|
|
8
|
+
const os_1 = require("os");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
async function runSteps(input, options) {
|
|
11
|
+
const steps = Array.isArray(input) ? input : [input];
|
|
12
|
+
for (const step of steps) {
|
|
13
|
+
if (step.type === "process") {
|
|
14
|
+
await (0, process_1.exec)(step.config.command, (step.config.args || []).map((v) => (0, string_1.render)(v, options.process?.vars || {})), {
|
|
15
|
+
env: {
|
|
16
|
+
...process.env,
|
|
17
|
+
...options.env,
|
|
18
|
+
...step.config.env,
|
|
19
|
+
},
|
|
20
|
+
}, {
|
|
21
|
+
log: options.verbose,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else if (step.type === "node") {
|
|
25
|
+
let tempDir;
|
|
26
|
+
if (options.node?.tempDir) {
|
|
27
|
+
tempDir = await options.node.tempDir();
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
tempDir = (0, path_1.join)((0, os_1.tmpdir)(), (0, crypto_1.randomBytes)(8).toString("hex"));
|
|
31
|
+
await (0, promises_1.mkdir)(tempDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
const scriptPath = (0, path_1.join)(tempDir, "script.js");
|
|
34
|
+
const vars = Object.entries({
|
|
35
|
+
...step.config.vars,
|
|
36
|
+
...options.node?.vars,
|
|
37
|
+
}).reduce((items, [name, value]) => {
|
|
38
|
+
items.push(`let ${name} = ${JSON.stringify(value)}`);
|
|
39
|
+
return items;
|
|
40
|
+
}, []);
|
|
41
|
+
await (0, promises_1.writeFile)(scriptPath, Array.isArray(step.config.code)
|
|
42
|
+
? [...vars, ...step.config.code].join(";\n")
|
|
43
|
+
: `${vars.join(";\n")}\n${step.config.code}`);
|
|
44
|
+
await (0, process_1.exec)("node", [scriptPath], {
|
|
45
|
+
env: {
|
|
46
|
+
...process.env,
|
|
47
|
+
...options.env,
|
|
48
|
+
...step.config.env,
|
|
49
|
+
},
|
|
50
|
+
}, {
|
|
51
|
+
log: options.verbose,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
throw new Error(`Invalid step type: ${step.type}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.runSteps = runSteps;
|
package/utils/string.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export declare function serialize(message: string, data?: Object): string;
|
|
2
2
|
export declare function snakeCase(value: string, char?: string): string;
|
|
3
3
|
export declare function render(subject: string, vars: Record<string, string | undefined>): string;
|
|
4
|
-
|
|
4
|
+
type NoInfer<T> = [T][T extends any ? 0 : never];
|
|
5
|
+
export declare function parseStringList<T>(value: string | undefined, validValues?: T[], defaultsValues?: NoInfer<T>[] | true): T[];
|
|
5
6
|
export type UriType = {
|
|
6
7
|
protocol?: "http" | "https";
|
|
7
8
|
host?: string;
|
|
@@ -20,3 +21,4 @@ export declare function checkMatch(subject: string | undefined, patterns: string
|
|
|
20
21
|
export declare function formatDateTime(datetime: string): string;
|
|
21
22
|
export declare function splitLines(input: string, satinize?: boolean): string[];
|
|
22
23
|
export declare function undefIfEmpty(input: string): string | undefined;
|
|
24
|
+
export {};
|
package/utils/string.js
CHANGED
|
@@ -28,11 +28,12 @@ function render(subject, vars) {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
exports.render = render;
|
|
31
|
-
function parseStringList(value, validValues) {
|
|
31
|
+
function parseStringList(value, validValues, defaultsValues) {
|
|
32
|
+
const resultFallback = (defaultsValues === true ? validValues : defaultsValues) ?? [];
|
|
32
33
|
const result = value
|
|
33
34
|
?.split(",")
|
|
34
35
|
.map((v) => v.trim())
|
|
35
|
-
.filter((v) => !!v.length) ??
|
|
36
|
+
.filter((v) => !!v.length) ?? resultFallback;
|
|
36
37
|
if (validValues)
|
|
37
38
|
for (const v of result)
|
|
38
39
|
if (!validValues.includes(v))
|