UNPKG

@decaf-ts/core

Version:

Core persistence module for the decaf framework

1 lines 82.8 kB
var e,t;e=this,t=function(e,t,r,a,s,n,o,i){"use strict";var c;e.PersistenceKeys=void 0,(c=e.PersistenceKeys||(e.PersistenceKeys={})).INDEX="index",c.UNIQUE="unique",c.ADAPTER="adapter",c.INJECTABLE="decaf_{0}_adapter_for_{1}",c.SERVICE="service",c.TABLE="table",c.COLUMN="column",c.METADATA="__metadata",c.OWNERSHIP="ownership",c.CREATED_BY="ownership.created-by",c.UPDATED_BY="ownership.updated-by",c.RELATIONS="__relations",c.RELATION="relation",c.ONE_TO_ONE="relation.one-to-one",c.ONE_TO_MANY="relation.one-to-many",c.MANY_TO_ONE="relation.many-to-one",c.MANY_TO_MANY="relation.many-to-many",c.POPULATE="populate",c.NO_VALIDATE="no-validate",c.MIGRATION="migration",c.STATEMENT="statement",c.QUERY="query",c.GENERATED="generated";const l=Object.assign({},a.DefaultRepositoryFlags,{allowGenerationOverride:!1,enforceUpdateValidation:!0,allowRawStatements:!0,forcePrepareSimpleQueries:!1,forcePrepareComplexQueries:!1,cacheForPopulate:{}});class d{constructor(){this.observers=[]}count(){return this.observers.length}observe(e,t){if(-1!==this.observers.map(e=>e.observer).indexOf(e))throw new a.InternalError("Observer already registered");this.observers.push({observer:e,filter:t})}unObserve(e){const t=this.observers.map(e=>e.observer).indexOf(e);if(-1===t)throw new a.InternalError("Failed to find Observer");this.observers.splice(t,1)}async updateObservers(e,t,r,...a){const{log:s,ctxArgs:n}=w.logCtx(a,this.updateObservers);(await Promise.allSettled(this.observers.filter(a=>{const{filter:o}=a;if(!o)return!0;try{return o(e,t,r,...n)}catch(e){return s.error(`Failed to filter observer ${a.observer.toString()}: ${e}`),!1}}).map(a=>{a.observer.refresh(e,t,r,...n)}))).forEach((e,t)=>{"rejected"===e.status&&s.error(`Failed to update observable ${this.observers[t].toString()}: ${e.reason}`)})}}class p extends a.Context{constructor(){super()}}class u extends a.InternalError{constructor(e){super(e,u.name,500)}}class h extends a.InternalError{constructor(e,t=h.name){super(e,t,500)}}class g extends h{constructor(e){super(e,g.name)}}class f extends s.LoggedClass{logFor(e,...t){return e.logger.for(this)}logCtx(e,t){return f.logCtx.call(this,e,t)}static logCtx(e,t){if(1>e.length)throw new a.InternalError("No context provided");const r=e.pop();if(!(r instanceof a.Context))throw new a.InternalError("No context provided");if(e.filter(e=>e instanceof a.Context).length>1)throw Error("here");const s=this?r.logger.for(this).for(t):r.logger.clear().for(this).for(t);return{ctx:r,log:t?s.for(t):s,ctxArgs:[...e,r]}}}function y(e){return e.reduce((e,t)=>e.then(async e=>[...e,await t()]),Promise.resolve([]))}const m=o.Decoration.flavourResolver.bind(o.Decoration);o.Decoration.flavourResolver=e=>{try{const t=m(e);if(t&&t!==o.DefaultFlavour)return t;const r="function"==typeof e?e:e?.constructor,a=r&&"function"==typeof o.Metadata.registeredFlavour?o.Metadata.registeredFlavour(r):void 0;if(a&&a!==o.DefaultFlavour)return a;const s=w._currentFlavour;if(s){const e=w._cache?.[s];return e?.flavour?e.flavour:s}}catch(e){return o.DefaultFlavour}};class w extends f{static{this._cache={}}get config(){return this._config}get alias(){return this._alias||this.flavour}repository(){if(!w._baseRepository)throw new a.InternalError("This should be overridden when necessary. Otherwise it will be replaced lazily");return w._baseRepository}async shutdownProxies(e){if(this.proxies){if(e&&!(e in this.proxies))throw new a.InternalError("No proxy found for "+e);if(e)try{await this.proxies[e].shutdown(),delete this.proxies[e]}catch(t){this.log.error(`Failed to shutdown proxied adapter ${e}: ${t}`)}else for(const e in this.proxies){try{await this.proxies[e].shutdown()}catch(t){this.log.error(`Failed to shutdown proxied adapter ${e}: ${t}`);continue}delete this.proxies[e]}}}async shutdown(){await this.shutdownProxies(),this.dispatch&&await this.dispatch.close()}constructor(e,t,r){if(super(),this._config=e,this.flavour=t,this._alias=r,this.Context=p,this.alias in w._cache)throw new a.InternalError(`${this.alias} persistence adapter ${this._alias?`(${this.flavour}) `:""} already registered`);w._cache[this.alias]=this,this.log.info(`Created ${this.alias} persistence adapter ${this._alias?`(${this.flavour}) `:""} persistence adapter`),w._currentFlavour||(this.log.verbose(`Defined ${this.alias} persistence adapter as current`),w._currentFlavour=this.alias)}Dispatch(){return new w._baseDispatch}ObserverHandler(){return new d}isReserved(e){return!e}async initialize(...e){}async Sequence(e){return new w._baseSequence(e,this)}async flags(e,t,r,...i){let c=r.logger||s.Logging.for(this.toString());return r.correlationId&&(c=c.for({correlationId:r.correlationId})),Object.assign({},l,r,{affectedTables:(Array.isArray(t)?t:[t]).map(n.Model.tableName),writeOperation:e!==a.OperationKeys.READ,timestamp:new Date,operation:e,ignoredValidationProperties:o.Metadata.validationExceptions(Array.isArray(t)&&t[0]?t[0]:t,e),logger:c})}async context(e,t,r,...a){this.log.for(this.context).debug(`Creating new context for ${e} operation on ${r?Array.isArray(r)?r.map(e=>e.name):r.name:"no"} model with flag overrides: ${JSON.stringify(t)}`);const s=await this.flags(e,r,t,...a);return(new this.Context).accumulate(s)}prepare(t,...r){const{log:s}=this.logCtx(r,this.prepare),o=t.segregate(),i=Object.entries(o.model).reduce((e,[r,s])=>{if(void 0===s)return e;const o=n.Model.columnName(t.constructor,r);if(this.isReserved(o))throw new a.InternalError(`Property name ${o} is reserved`);return e[o]=s,e},{});return t[e.PersistenceKeys.METADATA]&&(s.silly("Passing along persistence metadata for "+t[e.PersistenceKeys.METADATA]),Object.defineProperty(i,e.PersistenceKeys.METADATA,{enumerable:!1,writable:!0,configurable:!0,value:t[e.PersistenceKeys.METADATA]})),{record:i,id:t[n.Model.pk(t.constructor)],transient:o.transient}}revert(t,r,s,o,...i){const{log:c,ctx:l}=this.logCtx(i,this.revert),d={};d[n.Model.pk(r)]=s;const p=new r(d);c.silly(`Rebuilding model ${p.constructor.name} id ${s}`);const u=t[e.PersistenceKeys.METADATA],h=Object.keys(p).reduce((e,a)=>(e[a]=t[n.Model.columnName(r,a)],e),p);return l.get("rebuildWithTransient")&&o&&(c.verbose("re-adding transient properties: "+Object.keys(o).join(", ")),Object.entries(o).forEach(([e,t])=>{if(e in h)throw new a.InternalError(`Transient property ${e} already exists on model ${p.constructor.name}. should be impossible`);h[e]=t})),u&&(c.silly(`Passing along ${this.flavour} persistence metadata for ${p.constructor.name} id ${s}: ${u}`),Object.defineProperty(h,e.PersistenceKeys.METADATA,{enumerable:!1,configurable:!0,writable:!0,value:u})),h}async createAll(e,t,r,...s){if(t.length!==r.length)throw new a.InternalError("Ids and models must have the same length");const{log:o,ctxArgs:i}=this.logCtx(s,this.createAll),c=n.Model.tableName(e);return o.debug(`Creating ${t.length} entries ${c} table`),y(t.map((t,a)=>()=>this.create(e,t,r[a],...i)))}async readAll(e,t,...r){const{log:a,ctxArgs:s}=this.logCtx(r,this.readAll),o=n.Model.tableName(e);return a.debug(`Reading ${t.length} entries ${o} table`),y(t.map(t=>()=>this.read(e,t,...s)))}async updateAll(e,t,r,...s){if(t.length!==r.length)throw new a.InternalError("Ids and models must have the same length");const{log:o,ctxArgs:i}=this.logCtx(s,this.updateAll),c=n.Model.tableName(e);return o.debug(`Updating ${t.length} entries ${c} table`),y(t.map((t,a)=>()=>this.update(e,t,r[a],...i)))}async deleteAll(e,t,...r){const{log:a,ctxArgs:s}=w.logCtx(r,this.deleteAll);return a.debug(`Deleting ${t.length} entries from ${e} table`),y(t.map(t=>()=>this.delete(e,t,...s)))}observe(e,t){this.observerHandler||Object.defineProperty(this,"observerHandler",{value:this.ObserverHandler(),writable:!1}),this.observerHandler.observe(e,t);const r=this.log.for(this.observe);r.verbose("Registering new observer "+e.toString()),this.dispatch||(r.info("Creating dispatch for "+this.alias),this.dispatch=this.Dispatch(),this.dispatch.observe(this))}unObserve(e){if(!this.observerHandler)throw new a.InternalError("ObserverHandler not initialized. Did you register any observables?");this.observerHandler.unObserve(e),this.log.for(this.unObserve).verbose(`Observer ${e.toString()} removed`)}async updateObservers(e,t,r,...s){if(!this.observerHandler)throw new a.InternalError("ObserverHandler not initialized. Did you register any observables?");const{log:n,ctxArgs:o}=w.logCtx(s,this.updateObservers);n.verbose(`Updating ${this.observerHandler.count()} observers for adapter ${this.alias}: Event: `),await this.observerHandler.updateObservers(e,t,r,...o)}async refresh(e,t,r,...a){return this.updateObservers(e,t,r,...a)}toString(){return this.flavour+" adapter"}static flavourOf(e){return o.Metadata.flavourOf(e)}static get currentFlavour(){if(!w._currentFlavour)throw new a.InternalError("No persistence flavour set. Please initialize your adapter");return w._currentFlavour}static get current(){return w.get(this.currentFlavour)}static get(e){if(!e)return w.get(this._currentFlavour);if(e in this._cache)return this._cache[e];throw new a.InternalError(`No Adapter registered under ${e}.`)}static setCurrent(e){this._currentFlavour=e}static models(e){try{return o.Metadata.flavouredAs(e).filter(n.Model.isModel)}catch(e){throw new a.InternalError(e)}}static decoration(){}static logCtx(e,t){return super.logCtx(e,t)}get client(){return this._client||(this._client=this.getClient()),this._client}for(e,...t){this.proxies||(this.proxies={});const r=`${this.alias} - ${n.hashObj(e)}`;if(r in this.proxies)return this.proxies[r];let a;const s=new Proxy(this,{get:(t,r,s)=>{if("_config"===r){const a=Reflect.get(t,r,s);return Object.assign({},a,e)}return"_client"===r?a:Reflect.get(t,r,s)},set:(e,t,r,s)=>"_client"===t?(a=r,!0):Reflect.set(e,t,r,s)});return this.proxies[r]=s,s}migrations(){return o.Metadata.migrationsFor(this)}async getQueryRunner(){return this}async migrate(e=this.migrations(),...t){e instanceof p&&(t=[e],e=this.migrations());const{ctx:r}=w.logCtx(t,this.migrate),a=await this.getQueryRunner();for(const t of e)try{const e=new t;await e.up(a,this,r),await e.down(a,this,r)}catch(e){throw new h(e)}}}r.__decorate([s.final(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[String]),r.__metadata("design:returntype",Promise)],w.prototype,"shutdownProxies",null),r.__decorate([s.final(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[String,Object,Object,Object]),r.__metadata("design:returntype",Promise)],w.prototype,"context",null),r.__decorate([s.final(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object,Function]),r.__metadata("design:returntype",void 0)],w.prototype,"observe",null),r.__decorate([s.final(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object]),r.__metadata("design:returntype",void 0)],w.prototype,"unObserve",null),r.__decorate([s.final(),r.__metadata("design:type",Object),r.__metadata("design:paramtypes",[])],w.prototype,"client",null);class b extends a.InternalError{constructor(e){super(e,b.name,500)}}class _ extends a.InternalError{constructor(e){super(e,_.name,500)}}var O,E,v,x,A,M;e.QueryClause=void 0,(O=e.QueryClause||(e.QueryClause={})).FIND_BY="findBy",O.SELECT="Select",O.AND="And",O.OR="Or",O.GROUP_BY="GroupBy",O.ORDER_BY="OrderBy",O.THEN="Then",O.THEN_BY="ThenBy",e.Operator=void 0,(E=e.Operator||(e.Operator={})).EQUAL="EQUAL",E.DIFFERENT="DIFFERENT",E.BIGGER="BIGGER",E.BIGGER_EQ="BIGGER_EQ",E.SMALLER="SMALLER",E.SMALLER_EQ="SMALLER_EQ",E.NOT="NOT",E.IN="IN",E.REGEXP="REGEXP",e.GroupOperator=void 0,(v=e.GroupOperator||(e.GroupOperator={})).AND="AND",v.OR="OR",e.PreparedStatementKeys=void 0,(x=e.PreparedStatementKeys||(e.PreparedStatementKeys={})).LIST_BY="listBy",x.FIND_BY="findBy",x.FIND_ONE_BY="findOneBy",x.PAGE_BY="paginateBy";class C extends n.Model{constructor(e,t,r){super(),this.attr1=void 0,this.operator=void 0,this.comparison=void 0,t||r?(this.attr1=e,this.operator=t,this.comparison=r):n.Model.fromModel(this,e)}and(e){return C.and(this,e)}or(e){return C.or(this,e)}not(t){return new C(this,e.Operator.NOT,t)}hasErrors(...t){const r=()=>{const t=`Invalid operator ${this.operator}}`;if("string"==typeof this.attr1){if(this.comparison instanceof C)return{comparison:{condition:"Both sides of the comparison must be of the same type"}};if(-1===Object.values(e.Operator).indexOf(this.operator))return{operator:{condition:t}}}if(this.attr1 instanceof C){if(!(this.comparison instanceof C)&&this.operator!==e.Operator.NOT)return{comparison:{condition:t}};if(-1===Object.values(e.GroupOperator).indexOf(this.operator)&&this.operator!==e.Operator.NOT)return{operator:{condition:t}}}},a=super.hasErrors(...t);return this.isAsync()?(async()=>await Promise.resolve(a)??r())():a??r()}static and(t,r){return C.group(t,e.GroupOperator.AND,r)}static or(t,r){return C.group(t,e.GroupOperator.OR,r)}static group(e,t,r){return new C(e,t,r)}static attribute(e){return(new C.Builder).attribute(e)}static attr(e){return this.attribute(e)}static{this.Builder=class{constructor(){this.attr1=void 0,this.operator=void 0,this.comparison=void 0}attribute(e){return this.attr1=e,this}attr(e){return this.attribute(e)}eq(t){return this.setOp(e.Operator.EQUAL,t)}dif(t){return this.setOp(e.Operator.DIFFERENT,t)}gt(t){return this.setOp(e.Operator.BIGGER,t)}lt(t){return this.setOp(e.Operator.SMALLER,t)}gte(t){return this.setOp(e.Operator.BIGGER_EQ,t)}lte(t){return this.setOp(e.Operator.SMALLER_EQ,t)}in(t){return this.setOp(e.Operator.IN,t)}regexp(t){return this.setOp(e.Operator.REGEXP,RegExp(t).source)}setOp(e,t){return this.operator=e,this.comparison=t,this.build()}build(){try{return new C(this.attr1,this.operator,this.comparison)}catch(e){throw new b(e)}}}}static builder(){return new C.Builder}static from(e){return new C(e)}}r.__decorate([n.required(),r.__metadata("design:type",Object)],C.prototype,"attr1",void 0),r.__decorate([n.required(),r.__metadata("design:type",String)],C.prototype,"operator",void 0),r.__decorate([n.required(),r.__metadata("design:type",Object)],C.prototype,"comparison",void 0),e.OrderDirection=void 0,(A=e.OrderDirection||(e.OrderDirection={})).ASC="asc",A.DSC="desc",e.Cascade=void 0,(M=e.Cascade||(e.Cascade={})).CASCADE="cascade",M.NONE="none";const P={update:e.Cascade.CASCADE,delete:e.Cascade.NONE},N={Equals:(e,t)=>C.attribute(e).eq(t),Diff:(e,t)=>C.attribute(e).dif(t),LessThan:(e,t)=>C.attribute(e).lt(t),LessThanEqual:(e,t)=>C.attribute(e).lte(t),GreaterThan:(e,t)=>C.attribute(e).gt(t),GreaterThanEqual:(e,t)=>C.attribute(e).gte(t),In:(e,t)=>C.attribute(e).in(t),Matches:(e,t)=>C.attribute(e).regexp(t)},D=e=>e.charAt(0).toLowerCase()+e.slice(1);class I extends s.LoggedClass{static get log(){return this._logger||(this._logger=s.Logging.for(I.name)),this._logger}static build(t,...r){if(!t.startsWith(e.QueryClause.FIND_BY))throw Error("Unsupported method "+t);const a=this.extractCore(t),s=this.extractSelect(t),n=this.extractGroupBy(t),o=this.buildWhere(a,r),{orderBy:i,limit:c,offset:l}=this.extractOrderLimitOffset(t,r);return{action:"find",select:s,where:o,groupBy:n,orderBy:i,limit:c,offset:l}}static extractCore(t){const r=t.substring(e.QueryClause.FIND_BY.length),a=r.match(/(Then[A-Z]|OrderBy|GroupBy|Limit|Offset)/);return a?r.substring(0,a.index):r}static getFieldsFromMethodName(e){return(this.extractCore(e).split(/OrderBy|GroupBy/)[0]||"").split(/And|Or/).map(e=>{const{operator:t,field:r}=this.parseFieldAndOperator(e);return r+(t??"")})}static extractSelect(t){const r=t.indexOf(e.QueryClause.SELECT);if(-1===r)return;const a=t.substring(r+e.QueryClause.SELECT.length),s=a.match(/(Then[A-Z]|OrderBy|GroupBy|Limit|Offset)/);return(s?a.substring(0,s.index):a).split(e.QueryClause.AND).map(D).filter(Boolean)}static extractGroupBy(t){const r=t.indexOf(e.QueryClause.GROUP_BY);if(-1!==r)return t.substring(r+e.QueryClause.GROUP_BY.length).split(e.QueryClause.ORDER_BY)[0].split(e.QueryClause.THEN_BY).map(D).filter(Boolean)}static buildWhere(t,r){if(!t&&0===r.length)return;const a=(t.split(/OrderBy|GroupBy/)[0]||"").split(/And|Or/),s=t.match(/And|Or/g)||[];let n;if(a.forEach((t,a)=>{const{field:o,operator:i}=this.parseFieldAndOperator(t),c=i?N[i]:N.Equals;if(!c)throw Error("Unsupported operator "+i);const l=r[a];if(void 0===l)throw Error("Invalid value for field "+o);const d=c(o,l);n=0===a?d:s[a-1]===e.QueryClause.AND?n.and(d):n.or(d)}),0!==a.length){if(!n)throw Error("No conditions found in method name");return n}}static parseFieldAndOperator(e){for(const t of Object.keys(N))if(e.endsWith(t)){const r=e.slice(0,-t.length);return{field:D(r),operator:t}}return{field:D(e)}}static extractOrderByField(e){const t=e.match(/OrderBy(.+)$/);if(!t)return;const r=t[1];return r.charAt(0).toLowerCase()+r.slice(1)}static getProperlyOrderByOrThrow(t,r){const a=I.log.for(this.getProperlyOrderByOrThrow);if(r||t){if(r&&!t)throw new b("Expected OrderBy clause, but no sortable field was found in method name.");if(r||!t){if(!Object.values(e.OrderDirection).includes(r))throw new b(`Invalid OrderBy direction ${r}. Expected one of: ${Object.values(e.OrderDirection).join(", ")}.`);return[[t,r]]}a.debug("Ignoring OrderBy clause because direction is undefined.")}}static extractOrderLimitOffset(e,t){const r=this.extractCore(e).split(/And|Or/).length,s=t.slice(r)??[];let n,o,i;if(s.at(-1)instanceof a.Context&&s.pop(),s.length>=1){const t=s[0],r=this.extractOrderByField(e);n=this.getProperlyOrderByOrThrow(r,t)}return 2>s.length||"number"!=typeof s[1]||(o=s[1]),3>s.length||"number"!=typeof s[2]||(i=s[2]),{orderBy:n,limit:o,offset:i}}}function B(){return o.Decoration.for(e.PersistenceKeys.STATEMENT).define({decorator:()=>(t,r,a)=>o.apply(o.methodMetadata(o.Metadata.key(e.PersistenceKeys.STATEMENT,r),!0))(t,r,a),args:[]}).apply()}class T extends a.Repository{static{this._cache={}}get log(){return this.logger||(this.logger=this.adapter.log.for(this.toString())),this.logger}get adapter(){if(!this._adapter)throw new a.InternalError("No adapter found for this repository. did you use the @uses decorator or pass it in the constructor?");return this._adapter}get tableName(){return this._tableName||(this._tableName=n.Model.tableName(this.class)),this._tableName}get pkProps(){return super.pkProps}constructor(e,t,...r){super(t),this.observers=[],this._overrides={allowGenerationOverride:!1,allowRawStatements:!0,forcePrepareSimpleQueries:!1,forcePrepareComplexQueries:!1,ignoreDevSafeGuards:!1,mergeForUpdate:!0,applyUpdateValidation:!0},e&&(this._adapter=e),t&&(T.register(t,this,this.adapter.alias),e)&&o.Metadata.get(t,o.DecorationKeys.FLAVOUR)===o.DefaultFlavour&&o.uses(e.flavour)(t);const s=this;[this.createAll,this.readAll,this.deleteAll].forEach(e=>{const t=e.name;a.wrapMethodWithContext(s,s[t+"Prefix"],e,s[t+"Suffix"])}),a.wrapMethodWithContextForUpdate(s,s[this.updateAll.name+"Prefix"],this.updateAll,s[this.updateAll.name+"Suffix"])}logCtx(e,t){return w.logCtx(e,t)}override(e){return new Proxy(this,{get:(t,r,a)=>{const s=Reflect.get(t,r,a);return"_overrides"!==r?s:Object.assign({},s,e)}})}for(e,...t){return new Proxy(this,{get:(r,a,s)=>"adapter"===a?this.adapter.for(e,...t):Reflect.get(r,a,s)})}ObserverHandler(){return new d}async createPrefix(e,...t){const r=await p.args(a.OperationKeys.CREATE,this.class,t,this.adapter,this._overrides||{}),s=r.context.get("ignoreHandlers"),n=r.context.get("ignoreValidation");if(e=new this.class(e),s||await a.enforceDBDecorators(this,r.context,e,a.OperationKeys.CREATE,a.OperationKeys.ON),!n){const t=await Promise.resolve(e.hasErrors(...r.context.get("ignoredValidationProperties")||[]));if(t)throw new a.ValidationError(t.toString())}return[e,...r.args]}async create(e,...t){const{ctx:r,log:a,ctxArgs:s}=this.logCtx(t,this.create);a.debug(`Creating new ${this.class.name} in table ${n.Model.tableName(this.class)}`);let{record:o,id:i,transient:c}=this.adapter.prepare(e,r);return o=await this.adapter.create(this.class,i,o,...s),this.adapter.revert(o,this.class,i,c,r)}async createAll(e,...t){if(!e.length)return e;const{ctx:r,log:a,ctxArgs:s}=this.logCtx(t,this.createAll);a.debug(`Creating ${e.length} new ${this.class.name} in table ${n.Model.tableName(this.class)}`);const o=e.map(e=>this.adapter.prepare(e,r)),i=o.map(e=>e.id);let c=o.map(e=>e.record);return c=await this.adapter.createAll(this.class,i,c,...s),c.map((e,t)=>this.adapter.revert(e,this.class,i[t],r.get("rebuildWithTransient")?o[t].transient:void 0,r))}async createAllPrefix(e,...t){const r=await p.args(a.OperationKeys.CREATE,this.class,t,this.adapter,this._overrides||{}),s=r.context.get("ignoreHandlers"),o=r.context.get("ignoreValidation");if(!e.length)return[e,...r.args];const i=n.Model.sequenceFor(e[0]);let c=[];if(n.Model.generatedBySequence(this.class)?(i.name||(i.name=n.Model.sequenceName(e[0],"pk")),c=await(await this.adapter.Sequence(i)).range(e.length,...r.args)):n.Model.generated(this.class,this.pk)||(c=e.map((e,t)=>{if(void 0===e[this.pk])throw new a.InternalError("Primary key is not defined for model in position "+t);return e[this.pk]})),e=await Promise.all(e.map(async(e,t)=>(e=new this.class(e),i.type&&(e[this.pk]="String"!==i.type||i.generated?c[t]:""+e[this.pk]),s||await a.enforceDBDecorators(this,r.context,e,a.OperationKeys.CREATE,a.OperationKeys.ON),e))),!o){const t=r.context.get("ignoredValidationProperties")||[],s=await Promise.all(e.map(e=>Promise.resolve(e.hasErrors(...t)))),n=a.reduceErrorsToPrint(s);if(n)throw new a.ValidationError(n)}return[e,...r.args]}async readPrefix(e,...t){const r=await p.args(a.OperationKeys.READ,this.class,t,this.adapter,this._overrides||{}),s=new this.class;return s[this.pk]=e,await a.enforceDBDecorators(this,r.context,s,a.OperationKeys.READ,a.OperationKeys.ON),[e,...r.args]}async read(e,...t){const{ctx:r,log:a,ctxArgs:s}=this.logCtx(t,this.read);a.debug(`reading ${this.class.name} from table ${n.Model.tableName(this.class)} with pk ${this.pk}`);const o=await this.adapter.read(this.class,e,...s);return this.adapter.revert(o,this.class,e,void 0,r)}async readAllPrefix(e,...t){const r=await p.args(a.OperationKeys.READ,this.class,t,this.adapter,this._overrides||{});return await Promise.all(e.map(async e=>{const t=new this.class;return t[this.pk]=e,a.enforceDBDecorators(this,r.context,t,a.OperationKeys.READ,a.OperationKeys.ON)})),[e,...r.args]}async readAll(e,...t){const{ctx:r,log:a,ctxArgs:s}=this.logCtx(t,this.readAll);return a.debug(`reading ${e.length} ${this.class.name} in table ${n.Model.tableName(this.class)}`),(await this.adapter.readAll(this.class,e,...s)).map((t,a)=>this.adapter.revert(t,this.class,e[a],void 0,r))}async update(e,...t){const{ctxArgs:r,log:a,ctx:s}=this.logCtx(t,this.update);let{record:o,id:i,transient:c}=this.adapter.prepare(e,s);return a.debug(`updating ${this.class.name} in table ${n.Model.tableName(this.class)} with id ${i}`),o=await this.adapter.update(this.class,i,o,...r),this.adapter.revert(o,this.class,i,c,s)}async updatePrefix(e,...t){const r=await p.args(a.OperationKeys.UPDATE,this.class,t,this.adapter,this._overrides||{}),s=r.context,o=s.get("ignoreHandlers"),i=s.get("ignoreValidation"),c=e[this.pk];if(!c)throw new a.InternalError("No value for the Id is defined under the property "+this.pk);let l;if(s.get("applyUpdateValidation")&&(l=await this.read(c,s),s.get("mergeForUpdate")&&(e=n.Model.merge(l,e,this.class))),o||await a.enforceDBDecorators(this,r.context,e,a.OperationKeys.UPDATE,a.OperationKeys.ON,l),!i){const t=await Promise.resolve(e.hasErrors(l,...r.context.get("ignoredValidationProperties")||[]));if(t)throw new a.ValidationError(t.toString())}return[e,...r.args,l]}async updateAll(e,...t){const{ctx:r,log:a,ctxArgs:s}=this.logCtx(t,this.updateAll);a.debug(`Updating ${e.length} new ${this.class.name} in table ${n.Model.tableName(this.class)}`);const o=e.map(e=>this.adapter.prepare(e,r));return(await this.adapter.updateAll(this.class,o.map(e=>e.id),o.map(e=>e.record),...s)).map((e,t)=>this.adapter.revert(e,this.class,o[t].id,r.get("rebuildWithTransient")?o[t].transient:void 0,r))}async updateAllPrefix(e,...t){const r=await p.args(a.OperationKeys.UPDATE,this.class,t,this.adapter,this._overrides||{}),s=r.context,o=s.get("ignoreHandlers"),i=s.get("ignoreValidation"),c=e.map(e=>{const t=e[this.pk];if(!t)throw new a.InternalError("missing id on update operation");return t});let l;if(s.get("applyUpdateValidation")&&(l=await this.readAll(c,s),s.get("mergeForUpdate")&&(e=e.map((e,t)=>n.Model.merge(l[t],e,this.class)))),o||await Promise.all(e.map((e,t)=>a.enforceDBDecorators(this,r.context,e,a.OperationKeys.UPDATE,a.OperationKeys.ON,l?l[t]:void 0))),!i){const t=s.get("ignoredValidationProperties")||[];let r;r=s.get("applyUpdateValidation")?await Promise.all(e.map((e,r)=>Promise.resolve(e.hasErrors(l[r],...t)))):await Promise.resolve(e.map(e=>e.hasErrors(...t)));const n=a.reduceErrorsToPrint(r);if(n)throw new a.ValidationError(n)}return[e,...r.args,l]}async deletePrefix(e,...t){const r=await p.args(a.OperationKeys.DELETE,this.class,t,this.adapter,this._overrides||{}),s=await this.read(e,...r.args);return await a.enforceDBDecorators(this,r.context,s,a.OperationKeys.DELETE,a.OperationKeys.ON),[e,...r.args]}async delete(e,...t){const{ctx:r,log:a,ctxArgs:s}=this.logCtx(t,this.delete);a.debug(`deleting new ${this.class.name} in table ${n.Model.tableName(this.class)} with pk ${e}`);const o=await this.adapter.delete(this.class,e,...s);return this.adapter.revert(o,this.class,e,void 0,r)}async deleteAllPrefix(e,...t){const r=await p.args(a.OperationKeys.DELETE,this.class,t,this.adapter,this._overrides||{}),s=await this.readAll(e,...r.args);return await Promise.all(s.map(async e=>a.enforceDBDecorators(this,p.childFrom(r.context),e,a.OperationKeys.DELETE,a.OperationKeys.ON))),[e,...r.args]}async deleteAll(e,...t){const{ctx:r,log:a,ctxArgs:s}=this.logCtx(t,this.create);return a.debug(`deleting ${e.length} ${this.class.name} in table ${n.Model.tableName(this.class)}`),(await this.adapter.deleteAll(this.class,e,...s)).map((t,a)=>this.adapter.revert(t,this.class,e[a],void 0,r))}select(e){return this.adapter.Statement(this._overrides).select(e).from(this.class)}async query(t,r,a=e.OrderDirection.ASC,s,n,...o){const i=await p.args(e.PersistenceKeys.QUERY,this.class,o,this.adapter,this._overrides||{}),{ctx:c}=this.logCtx(i.args,this.query),l=[r,a],d=this.select().where(t).orderBy(l);return s&&d.limit(s),n&&d.offset(n),d.execute(c)}async listBy(t,r,...a){const s=await p.args(e.PreparedStatementKeys.LIST_BY,this.class,a,this.adapter,this._overrides||{}),{log:o,ctxArgs:i}=this.logCtx(s.args,this.listBy);return o.verbose(`listing ${n.Model.tableName(this.class)} by ${t} ${r}`),this.select().orderBy([t,r]).execute(...i)}async paginateBy(t,r,a={offset:1,limit:10},...s){let{offset:o,bookmark:i,limit:c}=a;if(!o&&!i)throw new b("PaginateBy needs a page or a bookmark");const l=await p.args(e.PreparedStatementKeys.PAGE_BY,this.class,s,this.adapter,this._overrides||{}),{log:d,ctxArgs:u}=this.logCtx(l.args,this.paginateBy);let h;if(d.verbose(`paginating ${n.Model.tableName(this.class)} with page size ${c}`),i)h=await this.override({forcePrepareComplexQueries:!1,forcePrepareSimpleQueries:!1}).select().where(this.attr(n.Model.pk(this.class)).gt(i)).orderBy([t,r]).paginate(c,...u),o=1;else{if(!o)throw new b("PaginateBy needs a page or a bookmark");h=await this.override({forcePrepareComplexQueries:!1,forcePrepareSimpleQueries:!1}).select().orderBy([t,r]).paginate(c,...u)}const g=await h.page(o,...u);return h.serialize(g)}async findOneBy(t,r,...s){const o=await p.args(e.PreparedStatementKeys.FIND_ONE_BY,this.class,s,this.adapter,this._overrides||{}),{log:i,ctxArgs:c}=this.logCtx(o.args,this.findOneBy);i.verbose(`finding ${n.Model.tableName(this.class)} with ${t} ${r}`);const l=await this.select().where(this.attr(t).eq(r)).limit(1).execute(...c);if(!l.length)throw new a.NotFoundError("No results found");return l[0]}async findBy(t,r,...a){const s=await p.args(e.PreparedStatementKeys.FIND_BY,this.class,a,this.adapter,this._overrides||{}),{log:o,ctxArgs:i}=this.logCtx(s.args,this.findBy);return o.verbose(`finding ${n.Model.tableName(this.class)} with ${t} ${r}`),this.select().where(this.attr(t).eq(r)).execute(...i)}async statement(t,...r){if(!T.statements(this,t))throw new b("Invalid prepared statement requested "+t);const a=await p.args(e.PersistenceKeys.STATEMENT,this.class,r,this.adapter,this._overrides||{}),{log:s,ctxArgs:n}=this.logCtx(a.args,this.statement);return s.verbose("Executing prepared statement "+t),this[t](...n)}attr(e){return C.attr(e)}observe(e,t){this.observerHandler||Object.defineProperty(this,"observerHandler",{value:this.ObserverHandler(),writable:!1});const r=this.log.for(this.observe),a=n.Model.tableName(this.class);this.adapter.observe(this,(e,t,r,...s)=>"string"==typeof e?e===a:o.Metadata.constr(e)===o.Metadata.constr(this.class)),r.verbose(`now observing ${this.adapter} filtering on table === ${a}`),this.observerHandler.observe(e,t),r.verbose("Registered new observer "+e.toString())}unObserve(e){if(!this.observerHandler)throw new a.InternalError("ObserverHandler not initialized. Did you register any observables?");this.observerHandler.unObserve(e),this.log.for(this.unObserve).verbose(`Observer ${e.toString()} removed`),this.observerHandler.count()||(this.log.verbose(`No more observers registered for ${this.adapter}, unsubscribing`),this.adapter.unObserve(this),this.log.verbose("No longer observing adapter "+this.adapter.flavour))}async updateObservers(e,t,r,...s){if(!this.observerHandler)throw new a.InternalError("ObserverHandler not initialized. Did you register any observables?");const{log:o,ctxArgs:i}=this.logCtx(s,this.updateObservers);o.verbose(`Updating ${this.observerHandler.count()} observers for ${this}`),await this.observerHandler.updateObservers(e,t,Array.isArray(r)?r.map(e=>w._baseSequence.parseValue(n.Model.sequenceFor(this.class).type,e)):w._baseSequence.parseValue(n.Model.sequenceFor(this.class).type,r),...i)}async refresh(e,t,r,...a){return this.updateObservers(e,t,r,...a)}static forModel(t,r,...s){let n;const i=r||o.Metadata.flavourOf(t)||w.currentFlavour;try{n=this.get(t,i)}catch(e){n=void 0}if(n instanceof T)return n;const c=r||o.Metadata.flavourOf(t)||n&&o.Metadata.get(n,e.PersistenceKeys.ADAPTER)||w.currentFlavour,l=c?w.get(c):void 0;if(!l)throw new a.InternalError("No registered persistence adapter found flavour "+c);return n=n||l.repository(),new n(l,t,...s)}static get(e,t){const r=n.Model.tableName(e);let s=r;if(t&&(s=[r,t].join(a.DefaultSeparator)),s in this._cache)return this._cache[s];if(r in this._cache)return this._cache[r];throw new a.InternalError("Could not find repository registered under "+r)}static register(e,t,r){let s=n.Model.tableName(e);if(r&&(s=[s,r].join(a.DefaultSeparator)),s in this._cache&&this._cache[s]instanceof T)throw new a.InternalError(s+" already has a registered instance");this._cache[s]=t}static statements(t,r){const a=t instanceof T?t.constructor:t,s=o.Metadata.get(a,r?o.Metadata.key(e.PersistenceKeys.STATEMENT,r):e.PersistenceKeys.STATEMENT);return(r?s:Object.keys(s))||!1}static queries(t,r){const a=t instanceof T?t.constructor:t;return o.Metadata.get(a,r?o.Metadata.key(e.PersistenceKeys.QUERY,r):e.PersistenceKeys.QUERY)}}function R(t,r){if(!(r||(r=o.Decoration.flavourResolver(t instanceof n.Model?t.constructor:t))&&r!==o.DefaultFlavour))throw new a.InternalError("Could not retrieve flavour from model "+(t instanceof n.Model?t.constructor.name:t.name));return n.sf(e.PersistenceKeys.INJECTABLE,r,n.Model.tableName(t))}r.__decorate([B(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object,String,void 0]),r.__metadata("design:returntype",Promise)],T.prototype,"listBy",null),r.__decorate([B(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object,String,Object,void 0]),r.__metadata("design:returntype",Promise)],T.prototype,"paginateBy",null),r.__decorate([B(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object,Object,void 0]),r.__metadata("design:returntype",Promise)],T.prototype,"findOneBy",null),r.__decorate([B(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object,Object,void 0]),r.__metadata("design:returntype",Promise)],T.prototype,"findBy",null),r.__decorate([s.final(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object,Function]),r.__metadata("design:returntype",void 0)],T.prototype,"observe",null),r.__decorate([s.final(),r.__metadata("design:type",Function),r.__metadata("design:paramtypes",[Object]),r.__metadata("design:returntype",void 0)],T.prototype,"unObserve",null),w&&(w._baseRepository=T);class $ extends t.InjectableRegistryImp{get log(){return this.logger||(this.logger=s.Logging.for(this)),this.logger}constructor(){super()}get(r,a){const s=this.log.for(this.get);let i;try{i=super.get(r)}catch{}if(!i){let c;if("function"==typeof r?c=n.Model.get(r.toString())||r:"symbol"!=typeof r&&"string"!=typeof r||(c=n.Model.get(r.toString())),!c)return;const l=e.PersistenceKeys.ADAPTER,d=a||o.Metadata.get(c,l);try{let e=d;try{d&&w.get(d)}catch{const t=w.current;t&&t.flavour===d&&(e=t.alias)}if(i=T.forModel(c,e),i instanceof T)return i;const r=d||o.Metadata.get(i.constructor,l)||o.Metadata.get(c,l);t.Injectables.register(i,R(c,r))}catch(e){s.debug("No registered repository or adapter found. falling back to default adapter. Error: "+(e?.message||JSON.stringify(e)));const t=T.get(c,d);if("function"==typeof t){const e=d?w.get(d):w.current;if(!e)return;return new t(e,c)}}}return i}}async function K(e,t,r,s){const o=t.logger.for(K);if(!s){const t=n.Model.get(e.constructor.name);if(!t)throw new a.InternalError("Could not find model "+e.constructor.name);s=T.forModel(t,r),o.info("Retrieved "+s.toString())}let i;if(void 0===e[n.Model.pk(s.class)])o.info(`No pk found in ${n.Model.tableName(s.class)} - creating`),i=await s.create(e,t);else{o.info(`pk found in ${n.Model.tableName(s.class)} - attempting update`);try{i=await s.update(e,t),o.info("Updated "+n.Model.tableName(s.class))}catch(r){if(!(r instanceof a.NotFoundError))throw r;o.info("update Failed - creating new "+n.Model.tableName(s.class)),i=await s.create(e,t)}o.info("After create update: "+i)}return i}async function k(e,t,r,o){const i=o[r];if(!i)return;if("object"!=typeof i){const t=V(o,r,this.adapter.alias),a=await t.read(i);return await Q(e,o,r,i,a),void(o[r]=i)}const c=s.isClass(t.class)?t.class:t.class();if(!c)throw new a.InternalError("Could not find model "+t.class);const l=T.forModel(c,this.adapter.alias),d=await l.create(i,e),p=n.Model.pk(d);await Q(e,o,r,d[p],d),o[r]=d[p]}async function F(t,r,a,s){const o=s[a];if(!o)return;if(r.cascade.update!==e.Cascade.CASCADE)return;if("object"!=typeof o){const e=V(s,a,this.adapter.alias),r=await e.read(o,t);return await Q(t,s,a,o,r),void(s[a]=o)}const i=await K(s[a],t,this.adapter.alias),c=n.Model.pk(i);await Q(t,s,a,i[c],i),s[a]=i[c]}async function j(t,r,a,s){const o=s[a];if(!o)return;if(r.cascade.update!==e.Cascade.CASCADE)return;const i=V(s,a,this.adapter.alias);let c;c=o instanceof n.Model?await i.delete(s[a][i.pk],t):await i.delete(s[a],t),await Q(t,s,a,c[i.pk],c)}async function L(e,t,r,s){const o=s[r];if(!o||!o.length)return;const i=typeof o[0];if(!o.every(e=>typeof e===i))throw new a.InternalError(`Invalid operation. All elements of property ${r} must match the same type.`);const c=e.logger.for(L),l=new Set([...o]);if("object"!==i){const t=V(s,r,this.adapter.alias),a=await t.readAll([...l.values()],e);for(let t=0;t<a.length;t++){const s=a[t];c.warn("FOUND ONE TO MANY VALUE: "+JSON.stringify(s)),await Q(e,s,r,[...l.values()][t],a)}return s[r]=[...l],void c.warn("SET ONE TO MANY IDS: "+s[r])}const d=n.Model.pk(o[0].constructor),p=new Set;for(const t of o){c.info("Creating or updating one-to-many model: "+JSON.stringify(t));const a=await K(t,e,this.adapter.alias);c.info(`caching: ${JSON.stringify(a)} under ${a[d]}`),await Q(e,s,r,a[d],a),c.info("Creating or updating one-to-many model: "+JSON.stringify(t)),p.add(a[d])}s[r]=[...p]}async function q(t,r,a,s){const{cascade:n}=r;if(n.update===e.Cascade.CASCADE)return L.call(this,t,r,a,s)}async function U(t,r,s,n){if(r.cascade.delete!==e.Cascade.CASCADE)return;const o=n[s];if(!o||!o.length)return;const i=typeof o[0];if(!o.every(e=>typeof e===i))throw new a.InternalError(`Invalid operation. All elements of property ${s} must match the same type.`);const c="function"!=typeof r.class||r.class.name?r.class:r.class(),l="object"===i,d=l?T.forModel(c,this.adapter.alias):V(n,s,this.adapter.alias),p=[...new Set([...l?o.map(e=>e[d.pk]):o]).values()];let u,h;try{u=await d.deleteAll(p,t)}catch(e){throw t.logger.error("Failed to delete all records",e),e}for(let e=0;e<u.length;e++){h=u[e];try{await Q(t,n,s,p[e],h)}catch(r){throw t.logger.error(`Failed to cache record ${p[e]} with key ${s} and model ${JSON.stringify(n,void 0,2)} `,r),r}}n[s]=p}function G(t,r,a){return[e.PersistenceKeys.POPULATE,t,r,a].join(".")}async function Q(e,t,r,a,s){const n=G(t.constructor.name,r,a),o=e.get("cacheForPopulate")||{};return o[n]=s,e.accumulate({cacheForPopulate:o})}async function Y(e,t,r,s){if(!t.populate)return;const n=s[r],o=Array.isArray(n);if(void 0===n||o&&0===n.length)return;const i=await(async(t,r,s,n,o)=>{let i,c;const l=[],d=t.get("cacheForPopulate")||{};for(const t of n){i=G(r.constructor.name,s,t);try{if(c=d[i],!c)throw Error("Not found in cache")}catch(n){const i=V(r,s,o);if(!i)throw new a.InternalError("Could not find repo");c=await i.read(t,e)}l.push(c)}return l})(e,s,r,o?n:[n],this.adapter.alias);s[r]=o?i:i[0]}const z=["array","string","number","boolean","symbol","function","object","undefined","null","bigint"];function V(e,t,r){if(!e)throw Error("No model was provided to get repository");let s;if(Array.isArray(e[t])||e[t]instanceof Set){const r=o.Metadata.get(e instanceof n.Model?e.constructor:e,o.Metadata.key(n.ValidationKeys.REFLECT,t,n.ValidationKeys.LIST))?.clazz;if(!r)throw new a.InternalError("Failed to find types decorators for property "+t);s=(Array.isArray(r)?[...r]:[r]).map(e=>"function"!=typeof e||e.name?e:e())}else s=o.Metadata.getPropDesignTypes(e instanceof n.Model?e.constructor:e,t)?.designTypes;const i=s?.find(e=>!z.includes((""+e.name).toLowerCase()));return T.forModel(i,r)}class H extends a.BadRequestError{constructor(e,t=H.name,r=401){super(e,t,r)}}class W extends H{constructor(e,t=W.name){super(e,t,403)}}class J extends a.InternalError{constructor(e){super(e,J.name,503)}}function X(t){return o.Decoration.for(e.PersistenceKeys.TABLE).define({decorator:t=>r=>o.metadata(e.PersistenceKeys.TABLE,t||r.name.toLowerCase())(r),args:[t]}).apply()}function Z(t,r,a){return o.Decoration.for(e.PersistenceKeys.INDEX).define({decorator:(t,r,a)=>(s,n)=>("string"==typeof t&&(a=t,t=void 0,r=void 0),"string"==typeof r&&(a=r,r=void 0),!r&&t&&t.find(t=>![e.OrderDirection.ASC,e.OrderDirection.DSC].includes(t))&&(r=t,t=void 0),o.propMetadata(o.Metadata.key(`${e.PersistenceKeys.INDEX}${r&&r?.length?"."+r.join("."):""}`,n),{directions:t,compositions:r,name:a})(s,n)),args:[t,r,a]}).apply()}async function ee(e,t,r,s){if(s[r]&&(await this.select().where(C.attribute(r).eq(s[r])).execute()).length)throw new a.ConflictError(`model already exists with property ${r} equal to ${JSON.stringify(s[r],void 0,2)}`)}async function te(e,t,r,a){throw new H("This adapter does not support user identification")}function re(){return a.timestamp([a.OperationKeys.CREATE])}function ae(){return a.timestamp()}function se(){return(t,r)=>o.propMetadata(o.Metadata.key(e.PersistenceKeys.GENERATED,r),!0)(t,r)}function ne(...t){return(r,a)=>{const s=o.Metadata.get(r,o.Metadata.key(e.PersistenceKeys.NO_VALIDATE,a))||[],n=[...new Set([...s,...t])];return o.apply(o.metadata(o.Metadata.key(e.PersistenceKeys.NO_VALIDATE,a),n))(r,a)}}function oe(t,r){return o.Decoration.for(e.PersistenceKeys.RELATIONS).define({decorator:(t,r)=>(a,s)=>(o.propMetadata(t,r)(a,s),o.propMetadata(o.Metadata.key(e.PersistenceKeys.RELATIONS,s),Object.assign({},r,{key:t}))(a,s)),args:[t,r]}).apply()}o.Decoration.for(a.DBKeys.TIMESTAMP).extend(se()).apply(),o.Decoration.for(a.DBKeys.COMPOSED).extend(se()).apply(),o.Metadata.validationExceptions=((t,r)=>{const a=o.Metadata.get(t,e.PersistenceKeys.NO_VALIDATE)||[],s=Object.entries(a).filter(([,e])=>e.includes(r)).map(([e])=>e),i=n.Model.nestedRelations(t);return[...new Set([...s,...i])]}).bind(o.Metadata),o.Metadata.migrationsFor=(t=>{if(!(t=t??w.current))throw new a.InternalError("Could not get adapter for migrations");return o.Metadata.innerGet(Symbol.for(e.PersistenceKeys.MIGRATION),t.alias).map(e=>e.class)}).bind(o.Metadata),o.Metadata.relations=((t,r)=>{const s=o.Metadata.get(t,e.PersistenceKeys.RELATIONS);if(s){if(!r)return Object.keys(s);if(!s[r])throw new a.InternalError("No relations metadata found for property "+r);return s[r]}}).bind(o.Metadata),n.Model.relations=(e,t)=>o.Metadata.relations(e instanceof n.Model?e.constructor:e,t)||[],n.Model.nestedRelations=(t,r)=>{r?.length||(r=n.Model.relations(t));let a=[];const s=o.Metadata.get(t,e.PersistenceKeys.RELATIONS);if(!s||!Object.keys(s).length)return[...new Set([...r])];for(const e in s){const t=s[e];if(t?.class&&n.Model.relations(t.class)){const s=n.Model.relations(t.class),o=s.map(t=>`${e}.${t}`);r=[...r,...s,...o],a=n.Model.nestedRelations(t.class,r)}}return[...new Set([...r,...a])]},n.Model.generated=((t,r)=>!!o.Metadata.get("function"!=typeof t?t.constructor:t,o.Metadata.key(e.PersistenceKeys.GENERATED,r))).bind(o.Metadata),n.Model.generatedBySequence=((e,t)=>{const r="function"!=typeof e?e.constructor:e;return!!n.Model.sequenceFor(r).generated}).bind(o.Metadata),o.Metadata.createdBy=(t=>{const r=o.Metadata.get("function"!=typeof t?t.constructor:t,e.PersistenceKeys.CREATED_BY);if(!r)throw new a.InternalError("No createdBy metadata found for model. did you use @createdBy()?");return r}).bind(o.Metadata),o.Metadata.updatedBy=(t=>{const r=o.Metadata.get("function"!=typeof t?t.constructor:t,e.PersistenceKeys.UPDATED_BY);if(!r)throw new a.InternalError("No updatedBy metadata found for model. did you use @updatedBy()?");return r}).bind(o.Metadata),n.Model.tableName=t=>{if(!(t instanceof n.Model?n.Model.get(t.constructor.name):t))throw new a.InternalError("Unable to find model "+t);return o.Metadata.get(t instanceof n.Model?t.constructor:t,e.PersistenceKeys.TABLE)||(t instanceof n.Model?t.constructor.name:t.name)},n.Model.columnName=(t,r)=>o.Metadata.get(t instanceof n.Model?t.constructor:t,o.Metadata.key(e.PersistenceKeys.COLUMN,r))||r,n.Model.sequenceName=(e,...t)=>[n.Model.tableName(e),...t].join("_"),n.Model.sequenceFor=(e,t)=>{if(t)throw new u("not currently supported");const r=n.Model.pkProps(e instanceof n.Model?e.constructor:e);if(!r)throw new a.InternalError("No sequence options defined for model. did you use the @pk decorator?");return r},n.Model.indexes=t=>{const r=o.Metadata.get(t instanceof n.Model?t.constructor:t,e.PersistenceKeys.INDEX);return Object.keys(r||{}).reduce((t,a)=>(t[a]={[e.PersistenceKeys.INDEX]:r[a]},t),{})},t.Injectables.services=()=>o.Metadata.innerGet(Symbol.for(e.PersistenceKeys.SERVICE)),t.Injectables.repositories=()=>o.Metadata.innerGet(Symbol.for(a.DBKeys.REPOSITORY));class ie extends f{constructor(){super()}async initialize(){if(!this.adapter)return void this.log.for(this.initialize).verbose("No adapter observed for dispatch; skipping initialization");const e=this.adapter;[a.OperationKeys.CREATE,a.OperationKeys.UPDATE,a.OperationKeys.DELETE,a.BulkCrudOperationKeys.CREATE_ALL,a.BulkCrudOperationKeys.UPDATE_ALL,a.BulkCrudOperationKeys.DELETE_ALL].forEach(t=>{if(!e[t])throw new a.InternalError(`Method ${t} not found in ${e.alias} adapter to bind Observables Dispatch`);let r=Object.getOwnPropertyDescriptor(e,t),s=e;for(;!r&&s!==Object.prototype;)s=Object.getPrototypeOf(s),r=Object.getOwnPropertyDescriptor(s,t);r&&r.writable?e[t]=new Proxy(e[t],{apply:async(e,r,s)=>{const{log:n,ctxArgs:o}=r.logCtx(s,e),[i,c]=s,l=await e.apply(r,o);return this.updateObservers(i,(e=>{switch(e){case a.BulkCrudOperationKeys.CREATE_ALL:return a.OperationKeys.CREATE;case a.BulkCrudOperationKeys.UPDATE_ALL:return a.OperationKeys.UPDATE;case a.BulkCrudOperationKeys.DELETE_ALL:return a.OperationKeys.DELETE;default:return e}})(t),c,l,...o.slice(s.length)).then(()=>{n.verbose(`Observer refresh dispatched by ${t} for ${i}`),n.debug("pks: "+c)}).catch(e=>n.error(`Failed to dispatch observer refresh for ${t} on ${i}: ${e}`)),l}}):this.log.error(`Could not find method ${t} to bind Observables Dispatch`)})}async close(){}observe(e){if(!(e instanceof w))throw new u("Only Adapters can be observed by dispatch");this.adapter=e,this.models=w.models(this.adapter.alias),this.initialize().then(()=>this.log.verbose(`Dispatch initialized for ${this.adapter.alias} adapter`))}unObserve(e){if(this.adapter!==e)throw new u("Only the adapter that was used to observe can be unobserved");this.adapter=void 0}async updateObservers(e,t,r,...s){const o="string"==typeof e?e:n.Model.tableName(e),{log:i,ctxArgs:c}=this.logCtx(s,this.updateObservers);if(this.adapter)try{i.debug(`Dispatching ${t} from table ${o} for ${t} with id: ${JSON.stringify(r)}`),await this.adapter.refresh(e,t,r,...c)}catch(e){throw new a.InternalError("Failed to refresh dispatch: "+e)}else i.verbose(`No adapter observed for dispatch; skipping observer update for ${o}:${t}`)}}w&&(w._baseDispatch=ie);class ce{generate(e){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})}static get instance(){return ce._instance||(ce._instance=new ce),ce._instance}}class le{constructor(){this.count=14}generate(e){return(""+((e=(e?parseInt(e):0)||0)+1)).padStart(this.count,"0")}static get instance(){return le._instance||(le._instance=new le),le._instance}}function de(e,t,r,a){const s=async function(...e){let a;try{a=await Promise.resolve(r.call(this,...e))}catch(e){if(e instanceof g)return;throw e}return Promise.resolve(t.apply(this,a))}.bind(e),n=a||t.name;Object.defineProperty(s,"name",{enumerable:!0,configurable:!0,writable:!1,value:n}),e[n]=s}class pe extends s.LoggedClass{constructor(){super(),this.transaction=!0,[this.up,this.down].forEach(e=>{const t=e.name;de(this,e,this.prefix(t))})}get adapter(){const t=o.Metadata.get(this.constructor,e.PersistenceKeys.MIGRATION);if(!t)throw new a.InternalError("No migration metadata for "+this.constructor.name);const r=t.flavour;return w.get(r)}async enforceRules(t,r,a){const s=o.Metadata.get(this.constructor,e.PersistenceKeys.MIGRATION)?.rules;if(!s||!s.length)return!0;for(const e of s)if(!await e(t,r,a))return!1;return!0}prefix(e){return async function(t){let r;t instanceof w?r=this.getQueryRunner(t.client):(r=t,t=this.adapter);const a=await p.args("migration",n.Model,[e],t);if(!await this.enforceRules(r,t,a.context))throw a.context.logger.verbose(`Skipping migration ${this.constructor.name} due to rules`),new g("Migration skipped for rule enforcement");return[r,t,a.context]}.bind(this)}}class ue extends n.Model{constructor(e){super(e)}}r.__decorate([re(),r.__metadata("design:type",Date)],ue.prototype,"createdAt",void 0),r.__decorate([ae(),r.__metadata("design:type",Date)],ue.prototype,"updatedAt",void 0);const he={type:void 0,generated:!1,startWith:0,incrementBy:1,cycle:!1},ge=he,fe={type:"Number",generated:!0,startWith:0,incrementBy:1,cycle:!1},ye=Object.assign({},fe,{type:"BigInt"});async function me(e,t,r,s){if(!t.type||!t.generated||s[r])return;let o;t.name||(t.name=n.Model.sequenceName(s,"pk"));try{o=await this.adapter.Sequence(t)}catch(e){throw new a.InternalError(`Failed to instantiate Sequence ${t.name}: ${e}`)}var i,c,l;i=s,c=r,l=await o.next(e),Reflect.set(i,c,l)}function we(t,r){return(s,i)=>{switch(o.prop()(s,i),t.type){case void 0:{const e=o.Metadata.type(s.constructor,i);if(![Number.name,String.name,BigInt.name].includes(e?.name||e))throw Error("Incorrrect option type");t.type=e;break}case String.name||String.name.toLowerCase():case String:t.generated=!1,t.type=String;break;case Number.name||String.name.toLowerCase():case Number:t.generated=!0,t.type=Number;break;case BigInt.name||BigInt.name.toLowerCase():case BigInt:t.type=BigInt,t.generated=!0;break;case"uuid":case"serial":t.generated=!0;break;default:throw Error("Unsupported type")}void 0===t.generated&&(t.generated=!0);const c=[Z([e.OrderDirection.ASC,e.OrderDirection.DSC]),n.required(),a.readonly(),o.propMetadata(o.Metadata.key(a.DBKeys.ID,i),t),a.onCreate(me,t,r)];return t.generated&&c.push(se()),o.apply(...c)(s,i)}}function be(e=ge){return e=Object.assign({},ge,e),o.Decoration.for(a.DBKeys.ID).define({decorator:we,args:[e,{priority:60}]}).apply()}e.SequenceModel=class extends ue{constructor(e){super(e)}},r.__decorate([be({type:"String",generated:!1}),r.__metadata("design:type",String)],e.SequenceModel.prototype,"id",void 0),r.__decorate([n.required(),Z(),r.__metadata("design:type",Object)],e.SequenceModel.prototype,"current",void 0),e.SequenceModel=r.__decorate([X("??sequence"),n.model(),r.__metadata("design:paramtypes",[Object])],e.SequenceModel);class _e extends f{static{this.lock=new i.MultiLock}constructor(t,r){super(),this.options=t,this.adapter=r,this.repo=T.forModel(e.SequenceModel,r.alias)}async current(...t){const r=(await p.args(a.OperationKeys.READ,e.SequenceModel,t,this.adapter)).context,{name:s,startWith:n}=this.options;try{const e=await this.repo.read(s,r);return this.parse(e.current)}catch(e){const t=r.logger.for(this.current);if(e instanceof a.NotFoundError){if(t.debug(`Sequence.current missing ${s}, returning startWith=${n}`),void 0===n)throw new a.InternalError("Starting value is not defined for a non existing sequence");try{return this.parse(n)}catch(e){throw new a.InternalError(`Failed to parse initial value for sequence ${n}: ${e}`)}}throw new a.InternalError(`Failed to retrieve current value for sequence ${s}: ${e}`)}}async increment(t,r){const s=r.logger.for(this.increment),{type:n,incrementBy:o,name:i}=this.options;if(!i)throw new a.InternalError("S