@objectstack/sveltekit 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +6 -0
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +8 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
|
|
2
|
-
> @objectstack/sveltekit@4.0.
|
|
2
|
+
> @objectstack/sveltekit@4.0.2 build /home/runner/work/framework/framework/packages/adapters/sveltekit
|
|
3
3
|
> tsup --config ../../../tsup.config.ts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.5.1
|
|
8
|
-
[34mCLI[39m Using tsup config: /home/runner/work/
|
|
8
|
+
[34mCLI[39m Using tsup config: /home/runner/work/framework/framework/tsup.config.ts
|
|
9
9
|
[34mCLI[39m Target: es2020
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m4.
|
|
14
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[32m10.
|
|
15
|
-
[32mESM[39m ⚡️ Build success in
|
|
16
|
-
[32mCJS[39m [1mdist/index.js [22m[32m5.
|
|
17
|
-
[32mCJS[39m [1mdist/index.js.map [22m[32m10.
|
|
18
|
-
[32mCJS[39m ⚡️ Build success in
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m4.78 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m10.84 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 48ms
|
|
16
|
+
[32mCJS[39m [1mdist/index.js [22m[32m5.83 KB[39m
|
|
17
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m10.88 KB[39m
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 54ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 12918ms
|
|
21
21
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m1.65 KB[39m
|
|
22
22
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.65 KB[39m
|
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -80,6 +80,12 @@ function createRequestHandler(options) {
|
|
|
80
80
|
headers: { "Content-Type": "application/json" }
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
|
+
if (segments.length === 1 && segments[0] === "discovery" && method === "GET") {
|
|
84
|
+
return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {
|
|
85
|
+
status: 200,
|
|
86
|
+
headers: { "Content-Type": "application/json" }
|
|
87
|
+
});
|
|
88
|
+
}
|
|
83
89
|
try {
|
|
84
90
|
if (segments[0] === "auth") {
|
|
85
91
|
const subPath2 = segments.slice(1).join("/");
|
|
@@ -132,7 +138,7 @@ function createRequestHandler(options) {
|
|
|
132
138
|
url.searchParams.forEach((val, key) => {
|
|
133
139
|
queryParams[key] = val;
|
|
134
140
|
});
|
|
135
|
-
const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request });
|
|
141
|
+
const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request }, prefix);
|
|
136
142
|
return toResponse(result);
|
|
137
143
|
} catch (err) {
|
|
138
144
|
return errorJson(err.message || "Internal Server Error", err.statusCode || 500);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { type ObjectKernel, HttpDispatcher, HttpDispatcherResult } from '@objectstack/runtime';\n\nexport interface SvelteKitAdapterOptions {\n kernel: ObjectKernel;\n prefix?: string;\n}\n\n/**\n * Auth service interface with handleRequest method\n */\ninterface AuthService {\n handleRequest(request: Request): Promise<Response>;\n}\n\n/**\n * SvelteKit request event type (minimal interface to avoid hard dependency on @sveltejs/kit types at runtime)\n */\ninterface RequestEvent {\n request: Request;\n url: URL;\n params: Record<string, string>;\n}\n\n/**\n * Creates a SvelteKit request handler for ObjectStack API routes.\n * Use in a catch-all `+server.ts` route like `src/routes/api/[...path]/+server.ts`.\n *\n * Only auth, GraphQL, storage, and discovery need explicit handling.\n * All other routes delegate to `HttpDispatcher.dispatch()` automatically.\n *\n * @example\n * ```ts\n * // src/routes/api/[...path]/+server.ts\n * import { createRequestHandler } from '@objectstack/sveltekit';\n * import { kernel } from '$lib/kernel';\n *\n * const handler = createRequestHandler({ kernel });\n *\n * export const GET = handler;\n * export const POST = handler;\n * export const PUT = handler;\n * export const PATCH = handler;\n * export const DELETE = handler;\n * ```\n */\nexport function createRequestHandler(options: SvelteKitAdapterOptions) {\n const dispatcher = new HttpDispatcher(options.kernel);\n const prefix = options.prefix || '/api';\n\n const errorJson = (message: string, code: number = 500) => {\n return new Response(JSON.stringify({ success: false, error: { message, code } }), {\n status: code,\n headers: { 'Content-Type': 'application/json' },\n });\n };\n\n const toResponse = (result: HttpDispatcherResult): Response => {\n if (result.handled) {\n if (result.response) {\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (result.response.headers) {\n Object.entries(result.response.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(JSON.stringify(result.response.body), {\n status: result.response.status,\n headers,\n });\n }\n if (result.result) {\n const res = result.result;\n if (res.type === 'redirect' && res.url) {\n return new Response(null, {\n status: 302,\n headers: { Location: res.url },\n });\n }\n if (res.type === 'stream' && res.stream) {\n const headers = new Headers();\n if (res.headers) {\n Object.entries(res.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(res.stream, { status: 200, headers });\n }\n return new Response(JSON.stringify(res), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n return errorJson('Not Found', 404);\n };\n\n return async function handler(event: RequestEvent): Promise<Response> {\n const { request, url } = event;\n const method = request.method;\n const path = url.pathname.substring(prefix.length);\n const segments = path.split('/').filter(Boolean);\n\n // --- Discovery ---\n if (segments.length === 0 && method === 'GET') {\n return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n try {\n // --- Auth (needs auth service integration) ---\n if (segments[0] === 'auth') {\n const subPath = segments.slice(1).join('/');\n\n // Try AuthPlugin service first (prefer async to support factory-based services)\n let authService: AuthService | null = null;\n try {\n if (typeof options.kernel.getServiceAsync === 'function') {\n authService = await options.kernel.getServiceAsync<AuthService>('auth');\n } else if (typeof options.kernel.getService === 'function') {\n authService = options.kernel.getService<AuthService>('auth');\n }\n } catch {\n // Service not registered — fall through to dispatcher\n authService = null;\n }\n\n if (authService && typeof authService.handleRequest === 'function') {\n return await authService.handleRequest(request);\n }\n\n // Fallback to dispatcher\n const body = method === 'GET' || method === 'HEAD'\n ? {}\n : await request.json().catch(() => ({}));\n const result = await dispatcher.handleAuth(subPath, method, body, { request });\n return toResponse(result);\n }\n\n // --- GraphQL (returns raw result, not HttpDispatcherResult) ---\n if (segments[0] === 'graphql' && method === 'POST') {\n const body = await request.json() as { query: string; variables?: any };\n const result = await dispatcher.handleGraphQL(body, { request });\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // --- Storage (needs formData parsing) ---\n if (segments[0] === 'storage') {\n const subPath = segments.slice(1).join('/');\n let file: any = undefined;\n if (method === 'POST' && subPath === 'upload') {\n const formData = await request.formData();\n file = formData.get('file');\n }\n const result = await dispatcher.handleStorage(\n subPath ? `/${subPath}` : '',\n method,\n file,\n { request },\n );\n return toResponse(result);\n }\n\n // --- Catch-all: delegate to dispatcher.dispatch() ---\n // Handles meta, data, packages, analytics, automation, i18n, ui,\n // openapi, custom API endpoints, and any future routes.\n const subPath = path || '';\n\n let body: any = undefined;\n if (method === 'POST' || method === 'PUT' || method === 'PATCH') {\n body = await request.json().catch(() => ({}));\n }\n\n const queryParams: Record<string, any> = {};\n url.searchParams.forEach((val, key) => { queryParams[key] = val; });\n\n const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request });\n return toResponse(result);\n } catch (err: any) {\n return errorJson(err.message || 'Internal Server Error', err.statusCode || 500);\n }\n };\n}\n\n/**\n * Creates a SvelteKit handle hook that attaches the kernel to event.locals.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { createHandle } from '@objectstack/sveltekit';\n * export const handle = createHandle({ kernel });\n * ```\n */\nexport function createHandle(options: SvelteKitAdapterOptions) {\n return async function handle({ event, resolve }: { event: any; resolve: (event: any) => Promise<Response> }) {\n event.locals.objectStack = options.kernel;\n return resolve(event);\n };\n}\n"],"mappings":"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","names":["subPath","body","result"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { type ObjectKernel, HttpDispatcher, HttpDispatcherResult } from '@objectstack/runtime';\n\nexport interface SvelteKitAdapterOptions {\n kernel: ObjectKernel;\n prefix?: string;\n}\n\n/**\n * Auth service interface with handleRequest method\n */\ninterface AuthService {\n handleRequest(request: Request): Promise<Response>;\n}\n\n/**\n * SvelteKit request event type (minimal interface to avoid hard dependency on @sveltejs/kit types at runtime)\n */\ninterface RequestEvent {\n request: Request;\n url: URL;\n params: Record<string, string>;\n}\n\n/**\n * Creates a SvelteKit request handler for ObjectStack API routes.\n * Use in a catch-all `+server.ts` route like `src/routes/api/[...path]/+server.ts`.\n *\n * Only auth, GraphQL, storage, and discovery need explicit handling.\n * All other routes delegate to `HttpDispatcher.dispatch()` automatically.\n *\n * @example\n * ```ts\n * // src/routes/api/[...path]/+server.ts\n * import { createRequestHandler } from '@objectstack/sveltekit';\n * import { kernel } from '$lib/kernel';\n *\n * const handler = createRequestHandler({ kernel });\n *\n * export const GET = handler;\n * export const POST = handler;\n * export const PUT = handler;\n * export const PATCH = handler;\n * export const DELETE = handler;\n * ```\n */\nexport function createRequestHandler(options: SvelteKitAdapterOptions) {\n const dispatcher = new HttpDispatcher(options.kernel);\n const prefix = options.prefix || '/api';\n\n const errorJson = (message: string, code: number = 500) => {\n return new Response(JSON.stringify({ success: false, error: { message, code } }), {\n status: code,\n headers: { 'Content-Type': 'application/json' },\n });\n };\n\n const toResponse = (result: HttpDispatcherResult): Response => {\n if (result.handled) {\n if (result.response) {\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (result.response.headers) {\n Object.entries(result.response.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(JSON.stringify(result.response.body), {\n status: result.response.status,\n headers,\n });\n }\n if (result.result) {\n const res = result.result;\n if (res.type === 'redirect' && res.url) {\n return new Response(null, {\n status: 302,\n headers: { Location: res.url },\n });\n }\n if (res.type === 'stream' && res.stream) {\n const headers = new Headers();\n if (res.headers) {\n Object.entries(res.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(res.stream, { status: 200, headers });\n }\n return new Response(JSON.stringify(res), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n return errorJson('Not Found', 404);\n };\n\n return async function handler(event: RequestEvent): Promise<Response> {\n const { request, url } = event;\n const method = request.method;\n const path = url.pathname.substring(prefix.length);\n const segments = path.split('/').filter(Boolean);\n\n // --- Discovery ---\n if (segments.length === 0 && method === 'GET') {\n return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n if (segments.length === 1 && segments[0] === 'discovery' && method === 'GET') {\n return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n try {\n // --- Auth (needs auth service integration) ---\n if (segments[0] === 'auth') {\n const subPath = segments.slice(1).join('/');\n\n // Try AuthPlugin service first (prefer async to support factory-based services)\n let authService: AuthService | null = null;\n try {\n if (typeof options.kernel.getServiceAsync === 'function') {\n authService = await options.kernel.getServiceAsync<AuthService>('auth');\n } else if (typeof options.kernel.getService === 'function') {\n authService = options.kernel.getService<AuthService>('auth');\n }\n } catch {\n // Service not registered — fall through to dispatcher\n authService = null;\n }\n\n if (authService && typeof authService.handleRequest === 'function') {\n return await authService.handleRequest(request);\n }\n\n // Fallback to dispatcher\n const body = method === 'GET' || method === 'HEAD'\n ? {}\n : await request.json().catch(() => ({}));\n const result = await dispatcher.handleAuth(subPath, method, body, { request });\n return toResponse(result);\n }\n\n // --- GraphQL (returns raw result, not HttpDispatcherResult) ---\n if (segments[0] === 'graphql' && method === 'POST') {\n const body = await request.json() as { query: string; variables?: any };\n const result = await dispatcher.handleGraphQL(body, { request });\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // --- Storage (needs formData parsing) ---\n if (segments[0] === 'storage') {\n const subPath = segments.slice(1).join('/');\n let file: any = undefined;\n if (method === 'POST' && subPath === 'upload') {\n const formData = await request.formData();\n file = formData.get('file');\n }\n const result = await dispatcher.handleStorage(\n subPath ? `/${subPath}` : '',\n method,\n file,\n { request },\n );\n return toResponse(result);\n }\n\n // --- Catch-all: delegate to dispatcher.dispatch() ---\n // Handles meta, data, packages, analytics, automation, i18n, ui,\n // openapi, custom API endpoints, and any future routes.\n const subPath = path || '';\n\n let body: any = undefined;\n if (method === 'POST' || method === 'PUT' || method === 'PATCH') {\n body = await request.json().catch(() => ({}));\n }\n\n const queryParams: Record<string, any> = {};\n url.searchParams.forEach((val, key) => { queryParams[key] = val; });\n\n const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request }, prefix);\n return toResponse(result);\n } catch (err: any) {\n return errorJson(err.message || 'Internal Server Error', err.statusCode || 500);\n }\n };\n}\n\n/**\n * Creates a SvelteKit handle hook that attaches the kernel to event.locals.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { createHandle } from '@objectstack/sveltekit';\n * export const handle = createHandle({ kernel });\n * ```\n */\nexport function createHandle(options: SvelteKitAdapterOptions) {\n return async function handle({ event, resolve }: { event: any; resolve: (event: any) => Promise<Response> }) {\n event.locals.objectStack = options.kernel;\n return resolve(event);\n };\n}\n"],"mappings":"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","names":["subPath","body","result"]}
|
package/dist/index.mjs
CHANGED
|
@@ -55,6 +55,12 @@ function createRequestHandler(options) {
|
|
|
55
55
|
headers: { "Content-Type": "application/json" }
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
+
if (segments.length === 1 && segments[0] === "discovery" && method === "GET") {
|
|
59
|
+
return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {
|
|
60
|
+
status: 200,
|
|
61
|
+
headers: { "Content-Type": "application/json" }
|
|
62
|
+
});
|
|
63
|
+
}
|
|
58
64
|
try {
|
|
59
65
|
if (segments[0] === "auth") {
|
|
60
66
|
const subPath2 = segments.slice(1).join("/");
|
|
@@ -107,7 +113,7 @@ function createRequestHandler(options) {
|
|
|
107
113
|
url.searchParams.forEach((val, key) => {
|
|
108
114
|
queryParams[key] = val;
|
|
109
115
|
});
|
|
110
|
-
const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request });
|
|
116
|
+
const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request }, prefix);
|
|
111
117
|
return toResponse(result);
|
|
112
118
|
} catch (err) {
|
|
113
119
|
return errorJson(err.message || "Internal Server Error", err.statusCode || 500);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { type ObjectKernel, HttpDispatcher, HttpDispatcherResult } from '@objectstack/runtime';\n\nexport interface SvelteKitAdapterOptions {\n kernel: ObjectKernel;\n prefix?: string;\n}\n\n/**\n * Auth service interface with handleRequest method\n */\ninterface AuthService {\n handleRequest(request: Request): Promise<Response>;\n}\n\n/**\n * SvelteKit request event type (minimal interface to avoid hard dependency on @sveltejs/kit types at runtime)\n */\ninterface RequestEvent {\n request: Request;\n url: URL;\n params: Record<string, string>;\n}\n\n/**\n * Creates a SvelteKit request handler for ObjectStack API routes.\n * Use in a catch-all `+server.ts` route like `src/routes/api/[...path]/+server.ts`.\n *\n * Only auth, GraphQL, storage, and discovery need explicit handling.\n * All other routes delegate to `HttpDispatcher.dispatch()` automatically.\n *\n * @example\n * ```ts\n * // src/routes/api/[...path]/+server.ts\n * import { createRequestHandler } from '@objectstack/sveltekit';\n * import { kernel } from '$lib/kernel';\n *\n * const handler = createRequestHandler({ kernel });\n *\n * export const GET = handler;\n * export const POST = handler;\n * export const PUT = handler;\n * export const PATCH = handler;\n * export const DELETE = handler;\n * ```\n */\nexport function createRequestHandler(options: SvelteKitAdapterOptions) {\n const dispatcher = new HttpDispatcher(options.kernel);\n const prefix = options.prefix || '/api';\n\n const errorJson = (message: string, code: number = 500) => {\n return new Response(JSON.stringify({ success: false, error: { message, code } }), {\n status: code,\n headers: { 'Content-Type': 'application/json' },\n });\n };\n\n const toResponse = (result: HttpDispatcherResult): Response => {\n if (result.handled) {\n if (result.response) {\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (result.response.headers) {\n Object.entries(result.response.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(JSON.stringify(result.response.body), {\n status: result.response.status,\n headers,\n });\n }\n if (result.result) {\n const res = result.result;\n if (res.type === 'redirect' && res.url) {\n return new Response(null, {\n status: 302,\n headers: { Location: res.url },\n });\n }\n if (res.type === 'stream' && res.stream) {\n const headers = new Headers();\n if (res.headers) {\n Object.entries(res.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(res.stream, { status: 200, headers });\n }\n return new Response(JSON.stringify(res), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n return errorJson('Not Found', 404);\n };\n\n return async function handler(event: RequestEvent): Promise<Response> {\n const { request, url } = event;\n const method = request.method;\n const path = url.pathname.substring(prefix.length);\n const segments = path.split('/').filter(Boolean);\n\n // --- Discovery ---\n if (segments.length === 0 && method === 'GET') {\n return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n try {\n // --- Auth (needs auth service integration) ---\n if (segments[0] === 'auth') {\n const subPath = segments.slice(1).join('/');\n\n // Try AuthPlugin service first (prefer async to support factory-based services)\n let authService: AuthService | null = null;\n try {\n if (typeof options.kernel.getServiceAsync === 'function') {\n authService = await options.kernel.getServiceAsync<AuthService>('auth');\n } else if (typeof options.kernel.getService === 'function') {\n authService = options.kernel.getService<AuthService>('auth');\n }\n } catch {\n // Service not registered — fall through to dispatcher\n authService = null;\n }\n\n if (authService && typeof authService.handleRequest === 'function') {\n return await authService.handleRequest(request);\n }\n\n // Fallback to dispatcher\n const body = method === 'GET' || method === 'HEAD'\n ? {}\n : await request.json().catch(() => ({}));\n const result = await dispatcher.handleAuth(subPath, method, body, { request });\n return toResponse(result);\n }\n\n // --- GraphQL (returns raw result, not HttpDispatcherResult) ---\n if (segments[0] === 'graphql' && method === 'POST') {\n const body = await request.json() as { query: string; variables?: any };\n const result = await dispatcher.handleGraphQL(body, { request });\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // --- Storage (needs formData parsing) ---\n if (segments[0] === 'storage') {\n const subPath = segments.slice(1).join('/');\n let file: any = undefined;\n if (method === 'POST' && subPath === 'upload') {\n const formData = await request.formData();\n file = formData.get('file');\n }\n const result = await dispatcher.handleStorage(\n subPath ? `/${subPath}` : '',\n method,\n file,\n { request },\n );\n return toResponse(result);\n }\n\n // --- Catch-all: delegate to dispatcher.dispatch() ---\n // Handles meta, data, packages, analytics, automation, i18n, ui,\n // openapi, custom API endpoints, and any future routes.\n const subPath = path || '';\n\n let body: any = undefined;\n if (method === 'POST' || method === 'PUT' || method === 'PATCH') {\n body = await request.json().catch(() => ({}));\n }\n\n const queryParams: Record<string, any> = {};\n url.searchParams.forEach((val, key) => { queryParams[key] = val; });\n\n const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request });\n return toResponse(result);\n } catch (err: any) {\n return errorJson(err.message || 'Internal Server Error', err.statusCode || 500);\n }\n };\n}\n\n/**\n * Creates a SvelteKit handle hook that attaches the kernel to event.locals.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { createHandle } from '@objectstack/sveltekit';\n * export const handle = createHandle({ kernel });\n * ```\n */\nexport function createHandle(options: SvelteKitAdapterOptions) {\n return async function handle({ event, resolve }: { event: any; resolve: (event: any) => Promise<Response> }) {\n event.locals.objectStack = options.kernel;\n return resolve(event);\n };\n}\n"],"mappings":"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","names":["subPath","body","result"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { type ObjectKernel, HttpDispatcher, HttpDispatcherResult } from '@objectstack/runtime';\n\nexport interface SvelteKitAdapterOptions {\n kernel: ObjectKernel;\n prefix?: string;\n}\n\n/**\n * Auth service interface with handleRequest method\n */\ninterface AuthService {\n handleRequest(request: Request): Promise<Response>;\n}\n\n/**\n * SvelteKit request event type (minimal interface to avoid hard dependency on @sveltejs/kit types at runtime)\n */\ninterface RequestEvent {\n request: Request;\n url: URL;\n params: Record<string, string>;\n}\n\n/**\n * Creates a SvelteKit request handler for ObjectStack API routes.\n * Use in a catch-all `+server.ts` route like `src/routes/api/[...path]/+server.ts`.\n *\n * Only auth, GraphQL, storage, and discovery need explicit handling.\n * All other routes delegate to `HttpDispatcher.dispatch()` automatically.\n *\n * @example\n * ```ts\n * // src/routes/api/[...path]/+server.ts\n * import { createRequestHandler } from '@objectstack/sveltekit';\n * import { kernel } from '$lib/kernel';\n *\n * const handler = createRequestHandler({ kernel });\n *\n * export const GET = handler;\n * export const POST = handler;\n * export const PUT = handler;\n * export const PATCH = handler;\n * export const DELETE = handler;\n * ```\n */\nexport function createRequestHandler(options: SvelteKitAdapterOptions) {\n const dispatcher = new HttpDispatcher(options.kernel);\n const prefix = options.prefix || '/api';\n\n const errorJson = (message: string, code: number = 500) => {\n return new Response(JSON.stringify({ success: false, error: { message, code } }), {\n status: code,\n headers: { 'Content-Type': 'application/json' },\n });\n };\n\n const toResponse = (result: HttpDispatcherResult): Response => {\n if (result.handled) {\n if (result.response) {\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (result.response.headers) {\n Object.entries(result.response.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(JSON.stringify(result.response.body), {\n status: result.response.status,\n headers,\n });\n }\n if (result.result) {\n const res = result.result;\n if (res.type === 'redirect' && res.url) {\n return new Response(null, {\n status: 302,\n headers: { Location: res.url },\n });\n }\n if (res.type === 'stream' && res.stream) {\n const headers = new Headers();\n if (res.headers) {\n Object.entries(res.headers).forEach(([k, v]) => headers.set(k, v as string));\n }\n return new Response(res.stream, { status: 200, headers });\n }\n return new Response(JSON.stringify(res), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n return errorJson('Not Found', 404);\n };\n\n return async function handler(event: RequestEvent): Promise<Response> {\n const { request, url } = event;\n const method = request.method;\n const path = url.pathname.substring(prefix.length);\n const segments = path.split('/').filter(Boolean);\n\n // --- Discovery ---\n if (segments.length === 0 && method === 'GET') {\n return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n if (segments.length === 1 && segments[0] === 'discovery' && method === 'GET') {\n return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n try {\n // --- Auth (needs auth service integration) ---\n if (segments[0] === 'auth') {\n const subPath = segments.slice(1).join('/');\n\n // Try AuthPlugin service first (prefer async to support factory-based services)\n let authService: AuthService | null = null;\n try {\n if (typeof options.kernel.getServiceAsync === 'function') {\n authService = await options.kernel.getServiceAsync<AuthService>('auth');\n } else if (typeof options.kernel.getService === 'function') {\n authService = options.kernel.getService<AuthService>('auth');\n }\n } catch {\n // Service not registered — fall through to dispatcher\n authService = null;\n }\n\n if (authService && typeof authService.handleRequest === 'function') {\n return await authService.handleRequest(request);\n }\n\n // Fallback to dispatcher\n const body = method === 'GET' || method === 'HEAD'\n ? {}\n : await request.json().catch(() => ({}));\n const result = await dispatcher.handleAuth(subPath, method, body, { request });\n return toResponse(result);\n }\n\n // --- GraphQL (returns raw result, not HttpDispatcherResult) ---\n if (segments[0] === 'graphql' && method === 'POST') {\n const body = await request.json() as { query: string; variables?: any };\n const result = await dispatcher.handleGraphQL(body, { request });\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // --- Storage (needs formData parsing) ---\n if (segments[0] === 'storage') {\n const subPath = segments.slice(1).join('/');\n let file: any = undefined;\n if (method === 'POST' && subPath === 'upload') {\n const formData = await request.formData();\n file = formData.get('file');\n }\n const result = await dispatcher.handleStorage(\n subPath ? `/${subPath}` : '',\n method,\n file,\n { request },\n );\n return toResponse(result);\n }\n\n // --- Catch-all: delegate to dispatcher.dispatch() ---\n // Handles meta, data, packages, analytics, automation, i18n, ui,\n // openapi, custom API endpoints, and any future routes.\n const subPath = path || '';\n\n let body: any = undefined;\n if (method === 'POST' || method === 'PUT' || method === 'PATCH') {\n body = await request.json().catch(() => ({}));\n }\n\n const queryParams: Record<string, any> = {};\n url.searchParams.forEach((val, key) => { queryParams[key] = val; });\n\n const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request }, prefix);\n return toResponse(result);\n } catch (err: any) {\n return errorJson(err.message || 'Internal Server Error', err.statusCode || 500);\n }\n };\n}\n\n/**\n * Creates a SvelteKit handle hook that attaches the kernel to event.locals.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { createHandle } from '@objectstack/sveltekit';\n * export const handle = createHandle({ kernel });\n * ```\n */\nexport function createHandle(options: SvelteKitAdapterOptions) {\n return async function handle({ event, resolve }: { event: any; resolve: (event: any) => Promise<Response> }) {\n event.locals.objectStack = options.kernel;\n return resolve(event);\n };\n}\n"],"mappings":"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","names":["subPath","body","result"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/sveltekit",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@sveltejs/kit": "^2.
|
|
16
|
-
"@objectstack/runtime": "^4.0.
|
|
15
|
+
"@sveltejs/kit": "^2.56.1",
|
|
16
|
+
"@objectstack/runtime": "^4.0.2"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@sveltejs/kit": "^2.
|
|
19
|
+
"@sveltejs/kit": "^2.56.1",
|
|
20
20
|
"typescript": "^6.0.2",
|
|
21
21
|
"vitest": "^4.1.2",
|
|
22
|
-
"@objectstack/runtime": "4.0.
|
|
22
|
+
"@objectstack/runtime": "4.0.2"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsup --config ../../../tsup.config.ts",
|
package/src/index.ts
CHANGED
|
@@ -106,6 +106,13 @@ export function createRequestHandler(options: SvelteKitAdapterOptions) {
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
if (segments.length === 1 && segments[0] === 'discovery' && method === 'GET') {
|
|
110
|
+
return new Response(JSON.stringify({ data: await dispatcher.getDiscoveryInfo(prefix) }), {
|
|
111
|
+
status: 200,
|
|
112
|
+
headers: { 'Content-Type': 'application/json' },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
109
116
|
try {
|
|
110
117
|
// --- Auth (needs auth service integration) ---
|
|
111
118
|
if (segments[0] === 'auth') {
|
|
@@ -176,7 +183,7 @@ export function createRequestHandler(options: SvelteKitAdapterOptions) {
|
|
|
176
183
|
const queryParams: Record<string, any> = {};
|
|
177
184
|
url.searchParams.forEach((val, key) => { queryParams[key] = val; });
|
|
178
185
|
|
|
179
|
-
const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request });
|
|
186
|
+
const result = await dispatcher.dispatch(method, subPath, body, queryParams, { request }, prefix);
|
|
180
187
|
return toResponse(result);
|
|
181
188
|
} catch (err: any) {
|
|
182
189
|
return errorJson(err.message || 'Internal Server Error', err.statusCode || 500);
|