d3ro-voice/server/cloudflare-worker/src/index.ts
Yun Chan 708e20f747
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped
feat: complete release preparation, 10+ ad mediation, CI/CD, and docker deployment
2026-08-20 11:12:05 +09:00

96 lines
3 KiB
TypeScript

// server/cloudflare-worker/src/index.ts
// D3RO Voice — Global Cloudflare Edge Gateway & Proxy Worker
export interface Env {
BACKEND_ORIGIN: string
SERVICE_NAME?: string
}
const CORS_HEADERS: Record<string, string> = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, Range',
'Access-Control-Expose-Headers': 'Content-Length, Content-Range, X-D3RO-Status',
'Access-Control-Max-Age': '86400',
}
export default {
async fetch(request: Request, env: Env, _ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url)
// 1. Handle CORS Preflight (OPTIONS)
if (request.method === 'OPTIONS') {
return new Response(null, {
status: 204,
headers: CORS_HEADERS,
})
}
// 2. Edge Health Check Ping (/worker-health)
if (url.pathname === '/worker-health') {
return new Response(
JSON.stringify({
status: 'Healthy',
worker: env.SERVICE_NAME ?? 'D3RO Voice Edge Worker',
backendOrigin: env.BACKEND_ORIGIN,
timestamp: new Date().toISOString(),
region: request.cf?.colo ?? 'global',
}),
{
headers: {
'Content-Type': 'application/json',
...CORS_HEADERS,
},
}
)
}
// 3. Construct Target Backend URL
const backendOrigin = (env.BACKEND_ORIGIN || 'https://d3ro.chanpaca.net').replace(/\/$/, '')
const targetUrl = new URL(`${url.pathname}${url.search}`, backendOrigin)
// Forward Headers
const forwardHeaders = new Headers(request.headers)
forwardHeaders.set('X-Forwarded-Host', url.host)
forwardHeaders.set('X-Forwarded-Proto', url.protocol.replace(':', ''))
forwardHeaders.set('X-D3RO-Edge-Proxy', 'Cloudflare-Worker')
try {
const response = await fetch(targetUrl.toString(), {
method: request.method,
headers: forwardHeaders,
body: request.method !== 'GET' && request.method !== 'HEAD' ? request.body : undefined,
redirect: 'follow',
})
// Clone response headers and attach CORS
const newHeaders = new Headers(response.headers)
for (const [key, value] of Object.entries(CORS_HEADERS)) {
newHeaders.set(key, value)
}
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders,
})
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : String(err)
return new Response(
JSON.stringify({
error: 'EdgeGatewayError',
message: `Unable to connect to origin NAS backend: ${errorMessage}`,
targetUrl: targetUrl.toString(),
timestamp: new Date().toISOString(),
}),
{
status: 502,
headers: {
'Content-Type': 'application/json',
...CORS_HEADERS,
},
}
)
}
},
}