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.
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +8 -0
- package/dist/index.d.ts +347 -0
- package/dist/index.js +4 -0
- package/dist/src-yXf02Wox.js +7077 -0
- package/package.json +11 -7
- package/src/cli.ts +0 -3
- package/src/constants.ts +0 -188
- package/src/helpers/addons/addons-setup.ts +0 -226
- package/src/helpers/addons/examples-setup.ts +0 -104
- package/src/helpers/addons/fumadocs-setup.ts +0 -103
- package/src/helpers/addons/ruler-setup.ts +0 -139
- package/src/helpers/addons/starlight-setup.ts +0 -51
- package/src/helpers/addons/tauri-setup.ts +0 -96
- package/src/helpers/addons/ultracite-setup.ts +0 -232
- package/src/helpers/addons/vite-pwa-setup.ts +0 -59
- package/src/helpers/core/add-addons.ts +0 -85
- package/src/helpers/core/add-deployment.ts +0 -102
- package/src/helpers/core/api-setup.ts +0 -280
- package/src/helpers/core/auth-setup.ts +0 -203
- package/src/helpers/core/backend-setup.ts +0 -73
- package/src/helpers/core/command-handlers.ts +0 -354
- package/src/helpers/core/convex-codegen.ts +0 -14
- package/src/helpers/core/create-project.ts +0 -133
- package/src/helpers/core/create-readme.ts +0 -687
- package/src/helpers/core/db-setup.ts +0 -184
- package/src/helpers/core/detect-project-config.ts +0 -41
- package/src/helpers/core/env-setup.ts +0 -449
- package/src/helpers/core/git.ts +0 -31
- package/src/helpers/core/install-dependencies.ts +0 -32
- package/src/helpers/core/payments-setup.ts +0 -48
- package/src/helpers/core/post-installation.ts +0 -383
- package/src/helpers/core/project-config.ts +0 -246
- package/src/helpers/core/runtime-setup.ts +0 -76
- package/src/helpers/core/template-manager.ts +0 -917
- package/src/helpers/core/workspace-setup.ts +0 -184
- package/src/helpers/database-providers/d1-setup.ts +0 -28
- package/src/helpers/database-providers/docker-compose-setup.ts +0 -50
- package/src/helpers/database-providers/mongodb-atlas-setup.ts +0 -186
- package/src/helpers/database-providers/neon-setup.ts +0 -243
- package/src/helpers/database-providers/planetscale-setup.ts +0 -78
- package/src/helpers/database-providers/prisma-postgres-setup.ts +0 -196
- package/src/helpers/database-providers/supabase-setup.ts +0 -218
- package/src/helpers/database-providers/turso-setup.ts +0 -309
- package/src/helpers/deployment/alchemy/alchemy-combined-setup.ts +0 -80
- package/src/helpers/deployment/alchemy/alchemy-next-setup.ts +0 -51
- package/src/helpers/deployment/alchemy/alchemy-nuxt-setup.ts +0 -104
- package/src/helpers/deployment/alchemy/alchemy-react-router-setup.ts +0 -32
- package/src/helpers/deployment/alchemy/alchemy-solid-setup.ts +0 -32
- package/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts +0 -98
- package/src/helpers/deployment/alchemy/alchemy-tanstack-router-setup.ts +0 -33
- package/src/helpers/deployment/alchemy/alchemy-tanstack-start-setup.ts +0 -98
- package/src/helpers/deployment/alchemy/env-dts-setup.ts +0 -76
- package/src/helpers/deployment/alchemy/index.ts +0 -7
- package/src/helpers/deployment/server-deploy-setup.ts +0 -55
- package/src/helpers/deployment/web-deploy-setup.ts +0 -58
- package/src/index.ts +0 -253
- package/src/prompts/addons.ts +0 -178
- package/src/prompts/api.ts +0 -49
- package/src/prompts/auth.ts +0 -84
- package/src/prompts/backend.ts +0 -83
- package/src/prompts/config-prompts.ts +0 -138
- package/src/prompts/database-setup.ts +0 -112
- package/src/prompts/database.ts +0 -57
- package/src/prompts/examples.ts +0 -64
- package/src/prompts/frontend.ts +0 -118
- package/src/prompts/git.ts +0 -16
- package/src/prompts/install.ts +0 -16
- package/src/prompts/orm.ts +0 -53
- package/src/prompts/package-manager.ts +0 -32
- package/src/prompts/payments.ts +0 -50
- package/src/prompts/project-name.ts +0 -86
- package/src/prompts/runtime.ts +0 -47
- package/src/prompts/server-deploy.ts +0 -91
- package/src/prompts/web-deploy.ts +0 -107
- package/src/types.ts +0 -2
- package/src/utils/add-package-deps.ts +0 -57
- package/src/utils/analytics.ts +0 -39
- package/src/utils/better-auth-plugin-setup.ts +0 -71
- package/src/utils/biome-formatter.ts +0 -82
- package/src/utils/bts-config.ts +0 -122
- package/src/utils/command-exists.ts +0 -16
- package/src/utils/compatibility-rules.ts +0 -319
- package/src/utils/compatibility.ts +0 -11
- package/src/utils/config-processing.ts +0 -130
- package/src/utils/config-validation.ts +0 -470
- package/src/utils/display-config.ts +0 -96
- package/src/utils/docker-utils.ts +0 -70
- package/src/utils/errors.ts +0 -32
- package/src/utils/generate-reproducible-command.ts +0 -53
- package/src/utils/get-latest-cli-version.ts +0 -11
- package/src/utils/get-package-manager.ts +0 -13
- package/src/utils/open-url.ts +0 -25
- package/src/utils/package-runner.ts +0 -23
- package/src/utils/project-directory.ts +0 -102
- package/src/utils/project-name-validation.ts +0 -43
- package/src/utils/render-title.ts +0 -48
- package/src/utils/setup-catalogs.ts +0 -192
- package/src/utils/sponsors.ts +0 -101
- package/src/utils/telemetry.ts +0 -19
- package/src/utils/template-processor.ts +0 -64
- package/src/utils/templates.ts +0 -94
- package/src/utils/ts-morph.ts +0 -26
- package/src/validation.ts +0 -117
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import os from "node:os";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { confirm, isCancel, log, select, spinner, text } from "@clack/prompts";
|
|
4
|
-
import consola from "consola";
|
|
5
|
-
import { $ } from "execa";
|
|
6
|
-
import pc from "picocolors";
|
|
7
|
-
import type { ProjectConfig } from "../../types";
|
|
8
|
-
import { commandExists } from "../../utils/command-exists";
|
|
9
|
-
import { exitCancelled } from "../../utils/errors";
|
|
10
|
-
import { addEnvVariablesToFile, type EnvVariable } from "../core/env-setup";
|
|
11
|
-
|
|
12
|
-
type TursoConfig = {
|
|
13
|
-
dbUrl: string;
|
|
14
|
-
authToken: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
async function isTursoInstalled() {
|
|
18
|
-
return commandExists("turso");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function isTursoLoggedIn() {
|
|
22
|
-
try {
|
|
23
|
-
const output = await $`turso auth whoami`;
|
|
24
|
-
return !output.stdout.includes("You are not logged in");
|
|
25
|
-
} catch {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function loginToTurso() {
|
|
31
|
-
const s = spinner();
|
|
32
|
-
try {
|
|
33
|
-
s.start("Logging in to Turso...");
|
|
34
|
-
await $`turso auth login`;
|
|
35
|
-
s.stop("Logged into Turso");
|
|
36
|
-
return true;
|
|
37
|
-
} catch {
|
|
38
|
-
s.stop(pc.red("Failed to log in to Turso"));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async function installTursoCLI(isMac: boolean) {
|
|
43
|
-
const s = spinner();
|
|
44
|
-
try {
|
|
45
|
-
s.start("Installing Turso CLI...");
|
|
46
|
-
|
|
47
|
-
if (isMac) {
|
|
48
|
-
await $`brew install tursodatabase/tap/turso`;
|
|
49
|
-
} else {
|
|
50
|
-
const { stdout: installScript } = await $`curl -sSfL https://get.tur.so/install.sh`;
|
|
51
|
-
await $`bash -c '${installScript}'`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
s.stop("Turso CLI installed");
|
|
55
|
-
return true;
|
|
56
|
-
} catch (error) {
|
|
57
|
-
if (error instanceof Error && error.message.includes("User force closed")) {
|
|
58
|
-
s.stop("Turso CLI installation cancelled");
|
|
59
|
-
log.warn(pc.yellow("Turso CLI installation cancelled by user"));
|
|
60
|
-
throw new Error("Installation cancelled");
|
|
61
|
-
}
|
|
62
|
-
s.stop(pc.red("Failed to install Turso CLI"));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function getTursoGroups() {
|
|
67
|
-
const s = spinner();
|
|
68
|
-
try {
|
|
69
|
-
s.start("Fetching Turso groups...");
|
|
70
|
-
const { stdout } = await $`turso group list`;
|
|
71
|
-
const lines = stdout.trim().split("\n");
|
|
72
|
-
|
|
73
|
-
if (lines.length <= 1) {
|
|
74
|
-
s.stop("No Turso groups found");
|
|
75
|
-
return [];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const groups = lines.slice(1).map((line) => {
|
|
79
|
-
const [name, locations, version, status] = line.trim().split(/\s{2,}/);
|
|
80
|
-
return { name, locations, version, status };
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
s.stop(`Found ${groups.length} Turso groups`);
|
|
84
|
-
return groups;
|
|
85
|
-
} catch (error) {
|
|
86
|
-
s.stop(pc.red("Error fetching Turso groups"));
|
|
87
|
-
console.error("Error fetching Turso groups:", error);
|
|
88
|
-
return [];
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async function selectTursoGroup() {
|
|
93
|
-
const groups = await getTursoGroups();
|
|
94
|
-
|
|
95
|
-
if (groups.length === 0) {
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (groups.length === 1) {
|
|
100
|
-
log.info(`Using the only available group: ${pc.blue(groups[0].name)}`);
|
|
101
|
-
return groups[0].name;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const groupOptions = groups.map((group) => ({
|
|
105
|
-
value: group.name,
|
|
106
|
-
label: `${group.name} (${group.locations})`,
|
|
107
|
-
}));
|
|
108
|
-
|
|
109
|
-
const selectedGroup = await select({
|
|
110
|
-
message: "Select a Turso database group:",
|
|
111
|
-
options: groupOptions,
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
if (isCancel(selectedGroup)) return exitCancelled("Operation cancelled");
|
|
115
|
-
|
|
116
|
-
return selectedGroup as string;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async function createTursoDatabase(dbName: string, groupName: string | null) {
|
|
120
|
-
const s = spinner();
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
s.start(`Creating Turso database "${dbName}"${groupName ? ` in group "${groupName}"` : ""}...`);
|
|
124
|
-
|
|
125
|
-
if (groupName) {
|
|
126
|
-
await $`turso db create ${dbName} --group ${groupName}`;
|
|
127
|
-
} else {
|
|
128
|
-
await $`turso db create ${dbName}`;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
s.stop(`Turso database "${dbName}" created`);
|
|
132
|
-
} catch (error) {
|
|
133
|
-
s.stop(pc.red(`Failed to create database "${dbName}"`));
|
|
134
|
-
if (error instanceof Error && error.message.includes("already exists")) {
|
|
135
|
-
throw new Error("DATABASE_EXISTS");
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
s.start("Retrieving database connection details...");
|
|
140
|
-
try {
|
|
141
|
-
const { stdout: dbUrl } = await $`turso db show ${dbName} --url`;
|
|
142
|
-
const { stdout: authToken } = await $`turso db tokens create ${dbName}`;
|
|
143
|
-
|
|
144
|
-
s.stop("Database connection details retrieved");
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
dbUrl: dbUrl.trim(),
|
|
148
|
-
authToken: authToken.trim(),
|
|
149
|
-
};
|
|
150
|
-
} catch {
|
|
151
|
-
s.stop(pc.red("Failed to retrieve database connection details"));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async function writeEnvFile(
|
|
156
|
-
projectDir: string,
|
|
157
|
-
backend: ProjectConfig["backend"],
|
|
158
|
-
config?: TursoConfig,
|
|
159
|
-
) {
|
|
160
|
-
const targetApp = backend === "self" ? "apps/web" : "apps/server";
|
|
161
|
-
const envPath = path.join(projectDir, targetApp, ".env");
|
|
162
|
-
const variables: EnvVariable[] = [
|
|
163
|
-
{
|
|
164
|
-
key: "DATABASE_URL",
|
|
165
|
-
value: config?.dbUrl ?? "",
|
|
166
|
-
condition: true,
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
key: "DATABASE_AUTH_TOKEN",
|
|
170
|
-
value: config?.authToken ?? "",
|
|
171
|
-
condition: true,
|
|
172
|
-
},
|
|
173
|
-
];
|
|
174
|
-
await addEnvVariablesToFile(envPath, variables);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function displayManualSetupInstructions() {
|
|
178
|
-
log.info(`Manual Turso Setup Instructions:
|
|
179
|
-
|
|
180
|
-
1. Visit https://turso.tech and create an account
|
|
181
|
-
2. Create a new database from the dashboard
|
|
182
|
-
3. Get your database URL and authentication token
|
|
183
|
-
4. Add these credentials to the .env file in apps/server/.env
|
|
184
|
-
|
|
185
|
-
DATABASE_URL=your_database_url
|
|
186
|
-
DATABASE_AUTH_TOKEN=your_auth_token`);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export async function setupTurso(config: ProjectConfig, cliInput?: { manualDb?: boolean }) {
|
|
190
|
-
const { orm, projectDir, backend } = config;
|
|
191
|
-
const manualDb = cliInput?.manualDb ?? false;
|
|
192
|
-
const _isDrizzle = orm === "drizzle";
|
|
193
|
-
const setupSpinner = spinner();
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
if (manualDb) {
|
|
197
|
-
await writeEnvFile(projectDir, backend);
|
|
198
|
-
displayManualSetupInstructions();
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const mode = await select({
|
|
203
|
-
message: "Turso setup: choose mode",
|
|
204
|
-
options: [
|
|
205
|
-
{
|
|
206
|
-
label: "Automatic",
|
|
207
|
-
value: "auto",
|
|
208
|
-
hint: "Automated setup with provider CLI, sets .env",
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
label: "Manual",
|
|
212
|
-
value: "manual",
|
|
213
|
-
hint: "Manual setup, add env vars yourself",
|
|
214
|
-
},
|
|
215
|
-
],
|
|
216
|
-
initialValue: "auto",
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
if (isCancel(mode)) return exitCancelled("Operation cancelled");
|
|
220
|
-
|
|
221
|
-
if (mode === "manual") {
|
|
222
|
-
await writeEnvFile(projectDir, backend);
|
|
223
|
-
displayManualSetupInstructions();
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
setupSpinner.start("Checking Turso CLI availability...");
|
|
228
|
-
const platform = os.platform();
|
|
229
|
-
const isMac = platform === "darwin";
|
|
230
|
-
const _isLinux = platform === "linux";
|
|
231
|
-
const isWindows = platform === "win32";
|
|
232
|
-
|
|
233
|
-
if (isWindows) {
|
|
234
|
-
if (setupSpinner) setupSpinner.stop(pc.yellow("Turso setup not supported on Windows"));
|
|
235
|
-
log.warn(pc.yellow("Automatic Turso setup is not supported on Windows."));
|
|
236
|
-
await writeEnvFile(projectDir, backend);
|
|
237
|
-
displayManualSetupInstructions();
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (setupSpinner) setupSpinner.stop("Turso CLI availability checked");
|
|
242
|
-
|
|
243
|
-
const isCliInstalled = await isTursoInstalled();
|
|
244
|
-
|
|
245
|
-
if (!isCliInstalled) {
|
|
246
|
-
const shouldInstall = await confirm({
|
|
247
|
-
message: "Would you like to install Turso CLI?",
|
|
248
|
-
initialValue: true,
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
if (isCancel(shouldInstall)) return exitCancelled("Operation cancelled");
|
|
252
|
-
|
|
253
|
-
if (!shouldInstall) {
|
|
254
|
-
await writeEnvFile(projectDir, backend);
|
|
255
|
-
displayManualSetupInstructions();
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
await installTursoCLI(isMac);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const isLoggedIn = await isTursoLoggedIn();
|
|
263
|
-
if (!isLoggedIn) {
|
|
264
|
-
await loginToTurso();
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const selectedGroup = await selectTursoGroup();
|
|
268
|
-
|
|
269
|
-
let success = false;
|
|
270
|
-
let dbName = "";
|
|
271
|
-
let suggestedName = path.basename(projectDir);
|
|
272
|
-
|
|
273
|
-
while (!success) {
|
|
274
|
-
const dbNameResponse = await text({
|
|
275
|
-
message: "Enter a name for your database:",
|
|
276
|
-
defaultValue: suggestedName,
|
|
277
|
-
initialValue: suggestedName,
|
|
278
|
-
placeholder: suggestedName,
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
if (isCancel(dbNameResponse)) return exitCancelled("Operation cancelled");
|
|
282
|
-
|
|
283
|
-
dbName = dbNameResponse as string;
|
|
284
|
-
|
|
285
|
-
try {
|
|
286
|
-
const config = await createTursoDatabase(dbName, selectedGroup);
|
|
287
|
-
await writeEnvFile(projectDir, backend, config);
|
|
288
|
-
success = true;
|
|
289
|
-
} catch (error) {
|
|
290
|
-
if (error instanceof Error && error.message === "DATABASE_EXISTS") {
|
|
291
|
-
log.warn(pc.yellow(`Database "${pc.red(dbName)}" already exists`));
|
|
292
|
-
suggestedName = `${dbName}-${Math.floor(Math.random() * 1000)}`;
|
|
293
|
-
} else {
|
|
294
|
-
throw error;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
log.success("Turso database setup completed successfully!");
|
|
300
|
-
} catch (error) {
|
|
301
|
-
if (setupSpinner) setupSpinner.stop(pc.red("Turso CLI availability check failed"));
|
|
302
|
-
consola.error(
|
|
303
|
-
pc.red(`Error during Turso setup: ${error instanceof Error ? error.message : String(error)}`),
|
|
304
|
-
);
|
|
305
|
-
await writeEnvFile(projectDir, backend);
|
|
306
|
-
displayManualSetupInstructions();
|
|
307
|
-
log.success("Setup completed with manual configuration required.");
|
|
308
|
-
}
|
|
309
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import type { PackageManager, ProjectConfig } from "../../../types";
|
|
4
|
-
import { addPackageDependency } from "../../../utils/add-package-deps";
|
|
5
|
-
import { setupAlchemyServerDeploy } from "../server-deploy-setup";
|
|
6
|
-
import { setupNextAlchemyDeploy } from "./alchemy-next-setup";
|
|
7
|
-
import { setupNuxtAlchemyDeploy } from "./alchemy-nuxt-setup";
|
|
8
|
-
import { setupReactRouterAlchemyDeploy } from "./alchemy-react-router-setup";
|
|
9
|
-
import { setupSolidAlchemyDeploy } from "./alchemy-solid-setup";
|
|
10
|
-
import { setupSvelteAlchemyDeploy } from "./alchemy-svelte-setup";
|
|
11
|
-
import { setupTanStackRouterAlchemyDeploy } from "./alchemy-tanstack-router-setup";
|
|
12
|
-
import { setupTanStackStartAlchemyDeploy } from "./alchemy-tanstack-start-setup";
|
|
13
|
-
|
|
14
|
-
export async function setupCombinedAlchemyDeploy(
|
|
15
|
-
projectDir: string,
|
|
16
|
-
packageManager: PackageManager,
|
|
17
|
-
config: ProjectConfig,
|
|
18
|
-
) {
|
|
19
|
-
await addPackageDependency({
|
|
20
|
-
devDependencies: ["alchemy"],
|
|
21
|
-
projectDir,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const rootPkgPath = path.join(projectDir, "package.json");
|
|
25
|
-
if (await fs.pathExists(rootPkgPath)) {
|
|
26
|
-
const pkg = await fs.readJson(rootPkgPath);
|
|
27
|
-
|
|
28
|
-
pkg.scripts = {
|
|
29
|
-
...pkg.scripts,
|
|
30
|
-
deploy: "alchemy deploy",
|
|
31
|
-
destroy: "alchemy destroy",
|
|
32
|
-
dev: "alchemy dev",
|
|
33
|
-
};
|
|
34
|
-
await fs.writeJson(rootPkgPath, pkg, { spaces: 2 });
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const serverDir = path.join(projectDir, "apps/server");
|
|
38
|
-
if (await fs.pathExists(serverDir)) {
|
|
39
|
-
await setupAlchemyServerDeploy(serverDir, projectDir);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const frontend = config.frontend;
|
|
43
|
-
const isNext = frontend.includes("next");
|
|
44
|
-
const isNuxt = frontend.includes("nuxt");
|
|
45
|
-
const isSvelte = frontend.includes("svelte");
|
|
46
|
-
const isTanstackRouter = frontend.includes("tanstack-router");
|
|
47
|
-
const isTanstackStart = frontend.includes("tanstack-start");
|
|
48
|
-
const isReactRouter = frontend.includes("react-router");
|
|
49
|
-
const isSolid = frontend.includes("solid");
|
|
50
|
-
|
|
51
|
-
if (isNext) {
|
|
52
|
-
await setupNextAlchemyDeploy(projectDir, packageManager, {
|
|
53
|
-
skipAppScripts: true,
|
|
54
|
-
});
|
|
55
|
-
} else if (isNuxt) {
|
|
56
|
-
await setupNuxtAlchemyDeploy(projectDir, packageManager, {
|
|
57
|
-
skipAppScripts: true,
|
|
58
|
-
});
|
|
59
|
-
} else if (isSvelte) {
|
|
60
|
-
await setupSvelteAlchemyDeploy(projectDir, packageManager, {
|
|
61
|
-
skipAppScripts: true,
|
|
62
|
-
});
|
|
63
|
-
} else if (isTanstackStart) {
|
|
64
|
-
await setupTanStackStartAlchemyDeploy(projectDir, packageManager, {
|
|
65
|
-
skipAppScripts: true,
|
|
66
|
-
});
|
|
67
|
-
} else if (isTanstackRouter) {
|
|
68
|
-
await setupTanStackRouterAlchemyDeploy(projectDir, packageManager, {
|
|
69
|
-
skipAppScripts: true,
|
|
70
|
-
});
|
|
71
|
-
} else if (isReactRouter) {
|
|
72
|
-
await setupReactRouterAlchemyDeploy(projectDir, packageManager, {
|
|
73
|
-
skipAppScripts: true,
|
|
74
|
-
});
|
|
75
|
-
} else if (isSolid) {
|
|
76
|
-
await setupSolidAlchemyDeploy(projectDir, packageManager, {
|
|
77
|
-
skipAppScripts: true,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import type { PackageManager } from "../../../types";
|
|
4
|
-
import { addPackageDependency } from "../../../utils/add-package-deps";
|
|
5
|
-
|
|
6
|
-
export async function setupNextAlchemyDeploy(
|
|
7
|
-
projectDir: string,
|
|
8
|
-
_packageManager: PackageManager,
|
|
9
|
-
options?: { skipAppScripts?: boolean },
|
|
10
|
-
) {
|
|
11
|
-
const webAppDir = path.join(projectDir, "apps/web");
|
|
12
|
-
if (!(await fs.pathExists(webAppDir))) return;
|
|
13
|
-
|
|
14
|
-
await addPackageDependency({
|
|
15
|
-
dependencies: ["@opennextjs/cloudflare"],
|
|
16
|
-
devDependencies: ["alchemy", "wrangler", "@cloudflare/workers-types"],
|
|
17
|
-
projectDir: webAppDir,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const pkgPath = path.join(webAppDir, "package.json");
|
|
21
|
-
if (await fs.pathExists(pkgPath)) {
|
|
22
|
-
const pkg = await fs.readJson(pkgPath);
|
|
23
|
-
|
|
24
|
-
if (!options?.skipAppScripts) {
|
|
25
|
-
pkg.scripts = {
|
|
26
|
-
...pkg.scripts,
|
|
27
|
-
deploy: "alchemy deploy",
|
|
28
|
-
destroy: "alchemy destroy",
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const openNextConfigPath = path.join(webAppDir, "open-next.config.ts");
|
|
35
|
-
const openNextConfigContent = `import { defineCloudflareConfig } from "@opennextjs/cloudflare";
|
|
36
|
-
|
|
37
|
-
export default defineCloudflareConfig({});
|
|
38
|
-
`;
|
|
39
|
-
|
|
40
|
-
await fs.writeFile(openNextConfigPath, openNextConfigContent);
|
|
41
|
-
|
|
42
|
-
const gitignorePath = path.join(webAppDir, ".gitignore");
|
|
43
|
-
if (await fs.pathExists(gitignorePath)) {
|
|
44
|
-
const gitignoreContent = await fs.readFile(gitignorePath, "utf-8");
|
|
45
|
-
if (!gitignoreContent.includes("wrangler.jsonc")) {
|
|
46
|
-
await fs.appendFile(gitignorePath, "\nwrangler.jsonc\n");
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
await fs.writeFile(gitignorePath, "wrangler.jsonc\n");
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import { IndentationText, Node, Project, QuoteKind } from "ts-morph";
|
|
4
|
-
import type { PackageManager } from "../../../types";
|
|
5
|
-
import { addPackageDependency } from "../../../utils/add-package-deps";
|
|
6
|
-
|
|
7
|
-
export async function setupNuxtAlchemyDeploy(
|
|
8
|
-
projectDir: string,
|
|
9
|
-
_packageManager: PackageManager,
|
|
10
|
-
options?: { skipAppScripts?: boolean },
|
|
11
|
-
) {
|
|
12
|
-
const webAppDir = path.join(projectDir, "apps/web");
|
|
13
|
-
if (!(await fs.pathExists(webAppDir))) return;
|
|
14
|
-
|
|
15
|
-
await addPackageDependency({
|
|
16
|
-
devDependencies: ["alchemy", "nitro-cloudflare-dev", "wrangler"],
|
|
17
|
-
projectDir: webAppDir,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const pkgPath = path.join(webAppDir, "package.json");
|
|
21
|
-
if (await fs.pathExists(pkgPath)) {
|
|
22
|
-
const pkg = await fs.readJson(pkgPath);
|
|
23
|
-
|
|
24
|
-
if (!options?.skipAppScripts) {
|
|
25
|
-
pkg.scripts = {
|
|
26
|
-
...pkg.scripts,
|
|
27
|
-
deploy: "alchemy deploy",
|
|
28
|
-
destroy: "alchemy destroy",
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const nuxtConfigPath = path.join(webAppDir, "nuxt.config.ts");
|
|
35
|
-
if (!(await fs.pathExists(nuxtConfigPath))) return;
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
const project = new Project({
|
|
39
|
-
manipulationSettings: {
|
|
40
|
-
indentationText: IndentationText.TwoSpaces,
|
|
41
|
-
quoteKind: QuoteKind.Double,
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
project.addSourceFileAtPath(nuxtConfigPath);
|
|
46
|
-
const sourceFile = project.getSourceFileOrThrow(nuxtConfigPath);
|
|
47
|
-
|
|
48
|
-
const exportAssignment = sourceFile.getExportAssignment((d) => !d.isExportEquals());
|
|
49
|
-
if (!exportAssignment) return;
|
|
50
|
-
|
|
51
|
-
const defineConfigCall = exportAssignment.getExpression();
|
|
52
|
-
if (
|
|
53
|
-
!Node.isCallExpression(defineConfigCall) ||
|
|
54
|
-
defineConfigCall.getExpression().getText() !== "defineNuxtConfig"
|
|
55
|
-
)
|
|
56
|
-
return;
|
|
57
|
-
|
|
58
|
-
let configObject = defineConfigCall.getArguments()[0];
|
|
59
|
-
if (!configObject) {
|
|
60
|
-
configObject = defineConfigCall.addArgument("{}");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (Node.isObjectLiteralExpression(configObject)) {
|
|
64
|
-
if (!configObject.getProperty("nitro")) {
|
|
65
|
-
configObject.addPropertyAssignment({
|
|
66
|
-
name: "nitro",
|
|
67
|
-
initializer: `{
|
|
68
|
-
preset: "cloudflare_module",
|
|
69
|
-
cloudflare: {
|
|
70
|
-
deployConfig: true,
|
|
71
|
-
nodeCompat: true
|
|
72
|
-
}
|
|
73
|
-
}`,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const modulesProperty = configObject.getProperty("modules");
|
|
78
|
-
if (modulesProperty && Node.isPropertyAssignment(modulesProperty)) {
|
|
79
|
-
const initializer = modulesProperty.getInitializer();
|
|
80
|
-
if (Node.isArrayLiteralExpression(initializer)) {
|
|
81
|
-
const hasModule = initializer
|
|
82
|
-
.getElements()
|
|
83
|
-
.some(
|
|
84
|
-
(el) =>
|
|
85
|
-
el.getText() === '"nitro-cloudflare-dev"' ||
|
|
86
|
-
el.getText() === "'nitro-cloudflare-dev'",
|
|
87
|
-
);
|
|
88
|
-
if (!hasModule) {
|
|
89
|
-
initializer.addElement('"nitro-cloudflare-dev"');
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
} else if (!modulesProperty) {
|
|
93
|
-
configObject.addPropertyAssignment({
|
|
94
|
-
name: "modules",
|
|
95
|
-
initializer: '["nitro-cloudflare-dev"]',
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
await project.save();
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.warn("Failed to update nuxt.config.ts:", error);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import type { PackageManager } from "../../../types";
|
|
4
|
-
import { addPackageDependency } from "../../../utils/add-package-deps";
|
|
5
|
-
|
|
6
|
-
export async function setupReactRouterAlchemyDeploy(
|
|
7
|
-
projectDir: string,
|
|
8
|
-
_packageManager: PackageManager,
|
|
9
|
-
options?: { skipAppScripts?: boolean },
|
|
10
|
-
) {
|
|
11
|
-
const webAppDir = path.join(projectDir, "apps/web");
|
|
12
|
-
if (!(await fs.pathExists(webAppDir))) return;
|
|
13
|
-
|
|
14
|
-
await addPackageDependency({
|
|
15
|
-
devDependencies: ["alchemy"],
|
|
16
|
-
projectDir: webAppDir,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const pkgPath = path.join(webAppDir, "package.json");
|
|
20
|
-
if (await fs.pathExists(pkgPath)) {
|
|
21
|
-
const pkg = await fs.readJson(pkgPath);
|
|
22
|
-
|
|
23
|
-
if (!options?.skipAppScripts) {
|
|
24
|
-
pkg.scripts = {
|
|
25
|
-
...pkg.scripts,
|
|
26
|
-
deploy: "alchemy deploy",
|
|
27
|
-
destroy: "alchemy destroy",
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "fs-extra";
|
|
3
|
-
import type { PackageManager } from "../../../types";
|
|
4
|
-
import { addPackageDependency } from "../../../utils/add-package-deps";
|
|
5
|
-
|
|
6
|
-
export async function setupSolidAlchemyDeploy(
|
|
7
|
-
projectDir: string,
|
|
8
|
-
_packageManager: PackageManager,
|
|
9
|
-
options?: { skipAppScripts?: boolean },
|
|
10
|
-
) {
|
|
11
|
-
const webAppDir = path.join(projectDir, "apps/web");
|
|
12
|
-
if (!(await fs.pathExists(webAppDir))) return;
|
|
13
|
-
|
|
14
|
-
await addPackageDependency({
|
|
15
|
-
devDependencies: ["alchemy"],
|
|
16
|
-
projectDir: webAppDir,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const pkgPath = path.join(webAppDir, "package.json");
|
|
20
|
-
if (await fs.pathExists(pkgPath)) {
|
|
21
|
-
const pkg = await fs.readJson(pkgPath);
|
|
22
|
-
|
|
23
|
-
if (!options?.skipAppScripts) {
|
|
24
|
-
pkg.scripts = {
|
|
25
|
-
...pkg.scripts,
|
|
26
|
-
deploy: "alchemy deploy",
|
|
27
|
-
destroy: "alchemy destroy",
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
31
|
-
}
|
|
32
|
-
}
|