From 3e630785bb4dba96cefd8b6c49a51da7ccf4b86e Mon Sep 17 00:00:00 2001 From: zuiidea Date: Tue, 14 Apr 2026 22:32:59 +0800 Subject: [PATCH] feat(create): detect package managers and run install Made-with: Cursor --- packages/create/src/install.ts | 22 ++++++++++++++++ packages/create/src/package-manager.ts | 35 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 packages/create/src/install.ts create mode 100644 packages/create/src/package-manager.ts diff --git a/packages/create/src/install.ts b/packages/create/src/install.ts new file mode 100644 index 0000000..3ba4af6 --- /dev/null +++ b/packages/create/src/install.ts @@ -0,0 +1,22 @@ +import { spawnSync } from "node:child_process"; +import type { PackageManagerName } from "./package-manager.js"; +import { spawnInstall } from "./package-manager.js"; +import { CliError } from "./errors.js"; + +export function installDependencies( + cwd: string, + manager: PackageManagerName +): void { + const { cmd, args } = spawnInstall(manager); + const res = spawnSync(cmd, args, { + cwd, + stdio: "inherit", + env: { ...process.env, CI: "1" }, + }); + if (res.error || res.status !== 0) { + throw new CliError( + `${cmd} ${args.join(" ")} failed in ${cwd}`, + "INSTALL_FAILED" + ); + } +} diff --git a/packages/create/src/package-manager.ts b/packages/create/src/package-manager.ts new file mode 100644 index 0000000..ecc374f --- /dev/null +++ b/packages/create/src/package-manager.ts @@ -0,0 +1,35 @@ +import { spawnSync } from "node:child_process"; + +export type PackageManagerName = "npm" | "pnpm" | "yarn" | "bun"; + +const ORDER: PackageManagerName[] = ["pnpm", "npm", "yarn", "bun"]; + +export function isManagerAvailable(name: PackageManagerName): boolean { + const result = spawnSync(name, ["--version"], { stdio: "ignore" }); + return result.status === 0; +} + +export function detectAvailableManagers(): PackageManagerName[] { + return ORDER.filter(isManagerAvailable); +} + +/** Install argv; cwd is applied by install.ts via spawnSync `cwd` option. */ +export function spawnInstall(name: PackageManagerName): { + cmd: string; + args: string[]; +} { + switch (name) { + case "pnpm": + return { cmd: "pnpm", args: ["install"] }; + case "npm": + return { cmd: "npm", args: ["install"] }; + case "yarn": + return { cmd: "yarn", args: ["install"] }; + case "bun": + return { cmd: "bun", args: ["install"] }; + default: { + const _: never = name; + throw new Error(`unsupported manager ${_}`); + } + } +}