@datatruck/cli 0.40.3 → 0.41.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.
- package/config.schema.json +6 -3
- package/lib/cli.js +5 -4
- package/lib/repositories/DatatruckRepository.d.ts +1 -0
- package/lib/repositories/DatatruckRepository.js +8 -8
- package/lib/utils/datatruck/client.d.ts +7 -1
- package/lib/utils/datatruck/client.js +47 -4
- package/lib/utils/datatruck/config.js +1 -1
- package/lib/utils/datatruck/cron-server.js +1 -1
- package/lib/utils/datatruck/job.js +1 -1
- package/lib/utils/fs.d.ts +1 -1
- package/lib/utils/fs.js +1 -1
- package/lib/utils/http.js +1 -1
- package/lib/utils/mongodb.js +1 -1
- package/lib/utils/mysql.js +2 -0
- package/lib/utils/options.js +3 -1
- package/lib/utils/progress.js +1 -1
- package/lib/utils/tar.js +2 -2
- package/lib/utils/virtual-fs.d.ts +1 -0
- package/package.json +12 -12
package/config.schema.json
CHANGED
|
@@ -1113,6 +1113,9 @@
|
|
|
1113
1113
|
"type": "boolean"
|
|
1114
1114
|
}
|
|
1115
1115
|
]
|
|
1116
|
+
},
|
|
1117
|
+
"insecureTls": {
|
|
1118
|
+
"type": "boolean"
|
|
1116
1119
|
}
|
|
1117
1120
|
},
|
|
1118
1121
|
"additionalProperties": false,
|
|
@@ -1249,15 +1252,15 @@
|
|
|
1249
1252
|
"path": {
|
|
1250
1253
|
"type": "string"
|
|
1251
1254
|
},
|
|
1252
|
-
"username": {
|
|
1253
|
-
"type": "string"
|
|
1254
|
-
},
|
|
1255
1255
|
"host": {
|
|
1256
1256
|
"type": "string"
|
|
1257
1257
|
},
|
|
1258
1258
|
"port": {
|
|
1259
1259
|
"type": "number"
|
|
1260
1260
|
},
|
|
1261
|
+
"username": {
|
|
1262
|
+
"type": "string"
|
|
1263
|
+
},
|
|
1261
1264
|
"protocol": {
|
|
1262
1265
|
"enum": [
|
|
1263
1266
|
"http",
|
package/lib/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
17
17
|
const commander_1 = require("commander");
|
|
18
18
|
const fs_2 = require("fs");
|
|
19
19
|
const path_1 = require("path");
|
|
20
|
+
const util_1 = require("util");
|
|
20
21
|
function getGlobalOptions() {
|
|
21
22
|
const result = program.opts();
|
|
22
23
|
const parseBool = (v) => v === "true" ? true : v === "false" ? false : v;
|
|
@@ -49,21 +50,21 @@ function createCommandAction(Constructor) {
|
|
|
49
50
|
if (errors?.length) {
|
|
50
51
|
console.error();
|
|
51
52
|
errors.forEach((error, index) => {
|
|
52
|
-
console.error(chalk_1.default.red(`${index + 1}. ` + (
|
|
53
|
+
console.error(chalk_1.default.red(`${index + 1}. ` + (0, util_1.format)(error)));
|
|
53
54
|
if (errors[index + 1])
|
|
54
55
|
console.error();
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
if (error) {
|
|
58
59
|
if (globalOptions.verbose) {
|
|
59
|
-
console.error(chalk_1.default.red(
|
|
60
|
+
console.error(chalk_1.default.red((0, util_1.format)(error)));
|
|
60
61
|
}
|
|
61
62
|
else {
|
|
62
63
|
if (error instanceof error_1.AppError) {
|
|
63
64
|
console.error(chalk_1.default.red(error.message));
|
|
64
65
|
}
|
|
65
66
|
else {
|
|
66
|
-
console.error(chalk_1.default.red(
|
|
67
|
+
console.error(chalk_1.default.red((0, util_1.format)(error)));
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
}
|
|
@@ -97,7 +98,7 @@ function parseArgs(args) {
|
|
|
97
98
|
process.stdout.write(cli_1.showCursorCommand);
|
|
98
99
|
console.info(`\nClosing... (reason: ${eventName})`);
|
|
99
100
|
if (error instanceof Error)
|
|
100
|
-
console.error(
|
|
101
|
+
console.error((0, util_1.format)(error));
|
|
101
102
|
}
|
|
102
103
|
if (!verbose)
|
|
103
104
|
try {
|
|
@@ -46,15 +46,15 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
46
46
|
return this.config.backend;
|
|
47
47
|
}
|
|
48
48
|
fetchDiskStats(config) {
|
|
49
|
-
const fs = (0, client_1.createFs)(config
|
|
49
|
+
const fs = (0, client_1.createFs)(config, this.verbose);
|
|
50
50
|
return fs.fetchDiskStats(".");
|
|
51
51
|
}
|
|
52
52
|
async init(data) {
|
|
53
|
-
const fs = (0, client_1.createFs)(this.config
|
|
53
|
+
const fs = (0, client_1.createFs)(this.config, this.verbose);
|
|
54
54
|
await fs.mkdir(".");
|
|
55
55
|
}
|
|
56
56
|
async prune(data) {
|
|
57
|
-
const fs = (0, client_1.createFs)(this.config
|
|
57
|
+
const fs = (0, client_1.createFs)(this.config, this.verbose);
|
|
58
58
|
const snapshotName = DatatruckRepository.createSnapshotName(data.snapshot, {
|
|
59
59
|
name: data.snapshot.packageName,
|
|
60
60
|
});
|
|
@@ -64,7 +64,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
64
64
|
await fs.rmAll(snapshotName);
|
|
65
65
|
}
|
|
66
66
|
async fetchSnapshots(data) {
|
|
67
|
-
const fs = (0, client_1.createFs)(this.config
|
|
67
|
+
const fs = (0, client_1.createFs)(this.config, this.verbose);
|
|
68
68
|
if (!(await fs.existsDir(".")))
|
|
69
69
|
throw new error_1.AppError(`Repository (${this.repository.name}) out path does not exist: ${fs.resolvePath(".")}`);
|
|
70
70
|
const snapshots = [];
|
|
@@ -110,7 +110,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
110
110
|
return snapshots;
|
|
111
111
|
}
|
|
112
112
|
async backup(data) {
|
|
113
|
-
const fs = (0, client_1.createFs)(this.config
|
|
113
|
+
const fs = (0, client_1.createFs)(this.config, this.verbose);
|
|
114
114
|
const snapshotName = DatatruckRepository.createSnapshotName(data.snapshot, data.package);
|
|
115
115
|
const outPath = fs.isLocal()
|
|
116
116
|
? fs.resolvePath(snapshotName)
|
|
@@ -231,8 +231,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
231
231
|
};
|
|
232
232
|
}
|
|
233
233
|
async copy(data) {
|
|
234
|
-
const sourceFs = (0, client_1.createFs)(this.config
|
|
235
|
-
const targetFs = (0, client_1.createFs)(data.mirrorRepositoryConfig
|
|
234
|
+
const sourceFs = (0, client_1.createFs)(this.config, this.verbose);
|
|
235
|
+
const targetFs = (0, client_1.createFs)(data.mirrorRepositoryConfig, this.verbose);
|
|
236
236
|
const snapshotName = DatatruckRepository.createSnapshotName(data.snapshot, data.package);
|
|
237
237
|
if (data.options.verbose)
|
|
238
238
|
(0, cli_1.logExec)(`Copying backup files to ${data.mirrorRepositoryConfig.backend}`);
|
|
@@ -302,7 +302,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
302
302
|
return { bytes };
|
|
303
303
|
}
|
|
304
304
|
async restore(data) {
|
|
305
|
-
const fs = (0, client_1.createFs)(this.config
|
|
305
|
+
const fs = (0, client_1.createFs)(this.config, this.verbose);
|
|
306
306
|
const relRestorePath = data.snapshotPath;
|
|
307
307
|
(0, assert_1.ok)(relRestorePath);
|
|
308
308
|
const restorePath = (0, path_1.resolve)(relRestorePath);
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { DiskStats } from "../fs";
|
|
2
2
|
import { BasicProgress } from "../progress";
|
|
3
3
|
import { AbstractFs, FsOptions } from "../virtual-fs";
|
|
4
|
+
import { Agent } from "undici";
|
|
4
5
|
export declare class RemoteFs extends AbstractFs {
|
|
5
6
|
readonly options: FsOptions & {
|
|
6
7
|
verbose?: boolean;
|
|
7
8
|
};
|
|
8
9
|
protected url: string;
|
|
9
10
|
protected headers: Record<string, string>;
|
|
11
|
+
protected agent: Agent | undefined;
|
|
10
12
|
constructor(options: FsOptions & {
|
|
11
13
|
verbose?: boolean;
|
|
12
14
|
});
|
|
13
15
|
isLocal(): boolean;
|
|
16
|
+
private getCurlArgs;
|
|
14
17
|
protected fetchJson(name: string, params: any[]): Promise<any>;
|
|
15
18
|
protected post(name: string, params: any[], data: string): Promise<import("undici").Response>;
|
|
16
19
|
existsDir(path: string): Promise<boolean>;
|
|
@@ -32,4 +35,7 @@ export declare class RemoteFs extends AbstractFs {
|
|
|
32
35
|
}>;
|
|
33
36
|
}
|
|
34
37
|
export declare function isRemoteBackend(backend: string): boolean;
|
|
35
|
-
export declare function createFs(
|
|
38
|
+
export declare function createFs(options: {
|
|
39
|
+
backend: string;
|
|
40
|
+
insecureTls?: boolean;
|
|
41
|
+
}, verbose: boolean | undefined): AbstractFs;
|
|
@@ -7,10 +7,12 @@ const cli_1 = require("../cli");
|
|
|
7
7
|
const http_1 = require("../http");
|
|
8
8
|
const virtual_fs_1 = require("../virtual-fs");
|
|
9
9
|
const repository_server_1 = require("./repository-server");
|
|
10
|
+
const undici_1 = require("undici");
|
|
10
11
|
class RemoteFs extends virtual_fs_1.AbstractFs {
|
|
11
12
|
options;
|
|
12
13
|
url;
|
|
13
14
|
headers;
|
|
15
|
+
agent;
|
|
14
16
|
constructor(options) {
|
|
15
17
|
super(options);
|
|
16
18
|
this.options = options;
|
|
@@ -24,24 +26,50 @@ class RemoteFs extends virtual_fs_1.AbstractFs {
|
|
|
24
26
|
this.url = url.href;
|
|
25
27
|
if (this.url.endsWith("/"))
|
|
26
28
|
this.url = this.url.slice(0, -1);
|
|
29
|
+
if (options.insecureTls)
|
|
30
|
+
this.agent = new undici_1.Agent({
|
|
31
|
+
connect: {
|
|
32
|
+
rejectUnauthorized: false,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
27
35
|
}
|
|
28
36
|
isLocal() {
|
|
29
37
|
return false;
|
|
30
38
|
}
|
|
39
|
+
getCurlArgs(headers = {}) {
|
|
40
|
+
const args = Object.entries({ ...headers, ...this.headers }).flatMap(([k, v]) => ["-H", `"${k}: ${v}"`]);
|
|
41
|
+
if (this.options.insecureTls)
|
|
42
|
+
args.push("-k");
|
|
43
|
+
args.push("-v");
|
|
44
|
+
return args;
|
|
45
|
+
}
|
|
31
46
|
async fetchJson(name, params) {
|
|
32
47
|
const url = (0, http_1.createHref)(`${this.url}/${name}`, {
|
|
33
48
|
params: JSON.stringify(params),
|
|
34
49
|
});
|
|
50
|
+
if (this.options.verbose)
|
|
51
|
+
(0, cli_1.logExec)("curl", [...this.getCurlArgs(), `"${url}"`]);
|
|
35
52
|
return await (0, http_1.fetchJson)(url, {
|
|
36
53
|
headers: this.headers,
|
|
54
|
+
dispatcher: this.agent,
|
|
37
55
|
});
|
|
38
56
|
}
|
|
39
57
|
async post(name, params, data) {
|
|
40
58
|
const url = (0, http_1.createHref)(`${this.url}/${name}`, {
|
|
41
59
|
params: JSON.stringify(params),
|
|
42
60
|
});
|
|
61
|
+
if (this.options.verbose)
|
|
62
|
+
(0, cli_1.logExec)("curl", [
|
|
63
|
+
...this.getCurlArgs({ "Content-Type": "application/json" }),
|
|
64
|
+
"--request",
|
|
65
|
+
"POST",
|
|
66
|
+
"--data",
|
|
67
|
+
`"${data}"`,
|
|
68
|
+
`"${url}"`,
|
|
69
|
+
]);
|
|
43
70
|
return await (0, http_1.post)(url, data, {
|
|
44
71
|
headers: this.headers,
|
|
72
|
+
dispatcher: this.agent,
|
|
45
73
|
});
|
|
46
74
|
}
|
|
47
75
|
async existsDir(path) {
|
|
@@ -82,9 +110,17 @@ class RemoteFs extends virtual_fs_1.AbstractFs {
|
|
|
82
110
|
const url = (0, http_1.createHref)(`${this.url}/upload`, {
|
|
83
111
|
params: JSON.stringify([target]),
|
|
84
112
|
});
|
|
113
|
+
if (this.options.verbose)
|
|
114
|
+
(0, cli_1.logExec)("curl", [
|
|
115
|
+
...this.getCurlArgs(),
|
|
116
|
+
"-F",
|
|
117
|
+
`data=@${source}`,
|
|
118
|
+
`"${url}"`,
|
|
119
|
+
]);
|
|
85
120
|
return await (0, http_1.uploadFile)(url, source, {
|
|
86
121
|
headers: this.headers,
|
|
87
122
|
checksum: true,
|
|
123
|
+
dispatcher: this.agent,
|
|
88
124
|
});
|
|
89
125
|
}
|
|
90
126
|
async download(source, target, options = {}) {
|
|
@@ -93,9 +129,12 @@ class RemoteFs extends virtual_fs_1.AbstractFs {
|
|
|
93
129
|
const url = (0, http_1.createHref)(`${this.url}/download`, {
|
|
94
130
|
params: JSON.stringify([source]),
|
|
95
131
|
});
|
|
132
|
+
if (this.options.verbose)
|
|
133
|
+
(0, cli_1.logExec)("curl", [...this.getCurlArgs(), `"${url}"`, ">", target]);
|
|
96
134
|
return await (0, http_1.downloadFile)(url, target, {
|
|
97
135
|
...options,
|
|
98
136
|
headers: this.headers,
|
|
137
|
+
dispatcher: this.agent,
|
|
99
138
|
});
|
|
100
139
|
}
|
|
101
140
|
}
|
|
@@ -103,8 +142,12 @@ exports.RemoteFs = RemoteFs;
|
|
|
103
142
|
function isRemoteBackend(backend) {
|
|
104
143
|
return backend.startsWith("http:") || backend.startsWith("https:");
|
|
105
144
|
}
|
|
106
|
-
function createFs(
|
|
107
|
-
return isRemoteBackend(backend)
|
|
108
|
-
? new RemoteFs({
|
|
109
|
-
|
|
145
|
+
function createFs(options, verbose) {
|
|
146
|
+
return isRemoteBackend(options.backend)
|
|
147
|
+
? new RemoteFs({
|
|
148
|
+
backend: options.backend,
|
|
149
|
+
insecureTls: options.insecureTls,
|
|
150
|
+
verbose,
|
|
151
|
+
})
|
|
152
|
+
: new virtual_fs_1.LocalFs({ backend: options.backend });
|
|
110
153
|
}
|
|
@@ -75,7 +75,7 @@ function filterRepositoryByEnabled(repository, action) {
|
|
|
75
75
|
if (typeof enabled === "boolean")
|
|
76
76
|
return enabled;
|
|
77
77
|
const defaults = enabled["defaults"] ?? true;
|
|
78
|
-
return action ? enabled[action] ?? defaults : true;
|
|
78
|
+
return action ? (enabled[action] ?? defaults) : true;
|
|
79
79
|
}
|
|
80
80
|
function filterPackages(config, options) {
|
|
81
81
|
const filterRepo = (0, string_1.createPatternFilter)(options.repositoryNames);
|
|
@@ -14,7 +14,7 @@ function createCrons(jobs, options) {
|
|
|
14
14
|
for (const name in jobs) {
|
|
15
15
|
const job = jobs[name];
|
|
16
16
|
if (job.schedule)
|
|
17
|
-
crons.push(
|
|
17
|
+
crons.push(new croner_1.Cron(typeof job.schedule === "string"
|
|
18
18
|
? job.schedule
|
|
19
19
|
: (0, cron_1.formatCronScheduleObject)(job.schedule), {
|
|
20
20
|
paused: true,
|
|
@@ -60,7 +60,7 @@ async function runJob(job, name, config) {
|
|
|
60
60
|
async function runCronJob(job, name, config) {
|
|
61
61
|
let pid = 0;
|
|
62
62
|
try {
|
|
63
|
-
const log = config.log?.enabled ?? true
|
|
63
|
+
const log = (config.log?.enabled ?? true)
|
|
64
64
|
? await createJobLog(config.log, name)
|
|
65
65
|
: undefined;
|
|
66
66
|
const cliOptions = getJobCliOptions(job);
|
package/lib/utils/fs.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export declare function writeGitIgnoreList(options: {
|
|
|
36
36
|
paths: NodeJS.ReadableStream | string[];
|
|
37
37
|
outDir: string;
|
|
38
38
|
}): Promise<string>;
|
|
39
|
-
export declare function copyFileWithStreams(source: string, target: string): Promise<
|
|
39
|
+
export declare function copyFileWithStreams(source: string, target: string): Promise<void>;
|
|
40
40
|
export declare function updateFileStats(path: string, fileInfo: Stats): Promise<void>;
|
|
41
41
|
export declare function isNotFoundError(error: unknown): boolean;
|
|
42
42
|
export declare function readTextFile(path: string): Promise<string>;
|
package/lib/utils/fs.js
CHANGED
|
@@ -279,7 +279,7 @@ async function copyFileWithStreams(source, target) {
|
|
|
279
279
|
const r = (0, fs_1.createReadStream)(source);
|
|
280
280
|
const w = (0, fs_2.createWriteStream)(target);
|
|
281
281
|
try {
|
|
282
|
-
|
|
282
|
+
await new Promise((resolve, reject) => {
|
|
283
283
|
r.on("error", reject);
|
|
284
284
|
w.on("error", reject);
|
|
285
285
|
w.on("finish", resolve);
|
package/lib/utils/http.js
CHANGED
|
@@ -67,7 +67,7 @@ async function sendFile(req, res, path, options = {}) {
|
|
|
67
67
|
try {
|
|
68
68
|
file = (0, fs_1.createReadStream)(path);
|
|
69
69
|
const fileStat = await (0, promises_1.stat)(path);
|
|
70
|
-
res.setHeader(options.contentLength ?? true ? "Content-Length" : "x-content-length", fileStat.size);
|
|
70
|
+
res.setHeader((options.contentLength ?? true) ? "Content-Length" : "x-content-length", fileStat.size);
|
|
71
71
|
if (options.checksum)
|
|
72
72
|
res.setHeader("x-checksum", await (0, crypto_1.calcFileHash)(path, "sha1"));
|
|
73
73
|
file.pipe(res);
|
package/lib/utils/mongodb.js
CHANGED
|
@@ -32,7 +32,7 @@ async function resolveMongoUri(input) {
|
|
|
32
32
|
return {
|
|
33
33
|
...object,
|
|
34
34
|
password: object.password !== undefined
|
|
35
|
-
? (await (0, fs_1.fetchData)(object.password, (p) => p.path)) ?? ""
|
|
35
|
+
? ((await (0, fs_1.fetchData)(object.password, (p) => p.path)) ?? "")
|
|
36
36
|
: "",
|
|
37
37
|
};
|
|
38
38
|
}
|
package/lib/utils/mysql.js
CHANGED
package/lib/utils/options.js
CHANGED
|
@@ -26,7 +26,9 @@ function createCommand(config, action) {
|
|
|
26
26
|
}
|
|
27
27
|
else if (typeof flag === "string") {
|
|
28
28
|
const flags = [
|
|
29
|
-
option.shortFlag
|
|
29
|
+
option.shortFlag
|
|
30
|
+
? `${"-".repeat(option.shortFlag.length > 1 ? 2 : 1)}${option.shortFlag},`
|
|
31
|
+
: "",
|
|
30
32
|
`--${name}`,
|
|
31
33
|
option.value !== "boolean"
|
|
32
34
|
? option.value === "array"
|
package/lib/utils/progress.js
CHANGED
|
@@ -30,7 +30,7 @@ class ProgressManager {
|
|
|
30
30
|
? this.tty
|
|
31
31
|
? `interval:${300}`
|
|
32
32
|
: "interval"
|
|
33
|
-
: options.mode ?? "interval";
|
|
33
|
+
: (options.mode ?? "interval");
|
|
34
34
|
this.intervalMs = 1000;
|
|
35
35
|
if (typeof mode === "string" && mode.startsWith("interval:")) {
|
|
36
36
|
const [, ms] = mode.split(":");
|
package/lib/utils/tar.js
CHANGED
|
@@ -156,8 +156,8 @@ function normalizeTarPath(path) {
|
|
|
156
156
|
}
|
|
157
157
|
async function extractTar(options) {
|
|
158
158
|
let total = options.onEntry
|
|
159
|
-
? options.total ??
|
|
160
|
-
(await listTar({ input: options.input, verbose: options.verbose }))
|
|
159
|
+
? (options.total ??
|
|
160
|
+
(await listTar({ input: options.input, verbose: options.verbose })))
|
|
161
161
|
: undefined;
|
|
162
162
|
if (!(await (0, fs_1.existsDir)(options.output))) {
|
|
163
163
|
if (options.verbose)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datatruck/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"description": "Tool for creating and managing backups",
|
|
5
5
|
"homepage": "https://github.com/swordev/datatruck#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -30,23 +30,23 @@
|
|
|
30
30
|
"ajv": "^8.17.1",
|
|
31
31
|
"async": "^3.2.6",
|
|
32
32
|
"chalk": "^4.1.2",
|
|
33
|
-
"commander": "^
|
|
34
|
-
"croner": "^
|
|
33
|
+
"commander": "^14.0.0",
|
|
34
|
+
"croner": "^9.1.0",
|
|
35
35
|
"dayjs": "^1.11.13",
|
|
36
|
-
"fast-folder-size": "^2.
|
|
37
|
-
"fast-glob": "^3.3.
|
|
38
|
-
"listr2": "^
|
|
36
|
+
"fast-folder-size": "^2.4.0",
|
|
37
|
+
"fast-glob": "^3.3.3",
|
|
38
|
+
"listr2": "^9.0.1",
|
|
39
39
|
"micromatch": "^4.0.8",
|
|
40
|
-
"mongodb": "^6.
|
|
41
|
-
"mysql2": "^3.
|
|
40
|
+
"mongodb": "^6.18.0",
|
|
41
|
+
"mysql2": "^3.14.3",
|
|
42
42
|
"tty-table": "^4.2.3",
|
|
43
|
-
"undici": "^
|
|
44
|
-
"yaml": "^2.
|
|
43
|
+
"undici": "^7.14.0",
|
|
44
|
+
"yaml": "^2.8.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@types/async": "^3.2.
|
|
47
|
+
"@types/async": "^3.2.25",
|
|
48
48
|
"@types/micromatch": "^4.0.9",
|
|
49
|
-
"mongodb-memory-server": "^10.0
|
|
49
|
+
"mongodb-memory-server": "^10.2.0"
|
|
50
50
|
},
|
|
51
51
|
"optionalDependencies": {
|
|
52
52
|
"ts-node": "^10.9.2"
|