create-better-t-stack 2.49.0 → 2.49.1-canary.80158905
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-DXyLKhXK.js → src-CyG8-I-3.js} +289 -157
- package/package.json +1 -1
- package/templates/api/orpc/server/base/_gitignore +34 -0
- package/templates/api/orpc/server/base/package.json.hbs +24 -0
- package/templates/{backend/server/server-base → api/orpc/server/base}/src/routers/index.ts.hbs +2 -2
- package/templates/api/orpc/server/base/tsconfig.json.hbs +10 -0
- package/templates/api/orpc/server/base/tsdown.config.ts.hbs +7 -0
- package/templates/api/orpc/server/{base/src/lib → rest/src}/context.ts.hbs +5 -5
- package/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs +1 -1
- package/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs +1 -1
- package/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs +1 -1
- package/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs +1 -1
- package/templates/api/trpc/server/base/_gitignore +34 -0
- package/templates/api/trpc/server/base/package.json.hbs +23 -0
- package/templates/api/trpc/server/base/src/routers/index.ts.hbs +55 -0
- package/templates/api/trpc/server/base/tsconfig.json.hbs +13 -0
- package/templates/api/trpc/server/base/tsdown.config.ts.hbs +7 -0
- package/templates/api/trpc/server/{base/src/lib → rest/src}/context.ts.hbs +5 -5
- package/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs +2 -2
- package/templates/auth/better-auth/server/base/_gitignore +34 -0
- package/templates/auth/better-auth/server/base/package.json.hbs +24 -0
- package/templates/auth/better-auth/server/base/src/{lib/auth.ts.hbs → index.ts.hbs} +6 -6
- package/templates/auth/better-auth/server/base/tsconfig.json.hbs +13 -0
- package/templates/auth/better-auth/server/base/tsdown.config.ts.hbs +7 -0
- package/templates/backend/server/{server-base → base}/package.json.hbs +0 -1
- package/templates/backend/server/{server-base → base}/tsconfig.json.hbs +5 -10
- package/templates/backend/server/base/tsdown.config.ts.hbs +14 -0
- package/templates/backend/server/elysia/src/index.ts.hbs +5 -5
- package/templates/backend/server/express/src/index.ts.hbs +5 -5
- package/templates/backend/server/fastify/src/index.ts.hbs +5 -5
- package/templates/backend/server/hono/src/index.ts.hbs +5 -5
- package/templates/base/_gitignore +47 -1
- package/templates/base/package.json.hbs +1 -3
- package/templates/base/tsconfig.base.json +23 -0
- package/templates/db/base/_gitignore +34 -0
- package/templates/db/base/package.json.hbs +23 -0
- package/templates/db/base/tsconfig.json.hbs +13 -0
- package/templates/db/base/tsdown.config.ts.hbs +7 -0
- package/templates/db/drizzle/mysql/drizzle.config.ts.hbs +7 -2
- package/templates/db/drizzle/postgres/drizzle.config.ts.hbs +7 -2
- package/templates/db/drizzle/sqlite/drizzle.config.ts.hbs +7 -2
- package/templates/db/prisma/mongodb/prisma.config.ts.hbs +5 -1
- package/templates/db/prisma/mongodb/src/index.ts.hbs +5 -0
- package/templates/db/prisma/mysql/prisma.config.ts.hbs +5 -1
- package/templates/db/prisma/mysql/src/{db/index.ts.hbs → index.ts.hbs} +1 -1
- package/templates/db/prisma/postgres/prisma.config.ts.hbs +7 -3
- package/templates/db/prisma/postgres/src/{db/index.ts.hbs → index.ts.hbs} +1 -1
- package/templates/db/prisma/sqlite/prisma.config.ts.hbs +5 -1
- package/templates/db/prisma/sqlite/src/{db/index.ts.hbs → index.ts.hbs} +3 -3
- package/templates/examples/todo/server/drizzle/base/src/routers/todo.ts.hbs +6 -6
- package/templates/examples/todo/server/mongoose/base/src/routers/todo.ts.hbs +4 -4
- package/templates/examples/todo/server/prisma/base/src/routers/todo.ts.hbs +4 -4
- package/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs +1 -1
- package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +1 -1
- package/templates/db/prisma/mongodb/src/db/index.ts.hbs +0 -5
- /package/templates/api/orpc/server/{base/src/lib/orpc.ts.hbs → rest/src/index.ts.hbs} +0 -0
- /package/templates/api/trpc/server/{base/src/lib/trpc.ts.hbs → rest/src/index.ts.hbs} +0 -0
- /package/templates/auth/better-auth/server/db/drizzle/mysql/src/{db/schema → schema}/auth.ts +0 -0
- /package/templates/auth/better-auth/server/db/drizzle/postgres/src/{db/schema → schema}/auth.ts +0 -0
- /package/templates/auth/better-auth/server/db/drizzle/sqlite/src/{db/schema → schema}/auth.ts +0 -0
- /package/templates/auth/better-auth/server/db/mongoose/mongodb/src/{db/models → models}/auth.model.ts +0 -0
- /package/templates/backend/server/{server-base → base}/_gitignore +0 -0
- /package/templates/db/drizzle/mysql/src/{db/index.ts.hbs → index.ts.hbs} +0 -0
- /package/templates/db/drizzle/postgres/src/{db/index.ts.hbs → index.ts.hbs} +0 -0
- /package/templates/db/drizzle/sqlite/src/{db/index.ts.hbs → index.ts.hbs} +0 -0
- /package/templates/db/mongoose/mongodb/src/{db/index.ts.hbs → index.ts.hbs} +0 -0
- /package/templates/examples/todo/server/mongoose/mongodb/src/db/models/{todo.model.ts → todo.model.ts.hbs} +0 -0
- /package/templates/examples/todo/server/prisma/mongodb/prisma/schema/{todo.prisma → todo.prisma.hbs} +0 -0
- /package/templates/examples/todo/server/prisma/mysql/prisma/schema/{todo.prisma → todo.prisma.hbs} +0 -0
- /package/templates/examples/todo/server/prisma/postgres/prisma/schema/{todo.prisma → todo.prisma.hbs} +0 -0
- /package/templates/examples/todo/server/prisma/sqlite/prisma/schema/{todo.prisma → todo.prisma.hbs} +0 -0
|
@@ -71,6 +71,7 @@ const dependencyVersionMap = {
|
|
|
71
71
|
"drizzle-kit": "^0.31.2",
|
|
72
72
|
"@planetscale/database": "^1.19.0",
|
|
73
73
|
"@libsql/client": "^0.15.9",
|
|
74
|
+
libsql: "^0.5.22",
|
|
74
75
|
"@neondatabase/serverless": "^1.0.1",
|
|
75
76
|
pg: "^8.14.1",
|
|
76
77
|
"@types/pg": "^8.11.11",
|
|
@@ -146,7 +147,9 @@ const dependencyVersionMap = {
|
|
|
146
147
|
"@cloudflare/workers-types": "^4.20250822.0",
|
|
147
148
|
alchemy: "^0.67.0",
|
|
148
149
|
nitropack: "^2.12.4",
|
|
149
|
-
dotenv: "^17.2.
|
|
150
|
+
dotenv: "^17.2.2",
|
|
151
|
+
tsdown: "^0.15.5",
|
|
152
|
+
zod: "^4.1.11",
|
|
150
153
|
"@polar-sh/better-auth": "^1.1.3",
|
|
151
154
|
"@polar-sh/sdk": "^0.34.16"
|
|
152
155
|
};
|
|
@@ -1375,7 +1378,7 @@ const getLatestCLIVersion = () => {
|
|
|
1375
1378
|
*/
|
|
1376
1379
|
function isTelemetryEnabled() {
|
|
1377
1380
|
const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
|
|
1378
|
-
const BTS_TELEMETRY = "
|
|
1381
|
+
const BTS_TELEMETRY = "0";
|
|
1379
1382
|
if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
|
|
1380
1383
|
if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
|
|
1381
1384
|
return true;
|
|
@@ -1383,8 +1386,8 @@ function isTelemetryEnabled() {
|
|
|
1383
1386
|
|
|
1384
1387
|
//#endregion
|
|
1385
1388
|
//#region src/utils/analytics.ts
|
|
1386
|
-
const POSTHOG_API_KEY = "
|
|
1387
|
-
const POSTHOG_HOST = "
|
|
1389
|
+
const POSTHOG_API_KEY = "random";
|
|
1390
|
+
const POSTHOG_HOST = "random";
|
|
1388
1391
|
function generateSessionId() {
|
|
1389
1392
|
const rand = Math.random().toString(36).slice(2);
|
|
1390
1393
|
return `cli_${Date.now().toString(36)}${rand}`;
|
|
@@ -1992,15 +1995,17 @@ const addPackageDependency = async (opts) => {
|
|
|
1992
1995
|
if (!pkgJson.dependencies) pkgJson.dependencies = {};
|
|
1993
1996
|
if (!pkgJson.devDependencies) pkgJson.devDependencies = {};
|
|
1994
1997
|
for (const pkgName of dependencies) {
|
|
1995
|
-
const version =
|
|
1998
|
+
const version = dependencyVersionMap[pkgName];
|
|
1996
1999
|
if (version) pkgJson.dependencies[pkgName] = version;
|
|
1997
2000
|
else console.warn(`Warning: Dependency ${pkgName} not found in version map.`);
|
|
1998
2001
|
}
|
|
1999
2002
|
for (const pkgName of devDependencies) {
|
|
2000
|
-
const version =
|
|
2003
|
+
const version = dependencyVersionMap[pkgName];
|
|
2001
2004
|
if (version) pkgJson.devDependencies[pkgName] = version;
|
|
2002
2005
|
else console.warn(`Warning: Dev dependency ${pkgName} not found in version map.`);
|
|
2003
2006
|
}
|
|
2007
|
+
for (const [pkgName, version] of Object.entries(customDependencies)) pkgJson.dependencies[pkgName] = version;
|
|
2008
|
+
for (const [pkgName, version] of Object.entries(customDevDependencies)) pkgJson.devDependencies[pkgName] = version;
|
|
2004
2009
|
await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
2005
2010
|
};
|
|
2006
2011
|
|
|
@@ -2770,23 +2775,28 @@ async function setupBackendFramework(projectDir, context) {
|
|
|
2770
2775
|
return;
|
|
2771
2776
|
}
|
|
2772
2777
|
await fs.ensureDir(serverAppDir);
|
|
2773
|
-
const serverBaseDir = path.join(PKG_ROOT, "templates/backend/server/
|
|
2778
|
+
const serverBaseDir = path.join(PKG_ROOT, "templates/backend/server/base");
|
|
2774
2779
|
if (await fs.pathExists(serverBaseDir)) await processAndCopyFiles("**/*", serverBaseDir, serverAppDir, context);
|
|
2775
2780
|
const frameworkSrcDir = path.join(PKG_ROOT, `templates/backend/server/${context.backend}`);
|
|
2776
2781
|
if (await fs.pathExists(frameworkSrcDir)) await processAndCopyFiles("**/*", frameworkSrcDir, serverAppDir, context, true);
|
|
2777
2782
|
if (context.api !== "none") {
|
|
2783
|
+
const apiPackageDir = path.join(projectDir, "packages/api");
|
|
2784
|
+
await fs.ensureDir(apiPackageDir);
|
|
2778
2785
|
const apiServerBaseDir = path.join(PKG_ROOT, `templates/api/${context.api}/server/base`);
|
|
2779
|
-
if (await fs.pathExists(apiServerBaseDir)) await processAndCopyFiles("**/*", apiServerBaseDir,
|
|
2780
|
-
|
|
2781
|
-
if (
|
|
2786
|
+
if (await fs.pathExists(apiServerBaseDir)) await processAndCopyFiles("**/*", apiServerBaseDir, apiPackageDir, context);
|
|
2787
|
+
let apiServerFrameworkDir = "";
|
|
2788
|
+
if (context.backend === "next") apiServerFrameworkDir = path.join(PKG_ROOT, `templates/api/${context.api}/server/${context.backend}`);
|
|
2789
|
+
else apiServerFrameworkDir = path.join(PKG_ROOT, `templates/api/${context.api}/server/rest`);
|
|
2790
|
+
if (await fs.pathExists(apiServerFrameworkDir)) await processAndCopyFiles("**/*", apiServerFrameworkDir, apiPackageDir, context, true);
|
|
2791
|
+
}
|
|
2792
|
+
if (context.database !== "none" && context.orm !== "none") {
|
|
2793
|
+
const dbPackageDir = path.join(projectDir, "packages/db");
|
|
2794
|
+
await fs.ensureDir(dbPackageDir);
|
|
2795
|
+
const dbBaseDir = path.join(PKG_ROOT, "templates/db/base");
|
|
2796
|
+
if (await fs.pathExists(dbBaseDir)) await processAndCopyFiles("**/*", dbBaseDir, dbPackageDir, context);
|
|
2797
|
+
const dbOrmSrcDir = path.join(PKG_ROOT, `templates/db/${context.orm}/${context.database}`);
|
|
2798
|
+
if (await fs.pathExists(dbOrmSrcDir)) await processAndCopyFiles("**/*", dbOrmSrcDir, dbPackageDir, context);
|
|
2782
2799
|
}
|
|
2783
|
-
}
|
|
2784
|
-
async function setupDbOrmTemplates(projectDir, context) {
|
|
2785
|
-
if (context.backend === "convex" || context.orm === "none" || context.database === "none") return;
|
|
2786
|
-
const serverAppDir = path.join(projectDir, "apps/server");
|
|
2787
|
-
await fs.ensureDir(serverAppDir);
|
|
2788
|
-
const dbOrmSrcDir = path.join(PKG_ROOT, `templates/db/${context.orm}/${context.database}`);
|
|
2789
|
-
if (await fs.pathExists(dbOrmSrcDir)) await processAndCopyFiles("**/*", dbOrmSrcDir, serverAppDir, context);
|
|
2790
2800
|
}
|
|
2791
2801
|
async function setupAuthTemplate(projectDir, context) {
|
|
2792
2802
|
if (!context.auth || context.auth === "none") return;
|
|
@@ -2867,20 +2877,24 @@ async function setupAuthTemplate(projectDir, context) {
|
|
|
2867
2877
|
return;
|
|
2868
2878
|
}
|
|
2869
2879
|
if (serverAppDirExists && context.backend !== "convex") {
|
|
2880
|
+
const authPackageDir = path.join(projectDir, "packages/auth");
|
|
2881
|
+
await fs.ensureDir(authPackageDir);
|
|
2870
2882
|
const authServerBaseSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/base`);
|
|
2871
|
-
if (await fs.pathExists(authServerBaseSrc)) await processAndCopyFiles("**/*", authServerBaseSrc,
|
|
2883
|
+
if (await fs.pathExists(authServerBaseSrc)) await processAndCopyFiles("**/*", authServerBaseSrc, authPackageDir, context);
|
|
2872
2884
|
if (context.backend === "next") {
|
|
2873
2885
|
const authServerNextSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/next`);
|
|
2874
|
-
if (await fs.pathExists(authServerNextSrc)) await processAndCopyFiles("**/*", authServerNextSrc,
|
|
2886
|
+
if (await fs.pathExists(authServerNextSrc)) await processAndCopyFiles("**/*", authServerNextSrc, authPackageDir, context);
|
|
2875
2887
|
}
|
|
2876
2888
|
if (context.orm !== "none" && context.database !== "none") {
|
|
2889
|
+
const dbPackageDir = path.join(projectDir, "packages/db");
|
|
2890
|
+
await fs.ensureDir(dbPackageDir);
|
|
2877
2891
|
const orm = context.orm;
|
|
2878
2892
|
const db = context.database;
|
|
2879
2893
|
let authDbSrc = "";
|
|
2880
2894
|
if (orm === "drizzle") authDbSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/db/drizzle/${db}`);
|
|
2881
2895
|
else if (orm === "prisma") authDbSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/db/prisma/${db}`);
|
|
2882
2896
|
else if (orm === "mongoose") authDbSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/db/mongoose/${db}`);
|
|
2883
|
-
if (authDbSrc && await fs.pathExists(authDbSrc)) await processAndCopyFiles("**/*", authDbSrc,
|
|
2897
|
+
if (authDbSrc && await fs.pathExists(authDbSrc)) await processAndCopyFiles("**/*", authDbSrc, dbPackageDir, context);
|
|
2884
2898
|
}
|
|
2885
2899
|
}
|
|
2886
2900
|
if ((hasReactWeb || hasNuxtWeb || hasSvelteWeb || hasSolidWeb) && webAppDirExists) {
|
|
@@ -2927,8 +2941,10 @@ async function setupPaymentsTemplate(projectDir, context) {
|
|
|
2927
2941
|
const serverAppDirExists = await fs.pathExists(serverAppDir);
|
|
2928
2942
|
const webAppDirExists = await fs.pathExists(webAppDir);
|
|
2929
2943
|
if (serverAppDirExists && context.backend !== "convex") {
|
|
2944
|
+
const authPackageDir = path.join(projectDir, "packages/auth");
|
|
2945
|
+
await fs.ensureDir(authPackageDir);
|
|
2930
2946
|
const paymentsServerSrc = path.join(PKG_ROOT, `templates/payments/${context.payments}/server/base`);
|
|
2931
|
-
if (await fs.pathExists(paymentsServerSrc)) await processAndCopyFiles("**/*", paymentsServerSrc,
|
|
2947
|
+
if (await fs.pathExists(paymentsServerSrc)) await processAndCopyFiles("**/*", paymentsServerSrc, authPackageDir, context);
|
|
2932
2948
|
}
|
|
2933
2949
|
const hasReactWeb = context.frontend.some((f) => [
|
|
2934
2950
|
"tanstack-router",
|
|
@@ -3006,15 +3022,21 @@ async function setupExamplesTemplate(projectDir, context) {
|
|
|
3006
3022
|
const exampleBaseDir = path.join(PKG_ROOT, `templates/examples/${example}`);
|
|
3007
3023
|
if (serverAppDirExists && context.backend !== "convex" && context.backend !== "none") {
|
|
3008
3024
|
const exampleServerSrc = path.join(exampleBaseDir, "server");
|
|
3009
|
-
if (
|
|
3010
|
-
const
|
|
3011
|
-
|
|
3025
|
+
if (context.api !== "none") {
|
|
3026
|
+
const apiPackageDir = path.join(projectDir, "packages/api");
|
|
3027
|
+
await fs.ensureDir(apiPackageDir);
|
|
3028
|
+
const exampleOrmBaseSrc = path.join(exampleServerSrc, context.orm, "base");
|
|
3029
|
+
if (await fs.pathExists(exampleOrmBaseSrc)) await processAndCopyFiles("**/*", exampleOrmBaseSrc, apiPackageDir, context, false);
|
|
3012
3030
|
}
|
|
3013
3031
|
if (context.orm !== "none" && context.database !== "none") {
|
|
3014
|
-
const
|
|
3015
|
-
|
|
3032
|
+
const dbPackageDir = path.join(projectDir, "packages/db");
|
|
3033
|
+
await fs.ensureDir(dbPackageDir);
|
|
3016
3034
|
const exampleDbSchemaSrc = path.join(exampleServerSrc, context.orm, context.database);
|
|
3017
|
-
if (await fs.pathExists(exampleDbSchemaSrc)) await processAndCopyFiles("**/*", exampleDbSchemaSrc,
|
|
3035
|
+
if (await fs.pathExists(exampleDbSchemaSrc)) await processAndCopyFiles("**/*", exampleDbSchemaSrc, dbPackageDir, context, false);
|
|
3036
|
+
}
|
|
3037
|
+
if (example === "ai" && context.backend === "next") {
|
|
3038
|
+
const aiNextServerSrc = path.join(exampleServerSrc, "next");
|
|
3039
|
+
if (await fs.pathExists(aiNextServerSrc)) await processAndCopyFiles("**/*", aiNextServerSrc, serverAppDir, context, false);
|
|
3018
3040
|
}
|
|
3019
3041
|
}
|
|
3020
3042
|
if (webAppDirExists) {
|
|
@@ -3081,9 +3103,9 @@ async function handleExtras(projectDir, context) {
|
|
|
3081
3103
|
}
|
|
3082
3104
|
async function setupDockerComposeTemplates(projectDir, context) {
|
|
3083
3105
|
if (context.dbSetup !== "docker" || context.database === "none") return;
|
|
3084
|
-
const
|
|
3106
|
+
const dbPackageDir = path.join(projectDir, "packages/db");
|
|
3085
3107
|
const dockerSrcDir = path.join(PKG_ROOT, `templates/db-setup/docker-compose/${context.database}`);
|
|
3086
|
-
if (await fs.pathExists(dockerSrcDir)) await processAndCopyFiles("**/*", dockerSrcDir,
|
|
3108
|
+
if (await fs.pathExists(dockerSrcDir)) await processAndCopyFiles("**/*", dockerSrcDir, dbPackageDir, context);
|
|
3087
3109
|
}
|
|
3088
3110
|
async function setupDeploymentTemplates(projectDir, context) {
|
|
3089
3111
|
if (context.webDeploy === "alchemy" || context.serverDeploy === "alchemy") if (context.webDeploy === "alchemy" && context.serverDeploy === "alchemy") {
|
|
@@ -3963,10 +3985,10 @@ async function setupExamples(config) {
|
|
|
3963
3985
|
if (examples.includes("ai")) {
|
|
3964
3986
|
const webClientDir = path.join(projectDir, "apps/web");
|
|
3965
3987
|
const nativeClientDir = path.join(projectDir, "apps/native");
|
|
3966
|
-
const
|
|
3988
|
+
const apiDir = path.join(projectDir, "packages/api");
|
|
3967
3989
|
const webClientDirExists = await fs.pathExists(webClientDir);
|
|
3968
3990
|
const nativeClientDirExists = await fs.pathExists(nativeClientDir);
|
|
3969
|
-
const
|
|
3991
|
+
const apiDirExists = await fs.pathExists(apiDir);
|
|
3970
3992
|
const hasNuxt = frontend.includes("nuxt");
|
|
3971
3993
|
const hasSvelte = frontend.includes("svelte");
|
|
3972
3994
|
const hasReactWeb = frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("next") || frontend.includes("tanstack-start");
|
|
@@ -3987,9 +4009,9 @@ async function setupExamples(config) {
|
|
|
3987
4009
|
dependencies: ["ai", "@ai-sdk/react"],
|
|
3988
4010
|
projectDir: nativeClientDir
|
|
3989
4011
|
});
|
|
3990
|
-
if (
|
|
4012
|
+
if (apiDirExists && backend !== "none") await addPackageDependency({
|
|
3991
4013
|
dependencies: ["ai", "@ai-sdk/google"],
|
|
3992
|
-
projectDir:
|
|
4014
|
+
projectDir: apiDir
|
|
3993
4015
|
});
|
|
3994
4016
|
}
|
|
3995
4017
|
}
|
|
@@ -4105,32 +4127,54 @@ function getConvexDependencies(frontend) {
|
|
|
4105
4127
|
return deps;
|
|
4106
4128
|
}
|
|
4107
4129
|
async function setupApi(config) {
|
|
4108
|
-
const { api, projectName, frontend, backend, packageManager, projectDir } = config;
|
|
4130
|
+
const { api, projectName, frontend, backend, packageManager, projectDir, auth } = config;
|
|
4109
4131
|
const isConvex = backend === "convex";
|
|
4110
4132
|
const webDir = path.join(projectDir, "apps/web");
|
|
4111
4133
|
const nativeDir = path.join(projectDir, "apps/native");
|
|
4112
4134
|
const serverDir = path.join(projectDir, "apps/server");
|
|
4113
4135
|
const webDirExists = await fs.pathExists(webDir);
|
|
4114
4136
|
const nativeDirExists = await fs.pathExists(nativeDir);
|
|
4115
|
-
|
|
4137
|
+
await fs.pathExists(serverDir);
|
|
4116
4138
|
const frontendType = getFrontendType(frontend);
|
|
4117
4139
|
if (!isConvex && api !== "none") {
|
|
4118
4140
|
const apiDeps = getApiDependencies(api, frontendType);
|
|
4119
|
-
|
|
4141
|
+
const apiPackageDir = path.join(projectDir, "packages/api");
|
|
4142
|
+
if (apiDeps.server) {
|
|
4120
4143
|
await addPackageDependency({
|
|
4121
4144
|
dependencies: apiDeps.server.dependencies,
|
|
4122
|
-
projectDir:
|
|
4145
|
+
projectDir: apiPackageDir
|
|
4146
|
+
});
|
|
4147
|
+
const frameworkDeps = [];
|
|
4148
|
+
if (backend === "hono") frameworkDeps.push("hono");
|
|
4149
|
+
else if (backend === "elysia") frameworkDeps.push("elysia");
|
|
4150
|
+
else if (backend === "express") frameworkDeps.push("express", "@types/express");
|
|
4151
|
+
else if (backend === "fastify") frameworkDeps.push("fastify");
|
|
4152
|
+
if (frameworkDeps.length > 0) await addPackageDependency({
|
|
4153
|
+
dependencies: frameworkDeps,
|
|
4154
|
+
projectDir: apiPackageDir
|
|
4123
4155
|
});
|
|
4124
4156
|
if (api === "trpc") {
|
|
4125
4157
|
if (backend === "hono") await addPackageDependency({
|
|
4126
4158
|
dependencies: ["@hono/trpc-server"],
|
|
4127
|
-
projectDir:
|
|
4159
|
+
projectDir: apiPackageDir
|
|
4128
4160
|
});
|
|
4129
4161
|
else if (backend === "elysia") await addPackageDependency({
|
|
4130
4162
|
dependencies: ["@elysiajs/trpc"],
|
|
4131
|
-
projectDir:
|
|
4163
|
+
projectDir: apiPackageDir
|
|
4164
|
+
});
|
|
4165
|
+
else if (backend === "express") await addPackageDependency({
|
|
4166
|
+
dependencies: ["@trpc/server"],
|
|
4167
|
+
projectDir: apiPackageDir
|
|
4168
|
+
});
|
|
4169
|
+
else if (backend === "fastify") await addPackageDependency({
|
|
4170
|
+
dependencies: ["@trpc/server"],
|
|
4171
|
+
projectDir: apiPackageDir
|
|
4132
4172
|
});
|
|
4133
4173
|
}
|
|
4174
|
+
if (auth === "better-auth") await addPackageDependency({
|
|
4175
|
+
dependencies: ["better-auth"],
|
|
4176
|
+
projectDir: apiPackageDir
|
|
4177
|
+
});
|
|
4134
4178
|
}
|
|
4135
4179
|
if (webDirExists && apiDeps.web) await addPackageDependency({
|
|
4136
4180
|
dependencies: apiDeps.web.dependencies,
|
|
@@ -4174,7 +4218,7 @@ async function setupApi(config) {
|
|
|
4174
4218
|
//#endregion
|
|
4175
4219
|
//#region src/helpers/core/backend-setup.ts
|
|
4176
4220
|
async function setupBackendDependencies(config) {
|
|
4177
|
-
const { backend, runtime, api, projectDir } = config;
|
|
4221
|
+
const { backend, runtime, api, auth, examples, projectDir } = config;
|
|
4178
4222
|
if (backend === "convex") return;
|
|
4179
4223
|
const framework = backend;
|
|
4180
4224
|
const serverDir = path.join(projectDir, "apps/server");
|
|
@@ -4202,6 +4246,13 @@ async function setupBackendDependencies(config) {
|
|
|
4202
4246
|
dependencies.push("fastify", "@fastify/cors");
|
|
4203
4247
|
if (runtime === "node") devDependencies.push("tsx", "@types/node");
|
|
4204
4248
|
}
|
|
4249
|
+
if (api === "trpc") {
|
|
4250
|
+
if (framework === "express") dependencies.push("@trpc/server");
|
|
4251
|
+
else if (framework === "fastify") dependencies.push("@trpc/server");
|
|
4252
|
+
else if (runtime === "workers") dependencies.push("@trpc/server");
|
|
4253
|
+
} else if (api === "orpc") dependencies.push("@orpc/server", "@orpc/openapi", "@orpc/zod");
|
|
4254
|
+
if (auth === "better-auth") dependencies.push("better-auth");
|
|
4255
|
+
if (examples.includes("ai")) dependencies.push("ai", "@ai-sdk/google");
|
|
4205
4256
|
if (runtime === "bun") devDependencies.push("@types/bun");
|
|
4206
4257
|
if (dependencies.length > 0 || devDependencies.length > 0) await addPackageDependency({
|
|
4207
4258
|
dependencies,
|
|
@@ -4220,7 +4271,7 @@ async function setupAuth(config) {
|
|
|
4220
4271
|
const nativeDir = path.join(projectDir, "apps/native");
|
|
4221
4272
|
const clientDirExists = await fs.pathExists(clientDir);
|
|
4222
4273
|
const nativeDirExists = await fs.pathExists(nativeDir);
|
|
4223
|
-
|
|
4274
|
+
await fs.pathExists(serverDir);
|
|
4224
4275
|
try {
|
|
4225
4276
|
if (backend === "convex") {
|
|
4226
4277
|
if (auth === "clerk" && clientDirExists) {
|
|
@@ -4276,9 +4327,11 @@ async function setupAuth(config) {
|
|
|
4276
4327
|
});
|
|
4277
4328
|
return;
|
|
4278
4329
|
}
|
|
4279
|
-
|
|
4330
|
+
const authPackageDir = path.join(projectDir, "packages/auth");
|
|
4331
|
+
const authPackageDirExists = await fs.pathExists(authPackageDir);
|
|
4332
|
+
if (authPackageDirExists && auth === "better-auth") await addPackageDependency({
|
|
4280
4333
|
dependencies: ["better-auth"],
|
|
4281
|
-
projectDir:
|
|
4334
|
+
projectDir: authPackageDir
|
|
4282
4335
|
});
|
|
4283
4336
|
if (frontend.some((f) => [
|
|
4284
4337
|
"react-router",
|
|
@@ -4300,9 +4353,9 @@ async function setupAuth(config) {
|
|
|
4300
4353
|
dependencies: ["better-auth", "@better-auth/expo"],
|
|
4301
4354
|
projectDir: nativeDir
|
|
4302
4355
|
});
|
|
4303
|
-
if (
|
|
4356
|
+
if (authPackageDirExists) await addPackageDependency({
|
|
4304
4357
|
dependencies: ["@better-auth/expo"],
|
|
4305
|
-
projectDir:
|
|
4358
|
+
projectDir: authPackageDir
|
|
4306
4359
|
});
|
|
4307
4360
|
}
|
|
4308
4361
|
}
|
|
@@ -4485,8 +4538,6 @@ async function setupEnvironmentVariables(config) {
|
|
|
4485
4538
|
return;
|
|
4486
4539
|
}
|
|
4487
4540
|
const serverDir = path.join(projectDir, "apps/server");
|
|
4488
|
-
if (!await fs.pathExists(serverDir)) return;
|
|
4489
|
-
const envPath = path.join(serverDir, ".env");
|
|
4490
4541
|
let corsOrigin = "http://localhost:3001";
|
|
4491
4542
|
if (hasReactRouter || hasSvelte) corsOrigin = "http://localhost:5173";
|
|
4492
4543
|
let databaseUrl = null;
|
|
@@ -4502,47 +4553,50 @@ async function setupEnvironmentVariables(config) {
|
|
|
4502
4553
|
break;
|
|
4503
4554
|
case "sqlite":
|
|
4504
4555
|
if (config.runtime === "workers") databaseUrl = "http://127.0.0.1:8080";
|
|
4505
|
-
else databaseUrl = "
|
|
4556
|
+
else databaseUrl = `file:${path.join(config.projectDir, "apps/server", "local.db")}`;
|
|
4506
4557
|
break;
|
|
4507
4558
|
}
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4559
|
+
if (await fs.pathExists(serverDir)) {
|
|
4560
|
+
const serverEnvPath = path.join(serverDir, ".env");
|
|
4561
|
+
const serverVars = [
|
|
4562
|
+
{
|
|
4563
|
+
key: "BETTER_AUTH_SECRET",
|
|
4564
|
+
value: generateAuthSecret(),
|
|
4565
|
+
condition: !!auth
|
|
4566
|
+
},
|
|
4567
|
+
{
|
|
4568
|
+
key: "BETTER_AUTH_URL",
|
|
4569
|
+
value: "http://localhost:3000",
|
|
4570
|
+
condition: !!auth
|
|
4571
|
+
},
|
|
4572
|
+
{
|
|
4573
|
+
key: "POLAR_ACCESS_TOKEN",
|
|
4574
|
+
value: "",
|
|
4575
|
+
condition: config.payments === "polar"
|
|
4576
|
+
},
|
|
4577
|
+
{
|
|
4578
|
+
key: "POLAR_SUCCESS_URL",
|
|
4579
|
+
value: `${corsOrigin}/success?checkout_id={CHECKOUT_ID}`,
|
|
4580
|
+
condition: config.payments === "polar"
|
|
4581
|
+
},
|
|
4582
|
+
{
|
|
4583
|
+
key: "CORS_ORIGIN",
|
|
4584
|
+
value: corsOrigin,
|
|
4585
|
+
condition: true
|
|
4586
|
+
},
|
|
4587
|
+
{
|
|
4588
|
+
key: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
4589
|
+
value: "",
|
|
4590
|
+
condition: examples?.includes("ai") || false
|
|
4591
|
+
},
|
|
4592
|
+
{
|
|
4593
|
+
key: "DATABASE_URL",
|
|
4594
|
+
value: databaseUrl,
|
|
4595
|
+
condition: database !== "none" && dbSetup === "none"
|
|
4596
|
+
}
|
|
4597
|
+
];
|
|
4598
|
+
await addEnvVariablesToFile(serverEnvPath, serverVars);
|
|
4599
|
+
}
|
|
4546
4600
|
const isUnifiedAlchemy = webDeploy === "alchemy" && serverDeploy === "alchemy";
|
|
4547
4601
|
const isIndividualAlchemy = webDeploy === "alchemy" || serverDeploy === "alchemy";
|
|
4548
4602
|
if (isUnifiedAlchemy) {
|
|
@@ -4561,14 +4615,11 @@ async function setupEnvironmentVariables(config) {
|
|
|
4561
4615
|
condition: true
|
|
4562
4616
|
}]);
|
|
4563
4617
|
}
|
|
4564
|
-
if (serverDeploy === "alchemy") {
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
condition: true
|
|
4570
|
-
}]);
|
|
4571
|
-
}
|
|
4618
|
+
if (serverDeploy === "alchemy") await addEnvVariablesToFile(path.join(serverDir, ".env"), [{
|
|
4619
|
+
key: "ALCHEMY_PASSWORD",
|
|
4620
|
+
value: "please-change-this",
|
|
4621
|
+
condition: true
|
|
4622
|
+
}]);
|
|
4572
4623
|
}
|
|
4573
4624
|
}
|
|
4574
4625
|
|
|
@@ -4603,7 +4654,7 @@ async function setupCloudflareD1(config) {
|
|
|
4603
4654
|
const envPath = path.join(projectDir, "apps/server", ".env");
|
|
4604
4655
|
const variables = [{
|
|
4605
4656
|
key: "DATABASE_URL",
|
|
4606
|
-
value: "
|
|
4657
|
+
value: `file:${path.join(projectDir, "apps/server", "local.db")}`,
|
|
4607
4658
|
condition: true
|
|
4608
4659
|
}];
|
|
4609
4660
|
try {
|
|
@@ -5133,9 +5184,9 @@ async function writeEnvFile$1(projectDir, config) {
|
|
|
5133
5184
|
}
|
|
5134
5185
|
async function addDotenvImportToPrismaConfig(projectDir) {
|
|
5135
5186
|
try {
|
|
5136
|
-
const prismaConfigPath = path.join(projectDir, "
|
|
5187
|
+
const prismaConfigPath = path.join(projectDir, "packages/db/prisma.config.ts");
|
|
5137
5188
|
let content = await fs.readFile(prismaConfigPath, "utf8");
|
|
5138
|
-
content = `import "dotenv
|
|
5189
|
+
content = `import dotenv from "dotenv";\ndotenv.config({ path: "../../apps/server/.env" });\n${content}`;
|
|
5139
5190
|
await fs.writeFile(prismaConfigPath, content);
|
|
5140
5191
|
} catch (_error) {
|
|
5141
5192
|
consola$1.error("Failed to update prisma.config.ts");
|
|
@@ -5151,11 +5202,12 @@ function displayManualSetupInstructions$1() {
|
|
|
5151
5202
|
|
|
5152
5203
|
DATABASE_URL="your_database_url"`);
|
|
5153
5204
|
}
|
|
5154
|
-
async function addPrismaAccelerateExtension(
|
|
5205
|
+
async function addPrismaAccelerateExtension(projectDir) {
|
|
5155
5206
|
try {
|
|
5207
|
+
const dbPackageDir = path.join(projectDir, "packages/db");
|
|
5156
5208
|
await addPackageDependency({
|
|
5157
5209
|
dependencies: ["@prisma/extension-accelerate"],
|
|
5158
|
-
projectDir:
|
|
5210
|
+
projectDir: dbPackageDir
|
|
5159
5211
|
});
|
|
5160
5212
|
return true;
|
|
5161
5213
|
} catch (_error) {
|
|
@@ -5216,7 +5268,7 @@ async function setupPrismaPostgres(config, cliInput) {
|
|
|
5216
5268
|
await writeEnvFile$1(projectDir, prismaConfig);
|
|
5217
5269
|
if (orm === "prisma") {
|
|
5218
5270
|
await addDotenvImportToPrismaConfig(projectDir);
|
|
5219
|
-
await addPrismaAccelerateExtension(
|
|
5271
|
+
await addPrismaAccelerateExtension(projectDir);
|
|
5220
5272
|
}
|
|
5221
5273
|
const connectionType = orm === "drizzle" ? "direct connection" : "Prisma Accelerate";
|
|
5222
5274
|
log.success(pc.green(`Prisma Postgres database configured successfully with ${connectionType}!`));
|
|
@@ -5316,18 +5368,18 @@ function displayManualSupabaseInstructions(output) {
|
|
|
5316
5368
|
log.info(`"Manual Supabase Setup Instructions:"
|
|
5317
5369
|
1. Ensure Docker is installed and running.
|
|
5318
5370
|
2. Install the Supabase CLI (e.g., \`npm install -g supabase\`).
|
|
5319
|
-
3. Run \`supabase init\` in your project's \`
|
|
5320
|
-
4. Run \`supabase start\` in your project's \`
|
|
5371
|
+
3. Run \`supabase init\` in your project's \`packages/db\` directory.
|
|
5372
|
+
4. Run \`supabase start\` in your project's \`packages/db\` directory.
|
|
5321
5373
|
5. Copy the 'DB URL' from the output.${output ? `
|
|
5322
5374
|
${pc.bold("Relevant output from `supabase start`:")}
|
|
5323
5375
|
${pc.dim(output)}` : ""}
|
|
5324
|
-
6. Add the DB URL to the .env file in \`
|
|
5376
|
+
6. Add the DB URL to the .env file in \`packages/db/.env\` as \`DATABASE_URL\`:
|
|
5325
5377
|
${pc.gray("DATABASE_URL=\"your_supabase_db_url\"")}`);
|
|
5326
5378
|
}
|
|
5327
5379
|
async function setupSupabase(config, cliInput) {
|
|
5328
5380
|
const { projectDir, packageManager } = config;
|
|
5329
5381
|
const manualDb = cliInput?.manualDb ?? false;
|
|
5330
|
-
const serverDir = path.join(projectDir, "
|
|
5382
|
+
const serverDir = path.join(projectDir, "packages", "db");
|
|
5331
5383
|
try {
|
|
5332
5384
|
await fs.ensureDir(serverDir);
|
|
5333
5385
|
if (manualDb) {
|
|
@@ -5610,15 +5662,15 @@ async function setupDatabase(config, cliInput) {
|
|
|
5610
5662
|
const { database, orm, dbSetup, backend, projectDir } = config;
|
|
5611
5663
|
if (backend === "convex" || database === "none") {
|
|
5612
5664
|
if (backend !== "convex") {
|
|
5613
|
-
const serverDir
|
|
5614
|
-
const serverDbDir = path.join(serverDir
|
|
5665
|
+
const serverDir = path.join(projectDir, "apps/server");
|
|
5666
|
+
const serverDbDir = path.join(serverDir, "src/db");
|
|
5615
5667
|
if (await fs.pathExists(serverDbDir)) await fs.remove(serverDbDir);
|
|
5616
5668
|
}
|
|
5617
5669
|
return;
|
|
5618
5670
|
}
|
|
5619
5671
|
const s = spinner();
|
|
5620
|
-
const
|
|
5621
|
-
if (!await fs.pathExists(
|
|
5672
|
+
const dbPackageDir = path.join(projectDir, "packages/db");
|
|
5673
|
+
if (!await fs.pathExists(dbPackageDir)) return;
|
|
5622
5674
|
try {
|
|
5623
5675
|
if (orm === "prisma") if (database === "mysql" && dbSetup === "planetscale") await addPackageDependency({
|
|
5624
5676
|
dependencies: [
|
|
@@ -5627,23 +5679,27 @@ async function setupDatabase(config, cliInput) {
|
|
|
5627
5679
|
"@planetscale/database"
|
|
5628
5680
|
],
|
|
5629
5681
|
devDependencies: ["prisma"],
|
|
5630
|
-
projectDir:
|
|
5682
|
+
projectDir: dbPackageDir
|
|
5631
5683
|
});
|
|
5632
5684
|
else if (database === "sqlite" && dbSetup === "turso") await addPackageDependency({
|
|
5633
5685
|
dependencies: ["@prisma/client", "@prisma/adapter-libsql"],
|
|
5634
5686
|
devDependencies: ["prisma"],
|
|
5635
|
-
projectDir:
|
|
5687
|
+
projectDir: dbPackageDir
|
|
5636
5688
|
});
|
|
5637
5689
|
else await addPackageDependency({
|
|
5638
5690
|
dependencies: ["@prisma/client"],
|
|
5639
5691
|
devDependencies: ["prisma"],
|
|
5640
|
-
projectDir:
|
|
5692
|
+
projectDir: dbPackageDir
|
|
5641
5693
|
});
|
|
5642
5694
|
else if (orm === "drizzle") {
|
|
5643
5695
|
if (database === "sqlite") await addPackageDependency({
|
|
5644
|
-
dependencies: [
|
|
5696
|
+
dependencies: [
|
|
5697
|
+
"drizzle-orm",
|
|
5698
|
+
"@libsql/client",
|
|
5699
|
+
"libsql"
|
|
5700
|
+
],
|
|
5645
5701
|
devDependencies: ["drizzle-kit"],
|
|
5646
|
-
projectDir:
|
|
5702
|
+
projectDir: dbPackageDir
|
|
5647
5703
|
});
|
|
5648
5704
|
else if (database === "postgres") if (dbSetup === "neon") await addPackageDependency({
|
|
5649
5705
|
dependencies: [
|
|
@@ -5652,32 +5708,32 @@ async function setupDatabase(config, cliInput) {
|
|
|
5652
5708
|
"ws"
|
|
5653
5709
|
],
|
|
5654
5710
|
devDependencies: ["drizzle-kit", "@types/ws"],
|
|
5655
|
-
projectDir:
|
|
5711
|
+
projectDir: dbPackageDir
|
|
5656
5712
|
});
|
|
5657
5713
|
else if (dbSetup === "planetscale") await addPackageDependency({
|
|
5658
5714
|
dependencies: ["drizzle-orm", "pg"],
|
|
5659
5715
|
devDependencies: ["drizzle-kit", "@types/pg"],
|
|
5660
|
-
projectDir:
|
|
5716
|
+
projectDir: dbPackageDir
|
|
5661
5717
|
});
|
|
5662
5718
|
else await addPackageDependency({
|
|
5663
5719
|
dependencies: ["drizzle-orm", "pg"],
|
|
5664
5720
|
devDependencies: ["drizzle-kit", "@types/pg"],
|
|
5665
|
-
projectDir:
|
|
5721
|
+
projectDir: dbPackageDir
|
|
5666
5722
|
});
|
|
5667
5723
|
else if (database === "mysql") if (dbSetup === "planetscale") await addPackageDependency({
|
|
5668
5724
|
dependencies: ["drizzle-orm", "@planetscale/database"],
|
|
5669
5725
|
devDependencies: ["drizzle-kit"],
|
|
5670
|
-
projectDir:
|
|
5726
|
+
projectDir: dbPackageDir
|
|
5671
5727
|
});
|
|
5672
5728
|
else await addPackageDependency({
|
|
5673
5729
|
dependencies: ["drizzle-orm", "mysql2"],
|
|
5674
5730
|
devDependencies: ["drizzle-kit"],
|
|
5675
|
-
projectDir:
|
|
5731
|
+
projectDir: dbPackageDir
|
|
5676
5732
|
});
|
|
5677
5733
|
} else if (orm === "mongoose") await addPackageDependency({
|
|
5678
5734
|
dependencies: ["mongoose"],
|
|
5679
5735
|
devDependencies: [],
|
|
5680
|
-
projectDir:
|
|
5736
|
+
projectDir: dbPackageDir
|
|
5681
5737
|
});
|
|
5682
5738
|
if (dbSetup === "docker") await setupDockerCompose(config);
|
|
5683
5739
|
else if (database === "sqlite" && dbSetup === "turso") await setupTurso(config, cliInput);
|
|
@@ -6043,7 +6099,7 @@ SERVER_URL={your-production-server-domain}
|
|
|
6043
6099
|
CORS_ORIGIN={your-production-web-domain}
|
|
6044
6100
|
BETTER_AUTH_URL={your-production-server-domain}
|
|
6045
6101
|
\`\`\`
|
|
6046
|
-
- In \`apps/server/lib/auth.ts\`, uncomment the \`session.cookieCache\` and \`advanced.crossSubDomainCookies\` sections and replace \`<your-workers-subdomain>\` with your actual workers subdomain. These settings are required to ensure cookies are transferred properly between your web and server domains.
|
|
6102
|
+
- In \`apps/server/src/lib/auth.ts\`, uncomment the \`session.cookieCache\` and \`advanced.crossSubDomainCookies\` sections and replace \`<your-workers-subdomain>\` with your actual workers subdomain. These settings are required to ensure cookies are transferred properly between your web and server domains.
|
|
6047
6103
|
`;
|
|
6048
6104
|
}
|
|
6049
6105
|
function generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy) {
|
|
@@ -6334,12 +6390,66 @@ function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy) {
|
|
|
6334
6390
|
return instructions.length ? `\n${instructions.join("\n")}` : "";
|
|
6335
6391
|
}
|
|
6336
6392
|
|
|
6393
|
+
//#endregion
|
|
6394
|
+
//#region src/helpers/core/workspace-setup.ts
|
|
6395
|
+
async function setupWorkspaceDependencies(projectDir, options) {
|
|
6396
|
+
const projectName = options.projectName;
|
|
6397
|
+
const workspaceVersion = options.packageManager === "npm" ? "*" : "workspace:*";
|
|
6398
|
+
const commonDeps = ["dotenv", "zod"];
|
|
6399
|
+
const commonDevDeps = ["tsdown"];
|
|
6400
|
+
const dbPackageDir = path.join(projectDir, "packages/db");
|
|
6401
|
+
if (await fs.pathExists(dbPackageDir)) await addPackageDependency({
|
|
6402
|
+
dependencies: commonDeps,
|
|
6403
|
+
devDependencies: commonDevDeps,
|
|
6404
|
+
projectDir: dbPackageDir
|
|
6405
|
+
});
|
|
6406
|
+
const authPackageDir = path.join(projectDir, "packages/auth");
|
|
6407
|
+
if (await fs.pathExists(authPackageDir)) await addPackageDependency({
|
|
6408
|
+
dependencies: commonDeps,
|
|
6409
|
+
devDependencies: commonDevDeps,
|
|
6410
|
+
customDependencies: { [`@${projectName}/db`]: workspaceVersion },
|
|
6411
|
+
projectDir: authPackageDir
|
|
6412
|
+
});
|
|
6413
|
+
const apiPackageDir = path.join(projectDir, "packages/api");
|
|
6414
|
+
if (await fs.pathExists(apiPackageDir)) await addPackageDependency({
|
|
6415
|
+
dependencies: commonDeps,
|
|
6416
|
+
devDependencies: commonDevDeps,
|
|
6417
|
+
customDependencies: {
|
|
6418
|
+
[`@${projectName}/auth`]: workspaceVersion,
|
|
6419
|
+
[`@${projectName}/db`]: workspaceVersion
|
|
6420
|
+
},
|
|
6421
|
+
projectDir: apiPackageDir
|
|
6422
|
+
});
|
|
6423
|
+
const serverPackageDir = path.join(projectDir, "apps/server");
|
|
6424
|
+
if (await fs.pathExists(serverPackageDir)) await addPackageDependency({
|
|
6425
|
+
dependencies: commonDeps,
|
|
6426
|
+
devDependencies: commonDevDeps,
|
|
6427
|
+
customDependencies: {
|
|
6428
|
+
[`@${projectName}/api`]: workspaceVersion,
|
|
6429
|
+
[`@${projectName}/auth`]: workspaceVersion,
|
|
6430
|
+
[`@${projectName}/db`]: workspaceVersion
|
|
6431
|
+
},
|
|
6432
|
+
projectDir: serverPackageDir
|
|
6433
|
+
});
|
|
6434
|
+
if (options.api && options.api !== "none") {
|
|
6435
|
+
const webPackageDir = path.join(projectDir, "apps/web");
|
|
6436
|
+
if (await fs.pathExists(webPackageDir)) await addPackageDependency({
|
|
6437
|
+
customDependencies: { [`@${projectName}/api`]: workspaceVersion },
|
|
6438
|
+
projectDir: webPackageDir
|
|
6439
|
+
});
|
|
6440
|
+
}
|
|
6441
|
+
}
|
|
6442
|
+
|
|
6337
6443
|
//#endregion
|
|
6338
6444
|
//#region src/helpers/core/project-config.ts
|
|
6339
6445
|
async function updatePackageConfigurations(projectDir, options) {
|
|
6340
6446
|
await updateRootPackageJson(projectDir, options);
|
|
6341
|
-
if (options.backend !== "convex")
|
|
6342
|
-
|
|
6447
|
+
if (options.backend !== "convex") {
|
|
6448
|
+
await updateServerPackageJson(projectDir, options);
|
|
6449
|
+
await updateAuthPackageJson(projectDir, options);
|
|
6450
|
+
await updateApiPackageJson(projectDir, options);
|
|
6451
|
+
await setupWorkspaceDependencies(projectDir, options);
|
|
6452
|
+
} else await updateConvexPackageJson(projectDir, options);
|
|
6343
6453
|
}
|
|
6344
6454
|
async function updateRootPackageJson(projectDir, options) {
|
|
6345
6455
|
const rootPackageJsonPath = path.join(projectDir, "package.json");
|
|
@@ -6349,6 +6459,7 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
6349
6459
|
if (!packageJson.scripts) packageJson.scripts = {};
|
|
6350
6460
|
const scripts = packageJson.scripts;
|
|
6351
6461
|
const backendPackageName = options.backend === "convex" ? `@${options.projectName}/backend` : "server";
|
|
6462
|
+
const dbPackageName = `@${options.projectName}/db`;
|
|
6352
6463
|
let serverDevScript = "";
|
|
6353
6464
|
if (options.addons.includes("turborepo")) serverDevScript = `turbo -F ${backendPackageName} dev`;
|
|
6354
6465
|
else if (options.packageManager === "bun") serverDevScript = `bun run --filter ${backendPackageName} dev`;
|
|
@@ -6368,14 +6479,14 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
6368
6479
|
scripts["dev:server"] = serverDevScript;
|
|
6369
6480
|
if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} dev:setup`;
|
|
6370
6481
|
if (needsDbScripts) {
|
|
6371
|
-
scripts["db:push"] = `turbo -F ${
|
|
6372
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `turbo -F ${
|
|
6482
|
+
scripts["db:push"] = `turbo -F ${dbPackageName} db:push`;
|
|
6483
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `turbo -F ${dbPackageName} db:studio`;
|
|
6373
6484
|
if (options.orm === "prisma") {
|
|
6374
|
-
scripts["db:generate"] = `turbo -F ${
|
|
6375
|
-
scripts["db:migrate"] = `turbo -F ${
|
|
6485
|
+
scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
|
|
6486
|
+
scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
|
|
6376
6487
|
} else if (options.orm === "drizzle") {
|
|
6377
|
-
scripts["db:generate"] = `turbo -F ${
|
|
6378
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `turbo -F ${
|
|
6488
|
+
scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
|
|
6489
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
|
|
6379
6490
|
}
|
|
6380
6491
|
}
|
|
6381
6492
|
if (options.dbSetup === "docker") {
|
|
@@ -6393,14 +6504,14 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
6393
6504
|
scripts["dev:server"] = serverDevScript;
|
|
6394
6505
|
if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} dev:setup`;
|
|
6395
6506
|
if (needsDbScripts) {
|
|
6396
|
-
scripts["db:push"] = `pnpm --filter ${
|
|
6397
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `pnpm --filter ${
|
|
6507
|
+
scripts["db:push"] = `pnpm --filter ${dbPackageName} db:push`;
|
|
6508
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `pnpm --filter ${dbPackageName} db:studio`;
|
|
6398
6509
|
if (options.orm === "prisma") {
|
|
6399
|
-
scripts["db:generate"] = `pnpm --filter ${
|
|
6400
|
-
scripts["db:migrate"] = `pnpm --filter ${
|
|
6510
|
+
scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
|
|
6511
|
+
scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
|
|
6401
6512
|
} else if (options.orm === "drizzle") {
|
|
6402
|
-
scripts["db:generate"] = `pnpm --filter ${
|
|
6403
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `pnpm --filter ${
|
|
6513
|
+
scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
|
|
6514
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
|
|
6404
6515
|
}
|
|
6405
6516
|
}
|
|
6406
6517
|
if (options.dbSetup === "docker") {
|
|
@@ -6418,14 +6529,14 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
6418
6529
|
scripts["dev:server"] = serverDevScript;
|
|
6419
6530
|
if (options.backend === "convex") scripts["dev:setup"] = `npm run dev:setup --workspace ${backendPackageName}`;
|
|
6420
6531
|
if (needsDbScripts) {
|
|
6421
|
-
scripts["db:push"] = `npm run db:push --workspace ${
|
|
6422
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `npm run db:studio --workspace ${
|
|
6532
|
+
scripts["db:push"] = `npm run db:push --workspace ${dbPackageName}`;
|
|
6533
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `npm run db:studio --workspace ${dbPackageName}`;
|
|
6423
6534
|
if (options.orm === "prisma") {
|
|
6424
|
-
scripts["db:generate"] = `npm run db:generate --workspace ${
|
|
6425
|
-
scripts["db:migrate"] = `npm run db:migrate --workspace ${
|
|
6535
|
+
scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
|
|
6536
|
+
scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
|
|
6426
6537
|
} else if (options.orm === "drizzle") {
|
|
6427
|
-
scripts["db:generate"] = `npm run db:generate --workspace ${
|
|
6428
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `npm run db:migrate --workspace ${
|
|
6538
|
+
scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
|
|
6539
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
|
|
6429
6540
|
}
|
|
6430
6541
|
}
|
|
6431
6542
|
if (options.dbSetup === "docker") {
|
|
@@ -6443,14 +6554,14 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
6443
6554
|
scripts["dev:server"] = serverDevScript;
|
|
6444
6555
|
if (options.backend === "convex") scripts["dev:setup"] = `bun run --filter ${backendPackageName} dev:setup`;
|
|
6445
6556
|
if (needsDbScripts) {
|
|
6446
|
-
scripts["db:push"] = `bun run --filter ${
|
|
6447
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `bun run --filter ${
|
|
6557
|
+
scripts["db:push"] = `bun run --filter ${dbPackageName} db:push`;
|
|
6558
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `bun run --filter ${dbPackageName} db:studio`;
|
|
6448
6559
|
if (options.orm === "prisma") {
|
|
6449
|
-
scripts["db:generate"] = `bun run --filter ${
|
|
6450
|
-
scripts["db:migrate"] = `bun run --filter ${
|
|
6560
|
+
scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
|
|
6561
|
+
scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
|
|
6451
6562
|
} else if (options.orm === "drizzle") {
|
|
6452
|
-
scripts["db:generate"] = `bun run --filter ${
|
|
6453
|
-
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `bun run --filter ${
|
|
6563
|
+
scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
|
|
6564
|
+
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
|
|
6454
6565
|
}
|
|
6455
6566
|
}
|
|
6456
6567
|
if (options.dbSetup === "docker") {
|
|
@@ -6483,6 +6594,22 @@ async function updateServerPackageJson(projectDir, options) {
|
|
|
6483
6594
|
const serverPackageJson = await fs.readJson(serverPackageJsonPath);
|
|
6484
6595
|
if (!serverPackageJson.scripts) serverPackageJson.scripts = {};
|
|
6485
6596
|
const scripts = serverPackageJson.scripts;
|
|
6597
|
+
if (options.dbSetup === "docker") {
|
|
6598
|
+
scripts["db:start"] = "docker compose up -d";
|
|
6599
|
+
scripts["db:watch"] = "docker compose up";
|
|
6600
|
+
scripts["db:stop"] = "docker compose stop";
|
|
6601
|
+
scripts["db:down"] = "docker compose down";
|
|
6602
|
+
}
|
|
6603
|
+
await fs.writeJson(serverPackageJsonPath, serverPackageJson, { spaces: 2 });
|
|
6604
|
+
await updateDbPackageJson(projectDir, options);
|
|
6605
|
+
}
|
|
6606
|
+
async function updateDbPackageJson(projectDir, options) {
|
|
6607
|
+
const dbPackageJsonPath = path.join(projectDir, "packages/db/package.json");
|
|
6608
|
+
if (!await fs.pathExists(dbPackageJsonPath)) return;
|
|
6609
|
+
const dbPackageJson = await fs.readJson(dbPackageJsonPath);
|
|
6610
|
+
dbPackageJson.name = `@${options.projectName}/db`;
|
|
6611
|
+
if (!dbPackageJson.scripts) dbPackageJson.scripts = {};
|
|
6612
|
+
const scripts = dbPackageJson.scripts;
|
|
6486
6613
|
if (options.database !== "none") {
|
|
6487
6614
|
if (options.database === "sqlite" && options.orm === "drizzle" && options.dbSetup !== "d1") scripts["db:local"] = "turso dev --db-file local.db";
|
|
6488
6615
|
if (options.orm === "prisma") {
|
|
@@ -6497,13 +6624,21 @@ async function updateServerPackageJson(projectDir, options) {
|
|
|
6497
6624
|
if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = "drizzle-kit migrate";
|
|
6498
6625
|
}
|
|
6499
6626
|
}
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6627
|
+
await fs.writeJson(dbPackageJsonPath, dbPackageJson, { spaces: 2 });
|
|
6628
|
+
}
|
|
6629
|
+
async function updateAuthPackageJson(projectDir, options) {
|
|
6630
|
+
const authPackageJsonPath = path.join(projectDir, "packages/auth/package.json");
|
|
6631
|
+
if (!await fs.pathExists(authPackageJsonPath)) return;
|
|
6632
|
+
const authPackageJson = await fs.readJson(authPackageJsonPath);
|
|
6633
|
+
authPackageJson.name = `@${options.projectName}/auth`;
|
|
6634
|
+
await fs.writeJson(authPackageJsonPath, authPackageJson, { spaces: 2 });
|
|
6635
|
+
}
|
|
6636
|
+
async function updateApiPackageJson(projectDir, options) {
|
|
6637
|
+
const apiPackageJsonPath = path.join(projectDir, "packages/api/package.json");
|
|
6638
|
+
if (!await fs.pathExists(apiPackageJsonPath)) return;
|
|
6639
|
+
const apiPackageJson = await fs.readJson(apiPackageJsonPath);
|
|
6640
|
+
apiPackageJson.name = `@${options.projectName}/api`;
|
|
6641
|
+
await fs.writeJson(apiPackageJsonPath, apiPackageJson, { spaces: 2 });
|
|
6507
6642
|
}
|
|
6508
6643
|
async function updateConvexPackageJson(projectDir, options) {
|
|
6509
6644
|
const convexPackageJsonPath = path.join(projectDir, "packages/backend/package.json");
|
|
@@ -6524,10 +6659,7 @@ async function createProject(options, cliInput) {
|
|
|
6524
6659
|
await copyBaseTemplate(projectDir, options);
|
|
6525
6660
|
await setupFrontendTemplates(projectDir, options);
|
|
6526
6661
|
await setupBackendFramework(projectDir, options);
|
|
6527
|
-
if (!isConvex)
|
|
6528
|
-
await setupDbOrmTemplates(projectDir, options);
|
|
6529
|
-
await setupDockerComposeTemplates(projectDir, options);
|
|
6530
|
-
}
|
|
6662
|
+
if (!isConvex) await setupDockerComposeTemplates(projectDir, options);
|
|
6531
6663
|
await setupAuthTemplate(projectDir, options);
|
|
6532
6664
|
if (options.payments && options.payments !== "none") await setupPaymentsTemplate(projectDir, options);
|
|
6533
6665
|
if (options.examples.length > 0 && options.examples[0] !== "none") await setupExamplesTemplate(projectDir, options);
|