bunkit-cli 1.0.2 → 1.1.1
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 +703 -440
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11215,7 +11215,7 @@ function normalizeString(path, allowAboveRoot) {
|
|
|
11215
11215
|
}
|
|
11216
11216
|
return res;
|
|
11217
11217
|
}
|
|
11218
|
-
var _DRIVE_LETTER_START_RE, _UNC_REGEX, _IS_ABSOLUTE_RE, _DRIVE_LETTER_RE, normalize = function(path) {
|
|
11218
|
+
var _DRIVE_LETTER_START_RE, _UNC_REGEX, _IS_ABSOLUTE_RE, _DRIVE_LETTER_RE, _ROOT_FOLDER_RE, sep = "/", delimiter = ":", normalize = function(path) {
|
|
11219
11219
|
if (path.length === 0) {
|
|
11220
11220
|
return ".";
|
|
11221
11221
|
}
|
|
@@ -11280,24 +11280,95 @@ var _DRIVE_LETTER_START_RE, _UNC_REGEX, _IS_ABSOLUTE_RE, _DRIVE_LETTER_RE, norma
|
|
|
11280
11280
|
return resolvedPath.length > 0 ? resolvedPath : ".";
|
|
11281
11281
|
}, isAbsolute = function(p2) {
|
|
11282
11282
|
return _IS_ABSOLUTE_RE.test(p2);
|
|
11283
|
+
}, toNamespacedPath = function(p2) {
|
|
11284
|
+
return normalizeWindowsPath(p2);
|
|
11285
|
+
}, _EXTNAME_RE, extname = function(p2) {
|
|
11286
|
+
const match = _EXTNAME_RE.exec(normalizeWindowsPath(p2));
|
|
11287
|
+
return match && match[1] || "";
|
|
11288
|
+
}, relative = function(from, to) {
|
|
11289
|
+
const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
11290
|
+
const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
11291
|
+
if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) {
|
|
11292
|
+
return _to.join("/");
|
|
11293
|
+
}
|
|
11294
|
+
const _fromCopy = [..._from];
|
|
11295
|
+
for (const segment of _fromCopy) {
|
|
11296
|
+
if (_to[0] !== segment) {
|
|
11297
|
+
break;
|
|
11298
|
+
}
|
|
11299
|
+
_from.shift();
|
|
11300
|
+
_to.shift();
|
|
11301
|
+
}
|
|
11302
|
+
return [..._from.map(() => ".."), ..._to].join("/");
|
|
11283
11303
|
}, dirname = function(p2) {
|
|
11284
11304
|
const segments = normalizeWindowsPath(p2).replace(/\/$/, "").split("/").slice(0, -1);
|
|
11285
11305
|
if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) {
|
|
11286
11306
|
segments[0] += "/";
|
|
11287
11307
|
}
|
|
11288
11308
|
return segments.join("/") || (isAbsolute(p2) ? "/" : ".");
|
|
11309
|
+
}, format = function(p2) {
|
|
11310
|
+
const segments = [p2.root, p2.dir, p2.base ?? p2.name + p2.ext].filter(Boolean);
|
|
11311
|
+
return normalizeWindowsPath(p2.root ? resolve(...segments) : segments.join("/"));
|
|
11289
11312
|
}, basename = function(p2, extension) {
|
|
11290
11313
|
const lastSegment = normalizeWindowsPath(p2).split("/").pop();
|
|
11291
11314
|
return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;
|
|
11292
|
-
}
|
|
11315
|
+
}, parse = function(p2) {
|
|
11316
|
+
const root = normalizeWindowsPath(p2).split("/").shift() || "/";
|
|
11317
|
+
const base = basename(p2);
|
|
11318
|
+
const extension = extname(base);
|
|
11319
|
+
return {
|
|
11320
|
+
root,
|
|
11321
|
+
dir: dirname(p2),
|
|
11322
|
+
base,
|
|
11323
|
+
ext: extension,
|
|
11324
|
+
name: base.slice(0, base.length - extension.length)
|
|
11325
|
+
};
|
|
11326
|
+
}, path;
|
|
11293
11327
|
var init_pathe_ff20891b = __esm(() => {
|
|
11294
11328
|
_DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
11295
11329
|
_UNC_REGEX = /^[/\\]{2}/;
|
|
11296
11330
|
_IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
11297
11331
|
_DRIVE_LETTER_RE = /^[A-Za-z]:$/;
|
|
11332
|
+
_ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
|
|
11333
|
+
_EXTNAME_RE = /.(\.[^./]+)$/;
|
|
11334
|
+
path = {
|
|
11335
|
+
__proto__: null,
|
|
11336
|
+
basename,
|
|
11337
|
+
delimiter,
|
|
11338
|
+
dirname,
|
|
11339
|
+
extname,
|
|
11340
|
+
format,
|
|
11341
|
+
isAbsolute,
|
|
11342
|
+
join,
|
|
11343
|
+
normalize,
|
|
11344
|
+
normalizeString,
|
|
11345
|
+
parse,
|
|
11346
|
+
relative,
|
|
11347
|
+
resolve,
|
|
11348
|
+
sep,
|
|
11349
|
+
toNamespacedPath
|
|
11350
|
+
};
|
|
11298
11351
|
});
|
|
11299
11352
|
|
|
11300
11353
|
// ../../node_modules/pathe/dist/index.mjs
|
|
11354
|
+
var exports_dist = {};
|
|
11355
|
+
__export(exports_dist, {
|
|
11356
|
+
toNamespacedPath: () => toNamespacedPath,
|
|
11357
|
+
sep: () => sep,
|
|
11358
|
+
resolve: () => resolve,
|
|
11359
|
+
relative: () => relative,
|
|
11360
|
+
parse: () => parse,
|
|
11361
|
+
normalizeString: () => normalizeString,
|
|
11362
|
+
normalize: () => normalize,
|
|
11363
|
+
join: () => join,
|
|
11364
|
+
isAbsolute: () => isAbsolute,
|
|
11365
|
+
format: () => format,
|
|
11366
|
+
extname: () => extname,
|
|
11367
|
+
dirname: () => dirname,
|
|
11368
|
+
delimiter: () => delimiter,
|
|
11369
|
+
default: () => path,
|
|
11370
|
+
basename: () => basename
|
|
11371
|
+
});
|
|
11301
11372
|
var init_dist = __esm(() => {
|
|
11302
11373
|
init_pathe_ff20891b();
|
|
11303
11374
|
});
|
|
@@ -18563,7 +18634,7 @@ async function isGitAvailable() {
|
|
|
18563
18634
|
}
|
|
18564
18635
|
}
|
|
18565
18636
|
async function initGit(cwd2) {
|
|
18566
|
-
await execa("git", ["init"], { cwd: cwd2 });
|
|
18637
|
+
await execa("git", ["init", "--initial-branch=main"], { cwd: cwd2 });
|
|
18567
18638
|
await execa("git", ["add", "-A"], { cwd: cwd2 });
|
|
18568
18639
|
try {
|
|
18569
18640
|
await execa("git", ["commit", "-m", "Initial commit from bunkit", "--no-verify"], { cwd: cwd2 });
|
|
@@ -26251,77 +26322,116 @@ var themes = {
|
|
|
26251
26322
|
};
|
|
26252
26323
|
function generateThemeCSS(theme, customRadius) {
|
|
26253
26324
|
const radius = customRadius || theme.light.radius;
|
|
26254
|
-
return `@
|
|
26255
|
-
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
|
|
26259
|
-
|
|
26260
|
-
|
|
26261
|
-
|
|
26262
|
-
|
|
26263
|
-
|
|
26264
|
-
|
|
26265
|
-
|
|
26266
|
-
|
|
26267
|
-
|
|
26268
|
-
|
|
26269
|
-
|
|
26270
|
-
|
|
26271
|
-
|
|
26272
|
-
|
|
26273
|
-
|
|
26274
|
-
|
|
26275
|
-
|
|
26276
|
-
|
|
26277
|
-
|
|
26278
|
-
|
|
26279
|
-
|
|
26280
|
-
|
|
26281
|
-
|
|
26282
|
-
|
|
26283
|
-
|
|
26284
|
-
|
|
26285
|
-
|
|
26286
|
-
|
|
26287
|
-
|
|
26288
|
-
|
|
26289
|
-
}
|
|
26290
|
-
|
|
26291
|
-
|
|
26292
|
-
|
|
26293
|
-
|
|
26294
|
-
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
|
|
26299
|
-
|
|
26300
|
-
|
|
26301
|
-
|
|
26302
|
-
|
|
26303
|
-
|
|
26304
|
-
|
|
26305
|
-
|
|
26306
|
-
|
|
26307
|
-
|
|
26308
|
-
|
|
26309
|
-
|
|
26310
|
-
|
|
26311
|
-
|
|
26312
|
-
|
|
26313
|
-
|
|
26314
|
-
|
|
26315
|
-
|
|
26316
|
-
|
|
26317
|
-
|
|
26318
|
-
|
|
26319
|
-
|
|
26320
|
-
|
|
26321
|
-
|
|
26322
|
-
|
|
26323
|
-
|
|
26324
|
-
}
|
|
26325
|
+
return `@import "tailwindcss";
|
|
26326
|
+
@import "tw-animate-css";
|
|
26327
|
+
|
|
26328
|
+
:root {
|
|
26329
|
+
--radius: ${radius};
|
|
26330
|
+
--background: ${theme.light.background};
|
|
26331
|
+
--foreground: ${theme.light.foreground};
|
|
26332
|
+
--card: ${theme.light.card};
|
|
26333
|
+
--card-foreground: ${theme.light.cardForeground};
|
|
26334
|
+
--popover: ${theme.light.popover};
|
|
26335
|
+
--popover-foreground: ${theme.light.popoverForeground};
|
|
26336
|
+
--primary: ${theme.light.primary};
|
|
26337
|
+
--primary-foreground: ${theme.light.primaryForeground};
|
|
26338
|
+
--secondary: ${theme.light.secondary};
|
|
26339
|
+
--secondary-foreground: ${theme.light.secondaryForeground};
|
|
26340
|
+
--muted: ${theme.light.muted};
|
|
26341
|
+
--muted-foreground: ${theme.light.mutedForeground};
|
|
26342
|
+
--accent: ${theme.light.accent};
|
|
26343
|
+
--accent-foreground: ${theme.light.accentForeground};
|
|
26344
|
+
--destructive: ${theme.light.destructive};
|
|
26345
|
+
--destructive-foreground: ${theme.light.destructiveForeground};
|
|
26346
|
+
--border: ${theme.light.border};
|
|
26347
|
+
--input: ${theme.light.input};
|
|
26348
|
+
--ring: ${theme.light.ring};
|
|
26349
|
+
--chart-1: ${theme.light.chart1};
|
|
26350
|
+
--chart-2: ${theme.light.chart2};
|
|
26351
|
+
--chart-3: ${theme.light.chart3};
|
|
26352
|
+
--chart-4: ${theme.light.chart4};
|
|
26353
|
+
--chart-5: ${theme.light.chart5};
|
|
26354
|
+
--sidebar: ${theme.light.sidebar};
|
|
26355
|
+
--sidebar-foreground: ${theme.light.sidebarForeground};
|
|
26356
|
+
--sidebar-primary: ${theme.light.sidebarPrimary};
|
|
26357
|
+
--sidebar-primary-foreground: ${theme.light.sidebarPrimaryForeground};
|
|
26358
|
+
--sidebar-accent: ${theme.light.sidebarAccent};
|
|
26359
|
+
--sidebar-accent-foreground: ${theme.light.sidebarAccentForeground};
|
|
26360
|
+
--sidebar-border: ${theme.light.sidebarBorder};
|
|
26361
|
+
--sidebar-ring: ${theme.light.sidebarRing};
|
|
26362
|
+
}
|
|
26363
|
+
|
|
26364
|
+
.dark {
|
|
26365
|
+
--background: ${theme.dark.background};
|
|
26366
|
+
--foreground: ${theme.dark.foreground};
|
|
26367
|
+
--card: ${theme.dark.card};
|
|
26368
|
+
--card-foreground: ${theme.dark.cardForeground};
|
|
26369
|
+
--popover: ${theme.dark.popover};
|
|
26370
|
+
--popover-foreground: ${theme.dark.popoverForeground};
|
|
26371
|
+
--primary: ${theme.dark.primary};
|
|
26372
|
+
--primary-foreground: ${theme.dark.primaryForeground};
|
|
26373
|
+
--secondary: ${theme.dark.secondary};
|
|
26374
|
+
--secondary-foreground: ${theme.dark.secondaryForeground};
|
|
26375
|
+
--muted: ${theme.dark.muted};
|
|
26376
|
+
--muted-foreground: ${theme.dark.mutedForeground};
|
|
26377
|
+
--accent: ${theme.dark.accent};
|
|
26378
|
+
--accent-foreground: ${theme.dark.accentForeground};
|
|
26379
|
+
--destructive: ${theme.dark.destructive};
|
|
26380
|
+
--destructive-foreground: ${theme.dark.destructiveForeground};
|
|
26381
|
+
--border: ${theme.dark.border};
|
|
26382
|
+
--input: ${theme.dark.input};
|
|
26383
|
+
--ring: ${theme.dark.ring};
|
|
26384
|
+
--chart-1: ${theme.dark.chart1};
|
|
26385
|
+
--chart-2: ${theme.dark.chart2};
|
|
26386
|
+
--chart-3: ${theme.dark.chart3};
|
|
26387
|
+
--chart-4: ${theme.dark.chart4};
|
|
26388
|
+
--chart-5: ${theme.dark.chart5};
|
|
26389
|
+
--sidebar: ${theme.dark.sidebar};
|
|
26390
|
+
--sidebar-foreground: ${theme.dark.sidebarForeground};
|
|
26391
|
+
--sidebar-primary: ${theme.dark.sidebarPrimary};
|
|
26392
|
+
--sidebar-primary-foreground: ${theme.dark.sidebarPrimaryForeground};
|
|
26393
|
+
--sidebar-accent: ${theme.dark.sidebarAccent};
|
|
26394
|
+
--sidebar-accent-foreground: ${theme.dark.sidebarAccentForeground};
|
|
26395
|
+
--sidebar-border: ${theme.dark.sidebarBorder};
|
|
26396
|
+
--sidebar-ring: ${theme.dark.sidebarRing};
|
|
26397
|
+
}
|
|
26398
|
+
|
|
26399
|
+
@theme inline {
|
|
26400
|
+
--color-background: var(--background);
|
|
26401
|
+
--color-foreground: var(--foreground);
|
|
26402
|
+
--color-card: var(--card);
|
|
26403
|
+
--color-card-foreground: var(--card-foreground);
|
|
26404
|
+
--color-popover: var(--popover);
|
|
26405
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
26406
|
+
--color-primary: var(--primary);
|
|
26407
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
26408
|
+
--color-secondary: var(--secondary);
|
|
26409
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
26410
|
+
--color-muted: var(--muted);
|
|
26411
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
26412
|
+
--color-accent: var(--accent);
|
|
26413
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
26414
|
+
--color-destructive: var(--destructive);
|
|
26415
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
26416
|
+
--color-border: var(--border);
|
|
26417
|
+
--color-input: var(--input);
|
|
26418
|
+
--color-ring: var(--ring);
|
|
26419
|
+
--color-chart-1: var(--chart-1);
|
|
26420
|
+
--color-chart-2: var(--chart-2);
|
|
26421
|
+
--color-chart-3: var(--chart-3);
|
|
26422
|
+
--color-chart-4: var(--chart-4);
|
|
26423
|
+
--color-chart-5: var(--chart-5);
|
|
26424
|
+
--color-sidebar: var(--sidebar);
|
|
26425
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
26426
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
26427
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
26428
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
26429
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
26430
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
26431
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
26432
|
+
--radius-lg: var(--radius);
|
|
26433
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
26434
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
26325
26435
|
}
|
|
26326
26436
|
|
|
26327
26437
|
@layer base {
|
|
@@ -26339,7 +26449,6 @@ function generateThemeCSS(theme, customRadius) {
|
|
|
26339
26449
|
init_execa();
|
|
26340
26450
|
init_dist();
|
|
26341
26451
|
init_src();
|
|
26342
|
-
init_src();
|
|
26343
26452
|
var DEFAULT_SHADCN_COMPONENTS = [
|
|
26344
26453
|
"button",
|
|
26345
26454
|
"card"
|
|
@@ -26347,50 +26456,121 @@ var DEFAULT_SHADCN_COMPONENTS = [
|
|
|
26347
26456
|
async function installShadcnComponents(projectPath, components, options = {}) {
|
|
26348
26457
|
const cwd2 = options.cwd || projectPath;
|
|
26349
26458
|
const stdio = options.silent ? "pipe" : "inherit";
|
|
26459
|
+
const targetCwd = options.isMonorepo ? join(projectPath, "packages/ui") : cwd2;
|
|
26460
|
+
try {
|
|
26461
|
+
logger.debug("Installing dependencies with Bun before running shadcn CLI...");
|
|
26462
|
+
await execa("bun", ["install"], {
|
|
26463
|
+
cwd: options.isMonorepo ? projectPath : targetCwd,
|
|
26464
|
+
stdio: options.silent ? "pipe" : "inherit",
|
|
26465
|
+
env: {
|
|
26466
|
+
...process.env,
|
|
26467
|
+
BUN_INSTALL_LINKER: "isolated"
|
|
26468
|
+
}
|
|
26469
|
+
});
|
|
26470
|
+
} catch (installError) {
|
|
26471
|
+
logger.warn(`Failed to install dependencies with Bun: ${installError.message}`);
|
|
26472
|
+
}
|
|
26350
26473
|
try {
|
|
26351
26474
|
await execa("bunx", ["shadcn@latest", "add", ...components], {
|
|
26352
|
-
cwd:
|
|
26353
|
-
stdio
|
|
26475
|
+
cwd: targetCwd,
|
|
26476
|
+
stdio,
|
|
26477
|
+
env: {
|
|
26478
|
+
...process.env,
|
|
26479
|
+
BUN_INSTALL_LINKER: "isolated",
|
|
26480
|
+
npm_config_force: "true"
|
|
26481
|
+
}
|
|
26354
26482
|
});
|
|
26483
|
+
if (options.isMonorepo) {
|
|
26484
|
+
await updateComponentsIndex(join(targetCwd, "src/components"));
|
|
26485
|
+
}
|
|
26355
26486
|
} catch (error) {
|
|
26356
26487
|
try {
|
|
26357
26488
|
await execa("npx", ["shadcn@latest", "add", ...components], {
|
|
26358
|
-
cwd:
|
|
26489
|
+
cwd: targetCwd,
|
|
26359
26490
|
stdio
|
|
26360
26491
|
});
|
|
26492
|
+
if (options.isMonorepo) {
|
|
26493
|
+
await updateComponentsIndex(join(targetCwd, "src/components"));
|
|
26494
|
+
}
|
|
26361
26495
|
} catch (fallbackError) {
|
|
26362
|
-
logger.warn(`Could not install shadcn components automatically. You can install them manually with: bunx shadcn@latest add ${components.join(" ")}`);
|
|
26496
|
+
logger.warn(`Could not install shadcn components automatically. You can install them manually with: cd ${targetCwd} && bun install && bunx shadcn@latest add ${components.join(" ")}`);
|
|
26497
|
+
throw fallbackError;
|
|
26363
26498
|
}
|
|
26364
26499
|
}
|
|
26365
26500
|
}
|
|
26501
|
+
async function updateComponentsIndex(componentsDir) {
|
|
26502
|
+
const indexPath = join(componentsDir, "index.ts");
|
|
26503
|
+
const uiDir = join(componentsDir, "ui");
|
|
26504
|
+
try {
|
|
26505
|
+
const { existsSync } = await import("fs");
|
|
26506
|
+
if (!existsSync(uiDir)) {
|
|
26507
|
+
logger.debug(`UI directory does not exist: ${uiDir}`);
|
|
26508
|
+
return;
|
|
26509
|
+
}
|
|
26510
|
+
const { readdir } = await import("fs/promises");
|
|
26511
|
+
const entries = await readdir(uiDir, { withFileTypes: true });
|
|
26512
|
+
const componentFiles = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".tsx")).map((entry) => entry.name.replace(".tsx", "")).sort();
|
|
26513
|
+
if (componentFiles.length === 0) {
|
|
26514
|
+
logger.debug(`No component files found in ${uiDir}`);
|
|
26515
|
+
return;
|
|
26516
|
+
}
|
|
26517
|
+
const exports = componentFiles.map((comp) => `export * from './ui/${comp}';`).join(`
|
|
26518
|
+
`);
|
|
26519
|
+
const newContent = `// Auto-generated exports for shadcn/ui components
|
|
26520
|
+
// Components are installed via: bunkit add component --components [name]
|
|
26521
|
+
// Or: bunx shadcn@latest add [name] (from packages/ui directory)
|
|
26522
|
+
|
|
26523
|
+
${exports}
|
|
26524
|
+
`;
|
|
26525
|
+
await writeFile(indexPath, newContent);
|
|
26526
|
+
logger.debug(`Updated components index with ${componentFiles.length} components`);
|
|
26527
|
+
} catch (error) {
|
|
26528
|
+
logger.warn(`Could not update components index file: ${error.message}`);
|
|
26529
|
+
}
|
|
26530
|
+
}
|
|
26366
26531
|
async function installDefaultShadcnComponents(projectPath, options = {}) {
|
|
26367
26532
|
if (options.skipDefaults) {
|
|
26368
26533
|
return;
|
|
26369
26534
|
}
|
|
26535
|
+
const isMonorepo = options.isMonorepo ?? (await import("fs")).existsSync((await Promise.resolve().then(() => (init_dist(), exports_dist))).join(projectPath, "packages/ui/components.json"));
|
|
26370
26536
|
logger.step("Installing default shadcn/ui components...");
|
|
26371
26537
|
try {
|
|
26372
26538
|
await installShadcnComponents(projectPath, [...DEFAULT_SHADCN_COMPONENTS], {
|
|
26373
26539
|
silent: options.silent,
|
|
26374
|
-
cwd: projectPath
|
|
26540
|
+
cwd: projectPath,
|
|
26541
|
+
isMonorepo
|
|
26375
26542
|
});
|
|
26376
26543
|
logger.success("Default components installed");
|
|
26377
26544
|
} catch (error) {
|
|
26378
|
-
|
|
26545
|
+
const manualCommand = isMonorepo ? "cd packages/ui && bunx shadcn@latest add button card" : "bunx shadcn@latest add button card";
|
|
26546
|
+
logger.warn(`Could not install default components automatically. Install them manually with: ${manualCommand}`);
|
|
26379
26547
|
}
|
|
26380
26548
|
}
|
|
26381
|
-
async function createShadcnExample(projectPath, isMonorepo = false) {
|
|
26549
|
+
async function createShadcnExample(projectPath, isMonorepo = false, packageName) {
|
|
26382
26550
|
const examplePath = isMonorepo ? join(projectPath, "apps/web/src/components/example.tsx") : join(projectPath, "src/components/example.tsx");
|
|
26383
|
-
const
|
|
26384
|
-
|
|
26385
|
-
import { Button } from "@/components/ui/button"
|
|
26386
|
-
import {
|
|
26551
|
+
const buttonImport = isMonorepo ? `import { Button } from "@workspace/ui/components/ui/button"` : `import { Button } from "@/components/ui/button"`;
|
|
26552
|
+
const cardImport = isMonorepo ? `import {
|
|
26387
26553
|
Card,
|
|
26388
26554
|
CardContent,
|
|
26389
26555
|
CardDescription,
|
|
26390
26556
|
CardFooter,
|
|
26391
26557
|
CardHeader,
|
|
26392
26558
|
CardTitle,
|
|
26393
|
-
} from "
|
|
26559
|
+
} from "@workspace/ui/components/ui/card"` : `import {
|
|
26560
|
+
Card,
|
|
26561
|
+
CardContent,
|
|
26562
|
+
CardDescription,
|
|
26563
|
+
CardFooter,
|
|
26564
|
+
CardHeader,
|
|
26565
|
+
CardTitle,
|
|
26566
|
+
} from "@/components/ui/card"`;
|
|
26567
|
+
const importHint = isMonorepo ? `// In monorepo, components are imported from @workspace/ui package
|
|
26568
|
+
// This ensures all apps share the same UI components and Tailwind CSS v4 config` : `// Components are imported using the @ alias configured in tsconfig.json`;
|
|
26569
|
+
const exampleContent = `"use client"
|
|
26570
|
+
|
|
26571
|
+
${importHint}
|
|
26572
|
+
${buttonImport}
|
|
26573
|
+
${cardImport}
|
|
26394
26574
|
|
|
26395
26575
|
/**
|
|
26396
26576
|
* Example component showcasing shadcn/ui components
|
|
@@ -26410,7 +26590,7 @@ export function ExampleComponent() {
|
|
|
26410
26590
|
</CardHeader>
|
|
26411
26591
|
<CardContent>
|
|
26412
26592
|
<p className="text-sm text-muted-foreground">
|
|
26413
|
-
You can start building your UI by importing components from @/components/ui
|
|
26593
|
+
${isMonorepo ? "Components are shared via @workspace/ui package. Add more components with: bunkit add component --components [name]" : "You can start building your UI by importing components from @/components/ui"}
|
|
26414
26594
|
</p>
|
|
26415
26595
|
</CardContent>
|
|
26416
26596
|
<CardFooter className="flex gap-2">
|
|
@@ -26433,9 +26613,77 @@ init_dist();
|
|
|
26433
26613
|
init_src();
|
|
26434
26614
|
async function createShadcnDocs(projectPath, isMonorepo = false, context) {
|
|
26435
26615
|
const docsPath = isMonorepo ? join(projectPath, "packages/ui/SHADCN.md") : join(projectPath, "SHADCN.md");
|
|
26616
|
+
const monorepoSection = isMonorepo ? `
|
|
26617
|
+
## \uD83C\uDFD7\uFE0F Bun Monorepo Setup
|
|
26618
|
+
|
|
26619
|
+
This is a **Bun monorepo** with shared UI components in \`packages/ui\`. All shadcn/ui components are installed here and shared across all apps in the monorepo.
|
|
26620
|
+
|
|
26621
|
+
### Monorepo Structure
|
|
26622
|
+
|
|
26623
|
+
\`\`\`
|
|
26624
|
+
packages/
|
|
26625
|
+
ui/ # Shared UI package
|
|
26626
|
+
src/
|
|
26627
|
+
components/ui/ # shadcn/ui components
|
|
26628
|
+
styles/ # Tailwind CSS v4 configuration
|
|
26629
|
+
lib/utils.ts # Utility functions (cn helper)
|
|
26630
|
+
components.json # shadcn/ui configuration
|
|
26631
|
+
\`\`\`
|
|
26632
|
+
|
|
26633
|
+
### Adding Components (Monorepo)
|
|
26634
|
+
|
|
26635
|
+
Components are installed in \`packages/ui\` and automatically shared:
|
|
26636
|
+
|
|
26637
|
+
\`\`\`bash
|
|
26638
|
+
# From project root - bunkit handles monorepo detection
|
|
26639
|
+
bunkit add component --components button
|
|
26640
|
+
|
|
26641
|
+
# Or directly in packages/ui directory
|
|
26642
|
+
cd packages/ui
|
|
26643
|
+
bunx shadcn@latest add button
|
|
26644
|
+
\`\`\`
|
|
26645
|
+
|
|
26646
|
+
### Using Components (Monorepo)
|
|
26647
|
+
|
|
26648
|
+
Import components using Bun workspace aliases:
|
|
26649
|
+
|
|
26650
|
+
\`\`\`tsx
|
|
26651
|
+
// Recommended: Use @workspace/ui alias (Bun workspace resolution)
|
|
26652
|
+
import { Button } from "@workspace/ui/components/ui/button"
|
|
26653
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@workspace/ui/components/ui/card"
|
|
26654
|
+
|
|
26655
|
+
// Or use the package name directly
|
|
26656
|
+
import { Button } from "@${context?.packageName || "workspace"}/ui/components/ui/button"
|
|
26657
|
+
\`\`\`
|
|
26658
|
+
|
|
26659
|
+
### Tailwind CSS v4 Configuration
|
|
26660
|
+
|
|
26661
|
+
Tailwind CSS v4 is configured in \`packages/ui/src/styles/globals.css\` using CSS-first configuration:
|
|
26662
|
+
- \u2705 No \`tailwind.config.ts\` needed (Tailwind v4 feature)
|
|
26663
|
+
- \u2705 Uses \`@theme inline\` directive for design tokens
|
|
26664
|
+
- \u2705 OKLCH color space (modern color format)
|
|
26665
|
+
- \u2705 Shared across all apps via workspace imports
|
|
26666
|
+
|
|
26667
|
+
All apps import the CSS from the UI package:
|
|
26668
|
+
\`\`\`css
|
|
26669
|
+
/* In apps/web/src/app/globals.css */
|
|
26670
|
+
@import "../../../packages/ui/src/styles/globals.css";
|
|
26671
|
+
\`\`\`
|
|
26672
|
+
|
|
26673
|
+
### Bun Workspace Features
|
|
26674
|
+
|
|
26675
|
+
This setup leverages Bun 1.3 workspace features:
|
|
26676
|
+
- **Catalogs**: Dependency versions managed in root \`package.json\` catalog
|
|
26677
|
+
- **Isolated Installs**: Each package only sees its declared dependencies
|
|
26678
|
+
- **Workspace Aliases**: Use \`@workspace/ui\` for internal imports
|
|
26679
|
+
- **Fast Resolution**: Bun's native workspace resolution
|
|
26680
|
+
|
|
26681
|
+
` : "";
|
|
26436
26682
|
const docsContent = `# shadcn/ui Guide
|
|
26437
26683
|
|
|
26438
|
-
This project uses [shadcn/ui](https://ui.shadcn.com) - a collection of re-usable components built with Radix UI and Tailwind CSS.
|
|
26684
|
+
This project uses [shadcn/ui](https://ui.shadcn.com) - a collection of re-usable components built with Radix UI and Tailwind CSS v4.
|
|
26685
|
+
|
|
26686
|
+
${monorepoSection}
|
|
26439
26687
|
|
|
26440
26688
|
## \uD83D\uDE80 Quick Start
|
|
26441
26689
|
|
|
@@ -26457,14 +26705,40 @@ bunkit add component --all
|
|
|
26457
26705
|
Or use the official shadcn CLI directly:
|
|
26458
26706
|
|
|
26459
26707
|
\`\`\`bash
|
|
26460
|
-
bunx shadcn@latest add button
|
|
26461
|
-
bunx shadcn@latest add card
|
|
26462
|
-
bunx shadcn@latest add input
|
|
26708
|
+
${isMonorepo ? "cd packages/ui && " : ""}bunx shadcn@latest add button
|
|
26709
|
+
${isMonorepo ? "cd packages/ui && " : ""}bunx shadcn@latest add card
|
|
26710
|
+
${isMonorepo ? "cd packages/ui && " : ""}bunx shadcn@latest add input
|
|
26463
26711
|
\`\`\`
|
|
26464
26712
|
|
|
26465
26713
|
### Using Components
|
|
26466
26714
|
|
|
26467
|
-
Import components from the
|
|
26715
|
+
${isMonorepo ? `Import components from the \`@workspace/ui\` package:
|
|
26716
|
+
|
|
26717
|
+
\`\`\`tsx
|
|
26718
|
+
import { Button } from "@workspace/ui/components/ui/button"
|
|
26719
|
+
import {
|
|
26720
|
+
Card,
|
|
26721
|
+
CardContent,
|
|
26722
|
+
CardDescription,
|
|
26723
|
+
CardFooter,
|
|
26724
|
+
CardHeader,
|
|
26725
|
+
CardTitle,
|
|
26726
|
+
} from "@workspace/ui/components/ui/card"
|
|
26727
|
+
|
|
26728
|
+
export function MyComponent() {
|
|
26729
|
+
return (
|
|
26730
|
+
<Card>
|
|
26731
|
+
<CardHeader>
|
|
26732
|
+
<CardTitle>Hello</CardTitle>
|
|
26733
|
+
<CardDescription>World</CardDescription>
|
|
26734
|
+
</CardHeader>
|
|
26735
|
+
<CardContent>
|
|
26736
|
+
<Button>Click me</Button>
|
|
26737
|
+
</CardContent>
|
|
26738
|
+
</Card>
|
|
26739
|
+
)
|
|
26740
|
+
}
|
|
26741
|
+
\`\`\`` : `Import components from the \`@/components/ui\` path:
|
|
26468
26742
|
|
|
26469
26743
|
\`\`\`tsx
|
|
26470
26744
|
import { Button } from "@/components/ui/button"
|
|
@@ -26490,7 +26764,7 @@ export function MyComponent() {
|
|
|
26490
26764
|
</Card>
|
|
26491
26765
|
)
|
|
26492
26766
|
}
|
|
26493
|
-
|
|
26767
|
+
\`\`\``}
|
|
26494
26768
|
|
|
26495
26769
|
## \uD83D\uDCDA Available Components
|
|
26496
26770
|
|
|
@@ -26521,20 +26795,34 @@ Your project is configured with:
|
|
|
26521
26795
|
Edit the CSS variables in \`${isMonorepo ? "packages/ui/src/styles/globals.css" : "src/app/globals.css"}\`:
|
|
26522
26796
|
|
|
26523
26797
|
\`\`\`css
|
|
26524
|
-
|
|
26525
|
-
|
|
26526
|
-
|
|
26527
|
-
|
|
26528
|
-
|
|
26529
|
-
|
|
26530
|
-
|
|
26798
|
+
/* Tailwind CSS v4 uses CSS-first configuration */
|
|
26799
|
+
@import "tailwindcss";
|
|
26800
|
+
@import "tw-animate-css";
|
|
26801
|
+
|
|
26802
|
+
:root {
|
|
26803
|
+
--radius: 0.625rem;
|
|
26804
|
+
--background: oklch(...);
|
|
26805
|
+
--foreground: oklch(...);
|
|
26806
|
+
/* ... */
|
|
26807
|
+
}
|
|
26808
|
+
|
|
26809
|
+
@theme inline {
|
|
26810
|
+
--color-background: var(--background);
|
|
26811
|
+
--color-foreground: var(--foreground);
|
|
26812
|
+
/* ... */
|
|
26531
26813
|
}
|
|
26532
26814
|
\`\`\`
|
|
26533
26815
|
|
|
26816
|
+
**Note**: Tailwind CSS v4 uses CSS-first configuration. No \`tailwind.config.ts\` is needed - all configuration is done via CSS using the \`@theme inline\` directive.
|
|
26817
|
+
|
|
26534
26818
|
### Component Customization
|
|
26535
26819
|
|
|
26536
26820
|
Components are copied directly into your project at \`${isMonorepo ? "packages/ui/src/components/ui" : "src/components/ui"}\`. You can modify them directly - they're YOUR code!
|
|
26537
26821
|
|
|
26822
|
+
${isMonorepo ? `
|
|
26823
|
+
**Monorepo Tip**: Since components are in \`packages/ui\`, changes automatically propagate to all apps that import them. This ensures consistent UI across your entire monorepo.
|
|
26824
|
+
` : ""}
|
|
26825
|
+
|
|
26538
26826
|
## \uD83D\uDCD6 Documentation
|
|
26539
26827
|
|
|
26540
26828
|
- [Official shadcn/ui Docs](https://ui.shadcn.com)
|
|
@@ -26644,119 +26932,6 @@ ${shadcnCss}`;
|
|
|
26644
26932
|
}
|
|
26645
26933
|
await writeFile(globalsCssPath, globalsCss);
|
|
26646
26934
|
}
|
|
26647
|
-
const tailwindConfigPath = join(projectPath, "tailwind.config.ts");
|
|
26648
|
-
let tailwindConfig = "";
|
|
26649
|
-
try {
|
|
26650
|
-
tailwindConfig = await Bun.file(tailwindConfigPath).text();
|
|
26651
|
-
} catch {}
|
|
26652
|
-
if (tailwindConfig && !tailwindConfig.includes("hsl(var(--background))")) {
|
|
26653
|
-
const shadcnTheme = ` theme: {
|
|
26654
|
-
extend: {
|
|
26655
|
-
colors: {
|
|
26656
|
-
border: "hsl(var(--border))",
|
|
26657
|
-
input: "hsl(var(--input))",
|
|
26658
|
-
ring: "hsl(var(--ring))",
|
|
26659
|
-
background: "hsl(var(--background))",
|
|
26660
|
-
foreground: "hsl(var(--foreground))",
|
|
26661
|
-
primary: {
|
|
26662
|
-
DEFAULT: "hsl(var(--primary))",
|
|
26663
|
-
foreground: "hsl(var(--primary-foreground))",
|
|
26664
|
-
},
|
|
26665
|
-
secondary: {
|
|
26666
|
-
DEFAULT: "hsl(var(--secondary))",
|
|
26667
|
-
foreground: "hsl(var(--secondary-foreground))",
|
|
26668
|
-
},
|
|
26669
|
-
destructive: {
|
|
26670
|
-
DEFAULT: "hsl(var(--destructive))",
|
|
26671
|
-
foreground: "hsl(var(--destructive-foreground))",
|
|
26672
|
-
},
|
|
26673
|
-
muted: {
|
|
26674
|
-
DEFAULT: "hsl(var(--muted))",
|
|
26675
|
-
foreground: "hsl(var(--muted-foreground))",
|
|
26676
|
-
},
|
|
26677
|
-
accent: {
|
|
26678
|
-
DEFAULT: "hsl(var(--accent))",
|
|
26679
|
-
foreground: "hsl(var(--accent-foreground))",
|
|
26680
|
-
},
|
|
26681
|
-
popover: {
|
|
26682
|
-
DEFAULT: "hsl(var(--popover))",
|
|
26683
|
-
foreground: "hsl(var(--popover-foreground))",
|
|
26684
|
-
},
|
|
26685
|
-
card: {
|
|
26686
|
-
DEFAULT: "hsl(var(--card))",
|
|
26687
|
-
foreground: "hsl(var(--card-foreground))",
|
|
26688
|
-
},
|
|
26689
|
-
},
|
|
26690
|
-
borderRadius: {
|
|
26691
|
-
lg: "var(--radius)",
|
|
26692
|
-
md: "calc(var(--radius) - 2px)",
|
|
26693
|
-
sm: "calc(var(--radius) - 4px)",
|
|
26694
|
-
},
|
|
26695
|
-
},
|
|
26696
|
-
},`;
|
|
26697
|
-
if (tailwindConfig.includes("theme:")) {
|
|
26698
|
-
const updatedConfig = tailwindConfig.replace(/theme:\s*\{[^}]*\}/s, shadcnTheme.trim());
|
|
26699
|
-
await writeFile(tailwindConfigPath, updatedConfig);
|
|
26700
|
-
} else {
|
|
26701
|
-
const updatedConfig = tailwindConfig.replace(/(\s*)(plugins:.*?)(\n\s*\};)/s, `$1$2$1${shadcnTheme}$3`);
|
|
26702
|
-
await writeFile(tailwindConfigPath, updatedConfig);
|
|
26703
|
-
}
|
|
26704
|
-
} else if (!tailwindConfig) {
|
|
26705
|
-
const newTailwindConfig = `import type { Config } from 'tailwindcss';
|
|
26706
|
-
|
|
26707
|
-
const config: Config = {
|
|
26708
|
-
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
|
|
26709
|
-
theme: {
|
|
26710
|
-
extend: {
|
|
26711
|
-
colors: {
|
|
26712
|
-
border: "hsl(var(--border))",
|
|
26713
|
-
input: "hsl(var(--input))",
|
|
26714
|
-
ring: "hsl(var(--ring))",
|
|
26715
|
-
background: "hsl(var(--background))",
|
|
26716
|
-
foreground: "hsl(var(--foreground))",
|
|
26717
|
-
primary: {
|
|
26718
|
-
DEFAULT: "hsl(var(--primary))",
|
|
26719
|
-
foreground: "hsl(var(--primary-foreground))",
|
|
26720
|
-
},
|
|
26721
|
-
secondary: {
|
|
26722
|
-
DEFAULT: "hsl(var(--secondary))",
|
|
26723
|
-
foreground: "hsl(var(--secondary-foreground))",
|
|
26724
|
-
},
|
|
26725
|
-
destructive: {
|
|
26726
|
-
DEFAULT: "hsl(var(--destructive))",
|
|
26727
|
-
foreground: "hsl(var(--destructive-foreground))",
|
|
26728
|
-
},
|
|
26729
|
-
muted: {
|
|
26730
|
-
DEFAULT: "hsl(var(--muted))",
|
|
26731
|
-
foreground: "hsl(var(--muted-foreground))",
|
|
26732
|
-
},
|
|
26733
|
-
accent: {
|
|
26734
|
-
DEFAULT: "hsl(var(--accent))",
|
|
26735
|
-
foreground: "hsl(var(--accent-foreground))",
|
|
26736
|
-
},
|
|
26737
|
-
popover: {
|
|
26738
|
-
DEFAULT: "hsl(var(--popover))",
|
|
26739
|
-
foreground: "hsl(var(--popover-foreground))",
|
|
26740
|
-
},
|
|
26741
|
-
card: {
|
|
26742
|
-
DEFAULT: "hsl(var(--card))",
|
|
26743
|
-
foreground: "hsl(var(--card-foreground))",
|
|
26744
|
-
},
|
|
26745
|
-
},
|
|
26746
|
-
borderRadius: {
|
|
26747
|
-
lg: "var(--radius)",
|
|
26748
|
-
md: "calc(var(--radius) - 2px)",
|
|
26749
|
-
sm: "calc(var(--radius) - 4px)",
|
|
26750
|
-
},
|
|
26751
|
-
},
|
|
26752
|
-
},
|
|
26753
|
-
plugins: [],
|
|
26754
|
-
};
|
|
26755
|
-
|
|
26756
|
-
export default config;
|
|
26757
|
-
`;
|
|
26758
|
-
await writeFile(tailwindConfigPath, newTailwindConfig);
|
|
26759
|
-
}
|
|
26760
26935
|
if (context.install !== false) {}
|
|
26761
26936
|
await createShadcnExample(projectPath, false);
|
|
26762
26937
|
await createShadcnDocs(projectPath, false, context);
|
|
@@ -26778,10 +26953,13 @@ async function setupShadcnMonorepo(projectPath, context) {
|
|
|
26778
26953
|
main: "./src/index.ts",
|
|
26779
26954
|
types: "./src/index.ts",
|
|
26780
26955
|
exports: {
|
|
26956
|
+
".": "./src/index.ts",
|
|
26781
26957
|
"./components": "./src/components/index.ts",
|
|
26958
|
+
"./components/*": "./src/components/ui/*/index.ts",
|
|
26782
26959
|
"./lib/utils": "./src/lib/utils.ts",
|
|
26783
26960
|
"./hooks": "./src/hooks/index.ts",
|
|
26784
|
-
"./styles": "./src/styles/globals.css"
|
|
26961
|
+
"./styles": "./src/styles/globals.css",
|
|
26962
|
+
"./components/ui/*": "./src/components/ui/*/index.ts"
|
|
26785
26963
|
},
|
|
26786
26964
|
dependencies: {
|
|
26787
26965
|
"@radix-ui/react-slot": "catalog:",
|
|
@@ -26810,11 +26988,11 @@ async function setupShadcnMonorepo(projectPath, context) {
|
|
|
26810
26988
|
},
|
|
26811
26989
|
iconLibrary: "lucide",
|
|
26812
26990
|
aliases: {
|
|
26813
|
-
components: "
|
|
26814
|
-
utils: "
|
|
26815
|
-
hooks: "
|
|
26816
|
-
lib: "
|
|
26817
|
-
ui: "
|
|
26991
|
+
components: "@/components",
|
|
26992
|
+
utils: "@/lib/utils",
|
|
26993
|
+
hooks: "@/hooks",
|
|
26994
|
+
lib: "@/lib",
|
|
26995
|
+
ui: "@/components/ui"
|
|
26818
26996
|
}
|
|
26819
26997
|
};
|
|
26820
26998
|
await writeFile(join(projectPath, "packages/ui/components.json"), JSON.stringify(uiComponentsJson, null, 2));
|
|
@@ -26827,9 +27005,27 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
26827
27005
|
`;
|
|
26828
27006
|
await writeFile(join(projectPath, "packages/ui/src/lib/utils.ts"), uiUtilsContent);
|
|
26829
27007
|
const uiComponentsIndex = `// Export shadcn/ui components here
|
|
26830
|
-
// Components
|
|
27008
|
+
// Components are installed in src/components/ui/ and exported here
|
|
27009
|
+
// Add components using: bunkit add component --components button,card,input
|
|
27010
|
+
// Or directly: bunx shadcn@latest add [component] (from packages/ui directory)
|
|
27011
|
+
|
|
27012
|
+
// Components will be automatically exported here when added
|
|
26831
27013
|
`;
|
|
26832
27014
|
await writeFile(join(projectPath, "packages/ui/src/components/index.ts"), uiComponentsIndex);
|
|
27015
|
+
const uiIndexContent = `// Main entry point for @${packageName}/ui package
|
|
27016
|
+
// This package provides shared shadcn/ui components and Tailwind CSS v4 configuration
|
|
27017
|
+
|
|
27018
|
+
// Export utilities
|
|
27019
|
+
export * from './lib/utils';
|
|
27020
|
+
|
|
27021
|
+
// Export hooks (if any)
|
|
27022
|
+
export * from './hooks';
|
|
27023
|
+
|
|
27024
|
+
// Components are exported from individual files
|
|
27025
|
+
// Import like: import { Button } from '@${packageName}/ui/components/ui/button'
|
|
27026
|
+
// Or use the re-export: import { Button } from '@workspace/ui/components/ui/button'
|
|
27027
|
+
`;
|
|
27028
|
+
await writeFile(join(projectPath, "packages/ui/src/index.ts"), uiIndexContent);
|
|
26833
27029
|
const uiHooksIndex = `// Export custom hooks here
|
|
26834
27030
|
`;
|
|
26835
27031
|
await writeFile(join(projectPath, "packages/ui/src/hooks/index.ts"), uiHooksIndex);
|
|
@@ -26850,212 +27046,81 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
26850
27046
|
resolveJsonModule: true,
|
|
26851
27047
|
isolatedModules: true,
|
|
26852
27048
|
jsx: "react-jsx",
|
|
26853
|
-
types: ["react", "react-dom"]
|
|
27049
|
+
types: ["react", "react-dom"],
|
|
27050
|
+
paths: {
|
|
27051
|
+
"@/*": ["./src/*"]
|
|
27052
|
+
}
|
|
26854
27053
|
},
|
|
26855
27054
|
include: ["src/**/*"],
|
|
26856
27055
|
exclude: ["node_modules"]
|
|
26857
27056
|
};
|
|
26858
27057
|
await writeFile(join(projectPath, "packages/ui/tsconfig.json"), JSON.stringify(uiTsconfig, null, 2));
|
|
26859
|
-
|
|
26860
|
-
|
|
26861
|
-
|
|
26862
|
-
|
|
26863
|
-
style,
|
|
26864
|
-
rsc: true,
|
|
26865
|
-
tsx: true,
|
|
26866
|
-
tailwind: {
|
|
26867
|
-
config: "",
|
|
26868
|
-
css: "../../packages/ui/src/styles/globals.css",
|
|
26869
|
-
baseColor,
|
|
26870
|
-
cssVariables: true
|
|
26871
|
-
},
|
|
26872
|
-
iconLibrary: "lucide",
|
|
26873
|
-
aliases: {
|
|
26874
|
-
components: "@/components",
|
|
26875
|
-
hooks: "@/hooks",
|
|
26876
|
-
lib: "@/lib",
|
|
26877
|
-
utils: "@workspace/ui/lib/utils",
|
|
26878
|
-
ui: "@workspace/ui/components"
|
|
26879
|
-
}
|
|
26880
|
-
};
|
|
26881
|
-
await writeFile(join(projectPath, "apps/web/components.json"), JSON.stringify(webComponentsJson, null, 2));
|
|
26882
|
-
const webGlobalsCssPath = join(projectPath, "apps/web/src/app/globals.css");
|
|
26883
|
-
const webGlobalsCss = `@import "../../../packages/ui/src/styles/globals.css";
|
|
26884
|
-
`;
|
|
26885
|
-
await writeFile(webGlobalsCssPath, webGlobalsCss);
|
|
26886
|
-
const webPackageJsonPath = join(projectPath, "apps/web/package.json");
|
|
26887
|
-
let webPackageJson = {};
|
|
26888
|
-
try {
|
|
26889
|
-
webPackageJson = JSON.parse(await Bun.file(webPackageJsonPath).text());
|
|
26890
|
-
} catch {}
|
|
26891
|
-
if (webPackageJson.dependencies) {
|
|
26892
|
-
webPackageJson.dependencies[uiPackageName] = "workspace:*";
|
|
26893
|
-
await writeFile(webPackageJsonPath, JSON.stringify(webPackageJson, null, 2));
|
|
26894
|
-
}
|
|
26895
|
-
await ensureDirectory(join(projectPath, "apps/platform/src/components"));
|
|
26896
|
-
await ensureDirectory(join(projectPath, "apps/platform/src/lib"));
|
|
26897
|
-
const platformComponentsJson = {
|
|
26898
|
-
$schema: "https://ui.shadcn.com/schema.json",
|
|
26899
|
-
style,
|
|
26900
|
-
rsc: true,
|
|
26901
|
-
tsx: true,
|
|
26902
|
-
tailwind: {
|
|
26903
|
-
config: "",
|
|
26904
|
-
css: "../../packages/ui/src/styles/globals.css",
|
|
26905
|
-
baseColor,
|
|
26906
|
-
cssVariables: true
|
|
26907
|
-
},
|
|
26908
|
-
iconLibrary: "lucide",
|
|
26909
|
-
aliases: {
|
|
26910
|
-
components: "@/components",
|
|
26911
|
-
hooks: "@/hooks",
|
|
26912
|
-
lib: "@/lib",
|
|
26913
|
-
utils: "@workspace/ui/lib/utils",
|
|
26914
|
-
ui: "@workspace/ui/components"
|
|
27058
|
+
const configureNextJsApp = async (appName) => {
|
|
27059
|
+
const appPath = join(projectPath, `apps/${appName}`);
|
|
27060
|
+
if (!await directoryExists(appPath)) {
|
|
27061
|
+
return;
|
|
26915
27062
|
}
|
|
26916
|
-
|
|
26917
|
-
|
|
26918
|
-
|
|
26919
|
-
|
|
26920
|
-
|
|
26921
|
-
|
|
26922
|
-
|
|
26923
|
-
|
|
26924
|
-
|
|
26925
|
-
|
|
26926
|
-
|
|
26927
|
-
|
|
26928
|
-
platformPackageJson.dependencies[uiPackageName] = "workspace:*";
|
|
26929
|
-
await writeFile(platformPackageJsonPath, JSON.stringify(platformPackageJson, null, 2));
|
|
26930
|
-
}
|
|
26931
|
-
const updateAppTailwindConfig = async (appPath) => {
|
|
26932
|
-
const tailwindConfigPath = join(projectPath, appPath, "tailwind.config.ts");
|
|
26933
|
-
let tailwindConfig = "";
|
|
26934
|
-
try {
|
|
26935
|
-
tailwindConfig = await Bun.file(tailwindConfigPath).text();
|
|
26936
|
-
} catch {}
|
|
26937
|
-
const shadcnTheme = ` theme: {
|
|
26938
|
-
extend: {
|
|
26939
|
-
colors: {
|
|
26940
|
-
border: "hsl(var(--border))",
|
|
26941
|
-
input: "hsl(var(--input))",
|
|
26942
|
-
ring: "hsl(var(--ring))",
|
|
26943
|
-
background: "hsl(var(--background))",
|
|
26944
|
-
foreground: "hsl(var(--foreground))",
|
|
26945
|
-
primary: {
|
|
26946
|
-
DEFAULT: "hsl(var(--primary))",
|
|
26947
|
-
foreground: "hsl(var(--primary-foreground))",
|
|
26948
|
-
},
|
|
26949
|
-
secondary: {
|
|
26950
|
-
DEFAULT: "hsl(var(--secondary))",
|
|
26951
|
-
foreground: "hsl(var(--secondary-foreground))",
|
|
26952
|
-
},
|
|
26953
|
-
destructive: {
|
|
26954
|
-
DEFAULT: "hsl(var(--destructive))",
|
|
26955
|
-
foreground: "hsl(var(--destructive-foreground))",
|
|
26956
|
-
},
|
|
26957
|
-
muted: {
|
|
26958
|
-
DEFAULT: "hsl(var(--muted))",
|
|
26959
|
-
foreground: "hsl(var(--muted-foreground))",
|
|
26960
|
-
},
|
|
26961
|
-
accent: {
|
|
26962
|
-
DEFAULT: "hsl(var(--accent))",
|
|
26963
|
-
foreground: "hsl(var(--accent-foreground))",
|
|
26964
|
-
},
|
|
26965
|
-
popover: {
|
|
26966
|
-
DEFAULT: "hsl(var(--popover))",
|
|
26967
|
-
foreground: "hsl(var(--popover-foreground))",
|
|
26968
|
-
},
|
|
26969
|
-
card: {
|
|
26970
|
-
DEFAULT: "hsl(var(--card))",
|
|
26971
|
-
foreground: "hsl(var(--card-foreground))",
|
|
26972
|
-
},
|
|
26973
|
-
},
|
|
26974
|
-
borderRadius: {
|
|
26975
|
-
lg: "var(--radius)",
|
|
26976
|
-
md: "calc(var(--radius) - 2px)",
|
|
26977
|
-
sm: "calc(var(--radius) - 4px)",
|
|
27063
|
+
await ensureDirectory(join(appPath, "src/components"));
|
|
27064
|
+
await ensureDirectory(join(appPath, "src/lib"));
|
|
27065
|
+
const appComponentsJson = {
|
|
27066
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
27067
|
+
style,
|
|
27068
|
+
rsc: true,
|
|
27069
|
+
tsx: true,
|
|
27070
|
+
tailwind: {
|
|
27071
|
+
config: "",
|
|
27072
|
+
css: "../../packages/ui/src/styles/globals.css",
|
|
27073
|
+
baseColor,
|
|
27074
|
+
cssVariables: true
|
|
26978
27075
|
},
|
|
26979
|
-
|
|
26980
|
-
|
|
26981
|
-
|
|
26982
|
-
|
|
26983
|
-
|
|
26984
|
-
|
|
26985
|
-
|
|
26986
|
-
const updatedConfig = tailwindConfig.replace(/(\s*)(plugins:.*?)(\n\s*\};)/s, `$1$2$1${shadcnTheme}$3`);
|
|
26987
|
-
await writeFile(tailwindConfigPath, updatedConfig);
|
|
27076
|
+
iconLibrary: "lucide",
|
|
27077
|
+
aliases: {
|
|
27078
|
+
components: "@/components",
|
|
27079
|
+
hooks: "@/hooks",
|
|
27080
|
+
lib: "@/lib",
|
|
27081
|
+
utils: "@workspace/ui/lib/utils",
|
|
27082
|
+
ui: "@workspace/ui/components/ui"
|
|
26988
27083
|
}
|
|
26989
|
-
}
|
|
26990
|
-
|
|
26991
|
-
|
|
26992
|
-
const
|
|
26993
|
-
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
|
|
26994
|
-
theme: {
|
|
26995
|
-
extend: {
|
|
26996
|
-
colors: {
|
|
26997
|
-
border: "hsl(var(--border))",
|
|
26998
|
-
input: "hsl(var(--input))",
|
|
26999
|
-
ring: "hsl(var(--ring))",
|
|
27000
|
-
background: "hsl(var(--background))",
|
|
27001
|
-
foreground: "hsl(var(--foreground))",
|
|
27002
|
-
primary: {
|
|
27003
|
-
DEFAULT: "hsl(var(--primary))",
|
|
27004
|
-
foreground: "hsl(var(--primary-foreground))",
|
|
27005
|
-
},
|
|
27006
|
-
secondary: {
|
|
27007
|
-
DEFAULT: "hsl(var(--secondary))",
|
|
27008
|
-
foreground: "hsl(var(--secondary-foreground))",
|
|
27009
|
-
},
|
|
27010
|
-
destructive: {
|
|
27011
|
-
DEFAULT: "hsl(var(--destructive))",
|
|
27012
|
-
foreground: "hsl(var(--destructive-foreground))",
|
|
27013
|
-
},
|
|
27014
|
-
muted: {
|
|
27015
|
-
DEFAULT: "hsl(var(--muted))",
|
|
27016
|
-
foreground: "hsl(var(--muted-foreground))",
|
|
27017
|
-
},
|
|
27018
|
-
accent: {
|
|
27019
|
-
DEFAULT: "hsl(var(--accent))",
|
|
27020
|
-
foreground: "hsl(var(--accent-foreground))",
|
|
27021
|
-
},
|
|
27022
|
-
popover: {
|
|
27023
|
-
DEFAULT: "hsl(var(--popover))",
|
|
27024
|
-
foreground: "hsl(var(--popover-foreground))",
|
|
27025
|
-
},
|
|
27026
|
-
card: {
|
|
27027
|
-
DEFAULT: "hsl(var(--card))",
|
|
27028
|
-
foreground: "hsl(var(--card-foreground))",
|
|
27029
|
-
},
|
|
27030
|
-
},
|
|
27031
|
-
borderRadius: {
|
|
27032
|
-
lg: "var(--radius)",
|
|
27033
|
-
md: "calc(var(--radius) - 2px)",
|
|
27034
|
-
sm: "calc(var(--radius) - 4px)",
|
|
27035
|
-
},
|
|
27036
|
-
},
|
|
27037
|
-
},
|
|
27038
|
-
plugins: [],
|
|
27039
|
-
};
|
|
27040
|
-
|
|
27041
|
-
export default config;
|
|
27084
|
+
};
|
|
27085
|
+
await writeFile(join(appPath, "components.json"), JSON.stringify(appComponentsJson, null, 2));
|
|
27086
|
+
const globalsCssPath = join(appPath, "src/app/globals.css");
|
|
27087
|
+
const globalsCss = `@import "../../../packages/ui/src/styles/globals.css";
|
|
27042
27088
|
`;
|
|
27043
|
-
|
|
27089
|
+
await writeFile(globalsCssPath, globalsCss);
|
|
27090
|
+
const packageJsonPath = join(appPath, "package.json");
|
|
27091
|
+
let packageJson = {};
|
|
27092
|
+
try {
|
|
27093
|
+
packageJson = JSON.parse(await Bun.file(packageJsonPath).text());
|
|
27094
|
+
} catch {}
|
|
27095
|
+
if (packageJson.dependencies) {
|
|
27096
|
+
packageJson.dependencies[uiPackageName] = "workspace:*";
|
|
27097
|
+
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
27044
27098
|
}
|
|
27099
|
+
await createShadcnExample(appPath, true, packageName);
|
|
27045
27100
|
};
|
|
27046
|
-
await
|
|
27047
|
-
await
|
|
27101
|
+
await configureNextJsApp("web");
|
|
27102
|
+
await configureNextJsApp("platform");
|
|
27103
|
+
await configureNextJsApp("app");
|
|
27048
27104
|
const rootPackageJsonPath = join(projectPath, "package.json");
|
|
27049
27105
|
let rootPackageJson = {};
|
|
27050
27106
|
try {
|
|
27051
27107
|
rootPackageJson = JSON.parse(await Bun.file(rootPackageJsonPath).text());
|
|
27052
27108
|
} catch {}
|
|
27053
|
-
if (rootPackageJson.catalog) {
|
|
27054
|
-
rootPackageJson.catalog
|
|
27055
|
-
|
|
27056
|
-
|
|
27057
|
-
|
|
27058
|
-
|
|
27109
|
+
if (!rootPackageJson.catalog) {
|
|
27110
|
+
rootPackageJson.catalog = {};
|
|
27111
|
+
}
|
|
27112
|
+
const shadcnDependencies = {
|
|
27113
|
+
"@radix-ui/react-slot": "^1.2.3",
|
|
27114
|
+
"class-variance-authority": "^0.7.1",
|
|
27115
|
+
clsx: "^2.1.1",
|
|
27116
|
+
"tailwind-merge": "^3.3.1",
|
|
27117
|
+
"lucide-react": "^0.468.0",
|
|
27118
|
+
"@types/react": "^19.2.2",
|
|
27119
|
+
"@types/react-dom": "^19.2.2",
|
|
27120
|
+
typescript: "^5.9.3"
|
|
27121
|
+
};
|
|
27122
|
+
Object.assign(rootPackageJson.catalog, shadcnDependencies);
|
|
27123
|
+
await writeFile(rootPackageJsonPath, JSON.stringify(rootPackageJson, null, 2));
|
|
27059
27124
|
await createShadcnDocs(join(projectPath, "packages/ui"), true, context);
|
|
27060
27125
|
}
|
|
27061
27126
|
|
|
@@ -29926,6 +29991,7 @@ async function buildFullPreset(projectPath, context) {
|
|
|
29926
29991
|
await ensureDirectory(join(projectPath, "apps/api"));
|
|
29927
29992
|
await ensureDirectory(join(projectPath, "packages/types"));
|
|
29928
29993
|
await ensureDirectory(join(projectPath, "packages/utils"));
|
|
29994
|
+
await ensureDirectory(join(projectPath, "packages/ui"));
|
|
29929
29995
|
if (context.database && context.database !== "none") {
|
|
29930
29996
|
await ensureDirectory(join(projectPath, "packages/db"));
|
|
29931
29997
|
}
|
|
@@ -30000,7 +30066,8 @@ async function buildFullPreset(projectPath, context) {
|
|
|
30000
30066
|
react: "catalog:",
|
|
30001
30067
|
"react-dom": "catalog:",
|
|
30002
30068
|
next: "catalog:",
|
|
30003
|
-
[`@${context.packageName}/types`]: "workspace:*"
|
|
30069
|
+
[`@${context.packageName}/types`]: "workspace:*",
|
|
30070
|
+
[`@${context.packageName}/ui`]: "workspace:*"
|
|
30004
30071
|
},
|
|
30005
30072
|
devDependencies: {
|
|
30006
30073
|
"@types/react": "catalog:",
|
|
@@ -30027,7 +30094,8 @@ async function buildFullPreset(projectPath, context) {
|
|
|
30027
30094
|
react: "catalog:",
|
|
30028
30095
|
"react-dom": "catalog:",
|
|
30029
30096
|
next: "catalog:",
|
|
30030
|
-
[`@${context.packageName}/types`]: "workspace:*"
|
|
30097
|
+
[`@${context.packageName}/types`]: "workspace:*",
|
|
30098
|
+
[`@${context.packageName}/ui`]: "workspace:*"
|
|
30031
30099
|
},
|
|
30032
30100
|
devDependencies: {
|
|
30033
30101
|
"@types/react": "catalog:",
|
|
@@ -30825,8 +30893,15 @@ networks:
|
|
|
30825
30893
|
if (context.cicd) {
|
|
30826
30894
|
await setupGitHubActions(projectPath, context);
|
|
30827
30895
|
}
|
|
30828
|
-
if (context.
|
|
30829
|
-
|
|
30896
|
+
if (context.cssFramework === "tailwind" && (context.uiLibrary === "shadcn" || context.uiLibrary === undefined)) {
|
|
30897
|
+
const fullContext = {
|
|
30898
|
+
...context,
|
|
30899
|
+
uiLibrary: "shadcn",
|
|
30900
|
+
shadcnStyle: context.shadcnStyle || "new-york",
|
|
30901
|
+
shadcnBaseColor: context.shadcnBaseColor || "zinc",
|
|
30902
|
+
shadcnRadius: context.shadcnRadius || "0.625rem"
|
|
30903
|
+
};
|
|
30904
|
+
await setupShadcnMonorepo(projectPath, fullContext);
|
|
30830
30905
|
}
|
|
30831
30906
|
await setupTooling(projectPath, context);
|
|
30832
30907
|
await setupVSCodeDebug(projectPath, context, "full");
|
|
@@ -31422,14 +31497,14 @@ async function buildEnterprisePreset(projectPath, context) {
|
|
|
31422
31497
|
version: "0.0.0",
|
|
31423
31498
|
private: true,
|
|
31424
31499
|
scripts: {
|
|
31425
|
-
dev: "next dev -p 3000",
|
|
31500
|
+
dev: "next dev -p ${PORT:-3000}",
|
|
31426
31501
|
build: "next build",
|
|
31427
|
-
start: "next start -p 3000",
|
|
31502
|
+
start: "next start -p ${PORT:-3000}",
|
|
31428
31503
|
lint: "biome check .",
|
|
31429
31504
|
format: "biome check --write .",
|
|
31430
|
-
debug: "bun --inspect node_modules/.bin/next dev -p 3000",
|
|
31431
|
-
"debug:brk": "bun --inspect-brk node_modules/.bin/next dev -p 3000",
|
|
31432
|
-
"debug:wait": "bun --inspect-wait node_modules/.bin/next dev -p 3000"
|
|
31505
|
+
debug: "bun --inspect node_modules/.bin/next dev -p ${PORT:-3000}",
|
|
31506
|
+
"debug:brk": "bun --inspect-brk node_modules/.bin/next dev -p ${PORT:-3000}",
|
|
31507
|
+
"debug:wait": "bun --inspect-wait node_modules/.bin/next dev -p ${PORT:-3000}"
|
|
31433
31508
|
},
|
|
31434
31509
|
dependencies: {
|
|
31435
31510
|
react: "catalog:",
|
|
@@ -31453,14 +31528,14 @@ async function buildEnterprisePreset(projectPath, context) {
|
|
|
31453
31528
|
version: "0.0.0",
|
|
31454
31529
|
private: true,
|
|
31455
31530
|
scripts: {
|
|
31456
|
-
dev: "next dev -p 3001",
|
|
31531
|
+
dev: "next dev -p ${PORT:-3001}",
|
|
31457
31532
|
build: "next build",
|
|
31458
|
-
start: "next start -p 3001",
|
|
31533
|
+
start: "next start -p ${PORT:-3001}",
|
|
31459
31534
|
lint: "biome check .",
|
|
31460
31535
|
format: "biome check --write .",
|
|
31461
|
-
debug: "bun --inspect node_modules/.bin/next dev -p 3001",
|
|
31462
|
-
"debug:brk": "bun --inspect-brk node_modules/.bin/next dev -p 3001",
|
|
31463
|
-
"debug:wait": "bun --inspect-wait node_modules/.bin/next dev -p 3001"
|
|
31536
|
+
debug: "bun --inspect node_modules/.bin/next dev -p ${PORT:-3001}",
|
|
31537
|
+
"debug:brk": "bun --inspect-brk node_modules/.bin/next dev -p ${PORT:-3001}",
|
|
31538
|
+
"debug:wait": "bun --inspect-wait node_modules/.bin/next dev -p ${PORT:-3001}"
|
|
31464
31539
|
},
|
|
31465
31540
|
dependencies: {
|
|
31466
31541
|
react: "catalog:",
|
|
@@ -31485,14 +31560,14 @@ async function buildEnterprisePreset(projectPath, context) {
|
|
|
31485
31560
|
version: "0.0.0",
|
|
31486
31561
|
private: true,
|
|
31487
31562
|
scripts: {
|
|
31488
|
-
dev: "next dev -p 3002",
|
|
31563
|
+
dev: "next dev -p ${PORT:-3002}",
|
|
31489
31564
|
build: "next build",
|
|
31490
|
-
start: "next start -p 3002",
|
|
31565
|
+
start: "next start -p ${PORT:-3002}",
|
|
31491
31566
|
lint: "biome check .",
|
|
31492
31567
|
format: "biome check --write .",
|
|
31493
|
-
debug: "bun --inspect node_modules/.bin/next dev -p 3002",
|
|
31494
|
-
"debug:brk": "bun --inspect-brk node_modules/.bin/next dev -p 3002",
|
|
31495
|
-
"debug:wait": "bun --inspect-wait node_modules/.bin/next dev -p 3002"
|
|
31568
|
+
debug: "bun --inspect node_modules/.bin/next dev -p ${PORT:-3002}",
|
|
31569
|
+
"debug:brk": "bun --inspect-brk node_modules/.bin/next dev -p ${PORT:-3002}",
|
|
31570
|
+
"debug:wait": "bun --inspect-wait node_modules/.bin/next dev -p ${PORT:-3002}"
|
|
31496
31571
|
},
|
|
31497
31572
|
dependencies: {
|
|
31498
31573
|
react: "catalog:",
|
|
@@ -31566,11 +31641,63 @@ async function buildEnterprisePreset(projectPath, context) {
|
|
|
31566
31641
|
if (context.cicd) {
|
|
31567
31642
|
await setupGitHubActions(projectPath, context);
|
|
31568
31643
|
}
|
|
31569
|
-
if (context.uiLibrary === "shadcn") {
|
|
31570
|
-
|
|
31644
|
+
if (context.cssFramework === "tailwind" && (context.uiLibrary === "shadcn" || context.uiLibrary === undefined)) {
|
|
31645
|
+
const enterpriseContext = {
|
|
31646
|
+
...context,
|
|
31647
|
+
uiLibrary: "shadcn",
|
|
31648
|
+
shadcnStyle: context.shadcnStyle || "new-york",
|
|
31649
|
+
shadcnBaseColor: context.shadcnBaseColor || "zinc",
|
|
31650
|
+
shadcnRadius: context.shadcnRadius || "0.625rem"
|
|
31651
|
+
};
|
|
31652
|
+
await setupShadcnMonorepo(projectPath, enterpriseContext);
|
|
31571
31653
|
}
|
|
31572
31654
|
await setupTooling(projectPath, context);
|
|
31573
31655
|
await setupVSCodeDebug(projectPath, context);
|
|
31656
|
+
const typesPackageJson = {
|
|
31657
|
+
name: `@${context.packageName}/types`,
|
|
31658
|
+
version: "0.0.0",
|
|
31659
|
+
private: true,
|
|
31660
|
+
main: "./src/index.ts",
|
|
31661
|
+
types: "./src/index.ts"
|
|
31662
|
+
};
|
|
31663
|
+
await writeFile(join(projectPath, "packages/types/package.json"), JSON.stringify(typesPackageJson, null, 2));
|
|
31664
|
+
const typesContent = `// Shared types for ${context.projectName}
|
|
31665
|
+
|
|
31666
|
+
export interface User {
|
|
31667
|
+
id: string;
|
|
31668
|
+
email: string;
|
|
31669
|
+
name?: string;
|
|
31670
|
+
createdAt: Date;
|
|
31671
|
+
}
|
|
31672
|
+
|
|
31673
|
+
export interface ApiResponse<T = unknown> {
|
|
31674
|
+
data?: T;
|
|
31675
|
+
error?: string;
|
|
31676
|
+
message?: string;
|
|
31677
|
+
}
|
|
31678
|
+
`;
|
|
31679
|
+
await ensureDirectory(join(projectPath, "packages/types/src"));
|
|
31680
|
+
await writeFile(join(projectPath, "packages/types/src/index.ts"), typesContent);
|
|
31681
|
+
const utilsPackageJson = {
|
|
31682
|
+
name: `@${context.packageName}/utils`,
|
|
31683
|
+
version: "0.0.0",
|
|
31684
|
+
private: true,
|
|
31685
|
+
main: "./src/index.ts",
|
|
31686
|
+
types: "./src/index.ts"
|
|
31687
|
+
};
|
|
31688
|
+
await writeFile(join(projectPath, "packages/utils/package.json"), JSON.stringify(utilsPackageJson, null, 2));
|
|
31689
|
+
const utilsContent = `// Shared utilities for ${context.projectName}
|
|
31690
|
+
|
|
31691
|
+
export function formatDate(date: Date): string {
|
|
31692
|
+
return date.toISOString();
|
|
31693
|
+
}
|
|
31694
|
+
|
|
31695
|
+
export function capitalize(str: string): string {
|
|
31696
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
31697
|
+
}
|
|
31698
|
+
`;
|
|
31699
|
+
await ensureDirectory(join(projectPath, "packages/utils/src"));
|
|
31700
|
+
await writeFile(join(projectPath, "packages/utils/src/index.ts"), utilsContent);
|
|
31574
31701
|
await ensureDirectory(join(projectPath, "apps/service-identity/src/routes"));
|
|
31575
31702
|
await ensureDirectory(join(projectPath, "apps/service-identity/src/middleware"));
|
|
31576
31703
|
const serviceIdentityIndex = `import { Hono } from 'hono';
|
|
@@ -31701,10 +31828,14 @@ bun install
|
|
|
31701
31828
|
bun dev
|
|
31702
31829
|
|
|
31703
31830
|
# Start individual apps
|
|
31704
|
-
bun run dev:web # Start marketing site
|
|
31705
|
-
bun run dev:app # Start main product app
|
|
31706
|
-
bun run dev:platform # Start admin dashboard
|
|
31707
|
-
bun run dev:identity # Start identity service
|
|
31831
|
+
bun run dev:web # Start marketing site (port 3000)
|
|
31832
|
+
bun run dev:app # Start main product app (port 3002)
|
|
31833
|
+
bun run dev:platform # Start admin dashboard (port 3001)
|
|
31834
|
+
bun run dev:identity # Start identity service (port 3003)
|
|
31835
|
+
|
|
31836
|
+
# Use custom ports if defaults are in use
|
|
31837
|
+
PORT=3004 bun run dev:app # Run app on port 3004
|
|
31838
|
+
PORT=3005 bun run dev:web # Run web on port 3005
|
|
31708
31839
|
|
|
31709
31840
|
# Build all apps
|
|
31710
31841
|
bun build
|
|
@@ -31714,6 +31845,26 @@ bun lint
|
|
|
31714
31845
|
bun format
|
|
31715
31846
|
\`\`\`
|
|
31716
31847
|
|
|
31848
|
+
### Port Configuration
|
|
31849
|
+
|
|
31850
|
+
All apps support the \`PORT\` environment variable to override the default port:
|
|
31851
|
+
|
|
31852
|
+
- **apps/web**: Default port 3000
|
|
31853
|
+
- **apps/platform**: Default port 3001
|
|
31854
|
+
- **apps/app**: Default port 3002
|
|
31855
|
+
- **apps/service-identity**: Default port 3003
|
|
31856
|
+
|
|
31857
|
+
If a port is already in use, you can easily change it:
|
|
31858
|
+
|
|
31859
|
+
\`\`\`bash
|
|
31860
|
+
# Example: Run app on a different port
|
|
31861
|
+
PORT=4000 cd apps/app && bun dev
|
|
31862
|
+
|
|
31863
|
+
# Or set it globally for the session
|
|
31864
|
+
export PORT=4000
|
|
31865
|
+
cd apps/app && bun dev
|
|
31866
|
+
\`\`\`
|
|
31867
|
+
|
|
31717
31868
|
## Adding More Services
|
|
31718
31869
|
|
|
31719
31870
|
You can easily add more services using bunkit:
|
|
@@ -32720,6 +32871,69 @@ async function createCommand2(preset, name, options) {
|
|
|
32720
32871
|
}
|
|
32721
32872
|
console.log("");
|
|
32722
32873
|
const s = Y2();
|
|
32874
|
+
const isEnterprise = normalizedPreset === "enterprise-monorepo";
|
|
32875
|
+
let shadcnStyle = "new-york";
|
|
32876
|
+
let shadcnBaseColor = "zinc";
|
|
32877
|
+
let shadcnRadius = "0.625rem";
|
|
32878
|
+
if (isEnterprise) {
|
|
32879
|
+
Me(`Default theme: ${source_default.cyan("New York")} style, ${source_default.cyan("Zinc")} color, ${source_default.cyan("0.625rem")} radius`, "shadcn/ui defaults");
|
|
32880
|
+
const customize = await ye({
|
|
32881
|
+
message: `\uD83C\uDFA8 Customize shadcn/ui theme?`,
|
|
32882
|
+
initialValue: false
|
|
32883
|
+
});
|
|
32884
|
+
if (pD(customize)) {
|
|
32885
|
+
xe("Operation cancelled.");
|
|
32886
|
+
process.exit(0);
|
|
32887
|
+
}
|
|
32888
|
+
if (customize) {
|
|
32889
|
+
const styleChoice = await ve({
|
|
32890
|
+
message: "\uD83C\uDFA8 Component style",
|
|
32891
|
+
options: [
|
|
32892
|
+
{ value: "new-york", label: "New York (Recommended)", hint: "Modern, rounded, subtle shadows" },
|
|
32893
|
+
{ value: "default", label: "Default", hint: "Classic, sharper edges, higher contrast" }
|
|
32894
|
+
],
|
|
32895
|
+
initialValue: "new-york"
|
|
32896
|
+
});
|
|
32897
|
+
if (pD(styleChoice)) {
|
|
32898
|
+
xe("Operation cancelled.");
|
|
32899
|
+
process.exit(0);
|
|
32900
|
+
}
|
|
32901
|
+
shadcnStyle = styleChoice;
|
|
32902
|
+
const colorChoice = await ve({
|
|
32903
|
+
message: "\uD83C\uDFA8 Base color theme",
|
|
32904
|
+
options: [
|
|
32905
|
+
{ value: "zinc", label: "Zinc (Recommended)", hint: "Neutral gray - versatile, modern" },
|
|
32906
|
+
{ value: "neutral", label: "Neutral", hint: "Pure neutral - no color cast" },
|
|
32907
|
+
{ value: "gray", label: "Gray", hint: "Warm gray palette" },
|
|
32908
|
+
{ value: "slate", label: "Slate", hint: "Cool gray - bluer tone" },
|
|
32909
|
+
{ value: "stone", label: "Stone", hint: "Warm beige-gray - earthy feel" }
|
|
32910
|
+
],
|
|
32911
|
+
initialValue: "zinc"
|
|
32912
|
+
});
|
|
32913
|
+
if (pD(colorChoice)) {
|
|
32914
|
+
xe("Operation cancelled.");
|
|
32915
|
+
process.exit(0);
|
|
32916
|
+
}
|
|
32917
|
+
shadcnBaseColor = colorChoice;
|
|
32918
|
+
const radiusInput = await he({
|
|
32919
|
+
message: "\uD83D\uDCD0 Border radius",
|
|
32920
|
+
placeholder: "0.625rem",
|
|
32921
|
+
initialValue: "0.625rem",
|
|
32922
|
+
validate: (value) => {
|
|
32923
|
+
if (!value.trim())
|
|
32924
|
+
return "Radius cannot be empty";
|
|
32925
|
+
if (!/^\d+(\.\d+)?(rem|px|em|%)$/.test(value.trim())) {
|
|
32926
|
+
return "Please enter a valid CSS value (e.g., 0.5rem, 8px)";
|
|
32927
|
+
}
|
|
32928
|
+
}
|
|
32929
|
+
});
|
|
32930
|
+
if (pD(radiusInput)) {
|
|
32931
|
+
xe("Operation cancelled.");
|
|
32932
|
+
process.exit(0);
|
|
32933
|
+
}
|
|
32934
|
+
shadcnRadius = radiusInput;
|
|
32935
|
+
}
|
|
32936
|
+
}
|
|
32723
32937
|
s.start(`${source_default.cyan("\uD83D\uDD28")} Creating ${preset} project: ${source_default.bold(name)}`);
|
|
32724
32938
|
try {
|
|
32725
32939
|
const config = {
|
|
@@ -32731,13 +32945,18 @@ async function createCommand2(preset, name, options) {
|
|
|
32731
32945
|
database: "none",
|
|
32732
32946
|
redis: false,
|
|
32733
32947
|
useBunSecrets: false,
|
|
32734
|
-
codeQuality: "ultracite",
|
|
32948
|
+
codeQuality: isEnterprise ? "biome" : "ultracite",
|
|
32735
32949
|
tsStrictness: "strict",
|
|
32736
32950
|
testing: "bun-test",
|
|
32737
32951
|
docker: false,
|
|
32738
32952
|
cicd: false,
|
|
32739
32953
|
envExample: true,
|
|
32740
|
-
pathAliases: true
|
|
32954
|
+
pathAliases: true,
|
|
32955
|
+
cssFramework: isEnterprise ? "tailwind" : undefined,
|
|
32956
|
+
uiLibrary: isEnterprise ? "shadcn" : undefined,
|
|
32957
|
+
shadcnStyle: isEnterprise ? shadcnStyle : undefined,
|
|
32958
|
+
shadcnBaseColor: isEnterprise ? shadcnBaseColor : undefined,
|
|
32959
|
+
shadcnRadius: isEnterprise ? shadcnRadius : undefined
|
|
32741
32960
|
};
|
|
32742
32961
|
s.message(`${source_default.cyan("\uD83D\uDCC1")} Creating project structure...`);
|
|
32743
32962
|
await createProject(config);
|
|
@@ -32771,6 +32990,26 @@ async function createCommand2(preset, name, options) {
|
|
|
32771
32990
|
break;
|
|
32772
32991
|
}
|
|
32773
32992
|
s.message(`${source_default.cyan("\u2728")} Finalizing setup...`);
|
|
32993
|
+
if (config.install !== false) {
|
|
32994
|
+
s.message(`${source_default.cyan("\uD83D\uDCE6")} Installing dependencies...`);
|
|
32995
|
+
try {
|
|
32996
|
+
await installDependencies(projectPath);
|
|
32997
|
+
} catch (error) {
|
|
32998
|
+
s.message(`${source_default.yellow("\u26A0\uFE0F")} Dependency installation had issues, but continuing...`);
|
|
32999
|
+
}
|
|
33000
|
+
}
|
|
33001
|
+
if (isEnterprise && config.uiLibrary === "shadcn" && config.install !== false) {
|
|
33002
|
+
s.message(`${source_default.cyan("\uD83E\uDDE9")} Installing default shadcn/ui components...`);
|
|
33003
|
+
try {
|
|
33004
|
+
await installDefaultShadcnComponents(projectPath, {
|
|
33005
|
+
silent: false,
|
|
33006
|
+
skipDefaults: false
|
|
33007
|
+
});
|
|
33008
|
+
} catch (error) {
|
|
33009
|
+
s.message(`${source_default.yellow("\u26A0\uFE0F")} Could not install default components automatically`);
|
|
33010
|
+
s.message(`${source_default.dim(" You can install them manually:")} ${source_default.cyan("cd packages/ui && bun install && bunx shadcn@latest add button card")}`);
|
|
33011
|
+
}
|
|
33012
|
+
}
|
|
32774
33013
|
s.stop(`${source_default.green("\u2705")} Project ${source_default.bold(name)} created successfully!`);
|
|
32775
33014
|
const getPresetEmoji = () => {
|
|
32776
33015
|
switch (normalizedPreset) {
|
|
@@ -33268,6 +33507,20 @@ ${import_picocolors5.default.bold("Package info:")}
|
|
|
33268
33507
|
// src/commands/add/component.ts
|
|
33269
33508
|
init_dist();
|
|
33270
33509
|
import { existsSync } from "fs";
|
|
33510
|
+
async function getPackageName(cwd2) {
|
|
33511
|
+
try {
|
|
33512
|
+
const packageJsonPath = join(cwd2, "package.json");
|
|
33513
|
+
if (existsSync(packageJsonPath)) {
|
|
33514
|
+
const packageJson = JSON.parse(await Bun.file(packageJsonPath).text());
|
|
33515
|
+
const name = packageJson.name;
|
|
33516
|
+
if (name && name.endsWith("-monorepo")) {
|
|
33517
|
+
return name.replace("-monorepo", "");
|
|
33518
|
+
}
|
|
33519
|
+
return name || null;
|
|
33520
|
+
}
|
|
33521
|
+
} catch {}
|
|
33522
|
+
return null;
|
|
33523
|
+
}
|
|
33271
33524
|
async function addComponentCommand(options = {}) {
|
|
33272
33525
|
const cwd2 = options.cwd || process.cwd();
|
|
33273
33526
|
const spinner = Y2();
|
|
@@ -33279,6 +33532,12 @@ async function addComponentCommand(options = {}) {
|
|
|
33279
33532
|
process.exit(1);
|
|
33280
33533
|
}
|
|
33281
33534
|
const targetPath = isMonorepo ? join(cwd2, "packages/ui") : cwd2;
|
|
33535
|
+
const targetComponentsJson = join(targetPath, "components.json");
|
|
33536
|
+
if (!existsSync(targetComponentsJson)) {
|
|
33537
|
+
M2.error(`shadcn/ui is not configured in ${isMonorepo ? "packages/ui" : "this project"}.`);
|
|
33538
|
+
M2.info("Run `bunkit init` with --ui-library shadcn to set up shadcn/ui first.");
|
|
33539
|
+
process.exit(1);
|
|
33540
|
+
}
|
|
33282
33541
|
let components = [];
|
|
33283
33542
|
if (options.all) {
|
|
33284
33543
|
const popularComponents = [
|
|
@@ -33364,12 +33623,16 @@ async function addComponentCommand(options = {}) {
|
|
|
33364
33623
|
try {
|
|
33365
33624
|
await installShadcnComponents(targetPath, components, {
|
|
33366
33625
|
silent: false,
|
|
33367
|
-
cwd:
|
|
33626
|
+
cwd: cwd2,
|
|
33627
|
+
isMonorepo
|
|
33368
33628
|
});
|
|
33369
33629
|
spinner.stop(`\u2705 Installed: ${components.join(", ")}`);
|
|
33370
33630
|
if (isMonorepo) {
|
|
33631
|
+
const packageName = await getPackageName(cwd2);
|
|
33371
33632
|
Me(`Components installed in packages/ui. Import them using:
|
|
33372
|
-
import { Button } from "@workspace/ui/components/ui/button"
|
|
33633
|
+
` + `import { Button } from "@workspace/ui/components/ui/button"
|
|
33634
|
+
` + `// Or using workspace alias:
|
|
33635
|
+
` + `import { Button } from "${packageName ? `@${packageName}/ui` : "@workspace/ui"}/components/ui/button"`, "Usage");
|
|
33373
33636
|
} else {
|
|
33374
33637
|
Me(`Import components using:
|
|
33375
33638
|
import { Button } from "@/components/ui/button"`, "Usage");
|