|  | 
|  | 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