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"; import { iamAssignments, iamPolicies, iamRoles, iamSubjectAttrs } from "./schema/mysql.js"; import { iamAssignments as iamAssignments$1, iamPolicies as iamPolicies$1, iamRoles as iamRoles$1, iamSubjectAttrs as iamSubjectAttrs$1 } from "./schema/pg.js"; import { iamAssignments as iamAssignments$2, iamPolicies as iamPolicies$2, iamRoles as iamRoles$2, iamSubjectAttrs as iamSubjectAttrs$2 } from "./schema/sqlite.js"; import { SQL, SQLWrapper } from "drizzle-orm"; import { PgDatabase } from "drizzle-orm/pg-core"; import { MySqlDatabase } from "drizzle-orm/mysql-core"; import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; import { MySqlTableWithColumns } from "drizzle-orm/mysql-core/table"; import { PgTableWithColumns } from "drizzle-orm/pg-core/table"; import { SQLiteTableWithColumns } from "drizzle-orm/sqlite-core/table"; //#region src/adapters/drizzle/index.d.ts /** IamDrizzle adapter integration types. Type-only namespace - zero bundle cost. */ declare namespace IamDrizzle { /** * Describes the wiring required to instantiate a {@link IamDrizzleAdapter}. * * @example * ```ts * import { drizzle } from 'drizzle-orm/node-postgres' * import { eq, and } from 'drizzle-orm' * import { iamPolicies, iamRoles, iamAssignments, iamSubjectAttrs } from './schema' * * const config: IamDrizzle.IConfig = { * db: drizzle(pool), * tables: { policies: iamPolicies, roles: iamRoles, assignments: iamAssignments, attrs: iamSubjectAttrs }, * ops: { eq, and }, * } * ``` */ interface IConfig { /** Provides the IamDrizzle database instance with select/insert/delete builders. */ db: TDb; /** Provides references to the four IamDrizzle table schemas used by the adapter. */ tables: { policies: DbTableFor; roles: DbTableFor; assignments: DbTableFor; attrs: DbTableFor; }; /** Provides IamDrizzle operator functions for building WHERE clauses. */ ops: { eq: (col: unknown, val: unknown) => unknown; and: (...conditions: (SQLWrapper | undefined)[]) => SQL | undefined; }; /** * JSON column encoding strategy. * * - `'native'` (default) writes plain objects/arrays so Postgres `jsonb` * and MySQL `json` columns store queryable JSON (enables GIN indexes, * `jsonb_typeof` checks, and avoids double-encoding). * - `'string'` `JSON.stringify`s every payload - required for SQLite, whose * columns are TEXT, or any deployment storing JSON in a text column. * * The read path accepts both shapes, so switching is migration-safe. */ json?: 'native' | 'string'; /** * Invoked when a stored row fails JSON parse or shape validation. The * malformed row is dropped from the result set; 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: 'drizzle'; rowId: string; }) => void; } /** Row shapes returned by IamDrizzle queries. */ type PolicyRow = typeof iamPolicies$1.$inferSelect | typeof iamPolicies.$inferSelect | typeof iamPolicies$2.$inferSelect; /** Database row shape for the roles table. */ type RoleRow = typeof iamRoles$1.$inferSelect | typeof iamRoles.$inferSelect | typeof iamRoles$2.$inferSelect; /** Database row shape for the role-to-subject assignments table. */ type AssignmentRow = typeof iamAssignments$1.$inferSelect | typeof iamAssignments.$inferSelect | typeof iamAssignments$2.$inferSelect; /** Database row shape for the subject attributes table. */ type AttrRow = typeof iamSubjectAttrs$1.$inferSelect | typeof iamSubjectAttrs.$inferSelect | typeof iamSubjectAttrs$2.$inferSelect; type DrizzleTable = PgTableWithColumns | MySqlTableWithColumns | SQLiteTableWithColumns; /** * Structural db interface — all supported Drizzle instances satisfy this. * Using a structural interface (not a union) lets TypeScript call * `db.select()` on a generic `TDb extends AnyDrizzleDb` without the * "each member of the union has incompatible signatures" error. */ interface AnyDrizzleDb { select(...args: any[]): any; insert(table: any): any; delete(table: any): any; } /** * Maps a concrete db instance to its matching table type so that * passing a pg db with sqlite tables is a compile error. * Falls back to `any` when `TDb` is the bare structural default — * this keeps `IamDrizzle.IConfig` (no type args) permissive for tests/mocks. */ type DbTableFor = TDb extends PgDatabase ? PgTableWithColumns : TDb extends MySqlDatabase ? MySqlTableWithColumns : TDb extends BaseSQLiteDatabase ? SQLiteTableWithColumns : any; } /** * IamDrizzle-backed adapter; needs 4 tables (policies, roles, assignments, subject attributes) and `{ eq, and }` ops. * * @template TAction - Constrains valid action strings. * @template TResource - Constrains valid resource strings. * @template TRole - Constrains valid role strings. * @template TScope - Constrains valid scope strings. * * @example * ```ts * import { drizzle } from 'drizzle-orm/node-postgres' * import { eq, and } from 'drizzle-orm' * import { IamDrizzleAdapter } from '@gentleduck/iam/adapters/drizzle' * * const adapter = new IamDrizzleAdapter({ db: drizzle(pool), tables, ops: { eq, and } }) * const engine = new IamEngine({ adapter }) * ``` */ declare class IamDrizzleAdapter implements IamAdapter.IAdapter { private _db; private _t; private _eq; private _and; private _json; private _onPolicyError?; /** * Creates a new IamDrizzle adapter. * * @param config - Provides the IamDrizzle db, tables, and operator functions. */ constructor(config: IamDrizzle.IConfig); /** * Typed SELECT helpers consolidate the `as unknown as RowType[]` casts at * the module edge into one place. IamDrizzle's `select().from()` returns * untyped rows; row shapes are pinned at the boundary here. */ private _selectAll; private _selectFirst; private _selectWhere; private _reportPolicyError; /** * Parse a row's JSON columns + validate the policy shape. Returns `null` on * any failure (parse error or invalid shape) so the caller can drop the row. */ private _safeParsePolicy; private _safeParseRole; /** * Lists every policy in the database. * * @param _opts - Ignored read options accepted for interface compatibility. * @returns All policies parsed from the policies table. */ 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>; /** * Upserts a policy (inserts or updates on conflict). * * @param p - Provides the policy to persist. * @returns Resolves once the upsert completes. */ savePolicy(p: AccessControl.IPolicy): Promise; /** * Removes a policy by ID. * * @param id - Identifies the policy to delete. * @returns Resolves once the delete completes. */ deletePolicy(id: string): Promise; /** * Lists every role in the database. * * @param _opts - Ignored read options accepted for interface compatibility. * @returns All roles parsed from the roles table. */ 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>; /** * Upserts a role (inserts or updates on conflict). * * @param r - Provides the role to persist. * @returns Resolves once the upsert completes. */ saveRole(r: AccessControl.IRole): Promise; /** * Removes a role by ID. * * @param id - Identifies the role to delete. * @returns Resolves once the delete completes. */ deleteRole(id: string): Promise; /** * Lists deduplicated role IDs assigned to a subject. * * @param subjectId - Identifies the subject whose roles are read. * @param _opts - Ignored read options accepted for interface compatibility. * @returns Deduplicated array of role IDs. */ getSubjectRoles(subjectId: string, _opts?: IamAdapter.IReadOptions): Promise; /** * Lists scoped role assignments for a subject (excludes unscoped). * * @param subjectId - Identifies the subject whose scoped roles are read. * @param _opts - Ignored read options accepted for interface compatibility. * @returns Array of `(role, scope)` pairs. */ getSubjectScopedRoles(subjectId: string, _opts?: IamAdapter.IReadOptions): Promise[]>; /** * Grants a role to a subject, optionally restricted to a scope. * * No-ops on duplicate `(subject, role, scope)` rows. * * @param subjectId - Identifies the subject receiving the role. * @param roleId - Specifies the role being granted. * @param scope - Optional scope binding the assignment. * @returns Resolves once the insert completes. */ assignRole(subjectId: string, roleId: TRole, scope?: TScope): Promise; /** * Removes role assignments matching the given filters. * * @param subjectId - Identifies the subject losing the role. * @param roleId - Specifies the role being revoked. * @param scope - Optional scope filter to narrow the delete. * @returns Resolves once the delete completes. */ revokeRole(subjectId: string, roleId: TRole, scope?: TScope): Promise; /** * Fetches the attribute bag stored for a subject. * * @param subjectId - 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(subjectId: string, _opts?: IamAdapter.IReadOptions): Promise; private _validateAttributesShape; /** * Shallow-merges new attributes into the subject's existing bag (upsert). * * @param subjectId - Identifies the subject whose attributes are written. * @param attrs - Provides the partial attribute patch to merge in. * @returns Resolves once the upsert completes. */ setSubjectAttributes(subjectId: string, attrs: IamPrimitives.Attributes): Promise; } //#endregion export { IamDrizzle, IamDrizzleAdapter }; //# sourceMappingURL=index.d.ts.map