UNPKG

mongoose-transaction-decorator

Version:
103 lines (102 loc) 4.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transaction = void 0; const mongoose_1 = require("mongoose"); const decorator_1 = require("./decorator"); const als_1 = require("./als"); const modelDistinct = 'distinct'; const specials = { documentAndQueryMiddlewares: ['remove', 'updateOne', 'deleteOne'], modelMethods: ['bulkSave', 'bulkWrite', 'watch', modelDistinct], // 与事务相关却无中间件可触发的model方法 }; // 根据mongoose所有类型中间件(已剔除事务无关中间件)的配置 const middlewareGroups = { ["document" /* document */]: ['save', ...specials.documentAndQueryMiddlewares], ["query" /* query */]: [ 'count', 'countDocuments', 'deleteMany', 'deleteOne', 'estimatedDocumentCount', 'find', 'findOne', 'findOneAndDelete', 'findOneAndRemove', 'findOneAndReplace', 'findOneAndUpdate', 'remove', 'replaceOne', 'update', 'updateOne', 'updateMany', ], ["aggregate" /* aggregate */]: ['aggregate'], ["model" /* model */]: ['insertMany'], // mongoose model无法获取options参数,需要重写方法方式拦截处理 }; /** * 中间件前置钩子,为带事务相关操作的方法自动注入装饰器session * - 若用户无手动设置session时,自动注入事务装饰器的session;否,则不处理 * @param next */ function preCb(next) { const als = new als_1.ALS(); const session = als.get(decorator_1.TRANSACTION_SESSION); if (this instanceof mongoose_1.Document) { this.$session() || this.$session(session); } else if (this instanceof mongoose_1.Query) { this.getOptions().session || this.session(session); } else if (this instanceof mongoose_1.Aggregate) { // FIXME:mongoose类型声明文件不完整,持续关注https://github.com/Automattic/mongoose/issues/11594 this.options.session || this.session(session); } next(); } /** * 重写由于model无法获取options参数的带事务相关的方法 * - 若用户无手动设置session时,自动注入事务装饰器的session;否,则不处理 * @param schema * @param method */ function overwriteMethod(schema, method) { if ([...middlewareGroups.model, ...specials.modelMethods].includes(method)) { const als = new als_1.ALS(); schema.statics[method] = function (...args) { const session = als.get(decorator_1.TRANSACTION_SESSION); if (method !== modelDistinct) { // FIXME: Modle.distinct返回Query, 如果用户后续再继续手动Query.session(userSession)那么自动注入的session将被覆盖 // 持续关注https://github.com/Automattic/mongoose/issues/11587,等待官方提供支持 return mongoose_1.Model.distinct.apply(this, args).session(session); } else { const options = args[1] || {}; // method options parameter if (!(options === null || options === void 0 ? void 0 : options.session)) { args[1] = Object.assign(options, { session }); } return mongoose_1.Model[method].apply(this, args); } }; } } /** * 自动注入session的mongoose插件 * @param schema */ function transaction(schema) { for (const middlewareType in middlewareGroups) { middlewareGroups[middlewareType].forEach(method => { if (middlewareType === "model" /* model */) { overwriteMethod(schema, method); } else if (middlewareType === "document" /* document */ && specials.documentAndQueryMiddlewares.includes(method)) { schema.pre(method, { document: true, query: true }, preCb); } else { schema.pre(method, preCb); } }); } } exports.transaction = transaction;