This release is 9 versions behind 1.3.0 — the latest version of @fedify/fedify. Jump to latest
Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Built and signed on GitHub Actions
An ActivityPub/fediverse server framework
This package works with Node.js, Deno, Bun
JSR Score
100%
Published
a month ago (1.2.0)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671import type { Actor, Recipient } from "../vocab/actor.ts"; import type { Activity, Hashtag, Object } from "../vocab/vocab.ts"; import type { ActorDispatcher, ActorHandleMapper, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCounter, CollectionCursor, CollectionDispatcher, InboxErrorHandler, InboxListener, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectDispatcher, SharedInboxKeyDispatcher, } from "./callback.ts"; import type { Context, RequestContext } from "./context.ts"; /** * Options for {@link Federation.startQueue} method. * @since 1.0.0 */ export interface FederationStartQueueOptions { /** * The signal to abort the task queue. */ signal?: AbortSignal; } /** * An object that registers federation-related business logic and dispatches * requests to the appropriate handlers. * * It also provides a middleware interface for handling requests before your * web framework's router; see {@link Federation.fetch}. * * @since 0.13.0 */ export interface Federation<TContextData> { /** * Manually start the task queue. * * This method is useful when you set the `manuallyStartQueue` option to * `true` in the {@link createFederation} function. * @param contextData The context data to pass to the context. * @param options Additional options for starting the queue. */ startQueue( contextData: TContextData, options?: FederationStartQueueOptions, ): Promise<void>; /** * Create a new context. * @param baseUrl The base URL of the server. The `pathname` remains root, * and the `search` and `hash` are stripped. * @param contextData The context data to pass to the context. * @returns The new context. */ createContext(baseUrl: URL, contextData: TContextData): Context<TContextData>; /** * Create a new context for a request. * @param request The request object. * @param contextData The context data to pass to the context. * @returns The new request context. */ createContext( request: Request, contextData: TContextData, ): RequestContext<TContextData>; /** * Registers a NodeInfo dispatcher. * @param path The URI path pattern for the NodeInfo dispatcher. The syntax * is based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have no variables. * @param dispatcher A NodeInfo dispatcher callback to register. * @throws {RouterError} Thrown if the path pattern is invalid. */ setNodeInfoDispatcher( path: string, dispatcher: NodeInfoDispatcher<TContextData>, ): void; /** * Registers an actor dispatcher. * * @example * ``` typescript * federation.setActorDispatcher( * "/users/{identifier}", * async (ctx, identifier) => { * return new Person({ * id: ctx.getActorUri(identifier), * // ... * }); * } * ); * ``` * * @param path The URI path pattern for the actor dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`. * @param dispatcher An actor dispatcher callback to register. * @returns An object with methods to set other actor dispatcher callbacks. * @throws {RouterError} Thrown if the path pattern is invalid. */ setActorDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: ActorDispatcher<TContextData>, ): ActorCallbackSetters<TContextData>; /** * Registers an object dispatcher. * * @typeParam TContextData The context data to pass to the {@link Context}. * @typeParam TObject The type of object to dispatch. * @typeParam TParam The parameter names of the requested URL. * @param cls The Activity Vocabulary class of the object to dispatch. * @param path The URI path pattern for the object dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one or more variables. * @param dispatcher An object dispatcher callback to register. */ setObjectDispatcher<TObject extends Object, TParam extends string>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>, ): ObjectCallbackSetters<TContextData, TObject, TParam>; /** * Registers an object dispatcher. * * @typeParam TContextData The context data to pass to the {@link Context}. * @typeParam TObject The type of object to dispatch. * @typeParam TParam The parameter names of the requested URL. * @param cls The Activity Vocabulary class of the object to dispatch. * @param path The URI path pattern for the object dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one or more variables. * @param dispatcher An object dispatcher callback to register. */ setObjectDispatcher<TObject extends Object, TParam extends string>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>, ): ObjectCallbackSetters<TContextData, TObject, TParam>; /** * Registers an object dispatcher. * * @typeParam TContextData The context data to pass to the {@link Context}. * @typeParam TObject The type of object to dispatch. * @typeParam TParam The parameter names of the requested URL. * @param cls The Activity Vocabulary class of the object to dispatch. * @param path The URI path pattern for the object dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one or more variables. * @param dispatcher An object dispatcher callback to register. */ setObjectDispatcher<TObject extends Object, TParam extends string>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>, ): ObjectCallbackSetters<TContextData, TObject, TParam>; /** * Registers an object dispatcher. * * @typeParam TContextData The context data to pass to the {@link Context}. * @typeParam TObject The type of object to dispatch. * @typeParam TParam The parameter names of the requested URL. * @param cls The Activity Vocabulary class of the object to dispatch. * @param path The URI path pattern for the object dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one or more variables. * @param dispatcher An object dispatcher callback to register. */ setObjectDispatcher<TObject extends Object, TParam extends string>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>, ): ObjectCallbackSetters<TContextData, TObject, TParam>; /** * Registers an object dispatcher. * * @typeParam TContextData The context data to pass to the {@link Context}. * @typeParam TObject The type of object to dispatch. * @typeParam TParam The parameter names of the requested URL. * @param cls The Activity Vocabulary class of the object to dispatch. * @param path The URI path pattern for the object dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one or more variables. * @param dispatcher An object dispatcher callback to register. */ setObjectDispatcher<TObject extends Object, TParam extends string>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>, ): ObjectCallbackSetters<TContextData, TObject, TParam>; /** * Registers an object dispatcher. * * @typeParam TContextData The context data to pass to the {@link Context}. * @typeParam TObject The type of object to dispatch. * @typeParam TParam The parameter names of the requested URL. * @param cls The Activity Vocabulary class of the object to dispatch. * @param path The URI path pattern for the object dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one or more variables. * @param dispatcher An object dispatcher callback to register. */ setObjectDispatcher<TObject extends Object, TParam extends string>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>, ): ObjectCallbackSetters<TContextData, TObject, TParam>; /** * Registers an inbox dispatcher. * * @param path The URI path pattern for the inbox dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`, and must match * the inbox listener path. * @param dispatcher An inbox dispatcher callback to register. * @throws {@link RouterError} Thrown if the path pattern is invalid. */ setInboxDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: CollectionDispatcher< Activity, RequestContext<TContextData>, TContextData, void >, ): CollectionCallbackSetters< RequestContext<TContextData>, TContextData, void >; /** * Registers an outbox dispatcher. * * @example * ``` typescript * federation.setOutboxDispatcher( * "/users/{identifier}/outbox", * async (ctx, identifier, options) => { * let items: Activity[]; * let nextCursor: string; * // ... * return { items, nextCursor }; * } * ); * ``` * * @param path The URI path pattern for the outbox dispatcher. The syntax is * based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`. * @param dispatcher An outbox dispatcher callback to register. * @throws {@link RouterError} Thrown if the path pattern is invalid. */ setOutboxDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: CollectionDispatcher< Activity, RequestContext<TContextData>, TContextData, void >, ): CollectionCallbackSetters< RequestContext<TContextData>, TContextData, void >; /** * Registers a following collection dispatcher. * @param path The URI path pattern for the following collection. The syntax * is based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`. * @param dispatcher A following collection callback to register. * @returns An object with methods to set other following collection * callbacks. * @throws {RouterError} Thrown if the path pattern is invalid. */ setFollowingDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: CollectionDispatcher< Actor | URL, RequestContext<TContextData>, TContextData, void >, ): CollectionCallbackSetters< RequestContext<TContextData>, TContextData, void >; /** * Registers a followers collection dispatcher. * @param path The URI path pattern for the followers collection. The syntax * is based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`. * @param dispatcher A followers collection callback to register. * @returns An object with methods to set other followers collection * callbacks. * @throws {@link RouterError} Thrown if the path pattern is invalid. */ setFollowersDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: CollectionDispatcher< Recipient, Context<TContextData>, TContextData, URL >, ): CollectionCallbackSetters<Context<TContextData>, TContextData, URL>; /** * Registers a liked collection dispatcher. * @param path The URI path pattern for the liked collection. The syntax * is based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`. * @param dispatcher A liked collection callback to register. * @returns An object with methods to set other liked collection * callbacks. * @throws {@link RouterError} Thrown if the path pattern is invalid. */ setLikedDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: CollectionDispatcher< Object | URL, RequestContext<TContextData>, TContextData, void >, ): CollectionCallbackSetters< RequestContext<TContextData>, TContextData, void >; /** * Registers a featured collection dispatcher. * @param path The URI path pattern for the featured collection. The syntax * is based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`. * @param dispatcher A featured collection callback to register. * @returns An object with methods to set other featured collection * callbacks. * @throws {@link RouterError} Thrown if the path pattern is invalid. */ setFeaturedDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: CollectionDispatcher< Object, RequestContext<TContextData>, TContextData, void >, ): CollectionCallbackSetters< RequestContext<TContextData>, TContextData, void >; /** * Registers a featured tags collection dispatcher. * @param path The URI path pattern for the featured tags collection. * The syntax is based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path * must have one variable: `{identifier}`. * @param dispatcher A featured tags collection callback to register. * @returns An object with methods to set other featured tags collection * callbacks. * @throws {@link RouterError} Thrown if the path pattern is invalid. */ setFeaturedTagsDispatcher( path: `${string}{identifier}${string}` | `${string}{handle}${string}`, dispatcher: CollectionDispatcher< Hashtag, RequestContext<TContextData>, TContextData, void >, ): CollectionCallbackSetters< RequestContext<TContextData>, TContextData, void >; /** * Assigns the URL path for the inbox and starts setting inbox listeners. * * @example * ``` typescript * federation * .setInboxListeners("/users/{identifier}/inbox", "/inbox") * .on(Follow, async (ctx, follow) => { * const from = await follow.getActor(ctx); * if (!isActor(from)) return; * // ... * }) * .on(Undo, async (ctx, undo) => { * // ... * }); * ``` * * @param inboxPath The URI path pattern for the inbox. The syntax is based * on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). * The path must have one variable: `{identifier}`, and must * match the inbox dispatcher path. * @param sharedInboxPath An optional URI path pattern for the shared inbox. * The syntax is based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). * The path must have no variables. * @returns An object to register inbox listeners. * @throws {RouteError} Thrown if the path pattern is invalid. */ setInboxListeners( inboxPath: `${string}{identifier}${string}` | `${string}{handle}${string}`, sharedInboxPath?: string, ): InboxListenerSetters<TContextData>; /** * Handles a request related to federation. If a request is not related to * federation, the `onNotFound` or `onNotAcceptable` callback is called. * * Usually, this method is called from a server's request handler or * a web framework's middleware. * * @param request The request object. * @param parameters The parameters for handling the request. * @returns The response to the request. */ fetch( request: Request, options: FederationFetchOptions<TContextData>, ): Promise<Response>; } /** * Additional settings for the actor dispatcher. * * ``` typescript * const federation = createFederation<void>({ ... }); * federation * .setActorDispatcher("/users/{identifier}", async (ctx, identifier) => { * // ... * }) * .setKeyPairsDispatcher(async (ctxData, identifier) => { * // ... * }); * ``` */ export interface ActorCallbackSetters<TContextData> { /** * Sets the key pairs dispatcher for actors. * @param dispatcher A callback that returns the key pairs for an actor. * @returns The setters object so that settings can be chained. * @since 0.10.0 */ setKeyPairsDispatcher( dispatcher: ActorKeyPairsDispatcher<TContextData>, ): ActorCallbackSetters<TContextData>; /** * Sets the callback function that maps a WebFinger username to * the corresponding actor's identifier. If it's omitted, the identifier * is assumed to be the same as the WebFinger username, which makes your * actors have the immutable handles. If you want to let your actors change * their fediverse handles, you should set this dispatcher. * @since 0.15.0 */ mapHandle( mapper: ActorHandleMapper<TContextData>, ): ActorCallbackSetters<TContextData>; /** * Specifies the conditions under which requests are authorized. * @param predicate A callback that returns whether a request is authorized. * @returns The setters object so that settings can be chained. * @since 0.7.0 */ authorize( predicate: AuthorizePredicate<TContextData>, ): ActorCallbackSetters<TContextData>; } /** * Additional settings for an object dispatcher. */ export interface ObjectCallbackSetters< TContextData, TObject extends Object, TParam extends string, > { /** * Specifies the conditions under which requests are authorized. * @param predicate A callback that returns whether a request is authorized. * @returns The setters object so that settings can be chained. * @since 0.7.0 */ authorize( predicate: ObjectAuthorizePredicate<TContextData, TParam>, ): ObjectCallbackSetters<TContextData, TObject, TParam>; } /** * Additional settings for a collection dispatcher. * * @typeParam TContext The type of the context. {@link Context} or * {@link RequestContext}. * @typeParam TContextData The context data to pass to the {@link Context}. * @typeParam TFilter The type of filter for the collection. */ export interface CollectionCallbackSetters< TContext extends Context<TContextData>, TContextData, TFilter, > { /** * Sets the counter for the collection. * @param counter A callback that returns the number of items in the collection. * @returns The setters object so that settings can be chained. */ setCounter( counter: CollectionCounter<TContextData, TFilter>, ): CollectionCallbackSetters<TContext, TContextData, TFilter>; /** * Sets the first cursor for the collection. * @param cursor The cursor for the first item in the collection. * @returns The setters object so that settings can be chained. */ setFirstCursor( cursor: CollectionCursor<TContext, TContextData, TFilter>, ): CollectionCallbackSetters<TContext, TContextData, TFilter>; /** * Sets the last cursor for the collection. * @param cursor The cursor for the last item in the collection. * @returns The setters object so that settings can be chained. */ setLastCursor( cursor: CollectionCursor<TContext, TContextData, TFilter>, ): CollectionCallbackSetters<TContext, TContextData, TFilter>; /** * Specifies the conditions under which requests are authorized. * @param predicate A callback that returns whether a request is authorized. * @returns The setters object so that settings can be chained. * @since 0.7.0 */ authorize( predicate: AuthorizePredicate<TContextData>, ): CollectionCallbackSetters<TContext, TContextData, TFilter>; } /** * Registry for inbox listeners for different activity types. */ export interface InboxListenerSetters<TContextData> { /** * Registers a listener for a specific incoming activity type. * * @param type A subclass of {@link Activity} to listen to. * @param listener A callback to handle an incoming activity. * @returns The setters object so that settings can be chained. */ on<TActivity extends Activity>( // deno-lint-ignore no-explicit-any type: new (...args: any[]) => TActivity, listener: InboxListener<TContextData, TActivity>, ): InboxListenerSetters<TContextData>; /** * Registers an error handler for inbox listeners. Any exceptions thrown * from the listeners are caught and passed to this handler. * * @param handler A callback to handle an error. * @returns The setters object so that settings can be chained. */ onError( handler: InboxErrorHandler<TContextData>, ): InboxListenerSetters<TContextData>; /** * Configures a callback to dispatch the key pair for the authenticated * document loader of the {@link Context} passed to the shared inbox listener. * * @param dispatcher A callback to dispatch the key pair for the authenticated * document loader. * @returns The setters object so that settings can be chained. * @since 0.11.0 */ setSharedKeyDispatcher( dispatcher: SharedInboxKeyDispatcher<TContextData>, ): InboxListenerSetters<TContextData>; } /** * Parameters of {@link Federation.fetch} method. * * @typeParam TContextData The context data to pass to the {@link Context}. * @since 0.6.0 */ export interface FederationFetchOptions<TContextData> { /** * The context data to pass to the {@link Context}. */ contextData: TContextData; /** * A callback to handle a request when the route is not found. * If not provided, a 404 response is returned. * @param request The request object. * @returns The response to the request. */ onNotFound?: (request: Request) => Response | Promise<Response>; /** * A callback to handle a request when the request's `Accept` header is not * acceptable. If not provided, a 406 response is returned. * @param request The request object. * @returns The response to the request. */ onNotAcceptable?: (request: Request) => Response | Promise<Response>; /** * A callback to handle a request when the request is unauthorized. * If not provided, a 401 response is returned. * @param request The request object. * @returns The response to the request. * @since 0.7.0 */ onUnauthorized?: (request: Request) => Response | Promise<Response>; }