uilint 0.2.9 → 0.2.11
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/chunk-FRNXXIEM.js +197 -0
- package/dist/chunk-FRNXXIEM.js.map +1 -0
- package/dist/index.js +105 -151
- package/dist/index.js.map +1 -1
- package/dist/{install-ui-OEFHX4FG.js → install-ui-KI7YHOVZ.js} +939 -259
- package/dist/install-ui-KI7YHOVZ.js.map +1 -0
- package/package.json +3 -3
- package/dist/chunk-RHTG6DUD.js +0 -89
- package/dist/chunk-RHTG6DUD.js.map +0 -1
- package/dist/install-ui-OEFHX4FG.js.map +0 -1
|
@@ -0,0 +1,197 @@
|
|
|
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 multiselect2(options) {
|
|
88
|
+
const result = await p.multiselect({
|
|
89
|
+
message: options.message,
|
|
90
|
+
options: options.options,
|
|
91
|
+
required: options.required,
|
|
92
|
+
initialValues: options.initialValues
|
|
93
|
+
});
|
|
94
|
+
return handleCancel(result);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/utils/next-detect.ts
|
|
98
|
+
import { existsSync, readdirSync } from "fs";
|
|
99
|
+
import { join as join2 } from "path";
|
|
100
|
+
function fileExists(projectPath, relPath) {
|
|
101
|
+
return existsSync(join2(projectPath, relPath));
|
|
102
|
+
}
|
|
103
|
+
function detectNextAppRouter(projectPath) {
|
|
104
|
+
const roots = ["app", join2("src", "app")];
|
|
105
|
+
const candidates = [];
|
|
106
|
+
let chosenRoot = null;
|
|
107
|
+
for (const root of roots) {
|
|
108
|
+
if (existsSync(join2(projectPath, root))) {
|
|
109
|
+
chosenRoot = root;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!chosenRoot) return null;
|
|
114
|
+
const entryCandidates = [
|
|
115
|
+
join2(chosenRoot, "layout.tsx"),
|
|
116
|
+
join2(chosenRoot, "layout.jsx"),
|
|
117
|
+
join2(chosenRoot, "layout.ts"),
|
|
118
|
+
join2(chosenRoot, "layout.js"),
|
|
119
|
+
// Fallbacks (less ideal, but can work):
|
|
120
|
+
join2(chosenRoot, "page.tsx"),
|
|
121
|
+
join2(chosenRoot, "page.jsx")
|
|
122
|
+
];
|
|
123
|
+
for (const rel of entryCandidates) {
|
|
124
|
+
if (fileExists(projectPath, rel)) candidates.push(rel);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
appRoot: chosenRoot,
|
|
128
|
+
appRootAbs: join2(projectPath, chosenRoot),
|
|
129
|
+
candidates
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
133
|
+
"node_modules",
|
|
134
|
+
".git",
|
|
135
|
+
".next",
|
|
136
|
+
"dist",
|
|
137
|
+
"build",
|
|
138
|
+
"out",
|
|
139
|
+
".turbo",
|
|
140
|
+
".vercel",
|
|
141
|
+
".cursor",
|
|
142
|
+
"coverage",
|
|
143
|
+
".uilint"
|
|
144
|
+
]);
|
|
145
|
+
function findNextAppRouterProjects(rootDir, options) {
|
|
146
|
+
const maxDepth = options?.maxDepth ?? 4;
|
|
147
|
+
const ignoreDirs = options?.ignoreDirs ?? DEFAULT_IGNORE_DIRS;
|
|
148
|
+
const results = [];
|
|
149
|
+
const visited = /* @__PURE__ */ new Set();
|
|
150
|
+
function walk(dir, depth) {
|
|
151
|
+
if (depth > maxDepth) return;
|
|
152
|
+
if (visited.has(dir)) return;
|
|
153
|
+
visited.add(dir);
|
|
154
|
+
const detection = detectNextAppRouter(dir);
|
|
155
|
+
if (detection) {
|
|
156
|
+
results.push({ projectPath: dir, detection });
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
let entries = [];
|
|
160
|
+
try {
|
|
161
|
+
entries = readdirSync(dir, { withFileTypes: true }).map((d) => ({
|
|
162
|
+
name: d.name,
|
|
163
|
+
isDirectory: d.isDirectory()
|
|
164
|
+
}));
|
|
165
|
+
} catch {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (const ent of entries) {
|
|
169
|
+
if (!ent.isDirectory) continue;
|
|
170
|
+
if (ignoreDirs.has(ent.name)) continue;
|
|
171
|
+
if (ent.name.startsWith(".") && ent.name !== ".") continue;
|
|
172
|
+
walk(join2(dir, ent.name), depth + 1);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
walk(rootDir, 0);
|
|
176
|
+
return results;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export {
|
|
180
|
+
pc,
|
|
181
|
+
intro2 as intro,
|
|
182
|
+
outro2 as outro,
|
|
183
|
+
withSpinner,
|
|
184
|
+
createSpinner,
|
|
185
|
+
note2 as note,
|
|
186
|
+
log2 as log,
|
|
187
|
+
logInfo,
|
|
188
|
+
logSuccess,
|
|
189
|
+
logWarning,
|
|
190
|
+
logError,
|
|
191
|
+
select2 as select,
|
|
192
|
+
confirm2 as confirm,
|
|
193
|
+
multiselect2 as multiselect,
|
|
194
|
+
detectNextAppRouter,
|
|
195
|
+
findNextAppRouterProjects
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=chunk-FRNXXIEM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/prompts.ts","../src/utils/next-detect.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","import { existsSync, readdirSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface NextAppRouterDetection {\n /**\n * Relative path to the Next App Router root dir (either \"app\" or \"src/app\").\n */\n appRoot: string;\n /**\n * Absolute path to the App Router root dir.\n */\n appRootAbs: string;\n /**\n * Candidate entry files (relative paths) that are good injection targets.\n */\n candidates: string[];\n}\n\nfunction fileExists(projectPath: string, relPath: string): boolean {\n return existsSync(join(projectPath, relPath));\n}\n\nexport function detectNextAppRouter(\n projectPath: string\n): NextAppRouterDetection | null {\n const roots = [\"app\", join(\"src\", \"app\")];\n const candidates: string[] = [];\n\n let chosenRoot: string | null = null;\n for (const root of roots) {\n if (existsSync(join(projectPath, root))) {\n chosenRoot = root;\n break;\n }\n }\n\n if (!chosenRoot) return null;\n\n // Prioritize layout files (Next App Router canonical integration point).\n const entryCandidates = [\n join(chosenRoot, \"layout.tsx\"),\n join(chosenRoot, \"layout.jsx\"),\n join(chosenRoot, \"layout.ts\"),\n join(chosenRoot, \"layout.js\"),\n // Fallbacks (less ideal, but can work):\n join(chosenRoot, \"page.tsx\"),\n join(chosenRoot, \"page.jsx\"),\n ];\n\n for (const rel of entryCandidates) {\n if (fileExists(projectPath, rel)) candidates.push(rel);\n }\n\n // If nothing exists, still return detection so routes can be installed.\n return {\n appRoot: chosenRoot,\n appRootAbs: join(projectPath, chosenRoot),\n candidates,\n };\n}\n\nexport interface NextAppRouterProjectMatch {\n /**\n * Absolute path to the Next project root (dir containing app/ or src/app/).\n */\n projectPath: string;\n detection: NextAppRouterDetection;\n}\n\nconst DEFAULT_IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \"dist\",\n \"build\",\n \"out\",\n \".turbo\",\n \".vercel\",\n \".cursor\",\n \"coverage\",\n \".uilint\",\n]);\n\n/**\n * Best-effort monorepo discovery for Next.js App Router apps.\n *\n * Walks down from `rootDir` looking for directories that contain `app/` or\n * `src/app/`. Skips common large/irrelevant dirs.\n */\nexport function findNextAppRouterProjects(\n rootDir: string,\n options?: { maxDepth?: number; ignoreDirs?: Set<string> }\n): NextAppRouterProjectMatch[] {\n const maxDepth = options?.maxDepth ?? 4;\n const ignoreDirs = options?.ignoreDirs ?? DEFAULT_IGNORE_DIRS;\n const results: NextAppRouterProjectMatch[] = [];\n const visited = new Set<string>();\n\n function walk(dir: string, depth: number) {\n if (depth > maxDepth) return;\n if (visited.has(dir)) return;\n visited.add(dir);\n\n const detection = detectNextAppRouter(dir);\n if (detection) {\n results.push({ projectPath: dir, detection });\n // Don't descend further once we found a project root (avoid nested hits).\n return;\n }\n\n let entries: Array<{ name: string; isDirectory: boolean }> = [];\n try {\n entries = readdirSync(dir, { withFileTypes: true }).map((d) => ({\n name: d.name,\n isDirectory: d.isDirectory(),\n }));\n } catch {\n return;\n }\n\n for (const ent of entries) {\n if (!ent.isDirectory) continue;\n if (ignoreDirs.has(ent.name)) continue;\n // Skip hidden dirs by default (except `src` which matters)\n if (ent.name.startsWith(\".\") && ent.name !== \".\") continue;\n walk(join(dir, ent.name), depth + 1);\n }\n }\n\n walk(rootDir, 0);\n return results;\n}\n"],"mappings":"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","names":["intro","outro","cancel","cancel","note","log","select","confirm","multiselect","join"]}
|