@datatruck/cli 0.32.2 → 0.33.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.
Files changed (127) hide show
  1. package/config.schema.json +374 -31
  2. package/lib/{Action → actions}/BackupAction.d.ts +5 -17
  3. package/lib/{Action → actions}/BackupAction.js +32 -85
  4. package/lib/{Action → actions}/ConfigAction.d.ts +4 -2
  5. package/lib/{Action → actions}/ConfigAction.js +16 -8
  6. package/lib/{Action → actions}/CopyAction.d.ts +17 -13
  7. package/lib/actions/CopyAction.js +285 -0
  8. package/lib/{Action → actions}/InitAction.d.ts +1 -1
  9. package/lib/{Action → actions}/InitAction.js +3 -3
  10. package/lib/{Action → actions}/PruneAction.d.ts +1 -2
  11. package/lib/{Action → actions}/PruneAction.js +2 -2
  12. package/lib/{Action → actions}/RestoreAction.d.ts +4 -13
  13. package/lib/{Action → actions}/RestoreAction.js +17 -17
  14. package/lib/{Action → actions}/SnapshotsAction.d.ts +2 -3
  15. package/lib/{Action → actions}/SnapshotsAction.js +3 -3
  16. package/lib/cli.d.ts +3 -3
  17. package/lib/cli.js +18 -17
  18. package/lib/commands/BackupCommand.d.ts +43 -0
  19. package/lib/{Command → commands}/BackupCommand.js +7 -6
  20. package/lib/{Command → commands}/CleanCacheCommand.d.ts +4 -2
  21. package/lib/{Command → commands}/CleanCacheCommand.js +6 -5
  22. package/lib/{Command → commands}/CommandAbstract.d.ts +10 -6
  23. package/lib/{Command → commands}/CommandAbstract.js +5 -3
  24. package/lib/commands/ConfigCommand.d.ts +22 -0
  25. package/lib/{Command → commands}/ConfigCommand.js +5 -5
  26. package/lib/commands/CopyCommand.d.ts +17 -0
  27. package/lib/{Command → commands}/CopyCommand.js +7 -6
  28. package/lib/commands/InitCommand.d.ts +19 -0
  29. package/lib/{Command → commands}/InitCommand.js +9 -9
  30. package/lib/{Command → commands}/PruneCommand.d.ts +7 -4
  31. package/lib/{Command → commands}/PruneCommand.js +11 -11
  32. package/lib/commands/RestoreCommand.d.ts +38 -0
  33. package/lib/{Command → commands}/RestoreCommand.js +7 -6
  34. package/lib/{Command → commands}/SnapshotsCommand.d.ts +8 -6
  35. package/lib/{Command → commands}/SnapshotsCommand.js +12 -12
  36. package/lib/{Command → commands}/StartServerCommand.d.ts +4 -2
  37. package/lib/{Command → commands}/StartServerCommand.js +5 -5
  38. package/lib/index.d.ts +20 -23
  39. package/lib/index.js +8 -8
  40. package/lib/{Repository → repositories}/DatatruckRepository.js +2 -2
  41. package/lib/{Repository → repositories}/RepositoryAbstract.d.ts +7 -7
  42. package/lib/{Repository → repositories}/ResticRepository.js +7 -6
  43. package/lib/{Task → tasks}/MssqlTask.js +2 -2
  44. package/lib/{Task → tasks}/MysqlDumpTask.js +4 -4
  45. package/lib/{Task → tasks}/ScriptTask.d.ts +2 -2
  46. package/lib/{Task → tasks}/SqlDumpTaskAbstract.js +4 -4
  47. package/lib/{Task → tasks}/TaskAbstract.d.ts +4 -4
  48. package/lib/utils/DataFormat.js +3 -3
  49. package/lib/utils/Restic.d.ts +1 -0
  50. package/lib/utils/Restic.js +12 -2
  51. package/lib/utils/cli.d.ts +9 -3
  52. package/lib/utils/cli.js +17 -1
  53. package/lib/utils/cron.d.ts +11 -0
  54. package/lib/utils/cron.js +27 -0
  55. package/lib/utils/datatruck/command.d.ts +29 -0
  56. package/lib/utils/datatruck/command.js +61 -0
  57. package/lib/{Config/RepositoryConfig.d.ts → utils/datatruck/config-repository-type.d.ts} +19 -8
  58. package/lib/{Config/TaskConfig.d.ts → utils/datatruck/config-task-type.d.ts} +6 -6
  59. package/lib/utils/datatruck/config-type.d.ts +50 -0
  60. package/lib/utils/datatruck/config.d.ts +19 -10
  61. package/lib/utils/datatruck/config.js +43 -7
  62. package/lib/utils/datatruck/cron-server.d.ts +27 -6
  63. package/lib/utils/datatruck/cron-server.js +38 -20
  64. package/lib/utils/datatruck/paths.d.ts +2 -2
  65. package/lib/utils/datatruck/report-list.d.ts +12 -0
  66. package/lib/utils/datatruck/report-list.js +57 -0
  67. package/lib/utils/datatruck/repository-server.js +3 -2
  68. package/lib/utils/datatruck/repository.d.ts +16 -0
  69. package/lib/utils/datatruck/repository.js +30 -0
  70. package/lib/utils/datatruck/snapshot.d.ts +2 -2
  71. package/lib/utils/datatruck/task.d.ts +3 -0
  72. package/lib/{Factory/TaskFactory.js → utils/datatruck/task.js} +8 -8
  73. package/lib/utils/date.js +6 -2
  74. package/lib/utils/fs.d.ts +3 -0
  75. package/lib/utils/fs.js +24 -4
  76. package/lib/utils/list.d.ts +5 -5
  77. package/lib/utils/mysql.js +5 -5
  78. package/lib/utils/object.d.ts +13 -0
  79. package/lib/utils/object.js +32 -1
  80. package/lib/utils/process.js +4 -1
  81. package/lib/utils/string.d.ts +1 -0
  82. package/lib/utils/string.js +7 -3
  83. package/lib/utils/ts.d.ts +16 -0
  84. package/lib/utils/watcher.d.ts +10 -0
  85. package/lib/utils/watcher.js +34 -0
  86. package/package.json +3 -3
  87. package/lib/Action/CopyAction.js +0 -164
  88. package/lib/Command/BackupCommand.d.ts +0 -19
  89. package/lib/Command/ConfigCommand.d.ts +0 -15
  90. package/lib/Command/CopyCommand.d.ts +0 -16
  91. package/lib/Command/InitCommand.d.ts +0 -13
  92. package/lib/Command/RestoreCommand.d.ts +0 -17
  93. package/lib/Config/Config.d.ts +0 -28
  94. package/lib/Config/PackageConfig.d.ts +0 -24
  95. package/lib/Config/PackageRepositoryConfig.d.ts +0 -15
  96. package/lib/Config/PrunePolicyConfig.d.ts +0 -2
  97. package/lib/Config/RepositoryConfig.js +0 -2
  98. package/lib/Config/TaskConfig.js +0 -2
  99. package/lib/Factory/CommandFactory.d.ts +0 -45
  100. package/lib/Factory/CommandFactory.js +0 -96
  101. package/lib/Factory/RepositoryFactory.d.ts +0 -3
  102. package/lib/Factory/RepositoryFactory.js +0 -23
  103. package/lib/Factory/TaskFactory.d.ts +0 -3
  104. /package/lib/{Action → actions}/CleanCacheAction.d.ts +0 -0
  105. /package/lib/{Action → actions}/CleanCacheAction.js +0 -0
  106. /package/lib/{Repository → repositories}/DatatruckRepository.d.ts +0 -0
  107. /package/lib/{Repository → repositories}/GitRepository.d.ts +0 -0
  108. /package/lib/{Repository → repositories}/GitRepository.js +0 -0
  109. /package/lib/{Repository → repositories}/RepositoryAbstract.js +0 -0
  110. /package/lib/{Repository → repositories}/ResticRepository.d.ts +0 -0
  111. /package/lib/{Task → tasks}/GitTask.d.ts +0 -0
  112. /package/lib/{Task → tasks}/GitTask.js +0 -0
  113. /package/lib/{Task → tasks}/MariadbTask.d.ts +0 -0
  114. /package/lib/{Task → tasks}/MariadbTask.js +0 -0
  115. /package/lib/{Task → tasks}/MssqlTask.d.ts +0 -0
  116. /package/lib/{Task → tasks}/MysqlDumpTask.d.ts +0 -0
  117. /package/lib/{Task → tasks}/PostgresqlDumpTask.d.ts +0 -0
  118. /package/lib/{Task → tasks}/PostgresqlDumpTask.js +0 -0
  119. /package/lib/{Task → tasks}/ScriptTask.js +0 -0
  120. /package/lib/{Task → tasks}/SqlDumpTaskAbstract.d.ts +0 -0
  121. /package/lib/{Task → tasks}/TaskAbstract.js +0 -0
  122. /package/lib/{Config/Config.js → utils/datatruck/config-repository-type.js} +0 -0
  123. /package/lib/{Config/PackageConfig.js → utils/datatruck/config-task-type.js} +0 -0
  124. /package/lib/{Config/PackageRepositoryConfig.js → utils/datatruck/config-type.js} +0 -0
  125. /package/lib/{Error/AppError.d.ts → utils/datatruck/error.d.ts} +0 -0
  126. /package/lib/{Error/AppError.js → utils/datatruck/error.js} +0 -0
  127. /package/lib/{Config/PrunePolicyConfig.js → utils/ts.js} +0 -0
@@ -6,6 +6,7 @@ const process_1 = require("./process");
6
6
  const string_1 = require("./string");
7
7
  const promises_1 = require("fs/promises");
8
8
  const path_1 = require("path");
9
+ const emptySnapshotTag = "empty-snapshot";
9
10
  class Restic {
10
11
  options;
11
12
  constructor(options) {
@@ -95,6 +96,7 @@ class Restic {
95
96
  ...(options.json ? ["--json"] : []),
96
97
  ...(options.paths?.flatMap((path) => ["--path", path]) ?? []),
97
98
  ...(options.latest ? ["--latest", options.latest.toString()] : []),
99
+ ...(options.snapshotIds || []),
98
100
  ], {
99
101
  stdout: { save: true },
100
102
  });
@@ -151,9 +153,10 @@ class Restic {
151
153
  error.message.includes("unable to save snapshot: snapshot is empty")) {
152
154
  if (options.createEmptyDir) {
153
155
  const emptyPath = await options.createEmptyDir();
154
- await (0, promises_1.writeFile)(`${emptyPath}/.empty`, "");
156
+ await (0, promises_1.writeFile)(`${emptyPath}/.${emptySnapshotTag}`, "");
155
157
  return await this.backup({
156
158
  ...options,
159
+ tags: [...(options.tags || []), emptySnapshotTag],
157
160
  cwd: emptyPath,
158
161
  allowEmptySnapshot: false,
159
162
  paths: ["."],
@@ -197,10 +200,14 @@ class Restic {
197
200
  progressTimeout = setTimeout(progressRutine, progressInterval);
198
201
  }
199
202
  }
203
+ const snapshots = await this.snapshots({
204
+ snapshotIds: [options.id],
205
+ json: true,
206
+ });
200
207
  if (typeof progressInterval === "number")
201
208
  progressRutine();
202
209
  try {
203
- return await this.exec(["restore", "--json", options.id, "--target", options.target], {
210
+ const result = await this.exec(["restore", "--json", options.id, "--target", options.target], {
204
211
  stderr: {
205
212
  toExitCode: true,
206
213
  },
@@ -214,6 +221,9 @@ class Restic {
214
221
  }),
215
222
  },
216
223
  });
224
+ if (snapshots.at(0)?.tags?.includes(emptySnapshotTag))
225
+ await (0, promises_1.rm)((0, path_1.join)(options.target, `.${emptySnapshotTag}`));
226
+ return result;
217
227
  }
218
228
  finally {
219
229
  clearTimeout(progressTimeout);
@@ -1,11 +1,17 @@
1
1
  /// <reference types="node" />
2
+ import { Listr3TaskResultEnd } from "./list";
2
3
  export declare const showCursorCommand = "\u001B[?25h";
3
4
  export declare function renderProgressBar(progress: number, size?: number, subprogress?: number): string;
4
5
  export declare function logExec(command: string, argv?: string[], env?: NodeJS.ProcessEnv, logToStderr?: boolean): void;
5
6
  export declare function renderResult(error: Error | null | string | boolean | undefined, color?: boolean): string;
6
7
  export declare function renderError(error: Error | null | string | undefined, verbose?: number): string;
8
+ export declare function renderListTaskItem<T extends Record<string, any>>(item: Listr3TaskResultEnd<T>, color: boolean | undefined, config: {
9
+ [K in Listr3TaskResultEnd<T>["key"]]: (data: Extract<Listr3TaskResultEnd<T>, {
10
+ key: K;
11
+ }>["data"]) => string | number | string[] | Record<string, string | number>;
12
+ }): string;
7
13
  export declare function renderObject(object: Record<string, any>, color?: boolean): string;
8
- export type OptionsType<T1, T2 extends {
14
+ export type OptionsConfig<T1, T2 extends {
9
15
  [K in keyof T1]: unknown;
10
16
  }> = {
11
17
  [K in keyof Required<T1>]: {
@@ -18,8 +24,8 @@ export type OptionsType<T1, T2 extends {
18
24
  };
19
25
  export declare function parseOptions<T1, T2 extends {
20
26
  [K in keyof T1]: unknown;
21
- }>(object: T1, options: OptionsType<T1, T2>): T2;
27
+ }>(object: T1, options: OptionsConfig<T1, T2>): T2;
22
28
  export declare function stringifyOptions<T1, T2 extends {
23
29
  [K in keyof T1]: unknown;
24
- }>(options: OptionsType<T1, T2>, object: any): string[];
30
+ }>(options: OptionsConfig<T1, T2>, object: any): string[];
25
31
  export declare function confirm(message: string): Promise<unknown>;
package/lib/utils/cli.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.confirm = exports.stringifyOptions = exports.parseOptions = exports.renderObject = exports.renderError = exports.renderResult = exports.logExec = exports.renderProgressBar = exports.showCursorCommand = void 0;
6
+ exports.confirm = exports.stringifyOptions = exports.parseOptions = exports.renderObject = exports.renderListTaskItem = exports.renderError = exports.renderResult = exports.logExec = exports.renderProgressBar = exports.showCursorCommand = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  const chalk_2 = require("chalk");
9
9
  const readline_1 = require("readline");
@@ -75,6 +75,22 @@ function renderError(error, verbose) {
75
75
  return chalk_1.default.red(message.trim());
76
76
  }
77
77
  exports.renderError = renderError;
78
+ function renderListTaskItem(item, color, config) {
79
+ const result = config[item.key]?.(item.data);
80
+ if (typeof result === "string" || typeof result === "number") {
81
+ return result.toString();
82
+ }
83
+ else if (Array.isArray(result)) {
84
+ return result.join(" ");
85
+ }
86
+ else if (typeof result === "object" && !!result) {
87
+ return renderObject(result, color);
88
+ }
89
+ else {
90
+ return "";
91
+ }
92
+ }
93
+ exports.renderListTaskItem = renderListTaskItem;
78
94
  function renderObject(object, color) {
79
95
  const values = [];
80
96
  for (const key in object)
@@ -0,0 +1,11 @@
1
+ export type CronScheduleUnit = number | {
2
+ each: number;
3
+ };
4
+ export type CronScheduleObject = {
5
+ minute?: CronScheduleUnit;
6
+ hour?: CronScheduleUnit;
7
+ day?: CronScheduleUnit;
8
+ month?: CronScheduleUnit;
9
+ weekDay?: CronScheduleUnit;
10
+ };
11
+ export declare function formatCronScheduleObject(object: CronScheduleObject): string;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatCronScheduleObject = void 0;
4
+ function formatCronScheduleObject(object) {
5
+ const keys = [
6
+ "minute",
7
+ "hour",
8
+ "day",
9
+ "month",
10
+ "weekDay",
11
+ ];
12
+ const result = [];
13
+ for (const key of keys) {
14
+ const value = object[key];
15
+ if (typeof value === "number") {
16
+ result.push(value.toString());
17
+ }
18
+ else if (!!value && typeof value === "object") {
19
+ result.push(`*/${value.each}`);
20
+ }
21
+ else {
22
+ result.push("*");
23
+ }
24
+ }
25
+ return result.join(" ");
26
+ }
27
+ exports.formatCronScheduleObject = formatCronScheduleObject;
@@ -0,0 +1,29 @@
1
+ import { BackupCommand } from "../../commands/BackupCommand";
2
+ import { CleanCacheCommand } from "../../commands/CleanCacheCommand";
3
+ import { GlobalOptions } from "../../commands/CommandAbstract";
4
+ import { ConfigCommand } from "../../commands/ConfigCommand";
5
+ import { CopyCommand } from "../../commands/CopyCommand";
6
+ import { InitCommand } from "../../commands/InitCommand";
7
+ import { PruneCommand } from "../../commands/PruneCommand";
8
+ import { RestoreCommand } from "../../commands/RestoreCommand";
9
+ import { SnapshotsCommand } from "../../commands/SnapshotsCommand";
10
+ import { StartServerCommand } from "../../commands/StartServerCommand";
11
+ import { Streams } from "../stream";
12
+ export declare const datatruckCommandMap: {
13
+ config: typeof ConfigCommand;
14
+ init: typeof InitCommand;
15
+ snapshots: typeof SnapshotsCommand;
16
+ prune: typeof PruneCommand;
17
+ backup: typeof BackupCommand;
18
+ restore: typeof RestoreCommand;
19
+ copy: typeof CopyCommand;
20
+ cleanCache: typeof CleanCacheCommand;
21
+ startServer: typeof StartServerCommand;
22
+ };
23
+ export type DatatruckCommandMap = typeof datatruckCommandMap;
24
+ export type InferDatatruckCommandOptions<T extends keyof DatatruckCommandMap> = InstanceType<DatatruckCommandMap[T]>["inputOptions"];
25
+ export type InferDatatruckCommandResult<T extends keyof DatatruckCommandMap, R = Awaited<ReturnType<InstanceType<DatatruckCommandMap[T]>["exec"]>>> = "result" extends keyof R ? R["result"] : undefined;
26
+ export declare function createCommand<T extends keyof DatatruckCommandMap>(name: T, globalOptions: GlobalOptions<true>, options: InferDatatruckCommandOptions<T>, streams?: Partial<Streams>, configPath?: string): BackupCommand | CopyCommand | PruneCommand | CleanCacheCommand | ConfigCommand | InitCommand | RestoreCommand | SnapshotsCommand | StartServerCommand;
27
+ export declare function createCommands(globalOptions: GlobalOptions<true>): {
28
+ [K in keyof DatatruckCommandMap as `${K}`]: (options: InferDatatruckCommandOptions<K>) => Promise<InferDatatruckCommandResult<K>>;
29
+ };
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCommands = exports.createCommand = exports.datatruckCommandMap = void 0;
4
+ const BackupCommand_1 = require("../../commands/BackupCommand");
5
+ const CleanCacheCommand_1 = require("../../commands/CleanCacheCommand");
6
+ const ConfigCommand_1 = require("../../commands/ConfigCommand");
7
+ const CopyCommand_1 = require("../../commands/CopyCommand");
8
+ const InitCommand_1 = require("../../commands/InitCommand");
9
+ const PruneCommand_1 = require("../../commands/PruneCommand");
10
+ const RestoreCommand_1 = require("../../commands/RestoreCommand");
11
+ const SnapshotsCommand_1 = require("../../commands/SnapshotsCommand");
12
+ const StartServerCommand_1 = require("../../commands/StartServerCommand");
13
+ const error_1 = require("./error");
14
+ const stream_1 = require("stream");
15
+ exports.datatruckCommandMap = {
16
+ config: ConfigCommand_1.ConfigCommand,
17
+ init: InitCommand_1.InitCommand,
18
+ snapshots: SnapshotsCommand_1.SnapshotsCommand,
19
+ prune: PruneCommand_1.PruneCommand,
20
+ backup: BackupCommand_1.BackupCommand,
21
+ restore: RestoreCommand_1.RestoreCommand,
22
+ copy: CopyCommand_1.CopyCommand,
23
+ cleanCache: CleanCacheCommand_1.CleanCacheCommand,
24
+ startServer: StartServerCommand_1.StartServerCommand,
25
+ };
26
+ function createCommand(name, globalOptions, options, streams, configPath) {
27
+ const constructor = exports.datatruckCommandMap[name];
28
+ if (!constructor)
29
+ throw new error_1.AppError(`Invalid command name: ${name}`);
30
+ return new constructor(globalOptions, options, streams, configPath);
31
+ }
32
+ exports.createCommand = createCommand;
33
+ function createCommands(globalOptions) {
34
+ const object = {};
35
+ for (const name in exports.datatruckCommandMap) {
36
+ object[name] = async (options) => {
37
+ let stdoutData = "";
38
+ const stdout = new stream_1.Writable({
39
+ write(chunk, encoding, callback) {
40
+ stdoutData += chunk.toString();
41
+ process.stdout.write(chunk, encoding, callback);
42
+ },
43
+ }).on("data", (chunk) => (stdoutData += chunk.toString()));
44
+ const end = () => !stdout.closed &&
45
+ new Promise((resolve) => stdout.end().on("close", resolve));
46
+ try {
47
+ const command = createCommand(name, { ...globalOptions, outputFormat: "json", verbose: 1 }, options, { stdout });
48
+ const { exitCode } = await command.exec();
49
+ if (exitCode !== 0)
50
+ throw new Error(`Invalid exit code: ${exitCode}`);
51
+ await end();
52
+ return JSON.parse(stdoutData);
53
+ }
54
+ finally {
55
+ await end();
56
+ }
57
+ };
58
+ }
59
+ return object;
60
+ }
61
+ exports.createCommands = createCommands;
@@ -1,11 +1,18 @@
1
- import { DatatruckRepositoryConfig, datatruckRepositoryName } from "../Repository/DatatruckRepository";
2
- import { GitRepositoryConfig, gitRepositoryName } from "../Repository/GitRepository";
3
- import { ResticRepositoryConfig, resticRepositoryName } from "../Repository/ResticRepository";
4
- export type RepositoryConfigType = RepositoryConfig["type"];
5
- export type RepositoryConfigEnabledAction = "backup" | "init" | "prune" | "restore" | "snapshots";
6
- export type RepositoryEnabledObject = {
7
- [K in "defaults" | RepositoryConfigEnabledAction]?: boolean;
8
- };
1
+ import type { DatatruckPackageRepositoryConfig, DatatruckRepositoryConfig, datatruckRepositoryName } from "../../repositories/DatatruckRepository";
2
+ import type { GitPackageRepositoryConfig, GitRepositoryConfig, gitRepositoryName } from "../../repositories/GitRepository";
3
+ import type { ResticPackageRepositoryConfig, ResticRepositoryConfig, resticRepositoryName } from "../../repositories/ResticRepository";
4
+ export type PackageRepositoryConfig = {
5
+ names?: string[];
6
+ } & ({
7
+ type: typeof resticRepositoryName;
8
+ config: ResticPackageRepositoryConfig;
9
+ } | {
10
+ type: typeof datatruckRepositoryName;
11
+ config: DatatruckPackageRepositoryConfig;
12
+ } | {
13
+ type: typeof gitRepositoryName;
14
+ config: GitPackageRepositoryConfig;
15
+ });
9
16
  export type ResticRepositoryConfigItem = {
10
17
  type: typeof resticRepositoryName;
11
18
  config: ResticRepositoryConfig;
@@ -18,6 +25,10 @@ export type GitRepositoryConfigItem = {
18
25
  type: typeof gitRepositoryName;
19
26
  config: GitRepositoryConfig;
20
27
  };
28
+ export type RepositoryConfigEnabledAction = "backup" | "init" | "prune" | "restore" | "snapshots";
29
+ export type RepositoryEnabledObject = {
30
+ [K in "defaults" | RepositoryConfigEnabledAction]?: boolean;
31
+ };
21
32
  type CommonRepositoryConfig = {
22
33
  name: string;
23
34
  mirrorRepoNames?: string[];
@@ -1,9 +1,9 @@
1
- import { GitTaskConfig, gitTaskName } from "../Task/GitTask";
2
- import { MariadbTaskConfig, mariadbTaskName } from "../Task/MariadbTask";
3
- import { MssqlTaskConfig, mssqlTaskName } from "../Task/MssqlTask";
4
- import { MysqlDumpTaskConfig, mysqlDumpTaskName } from "../Task/MysqlDumpTask";
5
- import { PostgresqlDumpTaskConfig, postgresqlDumpTaskName } from "../Task/PostgresqlDumpTask";
6
- import { ScriptTaskConfig, scriptTaskName } from "../Task/ScriptTask";
1
+ import type { GitTaskConfig, gitTaskName } from "../../tasks/GitTask";
2
+ import type { MariadbTaskConfig, mariadbTaskName } from "../../tasks/MariadbTask";
3
+ import type { MssqlTaskConfig, mssqlTaskName } from "../../tasks/MssqlTask";
4
+ import type { MysqlDumpTaskConfig, mysqlDumpTaskName } from "../../tasks/MysqlDumpTask";
5
+ import type { PostgresqlDumpTaskConfig, postgresqlDumpTaskName } from "../../tasks/PostgresqlDumpTask";
6
+ import type { ScriptTaskConfig, scriptTaskName } from "../../tasks/ScriptTask";
7
7
  export type GitTaskConfigItem = {
8
8
  name: typeof gitTaskName;
9
9
  config: GitTaskConfig;
@@ -0,0 +1,50 @@
1
+ import type { PruneActionsOptions } from "../../actions/PruneAction";
2
+ import type { DataFormatType } from "../DataFormat";
3
+ import type { ReportStep } from "../reportSteps";
4
+ import type { SpawnStep } from "../spawnSteps";
5
+ import type { PackageRepositoryConfig, RepositoryConfigEnabledAction, RepositoryConfig } from "./config-repository-type";
6
+ import type { TaskConfig } from "./config-task-type";
7
+ import type { DatatruckCronServerOptions } from "./cron-server";
8
+ import type { DatatruckRepositoryServerOptions } from "./repository-server";
9
+ export { RepositoryConfig, RepositoryConfigEnabledAction, TaskConfig };
10
+ export type Config = {
11
+ $schema?: string;
12
+ tempDir?: string;
13
+ minFreeDiskSpace?: string | number;
14
+ repositories: RepositoryConfig[];
15
+ packages: PackageConfig[];
16
+ server?: DatatruckServerOptions;
17
+ reports?: DatatruckReportConfig[];
18
+ prunePolicy?: DatatruckPolicyConfig;
19
+ };
20
+ export type DatatruckServerOptions = {
21
+ log?: boolean;
22
+ repository?: DatatruckRepositoryServerOptions;
23
+ cron?: DatatruckCronServerOptions;
24
+ };
25
+ export type DatatruckReportConfig = {
26
+ when?: "success" | "error";
27
+ format?: Exclude<DataFormatType, "custom" | "tpl">;
28
+ run: SpawnStep | ReportStep;
29
+ };
30
+ export type DatatruckPolicyConfig = Pick<PruneActionsOptions, "keepDaily" | "keepHourly" | "keepMinutely" | "keepLast" | "keepMonthly" | "keepWeekly" | "keepYearly" | "groupBy" | "tags">;
31
+ export type PackageConfigMeta = {
32
+ [name: string]: any;
33
+ };
34
+ export type PackageConfig = {
35
+ name: string;
36
+ enabled?: boolean;
37
+ task?: TaskConfig;
38
+ path?: string;
39
+ restorePath?: string;
40
+ meta?: PackageConfigMeta;
41
+ restorePermissions?: {
42
+ uid: string | number;
43
+ gid: string | number;
44
+ };
45
+ include?: (string | SpawnStep)[];
46
+ exclude?: (string | SpawnStep)[];
47
+ repositoryNames?: string[];
48
+ prunePolicy?: DatatruckPolicyConfig;
49
+ repositoryConfigs?: PackageRepositoryConfig[];
50
+ };
@@ -1,10 +1,19 @@
1
- import { Config } from "../../Config/Config";
2
- import type { PackageConfig } from "../../Config/PackageConfig";
3
- import { RepositoryConfigEnabledAction, RepositoryConfig } from "../../Config/RepositoryConfig";
1
+ import type { Config } from "./config-type";
2
+ import type { PackageConfig, RepositoryConfigEnabledAction, RepositoryConfig } from "./config-type";
4
3
  export declare function findRepositoryOrFail(config: Config, repositoryName: string): RepositoryConfig;
5
4
  export declare function findPackageOrFail(config: Config, packageName: string): PackageConfig;
5
+ export declare function findPackageRepositoryConfig(pkg: PackageConfig, repo: RepositoryConfig): import("../../repositories/ResticRepository").ResticPackageRepositoryConfig | import("../../repositories/DatatruckRepository").DatatruckPackageRepositoryConfig | import("../../repositories/GitRepository").GitPackageRepositoryConfig | undefined;
6
+ export declare function filterRepository(repositories: RepositoryConfig[], options: {
7
+ include?: string[];
8
+ exclude?: string[];
9
+ action?: RepositoryConfigEnabledAction;
10
+ }): RepositoryConfig[];
11
+ export declare function sortReposByType<T extends {
12
+ name: string;
13
+ type: RepositoryConfig["type"];
14
+ }>(repositories: T[], types?: RepositoryConfig["type"][]): T[];
6
15
  export declare function ensureSameRepositoryType(a: RepositoryConfig, b: RepositoryConfig): void;
7
- export declare function filterRepository(repository: RepositoryConfig, action?: RepositoryConfigEnabledAction): boolean;
16
+ export declare function filterRepositoryByEnabled(repository: RepositoryConfig, action?: RepositoryConfigEnabledAction): boolean;
8
17
  export declare function filterPackages(config: Config, options: {
9
18
  packageNames?: string[];
10
19
  packageTaskNames?: string[];
@@ -34,17 +43,17 @@ export declare const pkgPathParams: {
34
43
  };
35
44
  export declare const pkgIncludeParams: {
36
45
  action: string;
37
- packageName: string;
38
46
  temp: string;
39
47
  snapshotId: string;
40
48
  snapshotDate: string;
49
+ packageName: string;
41
50
  };
42
51
  export declare const pkgExcludeParams: {
43
52
  action: string;
44
- packageName: string;
45
53
  temp: string;
46
54
  snapshotId: string;
47
55
  snapshotDate: string;
56
+ packageName: string;
48
57
  };
49
58
  export declare const pkgRestorePathParams: {
50
59
  [name in "temp" | keyof ResolvePackagePathParams]: string;
@@ -55,32 +64,32 @@ export declare const dbNameParams: {
55
64
  export declare const params: {
56
65
  pkgPath: {
57
66
  action: string;
58
- packageName: string;
59
67
  temp: string;
60
68
  snapshotId: string;
61
69
  snapshotDate: string;
70
+ packageName: string;
62
71
  };
63
72
  pkgRestorePath: {
64
73
  path: string;
65
74
  action: string;
66
- packageName: string;
67
75
  temp: string;
68
76
  snapshotId: string;
69
77
  snapshotDate: string;
78
+ packageName: string;
70
79
  };
71
80
  pkgInclude: {
72
81
  action: string;
73
- packageName: string;
74
82
  temp: string;
75
83
  snapshotId: string;
76
84
  snapshotDate: string;
85
+ packageName: string;
77
86
  };
78
87
  pkgExclude: {
79
88
  action: string;
80
- packageName: string;
81
89
  temp: string;
82
90
  snapshotId: string;
83
91
  snapshotDate: string;
92
+ packageName: string;
84
93
  };
85
94
  dbName: {
86
95
  snapshotId: string;
@@ -1,24 +1,60 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.params = exports.dbNameParams = exports.pkgRestorePathParams = exports.pkgExcludeParams = exports.pkgIncludeParams = exports.pkgPathParams = exports.resolvePackages = exports.resolvePackage = exports.resolveDatabaseName = exports.resolvePackagePath = exports.filterPackages = exports.filterRepository = exports.ensureSameRepositoryType = exports.findPackageOrFail = exports.findRepositoryOrFail = void 0;
4
- const AppError_1 = require("../../Error/AppError");
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;
5
4
  const string_1 = require("../string");
6
5
  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);
10
10
  if (!repo)
11
- throw new AppError_1.AppError(`Repository '${repositoryName}' not found`);
11
+ throw new error_1.AppError(`Repository '${repositoryName}' not found`);
12
12
  return repo;
13
13
  }
14
14
  exports.findRepositoryOrFail = findRepositoryOrFail;
15
15
  function findPackageOrFail(config, packageName) {
16
16
  const pkg = config.packages.find((v) => v.name === packageName);
17
17
  if (!pkg)
18
- throw new AppError_1.AppError(`Package '${packageName}' not found`);
18
+ throw new error_1.AppError(`Package '${packageName}' not found`);
19
19
  return pkg;
20
20
  }
21
21
  exports.findPackageOrFail = findPackageOrFail;
22
+ function findPackageRepositoryConfig(pkg, repo) {
23
+ return pkg.repositoryConfigs?.find((config) => config.type === repo.type &&
24
+ (!config.names || config.names.includes(repo.name)))?.config;
25
+ }
26
+ exports.findPackageRepositoryConfig = findPackageRepositoryConfig;
27
+ function filterRepository(repositories, options) {
28
+ return repositories.filter((r) => {
29
+ if (options.include && !options.include.includes(r.name))
30
+ return false;
31
+ if (options.exclude && options.exclude.includes(r.name))
32
+ return false;
33
+ if (options.action && !filterRepositoryByEnabled(r, options.action))
34
+ return false;
35
+ return true;
36
+ });
37
+ }
38
+ exports.filterRepository = filterRepository;
39
+ function sortReposByType(repositories, types) {
40
+ const groups = repositories.reduce((group, item) => {
41
+ if (!group[item.type])
42
+ group[item.type] = [];
43
+ group[item.type].push(item);
44
+ return group;
45
+ }, {});
46
+ const result = [];
47
+ const sortedTypes = [
48
+ ...new Set([...(types || []), ...Object.keys(groups)]),
49
+ ];
50
+ for (const type of sortedTypes) {
51
+ const group = groups[type];
52
+ if (group)
53
+ result.push(...group.sort((a, b) => a.name.localeCompare(b.name)));
54
+ }
55
+ return result;
56
+ }
57
+ exports.sortReposByType = sortReposByType;
22
58
  function ensureSameRepositoryType(a, b) {
23
59
  if (a.type !== b.type) {
24
60
  const names = [a.name, b.name].join(" and ");
@@ -27,14 +63,14 @@ function ensureSameRepositoryType(a, b) {
27
63
  }
28
64
  }
29
65
  exports.ensureSameRepositoryType = ensureSameRepositoryType;
30
- function filterRepository(repository, action) {
66
+ function filterRepositoryByEnabled(repository, action) {
31
67
  const enabled = repository.enabled ?? true;
32
68
  if (typeof enabled === "boolean")
33
69
  return enabled;
34
70
  const defaults = enabled["defaults"] ?? true;
35
71
  return action ? enabled[action] ?? defaults : true;
36
72
  }
37
- exports.filterRepository = filterRepository;
73
+ exports.filterRepositoryByEnabled = filterRepositoryByEnabled;
38
74
  function filterPackages(config, options) {
39
75
  const packagePatterns = (0, string_1.makePathPatterns)(options.packageNames);
40
76
  const taskNamePatterns = (0, string_1.makePathPatterns)(options.packageTaskNames);
@@ -43,7 +79,7 @@ function filterPackages(config, options) {
43
79
  pkg = Object.assign({}, pkg);
44
80
  pkg.repositoryNames = (pkg.repositoryNames ?? []).filter((name) => {
45
81
  const repo = findRepositoryOrFail(config, name);
46
- if (!filterRepository(repo, options?.sourceAction))
82
+ if (!filterRepositoryByEnabled(repo, options?.sourceAction))
47
83
  return false;
48
84
  return ((!options.repositoryNames ||
49
85
  options.repositoryNames.includes(name)) &&
@@ -1,14 +1,35 @@
1
- import { BackupCommandOptions } from "../../Command/BackupCommand";
2
- import { CopyCommandOptionsType } from "../../Command/CopyCommand";
1
+ import { BackupCommandOptions } from "../../commands/BackupCommand";
2
+ import { CopyCommandOptions } from "../../commands/CopyCommand";
3
+ import { PruneCommandOptions } from "../../commands/PruneCommand";
4
+ export type CronScheduleObject = {
5
+ minute?: number | {
6
+ each: number;
7
+ };
8
+ hour?: number | {
9
+ each: number;
10
+ };
11
+ day?: number | {
12
+ each: number;
13
+ };
14
+ month?: number | {
15
+ each: number;
16
+ };
17
+ weekDay?: number | {
18
+ each: number;
19
+ };
20
+ };
3
21
  export type CronAction = {
4
- schedule: string;
22
+ schedule: string | CronScheduleObject;
23
+ } & ({
5
24
  name: "backup";
6
25
  options: BackupCommandOptions;
7
26
  } | {
8
- schedule: string;
9
27
  name: "copy";
10
- options: CopyCommandOptionsType;
11
- };
28
+ options: CopyCommandOptions;
29
+ } | {
30
+ name: "prune";
31
+ options: PruneCommandOptions;
32
+ });
12
33
  export type DatatruckCronServerOptions = {
13
34
  enabled?: boolean;
14
35
  actions?: CronAction[];