oak-domain 5.1.0 → 5.1.2
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/ActionDefDict.d.ts +1 -3
- package/lib/base-app-domain/Log/Action.d.ts +1 -7
- package/lib/base-app-domain/Log/Action.js +2 -11
- package/lib/base-app-domain/Log/Schema.d.ts +4 -4
- package/lib/base-app-domain/Log/Storage.js +1 -0
- package/lib/base-app-domain/Log/Style.js +0 -6
- package/lib/entities/Log.d.ts +2 -7
- package/lib/entities/Log.js +1 -14
- package/lib/store/AsyncRowStore.js +6 -0
- package/lib/store/CascadeStore.d.ts +1 -1
- package/lib/store/CascadeStore.js +55 -46
- package/lib/store/RelationAuth.js +9 -0
- package/lib/store/relation.d.ts +1 -1
- package/lib/store/relation.js +4 -4
- package/lib/store/triggers.js +35 -21
- package/lib/types/Auth.d.ts +1 -1
- package/lib/types/Connector.d.ts +3 -1
- package/lib/types/Entity.d.ts +3 -0
- package/lib/types/Exception.d.ts +6 -0
- package/lib/types/Exception.js +15 -1
- package/lib/types/Sync.d.ts +13 -1
- package/lib/types/Trigger.js +1 -0
- package/lib/utils/SimpleConnector.d.ts +3 -2
- package/package.json +1 -1
- package/src/entities/Log.ts +2 -18
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { ActionDef } from "../../types/Action";
|
|
2
1
|
import { GenericAction } from "../../actions/action";
|
|
3
|
-
export type IState = 'normal' | 'rollbacked' | string;
|
|
4
|
-
export type State = IState | string;
|
|
5
2
|
export type IAction = 'undo' | 'redo' | string;
|
|
6
3
|
export type ParticularAction = IAction;
|
|
7
4
|
export declare const actions: string[];
|
|
8
|
-
export declare const IActionDef: ActionDef<IAction, IState>;
|
|
9
5
|
export type Action = GenericAction | ParticularAction | string;
|
|
10
|
-
export declare const actionDefDict: {
|
|
11
|
-
iState: ActionDef<string, string>;
|
|
12
|
-
};
|
|
6
|
+
export declare const actionDefDict: {};
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.actionDefDict = exports.
|
|
3
|
+
exports.actionDefDict = exports.actions = void 0;
|
|
4
4
|
exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "undo", "redo"];
|
|
5
|
-
exports.
|
|
6
|
-
stm: {
|
|
7
|
-
undo: ['normal', 'rollbacked'],
|
|
8
|
-
redo: ['rollbacked', 'normal'],
|
|
9
|
-
},
|
|
10
|
-
is: 'normal',
|
|
11
|
-
};
|
|
12
|
-
exports.actionDefDict = {
|
|
13
|
-
iState: exports.IActionDef
|
|
14
|
-
};
|
|
5
|
+
exports.actionDefDict = {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Q_DateValue, Q_NumberValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey, SubQueryPredicateMetadata } from "../../types/Demand";
|
|
2
2
|
import { OneOf } from "../../types/Polyfill";
|
|
3
3
|
import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, AggregationResult, EntityShape } from "../../types/Entity";
|
|
4
|
-
import { Action, ParticularAction
|
|
4
|
+
import { Action, ParticularAction } from "./Action";
|
|
5
5
|
import { String } from "../../types/DataType";
|
|
6
6
|
import * as Oper from "../Oper/Schema";
|
|
7
7
|
import * as ModiEntity from "../ModiEntity/Schema";
|
|
@@ -9,13 +9,13 @@ import * as OperEntity from "../OperEntity/Schema";
|
|
|
9
9
|
export type OpSchema = EntityShape & {
|
|
10
10
|
entity: String<32>;
|
|
11
11
|
entityId: String<64>;
|
|
12
|
-
iState
|
|
12
|
+
iState: "normal" | "rollbacked";
|
|
13
13
|
};
|
|
14
14
|
export type OpAttr = keyof OpSchema;
|
|
15
15
|
export type Schema = EntityShape & {
|
|
16
16
|
entity: String<32>;
|
|
17
17
|
entityId: String<64>;
|
|
18
|
-
iState
|
|
18
|
+
iState: "normal" | "rollbacked";
|
|
19
19
|
oper$log?: Array<Oper.Schema>;
|
|
20
20
|
oper$log$$aggr?: AggregationResult<Oper.Schema>;
|
|
21
21
|
modiEntity$entity?: Array<ModiEntity.Schema>;
|
|
@@ -32,7 +32,7 @@ type AttrFilter = {
|
|
|
32
32
|
$$updateAt$$: Q_DateValue;
|
|
33
33
|
entity: Q_StringValue;
|
|
34
34
|
entityId: Q_StringValue;
|
|
35
|
-
iState: Q_EnumValue<
|
|
35
|
+
iState: Q_EnumValue<"normal" | "rollbacked">;
|
|
36
36
|
oper$log: Oper.Filter & SubQueryPredicateMetadata;
|
|
37
37
|
modiEntity$entity: ModiEntity.Filter & SubQueryPredicateMetadata;
|
|
38
38
|
operEntity$entity: OperEntity.Filter & SubQueryPredicateMetadata;
|
package/lib/entities/Log.d.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import { ActionDef } from '../types/Action';
|
|
2
1
|
import { String } from '../types/DataType';
|
|
3
2
|
import { EntityShape } from '../types/Entity';
|
|
4
3
|
import { EntityDesc } from '../types/EntityDesc';
|
|
5
4
|
export interface Schema extends EntityShape {
|
|
6
5
|
entity: String<32>;
|
|
7
6
|
entityId: String<64>;
|
|
7
|
+
iState: 'normal' | 'rollbacked';
|
|
8
8
|
}
|
|
9
|
-
export type IState = 'normal' | 'rollbacked';
|
|
10
|
-
export type State = IState;
|
|
11
9
|
export type IAction = 'undo' | 'redo';
|
|
12
10
|
export type Action = IAction;
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const entityDesc: EntityDesc<Schema, Action, '', {
|
|
15
|
-
iState: IState;
|
|
16
|
-
}>;
|
|
11
|
+
export declare const entityDesc: EntityDesc<Schema, Action>;
|
package/lib/entities/Log.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.entityDesc =
|
|
3
|
+
exports.entityDesc = void 0;
|
|
4
4
|
;
|
|
5
|
-
exports.IActionDef = {
|
|
6
|
-
stm: {
|
|
7
|
-
undo: ['normal', 'rollbacked'],
|
|
8
|
-
redo: ['rollbacked', 'normal'],
|
|
9
|
-
},
|
|
10
|
-
is: 'normal',
|
|
11
|
-
};
|
|
12
5
|
exports.entityDesc = {
|
|
13
6
|
locales: {
|
|
14
7
|
zh_CN: {
|
|
@@ -35,11 +28,5 @@ exports.entityDesc = {
|
|
|
35
28
|
undo: '',
|
|
36
29
|
redo: '',
|
|
37
30
|
},
|
|
38
|
-
color: {
|
|
39
|
-
iState: {
|
|
40
|
-
normal: '#229954',
|
|
41
|
-
rollbacked: '#2C3E50',
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
31
|
},
|
|
45
32
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AsyncContext = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const types_1 = require("../types");
|
|
5
6
|
const action_1 = require("../actions/action");
|
|
6
7
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
7
8
|
const filter_1 = require("./filter");
|
|
@@ -81,9 +82,14 @@ class AsyncContext {
|
|
|
81
82
|
break;
|
|
82
83
|
}
|
|
83
84
|
case 'remove': {
|
|
85
|
+
const deleteAt = data[types_1.DeleteAtAttribute];
|
|
86
|
+
(0, assert_1.default)(deleteAt);
|
|
84
87
|
this.opRecords.push({
|
|
85
88
|
id,
|
|
86
89
|
a: 'r',
|
|
90
|
+
d: {
|
|
91
|
+
[types_1.DeleteAtAttribute]: deleteAt,
|
|
92
|
+
},
|
|
87
93
|
e: entity,
|
|
88
94
|
f: filter,
|
|
89
95
|
});
|
|
@@ -67,7 +67,7 @@ export declare abstract class CascadeStore<ED extends EntityDict & BaseEntityDic
|
|
|
67
67
|
afterFns: (() => R)[];
|
|
68
68
|
};
|
|
69
69
|
protected preProcessDataCreated<T extends keyof ED>(entity: T, data: ED[T]['Create']['data']): void;
|
|
70
|
-
protected preProcessDataUpdated(data: Record<string, any
|
|
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
72
|
/**
|
|
73
73
|
* 和具体的update过程无关的例程放在这里,包括对later动作的处理、对oper的记录以及对record的收集等
|
|
@@ -23,7 +23,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
23
23
|
operationRewriters = [];
|
|
24
24
|
async reinforceSelectionAsync(entity, selection, context, option, isAggr) {
|
|
25
25
|
if (!isAggr && !selection.distinct) {
|
|
26
|
-
this.reinforceSelectionInner(entity, selection, context);
|
|
26
|
+
this.reinforceSelectionInner(entity, selection, context, option);
|
|
27
27
|
}
|
|
28
28
|
const rewriterPromises = this.selectionRewriters.map(ele => ele(this.getSchema(), entity, selection, context, option, isAggr));
|
|
29
29
|
if (rewriterPromises.length > 0) {
|
|
@@ -32,14 +32,14 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
32
32
|
}
|
|
33
33
|
reinforceSelectionSync(entity, selection, context, option, isAggr) {
|
|
34
34
|
if (!isAggr && !selection.distinct) {
|
|
35
|
-
this.reinforceSelectionInner(entity, selection, context);
|
|
35
|
+
this.reinforceSelectionInner(entity, selection, context, option);
|
|
36
36
|
}
|
|
37
37
|
this.selectionRewriters.forEach(ele => {
|
|
38
38
|
const result = ele(this.getSchema(), entity, selection, context, option, isAggr);
|
|
39
39
|
(0, assert_1.default)(!(result instanceof Promise));
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
-
reinforceSelectionInner(entity, selection, context) {
|
|
42
|
+
reinforceSelectionInner(entity, selection, context, option) {
|
|
43
43
|
const { filter, data, sorter } = selection;
|
|
44
44
|
const assignNecessaryProjectionAttrs = (projectionNode, attrs) => {
|
|
45
45
|
attrs.forEach((attr) => {
|
|
@@ -240,7 +240,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
240
240
|
else {
|
|
241
241
|
assignNecessaryProjectionAttrs(data, ['entity', 'entityId']);
|
|
242
242
|
}
|
|
243
|
-
this.reinforceSelectionInner(rel[0], projectionNode[attr], context);
|
|
243
|
+
this.reinforceSelectionInner(rel[0], projectionNode[attr], context, option);
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
}
|
|
@@ -272,7 +272,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
272
272
|
// 如果对象上有relation关系,在此将本用户相关的relation和actionAuth全部取出
|
|
273
273
|
// 还要将actionAuth上没有relation关系但destEntity为本对象的行也全部取出,这些是指向userId的可能路径
|
|
274
274
|
// 放在这里有点怪异,暂先这样
|
|
275
|
-
if (context instanceof AsyncRowStore_1.AsyncContext) {
|
|
275
|
+
if (context instanceof AsyncRowStore_1.AsyncContext && !option.dontCollect) {
|
|
276
276
|
const userId = context.getCurrentUserId(true);
|
|
277
277
|
if (userId && !entities_1.SYSTEM_RESERVE_ENTITIES.includes(entity2)) {
|
|
278
278
|
if (this.getSchema()[entity2].relation && !projectionNode.userRelation$entity) {
|
|
@@ -289,7 +289,11 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
289
289
|
id: 1,
|
|
290
290
|
name: 1,
|
|
291
291
|
display: 1,
|
|
292
|
-
|
|
292
|
+
[Entity_1.CreateAtAttribute]: 1,
|
|
293
|
+
[Entity_1.UpdateAtAttribute]: 1,
|
|
294
|
+
},
|
|
295
|
+
[Entity_1.CreateAtAttribute]: 1,
|
|
296
|
+
[Entity_1.UpdateAtAttribute]: 1,
|
|
293
297
|
},
|
|
294
298
|
filter: {
|
|
295
299
|
userId,
|
|
@@ -331,10 +335,12 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
331
335
|
const cascadeSelectionFns = [];
|
|
332
336
|
const supportMtoJoin = this.supportManyToOneJoin();
|
|
333
337
|
const { toModi } = this.getSchema()[entity];
|
|
338
|
+
const projection = {};
|
|
334
339
|
(0, assert_1.default)(typeof projection2 === 'object');
|
|
335
340
|
for (const attr in projection2) {
|
|
336
341
|
const relation = (0, relation_1.judgeRelation)(this.storageSchema, entity, attr);
|
|
337
342
|
if (relation === 1 || relation == 0) {
|
|
343
|
+
projection[attr] = projection2[attr];
|
|
338
344
|
}
|
|
339
345
|
else if (relation === 2) {
|
|
340
346
|
// 基于entity/entityId的多对一
|
|
@@ -364,6 +370,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
364
370
|
subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => {
|
|
365
371
|
return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2));
|
|
366
372
|
}));
|
|
373
|
+
projection[attr] = subProjection;
|
|
367
374
|
}
|
|
368
375
|
else {
|
|
369
376
|
cascadeSelectionFns.push((result) => {
|
|
@@ -451,6 +458,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
451
458
|
subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => {
|
|
452
459
|
return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2));
|
|
453
460
|
}));
|
|
461
|
+
projection[attr] = subProjection;
|
|
454
462
|
}
|
|
455
463
|
else {
|
|
456
464
|
cascadeSelectionFns.push((result) => {
|
|
@@ -640,7 +648,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
640
648
|
}
|
|
641
649
|
}
|
|
642
650
|
return {
|
|
643
|
-
projection
|
|
651
|
+
projection,
|
|
644
652
|
cascadeSelectionFns,
|
|
645
653
|
};
|
|
646
654
|
}
|
|
@@ -698,7 +706,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
698
706
|
option2.modiParentEntity = entity;
|
|
699
707
|
}
|
|
700
708
|
}
|
|
701
|
-
if (toLog && action !== 'create') {
|
|
709
|
+
if (toLog && action !== 'create' && !option.dontCreateOper) {
|
|
702
710
|
// 此对象(及其下辖的cascade更新都需要记录log)
|
|
703
711
|
(0, assert_1.default)(typeof filter.id === 'string');
|
|
704
712
|
(0, assert_1.default)(!option2.logId, 'undo无法支持嵌套');
|
|
@@ -710,6 +718,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
710
718
|
id: (0, uuid_1.generateNewId)(),
|
|
711
719
|
data: {
|
|
712
720
|
id: logId,
|
|
721
|
+
iState: 'normal',
|
|
713
722
|
},
|
|
714
723
|
action: 'create',
|
|
715
724
|
}
|
|
@@ -1012,8 +1021,8 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1012
1021
|
}
|
|
1013
1022
|
}
|
|
1014
1023
|
Object.assign(data2, {
|
|
1015
|
-
[Entity_1.CreateAtAttribute]: now,
|
|
1016
|
-
[Entity_1.UpdateAtAttribute]: now,
|
|
1024
|
+
[Entity_1.CreateAtAttribute]: data2[Entity_1.CreateAtAttribute] || now,
|
|
1025
|
+
[Entity_1.UpdateAtAttribute]: data2[Entity_1.UpdateAtAttribute] || now,
|
|
1017
1026
|
[Entity_1.DeleteAtAttribute]: null,
|
|
1018
1027
|
});
|
|
1019
1028
|
};
|
|
@@ -1025,9 +1034,18 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1025
1034
|
}
|
|
1026
1035
|
}
|
|
1027
1036
|
// 对更新的数据,去掉所有的undefined属性
|
|
1028
|
-
preProcessDataUpdated(data) {
|
|
1037
|
+
preProcessDataUpdated(action, data, async) {
|
|
1029
1038
|
const undefinedKeys = Object.keys(data).filter(ele => data[ele] === undefined);
|
|
1030
1039
|
undefinedKeys.forEach(ele => (0, lodash_1.unset)(data, ele));
|
|
1040
|
+
// 优化一下,如果不更新任何属性,则不实际执行
|
|
1041
|
+
const now = Date.now();
|
|
1042
|
+
// 后台应该还是以实际操作时间为准,前台以传入的updateAt来界定操作的产生“时间”,这里可用来避免同一次更新被算做多次
|
|
1043
|
+
if ((Object.keys(data).length > 0 || action !== 'update') && (!data[Entity_1.UpdateAtAttribute] || async)) {
|
|
1044
|
+
data[Entity_1.UpdateAtAttribute] = now;
|
|
1045
|
+
}
|
|
1046
|
+
if (action === 'remove' && (!data[Entity_1.DeleteAtAttribute] || async)) {
|
|
1047
|
+
data[Entity_1.DeleteAtAttribute] = now;
|
|
1048
|
+
}
|
|
1031
1049
|
}
|
|
1032
1050
|
judgeRelation(entity, attr) {
|
|
1033
1051
|
return (0, relation_1.judgeRelation)(this.storageSchema, entity, attr);
|
|
@@ -1212,7 +1230,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1212
1230
|
};
|
|
1213
1231
|
const closeRootMode = context.openRootMode();
|
|
1214
1232
|
await this.cascadeUpdateAsync('oper', createOper, context, {
|
|
1215
|
-
dontCollect:
|
|
1233
|
+
dontCollect: !option.logId, // 如果是在创建log,则把oper收集回去
|
|
1216
1234
|
});
|
|
1217
1235
|
closeRootMode();
|
|
1218
1236
|
}
|
|
@@ -1256,8 +1274,12 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1256
1274
|
});
|
|
1257
1275
|
});
|
|
1258
1276
|
}
|
|
1277
|
+
if (ids.length === 0) {
|
|
1278
|
+
// 如果没有行需要更新/删除,直接返回
|
|
1279
|
+
return {};
|
|
1280
|
+
}
|
|
1259
1281
|
if (data) {
|
|
1260
|
-
this.preProcessDataUpdated(data);
|
|
1282
|
+
this.preProcessDataUpdated(action, data, true);
|
|
1261
1283
|
}
|
|
1262
1284
|
if (option.modiParentEntity && !['modi', 'modiEntity'].includes(entity)) {
|
|
1263
1285
|
// 延时更新,变成对modi的插入
|
|
@@ -1270,16 +1292,15 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1270
1292
|
if (updateAttrCount === 0) {
|
|
1271
1293
|
return {};
|
|
1272
1294
|
}
|
|
1295
|
+
// 尝试和当前targetEntity的最后一条create/update进行合并,优化modi的条数
|
|
1273
1296
|
const upsertModis = await this.selectAbjointRowAsync('modi', {
|
|
1274
1297
|
data: {
|
|
1275
1298
|
id: 1,
|
|
1276
1299
|
data: 1,
|
|
1300
|
+
action: 1,
|
|
1277
1301
|
},
|
|
1278
1302
|
filter: {
|
|
1279
1303
|
targetEntity: entity,
|
|
1280
|
-
action: {
|
|
1281
|
-
$in: ['create', 'update'],
|
|
1282
|
-
},
|
|
1283
1304
|
entity: option.modiParentEntity,
|
|
1284
1305
|
entityId: option.modiParentId,
|
|
1285
1306
|
iState: 'active',
|
|
@@ -1301,17 +1322,19 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1301
1322
|
count: 1,
|
|
1302
1323
|
}, context, option);
|
|
1303
1324
|
if (upsertModis.length > 0) {
|
|
1304
|
-
const { data: originData, id: originId } = upsertModis[0];
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
data:
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
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
|
+
}
|
|
1315
1338
|
}
|
|
1316
1339
|
}
|
|
1317
1340
|
if (!modiUpsert) {
|
|
@@ -1384,7 +1407,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1384
1407
|
};
|
|
1385
1408
|
const closeRootMode = context.openRootMode();
|
|
1386
1409
|
await this.cascadeUpdateAsync('oper', createOper, context, {
|
|
1387
|
-
dontCollect:
|
|
1410
|
+
dontCollect: !option.logId, // 如果是在创建log,则把oper收集回去
|
|
1388
1411
|
});
|
|
1389
1412
|
closeRootMode();
|
|
1390
1413
|
}
|
|
@@ -1394,22 +1417,18 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1394
1417
|
context.saveOpRecord(entity, {
|
|
1395
1418
|
id: operId,
|
|
1396
1419
|
action,
|
|
1397
|
-
data:
|
|
1420
|
+
data: data,
|
|
1398
1421
|
filter: {
|
|
1399
1422
|
id: {
|
|
1400
1423
|
$in: ids,
|
|
1401
1424
|
}
|
|
1402
|
-
}
|
|
1425
|
+
},
|
|
1403
1426
|
});
|
|
1404
1427
|
}
|
|
1405
1428
|
}
|
|
1406
1429
|
else {
|
|
1407
1430
|
const updateAttrCount = Object.keys(data).length;
|
|
1408
1431
|
if (updateAttrCount > 0) {
|
|
1409
|
-
// 优化一下,如果不更新任何属性,则不实际执行
|
|
1410
|
-
Object.assign(data, {
|
|
1411
|
-
[Entity_1.UpdateAtAttribute]: now,
|
|
1412
|
-
});
|
|
1413
1432
|
if (!option.dontCollect) {
|
|
1414
1433
|
context.saveOpRecord(entity, {
|
|
1415
1434
|
id: operId,
|
|
@@ -1423,11 +1442,6 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1423
1442
|
});
|
|
1424
1443
|
}
|
|
1425
1444
|
}
|
|
1426
|
-
else if (action !== 'update') {
|
|
1427
|
-
// 如果不是update动作而是用户自定义的动作,这里还是要记录oper
|
|
1428
|
-
await createOper();
|
|
1429
|
-
return {};
|
|
1430
|
-
}
|
|
1431
1445
|
else {
|
|
1432
1446
|
return {};
|
|
1433
1447
|
}
|
|
@@ -1483,15 +1497,10 @@ class CascadeStore extends RowStore_1.RowStore {
|
|
|
1483
1497
|
if (action === 'remove') {
|
|
1484
1498
|
}
|
|
1485
1499
|
else {
|
|
1500
|
+
this.preProcessDataUpdated(action, data);
|
|
1486
1501
|
const updateAttrCount = Object.keys(data).length;
|
|
1487
|
-
if (updateAttrCount
|
|
1502
|
+
if (updateAttrCount == 0) {
|
|
1488
1503
|
// 优化一下,如果不更新任何属性,则不实际执行
|
|
1489
|
-
Object.assign(data, {
|
|
1490
|
-
$$updateAt$$: now,
|
|
1491
|
-
});
|
|
1492
|
-
this.preProcessDataUpdated(data);
|
|
1493
|
-
}
|
|
1494
|
-
else {
|
|
1495
1504
|
return 0;
|
|
1496
1505
|
}
|
|
1497
1506
|
}
|
|
@@ -60,6 +60,7 @@ class RelationAuth {
|
|
|
60
60
|
const relationAuths = context.select('relationAuth', {
|
|
61
61
|
data: {
|
|
62
62
|
id: 1,
|
|
63
|
+
pathId: 1,
|
|
63
64
|
path: {
|
|
64
65
|
id: 1,
|
|
65
66
|
sourceEntity: 1,
|
|
@@ -732,6 +733,7 @@ class RelationAuth {
|
|
|
732
733
|
const actionAuths = context.select('actionAuth', {
|
|
733
734
|
data: {
|
|
734
735
|
id: 1,
|
|
736
|
+
pathId: 1,
|
|
735
737
|
path: {
|
|
736
738
|
id: 1,
|
|
737
739
|
value: 1,
|
|
@@ -830,15 +832,21 @@ class RelationAuth {
|
|
|
830
832
|
value: 1,
|
|
831
833
|
recursive: 1,
|
|
832
834
|
},
|
|
835
|
+
pathId: 1,
|
|
833
836
|
deActions: 1,
|
|
837
|
+
relationId: 1,
|
|
834
838
|
relation: {
|
|
835
839
|
id: 1,
|
|
840
|
+
entity: 1,
|
|
841
|
+
entityId: 1,
|
|
836
842
|
userRelation$relation: {
|
|
837
843
|
$entity: 'userRelation',
|
|
838
844
|
data: {
|
|
839
845
|
id: 1,
|
|
840
846
|
entity: 1,
|
|
841
847
|
entityId: 1,
|
|
848
|
+
userId: 1,
|
|
849
|
+
relationId: 1,
|
|
842
850
|
},
|
|
843
851
|
filter: {
|
|
844
852
|
userId: context.getCurrentUserId(),
|
|
@@ -1123,6 +1131,7 @@ async function getUserRelationsByActions(params, context) {
|
|
|
1123
1131
|
const actionAuths = await context.select('actionAuth', {
|
|
1124
1132
|
data: {
|
|
1125
1133
|
id: 1,
|
|
1134
|
+
pathId: 1,
|
|
1126
1135
|
path: {
|
|
1127
1136
|
id: 1,
|
|
1128
1137
|
value: 1,
|
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,
|
|
12
|
+
export declare function judgeRelation<ED extends EntityDict & BaseEntityDict>(schema: StorageSchema<ED>, entity: keyof ED, attr: string, allowUnrecognized?: boolean): string | 1 | 2 | string[] | 0 | -1;
|
package/lib/store/relation.js
CHANGED
|
@@ -13,7 +13,7 @@ const Entity_1 = require("../types/Entity");
|
|
|
13
13
|
* @param row
|
|
14
14
|
* @returns
|
|
15
15
|
*/
|
|
16
|
-
function judgeRelation(schema, entity, attr,
|
|
16
|
+
function judgeRelation(schema, entity, attr, allowUnrecognized) {
|
|
17
17
|
const { [entity]: { attributes } } = schema;
|
|
18
18
|
if (attr.startsWith(Demand_1.EXPRESSION_PREFIX) || attr.startsWith('#')) {
|
|
19
19
|
// 表达式属性或者metadata
|
|
@@ -27,8 +27,8 @@ function judgeRelation(schema, entity, attr, allowUnrecoganized) {
|
|
|
27
27
|
const firstDelimiter = attr.indexOf('$');
|
|
28
28
|
const entity2 = attr.slice(0, firstDelimiter);
|
|
29
29
|
(0, assert_1.default)(schema.hasOwnProperty(entity2));
|
|
30
|
-
const
|
|
31
|
-
const foreignKey = attr.slice(firstDelimiter + 1,
|
|
30
|
+
const secondDelimiter = attr.indexOf('$', firstDelimiter + 1);
|
|
31
|
+
const foreignKey = attr.slice(firstDelimiter + 1, secondDelimiter > 0 ? secondDelimiter : attr.length);
|
|
32
32
|
const { [entity2]: { attributes: attributes2 } } = schema;
|
|
33
33
|
if (foreignKey === 'entity') {
|
|
34
34
|
// 基于反指对象的反向关联
|
|
@@ -63,7 +63,7 @@ function judgeRelation(schema, entity, attr, allowUnrecoganized) {
|
|
|
63
63
|
if (Entity_1.initinctiveAttributes.includes(attr)) {
|
|
64
64
|
return 1;
|
|
65
65
|
}
|
|
66
|
-
else if (
|
|
66
|
+
else if (allowUnrecognized) {
|
|
67
67
|
return -1;
|
|
68
68
|
}
|
|
69
69
|
else {
|
package/lib/store/triggers.js
CHANGED
|
@@ -46,7 +46,6 @@ async function undoLog(log, context) {
|
|
|
46
46
|
filter: filter,
|
|
47
47
|
}, {
|
|
48
48
|
blockTrigger: true,
|
|
49
|
-
dontCollect: true,
|
|
50
49
|
dontCreateOper: true,
|
|
51
50
|
});
|
|
52
51
|
break;
|
|
@@ -61,7 +60,6 @@ async function undoLog(log, context) {
|
|
|
61
60
|
data: undoData[id],
|
|
62
61
|
}, {
|
|
63
62
|
blockTrigger: true,
|
|
64
|
-
dontCollect: true,
|
|
65
63
|
dontCreateOper: true,
|
|
66
64
|
});
|
|
67
65
|
}
|
|
@@ -81,7 +79,6 @@ async function undoLog(log, context) {
|
|
|
81
79
|
}
|
|
82
80
|
}, {
|
|
83
81
|
blockTrigger: true,
|
|
84
|
-
dontCollect: true,
|
|
85
82
|
dontCreateOper: true,
|
|
86
83
|
});
|
|
87
84
|
}
|
|
@@ -89,20 +86,24 @@ async function undoLog(log, context) {
|
|
|
89
86
|
}
|
|
90
87
|
}
|
|
91
88
|
}
|
|
92
|
-
await context.operate('
|
|
89
|
+
await context.operate('log', {
|
|
93
90
|
id: 'dummy',
|
|
94
91
|
action: 'undo',
|
|
95
92
|
data: {
|
|
96
93
|
iState: 'rollbacked',
|
|
94
|
+
oper$log: {
|
|
95
|
+
id: 'dummy',
|
|
96
|
+
action: 'undo',
|
|
97
|
+
data: {
|
|
98
|
+
iState: 'rollbacked',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
97
101
|
},
|
|
98
102
|
filter: {
|
|
99
|
-
id:
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
+
id: log.id,
|
|
104
|
+
},
|
|
103
105
|
}, {
|
|
104
106
|
blockTrigger: true,
|
|
105
|
-
dontCollect: true,
|
|
106
107
|
dontCreateOper: true,
|
|
107
108
|
});
|
|
108
109
|
}
|
|
@@ -124,7 +125,6 @@ async function redoLog(log, context) {
|
|
|
124
125
|
data: data,
|
|
125
126
|
}, {
|
|
126
127
|
blockTrigger: true,
|
|
127
|
-
dontCollect: true,
|
|
128
128
|
dontCreateOper: true,
|
|
129
129
|
});
|
|
130
130
|
break;
|
|
@@ -137,7 +137,6 @@ async function redoLog(log, context) {
|
|
|
137
137
|
filter: filter,
|
|
138
138
|
}, {
|
|
139
139
|
blockTrigger: true,
|
|
140
|
-
dontCollect: true,
|
|
141
140
|
dontCreateOper: true,
|
|
142
141
|
});
|
|
143
142
|
break;
|
|
@@ -150,27 +149,30 @@ async function redoLog(log, context) {
|
|
|
150
149
|
filter: filter,
|
|
151
150
|
}, {
|
|
152
151
|
blockTrigger: true,
|
|
153
|
-
dontCollect: true,
|
|
154
152
|
dontCreateOper: true,
|
|
155
153
|
});
|
|
156
154
|
break;
|
|
157
155
|
}
|
|
158
156
|
}
|
|
159
157
|
}
|
|
160
|
-
await context.operate('
|
|
158
|
+
await context.operate('log', {
|
|
161
159
|
id: 'dummy',
|
|
162
160
|
action: 'redo',
|
|
163
161
|
data: {
|
|
164
162
|
iState: 'normal',
|
|
163
|
+
oper$log: {
|
|
164
|
+
id: 'dummy',
|
|
165
|
+
action: 'redo',
|
|
166
|
+
data: {
|
|
167
|
+
iState: 'normal',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
165
170
|
},
|
|
166
171
|
filter: {
|
|
167
|
-
id:
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
}
|
|
172
|
+
id: log.id,
|
|
173
|
+
},
|
|
171
174
|
}, {
|
|
172
175
|
blockTrigger: true,
|
|
173
|
-
dontCollect: true,
|
|
174
176
|
dontCreateOper: true,
|
|
175
177
|
});
|
|
176
178
|
}
|
|
@@ -201,11 +203,12 @@ exports.logTriggers = [
|
|
|
201
203
|
},
|
|
202
204
|
entity: 1,
|
|
203
205
|
entityId: 1,
|
|
206
|
+
[types_1.SeqAttribute]: 1,
|
|
204
207
|
},
|
|
205
208
|
filter: {
|
|
206
209
|
id: ids[0],
|
|
207
210
|
},
|
|
208
|
-
}, {});
|
|
211
|
+
}, { dontCollect: true });
|
|
209
212
|
const logs = await context.select('log', {
|
|
210
213
|
data: {
|
|
211
214
|
id: 1,
|
|
@@ -217,8 +220,13 @@ exports.logTriggers = [
|
|
|
217
220
|
action: 1,
|
|
218
221
|
targetEntity: 1,
|
|
219
222
|
filter: 1,
|
|
223
|
+
iState: 1,
|
|
220
224
|
},
|
|
221
225
|
},
|
|
226
|
+
iState: 1,
|
|
227
|
+
entity: 1,
|
|
228
|
+
entityId: 1,
|
|
229
|
+
[types_1.SeqAttribute]: 1,
|
|
222
230
|
},
|
|
223
231
|
filter: {
|
|
224
232
|
iState: 'normal',
|
|
@@ -271,11 +279,12 @@ exports.logTriggers = [
|
|
|
271
279
|
iState: 1,
|
|
272
280
|
entity: 1,
|
|
273
281
|
entityId: 1,
|
|
282
|
+
[types_1.SeqAttribute]: 1,
|
|
274
283
|
},
|
|
275
284
|
filter: {
|
|
276
285
|
id: ids[0],
|
|
277
286
|
},
|
|
278
|
-
}, {});
|
|
287
|
+
}, { dontCollect: true });
|
|
279
288
|
const logs = await context.select('log', {
|
|
280
289
|
data: {
|
|
281
290
|
id: 1,
|
|
@@ -287,8 +296,13 @@ exports.logTriggers = [
|
|
|
287
296
|
action: 1,
|
|
288
297
|
targetEntity: 1,
|
|
289
298
|
filter: 1,
|
|
299
|
+
iState: 1,
|
|
290
300
|
},
|
|
291
301
|
},
|
|
302
|
+
iState: 1,
|
|
303
|
+
entity: 1,
|
|
304
|
+
entityId: 1,
|
|
305
|
+
[types_1.SeqAttribute]: 1,
|
|
292
306
|
},
|
|
293
307
|
filter: {
|
|
294
308
|
iState: 'rollbacked',
|
|
@@ -345,7 +359,7 @@ exports.logTriggers = [
|
|
|
345
359
|
iState: 'rollbacked',
|
|
346
360
|
},
|
|
347
361
|
}, {});
|
|
348
|
-
return (result.oper
|
|
362
|
+
return (result.oper?.remove || 0) + (result2.log?.remove || 0);
|
|
349
363
|
}
|
|
350
364
|
}
|
|
351
365
|
];
|
package/lib/types/Auth.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { SyncContext } from "../store/SyncRowStore";
|
|
|
4
4
|
import { EntityDict, OperateOption, SelectOption } from "../types/Entity";
|
|
5
5
|
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
6
6
|
import { ModiTurn } from './Trigger';
|
|
7
|
-
export type CheckerType = 'row' | 'data' | 'logical' | 'logicalData';
|
|
7
|
+
export type CheckerType = 'row' | 'data' | 'logical' | 'logicalData' | 'relation';
|
|
8
8
|
/**
|
|
9
9
|
* conditionalFilter是指该action发生时,operation所操作的行中有满足conditionalFilter的行
|
|
10
10
|
* 被转化成trigger的filter条件,详细可看trigger中的说明
|
package/lib/types/Connector.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ export interface Connector<ED extends EntityDict & BaseEntityDict, FrontCxt exte
|
|
|
21
21
|
headers?: Record<string, any>;
|
|
22
22
|
}>;
|
|
23
23
|
serializeException: (exception: OakException<ED>, headers: IncomingHttpHeaders, body: any) => {
|
|
24
|
-
body:
|
|
24
|
+
body: {
|
|
25
|
+
exception: string;
|
|
26
|
+
};
|
|
25
27
|
headers?: Record<string, any>;
|
|
26
28
|
};
|
|
27
29
|
getSubscribeRouter: () => string;
|
package/lib/types/Entity.d.ts
CHANGED
|
@@ -162,6 +162,9 @@ export type UpdateOpResult<ED extends EntityDict, T extends keyof ED> = {
|
|
|
162
162
|
export type RemoveOpResult<ED extends EntityDict, T extends keyof ED> = {
|
|
163
163
|
id: string;
|
|
164
164
|
a: 'r';
|
|
165
|
+
d: {
|
|
166
|
+
[DeleteAtAttribute]: number;
|
|
167
|
+
};
|
|
165
168
|
e: T;
|
|
166
169
|
f?: Filter;
|
|
167
170
|
};
|
package/lib/types/Exception.d.ts
CHANGED
|
@@ -169,6 +169,12 @@ export declare class OakExternalException<ED extends EntityDict & BaseEntityDict
|
|
|
169
169
|
constructor(source: string, code?: string, message?: string, data?: any);
|
|
170
170
|
toString(): string;
|
|
171
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* socket连接异常
|
|
174
|
+
*/
|
|
175
|
+
export declare class OakSocketConnectException<ED extends EntityDict & BaseEntityDict> extends OakUserException<ED> {
|
|
176
|
+
constructor(message?: string);
|
|
177
|
+
}
|
|
172
178
|
export declare function makeException<ED extends EntityDict & BaseEntityDict>(data: {
|
|
173
179
|
name: string;
|
|
174
180
|
message?: string;
|
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.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = 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.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = 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 {
|
|
@@ -385,6 +385,16 @@ class OakExternalException extends OakUserException {
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
exports.OakExternalException = OakExternalException;
|
|
388
|
+
/**
|
|
389
|
+
* socket连接异常
|
|
390
|
+
*/
|
|
391
|
+
class OakSocketConnectException extends OakUserException {
|
|
392
|
+
constructor(message) {
|
|
393
|
+
super(message || '连接出现问题,请尝试刷新页面');
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
exports.OakSocketConnectException = OakSocketConnectException;
|
|
397
|
+
;
|
|
388
398
|
function makeException(data) {
|
|
389
399
|
const { name } = data;
|
|
390
400
|
let e = undefined;
|
|
@@ -473,6 +483,10 @@ function makeException(data) {
|
|
|
473
483
|
e = new OakServerProxyException(data.message);
|
|
474
484
|
break;
|
|
475
485
|
}
|
|
486
|
+
case 'OakSocketConnectException': {
|
|
487
|
+
e = new OakSocketConnectException(data.message);
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
476
490
|
default:
|
|
477
491
|
return;
|
|
478
492
|
}
|
package/lib/types/Sync.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export interface SyncRemoteConfigBase<ED extends EntityDict & BaseEntityDict, Cx
|
|
|
51
51
|
pushEntities?: Array<PushEntityDef<ED, keyof ED, Cxt>>;
|
|
52
52
|
pullEntities?: Array<PullEntityDef<ED, keyof ED, Cxt>>;
|
|
53
53
|
}
|
|
54
|
-
interface SyncRemoteConfig<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends SyncRemoteConfigBase<ED, Cxt> {
|
|
54
|
+
export interface SyncRemoteConfig<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends SyncRemoteConfigBase<ED, Cxt> {
|
|
55
55
|
getPushInfo: (context: Cxt, option: {
|
|
56
56
|
remoteEntityId: string;
|
|
57
57
|
userId: string;
|
|
@@ -60,6 +60,18 @@ interface SyncRemoteConfig<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
|
|
60
60
|
selfId: string;
|
|
61
61
|
remoteEntityId: string;
|
|
62
62
|
}) => Promise<RemotePullInfo>;
|
|
63
|
+
/**
|
|
64
|
+
* 同步失败回调
|
|
65
|
+
*/
|
|
66
|
+
onFailed?: (result: {
|
|
67
|
+
data: {
|
|
68
|
+
entity: keyof ED;
|
|
69
|
+
action: ED[keyof ED]['Action'];
|
|
70
|
+
data: ED[keyof ED]['Operation']['data'];
|
|
71
|
+
rowIds: string[];
|
|
72
|
+
}[];
|
|
73
|
+
reason: Error;
|
|
74
|
+
}, context: Cxt) => Promise<void>;
|
|
63
75
|
}
|
|
64
76
|
export interface SyncSelfConfigBase<ED extends EntityDict & BaseEntityDict> {
|
|
65
77
|
endpoint?: string;
|
package/lib/types/Trigger.js
CHANGED
|
@@ -60,8 +60,9 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
60
60
|
headers?: Record<string, any> | undefined;
|
|
61
61
|
}>;
|
|
62
62
|
serializeException(exception: OakException<ED>, headers: IncomingHttpHeaders, body: any): {
|
|
63
|
-
body:
|
|
64
|
-
|
|
63
|
+
body: {
|
|
64
|
+
exception: string;
|
|
65
|
+
};
|
|
65
66
|
};
|
|
66
67
|
getBridgeRouter(): string;
|
|
67
68
|
/**
|
package/package.json
CHANGED
package/src/entities/Log.ts
CHANGED
|
@@ -6,24 +6,14 @@ import { EntityDesc } from '../types/EntityDesc';
|
|
|
6
6
|
export interface Schema extends EntityShape {
|
|
7
7
|
entity: String<32>; // 关联的目标对象
|
|
8
8
|
entityId: String<64>; // 关联的目标对象id
|
|
9
|
+
iState: 'normal' | 'rollbacked';
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
export type IState = 'normal' | 'rollbacked';
|
|
12
|
-
export type State = IState;
|
|
13
12
|
export type IAction = 'undo' | 'redo';
|
|
14
13
|
export type Action = IAction;
|
|
15
|
-
export const IActionDef: ActionDef<IAction, IState> = {
|
|
16
|
-
stm: {
|
|
17
|
-
undo: ['normal', 'rollbacked'],
|
|
18
|
-
redo: ['rollbacked', 'normal'],
|
|
19
|
-
},
|
|
20
|
-
is: 'normal',
|
|
21
|
-
};
|
|
22
14
|
|
|
23
15
|
|
|
24
|
-
export const entityDesc: EntityDesc<Schema, Action
|
|
25
|
-
iState: IState,
|
|
26
|
-
}> = {
|
|
16
|
+
export const entityDesc: EntityDesc<Schema, Action> = {
|
|
27
17
|
locales: {
|
|
28
18
|
zh_CN: {
|
|
29
19
|
name: '日志',
|
|
@@ -49,11 +39,5 @@ export const entityDesc: EntityDesc<Schema, Action, '', {
|
|
|
49
39
|
undo: '',
|
|
50
40
|
redo: '',
|
|
51
41
|
},
|
|
52
|
-
color: {
|
|
53
|
-
iState: {
|
|
54
|
-
normal: '#229954',
|
|
55
|
-
rollbacked: '#2C3E50',
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
42
|
},
|
|
59
43
|
};
|