@datatruck/cli 0.26.2 → 0.28.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 (152) hide show
  1. package/Action/BackupAction.d.ts +69 -34
  2. package/Action/BackupAction.js +284 -244
  3. package/Action/CleanCacheAction.d.ts +8 -4
  4. package/Action/CleanCacheAction.js +8 -5
  5. package/Action/ConfigAction.d.ts +12 -5
  6. package/Action/ConfigAction.js +14 -18
  7. package/Action/CopyAction.d.ts +49 -0
  8. package/Action/CopyAction.js +144 -0
  9. package/Action/InitAction.d.ts +3 -3
  10. package/Action/InitAction.js +9 -9
  11. package/Action/PruneAction.d.ts +9 -9
  12. package/Action/PruneAction.js +39 -23
  13. package/Action/RestoreAction.d.ts +48 -23
  14. package/Action/RestoreAction.js +158 -195
  15. package/Action/SnapshotsAction.d.ts +8 -8
  16. package/Action/SnapshotsAction.js +8 -8
  17. package/CHANGELOG.md +495 -0
  18. package/Command/BackupCommand.d.ts +6 -4
  19. package/Command/BackupCommand.js +9 -26
  20. package/Command/CleanCacheCommand.d.ts +4 -4
  21. package/Command/CleanCacheCommand.js +26 -5
  22. package/Command/CommandAbstract.d.ts +10 -7
  23. package/Command/CommandAbstract.js +4 -1
  24. package/Command/ConfigCommand.d.ts +6 -9
  25. package/Command/ConfigCommand.js +13 -8
  26. package/Command/CopyCommand.d.ts +15 -0
  27. package/Command/CopyCommand.js +61 -0
  28. package/Command/InitCommand.d.ts +4 -4
  29. package/Command/InitCommand.js +11 -15
  30. package/Command/PruneCommand.d.ts +3 -3
  31. package/Command/PruneCommand.js +13 -12
  32. package/Command/RestoreCommand.js +9 -17
  33. package/Command/SnapshotsCommand.d.ts +4 -4
  34. package/Command/SnapshotsCommand.js +16 -15
  35. package/Command/StartServerCommand.d.ts +6 -0
  36. package/Command/StartServerCommand.js +24 -0
  37. package/Config/Config.d.ts +11 -0
  38. package/Config/Config.js +43 -0
  39. package/Config/PrunePolicyConfig.d.ts +2 -2
  40. package/Factory/CommandFactory.d.ts +29 -33
  41. package/Factory/CommandFactory.js +32 -53
  42. package/Factory/RepositoryFactory.d.ts +1 -1
  43. package/Factory/RepositoryFactory.js +3 -3
  44. package/Factory/TaskFactory.d.ts +1 -1
  45. package/Factory/TaskFactory.js +3 -3
  46. package/Repository/DatatruckRepository.d.ts +17 -16
  47. package/Repository/DatatruckRepository.js +131 -149
  48. package/Repository/GitRepository.d.ts +9 -8
  49. package/Repository/GitRepository.js +22 -25
  50. package/Repository/RepositoryAbstract.d.ts +39 -37
  51. package/Repository/RepositoryAbstract.js +4 -5
  52. package/Repository/ResticRepository.d.ts +9 -8
  53. package/Repository/ResticRepository.js +30 -28
  54. package/Task/GitTask.d.ts +6 -7
  55. package/Task/GitTask.js +24 -30
  56. package/Task/MariadbTask.d.ts +4 -5
  57. package/Task/MariadbTask.js +26 -32
  58. package/Task/MssqlTask.d.ts +5 -3
  59. package/Task/MssqlTask.js +11 -12
  60. package/Task/MysqlDumpTask.d.ts +10 -3
  61. package/Task/MysqlDumpTask.js +107 -31
  62. package/Task/ScriptTask.d.ts +23 -18
  63. package/Task/ScriptTask.js +34 -24
  64. package/Task/SqlDumpTaskAbstract.d.ts +8 -3
  65. package/Task/SqlDumpTaskAbstract.js +31 -19
  66. package/Task/TaskAbstract.d.ts +24 -25
  67. package/Task/TaskAbstract.js +6 -10
  68. package/cli.js +14 -5
  69. package/config.schema.json +124 -3
  70. package/package.json +4 -5
  71. package/utils/DataFormat.d.ts +23 -12
  72. package/utils/DataFormat.js +36 -14
  73. package/utils/cli.d.ts +2 -9
  74. package/utils/cli.js +9 -52
  75. package/utils/datatruck/client.d.ts +24 -0
  76. package/utils/datatruck/client.js +99 -0
  77. package/utils/datatruck/config.d.ts +8 -6
  78. package/utils/datatruck/config.js +18 -3
  79. package/utils/datatruck/paths.d.ts +5 -9
  80. package/utils/datatruck/paths.js +2 -2
  81. package/utils/datatruck/server.d.ts +21 -0
  82. package/utils/datatruck/server.js +96 -0
  83. package/utils/datatruck/snapshot.d.ts +2 -2
  84. package/utils/date.d.ts +7 -3
  85. package/utils/date.js +22 -14
  86. package/utils/fs.d.ts +27 -15
  87. package/utils/fs.js +110 -62
  88. package/utils/http.d.ts +21 -0
  89. package/utils/http.js +154 -0
  90. package/utils/list.d.ts +64 -0
  91. package/utils/list.js +145 -0
  92. package/utils/mysql.d.ts +2 -0
  93. package/utils/mysql.js +21 -2
  94. package/utils/process.d.ts +1 -0
  95. package/utils/process.js +24 -31
  96. package/utils/progress.d.ts +33 -0
  97. package/utils/progress.js +113 -0
  98. package/utils/steps.d.ts +11 -0
  99. package/utils/steps.js +22 -10
  100. package/utils/stream.d.ts +7 -0
  101. package/utils/stream.js +10 -0
  102. package/utils/string.d.ts +0 -1
  103. package/utils/string.js +1 -13
  104. package/utils/tar.d.ts +10 -3
  105. package/utils/tar.js +70 -44
  106. package/utils/temp.d.ts +26 -0
  107. package/utils/temp.js +133 -0
  108. package/utils/virtual-fs.d.ts +37 -0
  109. package/utils/virtual-fs.js +65 -0
  110. package/Action/BackupSessionsAction.d.ts +0 -13
  111. package/Action/BackupSessionsAction.js +0 -18
  112. package/Action/RestoreSessionsAction.d.ts +0 -13
  113. package/Action/RestoreSessionsAction.js +0 -18
  114. package/Command/BackupSessionsCommand.d.ts +0 -12
  115. package/Command/BackupSessionsCommand.js +0 -92
  116. package/Command/RestoreSessionsCommand.d.ts +0 -12
  117. package/Command/RestoreSessionsCommand.js +0 -91
  118. package/Decorator/EntityDecorator.d.ts +0 -11
  119. package/Decorator/EntityDecorator.js +0 -17
  120. package/Entity/BackupSessionEntity.d.ts +0 -6
  121. package/Entity/BackupSessionEntity.js +0 -25
  122. package/Entity/BackupSessionRepositoryEntity.d.ts +0 -6
  123. package/Entity/BackupSessionRepositoryEntity.js +0 -25
  124. package/Entity/BackupSessionTaskEntity.d.ts +0 -5
  125. package/Entity/BackupSessionTaskEntity.js +0 -24
  126. package/Entity/CrudEntityAbstract.d.ts +0 -5
  127. package/Entity/CrudEntityAbstract.js +0 -9
  128. package/Entity/RestoreSessionEntity.d.ts +0 -5
  129. package/Entity/RestoreSessionEntity.js +0 -24
  130. package/Entity/RestoreSessionRepositoryEntity.d.ts +0 -6
  131. package/Entity/RestoreSessionRepositoryEntity.js +0 -25
  132. package/Entity/RestoreSessionTaskEntity.d.ts +0 -5
  133. package/Entity/RestoreSessionTaskEntity.js +0 -24
  134. package/Entity/StateEntityAbstract.d.ts +0 -9
  135. package/Entity/StateEntityAbstract.js +0 -12
  136. package/Factory/EntityFactory.d.ts +0 -6
  137. package/Factory/EntityFactory.js +0 -40
  138. package/SessionDriver/ConsoleSessionDriver.d.ts +0 -42
  139. package/SessionDriver/ConsoleSessionDriver.js +0 -208
  140. package/SessionDriver/SessionDriverAbstract.d.ts +0 -77
  141. package/SessionDriver/SessionDriverAbstract.js +0 -28
  142. package/SessionDriver/SqliteSessionDriver.d.ts +0 -20
  143. package/SessionDriver/SqliteSessionDriver.js +0 -173
  144. package/SessionManager/BackupSessionManager.d.ts +0 -45
  145. package/SessionManager/BackupSessionManager.js +0 -218
  146. package/SessionManager/RestoreSessionManager.d.ts +0 -47
  147. package/SessionManager/RestoreSessionManager.js +0 -218
  148. package/SessionManager/SessionManagerAbstract.d.ts +0 -18
  149. package/SessionManager/SessionManagerAbstract.js +0 -36
  150. package/migrations/001-initial.sql +0 -98
  151. package/utils/entity.d.ts +0 -4
  152. package/utils/entity.js +0 -10
@@ -3,21 +3,34 @@ 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.DataFormat = void 0;
6
+ exports.DataFormat = exports.dataFormats = void 0;
7
7
  const AppError_1 = require("../Error/AppError");
8
- const cli_table3_1 = __importDefault(require("cli-table3"));
8
+ const stream_1 = require("./stream");
9
+ const tty_table_1 = __importDefault(require("tty-table"));
9
10
  const util_1 = require("util");
11
+ exports.dataFormats = [
12
+ "json",
13
+ "list",
14
+ "pjson",
15
+ "table",
16
+ "yaml",
17
+ "custom",
18
+ "tpl",
19
+ ];
10
20
  const customPrefix = "custom=";
11
21
  const tplPrefix = "tpl=";
12
22
  class DataFormat {
13
23
  options;
24
+ streams;
14
25
  constructor(options) {
15
26
  this.options = options;
27
+ this.streams = (0, stream_1.createStreams)(options.streams);
28
+ }
29
+ getJson() {
30
+ return this.options.json;
16
31
  }
17
32
  formatToJson() {
18
- return JSON.stringify(this.options.json
19
- ? this.options.items.map(this.options.json)
20
- : this.options.items);
33
+ return JSON.stringify(this.getJson());
21
34
  }
22
35
  formatToPrettyJson() {
23
36
  return (0, util_1.formatWithOptions)({
@@ -27,23 +40,32 @@ class DataFormat {
27
40
  maxStringLength: Infinity,
28
41
  breakLength: Infinity,
29
42
  compact: false,
30
- }, this.options.items);
43
+ }, this.getJson());
31
44
  }
32
45
  formatToYaml() {
33
- return require("yaml").stringify(this.options.items);
46
+ return require("yaml").stringify(this.getJson());
34
47
  }
35
48
  formatToTable() {
36
- const table = new cli_table3_1.default({
37
- head: this.options.table.labels,
38
- });
39
- for (const item of this.options.items)
40
- table.push(this.options.table.handler(item));
41
- return table.toString();
49
+ if (!this.options.table)
50
+ throw new Error(`Unsupported format: table`);
51
+ const table = (0, tty_table_1.default)(this.options.table.headers, this.options.table.rows(), {});
52
+ return table.render();
53
+ }
54
+ formatToList() {
55
+ if (!this.options.list)
56
+ throw new Error(`Unsupported format: list`);
57
+ return this.options.list().join("\n");
58
+ }
59
+ log(format, options) {
60
+ this.streams.stdout.write(`${this.format(format, options)}\n`);
42
61
  }
43
62
  format(format, options) {
44
63
  if (format === "table") {
45
64
  return this.formatToTable();
46
65
  }
66
+ else if (format === "list") {
67
+ return this.formatToList();
68
+ }
47
69
  else if (format === "json") {
48
70
  return this.formatToJson();
49
71
  }
@@ -55,7 +77,7 @@ class DataFormat {
55
77
  }
56
78
  else if (format.startsWith(customPrefix)) {
57
79
  const code = format.slice(customPrefix.length);
58
- return runCustomCode(this.options.items, code);
80
+ return runCustomCode(this.getJson(), code);
59
81
  }
60
82
  else if (format.startsWith(tplPrefix)) {
61
83
  const name = format.slice(tplPrefix.length);
package/utils/cli.d.ts CHANGED
@@ -1,15 +1,9 @@
1
1
  /// <reference types="node" />
2
- export declare function clearLastLine(): void;
3
- export declare const spinnerChars: string[];
4
2
  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
3
  export declare function renderProgressBar(progress: number, size?: number, subprogress?: number): string;
9
- export declare function logVars(data: Record<string, any>): void;
10
4
  export declare function logExec(command: string, argv?: string[], env?: NodeJS.ProcessEnv, logToStderr?: boolean): void;
11
- export declare function resultColumn(error: Error | null | string, state?: "started" | "ended"): "❌" | " ? " | "✅";
12
- export declare function errorColumn(error: Error | null | string, verbose: number): string;
5
+ export declare function resultColumn(error: Error | null | string | boolean | undefined, color?: boolean): string;
6
+ export declare function errorColumn(error: Error | null | string | undefined, verbose?: number): string;
13
7
  export type OptionsType<T1, T2 extends {
14
8
  [K in keyof T1]: unknown;
15
9
  }> = {
@@ -24,5 +18,4 @@ export type OptionsType<T1, T2 extends {
24
18
  export declare function parseOptions<T1, T2 extends {
25
19
  [K in keyof T1]: unknown;
26
20
  }>(object: T1, options: OptionsType<T1, T2>): T2;
27
- export declare function truncate(text: string, limit: number): [string, boolean];
28
21
  export declare function confirm(message: string): Promise<unknown>;
package/utils/cli.js CHANGED
@@ -3,23 +3,11 @@ 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.truncate = exports.parseOptions = exports.errorColumn = exports.resultColumn = exports.logExec = exports.logVars = exports.renderProgressBar = exports.renderSpinner = exports.hideCursorCommand = exports.clearCommand = exports.showCursorCommand = exports.spinnerChars = exports.clearLastLine = void 0;
6
+ exports.confirm = exports.parseOptions = exports.errorColumn = exports.resultColumn = 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");
10
- function clearLastLine() {
11
- process.stdout.moveCursor(0, -1);
12
- process.stdout.clearLine(1);
13
- }
14
- exports.clearLastLine = clearLastLine;
15
- exports.spinnerChars = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
16
10
  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
11
  function renderProgressBar(progress, size = 10, subprogress) {
24
12
  if (progress > 100)
25
13
  throw new Error(`Invalid progress value: ${progress}`);
@@ -45,18 +33,6 @@ function renderProgressBar(progress, size = 10, subprogress) {
45
33
  return (0, chalk_2.cyan)(result);
46
34
  }
47
35
  exports.renderProgressBar = renderProgressBar;
48
- function logVars(data) {
49
- let first = true;
50
- for (const key in data) {
51
- if (first) {
52
- console.info();
53
- first = false;
54
- }
55
- const value = data[key];
56
- console.info(`${chalk_1.default.cyan(key)}${chalk_1.default.grey(":")} ${chalk_1.default.white(value ?? "")}`);
57
- }
58
- }
59
- exports.logVars = logVars;
60
36
  function logExec(command, argv = [], env, logToStderr) {
61
37
  const envText = env
62
38
  ? Object.keys(env)
@@ -72,8 +48,14 @@ function logExec(command, argv = [], env, logToStderr) {
72
48
  : console.info(text);
73
49
  }
74
50
  exports.logExec = logExec;
75
- function resultColumn(error, state) {
76
- return error ? "❌" : state === "started" ? " ? " : "✅";
51
+ function resultColumn(error, color = true) {
52
+ return error
53
+ ? color
54
+ ? chalk_1.default.red("Χ")
55
+ : "Χ"
56
+ : color
57
+ ? chalk_1.default.green("✓")
58
+ : "✓";
77
59
  }
78
60
  exports.resultColumn = resultColumn;
79
61
  function errorColumn(error, verbose) {
@@ -107,31 +89,6 @@ function parseOptions(object, options) {
107
89
  return result;
108
90
  }
109
91
  exports.parseOptions = parseOptions;
110
- function truncate(text, limit) {
111
- let inColor = false;
112
- let visibleLength = 0;
113
- if (limit >= text.length)
114
- return [text, false];
115
- for (let index = 0; index < text.length; ++index) {
116
- const c = text[index];
117
- if (c === "\x1B") {
118
- inColor = true;
119
- }
120
- else if (inColor) {
121
- if (c === "m") {
122
- inColor = false;
123
- }
124
- }
125
- else {
126
- visibleLength++;
127
- }
128
- if (visibleLength === limit) {
129
- return [text.slice(0, index) + (inColor ? `\x1B[39m` : ""), true];
130
- }
131
- }
132
- return [text, false];
133
- }
134
- exports.truncate = truncate;
135
92
  function confirm(message) {
136
93
  const rl = (0, readline_1.createInterface)({
137
94
  input: process.stdin,
@@ -0,0 +1,24 @@
1
+ import { DiskStats } from "../fs";
2
+ import { AbstractFs, FsOptions } from "../virtual-fs";
3
+ export declare class RemoteFs extends AbstractFs {
4
+ readonly options: FsOptions;
5
+ protected url: string;
6
+ protected headers: Record<string, string>;
7
+ constructor(options: FsOptions);
8
+ isLocal(): boolean;
9
+ protected fetchJson(name: string, params: any[]): Promise<any>;
10
+ protected post(name: string, params: any[], data: string): Promise<void>;
11
+ existsDir(path: string): Promise<any>;
12
+ mkdir(path: string): Promise<any>;
13
+ readFile(path: string): Promise<any>;
14
+ readdir(path: string): Promise<any>;
15
+ readFileIfExists(path: string): Promise<string | undefined>;
16
+ ensureEmptyDir(path: string): Promise<void>;
17
+ writeFile(path: string, contents: string): Promise<void>;
18
+ rmAll(path: string): Promise<void>;
19
+ fetchDiskStats(path: string): Promise<DiskStats>;
20
+ upload(source: string, target: string): Promise<void>;
21
+ download(source: string, target: string, timeout?: number): Promise<void>;
22
+ }
23
+ export declare function isRemoteBackend(backend: string): boolean;
24
+ export declare function createFs(backend: string): AbstractFs;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createFs = exports.isRemoteBackend = exports.RemoteFs = void 0;
4
+ const http_1 = require("../http");
5
+ const virtual_fs_1 = require("../virtual-fs");
6
+ const server_1 = require("./server");
7
+ class RemoteFs extends virtual_fs_1.AbstractFs {
8
+ options;
9
+ url;
10
+ headers;
11
+ constructor(options) {
12
+ super(options);
13
+ this.options = options;
14
+ const url = new URL(options.backend);
15
+ this.headers = {
16
+ [server_1.headerKey.user]: url.username,
17
+ [server_1.headerKey.password]: url.password,
18
+ };
19
+ url.username = "";
20
+ url.password = "";
21
+ this.url = url.href;
22
+ if (this.url.endsWith("/"))
23
+ this.url = this.url.slice(0, -1);
24
+ }
25
+ isLocal() {
26
+ return false;
27
+ }
28
+ async fetchJson(name, params) {
29
+ return await (0, http_1.fetchJson)(`${this.url}/${name}`, {
30
+ headers: this.headers,
31
+ query: {
32
+ params: JSON.stringify(params),
33
+ },
34
+ });
35
+ }
36
+ async post(name, params, data) {
37
+ return await (0, http_1.post)(`${this.url}/${name}`, data, {
38
+ headers: this.headers,
39
+ query: {
40
+ params: JSON.stringify(params),
41
+ },
42
+ });
43
+ }
44
+ async existsDir(path) {
45
+ return await this.fetchJson("existsDir", [path]);
46
+ }
47
+ async mkdir(path) {
48
+ return await this.fetchJson("mkdir", [path]);
49
+ }
50
+ async readFile(path) {
51
+ return await this.fetchJson("readFile", [path]);
52
+ }
53
+ async readdir(path) {
54
+ return await this.fetchJson("readdir", [path]);
55
+ }
56
+ async readFileIfExists(path) {
57
+ return await this.fetchJson("readFileIfExists", [path]);
58
+ }
59
+ async ensureEmptyDir(path) {
60
+ return await this.fetchJson("readdir", [path]);
61
+ }
62
+ async writeFile(path, contents) {
63
+ await this.post("writeFile", [path], contents);
64
+ }
65
+ async rmAll(path) {
66
+ await this.fetchJson("rmAll", [path]);
67
+ }
68
+ async fetchDiskStats(path) {
69
+ return await this.fetchJson("fetchDiskStats", [path]);
70
+ }
71
+ async upload(source, target) {
72
+ await (0, http_1.uploadFile)(`${this.url}/upload`, source, {
73
+ headers: this.headers,
74
+ query: {
75
+ params: JSON.stringify([target]),
76
+ },
77
+ });
78
+ }
79
+ async download(source, target, timeout = 100000) {
80
+ await (0, http_1.downloadFile)(`${this.url}/download`, target, {
81
+ timeout,
82
+ headers: this.headers,
83
+ query: {
84
+ params: JSON.stringify([source]),
85
+ },
86
+ });
87
+ }
88
+ }
89
+ exports.RemoteFs = RemoteFs;
90
+ function isRemoteBackend(backend) {
91
+ return backend.startsWith("http:") || backend.startsWith("https:");
92
+ }
93
+ exports.isRemoteBackend = isRemoteBackend;
94
+ function createFs(backend) {
95
+ return isRemoteBackend(backend)
96
+ ? new RemoteFs({ backend })
97
+ : new virtual_fs_1.LocalFs({ backend });
98
+ }
99
+ exports.createFs = createFs;
@@ -2,6 +2,8 @@ import { ConfigType } from "../../Config/Config";
2
2
  import type { PackageConfigType } from "../../Config/PackageConfig";
3
3
  import { RepositoryConfigEnabledActionType, RepositoryConfigType } from "../../Config/RepositoryConfig";
4
4
  export declare function findRepositoryOrFail(config: ConfigType, repositoryName: string): RepositoryConfigType;
5
+ export declare function findPackageOrFail(config: ConfigType, packageName: string): PackageConfigType;
6
+ export declare function ensureSameRepositoryType(a: RepositoryConfigType, b: RepositoryConfigType): void;
5
7
  export declare function filterRepository(repository: RepositoryConfigType, action?: RepositoryConfigEnabledActionType): boolean;
6
8
  export declare function filterPackages(config: ConfigType, options: {
7
9
  packageNames?: string[];
@@ -31,18 +33,18 @@ export declare const pkgPathParams: {
31
33
  [name in "temp" | Exclude<keyof ResolvePackagePathParamsType, "path">]: string;
32
34
  };
33
35
  export declare const pkgIncludeParams: {
36
+ action: string;
34
37
  packageName: string;
35
38
  temp: string;
36
39
  snapshotId: string;
37
40
  snapshotDate: string;
38
- action: string;
39
41
  };
40
42
  export declare const pkgExcludeParams: {
43
+ action: string;
41
44
  packageName: string;
42
45
  temp: string;
43
46
  snapshotId: string;
44
47
  snapshotDate: string;
45
- action: string;
46
48
  };
47
49
  export declare const pkgRestorePathParams: {
48
50
  [name in "temp" | keyof ResolvePackagePathParamsType]: string;
@@ -52,33 +54,33 @@ export declare const dbNameParams: {
52
54
  };
53
55
  export declare const params: {
54
56
  pkgPath: {
57
+ action: string;
55
58
  packageName: string;
56
59
  temp: string;
57
60
  snapshotId: string;
58
61
  snapshotDate: string;
59
- action: string;
60
62
  };
61
63
  pkgRestorePath: {
62
64
  path: string;
65
+ action: string;
63
66
  packageName: string;
64
67
  temp: string;
65
68
  snapshotId: string;
66
69
  snapshotDate: string;
67
- action: string;
68
70
  };
69
71
  pkgInclude: {
72
+ action: string;
70
73
  packageName: string;
71
74
  temp: string;
72
75
  snapshotId: string;
73
76
  snapshotDate: string;
74
- action: string;
75
77
  };
76
78
  pkgExclude: {
79
+ action: string;
77
80
  packageName: string;
78
81
  temp: string;
79
82
  snapshotId: string;
80
83
  snapshotDate: string;
81
- action: string;
82
84
  };
83
85
  dbName: {
84
86
  snapshotId: string;
@@ -1,9 +1,9 @@
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.findRepositoryOrFail = void 0;
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
4
  const AppError_1 = require("../../Error/AppError");
5
- const fs_1 = require("../fs");
6
5
  const string_1 = require("../string");
6
+ const temp_1 = require("../temp");
7
7
  const micromatch_1 = require("micromatch");
8
8
  function findRepositoryOrFail(config, repositoryName) {
9
9
  const repo = config.repositories.find((v) => v.name === repositoryName);
@@ -12,6 +12,21 @@ function findRepositoryOrFail(config, repositoryName) {
12
12
  return repo;
13
13
  }
14
14
  exports.findRepositoryOrFail = findRepositoryOrFail;
15
+ function findPackageOrFail(config, packageName) {
16
+ const pkg = config.packages.find((v) => v.name === packageName);
17
+ if (!pkg)
18
+ throw new AppError_1.AppError(`Package '${packageName}' not found`);
19
+ return pkg;
20
+ }
21
+ exports.findPackageOrFail = findPackageOrFail;
22
+ function ensureSameRepositoryType(a, b) {
23
+ if (a.type !== b.type) {
24
+ const names = [a.name, b.name].join(" and ");
25
+ const types = [a.type, b.type].join(" != ");
26
+ throw new Error(`Incompatible repository types between ${names} (${types})`);
27
+ }
28
+ }
29
+ exports.ensureSameRepositoryType = ensureSameRepositoryType;
15
30
  function filterRepository(repository, action) {
16
31
  const enabled = repository.enabled ?? true;
17
32
  if (typeof enabled === "boolean")
@@ -50,7 +65,7 @@ function resolvePackagePath(value, params) {
50
65
  return (0, string_1.render)(value, {
51
66
  ...params,
52
67
  ...{
53
- temp: (0, fs_1.tmpDir)("pkg"),
68
+ temp: (0, temp_1.tmpDir)("pkg"),
54
69
  },
55
70
  });
56
71
  }
@@ -1,21 +1,17 @@
1
1
  import { PackageConfigType } from "../../Config/PackageConfig";
2
- import { SnapshotType } from "../../Repository/RepositoryAbstract";
2
+ import { PreSnapshot } from "../../Repository/RepositoryAbstract";
3
3
  import { Step } from "../steps";
4
4
  export type ParsePathsOptions = {
5
5
  cwd?: string;
6
6
  verbose?: boolean;
7
7
  vars?: Record<string, any>;
8
- };
9
- export declare function parsePaths(values: (string | Step)[], options: {
10
- cwd?: string;
11
- verbose?: boolean;
12
- vars?: Record<string, any>;
13
8
  tempDir?: () => Promise<string>;
14
- }): Promise<string[]>;
9
+ };
10
+ export declare function parsePaths(values: (string | Step)[], options: ParsePathsOptions): Promise<string[]>;
15
11
  export type BackupPathsOptions = {
16
12
  package: PackageConfigType;
17
- snapshot: SnapshotType;
18
- targetPath: string;
13
+ snapshot: PreSnapshot;
14
+ path: string;
19
15
  verbose?: boolean;
20
16
  };
21
17
  export declare function parseBackupPaths(paths: (string | Step)[], options: BackupPathsOptions): Promise<string[]>;
@@ -21,13 +21,13 @@ async function parsePaths(values, options) {
21
21
  exports.parsePaths = parsePaths;
22
22
  async function parseBackupPaths(paths, options) {
23
23
  return parsePaths(paths, {
24
- cwd: options.targetPath,
24
+ cwd: options.path,
25
25
  verbose: options.verbose,
26
26
  vars: {
27
27
  dtt: {
28
28
  package: options.package,
29
29
  snapshot: options.snapshot,
30
- targetPath: options.targetPath,
30
+ path: options.path,
31
31
  },
32
32
  },
33
33
  });
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import { IncomingMessage } from "http";
3
+ type User = {
4
+ name: string;
5
+ password: string;
6
+ };
7
+ export type DatatruckServerOptions = {
8
+ path?: string;
9
+ log?: boolean;
10
+ listen?: {
11
+ port?: number;
12
+ address?: string;
13
+ };
14
+ users?: User[];
15
+ };
16
+ export declare const headerKey: {
17
+ user: string;
18
+ password: string;
19
+ };
20
+ export declare function createDatatruckServer(options: DatatruckServerOptions): import("node:http").Server<typeof IncomingMessage, typeof import("node:http").ServerResponse>;
21
+ export {};
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDatatruckServer = exports.headerKey = void 0;
4
+ const http_1 = require("../http");
5
+ const virtual_fs_1 = require("../virtual-fs");
6
+ const fs_1 = require("fs");
7
+ const http_2 = require("http");
8
+ function parseUrl(inUrl) {
9
+ const url = new URL(`http://127.0.0.1${inUrl}`);
10
+ const inParams = url.searchParams.get("params");
11
+ const action = url.pathname.slice(1);
12
+ if (typeof inParams === "string") {
13
+ const params = JSON.parse(inParams);
14
+ if (!Array.isArray(params))
15
+ throw new Error(`Invalid params`);
16
+ return { action, params };
17
+ }
18
+ else {
19
+ return { action, params: [] };
20
+ }
21
+ }
22
+ exports.headerKey = {
23
+ user: "x-dtt-user",
24
+ password: "x-dtt-password",
25
+ };
26
+ function validateRequest(req, users) {
27
+ const name = req.headers[exports.headerKey.user];
28
+ const password = req.headers[exports.headerKey.password];
29
+ return users.some((user) => user.name.length &&
30
+ user.password.length &&
31
+ user.name === name &&
32
+ user.password === password);
33
+ }
34
+ function createDatatruckServer(options) {
35
+ const log = options.log ?? true;
36
+ return (0, http_2.createServer)(async (req, res) => {
37
+ try {
38
+ if (req.url === "/" || req.url === "/favicon.ico") {
39
+ return res.end();
40
+ }
41
+ else if (!validateRequest(req, options.users || [])) {
42
+ res.statusCode = 401;
43
+ return res.end();
44
+ }
45
+ if (log)
46
+ console.info(`> ${req.url}`);
47
+ const fs = new virtual_fs_1.LocalFs({
48
+ backend: options.path ?? ".",
49
+ });
50
+ const { action, params } = parseUrl(req.url);
51
+ if (action === "upload") {
52
+ const [target] = params;
53
+ const file = (0, fs_1.createWriteStream)(fs.resolvePath(target));
54
+ req.pipe(file);
55
+ await new Promise((resolve, reject) => {
56
+ req.on("error", reject);
57
+ file.on("error", reject);
58
+ file.on("close", resolve);
59
+ });
60
+ }
61
+ else if (action === "download") {
62
+ const [target] = params;
63
+ const file = (0, fs_1.createReadStream)(fs.resolvePath(target));
64
+ file.pipe(res);
65
+ await new Promise((resolve, reject) => {
66
+ req.on("error", reject);
67
+ file.on("error", reject);
68
+ res.on("error", reject);
69
+ res.on("close", resolve);
70
+ });
71
+ }
72
+ else if (action === "writeFile") {
73
+ const data = await (0, http_1.readRequestData)(req);
74
+ const [target] = params;
75
+ await fs.writeFile(target, data);
76
+ }
77
+ else {
78
+ const object = fs[action]?.bind(fs);
79
+ if (!object)
80
+ throw new Error(`Invalid action: ${action}`);
81
+ const json = await object(...params);
82
+ if (json !== undefined)
83
+ res.write(JSON.stringify(json));
84
+ }
85
+ res.end();
86
+ if (log)
87
+ console.info(`<${action}`);
88
+ }
89
+ catch (error) {
90
+ if (log)
91
+ console.error(`<${req.url}`, error);
92
+ res.statusCode = 500;
93
+ }
94
+ });
95
+ }
96
+ exports.createDatatruckServer = createDatatruckServer;
@@ -1,4 +1,4 @@
1
1
  import { SnapshotGroupByType } from "../../Action/SnapshotsAction";
2
- import { SnapshotResultType } from "../../Repository/RepositoryAbstract";
2
+ import { Snapshot } from "../../Repository/RepositoryAbstract";
3
3
  import { FilterByLastOptionsType } from "../date";
4
- export declare function groupAndFilter<TSnapshot extends SnapshotResultType>(snapshots: TSnapshot[], groupByKey?: SnapshotGroupByType[], filter?: FilterByLastOptionsType | ((groupedSnapshots: TSnapshot[]) => FilterByLastOptionsType), reasons?: Record<number, string[]>): TSnapshot[];
4
+ export declare function groupAndFilter<TSnapshot extends Snapshot>(snapshots: TSnapshot[], groupByKey?: SnapshotGroupByType[], filter?: FilterByLastOptionsType | ((groupedSnapshots: TSnapshot[]) => FilterByLastOptionsType), reasons?: Record<number, string[]>): TSnapshot[];
package/utils/date.d.ts CHANGED
@@ -10,7 +10,11 @@ export type FilterByLastOptionsType = {
10
10
  export declare function filterByLast<TItem extends {
11
11
  date: string;
12
12
  }>(items: TItem[], options: FilterByLastOptionsType, reasons?: Record<number, string[]>): TItem[];
13
- export declare function createChron(): {
14
- start: () => number;
15
- elapsed: (formatted?: boolean) => string | number;
13
+ export type Timer = {
14
+ reset: (min?: number) => boolean;
15
+ check: (min: number) => boolean;
16
+ elapsed: () => number;
17
+ stop: () => void;
16
18
  };
19
+ export declare function createTimer(): Timer;
20
+ export declare function duration(ms: number): string;