mioku 0.9.5 → 0.9.7

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.
@@ -0,0 +1,217 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const node_child_process = __toESM(require("node:child_process"));
25
+ const node_fs = __toESM(require("node:fs"));
26
+ const node_os = __toESM(require("node:os"));
27
+ const node_path = __toESM(require("node:path"));
28
+
29
+ //#region src/core/exec.ts
30
+ const isWindows = process.platform === "win32";
31
+ const resolveCache = new Map();
32
+ function windowsExtensions() {
33
+ const raw = process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD";
34
+ return raw.split(";").map((ext) => ext.trim()).filter(Boolean);
35
+ }
36
+ function searchDirs() {
37
+ const raw = process.env.PATH || process.env.Path || "";
38
+ const dirs = raw.split(node_path.delimiter).map((d) => d.trim()).filter(Boolean);
39
+ const home = node_os.homedir();
40
+ const extra = isWindows ? [
41
+ node_path.join(home, ".bun", "bin"),
42
+ node_path.join(process.env.APPDATA || "", "npm"),
43
+ node_path.join(process.env.ProgramFiles || "", "nodejs")
44
+ ] : [
45
+ node_path.join(home, ".bun", "bin"),
46
+ "/usr/local/bin",
47
+ "/opt/homebrew/bin",
48
+ node_path.join(home, ".npm-global", "bin")
49
+ ];
50
+ return [...dirs, ...extra.filter((dir) => dir && !dir.endsWith(node_path.sep))];
51
+ }
52
+ function isExecutableFile(candidate) {
53
+ try {
54
+ return node_fs.statSync(candidate).isFile();
55
+ } catch {
56
+ return false;
57
+ }
58
+ }
59
+ function resolveCommand(command) {
60
+ if (resolveCache.has(command)) return resolveCache.get(command) ?? null;
61
+ let resolved = null;
62
+ if (command.includes("/") || command.includes(node_path.sep)) resolved = isExecutableFile(command) ? node_path.resolve(command) : null;
63
+ else {
64
+ const exts = isWindows ? windowsExtensions() : [""];
65
+ const hasKnownExt = isWindows && exts.some((ext) => command.toLowerCase().endsWith(ext.toLowerCase()));
66
+ outer: for (const dir of searchDirs()) {
67
+ if (hasKnownExt) {
68
+ const direct = node_path.join(dir, command);
69
+ if (isExecutableFile(direct)) {
70
+ resolved = direct;
71
+ break;
72
+ }
73
+ continue;
74
+ }
75
+ for (const ext of exts) {
76
+ const candidate = node_path.join(dir, command + ext);
77
+ if (isExecutableFile(candidate)) {
78
+ resolved = candidate;
79
+ break outer;
80
+ }
81
+ }
82
+ }
83
+ }
84
+ resolveCache.set(command, resolved);
85
+ return resolved;
86
+ }
87
+ function clearCommandCache() {
88
+ resolveCache.clear();
89
+ }
90
+ function needsCmdShell(resolved) {
91
+ if (!isWindows) return false;
92
+ const ext = node_path.extname(resolved).toLowerCase();
93
+ return ext === ".cmd" || ext === ".bat";
94
+ }
95
+ function quoteForCmd(arg) {
96
+ if (arg === "") return "\"\"";
97
+ const escaped = arg.replace(/(\\*)"/g, "$1$1\\\"").replace(/(\\+)$/, "$1$1");
98
+ return `"${escaped}"`;
99
+ }
100
+ function buildSpawnPlan(command, args) {
101
+ const resolved = resolveCommand(command);
102
+ if (!resolved) return {
103
+ file: command,
104
+ args
105
+ };
106
+ if (!needsCmdShell(resolved)) return {
107
+ file: resolved,
108
+ args
109
+ };
110
+ const comspec = process.env.ComSpec || process.env.COMSPEC || "cmd.exe";
111
+ const line = [resolved, ...args].map(quoteForCmd).join(" ");
112
+ return {
113
+ file: comspec,
114
+ args: [
115
+ "/d",
116
+ "/s",
117
+ "/c",
118
+ `"${line}"`
119
+ ],
120
+ windowsVerbatimArguments: true
121
+ };
122
+ }
123
+ function runCommand(command, args, options = {}) {
124
+ const plan = buildSpawnPlan(command, args);
125
+ return new Promise((resolve) => {
126
+ const child = (0, node_child_process.spawn)(plan.file, plan.args, {
127
+ cwd: options.cwd,
128
+ env: options.env,
129
+ stdio: [
130
+ "ignore",
131
+ "pipe",
132
+ "pipe"
133
+ ],
134
+ windowsVerbatimArguments: plan.windowsVerbatimArguments
135
+ });
136
+ let stdout = "";
137
+ let stderr = "";
138
+ child.stdout?.on("data", (chunk) => {
139
+ stdout += String(chunk);
140
+ });
141
+ child.stderr?.on("data", (chunk) => {
142
+ stderr += String(chunk);
143
+ });
144
+ child.on("close", (code) => {
145
+ resolve({
146
+ stdout,
147
+ stderr,
148
+ code: code ?? 1
149
+ });
150
+ });
151
+ child.on("error", (error) => {
152
+ resolve({
153
+ stdout,
154
+ stderr: `${stderr}\n${error.message}`.trim(),
155
+ code: 1
156
+ });
157
+ });
158
+ });
159
+ }
160
+ function runCommandInherit(command, args, options = {}) {
161
+ const plan = buildSpawnPlan(command, args);
162
+ const result = (0, node_child_process.spawnSync)(plan.file, plan.args, {
163
+ cwd: options.cwd,
164
+ stdio: "inherit",
165
+ windowsVerbatimArguments: plan.windowsVerbatimArguments
166
+ });
167
+ if (result.error) throw result.error;
168
+ if (result.status !== 0) throw new Error(`${command} 退出码 ${result.status}`);
169
+ }
170
+ function commandExists(command) {
171
+ return resolveCommand(command) !== null;
172
+ }
173
+
174
+ //#endregion
175
+ Object.defineProperty(exports, '__toESM', {
176
+ enumerable: true,
177
+ get: function () {
178
+ return __toESM;
179
+ }
180
+ });
181
+ Object.defineProperty(exports, 'buildSpawnPlan', {
182
+ enumerable: true,
183
+ get: function () {
184
+ return buildSpawnPlan;
185
+ }
186
+ });
187
+ Object.defineProperty(exports, 'clearCommandCache', {
188
+ enumerable: true,
189
+ get: function () {
190
+ return clearCommandCache;
191
+ }
192
+ });
193
+ Object.defineProperty(exports, 'commandExists', {
194
+ enumerable: true,
195
+ get: function () {
196
+ return commandExists;
197
+ }
198
+ });
199
+ Object.defineProperty(exports, 'resolveCommand', {
200
+ enumerable: true,
201
+ get: function () {
202
+ return resolveCommand;
203
+ }
204
+ });
205
+ Object.defineProperty(exports, 'runCommand', {
206
+ enumerable: true,
207
+ get: function () {
208
+ return runCommand;
209
+ }
210
+ });
211
+ Object.defineProperty(exports, 'runCommandInherit', {
212
+ enumerable: true,
213
+ get: function () {
214
+ return runCommandInherit;
215
+ }
216
+ });
217
+ //# sourceMappingURL=exec-BojymP61.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-BojymP61.cjs","names":["path","candidate: string","command: string","resolved: string | null","resolved: string","arg: string","args: string[]","options: { cwd?: string; env?: NodeJS.ProcessEnv }","options: { cwd?: string }"],"sources":["../src/core/exec.ts"],"sourcesContent":["import { spawn, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nconst isWindows = process.platform === \"win32\";\n\nconst resolveCache = new Map<string, string | null>();\n\nfunction windowsExtensions(): string[] {\n const raw = process.env.PATHEXT || \".COM;.EXE;.BAT;.CMD\";\n return raw\n .split(\";\")\n .map((ext) => ext.trim())\n .filter(Boolean);\n}\n\n// PATH is a snapshot taken at process start, so a package manager installed\n// mid-run won't be on it. These are the standard install prefixes for bun and\n// for npm's global bin, which is where `npm i -g bun` actually lands.\nfunction searchDirs(): string[] {\n const raw = process.env.PATH || process.env.Path || \"\";\n const dirs = raw.split(path.delimiter).map((d) => d.trim()).filter(Boolean);\n const home = os.homedir();\n\n const extra = isWindows\n ? [\n path.join(home, \".bun\", \"bin\"),\n path.join(process.env.APPDATA || \"\", \"npm\"),\n path.join(process.env.ProgramFiles || \"\", \"nodejs\"),\n ]\n : [\n path.join(home, \".bun\", \"bin\"),\n \"/usr/local/bin\",\n \"/opt/homebrew/bin\",\n path.join(home, \".npm-global\", \"bin\"),\n ];\n\n return [...dirs, ...extra.filter((dir) => dir && !dir.endsWith(path.sep))];\n}\n\nfunction isExecutableFile(candidate: string): boolean {\n try {\n return fs.statSync(candidate).isFile();\n } catch {\n return false;\n }\n}\n\nexport function resolveCommand(command: string): string | null {\n if (resolveCache.has(command)) return resolveCache.get(command) ?? null;\n\n let resolved: string | null = null;\n\n if (command.includes(\"/\") || command.includes(path.sep)) {\n resolved = isExecutableFile(command) ? path.resolve(command) : null;\n } else {\n const exts = isWindows ? windowsExtensions() : [\"\"];\n const hasKnownExt =\n isWindows && exts.some((ext) => command.toLowerCase().endsWith(ext.toLowerCase()));\n\n outer: for (const dir of searchDirs()) {\n if (hasKnownExt) {\n const direct = path.join(dir, command);\n if (isExecutableFile(direct)) {\n resolved = direct;\n break;\n }\n continue;\n }\n for (const ext of exts) {\n const candidate = path.join(dir, command + ext);\n if (isExecutableFile(candidate)) {\n resolved = candidate;\n break outer;\n }\n }\n }\n }\n\n resolveCache.set(command, resolved);\n return resolved;\n}\n\nexport function clearCommandCache(): void {\n resolveCache.clear();\n}\n\nfunction needsCmdShell(resolved: string): boolean {\n if (!isWindows) return false;\n const ext = path.extname(resolved).toLowerCase();\n return ext === \".cmd\" || ext === \".bat\";\n}\n\n// cmd.exe argument quoting: escape embedded quotes and any run of backslashes\n// that precedes a quote, then wrap the whole thing so metacharacters inside\n// (&, |, <, >, ^) are inert.\nfunction quoteForCmd(arg: string): string {\n if (arg === \"\") return '\"\"';\n const escaped = arg\n .replace(/(\\\\*)\"/g, '$1$1\\\\\"')\n .replace(/(\\\\+)$/, \"$1$1\");\n return `\"${escaped}\"`;\n}\n\nexport interface SpawnPlan {\n file: string;\n args: string[];\n windowsVerbatimArguments?: boolean;\n}\n\n// Windows can't CreateProcess a .cmd/.bat shim directly (npm installs bun as\n// bun.cmd), so those get routed through cmd.exe with hand-quoted arguments\n// rather than shell: true, which would leave the args unquoted.\nexport function buildSpawnPlan(command: string, args: string[]): SpawnPlan {\n const resolved = resolveCommand(command);\n\n if (!resolved) {\n return { file: command, args };\n }\n\n if (!needsCmdShell(resolved)) {\n return { file: resolved, args };\n }\n\n const comspec = process.env.ComSpec || process.env.COMSPEC || \"cmd.exe\";\n const line = [resolved, ...args].map(quoteForCmd).join(\" \");\n return {\n file: comspec,\n args: [\"/d\", \"/s\", \"/c\", `\"${line}\"`],\n windowsVerbatimArguments: true,\n };\n}\n\nexport interface RunCommandResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nexport function runCommand(\n command: string,\n args: string[],\n options: { cwd?: string; env?: NodeJS.ProcessEnv } = {},\n): Promise<RunCommandResult> {\n const plan = buildSpawnPlan(command, args);\n\n return new Promise((resolve) => {\n const child = spawn(plan.file, plan.args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsVerbatimArguments: plan.windowsVerbatimArguments,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n\n child.on(\"close\", (code) => {\n resolve({ stdout, stderr, code: code ?? 1 });\n });\n child.on(\"error\", (error) => {\n resolve({\n stdout,\n stderr: `${stderr}\\n${error.message}`.trim(),\n code: 1,\n });\n });\n });\n}\n\nexport function runCommandInherit(\n command: string,\n args: string[],\n options: { cwd?: string } = {},\n): void {\n const plan = buildSpawnPlan(command, args);\n const result = spawnSync(plan.file, plan.args, {\n cwd: options.cwd,\n stdio: \"inherit\",\n windowsVerbatimArguments: plan.windowsVerbatimArguments,\n });\n\n if (result.error) throw result.error;\n if (result.status !== 0) {\n throw new Error(`${command} 退出码 ${result.status}`);\n }\n}\n\nexport function commandExists(command: string): boolean {\n return resolveCommand(command) !== null;\n}\n"],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ import { spawn, spawnSync } from "node:child_process";
2
+ import * as fs$1 from "node:fs";
3
+ import * as os from "node:os";
4
+ import * as path$1 from "node:path";
5
+
6
+ //#region src/core/exec.ts
7
+ const isWindows = process.platform === "win32";
8
+ const resolveCache = new Map();
9
+ function windowsExtensions() {
10
+ const raw = process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD";
11
+ return raw.split(";").map((ext) => ext.trim()).filter(Boolean);
12
+ }
13
+ function searchDirs() {
14
+ const raw = process.env.PATH || process.env.Path || "";
15
+ const dirs = raw.split(path$1.delimiter).map((d) => d.trim()).filter(Boolean);
16
+ const home = os.homedir();
17
+ const extra = isWindows ? [
18
+ path$1.join(home, ".bun", "bin"),
19
+ path$1.join(process.env.APPDATA || "", "npm"),
20
+ path$1.join(process.env.ProgramFiles || "", "nodejs")
21
+ ] : [
22
+ path$1.join(home, ".bun", "bin"),
23
+ "/usr/local/bin",
24
+ "/opt/homebrew/bin",
25
+ path$1.join(home, ".npm-global", "bin")
26
+ ];
27
+ return [...dirs, ...extra.filter((dir) => dir && !dir.endsWith(path$1.sep))];
28
+ }
29
+ function isExecutableFile(candidate) {
30
+ try {
31
+ return fs$1.statSync(candidate).isFile();
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
36
+ function resolveCommand(command) {
37
+ if (resolveCache.has(command)) return resolveCache.get(command) ?? null;
38
+ let resolved = null;
39
+ if (command.includes("/") || command.includes(path$1.sep)) resolved = isExecutableFile(command) ? path$1.resolve(command) : null;
40
+ else {
41
+ const exts = isWindows ? windowsExtensions() : [""];
42
+ const hasKnownExt = isWindows && exts.some((ext) => command.toLowerCase().endsWith(ext.toLowerCase()));
43
+ outer: for (const dir of searchDirs()) {
44
+ if (hasKnownExt) {
45
+ const direct = path$1.join(dir, command);
46
+ if (isExecutableFile(direct)) {
47
+ resolved = direct;
48
+ break;
49
+ }
50
+ continue;
51
+ }
52
+ for (const ext of exts) {
53
+ const candidate = path$1.join(dir, command + ext);
54
+ if (isExecutableFile(candidate)) {
55
+ resolved = candidate;
56
+ break outer;
57
+ }
58
+ }
59
+ }
60
+ }
61
+ resolveCache.set(command, resolved);
62
+ return resolved;
63
+ }
64
+ function clearCommandCache() {
65
+ resolveCache.clear();
66
+ }
67
+ function needsCmdShell(resolved) {
68
+ if (!isWindows) return false;
69
+ const ext = path$1.extname(resolved).toLowerCase();
70
+ return ext === ".cmd" || ext === ".bat";
71
+ }
72
+ function quoteForCmd(arg) {
73
+ if (arg === "") return "\"\"";
74
+ const escaped = arg.replace(/(\\*)"/g, "$1$1\\\"").replace(/(\\+)$/, "$1$1");
75
+ return `"${escaped}"`;
76
+ }
77
+ function buildSpawnPlan(command, args) {
78
+ const resolved = resolveCommand(command);
79
+ if (!resolved) return {
80
+ file: command,
81
+ args
82
+ };
83
+ if (!needsCmdShell(resolved)) return {
84
+ file: resolved,
85
+ args
86
+ };
87
+ const comspec = process.env.ComSpec || process.env.COMSPEC || "cmd.exe";
88
+ const line = [resolved, ...args].map(quoteForCmd).join(" ");
89
+ return {
90
+ file: comspec,
91
+ args: [
92
+ "/d",
93
+ "/s",
94
+ "/c",
95
+ `"${line}"`
96
+ ],
97
+ windowsVerbatimArguments: true
98
+ };
99
+ }
100
+ function runCommand(command, args, options = {}) {
101
+ const plan = buildSpawnPlan(command, args);
102
+ return new Promise((resolve) => {
103
+ const child = spawn(plan.file, plan.args, {
104
+ cwd: options.cwd,
105
+ env: options.env,
106
+ stdio: [
107
+ "ignore",
108
+ "pipe",
109
+ "pipe"
110
+ ],
111
+ windowsVerbatimArguments: plan.windowsVerbatimArguments
112
+ });
113
+ let stdout = "";
114
+ let stderr = "";
115
+ child.stdout?.on("data", (chunk) => {
116
+ stdout += String(chunk);
117
+ });
118
+ child.stderr?.on("data", (chunk) => {
119
+ stderr += String(chunk);
120
+ });
121
+ child.on("close", (code) => {
122
+ resolve({
123
+ stdout,
124
+ stderr,
125
+ code: code ?? 1
126
+ });
127
+ });
128
+ child.on("error", (error) => {
129
+ resolve({
130
+ stdout,
131
+ stderr: `${stderr}\n${error.message}`.trim(),
132
+ code: 1
133
+ });
134
+ });
135
+ });
136
+ }
137
+ function runCommandInherit(command, args, options = {}) {
138
+ const plan = buildSpawnPlan(command, args);
139
+ const result = spawnSync(plan.file, plan.args, {
140
+ cwd: options.cwd,
141
+ stdio: "inherit",
142
+ windowsVerbatimArguments: plan.windowsVerbatimArguments
143
+ });
144
+ if (result.error) throw result.error;
145
+ if (result.status !== 0) throw new Error(`${command} 退出码 ${result.status}`);
146
+ }
147
+ function commandExists(command) {
148
+ return resolveCommand(command) !== null;
149
+ }
150
+
151
+ //#endregion
152
+ export { buildSpawnPlan, clearCommandCache, commandExists, resolveCommand, runCommand, runCommandInherit };
153
+ //# sourceMappingURL=exec-BzODBZwA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-BzODBZwA.js","names":["path","candidate: string","command: string","resolved: string | null","resolved: string","arg: string","args: string[]","options: { cwd?: string; env?: NodeJS.ProcessEnv }","options: { cwd?: string }"],"sources":["../src/core/exec.ts"],"sourcesContent":["import { spawn, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nconst isWindows = process.platform === \"win32\";\n\nconst resolveCache = new Map<string, string | null>();\n\nfunction windowsExtensions(): string[] {\n const raw = process.env.PATHEXT || \".COM;.EXE;.BAT;.CMD\";\n return raw\n .split(\";\")\n .map((ext) => ext.trim())\n .filter(Boolean);\n}\n\n// PATH is a snapshot taken at process start, so a package manager installed\n// mid-run won't be on it. These are the standard install prefixes for bun and\n// for npm's global bin, which is where `npm i -g bun` actually lands.\nfunction searchDirs(): string[] {\n const raw = process.env.PATH || process.env.Path || \"\";\n const dirs = raw.split(path.delimiter).map((d) => d.trim()).filter(Boolean);\n const home = os.homedir();\n\n const extra = isWindows\n ? [\n path.join(home, \".bun\", \"bin\"),\n path.join(process.env.APPDATA || \"\", \"npm\"),\n path.join(process.env.ProgramFiles || \"\", \"nodejs\"),\n ]\n : [\n path.join(home, \".bun\", \"bin\"),\n \"/usr/local/bin\",\n \"/opt/homebrew/bin\",\n path.join(home, \".npm-global\", \"bin\"),\n ];\n\n return [...dirs, ...extra.filter((dir) => dir && !dir.endsWith(path.sep))];\n}\n\nfunction isExecutableFile(candidate: string): boolean {\n try {\n return fs.statSync(candidate).isFile();\n } catch {\n return false;\n }\n}\n\nexport function resolveCommand(command: string): string | null {\n if (resolveCache.has(command)) return resolveCache.get(command) ?? null;\n\n let resolved: string | null = null;\n\n if (command.includes(\"/\") || command.includes(path.sep)) {\n resolved = isExecutableFile(command) ? path.resolve(command) : null;\n } else {\n const exts = isWindows ? windowsExtensions() : [\"\"];\n const hasKnownExt =\n isWindows && exts.some((ext) => command.toLowerCase().endsWith(ext.toLowerCase()));\n\n outer: for (const dir of searchDirs()) {\n if (hasKnownExt) {\n const direct = path.join(dir, command);\n if (isExecutableFile(direct)) {\n resolved = direct;\n break;\n }\n continue;\n }\n for (const ext of exts) {\n const candidate = path.join(dir, command + ext);\n if (isExecutableFile(candidate)) {\n resolved = candidate;\n break outer;\n }\n }\n }\n }\n\n resolveCache.set(command, resolved);\n return resolved;\n}\n\nexport function clearCommandCache(): void {\n resolveCache.clear();\n}\n\nfunction needsCmdShell(resolved: string): boolean {\n if (!isWindows) return false;\n const ext = path.extname(resolved).toLowerCase();\n return ext === \".cmd\" || ext === \".bat\";\n}\n\n// cmd.exe argument quoting: escape embedded quotes and any run of backslashes\n// that precedes a quote, then wrap the whole thing so metacharacters inside\n// (&, |, <, >, ^) are inert.\nfunction quoteForCmd(arg: string): string {\n if (arg === \"\") return '\"\"';\n const escaped = arg\n .replace(/(\\\\*)\"/g, '$1$1\\\\\"')\n .replace(/(\\\\+)$/, \"$1$1\");\n return `\"${escaped}\"`;\n}\n\nexport interface SpawnPlan {\n file: string;\n args: string[];\n windowsVerbatimArguments?: boolean;\n}\n\n// Windows can't CreateProcess a .cmd/.bat shim directly (npm installs bun as\n// bun.cmd), so those get routed through cmd.exe with hand-quoted arguments\n// rather than shell: true, which would leave the args unquoted.\nexport function buildSpawnPlan(command: string, args: string[]): SpawnPlan {\n const resolved = resolveCommand(command);\n\n if (!resolved) {\n return { file: command, args };\n }\n\n if (!needsCmdShell(resolved)) {\n return { file: resolved, args };\n }\n\n const comspec = process.env.ComSpec || process.env.COMSPEC || \"cmd.exe\";\n const line = [resolved, ...args].map(quoteForCmd).join(\" \");\n return {\n file: comspec,\n args: [\"/d\", \"/s\", \"/c\", `\"${line}\"`],\n windowsVerbatimArguments: true,\n };\n}\n\nexport interface RunCommandResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\nexport function runCommand(\n command: string,\n args: string[],\n options: { cwd?: string; env?: NodeJS.ProcessEnv } = {},\n): Promise<RunCommandResult> {\n const plan = buildSpawnPlan(command, args);\n\n return new Promise((resolve) => {\n const child = spawn(plan.file, plan.args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsVerbatimArguments: plan.windowsVerbatimArguments,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n\n child.on(\"close\", (code) => {\n resolve({ stdout, stderr, code: code ?? 1 });\n });\n child.on(\"error\", (error) => {\n resolve({\n stdout,\n stderr: `${stderr}\\n${error.message}`.trim(),\n code: 1,\n });\n });\n });\n}\n\nexport function runCommandInherit(\n command: string,\n args: string[],\n options: { cwd?: string } = {},\n): void {\n const plan = buildSpawnPlan(command, args);\n const result = spawnSync(plan.file, plan.args, {\n cwd: options.cwd,\n stdio: \"inherit\",\n windowsVerbatimArguments: plan.windowsVerbatimArguments,\n });\n\n if (result.error) throw result.error;\n if (result.status !== 0) {\n throw new Error(`${command} 退出码 ${result.status}`);\n }\n}\n\nexport function commandExists(command: string): boolean {\n return resolveCommand(command) !== null;\n}\n"],"mappings":"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"}