{"version":3,"file":"index.cjs","names":["parsePolicyRow","validatePolicy","parseRoleRow","validateRole"],"sources":["../../../src/adapters/drizzle/index.ts"],"sourcesContent":["import type { SQL, SQLWrapper } from 'drizzle-orm'\nimport type { MySqlDatabase } from 'drizzle-orm/mysql-core'\nimport type { MySqlTableWithColumns } from 'drizzle-orm/mysql-core/table'\nimport type { PgDatabase } from 'drizzle-orm/pg-core'\nimport type { PgTableWithColumns } from 'drizzle-orm/pg-core/table'\nimport type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core'\nimport type { SQLiteTableWithColumns } from 'drizzle-orm/sqlite-core/table'\nimport type { AccessControl, IamAdapter, IamPrimitives, IamRequest } from '../../core/types'\nimport { parsePolicyRow, parseRoleRow, validatePolicy, validateRole } from '../../core/validate'\nimport type {\n  iamAssignments as AssignmentMysql,\n  iamSubjectAttrs as AttrMysql,\n  iamPolicies as PolicyMysql,\n  iamRoles as RoleMysql,\n} from './schema/mysql'\nimport type {\n  iamAssignments as AssignmentPg,\n  iamSubjectAttrs as AttrPg,\n  iamPolicies as PolicyPg,\n  iamRoles as RolePg,\n} from './schema/pg'\nimport type {\n  iamAssignments as AssignmentSqlite,\n  iamSubjectAttrs as AttrSqlite,\n  iamPolicies as PolicySqlite,\n  iamRoles as RoleSqlite,\n} from './schema/sqlite'\n\n/** IamDrizzle adapter integration types. Type-only namespace - zero bundle cost. */\nexport namespace IamDrizzle {\n  /**\n   * Describes the wiring required to instantiate a {@link IamDrizzleAdapter}.\n   *\n   * @example\n   * ```ts\n   * import { drizzle } from 'drizzle-orm/node-postgres'\n   * import { eq, and } from 'drizzle-orm'\n   * import { iamPolicies, iamRoles, iamAssignments, iamSubjectAttrs } from './schema'\n   *\n   * const config: IamDrizzle.IConfig = {\n   *   db: drizzle(pool),\n   *   tables: { policies: iamPolicies, roles: iamRoles, assignments: iamAssignments, attrs: iamSubjectAttrs },\n   *   ops: { eq, and },\n   * }\n   * ```\n   */\n  export interface IConfig<TDb extends AnyDrizzleDb = AnyDrizzleDb> {\n    /** Provides the IamDrizzle database instance with select/insert/delete builders. */\n    db: TDb\n    /** Provides references to the four IamDrizzle table schemas used by the adapter. */\n    tables: {\n      policies: DbTableFor<TDb>\n      roles: DbTableFor<TDb>\n      assignments: DbTableFor<TDb>\n      attrs: DbTableFor<TDb>\n    }\n    /** Provides IamDrizzle operator functions for building WHERE clauses. */\n    ops: {\n      eq: (col: unknown, val: unknown) => unknown\n      and: (...conditions: (SQLWrapper | undefined)[]) => SQL<unknown> | undefined\n    }\n    /**\n     * JSON column encoding strategy.\n     *\n     * - `'native'` (default) writes plain objects/arrays so Postgres `jsonb`\n     *   and MySQL `json` columns store queryable JSON (enables GIN indexes,\n     *   `jsonb_typeof` checks, and avoids double-encoding).\n     * - `'string'` `JSON.stringify`s every payload - required for SQLite, whose\n     *   columns are TEXT, or any deployment storing JSON in a text column.\n     *\n     * The read path accepts both shapes, so switching is migration-safe.\n     */\n    json?: 'native' | 'string'\n    /**\n     * Invoked when a stored row fails JSON parse or shape validation. The\n     * malformed row is dropped from the result set; the rest are returned\n     * intact. Wire this to your alerting pipeline so corrupt rows do not\n     * silently vanish from authorization decisions.\n     */\n    onPolicyError?: (err: Error, ctx: { adapter: 'drizzle'; rowId: string }) => void\n  }\n\n  /** Row shapes returned by IamDrizzle queries. */\n  export type PolicyRow =\n    | typeof PolicyPg.$inferSelect\n    | typeof PolicyMysql.$inferSelect\n    | typeof PolicySqlite.$inferSelect\n  /** Database row shape for the roles table. */\n  export type RoleRow = typeof RolePg.$inferSelect | typeof RoleMysql.$inferSelect | typeof RoleSqlite.$inferSelect\n\n  /** Database row shape for the role-to-subject assignments table. */\n  export type AssignmentRow =\n    | typeof AssignmentPg.$inferSelect\n    | typeof AssignmentMysql.$inferSelect\n    | typeof AssignmentSqlite.$inferSelect\n\n  /** Database row shape for the subject attributes table. */\n  export type AttrRow = typeof AttrPg.$inferSelect | typeof AttrMysql.$inferSelect | typeof AttrSqlite.$inferSelect\n\n  export type DrizzleTable = PgTableWithColumns<any> | MySqlTableWithColumns<any> | SQLiteTableWithColumns<any>\n\n  /**\n   * Structural db interface — all supported Drizzle instances satisfy this.\n   * Using a structural interface (not a union) lets TypeScript call\n   * `db.select()` on a generic `TDb extends AnyDrizzleDb` without the\n   * \"each member of the union has incompatible signatures\" error.\n   */\n  export interface AnyDrizzleDb {\n    select(...args: any[]): any\n    insert(table: any): any\n    delete(table: any): any\n  }\n\n  /**\n   * Maps a concrete db instance to its matching table type so that\n   * passing a pg db with sqlite tables is a compile error.\n   * Falls back to `any` when `TDb` is the bare structural default —\n   * this keeps `IamDrizzle.IConfig` (no type args) permissive for tests/mocks.\n   */\n  export type DbTableFor<TDb extends AnyDrizzleDb> =\n    TDb extends PgDatabase<any, any, any>\n      ? PgTableWithColumns<any>\n      : TDb extends MySqlDatabase<any, any, any, any>\n        ? MySqlTableWithColumns<any>\n        : TDb extends BaseSQLiteDatabase<any, any, any, any>\n          ? SQLiteTableWithColumns<any>\n          : any\n}\n\n/**\n * IamDrizzle-backed adapter; needs 4 tables (policies, roles, assignments, subject attributes) and `{ eq, and }` ops.\n *\n * @template TAction - Constrains valid action strings.\n * @template TResource - Constrains valid resource strings.\n * @template TRole - Constrains valid role strings.\n * @template TScope - Constrains valid scope strings.\n *\n * @example\n * ```ts\n * import { drizzle } from 'drizzle-orm/node-postgres'\n * import { eq, and } from 'drizzle-orm'\n * import { IamDrizzleAdapter } from '@gentleduck/iam/adapters/drizzle'\n *\n * const adapter = new IamDrizzleAdapter({ db: drizzle(pool), tables, ops: { eq, and } })\n * const engine = new IamEngine({ adapter })\n * ```\n */\nexport class IamDrizzleAdapter<\n  TAction extends string = string,\n  TResource extends string = string,\n  TRole extends string = string,\n  TScope extends string = string,\n  TDb extends IamDrizzle.AnyDrizzleDb = IamDrizzle.AnyDrizzleDb,\n> implements IamAdapter.IAdapter<TAction, TResource, TRole, TScope>\n{\n  private _db: TDb\n  private _t: IamDrizzle.IConfig<TDb>['tables']\n  private _eq: IamDrizzle.IConfig['ops']['eq']\n  private _and: IamDrizzle.IConfig['ops']['and']\n  private _json: 'native' | 'string'\n  private _onPolicyError?: (err: Error, ctx: { adapter: 'drizzle'; rowId: string }) => void\n\n  /**\n   * Creates a new IamDrizzle adapter.\n   *\n   * @param config - Provides the IamDrizzle db, tables, and operator functions.\n   */\n  constructor(config: IamDrizzle.IConfig<TDb>) {\n    this._db = config.db\n    this._t = config.tables\n    this._eq = config.ops.eq\n    this._and = config.ops.and\n    this._json = config.json ?? 'native'\n    this._onPolicyError = config.onPolicyError\n  }\n\n  /**\n   * Typed SELECT helpers consolidate the `as unknown as RowType[]` casts at\n   * the module edge into one place. IamDrizzle's `select().from()` returns\n   * untyped rows; row shapes are pinned at the boundary here.\n   */\n  private async _selectAll<T>(table: IamDrizzle.DrizzleTable): Promise<T[]> {\n    return await this._db.select().from(table)\n  }\n  private async _selectFirst<T>(\n    table: IamDrizzle.DrizzleTable,\n    whereCol: unknown,\n    whereVal: unknown,\n  ): Promise<T | undefined> {\n    const rows = await this._db.select().from(table).where(this._eq(whereCol, whereVal)).limit(1)\n    return rows[0]\n  }\n  private async _selectWhere<T>(table: IamDrizzle.DrizzleTable, whereCol: unknown, whereVal: unknown): Promise<T[]> {\n    return await this._db.select().from(table).where(this._eq(whereCol, whereVal))\n  }\n\n  private _reportPolicyError(err: Error, rowId: string): void {\n    if (this._onPolicyError) {\n      this._onPolicyError(err, { adapter: 'drizzle', rowId })\n      return\n    }\n    // eslint-disable-next-line no-console\n    console.warn(`[@gentleduck/iam:drizzle] dropped malformed row \"${rowId}\": ${err.message}`)\n  }\n\n  /**\n   * Parse a row's JSON columns + validate the policy shape. Returns `null` on\n   * any failure (parse error or invalid shape) so the caller can drop the row.\n   */\n  private _safeParsePolicy(row: IamDrizzle.PolicyRow): AccessControl.IPolicy<TAction, TResource, TRole> | null {\n    let parsedRules: unknown\n    let parsedTargets: unknown\n    try {\n      parsedRules =\n        typeof row.rules === 'string' ? JSON.parse(row.rules) : (row.rules as AccessControl.IPolicy['rules'])\n      parsedTargets = row.targets\n        ? typeof row.targets === 'string'\n          ? JSON.parse(row.targets)\n          : (row.targets as AccessControl.IPolicy['targets'])\n        : undefined\n    } catch (err) {\n      this._reportPolicyError(err instanceof Error ? err : new Error(String(err)), row.id)\n      return null\n    }\n\n    const candidate = {\n      id: row.id,\n      name: row.name,\n      description: row.description ?? undefined,\n      version: row.version,\n      algorithm: row.algorithm as AccessControl.IPolicy['algorithm'],\n      rules: parsedRules,\n      targets: parsedTargets,\n    }\n    const policy = parsePolicyRow<TAction, TResource, TRole>(candidate)\n    if (policy === null) {\n      const issues = validatePolicy(candidate)\n        .issues.map((i) => i.message)\n        .join('; ')\n      this._reportPolicyError(new Error(`Invalid policy \"${row.id}\": ${issues}`), row.id)\n      return null\n    }\n    return policy\n  }\n\n  private _safeParseRole(row: IamDrizzle.RoleRow): AccessControl.IRole<TAction, TResource, TRole, TScope> | null {\n    let permissions: unknown\n    let inherits: unknown\n    let metadata: unknown\n    try {\n      permissions =\n        typeof row.permissions === 'string'\n          ? JSON.parse(row.permissions)\n          : (row.permissions as AccessControl.IRole['permissions'])\n      inherits = typeof row.inherits === 'string' ? JSON.parse(row.inherits) : ((row.inherits as string[] | null) ?? [])\n      metadata = row.metadata\n        ? typeof row.metadata === 'string'\n          ? JSON.parse(row.metadata)\n          : (row.metadata as AccessControl.IRole['metadata'])\n        : undefined\n    } catch (err) {\n      this._reportPolicyError(err instanceof Error ? err : new Error(String(err)), row.id)\n      return null\n    }\n\n    const candidate = {\n      id: row.id,\n      name: row.name,\n      description: row.description ?? undefined,\n      permissions,\n      inherits,\n      scope: row.scope ?? undefined,\n      metadata,\n    }\n    const role = parseRoleRow<TAction, TResource, TRole, TScope>(candidate)\n    if (role === null) {\n      const issues = validateRole(candidate)\n        .issues.map((i) => i.message)\n        .join('; ')\n      this._reportPolicyError(new Error(`Invalid role \"${row.id}\": ${issues}`), row.id)\n      return null\n    }\n    return role\n  }\n\n  /**\n   * Lists every policy in the database.\n   *\n   * @param _opts - Ignored read options accepted for interface compatibility.\n   * @returns All policies parsed from the policies table.\n   */\n  async listPolicies(_opts?: IamAdapter.IReadOptions): Promise<AccessControl.IPolicy<TAction, TResource, TRole>[]> {\n    const rows = await this._selectAll<IamDrizzle.PolicyRow>(this._t.policies)\n    const out: AccessControl.IPolicy<TAction, TResource, TRole>[] = []\n    for (const row of rows) {\n      const parsed = this._safeParsePolicy(row)\n      if (parsed) out.push(parsed)\n    }\n    return out\n  }\n\n  /**\n   * Fetches a single policy by ID.\n   *\n   * @param id - Identifies the policy to look up.\n   * @param _opts - Ignored read options accepted for interface compatibility.\n   * @returns The matching policy or `null` when absent.\n   */\n  async getPolicy(\n    id: string,\n    _opts?: IamAdapter.IReadOptions,\n  ): Promise<AccessControl.IPolicy<TAction, TResource, TRole> | null> {\n    const row = await this._selectFirst<IamDrizzle.PolicyRow>(this._t.policies, this._t.policies.id, id)\n    return row ? this._safeParsePolicy(row) : null\n  }\n\n  /**\n   * Upserts a policy (inserts or updates on conflict).\n   *\n   * @param p - Provides the policy to persist.\n   * @returns Resolves once the upsert completes.\n   */\n  async savePolicy(p: AccessControl.IPolicy<TAction, TResource, TRole>): Promise<void> {\n    const data = serializePolicy(p, this._json)\n    await this._db.insert(this._t.policies).values(data).onConflictDoUpdate({ target: this._t.policies.id, set: data })\n  }\n\n  /**\n   * Removes a policy by ID.\n   *\n   * @param id - Identifies the policy to delete.\n   * @returns Resolves once the delete completes.\n   */\n  async deletePolicy(id: string): Promise<void> {\n    await this._db.delete(this._t.policies).where(this._eq(this._t.policies.id, id))\n  }\n\n  /**\n   * Lists every role in the database.\n   *\n   * @param _opts - Ignored read options accepted for interface compatibility.\n   * @returns All roles parsed from the roles table.\n   */\n  async listRoles(_opts?: IamAdapter.IReadOptions): Promise<AccessControl.IRole<TAction, TResource, TRole, TScope>[]> {\n    const rows = await this._selectAll<IamDrizzle.RoleRow>(this._t.roles)\n    const out: AccessControl.IRole<TAction, TResource, TRole, TScope>[] = []\n    for (const row of rows) {\n      const parsed = this._safeParseRole(row)\n      if (parsed) out.push(parsed)\n    }\n    return out\n  }\n\n  /**\n   * Fetches a single role by ID.\n   *\n   * @param id - Identifies the role to look up.\n   * @param _opts - Ignored read options accepted for interface compatibility.\n   * @returns The matching role or `null` when absent.\n   */\n  async getRole(\n    id: string,\n    _opts?: IamAdapter.IReadOptions,\n  ): Promise<AccessControl.IRole<TAction, TResource, TRole, TScope> | null> {\n    const row = await this._selectFirst<IamDrizzle.RoleRow>(this._t.roles, this._t.roles.id, id)\n    return row ? this._safeParseRole(row) : null\n  }\n\n  /**\n   * Upserts a role (inserts or updates on conflict).\n   *\n   * @param r - Provides the role to persist.\n   * @returns Resolves once the upsert completes.\n   */\n  async saveRole(r: AccessControl.IRole<TAction, TResource, TRole, TScope>): Promise<void> {\n    const data = serializeRole(r, this._json)\n    await this._db.insert(this._t.roles).values(data).onConflictDoUpdate({ target: this._t.roles.id, set: data })\n  }\n\n  /**\n   * Removes a role by ID.\n   *\n   * @param id - Identifies the role to delete.\n   * @returns Resolves once the delete completes.\n   */\n  async deleteRole(id: string): Promise<void> {\n    await this._db.delete(this._t.roles).where(this._eq(this._t.roles.id, id))\n  }\n\n  /**\n   * Lists deduplicated role IDs assigned to a subject.\n   *\n   * @param subjectId - Identifies the subject whose roles are read.\n   * @param _opts - Ignored read options accepted for interface compatibility.\n   * @returns Deduplicated array of role IDs.\n   */\n  async getSubjectRoles(subjectId: string, _opts?: IamAdapter.IReadOptions): Promise<TRole[]> {\n    const rows = await this._selectWhere<IamDrizzle.AssignmentRow>(\n      this._t.assignments,\n      this._t.assignments.subjectId,\n      subjectId,\n    )\n    // Unscoped (global) roles only - mirrors file/memory/redis adapters.\n    return [...new Set(rows.filter((r) => r.scope == null).map((r) => r.roleId as TRole))]\n  }\n\n  /**\n   * Lists scoped role assignments for a subject (excludes unscoped).\n   *\n   * @param subjectId - Identifies the subject whose scoped roles are read.\n   * @param _opts - Ignored read options accepted for interface compatibility.\n   * @returns Array of `(role, scope)` pairs.\n   */\n  async getSubjectScopedRoles(\n    subjectId: string,\n    _opts?: IamAdapter.IReadOptions,\n  ): Promise<IamRequest.IScopedRole<TRole, TScope>[]> {\n    const rows = await this._selectWhere<IamDrizzle.AssignmentRow>(\n      this._t.assignments,\n      this._t.assignments.subjectId,\n      subjectId,\n    )\n    return rows.filter((r) => r.scope != null).map((r) => ({ role: r.roleId as TRole, scope: r.scope as TScope }))\n  }\n\n  /**\n   * Grants a role to a subject, optionally restricted to a scope.\n   *\n   * No-ops on duplicate `(subject, role, scope)` rows.\n   *\n   * @param subjectId - Identifies the subject receiving the role.\n   * @param roleId - Specifies the role being granted.\n   * @param scope - Optional scope binding the assignment.\n   * @returns Resolves once the insert completes.\n   */\n  async assignRole(subjectId: string, roleId: TRole, scope?: TScope): Promise<void> {\n    await this._db\n      .insert(this._t.assignments)\n      .values({ subjectId, roleId, scope: scope ?? null })\n      .onConflictDoNothing()\n  }\n\n  /**\n   * Removes role assignments matching the given filters.\n   *\n   * @param subjectId - Identifies the subject losing the role.\n   * @param roleId - Specifies the role being revoked.\n   * @param scope - Optional scope filter to narrow the delete.\n   * @returns Resolves once the delete completes.\n   */\n  async revokeRole(subjectId: string, roleId: TRole, scope?: TScope): Promise<void> {\n    const conditions = [\n      this._eq(this._t.assignments.subjectId, subjectId),\n      this._eq(this._t.assignments.roleId, roleId),\n    ]\n    if (scope) conditions.push(this._eq(this._t.assignments.scope, scope))\n    await this._db.delete(this._t.assignments).where(this._and(...(conditions as (SQLWrapper | undefined)[])))\n  }\n\n  /**\n   * Fetches the attribute bag stored for a subject.\n   *\n   * @param subjectId - Identifies the subject whose attributes are read.\n   * @param _opts - Ignored read options accepted for interface compatibility.\n   * @returns The subject's attributes or `{}` when none are recorded.\n   */\n  async getSubjectAttributes(subjectId: string, _opts?: IamAdapter.IReadOptions): Promise<IamPrimitives.Attributes> {\n    const row = await this._selectFirst<IamDrizzle.AttrRow>(this._t.attrs, this._t.attrs.subjectId, subjectId)\n    if (!row) return {}\n    const data = row.data\n    if (typeof data === 'string') {\n      let parsed: unknown\n      try {\n        parsed = JSON.parse(data)\n      } catch (err) {\n        // Corruption is not \"no attributes\" - surface so the engine fails closed.\n        this._reportPolicyError(err instanceof Error ? err : new Error(String(err)), subjectId)\n        throw new Error(`[@gentleduck/iam:drizzle] corrupted attributes for \"${subjectId}\" (JSON parse failed)`)\n      }\n      return this._validateAttributesShape(parsed, subjectId)\n    }\n    if (data === null || data === undefined) return {}\n    return this._validateAttributesShape(data, subjectId)\n  }\n\n  private _validateAttributesShape(value: unknown, subjectId: string): IamPrimitives.Attributes {\n    if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n      const got = value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value\n      this._reportPolicyError(new Error(`Attributes for \"${subjectId}\" must be a JSON object (got ${got})`), subjectId)\n      throw new Error(`[@gentleduck/iam:drizzle] corrupted attributes for \"${subjectId}\" (not a JSON object)`)\n    }\n    return value as IamPrimitives.Attributes\n  }\n\n  /**\n   * Shallow-merges new attributes into the subject's existing bag (upsert).\n   *\n   * @param subjectId - Identifies the subject whose attributes are written.\n   * @param attrs - Provides the partial attribute patch to merge in.\n   * @returns Resolves once the upsert completes.\n   */\n  async setSubjectAttributes(subjectId: string, attrs: IamPrimitives.Attributes): Promise<void> {\n    // Admin overwrite must recover from corrupt existing data instead of\n    // locking the operator out.\n    let existing: IamPrimitives.Attributes\n    try {\n      existing = await this.getSubjectAttributes(subjectId)\n    } catch (err) {\n      this._reportPolicyError(err instanceof Error ? err : new Error(String(err)), subjectId)\n      existing = {}\n    }\n    const mergedObj = { ...existing, ...attrs }\n    const merged = this._json === 'string' ? JSON.stringify(mergedObj) : mergedObj\n    await this._db\n      .insert(this._t.attrs)\n      .values({ subjectId, data: merged })\n      .onConflictDoUpdate({ target: this._t.attrs.subjectId, set: { data: merged } })\n  }\n}\n\n/**\n * Encodes a JSON payload for storage: `JSON.stringify` in `'string'` mode\n * (SQLite / text columns), or the value untouched in `'native'` mode so\n * IamDrizzle hands a real object to a `jsonb`/`json` column.\n */\nfunction encodeJson(value: unknown, mode: 'native' | 'string'): unknown {\n  return mode === 'string' ? JSON.stringify(value) : value\n}\n\n/** Converts a Policy object into a flat record for storage under the given JSON mode. */\nfunction serializePolicy(p: AccessControl.IPolicy, json: 'native' | 'string'): Record<string, unknown> {\n  return {\n    id: p.id,\n    name: p.name,\n    description: p.description ?? null,\n    version: p.version ?? 1,\n    algorithm: p.algorithm,\n    rules: encodeJson(p.rules, json),\n    targets: p.targets ? encodeJson(p.targets, json) : null,\n  }\n}\n\n/** Converts a Role object into a flat record for storage under the given JSON mode. */\nfunction serializeRole(r: AccessControl.IRole, json: 'native' | 'string'): Record<string, unknown> {\n  return {\n    id: r.id,\n    name: r.name,\n    description: r.description ?? null,\n    permissions: encodeJson(r.permissions, json),\n    inherits: encodeJson(r.inherits ?? [], json),\n    scope: r.scope ?? null,\n    metadata: r.metadata ? encodeJson(r.metadata, json) : null,\n  }\n}\n"],"mappings":"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"}