Skip to content

Commit fe5f61d

Browse files
authored
feat(server): migrate sveltekit adapter (#343)
1 parent da048dd commit fe5f61d

File tree

14 files changed

+448
-14
lines changed

14 files changed

+448
-14
lines changed

packages/server/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@
9898
"types": "./dist/nuxt.d.cts",
9999
"default": "./dist/nuxt.cjs"
100100
}
101+
},
102+
"./sveltekit": {
103+
"import": {
104+
"types": "./dist/sveltekit.d.ts",
105+
"default": "./dist/sveltekit.js"
106+
},
107+
"require": {
108+
"types": "./dist/sveltekit.d.cts",
109+
"default": "./dist/sveltekit.cjs"
110+
}
101111
}
102112
},
103113
"dependencies": {
@@ -111,6 +121,7 @@
111121
"zod-validation-error": "catalog:"
112122
},
113123
"devDependencies": {
124+
"@sveltejs/kit": "^2.48.3",
114125
"@types/body-parser": "^1.19.6",
115126
"@types/express": "^5.0.0",
116127
"@types/supertest": "^6.0.3",
@@ -131,6 +142,7 @@
131142
"zod": "~3.25.0"
132143
},
133144
"peerDependencies": {
145+
"@sveltejs/kit": "^2.0.0",
134146
"elysia": "^1.3.0",
135147
"express": "^5.0.0",
136148
"fastify": "^5.0.0",
@@ -161,6 +173,9 @@
161173
},
162174
"nuxt": {
163175
"optional": true
176+
},
177+
"@sveltejs/kit": {
178+
"optional": true
164179
}
165180
}
166181
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './handler';
1+
export { createElysiaHandler, type ElysiaOptions } from './handler';
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { ZenStackMiddleware, type MiddlewareOptions } from './middleware';
1+
export { ZenStackMiddleware, type ExpressMiddlewareOptions } from './middleware';

packages/server/src/adapter/express/middleware.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { logInternalError, type CommonAdapterOptions } from '../common';
66
/**
77
* Express middleware options
88
*/
9-
export interface MiddlewareOptions<Schema extends SchemaDef> extends CommonAdapterOptions<Schema> {
9+
export interface ExpressMiddlewareOptions<Schema extends SchemaDef> extends CommonAdapterOptions<Schema> {
1010
/**
1111
* Callback for getting a ZenStackClient for the given request
1212
*/
@@ -27,7 +27,7 @@ export interface MiddlewareOptions<Schema extends SchemaDef> extends CommonAdapt
2727
/**
2828
* Creates an Express middleware for handling CRUD requests.
2929
*/
30-
const factory = <Schema extends SchemaDef>(options: MiddlewareOptions<Schema>): Handler => {
30+
const factory = <Schema extends SchemaDef>(options: ExpressMiddlewareOptions<Schema>): Handler => {
3131
const requestHandler = options.apiHandler;
3232

3333
return async (request, response, next) => {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export { ZenStackFastifyPlugin, type PluginOptions } from './plugin';
1+
export { ZenStackFastifyPlugin, type FastifyPluginOptions } from './plugin';
22

packages/server/src/adapter/fastify/plugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { logInternalError, type CommonAdapterOptions } from '../common';
77
/**
88
* Fastify plugin options
99
*/
10-
export interface PluginOptions<Schema extends SchemaDef> extends CommonAdapterOptions<Schema> {
10+
export interface FastifyPluginOptions<Schema extends SchemaDef> extends CommonAdapterOptions<Schema> {
1111

1212
/**
1313
* Url prefix, e.g.: /api
@@ -23,7 +23,7 @@ export interface PluginOptions<Schema extends SchemaDef> extends CommonAdapterOp
2323
/**
2424
* Fastify plugin for handling CRUD requests.
2525
*/
26-
const pluginHandler: FastifyPluginCallback<PluginOptions<SchemaDef>> = (fastify, options, done) => {
26+
const pluginHandler: FastifyPluginCallback<FastifyPluginOptions<SchemaDef>> = (fastify, options, done) => {
2727
const prefix = options.prefix ?? '';
2828

2929
fastify.all(`${prefix}/*`, async (request, reply) => {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './handler';
1+
export { createHonoHandler, type HonoOptions } from './handler';

packages/server/src/adapter/nuxt/handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ import { logInternalError, type CommonAdapterOptions } from '../common';
1414
/**
1515
* Nuxt request handler options
1616
*/
17-
export interface HandlerOptions<Schema extends SchemaDef> extends CommonAdapterOptions<Schema> {
17+
export interface NuxtHandlerOptions<Schema extends SchemaDef> extends CommonAdapterOptions<Schema> {
1818
/**
1919
* Callback for getting a ZenStackClient for the given request
2020
*/
2121
getClient: (event: H3Event<EventHandlerRequest>) => ClientContract<Schema> | Promise<ClientContract<Schema>>;
2222
}
2323

24-
export function createEventHandler<Schema extends SchemaDef>(options: HandlerOptions<Schema>) {
24+
export function createEventHandler<Schema extends SchemaDef>(options: NuxtHandlerOptions<Schema>) {
2525
return defineEventHandler(async (event) => {
2626
const client = await options.getClient(event);
2727
if (!client) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './handler';
1+
export { createEventHandler, type NuxtHandlerOptions } from './handler';
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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

Comments
 (0)