feat(authz): generate Permission and Role union types
Emits sorted TS unions from the merged catalog so a typo in can(ctx, "post:wrtie") is a compile-time error. Uses JSON.stringify for string-literal escaping (not manual backslash/quote replace) so role names containing raw newlines still produce valid TypeScript; role names are not regex-validated like permission ids, so this matters for the raw mergeCatalogs path.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
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 compile-time unions for the registered permissions and roles, so a
|
||||
* typo in can(ctx, "post:wrtie") is a type error rather than a silent false.
|
||||
*/
|
||||
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()])};
|
||||
`;
|
||||
}
|
||||
Reference in New Issue
Block a user