docs: skip generated type files in the Task 10 authz scan

The brief asserted permissions.gen.ts would be discovered as an entry named
permissions.gen and filtered by a later task. It is not: isSafeIslandName
rejects the dot in the stripped basename, so it takes the warn-and-skip path
and would print a warning on every boot of any app that ran the codegen,
while Task 14's name-based filter for it was dead code.

The scan now skips *.gen.ts / *.gen.js quietly, before the name check. Also
records the extraExtensions argument the implementer added to scanDir, which
keeps .js out of the route-scanning allow-list where it would otherwise leak
into generated route URLs via fileToRoute.

Caught by the Task 10 implementer testing the claim rather than trusting it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 19:55:33 +05:30
co-authored by Claude Opus 5
parent e7743cdbb5
commit 41fb82b9e9
@@ -2563,8 +2563,14 @@ Add the scan immediately after the existing `schemas` loop:
// Authorization declarations: app/authz/<name>.{ts,js}, each default-exporting // Authorization declarations: app/authz/<name>.{ts,js}, each default-exporting
// a defineAuthz() module. Merged into the catalog at boot. // a defineAuthz() module. Merged into the catalog at boot.
const authz: ComponentRef[] = []; const authz: ComponentRef[] = [];
for (const f of scanDir(join(appDir, "authz"))) { // scanDir's extension allow-list is route-oriented; passing [".js"] here keeps
// .js out of app/pages scanning, where it would leak into route URLs.
for (const f of scanDir(join(appDir, "authz"), [".js"])) {
if (!/\.(ts|js)$/.test(f.file)) continue; if (!/\.(ts|js)$/.test(f.file)) continue;
// Generated type files (permissions.gen.ts) live here too. Skip them quietly:
// they export types only, and isSafeIslandName would otherwise reject the dot
// and warn on every boot.
if (/[.]gen[.](ts|js)$/.test(f.file)) continue;
const name = basename(f.file).replace(/\.(ts|js)$/, ""); const name = basename(f.file).replace(/\.(ts|js)$/, "");
if (!isSafeIslandName(name)) { if (!isSafeIslandName(name)) {
console.warn(`[wrnexus] skipping authz declaration with unsafe name: ${name}`); console.warn(`[wrnexus] skipping authz declaration with unsafe name: ${name}`);
@@ -3243,7 +3249,7 @@ export async function loadAppAuthzCatalog(appDir: string): Promise<AuthzCatalog>
if (!router.authz.length) return emptyCatalog(); if (!router.authz.length) return emptyCatalog();
const sources: CatalogSource[] = []; const sources: CatalogSource[] = [];
for (const entry of router.authz) { for (const entry of router.authz) {
if (entry.name === "permissions.gen") continue; // generated types, not a declaration // buildRouter already skips *.gen.ts, so only real declarations arrive here.
const imported = (await import(pathToFileURL(entry.file).href)) as { default?: AuthzModule }; const imported = (await import(pathToFileURL(entry.file).href)) as { default?: AuthzModule };
if (!imported.default) continue; if (!imported.default) continue;
sources.push({ source: entry.file, module: imported.default }); sources.push({ source: entry.file, module: imported.default });