uilint 0.2.41 → 0.2.43

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,118 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/utils/prompts.ts
4
+ import * as p from "@clack/prompts";
5
+ import pc from "picocolors";
6
+ import { readFileSync } from "fs";
7
+ import { dirname, join } from "path";
8
+ import { fileURLToPath } from "url";
9
+ function getCLIVersion() {
10
+ try {
11
+ const __dirname = dirname(fileURLToPath(import.meta.url));
12
+ const pkgPath = join(__dirname, "..", "..", "package.json");
13
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
14
+ return pkg.version || "0.0.0";
15
+ } catch {
16
+ return "0.0.0";
17
+ }
18
+ }
19
+ function intro2(title) {
20
+ const version = getCLIVersion();
21
+ const header = pc.bold(pc.cyan("\u25C6 UILint")) + pc.dim(` v${version}`);
22
+ console.log();
23
+ p.intro(title ? `${header} ${pc.dim("\xB7")} ${title}` : header);
24
+ }
25
+ function outro2(message) {
26
+ p.outro(pc.green(message));
27
+ }
28
+ function cancel2(message = "Operation cancelled.") {
29
+ p.cancel(pc.yellow(message));
30
+ process.exit(0);
31
+ }
32
+ function handleCancel(value) {
33
+ if (p.isCancel(value)) {
34
+ cancel2();
35
+ process.exit(0);
36
+ }
37
+ return value;
38
+ }
39
+ async function withSpinner(message, fn) {
40
+ const s = p.spinner();
41
+ s.start(message);
42
+ try {
43
+ const result = fn.length >= 1 ? await fn(s) : await fn();
44
+ s.stop(pc.green("\u2713 ") + message);
45
+ return result;
46
+ } catch (error) {
47
+ s.stop(pc.red("\u2717 ") + message);
48
+ throw error;
49
+ }
50
+ }
51
+ function createSpinner() {
52
+ return p.spinner();
53
+ }
54
+ function note2(message, title) {
55
+ p.note(message, title);
56
+ }
57
+ function log2(message) {
58
+ p.log.message(message);
59
+ }
60
+ function logInfo(message) {
61
+ p.log.info(message);
62
+ }
63
+ function logSuccess(message) {
64
+ p.log.success(message);
65
+ }
66
+ function logWarning(message) {
67
+ p.log.warn(message);
68
+ }
69
+ function logError(message) {
70
+ p.log.error(message);
71
+ }
72
+ async function select2(options) {
73
+ const result = await p.select({
74
+ message: options.message,
75
+ options: options.options,
76
+ initialValue: options.initialValue
77
+ });
78
+ return handleCancel(result);
79
+ }
80
+ async function confirm2(options) {
81
+ const result = await p.confirm({
82
+ message: options.message,
83
+ initialValue: options.initialValue ?? true
84
+ });
85
+ return handleCancel(result);
86
+ }
87
+ async function text2(options) {
88
+ const result = await p.text(options);
89
+ return handleCancel(result);
90
+ }
91
+ async function multiselect2(options) {
92
+ const result = await p.multiselect({
93
+ message: options.message,
94
+ options: options.options,
95
+ required: options.required,
96
+ initialValues: options.initialValues
97
+ });
98
+ return handleCancel(result);
99
+ }
100
+
101
+ export {
102
+ pc,
103
+ intro2 as intro,
104
+ outro2 as outro,
105
+ withSpinner,
106
+ createSpinner,
107
+ note2 as note,
108
+ log2 as log,
109
+ logInfo,
110
+ logSuccess,
111
+ logWarning,
112
+ logError,
113
+ select2 as select,
114
+ confirm2 as confirm,
115
+ text2 as text,
116
+ multiselect2 as multiselect
117
+ };
118
+ //# sourceMappingURL=chunk-CZNPG4UI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/prompts.ts"],"sourcesContent":["/**\n * Shared clack/prompts utilities for UILint CLI\n * Provides branded intro/outro, spinners, and common UI patterns\n */\n\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Get the CLI version from package.json\n */\nfunction getCLIVersion(): string {\n try {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkgPath = join(__dirname, \"..\", \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n version?: string;\n };\n return pkg.version || \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\n/**\n * Branded UILint intro with logo and version\n */\nexport function intro(title?: string): void {\n const version = getCLIVersion();\n const header = pc.bold(pc.cyan(\"◆ UILint\")) + pc.dim(` v${version}`);\n \n console.log();\n p.intro(title ? `${header} ${pc.dim(\"·\")} ${title}` : header);\n}\n\n/**\n * Styled outro with next steps\n */\nexport function outro(message: string): void {\n p.outro(pc.green(message));\n}\n\n/**\n * Cancel message when user exits\n */\nexport function cancel(message = \"Operation cancelled.\"): void {\n p.cancel(pc.yellow(message));\n process.exit(0);\n}\n\n/**\n * Check if user cancelled a prompt\n */\nexport function isCancel(value: unknown): value is symbol {\n return p.isCancel(value);\n}\n\n/**\n * Handle cancel check - exits if cancelled\n */\nexport function handleCancel<T>(value: T | symbol): T {\n if (p.isCancel(value)) {\n cancel();\n process.exit(0);\n }\n return value as T;\n}\n\n/**\n * Spinner wrapper with automatic error handling\n */\nexport async function withSpinner<T>(\n message: string,\n fn: (() => Promise<T>) | ((spinner: ReturnType<typeof p.spinner>) => Promise<T>)\n): Promise<T> {\n const s = p.spinner();\n s.start(message);\n try {\n const result =\n fn.length >= 1\n ? await (fn as (spinner: ReturnType<typeof p.spinner>) => Promise<T>)(s)\n : await (fn as () => Promise<T>)();\n s.stop(pc.green(\"✓ \") + message);\n return result;\n } catch (error) {\n s.stop(pc.red(\"✗ \") + message);\n throw error;\n }\n}\n\n/**\n * Spinner that can be updated\n */\nexport function createSpinner() {\n return p.spinner();\n}\n\n/**\n * Display a note box\n */\nexport function note(message: string, title?: string): void {\n p.note(message, title);\n}\n\n/**\n * Display a log message\n */\nexport function log(message: string): void {\n p.log.message(message);\n}\n\n/**\n * Display an info message\n */\nexport function logInfo(message: string): void {\n p.log.info(message);\n}\n\n/**\n * Display a success message\n */\nexport function logSuccess(message: string): void {\n p.log.success(message);\n}\n\n/**\n * Display a warning message\n */\nexport function logWarning(message: string): void {\n p.log.warn(message);\n}\n\n/**\n * Display an error message\n */\nexport function logError(message: string): void {\n p.log.error(message);\n}\n\n/**\n * Display a step message\n */\nexport function logStep(message: string): void {\n p.log.step(message);\n}\n\n/**\n * Select prompt wrapper\n */\nexport async function select<T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n initialValue?: T;\n}): Promise<T> {\n const result = await p.select({\n message: options.message,\n options: options.options as { value: T; label: string; hint?: string }[],\n initialValue: options.initialValue,\n } as Parameters<typeof p.select>[0]);\n return handleCancel(result) as T;\n}\n\n/**\n * Confirm prompt wrapper\n */\nexport async function confirm(options: {\n message: string;\n initialValue?: boolean;\n}): Promise<boolean> {\n const result = await p.confirm({\n message: options.message,\n initialValue: options.initialValue ?? true,\n });\n return handleCancel(result);\n}\n\n/**\n * Text input prompt wrapper\n */\nexport async function text(options: {\n message: string;\n placeholder?: string;\n defaultValue?: string;\n validate?: (value: string) => string | Error | undefined;\n}): Promise<string> {\n const result = await p.text(options);\n return handleCancel(result);\n}\n\n/**\n * Multiselect prompt wrapper\n */\nexport async function multiselect<T extends string>(options: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n required?: boolean;\n initialValues?: T[];\n}): Promise<T[]> {\n const result = await p.multiselect({\n message: options.message,\n options: options.options as { value: T; label: string; hint?: string }[],\n required: options.required,\n initialValues: options.initialValues,\n } as Parameters<typeof p.multiselect>[0]);\n return handleCancel(result) as T[];\n}\n\n/**\n * Group of tasks displayed together\n */\nexport async function group<T extends Record<string, unknown>>(\n prompts: p.PromptGroup<T>,\n options?: p.PromptGroupOptions<T>\n): Promise<T> {\n const result = await p.group(prompts, options);\n return result;\n}\n\n// Re-export picocolors for consistent styling\nexport { pc };\n"],"mappings":";;;AAKA,YAAY,OAAO;AACnB,OAAO,QAAQ;AACf,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAK9B,SAAS,gBAAwB;AAC/B,MAAI;AACF,UAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,UAAM,UAAU,KAAK,WAAW,MAAM,MAAM,cAAc;AAC1D,UAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AAGrD,WAAO,IAAI,WAAW;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAASA,OAAM,OAAsB;AAC1C,QAAM,UAAU,cAAc;AAC9B,QAAM,SAAS,GAAG,KAAK,GAAG,KAAK,eAAU,CAAC,IAAI,GAAG,IAAI,KAAK,OAAO,EAAE;AAEnE,UAAQ,IAAI;AACZ,EAAE,QAAM,QAAQ,GAAG,MAAM,IAAI,GAAG,IAAI,MAAG,CAAC,IAAI,KAAK,KAAK,MAAM;AAC9D;AAKO,SAASC,OAAM,SAAuB;AAC3C,EAAE,QAAM,GAAG,MAAM,OAAO,CAAC;AAC3B;AAKO,SAASC,QAAO,UAAU,wBAA8B;AAC7D,EAAE,SAAO,GAAG,OAAO,OAAO,CAAC;AAC3B,UAAQ,KAAK,CAAC;AAChB;AAYO,SAAS,aAAgB,OAAsB;AACpD,MAAM,WAAS,KAAK,GAAG;AACrB,IAAAC,QAAO;AACP,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO;AACT;AAKA,eAAsB,YACpB,SACA,IACY;AACZ,QAAM,IAAM,UAAQ;AACpB,IAAE,MAAM,OAAO;AACf,MAAI;AACF,UAAM,SACJ,GAAG,UAAU,IACT,MAAO,GAA6D,CAAC,IACrE,MAAO,GAAwB;AACrC,MAAE,KAAK,GAAG,MAAM,SAAI,IAAI,OAAO;AAC/B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,MAAE,KAAK,GAAG,IAAI,SAAI,IAAI,OAAO;AAC7B,UAAM;AAAA,EACR;AACF;AAKO,SAAS,gBAAgB;AAC9B,SAAS,UAAQ;AACnB;AAKO,SAASC,MAAK,SAAiB,OAAsB;AAC1D,EAAE,OAAK,SAAS,KAAK;AACvB;AAKO,SAASC,KAAI,SAAuB;AACzC,EAAE,MAAI,QAAQ,OAAO;AACvB;AAKO,SAAS,QAAQ,SAAuB;AAC7C,EAAE,MAAI,KAAK,OAAO;AACpB;AAKO,SAAS,WAAW,SAAuB;AAChD,EAAE,MAAI,QAAQ,OAAO;AACvB;AAKO,SAAS,WAAW,SAAuB;AAChD,EAAE,MAAI,KAAK,OAAO;AACpB;AAKO,SAAS,SAAS,SAAuB;AAC9C,EAAE,MAAI,MAAM,OAAO;AACrB;AAYA,eAAsBC,QAAyB,SAIhC;AACb,QAAM,SAAS,MAAQ,SAAO;AAAA,IAC5B,SAAS,QAAQ;AAAA,IACjB,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ;AAAA,EACxB,CAAmC;AACnC,SAAO,aAAa,MAAM;AAC5B;AAKA,eAAsBC,SAAQ,SAGT;AACnB,QAAM,SAAS,MAAQ,UAAQ;AAAA,IAC7B,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ,gBAAgB;AAAA,EACxC,CAAC;AACD,SAAO,aAAa,MAAM;AAC5B;AAKA,eAAsBC,MAAK,SAKP;AAClB,QAAM,SAAS,MAAQ,OAAK,OAAO;AACnC,SAAO,aAAa,MAAM;AAC5B;AAKA,eAAsBC,aAA8B,SAKnC;AACf,QAAM,SAAS,MAAQ,cAAY;AAAA,IACjC,SAAS,QAAQ;AAAA,IACjB,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,eAAe,QAAQ;AAAA,EACzB,CAAwC;AACxC,SAAO,aAAa,MAAM;AAC5B;","names":["intro","outro","cancel","cancel","note","log","select","confirm","text","multiselect"]}
@@ -162,10 +162,76 @@ async function runTestsWithCoverage(pm, projectPath) {
162
162
  const { command, args } = getTestCoverageCommand(pm);
163
163
  await spawnAsync(command, args, projectPath);
164
164
  }
165
+ var UILINT_PACKAGES = [
166
+ "uilint",
167
+ "uilint-eslint",
168
+ "uilint-core",
169
+ "uilint-react"
170
+ ];
171
+ function getInstalledUilintPackages(projectPath) {
172
+ const pkgJsonPath = join(projectPath, "package.json");
173
+ if (!existsSync(pkgJsonPath)) {
174
+ return /* @__PURE__ */ new Map();
175
+ }
176
+ try {
177
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
178
+ const result = /* @__PURE__ */ new Map();
179
+ const allDeps = {
180
+ ...pkgJson.dependencies,
181
+ ...pkgJson.devDependencies
182
+ };
183
+ for (const pkg of UILINT_PACKAGES) {
184
+ if (allDeps[pkg]) {
185
+ result.set(pkg, allDeps[pkg]);
186
+ }
187
+ }
188
+ return result;
189
+ } catch {
190
+ return /* @__PURE__ */ new Map();
191
+ }
192
+ }
193
+ async function updatePackages(pm, projectPath, packages, options = { dev: true }) {
194
+ if (!packages.length) return;
195
+ const isDev = options.dev ?? true;
196
+ const packagesWithLatest = packages.map((pkg) => `${pkg}@latest`);
197
+ switch (pm) {
198
+ case "pnpm":
199
+ await spawnAsync(
200
+ "pnpm",
201
+ ["add", ...isDev ? ["-D"] : [], ...packagesWithLatest],
202
+ projectPath
203
+ );
204
+ return;
205
+ case "yarn":
206
+ await spawnAsync(
207
+ "yarn",
208
+ ["add", ...isDev ? ["-D"] : [], ...packagesWithLatest],
209
+ projectPath
210
+ );
211
+ return;
212
+ case "bun":
213
+ await spawnAsync(
214
+ "bun",
215
+ ["add", ...isDev ? ["-d"] : [], ...packagesWithLatest],
216
+ projectPath
217
+ );
218
+ return;
219
+ case "npm":
220
+ default:
221
+ await spawnAsync(
222
+ "npm",
223
+ ["install", isDev ? "--save-dev" : "--save", ...packagesWithLatest],
224
+ projectPath
225
+ );
226
+ return;
227
+ }
228
+ }
165
229
 
166
230
  export {
167
231
  detectPackageManager,
168
232
  installDependencies,
169
- runTestsWithCoverage
233
+ runTestsWithCoverage,
234
+ getInstalledUilintPackages,
235
+ updatePackages
170
236
  };
171
- //# sourceMappingURL=chunk-OTU5FY6B.js.map
237
+ //# sourceMappingURL=chunk-JPE27ROY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/package-manager.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"fs\";\nimport { spawn } from \"child_process\";\nimport { dirname, join } from \"path\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"npm\" | \"bun\";\n\n/**\n * Detect which package manager a project uses by looking for lockfiles.\n * Walks up the directory tree to support monorepos.\n */\nexport function detectPackageManager(projectPath: string): PackageManager {\n // Monorepo-friendly detection: walk up to find the lockfile/workspace marker.\n let dir = projectPath;\n for (;;) {\n // pnpm\n if (existsSync(join(dir, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(join(dir, \"pnpm-workspace.yaml\"))) return \"pnpm\";\n\n // yarn\n if (existsSync(join(dir, \"yarn.lock\"))) return \"yarn\";\n\n // bun\n if (existsSync(join(dir, \"bun.lockb\"))) return \"bun\";\n if (existsSync(join(dir, \"bun.lock\"))) return \"bun\";\n\n // npm\n if (existsSync(join(dir, \"package-lock.json\"))) return \"npm\";\n\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n // Default: npm (best-effort)\n return \"npm\";\n}\n\nfunction spawnAsync(\n command: string,\n args: string[],\n cwd: string\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n // Capture output so we can surface it in installer summaries, while still\n // streaming to the user for a good UX.\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n const MAX_CAPTURE = 64 * 1024; // keep last 64KB per stream\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(chunk);\n stdoutChunks.push(chunk);\n // keep bounded\n while (Buffer.concat(stdoutChunks).length > MAX_CAPTURE) stdoutChunks.shift();\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(chunk);\n stderrChunks.push(chunk);\n while (Buffer.concat(stderrChunks).length > MAX_CAPTURE) stderrChunks.shift();\n });\n\n child.on(\"error\", (err) => {\n reject(err);\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n\n const cmd = `${command} ${args.join(\" \")}`.trim();\n const stdout = Buffer.concat(stdoutChunks).toString(\"utf-8\").trim();\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\").trim();\n const snippet = (stderr || stdout).trim();\n\n reject(\n new Error(\n `${cmd} exited with ${code}${\n snippet ? `\\n\\n--- output ---\\n${snippet}\\n--- end output ---` : \"\"\n }`\n )\n );\n });\n });\n}\n\n/**\n * Get the set of packages already installed in a project\n * (both dependencies and devDependencies)\n */\nfunction getInstalledPackages(projectPath: string): Set<string> {\n const pkgJsonPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgJsonPath)) {\n return new Set();\n }\n\n try {\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const installed = new Set<string>();\n if (pkgJson.dependencies) {\n for (const name of Object.keys(pkgJson.dependencies)) {\n installed.add(name);\n }\n }\n if (pkgJson.devDependencies) {\n for (const name of Object.keys(pkgJson.devDependencies)) {\n installed.add(name);\n }\n }\n return installed;\n } catch {\n return new Set();\n }\n}\n\n/**\n * Extract package name from a package specifier (e.g., \"foo@^1.0.0\" -> \"foo\")\n */\nfunction getPackageName(specifier: string): string {\n // Handle scoped packages like @scope/pkg@version\n if (specifier.startsWith(\"@\")) {\n const slashIndex = specifier.indexOf(\"/\");\n if (slashIndex === -1) return specifier;\n\n const afterSlash = specifier.slice(slashIndex + 1);\n const atIndex = afterSlash.indexOf(\"@\");\n if (atIndex === -1) return specifier;\n return specifier.slice(0, slashIndex + 1 + atIndex);\n }\n\n // Handle unscoped packages like pkg@version\n const atIndex = specifier.indexOf(\"@\");\n if (atIndex === -1) return specifier;\n return specifier.slice(0, atIndex);\n}\n\n/**\n * Filter out packages that are already installed\n */\nfunction filterAlreadyInstalled(\n packages: string[],\n projectPath: string\n): string[] {\n const installed = getInstalledPackages(projectPath);\n return packages.filter((pkg) => {\n const name = getPackageName(pkg);\n return !installed.has(name);\n });\n}\n\nexport async function installDependencies(\n pm: PackageManager,\n projectPath: string,\n packages: string[],\n options: { dev?: boolean } = { dev: true }\n): Promise<void> {\n if (!packages.length) return;\n\n // Filter out packages that are already installed to avoid yarn/npm errors\n // when trying to add a regular dependency as a dev dependency or vice versa\n const packagesToInstall = filterAlreadyInstalled(packages, projectPath);\n if (!packagesToInstall.length) return;\n\n const isDev = options.dev ?? true;\n\n switch (pm) {\n case \"pnpm\":\n await spawnAsync(\n \"pnpm\",\n [\"add\", ...(isDev ? [\"-D\"] : []), ...packagesToInstall],\n projectPath\n );\n return;\n case \"yarn\":\n await spawnAsync(\n \"yarn\",\n [\"add\", ...(isDev ? [\"-D\"] : []), ...packagesToInstall],\n projectPath\n );\n return;\n case \"bun\":\n await spawnAsync(\n \"bun\",\n [\"add\", ...(isDev ? [\"-d\"] : []), ...packagesToInstall],\n projectPath\n );\n return;\n case \"npm\":\n default:\n await spawnAsync(\n \"npm\",\n [\"install\", isDev ? \"--save-dev\" : \"--save\", ...packagesToInstall],\n projectPath\n );\n return;\n }\n}\n\n/**\n * Get the command and arguments to run tests with coverage\n */\nexport function getTestCoverageCommand(pm: PackageManager): {\n command: string;\n args: string[];\n} {\n switch (pm) {\n case \"pnpm\":\n return { command: \"pnpm\", args: [\"test\", \"--\", \"--coverage\"] };\n case \"yarn\":\n return { command: \"yarn\", args: [\"test\", \"--coverage\"] };\n case \"bun\":\n return { command: \"bun\", args: [\"test\", \"--coverage\"] };\n case \"npm\":\n default:\n return { command: \"npm\", args: [\"test\", \"--\", \"--coverage\"] };\n }\n}\n\n/**\n * Run tests with coverage for a project\n */\nexport async function runTestsWithCoverage(\n pm: PackageManager,\n projectPath: string\n): Promise<void> {\n const { command, args } = getTestCoverageCommand(pm);\n await spawnAsync(command, args, projectPath);\n}\n\n/**\n * UILint packages that can be updated\n */\nexport const UILINT_PACKAGES = [\n \"uilint\",\n \"uilint-eslint\",\n \"uilint-core\",\n \"uilint-react\",\n] as const;\n\nexport type UilintPackage = (typeof UILINT_PACKAGES)[number];\n\n/**\n * Get installed uilint packages and their versions\n */\nexport function getInstalledUilintPackages(\n projectPath: string\n): Map<UilintPackage, string> {\n const pkgJsonPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgJsonPath)) {\n return new Map();\n }\n\n try {\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n\n const result = new Map<UilintPackage, string>();\n const allDeps = {\n ...pkgJson.dependencies,\n ...pkgJson.devDependencies,\n };\n\n for (const pkg of UILINT_PACKAGES) {\n if (allDeps[pkg]) {\n result.set(pkg, allDeps[pkg]);\n }\n }\n\n return result;\n } catch {\n return new Map();\n }\n}\n\n/**\n * Update packages to their latest versions\n */\nexport async function updatePackages(\n pm: PackageManager,\n projectPath: string,\n packages: string[],\n options: { dev?: boolean } = { dev: true }\n): Promise<void> {\n if (!packages.length) return;\n\n const isDev = options.dev ?? true;\n\n // Use @latest to update to latest version\n const packagesWithLatest = packages.map((pkg) => `${pkg}@latest`);\n\n switch (pm) {\n case \"pnpm\":\n await spawnAsync(\n \"pnpm\",\n [\"add\", ...(isDev ? [\"-D\"] : []), ...packagesWithLatest],\n projectPath\n );\n return;\n case \"yarn\":\n await spawnAsync(\n \"yarn\",\n [\"add\", ...(isDev ? [\"-D\"] : []), ...packagesWithLatest],\n projectPath\n );\n return;\n case \"bun\":\n await spawnAsync(\n \"bun\",\n [\"add\", ...(isDev ? [\"-d\"] : []), ...packagesWithLatest],\n projectPath\n );\n return;\n case \"npm\":\n default:\n await spawnAsync(\n \"npm\",\n [\"install\", isDev ? \"--save-dev\" : \"--save\", ...packagesWithLatest],\n projectPath\n );\n return;\n }\n}\n"],"mappings":"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","names":["atIndex"]}
@@ -3,109 +3,11 @@ import {
3
3
  detectPackageManager,
4
4
  installDependencies,
5
5
  runTestsWithCoverage
6
- } from "./chunk-OTU5FY6B.js";
7
-
8
- // src/utils/prompts.ts
9
- import * as p from "@clack/prompts";
10
- import pc from "picocolors";
11
- import { readFileSync } from "fs";
12
- import { dirname, join } from "path";
13
- import { fileURLToPath } from "url";
14
- function getCLIVersion() {
15
- try {
16
- const __dirname = dirname(fileURLToPath(import.meta.url));
17
- const pkgPath = join(__dirname, "..", "..", "package.json");
18
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
19
- return pkg.version || "0.0.0";
20
- } catch {
21
- return "0.0.0";
22
- }
23
- }
24
- function intro2(title) {
25
- const version = getCLIVersion();
26
- const header = pc.bold(pc.cyan("\u25C6 UILint")) + pc.dim(` v${version}`);
27
- console.log();
28
- p.intro(title ? `${header} ${pc.dim("\xB7")} ${title}` : header);
29
- }
30
- function outro2(message) {
31
- p.outro(pc.green(message));
32
- }
33
- function cancel2(message = "Operation cancelled.") {
34
- p.cancel(pc.yellow(message));
35
- process.exit(0);
36
- }
37
- function handleCancel(value) {
38
- if (p.isCancel(value)) {
39
- cancel2();
40
- process.exit(0);
41
- }
42
- return value;
43
- }
44
- async function withSpinner(message, fn) {
45
- const s = p.spinner();
46
- s.start(message);
47
- try {
48
- const result = fn.length >= 1 ? await fn(s) : await fn();
49
- s.stop(pc.green("\u2713 ") + message);
50
- return result;
51
- } catch (error) {
52
- s.stop(pc.red("\u2717 ") + message);
53
- throw error;
54
- }
55
- }
56
- function createSpinner() {
57
- return p.spinner();
58
- }
59
- function note2(message, title) {
60
- p.note(message, title);
61
- }
62
- function log2(message) {
63
- p.log.message(message);
64
- }
65
- function logInfo(message) {
66
- p.log.info(message);
67
- }
68
- function logSuccess(message) {
69
- p.log.success(message);
70
- }
71
- function logWarning(message) {
72
- p.log.warn(message);
73
- }
74
- function logError(message) {
75
- p.log.error(message);
76
- }
77
- async function select2(options) {
78
- const result = await p.select({
79
- message: options.message,
80
- options: options.options,
81
- initialValue: options.initialValue
82
- });
83
- return handleCancel(result);
84
- }
85
- async function confirm2(options) {
86
- const result = await p.confirm({
87
- message: options.message,
88
- initialValue: options.initialValue ?? true
89
- });
90
- return handleCancel(result);
91
- }
92
- async function text2(options) {
93
- const result = await p.text(options);
94
- return handleCancel(result);
95
- }
96
- async function multiselect2(options) {
97
- const result = await p.multiselect({
98
- message: options.message,
99
- options: options.options,
100
- required: options.required,
101
- initialValues: options.initialValues
102
- });
103
- return handleCancel(result);
104
- }
6
+ } from "./chunk-JPE27ROY.js";
105
7
 
106
8
  // src/utils/coverage-detect.ts
107
- import { existsSync, readFileSync as readFileSync2, statSync } from "fs";
108
- import { join as join2 } from "path";
9
+ import { existsSync, readFileSync, statSync } from "fs";
10
+ import { join } from "path";
109
11
  var VITEST_CONFIG_FILES = [
110
12
  "vitest.config.ts",
111
13
  "vitest.config.js",
@@ -114,9 +16,9 @@ var VITEST_CONFIG_FILES = [
114
16
  ];
115
17
  function checkPackageDeps(projectPath) {
116
18
  try {
117
- const pkgPath = join2(projectPath, "package.json");
19
+ const pkgPath = join(projectPath, "package.json");
118
20
  if (!existsSync(pkgPath)) return { hasVitest: false, hasCoveragePackage: false };
119
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
21
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
120
22
  const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
121
23
  const hasVitest = "vitest" in deps;
122
24
  const hasCoveragePackage = "@vitest/coverage-v8" in deps || "@vitest/coverage-istanbul" in deps;
@@ -127,7 +29,7 @@ function checkPackageDeps(projectPath) {
127
29
  }
128
30
  function findVitestConfig(projectPath) {
129
31
  for (const configFile of VITEST_CONFIG_FILES) {
130
- const configPath = join2(projectPath, configFile);
32
+ const configPath = join(projectPath, configFile);
131
33
  if (existsSync(configPath)) {
132
34
  return configPath;
133
35
  }
@@ -136,7 +38,7 @@ function findVitestConfig(projectPath) {
136
38
  }
137
39
  function parseCoverageConfig(configPath) {
138
40
  try {
139
- const content = readFileSync2(configPath, "utf-8");
41
+ const content = readFileSync(configPath, "utf-8");
140
42
  const hasCoverageConfig = /coverage\s*:\s*\{/.test(content);
141
43
  if (!hasCoverageConfig) {
142
44
  return { hasCoverageConfig: false, coverageProvider: null };
@@ -149,7 +51,7 @@ function parseCoverageConfig(configPath) {
149
51
  }
150
52
  }
151
53
  function findCoverageData(projectPath) {
152
- const coverageDataPath = join2(projectPath, "coverage", "coverage-final.json");
54
+ const coverageDataPath = join(projectPath, "coverage", "coverage-final.json");
153
55
  if (existsSync(coverageDataPath)) {
154
56
  try {
155
57
  const stats = statSync(coverageDataPath);
@@ -192,36 +94,36 @@ function detectCoverageSetup(projectPath) {
192
94
 
193
95
  // src/utils/next-detect.ts
194
96
  import { existsSync as existsSync2, readdirSync } from "fs";
195
- import { join as join3 } from "path";
97
+ import { join as join2 } from "path";
196
98
  function fileExists(projectPath, relPath) {
197
- return existsSync2(join3(projectPath, relPath));
99
+ return existsSync2(join2(projectPath, relPath));
198
100
  }
199
101
  function detectNextAppRouter(projectPath) {
200
- const roots = ["app", join3("src", "app")];
102
+ const roots = ["app", join2("src", "app")];
201
103
  const candidates = [];
202
104
  let chosenRoot = null;
203
105
  for (const root of roots) {
204
- if (existsSync2(join3(projectPath, root))) {
106
+ if (existsSync2(join2(projectPath, root))) {
205
107
  chosenRoot = root;
206
108
  break;
207
109
  }
208
110
  }
209
111
  if (!chosenRoot) return null;
210
112
  const entryCandidates = [
211
- join3(chosenRoot, "layout.tsx"),
212
- join3(chosenRoot, "layout.jsx"),
213
- join3(chosenRoot, "layout.ts"),
214
- join3(chosenRoot, "layout.js"),
113
+ join2(chosenRoot, "layout.tsx"),
114
+ join2(chosenRoot, "layout.jsx"),
115
+ join2(chosenRoot, "layout.ts"),
116
+ join2(chosenRoot, "layout.js"),
215
117
  // Fallbacks (less ideal, but can work):
216
- join3(chosenRoot, "page.tsx"),
217
- join3(chosenRoot, "page.jsx")
118
+ join2(chosenRoot, "page.tsx"),
119
+ join2(chosenRoot, "page.jsx")
218
120
  ];
219
121
  for (const rel of entryCandidates) {
220
122
  if (fileExists(projectPath, rel)) candidates.push(rel);
221
123
  }
222
124
  return {
223
125
  appRoot: chosenRoot,
224
- appRootAbs: join3(projectPath, chosenRoot),
126
+ appRootAbs: join2(projectPath, chosenRoot),
225
127
  candidates
226
128
  };
227
129
  }
@@ -265,7 +167,7 @@ function findNextAppRouterProjects(rootDir, options) {
265
167
  if (!ent.isDirectory) continue;
266
168
  if (ignoreDirs.has(ent.name)) continue;
267
169
  if (ent.name.startsWith(".") && ent.name !== ".") continue;
268
- walk(join3(dir, ent.name), depth + 1);
170
+ walk(join2(dir, ent.name), depth + 1);
269
171
  }
270
172
  }
271
173
  walk(rootDir, 0);
@@ -273,14 +175,14 @@ function findNextAppRouterProjects(rootDir, options) {
273
175
  }
274
176
 
275
177
  // src/utils/eslint-config-inject.ts
276
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync } from "fs";
277
- import { join as join4, relative, dirname as dirname2 } from "path";
178
+ import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync } from "fs";
179
+ import { join as join3, relative, dirname } from "path";
278
180
  import { parseExpression, parseModule, generateCode } from "magicast";
279
181
  import { findWorkspaceRoot } from "uilint-core/node";
280
182
  var CONFIG_EXTENSIONS = [".ts", ".mjs", ".js", ".cjs"];
281
183
  function findEslintConfigFile(projectPath) {
282
184
  for (const ext of CONFIG_EXTENSIONS) {
283
- const configPath = join4(projectPath, `eslint.config${ext}`);
185
+ const configPath = join3(projectPath, `eslint.config${ext}`);
284
186
  if (existsSync3(configPath)) {
285
187
  return configPath;
286
188
  }
@@ -312,7 +214,7 @@ function getObjectPropertyValue(obj, keyName) {
312
214
  function hasSpreadProperties(obj) {
313
215
  if (!obj || obj.type !== "ObjectExpression") return false;
314
216
  return (obj.properties ?? []).some(
315
- (p2) => p2 && (p2.type === "SpreadElement" || p2.type === "SpreadProperty")
217
+ (p) => p && (p.type === "SpreadElement" || p.type === "SpreadProperty")
316
218
  );
317
219
  }
318
220
  var IGNORED_AST_KEYS = /* @__PURE__ */ new Set([
@@ -530,8 +432,8 @@ function findExistingDefaultImportLocalName(program, from) {
530
432
  function addLocalRuleImportsAst(mod, selectedRules, configPath, rulesRoot, fileExtension = ".js", isTypeScriptProject = false) {
531
433
  const importNames = /* @__PURE__ */ new Map();
532
434
  let changed = false;
533
- const configDir = dirname2(configPath);
534
- const rulesDir = join4(rulesRoot, ".uilint", "rules");
435
+ const configDir = dirname(configPath);
436
+ const rulesDir = join3(rulesRoot, ".uilint", "rules");
535
437
  const relativeRulesPath = relative(configDir, rulesDir).replace(/\\/g, "/");
536
438
  const normalizedRulesPath = relativeRulesPath.startsWith("./") || relativeRulesPath.startsWith("../") ? relativeRulesPath : `./${relativeRulesPath}`;
537
439
  const used = collectTopLevelBindings(mod.$ast);
@@ -564,8 +466,8 @@ function addLocalRuleRequiresAst(program, selectedRules, configPath, rulesRoot,
564
466
  if (!program || program.type !== "Program") {
565
467
  return { importNames, changed };
566
468
  }
567
- const configDir = dirname2(configPath);
568
- const rulesDir = join4(rulesRoot, ".uilint", "rules");
469
+ const configDir = dirname(configPath);
470
+ const rulesDir = join3(rulesRoot, ".uilint", "rules");
569
471
  const relativeRulesPath = relative(configDir, rulesDir).replace(/\\/g, "/");
570
472
  const normalizedRulesPath = relativeRulesPath.startsWith("./") || relativeRulesPath.startsWith("../") ? relativeRulesPath : `./${relativeRulesPath}`;
571
473
  const used = collectTopLevelBindings(program);
@@ -629,7 +531,7 @@ function updateExistingUilintConfigBlock(configObj, selectedRules, ruleImportNam
629
531
  const rulesObj = getObjectPropertyValue(configObj, "rules");
630
532
  if (pluginsObj?.type === "ObjectExpression") {
631
533
  const uilintPluginProp = pluginsObj.properties?.find(
632
- (p2) => (p2.type === "ObjectProperty" || p2.type === "Property") && (p2.key?.type === "Identifier" && p2.key.name === "uilint" || isStringLiteral(p2.key) && p2.key.value === "uilint")
534
+ (p) => (p.type === "ObjectProperty" || p.type === "Property") && (p.key?.type === "Identifier" && p.key.name === "uilint" || isStringLiteral(p.key) && p.key.value === "uilint")
633
535
  );
634
536
  if (uilintPluginProp) {
635
537
  const uilintValue = uilintPluginProp.value;
@@ -648,7 +550,7 @@ function updateExistingUilintConfigBlock(configObj, selectedRules, ruleImportNam
648
550
  }
649
551
  for (const [ruleId, importName] of ruleImportNames.entries()) {
650
552
  const exists = pluginRulesObj.properties?.some(
651
- (p2) => (p2.type === "ObjectProperty" || p2.type === "Property") && isStringLiteral(p2.key) && p2.key.value === ruleId
553
+ (p) => (p.type === "ObjectProperty" || p.type === "Property") && isStringLiteral(p.key) && p.key.value === ruleId
652
554
  );
653
555
  if (!exists) {
654
556
  const propCode = `{ "${ruleId}": ${importName} }`;
@@ -668,7 +570,7 @@ function updateExistingUilintConfigBlock(configObj, selectedRules, ruleImportNam
668
570
  2
669
571
  )}]` : `"${rule.defaultSeverity}"`;
670
572
  const existingPropIndex = rulesObj.properties?.findIndex(
671
- (p2) => (p2.type === "ObjectProperty" || p2.type === "Property") && isStringLiteral(p2.key) && p2.key.value === ruleKey
573
+ (p) => (p.type === "ObjectProperty" || p.type === "Property") && isStringLiteral(p.key) && p.key.value === ruleKey
672
574
  );
673
575
  const propCode = `{ "${ruleKey}": ${valueCode} }`;
674
576
  const tempObj = parseExpression(propCode).$ast;
@@ -782,7 +684,7 @@ async function installEslintPlugin(opts) {
782
684
  };
783
685
  }
784
686
  const configFilename = getEslintConfigFilename(configPath);
785
- const original = readFileSync3(configPath, "utf-8");
687
+ const original = readFileSync2(configPath, "utf-8");
786
688
  const isCommonJS = configPath.endsWith(".cjs");
787
689
  const ast = getUilintEslintConfigInfoFromSourceAst(original);
788
690
  if ("error" in ast) {
@@ -834,9 +736,9 @@ async function installEslintPlugin(opts) {
834
736
  };
835
737
  }
836
738
  let modifiedAst = false;
837
- const localRulesDir = join4(opts.projectPath, ".uilint", "rules");
739
+ const localRulesDir = join3(opts.projectPath, ".uilint", "rules");
838
740
  const workspaceRoot = findWorkspaceRoot(opts.projectPath);
839
- const workspaceRulesDir = join4(workspaceRoot, ".uilint", "rules");
741
+ const workspaceRulesDir = join3(workspaceRoot, ".uilint", "rules");
840
742
  const rulesRoot = existsSync3(localRulesDir) ? opts.projectPath : workspaceRoot;
841
743
  const isTypeScriptConfig = configPath.endsWith(".ts");
842
744
  let fileExtension = isTypeScriptConfig ? "" : ".js";
@@ -928,7 +830,7 @@ async function uninstallEslintPlugin(options) {
928
830
  };
929
831
  }
930
832
  try {
931
- const original = readFileSync3(configPath, "utf-8");
833
+ const original = readFileSync2(configPath, "utf-8");
932
834
  let updated = original.replace(
933
835
  /^import\s+\{[^}]*\}\s+from\s+["'][^"']*\.uilint\/rules[^"']*["'];?\s*$/gm,
934
836
  ""
@@ -1042,7 +944,7 @@ function extractOptionsFromValueNode(valueNode) {
1042
944
  function readRuleConfigsFromConfig(configPath) {
1043
945
  const configs = /* @__PURE__ */ new Map();
1044
946
  try {
1045
- const source = readFileSync3(configPath, "utf-8");
947
+ const source = readFileSync2(configPath, "utf-8");
1046
948
  const mod = parseModule(source);
1047
949
  const found = findExportedConfigArrayExpression(mod);
1048
950
  if (!found) {
@@ -1083,7 +985,7 @@ function findRulePropertyInConfigArray(arrayExpr, ruleId) {
1083
985
  }
1084
986
  function updateRuleSeverityInConfig(configPath, ruleId, severity) {
1085
987
  try {
1086
- const source = readFileSync3(configPath, "utf-8");
988
+ const source = readFileSync2(configPath, "utf-8");
1087
989
  const mod = parseModule(source);
1088
990
  const found = findExportedConfigArrayExpression(mod);
1089
991
  if (!found) {
@@ -1134,7 +1036,7 @@ function updateRuleSeverityInConfig(configPath, ruleId, severity) {
1134
1036
  }
1135
1037
  function updateRuleConfigInConfig(configPath, ruleId, severity, options) {
1136
1038
  try {
1137
- const source = readFileSync3(configPath, "utf-8");
1039
+ const source = readFileSync2(configPath, "utf-8");
1138
1040
  const mod = parseModule(source);
1139
1041
  const found = findExportedConfigArrayExpression(mod);
1140
1042
  if (!found) {
@@ -1168,10 +1070,10 @@ function updateRuleConfigInConfig(configPath, ruleId, severity, options) {
1168
1070
  }
1169
1071
 
1170
1072
  // src/utils/coverage-prepare.ts
1171
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
1073
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
1172
1074
  function injectCoverageConfig(vitestConfigPath) {
1173
1075
  try {
1174
- const content = readFileSync4(vitestConfigPath, "utf-8");
1076
+ const content = readFileSync3(vitestConfigPath, "utf-8");
1175
1077
  if (/coverage\s*:\s*\{/.test(content)) {
1176
1078
  return false;
1177
1079
  }
@@ -1266,21 +1168,6 @@ function needsCoveragePreparation(setup) {
1266
1168
  }
1267
1169
 
1268
1170
  export {
1269
- pc,
1270
- intro2 as intro,
1271
- outro2 as outro,
1272
- withSpinner,
1273
- createSpinner,
1274
- note2 as note,
1275
- log2 as log,
1276
- logInfo,
1277
- logSuccess,
1278
- logWarning,
1279
- logError,
1280
- select2 as select,
1281
- confirm2 as confirm,
1282
- text2 as text,
1283
- multiselect2 as multiselect,
1284
1171
  detectNextAppRouter,
1285
1172
  findNextAppRouterProjects,
1286
1173
  findEslintConfigFile,
@@ -1296,4 +1183,4 @@ export {
1296
1183
  prepareCoverage,
1297
1184
  needsCoveragePreparation
1298
1185
  };
1299
- //# sourceMappingURL=chunk-PVUDWWTL.js.map
1186
+ //# sourceMappingURL=chunk-KNZVCCXM.js.map