create-better-t-stack 3.7.3-canary.8e4d5716 → 3.7.3-canary.fe324be3

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 (104) hide show
  1. package/dist/cli.d.ts +1 -0
  2. package/dist/cli.js +8 -0
  3. package/dist/index.d.ts +347 -0
  4. package/dist/index.js +4 -0
  5. package/dist/src-yXf02Wox.js +7077 -0
  6. package/package.json +11 -7
  7. package/src/cli.ts +0 -3
  8. package/src/constants.ts +0 -188
  9. package/src/helpers/addons/addons-setup.ts +0 -226
  10. package/src/helpers/addons/examples-setup.ts +0 -104
  11. package/src/helpers/addons/fumadocs-setup.ts +0 -103
  12. package/src/helpers/addons/ruler-setup.ts +0 -139
  13. package/src/helpers/addons/starlight-setup.ts +0 -51
  14. package/src/helpers/addons/tauri-setup.ts +0 -96
  15. package/src/helpers/addons/ultracite-setup.ts +0 -232
  16. package/src/helpers/addons/vite-pwa-setup.ts +0 -59
  17. package/src/helpers/core/add-addons.ts +0 -85
  18. package/src/helpers/core/add-deployment.ts +0 -102
  19. package/src/helpers/core/api-setup.ts +0 -280
  20. package/src/helpers/core/auth-setup.ts +0 -203
  21. package/src/helpers/core/backend-setup.ts +0 -73
  22. package/src/helpers/core/command-handlers.ts +0 -354
  23. package/src/helpers/core/convex-codegen.ts +0 -14
  24. package/src/helpers/core/create-project.ts +0 -133
  25. package/src/helpers/core/create-readme.ts +0 -687
  26. package/src/helpers/core/db-setup.ts +0 -184
  27. package/src/helpers/core/detect-project-config.ts +0 -41
  28. package/src/helpers/core/env-setup.ts +0 -449
  29. package/src/helpers/core/git.ts +0 -31
  30. package/src/helpers/core/install-dependencies.ts +0 -32
  31. package/src/helpers/core/payments-setup.ts +0 -48
  32. package/src/helpers/core/post-installation.ts +0 -383
  33. package/src/helpers/core/project-config.ts +0 -246
  34. package/src/helpers/core/runtime-setup.ts +0 -76
  35. package/src/helpers/core/template-manager.ts +0 -917
  36. package/src/helpers/core/workspace-setup.ts +0 -184
  37. package/src/helpers/database-providers/d1-setup.ts +0 -28
  38. package/src/helpers/database-providers/docker-compose-setup.ts +0 -50
  39. package/src/helpers/database-providers/mongodb-atlas-setup.ts +0 -186
  40. package/src/helpers/database-providers/neon-setup.ts +0 -243
  41. package/src/helpers/database-providers/planetscale-setup.ts +0 -78
  42. package/src/helpers/database-providers/prisma-postgres-setup.ts +0 -196
  43. package/src/helpers/database-providers/supabase-setup.ts +0 -218
  44. package/src/helpers/database-providers/turso-setup.ts +0 -309
  45. package/src/helpers/deployment/alchemy/alchemy-combined-setup.ts +0 -80
  46. package/src/helpers/deployment/alchemy/alchemy-next-setup.ts +0 -51
  47. package/src/helpers/deployment/alchemy/alchemy-nuxt-setup.ts +0 -104
  48. package/src/helpers/deployment/alchemy/alchemy-react-router-setup.ts +0 -32
  49. package/src/helpers/deployment/alchemy/alchemy-solid-setup.ts +0 -32
  50. package/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts +0 -98
  51. package/src/helpers/deployment/alchemy/alchemy-tanstack-router-setup.ts +0 -33
  52. package/src/helpers/deployment/alchemy/alchemy-tanstack-start-setup.ts +0 -98
  53. package/src/helpers/deployment/alchemy/env-dts-setup.ts +0 -76
  54. package/src/helpers/deployment/alchemy/index.ts +0 -7
  55. package/src/helpers/deployment/server-deploy-setup.ts +0 -55
  56. package/src/helpers/deployment/web-deploy-setup.ts +0 -58
  57. package/src/index.ts +0 -253
  58. package/src/prompts/addons.ts +0 -178
  59. package/src/prompts/api.ts +0 -49
  60. package/src/prompts/auth.ts +0 -84
  61. package/src/prompts/backend.ts +0 -83
  62. package/src/prompts/config-prompts.ts +0 -138
  63. package/src/prompts/database-setup.ts +0 -112
  64. package/src/prompts/database.ts +0 -57
  65. package/src/prompts/examples.ts +0 -64
  66. package/src/prompts/frontend.ts +0 -118
  67. package/src/prompts/git.ts +0 -16
  68. package/src/prompts/install.ts +0 -16
  69. package/src/prompts/orm.ts +0 -53
  70. package/src/prompts/package-manager.ts +0 -32
  71. package/src/prompts/payments.ts +0 -50
  72. package/src/prompts/project-name.ts +0 -86
  73. package/src/prompts/runtime.ts +0 -47
  74. package/src/prompts/server-deploy.ts +0 -91
  75. package/src/prompts/web-deploy.ts +0 -107
  76. package/src/types.ts +0 -2
  77. package/src/utils/add-package-deps.ts +0 -57
  78. package/src/utils/analytics.ts +0 -39
  79. package/src/utils/better-auth-plugin-setup.ts +0 -71
  80. package/src/utils/biome-formatter.ts +0 -82
  81. package/src/utils/bts-config.ts +0 -122
  82. package/src/utils/command-exists.ts +0 -16
  83. package/src/utils/compatibility-rules.ts +0 -319
  84. package/src/utils/compatibility.ts +0 -11
  85. package/src/utils/config-processing.ts +0 -130
  86. package/src/utils/config-validation.ts +0 -470
  87. package/src/utils/display-config.ts +0 -96
  88. package/src/utils/docker-utils.ts +0 -70
  89. package/src/utils/errors.ts +0 -32
  90. package/src/utils/generate-reproducible-command.ts +0 -53
  91. package/src/utils/get-latest-cli-version.ts +0 -11
  92. package/src/utils/get-package-manager.ts +0 -13
  93. package/src/utils/open-url.ts +0 -25
  94. package/src/utils/package-runner.ts +0 -23
  95. package/src/utils/project-directory.ts +0 -102
  96. package/src/utils/project-name-validation.ts +0 -43
  97. package/src/utils/render-title.ts +0 -48
  98. package/src/utils/setup-catalogs.ts +0 -192
  99. package/src/utils/sponsors.ts +0 -101
  100. package/src/utils/telemetry.ts +0 -19
  101. package/src/utils/template-processor.ts +0 -64
  102. package/src/utils/templates.ts +0 -94
  103. package/src/utils/ts-morph.ts +0 -26
  104. package/src/validation.ts +0 -117
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "3.7.3-canary.8e4d5716",
3
+ "version": "3.7.3-canary.fe324be3",
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",
7
7
  "author": "Aman Varshney",
8
8
  "bin": {
9
- "create-better-t-stack": "src/cli.ts"
9
+ "create-better-t-stack": "dist/cli.js"
10
10
  },
11
11
  "files": [
12
12
  "templates",
13
- "src"
13
+ "dist"
14
14
  ],
15
15
  "keywords": [
16
16
  "better-t-stack",
@@ -48,19 +48,24 @@
48
48
  },
49
49
  "homepage": "https://better-t-stack.dev/",
50
50
  "scripts": {
51
+ "build": "tsdown --publint",
52
+ "dev": "tsdown --watch",
51
53
  "check-types": "tsc --noEmit",
52
54
  "test": "bun run build && vitest run; rm -rf .smoke || true",
53
- "test:ui": "bun run build && vitest --ui"
55
+ "test:ui": "bun run build && vitest --ui",
56
+ "prepublishOnly": "npm run build"
54
57
  },
55
58
  "exports": {
56
59
  ".": {
57
- "import": "./src/index.ts"
60
+ "types": "./dist/index.d.ts",
61
+ "import": "./dist/index.js"
58
62
  },
59
63
  "./cli": {
60
- "import": "./src/cli.ts"
64
+ "import": "./dist/cli.js"
61
65
  }
62
66
  },
63
67
  "dependencies": {
68
+ "@better-t-stack/types": "3.7.3",
64
69
  "@biomejs/js-api": "^3.0.0",
65
70
  "@biomejs/wasm-nodejs": "^2.2.6",
66
71
  "@clack/prompts": "^1.0.0-alpha.6",
@@ -79,7 +84,6 @@
79
84
  "zod": "^4.1.13"
80
85
  },
81
86
  "devDependencies": {
82
- "@create-better-t-stack/types": "1.0.0",
83
87
  "@types/fs-extra": "^11.0.4",
84
88
  "@types/node": "^24.9.1",
85
89
  "@vitest/ui": "^3.2.4",
package/src/cli.ts DELETED
@@ -1,3 +0,0 @@
1
- import { createBtsCli } from "./index";
2
-
3
- createBtsCli().run();
package/src/constants.ts DELETED
@@ -1,188 +0,0 @@
1
- import path from "node:path";
2
- import { fileURLToPath } from "node:url";
3
- import { getUserPkgManager } from "./utils/get-package-manager";
4
-
5
- const __filename = fileURLToPath(import.meta.url);
6
- const distPath = path.dirname(__filename);
7
- export const PKG_ROOT = path.join(distPath, "../");
8
-
9
- export const DEFAULT_CONFIG_BASE = {
10
- projectName: "my-better-t-app",
11
- relativePath: "my-better-t-app",
12
- frontend: ["tanstack-router"],
13
- database: "sqlite",
14
- orm: "drizzle",
15
- auth: "better-auth",
16
- payments: "none",
17
- addons: ["turborepo"],
18
- examples: [],
19
- git: true,
20
- install: true,
21
- dbSetup: "none",
22
- backend: "hono",
23
- runtime: "bun",
24
- api: "trpc",
25
- webDeploy: "none",
26
- serverDeploy: "none",
27
- } as const;
28
-
29
- export function getDefaultConfig() {
30
- return {
31
- ...DEFAULT_CONFIG_BASE,
32
- projectDir: path.resolve(process.cwd(), DEFAULT_CONFIG_BASE.projectName),
33
- packageManager: getUserPkgManager(),
34
- frontend: [...DEFAULT_CONFIG_BASE.frontend],
35
- addons: [...DEFAULT_CONFIG_BASE.addons],
36
- examples: [...DEFAULT_CONFIG_BASE.examples],
37
- };
38
- }
39
-
40
- export const DEFAULT_CONFIG = getDefaultConfig();
41
-
42
- export const dependencyVersionMap = {
43
- typescript: "^5",
44
-
45
- "better-auth": "^1.4.5",
46
- "@better-auth/expo": "^1.4.5",
47
-
48
- "@clerk/nextjs": "^6.31.5",
49
- "@clerk/clerk-react": "^5.45.0",
50
- "@clerk/tanstack-react-start": "^0.26.3",
51
- "@clerk/clerk-expo": "^2.14.25",
52
-
53
- "drizzle-orm": "^0.45.0",
54
- "drizzle-kit": "^0.31.8",
55
- "@planetscale/database": "^1.19.0",
56
-
57
- "@libsql/client": "^0.14.0",
58
- libsql: "^0.5.22",
59
-
60
- "@neondatabase/serverless": "^1.0.2",
61
- pg: "^8.16.3",
62
- "@types/pg": "^8.15.6",
63
- "@types/ws": "^8.18.1",
64
- ws: "^8.18.3",
65
-
66
- mysql2: "^3.14.0",
67
-
68
- "@prisma/client": "^7.0.1",
69
- prisma: "^7.0.1",
70
- "@prisma/adapter-d1": "^7.0.1",
71
- "@prisma/adapter-neon": "^7.0.1",
72
- "@prisma/adapter-mariadb": "^7.0.1",
73
- "@prisma/adapter-libsql": "^7.0.1",
74
- "@prisma/adapter-better-sqlite3": "^7.0.1",
75
- "@prisma/adapter-pg": "^7.0.1",
76
- "@prisma/adapter-planetscale": "^7.0.1",
77
-
78
- mongoose: "^8.14.0",
79
-
80
- "vite-plugin-pwa": "^1.0.1",
81
- "@vite-pwa/assets-generator": "^1.0.0",
82
-
83
- "@tauri-apps/cli": "^2.4.0",
84
-
85
- "@biomejs/biome": "^2.2.0",
86
- oxlint: "^1.12.0",
87
-
88
- husky: "^9.1.7",
89
- "lint-staged": "^16.1.2",
90
-
91
- tsx: "^4.19.2",
92
- "@types/node": "^22.13.11",
93
-
94
- "@types/bun": "^1.3.4",
95
-
96
- "@elysiajs/node": "^1.3.1",
97
-
98
- "@elysiajs/cors": "^1.3.3",
99
- "@elysiajs/trpc": "^1.1.0",
100
- elysia: "^1.3.21",
101
-
102
- "@hono/node-server": "^1.14.4",
103
- "@hono/trpc-server": "^0.4.0",
104
- hono: "^4.8.2",
105
-
106
- cors: "^2.8.5",
107
- express: "^5.1.0",
108
- "@types/express": "^5.0.1",
109
- "@types/cors": "^2.8.17",
110
-
111
- fastify: "^5.3.3",
112
- "@fastify/cors": "^11.0.1",
113
-
114
- turbo: "^2.5.4",
115
-
116
- ai: "^5.0.49",
117
- "@ai-sdk/google": "^2.0.13",
118
- "@ai-sdk/vue": "^2.0.49",
119
- "@ai-sdk/svelte": "^3.0.39",
120
- "@ai-sdk/react": "^2.0.39",
121
- streamdown: "^1.3.0",
122
- shiki: "^3.12.2",
123
-
124
- "@orpc/server": "^1.10.0",
125
- "@orpc/client": "^1.10.0",
126
- "@orpc/openapi": "^1.10.0",
127
- "@orpc/zod": "^1.10.0",
128
- "@orpc/tanstack-query": "^1.10.0",
129
-
130
- "@trpc/tanstack-react-query": "^11.5.0",
131
- "@trpc/server": "^11.5.0",
132
- "@trpc/client": "^11.5.0",
133
-
134
- next: "^16.0.7",
135
-
136
- convex: "^1.29.3",
137
- "@convex-dev/react-query": "^0.1.0",
138
- "convex-svelte": "^0.0.12",
139
- "convex-nuxt": "0.1.5",
140
- "convex-vue": "^0.1.5",
141
- "@convex-dev/better-auth": "^0.9.7",
142
-
143
- "@tanstack/svelte-query": "^5.85.3",
144
- "@tanstack/svelte-query-devtools": "^5.85.3",
145
-
146
- "@tanstack/vue-query-devtools": "^5.90.2",
147
- "@tanstack/vue-query": "^5.90.2",
148
-
149
- "@tanstack/react-query-devtools": "^5.85.5",
150
- "@tanstack/react-query": "^5.85.5",
151
-
152
- "@tanstack/solid-query": "^5.87.4",
153
- "@tanstack/solid-query-devtools": "^5.87.4",
154
- "@tanstack/solid-router-devtools": "^1.131.44",
155
-
156
- wrangler: "^4.40.3",
157
- "@cloudflare/vite-plugin": "^1.13.8",
158
- "@opennextjs/cloudflare": "^1.6.5",
159
- "nitro-cloudflare-dev": "^0.2.2",
160
- "@sveltejs/adapter-cloudflare": "^7.2.1",
161
- "@cloudflare/workers-types": "^4.20250822.0",
162
-
163
- alchemy: "^0.77.0",
164
-
165
- dotenv: "^17.2.2",
166
- tsdown: "^0.16.5",
167
- zod: "^4.1.13",
168
- srvx: "0.8.15",
169
-
170
- "@polar-sh/better-auth": "^1.1.3",
171
- "@polar-sh/sdk": "^0.34.16",
172
- } as const;
173
-
174
- export type AvailableDependencies = keyof typeof dependencyVersionMap;
175
-
176
- export const ADDON_COMPATIBILITY = {
177
- pwa: ["tanstack-router", "react-router", "solid", "next"],
178
- tauri: ["tanstack-router", "react-router", "nuxt", "svelte", "solid", "next"],
179
- biome: [],
180
- husky: [],
181
- turborepo: [],
182
- starlight: [],
183
- ultracite: [],
184
- ruler: [],
185
- oxlint: [],
186
- fumadocs: [],
187
- none: [],
188
- } as const;
@@ -1,226 +0,0 @@
1
- import path from "node:path";
2
- import { log, spinner } from "@clack/prompts";
3
- import { execa } from "execa";
4
- import fs from "fs-extra";
5
- import pc from "picocolors";
6
- import type { Frontend, PackageManager, ProjectConfig } from "../../types";
7
- import { addPackageDependency } from "../../utils/add-package-deps";
8
- import { getPackageExecutionCommand } from "../../utils/package-runner";
9
- import { setupFumadocs } from "./fumadocs-setup";
10
- import { setupRuler } from "./ruler-setup";
11
- import { setupStarlight } from "./starlight-setup";
12
- import { setupTauri } from "./tauri-setup";
13
- import { setupUltracite } from "./ultracite-setup";
14
- import { addPwaToViteConfig } from "./vite-pwa-setup";
15
-
16
- export async function setupAddons(config: ProjectConfig, isAddCommand = false) {
17
- const { addons, frontend, projectDir, packageManager } = config;
18
- const hasReactWebFrontend =
19
- frontend.includes("react-router") ||
20
- frontend.includes("tanstack-router") ||
21
- frontend.includes("next");
22
- const hasNuxtFrontend = frontend.includes("nuxt");
23
- const hasSvelteFrontend = frontend.includes("svelte");
24
- const hasSolidFrontend = frontend.includes("solid");
25
- const hasNextFrontend = frontend.includes("next");
26
-
27
- if (addons.includes("turborepo")) {
28
- await addPackageDependency({
29
- devDependencies: ["turbo"],
30
- projectDir,
31
- });
32
-
33
- if (isAddCommand) {
34
- log.info(`${pc.yellow("Update your package.json scripts:")}
35
-
36
- ${pc.dim("Replace:")} ${pc.yellow('"pnpm -r dev"')} ${pc.dim("→")} ${pc.green('"turbo dev"')}
37
- ${pc.dim("Replace:")} ${pc.yellow('"pnpm --filter web dev"')} ${pc.dim(
38
- "→",
39
- )} ${pc.green('"turbo -F web dev"')}
40
-
41
- ${pc.cyan("Docs:")} ${pc.underline("https://turborepo.com/docs")}
42
- `);
43
- }
44
- }
45
-
46
- if (addons.includes("pwa") && (hasReactWebFrontend || hasSolidFrontend)) {
47
- await setupPwa(projectDir, frontend);
48
- }
49
- if (
50
- addons.includes("tauri") &&
51
- (hasReactWebFrontend ||
52
- hasNuxtFrontend ||
53
- hasSvelteFrontend ||
54
- hasSolidFrontend ||
55
- hasNextFrontend)
56
- ) {
57
- await setupTauri(config);
58
- }
59
- const hasUltracite = addons.includes("ultracite");
60
- const hasBiome = addons.includes("biome");
61
- const hasHusky = addons.includes("husky");
62
- const hasOxlint = addons.includes("oxlint");
63
-
64
- if (hasUltracite) {
65
- await setupUltracite(config, hasHusky);
66
- } else {
67
- if (hasBiome) {
68
- await setupBiome(projectDir);
69
- }
70
- if (hasHusky) {
71
- let linter: "biome" | "oxlint" | undefined;
72
- if (hasOxlint) {
73
- linter = "oxlint";
74
- } else if (hasBiome) {
75
- linter = "biome";
76
- }
77
- await setupHusky(projectDir, linter);
78
- }
79
- }
80
-
81
- if (addons.includes("oxlint")) {
82
- await setupOxlint(projectDir, packageManager);
83
- }
84
- if (addons.includes("starlight")) {
85
- await setupStarlight(config);
86
- }
87
-
88
- if (addons.includes("ruler")) {
89
- await setupRuler(config);
90
- }
91
- if (addons.includes("fumadocs")) {
92
- await setupFumadocs(config);
93
- }
94
- }
95
-
96
- function getWebAppDir(projectDir: string, frontends: Frontend[]) {
97
- if (
98
- frontends.some((f) =>
99
- ["react-router", "tanstack-router", "nuxt", "svelte", "solid"].includes(f),
100
- )
101
- ) {
102
- return path.join(projectDir, "apps/web");
103
- }
104
- return path.join(projectDir, "apps/web");
105
- }
106
-
107
- export async function setupBiome(projectDir: string) {
108
- await addPackageDependency({
109
- devDependencies: ["@biomejs/biome"],
110
- projectDir,
111
- });
112
-
113
- const packageJsonPath = path.join(projectDir, "package.json");
114
- if (await fs.pathExists(packageJsonPath)) {
115
- const packageJson = await fs.readJson(packageJsonPath);
116
-
117
- packageJson.scripts = {
118
- ...packageJson.scripts,
119
- check: "biome check --write .",
120
- };
121
-
122
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
123
- }
124
- }
125
-
126
- export async function setupHusky(projectDir: string, linter?: "biome" | "oxlint") {
127
- await addPackageDependency({
128
- devDependencies: ["husky", "lint-staged"],
129
- projectDir,
130
- });
131
-
132
- const packageJsonPath = path.join(projectDir, "package.json");
133
- if (await fs.pathExists(packageJsonPath)) {
134
- const packageJson = await fs.readJson(packageJsonPath);
135
-
136
- packageJson.scripts = {
137
- ...packageJson.scripts,
138
- prepare: "husky",
139
- };
140
-
141
- if (linter === "oxlint") {
142
- packageJson["lint-staged"] = {
143
- "**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx,vue,astro,svelte}": "oxlint",
144
- };
145
- } else if (linter === "biome") {
146
- packageJson["lint-staged"] = {
147
- "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": ["biome check --write ."],
148
- };
149
- } else {
150
- packageJson["lint-staged"] = {
151
- "**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx,vue,astro,svelte}": "",
152
- };
153
- }
154
-
155
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
156
- }
157
- }
158
-
159
- async function setupPwa(projectDir: string, frontends: Frontend[]) {
160
- const isCompatibleFrontend = frontends.some((f) =>
161
- ["react-router", "tanstack-router", "solid"].includes(f),
162
- );
163
- if (!isCompatibleFrontend) return;
164
-
165
- const clientPackageDir = getWebAppDir(projectDir, frontends);
166
-
167
- if (!(await fs.pathExists(clientPackageDir))) {
168
- return;
169
- }
170
-
171
- await addPackageDependency({
172
- dependencies: ["vite-plugin-pwa"],
173
- devDependencies: ["@vite-pwa/assets-generator"],
174
- projectDir: clientPackageDir,
175
- });
176
-
177
- const clientPackageJsonPath = path.join(clientPackageDir, "package.json");
178
- if (await fs.pathExists(clientPackageJsonPath)) {
179
- const packageJson = await fs.readJson(clientPackageJsonPath);
180
-
181
- packageJson.scripts = {
182
- ...packageJson.scripts,
183
- "generate-pwa-assets": "pwa-assets-generator",
184
- };
185
-
186
- await fs.writeJson(clientPackageJsonPath, packageJson, { spaces: 2 });
187
- }
188
-
189
- const viteConfigTs = path.join(clientPackageDir, "vite.config.ts");
190
-
191
- if (await fs.pathExists(viteConfigTs)) {
192
- await addPwaToViteConfig(viteConfigTs, path.basename(projectDir));
193
- }
194
- }
195
-
196
- async function setupOxlint(projectDir: string, packageManager: PackageManager) {
197
- await addPackageDependency({
198
- devDependencies: ["oxlint"],
199
- projectDir,
200
- });
201
-
202
- const packageJsonPath = path.join(projectDir, "package.json");
203
- if (await fs.pathExists(packageJsonPath)) {
204
- const packageJson = await fs.readJson(packageJsonPath);
205
-
206
- packageJson.scripts = {
207
- ...packageJson.scripts,
208
- check: "oxlint",
209
- };
210
-
211
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
212
- }
213
-
214
- const oxlintInitCommand = getPackageExecutionCommand(packageManager, "oxlint@latest --init");
215
-
216
- const s = spinner();
217
- s.start("Initializing oxlint...");
218
-
219
- await execa(oxlintInitCommand, {
220
- cwd: projectDir,
221
- env: { CI: "true" },
222
- shell: true,
223
- });
224
-
225
- s.stop("oxlint initialized successfully!");
226
- }
@@ -1,104 +0,0 @@
1
- import path from "node:path";
2
- import fs from "fs-extra";
3
- import type { AvailableDependencies } from "../../constants";
4
- import type { ProjectConfig } from "../../types";
5
- import { addPackageDependency } from "../../utils/add-package-deps";
6
-
7
- export async function setupExamples(config: ProjectConfig) {
8
- const { examples, frontend, backend, projectDir, orm, database } = config;
9
-
10
- if (backend === "convex" || !examples || examples.length === 0 || examples[0] === "none") {
11
- return;
12
- }
13
-
14
- const apiDir = path.join(projectDir, "packages/api");
15
- const apiDirExists = await fs.pathExists(apiDir);
16
-
17
- if (apiDirExists && backend !== "none") {
18
- if (orm === "drizzle") {
19
- const dependencies: AvailableDependencies[] = ["drizzle-orm"];
20
- if (database === "postgres") {
21
- // Workaround: not sure there is a weird types error if i add it in dev dep
22
- dependencies.push("@types/pg");
23
- }
24
- await addPackageDependency({
25
- dependencies,
26
- projectDir: apiDir,
27
- });
28
- } else if (orm === "prisma") {
29
- await addPackageDependency({
30
- dependencies: ["@prisma/client"],
31
- projectDir: apiDir,
32
- });
33
- } else if (orm === "mongoose") {
34
- await addPackageDependency({
35
- dependencies: ["mongoose"],
36
- projectDir: apiDir,
37
- });
38
- }
39
- }
40
-
41
- if (examples.includes("ai")) {
42
- const webClientDir = path.join(projectDir, "apps/web");
43
- const nativeClientDir = path.join(projectDir, "apps/native");
44
- const apiDir = path.join(projectDir, "packages/api");
45
-
46
- const webClientDirExists = await fs.pathExists(webClientDir);
47
- const nativeClientDirExists = await fs.pathExists(nativeClientDir);
48
- const apiDirExists = await fs.pathExists(apiDir);
49
-
50
- const hasNuxt = frontend.includes("nuxt");
51
- const hasSvelte = frontend.includes("svelte");
52
- const hasReactWeb =
53
- frontend.includes("react-router") ||
54
- frontend.includes("tanstack-router") ||
55
- frontend.includes("next") ||
56
- frontend.includes("tanstack-start");
57
- const hasNext = frontend.includes("next");
58
- const hasReactNative =
59
- frontend.includes("native-bare") ||
60
- frontend.includes("native-uniwind") ||
61
- frontend.includes("native-unistyles");
62
-
63
- if (webClientDirExists) {
64
- const dependencies: AvailableDependencies[] = ["ai"];
65
- if (hasNuxt) {
66
- dependencies.push("@ai-sdk/vue");
67
- } else if (hasSvelte) {
68
- dependencies.push("@ai-sdk/svelte");
69
- } else if (hasReactWeb) {
70
- dependencies.push("@ai-sdk/react", "streamdown");
71
- }
72
-
73
- if (hasNext) {
74
- dependencies.push("shiki");
75
- }
76
-
77
- await addPackageDependency({
78
- dependencies,
79
- projectDir: webClientDir,
80
- });
81
- }
82
-
83
- if (nativeClientDirExists && hasReactNative) {
84
- await addPackageDependency({
85
- dependencies: ["ai", "@ai-sdk/react"],
86
- projectDir: nativeClientDir,
87
- });
88
- }
89
-
90
- if (apiDirExists && backend !== "none") {
91
- await addPackageDependency({
92
- dependencies: ["ai", "@ai-sdk/google"],
93
- projectDir: apiDir,
94
- });
95
- }
96
-
97
- if (backend === "self" && webClientDirExists) {
98
- await addPackageDependency({
99
- dependencies: ["ai", "@ai-sdk/google"],
100
- projectDir: webClientDir,
101
- });
102
- }
103
- }
104
- }
@@ -1,103 +0,0 @@
1
- import path from "node:path";
2
- import { isCancel, log, select, spinner } from "@clack/prompts";
3
- import consola from "consola";
4
- import { execa } from "execa";
5
- import fs from "fs-extra";
6
- import pc from "picocolors";
7
- import type { ProjectConfig } from "../../types";
8
- import { exitCancelled } from "../../utils/errors";
9
- import { getPackageExecutionCommand } from "../../utils/package-runner";
10
-
11
- type FumadocsTemplate =
12
- | "next-mdx"
13
- | "waku"
14
- | "react-router"
15
- | "react-router-spa"
16
- | "tanstack-start";
17
-
18
- const TEMPLATES = {
19
- "next-mdx": {
20
- label: "Next.js: Fumadocs MDX",
21
- hint: "Recommended template with MDX support",
22
- value: "+next+fuma-docs-mdx",
23
- },
24
- waku: {
25
- label: "Waku: Content Collections",
26
- hint: "Template using Waku with content collections",
27
- value: "waku",
28
- },
29
- "react-router": {
30
- label: "React Router: MDX Remote",
31
- hint: "Template for React Router with MDX remote",
32
- value: "react-router",
33
- },
34
- "react-router-spa": {
35
- label: "React Router: SPA",
36
- hint: "Template for React Router SPA",
37
- value: "react-router-spa",
38
- },
39
- "tanstack-start": {
40
- label: "Tanstack Start: MDX Remote",
41
- hint: "Template for Tanstack Start with MDX remote",
42
- value: "tanstack-start",
43
- },
44
- } as const;
45
-
46
- export async function setupFumadocs(config: ProjectConfig) {
47
- const { packageManager, projectDir } = config;
48
-
49
- try {
50
- log.info("Setting up Fumadocs...");
51
-
52
- const template = await select<FumadocsTemplate>({
53
- message: "Choose a template",
54
- options: Object.entries(TEMPLATES).map(([key, template]) => ({
55
- value: key as FumadocsTemplate,
56
- label: template.label,
57
- hint: template.hint,
58
- })),
59
- initialValue: "next-mdx",
60
- });
61
-
62
- if (isCancel(template)) return exitCancelled("Operation cancelled");
63
-
64
- const templateArg = TEMPLATES[template].value;
65
-
66
- const commandWithArgs = `create-fumadocs-app@latest fumadocs --template ${templateArg} --src --pm ${packageManager} --no-git`;
67
-
68
- const fumadocsInitCommand = getPackageExecutionCommand(packageManager, commandWithArgs);
69
-
70
- const appsDir = path.join(projectDir, "apps");
71
- await fs.ensureDir(appsDir);
72
-
73
- const s = spinner();
74
- s.start("Running Fumadocs create command...");
75
-
76
- await execa(fumadocsInitCommand, {
77
- cwd: appsDir,
78
- env: { CI: "true" },
79
- shell: true,
80
- });
81
-
82
- const fumadocsDir = path.join(projectDir, "apps", "fumadocs");
83
- const packageJsonPath = path.join(fumadocsDir, "package.json");
84
-
85
- if (await fs.pathExists(packageJsonPath)) {
86
- const packageJson = await fs.readJson(packageJsonPath);
87
- packageJson.name = "fumadocs";
88
-
89
- if (packageJson.scripts?.dev) {
90
- packageJson.scripts.dev = `${packageJson.scripts.dev} --port=4000`;
91
- }
92
-
93
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
94
- }
95
-
96
- s.stop("Fumadocs setup complete!");
97
- } catch (error) {
98
- log.error(pc.red("Failed to set up Fumadocs"));
99
- if (error instanceof Error) {
100
- consola.error(pc.red(error.message));
101
- }
102
- }
103
- }