{"version":3,"sources":["../../src/testing/test-soft-delete.module.ts","../../src/soft-delete.constants.ts","../../src/services/soft-delete.service.ts","../../src/errors/cascade-relation-not-found.error.ts","../../src/prisma/cascade-handler.ts","../../src/services/soft-delete-context.ts","../../src/events/soft-delete-event-emitter.ts","../../src/events/soft-delete.events.ts","../../src/prisma/audit-lifecycle.ts","../../src/testing/expect-soft-deleted.ts"],"sourcesContent":["import { DynamicModule, Module } from '@nestjs/common';\nimport { SOFT_DELETE_MODULE_OPTIONS, SOFT_DELETE_PRISMA_SERVICE } from '../soft-delete.constants';\nimport { SoftDeleteService } from '../services/soft-delete.service';\nimport { SoftDeleteEventEmitter } from '../events/soft-delete-event-emitter';\nimport { CascadeHandler } from '../prisma/cascade-handler';\nimport type { SoftDeleteModuleOptions } from '../interfaces/soft-delete-options.interface';\n\n@Module({})\nexport class TestSoftDeleteModule {\n  static register(\n    options: Partial<SoftDeleteModuleOptions> & { softDeleteModels: string[] },\n    prisma?: any,\n  ): DynamicModule {\n    const fullOptions: SoftDeleteModuleOptions = {\n      deletedAtField: 'deletedAt',\n      prismaServiceToken: 'TEST_PRISMA',\n      ...options,\n    };\n\n    const providers: any[] = [\n      { provide: SOFT_DELETE_MODULE_OPTIONS, useValue: fullOptions },\n      { provide: CascadeHandler, useValue: null },\n      SoftDeleteService,\n      SoftDeleteEventEmitter,\n    ];\n\n    if (prisma) {\n      providers.push({ provide: SOFT_DELETE_PRISMA_SERVICE, useValue: prisma });\n    }\n\n    return {\n      module: TestSoftDeleteModule,\n      providers,\n      exports: [SoftDeleteService, SOFT_DELETE_MODULE_OPTIONS, SoftDeleteEventEmitter],\n    };\n  }\n}\n","export const SOFT_DELETE_MODULE_OPTIONS = Symbol('SOFT_DELETE_MODULE_OPTIONS');\nexport const SOFT_DELETE_PRISMA_SERVICE = Symbol('SOFT_DELETE_PRISMA_SERVICE');\nexport const WITH_DELETED_KEY = 'SOFT_DELETE_WITH_DELETED';\nexport const ONLY_DELETED_KEY = 'SOFT_DELETE_ONLY_DELETED';\nexport const SKIP_SOFT_DELETE_KEY = 'SOFT_DELETE_SKIP';\nexport const WITH_DELETED_RELATIONS_KEY = 'SOFT_DELETE_WITH_DELETED_RELATIONS';\nexport const DEFAULT_DELETED_AT_FIELD = 'deletedAt';\nexport const DEFAULT_MAX_CASCADE_DEPTH = 3;\nexport const SOFT_DELETE_EVENT_EMITTER = Symbol('SOFT_DELETE_EVENT_EMITTER');\n","import { Inject, Injectable, Optional } from '@nestjs/common';\nimport { SOFT_DELETE_MODULE_OPTIONS, SOFT_DELETE_PRISMA_SERVICE } from '../soft-delete.constants';\nimport { SoftDeleteModuleOptions } from '../interfaces/soft-delete-options.interface';\nimport { CascadeHandler } from '../prisma/cascade-handler';\nimport { SoftDeleteContext } from './soft-delete-context';\nimport { SoftDeleteEventEmitter } from '../events/soft-delete-event-emitter';\nimport { RestoredEvent, PurgedEvent } from '../events/soft-delete.events';\nimport {\n  DEFAULT_AUDIT_MAX_BATCH_RECORDS,\n  runAuditLifecycle,\n  validateAuditLifecycleOptions,\n} from '../prisma/audit-lifecycle';\n\n@Injectable()\nexport class SoftDeleteService {\n  private readonly deletedAtField: string;\n  private readonly deletedByField: string | null;\n\n  constructor(\n    @Inject(SOFT_DELETE_MODULE_OPTIONS) private readonly options: SoftDeleteModuleOptions,\n    @Inject(SOFT_DELETE_PRISMA_SERVICE) private readonly prisma: any,\n    @Optional() @Inject(CascadeHandler) private readonly cascadeHandler: CascadeHandler | null,\n    @Optional()\n    @Inject(SoftDeleteEventEmitter)\n    private readonly eventEmitter: SoftDeleteEventEmitter | null,\n  ) {\n    validateAuditLifecycleOptions(options);\n    this.deletedAtField = options.deletedAtField ?? 'deletedAt';\n    this.deletedByField = options.deletedByField ?? null;\n  }\n\n  /**\n   * Helper: get Prisma model delegate by name.\n   * Converts model name (e.g. \"User\") to camelCase key (e.g. \"user\").\n   */\n  private getModelDelegate(model: string): any {\n    const key = model.charAt(0).toLowerCase() + model.slice(1);\n    return this.prisma[key];\n  }\n\n  private buildRestoreData(): Record<string, any> {\n    const data: Record<string, any> = {\n      [this.deletedAtField]: null,\n    };\n    if (this.deletedByField) {\n      data[this.deletedByField] = null;\n    }\n    return data;\n  }\n\n  private buildDeletedWhere(where: Record<string, any> | undefined): Record<string, any> {\n    return {\n      ...(where ?? {}),\n      [this.deletedAtField]: { not: null },\n    };\n  }\n\n  private findPrimaryKey(model: string): string {\n    if (this.cascadeHandler) {\n      return this.cascadeHandler.findPrimaryKey(model);\n    }\n\n    const modelDef = this.options.dmmf?.datamodel.models.find(\n      (candidate: any) => candidate.name === model,\n    );\n    const pkField = modelDef?.fields.find((field: any) => field.isId);\n    return pkField?.name ?? 'id';\n  }\n\n  private async runLifecycle<T>(\n    model: string,\n    operation: string,\n    action: 'restored' | 'purged',\n    callback: (client: any) => Promise<T>,\n  ): Promise<T> {\n    return runAuditLifecycle(this.prisma, this.options, model, operation, action, callback);\n  }\n\n  /**\n   * Restore a soft-deleted record by setting deletedAt (and optionally deletedBy) back to null.\n   * If cascade is configured, cascade-restores child records as well.\n   */\n  async restore<T = any>(model: string, where: Record<string, any>): Promise<T> {\n    const restored = await this.runLifecycle(model, 'restore', 'restored', (client) =>\n      SoftDeleteContext.run(\n        {\n          filterMode: 'withDeleted',\n          skipSoftDelete: false,\n          actorId: SoftDeleteContext.getActorId(),\n        },\n        async () => {\n          const modelKey = model.charAt(0).toLowerCase() + model.slice(1);\n          const delegate = client[modelKey];\n          const deletedWhere = this.buildDeletedWhere(where);\n          const record = await delegate.findFirst({ where: deletedWhere });\n          if (!record) {\n            throw new Error(\n              `Record not found for model \"${model}\" with query ${JSON.stringify(where)}`,\n            );\n          }\n          const deletedAt = record[this.deletedAtField];\n          const result = await delegate.update({\n            where: {\n              ...deletedWhere,\n              [this.deletedAtField]: deletedAt,\n            },\n            data: this.buildRestoreData(),\n          });\n          if (this.cascadeHandler && deletedAt) {\n            const pkField = this.cascadeHandler.findPrimaryKey(model);\n            await this.cascadeHandler.cascadeRestore(\n              client,\n              model,\n              record[pkField],\n              deletedAt,\n              0,\n              this.options.auditLifecycle === 'atomic-required'\n                ? (childModel, callback) =>\n                    this.runLifecycle(childModel, 'cascadeRestore', 'restored', callback)\n                : undefined,\n            );\n          }\n          return result;\n        },\n      ),\n    );\n\n    this.eventEmitter?.emitRestored(\n      new RestoredEvent(model, where, SoftDeleteContext.getActorId()),\n    );\n\n    return restored as T;\n  }\n\n  /**\n   * Restore all soft-deleted records matching the given filter.\n   * If cascade is configured, cascade-restores child records for each affected parent.\n   */\n  async restoreMany(\n    model: string,\n    options: { where?: Record<string, any> } = {},\n  ): Promise<{ count: number }> {\n    const delegate = this.getModelDelegate(model);\n    const where = options.where ?? {};\n    const deletedWhere = this.buildDeletedWhere(where);\n    const data = this.buildRestoreData();\n\n    if (this.options.auditLifecycle === 'atomic-required') {\n      const maxRecords = this.options.auditMaxBatchRecords ?? DEFAULT_AUDIT_MAX_BATCH_RECORDS;\n      const result = await this.runLifecycle(model, 'restoreMany', 'restored', (client) =>\n        SoftDeleteContext.run(\n          {\n            filterMode: 'withDeleted',\n            skipSoftDelete: false,\n            actorId: SoftDeleteContext.getActorId(),\n          },\n          async () => {\n            const key = model.charAt(0).toLowerCase() + model.slice(1);\n            const delegate = client[key];\n            const records = await delegate.findMany({\n              where: deletedWhere,\n              take: maxRecords + 1,\n            });\n            if (records.length > maxRecords) {\n              throw new Error(\n                `[@nestarc/soft-delete] ${model}.restoreMany exceeds auditMaxBatchRecords (${maxRecords})`,\n              );\n            }\n            const pkField = this.findPrimaryKey(model);\n            for (const record of records) {\n              await delegate.update({\n                where: {\n                  ...deletedWhere,\n                  [pkField]: record[pkField],\n                  [this.deletedAtField]: record[this.deletedAtField],\n                },\n                data,\n              });\n              const deletedAt = record[this.deletedAtField];\n              if (this.cascadeHandler && deletedAt) {\n                await this.cascadeHandler.cascadeRestore(\n                  client,\n                  model,\n                  record[pkField],\n                  deletedAt,\n                  0,\n                  (childModel, callback) =>\n                    this.runLifecycle(childModel, 'cascadeRestore', 'restored', callback),\n                );\n              }\n            }\n            return { count: records.length };\n          },\n        ),\n      );\n      if (result.count > 0) {\n        this.eventEmitter?.emitRestored(\n          new RestoredEvent(model, where, SoftDeleteContext.getActorId(), result.count),\n        );\n      }\n      return result;\n    }\n\n    let recordsToCascade: Array<Record<string, any>> = [];\n    let pkField = 'id';\n\n    if (this.cascadeHandler) {\n      pkField = this.cascadeHandler.findPrimaryKey(model);\n      recordsToCascade = await this.withDeleted(() =>\n        delegate.findMany({\n          where: deletedWhere,\n          select: {\n            [pkField]: true,\n            [this.deletedAtField]: true,\n          },\n        }),\n      );\n    }\n\n    const result = await delegate.updateMany({\n      where: deletedWhere,\n      data,\n    });\n\n    if (this.cascadeHandler) {\n      for (const record of recordsToCascade) {\n        const deletedAt = record[this.deletedAtField];\n        if (!deletedAt) {\n          continue;\n        }\n\n        await SoftDeleteContext.run(\n          {\n            filterMode: 'withDeleted',\n            skipSoftDelete: false,\n            actorId: SoftDeleteContext.getActorId(),\n          },\n          () =>\n            this.cascadeHandler!.cascadeRestore(this.prisma, model, record[pkField], deletedAt, 0),\n        );\n      }\n    }\n\n    if (result.count > 0) {\n      this.eventEmitter?.emitRestored(\n        new RestoredEvent(model, where, SoftDeleteContext.getActorId(), result.count),\n      );\n    }\n\n    return result;\n  }\n\n  /**\n   * Permanently delete a record, bypassing soft-delete logic.\n   */\n  async forceDelete<T = any>(model: string, where: Record<string, any>): Promise<T> {\n    return this.runLifecycle(model, 'forceDelete', 'purged', (client) =>\n      SoftDeleteContext.run({ filterMode: 'default', skipSoftDelete: true }, async () => {\n        const key = model.charAt(0).toLowerCase() + model.slice(1);\n        return client[key].delete({ where }) as T;\n      }),\n    );\n  }\n\n  /**\n   * Permanently delete soft-deleted records older than the specified date.\n   * Runs within skipSoftDelete context so the extension does not intercept the deleteMany.\n   */\n  async purge(\n    model: string,\n    options: { olderThan: Date; where?: Record<string, any> },\n  ): Promise<{ count: number }> {\n    const { olderThan, where: extraWhere } = options;\n\n    const result = await this.runLifecycle(model, 'purge', 'purged', (client) =>\n      SoftDeleteContext.run({ filterMode: 'default', skipSoftDelete: true }, async () => {\n        const key = model.charAt(0).toLowerCase() + model.slice(1);\n        return client[key].deleteMany({\n          where: {\n            ...extraWhere,\n            [this.deletedAtField]: { not: null, lt: olderThan },\n          },\n        });\n      }),\n    );\n\n    if (result.count > 0) {\n      this.eventEmitter?.emitPurged(new PurgedEvent(model, result.count, olderThan));\n    }\n\n    return result;\n  }\n\n  /**\n   * Execute a callback where all queries include soft-deleted records.\n   */\n  async withDeleted<T>(callback: () => T | Promise<T>): Promise<T> {\n    return SoftDeleteContext.run({ filterMode: 'withDeleted', skipSoftDelete: false }, callback);\n  }\n\n  /**\n   * Execute a callback where only soft-deleted records are returned.\n   */\n  async onlyDeleted<T>(callback: () => T | Promise<T>): Promise<T> {\n    return SoftDeleteContext.run({ filterMode: 'onlyDeleted', skipSoftDelete: false }, callback);\n  }\n}\n","export class CascadeRelationNotFoundError extends Error {\n  constructor(parent: string, child: string) {\n    super(\n      `Cannot find a relation from \"${child}\" to \"${parent}\" in Prisma DMMF. ` +\n      `Ensure \"${child}\" has a @relation field pointing to \"${parent}\".`,\n    );\n    this.name = 'CascadeRelationNotFoundError';\n  }\n}\n","import type { PrismaDmmfLike } from '../interfaces/soft-delete-options.interface';\nimport { CascadeRelationNotFoundError } from '../errors/cascade-relation-not-found.error';\n\nexport interface CascadeHandlerOptions {\n  cascade: Record<string, string[]>;\n  deletedAtField: string;\n  deletedByField?: string | null;\n  maxCascadeDepth: number;\n  dmmf: PrismaDmmfLike;\n}\n\nexport type CascadeLifecycleRunner = <T>(\n  model: string,\n  callback: (client: any) => Promise<T>,\n) => Promise<T>;\n\n/**\n * Handles cascading soft-delete and restore operations by walking\n * the cascade graph defined in the module options and using Prisma\n * DMMF metadata to resolve foreign-key relationships.\n */\nexport class CascadeHandler {\n  private readonly cascade: Record<string, string[]>;\n  private readonly deletedAtField: string;\n  private readonly maxCascadeDepth: number;\n  private readonly dmmf: PrismaDmmfLike;\n  private readonly fkCache = new Map<string, string>();\n\n  constructor(options: CascadeHandlerOptions) {\n    this.cascade = options.cascade;\n    this.deletedAtField = options.deletedAtField;\n    this.maxCascadeDepth = options.maxCascadeDepth;\n    this.dmmf = options.dmmf;\n  }\n\n  /**\n   * Finds the primary key field name for a given model by inspecting the\n   * Prisma DMMF datamodel. Falls back to 'id' if the model or PK is not found.\n   */\n  findPrimaryKey(model: string): string {\n    const modelDef = this.dmmf.datamodel.models.find((m: any) => m.name === model);\n    const pkField = modelDef?.fields.find((f: any) => f.isId);\n    return pkField?.name ?? 'id';\n  }\n\n  /**\n   * Finds the foreign key field on the child model that references the parent model\n   * by inspecting the Prisma DMMF datamodel. Results are cached for performance.\n   *\n   * @throws CascadeRelationNotFoundError if no relation from child to parent exists\n   */\n  findForeignKey(parent: string, child: string): string {\n    const cacheKey = `${parent}:${child}`;\n    const cached = this.fkCache.get(cacheKey);\n    if (cached) {\n      return cached;\n    }\n\n    const childModel = this.dmmf.datamodel.models.find((m: any) => m.name === child);\n\n    if (!childModel) {\n      throw new CascadeRelationNotFoundError(parent, child);\n    }\n\n    for (const field of childModel.fields) {\n      if (\n        field.kind === 'object' &&\n        field.type === parent &&\n        field.relationFromFields &&\n        field.relationFromFields.length > 0\n      ) {\n        const fk = field.relationFromFields[0];\n        this.fkCache.set(cacheKey, fk);\n        return fk;\n      }\n    }\n\n    throw new CascadeRelationNotFoundError(parent, child);\n  }\n\n  /**\n   * Cascades a soft-delete from a parent record to all configured child models.\n   * Recursively walks the cascade graph up to maxCascadeDepth.\n   */\n  async cascadeSoftDelete(\n    prisma: any,\n    parentModel: string,\n    parentId: unknown,\n    deletedAt: Date,\n    depth: number,\n    lifecycle?: CascadeLifecycleRunner,\n  ): Promise<void> {\n    if (depth >= this.maxCascadeDepth) {\n      return;\n    }\n\n    const children = this.cascade[parentModel];\n    if (!children || children.length === 0) {\n      return;\n    }\n\n    for (const childModel of children) {\n      const fk = this.findForeignKey(parentModel, childModel);\n      const childKey = childModel.charAt(0).toLowerCase() + childModel.slice(1);\n      const pkField = this.findPrimaryKey(childModel);\n\n      if (!lifecycle) {\n        await prisma[childKey].updateMany({\n          where: {\n            [fk]: parentId,\n            [this.deletedAtField]: null,\n          },\n          data: {\n            [this.deletedAtField]: deletedAt,\n          },\n        });\n        const affectedChildren = await prisma[childKey].findMany({\n          where: { [fk]: parentId, [this.deletedAtField]: deletedAt },\n          select: { [pkField]: true },\n        });\n        for (const child of affectedChildren) {\n          await this.cascadeSoftDelete(prisma, childModel, child[pkField], deletedAt, depth + 1);\n        }\n        continue;\n      }\n\n      const affectedChildren = await prisma[childKey].findMany({\n        where: { [fk]: parentId, [this.deletedAtField]: null },\n        select: { [pkField]: true },\n      });\n\n      for (const child of affectedChildren) {\n        const data: Record<string, unknown> = {\n          [this.deletedAtField]: deletedAt,\n        };\n        const update = (mutationClient: any) =>\n          mutationClient[childKey].update({\n            where: {\n              [pkField]: child[pkField],\n              [fk]: parentId,\n              [this.deletedAtField]: null,\n            },\n            data,\n          });\n        await lifecycle(childModel, update);\n        await this.cascadeSoftDelete(\n          prisma,\n          childModel,\n          child[pkField],\n          deletedAt,\n          depth + 1,\n          lifecycle,\n        );\n      }\n    }\n  }\n\n  /**\n   * Cascades a restore from a parent record to all configured child models.\n   * Uses +/-1 second timestamp matching to find children that were soft-deleted\n   * at approximately the same time as the parent.\n   */\n  async cascadeRestore(\n    prisma: any,\n    parentModel: string,\n    parentId: unknown,\n    deletedAt: Date,\n    depth: number,\n    lifecycle?: CascadeLifecycleRunner,\n  ): Promise<void> {\n    if (depth >= this.maxCascadeDepth) {\n      return;\n    }\n\n    const children = this.cascade[parentModel];\n    if (!children || children.length === 0) {\n      return;\n    }\n\n    const lowerBound = new Date(deletedAt.getTime() - 1000);\n    const upperBound = new Date(deletedAt.getTime() + 1000);\n\n    for (const childModel of children) {\n      const fk = this.findForeignKey(parentModel, childModel);\n      const childKey = childModel.charAt(0).toLowerCase() + childModel.slice(1);\n      const pkField = this.findPrimaryKey(childModel);\n\n      // Find affected children BEFORE restoring (to capture their deletedAt for recursion)\n      const affectedChildren = await prisma[childKey].findMany({\n        where: {\n          [fk]: parentId,\n          [this.deletedAtField]: {\n            gte: lowerBound,\n            lte: upperBound,\n          },\n        },\n        select: { [pkField]: true, [this.deletedAtField]: true },\n      });\n\n      if (!lifecycle) {\n        await prisma[childKey].updateMany({\n          where: {\n            [fk]: parentId,\n            [this.deletedAtField]: {\n              gte: lowerBound,\n              lte: upperBound,\n            },\n          },\n          data: {\n            [this.deletedAtField]: null,\n          },\n        });\n        for (const child of affectedChildren) {\n          await this.cascadeRestore(\n            prisma,\n            childModel,\n            child[pkField],\n            child[this.deletedAtField],\n            depth + 1,\n          );\n        }\n        continue;\n      }\n\n      // Recurse for each affected child with its original deletedAt\n      for (const child of affectedChildren) {\n        const data: Record<string, unknown> = {\n          [this.deletedAtField]: null,\n        };\n        const update = (mutationClient: any) =>\n          mutationClient[childKey].update({\n            where: {\n              [pkField]: child[pkField],\n              [fk]: parentId,\n              [this.deletedAtField]: child[this.deletedAtField],\n            },\n            data,\n          });\n        await lifecycle(childModel, update);\n        await this.cascadeRestore(\n          prisma,\n          childModel,\n          child[pkField],\n          child[this.deletedAtField],\n          depth + 1,\n          lifecycle,\n        );\n      }\n    }\n  }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { SoftDeleteFilterMode, SoftDeleteStore } from '../interfaces/soft-delete-context.interface';\n\nexport class SoftDeleteContext {\n  private static storage = new AsyncLocalStorage<SoftDeleteStore>();\n\n  /**\n   * Runs a callback within the given soft-delete context store.\n   *\n   * Supports both synchronous and asynchronous callbacks. When the callback\n   * returns a Promise (e.g. a Prisma query), the context is preserved\n   * throughout the entire async chain — including inside Prisma extension\n   * handlers whose internal Promise implementation may not propagate\n   * AsyncLocalStorage context on its own.\n   */\n  static run<T>(store: SoftDeleteStore, callback: () => T): T {\n    return this.storage.run(store, () => {\n      const result = callback();\n      // If the callback returns a thenable (Promise), wrap it so the\n      // continuation executes inside the same AsyncLocalStorage context.\n      // Prisma's internal query-engine Promises may not propagate the\n      // Node.js async context, so we re-enter via an async IIFE that\n      // keeps the store active for every `await` in the chain.\n      if (result != null && typeof (result as any).then === 'function') {\n        return new Promise<any>((resolve, reject) => {\n          (result as any).then(\n            (val: any) => resolve(val),\n            (err: any) => reject(err),\n          );\n        }) as any as T;\n      }\n      return result;\n    });\n  }\n\n  static getFilterMode(): SoftDeleteFilterMode {\n    return this.storage.getStore()?.filterMode ?? 'default';\n  }\n\n  static isSkipped(): boolean {\n    return this.storage.getStore()?.skipSoftDelete ?? false;\n  }\n\n  static getActorId(): string | null {\n    return this.storage.getStore()?.actorId ?? null;\n  }\n\n  static getWithDeletedRelationPaths(): string[] {\n    return this.storage.getStore()?.withDeletedRelationPaths ?? [];\n  }\n\n  static isWithDeletedRelationPath(path: string): boolean {\n    return this.getWithDeletedRelationPaths().includes(path);\n  }\n}\n","import { Injectable, Optional, Inject } from '@nestjs/common';\nimport { SoftDeletedEvent } from './soft-delete.events';\nimport { RestoredEvent } from './soft-delete.events';\nimport { PurgedEvent } from './soft-delete.events';\n\nlet registeredSoftDeleteEventEmitter: SoftDeleteEventEmitter | null = null;\n\nfunction registerSoftDeleteEventEmitter(instance: SoftDeleteEventEmitter): void {\n  registeredSoftDeleteEventEmitter = instance;\n}\n\nexport function getRegisteredSoftDeleteEventEmitter(): SoftDeleteEventEmitter | null {\n  return registeredSoftDeleteEventEmitter;\n}\n\nexport function resetRegisteredSoftDeleteEventEmitter(): void {\n  registeredSoftDeleteEventEmitter = null;\n}\n\n@Injectable()\nexport class SoftDeleteEventEmitter {\n  constructor(\n    @Optional() @Inject('EventEmitter2') private readonly eventEmitter: any | null,\n  ) {\n    if (this.eventEmitter) {\n      registerSoftDeleteEventEmitter(this);\n    }\n  }\n\n  get isEnabled(): boolean {\n    return this.eventEmitter != null;\n  }\n\n  emitSoftDeleted(event: SoftDeletedEvent): void {\n    this.eventEmitter?.emit(SoftDeletedEvent.EVENT_NAME, event);\n  }\n\n  emitRestored(event: RestoredEvent): void {\n    this.eventEmitter?.emit(RestoredEvent.EVENT_NAME, event);\n  }\n\n  emitPurged(event: PurgedEvent): void {\n    this.eventEmitter?.emit(PurgedEvent.EVENT_NAME, event);\n  }\n}\n","export class SoftDeletedEvent {\n  static readonly EVENT_NAME = 'soft-delete.deleted' as const;\n\n  constructor(\n    public readonly model: string,\n    public readonly where: Record<string, unknown>,\n    public readonly deletedAt: Date,\n    public readonly actorId: string | null = null,\n    public readonly count?: number,\n  ) {}\n}\n\nexport class RestoredEvent {\n  static readonly EVENT_NAME = 'soft-delete.restored' as const;\n\n  constructor(\n    public readonly model: string,\n    public readonly where: Record<string, unknown>,\n    public readonly actorId: string | null = null,\n    public readonly count?: number,\n  ) {}\n}\n\nexport class PurgedEvent {\n  static readonly EVENT_NAME = 'soft-delete.purged' as const;\n\n  constructor(\n    public readonly model: string,\n    public readonly count: number,\n    public readonly olderThan: Date,\n  ) {}\n}\n","import type {\n  SoftDeleteExtensionOptions,\n  SoftDeleteModuleOptions,\n} from '../interfaces/soft-delete-options.interface';\n\nexport const DEFAULT_AUDIT_MAX_BATCH_RECORDS = 1000;\n\ntype AuditLifecycleOptions = Pick<\n  SoftDeleteExtensionOptions | SoftDeleteModuleOptions,\n  'auditLifecycle' | 'auditMaxBatchRecords'\n>;\n\ninterface AuditLifecycleClient {\n  getAuditCapabilities(): {\n    consistency: string;\n    atomicLifecycle: boolean;\n  };\n  withAuditLifecycle<T>(\n    input: {\n      action: string;\n      metadata?: Record<string, unknown>;\n      suppressOuterOperation?: {\n        model: string;\n        operation: 'delete' | 'deleteMany';\n      };\n    },\n    callback: (tx: any) => Promise<T>,\n  ): Promise<T>;\n}\n\nexport function validateAuditLifecycleOptions(options: AuditLifecycleOptions): void {\n  if (options.auditLifecycle !== undefined && options.auditLifecycle !== 'atomic-required') {\n    throw new Error(\n      '[@nestarc/soft-delete] auditLifecycle must be \"atomic-required\" when provided',\n    );\n  }\n\n  if (\n    options.auditMaxBatchRecords !== undefined &&\n    (!Number.isInteger(options.auditMaxBatchRecords) || options.auditMaxBatchRecords < 1)\n  ) {\n    throw new Error('[@nestarc/soft-delete] auditMaxBatchRecords must be a positive integer');\n  }\n}\n\nexport function requireAuditLifecycleClient(client: any): AuditLifecycleClient {\n  if (typeof client?.withAuditLifecycle !== 'function') {\n    throw new Error(\n      '[@nestarc/soft-delete] auditLifecycle: \"atomic-required\" requires the extension order tenancy -> audit-log -> soft-delete and execution inside withAuditTransaction()',\n    );\n  }\n  if (typeof client?.getAuditCapabilities !== 'function') {\n    throw new Error(\n      '[@nestarc/soft-delete] auditLifecycle: \"atomic-required\" requires @nestarc/audit-log >=0.4.1 with atomic lifecycle capabilities',\n    );\n  }\n  const capabilities = client.getAuditCapabilities();\n  if (capabilities?.consistency !== 'atomic-required' || capabilities?.atomicLifecycle !== true) {\n    throw new Error(\n      '[@nestarc/soft-delete] auditLifecycle: \"atomic-required\" requires audit-log consistency: \"atomic-required\"',\n    );\n  }\n  return client as AuditLifecycleClient;\n}\n\nexport async function runAuditLifecycle<T>(\n  client: any,\n  options: AuditLifecycleOptions,\n  model: string,\n  operation: string,\n  action: 'softDeleted' | 'restored' | 'purged',\n  callback: (mutationClient: any) => Promise<T>,\n  suppressOuterOperation?: 'delete' | 'deleteMany',\n): Promise<T> {\n  if (options.auditLifecycle !== 'atomic-required') {\n    return callback(client);\n  }\n\n  return requireAuditLifecycleClient(client).withAuditLifecycle(\n    {\n      action: `${model}.${action}`,\n      metadata: {\n        auditKind: 'record',\n        lifecycle: 'soft-delete',\n        lifecycleOperation: operation,\n      },\n      ...(suppressOuterOperation\n        ? { suppressOuterOperation: { model, operation: suppressOuterOperation } }\n        : {}),\n    },\n    callback,\n  );\n}\n","import { SoftDeleteContext } from '../services/soft-delete-context';\n\nexport async function expectSoftDeleted(\n  modelDelegate: any,\n  where: Record<string, any>,\n  deletedAtField = 'deletedAt',\n): Promise<void> {\n  const record = await SoftDeleteContext.run(\n    { filterMode: 'withDeleted', skipSoftDelete: false },\n    () => modelDelegate.findFirst({ where }),\n  );\n\n  if (!record) {\n    throw new Error(`Expected record to exist (soft-deleted), but it was not found`);\n  }\n\n  if (record[deletedAtField] === null || record[deletedAtField] === undefined) {\n    throw new Error(\n      `Expected record to be soft-deleted (${deletedAtField} should be non-null), but ${deletedAtField} is ${record[deletedAtField]}`,\n    );\n  }\n}\n\nexport async function expectNotSoftDeleted(\n  modelDelegate: any,\n  where: Record<string, any>,\n  deletedAtField = 'deletedAt',\n): Promise<void> {\n  const record = await modelDelegate.findFirst({ where });\n\n  if (!record) {\n    throw new Error(`Expected record to exist (not soft-deleted), but it was not found`);\n  }\n\n  if (record[deletedAtField] !== null && record[deletedAtField] !== undefined) {\n    throw new Error(\n      `Expected record to NOT be soft-deleted (${deletedAtField} should be null), but ${deletedAtField} is ${record[deletedAtField]}`,\n    );\n  }\n}\n\nexport async function expectCascadeSoftDeleted(\n  prisma: any,\n  parentModel: string,\n  where: Record<string, any>,\n  childModels: string[],\n  deletedAtField = 'deletedAt',\n): Promise<void> {\n  const parentKey = parentModel.charAt(0).toLowerCase() + parentModel.slice(1);\n  await expectSoftDeleted(prisma[parentKey], where, deletedAtField);\n\n  for (const childModel of childModels) {\n    const childKey = childModel.charAt(0).toLowerCase() + childModel.slice(1);\n    const deletedChildren = await SoftDeleteContext.run(\n      { filterMode: 'onlyDeleted', skipSoftDelete: false },\n      () => prisma[childKey].findMany({ where: { [deletedAtField]: { not: null } } }),\n    );\n\n    if (deletedChildren.length === 0) {\n      throw new Error(\n        `Expected \"${childModel}\" to have cascade soft-deleted records, but found none`,\n      );\n    }\n  }\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAwB,cAAc;;;ACA/B,IAAM,6BAA6B,uBAAO,4BAA4B;AACtE,IAAM,6BAA6B,uBAAO,4BAA4B;;;ACD7E,SAAS,UAAAA,SAAQ,cAAAC,aAAY,YAAAC,iBAAgB;;;ACAtC,IAAM,+BAAN,cAA2C,MAAM;AAAA,EACtD,YAAY,QAAgB,OAAe;AACzC;AAAA,MACE,gCAAgC,KAAK,SAAS,MAAM,6BACzC,KAAK,wCAAwC,MAAM;AAAA,IAChE;AACA,SAAK,OAAO;AAAA,EACd;AACF;;;ACaO,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,oBAAI,IAAoB;AAAA,EAEnD,YAAY,SAAgC;AAC1C,SAAK,UAAU,QAAQ;AACvB,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,kBAAkB,QAAQ;AAC/B,SAAK,OAAO,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,OAAuB;AACpC,UAAM,WAAW,KAAK,KAAK,UAAU,OAAO,KAAK,CAAC,MAAW,EAAE,SAAS,KAAK;AAC7E,UAAM,UAAU,UAAU,OAAO,KAAK,CAAC,MAAW,EAAE,IAAI;AACxD,WAAO,SAAS,QAAQ;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAe,QAAgB,OAAuB;AACpD,UAAM,WAAW,GAAG,MAAM,IAAI,KAAK;AACnC,UAAM,SAAS,KAAK,QAAQ,IAAI,QAAQ;AACxC,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,KAAK,KAAK,UAAU,OAAO,KAAK,CAAC,MAAW,EAAE,SAAS,KAAK;AAE/E,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,6BAA6B,QAAQ,KAAK;AAAA,IACtD;AAEA,eAAW,SAAS,WAAW,QAAQ;AACrC,UACE,MAAM,SAAS,YACf,MAAM,SAAS,UACf,MAAM,sBACN,MAAM,mBAAmB,SAAS,GAClC;AACA,cAAM,KAAK,MAAM,mBAAmB,CAAC;AACrC,aAAK,QAAQ,IAAI,UAAU,EAAE;AAC7B,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,IAAI,6BAA6B,QAAQ,KAAK;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBACJ,QACA,aACA,UACA,WACA,OACA,WACe;AACf,QAAI,SAAS,KAAK,iBAAiB;AACjC;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,QAAQ,WAAW;AACzC,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC;AAAA,IACF;AAEA,eAAW,cAAc,UAAU;AACjC,YAAM,KAAK,KAAK,eAAe,aAAa,UAAU;AACtD,YAAM,WAAW,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,WAAW,MAAM,CAAC;AACxE,YAAM,UAAU,KAAK,eAAe,UAAU;AAE9C,UAAI,CAAC,WAAW;AACd,cAAM,OAAO,QAAQ,EAAE,WAAW;AAAA,UAChC,OAAO;AAAA,YACL,CAAC,EAAE,GAAG;AAAA,YACN,CAAC,KAAK,cAAc,GAAG;AAAA,UACzB;AAAA,UACA,MAAM;AAAA,YACJ,CAAC,KAAK,cAAc,GAAG;AAAA,UACzB;AAAA,QACF,CAAC;AACD,cAAMC,oBAAmB,MAAM,OAAO,QAAQ,EAAE,SAAS;AAAA,UACvD,OAAO,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,cAAc,GAAG,UAAU;AAAA,UAC1D,QAAQ,EAAE,CAAC,OAAO,GAAG,KAAK;AAAA,QAC5B,CAAC;AACD,mBAAW,SAASA,mBAAkB;AACpC,gBAAM,KAAK,kBAAkB,QAAQ,YAAY,MAAM,OAAO,GAAG,WAAW,QAAQ,CAAC;AAAA,QACvF;AACA;AAAA,MACF;AAEA,YAAM,mBAAmB,MAAM,OAAO,QAAQ,EAAE,SAAS;AAAA,QACvD,OAAO,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,cAAc,GAAG,KAAK;AAAA,QACrD,QAAQ,EAAE,CAAC,OAAO,GAAG,KAAK;AAAA,MAC5B,CAAC;AAED,iBAAW,SAAS,kBAAkB;AACpC,cAAM,OAAgC;AAAA,UACpC,CAAC,KAAK,cAAc,GAAG;AAAA,QACzB;AACA,cAAM,SAAS,CAAC,mBACd,eAAe,QAAQ,EAAE,OAAO;AAAA,UAC9B,OAAO;AAAA,YACL,CAAC,OAAO,GAAG,MAAM,OAAO;AAAA,YACxB,CAAC,EAAE,GAAG;AAAA,YACN,CAAC,KAAK,cAAc,GAAG;AAAA,UACzB;AAAA,UACA;AAAA,QACF,CAAC;AACH,cAAM,UAAU,YAAY,MAAM;AAClC,cAAM,KAAK;AAAA,UACT;AAAA,UACA;AAAA,UACA,MAAM,OAAO;AAAA,UACb;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eACJ,QACA,aACA,UACA,WACA,OACA,WACe;AACf,QAAI,SAAS,KAAK,iBAAiB;AACjC;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,QAAQ,WAAW;AACzC,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC;AAAA,IACF;AAEA,UAAM,aAAa,IAAI,KAAK,UAAU,QAAQ,IAAI,GAAI;AACtD,UAAM,aAAa,IAAI,KAAK,UAAU,QAAQ,IAAI,GAAI;AAEtD,eAAW,cAAc,UAAU;AACjC,YAAM,KAAK,KAAK,eAAe,aAAa,UAAU;AACtD,YAAM,WAAW,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,WAAW,MAAM,CAAC;AACxE,YAAM,UAAU,KAAK,eAAe,UAAU;AAG9C,YAAM,mBAAmB,MAAM,OAAO,QAAQ,EAAE,SAAS;AAAA,QACvD,OAAO;AAAA,UACL,CAAC,EAAE,GAAG;AAAA,UACN,CAAC,KAAK,cAAc,GAAG;AAAA,YACrB,KAAK;AAAA,YACL,KAAK;AAAA,UACP;AAAA,QACF;AAAA,QACA,QAAQ,EAAE,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,cAAc,GAAG,KAAK;AAAA,MACzD,CAAC;AAED,UAAI,CAAC,WAAW;AACd,cAAM,OAAO,QAAQ,EAAE,WAAW;AAAA,UAChC,OAAO;AAAA,YACL,CAAC,EAAE,GAAG;AAAA,YACN,CAAC,KAAK,cAAc,GAAG;AAAA,cACrB,KAAK;AAAA,cACL,KAAK;AAAA,YACP;AAAA,UACF;AAAA,UACA,MAAM;AAAA,YACJ,CAAC,KAAK,cAAc,GAAG;AAAA,UACzB;AAAA,QACF,CAAC;AACD,mBAAW,SAAS,kBAAkB;AACpC,gBAAM,KAAK;AAAA,YACT;AAAA,YACA;AAAA,YACA,MAAM,OAAO;AAAA,YACb,MAAM,KAAK,cAAc;AAAA,YACzB,QAAQ;AAAA,UACV;AAAA,QACF;AACA;AAAA,MACF;AAGA,iBAAW,SAAS,kBAAkB;AACpC,cAAM,OAAgC;AAAA,UACpC,CAAC,KAAK,cAAc,GAAG;AAAA,QACzB;AACA,cAAM,SAAS,CAAC,mBACd,eAAe,QAAQ,EAAE,OAAO;AAAA,UAC9B,OAAO;AAAA,YACL,CAAC,OAAO,GAAG,MAAM,OAAO;AAAA,YACxB,CAAC,EAAE,GAAG;AAAA,YACN,CAAC,KAAK,cAAc,GAAG,MAAM,KAAK,cAAc;AAAA,UAClD;AAAA,UACA;AAAA,QACF,CAAC;AACH,cAAM,UAAU,YAAY,MAAM;AAClC,cAAM,KAAK;AAAA,UACT;AAAA,UACA;AAAA,UACA,MAAM,OAAO;AAAA,UACb,MAAM,KAAK,cAAc;AAAA,UACzB,QAAQ;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC1PA,SAAS,yBAAyB;AAG3B,IAAM,oBAAN,MAAwB;AAAA,EAC7B,OAAe,UAAU,IAAI,kBAAmC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWhE,OAAO,IAAO,OAAwB,UAAsB;AAC1D,WAAO,KAAK,QAAQ,IAAI,OAAO,MAAM;AACnC,YAAM,SAAS,SAAS;AAMxB,UAAI,UAAU,QAAQ,OAAQ,OAAe,SAAS,YAAY;AAChE,eAAO,IAAI,QAAa,CAAC,SAAS,WAAW;AAC3C,UAAC,OAAe;AAAA,YACd,CAAC,QAAa,QAAQ,GAAG;AAAA,YACzB,CAAC,QAAa,OAAO,GAAG;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,gBAAsC;AAC3C,WAAO,KAAK,QAAQ,SAAS,GAAG,cAAc;AAAA,EAChD;AAAA,EAEA,OAAO,YAAqB;AAC1B,WAAO,KAAK,QAAQ,SAAS,GAAG,kBAAkB;AAAA,EACpD;AAAA,EAEA,OAAO,aAA4B;AACjC,WAAO,KAAK,QAAQ,SAAS,GAAG,WAAW;AAAA,EAC7C;AAAA,EAEA,OAAO,8BAAwC;AAC7C,WAAO,KAAK,QAAQ,SAAS,GAAG,4BAA4B,CAAC;AAAA,EAC/D;AAAA,EAEA,OAAO,0BAA0B,MAAuB;AACtD,WAAO,KAAK,4BAA4B,EAAE,SAAS,IAAI;AAAA,EACzD;AACF;;;ACtDA,SAAS,YAAY,UAAU,cAAc;;;ACAtC,IAAM,mBAAN,MAAuB;AAAA,EAG5B,YACkB,OACA,OACA,WACA,UAAyB,MACzB,OAChB;AALgB;AACA;AACA;AACA;AACA;AAAA,EACf;AAAA,EALe;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAPlB,OAAgB,aAAa;AAS/B;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAGzB,YACkB,OACA,OACA,UAAyB,MACzB,OAChB;AAJgB;AACA;AACA;AACA;AAAA,EACf;AAAA,EAJe;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EANlB,OAAgB,aAAa;AAQ/B;AAEO,IAAM,cAAN,MAAkB;AAAA,EAGvB,YACkB,OACA,OACA,WAChB;AAHgB;AACA;AACA;AAAA,EACf;AAAA,EAHe;AAAA,EACA;AAAA,EACA;AAAA,EALlB,OAAgB,aAAa;AAO/B;;;AD1BA,IAAI,mCAAkE;AAEtE,SAAS,+BAA+B,UAAwC;AAC9E,qCAAmC;AACrC;AAWO,IAAM,yBAAN,MAA6B;AAAA,EAClC,YACwD,cACtD;AADsD;AAEtD,QAAI,KAAK,cAAc;AACrB,qCAA+B,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EALwD;AAAA,EAOxD,IAAI,YAAqB;AACvB,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AAAA,EAEA,gBAAgB,OAA+B;AAC7C,SAAK,cAAc,KAAK,iBAAiB,YAAY,KAAK;AAAA,EAC5D;AAAA,EAEA,aAAa,OAA4B;AACvC,SAAK,cAAc,KAAK,cAAc,YAAY,KAAK;AAAA,EACzD;AAAA,EAEA,WAAW,OAA0B;AACnC,SAAK,cAAc,KAAK,YAAY,YAAY,KAAK;AAAA,EACvD;AACF;AAxBa,yBAAN;AAAA,EADN,WAAW;AAAA,EAGP,4BAAS;AAAA,EAAG,0BAAO,eAAe;AAAA,GAF1B;;;AEfN,IAAM,kCAAkC;AAyBxC,SAAS,8BAA8B,SAAsC;AAClF,MAAI,QAAQ,mBAAmB,UAAa,QAAQ,mBAAmB,mBAAmB;AACxF,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,MACE,QAAQ,yBAAyB,WAChC,CAAC,OAAO,UAAU,QAAQ,oBAAoB,KAAK,QAAQ,uBAAuB,IACnF;AACA,UAAM,IAAI,MAAM,wEAAwE;AAAA,EAC1F;AACF;AAEO,SAAS,4BAA4B,QAAmC;AAC7E,MAAI,OAAO,QAAQ,uBAAuB,YAAY;AACpD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,QAAQ,yBAAyB,YAAY;AACtD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,eAAe,OAAO,qBAAqB;AACjD,MAAI,cAAc,gBAAgB,qBAAqB,cAAc,oBAAoB,MAAM;AAC7F,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,kBACpB,QACA,SACA,OACA,WACA,QACA,UACA,wBACY;AACZ,MAAI,QAAQ,mBAAmB,mBAAmB;AAChD,WAAO,SAAS,MAAM;AAAA,EACxB;AAEA,SAAO,4BAA4B,MAAM,EAAE;AAAA,IACzC;AAAA,MACE,QAAQ,GAAG,KAAK,IAAI,MAAM;AAAA,MAC1B,UAAU;AAAA,QACR,WAAW;AAAA,QACX,WAAW;AAAA,QACX,oBAAoB;AAAA,MACtB;AAAA,MACA,GAAI,yBACA,EAAE,wBAAwB,EAAE,OAAO,WAAW,uBAAuB,EAAE,IACvE,CAAC;AAAA,IACP;AAAA,IACA;AAAA,EACF;AACF;;;AN9EO,IAAM,oBAAN,MAAwB;AAAA,EAI7B,YACuD,SACA,QACA,gBAGpC,cACjB;AANqD;AACA;AACA;AAGpC;AAEjB,kCAA8B,OAAO;AACrC,SAAK,iBAAiB,QAAQ,kBAAkB;AAChD,SAAK,iBAAiB,QAAQ,kBAAkB;AAAA,EAClD;AAAA,EAVuD;AAAA,EACA;AAAA,EACA;AAAA,EAGpC;AAAA,EATF;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBT,iBAAiB,OAAoB;AAC3C,UAAM,MAAM,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AACzD,WAAO,KAAK,OAAO,GAAG;AAAA,EACxB;AAAA,EAEQ,mBAAwC;AAC9C,UAAM,OAA4B;AAAA,MAChC,CAAC,KAAK,cAAc,GAAG;AAAA,IACzB;AACA,QAAI,KAAK,gBAAgB;AACvB,WAAK,KAAK,cAAc,IAAI;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,OAA6D;AACrF,WAAO;AAAA,MACL,GAAI,SAAS,CAAC;AAAA,MACd,CAAC,KAAK,cAAc,GAAG,EAAE,KAAK,KAAK;AAAA,IACrC;AAAA,EACF;AAAA,EAEQ,eAAe,OAAuB;AAC5C,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK,eAAe,eAAe,KAAK;AAAA,IACjD;AAEA,UAAM,WAAW,KAAK,QAAQ,MAAM,UAAU,OAAO;AAAA,MACnD,CAAC,cAAmB,UAAU,SAAS;AAAA,IACzC;AACA,UAAM,UAAU,UAAU,OAAO,KAAK,CAAC,UAAe,MAAM,IAAI;AAChE,WAAO,SAAS,QAAQ;AAAA,EAC1B;AAAA,EAEA,MAAc,aACZ,OACA,WACA,QACA,UACY;AACZ,WAAO,kBAAkB,KAAK,QAAQ,KAAK,SAAS,OAAO,WAAW,QAAQ,QAAQ;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAiB,OAAe,OAAwC;AAC5E,UAAM,WAAW,MAAM,KAAK;AAAA,MAAa;AAAA,MAAO;AAAA,MAAW;AAAA,MAAY,CAAC,WACtE,kBAAkB;AAAA,QAChB;AAAA,UACE,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,SAAS,kBAAkB,WAAW;AAAA,QACxC;AAAA,QACA,YAAY;AACV,gBAAM,WAAW,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AAC9D,gBAAM,WAAW,OAAO,QAAQ;AAChC,gBAAM,eAAe,KAAK,kBAAkB,KAAK;AACjD,gBAAM,SAAS,MAAM,SAAS,UAAU,EAAE,OAAO,aAAa,CAAC;AAC/D,cAAI,CAAC,QAAQ;AACX,kBAAM,IAAI;AAAA,cACR,+BAA+B,KAAK,gBAAgB,KAAK,UAAU,KAAK,CAAC;AAAA,YAC3E;AAAA,UACF;AACA,gBAAM,YAAY,OAAO,KAAK,cAAc;AAC5C,gBAAM,SAAS,MAAM,SAAS,OAAO;AAAA,YACnC,OAAO;AAAA,cACL,GAAG;AAAA,cACH,CAAC,KAAK,cAAc,GAAG;AAAA,YACzB;AAAA,YACA,MAAM,KAAK,iBAAiB;AAAA,UAC9B,CAAC;AACD,cAAI,KAAK,kBAAkB,WAAW;AACpC,kBAAM,UAAU,KAAK,eAAe,eAAe,KAAK;AACxD,kBAAM,KAAK,eAAe;AAAA,cACxB;AAAA,cACA;AAAA,cACA,OAAO,OAAO;AAAA,cACd;AAAA,cACA;AAAA,cACA,KAAK,QAAQ,mBAAmB,oBAC5B,CAAC,YAAY,aACX,KAAK,aAAa,YAAY,kBAAkB,YAAY,QAAQ,IACtE;AAAA,YACN;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,SAAK,cAAc;AAAA,MACjB,IAAI,cAAc,OAAO,OAAO,kBAAkB,WAAW,CAAC;AAAA,IAChE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YACJ,OACA,UAA2C,CAAC,GAChB;AAC5B,UAAM,WAAW,KAAK,iBAAiB,KAAK;AAC5C,UAAM,QAAQ,QAAQ,SAAS,CAAC;AAChC,UAAM,eAAe,KAAK,kBAAkB,KAAK;AACjD,UAAM,OAAO,KAAK,iBAAiB;AAEnC,QAAI,KAAK,QAAQ,mBAAmB,mBAAmB;AACrD,YAAM,aAAa,KAAK,QAAQ,wBAAwB;AACxD,YAAMC,UAAS,MAAM,KAAK;AAAA,QAAa;AAAA,QAAO;AAAA,QAAe;AAAA,QAAY,CAAC,WACxE,kBAAkB;AAAA,UAChB;AAAA,YACE,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,SAAS,kBAAkB,WAAW;AAAA,UACxC;AAAA,UACA,YAAY;AACV,kBAAM,MAAM,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AACzD,kBAAMC,YAAW,OAAO,GAAG;AAC3B,kBAAM,UAAU,MAAMA,UAAS,SAAS;AAAA,cACtC,OAAO;AAAA,cACP,MAAM,aAAa;AAAA,YACrB,CAAC;AACD,gBAAI,QAAQ,SAAS,YAAY;AAC/B,oBAAM,IAAI;AAAA,gBACR,0BAA0B,KAAK,8CAA8C,UAAU;AAAA,cACzF;AAAA,YACF;AACA,kBAAMC,WAAU,KAAK,eAAe,KAAK;AACzC,uBAAW,UAAU,SAAS;AAC5B,oBAAMD,UAAS,OAAO;AAAA,gBACpB,OAAO;AAAA,kBACL,GAAG;AAAA,kBACH,CAACC,QAAO,GAAG,OAAOA,QAAO;AAAA,kBACzB,CAAC,KAAK,cAAc,GAAG,OAAO,KAAK,cAAc;AAAA,gBACnD;AAAA,gBACA;AAAA,cACF,CAAC;AACD,oBAAM,YAAY,OAAO,KAAK,cAAc;AAC5C,kBAAI,KAAK,kBAAkB,WAAW;AACpC,sBAAM,KAAK,eAAe;AAAA,kBACxB;AAAA,kBACA;AAAA,kBACA,OAAOA,QAAO;AAAA,kBACd;AAAA,kBACA;AAAA,kBACA,CAAC,YAAY,aACX,KAAK,aAAa,YAAY,kBAAkB,YAAY,QAAQ;AAAA,gBACxE;AAAA,cACF;AAAA,YACF;AACA,mBAAO,EAAE,OAAO,QAAQ,OAAO;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AACA,UAAIF,QAAO,QAAQ,GAAG;AACpB,aAAK,cAAc;AAAA,UACjB,IAAI,cAAc,OAAO,OAAO,kBAAkB,WAAW,GAAGA,QAAO,KAAK;AAAA,QAC9E;AAAA,MACF;AACA,aAAOA;AAAA,IACT;AAEA,QAAI,mBAA+C,CAAC;AACpD,QAAI,UAAU;AAEd,QAAI,KAAK,gBAAgB;AACvB,gBAAU,KAAK,eAAe,eAAe,KAAK;AAClD,yBAAmB,MAAM,KAAK;AAAA,QAAY,MACxC,SAAS,SAAS;AAAA,UAChB,OAAO;AAAA,UACP,QAAQ;AAAA,YACN,CAAC,OAAO,GAAG;AAAA,YACX,CAAC,KAAK,cAAc,GAAG;AAAA,UACzB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,SAAS,WAAW;AAAA,MACvC,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AAED,QAAI,KAAK,gBAAgB;AACvB,iBAAW,UAAU,kBAAkB;AACrC,cAAM,YAAY,OAAO,KAAK,cAAc;AAC5C,YAAI,CAAC,WAAW;AACd;AAAA,QACF;AAEA,cAAM,kBAAkB;AAAA,UACtB;AAAA,YACE,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,SAAS,kBAAkB,WAAW;AAAA,UACxC;AAAA,UACA,MACE,KAAK,eAAgB,eAAe,KAAK,QAAQ,OAAO,OAAO,OAAO,GAAG,WAAW,CAAC;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,QAAQ,GAAG;AACpB,WAAK,cAAc;AAAA,QACjB,IAAI,cAAc,OAAO,OAAO,kBAAkB,WAAW,GAAG,OAAO,KAAK;AAAA,MAC9E;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAqB,OAAe,OAAwC;AAChF,WAAO,KAAK;AAAA,MAAa;AAAA,MAAO;AAAA,MAAe;AAAA,MAAU,CAAC,WACxD,kBAAkB,IAAI,EAAE,YAAY,WAAW,gBAAgB,KAAK,GAAG,YAAY;AACjF,cAAM,MAAM,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AACzD,eAAO,OAAO,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;AAAA,MACrC,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MACJ,OACA,SAC4B;AAC5B,UAAM,EAAE,WAAW,OAAO,WAAW,IAAI;AAEzC,UAAM,SAAS,MAAM,KAAK;AAAA,MAAa;AAAA,MAAO;AAAA,MAAS;AAAA,MAAU,CAAC,WAChE,kBAAkB,IAAI,EAAE,YAAY,WAAW,gBAAgB,KAAK,GAAG,YAAY;AACjF,cAAM,MAAM,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AACzD,eAAO,OAAO,GAAG,EAAE,WAAW;AAAA,UAC5B,OAAO;AAAA,YACL,GAAG;AAAA,YACH,CAAC,KAAK,cAAc,GAAG,EAAE,KAAK,MAAM,IAAI,UAAU;AAAA,UACpD;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,QAAQ,GAAG;AACpB,WAAK,cAAc,WAAW,IAAI,YAAY,OAAO,OAAO,OAAO,SAAS,CAAC;AAAA,IAC/E;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAe,UAA4C;AAC/D,WAAO,kBAAkB,IAAI,EAAE,YAAY,eAAe,gBAAgB,MAAM,GAAG,QAAQ;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAe,UAA4C;AAC/D,WAAO,kBAAkB,IAAI,EAAE,YAAY,eAAe,gBAAgB,MAAM,GAAG,QAAQ;AAAA,EAC7F;AACF;AApSa,oBAAN;AAAA,EADNG,YAAW;AAAA,EAMP,mBAAAC,QAAO,0BAA0B;AAAA,EACjC,mBAAAA,QAAO,0BAA0B;AAAA,EACjC,mBAAAC,UAAS;AAAA,EAAG,mBAAAD,QAAO,cAAc;AAAA,EACjC,mBAAAC,UAAS;AAAA,EACT,mBAAAD,QAAO,sBAAsB;AAAA,GATrB;;;AFNN,IAAM,uBAAN,MAA2B;AAAA,EAChC,OAAO,SACL,SACA,QACe;AACf,UAAM,cAAuC;AAAA,MAC3C,gBAAgB;AAAA,MAChB,oBAAoB;AAAA,MACpB,GAAG;AAAA,IACL;AAEA,UAAM,YAAmB;AAAA,MACvB,EAAE,SAAS,4BAA4B,UAAU,YAAY;AAAA,MAC7D,EAAE,SAAS,gBAAgB,UAAU,KAAK;AAAA,MAC1C;AAAA,MACA;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,gBAAU,KAAK,EAAE,SAAS,4BAA4B,UAAU,OAAO,CAAC;AAAA,IAC1E;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA,SAAS,CAAC,mBAAmB,4BAA4B,sBAAsB;AAAA,IACjF;AAAA,EACF;AACF;AA5Ba,uBAAN;AAAA,EADN,OAAO,CAAC,CAAC;AAAA,GACG;;;ASNb,eAAsB,kBACpB,eACA,OACA,iBAAiB,aACF;AACf,QAAM,SAAS,MAAM,kBAAkB;AAAA,IACrC,EAAE,YAAY,eAAe,gBAAgB,MAAM;AAAA,IACnD,MAAM,cAAc,UAAU,EAAE,MAAM,CAAC;AAAA,EACzC;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AAEA,MAAI,OAAO,cAAc,MAAM,QAAQ,OAAO,cAAc,MAAM,QAAW;AAC3E,UAAM,IAAI;AAAA,MACR,uCAAuC,cAAc,6BAA6B,cAAc,OAAO,OAAO,cAAc,CAAC;AAAA,IAC/H;AAAA,EACF;AACF;AAEA,eAAsB,qBACpB,eACA,OACA,iBAAiB,aACF;AACf,QAAM,SAAS,MAAM,cAAc,UAAU,EAAE,MAAM,CAAC;AAEtD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAEA,MAAI,OAAO,cAAc,MAAM,QAAQ,OAAO,cAAc,MAAM,QAAW;AAC3E,UAAM,IAAI;AAAA,MACR,2CAA2C,cAAc,yBAAyB,cAAc,OAAO,OAAO,cAAc,CAAC;AAAA,IAC/H;AAAA,EACF;AACF;AAEA,eAAsB,yBACpB,QACA,aACA,OACA,aACA,iBAAiB,aACF;AACf,QAAM,YAAY,YAAY,OAAO,CAAC,EAAE,YAAY,IAAI,YAAY,MAAM,CAAC;AAC3E,QAAM,kBAAkB,OAAO,SAAS,GAAG,OAAO,cAAc;AAEhE,aAAW,cAAc,aAAa;AACpC,UAAM,WAAW,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,WAAW,MAAM,CAAC;AACxE,UAAM,kBAAkB,MAAM,kBAAkB;AAAA,MAC9C,EAAE,YAAY,eAAe,gBAAgB,MAAM;AAAA,MACnD,MAAM,OAAO,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,cAAc,GAAG,EAAE,KAAK,KAAK,EAAE,EAAE,CAAC;AAAA,IAChF;AAEA,QAAI,gBAAgB,WAAW,GAAG;AAChC,YAAM,IAAI;AAAA,QACR,aAAa,UAAU;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AACF;","names":["Inject","Injectable","Optional","affectedChildren","result","delegate","pkField","Injectable","Inject","Optional"]}