create-better-fullstack 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-BkBCdTQg.mjs → src-uKym6_H1.mjs} +493 -72
- package/package.json +4 -4
package/dist/cli.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-
|
|
2
|
+
import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-uKym6_H1.mjs";
|
|
3
3
|
|
|
4
4
|
export { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
|
|
@@ -1157,19 +1157,34 @@ async function getApiChoice(Api, frontend, backend, astroIntegration) {
|
|
|
1157
1157
|
if (backend === "convex" || backend === "none") return "none";
|
|
1158
1158
|
const allowed = allowedApisForFrontends(frontend ?? [], astroIntegration);
|
|
1159
1159
|
if (Api) return allowed.includes(Api) ? Api : allowed[0];
|
|
1160
|
-
const
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1160
|
+
const apiOptionMap = {
|
|
1161
|
+
trpc: {
|
|
1162
|
+
value: "trpc",
|
|
1163
|
+
label: "tRPC",
|
|
1164
|
+
hint: "End-to-end typesafe APIs made easy"
|
|
1165
|
+
},
|
|
1166
|
+
orpc: {
|
|
1167
|
+
value: "orpc",
|
|
1168
|
+
label: "oRPC",
|
|
1169
|
+
hint: "End-to-end type-safe APIs that adhere to OpenAPI standards"
|
|
1170
|
+
},
|
|
1171
|
+
"ts-rest": {
|
|
1172
|
+
value: "ts-rest",
|
|
1173
|
+
label: "ts-rest",
|
|
1174
|
+
hint: "RPC-like client, contract, and server implementation for REST APIs"
|
|
1175
|
+
},
|
|
1176
|
+
garph: {
|
|
1177
|
+
value: "garph",
|
|
1178
|
+
label: "Garph",
|
|
1179
|
+
hint: "Fullstack GraphQL framework with end-to-end type safety"
|
|
1180
|
+
},
|
|
1181
|
+
none: {
|
|
1182
|
+
value: "none",
|
|
1183
|
+
label: "None",
|
|
1184
|
+
hint: "No API layer (e.g. for full-stack frameworks like Next.js with Route Handlers)"
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
const apiOptions = allowed.map((a) => apiOptionMap[a]);
|
|
1173
1188
|
const apiType = await navigableSelect({
|
|
1174
1189
|
message: "Select API type",
|
|
1175
1190
|
options: apiOptions,
|
|
@@ -1241,41 +1256,54 @@ async function getAuthChoice(auth, backend, frontend) {
|
|
|
1241
1256
|
"native-uniwind",
|
|
1242
1257
|
"native-unistyles"
|
|
1243
1258
|
].includes(f));
|
|
1244
|
-
const options = [];
|
|
1245
|
-
if (supportedBetterAuthFrontends) options.push({
|
|
1259
|
+
const options$1 = [];
|
|
1260
|
+
if (supportedBetterAuthFrontends) options$1.push({
|
|
1246
1261
|
value: "better-auth",
|
|
1247
1262
|
label: "Better-Auth",
|
|
1248
1263
|
hint: "comprehensive auth framework for TypeScript"
|
|
1249
1264
|
});
|
|
1250
|
-
if (hasClerkCompatibleFrontends) options.push({
|
|
1265
|
+
if (hasClerkCompatibleFrontends) options$1.push({
|
|
1251
1266
|
value: "clerk",
|
|
1252
1267
|
label: "Clerk",
|
|
1253
1268
|
hint: "More than auth, Complete User Management"
|
|
1254
1269
|
});
|
|
1255
|
-
if (options.length === 0) return "none";
|
|
1256
|
-
options.push({
|
|
1270
|
+
if (options$1.length === 0) return "none";
|
|
1271
|
+
options$1.push({
|
|
1257
1272
|
value: "none",
|
|
1258
1273
|
label: "None",
|
|
1259
1274
|
hint: "No auth"
|
|
1260
1275
|
});
|
|
1261
1276
|
const response$1 = await navigableSelect({
|
|
1262
1277
|
message: "Select authentication provider",
|
|
1263
|
-
options,
|
|
1278
|
+
options: options$1,
|
|
1264
1279
|
initialValue: "none"
|
|
1265
1280
|
});
|
|
1266
1281
|
if (isCancel$1(response$1)) return exitCancelled("Operation cancelled");
|
|
1267
1282
|
return response$1;
|
|
1268
1283
|
}
|
|
1284
|
+
const supportsNextAuth = frontend?.includes("next") && backend === "self";
|
|
1285
|
+
const options = [{
|
|
1286
|
+
value: "better-auth",
|
|
1287
|
+
label: "Better-Auth",
|
|
1288
|
+
hint: "comprehensive auth framework for TypeScript"
|
|
1289
|
+
}, {
|
|
1290
|
+
value: "clerk",
|
|
1291
|
+
label: "Clerk",
|
|
1292
|
+
hint: "More than auth, Complete User Management"
|
|
1293
|
+
}];
|
|
1294
|
+
if (supportsNextAuth) options.push({
|
|
1295
|
+
value: "nextauth",
|
|
1296
|
+
label: "Auth.js (NextAuth)",
|
|
1297
|
+
hint: "Authentication for Next.js (formerly NextAuth.js)"
|
|
1298
|
+
});
|
|
1299
|
+
options.push({
|
|
1300
|
+
value: "none",
|
|
1301
|
+
label: "None",
|
|
1302
|
+
hint: "No authentication"
|
|
1303
|
+
});
|
|
1269
1304
|
const response = await navigableSelect({
|
|
1270
1305
|
message: "Select authentication provider",
|
|
1271
|
-
options
|
|
1272
|
-
value: "better-auth",
|
|
1273
|
-
label: "Better-Auth",
|
|
1274
|
-
hint: "comprehensive auth framework for TypeScript"
|
|
1275
|
-
}, {
|
|
1276
|
-
value: "none",
|
|
1277
|
-
label: "None"
|
|
1278
|
-
}],
|
|
1306
|
+
options,
|
|
1279
1307
|
initialValue: DEFAULT_CONFIG.auth
|
|
1280
1308
|
});
|
|
1281
1309
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
@@ -1319,6 +1347,22 @@ async function getBackendFrameworkChoice(backendFramework, frontends) {
|
|
|
1319
1347
|
value: "fets",
|
|
1320
1348
|
label: "feTS",
|
|
1321
1349
|
hint: "TypeScript HTTP Framework with e2e type-safety"
|
|
1350
|
+
}, {
|
|
1351
|
+
value: "nestjs",
|
|
1352
|
+
label: "NestJS",
|
|
1353
|
+
hint: "Progressive Node.js framework for scalable applications"
|
|
1354
|
+
}, {
|
|
1355
|
+
value: "adonisjs",
|
|
1356
|
+
label: "AdonisJS",
|
|
1357
|
+
hint: "Full-featured MVC framework for Node.js"
|
|
1358
|
+
}, {
|
|
1359
|
+
value: "nitro",
|
|
1360
|
+
label: "Nitro",
|
|
1361
|
+
hint: "Universal server framework from UnJS"
|
|
1362
|
+
}, {
|
|
1363
|
+
value: "encore",
|
|
1364
|
+
label: "Encore",
|
|
1365
|
+
hint: "Backend development platform with built-in infrastructure"
|
|
1322
1366
|
});
|
|
1323
1367
|
if (!hasIncompatibleFrontend) backendOptions.push({
|
|
1324
1368
|
value: "convex",
|
|
@@ -1577,6 +1621,27 @@ async function getDBSetupChoice(databaseType, dbSetup, _orm, backend, runtime) {
|
|
|
1577
1621
|
return response;
|
|
1578
1622
|
}
|
|
1579
1623
|
|
|
1624
|
+
//#endregion
|
|
1625
|
+
//#region src/prompts/ecosystem.ts
|
|
1626
|
+
async function getEcosystemChoice(ecosystem) {
|
|
1627
|
+
if (ecosystem !== void 0) return ecosystem;
|
|
1628
|
+
const response = await navigableSelect({
|
|
1629
|
+
message: "Select ecosystem",
|
|
1630
|
+
options: [{
|
|
1631
|
+
value: "typescript",
|
|
1632
|
+
label: "TypeScript",
|
|
1633
|
+
hint: "Full-stack TypeScript with React, Vue, Svelte, and more"
|
|
1634
|
+
}, {
|
|
1635
|
+
value: "rust",
|
|
1636
|
+
label: "Rust",
|
|
1637
|
+
hint: "Rust ecosystem with Axum, Leptos, and more"
|
|
1638
|
+
}],
|
|
1639
|
+
initialValue: "typescript"
|
|
1640
|
+
});
|
|
1641
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
1642
|
+
return response;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1580
1645
|
//#endregion
|
|
1581
1646
|
//#region src/prompts/effect.ts
|
|
1582
1647
|
async function getEffectChoice(effect) {
|
|
@@ -1625,6 +1690,36 @@ async function getEmailChoice(email, backend) {
|
|
|
1625
1690
|
label: "React Email",
|
|
1626
1691
|
hint: "Build emails using React components (no sending service)."
|
|
1627
1692
|
},
|
|
1693
|
+
{
|
|
1694
|
+
value: "nodemailer",
|
|
1695
|
+
label: "Nodemailer",
|
|
1696
|
+
hint: "Classic Node.js email sending library."
|
|
1697
|
+
},
|
|
1698
|
+
{
|
|
1699
|
+
value: "postmark",
|
|
1700
|
+
label: "Postmark",
|
|
1701
|
+
hint: "Transactional email service with high deliverability."
|
|
1702
|
+
},
|
|
1703
|
+
{
|
|
1704
|
+
value: "sendgrid",
|
|
1705
|
+
label: "SendGrid",
|
|
1706
|
+
hint: "Email delivery and marketing platform by Twilio."
|
|
1707
|
+
},
|
|
1708
|
+
{
|
|
1709
|
+
value: "aws-ses",
|
|
1710
|
+
label: "AWS SES",
|
|
1711
|
+
hint: "Amazon Simple Email Service for scalable email."
|
|
1712
|
+
},
|
|
1713
|
+
{
|
|
1714
|
+
value: "mailgun",
|
|
1715
|
+
label: "Mailgun",
|
|
1716
|
+
hint: "Email API service for sending and tracking emails."
|
|
1717
|
+
},
|
|
1718
|
+
{
|
|
1719
|
+
value: "plunk",
|
|
1720
|
+
label: "Plunk",
|
|
1721
|
+
hint: "Open-source email platform for developers."
|
|
1722
|
+
},
|
|
1628
1723
|
{
|
|
1629
1724
|
value: "none",
|
|
1630
1725
|
label: "None",
|
|
@@ -1825,6 +1920,26 @@ async function getFrontendChoice(frontendOptions, backend, auth) {
|
|
|
1825
1920
|
value: "tanstack-start",
|
|
1826
1921
|
label: "TanStack Start",
|
|
1827
1922
|
hint: "SSR, Server Functions, API Routes and more with TanStack Router"
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
value: "qwik",
|
|
1926
|
+
label: "Qwik",
|
|
1927
|
+
hint: "Resumable framework with instant load times"
|
|
1928
|
+
},
|
|
1929
|
+
{
|
|
1930
|
+
value: "angular",
|
|
1931
|
+
label: "Angular",
|
|
1932
|
+
hint: "Enterprise-grade TypeScript framework by Google"
|
|
1933
|
+
},
|
|
1934
|
+
{
|
|
1935
|
+
value: "redwood",
|
|
1936
|
+
label: "RedwoodJS",
|
|
1937
|
+
hint: "Opinionated fullstack (React + GraphQL + Prisma)"
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
value: "fresh",
|
|
1941
|
+
label: "Fresh",
|
|
1942
|
+
hint: "Deno-native framework with islands architecture"
|
|
1828
1943
|
}
|
|
1829
1944
|
].filter((option) => isFrontendAllowedWithBackend(option.value, backend, auth)),
|
|
1830
1945
|
initialValue: DEFAULT_CONFIG.frontend[0]
|
|
@@ -2141,18 +2256,37 @@ async function getPackageManagerChoice(packageManager) {
|
|
|
2141
2256
|
async function getPaymentsChoice(payments, auth, backend, frontends) {
|
|
2142
2257
|
if (payments !== void 0) return payments;
|
|
2143
2258
|
if (backend === "none") return "none";
|
|
2144
|
-
|
|
2259
|
+
const isPolarCompatible = auth === "better-auth" && backend !== "convex" && (frontends?.length === 0 || splitFrontends(frontends).web.length > 0);
|
|
2260
|
+
const options = [];
|
|
2261
|
+
if (isPolarCompatible) options.push({
|
|
2262
|
+
value: "polar",
|
|
2263
|
+
label: "Polar",
|
|
2264
|
+
hint: "Turn your software into a business. 6 lines of code."
|
|
2265
|
+
});
|
|
2266
|
+
options.push({
|
|
2267
|
+
value: "stripe",
|
|
2268
|
+
label: "Stripe",
|
|
2269
|
+
hint: "Payment processing platform for internet businesses."
|
|
2270
|
+
}, {
|
|
2271
|
+
value: "lemon-squeezy",
|
|
2272
|
+
label: "Lemon Squeezy",
|
|
2273
|
+
hint: "All-in-one platform for SaaS, digital products, and subscriptions."
|
|
2274
|
+
}, {
|
|
2275
|
+
value: "paddle",
|
|
2276
|
+
label: "Paddle",
|
|
2277
|
+
hint: "Complete payments infrastructure for SaaS."
|
|
2278
|
+
}, {
|
|
2279
|
+
value: "dodo",
|
|
2280
|
+
label: "Dodo Payments",
|
|
2281
|
+
hint: "Simple payment infrastructure for developers."
|
|
2282
|
+
}, {
|
|
2283
|
+
value: "none",
|
|
2284
|
+
label: "None",
|
|
2285
|
+
hint: "No payments integration"
|
|
2286
|
+
});
|
|
2145
2287
|
const response = await navigableSelect({
|
|
2146
2288
|
message: "Select payments provider",
|
|
2147
|
-
options
|
|
2148
|
-
value: "polar",
|
|
2149
|
-
label: "Polar",
|
|
2150
|
-
hint: "Turn your software into a business. 6 lines of code."
|
|
2151
|
-
}, {
|
|
2152
|
-
value: "none",
|
|
2153
|
-
label: "None",
|
|
2154
|
-
hint: "No payments integration"
|
|
2155
|
-
}],
|
|
2289
|
+
options,
|
|
2156
2290
|
initialValue: DEFAULT_CONFIG.payments
|
|
2157
2291
|
});
|
|
2158
2292
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
@@ -2237,6 +2371,181 @@ async function getRuntimeChoice(runtime, backend) {
|
|
|
2237
2371
|
return response;
|
|
2238
2372
|
}
|
|
2239
2373
|
|
|
2374
|
+
//#endregion
|
|
2375
|
+
//#region src/prompts/rust-ecosystem.ts
|
|
2376
|
+
async function getRustWebFrameworkChoice(rustWebFramework) {
|
|
2377
|
+
if (rustWebFramework !== void 0) return rustWebFramework;
|
|
2378
|
+
const response = await navigableSelect({
|
|
2379
|
+
message: "Select Rust web framework",
|
|
2380
|
+
options: [
|
|
2381
|
+
{
|
|
2382
|
+
value: "axum",
|
|
2383
|
+
label: "Axum",
|
|
2384
|
+
hint: "Ergonomic and modular web framework from Tokio"
|
|
2385
|
+
},
|
|
2386
|
+
{
|
|
2387
|
+
value: "actix-web",
|
|
2388
|
+
label: "Actix Web",
|
|
2389
|
+
hint: "Powerful, pragmatic, and extremely fast web framework"
|
|
2390
|
+
},
|
|
2391
|
+
{
|
|
2392
|
+
value: "none",
|
|
2393
|
+
label: "None",
|
|
2394
|
+
hint: "No web framework"
|
|
2395
|
+
}
|
|
2396
|
+
],
|
|
2397
|
+
initialValue: "axum"
|
|
2398
|
+
});
|
|
2399
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2400
|
+
return response;
|
|
2401
|
+
}
|
|
2402
|
+
async function getRustFrontendChoice(rustFrontend) {
|
|
2403
|
+
if (rustFrontend !== void 0) return rustFrontend;
|
|
2404
|
+
const response = await navigableSelect({
|
|
2405
|
+
message: "Select Rust frontend framework",
|
|
2406
|
+
options: [
|
|
2407
|
+
{
|
|
2408
|
+
value: "leptos",
|
|
2409
|
+
label: "Leptos",
|
|
2410
|
+
hint: "Build fast web applications with Rust"
|
|
2411
|
+
},
|
|
2412
|
+
{
|
|
2413
|
+
value: "dioxus",
|
|
2414
|
+
label: "Dioxus",
|
|
2415
|
+
hint: "Fullstack, cross-platform UI library for Rust"
|
|
2416
|
+
},
|
|
2417
|
+
{
|
|
2418
|
+
value: "none",
|
|
2419
|
+
label: "None",
|
|
2420
|
+
hint: "No Rust frontend (API only)"
|
|
2421
|
+
}
|
|
2422
|
+
],
|
|
2423
|
+
initialValue: "none"
|
|
2424
|
+
});
|
|
2425
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2426
|
+
return response;
|
|
2427
|
+
}
|
|
2428
|
+
async function getRustOrmChoice(rustOrm) {
|
|
2429
|
+
if (rustOrm !== void 0) return rustOrm;
|
|
2430
|
+
const response = await navigableSelect({
|
|
2431
|
+
message: "Select Rust ORM/database layer",
|
|
2432
|
+
options: [
|
|
2433
|
+
{
|
|
2434
|
+
value: "sea-orm",
|
|
2435
|
+
label: "SeaORM",
|
|
2436
|
+
hint: "Async & dynamic ORM for Rust"
|
|
2437
|
+
},
|
|
2438
|
+
{
|
|
2439
|
+
value: "sqlx",
|
|
2440
|
+
label: "SQLx",
|
|
2441
|
+
hint: "Async SQL toolkit with compile-time checked queries"
|
|
2442
|
+
},
|
|
2443
|
+
{
|
|
2444
|
+
value: "none",
|
|
2445
|
+
label: "None",
|
|
2446
|
+
hint: "No database layer"
|
|
2447
|
+
}
|
|
2448
|
+
],
|
|
2449
|
+
initialValue: "none"
|
|
2450
|
+
});
|
|
2451
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2452
|
+
return response;
|
|
2453
|
+
}
|
|
2454
|
+
async function getRustApiChoice(rustApi) {
|
|
2455
|
+
if (rustApi !== void 0) return rustApi;
|
|
2456
|
+
const response = await navigableSelect({
|
|
2457
|
+
message: "Select Rust API layer",
|
|
2458
|
+
options: [
|
|
2459
|
+
{
|
|
2460
|
+
value: "tonic",
|
|
2461
|
+
label: "Tonic",
|
|
2462
|
+
hint: "gRPC implementation for Rust"
|
|
2463
|
+
},
|
|
2464
|
+
{
|
|
2465
|
+
value: "async-graphql",
|
|
2466
|
+
label: "async-graphql",
|
|
2467
|
+
hint: "High-performance GraphQL server library"
|
|
2468
|
+
},
|
|
2469
|
+
{
|
|
2470
|
+
value: "none",
|
|
2471
|
+
label: "None",
|
|
2472
|
+
hint: "REST API only"
|
|
2473
|
+
}
|
|
2474
|
+
],
|
|
2475
|
+
initialValue: "none"
|
|
2476
|
+
});
|
|
2477
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2478
|
+
return response;
|
|
2479
|
+
}
|
|
2480
|
+
async function getRustCliChoice(rustCli) {
|
|
2481
|
+
if (rustCli !== void 0) return rustCli;
|
|
2482
|
+
const response = await navigableSelect({
|
|
2483
|
+
message: "Select Rust CLI tools",
|
|
2484
|
+
options: [
|
|
2485
|
+
{
|
|
2486
|
+
value: "clap",
|
|
2487
|
+
label: "Clap",
|
|
2488
|
+
hint: "Command Line Argument Parser for Rust"
|
|
2489
|
+
},
|
|
2490
|
+
{
|
|
2491
|
+
value: "ratatui",
|
|
2492
|
+
label: "Ratatui",
|
|
2493
|
+
hint: "Build rich terminal user interfaces"
|
|
2494
|
+
},
|
|
2495
|
+
{
|
|
2496
|
+
value: "none",
|
|
2497
|
+
label: "None",
|
|
2498
|
+
hint: "No CLI tools"
|
|
2499
|
+
}
|
|
2500
|
+
],
|
|
2501
|
+
initialValue: "none"
|
|
2502
|
+
});
|
|
2503
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2504
|
+
return response;
|
|
2505
|
+
}
|
|
2506
|
+
async function getRustLibrariesChoice(rustLibraries) {
|
|
2507
|
+
if (rustLibraries !== void 0) return rustLibraries;
|
|
2508
|
+
const response = await navigableMultiselect({
|
|
2509
|
+
message: "Select Rust libraries",
|
|
2510
|
+
options: [
|
|
2511
|
+
{
|
|
2512
|
+
value: "serde",
|
|
2513
|
+
label: "Serde",
|
|
2514
|
+
hint: "Serialization framework for Rust"
|
|
2515
|
+
},
|
|
2516
|
+
{
|
|
2517
|
+
value: "validator",
|
|
2518
|
+
label: "Validator",
|
|
2519
|
+
hint: "Struct validation derive macros"
|
|
2520
|
+
},
|
|
2521
|
+
{
|
|
2522
|
+
value: "jsonwebtoken",
|
|
2523
|
+
label: "jsonwebtoken",
|
|
2524
|
+
hint: "JWT encoding/decoding library"
|
|
2525
|
+
},
|
|
2526
|
+
{
|
|
2527
|
+
value: "argon2",
|
|
2528
|
+
label: "Argon2",
|
|
2529
|
+
hint: "Password hashing library"
|
|
2530
|
+
},
|
|
2531
|
+
{
|
|
2532
|
+
value: "tokio-test",
|
|
2533
|
+
label: "Tokio Test",
|
|
2534
|
+
hint: "Testing utilities for Tokio"
|
|
2535
|
+
},
|
|
2536
|
+
{
|
|
2537
|
+
value: "mockall",
|
|
2538
|
+
label: "Mockall",
|
|
2539
|
+
hint: "Powerful mocking library for Rust"
|
|
2540
|
+
}
|
|
2541
|
+
],
|
|
2542
|
+
required: false,
|
|
2543
|
+
initialValues: ["serde"]
|
|
2544
|
+
});
|
|
2545
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
2546
|
+
return response;
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2240
2549
|
//#endregion
|
|
2241
2550
|
//#region src/prompts/server-deploy.ts
|
|
2242
2551
|
async function getServerDeploymentChoice(deployment, runtime, backend, _webDeploy) {
|
|
@@ -2520,46 +2829,158 @@ async function getDeploymentChoice(deployment, _runtime, _backend, frontend = []
|
|
|
2520
2829
|
//#region src/prompts/config-prompts.ts
|
|
2521
2830
|
async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
2522
2831
|
const result = await navigableGroup({
|
|
2523
|
-
|
|
2832
|
+
ecosystem: () => getEcosystemChoice(flags.ecosystem),
|
|
2833
|
+
frontend: ({ results }) => {
|
|
2834
|
+
if (results.ecosystem === "rust") return Promise.resolve([]);
|
|
2835
|
+
return getFrontendChoice(flags.frontend, flags.backend, flags.auth);
|
|
2836
|
+
},
|
|
2524
2837
|
astroIntegration: ({ results }) => {
|
|
2838
|
+
if (results.ecosystem === "rust") return Promise.resolve(void 0);
|
|
2525
2839
|
if (results.frontend?.includes("astro")) return getAstroIntegrationChoice(flags.astroIntegration);
|
|
2526
2840
|
return Promise.resolve(void 0);
|
|
2527
2841
|
},
|
|
2528
2842
|
uiLibrary: ({ results }) => {
|
|
2843
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2529
2844
|
if (hasWebStyling(results.frontend)) return getUILibraryChoice(flags.uiLibrary, results.frontend);
|
|
2530
2845
|
return Promise.resolve("none");
|
|
2531
2846
|
},
|
|
2532
2847
|
cssFramework: ({ results }) => {
|
|
2848
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2533
2849
|
if (hasWebStyling(results.frontend)) return getCSSFrameworkChoice(flags.cssFramework, results.uiLibrary);
|
|
2534
2850
|
return Promise.resolve("none");
|
|
2535
2851
|
},
|
|
2536
|
-
backend: ({ results }) =>
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2852
|
+
backend: ({ results }) => {
|
|
2853
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2854
|
+
return getBackendFrameworkChoice(flags.backend, results.frontend);
|
|
2855
|
+
},
|
|
2856
|
+
runtime: ({ results }) => {
|
|
2857
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2858
|
+
return getRuntimeChoice(flags.runtime, results.backend);
|
|
2859
|
+
},
|
|
2860
|
+
database: ({ results }) => {
|
|
2861
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2862
|
+
return getDatabaseChoice(flags.database, results.backend, results.runtime);
|
|
2863
|
+
},
|
|
2864
|
+
orm: ({ results }) => {
|
|
2865
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2866
|
+
return getORMChoice(flags.orm, results.database !== "none", results.database, results.backend, results.runtime);
|
|
2867
|
+
},
|
|
2868
|
+
api: ({ results }) => {
|
|
2869
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2870
|
+
return getApiChoice(flags.api, results.frontend, results.backend, results.astroIntegration);
|
|
2871
|
+
},
|
|
2872
|
+
auth: ({ results }) => {
|
|
2873
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2874
|
+
return getAuthChoice(flags.auth, results.backend, results.frontend);
|
|
2875
|
+
},
|
|
2876
|
+
payments: ({ results }) => {
|
|
2877
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2878
|
+
return getPaymentsChoice(flags.payments, results.auth, results.backend, results.frontend);
|
|
2879
|
+
},
|
|
2880
|
+
email: ({ results }) => {
|
|
2881
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2882
|
+
return getEmailChoice(flags.email, results.backend);
|
|
2883
|
+
},
|
|
2884
|
+
effect: ({ results }) => {
|
|
2885
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2886
|
+
return getEffectChoice(flags.effect);
|
|
2887
|
+
},
|
|
2888
|
+
addons: ({ results }) => {
|
|
2889
|
+
if (results.ecosystem === "rust") return Promise.resolve([]);
|
|
2890
|
+
return getAddonsChoice(flags.addons, results.frontend, results.auth);
|
|
2891
|
+
},
|
|
2892
|
+
examples: ({ results }) => {
|
|
2893
|
+
if (results.ecosystem === "rust") return Promise.resolve([]);
|
|
2894
|
+
return getExamplesChoice(flags.examples, results.database, results.frontend, results.backend, results.api);
|
|
2895
|
+
},
|
|
2896
|
+
dbSetup: ({ results }) => {
|
|
2897
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2898
|
+
return getDBSetupChoice(results.database ?? "none", flags.dbSetup, results.orm, results.backend, results.runtime);
|
|
2899
|
+
},
|
|
2900
|
+
webDeploy: ({ results }) => {
|
|
2901
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2902
|
+
return getDeploymentChoice(flags.webDeploy, results.runtime, results.backend, results.frontend);
|
|
2903
|
+
},
|
|
2904
|
+
serverDeploy: ({ results }) => {
|
|
2905
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2906
|
+
return getServerDeploymentChoice(flags.serverDeploy, results.runtime, results.backend, results.webDeploy);
|
|
2907
|
+
},
|
|
2908
|
+
ai: ({ results }) => {
|
|
2909
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2910
|
+
return getAIChoice(flags.ai);
|
|
2911
|
+
},
|
|
2912
|
+
validation: ({ results }) => {
|
|
2913
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2914
|
+
return getValidationChoice(flags.validation);
|
|
2915
|
+
},
|
|
2916
|
+
forms: ({ results }) => {
|
|
2917
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2918
|
+
return getFormsChoice(flags.forms, results.frontend);
|
|
2919
|
+
},
|
|
2920
|
+
stateManagement: ({ results }) => {
|
|
2921
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2922
|
+
return getStateManagementChoice(flags.stateManagement, results.frontend);
|
|
2923
|
+
},
|
|
2924
|
+
animation: ({ results }) => {
|
|
2925
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2926
|
+
return getAnimationChoice(flags.animation, results.frontend);
|
|
2927
|
+
},
|
|
2928
|
+
testing: ({ results }) => {
|
|
2929
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2930
|
+
return getTestingChoice(flags.testing);
|
|
2931
|
+
},
|
|
2932
|
+
realtime: ({ results }) => {
|
|
2933
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2934
|
+
return getRealtimeChoice(flags.realtime, results.backend);
|
|
2935
|
+
},
|
|
2936
|
+
jobQueue: ({ results }) => {
|
|
2937
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2938
|
+
return getJobQueueChoice(flags.jobQueue, results.backend);
|
|
2939
|
+
},
|
|
2940
|
+
fileUpload: ({ results }) => {
|
|
2941
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2942
|
+
return getFileUploadChoice(flags.fileUpload, results.backend);
|
|
2943
|
+
},
|
|
2944
|
+
logging: ({ results }) => {
|
|
2945
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2946
|
+
return getLoggingChoice(flags.logging, results.backend);
|
|
2947
|
+
},
|
|
2948
|
+
observability: ({ results }) => {
|
|
2949
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2950
|
+
return getObservabilityChoice(flags.observability, results.backend);
|
|
2951
|
+
},
|
|
2952
|
+
cms: ({ results }) => {
|
|
2953
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2954
|
+
return getCMSChoice(flags.cms, results.backend);
|
|
2955
|
+
},
|
|
2956
|
+
caching: ({ results }) => {
|
|
2957
|
+
if (results.ecosystem === "rust") return Promise.resolve("none");
|
|
2958
|
+
return getCachingChoice(flags.caching, results.backend);
|
|
2959
|
+
},
|
|
2960
|
+
rustWebFramework: ({ results }) => {
|
|
2961
|
+
if (results.ecosystem === "typescript") return Promise.resolve("none");
|
|
2962
|
+
return getRustWebFrameworkChoice(flags.rustWebFramework);
|
|
2963
|
+
},
|
|
2964
|
+
rustFrontend: ({ results }) => {
|
|
2965
|
+
if (results.ecosystem === "typescript") return Promise.resolve("none");
|
|
2966
|
+
return getRustFrontendChoice(flags.rustFrontend);
|
|
2967
|
+
},
|
|
2968
|
+
rustOrm: ({ results }) => {
|
|
2969
|
+
if (results.ecosystem === "typescript") return Promise.resolve("none");
|
|
2970
|
+
return getRustOrmChoice(flags.rustOrm);
|
|
2971
|
+
},
|
|
2972
|
+
rustApi: ({ results }) => {
|
|
2973
|
+
if (results.ecosystem === "typescript") return Promise.resolve("none");
|
|
2974
|
+
return getRustApiChoice(flags.rustApi);
|
|
2975
|
+
},
|
|
2976
|
+
rustCli: ({ results }) => {
|
|
2977
|
+
if (results.ecosystem === "typescript") return Promise.resolve("none");
|
|
2978
|
+
return getRustCliChoice(flags.rustCli);
|
|
2979
|
+
},
|
|
2980
|
+
rustLibraries: ({ results }) => {
|
|
2981
|
+
if (results.ecosystem === "typescript") return Promise.resolve([]);
|
|
2982
|
+
return getRustLibrariesChoice(flags.rustLibraries);
|
|
2983
|
+
},
|
|
2563
2984
|
git: () => getGitChoice(flags.git),
|
|
2564
2985
|
packageManager: () => getPackageManagerChoice(flags.packageManager),
|
|
2565
2986
|
install: () => getinstallChoice(flags.install)
|
|
@@ -2602,13 +3023,13 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
2602
3023
|
observability: result.observability,
|
|
2603
3024
|
cms: result.cms,
|
|
2604
3025
|
caching: result.caching,
|
|
2605
|
-
ecosystem:
|
|
2606
|
-
rustWebFramework:
|
|
2607
|
-
rustFrontend:
|
|
2608
|
-
rustOrm:
|
|
2609
|
-
rustApi:
|
|
2610
|
-
rustCli:
|
|
2611
|
-
rustLibraries:
|
|
3026
|
+
ecosystem: result.ecosystem,
|
|
3027
|
+
rustWebFramework: result.rustWebFramework,
|
|
3028
|
+
rustFrontend: result.rustFrontend,
|
|
3029
|
+
rustOrm: result.rustOrm,
|
|
3030
|
+
rustApi: result.rustApi,
|
|
3031
|
+
rustCli: result.rustCli,
|
|
3032
|
+
rustLibraries: result.rustLibraries
|
|
2612
3033
|
};
|
|
2613
3034
|
}
|
|
2614
3035
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-better-fullstack",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "A CLI-first toolkit for building Full Stack applications. Skip the configuration. Ship the code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"better-auth",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "tsdown --publint",
|
|
64
64
|
"dev": "tsdown --watch",
|
|
65
|
-
"lint": "oxlint . && tsc --noEmit",
|
|
65
|
+
"lint": "oxlint . && tsc --noEmit && bun test test/cli-builder-sync.test.ts",
|
|
66
66
|
"check-types": "tsc --noEmit",
|
|
67
67
|
"test": "bun run build && bun test",
|
|
68
68
|
"test:watch": "bun run build && bun test --watch",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"prepublishOnly": "npm run build"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@better-fullstack/template-generator": "^1.1.
|
|
76
|
-
"@better-fullstack/types": "^1.1.
|
|
75
|
+
"@better-fullstack/template-generator": "^1.1.1",
|
|
76
|
+
"@better-fullstack/types": "^1.1.1",
|
|
77
77
|
"@clack/core": "^0.5.0",
|
|
78
78
|
"@clack/prompts": "^1.0.0-alpha.8",
|
|
79
79
|
"@orpc/server": "^1.13.0",
|