Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -304,11 +304,15 @@ shell = "nu -c"
run = '''
let pkgs = ($env.usage_packages | split row " " | where ($it | is-not-empty))
mise run prepare-each ...$pkgs
mise run check-each ...$pkgs
for pkg in $pkgs {
print $"Running tests for package: ($pkg)"
deno task --filter $"@fedify/($pkg)" test
if ($"packages/($pkg)/deno.json" | path exists) {
mise run check-each $pkg
print $"Running Deno tests for package: ($pkg)"
deno task --filter $"@fedify/($pkg)" test
}
Comment on lines +308 to +312

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "Root Deno workspace:"
jq '.workspace' deno.json

echo
echo "Package-local Deno configurations:"
fd --type f '^deno\.json$' packages | sort

echo
echo "Current test-each gate:"
sed -n '301,315p' mise.toml

Repository: fedify-dev/fedify

Length of output: 2803


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "Root Deno config file:"
if [ -f deno.json ]; then
  jq '{specifiers: .imports, tasks: (.tasks // {} | keys | sort), tools: .tools // {}, workspace: .workspace}' deno.json
fi

echo
echo "Package-local Deno config relevant fields:"
python3 - <<'PY'
import json, pathlib
root = json.load(open("deno.json"))
workspace = root.get("workspace") or []
for p in sorted(pathlib.Path("packages").glob("*/deno.json")):
    name = "packages/" + str(p.parent.relative_to("packages"))
    data = json.load(open(p))
    print(f"{name}: has_tasks={bool(data.get('tasks'))}, has_specifiers={bool(data.get('imports'))}, in_root_workspace={name in workspace}")
PY

echo
echo "Relevant mise.toml lines:"
sed -n '296,318p' mise.toml

Repository: fedify-dev/fedify

Length of output: 7414


Check root Deno workspace membership before running Deno tasks.

packages/<pkg>/deno.json exists for every package, so the current condition runs check-each and deno task --filter even for packages not listed under deno.json.workspace. Gate these commands on the package being present in the root deno.json workspace as well as having a package-local Deno config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mise.toml` around lines 308 - 312, Update the package loop condition around
the Deno commands to require both the package-local packages/($pkg)/deno.json
and membership in the root deno.json workspace; only then run mise run
check-each and deno task --filter. Keep packages lacking either configuration
out of this Deno task path.

print $"Running Node.js tests for package: ($pkg)"
pnpm --filter $"@fedify/($pkg)" test
print $"Running Bun tests for package: ($pkg)"
pnpm --filter $"@fedify/($pkg)" test:bun
Comment on lines +313 to 316

@2chanhaeng 2chanhaeng Aug 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add checking package.json for Node and Bun? For example, @fedify/fresh doesn't have package.json because Fresh is made for Deno and JSR.

}
'''
Expand Down
4 changes: 3 additions & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
"build:self": "tsdown",
"build": "pnpm --filter @fedify/next... run build:self",
"prepack": "pnpm build",
"prepublish": "pnpm build"
"prepublish": "pnpm build",
"test": "node --experimental-transform-types --test",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing TS files directly doesn't work well with Next.js, I think. How about testing built files only? Like node --test 'dist/'.

"test:bun": "bun test"
}
}
115 changes: 115 additions & 0 deletions packages/next/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {
createFederation,
InProcessMessageQueue,
MemoryKvStore,
} from "@fedify/fedify";
import { test } from "@fedify/fixture";
import { strict as assert } from "node:assert";
Comment thread
2chanhaeng marked this conversation as resolved.
import {
fedifyWith,
integrateFederation,
isFederationRequest,
isNodeInfoRequest,
} from "./index.ts";

test("Accept header detection", () => {
const request = new Request("https://example.com/", {
headers: {
Accept: "application/activity+json",
},
});

assert.strictEqual(isFederationRequest(request), true);
});

test("Content-Type header detection", () => {
const request = new Request("https://example.com/", {
method: "POST",
headers: {
"Content-Type": "application/activity+json",
},
});

assert.strictEqual(isFederationRequest(request), true);
});

test("NodeInfo route detection", () => {
const request1 = new Request("https://example.com/.well-known/nodeinfo", {});

const request2 = new Request(
"https://example.com/.well-known/x-nodeinfo2",
{},
);

assert.strictEqual(isNodeInfoRequest(request1), true);
assert.strictEqual(isNodeInfoRequest(request2), true);
});

test("Non-federation request delegation", async () => {
const federation = createFederation({
kv: new MemoryKvStore(),
queue: new InProcessMessageQueue(),
});
const customMiddleware = (request: Request) => {
if (request.url === "https://example.com/test") {
return new Response("Custom middleware response");
}
return new Response("Default response");
};
const middleware = fedifyWith(federation)(customMiddleware);

const request = new Request("https://example.com/", {
headers: {
Accept: "text/html",
},
});

const request2 = new Request("https://example.com/test", {
headers: {
Accept: "text/html",
},
});

assert.strictEqual(isFederationRequest(request), false);
assert.strictEqual(isFederationRequest(request2), false);

const response1 = await middleware(request);
const response2 = await middleware(request2);

assert.strictEqual(await response1.text(), "Default response");
assert.strictEqual(await response2.text(), "Custom middleware response");
});

test("Custom not-found/not acceptable handler", async () => {
const federation = createFederation({
kv: new MemoryKvStore(),
queue: new InProcessMessageQueue(),
});

// Set up a dispatcher that always returns null to simulate a not acceptable scenario
federation.setActorDispatcher("/users/{identifier}", () => null);

const handler = integrateFederation(federation, undefined, {
onNotFound: () => new Response("Custom not found", { status: 418 }),
onNotAcceptable: () =>
new Response("Custom not acceptable", { status: 418 }),
});

const response1 = await handler(
new Request("https://example.com/missing", {
headers: { Accept: "application/activity+json" },
}),
);

assert.strictEqual(response1.status, 418);
assert.strictEqual(await response1.text(), "Custom not found");

const response2 = await handler(
new Request("https://example.com/users/123", {
headers: { Accept: "text/html" },
}),
);

assert.strictEqual(response2.status, 418);
assert.strictEqual(await response2.text(), "Custom not acceptable");
});
Loading