oak-domain 2.6.2 → 2.6.4

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.
Files changed (44) hide show
  1. package/lib/base-app-domain/Modi/Storage.js +2 -4
  2. package/lib/base-app-domain/User/Storage.js +2 -4
  3. package/lib/compiler/schemalBuilder.js +92 -89
  4. package/lib/entities/Modi.js +1 -0
  5. package/lib/entities/ModiEntity.js +1 -0
  6. package/lib/entities/Oper.js +1 -0
  7. package/lib/entities/OperEntity.js +1 -0
  8. package/lib/entities/User.js +1 -0
  9. package/lib/entities/UserEntityGrant.js +1 -0
  10. package/lib/store/AsyncRowStore.js +40 -42
  11. package/lib/store/CascadeStore.js +39 -33
  12. package/lib/store/checker.d.ts +2 -2
  13. package/lib/store/checker.js +516 -136
  14. package/lib/store/filter.js +7 -15
  15. package/lib/types/Auth.d.ts +10 -10
  16. package/lib/types/DataType.d.ts +4 -1
  17. package/lib/types/DataType.js +2 -1
  18. package/lib/types/Exception.d.ts +6 -0
  19. package/lib/types/Exception.js +25 -1
  20. package/lib/types/Locale.d.ts +1 -0
  21. package/lib/types/Polyfill.d.ts +1 -0
  22. package/lib/types/Storage.d.ts +1 -0
  23. package/lib/types/Style.d.ts +11 -0
  24. package/lib/types/Style.js +2 -0
  25. package/lib/types/Timer.d.ts +3 -2
  26. package/lib/types/index.d.ts +1 -0
  27. package/lib/types/index.js +1 -0
  28. package/lib/types/schema/DataTypes.d.ts +2 -0
  29. package/lib/utils/SimpleConnector.js +6 -5
  30. package/lib/utils/mask.d.ts +5 -0
  31. package/lib/utils/mask.js +35 -0
  32. package/lib/utils/money.d.ts +5 -0
  33. package/lib/utils/money.js +24 -0
  34. package/lib/utils/validator.d.ts +4 -2
  35. package/lib/utils/validator.js +8 -3
  36. package/package.json +3 -2
  37. package/src/entities/Modi.ts +1 -0
  38. package/src/entities/ModiEntity.ts +1 -0
  39. package/src/entities/Oper.ts +1 -0
  40. package/src/entities/OperEntity.ts +1 -0
  41. package/src/entities/User.ts +1 -0
  42. package/src/entities/UserEntityGrant.ts +1 -0
  43. package/lib/utils/cron.d.ts +0 -1
  44. package/lib/utils/cron.js +0 -18
@@ -13,8 +13,8 @@ var relation_1 = require("./relation");
13
13
  var uuid_1 = require("../utils/uuid");
14
14
  function translateCheckerInAsyncContext(checker) {
15
15
  var _this = this;
16
- var entity = checker.entity, type = checker.type, action = checker.action;
17
- var when = ((action === 'create' || action instanceof Array && action.includes('create')) && ['relation'].includes(type)) ? 'after' : 'before';
16
+ var entity = checker.entity, type = checker.type;
17
+ var when = 'before'; // 现在createrelation改成提前的expression检查了,原先是先插入再后检查,性能不行,而且select也需要实现前检查
18
18
  switch (type) {
19
19
  case 'data': {
20
20
  var checkerFn_1 = checker.checker;
@@ -102,44 +102,36 @@ function translateCheckerInAsyncContext(checker) {
102
102
  };
103
103
  }
104
104
  case 'relation': {
105
- var relationFilter_1 = checker.relationFilter, errMsg_2 = checker.errMsg;
105
+ var relationFilter_1 = checker.relationFilter, errMsg = checker.errMsg;
106
106
  var fn = (function (_a, context, option) {
107
107
  var operation = _a.operation;
108
108
  return tslib_1.__awaiter(_this, void 0, void 0, function () {
109
- var filter2, data, filter, _b, _c, _d;
110
- return tslib_1.__generator(this, function (_e) {
111
- switch (_e.label) {
109
+ var result, _b;
110
+ return tslib_1.__generator(this, function (_c) {
111
+ switch (_c.label) {
112
112
  case 0:
113
113
  if (context.isRoot()) {
114
114
  return [2 /*return*/, 0];
115
115
  }
116
- if (!(operation.action === 'create')) return [3 /*break*/, 3];
116
+ if (!(typeof relationFilter_1 === 'function')) return [3 /*break*/, 2];
117
117
  return [4 /*yield*/, relationFilter_1(operation, context, option)];
118
118
  case 1:
119
- filter2 = _e.sent();
120
- data = operation.data;
121
- filter = data instanceof Array ? {
122
- id: {
123
- $in: data.map(function (ele) { return ele.id; }),
124
- },
125
- } : {
126
- id: data.id,
127
- };
128
- return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, filter2, filter, true)];
119
+ _b = _c.sent();
120
+ return [3 /*break*/, 3];
129
121
  case 2:
130
- if (_e.sent()) {
131
- return [2 /*return*/, 0];
132
- }
133
- throw new Exception_1.OakUserUnpermittedException(errMsg_2);
122
+ _b = relationFilter_1;
123
+ _c.label = 3;
134
124
  case 3:
135
- _b = operation;
136
- _c = filter_1.combineFilters;
137
- _d = [operation.filter];
138
- return [4 /*yield*/, relationFilter_1(operation, context, option)];
139
- case 4:
140
- _b.filter = _c.apply(void 0, [_d.concat([_e.sent()])]);
141
- _e.label = 5;
142
- case 5: return [2 /*return*/, 0];
125
+ 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
+ }
133
+ }
134
+ return [2 /*return*/, 0];
143
135
  }
144
136
  });
145
137
  });
@@ -181,8 +173,8 @@ function translateCheckerInAsyncContext(checker) {
181
173
  }
182
174
  exports.translateCheckerInAsyncContext = translateCheckerInAsyncContext;
183
175
  function translateCheckerInSyncContext(checker) {
184
- var entity = checker.entity, type = checker.type, action = checker.action;
185
- var when = ((action === 'create' || action instanceof Array && action.includes('create')) && ['relation'].includes(type)) ? 'after' : 'before';
176
+ var entity = checker.entity, type = checker.type;
177
+ var when = 'before'; // 现在createrelation改成提前的expression检查了,原先是先插入再后检查,性能不行,而且select也需要实现前检查
186
178
  switch (type) {
187
179
  case 'data': {
188
180
  var checkerFn_3 = checker.checker;
@@ -193,7 +185,7 @@ function translateCheckerInSyncContext(checker) {
193
185
  };
194
186
  }
195
187
  case 'row': {
196
- var filter_3 = checker.filter, errMsg_3 = checker.errMsg;
188
+ var filter_3 = checker.filter, errMsg_2 = checker.errMsg;
197
189
  var fn = function (operation, context, option) {
198
190
  var operationFilter = operation.filter, action = operation.action;
199
191
  var filter2 = typeof filter_3 === 'function' ? filter_3(operation, context, option) : filter_3;
@@ -207,7 +199,7 @@ function translateCheckerInSyncContext(checker) {
207
199
  if ((0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter, true)) {
208
200
  return;
209
201
  }
210
- var e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_3);
202
+ var e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_2);
211
203
  throw e;
212
204
  }
213
205
  };
@@ -217,28 +209,25 @@ function translateCheckerInSyncContext(checker) {
217
209
  };
218
210
  }
219
211
  case 'relation': {
220
- var relationFilter_2 = checker.relationFilter, errMsg_4 = checker.errMsg;
212
+ var relationFilter_2 = checker.relationFilter, errMsg_3 = checker.errMsg;
221
213
  var fn = function (operation, context, option) {
222
214
  if (context.isRoot()) {
223
215
  return;
224
216
  }
225
- var filter2 = typeof relationFilter_2 === 'function' ? relationFilter_2(operation, context, option) : relationFilter_2;
226
- var filter = operation.filter, action = operation.action;
227
- var filter3 = filter;
228
- if (action === 'create') {
229
- var data = operation.data;
230
- filter3 = data instanceof Array ? {
231
- id: {
232
- $in: data.map(function (ele) { return ele.id; }),
233
- },
234
- } : { id: data.id };
235
- }
236
- (0, assert_1.default)(filter3);
237
- (0, assert_1.default)(!(filter2 instanceof Promise));
238
- if ((0, filter_1.checkFilterContains)(entity, context, filter2, filter3, true)) {
239
- return;
217
+ var result = typeof relationFilter_2 === 'function' ? relationFilter_2(operation, context, option) : relationFilter_2;
218
+ (0, assert_1.default)(!(result instanceof Promise));
219
+ if (result) {
220
+ var filter = operation.filter, action = operation.action;
221
+ if (action === 'create') {
222
+ 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"));
223
+ return;
224
+ }
225
+ (0, assert_1.default)(filter);
226
+ if ((0, filter_1.checkFilterContains)(entity, context, result, filter, true)) {
227
+ return;
228
+ }
229
+ throw new Exception_1.OakUserUnpermittedException(errMsg_3);
240
230
  }
241
- throw new Exception_1.OakUserUnpermittedException(errMsg_4);
242
231
  };
243
232
  return {
244
233
  fn: fn,
@@ -265,9 +254,12 @@ function translateCheckerInSyncContext(checker) {
265
254
  }
266
255
  }
267
256
  exports.translateCheckerInSyncContext = translateCheckerInSyncContext;
268
- function translateCascadeRelationFilterMaker(schema, lch, entity2) {
257
+ function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) {
269
258
  var cascadePath = lch.cascadePath, relations = lch.relations;
270
- var paths = cascadePath.split('.');
259
+ var paths = cascadePath ? cascadePath.split('.') : [];
260
+ if (pathPrefix) {
261
+ paths.unshift(pathPrefix);
262
+ }
271
263
  var translateRelationFilter = function (entity) {
272
264
  // 有两种情况,此entity和user有Relation定义,或是此entity已经指向user
273
265
  if (entity === 'user') {
@@ -312,11 +304,12 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2) {
312
304
  };
313
305
  var translateFilterMakerIter = function (entity, iter) {
314
306
  var relation = (0, relation_1.judgeRelation)(schema, entity, paths[iter]);
307
+ (0, assert_1.default)(relation === 2 || typeof relation === 'string');
315
308
  if (iter === paths.length - 1) {
316
309
  if (relation === 2) {
317
- var filterMaker_1 = translateRelationFilter(paths[iter]);
310
+ var filterMaker2_1 = translateRelationFilter(paths[iter]);
318
311
  return function (userId) {
319
- var filter = filterMaker_1(userId);
312
+ var filter = filterMaker2_1(userId);
320
313
  (0, assert_1.default)(filter.id);
321
314
  return {
322
315
  entity: paths[iter],
@@ -324,11 +317,10 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2) {
324
317
  };
325
318
  };
326
319
  }
327
- (0, assert_1.default)(typeof relation === 'string');
328
- var filterMaker_2 = translateRelationFilter(relation);
320
+ var filterMaker2_2 = translateRelationFilter(relation);
329
321
  return function (userId) {
330
322
  var _a;
331
- var filter = filterMaker_2(userId);
323
+ var filter = filterMaker2_2(userId);
332
324
  (0, assert_1.default)(filter.id);
333
325
  return _a = {},
334
326
  _a["".concat(paths[iter], "Id")] = filter.id,
@@ -336,43 +328,400 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2) {
336
328
  };
337
329
  }
338
330
  else {
339
- var subFilterMaker_1 = translateFilterMakerIter(paths[iter], iter + 1);
340
- if (iter === 0) {
341
- return function (userId) {
342
- var _a;
343
- var subFilter = subFilterMaker_1(userId);
344
- return _a = {},
345
- _a[paths[iter]] = subFilter,
346
- _a;
347
- };
348
- }
331
+ var filterMaker_1 = relation === 2 ? translateFilterMakerIter(paths[iter], iter + 1) : translateFilterMakerIter(relation, iter + 1);
349
332
  return function (userId) {
350
333
  var _a;
351
334
  return (_a = {},
352
- _a[paths[iter]] = subFilterMaker_1(userId),
335
+ _a[paths[iter]] = filterMaker_1(userId),
353
336
  _a);
354
337
  };
355
338
  }
356
339
  };
357
- var filter = cascadePath ? translateFilterMakerIter(entity2, 0) : translateRelationFilter(entity2);
358
- return filter;
340
+ var filterMaker = paths.length ? translateFilterMakerIter(entity2, 0) : translateRelationFilter(entity2);
341
+ if (!paths.length) {
342
+ // 不可能是create
343
+ return function (oper, userId) { return filterMaker(userId); };
344
+ }
345
+ /**
346
+ * 针对第一层做一下特别优化,比如对象A指向对象B(多对一),如果A的cascadePath是 'B',
347
+ * 当create A时,会带有Bid。此时生成该B对象上的相关表达式查询返回,可以避免必须将此判定在对象创建之后再做
348
+ * 另一使用场景是,在查询A时,如果带有Bid(在对象跳一对多子对象场景下很常见),可以提前判定这个查询对某些用户一定返回空集
349
+ *
350
+ * 20230306:
351
+ * 在前台的权限判断中,会将list上的filter当成内在的限制对create动作进行判断,此时有一种可能是,filter并不能直接判断出外键,但会限制外键的查询范围。
352
+ * 例如,在jichuang项目中,就存在park/list上,平台的用户去访问时,其查询条件是{ system: { platformId: 1 }};而用户的关系落在system.platform.platformProvider上,
353
+ * 此时如直接通过data上的外键判断就会失败,需要通过对filter上相应的语义解构,进行进一步的判断
354
+ */
355
+ var _a = tslib_1.__read(paths, 1), attr = _a[0];
356
+ var relation = (0, relation_1.judgeRelation)(schema, entity2, attr);
357
+ (0, assert_1.default)(relation === 2 || typeof relation === 'string');
358
+ var filterMaker2 = paths.length > 1
359
+ ? (relation === 2 ? translateFilterMakerIter(attr, 1) : translateFilterMakerIter(relation, 1))
360
+ : (relation === 2 ? translateRelationFilter(attr) : translateRelationFilter(relation));
361
+ var translateCreateFilterMaker = function (entity, filter, userId) {
362
+ var counters = [];
363
+ if (filter) {
364
+ if (relation === 2) {
365
+ if (filter.entity === entity && filter.entityId) {
366
+ // 这里对entityId的限定的数据只要和userId有一条relation,就不能否定可能会有创建动作(外键在最终create时,data上一定会有判定)
367
+ counters.push({
368
+ $entity: attr,
369
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: filter.entityId }),
370
+ });
371
+ }
372
+ if (filter[attr]) {
373
+ counters.push({
374
+ $entity: attr,
375
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), filter[attr]),
376
+ });
377
+ }
378
+ }
379
+ else {
380
+ (0, assert_1.default)(typeof relation === 'string');
381
+ if (filter["".concat(attr, "Id")]) {
382
+ var filterMaker3 = paths.length > 1 ? translateFilterMakerIter(relation, 1) : translateRelationFilter(relation);
383
+ // 这里对attrId的限定的数据只要和userId有一条relation,就不能否定可能会有创建动作(外键在最终create时,data上一定会有判定)
384
+ counters.push({
385
+ $entity: relation,
386
+ $filter: (0, filter_1.addFilterSegment)(filterMaker3(userId), { id: filter["".concat(attr, "Id")] }),
387
+ });
388
+ }
389
+ if (filter[attr]) {
390
+ counters.push({
391
+ $entity: relation,
392
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), filter[attr]),
393
+ });
394
+ }
395
+ }
396
+ if (filter.$and) {
397
+ var countersAnd = filter.$and.map(function (ele) { return translateCreateFilterMaker(entity, ele, userId); });
398
+ // and 只要有一个满足就行
399
+ var ca2 = countersAnd.filter(function (ele) { return !(ele instanceof Exception_1.OakUserUnpermittedException); });
400
+ counters.push.apply(counters, tslib_1.__spreadArray([], tslib_1.__read(ca2), false));
401
+ }
402
+ if (filter.$or) {
403
+ var countersOr = filter.$and.map(function (ele) { return translateCreateFilterMaker(entity, ele, userId); });
404
+ // or也只要有一个满足就行(不能否定)
405
+ var co2 = countersOr.filter(function (ele) { return !(ele instanceof Exception_1.OakUserUnpermittedException); });
406
+ counters.push.apply(counters, tslib_1.__spreadArray([], tslib_1.__read(co2), false));
407
+ }
408
+ }
409
+ if (counters.length === 0) {
410
+ // 一个counter都找不出来,说明当前路径上不满足
411
+ return new Exception_1.OakUserUnpermittedException();
412
+ }
413
+ else if (counters.length === 1) {
414
+ return counters[0];
415
+ }
416
+ // 是or关系,只要其中有一个满足就可以通过
417
+ return {
418
+ $$or: counters,
419
+ };
420
+ };
421
+ return function (operation, userId) {
422
+ var action = operation.action;
423
+ if (action === 'create') {
424
+ var data = operation.data;
425
+ if (data) {
426
+ // 有data的情形根据data判定
427
+ var getForeignKeyId_1 = function (d) {
428
+ if (relation === 2) {
429
+ if (d.entity === attr && typeof d.entityId === 'string') {
430
+ return d.entityId;
431
+ }
432
+ throw new Exception_1.OakUserUnpermittedException();
433
+ }
434
+ else {
435
+ (0, assert_1.default)(typeof relation === 'string');
436
+ if (typeof d["".concat(attr, "Id")] === 'string') {
437
+ return d["".concat(attr, "Id")];
438
+ }
439
+ throw new Exception_1.OakUserUnpermittedException();
440
+ }
441
+ };
442
+ if (relation === 2) {
443
+ if (data instanceof Array) {
444
+ var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); }));
445
+ return {
446
+ $entity: attr,
447
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: fkIds } }),
448
+ $count: fkIds.length,
449
+ };
450
+ }
451
+ var fkId_1 = getForeignKeyId_1(data);
452
+ return {
453
+ $entity: attr,
454
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: fkId_1 }),
455
+ };
456
+ }
457
+ (0, assert_1.default)(typeof relation === 'string');
458
+ if (data instanceof Array) {
459
+ var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); }));
460
+ return {
461
+ $entity: relation,
462
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: fkIds } }),
463
+ $count: fkIds.length,
464
+ };
465
+ }
466
+ var fkId = getForeignKeyId_1(data);
467
+ return {
468
+ $entity: relation,
469
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: fkId }),
470
+ };
471
+ }
472
+ else {
473
+ // todo
474
+ var filter_4 = operation.filter;
475
+ if (filter_4) {
476
+ var counter = translateCreateFilterMaker(entity2, filter_4, userId);
477
+ if (counter instanceof Exception_1.OakUserUnpermittedException) {
478
+ throw counter;
479
+ }
480
+ return counter;
481
+ }
482
+ throw new Exception_1.OakUserUnpermittedException();
483
+ }
484
+ }
485
+ var filter = operation.filter;
486
+ if (relation === 2 && (filter === null || filter === void 0 ? void 0 : filter.entity) === attr && (filter === null || filter === void 0 ? void 0 : filter.entityId)) {
487
+ if (typeof filter.entityId === 'string') {
488
+ return {
489
+ $entity: attr,
490
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: filter.entityId }),
491
+ };
492
+ }
493
+ else if (filter.entityId.$in && filter.entityId.$in instanceof Array) {
494
+ var entityIds = (0, lodash_1.uniq)(filter.entityId.$in);
495
+ return {
496
+ $entity: relation,
497
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: entityIds } }),
498
+ $count: entityIds.length,
499
+ };
500
+ }
501
+ }
502
+ else if (filter && filter["".concat(attr, "Id")]) {
503
+ if (typeof filter["".concat(attr, "Id")] === 'string') {
504
+ return {
505
+ $entity: attr,
506
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: filter["".concat(attr, "Id")] }),
507
+ };
508
+ }
509
+ else if (filter["".concat(attr, "Id")].$in && filter["".concat(attr, "Id")].$in instanceof Array) {
510
+ var entityIds = (0, lodash_1.uniq)(filter["".concat(attr, "Id")].$in);
511
+ return {
512
+ $entity: relation,
513
+ $filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: entityIds } }),
514
+ $count: entityIds.length,
515
+ };
516
+ }
517
+ }
518
+ return filterMaker(userId);
519
+ };
359
520
  }
360
- function translateActionAuthFilterMaker(schema, relationItem, entity) {
521
+ function translateActionAuthFilterMaker(schema, relationItem, entity, pathPrefix) {
361
522
  if (relationItem instanceof Array) {
362
- var maker_1 = relationItem.map(function (ele) {
523
+ var maker = relationItem.map(function (ele) {
363
524
  if (ele instanceof Array) {
364
- return ele.map(function (ele2) { return translateCascadeRelationFilterMaker(schema, ele2, entity); });
525
+ return ele.map(function (ele2) { return translateCascadeRelationFilterMaker(schema, ele2, entity, pathPrefix); });
365
526
  }
366
- return [translateCascadeRelationFilterMaker(schema, ele, entity)];
527
+ return translateCascadeRelationFilterMaker(schema, ele, entity, pathPrefix);
367
528
  });
368
- return function (userId) { return ({
369
- $or: maker_1.map(function (ele) { return ({
370
- $and: ele.map(function (ele2) { return ele2(userId); })
371
- }); })
372
- }); };
529
+ return maker;
373
530
  }
374
- var filterMaker = translateCascadeRelationFilterMaker(schema, relationItem, entity);
375
- return function (userId) { return filterMaker(userId); };
531
+ var filterMaker = translateCascadeRelationFilterMaker(schema, relationItem, entity, pathPrefix);
532
+ return filterMaker;
533
+ }
534
+ function execCreateCounter(context, counter) {
535
+ if (counter === null || counter === void 0 ? void 0 : counter.$$and) {
536
+ // 每个counter都要满足才能过
537
+ var counters = counter === null || counter === void 0 ? void 0 : counter.$$and;
538
+ (0, assert_1.default)(counters.length > 0);
539
+ var counterResults = counters.map(function (ele) { return execCreateCounter(context, ele); });
540
+ if (counterResults[0] instanceof Promise) {
541
+ return Promise.all(counterResults)
542
+ .then(function (cr2) {
543
+ var unpermitted = cr2.find(function (ele) { return ele instanceof Exception_1.OakUserUnpermittedException; });
544
+ if (unpermitted) {
545
+ return unpermitted;
546
+ }
547
+ return undefined;
548
+ });
549
+ }
550
+ else {
551
+ var unpermitted = counterResults.find(function (ele) { return ele instanceof Exception_1.OakUserUnpermittedException; });
552
+ if (unpermitted) {
553
+ return unpermitted;
554
+ }
555
+ else {
556
+ return undefined;
557
+ }
558
+ }
559
+ }
560
+ else if (counter === null || counter === void 0 ? void 0 : counter.$$or) {
561
+ // 只要有一个counter能过就算过
562
+ var counters = counter === null || counter === void 0 ? void 0 : counter.$$or;
563
+ (0, assert_1.default)(counters.length > 0);
564
+ var counterResults = counters.map(function (ele) { return execCreateCounter(context, ele); });
565
+ if (counterResults[0] instanceof Promise) {
566
+ return Promise.all(counterResults)
567
+ .then(function (cr2) {
568
+ var permittedIdx = cr2.indexOf(undefined);
569
+ if (permittedIdx !== -1) {
570
+ return undefined;
571
+ }
572
+ return new Exception_1.OakUserUnpermittedException();
573
+ });
574
+ }
575
+ else {
576
+ var permittedIndex = counterResults.indexOf(undefined);
577
+ if (permittedIndex !== -1) {
578
+ return undefined;
579
+ }
580
+ else {
581
+ return new Exception_1.OakUserUnpermittedException();
582
+ }
583
+ }
584
+ }
585
+ else if (counter === null || counter === void 0 ? void 0 : counter.$entity) {
586
+ var _a = counter, $entity = _a.$entity, $filter = _a.$filter, _b = _a.$count, $count_1 = _b === void 0 ? 1 : _b;
587
+ var count = context.count($entity, {
588
+ filter: $filter,
589
+ }, { dontCollect: true });
590
+ if (count instanceof Promise) {
591
+ return count.then(function (c2) {
592
+ if (c2 >= $count_1) {
593
+ return undefined;
594
+ }
595
+ return new Exception_1.OakUserUnpermittedException();
596
+ });
597
+ }
598
+ else {
599
+ return count >= $count_1 ? undefined : new Exception_1.OakUserUnpermittedException();
600
+ }
601
+ }
602
+ }
603
+ function makePotentialFilter(operation, context, filterMaker) {
604
+ var e_1, _a, e_2, _b;
605
+ var userId = context.getCurrentUserId();
606
+ (0, assert_1.default)(userId);
607
+ var filters = filterMaker instanceof Array ? filterMaker.map(function (ele) {
608
+ if (ele instanceof Array) {
609
+ return ele.map(function (ele2) { return ele2(operation, userId); });
610
+ }
611
+ return ele(operation, userId);
612
+ }) : [filterMaker(operation, userId)];
613
+ /**
614
+ * 在下面的逻辑中,如果某个maker返回的是$entity类型,则检查是否有满足条件的项,没有就要抛出异常,有就返回undefined
615
+ * undefined项即意味着该条件通过
616
+ * 再加上and和or的布尔逻辑判断,得到最终结果
617
+ * 还要考虑同步和异步……
618
+ * 代码比较复杂,因为原先没有$entity这种返回结果的设计
619
+ * by Xc 20130219
620
+ */
621
+ var filtersOr = [];
622
+ var isAsyncOr = false;
623
+ try {
624
+ for (var filters_1 = tslib_1.__values(filters), filters_1_1 = filters_1.next(); !filters_1_1.done; filters_1_1 = filters_1.next()) {
625
+ var f = filters_1_1.value;
626
+ if (f instanceof Array) {
627
+ var isAsyncAnd = false;
628
+ (0, assert_1.default)(f.length > 0);
629
+ var filtersAnd = [];
630
+ try {
631
+ 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()) {
632
+ var ff = f_1_1.value;
633
+ if ((ff === null || ff === void 0 ? void 0 : ff.$$and) || (ff === null || ff === void 0 ? void 0 : ff.$$or) || (ff === null || ff === void 0 ? void 0 : ff.$entity)) {
634
+ // 每个counter都要满足才能过
635
+ var result = execCreateCounter(context, ff);
636
+ if (result instanceof Promise) {
637
+ isAsyncAnd = true;
638
+ }
639
+ filtersAnd.push(result);
640
+ }
641
+ else if (ff) {
642
+ filtersAnd.push(ff);
643
+ }
644
+ }
645
+ }
646
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
647
+ finally {
648
+ try {
649
+ if (f_1_1 && !f_1_1.done && (_b = f_1.return)) _b.call(f_1);
650
+ }
651
+ finally { if (e_2) throw e_2.error; }
652
+ }
653
+ if (isAsyncAnd = true) {
654
+ isAsyncOr = true;
655
+ filtersOr.push(isAsyncAnd ? Promise.all(filtersAnd).then(function (fa) {
656
+ var e_3, _a;
657
+ var faR = [];
658
+ try {
659
+ 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()) {
660
+ var faItem = fa_1_1.value;
661
+ if (faItem instanceof Exception_1.OakUserUnpermittedException) {
662
+ return faItem;
663
+ }
664
+ else if (faItem) {
665
+ faR.push(faItem);
666
+ }
667
+ }
668
+ }
669
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
670
+ finally {
671
+ try {
672
+ if (fa_1_1 && !fa_1_1.done && (_a = fa_1.return)) _a.call(fa_1);
673
+ }
674
+ finally { if (e_3) throw e_3.error; }
675
+ }
676
+ if (faR.length > 0) {
677
+ return {
678
+ $and: faR,
679
+ };
680
+ }
681
+ }) : {
682
+ $and: filtersAnd,
683
+ });
684
+ }
685
+ }
686
+ else {
687
+ if ((f === null || f === void 0 ? void 0 : f.$$and) || (f === null || f === void 0 ? void 0 : f.$$or) || (f === null || f === void 0 ? void 0 : f.$entity)) {
688
+ var counterResults = execCreateCounter(context, f);
689
+ if (counterResults instanceof Promise) {
690
+ isAsyncOr = true;
691
+ }
692
+ filtersOr.push(counterResults);
693
+ }
694
+ else if (f) {
695
+ filtersOr.push(f);
696
+ }
697
+ }
698
+ }
699
+ }
700
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
701
+ finally {
702
+ try {
703
+ if (filters_1_1 && !filters_1_1.done && (_a = filters_1.return)) _a.call(filters_1);
704
+ }
705
+ finally { if (e_1) throw e_1.error; }
706
+ }
707
+ // or的逻辑是,有一个成功就直接通过
708
+ var returnOrFilters = function (filters) {
709
+ if (filters.length === 0 || filters.includes(undefined)) {
710
+ return undefined;
711
+ }
712
+ var foFilters = filters.filter(function (ele) { return ele !== undefined && !(ele instanceof Exception_1.OakUserUnpermittedException); });
713
+ if (foFilters.length > 0) {
714
+ return {
715
+ $or: foFilters,
716
+ };
717
+ }
718
+ throw new Exception_1.OakUserUnpermittedException();
719
+ };
720
+ if (isAsyncOr) {
721
+ return Promise.all(filtersOr)
722
+ .then(function (filters) { return returnOrFilters(filters); });
723
+ }
724
+ return returnOrFilters(filtersOr);
376
725
  }
377
726
  /**
378
727
  * 根据权限定义,创建出相应的checker
@@ -388,69 +737,100 @@ function createAuthCheckers(schema, authDict) {
388
737
  var _b = authDict[entity], relationAuth = _b.relationAuth, actionAuth = _b.actionAuth;
389
738
  if (relationAuth) {
390
739
  var raFilterMakerDict_1 = {};
391
- var userEntityName_1 = "user".concat((0, string_1.firstLetterUpperCase)(entity));
740
+ var userEntityName = "user".concat((0, string_1.firstLetterUpperCase)(entity));
741
+ var allAuthItem = [];
392
742
  for (var r in relationAuth) {
743
+ var authItem = relationAuth[r];
393
744
  Object.assign(raFilterMakerDict_1, (_a = {},
394
- _a[r] = translateActionAuthFilterMaker(schema, relationAuth[r], entity),
745
+ _a[r] = translateActionAuthFilterMaker(schema, authItem, userEntityName, entity),
395
746
  _a));
747
+ if (authItem instanceof Array) {
748
+ allAuthItem.push.apply(allAuthItem, tslib_1.__spreadArray([], tslib_1.__read(authItem), false));
749
+ }
750
+ else {
751
+ allAuthItem.push(authItem);
752
+ }
396
753
  }
754
+ // 如果不指定relation,则使用所有的authItem的or组合
755
+ Object.assign(raFilterMakerDict_1, {
756
+ '@@all': translateActionAuthFilterMaker(schema, allAuthItem, userEntityName, entity),
757
+ });
397
758
  var entityIdAttr_1 = "".concat(entity, "Id");
398
759
  checkers.push({
399
- entity: userEntityName_1,
760
+ entity: userEntityName,
400
761
  action: 'create',
401
762
  type: 'relation',
402
763
  relationFilter: function (operation, context) {
403
- var _a;
404
764
  var data = operation.data;
405
765
  (0, assert_1.default)(!(data instanceof Array));
406
- var _b = data, relation = _b.relation, _c = entityIdAttr_1, entityId = _b[_c];
407
- var userId = context.getCurrentUserId();
766
+ var _a = data, relation = _a.relation, _b = entityIdAttr_1, entityId = _a[_b];
767
+ if (!relation) {
768
+ // 不指定relation测试是否有创建权限
769
+ return makePotentialFilter(operation, context, raFilterMakerDict_1['@@all']);
770
+ }
408
771
  if (!raFilterMakerDict_1[relation]) {
409
- return;
772
+ throw new Exception_1.OakUserUnpermittedException();
410
773
  }
411
- var filter = raFilterMakerDict_1[relation](userId);
412
- return _a = {},
413
- _a[entity] = filter,
414
- _a;
774
+ var filter = makePotentialFilter(operation, context, raFilterMakerDict_1[relation]);
775
+ return filter;
415
776
  },
416
777
  errMsg: '越权操作',
417
778
  });
418
779
  checkers.push({
419
- entity: userEntityName_1,
780
+ entity: userEntityName,
420
781
  action: 'remove',
421
782
  type: 'relation',
422
783
  relationFilter: function (operation, context) {
423
- var _a;
424
- var userId = context.getCurrentUserId();
425
- var filter = operation.filter;
426
- var makeFilterFromRows = function (rows) {
427
- var relations = (0, lodash_1.uniq)(rows.map(function (ele) { return ele.relation; }));
428
- var entityIds = (0, lodash_1.uniq)(rows.map(function (ele) { return ele[entityIdAttr_1]; }));
429
- (0, assert_1.default)(entityIds.length === 1, "\u5728\u56DE\u6536".concat(userEntityName_1, "\u4E0A\u6743\u9650\u65F6\uFF0C\u5355\u6B21\u56DE\u6536\u6D89\u53CA\u5230\u4E86\u4E0D\u540C\u7684\u5BF9\u8C61\uFF0C\u6B64\u64CD\u4F5C\u4E0D\u88AB\u5141\u8BB8"));
784
+ // 目前过不去
785
+ return undefined;
786
+ /* const userId = context.getCurrentUserId();
787
+ const { filter } = operation as ED[keyof ED]['Remove'];
788
+ const makeFilterFromRows = (rows: Partial<ED[keyof ED]['Schema']>[]): SyncOrAsync<ED[keyof ED]['Selection']['filter']> => {
789
+ const relations = uniq(rows.map(ele => ele.relation));
790
+ const entityIds = uniq(rows.map(ele => ele[entityIdAttr]));
791
+ assert(entityIds.length === 1, `在回收${userEntityName}上权限时,单次回收涉及到了不同的对象,此操作不被允许`);
430
792
  // const entityId = entityIds[0]!;
793
+
431
794
  // 所有的relation条件要同时满足and关系(注意这里的filter翻译出来是在entity对象上,不是在userEntity对象上)
432
- return {
433
- $and: relations.map(function (relation) { return raFilterMakerDict_1[relation]; }).filter(function (ele) { return !!ele; }).map(function (ele) {
434
- var _a;
435
- return (_a = {},
436
- _a[entity] = ele(userId),
437
- _a);
438
- })
439
- };
795
+ const filtersAnd = relations.map(
796
+ (relation) => raFilterMakerDict[relation!]
797
+ ).filter(
798
+ ele => !!ele
799
+ ).map(
800
+ ele => makePotentialFilter(operation, context, ele)
801
+ );
802
+ if (filtersAnd.find(ele => ele instanceof Promise)) {
803
+ return Promise.all(filtersAnd).then(
804
+ (fa) => {
805
+ if (fa.length > 0) {
806
+ return {
807
+ $and: fa,
808
+ } as ED[keyof ED]['Selection']['filter'];
809
+ }
810
+ }
811
+ );
812
+ }
813
+ if (filtersAnd.length > 0) {
814
+ return {
815
+ $and: filtersAnd
816
+ } as ED[keyof ED]['Selection']['filter'];
817
+ }
440
818
  };
441
- var toBeRemoved = context.select(userEntityName_1, {
442
- data: (_a = {
443
- id: 1,
444
- relation: 1
445
- },
446
- _a[entityIdAttr_1] = 1,
447
- _a),
448
- filter: filter,
819
+
820
+ const toBeRemoved = context.select(userEntityName, {
821
+ data: {
822
+ id: 1,
823
+ relation: 1,
824
+ [entityIdAttr]: 1,
825
+ },
826
+ filter,
449
827
  }, { dontCollect: true });
450
828
  if (toBeRemoved instanceof Promise) {
451
- return toBeRemoved.then(function (rows) { return makeFilterFromRows(rows); });
829
+ return toBeRemoved.then(
830
+ (rows) => makeFilterFromRows(rows)
831
+ );
452
832
  }
453
- return makeFilterFromRows(toBeRemoved);
833
+ return makeFilterFromRows(toBeRemoved); */
454
834
  },
455
835
  errMsg: '越权操作',
456
836
  });
@@ -466,7 +846,7 @@ function createAuthCheckers(schema, authDict) {
466
846
  type: 'relation',
467
847
  relationFilter: function (operation, context) {
468
848
  // const { filter } = operation;
469
- var filter = filterMaker(context.getCurrentUserId());
849
+ var filter = makePotentialFilter(operation, context, filterMaker);
470
850
  return filter;
471
851
  },
472
852
  errMsg: '定义的actionAuth中检查出来越权操作',
@@ -491,7 +871,7 @@ exports.createAuthCheckers = createAuthCheckers;
491
871
  * 如果有的对象允许删除,需要使用trigger来处理其相关联的外键对象,这些trigger写作before,则会在checker之前执行,仍然可以删除成功
492
872
  */
493
873
  function createRemoveCheckers(schema, authDict) {
494
- var e_1, _a;
874
+ var e_4, _a;
495
875
  var checkers = [];
496
876
  // 先建立所有的一对多的关系
497
877
  var OneToManyMatrix = {};
@@ -506,7 +886,7 @@ function createRemoveCheckers(schema, authDict) {
506
886
  }
507
887
  };
508
888
  var addToMtoEntity = function (e, fs) {
509
- var e_2, _a;
889
+ var e_5, _a;
510
890
  var _b;
511
891
  try {
512
892
  for (var fs_1 = tslib_1.__values(fs), fs_1_1 = fs_1.next(); !fs_1_1.done; fs_1_1 = fs_1.next()) {
@@ -519,12 +899,12 @@ function createRemoveCheckers(schema, authDict) {
519
899
  }
520
900
  }
521
901
  }
522
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
902
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
523
903
  finally {
524
904
  try {
525
905
  if (fs_1_1 && !fs_1_1.done && (_a = fs_1.return)) _a.call(fs_1);
526
906
  }
527
- finally { if (e_2) throw e_2.error; }
907
+ finally { if (e_5) throw e_5.error; }
528
908
  }
529
909
  };
530
910
  for (var entity in schema) {
@@ -554,7 +934,7 @@ function createRemoveCheckers(schema, authDict) {
554
934
  action: 'remove',
555
935
  type: 'logical',
556
936
  checker: function (operation, context, option) {
557
- var e_3, _a, e_4, _b;
937
+ var e_6, _a, e_7, _b;
558
938
  var promises = [];
559
939
  if (OneToManyMatrix[entity]) {
560
940
  var _loop_5 = function (otm) {
@@ -594,17 +974,17 @@ function createRemoveCheckers(schema, authDict) {
594
974
  }
595
975
  };
596
976
  try {
597
- for (var _c = (e_3 = void 0, tslib_1.__values(OneToManyMatrix[entity])), _d = _c.next(); !_d.done; _d = _c.next()) {
977
+ for (var _c = (e_6 = void 0, tslib_1.__values(OneToManyMatrix[entity])), _d = _c.next(); !_d.done; _d = _c.next()) {
598
978
  var otm = _d.value;
599
979
  _loop_5(otm);
600
980
  }
601
981
  }
602
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
982
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
603
983
  finally {
604
984
  try {
605
985
  if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
606
986
  }
607
- finally { if (e_3) throw e_3.error; }
987
+ finally { if (e_6) throw e_6.error; }
608
988
  }
609
989
  }
610
990
  if (OneToManyOnEntityMatrix[entity]) {
@@ -652,17 +1032,17 @@ function createRemoveCheckers(schema, authDict) {
652
1032
  }
653
1033
  };
654
1034
  try {
655
- for (var _e = (e_4 = void 0, tslib_1.__values(OneToManyOnEntityMatrix[entity])), _f = _e.next(); !_f.done; _f = _e.next()) {
1035
+ for (var _e = (e_7 = void 0, tslib_1.__values(OneToManyOnEntityMatrix[entity])), _f = _e.next(); !_f.done; _f = _e.next()) {
656
1036
  var otm = _f.value;
657
1037
  _loop_6(otm);
658
1038
  }
659
1039
  }
660
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
1040
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
661
1041
  finally {
662
1042
  try {
663
1043
  if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
664
1044
  }
665
- finally { if (e_4) throw e_4.error; }
1045
+ finally { if (e_7) throw e_7.error; }
666
1046
  }
667
1047
  }
668
1048
  if (promises.length > 0) {
@@ -677,15 +1057,15 @@ function createRemoveCheckers(schema, authDict) {
677
1057
  _loop_3(entity);
678
1058
  }
679
1059
  }
680
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1060
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
681
1061
  finally {
682
1062
  try {
683
1063
  if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1);
684
1064
  }
685
- finally { if (e_1) throw e_1.error; }
1065
+ finally { if (e_4) throw e_4.error; }
686
1066
  }
687
1067
  var _loop_4 = function (entity) {
688
- var e_5, _b;
1068
+ var e_8, _b;
689
1069
  var cascadeRemove = authDict[entity].cascadeRemove;
690
1070
  if (cascadeRemove) {
691
1071
  var entitiesOnEntityAttr = [];
@@ -805,17 +1185,17 @@ function createRemoveCheckers(schema, authDict) {
805
1185
  });
806
1186
  };
807
1187
  try {
808
- for (var restEntities_1 = (e_5 = void 0, tslib_1.__values(restEntities)), restEntities_1_1 = restEntities_1.next(); !restEntities_1_1.done; restEntities_1_1 = restEntities_1.next()) {
1188
+ 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()) {
809
1189
  var e = restEntities_1_1.value;
810
1190
  _loop_8(e);
811
1191
  }
812
1192
  }
813
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
1193
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
814
1194
  finally {
815
1195
  try {
816
1196
  if (restEntities_1_1 && !restEntities_1_1.done && (_b = restEntities_1.return)) _b.call(restEntities_1);
817
1197
  }
818
- finally { if (e_5) throw e_5.error; }
1198
+ finally { if (e_8) throw e_8.error; }
819
1199
  }
820
1200
  }
821
1201
  }