oak-domain 2.2.0 → 2.3.0
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/Schema.d.ts +10 -23
- package/lib/base-app-domain/ModiEntity/Schema.d.ts +4 -16
- package/lib/base-app-domain/Oper/Schema.d.ts +6 -18
- package/lib/base-app-domain/OperEntity/Schema.d.ts +4 -17
- package/lib/base-app-domain/User/Schema.d.ts +14 -21
- package/lib/checkers/index.d.ts +2 -2
- package/lib/checkers/index.js +6 -1
- package/lib/compiler/schemalBuilder.js +145 -31
- package/lib/store/AsyncRowStore.d.ts +3 -1
- package/lib/store/AsyncRowStore.js +3 -0
- package/lib/store/CascadeStore.d.ts +4 -2
- package/lib/store/CascadeStore.js +136 -62
- package/lib/store/SyncRowStore.d.ts +3 -1
- package/lib/store/SyncRowStore.js +3 -0
- package/lib/store/TriggerExecutor.js +43 -5
- package/lib/store/checker.d.ts +2 -1
- package/lib/store/checker.js +158 -23
- package/lib/store/filter.d.ts +1 -0
- package/lib/store/filter.js +49 -26
- package/lib/store/relation.js +4 -2
- package/lib/store/selection.js +2 -2
- package/lib/types/Auth.d.ts +11 -2
- package/lib/types/Entity.d.ts +32 -1
- package/lib/types/Expression.js +19 -4
- package/lib/types/Storage.d.ts +4 -3
- package/lib/types/Timer.d.ts +1 -2
- package/lib/types/Trigger.d.ts +12 -0
- package/lib/utils/SimpleConnector.js +15 -0
- package/lib/utils/cron.d.ts +1 -0
- package/lib/utils/cron.js +18 -0
- package/lib/utils/lodash.d.ts +16 -1
- package/lib/utils/lodash.js +48 -31
- package/lib/utils/uuid.js +18 -6
- package/package.json +2 -2
package/lib/store/filter.d.ts
CHANGED
|
@@ -97,3 +97,4 @@ export declare function makeTreeAncestorFilter<ED extends EntityDict, T extends
|
|
|
97
97
|
*/
|
|
98
98
|
export declare function makeTreeDescendantFilter<ED extends EntityDict, T extends keyof ED>(entity: T, parentKey: string, filter: ED[T]['Selection']['filter'], level?: number, includeAll?: boolean, includeSelf?: boolean): ED[T]['Selection']['filter'];
|
|
99
99
|
export declare function checkFilterContains<ED extends EntityDict, T extends keyof ED, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, context: Cxt, contained: ED[T]['Selection']['filter'], filter?: ED[T]['Selection']['filter']): boolean | Promise<boolean>;
|
|
100
|
+
export declare function checkFilterRepel<ED extends EntityDict, T extends keyof ED, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, context: Cxt, filter1: ED[T]['Selection']['filter'], filter2: ED[T]['Selection']['filter']): boolean | Promise<boolean>;
|
package/lib/store/filter.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkFilterContains = exports.makeTreeDescendantFilter = exports.makeTreeAncestorFilter = exports.same = exports.getRelevantIds = exports.repel = exports.contains = exports.judgeValueRelation = exports.combineFilters = exports.unionFilterSegment = exports.addFilterSegment = void 0;
|
|
3
|
+
exports.checkFilterRepel = exports.checkFilterContains = exports.makeTreeDescendantFilter = exports.makeTreeAncestorFilter = exports.same = exports.getRelevantIds = exports.repel = exports.contains = exports.judgeValueRelation = exports.combineFilters = exports.unionFilterSegment = exports.addFilterSegment = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
var types_1 = require("../types");
|
|
@@ -502,7 +502,7 @@ function judgeFilter2ValueRelation(entity, schema, attr, filter, conditionalFilt
|
|
|
502
502
|
var logicQueries = filter[attr2];
|
|
503
503
|
var results = logicQueries.map(function (logicQuery) { return judgeFilter2ValueRelation(entity, schema, attr, logicQuery, conditionalFilterAttrValue, contained); });
|
|
504
504
|
// 如果filter的多个算子是and关系,则只要有一个包含此条件就是包含,只要有一个与此条件相斥就是相斥
|
|
505
|
-
// 如果filter的多个算子是or关系,则必须所有的条件都包含此条件才是包含,必须所有的条件都与此条件相斥才是相斥
|
|
505
|
+
// 如果filter的多个算子是or关系,则必须所有的条件都包含此条件才是包含,必须所有的条件都与此条件相斥才是相斥
|
|
506
506
|
if (attr2 === '$and') {
|
|
507
507
|
if (results.includes(true)) {
|
|
508
508
|
return true;
|
|
@@ -520,25 +520,17 @@ function judgeFilter2ValueRelation(entity, schema, attr, filter, conditionalFilt
|
|
|
520
520
|
}
|
|
521
521
|
case '$not': {
|
|
522
522
|
/*
|
|
523
|
-
* 若filter的not条件被conditionalFilterAttrValue
|
|
524
|
-
*
|
|
525
|
-
* 但两条规则都没法应用,会无限递归
|
|
523
|
+
* 若filter的not条件被conditionalFilterAttrValue条件包容,则说明两者互斥
|
|
524
|
+
* filter包容conditionalFilterAttrValue条件暂时无法由其not条件推论出来
|
|
526
525
|
*/
|
|
527
526
|
var logicQuery = filter[attr2];
|
|
528
|
-
|
|
529
|
-
[attr2]: {
|
|
530
|
-
$not: conditionalFilterAttrValue
|
|
531
|
-
}
|
|
532
|
-
}, logicQuery, contained)) {
|
|
533
|
-
return true;
|
|
534
|
-
} */
|
|
535
|
-
if (!contained && judgeFilterRelation(entity, schema, (_a = {}, _a[attr2] = conditionalFilterAttrValue, _a), logicQuery, contained)) {
|
|
527
|
+
if (!contained && judgeFilterRelation(entity, schema, logicQuery, (_a = {}, _a[attr] = conditionalFilterAttrValue, _a), true)) {
|
|
536
528
|
return true;
|
|
537
529
|
}
|
|
538
530
|
break;
|
|
539
531
|
}
|
|
540
532
|
default: {
|
|
541
|
-
|
|
533
|
+
(0, assert_1.default)(false);
|
|
542
534
|
}
|
|
543
535
|
}
|
|
544
536
|
}
|
|
@@ -566,6 +558,7 @@ function judgeFilter2ValueRelation(entity, schema, attr, filter, conditionalFilt
|
|
|
566
558
|
}
|
|
567
559
|
}
|
|
568
560
|
}
|
|
561
|
+
// 到这里说明无法判断相容或者相斥,安全起见全返回false
|
|
569
562
|
return false;
|
|
570
563
|
}
|
|
571
564
|
/**
|
|
@@ -584,15 +577,15 @@ function judgeFilterRelation(entity, schema, filter, conditionalFilter, containe
|
|
|
584
577
|
var logicQueries = conditionalFilter[attr];
|
|
585
578
|
var results = logicQueries.map(function (logicQuery) { return judgeFilterRelation(entity, schema, filter, logicQuery, contained); });
|
|
586
579
|
if (contained) {
|
|
587
|
-
//
|
|
580
|
+
// 如果是包容关系,or和and需要全部被包容
|
|
588
581
|
if (results.includes(false)) {
|
|
589
582
|
return false;
|
|
590
583
|
}
|
|
591
584
|
}
|
|
592
585
|
else if (!contained) {
|
|
593
|
-
//
|
|
594
|
-
if (
|
|
595
|
-
return
|
|
586
|
+
// 如果是相斥关系,and只需要和一个相斥,or需要和全部相斥
|
|
587
|
+
if (attr === '$and' && results.includes(true) || attr === '$or' && !results.includes(false)) {
|
|
588
|
+
return true;
|
|
596
589
|
}
|
|
597
590
|
}
|
|
598
591
|
else {
|
|
@@ -602,12 +595,19 @@ function judgeFilterRelation(entity, schema, filter, conditionalFilter, containe
|
|
|
602
595
|
}
|
|
603
596
|
case '$not': {
|
|
604
597
|
/**
|
|
605
|
-
* 若filter与not
|
|
606
|
-
* 若filter
|
|
598
|
+
* 若filter与conditionalFilter not所定义的部分相斥,则filter与conditionalFilter相容
|
|
599
|
+
* 若filter将conditionalFilter not所定义的部分包容,则filter与conditionalFilter相斥
|
|
607
600
|
*/
|
|
608
601
|
var logicQuery = conditionalFilter[attr];
|
|
609
|
-
if (
|
|
610
|
-
|
|
602
|
+
if (contained) {
|
|
603
|
+
if (!judgeFilterRelation(entity, schema, filter, logicQuery, false)) {
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
if (judgeFilterRelation(entity, schema, filter, logicQuery, true)) {
|
|
609
|
+
return true;
|
|
610
|
+
}
|
|
611
611
|
}
|
|
612
612
|
break;
|
|
613
613
|
}
|
|
@@ -655,8 +655,8 @@ function judgeFilterRelation(entity, schema, filter, conditionalFilter, containe
|
|
|
655
655
|
* @returns
|
|
656
656
|
*/
|
|
657
657
|
function contains(entity, schema, filter, conditionalFilter) {
|
|
658
|
-
|
|
659
|
-
return false;
|
|
658
|
+
return judgeFilterRelation(entity, schema, filter, conditionalFilter, true);
|
|
659
|
+
// return false;
|
|
660
660
|
}
|
|
661
661
|
exports.contains = contains;
|
|
662
662
|
/**
|
|
@@ -675,8 +675,8 @@ exports.contains = contains;
|
|
|
675
675
|
*/
|
|
676
676
|
function repel(entity, schema, filter1, filter2) {
|
|
677
677
|
// todo
|
|
678
|
-
|
|
679
|
-
return false;
|
|
678
|
+
return judgeFilterRelation(entity, schema, filter1, filter2, false);
|
|
679
|
+
// return false;
|
|
680
680
|
}
|
|
681
681
|
exports.repel = repel;
|
|
682
682
|
/**
|
|
@@ -853,3 +853,26 @@ function checkFilterContains(entity, context, contained, filter) {
|
|
|
853
853
|
return count === 0;
|
|
854
854
|
}
|
|
855
855
|
exports.checkFilterContains = checkFilterContains;
|
|
856
|
+
function checkFilterRepel(entity, context, filter1, filter2) {
|
|
857
|
+
if (!filter2) {
|
|
858
|
+
throw new types_1.OakRowInconsistencyException();
|
|
859
|
+
}
|
|
860
|
+
var schema = context.getSchema();
|
|
861
|
+
// 优先判断两个条件是否相容
|
|
862
|
+
if (repel(entity, schema, filter2, filter1)) {
|
|
863
|
+
return true;
|
|
864
|
+
}
|
|
865
|
+
// 再判断两者同时成立时取得的行数是否为0
|
|
866
|
+
var filter3 = combineFilters([filter2, filter1]);
|
|
867
|
+
var count = context.count(entity, {
|
|
868
|
+
filter: filter3,
|
|
869
|
+
}, {
|
|
870
|
+
dontCollect: true,
|
|
871
|
+
blockTrigger: true,
|
|
872
|
+
});
|
|
873
|
+
if (count instanceof Promise) {
|
|
874
|
+
return count.then(function (count2) { return count2 !== 0; });
|
|
875
|
+
}
|
|
876
|
+
return count !== 0;
|
|
877
|
+
}
|
|
878
|
+
exports.checkFilterRepel = checkFilterRepel;
|
package/lib/store/relation.js
CHANGED
|
@@ -24,9 +24,11 @@ function judgeRelation(schema, entity, attr) {
|
|
|
24
24
|
return 1;
|
|
25
25
|
}
|
|
26
26
|
if (attr.includes('$')) {
|
|
27
|
-
var
|
|
27
|
+
var firstDelimiter = attr.indexOf('$');
|
|
28
|
+
var entity2 = attr.slice(0, firstDelimiter);
|
|
28
29
|
(0, assert_1.default)(schema.hasOwnProperty(entity2));
|
|
29
|
-
var
|
|
30
|
+
var secondDelemiter = attr.indexOf('$', firstDelimiter + 1);
|
|
31
|
+
var foreignKey = attr.slice(firstDelimiter + 1, secondDelemiter > 0 ? secondDelemiter : attr.length);
|
|
30
32
|
var _c = schema, _d = entity2, attributes2 = _c[_d].attributes;
|
|
31
33
|
if (foreignKey === 'entity') {
|
|
32
34
|
// 基于反指对象的反向关联
|
package/lib/store/selection.js
CHANGED
|
@@ -181,7 +181,7 @@ function reinforceSelection(schema, entity, selection) {
|
|
|
181
181
|
necessaryAttrs.push("".concat(attr, "Id"));
|
|
182
182
|
checkProjectionNode(rel, projectionNode[attr]);
|
|
183
183
|
}
|
|
184
|
-
else if (rel instanceof Array) {
|
|
184
|
+
else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
|
|
185
185
|
var data_1 = projectionNode[attr].data;
|
|
186
186
|
if (rel[1]) {
|
|
187
187
|
checkNode(data_1, [rel[1]]);
|
|
@@ -189,7 +189,7 @@ function reinforceSelection(schema, entity, selection) {
|
|
|
189
189
|
else {
|
|
190
190
|
checkNode(data_1, ['entity', 'entityId']);
|
|
191
191
|
}
|
|
192
|
-
|
|
192
|
+
reinforceSelection(schema, rel[0], projectionNode[attr]);
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
}
|
package/lib/types/Auth.d.ts
CHANGED
|
@@ -3,12 +3,17 @@ import { SyncContext } from "../store/SyncRowStore";
|
|
|
3
3
|
import { EntityDict, OperateOption, SelectOption } from "../types/Entity";
|
|
4
4
|
import { RefOrExpression } from "./Expression";
|
|
5
5
|
export declare type CheckerType = 'relation' | 'row' | 'data' | 'expression' | 'expressionRelation';
|
|
6
|
+
/**
|
|
7
|
+
* conditionalFilter是指该action发生时,operation所操作的行中有满足conditionalFilter的行
|
|
8
|
+
* 被转化成trigger的filter条件,详细可看trigger中的说明
|
|
9
|
+
*/
|
|
6
10
|
export declare type DataChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
|
7
11
|
priority?: number;
|
|
8
12
|
type: 'data';
|
|
9
13
|
entity: T;
|
|
10
14
|
action: Omit<ED[T]['Action'], 'remove'> | Array<Omit<ED[T]['Action'], 'remove'>>;
|
|
11
15
|
checker: (data: ED[T]['Create']['data'] | ED[T]['Update']['data'], context: Cxt) => void;
|
|
16
|
+
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
|
|
12
17
|
};
|
|
13
18
|
export declare type RowChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
|
14
19
|
priority?: number;
|
|
@@ -21,6 +26,7 @@ export declare type RowChecker<ED extends EntityDict, T extends keyof ED, Cxt ex
|
|
|
21
26
|
entity: keyof ED;
|
|
22
27
|
selection: (filter?: ED[T]['Selection']['filter']) => ED[keyof ED]['Selection'];
|
|
23
28
|
};
|
|
29
|
+
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
|
|
24
30
|
};
|
|
25
31
|
export declare type RelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
|
26
32
|
priority?: number;
|
|
@@ -29,6 +35,7 @@ export declare type RelationChecker<ED extends EntityDict, T extends keyof ED, C
|
|
|
29
35
|
action: Omit<ED[T]['Action'], 'create'> | Array<Omit<ED[T]['Action'], 'create'>>;
|
|
30
36
|
relationFilter: (operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => ED[T]['Selection']['filter'];
|
|
31
37
|
errMsg: string;
|
|
38
|
+
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
|
|
32
39
|
};
|
|
33
40
|
export declare type ExpressionChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
|
34
41
|
priority?: number;
|
|
@@ -39,8 +46,9 @@ export declare type ExpressionChecker<ED extends EntityDict, T extends keyof ED,
|
|
|
39
46
|
entity: T2;
|
|
40
47
|
expr: RefOrExpression<keyof ED[T2]['OpSchema']>;
|
|
41
48
|
filter: ED[T2]['Selection']['filter'];
|
|
42
|
-
};
|
|
49
|
+
} | undefined | string;
|
|
43
50
|
errMsg: string;
|
|
51
|
+
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
|
|
44
52
|
};
|
|
45
53
|
export declare type ExpressionRelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
|
46
54
|
priority?: number;
|
|
@@ -51,7 +59,8 @@ export declare type ExpressionRelationChecker<ED extends EntityDict, T extends k
|
|
|
51
59
|
entity: T2;
|
|
52
60
|
expr: RefOrExpression<keyof ED[T2]['OpSchema']>;
|
|
53
61
|
filter: ED[T2]['Selection']['filter'];
|
|
54
|
-
};
|
|
62
|
+
} | undefined | string;
|
|
55
63
|
errMsg: string;
|
|
64
|
+
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
|
|
56
65
|
};
|
|
57
66
|
export declare type Checker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = DataChecker<ED, T, Cxt> | RowChecker<ED, T, Cxt> | RelationChecker<ED, T, Cxt> | ExpressionChecker<ED, T, Cxt> | ExpressionRelationChecker<ED, T, Cxt>;
|
package/lib/types/Entity.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export interface EntityDef {
|
|
|
73
73
|
Action: string;
|
|
74
74
|
ParticularAction?: string;
|
|
75
75
|
Selection: Omit<DeduceSelection<this['Schema']>, 'action'>;
|
|
76
|
+
Aggregation: Omit<DeduceAggregation<this['Schema'], DeduceProjection<this['Schema']>, DeduceFilter<this['Schema']>, DeduceSorter<this['Schema']>>, 'action'>;
|
|
76
77
|
Operation: DeduceOperation<this['Schema']>;
|
|
77
78
|
Create: DeduceCreateOperation<this['Schema']>;
|
|
78
79
|
CreateSingle: DeduceCreateSingleOperation<this['Schema']>;
|
|
@@ -90,7 +91,18 @@ declare type DeduceProjection<SH extends GeneralEntityShape> = {
|
|
|
90
91
|
'#id'?: NodeId;
|
|
91
92
|
} & {
|
|
92
93
|
[K in keyof SH]?: number | OtmSubProjection | any;
|
|
93
|
-
} & Partial<ExprOp<keyof SH>>;
|
|
94
|
+
} & Partial<ExprOp<keyof SH | string>>;
|
|
95
|
+
export declare type AggregationOp = `#max-${number}` | `#min-${number}` | `#avg-${number}` | `#count-${number}` | `#sum-${number}`;
|
|
96
|
+
export declare type DeduceAggregationData<SH extends GeneralEntityShape, P extends DeduceProjection<SH>> = {
|
|
97
|
+
[A in AggregationOp]?: P;
|
|
98
|
+
} & {
|
|
99
|
+
'#aggr'?: P;
|
|
100
|
+
};
|
|
101
|
+
export declare type AggregationResult<SH extends GeneralEntityShape> = Array<{
|
|
102
|
+
[A in AggregationOp]?: number | string;
|
|
103
|
+
} & {
|
|
104
|
+
'#data'?: Partial<SH>;
|
|
105
|
+
}>;
|
|
94
106
|
export declare type AttrFilter<SH extends GeneralEntityShape> = {
|
|
95
107
|
[K in keyof SH]: any;
|
|
96
108
|
};
|
|
@@ -104,6 +116,7 @@ export declare type DeduceSorterItem<SH extends GeneralEntityShape> = {
|
|
|
104
116
|
};
|
|
105
117
|
export declare type DeduceSorter<SH extends GeneralEntityShape> = Array<DeduceSorterItem<SH>>;
|
|
106
118
|
export declare type DeduceSelection<SH extends GeneralEntityShape> = Selection<DeduceProjection<SH>, DeduceFilter<SH>, DeduceSorter<SH>>;
|
|
119
|
+
export declare type DeduceAggregation<SH extends GeneralEntityShape, P extends DeduceProjection<SH>, F extends DeduceFilter<SH>, S extends DeduceSorter<SH>> = Omit<Operation<'aggregate', DeduceAggregationData<SH, P>, F, S>, 'action'>;
|
|
107
120
|
export declare type DeduceCreateOperationData<SH extends GeneralEntityShape> = {
|
|
108
121
|
id: string;
|
|
109
122
|
} & {
|
|
@@ -137,6 +150,9 @@ export declare type RemoveOpResult<ED extends EntityDict, T extends keyof ED> =
|
|
|
137
150
|
e: T;
|
|
138
151
|
f?: DeduceFilter<ED[T]['Schema']>;
|
|
139
152
|
};
|
|
153
|
+
export declare type RelationHierarchy<R extends string> = {
|
|
154
|
+
[K in R]?: R[];
|
|
155
|
+
};
|
|
140
156
|
export declare type SelectOpResult<ED extends EntityDict> = {
|
|
141
157
|
a: 's';
|
|
142
158
|
d: {
|
|
@@ -156,4 +172,19 @@ export declare type Configuration = {
|
|
|
156
172
|
actionType?: ActionType;
|
|
157
173
|
static?: boolean;
|
|
158
174
|
};
|
|
175
|
+
export declare type Exportation<ED extends EntityDict, T extends keyof ED, K extends string> = {
|
|
176
|
+
name: string;
|
|
177
|
+
id: string;
|
|
178
|
+
entity: T;
|
|
179
|
+
projection: ED[T]['Selection']['data'];
|
|
180
|
+
headers: K[];
|
|
181
|
+
fn: (data: ED[T]['Schema']) => Partial<Record<K, string | number | boolean | null>>;
|
|
182
|
+
};
|
|
183
|
+
export declare type Importation<ED extends EntityDict, T extends keyof ED, K extends string> = {
|
|
184
|
+
name: string;
|
|
185
|
+
id: string;
|
|
186
|
+
entity: T;
|
|
187
|
+
headers: K[];
|
|
188
|
+
fn: (data: Partial<Record<K, string | number | boolean>>) => ED[T]['CreateSingle']['data'];
|
|
189
|
+
};
|
|
159
190
|
export {};
|
package/lib/types/Expression.js
CHANGED
|
@@ -361,7 +361,7 @@ function getAttrRefInExpression(expression) {
|
|
|
361
361
|
_a['#current'] = [],
|
|
362
362
|
_a);
|
|
363
363
|
var check = function (node) {
|
|
364
|
-
var _a;
|
|
364
|
+
var _a, e_3, _b;
|
|
365
365
|
if (node['#attr']) {
|
|
366
366
|
result['#current'].push(node['#attr']);
|
|
367
367
|
}
|
|
@@ -375,9 +375,24 @@ function getAttrRefInExpression(expression) {
|
|
|
375
375
|
_a));
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
|
-
else {
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
else if (node instanceof Array) {
|
|
379
|
+
try {
|
|
380
|
+
for (var node_1 = tslib_1.__values(node), node_1_1 = node_1.next(); !node_1_1.done; node_1_1 = node_1.next()) {
|
|
381
|
+
var subNode = node_1_1.value;
|
|
382
|
+
check(subNode);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
386
|
+
finally {
|
|
387
|
+
try {
|
|
388
|
+
if (node_1_1 && !node_1_1.done && (_b = node_1.return)) _b.call(node_1);
|
|
389
|
+
}
|
|
390
|
+
finally { if (e_3) throw e_3.error; }
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else if (typeof node === 'object') {
|
|
394
|
+
for (var attr in node) {
|
|
395
|
+
check(node[attr]);
|
|
381
396
|
}
|
|
382
397
|
}
|
|
383
398
|
};
|
package/lib/types/Storage.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ActionType } from '.';
|
|
2
|
-
import { EntityDict, EntityShape, InstinctiveAttributes } from './Entity';
|
|
2
|
+
import { EntityDict, EntityShape, InstinctiveAttributes, RelationHierarchy } from './Entity';
|
|
3
3
|
import { DataType, DataTypeParams } from './schema/DataTypes';
|
|
4
4
|
export declare type Ref = 'ref';
|
|
5
5
|
export interface Column<SH extends EntityShape> {
|
|
@@ -36,7 +36,7 @@ export declare type UniqConstraint<SH extends EntityShape> = {
|
|
|
36
36
|
attributes: Array<keyof SH>;
|
|
37
37
|
type?: string;
|
|
38
38
|
};
|
|
39
|
-
export interface StorageDesc<SH extends EntityShape> {
|
|
39
|
+
export interface StorageDesc<SH extends EntityShape, Relation extends string = ''> {
|
|
40
40
|
storageName?: string;
|
|
41
41
|
comment?: string;
|
|
42
42
|
attributes: Attributes<SH>;
|
|
@@ -48,8 +48,9 @@ export interface StorageDesc<SH extends EntityShape> {
|
|
|
48
48
|
static?: true;
|
|
49
49
|
actions: string[];
|
|
50
50
|
actionType: ActionType;
|
|
51
|
+
relationHierarchy?: RelationHierarchy<Relation>;
|
|
51
52
|
view?: true;
|
|
52
53
|
}
|
|
53
54
|
export declare type StorageSchema<ED extends EntityDict> = {
|
|
54
|
-
[K in keyof ED]: StorageDesc<ED[K]['OpSchema']>;
|
|
55
|
+
[K in keyof ED]: StorageDesc<ED[K]['OpSchema'], any>;
|
|
55
56
|
};
|
package/lib/types/Timer.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { RecurrenceRule, RecurrenceSpecDateRange, RecurrenceSpecObjLit } from 'node-schedule';
|
|
2
1
|
import { EntityDict } from './Entity';
|
|
3
2
|
import { AsyncContext } from "../store/AsyncRowStore";
|
|
4
3
|
declare type RoutineFn<ED extends EntityDict, Cxt extends AsyncContext<ED>> = (context: Cxt) => Promise<string>;
|
|
@@ -8,7 +7,7 @@ export declare type Routine<ED extends EntityDict, Cxt extends AsyncContext<ED>>
|
|
|
8
7
|
};
|
|
9
8
|
export declare type Timer<ED extends EntityDict, Cxt extends AsyncContext<ED>> = {
|
|
10
9
|
name: string;
|
|
11
|
-
cron:
|
|
10
|
+
cron: string;
|
|
12
11
|
fn: RoutineFn<ED, Cxt>;
|
|
13
12
|
};
|
|
14
13
|
export {};
|
package/lib/types/Trigger.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export interface CreateTriggerCrossTxn<ED extends EntityDict, T extends keyof ED
|
|
|
25
25
|
strict?: 'takeEasy' | 'makeSure';
|
|
26
26
|
}
|
|
27
27
|
export declare type CreateTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = CreateTriggerInTxn<ED, T, Cxt> | CreateTriggerCrossTxn<ED, T, Cxt>;
|
|
28
|
+
/**
|
|
29
|
+
* update trigger如果带有filter,说明只对存在限定条件的行起作用。此时系统在进行相应动作时,
|
|
30
|
+
* 会判定当前动作的filter条件和trigger所定义的filter是否有交集(即有同时满足两个条件的行)
|
|
31
|
+
* 只要有,就会触发trigger。要注意的是这个条件是exists而不是all
|
|
32
|
+
*/
|
|
28
33
|
export interface UpdateTriggerBase<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends TriggerBase<ED, T> {
|
|
29
34
|
action: Exclude<ED[T]['Action'], GenericAction> | 'update' | Array<Exclude<ED[T]['Action'], GenericAction> | 'update'>;
|
|
30
35
|
attributes?: keyof ED[T]['OpSchema'] | Array<keyof ED[T]['OpSchema']>;
|
|
@@ -32,6 +37,7 @@ export interface UpdateTriggerBase<ED extends EntityDict, T extends keyof ED, Cx
|
|
|
32
37
|
fn: (event: {
|
|
33
38
|
operation: ED[T]['Update'];
|
|
34
39
|
}, context: Cxt, option: OperateOption) => Promise<number> | number;
|
|
40
|
+
filter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Update'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
|
|
35
41
|
}
|
|
36
42
|
export interface UpdateTriggerInTxn<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends UpdateTriggerBase<ED, T, Cxt> {
|
|
37
43
|
when: 'before' | 'after';
|
|
@@ -41,12 +47,18 @@ export interface UpdateTriggerCrossTxn<ED extends EntityDict, T extends keyof ED
|
|
|
41
47
|
strict?: 'takeEasy' | 'makeSure';
|
|
42
48
|
}
|
|
43
49
|
export declare type UpdateTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = UpdateTriggerInTxn<ED, T, Cxt> | UpdateTriggerCrossTxn<ED, T, Cxt>;
|
|
50
|
+
/**
|
|
51
|
+
* 同update trigger一样,remove trigger如果带有filter,说明只对存在限定条件的行起作用。此时系统在进行相应动作时,
|
|
52
|
+
* 会判定当前动作的filter条件和trigger所定义的filter是否有交集(即有同时满足两个条件的行)
|
|
53
|
+
* 只要有,就会触发trigger。要注意的是这个条件是exists而不是all
|
|
54
|
+
*/
|
|
44
55
|
export interface RemoveTriggerBase<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends TriggerBase<ED, T> {
|
|
45
56
|
action: 'remove';
|
|
46
57
|
check?: (operation: ED[T]['Remove']) => boolean;
|
|
47
58
|
fn: (event: {
|
|
48
59
|
operation: ED[T]['Remove'];
|
|
49
60
|
}, context: Cxt, option: OperateOption) => Promise<number> | number;
|
|
61
|
+
filter?: ED[T]['Remove']['filter'] | ((operation: ED[T]['Remove'], context: Cxt, option: OperateOption) => ED[T]['Remove']['filter']);
|
|
50
62
|
}
|
|
51
63
|
export interface RemoveTriggerInTxn<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends RemoveTriggerBase<ED, T, Cxt> {
|
|
52
64
|
when: 'before' | 'after';
|
|
@@ -3,8 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SimpleConnector = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
var stream_1 = require("stream");
|
|
6
7
|
var types_1 = require("../types");
|
|
7
8
|
function makeContentTypeAndBody(data) {
|
|
9
|
+
//
|
|
10
|
+
if (process.env.OAK_PLATFORM !== 'wechatMp') {
|
|
11
|
+
if (data instanceof FormData) {
|
|
12
|
+
return {
|
|
13
|
+
contentType: 'multipart/form-data',
|
|
14
|
+
body: data,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
8
18
|
return {
|
|
9
19
|
contentType: 'application/json',
|
|
10
20
|
body: JSON.stringify(data),
|
|
@@ -82,6 +92,11 @@ var SimpleConnector = /** @class */ (function (_super) {
|
|
|
82
92
|
});
|
|
83
93
|
};
|
|
84
94
|
SimpleConnector.prototype.serializeResult = function (result, context, headers, body) {
|
|
95
|
+
if (result instanceof stream_1.Stream) {
|
|
96
|
+
return {
|
|
97
|
+
body: result,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
85
100
|
return {
|
|
86
101
|
body: {
|
|
87
102
|
result: result,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function schedule(cron: string, fn: (date: Date) => any): void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schedule = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var cronjs_matcher_1 = require("@datasert/cronjs-matcher");
|
|
6
|
+
var dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
|
7
|
+
function schedule(cron, fn) {
|
|
8
|
+
var futureMatches = (0, cronjs_matcher_1.getFutureMatches)(cron, {
|
|
9
|
+
matchCount: 1,
|
|
10
|
+
});
|
|
11
|
+
var date = (0, dayjs_1.default)(futureMatches[0]);
|
|
12
|
+
var interval = date.diff((0, dayjs_1.default)(), 'ms');
|
|
13
|
+
setTimeout(function () {
|
|
14
|
+
fn(new Date());
|
|
15
|
+
schedule(cron, fn);
|
|
16
|
+
}, interval);
|
|
17
|
+
}
|
|
18
|
+
exports.schedule = schedule;
|
package/lib/utils/lodash.d.ts
CHANGED
|
@@ -2,4 +2,19 @@
|
|
|
2
2
|
* 避免lodash打包体积过大
|
|
3
3
|
* 像assign, keys尽量使用Object的函数
|
|
4
4
|
*/
|
|
5
|
-
|
|
5
|
+
import unset from 'lodash/unset';
|
|
6
|
+
import uniqBy from 'lodash/uniqBy';
|
|
7
|
+
import pull from 'lodash/pull';
|
|
8
|
+
import uniq from 'lodash/uniq';
|
|
9
|
+
import get from 'lodash/get';
|
|
10
|
+
import set from 'lodash/set';
|
|
11
|
+
import intersection from 'lodash/intersection';
|
|
12
|
+
import omit from 'lodash/omit';
|
|
13
|
+
import merge from 'lodash/merge';
|
|
14
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
15
|
+
import pick from 'lodash/pick';
|
|
16
|
+
import isEqual from 'lodash/isEqual';
|
|
17
|
+
import union from 'lodash/union';
|
|
18
|
+
import difference from 'lodash/difference';
|
|
19
|
+
import groupBy from 'lodash/groupBy';
|
|
20
|
+
export { unset, pull, uniq, uniqBy, get, set, intersection, omit, merge, cloneDeep, pick, isEqual, union, difference, groupBy, };
|
package/lib/utils/lodash.js
CHANGED
|
@@ -1,38 +1,55 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.groupBy = exports.difference = exports.union = exports.isEqual = exports.pick = exports.cloneDeep = exports.merge = exports.omit = exports.intersection = exports.set = exports.get = exports.uniqBy = exports.uniq = exports.pull = exports.unset = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
4
5
|
/**
|
|
5
6
|
* 避免lodash打包体积过大
|
|
6
7
|
* 像assign, keys尽量使用Object的函数
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
9
|
+
var unset_1 = tslib_1.__importDefault(require("lodash/unset"));
|
|
10
|
+
exports.unset = unset_1.default;
|
|
11
|
+
var uniqBy_1 = tslib_1.__importDefault(require("lodash/uniqBy"));
|
|
12
|
+
exports.uniqBy = uniqBy_1.default;
|
|
13
|
+
var pull_1 = tslib_1.__importDefault(require("lodash/pull"));
|
|
14
|
+
exports.pull = pull_1.default;
|
|
15
|
+
var uniq_1 = tslib_1.__importDefault(require("lodash/uniq"));
|
|
16
|
+
exports.uniq = uniq_1.default;
|
|
17
|
+
var get_1 = tslib_1.__importDefault(require("lodash/get"));
|
|
18
|
+
exports.get = get_1.default;
|
|
19
|
+
var set_1 = tslib_1.__importDefault(require("lodash/set"));
|
|
20
|
+
exports.set = set_1.default;
|
|
21
|
+
var intersection_1 = tslib_1.__importDefault(require("lodash/intersection"));
|
|
22
|
+
exports.intersection = intersection_1.default;
|
|
23
|
+
var omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
24
|
+
exports.omit = omit_1.default;
|
|
25
|
+
var merge_1 = tslib_1.__importDefault(require("lodash/merge"));
|
|
26
|
+
exports.merge = merge_1.default;
|
|
27
|
+
var cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
28
|
+
exports.cloneDeep = cloneDeep_1.default;
|
|
29
|
+
var pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
|
30
|
+
exports.pick = pick_1.default;
|
|
31
|
+
var isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
|
|
32
|
+
exports.isEqual = isEqual_1.default;
|
|
33
|
+
var union_1 = tslib_1.__importDefault(require("lodash/union"));
|
|
34
|
+
exports.union = union_1.default;
|
|
35
|
+
var difference_1 = tslib_1.__importDefault(require("lodash/difference"));
|
|
36
|
+
exports.difference = difference_1.default;
|
|
37
|
+
var groupBy_1 = tslib_1.__importDefault(require("lodash/groupBy"));
|
|
38
|
+
exports.groupBy = groupBy_1.default;
|
|
39
|
+
// export {
|
|
40
|
+
// unset,
|
|
41
|
+
// pull,
|
|
42
|
+
// uniq,
|
|
43
|
+
// uniqBy,
|
|
44
|
+
// get,
|
|
45
|
+
// set,
|
|
46
|
+
// intersection,
|
|
47
|
+
// omit,
|
|
48
|
+
// merge,
|
|
49
|
+
// cloneDeep,
|
|
50
|
+
// pick,
|
|
51
|
+
// isEqual,
|
|
52
|
+
// union,
|
|
53
|
+
// difference,
|
|
54
|
+
// groupBy,
|
|
55
|
+
// } from 'lodash';
|
package/lib/utils/uuid.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateNewId = exports.setGenerateIdOption = exports.produceIds = exports.generateNewIdAsync = exports.expandUuidTo36Bytes = exports.shrinkUuidTo32Bytes = exports.sequentialUuid = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
5
|
var uuid_1 = require("uuid");
|
|
7
6
|
var random_1 = require("./random/random");
|
|
8
7
|
var _nodeId;
|
|
@@ -172,11 +171,24 @@ function setGenerateIdOption(option) {
|
|
|
172
171
|
}
|
|
173
172
|
exports.setGenerateIdOption = setGenerateIdOption;
|
|
174
173
|
function generateNewId() {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
174
|
+
if (ID_BUFFER.length > 0) {
|
|
175
|
+
var id = ID_BUFFER.pop();
|
|
176
|
+
if (ID_BUFFER.length < 64) {
|
|
177
|
+
produceIds();
|
|
178
|
+
}
|
|
179
|
+
return id;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// 如果没来的及填满缓冲池,这里用一个简单的算法产生同步id(在小程序环境下跑出来过)
|
|
183
|
+
var random = new Uint8Array(16);
|
|
184
|
+
var iter = 0;
|
|
185
|
+
do {
|
|
186
|
+
random[iter] = Math.ceil(Math.random() * 1000) % 128;
|
|
187
|
+
} while (++iter < 16);
|
|
188
|
+
if ((ID_OPTION === null || ID_OPTION === void 0 ? void 0 : ID_OPTION.shuffle) || process.env.NODE_ENV === 'development') {
|
|
189
|
+
return (0, uuid_1.v4)({ random: random });
|
|
190
|
+
}
|
|
191
|
+
return sequentialUuid({ random: random });
|
|
179
192
|
}
|
|
180
|
-
return id;
|
|
181
193
|
}
|
|
182
194
|
exports.generateNewId = generateNewId;
|