@datatruck/cli 0.34.3 → 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.
@@ -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 Error(`Invalid snapshot date: ${date}`);
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 Error(`Task failed`);
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 Error(`Backup failed`);
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/datatruck/error");
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 Error("No snapshots found");
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 Error("No mirror snapshots found");
222
+ throw new error_1.AppError("No mirror snapshots found");
216
223
  const sourceRepoMap = this.createSourceRepoMap();
217
- return data.snapshots.flatMap((snapshot) => repositoryNames2.map((repo2) => {
218
- const id = snapshot.id.slice(0, 8);
219
- const pkgName = snapshot.packageName;
220
- return l.$task({
221
- key: "copy",
222
- keyIndex: [snapshot.packageName, repo2.name, snapshot.id],
223
- data: {
224
- snapshotId: snapshot.id,
225
- packageName: snapshot.packageName,
226
- repositoryName: repoConfig.name,
227
- mirrorRepositoryName: repo2.name,
228
- bytes: 0,
229
- skipped: false,
230
- },
231
- title: {
232
- initial: `Copy snapshot: ${pkgName} (${id}) » ${repo2.name}`,
233
- started: `Copying snapshot: ${pkgName} (${id}) » ${repo2.name}`,
234
- completed: `Snapshot copied: ${pkgName} (${id}) » ${repo2.name}`,
235
- failed: `Snapshot copy failed: ${pkgName} (${id}) » ${repo2.name}`,
236
- },
237
- exitOnError: false,
238
- run: async (task, data) => {
239
- const mirrorConfig = (0, config_1.findRepositoryOrFail)(this.config, repo2.name);
240
- const mirrorRepo = await (0, repository_1.createAndInitRepo)(mirrorConfig, this.options.verbose);
241
- const currentCopies = await mirrorRepo.fetchSnapshots({
242
- options: {
243
- ids: [snapshot.id],
244
- packageNames: [snapshot.packageName],
245
- verbose: this.options.verbose,
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
- data.bytes = copy.bytes;
278
- sourceRepo.set(mirrorRepo);
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 Error(`Snapshot id filter can not be used with 'keep' filters`);
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 Error(`Policy config requires groupBy packageName`);
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");
@@ -165,10 +166,10 @@ class RestoreAction {
165
166
  if (minFreeDiskSpace)
166
167
  await (0, temp_1.ensureFreeDiskTempSpace)(minFreeDiskSpace);
167
168
  if (!options.snapshotId)
168
- throw new Error("Snapshot id is required");
169
+ throw new error_1.AppError("Snapshot id is required");
169
170
  const snapshots = this.groupSnapshots(await this.findSnapshots());
170
171
  if (!snapshots.length)
171
- throw new Error("None snapshot found");
172
+ throw new error_1.AppError("None snapshot found");
172
173
  data.id = options.snapshotId;
173
174
  data.packages = snapshots.length;
174
175
  return snapshots.map((snapshot) => l.$task({
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/datatruck/error");
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 Error(`Config path is required by cron server`);
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 Error(`Repository (${this.repository.name}) out path does not exist: ${fs.resolvePath(".")}`);
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 = configPacks.findIndex((pack) => (0, string_1.match)(entry.path, pack.include, pack.exclude));
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");
@@ -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 Error(`Path is required`);
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;
@@ -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/datatruck/error");
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 Error(`Path is not required: ${data.package.path}`);
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/datatruck/error");
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/datatruck/error");
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 Error(`Invalid sql file type: ${type}`);
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 Error(`Current working directory does not exist: ${cwd}`);
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 Error(message, {
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
- let message = null;
63
- if (typeof error === "string") {
64
- message = error;
63
+ if (!error) {
64
+ return "";
65
65
  }
66
- else if (error) {
67
- message = error.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
- if (!verbose) {
73
- message = message.split(/\r?\n/).shift() ?? "";
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) {
@@ -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("./datatruck/error");
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 Error(`Unsupported format: table`);
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 Error(`Unsupported format: list`);
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("./error");
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 Error(`Incompatible repository types between ${names} (${types})`);
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 Error(`Invalid step type: ${report.run.type}`);
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("./error");
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("./error");
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 ?? {});
@@ -1,4 +1,4 @@
1
1
  export declare class AppError extends Error {
2
- constructor(message: string);
2
+ constructor(message: string, options?: ErrorOptions);
3
3
  static create(message: string, errors: Error[]): Error;
4
4
  }
@@ -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 Error(`Dir is not empty: ${path}`);
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 Error(`Dir has not one file: ${files.length}`);
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 Error(`Dir is not created: ${path}`);
70
+ throw new error_1.AppError(`Dir is not created: ${path}`);
70
71
  }
71
72
  exports.ensureExistsDir = ensureExistsDir;
72
73
  async function safeStat(path) {
@@ -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("./datatruck/error");
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");
@@ -11,7 +11,7 @@ export declare class StrictMap<K, V> {
11
11
  has(key: K): boolean;
12
12
  get(key: K): NonNullable<V>;
13
13
  set(key: K, value: V): void;
14
- with(key: K): {
14
+ withKey(key: K): {
15
15
  has: () => boolean;
16
16
  get: () => NonNullable<V>;
17
17
  set: (value: V) => void;
@@ -78,7 +78,7 @@ class StrictMap {
78
78
  throw new Error(`Map key already exists: ${stringKey}`);
79
79
  this.map.set(stringKey, value);
80
80
  }
81
- with(key) {
81
+ withKey(key) {
82
82
  return {
83
83
  has: () => this.has(key),
84
84
  get: () => this.get(key),
@@ -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 Error(`Topic is less than 32 characters: ${topic}`);
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 Error(`Invalid step type: ${step.type}`);
38
+ throw new error_1.AppError(`Invalid step type: ${step.type}`);
38
39
  }
39
40
  }
40
41
  }
@@ -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("./datatruck/error");
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()}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datatruck/cli",
3
- "version": "0.34.3",
3
+ "version": "0.34.4",
4
4
  "description": "Tool for creating and managing backups",
5
5
  "homepage": "https://github.com/swordev/datatruck#readme",
6
6
  "bugs": {