mirror of
https://github.com/saltbo/zpan.git
synced 2026-08-29 00:01:42 +08:00
b5be4c5ebd
- server/entry-lambda.ts: Hono app via hono/aws-lambda handle(); lazy init pattern for CJS compatibility and warm-start reuse; serves SPA static files from dist/ with MIME detection and index.html fallback - deploy/aws-lambda/template.yaml: SAM template with Function URL (no API Gateway), Node 22, TURSO_* / BETTER_AUTH_SECRET / APP_URL env vars, minimal IAM (AWSLambdaBasicExecutionRole) - .github/workflows/deploy-aws-lambda.yml: 8-step contract (guard upstream, check secrets with exact names, resolve tag, checkout, ensure SAM artifact bucket, apply Turso migrations, build + sam deploy, post-deploy auto-gen BETTER_AUTH_SECRET + patch BETTER_AUTH_URL + write URL to summary) - package.json: build:lambda script (tsup CJS, external @libsql/client) - docs/deploy/aws-lambda.md: Prerequisites / Secrets / Trigger / First-boot storage / Cost sections - README.md, V2_ROADMAP.md: link new doc Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
import { existsSync, readFileSync } from 'node:fs'
|
|
import { extname, join } from 'node:path'
|
|
import { Hono } from 'hono'
|
|
import { handle } from 'hono/aws-lambda'
|
|
import { createBootstrap } from './bootstrap'
|
|
import { createLibsqlPlatform } from './platform/libsql'
|
|
|
|
const MIME: Record<string, string> = {
|
|
'.html': 'text/html; charset=utf-8',
|
|
'.js': 'application/javascript',
|
|
'.css': 'text/css',
|
|
'.json': 'application/json',
|
|
'.png': 'image/png',
|
|
'.jpg': 'image/jpeg',
|
|
'.svg': 'image/svg+xml',
|
|
'.ico': 'image/x-icon',
|
|
'.woff': 'font/woff',
|
|
'.woff2': 'font/woff2',
|
|
'.webp': 'image/webp',
|
|
}
|
|
|
|
// Initialized once per Lambda container; reused across warm invocations.
|
|
let cachedHandler: ReturnType<typeof handle> | undefined
|
|
|
|
async function init(): Promise<ReturnType<typeof handle>> {
|
|
if (cachedHandler) return cachedHandler
|
|
|
|
const platform = await createLibsqlPlatform({
|
|
TURSO_DATABASE_URL: process.env.TURSO_DATABASE_URL!,
|
|
TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN,
|
|
})
|
|
const app = await createBootstrap(platform)
|
|
|
|
const server = new Hono()
|
|
server.route('/', app)
|
|
server.get('/*', (c) => {
|
|
const filePath = join('./dist', c.req.path === '/' ? 'index.html' : c.req.path)
|
|
if (existsSync(filePath)) {
|
|
const content = readFileSync(filePath)
|
|
const mime = MIME[extname(filePath)] ?? 'application/octet-stream'
|
|
return c.body(content, 200, { 'Content-Type': mime })
|
|
}
|
|
return c.html(readFileSync('./dist/index.html', 'utf-8'))
|
|
})
|
|
|
|
cachedHandler = handle(server)
|
|
return cachedHandler
|
|
}
|
|
|
|
// biome-ignore lint/suspicious/noExplicitAny: Lambda event/context types vary by invocation model
|
|
export const handler = async (event: any, context: any) => (await init())(event, context)
|