diff --git a/apps/cli/CHANGELOG.md b/apps/cli/CHANGELOG.md deleted file mode 100644 index 87157ab..0000000 --- a/apps/cli/CHANGELOG.md +++ /dev/null @@ -1,1675 +0,0 @@ -# Change Log - -## 2.33.9 - -### Patch Changes - -- b2d33a8: fix ultracite integrations flag - -## 2.33.8 - -### Patch Changes - -- 4790cb8: optimize oRPC client dependencies by removing server dependency - -## 2.33.7 - -### Patch Changes - -- 699efa4: nothing here - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.33.6](https://github.com/AmanVarshney01/create-better-t-stack/compare/v2.33.5...v2.33.6) (2025-08-15) - -### Bug Fixes - -- remove forced none webdeploy when convex ([ac1067a](https://github.com/AmanVarshney01/create-better-t-stack/commit/ac1067ab231fa452bd85bf8ce51bb2edc7746199)) - -## 2.33.5 (2025-08-15) - -### Bug Fixes - -- backend none templates ([#241](https://github.com/AmanVarshney01/create-better-t-stack/issues/241)) ([8209713](https://github.com/AmanVarshney01/create-better-t-stack/commit/8209713bd644a812cfd2f9fa81adc5da97ab13cc)) -- **cli:** add --no-git option to fumadocs setup command ([7d76289](https://github.com/AmanVarshney01/create-better-t-stack/commit/7d76289db791aef7c6d31a1f9f598dddc0db7490)) -- **cli:** add @types/node when workers runtime ([a0c6acb](https://github.com/AmanVarshney01/create-better-t-stack/commit/a0c6acbc608ab3613db5a6e7dafb7cabd22365bf)) -- **cli:** Add conditional rendering for private data based on API type ([5ab503a](https://github.com/AmanVarshney01/create-better-t-stack/commit/5ab503a814019828ba6d1ebd0c9817177e4fbfa9)) -- **cli:** add missing wrangler.jsonc file ignore to biome.json.hbs ([#492](https://github.com/AmanVarshney01/create-better-t-stack/issues/492)) ([5b2827e](https://github.com/AmanVarshney01/create-better-t-stack/commit/5b2827ef123bb9dbd45135a19d3e1dc91406823a)) -- **cli:** add react deps in next backend ([a4209b7](https://github.com/AmanVarshney01/create-better-t-stack/commit/a4209b7a5352d57be9ff55a73ec5bc04dfd25f5c)) -- **cli:** comment isolated linker in bunfig.toml when native-nativewind ([ad1d28f](https://github.com/AmanVarshney01/create-better-t-stack/commit/ad1d28ff287262b378d5bbeb81f8cba90489ce37)) -- **cli:** fix nuxt template issues with bun ([53985fe](https://github.com/AmanVarshney01/create-better-t-stack/commit/53985feabb66cf9b0acd240f8a55d74849e102da)) -- **cli:** fix telemetry ([901e1ff](https://github.com/AmanVarshney01/create-better-t-stack/commit/901e1fffd91490689126eb0112b9930c382f9f61)) -- **cli:** remove telemetry console logs ([71e5850](https://github.com/AmanVarshney01/create-better-t-stack/commit/71e585040265cc9e0c0bf5842a023e580ad95b1f)) -- **cli:** remove unwanted orm directories ([78fe4b7](https://github.com/AmanVarshney01/create-better-t-stack/commit/78fe4b76b7a926eb6b6b0350755312d96fe60583)) -- **cli:** ruler template path ([a231a81](https://github.com/AmanVarshney01/create-better-t-stack/commit/a231a8183903d93f8f41b3e1484601d0ee4cc385)) -- **cli:** start script paths in Bun and Node runtime setup ([b47671c](https://github.com/AmanVarshney01/create-better-t-stack/commit/b47671c24d8cae51de12b5334c519238dde62d77)) -- **cli:** Update Nuxt template dependencies and add TailwindCSS ([17389ac](https://github.com/AmanVarshney01/create-better-t-stack/commit/17389ac381a6c76baa668920e3883e0a77c1b5f1)) -- dependency installation output flow ([f73c7d2](https://github.com/AmanVarshney01/create-better-t-stack/commit/f73c7d2064505db93b9e0cd86bc2b0a5633e9e90)) -- enforce Convex backend when --api none is specified ([920a8f0](https://github.com/AmanVarshney01/create-better-t-stack/commit/920a8f01ca03cd72a04f17d6807a80ea99989266)) -- ensure .npmrc is included and copied for native setup ([ea79154](https://github.com/AmanVarshney01/create-better-t-stack/commit/ea79154ae9cf3aa845a06fedb00d22b457432027)) -- **post-installation:** use selected package manager ([#342](https://github.com/AmanVarshney01/create-better-t-stack/issues/342)) ([3fbd751](https://github.com/AmanVarshney01/create-better-t-stack/commit/3fbd751ceb2bc0e09a3164c9416409505517da80)) -- remove unneeded todo schema at auth.ts from drizzle-sqlite template ([#114](https://github.com/AmanVarshney01/create-better-t-stack/issues/114)) ([6b2cde8](https://github.com/AmanVarshney01/create-better-t-stack/commit/6b2cde803017202624cb0971e0e9ec9f97d8aca0)) -- show proper error messages on auth failure in Next.js frontend ([#445](https://github.com/AmanVarshney01/create-better-t-stack/issues/445)) ([2ad89b7](https://github.com/AmanVarshney01/create-better-t-stack/commit/2ad89b72b5798219dd53e79eacc7a9dc92a5e41b)) -- **templates:** password must be at least 8 characters ([#190](https://github.com/AmanVarshney01/create-better-t-stack/issues/190)) ([f1ce6b4](https://github.com/AmanVarshney01/create-better-t-stack/commit/f1ce6b4c09cf7dd272257f91d3eb3c555888befb)) -- **todos:** trpc v11 ([#93](https://github.com/AmanVarshney01/create-better-t-stack/issues/93)) ([a69ff19](https://github.com/AmanVarshney01/create-better-t-stack/commit/a69ff19a7eac3b077368879d681cdd36268febcc)) -- use npx degit for template cloning ([78340fc](https://github.com/AmanVarshney01/create-better-t-stack/commit/78340fca07c18ceefe9cac5bf6aa5bb293741248)) -- web-deploy validation to check for frontend flag ([5fec00a](https://github.com/AmanVarshney01/create-better-t-stack/commit/5fec00a48f31501b9c7bea0e6ad205c6eaa83c31)) -- **web:** miscellaneous improvements ([#416](https://github.com/AmanVarshney01/create-better-t-stack/issues/416)) ([2543c53](https://github.com/AmanVarshney01/create-better-t-stack/commit/2543c5317b21c8e18082e1e7225d3df77c00cc83)) - -### Features - -- add @better-t-stack/types package ([19b625c](https://github.com/AmanVarshney01/create-better-t-stack/commit/19b625c5c71914f6c46f681ed51d8fefaefcf191)) -- add ai chat example and update flags structure ([a6ac5dc](https://github.com/AmanVarshney01/create-better-t-stack/commit/a6ac5dc86c758435a42490912719715f97f888ad)) -- add authentication in native ([81dc240](https://github.com/AmanVarshney01/create-better-t-stack/commit/81dc240e7bc5febbf13f8073f6f06bbc81be4cdc)) -- add command ([#337](https://github.com/AmanVarshney01/create-better-t-stack/issues/337)) ([9c7a0f0](https://github.com/AmanVarshney01/create-better-t-stack/commit/9c7a0f0110ab811b11112e5be8de765fb60d4162)) -- add Ctrl+C interrupt handling ([cc8850d](https://github.com/AmanVarshney01/create-better-t-stack/commit/cc8850d7c2340d1decabe3bd4d3d98ec2e14509d)) -- add mysql database ([c9b7e25](https://github.com/AmanVarshney01/create-better-t-stack/commit/c9b7e25e1d6f572b5abc72229e21a53a17163461)) -- add package manager selection and configuration ([4659db9](https://github.com/AmanVarshney01/create-better-t-stack/commit/4659db93f8adbdc3976b5929e1f039d393c115c4)) -- add project name validation ([ecd7db9](https://github.com/AmanVarshney01/create-better-t-stack/commit/ecd7db9e488f27ae5f9e5ae5894b00f9ca50764f)) -- Auto-generate .env.example files with empty values ([1cc9d81](https://github.com/AmanVarshney01/create-better-t-stack/commit/1cc9d819449ca83bacd375167bf729738ae512a2)) -- **cli:** add disable analytics option ([#496](https://github.com/AmanVarshney01/create-better-t-stack/issues/496)) ([3c00c54](https://github.com/AmanVarshney01/create-better-t-stack/commit/3c00c5453f16ed37f5031fe1ef6355092160a4d5)) -- **cli:** add nuxt + convex support ([#458](https://github.com/AmanVarshney01/create-better-t-stack/issues/458)) ([430fa41](https://github.com/AmanVarshney01/create-better-t-stack/commit/430fa41abdbd307cf5f7c407280def7a943a9792)) -- **cli:** add prisma create-db setup ([#419](https://github.com/AmanVarshney01/create-better-t-stack/issues/419)) ([0c26578](https://github.com/AmanVarshney01/create-better-t-stack/commit/0c26578e8e9a10cc8e6224c3d1a79ad4c3d1eb30)) -- **cli:** add programmatic api ([#494](https://github.com/AmanVarshney01/create-better-t-stack/issues/494)) ([aecde5a](https://github.com/AmanVarshney01/create-better-t-stack/commit/aecde5a54ec545fe4c7f67716298b128c610eb5f)) -- **cli:** add reproducible command output and flag support ([b56096f](https://github.com/AmanVarshney01/create-better-t-stack/commit/b56096f36a71f53b43ca86b8c592736132540fa5)) -- **cli:** add ultracite, oxlint, fumadocs addons ([#427](https://github.com/AmanVarshney01/create-better-t-stack/issues/427)) ([216c242](https://github.com/AmanVarshney01/create-better-t-stack/commit/216c242f7d78f394b1b24a23825823e18d0cc341)) -- **cli:** add vibe rules addon ([#481](https://github.com/AmanVarshney01/create-better-t-stack/issues/481)) ([6cf476a](https://github.com/AmanVarshney01/create-better-t-stack/commit/6cf476a21e6cd6b3ae424bfc1b5b0c5f72268681)) -- **cli:** allow disable telemetry ([65c29c2](https://github.com/AmanVarshney01/create-better-t-stack/commit/65c29c26c52b575f6ddeb8d94162f499ef5d03d5)) -- **cli:** display pre-selected flags before prompts ([0983fc1](https://github.com/AmanVarshney01/create-better-t-stack/commit/0983fc1746cea5553d3587e9af5750abca8dda48)) -- **cli:** migrate vibe-rules to ruler ([#503](https://github.com/AmanVarshney01/create-better-t-stack/issues/503)) ([94dcd82](https://github.com/AmanVarshney01/create-better-t-stack/commit/94dcd82afd079a5290c37ebc6305e64223d5ecdc)) -- **cli:** upgrade to ai sdk v5 ([#487](https://github.com/AmanVarshney01/create-better-t-stack/issues/487)) ([f412d8f](https://github.com/AmanVarshney01/create-better-t-stack/commit/f412d8f0c70b7416c27a69fcbd97c046fdff6a4e)) -- **cli:** Upgrade to Prisma 6.13.0 ([#431](https://github.com/AmanVarshney01/create-better-t-stack/issues/431)) ([16c4d42](https://github.com/AmanVarshney01/create-better-t-stack/commit/16c4d423dd20c9a7e86ecd94ffeb003c5e152aaf)) -- **env-setup:** use a local file as default in sqlite ([#124](https://github.com/AmanVarshney01/create-better-t-stack/issues/124)) ([33a43fc](https://github.com/AmanVarshney01/create-better-t-stack/commit/33a43fcf1400d39d512751ddc6a7a9084b788f92)) -- **web:** add llms.txt ([1f36e9e](https://github.com/AmanVarshney01/create-better-t-stack/commit/1f36e9effcfb09f846703fe83ff886b1d056e844)) -- **web:** improve docs and refactor cli ([#476](https://github.com/AmanVarshney01/create-better-t-stack/issues/476)) ([51cfb35](https://github.com/AmanVarshney01/create-better-t-stack/commit/51cfb359123b1269be08147be96661d73e47d844)) -- **web:** improve sponsors section, add special sponsor highlighting, update README, add X icon ([#426](https://github.com/AmanVarshney01/create-better-t-stack/issues/426)) ([16518cc](https://github.com/AmanVarshney01/create-better-t-stack/commit/16518cc44975068e407721be55d342de095b4e8d)) - -# v2.33.5 (Fri Aug 15 2025) - -#### 🐛 Bug Fix - -- chore: change ruler hint [#509](https://github.com/AmanVarshney01/create-better-t-stack/pull/509) ([@AmanVarshney01](https://github.com/AmanVarshney01)) -- chore: migrate to auto for versioning [#509](https://github.com/AmanVarshney01/create-better-t-stack/pull/509) ([@AmanVarshney01](https://github.com/AmanVarshney01)) - -#### ⚠️ Pushed to `main` - -- chore(cli): add vitest ui for tests ([@AmanVarshney01](https://github.com/AmanVarshney01)) - -#### Authors: 1 - -- Aman Varshney ([@AmanVarshney01](https://github.com/AmanVarshney01)) - ---- - -# create-better-t-stack - -## 2.33.4 - -### Patch Changes - -- ffe59ac: remove manual ultracite package handling - -## 2.33.3 - -### Patch Changes - -- 1aca452: update biome to v2.2.0 - -## 2.33.2 - -### Patch Changes - -- a231a81: fix ruler template path - -## 2.33.1 - -### Patch Changes - -- 0da814a: rename vibe-rules to ruler - -## 2.33.0 - -### Minor Changes - -- 94dcd82: migrate vibe-rules to ruler - -## 2.32.2 - -### Patch Changes - -- 78fe4b7: fix unwanted orm directories (sorry it was pretty bad) - -## 2.32.1 - -### Patch Changes - -- 3c00c54: add disable analytics option - -## 2.32.0 - -### Minor Changes - -- aecde5a: Add programmatic API - -### Patch Changes - -- 5b2827e: Extend biome.json.hbs, add missing wrangler.jsonc file ignore - -## 2.31.0 - -### Minor Changes - -- f412d8f: Upgrade to AI SDK v5 - -## 2.30.0 - -### Minor Changes - -- 6cf476a: add vibe-rules addon with a better t stack rules file - -## 2.29.4 - -### Patch Changes - -- 7d76289: add --no-git option to fumadocs setup command - -## 2.29.3 - -### Patch Changes - -- a0c6acb: add @types/node in server when workers runtime - -## 2.29.2 - -### Patch Changes - -- a188d51: Switched analytics to use fetch instead of posthog-node - -## 2.29.1 - -### Patch Changes - -- b06fa74: update dependencies -- ad1d28f: Comment isolated linker in bunfig.toml when native-nativewind is selected - -## 2.29.0 - -### Minor Changes - -- 430fa41: Add Nuxt + Convex support - -## 2.28.5 - -### Patch Changes - -- 2ad89b7: fix auth error handling in all react templates - -## 2.28.4 - -### Patch Changes - -- 53985fe: fix nuxt template issues with bun - -## 2.28.3 - -### Patch Changes - -- 17389ac: Update Nuxt template deps and add tailwind as dep - -## 2.28.2 - -### Patch Changes - -- c8df019: update readme - -## 2.28.1 - -### Patch Changes - -- 16c4d42: Upgrade to Prisma 6.13.0 - -## 2.28.0 - -### Minor Changes - -- 216c242: Added addons: fumadocs, ultracite, oxlint - - Added bunfig.toml with isolated linker - - Grouped addon prompts - -### Patch Changes - -- 82a4f42: Added Sao Paulo region - -## 2.27.1 - -### Patch Changes - -- 31be802: Update prisma setup options labels and hints - -## 2.27.0 - -### Minor Changes - -- 0c26578: feat: Add quick setup option with create-db by Prisma - feat: Make Prisma Postgres available for both Prisma and Drizzle ORMs - -## 2.26.5 - -### Patch Changes - -- 23497b6: Remove tsc-alias configuration from tsconfig - -## 2.26.4 - -### Patch Changes - -- a4209b7: add react deps in next backend - -## 2.26.3 - -### Patch Changes - -- 2b71ef2: Use next-themes in theme provider for React frontends, and fix neon setup - -## 2.26.2 - -### Patch Changes - -- e2e4504: Bump better-auth packages to v1.3.0 - -## 2.26.1 - -### Patch Changes - -- 5ab503a: Add conditional rendering for private data based on API type in dashboard page - -## 2.26.0 - -### Minor Changes - -- 8a9ddc9: Update Nuxt template to v4 - -## 2.25.9 - -### Patch Changes - -- b47671c: Fix start script paths in Bun and Node runtime setup -- b9e9292: Return DB results directly in todo router handlers - -## 2.25.8 - -### Patch Changes - -- 5080b6b: Switch to tsdown in server template and update configs - -## 2.25.7 - -### Patch Changes - -- 4ece24b: Update telemetry disable instructions to use BTS_TELEMETRY_DISABLED - -## 2.25.6 - -### Patch Changes - -- 71e5850: remove telemetry console logs - -## 2.25.5 - -### Patch Changes - -- 901e1ff: fix telemetry logic - -## 2.25.4 - -### Patch Changes - -- 65c29c2: Allow disabling telemetry with BTS_TELEMETRY_DISABLED=1 - -## 2.25.3 - -### Patch Changes - -- ea826a5: biome ignore .wrangler dir - -## 2.25.2 - -### Patch Changes - -- 7881892: remove trailing comma in biome.json - -## 2.25.1 - -### Patch Changes - -- 110fa5a: exclude .expo dir from biome.json - -## 2.25.0 - -### Minor Changes - -- 3569b04: Added support for local database setup using Docker Compose for PostgreSQL, MySQL, and MongoDB. - -## 2.24.5 - -### Patch Changes - -- b2195dd: Upgrade to zod@4.0.2 - -## 2.24.4 - -### Patch Changes - -- 5fec00a: fix: web-deploy validation to check for frontend flag - -## 2.24.3 - -### Patch Changes - -- fe7b4ff: Remove unnecessary returning() from todo insert query - -## 2.24.2 - -### Patch Changes - -- e21756a: fix root path in unistyles template - -## 2.24.1 - -### Patch Changes - -- d344b85: Prevent web-deploy when no web frontend is selected -- 98bb4a3: Upgrade to unistyles 3.0 - -## 2.24.0 - -### Minor Changes - -- 0ae1347: add workers support for tanstack start - -## 2.23.1 - -### Patch Changes - -- aea23e8: add workers help message in neext steps box - -## 2.23.0 - -### Minor Changes - -- d267427: add cloudflare workers deployment support for next, solid, tanstack-router, react-router, nuxt - -## 2.22.10 - -### Patch Changes - -- 8dc521c: Avoid db:local script for D1 database - -## 2.22.9 - -### Patch Changes - -- 3ae5ab9: auto git commit if git init is true - -## 2.22.8 - -### Patch Changes - -- 0486e2a: Update TanStack Start references from devinxi to vite - -## 2.22.7 - -### Patch Changes - -- 2948629: Update Unistyles config and bump to 3.0.0-rc.5 - -## 2.22.6 - -### Patch Changes - -- e21f6de: generate better readme - -## 2.22.5 - -### Patch Changes - -- 32275d3: Add support for Neon database in db-setup - -## 2.22.4 - -### Patch Changes - -- da3d0ed: Exclude bts.jsonc from Biome - -## 2.22.3 - -### Patch Changes - -- e37a846: Update dependencies and version maps to latest releases - -## 2.22.2 - -### Patch Changes - -- 215bd2f: refactor files - -## 2.22.1 - -### Patch Changes - -- 3fbd751: fix(post-installation): use selected package manager - -## 2.22.0 - -### Minor Changes - -- 9c7a0f0: Add 'add' command for adding addons to existing projects - -## 2.21.1 - -### Patch Changes - -- 410ffda: update tailwindcss dep in next - -## 2.21.0 - -### Minor Changes - -- 0c5dd2e: add d1 database setup - -## 2.20.0 - -### Minor Changes - -- 7013426: upgrade to biome v2 - -## 2.19.1 - -### Patch Changes - -- 2e56b27: Switch workers template from TOML to JSONC format - -## 2.19.0 - -### Minor Changes - -- b34e94a: add cloudflare workers support for hono - -## 2.18.6 - -### Patch Changes - -- 2eacf7b: Add better-auth package in solid frontend - -## 2.18.5 - -### Patch Changes - -- 2e1aad3: update prisma dep - -## 2.18.4 - -### Patch Changes - -- 4cae3b7: fix prisma type error - -## 2.18.3 - -### Patch Changes - -- bfcecf5: update domain - -## 2.18.2 - -### Patch Changes - -- fd86d51: add sponsors, builder, docs command - -## 2.18.1 - -### Patch Changes - -- fc8e994: Migrate to radix-ui monorepo package and update imports - -## 2.18.0 - -### Minor Changes - -- 0ffaedd: Upgrade to Tanstack start vite - -### Patch Changes - -- 1dc9222: use zod for project name validation - -## 2.17.1 - -### Patch Changes - -- 28e5a7e: Remove redundant await return in create project mutation - -## 2.17.0 - -### Minor Changes - -- d677159: migrate to trpc-cli - -## 2.16.7 - -### Patch Changes - -- 5567d65: Show privateData only for selected API in dashboard template - -## 2.16.6 - -### Patch Changes - -- 737690c: Add trustedDependencies for Supabase when dbSetup is supabase - -## 2.16.5 - -### Patch Changes - -- 591affc: add neondb cli support - -## 2.16.4 - -### Patch Changes - -- da16fdc: remove biome check after installation - -## 2.16.3 - -### Patch Changes - -- ded8f89: Refactor Neon authentication logic - -## 2.16.2 - -### Patch Changes - -- 9aad821: fix react version - -## 2.16.1 - -### Patch Changes - -- 2e6454a: Improve oRPC templates - -## 2.16.0 - -### Minor Changes - -- 1485809: update orpc tanstack integration - -## 2.15.2 - -### Patch Changes - -- 314a38c: Remove @better-auth/expo from unistyles template - -## 2.15.1 - -### Patch Changes - -- f19c6d7: Simplify frontend/native prompt messages - -## 2.15.0 - -### Minor Changes - -- 7851d06: add AI and todo example templates for nativewind and unistyles - -## 2.14.4 - -### Patch Changes - -- 942c48f: run project tracker after reproducible command - -## 2.14.3 - -### Patch Changes - -- 3be1953: THIS IS JUST A TEST - -## 2.14.2 - -### Patch Changes - -- 27e4411: update react router deps and fix next backend tsconfig error - -## 2.14.1 - -### Patch Changes - -- c5c3fa3: update nextjs backend hint - -## 2.14.0 - -### Minor Changes - -- 591ecf8: add posthog analytics - -### Patch Changes - -- 906b555: Add Native Todo Example Support -- 1c2e8f1: fix convex imports -- 46651fb: add composite in server for references - -## 2.13.4 - -### Patch Changes - -- 71706c6: update database setup log messages - -## 2.13.3 - -### Patch Changes - -- a9d3601: Refactor CLI argument parsing, validation, and project setup logic - -## 2.13.2 - -### Patch Changes - -- cb0c98d: Add todo example and --configure to setup - -## 2.13.1 - -### Patch Changes - -- 07deae5: remove deprecated @types/globby - -## 2.13.0 - -### Minor Changes - -- 1cc9d81: Auto-generate .env.example files with empty values - -## 2.12.0 - -### Minor Changes - -- b9dae19: add fastify - -## 2.11.0 - -### Minor Changes - -- 01d745a: add pwa support in nextjs - -### Patch Changes - -- 5cfd3d3: fix zod v4 madness - -## 2.10.4 - -### Patch Changes - -- 1521aa1: add react query devtools in next template - -## 2.10.3 - -### Patch Changes - -- aed897c: fixed(#269): duplicate logging message during project creation - -## 2.10.2 - -### Patch Changes - -- 34ecf97: added support to select region for neon postgres - -## 2.10.1 - -### Patch Changes - -- 5a90912: fix prisma config dotenv error - -## 2.10.0 - -### Minor Changes - -- 5c5a4b2: add supabase database setup - -### Patch Changes - -- 0631b23: add supabase flag validation - -## 2.9.9 - -### Patch Changes - -- 4840951: remove references from tsconfig when backend is none or convex - -## 2.9.8 - -### Patch Changes - -- c147b35: fix tauri frontend dist locationd for react router - -## 2.9.7 - -### Patch Changes - -- 2b8eb62: add server references in web apps - -## 2.9.6 - -### Patch Changes - -- f5598c9: add tauri option for nextjs - -## 2.9.5 - -### Patch Changes - -- 6a339bc: dont allow examples when api is none - -## 2.9.4 - -### Patch Changes - -- 95c9113: fix incorrect helper usage - -## 2.9.3 - -### Patch Changes - -- 8209713: fix templates when backend is none - -## 2.9.2 - -### Patch Changes - -- 89caa15: Make Turborepo a default addon - -## 2.9.1 - -### Patch Changes - -- 296ea3d: Improve type safety for orpc protectedProcedure context - -## 2.9.0 - -### Minor Changes - -- 6c269a4: add expo with unistyles - -### Patch Changes - -- d09a284: make backend optional - -## 2.8.4 - -### Patch Changes - -- 4d5495d: Bump orpc and nativewind dependencies - -## 2.8.3 - -### Patch Changes - -- b0e23cb: Remove todos route from base Solid frontend template - -## 2.8.2 - -### Patch Changes - -- 317fd47: update readme - -## 2.8.1 - -### Patch Changes - -- 357dfbb: Prompt to overwrite non-empty dirs before config -- a2469b6: Add merge and rename options for existing directories - -## 2.8.0 - -### Minor Changes - -- 4f89b8b: add solid - -## 2.7.2 - -### Patch Changes - -- 1695185: Use CommonJS exports in babel config - -## 2.7.1 - -### Patch Changes - -- 7ecef29: Enable edge-to-edge display for Android - -## 2.7.0 - -### Minor Changes - -- 437cf9a: add mongoose orm support to the stack builder - -### Patch Changes - -- 0cb24b1: add migrate and generate scripts - -## 2.6.1 - -### Patch Changes - -- cebb077: Add dotenv import to Prisma config files - -## 2.6.0 - -### Minor Changes - -- d5894e5: upgrade to expo 53 - -## 2.5.2 - -### Patch Changes - -- 920a8f0: Fixed an issue where the CLI would still allow selecting non-Convex backends after specifying `--api none` flag. - -## 2.5.1 - -### Patch Changes - -- 9e00e20: add todo, ai template for next - -## 2.5.0 - -### Minor Changes - -- 8c648de: update to prisma v6.7.0 - -## 2.4.1 - -### Patch Changes - -- 0510a27: Fix spinner behavior in Neon command execution - -## 2.4.0 - -### Minor Changes - -- 065f862: add convex for svelte - -## 2.3.0 - -### Minor Changes - -- 2a5358a: add convex - -## 2.2.4 - -### Patch Changes - -- 9180ac2: fix shebang banner -- 49f1fa1: Replace tsup with tsdown - -## 2.2.3 - -### Patch Changes - -- aef7aa4: Refactor: Simplify error handling in CLI helpers - -## 2.2.2 - -### Patch Changes - -- f1ce6b4: fix(templates): password must be at least 8 characters - -## 2.2.1 - -### Patch Changes - -- ca0dcda: add svelte post installation hint - -## 2.2.0 - -### Minor Changes - -- ba55384: Add svelte - -## 2.1.5 - -### Patch Changes - -- 8adf020: add svelte - -## 2.1.4 - -### Patch Changes - -- 9b685d7: add .cache in native gitignore - -## 2.1.3 - -### Patch Changes - -- b400b7e: Add .nuxt to ignore list in biome.json - -## 2.1.2 - -### Patch Changes - -- 6031287: add zod dep in react router - -## 2.1.1 - -### Patch Changes - -- 9c125c2: fix prisma todo location - -## 2.1.0 - -### Minor Changes - -- d3a80b7: add nuxt and expo with orpc - -## 2.0.12 - -### Patch Changes - -- 7839950: Add express.json() middleware to the Express backend template. - Rename the TanStack Start frontend package to "web". - -## 2.0.11 - -### Patch Changes - -- ea79154: ensure .npmrc is included and copied for native setup - -## 2.0.10 - -### Patch Changes - -- 579d125: add zod dep in tanstack start - -## 2.0.9 - -### Patch Changes - -- b5267e0: Add setup warnings and handle no-ORM auth - -## 2.0.8 - -### Patch Changes - -- 1cb5c0c: fix database none flags validation - -## 2.0.7 - -### Patch Changes - -- d82ad80: fix native scaffolding - -## 2.0.6 - -### Patch Changes - -- 0de49d4: remove none option in api -- 0de49d4: Only add tRPC server adapters when API is tRPC - -## 2.0.6-beta.1 - -### Patch Changes - -- 9d9bd1d: remove none option in api - -## 2.0.6-beta.0 - -### Patch Changes - -- 0a4813b: Only add tRPC server adapters when API is tRPC - -## 2.0.5 - -### Patch Changes - -- 88afa9a: fix ai example template path - -## 2.0.4 - -### Patch Changes - -- 933c4ac: Implement @/\* path aliases and move dotenv imports - -## 2.0.3 - -### Patch Changes - -- 98fdc3b: fix pnpm dev script - -## 2.0.2 - -### Patch Changes - -- 13241ee: fix cli project name check - -## 2.0.1 - -### Patch Changes - -- 2a51f85: fix express server orpc route - -## 2.0.0 - -### Major Changes - -- 7f441ef: add orpc, make turborepo optional, use handlebarjs to scaffold template - -## 1.13.2 - -### Patch Changes - -- 1e67949: add consola errors, update to better-auth v1.2.6 - -## 1.13.1 - -### Patch Changes - -- 6d16f27: Update trpc endpoint path from '/api/trpc' to '/trpc' - -## 1.13.0 - -### Minor Changes - -- 33158a2: add nextjs frontend and backend - -## 1.12.4 - -### Patch Changes - -- bef8182: add command completions - -## 1.12.3 - -### Patch Changes - -- 3e7a605: upgrade to prisma v6.6.0 - -## 1.12.2 - -### Patch Changes - -- 5a15147: Fix validation logic with --yes flag for addon compatibility - -## 1.12.1 - -### Patch Changes - -- 30efd64: Add spinner feedback to database setup workflows - -## 1.12.0 - -### Minor Changes - -- 0868672: add neon postgres setup - -## 1.11.0 - -### Minor Changes - -- aac6a7d: add starlight docs addon - -## 1.10.3 - -### Patch Changes - -- 8120222: Replace postgres package with pg for PostgreSQL support with drizzle - -## 1.10.2 - -### Patch Changes - -- c84bfcd: Fix Postgres DB setup choice condition to require Prisma ORM - -## 1.10.1 - -### Patch Changes - -- 9222c1e: Change PrismaClient instantiation from `let` to `const` - -## 1.10.0 - -### Minor Changes - -- c9b7e25: add mysql database - -## 1.9.2 - -### Patch Changes - -- 7504d27: Rename database environment variables for consistency - -## 1.9.1 - -### Patch Changes - -- fe7153f: update deps - -## 1.9.0 - -### Minor Changes - -- 2cf01d1: Add express backend, mongodb database and automated mongodb atlas setup - -## 1.8.1 - -### Patch Changes - -- e8a777e: make frontend optional - -## 1.8.0 - -### Minor Changes - -- d943bf0: add tanstack start - -## 1.7.1 - -### Patch Changes - -- 935a23b: update readme - -## 1.7.0 - -### Minor Changes - -- 81dc240: Add Better Auth in Native - -## 1.6.2 - -### Patch Changes - -- b3c746c: Add useSortedClasses rule to Biome configuration - -## 1.6.1 - -### Patch Changes - -- b170dfc: fix prisma postgres setup prompt - -## 1.6.0 - -### Minor Changes - -- cc56381: Add automatic prisma postgres setup - -## 1.5.0 - -### Minor Changes - -- dafefb8: Add React Router - -## 1.4.5 - -### Patch Changes - -- 0d7ac63: Update CLI prompts - -## 1.4.4 - -### Patch Changes - -- b230ddb: Improve native connectivity instruction message - -## 1.4.3 - -### Patch Changes - -- b296ac2: use spaces instead of commas in flags - -## 1.4.2 - -### Patch Changes - -- 5435dd3: Replace log.info with note for post-install instructions - -## 1.4.1 - -### Patch Changes - -- c3ebe27: Remove debug console.log in examples setup - -## 1.4.0 - -### Minor Changes - -- a6ac5dc: Add AI chat example and update flags structures - -## 1.3.3 - -### Patch Changes - -- a69ff19: fix(todos): trpc v11 - -## 1.3.2 - -### Patch Changes - -- 851c1b7: Add @trpc/tanstack-react-query dependency to web package.json - -## 1.3.1 - -### Patch Changes - -- b0e3432: fix several bugs - -## 1.3.0 - -### Minor Changes - -- 1c66d64: Added support for building mobile applications with Expo - -## 1.2.0 - -### Minor Changes - -- 91fe9f8: Add option to choose elysiajs as backend framework - -## 1.1.0 - -### Minor Changes - -- 88afd53: Add runtime selection feature between Bun and Node.js - -## 1.0.10 - -### Patch Changes - -- 4a45ce9: Use current package manager version in packageManager field - -## 1.0.9 - -### Patch Changes - -- 380f659: Add package manager specific support for Tauri setup - -## 1.0.8 - -### Patch Changes - -- c9d4e4c: Fix self-closing div tag syntax in client template - -## 1.0.7 - -### Patch Changes - -- 2bfbcf6: fix several db conf issues - -## 1.0.6 - -### Patch Changes - -- d0133f3: rename packages folder to apps - -## 1.0.5 - -### Patch Changes - -- 6683202: Fix get() error method drizzle - -## 1.0.4 - -### Patch Changes - -- e358534: Add prismaSchemaFolder preview feature to Prisma config - -## 1.0.3 - -### Patch Changes - -- 53be1b8: fix pnpm workspace - -## 1.0.2 - -### Patch Changes - -- b5f47fc: Add Todo button to homepage when examples are included - -## 1.0.1 - -### Patch Changes - -- e7335d6: stable release - -## 1.0.0 - -### Major Changes - -- 4cc13bf: stable release - -## 0.17.2 - -### Patch Changes - -- 137cc31: some improvements - -## 0.17.1 - -### Patch Changes - -- 9574230: Redirect unauthenticated users to login page instead of home - -## 0.17.0 - -### Minor Changes - -- 996b35b: Add Biome and Husky for code formatting and Git hooks - -## 0.16.0 - -### Minor Changes - -- 406864f: Add Tauri Desktop App addon - -## 0.15.0 - -### Minor Changes - -- 66a47c7: Add Progressive Web App (PWA) support - -## 0.14.1 - -### Patch Changes - -- 03c400d: fix schema - -## 0.14.0 - -### Minor Changes - -- fc59f63: Enhance template with improved UI - -## 0.13.1 - -### Patch Changes - -- 3124a6a: fix .gitignore - -## 0.13.0 - -### Minor Changes - -- af70905: Fix auth template setup, todo example, turso setup with setup selection - -## 0.12.3 - -### Patch Changes - -- 17db765: Remove GitHub Actions and SEO addons - -## 0.12.2 - -### Patch Changes - -- e4f950c: fix env when turso setup is off - -## 0.12.1 - -### Patch Changes - -- 5897e9c: several improvements - -## 0.12.0 - -### Minor Changes - -- 03d9559: Simplify auth setup, centralize environment variable management and fix readme - -## 0.11.5 - -### Patch Changes - -- 640e64e: Improve package manager prompts - -## 0.11.4 - -### Patch Changes - -- b7ac81d: Add dependency version constants and package management utility - -## 0.11.3 - -### Patch Changes - -- ac2f220: simplify auth setup - -## 0.11.2 - -### Patch Changes - -- 98b1262: Add postgres support - -## 0.11.1 - -### Patch Changes - -- 036c62c: Enhance authentication setup and improve documentation - -## 0.11.0 - -### Minor Changes - -- f02ffd7: added github seo add-on - -## 0.10.4 - -### Patch Changes - -- 03571ca: allow specifying project path in prompt - -## 0.10.3 - -### Patch Changes - -- 5b13b04: rename features to addons - -## 0.10.2 - -### Patch Changes - -- 76ea670: fix template typo - -## 0.10.1 - -### Patch Changes - -- 48efa59: fix commander init - -## 0.10.0 - -### Minor Changes - -- 792885b: add auth, drizzle, prisma setup logic - -## 0.9.0 - -### Minor Changes - -- 6600d1f: implement auth add or remove logic - -## 0.8.1 - -### Patch Changes - -- ba77104: update ascii art - -## 0.8.0 - -### Minor Changes - -- 3d78d1e: add flags and prompt for orm, add none option in database - -## 0.7.5 - -### Patch Changes - -- 64fc644: refactor(cli): simplify database selection flags - -## 0.7.4 - -### Patch Changes - -- d30adfd: remove ugly emojis - -## 0.7.3 - -### Patch Changes - -- 7181751: remove caching in degit - -## 0.7.2 - -### Patch Changes - -- 91b786c: update readme - -## 0.7.1 - -### Patch Changes - -- be5c662: update readme - -## 0.7.0 - -### Minor Changes - -- f98216e: replace chalk with picocolors - -## 0.6.2 - -### Patch Changes - -- e9ecdbf: update template repo url and add degit - -## 0.6.1 - -### Patch Changes - -- f73c7d2: fix: dependency installation output flow - -## 0.6.0 - -### Minor Changes - -- aa3eaad: refactor: simplify package manager flags - -## 0.5.0 - -### Minor Changes - -- 0983fc1: feat(cli): display pre-selected flags before prompts - -## 0.4.6 - -### Patch Changes - -- 31f1271: Improve prompts - -## 0.4.5 - -### Patch Changes - -- 7fc5010: add small title for shorter window - -## 0.4.4 - -### Patch Changes - -- 92d2443: clear console on start - -## 0.4.3 - -### Patch Changes - -- ecd7db9: feat: add project name validation - -## 0.4.2 - -### Patch Changes - -- d8875f0: bug fixes - -## 0.4.1 - -### Patch Changes - -- 305fb72: remove logger and fix minor bugs - -## 0.4.0 - -### Minor Changes - -- 76a14ea: refactor: migrate inquirer to @clack/prompts - -## 0.3.4 - -### Patch Changes - -- 0bd0c8e: colorize the prompts - -## 0.3.3 - -### Patch Changes - -- ffda73e: Improve error handling - -## 0.3.2 - -### Patch Changes - -- d99e161: use script syntax in execa - -## 0.3.1 - -### Patch Changes - -- 7481bee: fix package manager detection - -## 0.3.0 - -### Minor Changes - -- 4659db9: feat: add package manager selection and configuration - -## 0.2.1 - -### Patch Changes - -- a0cef2b: bump version to 0.2.1 - -## 0.2.0 - -### Minor Changes - -- b56096f: feat(cli): add reproducible command output and flag support - -## 0.1.3 - -### Patch Changes - -- a06be85: refactor(cli): improve Turso database setup workflow - -## 0.1.2 - -### Patch Changes - -- 5554818: auto get current package version - -## 0.1.1 - -### Patch Changes - -- 5d89847: Add -y to auto select the defaults - -## 0.1.0 - -### Minor Changes - -- 5c83a10: initial release diff --git a/apps/cli/src/helpers/core/command-handlers.ts b/apps/cli/src/helpers/core/command-handlers.ts index fc97645..c557e5f 100644 --- a/apps/cli/src/helpers/core/command-handlers.ts +++ b/apps/cli/src/helpers/core/command-handlers.ts @@ -17,7 +17,7 @@ import type { ProjectConfig, } from "../../types"; import { trackProjectCreation } from "../../utils/analytics"; -import { coerceBackendPresets } from "../../utils/compatibility-rules"; + import { displayConfig } from "../../utils/display-config"; import { exitWithError, handleError } from "../../utils/errors"; import { generateReproducibleCommand } from "../../utils/generate-reproducible-command"; @@ -148,20 +148,8 @@ export async function createProjectHandler( relativePath: finalPathInput, }; - coerceBackendPresets(config); - validateConfigCompatibility(config, providedFlags, cliInput); - if (config.backend === "convex") { - log.info( - `Due to '--backend convex' flag, the following options have been automatically set: database=none, orm=none, api=none, runtime=none, dbSetup=none, examples=todo`, - ); - } else if (config.backend === "none") { - log.info( - "Due to '--backend none', the following options have been automatically set: --auth none, --database=none, --orm=none, --api=none, --runtime=none, --db-setup=none, --examples=none", - ); - } - log.info(pc.yellow("Using default/flag options (config prompts skipped):")); log.message(displayConfig(config)); log.message(""); diff --git a/apps/cli/src/utils/compatibility-rules.ts b/apps/cli/src/utils/compatibility-rules.ts index 8f3eaad..07600ec 100644 --- a/apps/cli/src/utils/compatibility-rules.ts +++ b/apps/cli/src/utils/compatibility-rules.ts @@ -133,72 +133,6 @@ export function validateWorkersCompatibility( } } -export function coerceBackendPresets(config: Partial) { - if (config.backend === "convex") { - config.database = "none"; - config.orm = "none"; - config.api = "none"; - config.runtime = "none"; - config.dbSetup = "none"; - config.examples = ["todo"] as ProjectConfig["examples"]; - } - if (config.backend === "none") { - config.auth = "none" as ProjectConfig["auth"]; - config.database = "none"; - config.orm = "none"; - config.api = "none"; - config.runtime = "none"; - config.dbSetup = "none"; - config.examples = [] as ProjectConfig["examples"]; - } -} - -export function incompatibleFlagsForBackend( - backend: ProjectConfig["backend"] | undefined, - providedFlags: Set, - options: CLIInput, -): string[] { - const list: string[] = []; - if (backend === "convex") { - if ( - providedFlags.has("auth") && - options.auth && - options.auth !== "none" && - options.auth !== "clerk" - ) - list.push(`--auth ${options.auth}`); - if (providedFlags.has("database") && options.database !== "none") - list.push(`--database ${options.database}`); - if (providedFlags.has("orm") && options.orm !== "none") - list.push(`--orm ${options.orm}`); - if (providedFlags.has("api") && options.api !== "none") - list.push(`--api ${options.api}`); - if (providedFlags.has("runtime") && options.runtime !== "none") - list.push(`--runtime ${options.runtime}`); - if (providedFlags.has("dbSetup") && options.dbSetup !== "none") - list.push(`--db-setup ${options.dbSetup}`); - } - if (backend === "none") { - if (providedFlags.has("auth") && options.auth && options.auth !== "none") - list.push(`--auth ${options.auth}`); - if (providedFlags.has("database") && options.database !== "none") - list.push(`--database ${options.database}`); - if (providedFlags.has("orm") && options.orm !== "none") - list.push(`--orm ${options.orm}`); - if (providedFlags.has("api") && options.api !== "none") - list.push(`--api ${options.api}`); - if (providedFlags.has("runtime") && options.runtime !== "none") - list.push(`--runtime ${options.runtime}`); - if (providedFlags.has("dbSetup") && options.dbSetup !== "none") - list.push(`--db-setup ${options.dbSetup}`); - if (providedFlags.has("examples") && options.examples) { - const hasNonNoneExamples = options.examples.some((ex) => ex !== "none"); - if (hasNonNoneExamples) list.push("--examples"); - } - } - return list; -} - export function validateApiFrontendCompatibility( api: API | undefined, frontends: Frontend[] = [], diff --git a/apps/cli/src/utils/config-validation.ts b/apps/cli/src/utils/config-validation.ts index ce83fde..9505956 100644 --- a/apps/cli/src/utils/config-validation.ts +++ b/apps/cli/src/utils/config-validation.ts @@ -6,9 +6,7 @@ import type { Runtime, } from "../types"; import { - coerceBackendPresets, ensureSingleWebAndNative, - incompatibleFlagsForBackend, isWebFrontend, validateAddonsAgainstFrontends, validateAlchemyCompatibility, @@ -226,38 +224,19 @@ export function validateBackendConstraints( } } - if (backend === "convex" || backend === "none") { - const incompatibleFlags = incompatibleFlagsForBackend( - backend, - providedFlags, - options, - ); - if (incompatibleFlags.length > 0) { + if ( + backend === "convex" && + providedFlags.has("frontend") && + options.frontend + ) { + const incompatibleFrontends = options.frontend.filter((f) => f === "solid"); + if (incompatibleFrontends.length > 0) { exitWithError( - `The following flags are incompatible with '--backend ${backend}': ${incompatibleFlags.join( + `The following frontends are not compatible with '--backend convex': ${incompatibleFrontends.join( ", ", - )}. Please remove them.`, + )}. Please choose a different frontend or backend.`, ); } - - if ( - backend === "convex" && - providedFlags.has("frontend") && - options.frontend - ) { - const incompatibleFrontends = options.frontend.filter( - (f) => f === "solid", - ); - if (incompatibleFrontends.length > 0) { - exitWithError( - `The following frontends are not compatible with '--backend convex': ${incompatibleFrontends.join( - ", ", - )}. Please choose a different frontend or backend.`, - ); - } - } - - coerceBackendPresets(config); } } diff --git a/apps/cli/src/validation.ts b/apps/cli/src/validation.ts index f274d45..515f190 100644 --- a/apps/cli/src/validation.ts +++ b/apps/cli/src/validation.ts @@ -11,6 +11,39 @@ import { import { exitWithError } from "./utils/errors"; import { extractAndValidateProjectName } from "./utils/project-name-validation"; +const CORE_STACK_FLAGS = new Set([ + "database", + "orm", + "backend", + "runtime", + "frontend", + "addons", + "examples", + "auth", + "dbSetup", + "api", + "webDeploy", + "serverDeploy", +]); + +function validateYesFlagCombination( + options: CLIInput, + providedFlags: Set, +) { + if (!options.yes) return; + + const coreStackFlagsProvided = Array.from(providedFlags).filter((flag) => + CORE_STACK_FLAGS.has(flag), + ); + + if (coreStackFlagsProvided.length > 0) { + exitWithError( + `Cannot combine --yes with core stack configuration flags: ${coreStackFlagsProvided.map((f) => `--${f}`).join(", ")}. ` + + "The --yes flag uses default configuration. Remove these flags or use --yes without them.", + ); + } +} + export function processAndValidateFlags( options: CLIInput, providedFlags: Set, @@ -29,6 +62,8 @@ export function processAndValidateFlags( return cfg; } + validateYesFlagCombination(options, providedFlags); + try { validateArrayOptions(options); } catch (error) { @@ -55,6 +90,11 @@ export function processProvidedFlagsWithoutValidation( options: CLIInput, projectName?: string, ): Partial { + if (!options.yolo) { + const providedFlags = getProvidedFlags(options); + validateYesFlagCombination(options, providedFlags); + } + const config = processFlags(options, projectName); const validatedProjectName = extractAndValidateProjectName( diff --git a/apps/cli/test/cli.smoke.test.ts b/apps/cli/test/cli.smoke.test.ts index 19687b9..dad6cdb 100644 --- a/apps/cli/test/cli.smoke.test.ts +++ b/apps/cli/test/cli.smoke.test.ts @@ -432,7 +432,6 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", frontend, "--backend", @@ -447,10 +446,14 @@ describe("create-better-t-stack smoke", () => { "none", "--auth", "none", - "--addons", - "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", + "--addons", + "none", "--examples", "none", "--package-manager", @@ -509,17 +512,30 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", frontend, "--backend", "convex", + "--runtime", + "none", + "--database", + "none", + "--orm", + "none", + "--api", + "none", "--auth", "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "none", "--package-manager", "bun", "--no-install", @@ -563,17 +579,30 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", frontend, "--backend", "convex", + "--runtime", + "none", + "--api", + "none", + "--database", + "none", + "--orm", + "none", "--auth", "clerk", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "none", "--package-manager", "bun", "--no-install", @@ -606,17 +635,30 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", frontend, "--backend", "convex", + "--runtime", + "none", + "--api", + "none", + "--database", + "none", + "--orm", + "none", "--auth", "clerk", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "none", "--package-manager", "bun", "--no-install", @@ -648,18 +690,31 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "tanstack-router", "native-nativewind", "--backend", "convex", + "--runtime", + "none", + "--api", + "none", + "--database", + "none", + "--orm", + "none", "--auth", "clerk", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "none", "--package-manager", "bun", "--no-install", @@ -690,18 +745,32 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "next", "native-unistyles", "--backend", "convex", + "--runtime", + "none", + "--api", + "none", + "--database", + "none", + "--orm", + "none", "--auth", "clerk", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "none", "--package-manager", "bun", "--no-install", @@ -732,18 +801,32 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-start", "native-nativewind", "--backend", "convex", + "--runtime", + "none", + "--api", + "none", + "--database", + "none", + "--orm", + "none", "--auth", "clerk", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "none", "--package-manager", "bun", "--no-install", @@ -777,19 +860,7 @@ describe("create-better-t-stack smoke", () => { it("scaffolds minimal default project with yes flag", async () => { const projectName = "app-default"; - await runCli( - [ - projectName, - "--yes", - "--db-setup", - "none", - "--addons", - "none", - "--no-install", - "--no-git", - ], - workdir, - ); + await runCli([projectName, "--yes", "--no-install", "--no-git"], workdir); const projectDir = join(workdir, projectName); assertScaffoldedProject(projectDir); @@ -798,6 +869,7 @@ describe("create-better-t-stack smoke", () => { hasServer: true, hasAuth: true, hasDatabase: true, + hasTurborepo: true, }); assertBtsConfig(projectDir, { frontend: ["tanstack-router"], @@ -805,59 +877,7 @@ describe("create-better-t-stack smoke", () => { database: "sqlite", orm: "drizzle", auth: "better-auth", - addons: [], - }); - }); - - it("scaffolds with explicit minimal flags (no db, no api, no auth, no addons)", async () => { - const projectName = "app-min"; - await runCli( - [ - projectName, - "--yes", - "--frontend", - "tanstack-router", - "--backend", - "hono", - "--runtime", - "bun", - "--database", - "none", - "--orm", - "none", - "--api", - "none", - "--auth", - "none", - "--addons", - "none", - "--db-setup", - "none", - "--examples", - "none", - "--package-manager", - "bun", - "--no-install", - "--no-git", - ], - workdir, - ); - - const projectDir = join(workdir, projectName); - assertScaffoldedProject(projectDir); - assertProjectStructure(projectDir, { - hasWeb: true, - hasServer: true, - hasAuth: false, - hasDatabase: false, - }); - assertBtsConfig(projectDir, { - frontend: ["tanstack-router"], - backend: "hono", - database: "none", - orm: "none", - auth: "none", - addons: [], + addons: ["turborepo"], }); }); @@ -866,7 +886,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -889,6 +909,10 @@ describe("create-better-t-stack smoke", () => { "none", "--package-manager", "bun", + "--web-deploy", + "none", + "--server-deploy", + "none", "--no-install", "--no-git", ], @@ -916,19 +940,35 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", "convex", + "--runtime", + "none", + "--api", + "none", + "--database", + "none", + "--orm", + "none", "--auth", "none", "--db-setup", "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "todo", "--package-manager", "bun", + "--web-deploy", + "none", + "--server-deploy", + "none", "--no-install", "--no-git", ], @@ -959,11 +999,12 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "next", "--backend", "none", + "--runtime", + "bun", "--database", "none", "--orm", @@ -972,10 +1013,14 @@ describe("create-better-t-stack smoke", () => { "none", "--auth", "none", - "--addons", - "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", + "--addons", + "none", "--examples", "none", "--package-manager", @@ -1003,11 +1048,12 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "nuxt", "--backend", "none", + "--runtime", + "bun", "--database", "none", "--orm", @@ -1016,10 +1062,14 @@ describe("create-better-t-stack smoke", () => { "none", "--auth", "none", - "--addons", - "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", + "--addons", + "none", "--examples", "none", "--package-manager", @@ -1047,11 +1097,12 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "svelte", "--backend", "none", + "--runtime", + "bun", "--database", "none", "--orm", @@ -1060,10 +1111,14 @@ describe("create-better-t-stack smoke", () => { "none", "--auth", "none", - "--addons", - "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", + "--addons", + "none", "--examples", "none", "--package-manager", @@ -1091,11 +1146,12 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "solid", "--backend", "none", + "--runtime", + "bun", "--database", "none", "--orm", @@ -1104,10 +1160,14 @@ describe("create-better-t-stack smoke", () => { "none", "--auth", "none", - "--addons", - "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", + "--addons", + "none", "--examples", "none", "--package-manager", @@ -1135,11 +1195,12 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "native-nativewind", "--backend", "none", + "--runtime", + "bun", "--database", "none", "--orm", @@ -1148,10 +1209,14 @@ describe("create-better-t-stack smoke", () => { "none", "--auth", "none", - "--addons", - "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", + "--addons", + "none", "--examples", "none", "--package-manager", @@ -1181,7 +1246,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1198,9 +1263,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1227,7 +1296,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1244,9 +1313,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1273,7 +1346,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1290,9 +1363,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1321,7 +1398,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1338,9 +1415,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1368,7 +1449,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1385,9 +1466,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1415,7 +1500,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1432,9 +1517,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1462,7 +1551,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1479,9 +1568,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1511,7 +1604,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1534,6 +1627,10 @@ describe("create-better-t-stack smoke", () => { "none", "--package-manager", "bun", + "--web-deploy", + "none", + "--server-deploy", + "none", "--no-install", "--no-git", ], @@ -1557,7 +1654,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1579,6 +1676,10 @@ describe("create-better-t-stack smoke", () => { "none", "--examples", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -1607,7 +1708,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1624,9 +1725,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1648,7 +1753,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1665,9 +1770,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1690,7 +1799,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "", - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1707,10 +1816,10 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "none", + "--db-setup", + "none", "--package-manager", "bun", "--no-install", @@ -1724,7 +1833,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-database-orm", - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1741,9 +1850,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1758,7 +1871,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-frontend-api", - "--yes", + "--frontend", "nuxt", "--backend", @@ -1775,9 +1888,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1792,7 +1909,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-multiple-web", - "--yes", + "--frontend", "tanstack-router", "next", @@ -1810,9 +1927,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -1827,7 +1948,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-turso-sqlite", - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1844,10 +1965,16 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "turso", "--examples", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -1861,7 +1988,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-convex-better-auth", - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1872,6 +1999,12 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -1885,7 +2018,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-nuxt-convex-clerk", - "--yes", + "--frontend", "nuxt", "--backend", @@ -1896,6 +2029,12 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -1909,7 +2048,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-svlete-convex-clerk", - "--yes", + "--frontend", "svelte", "--backend", @@ -1920,6 +2059,12 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -1936,7 +2081,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -1953,10 +2098,16 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "turso", "--examples", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -1979,13 +2130,26 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "none", "--backend", "none", + "--runtime", + "bun", + "--database", + "none", + "--orm", + "none", + "--api", + "none", + "--auth", + "none", + "--db-setup", + "none", "--web-deploy", "wrangler", + "--server-deploy", + "none", "--addons", "none", "--examples", @@ -2014,7 +2178,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2033,9 +2197,11 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", "none", "--package-manager", "bun", @@ -2058,7 +2224,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-runtime-backend", - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2075,9 +2241,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2092,7 +2262,7 @@ describe("create-better-t-stack smoke", () => { await runCliExpectingError( [ "invalid-combo-runtime-orm", - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2109,9 +2279,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2129,7 +2303,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2146,9 +2320,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "npm", @@ -2170,7 +2348,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2187,9 +2365,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "pnpm", @@ -2215,7 +2397,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "nuxt", "--backend", @@ -2232,10 +2414,14 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "ai", + "--db-setup", + "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -2258,7 +2444,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2275,10 +2461,14 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "todo", + "--db-setup", + "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -2299,7 +2489,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2316,10 +2506,14 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "ai", + "--db-setup", + "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--package-manager", "bun", "--no-install", @@ -2340,17 +2534,31 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", "convex", + "--runtime", + "none", + "--api", + "none", + "--database", + "none", + "--orm", + "none", "--auth", "none", "--db-setup", "none", + "--web-deploy", + "none", + "--server-deploy", + "none", "--addons", "none", + "--examples", + "todo", "--package-manager", "bun", "--no-install", @@ -2373,7 +2581,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2390,9 +2598,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2412,7 +2624,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--directory-conflict", "overwrite", "--frontend", @@ -2431,9 +2643,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2453,7 +2669,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2472,7 +2688,9 @@ describe("create-better-t-stack smoke", () => { "pwa", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2494,7 +2712,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2513,7 +2731,9 @@ describe("create-better-t-stack smoke", () => { "tauri", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2535,7 +2755,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2554,7 +2774,9 @@ describe("create-better-t-stack smoke", () => { "husky", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2576,7 +2798,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2593,9 +2815,13 @@ describe("create-better-t-stack smoke", () => { "better-auth", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2623,7 +2849,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2640,9 +2866,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2665,7 +2895,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2682,9 +2912,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2707,7 +2941,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "next", "--backend", @@ -2724,9 +2958,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2749,7 +2987,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "nuxt", "--backend", @@ -2766,9 +3004,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2791,7 +3033,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "svelte", "--backend", @@ -2808,9 +3050,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2833,7 +3079,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "solid", "--backend", @@ -2850,9 +3096,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2875,7 +3125,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "next", "--backend", @@ -2892,9 +3142,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -2917,7 +3171,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -2934,9 +3188,13 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", + "--examples", + "none", "--db-setup", "none", - "--examples", + "--web-deploy", + "none", + "--server-deploy", "none", "--package-manager", "bun", @@ -3188,7 +3446,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -3209,10 +3467,10 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "none", + "--db-setup", + "none", "--package-manager", "bun", "--no-install", @@ -3235,7 +3493,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -3256,10 +3514,10 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "none", + "--db-setup", + "none", "--package-manager", "bun", "--no-install", @@ -3282,7 +3540,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--directory-conflict", "overwrite", "--frontend", @@ -3293,6 +3551,8 @@ describe("create-better-t-stack smoke", () => { "workers", "--server-deploy", "alchemy", + "--web-deploy", + "none", "--database", "none", "--orm", @@ -3303,10 +3563,10 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "none", + "--db-setup", + "none", "--package-manager", "bun", "--no-install", @@ -3338,7 +3598,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -3347,6 +3607,8 @@ describe("create-better-t-stack smoke", () => { "workers", "--server-deploy", "wrangler", + "--web-deploy", + "none", "--database", "none", "--orm", @@ -3357,10 +3619,10 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "none", + "--db-setup", + "none", "--package-manager", "bun", "--no-install", @@ -3383,7 +3645,7 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", + "--frontend", "tanstack-router", "--backend", @@ -3392,6 +3654,8 @@ describe("create-better-t-stack smoke", () => { "workers", "--server-deploy", "alchemy", + "--web-deploy", + "none", "--database", "none", "--orm", @@ -3402,10 +3666,10 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "none", + "--db-setup", + "none", "--package-manager", "bun", "--no-install", @@ -3428,13 +3692,16 @@ describe("create-better-t-stack smoke", () => { await runCli( [ projectName, - "--yes", "--frontend", "tanstack-router", "--backend", "none", + "--runtime", + "bun", "--web-deploy", "wrangler", + "--server-deploy", + "none", "--database", "none", "--orm", @@ -3445,10 +3712,10 @@ describe("create-better-t-stack smoke", () => { "none", "--addons", "none", - "--db-setup", - "none", "--examples", "none", + "--db-setup", + "none", "--package-manager", "bun", "--no-install", diff --git a/apps/cli/test/programmatic-api.test.ts b/apps/cli/test/programmatic-api.test.ts index 2f1e995..9819c74 100644 --- a/apps/cli/test/programmatic-api.test.ts +++ b/apps/cli/test/programmatic-api.test.ts @@ -83,7 +83,19 @@ describe("Programmatic API - Fast Tests", () => { describe("Core functionality", () => { test("creates minimal project successfully", async () => { const result = await init("test-app", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -100,7 +112,19 @@ describe("Programmatic API - Fast Tests", () => { test("returns complete result structure", async () => { const result = await init("result-test", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -116,7 +140,19 @@ describe("Programmatic API - Fast Tests", () => { test("handles project with custom name", async () => { const result = await init("custom-name", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -130,8 +166,19 @@ describe("Programmatic API - Fast Tests", () => { describe("Configuration options", () => { test("creates project with Next.js frontend", async () => { const result = await init("next-app", { - yes: true, frontend: ["next"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -144,8 +191,19 @@ describe("Programmatic API - Fast Tests", () => { test("creates project with Fastify backend", async () => { const result = await init("fastify-app", { - yes: true, + frontend: ["tanstack-router"], backend: "fastify", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -158,9 +216,19 @@ describe("Programmatic API - Fast Tests", () => { test("creates project with PostgreSQL + Prisma", async () => { const result = await init("pg-app", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", database: "postgres", orm: "prisma", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -174,8 +242,19 @@ describe("Programmatic API - Fast Tests", () => { test("creates project with oRPC API", async () => { const result = await init("orpc-app", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", api: "orpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -188,8 +267,19 @@ describe("Programmatic API - Fast Tests", () => { test("creates project with Node runtime", async () => { const result = await init("node-app", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", runtime: "node", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -202,8 +292,19 @@ describe("Programmatic API - Fast Tests", () => { test("creates project with Biome addon", async () => { const result = await init("biome-app", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", addons: ["biome"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -216,7 +317,19 @@ describe("Programmatic API - Fast Tests", () => { test("creates project with analytics disabled", async () => { const result = await init("no-analytics-app", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", disableAnalytics: true, install: false, git: false, @@ -231,7 +344,19 @@ describe("Programmatic API - Fast Tests", () => { test("handles invalid project name", async () => { await expect( init("", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }), @@ -241,7 +366,19 @@ describe("Programmatic API - Fast Tests", () => { test("handles invalid characters in project name", async () => { await expect( init("invalid", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }), @@ -251,9 +388,19 @@ describe("Programmatic API - Fast Tests", () => { test("handles incompatible database + ORM combination", async () => { await expect( init("incompatible", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", database: "mongodb", orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, yolo: false, @@ -264,19 +411,41 @@ describe("Programmatic API - Fast Tests", () => { test("handles auth without database", async () => { await expect( init("auth-no-db", { - yes: true, - auth: "better-auth", + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", database: "none", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, yolo: false, }), - ).rejects.toThrow(/Authentication requires/); + ).rejects.toThrow(/ORM selection requires a database/); }); test("handles directory conflict with error strategy", async () => { const result1 = await init("conflict-test", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -284,7 +453,19 @@ describe("Programmatic API - Fast Tests", () => { expect(result1.success).toBe(true); const result2 = await init("conflict-test", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, directoryConflict: "error", @@ -298,8 +479,19 @@ describe("Programmatic API - Fast Tests", () => { describe("Advanced features", () => { test("creates project with multiple addons", async () => { const result = await init("multi-addon", { - yes: true, + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", + database: "sqlite", + orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", addons: ["biome", "turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -312,10 +504,19 @@ describe("Programmatic API - Fast Tests", () => { test("creates project with authentication enabled", async () => { const result = await init("auth-app", { - yes: true, - auth: "better-auth", + frontend: ["tanstack-router"], + backend: "hono", + runtime: "bun", database: "sqlite", orm: "drizzle", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); @@ -330,11 +531,19 @@ describe("Programmatic API - Fast Tests", () => { test("validates reproducible command format", async () => { const result = await init("repro-test", { - yes: true, frontend: ["next"], backend: "fastify", + runtime: "bun", database: "postgres", orm: "prisma", + api: "trpc", + auth: "better-auth", + dbSetup: "none", + webDeploy: "none", + serverDeploy: "none", + addons: ["turborepo"], + examples: ["none"], + packageManager: "bun", install: false, git: false, }); diff --git a/apps/web/src/app/(home)/_components/stack-builder.tsx b/apps/web/src/app/(home)/_components/stack-builder.tsx index 9cd2dd0..272c3e0 100644 --- a/apps/web/src/app/(home)/_components/stack-builder.tsx +++ b/apps/web/src/app/(home)/_components/stack-builder.tsx @@ -229,7 +229,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { if (JSON.stringify(nextStack[catKey]) !== JSON.stringify(value)) { const displayName = getCategoryDisplayName(catKey); const valueDisplay = Array.isArray(value) ? value.join(", ") : value; - const message = `${displayName} set to '${valueDisplay}'`; + const message = `${displayName} set to '${valueDisplay}' (Convex backend requires this configuration)`; notes[catKey].notes.push( `Convex backend selected: ${displayName} will be set to '${valueDisplay}'.`, @@ -263,7 +263,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { notes.backend.hasIssue = true; changes.push({ category: "convex", - message: "Removed incompatible web frontends (Solid)", + message: "Removed Solid frontend (not compatible with Convex backend)", }); } if (nextStack.nativeFrontend[0] === "none") { @@ -285,7 +285,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { if (JSON.stringify(nextStack[catKey]) !== JSON.stringify(value)) { const displayName = getCategoryDisplayName(catKey); const valueDisplay = Array.isArray(value) ? "none" : value; - const message = `${displayName} set to '${valueDisplay}'`; + const message = `${displayName} set to '${valueDisplay}' (no backend selected)`; notes[catKey].notes.push( `No backend selected: ${displayName} will be set to '${valueDisplay}'.`, @@ -312,7 +312,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "runtime", - message: "Runtime set to 'Bun' (None is only for Convex)", + message: + "Runtime set to 'Bun' (runtime 'None' is only available with Convex backend)", }); } if (nextStack.api === "none" && (isConvex || isBackendNone)) { @@ -328,7 +329,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "api", - message: "Examples removed (API 'None' does not support examples)", + message: + "Examples removed (examples require an API layer but 'None' was selected)", }); } } @@ -347,7 +349,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "database", - message: "ORM set to 'None' (requires a database)", + message: + "ORM set to 'None' (ORM requires a database but 'None' was selected)", }); } if (nextStack.auth !== "none" && nextStack.backend !== "convex") { @@ -363,7 +366,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "database", - message: "Authentication set to 'None' (requires a database)", + message: + "Authentication set to 'None' (auth requires a database but 'None' was selected)", }); } if (nextStack.dbSetup !== "none") { @@ -379,7 +383,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "database", - message: "DB Setup set to 'None' (requires a database)", + message: + "DB Setup set to 'None' (database setup requires a database but 'None' was selected)", }); } } else if (nextStack.database === "mongodb") { @@ -396,7 +401,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "database", - message: "ORM set to 'Prisma' (MongoDB requires Prisma or Mongoose)", + message: + "ORM set to 'Prisma' (MongoDB database only works with Prisma or Mongoose ORM)", }); } } else { @@ -413,7 +419,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "database", - message: "ORM set to 'Drizzle' (Mongoose only works with MongoDB)", + message: + "ORM set to 'Drizzle' (Mongoose ORM only works with MongoDB database)", }); } if (nextStack.dbSetup === "turso") { @@ -430,7 +437,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "dbSetup", - message: "Database set to 'SQLite' (required by Turso)", + message: + "Database set to 'SQLite' (Turso hosting requires SQLite database)", }); } if (nextStack.orm !== "drizzle") { @@ -446,7 +454,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "dbSetup", - message: "ORM set to 'Drizzle' (required by Turso)", + message: + "ORM set to 'Drizzle' (Turso hosting requires Drizzle ORM)", }); } } else if (nextStack.dbSetup === "prisma-postgres") { @@ -495,7 +504,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changes.push({ category: "dbSetup", message: - "ORM set to 'Prisma' (MongoDB Atlas requires Prisma or Mongoose)", + "ORM set to 'Prisma' (MongoDB Atlas with current setup requires Prisma ORM)", }); } } else if (nextStack.dbSetup === "neon") { @@ -512,7 +521,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "dbSetup", - message: "Database set to 'PostgreSQL' (required by Neon)", + message: + "Database set to 'PostgreSQL' (Neon hosting requires PostgreSQL database)", }); } } else if (nextStack.dbSetup === "supabase") { @@ -530,7 +540,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changes.push({ category: "dbSetup", message: - "Database set to 'PostgreSQL' (required by Supabase setup)", + "Database set to 'PostgreSQL' (Supabase hosting requires PostgreSQL database)", }); } } else if (nextStack.dbSetup === "d1") { @@ -647,21 +657,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "runtime", - message: "Backend set to 'Hono' (required by Cloudflare Workers)", - }); - } - - if (nextStack.serverDeploy === "none") { - notes.serverDeploy.notes.push( - "Cloudflare Workers runtime requires a server deployment. Wrangler will be selected.", - ); - notes.serverDeploy.hasIssue = true; - nextStack.serverDeploy = "wrangler"; - changed = true; - changes.push({ - category: "serverDeploy", message: - "Server deployment set to 'Wrangler' (required by Cloudflare Workers)", + "Backend set to 'Hono' (Cloudflare Workers runtime only works with Hono backend)", }); } @@ -678,7 +675,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "runtime", - message: "ORM set to 'Drizzle' (required by Cloudflare Workers)", + message: + "ORM set to 'Drizzle' (Cloudflare Workers runtime only supports Drizzle or no ORM)", }); } @@ -696,7 +694,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changes.push({ category: "runtime", message: - "Database set to 'SQLite' (MongoDB not compatible with Workers)", + "Database set to 'SQLite' (MongoDB not compatible with Cloudflare Workers runtime)", }); } @@ -714,9 +712,48 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changes.push({ category: "runtime", message: - "DB Setup set to 'D1' (Docker not compatible with Workers)", + "DB Setup set to 'D1' (Docker setup not compatible with Cloudflare Workers runtime)", }); } + } else { + if (nextStack.serverDeploy === "wrangler") { + notes.runtime.notes.push( + "Wrangler deployment requires Cloudflare Workers runtime. Server deployment disabled.", + ); + notes.serverDeploy.notes.push( + "Selected runtime is not compatible with Wrangler deployment. Server deployment disabled.", + ); + notes.runtime.hasIssue = true; + notes.serverDeploy.hasIssue = true; + nextStack.serverDeploy = "none"; + changed = true; + changes.push({ + category: "runtime", + message: + "Server deployment set to 'None' (Wrangler requires Cloudflare Workers runtime)", + }); + } + } + + if ( + nextStack.backend !== "hono" && + nextStack.serverDeploy === "wrangler" + ) { + notes.backend.notes.push( + "Wrangler deployment requires Hono backend (via Workers runtime). Server deployment disabled.", + ); + notes.serverDeploy.notes.push( + "Selected backend is not compatible with Wrangler deployment. Server deployment disabled.", + ); + notes.backend.hasIssue = true; + notes.serverDeploy.hasIssue = true; + nextStack.serverDeploy = "none"; + changed = true; + changes.push({ + category: "backend", + message: + "Server deployment set to 'None' (Wrangler requires Hono backend via Workers runtime)", + }); } const isNuxt = nextStack.webFrontend.includes("nuxt"); @@ -754,7 +791,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "auth", - message: "Auth set to 'None' (Clerk only available with Convex)", + message: + "Auth set to 'None' (Clerk authentication only works with Convex backend)", }); } else { const hasClerkCompatibleFrontend = @@ -784,7 +822,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changes.push({ category: "auth", message: - "Auth set to 'None' (Clerk not compatible with selected frontends)", + "Auth set to 'None' (Clerk not compatible with Svelte, Nuxt, or Solid frontends)", }); } } @@ -804,7 +842,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changes.push({ category: "auth", message: - "Auth set to 'None' (Better-Auth not compatible with Convex)", + "Auth set to 'None' (Better-Auth not compatible with Convex backend - use Clerk instead)", }); } @@ -824,7 +862,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { notes.addons.hasIssue = true; changes.push({ category: "addons", - message: "PWA addon removed (requires compatible web frontend)", + message: + "PWA addon removed (only works with TanStack Router, React Router, Solid, or Next.js)", }); } if (!isTauriCompat && nextStack.addons.includes("tauri")) { @@ -839,7 +878,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { notes.addons.hasIssue = true; changes.push({ category: "addons", - message: "Tauri addon removed (requires compatible web frontend)", + message: + "Tauri addon removed (only works with TanStack Router, React Router, Nuxt, Svelte, Solid, or Next.js)", }); } @@ -872,7 +912,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "addons", - message: "Biome addon removed (included in Ultracite)", + message: + "Biome addon removed (Ultracite already includes Biome configuration)", }); } } @@ -895,21 +936,22 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { incompatibleExamples.push("todo"); changes.push({ category: "examples", - message: "Todo example removed (requires a database)", + message: + "Todo example removed (requires a database but 'None' was selected)", }); } if (nextStack.backend === "elysia" && nextStack.examples.includes("ai")) { incompatibleExamples.push("ai"); changes.push({ category: "examples", - message: "AI example removed (not compatible with Elysia)", + message: "AI example removed (not compatible with Elysia backend)", }); } if (isSolid && nextStack.examples.includes("ai")) { incompatibleExamples.push("ai"); changes.push({ category: "examples", - message: "AI example removed (not compatible with Solid)", + message: "AI example removed (not compatible with Solid frontend)", }); } @@ -976,7 +1018,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "webDeploy", - message: "Web deployment set to 'none' (requires web frontend)", + message: + "Web deployment set to 'None' (requires a web frontend but only native frontend selected)", }); } @@ -996,91 +1039,41 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "serverDeploy", - message: "Server deployment set to 'none' (requires backend)", + message: + "Server deployment set to 'None' (requires a backend but 'None' or 'Convex' was selected)", }); } - if (nextStack.serverDeploy !== "none" && nextStack.runtime !== "workers") { + if ( + nextStack.serverDeploy === "wrangler" && + (nextStack.runtime !== "workers" || nextStack.backend !== "hono") + ) { notes.serverDeploy.notes.push( - "Selected server deployment targets Cloudflare Workers. Runtime will be set to 'Cloudflare Workers'.", + "Wrangler deployment requires Cloudflare Workers runtime and Hono backend. Server deployment disabled.", ); - notes.runtime.notes.push( - "Server deployment requires Cloudflare Workers runtime. It will be selected.", + notes.serverDeploy.notes.push( + "To use Wrangler: Set Runtime to 'Cloudflare Workers' and Backend to 'Hono', then re-enable Wrangler deployment.", ); + if (nextStack.runtime !== "workers") { + notes.runtime.notes.push( + "Selected runtime is not compatible with Wrangler deployment. Switch to 'Cloudflare Workers' to use Wrangler.", + ); + } + if (nextStack.backend !== "hono") { + notes.backend.notes.push( + "Selected backend is not compatible with Wrangler deployment. Switch to 'Hono' to use Wrangler.", + ); + } notes.serverDeploy.hasIssue = true; notes.runtime.hasIssue = true; - nextStack.runtime = "workers"; + notes.backend.hasIssue = true; + nextStack.serverDeploy = "none"; changed = true; changes.push({ category: "serverDeploy", message: - "Runtime set to 'Cloudflare Workers' (required by server deployment)", + "Server deployment disabled (Tip: Use Cloudflare Workers runtime + Hono backend to enable Wrangler)", }); - - if (nextStack.backend !== "hono") { - notes.runtime.notes.push( - "Cloudflare Workers runtime requires Hono backend. Hono will be selected.", - ); - notes.backend.notes.push( - "Cloudflare Workers runtime requires Hono backend. It will be selected.", - ); - notes.runtime.hasIssue = true; - notes.backend.hasIssue = true; - nextStack.backend = "hono"; - changes.push({ - category: "runtime", - message: "Backend set to 'Hono' (required by Cloudflare Workers)", - }); - } - - if (nextStack.orm !== "drizzle" && nextStack.orm !== "none") { - notes.runtime.notes.push( - "Cloudflare Workers runtime requires Drizzle ORM or no ORM. Drizzle will be selected.", - ); - notes.orm.notes.push( - "Cloudflare Workers runtime requires Drizzle ORM or no ORM. Drizzle will be selected.", - ); - notes.runtime.hasIssue = true; - notes.orm.hasIssue = true; - nextStack.orm = "drizzle"; - changes.push({ - category: "runtime", - message: "ORM set to 'Drizzle' (required by Cloudflare Workers)", - }); - } - - if (nextStack.database === "mongodb") { - notes.runtime.notes.push( - "Cloudflare Workers runtime is not compatible with MongoDB. SQLite will be selected.", - ); - notes.database.notes.push( - "MongoDB is not compatible with Cloudflare Workers runtime. SQLite will be selected.", - ); - notes.runtime.hasIssue = true; - notes.database.hasIssue = true; - nextStack.database = "sqlite"; - changes.push({ - category: "runtime", - message: - "Database set to 'SQLite' (MongoDB not compatible with Workers)", - }); - } - - if (nextStack.dbSetup === "docker") { - notes.runtime.notes.push( - "Cloudflare Workers runtime does not support Docker setup. D1 will be selected.", - ); - notes.dbSetup.notes.push( - "Docker setup is not compatible with Cloudflare Workers runtime. D1 will be selected.", - ); - notes.runtime.hasIssue = true; - notes.dbSetup.hasIssue = true; - nextStack.dbSetup = "d1"; - changes.push({ - category: "runtime", - message: "DB Setup set to 'D1' (Docker not compatible with Workers)", - }); - } } const isAlchemyWebDeploy = nextStack.webDeploy === "alchemy"; @@ -1121,7 +1114,7 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => { changed = true; changes.push({ category: "alchemy", - message: `Removed ${incompatibleFrontends.join(" and ")} (not compatible with Alchemy ${deployType})`, + message: `Removed ${incompatibleFrontends.join(" and ")} frontend (temporarily not compatible with Alchemy ${deployType} - support coming soon)`, }); } } @@ -1172,21 +1165,17 @@ const generateCommand = (stackState: StackState): string => { flags.push(`--backend ${stackState.backend}`); - if (stackState.backend !== "convex") { - flags.push(`--runtime ${stackState.runtime}`); + flags.push(`--runtime ${stackState.runtime}`); - flags.push(`--api ${stackState.api}`); + flags.push(`--api ${stackState.api}`); - flags.push(`--database ${stackState.database}`); + flags.push(`--auth ${stackState.auth}`); - flags.push(`--orm ${stackState.orm}`); + flags.push(`--database ${stackState.database}`); - flags.push(`--auth ${stackState.auth}`); + flags.push(`--orm ${stackState.orm}`); - flags.push(`--db-setup ${stackState.dbSetup}`); - } else { - flags.push(`--auth ${stackState.auth}`); - } + flags.push(`--db-setup ${stackState.dbSetup}`); flags.push(`--package-manager ${stackState.packageManager}`); @@ -1276,27 +1265,26 @@ const StackBuilder = () => { if ( ["webFrontend", "nativeFrontend", "addons", "examples"].includes(catKey) ) { - const currentValues: string[] = []; - randomStack[ - catKey as "webFrontend" | "nativeFrontend" | "addons" | "examples" - ] = currentValues; - if (catKey === "webFrontend" || catKey === "nativeFrontend") { const randomIndex = Math.floor(Math.random() * options.length); const selectedOption = options[randomIndex].id; - currentValues.push(selectedOption); - if (selectedOption === "none" && currentValues.length > 1) { - randomStack[catKey] = ["none"]; - } else if (selectedOption !== "none") { - randomStack[catKey] = currentValues.filter((id) => id !== "none"); - } + randomStack[catKey as "webFrontend" | "nativeFrontend"] = [ + selectedOption, + ]; } else { const numToPick = Math.floor( - Math.random() * Math.min(options.length + 1, 4), + Math.random() * Math.min(options.length, 4), ); - const shuffledOptions = [...options].sort(() => 0.5 - Math.random()); - for (let i = 0; i < numToPick; i++) { - currentValues.push(shuffledOptions[i].id); + if (numToPick === 0) { + randomStack[catKey as "addons" | "examples"] = ["none"]; + } else { + const shuffledOptions = [...options] + .filter((opt) => opt.id !== "none") + .sort(() => 0.5 - Math.random()) + .slice(0, numToPick); + randomStack[catKey as "addons" | "examples"] = shuffledOptions.map( + (opt) => opt.id, + ); } } } else { @@ -1475,18 +1463,26 @@ const StackBuilder = () => { } } setLastChanges(compatibilityAnalysis.changes); - setStack(compatibilityAnalysis.adjustedStack); + + const isStackDifferent = + JSON.stringify(stack) !== + JSON.stringify(compatibilityAnalysis.adjustedStack); + if (isStackDifferent) { + setStack(compatibilityAnalysis.adjustedStack); + } } }, [ compatibilityAnalysis.adjustedStack, setStack, compatibilityAnalysis.changes, + stack, ]); useEffect(() => { - const cmd = generateCommand(stack); + const stackToUse = compatibilityAnalysis.adjustedStack || stack; + const cmd = generateCommand(stackToUse); setCommand(cmd); - }, [stack]); + }, [stack, compatibilityAnalysis.adjustedStack]); useEffect(() => { setProjectNameError(validateProjectName(stack.projectName || ""));