@datatruck/cli 0.15.0 → 0.16.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 (36) hide show
  1. package/Action/BackupAction.js +7 -7
  2. package/Action/RestoreAction.js +4 -4
  3. package/Entity/StateEntityAbstract.d.ts +2 -6
  4. package/Error/AppError.d.ts +1 -0
  5. package/Error/AppError.js +4 -0
  6. package/Repository/DatatruckRepository.js +68 -87
  7. package/Repository/RepositoryAbstract.d.ts +4 -15
  8. package/Repository/ResticRepository.js +14 -14
  9. package/SessionDriver/ConsoleSessionDriver.d.ts +2 -6
  10. package/SessionDriver/ConsoleSessionDriver.js +52 -26
  11. package/SessionDriver/SqliteSessionDriver.js +5 -0
  12. package/SessionManager/BackupSessionManager.d.ts +5 -3
  13. package/SessionManager/BackupSessionManager.js +14 -18
  14. package/SessionManager/RestoreSessionManager.d.ts +6 -4
  15. package/SessionManager/RestoreSessionManager.js +14 -18
  16. package/SessionManager/SessionManagerAbstract.d.ts +5 -1
  17. package/SessionManager/SessionManagerAbstract.js +13 -2
  18. package/Task/GitTask.js +6 -6
  19. package/Task/MariadbTask.js +3 -3
  20. package/Task/MysqlDumpTask.d.ts +3 -1
  21. package/Task/MysqlDumpTask.js +5 -2
  22. package/Task/PostgresqlDumpTask.d.ts +3 -1
  23. package/Task/PostgresqlDumpTask.js +2 -2
  24. package/Task/SqlDumpTaskAbstract.d.ts +3 -1
  25. package/Task/SqlDumpTaskAbstract.js +33 -11
  26. package/Task/TaskAbstract.d.ts +3 -14
  27. package/migrations/001-initial.sql +6 -36
  28. package/package.json +1 -1
  29. package/util/cli-util.d.ts +1 -1
  30. package/util/cli-util.js +17 -2
  31. package/util/fs-util.js +1 -1
  32. package/util/process-util.d.ts +3 -0
  33. package/util/process-util.js +11 -0
  34. package/util/progress.d.ts +12 -0
  35. package/util/progress.js +2 -0
  36. package/util/zip-util.js +6 -2
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.ConsoleSessionDriver = void 0;
4
7
  const AppError_1 = require("../Error/AppError");
@@ -6,6 +9,7 @@ const cli_util_1 = require("../util/cli-util");
6
9
  const date_util_1 = require("../util/date-util");
7
10
  const SessionDriverAbstract_1 = require("./SessionDriverAbstract");
8
11
  const chalk_1 = require("chalk");
12
+ const pretty_bytes_1 = __importDefault(require("pretty-bytes"));
9
13
  const sep = (0, chalk_1.grey)(`|`);
10
14
  const renderBadge = (badge) => `${badge.color(badge.name)}${(0, chalk_1.grey)(`:`)} ${(0, chalk_1.white)(badge.value)}`;
11
15
  const renderBadges = (badges) => badges.map(renderBadge).join(` ${sep} `);
@@ -72,28 +76,53 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
72
76
  ]);
73
77
  const padding = " ".repeat(message.level ?? 0);
74
78
  const sessionId = message.sessionId.toString().padStart(2, "0");
75
- const parts = [
79
+ let parts = [
76
80
  `${padding}${message.textPrefix} [${(0, chalk_1.grey)(sessionId)}] ${message.text}`,
77
81
  badges,
78
82
  ];
79
- if (typeof message.progressPercent === "number") {
80
- parts.push((0, chalk_1.cyan)((0, cli_util_1.renderProgressBar)(message.progressPercent ?? 0, 10)), `${message.progressPercent?.toFixed(2)}%`);
81
- }
82
- if (typeof message.progressCurrent === "number" ||
83
- typeof message.progressTotal === "number") {
84
- parts.push(`${message.progressCurrent ?? "?"}/${message.progressTotal ?? "?"}`);
85
- }
86
- if (message.progressStepDescription && message.progressStepItem) {
87
- parts.push(`${message.progressStepDescription}: ${message.progressStepItem}`);
88
- }
89
- else if (message.progressStepDescription) {
90
- parts.push(message.progressStepDescription);
91
- }
92
- else if (message.progressStepItem) {
93
- parts.push(message.progressStepItem);
94
- }
95
- if (typeof message.progressStepPercent === "number") {
96
- parts.push((0, chalk_1.cyan)((0, cli_util_1.renderProgressBar)(message.progressStepPercent ?? 0, 10)));
83
+ const progress = message.progress;
84
+ const absolute = progress?.absolute || {};
85
+ const relative = progress?.relative || {};
86
+ if (typeof absolute.percent === "number" ||
87
+ typeof relative.percent === "number") {
88
+ parts.push((0, cli_util_1.renderProgressBar)(absolute.percent ?? 0, 10, relative.percent ?? undefined));
89
+ }
90
+ const createProgressParts = (p) => {
91
+ const result = [];
92
+ if (typeof p.percent === "number")
93
+ result.push(`${p.percent.toFixed(2)}%`);
94
+ if (typeof p.current === "number" || typeof p.total === "number") {
95
+ const format = (value) => p.format === "size" ? (0, pretty_bytes_1.default)(value) : value;
96
+ if (typeof p.current === "number" && typeof p.total === "number") {
97
+ result.push(`${format(p.current)}/${format(p.total)}`);
98
+ }
99
+ else if (typeof p.current === "number") {
100
+ result.push(`${format(p.current)}`);
101
+ }
102
+ else if (typeof p.total === "number") {
103
+ result.push(`?/${format(p.total)}`);
104
+ }
105
+ }
106
+ if (p.description && p.payload) {
107
+ result.push(`${p.description}: ${p.payload}`);
108
+ }
109
+ else if (p.description) {
110
+ result.push(p.description);
111
+ }
112
+ else if (p.payload) {
113
+ result.push(p.payload);
114
+ }
115
+ return result;
116
+ };
117
+ if (progress?.absolute)
118
+ parts.push(...createProgressParts(progress?.absolute));
119
+ if (progress?.relative) {
120
+ const relativeParts = createProgressParts(progress?.relative);
121
+ if (relativeParts.length) {
122
+ return (parts.join(` ${sep} `) +
123
+ ` ${(0, chalk_1.cyan)("▷")} ` +
124
+ relativeParts.join(` ${sep} `));
125
+ }
97
126
  }
98
127
  return parts.join(` ${sep} `);
99
128
  }
@@ -124,7 +153,9 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
124
153
  if (data.data.error)
125
154
  message.errorBadge = {
126
155
  name: "error",
127
- value: this.tty ? data.data.error.split("\n")[0] : data.data.error,
156
+ value: this.tty && data.data.error.startsWith(`${AppError_1.AppError.name} :`)
157
+ ? data.data.error.split("\n")[0]
158
+ : data.data.error,
128
159
  color: chalk_1.red,
129
160
  };
130
161
  }
@@ -132,12 +163,7 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
132
163
  message.textPrefix = "{spinner}";
133
164
  }
134
165
  if (hasProgress) {
135
- message.progressPercent = data.data.progressPercent;
136
- message.progressCurrent = data.data.progressCurrent;
137
- message.progressTotal = data.data.progressTotal;
138
- message.progressStepDescription = data.data.progressStepDescription;
139
- message.progressStepItem = data.data.progressStepItem;
140
- message.progressStepPercent = data.data.progressStepPercent;
166
+ message.progress = data.data.progress;
141
167
  }
142
168
  if (data.entity === SessionDriverAbstract_1.EntityEnum.BackupSession ||
143
169
  data.entity === SessionDriverAbstract_1.EntityEnum.RestoreSession) {
@@ -134,6 +134,11 @@ class SqliteSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
134
134
  let stm;
135
135
  let object = data.data;
136
136
  const id = object.id;
137
+ object = {
138
+ ...object,
139
+ // @ts-expect-error
140
+ progress: data.data.progress ? JSON.stringify(data.data.progress) : null,
141
+ };
137
142
  if (data.action === SessionDriverAbstract_1.ActionEnum.Init) {
138
143
  // @ts-expect-error
139
144
  object = { ...object, id: null };
@@ -2,9 +2,9 @@ import { BackupSessionsActionOptionsType } from "../Action/BackupSessionsAction"
2
2
  import { BackupSessionEntity } from "../Entity/BackupSessionEntity";
3
3
  import { BackupSessionRepositoryEntity } from "../Entity/BackupSessionRepositoryEntity";
4
4
  import { BackupSessionTaskEntity } from "../Entity/BackupSessionTaskEntity";
5
- import { ProgressDataType } from "../Repository/RepositoryAbstract";
6
5
  import { WriteDataType } from "../SessionDriver/SessionDriverAbstract";
7
6
  import { ObjectVault } from "../util/ObjectVault";
7
+ import { Progress } from "../util/progress";
8
8
  import SessionManagerAbstract from "./SessionManagerAbstract";
9
9
  export declare class BackupSessionManager extends SessionManagerAbstract {
10
10
  sessionVault: ObjectVault<BackupSessionEntity>;
@@ -33,11 +33,13 @@ export declare class BackupSessionManager extends SessionManagerAbstract {
33
33
  startTask(input: Pick<BackupSessionTaskEntity, "id">): Promise<number>;
34
34
  progressTask(input: {
35
35
  id: number;
36
- } & ProgressDataType): Promise<number>;
36
+ progress: Progress;
37
+ }): Promise<number>;
37
38
  endTask(input: Pick<BackupSessionTaskEntity, "id" | "error">): Promise<number>;
38
39
  startRepository(input: Pick<BackupSessionRepositoryEntity, "id">): Promise<number>;
39
40
  progressRepository(input: {
40
41
  id: number;
41
- } & ProgressDataType): Promise<number>;
42
+ progress: Progress;
43
+ }): Promise<number>;
42
44
  endRepository(input: Pick<BackupSessionRepositoryEntity, "id" | "error">): Promise<number>;
43
45
  }
@@ -33,17 +33,25 @@ class BackupSessionManager extends SessionManagerAbstract_1.default {
33
33
  }
34
34
  async endDrivers(data) {
35
35
  const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
36
+ this.stopDelayedProgress();
36
37
  for (const driver of drivers) {
37
38
  await driver.onEnd(data);
38
39
  }
39
40
  }
40
41
  async alter(data) {
41
42
  const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
43
+ const write = async () => {
44
+ for (const driver of drivers) {
45
+ await driver.onWrite(data);
46
+ }
47
+ };
42
48
  if (data.action === SessionDriverAbstract_1.ActionEnum.Progress &&
43
- !this.checkProgress(data.data.progressStepDescription))
44
- return data.data.id;
45
- for (const driver of drivers) {
46
- await driver.onWrite(data);
49
+ !this.checkProgress(data.data.progress?.relative?.description)) {
50
+ this.delayProgress(write);
51
+ }
52
+ else {
53
+ this.stopDelayedProgress();
54
+ await write();
47
55
  }
48
56
  return data.data.id;
49
57
  }
@@ -146,13 +154,7 @@ class BackupSessionManager extends SessionManagerAbstract_1.default {
146
154
  sessionData: this.sessionVault.get(object.sessionId),
147
155
  data: {
148
156
  ...object,
149
- id: input.id,
150
- progressCurrent: input.stats?.current,
151
- progressTotal: input.stats?.total,
152
- progressPercent: input.stats?.percent,
153
- progressStepDescription: input.step?.description,
154
- progressStepItem: input.step?.item,
155
- progressStepPercent: input.step?.percent,
157
+ ...input,
156
158
  updatingDate: new Date().toISOString(),
157
159
  },
158
160
  });
@@ -195,13 +197,7 @@ class BackupSessionManager extends SessionManagerAbstract_1.default {
195
197
  sessionData: this.sessionVault.get(object.sessionId),
196
198
  data: {
197
199
  ...object,
198
- id: input.id,
199
- progressCurrent: input.stats?.current,
200
- progressTotal: input.stats?.total,
201
- progressPercent: input.stats?.percent,
202
- progressStepDescription: input.step?.description,
203
- progressStepItem: input.step?.item,
204
- progressStepPercent: input.step?.percent,
200
+ ...input,
205
201
  updatingDate: new Date().toISOString(),
206
202
  },
207
203
  });
@@ -2,16 +2,16 @@ import { BackupSessionsActionOptionsType } from "../Action/BackupSessionsAction"
2
2
  import { RestoreSessionEntity } from "../Entity/RestoreSessionEntity";
3
3
  import { RestoreSessionRepositoryEntity } from "../Entity/RestoreSessionRepositoryEntity";
4
4
  import { RestoreSessionTaskEntity } from "../Entity/RestoreSessionTaskEntity";
5
- import { ProgressDataType } from "../Repository/RepositoryAbstract";
6
5
  import { WriteDataType } from "../SessionDriver/SessionDriverAbstract";
7
6
  import { ObjectVault } from "../util/ObjectVault";
7
+ import { Progress } from "../util/progress";
8
8
  import SessionManagerAbstract from "./SessionManagerAbstract";
9
9
  export declare class RestoreSessionManager extends SessionManagerAbstract {
10
10
  sessionVault: ObjectVault<RestoreSessionEntity>;
11
11
  repositoryVault: ObjectVault<RestoreSessionRepositoryEntity>;
12
12
  taskVault: ObjectVault<RestoreSessionTaskEntity>;
13
13
  protected lastProgressDate: number | undefined;
14
- protected lastProgressStepDescription: string | null | undefined;
14
+ protected lastRelativeProgressDescription: string | null | undefined;
15
15
  findId(data: {
16
16
  packageName: string;
17
17
  }): number;
@@ -36,10 +36,12 @@ export declare class RestoreSessionManager extends SessionManagerAbstract {
36
36
  startRepository(input: Pick<RestoreSessionRepositoryEntity, "id">): Promise<number>;
37
37
  progressTask(input: {
38
38
  id: number;
39
- } & ProgressDataType): Promise<number>;
39
+ progress: Progress;
40
+ }): Promise<number>;
40
41
  endTask(input: Pick<RestoreSessionTaskEntity, "id" | "error">): Promise<number>;
41
42
  progressRepository(input: {
42
43
  id: number;
43
- } & ProgressDataType): Promise<number>;
44
+ progress: Progress;
45
+ }): Promise<number>;
44
46
  endRepository(input: Pick<RestoreSessionRepositoryEntity, "id" | "error">): Promise<number>;
45
47
  }
@@ -33,17 +33,25 @@ class RestoreSessionManager extends SessionManagerAbstract_1.default {
33
33
  }
34
34
  async endDrivers() {
35
35
  const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
36
+ this.stopDelayedProgress();
36
37
  for (const driver of drivers) {
37
38
  await driver.onEnd();
38
39
  }
39
40
  }
40
41
  async alter(data) {
41
42
  const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
43
+ const write = async () => {
44
+ for (const driver of drivers) {
45
+ await driver.onWrite(data);
46
+ }
47
+ };
42
48
  if (data.action === SessionDriverAbstract_1.ActionEnum.Progress &&
43
- !this.checkProgress(data.data.progressStepDescription))
44
- return data.data.id;
45
- for (const driver of drivers) {
46
- await driver.onWrite(data);
49
+ !this.checkProgress(data.data.progress?.relative?.description)) {
50
+ this.delayProgress(write);
51
+ }
52
+ else {
53
+ this.stopDelayedProgress();
54
+ await write();
47
55
  }
48
56
  return data.data.id;
49
57
  }
@@ -161,13 +169,7 @@ class RestoreSessionManager extends SessionManagerAbstract_1.default {
161
169
  sessionData: this.sessionVault.get(object.sessionId),
162
170
  data: {
163
171
  ...object,
164
- id: input.id,
165
- progressCurrent: input.stats?.current,
166
- progressTotal: input.stats?.total,
167
- progressPercent: input.stats?.percent,
168
- progressStepDescription: input.step?.description,
169
- progressStepItem: input.step?.item,
170
- progressStepPercent: input.step?.percent,
172
+ ...input,
171
173
  updatingDate: new Date().toISOString(),
172
174
  },
173
175
  });
@@ -195,13 +197,7 @@ class RestoreSessionManager extends SessionManagerAbstract_1.default {
195
197
  sessionData: this.sessionVault.get(object.sessionId),
196
198
  data: {
197
199
  ...object,
198
- id: input.id,
199
- progressCurrent: input.stats?.current,
200
- progressTotal: input.stats?.total,
201
- progressPercent: input.stats?.percent,
202
- progressStepDescription: input.step?.description,
203
- progressStepItem: input.step?.item,
204
- progressStepPercent: input.step?.percent,
200
+ ...input,
205
201
  updatingDate: new Date().toISOString(),
206
202
  },
207
203
  });
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { SessionDriverAbstract } from "../SessionDriver/SessionDriverAbstract";
2
3
  export declare type OptionsType = {
3
4
  driver: SessionDriverAbstract;
@@ -8,7 +9,10 @@ export declare type OptionsType = {
8
9
  export default abstract class SessionManagerAbstract {
9
10
  readonly options: OptionsType;
10
11
  protected lastProgressDate: number | undefined;
11
- protected lastProgressStepDescription: string | null | undefined;
12
+ protected lastRelativeProgressDescription: string | null | undefined;
13
+ protected progressTimeout: ReturnType<typeof setTimeout> | undefined;
12
14
  constructor(options: OptionsType);
15
+ protected stopDelayedProgress(): void;
16
+ protected delayProgress(cb: () => Promise<any>): void;
13
17
  protected checkProgress(description: string | null | undefined): boolean;
14
18
  }
@@ -4,16 +4,27 @@ class SessionManagerAbstract {
4
4
  constructor(options) {
5
5
  this.options = options;
6
6
  }
7
+ stopDelayedProgress() {
8
+ clearTimeout(this.progressTimeout);
9
+ this.progressTimeout = undefined;
10
+ }
11
+ delayProgress(cb) {
12
+ clearTimeout(this.progressTimeout);
13
+ this.progressTimeout = setTimeout(async () => {
14
+ this.progressTimeout = undefined;
15
+ await cb();
16
+ }, 1500);
17
+ }
7
18
  checkProgress(description) {
8
19
  const progressInterval = this.options.progressInterval;
9
20
  if (progressInterval) {
10
21
  const skip = this.lastProgressDate &&
11
- description === this.lastProgressStepDescription &&
22
+ description === this.lastRelativeProgressDescription &&
12
23
  Date.now() - this.lastProgressDate < progressInterval;
13
24
  if (skip)
14
25
  return false;
15
26
  this.lastProgressDate = Date.now();
16
- this.lastProgressStepDescription = description;
27
+ this.lastRelativeProgressDescription = description;
17
28
  }
18
29
  return true;
19
30
  }
package/Task/GitTask.js CHANGED
@@ -73,7 +73,7 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
73
73
  // Bundle
74
74
  const bundlePath = (0, path_1.join)(targetPath, "repo.bundle");
75
75
  await data.onProgress({
76
- step: {
76
+ relative: {
77
77
  description: "Creating bundle",
78
78
  },
79
79
  });
@@ -176,11 +176,11 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
176
176
  onPath: async ({ entryPath }) => {
177
177
  currentFiles++;
178
178
  await data.onProgress({
179
- step: {
179
+ relative: {
180
180
  description: "Copying file",
181
- item: entryPath,
181
+ payload: entryPath,
182
182
  },
183
- stats: {
183
+ absolute: {
184
184
  total,
185
185
  current: currentFiles,
186
186
  percent: (0, math_util_1.progressPercent)(total, currentFiles),
@@ -210,12 +210,12 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
210
210
  await (0, fs_util_1.forEachFile)(targetPath, () => totalFiles++, true);
211
211
  const incrementProgress = async (description, item, count = true) => {
212
212
  await data.onProgress({
213
- stats: {
213
+ absolute: {
214
214
  total: totalFiles,
215
215
  current: Math.max(currentFiles, 0),
216
216
  percent: (0, math_util_1.progressPercent)(totalFiles, Math.max(currentFiles, 0)),
217
217
  },
218
- step: { description, item },
218
+ relative: { description, payload: item },
219
219
  });
220
220
  if (count)
221
221
  currentFiles++;
@@ -108,11 +108,11 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
108
108
  else if (paths.length) {
109
109
  const path = (0, posix_1.normalize)(paths[0]);
110
110
  await data.onProgress({
111
- step: {
111
+ relative: {
112
112
  description: "Copying file",
113
- item: path,
113
+ payload: path,
114
114
  },
115
- stats: {
115
+ absolute: {
116
116
  current,
117
117
  percent: (0, math_util_1.progressPercent)(total, current),
118
118
  total,
@@ -9,7 +9,9 @@ export declare class MysqlDumpTask extends SqlDumpTaskAbstract<MysqlDumpTaskConf
9
9
  onCreateDatabase(database: TargetDatabaseType): Promise<void>;
10
10
  onExecQuery(query: string): Promise<import("../util/process-util").ExecResultType>;
11
11
  onFetchTableNames(database: string): Promise<string[]>;
12
- onExportTables(tableNames: string[], output: string): Promise<void>;
12
+ onExportTables(tableNames: string[], output: string, onProgress: (progress: {
13
+ totalBytes: number;
14
+ }) => void): Promise<void>;
13
15
  onExportStoredPrograms(output: string): Promise<void>;
14
16
  onImport(path: string, database: string): Promise<void>;
15
17
  }
@@ -70,7 +70,7 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
70
70
  table_name
71
71
  `);
72
72
  }
73
- async onExportTables(tableNames, output) {
73
+ async onExportTables(tableNames, output, onProgress) {
74
74
  const stream = (0, fs_1.createWriteStream)(output);
75
75
  await Promise.all([
76
76
  new Promise((resolve, reject) => {
@@ -83,7 +83,10 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
83
83
  "--skip-add-drop-table=false",
84
84
  ...tableNames,
85
85
  ], null, {
86
- pipe: { stream: stream },
86
+ pipe: {
87
+ stream,
88
+ onWriteProgress: onProgress,
89
+ },
87
90
  log: {
88
91
  exec: this.verbose,
89
92
  stderr: this.verbose,
@@ -9,7 +9,9 @@ export declare class PostgresqlDumpTask extends SqlDumpTaskAbstract<PostgresqlDu
9
9
  onCreateDatabase(database: TargetDatabaseType): Promise<void>;
10
10
  onExecQuery(query: string): Promise<import("../util/process-util").ExecResultType>;
11
11
  onFetchTableNames(database: string): Promise<string[]>;
12
- onExportTables(tableNames: string[], output: string): Promise<void>;
12
+ onExportTables(tableNames: string[], output: string, onProgress: (progress: {
13
+ totalBytes: number;
14
+ }) => void): Promise<void>;
13
15
  onExportStoredPrograms(): Promise<void>;
14
16
  onImport(path: string, database: string): Promise<void>;
15
17
  }
@@ -73,7 +73,7 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
73
73
  CONCAT(table_schema, '.', table_name)
74
74
  `);
75
75
  }
76
- async onExportTables(tableNames, output) {
76
+ async onExportTables(tableNames, output, onProgress) {
77
77
  const stream = (0, fs_1.createWriteStream)(output);
78
78
  await Promise.all([
79
79
  new Promise((resolve, reject) => {
@@ -84,7 +84,7 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
84
84
  ...(await this.buildConnectionArgs()),
85
85
  ...(tableNames?.flatMap((v) => ["-t", v]) ?? []),
86
86
  ], null, {
87
- pipe: { stream: stream },
87
+ pipe: { stream, onWriteProgress: onProgress },
88
88
  stderr: {
89
89
  toExitCode: true,
90
90
  },
@@ -29,7 +29,9 @@ export declare abstract class SqlDumpTaskAbstract<TConfig extends SqlDumpTaskCon
29
29
  abstract onDatabaseIsEmpty(databaseName: string): Promise<boolean>;
30
30
  abstract onFetchTableNames(database: string): Promise<string[]>;
31
31
  abstract onExecQuery(query: string): ReturnType<typeof exec>;
32
- abstract onExportTables(tableNames: string[], output: string): Promise<void>;
32
+ abstract onExportTables(tableNames: string[], output: string, onProgress: (data: {
33
+ totalBytes: number;
34
+ }) => void): Promise<void>;
33
35
  abstract onExportStoredPrograms(output: string): Promise<void>;
34
36
  abstract onImport(path: string, database: string): Promise<void>;
35
37
  onBackup(data: BackupDataType): Promise<void>;
@@ -119,35 +119,57 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
119
119
  if (!this.config.oneFileByTable) {
120
120
  const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ database: this.config.database }));
121
121
  data.onProgress({
122
- step: {
122
+ relative: {
123
123
  description: "Exporting",
124
124
  },
125
125
  });
126
- await this.onExportTables(tableNames, outPath);
126
+ await this.onExportTables(tableNames, outPath, async (progress) => {
127
+ await data.onProgress({
128
+ absolute: {
129
+ description: "Exporting in single file",
130
+ current: progress.totalBytes,
131
+ format: "size",
132
+ },
133
+ });
134
+ });
127
135
  }
128
136
  else {
129
137
  let current = 0;
130
138
  for (const tableName of tableNames) {
131
- data.onProgress({
132
- step: {
139
+ await data.onProgress({
140
+ relative: {
133
141
  description: "Exporting",
134
- item: tableName,
142
+ payload: tableName,
135
143
  },
136
- stats: {
144
+ absolute: {
137
145
  total: tableNames.length,
138
146
  current: current,
139
147
  percent: (0, math_util_1.progressPercent)(tableNames.length, current),
140
148
  },
141
149
  });
142
150
  const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ table: tableName }));
143
- await this.onExportTables([tableName], outPath);
151
+ await this.onExportTables([tableName], outPath, async (progress) => {
152
+ await data.onProgress({
153
+ relative: {
154
+ description: "Exporting",
155
+ payload: tableName,
156
+ current: progress.totalBytes,
157
+ format: "size",
158
+ },
159
+ absolute: {
160
+ total: tableNames.length,
161
+ current: current,
162
+ percent: (0, math_util_1.progressPercent)(tableNames.length, current),
163
+ },
164
+ });
165
+ });
144
166
  current++;
145
167
  }
146
168
  }
147
169
  if (this.config.storedPrograms) {
148
170
  const outPath = (0, path_1.join)(outputPath, "stored-programs.sql");
149
171
  data.onProgress({
150
- step: {
172
+ relative: {
151
173
  description: "Exporting storaged programs",
152
174
  },
153
175
  });
@@ -199,11 +221,11 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
199
221
  for (const item of items) {
200
222
  const path = (0, path_1.join)(restorePath, item.fileName);
201
223
  data.onProgress({
202
- step: {
224
+ relative: {
203
225
  description: "Importing",
204
- item: item.fileName,
226
+ payload: item.fileName,
205
227
  },
206
- stats: {
228
+ absolute: {
207
229
  total: items.length,
208
230
  current: current,
209
231
  percent: (0, math_util_1.progressPercent)(items.length, current),
@@ -2,27 +2,16 @@ import { BackupActionOptionsType } from "../Action/BackupAction";
2
2
  import { RestoreActionOptionsType } from "../Action/RestoreAction";
3
3
  import { PackageConfigType } from "../Config/PackageConfig";
4
4
  import { SnapshotType } from "../Repository/RepositoryAbstract";
5
- export declare type ProgressDataType = {
6
- stats?: {
7
- total?: number;
8
- current?: number;
9
- percent?: number;
10
- };
11
- step?: {
12
- description?: string;
13
- item?: string;
14
- percent?: number;
15
- };
16
- };
5
+ import { Progress } from "../util/progress";
17
6
  export declare type BackupDataType = {
18
- onProgress: (data: ProgressDataType) => Promise<void>;
7
+ onProgress: (data: Progress) => Promise<void>;
19
8
  options: BackupActionOptionsType;
20
9
  package: PackageConfigType;
21
10
  targetPath: string | undefined;
22
11
  snapshot: SnapshotType;
23
12
  };
24
13
  export declare type RestoreDataType = {
25
- onProgress: (data: ProgressDataType) => Promise<void>;
14
+ onProgress: (data: Progress) => Promise<void>;
26
15
  options: RestoreActionOptionsType;
27
16
  package: PackageConfigType;
28
17
  targetPath: string | undefined;