Initial commit
This commit is contained in:
148
templates/cloudflare-worker-backend/src/index.ts
Normal file
148
templates/cloudflare-worker-backend/src/index.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* Cloudflare Worker Backend for TinaCMS
|
||||
*
|
||||
* This Worker provides a self-hosted TinaCMS backend on Cloudflare's edge network.
|
||||
*
|
||||
* Features:
|
||||
* - GraphQL API for content management
|
||||
* - Authentication via Auth.js or custom providers
|
||||
* - Local development mode
|
||||
* - Global edge deployment
|
||||
*
|
||||
* Setup:
|
||||
* 1. Install dependencies: npm install @tinacms/datalayer tinacms-authjs
|
||||
* 2. Generate database client: npx @tinacms/cli@latest init backend
|
||||
* 3. Configure wrangler.jsonc
|
||||
* 4. Deploy: npx wrangler deploy
|
||||
*
|
||||
* Environment Variables:
|
||||
* - TINA_PUBLIC_IS_LOCAL: "true" for local dev, "false" for production
|
||||
* - NEXTAUTH_SECRET: Secret key for Auth.js (production only)
|
||||
*/
|
||||
|
||||
import { TinaNodeBackend, LocalBackendAuthProvider } from '@tinacms/datalayer'
|
||||
import { AuthJsBackendAuthProvider, TinaAuthJSOptions } from 'tinacms-authjs'
|
||||
// @ts-ignore - Generated by TinaCMS CLI
|
||||
import databaseClient from '../../tina/__generated__/databaseClient'
|
||||
|
||||
/**
|
||||
* Cloudflare Workers Environment
|
||||
*
|
||||
* Extend this interface to add your environment variables and bindings
|
||||
*/
|
||||
interface Env {
|
||||
// Environment variables
|
||||
TINA_PUBLIC_IS_LOCAL?: string
|
||||
NEXTAUTH_SECRET?: string
|
||||
|
||||
// Optional: KV namespace for session storage
|
||||
// SESSION_KV?: KVNamespace
|
||||
|
||||
// Optional: D1 database for user management
|
||||
// DB?: D1Database
|
||||
}
|
||||
|
||||
/**
|
||||
* Main Worker Handler
|
||||
*
|
||||
* Processes incoming requests and routes them to the TinaCMS backend
|
||||
*/
|
||||
export default {
|
||||
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
||||
// Determine if we're in local development mode
|
||||
const isLocal = env.TINA_PUBLIC_IS_LOCAL === 'true'
|
||||
|
||||
// Initialize TinaCMS backend
|
||||
const handler = TinaNodeBackend({
|
||||
authProvider: isLocal
|
||||
? LocalBackendAuthProvider()
|
||||
: AuthJsBackendAuthProvider({
|
||||
authOptions: TinaAuthJSOptions({
|
||||
databaseClient,
|
||||
secret: env.NEXTAUTH_SECRET || '',
|
||||
// Add OAuth providers here:
|
||||
// providers: [
|
||||
// DiscordProvider({
|
||||
// clientId: env.DISCORD_CLIENT_ID,
|
||||
// clientSecret: env.DISCORD_CLIENT_SECRET,
|
||||
// }),
|
||||
// ],
|
||||
}),
|
||||
}),
|
||||
databaseClient,
|
||||
})
|
||||
|
||||
try {
|
||||
// Handle CORS preflight requests
|
||||
if (request.method === 'OPTIONS') {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Process the request through TinaCMS
|
||||
const response = await handler(request)
|
||||
|
||||
// Add CORS headers to response
|
||||
const corsResponse = new Response(response.body, response)
|
||||
corsResponse.headers.set('Access-Control-Allow-Origin': '*')
|
||||
corsResponse.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
||||
corsResponse.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||||
|
||||
return corsResponse
|
||||
} catch (error) {
|
||||
console.error('TinaCMS Backend Error:', error)
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
error: 'Internal Server Error',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
}),
|
||||
{
|
||||
status: 500,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative: Hono-based Implementation (Recommended)
|
||||
*
|
||||
* For more flexibility, use Hono framework:
|
||||
*
|
||||
* import { Hono } from 'hono'
|
||||
* import { cors } from 'hono/cors'
|
||||
*
|
||||
* const app = new Hono()
|
||||
*
|
||||
* app.use('/*', cors())
|
||||
*
|
||||
* app.all('/api/tina/*', async (c) => {
|
||||
* const isLocal = c.env.TINA_PUBLIC_IS_LOCAL === 'true'
|
||||
*
|
||||
* const handler = TinaNodeBackend({
|
||||
* authProvider: isLocal
|
||||
* ? LocalBackendAuthProvider()
|
||||
* : AuthJsBackendAuthProvider({
|
||||
* authOptions: TinaAuthJSOptions({
|
||||
* databaseClient,
|
||||
* secret: c.env.NEXTAUTH_SECRET,
|
||||
* }),
|
||||
* }),
|
||||
* databaseClient,
|
||||
* })
|
||||
*
|
||||
* return handler(c.req.raw)
|
||||
* })
|
||||
*
|
||||
* export default app
|
||||
*/
|
||||
55
templates/cloudflare-worker-backend/wrangler.jsonc
Normal file
55
templates/cloudflare-worker-backend/wrangler.jsonc
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/cloudflare/wrangler/main/npm/wrangler/wrangler-schema.json",
|
||||
"name": "tina-backend",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2025-10-24",
|
||||
"compatibility_flags": ["nodejs_compat"],
|
||||
|
||||
// Environment variables for development
|
||||
"vars": {
|
||||
"TINA_PUBLIC_IS_LOCAL": "false"
|
||||
},
|
||||
|
||||
// Environment-specific configurations
|
||||
"env": {
|
||||
"development": {
|
||||
"vars": {
|
||||
"TINA_PUBLIC_IS_LOCAL": "true"
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
"vars": {
|
||||
"TINA_PUBLIC_IS_LOCAL": "false"
|
||||
},
|
||||
// Add secrets via: wrangler secret put NEXTAUTH_SECRET
|
||||
"secrets": [
|
||||
"NEXTAUTH_SECRET"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// Optional: Add KV for session storage
|
||||
// "kv_namespaces": [
|
||||
// {
|
||||
// "binding": "SESSION_KV",
|
||||
// "id": "your-kv-namespace-id"
|
||||
// }
|
||||
// ],
|
||||
|
||||
// Optional: Add D1 for user management
|
||||
// "d1_databases": [
|
||||
// {
|
||||
// "binding": "DB",
|
||||
// "database_name": "tina-users",
|
||||
// "database_id": "your-d1-database-id"
|
||||
// }
|
||||
// ],
|
||||
|
||||
// Routes configuration (adjust based on your setup)
|
||||
"routes": [
|
||||
{
|
||||
"pattern": "yourdomain.com/api/tina/*",
|
||||
"zone_name": "yourdomain.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user