oak-domain 5.1.32 → 5.1.33
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/Modi/Storage.js +1 -0
- package/lib/base-app-domain/Modi/_baseSchema.d.ts +1 -1
- package/lib/base-app-domain/Oper/Storage.js +1 -0
- package/lib/base-app-domain/Oper/_baseSchema.d.ts +1 -1
- package/lib/compiler/identifier.d.ts +9 -0
- package/lib/compiler/identifier.js +160 -0
- package/lib/compiler/schemalBuilder.d.ts +0 -1
- package/lib/compiler/schemalBuilder.js +144 -33
- package/lib/compiler/tscBuilder.d.ts +47 -0
- package/lib/compiler/tscBuilder.js +2823 -0
- package/lib/store/CascadeStore.d.ts +1 -1
- package/lib/store/CascadeStore.js +3 -1
- package/lib/store/IntrinsicCheckers.js +3 -1
- package/lib/store/RelationAuth.js +34 -8
- package/lib/store/TriggerExecutor.js +13 -0
- package/lib/store/checker.js +1 -0
- package/lib/store/diffSchema.d.ts +1 -0
- package/lib/store/diffSchema.js +2 -0
- package/lib/store/relation.d.ts +1 -1
- package/lib/types/Configuration.d.ts +1 -1
- package/lib/types/Connector.d.ts +17 -2
- package/lib/types/Demand.d.ts +1 -0
- package/lib/types/Exception.d.ts +20 -0
- package/lib/types/Exception.js +60 -1
- package/lib/types/Storage.d.ts +1 -0
- package/lib/types/Trigger.d.ts +647 -11
- package/lib/types/Trigger.js +34 -3
- package/lib/utils/SimpleConnector.d.ts +5 -5
- package/lib/utils/SimpleConnector.js +4 -2
- package/lib/utils/glob.d.ts +30 -0
- package/lib/utils/glob.js +286 -0
- package/lib/utils/url/whatwg-url/lib/urlencoded.d.ts +1 -1
- package/package.json +4 -3
|
@@ -76,7 +76,7 @@ export declare abstract class CascadeStore<ED extends EntityDict & BaseEntityDic
|
|
|
76
76
|
};
|
|
77
77
|
protected preProcessDataCreated<T extends keyof ED>(entity: T, data: ED[T]['Create']['data']): void;
|
|
78
78
|
protected preProcessDataUpdated(action: string, data: Record<string, any>, async?: true): void;
|
|
79
|
-
judgeRelation(entity: keyof ED, attr: string): string |
|
|
79
|
+
judgeRelation(entity: keyof ED, attr: string): string | 2 | 1 | string[] | 0 | -1;
|
|
80
80
|
private tryMergeModi;
|
|
81
81
|
/**
|
|
82
82
|
* 和具体的update过程无关的例程放在这里,包括对later动作的处理、对oper的记录以及对record的收集等
|
|
@@ -1311,6 +1311,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1311
1311
|
operatorId,
|
|
1312
1312
|
targetEntity: entity,
|
|
1313
1313
|
bornAt,
|
|
1314
|
+
iState: 'normal',
|
|
1314
1315
|
operEntity$oper: data instanceof Array ? [{
|
|
1315
1316
|
id: 'dummy',
|
|
1316
1317
|
action: 'create',
|
|
@@ -1450,6 +1451,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1450
1451
|
targetEntity: entity,
|
|
1451
1452
|
bornAt,
|
|
1452
1453
|
operatorId,
|
|
1454
|
+
iState: 'normal',
|
|
1453
1455
|
operEntity$oper: [{
|
|
1454
1456
|
id: 'dummy',
|
|
1455
1457
|
action: 'create',
|
|
@@ -1496,7 +1498,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1496
1498
|
}
|
|
1497
1499
|
else {
|
|
1498
1500
|
// 如果没有更新到行,说明这些数据还在modi当中
|
|
1499
|
-
(0, assert_1.default)(count === 0,
|
|
1501
|
+
(0, assert_1.default)(count === 0, `update成功的行数只能为id所在行数或者0,得到: ${count}, ids: ${ids.join(',')}`);
|
|
1500
1502
|
return await createModi();
|
|
1501
1503
|
}
|
|
1502
1504
|
}
|
|
@@ -286,7 +286,9 @@ function cascadelyCheckUpdateFilters(entity, schema, action, data, filter, matri
|
|
|
286
286
|
if (typeof f === 'function') {
|
|
287
287
|
const cf = f({ action, data, filter }, context);
|
|
288
288
|
if (cf instanceof Promise) {
|
|
289
|
-
return cf.then(
|
|
289
|
+
return cf.then(
|
|
290
|
+
// @oak-ignore
|
|
291
|
+
(cf2) => cf2 ? checkConditionalFilter(cf2) : true);
|
|
290
292
|
}
|
|
291
293
|
return cf ? checkConditionalFilter(cf) : true;
|
|
292
294
|
}
|
|
@@ -31,6 +31,7 @@ class RelationAuth {
|
|
|
31
31
|
if (context.isRoot()) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
+
// @oak-ignore 这里只有纯前台会跑到,一定是同步的
|
|
34
35
|
this.checkActions2(entity, operation, context);
|
|
35
36
|
}
|
|
36
37
|
// 后台检查filter是否满足relation约束
|
|
@@ -58,6 +59,7 @@ class RelationAuth {
|
|
|
58
59
|
/**
|
|
59
60
|
* 找到能创建此relation的所有父级relation,只要user和其中一个有关联即可以通过
|
|
60
61
|
*/
|
|
62
|
+
// @oak-ignore
|
|
61
63
|
const relationAuths = context.select('relationAuth', {
|
|
62
64
|
data: {
|
|
63
65
|
id: 1,
|
|
@@ -108,7 +110,9 @@ class RelationAuth {
|
|
|
108
110
|
return ele > 0;
|
|
109
111
|
}));
|
|
110
112
|
}
|
|
111
|
-
const result = relationAuths.map(
|
|
113
|
+
const result = relationAuths.map(
|
|
114
|
+
// @oak-ignore
|
|
115
|
+
ra => checkRelationAuth(ra));
|
|
112
116
|
return !!result.find(ele => ele > 0);
|
|
113
117
|
};
|
|
114
118
|
/**
|
|
@@ -127,6 +131,7 @@ class RelationAuth {
|
|
|
127
131
|
if (relevantIds.length > 0) {
|
|
128
132
|
return relevantIds;
|
|
129
133
|
}
|
|
134
|
+
// @oak-ignore
|
|
130
135
|
const relations = context.select('relation', {
|
|
131
136
|
data: {
|
|
132
137
|
id: 1,
|
|
@@ -170,6 +175,7 @@ class RelationAuth {
|
|
|
170
175
|
// 如果没有relationId(前端cache中),直接返回false
|
|
171
176
|
return false;
|
|
172
177
|
}
|
|
178
|
+
// @oak-ignore
|
|
173
179
|
const value = relationIds.map(ele => checkOnRelationId(entity2, ele, entityFilter));
|
|
174
180
|
if (intersection) {
|
|
175
181
|
return !(value.includes(false));
|
|
@@ -340,6 +346,7 @@ class RelationAuth {
|
|
|
340
346
|
* 这种情况一般发生在entity1 -> entity2上,此时entity2应该是一个固定id查询的filter
|
|
341
347
|
* 在这里先假设如果碰到了list类型的filter,直接不使用deduce路径上的对象来推导
|
|
342
348
|
*/
|
|
349
|
+
// @oak-ignore
|
|
343
350
|
const rows2 = context.select(entity, {
|
|
344
351
|
data: {
|
|
345
352
|
id: 1,
|
|
@@ -363,6 +370,7 @@ class RelationAuth {
|
|
|
363
370
|
// 说明没有找到行,这时候有一种可能是modi。这时候只能假设是指定id更新了,其它情况很难处理。by Xc
|
|
364
371
|
if (filter.id) {
|
|
365
372
|
// 用modi对应的entity/entityId来判定
|
|
373
|
+
// @oak-ignore
|
|
366
374
|
const modies = context.select('modi', {
|
|
367
375
|
data: {
|
|
368
376
|
id: 1,
|
|
@@ -820,7 +828,9 @@ class RelationAuth {
|
|
|
820
828
|
(0, assert_1.default)(context instanceof AsyncRowStore_1.AsyncContext);
|
|
821
829
|
return actionAuths.then((aas) => Promise.all(dlSelections.map((ele) => Promise.all(ele.map((ele2) => this.checkActionAuthInGroup(ele2.entity, ele2.filter, aas, context))))).then((result) => checkResult(result)));
|
|
822
830
|
}
|
|
823
|
-
return checkResult(dlSelections.map(ele => ele.map(
|
|
831
|
+
return checkResult(dlSelections.map(ele => ele.map(
|
|
832
|
+
// @oak-ignore
|
|
833
|
+
ele2 => this.checkActionAuthInGroup(ele2.entity, ele2.filter, actionAuths, context))));
|
|
824
834
|
};
|
|
825
835
|
if (deducedLeafSelections[0] instanceof Promise) {
|
|
826
836
|
return Promise.all(deducedLeafSelections)
|
|
@@ -859,11 +869,14 @@ class RelationAuth {
|
|
|
859
869
|
const result = [];
|
|
860
870
|
if (specialEntities.length > 0) {
|
|
861
871
|
// 对于deduce出来的special对象,直接判定create应该问题不大,否则写起来太烦琐(具体情况遇到了再调试)
|
|
862
|
-
result.push(...specialEntities.map(
|
|
872
|
+
result.push(...specialEntities.map(
|
|
873
|
+
// @oak-ignore
|
|
874
|
+
ele => this.checkOperateSpecialEntities2(ele.entity, ele.entity === entity ? node.action : 'create', ele.filter, context)));
|
|
863
875
|
}
|
|
864
876
|
if (unspecicalEntities.length > 0) {
|
|
865
877
|
const allEntities = unspecicalEntities.map(ele => ele.entity);
|
|
866
878
|
const allActions = (0, lodash_1.uniq)(unspecicalEntities.map(ele => ele.actions).flat());
|
|
879
|
+
// @oak-ignore
|
|
867
880
|
const actionAuths2 = context.select('actionAuth', {
|
|
868
881
|
data: {
|
|
869
882
|
id: 1,
|
|
@@ -937,10 +950,14 @@ class RelationAuth {
|
|
|
937
950
|
return result.includes(true);
|
|
938
951
|
};
|
|
939
952
|
if (actionAuths2 instanceof Promise) {
|
|
940
|
-
result.push(actionAuths2.then(
|
|
953
|
+
result.push(actionAuths2.then(
|
|
954
|
+
// @oak-ignore
|
|
955
|
+
(ars2) => checkActionAuths(ars2)));
|
|
941
956
|
}
|
|
942
957
|
else {
|
|
943
|
-
result.push(
|
|
958
|
+
result.push(
|
|
959
|
+
// @oak-ignore
|
|
960
|
+
checkActionAuths(actionAuths2));
|
|
944
961
|
}
|
|
945
962
|
}
|
|
946
963
|
if (result.find(ele => ele instanceof Promise)) {
|
|
@@ -987,6 +1004,7 @@ class RelationAuth {
|
|
|
987
1004
|
const childLegalAuths = legalPaths.map((ele) => {
|
|
988
1005
|
const { path: { value: pv }, relationId } = ele;
|
|
989
1006
|
const pv2 = pv ? `${pathToParent}.${pv}` : pathToParent;
|
|
1007
|
+
// @oak-ignore
|
|
990
1008
|
return context.select('actionAuth', {
|
|
991
1009
|
data: {
|
|
992
1010
|
id: 1,
|
|
@@ -1006,13 +1024,18 @@ class RelationAuth {
|
|
|
1006
1024
|
}, { dontCollect: true });
|
|
1007
1025
|
});
|
|
1008
1026
|
if (childLegalAuths[0] instanceof Promise) {
|
|
1009
|
-
return Promise.all(childLegalAuths).then((clas) => child.map(
|
|
1027
|
+
return Promise.all(childLegalAuths).then((clas) => child.map(
|
|
1028
|
+
// @oak-ignore
|
|
1029
|
+
(c) => checkNode(c, clas.flat())));
|
|
1010
1030
|
}
|
|
1011
|
-
return child.map(
|
|
1031
|
+
return child.map(
|
|
1032
|
+
// @oak-ignore
|
|
1033
|
+
(c) => checkNode(c, childLegalAuths.flat()));
|
|
1012
1034
|
}
|
|
1013
1035
|
const childLegalAuths = legalPaths.map((ele) => {
|
|
1014
1036
|
const { path: { value: pv }, relationId } = ele;
|
|
1015
1037
|
const pv2 = pv ? `${pathToParent}.${pv}` : pathToParent;
|
|
1038
|
+
// @oak-ignore
|
|
1016
1039
|
return context.select('actionAuth', {
|
|
1017
1040
|
data: {
|
|
1018
1041
|
id: 1,
|
|
@@ -1032,8 +1055,11 @@ class RelationAuth {
|
|
|
1032
1055
|
}, { dontCollect: true });
|
|
1033
1056
|
}).flat();
|
|
1034
1057
|
if (childLegalAuths[0] instanceof Promise) {
|
|
1035
|
-
return Promise.all(childLegalAuths).then(
|
|
1058
|
+
return Promise.all(childLegalAuths).then(
|
|
1059
|
+
// @oak-ignore
|
|
1060
|
+
(clas) => checkNode(child, clas.flat()));
|
|
1036
1061
|
}
|
|
1062
|
+
// @oak-ignore
|
|
1037
1063
|
return checkNode(child, childLegalAuths);
|
|
1038
1064
|
}).flat();
|
|
1039
1065
|
if (childResult[0] instanceof Promise) {
|
|
@@ -104,6 +104,17 @@ class TriggerExecutor {
|
|
|
104
104
|
|| trigger.action instanceof Array && !trigger.action.includes('create'), `trigger【${trigger.name}】是create类型但却带有filter`);
|
|
105
105
|
(0, assert_1.default)(trigger.when === 'before' || trigger.when === 'commit', `定义了filter的trigger【${trigger.name}】的when只能是before或者commit`);
|
|
106
106
|
}
|
|
107
|
+
if (Array.isArray(trigger.action)) {
|
|
108
|
+
const actions = trigger.action;
|
|
109
|
+
const seen = new Set();
|
|
110
|
+
const duplicate = actions.find(item => {
|
|
111
|
+
if (seen.has(item))
|
|
112
|
+
return true;
|
|
113
|
+
seen.add(item);
|
|
114
|
+
return false;
|
|
115
|
+
});
|
|
116
|
+
(0, assert_1.default)(!duplicate, `注册 trigger 「${trigger.name}」 时发现定义中出现了重复定义的action: 「${duplicate}」`);
|
|
117
|
+
}
|
|
107
118
|
Object.assign(this.triggerNameMap, {
|
|
108
119
|
[trigger.name]: trigger,
|
|
109
120
|
});
|
|
@@ -293,6 +304,7 @@ class TriggerExecutor {
|
|
|
293
304
|
const { filter } = trigger;
|
|
294
305
|
const filterr = typeof filter === 'function' ? filter(operation, context, option) : filter;
|
|
295
306
|
(0, assert_1.default)(!(filterr instanceof Promise));
|
|
307
|
+
// @oak-ignore
|
|
296
308
|
const filterRepelled = (0, filter_1.checkFilterRepel)(entity, context, filterr, operation.filter);
|
|
297
309
|
if (filterRepelled) {
|
|
298
310
|
continue;
|
|
@@ -365,6 +377,7 @@ class TriggerExecutor {
|
|
|
365
377
|
await this.preCommitTrigger(entity, operation, trigger, context, option);
|
|
366
378
|
return execCommitTrigger(idx + 1);
|
|
367
379
|
};
|
|
380
|
+
// @oak-ignore
|
|
368
381
|
return execPreTrigger(0)
|
|
369
382
|
.then(() => execCommitTrigger(0));
|
|
370
383
|
}
|
package/lib/store/checker.js
CHANGED
|
@@ -161,6 +161,7 @@ function translateCheckerInSyncContext(checker, schema) {
|
|
|
161
161
|
}
|
|
162
162
|
(0, assert_1.default)(!(filter2 instanceof Promise));
|
|
163
163
|
(0, assert_1.default)(operationFilter2, '定义了row类型的checker但却进行了无filter操作');
|
|
164
|
+
// @oak-ignore
|
|
164
165
|
if ((0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter2, true)) {
|
|
165
166
|
return;
|
|
166
167
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/store/relation.d.ts
CHANGED
|
@@ -9,4 +9,4 @@ import { StorageSchema } from "../types/Storage";
|
|
|
9
9
|
* @param row
|
|
10
10
|
* @returns
|
|
11
11
|
*/
|
|
12
|
-
export declare function judgeRelation<ED extends EntityDict & BaseEntityDict>(schema: StorageSchema<ED>, entity: keyof ED, attr: string, allowUnrecognized?: boolean): string |
|
|
12
|
+
export declare function judgeRelation<ED extends EntityDict & BaseEntityDict>(schema: StorageSchema<ED>, entity: keyof ED, attr: string, allowUnrecognized?: boolean): string | 2 | 1 | string[] | 0 | -1;
|
package/lib/types/Connector.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { SyncContext } from "../store/SyncRowStore";
|
|
|
3
3
|
import { EntityDict, OpRecord } from "./Entity";
|
|
4
4
|
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
5
5
|
import { OakException } from "./Exception";
|
|
6
|
+
type Promisable<T> = T | Promise<T>;
|
|
6
7
|
export interface Connector<ED extends EntityDict & BaseEntityDict, FrontCxt extends SyncContext<ED>> {
|
|
7
8
|
callAspect: (name: string, params: any, context?: FrontCxt) => Promise<{
|
|
8
9
|
result: any;
|
|
@@ -10,11 +11,11 @@ export interface Connector<ED extends EntityDict & BaseEntityDict, FrontCxt exte
|
|
|
10
11
|
message?: string | null;
|
|
11
12
|
}>;
|
|
12
13
|
getRouter: () => string;
|
|
13
|
-
parseRequest: (headers: IncomingHttpHeaders, body?: any, files?: any) => {
|
|
14
|
+
parseRequest: (headers: IncomingHttpHeaders, body?: any, files?: any) => Promisable<{
|
|
14
15
|
contextString?: string;
|
|
15
16
|
aspectName: string;
|
|
16
17
|
data?: any;
|
|
17
|
-
}
|
|
18
|
+
}>;
|
|
18
19
|
serializeResult: (result: any, opRecords: OpRecord<ED>[], headers: IncomingHttpHeaders, body: any, message?: string) => Promise<{
|
|
19
20
|
body: any;
|
|
20
21
|
headers?: Record<string, any>;
|
|
@@ -43,4 +44,18 @@ export interface Connector<ED extends EntityDict & BaseEntityDict, FrontCxt exte
|
|
|
43
44
|
[T in keyof ED]?: ED[T]['OpSchema'][];
|
|
44
45
|
}>;
|
|
45
46
|
getCorsHeader: () => string[];
|
|
47
|
+
getCorsExposeHeaders?: () => string[];
|
|
48
|
+
registerCustomAspect?: () => {
|
|
49
|
+
name: string;
|
|
50
|
+
handler: (params: {
|
|
51
|
+
headers?: IncomingHttpHeaders;
|
|
52
|
+
contextString?: string;
|
|
53
|
+
params?: any;
|
|
54
|
+
}) => Promise<{
|
|
55
|
+
result: any;
|
|
56
|
+
opRecords?: OpRecord<ED>[];
|
|
57
|
+
message?: string;
|
|
58
|
+
}>;
|
|
59
|
+
}[];
|
|
46
60
|
}
|
|
61
|
+
export {};
|
package/lib/types/Demand.d.ts
CHANGED
package/lib/types/Exception.d.ts
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { StorageSchema } from ".";
|
|
2
2
|
import { EntityDict, OpRecord } from "./Entity";
|
|
3
3
|
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
4
|
+
declare const OAK_EXCEPTION_SYMBOL: unique symbol;
|
|
5
|
+
/**
|
|
6
|
+
* 判断一个对象是否为 OakException 实例,作用和 `instanceof` 类似,但更安全可靠。
|
|
7
|
+
* 如OakUserException继承自OakException,使用时可传入OakUserException以进一步确认类型。
|
|
8
|
+
* @param obj 需要判断的对象
|
|
9
|
+
* @param exceptionName 可选参数,指定异常类名以进一步确认
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* if (isOakException(e, OakUserException)) {
|
|
13
|
+
* // 这里的 e 已被类型缩小为 OakUserException
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @returns 如果对象是 OakException 实例则返回 true,否则返回 false
|
|
18
|
+
*/
|
|
19
|
+
export declare function isOakException<T extends OakException<any>>(obj: any, errType?: new () => T): obj is T;
|
|
4
20
|
export declare class OakException<ED extends EntityDict & BaseEntityDict> extends Error {
|
|
5
21
|
opRecords: OpRecord<ED>[];
|
|
6
22
|
_module?: string;
|
|
7
23
|
params?: Record<string, any>;
|
|
24
|
+
[OAK_EXCEPTION_SYMBOL]: boolean;
|
|
8
25
|
constructor(message?: string, _module?: string, params?: Record<string, any>);
|
|
9
26
|
addData<T extends keyof ED>(entity: T, rows: Partial<ED[T]['Schema']>[], schema: StorageSchema<ED>): void;
|
|
10
27
|
setOpRecords(opRecords: OpRecord<ED>[]): void;
|
|
@@ -81,6 +98,8 @@ export declare class OakServerProxyException<ED extends EntityDict & BaseEntityD
|
|
|
81
98
|
}
|
|
82
99
|
export declare class OakClockDriftException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
83
100
|
}
|
|
101
|
+
export declare class OakInsecureRequestException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
102
|
+
}
|
|
84
103
|
export declare class OakSignatureVerificationException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
85
104
|
constructor(message?: string, _module?: string, params?: Record<string, any>);
|
|
86
105
|
}
|
|
@@ -200,3 +219,4 @@ export declare function makeException<ED extends EntityDict & BaseEntityDict>(da
|
|
|
200
219
|
opRecords: OpRecord<ED>[];
|
|
201
220
|
[A: string]: any;
|
|
202
221
|
}): OakException<ED> | undefined;
|
|
222
|
+
export {};
|
package/lib/types/Exception.js
CHANGED
|
@@ -1,13 +1,64 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OakApplicationHasToUpgrade = exports.OakSocketConnectException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakDataInvisibleException = exports.OakOperationUnpermittedException = 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;
|
|
3
|
+
exports.OakApplicationHasToUpgrade = exports.OakSocketConnectException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakDataInvisibleException = exports.OakOperationUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakSignatureVerificationException = exports.OakInsecureRequestException = 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
|
+
exports.isOakException = isOakException;
|
|
4
5
|
exports.makeException = makeException;
|
|
5
6
|
const relation_1 = require("../store/relation");
|
|
6
7
|
const lodash_1 = require("../utils/lodash");
|
|
8
|
+
const OAK_EXCEPTION_SYMBOL = Symbol.for('oak-domain:exception');
|
|
9
|
+
/**
|
|
10
|
+
* 判断一个对象是否为 OakException 实例,作用和 `instanceof` 类似,但更安全可靠。
|
|
11
|
+
* 如OakUserException继承自OakException,使用时可传入OakUserException以进一步确认类型。
|
|
12
|
+
* @param obj 需要判断的对象
|
|
13
|
+
* @param exceptionName 可选参数,指定异常类名以进一步确认
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* if (isOakException(e, OakUserException)) {
|
|
17
|
+
* // 这里的 e 已被类型缩小为 OakUserException
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @returns 如果对象是 OakException 实例则返回 true,否则返回 false
|
|
22
|
+
*/
|
|
23
|
+
function isOakException(obj, errType) {
|
|
24
|
+
if (!obj) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const isOakException = !!obj[OAK_EXCEPTION_SYMBOL];
|
|
28
|
+
if (isOakException) {
|
|
29
|
+
if (!errType) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
let proto = Object.getPrototypeOf(obj);
|
|
38
|
+
const expectedName = errType.name;
|
|
39
|
+
let depth = 0;
|
|
40
|
+
const maxDepth = 10; // 防止无限循环
|
|
41
|
+
while (proto && depth < maxDepth) {
|
|
42
|
+
const constructorName = proto.constructor?.name;
|
|
43
|
+
if (constructorName === expectedName) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
proto = Object.getPrototypeOf(proto);
|
|
47
|
+
depth++;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
console.warn(e);
|
|
53
|
+
// 如果检查过程出错,安全返回 false
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
7
57
|
class OakException extends Error {
|
|
8
58
|
opRecords;
|
|
9
59
|
_module;
|
|
10
60
|
params;
|
|
61
|
+
[OAK_EXCEPTION_SYMBOL] = true;
|
|
11
62
|
constructor(message, _module, params) {
|
|
12
63
|
super(message);
|
|
13
64
|
this._module = _module;
|
|
@@ -200,6 +251,10 @@ exports.OakServerProxyException = OakServerProxyException;
|
|
|
200
251
|
class OakClockDriftException extends OakException {
|
|
201
252
|
}
|
|
202
253
|
exports.OakClockDriftException = OakClockDriftException;
|
|
254
|
+
// 非安全的请求(未加密)
|
|
255
|
+
class OakInsecureRequestException extends OakException {
|
|
256
|
+
}
|
|
257
|
+
exports.OakInsecureRequestException = OakInsecureRequestException;
|
|
203
258
|
// 验签失败
|
|
204
259
|
class OakSignatureVerificationException extends OakException {
|
|
205
260
|
constructor(message, _module, params) {
|
|
@@ -528,6 +583,10 @@ function makeException(data) {
|
|
|
528
583
|
e = new OakClockDriftException(message, _module, params);
|
|
529
584
|
break;
|
|
530
585
|
}
|
|
586
|
+
case 'OakInsecureRequestException': {
|
|
587
|
+
e = new OakInsecureRequestException(message, _module, params);
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
531
590
|
case 'OakServerProxyException': {
|
|
532
591
|
e = new OakServerProxyException(message, _module, params);
|
|
533
592
|
break;
|
package/lib/types/Storage.d.ts
CHANGED