Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
5cd8862
Initialize @fedify/uri-template package
2chanhaeng Apr 27, 2026
25644de
Update version of @fedify/uri-template
2chanhaeng Apr 28, 2026
3b29ce3
Add test for template
2chanhaeng Apr 28, 2026
76e7c75
Allow **/*.bench.ts files use `@fedfiy/fixture`
2chanhaeng May 1, 2026
c4c9090
Implement RFC 6570 URI template expansion
2chanhaeng May 1, 2026
01a2b4a
Add test suite for @fedify/uri-template Template
2chanhaeng May 1, 2026
8759b52
Report URI template expansion errors
2chanhaeng May 2, 2026
2372a59
Document URI template compatibility
2chanhaeng May 2, 2026
1491e21
Refine URI template expansion internals
2chanhaeng May 4, 2026
8d35a15
Add URI template matching
2chanhaeng May 4, 2026
4f66ded
Add test suite for URI template matching
2chanhaeng May 4, 2026
02406c7
Add RFC 6570 Router class
2chanhaeng May 6, 2026
3b46270
Add Router conformance tests
2chanhaeng May 6, 2026
fd37b88
Capture legacy Router failures
2chanhaeng May 6, 2026
f3f83cf
Reorganize uri-template into per-feature module layouts
2chanhaeng May 6, 2026
e923449
Rename "symmetric" to "round-trip" in user-facing prose
2chanhaeng May 6, 2026
a5045e0
Rename router memory pressure scenario factories
2chanhaeng May 6, 2026
64d18ce
Document operator behavior table and drop dead constant
2chanhaeng May 6, 2026
f04d756
Drop unused VariableSpec and align reporter docs with expansion
2chanhaeng May 6, 2026
a14d5bb
Document route-shape gaps in uri-template-router compatibility test
2chanhaeng May 6, 2026
14a4b29
Drop "using RegExp" qualifier from Template bench label
2chanhaeng May 6, 2026
64eb2dc
Add Router#register, batch trie insert, and constructor routes
2chanhaeng May 7, 2026
dd27de3
Move URI template old tests
2chanhaeng May 8, 2026
3fb2396
Group uri-template tests by suite via nested t.step
2chanhaeng May 8, 2026
bdf5f54
Export `isExpression` from @fedify/uri-template
2chanhaeng May 8, 2026
6a3576d
Migrate @fedify/fedify to @fedify/uri-template router
2chanhaeng May 8, 2026
319ead3
Note uri-template router migration in CHANGES.md
2chanhaeng May 8, 2026
97b15f7
Export isPath helper from @fedify/uri-template
2chanhaeng May 8, 2026
8a5d66b
Tighten match backtracking bounds in @fedify/uri-template
2chanhaeng May 8, 2026
ea23a6a
Replace match bench with backtracking-pressure cases
2chanhaeng May 8, 2026
10fc20b
Add PR link
2chanhaeng May 9, 2026
074a546
Export `assertPath` from @fedify/uri-template
2chanhaeng May 9, 2026
0e1bc07
Replace `Router` from @fedify/fedify with the wrapper of `Router` fro…
2chanhaeng May 9, 2026
8de1d9c
Apply review feedback from PR #758
2chanhaeng May 9, 2026
e49a92a
Fix `consumeUnnamed` over-pruning of valid match decompositions
2chanhaeng May 9, 2026
9b41938
Fix `defaultReporter`
2chanhaeng May 11, 2026
5f60402
Tighten identifier path validation in FederationBuilder
2chanhaeng May 11, 2026
1d8e02a
Accept the empty path so trailing-slash retry can match `/`
2chanhaeng May 11, 2026
99da76c
Polish naming and fixture comments in uri-template tests
2chanhaeng May 11, 2026
2195307
Centralize expression parse error reporting in the tokenizer
2chanhaeng May 11, 2026
880d1e5
Drop stale router trie entries on re-registration
2chanhaeng May 11, 2026
04be48b
Serialize Deno check tasks behind install in `mise test`
2chanhaeng May 11, 2026
c611249
Make @fedify/uri-template default reporter a no-op
2chanhaeng May 11, 2026
5e96c8c
Recover round-trip for associative keys with non-varname characters
2chanhaeng May 11, 2026
2c1d58a
Split identifier path validation into loose and strict asserts
2chanhaeng May 12, 2026
996a371
Exclude old/ compat tests from published @fedify/uri-template
2chanhaeng May 12, 2026
cc67dd8
Reuse PrioritizedRouteEntry as the Trie entry constraint
2chanhaeng May 12, 2026
679f2c9
Drop unused throw() helper from TemplateParseError
2chanhaeng May 12, 2026
1a1de0d
Note compat Router shim breaking changes in changelog
2chanhaeng May 12, 2026
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
23 changes: 23 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,22 @@ To be released.
deliberately exclude raw URLs, query strings, and identifier values to
keep cardinality bounded. [[#316], [#736], [#757]]

- Replaced Fedify's internal federation routing with
*@fedify/uri-template* for stricter RFC 6570 URI Template expansion and
matching. The deprecated `Router` export from *@fedify/fedify* remains
available for compatibility. [[#418], [#758] by ChanHaeng Lee]

- *Breaking change*: Tightened the deprecated `Router` shim from
*@fedify/fedify/federation*: `route()` now throws `RouterError` for
inputs that are not router paths (previously such inputs returned `null`
on non-match), and `trailingSlashInsensitive` is no longer mutable
post-construction (assignments after construction create an inert own
property; the flag must be passed to the constructor). Callers should
validate inputs and pass options at construction, or migrate to `Router`
from *@fedify/uri-template*. [[#418], [#758] by ChanHaeng Lee]

[#316]: https://github.com/fedify-dev/fedify/issues/316
[#418]: https://github.com/fedify-dev/fedify/issues/418
[#619]: https://github.com/fedify-dev/fedify/issues/619
[#735]: https://github.com/fedify-dev/fedify/issues/735
[#736]: https://github.com/fedify-dev/fedify/issues/736
Expand All @@ -60,6 +75,7 @@ To be released.
[#753]: https://github.com/fedify-dev/fedify/pull/753
[#755]: https://github.com/fedify-dev/fedify/pull/755
[#757]: https://github.com/fedify-dev/fedify/pull/757
[#758]: https://github.com/fedify-dev/fedify/pull/758

### @fedify/fixture

Expand All @@ -72,6 +88,13 @@ To be released.
- Added a `meterProvider` option to `createFederation()` so mock contexts can
expose a test OpenTelemetry meter provider. [[#316], [#619], [#755]]

### @fedify/uri-template

- Added *@fedify/uri-template*, a dependency-free RFC 6570 URI Template
implementation for expansion, variable extraction, and round-trip route
matching. This package replaces Fedify's previous direct use of
*url-template* and *uri-template-router*. [[#418], [#758] by ChanHaeng Lee]

### @fedify/amqp

- Added `AmqpMessageQueue.getDepth()` for reporting queued, ready, and
Expand Down
5 changes: 5 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@
"urlpattern",
"uuidv7",
"valueparser",
"varspec",
"varname",
"varnames",
"varchar",
"varchars",
"Vinxi",
"vitepress",
"vtsls",
Expand Down
1 change: 1 addition & 0 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"./packages/sqlite",
"./packages/sveltekit",
"./packages/testing",
"./packages/uri-template",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"./packages/vocab",
"./packages/vocab-runtime",
"./packages/vocab-tools",
Expand Down
9 changes: 3 additions & 6 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,17 @@ depends = [

[tasks."check:fmt"]
description = "Check code formatting"
wait_for = ["install"]
run = "deno fmt --check"

[tasks."check:lint"]
description = "Check code linting"
wait_for = ["install"]
run = "deno lint"

[tasks."check:types"]
description = "Check TypeScript types"
wait_for = ["install"]
run = "deno check $(deno eval 'import m from \"./deno.json\" with { type: \"json\" }; for (let p of m.workspace) console.log(p)')"

[tasks."check:md"]
Expand All @@ -69,6 +72,7 @@ run = "hongdown --check"
[tasks.check-versions]
description = "Check that all package versions are consistent across the monorepo"
usage = 'flag "--fix" help="Automatically fix version mismatches"'
wait_for = ["install"]
run = '''
if [ "${usage_fix}" = "true" ]; then
deno run --allow-read --allow-write scripts/check_versions.ts --fix
Expand All @@ -79,6 +83,7 @@ fi

[tasks."check:fixture-usage"]
description = "Ensure @fedify/fixture is only used in **/*.test.ts files"
wait_for = ["install"]
run = "deno run --allow-read scripts/check_fixture_usage.ts"

[tasks."check:manifest:workspace-protocol"]
Expand Down
3 changes: 3 additions & 0 deletions packages/fedify/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ Here is the list of packages:
| [@fedify/sqlite](/packages/sqlite/) | [JSR][jsr:@fedify/sqlite] | [npm][npm:@fedify/sqlite] | SQLite driver |
| [@fedify/sveltekit](/packages/sveltekit/) | [JSR][jsr:@fedify/sveltekit] | [npm][npm:@fedify/sveltekit] | SvelteKit integration |
| [@fedify/testing](/packages/testing/) | [JSR][jsr:@fedify/testing] | [npm][npm:@fedify/testing] | Testing utilities |
| [@fedify/uri-template](/packages/uri-template/) | [JSR][jsr:@fedify/uri-template] | [npm][npm:@fedify/uri-template] | RFC 6570 URI Template library |
| [@fedify/vocab](/packages/vocab/) | [JSR][jsr:@fedify/vocab] | [npm][npm:@fedify/vocab] | Activity Vocabulary library |
| [@fedify/vocab-runtime](/packages/vocab-runtime/) | [JSR][jsr:@fedify/vocab-runtime] | [npm][npm:@fedify/vocab-runtime] | Runtime library for code-generated vocab |
| [@fedify/vocab-tools](/packages/vocab-tools/) | [JSR][jsr:@fedify/vocab-tools] | [npm][npm:@fedify/vocab-tools] | Code generation tools for Activity Vocab |
Expand Down Expand Up @@ -176,6 +177,8 @@ Here is the list of packages:
[npm:@fedify/sveltekit]: https://www.npmjs.com/package/@fedify/sveltekit
[jsr:@fedify/testing]: https://jsr.io/@fedify/testing
[npm:@fedify/testing]: https://www.npmjs.com/package/@fedify/testing
[jsr:@fedify/uri-template]: https://jsr.io/@fedify/uri-template
[npm:@fedify/uri-template]: https://www.npmjs.com/package/@fedify/uri-template
[jsr:@fedify/vocab]: https://jsr.io/@fedify/vocab
[npm:@fedify/vocab]: https://www.npmjs.com/package/@fedify/vocab
[jsr:@fedify/vocab-runtime]: https://jsr.io/@fedify/vocab-runtime
Expand Down
4 changes: 1 addition & 3 deletions packages/fedify/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
"json-canon": "npm:json-canon@^1.0.1",
"jsonld": "npm:jsonld@^9.0.0",
"pkijs": "npm:pkijs@^3.3.3",
"structured-field-values": "npm:structured-field-values@^2.0.4",
"uri-template-router": "npm:uri-template-router@^1.0.0",
"url-template": "npm:url-template@^3.1.1"
"structured-field-values": "npm:structured-field-values@^2.0.4"
},
"exclude": [
".test-report.xml",
Expand Down
3 changes: 1 addition & 2 deletions packages/fedify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
}
},
"dependencies": {
"@fedify/uri-template": "workspace:*",
"@fedify/vocab": "workspace:*",
"@fedify/vocab-runtime": "workspace:*",
"@fedify/webfinger": "workspace:*",
Expand All @@ -153,8 +154,6 @@
"json-canon": "^1.0.1",
"jsonld": "^9.0.0",
"structured-field-values": "^2.0.4",
"uri-template-router": "^1.0.0",
"url-template": "^3.1.1",
"urlpattern-polyfill": "catalog:"
},
"devDependencies": {
Expand Down
45 changes: 44 additions & 1 deletion packages/fedify/src/federation/builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test } from "@fedify/fixture";
import { RouterError } from "@fedify/uri-template";
import { Activity, Note, Person } from "@fedify/vocab";
import { assertEquals, assertExists, assertThrows } from "@std/assert";
import type { Protocol } from "../nodeinfo/types.ts";
Expand All @@ -13,7 +14,6 @@ import type {
} from "./callback.ts";
import { MemoryKvStore } from "./kv.ts";
import type { FederationImpl } from "./middleware.ts";
import { RouterError } from "./router.ts";

test("FederationBuilder", async (t) => {
await t.step(
Expand Down Expand Up @@ -211,6 +211,27 @@ test("FederationBuilder", async (t) => {
),
RouterError,
);
assertThrows(
() =>
builderAfterInvalid.setOutboxListeners(
"/users/{identifier:3}/outbox" as `${string}{identifier}${string}`,
),
RouterError,
);
assertThrows(
() =>
builderAfterInvalid.setOutboxListeners(
"/users/{identifier*}/outbox" as `${string}{identifier}${string}`,
),
RouterError,
);
assertThrows(
() =>
builderAfterInvalid.setOutboxListeners(
"/users/{identifier,identifier}/outbox" as `${string}{identifier}${string}`,
),
RouterError,
);
builderAfterInvalid.setOutboxListeners("/users/{identifier}/outbox");

const builder2 = createFederationBuilder<void>();
Expand All @@ -231,6 +252,18 @@ test("FederationBuilder", async (t) => {
RouterError,
);

const builder3a = createFederationBuilder<void>();
assertThrows(
() => builder3a.setOutboxListeners("/users{;identifier}/outbox"),
RouterError,
);

const builder3b = createFederationBuilder<void>();
assertThrows(
() => builder3b.setOutboxListeners("/users{.identifier}/outbox"),
RouterError,
);

const builder4 = createFederationBuilder<void>();
assertThrows(
() =>
Expand All @@ -240,6 +273,16 @@ test("FederationBuilder", async (t) => {
),
RouterError,
);

const builder5 = createFederationBuilder<void>();
assertThrows(
() =>
builder5.setOutboxDispatcher(
"/users/{identifier:3}/outbox" as `${string}{identifier}${string}`,
() => ({ items: [] }),
),
RouterError,
);
});

await t.step("should pass build options correctly", async () => {
Expand Down
Loading