Merge branch 'release'
This commit is contained in:
commit
287659de1e
|
|
@ -33,7 +33,7 @@ var TriggerExecutor = /** @class */ (function () {
|
||||||
TriggerExecutor.prototype.registerChecker = function (checker) {
|
TriggerExecutor.prototype.registerChecker = function (checker) {
|
||||||
var entity = checker.entity, action = checker.action, type = checker.type, conditionalFilter = checker.conditionalFilter;
|
var entity = checker.entity, action = checker.action, type = checker.type, conditionalFilter = checker.conditionalFilter;
|
||||||
var triggerName = "".concat(String(entity)).concat(action, "\u6743\u9650\u68C0\u67E5-").concat(this.counter++);
|
var triggerName = "".concat(String(entity)).concat(action, "\u6743\u9650\u68C0\u67E5-").concat(this.counter++);
|
||||||
var _a = (0, checker_1.translateCheckerInAsyncContext)(checker), fn = _a.fn, when = _a.when;
|
var _a = (0, checker_1.translateCheckerInAsyncContext)(checker, true), fn = _a.fn, when = _a.when;
|
||||||
var priority = type === 'data' ? Trigger_1.DATA_CHECKER_DEFAULT_PRIORITY : Trigger_1.CHECKER_DEFAULT_PRIORITY; // checker的默认优先级最低(前面的trigger可能会赋上一些相应的值)
|
var priority = type === 'data' ? Trigger_1.DATA_CHECKER_DEFAULT_PRIORITY : Trigger_1.CHECKER_DEFAULT_PRIORITY; // checker的默认优先级最低(前面的trigger可能会赋上一些相应的值)
|
||||||
var trigger = {
|
var trigger = {
|
||||||
checkerType: type,
|
checkerType: type,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,13 @@ import { AuthDefDict, Checker, EntityDict, OperateOption, SelectOption, StorageS
|
||||||
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
||||||
import { AsyncContext } from "./AsyncRowStore";
|
import { AsyncContext } from "./AsyncRowStore";
|
||||||
import { SyncContext } from './SyncRowStore';
|
import { SyncContext } from './SyncRowStore';
|
||||||
export declare function translateCheckerInAsyncContext<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>): {
|
/**
|
||||||
|
*
|
||||||
|
* @param checker 要翻译的checker
|
||||||
|
* @param silent 如果silent,则row和relation类型的checker只会把限制条件加到查询上,而不报错(除掉create动作)
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export declare function translateCheckerInAsyncContext<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>, silent?: boolean): {
|
||||||
fn: Trigger<ED, T, Cxt>['fn'];
|
fn: Trigger<ED, T, Cxt>['fn'];
|
||||||
when: 'before' | 'after';
|
when: 'before' | 'after';
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,13 @@ var string_1 = require("../utils/string");
|
||||||
var lodash_1 = require("../utils/lodash");
|
var lodash_1 = require("../utils/lodash");
|
||||||
var relation_1 = require("./relation");
|
var relation_1 = require("./relation");
|
||||||
var uuid_1 = require("../utils/uuid");
|
var uuid_1 = require("../utils/uuid");
|
||||||
function translateCheckerInAsyncContext(checker) {
|
/**
|
||||||
|
*
|
||||||
|
* @param checker 要翻译的checker
|
||||||
|
* @param silent 如果silent,则row和relation类型的checker只会把限制条件加到查询上,而不报错(除掉create动作)
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function translateCheckerInAsyncContext(checker, silent) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
var entity = checker.entity, type = checker.type;
|
var entity = checker.entity, type = checker.type;
|
||||||
var when = 'before'; // 现在create的relation改成提前的expression检查了,原先是先插入再后检查,性能不行,而且select也需要实现前检查
|
var when = 'before'; // 现在create的relation改成提前的expression检查了,原先是先插入再后检查,性能不行,而且select也需要实现前检查
|
||||||
|
|
@ -59,7 +65,7 @@ function translateCheckerInAsyncContext(checker) {
|
||||||
_c.label = 3;
|
_c.label = 3;
|
||||||
case 3:
|
case 3:
|
||||||
filter2 = _b;
|
filter2 = _b;
|
||||||
if (!['select', 'count', 'stat'].includes(action)) return [3 /*break*/, 4];
|
if (!silent) return [3 /*break*/, 4];
|
||||||
operation.filter = (0, filter_1.addFilterSegment)(operationFilter || {}, filter2);
|
operation.filter = (0, filter_1.addFilterSegment)(operationFilter || {}, filter2);
|
||||||
return [2 /*return*/, 0];
|
return [2 /*return*/, 0];
|
||||||
case 4: return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter || {}, true)];
|
case 4: return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter || {}, true)];
|
||||||
|
|
@ -102,11 +108,11 @@ function translateCheckerInAsyncContext(checker) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case 'relation': {
|
case 'relation': {
|
||||||
var relationFilter_1 = checker.relationFilter, errMsg = checker.errMsg;
|
var relationFilter_1 = checker.relationFilter, errMsg_2 = checker.errMsg;
|
||||||
var fn = (function (_a, context, option) {
|
var fn = (function (_a, context, option) {
|
||||||
var operation = _a.operation;
|
var operation = _a.operation;
|
||||||
return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
||||||
var result, _b;
|
var result, _b, filter, action;
|
||||||
return tslib_1.__generator(this, function (_c) {
|
return tslib_1.__generator(this, function (_c) {
|
||||||
switch (_c.label) {
|
switch (_c.label) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -123,15 +129,24 @@ function translateCheckerInAsyncContext(checker) {
|
||||||
_c.label = 3;
|
_c.label = 3;
|
||||||
case 3:
|
case 3:
|
||||||
result = _b;
|
result = _b;
|
||||||
if (result) {
|
if (!result) return [3 /*break*/, 5];
|
||||||
if (operation.action === 'create') {
|
filter = operation.filter, action = operation.action;
|
||||||
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"));
|
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"));
|
||||||
else {
|
return [2 /*return*/, 0];
|
||||||
operation.filter = (0, filter_1.combineFilters)([operation.filter, result]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return [2 /*return*/, 0];
|
if (silent) {
|
||||||
|
operation.filter = (0, filter_1.addFilterSegment)(filter || {}, result);
|
||||||
|
return [2 /*return*/, 0];
|
||||||
|
}
|
||||||
|
(0, assert_1.default)(filter);
|
||||||
|
return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, result, filter, true)];
|
||||||
|
case 4:
|
||||||
|
if (_c.sent()) {
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
throw new Exception_1.OakUserUnpermittedException(errMsg_2);
|
||||||
|
case 5: return [2 /*return*/, 0];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -185,23 +200,17 @@ function translateCheckerInSyncContext(checker) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case 'row': {
|
case 'row': {
|
||||||
var filter_3 = checker.filter, errMsg_2 = checker.errMsg;
|
var filter_3 = checker.filter, errMsg_3 = checker.errMsg;
|
||||||
var fn = function (operation, context, option) {
|
var fn = function (operation, context, option) {
|
||||||
var operationFilter = operation.filter, action = operation.action;
|
var operationFilter = operation.filter, action = operation.action;
|
||||||
var filter2 = typeof filter_3 === 'function' ? filter_3(operation, context, option) : filter_3;
|
var filter2 = typeof filter_3 === 'function' ? filter_3(operation, context, option) : filter_3;
|
||||||
(0, assert_1.default)(operationFilter);
|
(0, assert_1.default)(operationFilter);
|
||||||
if (['select', 'count', 'stat'].includes(action)) {
|
(0, assert_1.default)(!(filter2 instanceof Promise));
|
||||||
operation.filter = (0, filter_1.addFilterSegment)(operationFilter, filter2);
|
if ((0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter, true)) {
|
||||||
return 0;
|
return;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
var e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_3);
|
||||||
|
throw e;
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
fn: fn,
|
fn: fn,
|
||||||
|
|
@ -209,7 +218,7 @@ function translateCheckerInSyncContext(checker) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case 'relation': {
|
case 'relation': {
|
||||||
var relationFilter_2 = checker.relationFilter, errMsg_3 = checker.errMsg;
|
var relationFilter_2 = checker.relationFilter, errMsg_4 = checker.errMsg;
|
||||||
var fn = function (operation, context, option) {
|
var fn = function (operation, context, option) {
|
||||||
if (context.isRoot()) {
|
if (context.isRoot()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -226,7 +235,7 @@ function translateCheckerInSyncContext(checker) {
|
||||||
if ((0, filter_1.checkFilterContains)(entity, context, result, filter, true)) {
|
if ((0, filter_1.checkFilterContains)(entity, context, result, filter, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new Exception_1.OakUserUnpermittedException(errMsg_3);
|
throw new Exception_1.OakUserUnpermittedException(errMsg_4);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -107,3 +107,4 @@ export declare function makeTreeDescendantFilter<ED extends EntityDict, T extend
|
||||||
*/
|
*/
|
||||||
export declare function checkFilterContains<ED extends EntityDict, T extends keyof ED, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, context: Cxt, contained: ED[T]['Selection']['filter'], filter?: ED[T]['Selection']['filter'], dataCompare?: true): boolean | Promise<boolean>;
|
export declare function checkFilterContains<ED extends EntityDict, T extends keyof ED, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, context: Cxt, contained: ED[T]['Selection']['filter'], filter?: ED[T]['Selection']['filter'], dataCompare?: true): boolean | Promise<boolean>;
|
||||||
export declare function checkFilterRepel<ED extends EntityDict, T extends keyof ED, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, context: Cxt, filter1: ED[T]['Selection']['filter'], filter2: ED[T]['Selection']['filter'], dataCompare?: true): boolean | Promise<boolean>;
|
export declare function checkFilterRepel<ED extends EntityDict, T extends keyof ED, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, context: Cxt, filter1: ED[T]['Selection']['filter'], filter2: ED[T]['Selection']['filter'], dataCompare?: true): boolean | Promise<boolean>;
|
||||||
|
export declare function getCascadeEntityFilter<ED extends EntityDict, T extends keyof ED>(filter: NonNullable<ED[T]['Selection']['filter']>, attr: keyof NonNullable<ED[T]['Selection']['filter']>): ED[keyof ED]['Selection']['filter'];
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.checkFilterRepel = exports.checkFilterContains = exports.makeTreeDescendantFilter = exports.makeTreeAncestorFilter = exports.same = exports.getRelevantIds = exports.repel = exports.contains = exports.judgeValueRelation = exports.combineFilters = exports.unionFilterSegment = exports.addFilterSegment = void 0;
|
exports.getCascadeEntityFilter = exports.checkFilterRepel = exports.checkFilterContains = exports.makeTreeDescendantFilter = exports.makeTreeAncestorFilter = exports.same = exports.getRelevantIds = exports.repel = exports.contains = exports.judgeValueRelation = exports.combineFilters = exports.unionFilterSegment = exports.addFilterSegment = void 0;
|
||||||
var tslib_1 = require("tslib");
|
var tslib_1 = require("tslib");
|
||||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||||
var types_1 = require("../types");
|
var types_1 = require("../types");
|
||||||
|
|
@ -845,6 +845,7 @@ function checkFilterContains(entity, context, contained, filter, dataCompare) {
|
||||||
}]);
|
}]);
|
||||||
var count = context.count(entity, {
|
var count = context.count(entity, {
|
||||||
filter: filter2,
|
filter: filter2,
|
||||||
|
count: 1,
|
||||||
}, {
|
}, {
|
||||||
dontCollect: true,
|
dontCollect: true,
|
||||||
blockTrigger: true,
|
blockTrigger: true,
|
||||||
|
|
@ -883,3 +884,22 @@ function checkFilterRepel(entity, context, filter1, filter2, dataCompare) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
exports.checkFilterRepel = checkFilterRepel;
|
exports.checkFilterRepel = checkFilterRepel;
|
||||||
|
function getCascadeEntityFilter(filter, attr) {
|
||||||
|
var filters = [];
|
||||||
|
if (filter[attr]) {
|
||||||
|
(0, assert_1.default)(typeof filter[attr] === 'object');
|
||||||
|
filters.push(filter[attr]);
|
||||||
|
}
|
||||||
|
if (filter.$and) {
|
||||||
|
filter.$and.forEach(function (ele) {
|
||||||
|
var f2 = getCascadeEntityFilter(ele, attr);
|
||||||
|
if (f2) {
|
||||||
|
filters.push(f2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (filters.length > 0) {
|
||||||
|
return combineFilters(filters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.getCascadeEntityFilter = getCascadeEntityFilter;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "oak-domain",
|
"name": "oak-domain",
|
||||||
"version": "2.6.5",
|
"version": "2.6.6",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "XuChang"
|
"name": "XuChang"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict> {
|
||||||
registerChecker<T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>): void {
|
registerChecker<T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>): void {
|
||||||
const { entity, action, type, conditionalFilter } = checker;
|
const { entity, action, type, conditionalFilter } = checker;
|
||||||
const triggerName = `${String(entity)}${action}权限检查-${this.counter++}`;
|
const triggerName = `${String(entity)}${action}权限检查-${this.counter++}`;
|
||||||
const { fn, when } = translateCheckerInAsyncContext(checker);
|
const { fn, when } = translateCheckerInAsyncContext(checker, true);
|
||||||
const priority = type === 'data' ? DATA_CHECKER_DEFAULT_PRIORITY : CHECKER_DEFAULT_PRIORITY; // checker的默认优先级最低(前面的trigger可能会赋上一些相应的值)
|
const priority = type === 'data' ? DATA_CHECKER_DEFAULT_PRIORITY : CHECKER_DEFAULT_PRIORITY; // checker的默认优先级最低(前面的trigger可能会赋上一些相应的值)
|
||||||
const trigger = {
|
const trigger = {
|
||||||
checkerType: type,
|
checkerType: type,
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,17 @@ import { union, uniq, difference } from '../utils/lodash';
|
||||||
import { judgeRelation } from './relation';
|
import { judgeRelation } from './relation';
|
||||||
import { generateNewId } from '../utils/uuid';
|
import { generateNewId } from '../utils/uuid';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param checker 要翻译的checker
|
||||||
|
* @param silent 如果silent,则row和relation类型的checker只会把限制条件加到查询上,而不报错(除掉create动作)
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function translateCheckerInAsyncContext<
|
export function translateCheckerInAsyncContext<
|
||||||
ED extends EntityDict & BaseEntityDict,
|
ED extends EntityDict & BaseEntityDict,
|
||||||
T extends keyof ED,
|
T extends keyof ED,
|
||||||
Cxt extends AsyncContext<ED>
|
Cxt extends AsyncContext<ED>
|
||||||
>(checker: Checker<ED, T, Cxt>): {
|
>(checker: Checker<ED, T, Cxt>, silent?: boolean): {
|
||||||
fn: Trigger<ED, T, Cxt>['fn'];
|
fn: Trigger<ED, T, Cxt>['fn'];
|
||||||
when: 'before' | 'after';
|
when: 'before' | 'after';
|
||||||
} {
|
} {
|
||||||
|
|
@ -42,7 +48,7 @@ export function translateCheckerInAsyncContext<
|
||||||
const fn = (async ({ operation }, context, option) => {
|
const fn = (async ({ operation }, context, option) => {
|
||||||
const { filter: operationFilter, action } = operation;
|
const { filter: operationFilter, action } = operation;
|
||||||
const filter2 = typeof filter === 'function' ? await (filter as Function)(operation, context, option) : filter;
|
const filter2 = typeof filter === 'function' ? await (filter as Function)(operation, context, option) : filter;
|
||||||
if (['select', 'count', 'stat'].includes(action)) {
|
if (silent) {
|
||||||
operation.filter = addFilterSegment(operationFilter || {}, filter2);
|
operation.filter = addFilterSegment(operationFilter || {}, filter2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -95,12 +101,20 @@ export function translateCheckerInAsyncContext<
|
||||||
const result = typeof relationFilter === 'function' ? await relationFilter(operation, context, option) : relationFilter;
|
const result = typeof relationFilter === 'function' ? await relationFilter(operation, context, option) : relationFilter;
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
if (operation.action === 'create') {
|
const { filter, action } = operation;
|
||||||
|
if (action === 'create') {
|
||||||
console.warn(`${entity as string}对象的create类型的checker中,存在无法转换为表达式形式的情况,请尽量使用authDef格式定义这类checker`);
|
console.warn(`${entity as string}对象的create类型的checker中,存在无法转换为表达式形式的情况,请尽量使用authDef格式定义这类checker`);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
if (silent) {
|
||||||
operation.filter = combineFilters([operation.filter, result as ED[T]['Selection']['filter']]);
|
operation.filter = addFilterSegment(filter || {}, result);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
assert(filter);
|
||||||
|
if (await checkFilterContains<ED, T, Cxt>(entity, context, result, filter, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new OakUserUnpermittedException(errMsg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}) as UpdateTriggerInTxn<ED, T, Cxt>['fn'];
|
}) as UpdateTriggerInTxn<ED, T, Cxt>['fn'];
|
||||||
|
|
@ -155,18 +169,12 @@ export function translateCheckerInSyncContext<
|
||||||
const { filter: operationFilter, action } = operation;
|
const { filter: operationFilter, action } = operation;
|
||||||
const filter2 = typeof filter === 'function' ? (filter as Function)(operation, context, option) : filter;
|
const filter2 = typeof filter === 'function' ? (filter as Function)(operation, context, option) : filter;
|
||||||
assert(operationFilter);
|
assert(operationFilter);
|
||||||
if (['select', 'count', 'stat'].includes(action)) {
|
assert(!(filter2 instanceof Promise));
|
||||||
operation.filter = addFilterSegment(operationFilter, filter2);
|
if (checkFilterContains<ED, T, Cxt>(entity, context, filter2, operationFilter, true)) {
|
||||||
return 0;
|
return;
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(!(filter2 instanceof Promise));
|
|
||||||
if (checkFilterContains<ED, T, Cxt>(entity, context, filter2, operationFilter, true)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const e = new OakRowInconsistencyException(undefined, errMsg);
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
|
const e = new OakRowInconsistencyException(undefined, errMsg);
|
||||||
|
throw e;
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
fn,
|
fn,
|
||||||
|
|
|
||||||
|
|
@ -901,6 +901,7 @@ export function checkFilterContains<ED extends EntityDict, T extends keyof ED, C
|
||||||
}]);
|
}]);
|
||||||
const count = context.count(entity, {
|
const count = context.count(entity, {
|
||||||
filter: filter2,
|
filter: filter2,
|
||||||
|
count: 1,
|
||||||
}, {
|
}, {
|
||||||
dontCollect: true,
|
dontCollect: true,
|
||||||
blockTrigger: true,
|
blockTrigger: true,
|
||||||
|
|
@ -947,4 +948,28 @@ export function checkFilterRepel<ED extends EntityDict, T extends keyof ED, Cxt
|
||||||
return count === 0;
|
return count === 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCascadeEntityFilter<ED extends EntityDict, T extends keyof ED>(
|
||||||
|
filter: NonNullable<ED[T]['Selection']['filter']>,
|
||||||
|
attr: keyof NonNullable<ED[T]['Selection']['filter']>
|
||||||
|
): ED[keyof ED]['Selection']['filter'] {
|
||||||
|
const filters: ED[keyof ED]['Selection']['filter'][] = [];
|
||||||
|
if (filter![attr]) {
|
||||||
|
assert(typeof filter![attr] === 'object');
|
||||||
|
filters.push(filter![attr]);
|
||||||
|
}
|
||||||
|
if (filter.$and) {
|
||||||
|
filter.$and.forEach(
|
||||||
|
(ele: NonNullable<ED[T]['Selection']['filter']>) => {
|
||||||
|
const f2 = getCascadeEntityFilter(ele, attr);
|
||||||
|
if (f2) {
|
||||||
|
filters.push(f2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (filters.length > 0) {
|
||||||
|
return combineFilters(filters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue