Skip to main content
Module

x/darkflare/route.ts

The API Engine
Go to Latest
File
import { Value } from 'https://esm.sh/@sinclair/typebox@0.25.20/value'import { ErrorMessage } from './ErrorMessage.d.ts'import type { DarkflareContext } from './DarkflareContext.d.ts'import type { TSchema } from 'https://esm.sh/@sinclair/typebox@0.25.20'import { fileTypeFromBuffer, fileTypeFromStream } from 'https://esm.sh/file-type@18.1.0'
export const route = <B = unknown, Q = unknown, H = unknown, C = unknown, P = unknown>( schema: { body?: B query?: Q headers?: H cookies?: C parameters?: P }, handler: ( ctx: DarkflareContext<B, Q, H, C, P> ) => unknown | Promise<unknown>) => { return { schema,
async handle(__darkflare: { onError: (err: ErrorMessage, request: Request) => Response, cors?: string, cache?: number }, request: Request, parameters: Record<string, string>, query: Record<string, unknown>, cf: Record<string, string>, waitUntil: (promise: Promise<unknown>) => void, env: darkflare.Environment) { // request const headers: { [key: string]: string } = {} let body = {} , cookies = {}
// response const h = new Headers() let p , c: number | undefined
if (schema.parameters && !Value.Check((schema.parameters as unknown) as TSchema, parameters)) return __darkflare.onError('MALFORMED PARAMETERS', request)
if (schema.query && !Value.Check((schema.query as unknown) as TSchema, query)) return __darkflare.onError('MALFORMED QUERY', request)
for (const [key, value] of request.headers) headers[key.toLowerCase()] = value
if (schema.headers && !Value.Check((schema.headers as unknown) as TSchema, headers)) return __darkflare.onError('MALFORMED HEADERS', request)
try { const type = headers['content-type'] if (type?.includes('application/json')) body = await request.json() else if (type?.includes('text/plain')) body = await request.text() } catch (_err) { body = {} } if (schema.body && !Value.Check((schema.body as unknown) as TSchema, body)) return __darkflare.onError('MALFORMED BODY', request)
try { cookies = (headers.cookies || '') .split(/;\s*/) .map(pair => pair.split(/=(.+)/)) .reduce((acc: Record<string, string>, [key, value]) => { acc[key] = value return acc }, {}) } catch (_err) { cookies = {} }
if (schema.cookies && !Value.Check((schema.cookies as unknown) as TSchema, cookies)) return __darkflare.onError('MALFORMED COOKIES', request)
// set default headers if (__darkflare.cors) h.set('access-control-allow-origin', __darkflare.cors)
if (request.method === 'GET') h.set('cache-control', `max-age=${__darkflare.cache ?? 0}`)
// construct context object const ctx: DarkflareContext = { env,
req: { raw: request, body, query, headers, cookies, parameters, geo: { ip: headers['cf-connecting-ip'], city: cf.city, region: cf.region, country: cf.country, continent: cf.continent, regionCode: cf.regionCode, latitude: cf.latitude, longitude: cf.longitude, postalCode: cf.postalCode, timezone: cf.timezone, datacenter: cf.colo }, buffer: request.arrayBuffer, blob: request.blob, formData: request.formData, stream: request.body },
res: { code: code => { c = code }, cookie: (name, value, options) => { let cookie = `${name}=${value};` h.set('set-cookie', ( options?.expiresAt && (cookie += ` expires=${options.expiresAt.toUTCString()};`), options?.maxAge && (cookie += ` max-age=${options.maxAge};`), options?.domain && (cookie += ` domain=${options.domain};`), options?.path && (cookie += ` path=${options.path};`), options?.secure && (cookie += ' secure;'), options?.httpOnly && (cookie += ' httpOnly;'), options?.sameSite && (cookie += ` sameSite=${options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1)};`), cookie )) }, header(name, value) { h.set(name, value) }, html(payload, code) { h.set('content-type', 'text/html; charset=utf-8;') p = payload c = code }, json(payload, code) { h.set('content-type', 'application/json; charset=utf-8;') p = payload c = code }, text(payload, code) { h.set('content-type', 'text/plain; charset=utf-8;') p = payload c = code }, redirect(destination, code) { h.set('location', destination)
c = code ?? 307 }, blob(payload, code) { p = payload c = code }, stream(payload, code) { p = payload c = code }, buffer(payload, code) { p = payload c = code }, formData(payload, code) { p = payload c = code } },
waitUntil }
try { const result = await handler(ctx as DarkflareContext<B, Q, H, C, P>)
if (!c) c = 200
if (c !== 200) h.delete('cache-control')
// redirect if (h.has('location')) return new Response(null, { headers: h, status: c }) if (!p) p = result
if (!p) return new Response(null, { headers: h, status: c })
if (typeof p === 'string') { // string h.set('content-length', p.length.toString())
if (!h.has('content-type')) h.set('content-type', 'text/plain; charset=utf-8;') } else if (p instanceof Uint8Array || p instanceof ArrayBuffer) { // buffer h.set('content-length', p.byteLength.toString())
if (!h.has('content-type')) { const type = await fileTypeFromBuffer(p)
if (type) h.set('content-type', type.mime) } } else if (p instanceof Blob) { // blob h.set('content-length', p.size.toString())
if (!h.has('content-type')) { const type = await fileTypeFromBuffer(await p.arrayBuffer())
if (type) h.set('content-type', type.mime) } } else if (p instanceof ReadableStream) { // stream if (!h.has('content-type')) { // @ts-ignore: ReadableStream is valid here const type = await fileTypeFromStream(p)
if (type) h.set('content-type', type.mime) } } else { // object p = JSON.stringify(p)
h.set('content-length', p.length.toString())
if (!h.has('content-type')) h.set('content-type', 'application/json; charset=utf-8;')
if (((p as unknown) as { code: number }).code) c = ((p as unknown) as { code: number }).code }
return new Response(p, { headers: h, status: c }) } catch (_err) { return __darkflare.onError('SOMETHING WENT WRONG', request) } } }}