@datatruck/cli 0.0.1

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 (154) hide show
  1. package/lib/Action/BackupAction.d.ts +32 -0
  2. package/lib/Action/BackupAction.js +201 -0
  3. package/lib/Action/BackupSessionsAction.d.ts +13 -0
  4. package/lib/Action/BackupSessionsAction.js +16 -0
  5. package/lib/Action/CleanCacheAction.d.ts +9 -0
  6. package/lib/Action/CleanCacheAction.js +18 -0
  7. package/lib/Action/ConfigAction.d.ts +14 -0
  8. package/lib/Action/ConfigAction.js +64 -0
  9. package/lib/Action/InitAction.d.ts +18 -0
  10. package/lib/Action/InitAction.js +39 -0
  11. package/lib/Action/PruneAction.d.ts +37 -0
  12. package/lib/Action/PruneAction.js +80 -0
  13. package/lib/Action/RestoreAction.d.ts +36 -0
  14. package/lib/Action/RestoreAction.js +246 -0
  15. package/lib/Action/RestoreSessionsAction.d.ts +13 -0
  16. package/lib/Action/RestoreSessionsAction.js +16 -0
  17. package/lib/Action/SnapshotsAction.d.ts +30 -0
  18. package/lib/Action/SnapshotsAction.js +35 -0
  19. package/lib/Command/BackupCommand.d.ts +15 -0
  20. package/lib/Command/BackupCommand.js +83 -0
  21. package/lib/Command/BackupSessionsCommand.d.ts +12 -0
  22. package/lib/Command/BackupSessionsCommand.js +88 -0
  23. package/lib/Command/CleanCacheCommand.d.ts +6 -0
  24. package/lib/Command/CleanCacheCommand.js +20 -0
  25. package/lib/Command/CommandAbstract.d.ts +19 -0
  26. package/lib/Command/CommandAbstract.js +14 -0
  27. package/lib/Command/ConfigCommand.d.ts +17 -0
  28. package/lib/Command/ConfigCommand.js +61 -0
  29. package/lib/Command/InitCommand.d.ts +13 -0
  30. package/lib/Command/InitCommand.js +67 -0
  31. package/lib/Command/PruneCommand.d.ts +27 -0
  32. package/lib/Command/PruneCommand.js +160 -0
  33. package/lib/Command/RestoreCommand.d.ts +14 -0
  34. package/lib/Command/RestoreCommand.js +71 -0
  35. package/lib/Command/RestoreSessionsCommand.d.ts +12 -0
  36. package/lib/Command/RestoreSessionsCommand.js +87 -0
  37. package/lib/Command/SnapshotsCommand.d.ts +25 -0
  38. package/lib/Command/SnapshotsCommand.js +128 -0
  39. package/lib/Config/Config.d.ts +8 -0
  40. package/lib/Config/Config.js +19 -0
  41. package/lib/Config/PackageConfig.d.ts +27 -0
  42. package/lib/Config/PackageConfig.js +69 -0
  43. package/lib/Config/PackageRepositoryConfig.d.ts +17 -0
  44. package/lib/Config/PackageRepositoryConfig.js +37 -0
  45. package/lib/Config/PrunePolicyConfig.d.ts +4 -0
  46. package/lib/Config/PrunePolicyConfig.js +28 -0
  47. package/lib/Config/RepositoryConfig.d.ts +18 -0
  48. package/lib/Config/RepositoryConfig.js +37 -0
  49. package/lib/Config/TaskConfig.d.ts +23 -0
  50. package/lib/Config/TaskConfig.js +39 -0
  51. package/lib/Decorator/EntityDecorator.d.ts +11 -0
  52. package/lib/Decorator/EntityDecorator.js +17 -0
  53. package/lib/Entity/BackupSessionEntity.d.ts +6 -0
  54. package/lib/Entity/BackupSessionEntity.js +22 -0
  55. package/lib/Entity/BackupSessionRepositoryEntity.d.ts +6 -0
  56. package/lib/Entity/BackupSessionRepositoryEntity.js +22 -0
  57. package/lib/Entity/BackupSessionTaskEntity.d.ts +5 -0
  58. package/lib/Entity/BackupSessionTaskEntity.js +22 -0
  59. package/lib/Entity/CrudEntityAbstract.d.ts +5 -0
  60. package/lib/Entity/CrudEntityAbstract.js +6 -0
  61. package/lib/Entity/RestoreSessionEntity.d.ts +5 -0
  62. package/lib/Entity/RestoreSessionEntity.js +22 -0
  63. package/lib/Entity/RestoreSessionRepositoryEntity.d.ts +6 -0
  64. package/lib/Entity/RestoreSessionRepositoryEntity.js +22 -0
  65. package/lib/Entity/RestoreSessionTaskEntity.d.ts +5 -0
  66. package/lib/Entity/RestoreSessionTaskEntity.js +22 -0
  67. package/lib/Entity/StateEntityAbstract.d.ts +12 -0
  68. package/lib/Entity/StateEntityAbstract.js +7 -0
  69. package/lib/Error/AppError.d.ts +2 -0
  70. package/lib/Error/AppError.js +6 -0
  71. package/lib/Factory/CommandFactory.d.ts +42 -0
  72. package/lib/Factory/CommandFactory.js +79 -0
  73. package/lib/Factory/EntityFactory.d.ts +6 -0
  74. package/lib/Factory/EntityFactory.js +40 -0
  75. package/lib/Factory/RepositoryFactory.d.ts +3 -0
  76. package/lib/Factory/RepositoryFactory.js +23 -0
  77. package/lib/Factory/TaskFactory.d.ts +3 -0
  78. package/lib/Factory/TaskFactory.js +30 -0
  79. package/lib/JsonSchema/DefinitionEnum.d.ts +25 -0
  80. package/lib/JsonSchema/DefinitionEnum.js +32 -0
  81. package/lib/JsonSchema/JsonSchema.d.ts +4 -0
  82. package/lib/JsonSchema/JsonSchema.js +50 -0
  83. package/lib/Repository/GitRepository.d.ts +29 -0
  84. package/lib/Repository/GitRepository.js +237 -0
  85. package/lib/Repository/LocalRepository.d.ts +51 -0
  86. package/lib/Repository/LocalRepository.js +358 -0
  87. package/lib/Repository/RepositoryAbstract.d.ts +77 -0
  88. package/lib/Repository/RepositoryAbstract.js +19 -0
  89. package/lib/Repository/ResticRepository.d.ts +36 -0
  90. package/lib/Repository/ResticRepository.js +230 -0
  91. package/lib/SessionDriver/ConsoleSessionDriver.d.ts +37 -0
  92. package/lib/SessionDriver/ConsoleSessionDriver.js +178 -0
  93. package/lib/SessionDriver/SessionDriverAbstract.d.ts +78 -0
  94. package/lib/SessionDriver/SessionDriverAbstract.js +27 -0
  95. package/lib/SessionDriver/SqliteSessionDriver.d.ts +20 -0
  96. package/lib/SessionDriver/SqliteSessionDriver.js +169 -0
  97. package/lib/SessionManager/BackupSessionManager.d.ts +44 -0
  98. package/lib/SessionManager/BackupSessionManager.js +206 -0
  99. package/lib/SessionManager/RestoreSessionManager.d.ts +44 -0
  100. package/lib/SessionManager/RestoreSessionManager.js +206 -0
  101. package/lib/Task/GitTask.d.ts +35 -0
  102. package/lib/Task/GitTask.js +248 -0
  103. package/lib/Task/MariadbTask.d.ts +25 -0
  104. package/lib/Task/MariadbTask.js +139 -0
  105. package/lib/Task/MssqlTask.d.ts +22 -0
  106. package/lib/Task/MssqlTask.js +109 -0
  107. package/lib/Task/MysqlDumpTask.d.ts +14 -0
  108. package/lib/Task/MysqlDumpTask.js +129 -0
  109. package/lib/Task/PostgresqlDumpTask.d.ts +14 -0
  110. package/lib/Task/PostgresqlDumpTask.js +101 -0
  111. package/lib/Task/SqlDumpTaskAbstract.d.ts +36 -0
  112. package/lib/Task/SqlDumpTaskAbstract.js +146 -0
  113. package/lib/Task/TaskAbstract.d.ts +37 -0
  114. package/lib/Task/TaskAbstract.js +17 -0
  115. package/lib/bin.d.ts +2 -0
  116. package/lib/bin.js +5 -0
  117. package/lib/cli.d.ts +4 -0
  118. package/lib/cli.js +110 -0
  119. package/lib/index.d.ts +0 -0
  120. package/lib/index.js +1 -0
  121. package/lib/util/DataFormat.d.ts +24 -0
  122. package/lib/util/DataFormat.js +50 -0
  123. package/lib/util/GitUtil.d.ts +38 -0
  124. package/lib/util/GitUtil.js +105 -0
  125. package/lib/util/ObjectVault.d.ts +13 -0
  126. package/lib/util/ObjectVault.js +31 -0
  127. package/lib/util/ResticUtil.d.ts +92 -0
  128. package/lib/util/ResticUtil.js +144 -0
  129. package/lib/util/cli-util.d.ts +27 -0
  130. package/lib/util/cli-util.js +118 -0
  131. package/lib/util/datatruck/config-util.d.ts +55 -0
  132. package/lib/util/datatruck/config-util.js +93 -0
  133. package/lib/util/datatruck/paths-util.d.ts +5 -0
  134. package/lib/util/datatruck/paths-util.js +22 -0
  135. package/lib/util/datatruck/snapshot-util.d.ts +4 -0
  136. package/lib/util/datatruck/snapshot-util.js +31 -0
  137. package/lib/util/date-util.d.ts +12 -0
  138. package/lib/util/date-util.js +74 -0
  139. package/lib/util/entity-util.d.ts +4 -0
  140. package/lib/util/entity-util.js +10 -0
  141. package/lib/util/fs-util.d.ts +43 -0
  142. package/lib/util/fs-util.js +278 -0
  143. package/lib/util/math-util.d.ts +1 -0
  144. package/lib/util/math-util.js +7 -0
  145. package/lib/util/object-util.d.ts +7 -0
  146. package/lib/util/object-util.js +58 -0
  147. package/lib/util/process-util.d.ts +50 -0
  148. package/lib/util/process-util.js +181 -0
  149. package/lib/util/string-util.d.ts +17 -0
  150. package/lib/util/string-util.js +77 -0
  151. package/lib/util/zip-util.d.ts +52 -0
  152. package/lib/util/zip-util.js +135 -0
  153. package/migrations/001-initial.sql +122 -0
  154. package/package.json +62 -0
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DataFormat = void 0;
7
+ const cli_table3_1 = __importDefault(require("cli-table3"));
8
+ const util_1 = require("util");
9
+ class DataFormat {
10
+ constructor(options) {
11
+ this.options = options;
12
+ }
13
+ formatToJson() {
14
+ return JSON.stringify(this.options.json
15
+ ? this.options.items.map(this.options.json)
16
+ : this.options.items);
17
+ }
18
+ formatToPrettyJson() {
19
+ return (0, util_1.formatWithOptions)({
20
+ colors: true,
21
+ depth: Infinity,
22
+ }, this.options.items);
23
+ }
24
+ formatToYaml() {
25
+ return require("yaml").stringify(this.options.items);
26
+ }
27
+ formatToTable() {
28
+ const table = new cli_table3_1.default({
29
+ head: this.options.table.labels,
30
+ });
31
+ for (const item of this.options.items)
32
+ table.push(this.options.table.handler(item));
33
+ return table.toString();
34
+ }
35
+ format(format) {
36
+ if (format === "table") {
37
+ return this.formatToTable();
38
+ }
39
+ else if (format === "json") {
40
+ return this.formatToJson();
41
+ }
42
+ else if (format === "pjson") {
43
+ return this.formatToPrettyJson();
44
+ }
45
+ else if (format === "yaml") {
46
+ return this.formatToYaml();
47
+ }
48
+ }
49
+ }
50
+ exports.DataFormat = DataFormat;
@@ -0,0 +1,38 @@
1
+ import { ExecSettingsInterface } from "./process-util";
2
+ export declare class GitUtil {
3
+ readonly options: {
4
+ dir: string;
5
+ log?: boolean;
6
+ };
7
+ constructor(options: {
8
+ dir: string;
9
+ log?: boolean;
10
+ });
11
+ exec(args: string[], settings?: ExecSettingsInterface, cwd?: boolean): Promise<import("./process-util").ExecResultType>;
12
+ canBeInit(repo: string): Promise<boolean>;
13
+ clone(options: {
14
+ repo: string;
15
+ branch?: string;
16
+ orphan?: boolean;
17
+ }): Promise<import("./process-util").ExecResultType>;
18
+ checkout(options: {
19
+ branchName: string;
20
+ orphan?: boolean;
21
+ }): Promise<import("./process-util").ExecResultType>;
22
+ checkBranch(options: {
23
+ name: string;
24
+ repo?: string;
25
+ }): Promise<boolean>;
26
+ removeAll(): Promise<import("./process-util").ExecResultType>;
27
+ haveChanges(): Promise<boolean>;
28
+ fetchCommitId(tag: string): Promise<string>;
29
+ getTags(names?: string[]): Promise<{
30
+ name: string;
31
+ message?: string | undefined;
32
+ }[]>;
33
+ addTag(name: string, message?: string): Promise<void>;
34
+ pushTags(): Promise<import("./process-util").ExecResultType>;
35
+ push(options: {
36
+ branchName: string;
37
+ }): Promise<import("./process-util").ExecResultType>;
38
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GitUtil = void 0;
4
+ const fs_util_1 = require("./fs-util");
5
+ const process_util_1 = require("./process-util");
6
+ const fs_extra_1 = require("fs-extra");
7
+ class GitUtil {
8
+ constructor(options) {
9
+ this.options = options;
10
+ }
11
+ async exec(args, settings, cwd) {
12
+ return await (0, process_util_1.exec)("git", args, { cwd: cwd === false ? undefined : this.options.dir }, {
13
+ log: this.options.log,
14
+ ...(settings ?? {}),
15
+ });
16
+ }
17
+ async canBeInit(repo) {
18
+ return ((0, fs_util_1.isLocalDir)(repo) &&
19
+ (!(await (0, fs_util_1.checkDir)(repo)) || !(await (0, fs_extra_1.readdir)(repo)).length));
20
+ }
21
+ async clone(options) {
22
+ return await this.exec([
23
+ "clone",
24
+ ...(/^\w+\:\/\//.test(options.repo) ? ["--depth=1"] : []),
25
+ ...(options.orphan ? ["--orphan"] : []),
26
+ ...(options.branch ? ["--branch", options.branch] : []),
27
+ "--config",
28
+ "core.autocrlf=false",
29
+ options.repo,
30
+ ".",
31
+ ]);
32
+ }
33
+ async checkout(options) {
34
+ return await this.exec([
35
+ "checkout",
36
+ ...(options.orphan ? ["--orphan"] : []),
37
+ options.branchName,
38
+ ]);
39
+ }
40
+ async checkBranch(options) {
41
+ const result = await this.exec([
42
+ "ls-remote",
43
+ "--exit-code",
44
+ ...(options.repo ? [options.repo] : ["--heads", "origin"]),
45
+ ], {
46
+ stdout: { save: true },
47
+ onExitCodeError: () => false,
48
+ }, options.repo ? false : true);
49
+ return result.stdout
50
+ .split(/\r?\n/g)
51
+ .some((line) => line.endsWith(`refs/heads/${options.name}`));
52
+ }
53
+ async removeAll() {
54
+ return await this.exec(["rm", "--force", "--ignore-unmatch", "*"]);
55
+ }
56
+ async haveChanges() {
57
+ const statusResult = await this.exec(["status", "-s"], {
58
+ stdout: { save: true },
59
+ });
60
+ return !!statusResult.stdout.trim().length;
61
+ }
62
+ async fetchCommitId(tag) {
63
+ return (await this.exec(["rev-list", "-n", "1", tag], { stdout: { save: true } })).stdout?.trim();
64
+ }
65
+ async getTags(names) {
66
+ const result = await this.exec(["tag", "-n", ...(names ?? [])], {
67
+ stdout: { save: true },
68
+ });
69
+ return result.stdout.split(/\r?\n/).reduce((result, value) => {
70
+ value = value.trim();
71
+ if (!value.length)
72
+ return result;
73
+ let separatorIndex = value.indexOf(" ");
74
+ if (separatorIndex === -1)
75
+ separatorIndex = value.length;
76
+ const name = value.slice(0, separatorIndex);
77
+ const message = value.slice(separatorIndex + 1);
78
+ result.push({
79
+ name: name,
80
+ message: message ?? null,
81
+ });
82
+ return result;
83
+ }, []);
84
+ }
85
+ async addTag(name, message) {
86
+ if (message) {
87
+ await this.exec(["tag", "-a", name, "-m", message]);
88
+ }
89
+ else {
90
+ await this.exec(["tag", name]);
91
+ }
92
+ }
93
+ async pushTags() {
94
+ return await this.exec(["push", "--tags"]);
95
+ }
96
+ async push(options) {
97
+ return await this.exec([
98
+ "push",
99
+ "--progress",
100
+ "origin",
101
+ options.branchName,
102
+ ]);
103
+ }
104
+ }
105
+ exports.GitUtil = GitUtil;
@@ -0,0 +1,13 @@
1
+ export declare type KeysType = (string | number)[];
2
+ export declare class ObjectVault<TObject> {
3
+ protected counter: number;
4
+ protected readonly ids: Record<string, number>;
5
+ protected readonly objects: Record<number, TObject>;
6
+ static serializeKeys(keys: KeysType): string;
7
+ get(id: number): TObject;
8
+ getId(keys: KeysType): number;
9
+ add(options: {
10
+ keys: KeysType;
11
+ handler: (id: number) => TObject;
12
+ }): TObject;
13
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectVault = void 0;
4
+ class ObjectVault {
5
+ constructor() {
6
+ this.counter = 0;
7
+ this.ids = {};
8
+ this.objects = {};
9
+ }
10
+ static serializeKeys(keys) {
11
+ return JSON.stringify(keys);
12
+ }
13
+ get(id) {
14
+ if (!(id in this.objects))
15
+ throw new Error(`Object not found: ${id}`);
16
+ return this.objects[id];
17
+ }
18
+ getId(keys) {
19
+ const key = ObjectVault.serializeKeys(keys);
20
+ const id = this.ids[key];
21
+ if (!id)
22
+ throw new Error(`Id not found: ${JSON.stringify(keys)}`);
23
+ return id;
24
+ }
25
+ add(options) {
26
+ const key = ObjectVault.serializeKeys(options.keys);
27
+ const id = (this.ids[key] = ++this.counter);
28
+ return (this.objects[id] = options.handler(id));
29
+ }
30
+ }
31
+ exports.ObjectVault = ObjectVault;
@@ -0,0 +1,92 @@
1
+ import { ExecSettingsInterface } from "./process-util";
2
+ import { UriType } from "./string-util";
3
+ export declare type RepositoryType = {
4
+ name?: string;
5
+ env?: Record<string, string>;
6
+ passwordFile?: string;
7
+ backend: "local" | "rest" | "sftp" | "s3" | "azure" | "gs" | "rclone";
8
+ } & UriType;
9
+ export declare type BackupStreamType = {
10
+ message_type: "status";
11
+ seconds_elapsed: number;
12
+ percent_done: number;
13
+ total_files: number;
14
+ files_done?: number;
15
+ total_bytes: number;
16
+ bytes_done?: number;
17
+ current_files?: string[];
18
+ } | {
19
+ message_type: "summary";
20
+ files_new: number;
21
+ files_changed: number;
22
+ files_unmodified: number;
23
+ dirs_new: number;
24
+ dirs_changed: number;
25
+ dirs_unmodified: number;
26
+ data_blobs: number;
27
+ tree_blobs: number;
28
+ data_added: number;
29
+ total_files_processed: number;
30
+ total_bytes_processed: number;
31
+ total_duration: number;
32
+ snapshot_id: string;
33
+ };
34
+ export declare class ResticUtil {
35
+ readonly options: {
36
+ log?: boolean;
37
+ env: Record<string, string>;
38
+ };
39
+ constructor(options: {
40
+ log?: boolean;
41
+ env: Record<string, string>;
42
+ });
43
+ static formatRepository(input: RepositoryType, hidePassword?: boolean): Promise<string>;
44
+ exec(args: string[], settings?: ExecSettingsInterface, options?: {
45
+ cwd?: string;
46
+ }): Promise<import("./process-util").ExecResultType>;
47
+ checkRepository(): Promise<boolean>;
48
+ forget(options: {
49
+ snapshotId?: string;
50
+ keepLast?: number;
51
+ keepHourly?: number;
52
+ keepDaily?: number;
53
+ keepWeekly?: number;
54
+ keepMonthly?: number;
55
+ keepYearly?: number;
56
+ keepWithin?: string;
57
+ keepTag?: string[];
58
+ tag?: string[];
59
+ prune?: boolean;
60
+ }): Promise<string>;
61
+ snapshots(options: {
62
+ tags?: string[];
63
+ paths?: string[];
64
+ latest?: number;
65
+ json?: boolean;
66
+ }): Promise<{
67
+ time: string;
68
+ tree: string;
69
+ paths: string[];
70
+ tags?: string[];
71
+ hostname: string;
72
+ username: string;
73
+ excludes: string[];
74
+ id: string;
75
+ short_id: string;
76
+ }[]>;
77
+ checkBackupSetPathSupport(): Promise<boolean>;
78
+ backup(options: {
79
+ cwd?: string;
80
+ tags?: string[];
81
+ paths: string[];
82
+ setPaths?: string[];
83
+ exclude?: string[];
84
+ parent?: string;
85
+ onStream?: (data: BackupStreamType) => Promise<void>;
86
+ }): Promise<import("./process-util").ExecResultType>;
87
+ restore(options: {
88
+ id: string;
89
+ target: string;
90
+ onStream?: (data: BackupStreamType) => Promise<void>;
91
+ }): Promise<import("./process-util").ExecResultType>;
92
+ }
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResticUtil = void 0;
4
+ const process_util_1 = require("./process-util");
5
+ const string_util_1 = require("./string-util");
6
+ const fs_extra_1 = require("fs-extra");
7
+ const path_1 = require("path");
8
+ class ResticUtil {
9
+ constructor(options) {
10
+ this.options = options;
11
+ }
12
+ static async formatRepository(input, hidePassword) {
13
+ if (input.backend === "local") {
14
+ if (typeof input.path !== "string")
15
+ throw new Error(`Invalid path at "${input.name}" repository: ${input.path}`);
16
+ return (0, path_1.normalize)(input.path);
17
+ }
18
+ if (input.passwordFile)
19
+ input = {
20
+ ...input,
21
+ password: (await (0, fs_extra_1.readFile)(input.passwordFile)).toString(),
22
+ };
23
+ return `${input.backend}:${(0, string_util_1.formatUri)(input, hidePassword)}`;
24
+ }
25
+ async exec(args, settings, options) {
26
+ return await (0, process_util_1.exec)("restic", args, {
27
+ stdio: ["ignore", "pipe", "pipe"],
28
+ env: { ...this.options.env },
29
+ cwd: options?.cwd,
30
+ }, {
31
+ stderr: { toExitCode: true },
32
+ log: this.options.log
33
+ ? {
34
+ exec: true,
35
+ stdout: true,
36
+ stderr: true,
37
+ colorize: true,
38
+ allToStderr: true,
39
+ envNames: ["RESTIC_REPOSITORY"],
40
+ }
41
+ : {},
42
+ ...(settings ?? {}),
43
+ });
44
+ }
45
+ async checkRepository() {
46
+ const result = await this.exec(["cat", "config"], {
47
+ onExitCodeError: () => false,
48
+ });
49
+ return result.exitCode === 0;
50
+ }
51
+ async forget(options) {
52
+ const result = await this.exec([
53
+ "forget",
54
+ ...(options.keepLast ? ["--keep-last", options.keepLast.toString()] : []),
55
+ ...(options.keepHourly
56
+ ? ["--keep-hourly", options.keepHourly.toString()]
57
+ : []),
58
+ ...(options.keepDaily
59
+ ? ["--keep-daily", options.keepDaily.toString()]
60
+ : []),
61
+ ...(options.keepWeekly
62
+ ? ["--keep-weekly", options.keepWeekly.toString()]
63
+ : []),
64
+ ...(options.keepMonthly
65
+ ? ["--keep-monthly", options.keepMonthly.toString()]
66
+ : []),
67
+ ...(options.keepYearly
68
+ ? ["--keep-yearly", options.keepYearly.toString()]
69
+ : []),
70
+ ...(options.keepWithin
71
+ ? ["--keep-within", options.keepWithin.toString()]
72
+ : []),
73
+ ...(options.keepTag
74
+ ? options.keepTag.flatMap((v) => ["--keepTag", v])
75
+ : []),
76
+ ...(options.tag ? options.tag.flatMap((v) => ["--tag", v]) : []),
77
+ ...(options.prune ? ["--prune"] : []),
78
+ ...(options.snapshotId ? [options.snapshotId] : []),
79
+ ]);
80
+ return result.stdout;
81
+ }
82
+ async snapshots(options) {
83
+ const result = await this.exec([
84
+ "snapshots",
85
+ ...(options.tags?.flatMap((tag) => [`--tag`, tag]) ?? []),
86
+ ...(options.json ? ["--json"] : []),
87
+ ...(options.paths?.flatMap((path) => ["--path", path]) ?? []),
88
+ ...(options.latest ? ["--latest", options.latest.toString()] : []),
89
+ ], {
90
+ stdout: { save: true },
91
+ });
92
+ return JSON.parse(result.stdout);
93
+ }
94
+ async checkBackupSetPathSupport() {
95
+ const result = await this.exec(["backup", "--set-path"], {
96
+ onExitCodeError: () => false,
97
+ stderr: { save: true },
98
+ });
99
+ return result.stderr.includes("flag needs an argument");
100
+ }
101
+ async backup(options) {
102
+ return await this.exec([
103
+ "backup",
104
+ "--json",
105
+ ...(options.exclude?.flatMap((v) => ["-e", v]) ?? []),
106
+ ...(options.tags?.flatMap((v) => ["--tag", v]) ?? []),
107
+ ...(options.setPaths?.flatMap((v) => ["--set-path", v]) ?? []),
108
+ ...(options.parent ? ["--parent", options.parent] : []),
109
+ ...options.paths,
110
+ ], {
111
+ stderr: {
112
+ toExitCode: true,
113
+ },
114
+ stdout: {
115
+ ...(options.onStream && {
116
+ onData: async (data) => {
117
+ if (data.startsWith("{") && data.endsWith("}")) {
118
+ await options.onStream?.(JSON.parse(data));
119
+ }
120
+ },
121
+ }),
122
+ },
123
+ }, {
124
+ cwd: options.cwd,
125
+ });
126
+ }
127
+ async restore(options) {
128
+ return await this.exec(["restore", "--json", options.id, "--target", options.target], {
129
+ stderr: {
130
+ toExitCode: true,
131
+ },
132
+ stdout: {
133
+ ...(options.onStream && {
134
+ onData: async (data) => {
135
+ if (data.startsWith("{") && data.endsWith("}")) {
136
+ await options.onStream?.(JSON.parse(data));
137
+ }
138
+ },
139
+ }),
140
+ },
141
+ });
142
+ }
143
+ }
144
+ exports.ResticUtil = ResticUtil;
@@ -0,0 +1,27 @@
1
+ /// <reference types="node" />
2
+ export declare function clearLastLine(): void;
3
+ export declare const spinnerChars: string[];
4
+ export declare const showCursorCommand = "\u001B[?25h";
5
+ export declare const clearCommand = "\r\u001B[K";
6
+ export declare const hideCursorCommand = "\u001B[?25l";
7
+ export declare function renderSpinner(counter: number): string;
8
+ export declare function renderProgressBar(progress: number, size?: number): string;
9
+ export declare function logExec(command: string, argv?: string[], env?: NodeJS.ProcessEnv, logToStderr?: boolean): void;
10
+ export declare function resultColumn(error: Error | null | string, state?: "started" | "ended"): "❌" | " ? " | "✅";
11
+ export declare function errorColumn(error: Error | null | string, verbose: number): string;
12
+ export declare type OptionsType<T1, T2 extends {
13
+ [K in keyof T1]: unknown;
14
+ }> = {
15
+ [K in keyof Required<T1>]: {
16
+ option: string;
17
+ description: string;
18
+ required?: boolean;
19
+ defaults?: Exclude<T1[K], undefined>;
20
+ parser?: (value: Exclude<T1[K], undefined>) => Exclude<T2[K], undefined>;
21
+ };
22
+ };
23
+ export declare function parseOptions<T1, T2 extends {
24
+ [K in keyof T1]: unknown;
25
+ }>(object: T1, options: OptionsType<T1, T2>): T2;
26
+ export declare function truncate(text: string, limit: number): [string, boolean];
27
+ export declare function confirm(message: string): Promise<unknown>;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.confirm = exports.truncate = exports.parseOptions = exports.errorColumn = exports.resultColumn = exports.logExec = exports.renderProgressBar = exports.renderSpinner = exports.hideCursorCommand = exports.clearCommand = exports.showCursorCommand = exports.spinnerChars = exports.clearLastLine = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const chalk_2 = require("chalk");
9
+ const readline_1 = require("readline");
10
+ function clearLastLine() {
11
+ process.stdout.moveCursor(0, -1);
12
+ process.stdout.clearLine(1);
13
+ }
14
+ exports.clearLastLine = clearLastLine;
15
+ exports.spinnerChars = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
16
+ exports.showCursorCommand = "\u001B[?25h";
17
+ exports.clearCommand = "\r\x1b[K";
18
+ exports.hideCursorCommand = "\x1B[?25l";
19
+ function renderSpinner(counter) {
20
+ return exports.spinnerChars[counter % (exports.spinnerChars.length - 1)];
21
+ }
22
+ exports.renderSpinner = renderSpinner;
23
+ function renderProgressBar(progress, size = 10) {
24
+ const completeChar = "\u2588";
25
+ const incompleteChar = "\u2591";
26
+ const completedSize = Math.round((progress * size) / 100);
27
+ const restSize = Math.max(size - completedSize, 0);
28
+ return completeChar.repeat(completedSize) + incompleteChar.repeat(restSize);
29
+ }
30
+ exports.renderProgressBar = renderProgressBar;
31
+ function logExec(command, argv = [], env, logToStderr) {
32
+ const envText = env
33
+ ? Object.keys(env)
34
+ .reduce((items, key) => {
35
+ items.push(`${chalk_1.default.cyan(key)}${chalk_1.default.grey("=")}${chalk_1.default.white(env[key] ?? "")}`);
36
+ return items;
37
+ }, [])
38
+ .join(" ")
39
+ : "";
40
+ const text = `+ ${envText ? envText + " " : ""}${chalk_1.default.yellow(`${command} ${argv.join(" ")}`)}`;
41
+ logToStderr ? process.stderr.write(`${text}\n`) : console.info(text);
42
+ }
43
+ exports.logExec = logExec;
44
+ function resultColumn(error, state) {
45
+ return error ? "❌" : state === "started" ? " ? " : "✅";
46
+ }
47
+ exports.resultColumn = resultColumn;
48
+ function errorColumn(error, verbose) {
49
+ let message = null;
50
+ if (typeof error === "string") {
51
+ message = error;
52
+ }
53
+ else if (error) {
54
+ message = error.message;
55
+ }
56
+ else {
57
+ return "";
58
+ }
59
+ if (!verbose) {
60
+ message = message.split(/\r?\n/).shift() ?? "";
61
+ }
62
+ return chalk_1.default.red(message.trim());
63
+ }
64
+ exports.errorColumn = errorColumn;
65
+ function parseOptions(object, options) {
66
+ const result = {};
67
+ for (const key in options) {
68
+ const value = object?.[key] ?? options[key].defaults;
69
+ const parser = options[key].parser;
70
+ if (typeof value !== "undefined") {
71
+ result[key] = parser ? parser(value) : value;
72
+ }
73
+ }
74
+ return result;
75
+ }
76
+ exports.parseOptions = parseOptions;
77
+ function truncate(text, limit) {
78
+ let inColor = false;
79
+ let visibleLength = 0;
80
+ if (limit >= text.length)
81
+ return [text, false];
82
+ for (let index = 0; index < text.length; ++index) {
83
+ const c = text[index];
84
+ if (c === "\x1B") {
85
+ inColor = true;
86
+ }
87
+ else if (inColor) {
88
+ if (c === "m") {
89
+ inColor = false;
90
+ }
91
+ }
92
+ else {
93
+ visibleLength++;
94
+ }
95
+ if (visibleLength === limit) {
96
+ return [text.slice(0, index) + (inColor ? `\x1B[39m` : ""), true];
97
+ }
98
+ }
99
+ return [text, false];
100
+ }
101
+ exports.truncate = truncate;
102
+ function confirm(message) {
103
+ const rl = (0, readline_1.createInterface)({
104
+ input: process.stdin,
105
+ output: process.stdout,
106
+ });
107
+ let result = false;
108
+ return new Promise((resolve) => {
109
+ rl.question(`${(0, chalk_2.cyan)("?")} ${message} ${(0, chalk_2.grey)("(y/N)")}: `, function (answer) {
110
+ result = /^\s*y(es)?\s*$/i.test(answer);
111
+ rl.close();
112
+ });
113
+ rl.on("close", () => {
114
+ resolve(result);
115
+ });
116
+ });
117
+ }
118
+ exports.confirm = confirm;
@@ -0,0 +1,55 @@
1
+ import { ConfigType } from "../../Config/Config";
2
+ import type { PackageConfigType } from "../../Config/PackageConfig";
3
+ export declare function findRepositoryOrFail(config: ConfigType, repositoryName: string): import("../../Config/RepositoryConfig").RepositoryConfigType;
4
+ export declare function filterPackages(config: ConfigType, options: {
5
+ packageNames?: string[];
6
+ repositoryNames?: string[];
7
+ repositoryTypes?: string[];
8
+ }): PackageConfigType[];
9
+ declare type ResolvePackagePathParamsType = ResolvePackageParamsType & {
10
+ packageName: string;
11
+ path: string | undefined;
12
+ };
13
+ export declare function resolvePackagePath(value: string, params: ResolvePackagePathParamsType): string;
14
+ declare type ResolveDatabaseNameParamsType = ResolvePackageParamsType & {
15
+ packageName: string;
16
+ database: string | undefined;
17
+ };
18
+ export declare function resolveDatabaseName(value: string, params: ResolveDatabaseNameParamsType): string;
19
+ declare type ResolvePackageParamsType = {
20
+ snapshotId: string;
21
+ action: "backup" | "restore";
22
+ };
23
+ export declare function resolvePackage(pkg: PackageConfigType, params: ResolvePackageParamsType): PackageConfigType;
24
+ export declare function resolvePackages(packages: PackageConfigType[], params: ResolvePackageParamsType): PackageConfigType[];
25
+ export declare const pkgPathParams: {
26
+ [name in "temp" | Exclude<keyof ResolvePackagePathParamsType, "path">]: string;
27
+ };
28
+ export declare const pkgRestorePathParams: {
29
+ [name in "temp" | keyof ResolvePackagePathParamsType]: string;
30
+ };
31
+ export declare const dbNameParams: {
32
+ [name in keyof ResolveDatabaseNameParamsType]: string;
33
+ };
34
+ export declare const params: {
35
+ pkgPath: {
36
+ packageName: string;
37
+ temp: string;
38
+ snapshotId: string;
39
+ action: string;
40
+ };
41
+ pkgRestorePath: {
42
+ packageName: string;
43
+ path: string;
44
+ temp: string;
45
+ snapshotId: string;
46
+ action: string;
47
+ };
48
+ dbName: {
49
+ snapshotId: string;
50
+ action: string;
51
+ packageName: string;
52
+ database: string;
53
+ };
54
+ };
55
+ export {};