bunkit-cli 0.6.1 → 0.8.0
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/README.md +61 -3
- package/dist/index.js +2177 -160
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3773,22 +3773,23 @@ var quotes, getRandomQuote = () => {
|
|
|
3773
3773
|
`, createBanner = (version = "0.3.1") => {
|
|
3774
3774
|
const quote = getRandomQuote();
|
|
3775
3775
|
const content = [
|
|
3776
|
-
source_default.
|
|
3776
|
+
source_default.yellowBright(logo.trim()),
|
|
3777
3777
|
"",
|
|
3778
|
-
source_default.cyan("\uD83C\uDF5E Bake production-ready apps in seconds"),
|
|
3779
|
-
source_default.dim("Modern \u2022 Fast \u2022 Opinionated"),
|
|
3778
|
+
source_default.bold.cyan("\uD83C\uDF5E Bake production-ready apps in seconds"),
|
|
3779
|
+
source_default.dim("Modern \u2022 Fast \u2022 Opinionated \u2022 Type-Safe"),
|
|
3780
3780
|
"",
|
|
3781
|
-
source_default.cyan(quote),
|
|
3781
|
+
source_default.italic.cyan(quote),
|
|
3782
3782
|
"",
|
|
3783
|
-
source_default.dim(`
|
|
3783
|
+
source_default.dim(`Version ${version}`)
|
|
3784
3784
|
].join(`
|
|
3785
3785
|
`);
|
|
3786
3786
|
return boxen(content, {
|
|
3787
|
-
padding: 1,
|
|
3787
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
3788
3788
|
margin: { top: 1, bottom: 1 },
|
|
3789
|
-
borderColor: "
|
|
3789
|
+
borderColor: "cyan",
|
|
3790
3790
|
borderStyle: "round",
|
|
3791
|
-
|
|
3791
|
+
title: "bunkit",
|
|
3792
|
+
titleAlignment: "center"
|
|
3792
3793
|
});
|
|
3793
3794
|
}, showBanner = (version) => {
|
|
3794
3795
|
console.log(createBanner(version));
|
|
@@ -22651,11 +22652,17 @@ var init_types2 = __esm(() => {
|
|
|
22651
22652
|
features: exports_external.array(exports_external.string()).optional(),
|
|
22652
22653
|
git: exports_external.boolean().default(true),
|
|
22653
22654
|
install: exports_external.boolean().default(true),
|
|
22654
|
-
database: exports_external.enum(["postgres-drizzle", "supabase", "sqlite-drizzle", "none"]).optional(),
|
|
22655
|
+
database: exports_external.enum(["postgres-drizzle", "supabase", "supabase-drizzle", "sqlite-drizzle", "none"]).optional(),
|
|
22656
|
+
supabasePreset: exports_external.enum(["full-stack", "auth-only", "database-only", "custom"]).optional(),
|
|
22657
|
+
supabaseFeatures: exports_external.array(exports_external.enum(["auth", "storage", "realtime", "edge-functions", "database"])).optional(),
|
|
22658
|
+
supabaseWithDrizzle: exports_external.boolean().optional(),
|
|
22655
22659
|
codeQuality: exports_external.enum(["ultracite", "biome"]).default("ultracite"),
|
|
22656
22660
|
tsStrictness: exports_external.enum(["strict", "moderate", "loose"]).default("strict"),
|
|
22657
22661
|
uiLibrary: exports_external.enum(["shadcn", "none"]).optional(),
|
|
22658
22662
|
cssFramework: exports_external.enum(["tailwind", "vanilla", "css-modules"]).optional(),
|
|
22663
|
+
shadcnStyle: exports_external.enum(["new-york", "default"]).optional(),
|
|
22664
|
+
shadcnBaseColor: exports_external.enum(["neutral", "gray", "zinc", "stone", "slate"]).optional(),
|
|
22665
|
+
shadcnRadius: exports_external.string().optional(),
|
|
22659
22666
|
testing: exports_external.enum(["bun-test", "vitest", "none"]).default("bun-test"),
|
|
22660
22667
|
docker: exports_external.boolean().default(false),
|
|
22661
22668
|
cicd: exports_external.boolean().default(false),
|
|
@@ -22807,7 +22814,13 @@ function createTemplateContext(config) {
|
|
|
22807
22814
|
docker: config.docker,
|
|
22808
22815
|
cicd: config.cicd,
|
|
22809
22816
|
envExample: config.envExample,
|
|
22810
|
-
pathAliases: config.pathAliases
|
|
22817
|
+
pathAliases: config.pathAliases,
|
|
22818
|
+
shadcnStyle: config.shadcnStyle,
|
|
22819
|
+
shadcnBaseColor: config.shadcnBaseColor,
|
|
22820
|
+
shadcnRadius: config.shadcnRadius,
|
|
22821
|
+
supabasePreset: config.supabasePreset,
|
|
22822
|
+
supabaseFeatures: config.supabaseFeatures,
|
|
22823
|
+
supabaseWithDrizzle: config.supabaseWithDrizzle
|
|
22811
22824
|
};
|
|
22812
22825
|
}
|
|
22813
22826
|
var import_fs_extra2;
|
|
@@ -24182,6 +24195,41 @@ class dD extends x {
|
|
|
24182
24195
|
}
|
|
24183
24196
|
var A;
|
|
24184
24197
|
A = new WeakMap;
|
|
24198
|
+
var kD = Object.defineProperty;
|
|
24199
|
+
var $D = (e, u, t) => (u in e) ? kD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
24200
|
+
var H = (e, u, t) => ($D(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
24201
|
+
var SD = class extends x {
|
|
24202
|
+
constructor(u) {
|
|
24203
|
+
super(u, false), H(this, "options"), H(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: t }) => t === u.cursorAt), 0), this.on("key", (t) => {
|
|
24204
|
+
t === "a" && this.toggleAll();
|
|
24205
|
+
}), this.on("cursor", (t) => {
|
|
24206
|
+
switch (t) {
|
|
24207
|
+
case "left":
|
|
24208
|
+
case "up":
|
|
24209
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
24210
|
+
break;
|
|
24211
|
+
case "down":
|
|
24212
|
+
case "right":
|
|
24213
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
24214
|
+
break;
|
|
24215
|
+
case "space":
|
|
24216
|
+
this.toggleValue();
|
|
24217
|
+
break;
|
|
24218
|
+
}
|
|
24219
|
+
});
|
|
24220
|
+
}
|
|
24221
|
+
get _value() {
|
|
24222
|
+
return this.options[this.cursor].value;
|
|
24223
|
+
}
|
|
24224
|
+
toggleAll() {
|
|
24225
|
+
const u = this.value.length === this.options.length;
|
|
24226
|
+
this.value = u ? [] : this.options.map((t) => t.value);
|
|
24227
|
+
}
|
|
24228
|
+
toggleValue() {
|
|
24229
|
+
const u = this.value.includes(this._value);
|
|
24230
|
+
this.value = u ? this.value.filter((t) => t !== this._value) : [...this.value, this._value];
|
|
24231
|
+
}
|
|
24232
|
+
};
|
|
24185
24233
|
var OD = Object.defineProperty;
|
|
24186
24234
|
var PD = (e, u, t) => (u in e) ? OD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
24187
24235
|
var J = (e, u, t) => (PD(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
@@ -24353,6 +24401,47 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
24353
24401
|
}
|
|
24354
24402
|
} }).prompt();
|
|
24355
24403
|
};
|
|
24404
|
+
var fe = (t) => {
|
|
24405
|
+
const n = (r2, i) => {
|
|
24406
|
+
const s = r2.label ?? String(r2.value);
|
|
24407
|
+
return i === "active" ? `${import_picocolors2.default.cyan(A2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(T)} ${import_picocolors2.default.dim(s)} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : i === "active-selected" ? `${import_picocolors2.default.green(T)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(F)} ${import_picocolors2.default.dim(s)}`;
|
|
24408
|
+
};
|
|
24409
|
+
return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r2) {
|
|
24410
|
+
if (this.required && r2.length === 0)
|
|
24411
|
+
return `Please select at least one option.
|
|
24412
|
+
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
24413
|
+
}, render() {
|
|
24414
|
+
const r2 = `${import_picocolors2.default.gray(o)}
|
|
24415
|
+
${b2(this.state)} ${t.message}
|
|
24416
|
+
`, i = (s, c) => {
|
|
24417
|
+
const a = this.value.includes(s.value);
|
|
24418
|
+
return c && a ? n(s, "active-selected") : a ? n(s, "selected") : n(s, c ? "active" : "inactive");
|
|
24419
|
+
};
|
|
24420
|
+
switch (this.state) {
|
|
24421
|
+
case "submit":
|
|
24422
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
|
|
24423
|
+
case "cancel": {
|
|
24424
|
+
const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
24425
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
|
|
24426
|
+
${import_picocolors2.default.gray(o)}` : ""}`;
|
|
24427
|
+
}
|
|
24428
|
+
case "error": {
|
|
24429
|
+
const s = this.error.split(`
|
|
24430
|
+
`).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
|
|
24431
|
+
`);
|
|
24432
|
+
return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
24433
|
+
${import_picocolors2.default.yellow(o)} `)}
|
|
24434
|
+
${s}
|
|
24435
|
+
`;
|
|
24436
|
+
}
|
|
24437
|
+
default:
|
|
24438
|
+
return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
24439
|
+
${import_picocolors2.default.cyan(o)} `)}
|
|
24440
|
+
${import_picocolors2.default.cyan(d2)}
|
|
24441
|
+
`;
|
|
24442
|
+
}
|
|
24443
|
+
} }).prompt();
|
|
24444
|
+
};
|
|
24356
24445
|
var Me = (t = "", n = "") => {
|
|
24357
24446
|
const r2 = `
|
|
24358
24447
|
${t}
|
|
@@ -24424,7 +24513,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
24424
24513
|
}, R2 = (m2) => m2.replace(/\.+$/, ""), O2 = (m2) => {
|
|
24425
24514
|
const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
24426
24515
|
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
24427
|
-
},
|
|
24516
|
+
}, H2 = (m2 = "") => {
|
|
24428
24517
|
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
24429
24518
|
`);
|
|
24430
24519
|
let h2 = 0, w2 = 0;
|
|
@@ -24450,21 +24539,20 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
24450
24539
|
`) : process.stdout.write(`${w2} ${l2}
|
|
24451
24540
|
`), E(), s();
|
|
24452
24541
|
};
|
|
24453
|
-
return { start:
|
|
24542
|
+
return { start: H2, stop: N2, message: (m2 = "") => {
|
|
24454
24543
|
l2 = R2(m2 ?? l2);
|
|
24455
24544
|
} };
|
|
24456
24545
|
};
|
|
24457
24546
|
|
|
24458
24547
|
// src/index.ts
|
|
24459
24548
|
init_src();
|
|
24460
|
-
var
|
|
24549
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
24461
24550
|
|
|
24462
24551
|
// src/commands/init.enhanced.ts
|
|
24463
24552
|
init_boxen();
|
|
24464
24553
|
init_source();
|
|
24465
24554
|
init_dist();
|
|
24466
24555
|
init_src();
|
|
24467
|
-
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
24468
24556
|
|
|
24469
24557
|
// ../templates/src/render.ts
|
|
24470
24558
|
var import_ejs = __toESM(require_ejs(), 1);
|
|
@@ -24827,12 +24915,12 @@ services:
|
|
|
24827
24915
|
- "3000:3000"
|
|
24828
24916
|
environment:
|
|
24829
24917
|
- NODE_ENV=production
|
|
24830
|
-
${context.database && context.database !== "none" && context.database !== "supabase" ? "- DATABASE_URL=${DATABASE_URL:-postgres://postgres:postgres@db:5432/${context.projectName}}" : ""}
|
|
24831
|
-
${context.database && context.database !== "none" && context.database !== "supabase" ? `depends_on:
|
|
24918
|
+
${context.database && context.database !== "none" && context.database !== "supabase" && context.database !== "supabase-drizzle" ? "- DATABASE_URL=${DATABASE_URL:-postgres://postgres:postgres@db:5432/${context.projectName}}" : ""}
|
|
24919
|
+
${context.database && context.database !== "none" && context.database !== "supabase" && context.database !== "supabase-drizzle" ? `depends_on:
|
|
24832
24920
|
- db` : ""}
|
|
24833
24921
|
restart: unless-stopped
|
|
24834
24922
|
|
|
24835
|
-
${context.database && context.database !== "none" && context.database !== "supabase" ? `db:
|
|
24923
|
+
${context.database && context.database !== "none" && context.database !== "supabase" && context.database !== "supabase-drizzle" ? `db:
|
|
24836
24924
|
image: ${context.database === "sqlite-drizzle" ? "alpine:latest" : "postgres:16-alpine"}
|
|
24837
24925
|
${context.database !== "sqlite-drizzle" ? `environment:
|
|
24838
24926
|
- POSTGRES_USER=postgres
|
|
@@ -24987,7 +25075,7 @@ jobs:
|
|
|
24987
25075
|
${context.preset === "web" || context.preset === "full" ? `- name: Build application
|
|
24988
25076
|
run: bun run build
|
|
24989
25077
|
env:
|
|
24990
|
-
${context.database === "supabase" ? `NEXT_PUBLIC_SUPABASE_URL: \${{ secrets.SUPABASE_URL }}
|
|
25078
|
+
${context.database === "supabase" || context.database === "supabase-drizzle" ? `NEXT_PUBLIC_SUPABASE_URL: \${{ secrets.SUPABASE_URL }}
|
|
24991
25079
|
NEXT_PUBLIC_SUPABASE_ANON_KEY: \${{ secrets.SUPABASE_ANON_KEY }}
|
|
24992
25080
|
` : ""}NODE_ENV: production` : ""}
|
|
24993
25081
|
|
|
@@ -25074,6 +25162,1183 @@ updates:
|
|
|
25074
25162
|
await writeFile(join(projectPath, ".github/dependabot.yml"), dependabotConfig);
|
|
25075
25163
|
}
|
|
25076
25164
|
|
|
25165
|
+
// ../templates/src/generators/shadcn.ts
|
|
25166
|
+
init_dist();
|
|
25167
|
+
init_src();
|
|
25168
|
+
|
|
25169
|
+
// ../templates/src/generators/shadcn-themes.ts
|
|
25170
|
+
var neutralTheme = {
|
|
25171
|
+
light: {
|
|
25172
|
+
radius: "0.625rem",
|
|
25173
|
+
background: "oklch(1 0 0)",
|
|
25174
|
+
foreground: "oklch(0.145 0 0)",
|
|
25175
|
+
card: "oklch(1 0 0)",
|
|
25176
|
+
cardForeground: "oklch(0.145 0 0)",
|
|
25177
|
+
popover: "oklch(1 0 0)",
|
|
25178
|
+
popoverForeground: "oklch(0.145 0 0)",
|
|
25179
|
+
primary: "oklch(0.205 0 0)",
|
|
25180
|
+
primaryForeground: "oklch(0.985 0 0)",
|
|
25181
|
+
secondary: "oklch(0.97 0 0)",
|
|
25182
|
+
secondaryForeground: "oklch(0.205 0 0)",
|
|
25183
|
+
muted: "oklch(0.97 0 0)",
|
|
25184
|
+
mutedForeground: "oklch(0.556 0 0)",
|
|
25185
|
+
accent: "oklch(0.97 0 0)",
|
|
25186
|
+
accentForeground: "oklch(0.205 0 0)",
|
|
25187
|
+
destructive: "oklch(0.577 0.245 27.325)",
|
|
25188
|
+
destructiveForeground: "oklch(0.577 0.245 27.325)",
|
|
25189
|
+
border: "oklch(0.922 0 0)",
|
|
25190
|
+
input: "oklch(0.922 0 0)",
|
|
25191
|
+
ring: "oklch(0.708 0 0)",
|
|
25192
|
+
chart1: "oklch(0.646 0.222 41.116)",
|
|
25193
|
+
chart2: "oklch(0.6 0.118 184.704)",
|
|
25194
|
+
chart3: "oklch(0.398 0.07 227.392)",
|
|
25195
|
+
chart4: "oklch(0.828 0.189 84.429)",
|
|
25196
|
+
chart5: "oklch(0.769 0.188 70.08)",
|
|
25197
|
+
sidebar: "oklch(0.985 0 0)",
|
|
25198
|
+
sidebarForeground: "oklch(0.145 0 0)",
|
|
25199
|
+
sidebarPrimary: "oklch(0.205 0 0)",
|
|
25200
|
+
sidebarPrimaryForeground: "oklch(0.985 0 0)",
|
|
25201
|
+
sidebarAccent: "oklch(0.97 0 0)",
|
|
25202
|
+
sidebarAccentForeground: "oklch(0.205 0 0)",
|
|
25203
|
+
sidebarBorder: "oklch(0.922 0 0)",
|
|
25204
|
+
sidebarRing: "oklch(0.708 0 0)"
|
|
25205
|
+
},
|
|
25206
|
+
dark: {
|
|
25207
|
+
background: "oklch(0.145 0 0)",
|
|
25208
|
+
foreground: "oklch(0.985 0 0)",
|
|
25209
|
+
card: "oklch(0.145 0 0)",
|
|
25210
|
+
cardForeground: "oklch(0.985 0 0)",
|
|
25211
|
+
popover: "oklch(0.145 0 0)",
|
|
25212
|
+
popoverForeground: "oklch(0.985 0 0)",
|
|
25213
|
+
primary: "oklch(0.985 0 0)",
|
|
25214
|
+
primaryForeground: "oklch(0.205 0 0)",
|
|
25215
|
+
secondary: "oklch(0.269 0 0)",
|
|
25216
|
+
secondaryForeground: "oklch(0.985 0 0)",
|
|
25217
|
+
muted: "oklch(0.269 0 0)",
|
|
25218
|
+
mutedForeground: "oklch(0.708 0 0)",
|
|
25219
|
+
accent: "oklch(0.269 0 0)",
|
|
25220
|
+
accentForeground: "oklch(0.985 0 0)",
|
|
25221
|
+
destructive: "oklch(0.396 0.141 25.723)",
|
|
25222
|
+
destructiveForeground: "oklch(0.637 0.237 25.331)",
|
|
25223
|
+
border: "oklch(0.269 0 0)",
|
|
25224
|
+
input: "oklch(0.269 0 0)",
|
|
25225
|
+
ring: "oklch(0.439 0 0)",
|
|
25226
|
+
chart1: "oklch(0.488 0.243 264.376)",
|
|
25227
|
+
chart2: "oklch(0.696 0.17 162.48)",
|
|
25228
|
+
chart3: "oklch(0.769 0.188 70.08)",
|
|
25229
|
+
chart4: "oklch(0.627 0.265 303.9)",
|
|
25230
|
+
chart5: "oklch(0.645 0.246 16.439)",
|
|
25231
|
+
sidebar: "oklch(0.205 0 0)",
|
|
25232
|
+
sidebarForeground: "oklch(0.985 0 0)",
|
|
25233
|
+
sidebarPrimary: "oklch(0.488 0.243 264.376)",
|
|
25234
|
+
sidebarPrimaryForeground: "oklch(0.985 0 0)",
|
|
25235
|
+
sidebarAccent: "oklch(0.269 0 0)",
|
|
25236
|
+
sidebarAccentForeground: "oklch(0.985 0 0)",
|
|
25237
|
+
sidebarBorder: "oklch(0.269 0 0)",
|
|
25238
|
+
sidebarRing: "oklch(0.439 0 0)"
|
|
25239
|
+
}
|
|
25240
|
+
};
|
|
25241
|
+
var grayTheme = {
|
|
25242
|
+
light: {
|
|
25243
|
+
radius: "0.625rem",
|
|
25244
|
+
background: "oklch(1 0 0)",
|
|
25245
|
+
foreground: "oklch(0.13 0.028 261.692)",
|
|
25246
|
+
card: "oklch(1 0 0)",
|
|
25247
|
+
cardForeground: "oklch(0.13 0.028 261.692)",
|
|
25248
|
+
popover: "oklch(1 0 0)",
|
|
25249
|
+
popoverForeground: "oklch(0.13 0.028 261.692)",
|
|
25250
|
+
primary: "oklch(0.21 0.034 264.665)",
|
|
25251
|
+
primaryForeground: "oklch(0.985 0.002 247.839)",
|
|
25252
|
+
secondary: "oklch(0.967 0.003 264.542)",
|
|
25253
|
+
secondaryForeground: "oklch(0.21 0.034 264.665)",
|
|
25254
|
+
muted: "oklch(0.967 0.003 264.542)",
|
|
25255
|
+
mutedForeground: "oklch(0.551 0.027 264.364)",
|
|
25256
|
+
accent: "oklch(0.967 0.003 264.542)",
|
|
25257
|
+
accentForeground: "oklch(0.21 0.034 264.665)",
|
|
25258
|
+
destructive: "oklch(0.577 0.245 27.325)",
|
|
25259
|
+
destructiveForeground: "oklch(0.577 0.245 27.325)",
|
|
25260
|
+
border: "oklch(0.928 0.006 264.531)",
|
|
25261
|
+
input: "oklch(0.928 0.006 264.531)",
|
|
25262
|
+
ring: "oklch(0.707 0.022 261.325)",
|
|
25263
|
+
chart1: "oklch(0.646 0.222 41.116)",
|
|
25264
|
+
chart2: "oklch(0.6 0.118 184.704)",
|
|
25265
|
+
chart3: "oklch(0.398 0.07 227.392)",
|
|
25266
|
+
chart4: "oklch(0.828 0.189 84.429)",
|
|
25267
|
+
chart5: "oklch(0.769 0.188 70.08)",
|
|
25268
|
+
sidebar: "oklch(0.985 0.002 247.839)",
|
|
25269
|
+
sidebarForeground: "oklch(0.13 0.028 261.692)",
|
|
25270
|
+
sidebarPrimary: "oklch(0.21 0.034 264.665)",
|
|
25271
|
+
sidebarPrimaryForeground: "oklch(0.985 0.002 247.839)",
|
|
25272
|
+
sidebarAccent: "oklch(0.967 0.003 264.542)",
|
|
25273
|
+
sidebarAccentForeground: "oklch(0.21 0.034 264.665)",
|
|
25274
|
+
sidebarBorder: "oklch(0.928 0.006 264.531)",
|
|
25275
|
+
sidebarRing: "oklch(0.707 0.022 261.325)"
|
|
25276
|
+
},
|
|
25277
|
+
dark: {
|
|
25278
|
+
background: "oklch(0.13 0.028 261.692)",
|
|
25279
|
+
foreground: "oklch(0.985 0.002 247.839)",
|
|
25280
|
+
card: "oklch(0.21 0.034 264.665)",
|
|
25281
|
+
cardForeground: "oklch(0.985 0.002 247.839)",
|
|
25282
|
+
popover: "oklch(0.21 0.034 264.665)",
|
|
25283
|
+
popoverForeground: "oklch(0.985 0.002 247.839)",
|
|
25284
|
+
primary: "oklch(0.928 0.006 264.531)",
|
|
25285
|
+
primaryForeground: "oklch(0.21 0.034 264.665)",
|
|
25286
|
+
secondary: "oklch(0.278 0.033 256.848)",
|
|
25287
|
+
secondaryForeground: "oklch(0.985 0.002 247.839)",
|
|
25288
|
+
muted: "oklch(0.278 0.033 256.848)",
|
|
25289
|
+
mutedForeground: "oklch(0.707 0.022 261.325)",
|
|
25290
|
+
accent: "oklch(0.278 0.033 256.848)",
|
|
25291
|
+
accentForeground: "oklch(0.985 0.002 247.839)",
|
|
25292
|
+
destructive: "oklch(0.704 0.191 22.216)",
|
|
25293
|
+
destructiveForeground: "oklch(0.704 0.191 22.216)",
|
|
25294
|
+
border: "oklch(1 0 0 / 10%)",
|
|
25295
|
+
input: "oklch(1 0 0 / 15%)",
|
|
25296
|
+
ring: "oklch(0.551 0.027 264.364)",
|
|
25297
|
+
chart1: "oklch(0.488 0.243 264.376)",
|
|
25298
|
+
chart2: "oklch(0.696 0.17 162.48)",
|
|
25299
|
+
chart3: "oklch(0.769 0.188 70.08)",
|
|
25300
|
+
chart4: "oklch(0.627 0.265 303.9)",
|
|
25301
|
+
chart5: "oklch(0.645 0.246 16.439)",
|
|
25302
|
+
sidebar: "oklch(0.21 0.034 264.665)",
|
|
25303
|
+
sidebarForeground: "oklch(0.985 0.002 247.839)",
|
|
25304
|
+
sidebarPrimary: "oklch(0.488 0.243 264.376)",
|
|
25305
|
+
sidebarPrimaryForeground: "oklch(0.985 0.002 247.839)",
|
|
25306
|
+
sidebarAccent: "oklch(0.278 0.033 256.848)",
|
|
25307
|
+
sidebarAccentForeground: "oklch(0.985 0.002 247.839)",
|
|
25308
|
+
sidebarBorder: "oklch(1 0 0 / 10%)",
|
|
25309
|
+
sidebarRing: "oklch(0.551 0.027 264.364)"
|
|
25310
|
+
}
|
|
25311
|
+
};
|
|
25312
|
+
var zincTheme = {
|
|
25313
|
+
light: {
|
|
25314
|
+
radius: "0.625rem",
|
|
25315
|
+
background: "oklch(1 0 0)",
|
|
25316
|
+
foreground: "oklch(0.141 0.005 285.823)",
|
|
25317
|
+
card: "oklch(1 0 0)",
|
|
25318
|
+
cardForeground: "oklch(0.141 0.005 285.823)",
|
|
25319
|
+
popover: "oklch(1 0 0)",
|
|
25320
|
+
popoverForeground: "oklch(0.141 0.005 285.823)",
|
|
25321
|
+
primary: "oklch(0.21 0.006 285.885)",
|
|
25322
|
+
primaryForeground: "oklch(0.985 0 0)",
|
|
25323
|
+
secondary: "oklch(0.967 0.001 286.375)",
|
|
25324
|
+
secondaryForeground: "oklch(0.21 0.006 285.885)",
|
|
25325
|
+
muted: "oklch(0.967 0.001 286.375)",
|
|
25326
|
+
mutedForeground: "oklch(0.552 0.016 285.938)",
|
|
25327
|
+
accent: "oklch(0.967 0.001 286.375)",
|
|
25328
|
+
accentForeground: "oklch(0.21 0.006 285.885)",
|
|
25329
|
+
destructive: "oklch(0.577 0.245 27.325)",
|
|
25330
|
+
destructiveForeground: "oklch(0.577 0.245 27.325)",
|
|
25331
|
+
border: "oklch(0.92 0.004 286.32)",
|
|
25332
|
+
input: "oklch(0.92 0.004 286.32)",
|
|
25333
|
+
ring: "oklch(0.705 0.015 286.067)",
|
|
25334
|
+
chart1: "oklch(0.646 0.222 41.116)",
|
|
25335
|
+
chart2: "oklch(0.6 0.118 184.704)",
|
|
25336
|
+
chart3: "oklch(0.398 0.07 227.392)",
|
|
25337
|
+
chart4: "oklch(0.828 0.189 84.429)",
|
|
25338
|
+
chart5: "oklch(0.769 0.188 70.08)",
|
|
25339
|
+
sidebar: "oklch(0.985 0 0)",
|
|
25340
|
+
sidebarForeground: "oklch(0.141 0.005 285.823)",
|
|
25341
|
+
sidebarPrimary: "oklch(0.21 0.006 285.885)",
|
|
25342
|
+
sidebarPrimaryForeground: "oklch(0.985 0 0)",
|
|
25343
|
+
sidebarAccent: "oklch(0.967 0.001 286.375)",
|
|
25344
|
+
sidebarAccentForeground: "oklch(0.21 0.006 285.885)",
|
|
25345
|
+
sidebarBorder: "oklch(0.92 0.004 286.32)",
|
|
25346
|
+
sidebarRing: "oklch(0.705 0.015 286.067)"
|
|
25347
|
+
},
|
|
25348
|
+
dark: {
|
|
25349
|
+
background: "oklch(0.141 0.005 285.823)",
|
|
25350
|
+
foreground: "oklch(0.985 0 0)",
|
|
25351
|
+
card: "oklch(0.21 0.006 285.885)",
|
|
25352
|
+
cardForeground: "oklch(0.985 0 0)",
|
|
25353
|
+
popover: "oklch(0.21 0.006 285.885)",
|
|
25354
|
+
popoverForeground: "oklch(0.985 0 0)",
|
|
25355
|
+
primary: "oklch(0.92 0.004 286.32)",
|
|
25356
|
+
primaryForeground: "oklch(0.21 0.006 285.885)",
|
|
25357
|
+
secondary: "oklch(0.274 0.006 286.033)",
|
|
25358
|
+
secondaryForeground: "oklch(0.985 0 0)",
|
|
25359
|
+
muted: "oklch(0.274 0.006 286.033)",
|
|
25360
|
+
mutedForeground: "oklch(0.705 0.015 286.067)",
|
|
25361
|
+
accent: "oklch(0.274 0.006 286.033)",
|
|
25362
|
+
accentForeground: "oklch(0.985 0 0)",
|
|
25363
|
+
destructive: "oklch(0.704 0.191 22.216)",
|
|
25364
|
+
destructiveForeground: "oklch(0.704 0.191 22.216)",
|
|
25365
|
+
border: "oklch(1 0 0 / 10%)",
|
|
25366
|
+
input: "oklch(1 0 0 / 15%)",
|
|
25367
|
+
ring: "oklch(0.552 0.016 285.938)",
|
|
25368
|
+
chart1: "oklch(0.488 0.243 264.376)",
|
|
25369
|
+
chart2: "oklch(0.696 0.17 162.48)",
|
|
25370
|
+
chart3: "oklch(0.769 0.188 70.08)",
|
|
25371
|
+
chart4: "oklch(0.627 0.265 303.9)",
|
|
25372
|
+
chart5: "oklch(0.645 0.246 16.439)",
|
|
25373
|
+
sidebar: "oklch(0.21 0.006 285.885)",
|
|
25374
|
+
sidebarForeground: "oklch(0.985 0 0)",
|
|
25375
|
+
sidebarPrimary: "oklch(0.488 0.243 264.376)",
|
|
25376
|
+
sidebarPrimaryForeground: "oklch(0.985 0 0)",
|
|
25377
|
+
sidebarAccent: "oklch(0.274 0.006 286.033)",
|
|
25378
|
+
sidebarAccentForeground: "oklch(0.985 0 0)",
|
|
25379
|
+
sidebarBorder: "oklch(1 0 0 / 10%)",
|
|
25380
|
+
sidebarRing: "oklch(0.552 0.016 285.938)"
|
|
25381
|
+
}
|
|
25382
|
+
};
|
|
25383
|
+
var stoneTheme = {
|
|
25384
|
+
light: {
|
|
25385
|
+
radius: "0.625rem",
|
|
25386
|
+
background: "oklch(1 0 0)",
|
|
25387
|
+
foreground: "oklch(0.147 0.004 49.25)",
|
|
25388
|
+
card: "oklch(1 0 0)",
|
|
25389
|
+
cardForeground: "oklch(0.147 0.004 49.25)",
|
|
25390
|
+
popover: "oklch(1 0 0)",
|
|
25391
|
+
popoverForeground: "oklch(0.147 0.004 49.25)",
|
|
25392
|
+
primary: "oklch(0.216 0.006 56.043)",
|
|
25393
|
+
primaryForeground: "oklch(0.985 0.001 106.423)",
|
|
25394
|
+
secondary: "oklch(0.97 0.001 106.424)",
|
|
25395
|
+
secondaryForeground: "oklch(0.216 0.006 56.043)",
|
|
25396
|
+
muted: "oklch(0.97 0.001 106.424)",
|
|
25397
|
+
mutedForeground: "oklch(0.553 0.013 58.071)",
|
|
25398
|
+
accent: "oklch(0.97 0.001 106.424)",
|
|
25399
|
+
accentForeground: "oklch(0.216 0.006 56.043)",
|
|
25400
|
+
destructive: "oklch(0.577 0.245 27.325)",
|
|
25401
|
+
destructiveForeground: "oklch(0.577 0.245 27.325)",
|
|
25402
|
+
border: "oklch(0.923 0.003 48.717)",
|
|
25403
|
+
input: "oklch(0.923 0.003 48.717)",
|
|
25404
|
+
ring: "oklch(0.709 0.01 56.259)",
|
|
25405
|
+
chart1: "oklch(0.646 0.222 41.116)",
|
|
25406
|
+
chart2: "oklch(0.6 0.118 184.704)",
|
|
25407
|
+
chart3: "oklch(0.398 0.07 227.392)",
|
|
25408
|
+
chart4: "oklch(0.828 0.189 84.429)",
|
|
25409
|
+
chart5: "oklch(0.769 0.188 70.08)",
|
|
25410
|
+
sidebar: "oklch(0.985 0.001 106.423)",
|
|
25411
|
+
sidebarForeground: "oklch(0.147 0.004 49.25)",
|
|
25412
|
+
sidebarPrimary: "oklch(0.216 0.006 56.043)",
|
|
25413
|
+
sidebarPrimaryForeground: "oklch(0.985 0.001 106.423)",
|
|
25414
|
+
sidebarAccent: "oklch(0.97 0.001 106.424)",
|
|
25415
|
+
sidebarAccentForeground: "oklch(0.216 0.006 56.043)",
|
|
25416
|
+
sidebarBorder: "oklch(0.923 0.003 48.717)",
|
|
25417
|
+
sidebarRing: "oklch(0.709 0.01 56.259)"
|
|
25418
|
+
},
|
|
25419
|
+
dark: {
|
|
25420
|
+
background: "oklch(0.147 0.004 49.25)",
|
|
25421
|
+
foreground: "oklch(0.985 0.001 106.423)",
|
|
25422
|
+
card: "oklch(0.216 0.006 56.043)",
|
|
25423
|
+
cardForeground: "oklch(0.985 0.001 106.423)",
|
|
25424
|
+
popover: "oklch(0.216 0.006 56.043)",
|
|
25425
|
+
popoverForeground: "oklch(0.985 0.001 106.423)",
|
|
25426
|
+
primary: "oklch(0.923 0.003 48.717)",
|
|
25427
|
+
primaryForeground: "oklch(0.216 0.006 56.043)",
|
|
25428
|
+
secondary: "oklch(0.268 0.007 34.298)",
|
|
25429
|
+
secondaryForeground: "oklch(0.985 0.001 106.423)",
|
|
25430
|
+
muted: "oklch(0.268 0.007 34.298)",
|
|
25431
|
+
mutedForeground: "oklch(0.709 0.01 56.259)",
|
|
25432
|
+
accent: "oklch(0.268 0.007 34.298)",
|
|
25433
|
+
accentForeground: "oklch(0.985 0.001 106.423)",
|
|
25434
|
+
destructive: "oklch(0.704 0.191 22.216)",
|
|
25435
|
+
destructiveForeground: "oklch(0.704 0.191 22.216)",
|
|
25436
|
+
border: "oklch(1 0 0 / 10%)",
|
|
25437
|
+
input: "oklch(1 0 0 / 15%)",
|
|
25438
|
+
ring: "oklch(0.553 0.013 58.071)",
|
|
25439
|
+
chart1: "oklch(0.488 0.243 264.376)",
|
|
25440
|
+
chart2: "oklch(0.696 0.17 162.48)",
|
|
25441
|
+
chart3: "oklch(0.769 0.188 70.08)",
|
|
25442
|
+
chart4: "oklch(0.627 0.265 303.9)",
|
|
25443
|
+
chart5: "oklch(0.645 0.246 16.439)",
|
|
25444
|
+
sidebar: "oklch(0.216 0.006 56.043)",
|
|
25445
|
+
sidebarForeground: "oklch(0.985 0.001 106.423)",
|
|
25446
|
+
sidebarPrimary: "oklch(0.488 0.243 264.376)",
|
|
25447
|
+
sidebarPrimaryForeground: "oklch(0.985 0.001 106.423)",
|
|
25448
|
+
sidebarAccent: "oklch(0.268 0.007 34.298)",
|
|
25449
|
+
sidebarAccentForeground: "oklch(0.985 0.001 106.423)",
|
|
25450
|
+
sidebarBorder: "oklch(1 0 0 / 10%)",
|
|
25451
|
+
sidebarRing: "oklch(0.553 0.013 58.071)"
|
|
25452
|
+
}
|
|
25453
|
+
};
|
|
25454
|
+
var slateTheme = {
|
|
25455
|
+
light: {
|
|
25456
|
+
radius: "0.625rem",
|
|
25457
|
+
background: "oklch(1 0 0)",
|
|
25458
|
+
foreground: "oklch(0.129 0.042 264.695)",
|
|
25459
|
+
card: "oklch(1 0 0)",
|
|
25460
|
+
cardForeground: "oklch(0.129 0.042 264.695)",
|
|
25461
|
+
popover: "oklch(1 0 0)",
|
|
25462
|
+
popoverForeground: "oklch(0.129 0.042 264.695)",
|
|
25463
|
+
primary: "oklch(0.208 0.042 265.755)",
|
|
25464
|
+
primaryForeground: "oklch(0.984 0.003 247.858)",
|
|
25465
|
+
secondary: "oklch(0.968 0.007 247.896)",
|
|
25466
|
+
secondaryForeground: "oklch(0.208 0.042 265.755)",
|
|
25467
|
+
muted: "oklch(0.968 0.007 247.896)",
|
|
25468
|
+
mutedForeground: "oklch(0.554 0.046 257.417)",
|
|
25469
|
+
accent: "oklch(0.968 0.007 247.896)",
|
|
25470
|
+
accentForeground: "oklch(0.208 0.042 265.755)",
|
|
25471
|
+
destructive: "oklch(0.577 0.245 27.325)",
|
|
25472
|
+
destructiveForeground: "oklch(0.577 0.245 27.325)",
|
|
25473
|
+
border: "oklch(0.929 0.013 255.508)",
|
|
25474
|
+
input: "oklch(0.929 0.013 255.508)",
|
|
25475
|
+
ring: "oklch(0.704 0.04 256.788)",
|
|
25476
|
+
chart1: "oklch(0.646 0.222 41.116)",
|
|
25477
|
+
chart2: "oklch(0.6 0.118 184.704)",
|
|
25478
|
+
chart3: "oklch(0.398 0.07 227.392)",
|
|
25479
|
+
chart4: "oklch(0.828 0.189 84.429)",
|
|
25480
|
+
chart5: "oklch(0.769 0.188 70.08)",
|
|
25481
|
+
sidebar: "oklch(0.984 0.003 247.858)",
|
|
25482
|
+
sidebarForeground: "oklch(0.129 0.042 264.695)",
|
|
25483
|
+
sidebarPrimary: "oklch(0.208 0.042 265.755)",
|
|
25484
|
+
sidebarPrimaryForeground: "oklch(0.984 0.003 247.858)",
|
|
25485
|
+
sidebarAccent: "oklch(0.968 0.007 247.896)",
|
|
25486
|
+
sidebarAccentForeground: "oklch(0.208 0.042 265.755)",
|
|
25487
|
+
sidebarBorder: "oklch(0.929 0.013 255.508)",
|
|
25488
|
+
sidebarRing: "oklch(0.704 0.04 256.788)"
|
|
25489
|
+
},
|
|
25490
|
+
dark: {
|
|
25491
|
+
background: "oklch(0.129 0.042 264.695)",
|
|
25492
|
+
foreground: "oklch(0.984 0.003 247.858)",
|
|
25493
|
+
card: "oklch(0.208 0.042 265.755)",
|
|
25494
|
+
cardForeground: "oklch(0.984 0.003 247.858)",
|
|
25495
|
+
popover: "oklch(0.208 0.042 265.755)",
|
|
25496
|
+
popoverForeground: "oklch(0.984 0.003 247.858)",
|
|
25497
|
+
primary: "oklch(0.929 0.013 255.508)",
|
|
25498
|
+
primaryForeground: "oklch(0.208 0.042 265.755)",
|
|
25499
|
+
secondary: "oklch(0.279 0.041 260.031)",
|
|
25500
|
+
secondaryForeground: "oklch(0.984 0.003 247.858)",
|
|
25501
|
+
muted: "oklch(0.279 0.041 260.031)",
|
|
25502
|
+
mutedForeground: "oklch(0.704 0.04 256.788)",
|
|
25503
|
+
accent: "oklch(0.279 0.041 260.031)",
|
|
25504
|
+
accentForeground: "oklch(0.984 0.003 247.858)",
|
|
25505
|
+
destructive: "oklch(0.704 0.191 22.216)",
|
|
25506
|
+
destructiveForeground: "oklch(0.704 0.191 22.216)",
|
|
25507
|
+
border: "oklch(1 0 0 / 10%)",
|
|
25508
|
+
input: "oklch(1 0 0 / 15%)",
|
|
25509
|
+
ring: "oklch(0.551 0.027 264.364)",
|
|
25510
|
+
chart1: "oklch(0.488 0.243 264.376)",
|
|
25511
|
+
chart2: "oklch(0.696 0.17 162.48)",
|
|
25512
|
+
chart3: "oklch(0.769 0.188 70.08)",
|
|
25513
|
+
chart4: "oklch(0.627 0.265 303.9)",
|
|
25514
|
+
chart5: "oklch(0.645 0.246 16.439)",
|
|
25515
|
+
sidebar: "oklch(0.208 0.042 265.755)",
|
|
25516
|
+
sidebarForeground: "oklch(0.984 0.003 247.858)",
|
|
25517
|
+
sidebarPrimary: "oklch(0.488 0.243 264.376)",
|
|
25518
|
+
sidebarPrimaryForeground: "oklch(0.984 0.003 247.858)",
|
|
25519
|
+
sidebarAccent: "oklch(0.279 0.041 260.031)",
|
|
25520
|
+
sidebarAccentForeground: "oklch(0.984 0.003 247.858)",
|
|
25521
|
+
sidebarBorder: "oklch(1 0 0 / 10%)",
|
|
25522
|
+
sidebarRing: "oklch(0.551 0.027 264.364)"
|
|
25523
|
+
}
|
|
25524
|
+
};
|
|
25525
|
+
var themes = {
|
|
25526
|
+
neutral: neutralTheme,
|
|
25527
|
+
gray: grayTheme,
|
|
25528
|
+
zinc: zincTheme,
|
|
25529
|
+
stone: stoneTheme,
|
|
25530
|
+
slate: slateTheme
|
|
25531
|
+
};
|
|
25532
|
+
function generateThemeCSS(theme, customRadius) {
|
|
25533
|
+
const radius = customRadius || theme.light.radius;
|
|
25534
|
+
return `@layer base {
|
|
25535
|
+
:root {
|
|
25536
|
+
--radius: ${radius};
|
|
25537
|
+
--background: ${theme.light.background};
|
|
25538
|
+
--foreground: ${theme.light.foreground};
|
|
25539
|
+
--card: ${theme.light.card};
|
|
25540
|
+
--card-foreground: ${theme.light.cardForeground};
|
|
25541
|
+
--popover: ${theme.light.popover};
|
|
25542
|
+
--popover-foreground: ${theme.light.popoverForeground};
|
|
25543
|
+
--primary: ${theme.light.primary};
|
|
25544
|
+
--primary-foreground: ${theme.light.primaryForeground};
|
|
25545
|
+
--secondary: ${theme.light.secondary};
|
|
25546
|
+
--secondary-foreground: ${theme.light.secondaryForeground};
|
|
25547
|
+
--muted: ${theme.light.muted};
|
|
25548
|
+
--muted-foreground: ${theme.light.mutedForeground};
|
|
25549
|
+
--accent: ${theme.light.accent};
|
|
25550
|
+
--accent-foreground: ${theme.light.accentForeground};
|
|
25551
|
+
--destructive: ${theme.light.destructive};
|
|
25552
|
+
--destructive-foreground: ${theme.light.destructiveForeground};
|
|
25553
|
+
--border: ${theme.light.border};
|
|
25554
|
+
--input: ${theme.light.input};
|
|
25555
|
+
--ring: ${theme.light.ring};
|
|
25556
|
+
--chart-1: ${theme.light.chart1};
|
|
25557
|
+
--chart-2: ${theme.light.chart2};
|
|
25558
|
+
--chart-3: ${theme.light.chart3};
|
|
25559
|
+
--chart-4: ${theme.light.chart4};
|
|
25560
|
+
--chart-5: ${theme.light.chart5};
|
|
25561
|
+
--sidebar: ${theme.light.sidebar};
|
|
25562
|
+
--sidebar-foreground: ${theme.light.sidebarForeground};
|
|
25563
|
+
--sidebar-primary: ${theme.light.sidebarPrimary};
|
|
25564
|
+
--sidebar-primary-foreground: ${theme.light.sidebarPrimaryForeground};
|
|
25565
|
+
--sidebar-accent: ${theme.light.sidebarAccent};
|
|
25566
|
+
--sidebar-accent-foreground: ${theme.light.sidebarAccentForeground};
|
|
25567
|
+
--sidebar-border: ${theme.light.sidebarBorder};
|
|
25568
|
+
--sidebar-ring: ${theme.light.sidebarRing};
|
|
25569
|
+
}
|
|
25570
|
+
|
|
25571
|
+
.dark {
|
|
25572
|
+
--background: ${theme.dark.background};
|
|
25573
|
+
--foreground: ${theme.dark.foreground};
|
|
25574
|
+
--card: ${theme.dark.card};
|
|
25575
|
+
--card-foreground: ${theme.dark.cardForeground};
|
|
25576
|
+
--popover: ${theme.dark.popover};
|
|
25577
|
+
--popover-foreground: ${theme.dark.popoverForeground};
|
|
25578
|
+
--primary: ${theme.dark.primary};
|
|
25579
|
+
--primary-foreground: ${theme.dark.primaryForeground};
|
|
25580
|
+
--secondary: ${theme.dark.secondary};
|
|
25581
|
+
--secondary-foreground: ${theme.dark.secondaryForeground};
|
|
25582
|
+
--muted: ${theme.dark.muted};
|
|
25583
|
+
--muted-foreground: ${theme.dark.mutedForeground};
|
|
25584
|
+
--accent: ${theme.dark.accent};
|
|
25585
|
+
--accent-foreground: ${theme.dark.accentForeground};
|
|
25586
|
+
--destructive: ${theme.dark.destructive};
|
|
25587
|
+
--destructive-foreground: ${theme.dark.destructiveForeground};
|
|
25588
|
+
--border: ${theme.dark.border};
|
|
25589
|
+
--input: ${theme.dark.input};
|
|
25590
|
+
--ring: ${theme.dark.ring};
|
|
25591
|
+
--chart-1: ${theme.dark.chart1};
|
|
25592
|
+
--chart-2: ${theme.dark.chart2};
|
|
25593
|
+
--chart-3: ${theme.dark.chart3};
|
|
25594
|
+
--chart-4: ${theme.dark.chart4};
|
|
25595
|
+
--chart-5: ${theme.dark.chart5};
|
|
25596
|
+
--sidebar: ${theme.dark.sidebar};
|
|
25597
|
+
--sidebar-foreground: ${theme.dark.sidebarForeground};
|
|
25598
|
+
--sidebar-primary: ${theme.dark.sidebarPrimary};
|
|
25599
|
+
--sidebar-primary-foreground: ${theme.dark.sidebarPrimaryForeground};
|
|
25600
|
+
--sidebar-accent: ${theme.dark.sidebarAccent};
|
|
25601
|
+
--sidebar-accent-foreground: ${theme.dark.sidebarAccentForeground};
|
|
25602
|
+
--sidebar-border: ${theme.dark.sidebarBorder};
|
|
25603
|
+
--sidebar-ring: ${theme.dark.sidebarRing};
|
|
25604
|
+
}
|
|
25605
|
+
}
|
|
25606
|
+
|
|
25607
|
+
@layer base {
|
|
25608
|
+
* {
|
|
25609
|
+
@apply border-border outline-ring/50;
|
|
25610
|
+
}
|
|
25611
|
+
body {
|
|
25612
|
+
@apply bg-background text-foreground;
|
|
25613
|
+
}
|
|
25614
|
+
}
|
|
25615
|
+
`;
|
|
25616
|
+
}
|
|
25617
|
+
|
|
25618
|
+
// ../templates/src/generators/shadcn-components.ts
|
|
25619
|
+
init_execa();
|
|
25620
|
+
init_dist();
|
|
25621
|
+
init_src();
|
|
25622
|
+
init_src();
|
|
25623
|
+
var DEFAULT_SHADCN_COMPONENTS = [
|
|
25624
|
+
"button",
|
|
25625
|
+
"card"
|
|
25626
|
+
];
|
|
25627
|
+
async function installShadcnComponents(projectPath, components, options = {}) {
|
|
25628
|
+
const cwd2 = options.cwd || projectPath;
|
|
25629
|
+
const stdio = options.silent ? "pipe" : "inherit";
|
|
25630
|
+
try {
|
|
25631
|
+
await execa("bunx", ["shadcn@latest", "add", ...components], {
|
|
25632
|
+
cwd: cwd2,
|
|
25633
|
+
stdio
|
|
25634
|
+
});
|
|
25635
|
+
} catch (error) {
|
|
25636
|
+
try {
|
|
25637
|
+
await execa("npx", ["shadcn@latest", "add", ...components], {
|
|
25638
|
+
cwd: cwd2,
|
|
25639
|
+
stdio
|
|
25640
|
+
});
|
|
25641
|
+
} catch (fallbackError) {
|
|
25642
|
+
logger.warn(`Could not install shadcn components automatically. You can install them manually with: bunx shadcn@latest add ${components.join(" ")}`);
|
|
25643
|
+
}
|
|
25644
|
+
}
|
|
25645
|
+
}
|
|
25646
|
+
async function installDefaultShadcnComponents(projectPath, options = {}) {
|
|
25647
|
+
if (options.skipDefaults) {
|
|
25648
|
+
return;
|
|
25649
|
+
}
|
|
25650
|
+
logger.step("Installing default shadcn/ui components...");
|
|
25651
|
+
try {
|
|
25652
|
+
await installShadcnComponents(projectPath, [...DEFAULT_SHADCN_COMPONENTS], {
|
|
25653
|
+
silent: options.silent,
|
|
25654
|
+
cwd: projectPath
|
|
25655
|
+
});
|
|
25656
|
+
logger.success("Default components installed");
|
|
25657
|
+
} catch (error) {
|
|
25658
|
+
logger.warn("Could not install default components automatically. Install them manually with: bunx shadcn@latest add button card");
|
|
25659
|
+
}
|
|
25660
|
+
}
|
|
25661
|
+
async function createShadcnExample(projectPath, isMonorepo = false) {
|
|
25662
|
+
const examplePath = isMonorepo ? join(projectPath, "apps/web/src/components/example.tsx") : join(projectPath, "src/components/example.tsx");
|
|
25663
|
+
const exampleContent = `"use client"
|
|
25664
|
+
|
|
25665
|
+
import { Button } from "@/components/ui/button"
|
|
25666
|
+
import {
|
|
25667
|
+
Card,
|
|
25668
|
+
CardContent,
|
|
25669
|
+
CardDescription,
|
|
25670
|
+
CardFooter,
|
|
25671
|
+
CardHeader,
|
|
25672
|
+
CardTitle,
|
|
25673
|
+
} from "@/components/ui/card"
|
|
25674
|
+
|
|
25675
|
+
/**
|
|
25676
|
+
* Example component showcasing shadcn/ui components
|
|
25677
|
+
* This file demonstrates how to use Button and Card components
|
|
25678
|
+
*
|
|
25679
|
+
* You can delete this file once you're familiar with the patterns.
|
|
25680
|
+
*/
|
|
25681
|
+
export function ExampleComponent() {
|
|
25682
|
+
return (
|
|
25683
|
+
<div className="container mx-auto p-8 space-y-6">
|
|
25684
|
+
<Card>
|
|
25685
|
+
<CardHeader>
|
|
25686
|
+
<CardTitle>Welcome to shadcn/ui</CardTitle>
|
|
25687
|
+
<CardDescription>
|
|
25688
|
+
This is an example component showing how to use shadcn/ui components.
|
|
25689
|
+
</CardDescription>
|
|
25690
|
+
</CardHeader>
|
|
25691
|
+
<CardContent>
|
|
25692
|
+
<p className="text-sm text-muted-foreground">
|
|
25693
|
+
You can start building your UI by importing components from @/components/ui
|
|
25694
|
+
</p>
|
|
25695
|
+
</CardContent>
|
|
25696
|
+
<CardFooter className="flex gap-2">
|
|
25697
|
+
<Button>Get Started</Button>
|
|
25698
|
+
<Button variant="outline">Learn More</Button>
|
|
25699
|
+
</CardFooter>
|
|
25700
|
+
</Card>
|
|
25701
|
+
</div>
|
|
25702
|
+
)
|
|
25703
|
+
}
|
|
25704
|
+
`;
|
|
25705
|
+
try {
|
|
25706
|
+
await ensureDirectory(join(examplePath, ".."));
|
|
25707
|
+
await writeFile(examplePath, exampleContent);
|
|
25708
|
+
} catch (error) {}
|
|
25709
|
+
}
|
|
25710
|
+
|
|
25711
|
+
// ../templates/src/generators/shadcn-docs.ts
|
|
25712
|
+
init_dist();
|
|
25713
|
+
init_src();
|
|
25714
|
+
async function createShadcnDocs(projectPath, isMonorepo = false, context) {
|
|
25715
|
+
const docsPath = isMonorepo ? join(projectPath, "packages/ui/SHADCN.md") : join(projectPath, "SHADCN.md");
|
|
25716
|
+
const docsContent = `# shadcn/ui Guide
|
|
25717
|
+
|
|
25718
|
+
This project uses [shadcn/ui](https://ui.shadcn.com) - a collection of re-usable components built with Radix UI and Tailwind CSS.
|
|
25719
|
+
|
|
25720
|
+
## \uD83D\uDE80 Quick Start
|
|
25721
|
+
|
|
25722
|
+
### Adding Components
|
|
25723
|
+
|
|
25724
|
+
Use the bunkit CLI to add components:
|
|
25725
|
+
|
|
25726
|
+
\`\`\`bash
|
|
25727
|
+
# Add a single component
|
|
25728
|
+
bunkit add component --components button
|
|
25729
|
+
|
|
25730
|
+
# Add multiple components
|
|
25731
|
+
bunkit add component --components button,card,input
|
|
25732
|
+
|
|
25733
|
+
# Browse all available components
|
|
25734
|
+
bunkit add component --all
|
|
25735
|
+
\`\`\`
|
|
25736
|
+
|
|
25737
|
+
Or use the official shadcn CLI directly:
|
|
25738
|
+
|
|
25739
|
+
\`\`\`bash
|
|
25740
|
+
bunx shadcn@latest add button
|
|
25741
|
+
bunx shadcn@latest add card
|
|
25742
|
+
bunx shadcn@latest add input
|
|
25743
|
+
\`\`\`
|
|
25744
|
+
|
|
25745
|
+
### Using Components
|
|
25746
|
+
|
|
25747
|
+
Import components from the \`@/components/ui\` path:
|
|
25748
|
+
|
|
25749
|
+
\`\`\`tsx
|
|
25750
|
+
import { Button } from "@/components/ui/button"
|
|
25751
|
+
import {
|
|
25752
|
+
Card,
|
|
25753
|
+
CardContent,
|
|
25754
|
+
CardDescription,
|
|
25755
|
+
CardFooter,
|
|
25756
|
+
CardHeader,
|
|
25757
|
+
CardTitle,
|
|
25758
|
+
} from "@/components/ui/card"
|
|
25759
|
+
|
|
25760
|
+
export function MyComponent() {
|
|
25761
|
+
return (
|
|
25762
|
+
<Card>
|
|
25763
|
+
<CardHeader>
|
|
25764
|
+
<CardTitle>Hello</CardTitle>
|
|
25765
|
+
<CardDescription>World</CardDescription>
|
|
25766
|
+
</CardHeader>
|
|
25767
|
+
<CardContent>
|
|
25768
|
+
<Button>Click me</Button>
|
|
25769
|
+
</CardContent>
|
|
25770
|
+
</Card>
|
|
25771
|
+
)
|
|
25772
|
+
}
|
|
25773
|
+
\`\`\`
|
|
25774
|
+
|
|
25775
|
+
## \uD83D\uDCDA Available Components
|
|
25776
|
+
|
|
25777
|
+
shadcn/ui provides 60+ components. Browse them all at [ui.shadcn.com](https://ui.shadcn.com/components).
|
|
25778
|
+
|
|
25779
|
+
### Most Popular Components
|
|
25780
|
+
|
|
25781
|
+
- **Button** - \`bunkit add component --components button\`
|
|
25782
|
+
- **Card** - \`bunkit add component --components card\`
|
|
25783
|
+
- **Input** - \`bunkit add component --components input\`
|
|
25784
|
+
- **Dialog** - \`bunkit add component --components dialog\`
|
|
25785
|
+
- **Dropdown Menu** - \`bunkit add component --components dropdown-menu\`
|
|
25786
|
+
- **Form** - \`bunkit add component --components form\`
|
|
25787
|
+
- **Table** - \`bunkit add component --components table\`
|
|
25788
|
+
- **Toast** - \`bunkit add component --components toast\`
|
|
25789
|
+
|
|
25790
|
+
## \uD83C\uDFA8 Customization
|
|
25791
|
+
|
|
25792
|
+
### Themes
|
|
25793
|
+
|
|
25794
|
+
Your project is configured with:
|
|
25795
|
+
- **Style**: ${context?.shadcnStyle || "new-york"}
|
|
25796
|
+
- **Base Color**: ${context?.shadcnBaseColor || "zinc"}
|
|
25797
|
+
- **Border Radius**: ${context?.shadcnRadius || "0.625rem"}
|
|
25798
|
+
|
|
25799
|
+
### Modifying Themes
|
|
25800
|
+
|
|
25801
|
+
Edit the CSS variables in \`${isMonorepo ? "packages/ui/src/styles/globals.css" : "src/app/globals.css"}\`:
|
|
25802
|
+
|
|
25803
|
+
\`\`\`css
|
|
25804
|
+
@layer base {
|
|
25805
|
+
:root {
|
|
25806
|
+
--radius: 0.625rem;
|
|
25807
|
+
--background: oklch(...);
|
|
25808
|
+
--foreground: oklch(...);
|
|
25809
|
+
/* ... */
|
|
25810
|
+
}
|
|
25811
|
+
}
|
|
25812
|
+
\`\`\`
|
|
25813
|
+
|
|
25814
|
+
### Component Customization
|
|
25815
|
+
|
|
25816
|
+
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!
|
|
25817
|
+
|
|
25818
|
+
## \uD83D\uDCD6 Documentation
|
|
25819
|
+
|
|
25820
|
+
- [Official shadcn/ui Docs](https://ui.shadcn.com)
|
|
25821
|
+
- [Component Examples](https://ui.shadcn.com/components)
|
|
25822
|
+
- [Theming Guide](https://ui.shadcn.com/theming)
|
|
25823
|
+
|
|
25824
|
+
## \uD83D\uDCA1 Tips
|
|
25825
|
+
|
|
25826
|
+
1. **Components are yours** - They're copied into your project, so feel free to modify them
|
|
25827
|
+
2. **Type-safe** - All components are fully typed with TypeScript
|
|
25828
|
+
3. **Accessible** - Built on Radix UI primitives for accessibility
|
|
25829
|
+
4. **Customizable** - Use Tailwind classes to style components however you want
|
|
25830
|
+
|
|
25831
|
+
## \uD83D\uDD27 Configuration
|
|
25832
|
+
|
|
25833
|
+
Your \`components.json\` file (located at \`${isMonorepo ? "packages/ui/components.json" : "components.json"}\`) contains all shadcn/ui configuration.
|
|
25834
|
+
|
|
25835
|
+
To change settings, edit this file or run:
|
|
25836
|
+
|
|
25837
|
+
\`\`\`bash
|
|
25838
|
+
bunx shadcn@latest init
|
|
25839
|
+
\`\`\`
|
|
25840
|
+
|
|
25841
|
+
---
|
|
25842
|
+
|
|
25843
|
+
**Happy building! \uD83D\uDE80**
|
|
25844
|
+
`;
|
|
25845
|
+
try {
|
|
25846
|
+
await ensureDirectory(join(docsPath, ".."));
|
|
25847
|
+
await writeFile(docsPath, docsContent);
|
|
25848
|
+
} catch (error) {}
|
|
25849
|
+
}
|
|
25850
|
+
|
|
25851
|
+
// ../templates/src/generators/shadcn.ts
|
|
25852
|
+
async function setupShadcnWeb(projectPath, context) {
|
|
25853
|
+
await ensureDirectory(join(projectPath, "src/components/ui"));
|
|
25854
|
+
await ensureDirectory(join(projectPath, "src/lib"));
|
|
25855
|
+
const style = context.shadcnStyle || "new-york";
|
|
25856
|
+
const baseColor = context.shadcnBaseColor || "zinc";
|
|
25857
|
+
const radius = context.shadcnRadius || "0.625rem";
|
|
25858
|
+
const componentsJson = {
|
|
25859
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
25860
|
+
style,
|
|
25861
|
+
rsc: true,
|
|
25862
|
+
tsx: true,
|
|
25863
|
+
tailwind: {
|
|
25864
|
+
config: "",
|
|
25865
|
+
css: "src/app/globals.css",
|
|
25866
|
+
baseColor,
|
|
25867
|
+
cssVariables: true
|
|
25868
|
+
},
|
|
25869
|
+
iconLibrary: "lucide",
|
|
25870
|
+
aliases: {
|
|
25871
|
+
components: "@/components",
|
|
25872
|
+
utils: "@/lib/utils",
|
|
25873
|
+
ui: "@/components/ui",
|
|
25874
|
+
lib: "@/lib",
|
|
25875
|
+
hooks: "@/hooks"
|
|
25876
|
+
}
|
|
25877
|
+
};
|
|
25878
|
+
await writeFile(join(projectPath, "components.json"), JSON.stringify(componentsJson, null, 2));
|
|
25879
|
+
const utilsContent = `import { clsx, type ClassValue } from 'clsx';
|
|
25880
|
+
import { twMerge } from 'tailwind-merge';
|
|
25881
|
+
|
|
25882
|
+
export function cn(...inputs: ClassValue[]) {
|
|
25883
|
+
return twMerge(clsx(inputs));
|
|
25884
|
+
}
|
|
25885
|
+
`;
|
|
25886
|
+
await writeFile(join(projectPath, "src/lib/utils.ts"), utilsContent);
|
|
25887
|
+
const packageJsonPath = join(projectPath, "package.json");
|
|
25888
|
+
let packageJson = {};
|
|
25889
|
+
try {
|
|
25890
|
+
packageJson = JSON.parse(await Bun.file(packageJsonPath).text());
|
|
25891
|
+
} catch {}
|
|
25892
|
+
if (!packageJson.dependencies) {
|
|
25893
|
+
packageJson.dependencies = {};
|
|
25894
|
+
}
|
|
25895
|
+
packageJson.dependencies["@radix-ui/react-slot"] = "catalog:";
|
|
25896
|
+
packageJson.dependencies["class-variance-authority"] = "catalog:";
|
|
25897
|
+
packageJson.dependencies["clsx"] = "catalog:";
|
|
25898
|
+
packageJson.dependencies["tailwind-merge"] = "catalog:";
|
|
25899
|
+
packageJson.dependencies["lucide-react"] = "catalog:";
|
|
25900
|
+
if (!packageJson.catalog) {
|
|
25901
|
+
packageJson.catalog = {};
|
|
25902
|
+
}
|
|
25903
|
+
packageJson.catalog["@radix-ui/react-slot"] = "^1.2.3";
|
|
25904
|
+
packageJson.catalog["class-variance-authority"] = "^0.7.1";
|
|
25905
|
+
packageJson.catalog["clsx"] = "^2.1.1";
|
|
25906
|
+
packageJson.catalog["tailwind-merge"] = "^3.3.1";
|
|
25907
|
+
packageJson.catalog["lucide-react"] = "^0.468.0";
|
|
25908
|
+
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
25909
|
+
const globalsCssPath = join(projectPath, "src/app/globals.css");
|
|
25910
|
+
let globalsCss = "";
|
|
25911
|
+
try {
|
|
25912
|
+
globalsCss = await Bun.file(globalsCssPath).text();
|
|
25913
|
+
} catch {}
|
|
25914
|
+
if (!globalsCss.includes("--background")) {
|
|
25915
|
+
const theme = themes[baseColor] || themes.zinc;
|
|
25916
|
+
const shadcnCss = generateThemeCSS(theme, radius);
|
|
25917
|
+
if (globalsCss) {
|
|
25918
|
+
globalsCss = globalsCss + `
|
|
25919
|
+
` + shadcnCss;
|
|
25920
|
+
} else {
|
|
25921
|
+
globalsCss = `@import "tailwindcss";
|
|
25922
|
+
|
|
25923
|
+
${shadcnCss}`;
|
|
25924
|
+
}
|
|
25925
|
+
await writeFile(globalsCssPath, globalsCss);
|
|
25926
|
+
}
|
|
25927
|
+
const tailwindConfigPath = join(projectPath, "tailwind.config.ts");
|
|
25928
|
+
let tailwindConfig = "";
|
|
25929
|
+
try {
|
|
25930
|
+
tailwindConfig = await Bun.file(tailwindConfigPath).text();
|
|
25931
|
+
} catch {}
|
|
25932
|
+
if (tailwindConfig && !tailwindConfig.includes("hsl(var(--background))")) {
|
|
25933
|
+
const shadcnTheme = ` theme: {
|
|
25934
|
+
extend: {
|
|
25935
|
+
colors: {
|
|
25936
|
+
border: "hsl(var(--border))",
|
|
25937
|
+
input: "hsl(var(--input))",
|
|
25938
|
+
ring: "hsl(var(--ring))",
|
|
25939
|
+
background: "hsl(var(--background))",
|
|
25940
|
+
foreground: "hsl(var(--foreground))",
|
|
25941
|
+
primary: {
|
|
25942
|
+
DEFAULT: "hsl(var(--primary))",
|
|
25943
|
+
foreground: "hsl(var(--primary-foreground))",
|
|
25944
|
+
},
|
|
25945
|
+
secondary: {
|
|
25946
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
25947
|
+
foreground: "hsl(var(--secondary-foreground))",
|
|
25948
|
+
},
|
|
25949
|
+
destructive: {
|
|
25950
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
25951
|
+
foreground: "hsl(var(--destructive-foreground))",
|
|
25952
|
+
},
|
|
25953
|
+
muted: {
|
|
25954
|
+
DEFAULT: "hsl(var(--muted))",
|
|
25955
|
+
foreground: "hsl(var(--muted-foreground))",
|
|
25956
|
+
},
|
|
25957
|
+
accent: {
|
|
25958
|
+
DEFAULT: "hsl(var(--accent))",
|
|
25959
|
+
foreground: "hsl(var(--accent-foreground))",
|
|
25960
|
+
},
|
|
25961
|
+
popover: {
|
|
25962
|
+
DEFAULT: "hsl(var(--popover))",
|
|
25963
|
+
foreground: "hsl(var(--popover-foreground))",
|
|
25964
|
+
},
|
|
25965
|
+
card: {
|
|
25966
|
+
DEFAULT: "hsl(var(--card))",
|
|
25967
|
+
foreground: "hsl(var(--card-foreground))",
|
|
25968
|
+
},
|
|
25969
|
+
},
|
|
25970
|
+
borderRadius: {
|
|
25971
|
+
lg: "var(--radius)",
|
|
25972
|
+
md: "calc(var(--radius) - 2px)",
|
|
25973
|
+
sm: "calc(var(--radius) - 4px)",
|
|
25974
|
+
},
|
|
25975
|
+
},
|
|
25976
|
+
},`;
|
|
25977
|
+
if (tailwindConfig.includes("theme:")) {
|
|
25978
|
+
const updatedConfig = tailwindConfig.replace(/theme:\s*\{[^}]*\}/s, shadcnTheme.trim());
|
|
25979
|
+
await writeFile(tailwindConfigPath, updatedConfig);
|
|
25980
|
+
} else {
|
|
25981
|
+
const updatedConfig = tailwindConfig.replace(/(\s*)(plugins:.*?)(\n\s*\};)/s, `$1$2$1${shadcnTheme}$3`);
|
|
25982
|
+
await writeFile(tailwindConfigPath, updatedConfig);
|
|
25983
|
+
}
|
|
25984
|
+
} else if (!tailwindConfig) {
|
|
25985
|
+
const newTailwindConfig = `import type { Config } from 'tailwindcss';
|
|
25986
|
+
|
|
25987
|
+
const config: Config = {
|
|
25988
|
+
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
|
|
25989
|
+
theme: {
|
|
25990
|
+
extend: {
|
|
25991
|
+
colors: {
|
|
25992
|
+
border: "hsl(var(--border))",
|
|
25993
|
+
input: "hsl(var(--input))",
|
|
25994
|
+
ring: "hsl(var(--ring))",
|
|
25995
|
+
background: "hsl(var(--background))",
|
|
25996
|
+
foreground: "hsl(var(--foreground))",
|
|
25997
|
+
primary: {
|
|
25998
|
+
DEFAULT: "hsl(var(--primary))",
|
|
25999
|
+
foreground: "hsl(var(--primary-foreground))",
|
|
26000
|
+
},
|
|
26001
|
+
secondary: {
|
|
26002
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
26003
|
+
foreground: "hsl(var(--secondary-foreground))",
|
|
26004
|
+
},
|
|
26005
|
+
destructive: {
|
|
26006
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
26007
|
+
foreground: "hsl(var(--destructive-foreground))",
|
|
26008
|
+
},
|
|
26009
|
+
muted: {
|
|
26010
|
+
DEFAULT: "hsl(var(--muted))",
|
|
26011
|
+
foreground: "hsl(var(--muted-foreground))",
|
|
26012
|
+
},
|
|
26013
|
+
accent: {
|
|
26014
|
+
DEFAULT: "hsl(var(--accent))",
|
|
26015
|
+
foreground: "hsl(var(--accent-foreground))",
|
|
26016
|
+
},
|
|
26017
|
+
popover: {
|
|
26018
|
+
DEFAULT: "hsl(var(--popover))",
|
|
26019
|
+
foreground: "hsl(var(--popover-foreground))",
|
|
26020
|
+
},
|
|
26021
|
+
card: {
|
|
26022
|
+
DEFAULT: "hsl(var(--card))",
|
|
26023
|
+
foreground: "hsl(var(--card-foreground))",
|
|
26024
|
+
},
|
|
26025
|
+
},
|
|
26026
|
+
borderRadius: {
|
|
26027
|
+
lg: "var(--radius)",
|
|
26028
|
+
md: "calc(var(--radius) - 2px)",
|
|
26029
|
+
sm: "calc(var(--radius) - 4px)",
|
|
26030
|
+
},
|
|
26031
|
+
},
|
|
26032
|
+
},
|
|
26033
|
+
plugins: [],
|
|
26034
|
+
};
|
|
26035
|
+
|
|
26036
|
+
export default config;
|
|
26037
|
+
`;
|
|
26038
|
+
await writeFile(tailwindConfigPath, newTailwindConfig);
|
|
26039
|
+
}
|
|
26040
|
+
if (context.install !== false) {}
|
|
26041
|
+
await createShadcnExample(projectPath, false);
|
|
26042
|
+
await createShadcnDocs(projectPath, false, context);
|
|
26043
|
+
}
|
|
26044
|
+
async function setupShadcnMonorepo(projectPath, context) {
|
|
26045
|
+
const packageName = context.packageName || context.projectName.toLowerCase().replace(/\s+/g, "-");
|
|
26046
|
+
const uiPackageName = `@${packageName}/ui`;
|
|
26047
|
+
const style = context.shadcnStyle || "new-york";
|
|
26048
|
+
const baseColor = context.shadcnBaseColor || "zinc";
|
|
26049
|
+
const radius = context.shadcnRadius || "0.625rem";
|
|
26050
|
+
await ensureDirectory(join(projectPath, "packages/ui/src/components"));
|
|
26051
|
+
await ensureDirectory(join(projectPath, "packages/ui/src/lib"));
|
|
26052
|
+
await ensureDirectory(join(projectPath, "packages/ui/src/hooks"));
|
|
26053
|
+
await ensureDirectory(join(projectPath, "packages/ui/src/styles"));
|
|
26054
|
+
const uiPackageJson = {
|
|
26055
|
+
name: uiPackageName,
|
|
26056
|
+
version: "0.0.0",
|
|
26057
|
+
private: true,
|
|
26058
|
+
main: "./src/index.ts",
|
|
26059
|
+
types: "./src/index.ts",
|
|
26060
|
+
exports: {
|
|
26061
|
+
"./components": "./src/components/index.ts",
|
|
26062
|
+
"./lib/utils": "./src/lib/utils.ts",
|
|
26063
|
+
"./hooks": "./src/hooks/index.ts",
|
|
26064
|
+
"./styles": "./src/styles/globals.css"
|
|
26065
|
+
},
|
|
26066
|
+
dependencies: {
|
|
26067
|
+
"@radix-ui/react-slot": "catalog:",
|
|
26068
|
+
"class-variance-authority": "catalog:",
|
|
26069
|
+
clsx: "catalog:",
|
|
26070
|
+
"tailwind-merge": "catalog:",
|
|
26071
|
+
"lucide-react": "catalog:"
|
|
26072
|
+
},
|
|
26073
|
+
devDependencies: {
|
|
26074
|
+
"@types/react": "catalog:",
|
|
26075
|
+
"@types/react-dom": "catalog:",
|
|
26076
|
+
typescript: "catalog:"
|
|
26077
|
+
}
|
|
26078
|
+
};
|
|
26079
|
+
await writeFile(join(projectPath, "packages/ui/package.json"), JSON.stringify(uiPackageJson, null, 2));
|
|
26080
|
+
const uiComponentsJson = {
|
|
26081
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
26082
|
+
style,
|
|
26083
|
+
rsc: true,
|
|
26084
|
+
tsx: true,
|
|
26085
|
+
tailwind: {
|
|
26086
|
+
config: "",
|
|
26087
|
+
css: "src/styles/globals.css",
|
|
26088
|
+
baseColor,
|
|
26089
|
+
cssVariables: true
|
|
26090
|
+
},
|
|
26091
|
+
iconLibrary: "lucide",
|
|
26092
|
+
aliases: {
|
|
26093
|
+
components: "@workspace/ui/components",
|
|
26094
|
+
utils: "@workspace/ui/lib/utils",
|
|
26095
|
+
hooks: "@workspace/ui/hooks",
|
|
26096
|
+
lib: "@workspace/ui/lib",
|
|
26097
|
+
ui: "@workspace/ui/components"
|
|
26098
|
+
}
|
|
26099
|
+
};
|
|
26100
|
+
await writeFile(join(projectPath, "packages/ui/components.json"), JSON.stringify(uiComponentsJson, null, 2));
|
|
26101
|
+
const uiUtilsContent = `import { clsx, type ClassValue } from 'clsx';
|
|
26102
|
+
import { twMerge } from 'tailwind-merge';
|
|
26103
|
+
|
|
26104
|
+
export function cn(...inputs: ClassValue[]) {
|
|
26105
|
+
return twMerge(clsx(inputs));
|
|
26106
|
+
}
|
|
26107
|
+
`;
|
|
26108
|
+
await writeFile(join(projectPath, "packages/ui/src/lib/utils.ts"), uiUtilsContent);
|
|
26109
|
+
const uiComponentsIndex = `// Export shadcn/ui components here
|
|
26110
|
+
// Components will be added via: bunx shadcn@latest add [component]
|
|
26111
|
+
`;
|
|
26112
|
+
await writeFile(join(projectPath, "packages/ui/src/components/index.ts"), uiComponentsIndex);
|
|
26113
|
+
const uiHooksIndex = `// Export custom hooks here
|
|
26114
|
+
`;
|
|
26115
|
+
await writeFile(join(projectPath, "packages/ui/src/hooks/index.ts"), uiHooksIndex);
|
|
26116
|
+
const theme = themes[baseColor] || themes.zinc;
|
|
26117
|
+
const uiGlobalsCss = generateThemeCSS(theme, radius);
|
|
26118
|
+
await writeFile(join(projectPath, "packages/ui/src/styles/globals.css"), uiGlobalsCss);
|
|
26119
|
+
const uiTsconfig = {
|
|
26120
|
+
compilerOptions: {
|
|
26121
|
+
target: "ES2017",
|
|
26122
|
+
lib: ["dom", "dom.iterable", "esnext"],
|
|
26123
|
+
allowJs: true,
|
|
26124
|
+
skipLibCheck: true,
|
|
26125
|
+
strict: true,
|
|
26126
|
+
noEmit: true,
|
|
26127
|
+
esModuleInterop: true,
|
|
26128
|
+
module: "esnext",
|
|
26129
|
+
moduleResolution: "bundler",
|
|
26130
|
+
resolveJsonModule: true,
|
|
26131
|
+
isolatedModules: true,
|
|
26132
|
+
jsx: "react-jsx",
|
|
26133
|
+
types: ["react", "react-dom"]
|
|
26134
|
+
},
|
|
26135
|
+
include: ["src/**/*"],
|
|
26136
|
+
exclude: ["node_modules"]
|
|
26137
|
+
};
|
|
26138
|
+
await writeFile(join(projectPath, "packages/ui/tsconfig.json"), JSON.stringify(uiTsconfig, null, 2));
|
|
26139
|
+
await ensureDirectory(join(projectPath, "apps/web/src/components"));
|
|
26140
|
+
await ensureDirectory(join(projectPath, "apps/web/src/lib"));
|
|
26141
|
+
const webComponentsJson = {
|
|
26142
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
26143
|
+
style,
|
|
26144
|
+
rsc: true,
|
|
26145
|
+
tsx: true,
|
|
26146
|
+
tailwind: {
|
|
26147
|
+
config: "",
|
|
26148
|
+
css: "../../packages/ui/src/styles/globals.css",
|
|
26149
|
+
baseColor,
|
|
26150
|
+
cssVariables: true
|
|
26151
|
+
},
|
|
26152
|
+
iconLibrary: "lucide",
|
|
26153
|
+
aliases: {
|
|
26154
|
+
components: "@/components",
|
|
26155
|
+
hooks: "@/hooks",
|
|
26156
|
+
lib: "@/lib",
|
|
26157
|
+
utils: "@workspace/ui/lib/utils",
|
|
26158
|
+
ui: "@workspace/ui/components"
|
|
26159
|
+
}
|
|
26160
|
+
};
|
|
26161
|
+
await writeFile(join(projectPath, "apps/web/components.json"), JSON.stringify(webComponentsJson, null, 2));
|
|
26162
|
+
const webGlobalsCssPath = join(projectPath, "apps/web/src/app/globals.css");
|
|
26163
|
+
const webGlobalsCss = `@import "../../../packages/ui/src/styles/globals.css";
|
|
26164
|
+
`;
|
|
26165
|
+
await writeFile(webGlobalsCssPath, webGlobalsCss);
|
|
26166
|
+
const webPackageJsonPath = join(projectPath, "apps/web/package.json");
|
|
26167
|
+
let webPackageJson = {};
|
|
26168
|
+
try {
|
|
26169
|
+
webPackageJson = JSON.parse(await Bun.file(webPackageJsonPath).text());
|
|
26170
|
+
} catch {}
|
|
26171
|
+
if (webPackageJson.dependencies) {
|
|
26172
|
+
webPackageJson.dependencies[uiPackageName] = "workspace:*";
|
|
26173
|
+
await writeFile(webPackageJsonPath, JSON.stringify(webPackageJson, null, 2));
|
|
26174
|
+
}
|
|
26175
|
+
await ensureDirectory(join(projectPath, "apps/platform/src/components"));
|
|
26176
|
+
await ensureDirectory(join(projectPath, "apps/platform/src/lib"));
|
|
26177
|
+
const platformComponentsJson = {
|
|
26178
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
26179
|
+
style,
|
|
26180
|
+
rsc: true,
|
|
26181
|
+
tsx: true,
|
|
26182
|
+
tailwind: {
|
|
26183
|
+
config: "",
|
|
26184
|
+
css: "../../packages/ui/src/styles/globals.css",
|
|
26185
|
+
baseColor,
|
|
26186
|
+
cssVariables: true
|
|
26187
|
+
},
|
|
26188
|
+
iconLibrary: "lucide",
|
|
26189
|
+
aliases: {
|
|
26190
|
+
components: "@/components",
|
|
26191
|
+
hooks: "@/hooks",
|
|
26192
|
+
lib: "@/lib",
|
|
26193
|
+
utils: "@workspace/ui/lib/utils",
|
|
26194
|
+
ui: "@workspace/ui/components"
|
|
26195
|
+
}
|
|
26196
|
+
};
|
|
26197
|
+
await writeFile(join(projectPath, "apps/platform/components.json"), JSON.stringify(platformComponentsJson, null, 2));
|
|
26198
|
+
const platformGlobalsCssPath = join(projectPath, "apps/platform/src/app/globals.css");
|
|
26199
|
+
const platformGlobalsCss = `@import "../../../packages/ui/src/styles/globals.css";
|
|
26200
|
+
`;
|
|
26201
|
+
await writeFile(platformGlobalsCssPath, platformGlobalsCss);
|
|
26202
|
+
const platformPackageJsonPath = join(projectPath, "apps/platform/package.json");
|
|
26203
|
+
let platformPackageJson = {};
|
|
26204
|
+
try {
|
|
26205
|
+
platformPackageJson = JSON.parse(await Bun.file(platformPackageJsonPath).text());
|
|
26206
|
+
} catch {}
|
|
26207
|
+
if (platformPackageJson.dependencies) {
|
|
26208
|
+
platformPackageJson.dependencies[uiPackageName] = "workspace:*";
|
|
26209
|
+
await writeFile(platformPackageJsonPath, JSON.stringify(platformPackageJson, null, 2));
|
|
26210
|
+
}
|
|
26211
|
+
const updateAppTailwindConfig = async (appPath) => {
|
|
26212
|
+
const tailwindConfigPath = join(projectPath, appPath, "tailwind.config.ts");
|
|
26213
|
+
let tailwindConfig = "";
|
|
26214
|
+
try {
|
|
26215
|
+
tailwindConfig = await Bun.file(tailwindConfigPath).text();
|
|
26216
|
+
} catch {}
|
|
26217
|
+
const shadcnTheme = ` theme: {
|
|
26218
|
+
extend: {
|
|
26219
|
+
colors: {
|
|
26220
|
+
border: "hsl(var(--border))",
|
|
26221
|
+
input: "hsl(var(--input))",
|
|
26222
|
+
ring: "hsl(var(--ring))",
|
|
26223
|
+
background: "hsl(var(--background))",
|
|
26224
|
+
foreground: "hsl(var(--foreground))",
|
|
26225
|
+
primary: {
|
|
26226
|
+
DEFAULT: "hsl(var(--primary))",
|
|
26227
|
+
foreground: "hsl(var(--primary-foreground))",
|
|
26228
|
+
},
|
|
26229
|
+
secondary: {
|
|
26230
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
26231
|
+
foreground: "hsl(var(--secondary-foreground))",
|
|
26232
|
+
},
|
|
26233
|
+
destructive: {
|
|
26234
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
26235
|
+
foreground: "hsl(var(--destructive-foreground))",
|
|
26236
|
+
},
|
|
26237
|
+
muted: {
|
|
26238
|
+
DEFAULT: "hsl(var(--muted))",
|
|
26239
|
+
foreground: "hsl(var(--muted-foreground))",
|
|
26240
|
+
},
|
|
26241
|
+
accent: {
|
|
26242
|
+
DEFAULT: "hsl(var(--accent))",
|
|
26243
|
+
foreground: "hsl(var(--accent-foreground))",
|
|
26244
|
+
},
|
|
26245
|
+
popover: {
|
|
26246
|
+
DEFAULT: "hsl(var(--popover))",
|
|
26247
|
+
foreground: "hsl(var(--popover-foreground))",
|
|
26248
|
+
},
|
|
26249
|
+
card: {
|
|
26250
|
+
DEFAULT: "hsl(var(--card))",
|
|
26251
|
+
foreground: "hsl(var(--card-foreground))",
|
|
26252
|
+
},
|
|
26253
|
+
},
|
|
26254
|
+
borderRadius: {
|
|
26255
|
+
lg: "var(--radius)",
|
|
26256
|
+
md: "calc(var(--radius) - 2px)",
|
|
26257
|
+
sm: "calc(var(--radius) - 4px)",
|
|
26258
|
+
},
|
|
26259
|
+
},
|
|
26260
|
+
},`;
|
|
26261
|
+
if (tailwindConfig && !tailwindConfig.includes("hsl(var(--background))")) {
|
|
26262
|
+
if (tailwindConfig.includes("theme:")) {
|
|
26263
|
+
const updatedConfig = tailwindConfig.replace(/theme:\s*\{[^}]*\}/s, shadcnTheme.trim());
|
|
26264
|
+
await writeFile(tailwindConfigPath, updatedConfig);
|
|
26265
|
+
} else {
|
|
26266
|
+
const updatedConfig = tailwindConfig.replace(/(\s*)(plugins:.*?)(\n\s*\};)/s, `$1$2$1${shadcnTheme}$3`);
|
|
26267
|
+
await writeFile(tailwindConfigPath, updatedConfig);
|
|
26268
|
+
}
|
|
26269
|
+
} else if (!tailwindConfig) {
|
|
26270
|
+
const newTailwindConfig = `import type { Config } from 'tailwindcss';
|
|
26271
|
+
|
|
26272
|
+
const config: Config = {
|
|
26273
|
+
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
|
|
26274
|
+
theme: {
|
|
26275
|
+
extend: {
|
|
26276
|
+
colors: {
|
|
26277
|
+
border: "hsl(var(--border))",
|
|
26278
|
+
input: "hsl(var(--input))",
|
|
26279
|
+
ring: "hsl(var(--ring))",
|
|
26280
|
+
background: "hsl(var(--background))",
|
|
26281
|
+
foreground: "hsl(var(--foreground))",
|
|
26282
|
+
primary: {
|
|
26283
|
+
DEFAULT: "hsl(var(--primary))",
|
|
26284
|
+
foreground: "hsl(var(--primary-foreground))",
|
|
26285
|
+
},
|
|
26286
|
+
secondary: {
|
|
26287
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
26288
|
+
foreground: "hsl(var(--secondary-foreground))",
|
|
26289
|
+
},
|
|
26290
|
+
destructive: {
|
|
26291
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
26292
|
+
foreground: "hsl(var(--destructive-foreground))",
|
|
26293
|
+
},
|
|
26294
|
+
muted: {
|
|
26295
|
+
DEFAULT: "hsl(var(--muted))",
|
|
26296
|
+
foreground: "hsl(var(--muted-foreground))",
|
|
26297
|
+
},
|
|
26298
|
+
accent: {
|
|
26299
|
+
DEFAULT: "hsl(var(--accent))",
|
|
26300
|
+
foreground: "hsl(var(--accent-foreground))",
|
|
26301
|
+
},
|
|
26302
|
+
popover: {
|
|
26303
|
+
DEFAULT: "hsl(var(--popover))",
|
|
26304
|
+
foreground: "hsl(var(--popover-foreground))",
|
|
26305
|
+
},
|
|
26306
|
+
card: {
|
|
26307
|
+
DEFAULT: "hsl(var(--card))",
|
|
26308
|
+
foreground: "hsl(var(--card-foreground))",
|
|
26309
|
+
},
|
|
26310
|
+
},
|
|
26311
|
+
borderRadius: {
|
|
26312
|
+
lg: "var(--radius)",
|
|
26313
|
+
md: "calc(var(--radius) - 2px)",
|
|
26314
|
+
sm: "calc(var(--radius) - 4px)",
|
|
26315
|
+
},
|
|
26316
|
+
},
|
|
26317
|
+
},
|
|
26318
|
+
plugins: [],
|
|
26319
|
+
};
|
|
26320
|
+
|
|
26321
|
+
export default config;
|
|
26322
|
+
`;
|
|
26323
|
+
await writeFile(tailwindConfigPath, newTailwindConfig);
|
|
26324
|
+
}
|
|
26325
|
+
};
|
|
26326
|
+
await updateAppTailwindConfig("apps/web");
|
|
26327
|
+
await updateAppTailwindConfig("apps/platform");
|
|
26328
|
+
const rootPackageJsonPath = join(projectPath, "package.json");
|
|
26329
|
+
let rootPackageJson = {};
|
|
26330
|
+
try {
|
|
26331
|
+
rootPackageJson = JSON.parse(await Bun.file(rootPackageJsonPath).text());
|
|
26332
|
+
} catch {}
|
|
26333
|
+
if (rootPackageJson.catalog) {
|
|
26334
|
+
rootPackageJson.catalog["lucide-react"] = "^0.468.0";
|
|
26335
|
+
await writeFile(rootPackageJsonPath, JSON.stringify(rootPackageJson, null, 2));
|
|
26336
|
+
}
|
|
26337
|
+
await createShadcnExample(join(projectPath, "apps/web"), true);
|
|
26338
|
+
await createShadcnExample(join(projectPath, "apps/platform"), true);
|
|
26339
|
+
await createShadcnDocs(join(projectPath, "packages/ui"), true, context);
|
|
26340
|
+
}
|
|
26341
|
+
|
|
25077
26342
|
// ../templates/src/builders/web.ts
|
|
25078
26343
|
async function buildWebPreset(projectPath, context) {
|
|
25079
26344
|
await ensureDirectory(join(projectPath, "src/app"));
|
|
@@ -25205,6 +26470,9 @@ export default config;
|
|
|
25205
26470
|
if (context.cicd) {
|
|
25206
26471
|
await setupGitHubActions(projectPath, context);
|
|
25207
26472
|
}
|
|
26473
|
+
if (context.uiLibrary === "shadcn" && context.cssFramework === "tailwind") {
|
|
26474
|
+
await setupShadcnWeb(projectPath, context);
|
|
26475
|
+
}
|
|
25208
26476
|
}
|
|
25209
26477
|
// ../templates/src/builders/api.ts
|
|
25210
26478
|
init_dist();
|
|
@@ -25252,7 +26520,114 @@ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/${context.projectName
|
|
|
25252
26520
|
`;
|
|
25253
26521
|
await writeFile(join(projectPath, ".env.example"), envExample);
|
|
25254
26522
|
}
|
|
25255
|
-
async function
|
|
26523
|
+
async function setupSupabaseOnly(projectPath, context, isMonorepo = false) {
|
|
26524
|
+
const dbPath = isMonorepo ? join(projectPath, "packages/db") : join(projectPath, "src/db");
|
|
26525
|
+
await ensureDirectory(dbPath);
|
|
26526
|
+
const features = context.supabaseFeatures || ["auth", "storage", "realtime", "database"];
|
|
26527
|
+
const hasAuth = features.includes("auth");
|
|
26528
|
+
const hasStorage = features.includes("storage");
|
|
26529
|
+
const hasRealtime = features.includes("realtime");
|
|
26530
|
+
const hasEdgeFunctions = features.includes("edge-functions");
|
|
26531
|
+
const hasDatabase = features.includes("database");
|
|
26532
|
+
const clientContent = `import { createClient } from '@supabase/supabase-js';
|
|
26533
|
+
|
|
26534
|
+
// Supabase client
|
|
26535
|
+
export const supabase = createClient(
|
|
26536
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
26537
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
26538
|
+
{
|
|
26539
|
+
auth: {
|
|
26540
|
+
autoRefreshToken: true,
|
|
26541
|
+
persistSession: true,
|
|
26542
|
+
detectSessionInUrl: true,
|
|
26543
|
+
},
|
|
26544
|
+
}
|
|
26545
|
+
);
|
|
26546
|
+
|
|
26547
|
+
${hasAuth ? `// Auth helpers
|
|
26548
|
+
export const auth = supabase.auth;` : ""}
|
|
26549
|
+
|
|
26550
|
+
${hasStorage ? `// Storage helpers
|
|
26551
|
+
export const storage = supabase.storage;` : ""}
|
|
26552
|
+
|
|
26553
|
+
${hasRealtime ? `// Realtime helpers
|
|
26554
|
+
export const realtime = supabase.realtime;` : ""}
|
|
26555
|
+
|
|
26556
|
+
${hasEdgeFunctions ? `// Edge Functions helpers
|
|
26557
|
+
export const functions = supabase.functions;` : ""}
|
|
26558
|
+
|
|
26559
|
+
${hasDatabase ? `// Database helpers (using Supabase client directly)
|
|
26560
|
+
export const db = supabase.from;` : ""}
|
|
26561
|
+
`;
|
|
26562
|
+
await writeFile(join(dbPath, "index.ts"), clientContent);
|
|
26563
|
+
const examplesContent = `// Supabase usage examples
|
|
26564
|
+
import { supabase${hasAuth ? ", auth" : ""}${hasStorage ? ", storage" : ""}${hasRealtime ? ", realtime" : ""}${hasEdgeFunctions ? ", functions" : ""}${hasDatabase ? ", db" : ""} } from './index';
|
|
26565
|
+
|
|
26566
|
+
${hasAuth ? `// Auth example
|
|
26567
|
+
export async function signUp(email: string, password: string) {
|
|
26568
|
+
const { data, error } = await auth.signUp({
|
|
26569
|
+
email,
|
|
26570
|
+
password,
|
|
26571
|
+
});
|
|
26572
|
+
return { data, error };
|
|
26573
|
+
}
|
|
26574
|
+
|
|
26575
|
+
export async function signIn(email: string, password: string) {
|
|
26576
|
+
const { data, error } = await auth.signInWithPassword({
|
|
26577
|
+
email,
|
|
26578
|
+
password,
|
|
26579
|
+
});
|
|
26580
|
+
return { data, error };
|
|
26581
|
+
}
|
|
26582
|
+
|
|
26583
|
+
export async function signOut() {
|
|
26584
|
+
const { error } = await auth.signOut();
|
|
26585
|
+
return { error };
|
|
26586
|
+
}` : ""}
|
|
26587
|
+
|
|
26588
|
+
${hasStorage ? `// Storage example
|
|
26589
|
+
export async function uploadFile(bucket: string, path: string, file: File) {
|
|
26590
|
+
const { data, error } = await storage.from(bucket).upload(path, file);
|
|
26591
|
+
return { data, error };
|
|
26592
|
+
}
|
|
26593
|
+
|
|
26594
|
+
export function getPublicUrl(bucket: string, path: string) {
|
|
26595
|
+
const { data } = storage.from(bucket).getPublicUrl(path);
|
|
26596
|
+
return data.publicUrl;
|
|
26597
|
+
}` : ""}
|
|
26598
|
+
|
|
26599
|
+
${hasRealtime ? `// Realtime example
|
|
26600
|
+
export function subscribeToChannel(channel: string, callback: (payload: any) => void) {
|
|
26601
|
+
const channelInstance = realtime.channel(channel);
|
|
26602
|
+
channelInstance.on('postgres_changes', { event: '*', schema: 'public', table: '*' }, callback);
|
|
26603
|
+
channelInstance.subscribe();
|
|
26604
|
+
return channelInstance;
|
|
26605
|
+
}` : ""}
|
|
26606
|
+
|
|
26607
|
+
${hasEdgeFunctions ? `// Edge Functions example
|
|
26608
|
+
export async function invokeFunction(functionName: string, body?: any) {
|
|
26609
|
+
const { data, error } = await functions.invoke(functionName, { body });
|
|
26610
|
+
return { data, error };
|
|
26611
|
+
}` : ""}
|
|
26612
|
+
|
|
26613
|
+
${hasDatabase ? `// Database example (using Supabase client directly)
|
|
26614
|
+
export async function getUsers() {
|
|
26615
|
+
const { data, error } = await supabase.from('users').select('*');
|
|
26616
|
+
return { data, error };
|
|
26617
|
+
}` : ""}
|
|
26618
|
+
`;
|
|
26619
|
+
await writeFile(join(dbPath, "examples.ts"), examplesContent);
|
|
26620
|
+
if (hasEdgeFunctions) {
|
|
26621
|
+
await ensureDirectory(join(projectPath, "supabase/functions"));
|
|
26622
|
+
}
|
|
26623
|
+
const envExample = `# Supabase
|
|
26624
|
+
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
26625
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
26626
|
+
${hasDatabase ? "DATABASE_URL=postgresql://postgres:[password]@db.your-project.supabase.co:5432/postgres" : ""}
|
|
26627
|
+
`;
|
|
26628
|
+
await writeFile(join(projectPath, ".env.example"), envExample);
|
|
26629
|
+
}
|
|
26630
|
+
async function setupSupabaseDrizzle(projectPath, context, isMonorepo = false) {
|
|
25256
26631
|
const dbPath = isMonorepo ? join(projectPath, "packages/db") : join(projectPath, "src/db");
|
|
25257
26632
|
await ensureDirectory(join(dbPath, "schema"));
|
|
25258
26633
|
const drizzleConfig = `import { defineConfig } from 'drizzle-kit';
|
|
@@ -25267,6 +26642,12 @@ export default defineConfig({
|
|
|
25267
26642
|
});
|
|
25268
26643
|
`;
|
|
25269
26644
|
await writeFile(join(isMonorepo ? join(projectPath, "packages/db") : projectPath, "drizzle.config.ts"), drizzleConfig);
|
|
26645
|
+
const features = context.supabaseFeatures || ["auth", "storage", "realtime", "database"];
|
|
26646
|
+
const hasAuth = features.includes("auth");
|
|
26647
|
+
const hasStorage = features.includes("storage");
|
|
26648
|
+
const hasRealtime = features.includes("realtime");
|
|
26649
|
+
const hasEdgeFunctions = features.includes("edge-functions");
|
|
26650
|
+
const hasDatabase = features.includes("database");
|
|
25270
26651
|
const clientContent = `import { createClient } from '@supabase/supabase-js';
|
|
25271
26652
|
import { drizzle } from 'drizzle-orm/postgres-js';
|
|
25272
26653
|
import postgres from 'postgres';
|
|
@@ -25275,14 +26656,95 @@ import * as schema from './schema';
|
|
|
25275
26656
|
// Supabase client for auth, storage, realtime
|
|
25276
26657
|
export const supabase = createClient(
|
|
25277
26658
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
25278
|
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
|
|
26659
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
26660
|
+
{
|
|
26661
|
+
auth: {
|
|
26662
|
+
autoRefreshToken: true,
|
|
26663
|
+
persistSession: true,
|
|
26664
|
+
detectSessionInUrl: true,
|
|
26665
|
+
},
|
|
26666
|
+
}
|
|
25279
26667
|
);
|
|
25280
26668
|
|
|
26669
|
+
${hasAuth ? `// Auth helpers
|
|
26670
|
+
export const auth = supabase.auth;` : ""}
|
|
26671
|
+
|
|
26672
|
+
${hasStorage ? `// Storage helpers
|
|
26673
|
+
export const storage = supabase.storage;` : ""}
|
|
26674
|
+
|
|
26675
|
+
${hasRealtime ? `// Realtime helpers
|
|
26676
|
+
export const realtime = supabase.realtime;` : ""}
|
|
26677
|
+
|
|
26678
|
+
${hasEdgeFunctions ? `// Edge Functions helpers
|
|
26679
|
+
export const functions = supabase.functions;` : ""}
|
|
26680
|
+
|
|
25281
26681
|
// Drizzle client for type-safe database queries
|
|
25282
|
-
const queryClient = postgres(process.env.DATABASE_URL!);
|
|
25283
|
-
export const db = drizzle(queryClient, { schema })
|
|
26682
|
+
${hasDatabase ? `const queryClient = postgres(process.env.DATABASE_URL!);
|
|
26683
|
+
export const db = drizzle(queryClient, { schema });` : "// Database queries via Drizzle ORM"}
|
|
25284
26684
|
`;
|
|
25285
26685
|
await writeFile(join(dbPath, "index.ts"), clientContent);
|
|
26686
|
+
const examplesContent = `// Supabase + Drizzle usage examples
|
|
26687
|
+
import { supabase${hasAuth ? ", auth" : ""}${hasStorage ? ", storage" : ""}${hasRealtime ? ", realtime" : ""}${hasEdgeFunctions ? ", functions" : ""}, db } from './index';
|
|
26688
|
+
import { users } from './schema';
|
|
26689
|
+
import { eq } from 'drizzle-orm';
|
|
26690
|
+
|
|
26691
|
+
${hasAuth ? `// Auth example
|
|
26692
|
+
export async function signUp(email: string, password: string) {
|
|
26693
|
+
const { data, error } = await auth.signUp({
|
|
26694
|
+
email,
|
|
26695
|
+
password,
|
|
26696
|
+
});
|
|
26697
|
+
return { data, error };
|
|
26698
|
+
}
|
|
26699
|
+
|
|
26700
|
+
export async function signIn(email: string, password: string) {
|
|
26701
|
+
const { data, error } = await auth.signInWithPassword({
|
|
26702
|
+
email,
|
|
26703
|
+
password,
|
|
26704
|
+
});
|
|
26705
|
+
return { data, error };
|
|
26706
|
+
}
|
|
26707
|
+
|
|
26708
|
+
export async function signOut() {
|
|
26709
|
+
const { error } = await auth.signOut();
|
|
26710
|
+
return { error };
|
|
26711
|
+
}` : ""}
|
|
26712
|
+
|
|
26713
|
+
${hasStorage ? `// Storage example
|
|
26714
|
+
export async function uploadFile(bucket: string, path: string, file: File) {
|
|
26715
|
+
const { data, error } = await storage.from(bucket).upload(path, file);
|
|
26716
|
+
return { data, error };
|
|
26717
|
+
}
|
|
26718
|
+
|
|
26719
|
+
export function getPublicUrl(bucket: string, path: string) {
|
|
26720
|
+
const { data } = storage.from(bucket).getPublicUrl(path);
|
|
26721
|
+
return data.publicUrl;
|
|
26722
|
+
}` : ""}
|
|
26723
|
+
|
|
26724
|
+
${hasRealtime ? `// Realtime example
|
|
26725
|
+
export function subscribeToChannel(channel: string, callback: (payload: any) => void) {
|
|
26726
|
+
const channelInstance = realtime.channel(channel);
|
|
26727
|
+
channelInstance.on('postgres_changes', { event: '*', schema: 'public', table: '*' }, callback);
|
|
26728
|
+
channelInstance.subscribe();
|
|
26729
|
+
return channelInstance;
|
|
26730
|
+
}` : ""}
|
|
26731
|
+
|
|
26732
|
+
${hasEdgeFunctions ? `// Edge Functions example
|
|
26733
|
+
export async function invokeFunction(functionName: string, body?: any) {
|
|
26734
|
+
const { data, error } = await functions.invoke(functionName, { body });
|
|
26735
|
+
return { data, error };
|
|
26736
|
+
}` : ""}
|
|
26737
|
+
|
|
26738
|
+
${hasDatabase ? `// Database example (using Drizzle ORM)
|
|
26739
|
+
export async function getUsers() {
|
|
26740
|
+
return await db.select().from(users);
|
|
26741
|
+
}
|
|
26742
|
+
|
|
26743
|
+
export async function getUserById(id: string) {
|
|
26744
|
+
return await db.select().from(users).where(eq(users.id, id));
|
|
26745
|
+
}` : ""}
|
|
26746
|
+
`;
|
|
26747
|
+
await writeFile(join(dbPath, "examples.ts"), examplesContent);
|
|
25286
26748
|
const schemaContent = `import { pgTable, text, timestamp, uuid, boolean } from 'drizzle-orm/pg-core';
|
|
25287
26749
|
|
|
25288
26750
|
export const users = pgTable('users', {
|
|
@@ -25306,10 +26768,13 @@ export const profiles = pgTable('profiles', {
|
|
|
25306
26768
|
`;
|
|
25307
26769
|
await writeFile(join(dbPath, "schema/index.ts"), schemaContent);
|
|
25308
26770
|
await ensureDirectory(join(projectPath, "supabase/migrations"));
|
|
26771
|
+
if (hasEdgeFunctions) {
|
|
26772
|
+
await ensureDirectory(join(projectPath, "supabase/functions"));
|
|
26773
|
+
}
|
|
25309
26774
|
const envExample = `# Supabase
|
|
25310
26775
|
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
25311
26776
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
25312
|
-
DATABASE_URL=postgresql://postgres:[password]@db.your-project.supabase.co:5432/postgres
|
|
26777
|
+
${hasDatabase ? "DATABASE_URL=postgresql://postgres:[password]@db.your-project.supabase.co:5432/postgres" : ""}
|
|
25313
26778
|
`;
|
|
25314
26779
|
await writeFile(join(projectPath, ".env.example"), envExample);
|
|
25315
26780
|
}
|
|
@@ -25369,6 +26834,10 @@ function getDatabaseDependencies(databaseType) {
|
|
|
25369
26834
|
postgres: "^3.4.5"
|
|
25370
26835
|
};
|
|
25371
26836
|
case "supabase":
|
|
26837
|
+
return {
|
|
26838
|
+
"@supabase/supabase-js": "^2.48.1"
|
|
26839
|
+
};
|
|
26840
|
+
case "supabase-drizzle":
|
|
25372
26841
|
return {
|
|
25373
26842
|
"@supabase/supabase-js": "^2.48.1",
|
|
25374
26843
|
"drizzle-orm": "^0.38.0",
|
|
@@ -25555,7 +27024,9 @@ coverage = true
|
|
|
25555
27024
|
if (context.database === "postgres-drizzle") {
|
|
25556
27025
|
await setupPostgresDrizzle(projectPath, context, false);
|
|
25557
27026
|
} else if (context.database === "supabase") {
|
|
25558
|
-
await
|
|
27027
|
+
await setupSupabaseOnly(projectPath, context, false);
|
|
27028
|
+
} else if (context.database === "supabase-drizzle") {
|
|
27029
|
+
await setupSupabaseDrizzle(projectPath, context, false);
|
|
25559
27030
|
} else if (context.database === "sqlite-drizzle") {
|
|
25560
27031
|
await setupSQLiteDrizzle(projectPath, context, false);
|
|
25561
27032
|
}
|
|
@@ -25619,6 +27090,7 @@ async function buildFullPreset(projectPath, context) {
|
|
|
25619
27090
|
clsx: "^2.1.1",
|
|
25620
27091
|
"tailwind-merge": "^3.3.1",
|
|
25621
27092
|
"iconoir-react": "^7.11.0",
|
|
27093
|
+
"lucide-react": "^0.468.0",
|
|
25622
27094
|
"@biomejs/biome": "^2.3.0",
|
|
25623
27095
|
ultracite: "^6.0.1",
|
|
25624
27096
|
vitest: "^2.0.0",
|
|
@@ -26138,14 +27610,21 @@ Built with \u2764\uFE0F using Bun monorepo features
|
|
|
26138
27610
|
main: "./src/index.ts",
|
|
26139
27611
|
types: "./src/index.ts",
|
|
26140
27612
|
dependencies: context.database === "supabase" ? {
|
|
27613
|
+
"@supabase/supabase-js": "catalog:"
|
|
27614
|
+
} : context.database === "supabase-drizzle" ? {
|
|
26141
27615
|
"@supabase/supabase-js": "catalog:",
|
|
26142
27616
|
"drizzle-orm": "catalog:",
|
|
26143
27617
|
postgres: "catalog:"
|
|
26144
|
-
} : {
|
|
27618
|
+
} : context.database === "postgres-drizzle" ? {
|
|
27619
|
+
"drizzle-orm": "catalog:",
|
|
27620
|
+
postgres: "catalog:"
|
|
27621
|
+
} : context.database === "sqlite-drizzle" ? {
|
|
26145
27622
|
"drizzle-orm": "catalog:"
|
|
26146
|
-
},
|
|
27623
|
+
} : {},
|
|
26147
27624
|
devDependencies: {
|
|
26148
|
-
"drizzle-
|
|
27625
|
+
...context.database === "postgres-drizzle" || context.database === "supabase-drizzle" || context.database === "sqlite-drizzle" ? {
|
|
27626
|
+
"drizzle-kit": "catalog:"
|
|
27627
|
+
} : {},
|
|
26149
27628
|
"@types/bun": "latest",
|
|
26150
27629
|
typescript: "catalog:"
|
|
26151
27630
|
}
|
|
@@ -26154,7 +27633,9 @@ Built with \u2764\uFE0F using Bun monorepo features
|
|
|
26154
27633
|
if (context.database === "postgres-drizzle") {
|
|
26155
27634
|
await setupPostgresDrizzle(dbPackagePath, context, true);
|
|
26156
27635
|
} else if (context.database === "supabase") {
|
|
26157
|
-
await
|
|
27636
|
+
await setupSupabaseOnly(dbPackagePath, context, true);
|
|
27637
|
+
} else if (context.database === "supabase-drizzle") {
|
|
27638
|
+
await setupSupabaseDrizzle(dbPackagePath, context, true);
|
|
26158
27639
|
} else if (context.database === "sqlite-drizzle") {
|
|
26159
27640
|
await setupSQLiteDrizzle(dbPackagePath, context, true);
|
|
26160
27641
|
}
|
|
@@ -26180,7 +27661,7 @@ services:
|
|
|
26180
27661
|
- "3000:3000"
|
|
26181
27662
|
environment:
|
|
26182
27663
|
- NODE_ENV=production
|
|
26183
|
-
${context.database === "supabase" ? "- NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}\n - NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}" : ""}
|
|
27664
|
+
${context.database === "supabase" || context.database === "supabase-drizzle" ? "- NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}\n - NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}" : ""}
|
|
26184
27665
|
restart: unless-stopped
|
|
26185
27666
|
|
|
26186
27667
|
platform:
|
|
@@ -26191,7 +27672,7 @@ services:
|
|
|
26191
27672
|
- "3001:3000"
|
|
26192
27673
|
environment:
|
|
26193
27674
|
- NODE_ENV=production
|
|
26194
|
-
${context.database === "supabase" ? "- NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}\n - NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}" : ""}
|
|
27675
|
+
${context.database === "supabase" || context.database === "supabase-drizzle" ? "- NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}\n - NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}" : ""}
|
|
26195
27676
|
restart: unless-stopped
|
|
26196
27677
|
|
|
26197
27678
|
api:
|
|
@@ -26228,6 +27709,9 @@ ${context.database && context.database !== "none" && context.database !== "supab
|
|
|
26228
27709
|
if (context.cicd) {
|
|
26229
27710
|
await setupGitHubActions(projectPath, context);
|
|
26230
27711
|
}
|
|
27712
|
+
if (context.uiLibrary === "shadcn" && context.cssFramework === "tailwind") {
|
|
27713
|
+
await setupShadcnMonorepo(projectPath, context);
|
|
27714
|
+
}
|
|
26231
27715
|
}
|
|
26232
27716
|
// ../templates/src/builders/workspace.ts
|
|
26233
27717
|
init_dist();
|
|
@@ -26508,7 +27992,7 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26508
27992
|
throw new Error("Project name is required in non-interactive mode. " + "Provide it via BUNKIT_PROJECT_NAME env var or --name flag.");
|
|
26509
27993
|
}
|
|
26510
27994
|
projectName = await he({
|
|
26511
|
-
message: "\uD83D\uDCE6
|
|
27995
|
+
message: "\uD83D\uDCE6 Project name",
|
|
26512
27996
|
placeholder: "my-awesome-project",
|
|
26513
27997
|
validate: (value) => {
|
|
26514
27998
|
const result = validateProjectName(value);
|
|
@@ -26532,27 +28016,27 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26532
28016
|
throw new Error("Preset is required in non-interactive mode. " + "Provide it via BUNKIT_PRESET env var or --preset flag.");
|
|
26533
28017
|
}
|
|
26534
28018
|
preset = await ve({
|
|
26535
|
-
message: "\uD83C\uDFA8
|
|
28019
|
+
message: "\uD83C\uDFA8 Select project preset",
|
|
26536
28020
|
options: [
|
|
26537
28021
|
{
|
|
26538
28022
|
value: "minimal",
|
|
26539
28023
|
label: "\u26A1 Minimal",
|
|
26540
|
-
hint: "Single
|
|
28024
|
+
hint: "Single-file project, clean start - perfect for CLIs and scripts"
|
|
26541
28025
|
},
|
|
26542
28026
|
{
|
|
26543
28027
|
value: "web",
|
|
26544
|
-
label: "\uD83C\uDF10 Web
|
|
26545
|
-
hint: "Next.js 16 + React 19 -
|
|
28028
|
+
label: "\uD83C\uDF10 Web Application",
|
|
28029
|
+
hint: "Next.js 16 + React 19 + Tailwind CSS 4 - production-ready web app"
|
|
26546
28030
|
},
|
|
26547
28031
|
{
|
|
26548
28032
|
value: "api",
|
|
26549
28033
|
label: "\uD83D\uDE80 API Server",
|
|
26550
|
-
hint: "Hono + Bun.serve() - ultra-fast REST API"
|
|
28034
|
+
hint: "Hono 4 + Bun.serve() - ultra-fast REST API with native HMR"
|
|
26551
28035
|
},
|
|
26552
28036
|
{
|
|
26553
28037
|
value: "full",
|
|
26554
28038
|
label: "\uD83D\uDCE6 Full-Stack Monorepo",
|
|
26555
|
-
hint: "Web +
|
|
28039
|
+
hint: "Web + API + shared packages - enterprise-grade SaaS architecture"
|
|
26556
28040
|
}
|
|
26557
28041
|
]
|
|
26558
28042
|
});
|
|
@@ -26565,27 +28049,32 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26565
28049
|
if (!database && (preset === "api" || preset === "full")) {
|
|
26566
28050
|
if (!isNonInteractive) {
|
|
26567
28051
|
database = await ve({
|
|
26568
|
-
message: "\uD83D\uDDC4\uFE0F Database
|
|
28052
|
+
message: "\uD83D\uDDC4\uFE0F Database configuration",
|
|
26569
28053
|
options: [
|
|
26570
28054
|
{
|
|
26571
28055
|
value: "postgres-drizzle",
|
|
26572
28056
|
label: "PostgreSQL + Drizzle ORM",
|
|
26573
|
-
hint: "Production-ready
|
|
28057
|
+
hint: "Production-ready PostgreSQL with type-safe Drizzle ORM queries"
|
|
26574
28058
|
},
|
|
26575
28059
|
{
|
|
26576
28060
|
value: "supabase",
|
|
26577
|
-
label: "Supabase",
|
|
26578
|
-
hint: "
|
|
28061
|
+
label: "Supabase (Client Only)",
|
|
28062
|
+
hint: "Supabase JS client only - Auth, Storage, Realtime without Drizzle ORM"
|
|
28063
|
+
},
|
|
28064
|
+
{
|
|
28065
|
+
value: "supabase-drizzle",
|
|
28066
|
+
label: "Supabase + Drizzle ORM",
|
|
28067
|
+
hint: "Full Supabase stack with Drizzle ORM for type-safe database queries"
|
|
26579
28068
|
},
|
|
26580
28069
|
{
|
|
26581
28070
|
value: "sqlite-drizzle",
|
|
26582
28071
|
label: "SQLite + Drizzle ORM",
|
|
26583
|
-
hint: "Local-first
|
|
28072
|
+
hint: "Local-first embedded database - perfect for prototypes and local development"
|
|
26584
28073
|
},
|
|
26585
28074
|
{
|
|
26586
28075
|
value: "none",
|
|
26587
28076
|
label: "None",
|
|
26588
|
-
hint: "
|
|
28077
|
+
hint: "Skip database setup - add later if needed"
|
|
26589
28078
|
}
|
|
26590
28079
|
]
|
|
26591
28080
|
});
|
|
@@ -26597,21 +28086,116 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26597
28086
|
database = "none";
|
|
26598
28087
|
}
|
|
26599
28088
|
}
|
|
28089
|
+
let supabasePreset;
|
|
28090
|
+
let supabaseFeatures;
|
|
28091
|
+
let supabaseWithDrizzle;
|
|
28092
|
+
if (database === "supabase" || database === "supabase-drizzle") {
|
|
28093
|
+
supabaseWithDrizzle = database === "supabase-drizzle";
|
|
28094
|
+
const presetEnv = process.env.BUNKIT_SUPABASE_PRESET;
|
|
28095
|
+
supabasePreset = presetEnv || options.supabasePreset;
|
|
28096
|
+
if (!supabasePreset && !isNonInteractive) {
|
|
28097
|
+
supabasePreset = await ve({
|
|
28098
|
+
message: "\uD83C\uDFAF Supabase configuration preset",
|
|
28099
|
+
options: [
|
|
28100
|
+
{
|
|
28101
|
+
value: "full-stack",
|
|
28102
|
+
label: "Full Stack (Recommended)",
|
|
28103
|
+
hint: "Complete Supabase setup - Auth, Storage, Realtime, and Database"
|
|
28104
|
+
},
|
|
28105
|
+
{
|
|
28106
|
+
value: "auth-only",
|
|
28107
|
+
label: "Auth Only",
|
|
28108
|
+
hint: "Authentication only - perfect for simple apps with external data"
|
|
28109
|
+
},
|
|
28110
|
+
{
|
|
28111
|
+
value: "database-only",
|
|
28112
|
+
label: "Database Only",
|
|
28113
|
+
hint: "PostgreSQL database access only - no Auth, Storage, or Realtime"
|
|
28114
|
+
},
|
|
28115
|
+
{
|
|
28116
|
+
value: "custom",
|
|
28117
|
+
label: "Custom",
|
|
28118
|
+
hint: "Manually select Supabase features to include"
|
|
28119
|
+
}
|
|
28120
|
+
]
|
|
28121
|
+
});
|
|
28122
|
+
if (pD(supabasePreset)) {
|
|
28123
|
+
xe("Operation cancelled.");
|
|
28124
|
+
process.exit(0);
|
|
28125
|
+
}
|
|
28126
|
+
} else if (!supabasePreset) {
|
|
28127
|
+
supabasePreset = "full-stack";
|
|
28128
|
+
}
|
|
28129
|
+
if (supabasePreset === "full-stack") {
|
|
28130
|
+
supabaseFeatures = ["auth", "storage", "realtime", "database"];
|
|
28131
|
+
} else if (supabasePreset === "auth-only") {
|
|
28132
|
+
supabaseFeatures = ["auth"];
|
|
28133
|
+
} else if (supabasePreset === "database-only") {
|
|
28134
|
+
supabaseFeatures = ["database"];
|
|
28135
|
+
} else {
|
|
28136
|
+
const availableFeaturesEnv = process.env.BUNKIT_SUPABASE_FEATURES;
|
|
28137
|
+
let availableFeatures;
|
|
28138
|
+
if (availableFeaturesEnv) {
|
|
28139
|
+
availableFeatures = availableFeaturesEnv.split(",").map((f) => f.trim());
|
|
28140
|
+
} else if (options.supabaseFeatures) {
|
|
28141
|
+
availableFeatures = Array.isArray(options.supabaseFeatures) ? options.supabaseFeatures : String(options.supabaseFeatures).split(",").map((f) => f.trim());
|
|
28142
|
+
}
|
|
28143
|
+
if (!availableFeatures && !isNonInteractive) {
|
|
28144
|
+
const selectedFeatures = await fe({
|
|
28145
|
+
message: "\u2728 Select Supabase features to include",
|
|
28146
|
+
options: [
|
|
28147
|
+
{
|
|
28148
|
+
value: "auth",
|
|
28149
|
+
label: "Authentication",
|
|
28150
|
+
hint: "User authentication and authorization (sign up, sign in, sessions)"
|
|
28151
|
+
},
|
|
28152
|
+
{
|
|
28153
|
+
value: "storage",
|
|
28154
|
+
label: "Storage",
|
|
28155
|
+
hint: "File storage and CDN for images, documents, and media"
|
|
28156
|
+
},
|
|
28157
|
+
{
|
|
28158
|
+
value: "realtime",
|
|
28159
|
+
label: "Realtime",
|
|
28160
|
+
hint: "Real-time subscriptions and live updates via WebSockets"
|
|
28161
|
+
},
|
|
28162
|
+
{
|
|
28163
|
+
value: "edge-functions",
|
|
28164
|
+
label: "Edge Functions",
|
|
28165
|
+
hint: "Serverless functions deployed at the edge for low latency"
|
|
28166
|
+
},
|
|
28167
|
+
{
|
|
28168
|
+
value: "database",
|
|
28169
|
+
label: "Database",
|
|
28170
|
+
hint: "PostgreSQL database access via Supabase client"
|
|
28171
|
+
}
|
|
28172
|
+
]
|
|
28173
|
+
});
|
|
28174
|
+
if (pD(selectedFeatures)) {
|
|
28175
|
+
xe("Operation cancelled.");
|
|
28176
|
+
process.exit(0);
|
|
28177
|
+
}
|
|
28178
|
+
supabaseFeatures = selectedFeatures.length > 0 ? selectedFeatures : ["auth", "database"];
|
|
28179
|
+
} else {
|
|
28180
|
+
supabaseFeatures = availableFeatures || ["auth", "database"];
|
|
28181
|
+
}
|
|
28182
|
+
}
|
|
28183
|
+
}
|
|
26600
28184
|
let codeQuality = getOptionValue("BUNKIT_CODE_QUALITY", options.codeQuality, "ultracite");
|
|
26601
28185
|
if (!codeQuality) {
|
|
26602
28186
|
if (!isNonInteractive) {
|
|
26603
28187
|
codeQuality = await ve({
|
|
26604
|
-
message: "\uD83E\uDD16 Code quality
|
|
28188
|
+
message: "\uD83E\uDD16 Code quality tool",
|
|
26605
28189
|
options: [
|
|
26606
28190
|
{
|
|
26607
28191
|
value: "ultracite",
|
|
26608
28192
|
label: "Ultracite (Recommended)",
|
|
26609
|
-
hint: "AI-optimized Biome preset - syncs rules for Cursor, Claude, Windsurf"
|
|
28193
|
+
hint: "AI-optimized Biome preset - syncs rules for Cursor, Claude Code, Windsurf, Zed"
|
|
26610
28194
|
},
|
|
26611
28195
|
{
|
|
26612
28196
|
value: "biome",
|
|
26613
28197
|
label: "Biome",
|
|
26614
|
-
hint: "Standard Biome
|
|
28198
|
+
hint: "Standard Biome configuration - fast, reliable, zero-config linting and formatting"
|
|
26615
28199
|
}
|
|
26616
28200
|
]
|
|
26617
28201
|
});
|
|
@@ -26627,22 +28211,22 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26627
28211
|
if (!tsStrictness) {
|
|
26628
28212
|
if (!isNonInteractive) {
|
|
26629
28213
|
tsStrictness = await ve({
|
|
26630
|
-
message: "\uD83D\uDD12 TypeScript strictness
|
|
28214
|
+
message: "\uD83D\uDD12 TypeScript strictness level",
|
|
26631
28215
|
options: [
|
|
26632
28216
|
{
|
|
26633
28217
|
value: "strict",
|
|
26634
28218
|
label: "Strict (Recommended)",
|
|
26635
|
-
hint: "Maximum type safety - catches bugs early, prevents
|
|
28219
|
+
hint: "Maximum type safety - catches bugs early, prevents runtime errors"
|
|
26636
28220
|
},
|
|
26637
28221
|
{
|
|
26638
28222
|
value: "moderate",
|
|
26639
28223
|
label: "Moderate",
|
|
26640
|
-
hint: "Balanced - good safety without
|
|
28224
|
+
hint: "Balanced type checking - good safety without excessive strictness"
|
|
26641
28225
|
},
|
|
26642
28226
|
{
|
|
26643
28227
|
value: "loose",
|
|
26644
28228
|
label: "Loose",
|
|
26645
|
-
hint: "Minimal
|
|
28229
|
+
hint: "Minimal type checking - quick prototyping, easier migration from JavaScript"
|
|
26646
28230
|
}
|
|
26647
28231
|
]
|
|
26648
28232
|
});
|
|
@@ -26658,22 +28242,22 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26658
28242
|
if (!cssFramework && (preset === "web" || preset === "full")) {
|
|
26659
28243
|
if (!isNonInteractive) {
|
|
26660
28244
|
cssFramework = await ve({
|
|
26661
|
-
message: "\uD83C\uDFA8 CSS framework
|
|
28245
|
+
message: "\uD83C\uDFA8 CSS framework",
|
|
26662
28246
|
options: [
|
|
26663
28247
|
{
|
|
26664
28248
|
value: "tailwind",
|
|
26665
28249
|
label: "Tailwind CSS 4 (Recommended)",
|
|
26666
|
-
hint: "Utility-first
|
|
28250
|
+
hint: "Utility-first CSS framework - fast, modern, with OKLCH colors and @theme"
|
|
26667
28251
|
},
|
|
26668
28252
|
{
|
|
26669
28253
|
value: "vanilla",
|
|
26670
28254
|
label: "Vanilla CSS",
|
|
26671
|
-
hint: "Plain CSS files - full control, no framework"
|
|
28255
|
+
hint: "Plain CSS files - full control, no framework dependencies"
|
|
26672
28256
|
},
|
|
26673
28257
|
{
|
|
26674
28258
|
value: "css-modules",
|
|
26675
28259
|
label: "CSS Modules",
|
|
26676
|
-
hint: "Scoped CSS
|
|
28260
|
+
hint: "Scoped CSS with automatic class name generation - prevents style conflicts"
|
|
26677
28261
|
}
|
|
26678
28262
|
]
|
|
26679
28263
|
});
|
|
@@ -26689,17 +28273,17 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26689
28273
|
if (!uiLibrary && (preset === "web" || preset === "full") && cssFramework === "tailwind") {
|
|
26690
28274
|
if (!isNonInteractive) {
|
|
26691
28275
|
uiLibrary = await ve({
|
|
26692
|
-
message: "\uD83E\uDDE9 UI component library
|
|
28276
|
+
message: "\uD83E\uDDE9 UI component library",
|
|
26693
28277
|
options: [
|
|
26694
28278
|
{
|
|
26695
28279
|
value: "shadcn",
|
|
26696
28280
|
label: "shadcn/ui (Recommended)",
|
|
26697
|
-
hint: "64+ components,
|
|
28281
|
+
hint: "64+ accessible components, fully customizable, production-ready"
|
|
26698
28282
|
},
|
|
26699
28283
|
{
|
|
26700
28284
|
value: "none",
|
|
26701
28285
|
label: "None",
|
|
26702
|
-
hint: "
|
|
28286
|
+
hint: "Skip UI library - build custom components or add later"
|
|
26703
28287
|
}
|
|
26704
28288
|
]
|
|
26705
28289
|
});
|
|
@@ -26711,26 +28295,118 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26711
28295
|
uiLibrary = "shadcn";
|
|
26712
28296
|
}
|
|
26713
28297
|
}
|
|
28298
|
+
let shadcnStyle = getOptionValue("BUNKIT_SHADCN_STYLE", options.shadcnStyle);
|
|
28299
|
+
if (!shadcnStyle && uiLibrary === "shadcn") {
|
|
28300
|
+
if (!isNonInteractive) {
|
|
28301
|
+
shadcnStyle = await ve({
|
|
28302
|
+
message: "\uD83C\uDFA8 shadcn/ui component style",
|
|
28303
|
+
options: [
|
|
28304
|
+
{
|
|
28305
|
+
value: "new-york",
|
|
28306
|
+
label: "New York (Recommended)",
|
|
28307
|
+
hint: "Modern design aesthetic - rounded corners, subtle shadows, clean look"
|
|
28308
|
+
},
|
|
28309
|
+
{
|
|
28310
|
+
value: "default",
|
|
28311
|
+
label: "Default",
|
|
28312
|
+
hint: "Classic design aesthetic - sharper edges, higher contrast, traditional look"
|
|
28313
|
+
}
|
|
28314
|
+
]
|
|
28315
|
+
});
|
|
28316
|
+
if (pD(shadcnStyle)) {
|
|
28317
|
+
xe("Operation cancelled.");
|
|
28318
|
+
process.exit(0);
|
|
28319
|
+
}
|
|
28320
|
+
} else {
|
|
28321
|
+
shadcnStyle = "new-york";
|
|
28322
|
+
}
|
|
28323
|
+
}
|
|
28324
|
+
let shadcnBaseColor = getOptionValue("BUNKIT_SHADCN_BASE_COLOR", options.shadcnBaseColor);
|
|
28325
|
+
if (!shadcnBaseColor && uiLibrary === "shadcn") {
|
|
28326
|
+
if (!isNonInteractive) {
|
|
28327
|
+
shadcnBaseColor = await ve({
|
|
28328
|
+
message: "\uD83C\uDFA8 shadcn/ui base color theme",
|
|
28329
|
+
options: [
|
|
28330
|
+
{
|
|
28331
|
+
value: "zinc",
|
|
28332
|
+
label: "Zinc (Recommended)",
|
|
28333
|
+
hint: "Neutral gray palette - versatile, modern, works with any accent color"
|
|
28334
|
+
},
|
|
28335
|
+
{
|
|
28336
|
+
value: "neutral",
|
|
28337
|
+
label: "Neutral",
|
|
28338
|
+
hint: "Pure neutral palette - no color cast, perfect grayscale"
|
|
28339
|
+
},
|
|
28340
|
+
{
|
|
28341
|
+
value: "gray",
|
|
28342
|
+
label: "Gray",
|
|
28343
|
+
hint: "Warm gray palette - slightly warmer tone than zinc"
|
|
28344
|
+
},
|
|
28345
|
+
{
|
|
28346
|
+
value: "slate",
|
|
28347
|
+
label: "Slate",
|
|
28348
|
+
hint: "Cool gray palette - slightly bluer tone, modern and crisp"
|
|
28349
|
+
},
|
|
28350
|
+
{
|
|
28351
|
+
value: "stone",
|
|
28352
|
+
label: "Stone",
|
|
28353
|
+
hint: "Warm beige-gray palette - earthy, natural, organic feel"
|
|
28354
|
+
}
|
|
28355
|
+
]
|
|
28356
|
+
});
|
|
28357
|
+
if (pD(shadcnBaseColor)) {
|
|
28358
|
+
xe("Operation cancelled.");
|
|
28359
|
+
process.exit(0);
|
|
28360
|
+
}
|
|
28361
|
+
} else {
|
|
28362
|
+
shadcnBaseColor = "zinc";
|
|
28363
|
+
}
|
|
28364
|
+
}
|
|
28365
|
+
let shadcnRadius = getOptionValue("BUNKIT_SHADCN_RADIUS", options.shadcnRadius);
|
|
28366
|
+
if (!shadcnRadius && uiLibrary === "shadcn") {
|
|
28367
|
+
if (!isNonInteractive) {
|
|
28368
|
+
const radiusInput = await he({
|
|
28369
|
+
message: "\uD83D\uDCD0 Component border radius",
|
|
28370
|
+
placeholder: "0.625rem (default)",
|
|
28371
|
+
initialValue: "0.625rem",
|
|
28372
|
+
validate: (value) => {
|
|
28373
|
+
if (!value.trim()) {
|
|
28374
|
+
return "Radius cannot be empty";
|
|
28375
|
+
}
|
|
28376
|
+
if (!/^\d+(\.\d+)?(rem|px|em|%)$/.test(value.trim())) {
|
|
28377
|
+
return "Please enter a valid CSS value (e.g., 0.5rem, 8px)";
|
|
28378
|
+
}
|
|
28379
|
+
}
|
|
28380
|
+
});
|
|
28381
|
+
if (pD(radiusInput)) {
|
|
28382
|
+
xe("Operation cancelled.");
|
|
28383
|
+
process.exit(0);
|
|
28384
|
+
}
|
|
28385
|
+
shadcnRadius = radiusInput;
|
|
28386
|
+
} else {
|
|
28387
|
+
shadcnRadius = "0.625rem";
|
|
28388
|
+
}
|
|
28389
|
+
}
|
|
26714
28390
|
let testing = getOptionValue("BUNKIT_TESTING", options.testing, "bun-test");
|
|
26715
28391
|
if (!testing) {
|
|
26716
28392
|
if (!isNonInteractive) {
|
|
26717
28393
|
testing = await ve({
|
|
26718
|
-
message: "\uD83E\uDDEA Testing framework
|
|
28394
|
+
message: "\uD83E\uDDEA Testing framework",
|
|
26719
28395
|
options: [
|
|
26720
28396
|
{
|
|
26721
28397
|
value: "bun-test",
|
|
26722
28398
|
label: "Bun Test (Recommended)",
|
|
26723
|
-
hint: "Built-in
|
|
28399
|
+
hint: "Built-in testing framework - fast, Jest-compatible, zero configuration"
|
|
26724
28400
|
},
|
|
26725
28401
|
{
|
|
26726
28402
|
value: "vitest",
|
|
26727
28403
|
label: "Vitest",
|
|
26728
|
-
hint: "Vite-powered
|
|
28404
|
+
hint: "Vite-powered testing framework - fast, ESM-first, popular ecosystem choice"
|
|
26729
28405
|
},
|
|
26730
28406
|
{
|
|
26731
28407
|
value: "none",
|
|
26732
28408
|
label: "None",
|
|
26733
|
-
hint: "
|
|
28409
|
+
hint: "Skip testing setup - add testing framework later if needed"
|
|
26734
28410
|
}
|
|
26735
28411
|
]
|
|
26736
28412
|
});
|
|
@@ -26746,7 +28422,7 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26746
28422
|
if (docker === undefined) {
|
|
26747
28423
|
if (!isNonInteractive) {
|
|
26748
28424
|
docker = await ye({
|
|
26749
|
-
message: "\uD83D\uDC33
|
|
28425
|
+
message: "\uD83D\uDC33 Include Docker configuration",
|
|
26750
28426
|
initialValue: false
|
|
26751
28427
|
});
|
|
26752
28428
|
if (pD(docker)) {
|
|
@@ -26761,7 +28437,7 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26761
28437
|
if (cicd === undefined) {
|
|
26762
28438
|
if (!isNonInteractive) {
|
|
26763
28439
|
cicd = await ye({
|
|
26764
|
-
message: "\u2699\uFE0F
|
|
28440
|
+
message: "\u2699\uFE0F Include GitHub Actions CI/CD workflow",
|
|
26765
28441
|
initialValue: false
|
|
26766
28442
|
});
|
|
26767
28443
|
if (pD(cicd)) {
|
|
@@ -26776,7 +28452,7 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26776
28452
|
if (shouldInstall === undefined) {
|
|
26777
28453
|
if (!isNonInteractive) {
|
|
26778
28454
|
shouldInstall = await ye({
|
|
26779
|
-
message: "\uD83D\uDCE5 Install dependencies
|
|
28455
|
+
message: "\uD83D\uDCE5 Install dependencies after project creation",
|
|
26780
28456
|
initialValue: true
|
|
26781
28457
|
});
|
|
26782
28458
|
if (pD(shouldInstall)) {
|
|
@@ -26791,7 +28467,7 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26791
28467
|
if (shouldInitGit === undefined) {
|
|
26792
28468
|
if (!isNonInteractive) {
|
|
26793
28469
|
shouldInitGit = await ye({
|
|
26794
|
-
message: "\uD83D\uDD27 Initialize
|
|
28470
|
+
message: "\uD83D\uDD27 Initialize Git repository",
|
|
26795
28471
|
initialValue: true
|
|
26796
28472
|
});
|
|
26797
28473
|
if (pD(shouldInitGit)) {
|
|
@@ -26803,28 +28479,56 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26803
28479
|
}
|
|
26804
28480
|
}
|
|
26805
28481
|
if (!isNonInteractive) {
|
|
26806
|
-
|
|
26807
|
-
|
|
26808
|
-
`${source_default.bold("Project
|
|
28482
|
+
const configSummary = [
|
|
28483
|
+
"",
|
|
28484
|
+
`${source_default.bold.cyan("\uD83D\uDCE6 Project Configuration")}`,
|
|
28485
|
+
`${source_default.dim("\u2500".repeat(40))}`,
|
|
28486
|
+
`${source_default.bold("Project Name:")} ${source_default.cyan(projectName)}`,
|
|
26809
28487
|
`${source_default.bold("Preset:")} ${source_default.cyan(preset)}`,
|
|
26810
|
-
|
|
26811
|
-
|
|
26812
|
-
|
|
26813
|
-
|
|
26814
|
-
|
|
26815
|
-
|
|
26816
|
-
|
|
26817
|
-
|
|
28488
|
+
"",
|
|
28489
|
+
database && database !== "none" ? [
|
|
28490
|
+
`${source_default.bold.yellow("\uD83D\uDDC4\uFE0F Database")}`,
|
|
28491
|
+
` ${source_default.bold("Type:")} ${source_default.cyan(database)}`,
|
|
28492
|
+
(database === "supabase" || database === "supabase-drizzle") && supabasePreset ? ` ${source_default.bold("Preset:")} ${source_default.cyan(supabasePreset)}` : "",
|
|
28493
|
+
(database === "supabase" || database === "supabase-drizzle") && supabaseFeatures ? ` ${source_default.bold("Features:")} ${source_default.cyan(supabaseFeatures.join(", "))}` : ""
|
|
28494
|
+
].filter(Boolean).join(`
|
|
28495
|
+
`) : "",
|
|
28496
|
+
"",
|
|
28497
|
+
`${source_default.bold.yellow("\uD83D\uDEE0\uFE0F Development Tools")}`,
|
|
28498
|
+
` ${source_default.bold("Code Quality:")} ${source_default.cyan(codeQuality)}`,
|
|
28499
|
+
` ${source_default.bold("TypeScript:")} ${source_default.cyan(tsStrictness)}`,
|
|
28500
|
+
` ${source_default.bold("Testing:")} ${source_default.cyan(testing)}`,
|
|
28501
|
+
"",
|
|
28502
|
+
cssFramework ? [
|
|
28503
|
+
`${source_default.bold.yellow("\uD83C\uDFA8 Styling")}`,
|
|
28504
|
+
` ${source_default.bold("CSS Framework:")} ${source_default.cyan(cssFramework)}`,
|
|
28505
|
+
uiLibrary ? ` ${source_default.bold("UI Library:")} ${source_default.cyan(uiLibrary)}` : "",
|
|
28506
|
+
uiLibrary === "shadcn" && shadcnStyle ? ` ${source_default.bold(" Style:")} ${source_default.cyan(shadcnStyle)}` : "",
|
|
28507
|
+
uiLibrary === "shadcn" && shadcnBaseColor ? ` ${source_default.bold(" Base Color:")} ${source_default.cyan(shadcnBaseColor)}` : "",
|
|
28508
|
+
uiLibrary === "shadcn" && shadcnRadius ? ` ${source_default.bold(" Radius:")} ${source_default.cyan(shadcnRadius)}` : ""
|
|
28509
|
+
].filter(Boolean).join(`
|
|
28510
|
+
`) : "",
|
|
28511
|
+
"",
|
|
28512
|
+
docker || cicd ? [
|
|
28513
|
+
`${source_default.bold.yellow("\uD83D\uDE80 Deployment")}`,
|
|
28514
|
+
docker ? ` ${source_default.bold("Docker:")} ${source_default.green("\u2713 Enabled")}` : "",
|
|
28515
|
+
cicd ? ` ${source_default.bold("CI/CD:")} ${source_default.green("\u2713 Enabled")}` : ""
|
|
28516
|
+
].filter(Boolean).join(`
|
|
28517
|
+
`) : "",
|
|
28518
|
+
""
|
|
26818
28519
|
].filter(Boolean).join(`
|
|
26819
|
-
`)
|
|
26820
|
-
|
|
26821
|
-
|
|
28520
|
+
`);
|
|
28521
|
+
console.log(`
|
|
28522
|
+
` + boxen(configSummary, {
|
|
28523
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
28524
|
+
title: "\uD83D\uDCCB Configuration Summary",
|
|
26822
28525
|
titleAlignment: "left",
|
|
26823
28526
|
borderColor: "cyan",
|
|
26824
|
-
borderStyle: "round"
|
|
28527
|
+
borderStyle: "round",
|
|
28528
|
+
dimBorder: false
|
|
26825
28529
|
}));
|
|
26826
28530
|
const confirm = await ye({
|
|
26827
|
-
message: "
|
|
28531
|
+
message: "Confirm project configuration",
|
|
26828
28532
|
initialValue: true
|
|
26829
28533
|
});
|
|
26830
28534
|
if (pD(confirm) || !confirm) {
|
|
@@ -26832,8 +28536,9 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26832
28536
|
process.exit(0);
|
|
26833
28537
|
}
|
|
26834
28538
|
}
|
|
28539
|
+
console.log("");
|
|
26835
28540
|
const s = Y2();
|
|
26836
|
-
s.start("\uD83D\uDD28 Creating project structure
|
|
28541
|
+
s.start(`${source_default.cyan("\uD83D\uDD28")} Creating project structure...`);
|
|
26837
28542
|
try {
|
|
26838
28543
|
const config = {
|
|
26839
28544
|
name: projectName,
|
|
@@ -26850,12 +28555,18 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26850
28555
|
docker,
|
|
26851
28556
|
cicd,
|
|
26852
28557
|
envExample: true,
|
|
26853
|
-
pathAliases: true
|
|
28558
|
+
pathAliases: true,
|
|
28559
|
+
shadcnStyle,
|
|
28560
|
+
shadcnBaseColor,
|
|
28561
|
+
shadcnRadius,
|
|
28562
|
+
supabasePreset,
|
|
28563
|
+
supabaseFeatures,
|
|
28564
|
+
supabaseWithDrizzle
|
|
26854
28565
|
};
|
|
26855
28566
|
await createProject(config);
|
|
26856
28567
|
const projectPath = join(process.cwd(), config.path);
|
|
26857
28568
|
const context = createTemplateContext(config);
|
|
26858
|
-
s.message("\uD83D\uDCDD Generating files
|
|
28569
|
+
s.message(`${source_default.cyan("\uD83D\uDCDD")} Generating project files...`);
|
|
26859
28570
|
switch (preset) {
|
|
26860
28571
|
case "minimal":
|
|
26861
28572
|
await buildMinimalPreset(projectPath, context);
|
|
@@ -26871,18 +28582,22 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26871
28582
|
break;
|
|
26872
28583
|
}
|
|
26873
28584
|
if (database && database !== "none") {
|
|
26874
|
-
|
|
28585
|
+
const dbName = database === "postgres-drizzle" ? "PostgreSQL + Drizzle ORM" : database === "supabase" ? "Supabase (Client Only)" : database === "supabase-drizzle" ? "Supabase + Drizzle ORM" : database === "sqlite-drizzle" ? "SQLite + Drizzle ORM" : database;
|
|
28586
|
+
s.message(`${source_default.cyan("\uD83D\uDDC4\uFE0F")} Configuring ${dbName}...`);
|
|
28587
|
+
}
|
|
28588
|
+
if (uiLibrary === "shadcn") {
|
|
28589
|
+
s.message(`${source_default.cyan("\uD83C\uDFA8")} Setting up shadcn/ui components...`);
|
|
26875
28590
|
}
|
|
26876
28591
|
if (codeQuality === "ultracite") {
|
|
26877
|
-
s.message("\uD83E\uDD16
|
|
28592
|
+
s.message(`${source_default.cyan("\uD83E\uDD16")} Configuring Ultracite for AI editors...`);
|
|
26878
28593
|
}
|
|
26879
28594
|
if (docker) {
|
|
26880
|
-
s.message("\uD83D\uDC33
|
|
28595
|
+
s.message(`${source_default.cyan("\uD83D\uDC33")} Adding Docker configuration...`);
|
|
26881
28596
|
}
|
|
26882
28597
|
if (cicd) {
|
|
26883
|
-
s.message("\u2699\uFE0F Adding GitHub Actions
|
|
28598
|
+
s.message(`${source_default.cyan("\u2699\uFE0F")} Adding GitHub Actions CI/CD workflow...`);
|
|
26884
28599
|
}
|
|
26885
|
-
s.stop("\u2705 Project created
|
|
28600
|
+
s.stop(`${source_default.green("\u2705")} Project structure created successfully!`);
|
|
26886
28601
|
if (shouldInstall && preset !== "full") {
|
|
26887
28602
|
const additionalDeps = {};
|
|
26888
28603
|
if (database && database !== "none") {
|
|
@@ -26908,28 +28623,121 @@ async function enhancedInitCommand(options = {}) {
|
|
|
26908
28623
|
} else if (shouldInstall && preset === "full") {
|
|
26909
28624
|
await installDependencies(projectPath);
|
|
26910
28625
|
}
|
|
28626
|
+
if (shouldInstall && uiLibrary === "shadcn" && (preset === "web" || preset === "full")) {
|
|
28627
|
+
const componentSpinner = Y2();
|
|
28628
|
+
componentSpinner.start(`${source_default.cyan("\uD83E\uDDE9")} Installing default shadcn/ui components (button, card)...`);
|
|
28629
|
+
try {
|
|
28630
|
+
if (preset === "full") {
|
|
28631
|
+
await installDefaultShadcnComponents(join(projectPath, "packages/ui"), {
|
|
28632
|
+
silent: true
|
|
28633
|
+
});
|
|
28634
|
+
} else {
|
|
28635
|
+
await installDefaultShadcnComponents(projectPath, {
|
|
28636
|
+
silent: true
|
|
28637
|
+
});
|
|
28638
|
+
}
|
|
28639
|
+
componentSpinner.stop(`${source_default.green("\u2705")} Default components installed`);
|
|
28640
|
+
} catch (error) {
|
|
28641
|
+
componentSpinner.stop(`${source_default.yellow("\u26A0\uFE0F")} Could not install automatically`);
|
|
28642
|
+
Me("Install manually: bunx shadcn@latest add button card", "Component Installation");
|
|
28643
|
+
}
|
|
28644
|
+
}
|
|
26911
28645
|
const getDevCommand = () => {
|
|
26912
28646
|
if (preset === "full" || preset === "web")
|
|
26913
28647
|
return "bun dev";
|
|
26914
28648
|
return "bun run dev";
|
|
26915
28649
|
};
|
|
26916
|
-
const
|
|
26917
|
-
|
|
26918
|
-
|
|
26919
|
-
|
|
28650
|
+
const getPresetEmoji = () => {
|
|
28651
|
+
switch (preset) {
|
|
28652
|
+
case "minimal":
|
|
28653
|
+
return "\u26A1";
|
|
28654
|
+
case "web":
|
|
28655
|
+
return "\uD83C\uDF10";
|
|
28656
|
+
case "api":
|
|
28657
|
+
return "\uD83D\uDE80";
|
|
28658
|
+
case "full":
|
|
28659
|
+
return "\uD83D\uDCE6";
|
|
28660
|
+
default:
|
|
28661
|
+
return "\u2728";
|
|
28662
|
+
}
|
|
28663
|
+
};
|
|
28664
|
+
const nextStepsContent = [
|
|
28665
|
+
`${source_default.bold.cyan("\uD83D\uDCC1 Navigate to your project")}`,
|
|
28666
|
+
`${source_default.cyan("cd")} ${source_default.bold(projectName)}`,
|
|
28667
|
+
"",
|
|
28668
|
+
shouldInstall ? "" : [
|
|
28669
|
+
`${source_default.bold.cyan("\uD83D\uDCE6 Install dependencies")}`,
|
|
28670
|
+
`${source_default.cyan("bun install")}`,
|
|
28671
|
+
""
|
|
28672
|
+
].join(`
|
|
28673
|
+
`),
|
|
28674
|
+
`${source_default.bold.cyan("\uD83D\uDE80 Start development")}`,
|
|
28675
|
+
`${source_default.cyan(getDevCommand())} ${source_default.dim("# Start development server")}`,
|
|
28676
|
+
"",
|
|
28677
|
+
`${source_default.dim("\u2500".repeat(40))}`,
|
|
28678
|
+
`${source_default.bold.yellow("\uD83D\uDCA1 Quick Tips")}`,
|
|
28679
|
+
"",
|
|
28680
|
+
database && database !== "none" ? ` ${source_default.dim("\u2022")} Configure your database connection in ${source_default.cyan(".env")}` : "",
|
|
28681
|
+
uiLibrary === "shadcn" ? ` ${source_default.dim("\u2022")} Add more components: ${source_default.cyan("bunkit add component --all")}` : "",
|
|
28682
|
+
preset === "full" ? ` ${source_default.dim("\u2022")} Add workspaces: ${source_default.cyan("bunkit add workspace")}` : "",
|
|
28683
|
+
preset === "full" ? ` ${source_default.dim("\u2022")} Add packages: ${source_default.cyan("bunkit add package")}` : "",
|
|
28684
|
+
` ${source_default.dim("\u2022")} Read the ${source_default.cyan("README.md")} for project-specific documentation`,
|
|
28685
|
+
database === "supabase" || database === "supabase-drizzle" ? ` ${source_default.dim("\u2022")} Check ${source_default.cyan("SHADCN.md")} for shadcn/ui usage guide` : ""
|
|
26920
28686
|
].filter(Boolean).join(`
|
|
26921
28687
|
`);
|
|
26922
28688
|
console.log(`
|
|
26923
|
-
` + boxen(
|
|
26924
|
-
padding: 1,
|
|
26925
|
-
title:
|
|
28689
|
+
` + boxen(nextStepsContent, {
|
|
28690
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
28691
|
+
title: `${getPresetEmoji()} Next Steps`,
|
|
26926
28692
|
titleAlignment: "left",
|
|
26927
28693
|
borderColor: "green",
|
|
26928
|
-
borderStyle: "round"
|
|
28694
|
+
borderStyle: "round",
|
|
28695
|
+
dimBorder: false
|
|
28696
|
+
}));
|
|
28697
|
+
const projectSummary = [
|
|
28698
|
+
`${source_default.bold.green("\u2728 Project created successfully!")}`,
|
|
28699
|
+
"",
|
|
28700
|
+
`${source_default.dim("Project location:")} ${source_default.cyan(join(process.cwd(), projectName))}`,
|
|
28701
|
+
`${source_default.dim("Preset:")} ${source_default.cyan(preset)}`,
|
|
28702
|
+
database && database !== "none" ? `${source_default.dim("Database:")} ${source_default.cyan(database)}` : "",
|
|
28703
|
+
uiLibrary ? `${source_default.dim("UI Library:")} ${source_default.cyan(uiLibrary)}` : "",
|
|
28704
|
+
"",
|
|
28705
|
+
`${source_default.dim("Happy coding! \uD83C\uDF89")}`
|
|
28706
|
+
].filter(Boolean).join(`
|
|
28707
|
+
`);
|
|
28708
|
+
console.log(`
|
|
28709
|
+
` + boxen(projectSummary, {
|
|
28710
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
28711
|
+
borderColor: "green",
|
|
28712
|
+
borderStyle: "round",
|
|
28713
|
+
dimBorder: true
|
|
26929
28714
|
}));
|
|
26930
28715
|
} catch (error) {
|
|
26931
|
-
s.stop("\u274C Failed to create project
|
|
26932
|
-
|
|
28716
|
+
s.stop(`${source_default.red("\u274C")} Failed to create project`);
|
|
28717
|
+
const errorMessage = error.message;
|
|
28718
|
+
const errorBox = [
|
|
28719
|
+
`${source_default.bold.red("Error occurred during project creation")}`,
|
|
28720
|
+
"",
|
|
28721
|
+
source_default.red(errorMessage),
|
|
28722
|
+
"",
|
|
28723
|
+
`${source_default.dim("\u2500".repeat(40))}`,
|
|
28724
|
+
`${source_default.bold.yellow("\uD83D\uDCA1 Troubleshooting Tips")}`,
|
|
28725
|
+
"",
|
|
28726
|
+
` ${source_default.dim("\u2022")} Check if the directory already exists`,
|
|
28727
|
+
` ${source_default.dim("\u2022")} Ensure you have write permissions`,
|
|
28728
|
+
` ${source_default.dim("\u2022")} Verify your internet connection (for dependency installation)`,
|
|
28729
|
+
` ${source_default.dim("\u2022")} Try running with ${source_default.cyan("--no-install")} to skip dependency installation`,
|
|
28730
|
+
"",
|
|
28731
|
+
`${source_default.dim("Need help?")} ${source_default.cyan("https://github.com/Arakiss/bunkit/issues")}`
|
|
28732
|
+
].join(`
|
|
28733
|
+
`);
|
|
28734
|
+
console.log(`
|
|
28735
|
+
` + boxen(errorBox, {
|
|
28736
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
28737
|
+
borderColor: "red",
|
|
28738
|
+
borderStyle: "round"
|
|
28739
|
+
}));
|
|
28740
|
+
xe("Operation cancelled due to error");
|
|
26933
28741
|
process.exit(1);
|
|
26934
28742
|
}
|
|
26935
28743
|
}
|
|
@@ -26948,8 +28756,9 @@ async function createCommand2(preset, name, options) {
|
|
|
26948
28756
|
if (!validation2.valid) {
|
|
26949
28757
|
throw new Error(`Invalid project name: ${validation2.error}`);
|
|
26950
28758
|
}
|
|
28759
|
+
console.log("");
|
|
26951
28760
|
const s = Y2();
|
|
26952
|
-
s.start(
|
|
28761
|
+
s.start(`${source_default.cyan("\uD83D\uDD28")} Creating ${preset} project: ${source_default.bold(name)}`);
|
|
26953
28762
|
try {
|
|
26954
28763
|
const config = {
|
|
26955
28764
|
name,
|
|
@@ -26966,11 +28775,11 @@ async function createCommand2(preset, name, options) {
|
|
|
26966
28775
|
envExample: true,
|
|
26967
28776
|
pathAliases: true
|
|
26968
28777
|
};
|
|
26969
|
-
s.message("\uD83D\
|
|
28778
|
+
s.message(`${source_default.cyan("\uD83D\uDCC1")} Creating project structure...`);
|
|
26970
28779
|
await createProject(config);
|
|
26971
28780
|
const projectPath = join(process.cwd(), config.path);
|
|
26972
28781
|
const context = createTemplateContext(config);
|
|
26973
|
-
s.message("\uD83D\uDCDD Generating files
|
|
28782
|
+
s.message(`${source_default.cyan("\uD83D\uDCDD")} Generating project files...`);
|
|
26974
28783
|
switch (preset) {
|
|
26975
28784
|
case "minimal":
|
|
26976
28785
|
await buildMinimalPreset(projectPath, context);
|
|
@@ -26985,22 +28794,65 @@ async function createCommand2(preset, name, options) {
|
|
|
26985
28794
|
await buildFullPreset(projectPath, context);
|
|
26986
28795
|
break;
|
|
26987
28796
|
}
|
|
26988
|
-
s.
|
|
26989
|
-
|
|
26990
|
-
|
|
26991
|
-
|
|
26992
|
-
|
|
28797
|
+
s.message(`${source_default.cyan("\u2728")} Finalizing setup...`);
|
|
28798
|
+
s.stop(`${source_default.green("\u2705")} Project ${source_default.bold(name)} created successfully!`);
|
|
28799
|
+
const getPresetEmoji = () => {
|
|
28800
|
+
switch (preset) {
|
|
28801
|
+
case "minimal":
|
|
28802
|
+
return "\u26A1";
|
|
28803
|
+
case "web":
|
|
28804
|
+
return "\uD83C\uDF10";
|
|
28805
|
+
case "api":
|
|
28806
|
+
return "\uD83D\uDE80";
|
|
28807
|
+
case "full":
|
|
28808
|
+
return "\uD83D\uDCE6";
|
|
28809
|
+
default:
|
|
28810
|
+
return "\u2728";
|
|
28811
|
+
}
|
|
28812
|
+
};
|
|
28813
|
+
const nextStepsContent = [
|
|
28814
|
+
`${source_default.bold.cyan("\uD83D\uDCC1 Navigate to your project")}`,
|
|
28815
|
+
`${source_default.cyan("cd")} ${source_default.bold(name)}`,
|
|
28816
|
+
"",
|
|
28817
|
+
options.install === false ? [
|
|
28818
|
+
`${source_default.bold.cyan("\uD83D\uDCE6 Install dependencies")}`,
|
|
28819
|
+
`${source_default.cyan("bun install")}`,
|
|
28820
|
+
""
|
|
28821
|
+
].join(`
|
|
28822
|
+
`) : "",
|
|
28823
|
+
`${source_default.bold.cyan("\uD83D\uDE80 Start development")}`,
|
|
28824
|
+
`${source_default.cyan(preset === "web" ? "bun dev" : "bun run dev")} ${source_default.dim("# Start development server")}`,
|
|
28825
|
+
"",
|
|
28826
|
+
`${source_default.dim("\u2500".repeat(40))}`,
|
|
28827
|
+
`${source_default.bold.yellow("\uD83D\uDCA1 Tip")}`,
|
|
28828
|
+
` Use ${source_default.cyan("bunkit init")} for full customization options`
|
|
28829
|
+
].filter(Boolean).join(`
|
|
26993
28830
|
`);
|
|
26994
28831
|
console.log(`
|
|
26995
|
-
` + boxen(
|
|
26996
|
-
padding: 1,
|
|
26997
|
-
title:
|
|
28832
|
+
` + boxen(nextStepsContent, {
|
|
28833
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
28834
|
+
title: `${getPresetEmoji()} Next Steps`,
|
|
26998
28835
|
titleAlignment: "left",
|
|
26999
|
-
borderColor: "
|
|
27000
|
-
borderStyle: "round"
|
|
28836
|
+
borderColor: "green",
|
|
28837
|
+
borderStyle: "round",
|
|
28838
|
+
dimBorder: false
|
|
27001
28839
|
}));
|
|
27002
28840
|
} catch (error) {
|
|
27003
|
-
s.stop("\u274C Project creation failed
|
|
28841
|
+
s.stop(`${source_default.red("\u274C")} Project creation failed`);
|
|
28842
|
+
const errorBox = [
|
|
28843
|
+
`${source_default.bold.red("Error occurred")}`,
|
|
28844
|
+
"",
|
|
28845
|
+
source_default.red(error.message),
|
|
28846
|
+
"",
|
|
28847
|
+
`${source_default.dim("Need help?")} ${source_default.cyan("https://github.com/Arakiss/bunkit/issues")}`
|
|
28848
|
+
].join(`
|
|
28849
|
+
`);
|
|
28850
|
+
console.log(`
|
|
28851
|
+
` + boxen(errorBox, {
|
|
28852
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
28853
|
+
borderColor: "red",
|
|
28854
|
+
borderStyle: "round"
|
|
28855
|
+
}));
|
|
27004
28856
|
throw error;
|
|
27005
28857
|
}
|
|
27006
28858
|
}
|
|
@@ -27008,7 +28860,7 @@ async function createCommand2(preset, name, options) {
|
|
|
27008
28860
|
// src/commands/add/workspace.ts
|
|
27009
28861
|
init_dist();
|
|
27010
28862
|
init_src();
|
|
27011
|
-
var
|
|
28863
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
27012
28864
|
function getWorkspaceDependencies(preset) {
|
|
27013
28865
|
switch (preset) {
|
|
27014
28866
|
case "nextjs":
|
|
@@ -27091,8 +28943,8 @@ async function addWorkspaceCommand(options = {}) {
|
|
|
27091
28943
|
let workspaceName = options.name;
|
|
27092
28944
|
if (!workspaceName) {
|
|
27093
28945
|
const nameInput = await he({
|
|
27094
|
-
message: "Workspace name
|
|
27095
|
-
placeholder: "apps/
|
|
28946
|
+
message: "Workspace name",
|
|
28947
|
+
placeholder: "apps/admin or packages/email",
|
|
27096
28948
|
validate: (value) => {
|
|
27097
28949
|
if (!value)
|
|
27098
28950
|
return "Workspace name is required";
|
|
@@ -27120,15 +28972,15 @@ async function addWorkspaceCommand(options = {}) {
|
|
|
27120
28972
|
let preset = options.preset;
|
|
27121
28973
|
if (!preset) {
|
|
27122
28974
|
const presetChoice = await ve({
|
|
27123
|
-
message: "
|
|
28975
|
+
message: "Select workspace preset",
|
|
27124
28976
|
options: [
|
|
27125
28977
|
{
|
|
27126
28978
|
value: "nextjs",
|
|
27127
|
-
label: "Next.js",
|
|
27128
|
-
hint: "Next.js 16 + React 19 + Tailwind"
|
|
28979
|
+
label: "Next.js Application",
|
|
28980
|
+
hint: "Next.js 16 + React 19 + Tailwind CSS 4 - production-ready web app"
|
|
27129
28981
|
},
|
|
27130
|
-
{ value: "hono", label: "Hono API", hint: "
|
|
27131
|
-
{ value: "library", label: "Library", hint: "
|
|
28982
|
+
{ value: "hono", label: "Hono API Server", hint: "Hono 4 + Bun.serve() - ultra-fast REST API" },
|
|
28983
|
+
{ value: "library", label: "Shared Library", hint: "Reusable package for shared code and components" }
|
|
27132
28984
|
]
|
|
27133
28985
|
});
|
|
27134
28986
|
if (pD(presetChoice)) {
|
|
@@ -27166,18 +29018,18 @@ async function addWorkspaceCommand(options = {}) {
|
|
|
27166
29018
|
spinner.stop("Dependencies installed");
|
|
27167
29019
|
M2.success(`Workspace "${workspaceName}" created successfully!`);
|
|
27168
29020
|
const devCommand = preset === "nextjs" ? "next dev" : preset === "hono" ? "bun dev" : "bun run build";
|
|
27169
|
-
Me(`${
|
|
29021
|
+
Me(`${import_picocolors4.default.bold("Next steps:")}
|
|
27170
29022
|
|
|
27171
|
-
${
|
|
27172
|
-
${
|
|
29023
|
+
${import_picocolors4.default.cyan(`cd ${workspaceName}`)}
|
|
29024
|
+
${import_picocolors4.default.cyan(devCommand)}
|
|
27173
29025
|
|
|
27174
|
-
${
|
|
29026
|
+
${import_picocolors4.default.bold("Workspace info:")}
|
|
27175
29027
|
Name: ${getWorkspaceName(workspaceName)}
|
|
27176
29028
|
Type: ${preset}
|
|
27177
29029
|
Path: ${workspaceName}
|
|
27178
29030
|
|
|
27179
|
-
${preset === "library" ? `${
|
|
27180
|
-
import { example } from '${getWorkspaceName(workspaceName)}'` : ""}`,
|
|
29031
|
+
${preset === "library" ? `${import_picocolors4.default.bold("Usage in other workspaces:")}
|
|
29032
|
+
import { example } from '${getWorkspaceName(workspaceName)}'` : ""}`, import_picocolors4.default.green("Workspace ready!"));
|
|
27181
29033
|
} catch (error) {
|
|
27182
29034
|
spinner.stop("Failed");
|
|
27183
29035
|
throw error;
|
|
@@ -27187,7 +29039,7 @@ ${preset === "library" ? `${import_picocolors5.default.bold("Usage in other work
|
|
|
27187
29039
|
// src/commands/add/package.ts
|
|
27188
29040
|
init_dist();
|
|
27189
29041
|
init_src();
|
|
27190
|
-
var
|
|
29042
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
27191
29043
|
async function generatePackageFiles(packagePath, packageName, type) {
|
|
27192
29044
|
const { writeFile: writeFile2 } = await Promise.resolve().then(() => (init_src(), exports_src));
|
|
27193
29045
|
await ensureDirectory(join(packagePath, "src"));
|
|
@@ -27312,8 +29164,8 @@ async function addPackageCommand(options = {}) {
|
|
|
27312
29164
|
let packageName = options.name;
|
|
27313
29165
|
if (!packageName) {
|
|
27314
29166
|
const nameInput = await he({
|
|
27315
|
-
message: "Package name
|
|
27316
|
-
placeholder: "@myapp/email",
|
|
29167
|
+
message: "Package name",
|
|
29168
|
+
placeholder: "@myapp/email or utils",
|
|
27317
29169
|
validate: (value) => {
|
|
27318
29170
|
if (!value)
|
|
27319
29171
|
return "Package name is required";
|
|
@@ -27350,12 +29202,12 @@ async function addPackageCommand(options = {}) {
|
|
|
27350
29202
|
let type = options.type;
|
|
27351
29203
|
if (!type) {
|
|
27352
29204
|
const typeChoice = await ve({
|
|
27353
|
-
message: "
|
|
29205
|
+
message: "Select package type",
|
|
27354
29206
|
options: [
|
|
27355
|
-
{ value: "library", label: "Library", hint: "Shared code
|
|
27356
|
-
{ value: "utils", label: "
|
|
27357
|
-
{ value: "types", label: "
|
|
27358
|
-
{ value: "config", label: "
|
|
29207
|
+
{ value: "library", label: "Library", hint: "Shared code and components - reusable across workspaces" },
|
|
29208
|
+
{ value: "utils", label: "Utilities", hint: "Utility functions and helpers - common operations" },
|
|
29209
|
+
{ value: "types", label: "Type Definitions", hint: "Shared TypeScript types and interfaces" },
|
|
29210
|
+
{ value: "config", label: "Configuration", hint: "Shared configuration files and settings" }
|
|
27359
29211
|
]
|
|
27360
29212
|
});
|
|
27361
29213
|
if (pD(typeChoice)) {
|
|
@@ -27400,31 +29252,148 @@ async function addPackageCommand(options = {}) {
|
|
|
27400
29252
|
await installDependencies(cwd2, {});
|
|
27401
29253
|
spinner.stop("Dependencies installed");
|
|
27402
29254
|
M2.success(`Package "${fullPackageName}" created successfully!`);
|
|
27403
|
-
Me(`${
|
|
29255
|
+
Me(`${import_picocolors5.default.bold("Next steps:")}
|
|
27404
29256
|
|
|
27405
|
-
${
|
|
27406
|
-
${
|
|
29257
|
+
${import_picocolors5.default.bold("1. Use in other workspaces:")}
|
|
29258
|
+
${import_picocolors5.default.cyan(`import { example } from '${fullPackageName}'`)}
|
|
27407
29259
|
|
|
27408
|
-
${
|
|
27409
|
-
${
|
|
27410
|
-
${
|
|
27411
|
-
${
|
|
27412
|
-
${
|
|
29260
|
+
${import_picocolors5.default.bold("2. Add to workspace dependencies:")}
|
|
29261
|
+
${import_picocolors5.default.dim("// In apps/web/package.json")}
|
|
29262
|
+
${import_picocolors5.default.cyan('"dependencies": {')}
|
|
29263
|
+
${import_picocolors5.default.cyan(` "${fullPackageName}": "workspace:*"`)}
|
|
29264
|
+
${import_picocolors5.default.cyan("}")}
|
|
27413
29265
|
|
|
27414
|
-
${
|
|
27415
|
-
${
|
|
27416
|
-
${
|
|
29266
|
+
${import_picocolors5.default.bold("3. Develop the package:")}
|
|
29267
|
+
${import_picocolors5.default.cyan(`cd ${workspacePath}`)}
|
|
29268
|
+
${import_picocolors5.default.cyan("# Edit src/index.ts")}
|
|
27417
29269
|
|
|
27418
|
-
${
|
|
29270
|
+
${import_picocolors5.default.bold("Package info:")}
|
|
27419
29271
|
Name: ${fullPackageName}
|
|
27420
29272
|
Type: ${type}
|
|
27421
|
-
Path: ${workspacePath}`,
|
|
29273
|
+
Path: ${workspacePath}`, import_picocolors5.default.green("Package ready!"));
|
|
27422
29274
|
} catch (error) {
|
|
27423
29275
|
spinner.stop("Failed");
|
|
27424
29276
|
throw error;
|
|
27425
29277
|
}
|
|
27426
29278
|
}
|
|
27427
29279
|
|
|
29280
|
+
// src/commands/add/component.ts
|
|
29281
|
+
init_dist();
|
|
29282
|
+
import { existsSync } from "fs";
|
|
29283
|
+
async function addComponentCommand(options = {}) {
|
|
29284
|
+
const cwd2 = options.cwd || process.cwd();
|
|
29285
|
+
const spinner = Y2();
|
|
29286
|
+
const componentsJsonPath = join(cwd2, "components.json");
|
|
29287
|
+
const isMonorepo = existsSync(join(cwd2, "packages/ui/components.json"));
|
|
29288
|
+
if (!existsSync(componentsJsonPath) && !isMonorepo) {
|
|
29289
|
+
M2.error("shadcn/ui is not configured in this project.");
|
|
29290
|
+
M2.info("Run `bunkit init` with --ui-library shadcn to set up shadcn/ui first.");
|
|
29291
|
+
process.exit(1);
|
|
29292
|
+
}
|
|
29293
|
+
const targetPath = isMonorepo ? join(cwd2, "packages/ui") : cwd2;
|
|
29294
|
+
let components = [];
|
|
29295
|
+
if (options.all) {
|
|
29296
|
+
const popularComponents = [
|
|
29297
|
+
"button",
|
|
29298
|
+
"card",
|
|
29299
|
+
"input",
|
|
29300
|
+
"label",
|
|
29301
|
+
"textarea",
|
|
29302
|
+
"select",
|
|
29303
|
+
"checkbox",
|
|
29304
|
+
"radio-group",
|
|
29305
|
+
"switch",
|
|
29306
|
+
"dialog",
|
|
29307
|
+
"dropdown-menu",
|
|
29308
|
+
"alert",
|
|
29309
|
+
"badge",
|
|
29310
|
+
"avatar",
|
|
29311
|
+
"separator",
|
|
29312
|
+
"skeleton",
|
|
29313
|
+
"tabs",
|
|
29314
|
+
"accordion",
|
|
29315
|
+
"alert-dialog",
|
|
29316
|
+
"aspect-ratio",
|
|
29317
|
+
"breadcrumb",
|
|
29318
|
+
"calendar",
|
|
29319
|
+
"carousel",
|
|
29320
|
+
"chart",
|
|
29321
|
+
"collapsible",
|
|
29322
|
+
"command",
|
|
29323
|
+
"context-menu",
|
|
29324
|
+
"drawer",
|
|
29325
|
+
"form",
|
|
29326
|
+
"hover-card",
|
|
29327
|
+
"menubar",
|
|
29328
|
+
"navigation-menu",
|
|
29329
|
+
"popover",
|
|
29330
|
+
"progress",
|
|
29331
|
+
"scroll-area",
|
|
29332
|
+
"sheet",
|
|
29333
|
+
"slider",
|
|
29334
|
+
"sonner",
|
|
29335
|
+
"table",
|
|
29336
|
+
"toast",
|
|
29337
|
+
"toggle",
|
|
29338
|
+
"tooltip"
|
|
29339
|
+
];
|
|
29340
|
+
const selected = await fe({
|
|
29341
|
+
message: "Select shadcn/ui components to install",
|
|
29342
|
+
options: popularComponents.map((comp) => ({
|
|
29343
|
+
value: comp,
|
|
29344
|
+
label: comp
|
|
29345
|
+
})),
|
|
29346
|
+
required: true
|
|
29347
|
+
});
|
|
29348
|
+
if (pD(selected)) {
|
|
29349
|
+
xe("Operation cancelled.");
|
|
29350
|
+
process.exit(0);
|
|
29351
|
+
}
|
|
29352
|
+
components = selected;
|
|
29353
|
+
} else if (options.components && options.components.length > 0) {
|
|
29354
|
+
components = options.components;
|
|
29355
|
+
} else {
|
|
29356
|
+
const componentInput = await he({
|
|
29357
|
+
message: "Component name(s)",
|
|
29358
|
+
placeholder: "button,card,input (comma-separated)",
|
|
29359
|
+
validate: (value) => {
|
|
29360
|
+
if (!value.trim()) {
|
|
29361
|
+
return "Please enter at least one component name";
|
|
29362
|
+
}
|
|
29363
|
+
}
|
|
29364
|
+
});
|
|
29365
|
+
if (pD(componentInput)) {
|
|
29366
|
+
xe("Operation cancelled.");
|
|
29367
|
+
process.exit(0);
|
|
29368
|
+
}
|
|
29369
|
+
components = componentInput.split(/[,\s]+/).map((c3) => c3.trim()).filter(Boolean);
|
|
29370
|
+
}
|
|
29371
|
+
if (components.length === 0) {
|
|
29372
|
+
M2.error("No components specified.");
|
|
29373
|
+
process.exit(1);
|
|
29374
|
+
}
|
|
29375
|
+
spinner.start(`Installing ${components.length} component(s)...`);
|
|
29376
|
+
try {
|
|
29377
|
+
await installShadcnComponents(targetPath, components, {
|
|
29378
|
+
silent: false,
|
|
29379
|
+
cwd: targetPath
|
|
29380
|
+
});
|
|
29381
|
+
spinner.stop(`\u2705 Installed: ${components.join(", ")}`);
|
|
29382
|
+
if (isMonorepo) {
|
|
29383
|
+
Me(`Components installed in packages/ui. Import them using:
|
|
29384
|
+
import { Button } from "@workspace/ui/components/ui/button"`, "Usage");
|
|
29385
|
+
} else {
|
|
29386
|
+
Me(`Import components using:
|
|
29387
|
+
import { Button } from "@/components/ui/button"`, "Usage");
|
|
29388
|
+
}
|
|
29389
|
+
} catch (error) {
|
|
29390
|
+
spinner.stop("\u274C Failed to install components");
|
|
29391
|
+
M2.error(error.message);
|
|
29392
|
+
M2.info("Try installing manually: bunx shadcn@latest add " + components.join(" "));
|
|
29393
|
+
process.exit(1);
|
|
29394
|
+
}
|
|
29395
|
+
}
|
|
29396
|
+
|
|
27428
29397
|
// src/commands/add.ts
|
|
27429
29398
|
async function addCommand(feature, options) {
|
|
27430
29399
|
try {
|
|
@@ -27443,9 +29412,16 @@ async function addCommand(feature, options) {
|
|
|
27443
29412
|
cwd: process.cwd()
|
|
27444
29413
|
});
|
|
27445
29414
|
break;
|
|
29415
|
+
case "component":
|
|
29416
|
+
await addComponentCommand({
|
|
29417
|
+
components: options.components,
|
|
29418
|
+
all: options.all,
|
|
29419
|
+
cwd: process.cwd()
|
|
29420
|
+
});
|
|
29421
|
+
break;
|
|
27446
29422
|
default:
|
|
27447
29423
|
M2.error(`Unknown feature: ${feature}`);
|
|
27448
|
-
M2.info(`Available features: workspace, package`);
|
|
29424
|
+
M2.info(`Available features: workspace, package, component`);
|
|
27449
29425
|
process.exit(1);
|
|
27450
29426
|
}
|
|
27451
29427
|
} catch (error) {
|
|
@@ -27457,37 +29433,78 @@ async function addCommand(feature, options) {
|
|
|
27457
29433
|
var packageJson = await Bun.file(new URL("../package.json", import.meta.url)).json();
|
|
27458
29434
|
var VERSION = packageJson.version;
|
|
27459
29435
|
var program2 = new Command;
|
|
27460
|
-
program2.name("bunkit").description("Bake production-ready apps in seconds").version(VERSION)
|
|
27461
|
-
|
|
29436
|
+
program2.name("bunkit").description("Bake production-ready apps in seconds | Modern CLI for Bun-powered projects").version(VERSION).usage("<command> [options]").addHelpText("after", `
|
|
29437
|
+
Examples:
|
|
29438
|
+
$ bunkit init Create a new project interactively
|
|
29439
|
+
$ bunkit create web my-app Create a Next.js web application
|
|
29440
|
+
$ bunkit add workspace Add a new workspace to monorepo
|
|
29441
|
+
$ bunkit add component --all Browse and add shadcn/ui components
|
|
29442
|
+
|
|
29443
|
+
For more information, visit: https://github.com/Arakiss/bunkit
|
|
29444
|
+
`);
|
|
29445
|
+
program2.command("init").description("Create a new project with full customization options").alias("i").option("--name <name>", "Project name (kebab-case recommended, e.g., my-awesome-app)").option("--preset <preset>", "Project preset: minimal | web | api | full").option("--database <database>", "Database option: postgres-drizzle | supabase | supabase-drizzle | sqlite-drizzle | none").option("--supabase-preset <preset>", "Supabase configuration preset: full-stack | auth-only | database-only | custom").option("--supabase-features <features>", "Comma-separated Supabase features: auth,storage,realtime,edge-functions,database").option("--code-quality <tool>", "Code quality tool: ultracite | biome").option("--ts-strictness <level>", "TypeScript strictness level: strict | moderate | loose").option("--ui-library <library>", "UI component library: shadcn | none").option("--css-framework <framework>", "CSS framework: tailwind | vanilla | css-modules").option("--shadcn-style <style>", "shadcn/ui component style: new-york | default").option("--shadcn-base-color <color>", "shadcn/ui base color theme: neutral | gray | zinc | stone | slate").option("--shadcn-radius <radius>", "shadcn/ui border radius (CSS value, e.g., 0.5rem, 8px)").option("--testing <framework>", "Testing framework: bun-test | vitest | none").option("--docker", "Include Docker configuration files").option("--cicd", "Include GitHub Actions CI/CD workflow").option("--no-git", "Skip Git repository initialization").option("--no-install", "Skip dependency installation after project creation").option("--non-interactive", "Run in non-interactive mode (requires all options via flags)").addHelpText("after", `
|
|
29446
|
+
Examples:
|
|
29447
|
+
$ bunkit init Interactive project creation
|
|
29448
|
+
$ bunkit init --name my-app --preset web Quick web app creation
|
|
29449
|
+
$ bunkit init --preset full --database supabase Full-stack with Supabase
|
|
29450
|
+
|
|
29451
|
+
Presets:
|
|
29452
|
+
minimal Single-file project, clean start
|
|
29453
|
+
web Next.js 16 + React 19 web application
|
|
29454
|
+
api Hono API server with Bun.serve()
|
|
29455
|
+
full Full-stack monorepo (web + api + packages)
|
|
29456
|
+
`).action(async (options) => {
|
|
27462
29457
|
showBanner(VERSION);
|
|
27463
29458
|
try {
|
|
27464
29459
|
await enhancedInitCommand(options);
|
|
27465
|
-
Se(
|
|
29460
|
+
Se(import_picocolors6.default.green("\u2728 Done! Your project is ready to bake! \uD83C\uDF5E"));
|
|
27466
29461
|
} catch (error) {
|
|
27467
29462
|
M2.error(error.message);
|
|
27468
|
-
Se(
|
|
29463
|
+
Se(import_picocolors6.default.red("\u274C Project creation failed"));
|
|
27469
29464
|
process.exit(1);
|
|
27470
29465
|
}
|
|
27471
29466
|
});
|
|
27472
|
-
program2.command("create").argument("<preset>", "
|
|
29467
|
+
program2.command("create").alias("c").argument("<preset>", "Project preset: minimal | web | api | full").argument("<name>", "Project name (kebab-case recommended)").option("--no-git", "Skip Git repository initialization").option("--no-install", "Skip dependency installation after project creation").description("Quick project creation with sensible defaults (non-interactive)").addHelpText("after", `
|
|
29468
|
+
Examples:
|
|
29469
|
+
$ bunkit create web my-app Create Next.js web application
|
|
29470
|
+
$ bunkit create api my-api Create Hono API server
|
|
29471
|
+
$ bunkit create full my-saas Create full-stack monorepo
|
|
29472
|
+
$ bunkit create minimal my-tool Create minimal Bun project
|
|
29473
|
+
|
|
29474
|
+
Note: This command uses sensible defaults. Use 'bunkit init' for full customization.
|
|
29475
|
+
`).action(async (preset, name, options) => {
|
|
27473
29476
|
showBanner(VERSION);
|
|
27474
29477
|
try {
|
|
27475
29478
|
await createCommand2(preset, name, options);
|
|
27476
|
-
Se(
|
|
29479
|
+
Se(import_picocolors6.default.green("\u2728 Done! Your project is ready to bake! \uD83C\uDF5E"));
|
|
27477
29480
|
} catch (error) {
|
|
27478
29481
|
M2.error(error.message);
|
|
27479
|
-
Se(
|
|
29482
|
+
Se(import_picocolors6.default.red("\u274C Project creation failed"));
|
|
27480
29483
|
process.exit(1);
|
|
27481
29484
|
}
|
|
27482
29485
|
});
|
|
27483
|
-
program2.command("add").argument("<feature>", "Feature
|
|
29486
|
+
program2.command("add").alias("a").argument("<feature>", "Feature type: workspace | package | component").option("--name <name>", "Feature name (e.g., apps/admin, @myapp/utils, button)").option("--preset <preset>", "Workspace preset: nextjs | hono | library").option("--type <type>", "Package type: library | utils | types | config").option("--components <components>", "Comma-separated component names (e.g., button,card,input)").option("--all", "Show interactive component browser (for component feature)").description("Add workspace, shared package, or shadcn/ui component to existing project").addHelpText("after", `
|
|
29487
|
+
Examples:
|
|
29488
|
+
$ bunkit add workspace --name apps/admin --preset nextjs
|
|
29489
|
+
$ bunkit add package --name @myapp/utils --type utils
|
|
29490
|
+
$ bunkit add component --components button,card,input
|
|
29491
|
+
$ bunkit add component --all
|
|
29492
|
+
|
|
29493
|
+
Features:
|
|
29494
|
+
workspace Add a new workspace to monorepo (app or package)
|
|
29495
|
+
package Add a shared package to monorepo
|
|
29496
|
+
component Add shadcn/ui components (requires shadcn/ui setup)
|
|
29497
|
+
`).action(async (feature, options) => {
|
|
27484
29498
|
showBanner(VERSION);
|
|
27485
29499
|
try {
|
|
27486
|
-
|
|
27487
|
-
|
|
29500
|
+
const parsedOptions = {
|
|
29501
|
+
...options,
|
|
29502
|
+
components: options.components && typeof options.components === "string" ? options.components.split(",").map((c3) => c3.trim()) : options.components
|
|
29503
|
+
};
|
|
29504
|
+
await addCommand(feature, parsedOptions);
|
|
27488
29505
|
} catch (error) {
|
|
27489
29506
|
M2.error(error.message);
|
|
27490
|
-
Se(
|
|
29507
|
+
Se(import_picocolors6.default.red("\u274C Feature installation failed"));
|
|
27491
29508
|
process.exit(1);
|
|
27492
29509
|
}
|
|
27493
29510
|
});
|