/** Dotted uppercase: Group.Parent.Module or Group.Parent.Module.Submodule */ export const PRIVILEGE_KEY_CODE_PATTERN = /^[A-Z][A-Z0-9_]*\.[A-Z][A-Z0-9_]*\.[A-Z][A-Z0-9_]*(?:\.[A-Z][A-Z0-9_]*)?$/; export type ParsedPrivilegeKeyCode = { readonly group: string; readonly parent: string; readonly module: string; readonly submodule: string | null; }; export function isValidPrivilegeKeyCode(code: string): boolean { return typeof code === 'string' && PRIVILEGE_KEY_CODE_PATTERN.test(code); } export function assertPrivilegeKeyCode(code: string): string { if (!isValidPrivilegeKeyCode(code)) { throw new TypeError('Invalid privilege key code'); } return code; } export function parsePrivilegeKeyCode(code: string): ParsedPrivilegeKeyCode { assertPrivilegeKeyCode(code); const parts = code.split('.'); if (parts.length === 3) { const [group, parent, module] = parts; return { group, parent, module, submodule: null }; } const [group, parent, module, submodule] = parts; return { group, parent, module, submodule }; }