oak-domain 2.6.4 → 2.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/checkers/SyncCheckExecutor.d.ts +9 -0
- package/lib/checkers/SyncCheckExecutor.js +103 -0
- package/lib/store/TriggerExecutor.js +1 -1
- package/lib/store/checker.d.ts +7 -1
- package/lib/store/checker.js +36 -27
- package/lib/store/filter.d.ts +1 -0
- package/lib/store/filter.js +21 -1
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EntityDict } from '../types/Entity';
|
|
2
|
+
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
3
|
+
import { Checker, CheckerType } from '../types';
|
|
4
|
+
import { SyncContext } from '../store/SyncRowStore';
|
|
5
|
+
export default class SyncCheckerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends SyncContext<ED>> {
|
|
6
|
+
private checkerMap;
|
|
7
|
+
registerChecker<T extends keyof ED>(checker: Checker<ED, T, Cxt>): void;
|
|
8
|
+
check<T extends keyof ED>(entity: T, operation: Omit<ED[T]['Operation'], 'id'>, context: Cxt, when?: 'before' | 'after', checkerTypes?: CheckerType[]): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var tslib_1 = require("tslib");
|
|
4
|
+
// 简化版的对checker的同步检查
|
|
5
|
+
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
var types_1 = require("../types");
|
|
7
|
+
var checker_1 = require("../store/checker");
|
|
8
|
+
var filter_1 = require("../store/filter");
|
|
9
|
+
var SyncCheckerExecutor = /** @class */ (function () {
|
|
10
|
+
function SyncCheckerExecutor() {
|
|
11
|
+
this.checkerMap = {};
|
|
12
|
+
}
|
|
13
|
+
SyncCheckerExecutor.prototype.registerChecker = function (checker) {
|
|
14
|
+
var _this = this;
|
|
15
|
+
var entity = checker.entity, action = checker.action, priority = checker.priority, type = checker.type, conditionalFilter = checker.conditionalFilter;
|
|
16
|
+
var _a = (0, checker_1.translateCheckerInSyncContext)(checker), fn = _a.fn, when = _a.when;
|
|
17
|
+
if (priority === undefined) {
|
|
18
|
+
priority = type === 'data' ? types_1.DATA_CHECKER_DEFAULT_PRIORITY : types_1.CHECKER_DEFAULT_PRIORITY;
|
|
19
|
+
}
|
|
20
|
+
var addCheckerMap = function (action2) {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
if (_this.checkerMap[entity] && _this.checkerMap[entity][action2]) {
|
|
23
|
+
var iter = 0;
|
|
24
|
+
var checkers = _this.checkerMap[entity][action2];
|
|
25
|
+
for (; iter < checkers.length; iter++) {
|
|
26
|
+
if (priority <= checkers[iter].priority) {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
checkers.splice(iter, 0, {
|
|
31
|
+
type: type,
|
|
32
|
+
priority: priority,
|
|
33
|
+
fn: fn,
|
|
34
|
+
when: when,
|
|
35
|
+
filter: conditionalFilter,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
else if (_this.checkerMap[entity]) {
|
|
39
|
+
Object.assign(_this.checkerMap[entity], (_a = {},
|
|
40
|
+
_a[action2] = [{
|
|
41
|
+
type: type,
|
|
42
|
+
priority: priority,
|
|
43
|
+
fn: fn,
|
|
44
|
+
when: when,
|
|
45
|
+
filter: conditionalFilter,
|
|
46
|
+
}],
|
|
47
|
+
_a));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
Object.assign(_this.checkerMap, (_b = {},
|
|
51
|
+
_b[entity] = (_c = {},
|
|
52
|
+
_c[action2] = [{
|
|
53
|
+
type: type,
|
|
54
|
+
priority: priority,
|
|
55
|
+
fn: fn,
|
|
56
|
+
when: when,
|
|
57
|
+
filter: conditionalFilter,
|
|
58
|
+
}],
|
|
59
|
+
_c),
|
|
60
|
+
_b));
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
if (action instanceof Array) {
|
|
64
|
+
action.forEach(function (a) { return addCheckerMap(a); });
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
addCheckerMap(action);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
SyncCheckerExecutor.prototype.check = function (entity, operation, context, when, checkerTypes) {
|
|
71
|
+
var e_1, _a;
|
|
72
|
+
var action = operation.action;
|
|
73
|
+
var checkers = this.checkerMap[entity] && this.checkerMap[entity][action];
|
|
74
|
+
if (checkers) {
|
|
75
|
+
var checkers2 = checkers.filter(function (ele) { return (!checkerTypes || checkerTypes.includes(ele.type)) && (!when || ele.when === when); });
|
|
76
|
+
try {
|
|
77
|
+
for (var checkers2_1 = tslib_1.__values(checkers2), checkers2_1_1 = checkers2_1.next(); !checkers2_1_1.done; checkers2_1_1 = checkers2_1.next()) {
|
|
78
|
+
var checker = checkers2_1_1.value;
|
|
79
|
+
var filter = checker.filter;
|
|
80
|
+
if (filter) {
|
|
81
|
+
var filterr = typeof filter === 'function' ? filter(operation, context, {}) : filter;
|
|
82
|
+
(0, assert_1.default)(!(filter instanceof Promise), "\u5BF9".concat(entity, "\u7684\u52A8\u4F5C").concat(action, "\u4E0A\u5B9A\u4E49\u7684checker\uFF0C\u5176filter\u8FD4\u56DE\u4E86Promise\uFF0C\u8BF7\u6CE8\u610F\u5C06\u540C\u6B65\u548C\u5F02\u6B65\u7684\u8FD4\u56DE\u533A\u5206\u5BF9\u5F85"));
|
|
83
|
+
var isRepel = (0, filter_1.checkFilterRepel)(entity, context, filterr, operation.filter, true);
|
|
84
|
+
(0, assert_1.default)(typeof isRepel === 'boolean');
|
|
85
|
+
if (isRepel) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
checker.fn(operation, context, {});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
93
|
+
finally {
|
|
94
|
+
try {
|
|
95
|
+
if (checkers2_1_1 && !checkers2_1_1.done && (_a = checkers2_1.return)) _a.call(checkers2_1);
|
|
96
|
+
}
|
|
97
|
+
finally { if (e_1) throw e_1.error; }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
return SyncCheckerExecutor;
|
|
102
|
+
}());
|
|
103
|
+
exports.default = SyncCheckerExecutor;
|
|
@@ -33,7 +33,7 @@ var TriggerExecutor = /** @class */ (function () {
|
|
|
33
33
|
TriggerExecutor.prototype.registerChecker = function (checker) {
|
|
34
34
|
var entity = checker.entity, action = checker.action, type = checker.type, conditionalFilter = checker.conditionalFilter;
|
|
35
35
|
var triggerName = "".concat(String(entity)).concat(action, "\u6743\u9650\u68C0\u67E5-").concat(this.counter++);
|
|
36
|
-
var _a = (0, checker_1.translateCheckerInAsyncContext)(checker), fn = _a.fn, when = _a.when;
|
|
36
|
+
var _a = (0, checker_1.translateCheckerInAsyncContext)(checker, true), fn = _a.fn, when = _a.when;
|
|
37
37
|
var priority = type === 'data' ? Trigger_1.DATA_CHECKER_DEFAULT_PRIORITY : Trigger_1.CHECKER_DEFAULT_PRIORITY; // checker的默认优先级最低(前面的trigger可能会赋上一些相应的值)
|
|
38
38
|
var trigger = {
|
|
39
39
|
checkerType: type,
|
package/lib/store/checker.d.ts
CHANGED
|
@@ -2,7 +2,13 @@ import { AuthDefDict, Checker, EntityDict, OperateOption, SelectOption, StorageS
|
|
|
2
2
|
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
3
3
|
import { AsyncContext } from "./AsyncRowStore";
|
|
4
4
|
import { SyncContext } from './SyncRowStore';
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param checker 要翻译的checker
|
|
8
|
+
* @param silent 如果silent,则row和relation类型的checker只会把限制条件加到查询上,而不报错(除掉create动作)
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
11
|
+
export declare function translateCheckerInAsyncContext<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>, silent?: boolean): {
|
|
6
12
|
fn: Trigger<ED, T, Cxt>['fn'];
|
|
7
13
|
when: 'before' | 'after';
|
|
8
14
|
};
|
package/lib/store/checker.js
CHANGED
|
@@ -11,7 +11,13 @@ var string_1 = require("../utils/string");
|
|
|
11
11
|
var lodash_1 = require("../utils/lodash");
|
|
12
12
|
var relation_1 = require("./relation");
|
|
13
13
|
var uuid_1 = require("../utils/uuid");
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param checker 要翻译的checker
|
|
17
|
+
* @param silent 如果silent,则row和relation类型的checker只会把限制条件加到查询上,而不报错(除掉create动作)
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
function translateCheckerInAsyncContext(checker, silent) {
|
|
15
21
|
var _this = this;
|
|
16
22
|
var entity = checker.entity, type = checker.type;
|
|
17
23
|
var when = 'before'; // 现在create的relation改成提前的expression检查了,原先是先插入再后检查,性能不行,而且select也需要实现前检查
|
|
@@ -59,7 +65,7 @@ function translateCheckerInAsyncContext(checker) {
|
|
|
59
65
|
_c.label = 3;
|
|
60
66
|
case 3:
|
|
61
67
|
filter2 = _b;
|
|
62
|
-
if (!
|
|
68
|
+
if (!silent) return [3 /*break*/, 4];
|
|
63
69
|
operation.filter = (0, filter_1.addFilterSegment)(operationFilter || {}, filter2);
|
|
64
70
|
return [2 /*return*/, 0];
|
|
65
71
|
case 4: return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter || {}, true)];
|
|
@@ -102,11 +108,11 @@ function translateCheckerInAsyncContext(checker) {
|
|
|
102
108
|
};
|
|
103
109
|
}
|
|
104
110
|
case 'relation': {
|
|
105
|
-
var relationFilter_1 = checker.relationFilter,
|
|
111
|
+
var relationFilter_1 = checker.relationFilter, errMsg_2 = checker.errMsg;
|
|
106
112
|
var fn = (function (_a, context, option) {
|
|
107
113
|
var operation = _a.operation;
|
|
108
114
|
return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
109
|
-
var result, _b;
|
|
115
|
+
var result, _b, filter, action;
|
|
110
116
|
return tslib_1.__generator(this, function (_c) {
|
|
111
117
|
switch (_c.label) {
|
|
112
118
|
case 0:
|
|
@@ -123,15 +129,24 @@ function translateCheckerInAsyncContext(checker) {
|
|
|
123
129
|
_c.label = 3;
|
|
124
130
|
case 3:
|
|
125
131
|
result = _b;
|
|
126
|
-
if (result)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
operation.filter = (0, filter_1.combineFilters)([operation.filter, result]);
|
|
132
|
-
}
|
|
132
|
+
if (!result) return [3 /*break*/, 5];
|
|
133
|
+
filter = operation.filter, action = operation.action;
|
|
134
|
+
if (action === 'create') {
|
|
135
|
+
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"));
|
|
136
|
+
return [2 /*return*/, 0];
|
|
133
137
|
}
|
|
134
|
-
|
|
138
|
+
if (silent) {
|
|
139
|
+
operation.filter = (0, filter_1.addFilterSegment)(filter || {}, result);
|
|
140
|
+
return [2 /*return*/, 0];
|
|
141
|
+
}
|
|
142
|
+
(0, assert_1.default)(filter);
|
|
143
|
+
return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, result, filter, true)];
|
|
144
|
+
case 4:
|
|
145
|
+
if (_c.sent()) {
|
|
146
|
+
return [2 /*return*/];
|
|
147
|
+
}
|
|
148
|
+
throw new Exception_1.OakUserUnpermittedException(errMsg_2);
|
|
149
|
+
case 5: return [2 /*return*/, 0];
|
|
135
150
|
}
|
|
136
151
|
});
|
|
137
152
|
});
|
|
@@ -185,23 +200,17 @@ function translateCheckerInSyncContext(checker) {
|
|
|
185
200
|
};
|
|
186
201
|
}
|
|
187
202
|
case 'row': {
|
|
188
|
-
var filter_3 = checker.filter,
|
|
203
|
+
var filter_3 = checker.filter, errMsg_3 = checker.errMsg;
|
|
189
204
|
var fn = function (operation, context, option) {
|
|
190
205
|
var operationFilter = operation.filter, action = operation.action;
|
|
191
206
|
var filter2 = typeof filter_3 === 'function' ? filter_3(operation, context, option) : filter_3;
|
|
192
207
|
(0, assert_1.default)(operationFilter);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
(0, assert_1.default)(!(filter2 instanceof Promise));
|
|
199
|
-
if ((0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter, true)) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
var e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_2);
|
|
203
|
-
throw e;
|
|
208
|
+
(0, assert_1.default)(!(filter2 instanceof Promise));
|
|
209
|
+
if ((0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter, true)) {
|
|
210
|
+
return;
|
|
204
211
|
}
|
|
212
|
+
var e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_3);
|
|
213
|
+
throw e;
|
|
205
214
|
};
|
|
206
215
|
return {
|
|
207
216
|
fn: fn,
|
|
@@ -209,7 +218,7 @@ function translateCheckerInSyncContext(checker) {
|
|
|
209
218
|
};
|
|
210
219
|
}
|
|
211
220
|
case 'relation': {
|
|
212
|
-
var relationFilter_2 = checker.relationFilter,
|
|
221
|
+
var relationFilter_2 = checker.relationFilter, errMsg_4 = checker.errMsg;
|
|
213
222
|
var fn = function (operation, context, option) {
|
|
214
223
|
if (context.isRoot()) {
|
|
215
224
|
return;
|
|
@@ -226,7 +235,7 @@ function translateCheckerInSyncContext(checker) {
|
|
|
226
235
|
if ((0, filter_1.checkFilterContains)(entity, context, result, filter, true)) {
|
|
227
236
|
return;
|
|
228
237
|
}
|
|
229
|
-
throw new Exception_1.OakUserUnpermittedException(
|
|
238
|
+
throw new Exception_1.OakUserUnpermittedException(errMsg_4);
|
|
230
239
|
}
|
|
231
240
|
};
|
|
232
241
|
return {
|
|
@@ -362,7 +371,7 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) {
|
|
|
362
371
|
var counters = [];
|
|
363
372
|
if (filter) {
|
|
364
373
|
if (relation === 2) {
|
|
365
|
-
if (filter.entity ===
|
|
374
|
+
if (filter.entity === attr && filter.entityId) {
|
|
366
375
|
// 这里对entityId的限定的数据只要和userId有一条relation,就不能否定可能会有创建动作(外键在最终create时,data上一定会有判定)
|
|
367
376
|
counters.push({
|
|
368
377
|
$entity: attr,
|
package/lib/store/filter.d.ts
CHANGED
|
@@ -107,3 +107,4 @@ export declare function makeTreeDescendantFilter<ED extends EntityDict, T extend
|
|
|
107
107
|
*/
|
|
108
108
|
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>;
|
|
109
109
|
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>;
|
|
110
|
+
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'];
|
package/lib/store/filter.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
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;
|
|
3
|
+
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;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
var types_1 = require("../types");
|
|
@@ -845,6 +845,7 @@ function checkFilterContains(entity, context, contained, filter, dataCompare) {
|
|
|
845
845
|
}]);
|
|
846
846
|
var count = context.count(entity, {
|
|
847
847
|
filter: filter2,
|
|
848
|
+
count: 1,
|
|
848
849
|
}, {
|
|
849
850
|
dontCollect: true,
|
|
850
851
|
blockTrigger: true,
|
|
@@ -883,3 +884,22 @@ function checkFilterRepel(entity, context, filter1, filter2, dataCompare) {
|
|
|
883
884
|
return false;
|
|
884
885
|
}
|
|
885
886
|
exports.checkFilterRepel = checkFilterRepel;
|
|
887
|
+
function getCascadeEntityFilter(filter, attr) {
|
|
888
|
+
var filters = [];
|
|
889
|
+
if (filter[attr]) {
|
|
890
|
+
(0, assert_1.default)(typeof filter[attr] === 'object');
|
|
891
|
+
filters.push(filter[attr]);
|
|
892
|
+
}
|
|
893
|
+
if (filter.$and) {
|
|
894
|
+
filter.$and.forEach(function (ele) {
|
|
895
|
+
var f2 = getCascadeEntityFilter(ele, attr);
|
|
896
|
+
if (f2) {
|
|
897
|
+
filters.push(f2);
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
if (filters.length > 0) {
|
|
902
|
+
return combineFilters(filters);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
exports.getCascadeEntityFilter = getCascadeEntityFilter;
|