import type { AuthzCatalog } from "./types.ts"; function union(values: string[]): string { if (!values.length) return "never"; // JSON.stringify escapes backslashes, quotes, and control characters // (including raw newlines, which the registry does not reject in role // names and which would otherwise break out of the string literal). return values .slice() .sort() .map((value) => JSON.stringify(value)) .join(" | "); } /** * Emit `Permission`/`Role` string-literal unions from the registered catalog. * * This does NOT make `can(ctx, "post:wrtie")` a type error — `can()`, * `guardPermission()`, and `decideFor()` all take a bare `string`, and * nothing in the framework consumes this generated file automatically. * Import the unions yourself to type your OWN helpers/constants, e.g. * `const PERM: Permission = "post:write"` or a typed wrapper around `can()`. */ export function generatePermissionTypes(catalog: AuthzCatalog): string { return `// Generated by \`wrnexus authz generate\`. DO NOT EDIT. export type Permission = ${union([...catalog.permissions.keys()])}; export type Role = ${union([...catalog.roles.keys()])}; `; }