oak-domain 5.1.12 → 5.1.14
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/store/CascadeStore.d.ts +1 -0
- package/lib/store/CascadeStore.js +171 -125
- package/lib/store/RelationAuth.js +37 -1
- package/lib/store/projection.d.ts +2 -0
- package/lib/store/projection.js +15 -0
- package/lib/store/relation.js +1 -1
- package/lib/types/Configuration.d.ts +1 -12
- package/lib/types/Entity.d.ts +0 -1
- package/lib/types/Exception.d.ts +3 -0
- package/lib/types/Exception.js +12 -1
- package/lib/types/Expression.d.ts +1 -1
- package/lib/types/Expression.js +1 -4
- package/lib/types/Sync.d.ts +1 -0
- package/lib/utils/SimpleConnector.d.ts +1 -0
- package/lib/utils/SimpleConnector.js +40 -33
- package/package.json +1 -1
|
@@ -69,6 +69,7 @@ export declare abstract class CascadeStore<ED extends EntityDict & BaseEntityDic
|
|
|
69
69
|
protected preProcessDataCreated<T extends keyof ED>(entity: T, data: ED[T]['Create']['data']): void;
|
|
70
70
|
protected preProcessDataUpdated(action: string, data: Record<string, any>, async?: true): void;
|
|
71
71
|
judgeRelation(entity: keyof ED, attr: string): string | 1 | 2 | string[] | 0 | -1;
|
|
72
|
+
private tryMergeModi;
|
|
72
73
|
/**
|
|
73
74
|
* 和具体的update过程无关的例程放在这里,包括对later动作的处理、对oper的记录以及对record的收集等
|
|
74
75
|
* @param entity
|
|
@@ -247,7 +247,8 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
247
247
|
assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
|
|
248
248
|
}
|
|
249
249
|
// 如果对象中指向一对多的Modi,此时加上指向Modi的projection
|
|
250
|
-
|
|
250
|
+
// 此逻辑关闭,用户自己撰写去取modi by Xc 20241207
|
|
251
|
+
/* if (this.getSchema()[entity2].toModi) {
|
|
251
252
|
Object.assign(projectionNode, {
|
|
252
253
|
modi$entity: {
|
|
253
254
|
$entity: 'modi',
|
|
@@ -268,7 +269,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
268
269
|
},
|
|
269
270
|
}
|
|
270
271
|
});
|
|
271
|
-
}
|
|
272
|
+
} */
|
|
272
273
|
// 如果对象上有relation关系,在此将本用户相关的relation和actionAuth全部取出
|
|
273
274
|
// 还要将actionAuth上没有relation关系但destEntity为本对象的行也全部取出,这些是指向userId的可能路径
|
|
274
275
|
// 放在这里有点怪异,暂先这样
|
|
@@ -1050,6 +1051,118 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1050
1051
|
judgeRelation(entity, attr) {
|
|
1051
1052
|
return (0, relation_1.judgeRelation)(this.storageSchema, entity, attr);
|
|
1052
1053
|
}
|
|
1054
|
+
async tryMergeModi(entity, operation, context, ids, option) {
|
|
1055
|
+
const { action, data, filter, id: operId } = operation;
|
|
1056
|
+
const [upsertModi] = await this.selectAbjointRowAsync('modi', {
|
|
1057
|
+
data: {
|
|
1058
|
+
id: 1,
|
|
1059
|
+
data: 1,
|
|
1060
|
+
action: 1,
|
|
1061
|
+
},
|
|
1062
|
+
filter: {
|
|
1063
|
+
targetEntity: entity,
|
|
1064
|
+
iState: 'active',
|
|
1065
|
+
filter: ids.length > 0 ? {
|
|
1066
|
+
id: {
|
|
1067
|
+
$in: ids,
|
|
1068
|
+
},
|
|
1069
|
+
} : {
|
|
1070
|
+
id: ids[0],
|
|
1071
|
+
},
|
|
1072
|
+
},
|
|
1073
|
+
sorter: [
|
|
1074
|
+
{
|
|
1075
|
+
$attr: {
|
|
1076
|
+
$$createAt$$: 1,
|
|
1077
|
+
},
|
|
1078
|
+
$direction: 'desc',
|
|
1079
|
+
}
|
|
1080
|
+
],
|
|
1081
|
+
indexFrom: 0,
|
|
1082
|
+
count: 1,
|
|
1083
|
+
}, context, option);
|
|
1084
|
+
if (upsertModi) {
|
|
1085
|
+
const { data: data2, id: id2, action: action2 } = upsertModi;
|
|
1086
|
+
if (action === 'remove') {
|
|
1087
|
+
// 之前的都不做数
|
|
1088
|
+
if (action2 === 'create') {
|
|
1089
|
+
// 对冲掉
|
|
1090
|
+
return {
|
|
1091
|
+
id: await (0, uuid_1.generateNewIdAsync)(),
|
|
1092
|
+
action: 'remove',
|
|
1093
|
+
data: {},
|
|
1094
|
+
filter: {
|
|
1095
|
+
id: upsertModi.id,
|
|
1096
|
+
},
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
else {
|
|
1100
|
+
// 直接把这个改成删除
|
|
1101
|
+
(0, assert_1.default)(action2 !== 'remove');
|
|
1102
|
+
return {
|
|
1103
|
+
id: await (0, uuid_1.generateNewIdAsync)(),
|
|
1104
|
+
action: 'update',
|
|
1105
|
+
data: {
|
|
1106
|
+
action,
|
|
1107
|
+
data,
|
|
1108
|
+
},
|
|
1109
|
+
filter: {
|
|
1110
|
+
id: upsertModi.id,
|
|
1111
|
+
},
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
else {
|
|
1116
|
+
// 是update,直接把原来的data覆盖掉
|
|
1117
|
+
if (action !== action2 && process.env.NODE_ENV === 'development') {
|
|
1118
|
+
// 这种情况感觉是不会发生的
|
|
1119
|
+
console.warn('发生了同一行数据的modi的action不一致,请注意查看');
|
|
1120
|
+
}
|
|
1121
|
+
return {
|
|
1122
|
+
id: 'dummy',
|
|
1123
|
+
action: 'update',
|
|
1124
|
+
data: {
|
|
1125
|
+
data: Object.assign({}, data2, data),
|
|
1126
|
+
},
|
|
1127
|
+
filter: {
|
|
1128
|
+
id: id2,
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
// 说明没有已有的modi,必须要创建新的,此时应当在option中有相应的parentEntity/Id
|
|
1134
|
+
const { modiParentEntity, modiParentId } = option;
|
|
1135
|
+
(0, assert_1.default)(modiParentEntity && modiParentId);
|
|
1136
|
+
return {
|
|
1137
|
+
id: 'dummy',
|
|
1138
|
+
action: 'create',
|
|
1139
|
+
data: {
|
|
1140
|
+
id: operId,
|
|
1141
|
+
targetEntity: entity,
|
|
1142
|
+
entity: modiParentEntity,
|
|
1143
|
+
entityId: modiParentId,
|
|
1144
|
+
action,
|
|
1145
|
+
data,
|
|
1146
|
+
iState: 'active',
|
|
1147
|
+
filter: ids.length > 0 ? {
|
|
1148
|
+
id: {
|
|
1149
|
+
$in: ids,
|
|
1150
|
+
},
|
|
1151
|
+
} : {
|
|
1152
|
+
id: ids[0],
|
|
1153
|
+
},
|
|
1154
|
+
modiEntity$modi: {
|
|
1155
|
+
id: 'dummy',
|
|
1156
|
+
action: 'create',
|
|
1157
|
+
data: await Promise.all(ids.map(async (id) => ({
|
|
1158
|
+
id: await (0, uuid_1.generateNewIdAsync)(),
|
|
1159
|
+
entity: entity,
|
|
1160
|
+
entityId: id,
|
|
1161
|
+
}))),
|
|
1162
|
+
}
|
|
1163
|
+
},
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1053
1166
|
/**
|
|
1054
1167
|
* 和具体的update过程无关的例程放在这里,包括对later动作的处理、对oper的记录以及对record的收集等
|
|
1055
1168
|
* @param entity
|
|
@@ -1281,100 +1394,60 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1281
1394
|
if (data) {
|
|
1282
1395
|
this.preProcessDataUpdated(action, data, true);
|
|
1283
1396
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
// 变成对modi的插入
|
|
1287
|
-
// 优化,这里如果是对同一个targetEntity反复update,则变成对最后一条create/update的modi进行update,以避免发布文章这样的需求时产生过多的modi
|
|
1288
|
-
let modiUpsert;
|
|
1289
|
-
if (action === 'update') {
|
|
1290
|
-
// 如果action本身是update,且没有实际update属性,这里可以忽略
|
|
1291
|
-
const updateAttrCount = Object.keys(data).length;
|
|
1292
|
-
if (updateAttrCount === 0) {
|
|
1293
|
-
return {};
|
|
1294
|
-
}
|
|
1295
|
-
// 尝试和当前targetEntity的最后一条create/update进行合并,优化modi的条数
|
|
1296
|
-
const upsertModis = await this.selectAbjointRowAsync('modi', {
|
|
1297
|
-
data: {
|
|
1298
|
-
id: 1,
|
|
1299
|
-
data: 1,
|
|
1300
|
-
action: 1,
|
|
1301
|
-
},
|
|
1302
|
-
filter: {
|
|
1303
|
-
targetEntity: entity,
|
|
1304
|
-
entity: option.modiParentEntity,
|
|
1305
|
-
entityId: option.modiParentId,
|
|
1306
|
-
iState: 'active',
|
|
1307
|
-
filter: ids.length > 0 ? {
|
|
1308
|
-
id: {
|
|
1309
|
-
$in: ids,
|
|
1310
|
-
},
|
|
1311
|
-
} : filter,
|
|
1312
|
-
},
|
|
1313
|
-
sorter: [
|
|
1314
|
-
{
|
|
1315
|
-
$attr: {
|
|
1316
|
-
$$createAt$$: 1,
|
|
1317
|
-
},
|
|
1318
|
-
$direction: 'desc',
|
|
1319
|
-
}
|
|
1320
|
-
],
|
|
1321
|
-
indexFrom: 0,
|
|
1322
|
-
count: 1,
|
|
1323
|
-
}, context, option);
|
|
1324
|
-
if (upsertModis.length > 0) {
|
|
1325
|
-
const { data: originData, id: originId, action } = upsertModis[0];
|
|
1326
|
-
if (['create', 'update'].includes(action)) {
|
|
1327
|
-
modiUpsert = {
|
|
1328
|
-
id: 'dummy',
|
|
1329
|
-
action: 'update',
|
|
1330
|
-
data: {
|
|
1331
|
-
data: Object.assign({}, originData, data),
|
|
1332
|
-
},
|
|
1333
|
-
filter: {
|
|
1334
|
-
id: originId,
|
|
1335
|
-
}
|
|
1336
|
-
};
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
if (!modiUpsert) {
|
|
1341
|
-
modiUpsert = {
|
|
1342
|
-
id: 'dummy',
|
|
1343
|
-
action: 'create',
|
|
1344
|
-
data: {
|
|
1345
|
-
id: operId,
|
|
1346
|
-
targetEntity: entity,
|
|
1347
|
-
entity: option.modiParentEntity,
|
|
1348
|
-
entityId: option.modiParentId,
|
|
1349
|
-
action,
|
|
1350
|
-
data,
|
|
1351
|
-
iState: 'active',
|
|
1352
|
-
filter,
|
|
1353
|
-
},
|
|
1354
|
-
};
|
|
1355
|
-
if (ids.length > 0) {
|
|
1356
|
-
modiUpsert.data.modiEntity$modi = {
|
|
1357
|
-
id: 'dummy',
|
|
1358
|
-
action: 'create',
|
|
1359
|
-
data: await Promise.all(ids.map(async (id) => ({
|
|
1360
|
-
id: await (0, uuid_1.generateNewIdAsync)(),
|
|
1361
|
-
entity: entity,
|
|
1362
|
-
entityId: id,
|
|
1363
|
-
}))),
|
|
1364
|
-
};
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1397
|
+
const createModi = async () => {
|
|
1398
|
+
const modiOperation = await this.tryMergeModi(entity, operation, context, ids, option);
|
|
1367
1399
|
const closeRootMode = context.openRootMode();
|
|
1368
|
-
await this.cascadeUpdateAsync('modi',
|
|
1400
|
+
await this.cascadeUpdateAsync('modi', modiOperation, context, option);
|
|
1369
1401
|
closeRootMode();
|
|
1370
1402
|
return {
|
|
1371
1403
|
modi: {
|
|
1372
1404
|
['create']: 1,
|
|
1373
1405
|
},
|
|
1374
1406
|
};
|
|
1407
|
+
};
|
|
1408
|
+
if (option.modiParentEntity && !['modi', 'modiEntity'].includes(entity)) {
|
|
1409
|
+
// 延时更新,变成对modi的操作
|
|
1410
|
+
if (action === 'update' && Object.keys(data).length === 0) {
|
|
1411
|
+
return {};
|
|
1412
|
+
}
|
|
1413
|
+
return createModi();
|
|
1375
1414
|
}
|
|
1376
1415
|
else {
|
|
1377
|
-
const
|
|
1416
|
+
const saveRecordAndCreateOper = async () => {
|
|
1417
|
+
if (action === 'remove') {
|
|
1418
|
+
if (!option.dontCollect) {
|
|
1419
|
+
context.saveOpRecord(entity, {
|
|
1420
|
+
id: operId,
|
|
1421
|
+
action,
|
|
1422
|
+
data: data,
|
|
1423
|
+
filter: {
|
|
1424
|
+
id: {
|
|
1425
|
+
$in: ids,
|
|
1426
|
+
}
|
|
1427
|
+
},
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
else {
|
|
1432
|
+
const updateAttrCount = Object.keys(data).length;
|
|
1433
|
+
if (updateAttrCount > 0) {
|
|
1434
|
+
if (!option.dontCollect) {
|
|
1435
|
+
context.saveOpRecord(entity, {
|
|
1436
|
+
id: operId,
|
|
1437
|
+
action,
|
|
1438
|
+
data: data,
|
|
1439
|
+
filter: {
|
|
1440
|
+
id: {
|
|
1441
|
+
$in: ids,
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
else {
|
|
1448
|
+
return {};
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1378
1451
|
if (!option.dontCreateOper && !['oper', 'operEntity', 'modiEntity', 'modi', 'log'].includes(entity) && ids.length > 0) {
|
|
1379
1452
|
// 按照框架要求生成Oper和OperEntity这两个内置的对象
|
|
1380
1453
|
(0, assert_1.default)(operId);
|
|
@@ -1411,48 +1484,21 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1411
1484
|
});
|
|
1412
1485
|
closeRootMode();
|
|
1413
1486
|
}
|
|
1487
|
+
return {
|
|
1488
|
+
[entity]: {
|
|
1489
|
+
[action]: ids.length,
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1414
1492
|
};
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
id: operId,
|
|
1419
|
-
action,
|
|
1420
|
-
data: data,
|
|
1421
|
-
filter: {
|
|
1422
|
-
id: {
|
|
1423
|
-
$in: ids,
|
|
1424
|
-
}
|
|
1425
|
-
},
|
|
1426
|
-
});
|
|
1427
|
-
}
|
|
1493
|
+
const count = await this.updateAbjointRowAsync(entity, operation, context, option);
|
|
1494
|
+
if (count === ids.length) {
|
|
1495
|
+
return await saveRecordAndCreateOper();
|
|
1428
1496
|
}
|
|
1429
1497
|
else {
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
context.saveOpRecord(entity, {
|
|
1434
|
-
id: operId,
|
|
1435
|
-
action,
|
|
1436
|
-
data: data,
|
|
1437
|
-
filter: {
|
|
1438
|
-
id: {
|
|
1439
|
-
$in: ids,
|
|
1440
|
-
}
|
|
1441
|
-
},
|
|
1442
|
-
});
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
else {
|
|
1446
|
-
return {};
|
|
1447
|
-
}
|
|
1498
|
+
// 如果没有更新到行,说明这些数据还在modi当中
|
|
1499
|
+
(0, assert_1.default)(count === 0, 'update成功的行数只能为id所在行数或者0');
|
|
1500
|
+
return await createModi();
|
|
1448
1501
|
}
|
|
1449
|
-
await this.updateAbjointRowAsync(entity, operation, context, option);
|
|
1450
|
-
await createOper();
|
|
1451
|
-
return {
|
|
1452
|
-
[entity]: {
|
|
1453
|
-
[action]: ids.length,
|
|
1454
|
-
}
|
|
1455
|
-
};
|
|
1456
1502
|
}
|
|
1457
1503
|
}
|
|
1458
1504
|
}
|
|
@@ -352,12 +352,47 @@ class RelationAuth {
|
|
|
352
352
|
const dealWithData = (rows) => {
|
|
353
353
|
// 这里如果entity指向不同的实体,一般出现这样的查询,则其权限应当不由这条deduce路径处理
|
|
354
354
|
// 同上,如果找到的行数大于1行,说明deduce路径上的对象不确定,也暂不处理 by Xc 20230725
|
|
355
|
-
if (rows.length > 1
|
|
355
|
+
if (rows.length > 1) {
|
|
356
356
|
if (process.env.NODE_ENV === 'development') {
|
|
357
357
|
console.warn(`进行deduce推导时找到了${rows.length}行${entity}数据`);
|
|
358
358
|
}
|
|
359
359
|
return entityFilters;
|
|
360
360
|
}
|
|
361
|
+
else if (rows.length === 0) {
|
|
362
|
+
// 说明没有找到行,这时候有一种可能是modi。这时候只能假设是指定id更新了,其它情况很难处理。by Xc
|
|
363
|
+
if (filter.id) {
|
|
364
|
+
// 用modi对应的entity/entityId来判定
|
|
365
|
+
const modies = context.select('modi', {
|
|
366
|
+
data: {
|
|
367
|
+
id: 1,
|
|
368
|
+
data: 1,
|
|
369
|
+
entity: 1,
|
|
370
|
+
entityId: 1,
|
|
371
|
+
},
|
|
372
|
+
filter: {
|
|
373
|
+
filter,
|
|
374
|
+
}
|
|
375
|
+
}, {});
|
|
376
|
+
const getModiEntity = (modies) => {
|
|
377
|
+
if (modies[0]) {
|
|
378
|
+
const { entity, entityId } = modies[0];
|
|
379
|
+
entityFilters.push({
|
|
380
|
+
entity: entity,
|
|
381
|
+
filter: {
|
|
382
|
+
id: entityId,
|
|
383
|
+
},
|
|
384
|
+
actions: ['update'],
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return entityFilters;
|
|
388
|
+
};
|
|
389
|
+
if (modies instanceof Promise) {
|
|
390
|
+
return modies.then((modies2) => getModiEntity(modies2));
|
|
391
|
+
}
|
|
392
|
+
return getModiEntity(modies);
|
|
393
|
+
}
|
|
394
|
+
return entityFilters;
|
|
395
|
+
}
|
|
361
396
|
const { entity: deducedEntity, entityId: deducedEntityId } = rows[0];
|
|
362
397
|
if (!deducedEntity || !deducedEntityId) {
|
|
363
398
|
// 这种情况会出现在前台缓存里
|
|
@@ -801,6 +836,7 @@ class RelationAuth {
|
|
|
801
836
|
*/
|
|
802
837
|
findActionAuthsOnNode(node, context) {
|
|
803
838
|
const { entity, filter, action, userRelations } = node;
|
|
839
|
+
(0, assert_1.default)(filter);
|
|
804
840
|
const deducedEntityFilters2 = this.getDeducedEntityFilters(entity, filter, [action], context);
|
|
805
841
|
/**
|
|
806
842
|
* 搜索判定是否允许自建对象,自建的条件是 path = '',destEntity === entity
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fullModi = void 0;
|
|
4
|
+
exports.fullModi = {
|
|
5
|
+
id: 1,
|
|
6
|
+
targetEntity: 1,
|
|
7
|
+
entity: 1,
|
|
8
|
+
entityId: 1,
|
|
9
|
+
action: 1,
|
|
10
|
+
iState: 1,
|
|
11
|
+
data: 1,
|
|
12
|
+
filter: 1,
|
|
13
|
+
$$createAt$$: 1,
|
|
14
|
+
$$updateAt$$: 1,
|
|
15
|
+
};
|
package/lib/store/relation.js
CHANGED
|
@@ -65,6 +65,7 @@ export type AccessConfiguration = {
|
|
|
65
65
|
path?: string;
|
|
66
66
|
};
|
|
67
67
|
timeout?: number;
|
|
68
|
+
clockDriftDuration?: number;
|
|
68
69
|
};
|
|
69
70
|
/**
|
|
70
71
|
* 业务逻辑的通用配置
|
|
@@ -87,15 +88,3 @@ export type DependencyConfiguration = string[];
|
|
|
87
88
|
export type RenderConfiguration<ED extends BaseEntityDict & EntityDict> = {
|
|
88
89
|
styleDict: StyleDict<ED>;
|
|
89
90
|
};
|
|
90
|
-
/**
|
|
91
|
-
* 编译环境配置
|
|
92
|
-
*/
|
|
93
|
-
export type CompilerConfiguration = {
|
|
94
|
-
webpack?: {
|
|
95
|
-
resolve?: {
|
|
96
|
-
alias?: Record<string, string>;
|
|
97
|
-
fallback?: Record<string, string | false>;
|
|
98
|
-
};
|
|
99
|
-
extraOakModules?: (string | RegExp)[];
|
|
100
|
-
};
|
|
101
|
-
};
|
package/lib/types/Entity.d.ts
CHANGED
|
@@ -25,7 +25,6 @@ type FilterPart<A extends string, F extends Object | undefined> = {
|
|
|
25
25
|
export type SelectOption = {
|
|
26
26
|
dontCollect?: boolean;
|
|
27
27
|
blockTrigger?: true;
|
|
28
|
-
obscure?: boolean;
|
|
29
28
|
forUpdate?: true | 'skip locked' | 'nowait';
|
|
30
29
|
includedDeleted?: true;
|
|
31
30
|
ignoreAttrMiss?: true;
|
package/lib/types/Exception.d.ts
CHANGED
|
@@ -77,6 +77,9 @@ export declare class OakServerProxyException<ED extends EntityDict & BaseEntityD
|
|
|
77
77
|
}
|
|
78
78
|
export declare class OakClockDriftException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
79
79
|
}
|
|
80
|
+
export declare class OakSignatureVerificationException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
81
|
+
constructor(message?: string);
|
|
82
|
+
}
|
|
80
83
|
/**
|
|
81
84
|
* 数据不一致异常,系统认为现有的数据不允许相应的动作时抛此异常
|
|
82
85
|
*
|
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.OakSocketConnectException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakClockDriftException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = exports.OakRequestTimeoutException = exports.OakException = void 0;
|
|
3
|
+
exports.makeException = exports.OakSocketConnectException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakSignatureVerificationException = exports.OakClockDriftException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = exports.OakRequestTimeoutException = exports.OakException = void 0;
|
|
4
4
|
const relation_1 = require("../store/relation");
|
|
5
5
|
const lodash_1 = require("../utils/lodash");
|
|
6
6
|
class OakException extends Error {
|
|
@@ -188,6 +188,13 @@ exports.OakServerProxyException = OakServerProxyException;
|
|
|
188
188
|
class OakClockDriftException extends OakException {
|
|
189
189
|
}
|
|
190
190
|
exports.OakClockDriftException = OakClockDriftException;
|
|
191
|
+
// 验签失败
|
|
192
|
+
class OakSignatureVerificationException extends OakException {
|
|
193
|
+
constructor(message) {
|
|
194
|
+
super(message || '验签失败');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.OakSignatureVerificationException = OakSignatureVerificationException;
|
|
191
198
|
// 在系统更新数据时,以下三个异常应按规范依次抛出。
|
|
192
199
|
/**
|
|
193
200
|
* 数据不一致异常,系统认为现有的数据不允许相应的动作时抛此异常
|
|
@@ -510,6 +517,10 @@ function makeException(data) {
|
|
|
510
517
|
e = new OakRequestTimeoutException(data.message);
|
|
511
518
|
break;
|
|
512
519
|
}
|
|
520
|
+
case 'OakSignatureVerificationException': {
|
|
521
|
+
e = new OakSignatureVerificationException(data.message);
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
513
524
|
default:
|
|
514
525
|
return;
|
|
515
526
|
}
|
|
@@ -150,7 +150,7 @@ export declare function isStringExpression<A>(expression: any): expression is St
|
|
|
150
150
|
export declare function isAggrExpression<A>(expression: any): expression is AggrExpression<A>;
|
|
151
151
|
export declare function isExpression<A>(expression: any): expression is Expression<A>;
|
|
152
152
|
export declare function opMultipleParams(op: string): boolean;
|
|
153
|
-
export declare function execOp(op: string, params: any
|
|
153
|
+
export declare function execOp(op: string, params: any): ExpressionConstant;
|
|
154
154
|
/**
|
|
155
155
|
* 检查一个表达式,并分析其涉及到的属性
|
|
156
156
|
* @param expression
|
package/lib/types/Expression.js
CHANGED
|
@@ -136,10 +136,7 @@ function opMultipleParams(op) {
|
|
|
136
136
|
'$round', '$floor', '$ceil', '$$max', '$$min', '$$sum', '$$avg', '$$count'].includes(op);
|
|
137
137
|
}
|
|
138
138
|
exports.opMultipleParams = opMultipleParams;
|
|
139
|
-
function execOp(op, params
|
|
140
|
-
if (obscure && (params === undefined || params.includes(undefined))) {
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
139
|
+
function execOp(op, params) {
|
|
143
140
|
switch (op) {
|
|
144
141
|
case '$gt': {
|
|
145
142
|
return params[0] > params[1];
|
package/lib/types/Sync.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ export interface SyncRemoteConfig<ED extends EntityDict & BaseEntityDict, Cxt ex
|
|
|
77
77
|
reason: Error;
|
|
78
78
|
}, context: Cxt) => Promise<void>;
|
|
79
79
|
timeout?: number;
|
|
80
|
+
clockDriftDuration?: number;
|
|
80
81
|
}
|
|
81
82
|
export interface SyncSelfConfigBase<ED extends EntityDict & BaseEntityDict> {
|
|
82
83
|
endpoint?: string;
|
|
@@ -18,6 +18,7 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
18
18
|
private configuration;
|
|
19
19
|
private makeException;
|
|
20
20
|
private timeout;
|
|
21
|
+
private clockDriftDuration;
|
|
21
22
|
constructor(configuration: AccessConfiguration, makeException: (exceptionData: any) => OakException<ED>);
|
|
22
23
|
getCorsHeader(): string[];
|
|
23
24
|
protected makeHeadersAndBody(name: string, data: any, context?: FrontCxt): Promise<{
|
|
@@ -19,10 +19,12 @@ class SimpleConnector {
|
|
|
19
19
|
configuration;
|
|
20
20
|
makeException;
|
|
21
21
|
timeout;
|
|
22
|
+
clockDriftDuration;
|
|
22
23
|
constructor(configuration, makeException) {
|
|
23
24
|
this.configuration = configuration;
|
|
24
|
-
const { routerPrefixes, http, timeout } = configuration;
|
|
25
|
+
const { routerPrefixes, http, timeout, clockDriftDuration } = configuration;
|
|
25
26
|
this.timeout = timeout || 5000;
|
|
27
|
+
this.clockDriftDuration = clockDriftDuration || 10000;
|
|
26
28
|
const { ssl, hostname, port, path } = http;
|
|
27
29
|
const protocol = ssl ? 'https:' : 'http:';
|
|
28
30
|
let serverUrl = `${protocol}//${hostname}`;
|
|
@@ -77,7 +79,7 @@ class SimpleConnector {
|
|
|
77
79
|
async parseAspectResult(response) {
|
|
78
80
|
if (response.status > 299) {
|
|
79
81
|
const err = new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
|
|
80
|
-
throw err;
|
|
82
|
+
throw this.makeException(err);
|
|
81
83
|
}
|
|
82
84
|
const message = response.headers.get('oak-message');
|
|
83
85
|
const responseType = response.headers.get('Content-Type') ||
|
|
@@ -118,10 +120,14 @@ class SimpleConnector {
|
|
|
118
120
|
}
|
|
119
121
|
catch (err) {
|
|
120
122
|
// fetch返回异常一定是网络异常
|
|
123
|
+
let exception = err;
|
|
121
124
|
if (err instanceof types_1.OakRequestTimeoutException) {
|
|
122
|
-
|
|
125
|
+
exception = new types_1.OakNetworkException(`接口请求超时`);
|
|
123
126
|
}
|
|
124
|
-
|
|
127
|
+
else {
|
|
128
|
+
exception = new types_1.OakNetworkException(`接口请求时发生网络异常`);
|
|
129
|
+
}
|
|
130
|
+
throw this.makeException(exception);
|
|
125
131
|
}
|
|
126
132
|
return this.parseAspectResult(response);
|
|
127
133
|
}
|
|
@@ -143,14 +149,18 @@ class SimpleConnector {
|
|
|
143
149
|
response = await this.fetchWithTimeout(this.serverSubscribePointUrl, {}, this.timeout);
|
|
144
150
|
}
|
|
145
151
|
catch (err) {
|
|
152
|
+
let exception = err;
|
|
146
153
|
if (err instanceof types_1.OakRequestTimeoutException) {
|
|
147
|
-
|
|
154
|
+
exception = new types_1.OakNetworkException(`接口请求超时`);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
exception = new types_1.OakNetworkException(`接口请求时发生网络异常`);
|
|
148
158
|
}
|
|
149
|
-
throw
|
|
159
|
+
throw this.makeException(exception);
|
|
150
160
|
}
|
|
151
161
|
if (response.status > 299) {
|
|
152
162
|
const err = new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
|
|
153
|
-
throw err;
|
|
163
|
+
throw this.makeException(err);
|
|
154
164
|
}
|
|
155
165
|
const message = response.headers.get('oak-message');
|
|
156
166
|
const responseType = response.headers.get('Content-Type') ||
|
|
@@ -219,10 +229,6 @@ class SimpleConnector {
|
|
|
219
229
|
* @param headers
|
|
220
230
|
*/
|
|
221
231
|
makeBridgeUrl(url, headers) {
|
|
222
|
-
// if (process.env.PROD !== 'true') {
|
|
223
|
-
// console.warn('在development下无法通过bridge访问资源,将直接访问,可能失败', url);
|
|
224
|
-
// return url;
|
|
225
|
-
// }
|
|
226
232
|
const encodeUrl = encodeURIComponent(url);
|
|
227
233
|
return `${this.serverBridgeUrl}?url=${encodeUrl}`;
|
|
228
234
|
}
|
|
@@ -240,28 +246,29 @@ class SimpleConnector {
|
|
|
240
246
|
return {};
|
|
241
247
|
}
|
|
242
248
|
async fetchWithTimeout(url, options, timeout = 5000) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
-
//
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
//
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
249
|
+
return global.fetch(url, options);
|
|
250
|
+
// if (typeof AbortController === 'undefined' || timeout === 0) {
|
|
251
|
+
// return global.fetch(url, options);
|
|
252
|
+
// }
|
|
253
|
+
// const controller = new AbortController();
|
|
254
|
+
// const signal = controller.signal;
|
|
255
|
+
// // 设置超时
|
|
256
|
+
// const timeoutId = setTimeout(() => {
|
|
257
|
+
// controller.abort();
|
|
258
|
+
// }, timeout);
|
|
259
|
+
// // 发起 fetch 请求并传递 signal
|
|
260
|
+
// return global.fetch(url, Object.assign({}, options, { signal }))
|
|
261
|
+
// .then(response => {
|
|
262
|
+
// clearTimeout(timeoutId); // 如果请求成功,清除超时
|
|
263
|
+
// return response;
|
|
264
|
+
// })
|
|
265
|
+
// .catch(error => {
|
|
266
|
+
// clearTimeout(timeoutId); // 如果请求失败,清除超时
|
|
267
|
+
// if (error.name === 'AbortError') {
|
|
268
|
+
// throw new OakRequestTimeoutException();
|
|
269
|
+
// }
|
|
270
|
+
// throw error; // 其他错误
|
|
271
|
+
// });
|
|
265
272
|
}
|
|
266
273
|
}
|
|
267
274
|
exports.default = SimpleConnector;
|