Unverified Commit c40abb58 authored by Hong Minhee's avatar Hong Minhee
Browse files

Add uriGetter parameter to handleCollection()

The `handleCollection()` function now accepts a `uriGetter` parameter,<Plug>_
which is a function that retrieves the canonical URI for the collection.
This allows for setting the `id` property of
the `OrderedCollection`/`OrderedCollectionPage` objects that are returned by
the collection dispatchers.
parent 0840f80c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -85,6 +85,10 @@ To be released.
 -  The `lookupWebFinger()` and `getActorHandle()` functions no more throw
    an error when they fail to reach the WebFinger resource.

 -  Collection dispatchers now set the `id` property of
    the `OrderedCollection`/`OrderedCollectionPage` objects that they return
    to the their canonical URI.

 -  Now `fedify init` generates a default *tsconfig.json* file on Node.js and
    Bun, and fills the *deno.json* file with the default `compilerOptions` on
    Deno.
+1 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ see the [*Set Up Your Environment* section][1] in the Deno manual.
Please run the following commands before opening a pull request:

~~~~ bash
cd src/
deno fmt
deno task check
deno task test-all
+35 −0
Original line number Diff line number Diff line
@@ -610,6 +610,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      onNotFound,
      onNotAcceptable,
      onUnauthorized,
@@ -627,6 +630,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: { dispatcher },
      onNotFound,
      onNotAcceptable,
@@ -645,6 +651,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "no-one",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: { dispatcher },
      onNotFound,
      onNotAcceptable,
@@ -671,6 +680,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "no-one",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: { dispatcher },
      onNotFound,
      onNotAcceptable,
@@ -689,6 +701,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: { dispatcher },
      onNotFound,
      onNotAcceptable,
@@ -723,6 +738,7 @@ test("handleCollection()", async () => {
        toot: "http://joinmastodon.org/ns#",
      },
    ],
    id: "https://example.com/users/someone",
    type: "OrderedCollection",
    orderedItems: [
      {
@@ -752,6 +768,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: {
        dispatcher,
        authorizePredicate: (_ctx, _handle, key, keyOwner) =>
@@ -779,6 +798,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: {
        dispatcher,
        authorizePredicate: (_ctx, _handle, key, keyOwner) =>
@@ -805,6 +827,7 @@ test("handleCollection()", async () => {
        toot: "http://joinmastodon.org/ns#",
      },
    ],
    id: "https://example.com/users/someone",
    type: "OrderedCollection",
    orderedItems: [
      {
@@ -834,6 +857,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: {
        dispatcher,
        counter,
@@ -861,6 +887,7 @@ test("handleCollection()", async () => {
        toot: "http://joinmastodon.org/ns#",
      },
    ],
    id: "https://example.com/users/someone",
    type: "OrderedCollection",
    totalItems: 3,
    first: "https://example.com/?cursor=0",
@@ -886,6 +913,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: {
        dispatcher,
        counter,
@@ -913,6 +943,7 @@ test("handleCollection()", async () => {
        toot: "http://joinmastodon.org/ns#",
      },
    ],
    id: "https://example.com/users/someone?cursor=0",
    type: "OrderedCollectionPage",
    partOf: "https://example.com/",
    next: "https://example.com/?cursor=1",
@@ -942,6 +973,9 @@ test("handleCollection()", async () => {
      context,
      name: "collection",
      handle: "someone",
      uriGetter(handle) {
        return new URL(`https://example.com/users/${handle}`);
      },
      collectionCallbacks: {
        dispatcher,
        counter,
@@ -969,6 +1003,7 @@ test("handleCollection()", async () => {
        toot: "http://joinmastodon.org/ns#",
      },
    ],
    id: "https://example.com/users/someone?cursor=2",
    type: "OrderedCollectionPage",
    partOf: "https://example.com/",
    prev: "https://example.com/?cursor=1",
+8 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ export interface CollectionHandlerParameters<
> {
  name: string;
  handle: string;
  uriGetter: (handle: string) => URL;
  filter?: TFilter;
  filterPredicate?: (item: TItem) => boolean;
  context: TContext;
@@ -200,6 +201,7 @@ export async function handleCollection<
  {
    name,
    handle,
    uriGetter,
    filter,
    filterPredicate,
    context,
@@ -213,6 +215,7 @@ export async function handleCollection<
  const url = new URL(request.url);
  const cursor = url.searchParams.get("cursor");
  let collection: OrderedCollection | OrderedCollectionPage;
  const baseUri = uriGetter(handle);
  if (cursor == null) {
    const firstCursor = await collectionCallbacks.firstCursor?.(
      context,
@@ -229,6 +232,7 @@ export async function handleCollection<
      if (page == null) return await onNotFound(request);
      const { items } = page;
      collection = new OrderedCollection({
        id: baseUri,
        totalItems: totalItems == null ? null : Number(totalItems),
        items: filterCollectionItems(items, name, filterPredicate),
      });
@@ -245,12 +249,15 @@ export async function handleCollection<
        last.searchParams.set("cursor", lastCursor);
      }
      collection = new OrderedCollection({
        id: baseUri,
        totalItems: Number(totalItems),
        first,
        last,
      });
    }
  } else {
    const uri = new URL(baseUri);
    uri.searchParams.set("cursor", cursor);
    const page = await collectionCallbacks.dispatcher(
      context,
      handle,
@@ -272,6 +279,7 @@ export async function handleCollection<
    const partOf = new URL(context.url);
    partOf.searchParams.delete("cursor");
    collection = new OrderedCollectionPage({
      id: uri,
      prev,
      next,
      items: filterCollectionItems(items, name, filterPredicate),
+7 −0
Original line number Diff line number Diff line
@@ -2062,6 +2062,7 @@ class FederationImpl<TContextData> implements Federation<TContextData> {
        return await handleCollection(request, {
          name: "outbox",
          handle: route.values.handle,
          uriGetter: context.getOutboxUri.bind(context),
          context,
          collectionCallbacks: this.outboxCallbacks,
          onUnauthorized,
@@ -2073,6 +2074,7 @@ class FederationImpl<TContextData> implements Federation<TContextData> {
          return await handleCollection(request, {
            name: "inbox",
            handle: route.values.handle,
            uriGetter: context.getInboxUri.bind(context),
            context,
            collectionCallbacks: this.inboxCallbacks,
            onUnauthorized,
@@ -2115,6 +2117,7 @@ class FederationImpl<TContextData> implements Federation<TContextData> {
        return await handleCollection(request, {
          name: "following",
          handle: route.values.handle,
          uriGetter: context.getFollowingUri.bind(context),
          context,
          collectionCallbacks: this.followingCallbacks,
          onUnauthorized,
@@ -2130,6 +2133,7 @@ class FederationImpl<TContextData> implements Federation<TContextData> {
        return await handleCollection(request, {
          name: "followers",
          handle: route.values.handle,
          uriGetter: context.getFollowersUri.bind(context),
          context,
          filter: baseUrl != null ? new URL(baseUrl) : undefined,
          filterPredicate: baseUrl != null
@@ -2148,6 +2152,7 @@ class FederationImpl<TContextData> implements Federation<TContextData> {
        return await handleCollection(request, {
          name: "liked",
          handle: route.values.handle,
          uriGetter: context.getLikedUri.bind(context),
          context,
          collectionCallbacks: this.likedCallbacks,
          onUnauthorized,
@@ -2158,6 +2163,7 @@ class FederationImpl<TContextData> implements Federation<TContextData> {
        return await handleCollection(request, {
          name: "featured",
          handle: route.values.handle,
          uriGetter: context.getFeaturedUri.bind(context),
          context,
          collectionCallbacks: this.featuredCallbacks,
          onUnauthorized,
@@ -2168,6 +2174,7 @@ class FederationImpl<TContextData> implements Federation<TContextData> {
        return await handleCollection(request, {
          name: "featured tags",
          handle: route.values.handle,
          uriGetter: context.getFeaturedTagsUri.bind(context),
          context,
          collectionCallbacks: this.featuredTagsCallbacks,
          onUnauthorized,