@datatruck/cli 0.18.0 → 0.20.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/Action/BackupAction.js +4 -2
- package/Action/BackupSessionsAction.js +2 -0
- package/Action/CleanCacheAction.js +1 -0
- package/Action/ConfigAction.js +1 -0
- package/Action/InitAction.js +2 -0
- package/Action/PruneAction.js +2 -0
- package/Action/RestoreAction.js +5 -3
- package/Action/RestoreSessionsAction.js +2 -0
- package/Action/SnapshotsAction.js +2 -0
- package/Command/CommandAbstract.js +2 -0
- package/Entity/BackupSessionEntity.js +5 -2
- package/Entity/BackupSessionRepositoryEntity.js +5 -2
- package/Entity/BackupSessionTaskEntity.js +4 -2
- package/Entity/CrudEntityAbstract.js +3 -0
- package/Entity/RestoreSessionEntity.js +4 -2
- package/Entity/RestoreSessionRepositoryEntity.js +5 -2
- package/Entity/RestoreSessionTaskEntity.js +4 -2
- package/Entity/StateEntityAbstract.js +5 -0
- package/Factory/CommandFactory.js +1 -1
- package/JsonSchema/DefinitionEnum.js +1 -1
- package/Repository/DatatruckRepository.d.ts +8 -13
- package/Repository/DatatruckRepository.js +122 -231
- package/Repository/GitRepository.js +1 -1
- package/Repository/RepositoryAbstract.js +4 -2
- package/Repository/ResticRepository.js +2 -1
- package/SessionDriver/ConsoleSessionDriver.js +9 -5
- package/SessionDriver/SessionDriverAbstract.js +3 -2
- package/SessionDriver/SqliteSessionDriver.js +2 -4
- package/SessionManager/BackupSessionManager.js +3 -6
- package/SessionManager/RestoreSessionManager.js +3 -6
- package/SessionManager/SessionManagerAbstract.js +4 -0
- package/Task/GitTask.js +3 -2
- package/Task/MariadbTask.js +6 -4
- package/Task/MssqlTask.js +2 -1
- package/Task/ScriptTask.js +1 -0
- package/Task/SqlDumpTaskAbstract.js +2 -1
- package/Task/TaskAbstract.js +2 -1
- package/config.schema.json +23 -37
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +8 -8
- package/utils/DataFormat.js +1 -0
- package/utils/Git.js +2 -1
- package/utils/ObjectVault.js +3 -5
- package/utils/Restic.js +1 -0
- package/utils/datatruck/paths.js +5 -1
- package/utils/fs.d.ts +23 -24
- package/utils/fs.js +108 -96
- package/utils/process.d.ts +1 -1
- package/utils/process.js +17 -8
- package/utils/string.d.ts +0 -2
- package/utils/string.js +1 -9
- package/utils/tar.d.ts +35 -0
- package/utils/tar.js +127 -0
- package/utils/zip.d.ts +0 -97
- package/utils/zip.js +0 -238
package/Task/MssqlTask.js
CHANGED
|
@@ -25,6 +25,8 @@ exports.mssqlTaskDefinition = {
|
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
27
|
class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
28
|
+
static SUFFIX = ".BAK";
|
|
29
|
+
verbose;
|
|
28
30
|
get command() {
|
|
29
31
|
return this.config.command ?? "sqlcmd";
|
|
30
32
|
}
|
|
@@ -106,4 +108,3 @@ class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
exports.MssqlTask = MssqlTask;
|
|
109
|
-
MssqlTask.SUFFIX = ".BAK";
|
package/Task/ScriptTask.js
CHANGED
|
@@ -85,6 +85,7 @@ function parseSqlFile(fileName) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
88
|
+
verbose;
|
|
88
89
|
async fetchPassword() {
|
|
89
90
|
if (typeof this.config.password === "string")
|
|
90
91
|
return this.config.password;
|
|
@@ -114,7 +115,7 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
114
115
|
return true;
|
|
115
116
|
});
|
|
116
117
|
(0, assert_1.ok)(typeof outputPath === "string");
|
|
117
|
-
if (!(await (0, fs_1.
|
|
118
|
+
if (!(await (0, fs_1.existsDir)(outputPath)))
|
|
118
119
|
await (0, promises_1.mkdir)(outputPath, { recursive: true });
|
|
119
120
|
if (!this.config.oneFileByTable) {
|
|
120
121
|
const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ database: this.config.database }));
|
package/Task/TaskAbstract.js
CHANGED
|
@@ -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);
|
package/config.schema.json
CHANGED
|
@@ -458,45 +458,31 @@
|
|
|
458
458
|
"additionalProperties": false,
|
|
459
459
|
"properties": {
|
|
460
460
|
"compress": {
|
|
461
|
-
"
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
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
package/package.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datatruck/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.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": "^
|
|
10
|
-
"dayjs": "^1.11.
|
|
11
|
-
"fast-folder-size": "^
|
|
12
|
-
"fast-glob": "^3.
|
|
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": "^
|
|
16
|
-
"sqlite3": "^5.1.
|
|
15
|
+
"sqlite": "^5.0.1",
|
|
16
|
+
"sqlite3": "^5.1.6"
|
|
17
17
|
},
|
|
18
18
|
"optionalDependencies": {
|
|
19
19
|
"ts-node": "^10.9.1",
|
|
20
|
-
"yaml": "^2.2
|
|
20
|
+
"yaml": "^2.3.2"
|
|
21
21
|
},
|
|
22
22
|
"engine": {
|
|
23
23
|
"node": ">=16.0.0"
|
package/utils/DataFormat.js
CHANGED
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
|
}
|
|
@@ -15,7 +16,7 @@ class Git {
|
|
|
15
16
|
}
|
|
16
17
|
async canBeInit(repo) {
|
|
17
18
|
return ((0, fs_1.isLocalDir)(repo) &&
|
|
18
|
-
(!(await (0, fs_1.
|
|
19
|
+
(!(await (0, fs_1.existsDir)(repo)) || !(await (0, fs_1.readDir)(repo)).length));
|
|
19
20
|
}
|
|
20
21
|
async clone(options) {
|
|
21
22
|
return await this.exec([
|
package/utils/ObjectVault.js
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ObjectVault = void 0;
|
|
4
4
|
class ObjectVault {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
package/utils/datatruck/paths.js
CHANGED
|
@@ -9,7 +9,11 @@ async function parsePaths(values, options) {
|
|
|
9
9
|
paths.push(value);
|
|
10
10
|
}
|
|
11
11
|
else if (value.type === "spawn") {
|
|
12
|
-
const spawnResult = await (0, process_1.exec)(value.command, value.args, { cwd: options.cwd }, {
|
|
12
|
+
const spawnResult = await (0, process_1.exec)(value.command, value.args, { cwd: options.cwd }, {
|
|
13
|
+
log: options.verbose,
|
|
14
|
+
stderr: { save: true },
|
|
15
|
+
stdout: { save: true },
|
|
16
|
+
});
|
|
13
17
|
const spawnFiles = [spawnResult.stderr, spawnResult.stdout].flatMap((text) => text
|
|
14
18
|
.split(/\r?\n/)
|
|
15
19
|
.map((v) => v.trim())
|
package/utils/fs.d.ts
CHANGED
|
@@ -1,29 +1,20 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
/// <reference types="node" />
|
|
4
|
-
/// <reference types="node" />
|
|
5
4
|
import { Progress } from "./progress";
|
|
6
5
|
import { Entry, Options } from "fast-glob";
|
|
7
|
-
import {
|
|
6
|
+
import { ReadStream, Stats } from "fs";
|
|
8
7
|
import { WriteStream } from "fs";
|
|
9
8
|
import { Interface } from "readline";
|
|
10
9
|
export declare const isWSLSystem: boolean;
|
|
11
10
|
export declare function isEmptyDir(path: string): Promise<boolean>;
|
|
12
|
-
type EntryObject = {
|
|
13
|
-
name: string;
|
|
14
|
-
path: string;
|
|
15
|
-
dirent: Dirent;
|
|
16
|
-
stats: Stats;
|
|
17
|
-
};
|
|
18
|
-
export declare function applyPermissions(baseDir: string, permissionsPath: string): Promise<void>;
|
|
19
|
-
export declare function pathIterator(stream: AsyncIterable<string | Buffer>): AsyncIterable<EntryObject>;
|
|
20
11
|
export declare function isLocalDir(path: string): boolean;
|
|
21
|
-
export declare function isDirEmpty(path: string): Promise<boolean>;
|
|
22
12
|
export declare function mkdirIfNotExists(path: string): Promise<string>;
|
|
23
13
|
export declare function ensureEmptyDir(path: string): Promise<void>;
|
|
14
|
+
export declare function safeStat(path: string): Promise<Stats | undefined>;
|
|
24
15
|
export declare function existsDir(path: string): Promise<boolean>;
|
|
16
|
+
export declare function existsFile(path: string): Promise<boolean>;
|
|
25
17
|
export declare function writeJSONFile<T = any>(path: string, json: T): Promise<void>;
|
|
26
|
-
export declare function readdirIfExists(path: string): Promise<string[]>;
|
|
27
18
|
export declare const parseFileExtensions: string[];
|
|
28
19
|
export declare function parseFile(path: string, jsKey?: string): Promise<any>;
|
|
29
20
|
export declare function parsePackageFile(): {
|
|
@@ -32,7 +23,6 @@ export declare function parsePackageFile(): {
|
|
|
32
23
|
description: string;
|
|
33
24
|
};
|
|
34
25
|
export declare function findFile(sourcePath: string, baseName: string, extensions: string[], errorMessage?: string): Promise<string>;
|
|
35
|
-
export declare function existsFile(path: string): Promise<boolean>;
|
|
36
26
|
export declare function parentTmpDir(): string;
|
|
37
27
|
export declare function sessionTmpDir(): string;
|
|
38
28
|
export declare function isTmpDir(path: string): boolean;
|
|
@@ -41,8 +31,6 @@ export declare function tmpDir(prefix: string, id?: string): string;
|
|
|
41
31
|
export declare function fastFolderSizeAsync(path: string): Promise<number>;
|
|
42
32
|
export declare function mkTmpDir(prefix: string, id?: string): Promise<string>;
|
|
43
33
|
export declare function readPartialFile(path: string, positions: [number, number?]): Promise<string>;
|
|
44
|
-
export declare function checkFile(path: string): Promise<boolean>;
|
|
45
|
-
export declare function checkDir(path: string): Promise<boolean>;
|
|
46
34
|
export declare function readDir(path: string, optional?: boolean): Promise<string[]>;
|
|
47
35
|
export declare function forEachFile(dirPath: string, cb: (path: string, dir: boolean) => void, includeDir?: boolean): Promise<void>;
|
|
48
36
|
/**
|
|
@@ -104,18 +92,29 @@ export declare function createFileScanner(options: {
|
|
|
104
92
|
include: string[];
|
|
105
93
|
};
|
|
106
94
|
onProgress: (data: Progress) => Promise<void>;
|
|
107
|
-
disableCounting?: boolean;
|
|
108
|
-
disableEndProgress?: boolean;
|
|
109
95
|
}): Promise<{
|
|
96
|
+
disposed: boolean;
|
|
110
97
|
total: number;
|
|
111
98
|
current: number;
|
|
112
|
-
progress: (description: string,
|
|
113
|
-
|
|
114
|
-
current: number;
|
|
115
|
-
type?: "start" | "end";
|
|
116
|
-
percent?: number;
|
|
117
|
-
}) => Promise<void>;
|
|
118
|
-
updateProgress: (end?: boolean) => Promise<void>;
|
|
99
|
+
progress: (description: string, path?: string) => Promise<void>;
|
|
100
|
+
end: () => Promise<void>;
|
|
119
101
|
start: (cb?: ((entry: Required<Entry>) => any) | undefined) => Promise<void>;
|
|
120
102
|
}>;
|
|
103
|
+
type StreamItem = {
|
|
104
|
+
key: string;
|
|
105
|
+
stream: WriteStream;
|
|
106
|
+
finished: boolean;
|
|
107
|
+
error?: Error;
|
|
108
|
+
written?: boolean;
|
|
109
|
+
};
|
|
110
|
+
export declare function createWriteStreamPool(options: {
|
|
111
|
+
path: string;
|
|
112
|
+
onStreamPath?: (key: string) => string;
|
|
113
|
+
}): {
|
|
114
|
+
pool: Record<string, StreamItem>;
|
|
115
|
+
path(key: string | number): string | undefined;
|
|
116
|
+
writeLine(key: string | number, v: string): boolean;
|
|
117
|
+
end(): Promise<void>;
|
|
118
|
+
};
|
|
119
|
+
export declare function countFileLines(path: string): Promise<number>;
|
|
121
120
|
export {};
|
package/utils/fs.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.createFileScanner = exports.cpy = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.waitForClose = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.
|
|
6
|
+
exports.countFileLines = exports.createWriteStreamPool = exports.createFileScanner = exports.cpy = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.waitForClose = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.readPartialFile = exports.mkTmpDir = exports.fastFolderSizeAsync = exports.tmpDir = exports.rmTmpDir = exports.isTmpDir = exports.sessionTmpDir = exports.parentTmpDir = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.parseFileExtensions = exports.writeJSONFile = exports.existsFile = exports.existsDir = exports.safeStat = exports.ensureEmptyDir = exports.mkdirIfNotExists = exports.isLocalDir = exports.isEmptyDir = exports.isWSLSystem = void 0;
|
|
7
7
|
const globalData_1 = __importDefault(require("../globalData"));
|
|
8
8
|
const math_1 = require("./math");
|
|
9
9
|
const path_1 = require("./path");
|
|
@@ -35,37 +35,13 @@ async function isEmptyDir(path) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
exports.isEmptyDir = isEmptyDir;
|
|
38
|
-
async function applyPermissions(baseDir, permissionsPath) {
|
|
39
|
-
const singleReader = (0, readline_1.createInterface)({
|
|
40
|
-
input: (0, fs_1.createReadStream)(permissionsPath),
|
|
41
|
-
});
|
|
42
|
-
for await (const line of singleReader) {
|
|
43
|
-
const [rpath, rawUid, rawGui, rawMode] = line.split(":");
|
|
44
|
-
const path = (0, path_2.join)(baseDir, rpath);
|
|
45
|
-
if (!path.startsWith(baseDir)) {
|
|
46
|
-
throw new Error(`Entry path is out of the base dir: (${path}, ${baseDir})`);
|
|
47
|
-
}
|
|
48
|
-
const uid = Number(rawUid);
|
|
49
|
-
const guid = Number(rawGui);
|
|
50
|
-
await (0, promises_1.chown)(path, uid, guid);
|
|
51
|
-
const mode = Number(rawMode);
|
|
52
|
-
await (0, promises_1.chmod)(path, mode);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.applyPermissions = applyPermissions;
|
|
56
38
|
function pathIterator(stream) {
|
|
57
39
|
return stream;
|
|
58
40
|
}
|
|
59
|
-
exports.pathIterator = pathIterator;
|
|
60
41
|
function isLocalDir(path) {
|
|
61
42
|
return /^[\/\.]|([A-Z]:)/i.test(path);
|
|
62
43
|
}
|
|
63
44
|
exports.isLocalDir = isLocalDir;
|
|
64
|
-
async function isDirEmpty(path) {
|
|
65
|
-
const files = await readDir(path);
|
|
66
|
-
return !files.length;
|
|
67
|
-
}
|
|
68
|
-
exports.isDirEmpty = isDirEmpty;
|
|
69
45
|
async function mkdirIfNotExists(path) {
|
|
70
46
|
await (0, promises_1.mkdir)(path, {
|
|
71
47
|
recursive: true,
|
|
@@ -74,28 +50,29 @@ async function mkdirIfNotExists(path) {
|
|
|
74
50
|
}
|
|
75
51
|
exports.mkdirIfNotExists = mkdirIfNotExists;
|
|
76
52
|
async function ensureEmptyDir(path) {
|
|
77
|
-
if (!(await
|
|
53
|
+
if (!(await isEmptyDir(path)))
|
|
78
54
|
throw new Error(`Dir is not empty: ${path}`);
|
|
79
55
|
}
|
|
80
56
|
exports.ensureEmptyDir = ensureEmptyDir;
|
|
81
|
-
async function
|
|
57
|
+
async function safeStat(path) {
|
|
82
58
|
try {
|
|
83
|
-
|
|
84
|
-
return info.isDirectory();
|
|
85
|
-
}
|
|
86
|
-
catch (e) {
|
|
87
|
-
return false;
|
|
59
|
+
return await (0, promises_1.stat)(path);
|
|
88
60
|
}
|
|
61
|
+
catch (e) { }
|
|
62
|
+
}
|
|
63
|
+
exports.safeStat = safeStat;
|
|
64
|
+
async function existsDir(path) {
|
|
65
|
+
return (await safeStat(path))?.isDirectory() ?? false;
|
|
89
66
|
}
|
|
90
67
|
exports.existsDir = existsDir;
|
|
68
|
+
async function existsFile(path) {
|
|
69
|
+
return (await safeStat(path))?.isFile() ?? false;
|
|
70
|
+
}
|
|
71
|
+
exports.existsFile = existsFile;
|
|
91
72
|
async function writeJSONFile(path, json) {
|
|
92
73
|
await (0, promises_1.writeFile)(path, JSON.stringify(json));
|
|
93
74
|
}
|
|
94
75
|
exports.writeJSONFile = writeJSONFile;
|
|
95
|
-
async function readdirIfExists(path) {
|
|
96
|
-
return await readDir(path, true);
|
|
97
|
-
}
|
|
98
|
-
exports.readdirIfExists = readdirIfExists;
|
|
99
76
|
exports.parseFileExtensions = ["json", "js", "ts", "yaml", "yml"];
|
|
100
77
|
async function parseFile(path, jsKey) {
|
|
101
78
|
if (!(0, path_3.isAbsolute)(path))
|
|
@@ -140,16 +117,6 @@ async function findFile(sourcePath, baseName, extensions, errorMessage = "Path n
|
|
|
140
117
|
return path;
|
|
141
118
|
}
|
|
142
119
|
exports.findFile = findFile;
|
|
143
|
-
async function existsFile(path) {
|
|
144
|
-
try {
|
|
145
|
-
const info = await (0, promises_1.stat)(path);
|
|
146
|
-
return info.isFile();
|
|
147
|
-
}
|
|
148
|
-
catch (e) {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
exports.existsFile = existsFile;
|
|
153
120
|
function parentTmpDir() {
|
|
154
121
|
return (0, path_2.join)(globalData_1.default.tempDir, "datatruck-temp");
|
|
155
122
|
}
|
|
@@ -219,24 +186,6 @@ async function readPartialFile(path, positions) {
|
|
|
219
186
|
});
|
|
220
187
|
}
|
|
221
188
|
exports.readPartialFile = readPartialFile;
|
|
222
|
-
async function checkFile(path) {
|
|
223
|
-
try {
|
|
224
|
-
return (await (0, promises_1.stat)(path)).isFile();
|
|
225
|
-
}
|
|
226
|
-
catch (e) {
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
exports.checkFile = checkFile;
|
|
231
|
-
async function checkDir(path) {
|
|
232
|
-
try {
|
|
233
|
-
return (await (0, promises_1.stat)(path)).isDirectory();
|
|
234
|
-
}
|
|
235
|
-
catch (e) {
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
exports.checkDir = checkDir;
|
|
240
189
|
async function readDir(path, optional) {
|
|
241
190
|
try {
|
|
242
191
|
return await (0, promises_1.readdir)(path);
|
|
@@ -458,62 +407,125 @@ async function cpy(options) {
|
|
|
458
407
|
exports.cpy = cpy;
|
|
459
408
|
async function createFileScanner(options) {
|
|
460
409
|
const object = {
|
|
410
|
+
disposed: false,
|
|
461
411
|
total: 0,
|
|
462
412
|
current: 0,
|
|
463
|
-
progress: async (description,
|
|
413
|
+
progress: async (description, path) => {
|
|
414
|
+
if (object.disposed)
|
|
415
|
+
return;
|
|
416
|
+
if (path)
|
|
417
|
+
object.current++;
|
|
464
418
|
await options.onProgress({
|
|
465
419
|
relative: {
|
|
466
420
|
description,
|
|
467
|
-
payload:
|
|
468
|
-
percent: data.percent,
|
|
421
|
+
payload: path,
|
|
469
422
|
},
|
|
470
423
|
absolute: {
|
|
471
424
|
total: object.total,
|
|
472
|
-
current: object.current
|
|
473
|
-
percent: (0, math_1.progressPercent)(object.total, object.current
|
|
425
|
+
current: object.current,
|
|
426
|
+
percent: (0, math_1.progressPercent)(object.total, object.current),
|
|
474
427
|
},
|
|
475
428
|
});
|
|
476
|
-
if (data.type === "end") {
|
|
477
|
-
object.current += data.current;
|
|
478
|
-
}
|
|
479
429
|
},
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
await options.onProgress({
|
|
485
|
-
relative: {
|
|
486
|
-
description: end ? "Scanned files" : "Scanning files",
|
|
487
|
-
payload: object.total.toString(),
|
|
488
|
-
},
|
|
489
|
-
});
|
|
490
|
-
lastTime = currentTime;
|
|
491
|
-
}
|
|
430
|
+
end: async () => {
|
|
431
|
+
if (!object.disposed)
|
|
432
|
+
await object.progress("Finished");
|
|
433
|
+
object.disposed = true;
|
|
492
434
|
},
|
|
493
435
|
start: async (cb) => {
|
|
436
|
+
let lastTime = performance.now();
|
|
437
|
+
await object.progress("Scanning files");
|
|
494
438
|
for await (const entry of pathIterator(stream)) {
|
|
495
|
-
if (
|
|
439
|
+
if (cb) {
|
|
440
|
+
if (await cb(entry))
|
|
441
|
+
object.total++;
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
496
444
|
object.total++;
|
|
497
|
-
|
|
498
|
-
if (
|
|
499
|
-
await
|
|
445
|
+
}
|
|
446
|
+
if (lastTime - performance.now() > 500)
|
|
447
|
+
await object.progress("Scanning files");
|
|
500
448
|
}
|
|
501
|
-
|
|
502
|
-
await object.updateProgress(true);
|
|
449
|
+
await object.progress("Scanned files");
|
|
503
450
|
},
|
|
504
451
|
};
|
|
505
|
-
await options.onProgress({
|
|
506
|
-
relative: {
|
|
507
|
-
description: "Scanning files",
|
|
508
|
-
},
|
|
509
|
-
});
|
|
510
452
|
const stream = fast_glob_1.default.stream(options.glob.include, {
|
|
511
453
|
dot: true,
|
|
512
454
|
markDirectories: true,
|
|
513
455
|
stats: true,
|
|
514
456
|
...options.glob,
|
|
515
457
|
});
|
|
516
|
-
let lastTime = performance.now();
|
|
517
458
|
return object;
|
|
518
459
|
}
|
|
519
460
|
exports.createFileScanner = createFileScanner;
|
|
461
|
+
function createWriteStreamPool(options) {
|
|
462
|
+
const pool = {};
|
|
463
|
+
const create = (key) => {
|
|
464
|
+
const item = {
|
|
465
|
+
key,
|
|
466
|
+
stream: (0, fs_2.createWriteStream)((0, path_2.join)(options.path, options.onStreamPath ? options.onStreamPath(key) : key)),
|
|
467
|
+
finished: false,
|
|
468
|
+
};
|
|
469
|
+
item.stream
|
|
470
|
+
.once("error", (error) => {
|
|
471
|
+
item.finished = true;
|
|
472
|
+
item.error = error;
|
|
473
|
+
})
|
|
474
|
+
.once("close", () => (item.finished = true));
|
|
475
|
+
return (pool[item.key] = item);
|
|
476
|
+
};
|
|
477
|
+
return {
|
|
478
|
+
pool,
|
|
479
|
+
path(key) {
|
|
480
|
+
const item = pool[key];
|
|
481
|
+
if (!item)
|
|
482
|
+
return;
|
|
483
|
+
if (typeof item.stream.path !== "string")
|
|
484
|
+
throw new Error(`Stream path is not defined: ${key}`);
|
|
485
|
+
return item.stream.path;
|
|
486
|
+
},
|
|
487
|
+
writeLine(key, v) {
|
|
488
|
+
const item = pool[key] || create(key.toString());
|
|
489
|
+
if (item.finished) {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
else if (item.written) {
|
|
493
|
+
return item.stream.write(`\n${v}`);
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
item.written = true;
|
|
497
|
+
return item.stream.write(`${v}`);
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
async end() {
|
|
501
|
+
const items = Object.values(pool);
|
|
502
|
+
for (const item of items)
|
|
503
|
+
if (!item.finished)
|
|
504
|
+
item.stream.end();
|
|
505
|
+
const itemWithErrors = items.filter((v) => v.error);
|
|
506
|
+
if (itemWithErrors.length) {
|
|
507
|
+
const keys = itemWithErrors.map((item) => item.key);
|
|
508
|
+
throw new AggregateError(itemWithErrors.map((item) => item.error), `Streams faileds: ${keys.join(", ")}`);
|
|
509
|
+
}
|
|
510
|
+
await Promise.all(items
|
|
511
|
+
.filter((item) => !item.finished)
|
|
512
|
+
.map((item) => waitForClose(item.stream)));
|
|
513
|
+
},
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
exports.createWriteStreamPool = createWriteStreamPool;
|
|
517
|
+
function countFileLines(path) {
|
|
518
|
+
let lines = 0;
|
|
519
|
+
const rl = (0, readline_1.createInterface)({
|
|
520
|
+
input: (0, fs_1.createReadStream)(path),
|
|
521
|
+
});
|
|
522
|
+
return new Promise((resolve, reject) => {
|
|
523
|
+
rl.on("line", (line) => {
|
|
524
|
+
if (!line.length)
|
|
525
|
+
lines++;
|
|
526
|
+
});
|
|
527
|
+
rl.on("close", () => resolve(lines));
|
|
528
|
+
rl.on("error", reject);
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
exports.countFileLines = countFileLines;
|
package/utils/process.d.ts
CHANGED