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.
@@ -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,
@@ -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
- export declare function translateCheckerInAsyncContext<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>): {
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
  };
@@ -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
- function translateCheckerInAsyncContext(checker) {
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 (!['select', 'count', 'stat'].includes(action)) return [3 /*break*/, 4];
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, errMsg = checker.errMsg;
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
- if (operation.action === 'create') {
128
- 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"));
129
- }
130
- else {
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
- return [2 /*return*/, 0];
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, errMsg_2 = checker.errMsg;
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
- if (['select', 'count', 'stat'].includes(action)) {
194
- operation.filter = (0, filter_1.addFilterSegment)(operationFilter, filter2);
195
- return 0;
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, errMsg_3 = checker.errMsg;
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(errMsg_3);
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 === entity && filter.entityId) {
374
+ if (filter.entity === attr && filter.entityId) {
366
375
  // 这里对entityId的限定的数据只要和userId有一条relation,就不能否定可能会有创建动作(外键在最终create时,data上一定会有判定)
367
376
  counters.push({
368
377
  $entity: attr,
@@ -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'];
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oak-domain",
3
- "version": "2.6.4",
3
+ "version": "2.6.6",
4
4
  "author": {
5
5
  "name": "XuChang"
6
6
  },