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.21/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.21'// import { fileTypeFromBuffer, fileTypeFromStream } from 'https://esm.sh/file-type@18.2.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) } }, }}