@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
+ /// <reference types="node" />
2
+ import { SpawnOptions, ChildProcess } from "child_process";
3
+ import { ReadStream, WriteStream } from "fs";
4
+ export declare type ExecLogSettingsType = {
5
+ colorize?: boolean;
6
+ exec?: boolean;
7
+ stdout?: boolean;
8
+ stderr?: boolean;
9
+ allToStderr?: boolean;
10
+ envNames?: string[];
11
+ };
12
+ export interface ExecSettingsInterface {
13
+ exec?: boolean;
14
+ pipe?: {
15
+ stream: WriteStream | ReadStream;
16
+ onReadProgress?: (data: {
17
+ totalBytes: number;
18
+ currentBytes: number;
19
+ progress: number;
20
+ }) => void;
21
+ };
22
+ log?: ExecLogSettingsType | boolean;
23
+ onSpawn?: (p: ChildProcess) => void;
24
+ stdout?: {
25
+ save?: boolean;
26
+ onData?: (data: string) => Promise<void>;
27
+ };
28
+ stderr?: {
29
+ save?: boolean;
30
+ onData?: (data: string) => Promise<void>;
31
+ toExitCode?: boolean;
32
+ };
33
+ onExitCodeError?: (data: ExecResultType, error: Error) => Error | false;
34
+ }
35
+ export declare function logExecStdout(input: {
36
+ data: string;
37
+ colorize?: boolean;
38
+ stderr?: boolean;
39
+ lineSalt?: boolean;
40
+ }): void;
41
+ export declare function logExecStderr(data: string, colorize?: boolean): void;
42
+ export declare type ExecResultType = {
43
+ stdout: string;
44
+ stderr: string;
45
+ exitCode: number;
46
+ };
47
+ export declare function exec(command: string, argv?: string[], options?: SpawnOptions | null, settings?: ExecSettingsInterface): Promise<ExecResultType>;
48
+ declare type EventNameType = "exit" | "SIGINT" | "SIGUSR1" | "SIGUSR2" | "SIGTERM" | "uncaughtException";
49
+ export declare function onExit(cb: (eventName: EventNameType) => void): void;
50
+ export {};
@@ -0,0 +1,181 @@
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.onExit = exports.exec = exports.logExecStderr = exports.logExecStdout = void 0;
7
+ const cli_util_1 = require("./cli-util");
8
+ const fs_util_1 = require("./fs-util");
9
+ const math_util_1 = require("./math-util");
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const child_process_1 = require("child_process");
12
+ const fs_1 = require("fs");
13
+ const promises_1 = require("fs/promises");
14
+ function logExecStdout(input) {
15
+ let text = input.colorize ? chalk_1.default.grey(input.data) : input.data;
16
+ if (input.lineSalt)
17
+ text += "\n";
18
+ input.stderr ? process.stderr.write(text) : process.stdout.write(text);
19
+ }
20
+ exports.logExecStdout = logExecStdout;
21
+ function logExecStderr(data, colorize) {
22
+ process.stdout.write(colorize ? chalk_1.default.red(data) : data);
23
+ }
24
+ exports.logExecStderr = logExecStderr;
25
+ async function exec(command, argv = [], options = null, settings = {}) {
26
+ const pipe = settings.pipe;
27
+ let log = {};
28
+ if (settings.log === true) {
29
+ log.exec = log.stdout = log.stderr = log.allToStderr = log.colorize = true;
30
+ }
31
+ else if (settings.log) {
32
+ log = settings.log;
33
+ }
34
+ return new Promise(async (resolve, reject) => {
35
+ if (log.exec) {
36
+ const logEnv = log.envNames?.reduce((env, key) => {
37
+ env[key] = options?.env?.[key] ?? "";
38
+ return env;
39
+ }, {});
40
+ (0, cli_util_1.logExec)(command, pipe
41
+ ? [
42
+ ...argv,
43
+ pipe.stream instanceof fs_1.ReadStream ? "<" : ">",
44
+ String(pipe.stream.path),
45
+ ]
46
+ : argv, logEnv, log.allToStderr);
47
+ }
48
+ if (typeof options?.cwd === "string" && !(await (0, fs_util_1.checkDir)(options.cwd)))
49
+ return reject(new Error(`Current working directory does not exist: ${options.cwd}`));
50
+ if (pipe?.onReadProgress && pipe.stream instanceof fs_1.ReadStream) {
51
+ const fileInfo = await (0, promises_1.stat)(pipe.stream.path);
52
+ const totalBytes = fileInfo.size;
53
+ let currentBytes = 0;
54
+ pipe.stream.on("data", (data) => {
55
+ currentBytes += data.length;
56
+ pipe.onReadProgress?.({
57
+ totalBytes: totalBytes,
58
+ currentBytes: currentBytes,
59
+ progress: (0, math_util_1.progressPercent)(totalBytes, currentBytes),
60
+ });
61
+ });
62
+ }
63
+ const p = (0, child_process_1.spawn)(command, argv, options ?? {});
64
+ settings.onSpawn?.(p);
65
+ let spawnError;
66
+ const spawnData = {
67
+ stdout: "",
68
+ stderr: "",
69
+ exitCode: 0,
70
+ };
71
+ let finishListens = pipe ? 2 : 1;
72
+ let streamError;
73
+ const tryFinish = () => {
74
+ if (!--finishListens)
75
+ finish();
76
+ };
77
+ const finish = () => {
78
+ if (spawnData.exitCode) {
79
+ let exitCodeError;
80
+ if (settings.stderr?.toExitCode) {
81
+ exitCodeError = new Error(`Exit code ${spawnData.exitCode}: ${spawnData.stderr
82
+ .split(/\r?\n/g)
83
+ .filter((v) => !!v.length)
84
+ .join(" | ")}`);
85
+ }
86
+ else {
87
+ exitCodeError = new Error(`Exit code: ${spawnData.exitCode} (${command} ${argv.join(" ")})`);
88
+ }
89
+ const exitCodeErrorResult = settings.onExitCodeError?.(spawnData, exitCodeError);
90
+ if (exitCodeErrorResult instanceof Error) {
91
+ return reject(exitCodeErrorResult);
92
+ }
93
+ else if (exitCodeErrorResult !== false) {
94
+ return reject(exitCodeError);
95
+ }
96
+ }
97
+ if (streamError) {
98
+ reject(streamError);
99
+ }
100
+ else if (spawnError) {
101
+ reject(spawnError);
102
+ }
103
+ else {
104
+ resolve(spawnData);
105
+ }
106
+ };
107
+ if (pipe) {
108
+ pipe.stream.on("error", (error) => {
109
+ streamError = error;
110
+ tryFinish();
111
+ });
112
+ if (pipe.stream instanceof fs_1.WriteStream) {
113
+ if (!p.stdout)
114
+ throw new Error(`stdout is not defined`);
115
+ if (!p.stderr)
116
+ throw new Error(`stderr is not defined`);
117
+ p.stdout.pipe(pipe.stream, { end: false });
118
+ p.stderr.pipe(pipe.stream, { end: false });
119
+ p.on("close", tryFinish);
120
+ }
121
+ else if (pipe.stream instanceof fs_1.ReadStream) {
122
+ if (!p.stdin)
123
+ throw new Error(`stdin is not defined`);
124
+ pipe.stream.pipe(p.stdin);
125
+ }
126
+ }
127
+ if (log.stdout || settings.stdout) {
128
+ if (!p.stdout)
129
+ throw new Error(`stdout is not defined`);
130
+ p.stdout.on("data", async (data) => {
131
+ if (log.stdout)
132
+ logExecStdout({
133
+ data: data.toString(),
134
+ stderr: log.allToStderr,
135
+ colorize: log.colorize,
136
+ });
137
+ if (settings.stdout?.save)
138
+ spawnData.stdout += data.toString();
139
+ if (settings.stdout?.onData)
140
+ await settings.stdout.onData(data.toString());
141
+ });
142
+ }
143
+ if (log.stderr || settings.stderr) {
144
+ if (!p.stderr)
145
+ throw new Error(`stderr is not defined`);
146
+ p.stderr.on("data", async (data) => {
147
+ if (log.stderr)
148
+ logExecStdout({
149
+ data: data.toString(),
150
+ stderr: log.allToStderr,
151
+ colorize: log.colorize,
152
+ });
153
+ if (settings.stderr?.save || settings.stderr?.toExitCode)
154
+ spawnData.stderr += data.toString();
155
+ if (settings.stderr?.onData)
156
+ await settings.stderr.onData(data.toString());
157
+ });
158
+ }
159
+ p.on("error", (error) => (spawnError = error)).on("close", (exitCode) => {
160
+ spawnData.exitCode = exitCode ?? 0;
161
+ if (pipe?.stream instanceof fs_1.WriteStream)
162
+ pipe.stream.end();
163
+ tryFinish();
164
+ });
165
+ });
166
+ }
167
+ exports.exec = exec;
168
+ const eventNames = [
169
+ `exit`,
170
+ `SIGINT`,
171
+ `SIGUSR1`,
172
+ `SIGUSR2`,
173
+ `uncaughtException`,
174
+ `SIGTERM`,
175
+ ];
176
+ function onExit(cb) {
177
+ for (const eventName of eventNames) {
178
+ process.on(eventName, cb.bind(null, eventName));
179
+ }
180
+ }
181
+ exports.onExit = onExit;
@@ -0,0 +1,17 @@
1
+ export declare function serialize(message: string, data?: Object): string;
2
+ export declare function ucfirst(value: string): string;
3
+ export declare function lcfirst(value: string): string;
4
+ export declare function snakeCase(value: string, char?: string): string;
5
+ export declare function render(subject: string, vars: Record<string, string | undefined>): string;
6
+ export declare function parseStringList(value: string, validValues?: string[]): string[];
7
+ export declare type UriType = {
8
+ protocol?: "http" | "https";
9
+ host?: string;
10
+ username?: string;
11
+ password?: string;
12
+ port?: number;
13
+ path?: string;
14
+ };
15
+ export declare function formatUri(input: UriType, hidePassword?: boolean): string;
16
+ export declare function makePathPatterns(values: string[] | undefined): string[] | undefined;
17
+ export declare function formatDateTime(datetime: string): string;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatDateTime = exports.makePathPatterns = exports.formatUri = exports.parseStringList = exports.render = exports.snakeCase = exports.lcfirst = exports.ucfirst = exports.serialize = void 0;
4
+ const AppError_1 = require("../Error/AppError");
5
+ function serialize(message, data) {
6
+ if (data)
7
+ return `${message} (${JSON.stringify(data, null, 2)})`;
8
+ return message;
9
+ }
10
+ exports.serialize = serialize;
11
+ function ucfirst(value) {
12
+ return value.charAt(0).toUpperCase() + value.slice(1);
13
+ }
14
+ exports.ucfirst = ucfirst;
15
+ function lcfirst(value) {
16
+ return value.charAt(0).toLowerCase() + value.slice(1);
17
+ }
18
+ exports.lcfirst = lcfirst;
19
+ function snakeCase(value, char = "_") {
20
+ return value.replace(/[A-Z]/g, (letter) => `${char}${letter.toLowerCase()}`);
21
+ }
22
+ exports.snakeCase = snakeCase;
23
+ function render(subject, vars) {
24
+ return subject.replace(/{(\w+)}/g, function (match, name) {
25
+ const value = vars[name];
26
+ if (typeof value === "undefined")
27
+ throw new AppError_1.AppError(`Variable is not defined: '${subject}' (${name})`);
28
+ return value;
29
+ });
30
+ }
31
+ exports.render = render;
32
+ function parseStringList(value, validValues) {
33
+ const result = value
34
+ ?.split(",")
35
+ .map((v) => v.trim())
36
+ .filter((v) => !!v.length) ?? null;
37
+ if (validValues)
38
+ for (const v of result)
39
+ if (!validValues.includes(v))
40
+ throw new AppError_1.AppError(`Invalid value: ${v}`);
41
+ return result;
42
+ }
43
+ exports.parseStringList = parseStringList;
44
+ function formatUri(input, hidePassword) {
45
+ let uri = "";
46
+ if (input.protocol) {
47
+ uri = `${input.protocol}://`;
48
+ if (input.username) {
49
+ uri += `${input.username}`;
50
+ if (input.password)
51
+ uri += `:${hidePassword ? "********" : input.password}`;
52
+ uri += `@`;
53
+ }
54
+ if (input.host)
55
+ uri += input.host;
56
+ if (input.port)
57
+ uri += `:${input.port}`;
58
+ }
59
+ if (input.path)
60
+ uri += input.path;
61
+ return uri;
62
+ }
63
+ exports.formatUri = formatUri;
64
+ function makePathPatterns(values) {
65
+ return values?.flatMap((v) => [v, `${v}/**`]);
66
+ }
67
+ exports.makePathPatterns = makePathPatterns;
68
+ function formatDateTime(datetime) {
69
+ const date = new Date(datetime);
70
+ const [result] = new Date(date.getTime() - date.getTimezoneOffset() * 60000)
71
+ .toISOString()
72
+ .replace("Z", "")
73
+ .replace("T", " ")
74
+ .split(".");
75
+ return result;
76
+ }
77
+ exports.formatDateTime = formatDateTime;
@@ -0,0 +1,52 @@
1
+ export interface ZipDataFilterType {
2
+ recursive?: boolean;
3
+ exclude?: boolean;
4
+ patterns: string[];
5
+ }
6
+ export declare type ZipStreamDataType = {
7
+ type: "progress";
8
+ data: {
9
+ progress: number;
10
+ files: number;
11
+ path: string;
12
+ };
13
+ } | {
14
+ type: "summary";
15
+ data: {
16
+ folders: number;
17
+ files: number;
18
+ };
19
+ };
20
+ export interface ZipDataType {
21
+ command?: string;
22
+ path: string;
23
+ filter?: (ZipDataFilterType | string)[];
24
+ output: string;
25
+ deleteOnZip?: boolean;
26
+ includeList?: string;
27
+ excludeList?: string;
28
+ verbose?: boolean;
29
+ onStream?: (data: ZipStreamDataType) => Promise<void>;
30
+ }
31
+ export interface UnzipDataType {
32
+ command?: string;
33
+ input: string;
34
+ files?: (ZipDataFilterType | string)[];
35
+ output: string;
36
+ verbose?: boolean;
37
+ onStream?: (data: UnzipStreamDataType) => Promise<void>;
38
+ }
39
+ export declare type UnzipStreamDataType = {
40
+ type: "progress";
41
+ data: {
42
+ progress: number;
43
+ files: number;
44
+ path: string;
45
+ };
46
+ };
47
+ export declare function buildArguments(filters: (ZipDataFilterType | string)[]): string[];
48
+ export declare function zip(data: ZipDataType): Promise<{
49
+ folders: number;
50
+ files: number;
51
+ }>;
52
+ export declare function unzip(data: UnzipDataType): Promise<import("./process-util").ExecResultType>;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unzip = exports.zip = exports.buildArguments = void 0;
4
+ const process_util_1 = require("./process-util");
5
+ const path_1 = require("path");
6
+ function buildArguments(filters) {
7
+ const args = [];
8
+ for (const item of filters) {
9
+ let filter;
10
+ if (typeof item === "string") {
11
+ filter = {
12
+ recursive: false,
13
+ exclude: false,
14
+ patterns: [item],
15
+ };
16
+ }
17
+ else {
18
+ filter = item;
19
+ }
20
+ args.push(...filter.patterns.map((value) => {
21
+ let option = "-";
22
+ option += filter.exclude ? "x" : "i";
23
+ if (filter.recursive)
24
+ option += "r";
25
+ option += "!";
26
+ option += (0, path_1.normalize)(value);
27
+ return option;
28
+ }));
29
+ }
30
+ return args;
31
+ }
32
+ exports.buildArguments = buildArguments;
33
+ async function parseZipStream(chunk, buffer, cb) {
34
+ const lines = chunk.trim().split(/\r?\n/g);
35
+ for (const line of lines) {
36
+ let matches = null;
37
+ if ((matches = /^(\d+)% (\d+ )?\+/.exec(line))) {
38
+ const path = line.slice(line.indexOf("+") + 1).trim();
39
+ const progress = Number(matches[1]);
40
+ if (!buffer.currentPaths)
41
+ buffer.currentPaths = 0;
42
+ if (path !== buffer.lastPath)
43
+ buffer.currentPaths++;
44
+ buffer.lastPath = path;
45
+ await cb({
46
+ type: "progress",
47
+ data: { progress, path, files: buffer.currentPaths },
48
+ });
49
+ }
50
+ else if (line.startsWith("Add new data to archive:")) {
51
+ const [, folders] = /(\d+) folders?/i.exec(line) || [, 0];
52
+ const [, files] = /(\d+) files?/i.exec(line) || [, 0];
53
+ await cb({
54
+ type: "summary",
55
+ data: {
56
+ folders: Number(folders),
57
+ files: Number(files),
58
+ },
59
+ });
60
+ }
61
+ }
62
+ }
63
+ async function zip(data) {
64
+ let result = {
65
+ folders: 0,
66
+ files: 0,
67
+ };
68
+ let buffer = {};
69
+ await (0, process_util_1.exec)(data.command ?? "7z", [
70
+ "a",
71
+ "-mmt1",
72
+ "-bsp1",
73
+ ...(data.deleteOnZip ? ["-sdel"] : []),
74
+ (0, path_1.normalize)(data.output),
75
+ ...buildArguments(data.filter ?? []),
76
+ ...(data.includeList ? [`@${(0, path_1.normalize)(data.includeList)}`] : []),
77
+ ...(data.excludeList ? [`-x@${(0, path_1.normalize)(data.excludeList)}`] : []),
78
+ ], {
79
+ cwd: data.path,
80
+ }, {
81
+ log: data.verbose ?? false,
82
+ stderr: {
83
+ toExitCode: true,
84
+ },
85
+ stdout: {
86
+ onData: async (chunk) => {
87
+ parseZipStream(chunk, buffer, async (stream) => {
88
+ await data.onStream?.(stream);
89
+ if (stream.type === "summary")
90
+ result = stream.data;
91
+ });
92
+ },
93
+ },
94
+ });
95
+ return result;
96
+ }
97
+ exports.zip = zip;
98
+ async function parseUnzipStream(chunk, cb) {
99
+ const lines = chunk.trim().split(/\r?\n/g);
100
+ for (const line of lines) {
101
+ let matches = null;
102
+ if ((matches = /^(\d+)% (\d+) \-/.exec(line))) {
103
+ const progress = Number(matches[1]);
104
+ const files = Number(matches[2]);
105
+ const path = line.slice(line.indexOf("-") + 1).trim();
106
+ await cb({
107
+ type: "progress",
108
+ data: { progress, path, files },
109
+ });
110
+ }
111
+ }
112
+ }
113
+ async function unzip(data) {
114
+ return await (0, process_util_1.exec)(data.command ?? "7z", [
115
+ "x",
116
+ "-mmt1",
117
+ "-bsp1",
118
+ (0, path_1.normalize)(data.input),
119
+ ...buildArguments(data.files ?? []),
120
+ `-o${(0, path_1.normalize)(data.output)}`,
121
+ "-r",
122
+ ], {}, {
123
+ log: data.verbose ?? false,
124
+ stderr: { toExitCode: true },
125
+ stdout: {
126
+ ...(data.onStream && {
127
+ onData: async (chunk) => {
128
+ if (data.onStream)
129
+ parseUnzipStream(chunk, data.onStream);
130
+ },
131
+ }),
132
+ },
133
+ });
134
+ }
135
+ exports.unzip = unzip;
@@ -0,0 +1,122 @@
1
+ --------------------------------------------------------------------------------
2
+ -- Up
3
+ --------------------------------------------------------------------------------
4
+
5
+ CREATE TABLE "backup_session" (
6
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
7
+ "creationDate" TEXT NOT NULL,
8
+ "updatingDate" TEXT,
9
+
10
+ "startDate" TEXT,
11
+ "endDate" TEXT,
12
+ "state" TEXT,
13
+ "error" TEXT,
14
+ "progressCurrent" INTEGER,
15
+ "progressTotal" INTEGER,
16
+ "progressPercent" INTEGER,
17
+ "progressStep" TEXT,
18
+ "progressStepPercent" INTEGER,
19
+
20
+ "snapshotId" TEXT NOT NULL,
21
+ "packageName" TEXT NOT NULL,
22
+ -- "componentName" TEXT NOT NULL,
23
+ "tags" TEXT
24
+ );
25
+
26
+ CREATE TABLE "backup_session_task" (
27
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
28
+ "creationDate" TEXT NOT NULL,
29
+ "updatingDate" TEXT,
30
+
31
+ "startDate" TEXT,
32
+ "endDate" TEXT,
33
+ "state" TEXT,
34
+ "error" TEXT,
35
+ "progressCurrent" INTEGER,
36
+ "progressTotal" INTEGER,
37
+ "progressPercent" INTEGER,
38
+ "progressStep" TEXT,
39
+ "progressStepPercent" INTEGER,
40
+
41
+ "sessionId" INTEGER NOT NULL,
42
+ "taskName" TEXT NOT NULL
43
+ );
44
+
45
+ CREATE TABLE "backup_session_repository" (
46
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
47
+ "creationDate" TEXT NOT NULL,
48
+ "updatingDate" TEXT,
49
+
50
+ "startDate" TEXT,
51
+ "endDate" TEXT,
52
+ "state" TEXT,
53
+ "error" TEXT,
54
+ "progressCurrent" INTEGER,
55
+ "progressTotal" INTEGER,
56
+ "progressPercent" INTEGER,
57
+ "progressStep" TEXT,
58
+ "progressStepPercent" INTEGER,
59
+
60
+ "sessionId" INTEGER NOT NULL,
61
+ "repositoryName" TEXT NOT NULL,
62
+ "repositoryType" TEXT NOT NULL
63
+ );
64
+
65
+ CREATE TABLE "restore_session" (
66
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
67
+ "creationDate" TEXT NOT NULL,
68
+ "updatingDate" TEXT,
69
+
70
+ "startDate" TEXT,
71
+ "endDate" TEXT,
72
+ "state" TEXT,
73
+ "error" TEXT,
74
+ "progressCurrent" INTEGER,
75
+ "progressTotal" INTEGER,
76
+ "progressPercent" INTEGER,
77
+ "progressStep" TEXT,
78
+ "progressStepPercent" INTEGER,
79
+
80
+ "snapshotId" TEXT NOT NULL,
81
+ "packageName" TEXT NOT NULL -- ,
82
+ -- "componentName" TEXT NOT NULL
83
+ );
84
+
85
+ CREATE TABLE "restore_session_task" (
86
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
87
+ "creationDate" TEXT NOT NULL,
88
+ "updatingDate" TEXT,
89
+
90
+ "startDate" TEXT,
91
+ "endDate" TEXT,
92
+ "state" TEXT,
93
+ "error" TEXT,
94
+ "progressCurrent" INTEGER,
95
+ "progressTotal" INTEGER,
96
+ "progressPercent" INTEGER,
97
+ "progressStep" TEXT,
98
+ "progressStepPercent" INTEGER,
99
+
100
+ "sessionId" INTEGER NOT NULL,
101
+ "taskName" TEXT NOT NULL
102
+ );
103
+
104
+ CREATE TABLE "restore_session_repository" (
105
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
106
+ "creationDate" TEXT NOT NULL,
107
+ "updatingDate" TEXT,
108
+
109
+ "startDate" TEXT,
110
+ "endDate" TEXT,
111
+ "state" TEXT,
112
+ "error" TEXT,
113
+ "progressCurrent" INTEGER,
114
+ "progressTotal" INTEGER,
115
+ "progressPercent" INTEGER,
116
+ "progressStep" TEXT,
117
+ "progressStepPercent" INTEGER,
118
+
119
+ "sessionId" INTEGER NOT NULL,
120
+ "repositoryName" TEXT NOT NULL,
121
+ "repositoryType" TEXT NOT NULL
122
+ );
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@datatruck/cli",
3
+ "version": "0.0.1",
4
+ "description": "Tool for creating and managing backups",
5
+ "homepage": "https://github.com/swordev/datatruck#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/swordev/datatruck/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/swordev/datatruck"
12
+ },
13
+ "license": "MIT",
14
+ "author": {
15
+ "name": "Juanra GM",
16
+ "email": "juanrgm724@gmail.com",
17
+ "url": "https://github.com/juanrgm"
18
+ },
19
+ "exports": {
20
+ "./*": "./lib/*.js"
21
+ },
22
+ "main": "lib/index.js",
23
+ "bin": {
24
+ "datatruck": "lib/bin.js",
25
+ "dtt": "lib/bin.js"
26
+ },
27
+ "files": [
28
+ "lib",
29
+ "migrations"
30
+ ],
31
+ "dependencies": {
32
+ "ajv": "^8.10.0",
33
+ "chalk": "^4.1.2",
34
+ "cli-table3": "^0.6.1",
35
+ "commander": "^9.0.0",
36
+ "concurrently": "^7.0.0",
37
+ "dayjs": "^1.10.7",
38
+ "fast-glob": "^3.2.11",
39
+ "fs-extra": "^10.0.1",
40
+ "micromatch": "^4.0.4",
41
+ "sqlite": "^4.0.23",
42
+ "sqlite3": "^5.0.2"
43
+ },
44
+ "devDependencies": {
45
+ "@types/fs-extra": "^9.0.13",
46
+ "@types/json-schema": "^7.0.9",
47
+ "@types/micromatch": "^4.0.2",
48
+ "json-schema": "^0.4.0"
49
+ },
50
+ "optionalDependencies": {
51
+ "ts-node": "^10.5.0",
52
+ "yaml": "^1.10.2"
53
+ },
54
+ "engine": {
55
+ "node": ">=16.0.0"
56
+ },
57
+ "scripts": {
58
+ "build": "tsc --build",
59
+ "clean": "tsc --build --clean",
60
+ "watch": "tsc --build -w"
61
+ }
62
+ }