@fedify/fedify
Version:
An ActivityPub server framework
65 lines (64 loc) • 2.28 kB
JavaScript
/**
* Fedify with SvelteKit
* =====================
*
* This module provides a [SvelteKit] hook to integrate with the Fedify.
*
* [SvelteKit]: https://kit.svelte.dev/
*
* @module
* @since 1.3.0
*/
/**
* Create a SvelteKit hook handler to integrate with the {@link Federation}
* object.
*
* @example hooks.server.ts
* ``` typescript
* import { federation } from "./federation"; // Import the `Federation` object
*
* export const handle = fedifyHook(federation, () => undefined);
* ```
*
* @typeParam TContextData A type of the context data for the {@link Federation}
* object.
* @param federation A {@link Federation} object to integrate with SvelteKit.
* @param createContextData A function to create a context data for the
* {@link Federation} object.
* @returns A SvelteKit hook handler.
* @since 1.3.0
*/
export function fedifyHook(federation, createContextData) {
return async ({ event, resolve }) => {
return await federation.fetch(event.request, {
contextData: await createContextData(event),
...integrateFetchOptions({ event, resolve }),
});
};
}
function integrateFetchOptions({ event, resolve }) {
return {
async onNotFound() {
return await resolve(event);
},
// 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 `resolve`
// provided by the SvelteKit 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 SvelteKit to share the same routes
// and they do content negotiation depending on `Accept` header:
async onNotAcceptable() {
const res = await resolve(event);
if (res.status !== 404)
return res;
return new Response("Not acceptable", {
status: 406,
headers: {
"Content-Type": "text/plain",
Vary: "Accept",
},
});
},
};
}