create-better-t-stack 1.10.2 → 1.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{cancel as j,intro as rn,log as D,outro as nn,spinner as sn}from"@clack/prompts";import{Command as on}from"commander";import h from"picocolors";import we from"node:path";import{fileURLToPath as Ot}from"node:url";var K=()=>{let e=process.env.npm_config_user_agent;return e?.startsWith("pnpm")?"pnpm":e?.startsWith("bun")?"bun":"npm"};var Bt=Ot(import.meta.url),Lt=we.dirname(Bt),v=we.join(Lt,"../"),P={projectName:"my-better-t-app",frontend:["tanstack-router"],database:"sqlite",orm:"drizzle",auth:!0,addons:[],examples:[],git:!0,packageManager:K(),noInstall:!1,dbSetup:"none",backend:"hono",runtime:"bun"},se={"better-auth":"^1.2.4","@better-auth/expo":"^1.2.5","drizzle-orm":"^0.38.4","drizzle-kit":"^0.30.5","@libsql/client":"^0.14.0",
|
|
2
|
+
import{cancel as j,intro as rn,log as D,outro as nn,spinner as sn}from"@clack/prompts";import{Command as on}from"commander";import h from"picocolors";import we from"node:path";import{fileURLToPath as Ot}from"node:url";var K=()=>{let e=process.env.npm_config_user_agent;return e?.startsWith("pnpm")?"pnpm":e?.startsWith("bun")?"bun":"npm"};var Bt=Ot(import.meta.url),Lt=we.dirname(Bt),v=we.join(Lt,"../"),P={projectName:"my-better-t-app",frontend:["tanstack-router"],database:"sqlite",orm:"drizzle",auth:!0,addons:[],examples:[],git:!0,packageManager:K(),noInstall:!1,dbSetup:"none",backend:"hono",runtime:"bun"},se={"better-auth":"^1.2.4","@better-auth/expo":"^1.2.5","drizzle-orm":"^0.38.4","drizzle-kit":"^0.30.5","@libsql/client":"^0.14.0",pg:"^8.14.1","@types/pg":"^8.11.11",mysql2:"^3.14.0","@prisma/client":"^6.5.0",prisma:"^6.5.0","vite-plugin-pwa":"^0.21.2","@vite-pwa/assets-generator":"^0.2.6","@tauri-apps/cli":"^2.4.0","@biomejs/biome":"1.9.4",husky:"^9.1.7","lint-staged":"^15.5.0","@hono/node-server":"^1.14.0",tsx:"^4.19.2","@types/node":"^22.13.11","@types/bun":"^1.2.6","@elysiajs/node":"^1.2.6","@elysiajs/cors":"^1.2.0","@elysiajs/trpc":"^1.1.0",elysia:"^1.2.25","@hono/trpc-server":"^0.3.4",hono:"^4.7.5",cors:"^2.8.5",express:"^5.1.0","@types/express":"^5.0.1","@types/cors":"^2.8.17",ai:"^4.2.8","@ai-sdk/google":"^1.2.3","@prisma/extension-accelerate":"^1.3.0"};import Xa from"node:path";import{cancel as Ya,spinner as Za}from"@clack/prompts";import er from"fs-extra";import nt from"picocolors";import I from"node:path";import k from"fs-extra";import Mt from"node:path";import Pe from"fs-extra";var g=e=>{let{dependencies:a=[],devDependencies:t=[],projectDir:r}=e,n=Mt.join(r,"package.json"),s=Pe.readJSONSync(n);s.dependencies||(s.dependencies={}),s.devDependencies||(s.devDependencies={});for(let o of a){let i=se[o];s.dependencies[o]=i}for(let o of t){let i=se[o];s.devDependencies[o]=i}Pe.writeJSONSync(n,s,{spaces:2})};import X from"node:path";import{log as zt,spinner as Nt}from"@clack/prompts";import{execa as Ut}from"execa";import Y from"fs-extra";import ye from"picocolors";async function je(e,a,t){let r=Nt(),n=X.join(e,"apps/web");if(await Y.pathExists(n))try{r.start("Setting up Tauri desktop app support..."),g({devDependencies:["@tauri-apps/cli"],projectDir:n});let s=X.join(n,"package.json");if(await Y.pathExists(s)){let d=await Y.readJson(s);d.scripts={...d.scripts,tauri:"tauri","desktop:dev":"tauri dev","desktop:build":"tauri build"},await Y.writeJson(s,d,{spaces:2})}let o,i;switch(a){case"npm":o="npx",i=["@tauri-apps/cli@latest"];break;case"pnpm":o="pnpm",i=["dlx","@tauri-apps/cli@latest"];break;case"bun":o="bunx",i=["@tauri-apps/cli@latest"];break;default:o="npx",i=["@tauri-apps/cli@latest"]}let c=t.includes("react-router")?"http://localhost:5173":"http://localhost:3001";i=[...i,"init",`--app-name=${X.basename(e)}`,`--window-title=${X.basename(e)}`,"--frontend-dist=dist",`--dev-url=${c}`,`--before-dev-command=${a} run dev`,`--before-build-command=${a} run build`],await Ut(o,i,{cwd:n,env:{CI:"true"}}),r.stop("Tauri desktop app support configured successfully!")}catch(s){throw r.stop(ye.red("Failed to set up Tauri")),s instanceof Error&&zt.error(ye.red(s.message)),s}}async function ve(e,a,t,r){let n=r.includes("react-router")||r.includes("tanstack-router");a.includes("pwa")&&n&&await Gt(e,r),a.includes("tauri")&&n&&await je(e,t,r),a.includes("biome")&&await qt(e),a.includes("husky")&&await Vt(e)}function _t(e,a){return I.join(e,"apps/web")}async function qt(e){let a=I.join(v,"template/with-biome");await k.pathExists(a)&&await k.copy(a,e,{overwrite:!0}),g({devDependencies:["@biomejs/biome"],projectDir:e});let t=I.join(e,"package.json");if(await k.pathExists(t)){let r=await k.readJson(t);r.scripts={...r.scripts,check:"biome check --write ."},await k.writeJson(t,r,{spaces:2})}}async function Vt(e){let a=I.join(v,"template/with-husky");await k.pathExists(a)&&await k.copy(a,e,{overwrite:!0}),g({devDependencies:["husky","lint-staged"],projectDir:e});let t=I.join(e,"package.json");if(await k.pathExists(t)){let r=await k.readJson(t);r.scripts={...r.scripts,prepare:"husky"},r["lint-staged"]={"*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}":["biome check --write ."]},await k.writeJson(t,r,{spaces:2})}}async function Gt(e,a){let t=I.join(v,"template/with-pwa");await k.pathExists(t)&&await k.copy(t,e,{overwrite:!0});let r=_t(e,a);if(!await k.pathExists(r))return;g({dependencies:["vite-plugin-pwa"],devDependencies:["@vite-pwa/assets-generator"],projectDir:r});let n=I.join(r,"vite.config.ts");if(await k.pathExists(n)){let o=await k.readFile(n,"utf8");if(!o.includes("vite-plugin-pwa")){let p=o.match(/^import .* from ['"](.*)['"]/m);p?o=o.replace(p[0],`import { VitePWA } from "vite-plugin-pwa";
|
|
3
3
|
${p[0]}`):o=`import { VitePWA } from "vite-plugin-pwa";
|
|
4
4
|
${o}`}let i=`VitePWA({
|
|
5
5
|
registerType: "autoUpdate",
|
|
@@ -136,7 +136,7 @@ DATABASE_AUTH_TOKEN=`;await ha.writeFile(t,r)}function ee(){G.info(`Manual Turso
|
|
|
136
136
|
4. Add these credentials to the .env file in apps/server/.env
|
|
137
137
|
|
|
138
138
|
DATABASE_URL=your_database_url
|
|
139
|
-
DATABASE_AUTH_TOKEN=your_auth_token`)}async function Be(e,a){if(!a){await J(e),G.info(T.blue("Skipping Turso setup. Setting up empty configuration.")),ee();return}let t=da.platform(),r=t==="darwin";if(!(t!=="win32")){G.warn(T.yellow("Automatic Turso setup is not supported on Windows.")),await J(e),ee();return}try{if(!await ga()){let w=await ua({message:"Would you like to install Turso CLI?",initialValue:!0});if(de(w)&&(le(T.red("Operation cancelled")),process.exit(0)),!w){await J(e),ee();return}await Pa(r)}await ba()||await wa();let i=await ja(),p=!1,c="",d=Oe.basename(e);for(;!p;){let w=await fa({message:"Enter a name for your database:",defaultValue:d,initialValue:d,placeholder:d});de(w)&&(le(T.red("Operation cancelled")),process.exit(0)),c=w;let $=ue();try{$.start(`Creating Turso database "${c}"${i?` in group "${i}"`:""}...`);let A=await va(c,i);await J(e,A),$.stop("Turso database configured successfully!"),p=!0}catch(A){if(A instanceof Error&&A.message==="DATABASE_EXISTS")$.stop(T.yellow(`Database "${T.red(c)}" already exists`)),d=`${c}-${Math.floor(Math.random()*1e3)}`;else throw $.stop(T.red("Failed to create Turso database")),A}}}catch(s){G.error(T.red(`Error during Turso setup: ${s}`)),await J(e),ee(),G.success("Setup completed with manual configuration required.")}}async function ze(e,a,t,r,n,s,o){let i=xa(),p=Le.join(e,"apps/server");if(a==="none"){await $a.remove(Le.join(p,"src/db"));return}try{t==="prisma"?g({dependencies:["@prisma/client"],devDependencies:["prisma"],projectDir:p}):t==="drizzle"&&(a==="sqlite"?g({dependencies:["drizzle-orm","@libsql/client"],devDependencies:["drizzle-kit"],projectDir:p}):a==="postgres"?g({dependencies:["drizzle-orm","
|
|
139
|
+
DATABASE_AUTH_TOKEN=your_auth_token`)}async function Be(e,a){if(!a){await J(e),G.info(T.blue("Skipping Turso setup. Setting up empty configuration.")),ee();return}let t=da.platform(),r=t==="darwin";if(!(t!=="win32")){G.warn(T.yellow("Automatic Turso setup is not supported on Windows.")),await J(e),ee();return}try{if(!await ga()){let w=await ua({message:"Would you like to install Turso CLI?",initialValue:!0});if(de(w)&&(le(T.red("Operation cancelled")),process.exit(0)),!w){await J(e),ee();return}await Pa(r)}await ba()||await wa();let i=await ja(),p=!1,c="",d=Oe.basename(e);for(;!p;){let w=await fa({message:"Enter a name for your database:",defaultValue:d,initialValue:d,placeholder:d});de(w)&&(le(T.red("Operation cancelled")),process.exit(0)),c=w;let $=ue();try{$.start(`Creating Turso database "${c}"${i?` in group "${i}"`:""}...`);let A=await va(c,i);await J(e,A),$.stop("Turso database configured successfully!"),p=!0}catch(A){if(A instanceof Error&&A.message==="DATABASE_EXISTS")$.stop(T.yellow(`Database "${T.red(c)}" already exists`)),d=`${c}-${Math.floor(Math.random()*1e3)}`;else throw $.stop(T.red("Failed to create Turso database")),A}}}catch(s){G.error(T.red(`Error during Turso setup: ${s}`)),await J(e),ee(),G.success("Setup completed with manual configuration required.")}}async function ze(e,a,t,r,n,s,o){let i=xa(),p=Le.join(e,"apps/server");if(a==="none"){await $a.remove(Le.join(p,"src/db"));return}try{t==="prisma"?g({dependencies:["@prisma/client"],devDependencies:["prisma"],projectDir:p}):t==="drizzle"&&(a==="sqlite"?g({dependencies:["drizzle-orm","@libsql/client"],devDependencies:["drizzle-kit"],projectDir:p}):a==="postgres"?g({dependencies:["drizzle-orm","pg"],devDependencies:["drizzle-kit","@types/pg"],projectDir:p}):a==="mysql"&&g({dependencies:["drizzle-orm","mysql2"],devDependencies:["drizzle-kit"],projectDir:p})),a==="sqlite"&&n?await Be(e,t==="drizzle"):a==="postgres"&&t==="prisma"&&s?await Ie(e,r):a==="mongodb"&&o&&await Re(e)}catch(c){throw i.stop(Me.red("Failed to set up database")),c instanceof Error&&ka.error(Me.red(c.message)),c}}import U from"node:path";import te from"fs-extra";async function me(e,a){await te.ensureDir(U.dirname(e));let t="";await te.pathExists(e)&&(t=await te.readFile(e,"utf8"));let r=!1;for(let{key:n,value:s,condition:o}of a)if(o){let i=new RegExp(`^${n}=.*$`,"m");i.test(t)?s&&(t=t.replace(i,`${n}=${s}`),r=!0):(t+=`
|
|
140
140
|
${n}=${s}`,r=!0)}r&&await te.writeFile(e,t.trim())}async function Ne(e,a){let t=U.join(e,"apps/server"),r=U.join(t,".env"),n=a.frontend.includes("react-router"),s=a.frontend.includes("tanstack-router"),o=a.frontend.includes("tanstack-start"),i=n||s||o,p="http://localhost:3000";n?p="http://localhost:5173":(s||o)&&(p="http://localhost:3001");let c="",d=a.dbSetup==="turso"||a.dbSetup==="prisma-postgres"||a.dbSetup==="mongodb-atlas";d||(a.database==="postgres"?c="postgresql://postgres:postgres@localhost:5432/mydb?schema=public":a.database==="mysql"?c="mysql://root:password@localhost:3306/mydb":a.database==="mongodb"?c="mongodb://localhost:27017/mydatabase":a.database==="sqlite"&&(c="file:./local.db"));let w=[{key:"CORS_ORIGIN",value:p,condition:!0},{key:"BETTER_AUTH_SECRET",value:$e(),condition:!!a.auth},{key:"BETTER_AUTH_URL",value:"http://localhost:3000",condition:!!a.auth},{key:"DATABASE_URL",value:c,condition:a.database!=="none"&&c!==""&&!d},{key:"GOOGLE_GENERATIVE_AI_API_KEY",value:"",condition:a.examples?.includes("ai")||!1}];if(await me(r,w),i){let $=U.join(e,"apps/web"),A=[{key:"VITE_SERVER_URL",value:"http://localhost:3000",condition:!0}];await me(U.join($,".env"),A)}if(a.frontend.includes("native")){let $=U.join(e,"apps/native"),A=[{key:"EXPO_PUBLIC_SERVER_URL",value:"http://localhost:3000",condition:!0}];await me(U.join($,".env"),A)}}import x from"node:path";import b from"fs-extra";async function Ue(e,a,t,r,n,s=["tanstack-router"]){let o=s.includes("tanstack-router"),i=s.includes("tanstack-start"),p=s.includes("react-router"),c=o||p||i,d;o?d="web-tanstack-router":i?d="web-tanstack-start":d="web-react-router";let w=await b.pathExists(x.join(e,"apps/web"));a.includes("todo")&&c&&w?await Ta(e,t,r,d):await Ra(e,t),a.includes("ai")&&(n==="hono"||n==="express")&&c&&w&&await Aa(e,d)}async function Aa(e,a){let t=x.join(v,"template/examples/ai");if(await b.pathExists(t)){let r=x.join(t,`apps/${a}/src/routes/ai.tsx`),n=x.join(e,"apps/web/src/routes/ai.tsx");await b.pathExists(r)&&await b.copy(r,n,{overwrite:!0}),await Ea(e,a);let s=x.join(e,"apps/web");g({dependencies:["ai"],projectDir:s});let o=x.join(e,"apps/server");g({dependencies:["ai","@ai-sdk/google"],projectDir:o}),await Sa(e)}}async function Sa(e){let a=x.join(e,"apps/server/src/index.ts");if(await b.pathExists(a)){let t=await b.readFile(a,"utf8"),r=t.includes("hono"),n=t.includes("express");if(r){let s=`import { streamText } from "ai";
|
|
141
141
|
import { google } from "@ai-sdk/google";
|
|
142
142
|
import { stream } from "hono/streaming";`,o=`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-better-t-stack",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.3",
|
|
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",
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { drizzle } from "drizzle-orm/postgres
|
|
2
|
-
import postgres from "postgres";
|
|
1
|
+
import { drizzle } from "drizzle-orm/node-postgres";
|
|
3
2
|
|
|
4
|
-
const
|
|
5
|
-
export const db = drizzle({ client: queryClient });
|
|
3
|
+
export const db = drizzle(process.env.DATABASE_URL || "");
|