|
| 1 | +import type { Handle, RequestEvent } from '@sveltejs/kit'; |
| 2 | +import type { ClientContract } from '@zenstackhq/orm'; |
| 3 | +import type { SchemaDef } from '@zenstackhq/orm/schema'; |
| 4 | +import { logInternalError, type CommonAdapterOptions } from '../common'; |
| 5 | + |
| 6 | +/** |
| 7 | + * SvelteKit request handler options |
| 8 | + */ |
| 9 | +export interface SvelteKitHandlerOptions<Schema extends SchemaDef> extends CommonAdapterOptions<Schema> { |
| 10 | + /** |
| 11 | + * Url prefix, e.g.: /api |
| 12 | + */ |
| 13 | + prefix: string; |
| 14 | + |
| 15 | + /** |
| 16 | + * Callback for getting a ZenStackClient for the given request |
| 17 | + */ |
| 18 | + getClient: (event: RequestEvent) => ClientContract<Schema> | Promise<ClientContract<Schema>>; |
| 19 | +} |
| 20 | + |
| 21 | +/** |
| 22 | + * SvelteKit server hooks handler for handling CRUD requests. |
| 23 | + */ |
| 24 | +export default function createHandler<Schema extends SchemaDef>(options: SvelteKitHandlerOptions<Schema>): Handle { |
| 25 | + return async ({ event, resolve }) => { |
| 26 | + if (event.url.pathname.startsWith(options.prefix)) { |
| 27 | + const client = await options.getClient(event); |
| 28 | + if (!client) { |
| 29 | + return new Response(JSON.stringify({ message: 'unable to get ZenStackClient from request context' }), { |
| 30 | + status: 400, |
| 31 | + headers: { |
| 32 | + 'content-type': 'application/json', |
| 33 | + }, |
| 34 | + }); |
| 35 | + } |
| 36 | + |
| 37 | + const query = Object.fromEntries(event.url.searchParams); |
| 38 | + let requestBody: unknown; |
| 39 | + if (event.request.body) { |
| 40 | + const text = await event.request.text(); |
| 41 | + if (text) { |
| 42 | + requestBody = JSON.parse(text); |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + const path = event.url.pathname.substring(options.prefix.length); |
| 47 | + |
| 48 | + try { |
| 49 | + const r = await options.apiHandler.handleRequest({ |
| 50 | + method: event.request.method, |
| 51 | + path, |
| 52 | + query, |
| 53 | + requestBody, |
| 54 | + client, |
| 55 | + }); |
| 56 | + |
| 57 | + return new Response(JSON.stringify(r.body), { |
| 58 | + status: r.status, |
| 59 | + headers: { |
| 60 | + 'content-type': 'application/json', |
| 61 | + }, |
| 62 | + }); |
| 63 | + } catch (err) { |
| 64 | + logInternalError(options.apiHandler.log, err); |
| 65 | + return new Response(JSON.stringify({ message: 'An internal server error occurred' }), { |
| 66 | + status: 500, |
| 67 | + headers: { |
| 68 | + 'content-type': 'application/json', |
| 69 | + }, |
| 70 | + }); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + return resolve(event); |
| 75 | + }; |
| 76 | +} |
| 77 | + |
| 78 | +export { createHandler as SvelteKitHandler }; |
0 commit comments