@datatruck/cli 0.18.0 → 0.19.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 (51) hide show
  1. package/Action/BackupAction.js +4 -2
  2. package/Action/BackupSessionsAction.js +2 -0
  3. package/Action/CleanCacheAction.js +1 -0
  4. package/Action/ConfigAction.js +1 -0
  5. package/Action/InitAction.js +2 -0
  6. package/Action/PruneAction.js +2 -0
  7. package/Action/RestoreAction.js +4 -2
  8. package/Action/RestoreSessionsAction.js +2 -0
  9. package/Action/SnapshotsAction.js +2 -0
  10. package/Command/CommandAbstract.js +2 -0
  11. package/Entity/BackupSessionEntity.js +5 -2
  12. package/Entity/BackupSessionRepositoryEntity.js +5 -2
  13. package/Entity/BackupSessionTaskEntity.js +4 -2
  14. package/Entity/CrudEntityAbstract.js +3 -0
  15. package/Entity/RestoreSessionEntity.js +4 -2
  16. package/Entity/RestoreSessionRepositoryEntity.js +5 -2
  17. package/Entity/RestoreSessionTaskEntity.js +4 -2
  18. package/Entity/StateEntityAbstract.js +5 -0
  19. package/Factory/CommandFactory.js +1 -1
  20. package/JsonSchema/DefinitionEnum.js +1 -1
  21. package/Repository/DatatruckRepository.d.ts +8 -13
  22. package/Repository/DatatruckRepository.js +112 -229
  23. package/Repository/GitRepository.js +1 -1
  24. package/Repository/RepositoryAbstract.js +4 -2
  25. package/Repository/ResticRepository.js +2 -1
  26. package/SessionDriver/ConsoleSessionDriver.js +9 -5
  27. package/SessionDriver/SessionDriverAbstract.js +3 -2
  28. package/SessionDriver/SqliteSessionDriver.js +2 -4
  29. package/SessionManager/BackupSessionManager.js +3 -6
  30. package/SessionManager/RestoreSessionManager.js +3 -6
  31. package/SessionManager/SessionManagerAbstract.js +4 -0
  32. package/Task/GitTask.js +1 -0
  33. package/Task/MariadbTask.js +5 -4
  34. package/Task/MssqlTask.js +2 -1
  35. package/Task/ScriptTask.js +1 -0
  36. package/Task/SqlDumpTaskAbstract.js +1 -0
  37. package/Task/TaskAbstract.js +2 -1
  38. package/config.schema.json +23 -37
  39. package/index.d.ts +1 -0
  40. package/index.js +1 -0
  41. package/package.json +9 -8
  42. package/utils/DataFormat.js +1 -0
  43. package/utils/Git.js +1 -0
  44. package/utils/ObjectVault.js +3 -5
  45. package/utils/Restic.js +1 -0
  46. package/utils/fs.d.ts +3 -9
  47. package/utils/fs.js +24 -32
  48. package/utils/tar.d.ts +32 -0
  49. package/utils/tar.js +92 -0
  50. package/utils/zip.d.ts +0 -97
  51. package/utils/zip.js +0 -238
@@ -3,9 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TaskAbstract = void 0;
4
4
  const fs_1 = require("../utils/fs");
5
5
  class TaskAbstract {
6
+ config;
7
+ tmpDirs = [];
6
8
  constructor(config) {
7
9
  this.config = config;
8
- this.tmpDirs = [];
9
10
  }
10
11
  async mkTmpDir(prefix, id) {
11
12
  const dir = await (0, fs_1.mkTmpDir)(prefix, id);
@@ -458,45 +458,31 @@
458
458
  "additionalProperties": false,
459
459
  "properties": {
460
460
  "compress": {
461
- "anyOf": [
462
- {
463
- "type": "boolean"
464
- },
465
- {
466
- "type": "object",
467
- "additionalProperties": false,
468
- "properties": {
469
- "packs": {
470
- "type": "array",
471
- "items": {
472
- "type": "object",
473
- "additionalProperties": false,
474
- "required": [
475
- "include"
476
- ],
477
- "properties": {
478
- "name": {
479
- "type": "string"
480
- },
481
- "include": {
482
- "$ref": "#/definitions/stringlist-util"
483
- },
484
- "exclude": {
485
- "$ref": "#/definitions/stringlist-util"
486
- },
487
- "onePackByResult": {
488
- "type": "boolean"
489
- }
490
- }
491
- }
492
- }
461
+ "type": "boolean"
462
+ },
463
+ "packs": {
464
+ "type": "array",
465
+ "items": {
466
+ "type": "object",
467
+ "additionalProperties": false,
468
+ "required": [
469
+ "include"
470
+ ],
471
+ "properties": {
472
+ "name": {
473
+ "type": "string"
474
+ },
475
+ "include": {
476
+ "$ref": "#/definitions/stringlist-util"
477
+ },
478
+ "exclude": {
479
+ "$ref": "#/definitions/stringlist-util"
480
+ },
481
+ "onePackByResult": {
482
+ "type": "boolean"
493
483
  }
494
484
  }
495
- ]
496
- },
497
- "fileCopyConcurrency": {
498
- "type": "integer",
499
- "minimum": 1
485
+ }
500
486
  }
501
487
  }
502
488
  },
package/index.d.ts CHANGED
@@ -0,0 +1 @@
1
+ export {};
package/index.js CHANGED
@@ -1 +1,2 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,23 +1,24 @@
1
1
  {
2
2
  "name": "@datatruck/cli",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "dependencies": {
5
5
  "ajv": "^8.12.0",
6
6
  "async": "^3.2.4",
7
7
  "chalk": "^4.1.2",
8
8
  "cli-table3": "^0.6.3",
9
- "commander": "^9.4.1",
10
- "dayjs": "^1.11.7",
11
- "fast-folder-size": "^1.7.1",
12
- "fast-glob": "^3.2.12",
9
+ "commander": "^11.0.0",
10
+ "dayjs": "^1.11.10",
11
+ "fast-folder-size": "^2.2.0",
12
+ "fast-glob": "^3.3.1",
13
13
  "micromatch": "^4.0.5",
14
14
  "pretty-bytes": "^5.6.0",
15
- "sqlite": "^4.1.2",
16
- "sqlite3": "^5.1.4"
15
+ "sqlite": "^5.0.1",
16
+ "sqlite3": "^5.1.6",
17
+ "tar": "^6.2.0"
17
18
  },
18
19
  "optionalDependencies": {
19
20
  "ts-node": "^10.9.1",
20
- "yaml": "^2.2.1"
21
+ "yaml": "^2.3.2"
21
22
  },
22
23
  "engine": {
23
24
  "node": ">=16.0.0"
@@ -10,6 +10,7 @@ const util_1 = require("util");
10
10
  const customPrefix = "custom=";
11
11
  const tplPrefix = "tpl=";
12
12
  class DataFormat {
13
+ options;
13
14
  constructor(options) {
14
15
  this.options = options;
15
16
  }
package/utils/Git.js CHANGED
@@ -4,6 +4,7 @@ exports.Git = void 0;
4
4
  const fs_1 = require("./fs");
5
5
  const process_1 = require("./process");
6
6
  class Git {
7
+ options;
7
8
  constructor(options) {
8
9
  this.options = options;
9
10
  }
@@ -2,11 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObjectVault = void 0;
4
4
  class ObjectVault {
5
- constructor() {
6
- this.counter = 0;
7
- this.ids = {};
8
- this.objects = {};
9
- }
5
+ counter = 0;
6
+ ids = {};
7
+ objects = {};
10
8
  static serializeKeys(keys) {
11
9
  return JSON.stringify(keys);
12
10
  }
package/utils/Restic.js CHANGED
@@ -7,6 +7,7 @@ const string_1 = require("./string");
7
7
  const promises_1 = require("fs/promises");
8
8
  const path_1 = require("path");
9
9
  class Restic {
10
+ options;
10
11
  constructor(options) {
11
12
  this.options = options;
12
13
  }
package/utils/fs.d.ts CHANGED
@@ -104,18 +104,12 @@ export declare function createFileScanner(options: {
104
104
  include: string[];
105
105
  };
106
106
  onProgress: (data: Progress) => Promise<void>;
107
- disableCounting?: boolean;
108
- disableEndProgress?: boolean;
109
107
  }): Promise<{
108
+ disposed: boolean;
110
109
  total: number;
111
110
  current: number;
112
- progress: (description: string, data: {
113
- path?: string;
114
- current: number;
115
- type?: "start" | "end";
116
- percent?: number;
117
- }) => Promise<void>;
118
- updateProgress: (end?: boolean) => Promise<void>;
111
+ progress: (description: string, path?: string) => Promise<void>;
112
+ end: () => Promise<void>;
119
113
  start: (cb?: ((entry: Required<Entry>) => any) | undefined) => Promise<void>;
120
114
  }>;
121
115
  export {};
package/utils/fs.js CHANGED
@@ -458,62 +458,54 @@ async function cpy(options) {
458
458
  exports.cpy = cpy;
459
459
  async function createFileScanner(options) {
460
460
  const object = {
461
+ disposed: false,
461
462
  total: 0,
462
463
  current: 0,
463
- progress: async (description, data) => {
464
+ progress: async (description, path) => {
465
+ if (object.disposed)
466
+ return;
467
+ if (path)
468
+ object.current++;
464
469
  await options.onProgress({
465
470
  relative: {
466
471
  description,
467
- payload: data.path,
468
- percent: data.percent,
472
+ payload: path,
469
473
  },
470
474
  absolute: {
471
475
  total: object.total,
472
- current: object.current + data.current,
473
- percent: (0, math_1.progressPercent)(object.total, object.current + data.current),
476
+ current: object.current,
477
+ percent: (0, math_1.progressPercent)(object.total, object.current),
474
478
  },
475
479
  });
476
- if (data.type === "end") {
477
- object.current += data.current;
478
- }
479
480
  },
480
- updateProgress: async (end) => {
481
- const currentTime = performance.now();
482
- const diff = currentTime - lastTime;
483
- if (end || diff > 1000) {
484
- await options.onProgress({
485
- relative: {
486
- description: end ? "Scanned files" : "Scanning files",
487
- payload: object.total.toString(),
488
- },
489
- });
490
- lastTime = currentTime;
491
- }
481
+ end: async () => {
482
+ if (!object.disposed)
483
+ await object.progress("Finished");
484
+ object.disposed = true;
492
485
  },
493
486
  start: async (cb) => {
487
+ let lastTime = performance.now();
488
+ await object.progress("Scanning files");
494
489
  for await (const entry of pathIterator(stream)) {
495
- if (!options.disableCounting)
490
+ if (cb) {
491
+ if (await cb(entry))
492
+ object.total++;
493
+ }
494
+ else {
496
495
  object.total++;
497
- await object.updateProgress();
498
- if (cb)
499
- await cb(entry);
496
+ }
497
+ if (lastTime - performance.now() > 500)
498
+ await object.progress("Scanning files");
500
499
  }
501
- if (!options.disableEndProgress)
502
- await object.updateProgress(true);
500
+ await object.progress("Scanned files");
503
501
  },
504
502
  };
505
- await options.onProgress({
506
- relative: {
507
- description: "Scanning files",
508
- },
509
- });
510
503
  const stream = fast_glob_1.default.stream(options.glob.include, {
511
504
  dot: true,
512
505
  markDirectories: true,
513
506
  stats: true,
514
507
  ...options.glob,
515
508
  });
516
- let lastTime = performance.now();
517
509
  return object;
518
510
  }
519
511
  exports.createFileScanner = createFileScanner;
package/utils/tar.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ export type Progress = {
2
+ percent: number;
3
+ current: number;
4
+ total: number;
5
+ };
6
+ export type TarEntry = {
7
+ path: string;
8
+ progress: Progress;
9
+ };
10
+ export interface CreateTarOptions {
11
+ path: string;
12
+ verbose?: boolean;
13
+ output: string;
14
+ include: string[];
15
+ compress?: boolean;
16
+ onEntry?: (entry: TarEntry) => void;
17
+ }
18
+ export interface ExtractOptions {
19
+ input: string;
20
+ output: string;
21
+ verbose?: boolean;
22
+ total?: number;
23
+ onEntry?: (entry: TarEntry) => void;
24
+ }
25
+ export type ListTarOptions = {
26
+ input: string;
27
+ onEntry?: (entry: Pick<TarEntry, "path">) => void;
28
+ verbose?: boolean;
29
+ };
30
+ export declare function listTar(options: ListTarOptions): Promise<number>;
31
+ export declare function createTar(options: CreateTarOptions): Promise<void>;
32
+ export declare function extractTar(options: ExtractOptions): Promise<void>;
package/utils/tar.js ADDED
@@ -0,0 +1,92 @@
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.extractTar = exports.createTar = exports.listTar = void 0;
7
+ const cli_1 = require("./cli");
8
+ const fs_1 = require("./fs");
9
+ const math_1 = require("./math");
10
+ const fs_2 = require("fs");
11
+ const promises_1 = require("fs/promises");
12
+ const tar_1 = __importDefault(require("tar"));
13
+ async function listTar(options) {
14
+ if (options.verbose)
15
+ (0, cli_1.logExec)("tar", ["-ztvf", options.input]);
16
+ let total = 0;
17
+ await tar_1.default.list({
18
+ file: options.input,
19
+ onentry(entry) {
20
+ options.onEntry?.({ path: entry.path });
21
+ total++;
22
+ },
23
+ });
24
+ return total;
25
+ }
26
+ exports.listTar = listTar;
27
+ async function createTar(options) {
28
+ if (options.verbose)
29
+ (0, cli_1.logExec)("tar", [
30
+ options.compress ? "-czvf" : "-cvf",
31
+ options.output,
32
+ options.path,
33
+ ]);
34
+ let total = options.include.length;
35
+ if (!total)
36
+ throw new Error("'include' option is empty");
37
+ let current = 0;
38
+ let progressPromise;
39
+ const inStream = tar_1.default.create({
40
+ gzip: options.compress,
41
+ cwd: options.path,
42
+ filter(path) {
43
+ current++;
44
+ options.onEntry?.({
45
+ path: path,
46
+ progress: {
47
+ total,
48
+ current,
49
+ percent: (0, math_1.progressPercent)(total, current),
50
+ },
51
+ });
52
+ return true;
53
+ },
54
+ }, options.include);
55
+ const outStream = (0, fs_2.createWriteStream)(options.output);
56
+ await new Promise((resolve, reject) => {
57
+ inStream.on("error", reject);
58
+ outStream.on("error", reject);
59
+ inStream.pipe(outStream);
60
+ outStream.on("close", resolve);
61
+ });
62
+ await progressPromise;
63
+ }
64
+ exports.createTar = createTar;
65
+ async function extractTar(options) {
66
+ let total = options.total ??
67
+ (await listTar({ input: options.input, verbose: options.verbose }));
68
+ if (options.verbose) {
69
+ (0, cli_1.logExec)("tar", ["-xzvfp", options.input, "-C", options.output]);
70
+ (0, cli_1.logExec)("mkdir", ["-p", options.output]);
71
+ }
72
+ let current = 0;
73
+ await (0, promises_1.mkdir)(options.output, { recursive: true });
74
+ await (0, fs_1.ensureEmptyDir)(options.output);
75
+ await tar_1.default.extract({
76
+ file: options.input,
77
+ cwd: options.output,
78
+ preserveOwner: true,
79
+ onentry(entry) {
80
+ current++;
81
+ options.onEntry?.({
82
+ path: entry.path,
83
+ progress: {
84
+ total,
85
+ current,
86
+ percent: (0, math_1.progressPercent)(total, current),
87
+ },
88
+ });
89
+ },
90
+ });
91
+ }
92
+ exports.extractTar = extractTar;
package/utils/zip.d.ts DELETED
@@ -1,97 +0,0 @@
1
- export interface ZipDataFilterType {
2
- recursive?: boolean;
3
- exclude?: boolean;
4
- patterns: string[];
5
- }
6
- export interface ZipDataType {
7
- command?: string;
8
- path: string;
9
- filter?: (ZipDataFilterType | string)[];
10
- output: string;
11
- deleteOnZip?: boolean;
12
- includeList?: string;
13
- excludeList?: string;
14
- verbose?: boolean;
15
- onProgress?: (data: {
16
- percent: number;
17
- total: number;
18
- current: number;
19
- path?: string;
20
- type?: "start" | "end";
21
- }) => void | Promise<void>;
22
- onStream?: (data: ZipStream) => void | Promise<void>;
23
- }
24
- export interface UnzipDataType {
25
- command?: string;
26
- input: string;
27
- files?: (ZipDataFilterType | string)[];
28
- output: string;
29
- verbose?: boolean;
30
- onProgress?: (data: {
31
- percent: number;
32
- current: number;
33
- path?: string;
34
- type?: "start" | "end";
35
- }) => void | Promise<void>;
36
- onStream?: (data: UnzipStream) => void | Promise<void>;
37
- }
38
- export declare function buildArguments(filters: (ZipDataFilterType | string)[]): string[];
39
- export declare function checkSSEOption(command?: string): Promise<boolean>;
40
- type ListZipStream = {
41
- Path?: string;
42
- Folder?: string;
43
- Size?: string;
44
- "Packed Size"?: string;
45
- Modified?: string;
46
- Created?: string;
47
- Accessed?: string;
48
- Attributes?: string;
49
- Encrypted?: string;
50
- Comment?: string;
51
- CRC?: string;
52
- Method?: string;
53
- Characteristics?: string;
54
- "Host OS"?: string;
55
- Version?: string;
56
- Volume?: string;
57
- Offset?: string;
58
- };
59
- export declare function listZip(data: {
60
- command?: string;
61
- path: string;
62
- onStream: (item: ListZipStream) => Promise<void>;
63
- verbose?: boolean;
64
- }): Promise<void>;
65
- export type ZipStream = {
66
- type: "progress";
67
- data: {
68
- progress: number;
69
- files: number;
70
- path: string;
71
- };
72
- } | {
73
- type: "summary";
74
- data: {
75
- folders: number;
76
- files: number;
77
- };
78
- };
79
- export declare function zip(data: ZipDataType): Promise<{
80
- folders: number;
81
- files: number;
82
- }>;
83
- export type UnzipStream = {
84
- type: "progress";
85
- data: {
86
- percent: number;
87
- files: number;
88
- path: string;
89
- };
90
- };
91
- export declare function unzip(data: UnzipDataType): Promise<{
92
- files: number;
93
- stdout: string;
94
- stderr: string;
95
- exitCode: number;
96
- }>;
97
- export {};