Loading packages/fedify/src/federation/builder.ts +27 −23 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ import type { FederationOptions, InboxListenerSetters, ObjectCallbackSetters, ParamsKeyPath, Rfc6570Expression, } from "./federation.ts"; import type { CollectionCallbacks, Loading Loading @@ -110,7 +110,7 @@ export class FederationBuilderImpl<TContextData> string | symbol, CustomCollectionCallbacks< Object, Record<string, string>, string, RequestContext<TContextData>, TContextData > Loading Loading @@ -1208,21 +1208,22 @@ export class FederationBuilderImpl<TContextData> setCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, ...args: [ ConstructorWithTypeId<TObject>, ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any (new (...args: any[]) => TObject) & { typeId: URL }, `${string}${Rfc6570Expression<TParam>}${string}`, CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ] ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > { Loading @@ -1235,21 +1236,22 @@ export class FederationBuilderImpl<TContextData> setOrderedCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, ...args: [ ConstructorWithTypeId<TObject>, ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any (new (...args: any[]) => TObject) & { typeId: URL }, `${string}${Rfc6570Expression<TParam>}${string}`, CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ] ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > { Loading @@ -1259,22 +1261,24 @@ export class FederationBuilderImpl<TContextData> ...args, ); } #setCustomCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, collectionType: "collection" | "orderedCollection", itemType: ConstructorWithTypeId<TObject>, path: ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any itemType: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > { Loading Loading @@ -1302,7 +1306,7 @@ export class FederationBuilderImpl<TContextData> const callbacks: CustomCollectionCallbacks< TObject, TParams, TParam, RequestContext<TContextData>, TContextData > = { dispatcher }; Loading @@ -1312,13 +1316,13 @@ export class FederationBuilderImpl<TContextData> this.collectionTypeIds[name] = itemType; const setters: CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > = { setCounter( counter: CustomCollectionCounter< TParams, TParam, TContextData >, ) { Loading @@ -1327,7 +1331,7 @@ export class FederationBuilderImpl<TContextData> }, setFirstCursor( cursor: CustomCollectionCursor< TParams, TParam, RequestContext<TContextData>, TContextData >, Loading @@ -1337,7 +1341,7 @@ export class FederationBuilderImpl<TContextData> }, setLastCursor( cursor: CustomCollectionCursor< TParams, TParam, RequestContext<TContextData>, TContextData >, Loading @@ -1348,7 +1352,7 @@ export class FederationBuilderImpl<TContextData> authorize( predicate: ObjectAuthorizePredicate< TContextData, keyof TParams & string keyof TParam & string >, ) { callbacks.authorizePredicate = predicate; Loading packages/fedify/src/federation/callback.ts +6 −6 Original line number Diff line number Diff line Loading @@ -304,12 +304,12 @@ export type ObjectAuthorizePredicate<TContextData, TParam extends string> = ( */ export type CustomCollectionDispatcher< TItem, TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > = ( context: TContext, values: TParams, values: Record<TParam, string>, cursor: string | null, ) => PageItems<TItem> | null | Promise<PageItems<TItem> | null>; Loading @@ -323,11 +323,11 @@ export type CustomCollectionDispatcher< * @since 1.8.0 */ export type CustomCollectionCounter< TParams extends Record<string, string>, TParam extends string, TContextData, > = ( context: RequestContext<TContextData>, values: TParams, values: Record<TParam, string>, ) => number | bigint | null | Promise<number | bigint | null>; /** Loading @@ -343,10 +343,10 @@ export type CustomCollectionCounter< * @since 1.8.0 */ export type CustomCollectionCursor< TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > = ( context: TContext, values: TParams, values: Record<TParam, string>, ) => string | null | Promise<string | null>; packages/fedify/src/federation/federation.ts +23 −101 Original line number Diff line number Diff line Loading @@ -457,7 +457,7 @@ export interface Federatable<TContextData> { inboxPath: `${string}{identifier}${string}` | `${string}{handle}${string}`, sharedInboxPath?: string, ): InboxListenerSetters<TContextData>; /** /** ß * Registers a collection of objects dispatcher. * * @template TContextData The context data to pass to the {@link Context}. Loading @@ -471,21 +471,19 @@ export interface Federatable<TContextData> { * The path must have one or more variables. * @param dispatcher A collection dispatcher callback to register. */ setCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, >( setCollectionDispatcher<TObject extends Object, TParam extends string>( name: string | symbol, itemType: ConstructorWithTypeId<TObject>, path: ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any itemType: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData >; Loading @@ -506,19 +504,20 @@ export interface Federatable<TContextData> { */ setOrderedCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, itemType: ConstructorWithTypeId<TObject>, path: ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any itemType: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData >; Loading Loading @@ -1035,14 +1034,14 @@ export interface FederationFetchOptions<TContextData> { /** * Additional settings for a custom collection dispatcher. * * @template TParams The type of the parameters in the URL path. * @template TParam The type of the parameters in the URL path. * @template TContext The type of the context. {@link Context} or * {@link RequestContext}. * @template TContextData The context data to pass to the {@link Context}. * @template TFilter The type of filter for the collection. */ export interface CustomCollectionCallbackSetters< TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > { Loading @@ -1053,11 +1052,11 @@ export interface CustomCollectionCallbackSetters< */ setCounter( counter: CustomCollectionCounter< TParams, TParam, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1069,12 +1068,12 @@ export interface CustomCollectionCallbackSetters< */ setFirstCursor( cursor: CustomCollectionCursor< TParams, TParam, TContext, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1086,12 +1085,12 @@ export interface CustomCollectionCallbackSetters< */ setLastCursor( cursor: CustomCollectionCursor< TParams, TParam, TContext, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1105,7 +1104,7 @@ export interface CustomCollectionCallbackSetters< authorize( predicate: ObjectAuthorizePredicate<TContextData, string>, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1120,47 +1119,6 @@ export interface CustomCollectionCallbackSetters< export type ConstructorWithTypeId<TObject extends Object> = // deno-lint-ignore no-explicit-any (new (...args: any[]) => TObject) & { typeId: URL }; /** * Represents a path from the key of parameter objects. * @param Params - A record of parameters where keys are parameter names and * values are their string representations. * @returns A string representing the path with all parameters. * @example * ```ts * type UserPostPath = ParamsKeyPath<{ userId: string; postId: string }>; * let userPostPath: UserPostPath; * // userPostPath = "/posts/{postId}"; // invalid - does not contain `{userId}` * // userPostPath = "/users/{userId}"; // invalid - does not contain `{postId}` * userPostPath = "/users/{userId}/posts/{postId}"; // valid * userPostPath = "/posts/{postId}/users/{userId}"; // valid * ``` */ export type ParamsKeyPath<Params extends Record<string, string>> = & ParamPath<Extract<keyof Params, string>> & string; /** * Represents a path with multiple parameters. * All permutations of the parameters are included in the union type. * The path must have all parameters in the form of `{paramName}`. * @param Params - A union of parameter names. * @returns A string representing the path with all parameters. * @example * ```ts * type UserPostPath = ParamsPath<"userId" | "postId">; * // = `${string}{userId}${string}` & `${string}{postId}${string}` * // = * // | `${string}{userId}${string}{postId}${string}` * // | `${string}{postId}${string}{userId}${string}` * let userPostPath: UserPostPath; * userPostPath = "/users/posts"; // ❌ invalid * userPostPath = "/users/{userId}"; // ❌ invalid * userPostPath = "/posts/{postId}"; // ❌ invalid * userPostPath = "/users/{userId}/posts/{postId}"; // ✅ valid * userPostPath = "/posts/{postId}/users/{userId}"; // ✅ valid */ type ParamsPath<Params extends string> = UnionToIntersection<ParamPath<Params>>; /** * Defines a union of all valid RFC 6570 URI Template expressions for a given * parameter name. Loading Loading @@ -1189,7 +1147,7 @@ type ParamsPath<Params extends string> = UnionToIntersection<ParamPath<Params>>; * ``` * @see {@link https://tools.ietf.org/html/rfc6570} for the full specification. */ type Rfc6570Expression<Param extends string> = export type Rfc6570Expression<Param extends string> = | `{${Param}}` | `{+${Param}}` | `{#${Param}}` Loading @@ -1198,39 +1156,3 @@ type Rfc6570Expression<Param extends string> = | `{;${Param}}` | `{?${Param}}` | `{&${Param}}`; /** * Represents a path with a single parameter. * The path must have at least one of the parameters in the form of `{paramName}`. * @param Param - The name of the parameter. * @returns A string representing the path with the parameter. * @example * ```ts * type UserPostPath = ParamPath<"userId" | "postId">; * // = `${string}{userId}${string}` | `${string}{postId}${string}` * let userPostPath: UserPostPath; * userPostPath = "/users/posts"; // ❌ invalid * userPostPath = "/users/{userId}"; // ✅ valid * userPostPath = "/posts/{postId}"; // ✅ valid * userPostPath = "/users/{userId}/posts/{postId}"; // ✅ valid * userPostPath = "/posts/{postId}/users/{userId}"; // ✅ valid */ type ParamPath<Param extends string> = `${string}${Rfc6570Expression< Param >}${string}`; /** * Converts union types to intersection types. * * @template U - The union type to convert. * @returns The intersection type of the union. * @example * ```ts * type A = { a: string }; * type B = { b: number }; * type AorB = A | B; * type AandB = UnionToIntersection<AorB>; * // AandB = { a: string; b: number } */ type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never; packages/fedify/src/federation/handler.test.ts +5 −5 Original line number Diff line number Diff line Loading @@ -1543,7 +1543,7 @@ test("handleCustomCollection()", async () => { // Mock dispatcher similar to collection dispatcher pattern const dispatcher: CustomCollectionDispatcher< Create, Record<string, string>, string, RequestContext<void>, void > = ( Loading @@ -1568,13 +1568,13 @@ test("handleCustomCollection()", async () => { return { items }; }; const counter: CustomCollectionCounter<Record<string, string>, void> = ( const counter: CustomCollectionCounter<string, void> = ( _ctx: RequestContext<void>, values: Record<string, string>, ) => values.handle === "someone" ? 3 : null; const firstCursor: CustomCollectionCursor< Record<string, string>, string, RequestContext<void>, void > = ( Loading @@ -1583,7 +1583,7 @@ test("handleCustomCollection()", async () => { ) => values.handle === "someone" ? "0" : null; const lastCursor: CustomCollectionCursor< Record<string, string>, string, RequestContext<void>, void > = ( Loading @@ -1593,7 +1593,7 @@ test("handleCustomCollection()", async () => { const callbacks: CustomCollectionCallbacks< Create, Record<string, string>, string, RequestContext<void>, void > = { Loading packages/fedify/src/federation/handler.ts +23 −23 Original line number Diff line number Diff line Loading @@ -862,14 +862,14 @@ async function handleInboxInternal<TContextData>( /** * Callbacks for handling a custom collection. * @template TItem The type of items in the collection. * @template TParams The parameter names of the requested URL. * @template TParam The parameter names of the requested URL. * @template TContext The type of the context. {@link Context} or {@link RequestContext}. * @template TContextData The context data to pass to the `TContext`. * @since 1.8.0 */ export interface CustomCollectionCallbacks< TItem, TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > { Loading @@ -878,7 +878,7 @@ export interface CustomCollectionCallbacks< */ dispatcher: CustomCollectionDispatcher< TItem, TParams, TParam, TContext, TContextData >; Loading @@ -886,24 +886,24 @@ export interface CustomCollectionCallbacks< /** * A callback that counts the number of items in a custom collection. */ counter?: CustomCollectionCounter<TParams, TContextData>; counter?: CustomCollectionCounter<TParam, TContextData>; /** * A callback that returns the first cursor for a custom collection. */ firstCursor?: CustomCollectionCursor<TParams, TContext, TContextData>; firstCursor?: CustomCollectionCursor<TParam, TContext, TContextData>; /** * A callback that returns the last cursor for a custom collection. */ lastCursor?: CustomCollectionCursor<TParams, TContext, TContextData>; lastCursor?: CustomCollectionCursor<TParam, TContext, TContextData>; /** * A callback that determines if a request is authorized to access the custom collection. */ authorizePredicate?: ObjectAuthorizePredicate< TContextData, keyof TParams & string keyof TParam & string >; } Loading @@ -917,17 +917,17 @@ export interface CustomCollectionCallbacks< */ export interface CustomCollectionHandlerParameters< TItem, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, > extends ErrorHandlers { name: string; values: TParams; values: Record<TParam, string>; filterPredicate?: (item: TItem) => boolean; context: TContext; collectionCallbacks?: CustomCollectionCallbacks< TItem, TParams, TParam, TContext, TContextData >; Loading @@ -937,7 +937,7 @@ export interface CustomCollectionHandlerParameters< /** * Handles a custom collection request. * @template TItem The type of items in the collection. * @template TParams The parameter names of the requested URL. * @template TParam The parameter names of the requested URL. * @template TContext The type of the context, extending {@link RequestContext}. * @template TContextData The context data to pass to the `TContext`. * @param request The HTTP request. Loading @@ -947,21 +947,21 @@ export interface CustomCollectionHandlerParameters< */ export const handleCustomCollection: < TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( request: Request, handleParams: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, ) => Promise<Response> = exceptWrapper(_handleCustomCollection); async function _handleCustomCollection< TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( Loading @@ -975,7 +975,7 @@ async function _handleCustomCollection< filterPredicate, }: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, Loading Loading @@ -1011,21 +1011,21 @@ async function _handleCustomCollection< */ export const handleOrderedCollection: < TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( request: Request, handleParams: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, ) => Promise<Response> = exceptWrapper(_handleOrderedCollection); async function _handleOrderedCollection< TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( Loading @@ -1039,7 +1039,7 @@ async function _handleOrderedCollection< filterPredicate, }: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, Loading Loading @@ -1076,7 +1076,7 @@ async function _handleOrderedCollection< */ class CustomCollectionHandler< TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContextData, TContext extends RequestContext<TContextData>, TCollection extends Collection, Loading Loading @@ -1106,7 +1106,7 @@ class CustomCollectionHandler< */ #dispatcher: CustomCollectionDispatcher< TItem, TParams, TParam, TContext, TContextData >; Loading @@ -1125,11 +1125,11 @@ class CustomCollectionHandler< */ constructor( private readonly name: string, private readonly values: TParams, private readonly values: Record<TParam, string>, private readonly context: TContext, private readonly callbacks: CustomCollectionCallbacks< TItem, TParams, TParam, TContext, TContextData >, Loading Loading
packages/fedify/src/federation/builder.ts +27 −23 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ import type { FederationOptions, InboxListenerSetters, ObjectCallbackSetters, ParamsKeyPath, Rfc6570Expression, } from "./federation.ts"; import type { CollectionCallbacks, Loading Loading @@ -110,7 +110,7 @@ export class FederationBuilderImpl<TContextData> string | symbol, CustomCollectionCallbacks< Object, Record<string, string>, string, RequestContext<TContextData>, TContextData > Loading Loading @@ -1208,21 +1208,22 @@ export class FederationBuilderImpl<TContextData> setCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, ...args: [ ConstructorWithTypeId<TObject>, ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any (new (...args: any[]) => TObject) & { typeId: URL }, `${string}${Rfc6570Expression<TParam>}${string}`, CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ] ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > { Loading @@ -1235,21 +1236,22 @@ export class FederationBuilderImpl<TContextData> setOrderedCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, ...args: [ ConstructorWithTypeId<TObject>, ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any (new (...args: any[]) => TObject) & { typeId: URL }, `${string}${Rfc6570Expression<TParam>}${string}`, CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ] ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > { Loading @@ -1259,22 +1261,24 @@ export class FederationBuilderImpl<TContextData> ...args, ); } #setCustomCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, collectionType: "collection" | "orderedCollection", itemType: ConstructorWithTypeId<TObject>, path: ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any itemType: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > { Loading Loading @@ -1302,7 +1306,7 @@ export class FederationBuilderImpl<TContextData> const callbacks: CustomCollectionCallbacks< TObject, TParams, TParam, RequestContext<TContextData>, TContextData > = { dispatcher }; Loading @@ -1312,13 +1316,13 @@ export class FederationBuilderImpl<TContextData> this.collectionTypeIds[name] = itemType; const setters: CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData > = { setCounter( counter: CustomCollectionCounter< TParams, TParam, TContextData >, ) { Loading @@ -1327,7 +1331,7 @@ export class FederationBuilderImpl<TContextData> }, setFirstCursor( cursor: CustomCollectionCursor< TParams, TParam, RequestContext<TContextData>, TContextData >, Loading @@ -1337,7 +1341,7 @@ export class FederationBuilderImpl<TContextData> }, setLastCursor( cursor: CustomCollectionCursor< TParams, TParam, RequestContext<TContextData>, TContextData >, Loading @@ -1348,7 +1352,7 @@ export class FederationBuilderImpl<TContextData> authorize( predicate: ObjectAuthorizePredicate< TContextData, keyof TParams & string keyof TParam & string >, ) { callbacks.authorizePredicate = predicate; Loading
packages/fedify/src/federation/callback.ts +6 −6 Original line number Diff line number Diff line Loading @@ -304,12 +304,12 @@ export type ObjectAuthorizePredicate<TContextData, TParam extends string> = ( */ export type CustomCollectionDispatcher< TItem, TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > = ( context: TContext, values: TParams, values: Record<TParam, string>, cursor: string | null, ) => PageItems<TItem> | null | Promise<PageItems<TItem> | null>; Loading @@ -323,11 +323,11 @@ export type CustomCollectionDispatcher< * @since 1.8.0 */ export type CustomCollectionCounter< TParams extends Record<string, string>, TParam extends string, TContextData, > = ( context: RequestContext<TContextData>, values: TParams, values: Record<TParam, string>, ) => number | bigint | null | Promise<number | bigint | null>; /** Loading @@ -343,10 +343,10 @@ export type CustomCollectionCounter< * @since 1.8.0 */ export type CustomCollectionCursor< TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > = ( context: TContext, values: TParams, values: Record<TParam, string>, ) => string | null | Promise<string | null>;
packages/fedify/src/federation/federation.ts +23 −101 Original line number Diff line number Diff line Loading @@ -457,7 +457,7 @@ export interface Federatable<TContextData> { inboxPath: `${string}{identifier}${string}` | `${string}{handle}${string}`, sharedInboxPath?: string, ): InboxListenerSetters<TContextData>; /** /** ß * Registers a collection of objects dispatcher. * * @template TContextData The context data to pass to the {@link Context}. Loading @@ -471,21 +471,19 @@ export interface Federatable<TContextData> { * The path must have one or more variables. * @param dispatcher A collection dispatcher callback to register. */ setCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, >( setCollectionDispatcher<TObject extends Object, TParam extends string>( name: string | symbol, itemType: ConstructorWithTypeId<TObject>, path: ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any itemType: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData >; Loading @@ -506,19 +504,20 @@ export interface Federatable<TContextData> { */ setOrderedCollectionDispatcher< TObject extends Object, TParams extends Record<string, string>, TParam extends string, >( name: string | symbol, itemType: ConstructorWithTypeId<TObject>, path: ParamsKeyPath<TParams>, // deno-lint-ignore no-explicit-any itemType: (new (...args: any[]) => TObject) & { typeId: URL }, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: CustomCollectionDispatcher< TObject, TParams, TParam, RequestContext<TContextData>, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, RequestContext<TContextData>, TContextData >; Loading Loading @@ -1035,14 +1034,14 @@ export interface FederationFetchOptions<TContextData> { /** * Additional settings for a custom collection dispatcher. * * @template TParams The type of the parameters in the URL path. * @template TParam The type of the parameters in the URL path. * @template TContext The type of the context. {@link Context} or * {@link RequestContext}. * @template TContextData The context data to pass to the {@link Context}. * @template TFilter The type of filter for the collection. */ export interface CustomCollectionCallbackSetters< TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > { Loading @@ -1053,11 +1052,11 @@ export interface CustomCollectionCallbackSetters< */ setCounter( counter: CustomCollectionCounter< TParams, TParam, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1069,12 +1068,12 @@ export interface CustomCollectionCallbackSetters< */ setFirstCursor( cursor: CustomCollectionCursor< TParams, TParam, TContext, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1086,12 +1085,12 @@ export interface CustomCollectionCallbackSetters< */ setLastCursor( cursor: CustomCollectionCursor< TParams, TParam, TContext, TContextData >, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1105,7 +1104,7 @@ export interface CustomCollectionCallbackSetters< authorize( predicate: ObjectAuthorizePredicate<TContextData, string>, ): CustomCollectionCallbackSetters< TParams, TParam, TContext, TContextData >; Loading @@ -1120,47 +1119,6 @@ export interface CustomCollectionCallbackSetters< export type ConstructorWithTypeId<TObject extends Object> = // deno-lint-ignore no-explicit-any (new (...args: any[]) => TObject) & { typeId: URL }; /** * Represents a path from the key of parameter objects. * @param Params - A record of parameters where keys are parameter names and * values are their string representations. * @returns A string representing the path with all parameters. * @example * ```ts * type UserPostPath = ParamsKeyPath<{ userId: string; postId: string }>; * let userPostPath: UserPostPath; * // userPostPath = "/posts/{postId}"; // invalid - does not contain `{userId}` * // userPostPath = "/users/{userId}"; // invalid - does not contain `{postId}` * userPostPath = "/users/{userId}/posts/{postId}"; // valid * userPostPath = "/posts/{postId}/users/{userId}"; // valid * ``` */ export type ParamsKeyPath<Params extends Record<string, string>> = & ParamPath<Extract<keyof Params, string>> & string; /** * Represents a path with multiple parameters. * All permutations of the parameters are included in the union type. * The path must have all parameters in the form of `{paramName}`. * @param Params - A union of parameter names. * @returns A string representing the path with all parameters. * @example * ```ts * type UserPostPath = ParamsPath<"userId" | "postId">; * // = `${string}{userId}${string}` & `${string}{postId}${string}` * // = * // | `${string}{userId}${string}{postId}${string}` * // | `${string}{postId}${string}{userId}${string}` * let userPostPath: UserPostPath; * userPostPath = "/users/posts"; // ❌ invalid * userPostPath = "/users/{userId}"; // ❌ invalid * userPostPath = "/posts/{postId}"; // ❌ invalid * userPostPath = "/users/{userId}/posts/{postId}"; // ✅ valid * userPostPath = "/posts/{postId}/users/{userId}"; // ✅ valid */ type ParamsPath<Params extends string> = UnionToIntersection<ParamPath<Params>>; /** * Defines a union of all valid RFC 6570 URI Template expressions for a given * parameter name. Loading Loading @@ -1189,7 +1147,7 @@ type ParamsPath<Params extends string> = UnionToIntersection<ParamPath<Params>>; * ``` * @see {@link https://tools.ietf.org/html/rfc6570} for the full specification. */ type Rfc6570Expression<Param extends string> = export type Rfc6570Expression<Param extends string> = | `{${Param}}` | `{+${Param}}` | `{#${Param}}` Loading @@ -1198,39 +1156,3 @@ type Rfc6570Expression<Param extends string> = | `{;${Param}}` | `{?${Param}}` | `{&${Param}}`; /** * Represents a path with a single parameter. * The path must have at least one of the parameters in the form of `{paramName}`. * @param Param - The name of the parameter. * @returns A string representing the path with the parameter. * @example * ```ts * type UserPostPath = ParamPath<"userId" | "postId">; * // = `${string}{userId}${string}` | `${string}{postId}${string}` * let userPostPath: UserPostPath; * userPostPath = "/users/posts"; // ❌ invalid * userPostPath = "/users/{userId}"; // ✅ valid * userPostPath = "/posts/{postId}"; // ✅ valid * userPostPath = "/users/{userId}/posts/{postId}"; // ✅ valid * userPostPath = "/posts/{postId}/users/{userId}"; // ✅ valid */ type ParamPath<Param extends string> = `${string}${Rfc6570Expression< Param >}${string}`; /** * Converts union types to intersection types. * * @template U - The union type to convert. * @returns The intersection type of the union. * @example * ```ts * type A = { a: string }; * type B = { b: number }; * type AorB = A | B; * type AandB = UnionToIntersection<AorB>; * // AandB = { a: string; b: number } */ type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never;
packages/fedify/src/federation/handler.test.ts +5 −5 Original line number Diff line number Diff line Loading @@ -1543,7 +1543,7 @@ test("handleCustomCollection()", async () => { // Mock dispatcher similar to collection dispatcher pattern const dispatcher: CustomCollectionDispatcher< Create, Record<string, string>, string, RequestContext<void>, void > = ( Loading @@ -1568,13 +1568,13 @@ test("handleCustomCollection()", async () => { return { items }; }; const counter: CustomCollectionCounter<Record<string, string>, void> = ( const counter: CustomCollectionCounter<string, void> = ( _ctx: RequestContext<void>, values: Record<string, string>, ) => values.handle === "someone" ? 3 : null; const firstCursor: CustomCollectionCursor< Record<string, string>, string, RequestContext<void>, void > = ( Loading @@ -1583,7 +1583,7 @@ test("handleCustomCollection()", async () => { ) => values.handle === "someone" ? "0" : null; const lastCursor: CustomCollectionCursor< Record<string, string>, string, RequestContext<void>, void > = ( Loading @@ -1593,7 +1593,7 @@ test("handleCustomCollection()", async () => { const callbacks: CustomCollectionCallbacks< Create, Record<string, string>, string, RequestContext<void>, void > = { Loading
packages/fedify/src/federation/handler.ts +23 −23 Original line number Diff line number Diff line Loading @@ -862,14 +862,14 @@ async function handleInboxInternal<TContextData>( /** * Callbacks for handling a custom collection. * @template TItem The type of items in the collection. * @template TParams The parameter names of the requested URL. * @template TParam The parameter names of the requested URL. * @template TContext The type of the context. {@link Context} or {@link RequestContext}. * @template TContextData The context data to pass to the `TContext`. * @since 1.8.0 */ export interface CustomCollectionCallbacks< TItem, TParams extends Record<string, string>, TParam extends string, TContext extends Context<TContextData>, TContextData, > { Loading @@ -878,7 +878,7 @@ export interface CustomCollectionCallbacks< */ dispatcher: CustomCollectionDispatcher< TItem, TParams, TParam, TContext, TContextData >; Loading @@ -886,24 +886,24 @@ export interface CustomCollectionCallbacks< /** * A callback that counts the number of items in a custom collection. */ counter?: CustomCollectionCounter<TParams, TContextData>; counter?: CustomCollectionCounter<TParam, TContextData>; /** * A callback that returns the first cursor for a custom collection. */ firstCursor?: CustomCollectionCursor<TParams, TContext, TContextData>; firstCursor?: CustomCollectionCursor<TParam, TContext, TContextData>; /** * A callback that returns the last cursor for a custom collection. */ lastCursor?: CustomCollectionCursor<TParams, TContext, TContextData>; lastCursor?: CustomCollectionCursor<TParam, TContext, TContextData>; /** * A callback that determines if a request is authorized to access the custom collection. */ authorizePredicate?: ObjectAuthorizePredicate< TContextData, keyof TParams & string keyof TParam & string >; } Loading @@ -917,17 +917,17 @@ export interface CustomCollectionCallbacks< */ export interface CustomCollectionHandlerParameters< TItem, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, > extends ErrorHandlers { name: string; values: TParams; values: Record<TParam, string>; filterPredicate?: (item: TItem) => boolean; context: TContext; collectionCallbacks?: CustomCollectionCallbacks< TItem, TParams, TParam, TContext, TContextData >; Loading @@ -937,7 +937,7 @@ export interface CustomCollectionHandlerParameters< /** * Handles a custom collection request. * @template TItem The type of items in the collection. * @template TParams The parameter names of the requested URL. * @template TParam The parameter names of the requested URL. * @template TContext The type of the context, extending {@link RequestContext}. * @template TContextData The context data to pass to the `TContext`. * @param request The HTTP request. Loading @@ -947,21 +947,21 @@ export interface CustomCollectionHandlerParameters< */ export const handleCustomCollection: < TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( request: Request, handleParams: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, ) => Promise<Response> = exceptWrapper(_handleCustomCollection); async function _handleCustomCollection< TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( Loading @@ -975,7 +975,7 @@ async function _handleCustomCollection< filterPredicate, }: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, Loading Loading @@ -1011,21 +1011,21 @@ async function _handleCustomCollection< */ export const handleOrderedCollection: < TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( request: Request, handleParams: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, ) => Promise<Response> = exceptWrapper(_handleOrderedCollection); async function _handleOrderedCollection< TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContext extends RequestContext<TContextData>, TContextData, >( Loading @@ -1039,7 +1039,7 @@ async function _handleOrderedCollection< filterPredicate, }: CustomCollectionHandlerParameters< TItem, TParams, TParam, TContext, TContextData >, Loading Loading @@ -1076,7 +1076,7 @@ async function _handleOrderedCollection< */ class CustomCollectionHandler< TItem extends URL | Object | Link | Recipient, TParams extends Record<string, string>, TParam extends string, TContextData, TContext extends RequestContext<TContextData>, TCollection extends Collection, Loading Loading @@ -1106,7 +1106,7 @@ class CustomCollectionHandler< */ #dispatcher: CustomCollectionDispatcher< TItem, TParams, TParam, TContext, TContextData >; Loading @@ -1125,11 +1125,11 @@ class CustomCollectionHandler< */ constructor( private readonly name: string, private readonly values: TParams, private readonly values: Record<TParam, string>, private readonly context: TContext, private readonly callbacks: CustomCollectionCallbacks< TItem, TParams, TParam, TContext, TContextData >, Loading