diff --git a/src/router.test.ts b/src/router.test.ts index 5e9cb13..daa126b 100644 --- a/src/router.test.ts +++ b/src/router.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, assert } from "vitest"; import { createEndpoint, type Endpoint } from "./endpoint"; import { createRouter } from "./router"; import { z } from "zod"; @@ -397,3 +397,39 @@ describe("error handling", () => { expect(body.message).toBe("Resource not found"); }); }); + +describe("extend", () => { + it("should extend the router with new endpoints", async () => { + const initialEndpoint = createEndpoint("/initial", { method: "GET" }, async () => ({})); + const router = createRouter({ initialEndpoint }); + assert.ok(router.endpoints.initialEndpoint.path === "/initial"); + + const dynamicEndpoint = createEndpoint( + "/dynamic_added", + { + method: "POST", + }, + async (c) => { + return { message: "dynamically added", body: c.body }; + }, + ); + + const extendedRouter = router.extend({ dynamicEndpoint }); + assert.ok(extendedRouter.endpoints.initialEndpoint.path === "/initial"); + assert.ok(extendedRouter.endpoints.dynamicEndpoint.path === "/dynamic_added"); + + const dynamicRequest = new Request("http://localhost/dynamic_added", { + method: "POST", + body: JSON.stringify({ test: "data" }), + headers: { + "Content-Type": "application/json", + }, + }); + const dynamicResponse = await extendedRouter.handler(dynamicRequest); + expect(dynamicResponse.status).toBe(200); + const jsonResponse = await dynamicResponse.json(); + expect(jsonResponse.message).toBe("dynamically added"); + expect(jsonResponse.body).toEqual({ test: "data" }); + }); + +}); diff --git a/src/router.ts b/src/router.ts index 7c7f3cb..0b37d9a 100644 --- a/src/router.ts +++ b/src/router.ts @@ -100,11 +100,9 @@ export const createRouter = , Config extends const middlewareRouter = createRou3Router(); for (const endpoint of Object.values(endpoints)) { - if (!endpoint.options) { + if (!endpoint.options || endpoint.options?.metadata?.SERVER_ONLY) { continue; } - if (endpoint.options?.metadata?.SERVER_ONLY) continue; - const methods = Array.isArray(endpoint.options?.method) ? endpoint.options.method : [endpoint.options?.method]; @@ -240,6 +238,15 @@ export const createRouter = , Config extends return res; }, endpoints, + + /** + * Extend the router with new endpoints + * @param newEndpoints new endpoints to extend the router with + * @returns new router with additional endpoints + */ + extend: >(newEndpoints: NE) => { + return createRouter({ ...endpoints, ...newEndpoints } as E & NE, config); + }, }; };