"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createRemoveCheckers = exports.createAuthCheckers = exports.translateCheckerInSyncContext = exports.translateCheckerInAsyncContext = void 0; var tslib_1 = require("tslib"); var assert_1 = tslib_1.__importDefault(require("assert")); var filter_1 = require("../store/filter"); var Exception_1 = require("../types/Exception"); var types_1 = require("../types"); var actionDef_1 = require("./actionDef"); var string_1 = require("../utils/string"); var lodash_1 = require("../utils/lodash"); var relation_1 = require("./relation"); var uuid_1 = require("../utils/uuid"); function translateCheckerInAsyncContext(checker) { var _this = this; var entity = checker.entity, type = checker.type; var when = 'before'; // 现在create的relation改成提前的expression检查了,原先是先插入再后检查,性能不行,而且select也需要实现前检查 switch (type) { case 'data': { var checkerFn_1 = checker.checker; var fn = (function (_a, context) { var operation = _a.operation; return tslib_1.__awaiter(_this, void 0, void 0, function () { var data; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: data = operation.data; return [4 /*yield*/, checkerFn_1(data, context)]; case 1: _b.sent(); return [2 /*return*/, 0]; } }); }); }); return { fn: fn, when: when, }; } case 'row': { var filter_2 = checker.filter, errMsg_1 = checker.errMsg, inconsistentRows_1 = checker.inconsistentRows; var fn = (function (_a, context, option) { var operation = _a.operation; return tslib_1.__awaiter(_this, void 0, void 0, function () { var operationFilter, action, filter2, _b, entity2, selection2, rows2, e, rows2, e; return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: operationFilter = operation.filter, action = operation.action; if (!(typeof filter_2 === 'function')) return [3 /*break*/, 2]; return [4 /*yield*/, filter_2(operation, context, option)]; case 1: _b = _c.sent(); return [3 /*break*/, 3]; case 2: _b = filter_2; _c.label = 3; case 3: filter2 = _b; if (!['select', 'count', 'stat'].includes(action)) return [3 /*break*/, 4]; operation.filter = (0, filter_1.addFilterSegment)(operationFilter || {}, filter2); return [2 /*return*/, 0]; case 4: return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter || {}, true)]; case 5: if (_c.sent()) { return [2 /*return*/, 0]; } if (!inconsistentRows_1) return [3 /*break*/, 7]; entity2 = inconsistentRows_1.entity, selection2 = inconsistentRows_1.selection; return [4 /*yield*/, context.select(entity2, selection2(operationFilter), { dontCollect: true, blockTrigger: true, })]; case 6: rows2 = _c.sent(); e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_1); e.addData(entity2, rows2); throw e; case 7: return [4 /*yield*/, context.select(entity, { data: (0, actionDef_1.getFullProjection)(entity, context.getSchema()), filter: Object.assign({}, operationFilter, { $not: filter2, }) }, { dontCollect: true, blockTrigger: true, })]; case 8: rows2 = _c.sent(); e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_1); e.addData(entity, rows2); throw e; } }); }); }); return { fn: fn, when: when, }; } case 'relation': { var relationFilter_1 = checker.relationFilter, errMsg = checker.errMsg; var fn = (function (_a, context, option) { var operation = _a.operation; return tslib_1.__awaiter(_this, void 0, void 0, function () { var result, _b; return tslib_1.__generator(this, function (_c) { switch (_c.label) { case 0: if (context.isRoot()) { return [2 /*return*/, 0]; } if (!(typeof relationFilter_1 === 'function')) return [3 /*break*/, 2]; return [4 /*yield*/, relationFilter_1(operation, context, option)]; case 1: _b = _c.sent(); return [3 /*break*/, 3]; case 2: _b = relationFilter_1; _c.label = 3; case 3: result = _b; if (result) { if (operation.action === 'create') { console.warn("".concat(entity, "\u5BF9\u8C61\u7684create\u7C7B\u578B\u7684checker\u4E2D\uFF0C\u5B58\u5728\u65E0\u6CD5\u8F6C\u6362\u4E3A\u8868\u8FBE\u5F0F\u5F62\u5F0F\u7684\u60C5\u51B5\uFF0C\u8BF7\u5C3D\u91CF\u4F7F\u7528authDef\u683C\u5F0F\u5B9A\u4E49\u8FD9\u7C7Bchecker")); } else { operation.filter = (0, filter_1.combineFilters)([operation.filter, result]); } } return [2 /*return*/, 0]; } }); }); }); return { fn: fn, when: when, }; } case 'logical': case 'logicalRelation': { var checkerFn_2 = checker.checker; var fn = (function (_a, context, option) { var operation = _a.operation; return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: if (context.isRoot() && type === 'logicalRelation') { return [2 /*return*/, 0]; } return [4 /*yield*/, checkerFn_2(operation, context, option)]; case 1: _b.sent(); return [2 /*return*/, 0]; } }); }); }); return { fn: fn, when: when, }; } default: { (0, assert_1.default)(false); } } } exports.translateCheckerInAsyncContext = translateCheckerInAsyncContext; function translateCheckerInSyncContext(checker) { var entity = checker.entity, type = checker.type; var when = 'before'; // 现在create的relation改成提前的expression检查了,原先是先插入再后检查,性能不行,而且select也需要实现前检查 switch (type) { case 'data': { var checkerFn_3 = checker.checker; var fn = function (operation, context) { return checkerFn_3(operation.data, context); }; return { fn: fn, when: when, }; } case 'row': { var filter_3 = checker.filter, errMsg_2 = checker.errMsg; var fn = function (operation, context, option) { var operationFilter = operation.filter, action = operation.action; var filter2 = typeof filter_3 === 'function' ? filter_3(operation, context, option) : filter_3; (0, assert_1.default)(operationFilter); if (['select', 'count', 'stat'].includes(action)) { operation.filter = (0, filter_1.addFilterSegment)(operationFilter, filter2); return 0; } else { (0, assert_1.default)(!(filter2 instanceof Promise)); if ((0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter, true)) { return; } var e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_2); throw e; } }; return { fn: fn, when: when, }; } case 'relation': { var relationFilter_2 = checker.relationFilter, errMsg_3 = checker.errMsg; var fn = function (operation, context, option) { if (context.isRoot()) { return; } var result = typeof relationFilter_2 === 'function' ? relationFilter_2(operation, context, option) : relationFilter_2; (0, assert_1.default)(!(result instanceof Promise)); if (result) { var filter = operation.filter, action = operation.action; if (action === 'create') { console.warn("".concat(entity, "\u5BF9\u8C61\u7684create\u7C7B\u578B\u7684checker\u4E2D\uFF0C\u5B58\u5728\u65E0\u6CD5\u8F6C\u6362\u4E3A\u8868\u8FBE\u5F0F\u5F62\u5F0F\u7684\u60C5\u51B5\uFF0C\u8BF7\u5C3D\u91CF\u4F7F\u7528authDef\u683C\u5F0F\u5B9A\u4E49\u8FD9\u7C7Bchecker")); return; } (0, assert_1.default)(filter); if ((0, filter_1.checkFilterContains)(entity, context, result, filter, true)) { return; } throw new Exception_1.OakUserUnpermittedException(errMsg_3); } }; return { fn: fn, when: when, }; } case 'logical': case 'logicalRelation': { var checkerFn_4 = checker.checker; var fn = function (operation, context, option) { if (context.isRoot() && type === 'logicalRelation') { return; } checkerFn_4(operation, context, option); }; return { fn: fn, when: when, }; } default: { (0, assert_1.default)(false); } } } exports.translateCheckerInSyncContext = translateCheckerInSyncContext; function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) { var cascadePath = lch.cascadePath, relations = lch.relations; var paths = cascadePath ? cascadePath.split('.') : []; if (pathPrefix) { paths.unshift(pathPrefix); } var translateRelationFilter = function (entity) { // 有两种情况,此entity和user有Relation定义,或是此entity已经指向user if (entity === 'user') { return function (userId) { return ({ id: userId, }); }; } else if (schema[entity].relation) { if (relations) { var diff = (0, lodash_1.difference)(relations, schema[entity].relation); if (diff.length > 0) { throw new Error("".concat(entity2, "\u4E0A\u67D0auth\u5B9A\u4E49\u7684relations\u4E2D\u542B\u6709\u4E0D\u53EF\u8BC6\u522B\u7684\u5173\u7CFB\u5B9A\u4E49").concat(diff.join(','), "\uFF0C \u8BF7\u4ED4\u7EC6\u68C0\u67E5")); } } var relationEntityName_1 = "user".concat((0, string_1.firstLetterUpperCase)(entity)); return function (userId) { var _a; var filter = relations ? { userId: userId, relation: { $in: relations, }, } : { userId: userId, }; return { id: { $in: { entity: relationEntityName_1, data: (_a = {}, _a["".concat(entity, "Id")] = 1, _a), filter: filter, }, }, }; }; } else { (0, assert_1.default)(false, "".concat(entity2, "\u4E0A\u67D0auth\u5B9A\u4E49\u7684cascadePath").concat(cascadePath, "\u4E0D\u80FD\u5B9A\u4F4D\u5230User\u5BF9\u8C61\u6216\u8005\u548CUser\u5173\u8054\u7684\u5173\u7CFB\u5BF9\u8C61\uFF0C \u8BF7\u4ED4\u7EC6\u68C0\u67E5")); } }; var translateFilterMakerIter = function (entity, iter) { var relation = (0, relation_1.judgeRelation)(schema, entity, paths[iter]); (0, assert_1.default)(relation === 2 || typeof relation === 'string'); if (iter === paths.length - 1) { if (relation === 2) { var filterMaker2_1 = translateRelationFilter(paths[iter]); return function (userId) { var filter = filterMaker2_1(userId); (0, assert_1.default)(filter.id); return { entity: paths[iter], entityId: filter.id, }; }; } var filterMaker2_2 = translateRelationFilter(relation); return function (userId) { var _a; var filter = filterMaker2_2(userId); (0, assert_1.default)(filter.id); return _a = {}, _a["".concat(paths[iter], "Id")] = filter.id, _a; }; } else { var filterMaker_1 = relation === 2 ? translateFilterMakerIter(paths[iter], iter + 1) : translateFilterMakerIter(relation, iter + 1); return function (userId) { var _a; return (_a = {}, _a[paths[iter]] = filterMaker_1(userId), _a); }; } }; var filterMaker = paths.length ? translateFilterMakerIter(entity2, 0) : translateRelationFilter(entity2); if (!paths.length) { return function (oper, userId) { return filterMaker(userId); }; } /** * 针对第一层做一下特别优化,比如对象A指向对象B(多对一),如果A的cascadePath是 'B', * 当create A时,会带有Bid。此时生成该B对象上的相关表达式查询返回,可以避免必须将此判定在对象创建之后再做 * 另一使用场景是,在查询A时,如果带有Bid(在对象跳一对多子对象场景下很常见),可以提前判定这个查询对某些用户一定返回空集 */ var _a = tslib_1.__read(paths, 1), attr = _a[0]; var relation = (0, relation_1.judgeRelation)(schema, entity2, attr); (0, assert_1.default)(relation === 2 || typeof relation === 'string'); var filterMaker2 = paths.length > 1 ? (relation === 2 ? translateFilterMakerIter(attr, 1) : translateFilterMakerIter(relation, 1)) : (relation === 2 ? translateRelationFilter(attr) : translateRelationFilter(relation)); return function (operation, userId) { var action = operation.action; if (action === 'create') { var data = operation.data; var getForeignKeyId_1 = function (d) { if (relation === 2) { if (d.entity === attr && typeof d.entityId === 'string') { return d.entitId; } throw new Exception_1.OakUserUnpermittedException(); } else { (0, assert_1.default)(typeof relation === 'string'); if (typeof d["".concat(attr, "Id")] === 'string') { return d["".concat(attr, "Id")]; } throw new Exception_1.OakUserUnpermittedException(); } }; if (relation === 2) { if (data instanceof Array) { var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); })); return { $entity: attr, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: fkIds } }), $count: fkIds.length, }; } var fkId_1 = getForeignKeyId_1(data); return { $entity: attr, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: fkId_1 }), }; } (0, assert_1.default)(typeof relation === 'string'); if (data instanceof Array) { var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); })); return { $entity: relation, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: fkIds } }), $count: fkIds.length, }; } var fkId = getForeignKeyId_1(data); return { $entity: relation, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: fkId }), }; } var filter = operation.filter; if (relation === 2 && (filter === null || filter === void 0 ? void 0 : filter.entity) === attr && (filter === null || filter === void 0 ? void 0 : filter.entityId)) { if (typeof filter.entityId === 'string') { return { $entity: attr, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: filter.entityId }), }; } else if (filter.entityId.$in && filter.entityId.$in instanceof Array) { var entityIds = (0, lodash_1.uniq)(filter.entityId.$in); return { $entity: relation, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: entityIds } }), $count: entityIds.length, }; } } else if (filter && filter["".concat(attr, "Id")]) { if (typeof filter["".concat(attr, "Id")] === 'string') { return { $entity: attr, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: filter["".concat(attr, "Id")] }), }; } else if (filter["".concat(attr, "Id")].$in && filter["".concat(attr, "Id")].$in instanceof Array) { var entityIds = (0, lodash_1.uniq)(filter["".concat(attr, "Id")].$in); return { $entity: relation, $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: entityIds } }), $count: entityIds.length, }; } } return filterMaker(userId); }; } function translateActionAuthFilterMaker(schema, relationItem, entity, pathPrefix) { if (relationItem instanceof Array) { var maker = relationItem.map(function (ele) { if (ele instanceof Array) { return ele.map(function (ele2) { return translateCascadeRelationFilterMaker(schema, ele2, entity, pathPrefix); }); } return translateCascadeRelationFilterMaker(schema, ele, entity, pathPrefix); }); return maker; } var filterMaker = translateCascadeRelationFilterMaker(schema, relationItem, entity, pathPrefix); return filterMaker; } function makePotentialFilter(operation, context, filterMaker) { var e_1, _a; var userId = context.getCurrentUserId(); (0, assert_1.default)(userId); var filters = filterMaker instanceof Array ? filterMaker.map(function (ele) { if (ele instanceof Array) { return ele.map(function (ele2) { return ele2(operation, userId); }); } return ele(operation, userId); }) : [filterMaker(operation, userId)]; /** * 在下面的逻辑中,如果某个maker返回的是$entity类型,则检查是否有满足条件的项,没有就要抛出异常,有就返回undefined * undefined项即意味着该条件通过 * 再加上and和or的布尔逻辑判断,得到最终结果 * 还要考虑同步和异步…… * 代码比较复杂,因为原先没有$entity这种返回结果的设计 * by Xc 20130219 */ var filtersOr = []; var isAsyncOr = false; var _loop_1 = function (f) { var e_2, _b; if (f instanceof Array) { var isAsyncAnd = true; var filtersAnd = []; var _loop_2 = function (ff) { if (ff === null || ff === void 0 ? void 0 : ff.$entity) { var _e = ff, $entity = _e.$entity, $filter = _e.$filter, _f = _e.$count, $count_1 = _f === void 0 ? 1 : _f; var count = context.count($entity, { filter: $filter, }, {}); if (count instanceof Promise) { isAsyncAnd = true; filtersAnd.push(count.then(function (c2) { if (c2 >= $count_1) { return undefined; } return new Exception_1.OakUserUnpermittedException(); })); } else { filtersAnd.push(count >= $count_1 ? undefined : new Exception_1.OakUserUnpermittedException()); } } else if (ff) { filtersAnd.push(ff); } }; try { for (var f_1 = (e_2 = void 0, tslib_1.__values(f)), f_1_1 = f_1.next(); !f_1_1.done; f_1_1 = f_1.next()) { var ff = f_1_1.value; _loop_2(ff); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (f_1_1 && !f_1_1.done && (_b = f_1.return)) _b.call(f_1); } finally { if (e_2) throw e_2.error; } } if (isAsyncAnd = true) { isAsyncOr = true; filtersOr.push(isAsyncAnd ? Promise.all(filtersAnd).then(function (fa) { var e_3, _a; var faR = []; try { for (var fa_1 = (e_3 = void 0, tslib_1.__values(fa)), fa_1_1 = fa_1.next(); !fa_1_1.done; fa_1_1 = fa_1.next()) { var faItem = fa_1_1.value; if (faItem instanceof Exception_1.OakUserUnpermittedException) { return faItem; } else if (faItem) { faR.push(faItem); } } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (fa_1_1 && !fa_1_1.done && (_a = fa_1.return)) _a.call(fa_1); } finally { if (e_3) throw e_3.error; } } if (faR.length > 0) { return { $and: faR, }; } }) : { $and: filtersAnd, }); } } else { if (f === null || f === void 0 ? void 0 : f.$entity) { var _c = f, $entity = _c.$entity, $filter = _c.$filter, _d = _c.$count, $count_2 = _d === void 0 ? 1 : _d; var count = context.count($entity, { filter: $filter, }, {}); if (count instanceof Promise) { isAsyncOr = true; filtersOr.push(count.then(function (c2) { return c2 >= $count_2 ? undefined : new Exception_1.OakUserUnpermittedException(); })); } else { filtersOr.push(count >= $count_2 ? undefined : new Exception_1.OakUserUnpermittedException()); } } else if (f) { filtersOr.push(f); } } }; try { for (var filters_1 = tslib_1.__values(filters), filters_1_1 = filters_1.next(); !filters_1_1.done; filters_1_1 = filters_1.next()) { var f = filters_1_1.value; _loop_1(f); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (filters_1_1 && !filters_1_1.done && (_a = filters_1.return)) _a.call(filters_1); } finally { if (e_1) throw e_1.error; } } // or的逻辑是,有一个成功就直接通过 var returnOrFilters = function (filters) { if (filters.length === 0 || filters.includes(undefined)) { return undefined; } var foFilters = filters.filter(function (ele) { return ele !== undefined && !(ele instanceof Exception_1.OakUserUnpermittedException); }); if (foFilters.length > 0) { return { $or: foFilters, }; } throw new Exception_1.OakUserUnpermittedException(); }; if (isAsyncOr) { return Promise.all(filtersOr) .then(function (filters) { return returnOrFilters(filters); }); } return returnOrFilters(filtersOr); } /** * 根据权限定义,创建出相应的checker * @param schema * @param authDict * @returns */ function createAuthCheckers(schema, authDict) { var checkers = []; var _loop_3 = function (entity) { var _a; if (authDict[entity]) { var _b = authDict[entity], relationAuth = _b.relationAuth, actionAuth = _b.actionAuth; if (relationAuth) { var raFilterMakerDict_1 = {}; var userEntityName = "user".concat((0, string_1.firstLetterUpperCase)(entity)); for (var r in relationAuth) { Object.assign(raFilterMakerDict_1, (_a = {}, _a[r] = translateActionAuthFilterMaker(schema, relationAuth[r], userEntityName, entity), _a)); } var entityIdAttr_1 = "".concat(entity, "Id"); checkers.push({ entity: userEntityName, action: 'create', type: 'relation', relationFilter: function (operation, context) { var data = operation.data; (0, assert_1.default)(!(data instanceof Array)); var _a = data, relation = _a.relation, _b = entityIdAttr_1, entityId = _a[_b]; if (!raFilterMakerDict_1[relation]) { return; } var filter = makePotentialFilter(operation, context, raFilterMakerDict_1[relation]); return filter; }, errMsg: '越权操作', }); checkers.push({ entity: userEntityName, action: 'remove', type: 'relation', relationFilter: function (operation, context) { // 目前过不去 return undefined; /* const userId = context.getCurrentUserId(); const { filter } = operation as ED[keyof ED]['Remove']; const makeFilterFromRows = (rows: Partial[]): SyncOrAsync => { const relations = uniq(rows.map(ele => ele.relation)); const entityIds = uniq(rows.map(ele => ele[entityIdAttr])); assert(entityIds.length === 1, `在回收${userEntityName}上权限时,单次回收涉及到了不同的对象,此操作不被允许`); // const entityId = entityIds[0]!; // 所有的relation条件要同时满足and关系(注意这里的filter翻译出来是在entity对象上,不是在userEntity对象上) const filtersAnd = relations.map( (relation) => raFilterMakerDict[relation!] ).filter( ele => !!ele ).map( ele => makePotentialFilter(operation, context, ele) ); if (filtersAnd.find(ele => ele instanceof Promise)) { return Promise.all(filtersAnd).then( (fa) => { if (fa.length > 0) { return { $and: fa, } as ED[keyof ED]['Selection']['filter']; } } ); } if (filtersAnd.length > 0) { return { $and: filtersAnd } as ED[keyof ED]['Selection']['filter']; } }; const toBeRemoved = context.select(userEntityName, { data: { id: 1, relation: 1, [entityIdAttr]: 1, }, filter, }, { dontCollect: true }); if (toBeRemoved instanceof Promise) { return toBeRemoved.then( (rows) => makeFilterFromRows(rows) ); } return makeFilterFromRows(toBeRemoved); */ }, errMsg: '越权操作', }); // 转让权限现在用update动作,只允许update userId给其它人 // todo 等实现的时候再写 } if (actionAuth) { var _loop_4 = function (a) { var filterMaker = translateActionAuthFilterMaker(schema, actionAuth[a], entity); checkers.push({ entity: entity, action: a, type: 'relation', relationFilter: function (operation, context) { // const { filter } = operation; var filter = makePotentialFilter(operation, context, filterMaker); return filter; }, errMsg: '定义的actionAuth中检查出来越权操作', }); }; for (var a in actionAuth) { _loop_4(a); } } } }; for (var entity in schema) { _loop_3(entity); } return checkers; } exports.createAuthCheckers = createAuthCheckers; /** * 对对象的删除,检查其是否会产生其他行上的空指针,不允许这种情况的出现 * @param schema * @returns * 如果有的对象允许删除,需要使用trigger来处理其相关联的外键对象,这些trigger写作before,则会在checker之前执行,仍然可以删除成功 */ function createRemoveCheckers(schema, authDict) { var e_4, _a; var checkers = []; // 先建立所有的一对多的关系 var OneToManyMatrix = {}; var OneToManyOnEntityMatrix = {}; var addToMto = function (e, f, attr) { var _a; if (OneToManyMatrix[f]) { (_a = OneToManyMatrix[f]) === null || _a === void 0 ? void 0 : _a.push([e, attr]); } else { OneToManyMatrix[f] = [[e, attr]]; } }; var addToMtoEntity = function (e, fs) { var e_5, _a; var _b; try { for (var fs_1 = tslib_1.__values(fs), fs_1_1 = fs_1.next(); !fs_1_1.done; fs_1_1 = fs_1.next()) { var f = fs_1_1.value; if (!OneToManyOnEntityMatrix[f]) { OneToManyOnEntityMatrix[f] = [e]; } else { (_b = OneToManyOnEntityMatrix[f]) === null || _b === void 0 ? void 0 : _b.push(e); } } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (fs_1_1 && !fs_1_1.done && (_a = fs_1.return)) _a.call(fs_1); } finally { if (e_5) throw e_5.error; } } }; for (var entity in schema) { if (['operEntity', 'modiEntity', 'userEntityGrant'].includes(entity)) { continue; // 系统功能性数据,不用处理 } var attributes = schema[entity].attributes; for (var attr in attributes) { if (attributes[attr].type === 'ref') { addToMto(entity, attributes[attr].ref, attr); } else if (attr === 'entity') { if (attributes[attr].ref) { addToMtoEntity(entity, attributes[attr].ref); } else if (process.env.NODE_ENV === 'development') { console.warn("".concat(entity, "\u7684entity\u53CD\u6307\u6307\u9488\u627E\u4E0D\u5230\u6709\u6548\u7684\u5BF9\u8C61")); } } } } // 当删除一时,要确认多上面没有指向一的数据 var entities = (0, lodash_1.union)(Object.keys(OneToManyMatrix), Object.keys(OneToManyOnEntityMatrix)); var _loop_5 = function (entity) { checkers.push({ entity: entity, action: 'remove', type: 'logical', checker: function (operation, context, option) { var e_6, _a, e_7, _b; var promises = []; if (OneToManyMatrix[entity]) { var _loop_7 = function (otm) { var _g, _h; var _j = tslib_1.__read(otm, 2), e = _j[0], attr = _j[1]; var proj = (_g = { id: 1 }, _g[attr] = 1, _g); var filter = operation.filter && (_h = {}, _h[attr.slice(0, attr.length - 2)] = operation.filter, _h); var result = context.select(e, { data: proj, filter: filter, indexFrom: 0, count: 1 }, { dontCollect: true }); if (result instanceof Promise) { promises.push(result.then(function (_a) { var _b = tslib_1.__read(_a, 1), row = _b[0]; if (row) { var err = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(e, "\u300D\u5173\u8054\u7684\u884C")); err.addData(e, [row]); throw err; } })); } else { var _k = tslib_1.__read(result, 1), row = _k[0]; if (row) { var err = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(e, "\u300D\u5173\u8054\u7684\u884C")); err.addData(e, [row]); throw err; } } }; try { for (var _c = (e_6 = void 0, tslib_1.__values(OneToManyMatrix[entity])), _d = _c.next(); !_d.done; _d = _c.next()) { var otm = _d.value; _loop_7(otm); } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_6) throw e_6.error; } } } if (OneToManyOnEntityMatrix[entity]) { var _loop_8 = function (otm) { var _l, _m, _o; var proj = { id: 1, entity: 1, entityId: 1, }; var filter = operation.filter && (_l = {}, _l[entity] = operation.filter, _l); var result = context.select(otm, { data: proj, filter: filter, indexFrom: 0, count: 1 }, { dontCollect: true }); if (result instanceof Promise) { promises.push(result.then(function (_a) { var _b = tslib_1.__read(_a, 1), row = _b[0]; if (row) { var e = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(otm, "\u300D\u5173\u8054\u7684\u884C")); e.addData(otm, [row]); throw e; } })); } else { var _p = tslib_1.__read(result, 1), row = _p[0]; if (row) { var record = { a: 's', d: (_m = {}, _m[otm] = (_o = {}, _o[row.id] = row, _o), _m) }; var e = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(otm, "\u300D\u5173\u8054\u7684\u884C")); e.addData(otm, [row]); throw e; } } }; try { for (var _e = (e_7 = void 0, tslib_1.__values(OneToManyOnEntityMatrix[entity])), _f = _e.next(); !_f.done; _f = _e.next()) { var otm = _f.value; _loop_8(otm); } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_7) throw e_7.error; } } } if (promises.length > 0) { return Promise.all(promises).then(function () { return undefined; }); } } }); }; try { for (var entities_1 = tslib_1.__values(entities), entities_1_1 = entities_1.next(); !entities_1_1.done; entities_1_1 = entities_1.next()) { var entity = entities_1_1.value; _loop_5(entity); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1); } finally { if (e_4) throw e_4.error; } } var _loop_6 = function (entity) { var e_8, _b; var cascadeRemove = authDict[entity].cascadeRemove; if (cascadeRemove) { var entitiesOnEntityAttr = []; var hasAllEntity = false; var _loop_9 = function (attr) { if (attr === '@entity') { hasAllEntity = true; return "continue"; } var rel = (0, relation_1.judgeRelation)(schema, entity, attr); if (rel === 2) { entitiesOnEntityAttr.push(attr); checkers.push({ entity: attr, action: 'remove', type: 'logical', priority: types_1.REMOVE_CASCADE_PRIORITY, checker: function (operation, context) { var _a, _b; var filter = operation.filter; if (cascadeRemove[attr] === 'remove') { return context.operate(entity, { id: (0, uuid_1.generateNewId)(), action: 'remove', data: {}, filter: filter ? (_a = {}, _a[attr] = filter, _a) : undefined, }, { dontCollect: true }); } return context.operate(entity, { id: (0, uuid_1.generateNewId)(), action: 'update', data: { entity: null, entityId: null, }, filter: filter ? (_b = {}, _b[attr] = filter, _b) : undefined, }, { dontCollect: true }); } }); } else { (0, assert_1.default)(typeof rel === 'string'); checkers.push({ entity: rel, action: 'remove', type: 'logical', priority: types_1.REMOVE_CASCADE_PRIORITY, checker: function (operation, context) { var _a, _b, _c; var filter = operation.filter; if (cascadeRemove[attr] === 'remove') { return context.operate(entity, { id: (0, uuid_1.generateNewId)(), action: 'remove', data: {}, filter: filter ? (_a = {}, _a[attr] = filter, _a) : undefined, }, { dontCollect: true }); } return context.operate(entity, { id: (0, uuid_1.generateNewId)(), action: 'update', data: (_b = {}, _b["".concat(attr, "Id")] = null, _b), filter: filter ? (_c = {}, _c[attr] = filter, _c) : undefined, }, { dontCollect: true }); } }); } }; for (var attr in cascadeRemove) { _loop_9(attr); } if (hasAllEntity) { var attributes = schema[entity].attributes; var ref = attributes.entity.ref; var restEntities = (0, lodash_1.difference)(ref, entitiesOnEntityAttr); var _loop_10 = function (e) { checkers.push({ entity: e, action: 'remove', type: 'logical', priority: types_1.REMOVE_CASCADE_PRIORITY, checker: function (operation, context) { var _a, _b; var filter = operation.filter; if (cascadeRemove['@entity'] === 'remove') { return context.operate(entity, { id: (0, uuid_1.generateNewId)(), action: 'remove', data: {}, filter: filter ? (_a = {}, _a[e] = filter, _a) : undefined, }, { dontCollect: true }); } return context.operate(entity, { id: (0, uuid_1.generateNewId)(), action: 'update', data: { entity: null, entityId: null, }, filter: filter ? (_b = {}, _b[e] = filter, _b) : undefined, }, { dontCollect: true }); } }); }; try { for (var restEntities_1 = (e_8 = void 0, tslib_1.__values(restEntities)), restEntities_1_1 = restEntities_1.next(); !restEntities_1_1.done; restEntities_1_1 = restEntities_1.next()) { var e = restEntities_1_1.value; _loop_10(e); } } catch (e_8_1) { e_8 = { error: e_8_1 }; } finally { try { if (restEntities_1_1 && !restEntities_1_1.done && (_b = restEntities_1.return)) _b.call(restEntities_1); } finally { if (e_8) throw e_8.error; } } } } }; // 注入声明的cascade删除时的外键处理动作 for (var entity in authDict) { _loop_6(entity); } return checkers; } exports.createRemoveCheckers = createRemoveCheckers;