oak-domain 2.6.7 → 2.6.9
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/base-app-domain/ActionAuth/Schema.d.ts +156 -0
- package/lib/base-app-domain/ActionAuth/Schema.js +2 -0
- package/lib/base-app-domain/ActionAuth/Storage.d.ts +3 -0
- package/lib/base-app-domain/ActionAuth/Storage.js +49 -0
- package/lib/base-app-domain/EntityDict.d.ts +8 -0
- package/lib/base-app-domain/Modi/Storage.js +5 -0
- package/lib/base-app-domain/ModiEntity/Schema.d.ts +112 -4
- package/lib/base-app-domain/ModiEntity/Storage.js +4 -1
- package/lib/base-app-domain/Oper/Storage.js +3 -0
- package/lib/base-app-domain/OperEntity/Schema.d.ts +112 -4
- package/lib/base-app-domain/OperEntity/Storage.js +4 -1
- package/lib/base-app-domain/Relation/Schema.d.ts +160 -0
- package/lib/base-app-domain/Relation/Schema.js +2 -0
- package/lib/base-app-domain/Relation/Storage.d.ts +3 -0
- package/lib/base-app-domain/Relation/Storage.js +57 -0
- package/lib/base-app-domain/RelationAuth/Schema.d.ts +156 -0
- package/lib/base-app-domain/RelationAuth/Schema.js +2 -0
- package/lib/base-app-domain/RelationAuth/Storage.d.ts +3 -0
- package/lib/base-app-domain/RelationAuth/Storage.js +49 -0
- package/lib/base-app-domain/Storage.js +20 -12
- package/lib/base-app-domain/User/Schema.d.ts +11 -0
- package/lib/base-app-domain/UserEntityGrant/Storage.js +3 -0
- package/lib/base-app-domain/UserRelation/Schema.d.ts +175 -0
- package/lib/base-app-domain/UserRelation/Schema.js +2 -0
- package/lib/base-app-domain/UserRelation/Storage.d.ts +3 -0
- package/lib/base-app-domain/UserRelation/Storage.js +36 -0
- package/lib/base-app-domain/_SubQuery.d.ts +32 -0
- package/lib/checkers/index.js +1 -0
- package/lib/compiler/schemalBuilder.js +4 -1
- package/lib/entities/ActionAuth.d.ts +11 -0
- package/lib/entities/ActionAuth.js +30 -0
- package/lib/entities/Relation.d.ts +8 -0
- package/lib/entities/Relation.js +33 -0
- package/lib/entities/RelationAuth.d.ts +11 -0
- package/lib/entities/RelationAuth.js +30 -0
- package/lib/entities/UserRelation.d.ts +7 -0
- package/lib/entities/UserRelation.js +28 -0
- package/lib/store/CascadeStore.js +5 -4
- package/lib/store/checker.d.ts +1 -0
- package/lib/store/checker.js +200 -19
- package/lib/store/modi.js +2 -2
- package/lib/store/relation.js +1 -0
- package/lib/timers/vaccum.js +4 -4
- package/lib/types/Auth.d.ts +1 -1
- package/lib/types/Connector.d.ts +6 -0
- package/lib/types/Entity.d.ts +2 -1
- package/lib/types/Exception.d.ts +5 -2
- package/lib/types/Exception.js +15 -1
- package/lib/utils/SimpleConnector.d.ts +15 -2
- package/lib/utils/SimpleConnector.js +39 -4
- package/lib/utils/money.d.ts +2 -1
- package/lib/utils/money.js +17 -1
- package/lib/utils/validator.js +1 -1
- package/lib/utils/version.d.ts +7 -0
- package/lib/utils/version.js +21 -0
- package/package.json +1 -1
- package/src/entities/ActionAuth.ts +49 -0
- package/src/entities/Relation.ts +49 -0
- package/src/entities/RelationAuth.ts +49 -0
- package/src/entities/UserRelation.ts +44 -0
- package/lib/checkers/SyncCheckExecutor.d.ts +0 -9
- package/lib/checkers/SyncCheckExecutor.js +0 -103
package/lib/store/checker.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createRemoveCheckers = exports.createAuthCheckers = exports.translateCheckerInSyncContext = exports.translateCheckerInAsyncContext = void 0;
|
|
3
|
+
exports.createCreateCheckers = exports.createRemoveCheckers = exports.createAuthCheckers = exports.translateCheckerInSyncContext = exports.translateCheckerInAsyncContext = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
var filter_1 = require("../store/filter");
|
|
@@ -11,6 +11,7 @@ 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
|
+
var action_1 = require("../actions/action");
|
|
14
15
|
/**
|
|
15
16
|
*
|
|
16
17
|
* @param checker 要翻译的checker
|
|
@@ -112,7 +113,7 @@ function translateCheckerInAsyncContext(checker) {
|
|
|
112
113
|
var fn = (function (_a, context, option) {
|
|
113
114
|
var operation = _a.operation;
|
|
114
115
|
return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
115
|
-
var result, _b, filter, action;
|
|
116
|
+
var result, _b, filter, action, errMsg2;
|
|
116
117
|
return tslib_1.__generator(this, function (_c) {
|
|
117
118
|
switch (_c.label) {
|
|
118
119
|
case 0:
|
|
@@ -145,7 +146,8 @@ function translateCheckerInAsyncContext(checker) {
|
|
|
145
146
|
if (_c.sent()) {
|
|
146
147
|
return [2 /*return*/];
|
|
147
148
|
}
|
|
148
|
-
|
|
149
|
+
errMsg2 = typeof errMsg_2 === 'function' ? errMsg_2(operation, context, option) : errMsg_2;
|
|
150
|
+
throw new Exception_1.OakUserUnpermittedException(errMsg2);
|
|
149
151
|
case 5: return [2 /*return*/, 0];
|
|
150
152
|
}
|
|
151
153
|
});
|
|
@@ -235,7 +237,8 @@ function translateCheckerInSyncContext(checker) {
|
|
|
235
237
|
if ((0, filter_1.checkFilterContains)(entity, context, result, filter, true)) {
|
|
236
238
|
return;
|
|
237
239
|
}
|
|
238
|
-
|
|
240
|
+
var errMsg2 = typeof errMsg_4 === 'function' ? errMsg_4(operation, context, option) : errMsg_4;
|
|
241
|
+
throw new Exception_1.OakUserUnpermittedException(errMsg2);
|
|
239
242
|
}
|
|
240
243
|
};
|
|
241
244
|
return {
|
|
@@ -438,19 +441,20 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) {
|
|
|
438
441
|
if (d.entity === attr && typeof d.entityId === 'string') {
|
|
439
442
|
return d.entityId;
|
|
440
443
|
}
|
|
441
|
-
throw new Exception_1.OakUserUnpermittedException();
|
|
442
444
|
}
|
|
443
445
|
else {
|
|
444
446
|
(0, assert_1.default)(typeof relation === 'string');
|
|
445
447
|
if (typeof d["".concat(attr, "Id")] === 'string') {
|
|
446
448
|
return d["".concat(attr, "Id")];
|
|
447
449
|
}
|
|
448
|
-
throw new Exception_1.OakUserUnpermittedException();
|
|
449
450
|
}
|
|
450
451
|
};
|
|
451
452
|
if (relation === 2) {
|
|
452
453
|
if (data instanceof Array) {
|
|
453
|
-
var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); }));
|
|
454
|
+
var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); }).filter(function (ele) { return !!ele; }));
|
|
455
|
+
if (fkIds.length === 0) {
|
|
456
|
+
return new Exception_1.OakUserUnpermittedException();
|
|
457
|
+
}
|
|
454
458
|
return {
|
|
455
459
|
$entity: attr,
|
|
456
460
|
$filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: fkIds } }),
|
|
@@ -458,6 +462,9 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) {
|
|
|
458
462
|
};
|
|
459
463
|
}
|
|
460
464
|
var fkId_1 = getForeignKeyId_1(data);
|
|
465
|
+
if (!fkId_1) {
|
|
466
|
+
return new Exception_1.OakUserUnpermittedException();
|
|
467
|
+
}
|
|
461
468
|
return {
|
|
462
469
|
$entity: attr,
|
|
463
470
|
$filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: fkId_1 }),
|
|
@@ -465,7 +472,10 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) {
|
|
|
465
472
|
}
|
|
466
473
|
(0, assert_1.default)(typeof relation === 'string');
|
|
467
474
|
if (data instanceof Array) {
|
|
468
|
-
var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); }));
|
|
475
|
+
var fkIds = (0, lodash_1.uniq)(data.map(function (d) { return getForeignKeyId_1(d); }).filter(function (ele) { return !!ele; }));
|
|
476
|
+
if (fkIds.length === 0) {
|
|
477
|
+
return new Exception_1.OakUserUnpermittedException();
|
|
478
|
+
}
|
|
469
479
|
return {
|
|
470
480
|
$entity: relation,
|
|
471
481
|
$filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: { $in: fkIds } }),
|
|
@@ -473,6 +483,9 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) {
|
|
|
473
483
|
};
|
|
474
484
|
}
|
|
475
485
|
var fkId = getForeignKeyId_1(data);
|
|
486
|
+
if (!fkId) {
|
|
487
|
+
return new Exception_1.OakUserUnpermittedException();
|
|
488
|
+
}
|
|
476
489
|
return {
|
|
477
490
|
$entity: relation,
|
|
478
491
|
$filter: (0, filter_1.addFilterSegment)(filterMaker2(userId), { id: fkId }),
|
|
@@ -483,9 +496,9 @@ function translateCascadeRelationFilterMaker(schema, lch, entity2, pathPrefix) {
|
|
|
483
496
|
var filter_4 = operation.filter;
|
|
484
497
|
if (filter_4) {
|
|
485
498
|
var counter = translateCreateFilterMaker(entity2, filter_4, userId);
|
|
486
|
-
if (counter instanceof
|
|
487
|
-
|
|
488
|
-
}
|
|
499
|
+
// if (counter instanceof OakUserUnpermittedException) {
|
|
500
|
+
// throw counter;
|
|
501
|
+
// }
|
|
489
502
|
return counter;
|
|
490
503
|
}
|
|
491
504
|
throw new Exception_1.OakUserUnpermittedException();
|
|
@@ -593,19 +606,25 @@ function execCreateCounter(context, counter) {
|
|
|
593
606
|
}
|
|
594
607
|
else if (counter === null || counter === void 0 ? void 0 : counter.$entity) {
|
|
595
608
|
var _a = counter, $entity = _a.$entity, $filter = _a.$filter, _b = _a.$count, $count_1 = _b === void 0 ? 1 : _b;
|
|
596
|
-
|
|
609
|
+
// count不走reinforceSelection,先用select
|
|
610
|
+
var result = context.select($entity, {
|
|
611
|
+
data: {
|
|
612
|
+
id: 1,
|
|
613
|
+
},
|
|
597
614
|
filter: $filter,
|
|
615
|
+
indexFrom: 0,
|
|
616
|
+
count: $count_1,
|
|
598
617
|
}, { dontCollect: true });
|
|
599
|
-
if (
|
|
600
|
-
return
|
|
601
|
-
if (
|
|
618
|
+
if (result instanceof Promise) {
|
|
619
|
+
return result.then(function (r2) {
|
|
620
|
+
if (r2.length >= $count_1) {
|
|
602
621
|
return undefined;
|
|
603
622
|
}
|
|
604
623
|
return new Exception_1.OakUserUnpermittedException();
|
|
605
624
|
});
|
|
606
625
|
}
|
|
607
626
|
else {
|
|
608
|
-
return
|
|
627
|
+
return result.length >= $count_1 ? undefined : new Exception_1.OakUserUnpermittedException();
|
|
609
628
|
}
|
|
610
629
|
}
|
|
611
630
|
}
|
|
@@ -783,7 +802,10 @@ function createAuthCheckers(schema, authDict) {
|
|
|
783
802
|
var filter = makePotentialFilter(operation, context, raFilterMakerDict_1[relation]);
|
|
784
803
|
return filter;
|
|
785
804
|
},
|
|
786
|
-
errMsg:
|
|
805
|
+
errMsg: function (operation, context) {
|
|
806
|
+
console.error("\u521B\u5EFA".concat(entity, "\u65F6\u8D8A\u6743\uFF0CuserId\u662F").concat(context.getCurrentUserId(), "\uFF0C\u6570\u636E\u662F").concat(JSON.stringify(operation.data)));
|
|
807
|
+
return "\u521B\u5EFA".concat(entity, "\u65F6\u8D8A\u6743");
|
|
808
|
+
},
|
|
787
809
|
});
|
|
788
810
|
checkers.push({
|
|
789
811
|
entity: userEntityName,
|
|
@@ -841,7 +863,10 @@ function createAuthCheckers(schema, authDict) {
|
|
|
841
863
|
}
|
|
842
864
|
return makeFilterFromRows(toBeRemoved); */
|
|
843
865
|
},
|
|
844
|
-
errMsg:
|
|
866
|
+
errMsg: function (operation, context) {
|
|
867
|
+
console.error("\u79FB\u9664".concat(entity, "\u65F6\u8D8A\u6743\uFF0CuserId\u662F").concat(context.getCurrentUserId(), "\uFF0C\u79FB\u9664\u6761\u4EF6\u662F").concat(JSON.stringify(operation.filter)));
|
|
868
|
+
return "\u79FB\u9664".concat(entity, "\u65F6\u8D8A\u6743");
|
|
869
|
+
},
|
|
845
870
|
});
|
|
846
871
|
// 转让权限现在用update动作,只允许update userId给其它人
|
|
847
872
|
// todo 等实现的时候再写
|
|
@@ -858,7 +883,11 @@ function createAuthCheckers(schema, authDict) {
|
|
|
858
883
|
var filter = makePotentialFilter(operation, context, filterMaker);
|
|
859
884
|
return filter;
|
|
860
885
|
},
|
|
861
|
-
errMsg:
|
|
886
|
+
errMsg: function (operation, context) {
|
|
887
|
+
var _a = operation, action = _a.action, data = _a.data, filter = _a.filter;
|
|
888
|
+
console.error("\u5BF9".concat(entity, "\u8FDB\u884C").concat(action, "\u65F6\u8D8A\u6743\uFF0CuserId\u662F").concat(context.getCurrentUserId(), "\n \u6570\u636E\u662F").concat(JSON.stringify(data), "\uFF0C\u6761\u4EF6\u662F").concat(JSON.stringify(filter)));
|
|
889
|
+
return "\u5BF9".concat(entity, "\u8FDB\u884C").concat(action, "\u65F6\u8D8A\u6743");
|
|
890
|
+
},
|
|
862
891
|
});
|
|
863
892
|
};
|
|
864
893
|
for (var a in actionAuth) {
|
|
@@ -1216,3 +1245,155 @@ function createRemoveCheckers(schema, authDict) {
|
|
|
1216
1245
|
return checkers;
|
|
1217
1246
|
}
|
|
1218
1247
|
exports.createRemoveCheckers = createRemoveCheckers;
|
|
1248
|
+
function checkAttributeLegal(schema, entity, data) {
|
|
1249
|
+
var _a;
|
|
1250
|
+
var attributes = schema[entity].attributes;
|
|
1251
|
+
for (var attr in data) {
|
|
1252
|
+
if (attributes[attr]) {
|
|
1253
|
+
var _b = attributes[attr], type = _b.type, params = _b.params, defaultValue = _b.default, enumeration = _b.enumeration, notNull = _b.notNull;
|
|
1254
|
+
if (data[attr] === null || data[attr] === undefined) {
|
|
1255
|
+
if (notNull && defaultValue === undefined) {
|
|
1256
|
+
throw new Exception_1.OakAttrNotNullException(entity, [attr]);
|
|
1257
|
+
}
|
|
1258
|
+
if (defaultValue !== undefined) {
|
|
1259
|
+
Object.assign(data, (_a = {},
|
|
1260
|
+
_a[attr] = defaultValue,
|
|
1261
|
+
_a));
|
|
1262
|
+
}
|
|
1263
|
+
continue;
|
|
1264
|
+
}
|
|
1265
|
+
switch (type) {
|
|
1266
|
+
case 'char':
|
|
1267
|
+
case 'varchar': {
|
|
1268
|
+
if (typeof data[attr] !== 'string') {
|
|
1269
|
+
throw new Exception_1.OakInputIllegalException(entity, [attr], 'not a string');
|
|
1270
|
+
}
|
|
1271
|
+
var length_1 = params.length;
|
|
1272
|
+
if (length_1 && data[attr].length > length_1) {
|
|
1273
|
+
throw new Exception_1.OakInputIllegalException(entity, [attr], 'too long');
|
|
1274
|
+
}
|
|
1275
|
+
break;
|
|
1276
|
+
}
|
|
1277
|
+
case 'int':
|
|
1278
|
+
case 'smallint':
|
|
1279
|
+
case 'tinyint':
|
|
1280
|
+
case 'bigint':
|
|
1281
|
+
case 'decimal':
|
|
1282
|
+
case 'money': {
|
|
1283
|
+
if (typeof data[attr] !== 'number') {
|
|
1284
|
+
throw new Exception_1.OakInputIllegalException(entity, [attr], 'not a number');
|
|
1285
|
+
}
|
|
1286
|
+
var _c = params || {}, min = _c.min, max = _c.max;
|
|
1287
|
+
if (typeof min === 'number' && data[attr] < min) {
|
|
1288
|
+
throw new Exception_1.OakInputIllegalException(entity, [attr], 'too small');
|
|
1289
|
+
}
|
|
1290
|
+
if (typeof max === 'number' && data[attr] > max) {
|
|
1291
|
+
throw new Exception_1.OakInputIllegalException(entity, [attr], 'too big');
|
|
1292
|
+
}
|
|
1293
|
+
break;
|
|
1294
|
+
}
|
|
1295
|
+
case 'enum': {
|
|
1296
|
+
(0, assert_1.default)(enumeration);
|
|
1297
|
+
if (!enumeration.includes(data[attr])) {
|
|
1298
|
+
throw new Exception_1.OakInputIllegalException(entity, [attr], 'not in enumberation');
|
|
1299
|
+
}
|
|
1300
|
+
break;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
else {
|
|
1305
|
+
// 这里似乎还有一种update中带cascade remove的case,等遇到再说(貌似cascadeUpdate没有处理完整这种情况) by Xc
|
|
1306
|
+
if (typeof data[attr] === 'object' && data[attr].action === 'remove') {
|
|
1307
|
+
console.warn('cascade remove可能是未处理的边界,请注意');
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
function createCreateCheckers(schema) {
|
|
1313
|
+
var checkers = [];
|
|
1314
|
+
var _loop_9 = function (entity) {
|
|
1315
|
+
var _a = schema[entity], attributes = _a.attributes, actions = _a.actions;
|
|
1316
|
+
var notNullAttrs = Object.keys(attributes).filter(function (ele) { return attributes[ele].notNull; });
|
|
1317
|
+
var updateActions = (0, lodash_1.difference)(actions, action_1.excludeUpdateActions);
|
|
1318
|
+
checkers.push({
|
|
1319
|
+
entity: entity,
|
|
1320
|
+
type: 'data',
|
|
1321
|
+
action: 'create',
|
|
1322
|
+
checker: function (data) {
|
|
1323
|
+
var checkData = function (data2) {
|
|
1324
|
+
var e_9, _a, e_10, _b;
|
|
1325
|
+
var illegalNullAttrs = (0, lodash_1.difference)(notNullAttrs, Object.keys(data2));
|
|
1326
|
+
if (illegalNullAttrs.length > 0) {
|
|
1327
|
+
try {
|
|
1328
|
+
// 要处理多对一的cascade create
|
|
1329
|
+
for (var illegalNullAttrs_1 = (e_9 = void 0, tslib_1.__values(illegalNullAttrs)), illegalNullAttrs_1_1 = illegalNullAttrs_1.next(); !illegalNullAttrs_1_1.done; illegalNullAttrs_1_1 = illegalNullAttrs_1.next()) {
|
|
1330
|
+
var attr = illegalNullAttrs_1_1.value;
|
|
1331
|
+
if (attr === 'entityId') {
|
|
1332
|
+
if (illegalNullAttrs.includes('entity')) {
|
|
1333
|
+
continue;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
else if (attr === 'entity' && attributes[attr].ref) {
|
|
1337
|
+
var hasCascadeCreate = false;
|
|
1338
|
+
try {
|
|
1339
|
+
for (var _c = (e_10 = void 0, tslib_1.__values(attributes[attr].ref)), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
1340
|
+
var ref = _d.value;
|
|
1341
|
+
if (data2[ref] && data2[ref].action === 'create') {
|
|
1342
|
+
hasCascadeCreate = true;
|
|
1343
|
+
break;
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
1348
|
+
finally {
|
|
1349
|
+
try {
|
|
1350
|
+
if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
|
|
1351
|
+
}
|
|
1352
|
+
finally { if (e_10) throw e_10.error; }
|
|
1353
|
+
}
|
|
1354
|
+
if (hasCascadeCreate) {
|
|
1355
|
+
continue;
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
else if (attributes[attr].type === 'ref') {
|
|
1359
|
+
var ref = attributes[attr].ref;
|
|
1360
|
+
if (data2[ref] && data2[ref].action === 'create') {
|
|
1361
|
+
continue;
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
// 到这里说明确实是有not null的属性没有赋值
|
|
1365
|
+
throw new Exception_1.OakAttrNotNullException(entity, illegalNullAttrs);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
1369
|
+
finally {
|
|
1370
|
+
try {
|
|
1371
|
+
if (illegalNullAttrs_1_1 && !illegalNullAttrs_1_1.done && (_a = illegalNullAttrs_1.return)) _a.call(illegalNullAttrs_1);
|
|
1372
|
+
}
|
|
1373
|
+
finally { if (e_9) throw e_9.error; }
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
checkAttributeLegal(schema, entity, data2);
|
|
1377
|
+
};
|
|
1378
|
+
if (data instanceof Array) {
|
|
1379
|
+
data.forEach(function (ele) { return checkData(ele); });
|
|
1380
|
+
}
|
|
1381
|
+
else {
|
|
1382
|
+
checkData(data);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
}, {
|
|
1386
|
+
entity: entity,
|
|
1387
|
+
type: 'data',
|
|
1388
|
+
action: updateActions,
|
|
1389
|
+
checker: function (data) {
|
|
1390
|
+
checkAttributeLegal(schema, entity, data);
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
};
|
|
1394
|
+
for (var entity in schema) {
|
|
1395
|
+
_loop_9(entity);
|
|
1396
|
+
}
|
|
1397
|
+
return checkers;
|
|
1398
|
+
}
|
|
1399
|
+
exports.createCreateCheckers = createCreateCheckers;
|
package/lib/store/modi.js
CHANGED
|
@@ -151,8 +151,8 @@ function createModiRelatedTriggers(schema) {
|
|
|
151
151
|
var _this = this;
|
|
152
152
|
var triggers = [];
|
|
153
153
|
var _loop_2 = function (entity) {
|
|
154
|
-
var
|
|
155
|
-
if (
|
|
154
|
+
var toModi = schema[entity].toModi;
|
|
155
|
+
if (toModi) {
|
|
156
156
|
// 当关联modi的对象被删除时,对应的modi也删除。这里似乎只需要删除掉活跃对象?因为oper不能删除,所以oper和modi是必须要支持对deleted对象的容错?
|
|
157
157
|
// 这里没有想清楚,by Xc 20230209
|
|
158
158
|
triggers.push({
|
package/lib/store/relation.js
CHANGED
|
@@ -55,6 +55,7 @@ function judgeRelation(schema, entity, attr) {
|
|
|
55
55
|
else if (attributes.hasOwnProperty('entity')
|
|
56
56
|
&& attributes.hasOwnProperty('entityId')
|
|
57
57
|
&& schema.hasOwnProperty(attr)) {
|
|
58
|
+
(0, assert_1.default)(attributes.entity.ref.includes(attr), '不应当出现的case');
|
|
58
59
|
// 反向指针的外键
|
|
59
60
|
return 2;
|
|
60
61
|
}
|
package/lib/timers/vaccum.js
CHANGED
|
@@ -5,7 +5,6 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
|
6
6
|
var fs_1 = require("fs");
|
|
7
7
|
var filter_1 = require("../store/filter");
|
|
8
|
-
var node_zlib_1 = require("node:zlib");
|
|
9
8
|
var stream_1 = require("stream");
|
|
10
9
|
var uuid_1 = require("../utils/uuid");
|
|
11
10
|
/**
|
|
@@ -23,7 +22,7 @@ function vaccumEntities(option, context) {
|
|
|
23
22
|
case 0:
|
|
24
23
|
entities = option.entities, backupDir = option.backupDir;
|
|
25
24
|
_loop_1 = function (ele) {
|
|
26
|
-
var entity, filter, aliveLine, filter2, zip, now, backFile, fd_1, attributes_1, projection_1, attr, count_1, appendData_1, gzip_1, source_1, destination_1, _c, _d, _e;
|
|
25
|
+
var entity, filter, aliveLine, filter2, zip, now, backFile, fd_1, attributes_1, projection_1, attr, count_1, appendData_1, createGzip, gzip_1, source_1, destination_1, _c, _d, _e;
|
|
27
26
|
var _f, _g;
|
|
28
27
|
return tslib_1.__generator(this, function (_h) {
|
|
29
28
|
switch (_h.label) {
|
|
@@ -37,7 +36,7 @@ function vaccumEntities(option, context) {
|
|
|
37
36
|
if (filter) {
|
|
38
37
|
filter2 = (0, filter_1.combineFilters)([filter2, filter]);
|
|
39
38
|
}
|
|
40
|
-
if (!backupDir) return [3 /*break*/, 4];
|
|
39
|
+
if (!(backupDir && process.env.OAK_PLATFORM === 'server')) return [3 /*break*/, 4];
|
|
41
40
|
zip = option.zip;
|
|
42
41
|
now = (0, dayjs_1.default)();
|
|
43
42
|
backFile = "".concat(backupDir, "/").concat(entity, "-").concat(now.format('YYYY-MM-DD HH:mm:ss'), ".csv");
|
|
@@ -107,7 +106,8 @@ function vaccumEntities(option, context) {
|
|
|
107
106
|
return [3 /*break*/, 4];
|
|
108
107
|
case 2:
|
|
109
108
|
if (!zip) return [3 /*break*/, 4];
|
|
110
|
-
|
|
109
|
+
createGzip = require('zlib').createGzip;
|
|
110
|
+
gzip_1 = createGzip();
|
|
111
111
|
source_1 = (0, fs_1.createReadStream)(backFile);
|
|
112
112
|
destination_1 = (0, fs_1.createWriteStream)("".concat(backFile, ".zip"));
|
|
113
113
|
return [4 /*yield*/, new Promise(function (resolve, reject) {
|
package/lib/types/Auth.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export declare type RelationChecker<ED extends EntityDict, T extends keyof ED, C
|
|
|
35
35
|
when?: 'after';
|
|
36
36
|
action: ED[T]['Action'] | Array<ED[T]['Action']>;
|
|
37
37
|
relationFilter: (operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => SyncOrAsync<ED[T]['Selection']['filter']>;
|
|
38
|
-
errMsg: string;
|
|
38
|
+
errMsg: string | ((operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option?: OperateOption | SelectOption) => string);
|
|
39
39
|
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => SyncOrAsync<ED[T]['Selection']['filter']>);
|
|
40
40
|
};
|
|
41
41
|
export declare type LogicalChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
package/lib/types/Connector.d.ts
CHANGED
|
@@ -24,4 +24,10 @@ export declare abstract class Connector<ED extends EntityDict, BackCxt extends A
|
|
|
24
24
|
body: any;
|
|
25
25
|
headers?: Record<string, any>;
|
|
26
26
|
};
|
|
27
|
+
abstract getBridgeRouter(): string;
|
|
28
|
+
abstract makeBridgeUrl(url: string, headers?: Record<string, string>): string;
|
|
29
|
+
abstract parseBridgeRequestQuery(urlParams: string): {
|
|
30
|
+
url: string;
|
|
31
|
+
headers?: Record<string, string>;
|
|
32
|
+
};
|
|
27
33
|
}
|
package/lib/types/Entity.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export interface EntityShape {
|
|
|
65
65
|
$$updateAt$$: number | Date;
|
|
66
66
|
$$deleteAt$$?: number | Date | null;
|
|
67
67
|
}
|
|
68
|
-
interface GeneralEntityShape extends EntityShape {
|
|
68
|
+
export interface GeneralEntityShape extends EntityShape {
|
|
69
69
|
[K: string]: any;
|
|
70
70
|
}
|
|
71
71
|
export declare type MakeAction<A extends string> = A;
|
|
@@ -181,4 +181,5 @@ export declare type Configuration = {
|
|
|
181
181
|
actionType?: ActionType;
|
|
182
182
|
static?: boolean;
|
|
183
183
|
};
|
|
184
|
+
export declare type OtmKey<K extends string> = K | `${K}$${number}`;
|
|
184
185
|
export {};
|
package/lib/types/Exception.d.ts
CHANGED
|
@@ -55,12 +55,15 @@ export declare class OakRowInconsistencyException<ED extends EntityDict> extends
|
|
|
55
55
|
export declare class OakInputIllegalException<ED extends EntityDict> extends OakUserException<ED> {
|
|
56
56
|
private attributes;
|
|
57
57
|
private entity;
|
|
58
|
-
constructor(entity:
|
|
59
|
-
getEntity():
|
|
58
|
+
constructor(entity: keyof ED, attributes: string[], message?: string);
|
|
59
|
+
getEntity(): keyof ED;
|
|
60
60
|
getAttributes(): string[];
|
|
61
61
|
addAttributesPrefix(prefix: string): void;
|
|
62
62
|
toString(): string;
|
|
63
63
|
}
|
|
64
|
+
export declare class OakAttrNotNullException<ED extends EntityDict> extends OakInputIllegalException<ED> {
|
|
65
|
+
constructor(entity: keyof ED, attributes: string[], message?: string);
|
|
66
|
+
}
|
|
64
67
|
/**
|
|
65
68
|
* 用户权限不够时抛的异常
|
|
66
69
|
*/
|
package/lib/types/Exception.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.makeException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserUnpermittedException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakUserException = exports.OakExternalException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakDataException = exports.OakException = void 0;
|
|
3
|
+
exports.makeException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserUnpermittedException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakUserException = exports.OakExternalException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakDataException = exports.OakException = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
var OakException = /** @class */ (function (_super) {
|
|
@@ -179,6 +179,15 @@ var OakInputIllegalException = /** @class */ (function (_super) {
|
|
|
179
179
|
}(OakUserException));
|
|
180
180
|
exports.OakInputIllegalException = OakInputIllegalException;
|
|
181
181
|
;
|
|
182
|
+
// 属性为空
|
|
183
|
+
var OakAttrNotNullException = /** @class */ (function (_super) {
|
|
184
|
+
tslib_1.__extends(OakAttrNotNullException, _super);
|
|
185
|
+
function OakAttrNotNullException(entity, attributes, message) {
|
|
186
|
+
return _super.call(this, entity, attributes, message || '属性不允许为空') || this;
|
|
187
|
+
}
|
|
188
|
+
return OakAttrNotNullException;
|
|
189
|
+
}(OakInputIllegalException));
|
|
190
|
+
exports.OakAttrNotNullException = OakAttrNotNullException;
|
|
182
191
|
/**
|
|
183
192
|
* 用户权限不够时抛的异常
|
|
184
193
|
*/
|
|
@@ -344,6 +353,11 @@ function makeException(data) {
|
|
|
344
353
|
e.setOpRecords(data.opRecords);
|
|
345
354
|
return e;
|
|
346
355
|
}
|
|
356
|
+
case 'OakAttrNotNullException': {
|
|
357
|
+
var e = new OakAttrNotNullException(data.entity, data.attributes, data.message);
|
|
358
|
+
e.setOpRecords(data.opRecords);
|
|
359
|
+
return e;
|
|
360
|
+
}
|
|
347
361
|
default:
|
|
348
362
|
return;
|
|
349
363
|
}
|
|
@@ -4,8 +4,10 @@ import { AsyncContext, AsyncRowStore } from '../store/AsyncRowStore';
|
|
|
4
4
|
import { SyncContext } from '../store/SyncRowStore';
|
|
5
5
|
import { Connector, EntityDict, OakException } from "../types";
|
|
6
6
|
export declare class SimpleConnector<ED extends EntityDict, BackCxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>> extends Connector<ED, BackCxt, FrontCxt> {
|
|
7
|
-
static
|
|
8
|
-
|
|
7
|
+
static ASPECT_ROUTER: string;
|
|
8
|
+
static BRIDGE_ROUTER: string;
|
|
9
|
+
private serverAspectUrl;
|
|
10
|
+
private serverBridgeUrl;
|
|
9
11
|
private makeException;
|
|
10
12
|
private contextBuilder;
|
|
11
13
|
constructor(serverUrl: string, makeException: (exceptionData: any) => OakException<ED>, contextBuilder: (str: string | undefined) => (store: AsyncRowStore<ED, BackCxt>) => Promise<BackCxt>);
|
|
@@ -32,4 +34,15 @@ export declare class SimpleConnector<ED extends EntityDict, BackCxt extends Asyn
|
|
|
32
34
|
body: any;
|
|
33
35
|
headers?: Record<string, any> | undefined;
|
|
34
36
|
};
|
|
37
|
+
getBridgeRouter(): string;
|
|
38
|
+
/**
|
|
39
|
+
* 通过本地服务器桥接访问外部资源的url
|
|
40
|
+
* @param url
|
|
41
|
+
* @param headers
|
|
42
|
+
*/
|
|
43
|
+
makeBridgeUrl(url: string, headers?: Record<string, string>): string;
|
|
44
|
+
parseBridgeRequestQuery(urlParams: string): {
|
|
45
|
+
url: string;
|
|
46
|
+
headers?: Record<string, string> | undefined;
|
|
47
|
+
};
|
|
35
48
|
}
|
|
@@ -4,6 +4,7 @@ exports.SimpleConnector = void 0;
|
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
var stream_1 = require("stream");
|
|
7
|
+
var url_1 = tslib_1.__importDefault(require("url"));
|
|
7
8
|
var types_1 = require("../types");
|
|
8
9
|
function makeContentTypeAndBody(data) {
|
|
9
10
|
//
|
|
@@ -24,7 +25,8 @@ var SimpleConnector = /** @class */ (function (_super) {
|
|
|
24
25
|
tslib_1.__extends(SimpleConnector, _super);
|
|
25
26
|
function SimpleConnector(serverUrl, makeException, contextBuilder) {
|
|
26
27
|
var _this = _super.call(this) || this;
|
|
27
|
-
_this.
|
|
28
|
+
_this.serverAspectUrl = "".concat(serverUrl).concat(SimpleConnector.ASPECT_ROUTER);
|
|
29
|
+
_this.serverBridgeUrl = "".concat(serverUrl).concat(SimpleConnector.BRIDGE_ROUTER);
|
|
28
30
|
_this.makeException = makeException;
|
|
29
31
|
_this.contextBuilder = contextBuilder;
|
|
30
32
|
return _this;
|
|
@@ -37,7 +39,7 @@ var SimpleConnector = /** @class */ (function (_super) {
|
|
|
37
39
|
case 0:
|
|
38
40
|
cxtStr = context.toString();
|
|
39
41
|
_a = makeContentTypeAndBody(params), contentType = _a.contentType, body = _a.body;
|
|
40
|
-
return [4 /*yield*/, global.fetch(this.
|
|
42
|
+
return [4 /*yield*/, global.fetch(this.serverAspectUrl, {
|
|
41
43
|
method: 'POST',
|
|
42
44
|
headers: Object.assign({
|
|
43
45
|
'oak-cxt': cxtStr,
|
|
@@ -82,7 +84,7 @@ var SimpleConnector = /** @class */ (function (_super) {
|
|
|
82
84
|
});
|
|
83
85
|
};
|
|
84
86
|
SimpleConnector.prototype.getRouter = function () {
|
|
85
|
-
return SimpleConnector.
|
|
87
|
+
return SimpleConnector.ASPECT_ROUTER;
|
|
86
88
|
};
|
|
87
89
|
SimpleConnector.prototype.parseRequest = function (headers, body, store) {
|
|
88
90
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
@@ -139,7 +141,40 @@ var SimpleConnector = /** @class */ (function (_super) {
|
|
|
139
141
|
},
|
|
140
142
|
};
|
|
141
143
|
};
|
|
142
|
-
SimpleConnector.
|
|
144
|
+
SimpleConnector.prototype.getBridgeRouter = function () {
|
|
145
|
+
return SimpleConnector.BRIDGE_ROUTER;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* 通过本地服务器桥接访问外部资源的url
|
|
149
|
+
* @param url
|
|
150
|
+
* @param headers
|
|
151
|
+
*/
|
|
152
|
+
SimpleConnector.prototype.makeBridgeUrl = function (url, headers) {
|
|
153
|
+
// if (process.env.PROD !== 'true') {
|
|
154
|
+
// console.warn('在development下无法通过bridge访问资源,将直接访问,可能失败', url);
|
|
155
|
+
// return url;
|
|
156
|
+
// }
|
|
157
|
+
var encodeUrl = encodeURIComponent(url);
|
|
158
|
+
// const urlParse = URL.parse(url, true);
|
|
159
|
+
// const { search } = urlParse as {
|
|
160
|
+
// search: string;
|
|
161
|
+
// };
|
|
162
|
+
// if (headers) {
|
|
163
|
+
// search.append('headers', JSON.stringify(headers));
|
|
164
|
+
// }
|
|
165
|
+
return "".concat(this.serverBridgeUrl, "?url=").concat(encodeUrl);
|
|
166
|
+
};
|
|
167
|
+
SimpleConnector.prototype.parseBridgeRequestQuery = function (urlParams) {
|
|
168
|
+
var search = new url_1.default.URLSearchParams(urlParams);
|
|
169
|
+
var url = search.get('url');
|
|
170
|
+
var headers = search.get('headers');
|
|
171
|
+
return {
|
|
172
|
+
url: url,
|
|
173
|
+
headers: headers && JSON.parse(headers),
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
SimpleConnector.ASPECT_ROUTER = '/aspect';
|
|
177
|
+
SimpleConnector.BRIDGE_ROUTER = '/bridge';
|
|
143
178
|
return SimpleConnector;
|
|
144
179
|
}(types_1.Connector));
|
|
145
180
|
exports.SimpleConnector = SimpleConnector;
|
package/lib/utils/money.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ declare const ToCent: (float: number) => number;
|
|
|
2
2
|
declare const ToYuan: (int: number) => number;
|
|
3
3
|
declare const StringToCent: (value: string, allowNegative?: true) => number | undefined;
|
|
4
4
|
declare const CentToString: (value: number) => string | undefined;
|
|
5
|
-
|
|
5
|
+
declare const ThousandCont: (value: number) => string | undefined;
|
|
6
|
+
export { ToCent, ToYuan, StringToCent, CentToString, ThousandCont };
|
package/lib/utils/money.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CentToString = exports.StringToCent = exports.ToYuan = exports.ToCent = void 0;
|
|
3
|
+
exports.ThousandCont = exports.CentToString = exports.StringToCent = exports.ToYuan = exports.ToCent = void 0;
|
|
4
4
|
var ToCent = function (float) {
|
|
5
5
|
return Math.round(float * 100);
|
|
6
6
|
};
|
|
@@ -22,3 +22,19 @@ var CentToString = function (value) {
|
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
24
|
exports.CentToString = CentToString;
|
|
25
|
+
var ThousandCont = function (value) {
|
|
26
|
+
var value1 = "".concat(value);
|
|
27
|
+
var numArr = value1.split('.');
|
|
28
|
+
value1 = numArr[0];
|
|
29
|
+
var result = '';
|
|
30
|
+
while (value1.length > 3) {
|
|
31
|
+
result = ',' + value1.slice(-3) + result;
|
|
32
|
+
value1 = value1.slice(0, value1.length - 3);
|
|
33
|
+
}
|
|
34
|
+
if (value1) {
|
|
35
|
+
result = value1 + result;
|
|
36
|
+
}
|
|
37
|
+
result = result + '.' + numArr[1];
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
exports.ThousandCont = ThousandCont;
|
package/lib/utils/validator.js
CHANGED
|
@@ -114,7 +114,7 @@ function checkAttributesNotNull(entity, data, attributes, allowEmpty) {
|
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
if (attrs.length > 0) {
|
|
117
|
-
throw new types_1.
|
|
117
|
+
throw new types_1.OakAttrNotNullException(entity, attrs, '属性不能为空');
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
exports.checkAttributesNotNull = checkAttributesNotNull;
|