UNPKG

@fedify/fedify

Version:

An ActivityPub server framework

274 lines (273 loc) • 9.2 kB
import "@js-temporal/polyfill"; import "urlpattern-polyfill"; globalThis.addEventListener = () => {}; import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs"; import "../std__assert-BBjXFNOb.mjs"; import { r as assertFalse } from "../assert_rejects-DN60FHPX.mjs"; import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs"; import { t as assert } from "../assert-OguE97r2.mjs"; import { getLogger } from "@logtape/logtape"; import { Router, RouterError, assertPath, isPath } from "@fedify/uri-template"; import { test } from "@fedify/fixture"; //#region src/federation/router.ts const logger = getLogger([ "fedify", "federation", "router", "deprecated" ]); let deprecationWarned = false; function warnDeprecated() { if (deprecationWarned) return; deprecationWarned = true; logger.warn("The `Router` and `RouterError` classes from `@fedify/fedify` are deprecated. Please use `Router` from `@fedify/uri-template` instead."); } /** * URL router and constructor based on URI Template * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). * * @deprecated Import `Router` from `@fedify/uri-template` instead. This class * remains only for compatibility with older Fedify code. The * `@fedify/uri-template` router is the replacement implementation * and should be used directly in new code. */ var Router$1 = class Router$1 { #router; /** * Create a new {@link Router}. * @param options Options for the router. * @deprecated Use `new Router(options)` from `@fedify/uri-template` * instead. */ constructor(options) { this.#router = convertRouterError(() => new Router(options)); } /** * Whether to ignore trailing slashes when matching paths. * @deprecated Use `Router` from `@fedify/uri-template` instead. This * accessor forwards to the underlying `@fedify/uri-template` * router so that post-construction mutation keeps working as * in older Fedify code. */ get trailingSlashInsensitive() { return this.#router.trailingSlashInsensitive; } set trailingSlashInsensitive(value) { this.#router.trailingSlashInsensitive = value; } /** * Clones this router. * @deprecated Use `Router` from `@fedify/uri-template` instead. */ clone() { return convertRouterError(() => { const clone = new Router$1(); clone.#router = this.#router.clone(); return clone; }); } /** * Checks if a path name exists in the router. * @param name The name of the path. * @returns `true` if the path name exists, otherwise `false`. * @deprecated Use `Router` from `@fedify/uri-template` instead. */ has(name) { return convertRouterError(() => this.#router.has(name)); } /** * Adds a new path rule to the router. * @param template The path pattern. * @param name The name of the path. * @returns The names of the variables in the path pattern. * @deprecated Use `Router` from `@fedify/uri-template` instead. In this * compatibility class, `add()` both registers the route and * returns the variables in the path pattern. In * `@fedify/uri-template`, these two responsibilities are split: * `router.add(template, name)` registers the route and returns * `void`, while the pure static method * `Router.variables(template)` returns the variable names. To * migrate, call `Router.variables(template)` when variables are * needed, then call `router.add(template, name)` to register the * route. */ add(template, name) { return convertRouterError(() => { assertPath(template); this.#router.add(template, name); return Router.variables(template); }); } /** * Resolves a path name and values from a URL, if any match. * @param url The URL to resolve. * @returns The name of the path and its values, if any match. Otherwise, * `null`. * @deprecated Use `Router` from `@fedify/uri-template` instead. Unlike the * stricter `@fedify/uri-template` router, this compatibility * method keeps the old Fedify 2.x contract of returning `null` * (rather than throwing) for inputs that are not router paths. */ route(url) { return convertRouterError(() => { if (!isPath(url)) return null; return this.#router.route(url); }); } /** * Constructs a URL/path from a path name and values. * @param name The name of the path. * @param values The values to expand the path with. * @returns The URL/path, if the name exists. Otherwise, `null`. * @deprecated Use `Router` from `@fedify/uri-template` instead. */ build(name, values) { return convertRouterError(() => this.#router.build(name, values)); } }; /** * An error thrown by the {@link Router}. * @deprecated Import `RouterError` from `@fedify/uri-template` instead. */ var RouterError$1 = class extends RouterError { /** * Treats every `RouterError` from `@fedify/uri-template` as an instance of * this deprecated class. * * @deprecated Import `RouterError` from `@fedify/uri-template` instead. */ static [Symbol.hasInstance](instance) { return instance instanceof RouterError; } /** * Create a new {@link RouterError}. * @param message The error message. * @deprecated Import `RouterError` from `@fedify/uri-template` instead. */ constructor(message) { super(message); warnDeprecated(); } }; function convertRouterError(func) { try { warnDeprecated(); return func(); } catch (error) { if (error instanceof RouterError) throw new RouterError$1(error.message); throw error; } } //#endregion //#region src/federation/router.test.ts function setUp(options = {}) { const router = new Router$1(options); router.add("/users/{name}", "user"); router.add("/users/{name}/posts/{postId}" + (options.trailingSlashInsensitive ? "/" : ""), "post"); return router; } test("Router.clone()", () => { const original = setUp(); const clone = original.clone(); clone.add("/users/{name}/friends", "friends"); assert(clone.has("friends")); assertEquals(clone.route("/users/alice/friends"), { name: "friends", template: "/users/{name}/friends", values: { name: "alice" } }); assertFalse(original.has("friends")); assertEquals(original.route("/users/alice/friends"), null); }); test("Router.add()", () => { const router = new Router$1(); assertEquals(router.add("/users", "users"), /* @__PURE__ */ new Set()); assertEquals(router.add("/users/{name}", "user"), new Set(["name"])); assertEquals(router.add("/users/{name}/posts/{postId}", "post"), new Set(["name", "postId"])); assertThrows(() => router.add("foo", "name"), RouterError$1); }); test("Router.route()", () => { let router = setUp(); assertEquals(router.route("/users/alice"), { name: "user", template: "/users/{name}", values: { name: "alice" } }); assertEquals(router.route("/users/bob/"), null); assertEquals(router.route("/users/alice/posts/123"), { name: "post", template: "/users/{name}/posts/{postId}", values: { name: "alice", postId: "123" } }); assertEquals(router.route("/users/bob/posts/456/"), null); router = setUp({ trailingSlashInsensitive: true }); assertEquals(router.route("/users/alice"), { name: "user", template: "/users/{name}", values: { name: "alice" } }); assertEquals(router.route("/users/bob/"), { name: "user", template: "/users/{name}", values: { name: "bob" } }); assertEquals(router.route("/users/alice/posts/123"), { name: "post", template: "/users/{name}/posts/{postId}/", values: { name: "alice", postId: "123" } }); assertEquals(router.route("/users/bob/posts/456/"), { name: "post", template: "/users/{name}/posts/{postId}/", values: { name: "bob", postId: "456" } }); }); test("Router.trailingSlashInsensitive (post-construction mutation)", () => { const router = setUp(); assertFalse(router.trailingSlashInsensitive); assertEquals(router.route("/users/bob/"), null); router.trailingSlashInsensitive = true; assert(router.trailingSlashInsensitive); assertEquals(router.route("/users/bob/"), { name: "user", template: "/users/{name}", values: { name: "bob" } }); router.trailingSlashInsensitive = false; assertFalse(router.trailingSlashInsensitive); assertEquals(router.route("/users/bob/"), null); }); test("Router.build()", () => { const router = setUp(); assertEquals(router.build("user", { name: "alice" }), "/users/alice"); assertEquals(router.build("post", { name: "alice", postId: "123" }), "/users/alice/posts/123"); }); test("Router.route() returns null for non-path inputs", () => { const router = setUp(); assertEquals(router.route("https://example.com/users/alice"), null); assertEquals(router.route("users/alice"), null); assertEquals(router.route("not a path"), null); assertEquals(router.route("/unknown"), null); }); test("Compatibility between RouterErrors", () => { const newError = new RouterError("boom"); assert(newError instanceof RouterError); assert(newError instanceof RouterError$1); const previousError = new RouterError$1("boom"); assert(previousError instanceof RouterError$1); assert(previousError instanceof RouterError); }); //#endregion export {};