@simplysm/core-node 14.0.7 → 14.0.8
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/cp.d.ts +30 -0
- package/dist/utils/cp.d.ts.map +1 -0
- package/dist/utils/cp.js +149 -0
- package/dist/utils/cp.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/utils/cp.ts +202 -0
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,KAAK;AACL,cAAc,uBAAuB,CAAC;AAEtC,KAAK;AACL,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,KAAK;AACL,cAAc,uBAAuB,CAAC;AAEtC,KAAK;AACL,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ChildProcess } from "child_process";
|
|
2
|
+
export declare function codePageToEncoding(codePage: number): string;
|
|
3
|
+
export declare function resetEncodingCache(): void;
|
|
4
|
+
export declare function getSystemEncoding(): string;
|
|
5
|
+
export interface ExecOptions {
|
|
6
|
+
cwd?: string;
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
stdio?: "pipe" | "inherit";
|
|
9
|
+
shell?: boolean;
|
|
10
|
+
reject?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type ExecSyncOptions = Omit<ExecOptions, "reject">;
|
|
13
|
+
export interface ExecResult {
|
|
14
|
+
stdout: string;
|
|
15
|
+
stderr: string;
|
|
16
|
+
exitCode: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function decodeBytes(raw: Uint8Array, systemEncoding?: string): string;
|
|
19
|
+
export declare class ExecProcess implements PromiseLike<ExecResult> {
|
|
20
|
+
private readonly _process;
|
|
21
|
+
private readonly _promise;
|
|
22
|
+
constructor(cp: ChildProcess, promise: Promise<ExecResult>);
|
|
23
|
+
get pid(): number | undefined;
|
|
24
|
+
then<TResult1 = ExecResult, TResult2 = never>(onfulfilled?: ((value: ExecResult) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
25
|
+
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<ExecResult | TResult>;
|
|
26
|
+
kill(signal?: NodeJS.Signals | number): boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function exec(cmd: string, args: string[], options?: ExecOptions): ExecProcess;
|
|
29
|
+
export declare function execSync(cmd: string, args: string[], options?: ExecSyncOptions): ExecResult;
|
|
30
|
+
//# sourceMappingURL=cp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cp.d.ts","sourceRoot":"","sources":["..\\..\\src\\utils\\cp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAkBlD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CA2B1C;AAID,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAE1D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAY5E;AAMD,qBAAa,WAAY,YAAW,WAAW,CAAC,UAAU,CAAC;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;gBAEnC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC;IAK1D,IAAI,GAAG,IAAI,MAAM,GAAG,SAAS,CAE5B;IAED,IAAI,CAAC,QAAQ,GAAG,UAAU,EAAE,QAAQ,GAAG,KAAK,EAC1C,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,EAC9E,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAC1E,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAI/B,KAAK,CAAC,OAAO,GAAG,KAAK,EACnB,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,GACxE,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;IAIhC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO;CAGhD;AAMD,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,CAiDpF;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,UAAU,CAkB3F"}
|
package/dist/utils/cp.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { execSync as cpExecSync, spawn as cpSpawn, spawnSync as cpSpawnSync } from "child_process";
|
|
2
|
+
import { bytes } from "@simplysm/core-common";
|
|
3
|
+
const CODE_PAGE_MAP = {
|
|
4
|
+
65001: "utf-8",
|
|
5
|
+
949: "euc-kr",
|
|
6
|
+
932: "shift-jis",
|
|
7
|
+
936: "gbk",
|
|
8
|
+
950: "big5",
|
|
9
|
+
1252: "windows-1252",
|
|
10
|
+
1251: "windows-1251",
|
|
11
|
+
1250: "windows-1250",
|
|
12
|
+
874: "windows-874",
|
|
13
|
+
};
|
|
14
|
+
let _cachedEncoding;
|
|
15
|
+
export function codePageToEncoding(codePage) {
|
|
16
|
+
return CODE_PAGE_MAP[codePage] ?? "utf-8";
|
|
17
|
+
}
|
|
18
|
+
export function resetEncodingCache() {
|
|
19
|
+
_cachedEncoding = undefined;
|
|
20
|
+
}
|
|
21
|
+
export function getSystemEncoding() {
|
|
22
|
+
if (_cachedEncoding != null)
|
|
23
|
+
return _cachedEncoding;
|
|
24
|
+
try {
|
|
25
|
+
if (process.platform === "win32") {
|
|
26
|
+
const output = cpExecSync("chcp", { encoding: "utf-8" });
|
|
27
|
+
const match = output.match(/\d+/);
|
|
28
|
+
if (match) {
|
|
29
|
+
_cachedEncoding = codePageToEncoding(Number(match[0]));
|
|
30
|
+
return _cachedEncoding;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const lang = process.env["LANG"] ?? process.env["LC_ALL"] ?? "";
|
|
35
|
+
const dotIndex = lang.indexOf(".");
|
|
36
|
+
if (dotIndex >= 0) {
|
|
37
|
+
let encoding = lang.slice(dotIndex + 1).split("@")[0].toLowerCase();
|
|
38
|
+
if (encoding === "utf8")
|
|
39
|
+
encoding = "utf-8";
|
|
40
|
+
_cachedEncoding = encoding;
|
|
41
|
+
return _cachedEncoding;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// 감지 실패 시 fallback
|
|
47
|
+
}
|
|
48
|
+
_cachedEncoding = "utf-8";
|
|
49
|
+
return _cachedEncoding;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region decodeBytes
|
|
53
|
+
export function decodeBytes(raw, systemEncoding) {
|
|
54
|
+
const encoding = systemEncoding ?? getSystemEncoding();
|
|
55
|
+
if (encoding === "utf-8") {
|
|
56
|
+
return new TextDecoder("utf-8").decode(raw);
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(raw);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return new TextDecoder(encoding).decode(raw);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region ExecProcess
|
|
67
|
+
export class ExecProcess {
|
|
68
|
+
_process;
|
|
69
|
+
_promise;
|
|
70
|
+
constructor(cp, promise) {
|
|
71
|
+
this._process = cp;
|
|
72
|
+
this._promise = promise;
|
|
73
|
+
}
|
|
74
|
+
get pid() {
|
|
75
|
+
return this._process.pid;
|
|
76
|
+
}
|
|
77
|
+
then(onfulfilled, onrejected) {
|
|
78
|
+
return this._promise.then(onfulfilled, onrejected);
|
|
79
|
+
}
|
|
80
|
+
catch(onrejected) {
|
|
81
|
+
return this._promise.catch(onrejected);
|
|
82
|
+
}
|
|
83
|
+
kill(signal) {
|
|
84
|
+
return this._process.kill(signal);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region exec / execSync
|
|
89
|
+
export function exec(cmd, args, options) {
|
|
90
|
+
const isInherit = options?.stdio === "inherit";
|
|
91
|
+
const cp = cpSpawn(cmd, args, {
|
|
92
|
+
cwd: options?.cwd,
|
|
93
|
+
env: options?.env != null ? { ...process.env, ...options.env } : undefined,
|
|
94
|
+
stdio: isInherit ? "inherit" : "pipe",
|
|
95
|
+
shell: options?.shell ?? false,
|
|
96
|
+
});
|
|
97
|
+
const promise = new Promise((resolve, reject) => {
|
|
98
|
+
cp.on("error", (err) => {
|
|
99
|
+
reject(Object.assign(err, { stdout: "", stderr: "", exitCode: 1 }));
|
|
100
|
+
});
|
|
101
|
+
if (isInherit) {
|
|
102
|
+
cp.on("close", (code, signal) => {
|
|
103
|
+
const exitCode = code ?? (signal != null ? 1 : 0);
|
|
104
|
+
const result = { stdout: "", stderr: "", exitCode };
|
|
105
|
+
if (exitCode !== 0 && options.reject !== false) {
|
|
106
|
+
reject(Object.assign(new Error(`Command failed: ${cmd} ${args.join(" ")}`), result));
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
resolve(result);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const stdoutChunks = [];
|
|
115
|
+
const stderrChunks = [];
|
|
116
|
+
cp.stdout.on("data", (chunk) => stdoutChunks.push(chunk));
|
|
117
|
+
cp.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
118
|
+
cp.on("close", (code, signal) => {
|
|
119
|
+
const exitCode = code ?? (signal != null ? 1 : 0);
|
|
120
|
+
const stdout = decodeBytes(bytes.concat(stdoutChunks));
|
|
121
|
+
const stderr = decodeBytes(bytes.concat(stderrChunks));
|
|
122
|
+
const result = { stdout, stderr, exitCode };
|
|
123
|
+
if (exitCode !== 0 && options?.reject !== false) {
|
|
124
|
+
reject(Object.assign(new Error(`Command failed: ${cmd} ${args.join(" ")}`), result));
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
resolve(result);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
return new ExecProcess(cp, promise);
|
|
132
|
+
}
|
|
133
|
+
export function execSync(cmd, args, options) {
|
|
134
|
+
const isInherit = options?.stdio === "inherit";
|
|
135
|
+
const result = cpSpawnSync(cmd, args, {
|
|
136
|
+
cwd: options?.cwd,
|
|
137
|
+
env: options?.env != null ? { ...process.env, ...options.env } : undefined,
|
|
138
|
+
stdio: isInherit ? "inherit" : "pipe",
|
|
139
|
+
shell: options?.shell ?? false,
|
|
140
|
+
});
|
|
141
|
+
if (isInherit) {
|
|
142
|
+
return { stdout: "", stderr: "", exitCode: result.status ?? 0 };
|
|
143
|
+
}
|
|
144
|
+
const stdout = decodeBytes(result.stdout);
|
|
145
|
+
const stderr = decodeBytes(result.stderr);
|
|
146
|
+
return { stdout, stderr, exitCode: result.status ?? 0 };
|
|
147
|
+
}
|
|
148
|
+
//#endregion
|
|
149
|
+
//# sourceMappingURL=cp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cp.js","sourceRoot":"","sources":["..\\..\\src\\utils\\cp.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/core-node",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.8",
|
|
4
4
|
"description": "심플리즘 패키지 - 코어 (node)",
|
|
5
5
|
"author": "심플리즘",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"glob": "^13.0.6",
|
|
26
26
|
"minimatch": "^10.2.4",
|
|
27
27
|
"tsx": "^4.21.0",
|
|
28
|
-
"@simplysm/core-common": "14.0.
|
|
28
|
+
"@simplysm/core-common": "14.0.8"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^20.19.37"
|
package/src/index.ts
CHANGED
package/src/utils/cp.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import type { ChildProcess } from "child_process";
|
|
2
|
+
import { execSync as cpExecSync, spawn as cpSpawn, spawnSync as cpSpawnSync } from "child_process";
|
|
3
|
+
import { bytes } from "@simplysm/core-common";
|
|
4
|
+
|
|
5
|
+
const CODE_PAGE_MAP: Record<number, string> = {
|
|
6
|
+
65001: "utf-8",
|
|
7
|
+
949: "euc-kr",
|
|
8
|
+
932: "shift-jis",
|
|
9
|
+
936: "gbk",
|
|
10
|
+
950: "big5",
|
|
11
|
+
1252: "windows-1252",
|
|
12
|
+
1251: "windows-1251",
|
|
13
|
+
1250: "windows-1250",
|
|
14
|
+
874: "windows-874",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
let _cachedEncoding: string | undefined;
|
|
18
|
+
|
|
19
|
+
export function codePageToEncoding(codePage: number): string {
|
|
20
|
+
return CODE_PAGE_MAP[codePage] ?? "utf-8";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function resetEncodingCache(): void {
|
|
24
|
+
_cachedEncoding = undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getSystemEncoding(): string {
|
|
28
|
+
if (_cachedEncoding != null) return _cachedEncoding;
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
if (process.platform === "win32") {
|
|
32
|
+
const output = cpExecSync("chcp", { encoding: "utf-8" });
|
|
33
|
+
const match = output.match(/\d+/);
|
|
34
|
+
if (match) {
|
|
35
|
+
_cachedEncoding = codePageToEncoding(Number(match[0]));
|
|
36
|
+
return _cachedEncoding;
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
const lang = process.env["LANG"] ?? process.env["LC_ALL"] ?? "";
|
|
40
|
+
const dotIndex = lang.indexOf(".");
|
|
41
|
+
if (dotIndex >= 0) {
|
|
42
|
+
let encoding = lang.slice(dotIndex + 1).split("@")[0].toLowerCase();
|
|
43
|
+
if (encoding === "utf8") encoding = "utf-8";
|
|
44
|
+
_cachedEncoding = encoding;
|
|
45
|
+
return _cachedEncoding;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
// 감지 실패 시 fallback
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
_cachedEncoding = "utf-8";
|
|
53
|
+
return _cachedEncoding;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#region exec types
|
|
57
|
+
|
|
58
|
+
export interface ExecOptions {
|
|
59
|
+
cwd?: string;
|
|
60
|
+
env?: Record<string, string>;
|
|
61
|
+
stdio?: "pipe" | "inherit";
|
|
62
|
+
shell?: boolean;
|
|
63
|
+
reject?: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type ExecSyncOptions = Omit<ExecOptions, "reject">;
|
|
67
|
+
|
|
68
|
+
export interface ExecResult {
|
|
69
|
+
stdout: string;
|
|
70
|
+
stderr: string;
|
|
71
|
+
exitCode: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
|
|
76
|
+
//#region decodeBytes
|
|
77
|
+
|
|
78
|
+
export function decodeBytes(raw: Uint8Array, systemEncoding?: string): string {
|
|
79
|
+
const encoding = systemEncoding ?? getSystemEncoding();
|
|
80
|
+
|
|
81
|
+
if (encoding === "utf-8") {
|
|
82
|
+
return new TextDecoder("utf-8").decode(raw);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(raw);
|
|
87
|
+
} catch {
|
|
88
|
+
return new TextDecoder(encoding).decode(raw);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
|
|
94
|
+
//#region ExecProcess
|
|
95
|
+
|
|
96
|
+
export class ExecProcess implements PromiseLike<ExecResult> {
|
|
97
|
+
private readonly _process: ChildProcess;
|
|
98
|
+
private readonly _promise: Promise<ExecResult>;
|
|
99
|
+
|
|
100
|
+
constructor(cp: ChildProcess, promise: Promise<ExecResult>) {
|
|
101
|
+
this._process = cp;
|
|
102
|
+
this._promise = promise;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
get pid(): number | undefined {
|
|
106
|
+
return this._process.pid;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
then<TResult1 = ExecResult, TResult2 = never>(
|
|
110
|
+
onfulfilled?: ((value: ExecResult) => TResult1 | PromiseLike<TResult1>) | null,
|
|
111
|
+
onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,
|
|
112
|
+
): Promise<TResult1 | TResult2> {
|
|
113
|
+
return this._promise.then(onfulfilled, onrejected);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
catch<TResult = never>(
|
|
117
|
+
onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
|
|
118
|
+
): Promise<ExecResult | TResult> {
|
|
119
|
+
return this._promise.catch(onrejected);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
kill(signal?: NodeJS.Signals | number): boolean {
|
|
123
|
+
return this._process.kill(signal);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
|
|
129
|
+
//#region exec / execSync
|
|
130
|
+
|
|
131
|
+
export function exec(cmd: string, args: string[], options?: ExecOptions): ExecProcess {
|
|
132
|
+
const isInherit = options?.stdio === "inherit";
|
|
133
|
+
|
|
134
|
+
const cp = cpSpawn(cmd, args, {
|
|
135
|
+
cwd: options?.cwd,
|
|
136
|
+
env: options?.env != null ? { ...process.env, ...options.env } : undefined,
|
|
137
|
+
stdio: isInherit ? "inherit" : "pipe",
|
|
138
|
+
shell: options?.shell ?? false,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const promise = new Promise<ExecResult>((resolve, reject) => {
|
|
142
|
+
cp.on("error", (err) => {
|
|
143
|
+
reject(Object.assign(err, { stdout: "", stderr: "", exitCode: 1 }));
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
if (isInherit) {
|
|
147
|
+
cp.on("close", (code, signal) => {
|
|
148
|
+
const exitCode = code ?? (signal != null ? 1 : 0);
|
|
149
|
+
const result: ExecResult = { stdout: "", stderr: "", exitCode };
|
|
150
|
+
if (exitCode !== 0 && options.reject !== false) {
|
|
151
|
+
reject(Object.assign(new Error(`Command failed: ${cmd} ${args.join(" ")}`), result));
|
|
152
|
+
} else {
|
|
153
|
+
resolve(result);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const stdoutChunks: Uint8Array[] = [];
|
|
160
|
+
const stderrChunks: Uint8Array[] = [];
|
|
161
|
+
|
|
162
|
+
cp.stdout!.on("data", (chunk: Uint8Array) => stdoutChunks.push(chunk));
|
|
163
|
+
cp.stderr!.on("data", (chunk: Uint8Array) => stderrChunks.push(chunk));
|
|
164
|
+
|
|
165
|
+
cp.on("close", (code, signal) => {
|
|
166
|
+
const exitCode = code ?? (signal != null ? 1 : 0);
|
|
167
|
+
const stdout = decodeBytes(bytes.concat(stdoutChunks));
|
|
168
|
+
const stderr = decodeBytes(bytes.concat(stderrChunks));
|
|
169
|
+
const result: ExecResult = { stdout, stderr, exitCode };
|
|
170
|
+
|
|
171
|
+
if (exitCode !== 0 && options?.reject !== false) {
|
|
172
|
+
reject(Object.assign(new Error(`Command failed: ${cmd} ${args.join(" ")}`), result));
|
|
173
|
+
} else {
|
|
174
|
+
resolve(result);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return new ExecProcess(cp, promise);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function execSync(cmd: string, args: string[], options?: ExecSyncOptions): ExecResult {
|
|
183
|
+
const isInherit = options?.stdio === "inherit";
|
|
184
|
+
|
|
185
|
+
const result = cpSpawnSync(cmd, args, {
|
|
186
|
+
cwd: options?.cwd,
|
|
187
|
+
env: options?.env != null ? { ...process.env, ...options.env } : undefined,
|
|
188
|
+
stdio: isInherit ? "inherit" : "pipe",
|
|
189
|
+
shell: options?.shell ?? false,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
if (isInherit) {
|
|
193
|
+
return { stdout: "", stderr: "", exitCode: result.status ?? 0 };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const stdout = decodeBytes(result.stdout as Uint8Array);
|
|
197
|
+
const stderr = decodeBytes(result.stderr as Uint8Array);
|
|
198
|
+
|
|
199
|
+
return { stdout, stderr, exitCode: result.status ?? 0 };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
//#endregion
|