/** * @polymech/acl — Type definitions * * Pure ESM, zero external dependencies. * All methods are async (native Promise). */ // --------------------------------------------------------------------------- // Primitives // --------------------------------------------------------------------------- export type Value = string | number; export type Values = Value | Value[]; // --------------------------------------------------------------------------- // Result types // --------------------------------------------------------------------------- export type AclErrorCode = | 'OK' | 'INVALID_INPUT' | 'NOT_FOUND' | 'BACKEND_ERROR'; export interface AclOk { readonly ok: true; readonly code: 'OK'; readonly data: T; } export interface AclErr { readonly ok: false; readonly code: Exclude; readonly message: string; } export type AclResult = AclOk | AclErr; // Result constructors export const ok = (data: T): AclOk => ({ ok: true, code: 'OK', data }); export const okVoid: AclOk = Object.freeze({ ok: true, code: 'OK', data: undefined }) as AclOk; export const err = (code: AclErr['code'], message: string): AclErr => ({ ok: false, code, message }); // --------------------------------------------------------------------------- // Bucket naming // --------------------------------------------------------------------------- export interface BucketNames { readonly meta: string; readonly parents: string; readonly permissions: string; readonly resources: string; readonly roles: string; readonly users: string; } // --------------------------------------------------------------------------- // ACL Options // --------------------------------------------------------------------------- export interface AclOptions { buckets?: Partial; } // --------------------------------------------------------------------------- // Backend interface — purely async // --------------------------------------------------------------------------- /** * Transaction-based storage backend. * * `T` is the transaction type (e.g. `(() => void)[]` for in-memory). */ export interface IBackend { begin(): T | Promise; end(transaction: T): Promise; clean(): Promise; get(bucket: string, key: Value): Promise; union(bucket: string, keys: Value[]): Promise; unions(buckets: string[], keys: Value[]): Promise>; add(transaction: T, bucket: string, key: Value, values: Values): void | Promise; del(transaction: T, bucket: string, keys: Values): void | Promise; remove(transaction: T, bucket: string, key: Value, values: Values): void | Promise; } // --------------------------------------------------------------------------- // ACL public interface // --------------------------------------------------------------------------- export interface IAcl { allow(roles: Values, resources: Values, permissions: Values): Promise; allow(grants: AclGrant[]): Promise; addUserRoles(userId: Value, roles: Values): Promise; removeUserRoles(userId: Value, roles: Values): Promise; userRoles(userId: Value): Promise>; roleUsers(role: Value): Promise>; hasRole(userId: Value, role: string): Promise>; addRoleParents(role: string, parents: Values): Promise; removeRoleParents(role: string, parents?: Values): Promise; removeRole(role: string): Promise; removeResource(resource: string): Promise; removeAllow(role: string, resources: Values, permissions?: Values): Promise; allowedPermissions(userId: Value, resources: Values): Promise>>; isAllowed(userId: Value, resource: string, permissions: Values): Promise>; areAnyRolesAllowed(roles: Values, resource: string, permissions: Values): Promise>; whatResources(roles: Values, permissions?: Values): Promise | string[]>>; } // --------------------------------------------------------------------------- // Grant helpers // --------------------------------------------------------------------------- export interface AclGrant { roles: Values; allows: AclAllow[]; } export interface AclAllow { resources: Values; permissions: Values; } // --------------------------------------------------------------------------- // File store (optional, for FileBackend) // --------------------------------------------------------------------------- export interface IFileStore { read(path?: string): void | Promise; write(path?: string): void | Promise; }