@sgx4u/ui 1.0.6
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/CHANGELOG.md +69 -0
- package/LICENSE +7 -0
- package/README.md +161 -0
- package/SECURITY.md +5 -0
- package/SUPPORT.md +5 -0
- package/dist/bin.cjs +1218 -0
- package/dist/bin.d.cts +1 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +4 -0
- package/dist/chunk-SWLJZFBL.js +890 -0
- package/dist/cli-UJKWK2HV.js +200 -0
- package/dist/index.cjs +924 -0
- package/dist/index.d.cts +20 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +10 -0
- package/logo.svg +18 -0
- package/package.json +88 -0
|
@@ -0,0 +1,890 @@
|
|
|
1
|
+
// src/commands/add.ts
|
|
2
|
+
import fs4 from "fs-extra";
|
|
3
|
+
import inquirer2 from "inquirer";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import path4 from "path";
|
|
6
|
+
|
|
7
|
+
// src/commands/utils/config.util.ts
|
|
8
|
+
import fs2 from "fs-extra";
|
|
9
|
+
import inquirer from "inquirer";
|
|
10
|
+
import path2 from "path";
|
|
11
|
+
|
|
12
|
+
// src/commands/utils/alias.util.ts
|
|
13
|
+
import fs from "fs-extra";
|
|
14
|
+
import path from "path";
|
|
15
|
+
async function detectAlias(cwd) {
|
|
16
|
+
const configFiles = ["tsconfig.json", "jsconfig.json"];
|
|
17
|
+
for (const file of configFiles) {
|
|
18
|
+
const configPath = path.join(cwd, file);
|
|
19
|
+
if (!fs.existsSync(configPath)) continue;
|
|
20
|
+
const config = await fs.readJson(configPath);
|
|
21
|
+
const paths = config?.compilerOptions?.paths;
|
|
22
|
+
if (!paths || typeof paths !== "object") continue;
|
|
23
|
+
for (const [alias, targets] of Object.entries(paths)) {
|
|
24
|
+
if (!alias.endsWith("/*")) continue;
|
|
25
|
+
if (!Array.isArray(targets) || !targets[0]) continue;
|
|
26
|
+
const prefix = alias.replace("/*", "");
|
|
27
|
+
const baseDir = targets[0].replace("/*", "");
|
|
28
|
+
return { enabled: true, prefix, baseDir };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/commands/utils/config.util.ts
|
|
35
|
+
async function getConfig(cwd) {
|
|
36
|
+
try {
|
|
37
|
+
const configPath = path2.resolve(cwd, "ui.config.json");
|
|
38
|
+
const configExists = await fs2.pathExists(configPath);
|
|
39
|
+
if (configExists) return await fs2.readJson(configPath);
|
|
40
|
+
return null;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function createConfig({
|
|
46
|
+
cwd,
|
|
47
|
+
projectInfo
|
|
48
|
+
}) {
|
|
49
|
+
try {
|
|
50
|
+
const detectedDir = await detectUIDirectory(cwd);
|
|
51
|
+
const { uiDir, environment, typescript } = await inquirer.prompt([
|
|
52
|
+
{
|
|
53
|
+
type: "input",
|
|
54
|
+
name: "uiDir",
|
|
55
|
+
message: "Where would you like to add UI components?",
|
|
56
|
+
default: detectedDir,
|
|
57
|
+
validate: (input) => {
|
|
58
|
+
if (!input.trim()) return "Please enter a valid directory path.";
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: "list",
|
|
64
|
+
name: "environment",
|
|
65
|
+
message: "Which environment are you using?",
|
|
66
|
+
choices: [
|
|
67
|
+
{ name: "React", value: "react" },
|
|
68
|
+
{ name: "Next.js", value: "next" }
|
|
69
|
+
],
|
|
70
|
+
default: projectInfo.project
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
type: "confirm",
|
|
74
|
+
name: "typescript",
|
|
75
|
+
message: "Do you want to use TypeScript?",
|
|
76
|
+
default: projectInfo.hasTypeScript
|
|
77
|
+
}
|
|
78
|
+
]);
|
|
79
|
+
const finalUiPath = uiDir.startsWith("/") ? uiDir : `./${uiDir}`;
|
|
80
|
+
const aliasInfo = await detectAlias(cwd);
|
|
81
|
+
const aliases = aliasInfo ? {
|
|
82
|
+
[aliasInfo.prefix]: aliasInfo.baseDir,
|
|
83
|
+
[`${aliasInfo.prefix}/ui`]: finalUiPath,
|
|
84
|
+
[`${aliasInfo.prefix}/elements`]: `${finalUiPath}/elements`,
|
|
85
|
+
[`${aliasInfo.prefix}/modules`]: `${finalUiPath}/modules`,
|
|
86
|
+
[`${aliasInfo.prefix}/helpers`]: `${finalUiPath}/helpers`,
|
|
87
|
+
[`${aliasInfo.prefix}/hooks`]: `${finalUiPath}/hooks`,
|
|
88
|
+
[`${aliasInfo.prefix}/utils`]: `${finalUiPath}/utils`
|
|
89
|
+
} : {
|
|
90
|
+
ui: finalUiPath,
|
|
91
|
+
elements: `${finalUiPath}/elements`,
|
|
92
|
+
modules: `${finalUiPath}/modules`,
|
|
93
|
+
helpers: `${finalUiPath}/helpers`,
|
|
94
|
+
hooks: `${finalUiPath}/hooks`,
|
|
95
|
+
utils: `${finalUiPath}/utils`
|
|
96
|
+
};
|
|
97
|
+
const config = {
|
|
98
|
+
uiDir: finalUiPath,
|
|
99
|
+
environment,
|
|
100
|
+
typescript,
|
|
101
|
+
aliases,
|
|
102
|
+
registry: "https://registry.npmjs.org"
|
|
103
|
+
};
|
|
104
|
+
const configPath = path2.join(cwd, "ui.config.json");
|
|
105
|
+
await fs2.writeJson(configPath, config, { spaces: 4 });
|
|
106
|
+
return config;
|
|
107
|
+
} catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function detectUIDirectory(cwd) {
|
|
112
|
+
const srcUiPath = path2.join(cwd, "src");
|
|
113
|
+
if (await fs2.pathExists(srcUiPath)) return "src/ui";
|
|
114
|
+
return "ui";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/commands/utils/package.util.ts
|
|
118
|
+
import fs3 from "fs-extra";
|
|
119
|
+
import { execSync } from "child_process";
|
|
120
|
+
import path3 from "path";
|
|
121
|
+
async function getProjectInfo(cwd) {
|
|
122
|
+
const hasReact = await isPackageInstalled({ packageName: "react", cwd });
|
|
123
|
+
const hasNextJS = await isPackageInstalled({ packageName: "next", cwd });
|
|
124
|
+
const hasTypeScript = await isPackageInstalled({ packageName: "typescript", cwd });
|
|
125
|
+
const tailwindVersion = await getTailwindVersion(cwd);
|
|
126
|
+
const lucideVersion = await getPackageVersion({ packageName: "lucide-react", cwd });
|
|
127
|
+
const packageManager = await detectPackageManager(cwd);
|
|
128
|
+
const project = hasNextJS ? "next" : hasReact ? "react" : "none";
|
|
129
|
+
return { project, hasTypeScript, tailwindVersion, lucideVersion, packageManager };
|
|
130
|
+
}
|
|
131
|
+
async function isPackageInstalled({ packageName, cwd }) {
|
|
132
|
+
try {
|
|
133
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
134
|
+
if (!await fs3.pathExists(packageJsonPath)) return false;
|
|
135
|
+
const packageJson = await fs3.readJson(packageJsonPath);
|
|
136
|
+
const allDeps = {
|
|
137
|
+
...packageJson.dependencies,
|
|
138
|
+
...packageJson.devDependencies,
|
|
139
|
+
...packageJson.peerDependencies
|
|
140
|
+
};
|
|
141
|
+
return Object.keys(allDeps).some((dependency) => dependency === packageName);
|
|
142
|
+
} catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function installDependencies({
|
|
147
|
+
cwd,
|
|
148
|
+
packageManager,
|
|
149
|
+
dependencies
|
|
150
|
+
}) {
|
|
151
|
+
try {
|
|
152
|
+
const installCommand = getInstallCommand({ packageManager, packages: dependencies, isDev: false });
|
|
153
|
+
execSync(installCommand, { cwd, stdio: "pipe", encoding: "utf8" });
|
|
154
|
+
return true;
|
|
155
|
+
} catch {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function getPackageVersion({ packageName, cwd }) {
|
|
160
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
161
|
+
if (!await fs3.pathExists(packageJsonPath)) return null;
|
|
162
|
+
const packageJson = await fs3.readJson(packageJsonPath);
|
|
163
|
+
const allDeps = {
|
|
164
|
+
...packageJson.dependencies,
|
|
165
|
+
...packageJson.devDependencies,
|
|
166
|
+
...packageJson.peerDependencies
|
|
167
|
+
};
|
|
168
|
+
const rawVersion = allDeps[packageName];
|
|
169
|
+
if (rawVersion == null || typeof rawVersion !== "string") return null;
|
|
170
|
+
const packageVersion = rawVersion.replace(/^[\^~>=]+/, "").split(".");
|
|
171
|
+
if (packageVersion.length === 0 || packageVersion[0] === "") return null;
|
|
172
|
+
const version = packageVersion[1] != null ? `${packageVersion[0]}.${packageVersion[1]}` : packageVersion[0];
|
|
173
|
+
const parsed = Number.parseFloat(version);
|
|
174
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
175
|
+
}
|
|
176
|
+
async function detectPackageManager(cwd) {
|
|
177
|
+
try {
|
|
178
|
+
const pnpmLockPath = path3.join(cwd, "pnpm-lock.yaml");
|
|
179
|
+
if (await fs3.pathExists(pnpmLockPath)) return "pnpm";
|
|
180
|
+
const yarnLockPath = path3.join(cwd, "yarn.lock");
|
|
181
|
+
if (await fs3.pathExists(yarnLockPath)) return "yarn";
|
|
182
|
+
const bunLockPath = path3.join(cwd, "bun.lockb");
|
|
183
|
+
if (await fs3.pathExists(bunLockPath)) return "bun";
|
|
184
|
+
const npmLockPath = path3.join(cwd, "package-lock.json");
|
|
185
|
+
if (await fs3.pathExists(npmLockPath)) return "npm";
|
|
186
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
187
|
+
if (await fs3.pathExists(packageJsonPath)) {
|
|
188
|
+
try {
|
|
189
|
+
const packageJson = await fs3.readJson(packageJsonPath);
|
|
190
|
+
if (packageJson.packageManager) {
|
|
191
|
+
const packageManager = packageJson.packageManager;
|
|
192
|
+
if (packageManager.includes("pnpm")) return "pnpm";
|
|
193
|
+
if (packageManager.includes("yarn")) return "yarn";
|
|
194
|
+
if (packageManager.includes("bun")) return "bun";
|
|
195
|
+
if (packageManager.includes("npm")) return "npm";
|
|
196
|
+
}
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
execSync("pnpm --version", { stdio: "pipe", cwd });
|
|
202
|
+
return "pnpm";
|
|
203
|
+
} catch {
|
|
204
|
+
try {
|
|
205
|
+
execSync("yarn --version", { stdio: "pipe", cwd });
|
|
206
|
+
return "yarn";
|
|
207
|
+
} catch {
|
|
208
|
+
try {
|
|
209
|
+
execSync("bun --version", { stdio: "pipe", cwd });
|
|
210
|
+
return "bun";
|
|
211
|
+
} catch {
|
|
212
|
+
return "npm";
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
return "npm";
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function getInstallCommand({
|
|
221
|
+
packageManager,
|
|
222
|
+
packages,
|
|
223
|
+
isDev
|
|
224
|
+
}) {
|
|
225
|
+
const packagesStr = packages.join(" ");
|
|
226
|
+
switch (packageManager) {
|
|
227
|
+
case "pnpm":
|
|
228
|
+
return isDev ? `pnpm add -D ${packagesStr}` : `pnpm add ${packagesStr}`;
|
|
229
|
+
case "yarn":
|
|
230
|
+
return isDev ? `yarn add -D ${packagesStr}` : `yarn add ${packagesStr}`;
|
|
231
|
+
case "bun":
|
|
232
|
+
return isDev ? `bun add -d ${packagesStr}` : `bun add ${packagesStr}`;
|
|
233
|
+
default:
|
|
234
|
+
return isDev ? `npm install --save-dev ${packagesStr}` : `npm install ${packagesStr}`;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async function getTailwindVersion(cwd) {
|
|
238
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
239
|
+
if (!await fs3.pathExists(packageJsonPath)) return "none";
|
|
240
|
+
const packageJson = await fs3.readJson(packageJsonPath);
|
|
241
|
+
const allDeps = {
|
|
242
|
+
...packageJson.dependencies,
|
|
243
|
+
...packageJson.devDependencies,
|
|
244
|
+
...packageJson.peerDependencies
|
|
245
|
+
};
|
|
246
|
+
if (allDeps["tailwindcss"] && (allDeps["tailwindcss"].startsWith("4") || allDeps["tailwindcss"].startsWith("^4"))) {
|
|
247
|
+
return "v4";
|
|
248
|
+
}
|
|
249
|
+
return "none";
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/commands/utils/registry.util.ts
|
|
253
|
+
var GITHUB_REPO = "sgx4u/sgx4u-ui";
|
|
254
|
+
var GITHUB_BRANCH = "production";
|
|
255
|
+
var GITHUB_RAW_BASE = `https://raw.githubusercontent.com/${GITHUB_REPO}/${GITHUB_BRANCH}`;
|
|
256
|
+
async function fetchRegistry(projectType) {
|
|
257
|
+
try {
|
|
258
|
+
let registryEnvironment;
|
|
259
|
+
if (projectType === "next" || projectType === "react") registryEnvironment = "react";
|
|
260
|
+
else return null;
|
|
261
|
+
const registryFile = `registry.${registryEnvironment}.json`;
|
|
262
|
+
const registryUrl = `${GITHUB_RAW_BASE}/src/content/${registryFile}`;
|
|
263
|
+
const response = await fetch(registryUrl);
|
|
264
|
+
if (!response.ok) return null;
|
|
265
|
+
const registry = await response.json();
|
|
266
|
+
return registry;
|
|
267
|
+
} catch {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async function fetchComponent({
|
|
272
|
+
componentName,
|
|
273
|
+
projectType
|
|
274
|
+
}) {
|
|
275
|
+
try {
|
|
276
|
+
if (projectType === "none") return null;
|
|
277
|
+
const registry = await fetchRegistry(projectType);
|
|
278
|
+
if (!registry) return null;
|
|
279
|
+
for (const [registryKey, component] of Object.entries(registry.components)) {
|
|
280
|
+
if (registryKey === componentName) {
|
|
281
|
+
return {
|
|
282
|
+
...component,
|
|
283
|
+
name: registryKey
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return null;
|
|
288
|
+
} catch {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
async function fetchComponentFile(filePath) {
|
|
293
|
+
try {
|
|
294
|
+
const fileUrl = `${GITHUB_RAW_BASE}/${filePath}`;
|
|
295
|
+
const response = await fetch(fileUrl);
|
|
296
|
+
if (!response.ok) return null;
|
|
297
|
+
return await response.text();
|
|
298
|
+
} catch {
|
|
299
|
+
console.log(`\u26A0\uFE0F Failed to fetch file from GitHub: ${filePath}`);
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/commands/validation/data.validate.ts
|
|
305
|
+
function validateComponentName(name) {
|
|
306
|
+
if (!name || name.trim().length < 1 || typeof name !== "string") return false;
|
|
307
|
+
if (!/^[a-zA-Z0-9-_.]+$/.test(name)) return false;
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
function validateDirectory(directory) {
|
|
311
|
+
if (!directory || directory.trim().length < 1 || typeof directory !== "string") return false;
|
|
312
|
+
if (directory.includes("..")) return false;
|
|
313
|
+
if (directory.includes("\\") || directory.includes("//")) return false;
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/commands/add.ts
|
|
318
|
+
async function addComponent(componentName) {
|
|
319
|
+
try {
|
|
320
|
+
const cwd = process.cwd();
|
|
321
|
+
const validationSpinner = ora(" Validating...").start();
|
|
322
|
+
if (!validateComponentName(componentName)) {
|
|
323
|
+
validationSpinner.fail();
|
|
324
|
+
console.log("\u274C Component name is invalid!");
|
|
325
|
+
process.exit(1);
|
|
326
|
+
}
|
|
327
|
+
const config = await getConfig(cwd);
|
|
328
|
+
if (!config) {
|
|
329
|
+
validationSpinner.fail();
|
|
330
|
+
console.log("\u274C Failed to get configuration! Please initialize SGX4U UI first!");
|
|
331
|
+
process.exit(1);
|
|
332
|
+
}
|
|
333
|
+
const projectInfo = await getProjectInfo(cwd);
|
|
334
|
+
if (projectInfo.project === "none") {
|
|
335
|
+
console.log("\u274C No supported project detected!");
|
|
336
|
+
process.exit(1);
|
|
337
|
+
}
|
|
338
|
+
validationSpinner.succeed();
|
|
339
|
+
const installingSpinner = ora(` Installing ${componentName}`).start();
|
|
340
|
+
const component = await fetchComponent({ componentName, projectType: config.environment });
|
|
341
|
+
if (!component) {
|
|
342
|
+
installingSpinner.fail();
|
|
343
|
+
console.log("\u274C Failed to fetch component!");
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
const uiDirectory = config.uiDir;
|
|
347
|
+
const normalizedUiDirectory = uiDirectory.replace(/^[./\\]+/, "");
|
|
348
|
+
if (!normalizedUiDirectory || !validateDirectory(normalizedUiDirectory)) {
|
|
349
|
+
installingSpinner.fail();
|
|
350
|
+
console.log("\u274C Invalid directory!");
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
const baseDirectory = path4.join(cwd, normalizedUiDirectory);
|
|
354
|
+
const allFilesToInstall = /* @__PURE__ */ new Map();
|
|
355
|
+
const existingFiles = [];
|
|
356
|
+
const filesToProcess = component.files;
|
|
357
|
+
for (const file of filesToProcess) {
|
|
358
|
+
const normalizedOutputPath = file.outputPath.replace(/^ui[\\/]/, "");
|
|
359
|
+
const targetPath = path4.join(baseDirectory, normalizedOutputPath);
|
|
360
|
+
if (await fs4.pathExists(targetPath)) {
|
|
361
|
+
existingFiles.push(file.outputPath);
|
|
362
|
+
} else {
|
|
363
|
+
allFilesToInstall.set(file.outputPath, {
|
|
364
|
+
filePath: file.path,
|
|
365
|
+
targetPath
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (existingFiles.length > 0) {
|
|
370
|
+
installingSpinner.stop();
|
|
371
|
+
console.log(`\u26A0\uFE0F Skipping existing files:`);
|
|
372
|
+
existingFiles.forEach((file) => console.log(` \u2022 ${file}`));
|
|
373
|
+
}
|
|
374
|
+
const installedFiles = [];
|
|
375
|
+
for (const [relativePath, { filePath, targetPath }] of allFilesToInstall) {
|
|
376
|
+
try {
|
|
377
|
+
const content = await fetchComponentFile(filePath);
|
|
378
|
+
if (!content) {
|
|
379
|
+
installingSpinner.fail();
|
|
380
|
+
console.log(`\u26A0\uFE0F Failed to fetch ${relativePath}`);
|
|
381
|
+
process.exit(1);
|
|
382
|
+
}
|
|
383
|
+
await fs4.ensureDir(path4.dirname(targetPath));
|
|
384
|
+
await fs4.writeFile(targetPath, content, "utf8");
|
|
385
|
+
installedFiles.push(relativePath);
|
|
386
|
+
} catch (error) {
|
|
387
|
+
installingSpinner.fail();
|
|
388
|
+
console.log(`\u26A0\uFE0F Failed to install ${relativePath}: ${error}`);
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (installedFiles.length === 0) {
|
|
393
|
+
installingSpinner.succeed();
|
|
394
|
+
console.log(`\u2714 ${componentName} is already up to date!`);
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
installingSpinner.succeed();
|
|
398
|
+
console.log("\u{1F4C1} Added files:");
|
|
399
|
+
installedFiles.forEach((file) => console.log(` \u2022 ${file}`));
|
|
400
|
+
const allPackageDependencies = new Set(component.dependencies);
|
|
401
|
+
if (allPackageDependencies.size > 0) {
|
|
402
|
+
console.log("\u{1F4E6} Dependencies detected:");
|
|
403
|
+
const installedDependencies = [];
|
|
404
|
+
const missingDependencies = [];
|
|
405
|
+
for (const dependency of Array.from(allPackageDependencies)) {
|
|
406
|
+
if (await isPackageInstalled({ packageName: dependency, cwd })) installedDependencies.push(dependency);
|
|
407
|
+
else missingDependencies.push(dependency);
|
|
408
|
+
}
|
|
409
|
+
if (installedDependencies.length > 0) {
|
|
410
|
+
console.log("\u2714 Already installed dependencies:");
|
|
411
|
+
installedDependencies.forEach((dep) => console.log(` \u2022 ${dep}`));
|
|
412
|
+
}
|
|
413
|
+
if (missingDependencies.length > 0) {
|
|
414
|
+
console.log("\u274C Missing dependencies:");
|
|
415
|
+
missingDependencies.forEach((dep) => console.log(` \u2022 ${dep}`));
|
|
416
|
+
const { installDeps } = await inquirer2.prompt([
|
|
417
|
+
{
|
|
418
|
+
type: "confirm",
|
|
419
|
+
name: "installDeps",
|
|
420
|
+
message: `Auto install missing dependencies using ${projectInfo.packageManager}?`,
|
|
421
|
+
default: true
|
|
422
|
+
}
|
|
423
|
+
]);
|
|
424
|
+
if (installDeps) {
|
|
425
|
+
console.log(`\u{1F4E6} Installing missing dependencies using ${projectInfo.packageManager}...`);
|
|
426
|
+
const dependencyInstalled = await installDependencies({
|
|
427
|
+
cwd,
|
|
428
|
+
packageManager: projectInfo.packageManager,
|
|
429
|
+
dependencies: missingDependencies
|
|
430
|
+
});
|
|
431
|
+
if (dependencyInstalled) console.log("\u2714 Missing dependencies installed successfully!");
|
|
432
|
+
else console.log("\u274C Failed to install missing dependencies!");
|
|
433
|
+
} else {
|
|
434
|
+
console.log("\u26A0\uFE0F Please install missing dependencies manually:");
|
|
435
|
+
missingDependencies.forEach((dep) => console.log(` \u2022 ${dep}`));
|
|
436
|
+
}
|
|
437
|
+
} else {
|
|
438
|
+
console.log("\u2714 All dependencies are already installed!");
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
process.exit(1);
|
|
442
|
+
} catch (error) {
|
|
443
|
+
console.error(`\u274C Error: ${error}`);
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// src/commands/init.ts
|
|
449
|
+
import inquirer3 from "inquirer";
|
|
450
|
+
import ora2 from "ora";
|
|
451
|
+
|
|
452
|
+
// src/commands/utils/css.util.ts
|
|
453
|
+
import fs5 from "fs-extra";
|
|
454
|
+
import path5 from "path";
|
|
455
|
+
|
|
456
|
+
// src/commands/data/theme-tailwind-v4.data.ts
|
|
457
|
+
var themeVariablesV4 = `@import 'tailwindcss';
|
|
458
|
+
|
|
459
|
+
@custom-variant dark (&:is(.dark *));
|
|
460
|
+
|
|
461
|
+
:root {
|
|
462
|
+
--background: oklch(100% 0 0); /* #ffffff */
|
|
463
|
+
--background-light: oklch(97% 0 0); /* #f5f5f5 */
|
|
464
|
+
--foreground: oklch(26.9% 0 0); /* #262626 */
|
|
465
|
+
|
|
466
|
+
--primary: oklch(26.9% 0 0); /* #262626 */
|
|
467
|
+
--primary-dark: oklch(14.5% 0 0); /* #0a0a0a */
|
|
468
|
+
--primary-light: oklch(70.8% 0 0); /* #a1a1a1 */
|
|
469
|
+
--primary-foreground: var(--background);
|
|
470
|
+
|
|
471
|
+
--secondary: oklch(51.1% 0.262 276.966); /* #4f39f6 */
|
|
472
|
+
--secondary-dark: oklch(45.7% 0.24 277.023); /* #432dd7 */
|
|
473
|
+
--secondary-light: oklch(93% 0.034 272.788); /* #e0e7ff */
|
|
474
|
+
--secondary-foreground: var(--background);
|
|
475
|
+
|
|
476
|
+
--success: oklch(72.3% 0.219 149.579); /* #00c950 */
|
|
477
|
+
--success-dark: oklch(62.7% 0.194 149.214); /* #00a63e */
|
|
478
|
+
--success-light: oklch(96.2% 0.044 156.743); /* #dcfce7 */
|
|
479
|
+
--success-foreground: var(--background);
|
|
480
|
+
|
|
481
|
+
--warn: oklch(82.8% 0.189 84.429); /* #ffb900 */
|
|
482
|
+
--warn-dark: oklch(76.9% 0.188 70.08); /* #fe9a00 */
|
|
483
|
+
--warn-light: oklch(96.2% 0.059 95.617); /* #fef3c6 */
|
|
484
|
+
--warn-foreground: var(--background);
|
|
485
|
+
|
|
486
|
+
--danger: oklch(63.7% 0.237 25.331); /* #fb2c36 */
|
|
487
|
+
--danger-dark: oklch(57.7% 0.245 27.325); /* #e7000b */
|
|
488
|
+
--danger-light: oklch(93.6% 0.032 17.717); /* #ffe2e2 */
|
|
489
|
+
--danger-foreground: var(--background);
|
|
490
|
+
|
|
491
|
+
--muted: oklch(87% 0 0); /* #d4d4d4 */
|
|
492
|
+
--muted-dark: oklch(70.8% 0 0); /* #a1a1a1 */
|
|
493
|
+
--muted-light: oklch(95.514% 0.00011 271.152); /* #f0f0f0 */
|
|
494
|
+
--muted-foreground: oklch(43.9% 0 0); /* #525252 */
|
|
495
|
+
|
|
496
|
+
--card: var(--background);
|
|
497
|
+
|
|
498
|
+
--light: var(--background);
|
|
499
|
+
--dark: var(--foreground);
|
|
500
|
+
--border: var(--muted-light);
|
|
501
|
+
--input-placeholder: oklch(70.8% 0 0); /* #a1a1a1 */
|
|
502
|
+
|
|
503
|
+
--radius: 0.5rem;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.dark {
|
|
507
|
+
--background: oklch(23.929% 0.00003 271.152); /* #1f1f1f */
|
|
508
|
+
--background-light: oklch(26.9% 0 0); /* #262626 */
|
|
509
|
+
--foreground: oklch(98.5% 0 0); /* #fafafa */
|
|
510
|
+
|
|
511
|
+
--primary: oklch(97% 0 0); /* #f5f5f5 */
|
|
512
|
+
--primary-dark: oklch(92.2% 0 0); /* #e5e5e5 */
|
|
513
|
+
--primary-light: oklch(98.5% 0 0); /* #fafafa */
|
|
514
|
+
--primary-foreground: var(--background);
|
|
515
|
+
|
|
516
|
+
--secondary: oklch(0.6009 0.1957 277.79); /* #696cf2 */
|
|
517
|
+
--secondary-dark: oklch(0.5348 0.2183 278.55); /* #5951e6 */
|
|
518
|
+
--secondary-light: oklch(93% 0.034 272.788); /* #e0e7ff */
|
|
519
|
+
--secondary-foreground: var(--foreground);
|
|
520
|
+
|
|
521
|
+
--success: oklch(0.8152 0.1685 152.67); /* #5be18c */
|
|
522
|
+
--success-dark: oklch(0.7665 0.2043 149.52); /* #25d566 */
|
|
523
|
+
--success-light: oklch(96.2% 0.044 156.743); /* #dcfce7 */
|
|
524
|
+
--success-foreground: var(--foreground);
|
|
525
|
+
|
|
526
|
+
--warn: oklch(82.8% 0.189 84.429); /* #ffb900 */
|
|
527
|
+
--warn-dark: oklch(76.9% 0.188 70.08); /* #fe9a00 */
|
|
528
|
+
--warn-light: oklch(96.2% 0.059 95.617); /* #fef3c6 */
|
|
529
|
+
--warn-foreground: var(--foreground);
|
|
530
|
+
|
|
531
|
+
--danger: oklch(0.7287 0.1531 21.55); /* #f97c7c */
|
|
532
|
+
--danger-dark: oklch(0.6605 0.190501 23.9375); /* #f15656 */
|
|
533
|
+
--danger-light: oklch(93.6% 0.032 17.717); /* #ffe2e2 */
|
|
534
|
+
--danger-foreground: var(--foreground);
|
|
535
|
+
|
|
536
|
+
--muted: oklch(43.9% 0 0); /* #525252 */
|
|
537
|
+
--muted-dark: oklch(37.1% 0 0); /* #404040 */
|
|
538
|
+
--muted-light: oklch(55.6% 0 0); /* #737373 */
|
|
539
|
+
--muted-foreground: oklch(97% 0.001 106.424); /* #f5f5f5 */
|
|
540
|
+
|
|
541
|
+
--card: var(--background);
|
|
542
|
+
|
|
543
|
+
--light: var(--foreground);
|
|
544
|
+
--dark: var(--background);
|
|
545
|
+
--border: var(--muted-light);
|
|
546
|
+
--input-placeholder: oklch(70.8% 0 0); /* #a1a1a1 */
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
@theme {
|
|
550
|
+
--breakpoint-mobile: 36rem;
|
|
551
|
+
--breakpoint-tablet: 48rem;
|
|
552
|
+
--breakpoint-laptop: 64rem;
|
|
553
|
+
--breakpoint-desktop: 80rem;
|
|
554
|
+
--breakpoint-wide: 90rem;
|
|
555
|
+
|
|
556
|
+
--container-mobile: 36rem;
|
|
557
|
+
--container-tablet: 48rem;
|
|
558
|
+
--container-laptop: 64rem;
|
|
559
|
+
--container-desktop: 80rem;
|
|
560
|
+
--container-wide: 90rem;
|
|
561
|
+
|
|
562
|
+
--text-xxs: 0.625rem;
|
|
563
|
+
|
|
564
|
+
@keyframes animate-gradient {
|
|
565
|
+
0% {
|
|
566
|
+
background-position: 100% 50%;
|
|
567
|
+
}
|
|
568
|
+
to {
|
|
569
|
+
background-position: 0 50%;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
@keyframes animate-heart-beat {
|
|
574
|
+
0% {
|
|
575
|
+
box-shadow: 0 0 0 0px hsl(239, 83%, 68%);
|
|
576
|
+
}
|
|
577
|
+
100% {
|
|
578
|
+
box-shadow: 0 0 0 10px hsl(239, 83%, 68%, 0);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
@theme inline {
|
|
584
|
+
--color-background: var(--background);
|
|
585
|
+
--color-background-light: var(--background-light);
|
|
586
|
+
--color-foreground: var(--foreground);
|
|
587
|
+
|
|
588
|
+
--color-primary: var(--primary);
|
|
589
|
+
--color-primary-dark: var(--primary-dark);
|
|
590
|
+
--color-primary-light: var(--primary-light);
|
|
591
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
592
|
+
|
|
593
|
+
--color-secondary: var(--secondary);
|
|
594
|
+
--color-secondary-dark: var(--secondary-dark);
|
|
595
|
+
--color-secondary-light: var(--secondary-light);
|
|
596
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
597
|
+
|
|
598
|
+
--color-success: var(--success);
|
|
599
|
+
--color-success-dark: var(--success-dark);
|
|
600
|
+
--color-success-light: var(--success-light);
|
|
601
|
+
--color-success-foreground: var(--success-foreground);
|
|
602
|
+
|
|
603
|
+
--color-warn: var(--warn);
|
|
604
|
+
--color-warn-dark: var(--warn-dark);
|
|
605
|
+
--color-warn-light: var(--warn-light);
|
|
606
|
+
--color-warn-foreground: var(--warn-foreground);
|
|
607
|
+
|
|
608
|
+
--color-danger: var(--danger);
|
|
609
|
+
--color-danger-dark: var(--danger-dark);
|
|
610
|
+
--color-danger-light: var(--danger-light);
|
|
611
|
+
--color-danger-foreground: var(--danger-foreground);
|
|
612
|
+
|
|
613
|
+
--color-muted: var(--muted);
|
|
614
|
+
--color-muted-dark: var(--muted-dark);
|
|
615
|
+
--color-muted-light: var(--muted-light);
|
|
616
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
617
|
+
|
|
618
|
+
--color-card: var(--card);
|
|
619
|
+
|
|
620
|
+
--color-light: var(--light);
|
|
621
|
+
--color-dark: var(--dark);
|
|
622
|
+
--color-border: var(--border);
|
|
623
|
+
--color-input-placeholder: var(--input-placeholder);
|
|
624
|
+
|
|
625
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
626
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
627
|
+
--radius-lg: var(--radius);
|
|
628
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
@layer base {
|
|
632
|
+
* {
|
|
633
|
+
@apply scroll-m-24 border-border;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
body {
|
|
637
|
+
@apply bg-background text-foreground;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
::-webkit-scrollbar {
|
|
641
|
+
@apply size-1;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
::-webkit-scrollbar-track {
|
|
645
|
+
@apply bg-muted-light;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
::-webkit-scrollbar-thumb {
|
|
649
|
+
@apply bg-muted-dark;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
::-webkit-scrollbar-thumb:hover {
|
|
653
|
+
@apply bg-muted-foreground/75;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/* Selection */
|
|
657
|
+
::selection {
|
|
658
|
+
-webkit-text-fill-color: var(--background);
|
|
659
|
+
@apply bg-primary text-primary-foreground;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
@layer utilities {
|
|
664
|
+
/* Animate wave background */
|
|
665
|
+
.animate-wave-bg {
|
|
666
|
+
background-image: linear-gradient(
|
|
667
|
+
90deg,
|
|
668
|
+
rgb(238, 238, 238) 35%,
|
|
669
|
+
rgb(245, 245, 245) 50%,
|
|
670
|
+
rgb(238, 238, 238) 65%
|
|
671
|
+
);
|
|
672
|
+
background-size: 300%;
|
|
673
|
+
animation: animate-gradient 2.5s ease infinite;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/* Elevated card */
|
|
677
|
+
.elevated-card {
|
|
678
|
+
box-shadow: 0 0 20px var(--muted-light);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/* Glass card */
|
|
682
|
+
.glass-card {
|
|
683
|
+
background: hsla(0, 0%, 100%, 0.2) !important;
|
|
684
|
+
border: 1px solid hsla(0, 0%, 100%, 0.3) !important;
|
|
685
|
+
box-shadow: 0 4px 30px hsla(0, 0%, 0%, 0.1) !important;
|
|
686
|
+
backdrop-filter: blur(5px);
|
|
687
|
+
-webkit-backdrop-filter: blur(5px);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/* Hide scrollbar */
|
|
691
|
+
.hide-scrollbar {
|
|
692
|
+
scrollbar-width: none;
|
|
693
|
+
-ms-overflow-style: none;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.animate-changelog-timeline {
|
|
697
|
+
animation: animate-heart-beat 1.5s ease infinite;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
`;
|
|
701
|
+
|
|
702
|
+
// src/commands/utils/css.util.ts
|
|
703
|
+
async function createThemeFile({
|
|
704
|
+
cwd,
|
|
705
|
+
version
|
|
706
|
+
}) {
|
|
707
|
+
if (version === "none") return null;
|
|
708
|
+
const existingGlobalCssPath = await locateGlobalsCSS(cwd);
|
|
709
|
+
if (existingGlobalCssPath) {
|
|
710
|
+
const updated = await updateGlobalsCSS({
|
|
711
|
+
filePath: existingGlobalCssPath,
|
|
712
|
+
content: themeVariablesV4
|
|
713
|
+
});
|
|
714
|
+
if (!updated) return null;
|
|
715
|
+
return existingGlobalCssPath;
|
|
716
|
+
}
|
|
717
|
+
const srcAppDir = path5.join(cwd, "src", "app");
|
|
718
|
+
const appDir = path5.join(cwd, "app");
|
|
719
|
+
let newGlobalCssPath;
|
|
720
|
+
if (await fs5.pathExists(srcAppDir)) {
|
|
721
|
+
newGlobalCssPath = path5.join(srcAppDir, "globals.css");
|
|
722
|
+
} else if (await fs5.pathExists(appDir)) {
|
|
723
|
+
newGlobalCssPath = path5.join(appDir, "globals.css");
|
|
724
|
+
} else {
|
|
725
|
+
newGlobalCssPath = path5.join(cwd, "src", "app", "globals.css");
|
|
726
|
+
}
|
|
727
|
+
await fs5.ensureDir(path5.dirname(newGlobalCssPath));
|
|
728
|
+
const fileUpdated = await writeCSSFile({
|
|
729
|
+
filePath: newGlobalCssPath,
|
|
730
|
+
content: themeVariablesV4
|
|
731
|
+
});
|
|
732
|
+
if (!fileUpdated) return null;
|
|
733
|
+
return newGlobalCssPath;
|
|
734
|
+
}
|
|
735
|
+
async function locateGlobalsCSS(cwd) {
|
|
736
|
+
const commonPaths = [path5.join(cwd, "src", "app", "globals.css"), path5.join(cwd, "app", "globals.css")];
|
|
737
|
+
for (const cssPath of commonPaths) {
|
|
738
|
+
if (await fs5.pathExists(cssPath)) return cssPath;
|
|
739
|
+
}
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
async function writeCSSFile({ filePath, content }) {
|
|
743
|
+
try {
|
|
744
|
+
await fs5.writeFile(filePath, content, "utf8");
|
|
745
|
+
return true;
|
|
746
|
+
} catch {
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
async function updateGlobalsCSS({ filePath, content }) {
|
|
751
|
+
try {
|
|
752
|
+
await fs5.writeFile(filePath, content, "utf8");
|
|
753
|
+
return true;
|
|
754
|
+
} catch {
|
|
755
|
+
return false;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// src/commands/init.ts
|
|
760
|
+
async function initConfig() {
|
|
761
|
+
try {
|
|
762
|
+
console.log("\u2699\uFE0F Initializing configuration...");
|
|
763
|
+
const cwd = process.cwd();
|
|
764
|
+
const existingConfig = await getConfig(cwd);
|
|
765
|
+
if (existingConfig) {
|
|
766
|
+
console.log("\u2714 ui.config.json already exists in this project.");
|
|
767
|
+
const { overwrite } = await inquirer3.prompt([
|
|
768
|
+
{
|
|
769
|
+
type: "confirm",
|
|
770
|
+
name: "overwrite",
|
|
771
|
+
message: "Do you want to overwrite the existing configuration?",
|
|
772
|
+
default: false
|
|
773
|
+
}
|
|
774
|
+
]);
|
|
775
|
+
if (!overwrite) {
|
|
776
|
+
console.log("\u274C Configuration initialization cancelled!");
|
|
777
|
+
process.exit(1);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
const projectInfo = await getProjectInfo(cwd);
|
|
781
|
+
if (projectInfo.project === "none") {
|
|
782
|
+
console.log("\u274C No supported project detected!");
|
|
783
|
+
process.exit(1);
|
|
784
|
+
}
|
|
785
|
+
if (projectInfo.tailwindVersion === "none") {
|
|
786
|
+
console.log("\u{1F4E6} No supported Tailwind version detected!");
|
|
787
|
+
const { installTailwind } = await inquirer3.prompt([
|
|
788
|
+
{
|
|
789
|
+
type: "confirm",
|
|
790
|
+
name: "installTailwind",
|
|
791
|
+
message: "Would you like to install Tailwind CSS?",
|
|
792
|
+
default: true
|
|
793
|
+
}
|
|
794
|
+
]);
|
|
795
|
+
if (!installTailwind) {
|
|
796
|
+
console.log("\u274C Tailwind CSS is required for the UI components to work properly!");
|
|
797
|
+
process.exit(1);
|
|
798
|
+
}
|
|
799
|
+
const installTailwindSpinner = ora2(" Installing Tailwind CSS...").start();
|
|
800
|
+
const tailwindInstalled = await installDependencies({
|
|
801
|
+
cwd,
|
|
802
|
+
packageManager: projectInfo.packageManager,
|
|
803
|
+
dependencies: ["tailwindcss"]
|
|
804
|
+
});
|
|
805
|
+
if (tailwindInstalled) installTailwindSpinner.succeed();
|
|
806
|
+
else {
|
|
807
|
+
installTailwindSpinner.fail();
|
|
808
|
+
console.log("\u274C Failed to install Tailwind CSS. Please install it manually!");
|
|
809
|
+
process.exit(1);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
const config = await createConfig({ cwd, projectInfo });
|
|
813
|
+
if (!config) {
|
|
814
|
+
console.log("\u274C Failed to create configuration file!");
|
|
815
|
+
process.exit(1);
|
|
816
|
+
} else console.log("\u2714 Configuration file created successfully!");
|
|
817
|
+
const isCorrectLucideVersion = projectInfo.lucideVersion && projectInfo.lucideVersion >= 0.563 ? true : false;
|
|
818
|
+
if (!isCorrectLucideVersion) {
|
|
819
|
+
const lucideInstalled = await installDependencies({
|
|
820
|
+
cwd,
|
|
821
|
+
packageManager: projectInfo.packageManager,
|
|
822
|
+
dependencies: ["clsx", "lucide-react", "tailwind-merge"]
|
|
823
|
+
});
|
|
824
|
+
if (!lucideInstalled) {
|
|
825
|
+
console.log("\u274C Failed to install Lucide Icons. Please install it manually!");
|
|
826
|
+
process.exit(1);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
const themeSpinner = ora2(" Setting up theme variables...").start();
|
|
830
|
+
const createdThemeFile = await createThemeFile({ cwd, version: projectInfo.tailwindVersion });
|
|
831
|
+
if (!createdThemeFile) {
|
|
832
|
+
themeSpinner.fail();
|
|
833
|
+
console.log("\u274C Failed to setup theme variables!");
|
|
834
|
+
process.exit(1);
|
|
835
|
+
}
|
|
836
|
+
themeSpinner.succeed();
|
|
837
|
+
console.log("\u{1F389} Project initialization completed successfully!");
|
|
838
|
+
console.log("\u{1F4A1} Feel free to update the values in the configuration file to your needs!");
|
|
839
|
+
process.exit(1);
|
|
840
|
+
} catch (error) {
|
|
841
|
+
console.error(`\u274C Error: ${error}`);
|
|
842
|
+
process.exit(1);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
// src/commands/list.ts
|
|
847
|
+
import ora3 from "ora";
|
|
848
|
+
async function listComponents() {
|
|
849
|
+
const configSpinner = ora3(" Checking...").start();
|
|
850
|
+
try {
|
|
851
|
+
const cwd = process.cwd();
|
|
852
|
+
const config = await getConfig(cwd);
|
|
853
|
+
if (!config) {
|
|
854
|
+
configSpinner.fail();
|
|
855
|
+
console.log('\u274C No configuration found! Please run "sgx4u-ui init" first.');
|
|
856
|
+
process.exit(1);
|
|
857
|
+
}
|
|
858
|
+
configSpinner.succeed();
|
|
859
|
+
const fetchSpinner = ora3(" Fetching available components...").start();
|
|
860
|
+
const registry = await fetchRegistry(config.environment);
|
|
861
|
+
if (!registry) {
|
|
862
|
+
fetchSpinner.fail();
|
|
863
|
+
console.log("\u26A0\uFE0F Failed to fetch registry from GitHub!");
|
|
864
|
+
process.exit(1);
|
|
865
|
+
}
|
|
866
|
+
fetchSpinner.succeed();
|
|
867
|
+
console.log("\u{1F4CB} Available Components:");
|
|
868
|
+
Object.entries(registry.components).forEach(([registryKey, component]) => {
|
|
869
|
+
const componentName = component.name ?? registryKey;
|
|
870
|
+
console.log(`${componentName}: ${component.description}`);
|
|
871
|
+
console.log(` Install: sgx4u-ui add ${componentName}`);
|
|
872
|
+
console.log();
|
|
873
|
+
});
|
|
874
|
+
process.exit(1);
|
|
875
|
+
} catch (error) {
|
|
876
|
+
configSpinner.fail();
|
|
877
|
+
console.error(`\u274C Error: ${error}`);
|
|
878
|
+
process.exit(1);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
export {
|
|
883
|
+
getConfig,
|
|
884
|
+
createConfig,
|
|
885
|
+
getProjectInfo,
|
|
886
|
+
fetchComponent,
|
|
887
|
+
addComponent,
|
|
888
|
+
initConfig,
|
|
889
|
+
listComponents
|
|
890
|
+
};
|