UNPKG

monguito

Version:

MongoDB Abstract Repository implementation for Node.js

1 lines 40 kB
{"version":3,"file":"repo.cjs","sources":["../src/util/audit.ts","../src/util/exceptions.ts","../src/util/domain-model.ts","../src/mongoose.repository.ts","../src/util/transaction.ts","../src/mongoose.transactional-repository.ts","../src/util/schema.ts"],"sourcesContent":["/**\n * Models an auditable persistable domain object.\n * @property {Date} createdAt - the date and time when the entity was created.\n * @property {string} createdBy - the user who created the entity.\n * @property {Date} updatedAt - the date and time when the entity was last updated.\n * @property {string} updatedBy - the user who last updated the entity.\n * @property {number} version - the version of the entity.\n */\nexport interface Auditable {\n createdAt?: Date;\n createdBy?: string;\n updatedAt?: Date;\n updatedBy?: string;\n version?: number;\n}\n\n/**\n * Utility class designed to ease the definition of {@link Auditable} persistable domain objects.\n */\nexport abstract class AuditableClass implements Auditable {\n readonly createdAt?: Date;\n readonly createdBy?: string;\n readonly updatedAt?: Date;\n readonly updatedBy?: string;\n readonly version?: number;\n\n /**\n * Creates an auditable persistable domain object instance.\n * @param {Auditable} entity the entity to create the auditable persistable domain object from.\n */\n constructor(entity: Auditable) {\n this.createdAt = entity.createdAt ? new Date(entity.createdAt) : undefined;\n this.createdBy = entity.createdBy;\n this.updatedAt = entity.updatedAt ? new Date(entity.updatedAt) : undefined;\n this.updatedBy = entity.updatedBy;\n this.version = entity.version;\n }\n}\n\n/**\n * Determines whether a given domain object is {@link Auditable}.\n *\n * @param {any} entity the entity to evaluate.\n * @returns {boolean} `true` if the given entity is auditable, `false` otherwise.\n */\nexport const isAuditable = (entity: any): entity is Auditable =>\n entity &&\n 'createdAt' in entity &&\n 'updatedAt' in entity &&\n 'createdBy' in entity &&\n 'updatedBy' in entity;\n","import mongoose from 'mongoose';\n\nabstract class Exception extends Error {\n constructor(message: string, cause?: Error) {\n super(message, { cause });\n this.name = this.constructor.name;\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Models a client provided illegal argument exception.\n */\nexport class IllegalArgumentException extends Exception {\n /**\n * Creates an `IllegalArgumentException`, optionally wrapping an error.\n * @param {string} message the message of the exception.\n * @param {Error} cause (optional) the wrapped error.\n */\n constructor(message: string, cause?: Error) {\n super(message, cause);\n }\n}\n\n/**\n * Models an entity instantiation exception.\n */\nexport class InstantiationException extends Exception {\n /**\n * Creates an `InstantiationException`, optionally wrapping an error.\n * @param {string} message the message of the exception.\n * @param {Error} cause (optional) the wrapped error.\n */\n constructor(message: string, cause?: Error) {\n super(message, cause);\n }\n}\n\n/**\n * Models an undefined persistable domain object constructor exception.\n */\nexport class UndefinedConstructorException extends Exception {\n /**\n * Creates an `UndefinedConstructorException`, optionally wrapping an error.\n * @param {string} message the message of the exception.\n * @param {Error} cause (optional) the wrapped error.\n */\n constructor(message: string, cause?: Error) {\n super(message, cause);\n }\n}\n\n/**\n * Models a persistable domain object schema validation rule violation exception.\n * Since there may be several properties of the persistable domain object that are invalid,\n * this exception provides means to retrieve the invalid fields altogeher or by kind.\n */\nexport class ValidationException extends Exception {\n override cause: mongoose.Error.ValidationError;\n\n /**\n * Creates an `ValidationException`, optionally wrapping an error.\n * @param {string} message the message of the exception.\n * @param {Error} cause (optional) the wrapped error.\n */\n constructor(message: string, cause: mongoose.Error.ValidationError) {\n super(message, cause);\n this.cause = cause;\n }\n\n /**\n * Retrieves all the invalid field names of the persistable domain object.\n * @returns an array with the names of the invalid fields.\n */\n getInvalidFields(): string[] {\n return Object.keys(this.cause.errors);\n }\n\n /**\n * Retrieves all the non-specified required field names of the persistable domain object.\n * @returns an array with the names of the required fields that are not specified.\n */\n getInvalidRequiredFields(): string[] {\n return this.getInvalidFieldsOfKind('required');\n }\n\n /**\n * Retrieves all the duplicated unique field names of the persistable domain object.\n * @returns an array with the names of the unique fields that are duplicated.\n */\n getInvalidUniqueFields(): string[] {\n return this.getInvalidFieldsOfKind('unique');\n }\n\n private getInvalidFieldsOfKind(kind: string): string[] {\n const invalidFields: string[] = [];\n for (const field in this.cause.errors) {\n const error = this.cause.errors[field];\n if (error.kind === kind) {\n invalidFields.push(error.path);\n }\n }\n return invalidFields;\n }\n}\n","import { Schema } from 'mongoose';\nimport { Entity } from './entity';\nimport { IllegalArgumentException } from './exceptions';\n\n/**\n * Models a domain type instance constructor.\n */\ntype Constructor<T> = new (...args: any) => T;\n\n/**\n * Models an abstract domain type instance constructor.\n */\ntype AbsConstructor<T> = abstract new (...args: any) => T;\n\n/**\n * Models some domain type data.\n */\ntype DomainTypeData<T> = {\n type: Constructor<T> | AbsConstructor<T>;\n schema: Schema;\n};\n\n/**\n * Models some domain leaf type data.\n */\ntype DomainLeafTypeData<T> = { type: Constructor<T>; schema: Schema };\n\n/**\n * Models some domain intermediate type data.\n */\ntype DomainIntermediateTypeData<T> = {\n type: Constructor<T> | AbsConstructor<T>;\n schema: Schema;\n subtypes: (DomainIntermediateTypeData<T> | DomainLeafTypeData<T>)[];\n};\n\n/**\n * Domain model specification.\n */\nexport interface DomainModel<T extends Entity> extends DomainTypeData<T> {\n subtypes?: (DomainIntermediateTypeData<T> | DomainLeafTypeData<T>)[];\n}\n\n/**\n * Domain model implementation.\n */\nexport class DomainTree<T extends Entity> implements DomainModel<T> {\n readonly type: Constructor<T> | AbsConstructor<T>;\n readonly schema: Schema;\n readonly subtypes: (DomainIntermediateTypeData<T> | DomainLeafTypeData<T>)[];\n\n constructor(domainModel: DomainModel<T>) {\n if (!domainModel.type || !domainModel.schema) {\n throw new IllegalArgumentException(\n 'The given domain model must specify a type and a schema',\n );\n }\n this.type = domainModel.type;\n this.schema = domainModel.schema;\n this.subtypes = [];\n for (const subtypeData of domainModel.subtypes ?? []) {\n this.subtypes.push(new DomainTree(subtypeData));\n }\n }\n\n getSubtypeTree(): DomainModel<T>[] {\n return this.subtypes || [];\n }\n\n getSubtypeData(type: string): DomainModel<T> | undefined {\n return this.subtypes?.find((subtype) => subtype.type.name === type);\n }\n\n getSubtypeConstructor(type: string): Constructor<T> | undefined {\n const subtypeData = this.getSubtypeData(type);\n return subtypeData?.type as Constructor<T>;\n }\n\n getSupertypeConstructor(): Constructor<T> | undefined {\n return this.type as Constructor<T>;\n }\n\n getSupertypeName(): string {\n return this.type.name;\n }\n\n has(type: string): boolean {\n return type === this.getSupertypeName() || !!this.getSubtypeData(type);\n }\n}\n","import mongoose, {\n Connection,\n FilterQuery,\n HydratedDocument,\n Model,\n UpdateQuery,\n} from 'mongoose';\nimport { Optional } from 'typescript-optional';\nimport { PartialEntityWithId, Repository } from './repository';\nimport { isAuditable } from './util/audit';\nimport { DomainModel, DomainTree } from './util/domain-model';\nimport { Entity } from './util/entity';\nimport {\n IllegalArgumentException,\n InstantiationException,\n UndefinedConstructorException,\n ValidationException,\n} from './util/exceptions';\nimport {\n DeleteByIdOptions,\n FindAllOptions,\n FindByIdOptions,\n FindOneOptions,\n SaveOptions,\n} from './util/operation-options';\n\n/**\n * Abstract Mongoose-based implementation of the {@link Repository} interface.\n */\nexport abstract class MongooseRepository<T extends Entity & UpdateQuery<T>>\n implements Repository<T>\n{\n private readonly domainTree: DomainTree<T>;\n protected readonly entityModel: Model<T>;\n\n /**\n * Sets up the underlying configuration to enable database operation execution.\n * @param {DomainModel<T>} domainModel the domain model supported by this repository.\n * @param {Connection} connection (optional) a MongoDB instance connection.\n */\n protected constructor(\n domainModel: DomainModel<T>,\n protected readonly connection?: Connection,\n ) {\n this.domainTree = new DomainTree(domainModel);\n this.entityModel = this.createEntityModel(connection);\n }\n\n private createEntityModel(connection?: Connection) {\n let entityModel;\n if (connection) {\n entityModel = connection.model<T>(\n this.domainTree.type.name,\n this.domainTree.schema,\n );\n } else {\n entityModel = mongoose.model<T>(\n this.domainTree.type.name,\n this.domainTree.schema,\n );\n }\n for (const subtypeData of this.domainTree.getSubtypeTree()) {\n entityModel.discriminator(subtypeData.type.name, subtypeData.schema);\n }\n return entityModel;\n }\n\n /** @inheritdoc */\n async findById<S extends T>(\n id: string,\n options?: FindByIdOptions,\n ): Promise<Optional<S>> {\n if (!id) throw new IllegalArgumentException('The given ID must be valid');\n const document = await this.entityModel\n .findById(id)\n .session(options?.session ?? null)\n .exec();\n return Optional.ofNullable(this.instantiateFrom(document) as S);\n }\n\n /** @inheritdoc */\n async findOne<S extends T>(\n options?: FindOneOptions<S>,\n ): Promise<Optional<S>> {\n const document = await this.entityModel\n .findOne(options?.filters ?? undefined)\n .session(options?.session ?? null)\n .exec();\n return Optional.ofNullable(this.instantiateFrom(document) as S);\n }\n\n /** @inheritdoc */\n async findAll<S extends T>(options?: FindAllOptions<S>): Promise<S[]> {\n if (options?.pageable?.pageNumber && options?.pageable?.pageNumber < 0) {\n throw new IllegalArgumentException(\n 'The given page number must be a positive number',\n );\n }\n if (options?.pageable?.offset && options?.pageable?.offset < 0) {\n throw new IllegalArgumentException(\n 'The given page offset must be a positive number',\n );\n }\n\n const offset = options?.pageable?.offset ?? 0;\n const pageNumber = options?.pageable?.pageNumber ?? 0;\n try {\n const documents = await this.entityModel\n .find(options?.filters as FilterQuery<S>)\n .skip(pageNumber > 0 ? (pageNumber - 1) * offset : 0)\n .limit(offset)\n .sort(options?.sortBy)\n .session(options?.session ?? null)\n .exec();\n return documents.map((document) => this.instantiateFrom(document) as S);\n } catch (error) {\n throw new IllegalArgumentException(\n 'The given optional parameters must be valid',\n error,\n );\n }\n }\n\n /** @inheritdoc */\n async save<S extends T>(\n entity: S | PartialEntityWithId<S>,\n options?: SaveOptions,\n ): Promise<S> {\n if (!entity)\n throw new IllegalArgumentException(\n 'The given entity cannot be null or undefined',\n );\n if (!entity.id) {\n return await this.insert(entity as S, options);\n } else {\n return await this.update(entity as PartialEntityWithId<S>, options);\n }\n }\n\n /**\n * Inserts an entity.\n * @param {S} entity the entity to insert.\n * @param {SaveOptions} options (optional) insert operation options.\n * @returns {Promise<S>} the inserted entity.\n * @throws {IllegalArgumentException} if the given entity is `undefined` or `null`.\n */\n protected async insert<S extends T>(\n entity: S,\n options?: SaveOptions,\n ): Promise<S> {\n if (!entity)\n throw new IllegalArgumentException(\n 'The given entity cannot be null or undefined',\n );\n try {\n const document = this.createDocumentForInsertion(entity, options);\n const insertedDocument = (await document.save({\n session: options?.session,\n })) as HydratedDocument<S>;\n return this.instantiateFrom(insertedDocument) as S;\n } catch (error) {\n if (error instanceof mongoose.Error.ValidationError) {\n throw new ValidationException(\n 'One or more fields of the given entity do not specify valid values',\n error,\n );\n } else throw error;\n }\n }\n\n private createDocumentForInsertion<S extends T>(\n entity: S,\n options?: SaveOptions,\n ) {\n this.setDiscriminatorKeyOnEntity(entity);\n const document = new this.entityModel(entity);\n this.setAuditableDataOnDocumentToInsert(document, entity, options?.userId);\n return document;\n }\n\n private setDiscriminatorKeyOnEntity<S extends T>(\n entity: S | PartialEntityWithId<S>,\n ): void {\n const entityClassName = entity['constructor']['name'];\n if (!this.domainTree.has(entityClassName)) {\n throw new IllegalArgumentException(\n `The entity with name ${entityClassName} is not included in the setup of the custom repository`,\n );\n }\n const isSubtype = entityClassName !== this.domainTree.getSupertypeName();\n const hasEntityDiscriminatorKey = '__t' in entity;\n if (isSubtype && !hasEntityDiscriminatorKey) {\n entity['__t'] = entityClassName;\n }\n }\n\n private setAuditableDataOnDocumentToInsert<S extends T>(\n document: HydratedDocument<S>,\n entity: S,\n userId?: string,\n ): void {\n if (isAuditable(entity)) {\n if (userId) document.$locals.userId = userId;\n document.__v = 0;\n }\n }\n\n /**\n * Updates an entity.\n * @param {S} entity the entity to update.\n * @param {SaveOptions} options (optional) update operation options.\n * @returns {Promise<S>} the updated entity.\n * @throws {IllegalArgumentException} if the given entity is `undefined` or `null` or specifies an `id` not matching any existing entity.\n */\n protected async update<S extends T>(\n entity: PartialEntityWithId<S>,\n options?: SaveOptions,\n ): Promise<S> {\n if (!entity)\n throw new IllegalArgumentException('The given entity must be valid');\n const document = await this.entityModel\n .findById<HydratedDocument<S>>(entity.id)\n .session(options?.session ?? null);\n if (document) {\n try {\n document.set(entity);\n this.setAuditableDataOnDocumentToUpdate(document, options?.userId);\n const updatedDocument = (await document.save({\n session: options?.session,\n })) as HydratedDocument<S>;\n return this.instantiateFrom(updatedDocument) as S;\n } catch (error) {\n if (error instanceof mongoose.Error.ValidationError) {\n throw new ValidationException(\n 'One or more fields of the given entity do not specify valid values',\n error,\n );\n } else throw error;\n }\n }\n throw new IllegalArgumentException(\n `There is no document matching the given ID '${entity.id}'`,\n );\n }\n\n private setAuditableDataOnDocumentToUpdate<S extends T>(\n document: HydratedDocument<S>,\n userId?: string,\n ): void {\n document.isNew = false;\n if (isAuditable(document)) {\n if (userId) document.$locals.userId = userId;\n document.__v = ((document.__v as number) ?? 0) + 1;\n }\n }\n\n /** @inheritdoc */\n async deleteById(id: string, options?: DeleteByIdOptions): Promise<boolean> {\n if (!id) throw new IllegalArgumentException('The given ID must be valid');\n const isDeleted = await this.entityModel.findByIdAndDelete(id, {\n session: options?.session,\n });\n return !!isDeleted;\n }\n\n /**\n * Instantiates a persistable domain object from the given Mongoose Document.\n * @param {HydratedDocument<S> | null} document the given Mongoose Document.\n * @returns {S | null} the resulting persistable domain object instance.\n * @throws {UndefinedConstructorException} if there is no constructor available.\n */\n protected instantiateFrom<S extends T>(\n document: HydratedDocument<S> | null,\n ): S | null {\n if (!document) return null;\n const entityKey = document.get('__t');\n const constructor = entityKey\n ? this.domainTree.getSubtypeConstructor(entityKey)\n : this.domainTree.getSupertypeConstructor();\n if (constructor) {\n try {\n // safe instantiation as no abstract class instance can be stored in the first place\n return new constructor(document.toObject()) as S;\n } catch (error) {\n // still, the constructor of some entities may throw an error\n throw new InstantiationException(\n `An error occurred while instantiating an entity with ID ${document.id}`,\n error,\n );\n }\n }\n throw new UndefinedConstructorException(\n `There is no registered instance constructor for the document with ID ${document.id} or the corresponding entity type is abstract`,\n );\n }\n}\n","import mongoose, { ClientSession, Connection } from 'mongoose';\n\n/**\n * Models a callback function that writes to and reads from the database using a session.\n */\ntype DbCallback<T> = (session: ClientSession) => Promise<T>;\n\n/**\n * Specifies transaction options.\n * @property {ClientSession} session (optional) - a transaction session, required to run the operation within an existing transaction.\n */\nexport type TransactionOptions = {\n session?: ClientSession;\n};\n\nconst MAX_RETRIES = 3;\n\n/**\n * Runs the provided callback function within a transaction and commits the changes to the database\n * iff it has run successfully.\n *\n * @param {DbCallback<T>} callback a callback function that writes to and reads from the database using a session.\n * @param {TransactionOptions} options (optional) some options about the transaction.\n */\nexport async function runInTransaction<T>(\n callback: DbCallback<T>,\n options?: TransactionOptions & { connection?: Connection },\n): Promise<T> {\n if (options?.session) return callback(options.session);\n return await recursiveRunIntransaction(callback, 0, options?.connection);\n}\n\nasync function recursiveRunIntransaction<T>(\n callback: DbCallback<T>,\n retries: number,\n connection?: Connection,\n): Promise<T> {\n const session = await startSession(connection);\n session.startTransaction();\n try {\n const result = await callback(session);\n await session.commitTransaction();\n return result;\n } catch (error) {\n await session.abortTransaction();\n if (isTransientTransactionError(error) && retries < MAX_RETRIES) {\n return recursiveRunIntransaction(callback, ++retries, connection);\n }\n throw error;\n } finally {\n session.endSession();\n }\n}\n\nasync function startSession(connection?: Connection): Promise<ClientSession> {\n if (connection) {\n return await connection.startSession();\n } else {\n return await mongoose.connection.startSession();\n }\n}\n\n// Transient transaction errors can be safely retried.\nfunction isTransientTransactionError(error: any): boolean {\n return error.message.includes('does not match any in-progress transactions');\n}\n","import { ClientSession, Connection, UpdateQuery } from 'mongoose';\nimport { MongooseRepository } from './mongoose.repository';\nimport { PartialEntityWithId } from './repository';\nimport { TransactionalRepository } from './transactional-repository';\nimport { DomainModel } from './util/domain-model';\nimport { Entity } from './util/entity';\nimport {\n DeleteAllOptions,\n SaveAllOptions,\n SaveOptions,\n} from './util/operation-options';\nimport { runInTransaction } from './util/transaction';\n\n/**\n * Abstract Mongoose-based implementation of the {@link TransactionalRepository} interface.\n */\nexport abstract class MongooseTransactionalRepository<\n T extends Entity & UpdateQuery<T>,\n >\n extends MongooseRepository<T>\n implements TransactionalRepository<T>\n{\n /**\n * Sets up the underlying configuration to enable database operation execution.\n * @param {DomainModel<T>} domainModel the domain model supported by this repository.\n * @param {Connection} connection (optional) a MongoDB instance connection.\n */\n protected constructor(domainModel: DomainModel<T>, connection?: Connection) {\n super(domainModel, connection);\n }\n\n /** @inheritdoc */\n async saveAll<S extends T>(\n entities: (S | PartialEntityWithId<S>)[],\n options?: SaveAllOptions,\n ): Promise<S[]> {\n return await runInTransaction(\n async (session: ClientSession) =>\n await Promise.all(\n entities.map(\n async (entity) =>\n await this.save(entity, {\n userId: options?.userId,\n session,\n }),\n ),\n ),\n { ...options, connection: this.connection },\n );\n }\n\n /** @inheritdoc */\n async deleteAll<S extends T>(options?: DeleteAllOptions<S>): Promise<number> {\n return await runInTransaction(\n async (session: ClientSession) =>\n (await this.entityModel.deleteMany(options?.filters, { session }))\n .deletedCount,\n { ...options, connection: this.connection },\n );\n }\n\n /** @inheritdoc */\n protected async update<S extends T>(\n entity: PartialEntityWithId<S>,\n options?: SaveOptions,\n ): Promise<S> {\n const updateOperation = super.update.bind(this);\n return await runInTransaction(\n async (session: ClientSession) =>\n await updateOperation(entity, {\n userId: options?.userId,\n session: options?.session ?? session,\n }),\n { connection: this.connection },\n );\n }\n}\n","import {\n SchemaOptions as MongooseSchemaOptions,\n Schema,\n SchemaDefinition,\n} from 'mongoose';\n\nexport type SchemaPlugin = { fn: (schema: Schema) => void; options?: any };\n\nexport type SchemaOptions = MongooseSchemaOptions & {\n plugins?: SchemaPlugin[];\n};\n\n/**\n * Base schema to be extended by all persistable domain object schemas.\n */\nexport const BaseSchema = new Schema(\n {},\n {\n // required to deserialize domain objects\n toObject: {\n transform: (document: any, result: any) => {\n result.id = document.id;\n delete result._id;\n },\n },\n },\n);\n\n/**\n * Schema to be extended by all persistable domain objects that require audit capability.\n */\nexport const AuditableSchema = extendSchema(\n BaseSchema,\n {\n createdBy: { type: String },\n updatedBy: { type: String },\n },\n {\n timestamps: true,\n toObject: {\n transform: (document: any, result: any) => {\n result.id = document.id;\n result.version = document.__v;\n delete result._id;\n delete result.__v;\n },\n },\n plugins: [{ fn: setUserAuditData }],\n },\n);\n\n// Mongoose plugin definition\nfunction setUserAuditData(schema: Schema) {\n schema.pre('save', function (next) {\n if (this.$locals.userId) {\n if (!this.createdBy) {\n this.createdBy = this.$locals.userId;\n }\n this.updatedBy = this.$locals.userId;\n }\n delete this.$locals.userId;\n next();\n });\n}\n\n/**\n * Creates a new schema from the given data.\n * @param {Schema<T>} baseSchema the base schema.\n * @param {Schema<S>} extension the schema to extend from.\n * @returns {Schema<T & S>} a new schema that integrates the contents of the given parameters.\n */\nexport function extendSchema<T = object, S = object>(\n baseSchema: Schema<T>,\n extension: Schema<S>,\n): Schema<T & S>;\n/**\n * Creates a new schema from the given data.\n * @param {Schema<T>} baseSchema the base schema.\n * @param {SchemaDefinition<S>} extension the schema definition to extend from.\n * @param {SchemaOptions} options (optional) some schema options.\n * @returns {Schema<T & S>} a new schema that integrates the contents of the given parameters.\n */\nexport function extendSchema<T = object, S = object>(\n baseSchema: Schema<T>,\n extension: SchemaDefinition<S>,\n options?: SchemaOptions,\n): Schema<T & S>;\nexport function extendSchema<T = object, S = object>(\n baseSchema: Schema<T>,\n extension: Schema<T> | SchemaDefinition<S>,\n options?: SchemaOptions,\n): Schema<T & S> {\n const isExtensionASchema = extension instanceof Schema;\n const newSchema = new Schema<T & S>(\n { ...baseSchema.obj, ...(isExtensionASchema ? extension.obj : extension) },\n {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ...baseSchema.options,\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n ...(isExtensionASchema ? extension.options : options),\n },\n );\n registerPlugins(newSchema, baseSchema, extension, options);\n return newSchema;\n}\n\nfunction registerPlugins<T = object, S = object>(\n newSchema: Schema<T & S>,\n baseSchema: Schema<T>,\n extension: Schema<T> | SchemaDefinition<S>,\n options?: SchemaOptions,\n): void {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n baseSchema.plugins.forEach((plugin: SchemaPlugin) => {\n newSchema.plugin(plugin.fn, plugin.options);\n });\n if (extension instanceof Schema) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n extension.plugins.forEach((plugin: SchemaPlugin) => {\n newSchema.plugin(plugin.fn, plugin.options);\n });\n }\n if (options?.plugins) {\n options.plugins.forEach((plugin: SchemaPlugin) => {\n newSchema.plugin(plugin.fn, plugin.options);\n });\n }\n}\n"],"names":["isAuditable","entity","Exception","_Error","message","cause","_this","call","this","name","constructor","Error","captureStackTrace","_inheritsLoose","_wrapNativeSuper","IllegalArgumentException","_Exception","InstantiationException","_Exception2","UndefinedConstructorException","_Exception3","ValidationException","_Exception4","_this2","_proto","prototype","getInvalidFields","Object","keys","errors","getInvalidRequiredFields","getInvalidFieldsOfKind","getInvalidUniqueFields","kind","invalidFields","field","error","push","path","DomainTree","domainModel","type","schema","subtypes","_step","_iterator","_createForOfIteratorHelperLoose","_domainModel$subtypes","done","value","getSubtypeTree","getSubtypeData","_this$subtypes","find","subtype","getSubtypeConstructor","subtypeData","getSupertypeConstructor","getSupertypeName","has","MongooseRepository","connection","domainTree","entityModel","createEntityModel","model","mongoose","discriminator","findById","id","options","_options$session","Promise","resolve","session","exec","then","document","Optional","ofNullable","instantiateFrom","e","reject","findOne","_options$filters","_options$session2","filters","undefined","findAll","_options$pageable","_options$pageable2","_options$pageable3","_options$pageable4","_options$pageable$off","_options$pageable5","_options$pageable$pag","_options$pageable6","_this3","pageable","pageNumber","offset","_catch","_options$session3","skip","limit","sort","sortBy","documents","map","save","update","insert","_this5","createDocumentForInsertion","insertedDocument","ValidationError","setDiscriminatorKeyOnEntity","setAuditableDataOnDocumentToInsert","userId","entityClassName","$locals","__v","_options$session4","_this6","_exit","_temp2","_result","_temp","set","setAuditableDataOnDocumentToUpdate","updatedDocument","_this6$instantiateFro","_document$__v","isNew","deleteById","findByIdAndDelete","isDeleted","entityKey","get","toObject","recursiveRunIntransaction","callback","retries","startSession","startTransaction","result","commitTransaction","abortTransaction","includes","isTransientTransactionError","MAX_RETRIES","_finallyRethrows","_wasThrown","endSession","runInTransaction","MongooseTransactionalRepository","_MongooseRepository","saveAll","entities","all","_extends","deleteAll","deleteMany","_this2$entityModel$de","deletedCount","updateOperation","bind","BaseSchema","Schema","transform","_id","AuditableSchema","extendSchema","createdBy","String","updatedBy","timestamps","version","plugins","fn","pre","next","baseSchema","extension","isExtensionASchema","newSchema","obj","forEach","plugin","registerPlugins","createdAt","updatedAt","Date"],"mappings":"u0EAmBsB,IA0BTA,EAAc,SAACC,GAAW,OACrCA,GACA,cAAeA,GACf,cAAeA,GACf,cAAeA,GACf,cAAeA,CAAM,EChDRC,eAAUC,SAAAA,GACvB,SAAAD,EAAYE,EAAiBC,GAAa,IAAAC,EAKvC,OAJDA,EAAAH,EAAAI,KAAMH,KAAAA,EAAS,CAAEC,MAAAA,KAAQG,MACpBC,KAAOH,EAAKI,YAAYD,KACzBE,MAAMC,mBACRD,MAAMC,kBAAiBN,EAAOA,EAAKI,aACpCJ,CACH,CAAC,OAAAO,EAAAX,EAAAC,GAAAD,CAAA,CAPsBC,cAOtBW,EAP8BH,QAapBI,eAAyBC,SAAAA,GAMpC,SAAAD,EAAYX,EAAiBC,GAAa,OACxCW,EAAAT,KAAAC,KAAMJ,EAASC,IACjBG,IAAA,QAACK,EAAAE,EAAAC,GAAAD,CAAA,CARmCC,CAAQd,GAcjCe,eAAuB,SAAAC,GAMlC,SAAAD,EAAYb,EAAiBC,UAC3Ba,EAAAX,UAAMH,EAASC,IAAMG,IACvB,CAACS,OAAAJ,EAAAI,EAAAC,GAAAD,CAAA,CARiC,CAAQf,GAc/BiB,eAA8BC,SAAAA,GAMzC,SAAAD,EAAYf,EAAiBC,GAC3B,OAAAe,EAAAb,KAAMH,KAAAA,EAASC,QACjB,CAAC,OAAAQ,EAAAM,EAAAC,GAAAD,CAAA,CARwCC,CAAQlB,GAgBtCmB,eAAoB,SAAAC,GAQ/B,SAAAD,EAAYjB,EAAiBC,GAAqC,IAAAkB,EAE7C,OADnBA,EAAAD,EAAAf,KAAAC,KAAMJ,EAASC,IAAMG,MARdH,aASPkB,EAAKlB,MAAQA,EAAMkB,CACrB,CAACV,EAAAQ,EAAAC,GAAAE,IAAAA,EAAAH,EAAAI,UAmCAJ,OAnCAG,EAMDE,iBAAA,WACE,OAAOC,OAAOC,KAAKpB,KAAKH,MAAMwB,OAChC,EAACL,EAMDM,yBAAA,WACE,YAAYC,uBAAuB,WACrC,EAACP,EAMDQ,uBAAA,WACE,OAAOxB,KAAKuB,uBAAuB,SACrC,EAACP,EAEOO,uBAAA,SAAuBE,GAC7B,IAAMC,EAA0B,GAChC,IAAK,IAAMC,UAAc9B,MAAMwB,OAAQ,CACrC,IAAMO,EAAQ5B,KAAKH,MAAMwB,OAAOM,GAC5BC,EAAMH,OAASA,GACjBC,EAAcG,KAAKD,EAAME,KAE7B,CACA,OAAOJ,CACT,EAACb,CAAA,CA9C8B,CAAQnB,GCb5BqC,eAAU,WAKrB,SAAAA,EAAYC,GACV,GALOC,KAAAA,UACAC,EAAAA,KAAAA,YACAC,EAAAA,KAAAA,cAGP,GAAKH,EAAYC,OAASD,EAAYE,OACpC,MAAM,IAAI3B,EACR,2DAGJP,KAAKiC,KAAOD,EAAYC,KACxBjC,KAAKkC,OAASF,EAAYE,OAC1BlC,KAAKmC,SAAW,GAChB,QAAoDC,EAApDC,EAAAC,EAA8C,OAA9CC,EAA0BP,EAAYG,UAAQI,EAAI,MAAEH,EAAAC,KAAAG,MAAE,CAAAD,IAAAA,EACpDvC,KAAKmC,SAASN,KAAK,IAAIE,EADHK,EAAAK,OAEtB,CACF,CAAC,IAAAzB,EAAAe,EAAAd,iBAAAD,EAED0B,eAAA,WACE,OAAW1C,KAACmC,UAAY,EAC1B,EAACnB,EAED2B,eAAA,SAAeV,GAAY,IAAAW,EACzB,OAAOA,OAAPA,EAAO5C,KAAKmC,eAALS,EAAAA,EAAeC,KAAK,SAACC,GAAO,OAAKA,EAAQb,KAAKhC,OAASgC,CAAI,EACpE,EAACjB,EAED+B,sBAAA,SAAsBd,GACpB,IAAMe,EAAchD,KAAK2C,eAAeV,GACxC,aAAOe,SAAAA,EAAaf,IACtB,EAACjB,EAEDiC,wBAAA,WACE,OAAOjD,KAAKiC,IACd,EAACjB,EAEDkC,iBAAA,WACE,OAAWlD,KAACiC,KAAKhC,IACnB,EAACe,EAEDmC,IAAA,SAAIlB,GACF,OAAOA,IAASjC,KAAKkD,sBAAwBlD,KAAK2C,eAAeV,EACnE,EAACF,CAAA,CA1CoB,0FCjBD,IAAAqB,eAWpB,WAAA,SAAAA,EACEpB,EACmBqB,QAAAA,gBAAA,EAAArD,KAVJsD,gBACEC,EAAAA,KAAAA,mBASEvD,KAAUqD,WAAVA,EAEnBrD,KAAKsD,WAAa,IAAIvB,EAAWC,GACjChC,KAAKuD,YAAcvD,KAAKwD,kBAAkBH,EAC5C,CAAC,IAAArC,EAAAoC,EAAAnC,iBAAAD,EAEOwC,kBAAA,SAAkBH,GACxB,IAAIE,EAEFA,EADEF,EACYA,EAAWI,MACvBzD,KAAKsD,WAAWrB,KAAKhC,KACrBD,KAAKsD,WAAWpB,QAGJwB,EAAAA,QAASD,MACrBzD,KAAKsD,WAAWrB,KAAKhC,KACrBD,KAAKsD,WAAWpB,QAGpB,IAAAG,IAA0DD,EAA1DC,EAAAC,EAA0BtC,KAAKsD,WAAWZ,oBAAgBN,EAAAC,KAAAG,MAAE,CAAjD,IAAAQ,EAAWZ,EAAAK,MACpBc,EAAYI,cAAcX,EAAYf,KAAKhC,KAAM+C,EAAYd,OAC/D,CACA,OAAOqB,CACT,EAACvC,EAGK4C,kBACJC,EACAC,GAAyB,IAAA,IAAAC,EAAAjE,EAGFE,KADvB,IAAK6D,EAAI,MAAM,IAAItD,EAAyB,8BAA8B,OAAAyD,QAAAC,QACnDnE,EAAKyD,YACzBK,SAASC,GACTK,eAAOH,EAAQ,MAAPD,OAAO,EAAPA,EAASI,SAAOH,EAAI,MAC5BI,QAAMC,KAAA,SAHHC,GAIN,OAAOC,EAAAA,SAASC,WAAWzE,EAAK0E,gBAAgBH,GAAgB,EAClE,CAAC,MAAAI,GAAA,OAAAT,QAAAU,OAAAD,EAAA,CAAA,EAAAzD,EAGK2D,iBACJb,GAA2B,QAAAc,EAAAC,EAAA9D,EAEJf,KAAI,OAAAgE,QAAAC,QAAJlD,EAAKwC,YACzBoB,QAAwB,OAAjBC,EAACd,MAAAA,OAAAA,EAAAA,EAASgB,SAAOF,OAAIG,GAC5Bb,eAAOW,EAAQ,MAAPf,OAAO,EAAPA,EAASI,SAAOW,EAAI,MAC5BV,QAAMC,cAHHC,GAIN,OAAOC,EAAAA,SAASC,WAAWxD,EAAKyD,gBAAgBH,GAAgB,EAClE,CAAC,MAAAI,GAAA,OAAAT,QAAAU,OAAAD,KAAAzD,EAGKgE,QAAA,SAAqBlB,OAA2BmB,IAAAA,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAe1BzF,KAd1B,SAAI8D,UAAOmB,EAAPnB,EAAS4B,WAATT,EAAmBU,aAAqB,MAAP7B,GAAiB,OAAVoB,EAAPpB,EAAS4B,eAAQ,EAAjBR,EAAmBS,YAAa,EACnE,MAAM,IAAIpF,EACR,mDAGJ,GAAW,MAAPuD,GAAiB,OAAVqB,EAAPrB,EAAS4B,WAATP,EAAmBS,eAAU9B,GAAAsB,OAAOA,EAAPtB,EAAS4B,eAATN,EAAAA,EAAmBQ,QAAS,EAC3D,MAAU,IAAArF,EACR,mDAIJ,IAAMqF,EAAkCP,OAA5BA,QAAGvB,UAAOwB,EAAPxB,EAAS4B,iBAATJ,EAAmBM,QAAMP,EAAI,EACtCM,SAAUJ,EAAUC,MAAP1B,GAAiB,OAAV0B,EAAP1B,EAAS4B,eAAQ,EAAjBF,EAAmBG,YAAUJ,EAAI,EAAE,OAAAvB,QAAAC,QAAA4B,EAAA,eAClDC,EAAA,OAAA9B,QAAAC,QACsBwB,EAAKlC,YAC1BV,KAAY,MAAPiB,OAAO,EAAPA,EAASgB,SACdiB,KAAKJ,EAAa,GAAKA,EAAa,GAAKC,EAAS,GAClDI,MAAMJ,GACNK,WAAKnC,SAAAA,EAASoC,QACdhC,eAAO4B,EAAQ,MAAPhC,OAAO,EAAPA,EAASI,SAAO4B,EAAI,MAC5B3B,QAAMC,KAAA,SANH+B,GAON,OAAOA,EAAUC,IAAI,SAAC/B,GAAQ,OAAKoB,EAAKjB,gBAAgBH,EAAc,EAAE,EAC1E,EAASzC,SAAAA,GACP,UAAUrB,EACR,8CACAqB,EAEJ,GACF,CAAC,MAAA6C,GAAAT,OAAAA,QAAAU,OAAAD,EAAAzD,CAAAA,EAAAA,EAGKqF,KAAI,SACR5G,EACAqE,GAAqB,IAErB,IAAKrE,EACH,UAAUc,EACR,gDAEJ,OAEOyD,QAAAC,QAFFxE,EAAOoE,GACG7D,KAEKsG,OAAO7G,EAAkCqE,GAF9C9D,KAAKuG,OAAO9G,EAAaqE,GAI1C,CAAC,MAAAW,UAAAT,QAAAU,OAAAD,EAAAzD,CAAAA,EAAAA,EASeuF,OAAM,SACpB9G,EACAqE,OAAqB0C,IAAAA,EAOFxG,KALnB,IAAKP,EACH,MAAM,IAAIc,EACR,gDACA,OAAAyD,QAAAC,QAAA4B,EACA,WACF,IAAMxB,EAAWmC,EAAKC,2BAA2BhH,EAAQqE,GAAS,OAAAE,QAAAC,QAClCI,EAASgC,KAAK,CAC5CnC,QAAgB,MAAPJ,OAAO,EAAPA,EAASI,WAClBE,KAAA,SAFIsC,GAGN,OAAOF,EAAKhC,gBAAgBkC,EAAuB,EACrD,WAAS9E,SACHA,aAAiB8B,EAAQ,QAACvD,MAAMwG,gBAC5B,IAAI9F,EACR,qEACAe,GAESA,CACf,GACF,CAAC,MAAA6C,GAAAT,OAAAA,QAAAU,OAAAD,EAAA,CAAA,EAAAzD,EAEOyF,2BAAA,SACNhH,EACAqE,GAEA9D,KAAK4G,4BAA4BnH,GACjC,IAAM4E,EAAW,SAASd,YAAY9D,GAEtC,OADAO,KAAK6G,mCAAmCxC,EAAU5E,EAAQqE,MAAAA,OAAAA,EAAAA,EAASgD,QAC5DzC,CACT,EAACrD,EAEO4F,4BAAA,SACNnH,GAEA,IAAMsH,EAAkBtH,EAAoB,YAAQ,KACpD,IAAKO,KAAKsD,WAAWH,IAAI4D,GACvB,UAAUxG,EACgBwG,wBAAAA,4DAGVA,IAAoB/G,KAAKsD,WAAWJ,sBACpB,QAASzD,KAEzCA,EAAY,IAAIsH,EAEpB,EAAC/F,EAEO6F,mCAAA,SACNxC,EACA5E,EACAqH,GAEItH,EAAYC,KACVqH,IAAQzC,EAAS2C,QAAQF,OAASA,GACtCzC,EAAS4C,IAAM,EAEnB,EAACjG,EASesF,OAAM,SACpB7G,EACAqE,GAAqB,IAAA,IAAAoD,EAAAC,EAIEnH,KAFvB,IAAKP,EACH,MAAM,IAAIc,EAAyB,kCAAkC,OAAAyD,QAAAC,QAChDkD,EAAK5D,YACzBK,SAA8BnE,EAAOoE,IACrCK,QAAwBgD,OAAjBA,QAACpD,SAAAA,EAASI,SAAOgD,EAAI,OAAK9C,cAF9BC,GAAQ,IAAA+C,EAAAC,SAAAA,EAAAC,GAAAF,GAAAA,SAAAE,EAoBd,MAAU,IAAA/G,EACuCd,+CAAAA,EAAOoE,OACtD,CAAA,IAAA0D,EAnBElD,WAAAA,GAAAA,SAAQwB,EAAA,WAG2D,OADnExB,EAASmD,IAAI/H,GACb0H,EAAKM,mCAAmCpD,EAAUP,MAAAA,OAAAA,EAAAA,EAASgD,QAAQ9C,QAAAC,QACpCI,EAASgC,KAAK,CAC3CnC,QAAgB,MAAPJ,OAAO,EAAPA,EAASI,WAClBE,KAFIsD,SAAAA,OAAeC,EAGdR,EAAK3C,gBAAgBkD,GAAqB,OAAAN,EAAA,EAAAO,CAAA,EACnD,EAAS/F,SAAAA,GACHA,MAAAA,aAAiB8B,EAAQ,QAACvD,MAAMwG,oBACxB9F,EACR,qEACAe,GAESA,CACf,EAAC2F,CAfClD,GAeDkD,OAAAA,GAAAA,EAAAnD,KAAAmD,EAAAnD,KAAAiD,GAAAA,EAAAE,EAAA,EAKL,CAAC,MAAA9C,GAAAT,OAAAA,QAAAU,OAAAD,EAAAzD,CAAAA,EAAAA,EAEOyG,mCAAA,SACNpD,EACAyC,GAG2B,IAAAc,EAD3BvD,EAASwD,OAAQ,EACbrI,EAAY6E,KACVyC,IAAQzC,EAAS2C,QAAQF,OAASA,GACtCzC,EAAS4C,YAAMW,EAAEvD,EAAS4C,KAAcW,EAAI,GAAK,EAErD,EAAC5G,EAGK8G,oBAAWjE,EAAYC,GAA2B,IACtD,IAAKD,EAAI,UAAUtD,EAAyB,8BAA8B,OAAAyD,QAAAC,QAClDjE,KAAKuD,YAAYwE,kBAAkBlE,EAAI,CAC7DK,QAASJ,MAAAA,OAAAA,EAAAA,EAASI,WAClBE,cAFI4D,GAGN,QAASA,CAAU,EACrB,CAAC,MAAAvD,GAAA,OAAAT,QAAAU,OAAAD,EAAA,CAAA,EAAAzD,EAQSwD,gBAAA,SACRH,GAEA,IAAKA,EAAU,OAAW,KAC1B,IAAM4D,EAAY5D,EAAS6D,IAAI,OACzBhI,EAAc+H,EAChBjI,KAAKsD,WAAWP,sBAAsBkF,GACtCjI,KAAKsD,WAAWL,0BACpB,GAAI/C,EACF,IAEE,WAAWA,EAAYmE,EAAS8D,WAClC,CAAE,MAAOvG,GAEP,MAAU,IAAAnB,EACmD4D,2DAAAA,EAASR,GACpEjC,EAEJ,CAEF,MAAM,IAAIjB,EAA6B,wEACmC0D,EAASR,mDAErF,EAACT,CAAA,CA9PD,GCRagF,EAAA,SACbC,EACAC,EACAjF,GAAuBW,OAAAA,QAAAC,QAmBE,SAACZ,GAAuB,IACjD,OAAgBW,QAAAC,QAAZZ,EACWA,EAAWkF,eAEX7E,UAASL,WAAWkF,eAErC,CAAC,MAAA9D,GAAAT,OAAAA,QAAAU,OAAAD,IAvBuB8D,CAAalF,IAAWe,cAAxCF,GACqB,OAA3BA,EAAQsE,mEACJxE,QAAAC,QACmBoE,EAASnE,IAAQE,cAAhCqE,GAAM,OAAAzE,QAAAC,QACNC,EAAQwE,qBAAmBtE,KACjC,WAAA,OAAOqE,CAAO,EAAA,4DAJW5C,CAAA,EAKlBjE,SAAAA,GAAOoC,OAAAA,QAAAC,QACRC,EAAQyE,oBAAkBvE,KAChC,WAAA,GAkBJ,SAAqCxC,GACnC,OAAOA,EAAMhC,QAAQgJ,SAAS,8CAChC,CApBQC,CAA4BjH,IAAU0G,EAAUQ,EAClD,OAAOV,EAA0BC,IAAYC,EAASjF,GAExD,MAAMzB,CAAM,EACd,4FAX2BmH,CAAA,EAW1BC,SAAAA,EAAA1B,GACsB,GAArBpD,EAAQ+E,aAAaD,EAAA,MAAA1B,EAAAA,OAAAA,CAAA,IAEzB,EA5BsB4B,EAAA,SACpBb,EACAvE,OAEA,OAAsBE,QAAAC,QAAlBH,MAAAA,GAAAA,EAASI,QAAgBmE,EAASvE,EAAQI,SACjCkE,EAA0BC,EAAU,EAAU,MAAPvE,OAAO,EAAPA,EAAST,YAC/D,CAAC,MAAAoB,GAAA,OAAAT,QAAAU,OAAAD,EAfD,CAAA,EAAMqE,EAAc,ECCEK,eAGpB,SAAAC,GAQA,SAAAD,EAAsBnH,EAA6BqB,UACjD+F,EAAArJ,UAAMiC,EAAaqB,QACrB,CAAChD,EAAA8I,EAAAC,GAAApI,IAAAA,EAAAmI,EAAAlI,UA8CAkI,OA9CAnI,EAGKqI,QAAA,SACJC,EACAxF,OAAwBhE,IAAAA,EAORE,KAAI,OAAAgE,QAAAC,QALPiF,WACJhF,GAAsB,IAAA,OAAAF,QAAAC,QACrBD,QAAQuF,IACZD,EAASlD,aACA3G,GAAM,IAAA,OAAAuE,QAAAC,QACLnE,EAAKuG,KAAK5G,EAAQ,CACtBqH,OAAe,MAAPhD,OAAO,EAAPA,EAASgD,OACjB5C,QAAAA,IACAO,CAAAA,MAAAA,GAAAT,OAAAA,QAAAU,OAAAD,EAAA,CAAA,IAEPA,CAAAA,MAAAA,UAAAT,QAAAU,OAAAD,EAAA+E,CAAAA,EAAAA,KACE1F,EAAO,CAAET,WAAYvD,EAAKuD,cAEnC,CAAC,MAAAoB,GAAAT,OAAAA,QAAAU,OAAAD,EAAA,CAAA,EAAAzD,EAGKyI,mBAAuB3F,GAA6B,IAAA/C,IAAAA,EAG7Cf,KAAI,OAAAgE,QAAAC,QAFFiF,EAAgB,SACpBhF,GAAsB,IAAA,OAAAF,QAAAC,QACpBlD,EAAKwC,YAAYmG,WAAW5F,MAAAA,OAAAA,EAAAA,EAASgB,QAAS,CAAEZ,QAAAA,KAAUE,KAAAuF,SAAAA,UAAjEA,EACGC,YAAY,SAAAnF,GAAA,OAAAT,QAAAU,OAAAD,EAAA,CAAA,EAAA+E,EAAA,CAAA,EACZ1F,EAAST,CAAAA,WAAYtC,EAAKsC,cAEnC,CAAC,MAAAoB,UAAAT,QAAAU,OAAAD,EAAAzD,CAAAA,EAAAA,EAGesF,OAAM,SACpB7G,EACAqE,GAAqB,IAAA,IAEf+F,EAAkBT,EAAAnI,UAAMqF,OAAOwD,KAAK9J,MAAM,OAAAgE,QAAAC,QACnCiF,EACJhF,SAAAA,WAAsBH,EAAA,OAAAC,QAAAC,QACrB4F,EAAgBpK,EAAQ,CAC5BqH,aAAQhD,SAAAA,EAASgD,OACjB5C,QAAyBH,OAAlBA,EAAS,MAAPD,OAAO,EAAPA,EAASI,SAAOH,EAAIG,IAC7B,CAAA,MAAAO,GAAAT,OAAAA,QAAAU,OAAAD,EACJ,CAAA,EAAA,CAAEpB,WAPsCrD,KAOrBqD,aAEvB,CAAC,MAAAoB,GAAAT,OAAAA,QAAAU,OAAAD,EAAA0E,CAAAA,EAAAA,CAAA,CAxDD,CAAQ/F,GCJG2G,EAAa,IAAIC,SAC5B,CAAA,EACA,CAEE7B,SAAU,CACR8B,UAAW,SAAC5F,EAAeoE,GACzBA,EAAO5E,GAAKQ,EAASR,UACd4E,EAAOyB,GAChB,KAQOC,EAAkBC,EAC7BL,EACA,CACEM,UAAW,CAAEpI,KAAMqI,QACnBC,UAAW,CAAEtI,KAAMqI,SAErB,CACEE,YAAY,EACZrC,SAAU,CACR8B,UAAW,SAAC5F,EAAeoE,GACzBA,EAAO5E,GAAKQ,EAASR,GACrB4E,EAAOgC,QAAUpG,EAAS4C,WACnBwB,EAAOyB,WACPzB,EAAOxB,GAChB,GAEFyD,QAAS,CAAC,CAAEC,GAKhB,SAA0BzI,GACxBA,EAAO0I,IAAI,OAAQ,SAAUC,GACvB7K,KAAKgH,QAAQF,SACV9G,KAAKqK,YACRrK,KAAKqK,UAAYrK,KAAKgH,QAAQF,QAEhC9G,KAAKuK,UAAYvK,KAAKgH,QAAQF,eAEzB9G,KAAKgH,QAAQF,OACpB+D,GACF,EACF,eAwBgBT,EACdU,EACAC,EACAjH,GAEA,IAAMkH,EAAqBD,aAAqBf,SAC1CiB,EAAY,IAAIjB,EAAMA,OAAAR,EAAA,CAAA,EACrBsB,EAAWI,IAASF,EAAqBD,EAAUG,IAAMH,GAASvB,EAIlEsB,CAAAA,EAAAA,EAAWhH,QAGVkH,EAAqBD,EAAUjH,QAAUA,IAIjD,OAGF,SACEmH,EACAH,EACAC,EACAjH,GAIAgH,EAAWJ,QAAQS,QAAQ,SAACC,GAC1BH,EAAUG,OAAOA,EAAOT,GAAIS,EAAOtH,QACrC,GACIiH,aAAqBf,EAAAA,QAGvBe,EAAUL,QAAQS,QAAQ,SAACC,GACzBH,EAAUG,OAAOA,EAAOT,GAAIS,EAAOtH,QACrC,GAEEA,MAAAA,GAAAA,EAAS4G,SACX5G,EAAQ4G,QAAQS,QAAQ,SAACC,GACvBH,EAAUG,OAAOA,EAAOT,GAAIS,EAAOtH,QACrC,EAEJ,CA3BEuH,CAAgBJ,EAAWH,EAAYC,EAAWjH,GAC3CmH,CACT,wBN5EE,SAAYxL,GAAiBO,KAVpBsL,eAAS,EAAAtL,KACTqK,eAAS,EAAArK,KACTuL,eACAhB,EAAAA,KAAAA,eACAE,EAAAA,KAAAA,aAOP,EAAAzK,KAAKsL,UAAY7L,EAAO6L,UAAY,IAAIE,KAAK/L,EAAO6L,gBAAavG,EACjE/E,KAAKqK,UAAY5K,EAAO4K,UACxBrK,KAAKuL,UAAY9L,EAAO8L,UAAY,IAAIC,KAAK/L,EAAO8L,gBAAaxG,EACjE/E,KAAKuK,UAAY9K,EAAO8K,UACxBvK,KAAKyK,QAAUhL,EAAOgL,OACxB"}