lattice-ui 0.4.3

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.
Files changed (71) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +45 -0
  3. package/dist/cli.d.ts +1 -0
  4. package/dist/cli.js +426 -0
  5. package/dist/commands/add.d.ts +3 -0
  6. package/dist/commands/add.js +156 -0
  7. package/dist/commands/create.d.ts +23 -0
  8. package/dist/commands/create.js +351 -0
  9. package/dist/commands/doctor.d.ts +2 -0
  10. package/dist/commands/doctor.js +164 -0
  11. package/dist/commands/init.d.ts +21 -0
  12. package/dist/commands/init.js +547 -0
  13. package/dist/commands/remove.d.ts +3 -0
  14. package/dist/commands/remove.js +113 -0
  15. package/dist/commands/selection.d.ts +6 -0
  16. package/dist/commands/selection.js +27 -0
  17. package/dist/commands/upgrade.d.ts +3 -0
  18. package/dist/commands/upgrade.js +150 -0
  19. package/dist/core/errors.d.ts +21 -0
  20. package/dist/core/errors.js +52 -0
  21. package/dist/core/fs/copy.d.ts +13 -0
  22. package/dist/core/fs/copy.js +129 -0
  23. package/dist/core/fs/json.d.ts +3 -0
  24. package/dist/core/fs/json.js +163 -0
  25. package/dist/core/fs/patch.d.ts +16 -0
  26. package/dist/core/fs/patch.js +89 -0
  27. package/dist/core/logger.d.ts +27 -0
  28. package/dist/core/logger.js +166 -0
  29. package/dist/core/npm/latest.d.ts +1 -0
  30. package/dist/core/npm/latest.js +40 -0
  31. package/dist/core/output.d.ts +8 -0
  32. package/dist/core/output.js +20 -0
  33. package/dist/core/pm/detect.d.ts +18 -0
  34. package/dist/core/pm/detect.js +147 -0
  35. package/dist/core/pm/npm.d.ts +2 -0
  36. package/dist/core/pm/npm.js +48 -0
  37. package/dist/core/pm/pnpm.d.ts +2 -0
  38. package/dist/core/pm/pnpm.js +48 -0
  39. package/dist/core/pm/types.d.ts +8 -0
  40. package/dist/core/pm/types.js +2 -0
  41. package/dist/core/pm/yarn.d.ts +2 -0
  42. package/dist/core/pm/yarn.js +48 -0
  43. package/dist/core/project/findRoot.d.ts +1 -0
  44. package/dist/core/project/findRoot.js +60 -0
  45. package/dist/core/project/readPackageJson.d.ts +13 -0
  46. package/dist/core/project/readPackageJson.js +41 -0
  47. package/dist/core/project/writePackageJson.d.ts +2 -0
  48. package/dist/core/project/writePackageJson.js +41 -0
  49. package/dist/core/prompt.d.ts +23 -0
  50. package/dist/core/prompt.js +217 -0
  51. package/dist/core/registry/load.d.ts +3 -0
  52. package/dist/core/registry/load.js +59 -0
  53. package/dist/core/registry/schema.d.ts +18 -0
  54. package/dist/core/registry/schema.js +87 -0
  55. package/dist/ctx.d.ts +27 -0
  56. package/dist/ctx.js +75 -0
  57. package/dist/index.d.ts +2 -0
  58. package/dist/index.js +21 -0
  59. package/package.json +27 -0
  60. package/registry/components.json +118 -0
  61. package/registry/presets.json +6 -0
  62. package/templates/init/default.project.json.template +67 -0
  63. package/templates/init/package.json +22 -0
  64. package/templates/init/src/client/App.tsx +21 -0
  65. package/templates/init/src/client/main.client.tsx +26 -0
  66. package/templates/init/src/server/main.server.ts +3 -0
  67. package/templates/init/src/shared/constants.ts +1 -0
  68. package/templates/init/tsconfig.json +27 -0
  69. package/templates/init-lint/.prettierrc +7 -0
  70. package/templates/init-lint/eslint.config.mjs +51 -0
  71. package/templates/init-lint/package.json +19 -0
@@ -0,0 +1,27 @@
1
+ export interface Spinner {
2
+ succeed(message?: string): void;
3
+ fail(message?: string): void;
4
+ stop(message?: string): void;
5
+ }
6
+ export interface Logger {
7
+ readonly verbose: boolean;
8
+ info(message: string): void;
9
+ success(message: string): void;
10
+ warn(message: string): void;
11
+ error(message: string): void;
12
+ debug(message: string): void;
13
+ section(title: string): void;
14
+ kv(label: string, value: string): void;
15
+ step(message: string): void;
16
+ list(items: string[]): void;
17
+ confirm(message: string): Promise<boolean>;
18
+ spinner(message: string): Spinner;
19
+ }
20
+ export interface LoggerOptions {
21
+ verbose: boolean;
22
+ yes: boolean;
23
+ stdin?: NodeJS.ReadStream;
24
+ stdout?: NodeJS.WriteStream;
25
+ stderr?: NodeJS.WriteStream;
26
+ }
27
+ export declare function createLogger(options: LoggerOptions): Logger;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLogger = createLogger;
4
+ const promises_1 = require("node:readline/promises");
5
+ const FRAMES = ["-", "\\", "|", "/"];
6
+ const ICONS = {
7
+ tty: {
8
+ info: "?",
9
+ success: "✔",
10
+ warn: "⚠",
11
+ error: "✖",
12
+ step: "›",
13
+ debug: "·",
14
+ },
15
+ plain: {
16
+ info: "[?]",
17
+ success: "[+]",
18
+ warn: "[!]",
19
+ error: "[x]",
20
+ step: "[>]",
21
+ debug: "[d]",
22
+ },
23
+ };
24
+ const ANSI = {
25
+ reset: "\u001b[0m",
26
+ cyan: "\u001b[36m",
27
+ green: "\u001b[32m",
28
+ yellow: "\u001b[33m",
29
+ red: "\u001b[31m",
30
+ magenta: "\u001b[35m",
31
+ gray: "\u001b[90m",
32
+ bold: "\u001b[1m",
33
+ };
34
+ function isTTY(stdout, stderr) {
35
+ return Boolean(stdout.isTTY || stderr.isTTY);
36
+ }
37
+ function colorize(enabled, color, text) {
38
+ if (!enabled) {
39
+ return text;
40
+ }
41
+ return `${color}${text}${ANSI.reset}`;
42
+ }
43
+ function createLogger(options) {
44
+ const stdin = options.stdin ?? process.stdin;
45
+ const stdout = options.stdout ?? process.stdout;
46
+ const stderr = options.stderr ?? process.stderr;
47
+ const useColor = isTTY(stdout, stderr);
48
+ const useUnicodeIcons = isTTY(stdout, stderr);
49
+ function icon(kind) {
50
+ return useUnicodeIcons ? ICONS.tty[kind] : ICONS.plain[kind];
51
+ }
52
+ function write(stream, iconKey, message, color, tokenOnlyColor = true, leadingNewline = false) {
53
+ const token = icon(iconKey);
54
+ const decoratedToken = tokenOnlyColor ? colorize(useColor, color, token) : token;
55
+ const decoratedMessage = tokenOnlyColor ? message : colorize(useColor, color, message);
56
+ const prefix = token.length > 0 ? `${decoratedToken} ` : "";
57
+ stream.write(`${leadingNewline ? "\n" : ""}${prefix}${decoratedMessage}\n`);
58
+ }
59
+ return {
60
+ verbose: options.verbose,
61
+ info(message) {
62
+ write(stdout, "info", message, ANSI.cyan);
63
+ },
64
+ success(message) {
65
+ write(stdout, "success", message, ANSI.green);
66
+ },
67
+ warn(message) {
68
+ write(stderr, "warn", message, ANSI.yellow);
69
+ },
70
+ error(message) {
71
+ write(stderr, "error", message, ANSI.red);
72
+ },
73
+ debug(message) {
74
+ if (options.verbose) {
75
+ write(stdout, "debug", message, ANSI.gray);
76
+ }
77
+ },
78
+ section(title) {
79
+ const text = useColor ? `${ANSI.bold}${title}${ANSI.reset}` : title;
80
+ write(stdout, "step", text, ANSI.magenta, true, true);
81
+ },
82
+ kv(label, value) {
83
+ const labelText = useColor ? `${ANSI.bold}${label}${ANSI.reset}` : label;
84
+ write(stdout, "info", `${labelText}: ${value}`, ANSI.cyan);
85
+ },
86
+ step(message) {
87
+ write(stdout, "step", message, ANSI.cyan);
88
+ },
89
+ list(items) {
90
+ for (const item of items) {
91
+ const bullet = colorize(useColor, ANSI.gray, "-");
92
+ stdout.write(` ${bullet} ${item}\n`);
93
+ }
94
+ },
95
+ async confirm(message) {
96
+ if (options.yes) {
97
+ return true;
98
+ }
99
+ if (!stdin.isTTY || !stdout.isTTY) {
100
+ write(stderr, "warn", `${message} (confirmation required; pass --yes in non-interactive mode)`, ANSI.yellow);
101
+ return false;
102
+ }
103
+ const rl = (0, promises_1.createInterface)({ input: stdin, output: stdout });
104
+ try {
105
+ const answer = await rl.question(`${colorize(useColor, ANSI.cyan, icon("step"))} ${message} [y/N] `);
106
+ const normalized = answer.trim().toLowerCase();
107
+ return normalized === "y" || normalized === "yes";
108
+ }
109
+ finally {
110
+ rl.close();
111
+ }
112
+ },
113
+ spinner(message) {
114
+ if (!stdout.isTTY || options.verbose) {
115
+ write(stdout, "step", message, ANSI.cyan);
116
+ return {
117
+ succeed(nextMessage) {
118
+ if (nextMessage) {
119
+ write(stdout, "success", nextMessage, ANSI.green);
120
+ }
121
+ },
122
+ fail(nextMessage) {
123
+ if (nextMessage) {
124
+ write(stderr, "error", nextMessage, ANSI.red);
125
+ }
126
+ },
127
+ stop(nextMessage) {
128
+ if (nextMessage) {
129
+ write(stdout, "info", nextMessage, ANSI.cyan);
130
+ }
131
+ },
132
+ };
133
+ }
134
+ let frameIndex = 0;
135
+ const renderFrame = (frame) => `${colorize(useColor, ANSI.cyan, frame)} ${message}`;
136
+ stdout.write(renderFrame(FRAMES[frameIndex]));
137
+ const timer = setInterval(() => {
138
+ frameIndex = (frameIndex + 1) % FRAMES.length;
139
+ stdout.write(`\r${renderFrame(FRAMES[frameIndex])}`);
140
+ }, 80);
141
+ let finished = false;
142
+ const stop = (token, color, nextMessage, stream) => {
143
+ if (finished) {
144
+ return;
145
+ }
146
+ finished = true;
147
+ clearInterval(timer);
148
+ const output = stream ?? stdout;
149
+ const finalToken = colorize(useColor, color, token);
150
+ const finalMessage = nextMessage ?? message;
151
+ output.write(`\r${finalToken} ${finalMessage}\n`);
152
+ };
153
+ return {
154
+ succeed(nextMessage) {
155
+ stop(icon("success"), ANSI.green, nextMessage, stdout);
156
+ },
157
+ fail(nextMessage) {
158
+ stop(icon("error"), ANSI.red, nextMessage, stderr);
159
+ },
160
+ stop(nextMessage) {
161
+ stop(icon("info"), ANSI.cyan, nextMessage, stdout);
162
+ },
163
+ };
164
+ },
165
+ };
166
+ }
@@ -0,0 +1 @@
1
+ export declare function resolveLatestVersions(packages: string[]): Promise<Record<string, string>>;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveLatestVersions = resolveLatestVersions;
4
+ const errors_1 = require("../errors");
5
+ const LATEST_TIMEOUT_MS = 10_000;
6
+ async function fetchLatestVersion(packageName) {
7
+ const encodedName = encodeURIComponent(packageName);
8
+ const url = `https://registry.npmjs.org/${encodedName}/latest`;
9
+ let response;
10
+ try {
11
+ response = await fetch(url, {
12
+ headers: {
13
+ Accept: "application/json",
14
+ },
15
+ signal: AbortSignal.timeout(LATEST_TIMEOUT_MS),
16
+ });
17
+ }
18
+ catch (error) {
19
+ throw (0, errors_1.packageManagerFailedError)(`Failed to fetch latest version for ${packageName}.`, error);
20
+ }
21
+ if (!response.ok) {
22
+ throw (0, errors_1.packageManagerFailedError)(`Failed to fetch latest version for ${packageName}: npm registry responded with ${response.status}.`);
23
+ }
24
+ let payload;
25
+ try {
26
+ payload = (await response.json());
27
+ }
28
+ catch (error) {
29
+ throw (0, errors_1.packageManagerFailedError)(`Failed to parse npm registry response for ${packageName}.`, error);
30
+ }
31
+ if (typeof payload.version !== "string" || payload.version.length === 0) {
32
+ throw (0, errors_1.packageManagerFailedError)(`npm registry did not return a valid latest version for ${packageName}.`);
33
+ }
34
+ return payload.version;
35
+ }
36
+ async function resolveLatestVersions(packages) {
37
+ const uniquePackages = [...new Set(packages)];
38
+ const entries = await Promise.all(uniquePackages.map(async (packageName) => [packageName, await fetchLatestVersion(packageName)]));
39
+ return Object.fromEntries(entries);
40
+ }
@@ -0,0 +1,8 @@
1
+ import type { PackageManagerName } from "./pm/types";
2
+ export interface SummarizedItems {
3
+ total: number;
4
+ visible: string[];
5
+ hidden: number;
6
+ }
7
+ export declare function resolveLocalLatticeCommand(pmName: PackageManagerName): string;
8
+ export declare function summarizeItems(items: string[], limit?: number): SummarizedItems;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveLocalLatticeCommand = resolveLocalLatticeCommand;
4
+ exports.summarizeItems = summarizeItems;
5
+ function resolveLocalLatticeCommand(pmName) {
6
+ if (pmName === "npm") {
7
+ return "npx lattice";
8
+ }
9
+ return `${pmName} lattice`;
10
+ }
11
+ function summarizeItems(items, limit = 8) {
12
+ const normalizedLimit = Math.max(0, Math.floor(limit));
13
+ const uniqueItems = [...new Set(items)];
14
+ const visible = uniqueItems.slice(0, normalizedLimit);
15
+ return {
16
+ total: uniqueItems.length,
17
+ visible,
18
+ hidden: Math.max(0, uniqueItems.length - visible.length),
19
+ };
20
+ }
@@ -0,0 +1,18 @@
1
+ import type { PromptRuntime } from "../prompt";
2
+ import { promptSelect } from "../prompt";
3
+ import type { PackageManager, PackageManagerName } from "./types";
4
+ export type PackageManagerResolutionSource = "override" | "lockfile" | "installed" | "prompt";
5
+ export interface DetectPackageManagerResult {
6
+ name: PackageManagerName;
7
+ manager: PackageManager;
8
+ lockfiles: PackageManagerName[];
9
+ installed: PackageManagerName[];
10
+ source: PackageManagerResolutionSource;
11
+ }
12
+ export interface DetectPackageManagerOptions {
13
+ runtime?: PromptRuntime;
14
+ promptSelectFn?: typeof promptSelect;
15
+ detectInstalledPackageManagersFn?: () => Promise<PackageManagerName[]>;
16
+ }
17
+ export declare function detectInstalledPackageManagers(): Promise<PackageManagerName[]>;
18
+ export declare function detectPackageManager(cwd: string, override?: string, options?: DetectPackageManagerOptions): Promise<DetectPackageManagerResult>;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.detectInstalledPackageManagers = detectInstalledPackageManagers;
37
+ exports.detectPackageManager = detectPackageManager;
38
+ const node_child_process_1 = require("node:child_process");
39
+ const node_fs_1 = require("node:fs");
40
+ const path = __importStar(require("node:path"));
41
+ const errors_1 = require("../errors");
42
+ const prompt_1 = require("../prompt");
43
+ const npm_1 = require("./npm");
44
+ const pnpm_1 = require("./pnpm");
45
+ const yarn_1 = require("./yarn");
46
+ const promptPackageManagerOrder = ["npm", "pnpm", "yarn"];
47
+ const lockfileDetectionOrder = ["pnpm", "yarn", "npm"];
48
+ const PACKAGE_MANAGER_HINT = "--pm <pnpm|npm|yarn>";
49
+ const lockfileByManager = {
50
+ pnpm: "pnpm-lock.yaml",
51
+ yarn: "yarn.lock",
52
+ npm: "package-lock.json",
53
+ };
54
+ const managerFactory = {
55
+ pnpm: pnpm_1.createPnpmPackageManager,
56
+ yarn: yarn_1.createYarnPackageManager,
57
+ npm: npm_1.createNpmPackageManager,
58
+ };
59
+ async function exists(filePath) {
60
+ try {
61
+ await node_fs_1.promises.access(filePath);
62
+ return true;
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
+ }
68
+ function normalizePackageManagers(values) {
69
+ const unique = new Set(values);
70
+ return promptPackageManagerOrder.filter((managerName) => unique.has(managerName));
71
+ }
72
+ async function isPackageManagerInstalled(managerName) {
73
+ return new Promise((resolve) => {
74
+ const child = (0, node_child_process_1.spawn)(managerName, ["--version"], {
75
+ stdio: "ignore",
76
+ shell: process.platform === "win32",
77
+ });
78
+ child.on("error", () => {
79
+ resolve(false);
80
+ });
81
+ child.on("close", (code) => {
82
+ resolve(code === 0);
83
+ });
84
+ });
85
+ }
86
+ async function detectInstalledPackageManagers() {
87
+ const checks = await Promise.all(promptPackageManagerOrder.map(async (managerName) => (await isPackageManagerInstalled(managerName)) ? managerName : null));
88
+ return checks.filter((managerName) => managerName !== null);
89
+ }
90
+ function createResult(name, lockfiles, installed, source) {
91
+ return {
92
+ name,
93
+ manager: managerFactory[name](),
94
+ lockfiles,
95
+ installed,
96
+ source,
97
+ };
98
+ }
99
+ function ensureInstalled(selected, installed, reason) {
100
+ if (installed.includes(selected)) {
101
+ return;
102
+ }
103
+ if (reason === "override") {
104
+ throw (0, errors_1.usageError)(`Requested package manager "${selected}" is not installed. Install ${selected} or choose a different ${PACKAGE_MANAGER_HINT}.`);
105
+ }
106
+ throw (0, errors_1.usageError)(`Detected ${selected} from ${lockfileByManager[selected]} but ${selected} is not installed. Install ${selected} or re-run with ${PACKAGE_MANAGER_HINT}.`);
107
+ }
108
+ async function detectPackageManager(cwd, override, options) {
109
+ const requested = override?.trim();
110
+ if (requested && requested !== "pnpm" && requested !== "npm" && requested !== "yarn") {
111
+ throw (0, errors_1.usageError)(`Invalid --pm value "${override}". Use pnpm, npm, or yarn.`);
112
+ }
113
+ const lockfiles = [];
114
+ for (const managerName of lockfileDetectionOrder) {
115
+ if (await exists(path.join(cwd, lockfileByManager[managerName]))) {
116
+ lockfiles.push(managerName);
117
+ }
118
+ }
119
+ const installed = normalizePackageManagers(await (options?.detectInstalledPackageManagersFn ?? detectInstalledPackageManagers)());
120
+ if (requested) {
121
+ const selected = requested;
122
+ ensureInstalled(selected, installed, "override");
123
+ return createResult(selected, lockfiles, installed, "override");
124
+ }
125
+ if (lockfiles.length > 0) {
126
+ const selected = lockfiles[0];
127
+ ensureInstalled(selected, installed, "lockfile");
128
+ return createResult(selected, lockfiles, installed, "lockfile");
129
+ }
130
+ if (installed.length === 0) {
131
+ throw (0, errors_1.usageError)("No supported package manager is installed. Install npm, pnpm, or yarn and re-run the command.");
132
+ }
133
+ if (installed.length === 1) {
134
+ return createResult(installed[0], lockfiles, installed, "installed");
135
+ }
136
+ const runtime = options?.runtime ?? { yes: false, stdin: process.stdin, stdout: process.stdout };
137
+ const stdin = runtime.stdin ?? process.stdin;
138
+ const stdout = runtime.stdout ?? process.stdout;
139
+ if (runtime.yes || !stdin.isTTY || !stdout.isTTY) {
140
+ throw (0, errors_1.usageError)(`Multiple package managers are installed (${installed.join(", ")}). Re-run with ${PACKAGE_MANAGER_HINT}.`);
141
+ }
142
+ const selected = await (options?.promptSelectFn ?? prompt_1.promptSelect)(runtime, "Select a package manager", installed.map((managerName) => ({
143
+ label: managerName,
144
+ value: managerName,
145
+ })), { defaultIndex: 0 });
146
+ return createResult(selected, lockfiles, installed, "prompt");
147
+ }
@@ -0,0 +1,2 @@
1
+ import type { PackageManager } from "./types";
2
+ export declare function createNpmPackageManager(): PackageManager;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNpmPackageManager = createNpmPackageManager;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const errors_1 = require("../errors");
6
+ function run(command, args, cwd) {
7
+ return new Promise((resolve, reject) => {
8
+ const child = (0, node_child_process_1.spawn)(command, args, {
9
+ cwd,
10
+ stdio: "inherit",
11
+ shell: process.platform === "win32",
12
+ });
13
+ child.on("error", (error) => {
14
+ reject((0, errors_1.packageManagerFailedError)(`Failed to run ${command}: ${error.message}`, error));
15
+ });
16
+ child.on("close", (code) => {
17
+ if (code === 0) {
18
+ resolve();
19
+ return;
20
+ }
21
+ reject((0, errors_1.packageManagerFailedError)(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}.`));
22
+ });
23
+ });
24
+ }
25
+ function createNpmPackageManager() {
26
+ return {
27
+ name: "npm",
28
+ async add(dev, specs, cwd) {
29
+ if (specs.length === 0) {
30
+ return;
31
+ }
32
+ const args = ["install", ...(dev ? ["--save-dev"] : []), ...specs];
33
+ await run("npm", args, cwd);
34
+ },
35
+ async remove(specs, cwd) {
36
+ if (specs.length === 0) {
37
+ return;
38
+ }
39
+ await run("npm", ["uninstall", ...specs], cwd);
40
+ },
41
+ async install(cwd) {
42
+ await run("npm", ["install"], cwd);
43
+ },
44
+ async exec(bin, args, cwd) {
45
+ await run("npm", ["exec", "--", bin, ...args], cwd);
46
+ },
47
+ };
48
+ }
@@ -0,0 +1,2 @@
1
+ import type { PackageManager } from "./types";
2
+ export declare function createPnpmPackageManager(): PackageManager;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPnpmPackageManager = createPnpmPackageManager;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const errors_1 = require("../errors");
6
+ function run(command, args, cwd) {
7
+ return new Promise((resolve, reject) => {
8
+ const child = (0, node_child_process_1.spawn)(command, args, {
9
+ cwd,
10
+ stdio: "inherit",
11
+ shell: process.platform === "win32",
12
+ });
13
+ child.on("error", (error) => {
14
+ reject((0, errors_1.packageManagerFailedError)(`Failed to run ${command}: ${error.message}`, error));
15
+ });
16
+ child.on("close", (code) => {
17
+ if (code === 0) {
18
+ resolve();
19
+ return;
20
+ }
21
+ reject((0, errors_1.packageManagerFailedError)(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}.`));
22
+ });
23
+ });
24
+ }
25
+ function createPnpmPackageManager() {
26
+ return {
27
+ name: "pnpm",
28
+ async add(dev, specs, cwd) {
29
+ if (specs.length === 0) {
30
+ return;
31
+ }
32
+ const args = ["add", ...(dev ? ["-D"] : []), ...specs];
33
+ await run("pnpm", args, cwd);
34
+ },
35
+ async remove(specs, cwd) {
36
+ if (specs.length === 0) {
37
+ return;
38
+ }
39
+ await run("pnpm", ["remove", ...specs], cwd);
40
+ },
41
+ async install(cwd) {
42
+ await run("pnpm", ["install"], cwd);
43
+ },
44
+ async exec(bin, args, cwd) {
45
+ await run("pnpm", ["exec", bin, ...args], cwd);
46
+ },
47
+ };
48
+ }
@@ -0,0 +1,8 @@
1
+ export type PackageManagerName = "pnpm" | "npm" | "yarn";
2
+ export interface PackageManager {
3
+ name: "pnpm" | "npm" | "yarn";
4
+ add(dev: boolean, specs: string[], cwd: string): Promise<void>;
5
+ remove(specs: string[], cwd: string): Promise<void>;
6
+ install(cwd: string): Promise<void>;
7
+ exec(bin: string, args: string[], cwd: string): Promise<void>;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import type { PackageManager } from "./types";
2
+ export declare function createYarnPackageManager(): PackageManager;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createYarnPackageManager = createYarnPackageManager;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const errors_1 = require("../errors");
6
+ function run(command, args, cwd) {
7
+ return new Promise((resolve, reject) => {
8
+ const child = (0, node_child_process_1.spawn)(command, args, {
9
+ cwd,
10
+ stdio: "inherit",
11
+ shell: process.platform === "win32",
12
+ });
13
+ child.on("error", (error) => {
14
+ reject((0, errors_1.packageManagerFailedError)(`Failed to run ${command}: ${error.message}`, error));
15
+ });
16
+ child.on("close", (code) => {
17
+ if (code === 0) {
18
+ resolve();
19
+ return;
20
+ }
21
+ reject((0, errors_1.packageManagerFailedError)(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}.`));
22
+ });
23
+ });
24
+ }
25
+ function createYarnPackageManager() {
26
+ return {
27
+ name: "yarn",
28
+ async add(dev, specs, cwd) {
29
+ if (specs.length === 0) {
30
+ return;
31
+ }
32
+ const args = ["add", ...(dev ? ["--dev"] : []), ...specs];
33
+ await run("yarn", args, cwd);
34
+ },
35
+ async remove(specs, cwd) {
36
+ if (specs.length === 0) {
37
+ return;
38
+ }
39
+ await run("yarn", ["remove", ...specs], cwd);
40
+ },
41
+ async install(cwd) {
42
+ await run("yarn", ["install"], cwd);
43
+ },
44
+ async exec(bin, args, cwd) {
45
+ await run("yarn", ["run", bin, ...args], cwd);
46
+ },
47
+ };
48
+ }
@@ -0,0 +1 @@
1
+ export declare function findRoot(startDir: string): Promise<string | undefined>;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.findRoot = findRoot;
37
+ const node_fs_1 = require("node:fs");
38
+ const path = __importStar(require("node:path"));
39
+ async function hasPackageJson(dirPath) {
40
+ try {
41
+ await node_fs_1.promises.access(path.join(dirPath, "package.json"));
42
+ return true;
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ }
48
+ async function findRoot(startDir) {
49
+ let currentDir = path.resolve(startDir);
50
+ while (true) {
51
+ if (await hasPackageJson(currentDir)) {
52
+ return currentDir;
53
+ }
54
+ const parentDir = path.dirname(currentDir);
55
+ if (parentDir === currentDir) {
56
+ return undefined;
57
+ }
58
+ currentDir = parentDir;
59
+ }
60
+ }