Scan app/authz/<name>.{ts,js} the same way app/schemas is scanned,
exposing Router.authz: ComponentRef[]. Also update the two other
literal Router construction sites (prod runtime, dev-server test
fixture) that now need the new required field.
scanDir gains an optional extraExtensions parameter (default []) so
the authz scan can accept .js files without widening the extension
allow-list used by route scanning (app/pages, app/api, app/realtime),
which would otherwise leak .js into generated route URLs via
fileToRoute.
45 lines
1.7 KiB
TypeScript
45 lines
1.7 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { buildRouter } from "../src/index.ts";
|
|
|
|
function appWithAuthz(files: Record<string, string>): string {
|
|
const root = mkdtempSync(join(tmpdir(), "wrnexus-authz-"));
|
|
const dir = join(root, "app", "authz");
|
|
mkdirSync(dir, { recursive: true });
|
|
mkdirSync(join(root, "app", "pages"), { recursive: true });
|
|
for (const [name, body] of Object.entries(files)) writeFileSync(join(dir, name), body, "utf8");
|
|
return join(root, "app");
|
|
}
|
|
|
|
describe("app/authz discovery", () => {
|
|
test("collects .ts and .js declarations by filename", () => {
|
|
const appDir = appWithAuthz({
|
|
"blog.ts": "export default {};",
|
|
"billing.js": "export default {};",
|
|
});
|
|
const router = buildRouter(appDir);
|
|
expect(router.authz.map((entry) => entry.name).sort()).toEqual(["billing", "blog"]);
|
|
});
|
|
|
|
test("ignores non-module files", () => {
|
|
const appDir = appWithAuthz({ "blog.ts": "export default {};", "notes.md": "# hi" });
|
|
expect(buildRouter(appDir).authz.map((entry) => entry.name)).toEqual(["blog"]);
|
|
});
|
|
|
|
test("skips unsafe names", () => {
|
|
const appDir = appWithAuthz({
|
|
"ok.ts": "export default {};",
|
|
"bad name!.ts": "export default {};",
|
|
});
|
|
expect(buildRouter(appDir).authz.map((entry) => entry.name)).toEqual(["ok"]);
|
|
});
|
|
|
|
test("an app with no authz directory yields an empty list", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "wrnexus-authz-none-"));
|
|
mkdirSync(join(root, "app", "pages"), { recursive: true });
|
|
expect(buildRouter(join(root, "app")).authz).toEqual([]);
|
|
});
|
|
});
|