UNPKG

monguito

Version:

MongoDB Abstract Repository implementation for Node.js

3 lines (2 loc) 8.19 kB
import t,{Schema as e}from"mongoose";import{Optional as n}from"typescript-optional";class i{constructor(t){this.createdAt=void 0,this.createdBy=void 0,this.updatedAt=void 0,this.updatedBy=void 0,this.version=void 0,this.createdAt=t.createdAt?new Date(t.createdAt):void 0,this.createdBy=t.createdBy,this.updatedAt=t.updatedAt?new Date(t.updatedAt):void 0,this.updatedBy=t.updatedBy,this.version=t.version}}const s=t=>t&&"createdAt"in t&&"updatedAt"in t&&"createdBy"in t&&"updatedBy"in t;class o extends Error{constructor(t,e){super(t,{cause:e}),this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class r extends o{constructor(t,e){super(t,e)}}class a extends o{constructor(t,e){super(t,e)}}class u extends o{constructor(t,e){super(t,e)}}class l extends o{constructor(t,e){super(t,e),this.cause=void 0,this.cause=e}getInvalidFields(){return Object.keys(this.cause.errors)}getInvalidRequiredFields(){return this.getInvalidFieldsOfKind("required")}getInvalidUniqueFields(){return this.getInvalidFieldsOfKind("unique")}getInvalidFieldsOfKind(t){const e=[];for(const n in this.cause.errors){const i=this.cause.errors[n];i.kind===t&&e.push(i.path)}return e}}class c{constructor(t){if(this.type=void 0,this.schema=void 0,this.subtypes=void 0,!t.type||!t.schema)throw new r("The given domain model must specify a type and a schema");this.type=t.type,this.schema=t.schema,this.subtypes=[];for(const n of null!=(e=t.subtypes)?e:[]){var e;this.subtypes.push(new c(n))}}getSubtypeTree(){return this.subtypes||[]}getSubtypeData(t){var e;return null==(e=this.subtypes)?void 0:e.find(e=>e.type.name===t)}getSubtypeConstructor(t){const e=this.getSubtypeData(t);return null==e?void 0:e.type}getSupertypeConstructor(){return this.type}getSupertypeName(){return this.type.name}has(t){return t===this.getSupertypeName()||!!this.getSubtypeData(t)}}class d{constructor(t,e){this.connection=void 0,this.domainTree=void 0,this.entityModel=void 0,this.connection=e,this.domainTree=new c(t),this.entityModel=this.createEntityModel(e)}createEntityModel(e){let n;n=e?e.model(this.domainTree.type.name,this.domainTree.schema):t.model(this.domainTree.type.name,this.domainTree.schema);for(const t of this.domainTree.getSubtypeTree())n.discriminator(t.type.name,t.schema);return n}async findById(t,e){var i;if(!t)throw new r("The given ID must be valid");const s=await this.entityModel.findById(t).session(null!=(i=null==e?void 0:e.session)?i:null).exec();return n.ofNullable(this.instantiateFrom(s))}async findOne(t){var e,i;const s=await this.entityModel.findOne(null!=(e=null==t?void 0:t.filters)?e:void 0).session(null!=(i=null==t?void 0:t.session)?i:null).exec();return n.ofNullable(this.instantiateFrom(s))}async findAll(t){var e,n,i,s,o,a,u,l;if(null!=t&&null!=(e=t.pageable)&&e.pageNumber&&(null==t||null==(n=t.pageable)?void 0:n.pageNumber)<0)throw new r("The given page number must be a positive number");if(null!=t&&null!=(i=t.pageable)&&i.offset&&(null==t||null==(s=t.pageable)?void 0:s.offset)<0)throw new r("The given page offset must be a positive number");const c=null!=(o=null==t||null==(a=t.pageable)?void 0:a.offset)?o:0,d=null!=(u=null==t||null==(l=t.pageable)?void 0:l.pageNumber)?u:0;try{var h;return(await this.entityModel.find(null==t?void 0:t.filters).skip(d>0?(d-1)*c:0).limit(c).sort(null==t?void 0:t.sortBy).session(null!=(h=null==t?void 0:t.session)?h:null).exec()).map(t=>this.instantiateFrom(t))}catch(t){throw new r("The given optional parameters must be valid",t)}}async save(t,e){if(!t)throw new r("The given entity cannot be null or undefined");return t.id?await this.update(t,e):await this.insert(t,e)}async insert(e,n){if(!e)throw new r("The given entity cannot be null or undefined");try{const t=this.createDocumentForInsertion(e,n),i=await t.save({session:null==n?void 0:n.session});return this.instantiateFrom(i)}catch(e){throw e instanceof t.Error.ValidationError?new l("One or more fields of the given entity do not specify valid values",e):e}}createDocumentForInsertion(t,e){this.setDiscriminatorKeyOnEntity(t);const n=new this.entityModel(t);return this.setAuditableDataOnDocumentToInsert(n,t,null==e?void 0:e.userId),n}setDiscriminatorKeyOnEntity(t){const e=t.constructor.name;if(!this.domainTree.has(e))throw new r(`The entity with name ${e} is not included in the setup of the custom repository`);e!==this.domainTree.getSupertypeName()&&!("__t"in t)&&(t.__t=e)}setAuditableDataOnDocumentToInsert(t,e,n){s(e)&&(n&&(t.$locals.userId=n),t.__v=0)}async update(e,n){var i;if(!e)throw new r("The given entity must be valid");const s=await this.entityModel.findById(e.id).session(null!=(i=null==n?void 0:n.session)?i:null);if(s)try{s.set(e),this.setAuditableDataOnDocumentToUpdate(s,null==n?void 0:n.userId);const t=await s.save({session:null==n?void 0:n.session});return this.instantiateFrom(t)}catch(e){throw e instanceof t.Error.ValidationError?new l("One or more fields of the given entity do not specify valid values",e):e}throw new r(`There is no document matching the given ID '${e.id}'`)}setAuditableDataOnDocumentToUpdate(t,e){var n;t.isNew=!1,s(t)&&(e&&(t.$locals.userId=e),t.__v=(null!=(n=t.__v)?n:0)+1)}async deleteById(t,e){if(!t)throw new r("The given ID must be valid");return!!await this.entityModel.findByIdAndDelete(t,{session:null==e?void 0:e.session})}instantiateFrom(t){if(!t)return null;const e=t.get("__t"),n=e?this.domainTree.getSubtypeConstructor(e):this.domainTree.getSupertypeConstructor();if(n)try{return new n(t.toObject())}catch(e){throw new a(`An error occurred while instantiating an entity with ID ${t.id}`,e)}throw new u(`There is no registered instance constructor for the document with ID ${t.id} or the corresponding entity type is abstract`)}}function h(){return h=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)({}).hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},h.apply(null,arguments)}async function p(t,e){return null!=e&&e.session?t(e.session):await y(t,0,null==e?void 0:e.connection)}async function y(e,n,i){const s=await async function(e){return e?await e.startSession():await t.connection.startSession()}(i);s.startTransaction();try{const t=await e(s);return await s.commitTransaction(),t}catch(t){if(await s.abortTransaction(),function(t){return t.message.includes("does not match any in-progress transactions")}(t)&&n<3)return y(e,++n,i);throw t}finally{s.endSession()}}class v extends d{constructor(t,e){super(t,e)}async saveAll(t,e){var n=this;return await p(async function(i){return await Promise.all(t.map(async function(t){return await n.save(t,{userId:null==e?void 0:e.userId,session:i})}))},h({},e,{connection:this.connection}))}async deleteAll(t){var e=this;return await p(async function(n){return(await e.entityModel.deleteMany(null==t?void 0:t.filters,{session:n})).deletedCount},h({},t,{connection:this.connection}))}async update(t,e){const n=super.update.bind(this);return await p(async function(i){var s;return await n(t,{userId:null==e?void 0:e.userId,session:null!=(s=null==e?void 0:e.session)?s:i})},{connection:this.connection})}}const m=new e({},{toObject:{transform:(t,e)=>{e.id=t.id,delete e._id}}}),f=w(m,{createdBy:{type:String},updatedBy:{type:String}},{timestamps:!0,toObject:{transform:(t,e)=>{e.id=t.id,e.version=t.__v,delete e._id,delete e.__v}},plugins:[{fn:function(t){t.pre("save",function(t){this.$locals.userId&&(this.createdBy||(this.createdBy=this.$locals.userId),this.updatedBy=this.$locals.userId),delete this.$locals.userId,t()})}}]});function w(t,n,i){const s=n instanceof e,o=new e(h({},t.obj,s?n.obj:n),h({},t.options,s?n.options:i));return function(t,n,i,s){n.plugins.forEach(e=>{t.plugin(e.fn,e.options)}),i instanceof e&&i.plugins.forEach(e=>{t.plugin(e.fn,e.options)}),null!=s&&s.plugins&&s.plugins.forEach(e=>{t.plugin(e.fn,e.options)})}(o,t,n,i),o}export{i as AuditableClass,f as AuditableSchema,m as BaseSchema,r as IllegalArgumentException,d as MongooseRepository,v as MongooseTransactionalRepository,u as UndefinedConstructorException,l as ValidationException,w as extendSchema,s as isAuditable,p as runInTransaction}; //# sourceMappingURL=repo.modern.js.map