@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,32 @@
1
+ import type { ConfigType } from "../Config/Config";
2
+ import { PackageConfigType } from "../Config/PackageConfig";
3
+ import { RepositoryConfigType } from "../Config/RepositoryConfig";
4
+ import { TaskConfigType } from "../Config/TaskConfig";
5
+ import { AppError } from "../Error/AppError";
6
+ import { SnapshotType } from "../Repository/RepositoryAbstract";
7
+ import { BackupSessionManager } from "../SessionManager/BackupSessionManager";
8
+ import { IfRequireKeys } from "../util/ts-util";
9
+ export declare type BackupActionOptionsType = {
10
+ repositoryNames?: string[];
11
+ repositoryTypes?: string[];
12
+ packageNames?: string[];
13
+ tags?: string[];
14
+ dryRun?: boolean;
15
+ verbose?: boolean;
16
+ date?: string;
17
+ };
18
+ export declare class BackupAction<TRequired extends boolean = true> {
19
+ readonly config: ConfigType;
20
+ readonly options: IfRequireKeys<TRequired, BackupActionOptionsType>;
21
+ protected taskErrors: Record<string, Error[]>;
22
+ protected repoErrors: Record<string, Error[]>;
23
+ constructor(config: ConfigType, options?: IfRequireKeys<TRequired, BackupActionOptionsType>);
24
+ protected init(session: BackupSessionManager): Promise<[SnapshotType, PackageConfigType[]]>;
25
+ protected execTask(session: BackupSessionManager, pkg: PackageConfigType, task: TaskConfigType, snapshot: SnapshotType, targetPath: string | undefined): Promise<boolean>;
26
+ protected execRepository(session: BackupSessionManager, pkg: PackageConfigType, repo: RepositoryConfigType, snapshot: SnapshotType, targetPath: string | undefined): Promise<boolean>;
27
+ protected getError(pkg: PackageConfigType): AppError | null;
28
+ exec(session: BackupSessionManager): Promise<{
29
+ total: number;
30
+ errors: number;
31
+ }>;
32
+ }
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BackupAction = void 0;
4
+ const AppError_1 = require("../Error/AppError");
5
+ const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
6
+ const TaskFactory_1 = require("../Factory/TaskFactory");
7
+ const config_util_1 = require("../util/datatruck/config-util");
8
+ const crypto_1 = require("crypto");
9
+ class BackupAction {
10
+ constructor(config, options = {}) {
11
+ this.config = config;
12
+ this.options = options;
13
+ this.taskErrors = {};
14
+ this.repoErrors = {};
15
+ }
16
+ async init(session) {
17
+ const snapshot = {
18
+ id: (0, crypto_1.randomBytes)(20).toString("hex"),
19
+ date: this.options.date ?? new Date().toISOString(),
20
+ };
21
+ await session.initDrivers();
22
+ let packages = (0, config_util_1.filterPackages)(this.config, {
23
+ packageNames: this.options.packageNames,
24
+ repositoryNames: this.options.repositoryNames,
25
+ repositoryTypes: this.options.repositoryTypes,
26
+ });
27
+ packages = (0, config_util_1.resolvePackages)(packages, {
28
+ snapshotId: snapshot.id,
29
+ action: "backup",
30
+ });
31
+ for (const pkg of packages) {
32
+ const sessionId = await session.init({
33
+ snapshotId: snapshot.id,
34
+ packageName: pkg.name,
35
+ tags: this.options.tags?.join(",") ?? "",
36
+ });
37
+ if (pkg.task)
38
+ await session.initTask({
39
+ sessionId: sessionId,
40
+ taskName: pkg.task.name,
41
+ });
42
+ for (const repositoryName of pkg.repositoryNames ?? []) {
43
+ const repo = (0, config_util_1.findRepositoryOrFail)(this.config, repositoryName);
44
+ await session.initRepository({
45
+ sessionId: sessionId,
46
+ repositoryName: repositoryName,
47
+ repositoryType: repo.type,
48
+ });
49
+ }
50
+ }
51
+ return [snapshot, packages];
52
+ }
53
+ async execTask(session, pkg, task, snapshot, targetPath) {
54
+ const taskId = session.findTaskId({
55
+ packageName: pkg.name,
56
+ taskName: task.name,
57
+ });
58
+ await session.startTask({
59
+ id: taskId,
60
+ });
61
+ const key = `${pkg.name}`;
62
+ let error;
63
+ if (this.taskErrors[key]?.length) {
64
+ error = new AppError_1.AppError("Previous task failed");
65
+ }
66
+ else {
67
+ try {
68
+ const taskInstance = (0, TaskFactory_1.TaskFactory)(task);
69
+ await taskInstance.onBackup({
70
+ package: pkg,
71
+ options: this.options,
72
+ snapshot,
73
+ targetPath,
74
+ onProgress: async (data) => {
75
+ await session.progressTask({
76
+ id: taskId,
77
+ progressCurrent: data.current,
78
+ progressPercent: data.percent,
79
+ progressStep: data.step,
80
+ progressStepPercent: data.stepPercent,
81
+ progressTotal: data.total,
82
+ });
83
+ },
84
+ });
85
+ }
86
+ catch (_) {
87
+ if (!this.taskErrors[key])
88
+ this.taskErrors[key] = [];
89
+ this.taskErrors[key].push((error = _));
90
+ }
91
+ }
92
+ await session.endTask({
93
+ id: taskId,
94
+ error: error?.stack,
95
+ });
96
+ return error ? false : true;
97
+ }
98
+ async execRepository(session, pkg, repo, snapshot, targetPath) {
99
+ const repositoryId = session.findRepositoryId({
100
+ packageName: pkg.name,
101
+ repositoryName: repo.name,
102
+ });
103
+ await session.startRepository({
104
+ id: repositoryId,
105
+ });
106
+ let error;
107
+ if (this.taskErrors[pkg.name]?.length) {
108
+ error = new AppError_1.AppError("Task failed");
109
+ }
110
+ else {
111
+ try {
112
+ const repoInstance = (0, RepositoryFactory_1.RepositoryFactory)(repo);
113
+ await repoInstance.onBackup({
114
+ package: pkg,
115
+ targetPath,
116
+ packageConfig: pkg.repositoryConfigs?.find((config) => config.type === repo.type &&
117
+ (!config.names || config.names.includes(repo.name)))?.config,
118
+ options: this.options,
119
+ snapshot: snapshot,
120
+ onProgress: async (data) => {
121
+ await session.progressRepository({
122
+ id: repositoryId,
123
+ progressCurrent: data.current,
124
+ progressPercent: data.percent,
125
+ progressStep: data.step,
126
+ progressStepPercent: data.stepPercent,
127
+ progressTotal: data.total,
128
+ });
129
+ },
130
+ });
131
+ }
132
+ catch (_) {
133
+ if (!this.repoErrors[pkg.name])
134
+ this.repoErrors[pkg.name] = [];
135
+ this.repoErrors[pkg.name].push((error = _));
136
+ }
137
+ }
138
+ await session.endRepository({
139
+ id: repositoryId,
140
+ error: error?.stack,
141
+ });
142
+ return error ? false : true;
143
+ }
144
+ getError(pkg) {
145
+ const taskErrors = this.taskErrors[pkg.name]?.length;
146
+ const repoErrors = this.repoErrors[pkg.name]?.length;
147
+ if (taskErrors && repoErrors) {
148
+ return new AppError_1.AppError("Task and repository failed");
149
+ }
150
+ else if (taskErrors && !repoErrors) {
151
+ return new AppError_1.AppError("Task failed");
152
+ }
153
+ else if (!taskErrors && repoErrors) {
154
+ return new AppError_1.AppError("Repository failed");
155
+ }
156
+ else {
157
+ return null;
158
+ }
159
+ }
160
+ async exec(session) {
161
+ const [snapshot, packages] = await this.init(session);
162
+ let total = 0;
163
+ let errors = 0;
164
+ for (const pkg of packages) {
165
+ total++;
166
+ const id = session.findId({
167
+ packageName: pkg.name,
168
+ });
169
+ await session.start({
170
+ id,
171
+ });
172
+ let targetPath;
173
+ if (pkg.task) {
174
+ const taskInstance = (0, TaskFactory_1.TaskFactory)(pkg.task);
175
+ const result = await taskInstance.onBeforeBackup({
176
+ options: this.options,
177
+ package: pkg,
178
+ snapshot,
179
+ });
180
+ await this.execTask(session, pkg, pkg.task, snapshot, (targetPath = result?.targetPath));
181
+ }
182
+ for (const repoName of pkg.repositoryNames ?? []) {
183
+ const repo = (0, config_util_1.findRepositoryOrFail)(this.config, repoName);
184
+ await this.execRepository(session, pkg, repo, snapshot, targetPath);
185
+ }
186
+ const error = this.getError(pkg);
187
+ if (error)
188
+ errors++;
189
+ await session.end({
190
+ id: id,
191
+ error: error?.message,
192
+ });
193
+ }
194
+ await session.endDrivers();
195
+ return {
196
+ total: total,
197
+ errors: errors,
198
+ };
199
+ }
200
+ }
201
+ exports.BackupAction = BackupAction;
@@ -0,0 +1,13 @@
1
+ import type { ConfigType } from "../Config/Config";
2
+ import { ReadDataType } from "../SessionDriver/SessionDriverAbstract";
3
+ import { BackupSessionManager } from "../SessionManager/BackupSessionManager";
4
+ import { IfRequireKeys } from "../util/ts-util";
5
+ export declare type BackupSessionsActionOptionsType = ReadDataType & {
6
+ verbose?: boolean;
7
+ };
8
+ export declare class BackupSessionsAction<TRequired extends boolean = true> {
9
+ readonly config: ConfigType;
10
+ readonly options: IfRequireKeys<TRequired, BackupSessionsActionOptionsType>;
11
+ constructor(config: ConfigType, options: IfRequireKeys<TRequired, BackupSessionsActionOptionsType>);
12
+ exec(session: BackupSessionManager): Promise<import("../SessionDriver/SessionDriverAbstract").ReadResultType[]>;
13
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BackupSessionsAction = void 0;
4
+ class BackupSessionsAction {
5
+ constructor(config, options) {
6
+ this.config = config;
7
+ this.options = options;
8
+ }
9
+ async exec(session) {
10
+ await session.initDrivers();
11
+ const result = await session.readAll(this.options);
12
+ await session.endDrivers();
13
+ return result;
14
+ }
15
+ }
16
+ exports.BackupSessionsAction = BackupSessionsAction;
@@ -0,0 +1,9 @@
1
+ import { IfRequireKeys } from "../util/ts-util";
2
+ export declare type CleanCacheActionOptionsType = {
3
+ verbose?: boolean;
4
+ };
5
+ export declare class CleanCacheAction<TRequired extends boolean = true> {
6
+ readonly options: IfRequireKeys<TRequired, CleanCacheActionOptionsType>;
7
+ constructor(options: IfRequireKeys<TRequired, CleanCacheActionOptionsType>);
8
+ exec(): Promise<void>;
9
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CleanCacheAction = void 0;
4
+ const fs_util_1 = require("../util/fs-util");
5
+ const promises_1 = require("fs/promises");
6
+ class CleanCacheAction {
7
+ constructor(options) {
8
+ this.options = options;
9
+ }
10
+ async exec() {
11
+ const path = (0, fs_util_1.parentTmpDir)();
12
+ if (await (0, fs_util_1.existsDir)(path))
13
+ await (0, promises_1.rm)(path, {
14
+ recursive: true,
15
+ });
16
+ }
17
+ }
18
+ exports.CleanCacheAction = CleanCacheAction;
@@ -0,0 +1,14 @@
1
+ import type { ConfigType } from "../Config/Config";
2
+ import { IfRequireKeys } from "../util/ts-util";
3
+ export declare type ConfigActionOptionsType = {
4
+ path: string;
5
+ verbose?: boolean;
6
+ };
7
+ export declare class ConfigAction<TRequired extends boolean = true> {
8
+ readonly options: IfRequireKeys<TRequired, ConfigActionOptionsType>;
9
+ constructor(options: IfRequireKeys<TRequired, ConfigActionOptionsType>);
10
+ static validate(config: ConfigType): void;
11
+ static check(config: ConfigType): void;
12
+ static normalize(config: ConfigType): ConfigType;
13
+ exec(): Promise<ConfigType>;
14
+ }
@@ -0,0 +1,64 @@
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.ConfigAction = void 0;
7
+ const AppError_1 = require("../Error/AppError");
8
+ const JsonSchema_1 = require("../JsonSchema/JsonSchema");
9
+ const config_util_1 = require("../util/datatruck/config-util");
10
+ const fs_util_1 = require("../util/fs-util");
11
+ const ajv_1 = __importDefault(require("ajv"));
12
+ const assert_1 = require("assert");
13
+ const path_1 = require("path");
14
+ class ConfigAction {
15
+ constructor(options) {
16
+ this.options = options;
17
+ }
18
+ static validate(config) {
19
+ const validate = new ajv_1.default().compile(JsonSchema_1.schema);
20
+ if (!validate(config))
21
+ throw new AppError_1.AppError("Json schema error: " + JSON.stringify(validate.errors, null, 2));
22
+ }
23
+ static check(config) {
24
+ const repositoryNames = [];
25
+ for (const repo of config.repositories) {
26
+ if (repositoryNames.includes(repo.name))
27
+ throw new AppError_1.AppError(`Duplicated repository name: ${repo.name}`);
28
+ repositoryNames.push(repo.name);
29
+ }
30
+ const packageNames = [];
31
+ for (const pkg of config.packages) {
32
+ if (packageNames.includes(pkg.name))
33
+ throw new AppError_1.AppError(`Duplicated package name: ${pkg.name}`);
34
+ repositoryNames.push(pkg.name);
35
+ }
36
+ }
37
+ static normalize(config) {
38
+ config = Object.assign({}, config);
39
+ config.packages = config.packages.map((pkg) => {
40
+ pkg = Object.assign({}, pkg);
41
+ if (!pkg.restorePath)
42
+ pkg.restorePath = pkg.path
43
+ ? pkg.path
44
+ : (0, path_1.normalize)(`{temp}/{snapshotId}-{action}/{packageName}`);
45
+ if (!pkg.path)
46
+ pkg.path = (0, path_1.normalize)(`{temp}/{snapshotId}-{action}/{packageName}`);
47
+ pkg.repositoryNames =
48
+ pkg.repositoryNames ?? config.repositories.map((repo) => repo.name);
49
+ (0, assert_1.ok)(Array.isArray(pkg.repositoryNames));
50
+ for (const repoName of pkg.repositoryNames)
51
+ (0, config_util_1.findRepositoryOrFail)(config, repoName);
52
+ return pkg;
53
+ });
54
+ return config;
55
+ }
56
+ async exec() {
57
+ const path = await (0, fs_util_1.findFile)(this.options.path, "datatruck.config", fs_util_1.parseFileExtensions, "Config path not found");
58
+ const config = await (0, fs_util_1.parseFile)(path, "config");
59
+ ConfigAction.validate(config);
60
+ ConfigAction.check(config);
61
+ return ConfigAction.normalize(config);
62
+ }
63
+ }
64
+ exports.ConfigAction = ConfigAction;
@@ -0,0 +1,18 @@
1
+ import type { ConfigType } from "../Config/Config";
2
+ import { IfRequireKeys } from "../util/ts-util";
3
+ export declare type InitActionOptionsType = {
4
+ repositoryNames?: string[];
5
+ repositoryTypes?: string[];
6
+ verbose?: boolean;
7
+ };
8
+ export declare class InitAction<TRequired extends boolean = true> {
9
+ readonly config: ConfigType;
10
+ readonly options: IfRequireKeys<TRequired, InitActionOptionsType>;
11
+ constructor(config: ConfigType, options: IfRequireKeys<TRequired, InitActionOptionsType>);
12
+ exec(): Promise<{
13
+ repositoryName: string;
14
+ repositoryType: string;
15
+ repositorySource: string;
16
+ error: Error | null;
17
+ }[]>;
18
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InitAction = void 0;
4
+ const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
5
+ class InitAction {
6
+ constructor(config, options) {
7
+ this.config = config;
8
+ this.options = options;
9
+ }
10
+ async exec() {
11
+ const result = [];
12
+ for (const repo of this.config.repositories) {
13
+ if (this.options.repositoryNames &&
14
+ !this.options.repositoryNames.includes(repo.name))
15
+ continue;
16
+ if (this.options.repositoryTypes &&
17
+ !this.options.repositoryTypes.includes(repo.type))
18
+ continue;
19
+ const repoInstance = (0, RepositoryFactory_1.RepositoryFactory)(repo);
20
+ let initError = null;
21
+ try {
22
+ await repoInstance.onInit({
23
+ options: this.options,
24
+ });
25
+ }
26
+ catch (error) {
27
+ initError = error;
28
+ }
29
+ result.push({
30
+ repositoryName: repo.name,
31
+ repositoryType: repo.type,
32
+ repositorySource: repoInstance.onGetSource(),
33
+ error: initError,
34
+ });
35
+ }
36
+ return result;
37
+ }
38
+ }
39
+ exports.InitAction = InitAction;
@@ -0,0 +1,37 @@
1
+ import type { ConfigType } from "../Config/Config";
2
+ import { RepositoryConfigType } from "../Config/RepositoryConfig";
3
+ import { IfRequireKeys } from "../util/ts-util";
4
+ import { SnapshotExtendedType, SnapshotsActionOptionsType } from "./SnapshotsAction";
5
+ export declare type PruneActionsOptionsType = {
6
+ ids?: string[];
7
+ packageNames?: string[];
8
+ repositoryNames?: string[];
9
+ repositoryTypes?: RepositoryConfigType["type"][];
10
+ tags?: string[];
11
+ keepLast?: number;
12
+ keepMinutely?: number;
13
+ keepHourly?: number;
14
+ keepDaily?: number;
15
+ keepWeekly?: number;
16
+ keepMonthly?: number;
17
+ keepYearly?: number;
18
+ verbose?: boolean;
19
+ groupBy?: SnapshotsActionOptionsType["groupBy"];
20
+ dryRun?: boolean;
21
+ longId?: boolean;
22
+ returnsAll?: boolean;
23
+ };
24
+ export declare type PruneResultType = {
25
+ total: number;
26
+ prune: number;
27
+ snapshots: (SnapshotExtendedType & {
28
+ exclusionReasons: string[];
29
+ })[];
30
+ };
31
+ export declare class PruneAction<TRequired extends boolean = true> {
32
+ readonly config: ConfigType;
33
+ readonly options: IfRequireKeys<TRequired, PruneActionsOptionsType>;
34
+ constructor(config: ConfigType, options: IfRequireKeys<TRequired, PruneActionsOptionsType>);
35
+ confirm(snapshots: PruneResultType["snapshots"]): Promise<void>;
36
+ exec(): Promise<PruneResultType>;
37
+ }
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PruneAction = void 0;
4
+ const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
5
+ const snapshot_util_1 = require("../util/datatruck/snapshot-util");
6
+ const object_util_1 = require("../util/object-util");
7
+ const SnapshotsAction_1 = require("./SnapshotsAction");
8
+ class PruneAction {
9
+ constructor(config, options) {
10
+ this.config = config;
11
+ this.options = options;
12
+ }
13
+ async confirm(snapshots) {
14
+ const repository = (0, object_util_1.groupBy)(this.config.repositories, "name", true);
15
+ for (const snapshot of snapshots) {
16
+ if (!snapshot.exclusionReasons?.length) {
17
+ const repoInstance = (0, RepositoryFactory_1.RepositoryFactory)(repository[snapshot.repositoryName]);
18
+ await repoInstance.onPrune({
19
+ snapshot: snapshot,
20
+ options: { verbose: this.options.verbose },
21
+ });
22
+ }
23
+ }
24
+ }
25
+ async exec() {
26
+ const snapshotsAction = new SnapshotsAction_1.SnapshotsAction(this.config, this.options);
27
+ const snapshots = await snapshotsAction.exec();
28
+ const snapshotsDeleted = [];
29
+ const reasons = {};
30
+ const inputFilter = {
31
+ last: this.options.keepLast,
32
+ lastMinutely: this.options.keepMinutely,
33
+ lastHourly: this.options.keepHourly,
34
+ lastDaily: this.options.keepDaily,
35
+ lastMonthly: this.options.keepMonthly,
36
+ lastWeekly: this.options.keepWeekly,
37
+ lastYearly: this.options.keepYearly,
38
+ };
39
+ const hasInputFilter = Object.values(inputFilter).some(Number);
40
+ const usePrunePolicyConfig = !hasInputFilter && this.options.groupBy?.includes("packageName");
41
+ const keepSnapshots = (0, snapshot_util_1.groupAndFilter)(snapshots, this.options.groupBy, usePrunePolicyConfig
42
+ ? (groupedSnapshots) => {
43
+ const [firstSnapshot] = groupedSnapshots;
44
+ const packageName = firstSnapshot.packageName;
45
+ const config = this.config.packages.find((pkg) => pkg.name === packageName);
46
+ const prunePolicy = config?.prunePolicy ?? {};
47
+ return {
48
+ last: prunePolicy.keepLast,
49
+ lastMinutely: prunePolicy.keepMinutely,
50
+ lastHourly: prunePolicy.keepHourly,
51
+ lastDaily: prunePolicy.keepDaily,
52
+ lastMonthly: prunePolicy.keepMonthly,
53
+ lastWeekly: prunePolicy.keepWeekly,
54
+ lastYearly: prunePolicy.keepYearly,
55
+ };
56
+ }
57
+ : inputFilter, reasons);
58
+ const result = {
59
+ total: snapshots.length,
60
+ prune: 0,
61
+ snapshots: snapshotsDeleted,
62
+ };
63
+ let snapshotIndex = 0;
64
+ for (const snapshot of snapshots) {
65
+ const prune = !keepSnapshots.includes(snapshot);
66
+ if (prune)
67
+ result.prune++;
68
+ if (prune || this.options.returnsAll)
69
+ snapshotsDeleted.push({
70
+ ...snapshot,
71
+ exclusionReasons: reasons[snapshotIndex],
72
+ });
73
+ snapshotIndex++;
74
+ }
75
+ if (!this.options.dryRun)
76
+ await this.confirm(snapshotsDeleted);
77
+ return result;
78
+ }
79
+ }
80
+ exports.PruneAction = PruneAction;
@@ -0,0 +1,36 @@
1
+ import type { ConfigType } from "../Config/Config";
2
+ import { PackageConfigType } from "../Config/PackageConfig";
3
+ import { RepositoryConfigType } from "../Config/RepositoryConfig";
4
+ import { TaskConfigType } from "../Config/TaskConfig";
5
+ import { AppError } from "../Error/AppError";
6
+ import { SnapshotResultType } from "../Repository/RepositoryAbstract";
7
+ import { RestoreSessionManager } from "../SessionManager/RestoreSessionManager";
8
+ import { IfRequireKeys } from "../util/ts-util";
9
+ export declare type RestoreActionOptionsType = {
10
+ snapshotId: string;
11
+ tags?: string[];
12
+ packageNames?: string[];
13
+ repositoryNames?: string[];
14
+ repositoryTypes?: string[];
15
+ verbose?: boolean;
16
+ };
17
+ declare type SnapshotType = SnapshotResultType & {
18
+ repositoryName: string;
19
+ };
20
+ declare type SnapshotAndConfigType = [SnapshotType, PackageConfigType | null];
21
+ export declare class RestoreAction<TRequired extends boolean = true> {
22
+ readonly config: ConfigType;
23
+ readonly options: IfRequireKeys<TRequired, RestoreActionOptionsType>;
24
+ protected taskErrors: Record<string, Error[]>;
25
+ protected repoErrors: Record<string, Error[]>;
26
+ constructor(config: ConfigType, options: IfRequireKeys<TRequired, RestoreActionOptionsType>);
27
+ protected assocConfigs(packages: PackageConfigType[], snapshots: SnapshotType[]): [SnapshotType, PackageConfigType | null][];
28
+ protected init(session: RestoreSessionManager, snapshotId: string, snapshots: SnapshotAndConfigType[]): Promise<void>;
29
+ protected findSnapshots(): Promise<SnapshotType[]>;
30
+ protected groupSnapshots(snapshots: SnapshotType[]): SnapshotType[];
31
+ protected execTask(session: RestoreSessionManager, pkg: PackageConfigType, task: TaskConfigType, snapshot: SnapshotType, targetPath: string | undefined): Promise<boolean>;
32
+ protected execRepository(session: RestoreSessionManager, pkg: PackageConfigType, repo: RepositoryConfigType, snapshot: SnapshotType, targetPath: string | undefined): Promise<boolean>;
33
+ protected getError(pkg: PackageConfigType): AppError | null;
34
+ exec(session: RestoreSessionManager): Promise<boolean>;
35
+ }
36
+ export {};