@silkweave/fastify 3.2.1 → 4.0.0
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/build/index.d.mts.map +1 -1
- package/build/index.mjs +18 -1
- package/build/index.mjs.map +1 -1
- package/package.json +12 -4
package/build/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/adapter/fastify.ts"],"mappings":";;;;;;;UAqBiB,qBAAA,SAA8B,kBAAA,CAAmB,MAAA,EAAQ,iBAAA;EACxE,IAAA;EACA,IAAA;EACA,IAAA,GAAO,UAAA;;EAEP,IAAA,GAAO,oBAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/adapter/fastify.ts"],"mappings":";;;;;;;UAqBiB,qBAAA,SAA8B,kBAAA,CAAmB,MAAA,EAAQ,iBAAA;EACxE,IAAA;EACA,IAAA;EACA,IAAA,GAAO,UAAA;;EAEP,IAAA,GAAO,oBAAA;AAAA;AAAA,cAgNI,OAAA,EAAS,cAAA,CAAe,qBAAA"}
|
package/build/index.mjs
CHANGED
|
@@ -171,6 +171,23 @@ function splitInputSchema(action, method) {
|
|
|
171
171
|
body: hasBody && Object.keys(body.properties).length ? body : void 0
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Register the Scalar API-reference UI. It's an optional peer, so a missing
|
|
176
|
+
* module is skipped with a hint rather than crashing a headless deployment.
|
|
177
|
+
* Resolving the import here (vs. handing `register` a rejecting plugin promise)
|
|
178
|
+
* is what makes the absence catchable now instead of later during `listen`.
|
|
179
|
+
*/
|
|
180
|
+
async function registerScalarDocs(instance) {
|
|
181
|
+
const scalar = await import("@scalar/fastify-api-reference").catch((error) => {
|
|
182
|
+
const code = error.code;
|
|
183
|
+
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") {
|
|
184
|
+
instance.log.info("@scalar/fastify-api-reference is not installed - skipping the API reference UI. Install it to enable the docs UI.");
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
throw error;
|
|
188
|
+
});
|
|
189
|
+
if (scalar) await instance.register(scalar.default, { routePrefix: "/" });
|
|
190
|
+
}
|
|
174
191
|
const fastify = ({ host, port, auth, cors: corsConfig, ...fastifyOptions }) => {
|
|
175
192
|
const instance = fastify$1(fastifyOptions);
|
|
176
193
|
return (options, baseContext) => {
|
|
@@ -190,7 +207,7 @@ const fastify = ({ host, port, auth, cors: corsConfig, ...fastifyOptions }) => {
|
|
|
190
207
|
description: options.description,
|
|
191
208
|
version: options.version
|
|
192
209
|
} } });
|
|
193
|
-
await instance
|
|
210
|
+
await registerScalarDocs(instance);
|
|
194
211
|
if (auth?.authorizationServers?.length && auth.resourceUrl) instance.get("/.well-known/oauth-protected-resource", () => {
|
|
195
212
|
return generateProtectedResourceMetadata(auth.resourceUrl, auth.authorizationServers, auth.requiredScopes);
|
|
196
213
|
});
|
package/build/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["fastifyInstance"],"sources":["../src/adapter/fastify.ts"],"sourcesContent":["import type { FastifyCorsOptions } from '@fastify/cors'\nimport { AuthConfig, AuthInfo, generateProtectedResourceMetadata, OAuthRequest, OAuthResponse, validateToken } from '@silkweave/auth'\nimport { Action, actionMethod, ActionStreamRun, AdapterFactory, buildLogLevels, HttpMethod, isStreamingAction, Logger, LogLevel, methodHasBody, pathParamNames, resolveActionInput, runStreamingAction, SilkweaveContext, SilkweaveError, validateActionRouting } from '@silkweave/core'\nimport { once } from 'events'\nimport { FastifyBaseLogger, FastifyHttpOptions, fastify as fastifyInstance, FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'\nimport { Server } from 'http'\nimport z from 'zod/v4'\n\ntype FastifyLogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\nconst PINO_LEVEL_MAP: Record<LogLevel, FastifyLogLevel> = {\n emergency: 'fatal',\n alert: 'fatal',\n critical: 'fatal',\n error: 'error',\n warning: 'warn',\n notice: 'debug',\n info: 'info',\n debug: 'debug'\n}\n\nexport interface FastifyAdapterOptions extends FastifyHttpOptions<Server, FastifyBaseLogger> {\n host?: string\n port?: number\n auth?: AuthConfig\n /** CORS configuration. `false` to disable, `true`/`undefined` for permissive defaults, or a FastifyCorsOptions object. */\n cors?: FastifyCorsOptions | boolean\n}\n\nfunction toOAuthReq(request: FastifyRequest): OAuthRequest {\n return {\n method: request.method,\n url: new URL(request.url, `http://${request.hostname}`),\n headers: Object.fromEntries(Object.entries(request.headers).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])),\n body: request.body as Record<string, string> | undefined\n }\n}\n\nfunction sendOAuth(reply: FastifyReply, oauthRes: OAuthResponse) {\n for (const [key, value] of Object.entries(oauthRes.headers)) { reply.header(key, value) }\n return reply.status(oauthRes.status).send(oauthRes.body)\n}\n\nfunction mountOAuthRoutes(instance: FastifyInstance, auth: AuthConfig): Set<string> {\n const provider = auth.provider!\n // The provider builds its upstream redirect_uri as `${resourceUrl}${callbackPath}`,\n // so the callback route must match the configured callbackPath, not a hardcoded one.\n const callbackPath = auth.callbackPath ?? '/auth/callback'\n\n const paths = new Set([\n '/.well-known/oauth-authorization-server',\n '/authorize',\n callbackPath,\n '/token',\n '/register'\n ])\n\n instance.get('/.well-known/oauth-authorization-server', async (_req, reply) => {\n return sendOAuth(reply, provider.metadata())\n })\n instance.get('/authorize', async (req, reply) => {\n return sendOAuth(reply, await provider.authorize(toOAuthReq(req)))\n })\n instance.get(callbackPath, async (req, reply) => {\n return sendOAuth(reply, await provider.callback(toOAuthReq(req)))\n })\n instance.post('/token', async (req, reply) => {\n return sendOAuth(reply, await provider.token(toOAuthReq(req)))\n })\n instance.post('/register', async (req, reply) => {\n return sendOAuth(reply, await provider.register(toOAuthReq(req)))\n })\n\n return paths\n}\n\nfunction mountAuthMiddleware(instance: FastifyInstance, auth: AuthConfig, oauthPaths: Set<string>, context: SilkweaveContext) {\n instance.decorateRequest('__silkweave_auth', undefined)\n instance.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n if (request.url.startsWith('/.well-known/') || oauthPaths.has(request.url.split('?')[0])) { return }\n const result = await validateToken(request.headers.authorization, auth, context.fork({ request }))\n if (result.error) {\n for (const [key, value] of Object.entries(result.error.headers)) {\n reply.header(key, value)\n }\n return reply.status(result.error.statusCode).send(result.error.body)\n }\n if (result.auth) {\n (request as FastifyRequest & { __silkweave_auth?: AuthInfo }).__silkweave_auth = result.auth\n }\n })\n}\n\ntype StreamFormat = 'sse' | 'ndjson'\n\nfunction pickStreamFormat(acceptHeader: string | undefined): StreamFormat | null {\n if (!acceptHeader) { return null }\n if (acceptHeader.includes('text/event-stream')) { return 'sse' }\n if (acceptHeader.includes('application/x-ndjson') || acceptHeader.includes('application/ndjson')) { return 'ndjson' }\n return null\n}\n\nfunction encodeChunk(format: StreamFormat, chunk: unknown): string {\n const payload = JSON.stringify(chunk)\n return format === 'sse' ? `data: ${payload}\\n\\n` : `${payload}\\n`\n}\n\nfunction encodeStreamError(format: StreamFormat, error: unknown): string {\n const payload = JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n name: error instanceof Error ? error.name : 'Error'\n })\n return format === 'sse' ? `event: error\\ndata: ${payload}\\n\\n` : `${payload}\\n`\n}\n\nasync function streamAction(\n reply: FastifyReply,\n format: StreamFormat,\n action: Action,\n input: object,\n context: SilkweaveContext\n): Promise<void> {\n reply.raw.setHeader('Content-Type', format === 'sse' ? 'text/event-stream' : 'application/x-ndjson')\n reply.raw.setHeader('Cache-Control', 'no-cache, no-transform')\n reply.raw.setHeader('Connection', 'keep-alive')\n reply.raw.flushHeaders?.()\n reply.hijack()\n const raw = reply.raw\n const iter = (action.run as ActionStreamRun<object, unknown>)(input, context)\n // On client disconnect the next write() returns false and a plain\n // `once(raw, 'drain')` would park forever - the generator would never resume,\n // its finally/cleanup would never run, and response/context stay pinned. Track\n // 'close' and race the drain against it so we bail and tear the generator down.\n const gone = { value: raw.destroyed || raw.writableEnded }\n const onClose = () => { gone.value = true }\n raw.on('close', onClose)\n const closed = once(raw, 'close')\n try {\n for await (const chunk of iter) {\n if (gone.value) { break }\n if (!raw.write(encodeChunk(format, chunk))) {\n await Promise.race([once(raw, 'drain'), closed])\n if (gone.value) { break }\n }\n }\n if (!gone.value && format === 'sse') { raw.write('event: done\\ndata: {}\\n\\n') }\n } catch (error) {\n if (!gone.value) { raw.write(encodeStreamError(format, error)) }\n } finally {\n raw.off('close', onClose)\n // Ask the generator to run its finally/cleanup (release DB handles etc).\n await iter.return?.().catch(() => { /* generator cleanup best-effort */ })\n if (!raw.writableEnded) { raw.end() }\n }\n}\n\nfunction createActionLogger(instance: FastifyInstance): Logger {\n return {\n ...buildLogLevels((level, data) => {\n const pinoLevel = PINO_LEVEL_MAP[level] ?? 'info'\n instance.log[pinoLevel](data)\n }),\n progress: ({ progress, total, message }) => { instance.log.trace({ progress, total }, message) }\n }\n}\n\ninterface ObjectSchema {\n type: 'object'\n properties: Record<string, unknown>\n required: string[]\n}\n\n/**\n * Split an action's input JSON Schema into Fastify `params`/`querystring`/`body`\n * schemas based on its `path` placeholders and `queryParams`. Fastify's own AJV\n * validation, type coercion, and default-filling then apply per source, and the\n * three are merged back into a single input by `resolveActionInput` at runtime.\n */\nfunction splitInputSchema(action: Action, method: HttpMethod): {\n params?: ObjectSchema\n querystring?: ObjectSchema\n body?: ObjectSchema\n} {\n const json = z.toJSONSchema(action.input) as { properties?: Record<string, unknown>; required?: string[] }\n const properties = json.properties ?? {}\n const required = new Set(json.required ?? [])\n const pathParams = new Set(pathParamNames(action.path))\n const queryKeys = new Set((action.queryParams ?? []).map(String))\n const hasBody = methodHasBody(method)\n\n const params: ObjectSchema = { type: 'object', properties: {}, required: [] }\n const querystring: ObjectSchema = { type: 'object', properties: {}, required: [] }\n const body: ObjectSchema = { type: 'object', properties: {}, required: [] }\n\n for (const [key, prop] of Object.entries(properties)) {\n if (pathParams.has(key)) {\n params.properties[key] = prop\n params.required.push(key)\n } else if (!hasBody || queryKeys.has(key)) {\n querystring.properties[key] = prop\n if (required.has(key)) { querystring.required.push(key) }\n } else {\n body.properties[key] = prop\n if (required.has(key)) { body.required.push(key) }\n }\n }\n\n return {\n params: Object.keys(params.properties).length ? params : undefined,\n querystring: Object.keys(querystring.properties).length ? querystring : undefined,\n body: hasBody && Object.keys(body.properties).length ? body : undefined\n }\n}\n\nexport const fastify: AdapterFactory<FastifyAdapterOptions> = ({ host, port, auth, cors: corsConfig, ...fastifyOptions }) => {\n const instance = fastifyInstance(fastifyOptions)\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'fastify' })\n return {\n context,\n start: async (actions) => {\n if (corsConfig !== false) {\n const userConfig = corsConfig === true || corsConfig === undefined ? {} : corsConfig\n await instance.register(import('@fastify/cors'), { origin: '*', ...userConfig })\n }\n\n await instance.register(import('@fastify/swagger'), {\n openapi: {\n info: {\n title: options.name,\n description: options.description,\n version: options.version\n }\n }\n })\n await instance.register(import('@scalar/fastify-api-reference'), { routePrefix: '/' })\n\n if (auth?.authorizationServers?.length && auth.resourceUrl) {\n instance.get('/.well-known/oauth-protected-resource', () => {\n return generateProtectedResourceMetadata(auth.resourceUrl!, auth.authorizationServers!, auth.requiredScopes)\n })\n }\n\n const oauthPaths = auth?.provider ? mountOAuthRoutes(instance, auth) : new Set<string>()\n\n if (auth) {\n mountAuthMiddleware(instance, auth, oauthPaths, context)\n }\n\n instance.setErrorHandler((error, _request, reply) => {\n if (error instanceof SilkweaveError) {\n return reply.status(error.statusCode).send({ error: error.code, message: error.message })\n }\n if (error instanceof z.ZodError) {\n return reply.status(400).send({ error: 'validation_error', issues: error.issues })\n }\n // Fastify's schema (AJV) validation failures for body/querystring/params.\n const validation = (error as { validation?: unknown }).validation\n if (validation) {\n return reply.status(400).send({ error: 'validation_error', issues: validation })\n }\n instance.log.error(error)\n return reply.status(500).send({ error: 'internal', message: 'Internal server error' })\n })\n\n const logger = createActionLogger(instance)\n\n for (const action of actions) {\n validateActionRouting(action)\n const method = actionMethod(action)\n const url = action.path ? `/${action.path.replace(/^\\//, '')}` : `/${action.name}`\n const { params, querystring, body } = splitInputSchema(action, method)\n const streaming = isStreamingAction(action)\n instance.route({\n method,\n url,\n schema: {\n description: action.description,\n ...(params ? { params } : {}),\n ...(querystring ? { querystring } : {}),\n ...(body ? { body } : {}),\n response: {\n 200: { description: 'Successful response' }\n }\n },\n handler: async (request, reply) => {\n const authInfo = auth ? (request as FastifyRequest & { __silkweave_auth?: AuthInfo }).__silkweave_auth : undefined\n const actionContext = context.fork({ logger, request, ...(authInfo ? { auth: authInfo } : {}) })\n // Fastify's AJV only validates the JSON-Schema projection, which\n // cannot express Zod refinements/transforms. Parse the merged input\n // so .refine()/.email()/.transform() are enforced here as they are\n // over MCP/tRPC/CLI (a ZodError becomes a 400 via setErrorHandler).\n const input = action.input.parse(resolveActionInput(action, {\n params: request.params as Record<string, string | undefined>,\n query: request.query as Record<string, unknown>,\n body: request.body\n }))\n if (streaming) {\n const format = pickStreamFormat(request.headers.accept)\n if (format) {\n await streamAction(reply, format, action, input, actionContext)\n return reply\n }\n return runStreamingAction(action, input, actionContext)\n }\n return action.run(input, actionContext)\n }\n })\n }\n await instance.listen({ host, port })\n },\n stop: async () => { await instance.close() }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["fastifyInstance"],"sources":["../src/adapter/fastify.ts"],"sourcesContent":["import type { FastifyCorsOptions } from '@fastify/cors'\nimport { AuthConfig, AuthInfo, generateProtectedResourceMetadata, OAuthRequest, OAuthResponse, validateToken } from '@silkweave/auth'\nimport { Action, actionMethod, ActionStreamRun, AdapterFactory, buildLogLevels, HttpMethod, isStreamingAction, Logger, LogLevel, methodHasBody, pathParamNames, resolveActionInput, runStreamingAction, SilkweaveContext, SilkweaveError, validateActionRouting } from '@silkweave/core'\nimport { once } from 'events'\nimport { FastifyBaseLogger, FastifyHttpOptions, fastify as fastifyInstance, FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'\nimport { Server } from 'http'\nimport z from 'zod/v4'\n\ntype FastifyLogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\nconst PINO_LEVEL_MAP: Record<LogLevel, FastifyLogLevel> = {\n emergency: 'fatal',\n alert: 'fatal',\n critical: 'fatal',\n error: 'error',\n warning: 'warn',\n notice: 'debug',\n info: 'info',\n debug: 'debug'\n}\n\nexport interface FastifyAdapterOptions extends FastifyHttpOptions<Server, FastifyBaseLogger> {\n host?: string\n port?: number\n auth?: AuthConfig\n /** CORS configuration. `false` to disable, `true`/`undefined` for permissive defaults, or a FastifyCorsOptions object. */\n cors?: FastifyCorsOptions | boolean\n}\n\nfunction toOAuthReq(request: FastifyRequest): OAuthRequest {\n return {\n method: request.method,\n url: new URL(request.url, `http://${request.hostname}`),\n headers: Object.fromEntries(Object.entries(request.headers).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])),\n body: request.body as Record<string, string> | undefined\n }\n}\n\nfunction sendOAuth(reply: FastifyReply, oauthRes: OAuthResponse) {\n for (const [key, value] of Object.entries(oauthRes.headers)) { reply.header(key, value) }\n return reply.status(oauthRes.status).send(oauthRes.body)\n}\n\nfunction mountOAuthRoutes(instance: FastifyInstance, auth: AuthConfig): Set<string> {\n const provider = auth.provider!\n // The provider builds its upstream redirect_uri as `${resourceUrl}${callbackPath}`,\n // so the callback route must match the configured callbackPath, not a hardcoded one.\n const callbackPath = auth.callbackPath ?? '/auth/callback'\n\n const paths = new Set([\n '/.well-known/oauth-authorization-server',\n '/authorize',\n callbackPath,\n '/token',\n '/register'\n ])\n\n instance.get('/.well-known/oauth-authorization-server', async (_req, reply) => {\n return sendOAuth(reply, provider.metadata())\n })\n instance.get('/authorize', async (req, reply) => {\n return sendOAuth(reply, await provider.authorize(toOAuthReq(req)))\n })\n instance.get(callbackPath, async (req, reply) => {\n return sendOAuth(reply, await provider.callback(toOAuthReq(req)))\n })\n instance.post('/token', async (req, reply) => {\n return sendOAuth(reply, await provider.token(toOAuthReq(req)))\n })\n instance.post('/register', async (req, reply) => {\n return sendOAuth(reply, await provider.register(toOAuthReq(req)))\n })\n\n return paths\n}\n\nfunction mountAuthMiddleware(instance: FastifyInstance, auth: AuthConfig, oauthPaths: Set<string>, context: SilkweaveContext) {\n instance.decorateRequest('__silkweave_auth', undefined)\n instance.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n if (request.url.startsWith('/.well-known/') || oauthPaths.has(request.url.split('?')[0])) { return }\n const result = await validateToken(request.headers.authorization, auth, context.fork({ request }))\n if (result.error) {\n for (const [key, value] of Object.entries(result.error.headers)) {\n reply.header(key, value)\n }\n return reply.status(result.error.statusCode).send(result.error.body)\n }\n if (result.auth) {\n (request as FastifyRequest & { __silkweave_auth?: AuthInfo }).__silkweave_auth = result.auth\n }\n })\n}\n\ntype StreamFormat = 'sse' | 'ndjson'\n\nfunction pickStreamFormat(acceptHeader: string | undefined): StreamFormat | null {\n if (!acceptHeader) { return null }\n if (acceptHeader.includes('text/event-stream')) { return 'sse' }\n if (acceptHeader.includes('application/x-ndjson') || acceptHeader.includes('application/ndjson')) { return 'ndjson' }\n return null\n}\n\nfunction encodeChunk(format: StreamFormat, chunk: unknown): string {\n const payload = JSON.stringify(chunk)\n return format === 'sse' ? `data: ${payload}\\n\\n` : `${payload}\\n`\n}\n\nfunction encodeStreamError(format: StreamFormat, error: unknown): string {\n const payload = JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n name: error instanceof Error ? error.name : 'Error'\n })\n return format === 'sse' ? `event: error\\ndata: ${payload}\\n\\n` : `${payload}\\n`\n}\n\nasync function streamAction(\n reply: FastifyReply,\n format: StreamFormat,\n action: Action,\n input: object,\n context: SilkweaveContext\n): Promise<void> {\n reply.raw.setHeader('Content-Type', format === 'sse' ? 'text/event-stream' : 'application/x-ndjson')\n reply.raw.setHeader('Cache-Control', 'no-cache, no-transform')\n reply.raw.setHeader('Connection', 'keep-alive')\n reply.raw.flushHeaders?.()\n reply.hijack()\n const raw = reply.raw\n const iter = (action.run as ActionStreamRun<object, unknown>)(input, context)\n // On client disconnect the next write() returns false and a plain\n // `once(raw, 'drain')` would park forever - the generator would never resume,\n // its finally/cleanup would never run, and response/context stay pinned. Track\n // 'close' and race the drain against it so we bail and tear the generator down.\n const gone = { value: raw.destroyed || raw.writableEnded }\n const onClose = () => { gone.value = true }\n raw.on('close', onClose)\n const closed = once(raw, 'close')\n try {\n for await (const chunk of iter) {\n if (gone.value) { break }\n if (!raw.write(encodeChunk(format, chunk))) {\n await Promise.race([once(raw, 'drain'), closed])\n if (gone.value) { break }\n }\n }\n if (!gone.value && format === 'sse') { raw.write('event: done\\ndata: {}\\n\\n') }\n } catch (error) {\n if (!gone.value) { raw.write(encodeStreamError(format, error)) }\n } finally {\n raw.off('close', onClose)\n // Ask the generator to run its finally/cleanup (release DB handles etc).\n await iter.return?.().catch(() => { /* generator cleanup best-effort */ })\n if (!raw.writableEnded) { raw.end() }\n }\n}\n\nfunction createActionLogger(instance: FastifyInstance): Logger {\n return {\n ...buildLogLevels((level, data) => {\n const pinoLevel = PINO_LEVEL_MAP[level] ?? 'info'\n instance.log[pinoLevel](data)\n }),\n progress: ({ progress, total, message }) => { instance.log.trace({ progress, total }, message) }\n }\n}\n\ninterface ObjectSchema {\n type: 'object'\n properties: Record<string, unknown>\n required: string[]\n}\n\n/**\n * Split an action's input JSON Schema into Fastify `params`/`querystring`/`body`\n * schemas based on its `path` placeholders and `queryParams`. Fastify's own AJV\n * validation, type coercion, and default-filling then apply per source, and the\n * three are merged back into a single input by `resolveActionInput` at runtime.\n */\nfunction splitInputSchema(action: Action, method: HttpMethod): {\n params?: ObjectSchema\n querystring?: ObjectSchema\n body?: ObjectSchema\n} {\n const json = z.toJSONSchema(action.input) as { properties?: Record<string, unknown>; required?: string[] }\n const properties = json.properties ?? {}\n const required = new Set(json.required ?? [])\n const pathParams = new Set(pathParamNames(action.path))\n const queryKeys = new Set((action.queryParams ?? []).map(String))\n const hasBody = methodHasBody(method)\n\n const params: ObjectSchema = { type: 'object', properties: {}, required: [] }\n const querystring: ObjectSchema = { type: 'object', properties: {}, required: [] }\n const body: ObjectSchema = { type: 'object', properties: {}, required: [] }\n\n for (const [key, prop] of Object.entries(properties)) {\n if (pathParams.has(key)) {\n params.properties[key] = prop\n params.required.push(key)\n } else if (!hasBody || queryKeys.has(key)) {\n querystring.properties[key] = prop\n if (required.has(key)) { querystring.required.push(key) }\n } else {\n body.properties[key] = prop\n if (required.has(key)) { body.required.push(key) }\n }\n }\n\n return {\n params: Object.keys(params.properties).length ? params : undefined,\n querystring: Object.keys(querystring.properties).length ? querystring : undefined,\n body: hasBody && Object.keys(body.properties).length ? body : undefined\n }\n}\n\n/**\n * Register the Scalar API-reference UI. It's an optional peer, so a missing\n * module is skipped with a hint rather than crashing a headless deployment.\n * Resolving the import here (vs. handing `register` a rejecting plugin promise)\n * is what makes the absence catchable now instead of later during `listen`.\n */\nasync function registerScalarDocs(instance: FastifyInstance): Promise<void> {\n const scalar = await import('@scalar/fastify-api-reference').catch((error: unknown) => {\n const code = (error as { code?: string }).code\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {\n instance.log.info('@scalar/fastify-api-reference is not installed - skipping the API reference UI. Install it to enable the docs UI.')\n return null\n }\n throw error\n })\n if (scalar) {\n await instance.register(scalar.default, { routePrefix: '/' })\n }\n}\n\nexport const fastify: AdapterFactory<FastifyAdapterOptions> = ({ host, port, auth, cors: corsConfig, ...fastifyOptions }) => {\n const instance = fastifyInstance(fastifyOptions)\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'fastify' })\n return {\n context,\n start: async (actions) => {\n if (corsConfig !== false) {\n const userConfig = corsConfig === true || corsConfig === undefined ? {} : corsConfig\n await instance.register(import('@fastify/cors'), { origin: '*', ...userConfig })\n }\n\n await instance.register(import('@fastify/swagger'), {\n openapi: {\n info: {\n title: options.name,\n description: options.description,\n version: options.version\n }\n }\n })\n await registerScalarDocs(instance)\n\n if (auth?.authorizationServers?.length && auth.resourceUrl) {\n instance.get('/.well-known/oauth-protected-resource', () => {\n return generateProtectedResourceMetadata(auth.resourceUrl!, auth.authorizationServers!, auth.requiredScopes)\n })\n }\n\n const oauthPaths = auth?.provider ? mountOAuthRoutes(instance, auth) : new Set<string>()\n\n if (auth) {\n mountAuthMiddleware(instance, auth, oauthPaths, context)\n }\n\n instance.setErrorHandler((error, _request, reply) => {\n if (error instanceof SilkweaveError) {\n return reply.status(error.statusCode).send({ error: error.code, message: error.message })\n }\n if (error instanceof z.ZodError) {\n return reply.status(400).send({ error: 'validation_error', issues: error.issues })\n }\n // Fastify's schema (AJV) validation failures for body/querystring/params.\n const validation = (error as { validation?: unknown }).validation\n if (validation) {\n return reply.status(400).send({ error: 'validation_error', issues: validation })\n }\n instance.log.error(error)\n return reply.status(500).send({ error: 'internal', message: 'Internal server error' })\n })\n\n const logger = createActionLogger(instance)\n\n for (const action of actions) {\n validateActionRouting(action)\n const method = actionMethod(action)\n const url = action.path ? `/${action.path.replace(/^\\//, '')}` : `/${action.name}`\n const { params, querystring, body } = splitInputSchema(action, method)\n const streaming = isStreamingAction(action)\n instance.route({\n method,\n url,\n schema: {\n description: action.description,\n ...(params ? { params } : {}),\n ...(querystring ? { querystring } : {}),\n ...(body ? { body } : {}),\n response: {\n 200: { description: 'Successful response' }\n }\n },\n handler: async (request, reply) => {\n const authInfo = auth ? (request as FastifyRequest & { __silkweave_auth?: AuthInfo }).__silkweave_auth : undefined\n const actionContext = context.fork({ logger, request, ...(authInfo ? { auth: authInfo } : {}) })\n // Fastify's AJV only validates the JSON-Schema projection, which\n // cannot express Zod refinements/transforms. Parse the merged input\n // so .refine()/.email()/.transform() are enforced here as they are\n // over MCP/tRPC/CLI (a ZodError becomes a 400 via setErrorHandler).\n const input = action.input.parse(resolveActionInput(action, {\n params: request.params as Record<string, string | undefined>,\n query: request.query as Record<string, unknown>,\n body: request.body\n }))\n if (streaming) {\n const format = pickStreamFormat(request.headers.accept)\n if (format) {\n await streamAction(reply, format, action, input, actionContext)\n return reply\n }\n return runStreamingAction(action, input, actionContext)\n }\n return action.run(input, actionContext)\n }\n })\n }\n await instance.listen({ host, port })\n },\n stop: async () => { await instance.close() }\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silkweave/fastify",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Silkweave Fastify REST Adapter",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.silkweave.dev",
|
|
@@ -28,14 +28,22 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@fastify/cors": "^11.2.0",
|
|
30
30
|
"@fastify/swagger": "^9.7.0",
|
|
31
|
-
"@scalar/fastify-api-reference": "^1.49.0",
|
|
32
31
|
"fastify": "^5.8.2",
|
|
33
32
|
"zod": "^3.25.0",
|
|
34
|
-
"@silkweave/auth": "
|
|
35
|
-
"@silkweave/core": "
|
|
33
|
+
"@silkweave/auth": "4.0.0",
|
|
34
|
+
"@silkweave/core": "4.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@scalar/fastify-api-reference": "^1.49.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"@scalar/fastify-api-reference": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
36
43
|
},
|
|
37
44
|
"devDependencies": {
|
|
38
45
|
"@eslint/js": "^10.0.1",
|
|
46
|
+
"@scalar/fastify-api-reference": "^1.49.0",
|
|
39
47
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
40
48
|
"@types/node": "^22.0.0",
|
|
41
49
|
"eslint": "^10.4.0",
|