Unverified Commit 27a86736 authored by An Nyeong's avatar An Nyeong Committed by GitHub
Browse files

Merge branch 'main' into feature/sqlite-kv

parents 9153dacd 6c3b3daa
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - run: deno task test --coverage=.cov --junit-path=.test-report.xml
      env:
        RUST_BACKTRACE: ${{ runner.debug }}
@@ -124,7 +124,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - uses: pnpm/action-setup@v4
      with:
        version: 10
@@ -181,7 +181,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - uses: pnpm/action-setup@v4
      with:
        version: 10
@@ -207,7 +207,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - uses: pnpm/action-setup@v4
      with:
        version: 10
@@ -230,7 +230,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - run: deno task hooks:pre-commit

  release-test:
@@ -248,7 +248,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - uses: pnpm/action-setup@v4
      with:
        version: 10
@@ -283,7 +283,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - uses: pnpm/action-setup@v4
      with:
        version: 10
@@ -332,7 +332,7 @@ jobs:
      working-directory: ${{ github.workspace }}/fedify/
    - run: |
        pnpm install
        pnpm pack --recursive
        pnpm pack --recursive --filter='!./examples/**'
        if [[ "$GITHUB_REF_TYPE" != tag ]]; then
          rm fedify-cli-*.tgz
        fi
@@ -426,6 +426,7 @@ jobs:
          | @fedify/nestjs   | ${{ steps.versioning.outputs.version }} |                             | [npm][npm:@fedify/nestjs]   |
          | @fedify/postgres | ${{ steps.versioning.outputs.version }} | [JSR][jsr:@fedify/postgres] | [npm][npm:@fedify/postgres] |
          | @fedify/redis    | ${{ steps.versioning.outputs.version }} | [JSR][jsr:@fedify/redis]    | [npm][npm:@fedify/redis]    |
          | @fedify/testing  | ${{ steps.versioning.outputs.version }} | [JSR][jsr:@fedify/testing]  | [npm][npm:@fedify/testing]  |

          [jsr:@fedify/fedify]: https://jsr.io/@fedify/fedify@${{ steps.versioning.outputs.version }}
          [npm:@fedify/fedify]: https://www.npmjs.com/package/@fedify/fedify/v/${{ steps.versioning.outputs.short_version }}
@@ -441,6 +442,8 @@ jobs:
          [npm:@fedify/postgres]: https://www.npmjs.com/package/@fedify/postgres/v/${{ steps.versioning.outputs.short_version }}
          [jsr:@fedify/redis]: https://jsr.io/@fedify/redis@${{ steps.versioning.outputs.version }}
          [npm:@fedify/redis]: https://www.npmjs.com/package/@fedify/redis/v/${{ steps.versioning.outputs.short_version }}
          [jsr:@fedify/testing]: https://jsr.io/@fedify/testing@${{ steps.versioning.outputs.version }}
          [npm:@fedify/testing]: https://www.npmjs.com/package/@fedify/testing/v/${{ steps.versioning.outputs.short_version }}
        pr-number: ${{ github.event.pull_request.number }}
        comment-tag: publish

@@ -461,7 +464,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - run: deno task codegen
      working-directory: ${{ github.workspace }}/fedify/
    - uses: denoland/deployctl@v1
@@ -492,7 +495,7 @@ jobs:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: denoland/setup-deno@v2
      with:
        deno-version: "2.4.1"  # FIXME: https://github.com/fedify-dev/fedify/issues/303
        deno-version: v2.x
    - uses: pnpm/action-setup@v4
      with:
        version: 10
+62 −19
Original line number Diff line number Diff line
@@ -63,15 +63,6 @@ the versioning.
 -  Added `LookupWebFingerOptions.maxRedirection` option.
    [[#248], [#281] by Lee ByeongJun]

 -  Optimized `doubleKnock()` function to avoid multiple request body clones
    during redirects.  The request body is now read once and reused throughout
    the entire operation, preventing potential `TypeError: unusable` errors
    and improving performance.  [[#300] by Fabien O'Carroll]

     -  Added `SignRequestOptions.body` option.
     -  Added `DoubleKnockOptions.body` option.
     -  Updated internal signing functions to accept pre-read body buffers.

 -  Added `fedify webfinger` command. This command allows users to look up
    WebFinger information for a given resource.
    [[#260], [#278] by ChanHaeng Lee]
@@ -82,14 +73,17 @@ the versioning.
        in the WebFinger request.
     -  The `--allow-private-address` or `-p` option allows looking up
        WebFinger information for private addresses (e.g., `localhost`).
     -  The `--max-redirection` option allows uses to specify the maximum
        number of redirects to follow when performing WebFinger lookups.
        [[#311], [#328] by KeunHyeong Park]

 -  Added `--dry-run` option to `fedify init` command.  This option allows users
    to preview what files and configurations would be created without actually
    creating them.  [[#263], [#298] by Lee ByeongJun]

  -  Fixed a bug where the `fedify node` command had failed to correctly
     render the favicon in terminal emulators that do not support 24-bit
     colors.  [[#168], [#282], [#304] by Hyeonseo Kim]
 -  Fixed a bug where the `fedify nodeinfo` command (was `fedify node`) had
    failed to correctly render the favicon in terminal emulators that do not
    support 24-bit colors.  [[#168], [#282], [#304] by Hyeonseo Kim]

 -  Supported NestJS integration with the `@fedify/nestjs` package.
    [[#269], [#309] by Jaeyeol Lee]
@@ -97,18 +91,43 @@ the versioning.
     -  Added `@fedify/nestjs` package.
     -  Added `FedifyModule` for integrating Fedify into NestJS applications.

  -  Supported `KvStore` using SQLite with the `@fedify/sqlite` package, compatible with Bun, Deno and Node.js. [[#274], [#318] By An Subin]
 -  Added `SqliteKvStore`, implementing `KvStore` using SQLite with the
    `@fedify/sqlite` package. Compatible with Bun, Deno, and Node.js.
    [[#274], [#318] by An Subin]

     -  Added `@fedify/sqlite` package.
     -  Added `SqliteKvStore`, SQLite implementation of KvStore.

     -  Added `SqliteKvStore`, a SQLite implementation of `KvStore`.

 -  Added `-o`/`--output` option to `fedify lookup` command. This option allows
    users to save retrieved lookup results to specified path.
    [[#261], [#321] by Jiwon Kwon]

 -  Added `fedify nodeinfo` command, and deprecated `fedify node` command in
    favor of `fedify nodeinfo`.  [[#267], [#331] by Hyeonseo Kim]

 -  Added custom collection dispatchers.  [[#310], [#332] by ChanHaeng Lee]

     -  Added `CustomCollectionDispatcher`, `CustomCollectionCounter`, and
        `CustomCollectionCursor` types for custom collection dispatching.
     -  Added `CustomCollectionCallbackSetters` type for setting custom
        collection callbacks.
     -  Added `CustomCollectionHandler` class and `handleCustomCollection()` and
        `handleOrderedCollection()` functions to process custom collections.
     -  Added `setCollectionDispatcher()` and `setOrderedCollectionDispatcher()`
        methods to the `Federatable` interface. Implemented in
        `FederationBuilderImpl` class.
     -  Added `getCollectionUri()` method to the `Context` interface.
     -  Added utility types `ConstructorWithTypeId` and `ParamsKeyPath` for
        custom collection dispatchers.

[#168]: https://github.com/fedify-dev/fedify/issues/168
[#197]: https://github.com/fedify-dev/fedify/issues/197
[#248]: https://github.com/fedify-dev/fedify/issues/248
[#260]: https://github.com/fedify-dev/fedify/issues/260
[#261]: https://github.com/fedify-dev/fedify/issues/261
[#262]: https://github.com/fedify-dev/fedify/issues/262
[#263]: https://github.com/fedify-dev/fedify/issues/263
[#267]: https://github.com/fedify-dev/fedify/issues/267
[#269]: https://github.com/fedify-dev/fedify/issues/269
[#278]: https://github.com/fedify-dev/fedify/pull/278
[#281]: https://github.com/fedify-dev/fedify/pull/281
@@ -116,11 +135,35 @@ the versioning.
[#283]: https://github.com/fedify-dev/fedify/pull/283
[#285]: https://github.com/fedify-dev/fedify/pull/285
[#298]: https://github.com/fedify-dev/fedify/pull/298
[#300]: https://github.com/fedify-dev/fedify/pull/300
[#304]: https://github.com/fedify-dev/fedify/issues/304
[#309]: https://github.com/fedify-dev/fedify/pull/309
[#274]: https://github.com/fedify-dev/fedify/issues/274
[#318]: https://github.com/fedify-dev/fedify/pull/318
[#310]: https://github.com/fedify-dev/fedify/issues/310
[#311]: https://github.com/fedify-dev/fedify/issues/311
[#321]: https://github.com/fedify-dev/fedify/pull/321
[#328]: https://github.com/fedify-dev/fedify/pull/328
[#331]: https://github.com/fedify-dev/fedify/pull/331
[#332]: https://github.com/fedify-dev/fedify/pull/332


Version 1.7.7
-------------

Released on July 28, 2025.

 -  Optimized `doubleKnock()` function to avoid multiple request body clones
    during redirects.  The request body is now read once and reused throughout
    the entire operation, preventing potential `TypeError: unusable` errors
    and improving performance.  [[#300], [#335] by Fabien O'Carroll]

     -  Added `SignRequestOptions.body` option.
     -  Added `DoubleKnockOptions.body` option.
     -  Updated internal signing functions to accept pre-read body buffers.

[#300]: https://github.com/fedify-dev/fedify/pull/300
[#335]: https://github.com/fedify-dev/fedify/pull/335



Version 1.7.6
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
    "@jimp/core": "npm:@jimp/core@^1.6.0",
    "@jimp/wasm-webp": "npm:@jimp/wasm-webp@^1.6.0",
    "@poppanator/http-constants": "npm:@poppanator/http-constants@^1.1.1",
    "@std/assert": "jsr:@std/assert@^1.0.13",
    "@std/dotenv": "jsr:@std/dotenv@^0.225.2",
    "@std/assert": "jsr:@std/assert@^1.0.0",
    "@std/semver": "jsr:@std/semver@^1.0.5",
+78 −31
Original line number Diff line number Diff line
@@ -150,37 +150,6 @@ Deno.test("init --dry-run shows command for framework initialization", async ()
  }
});

Deno.test("init without --dry-run creates actual files", async () => {
  const testDir = await Deno.makeTempDir();
  const projectDir = join(testDir, "test-actual-project");

  try {
    // Run without --dry-run
    const result = await runInit([
      projectDir,
      "--runtime",
      "deno",
    ]);

    // Should not show dry-run header
    assertEquals(result.output.includes("DRY RUN MODE"), false);

    // Verify files were actually created
    assertEquals(
      await exists(projectDir),
      true,
      "Project directory should be created",
    );
    assertEquals(await exists(join(projectDir, "federation.ts")), true);
    assertEquals(await exists(join(projectDir, "logging.ts")), true);
    assertEquals(await exists(join(projectDir, "main.ts")), true);
    assertEquals(await exists(join(projectDir, "deno.json")), true);
    assertEquals(await exists(join(projectDir, ".env")), true);
  } finally {
    await Deno.remove(testDir, { recursive: true });
  }
});

Deno.test("init --dry-run fails on non-empty directory", async () => {
  const testDir = await Deno.makeTempDir();

@@ -251,3 +220,81 @@ Deno.test("init --dry-run shows dev dependencies for Node.js", async () => {
    await Deno.remove(testDir, { recursive: true });
  }
});

Deno.test("init - check version for AMQP package", async () => {
  const amqpData = await Deno.readTextFile(
    join(import.meta.dirname!, "../amqp/deno.json"),
  );
  const testDir = await Deno.makeTempDir();
  const projectDir = join(testDir, "test-amqp-project");
  try {
    const result = await runInit([
      projectDir,
      "--dry-run",
      "--runtime",
      "deno",
      "--message-queue",
      "amqp",
    ]);

    assertStringIncludes(
      result.output,
      `@fedify/amqp@${JSON.parse(amqpData).version.trim()}`,
    );
    assertEquals(await exists(projectDir), false);
  } finally {
    await Deno.remove(testDir, { recursive: true });
  }
});

Deno.test("init - check version for Redis package", async () => {
  const redisData = await Deno.readTextFile(
    join(import.meta.dirname!, "../redis/deno.json"),
  );
  const testDir = await Deno.makeTempDir();
  const projectDir = join(testDir, "test-redis-project");
  try {
    const result = await runInit([
      projectDir,
      "--dry-run",
      "--runtime",
      "deno",
      "--kv-store",
      "redis",
    ]);

    assertStringIncludes(
      result.output,
      `@fedify/redis@${JSON.parse(redisData).version.trim()}`,
    );
    assertEquals(await exists(projectDir), false);
  } finally {
    await Deno.remove(testDir, { recursive: true });
  }
});

Deno.test("init - check version for Postgres package", async () => {
  const postgresData = await Deno.readTextFile(
    join(import.meta.dirname!, "../postgres/deno.json"),
  );
  const testDir = await Deno.makeTempDir();
  const projectDir = join(testDir, "test-postgres-project");
  try {
    const result = await runInit([
      projectDir,
      "--dry-run",
      "--runtime",
      "deno",
      "--kv-store",
      "postgres",
    ]);

    assertStringIncludes(
      result.output,
      `@fedify/postgres@${JSON.parse(postgresData).version.trim()}`,
    );
    assertEquals(await exists(projectDir), false);
  } finally {
    await Deno.remove(testDir, { recursive: true });
  }
});
+24 −26
Original line number Diff line number Diff line
@@ -5,9 +5,17 @@ import { getLogger } from "@logtape/logtape";
import { stringify } from "@std/dotenv/stringify";
import { exists } from "@std/fs";
import { basename, dirname, join, normalize } from "@std/path";
import { format, greaterThan, parse } from "@std/semver";
import metadata from "./deno.json" with { type: "json" };

const packagesMetaData: Record<`@fedify/${string}`, string> = {
  "@fedify/fedify": metadata.version,
  "@fedify/redis": metadata.version,
  "@fedify/postgres": metadata.version,
  "@fedify/amqp": metadata.version,
  "@fedify/express": metadata.version,
  "@fedify/h3": metadata.version,
};

const logger = getLogger(["fedify", "cli", "init"]);

type Runtime = "deno" | "bun" | "node";
@@ -306,7 +314,7 @@ Then, try look up an actor from your server:
    init: (projectName, runtime, pm) => ({
      dependencies: {
        express: "^4.19.2",
        "@fedify/express": "^0.2.1",
        "@fedify/express": getLatestVersion("@fedify/express"),
        ...(runtime === "node"
          ? {
            "@dotenvx/dotenvx": "^1.14.1",
@@ -392,7 +400,7 @@ Then, try look up an actor from your server:
        ".",
      ],
      dependencies: {
        "@fedify/h3": "^0.1.2",
        "@fedify/h3": getLatestVersion("@fedify/h3"),
      },
      federationFile: "server/federation.ts",
      loggingFile: "server/logging.ts",
@@ -449,7 +457,7 @@ const kvStores: Record<KvStore, KvStoreDescription> = {
  redis: {
    label: "Redis",
    dependencies: {
      "@fedify/redis": "^0.2.1",
      "@fedify/redis": getLatestVersion("@fedify/redis"),
      "npm:ioredis": "^5.4.1",
    },
    imports: { "@fedify/redis": ["RedisKvStore"], ioredis: ["Redis"] },
@@ -465,7 +473,7 @@ const kvStores: Record<KvStore, KvStoreDescription> = {
  postgres: {
    label: "PostgreSQL",
    dependencies: {
      "@fedify/postgres": "^0.2.0",
      "@fedify/postgres": getLatestVersion("@fedify/postgres"),
      "npm:postgres": "^3.4.5",
    },
    imports: { "@fedify/postgres": ["PostgresKvStore"], postgres: "postgres" },
@@ -504,7 +512,7 @@ const messageQueues: Record<MessageQueue, MessageQueueDescription> = {
  redis: {
    label: "Redis",
    dependencies: {
      "@fedify/redis": "^0.2.1",
      "@fedify/redis": getLatestVersion("@fedify/redis"),
      "npm:ioredis": "^5.4.1",
    },
    imports: { "@fedify/redis": ["RedisMessageQueue"], ioredis: ["Redis"] },
@@ -520,7 +528,7 @@ const messageQueues: Record<MessageQueue, MessageQueueDescription> = {
  postgres: {
    label: "PostgreSQL",
    dependencies: {
      "@fedify/postgres": "^0.2.0",
      "@fedify/postgres": getLatestVersion("@fedify/postgres"),
      "npm:postgres": "^3.4.5",
    },
    imports: {
@@ -539,7 +547,7 @@ const messageQueues: Record<MessageQueue, MessageQueueDescription> = {
  amqp: {
    label: "AMQP (e.g., RabbitMQ)",
    dependencies: {
      "@fedify/amqp": "^0.1.0",
      "@fedify/amqp": getLatestVersion("@fedify/amqp"),
      "npm:amqplib": "^0.10.4",
    },
    devDependencies: {
@@ -1069,7 +1077,7 @@ await configure({
      }
    }
    const dependencies: Record<string, string> = {
      "@fedify/fedify": `^${await getLatestFedifyVersion(metadata.version)}`,
      "@fedify/fedify": getLatestVersion("@fedify/fedify"),
      "@logtape/logtape": "^0.8.2",
      ...initializer.dependencies,
      ...kvStoreDesc?.dependencies,
@@ -1489,25 +1497,15 @@ async function addDependencies(
  }
}

async function getLatestFedifyVersion(version: string): Promise<string> {
  const response = await fetch("https://jsr.io/@fedify/fedify/meta.json", {
    headers: {
      Accept: "application/json",
    },
  });
  // deno-lint-ignore no-explicit-any
  const result = await response.json() as any;
  let maxVersion = parse("0.0.0");
  for (const v in result.versions) {
    if (v === version) return version;
    else if (result.versions[v].yanked) continue;
    const semVer = parse(v);
    if (semVer.prerelease != null && semVer.prerelease.length > 0) continue;
    if (greaterThan(semVer, maxVersion)) maxVersion = semVer;
function getLatestVersion(packageName: `@fedify/${string}`): string {
  const version = packagesMetaData[packageName];
  if (!version) {
    throw new Error(
      `Version for package "${packageName}" not found in local metadata.`,
    );
  }
  return format(maxVersion);
  return version;
}

async function rewriteJsonFile(
  path: string,
  // deno-lint-ignore no-explicit-any
Loading