UNPKG

@fedify/fedify

Version:

An ActivityPub server framework

54 lines (53 loc) 2.21 kB
/** * Create a Hono middleware to integrate with the {@link Federation} object. * * @typeParam TContextData A type of the context data for the {@link Federation} * object. * @typeParam THonoContext A type of the Hono context. * @param federation A {@link Federation} object to integrate with Hono. * @param contextDataFactory A function to create a context data for the * {@link Federation} object. * @returns A Hono middleware. */ export function federation(federation, contextDataFactory) { return async (ctx, next) => { let contextData = contextDataFactory(ctx); if (contextData instanceof Promise) contextData = await contextData; return await federation.fetch(ctx.req.raw, { contextData, ...integrateFetchOptions(ctx, next), }); }; } function integrateFetchOptions(ctx, next) { return { // If the `federation` object finds a request not responsible for it // (i.e., not a federation-related request), it will call the `next` // provided by the Hono framework to continue the request handling // by the Hono: async onNotFound(_req) { await next(); return ctx.res; }, // Similar to `onNotFound`, but slightly more tricky one. // When the `federation` object finds a request not acceptable type-wise // (i.e., a user-agent doesn't want JSON-LD), it will call the `next` // provided by the Hono framework so that it renders HTML if there's some // page. Otherwise, it will simply return a 406 Not Acceptable response. // This kind of trick enables the Fedify and Hono to share the same routes // and they do content negotiation depending on `Accept` header: async onNotAcceptable(_req) { await next(); if (ctx.res.status !== 404) return ctx.res; return new Response("Not acceptable", { status: 406, headers: { "Content-Type": "text/plain", Vary: "Accept", }, }); }, }; }