@datatruck/cli 0.16.0 → 0.16.2

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 (69) hide show
  1. package/Action/BackupAction.d.ts +21 -5
  2. package/Action/BackupAction.js +64 -37
  3. package/Action/BackupSessionsAction.d.ts +1 -1
  4. package/Action/CleanCacheAction.d.ts +1 -1
  5. package/Action/ConfigAction.d.ts +1 -1
  6. package/Action/InitAction.d.ts +1 -1
  7. package/Action/PruneAction.d.ts +2 -2
  8. package/Action/RestoreAction.d.ts +12 -6
  9. package/Action/RestoreAction.js +26 -12
  10. package/Action/RestoreSessionsAction.d.ts +1 -1
  11. package/Action/SnapshotsAction.d.ts +3 -3
  12. package/Command/BackupCommand.d.ts +1 -1
  13. package/Command/BackupSessionsCommand.d.ts +1 -1
  14. package/Command/CleanCacheCommand.d.ts +1 -1
  15. package/Command/CommandAbstract.d.ts +2 -2
  16. package/Command/ConfigCommand.d.ts +2 -2
  17. package/Command/InitCommand.d.ts +2 -2
  18. package/Command/PruneCommand.d.ts +1 -1
  19. package/Command/RestoreCommand.d.ts +1 -1
  20. package/Command/RestoreSessionsCommand.d.ts +1 -1
  21. package/Command/SnapshotsCommand.d.ts +2 -2
  22. package/Config/Config.d.ts +1 -1
  23. package/Config/PackageConfig.d.ts +2 -2
  24. package/Config/PackageRepositoryConfig.d.ts +1 -1
  25. package/Config/PrunePolicyConfig.d.ts +1 -1
  26. package/Config/RepositoryConfig.d.ts +3 -3
  27. package/Config/TaskConfig.d.ts +1 -1
  28. package/Decorator/EntityDecorator.d.ts +1 -1
  29. package/Factory/CommandFactory.d.ts +2 -2
  30. package/Repository/DatatruckRepository.d.ts +4 -4
  31. package/Repository/DatatruckRepository.js +21 -18
  32. package/Repository/GitRepository.d.ts +2 -2
  33. package/Repository/GitRepository.js +3 -3
  34. package/Repository/RepositoryAbstract.d.ts +11 -9
  35. package/Repository/RepositoryAbstract.js +7 -0
  36. package/Repository/ResticRepository.d.ts +2 -2
  37. package/Repository/ResticRepository.js +3 -1
  38. package/SessionDriver/ConsoleSessionDriver.d.ts +3 -3
  39. package/SessionDriver/SessionDriverAbstract.d.ts +4 -4
  40. package/SessionManager/SessionManagerAbstract.d.ts +1 -1
  41. package/Task/GitTask.d.ts +1 -1
  42. package/Task/GitTask.js +2 -2
  43. package/Task/MariadbTask.d.ts +1 -1
  44. package/Task/MariadbTask.js +1 -1
  45. package/Task/MssqlTask.d.ts +1 -1
  46. package/Task/MysqlDumpTask.d.ts +1 -1
  47. package/Task/PostgresqlDumpTask.d.ts +1 -1
  48. package/Task/ScriptTask.d.ts +5 -5
  49. package/Task/ScriptTask.js +6 -6
  50. package/Task/SqlDumpTaskAbstract.d.ts +2 -2
  51. package/Task/SqlDumpTaskAbstract.js +2 -2
  52. package/Task/TaskAbstract.d.ts +4 -2
  53. package/Task/TaskAbstract.js +7 -0
  54. package/package.json +8 -8
  55. package/util/DataFormat.d.ts +1 -1
  56. package/util/ObjectVault.d.ts +1 -1
  57. package/util/ResticUtil.d.ts +3 -2
  58. package/util/ResticUtil.js +12 -10
  59. package/util/cli-util.d.ts +1 -1
  60. package/util/datatruck/config-util.d.ts +9 -9
  61. package/util/date-util.d.ts +1 -1
  62. package/util/fs-util.d.ts +4 -1
  63. package/util/fs-util.js +21 -3
  64. package/util/object-util.d.ts +1 -1
  65. package/util/process-util.d.ts +3 -3
  66. package/util/progress.d.ts +2 -2
  67. package/util/string-util.d.ts +1 -1
  68. package/util/zip-util.d.ts +3 -3
  69. package/util/zip-util.js +18 -16
@@ -1,9 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TaskAbstract = void 0;
4
+ const fs_util_1 = require("../util/fs-util");
4
5
  class TaskAbstract {
5
6
  constructor(config) {
6
7
  this.config = config;
8
+ this.tmpDirs = [];
9
+ }
10
+ async mkTmpDir(prefix, id) {
11
+ const dir = await (0, fs_util_1.mkTmpDir)(prefix, id);
12
+ this.tmpDirs.push(dir);
13
+ return dir;
7
14
  }
8
15
  async onBeforeBackup(data) {
9
16
  return undefined;
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@datatruck/cli",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "dependencies": {
5
- "ajv": "^8.11.0",
5
+ "ajv": "^8.11.2",
6
6
  "async": "^3.2.4",
7
7
  "chalk": "^4.1.2",
8
- "cli-table3": "^0.6.2",
9
- "commander": "^9.4.0",
10
- "dayjs": "^1.11.5",
8
+ "cli-table3": "^0.6.3",
9
+ "commander": "^9.4.1",
10
+ "dayjs": "^1.11.6",
11
11
  "fast-folder-size": "^1.7.1",
12
- "fast-glob": "^3.2.11",
12
+ "fast-glob": "^3.2.12",
13
13
  "micromatch": "^4.0.5",
14
14
  "pretty-bytes": "^5.6.0",
15
15
  "sqlite": "^4.1.2",
16
- "sqlite3": "^5.0.11"
16
+ "sqlite3": "^5.1.2"
17
17
  },
18
18
  "optionalDependencies": {
19
19
  "ts-node": "^10.9.1",
20
- "yaml": "^2.1.1"
20
+ "yaml": "^2.1.3"
21
21
  },
22
22
  "engine": {
23
23
  "node": ">=16.0.0"
@@ -1,4 +1,4 @@
1
- export declare type FormatType = "json" | "pjson" | "table" | "yaml" | "custom" | "tpl";
1
+ export type FormatType = "json" | "pjson" | "table" | "yaml" | "custom" | "tpl";
2
2
  export declare class DataFormat<TItem extends Record<string, unknown>> {
3
3
  readonly options: {
4
4
  items: TItem[];
@@ -1,4 +1,4 @@
1
- export declare type KeysType = (string | number)[];
1
+ export type KeysType = (string | number)[];
2
2
  export declare class ObjectVault<TObject> {
3
3
  protected counter: number;
4
4
  protected readonly ids: Record<string, number>;
@@ -1,6 +1,6 @@
1
1
  import { ExecResultType, ExecSettingsInterface } from "./process-util";
2
2
  import { UriType } from "./string-util";
3
- export declare type RepositoryType = {
3
+ export type RepositoryType = {
4
4
  name?: string;
5
5
  env?: Record<string, string>;
6
6
  password?: string | {
@@ -8,7 +8,7 @@ export declare type RepositoryType = {
8
8
  };
9
9
  backend: "local" | "rest" | "sftp" | "s3" | "azure" | "gs" | "rclone";
10
10
  } & Omit<UriType, "password">;
11
- export declare type BackupStreamType = {
11
+ export type BackupStreamType = {
12
12
  message_type: "status";
13
13
  seconds_elapsed?: number;
14
14
  percent_done: number;
@@ -90,6 +90,7 @@ export declare class ResticUtil {
90
90
  parent?: string;
91
91
  allowEmptySnapshot?: boolean;
92
92
  onStream?: (data: BackupStreamType) => void;
93
+ createEmptyDir?: () => Promise<string>;
93
94
  }): Promise<ExecResultType>;
94
95
  copy(options: {
95
96
  id: string;
@@ -148,16 +148,18 @@ class ResticUtil {
148
148
  catch (error) {
149
149
  if (options.allowEmptySnapshot &&
150
150
  error.message.includes("unable to save snapshot: snapshot is empty")) {
151
- const emptyPath = await (0, fs_util_1.mkTmpDir)("empty");
152
- await (0, promises_1.writeFile)(`${emptyPath}/.empty`, "");
153
- return await this.backup({
154
- ...options,
155
- cwd: emptyPath,
156
- allowEmptySnapshot: false,
157
- paths: ["."],
158
- exclude: [],
159
- excludeFile: [],
160
- });
151
+ if (options.createEmptyDir) {
152
+ const emptyPath = await options.createEmptyDir();
153
+ await (0, promises_1.writeFile)(`${emptyPath}/.empty`, "");
154
+ return await this.backup({
155
+ ...options,
156
+ cwd: emptyPath,
157
+ allowEmptySnapshot: false,
158
+ paths: ["."],
159
+ exclude: [],
160
+ excludeFile: [],
161
+ });
162
+ }
161
163
  }
162
164
  throw error;
163
165
  }
@@ -10,7 +10,7 @@ export declare function logVars(data: Record<string, any>): void;
10
10
  export declare function logExec(command: string, argv?: string[], env?: NodeJS.ProcessEnv, logToStderr?: boolean): void;
11
11
  export declare function resultColumn(error: Error | null | string, state?: "started" | "ended"): "❌" | " ? " | "✅";
12
12
  export declare function errorColumn(error: Error | null | string, verbose: number): string;
13
- export declare type OptionsType<T1, T2 extends {
13
+ export type OptionsType<T1, T2 extends {
14
14
  [K in keyof T1]: unknown;
15
15
  }> = {
16
16
  [K in keyof Required<T1>]: {
@@ -10,17 +10,17 @@ export declare function filterPackages(config: ConfigType, options: {
10
10
  repositoryTypes?: string[];
11
11
  sourceAction?: RepositoryConfigEnabledActionType;
12
12
  }): PackageConfigType[];
13
- declare type ResolvePackagePathParamsType = ResolvePackageParamsType & {
13
+ type ResolvePackagePathParamsType = ResolvePackageParamsType & {
14
14
  packageName: string;
15
15
  path: string | undefined;
16
16
  };
17
17
  export declare function resolvePackagePath(value: string, params: ResolvePackagePathParamsType): string;
18
- declare type ResolveDatabaseNameParamsType = ResolvePackageParamsType & {
18
+ type ResolveDatabaseNameParamsType = ResolvePackageParamsType & {
19
19
  packageName: string;
20
20
  database: string | undefined;
21
21
  };
22
22
  export declare function resolveDatabaseName(value: string, params: ResolveDatabaseNameParamsType): string;
23
- declare type ResolvePackageParamsType = {
23
+ type ResolvePackageParamsType = {
24
24
  snapshotId: string;
25
25
  snapshotDate: string;
26
26
  action: "backup" | "restore";
@@ -32,15 +32,15 @@ export declare const pkgPathParams: {
32
32
  };
33
33
  export declare const pkgIncludeParams: {
34
34
  packageName: string;
35
- temp: string;
36
35
  snapshotId: string;
36
+ temp: string;
37
37
  snapshotDate: string;
38
38
  action: string;
39
39
  };
40
40
  export declare const pkgExcludeParams: {
41
41
  packageName: string;
42
- temp: string;
43
42
  snapshotId: string;
43
+ temp: string;
44
44
  snapshotDate: string;
45
45
  action: string;
46
46
  };
@@ -53,30 +53,30 @@ export declare const dbNameParams: {
53
53
  export declare const params: {
54
54
  pkgPath: {
55
55
  packageName: string;
56
- temp: string;
57
56
  snapshotId: string;
57
+ temp: string;
58
58
  snapshotDate: string;
59
59
  action: string;
60
60
  };
61
61
  pkgRestorePath: {
62
62
  packageName: string;
63
63
  path: string;
64
- temp: string;
65
64
  snapshotId: string;
65
+ temp: string;
66
66
  snapshotDate: string;
67
67
  action: string;
68
68
  };
69
69
  pkgInclude: {
70
70
  packageName: string;
71
- temp: string;
72
71
  snapshotId: string;
72
+ temp: string;
73
73
  snapshotDate: string;
74
74
  action: string;
75
75
  };
76
76
  pkgExclude: {
77
77
  packageName: string;
78
- temp: string;
79
78
  snapshotId: string;
79
+ temp: string;
80
80
  snapshotDate: string;
81
81
  action: string;
82
82
  };
@@ -1,4 +1,4 @@
1
- export declare type FilterByLastOptionsType = {
1
+ export type FilterByLastOptionsType = {
2
2
  last?: number;
3
3
  lastMinutely?: number;
4
4
  lastHourly?: number;
package/util/fs-util.d.ts CHANGED
@@ -7,7 +7,7 @@ import { WriteStream } from "fs";
7
7
  import { Interface } from "readline";
8
8
  export declare const isWSLSystem: boolean;
9
9
  export declare function isEmptyDir(path: string): Promise<boolean>;
10
- declare type EntryObject = {
10
+ type EntryObject = {
11
11
  name: string;
12
12
  path: string;
13
13
  dirent: Dirent;
@@ -33,6 +33,8 @@ export declare function findFile(sourcePath: string, baseName: string, extension
33
33
  export declare function existsFile(path: string): Promise<boolean>;
34
34
  export declare function parentTmpDir(): string;
35
35
  export declare function sessionTmpDir(): string;
36
+ export declare function isTmpDir(path: string): boolean;
37
+ export declare function rmTmpDir(input: string | string[]): Promise<void>;
36
38
  export declare function tmpDir(prefix: string, id?: string): string;
37
39
  export declare function fastFolderSizeAsync(path: string): Promise<number>;
38
40
  export declare function mkTmpDir(prefix: string, id?: string): Promise<string>;
@@ -47,6 +49,7 @@ export declare function forEachFile(dirPath: string, cb: (path: string, dir: boo
47
49
  export declare function fastglobToGitIgnore(patterns: string[], baseDir: string): string[];
48
50
  export declare function writeGitIgnoreList(options: {
49
51
  paths: NodeJS.ReadableStream | string[];
52
+ outDir: string;
50
53
  }): Promise<string>;
51
54
  export declare function waitForClose(stream: WriteStream): Promise<WriteStream>;
52
55
  export declare function copyFileWithStreams(source: string, target: string): Promise<unknown>;
package/util/fs-util.js CHANGED
@@ -3,7 +3,7 @@ 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.cpy = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.waitForClose = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.checkDir = exports.checkFile = exports.readPartialFile = exports.mkTmpDir = exports.fastFolderSizeAsync = exports.tmpDir = exports.sessionTmpDir = exports.parentTmpDir = exports.existsFile = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.parseFileExtensions = exports.readdirIfExists = exports.writeJSONFile = exports.existsDir = exports.ensureEmptyDir = exports.mkdirIfNotExists = exports.isDirEmpty = exports.isLocalDir = exports.pathIterator = exports.applyPermissions = exports.isEmptyDir = exports.isWSLSystem = void 0;
6
+ exports.cpy = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.waitForClose = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.checkDir = exports.checkFile = exports.readPartialFile = exports.mkTmpDir = exports.fastFolderSizeAsync = exports.tmpDir = exports.rmTmpDir = exports.isTmpDir = exports.sessionTmpDir = exports.parentTmpDir = exports.existsFile = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.parseFileExtensions = exports.readdirIfExists = exports.writeJSONFile = exports.existsDir = exports.ensureEmptyDir = exports.mkdirIfNotExists = exports.isDirEmpty = exports.isLocalDir = exports.pathIterator = exports.applyPermissions = exports.isEmptyDir = exports.isWSLSystem = void 0;
7
7
  const globalData_1 = __importDefault(require("../globalData"));
8
8
  const path_util_1 = require("./path-util");
9
9
  const async_1 = require("async");
@@ -160,6 +160,24 @@ function sessionTmpDir() {
160
160
  return (0, path_1.join)(parentTmpDir(), process.pid.toString());
161
161
  }
162
162
  exports.sessionTmpDir = sessionTmpDir;
163
+ function isTmpDir(path) {
164
+ return path.startsWith(sessionTmpDir()) && path.includes("datatruck-temp");
165
+ }
166
+ exports.isTmpDir = isTmpDir;
167
+ async function rmTmpDir(input) {
168
+ if (typeof input === "string") {
169
+ if (!isTmpDir(input))
170
+ throw new Error(`Path is not a temp dir: ${input}`);
171
+ await (0, promises_1.rm)(input, {
172
+ recursive: true,
173
+ });
174
+ }
175
+ else {
176
+ for (const path of input)
177
+ await rmTmpDir(path);
178
+ }
179
+ }
180
+ exports.rmTmpDir = rmTmpDir;
163
181
  function tmpDir(prefix, id) {
164
182
  if (!id)
165
183
  id = (0, crypto_1.randomUUID)().slice(0, 8);
@@ -265,8 +283,8 @@ function fastglobToGitIgnore(patterns, baseDir) {
265
283
  }
266
284
  exports.fastglobToGitIgnore = fastglobToGitIgnore;
267
285
  async function writeGitIgnoreList(options) {
268
- const tempDir = await mkTmpDir("gitignore-list");
269
- const path = (0, path_1.join)(tempDir, `.gitignore`);
286
+ const { outDir } = options;
287
+ const path = (0, path_1.join)(outDir, `.gitignore`);
270
288
  const stream = (0, fs_2.createWriteStream)(path);
271
289
  const dirs = new Set();
272
290
  stream.write("*\n");
@@ -1,7 +1,7 @@
1
1
  export declare function merge<T extends Record<string, unknown>>(target: T, ...sources: Record<string, unknown>[]): T;
2
2
  export declare function push<T>(map: Record<string, T[]>, key: string, object: T): void;
3
3
  export declare function getErrorProperties(error: Error): Record<string, string>;
4
- declare type GroupByKeyParamType<TItem> = ((item: TItem) => string[] | string) | (keyof TItem)[] | keyof TItem;
4
+ type GroupByKeyParamType<TItem> = ((item: TItem) => string[] | string) | (keyof TItem)[] | keyof TItem;
5
5
  export declare function groupBy<TItem>(items: TItem[], keyOrCb: GroupByKeyParamType<TItem>): Record<string, TItem[]>;
6
6
  export declare function groupBy<TItem>(items: TItem[], keyOrCb: GroupByKeyParamType<TItem>, single: true): Record<string, TItem>;
7
7
  export {};
@@ -2,7 +2,7 @@
2
2
  /// <reference types="node" />
3
3
  import { SpawnOptions, ChildProcess } from "child_process";
4
4
  import { ReadStream, WriteStream } from "fs";
5
- export declare type ExecLogSettingsType = {
5
+ export type ExecLogSettingsType = {
6
6
  colorize?: boolean;
7
7
  exec?: boolean;
8
8
  stdout?: boolean;
@@ -44,12 +44,12 @@ export declare function logExecStdout(input: {
44
44
  lineSalt?: boolean;
45
45
  }): void;
46
46
  export declare function logExecStderr(data: string, colorize?: boolean): void;
47
- export declare type ExecResultType = {
47
+ export type ExecResultType = {
48
48
  stdout: string;
49
49
  stderr: string;
50
50
  exitCode: number;
51
51
  };
52
52
  export declare function exec(command: string, argv?: string[], options?: SpawnOptions | null, settings?: ExecSettingsInterface): Promise<ExecResultType>;
53
- declare type EventNameType = "exit" | "SIGINT" | "SIGUSR1" | "SIGUSR2" | "SIGTERM" | "uncaughtException";
53
+ type EventNameType = "exit" | "SIGINT" | "SIGUSR1" | "SIGUSR2" | "SIGTERM" | "uncaughtException";
54
54
  export declare function onExit(cb: (eventName: EventNameType, ...args: any[]) => void): void;
55
55
  export {};
@@ -1,4 +1,4 @@
1
- export declare type ProgressStats = {
1
+ export type ProgressStats = {
2
2
  percent?: number;
3
3
  total?: number;
4
4
  current?: number;
@@ -6,7 +6,7 @@ export declare type ProgressStats = {
6
6
  payload?: string;
7
7
  format?: "amount" | "size";
8
8
  };
9
- export declare type Progress = {
9
+ export type Progress = {
10
10
  absolute?: ProgressStats;
11
11
  relative?: ProgressStats;
12
12
  };
@@ -4,7 +4,7 @@ export declare function lcfirst(value: string): string;
4
4
  export declare function snakeCase(value: string, char?: string): string;
5
5
  export declare function render(subject: string, vars: Record<string, string | undefined>): string;
6
6
  export declare function parseStringList(value: string, validValues?: string[]): string[];
7
- export declare type UriType = {
7
+ export type UriType = {
8
8
  protocol?: "http" | "https";
9
9
  host?: string;
10
10
  username?: string;
@@ -37,7 +37,7 @@ export interface UnzipDataType {
37
37
  }
38
38
  export declare function buildArguments(filters: (ZipDataFilterType | string)[]): string[];
39
39
  export declare function checkSSEOption(command?: string): Promise<boolean>;
40
- declare type ListZipStream = {
40
+ type ListZipStream = {
41
41
  Path?: string;
42
42
  Folder?: string;
43
43
  Size?: string;
@@ -62,7 +62,7 @@ export declare function listZip(data: {
62
62
  onStream: (item: ListZipStream) => Promise<void>;
63
63
  verbose?: boolean;
64
64
  }): Promise<void>;
65
- export declare type ZipStream = {
65
+ export type ZipStream = {
66
66
  type: "progress";
67
67
  data: {
68
68
  progress: number;
@@ -80,7 +80,7 @@ export declare function zip(data: ZipDataType): Promise<{
80
80
  folders: number;
81
81
  files: number;
82
82
  }>;
83
- export declare type UnzipStream = {
83
+ export type UnzipStream = {
84
84
  type: "progress";
85
85
  data: {
86
86
  percent: number;
package/util/zip-util.js CHANGED
@@ -173,9 +173,9 @@ async function zip(data) {
173
173
  exports.zip = zip;
174
174
  function parseUnzipLine(line) {
175
175
  let matches = null;
176
- if ((matches = /^\s*(\d+)% (\d+) \-/.exec(line))) {
177
- const progress = Number(matches[1]);
178
- const files = Number(matches[2]);
176
+ if ((matches = /^\s*(?<percent>\d+)%(?: (?<files>\d+))? \-/.exec(line))) {
177
+ const progress = Number(matches.groups["percent"]);
178
+ const files = matches.groups["files"] ? Number(matches[2]) : 1;
179
179
  const path = line.slice(line.indexOf("-") + 1).trim();
180
180
  return {
181
181
  type: "progress",
@@ -204,20 +204,22 @@ async function unzip(data) {
204
204
  stderr: { toExitCode: true },
205
205
  stdout: {
206
206
  ...((data.onStream || data.onProgress) && {
207
- parseLines: true,
208
- onData: async (line) => {
209
- const stream = parseUnzipLine(line);
210
- if (stream) {
211
- if (stream.type === "progress") {
212
- const current = Math.max(0, stream.data.files - 1);
213
- summary.files = stream.data.files;
214
- await data.onProgress?.({
215
- current,
216
- percent: stream.data.percent,
217
- path: stream.data.path,
218
- });
207
+ onData: async (chunk) => {
208
+ const lines = chunk.replaceAll("\b", "").split(/\r?\n/);
209
+ for (const line of lines) {
210
+ const stream = parseUnzipLine(line);
211
+ if (stream) {
212
+ if (stream.type === "progress") {
213
+ const current = Math.max(0, stream.data.files - 1);
214
+ summary.files = stream.data.files;
215
+ await data.onProgress?.({
216
+ current,
217
+ percent: stream.data.percent,
218
+ path: stream.data.path,
219
+ });
220
+ }
221
+ await data.onStream?.(stream);
219
222
  }
220
- await data.onStream?.(stream);
221
223
  }
222
224
  },
223
225
  }),