bunkit-cli 1.2.0 → 1.3.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/dist/index.js +1507 -70
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14851,7 +14851,396 @@ var init_monorepo = __esm(() => {
|
|
|
14851
14851
|
init_fs();
|
|
14852
14852
|
});
|
|
14853
14853
|
|
|
14854
|
-
// ../core/src/presets.ts
|
|
14854
|
+
// ../core/src/presets/registry.ts
|
|
14855
|
+
class PresetRegistry {
|
|
14856
|
+
static aliasMap = null;
|
|
14857
|
+
static getAliasMap() {
|
|
14858
|
+
if (!this.aliasMap) {
|
|
14859
|
+
this.aliasMap = new Map;
|
|
14860
|
+
for (const [name, definition] of Object.entries(PRESET_DEFINITIONS)) {
|
|
14861
|
+
this.aliasMap.set(name, name);
|
|
14862
|
+
for (const alias of definition.aliases) {
|
|
14863
|
+
this.aliasMap.set(alias, name);
|
|
14864
|
+
}
|
|
14865
|
+
}
|
|
14866
|
+
}
|
|
14867
|
+
return this.aliasMap;
|
|
14868
|
+
}
|
|
14869
|
+
static normalize(input) {
|
|
14870
|
+
const map = this.getAliasMap();
|
|
14871
|
+
return map.get(input) || null;
|
|
14872
|
+
}
|
|
14873
|
+
static get(input) {
|
|
14874
|
+
const normalized = this.normalize(input);
|
|
14875
|
+
if (!normalized)
|
|
14876
|
+
return null;
|
|
14877
|
+
return PRESET_DEFINITIONS[normalized];
|
|
14878
|
+
}
|
|
14879
|
+
static hasCapability(input, capability) {
|
|
14880
|
+
const preset = this.get(input);
|
|
14881
|
+
if (!preset)
|
|
14882
|
+
return false;
|
|
14883
|
+
return preset.capabilities[capability];
|
|
14884
|
+
}
|
|
14885
|
+
static isMonorepo(input) {
|
|
14886
|
+
return this.hasCapability(input, "isMonorepo");
|
|
14887
|
+
}
|
|
14888
|
+
static getSelectOptions() {
|
|
14889
|
+
return Object.values(PRESET_DEFINITIONS).map((preset) => ({
|
|
14890
|
+
value: preset.name,
|
|
14891
|
+
label: `${preset.emoji} ${preset.displayName}`,
|
|
14892
|
+
hint: preset.hint
|
|
14893
|
+
}));
|
|
14894
|
+
}
|
|
14895
|
+
static getPresetsWithCapability(capability) {
|
|
14896
|
+
return Object.values(PRESET_DEFINITIONS).filter((preset) => preset.capabilities[capability]);
|
|
14897
|
+
}
|
|
14898
|
+
static isValid(input) {
|
|
14899
|
+
return this.normalize(input) !== null;
|
|
14900
|
+
}
|
|
14901
|
+
static getAllValidNames() {
|
|
14902
|
+
return Array.from(this.getAliasMap().keys());
|
|
14903
|
+
}
|
|
14904
|
+
}
|
|
14905
|
+
var PRESET_DEFINITIONS;
|
|
14906
|
+
var init_registry = __esm(() => {
|
|
14907
|
+
PRESET_DEFINITIONS = {
|
|
14908
|
+
minimal: {
|
|
14909
|
+
name: "minimal",
|
|
14910
|
+
displayName: "Minimal",
|
|
14911
|
+
description: "Single-file Bun project",
|
|
14912
|
+
hint: "Single-file Bun project - perfect for CLIs and scripts",
|
|
14913
|
+
emoji: "\u26A1",
|
|
14914
|
+
aliases: [],
|
|
14915
|
+
capabilities: {
|
|
14916
|
+
database: false,
|
|
14917
|
+
cssFramework: false,
|
|
14918
|
+
uiLibrary: false,
|
|
14919
|
+
auth: false,
|
|
14920
|
+
redis: false,
|
|
14921
|
+
docker: true,
|
|
14922
|
+
cicd: true,
|
|
14923
|
+
isMonorepo: false,
|
|
14924
|
+
hasApi: false,
|
|
14925
|
+
hasWeb: false
|
|
14926
|
+
},
|
|
14927
|
+
devCommand: "bun run dev",
|
|
14928
|
+
rootDependencies: {},
|
|
14929
|
+
rootDevDependencies: {
|
|
14930
|
+
"@types/bun": "latest",
|
|
14931
|
+
typescript: "^5.9.3"
|
|
14932
|
+
}
|
|
14933
|
+
},
|
|
14934
|
+
nextjs: {
|
|
14935
|
+
name: "nextjs",
|
|
14936
|
+
displayName: "Next.js Application",
|
|
14937
|
+
description: "Next.js 16 + React 19 + Tailwind CSS 4",
|
|
14938
|
+
hint: "Next.js 16 + React 19 + Tailwind CSS 4 - production-ready web app (single repo)",
|
|
14939
|
+
emoji: "\uD83C\uDF10",
|
|
14940
|
+
aliases: ["web"],
|
|
14941
|
+
capabilities: {
|
|
14942
|
+
database: true,
|
|
14943
|
+
cssFramework: true,
|
|
14944
|
+
uiLibrary: true,
|
|
14945
|
+
auth: true,
|
|
14946
|
+
redis: false,
|
|
14947
|
+
docker: true,
|
|
14948
|
+
cicd: true,
|
|
14949
|
+
isMonorepo: false,
|
|
14950
|
+
hasApi: false,
|
|
14951
|
+
hasWeb: true
|
|
14952
|
+
},
|
|
14953
|
+
devCommand: "bun dev",
|
|
14954
|
+
rootDependencies: {
|
|
14955
|
+
react: "^19.2.3",
|
|
14956
|
+
"react-dom": "^19.2.3",
|
|
14957
|
+
next: "^16.0.10"
|
|
14958
|
+
},
|
|
14959
|
+
rootDevDependencies: {
|
|
14960
|
+
"@types/bun": "latest",
|
|
14961
|
+
"@types/react": "^19.2.7",
|
|
14962
|
+
"@types/react-dom": "^19.2.3",
|
|
14963
|
+
"@types/node": "^25.0.3",
|
|
14964
|
+
typescript: "^5.9.3",
|
|
14965
|
+
tailwindcss: "^4.1.18",
|
|
14966
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
14967
|
+
postcss: "^8.5.6"
|
|
14968
|
+
}
|
|
14969
|
+
},
|
|
14970
|
+
"hono-api": {
|
|
14971
|
+
name: "hono-api",
|
|
14972
|
+
displayName: "Hono API Server",
|
|
14973
|
+
description: "Hono 4 + Bun.serve()",
|
|
14974
|
+
hint: "Hono 4 + Bun.serve() - full-featured API with middleware ecosystem (single repo)",
|
|
14975
|
+
emoji: "\uD83D\uDE80",
|
|
14976
|
+
aliases: ["api"],
|
|
14977
|
+
capabilities: {
|
|
14978
|
+
database: true,
|
|
14979
|
+
cssFramework: false,
|
|
14980
|
+
uiLibrary: false,
|
|
14981
|
+
auth: true,
|
|
14982
|
+
redis: true,
|
|
14983
|
+
docker: true,
|
|
14984
|
+
cicd: true,
|
|
14985
|
+
isMonorepo: false,
|
|
14986
|
+
hasApi: true,
|
|
14987
|
+
hasWeb: false
|
|
14988
|
+
},
|
|
14989
|
+
devCommand: "bun run dev",
|
|
14990
|
+
rootDependencies: {
|
|
14991
|
+
hono: "^4.11.1"
|
|
14992
|
+
},
|
|
14993
|
+
rootDevDependencies: {
|
|
14994
|
+
"@types/bun": "latest",
|
|
14995
|
+
typescript: "^5.9.3"
|
|
14996
|
+
}
|
|
14997
|
+
},
|
|
14998
|
+
"bun-api": {
|
|
14999
|
+
name: "bun-api",
|
|
15000
|
+
displayName: "Bun Native API",
|
|
15001
|
+
description: "Bun.serve() native routing",
|
|
15002
|
+
hint: "Bun.serve() native routing - ultra-fast API with zero dependencies (single repo)",
|
|
15003
|
+
emoji: "\u26A1",
|
|
15004
|
+
aliases: [],
|
|
15005
|
+
capabilities: {
|
|
15006
|
+
database: true,
|
|
15007
|
+
cssFramework: false,
|
|
15008
|
+
uiLibrary: false,
|
|
15009
|
+
auth: true,
|
|
15010
|
+
redis: true,
|
|
15011
|
+
docker: true,
|
|
15012
|
+
cicd: true,
|
|
15013
|
+
isMonorepo: false,
|
|
15014
|
+
hasApi: true,
|
|
15015
|
+
hasWeb: false
|
|
15016
|
+
},
|
|
15017
|
+
devCommand: "bun run dev",
|
|
15018
|
+
rootDependencies: {},
|
|
15019
|
+
rootDevDependencies: {
|
|
15020
|
+
"@types/bun": "latest",
|
|
15021
|
+
typescript: "^5.9.3"
|
|
15022
|
+
}
|
|
15023
|
+
},
|
|
15024
|
+
"bun-fullstack": {
|
|
15025
|
+
name: "bun-fullstack",
|
|
15026
|
+
displayName: "Bun Full-Stack",
|
|
15027
|
+
description: "Bun.serve() + HTML imports",
|
|
15028
|
+
hint: "Bun.serve() + HTML imports - full-stack app without Next.js (single repo)",
|
|
15029
|
+
emoji: "\uD83D\uDD25",
|
|
15030
|
+
aliases: [],
|
|
15031
|
+
capabilities: {
|
|
15032
|
+
database: true,
|
|
15033
|
+
cssFramework: true,
|
|
15034
|
+
uiLibrary: true,
|
|
15035
|
+
auth: true,
|
|
15036
|
+
redis: true,
|
|
15037
|
+
docker: true,
|
|
15038
|
+
cicd: true,
|
|
15039
|
+
isMonorepo: false,
|
|
15040
|
+
hasApi: true,
|
|
15041
|
+
hasWeb: true
|
|
15042
|
+
},
|
|
15043
|
+
devCommand: "bun run dev",
|
|
15044
|
+
rootDependencies: {},
|
|
15045
|
+
rootDevDependencies: {
|
|
15046
|
+
"@types/bun": "latest",
|
|
15047
|
+
typescript: "^5.9.3",
|
|
15048
|
+
tailwindcss: "^4.1.18",
|
|
15049
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
15050
|
+
postcss: "^8.5.6"
|
|
15051
|
+
}
|
|
15052
|
+
},
|
|
15053
|
+
"nextjs-monorepo": {
|
|
15054
|
+
name: "nextjs-monorepo",
|
|
15055
|
+
displayName: "Next.js Monorepo",
|
|
15056
|
+
description: "Next.js + Hono + shared packages",
|
|
15057
|
+
hint: "Next.js + Hono + shared packages - enterprise SaaS architecture",
|
|
15058
|
+
emoji: "\uD83D\uDCE6",
|
|
15059
|
+
aliases: ["full", "monorepo-nextjs"],
|
|
15060
|
+
capabilities: {
|
|
15061
|
+
database: true,
|
|
15062
|
+
cssFramework: true,
|
|
15063
|
+
uiLibrary: true,
|
|
15064
|
+
auth: true,
|
|
15065
|
+
redis: true,
|
|
15066
|
+
docker: true,
|
|
15067
|
+
cicd: true,
|
|
15068
|
+
isMonorepo: true,
|
|
15069
|
+
hasApi: true,
|
|
15070
|
+
hasWeb: true
|
|
15071
|
+
},
|
|
15072
|
+
workspaceStructure: {
|
|
15073
|
+
apps: ["web", "platform", "api"],
|
|
15074
|
+
packages: ["ui", "types", "utils"],
|
|
15075
|
+
tooling: ["typescript"]
|
|
15076
|
+
},
|
|
15077
|
+
devCommand: "bun dev",
|
|
15078
|
+
rootDependencies: {},
|
|
15079
|
+
rootDevDependencies: {
|
|
15080
|
+
"@types/bun": "latest",
|
|
15081
|
+
typescript: "catalog:"
|
|
15082
|
+
},
|
|
15083
|
+
catalogEntries: {
|
|
15084
|
+
react: "^19.2.3",
|
|
15085
|
+
"react-dom": "^19.2.3",
|
|
15086
|
+
next: "^16.0.10",
|
|
15087
|
+
"@types/react": "^19.2.7",
|
|
15088
|
+
"@types/react-dom": "^19.2.3",
|
|
15089
|
+
hono: "^4.11.1",
|
|
15090
|
+
"drizzle-orm": "^0.45.1",
|
|
15091
|
+
"drizzle-kit": "^0.31.8",
|
|
15092
|
+
postgres: "^3.4.7",
|
|
15093
|
+
"@supabase/supabase-js": "^2.88.0",
|
|
15094
|
+
tailwindcss: "^4.1.18",
|
|
15095
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
15096
|
+
postcss: "^8.5.6",
|
|
15097
|
+
autoprefixer: "^10.4.23",
|
|
15098
|
+
"radix-ui": "^1.4.3",
|
|
15099
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
15100
|
+
"@base-ui/react": "^1.0.0",
|
|
15101
|
+
shadcn: "^3.6.2",
|
|
15102
|
+
"class-variance-authority": "^0.7.1",
|
|
15103
|
+
clsx: "^2.1.1",
|
|
15104
|
+
"tailwind-merge": "^3.4.0",
|
|
15105
|
+
"tw-animate-css": "^1.4.0",
|
|
15106
|
+
"@phosphor-icons/react": "^2.1.10",
|
|
15107
|
+
"iconoir-react": "^7.11.0",
|
|
15108
|
+
ultracite: "^6.4.2",
|
|
15109
|
+
"@biomejs/biome": "^2.3.10",
|
|
15110
|
+
vitest: "^4.0.16",
|
|
15111
|
+
"@vitest/ui": "^4.0.16",
|
|
15112
|
+
"@types/node": "^25.0.3",
|
|
15113
|
+
typescript: "^5.9.3"
|
|
15114
|
+
}
|
|
15115
|
+
},
|
|
15116
|
+
"bun-monorepo": {
|
|
15117
|
+
name: "bun-monorepo",
|
|
15118
|
+
displayName: "Bun Monorepo",
|
|
15119
|
+
description: "Full-stack monorepo with Bun.serve()",
|
|
15120
|
+
hint: "Full-stack monorepo with Bun.serve() - no Next.js",
|
|
15121
|
+
emoji: "\uD83D\uDD25",
|
|
15122
|
+
aliases: ["monorepo-bun"],
|
|
15123
|
+
capabilities: {
|
|
15124
|
+
database: true,
|
|
15125
|
+
cssFramework: true,
|
|
15126
|
+
uiLibrary: true,
|
|
15127
|
+
auth: true,
|
|
15128
|
+
redis: true,
|
|
15129
|
+
docker: true,
|
|
15130
|
+
cicd: true,
|
|
15131
|
+
isMonorepo: true,
|
|
15132
|
+
hasApi: true,
|
|
15133
|
+
hasWeb: true
|
|
15134
|
+
},
|
|
15135
|
+
workspaceStructure: {
|
|
15136
|
+
apps: ["web", "api"],
|
|
15137
|
+
packages: ["ui", "types", "utils"],
|
|
15138
|
+
tooling: ["typescript"]
|
|
15139
|
+
},
|
|
15140
|
+
devCommand: "bun dev",
|
|
15141
|
+
rootDependencies: {},
|
|
15142
|
+
rootDevDependencies: {
|
|
15143
|
+
"@types/bun": "latest",
|
|
15144
|
+
typescript: "catalog:"
|
|
15145
|
+
},
|
|
15146
|
+
catalogEntries: {
|
|
15147
|
+
react: "^19.2.3",
|
|
15148
|
+
"react-dom": "^19.2.3",
|
|
15149
|
+
"@types/react": "^19.2.7",
|
|
15150
|
+
"@types/react-dom": "^19.2.3",
|
|
15151
|
+
"drizzle-orm": "^0.45.1",
|
|
15152
|
+
"drizzle-kit": "^0.31.8",
|
|
15153
|
+
postgres: "^3.4.7",
|
|
15154
|
+
"@supabase/supabase-js": "^2.88.0",
|
|
15155
|
+
tailwindcss: "^4.1.18",
|
|
15156
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
15157
|
+
postcss: "^8.5.6",
|
|
15158
|
+
autoprefixer: "^10.4.23",
|
|
15159
|
+
"radix-ui": "^1.4.3",
|
|
15160
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
15161
|
+
"@base-ui/react": "^1.0.0",
|
|
15162
|
+
shadcn: "^3.6.2",
|
|
15163
|
+
"class-variance-authority": "^0.7.1",
|
|
15164
|
+
clsx: "^2.1.1",
|
|
15165
|
+
"tailwind-merge": "^3.4.0",
|
|
15166
|
+
"tw-animate-css": "^1.4.0",
|
|
15167
|
+
"@phosphor-icons/react": "^2.1.10",
|
|
15168
|
+
"iconoir-react": "^7.11.0",
|
|
15169
|
+
ultracite: "^6.4.2",
|
|
15170
|
+
"@biomejs/biome": "^2.3.10",
|
|
15171
|
+
vitest: "^4.0.16",
|
|
15172
|
+
"@vitest/ui": "^4.0.16",
|
|
15173
|
+
"@types/node": "^25.0.3",
|
|
15174
|
+
typescript: "^5.9.3"
|
|
15175
|
+
}
|
|
15176
|
+
},
|
|
15177
|
+
"enterprise-monorepo": {
|
|
15178
|
+
name: "enterprise-monorepo",
|
|
15179
|
+
displayName: "Enterprise Monorepo",
|
|
15180
|
+
description: "Multiple Next.js apps + services",
|
|
15181
|
+
hint: "Multiple Next.js apps + services - platform, app, service-identity",
|
|
15182
|
+
emoji: "\uD83C\uDFE2",
|
|
15183
|
+
aliases: [],
|
|
15184
|
+
capabilities: {
|
|
15185
|
+
database: true,
|
|
15186
|
+
cssFramework: true,
|
|
15187
|
+
uiLibrary: true,
|
|
15188
|
+
auth: true,
|
|
15189
|
+
redis: true,
|
|
15190
|
+
docker: true,
|
|
15191
|
+
cicd: true,
|
|
15192
|
+
isMonorepo: true,
|
|
15193
|
+
hasApi: true,
|
|
15194
|
+
hasWeb: true
|
|
15195
|
+
},
|
|
15196
|
+
workspaceStructure: {
|
|
15197
|
+
apps: ["web", "platform", "admin", "api", "service-identity"],
|
|
15198
|
+
packages: ["ui", "types", "utils", "db", "auth"],
|
|
15199
|
+
tooling: ["typescript", "testing"]
|
|
15200
|
+
},
|
|
15201
|
+
devCommand: "bun dev",
|
|
15202
|
+
rootDependencies: {},
|
|
15203
|
+
rootDevDependencies: {
|
|
15204
|
+
"@types/bun": "latest",
|
|
15205
|
+
typescript: "catalog:"
|
|
15206
|
+
},
|
|
15207
|
+
catalogEntries: {
|
|
15208
|
+
react: "^19.2.3",
|
|
15209
|
+
"react-dom": "^19.2.3",
|
|
15210
|
+
next: "^16.0.10",
|
|
15211
|
+
"@types/react": "^19.2.7",
|
|
15212
|
+
"@types/react-dom": "^19.2.3",
|
|
15213
|
+
hono: "^4.11.1",
|
|
15214
|
+
"drizzle-orm": "^0.45.1",
|
|
15215
|
+
"drizzle-kit": "^0.31.8",
|
|
15216
|
+
postgres: "^3.4.7",
|
|
15217
|
+
"@supabase/supabase-js": "^2.88.0",
|
|
15218
|
+
tailwindcss: "^4.1.18",
|
|
15219
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
15220
|
+
postcss: "^8.5.6",
|
|
15221
|
+
autoprefixer: "^10.4.23",
|
|
15222
|
+
"radix-ui": "^1.4.3",
|
|
15223
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
15224
|
+
"@base-ui/react": "^1.0.0",
|
|
15225
|
+
shadcn: "^3.6.2",
|
|
15226
|
+
"class-variance-authority": "^0.7.1",
|
|
15227
|
+
clsx: "^2.1.1",
|
|
15228
|
+
"tailwind-merge": "^3.4.0",
|
|
15229
|
+
"tw-animate-css": "^1.4.0",
|
|
15230
|
+
"@phosphor-icons/react": "^2.1.10",
|
|
15231
|
+
"iconoir-react": "^7.11.0",
|
|
15232
|
+
ultracite: "^6.4.2",
|
|
15233
|
+
"@biomejs/biome": "^2.3.10",
|
|
15234
|
+
vitest: "^4.0.16",
|
|
15235
|
+
"@vitest/ui": "^4.0.16",
|
|
15236
|
+
"@types/node": "^25.0.3",
|
|
15237
|
+
typescript: "^5.9.3"
|
|
15238
|
+
}
|
|
15239
|
+
}
|
|
15240
|
+
};
|
|
15241
|
+
});
|
|
15242
|
+
|
|
15243
|
+
// ../core/src/presets/custom.ts
|
|
14855
15244
|
function getPresetsDir() {
|
|
14856
15245
|
return join(process.env.HOME || process.env.USERPROFILE || ".", ".bunkit");
|
|
14857
15246
|
}
|
|
@@ -14896,11 +15285,17 @@ async function listCustomPresets() {
|
|
|
14896
15285
|
const presets = await loadCustomPresets();
|
|
14897
15286
|
return Object.values(presets);
|
|
14898
15287
|
}
|
|
14899
|
-
var
|
|
15288
|
+
var init_custom2 = __esm(() => {
|
|
14900
15289
|
init_dist();
|
|
14901
15290
|
init_fs();
|
|
14902
15291
|
});
|
|
14903
15292
|
|
|
15293
|
+
// ../core/src/presets/index.ts
|
|
15294
|
+
var init_presets = __esm(() => {
|
|
15295
|
+
init_registry();
|
|
15296
|
+
init_custom2();
|
|
15297
|
+
});
|
|
15298
|
+
|
|
14904
15299
|
// ../core/src/project.ts
|
|
14905
15300
|
async function createProject(config) {
|
|
14906
15301
|
const projectPath = join(process.cwd(), config.path);
|
|
@@ -19091,8 +19486,12 @@ var init_types2 = __esm(() => {
|
|
|
19091
19486
|
tsStrictness: exports_external.enum(["strict", "moderate", "loose"]).default("strict"),
|
|
19092
19487
|
uiLibrary: exports_external.enum(["shadcn", "none"]).optional(),
|
|
19093
19488
|
cssFramework: exports_external.enum(["tailwind", "vanilla", "css-modules"]).optional(),
|
|
19094
|
-
shadcnStyle: exports_external.enum(["new-york", "default"]).optional(),
|
|
19489
|
+
shadcnStyle: exports_external.enum(["radix-maia", "radix-vega", "radix-nova", "radix-lyra", "radix-mira", "new-york", "default"]).optional(),
|
|
19490
|
+
shadcnBase: exports_external.enum(["radix", "base-ui"]).optional(),
|
|
19095
19491
|
shadcnBaseColor: exports_external.enum(["neutral", "gray", "zinc", "stone", "slate"]).optional(),
|
|
19492
|
+
shadcnIconLibrary: exports_external.enum(["phosphor", "lucide", "iconoir"]).optional(),
|
|
19493
|
+
shadcnMenuAccent: exports_external.enum(["subtle", "bold"]).optional(),
|
|
19494
|
+
shadcnMenuColor: exports_external.enum(["default", "muted"]).optional(),
|
|
19096
19495
|
shadcnRadius: exports_external.string().optional(),
|
|
19097
19496
|
testing: exports_external.enum(["bun-test", "vitest", "none"]).default("bun-test"),
|
|
19098
19497
|
docker: exports_external.boolean().default(false),
|
|
@@ -19195,6 +19594,8 @@ __export(exports_src, {
|
|
|
19195
19594
|
addWorkspaceToRoot: () => addWorkspaceToRoot,
|
|
19196
19595
|
addToCatalog: () => addToCatalog,
|
|
19197
19596
|
ProjectConfigSchema: () => ProjectConfigSchema,
|
|
19597
|
+
PresetRegistry: () => PresetRegistry,
|
|
19598
|
+
PRESET_DEFINITIONS: () => PRESET_DEFINITIONS,
|
|
19198
19599
|
FeatureConfigSchema: () => FeatureConfigSchema
|
|
19199
19600
|
});
|
|
19200
19601
|
var init_src = __esm(() => {
|
|
@@ -21360,6 +21761,240 @@ var require_commander = __commonJS((exports) => {
|
|
|
21360
21761
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
21361
21762
|
});
|
|
21362
21763
|
|
|
21764
|
+
// ../templates/src/shared/package-json.ts
|
|
21765
|
+
var exports_package_json = {};
|
|
21766
|
+
__export(exports_package_json, {
|
|
21767
|
+
writeUtilsPackageJson: () => writeUtilsPackageJson,
|
|
21768
|
+
writeUiPackageJson: () => writeUiPackageJson,
|
|
21769
|
+
writeTypesPackageJson: () => writeTypesPackageJson,
|
|
21770
|
+
writePackageJson: () => writePackageJson,
|
|
21771
|
+
writeNextjsAppPackageJson: () => writeNextjsAppPackageJson,
|
|
21772
|
+
writeMonorepoRootPackageJson: () => writeMonorepoRootPackageJson,
|
|
21773
|
+
writeHonoApiPackageJson: () => writeHonoApiPackageJson
|
|
21774
|
+
});
|
|
21775
|
+
async function writePackageJson(directory, options) {
|
|
21776
|
+
const packageJson = {
|
|
21777
|
+
name: options.name,
|
|
21778
|
+
version: options.version ?? "0.0.0"
|
|
21779
|
+
};
|
|
21780
|
+
if (options.private !== undefined) {
|
|
21781
|
+
packageJson.private = options.private;
|
|
21782
|
+
}
|
|
21783
|
+
if (options.description) {
|
|
21784
|
+
packageJson.description = options.description;
|
|
21785
|
+
}
|
|
21786
|
+
if (options.main) {
|
|
21787
|
+
packageJson.main = options.main;
|
|
21788
|
+
}
|
|
21789
|
+
if (options.types) {
|
|
21790
|
+
packageJson.types = options.types;
|
|
21791
|
+
}
|
|
21792
|
+
if (options.exports) {
|
|
21793
|
+
packageJson.exports = options.exports;
|
|
21794
|
+
}
|
|
21795
|
+
if (options.workspaces) {
|
|
21796
|
+
packageJson.workspaces = options.workspaces;
|
|
21797
|
+
}
|
|
21798
|
+
if (options.scripts && Object.keys(options.scripts).length > 0) {
|
|
21799
|
+
packageJson.scripts = options.scripts;
|
|
21800
|
+
}
|
|
21801
|
+
if (options.dependencies && Object.keys(options.dependencies).length > 0) {
|
|
21802
|
+
packageJson.dependencies = options.dependencies;
|
|
21803
|
+
}
|
|
21804
|
+
if (options.devDependencies && Object.keys(options.devDependencies).length > 0) {
|
|
21805
|
+
packageJson.devDependencies = options.devDependencies;
|
|
21806
|
+
}
|
|
21807
|
+
if (options.peerDependencies && Object.keys(options.peerDependencies).length > 0) {
|
|
21808
|
+
packageJson.peerDependencies = options.peerDependencies;
|
|
21809
|
+
}
|
|
21810
|
+
if (options.catalog && Object.keys(options.catalog).length > 0) {
|
|
21811
|
+
packageJson.catalog = options.catalog;
|
|
21812
|
+
}
|
|
21813
|
+
await writeFile(join(directory, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
21814
|
+
}
|
|
21815
|
+
async function writeMonorepoRootPackageJson(projectPath, projectName, catalog, options = {}) {
|
|
21816
|
+
const scripts = {
|
|
21817
|
+
dev: 'bun run --filter "*" dev',
|
|
21818
|
+
build: 'bun run --filter "*" build',
|
|
21819
|
+
lint: options.codeQuality === "ultracite" ? "ultracite check ." : "biome check .",
|
|
21820
|
+
format: options.codeQuality === "ultracite" ? "ultracite fix ." : "biome format --write .",
|
|
21821
|
+
test: "bun test"
|
|
21822
|
+
};
|
|
21823
|
+
if (options.hasWeb) {
|
|
21824
|
+
scripts["dev:web"] = 'bun run --filter "@*/web" dev';
|
|
21825
|
+
}
|
|
21826
|
+
if (options.hasPlatform) {
|
|
21827
|
+
scripts["dev:platform"] = 'bun run --filter "@*/platform" dev';
|
|
21828
|
+
}
|
|
21829
|
+
if (options.hasApi) {
|
|
21830
|
+
scripts["dev:api"] = 'bun run --filter "@*/api" dev';
|
|
21831
|
+
scripts.debug = "bun --inspect apps/api/src/index.ts";
|
|
21832
|
+
scripts["debug:brk"] = "bun --inspect-brk apps/api/src/index.ts";
|
|
21833
|
+
scripts["debug:wait"] = "bun --inspect-wait apps/api/src/index.ts";
|
|
21834
|
+
}
|
|
21835
|
+
await writePackageJson(projectPath, {
|
|
21836
|
+
name: `${projectName}-monorepo`,
|
|
21837
|
+
version: "0.0.0",
|
|
21838
|
+
private: true,
|
|
21839
|
+
workspaces: ["apps/*", "packages/*"],
|
|
21840
|
+
scripts,
|
|
21841
|
+
devDependencies: {
|
|
21842
|
+
"@types/bun": "latest",
|
|
21843
|
+
typescript: "catalog:"
|
|
21844
|
+
},
|
|
21845
|
+
catalog
|
|
21846
|
+
});
|
|
21847
|
+
}
|
|
21848
|
+
async function writeNextjsAppPackageJson(appPath, scopeName, appName, options = {}) {
|
|
21849
|
+
const dependencies = {
|
|
21850
|
+
react: "catalog:",
|
|
21851
|
+
"react-dom": "catalog:",
|
|
21852
|
+
next: "catalog:",
|
|
21853
|
+
"iconoir-react": "catalog:"
|
|
21854
|
+
};
|
|
21855
|
+
if (options.usesTypes) {
|
|
21856
|
+
dependencies[`@${scopeName}/types`] = "workspace:*";
|
|
21857
|
+
}
|
|
21858
|
+
if (options.usesUi) {
|
|
21859
|
+
dependencies[`@${scopeName}/ui`] = "workspace:*";
|
|
21860
|
+
}
|
|
21861
|
+
const devDependencies = {
|
|
21862
|
+
"@types/react": "catalog:",
|
|
21863
|
+
"@types/react-dom": "catalog:",
|
|
21864
|
+
"@types/node": "catalog:",
|
|
21865
|
+
typescript: "catalog:",
|
|
21866
|
+
tailwindcss: "catalog:",
|
|
21867
|
+
"@tailwindcss/postcss": "catalog:",
|
|
21868
|
+
postcss: "catalog:"
|
|
21869
|
+
};
|
|
21870
|
+
await writePackageJson(appPath, {
|
|
21871
|
+
name: `@${scopeName}/${appName}`,
|
|
21872
|
+
version: "0.0.0",
|
|
21873
|
+
private: true,
|
|
21874
|
+
scripts: {
|
|
21875
|
+
dev: "next dev",
|
|
21876
|
+
build: "next build",
|
|
21877
|
+
start: "next start",
|
|
21878
|
+
debug: "bun --inspect node_modules/.bin/next dev",
|
|
21879
|
+
"debug:brk": "bun --inspect-brk node_modules/.bin/next dev",
|
|
21880
|
+
"debug:wait": "bun --inspect-wait node_modules/.bin/next dev"
|
|
21881
|
+
},
|
|
21882
|
+
dependencies,
|
|
21883
|
+
devDependencies
|
|
21884
|
+
});
|
|
21885
|
+
}
|
|
21886
|
+
async function writeHonoApiPackageJson(appPath, scopeName, options = {}) {
|
|
21887
|
+
const dependencies = {
|
|
21888
|
+
hono: "catalog:"
|
|
21889
|
+
};
|
|
21890
|
+
if (options.usesTypes) {
|
|
21891
|
+
dependencies[`@${scopeName}/types`] = "workspace:*";
|
|
21892
|
+
}
|
|
21893
|
+
if (options.usesDb) {
|
|
21894
|
+
dependencies[`@${scopeName}/db`] = "workspace:*";
|
|
21895
|
+
}
|
|
21896
|
+
await writePackageJson(appPath, {
|
|
21897
|
+
name: `@${scopeName}/api`,
|
|
21898
|
+
version: "0.0.0",
|
|
21899
|
+
private: true,
|
|
21900
|
+
scripts: {
|
|
21901
|
+
dev: "bun --hot src/index.ts",
|
|
21902
|
+
build: "bun build src/index.ts --outdir dist --target bun",
|
|
21903
|
+
start: "bun dist/index.js",
|
|
21904
|
+
debug: "bun --inspect src/index.ts",
|
|
21905
|
+
"debug:brk": "bun --inspect-brk src/index.ts",
|
|
21906
|
+
"debug:wait": "bun --inspect-wait src/index.ts"
|
|
21907
|
+
},
|
|
21908
|
+
dependencies,
|
|
21909
|
+
devDependencies: {
|
|
21910
|
+
"@types/bun": "latest",
|
|
21911
|
+
typescript: "catalog:"
|
|
21912
|
+
}
|
|
21913
|
+
});
|
|
21914
|
+
}
|
|
21915
|
+
async function writeUiPackageJson(packagePath, scopeName) {
|
|
21916
|
+
await writePackageJson(packagePath, {
|
|
21917
|
+
name: `@${scopeName}/ui`,
|
|
21918
|
+
version: "0.0.0",
|
|
21919
|
+
private: true,
|
|
21920
|
+
main: "./src/index.ts",
|
|
21921
|
+
types: "./src/index.ts",
|
|
21922
|
+
exports: {
|
|
21923
|
+
".": "./src/index.ts",
|
|
21924
|
+
"./components": "./src/components/index.ts",
|
|
21925
|
+
"./lib/utils": "./src/lib/utils.ts",
|
|
21926
|
+
"./hooks": "./src/hooks/index.ts",
|
|
21927
|
+
"./globals.css": "./src/styles/globals.css",
|
|
21928
|
+
"./postcss.config": "./postcss.config.mjs"
|
|
21929
|
+
},
|
|
21930
|
+
scripts: {
|
|
21931
|
+
build: "tsc --noEmit",
|
|
21932
|
+
lint: "tsc --noEmit"
|
|
21933
|
+
},
|
|
21934
|
+
dependencies: {
|
|
21935
|
+
"@radix-ui/react-slot": "catalog:",
|
|
21936
|
+
"class-variance-authority": "catalog:",
|
|
21937
|
+
clsx: "catalog:",
|
|
21938
|
+
"tailwind-merge": "catalog:",
|
|
21939
|
+
"iconoir-react": "catalog:",
|
|
21940
|
+
tailwindcss: "catalog:",
|
|
21941
|
+
"@tailwindcss/postcss": "catalog:",
|
|
21942
|
+
postcss: "catalog:"
|
|
21943
|
+
},
|
|
21944
|
+
devDependencies: {
|
|
21945
|
+
"@types/react": "catalog:",
|
|
21946
|
+
"@types/react-dom": "catalog:",
|
|
21947
|
+
typescript: "catalog:"
|
|
21948
|
+
},
|
|
21949
|
+
peerDependencies: {
|
|
21950
|
+
react: "^19.0.0",
|
|
21951
|
+
"react-dom": "^19.0.0"
|
|
21952
|
+
}
|
|
21953
|
+
});
|
|
21954
|
+
}
|
|
21955
|
+
async function writeTypesPackageJson(packagePath, scopeName) {
|
|
21956
|
+
await writePackageJson(packagePath, {
|
|
21957
|
+
name: `@${scopeName}/types`,
|
|
21958
|
+
version: "0.0.0",
|
|
21959
|
+
private: true,
|
|
21960
|
+
main: "./src/index.ts",
|
|
21961
|
+
types: "./src/index.ts",
|
|
21962
|
+
exports: {
|
|
21963
|
+
".": "./src/index.ts"
|
|
21964
|
+
},
|
|
21965
|
+
scripts: {
|
|
21966
|
+
build: "tsc --noEmit",
|
|
21967
|
+
lint: "tsc --noEmit"
|
|
21968
|
+
},
|
|
21969
|
+
devDependencies: {
|
|
21970
|
+
typescript: "catalog:"
|
|
21971
|
+
}
|
|
21972
|
+
});
|
|
21973
|
+
}
|
|
21974
|
+
async function writeUtilsPackageJson(packagePath, scopeName) {
|
|
21975
|
+
await writePackageJson(packagePath, {
|
|
21976
|
+
name: `@${scopeName}/utils`,
|
|
21977
|
+
version: "0.0.0",
|
|
21978
|
+
private: true,
|
|
21979
|
+
main: "./src/index.ts",
|
|
21980
|
+
types: "./src/index.ts",
|
|
21981
|
+
exports: {
|
|
21982
|
+
".": "./src/index.ts"
|
|
21983
|
+
},
|
|
21984
|
+
scripts: {
|
|
21985
|
+
build: "tsc --noEmit",
|
|
21986
|
+
lint: "tsc --noEmit"
|
|
21987
|
+
},
|
|
21988
|
+
devDependencies: {
|
|
21989
|
+
typescript: "catalog:"
|
|
21990
|
+
}
|
|
21991
|
+
});
|
|
21992
|
+
}
|
|
21993
|
+
var init_package_json = __esm(() => {
|
|
21994
|
+
init_src();
|
|
21995
|
+
init_dist();
|
|
21996
|
+
});
|
|
21997
|
+
|
|
21363
21998
|
// ../../node_modules/.bun/ejs@3.1.10/node_modules/ejs/lib/utils.js
|
|
21364
21999
|
var require_utils5 = __commonJS((exports) => {
|
|
21365
22000
|
var regExpChars = /[|\\{}()[\]^$+*?.]/g;
|
|
@@ -27823,12 +28458,7 @@ var themes = {
|
|
|
27823
28458
|
};
|
|
27824
28459
|
function generateThemeCSS(theme, customRadius) {
|
|
27825
28460
|
const radius = customRadius || theme.light.radius;
|
|
27826
|
-
return
|
|
27827
|
-
@source "../../../apps/**/*.{ts,tsx}";
|
|
27828
|
-
@source "../../../components/**/*.{ts,tsx}";
|
|
27829
|
-
@source "../**/*.{ts,tsx}";
|
|
27830
|
-
|
|
27831
|
-
:root {
|
|
28461
|
+
return `:root {
|
|
27832
28462
|
--radius: ${radius};
|
|
27833
28463
|
--background: ${theme.light.background};
|
|
27834
28464
|
--foreground: ${theme.light.foreground};
|
|
@@ -27947,58 +28577,183 @@ function generateThemeCSS(theme, customRadius) {
|
|
|
27947
28577
|
}
|
|
27948
28578
|
`;
|
|
27949
28579
|
}
|
|
27950
|
-
|
|
27951
|
-
|
|
27952
|
-
|
|
27953
|
-
|
|
27954
|
-
|
|
27955
|
-
|
|
27956
|
-
|
|
27957
|
-
|
|
27958
|
-
|
|
27959
|
-
|
|
27960
|
-
|
|
27961
|
-
|
|
27962
|
-
|
|
27963
|
-
|
|
27964
|
-
|
|
27965
|
-
|
|
27966
|
-
|
|
27967
|
-
|
|
27968
|
-
|
|
27969
|
-
|
|
27970
|
-
|
|
27971
|
-
|
|
27972
|
-
|
|
27973
|
-
|
|
27974
|
-
|
|
27975
|
-
|
|
27976
|
-
|
|
27977
|
-
|
|
27978
|
-
|
|
27979
|
-
|
|
27980
|
-
|
|
27981
|
-
|
|
27982
|
-
|
|
27983
|
-
|
|
28580
|
+
function generateModernThemeCSS(baseColor, customRadius) {
|
|
28581
|
+
const theme = themes[baseColor] || themes.zinc;
|
|
28582
|
+
const radius = customRadius || "0.625rem";
|
|
28583
|
+
return `@theme inline {
|
|
28584
|
+
--color-background: var(--background);
|
|
28585
|
+
--color-foreground: var(--foreground);
|
|
28586
|
+
--font-sans: var(--font-sans);
|
|
28587
|
+
--font-mono: var(--font-geist-mono);
|
|
28588
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
28589
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
28590
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
28591
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
28592
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
28593
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
28594
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
28595
|
+
--color-sidebar: var(--sidebar);
|
|
28596
|
+
--color-chart-5: var(--chart-5);
|
|
28597
|
+
--color-chart-4: var(--chart-4);
|
|
28598
|
+
--color-chart-3: var(--chart-3);
|
|
28599
|
+
--color-chart-2: var(--chart-2);
|
|
28600
|
+
--color-chart-1: var(--chart-1);
|
|
28601
|
+
--color-ring: var(--ring);
|
|
28602
|
+
--color-input: var(--input);
|
|
28603
|
+
--color-border: var(--border);
|
|
28604
|
+
--color-destructive: var(--destructive);
|
|
28605
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
28606
|
+
--color-accent: var(--accent);
|
|
28607
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
28608
|
+
--color-muted: var(--muted);
|
|
28609
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
28610
|
+
--color-secondary: var(--secondary);
|
|
28611
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
28612
|
+
--color-primary: var(--primary);
|
|
28613
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
28614
|
+
--color-popover: var(--popover);
|
|
28615
|
+
--color-card-foreground: var(--card-foreground);
|
|
28616
|
+
--color-card: var(--card);
|
|
28617
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
28618
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
28619
|
+
--radius-lg: var(--radius);
|
|
28620
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
28621
|
+
--radius-2xl: calc(var(--radius) + 8px);
|
|
28622
|
+
--radius-3xl: calc(var(--radius) + 12px);
|
|
28623
|
+
--radius-4xl: calc(var(--radius) + 16px);
|
|
27984
28624
|
}
|
|
27985
|
-
|
|
27986
|
-
|
|
27987
|
-
|
|
27988
|
-
|
|
27989
|
-
|
|
27990
|
-
|
|
27991
|
-
|
|
27992
|
-
|
|
27993
|
-
|
|
27994
|
-
}
|
|
27995
|
-
|
|
27996
|
-
|
|
27997
|
-
|
|
27998
|
-
|
|
27999
|
-
|
|
28000
|
-
|
|
28001
|
-
|
|
28625
|
+
|
|
28626
|
+
:root {
|
|
28627
|
+
--background: ${theme.light.background};
|
|
28628
|
+
--foreground: ${theme.light.foreground};
|
|
28629
|
+
--card: ${theme.light.card};
|
|
28630
|
+
--card-foreground: ${theme.light.cardForeground};
|
|
28631
|
+
--popover: ${theme.light.popover};
|
|
28632
|
+
--popover-foreground: ${theme.light.popoverForeground};
|
|
28633
|
+
--primary: ${theme.light.primary};
|
|
28634
|
+
--primary-foreground: ${theme.light.primaryForeground};
|
|
28635
|
+
--secondary: ${theme.light.secondary};
|
|
28636
|
+
--secondary-foreground: ${theme.light.secondaryForeground};
|
|
28637
|
+
--muted: ${theme.light.muted};
|
|
28638
|
+
--muted-foreground: ${theme.light.mutedForeground};
|
|
28639
|
+
--accent: ${theme.light.accent};
|
|
28640
|
+
--accent-foreground: ${theme.light.accentForeground};
|
|
28641
|
+
--destructive: ${theme.light.destructive};
|
|
28642
|
+
--border: ${theme.light.border};
|
|
28643
|
+
--input: ${theme.light.input};
|
|
28644
|
+
--ring: ${theme.light.ring};
|
|
28645
|
+
--chart-1: ${theme.light.chart1};
|
|
28646
|
+
--chart-2: ${theme.light.chart2};
|
|
28647
|
+
--chart-3: ${theme.light.chart3};
|
|
28648
|
+
--chart-4: ${theme.light.chart4};
|
|
28649
|
+
--chart-5: ${theme.light.chart5};
|
|
28650
|
+
--radius: ${radius};
|
|
28651
|
+
--sidebar: ${theme.light.sidebar};
|
|
28652
|
+
--sidebar-foreground: ${theme.light.sidebarForeground};
|
|
28653
|
+
--sidebar-primary: ${theme.light.sidebarPrimary};
|
|
28654
|
+
--sidebar-primary-foreground: ${theme.light.sidebarPrimaryForeground};
|
|
28655
|
+
--sidebar-accent: ${theme.light.sidebarAccent};
|
|
28656
|
+
--sidebar-accent-foreground: ${theme.light.sidebarAccentForeground};
|
|
28657
|
+
--sidebar-border: ${theme.light.sidebarBorder};
|
|
28658
|
+
--sidebar-ring: ${theme.light.sidebarRing};
|
|
28659
|
+
}
|
|
28660
|
+
|
|
28661
|
+
.dark {
|
|
28662
|
+
--background: ${theme.dark.background};
|
|
28663
|
+
--foreground: ${theme.dark.foreground};
|
|
28664
|
+
--card: ${theme.dark.card};
|
|
28665
|
+
--card-foreground: ${theme.dark.cardForeground};
|
|
28666
|
+
--popover: ${theme.dark.popover};
|
|
28667
|
+
--popover-foreground: ${theme.dark.popoverForeground};
|
|
28668
|
+
--primary: ${theme.dark.primary};
|
|
28669
|
+
--primary-foreground: ${theme.dark.primaryForeground};
|
|
28670
|
+
--secondary: ${theme.dark.secondary};
|
|
28671
|
+
--secondary-foreground: ${theme.dark.secondaryForeground};
|
|
28672
|
+
--muted: ${theme.dark.muted};
|
|
28673
|
+
--muted-foreground: ${theme.dark.mutedForeground};
|
|
28674
|
+
--accent: ${theme.dark.accent};
|
|
28675
|
+
--accent-foreground: ${theme.dark.accentForeground};
|
|
28676
|
+
--destructive: ${theme.dark.destructive};
|
|
28677
|
+
--border: ${theme.dark.border};
|
|
28678
|
+
--input: ${theme.dark.input};
|
|
28679
|
+
--ring: ${theme.dark.ring};
|
|
28680
|
+
--chart-1: ${theme.dark.chart1};
|
|
28681
|
+
--chart-2: ${theme.dark.chart2};
|
|
28682
|
+
--chart-3: ${theme.dark.chart3};
|
|
28683
|
+
--chart-4: ${theme.dark.chart4};
|
|
28684
|
+
--chart-5: ${theme.dark.chart5};
|
|
28685
|
+
--sidebar: ${theme.dark.sidebar};
|
|
28686
|
+
--sidebar-foreground: ${theme.dark.sidebarForeground};
|
|
28687
|
+
--sidebar-primary: ${theme.dark.sidebarPrimary};
|
|
28688
|
+
--sidebar-primary-foreground: ${theme.dark.sidebarPrimaryForeground};
|
|
28689
|
+
--sidebar-accent: ${theme.dark.sidebarAccent};
|
|
28690
|
+
--sidebar-accent-foreground: ${theme.dark.sidebarAccentForeground};
|
|
28691
|
+
--sidebar-border: ${theme.dark.sidebarBorder};
|
|
28692
|
+
--sidebar-ring: ${theme.dark.sidebarRing};
|
|
28693
|
+
}
|
|
28694
|
+
|
|
28695
|
+
@layer base {
|
|
28696
|
+
* {
|
|
28697
|
+
@apply border-border outline-ring/50;
|
|
28698
|
+
}
|
|
28699
|
+
body {
|
|
28700
|
+
@apply bg-background text-foreground;
|
|
28701
|
+
}
|
|
28702
|
+
}
|
|
28703
|
+
`;
|
|
28704
|
+
}
|
|
28705
|
+
|
|
28706
|
+
// ../templates/src/generators/shadcn.ts
|
|
28707
|
+
async function setupShadcnWeb(projectPath, context) {
|
|
28708
|
+
await ensureDirectory(join(projectPath, "src/components/ui"));
|
|
28709
|
+
await ensureDirectory(join(projectPath, "src/lib"));
|
|
28710
|
+
const style = context.shadcnStyle || "new-york";
|
|
28711
|
+
const baseColor = context.shadcnBaseColor || "zinc";
|
|
28712
|
+
const radius = context.shadcnRadius || "0.625rem";
|
|
28713
|
+
const componentsJson = {
|
|
28714
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
28715
|
+
style,
|
|
28716
|
+
rsc: true,
|
|
28717
|
+
tsx: true,
|
|
28718
|
+
tailwind: {
|
|
28719
|
+
config: "",
|
|
28720
|
+
css: "src/app/globals.css",
|
|
28721
|
+
baseColor,
|
|
28722
|
+
cssVariables: true
|
|
28723
|
+
},
|
|
28724
|
+
iconLibrary: "lucide",
|
|
28725
|
+
aliases: {
|
|
28726
|
+
components: "@/components",
|
|
28727
|
+
utils: "@/lib/utils",
|
|
28728
|
+
ui: "@/components/ui",
|
|
28729
|
+
lib: "@/lib",
|
|
28730
|
+
hooks: "@/hooks"
|
|
28731
|
+
}
|
|
28732
|
+
};
|
|
28733
|
+
await writeFile(join(projectPath, "components.json"), JSON.stringify(componentsJson, null, 2));
|
|
28734
|
+
const utilsContent = `import { clsx, type ClassValue } from 'clsx';
|
|
28735
|
+
import { twMerge } from 'tailwind-merge';
|
|
28736
|
+
|
|
28737
|
+
export function cn(...inputs: ClassValue[]) {
|
|
28738
|
+
return twMerge(clsx(inputs));
|
|
28739
|
+
}
|
|
28740
|
+
`;
|
|
28741
|
+
await writeFile(join(projectPath, "src/lib/utils.ts"), utilsContent);
|
|
28742
|
+
const packageJsonPath = join(projectPath, "package.json");
|
|
28743
|
+
let packageJson = {};
|
|
28744
|
+
try {
|
|
28745
|
+
packageJson = JSON.parse(await Bun.file(packageJsonPath).text());
|
|
28746
|
+
} catch {}
|
|
28747
|
+
if (!packageJson.dependencies) {
|
|
28748
|
+
packageJson.dependencies = {};
|
|
28749
|
+
}
|
|
28750
|
+
packageJson.dependencies["@radix-ui/react-slot"] = "catalog:";
|
|
28751
|
+
packageJson.dependencies["class-variance-authority"] = "catalog:";
|
|
28752
|
+
packageJson.dependencies.clsx = "catalog:";
|
|
28753
|
+
packageJson.dependencies["tailwind-merge"] = "catalog:";
|
|
28754
|
+
packageJson.dependencies["lucide-react"] = "catalog:";
|
|
28755
|
+
if (!packageJson.catalog) {
|
|
28756
|
+
packageJson.catalog = {};
|
|
28002
28757
|
}
|
|
28003
28758
|
packageJson.catalog["@radix-ui/react-slot"] = "^1.2.4";
|
|
28004
28759
|
packageJson.catalog["class-variance-authority"] = "^0.7.1";
|
|
@@ -30266,6 +31021,622 @@ export default config;
|
|
|
30266
31021
|
await writeFile(packageJsonPath, JSON.stringify(existingPackageJson, null, 2));
|
|
30267
31022
|
await generateNextjsReadme(projectPath, context);
|
|
30268
31023
|
}
|
|
31024
|
+
// ../templates/src/builders/full-v2.ts
|
|
31025
|
+
init_src();
|
|
31026
|
+
init_dist();
|
|
31027
|
+
init_package_json();
|
|
31028
|
+
|
|
31029
|
+
// ../templates/src/shared/ui-package.ts
|
|
31030
|
+
init_src();
|
|
31031
|
+
init_dist();
|
|
31032
|
+
init_package_json();
|
|
31033
|
+
function isModernStyle(style) {
|
|
31034
|
+
return style === "radix-maia" || style === "radix-vega" || style === "radix-nova" || style === "radix-lyra" || style === "radix-mira";
|
|
31035
|
+
}
|
|
31036
|
+
async function buildUiPackage(packagesPath, options) {
|
|
31037
|
+
const uiPath = join(packagesPath, "ui");
|
|
31038
|
+
await ensureDirectory(join(uiPath, "src/components"));
|
|
31039
|
+
await ensureDirectory(join(uiPath, "src/hooks"));
|
|
31040
|
+
await ensureDirectory(join(uiPath, "src/lib"));
|
|
31041
|
+
await ensureDirectory(join(uiPath, "src/styles"));
|
|
31042
|
+
await writeUiPackageJson(uiPath, options.scopeName);
|
|
31043
|
+
await writeFile(join(uiPath, "tsconfig.json"), JSON.stringify({
|
|
31044
|
+
extends: "../../tooling/typescript/library.json",
|
|
31045
|
+
compilerOptions: {
|
|
31046
|
+
jsx: "react-jsx",
|
|
31047
|
+
rootDir: "./src",
|
|
31048
|
+
outDir: "./dist",
|
|
31049
|
+
baseUrl: ".",
|
|
31050
|
+
paths: {
|
|
31051
|
+
"@/*": ["./src/*"]
|
|
31052
|
+
}
|
|
31053
|
+
},
|
|
31054
|
+
include: ["src/**/*"],
|
|
31055
|
+
exclude: ["node_modules"]
|
|
31056
|
+
}, null, 2));
|
|
31057
|
+
const style = options.shadcnStyle || "radix-maia";
|
|
31058
|
+
const useModernStyle = isModernStyle(style);
|
|
31059
|
+
const iconLibrary = options.shadcnIconLibrary || (useModernStyle ? "phosphor" : "iconoir");
|
|
31060
|
+
const componentsJson = {
|
|
31061
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
31062
|
+
style,
|
|
31063
|
+
rsc: true,
|
|
31064
|
+
tsx: true,
|
|
31065
|
+
tailwind: {
|
|
31066
|
+
config: "",
|
|
31067
|
+
css: "./src/styles/globals.css",
|
|
31068
|
+
baseColor: options.shadcnBaseColor || "zinc",
|
|
31069
|
+
cssVariables: true,
|
|
31070
|
+
prefix: ""
|
|
31071
|
+
},
|
|
31072
|
+
iconLibrary,
|
|
31073
|
+
aliases: {
|
|
31074
|
+
components: "./src/components",
|
|
31075
|
+
utils: "./src/lib/utils",
|
|
31076
|
+
ui: "./src/components/ui",
|
|
31077
|
+
lib: "./src/lib",
|
|
31078
|
+
hooks: "./src/hooks"
|
|
31079
|
+
}
|
|
31080
|
+
};
|
|
31081
|
+
if (useModernStyle) {
|
|
31082
|
+
componentsJson.menuColor = options.shadcnMenuColor || "default";
|
|
31083
|
+
componentsJson.menuAccent = options.shadcnMenuAccent || "subtle";
|
|
31084
|
+
componentsJson.registries = {};
|
|
31085
|
+
}
|
|
31086
|
+
await writeFile(join(uiPath, "components.json"), JSON.stringify(componentsJson, null, 2));
|
|
31087
|
+
await writeFile(join(uiPath, "postcss.config.mjs"), `export default {
|
|
31088
|
+
plugins: {
|
|
31089
|
+
'@tailwindcss/postcss': {},
|
|
31090
|
+
},
|
|
31091
|
+
};
|
|
31092
|
+
`);
|
|
31093
|
+
const appsToScan = options.appsToScan || ["web", "platform"];
|
|
31094
|
+
const appSourcePaths = appsToScan.map((app) => `@source "../../../apps/${app}/src/**/*.{ts,tsx}";`);
|
|
31095
|
+
const baseColor = options.shadcnBaseColor || "zinc";
|
|
31096
|
+
const customRadius = options.shadcnRadius || "0.625rem";
|
|
31097
|
+
let globalsCss;
|
|
31098
|
+
if (useModernStyle) {
|
|
31099
|
+
const modernThemeCSS = generateModernThemeCSS(baseColor, customRadius);
|
|
31100
|
+
globalsCss = `@import "tailwindcss";
|
|
31101
|
+
@import "tw-animate-css";
|
|
31102
|
+
@import "shadcn/tailwind.css";
|
|
31103
|
+
${appSourcePaths.join(`
|
|
31104
|
+
`)}
|
|
31105
|
+
@source "../**/*.{ts,tsx}";
|
|
31106
|
+
|
|
31107
|
+
@custom-variant dark (&:is(.dark *));
|
|
31108
|
+
|
|
31109
|
+
${modernThemeCSS}
|
|
31110
|
+
`;
|
|
31111
|
+
} else {
|
|
31112
|
+
const theme = themes[baseColor] || themes.zinc;
|
|
31113
|
+
const themeCSS = generateThemeCSS(theme, customRadius);
|
|
31114
|
+
globalsCss = `@import "tailwindcss";
|
|
31115
|
+
${appSourcePaths.join(`
|
|
31116
|
+
`)}
|
|
31117
|
+
@source "../**/*.{ts,tsx}";
|
|
31118
|
+
|
|
31119
|
+
${themeCSS}
|
|
31120
|
+
`;
|
|
31121
|
+
}
|
|
31122
|
+
await writeFile(join(uiPath, "src/styles/globals.css"), globalsCss);
|
|
31123
|
+
await writeFile(join(uiPath, "src/lib/utils.ts"), `import { clsx, type ClassValue } from 'clsx';
|
|
31124
|
+
import { twMerge } from 'tailwind-merge';
|
|
31125
|
+
|
|
31126
|
+
export function cn(...inputs: ClassValue[]) {
|
|
31127
|
+
return twMerge(clsx(inputs));
|
|
31128
|
+
}
|
|
31129
|
+
`);
|
|
31130
|
+
await writeFile(join(uiPath, "src/components/index.ts"), `/**
|
|
31131
|
+
* UI Components
|
|
31132
|
+
*
|
|
31133
|
+
* Add shadcn/ui components using:
|
|
31134
|
+
* bunx shadcn@latest add button card dialog ...
|
|
31135
|
+
*
|
|
31136
|
+
* Then export them here for use across apps.
|
|
31137
|
+
*/
|
|
31138
|
+
|
|
31139
|
+
// Export components as they are added
|
|
31140
|
+
// Example: export { Button } from './ui/button';
|
|
31141
|
+
|
|
31142
|
+
// Empty export to make this a valid ES module
|
|
31143
|
+
export {};
|
|
31144
|
+
`);
|
|
31145
|
+
await writeFile(join(uiPath, "src/hooks/index.ts"), `/**
|
|
31146
|
+
* Shared Hooks
|
|
31147
|
+
*
|
|
31148
|
+
* Custom React hooks shared across apps.
|
|
31149
|
+
*/
|
|
31150
|
+
|
|
31151
|
+
// Export hooks as they are added
|
|
31152
|
+
// Example: export { useMediaQuery } from './use-media-query';
|
|
31153
|
+
|
|
31154
|
+
// Empty export to make this a valid ES module
|
|
31155
|
+
export {};
|
|
31156
|
+
`);
|
|
31157
|
+
await writeFile(join(uiPath, "src/index.ts"), `/**
|
|
31158
|
+
* @${options.scopeName}/ui - Shared UI Components
|
|
31159
|
+
*
|
|
31160
|
+
* This package provides:
|
|
31161
|
+
* - shadcn/ui components (add with: bunx shadcn@latest add <component>)
|
|
31162
|
+
* - Tailwind CSS v4 configuration
|
|
31163
|
+
* - Shared hooks and utilities
|
|
31164
|
+
*
|
|
31165
|
+
* Usage in apps:
|
|
31166
|
+
* - Import globals.css: import '@${options.scopeName}/ui/globals.css';
|
|
31167
|
+
* - Import components: import { Button } from '@${options.scopeName}/ui/components';
|
|
31168
|
+
* - Import utils: import { cn } from '@${options.scopeName}/ui/lib/utils';
|
|
31169
|
+
*/
|
|
31170
|
+
|
|
31171
|
+
export * from './lib/utils';
|
|
31172
|
+
export * from './hooks';
|
|
31173
|
+
export * from './components';
|
|
31174
|
+
`);
|
|
31175
|
+
}
|
|
31176
|
+
async function buildTypesPackage(packagesPath, scopeName) {
|
|
31177
|
+
const typesPath = join(packagesPath, "types");
|
|
31178
|
+
await ensureDirectory(join(typesPath, "src"));
|
|
31179
|
+
const { writeTypesPackageJson: writeTypesPackageJson2 } = await Promise.resolve().then(() => (init_package_json(), exports_package_json));
|
|
31180
|
+
await writeTypesPackageJson2(typesPath, scopeName);
|
|
31181
|
+
await writeFile(join(typesPath, "tsconfig.json"), JSON.stringify({
|
|
31182
|
+
extends: "../../tooling/typescript/library.json",
|
|
31183
|
+
compilerOptions: {
|
|
31184
|
+
rootDir: "./src",
|
|
31185
|
+
outDir: "./dist"
|
|
31186
|
+
},
|
|
31187
|
+
include: ["src/**/*"],
|
|
31188
|
+
exclude: ["node_modules"]
|
|
31189
|
+
}, null, 2));
|
|
31190
|
+
await writeFile(join(typesPath, "src/index.ts"), `/**
|
|
31191
|
+
* @${scopeName}/types - Shared TypeScript Types
|
|
31192
|
+
*
|
|
31193
|
+
* Define types that are shared across multiple packages/apps here.
|
|
31194
|
+
*/
|
|
31195
|
+
|
|
31196
|
+
// Example types - replace with your actual types
|
|
31197
|
+
|
|
31198
|
+
export interface User {
|
|
31199
|
+
id: string;
|
|
31200
|
+
email: string;
|
|
31201
|
+
name?: string;
|
|
31202
|
+
createdAt: Date;
|
|
31203
|
+
updatedAt: Date;
|
|
31204
|
+
}
|
|
31205
|
+
|
|
31206
|
+
export interface ApiResponse<T> {
|
|
31207
|
+
success: boolean;
|
|
31208
|
+
data?: T;
|
|
31209
|
+
error?: {
|
|
31210
|
+
code: string;
|
|
31211
|
+
message: string;
|
|
31212
|
+
};
|
|
31213
|
+
}
|
|
31214
|
+
|
|
31215
|
+
export interface PaginatedResponse<T> extends ApiResponse<T[]> {
|
|
31216
|
+
pagination: {
|
|
31217
|
+
page: number;
|
|
31218
|
+
perPage: number;
|
|
31219
|
+
total: number;
|
|
31220
|
+
totalPages: number;
|
|
31221
|
+
};
|
|
31222
|
+
}
|
|
31223
|
+
`);
|
|
31224
|
+
}
|
|
31225
|
+
async function buildUtilsPackage(packagesPath, scopeName) {
|
|
31226
|
+
const utilsPath = join(packagesPath, "utils");
|
|
31227
|
+
await ensureDirectory(join(utilsPath, "src"));
|
|
31228
|
+
const { writeUtilsPackageJson: writeUtilsPackageJson2 } = await Promise.resolve().then(() => (init_package_json(), exports_package_json));
|
|
31229
|
+
await writeUtilsPackageJson2(utilsPath, scopeName);
|
|
31230
|
+
await writeFile(join(utilsPath, "tsconfig.json"), JSON.stringify({
|
|
31231
|
+
extends: "../../tooling/typescript/library.json",
|
|
31232
|
+
compilerOptions: {
|
|
31233
|
+
rootDir: "./src",
|
|
31234
|
+
outDir: "./dist"
|
|
31235
|
+
},
|
|
31236
|
+
include: ["src/**/*"],
|
|
31237
|
+
exclude: ["node_modules"]
|
|
31238
|
+
}, null, 2));
|
|
31239
|
+
await writeFile(join(utilsPath, "src/index.ts"), `/**
|
|
31240
|
+
* @${scopeName}/utils - Shared Utilities
|
|
31241
|
+
*
|
|
31242
|
+
* Utility functions shared across packages and apps.
|
|
31243
|
+
*/
|
|
31244
|
+
|
|
31245
|
+
/**
|
|
31246
|
+
* Format a date to a human-readable string
|
|
31247
|
+
*/
|
|
31248
|
+
export function formatDate(date: Date | string, locale = 'en-US'): string {
|
|
31249
|
+
const d = typeof date === 'string' ? new Date(date) : date;
|
|
31250
|
+
return d.toLocaleDateString(locale, {
|
|
31251
|
+
year: 'numeric',
|
|
31252
|
+
month: 'long',
|
|
31253
|
+
day: 'numeric',
|
|
31254
|
+
});
|
|
31255
|
+
}
|
|
31256
|
+
|
|
31257
|
+
/**
|
|
31258
|
+
* Format a number as currency
|
|
31259
|
+
*/
|
|
31260
|
+
export function formatCurrency(
|
|
31261
|
+
amount: number,
|
|
31262
|
+
currency = 'USD',
|
|
31263
|
+
locale = 'en-US'
|
|
31264
|
+
): string {
|
|
31265
|
+
return new Intl.NumberFormat(locale, {
|
|
31266
|
+
style: 'currency',
|
|
31267
|
+
currency,
|
|
31268
|
+
}).format(amount);
|
|
31269
|
+
}
|
|
31270
|
+
|
|
31271
|
+
/**
|
|
31272
|
+
* Sleep for a specified number of milliseconds
|
|
31273
|
+
*/
|
|
31274
|
+
export function sleep(ms: number): Promise<void> {
|
|
31275
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
31276
|
+
}
|
|
31277
|
+
|
|
31278
|
+
/**
|
|
31279
|
+
* Safely parse JSON with a fallback value
|
|
31280
|
+
*/
|
|
31281
|
+
export function safeJsonParse<T>(json: string, fallback: T): T {
|
|
31282
|
+
try {
|
|
31283
|
+
return JSON.parse(json) as T;
|
|
31284
|
+
} catch {
|
|
31285
|
+
return fallback;
|
|
31286
|
+
}
|
|
31287
|
+
}
|
|
31288
|
+
|
|
31289
|
+
/**
|
|
31290
|
+
* Generate a random ID
|
|
31291
|
+
*/
|
|
31292
|
+
export function generateId(length = 12): string {
|
|
31293
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
31294
|
+
let result = '';
|
|
31295
|
+
for (let i = 0; i < length; i++) {
|
|
31296
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
31297
|
+
}
|
|
31298
|
+
return result;
|
|
31299
|
+
}
|
|
31300
|
+
|
|
31301
|
+
/**
|
|
31302
|
+
* Debounce a function
|
|
31303
|
+
*/
|
|
31304
|
+
export function debounce<T extends (...args: unknown[]) => unknown>(
|
|
31305
|
+
func: T,
|
|
31306
|
+
wait: number
|
|
31307
|
+
): (...args: Parameters<T>) => void {
|
|
31308
|
+
let timeout: ReturnType<typeof setTimeout> | null = null;
|
|
31309
|
+
return (...args: Parameters<T>) => {
|
|
31310
|
+
if (timeout) clearTimeout(timeout);
|
|
31311
|
+
timeout = setTimeout(() => func(...args), wait);
|
|
31312
|
+
};
|
|
31313
|
+
}
|
|
31314
|
+
|
|
31315
|
+
/**
|
|
31316
|
+
* Check if running on server
|
|
31317
|
+
* Uses a type-safe approach that works without DOM types
|
|
31318
|
+
*/
|
|
31319
|
+
export function isServer(): boolean {
|
|
31320
|
+
return !(typeof window !== 'undefined' && window.document);
|
|
31321
|
+
}
|
|
31322
|
+
|
|
31323
|
+
/**
|
|
31324
|
+
* Check if running on client
|
|
31325
|
+
* Uses a type-safe approach that works without DOM types
|
|
31326
|
+
*/
|
|
31327
|
+
export function isClient(): boolean {
|
|
31328
|
+
return typeof window !== 'undefined' && !!window.document;
|
|
31329
|
+
}
|
|
31330
|
+
|
|
31331
|
+
// Declare window for environments without DOM types
|
|
31332
|
+
declare const window: { document?: unknown } | undefined;
|
|
31333
|
+
`);
|
|
31334
|
+
}
|
|
31335
|
+
|
|
31336
|
+
// ../templates/src/builders/full-v2.ts
|
|
31337
|
+
async function buildFullPresetV2(projectPath, context) {
|
|
31338
|
+
const preset = PresetRegistry.get("nextjs-monorepo");
|
|
31339
|
+
if (!preset) {
|
|
31340
|
+
throw new Error("nextjs-monorepo preset not found in registry");
|
|
31341
|
+
}
|
|
31342
|
+
const scopeName = context.packageName;
|
|
31343
|
+
const directories = [
|
|
31344
|
+
"apps/web/src/app",
|
|
31345
|
+
"apps/web/src/components",
|
|
31346
|
+
"apps/web/src/lib",
|
|
31347
|
+
"apps/platform/src/app",
|
|
31348
|
+
"apps/platform/src/components",
|
|
31349
|
+
"apps/platform/src/lib",
|
|
31350
|
+
"apps/api/src/routes",
|
|
31351
|
+
"apps/api/src/middleware",
|
|
31352
|
+
"packages/ui",
|
|
31353
|
+
"packages/types",
|
|
31354
|
+
"packages/utils",
|
|
31355
|
+
"tooling/typescript"
|
|
31356
|
+
];
|
|
31357
|
+
for (const dir of directories) {
|
|
31358
|
+
await ensureDirectory(join(projectPath, dir));
|
|
31359
|
+
}
|
|
31360
|
+
const catalog = preset.catalogEntries || {};
|
|
31361
|
+
await writeMonorepoRootPackageJson(projectPath, scopeName, catalog, {
|
|
31362
|
+
hasWeb: true,
|
|
31363
|
+
hasPlatform: true,
|
|
31364
|
+
hasApi: true,
|
|
31365
|
+
codeQuality: context.codeQuality === "biome" ? "biome" : "ultracite"
|
|
31366
|
+
});
|
|
31367
|
+
await writeFile(join(projectPath, "bunfig.toml"), generateBunfigContent(context));
|
|
31368
|
+
await writeNextjsAppPackageJson(join(projectPath, "apps/web"), scopeName, "web", { usesUi: true, usesTypes: true });
|
|
31369
|
+
await writeFile(join(projectPath, "apps/web/src/app/layout.tsx"), `import type { Metadata } from 'next';
|
|
31370
|
+
import '@${scopeName}/ui/globals.css';
|
|
31371
|
+
|
|
31372
|
+
export const metadata: Metadata = {
|
|
31373
|
+
title: '${context.projectName}',
|
|
31374
|
+
description: 'Enterprise SaaS built with bunkit',
|
|
31375
|
+
};
|
|
31376
|
+
|
|
31377
|
+
export default function RootLayout({
|
|
31378
|
+
children,
|
|
31379
|
+
}: {
|
|
31380
|
+
children: React.ReactNode;
|
|
31381
|
+
}) {
|
|
31382
|
+
return (
|
|
31383
|
+
<html lang="en">
|
|
31384
|
+
<body className="antialiased">{children}</body>
|
|
31385
|
+
</html>
|
|
31386
|
+
);
|
|
31387
|
+
}
|
|
31388
|
+
`);
|
|
31389
|
+
await writeFile(join(projectPath, "apps/web/src/app/page.tsx"), `import { Home, Rocket, Book } from 'iconoir-react';
|
|
31390
|
+
|
|
31391
|
+
export default function HomePage() {
|
|
31392
|
+
return (
|
|
31393
|
+
<main className="min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-muted">
|
|
31394
|
+
<div className="text-center space-y-8 p-8 max-w-3xl">
|
|
31395
|
+
<div className="flex justify-center">
|
|
31396
|
+
<Home className="w-16 h-16 text-primary" />
|
|
31397
|
+
</div>
|
|
31398
|
+
<h1 className="text-5xl font-bold tracking-tight">
|
|
31399
|
+
Welcome to ${context.projectName}
|
|
31400
|
+
</h1>
|
|
31401
|
+
<p className="text-xl text-muted-foreground">
|
|
31402
|
+
Enterprise-grade SaaS built with Next.js 16, React 19, Hono, and Bun
|
|
31403
|
+
</p>
|
|
31404
|
+
<div className="flex gap-4 justify-center pt-4">
|
|
31405
|
+
<a
|
|
31406
|
+
href="/dashboard"
|
|
31407
|
+
className="inline-flex items-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition font-medium"
|
|
31408
|
+
>
|
|
31409
|
+
<Rocket className="w-5 h-5" />
|
|
31410
|
+
Get Started
|
|
31411
|
+
</a>
|
|
31412
|
+
<a
|
|
31413
|
+
href="/docs"
|
|
31414
|
+
className="inline-flex items-center gap-2 px-6 py-3 bg-secondary text-secondary-foreground rounded-lg hover:bg-secondary/90 transition font-medium"
|
|
31415
|
+
>
|
|
31416
|
+
<Book className="w-5 h-5" />
|
|
31417
|
+
Documentation
|
|
31418
|
+
</a>
|
|
31419
|
+
</div>
|
|
31420
|
+
</div>
|
|
31421
|
+
</main>
|
|
31422
|
+
);
|
|
31423
|
+
}
|
|
31424
|
+
`);
|
|
31425
|
+
await writeFile(join(projectPath, "apps/web/next.config.ts"), `import type { NextConfig } from 'next';
|
|
31426
|
+
|
|
31427
|
+
const nextConfig: NextConfig = {
|
|
31428
|
+
transpilePackages: ['@${scopeName}/ui'],
|
|
31429
|
+
};
|
|
31430
|
+
|
|
31431
|
+
export default nextConfig;
|
|
31432
|
+
`);
|
|
31433
|
+
await writeFile(join(projectPath, "apps/web/tsconfig.json"), JSON.stringify({
|
|
31434
|
+
extends: "../../tooling/typescript/nextjs.json",
|
|
31435
|
+
compilerOptions: {
|
|
31436
|
+
paths: {
|
|
31437
|
+
"@/*": ["./src/*"]
|
|
31438
|
+
}
|
|
31439
|
+
},
|
|
31440
|
+
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
31441
|
+
exclude: ["node_modules"]
|
|
31442
|
+
}, null, 2));
|
|
31443
|
+
await writeFile(join(projectPath, "apps/web/postcss.config.mjs"), `export default {
|
|
31444
|
+
plugins: {
|
|
31445
|
+
'@tailwindcss/postcss': {},
|
|
31446
|
+
},
|
|
31447
|
+
};
|
|
31448
|
+
`);
|
|
31449
|
+
await writeNextjsAppPackageJson(join(projectPath, "apps/platform"), scopeName, "platform", { usesUi: true, usesTypes: true });
|
|
31450
|
+
await writeFile(join(projectPath, "apps/platform/src/app/layout.tsx"), `import type { Metadata } from 'next';
|
|
31451
|
+
import '@${scopeName}/ui/globals.css';
|
|
31452
|
+
|
|
31453
|
+
export const metadata: Metadata = {
|
|
31454
|
+
title: '${context.projectName} - Admin',
|
|
31455
|
+
description: 'Admin dashboard for ${context.projectName}',
|
|
31456
|
+
};
|
|
31457
|
+
|
|
31458
|
+
export default function RootLayout({
|
|
31459
|
+
children,
|
|
31460
|
+
}: {
|
|
31461
|
+
children: React.ReactNode;
|
|
31462
|
+
}) {
|
|
31463
|
+
return (
|
|
31464
|
+
<html lang="en">
|
|
31465
|
+
<body className="antialiased">{children}</body>
|
|
31466
|
+
</html>
|
|
31467
|
+
);
|
|
31468
|
+
}
|
|
31469
|
+
`);
|
|
31470
|
+
await writeFile(join(projectPath, "apps/platform/src/app/page.tsx"), `import { ViewGrid, User, Dollar, GraphUp } from 'iconoir-react';
|
|
31471
|
+
|
|
31472
|
+
export default function DashboardPage() {
|
|
31473
|
+
return (
|
|
31474
|
+
<main className="min-h-screen bg-background">
|
|
31475
|
+
<div className="max-w-7xl mx-auto py-12 px-4">
|
|
31476
|
+
<header className="mb-8 flex items-center gap-3">
|
|
31477
|
+
<ViewGrid className="w-8 h-8 text-primary" />
|
|
31478
|
+
<div>
|
|
31479
|
+
<h1 className="text-3xl font-bold">Admin Dashboard</h1>
|
|
31480
|
+
<p className="text-muted-foreground">
|
|
31481
|
+
Manage your ${context.projectName} platform
|
|
31482
|
+
</p>
|
|
31483
|
+
</div>
|
|
31484
|
+
</header>
|
|
31485
|
+
|
|
31486
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
31487
|
+
<div className="bg-card p-6 rounded-lg border shadow-sm">
|
|
31488
|
+
<div className="flex items-center gap-3 mb-2">
|
|
31489
|
+
<User className="w-5 h-5 text-blue-500" />
|
|
31490
|
+
<h2 className="text-lg font-semibold">Users</h2>
|
|
31491
|
+
</div>
|
|
31492
|
+
<p className="text-3xl font-bold">1,234</p>
|
|
31493
|
+
</div>
|
|
31494
|
+
<div className="bg-card p-6 rounded-lg border shadow-sm">
|
|
31495
|
+
<div className="flex items-center gap-3 mb-2">
|
|
31496
|
+
<Dollar className="w-5 h-5 text-green-500" />
|
|
31497
|
+
<h2 className="text-lg font-semibold">Revenue</h2>
|
|
31498
|
+
</div>
|
|
31499
|
+
<p className="text-3xl font-bold">$12,345</p>
|
|
31500
|
+
</div>
|
|
31501
|
+
<div className="bg-card p-6 rounded-lg border shadow-sm">
|
|
31502
|
+
<div className="flex items-center gap-3 mb-2">
|
|
31503
|
+
<GraphUp className="w-5 h-5 text-purple-500" />
|
|
31504
|
+
<h2 className="text-lg font-semibold">Active</h2>
|
|
31505
|
+
</div>
|
|
31506
|
+
<p className="text-3xl font-bold">567</p>
|
|
31507
|
+
</div>
|
|
31508
|
+
</div>
|
|
31509
|
+
</div>
|
|
31510
|
+
</main>
|
|
31511
|
+
);
|
|
31512
|
+
}
|
|
31513
|
+
`);
|
|
31514
|
+
await writeFile(join(projectPath, "apps/platform/next.config.ts"), `import type { NextConfig } from 'next';
|
|
31515
|
+
|
|
31516
|
+
const nextConfig: NextConfig = {
|
|
31517
|
+
transpilePackages: ['@${scopeName}/ui'],
|
|
31518
|
+
};
|
|
31519
|
+
|
|
31520
|
+
export default nextConfig;
|
|
31521
|
+
`);
|
|
31522
|
+
await writeFile(join(projectPath, "apps/platform/tsconfig.json"), JSON.stringify({
|
|
31523
|
+
extends: "../../tooling/typescript/nextjs.json",
|
|
31524
|
+
compilerOptions: {
|
|
31525
|
+
paths: {
|
|
31526
|
+
"@/*": ["./src/*"]
|
|
31527
|
+
}
|
|
31528
|
+
},
|
|
31529
|
+
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
31530
|
+
exclude: ["node_modules"]
|
|
31531
|
+
}, null, 2));
|
|
31532
|
+
await writeFile(join(projectPath, "apps/platform/postcss.config.mjs"), `export default {
|
|
31533
|
+
plugins: {
|
|
31534
|
+
'@tailwindcss/postcss': {},
|
|
31535
|
+
},
|
|
31536
|
+
};
|
|
31537
|
+
`);
|
|
31538
|
+
await writeHonoApiPackageJson(join(projectPath, "apps/api"), scopeName, {
|
|
31539
|
+
usesTypes: true
|
|
31540
|
+
});
|
|
31541
|
+
await writeFile(join(projectPath, "apps/api/src/index.ts"), `import { Hono } from 'hono';
|
|
31542
|
+
import { logger } from 'hono/logger';
|
|
31543
|
+
import { cors } from 'hono/cors';
|
|
31544
|
+
|
|
31545
|
+
const app = new Hono();
|
|
31546
|
+
|
|
31547
|
+
// Middleware
|
|
31548
|
+
app.use('*', logger());
|
|
31549
|
+
app.use('*', cors());
|
|
31550
|
+
|
|
31551
|
+
// Routes
|
|
31552
|
+
app.get('/', (context) => {
|
|
31553
|
+
return context.json({
|
|
31554
|
+
name: '${context.projectName} API',
|
|
31555
|
+
version: '1.0.0',
|
|
31556
|
+
timestamp: new Date().toISOString(),
|
|
31557
|
+
});
|
|
31558
|
+
});
|
|
31559
|
+
|
|
31560
|
+
app.get('/health', (context) => {
|
|
31561
|
+
return context.json({ status: 'ok' });
|
|
31562
|
+
});
|
|
31563
|
+
|
|
31564
|
+
app.get('/api/users', (context) => {
|
|
31565
|
+
return context.json({
|
|
31566
|
+
users: [
|
|
31567
|
+
{ id: '1', email: 'john@example.com', name: 'John Doe' },
|
|
31568
|
+
{ id: '2', email: 'jane@example.com', name: 'Jane Smith' },
|
|
31569
|
+
],
|
|
31570
|
+
});
|
|
31571
|
+
});
|
|
31572
|
+
|
|
31573
|
+
// 404 handler
|
|
31574
|
+
app.notFound((context) => {
|
|
31575
|
+
return context.json({ error: 'Not found' }, 404);
|
|
31576
|
+
});
|
|
31577
|
+
|
|
31578
|
+
// Error handler
|
|
31579
|
+
app.onError((error, context) => {
|
|
31580
|
+
console.error('Error:', error);
|
|
31581
|
+
return context.json({ error: 'Internal server error' }, 500);
|
|
31582
|
+
});
|
|
31583
|
+
|
|
31584
|
+
// Start server with HMR
|
|
31585
|
+
const server = Bun.serve({
|
|
31586
|
+
fetch: app.fetch,
|
|
31587
|
+
port: 3002,
|
|
31588
|
+
development: {
|
|
31589
|
+
hmr: true,
|
|
31590
|
+
},
|
|
31591
|
+
});
|
|
31592
|
+
|
|
31593
|
+
console.log(\`\uD83D\uDE80 ${context.projectName} API running on \${server.url}\`);
|
|
31594
|
+
|
|
31595
|
+
export default app;
|
|
31596
|
+
`);
|
|
31597
|
+
await writeFile(join(projectPath, "apps/api/tsconfig.json"), JSON.stringify({
|
|
31598
|
+
extends: "../../tooling/typescript/api.json",
|
|
31599
|
+
compilerOptions: {
|
|
31600
|
+
types: ["bun-types"]
|
|
31601
|
+
},
|
|
31602
|
+
include: ["src/**/*"],
|
|
31603
|
+
exclude: ["node_modules"]
|
|
31604
|
+
}, null, 2));
|
|
31605
|
+
await buildUiPackage(join(projectPath, "packages"), {
|
|
31606
|
+
scopeName,
|
|
31607
|
+
shadcnStyle: context.shadcnStyle || "radix-maia",
|
|
31608
|
+
shadcnBase: context.shadcnBase || "radix",
|
|
31609
|
+
shadcnBaseColor: context.shadcnBaseColor || "zinc",
|
|
31610
|
+
shadcnIconLibrary: context.shadcnIconLibrary || "phosphor",
|
|
31611
|
+
shadcnMenuAccent: context.shadcnMenuAccent || "subtle",
|
|
31612
|
+
shadcnMenuColor: context.shadcnMenuColor || "default",
|
|
31613
|
+
shadcnRadius: context.shadcnRadius || "0.625rem",
|
|
31614
|
+
appsToScan: ["web", "platform"]
|
|
31615
|
+
});
|
|
31616
|
+
await buildTypesPackage(join(projectPath, "packages"), scopeName);
|
|
31617
|
+
await buildUtilsPackage(join(projectPath, "packages"), scopeName);
|
|
31618
|
+
await setupTooling(projectPath, context);
|
|
31619
|
+
await writeFile(join(projectPath, "tsconfig.json"), JSON.stringify({
|
|
31620
|
+
extends: "./tooling/typescript/base.json",
|
|
31621
|
+
include: ["apps/*/src/**/*", "packages/*/src/**/*"],
|
|
31622
|
+
exclude: ["node_modules", "**/node_modules", "**/.next"]
|
|
31623
|
+
}, null, 2));
|
|
31624
|
+
if (context.codeQuality === "ultracite") {
|
|
31625
|
+
await setupUltracite(projectPath, context);
|
|
31626
|
+
} else {
|
|
31627
|
+
await setupBiome(projectPath, context);
|
|
31628
|
+
}
|
|
31629
|
+
if (context.docker) {
|
|
31630
|
+
await setupDocker(projectPath, context);
|
|
31631
|
+
}
|
|
31632
|
+
if (context.cicd) {
|
|
31633
|
+
await setupGitHubActions(projectPath, context);
|
|
31634
|
+
}
|
|
31635
|
+
await setupVSCodeDebug(projectPath, context, "full");
|
|
31636
|
+
await generateMonorepoReadme(projectPath, context, "nextjs");
|
|
31637
|
+
}
|
|
31638
|
+
// ../templates/src/shared/index.ts
|
|
31639
|
+
init_package_json();
|
|
30269
31640
|
// ../templates/src/render.ts
|
|
30270
31641
|
var import_ejs = __toESM(require_ejs(), 1);
|
|
30271
31642
|
// src/commands/add/component.ts
|
|
@@ -31734,17 +33105,42 @@ async function enhancedInitCommand(options = {}) {
|
|
|
31734
33105
|
if (!shadcnStyle && uiLibrary === "shadcn") {
|
|
31735
33106
|
if (!isNonInteractive) {
|
|
31736
33107
|
shadcnStyle = await ve({
|
|
31737
|
-
message: "\uD83C\uDFA8 shadcn/ui
|
|
33108
|
+
message: "\uD83C\uDFA8 shadcn/ui visual style",
|
|
31738
33109
|
options: [
|
|
33110
|
+
{
|
|
33111
|
+
value: "radix-maia",
|
|
33112
|
+
label: "Maia (Recommended)",
|
|
33113
|
+
hint: "Modern, clean design with soft shadows and refined aesthetics"
|
|
33114
|
+
},
|
|
33115
|
+
{
|
|
33116
|
+
value: "radix-vega",
|
|
33117
|
+
label: "Vega",
|
|
33118
|
+
hint: "Bold, vibrant design with stronger colors and contrast"
|
|
33119
|
+
},
|
|
33120
|
+
{
|
|
33121
|
+
value: "radix-nova",
|
|
33122
|
+
label: "Nova",
|
|
33123
|
+
hint: "Minimalist design with subtle accents and clean lines"
|
|
33124
|
+
},
|
|
33125
|
+
{
|
|
33126
|
+
value: "radix-lyra",
|
|
33127
|
+
label: "Lyra",
|
|
33128
|
+
hint: "Elegant design with refined typography and spacing"
|
|
33129
|
+
},
|
|
33130
|
+
{
|
|
33131
|
+
value: "radix-mira",
|
|
33132
|
+
label: "Mira",
|
|
33133
|
+
hint: "Playful design with rounded elements and soft colors"
|
|
33134
|
+
},
|
|
31739
33135
|
{
|
|
31740
33136
|
value: "new-york",
|
|
31741
|
-
label: "New York (
|
|
31742
|
-
hint: "
|
|
33137
|
+
label: "New York (Legacy)",
|
|
33138
|
+
hint: "Classic modern aesthetic - rounded corners, subtle shadows"
|
|
31743
33139
|
},
|
|
31744
33140
|
{
|
|
31745
33141
|
value: "default",
|
|
31746
|
-
label: "Default",
|
|
31747
|
-
hint: "Classic design
|
|
33142
|
+
label: "Default (Legacy)",
|
|
33143
|
+
hint: "Classic design - sharper edges, higher contrast"
|
|
31748
33144
|
}
|
|
31749
33145
|
]
|
|
31750
33146
|
});
|
|
@@ -31753,7 +33149,7 @@ async function enhancedInitCommand(options = {}) {
|
|
|
31753
33149
|
process.exit(0);
|
|
31754
33150
|
}
|
|
31755
33151
|
} else {
|
|
31756
|
-
shadcnStyle = "
|
|
33152
|
+
shadcnStyle = "radix-maia";
|
|
31757
33153
|
}
|
|
31758
33154
|
}
|
|
31759
33155
|
let shadcnBaseColor = getOptionValue("BUNKIT_SHADCN_BASE_COLOR", options.shadcnBaseColor);
|
|
@@ -31822,6 +33218,38 @@ async function enhancedInitCommand(options = {}) {
|
|
|
31822
33218
|
shadcnRadius = "0.625rem";
|
|
31823
33219
|
}
|
|
31824
33220
|
}
|
|
33221
|
+
let shadcnIconLibrary = getOptionValue("BUNKIT_SHADCN_ICON_LIBRARY", options.shadcnIconLibrary);
|
|
33222
|
+
const isModernShadcnStyle = shadcnStyle === "radix-maia" || shadcnStyle === "radix-vega" || shadcnStyle === "radix-nova" || shadcnStyle === "radix-lyra" || shadcnStyle === "radix-mira";
|
|
33223
|
+
if (!shadcnIconLibrary && uiLibrary === "shadcn") {
|
|
33224
|
+
if (!isNonInteractive) {
|
|
33225
|
+
shadcnIconLibrary = await ve({
|
|
33226
|
+
message: "\uD83D\uDD23 Icon library",
|
|
33227
|
+
options: [
|
|
33228
|
+
{
|
|
33229
|
+
value: "phosphor",
|
|
33230
|
+
label: isModernShadcnStyle ? "Phosphor Icons (Recommended)" : "Phosphor Icons",
|
|
33231
|
+
hint: "Modern icon library with consistent design - default for new shadcn/ui styles"
|
|
33232
|
+
},
|
|
33233
|
+
{
|
|
33234
|
+
value: "iconoir",
|
|
33235
|
+
label: !isModernShadcnStyle ? "Iconoir (Recommended)" : "Iconoir",
|
|
33236
|
+
hint: "Lightweight icons with great variety - alternative choice"
|
|
33237
|
+
},
|
|
33238
|
+
{
|
|
33239
|
+
value: "lucide",
|
|
33240
|
+
label: "Lucide",
|
|
33241
|
+
hint: "Classic choice - based on Feather icons, widely used"
|
|
33242
|
+
}
|
|
33243
|
+
]
|
|
33244
|
+
});
|
|
33245
|
+
if (pD(shadcnIconLibrary)) {
|
|
33246
|
+
xe("Operation cancelled.");
|
|
33247
|
+
process.exit(0);
|
|
33248
|
+
}
|
|
33249
|
+
} else {
|
|
33250
|
+
shadcnIconLibrary = isModernShadcnStyle ? "phosphor" : "iconoir";
|
|
33251
|
+
}
|
|
33252
|
+
}
|
|
31825
33253
|
let testing = getOptionValue("BUNKIT_TESTING", options.testing, "bun-test");
|
|
31826
33254
|
if (!testing) {
|
|
31827
33255
|
if (!isNonInteractive) {
|
|
@@ -32062,7 +33490,11 @@ async function enhancedInitCommand(options = {}) {
|
|
|
32062
33490
|
envExample: true,
|
|
32063
33491
|
pathAliases: true,
|
|
32064
33492
|
shadcnStyle,
|
|
33493
|
+
shadcnBase: "radix",
|
|
32065
33494
|
shadcnBaseColor,
|
|
33495
|
+
shadcnIconLibrary,
|
|
33496
|
+
shadcnMenuAccent: "subtle",
|
|
33497
|
+
shadcnMenuColor: "default",
|
|
32066
33498
|
shadcnRadius,
|
|
32067
33499
|
supabasePreset,
|
|
32068
33500
|
supabaseFeatures,
|
|
@@ -32092,14 +33524,18 @@ async function enhancedInitCommand(options = {}) {
|
|
|
32092
33524
|
break;
|
|
32093
33525
|
case "full":
|
|
32094
33526
|
case "monorepo-nextjs":
|
|
32095
|
-
|
|
33527
|
+
case "nextjs-monorepo":
|
|
33528
|
+
await buildFullPresetV2(projectPath, context);
|
|
32096
33529
|
break;
|
|
32097
33530
|
case "monorepo-bun":
|
|
33531
|
+
case "bun-monorepo":
|
|
32098
33532
|
await buildMonorepoBunPreset(projectPath, context);
|
|
32099
33533
|
break;
|
|
32100
33534
|
case "enterprise-monorepo":
|
|
32101
33535
|
await buildEnterprisePreset(projectPath, context);
|
|
32102
33536
|
break;
|
|
33537
|
+
default:
|
|
33538
|
+
throw new Error(`Unknown preset: ${preset}. Valid presets are: minimal, nextjs, hono-api, bun-api, bun-fullstack, nextjs-monorepo, bun-monorepo, enterprise-monorepo`);
|
|
32103
33539
|
}
|
|
32104
33540
|
if (database && database !== "none") {
|
|
32105
33541
|
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;
|
|
@@ -32118,7 +33554,8 @@ async function enhancedInitCommand(options = {}) {
|
|
|
32118
33554
|
s.message(`${source_default.cyan("\u2699\uFE0F")} Adding GitHub Actions CI/CD workflow...`);
|
|
32119
33555
|
}
|
|
32120
33556
|
s.stop(`${source_default.green("\u2705")} Project structure created successfully!`);
|
|
32121
|
-
|
|
33557
|
+
const isMonorepoPreset = normalizedPreset === "nextjs-monorepo" || normalizedPreset === "bun-monorepo" || normalizedPreset === "enterprise-monorepo";
|
|
33558
|
+
if (shouldInstall && !isMonorepoPreset) {
|
|
32122
33559
|
const additionalDeps = {};
|
|
32123
33560
|
if (database && database !== "none") {
|
|
32124
33561
|
Object.assign(additionalDeps, getDatabaseDependencies(database));
|
|
@@ -32140,10 +33577,10 @@ async function enhancedInitCommand(options = {}) {
|
|
|
32140
33577
|
} else {
|
|
32141
33578
|
await installDependencies(projectPath);
|
|
32142
33579
|
}
|
|
32143
|
-
} else if (shouldInstall &&
|
|
33580
|
+
} else if (shouldInstall && isMonorepoPreset) {
|
|
32144
33581
|
await installDependencies(projectPath);
|
|
32145
33582
|
}
|
|
32146
|
-
if (shouldInstall && uiLibrary === "shadcn" && (normalizedPreset === "nextjs" || normalizedPreset === "bun-fullstack" ||
|
|
33583
|
+
if (shouldInstall && uiLibrary === "shadcn" && (normalizedPreset === "nextjs" || normalizedPreset === "bun-fullstack" || isMonorepoPreset)) {
|
|
32147
33584
|
const componentSpinner = Y2();
|
|
32148
33585
|
componentSpinner.start(`${source_default.cyan("\uD83E\uDDE9")} Installing default shadcn/ui components (button, card)...`);
|
|
32149
33586
|
try {
|