@hemia/lume 0.0.1 → 0.0.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.
- package/dist/index.js +309 -68
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,8 +32,8 @@ function getInstallCommand(packageManager) {
|
|
|
32
32
|
}
|
|
33
33
|
function installDependencies(dependencies, options = {}) {
|
|
34
34
|
if (dependencies.length === 0) return;
|
|
35
|
-
const { dev = false, cwd = process.cwd() } = options;
|
|
36
|
-
const packageManager = detectPackageManager(cwd);
|
|
35
|
+
const { dev = false, cwd = process.cwd(), packageManager: customPm } = options;
|
|
36
|
+
const packageManager = customPm ?? detectPackageManager(cwd);
|
|
37
37
|
const installCmd = getInstallCommand(packageManager);
|
|
38
38
|
const devFlag = dev ? packageManager === "npm" ? "--save-dev" : "-D" : "";
|
|
39
39
|
const command = `${installCmd} ${dependencies.join(" ")} ${devFlag}`.trim();
|
|
@@ -106,6 +106,14 @@ function getFrameworkFromConfig(cwd) {
|
|
|
106
106
|
return "vue";
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
function getPackageManagerFromConfig(cwd) {
|
|
110
|
+
try {
|
|
111
|
+
const config = fs3.readJsonSync(path3.resolve(cwd, "lume.config.json"));
|
|
112
|
+
return config.packageManager ?? "npm";
|
|
113
|
+
} catch {
|
|
114
|
+
return "npm";
|
|
115
|
+
}
|
|
116
|
+
}
|
|
109
117
|
function log(message, options) {
|
|
110
118
|
if (!options.silent) {
|
|
111
119
|
console.log(message);
|
|
@@ -134,6 +142,7 @@ async function add(components = [], options = {}) {
|
|
|
134
142
|
process.exit(1);
|
|
135
143
|
}
|
|
136
144
|
const framework = options.framework ?? getFrameworkFromConfig(cwd);
|
|
145
|
+
const packageManager = getPackageManagerFromConfig(cwd);
|
|
137
146
|
const frameworkRegistry = resolveRegistryPath(framework);
|
|
138
147
|
if (!options.silent) {
|
|
139
148
|
log(pc2.cyan(`
|
|
@@ -161,8 +170,13 @@ async function add(components = [], options = {}) {
|
|
|
161
170
|
await fs3.ensureDir(targetBase);
|
|
162
171
|
let copiedCount = 0;
|
|
163
172
|
for (const componentName of componentsArray) {
|
|
164
|
-
const
|
|
173
|
+
const sourceDir = path3.join(frameworkRegistry, componentName);
|
|
174
|
+
const sourceFile = path3.join(sourceDir, `${componentName}.vue`);
|
|
165
175
|
const target = path3.join(targetBase, `${componentName}.vue`);
|
|
176
|
+
if (!await fs3.pathExists(sourceFile)) {
|
|
177
|
+
log(pc2.red(`\u274C Source file not found: ${sourceFile}`), options);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
166
180
|
const targetExists = await fs3.pathExists(target);
|
|
167
181
|
if (targetExists && !options.overwrite && !options.yes) {
|
|
168
182
|
const { overwrite } = await prompts({
|
|
@@ -177,7 +191,7 @@ async function add(components = [], options = {}) {
|
|
|
177
191
|
}
|
|
178
192
|
}
|
|
179
193
|
if (options.overwrite || options.yes || !targetExists) {
|
|
180
|
-
await fs3.copy(
|
|
194
|
+
await fs3.copy(sourceFile, target, { overwrite: true });
|
|
181
195
|
copiedCount++;
|
|
182
196
|
log(pc2.green(` \u2713 ${componentName}`), options);
|
|
183
197
|
}
|
|
@@ -186,17 +200,17 @@ async function add(components = [], options = {}) {
|
|
|
186
200
|
const devDeps = Array.from(allDevDependencies);
|
|
187
201
|
if (deps.length > 0) {
|
|
188
202
|
log("", options);
|
|
189
|
-
installDependencies(deps);
|
|
203
|
+
installDependencies(deps, { packageManager });
|
|
190
204
|
}
|
|
191
205
|
if (devDeps.length > 0) {
|
|
192
206
|
log("", options);
|
|
193
|
-
installDependencies(devDeps, { dev: true });
|
|
207
|
+
installDependencies(devDeps, { dev: true, packageManager });
|
|
194
208
|
}
|
|
195
209
|
log(pc2.green(`
|
|
196
210
|
\u2705 Added ${copiedCount} component(s) to ${targetBase}/`), options);
|
|
197
211
|
}
|
|
198
212
|
|
|
199
|
-
// src/commands/
|
|
213
|
+
// src/commands/add-styles.ts
|
|
200
214
|
import fs4 from "fs-extra";
|
|
201
215
|
import path4 from "path";
|
|
202
216
|
import pc3 from "picocolors";
|
|
@@ -355,11 +369,215 @@ function getTemplateConfig(framework, template) {
|
|
|
355
369
|
};
|
|
356
370
|
}
|
|
357
371
|
|
|
372
|
+
// src/commands/add-styles.ts
|
|
373
|
+
function log2(message, options) {
|
|
374
|
+
if (!options.silent) {
|
|
375
|
+
console.log(message);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
function info(message, options) {
|
|
379
|
+
if (!options.silent) {
|
|
380
|
+
console.log(pc3.cyan(message));
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function extractCssVariables(cssContent) {
|
|
384
|
+
const vars = /* @__PURE__ */ new Map();
|
|
385
|
+
const varRegex = /--([a-zA-Z0-9-]+):\s*([^;]+);/g;
|
|
386
|
+
let match;
|
|
387
|
+
while ((match = varRegex.exec(cssContent)) !== null) {
|
|
388
|
+
vars.set(match[1], match[2]);
|
|
389
|
+
}
|
|
390
|
+
return vars;
|
|
391
|
+
}
|
|
392
|
+
function mergeCssVariables(existingCss, templateCss) {
|
|
393
|
+
const existingVars = extractCssVariables(existingCss);
|
|
394
|
+
const templateVars = extractCssVariables(templateCss);
|
|
395
|
+
for (const [key, value] of templateVars) {
|
|
396
|
+
existingVars.set(key, value);
|
|
397
|
+
}
|
|
398
|
+
let result = existingCss;
|
|
399
|
+
const rootMatch = result.match(/@layer base\s*\{[\s\S]*?:root\s*\{([\s\S]*?)\}/);
|
|
400
|
+
if (rootMatch) {
|
|
401
|
+
const newRootVars = Array.from(existingVars.entries()).map(([key, value]) => ` --${key}: ${value};`).join("\n");
|
|
402
|
+
result = result.replace(
|
|
403
|
+
/@layer base\s*\{[\s\S]*?:root\s*\{[\s\S]*?\}/,
|
|
404
|
+
`@layer base {
|
|
405
|
+
:root {
|
|
406
|
+
${newRootVars}
|
|
407
|
+
}`
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
return result;
|
|
411
|
+
}
|
|
412
|
+
function mergeTailwindConfig(existingConfig, templateConfig) {
|
|
413
|
+
const colorMatches = templateConfig.match(/colors:\s*\{([\s\S]*?)\}/);
|
|
414
|
+
const radiusMatches = templateConfig.match(/borderRadius:\s*\{([\s\S]*?)\}/);
|
|
415
|
+
let result = existingConfig;
|
|
416
|
+
if (!result.includes("theme:")) {
|
|
417
|
+
return templateConfig;
|
|
418
|
+
}
|
|
419
|
+
if (colorMatches) {
|
|
420
|
+
const colorsBlock = colorMatches[0];
|
|
421
|
+
if (!result.includes("colors:")) {
|
|
422
|
+
result = result.replace(
|
|
423
|
+
/theme:\s*\{/,
|
|
424
|
+
`theme: {
|
|
425
|
+
extend: {
|
|
426
|
+
colors: {${colorsBlock.replace("colors:", "")}`
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (radiusMatches) {
|
|
431
|
+
const radiusBlock = radiusMatches[0];
|
|
432
|
+
if (!result.includes("borderRadius:")) {
|
|
433
|
+
result = result.replace(
|
|
434
|
+
/theme:\s*\{/,
|
|
435
|
+
`theme: {
|
|
436
|
+
extend: {
|
|
437
|
+
borderRadius: {${radiusBlock.replace("borderRadius:", "")}`
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (!result.includes("colors:") && colorMatches) {
|
|
442
|
+
return templateConfig;
|
|
443
|
+
}
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
function getConfigPaths(cwd) {
|
|
447
|
+
try {
|
|
448
|
+
const config = fs4.readJsonSync(path4.resolve(cwd, "lume.config.json"));
|
|
449
|
+
return {
|
|
450
|
+
tailwindConfigPath: config.tailwind?.config ?? "tailwind.config.ts",
|
|
451
|
+
globalsCssPath: config.tailwind?.css ?? "src/assets/globals.css"
|
|
452
|
+
};
|
|
453
|
+
} catch {
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function detectFramework(cwd) {
|
|
458
|
+
try {
|
|
459
|
+
const config = fs4.readJsonSync(path4.resolve(cwd, "lume.config.json"));
|
|
460
|
+
return config.framework ?? "vue";
|
|
461
|
+
} catch {
|
|
462
|
+
return "vue";
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
async function addStyles(_args = [], options = {}) {
|
|
466
|
+
if (options.silent === void 0 && process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
467
|
+
console.log(`
|
|
468
|
+
lume add-styles
|
|
469
|
+
|
|
470
|
+
Add globals.css and tailwind.config.ts with merge support
|
|
471
|
+
|
|
472
|
+
Options:
|
|
473
|
+
-y, --yes Skip confirmation prompt
|
|
474
|
+
-o, --overwrite Overwrite existing files (don't merge)
|
|
475
|
+
-f, --force Force overwrite without asking
|
|
476
|
+
-c, --cwd Working directory
|
|
477
|
+
-s, --silent Mute output
|
|
478
|
+
-h, --help Show this help
|
|
479
|
+
`);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
const cwd = options.cwd ? path4.resolve(options.cwd) : process.cwd();
|
|
483
|
+
const configPath = path4.resolve(cwd, "lume.config.json");
|
|
484
|
+
if (!await fs4.pathExists(configPath)) {
|
|
485
|
+
const cssPath2 = path4.resolve(cwd, "src/assets/globals.css");
|
|
486
|
+
const tailwindPath2 = path4.resolve(cwd, "tailwind.config.ts");
|
|
487
|
+
log2(pc3.cyan("\n\u{1F4E6} Adding styles to your project\n"), options);
|
|
488
|
+
info("No lume.config.json found. Using default paths...", options);
|
|
489
|
+
await fs4.ensureDir(path4.dirname(cssPath2));
|
|
490
|
+
await fs4.writeFile(cssPath2, GLOBALS_CSS_TEMPLATE);
|
|
491
|
+
log2(pc3.green(`\u2705 Created src/assets/globals.css`), options);
|
|
492
|
+
await fs4.writeFile(tailwindPath2, TAILWIND_CONFIG_TEMPLATE);
|
|
493
|
+
log2(pc3.green(`\u2705 Created tailwind.config.ts`), options);
|
|
494
|
+
log2(pc3.green("\n\u2705 Styles added successfully!"), options);
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
const configPaths = getConfigPaths(cwd);
|
|
498
|
+
if (!configPaths) {
|
|
499
|
+
log2(pc3.red("\u274C Could not read lume.config.json"), options);
|
|
500
|
+
process.exit(1);
|
|
501
|
+
}
|
|
502
|
+
const framework = detectFramework(cwd);
|
|
503
|
+
const templateConfig = getTemplateConfig(framework);
|
|
504
|
+
const cssPath = path4.resolve(cwd, configPaths.globalsCssPath);
|
|
505
|
+
const tailwindPath = path4.resolve(cwd, configPaths.tailwindConfigPath);
|
|
506
|
+
const cssExists = await fs4.pathExists(cssPath);
|
|
507
|
+
const tailwindExists = await fs4.pathExists(tailwindPath);
|
|
508
|
+
log2(pc3.cyan("\n\u{1F4E6} Adding styles to your project\n"), options);
|
|
509
|
+
if (!cssExists && !tailwindExists) {
|
|
510
|
+
info("No existing CSS or config found. Writing new files...", options);
|
|
511
|
+
await fs4.ensureDir(path4.dirname(cssPath));
|
|
512
|
+
await fs4.writeFile(cssPath, GLOBALS_CSS_TEMPLATE);
|
|
513
|
+
log2(pc3.green(`\u2705 Created ${configPaths.globalsCssPath}`), options);
|
|
514
|
+
await fs4.writeFile(tailwindPath, TAILWIND_CONFIG_TEMPLATE);
|
|
515
|
+
log2(pc3.green(`\u2705 Created ${configPaths.tailwindConfigPath}`), options);
|
|
516
|
+
log2(pc3.green("\n\u2705 Styles added successfully!"), options);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
let shouldMerge = options.yes;
|
|
520
|
+
let shouldOverwrite = options.overwrite || options.force;
|
|
521
|
+
if ((cssExists || tailwindExists) && !options.yes) {
|
|
522
|
+
const { action } = await prompts2({
|
|
523
|
+
type: "select",
|
|
524
|
+
name: "action",
|
|
525
|
+
message: "Styles already exist. What would you like to do?",
|
|
526
|
+
choices: [
|
|
527
|
+
{ title: "Merge (recommended)", description: "Keep your variables, add missing ones from template", value: "merge" },
|
|
528
|
+
{ title: "Overwrite", description: "Replace with template (your custom styles will be lost)", value: "overwrite" },
|
|
529
|
+
{ title: "Skip", description: "Don't add styles", value: "skip" }
|
|
530
|
+
]
|
|
531
|
+
});
|
|
532
|
+
if (action === "skip") {
|
|
533
|
+
log2(pc3.dim("Cancelled."), options);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
shouldMerge = action === "merge";
|
|
537
|
+
shouldOverwrite = action === "overwrite";
|
|
538
|
+
}
|
|
539
|
+
if (cssExists) {
|
|
540
|
+
if (shouldOverwrite && !shouldMerge) {
|
|
541
|
+
await fs4.writeFile(cssPath, GLOBALS_CSS_TEMPLATE);
|
|
542
|
+
log2(pc3.green(`\u2705 Overwrote ${configPaths.globalsCssPath}`), options);
|
|
543
|
+
} else if (shouldMerge) {
|
|
544
|
+
const existingCss = await fs4.readFile(cssPath, "utf-8");
|
|
545
|
+
const mergedCss = mergeCssVariables(existingCss, GLOBALS_CSS_TEMPLATE);
|
|
546
|
+
await fs4.writeFile(cssPath, mergedCss);
|
|
547
|
+
log2(pc3.green(`\u2705 Merged CSS variables in ${configPaths.globalsCssPath}`), options);
|
|
548
|
+
}
|
|
549
|
+
} else {
|
|
550
|
+
await fs4.ensureDir(path4.dirname(cssPath));
|
|
551
|
+
await fs4.writeFile(cssPath, GLOBALS_CSS_TEMPLATE);
|
|
552
|
+
log2(pc3.green(`\u2705 Created ${configPaths.globalsCssPath}`), options);
|
|
553
|
+
}
|
|
554
|
+
if (tailwindExists) {
|
|
555
|
+
if (shouldOverwrite && !shouldMerge) {
|
|
556
|
+
await fs4.writeFile(tailwindPath, TAILWIND_CONFIG_TEMPLATE);
|
|
557
|
+
log2(pc3.green(`\u2705 Overwrote ${configPaths.tailwindConfigPath}`), options);
|
|
558
|
+
} else if (shouldMerge) {
|
|
559
|
+
const existingConfig = await fs4.readFile(tailwindPath, "utf-8");
|
|
560
|
+
const mergedConfig = mergeTailwindConfig(existingConfig, TAILWIND_CONFIG_TEMPLATE);
|
|
561
|
+
await fs4.writeFile(tailwindPath, mergedConfig);
|
|
562
|
+
log2(pc3.green(`\u2705 Merged Tailwind config in ${configPaths.tailwindConfigPath}`), options);
|
|
563
|
+
}
|
|
564
|
+
} else {
|
|
565
|
+
await fs4.writeFile(tailwindPath, TAILWIND_CONFIG_TEMPLATE);
|
|
566
|
+
log2(pc3.green(`\u2705 Created ${configPaths.tailwindConfigPath}`), options);
|
|
567
|
+
}
|
|
568
|
+
log2(pc3.green("\n\u2705 Styles added successfully!"), options);
|
|
569
|
+
}
|
|
570
|
+
|
|
358
571
|
// src/commands/init.ts
|
|
572
|
+
import fs5 from "fs-extra";
|
|
573
|
+
import path5 from "path";
|
|
574
|
+
import pc4 from "picocolors";
|
|
575
|
+
import prompts3 from "prompts";
|
|
359
576
|
var SUPPORTED_FRAMEWORKS = ["vue", "react", "svelte", "astro"];
|
|
360
|
-
|
|
577
|
+
var SUPPORTED_PACKAGE_MANAGERS = ["npm", "bun", "pnpm", "yarn"];
|
|
578
|
+
function detectFramework2() {
|
|
361
579
|
try {
|
|
362
|
-
const pkg =
|
|
580
|
+
const pkg = fs5.readJsonSync(path5.resolve(process.cwd(), "package.json"));
|
|
363
581
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
364
582
|
if (deps["vue"]) return "vue";
|
|
365
583
|
if (deps["react"]) return "react";
|
|
@@ -370,19 +588,19 @@ function detectFramework() {
|
|
|
370
588
|
return null;
|
|
371
589
|
}
|
|
372
590
|
}
|
|
373
|
-
function
|
|
591
|
+
function log3(message, options) {
|
|
374
592
|
if (!options.silent) {
|
|
375
593
|
console.log(message);
|
|
376
594
|
}
|
|
377
595
|
}
|
|
378
596
|
function warn2(message, options) {
|
|
379
597
|
if (!options.silent) {
|
|
380
|
-
console.log(
|
|
598
|
+
console.log(pc4.yellow(`\u26A0\uFE0F ${message}`));
|
|
381
599
|
}
|
|
382
600
|
}
|
|
383
|
-
function
|
|
601
|
+
function info2(message, options) {
|
|
384
602
|
if (!options.silent) {
|
|
385
|
-
console.log(
|
|
603
|
+
console.log(pc4.cyan(message));
|
|
386
604
|
}
|
|
387
605
|
}
|
|
388
606
|
async function init(options = {}) {
|
|
@@ -402,36 +620,36 @@ async function init(options = {}) {
|
|
|
402
620
|
}
|
|
403
621
|
if (options.reinstall === false) {
|
|
404
622
|
}
|
|
405
|
-
const cwd = options.cwd ?
|
|
623
|
+
const cwd = options.cwd ? path5.resolve(options.cwd) : process.cwd();
|
|
406
624
|
const validTemplates = ["next", "vite", "start", "react-router", "laravel", "astro"];
|
|
407
625
|
let template = options.template?.toLowerCase();
|
|
408
626
|
if (template && !validTemplates.includes(template)) {
|
|
409
627
|
warn2(`Invalid template "${template}". Using default.`, options);
|
|
410
628
|
template = void 0;
|
|
411
629
|
}
|
|
412
|
-
const configPath =
|
|
413
|
-
const configExists = await
|
|
630
|
+
const configPath = path5.resolve(cwd, "lume.config.json");
|
|
631
|
+
const configExists = await fs5.pathExists(configPath);
|
|
414
632
|
if (configExists && !options.force) {
|
|
415
633
|
if (!options.yes) {
|
|
416
|
-
const { overwrite } = await
|
|
634
|
+
const { overwrite } = await prompts3({
|
|
417
635
|
type: "confirm",
|
|
418
636
|
name: "overwrite",
|
|
419
637
|
message: "lume.config.json already exists. Overwrite?",
|
|
420
638
|
initial: false
|
|
421
639
|
});
|
|
422
640
|
if (!overwrite) {
|
|
423
|
-
|
|
641
|
+
log3("Cancelled.", options);
|
|
424
642
|
return;
|
|
425
643
|
}
|
|
426
644
|
}
|
|
427
645
|
}
|
|
428
|
-
const detected =
|
|
646
|
+
const detected = detectFramework2();
|
|
429
647
|
let framework;
|
|
430
648
|
if (detected) {
|
|
431
649
|
framework = detected;
|
|
432
|
-
|
|
650
|
+
info2(`Detected framework: ${detected}`, options);
|
|
433
651
|
} else if (!options.yes) {
|
|
434
|
-
const { framework: selectedFramework } = await
|
|
652
|
+
const { framework: selectedFramework } = await prompts3({
|
|
435
653
|
type: "select",
|
|
436
654
|
name: "framework",
|
|
437
655
|
message: "Which framework are you using?",
|
|
@@ -442,13 +660,35 @@ async function init(options = {}) {
|
|
|
442
660
|
framework = "vue";
|
|
443
661
|
}
|
|
444
662
|
if (!framework) {
|
|
445
|
-
|
|
663
|
+
log3(pc4.red("\u274C Framework selection required"), options);
|
|
664
|
+
process.exit(1);
|
|
665
|
+
}
|
|
666
|
+
const detectedPm = detectPackageManager(cwd);
|
|
667
|
+
let packageManager;
|
|
668
|
+
if (detectedPm) {
|
|
669
|
+
packageManager = detectedPm;
|
|
670
|
+
info2(`Detected package manager: ${detectedPm}`, options);
|
|
671
|
+
} else if (!options.yes) {
|
|
672
|
+
const { pm } = await prompts3({
|
|
673
|
+
type: "select",
|
|
674
|
+
name: "pm",
|
|
675
|
+
message: "Which package manager are you using?",
|
|
676
|
+
choices: SUPPORTED_PACKAGE_MANAGERS.map((pm2) => ({ title: pm2, value: pm2 }))
|
|
677
|
+
});
|
|
678
|
+
packageManager = pm;
|
|
679
|
+
} else {
|
|
680
|
+
packageManager = "npm";
|
|
681
|
+
}
|
|
682
|
+
if (!packageManager) {
|
|
683
|
+
log3(pc4.red("\u274C Package manager selection required"), options);
|
|
446
684
|
process.exit(1);
|
|
447
685
|
}
|
|
686
|
+
const installCmd = getInstallCommand(packageManager);
|
|
448
687
|
const templateConfig = getTemplateConfig(framework, template);
|
|
449
688
|
const useCssVariables = options.cssVariables !== false;
|
|
450
689
|
const config = {
|
|
451
690
|
framework,
|
|
691
|
+
packageManager,
|
|
452
692
|
style: useCssVariables ? "css-variables" : "default",
|
|
453
693
|
template: templateConfig.template,
|
|
454
694
|
tailwind: {
|
|
@@ -461,11 +701,11 @@ async function init(options = {}) {
|
|
|
461
701
|
utils: `@/${templateConfig.utilsPath}`
|
|
462
702
|
}
|
|
463
703
|
};
|
|
464
|
-
await
|
|
465
|
-
|
|
704
|
+
await fs5.writeJson(configPath, config, { spaces: 2 });
|
|
705
|
+
log3(pc4.green(`\u2705 Created lume.config.json`), options);
|
|
466
706
|
let writeFiles = options.yes;
|
|
467
707
|
if (!options.yes) {
|
|
468
|
-
const { confirm } = await
|
|
708
|
+
const { confirm } = await prompts3({
|
|
469
709
|
type: "confirm",
|
|
470
710
|
name: "confirm",
|
|
471
711
|
message: "Write globals.css and tailwind.config.ts?",
|
|
@@ -474,47 +714,47 @@ async function init(options = {}) {
|
|
|
474
714
|
writeFiles = confirm;
|
|
475
715
|
}
|
|
476
716
|
if (writeFiles) {
|
|
477
|
-
const cssPath =
|
|
478
|
-
await
|
|
479
|
-
if (await
|
|
717
|
+
const cssPath = path5.resolve(cwd, templateConfig.globalsCssPath);
|
|
718
|
+
await fs5.ensureDir(path5.dirname(cssPath));
|
|
719
|
+
if (await fs5.pathExists(cssPath)) {
|
|
480
720
|
if (options.force || !options.yes) {
|
|
481
|
-
const { overwrite } = await
|
|
721
|
+
const { overwrite } = await prompts3({
|
|
482
722
|
type: "confirm",
|
|
483
723
|
name: "overwrite",
|
|
484
724
|
message: `${templateConfig.globalsCssPath} already exists. Overwrite?`,
|
|
485
725
|
initial: false
|
|
486
726
|
});
|
|
487
727
|
if (overwrite) {
|
|
488
|
-
await
|
|
489
|
-
|
|
728
|
+
await fs5.writeFile(cssPath, GLOBALS_CSS_TEMPLATE);
|
|
729
|
+
log3(pc4.green(`\u2705 Updated ${templateConfig.globalsCssPath}`), options);
|
|
490
730
|
}
|
|
491
731
|
}
|
|
492
732
|
} else {
|
|
493
|
-
await
|
|
494
|
-
|
|
733
|
+
await fs5.writeFile(cssPath, GLOBALS_CSS_TEMPLATE);
|
|
734
|
+
log3(pc4.green(`\u2705 Created ${templateConfig.globalsCssPath}`), options);
|
|
495
735
|
}
|
|
496
|
-
const tailwindPath =
|
|
497
|
-
if (await
|
|
736
|
+
const tailwindPath = path5.resolve(cwd, templateConfig.tailwindConfigPath);
|
|
737
|
+
if (await fs5.pathExists(tailwindPath)) {
|
|
498
738
|
if (options.force || !options.yes) {
|
|
499
|
-
const { overwrite } = await
|
|
739
|
+
const { overwrite } = await prompts3({
|
|
500
740
|
type: "confirm",
|
|
501
741
|
name: "overwrite",
|
|
502
742
|
message: `${templateConfig.tailwindConfigPath} already exists. Overwrite?`,
|
|
503
743
|
initial: false
|
|
504
744
|
});
|
|
505
745
|
if (overwrite) {
|
|
506
|
-
await
|
|
507
|
-
|
|
746
|
+
await fs5.writeFile(tailwindPath, TAILWIND_CONFIG_TEMPLATE);
|
|
747
|
+
log3(pc4.green(`\u2705 Updated ${templateConfig.tailwindConfigPath}`), options);
|
|
508
748
|
}
|
|
509
749
|
}
|
|
510
750
|
} else {
|
|
511
|
-
await
|
|
512
|
-
|
|
751
|
+
await fs5.writeFile(tailwindPath, TAILWIND_CONFIG_TEMPLATE);
|
|
752
|
+
log3(pc4.green(`\u2705 Created ${templateConfig.tailwindConfigPath}`), options);
|
|
513
753
|
}
|
|
514
754
|
}
|
|
515
755
|
let installDeps = options.yes;
|
|
516
756
|
if (!options.yes) {
|
|
517
|
-
const { confirm } = await
|
|
757
|
+
const { confirm } = await prompts3({
|
|
518
758
|
type: "confirm",
|
|
519
759
|
name: "confirm",
|
|
520
760
|
message: "Install base dependencies (tailwindcss, autoprefixer, postcss)?",
|
|
@@ -523,30 +763,30 @@ async function init(options = {}) {
|
|
|
523
763
|
installDeps = confirm;
|
|
524
764
|
}
|
|
525
765
|
if (installDeps) {
|
|
526
|
-
|
|
766
|
+
log3("", options);
|
|
527
767
|
const baseDeps = ["tailwindcss", "autoprefixer", "postcss"];
|
|
528
768
|
installDependencies(baseDeps, { dev: true });
|
|
529
|
-
|
|
769
|
+
log3("", options);
|
|
530
770
|
const frameworkPkg = framework === "vue" ? "@hemia/lume-vue" : `@hemia/lume-${framework}`;
|
|
531
|
-
|
|
532
|
-
|
|
771
|
+
info2(`\u{1F4E6} Installing ${frameworkPkg}...`, options);
|
|
772
|
+
log3(pc4.dim(` When published, run: ${installCmd} ${frameworkPkg}`), options);
|
|
533
773
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
774
|
+
log3("", options);
|
|
775
|
+
log3(pc4.green("\u{1F389} All done! Run the following to add components:"), options);
|
|
776
|
+
info2(` lume add button`, options);
|
|
777
|
+
log3("", options);
|
|
538
778
|
}
|
|
539
779
|
|
|
540
780
|
// src/commands/list.ts
|
|
541
|
-
import
|
|
542
|
-
import
|
|
543
|
-
import
|
|
781
|
+
import fs6 from "fs-extra";
|
|
782
|
+
import path6 from "path";
|
|
783
|
+
import pc5 from "picocolors";
|
|
544
784
|
import { createRequire as createRequire2 } from "module";
|
|
545
785
|
var require3 = createRequire2(import.meta.url);
|
|
546
786
|
function getFrameworkFromConfig2() {
|
|
547
787
|
try {
|
|
548
|
-
const config =
|
|
549
|
-
|
|
788
|
+
const config = fs6.readJsonSync(
|
|
789
|
+
path6.resolve(process.cwd(), "hemia.config.json")
|
|
550
790
|
);
|
|
551
791
|
return config.framework ?? "vue";
|
|
552
792
|
} catch {
|
|
@@ -554,43 +794,43 @@ function getFrameworkFromConfig2() {
|
|
|
554
794
|
}
|
|
555
795
|
}
|
|
556
796
|
function resolveRegistryPath2(framework) {
|
|
557
|
-
const registryRoot =
|
|
797
|
+
const registryRoot = path6.dirname(
|
|
558
798
|
require3.resolve("@hemia/lume-registry/package.json")
|
|
559
799
|
);
|
|
560
|
-
return
|
|
800
|
+
return path6.join(registryRoot, "registry", framework);
|
|
561
801
|
}
|
|
562
802
|
async function list(options = {}) {
|
|
563
803
|
const framework = options.framework ?? getFrameworkFromConfig2();
|
|
564
804
|
const frameworkRegistry = resolveRegistryPath2(framework);
|
|
565
|
-
if (!await
|
|
566
|
-
console.log(
|
|
805
|
+
if (!await fs6.pathExists(frameworkRegistry)) {
|
|
806
|
+
console.log(pc5.red(`\u274C No components found for framework "${framework}"`));
|
|
567
807
|
process.exit(1);
|
|
568
808
|
}
|
|
569
|
-
const entries = await
|
|
809
|
+
const entries = await fs6.readdir(frameworkRegistry, { withFileTypes: true });
|
|
570
810
|
const components = entries.filter((entry) => entry.isDirectory());
|
|
571
811
|
if (components.length === 0) {
|
|
572
|
-
console.log(
|
|
812
|
+
console.log(pc5.yellow(`\u26A0\uFE0F No components available for ${framework}`));
|
|
573
813
|
return;
|
|
574
814
|
}
|
|
575
|
-
console.log(
|
|
815
|
+
console.log(pc5.cyan(`
|
|
576
816
|
\u{1F4E6} Available components for ${framework}:
|
|
577
817
|
`));
|
|
578
818
|
for (const component of components) {
|
|
579
819
|
const meta = await readComponentMeta(
|
|
580
|
-
|
|
820
|
+
path6.join(frameworkRegistry, component.name)
|
|
581
821
|
);
|
|
582
822
|
if (meta) {
|
|
583
|
-
const deps = meta.registryDependencies?.length ?
|
|
584
|
-
console.log(` ${
|
|
823
|
+
const deps = meta.registryDependencies?.length ? pc5.dim(` (requires: ${meta.registryDependencies.join(", ")})`) : "";
|
|
824
|
+
console.log(` ${pc5.green("\u25CF")} ${component.name}${deps}`);
|
|
585
825
|
} else {
|
|
586
|
-
console.log(` ${
|
|
826
|
+
console.log(` ${pc5.green("\u25CF")} ${component.name}`);
|
|
587
827
|
}
|
|
588
828
|
}
|
|
589
829
|
console.log();
|
|
590
|
-
console.log(
|
|
830
|
+
console.log(pc5.dim(`Total: ${components.length} component(s)`));
|
|
591
831
|
console.log();
|
|
592
|
-
console.log(
|
|
593
|
-
console.log(
|
|
832
|
+
console.log(pc5.cyan("Usage:"));
|
|
833
|
+
console.log(pc5.dim(` hemia add <component-name>`));
|
|
594
834
|
console.log();
|
|
595
835
|
}
|
|
596
836
|
|
|
@@ -599,5 +839,6 @@ var program = new Command();
|
|
|
599
839
|
program.name("lume").description("lume CLI \u2014 multi-framework component generator inspired by shadcn/ui").version("0.0.1");
|
|
600
840
|
program.command("init").description("Initialize your project and install dependencies").allowUnknownOption(true).argument("[components...]", "name, url or local path to component").option("-t, --template <template>", "the template to use. (next, vite, start, react-router, laravel, astro)").option("-p, --preset [name]", "use a preset configuration. (name, URL, or preset code)").option("-d, --defaults", "use default configuration. (default: false)").option("-y, --yes", "skip confirmation prompt. (default: true)").option("-f, --force", "force overwrite of existing configuration. (default: false)").option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.").option("-s, --silent", "mute output. (default: false)").option("--monorepo", "scaffold a monorepo project.").option("--no-monorepo", "skip the monorepo prompt.").option("--reinstall", "re-install existing UI components.").option("--no-reinstall", "do not re-install existing UI components.").option("--css-variables", "use css variables for theming. (default: true)").option("--no-css-variables", "do not use css variables for theming.").option("-h, --help", "display help for command").action(init);
|
|
601
841
|
program.command("add").description("add a component to your project").allowUnknownOption(true).argument("[components...]", "name, url or local path to component").option("-y, --yes", "skip confirmation prompt. (default: false)").option("-o, --overwrite", "overwrite existing files. (default: false)").option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.").option("-a, --all", "add all available components (default: false)").option("-p, --path <path>", "the path to add the component to.").option("-s, --silent", "mute output. (default: false)").option("--dry-run", "preview changes without writing files. (default: false)").option("--diff [path]", "show diff for a file.").option("--view [path]", "show file contents.").option("-h, --help", "display help for command").option("-f, --framework <framework>", "Target framework (vue, react, svelte, astro)").action(add);
|
|
842
|
+
program.command("add-styles").description("add globals.css and tailwind.config.ts with merge support").option("-y, --yes", "skip confirmation prompt. (default: false)").option("-o, --overwrite", "overwrite existing files. (default: false)").option("-f, --force", "force overwrite without asking. (default: false)").option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.").option("-s, --silent", "mute output. (default: false)").option("-h, --help", "display help for command").action(addStyles);
|
|
602
843
|
program.command("list").description("List all available components").option("-f, --framework <framework>", "Target framework (vue, react, svelte, astro)").action(list);
|
|
603
844
|
program.parse();
|