create-better-t-stack 1.10.1 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -257,7 +257,7 @@ serve(
257
257
  `)}}async function Ze(e,a){let t=u.join(v,`template/with-${a}`);await l.pathExists(t)&&await l.copy(t,e,{overwrite:!0})}async function et(e,a,t,r){if(a==="none"||t==="none")return;let n=u.join(v,Qa(a,t));if(await l.pathExists(n)&&(await l.copy(n,e,{overwrite:!0}),!r)){if(a==="prisma"){let s=u.join(e,"apps/server/prisma/schema/auth.prisma");await l.pathExists(s)&&await l.remove(s)}else if(a==="drizzle"){let s=u.join(e,"apps/server/src/db/schema/auth.ts");await l.pathExists(s)&&await l.remove(s)}}}async function tt(e,a,t,r,n,s){if(!a)return;let o=u.join(v,"template/with-auth");if(await l.pathExists(o)){let i=s.includes("react-router"),p=s.includes("tanstack-router"),c=s.includes("tanstack-start");if(i||p||c){let E=u.join(e,"apps/web"),F=u.join(o,"apps/web-base");if(await l.pathExists(F)&&await l.copy(F,E,{overwrite:!0}),i){let C=u.join(o,"apps/web-react-router");await l.pathExists(C)&&await l.copy(C,E,{overwrite:!0})}if(p){let C=u.join(o,"apps/web-tanstack-router");await l.pathExists(C)&&await l.copy(C,E,{overwrite:!0})}if(c){let C=u.join(o,"apps/web-tanstack-start");await l.pathExists(C)&&await l.copy(C,E,{overwrite:!0})}}let d=u.join(o,"apps/server/src"),w=u.join(e,"apps/server/src");await l.copy(u.join(d,"lib/trpc.ts"),u.join(w,"lib/trpc.ts"),{overwrite:!0}),await l.copy(u.join(d,"routers/index.ts"),u.join(w,"routers/index.ts"),{overwrite:!0});let $=`with-${t}-context.ts`;await l.copy(u.join(d,"lib",$),u.join(w,"lib/context.ts"),{overwrite:!0});let A=`with-${t}-index.ts`;await l.copy(u.join(d,A),u.join(w,"index.ts"),{overwrite:!0});let Q=Ka(r,n),q=u.join(d,Q);if(await l.pathExists(q)){let E=await l.readdir(q);for(let F of E)await l.copy(u.join(q,F),u.join(w,"lib",F),{overwrite:!0})}if(s.includes("native")){let E=u.join(o,"apps/native"),F=u.join(e,"apps/native");await l.pathExists(E)&&await l.copy(E,F,{overwrite:!0}),g({dependencies:["@better-auth/expo"],projectDir:u.join(e,"apps/server")}),await Ha(e,r,n)}}}async function Ha(e,a,t){let r=u.join(e,"apps/server"),n;if(a==="drizzle"?t==="sqlite"?n=u.join(r,"src/lib/auth.ts"):t==="postgres"&&(n=u.join(r,"src/lib/auth.ts")):a==="prisma"&&(t==="sqlite"?n=u.join(r,"src/lib/auth.ts"):t==="postgres"&&(n=u.join(r,"src/lib/auth.ts"))),n&&await l.pathExists(n)){let s=await l.readFile(n,"utf8");if(!s.includes("@better-auth/expo")){let o=`import { expo } from "@better-auth/expo";
258
258
  `,i=s.lastIndexOf("import"),p=s.indexOf(`
259
259
  `,i)+1;s=s.substring(0,p)+o+s.substring(p)}s.includes("plugins:")?s.includes("expo()")||(s=s.replace(/plugins: \[(.*?)\]/s,(o,i)=>`plugins: [${i}${i.trim()?", ":""}expo()]`)):s=s.replace(/}\);/,` plugins: [expo()],
260
- });`),s.includes("my-better-t-app://")||(s=s.replace(/trustedOrigins: \[(.*?)\]/s,(o,i)=>`trustedOrigins: [${i}${i.trim()?", ":""}"my-better-t-app://"]`)),await l.writeFile(n,s)}}async function at(e){let a=await rt(e);for(let t of a)if(await l.pathExists(t)){let r=u.join(u.dirname(t),".gitignore");await l.move(t,r,{overwrite:!0})}}async function rt(e){let a=[],t=u.join(e,"_gitignore");await l.pathExists(t)&&a.push(t);try{let r=await l.readdir(e,{withFileTypes:!0});for(let n of r)if(n.isDirectory()&&n.name!=="node_modules"){let s=u.join(e,n.name),o=await rt(s);a.push(...o)}}catch{}return a}function Qa(e,a){if(e==="drizzle"){if(a==="sqlite")return"template/with-drizzle-sqlite";if(a==="postgres")return"template/with-drizzle-postgres";if(a==="mysql")return"template/with-drizzle-mysql"}if(e==="prisma"){if(a==="sqlite")return"template/with-prisma-sqlite";if(a==="postgres")return"template/with-prisma-postgres";if(a==="mysql")return"template/with-prisma-mysql";if(a==="mongodb")return"template/with-prisma-mongodb"}return"template/base"}function Ka(e,a){if(e==="drizzle"){if(a==="sqlite")return"with-drizzle-sqlite-lib";if(a==="postgres")return"with-drizzle-postgres-lib";if(a==="mysql")return"with-drizzle-mysql-lib"}if(e==="prisma"){if(a==="sqlite")return"with-prisma-sqlite-lib";if(a==="postgres")return"with-prisma-postgres-lib";if(a==="mysql")return"with-prisma-mysql-lib";if(a==="mongodb")return"with-prisma-mongodb-lib"}throw new Error("Invalid ORM or database configuration for auth setup")}async function st(e){let a=Za(),t=Xa.resolve(process.cwd(),e.projectName);try{return await er.ensureDir(t),await Xe(t),await Ye(t,e.frontend),await at(t),await Ze(t,e.backend),await Se(t,e.backend,e.runtime),await et(t,e.orm,e.database,e.auth),await ze(t,e.database,e.orm,e.packageManager,e.dbSetup==="turso",e.dbSetup==="prisma-postgres",e.dbSetup==="mongodb-atlas"),await tt(t,e.auth,e.backend,e.orm,e.database,e.frontend),await Ae(t,e.auth,e.frontend),await Ke(t,e.runtime,e.backend),await Ue(t,e.examples,e.orm,e.auth,e.backend,e.frontend),await Ne(t,e),await Qe(t,e.git),e.addons.length>0&&await ve(t,e.addons,e.packageManager,e.frontend),await He(t,e),await Ee(t,e),e.noInstall||await Ge({projectDir:t,packageManager:e.packageManager,addons:e.addons}),We(e.database,e.projectName,e.packageManager,!e.noInstall,e.orm,e.addons,e.runtime,e.frontend),t}catch(r){throw a.message(nt.red("Failed")),r instanceof Error&&(Ya(nt.red(`Error during project creation: ${r.message}`)),process.exit(1)),r}}import{cancel as Yr,group as Zr}from"@clack/prompts";import en from"picocolors";import{cancel as tr,isCancel as ar,multiselect as rr}from"@clack/prompts";import nr from"picocolors";async function ot(e,a){if(e!==void 0)return e;let t=a?.includes("react-router")||a?.includes("tanstack-router"),r=[{value:"biome",label:"Biome",hint:"Add Biome for linting and formatting"},{value:"husky",label:"Husky",hint:"Add Git hooks with Husky, lint-staged (requires Biome)"}],s=t?[...[{value:"pwa",label:"PWA (Progressive Web App)",hint:"Make your app installable and work offline"},{value:"tauri",label:"Tauri Desktop App",hint:"Build native desktop apps from your web frontend"}],...r]:r,o=P.addons.filter(p=>t||p!=="pwa"&&p!=="tauri"),i=await rr({message:"Select addons",options:s,initialValues:o,required:!1});return ar(i)&&(tr(nr.red("Operation cancelled")),process.exit(0)),i.includes("husky")&&!i.includes("biome")&&i.push("biome"),i}import{cancel as sr,confirm as or,isCancel as ir}from"@clack/prompts";import cr from"picocolors";async function it(e,a,t){if(!a)return!1;if(e!==void 0)return e;let r=await or({message:"Add authentication with Better-Auth?",initialValue:P.auth});return ir(r)&&(sr(cr.red("Operation cancelled")),process.exit(0)),r}import{cancel as pr,isCancel as lr,select as dr}from"@clack/prompts";import ur from"picocolors";async function ct(e){if(e!==void 0)return e;let a=await dr({message:"Select backend framework",options:[{value:"hono",label:"Hono",hint:"Lightweight, ultrafast web framework"},{value:"express",label:"Express",hint:"Fast, unopinionated, minimalist web framework for Node.js"},{value:"elysia",label:"Elysia",hint:"Ergonomic web framework for building backend servers"}],initialValue:P.backend});return lr(a)&&(pr(ur.red("Operation cancelled")),process.exit(0)),a}import{cancel as mr,isCancel as fr,select as hr}from"@clack/prompts";import gr from"picocolors";async function pt(e){if(e!==void 0)return e;let a=await hr({message:"Select database",options:[{value:"none",label:"None",hint:"No database setup"},{value:"sqlite",label:"SQLite",hint:"lightweight, server-less, embedded relational database management system"},{value:"postgres",label:"PostgreSQL",hint:"powerful, open source object-relational database system"},{value:"mysql",label:"MySQL",hint:"popular open-source relational database system"},{value:"mongodb",label:"MongoDB",hint:"open-source NoSQL database that stores data in JSON-like documents called BSON"}],initialValue:P.database});return fr(a)&&(mr(gr.red("Operation cancelled")),process.exit(0)),a}import{cancel as br,isCancel as wr,select as Pr}from"@clack/prompts";import yr from"picocolors";async function lt(e,a,t){if(a!==void 0)return a;if(e==="sqlite"&&t==="prisma")return"none";let r=[];if(e==="sqlite")r=[{value:"turso",label:"Turso",hint:"SQLite for Production. Powered by libSQL"},{value:"none",label:"None",hint:"Manual setup"}];else if(e==="postgres")r=[{value:"prisma-postgres",label:"Prisma Postgres",hint:"Instant Postgres for Global Applications"},{value:"none",label:"None",hint:"Manual setup"}];else if(e==="mongodb")r=[{value:"mongodb-atlas",label:"MongoDB Atlas",hint:"The most effective way to deploy MongoDB"},{value:"none",label:"None",hint:"Manual setup"}];else return"none";let n=await Pr({message:`Select ${e} setup option`,options:r,initialValue:"none"});return wr(n)&&(br(yr.red("Operation cancelled")),process.exit(0)),n}import{cancel as jr,isCancel as vr,multiselect as dt}from"@clack/prompts";import kr from"picocolors";async function ut(e,a,t,r){if(e!==void 0)return e;if(a==="none")return[];if(!(t?.includes("react-router")||t?.includes("tanstack-router")||t?.includes("tanstack-start")))return[];let s=[];return r==="elysia"&&(s=await dt({message:"Include examples",options:[{value:"todo",label:"Todo App",hint:"A simple CRUD example app"}],required:!1,initialValues:P.examples})),(r==="hono"||r==="express")&&(s=await dt({message:"Include examples",options:[{value:"todo",label:"Todo App",hint:"A simple CRUD example app"},{value:"ai",label:"AI Chat",hint:"A simple AI chat interface using AI SDK"}],required:!1,initialValues:P.examples})),vr(s)&&(jr(kr.red("Operation cancelled")),process.exit(0)),s}import{cancel as mt,isCancel as ft,multiselect as xr,select as $r}from"@clack/prompts";import ht from"picocolors";async function gt(e){if(e!==void 0)return e;let a=await xr({message:"Select platforms to develop for",options:[{value:"web",label:"Web",hint:"React Web Application"},{value:"native",label:"Native",hint:"Create a React Native/Expo app"}],required:!1,initialValues:P.frontend.some(r=>r==="tanstack-router"||r==="react-router"||r==="tanstack-start")?["web"]:[]});ft(a)&&(mt(ht.red("Operation cancelled")),process.exit(0));let t=[];if(a.includes("web")){let r=await $r({message:"Choose frontend framework",options:[{value:"tanstack-router",label:"TanStack Router",hint:"Modern and scalable routing for React Applications"},{value:"react-router",label:"React Router",hint:"A user\u2011obsessed, standards\u2011focused, multi\u2011strategy router you can deploy anywhere."},{value:"tanstack-start",label:"TanStack Start (beta)",hint:"SSR, Streaming, Server Functions, API Routes, bundling and more powered by TanStack Router and Vite."}],initialValue:P.frontend.find(n=>n==="tanstack-router"||n==="react-router"||n==="tanstack-start")||"tanstack-router"});ft(r)&&(mt(ht.red("Operation cancelled")),process.exit(0)),t.push(r)}return a.includes("native")&&t.push("native"),t}import{cancel as Ar,confirm as Sr,isCancel as Er}from"@clack/prompts";import Tr from"picocolors";async function bt(e){if(e!==void 0)return e;let a=await Sr({message:"Initialize git repository?",initialValue:P.git});return Er(a)&&(Ar(Tr.red("Operation cancelled")),process.exit(0)),a}import{cancel as Dr,confirm as Cr,isCancel as Rr}from"@clack/prompts";import Fr from"picocolors";async function wt(e){if(e!==void 0)return e;let a=await Cr({message:"Install dependencies?",initialValue:!P.noInstall});return Rr(a)&&(Dr(Fr.red("Operation cancelled")),process.exit(0)),!a}import{cancel as Ir,isCancel as Or,log as Br,select as Lr}from"@clack/prompts";import Mr from"picocolors";async function Pt(e,a,t){if(!a)return"none";if(e!==void 0)return e;if(t==="mongodb")return Br.info("Only Prisma is supported with MongoDB."),"prisma";let r=await Lr({message:"Select ORM",options:[{value:"drizzle",label:"Drizzle",hint:"lightweight and performant TypeScript ORM"},{value:"prisma",label:"Prisma",hint:"Powerful, feature-rich ORM"}],initialValue:P.orm});return Or(r)&&(Ir(Mr.red("Operation cancelled")),process.exit(0)),r}import{cancel as zr,isCancel as Nr,select as Ur}from"@clack/prompts";import _r from"picocolors";async function yt(e){if(e!==void 0)return e;let a=K(),t=await Ur({message:"Choose package manager",options:[{value:"npm",label:"npm",hint:"Node Package Manager"},{value:"pnpm",label:"pnpm",hint:"Fast, disk space efficient package manager"},{value:"bun",label:"bun",hint:"All-in-one JavaScript runtime & toolkit"}],initialValue:a});return Nr(t)&&(zr(_r.red("Operation cancelled")),process.exit(0)),t}import H from"node:path";import{cancel as qr,isCancel as Vr,text as Gr}from"@clack/prompts";import _ from"fs-extra";import Wr from"picocolors";var Jr=["<",">",":",'"',"|","?","*"],jt=255;function vt(e){if(e!=="."){if(!e)return"Project name cannot be empty";if(e.length>jt)return`Project name must be less than ${jt} characters`;if(Jr.some(a=>e.includes(a)))return"Project name contains invalid characters";if(e.startsWith(".")||e.startsWith("-"))return"Project name cannot start with a dot or dash";if(e.toLowerCase()==="node_modules")return"Project name is reserved"}}async function kt(e){if(e)if(e==="."){let s=process.cwd();if(_.readdirSync(s).length===0)return e}else{let s=H.basename(e);if(!vt(s)){let i=H.resolve(process.cwd(),e);if(!_.pathExistsSync(i)||_.readdirSync(i).length===0)return e}}let a=!1,t="",r=P.projectName,n=1;for(;_.pathExistsSync(H.resolve(process.cwd(),r));)r=`${P.projectName}-${n}`,n++;for(;!a;){let s=await Gr({message:"Enter your project name or path (relative to current directory)",placeholder:r,initialValue:e,defaultValue:r,validate:o=>{let i=o.trim()||r;if(i==="."){if(_.readdirSync(process.cwd()).length>0)return"Current directory is not empty. Please choose a different directory.";a=!0;return}let p=H.resolve(process.cwd(),i),c=H.basename(p),d=vt(c);if(d)return d;if(!p.startsWith(process.cwd()))return"Project path must be within current directory";if(_.pathExistsSync(p)&&_.readdirSync(p).length>0)return`Directory "${i}" already exists and is not empty. Please choose a different name or path.`;a=!0}});Vr(s)&&(qr(Wr.red("Operation cancelled.")),process.exit(0)),t=s||r}return t}import{cancel as Hr,isCancel as Qr,select as Kr}from"@clack/prompts";import Xr from"picocolors";async function xt(e){if(e!==void 0)return e;let a=await Kr({message:"Select runtime",options:[{value:"bun",label:"Bun",hint:"Fast all-in-one JavaScript runtime"},{value:"node",label:"Node.js",hint:"Traditional Node.js runtime"}],initialValue:P.runtime});return Qr(a)&&(Hr(Xr.red("Operation cancelled")),process.exit(0)),a}async function $t(e){let a=await Zr({projectName:async()=>kt(e.projectName),frontend:()=>gt(e.frontend),backend:()=>ct(e.backend),runtime:()=>xt(e.runtime),database:()=>pt(e.database),orm:({results:t})=>Pt(e.orm,t.database!=="none",t.database),auth:({results:t})=>it(e.auth,t.database!=="none",t.frontend),dbSetup:({results:t})=>lt(t.database??"none",e.dbSetup,t.orm),addons:({results:t})=>ot(e.addons,t.frontend),examples:({results:t})=>ut(e.examples,t.database,t.frontend,t.backend),git:()=>bt(e.git),packageManager:()=>yt(e.packageManager),noInstall:()=>wt(e.noInstall)},{onCancel:()=>{Yr(en.red("Operation cancelled")),process.exit(0)}});return{projectName:a.projectName,frontend:a.frontend,database:a.database,orm:a.orm,auth:a.auth,addons:a.addons,examples:a.examples,git:a.git,packageManager:a.packageManager,noInstall:a.noInstall,dbSetup:a.dbSetup,backend:a.backend,runtime:a.runtime}}import S from"picocolors";function fe(e){let a=[];if(e.projectName&&a.push(`${S.blue("Project Name:")} ${e.projectName}`),e.frontend!==void 0){let t=e.frontend.length>0?e.frontend.join(", "):"none";a.push(`${S.blue("Frontend:")} ${t}`)}if(e.backend!==void 0&&a.push(`${S.blue("Backend Framework:")} ${e.backend}`),e.runtime!==void 0&&a.push(`${S.blue("Runtime:")} ${e.runtime}`),e.database!==void 0&&a.push(`${S.blue("Database:")} ${e.database}`),e.orm!==void 0&&a.push(`${S.blue("ORM:")} ${e.orm}`),e.auth!==void 0&&a.push(`${S.blue("Authentication:")} ${e.auth}`),e.addons!==void 0){let t=e.addons.length>0?e.addons.join(", "):"none";a.push(`${S.blue("Addons:")} ${t}`)}if(e.examples!==void 0){let t=e.examples.length>0?e.examples.join(", "):"none";a.push(`${S.blue("Examples:")} ${t}`)}return e.git!==void 0&&a.push(`${S.blue("Git Init:")} ${e.git}`),e.packageManager!==void 0&&a.push(`${S.blue("Package Manager:")} ${e.packageManager}`),e.noInstall!==void 0&&a.push(`${S.blue("Skip Install:")} ${e.noInstall}`),e.dbSetup!==void 0&&a.push(`${S.blue("Database Setup:")} ${e.dbSetup}`),a.join(`
260
+ });`),s.includes("my-better-t-app://")||(s=s.replace(/trustedOrigins: \[(.*?)\]/s,(o,i)=>`trustedOrigins: [${i}${i.trim()?", ":""}"my-better-t-app://"]`)),await l.writeFile(n,s)}}async function at(e){let a=await rt(e);for(let t of a)if(await l.pathExists(t)){let r=u.join(u.dirname(t),".gitignore");await l.move(t,r,{overwrite:!0})}}async function rt(e){let a=[],t=u.join(e,"_gitignore");await l.pathExists(t)&&a.push(t);try{let r=await l.readdir(e,{withFileTypes:!0});for(let n of r)if(n.isDirectory()&&n.name!=="node_modules"){let s=u.join(e,n.name),o=await rt(s);a.push(...o)}}catch{}return a}function Qa(e,a){if(e==="drizzle"){if(a==="sqlite")return"template/with-drizzle-sqlite";if(a==="postgres")return"template/with-drizzle-postgres";if(a==="mysql")return"template/with-drizzle-mysql"}if(e==="prisma"){if(a==="sqlite")return"template/with-prisma-sqlite";if(a==="postgres")return"template/with-prisma-postgres";if(a==="mysql")return"template/with-prisma-mysql";if(a==="mongodb")return"template/with-prisma-mongodb"}return"template/base"}function Ka(e,a){if(e==="drizzle"){if(a==="sqlite")return"with-drizzle-sqlite-lib";if(a==="postgres")return"with-drizzle-postgres-lib";if(a==="mysql")return"with-drizzle-mysql-lib"}if(e==="prisma"){if(a==="sqlite")return"with-prisma-sqlite-lib";if(a==="postgres")return"with-prisma-postgres-lib";if(a==="mysql")return"with-prisma-mysql-lib";if(a==="mongodb")return"with-prisma-mongodb-lib"}throw new Error("Invalid ORM or database configuration for auth setup")}async function st(e){let a=Za(),t=Xa.resolve(process.cwd(),e.projectName);try{return await er.ensureDir(t),await Xe(t),await Ye(t,e.frontend),await at(t),await Ze(t,e.backend),await Se(t,e.backend,e.runtime),await et(t,e.orm,e.database,e.auth),await ze(t,e.database,e.orm,e.packageManager,e.dbSetup==="turso",e.dbSetup==="prisma-postgres",e.dbSetup==="mongodb-atlas"),await tt(t,e.auth,e.backend,e.orm,e.database,e.frontend),await Ae(t,e.auth,e.frontend),await Ke(t,e.runtime,e.backend),await Ue(t,e.examples,e.orm,e.auth,e.backend,e.frontend),await Ne(t,e),await Qe(t,e.git),e.addons.length>0&&await ve(t,e.addons,e.packageManager,e.frontend),await He(t,e),await Ee(t,e),e.noInstall||await Ge({projectDir:t,packageManager:e.packageManager,addons:e.addons}),We(e.database,e.projectName,e.packageManager,!e.noInstall,e.orm,e.addons,e.runtime,e.frontend),t}catch(r){throw a.message(nt.red("Failed")),r instanceof Error&&(Ya(nt.red(`Error during project creation: ${r.message}`)),process.exit(1)),r}}import{cancel as Yr,group as Zr}from"@clack/prompts";import en from"picocolors";import{cancel as tr,isCancel as ar,multiselect as rr}from"@clack/prompts";import nr from"picocolors";async function ot(e,a){if(e!==void 0)return e;let t=a?.includes("react-router")||a?.includes("tanstack-router"),r=[{value:"biome",label:"Biome",hint:"Add Biome for linting and formatting"},{value:"husky",label:"Husky",hint:"Add Git hooks with Husky, lint-staged (requires Biome)"}],s=t?[...[{value:"pwa",label:"PWA (Progressive Web App)",hint:"Make your app installable and work offline"},{value:"tauri",label:"Tauri Desktop App",hint:"Build native desktop apps from your web frontend"}],...r]:r,o=P.addons.filter(p=>t||p!=="pwa"&&p!=="tauri"),i=await rr({message:"Select addons",options:s,initialValues:o,required:!1});return ar(i)&&(tr(nr.red("Operation cancelled")),process.exit(0)),i.includes("husky")&&!i.includes("biome")&&i.push("biome"),i}import{cancel as sr,confirm as or,isCancel as ir}from"@clack/prompts";import cr from"picocolors";async function it(e,a,t){if(!a)return!1;if(e!==void 0)return e;let r=await or({message:"Add authentication with Better-Auth?",initialValue:P.auth});return ir(r)&&(sr(cr.red("Operation cancelled")),process.exit(0)),r}import{cancel as pr,isCancel as lr,select as dr}from"@clack/prompts";import ur from"picocolors";async function ct(e){if(e!==void 0)return e;let a=await dr({message:"Select backend framework",options:[{value:"hono",label:"Hono",hint:"Lightweight, ultrafast web framework"},{value:"express",label:"Express",hint:"Fast, unopinionated, minimalist web framework for Node.js"},{value:"elysia",label:"Elysia",hint:"Ergonomic web framework for building backend servers"}],initialValue:P.backend});return lr(a)&&(pr(ur.red("Operation cancelled")),process.exit(0)),a}import{cancel as mr,isCancel as fr,select as hr}from"@clack/prompts";import gr from"picocolors";async function pt(e){if(e!==void 0)return e;let a=await hr({message:"Select database",options:[{value:"none",label:"None",hint:"No database setup"},{value:"sqlite",label:"SQLite",hint:"lightweight, server-less, embedded relational database management system"},{value:"postgres",label:"PostgreSQL",hint:"powerful, open source object-relational database system"},{value:"mysql",label:"MySQL",hint:"popular open-source relational database system"},{value:"mongodb",label:"MongoDB",hint:"open-source NoSQL database that stores data in JSON-like documents called BSON"}],initialValue:P.database});return fr(a)&&(mr(gr.red("Operation cancelled")),process.exit(0)),a}import{cancel as br,isCancel as wr,select as Pr}from"@clack/prompts";import yr from"picocolors";async function lt(e,a,t){if(a!==void 0)return a;if(e==="sqlite"&&t==="prisma")return"none";let r=[];if(e==="sqlite")r=[{value:"turso",label:"Turso",hint:"SQLite for Production. Powered by libSQL"},{value:"none",label:"None",hint:"Manual setup"}];else if(e==="postgres"&&t==="prisma")r=[{value:"prisma-postgres",label:"Prisma Postgres",hint:"Instant Postgres for Global Applications"},{value:"none",label:"None",hint:"Manual setup"}];else if(e==="mongodb")r=[{value:"mongodb-atlas",label:"MongoDB Atlas",hint:"The most effective way to deploy MongoDB"},{value:"none",label:"None",hint:"Manual setup"}];else return"none";let n=await Pr({message:`Select ${e} setup option`,options:r,initialValue:"none"});return wr(n)&&(br(yr.red("Operation cancelled")),process.exit(0)),n}import{cancel as jr,isCancel as vr,multiselect as dt}from"@clack/prompts";import kr from"picocolors";async function ut(e,a,t,r){if(e!==void 0)return e;if(a==="none")return[];if(!(t?.includes("react-router")||t?.includes("tanstack-router")||t?.includes("tanstack-start")))return[];let s=[];return r==="elysia"&&(s=await dt({message:"Include examples",options:[{value:"todo",label:"Todo App",hint:"A simple CRUD example app"}],required:!1,initialValues:P.examples})),(r==="hono"||r==="express")&&(s=await dt({message:"Include examples",options:[{value:"todo",label:"Todo App",hint:"A simple CRUD example app"},{value:"ai",label:"AI Chat",hint:"A simple AI chat interface using AI SDK"}],required:!1,initialValues:P.examples})),vr(s)&&(jr(kr.red("Operation cancelled")),process.exit(0)),s}import{cancel as mt,isCancel as ft,multiselect as xr,select as $r}from"@clack/prompts";import ht from"picocolors";async function gt(e){if(e!==void 0)return e;let a=await xr({message:"Select platforms to develop for",options:[{value:"web",label:"Web",hint:"React Web Application"},{value:"native",label:"Native",hint:"Create a React Native/Expo app"}],required:!1,initialValues:P.frontend.some(r=>r==="tanstack-router"||r==="react-router"||r==="tanstack-start")?["web"]:[]});ft(a)&&(mt(ht.red("Operation cancelled")),process.exit(0));let t=[];if(a.includes("web")){let r=await $r({message:"Choose frontend framework",options:[{value:"tanstack-router",label:"TanStack Router",hint:"Modern and scalable routing for React Applications"},{value:"react-router",label:"React Router",hint:"A user\u2011obsessed, standards\u2011focused, multi\u2011strategy router you can deploy anywhere."},{value:"tanstack-start",label:"TanStack Start (beta)",hint:"SSR, Streaming, Server Functions, API Routes, bundling and more powered by TanStack Router and Vite."}],initialValue:P.frontend.find(n=>n==="tanstack-router"||n==="react-router"||n==="tanstack-start")||"tanstack-router"});ft(r)&&(mt(ht.red("Operation cancelled")),process.exit(0)),t.push(r)}return a.includes("native")&&t.push("native"),t}import{cancel as Ar,confirm as Sr,isCancel as Er}from"@clack/prompts";import Tr from"picocolors";async function bt(e){if(e!==void 0)return e;let a=await Sr({message:"Initialize git repository?",initialValue:P.git});return Er(a)&&(Ar(Tr.red("Operation cancelled")),process.exit(0)),a}import{cancel as Dr,confirm as Cr,isCancel as Rr}from"@clack/prompts";import Fr from"picocolors";async function wt(e){if(e!==void 0)return e;let a=await Cr({message:"Install dependencies?",initialValue:!P.noInstall});return Rr(a)&&(Dr(Fr.red("Operation cancelled")),process.exit(0)),!a}import{cancel as Ir,isCancel as Or,log as Br,select as Lr}from"@clack/prompts";import Mr from"picocolors";async function Pt(e,a,t){if(!a)return"none";if(e!==void 0)return e;if(t==="mongodb")return Br.info("Only Prisma is supported with MongoDB."),"prisma";let r=await Lr({message:"Select ORM",options:[{value:"drizzle",label:"Drizzle",hint:"lightweight and performant TypeScript ORM"},{value:"prisma",label:"Prisma",hint:"Powerful, feature-rich ORM"}],initialValue:P.orm});return Or(r)&&(Ir(Mr.red("Operation cancelled")),process.exit(0)),r}import{cancel as zr,isCancel as Nr,select as Ur}from"@clack/prompts";import _r from"picocolors";async function yt(e){if(e!==void 0)return e;let a=K(),t=await Ur({message:"Choose package manager",options:[{value:"npm",label:"npm",hint:"Node Package Manager"},{value:"pnpm",label:"pnpm",hint:"Fast, disk space efficient package manager"},{value:"bun",label:"bun",hint:"All-in-one JavaScript runtime & toolkit"}],initialValue:a});return Nr(t)&&(zr(_r.red("Operation cancelled")),process.exit(0)),t}import H from"node:path";import{cancel as qr,isCancel as Vr,text as Gr}from"@clack/prompts";import _ from"fs-extra";import Wr from"picocolors";var Jr=["<",">",":",'"',"|","?","*"],jt=255;function vt(e){if(e!=="."){if(!e)return"Project name cannot be empty";if(e.length>jt)return`Project name must be less than ${jt} characters`;if(Jr.some(a=>e.includes(a)))return"Project name contains invalid characters";if(e.startsWith(".")||e.startsWith("-"))return"Project name cannot start with a dot or dash";if(e.toLowerCase()==="node_modules")return"Project name is reserved"}}async function kt(e){if(e)if(e==="."){let s=process.cwd();if(_.readdirSync(s).length===0)return e}else{let s=H.basename(e);if(!vt(s)){let i=H.resolve(process.cwd(),e);if(!_.pathExistsSync(i)||_.readdirSync(i).length===0)return e}}let a=!1,t="",r=P.projectName,n=1;for(;_.pathExistsSync(H.resolve(process.cwd(),r));)r=`${P.projectName}-${n}`,n++;for(;!a;){let s=await Gr({message:"Enter your project name or path (relative to current directory)",placeholder:r,initialValue:e,defaultValue:r,validate:o=>{let i=o.trim()||r;if(i==="."){if(_.readdirSync(process.cwd()).length>0)return"Current directory is not empty. Please choose a different directory.";a=!0;return}let p=H.resolve(process.cwd(),i),c=H.basename(p),d=vt(c);if(d)return d;if(!p.startsWith(process.cwd()))return"Project path must be within current directory";if(_.pathExistsSync(p)&&_.readdirSync(p).length>0)return`Directory "${i}" already exists and is not empty. Please choose a different name or path.`;a=!0}});Vr(s)&&(qr(Wr.red("Operation cancelled.")),process.exit(0)),t=s||r}return t}import{cancel as Hr,isCancel as Qr,select as Kr}from"@clack/prompts";import Xr from"picocolors";async function xt(e){if(e!==void 0)return e;let a=await Kr({message:"Select runtime",options:[{value:"bun",label:"Bun",hint:"Fast all-in-one JavaScript runtime"},{value:"node",label:"Node.js",hint:"Traditional Node.js runtime"}],initialValue:P.runtime});return Qr(a)&&(Hr(Xr.red("Operation cancelled")),process.exit(0)),a}async function $t(e){let a=await Zr({projectName:async()=>kt(e.projectName),frontend:()=>gt(e.frontend),backend:()=>ct(e.backend),runtime:()=>xt(e.runtime),database:()=>pt(e.database),orm:({results:t})=>Pt(e.orm,t.database!=="none",t.database),auth:({results:t})=>it(e.auth,t.database!=="none",t.frontend),dbSetup:({results:t})=>lt(t.database??"none",e.dbSetup,t.orm),addons:({results:t})=>ot(e.addons,t.frontend),examples:({results:t})=>ut(e.examples,t.database,t.frontend,t.backend),git:()=>bt(e.git),packageManager:()=>yt(e.packageManager),noInstall:()=>wt(e.noInstall)},{onCancel:()=>{Yr(en.red("Operation cancelled")),process.exit(0)}});return{projectName:a.projectName,frontend:a.frontend,database:a.database,orm:a.orm,auth:a.auth,addons:a.addons,examples:a.examples,git:a.git,packageManager:a.packageManager,noInstall:a.noInstall,dbSetup:a.dbSetup,backend:a.backend,runtime:a.runtime}}import S from"picocolors";function fe(e){let a=[];if(e.projectName&&a.push(`${S.blue("Project Name:")} ${e.projectName}`),e.frontend!==void 0){let t=e.frontend.length>0?e.frontend.join(", "):"none";a.push(`${S.blue("Frontend:")} ${t}`)}if(e.backend!==void 0&&a.push(`${S.blue("Backend Framework:")} ${e.backend}`),e.runtime!==void 0&&a.push(`${S.blue("Runtime:")} ${e.runtime}`),e.database!==void 0&&a.push(`${S.blue("Database:")} ${e.database}`),e.orm!==void 0&&a.push(`${S.blue("ORM:")} ${e.orm}`),e.auth!==void 0&&a.push(`${S.blue("Authentication:")} ${e.auth}`),e.addons!==void 0){let t=e.addons.length>0?e.addons.join(", "):"none";a.push(`${S.blue("Addons:")} ${t}`)}if(e.examples!==void 0){let t=e.examples.length>0?e.examples.join(", "):"none";a.push(`${S.blue("Examples:")} ${t}`)}return e.git!==void 0&&a.push(`${S.blue("Git Init:")} ${e.git}`),e.packageManager!==void 0&&a.push(`${S.blue("Package Manager:")} ${e.packageManager}`),e.noInstall!==void 0&&a.push(`${S.blue("Skip Install:")} ${e.noInstall}`),e.dbSetup!==void 0&&a.push(`${S.blue("Database Setup:")} ${e.dbSetup}`),a.join(`
261
261
  `)}function At(e){let a=[];e.database==="none"?a.push("--database none"):(a.push(`--database ${e.database}`),e.orm&&a.push(`--orm ${e.orm}`),e.dbSetup&&a.push(`--db-setup ${e.dbSetup}`)),a.push(e.auth?"--auth":"--no-auth"),a.push(e.git?"--git":"--no-git"),a.push(e.noInstall?"--no-install":"--install"),e.runtime&&a.push(`--runtime ${e.runtime}`),e.backend&&a.push(`--backend ${e.backend}`),e.frontend&&e.frontend.length>0&&a.push(`--frontend ${e.frontend.join(" ")}`),e.addons&&e.addons.length>0?a.push(`--addons ${e.addons.join(" ")}`):a.push("--addons none"),e.examples&&e.examples.length>0?a.push(`--examples ${e.examples.join(" ")}`):a.push("--no-examples"),e.packageManager&&a.push(`--package-manager ${e.packageManager}`);let t="",r=e.packageManager;r==="npm"?t="npx create-better-t-stack@latest":r==="pnpm"?t="pnpm create better-t-stack@latest":r==="bun"&&(t="bun create better-t-stack@latest");let n=e.projectName?` ${e.projectName}`:"";return`${t}${n} ${a.join(" ")}`}import tn from"node:path";import an from"fs-extra";var St=()=>{let e=tn.join(v,"package.json");return an.readJSONSync(e).version??"1.0.0"};import Et from"gradient-string";var Tt=`
262
262
  \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
263
263
  \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "1.10.1",
3
+ "version": "1.10.2",
4
4
  "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
5
5
  "type": "module",
6
6
  "license": "MIT",