add cloudflare workers support for all frontends (#366)

This commit is contained in:
Aman Varshney
2025-07-05 15:51:26 +05:30
committed by GitHub
parent 6499f8cf04
commit d2674270a4
53 changed files with 1213 additions and 159 deletions

View File

@@ -140013,6 +140013,6 @@
}
],
"lastUpdated": "Jul 1, 2025, 03:45 AM",
"generatedAt": "2025-07-01T04:23:00.971Z",
"generatedAt": "2025-07-05T10:12:56.694Z",
"totalRecords": 5637
}

View File

@@ -144,6 +144,14 @@
"none"
],
"description": "API type"
},
"webDeploy": {
"type": "string",
"enum": [
"workers",
"none"
],
"description": "Web deployment"
}
},
"required": [
@@ -159,7 +167,8 @@
"auth",
"packageManager",
"dbSetup",
"api"
"api",
"webDeploy"
],
"additionalProperties": false
}

View File

@@ -11,6 +11,7 @@ import {
ORMSchema,
PackageManagerSchema,
RuntimeSchema,
WebDeploySchema,
} from "../../cli/src/types";
const DATABASE_VALUES = DatabaseSchema.options;
@@ -23,91 +24,97 @@ const EXAMPLES_VALUES = ExamplesSchema.options;
const PACKAGE_MANAGER_VALUES = PackageManagerSchema.options;
const DATABASE_SETUP_VALUES = DatabaseSetupSchema.options;
const API_VALUES = APISchema.options;
const WEB_DEPLOY_VALUES = WebDeploySchema.options;
const schema = {
const configSchema = {
$schema: "http://json-schema.org/draft-07/schema#",
$id: "https://better-t-stack.dev/schema.json",
title: "Better-T-Stack Configuration",
description: "Configuration file for Better-T-Stack projects",
type: "object" as const,
type: "object",
properties: {
$schema: {
type: "string" as const,
type: "string",
description: "JSON Schema reference for validation",
},
version: {
type: "string" as const,
type: "string",
description: "CLI version used to create this project",
pattern: "^\\d+\\.\\d+\\.\\d+$",
},
createdAt: {
type: "string" as const,
format: "date-time" as const,
type: "string",
format: "date-time",
description: "Timestamp when the project was created",
},
database: {
type: "string" as const,
type: "string",
enum: DATABASE_VALUES,
description: DatabaseSchema.description,
},
orm: {
type: "string" as const,
type: "string",
enum: ORM_VALUES,
description: ORMSchema.description,
},
backend: {
type: "string" as const,
type: "string",
enum: BACKEND_VALUES,
description: BackendSchema.description,
},
runtime: {
type: "string" as const,
type: "string",
enum: RUNTIME_VALUES,
description: RuntimeSchema.description,
},
frontend: {
type: "array" as const,
type: "array",
items: {
type: "string" as const,
type: "string",
enum: FRONTEND_VALUES,
},
description: FrontendSchema.description,
},
addons: {
type: "array" as const,
type: "array",
items: {
type: "string" as const,
type: "string",
enum: ADDONS_VALUES,
},
description: AddonsSchema.description,
},
examples: {
type: "array" as const,
type: "array",
items: {
type: "string" as const,
type: "string",
enum: EXAMPLES_VALUES,
},
description: ExamplesSchema.description,
},
auth: {
type: "boolean" as const,
type: "boolean",
description: "Whether authentication is enabled",
},
packageManager: {
type: "string" as const,
type: "string",
enum: PACKAGE_MANAGER_VALUES,
description: PackageManagerSchema.description,
},
dbSetup: {
type: "string" as const,
type: "string",
enum: DATABASE_SETUP_VALUES,
description: DatabaseSetupSchema.description,
},
api: {
type: "string" as const,
type: "string",
enum: API_VALUES,
description: APISchema.description,
},
webDeploy: {
type: "string",
enum: WEB_DEPLOY_VALUES,
description: WebDeploySchema.description,
},
},
required: [
"version",
@@ -123,6 +130,7 @@ const schema = {
"packageManager",
"dbSetup",
"api",
"webDeploy",
],
additionalProperties: false,
};
@@ -130,7 +138,11 @@ const schema = {
async function generateSchema() {
const schemaPath = path.join(process.cwd(), "public", "schema.json");
await fs.ensureDir(path.dirname(schemaPath));
await fs.writeFile(schemaPath, JSON.stringify(schema, null, 2), "utf-8");
await fs.writeFile(
schemaPath,
JSON.stringify(configSchema, null, 2),
"utf-8",
);
console.log("✅ Generated schema.json from shared types package");
}

View File

@@ -73,6 +73,7 @@ const CATEGORY_ORDER: Array<keyof typeof TECH_OPTIONS> = [
"database",
"orm",
"dbSetup",
"webDeploy",
"auth",
"packageManager",
"addons",
@@ -124,6 +125,7 @@ const getBadgeColors = (category: string): string => {
case "packageManager":
return "border-orange-300 bg-orange-100 text-orange-800 dark:border-orange-700/30 dark:bg-orange-900/30 dark:text-orange-300";
case "git":
case "webDeploy":
case "install":
return "border-gray-300 bg-gray-100 text-gray-700 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400";
default:
@@ -800,6 +802,28 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => {
if (nextStack.examples.length !== originalExamplesLength)
changed = true;
}
// Web deploy compatibility: Workers not supported with TanStack Start
if (
nextStack.webDeploy === "workers" &&
nextStack.webFrontend.includes("tanstack-start")
) {
notes.webDeploy.notes.push(
"Cloudflare Workers deployment is not supported with TanStack Start. It will be set to 'None'.",
);
notes.webFrontend.notes.push(
"TanStack Start is not compatible with Cloudflare Workers deployment.",
);
notes.webDeploy.hasIssue = true;
notes.webFrontend.hasIssue = true;
nextStack.webDeploy = "none";
changed = true;
changes.push({
category: "webDeploy",
message:
"Web deployment set to 'None' (Workers not compatible with TanStack Start)",
});
}
}
}
@@ -899,6 +923,13 @@ const generateCommand = (stackState: StackState): string => {
}
}
if (
stackState.webDeploy &&
!checkDefault("webDeploy", stackState.webDeploy)
) {
flags.push(`--web-deploy ${stackState.webDeploy}`);
}
if (!checkDefault("install", stackState.install)) {
if (stackState.install === "false" && DEFAULT_STACK.install === "true") {
flags.push("--no-install");

View File

@@ -134,7 +134,7 @@ export const TECH_OPTIONS = {
},
{
id: "workers",
name: "Cloudflare Workers (beta)",
name: "Cloudflare Workers",
description: "Serverless runtime for the edge",
icon: "/icon/workers.svg",
color: "from-orange-400 to-orange-600",
@@ -320,6 +320,23 @@ export const TECH_OPTIONS = {
default: true,
},
],
webDeploy: [
{
id: "workers",
name: "Cloudflare Workers",
description: "Deploy to Cloudflare Workers",
icon: "/icon/workers.svg",
color: "from-orange-400 to-orange-600",
},
{
id: "none",
name: "No Deployment",
description: "Skip deployment configuration",
icon: "",
color: "from-gray-400 to-gray-600",
default: true,
},
],
auth: [
{
id: "true",
@@ -594,6 +611,7 @@ export type StackState = {
git: string;
install: string;
api: string;
webDeploy: string;
};
export const DEFAULT_STACK: StackState = {
@@ -612,6 +630,7 @@ export const DEFAULT_STACK: StackState = {
git: "true",
install: "true",
api: "trpc",
webDeploy: "none",
};
export const isStackDefault = <K extends keyof StackState>(

View File

@@ -51,6 +51,9 @@ export const stackParsers = {
"true",
"false",
]).withDefault(DEFAULT_STACK.install),
webDeploy: parseAsStringEnum<StackState["webDeploy"]>(
getValidIds("webDeploy"),
).withDefault(DEFAULT_STACK.webDeploy),
};
export const stackUrlKeys: UrlKeys<typeof stackParsers> = {
@@ -69,6 +72,7 @@ export const stackUrlKeys: UrlKeys<typeof stackParsers> = {
examples: "ex",
git: "git",
install: "i",
webDeploy: "wd",
};
export const stackQueryStatesOptions = {