@simon_he/pi 0.1.19 → 0.1.21

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.mjs ADDED
@@ -0,0 +1,729 @@
1
+ import { createRequire } from "node:module";
2
+ import path from "node:path";
3
+ import process from "node:process";
4
+ import fg from "fast-glob";
5
+ import { isFile, isWin, spaceFormat } from "lazy-js-utils";
6
+ import { getPkg, getPkgTool, hasPkg, isGo, isInstallPkg, isRust, jsShell, useNodeWorker } from "lazy-js-utils/node";
7
+ import color from "picocolors";
8
+ import { log } from "node:console";
9
+ import fs from "node:fs";
10
+ import os from "node:os";
11
+
12
+ //#region package.json
13
+ var version = "0.1.21";
14
+
15
+ //#endregion
16
+ //#region src/installDeps.ts
17
+ const isZh$6 = process.env.PI_Lang === "zh";
18
+ const gumDocUrl = "https://github.com/charmbracelet/gum";
19
+ const niDocUrl = "https://github.com/antfu/ni";
20
+ async function installDeps(options = {}) {
21
+ const { gum = true, ni = true, strict = true } = options;
22
+ const platform = process.platform;
23
+ if (gum && !await isInstallPkg("gum")) if (platform === "darwin") {
24
+ console.log(color.cyan(isZh$6 ? "正在为您安装必要的依赖gum..." : "Installing gum..."));
25
+ const { status } = await jsShell("brew install gum", [
26
+ "inherit",
27
+ "pipe",
28
+ "inherit"
29
+ ]);
30
+ if (status === 0) console.log(color.cyan(isZh$6 ? "gum 安装成功!" : "gum installed successfully!"));
31
+ else {
32
+ console.log(color.red(isZh$6 ? `gum 安装失败,请尝试从官网解决安装问题! ${gumDocUrl}` : `gum installation failed, please try manual install: ${gumDocUrl}`));
33
+ if (strict) process.exit(1);
34
+ }
35
+ } else console.log(color.yellow(isZh$6 ? `未检测到 gum,请根据系统手动安装: ${gumDocUrl}` : `gum not found, please install it manually: ${gumDocUrl}`));
36
+ if (ni && !await isInstallPkg("ni")) {
37
+ console.log(color.cyan(isZh$6 ? "正在为您安装必要的依赖ni..." : "Installing ni..."));
38
+ const { status } = await jsShell("npm i -g @antfu/ni", [
39
+ "inherit",
40
+ "pipe",
41
+ "inherit"
42
+ ]);
43
+ if (status === 0) console.log(color.cyan(isZh$6 ? "ni 安装成功!" : "ni installed successfully!"));
44
+ else {
45
+ console.log(color.red(isZh$6 ? `ni 安装失败,请尝试从官网解决安装问题! ${niDocUrl}` : `ni installation failed, please try manual install: ${niDocUrl}`));
46
+ if (strict) process.exit(1);
47
+ }
48
+ }
49
+ }
50
+
51
+ //#endregion
52
+ //#region src/help.ts
53
+ const isZh$5 = process.env.PI_Lang === "zh";
54
+ async function ensureGum() {
55
+ if (await isInstallPkg("gum")) return true;
56
+ await installDeps({
57
+ gum: true,
58
+ ni: false,
59
+ strict: false
60
+ });
61
+ return await isInstallPkg("gum");
62
+ }
63
+ function printPlainVersion() {
64
+ console.log(isZh$5 ? `pi 版本: ${version}` : `pi version: ${version}`);
65
+ console.log(isZh$5 ? "请为我的努力点一个行 🌟" : "Please give me a 🌟 for my efforts");
66
+ console.log(isZh$5 ? "谢谢 🤟" : "Thank you 🤟");
67
+ }
68
+ function printPlainHelp() {
69
+ console.log([
70
+ "PI Commands:",
71
+ "~ pi: install package",
72
+ "~ pix: npx package",
73
+ "~ pui: uninstall package",
74
+ "~ prun: run package script",
75
+ "~ pinit: package init",
76
+ "~ pbuild: go build | cargo build",
77
+ "~ pfind: find monorepo of yarn or pnpm",
78
+ "~ pa: agent alias",
79
+ "~ pu: package upgrade",
80
+ "~ pci: package clean install",
81
+ "~ pil: package latest install"
82
+ ].join("\n"));
83
+ }
84
+ async function help(argv) {
85
+ const arg = argv[0];
86
+ if (arg === "-v" || arg === "--version") {
87
+ if (await ensureGum()) await jsShell(isZh$5 ? `gum style \
88
+ --foreground 212 --border-foreground 212 --border double \
89
+ --align center --width 50 --margin "1 2" --padding "2 4" \
90
+ "pi 版本: ${version}" "请为我的努力点一个行 🌟" "谢谢 🤟"` : `gum style \
91
+ --foreground 212 --border-foreground 212 --border double \
92
+ --align center --width 50 --margin "1 2" --padding "2 4" \
93
+ "pi version: ${version}" "Please give me a 🌟 for my efforts" "Thank you 🤟"`, "inherit");
94
+ else printPlainVersion();
95
+ process.exit(0);
96
+ } else if (arg === "-h" || arg === "--help") {
97
+ if (await ensureGum()) await jsShell(`gum style \
98
+ --foreground 212 --border-foreground 212 --border double \
99
+ --align left --width 50 --margin "1 2" --padding "1 1" \
100
+ "PI Commands:" "~ pi: install package" "~ pix: npx package" "~ pui: uninstall package" "~ prun: run package script" "~ pinit: package init" "~ pbuild: go build | cargo build" "~ pfind: find monorepo of yarn or pnpm" "~ pa: agent alias" "~ pu: package upgrade" "~ pci: package clean install" "~ pil: package latest install"
101
+ `, "inherit");
102
+ else printPlainHelp();
103
+ process.exit(0);
104
+ }
105
+ }
106
+
107
+ //#endregion
108
+ //#region src/pa.ts
109
+ function pa() {
110
+ return jsShell("na");
111
+ }
112
+
113
+ //#endregion
114
+ //#region src/detectNode.ts
115
+ const isZh$4 = process.env.PI_Lang === "zh";
116
+ async function detectNode() {
117
+ let pkg;
118
+ try {
119
+ pkg = await getPkg();
120
+ } catch {
121
+ const cwd = process.cwd();
122
+ console.log(color.red(`当前目录: ${cwd} 没有package.json文件`));
123
+ process.exit(1);
124
+ }
125
+ if (pkg.engines?.node) {
126
+ const semver = await import("semver");
127
+ const satisfies = semver.satisfies || semver.default?.satisfies;
128
+ if (!satisfies) return;
129
+ if (!satisfies(process.version, pkg.engines.node)) {
130
+ const hasGum = await isInstallPkg("gum");
131
+ const hasFnm = await isInstallPkg("fnm");
132
+ if (!hasGum || !hasFnm) {
133
+ const missing = [!hasGum ? "gum" : "", !hasFnm ? "fnm" : ""].filter(Boolean).join(", ");
134
+ console.log(color.yellow(isZh$4 ? `当前 node 版本不满足 ${pkg.engines.node},未检测到 ${missing},请手动切换版本。` : `Current Node version does not satisfy ${pkg.engines.node}. Missing ${missing}. Please switch manually.`));
135
+ return;
136
+ }
137
+ const { result, status } = await jsShell(`echo "yes\nno" | gum filter --placeholder=" 当前node版本不满足 ${pkg.engines.node},是否切换node版本"`, [
138
+ "inherit",
139
+ "pipe",
140
+ "inherit"
141
+ ]);
142
+ if (status === 0 && result === "yes") await jsShell(`
143
+ current=$(echo $(fnm current))
144
+ registery=$(echo "$(fnm ls)" | sed 's/system//g' | sed 's/default//g' | sed 's/\* //g' | sed "s/$current/\* $current/g" | gum filter --placeholder=" 请选择一个node版本")
145
+ registery=$(echo $\{registery// /} | sed 's/\*//g')
146
+ if [ $registery ]; then
147
+ fnm use $\{registery% -*}
148
+ fi
149
+ `, [
150
+ "inherit",
151
+ "pipe",
152
+ "inherit"
153
+ ]);
154
+ }
155
+ }
156
+ }
157
+
158
+ //#endregion
159
+ //#region src/utils.ts
160
+ const DW = /\s-DW/g;
161
+ const W = /\s-W/g;
162
+ const Dw = /\s-Dw/g;
163
+ const w = /\s-w/g;
164
+ const D = /\s-D(?!w)/g;
165
+ const d = /\s-d(?!w)/g;
166
+ const isZh$3 = process.env.PI_Lang === "zh";
167
+ const log$1 = console.log;
168
+ async function getParams(params) {
169
+ const root = process.cwd();
170
+ try {
171
+ switch (await getPkgTool()) {
172
+ case "pnpm":
173
+ if (!isFile(path.resolve(root, "./pnpm-workspace.yaml"))) {
174
+ if (DW.test(params)) return params.replace(DW, " -D");
175
+ if (Dw.test(params)) return params.replace(Dw, " -D");
176
+ if (W.test(params)) return params.replace(W, "");
177
+ if (w.test(params)) return params.replace(w, "");
178
+ if (d.test(params)) return params.replace(d, " -D");
179
+ }
180
+ if (isFile("./pnpm-workspace.yaml")) {
181
+ if (D.test(params)) return params.replace(D, " -Dw");
182
+ if (d.test(params)) return params.replace(d, " -Dw");
183
+ if (!params || Dw.test(params) || w.test(params)) return params;
184
+ return `${params} -w`;
185
+ }
186
+ if (DW.test(params)) return params.replace(DW, " -Dw");
187
+ if (W.test(params)) return params.replace(W, " -w");
188
+ return params;
189
+ case "yarn":
190
+ if (!(await getPkg(path.resolve(root, "./package.json")))?.workspaces) {
191
+ if (Dw.test(params)) return params.replace(Dw, " -D");
192
+ if (DW.test(params)) return params.replace(DW, " -D");
193
+ if (W.test(params)) return params.replace(W, "");
194
+ if (w.test(params)) return params.replace(w, "");
195
+ if (d.test(params)) return params.replace(d, " -D");
196
+ }
197
+ if ((await getPkg())?.workspaces) {
198
+ if (D.test(params)) return params.replace(D, " -DW");
199
+ if (d.test(params)) return params.replace(d, " -DW");
200
+ if (!params || W.test(params) || DW.test(params)) return params;
201
+ return `${params} -W`;
202
+ }
203
+ if (Dw.test(params)) return params.replace(Dw, " -DW");
204
+ if (W.test(params)) return params.replace(W, " -W");
205
+ return params;
206
+ default: return d.test(params) ? params.replace(d, " -D") : params;
207
+ }
208
+ } catch {
209
+ console.log(color.red(`${isZh$3 ? "package.json并不存在,在以下目录中:" : "package.json has not been found in"} ${process.cwd()}`));
210
+ process.exit(1);
211
+ }
212
+ }
213
+ async function loading(text, isSilent = false) {
214
+ const { color, spinner } = await getStyle();
215
+ const ora = (await import("ora")).default;
216
+ return ora({
217
+ text,
218
+ spinner,
219
+ color,
220
+ isSilent,
221
+ discardStdin: true
222
+ }).start();
223
+ }
224
+ async function getStyle() {
225
+ const { PI_COLOR: color = "yellow", PI_SPINNER: spinner = "star" } = process.env;
226
+ return {
227
+ color,
228
+ spinner
229
+ };
230
+ }
231
+ async function getLatestVersion(pkg, isZh = true) {
232
+ const data = [];
233
+ for (const p of pkg.replace(/\s+/, " ").split(" ")) {
234
+ const [pName, v] = p.split("$");
235
+ let { status, result } = await jsShell(`npm view ${pName}`, [
236
+ "inherit",
237
+ "pipe",
238
+ "inherit"
239
+ ]);
240
+ if (status === 0) {
241
+ if (result.startsWith("@")) result = result.slice(1);
242
+ const item = isZh ? `${pName} ${color.gray(v)} -> ${result.match(/@(\S+)/)[1]}` : `Installed ${pName} ${color.dim(v)} -> latest version:${result.match(/@(\S+)/)[1]}`;
243
+ data.push(item);
244
+ } else throw new Error(result);
245
+ }
246
+ return `${data.join(" ")}${isZh ? " 安装成功! 😊" : " successfully! 😊"}`;
247
+ }
248
+ async function pushHistory(command) {
249
+ log$1(color.bold(color.blue(`${isZh$3 ? "快捷指令" : "shortcut command"}: ${command}`)));
250
+ const shellName = (process.env.SHELL || "/bin/bash").split("/").pop() || "bash";
251
+ let historyFile = "";
252
+ let historyFormat = "bash";
253
+ const home = process.env.HOME || os.homedir();
254
+ switch (shellName) {
255
+ case "zsh":
256
+ historyFile = path.join(home, ".zsh_history");
257
+ historyFormat = "zsh";
258
+ break;
259
+ case "bash":
260
+ historyFile = process.env.HISTFILE || path.join(home, ".bash_history");
261
+ historyFormat = "bash";
262
+ break;
263
+ case "fish":
264
+ historyFile = path.join(home, ".local", "share", "fish", "fish_history");
265
+ historyFormat = "fish";
266
+ break;
267
+ default:
268
+ historyFile = process.env.HISTFILE || path.join(home, ".bash_history");
269
+ historyFormat = "bash";
270
+ }
271
+ try {
272
+ if (!fs.existsSync(historyFile)) {
273
+ log$1(color.yellow(`${isZh$3 ? `未找到 ${shellName} 历史文件` : `${shellName} history file not found`}`));
274
+ return;
275
+ }
276
+ const raw = fs.readFileSync(historyFile, "utf8");
277
+ const timestamp = Math.floor(Date.now() / 1e3);
278
+ let newEntry = "";
279
+ if (historyFormat === "zsh") newEntry = `: ${timestamp}:0;${command}`;
280
+ else if (historyFormat === "fish") newEntry = `- cmd: ${command}\n when: ${timestamp}`;
281
+ else if (process.env.HISTTIMEFORMAT) newEntry = `#${timestamp}\n${command}`;
282
+ else newEntry = command;
283
+ function parseEntries(content) {
284
+ if (historyFormat === "fish") {
285
+ const lines = content.split(/\r?\n/);
286
+ const blocks = [];
287
+ let buffer = [];
288
+ for (const line of lines) if (line.startsWith("- cmd: ")) {
289
+ if (buffer.length) {
290
+ blocks.push(buffer.join("\n"));
291
+ buffer = [];
292
+ }
293
+ buffer.push(line);
294
+ } else if (buffer.length) buffer.push(line);
295
+ else if (line.trim() !== "") blocks.push(line);
296
+ if (buffer.length) blocks.push(buffer.join("\n"));
297
+ return blocks.filter(Boolean);
298
+ } else if (historyFormat === "zsh") return content.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
299
+ else {
300
+ const lines = content.split(/\r?\n/);
301
+ const entries = [];
302
+ for (let i = 0; i < lines.length; i++) {
303
+ const line = lines[i];
304
+ if (line.startsWith("#")) {
305
+ const next = lines[i + 1] ?? "";
306
+ entries.push(`${line}\n${next}`);
307
+ i++;
308
+ } else if (line.trim() !== "") entries.push(line);
309
+ }
310
+ return entries;
311
+ }
312
+ }
313
+ const entries = parseEntries(raw);
314
+ function extractCommand(entry) {
315
+ if (historyFormat === "fish") {
316
+ const m = entry.split("\n")[0].match(/^- cmd: (.*)$/);
317
+ return m ? m[1] : entry;
318
+ } else if (historyFormat === "zsh") {
319
+ const m = entry.match(/^[^;]*;(.+)$/);
320
+ return m ? m[1] : entry;
321
+ } else {
322
+ if (entry.startsWith("#")) {
323
+ const parts = entry.split(/\r?\n/);
324
+ return parts[1] ?? parts[0];
325
+ }
326
+ return entry;
327
+ }
328
+ }
329
+ const newEntries = [];
330
+ const newCmd = extractCommand(newEntry);
331
+ let existingFishBlock = null;
332
+ for (const e of entries) {
333
+ if (extractCommand(e) === newCmd) {
334
+ if (historyFormat === "fish") {
335
+ existingFishBlock = e;
336
+ continue;
337
+ }
338
+ continue;
339
+ }
340
+ newEntries.push(e);
341
+ }
342
+ if (historyFormat === "fish" && existingFishBlock) {
343
+ const lines = existingFishBlock.split("\n");
344
+ let hasWhen = false;
345
+ const updated = lines.map((line) => {
346
+ if (line.trim().startsWith("when:") || line.startsWith(" when:")) {
347
+ hasWhen = true;
348
+ return ` when: ${timestamp}`;
349
+ }
350
+ return line;
351
+ });
352
+ if (!hasWhen) updated.splice(1, 0, ` when: ${timestamp}`);
353
+ newEntries.push(updated.join("\n"));
354
+ } else newEntries.push(newEntry);
355
+ let finalContent = "";
356
+ if (historyFormat === "fish") finalContent = `${newEntries.map((e) => e.trimEnd()).join("\n")}\n`;
357
+ else finalContent = `${newEntries.join("\n")}\n`;
358
+ const tmpPath = `${historyFile}.ccommand.tmp`;
359
+ fs.writeFileSync(tmpPath, finalContent, "utf8");
360
+ fs.renameSync(tmpPath, historyFile);
361
+ } catch (err) {
362
+ log$1(color.red(`${isZh$3 ? `❌ 添加到 ${shellName} 历史记录失败` : `❌ Failed to add to ${shellName} history`}${err ? `: ${String(err)}` : ""}`));
363
+ }
364
+ }
365
+
366
+ //#endregion
367
+ //#region src/pi.ts
368
+ const isZh$2 = process.env.PI_Lang === "zh";
369
+ async function pi(params, pkg, executor = "ni") {
370
+ await detectNode();
371
+ const text = pkg ? `Installing ${params} ...` : "Updating dependency ...";
372
+ const isLatest = executor === "pil";
373
+ const start = Date.now();
374
+ let successMsg = "";
375
+ if (isLatest) successMsg = await getLatestVersion(pkg, isZh$2);
376
+ else successMsg = pkg ? isZh$2 ? `${pkg} 安装成功! 😊` : `Installed ${pkg} successfully! 😊` : isZh$2 ? "依赖更新成功! 😊" : "Updated dependency successfully! 😊";
377
+ const failMsg = pkg ? isZh$2 ? `${params} 安装失败 😭` : `Failed to install ${params} 😭` : isZh$2 ? "依赖更新失败 😭" : "Failed to update dependency 😭";
378
+ const isSilent = process.env.PI_SILENT === "true";
379
+ let stdio = isSilent ? "inherit" : [
380
+ "inherit",
381
+ "pipe",
382
+ "inherit"
383
+ ];
384
+ let loading_status;
385
+ const { PI_DEFAULT, PI_MaxSockets: sockets } = process.env;
386
+ const pkgTool = await getPkgTool();
387
+ const maxSockets = sockets || 4;
388
+ const install = !params ? "install" : "add";
389
+ if (pkgTool === "npm") if (PI_DEFAULT) {
390
+ executor = `${PI_DEFAULT} ${install}`;
391
+ loading_status = await loading(text, isSilent);
392
+ } else {
393
+ stdio = "inherit";
394
+ executor = "ni";
395
+ }
396
+ else {
397
+ executor = `${pkgTool} ${install}`;
398
+ loading_status = await loading(text, isSilent);
399
+ }
400
+ const newParams = isLatest ? "" : await getParams(params);
401
+ const runSockets = executor.split(" ")[0] === "npm" ? ` --max-sockets=${maxSockets}` : "";
402
+ const latestParams = Array.isArray(params) ? params : params ? [params] : [];
403
+ const cmdList = isLatest ? latestParams.map((p) => `${executor} ${p}`) : [`${executor}${newParams ? ` ${newParams}` : runSockets}`];
404
+ const runCmd = isLatest ? cmdList.join(" & ") : cmdList[0];
405
+ const runCommands = async (commands) => {
406
+ const results = await Promise.all(commands.map((command) => useNodeWorker({
407
+ params: command,
408
+ stdio,
409
+ errorExit: false
410
+ })));
411
+ const failed = results.find((r) => r.status !== 0);
412
+ const merged = results.map((r) => r.result).filter(Boolean).join("\n");
413
+ return {
414
+ status: failed ? failed.status : 0,
415
+ result: failed?.result || merged
416
+ };
417
+ };
418
+ let { status, result } = await runCommands(cmdList);
419
+ if (result && result.includes("pnpm versions with respective Node.js version support")) {
420
+ log(result);
421
+ log(color.yellow(isZh$2 ? "正在尝试使用 npm 再次执行..." : "Trying to use npm to run again..."));
422
+ const fallbackCommands = isLatest ? latestParams.map((p) => `npm install ${p}`) : [`npm install${newParams ? ` ${newParams}` : runSockets}`];
423
+ const fallbackResults = await Promise.all(fallbackCommands.map((command) => jsShell(command, { stdio })));
424
+ const fallbackFailed = fallbackResults.find((r) => r.status !== 0);
425
+ const fallbackMerged = fallbackResults.map((r) => r.result).filter(Boolean).join("\n");
426
+ status = fallbackFailed ? fallbackFailed.status : 0;
427
+ result = fallbackFailed?.result || fallbackMerged;
428
+ }
429
+ if (stdio === "inherit") loading_status = await loading("");
430
+ const costTime = (Date.now() - start) / 1e3;
431
+ successMsg += color.blue(` ---- ⏰:${costTime}s`);
432
+ if (status === 0) {
433
+ loading_status.succeed(color.green(successMsg));
434
+ pushHistory(runCmd);
435
+ } else if (result && result.includes("Not Found - 404")) {
436
+ const _pkg = result.match(/\/[^/:]+:/)?.[0].slice(1, -1);
437
+ const _result = isZh$2 ? `${_pkg} 包名可能有误或者版本号不存在,并不能在npm中搜索到,请检查` : `${_pkg} the package name may be wrong, and cannot be found in npm, please check`;
438
+ loading_status.fail(color.red(result ? `${failMsg}\n${_result}` : failMsg));
439
+ } else loading_status.fail(color.red(result ? `${failMsg}\n${result}` : failMsg));
440
+ if (result) {
441
+ const match = result.match(/ERR_PNPM_NO_MATCHING_VERSION_INSIDE_WORKSPACE\u2009 In : No matching version found for\s+([^@]+)/);
442
+ if (match) {
443
+ const dep = match[1];
444
+ jsShell(`pi ${dep}@latest`);
445
+ }
446
+ }
447
+ process.exit();
448
+ }
449
+
450
+ //#endregion
451
+ //#region src/pci.ts
452
+ function pci(params, pkg) {
453
+ return pi(params, pkg, "nci");
454
+ }
455
+
456
+ //#endregion
457
+ //#region src/require.ts
458
+ const entry = process.argv[1];
459
+ const base = entry ? path.resolve(entry) : path.join(process.cwd(), "index.js");
460
+ const localRequire = createRequire(base);
461
+
462
+ //#endregion
463
+ //#region src/pfind.ts
464
+ function pfind(params) {
465
+ const { ccommand } = localRequire("ccommand");
466
+ return ccommand(`find ${params}`);
467
+ }
468
+
469
+ //#endregion
470
+ //#region src/pil.ts
471
+ async function pil(params) {
472
+ const isZh = process.env.PI_Lang === "zh";
473
+ const { dependencies = {}, devDependencies = {} } = await getPkg();
474
+ if (!params) {
475
+ if (!await isInstallPkg("gum")) {
476
+ console.log(color.yellow(isZh ? "未检测到 gum,请先安装 gum 后再选择依赖。" : "gum not found. Please install gum before selecting dependencies."));
477
+ process.exit(1);
478
+ }
479
+ const { result: choose, status } = await jsShell(`echo ${[...Object.keys(dependencies).map((key) => `${key}: ${dependencies[key].replace(/([><~])/g, "\\$1")}`), ...Object.keys(devDependencies).map((key) => `${key}: ${devDependencies[key].replace(/([><~])/g, "\\$1")}`)].join(",")} | sed "s/,/\\n/g" | gum filter --no-limit --placeholder=" 🤔${process.env.PI_Lang === "zh" ? "请选择一个需要获取最新版本的依赖" : "Please select a dependency that needs to obtain the latest version."}"`, { stdio: [
480
+ "inherit",
481
+ "pipe",
482
+ "inherit"
483
+ ] });
484
+ if (status === 130) {
485
+ console.log(color.dim("已取消"));
486
+ process.exit(0);
487
+ } else if (status !== 0) throw new Error(choose);
488
+ params = choose.trim().split("\n").map((i) => {
489
+ const name = i.split(": ")[0];
490
+ if (name in devDependencies) return `${name}@latest -D`;
491
+ return `${name}@latest -S`;
492
+ }).join(" ");
493
+ }
494
+ let latestPkgname = params;
495
+ const reg = /\s(-[dws]+)/gi;
496
+ const suffix = [];
497
+ const command = latestPkgname = (await getParams(params)).replace(reg, (_, k) => {
498
+ suffix.push(k);
499
+ return "";
500
+ });
501
+ latestPkgname = latestPkgname.replace(/@latest/g, "").split(" ").filter(Boolean).map((i) => {
502
+ return `${i}$${dependencies[i] || devDependencies[i]}`;
503
+ }).join(" ");
504
+ const pkgs = command.replace(/\s+/, " ").trim().split(" ").filter(Boolean).filter((t) => !t.startsWith("-"));
505
+ let globalWorkspaceFlag = null;
506
+ const perFlags = [];
507
+ let assignIdx = 0;
508
+ for (const f of suffix) {
509
+ if (/^-(?:w|W)$/.test(f)) {
510
+ globalWorkspaceFlag = f;
511
+ continue;
512
+ }
513
+ perFlags[assignIdx++] = f;
514
+ }
515
+ const normalizeFlag = (f) => {
516
+ if (!f) return "";
517
+ if (/^-s$/i.test(f) || /^-S$/.test(f)) return "";
518
+ return f;
519
+ };
520
+ const combineWorkspace = (f, w) => {
521
+ if (!w) return f;
522
+ if (/w/i.test(f)) return f;
523
+ if (!f) return w;
524
+ if (/d/i.test(f)) return `-D${w.slice(1)}`;
525
+ return w;
526
+ };
527
+ const finalFlags = pkgs.map((_, i) => combineWorkspace(normalizeFlag(perFlags[i]), globalWorkspaceFlag));
528
+ const group = {};
529
+ pkgs.forEach((p, i) => {
530
+ const key = finalFlags[i] || "";
531
+ if (!group[key]) group[key] = [];
532
+ group[key].push(p);
533
+ });
534
+ return await pi(Object.entries(group).map(([flag, list]) => `${list.join(" ")}${flag ? ` ${flag}` : ""}`), latestPkgname.replace(/@latest/g, ""), "pil");
535
+ }
536
+
537
+ //#endregion
538
+ //#region src/pinit.ts
539
+ async function pinit() {
540
+ console.log("Initializing project...");
541
+ switch (await getPkgTool()) {
542
+ case "npm":
543
+ await jsShell("npm init -y");
544
+ return;
545
+ case "yarn":
546
+ await jsShell("yarn init -y");
547
+ return;
548
+ case "pnpm":
549
+ await jsShell("pnpm init -y");
550
+ return;
551
+ default: await jsShell("npm init -y");
552
+ }
553
+ }
554
+
555
+ //#endregion
556
+ //#region src/pio.ts
557
+ async function pio(params, pkg, executor = "ni") {
558
+ const successMsg = pkg ? `Installed ${pkg} successfully! 😊` : "Updated dependency successfully! 😊";
559
+ const failMsg = pkg ? `Failed to install ${pkg} 😭` : "Failed to update dependency! 😭";
560
+ const { status, result } = await useNodeWorker({
561
+ params: `${executor} ${await getParams(params)} --prefer-offline`,
562
+ stdio: "inherit"
563
+ });
564
+ const loading_status = await loading("");
565
+ if (status === 0) loading_status.succeed(color.green(successMsg));
566
+ else loading_status.fail(color.red(result ? `${result}\n\n${failMsg}` : failMsg));
567
+ process.exit();
568
+ }
569
+
570
+ //#endregion
571
+ //#region src/pix.ts
572
+ async function pix(params) {
573
+ switch (await getPkgTool()) {
574
+ case "bun": return jsShell(`bunx ${params}`);
575
+ default: return jsShell(`npx ${params}`);
576
+ }
577
+ }
578
+
579
+ //#endregion
580
+ //#region src/prun.ts
581
+ function prun(params) {
582
+ const { ccommand } = localRequire("ccommand");
583
+ return ccommand(params);
584
+ }
585
+
586
+ //#endregion
587
+ //#region src/pu.ts
588
+ function pu() {
589
+ return jsShell("nu");
590
+ }
591
+
592
+ //#endregion
593
+ //#region src/pui.ts
594
+ const isZh$1 = process.env.PI_Lang === "zh";
595
+ async function pui(params, pkg) {
596
+ const text = `${isZh$1 ? "正在为您卸载" : "Uninstalling"} ${pkg} ...`;
597
+ if (!params) {
598
+ const { dependencies = {}, devDependencies = {} } = await getPkg();
599
+ const { result: choose, status } = await jsShell(`echo ${[...Object.keys(dependencies).map((key) => `${key}: ${dependencies[key]}`), ...Object.keys(devDependencies).map((key) => `${key}: ${devDependencies[key]}`)].join(",")} | sed "s/,/\\n/g" | gum filter --placeholder=" 🤔${process.env.PI_Lang === "zh" ? "请选择一个需要删除依赖" : "Please select a dependency to get the latest version."}"`, [
600
+ "inherit",
601
+ "pipe",
602
+ "inherit"
603
+ ]);
604
+ if (status === 130) {
605
+ console.log(color.dim("已取消"));
606
+ process.exit(0);
607
+ } else if (status !== 0) throw new Error(choose);
608
+ pkg = params = choose.split(": ")[0];
609
+ }
610
+ const start = Date.now();
611
+ let successMsg = isZh$1 ? `${pkg}卸载成功! 😊` : `UnInstalled ${pkg} successfully! 😊`;
612
+ const failMsg = isZh$1 ? `${pkg}卸载失败 😭` : `Failed to uninstall ${pkg} 😭`;
613
+ if (!pkg) {
614
+ console.log(color.yellow(isZh$1 ? "需要指定要卸载的包名!" : "Need to specify an uninstall package name!"));
615
+ process.exit(1);
616
+ }
617
+ const loading_status = await loading(text);
618
+ const { status, result } = await useNodeWorker(`nun ${params}`);
619
+ const costTime = (Date.now() - start) / 1e3;
620
+ successMsg += color.blue(` ---- ⏰:${costTime}s`);
621
+ if (status === 0) loading_status.succeed(color.green(successMsg));
622
+ else loading_status.fail(color.red(result ? `${failMsg}\n${result}` : failMsg));
623
+ process.exit();
624
+ }
625
+
626
+ //#endregion
627
+ //#region src/index.ts
628
+ let rootPath = process.cwd();
629
+ const runMap = {
630
+ pi,
631
+ "pi.mjs": pi,
632
+ pix,
633
+ "pix.mjs": pix,
634
+ pa,
635
+ "pa.mjs": pa,
636
+ pui,
637
+ "pui.mjs": pui,
638
+ pu,
639
+ "pu.mjs": pu,
640
+ pil,
641
+ "pil.mjs": pil,
642
+ pci,
643
+ "pci.mjs": pci,
644
+ prun,
645
+ "prun.mjs": prun,
646
+ pinit,
647
+ "pinit.mjs": pinit,
648
+ pfind,
649
+ "pfind.mjs": pfind,
650
+ pio,
651
+ "pio.mjs": pio
652
+ };
653
+ const isZh = process.env.PI_Lang === "zh";
654
+ async function setup() {
655
+ const cmd = process.argv[1];
656
+ let exec = "";
657
+ if (isWin()) {
658
+ const last = cmd.lastIndexOf("\\") + 1;
659
+ exec = cmd.slice(last, cmd.length).split(".").slice(0, -1).join(".");
660
+ } else {
661
+ const last = cmd.lastIndexOf("/") + 1;
662
+ exec = cmd.slice(last, cmd.length);
663
+ }
664
+ const argv = process.argv.slice(2);
665
+ await help(argv);
666
+ let params = spaceFormat(argv.join(" ")).trim();
667
+ if (!await hasPkg(rootPath)) {
668
+ if (await isGo(rootPath)) {
669
+ if (exec === "pi") {
670
+ const loading_status = await loading(`${isZh ? "正在为您安装" : "Installing"} ${params} ...\n`);
671
+ const { status } = params ? await useNodeWorker(`go get ${params}`) : await useNodeWorker("go mod tidy");
672
+ if (status === 0) loading_status.succeed(color.green(isZh ? "安装成功! 😊" : "Installed successfully! 😊"));
673
+ else loading_status.fail(color.red(isZh ? "安装失败 😭" : "Failed to install 😭"));
674
+ } else if (exec === "pui") {
675
+ const loading_status = await loading(`${isZh ? "正在为您卸载" : "Uninstalling"} ${params} ...\n`);
676
+ const { status } = await useNodeWorker(`go clean ${params}`);
677
+ if (status === 0) loading_status.succeed(color.green(isZh ? "卸载成功! 😊" : "Uninstalled successfully! 😊"));
678
+ else loading_status.fail(color.red(isZh ? "卸载失败 😭" : "Failed to uninstall 😭"));
679
+ } else if (exec === "prun") {
680
+ const target = (await fg(params ? params.endsWith(".go") ? [`**/${params}`] : [`**/${params}.go`, `**/${params}/main.go`] : "main.go"))[0];
681
+ if (target) return await jsShell(`go run ${target}`, "inherit");
682
+ const { ccommand } = localRequire("ccommand");
683
+ return ccommand(params);
684
+ } else if (exec === "pinit") await jsShell(`go mod init ${params}`, "inherit");
685
+ else if (exec === "pbuild") await jsShell(`go build ${params}`, "inherit");
686
+ else console.log(color.red(isZh ? "当前指令还不支持" : "The commands is not supported"));
687
+ process.exit();
688
+ }
689
+ let projectPath = "";
690
+ if (params && !await isRust()) {
691
+ projectPath = params.split(" ")[0];
692
+ rootPath = path.resolve(rootPath, projectPath);
693
+ params = params.replace(projectPath, "").trim();
694
+ }
695
+ if (await isRust(rootPath)) {
696
+ if (exec === "pi") {
697
+ const loading_status = await loading(`${isZh ? "正在为您安装" : "Installing"} ${params} ...\n`);
698
+ const { status } = await useNodeWorker(`cargo install ${params}${projectPath ? `--manifest-path=./${projectPath}/Cargo.toml` : ""}`);
699
+ if (status === 0) loading_status.succeed(color.green(isZh ? "安装成功! 😊" : "Installed successfully! 😊"));
700
+ else loading_status.fail(color.red(isZh ? "安装失败 😭" : "Failed to install 😭"));
701
+ } else if (exec === "pui") {
702
+ const loading_status = await loading(`${isZh ? "正在为您卸载" : "Uninstalling"} ${params} ...\n`);
703
+ const { status } = await useNodeWorker(`cargo uninstall ${params}${projectPath ? `--manifest-path=./${projectPath}/Cargo.toml` : ""}`);
704
+ if (status === 0) loading_status.succeed(color.green(isZh ? "卸载成功! 😊" : "Uninstalled successfully! 😊"));
705
+ else loading_status.fail(color.red(isZh ? "卸载失败 😭" : "Failed to uninstall 😭"));
706
+ } else if (exec === "prun") await jsShell(`cargo run ${params}${projectPath ? `--manifest-path=./${projectPath}/Cargo.toml` : ""}`, "inherit");
707
+ else if (exec === "pinit") await jsShell(`cargo init ${params}${projectPath ? `--manifest-path=./${projectPath}/Cargo.toml` : ""}`, "inherit");
708
+ else if (exec === "pbuild") await jsShell(`cargo build ${params}${projectPath ? `--manifest-path=./${projectPath}/Cargo.toml` : ""}`, "inherit");
709
+ else console.log(color.red(isZh ? "当前指令还不支持" : "The commands is not supported"));
710
+ process.exit();
711
+ }
712
+ }
713
+ const handler = runMap[exec];
714
+ if (!handler) {
715
+ if (exec === "pbuild" || exec === "pbuild.mjs") console.log(color.yellow(isZh ? "pbuild 仅支持 Go/Rust 项目(go build / cargo build)。" : "pbuild is only supported for Go/Rust projects (go build / cargo build)."));
716
+ else console.log(color.yellow(isZh ? "命令不存在, 请执行 pi -h 查看帮助" : "The command does not exist, please execute pi -h to view the help"));
717
+ return;
718
+ }
719
+ const pkg = argv.filter((v) => !v.startsWith("-")).join(" ");
720
+ await installDeps();
721
+ await handler(params, pkg);
722
+ }
723
+ if (!process.env.PI_TEST) setup().catch((error) => {
724
+ console.error(error);
725
+ process.exit(1);
726
+ });
727
+
728
+ //#endregion
729
+ export { setup };