feat(router): discover app/authz declarations
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.
This commit is contained in:
@@ -59,6 +59,8 @@ export interface Router {
|
||||
stores: ComponentRef[];
|
||||
/** Validation schemas (`app/schemas/<name>.ts`) shared by API + forms. */
|
||||
schemas: ComponentRef[];
|
||||
/** Authorization declarations (`app/authz/<name>.ts`) merged into the catalog. */
|
||||
authz: ComponentRef[];
|
||||
matchPage(pathname: string): RouteMatch | null;
|
||||
matchApi(pathname: string): RouteMatch | null;
|
||||
matchRealtime(pathname: string): RouteMatch | null;
|
||||
@@ -283,6 +285,19 @@ export function buildRouter(appDir: string, opts: RouterOptions = {}): Router {
|
||||
schemas.push({ name, file: f.file });
|
||||
}
|
||||
|
||||
// Authorization declarations: app/authz/<name>.{ts,js}, each default-exporting
|
||||
// a defineAuthz() module. Merged into the catalog at boot.
|
||||
const authz: ComponentRef[] = [];
|
||||
for (const f of scanDir(join(appDir, "authz"), [".js"])) {
|
||||
if (!/\.(ts|js)$/.test(f.file)) continue;
|
||||
const name = basename(f.file).replace(/\.(ts|js)$/, "");
|
||||
if (!isSafeIslandName(name)) {
|
||||
console.warn(`[wrnexus] skipping authz declaration with unsafe name: ${name}`);
|
||||
continue;
|
||||
}
|
||||
authz.push({ name, file: f.file });
|
||||
}
|
||||
|
||||
return {
|
||||
pages,
|
||||
api,
|
||||
@@ -292,6 +307,7 @@ export function buildRouter(appDir: string, opts: RouterOptions = {}): Router {
|
||||
layouts,
|
||||
stores,
|
||||
schemas,
|
||||
authz,
|
||||
matchPage: (p) => matchRoute(pages, p),
|
||||
matchApi: (p) => matchRoute(api, p),
|
||||
matchRealtime: (p) => matchRoute(realtime, p),
|
||||
|
||||
Reference in New Issue
Block a user