@datatruck/cli 0.34.2 → 0.34.4
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/lib/actions/BackupAction.js +4 -3
- package/lib/actions/ConfigAction.js +1 -1
- package/lib/actions/CopyAction.js +88 -74
- package/lib/actions/PruneAction.js +3 -2
- package/lib/actions/RestoreAction.js +6 -5
- package/lib/cli.js +1 -1
- package/lib/commands/StartServerCommand.js +2 -1
- package/lib/repositories/DatatruckRepository.js +6 -3
- package/lib/repositories/ResticRepository.js +1 -1
- package/lib/tasks/GitTask.js +2 -1
- package/lib/tasks/MssqlTask.js +2 -2
- package/lib/tasks/MysqlDumpTask.js +1 -1
- package/lib/tasks/SqlDumpTaskAbstract.js +2 -2
- package/lib/utils/async-process.js +3 -2
- package/lib/utils/cli.js +10 -10
- package/lib/utils/data-format.js +3 -3
- package/lib/utils/datatruck/command.js +1 -1
- package/lib/utils/datatruck/config.js +2 -2
- package/lib/utils/datatruck/report-list.js +2 -1
- package/lib/utils/datatruck/repository.js +1 -1
- package/lib/utils/datatruck/task.js +1 -1
- package/lib/utils/{datatruck/error.d.ts → error.d.ts} +1 -1
- package/lib/utils/{datatruck/error.js → error.js} +2 -2
- package/lib/utils/fs.js +4 -3
- package/lib/utils/mysql.js +1 -1
- package/lib/utils/object.d.ts +1 -1
- package/lib/utils/object.js +1 -1
- package/lib/utils/reportSteps.js +3 -2
- package/lib/utils/string.js +1 -1
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ const report_list_1 = require("../utils/datatruck/report-list");
|
|
|
12
12
|
const repository_1 = require("../utils/datatruck/repository");
|
|
13
13
|
const task_1 = require("../utils/datatruck/task");
|
|
14
14
|
const date_1 = require("../utils/date");
|
|
15
|
+
const error_1 = require("../utils/error");
|
|
15
16
|
const fs_1 = require("../utils/fs");
|
|
16
17
|
const list_1 = require("../utils/list");
|
|
17
18
|
const progress_1 = require("../utils/progress");
|
|
@@ -32,7 +33,7 @@ class BackupAction {
|
|
|
32
33
|
prepareSnapshot() {
|
|
33
34
|
const date = this.options.date ?? new Date().toISOString();
|
|
34
35
|
if (!(0, dayjs_1.default)(date, "YYYY-MM-DDTHH:mm:ss.SSS[Z]", true).isValid())
|
|
35
|
-
throw new
|
|
36
|
+
throw new error_1.AppError(`Invalid snapshot date: ${date}`);
|
|
36
37
|
return {
|
|
37
38
|
id: (0, crypto_1.randomUUID)().replaceAll("-", ""),
|
|
38
39
|
date,
|
|
@@ -243,7 +244,7 @@ class BackupAction {
|
|
|
243
244
|
? l.result("task", pkg.name)
|
|
244
245
|
: undefined;
|
|
245
246
|
if (taskSummary?.error)
|
|
246
|
-
throw new
|
|
247
|
+
throw new error_1.AppError(`Task failed`);
|
|
247
248
|
const backup = await this.backup({
|
|
248
249
|
pkg,
|
|
249
250
|
repositoryName,
|
|
@@ -289,7 +290,7 @@ class BackupAction {
|
|
|
289
290
|
name,
|
|
290
291
|
]);
|
|
291
292
|
if (backupSummary.error)
|
|
292
|
-
throw new
|
|
293
|
+
throw new error_1.AppError(`Backup failed`);
|
|
293
294
|
const copy = await this.copy({
|
|
294
295
|
repositoryName: name,
|
|
295
296
|
mirrorRepositoryName: mirror,
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.ConfigAction = void 0;
|
|
7
7
|
const config_schema_1 = require("../config.schema");
|
|
8
8
|
const config_1 = require("../utils/datatruck/config");
|
|
9
|
-
const error_1 = require("../utils/
|
|
9
|
+
const error_1 = require("../utils/error");
|
|
10
10
|
const fs_1 = require("../utils/fs");
|
|
11
11
|
const ajv_1 = __importDefault(require("ajv"));
|
|
12
12
|
const assert_1 = require("assert");
|
|
@@ -57,6 +57,7 @@ const report_list_1 = require("../utils/datatruck/report-list");
|
|
|
57
57
|
const repository_1 = require("../utils/datatruck/repository");
|
|
58
58
|
const snapshot_1 = require("../utils/datatruck/snapshot");
|
|
59
59
|
const date_1 = require("../utils/date");
|
|
60
|
+
const error_1 = require("../utils/error");
|
|
60
61
|
const list_1 = require("../utils/list");
|
|
61
62
|
const object_1 = require("../utils/object");
|
|
62
63
|
const progress_1 = require("../utils/progress");
|
|
@@ -98,6 +99,12 @@ class CopyAction {
|
|
|
98
99
|
return new data_format_1.DataFormat({
|
|
99
100
|
streams: options.streams,
|
|
100
101
|
json: result,
|
|
102
|
+
list: () => result.map((item) => {
|
|
103
|
+
const icon = (0, cli_1.renderResult)(item.error, false);
|
|
104
|
+
const title = renderTitle(item);
|
|
105
|
+
const data = renderData(item, false, result);
|
|
106
|
+
return `${icon} ${title}: ${data}`;
|
|
107
|
+
}),
|
|
101
108
|
table: {
|
|
102
109
|
headers: [
|
|
103
110
|
{ value: "", width: 3 },
|
|
@@ -131,7 +138,7 @@ class CopyAction {
|
|
|
131
138
|
}).map(({ item }) => item)
|
|
132
139
|
: snapshots;
|
|
133
140
|
if (!result.length)
|
|
134
|
-
throw new
|
|
141
|
+
throw new error_1.AppError("No snapshots found");
|
|
135
142
|
return result;
|
|
136
143
|
}
|
|
137
144
|
createSourceRepoMap() {
|
|
@@ -212,83 +219,90 @@ class CopyAction {
|
|
|
212
219
|
action: "backup",
|
|
213
220
|
}), [repoConfig.type]);
|
|
214
221
|
if (!repositoryNames2.length)
|
|
215
|
-
throw new
|
|
222
|
+
throw new error_1.AppError("No mirror snapshots found");
|
|
216
223
|
const sourceRepoMap = this.createSourceRepoMap();
|
|
217
|
-
return
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (currentCopies.length) {
|
|
249
|
-
data.skipped = true;
|
|
250
|
-
return task.skip(`Already exists at ${mirrorConfig.name}: ${pkgName} (${id})`);
|
|
251
|
-
}
|
|
252
|
-
if (this.config.minFreeDiskSpace)
|
|
253
|
-
await mirrorRepo.ensureFreeDiskSpace(mirrorConfig.config, this.config.minFreeDiskSpace);
|
|
254
|
-
const sourceRepo = sourceRepoMap.with([
|
|
255
|
-
snapshot,
|
|
256
|
-
mirrorConfig,
|
|
257
|
-
]);
|
|
258
|
-
if (sourceRepo.has()) {
|
|
259
|
-
const copy = await sourceRepo.get().copy({
|
|
260
|
-
mirrorRepositoryConfig: mirrorConfig.config,
|
|
261
|
-
options: { verbose: this.options.verbose },
|
|
262
|
-
package: { name: snapshot.packageName },
|
|
263
|
-
snapshot,
|
|
264
|
-
onProgress: (p) => pm.update(p, (d) => (task.output = d)),
|
|
265
|
-
});
|
|
266
|
-
data.bytes = copy.bytes;
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
const copy = await this.copyCrossRepository({
|
|
270
|
-
mirrorConfig,
|
|
271
|
-
mirrorRepo,
|
|
272
|
-
repo,
|
|
273
|
-
repoConfig,
|
|
274
|
-
snapshot,
|
|
275
|
-
onProgress: (p) => pm.update(p, (d) => (task.output = d)),
|
|
224
|
+
return [
|
|
225
|
+
...data.snapshots.flatMap((snapshot) => repositoryNames2.map((repo2) => {
|
|
226
|
+
const id = snapshot.id.slice(0, 8);
|
|
227
|
+
const pkgName = snapshot.packageName;
|
|
228
|
+
return l.$task({
|
|
229
|
+
key: "copy",
|
|
230
|
+
keyIndex: [snapshot.packageName, repo2.name, snapshot.id],
|
|
231
|
+
data: {
|
|
232
|
+
snapshotId: snapshot.id,
|
|
233
|
+
packageName: snapshot.packageName,
|
|
234
|
+
repositoryName: repoConfig.name,
|
|
235
|
+
mirrorRepositoryName: repo2.name,
|
|
236
|
+
bytes: 0,
|
|
237
|
+
skipped: false,
|
|
238
|
+
},
|
|
239
|
+
title: {
|
|
240
|
+
initial: `Copy snapshot: ${pkgName} (${id}) » ${repo2.name}`,
|
|
241
|
+
started: `Copying snapshot: ${pkgName} (${id}) » ${repo2.name}`,
|
|
242
|
+
completed: `Snapshot copied: ${pkgName} (${id}) » ${repo2.name}`,
|
|
243
|
+
failed: `Snapshot copy failed: ${pkgName} (${id}) » ${repo2.name}`,
|
|
244
|
+
},
|
|
245
|
+
exitOnError: false,
|
|
246
|
+
run: async (task, data) => {
|
|
247
|
+
const mirrorConfig = (0, config_1.findRepositoryOrFail)(this.config, repo2.name);
|
|
248
|
+
const mirrorRepo = await (0, repository_1.createAndInitRepo)(mirrorConfig, this.options.verbose);
|
|
249
|
+
const currentCopies = await mirrorRepo.fetchSnapshots({
|
|
250
|
+
options: {
|
|
251
|
+
ids: [snapshot.id],
|
|
252
|
+
packageNames: [snapshot.packageName],
|
|
253
|
+
verbose: this.options.verbose,
|
|
254
|
+
},
|
|
276
255
|
});
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
256
|
+
if (currentCopies.length) {
|
|
257
|
+
data.skipped = true;
|
|
258
|
+
return task.skip(`Already exists at ${mirrorConfig.name}: ${pkgName} (${id})`);
|
|
259
|
+
}
|
|
260
|
+
if (this.config.minFreeDiskSpace)
|
|
261
|
+
await mirrorRepo.ensureFreeDiskSpace(mirrorConfig.config, this.config.minFreeDiskSpace);
|
|
262
|
+
const sourceRepo = sourceRepoMap.withKey([
|
|
263
|
+
{ id: snapshot.id, packageName: snapshot.packageName },
|
|
264
|
+
{ type: mirrorConfig.type },
|
|
265
|
+
]);
|
|
266
|
+
const $sourceRepo = repoConfig.type === mirrorConfig.type
|
|
267
|
+
? repo
|
|
268
|
+
: sourceRepo.has()
|
|
269
|
+
? sourceRepo.get()
|
|
270
|
+
: undefined;
|
|
271
|
+
if ($sourceRepo) {
|
|
272
|
+
const copy = await $sourceRepo.copy({
|
|
273
|
+
mirrorRepositoryConfig: mirrorConfig.config,
|
|
274
|
+
options: { verbose: this.options.verbose },
|
|
275
|
+
package: { name: snapshot.packageName },
|
|
276
|
+
snapshot,
|
|
277
|
+
onProgress: (p) => pm.update(p, (d) => (task.output = d)),
|
|
278
|
+
});
|
|
279
|
+
data.bytes = copy.bytes;
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
const copy = await this.copyCrossRepository({
|
|
283
|
+
mirrorConfig,
|
|
284
|
+
mirrorRepo,
|
|
285
|
+
repo,
|
|
286
|
+
repoConfig,
|
|
287
|
+
snapshot,
|
|
288
|
+
onProgress: (p) => pm.update(p, (d) => (task.output = d)),
|
|
289
|
+
});
|
|
290
|
+
data.bytes = copy.bytes;
|
|
291
|
+
sourceRepo.set(mirrorRepo);
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
})),
|
|
296
|
+
...(0, report_list_1.createReportListTasks)(l, {
|
|
297
|
+
hostname: this.config.hostname ?? (0, os_1.hostname)(),
|
|
298
|
+
action: "copy",
|
|
299
|
+
reports: this.config.reports || [],
|
|
300
|
+
verbose: this.options.verbose,
|
|
301
|
+
onMessage: (result, report) => this.dataFormat(result).format(report.format ?? "list"),
|
|
302
|
+
}),
|
|
303
|
+
];
|
|
283
304
|
},
|
|
284
305
|
}),
|
|
285
|
-
...(0, report_list_1.createReportListTasks)(l, {
|
|
286
|
-
hostname: this.config.hostname ?? (0, os_1.hostname)(),
|
|
287
|
-
action: "copy",
|
|
288
|
-
reports: this.config.reports || [],
|
|
289
|
-
verbose: this.options.verbose,
|
|
290
|
-
onMessage: (result, report) => this.dataFormat(result).format(report.format ?? "list"),
|
|
291
|
-
}),
|
|
292
306
|
])
|
|
293
307
|
.exec();
|
|
294
308
|
}
|
|
@@ -4,6 +4,7 @@ exports.PruneAction = void 0;
|
|
|
4
4
|
const repository_1 = require("../utils/datatruck/repository");
|
|
5
5
|
const snapshot_1 = require("../utils/datatruck/snapshot");
|
|
6
6
|
const date_1 = require("../utils/date");
|
|
7
|
+
const error_1 = require("../utils/error");
|
|
7
8
|
const object_1 = require("../utils/object");
|
|
8
9
|
const SnapshotsAction_1 = require("./SnapshotsAction");
|
|
9
10
|
class PruneAction {
|
|
@@ -41,10 +42,10 @@ class PruneAction {
|
|
|
41
42
|
const keepFilter = (0, date_1.createFilterByLastOptions)(this.options);
|
|
42
43
|
const hasKeepFilter = Object.values(keepFilter).some((v) => typeof v === "number");
|
|
43
44
|
if (hasIdFilter && hasKeepFilter)
|
|
44
|
-
throw new
|
|
45
|
+
throw new error_1.AppError(`Snapshot id filter can not be used with 'keep' filters`);
|
|
45
46
|
const prunePolicy = !hasIdFilter && !hasKeepFilter;
|
|
46
47
|
if (prunePolicy && !this.options.groupBy?.includes("packageName"))
|
|
47
|
-
throw new
|
|
48
|
+
throw new error_1.AppError(`Policy config requires groupBy packageName`);
|
|
48
49
|
const keepSnapshots = hasKeepFilter
|
|
49
50
|
? (0, snapshot_1.groupAndFilter)(snapshots, this.options.groupBy, keepFilter)
|
|
50
51
|
: prunePolicy
|
|
@@ -10,6 +10,7 @@ const config_1 = require("../utils/datatruck/config");
|
|
|
10
10
|
const repository_1 = require("../utils/datatruck/repository");
|
|
11
11
|
const task_1 = require("../utils/datatruck/task");
|
|
12
12
|
const date_1 = require("../utils/date");
|
|
13
|
+
const error_1 = require("../utils/error");
|
|
13
14
|
const fs_1 = require("../utils/fs");
|
|
14
15
|
const list_1 = require("../utils/list");
|
|
15
16
|
const progress_1 = require("../utils/progress");
|
|
@@ -69,8 +70,6 @@ class RestoreAction {
|
|
|
69
70
|
let { snapshot, pkg, task } = data;
|
|
70
71
|
const repoConfig = (0, config_1.findRepositoryOrFail)(this.config, snapshot.repositoryName);
|
|
71
72
|
const repo = await (0, repository_1.createAndInitRepo)(repoConfig, this.options.verbose);
|
|
72
|
-
if (this.options.initial)
|
|
73
|
-
pkg = { ...pkg, restorePath: pkg.path };
|
|
74
73
|
let snapshotPath = pkg.restorePath ?? pkg.path;
|
|
75
74
|
await data.gc.cleanupIfFail(async () => {
|
|
76
75
|
if (task) {
|
|
@@ -167,10 +166,10 @@ class RestoreAction {
|
|
|
167
166
|
if (minFreeDiskSpace)
|
|
168
167
|
await (0, temp_1.ensureFreeDiskTempSpace)(minFreeDiskSpace);
|
|
169
168
|
if (!options.snapshotId)
|
|
170
|
-
throw new
|
|
169
|
+
throw new error_1.AppError("Snapshot id is required");
|
|
171
170
|
const snapshots = this.groupSnapshots(await this.findSnapshots());
|
|
172
171
|
if (!snapshots.length)
|
|
173
|
-
throw new
|
|
172
|
+
throw new error_1.AppError("None snapshot found");
|
|
174
173
|
data.id = options.snapshotId;
|
|
175
174
|
data.packages = snapshots.length;
|
|
176
175
|
return snapshots.map((snapshot) => l.$task({
|
|
@@ -185,11 +184,13 @@ class RestoreAction {
|
|
|
185
184
|
},
|
|
186
185
|
exitOnError: false,
|
|
187
186
|
run: async (listTask) => {
|
|
188
|
-
|
|
187
|
+
let pkg = (0, config_1.resolvePackage)((0, config_1.findPackageOrFail)(this.config, snapshot.packageName), {
|
|
189
188
|
snapshotId: options.snapshotId,
|
|
190
189
|
snapshotDate: snapshot.date,
|
|
191
190
|
action: "restore",
|
|
192
191
|
});
|
|
192
|
+
if (this.options.initial)
|
|
193
|
+
pkg = { ...pkg, restorePath: pkg.path };
|
|
193
194
|
const gc = new temp_1.GargabeCollector();
|
|
194
195
|
const task = pkg.task ? (0, task_1.createTask)(pkg.task) : undefined;
|
|
195
196
|
const restore = await this.restore({
|
package/lib/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ const ConfigAction_1 = require("./actions/ConfigAction");
|
|
|
8
8
|
const globalData_1 = __importDefault(require("./globalData"));
|
|
9
9
|
const cli_1 = require("./utils/cli");
|
|
10
10
|
const command_1 = require("./utils/datatruck/command");
|
|
11
|
-
const error_1 = require("./utils/
|
|
11
|
+
const error_1 = require("./utils/error");
|
|
12
12
|
const exit_1 = require("./utils/exit");
|
|
13
13
|
const fs_1 = require("./utils/fs");
|
|
14
14
|
const string_1 = require("./utils/string");
|
|
@@ -4,6 +4,7 @@ exports.StartServerCommand = void 0;
|
|
|
4
4
|
const ConfigAction_1 = require("../actions/ConfigAction");
|
|
5
5
|
const cron_server_1 = require("../utils/datatruck/cron-server");
|
|
6
6
|
const repository_server_1 = require("../utils/datatruck/repository-server");
|
|
7
|
+
const error_1 = require("../utils/error");
|
|
7
8
|
const CommandAbstract_1 = require("./CommandAbstract");
|
|
8
9
|
class StartServerCommand extends CommandAbstract_1.CommandAbstract {
|
|
9
10
|
optionsConfig() {
|
|
@@ -31,7 +32,7 @@ class StartServerCommand extends CommandAbstract_1.CommandAbstract {
|
|
|
31
32
|
const cronOptions = config.server?.cron || {};
|
|
32
33
|
if (cronOptions.enabled ?? true) {
|
|
33
34
|
if (typeof this.configPath !== "string")
|
|
34
|
-
throw new
|
|
35
|
+
throw new error_1.AppError(`Config path is required by cron server`);
|
|
35
36
|
const server = (0, cron_server_1.createCronServer)(cronOptions, {
|
|
36
37
|
verbose,
|
|
37
38
|
log,
|
|
@@ -4,8 +4,8 @@ exports.DatatruckRepository = exports.datatruckRepositoryName = void 0;
|
|
|
4
4
|
const cli_1 = require("../utils/cli");
|
|
5
5
|
const crypto_1 = require("../utils/crypto");
|
|
6
6
|
const client_1 = require("../utils/datatruck/client");
|
|
7
|
-
const error_1 = require("../utils/datatruck/error");
|
|
8
7
|
const paths_1 = require("../utils/datatruck/paths");
|
|
8
|
+
const error_1 = require("../utils/error");
|
|
9
9
|
const fs_1 = require("../utils/fs");
|
|
10
10
|
const math_1 = require("../utils/math");
|
|
11
11
|
const string_1 = require("../utils/string");
|
|
@@ -65,7 +65,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
65
65
|
async fetchSnapshots(data) {
|
|
66
66
|
const fs = (0, client_1.createFs)(this.config.backend);
|
|
67
67
|
if (!(await fs.existsDir(".")))
|
|
68
|
-
throw new
|
|
68
|
+
throw new error_1.AppError(`Repository (${this.repository.name}) out path does not exist: ${fs.resolvePath(".")}`);
|
|
69
69
|
const snapshots = [];
|
|
70
70
|
const snapshotNames = await fs.readdir(".");
|
|
71
71
|
const packagePatterns = (0, string_1.makePathPatterns)(data.options.packageNames);
|
|
@@ -147,7 +147,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
147
147
|
scanner.total++;
|
|
148
148
|
stream.writeLine(defaultsPackIndex, ".");
|
|
149
149
|
await scanner.start(async (entry) => {
|
|
150
|
-
let packIndex =
|
|
150
|
+
let packIndex = packs.findIndex((pack) => pack !== defaultsPack &&
|
|
151
|
+
(0, string_1.match)(entry.path, pack.include, pack.exclude));
|
|
151
152
|
if (packIndex === -1)
|
|
152
153
|
packIndex = defaultsPackIndex;
|
|
153
154
|
const pack = packs[packIndex];
|
|
@@ -261,6 +262,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
261
262
|
relative: {
|
|
262
263
|
description: "Downloading",
|
|
263
264
|
format: "size",
|
|
265
|
+
payload: entry,
|
|
264
266
|
...progress,
|
|
265
267
|
},
|
|
266
268
|
}),
|
|
@@ -277,6 +279,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
277
279
|
relative: {
|
|
278
280
|
description: "Downloading",
|
|
279
281
|
format: "size",
|
|
282
|
+
payload: entry,
|
|
280
283
|
...progress,
|
|
281
284
|
},
|
|
282
285
|
}),
|
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ResticRepository = exports.resticRepositoryName = void 0;
|
|
7
7
|
const cli_1 = require("../utils/cli");
|
|
8
|
-
const error_1 = require("../utils/datatruck/error");
|
|
9
8
|
const paths_1 = require("../utils/datatruck/paths");
|
|
9
|
+
const error_1 = require("../utils/error");
|
|
10
10
|
const fs_1 = require("../utils/fs");
|
|
11
11
|
const math_1 = require("../utils/math");
|
|
12
12
|
const restic_1 = require("../utils/restic");
|
package/lib/tasks/GitTask.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GitTask = exports.gitTaskName = void 0;
|
|
4
4
|
const async_process_1 = require("../utils/async-process");
|
|
5
5
|
const cli_1 = require("../utils/cli");
|
|
6
|
+
const error_1 = require("../utils/error");
|
|
6
7
|
const fs_1 = require("../utils/fs");
|
|
7
8
|
const math_1 = require("../utils/math");
|
|
8
9
|
const stream_1 = require("../utils/stream");
|
|
@@ -21,7 +22,7 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
21
22
|
}
|
|
22
23
|
async backup(data) {
|
|
23
24
|
if (!data.package.path)
|
|
24
|
-
throw new
|
|
25
|
+
throw new error_1.AppError(`'package.path' is required`);
|
|
25
26
|
const snapshotPath = await (0, temp_1.mkTmpDir)(exports.gitTaskName, "task", "backup", "snapshot");
|
|
26
27
|
this.verbose = data.options.verbose;
|
|
27
28
|
const config = this.config;
|
package/lib/tasks/MssqlTask.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MssqlTask = exports.mssqlTaskName = void 0;
|
|
4
4
|
const async_process_1 = require("../utils/async-process");
|
|
5
5
|
const config_1 = require("../utils/datatruck/config");
|
|
6
|
-
const error_1 = require("../utils/
|
|
6
|
+
const error_1 = require("../utils/error");
|
|
7
7
|
const fs_1 = require("../utils/fs");
|
|
8
8
|
const temp_1 = require("../utils/temp");
|
|
9
9
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
@@ -51,7 +51,7 @@ class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
|
51
51
|
async backup(data) {
|
|
52
52
|
this.verbose = data.options.verbose;
|
|
53
53
|
if (data.package.path)
|
|
54
|
-
throw new
|
|
54
|
+
throw new error_1.AppError(`'package.path' is required: ${data.package.path}`);
|
|
55
55
|
const snapshotPath = await (0, temp_1.mkTmpDir)(exports.mssqlTaskName, "task", "backup", "snapshot");
|
|
56
56
|
const databaseNames = (await this.fetchDatabaseNames()).filter((databaseName) => (!this.config.includeDatabases ||
|
|
57
57
|
(0, micromatch_1.isMatch)(databaseName, this.config.includeDatabases)) &&
|
|
@@ -4,7 +4,7 @@ exports.MysqlDumpTask = exports.mysqlDumpTaskName = void 0;
|
|
|
4
4
|
const async_1 = require("../utils/async");
|
|
5
5
|
const cli_1 = require("../utils/cli");
|
|
6
6
|
const config_1 = require("../utils/datatruck/config");
|
|
7
|
-
const error_1 = require("../utils/
|
|
7
|
+
const error_1 = require("../utils/error");
|
|
8
8
|
const fs_1 = require("../utils/fs");
|
|
9
9
|
const math_1 = require("../utils/math");
|
|
10
10
|
const mysql_1 = require("../utils/mysql");
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SqlDumpTaskAbstract = void 0;
|
|
4
4
|
const cli_1 = require("../utils/cli");
|
|
5
5
|
const config_1 = require("../utils/datatruck/config");
|
|
6
|
-
const error_1 = require("../utils/
|
|
6
|
+
const error_1 = require("../utils/error");
|
|
7
7
|
const fs_1 = require("../utils/fs");
|
|
8
8
|
const math_1 = require("../utils/math");
|
|
9
9
|
const temp_1 = require("../utils/temp");
|
|
@@ -42,7 +42,7 @@ function parseSqlFile(fileName) {
|
|
|
42
42
|
return { fileName, database: lastName };
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
|
-
throw new
|
|
45
|
+
throw new error_1.AppError(`Invalid SQL file type: ${type}`);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AsyncProcess = void 0;
|
|
4
4
|
const cli_1 = require("./cli");
|
|
5
|
+
const error_1 = require("./error");
|
|
5
6
|
const math_1 = require("./math");
|
|
6
7
|
const process_1 = require("./process");
|
|
7
8
|
const stream_1 = require("./stream");
|
|
@@ -22,7 +23,7 @@ function ensureDir(cwd) {
|
|
|
22
23
|
}
|
|
23
24
|
catch (error) { }
|
|
24
25
|
if (!isDir)
|
|
25
|
-
throw new
|
|
26
|
+
throw new error_1.AppError(`Current working directory does not exist: ${cwd}`);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
class StdIn {
|
|
@@ -215,7 +216,7 @@ class AsyncProcess {
|
|
|
215
216
|
else if (result === false) {
|
|
216
217
|
return exitCode;
|
|
217
218
|
}
|
|
218
|
-
return new
|
|
219
|
+
return new error_1.AppError(message, {
|
|
219
220
|
cause: {
|
|
220
221
|
command: this.command,
|
|
221
222
|
argv: this.argv,
|
package/lib/utils/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.confirm = exports.stringifyOptions = exports.parseOptions = exports.renderObject = exports.renderListTaskItem = exports.renderError = exports.renderResult = exports.logExec = exports.renderProgressBar = exports.showCursorCommand = void 0;
|
|
7
|
+
const error_1 = require("./error");
|
|
7
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
9
|
const chalk_2 = require("chalk");
|
|
9
10
|
const readline_1 = require("readline");
|
|
@@ -59,20 +60,19 @@ function renderResult(error, color = true) {
|
|
|
59
60
|
}
|
|
60
61
|
exports.renderResult = renderResult;
|
|
61
62
|
function renderError(error, verbose) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
message = error;
|
|
63
|
+
if (!error) {
|
|
64
|
+
return "";
|
|
65
65
|
}
|
|
66
|
-
else if (error) {
|
|
67
|
-
message
|
|
66
|
+
else if (error instanceof error_1.AppError) {
|
|
67
|
+
return chalk_1.default.red(verbose ? error.stack ?? error.message : error.message);
|
|
68
68
|
}
|
|
69
|
-
else {
|
|
70
|
-
return
|
|
69
|
+
else if (error instanceof Error) {
|
|
70
|
+
return chalk_1.default.red(error.stack ?? error.message);
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
message =
|
|
72
|
+
else {
|
|
73
|
+
const message = error.split(/\r?\n/).shift() ?? "";
|
|
74
|
+
return chalk_1.default.red(message.trim());
|
|
74
75
|
}
|
|
75
|
-
return chalk_1.default.red(message.trim());
|
|
76
76
|
}
|
|
77
77
|
exports.renderError = renderError;
|
|
78
78
|
function renderListTaskItem(item, color, config) {
|
package/lib/utils/data-format.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.DataFormat = exports.dataFormats = void 0;
|
|
7
|
-
const error_1 = require("./
|
|
7
|
+
const error_1 = require("./error");
|
|
8
8
|
const stream_1 = require("./stream");
|
|
9
9
|
const tty_table_1 = __importDefault(require("tty-table"));
|
|
10
10
|
const util_1 = require("util");
|
|
@@ -47,13 +47,13 @@ class DataFormat {
|
|
|
47
47
|
}
|
|
48
48
|
formatToTable() {
|
|
49
49
|
if (!this.options.table)
|
|
50
|
-
throw new
|
|
50
|
+
throw new error_1.AppError(`Unsupported format: table`);
|
|
51
51
|
const table = (0, tty_table_1.default)(this.options.table.headers, this.options.table.rows(), {});
|
|
52
52
|
return table.render();
|
|
53
53
|
}
|
|
54
54
|
formatToList() {
|
|
55
55
|
if (!this.options.list)
|
|
56
|
-
throw new
|
|
56
|
+
throw new error_1.AppError(`Unsupported format: list`);
|
|
57
57
|
return this.options.list().join("\n");
|
|
58
58
|
}
|
|
59
59
|
log(format, options) {
|
|
@@ -10,7 +10,7 @@ const PruneCommand_1 = require("../../commands/PruneCommand");
|
|
|
10
10
|
const RestoreCommand_1 = require("../../commands/RestoreCommand");
|
|
11
11
|
const SnapshotsCommand_1 = require("../../commands/SnapshotsCommand");
|
|
12
12
|
const StartServerCommand_1 = require("../../commands/StartServerCommand");
|
|
13
|
-
const error_1 = require("
|
|
13
|
+
const error_1 = require("../error");
|
|
14
14
|
const stream_1 = require("stream");
|
|
15
15
|
exports.datatruckCommandMap = {
|
|
16
16
|
config: ConfigCommand_1.ConfigCommand,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.params = exports.dbNameParams = exports.pkgRestorePathParams = exports.pkgExcludeParams = exports.pkgIncludeParams = exports.pkgPathParams = exports.resolvePackages = exports.resolvePackage = exports.resolveDatabaseName = exports.resolvePackagePath = exports.filterPackages = exports.filterRepositoryByEnabled = exports.ensureSameRepositoryType = exports.sortReposByType = exports.filterRepository = exports.findPackageRepositoryConfig = exports.findPackageOrFail = exports.findRepositoryOrFail = void 0;
|
|
4
|
+
const error_1 = require("../error");
|
|
4
5
|
const string_1 = require("../string");
|
|
5
6
|
const temp_1 = require("../temp");
|
|
6
|
-
const error_1 = require("./error");
|
|
7
7
|
const micromatch_1 = require("micromatch");
|
|
8
8
|
function findRepositoryOrFail(config, repositoryName) {
|
|
9
9
|
const repo = config.repositories.find((v) => v.name === repositoryName);
|
|
@@ -59,7 +59,7 @@ function ensureSameRepositoryType(a, b) {
|
|
|
59
59
|
if (a.type !== b.type) {
|
|
60
60
|
const names = [a.name, b.name].join(" and ");
|
|
61
61
|
const types = [a.type, b.type].join(" != ");
|
|
62
|
-
throw new
|
|
62
|
+
throw new error_1.AppError(`Incompatible repository types between ${names} (${types})`);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
exports.ensureSameRepositoryType = ensureSameRepositoryType;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createReportListTasks = void 0;
|
|
4
|
+
const error_1 = require("../error");
|
|
4
5
|
const reportSteps_1 = require("../reportSteps");
|
|
5
6
|
const spawnSteps_1 = require("../spawnSteps");
|
|
6
7
|
function createReportListTasks(list, options) {
|
|
@@ -48,7 +49,7 @@ function createReportListTasks(list, options) {
|
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
51
|
else {
|
|
51
|
-
throw new
|
|
52
|
+
throw new error_1.AppError(`Invalid step type: ${report.run.type}`);
|
|
52
53
|
}
|
|
53
54
|
},
|
|
54
55
|
});
|
|
@@ -4,7 +4,7 @@ exports.createAndInitRepo = exports.createRepo = exports.getRepoConstructor = vo
|
|
|
4
4
|
const DatatruckRepository_1 = require("../../repositories/DatatruckRepository");
|
|
5
5
|
const GitRepository_1 = require("../../repositories/GitRepository");
|
|
6
6
|
const ResticRepository_1 = require("../../repositories/ResticRepository");
|
|
7
|
-
const error_1 = require("
|
|
7
|
+
const error_1 = require("../error");
|
|
8
8
|
const repoMap = {
|
|
9
9
|
[GitRepository_1.gitRepositoryName]: GitRepository_1.GitRepository,
|
|
10
10
|
[ResticRepository_1.resticRepositoryName]: ResticRepository_1.ResticRepository,
|
|
@@ -7,7 +7,7 @@ const MssqlTask_1 = require("../../tasks/MssqlTask");
|
|
|
7
7
|
const MysqlDumpTask_1 = require("../../tasks/MysqlDumpTask");
|
|
8
8
|
const PostgresqlDumpTask_1 = require("../../tasks/PostgresqlDumpTask");
|
|
9
9
|
const ScriptTask_1 = require("../../tasks/ScriptTask");
|
|
10
|
-
const error_1 = require("
|
|
10
|
+
const error_1 = require("../error");
|
|
11
11
|
function createTask(task) {
|
|
12
12
|
if (task.name === GitTask_1.gitTaskName) {
|
|
13
13
|
return new GitTask_1.GitTask(task.config ?? {});
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AppError = void 0;
|
|
4
4
|
class AppError extends Error {
|
|
5
|
-
constructor(message) {
|
|
6
|
-
super(message);
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message, options);
|
|
7
7
|
this.name = AppError.name;
|
|
8
8
|
}
|
|
9
9
|
static create(message, errors) {
|
package/lib/utils/fs.js
CHANGED
|
@@ -6,6 +6,7 @@ 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.readTextFile = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.readPartialFile = exports.fastFolderSizeAsync = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.include = 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
7
|
const pkg_1 = require("../pkg");
|
|
8
8
|
const bytes_1 = require("./bytes");
|
|
9
|
+
const error_1 = require("./error");
|
|
9
10
|
const math_1 = require("./math");
|
|
10
11
|
const stream_1 = require("./stream");
|
|
11
12
|
const string_1 = require("./string");
|
|
@@ -53,20 +54,20 @@ async function mkdirIfNotExists(path) {
|
|
|
53
54
|
exports.mkdirIfNotExists = mkdirIfNotExists;
|
|
54
55
|
async function ensureEmptyDir(path) {
|
|
55
56
|
if (!(await isEmptyDir(path)))
|
|
56
|
-
throw new
|
|
57
|
+
throw new error_1.AppError(`Dir is not empty: ${path}`);
|
|
57
58
|
}
|
|
58
59
|
exports.ensureEmptyDir = ensureEmptyDir;
|
|
59
60
|
async function ensureSingleFile(path) {
|
|
60
61
|
const files = await readDir(path);
|
|
61
62
|
if (files.length !== 1)
|
|
62
|
-
throw new
|
|
63
|
+
throw new error_1.AppError(`Dir has not one file: ${files.length}`);
|
|
63
64
|
const [file] = files;
|
|
64
65
|
return (0, path_1.join)(path, file);
|
|
65
66
|
}
|
|
66
67
|
exports.ensureSingleFile = ensureSingleFile;
|
|
67
68
|
async function ensureExistsDir(path) {
|
|
68
69
|
if (!(await existsDir(path)))
|
|
69
|
-
throw new
|
|
70
|
+
throw new error_1.AppError(`Dir is not created: ${path}`);
|
|
70
71
|
}
|
|
71
72
|
exports.ensureExistsDir = ensureExistsDir;
|
|
72
73
|
async function safeStat(path) {
|
package/lib/utils/mysql.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createMysqlCli = exports.assertDumpFile = void 0;
|
|
4
4
|
const async_process_1 = require("./async-process");
|
|
5
5
|
const cli_1 = require("./cli");
|
|
6
|
-
const error_1 = require("./
|
|
6
|
+
const error_1 = require("./error");
|
|
7
7
|
const fs_1 = require("./fs");
|
|
8
8
|
const process_1 = require("./process");
|
|
9
9
|
const string_1 = require("./string");
|
package/lib/utils/object.d.ts
CHANGED
package/lib/utils/object.js
CHANGED
package/lib/utils/reportSteps.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runReportSteps = exports.isReportStep = void 0;
|
|
4
|
+
const error_1 = require("./error");
|
|
4
5
|
const http_1 = require("./http");
|
|
5
6
|
function isReportStep(step) {
|
|
6
7
|
return step.type === "telegram" || step.type === "ntfy";
|
|
@@ -25,7 +26,7 @@ async function runReportSteps(input, options) {
|
|
|
25
26
|
.filter(Boolean)
|
|
26
27
|
.join("-");
|
|
27
28
|
if (topic.length < 32)
|
|
28
|
-
throw new
|
|
29
|
+
throw new error_1.AppError(`'step.config.topic' is less than 32 characters: ${topic}`);
|
|
29
30
|
await (0, http_1.post)(`https://ntfy.sh/${topic}`, options.data.message, {
|
|
30
31
|
headers: {
|
|
31
32
|
Title: options.data.title,
|
|
@@ -34,7 +35,7 @@ async function runReportSteps(input, options) {
|
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
37
|
-
throw new
|
|
38
|
+
throw new error_1.AppError(`Invalid step type: ${step.type}`);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
}
|
package/lib/utils/string.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.compareJsons = exports.undefIfEmpty = exports.checkMatch = exports.createMatchFilter = exports.endsWith = exports.match = exports.makePathPatterns = exports.formatUri = exports.parseStringList = exports.render = exports.snakeCase = void 0;
|
|
4
|
-
const error_1 = require("./
|
|
4
|
+
const error_1 = require("./error");
|
|
5
5
|
const micromatch_1 = require("micromatch");
|
|
6
6
|
function snakeCase(value, char = "_") {
|
|
7
7
|
return value.replace(/[A-Z]/g, (letter) => `${char}${letter.toLowerCase()}`);
|