import { n as IamPrimitives, t as AccessControl } from "../../access-control-CxeWQI64.js"; import { t as IamAdapter } from "../../adapter-DeNTUcdv.js"; import { t as IamRequest } from "../../request-BouexCSW.js"; //#region src/adapters/file/index.d.ts declare namespace IamFile { /** * Describes the minimal `node:fs/promises`-compatible surface used by {@link IamFileAdapter}. * * Tests inject an in-memory fake; production passes the real Node module. */ interface IFS { /** * Reads a file as UTF-8 text. * * @param path - Absolute path to read. * @param encoding - Must be `'utf8'`. * @returns The file contents as a string. */ readFile(path: string, encoding: 'utf8'): Promise; /** * Writes a file as UTF-8 text. * * @param path - Absolute path to write. * @param data - String contents to persist. * @param encoding - Must be `'utf8'`. * @returns Resolves once the write completes. */ writeFile(path: string, data: string, encoding: 'utf8'): Promise; /** * Creates a directory. **Not recursive** - the immediate parent must * already exist, so a typo in `init.path` cannot silently build a deep * tree. * * @param path - Absolute directory to create. * @returns Resolves once the directory exists. */ mkdir(path: string, options?: { recursive?: boolean; }): Promise; /** * Optional: resolve symlinks for a path. When present (e.g. the real * `node:fs/promises` provides it) the adapter uses it during the * `rootDir` containment check to reject symlinks that escape the root. * Test fakes typically omit this; the symlink check is skipped when * unavailable. * * @param path - Path to canonicalise. * @returns The canonical path with all symlinks resolved. */ realpath?(path: string): Promise; } /** Describes initialization options for {@link IamFileAdapter}. */ interface IInit { /** * Specifies the **absolute** path of the JSON store file. * * Rejected at construction when: * - the resolved path is not absolute, * - the normalized path contains a `..` segment, or * - {@link rootDir} is set and the path escapes it. * * The adapter creates the file on first write, but **does not** recursively * create directories - the immediate parent must already exist, guarding * against a typo in `path` accidentally building deep paths. */ path: string; /** * Optional containment root. When set, {@link path} must resolve to a * location inside this directory (after symlink resolution if the * filesystem driver exposes `realpath`). Strongly recommended whenever * any part of `path` is derived from caller-controlled input. * * If omitted, the adapter logs a one-shot `console.warn` at construction * and accepts any absolute path. */ rootDir?: string; /** * Provides the filesystem driver. Pass `await import('node:fs/promises')` * in Node or Bun, or any object implementing {@link IFS} for tests. */ fs: TFS; /** * Invoked when a stored row fails JSON parse or shape validation. The * malformed row is dropped from the loaded state; the rest are returned * intact. Wire this to your alerting pipeline so corrupt rows do not * silently vanish from authorization decisions. */ onPolicyError?: (err: Error, ctx: { adapter: 'file'; rowId: string; }) => void; } /** * Describes the on-disk JSON state shape held by {@link IamFileAdapter}. * * Exposed for typing the internal cache field; not part of the wire API. * * @template TAction - Constrains valid action strings. * @template TResource - Constrains valid resource strings. * @template TRole - Constrains valid role strings. * @template TScope - Constrains valid scope strings. */ interface IState { policies: Record>; roles: Record>; assignments: Record>; attributes: Record; } } declare class IamFileAdapter implements IamAdapter.IAdapter { private readonly _path; private readonly _parentDir; private readonly _rootDir; private readonly _fs; private readonly _onPolicyError?; private _cache; private _loadInFlight; /** * Create the adapter; synchronously validates `init.path` for absoluteness, `..`, and `rootDir` containment. * * @param init - Provides the store path and filesystem driver. */ constructor(init: IamFile.IInit); /** * Resolves symlinks via `realpath` (when the FS driver exposes one) and * re-checks containment under `_rootDir`. Runs on every read AND every * write so an attacker cannot swap the file for a symlink after the first * I/O and steer later writes elsewhere. Symlink check is skipped when * `realpath` is unavailable (test fakes, browser bundles) - the * constructor already enforced textual containment. */ private _assertWithinRoot; private _reportPolicyError; private _loadState; private _flush; /** * Lists every policy persisted on disk. * * @param _opts - Ignored read options accepted for interface compatibility. * @returns All stored policies. */ listPolicies(_opts?: IamAdapter.IReadOptions): Promise[]>; /** * Fetches a single policy by ID. * * @param id - Identifies the policy to look up. * @param _opts - Ignored read options accepted for interface compatibility. * @returns The matching policy or `null` when absent. */ getPolicy(id: string, _opts?: IamAdapter.IReadOptions): Promise | null>; /** * Stores or overwrites a policy and flushes to disk. * * @param p - Provides the policy to persist. * @returns Resolves once the file is rewritten. */ savePolicy(p: AccessControl.IPolicy): Promise; /** * Removes a policy by ID and flushes to disk. * * @param id - Identifies the policy to delete. * @returns Resolves once the file is rewritten. */ deletePolicy(id: string): Promise; /** * Lists every role persisted on disk. * * @param _opts - Ignored read options accepted for interface compatibility. * @returns All stored roles. */ listRoles(_opts?: IamAdapter.IReadOptions): Promise[]>; /** * Fetches a single role by ID. * * @param id - Identifies the role to look up. * @param _opts - Ignored read options accepted for interface compatibility. * @returns The matching role or `null` when absent. */ getRole(id: string, _opts?: IamAdapter.IReadOptions): Promise | null>; /** * Stores or overwrites a role and flushes to disk. * * @param r - Provides the role to persist. * @returns Resolves once the file is rewritten. */ saveRole(r: AccessControl.IRole): Promise; /** * Removes a role by ID and flushes to disk. * * @param id - Identifies the role to delete. * @returns Resolves once the file is rewritten. */ deleteRole(id: string): Promise; /** * Lists unscoped (global) roles assigned to a subject. * * @param id - Identifies the subject whose global roles are read. * @param _opts - Ignored read options accepted for interface compatibility. * @returns Deduplicated array of role IDs without scope. */ getSubjectRoles(id: string, _opts?: IamAdapter.IReadOptions): Promise; /** * Lists scoped role assignments for a subject. * * @param id - Identifies the subject whose scoped roles are read. * @param _opts - Ignored read options accepted for interface compatibility. * @returns Array of `(role, scope)` pairs for scoped assignments only. */ getSubjectScopedRoles(id: string, _opts?: IamAdapter.IReadOptions): Promise[]>; /** * Grants a role to a subject, optionally restricted to a scope. * * Duplicate `(role, scope)` pairs are silently ignored. * * @param id - Identifies the subject receiving the role. * @param roleId - Specifies the role being granted. * @param scope - Optional scope binding the assignment. * @returns Resolves once the file is rewritten. */ assignRole(id: string, roleId: TRole, scope?: TScope): Promise; /** * Removes a role assignment from a subject. * * @param id - Identifies the subject losing the role. * @param roleId - Specifies the role being revoked. * @param scope - Optional scope to match; omit to revoke unscoped only. * @returns Resolves once the file is rewritten. */ revokeRole(id: string, roleId: TRole, scope?: TScope): Promise; /** * Fetches the attribute bag stored for a subject. * * @param id - Identifies the subject whose attributes are read. * @param _opts - Ignored read options accepted for interface compatibility. * @returns The subject's attributes or `{}` when none are recorded. */ getSubjectAttributes(id: string, _opts?: IamAdapter.IReadOptions): Promise; /** * Shallow-merges new attributes into the subject's existing bag. * * @param id - Identifies the subject whose attributes are written. * @param attrs - Provides the partial attribute patch to merge in. * @returns Resolves once the file is rewritten. */ setSubjectAttributes(id: string, attrs: IamPrimitives.Attributes): Promise; } //#endregion export { IamFile, IamFileAdapter }; //# sourceMappingURL=index.d.ts.map