@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,51 @@
1
+ import { RepositoryAbstract, BackupDataType, InitDataType, RestoreDataType, SnapshotsDataType, SnapshotResultType, PruneDataType } from "./RepositoryAbstract";
2
+ import type { JSONSchema7 } from "json-schema";
3
+ export declare type MetaDataType = {
4
+ id: string;
5
+ date: string;
6
+ package: string;
7
+ tags: string[];
8
+ version: string;
9
+ };
10
+ export declare type LocalRepositoryConfigType = {
11
+ outPath: string;
12
+ compress?: boolean;
13
+ };
14
+ declare type CompressObjectType = {
15
+ packs?: {
16
+ include: string[];
17
+ exclude?: string[];
18
+ onePackByResult?: boolean;
19
+ }[];
20
+ };
21
+ export declare type LocalPackageRepositoryConfigType = {
22
+ compress?: CompressObjectType | boolean;
23
+ };
24
+ export declare const localRepositoryName = "local";
25
+ export declare const localRepositoryDefinition: JSONSchema7;
26
+ export declare const localPackageRepositoryDefinition: JSONSchema7;
27
+ export declare class LocalRepository extends RepositoryAbstract<LocalRepositoryConfigType> {
28
+ static zipBasenameTpl: string;
29
+ static buildSnapshotName(data: {
30
+ snapshotId: string;
31
+ snapshotDate: string;
32
+ packageName: string;
33
+ }): string;
34
+ static parseSnapshotName(name: string): {
35
+ snapshotDate: string;
36
+ packageName: string;
37
+ snapshotShortId: string;
38
+ sourcePath: string;
39
+ } | null;
40
+ protected buildMetaPath(snapshotName: string, packageName: string): string;
41
+ static parseMetaData(path: string): Promise<MetaDataType>;
42
+ static stringifyMetaData(data: MetaDataType): string;
43
+ onGetSource(): string;
44
+ onInit(data: InitDataType): Promise<void>;
45
+ onPrune(data: PruneDataType): Promise<void>;
46
+ onSnapshots(data: SnapshotsDataType): Promise<SnapshotResultType[]>;
47
+ private normalizeCompressConfig;
48
+ onBackup(data: BackupDataType<LocalPackageRepositoryConfigType>): Promise<void>;
49
+ onRestore(data: RestoreDataType<LocalPackageRepositoryConfigType>): Promise<void>;
50
+ }
51
+ export {};
@@ -0,0 +1,358 @@
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.LocalRepository = exports.localPackageRepositoryDefinition = exports.localRepositoryDefinition = exports.localRepositoryName = void 0;
7
+ const AppError_1 = require("../Error/AppError");
8
+ const DefinitionEnum_1 = require("../JsonSchema/DefinitionEnum");
9
+ const cli_util_1 = require("../util/cli-util");
10
+ const paths_util_1 = require("../util/datatruck/paths-util");
11
+ const fs_util_1 = require("../util/fs-util");
12
+ const math_util_1 = require("../util/math-util");
13
+ const string_util_1 = require("../util/string-util");
14
+ const zip_util_1 = require("../util/zip-util");
15
+ const RepositoryAbstract_1 = require("./RepositoryAbstract");
16
+ const assert_1 = require("assert");
17
+ const fast_glob_1 = __importDefault(require("fast-glob"));
18
+ const fs_1 = require("fs");
19
+ const fs_extra_1 = require("fs-extra");
20
+ const promises_1 = require("fs/promises");
21
+ const micromatch_1 = require("micromatch");
22
+ const path_1 = require("path");
23
+ const path_2 = require("path");
24
+ const readline_1 = require("readline");
25
+ exports.localRepositoryName = "local";
26
+ exports.localRepositoryDefinition = {
27
+ type: "object",
28
+ required: ["outPath"],
29
+ additionalProperties: false,
30
+ properties: {
31
+ outPath: { type: "string" },
32
+ compress: { type: "boolean" },
33
+ },
34
+ };
35
+ exports.localPackageRepositoryDefinition = {
36
+ type: "object",
37
+ additionalProperties: false,
38
+ properties: {
39
+ compress: {
40
+ anyOf: [
41
+ {
42
+ type: "boolean",
43
+ },
44
+ {
45
+ type: "object",
46
+ additionalProperties: false,
47
+ properties: {
48
+ packs: {
49
+ type: "array",
50
+ items: {
51
+ type: "object",
52
+ additionalProperties: false,
53
+ required: ["include"],
54
+ properties: {
55
+ include: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
56
+ exclude: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
57
+ onePackByResult: { type: "boolean" },
58
+ },
59
+ },
60
+ },
61
+ },
62
+ },
63
+ ],
64
+ },
65
+ },
66
+ };
67
+ class LocalRepository extends RepositoryAbstract_1.RepositoryAbstract {
68
+ static buildSnapshotName(data) {
69
+ const date = data.snapshotDate.replace(/:/g, "-");
70
+ const pkgName = encodeURIComponent(data.packageName).replace(/%40/g, "@");
71
+ const snapshotShortId = data.snapshotId.slice(0, 8);
72
+ return `${date}_${pkgName}_${snapshotShortId}`;
73
+ }
74
+ static parseSnapshotName(name) {
75
+ if (!name.endsWith(".json"))
76
+ return null;
77
+ name = name.replace(/\.json$/, "");
78
+ const nameParts = name.split("_");
79
+ if (nameParts.length !== 3)
80
+ return null;
81
+ let [snapshotDate, packageName, snapshotShortId] = nameParts;
82
+ const [date, time] = snapshotDate.split("T");
83
+ snapshotDate = `${date}T${time.replace(/-/g, ":")}`;
84
+ packageName = decodeURIComponent(packageName);
85
+ return { snapshotDate, packageName, snapshotShortId, sourcePath: name };
86
+ }
87
+ buildMetaPath(snapshotName, packageName) {
88
+ return (0, path_1.join)(this.config.outPath, snapshotName, packageName) + ".meta.json";
89
+ }
90
+ static async parseMetaData(path) {
91
+ const contents = await (0, promises_1.readFile)(path);
92
+ return JSON.parse(contents.toString());
93
+ }
94
+ static stringifyMetaData(data) {
95
+ return JSON.stringify(data);
96
+ }
97
+ onGetSource() {
98
+ return this.config.outPath;
99
+ }
100
+ async onInit(data) {
101
+ await (0, fs_util_1.mkdirIfNotExists)(this.config.outPath);
102
+ }
103
+ async onPrune(data) {
104
+ const snapshotName = LocalRepository.buildSnapshotName({
105
+ snapshotId: data.snapshot.id,
106
+ snapshotDate: data.snapshot.date,
107
+ packageName: data.snapshot.packageName,
108
+ });
109
+ const snapshotPath = (0, path_1.join)(this.config.outPath, snapshotName);
110
+ const metaPath = `${snapshotPath}.json`;
111
+ if (data.options.verbose)
112
+ (0, cli_util_1.logExec)(`Deleting ${snapshotPath}`);
113
+ if (await (0, fs_util_1.checkDir)(snapshotPath))
114
+ await (0, fs_extra_1.rm)(snapshotPath, {
115
+ recursive: true,
116
+ });
117
+ if (await (0, fs_util_1.checkFile)(metaPath))
118
+ await (0, fs_extra_1.rm)(metaPath);
119
+ }
120
+ async onSnapshots(data) {
121
+ if (!(await (0, fs_util_1.checkDir)(this.config.outPath)))
122
+ throw new Error(`Repository (${this.repository.name}) out path does not exist: ${this.config.outPath}`);
123
+ const snapshotNames = await (0, promises_1.readdir)(this.config.outPath);
124
+ const snapshots = [];
125
+ const packagePatterns = (0, string_util_1.makePathPatterns)(data.options.packageNames);
126
+ for (const snapshotName of snapshotNames) {
127
+ const snapshotNameData = LocalRepository.parseSnapshotName(snapshotName);
128
+ if (!snapshotNameData)
129
+ continue;
130
+ if (packagePatterns &&
131
+ !(0, micromatch_1.isMatch)(snapshotNameData.packageName, packagePatterns))
132
+ continue;
133
+ if (data.options.ids &&
134
+ !data.options.ids.some((id) => snapshotNameData.snapshotShortId.startsWith(id.slice(0, 8))))
135
+ continue;
136
+ const metaPath = (0, path_1.join)(this.config.outPath, snapshotName);
137
+ const meta = await LocalRepository.parseMetaData(metaPath);
138
+ if (data.options.ids &&
139
+ !data.options.ids.some((id) => meta.id.startsWith(id)))
140
+ continue;
141
+ if (data.options.tags &&
142
+ !data.options.tags.some((value) => data.options.tags?.includes(value)))
143
+ continue;
144
+ snapshots.push({
145
+ originalId: snapshotName,
146
+ id: meta.id,
147
+ date: meta.date,
148
+ packageName: meta.package,
149
+ tags: meta.tags,
150
+ });
151
+ }
152
+ return snapshots;
153
+ }
154
+ normalizeCompressConfig(packageConfig) {
155
+ let compress = packageConfig?.compress ?? this.config.compress;
156
+ if (compress === true) {
157
+ return {
158
+ packs: [
159
+ {
160
+ include: ["**"],
161
+ },
162
+ ],
163
+ };
164
+ }
165
+ else if (!compress) {
166
+ return undefined;
167
+ }
168
+ return compress;
169
+ }
170
+ async onBackup(data) {
171
+ const snapshotName = LocalRepository.buildSnapshotName({
172
+ snapshotId: data.snapshot.id,
173
+ snapshotDate: data.snapshot.date,
174
+ packageName: data.package.name,
175
+ });
176
+ const outPath = (0, path_1.join)(this.config.outPath, snapshotName);
177
+ const createdPaths = [];
178
+ const pkg = data.package;
179
+ await (0, promises_1.mkdir)(outPath, {
180
+ recursive: true,
181
+ });
182
+ const sourcePath = data.targetPath ?? pkg.path;
183
+ (0, assert_1.ok)(sourcePath);
184
+ const compress = this.normalizeCompressConfig(data.packageConfig);
185
+ const include = await (0, paths_util_1.parsePaths)(pkg.include ?? ["**"], {
186
+ cwd: sourcePath,
187
+ verbose: data.options.verbose,
188
+ });
189
+ const exclude = pkg.exclude
190
+ ? await (0, paths_util_1.parsePaths)(pkg.exclude, {
191
+ cwd: sourcePath,
192
+ verbose: data.options.verbose,
193
+ })
194
+ : undefined;
195
+ const stream = fast_glob_1.default.stream(include, {
196
+ cwd: sourcePath,
197
+ ignore: exclude,
198
+ dot: true,
199
+ onlyFiles: compress ? false : true,
200
+ markDirectories: true,
201
+ });
202
+ if (data.options.verbose)
203
+ (0, cli_util_1.logExec)(`Writing paths lists`);
204
+ const pathLists = await (0, fs_util_1.writePathLists)({
205
+ paths: stream,
206
+ packs: compress?.packs,
207
+ });
208
+ let currentFiles = 0;
209
+ if (compress?.packs) {
210
+ let packIndex = 0;
211
+ for (const packsPath of pathLists.includedPackPaths) {
212
+ const pack = compress.packs[packIndex];
213
+ if (pack.onePackByResult) {
214
+ const reader = (0, readline_1.createInterface)({
215
+ input: (0, fs_1.createReadStream)(packsPath),
216
+ });
217
+ let multipleIndex = 0;
218
+ for await (let packPath of reader) {
219
+ if (packPath.endsWith("/"))
220
+ packPath = packPath.slice(0, -1);
221
+ const target = (0, path_1.join)(outPath, `.${packIndex}-${multipleIndex++}-${encodeURIComponent(packPath.replace(/[\\/]/g, "-")).slice(0, 255)}.dd.zip`);
222
+ const stats = await (0, zip_util_1.zip)({
223
+ path: pkg.path,
224
+ output: target,
225
+ filter: [{ patterns: [packPath] }],
226
+ excludeList: pathLists.excludedPackPaths[packIndex],
227
+ verbose: data.options.verbose,
228
+ onStream: async (stream) => await data.onProgress({
229
+ total: pathLists.total.all,
230
+ current: currentFiles + stream.data.files,
231
+ percent: (0, math_util_1.progressPercent)(pathLists.total.all, currentFiles + stream.data.files),
232
+ step: stream.type === "progress" ? stream.data.path : "",
233
+ stepPercent: stream.type === "progress" ? stream.data.progress : null,
234
+ }),
235
+ });
236
+ currentFiles += stats.files;
237
+ }
238
+ }
239
+ else {
240
+ const target = (0, path_1.join)(outPath, `.${packIndex}.dd.zip`);
241
+ const stats = await (0, zip_util_1.zip)({
242
+ path: sourcePath,
243
+ output: target,
244
+ includeList: packsPath,
245
+ excludeList: pathLists.excludedPackPaths[packIndex],
246
+ verbose: data.options.verbose,
247
+ onStream: async (stream) => await data.onProgress({
248
+ total: pathLists.total.all,
249
+ current: currentFiles + stream.data.files,
250
+ percent: (0, math_util_1.progressPercent)(pathLists.total.all, currentFiles + stream.data.files),
251
+ step: stream.type === "progress" ? stream.data.path : "",
252
+ }),
253
+ });
254
+ currentFiles += stats.files;
255
+ }
256
+ packIndex++;
257
+ }
258
+ }
259
+ if (data.options.verbose)
260
+ (0, cli_util_1.logExec)(`Copying files to ${outPath}`);
261
+ const reader = (0, readline_1.createInterface)({
262
+ input: (0, fs_1.createReadStream)(pathLists.path),
263
+ });
264
+ for await (const entry of reader) {
265
+ const source = (0, path_1.join)(sourcePath, entry);
266
+ const target = (0, path_1.join)(outPath, entry);
267
+ if (entry.endsWith("/")) {
268
+ await (0, promises_1.mkdir)(target, {
269
+ recursive: true,
270
+ });
271
+ }
272
+ else {
273
+ currentFiles++;
274
+ await data.onProgress({
275
+ total: pathLists.total.all,
276
+ current: currentFiles,
277
+ percent: (0, math_util_1.progressPercent)(pathLists.total.all, currentFiles),
278
+ step: entry,
279
+ });
280
+ const dir = (0, path_2.dirname)(target);
281
+ if (!createdPaths.includes(dir)) {
282
+ await (0, promises_1.mkdir)(dir, {
283
+ recursive: true,
284
+ });
285
+ createdPaths.push(dir);
286
+ }
287
+ await (0, promises_1.copyFile)(source, target);
288
+ }
289
+ }
290
+ const metaPath = `${outPath}.json`;
291
+ const nodePkg = (0, fs_util_1.parsePackageFile)();
292
+ const meta = {
293
+ id: data.snapshot.id,
294
+ date: data.snapshot.date,
295
+ tags: data.options.tags ?? [],
296
+ package: data.package.name,
297
+ version: nodePkg.version,
298
+ };
299
+ if (data.options.verbose)
300
+ (0, cli_util_1.logExec)(`Writing metadata into ${metaPath}`);
301
+ await (0, promises_1.writeFile)(metaPath, LocalRepository.stringifyMetaData(meta));
302
+ }
303
+ async onRestore(data) {
304
+ const restorePath = data.targetPath ?? data.package.restorePath;
305
+ (0, assert_1.ok)(restorePath);
306
+ const [snapshot] = await this.onSnapshots({
307
+ options: {
308
+ ids: [data.options.snapshotId],
309
+ },
310
+ });
311
+ if (!snapshot)
312
+ throw new AppError_1.AppError("Snapshot not found");
313
+ const snapshotName = LocalRepository.buildSnapshotName({
314
+ snapshotId: data.snapshot.id,
315
+ snapshotDate: data.snapshot.date,
316
+ packageName: data.package.name,
317
+ });
318
+ const sourcePath = (0, path_1.join)(this.config.outPath, snapshotName);
319
+ let totalFiles = 0;
320
+ let currentFiles = -1;
321
+ await (0, fs_util_1.forEachFile)(sourcePath, () => {
322
+ totalFiles++;
323
+ }, true);
324
+ if (data.options.verbose)
325
+ (0, cli_util_1.logExec)(`Copying files to ${restorePath}`);
326
+ await (0, fs_extra_1.copy)(sourcePath, restorePath, {
327
+ filter: async (path) => {
328
+ const [firstFolder] = (0, path_1.relative)(sourcePath, path).split(path_1.sep);
329
+ const isZipFile = firstFolder.startsWith(".") && firstFolder.endsWith(".dd.zip");
330
+ await data.onProgress({
331
+ total: totalFiles,
332
+ current: Math.max(currentFiles, 0),
333
+ percent: (0, math_util_1.progressPercent)(totalFiles, Math.max(currentFiles, 0)),
334
+ step: (0, path_1.relative)(sourcePath, path),
335
+ });
336
+ if (isZipFile) {
337
+ await (0, zip_util_1.unzip)({
338
+ input: path,
339
+ output: restorePath,
340
+ verbose: data.options.verbose,
341
+ onStream: async (stream) => await data.onProgress({
342
+ total: totalFiles,
343
+ current: currentFiles + 1,
344
+ percent: (0, math_util_1.progressPercent)(totalFiles, currentFiles + 1),
345
+ step: stream.type === "progress"
346
+ ? `Extracting ${stream.data.path}`
347
+ : "",
348
+ }),
349
+ });
350
+ }
351
+ currentFiles++;
352
+ return isZipFile ? false : true;
353
+ },
354
+ });
355
+ }
356
+ }
357
+ exports.LocalRepository = LocalRepository;
358
+ LocalRepository.zipBasenameTpl = `.*.dd.zip`;
@@ -0,0 +1,77 @@
1
+ import type { BackupActionOptionsType } from "../Action/BackupAction";
2
+ import type { InitActionOptionsType } from "../Action/InitAction";
3
+ import type { RestoreActionOptionsType } from "../Action/RestoreAction";
4
+ import type { SnapshotExtendedType, SnapshotsActionOptionsType } from "../Action/SnapshotsAction";
5
+ import type { PackageConfigType } from "../Config/PackageConfig";
6
+ import type { RepositoryConfigType } from "../Config/RepositoryConfig";
7
+ export declare type SnapshotType = {
8
+ id: string;
9
+ date: string;
10
+ };
11
+ export declare type SnapshotResultType = SnapshotType & {
12
+ originalId: string;
13
+ packageName: string;
14
+ tags: string[];
15
+ };
16
+ export declare type ProgressDataType = {
17
+ total: number;
18
+ current: number;
19
+ percent: number;
20
+ step: string;
21
+ stepPercent?: number | null;
22
+ };
23
+ export declare type InitDataType = {
24
+ options: InitActionOptionsType;
25
+ };
26
+ export declare type SnapshotsDataType = {
27
+ options: Pick<SnapshotsActionOptionsType, "ids" | "packageNames" | "verbose" | "tags">;
28
+ };
29
+ export declare type BackupDataType<TPackageConfig> = {
30
+ options: BackupActionOptionsType;
31
+ snapshot: SnapshotType;
32
+ package: PackageConfigType;
33
+ targetPath: string | undefined;
34
+ packageConfig: TPackageConfig | undefined;
35
+ onProgress: (data: ProgressDataType) => Promise<void>;
36
+ };
37
+ export declare type RestoreDataType<TPackageConfig> = {
38
+ options: RestoreActionOptionsType;
39
+ snapshot: SnapshotType;
40
+ package: PackageConfigType;
41
+ targetPath: string | undefined;
42
+ packageConfig: TPackageConfig;
43
+ onProgress: (data: ProgressDataType) => Promise<void>;
44
+ };
45
+ export declare type PruneDataType = {
46
+ snapshot: SnapshotExtendedType;
47
+ options: {
48
+ verbose?: boolean;
49
+ };
50
+ };
51
+ export declare enum SnapshotTagEnum {
52
+ ID = "id",
53
+ SHORT_ID = "shortId",
54
+ DATE = "date",
55
+ PACKAGE = "package",
56
+ TAGS = "tags",
57
+ VERSION = "version"
58
+ }
59
+ export declare type SnapshotTagObjectType = {
60
+ [SnapshotTagEnum.ID]: string;
61
+ [SnapshotTagEnum.SHORT_ID]: string;
62
+ [SnapshotTagEnum.DATE]: string;
63
+ [SnapshotTagEnum.PACKAGE]: string;
64
+ [SnapshotTagEnum.TAGS]: string[];
65
+ [SnapshotTagEnum.VERSION]: string;
66
+ };
67
+ export declare abstract class RepositoryAbstract<TConfig> {
68
+ readonly repository: RepositoryConfigType;
69
+ readonly config: TConfig;
70
+ constructor(repository: RepositoryConfigType);
71
+ abstract onGetSource(): string;
72
+ abstract onInit(data: InitDataType): Promise<void>;
73
+ abstract onPrune(data: PruneDataType): Promise<void>;
74
+ abstract onSnapshots(data: SnapshotsDataType): Promise<SnapshotResultType[]>;
75
+ abstract onBackup(data: BackupDataType<unknown>): Promise<void>;
76
+ abstract onRestore(data: RestoreDataType<unknown>): Promise<void>;
77
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RepositoryAbstract = exports.SnapshotTagEnum = void 0;
4
+ var SnapshotTagEnum;
5
+ (function (SnapshotTagEnum) {
6
+ SnapshotTagEnum["ID"] = "id";
7
+ SnapshotTagEnum["SHORT_ID"] = "shortId";
8
+ SnapshotTagEnum["DATE"] = "date";
9
+ SnapshotTagEnum["PACKAGE"] = "package";
10
+ SnapshotTagEnum["TAGS"] = "tags";
11
+ SnapshotTagEnum["VERSION"] = "version";
12
+ })(SnapshotTagEnum = exports.SnapshotTagEnum || (exports.SnapshotTagEnum = {}));
13
+ class RepositoryAbstract {
14
+ constructor(repository) {
15
+ this.repository = repository;
16
+ this.config = repository.config;
17
+ }
18
+ }
19
+ exports.RepositoryAbstract = RepositoryAbstract;
@@ -0,0 +1,36 @@
1
+ import { RepositoryType } from "../util/ResticUtil";
2
+ import { RepositoryAbstract, BackupDataType, InitDataType, RestoreDataType, SnapshotsDataType, SnapshotResultType, SnapshotTagObjectType, SnapshotTagEnum, PruneDataType } from "./RepositoryAbstract";
3
+ import { JSONSchema7 } from "json-schema";
4
+ export declare type ResticRepositoryConfigType = {
5
+ passwordFile: string;
6
+ repository: RepositoryType;
7
+ };
8
+ export declare type ResticPackageRepositoryConfigType = {};
9
+ export declare const resticRepositoryName = "restic";
10
+ export declare const resticRepositoryDefinition: JSONSchema7;
11
+ export declare const resticPackageRepositoryDefinition: JSONSchema7;
12
+ export declare class ResticRepository extends RepositoryAbstract<ResticRepositoryConfigType> {
13
+ static refPrefix: string;
14
+ protected env: {
15
+ RESTIC_PASSWORD_FILE: string;
16
+ RESTIC_REPOSITORY: string;
17
+ };
18
+ buildEnv(): Promise<{
19
+ RESTIC_PASSWORD_FILE: string;
20
+ RESTIC_REPOSITORY: string;
21
+ }>;
22
+ static buildSnapshotTag(name: SnapshotTagEnum, value: string): string;
23
+ static parseSnapshotTag(tag: string): {
24
+ name: SnapshotTagEnum;
25
+ value: string;
26
+ } | null;
27
+ static parseSnapshotTags(tags: string[]): Required<Partial<SnapshotTagObjectType> & {
28
+ tags: string[];
29
+ }>;
30
+ onGetSource(): string;
31
+ onInit(data: InitDataType): Promise<void>;
32
+ onSnapshots(data: SnapshotsDataType): Promise<SnapshotResultType[]>;
33
+ onPrune(data: PruneDataType): Promise<void>;
34
+ onBackup(data: BackupDataType<ResticPackageRepositoryConfigType>): Promise<void>;
35
+ onRestore(data: RestoreDataType<ResticPackageRepositoryConfigType>): Promise<void>;
36
+ }