create-better-fullstack 1.5.4 → 1.6.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/{addons-setup-Bll5VFJd.mjs → addons-setup--oB72n29.mjs} +13 -37
- package/dist/addons-setup-By7Kqjss.mjs +5 -0
- package/dist/{bts-config-BYD8mHt-.mjs → bts-config-snHxP_EH.mjs} +14 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +92 -36
- package/dist/index.mjs +287 -17
- package/dist/{mcp-CRjipp-w.mjs → mcp-Bx_Esljk.mjs} +1 -1
- package/dist/mcp-entry.mjs +28 -4
- package/package.json +3 -3
- package/dist/addons-setup-CWGwxN68.mjs +0 -5
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { s as dependencyVersionMap, t as readBtsConfig } from "./bts-config-
|
|
2
|
+
import { s as dependencyVersionMap, t as readBtsConfig } from "./bts-config-snHxP_EH.mjs";
|
|
3
3
|
import { autocompleteMultiselect, cancel, group, isCancel, log, multiselect, select, spinner } from "@clack/prompts";
|
|
4
4
|
import pc from "picocolors";
|
|
5
5
|
import fs from "fs-extra";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import
|
|
8
|
-
import consola, { consola as consola$1 } from "consola";
|
|
7
|
+
import consola from "consola";
|
|
9
8
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
9
|
import { $ } from "execa";
|
|
11
10
|
|
|
@@ -987,39 +986,16 @@ async function setupStarlight(config) {
|
|
|
987
986
|
|
|
988
987
|
//#endregion
|
|
989
988
|
//#region src/helpers/addons/tauri-setup.ts
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
const devUrl = `http://localhost:${getLocalWebDevPort(frontend)}`;
|
|
1001
|
-
const frontendDist = hasNuxt ? "../.output/public" : hasSvelte ? "../build" : hasNext ? "../.next" : frontend.includes("react-router") ? "../build/client" : frontend.includes("react-vite") ? "../dist" : "../dist";
|
|
1002
|
-
const tauriArgs = [
|
|
1003
|
-
"@tauri-apps/cli@latest",
|
|
1004
|
-
"init",
|
|
1005
|
-
`--app-name=${path.basename(projectDir)}`,
|
|
1006
|
-
`--window-title=${path.basename(projectDir)}`,
|
|
1007
|
-
`--frontend-dist=${frontendDist}`,
|
|
1008
|
-
`--dev-url=${devUrl}`,
|
|
1009
|
-
`--before-dev-command=${packageManager} run dev`,
|
|
1010
|
-
`--before-build-command=${packageManager} run build`
|
|
1011
|
-
];
|
|
1012
|
-
const prefix = getPackageRunnerPrefix(packageManager);
|
|
1013
|
-
await $({
|
|
1014
|
-
cwd: clientPackageDir,
|
|
1015
|
-
env: { CI: "true" }
|
|
1016
|
-
})`${[...prefix, ...tauriArgs]}`;
|
|
1017
|
-
s.stop("Tauri desktop app support configured successfully!");
|
|
1018
|
-
} catch (error) {
|
|
1019
|
-
s.stop(pc.red("Failed to set up Tauri"));
|
|
1020
|
-
if (error instanceof Error) consola$1.error(pc.red(error.message));
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
989
|
+
/**
|
|
990
|
+
* Tauri setup is now handled entirely by template generation.
|
|
991
|
+
* The src-tauri/ directory (tauri.conf.json, Cargo.toml, main.rs, lib.rs, etc.)
|
|
992
|
+
* is emitted by the addons template handler from templates/addons/tauri/.
|
|
993
|
+
* Dependencies (@tauri-apps/cli, @tauri-apps/api) and scripts (tauri, desktop:dev,
|
|
994
|
+
* desktop:build) are added by addons-deps.ts.
|
|
995
|
+
*
|
|
996
|
+
* This function is kept as a no-op for backward compatibility with addons-setup.ts.
|
|
997
|
+
*/
|
|
998
|
+
async function setupTauri(_config) {}
|
|
1023
999
|
|
|
1024
1000
|
//#endregion
|
|
1025
1001
|
//#region src/helpers/addons/tui-setup.ts
|
|
@@ -1290,7 +1266,7 @@ async function setupAddons(config) {
|
|
|
1290
1266
|
const hasSvelteFrontend = frontend.includes("svelte");
|
|
1291
1267
|
const hasSolidFrontend = frontend.includes("solid");
|
|
1292
1268
|
const hasNextFrontend = frontend.includes("next");
|
|
1293
|
-
if (addons.includes("tauri") && (hasReactWebFrontend || hasNuxtFrontend || hasSvelteFrontend || hasSolidFrontend || hasNextFrontend)) await setupTauri(config);
|
|
1269
|
+
if (addons.includes("tauri") && (hasReactWebFrontend || hasNuxtFrontend || hasSvelteFrontend || hasSolidFrontend || hasNextFrontend)) await /* @__PURE__ */ setupTauri(config);
|
|
1294
1270
|
const hasUltracite = addons.includes("ultracite");
|
|
1295
1271
|
const hasBiome = addons.includes("biome");
|
|
1296
1272
|
const hasHusky = addons.includes("husky");
|
|
@@ -38,6 +38,7 @@ const DEFAULT_CONFIG_BASE = {
|
|
|
38
38
|
realtime: "none",
|
|
39
39
|
jobQueue: "none",
|
|
40
40
|
caching: "none",
|
|
41
|
+
i18n: "none",
|
|
41
42
|
search: "none",
|
|
42
43
|
fileStorage: "none",
|
|
43
44
|
animation: "none",
|
|
@@ -73,11 +74,15 @@ const DEFAULT_CONFIG_BASE = {
|
|
|
73
74
|
rustCli: "none",
|
|
74
75
|
rustLibraries: [],
|
|
75
76
|
rustLogging: "tracing",
|
|
77
|
+
rustErrorHandling: "anyhow-thiserror",
|
|
78
|
+
rustCaching: "none",
|
|
76
79
|
pythonWebFramework: "fastapi",
|
|
77
80
|
pythonOrm: "sqlalchemy",
|
|
78
81
|
pythonValidation: "pydantic",
|
|
79
82
|
pythonAi: [],
|
|
83
|
+
pythonAuth: "none",
|
|
80
84
|
pythonTaskQueue: "none",
|
|
85
|
+
pythonGraphql: "none",
|
|
81
86
|
pythonQuality: "ruff",
|
|
82
87
|
goWebFramework: "gin",
|
|
83
88
|
goOrm: "gorm",
|
|
@@ -174,6 +179,7 @@ async function writeBtsConfig(projectConfig) {
|
|
|
174
179
|
analytics: projectConfig.analytics,
|
|
175
180
|
cms: projectConfig.cms,
|
|
176
181
|
caching: projectConfig.caching,
|
|
182
|
+
i18n: projectConfig.i18n,
|
|
177
183
|
search: projectConfig.search,
|
|
178
184
|
fileStorage: projectConfig.fileStorage,
|
|
179
185
|
rustWebFramework: projectConfig.rustWebFramework,
|
|
@@ -183,11 +189,15 @@ async function writeBtsConfig(projectConfig) {
|
|
|
183
189
|
rustCli: projectConfig.rustCli,
|
|
184
190
|
rustLibraries: projectConfig.rustLibraries,
|
|
185
191
|
rustLogging: projectConfig.rustLogging,
|
|
192
|
+
rustErrorHandling: projectConfig.rustErrorHandling,
|
|
193
|
+
rustCaching: projectConfig.rustCaching,
|
|
186
194
|
pythonWebFramework: projectConfig.pythonWebFramework,
|
|
187
195
|
pythonOrm: projectConfig.pythonOrm,
|
|
188
196
|
pythonValidation: projectConfig.pythonValidation,
|
|
189
197
|
pythonAi: projectConfig.pythonAi,
|
|
198
|
+
pythonAuth: projectConfig.pythonAuth,
|
|
190
199
|
pythonTaskQueue: projectConfig.pythonTaskQueue,
|
|
200
|
+
pythonGraphql: projectConfig.pythonGraphql,
|
|
191
201
|
pythonQuality: projectConfig.pythonQuality,
|
|
192
202
|
goWebFramework: projectConfig.goWebFramework,
|
|
193
203
|
goOrm: projectConfig.goOrm,
|
|
@@ -235,6 +245,7 @@ async function writeBtsConfig(projectConfig) {
|
|
|
235
245
|
analytics: btsConfig.analytics,
|
|
236
246
|
cms: btsConfig.cms,
|
|
237
247
|
caching: btsConfig.caching,
|
|
248
|
+
i18n: btsConfig.i18n,
|
|
238
249
|
search: btsConfig.search,
|
|
239
250
|
fileStorage: btsConfig.fileStorage,
|
|
240
251
|
rustWebFramework: btsConfig.rustWebFramework,
|
|
@@ -244,10 +255,13 @@ async function writeBtsConfig(projectConfig) {
|
|
|
244
255
|
rustCli: btsConfig.rustCli,
|
|
245
256
|
rustLibraries: btsConfig.rustLibraries,
|
|
246
257
|
rustLogging: btsConfig.rustLogging,
|
|
258
|
+
rustErrorHandling: btsConfig.rustErrorHandling,
|
|
259
|
+
rustCaching: btsConfig.rustCaching,
|
|
247
260
|
pythonWebFramework: btsConfig.pythonWebFramework,
|
|
248
261
|
pythonOrm: btsConfig.pythonOrm,
|
|
249
262
|
pythonValidation: btsConfig.pythonValidation,
|
|
250
263
|
pythonAi: btsConfig.pythonAi,
|
|
264
|
+
pythonAuth: btsConfig.pythonAuth,
|
|
251
265
|
pythonTaskQueue: btsConfig.pythonTaskQueue,
|
|
252
266
|
pythonQuality: btsConfig.pythonQuality,
|
|
253
267
|
goWebFramework: btsConfig.goWebFramework,
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
//#region src/cli.ts
|
|
3
|
-
if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-
|
|
3
|
+
if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-Bx_Esljk.mjs").then((m) => m.startMcpServer());
|
|
4
4
|
else import("./index.mjs").then((m) => m.createBtsCli().run());
|
|
5
5
|
|
|
6
6
|
//#endregion
|
package/dist/index.d.mts
CHANGED
|
@@ -204,6 +204,11 @@ declare const router: {
|
|
|
204
204
|
none: "none";
|
|
205
205
|
"upstash-redis": "upstash-redis";
|
|
206
206
|
}>>;
|
|
207
|
+
i18n: z.ZodOptional<z.ZodEnum<{
|
|
208
|
+
none: "none";
|
|
209
|
+
i18next: "i18next";
|
|
210
|
+
"next-intl": "next-intl";
|
|
211
|
+
}>>;
|
|
207
212
|
search: z.ZodOptional<z.ZodEnum<{
|
|
208
213
|
none: "none";
|
|
209
214
|
meilisearch: "meilisearch";
|
|
@@ -325,6 +330,7 @@ declare const router: {
|
|
|
325
330
|
orpc: "orpc";
|
|
326
331
|
"ts-rest": "ts-rest";
|
|
327
332
|
garph: "garph";
|
|
333
|
+
"graphql-yoga": "graphql-yoga";
|
|
328
334
|
}>>;
|
|
329
335
|
cssFramework: z.ZodOptional<z.ZodEnum<{
|
|
330
336
|
none: "none";
|
|
@@ -422,6 +428,7 @@ declare const router: {
|
|
|
422
428
|
fly: "fly";
|
|
423
429
|
railway: "railway";
|
|
424
430
|
sst: "sst";
|
|
431
|
+
vercel: "vercel";
|
|
425
432
|
}>>;
|
|
426
433
|
serverDeploy: z.ZodOptional<z.ZodEnum<{
|
|
427
434
|
none: "none";
|
|
@@ -430,6 +437,7 @@ declare const router: {
|
|
|
430
437
|
fly: "fly";
|
|
431
438
|
railway: "railway";
|
|
432
439
|
sst: "sst";
|
|
440
|
+
vercel: "vercel";
|
|
433
441
|
}>>;
|
|
434
442
|
directoryConflict: z.ZodOptional<z.ZodEnum<{
|
|
435
443
|
merge: "merge";
|
|
@@ -444,6 +452,7 @@ declare const router: {
|
|
|
444
452
|
none: "none";
|
|
445
453
|
axum: "axum";
|
|
446
454
|
"actix-web": "actix-web";
|
|
455
|
+
rocket: "rocket";
|
|
447
456
|
}>>;
|
|
448
457
|
rustFrontend: z.ZodOptional<z.ZodEnum<{
|
|
449
458
|
none: "none";
|
|
@@ -454,6 +463,7 @@ declare const router: {
|
|
|
454
463
|
none: "none";
|
|
455
464
|
"sea-orm": "sea-orm";
|
|
456
465
|
sqlx: "sqlx";
|
|
466
|
+
diesel: "diesel";
|
|
457
467
|
}>>;
|
|
458
468
|
rustApi: z.ZodOptional<z.ZodEnum<{
|
|
459
469
|
none: "none";
|
|
@@ -479,11 +489,22 @@ declare const router: {
|
|
|
479
489
|
tracing: "tracing";
|
|
480
490
|
"env-logger": "env-logger";
|
|
481
491
|
}>>;
|
|
492
|
+
rustErrorHandling: z.ZodOptional<z.ZodEnum<{
|
|
493
|
+
none: "none";
|
|
494
|
+
"anyhow-thiserror": "anyhow-thiserror";
|
|
495
|
+
eyre: "eyre";
|
|
496
|
+
}>>;
|
|
497
|
+
rustCaching: z.ZodOptional<z.ZodEnum<{
|
|
498
|
+
none: "none";
|
|
499
|
+
redis: "redis";
|
|
500
|
+
moka: "moka";
|
|
501
|
+
}>>;
|
|
482
502
|
pythonWebFramework: z.ZodOptional<z.ZodEnum<{
|
|
483
503
|
none: "none";
|
|
484
504
|
fastapi: "fastapi";
|
|
485
505
|
django: "django";
|
|
486
506
|
flask: "flask";
|
|
507
|
+
litestar: "litestar";
|
|
487
508
|
}>>;
|
|
488
509
|
pythonOrm: z.ZodOptional<z.ZodEnum<{
|
|
489
510
|
none: "none";
|
|
@@ -503,10 +524,19 @@ declare const router: {
|
|
|
503
524
|
"anthropic-sdk": "anthropic-sdk";
|
|
504
525
|
crewai: "crewai";
|
|
505
526
|
}>>>;
|
|
527
|
+
pythonAuth: z.ZodOptional<z.ZodEnum<{
|
|
528
|
+
none: "none";
|
|
529
|
+
authlib: "authlib";
|
|
530
|
+
jwt: "jwt";
|
|
531
|
+
}>>;
|
|
506
532
|
pythonTaskQueue: z.ZodOptional<z.ZodEnum<{
|
|
507
533
|
none: "none";
|
|
508
534
|
celery: "celery";
|
|
509
535
|
}>>;
|
|
536
|
+
pythonGraphql: z.ZodOptional<z.ZodEnum<{
|
|
537
|
+
none: "none";
|
|
538
|
+
strawberry: "strawberry";
|
|
539
|
+
}>>;
|
|
510
540
|
pythonQuality: z.ZodOptional<z.ZodEnum<{
|
|
511
541
|
none: "none";
|
|
512
542
|
ruff: "ruff";
|
|
@@ -516,11 +546,13 @@ declare const router: {
|
|
|
516
546
|
gin: "gin";
|
|
517
547
|
echo: "echo";
|
|
518
548
|
fiber: "fiber";
|
|
549
|
+
chi: "chi";
|
|
519
550
|
}>>;
|
|
520
551
|
goOrm: z.ZodOptional<z.ZodEnum<{
|
|
521
552
|
none: "none";
|
|
522
553
|
gorm: "gorm";
|
|
523
554
|
sqlc: "sqlc";
|
|
555
|
+
ent: "ent";
|
|
524
556
|
}>>;
|
|
525
557
|
goApi: z.ZodOptional<z.ZodEnum<{
|
|
526
558
|
none: "none";
|
|
@@ -534,6 +566,8 @@ declare const router: {
|
|
|
534
566
|
goLogging: z.ZodOptional<z.ZodEnum<{
|
|
535
567
|
none: "none";
|
|
536
568
|
zap: "zap";
|
|
569
|
+
zerolog: "zerolog";
|
|
570
|
+
slog: "slog";
|
|
537
571
|
}>>;
|
|
538
572
|
aiDocs: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
539
573
|
none: "none";
|
|
@@ -562,9 +596,9 @@ declare const router: {
|
|
|
562
596
|
versionChannel: "stable" | "latest" | "beta";
|
|
563
597
|
install: boolean;
|
|
564
598
|
dbSetup: "none" | "turso" | "neon" | "prisma-postgres" | "planetscale" | "mongodb-atlas" | "supabase" | "upstash" | "d1" | "docker";
|
|
565
|
-
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph";
|
|
566
|
-
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
567
|
-
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
599
|
+
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
|
|
600
|
+
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
601
|
+
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
568
602
|
ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
|
|
569
603
|
effect: "effect" | "none" | "effect-full";
|
|
570
604
|
stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
|
|
@@ -584,26 +618,31 @@ declare const router: {
|
|
|
584
618
|
analytics: "none" | "plausible" | "umami";
|
|
585
619
|
cms: "none" | "payload" | "sanity" | "strapi" | "tinacms";
|
|
586
620
|
caching: "none" | "upstash-redis";
|
|
621
|
+
i18n: "none" | "i18next" | "next-intl";
|
|
587
622
|
search: "none" | "meilisearch" | "typesense" | "elasticsearch" | "algolia";
|
|
588
623
|
fileStorage: "none" | "s3" | "r2";
|
|
589
|
-
rustWebFramework: "none" | "axum" | "actix-web";
|
|
624
|
+
rustWebFramework: "none" | "axum" | "actix-web" | "rocket";
|
|
590
625
|
rustFrontend: "none" | "leptos" | "dioxus";
|
|
591
|
-
rustOrm: "none" | "sea-orm" | "sqlx";
|
|
626
|
+
rustOrm: "none" | "sea-orm" | "sqlx" | "diesel";
|
|
592
627
|
rustApi: "none" | "tonic" | "async-graphql";
|
|
593
628
|
rustCli: "none" | "clap" | "ratatui";
|
|
594
629
|
rustLibraries: ("none" | "serde" | "validator" | "jsonwebtoken" | "argon2" | "tokio-test" | "mockall")[];
|
|
595
630
|
rustLogging: "none" | "tracing" | "env-logger";
|
|
596
|
-
|
|
631
|
+
rustErrorHandling: "none" | "anyhow-thiserror" | "eyre";
|
|
632
|
+
rustCaching: "none" | "redis" | "moka";
|
|
633
|
+
pythonWebFramework: "none" | "fastapi" | "django" | "flask" | "litestar";
|
|
597
634
|
pythonOrm: "none" | "sqlalchemy" | "sqlmodel";
|
|
598
635
|
pythonValidation: "none" | "pydantic";
|
|
599
636
|
pythonAi: ("none" | "langgraph" | "langchain" | "llamaindex" | "openai-sdk" | "anthropic-sdk" | "crewai")[];
|
|
637
|
+
pythonAuth: "none" | "authlib" | "jwt";
|
|
600
638
|
pythonTaskQueue: "none" | "celery";
|
|
639
|
+
pythonGraphql: "none" | "strawberry";
|
|
601
640
|
pythonQuality: "none" | "ruff";
|
|
602
|
-
goWebFramework: "none" | "gin" | "echo" | "fiber";
|
|
603
|
-
goOrm: "none" | "gorm" | "sqlc";
|
|
641
|
+
goWebFramework: "none" | "gin" | "echo" | "fiber" | "chi";
|
|
642
|
+
goOrm: "none" | "gorm" | "sqlc" | "ent";
|
|
604
643
|
goApi: "none" | "grpc-go";
|
|
605
644
|
goCli: "none" | "cobra" | "bubbletea";
|
|
606
|
-
goLogging: "none" | "zap";
|
|
645
|
+
goLogging: "none" | "zap" | "zerolog" | "slog";
|
|
607
646
|
aiDocs: ("none" | "claude-md" | "agents-md" | "cursorrules")[];
|
|
608
647
|
astroIntegration?: "none" | "svelte" | "solid" | "react" | "vue" | undefined;
|
|
609
648
|
shadcnBase?: "radix" | "base" | undefined;
|
|
@@ -645,9 +684,9 @@ declare const router: {
|
|
|
645
684
|
versionChannel: "stable" | "latest" | "beta";
|
|
646
685
|
install: boolean;
|
|
647
686
|
dbSetup: "none" | "turso" | "neon" | "prisma-postgres" | "planetscale" | "mongodb-atlas" | "supabase" | "upstash" | "d1" | "docker";
|
|
648
|
-
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph";
|
|
649
|
-
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
650
|
-
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
687
|
+
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
|
|
688
|
+
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
689
|
+
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
651
690
|
ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
|
|
652
691
|
effect: "effect" | "none" | "effect-full";
|
|
653
692
|
stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
|
|
@@ -667,26 +706,31 @@ declare const router: {
|
|
|
667
706
|
analytics: "none" | "plausible" | "umami";
|
|
668
707
|
cms: "none" | "payload" | "sanity" | "strapi" | "tinacms";
|
|
669
708
|
caching: "none" | "upstash-redis";
|
|
709
|
+
i18n: "none" | "i18next" | "next-intl";
|
|
670
710
|
search: "none" | "meilisearch" | "typesense" | "elasticsearch" | "algolia";
|
|
671
711
|
fileStorage: "none" | "s3" | "r2";
|
|
672
|
-
rustWebFramework: "none" | "axum" | "actix-web";
|
|
712
|
+
rustWebFramework: "none" | "axum" | "actix-web" | "rocket";
|
|
673
713
|
rustFrontend: "none" | "leptos" | "dioxus";
|
|
674
|
-
rustOrm: "none" | "sea-orm" | "sqlx";
|
|
714
|
+
rustOrm: "none" | "sea-orm" | "sqlx" | "diesel";
|
|
675
715
|
rustApi: "none" | "tonic" | "async-graphql";
|
|
676
716
|
rustCli: "none" | "clap" | "ratatui";
|
|
677
717
|
rustLibraries: ("none" | "serde" | "validator" | "jsonwebtoken" | "argon2" | "tokio-test" | "mockall")[];
|
|
678
718
|
rustLogging: "none" | "tracing" | "env-logger";
|
|
679
|
-
|
|
719
|
+
rustErrorHandling: "none" | "anyhow-thiserror" | "eyre";
|
|
720
|
+
rustCaching: "none" | "redis" | "moka";
|
|
721
|
+
pythonWebFramework: "none" | "fastapi" | "django" | "flask" | "litestar";
|
|
680
722
|
pythonOrm: "none" | "sqlalchemy" | "sqlmodel";
|
|
681
723
|
pythonValidation: "none" | "pydantic";
|
|
682
724
|
pythonAi: ("none" | "langgraph" | "langchain" | "llamaindex" | "openai-sdk" | "anthropic-sdk" | "crewai")[];
|
|
725
|
+
pythonAuth: "none" | "authlib" | "jwt";
|
|
683
726
|
pythonTaskQueue: "none" | "celery";
|
|
727
|
+
pythonGraphql: "none" | "strawberry";
|
|
684
728
|
pythonQuality: "none" | "ruff";
|
|
685
|
-
goWebFramework: "none" | "gin" | "echo" | "fiber";
|
|
686
|
-
goOrm: "none" | "gorm" | "sqlc";
|
|
729
|
+
goWebFramework: "none" | "gin" | "echo" | "fiber" | "chi";
|
|
730
|
+
goOrm: "none" | "gorm" | "sqlc" | "ent";
|
|
687
731
|
goApi: "none" | "grpc-go";
|
|
688
732
|
goCli: "none" | "cobra" | "bubbletea";
|
|
689
|
-
goLogging: "none" | "zap";
|
|
733
|
+
goLogging: "none" | "zap" | "zerolog" | "slog";
|
|
690
734
|
aiDocs: ("none" | "claude-md" | "agents-md" | "cursorrules")[];
|
|
691
735
|
astroIntegration?: "none" | "svelte" | "solid" | "react" | "vue" | undefined;
|
|
692
736
|
shadcnBase?: "radix" | "base" | undefined;
|
|
@@ -741,9 +785,9 @@ declare const router: {
|
|
|
741
785
|
versionChannel: "stable" | "latest" | "beta";
|
|
742
786
|
install: boolean;
|
|
743
787
|
dbSetup: "none" | "turso" | "neon" | "prisma-postgres" | "planetscale" | "mongodb-atlas" | "supabase" | "upstash" | "d1" | "docker";
|
|
744
|
-
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph";
|
|
745
|
-
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
746
|
-
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
788
|
+
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
|
|
789
|
+
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
790
|
+
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
747
791
|
ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
|
|
748
792
|
effect: "effect" | "none" | "effect-full";
|
|
749
793
|
stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
|
|
@@ -763,26 +807,31 @@ declare const router: {
|
|
|
763
807
|
analytics: "none" | "plausible" | "umami";
|
|
764
808
|
cms: "none" | "payload" | "sanity" | "strapi" | "tinacms";
|
|
765
809
|
caching: "none" | "upstash-redis";
|
|
810
|
+
i18n: "none" | "i18next" | "next-intl";
|
|
766
811
|
search: "none" | "meilisearch" | "typesense" | "elasticsearch" | "algolia";
|
|
767
812
|
fileStorage: "none" | "s3" | "r2";
|
|
768
|
-
rustWebFramework: "none" | "axum" | "actix-web";
|
|
813
|
+
rustWebFramework: "none" | "axum" | "actix-web" | "rocket";
|
|
769
814
|
rustFrontend: "none" | "leptos" | "dioxus";
|
|
770
|
-
rustOrm: "none" | "sea-orm" | "sqlx";
|
|
815
|
+
rustOrm: "none" | "sea-orm" | "sqlx" | "diesel";
|
|
771
816
|
rustApi: "none" | "tonic" | "async-graphql";
|
|
772
817
|
rustCli: "none" | "clap" | "ratatui";
|
|
773
818
|
rustLibraries: ("none" | "serde" | "validator" | "jsonwebtoken" | "argon2" | "tokio-test" | "mockall")[];
|
|
774
819
|
rustLogging: "none" | "tracing" | "env-logger";
|
|
775
|
-
|
|
820
|
+
rustErrorHandling: "none" | "anyhow-thiserror" | "eyre";
|
|
821
|
+
rustCaching: "none" | "redis" | "moka";
|
|
822
|
+
pythonWebFramework: "none" | "fastapi" | "django" | "flask" | "litestar";
|
|
776
823
|
pythonOrm: "none" | "sqlalchemy" | "sqlmodel";
|
|
777
824
|
pythonValidation: "none" | "pydantic";
|
|
778
825
|
pythonAi: ("none" | "langgraph" | "langchain" | "llamaindex" | "openai-sdk" | "anthropic-sdk" | "crewai")[];
|
|
826
|
+
pythonAuth: "none" | "authlib" | "jwt";
|
|
779
827
|
pythonTaskQueue: "none" | "celery";
|
|
828
|
+
pythonGraphql: "none" | "strawberry";
|
|
780
829
|
pythonQuality: "none" | "ruff";
|
|
781
|
-
goWebFramework: "none" | "gin" | "echo" | "fiber";
|
|
782
|
-
goOrm: "none" | "gorm" | "sqlc";
|
|
830
|
+
goWebFramework: "none" | "gin" | "echo" | "fiber" | "chi";
|
|
831
|
+
goOrm: "none" | "gorm" | "sqlc" | "ent";
|
|
783
832
|
goApi: "none" | "grpc-go";
|
|
784
833
|
goCli: "none" | "cobra" | "bubbletea";
|
|
785
|
-
goLogging: "none" | "zap";
|
|
834
|
+
goLogging: "none" | "zap" | "zerolog" | "slog";
|
|
786
835
|
aiDocs: ("none" | "claude-md" | "agents-md" | "cursorrules")[];
|
|
787
836
|
astroIntegration?: "none" | "svelte" | "solid" | "react" | "vue" | undefined;
|
|
788
837
|
shadcnBase?: "radix" | "base" | undefined;
|
|
@@ -824,9 +873,9 @@ declare const router: {
|
|
|
824
873
|
versionChannel: "stable" | "latest" | "beta";
|
|
825
874
|
install: boolean;
|
|
826
875
|
dbSetup: "none" | "turso" | "neon" | "prisma-postgres" | "planetscale" | "mongodb-atlas" | "supabase" | "upstash" | "d1" | "docker";
|
|
827
|
-
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph";
|
|
828
|
-
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
829
|
-
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst";
|
|
876
|
+
api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
|
|
877
|
+
webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
878
|
+
serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
|
|
830
879
|
ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
|
|
831
880
|
effect: "effect" | "none" | "effect-full";
|
|
832
881
|
stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
|
|
@@ -846,26 +895,31 @@ declare const router: {
|
|
|
846
895
|
analytics: "none" | "plausible" | "umami";
|
|
847
896
|
cms: "none" | "payload" | "sanity" | "strapi" | "tinacms";
|
|
848
897
|
caching: "none" | "upstash-redis";
|
|
898
|
+
i18n: "none" | "i18next" | "next-intl";
|
|
849
899
|
search: "none" | "meilisearch" | "typesense" | "elasticsearch" | "algolia";
|
|
850
900
|
fileStorage: "none" | "s3" | "r2";
|
|
851
|
-
rustWebFramework: "none" | "axum" | "actix-web";
|
|
901
|
+
rustWebFramework: "none" | "axum" | "actix-web" | "rocket";
|
|
852
902
|
rustFrontend: "none" | "leptos" | "dioxus";
|
|
853
|
-
rustOrm: "none" | "sea-orm" | "sqlx";
|
|
903
|
+
rustOrm: "none" | "sea-orm" | "sqlx" | "diesel";
|
|
854
904
|
rustApi: "none" | "tonic" | "async-graphql";
|
|
855
905
|
rustCli: "none" | "clap" | "ratatui";
|
|
856
906
|
rustLibraries: ("none" | "serde" | "validator" | "jsonwebtoken" | "argon2" | "tokio-test" | "mockall")[];
|
|
857
907
|
rustLogging: "none" | "tracing" | "env-logger";
|
|
858
|
-
|
|
908
|
+
rustErrorHandling: "none" | "anyhow-thiserror" | "eyre";
|
|
909
|
+
rustCaching: "none" | "redis" | "moka";
|
|
910
|
+
pythonWebFramework: "none" | "fastapi" | "django" | "flask" | "litestar";
|
|
859
911
|
pythonOrm: "none" | "sqlalchemy" | "sqlmodel";
|
|
860
912
|
pythonValidation: "none" | "pydantic";
|
|
861
913
|
pythonAi: ("none" | "langgraph" | "langchain" | "llamaindex" | "openai-sdk" | "anthropic-sdk" | "crewai")[];
|
|
914
|
+
pythonAuth: "none" | "authlib" | "jwt";
|
|
862
915
|
pythonTaskQueue: "none" | "celery";
|
|
916
|
+
pythonGraphql: "none" | "strawberry";
|
|
863
917
|
pythonQuality: "none" | "ruff";
|
|
864
|
-
goWebFramework: "none" | "gin" | "echo" | "fiber";
|
|
865
|
-
goOrm: "none" | "gorm" | "sqlc";
|
|
918
|
+
goWebFramework: "none" | "gin" | "echo" | "fiber" | "chi";
|
|
919
|
+
goOrm: "none" | "gorm" | "sqlc" | "ent";
|
|
866
920
|
goApi: "none" | "grpc-go";
|
|
867
921
|
goCli: "none" | "cobra" | "bubbletea";
|
|
868
|
-
goLogging: "none" | "zap";
|
|
922
|
+
goLogging: "none" | "zap" | "zerolog" | "slog";
|
|
869
923
|
aiDocs: ("none" | "claude-md" | "agents-md" | "cursorrules")[];
|
|
870
924
|
astroIntegration?: "none" | "svelte" | "solid" | "react" | "vue" | undefined;
|
|
871
925
|
shadcnBase?: "radix" | "base" | undefined;
|
|
@@ -936,6 +990,7 @@ declare const router: {
|
|
|
936
990
|
fly: "fly";
|
|
937
991
|
railway: "railway";
|
|
938
992
|
sst: "sst";
|
|
993
|
+
vercel: "vercel";
|
|
939
994
|
}>>;
|
|
940
995
|
serverDeploy: z.ZodOptional<z.ZodEnum<{
|
|
941
996
|
none: "none";
|
|
@@ -944,6 +999,7 @@ declare const router: {
|
|
|
944
999
|
fly: "fly";
|
|
945
1000
|
railway: "railway";
|
|
946
1001
|
sst: "sst";
|
|
1002
|
+
vercel: "vercel";
|
|
947
1003
|
}>>;
|
|
948
1004
|
install: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
949
1005
|
packageManager: z.ZodOptional<z.ZodEnum<{
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as __reExport } from "./chunk-CCII7kTE.mjs";
|
|
3
|
-
import { a as DEFAULT_CONFIG, c as getDefaultConfig, i as getLatestCLIVersion, l as getUserPkgManager, n as updateBtsConfig, o as DEFAULT_UI_LIBRARY_BY_FRONTEND, r as writeBtsConfig, t as readBtsConfig } from "./bts-config-
|
|
4
|
-
import { _ as setLastPromptShownUI, a as getPackageExecutionArgs, c as UserCancelledError, d as handleError, f as didLastPromptShowUI, g as setIsFirstPrompt$1, h as runWithContextAsync, l as exitCancelled, m as isSilent, o as addPackageDependency, p as isFirstPrompt, s as CLIError, t as setupAddons, u as exitWithError } from "./addons-setup
|
|
3
|
+
import { a as DEFAULT_CONFIG, c as getDefaultConfig, i as getLatestCLIVersion, l as getUserPkgManager, n as updateBtsConfig, o as DEFAULT_UI_LIBRARY_BY_FRONTEND, r as writeBtsConfig, t as readBtsConfig } from "./bts-config-snHxP_EH.mjs";
|
|
4
|
+
import { _ as setLastPromptShownUI, a as getPackageExecutionArgs, c as UserCancelledError, d as handleError, f as didLastPromptShowUI, g as setIsFirstPrompt$1, h as runWithContextAsync, l as exitCancelled, m as isSilent, o as addPackageDependency, p as isFirstPrompt, s as CLIError, t as setupAddons, u as exitWithError } from "./addons-setup--oB72n29.mjs";
|
|
5
5
|
import { cancel, confirm, intro, isCancel, log, outro, select, spinner, text } from "@clack/prompts";
|
|
6
6
|
import { createRouterClient, os } from "@orpc/server";
|
|
7
7
|
import pc from "picocolors";
|
|
@@ -1720,6 +1720,11 @@ async function getApiChoice(Api, frontend, backend, astroIntegration) {
|
|
|
1720
1720
|
label: "Garph",
|
|
1721
1721
|
hint: "Fullstack GraphQL framework with end-to-end type safety"
|
|
1722
1722
|
},
|
|
1723
|
+
"graphql-yoga": {
|
|
1724
|
+
value: "graphql-yoga",
|
|
1725
|
+
label: "GraphQL Yoga",
|
|
1726
|
+
hint: "Batteries-included GraphQL server with Pothos schema builder"
|
|
1727
|
+
},
|
|
1723
1728
|
none: {
|
|
1724
1729
|
value: "none",
|
|
1725
1730
|
label: "None",
|
|
@@ -2618,6 +2623,11 @@ async function getGoWebFrameworkChoice(goWebFramework) {
|
|
|
2618
2623
|
label: "Fiber",
|
|
2619
2624
|
hint: "Express-inspired web framework built on Fasthttp"
|
|
2620
2625
|
},
|
|
2626
|
+
{
|
|
2627
|
+
value: "chi",
|
|
2628
|
+
label: "Chi",
|
|
2629
|
+
hint: "Lightweight, zero-dependency router built on net/http"
|
|
2630
|
+
},
|
|
2621
2631
|
{
|
|
2622
2632
|
value: "none",
|
|
2623
2633
|
label: "None",
|
|
@@ -2644,6 +2654,11 @@ async function getGoOrmChoice(goOrm) {
|
|
|
2644
2654
|
label: "sqlc",
|
|
2645
2655
|
hint: "Generate type-safe Go code from SQL"
|
|
2646
2656
|
},
|
|
2657
|
+
{
|
|
2658
|
+
value: "ent",
|
|
2659
|
+
label: "Ent",
|
|
2660
|
+
hint: "Code-first ORM by Meta with graph traversal API, 15k+ stars"
|
|
2661
|
+
},
|
|
2647
2662
|
{
|
|
2648
2663
|
value: "none",
|
|
2649
2664
|
label: "None",
|
|
@@ -2703,21 +2718,63 @@ async function getGoLoggingChoice(goLogging) {
|
|
|
2703
2718
|
if (goLogging !== void 0) return goLogging;
|
|
2704
2719
|
const response = await navigableSelect({
|
|
2705
2720
|
message: "Select Go logging library",
|
|
2706
|
-
options: [
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2721
|
+
options: [
|
|
2722
|
+
{
|
|
2723
|
+
value: "zap",
|
|
2724
|
+
label: "Zap",
|
|
2725
|
+
hint: "Blazing fast, structured, leveled logging in Go"
|
|
2726
|
+
},
|
|
2727
|
+
{
|
|
2728
|
+
value: "zerolog",
|
|
2729
|
+
label: "Zerolog",
|
|
2730
|
+
hint: "Zero-allocation JSON logger, fastest in benchmarks"
|
|
2731
|
+
},
|
|
2732
|
+
{
|
|
2733
|
+
value: "slog",
|
|
2734
|
+
label: "slog",
|
|
2735
|
+
hint: "Go 1.21+ stdlib structured logging (no external dependency)"
|
|
2736
|
+
},
|
|
2737
|
+
{
|
|
2738
|
+
value: "none",
|
|
2739
|
+
label: "None",
|
|
2740
|
+
hint: "No logging library"
|
|
2741
|
+
}
|
|
2742
|
+
],
|
|
2715
2743
|
initialValue: "zap"
|
|
2716
2744
|
});
|
|
2717
2745
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2718
2746
|
return response;
|
|
2719
2747
|
}
|
|
2720
2748
|
|
|
2749
|
+
//#endregion
|
|
2750
|
+
//#region src/prompts/i18n.ts
|
|
2751
|
+
async function getI18nChoice(i18n, frontend) {
|
|
2752
|
+
if (i18n !== void 0) return i18n;
|
|
2753
|
+
const response = await navigableSelect({
|
|
2754
|
+
message: "Select internationalization (i18n) library",
|
|
2755
|
+
options: [
|
|
2756
|
+
{
|
|
2757
|
+
value: "i18next",
|
|
2758
|
+
label: "i18next",
|
|
2759
|
+
hint: "Full-featured i18n framework, works with all frontends"
|
|
2760
|
+
},
|
|
2761
|
+
...frontend?.includes("next") ?? false ? [{
|
|
2762
|
+
value: "next-intl",
|
|
2763
|
+
label: "next-intl",
|
|
2764
|
+
hint: "Lightweight i18n for Next.js with App Router support"
|
|
2765
|
+
}] : [],
|
|
2766
|
+
{
|
|
2767
|
+
value: "none",
|
|
2768
|
+
label: "None",
|
|
2769
|
+
hint: "No internationalization setup"
|
|
2770
|
+
}
|
|
2771
|
+
],
|
|
2772
|
+
initialValue: "none"
|
|
2773
|
+
});
|
|
2774
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2775
|
+
return response;
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2721
2778
|
//#endregion
|
|
2722
2779
|
//#region src/utils/command-exists.ts
|
|
2723
2780
|
async function commandExists(command) {
|
|
@@ -3098,6 +3155,11 @@ async function getPythonWebFrameworkChoice(pythonWebFramework) {
|
|
|
3098
3155
|
label: "Flask",
|
|
3099
3156
|
hint: "Lightweight WSGI web framework with minimal boilerplate"
|
|
3100
3157
|
},
|
|
3158
|
+
{
|
|
3159
|
+
value: "litestar",
|
|
3160
|
+
label: "Litestar",
|
|
3161
|
+
hint: "High-performance ASGI framework with class-based controllers"
|
|
3162
|
+
},
|
|
3101
3163
|
{
|
|
3102
3164
|
value: "none",
|
|
3103
3165
|
label: "None",
|
|
@@ -3201,6 +3263,32 @@ async function getPythonAiChoice(pythonAi) {
|
|
|
3201
3263
|
if (response.includes("none")) return [];
|
|
3202
3264
|
return response;
|
|
3203
3265
|
}
|
|
3266
|
+
async function getPythonAuthChoice(pythonAuth) {
|
|
3267
|
+
if (pythonAuth !== void 0) return pythonAuth;
|
|
3268
|
+
const response = await navigableSelect({
|
|
3269
|
+
message: "Select Python authentication library",
|
|
3270
|
+
options: [
|
|
3271
|
+
{
|
|
3272
|
+
value: "authlib",
|
|
3273
|
+
label: "Authlib",
|
|
3274
|
+
hint: "Comprehensive auth library — OAuth1/2, OIDC, JWS, JWK, JWT"
|
|
3275
|
+
},
|
|
3276
|
+
{
|
|
3277
|
+
value: "jwt",
|
|
3278
|
+
label: "JWT (python-jose)",
|
|
3279
|
+
hint: "Simple JWT token creation and verification"
|
|
3280
|
+
},
|
|
3281
|
+
{
|
|
3282
|
+
value: "none",
|
|
3283
|
+
label: "None",
|
|
3284
|
+
hint: "No authentication library"
|
|
3285
|
+
}
|
|
3286
|
+
],
|
|
3287
|
+
initialValue: "none"
|
|
3288
|
+
});
|
|
3289
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3290
|
+
return response;
|
|
3291
|
+
}
|
|
3204
3292
|
async function getPythonTaskQueueChoice(pythonTaskQueue) {
|
|
3205
3293
|
if (pythonTaskQueue !== void 0) return pythonTaskQueue;
|
|
3206
3294
|
const response = await navigableSelect({
|
|
@@ -3219,6 +3307,24 @@ async function getPythonTaskQueueChoice(pythonTaskQueue) {
|
|
|
3219
3307
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3220
3308
|
return response;
|
|
3221
3309
|
}
|
|
3310
|
+
async function getPythonGraphqlChoice(pythonGraphql) {
|
|
3311
|
+
if (pythonGraphql !== void 0) return pythonGraphql;
|
|
3312
|
+
const response = await navigableSelect({
|
|
3313
|
+
message: "Select Python GraphQL framework",
|
|
3314
|
+
options: [{
|
|
3315
|
+
value: "strawberry",
|
|
3316
|
+
label: "Strawberry",
|
|
3317
|
+
hint: "Python GraphQL library using dataclasses and type hints"
|
|
3318
|
+
}, {
|
|
3319
|
+
value: "none",
|
|
3320
|
+
label: "None",
|
|
3321
|
+
hint: "No GraphQL framework"
|
|
3322
|
+
}],
|
|
3323
|
+
initialValue: "none"
|
|
3324
|
+
});
|
|
3325
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3326
|
+
return response;
|
|
3327
|
+
}
|
|
3222
3328
|
async function getPythonQualityChoice(pythonQuality) {
|
|
3223
3329
|
if (pythonQuality !== void 0) return pythonQuality;
|
|
3224
3330
|
const response = await navigableSelect({
|
|
@@ -3333,6 +3439,11 @@ async function getRustWebFrameworkChoice(rustWebFramework) {
|
|
|
3333
3439
|
label: "Actix Web",
|
|
3334
3440
|
hint: "Powerful, pragmatic, and extremely fast web framework"
|
|
3335
3441
|
},
|
|
3442
|
+
{
|
|
3443
|
+
value: "rocket",
|
|
3444
|
+
label: "Rocket",
|
|
3445
|
+
hint: "Convention-over-configuration web framework, 25k+ stars"
|
|
3446
|
+
},
|
|
3336
3447
|
{
|
|
3337
3448
|
value: "none",
|
|
3338
3449
|
label: "None",
|
|
@@ -3385,6 +3496,11 @@ async function getRustOrmChoice(rustOrm) {
|
|
|
3385
3496
|
label: "SQLx",
|
|
3386
3497
|
hint: "Async SQL toolkit with compile-time checked queries"
|
|
3387
3498
|
},
|
|
3499
|
+
{
|
|
3500
|
+
value: "diesel",
|
|
3501
|
+
label: "Diesel",
|
|
3502
|
+
hint: "Safe, extensible ORM with compile-time query validation"
|
|
3503
|
+
},
|
|
3388
3504
|
{
|
|
3389
3505
|
value: "none",
|
|
3390
3506
|
label: "None",
|
|
@@ -3516,6 +3632,58 @@ async function getRustLoggingChoice(rustLogging) {
|
|
|
3516
3632
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3517
3633
|
return response;
|
|
3518
3634
|
}
|
|
3635
|
+
async function getRustErrorHandlingChoice(rustErrorHandling) {
|
|
3636
|
+
if (rustErrorHandling !== void 0) return rustErrorHandling;
|
|
3637
|
+
const response = await navigableSelect({
|
|
3638
|
+
message: "Select Rust error handling library",
|
|
3639
|
+
options: [
|
|
3640
|
+
{
|
|
3641
|
+
value: "anyhow-thiserror",
|
|
3642
|
+
label: "anyhow + thiserror",
|
|
3643
|
+
hint: "anyhow for application errors, thiserror for custom error types"
|
|
3644
|
+
},
|
|
3645
|
+
{
|
|
3646
|
+
value: "eyre",
|
|
3647
|
+
label: "eyre + color-eyre",
|
|
3648
|
+
hint: "Customizable error reports with pretty backtraces via color-eyre"
|
|
3649
|
+
},
|
|
3650
|
+
{
|
|
3651
|
+
value: "none",
|
|
3652
|
+
label: "None",
|
|
3653
|
+
hint: "No error handling library (uses standard library only)"
|
|
3654
|
+
}
|
|
3655
|
+
],
|
|
3656
|
+
initialValue: "anyhow-thiserror"
|
|
3657
|
+
});
|
|
3658
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3659
|
+
return response;
|
|
3660
|
+
}
|
|
3661
|
+
async function getRustCachingChoice(rustCaching) {
|
|
3662
|
+
if (rustCaching !== void 0) return rustCaching;
|
|
3663
|
+
const response = await navigableSelect({
|
|
3664
|
+
message: "Select Rust caching library",
|
|
3665
|
+
options: [
|
|
3666
|
+
{
|
|
3667
|
+
value: "moka",
|
|
3668
|
+
label: "Moka",
|
|
3669
|
+
hint: "High-performance concurrent in-memory cache (Caffeine-inspired)"
|
|
3670
|
+
},
|
|
3671
|
+
{
|
|
3672
|
+
value: "redis",
|
|
3673
|
+
label: "Redis",
|
|
3674
|
+
hint: "Redis client with async support and connection pooling"
|
|
3675
|
+
},
|
|
3676
|
+
{
|
|
3677
|
+
value: "none",
|
|
3678
|
+
label: "None",
|
|
3679
|
+
hint: "No caching library"
|
|
3680
|
+
}
|
|
3681
|
+
],
|
|
3682
|
+
initialValue: "none"
|
|
3683
|
+
});
|
|
3684
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3685
|
+
return response;
|
|
3686
|
+
}
|
|
3519
3687
|
|
|
3520
3688
|
//#endregion
|
|
3521
3689
|
//#region src/prompts/search.ts
|
|
@@ -4220,6 +4388,10 @@ function getDeploymentDisplay(deployment) {
|
|
|
4220
4388
|
label: "Cloudflare",
|
|
4221
4389
|
hint: "Deploy to Cloudflare Workers using Alchemy"
|
|
4222
4390
|
};
|
|
4391
|
+
if (deployment === "vercel") return {
|
|
4392
|
+
label: "Vercel",
|
|
4393
|
+
hint: "Deploy to Vercel's edge network"
|
|
4394
|
+
};
|
|
4223
4395
|
return {
|
|
4224
4396
|
label: deployment,
|
|
4225
4397
|
hint: `Add ${deployment} deployment`
|
|
@@ -4230,7 +4402,11 @@ async function getDeploymentChoice(deployment, _runtime, _backend, frontend = []
|
|
|
4230
4402
|
if (!hasWebFrontend(frontend)) return "none";
|
|
4231
4403
|
const response = await navigableSelect({
|
|
4232
4404
|
message: "Select web deployment",
|
|
4233
|
-
options: [
|
|
4405
|
+
options: [
|
|
4406
|
+
"cloudflare",
|
|
4407
|
+
"vercel",
|
|
4408
|
+
"none"
|
|
4409
|
+
].map((deploy) => {
|
|
4234
4410
|
const { label, hint } = getDeploymentDisplay(deploy);
|
|
4235
4411
|
return {
|
|
4236
4412
|
value: deploy,
|
|
@@ -4398,6 +4574,10 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
4398
4574
|
if (results.ecosystem !== "typescript") return Promise.resolve("none");
|
|
4399
4575
|
return getCachingChoice(flags.caching, results.backend);
|
|
4400
4576
|
},
|
|
4577
|
+
i18n: ({ results }) => {
|
|
4578
|
+
if (results.ecosystem !== "typescript") return Promise.resolve("none");
|
|
4579
|
+
return getI18nChoice(flags.i18n, results.frontend);
|
|
4580
|
+
},
|
|
4401
4581
|
search: ({ results }) => {
|
|
4402
4582
|
if (results.ecosystem !== "typescript") return Promise.resolve("none");
|
|
4403
4583
|
return getSearchChoice(flags.search, results.backend);
|
|
@@ -4434,6 +4614,14 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
4434
4614
|
if (results.ecosystem !== "rust") return Promise.resolve("none");
|
|
4435
4615
|
return getRustLoggingChoice(flags.rustLogging);
|
|
4436
4616
|
},
|
|
4617
|
+
rustErrorHandling: ({ results }) => {
|
|
4618
|
+
if (results.ecosystem !== "rust") return Promise.resolve("none");
|
|
4619
|
+
return getRustErrorHandlingChoice(flags.rustErrorHandling);
|
|
4620
|
+
},
|
|
4621
|
+
rustCaching: ({ results }) => {
|
|
4622
|
+
if (results.ecosystem !== "rust") return Promise.resolve("none");
|
|
4623
|
+
return getRustCachingChoice(flags.rustCaching);
|
|
4624
|
+
},
|
|
4437
4625
|
pythonWebFramework: ({ results }) => {
|
|
4438
4626
|
if (results.ecosystem !== "python") return Promise.resolve("none");
|
|
4439
4627
|
return getPythonWebFrameworkChoice(flags.pythonWebFramework);
|
|
@@ -4450,10 +4638,18 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
4450
4638
|
if (results.ecosystem !== "python") return Promise.resolve([]);
|
|
4451
4639
|
return getPythonAiChoice(flags.pythonAi);
|
|
4452
4640
|
},
|
|
4641
|
+
pythonAuth: ({ results }) => {
|
|
4642
|
+
if (results.ecosystem !== "python") return Promise.resolve("none");
|
|
4643
|
+
return getPythonAuthChoice(flags.pythonAuth);
|
|
4644
|
+
},
|
|
4453
4645
|
pythonTaskQueue: ({ results }) => {
|
|
4454
4646
|
if (results.ecosystem !== "python") return Promise.resolve("none");
|
|
4455
4647
|
return getPythonTaskQueueChoice(flags.pythonTaskQueue);
|
|
4456
4648
|
},
|
|
4649
|
+
pythonGraphql: ({ results }) => {
|
|
4650
|
+
if (results.ecosystem !== "python") return Promise.resolve("none");
|
|
4651
|
+
return getPythonGraphqlChoice(flags.pythonGraphql);
|
|
4652
|
+
},
|
|
4457
4653
|
pythonQuality: ({ results }) => {
|
|
4458
4654
|
if (results.ecosystem !== "python") return Promise.resolve("none");
|
|
4459
4655
|
return getPythonQualityChoice(flags.pythonQuality);
|
|
@@ -4527,6 +4723,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
4527
4723
|
analytics: result.analytics,
|
|
4528
4724
|
cms: result.cms,
|
|
4529
4725
|
caching: result.caching,
|
|
4726
|
+
i18n: result.i18n,
|
|
4530
4727
|
search: result.search,
|
|
4531
4728
|
fileStorage: result.fileStorage,
|
|
4532
4729
|
ecosystem: result.ecosystem,
|
|
@@ -4537,11 +4734,15 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
4537
4734
|
rustCli: result.rustCli,
|
|
4538
4735
|
rustLibraries: result.rustLibraries,
|
|
4539
4736
|
rustLogging: result.rustLogging,
|
|
4737
|
+
rustErrorHandling: result.rustErrorHandling,
|
|
4738
|
+
rustCaching: result.rustCaching,
|
|
4540
4739
|
pythonWebFramework: result.pythonWebFramework,
|
|
4541
4740
|
pythonOrm: result.pythonOrm,
|
|
4542
4741
|
pythonValidation: result.pythonValidation,
|
|
4543
4742
|
pythonAi: result.pythonAi,
|
|
4743
|
+
pythonAuth: result.pythonAuth,
|
|
4544
4744
|
pythonTaskQueue: result.pythonTaskQueue,
|
|
4745
|
+
pythonGraphql: result.pythonGraphql,
|
|
4545
4746
|
pythonQuality: result.pythonQuality,
|
|
4546
4747
|
goWebFramework: result.goWebFramework,
|
|
4547
4748
|
goOrm: result.goOrm,
|
|
@@ -4802,6 +5003,7 @@ function getTypeScriptFlags(config) {
|
|
|
4802
5003
|
flags.push(`--logging ${config.logging}`);
|
|
4803
5004
|
flags.push(`--observability ${config.observability}`);
|
|
4804
5005
|
flags.push(`--caching ${config.caching}`);
|
|
5006
|
+
flags.push(`--i18n ${config.i18n}`);
|
|
4805
5007
|
flags.push(`--cms ${config.cms}`);
|
|
4806
5008
|
flags.push(`--search ${config.search}`);
|
|
4807
5009
|
flags.push(`--file-storage ${config.fileStorage}`);
|
|
@@ -4824,6 +5026,8 @@ function getRustFlags(config) {
|
|
|
4824
5026
|
flags.push(`--rust-cli ${config.rustCli}`);
|
|
4825
5027
|
flags.push(formatArrayFlag("rust-libraries", config.rustLibraries));
|
|
4826
5028
|
flags.push(`--rust-logging ${config.rustLogging}`);
|
|
5029
|
+
flags.push(`--rust-error-handling ${config.rustErrorHandling}`);
|
|
5030
|
+
flags.push(`--rust-caching ${config.rustCaching}`);
|
|
4827
5031
|
appendSharedNonTypeScriptFlags(flags, config);
|
|
4828
5032
|
appendCommonFlags(flags, config);
|
|
4829
5033
|
return flags;
|
|
@@ -4834,7 +5038,9 @@ function getPythonFlags(config) {
|
|
|
4834
5038
|
flags.push(`--python-orm ${config.pythonOrm}`);
|
|
4835
5039
|
flags.push(`--python-validation ${config.pythonValidation}`);
|
|
4836
5040
|
flags.push(formatArrayFlag("python-ai", config.pythonAi));
|
|
5041
|
+
flags.push(`--python-auth ${config.pythonAuth}`);
|
|
4837
5042
|
flags.push(`--python-task-queue ${config.pythonTaskQueue}`);
|
|
5043
|
+
flags.push(`--python-graphql ${config.pythonGraphql}`);
|
|
4838
5044
|
flags.push(`--python-quality ${config.pythonQuality}`);
|
|
4839
5045
|
appendSharedNonTypeScriptFlags(flags, config);
|
|
4840
5046
|
appendCommonFlags(flags, config);
|
|
@@ -5071,6 +5277,7 @@ function processFlags(options, projectName) {
|
|
|
5071
5277
|
if (options.observability !== void 0) config.observability = options.observability;
|
|
5072
5278
|
if (options.cms !== void 0) config.cms = options.cms;
|
|
5073
5279
|
if (options.caching !== void 0) config.caching = options.caching;
|
|
5280
|
+
if (options.i18n !== void 0) config.i18n = options.i18n;
|
|
5074
5281
|
if (options.search !== void 0) config.search = options.search;
|
|
5075
5282
|
if (options.fileStorage !== void 0) config.fileStorage = options.fileStorage;
|
|
5076
5283
|
if (options.analytics !== void 0) config.analytics = options.analytics;
|
|
@@ -5107,11 +5314,15 @@ function processFlags(options, projectName) {
|
|
|
5107
5314
|
if (options.rustCli !== void 0) config.rustCli = options.rustCli;
|
|
5108
5315
|
if (options.rustLibraries !== void 0) config.rustLibraries = processArrayOption(options.rustLibraries);
|
|
5109
5316
|
if (options.rustLogging !== void 0) config.rustLogging = options.rustLogging;
|
|
5317
|
+
if (options.rustErrorHandling !== void 0) config.rustErrorHandling = options.rustErrorHandling;
|
|
5318
|
+
if (options.rustCaching !== void 0) config.rustCaching = options.rustCaching;
|
|
5110
5319
|
if (options.pythonWebFramework !== void 0) config.pythonWebFramework = options.pythonWebFramework;
|
|
5111
5320
|
if (options.pythonOrm !== void 0) config.pythonOrm = options.pythonOrm;
|
|
5112
5321
|
if (options.pythonValidation !== void 0) config.pythonValidation = options.pythonValidation;
|
|
5113
5322
|
if (options.pythonAi !== void 0) config.pythonAi = processArrayOption(options.pythonAi);
|
|
5323
|
+
if (options.pythonAuth !== void 0) config.pythonAuth = options.pythonAuth;
|
|
5114
5324
|
if (options.pythonTaskQueue !== void 0) config.pythonTaskQueue = options.pythonTaskQueue;
|
|
5325
|
+
if (options.pythonGraphql !== void 0) config.pythonGraphql = options.pythonGraphql;
|
|
5115
5326
|
if (options.pythonQuality !== void 0) config.pythonQuality = options.pythonQuality;
|
|
5116
5327
|
if (options.goWebFramework !== void 0) config.goWebFramework = options.goWebFramework;
|
|
5117
5328
|
if (options.goOrm !== void 0) config.goOrm = options.goOrm;
|
|
@@ -5603,6 +5814,18 @@ function validateFullConfig(config, providedFlags, options) {
|
|
|
5603
5814
|
validateWorkersCompatibility(providedFlags, options, config);
|
|
5604
5815
|
if (config.runtime === "workers" && config.serverDeploy === "none") exitWithError("Cloudflare Workers runtime requires a server deployment. Please choose 'alchemy' for --server-deploy.");
|
|
5605
5816
|
if (providedFlags.has("serverDeploy") && config.serverDeploy === "cloudflare" && config.runtime !== "workers") exitWithError(`Server deployment '${config.serverDeploy}' requires '--runtime workers'. Please use '--runtime workers' or choose a different server deployment.`);
|
|
5817
|
+
if (config.serverDeploy === "vercel" && [
|
|
5818
|
+
"nestjs",
|
|
5819
|
+
"adonisjs",
|
|
5820
|
+
"encore"
|
|
5821
|
+
].includes(config.backend)) incompatibilityError({
|
|
5822
|
+
message: "Vercel serverless functions cannot host persistent-process backends",
|
|
5823
|
+
provided: {
|
|
5824
|
+
backend: config.backend,
|
|
5825
|
+
serverDeploy: config.serverDeploy
|
|
5826
|
+
},
|
|
5827
|
+
suggestions: ["Use --server-deploy fly or --server-deploy railway for NestJS/AdonisJS", "Switch to a serverless-compatible backend like Hono or Express"]
|
|
5828
|
+
});
|
|
5606
5829
|
if (config.addons && config.addons.length > 0) {
|
|
5607
5830
|
validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth);
|
|
5608
5831
|
config.addons = [...new Set(config.addons)];
|
|
@@ -6977,6 +7200,7 @@ async function displayPostInstallInstructions(config) {
|
|
|
6977
7200
|
const polarInstructions = config.payments === "polar" ? getPolarInstructions(backend, packageManager) : "";
|
|
6978
7201
|
const paymentSetupInstructions = getPaymentSetupInstructions(config.payments, backend);
|
|
6979
7202
|
const alchemyDeployInstructions = getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend);
|
|
7203
|
+
const vercelDeployInstructions = getVercelDeployInstructions(webDeploy, serverDeploy, backend);
|
|
6980
7204
|
const hasWeb = frontend?.some((f) => WEB_FRAMEWORKS.includes(f));
|
|
6981
7205
|
const hasNative = frontend?.includes("native-bare") || frontend?.includes("native-uniwind") || frontend?.includes("native-unistyles");
|
|
6982
7206
|
const bunWebNativeWarning = packageManager === "bun" && hasNative && hasWeb ? getBunWebNativeWarning() : "";
|
|
@@ -7022,6 +7246,7 @@ async function displayPostInstallInstructions(config) {
|
|
|
7022
7246
|
if (lintingInstructions) output += `\n${lintingInstructions.trim()}\n`;
|
|
7023
7247
|
if (pwaInstructions) output += `\n${pwaInstructions.trim()}\n`;
|
|
7024
7248
|
if (alchemyDeployInstructions) output += `\n${alchemyDeployInstructions.trim()}\n`;
|
|
7249
|
+
if (vercelDeployInstructions) output += `\n${vercelDeployInstructions.trim()}\n`;
|
|
7025
7250
|
if (starlightInstructions) output += `\n${starlightInstructions.trim()}\n`;
|
|
7026
7251
|
if (clerkInstructions) output += `\n${clerkInstructions.trim()}\n`;
|
|
7027
7252
|
if (authSetupInstructions) output += `\n${authSetupInstructions.trim()}\n`;
|
|
@@ -7162,6 +7387,18 @@ function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend)
|
|
|
7162
7387
|
else if (webDeploy === "cloudflare" && (serverDeploy === "cloudflare" || isBackendSelf)) instructions.push(`${pc.bold("Deploy with Alchemy:")}\n${pc.cyan("•")} Dev: ${`${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`${runCmd} destroy`}`);
|
|
7163
7388
|
return instructions.length ? `\n${instructions.join("\n")}` : "";
|
|
7164
7389
|
}
|
|
7390
|
+
function getVercelDeployInstructions(webDeploy, serverDeploy, backend) {
|
|
7391
|
+
const instructions = [];
|
|
7392
|
+
const isBackendSelf = backend === "self";
|
|
7393
|
+
if (webDeploy === "vercel" || serverDeploy === "vercel") {
|
|
7394
|
+
instructions.push(pc.bold("Deploy with Vercel:"));
|
|
7395
|
+
instructions.push(`${pc.cyan("•")} Install Vercel CLI: ${pc.white("npm i -g vercel")}`);
|
|
7396
|
+
if (webDeploy === "vercel") instructions.push(`${pc.cyan("•")} Deploy web: ${pc.white(`cd apps/web && vercel`)}`);
|
|
7397
|
+
if (serverDeploy === "vercel" && !isBackendSelf) instructions.push(`${pc.cyan("•")} Deploy server: ${pc.white(`cd apps/server && vercel`)}`);
|
|
7398
|
+
instructions.push(`${pc.cyan("•")} Docs: ${pc.underline("https://vercel.com/docs")}`);
|
|
7399
|
+
}
|
|
7400
|
+
return instructions.length ? `\n${instructions.join("\n")}` : "";
|
|
7401
|
+
}
|
|
7165
7402
|
function displayRustInstructions(config) {
|
|
7166
7403
|
const { relativePath, rustWebFramework, rustFrontend, rustOrm, rustApi, rustCli } = config;
|
|
7167
7404
|
const cdCmd = `cd ${relativePath}`;
|
|
@@ -7198,6 +7435,16 @@ function displayRustInstructions(config) {
|
|
|
7198
7435
|
tracing: "Tracing",
|
|
7199
7436
|
"env-logger": "env_logger"
|
|
7200
7437
|
}[rustLogging] || rustLogging}\n`;
|
|
7438
|
+
const { rustErrorHandling } = config;
|
|
7439
|
+
if (rustErrorHandling && rustErrorHandling !== "none") output += `${pc.cyan("•")} Error Handling: ${{
|
|
7440
|
+
"anyhow-thiserror": "anyhow + thiserror",
|
|
7441
|
+
eyre: "eyre + color-eyre"
|
|
7442
|
+
}[rustErrorHandling] || rustErrorHandling}\n`;
|
|
7443
|
+
const { rustCaching } = config;
|
|
7444
|
+
if (rustCaching && rustCaching !== "none") output += `${pc.cyan("•")} Caching: ${{
|
|
7445
|
+
moka: "Moka",
|
|
7446
|
+
redis: "Redis"
|
|
7447
|
+
}[rustCaching] || rustCaching}\n`;
|
|
7201
7448
|
output += `\n${pc.bold("Common Cargo commands:")}\n`;
|
|
7202
7449
|
output += `${pc.cyan("•")} Build: cargo build\n`;
|
|
7203
7450
|
output += `${pc.cyan("•")} Run: cargo run\n`;
|
|
@@ -7221,18 +7468,24 @@ function displayGoInstructions(config) {
|
|
|
7221
7468
|
if (goWebFramework && goWebFramework !== "none") output += `${pc.cyan("•")} Web Framework: ${{
|
|
7222
7469
|
gin: "Gin",
|
|
7223
7470
|
echo: "Echo",
|
|
7224
|
-
fiber: "Fiber"
|
|
7471
|
+
fiber: "Fiber",
|
|
7472
|
+
chi: "Chi"
|
|
7225
7473
|
}[goWebFramework] || goWebFramework}\n`;
|
|
7226
7474
|
if (goOrm && goOrm !== "none") output += `${pc.cyan("•")} Database: ${{
|
|
7227
7475
|
gorm: "GORM",
|
|
7228
|
-
sqlc: "sqlc"
|
|
7476
|
+
sqlc: "sqlc",
|
|
7477
|
+
ent: "Ent"
|
|
7229
7478
|
}[goOrm] || goOrm}\n`;
|
|
7230
7479
|
if (goApi && goApi !== "none") output += `${pc.cyan("•")} API: ${{ "grpc-go": "gRPC-Go" }[goApi] || goApi}\n`;
|
|
7231
7480
|
if (goCli && goCli !== "none") output += `${pc.cyan("•")} CLI: ${{
|
|
7232
7481
|
cobra: "Cobra",
|
|
7233
7482
|
bubbletea: "Bubble Tea"
|
|
7234
7483
|
}[goCli] || goCli}\n`;
|
|
7235
|
-
if (goLogging && goLogging !== "none") output += `${pc.cyan("•")} Logging: ${{
|
|
7484
|
+
if (goLogging && goLogging !== "none") output += `${pc.cyan("•")} Logging: ${{
|
|
7485
|
+
zap: "Zap",
|
|
7486
|
+
zerolog: "Zerolog",
|
|
7487
|
+
slog: "slog"
|
|
7488
|
+
}[goLogging] || goLogging}\n`;
|
|
7236
7489
|
output += `\n${pc.bold("Common Go commands:")}\n`;
|
|
7237
7490
|
output += `${pc.cyan("•")} Build: go build ./...\n`;
|
|
7238
7491
|
output += `${pc.cyan("•")} Run: go run cmd/server/main.go\n`;
|
|
@@ -7254,6 +7507,7 @@ function displayPythonInstructions(config) {
|
|
|
7254
7507
|
let runCommand = "uv run uvicorn app.main:app --reload";
|
|
7255
7508
|
if (pythonWebFramework === "django") runCommand = "uv run python manage.py runserver";
|
|
7256
7509
|
else if (pythonWebFramework === "flask") runCommand = "uv run flask --app app.main run --reload";
|
|
7510
|
+
else if (pythonWebFramework === "litestar") runCommand = "litestar --app src.app.main:app run --reload --port 3001";
|
|
7257
7511
|
let output = `${pc.bold("Next steps")}\n${pc.cyan("1.")} ${cdCmd}\n`;
|
|
7258
7512
|
let stepCounter = 2;
|
|
7259
7513
|
if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} uv sync\n`;
|
|
@@ -7262,7 +7516,8 @@ function displayPythonInstructions(config) {
|
|
|
7262
7516
|
if (pythonWebFramework && pythonWebFramework !== "none") output += `${pc.cyan("•")} Web Framework: ${{
|
|
7263
7517
|
fastapi: "FastAPI",
|
|
7264
7518
|
django: "Django",
|
|
7265
|
-
flask: "Flask"
|
|
7519
|
+
flask: "Flask",
|
|
7520
|
+
litestar: "Litestar"
|
|
7266
7521
|
}[pythonWebFramework] || pythonWebFramework}\n`;
|
|
7267
7522
|
if (pythonOrm && pythonOrm !== "none") output += `${pc.cyan("•")} ORM: ${{
|
|
7268
7523
|
sqlalchemy: "SQLAlchemy",
|
|
@@ -7450,8 +7705,11 @@ async function createProjectHandler(input, options = {}) {
|
|
|
7450
7705
|
rustCli: "none",
|
|
7451
7706
|
rustLibraries: [],
|
|
7452
7707
|
rustLogging: "none",
|
|
7708
|
+
rustErrorHandling: "none",
|
|
7709
|
+
rustCaching: "none",
|
|
7453
7710
|
cms: "none",
|
|
7454
7711
|
caching: "none",
|
|
7712
|
+
i18n: "none",
|
|
7455
7713
|
search: "none",
|
|
7456
7714
|
featureFlags: "none",
|
|
7457
7715
|
analytics: "none",
|
|
@@ -7460,7 +7718,9 @@ async function createProjectHandler(input, options = {}) {
|
|
|
7460
7718
|
pythonOrm: "none",
|
|
7461
7719
|
pythonValidation: "none",
|
|
7462
7720
|
pythonAi: [],
|
|
7721
|
+
pythonAuth: "none",
|
|
7463
7722
|
pythonTaskQueue: "none",
|
|
7723
|
+
pythonGraphql: "none",
|
|
7464
7724
|
pythonQuality: "none",
|
|
7465
7725
|
goWebFramework: "none",
|
|
7466
7726
|
goOrm: "none",
|
|
@@ -7764,6 +8024,7 @@ const router = os.router({
|
|
|
7764
8024
|
analytics: types_exports.AnalyticsSchema.optional().describe("Privacy-focused analytics"),
|
|
7765
8025
|
cms: types_exports.CMSSchema.optional().describe("Headless CMS solution"),
|
|
7766
8026
|
caching: types_exports.CachingSchema.optional().describe("Caching solution"),
|
|
8027
|
+
i18n: types_exports.I18nSchema.optional().describe("Internationalization (i18n) library"),
|
|
7767
8028
|
search: types_exports.SearchSchema.optional().describe("Search engine solution"),
|
|
7768
8029
|
fileStorage: types_exports.FileStorageSchema.optional().describe("File storage solution (S3, R2)"),
|
|
7769
8030
|
frontend: z.array(types_exports.FrontendSchema).optional(),
|
|
@@ -7800,17 +8061,21 @@ const router = os.router({
|
|
|
7800
8061
|
rustCli: types_exports.RustCliSchema.optional().describe("Rust CLI tools (clap, ratatui)"),
|
|
7801
8062
|
rustLibraries: z.array(types_exports.RustLibrariesSchema).optional().describe("Rust core libraries"),
|
|
7802
8063
|
rustLogging: types_exports.RustLoggingSchema.optional().describe("Rust logging (tracing, env-logger)"),
|
|
8064
|
+
rustErrorHandling: types_exports.RustErrorHandlingSchema.optional().describe("Rust error handling (anyhow-thiserror, eyre)"),
|
|
8065
|
+
rustCaching: types_exports.RustCachingSchema.optional().describe("Rust caching (moka, redis)"),
|
|
7803
8066
|
pythonWebFramework: types_exports.PythonWebFrameworkSchema.optional().describe("Python web framework (fastapi, django)"),
|
|
7804
8067
|
pythonOrm: types_exports.PythonOrmSchema.optional().describe("Python ORM/database (sqlalchemy, sqlmodel)"),
|
|
7805
8068
|
pythonValidation: types_exports.PythonValidationSchema.optional().describe("Python validation (pydantic)"),
|
|
7806
8069
|
pythonAi: z.array(types_exports.PythonAiSchema).optional().describe("Python AI/ML frameworks"),
|
|
8070
|
+
pythonAuth: types_exports.PythonAuthSchema.optional().describe("Python auth library (authlib, jwt)"),
|
|
7807
8071
|
pythonTaskQueue: types_exports.PythonTaskQueueSchema.optional().describe("Python task queue (celery)"),
|
|
8072
|
+
pythonGraphql: types_exports.PythonGraphqlSchema.optional().describe("Python GraphQL framework (strawberry)"),
|
|
7808
8073
|
pythonQuality: types_exports.PythonQualitySchema.optional().describe("Python code quality (ruff)"),
|
|
7809
8074
|
goWebFramework: types_exports.GoWebFrameworkSchema.optional().describe("Go web framework (gin, echo, fiber)"),
|
|
7810
8075
|
goOrm: types_exports.GoOrmSchema.optional().describe("Go ORM/database (gorm, sqlc)"),
|
|
7811
8076
|
goApi: types_exports.GoApiSchema.optional().describe("Go API layer (grpc-go)"),
|
|
7812
8077
|
goCli: types_exports.GoCliSchema.optional().describe("Go CLI tools (cobra, bubbletea)"),
|
|
7813
|
-
goLogging: types_exports.GoLoggingSchema.optional().describe("Go logging (zap)"),
|
|
8078
|
+
goLogging: types_exports.GoLoggingSchema.optional().describe("Go logging (zap, zerolog, slog)"),
|
|
7814
8079
|
aiDocs: z.array(types_exports.AiDocsSchema).optional().describe("AI documentation files (claude-md, agents-md, cursorrules)")
|
|
7815
8080
|
})])).handler(async ({ input }) => {
|
|
7816
8081
|
const [projectName, options] = input;
|
|
@@ -8032,6 +8297,7 @@ async function createVirtual(options) {
|
|
|
8032
8297
|
analytics: options.analytics || "none",
|
|
8033
8298
|
cms: options.cms || "none",
|
|
8034
8299
|
caching: options.caching || "none",
|
|
8300
|
+
i18n: options.i18n || "none",
|
|
8035
8301
|
search: options.search || "none",
|
|
8036
8302
|
fileStorage: options.fileStorage || "none",
|
|
8037
8303
|
rustWebFramework: options.rustWebFramework || "none",
|
|
@@ -8041,11 +8307,15 @@ async function createVirtual(options) {
|
|
|
8041
8307
|
rustCli: options.rustCli || "none",
|
|
8042
8308
|
rustLibraries: options.rustLibraries || [],
|
|
8043
8309
|
rustLogging: options.rustLogging || (options.ecosystem === "rust" ? "tracing" : "none"),
|
|
8310
|
+
rustErrorHandling: options.rustErrorHandling || (options.ecosystem === "rust" ? "anyhow-thiserror" : "none"),
|
|
8311
|
+
rustCaching: options.rustCaching || "none",
|
|
8044
8312
|
pythonWebFramework: options.pythonWebFramework || "none",
|
|
8045
8313
|
pythonOrm: options.pythonOrm || "none",
|
|
8046
8314
|
pythonValidation: options.pythonValidation || "none",
|
|
8047
8315
|
pythonAi: options.pythonAi || [],
|
|
8316
|
+
pythonAuth: options.pythonAuth || "none",
|
|
8048
8317
|
pythonTaskQueue: options.pythonTaskQueue || "none",
|
|
8318
|
+
pythonGraphql: options.pythonGraphql || "none",
|
|
8049
8319
|
pythonQuality: options.pythonQuality || "none",
|
|
8050
8320
|
goWebFramework: options.goWebFramework || "none",
|
|
8051
8321
|
goOrm: options.goOrm || "none",
|
package/dist/mcp-entry.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as getLatestCLIVersion, r as writeBtsConfig, t as readBtsConfig } from "./bts-config-
|
|
2
|
+
import { i as getLatestCLIVersion, r as writeBtsConfig, t as readBtsConfig } from "./bts-config-snHxP_EH.mjs";
|
|
3
3
|
import z from "zod";
|
|
4
|
-
import { AISchema, APISchema, AddonsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BackendSchema, CMSSchema, CSSFrameworkSchema, CachingSchema, DatabaseSchema, DatabaseSetupSchema, EcosystemSchema, EffectSchema, EmailSchema, ExamplesSchema, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GoApiSchema, GoCliSchema, GoLoggingSchema, GoOrmSchema, GoWebFrameworkSchema, JobQueueSchema, LoggingSchema, ORMSchema, ObservabilitySchema, PackageManagerSchema, PaymentsSchema, PythonAiSchema, PythonOrmSchema, PythonQualitySchema, PythonTaskQueueSchema, PythonValidationSchema, PythonWebFrameworkSchema, RealtimeSchema, RuntimeSchema, RustApiSchema, RustCliSchema, RustFrontendSchema, RustLibrariesSchema, RustLoggingSchema, RustOrmSchema, RustWebFrameworkSchema, SearchSchema, ServerDeploySchema, StateManagementSchema, TestingSchema, UILibrarySchema, ValidationSchema, WebDeploySchema, analyzeStackCompatibility } from "@better-fullstack/types";
|
|
4
|
+
import { AISchema, APISchema, AddonsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BackendSchema, CMSSchema, CSSFrameworkSchema, CachingSchema, DatabaseSchema, DatabaseSetupSchema, EcosystemSchema, EffectSchema, EmailSchema, ExamplesSchema, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GoApiSchema, GoCliSchema, GoLoggingSchema, GoOrmSchema, GoWebFrameworkSchema, I18nSchema, JobQueueSchema, LoggingSchema, ORMSchema, ObservabilitySchema, PackageManagerSchema, PaymentsSchema, PythonAiSchema, PythonAuthSchema, PythonGraphqlSchema, PythonOrmSchema, PythonQualitySchema, PythonTaskQueueSchema, PythonValidationSchema, PythonWebFrameworkSchema, RealtimeSchema, RuntimeSchema, RustApiSchema, RustCachingSchema, RustCliSchema, RustErrorHandlingSchema, RustFrontendSchema, RustLibrariesSchema, RustLoggingSchema, RustOrmSchema, RustWebFrameworkSchema, SearchSchema, ServerDeploySchema, StateManagementSchema, TestingSchema, UILibrarySchema, ValidationSchema, WebDeploySchema, analyzeStackCompatibility } from "@better-fullstack/types";
|
|
5
5
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
7
|
|
|
@@ -99,6 +99,7 @@ const SCHEMA_MAP = {
|
|
|
99
99
|
analytics: AnalyticsSchema,
|
|
100
100
|
cms: CMSSchema,
|
|
101
101
|
caching: CachingSchema,
|
|
102
|
+
i18n: I18nSchema,
|
|
102
103
|
search: SearchSchema,
|
|
103
104
|
fileStorage: FileStorageSchema,
|
|
104
105
|
addons: AddonsSchema,
|
|
@@ -115,11 +116,15 @@ const SCHEMA_MAP = {
|
|
|
115
116
|
rustCli: RustCliSchema,
|
|
116
117
|
rustLibraries: RustLibrariesSchema,
|
|
117
118
|
rustLogging: RustLoggingSchema,
|
|
119
|
+
rustErrorHandling: RustErrorHandlingSchema,
|
|
120
|
+
rustCaching: RustCachingSchema,
|
|
118
121
|
pythonWebFramework: PythonWebFrameworkSchema,
|
|
119
122
|
pythonOrm: PythonOrmSchema,
|
|
120
123
|
pythonValidation: PythonValidationSchema,
|
|
121
124
|
pythonAi: PythonAiSchema,
|
|
125
|
+
pythonAuth: PythonAuthSchema,
|
|
122
126
|
pythonTaskQueue: PythonTaskQueueSchema,
|
|
127
|
+
pythonGraphql: PythonGraphqlSchema,
|
|
123
128
|
pythonQuality: PythonQualitySchema,
|
|
124
129
|
goWebFramework: GoWebFrameworkSchema,
|
|
125
130
|
goOrm: GoOrmSchema,
|
|
@@ -156,6 +161,7 @@ const ECOSYSTEM_CATEGORIES = {
|
|
|
156
161
|
"analytics",
|
|
157
162
|
"cms",
|
|
158
163
|
"caching",
|
|
164
|
+
"i18n",
|
|
159
165
|
"search",
|
|
160
166
|
"fileStorage",
|
|
161
167
|
"astroIntegration"
|
|
@@ -167,14 +173,18 @@ const ECOSYSTEM_CATEGORIES = {
|
|
|
167
173
|
"rustApi",
|
|
168
174
|
"rustCli",
|
|
169
175
|
"rustLibraries",
|
|
170
|
-
"rustLogging"
|
|
176
|
+
"rustLogging",
|
|
177
|
+
"rustErrorHandling",
|
|
178
|
+
"rustCaching"
|
|
171
179
|
],
|
|
172
180
|
python: [
|
|
173
181
|
"pythonWebFramework",
|
|
174
182
|
"pythonOrm",
|
|
175
183
|
"pythonValidation",
|
|
176
184
|
"pythonAi",
|
|
185
|
+
"pythonAuth",
|
|
177
186
|
"pythonTaskQueue",
|
|
187
|
+
"pythonGraphql",
|
|
178
188
|
"pythonQuality"
|
|
179
189
|
],
|
|
180
190
|
go: [
|
|
@@ -285,6 +295,7 @@ function buildProjectConfig(input, overrides) {
|
|
|
285
295
|
analytics: "none",
|
|
286
296
|
cms: input.cms ?? "none",
|
|
287
297
|
caching: input.caching ?? "none",
|
|
298
|
+
i18n: input.i18n ?? "none",
|
|
288
299
|
search: input.search ?? "none",
|
|
289
300
|
fileStorage: input.fileStorage ?? "none",
|
|
290
301
|
addons: input.addons ?? [],
|
|
@@ -305,11 +316,15 @@ function buildProjectConfig(input, overrides) {
|
|
|
305
316
|
rustCli: input.rustCli ?? "none",
|
|
306
317
|
rustLibraries: input.rustLibraries ?? [],
|
|
307
318
|
rustLogging: input.rustLogging ?? "none",
|
|
319
|
+
rustErrorHandling: input.rustErrorHandling ?? "none",
|
|
320
|
+
rustCaching: input.rustCaching ?? "none",
|
|
308
321
|
pythonWebFramework: input.pythonWebFramework ?? "none",
|
|
309
322
|
pythonOrm: input.pythonOrm ?? "none",
|
|
310
323
|
pythonValidation: input.pythonValidation ?? "none",
|
|
311
324
|
pythonAi: input.pythonAi ?? [],
|
|
325
|
+
pythonAuth: input.pythonAuth ?? "none",
|
|
312
326
|
pythonTaskQueue: input.pythonTaskQueue ?? "none",
|
|
327
|
+
pythonGraphql: input.pythonGraphql ?? "none",
|
|
313
328
|
pythonQuality: input.pythonQuality ?? "none",
|
|
314
329
|
goWebFramework: input.goWebFramework ?? "none",
|
|
315
330
|
goOrm: input.goOrm ?? "none",
|
|
@@ -367,6 +382,7 @@ function buildCompatibilityInput(input) {
|
|
|
367
382
|
realtime: input.realtime ?? "none",
|
|
368
383
|
jobQueue: input.jobQueue ?? "none",
|
|
369
384
|
caching: input.caching ?? "none",
|
|
385
|
+
i18n: input.i18n ?? "none",
|
|
370
386
|
animation: input.animation ?? "none",
|
|
371
387
|
cssFramework: input.cssFramework ?? "tailwind",
|
|
372
388
|
uiLibrary: input.uiLibrary ?? "none",
|
|
@@ -394,11 +410,15 @@ function buildCompatibilityInput(input) {
|
|
|
394
410
|
rustCli: input.rustCli ?? "none",
|
|
395
411
|
rustLibraries: (input.rustLibraries ?? []).join(",") || "none",
|
|
396
412
|
rustLogging: input.rustLogging ?? "none",
|
|
413
|
+
rustErrorHandling: input.rustErrorHandling ?? "none",
|
|
414
|
+
rustCaching: input.rustCaching ?? "none",
|
|
397
415
|
pythonWebFramework: input.pythonWebFramework ?? "none",
|
|
398
416
|
pythonOrm: input.pythonOrm ?? "none",
|
|
399
417
|
pythonValidation: input.pythonValidation ?? "none",
|
|
400
418
|
pythonAi: (input.pythonAi ?? []).join(",") || "none",
|
|
419
|
+
pythonAuth: input.pythonAuth ?? "none",
|
|
401
420
|
pythonTaskQueue: input.pythonTaskQueue ?? "none",
|
|
421
|
+
pythonGraphql: input.pythonGraphql ?? "none",
|
|
402
422
|
pythonQuality: input.pythonQuality ?? "none",
|
|
403
423
|
goWebFramework: input.goWebFramework ?? "none",
|
|
404
424
|
goOrm: input.goOrm ?? "none",
|
|
@@ -584,6 +604,7 @@ async function startMcpServer() {
|
|
|
584
604
|
observability: ObservabilitySchema.optional().describe("Observability"),
|
|
585
605
|
search: SearchSchema.optional().describe("Search engine"),
|
|
586
606
|
caching: CachingSchema.optional().describe("Caching solution"),
|
|
607
|
+
i18n: I18nSchema.optional().describe("Internationalization (i18n) library"),
|
|
587
608
|
cms: CMSSchema.optional().describe("CMS"),
|
|
588
609
|
fileStorage: FileStorageSchema.optional().describe("File storage"),
|
|
589
610
|
fileUpload: FileUploadSchema.optional().describe("File upload"),
|
|
@@ -597,10 +618,13 @@ async function startMcpServer() {
|
|
|
597
618
|
rustCli: RustCliSchema.optional().describe("Rust CLI framework"),
|
|
598
619
|
rustLibraries: z.array(RustLibrariesSchema).optional().describe("Rust libraries"),
|
|
599
620
|
rustLogging: RustLoggingSchema.optional().describe("Rust logging library"),
|
|
621
|
+
rustErrorHandling: RustErrorHandlingSchema.optional().describe("Rust error handling library"),
|
|
622
|
+
rustCaching: RustCachingSchema.optional().describe("Rust caching library"),
|
|
600
623
|
pythonWebFramework: PythonWebFrameworkSchema.optional().describe("Python web framework"),
|
|
601
624
|
pythonOrm: PythonOrmSchema.optional().describe("Python ORM"),
|
|
602
625
|
pythonValidation: PythonValidationSchema.optional().describe("Python validation"),
|
|
603
626
|
pythonAi: z.array(PythonAiSchema).optional().describe("Python AI libraries"),
|
|
627
|
+
pythonAuth: PythonAuthSchema.optional().describe("Python auth library"),
|
|
604
628
|
pythonTaskQueue: PythonTaskQueueSchema.optional().describe("Python task queue"),
|
|
605
629
|
pythonQuality: PythonQualitySchema.optional().describe("Python code quality"),
|
|
606
630
|
goWebFramework: GoWebFrameworkSchema.optional().describe("Go web framework"),
|
|
@@ -676,7 +700,7 @@ async function startMcpServer() {
|
|
|
676
700
|
await writeBtsConfig(config);
|
|
677
701
|
let addonWarnings = [];
|
|
678
702
|
if (config.addons.length > 0 && config.addons[0] !== "none") {
|
|
679
|
-
const { setupAddons } = await import("./addons-setup-
|
|
703
|
+
const { setupAddons } = await import("./addons-setup-By7Kqjss.mjs");
|
|
680
704
|
addonWarnings = await setupAddons(config);
|
|
681
705
|
}
|
|
682
706
|
const installCmd = getInstallCommand(input.ecosystem ?? "typescript", projectName, input.packageManager);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-better-fullstack",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Scaffold production-ready fullstack apps in seconds. Pick your stack from 270+ options — the CLI wires everything together.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -112,8 +112,8 @@
|
|
|
112
112
|
"prepublishOnly": "npm run build"
|
|
113
113
|
},
|
|
114
114
|
"dependencies": {
|
|
115
|
-
"@better-fullstack/template-generator": "^1.
|
|
116
|
-
"@better-fullstack/types": "^1.
|
|
115
|
+
"@better-fullstack/template-generator": "^1.6.0",
|
|
116
|
+
"@better-fullstack/types": "^1.6.0",
|
|
117
117
|
"@clack/core": "^0.5.0",
|
|
118
118
|
"@clack/prompts": "^1.2.0",
|
|
119
119
|
"@orpc/server": "^1.13.13",
|