This release is 21 versions behind 1.2.3 — 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
2 months ago (0.15.0)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435import type { DocumentLoader } from "../runtime/docloader.ts"; import type { Actor, Recipient } from "../vocab/actor.ts"; import type { LookupObjectOptions } from "../vocab/lookup.ts"; import type { Activity, CryptographicKey, Multikey, Object, } from "../vocab/mod.ts"; import type { SenderKeyPair } from "./send.ts"; /** * A context. */ export interface Context<TContextData> { /** * The origin of the federated server, including the scheme (`http://` or * `https://`) and the host (e.g., `example.com:8080`). * @since 0.12.0 */ readonly origin: string; /** * The host of the federated server, including the hostname * (e.g., `example.com`) and the port following a colon (e.g., `:8080`) * if it is not the default port for the scheme. * @since 0.12.0 */ readonly host: string; /** * The hostname of the federated server (e.g., `example.com`). This is * the same as the host without the port. * @since 0.12.0 */ readonly hostname: string; /** * The user-defined data associated with the context. */ readonly data: TContextData; /** * The document loader for loading remote JSON-LD documents. */ readonly documentLoader: DocumentLoader; /** * The context loader for loading remote JSON-LD contexts. */ readonly contextLoader: DocumentLoader; /** * Builds the URI of the NodeInfo document. * @returns The NodeInfo URI. * @throws {RouterError} If no NodeInfo dispatcher is available. * @since 0.2.0 */ getNodeInfoUri(): URL; /** * Builds the URI of an actor with the given handle. * @param handle The actor's handle. * @returns The actor's URI. * @throws {RouterError} If no actor dispatcher is available. */ getActorUri(handle: string): URL; /** * Builds the URI of an object with the given class and values. * @param cls The class of the object. * @param values The values to pass to the object dispatcher. * @returns The object's URI. * @throws {RouteError} If no object dispatcher is available for the class. * @throws {TypeError} If values are invalid. * @since 0.7.0 */ getObjectUri<TObject extends Object>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, values: Record<string, string>, ): URL; /** * Builds the URI of an actor's outbox with the given handle. * @param handle The actor's handle. * @returns The actor's outbox URI. * @throws {RouterError} If no outbox dispatcher is available. */ getOutboxUri(handle: string): URL; /** * Builds the URI of the shared inbox. * @returns The shared inbox URI. * @throws {RouterError} If no inbox listener is available. */ getInboxUri(): URL; /** * Builds the URI of an actor's inbox with the given handle. * @param handle The actor's handle. * @returns The actor's inbox URI. * @throws {RouterError} If no inbox listener is available. */ getInboxUri(handle: string): URL; /** * Builds the URI of an actor's following collection with the given handle. * @param handle The actor's handle. * @returns The actor's following collection URI. * @throws {RouterError} If no following collection is available. */ getFollowingUri(handle: string): URL; /** * Builds the URI of an actor's followers collection with the given handle. * @param handle The actor's handle. * @returns The actor's followers collection URI. * @throws {RouterError} If no followers collection is available. */ getFollowersUri(handle: string): URL; /** * Builds the URI of an actor's liked collection with the given handle. * @param handle The actor's handle. * @returns The actor's liked collection URI. * @throws {RouterError} If no liked collection is available. * @since 0.11.0 */ getLikedUri(handle: string): URL; /** * Builds the URI of an actor's featured collection with the given handle. * @param handle The actor's handle. * @returns The actor's featured collection URI. * @throws {RouterError} If no featured collection is available. * @since 0.11.0 */ getFeaturedUri(handle: string): URL; /** * Builds the URI of an actor's featured tags collection with the given * handle. * @param handle The actor's handle. * @returns The actor's featured tags collection URI. * @throws {RouterError} If no featured tags collection is available. * @since 0.11.0 */ getFeaturedTagsUri(handle: string): URL; /** * Determines the type of the URI and extracts the associated data. * @param uri The URI to parse. * @since 0.9.0 */ parseUri(uri: URL): ParseUriResult | null; /** * Gets the key pairs for an actor. * @param handle The actor's handle. * @returns An async iterable of the actor's key pairs. It can be empty. * @since 0.10.0 */ getActorKeyPairs(handle: string): Promise<ActorKeyPair[]>; /** * Gets an authenticated {@link DocumentLoader} for the given identity. * Note that an authenticated document loader intentionally does not cache * the fetched documents. * @param identity The identity to get the document loader for. * The actor's handle. * @returns The authenticated document loader. * @throws {Error} If the identity is not valid. * @throws {TypeError} If the key is invalid or unsupported. * @since 0.4.0 */ getDocumentLoader(identity: { handle: string }): Promise<DocumentLoader>; /** * Gets an authenticated {@link DocumentLoader} for the given identity. * Note that an authenticated document loader intentionally does not cache * the fetched documents. * @param identity The identity to get the document loader for. * The actor's key pair. * @returns The authenticated document loader. * @throws {TypeError} If the key is invalid or unsupported. * @since 0.4.0 */ getDocumentLoader( identity: { keyId: URL; privateKey: CryptoKey }, ): DocumentLoader; /** * Looks up an ActivityStreams object by its URI (including `acct:` URIs) * or a fediverse handle (e.g., `@user@server` or `user@server`). * * @example * ``` typescript * // Look up an actor by its fediverse handle: * await ctx.lookupObject("@hongminhee@fosstodon.org"); * // returning a `Person` object. * * // A fediverse handle can omit the leading '@': * await ctx.lookupObject("hongminhee@fosstodon.org"); * // returning a `Person` object. * * // A `acct:` URI can be used as well: * await ctx.lookupObject("acct:hongminhee@fosstodon.org"); * // returning a `Person` object. * * // Look up an object by its URI: * await ctx.lookupObject("https://todon.eu/@hongminhee/112060633798771581"); * // returning a `Note` object. * * // It can be a `URL` object as well: * await ctx.lookupObject( * new URL("https://todon.eu/@hongminhee/112060633798771581") * ); * // returning a `Note` object. * ``` * * It's almost the same as the {@link lookupObject} function, but it uses * the context's document loader and context loader by default. * * @param identifier The URI or fediverse handle to look up. * @param options Lookup options. * @returns The object, or `null` if not found. * @since 0.15.0 */ lookupObject( identifier: string | URL, options?: LookupObjectOptions, ): Promise<Object | null>; /** * Sends an activity to recipients' inboxes. * @param sender The sender's handle or the sender's key pair(s). * @param recipients The recipients of the activity. * @param activity The activity to send. * @param options Options for sending the activity. */ sendActivity( sender: SenderKeyPair | SenderKeyPair[] | { handle: string }, recipients: Recipient | Recipient[], activity: Activity, options?: SendActivityOptions, ): Promise<void>; /** * Sends an activity to the outboxes of the sender's followers. * @param sender The sender's handle. * @param recipients In this case, it must be `"followers"`. * @param activity The activity to send. * @param options Options for sending the activity. * @throws {Error} If no followers collection is registered. * @since 0.14.0 */ sendActivity( sender: { handle: string }, recipients: "followers", activity: Activity, options?: SendActivityOptions, ): Promise<void>; } /** * A context for a request. */ export interface RequestContext<TContextData> extends Context<TContextData> { /** * The request object. */ readonly request: Request; /** * The URL of the request. */ readonly url: URL; /** * Gets an {@link Actor} object for the given handle. * @param handle The actor's handle. * @returns The actor object, or `null` if the actor is not found. * @throws {Error} If no actor dispatcher is available. * @since 0.7.0 */ getActor(handle: string): Promise<Actor | null>; /** * Gets an object of the given class with the given values. * @param cls The class to instantiate. * @param values The values to pass to the object dispatcher. * @returns The object of the given class with the given values, or `null` * if the object is not found. * @throws {Error} If no object dispatcher is available for the class. * @throws {TypeError} If values are invalid. * @since 0.7.0 */ getObject<TObject extends Object>( // deno-lint-ignore no-explicit-any cls: (new (...args: any[]) => TObject) & { typeId: URL }, values: Record<string, string>, ): Promise<TObject | null>; /** * Gets the public key of the sender, if any exists and it is verified. * Otherwise, `null` is returned. * * This can be used for implementing [authorized fetch] (also known as * secure mode) in ActivityPub. * * [authorized fetch]: https://swicg.github.io/activitypub-http-signature/#authorized-fetch * * @returns The public key of the sender, or `null` if the sender is not verified. * @since 0.7.0 */ getSignedKey(): Promise<CryptographicKey | null>; /** * Gets the owner of the signed key, if any exists and it is verified. * Otherwise, `null` is returned. * * This can be used for implementing [authorized fetch] (also known as * secure mode) in ActivityPub. * * [authorized fetch]: https://swicg.github.io/activitypub-http-signature/#authorized-fetch * * @returns The owner of the signed key, or `null` if the key is not verified * or the owner is not found. * @since 0.7.0 */ getSignedKeyOwner(): Promise<Actor | null>; } /** * A result of parsing an URI. */ export type ParseUriResult = /** * The case of an actor URI. */ | { type: "actor"; handle: string } /** * The case of an object URI. */ | { type: "object"; // deno-lint-ignore no-explicit-any class: (new (...args: any[]) => Object) & { typeId: URL }; typeId: URL; values: Record<string, string>; } /** * The case of an inbox URI. If `handle` is `undefined`, * it is a shared inbox. */ | { type: "inbox"; handle?: string } /** * The case of an outbox collection URI. */ | { type: "outbox"; handle: string } /** * The case of a following collection URI. */ | { type: "following"; handle: string } /** * The case of a followers collection URI. */ | { type: "followers"; handle: string } /** * The case of a liked collection URI. * @since 0.11.0 */ | { type: "liked"; handle: string } /** * The case of a featured collection URI. * @since 0.11.0 */ | { type: "featured"; handle: string } /** * The case of a featured tags collection URI. * @since 0.11.0 */ | { type: "featuredTags"; handle: string }; /** * Options for {@link Context.sendActivity} method and * {@link Federation.sendActivity} method. */ export interface SendActivityOptions { /** * Whether to prefer the shared inbox for the recipients. */ preferSharedInbox?: boolean; /** * Whether to send the activity immediately, without enqueuing it. * If `true`, the activity will be sent immediately and the retrial * policy will not be applied. * * @since 0.3.0 */ immediate?: boolean; /** * The base URIs to exclude from the recipients' inboxes. It is useful * for excluding the recipients having the same shared inbox with the sender. * * Note that the only `origin` parts of the `URL`s are compared. * * @since 0.9.0 */ excludeBaseUris?: URL[]; } /** * A pair of a public key and a private key in various formats. * @since 0.10.0 */ export interface ActorKeyPair extends CryptoKeyPair { /** * The URI of the public key, which is used for verifying HTTP Signatures. */ keyId: URL; /** * A {@link CryptographicKey} instance of the public key. */ cryptographicKey: CryptographicKey; /** * A {@link Multikey} instance of the public key. */ multikey: Multikey; }