oak-domain 5.1.20 → 5.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/base-app-domain/ActionAuth/_baseSchema.d.ts +2 -0
- package/lib/base-app-domain/ModiEntity/_baseSchema.d.ts +1 -0
- package/lib/base-app-domain/Oper/_baseSchema.d.ts +2 -0
- package/lib/base-app-domain/OperEntity/_baseSchema.d.ts +1 -0
- package/lib/base-app-domain/RelationAuth/_baseSchema.d.ts +3 -0
- package/lib/base-app-domain/User/_baseSchema.d.ts +1 -0
- package/lib/base-app-domain/UserEntityClaim/_baseSchema.d.ts +4 -0
- package/lib/base-app-domain/UserRelation/_baseSchema.d.ts +2 -0
- package/lib/compiler/dependencyBuilder.js +31 -24
- package/lib/compiler/schemalBuilder.js +1 -1
- package/lib/store/TriggerExecutor.js +12 -6
- package/lib/types/Configuration.d.ts +6 -11
- package/lib/types/Endpoint.d.ts +19 -1
- package/lib/types/Endpoint.js +1 -0
- package/lib/types/Trigger.d.ts +6 -6
- package/package.json +5 -1
|
@@ -58,8 +58,10 @@ export type OpSortAttr = Partial<{
|
|
|
58
58
|
$$seq$$: number;
|
|
59
59
|
$$updateAt$$: number;
|
|
60
60
|
action: number;
|
|
61
|
+
operatorId: number;
|
|
61
62
|
targetEntity: number;
|
|
62
63
|
bornAt: number;
|
|
64
|
+
logId: number;
|
|
63
65
|
iState: number;
|
|
64
66
|
[k: string]: any;
|
|
65
67
|
} | ExprOp<OpAttr | string>>;
|
|
@@ -35,6 +35,9 @@ export type OpSortAttr = Partial<{
|
|
|
35
35
|
$$createAt$$: number;
|
|
36
36
|
$$seq$$: number;
|
|
37
37
|
$$updateAt$$: number;
|
|
38
|
+
sourceRelationId: number;
|
|
39
|
+
pathId: number;
|
|
40
|
+
destRelationId: number;
|
|
38
41
|
[k: string]: any;
|
|
39
42
|
} | ExprOp<OpAttr | string>>;
|
|
40
43
|
export type OpAction = OakMakeAction<GenericAction | string>;
|
|
@@ -42,7 +42,11 @@ export type OpSortAttr = Partial<{
|
|
|
42
42
|
$$createAt$$: number;
|
|
43
43
|
$$seq$$: number;
|
|
44
44
|
$$updateAt$$: number;
|
|
45
|
+
uegId: number;
|
|
46
|
+
userId: number;
|
|
47
|
+
relationId: number;
|
|
45
48
|
claimEntityId: number;
|
|
49
|
+
userRelationId: number;
|
|
46
50
|
[k: string]: any;
|
|
47
51
|
} | ExprOp<OpAttr | string>>;
|
|
48
52
|
export type OpAction = OakMakeAction<GenericAction | string>;
|
|
@@ -285,7 +285,7 @@ function outputContext(depGraph, sourceFile, printer, filename) {
|
|
|
285
285
|
const { statements } = sourceFile;
|
|
286
286
|
const isBackend = filename.includes('BackendRuntimeContext');
|
|
287
287
|
const statements2 = [
|
|
288
|
-
factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(isBackend ? "BaseBackendRuntimeContext" : "BaseFrontendRuntimeContext"), undefined), factory.createStringLiteral(
|
|
288
|
+
factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(isBackend ? "BaseBackendRuntimeContext" : "BaseFrontendRuntimeContext"), undefined), factory.createStringLiteral(`@${root}/context/${isBackend ? 'BackendRuntimeContext' : 'FrontendRuntimeContext'}`), undefined),
|
|
289
289
|
...statements
|
|
290
290
|
];
|
|
291
291
|
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray(statements2), sourceFile);
|
|
@@ -745,27 +745,34 @@ function injectDataIndexFile(dataIndexFile, briefNames, printer) {
|
|
|
745
745
|
console.log(`注入${dataIndexFile}文件成功,共注入了${briefNames.length}个初始化数据引用`);
|
|
746
746
|
}
|
|
747
747
|
/**
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
* @param
|
|
751
|
-
* @param modulePageDir
|
|
748
|
+
* 将依赖项目的目录去覆盖原来的目录
|
|
749
|
+
* @param fromDir 依赖项目的目录
|
|
750
|
+
* @param toDir 当前项目的目录
|
|
752
751
|
*/
|
|
753
|
-
function
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
const
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
if (
|
|
761
|
-
|
|
762
|
-
const srcDir = join(modulePageDir, namespace, page);
|
|
763
|
-
console.log(`拷贝${srcDir}到${destDir}下`);
|
|
764
|
-
(0, fs_extra_1.copySync)(srcDir, destDir, {
|
|
765
|
-
recursive: true,
|
|
766
|
-
});
|
|
752
|
+
function tryCopyFilesRecursively(fromDir, toDir) {
|
|
753
|
+
const files = (0, fs_1.readdirSync)(fromDir);
|
|
754
|
+
files.forEach((file) => {
|
|
755
|
+
const fromFile = join(fromDir, file);
|
|
756
|
+
const toFile = join(toDir, file);
|
|
757
|
+
const stat = (0, fs_1.statSync)(fromFile);
|
|
758
|
+
if (stat.isFile()) {
|
|
759
|
+
if ((0, fs_1.existsSync)(join(toDir, file))) {
|
|
760
|
+
console.log(`覆盖文件${toFile}`);
|
|
767
761
|
}
|
|
768
|
-
|
|
762
|
+
else {
|
|
763
|
+
console.log(`拷贝文件${toFile}`);
|
|
764
|
+
}
|
|
765
|
+
(0, fs_extra_1.copySync)(fromFile, toFile, {
|
|
766
|
+
overwrite: true,
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
if (!(0, fs_1.existsSync)(toFile)) {
|
|
771
|
+
console.log(`创建文件夹${toFile}`);
|
|
772
|
+
(0, fs_extra_1.mkdirSync)(toFile);
|
|
773
|
+
}
|
|
774
|
+
tryCopyFilesRecursively(fromFile, toFile);
|
|
775
|
+
}
|
|
769
776
|
});
|
|
770
777
|
}
|
|
771
778
|
/**
|
|
@@ -792,10 +799,10 @@ function tryCopyModuleTemplateFiles(cwd, dependencies, briefNames, printer) {
|
|
|
792
799
|
injectDataIndexFileBriefNames.push(briefNames[idx]);
|
|
793
800
|
}
|
|
794
801
|
}
|
|
795
|
-
//
|
|
796
|
-
const
|
|
797
|
-
if ((0, fs_1.existsSync)(
|
|
798
|
-
|
|
802
|
+
// src下面的文件是可以拷贝到项目中的
|
|
803
|
+
const srcDir = join(moduleTemplateDir, 'src');
|
|
804
|
+
if ((0, fs_1.existsSync)(srcDir)) {
|
|
805
|
+
tryCopyFilesRecursively(srcDir, join(cwd, 'src'));
|
|
799
806
|
}
|
|
800
807
|
}
|
|
801
808
|
});
|
|
@@ -2532,7 +2532,7 @@ function _constructOpSortAttr(statements, entity) {
|
|
|
2532
2532
|
const text2 = text === 'Schema' ? entity : text;
|
|
2533
2533
|
const manyToOneItem = manyToOneSet && manyToOneSet.find(([refEntity]) => refEntity === text2);
|
|
2534
2534
|
if (manyToOneItem) {
|
|
2535
|
-
factory.createPropertySignature(undefined, factory.createIdentifier(`${name.text}Id`), undefined, factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword));
|
|
2535
|
+
members.push(factory.createPropertySignature(undefined, factory.createIdentifier(`${name.text}Id`), undefined, factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)));
|
|
2536
2536
|
}
|
|
2537
2537
|
else if (!['Object'].includes(text)) {
|
|
2538
2538
|
// todo 对State的专门处理
|
|
@@ -276,7 +276,8 @@ class TriggerExecutor {
|
|
|
276
276
|
// 加上modi的过滤条件
|
|
277
277
|
&& this.judgeModiTurn(option, trigger));
|
|
278
278
|
if (triggers) {
|
|
279
|
-
const preTriggers = triggers.filter(ele => ele.when === 'before' && (!ele.check || ele.check(operation))
|
|
279
|
+
const preTriggers = triggers.filter(ele => ele.when === 'before' && (!ele.check || ele.check(operation))
|
|
280
|
+
&& (!ele.attributes || (0, lodash_1.difference)(ele.attributes, Object.keys(operation.data)).length === 0));
|
|
280
281
|
const commitTriggers = triggers.filter(ele => ele.when === 'commit' &&
|
|
281
282
|
(!ele.check || ele.check(operation)));
|
|
282
283
|
if (context instanceof SyncRowStore_1.SyncContext) {
|
|
@@ -363,14 +364,18 @@ class TriggerExecutor {
|
|
|
363
364
|
if (trigger.strict === 'makeSure' && ids.length && !cleanTriggerDataBySelf) {
|
|
364
365
|
// 这里开root模式,否则还可能有权限问题
|
|
365
366
|
const closeRoot2 = context.openRootMode();
|
|
367
|
+
const data = {
|
|
368
|
+
[Entity_1.TriggerDataAttribute]: null,
|
|
369
|
+
[Entity_1.TriggerUuidAttribute]: null,
|
|
370
|
+
};
|
|
371
|
+
if (typeof callback === 'object') {
|
|
372
|
+
Object.assign(data, callback);
|
|
373
|
+
}
|
|
366
374
|
try {
|
|
367
375
|
await context.operate(entity, {
|
|
368
376
|
id: await (0, uuid_1.generateNewIdAsync)(),
|
|
369
377
|
action: 'update',
|
|
370
|
-
data
|
|
371
|
-
[Entity_1.TriggerDataAttribute]: null,
|
|
372
|
-
[Entity_1.TriggerUuidAttribute]: null,
|
|
373
|
-
},
|
|
378
|
+
data,
|
|
374
379
|
filter: {
|
|
375
380
|
id: {
|
|
376
381
|
$in: ids,
|
|
@@ -426,7 +431,8 @@ class TriggerExecutor {
|
|
|
426
431
|
// 加上modi的过滤条件
|
|
427
432
|
&& this.judgeModiTurn(option, trigger));
|
|
428
433
|
if (triggers) {
|
|
429
|
-
const postTriggers = triggers.filter(ele => ele.when === 'after' && (!ele.check || ele.check(operation))
|
|
434
|
+
const postTriggers = triggers.filter(ele => ele.when === 'after' && (!ele.check || ele.check(operation))
|
|
435
|
+
&& (!ele.attributes || (0, lodash_1.difference)(ele.attributes, Object.keys(operation.data)).length === 0));
|
|
430
436
|
const commitTriggers = triggers.filter(ele => ele.when === 'commit' &&
|
|
431
437
|
(!ele.check || ele.check(operation)));
|
|
432
438
|
if (context instanceof SyncRowStore_1.SyncContext) {
|
|
@@ -3,6 +3,9 @@ import { EntityDict as BaseEntityDict } from "../base-app-domain";
|
|
|
3
3
|
import { AttrUpdateMatrix } from './EntityDesc';
|
|
4
4
|
import { ActionDefDict } from './Action';
|
|
5
5
|
import { StyleDict } from './Style';
|
|
6
|
+
import type { IKoaBodyOptions } from 'koa-body';
|
|
7
|
+
import Koa from 'koa';
|
|
8
|
+
import KoaRouter from 'koa-router';
|
|
6
9
|
/**
|
|
7
10
|
* redis连接信息,如果是Redis集群,可以配置多个
|
|
8
11
|
*/
|
|
@@ -43,17 +46,9 @@ export type ServerConfiguration = {
|
|
|
43
46
|
methods?: string[];
|
|
44
47
|
};
|
|
45
48
|
internalExceptionMask?: string;
|
|
46
|
-
koaBody?:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
maxFileSize?: number;
|
|
50
|
-
maxFields?: number;
|
|
51
|
-
maxFieldsSize?: number;
|
|
52
|
-
uploadDir?: string;
|
|
53
|
-
keepExtensions?: boolean;
|
|
54
|
-
hashAlgorithm?: string;
|
|
55
|
-
multiples?: boolean;
|
|
56
|
-
};
|
|
49
|
+
koaBody?: IKoaBodyOptions;
|
|
50
|
+
socket?: (ctx: Koa.ParameterizedContext<any, KoaRouter.IRouterParamContext<any, {}>, any>) => {
|
|
51
|
+
url?: string;
|
|
57
52
|
};
|
|
58
53
|
};
|
|
59
54
|
/**
|
package/lib/types/Endpoint.d.ts
CHANGED
|
@@ -3,10 +3,28 @@ import { IncomingHttpHeaders, IncomingMessage } from "http";
|
|
|
3
3
|
import { AsyncContext } from "../store/AsyncRowStore";
|
|
4
4
|
import { EntityDict } from "./Entity";
|
|
5
5
|
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
6
|
-
export
|
|
6
|
+
export type EndpointItem<ED extends EntityDict & BaseEntityDict, BackCxt extends AsyncContext<ED>> = SimpleEndpoint<ED, BackCxt> | FreeEndpoint<ED, BackCxt>;
|
|
7
|
+
export interface SimpleEndpoint<ED extends EntityDict & BaseEntityDict, BackCxt extends AsyncContext<ED>> {
|
|
7
8
|
name: string;
|
|
8
9
|
params?: string[];
|
|
9
10
|
method: 'get' | 'post' | 'put' | 'delete';
|
|
11
|
+
type?: "simple";
|
|
10
12
|
fn: (context: BackCxt, params: Record<string, string>, headers: IncomingHttpHeaders, req: IncomingMessage, body?: any) => Promise<any>;
|
|
11
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 此类型的接口可能会保持长连接,逐步返回内容,所以直接控制res和req即可
|
|
16
|
+
* backendcontext也不能直接传入,在需要时调用方法开启事务
|
|
17
|
+
* 返回时可以指定contentType
|
|
18
|
+
*/
|
|
19
|
+
export interface FreeEndpoint<ED extends EntityDict & BaseEntityDict, BackCxt extends AsyncContext<ED>> {
|
|
20
|
+
name: string;
|
|
21
|
+
params?: string[];
|
|
22
|
+
method: 'get' | 'post' | 'put' | 'delete';
|
|
23
|
+
type: "free";
|
|
24
|
+
fn: (contextBuilder: () => Promise<BackCxt>, params: Record<string, string>, headers: IncomingHttpHeaders, req: IncomingMessage, body?: any) => Promise<{
|
|
25
|
+
headers?: Record<string, string | string[]>;
|
|
26
|
+
statusCode?: number;
|
|
27
|
+
data: any;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
12
30
|
export type Endpoint<ED extends EntityDict & BaseEntityDict, BackCxt extends AsyncContext<ED>> = EndpointItem<ED, BackCxt> | EndpointItem<ED, BackCxt>[];
|
package/lib/types/Endpoint.js
CHANGED
package/lib/types/Trigger.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export interface CreateTriggerInTxn<ED extends EntityDict & BaseEntityDict, T ex
|
|
|
36
36
|
operation: ED[T]['Create'];
|
|
37
37
|
}, context: Cxt, option: OperateOption) => Promise<number> | number;
|
|
38
38
|
}
|
|
39
|
-
interface TriggerCrossTxn<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED> | SyncContext<ED>> {
|
|
39
|
+
interface TriggerCrossTxn<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> {
|
|
40
40
|
when: 'commit';
|
|
41
41
|
strict?: 'takeEasy' | 'makeSure';
|
|
42
42
|
cs?: true;
|
|
@@ -45,9 +45,9 @@ interface TriggerCrossTxn<ED extends EntityDict & BaseEntityDict, Cxt extends As
|
|
|
45
45
|
grouped?: true;
|
|
46
46
|
fn: (event: {
|
|
47
47
|
ids: string[];
|
|
48
|
-
}, context: Cxt, option: OperateOption) => Promise<((context: Cxt, option: OperateOption) => Promise<any>) | void>;
|
|
48
|
+
}, context: Cxt, option: OperateOption) => Promise<((context: Cxt, option: OperateOption) => Promise<any>) | void | ED[T]['Update']['data']>;
|
|
49
49
|
}
|
|
50
|
-
export interface CreateTriggerCrossTxn<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends CreateTriggerBase<ED, T, Cxt>, TriggerCrossTxn<ED, Cxt> {
|
|
50
|
+
export interface CreateTriggerCrossTxn<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends CreateTriggerBase<ED, T, Cxt>, TriggerCrossTxn<ED, T, Cxt> {
|
|
51
51
|
}
|
|
52
52
|
export type CreateTrigger<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = CreateTriggerInTxn<ED, T, Cxt> | CreateTriggerCrossTxn<ED, T, Cxt>;
|
|
53
53
|
/**
|
|
@@ -57,7 +57,7 @@ export type CreateTrigger<ED extends EntityDict & BaseEntityDict, T extends keyo
|
|
|
57
57
|
*/
|
|
58
58
|
export interface UpdateTriggerBase<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends TriggerBase<ED, T> {
|
|
59
59
|
action: Exclude<ED[T]['Action'], ExcludeUpdateAction> | Array<Exclude<ED[T]['Action'], ExcludeUpdateAction>>;
|
|
60
|
-
attributes?:
|
|
60
|
+
attributes?: Array<keyof ED[T]['OpSchema']>;
|
|
61
61
|
mt?: ModiTurn;
|
|
62
62
|
check?: (operation: ED[T]['Update']) => boolean;
|
|
63
63
|
filter?: ED[T]['Filter'] | ((operation: ED[T]['Update'], context: Cxt, option: OperateOption) => ED[T]['Filter'] | Promise<ED[T]['Filter']>);
|
|
@@ -68,7 +68,7 @@ export interface UpdateTriggerInTxn<ED extends EntityDict & BaseEntityDict, T ex
|
|
|
68
68
|
operation: ED[T]['Update'];
|
|
69
69
|
}, context: Cxt, option: OperateOption) => Promise<number> | number;
|
|
70
70
|
}
|
|
71
|
-
export interface UpdateTriggerCrossTxn<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends UpdateTriggerBase<ED, T, Cxt>, TriggerCrossTxn<ED, Cxt> {
|
|
71
|
+
export interface UpdateTriggerCrossTxn<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends UpdateTriggerBase<ED, T, Cxt>, TriggerCrossTxn<ED, T, Cxt> {
|
|
72
72
|
}
|
|
73
73
|
export type UpdateTrigger<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = UpdateTriggerInTxn<ED, T, Cxt> | UpdateTriggerCrossTxn<ED, T, Cxt>;
|
|
74
74
|
/**
|
|
@@ -88,7 +88,7 @@ export interface RemoveTriggerInTxn<ED extends EntityDict & BaseEntityDict, T ex
|
|
|
88
88
|
operation: ED[T]['Remove'];
|
|
89
89
|
}, context: Cxt, option: OperateOption) => Promise<number> | number;
|
|
90
90
|
}
|
|
91
|
-
export interface RemoveTriggerCrossTxn<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends RemoveTriggerBase<ED, T, Cxt>, TriggerCrossTxn<ED, Cxt> {
|
|
91
|
+
export interface RemoveTriggerCrossTxn<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends RemoveTriggerBase<ED, T, Cxt>, TriggerCrossTxn<ED, T, Cxt> {
|
|
92
92
|
}
|
|
93
93
|
export type RemoveTrigger<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = RemoveTriggerInTxn<ED, T, Cxt> | RemoveTriggerCrossTxn<ED, T, Cxt>;
|
|
94
94
|
export interface SelectTriggerBase<ED extends EntityDict & BaseEntityDict, T extends keyof ED> extends TriggerBase<ED, T> {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oak-domain",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.22",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "XuChang"
|
|
6
6
|
},
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
"@babel/preset-typescript": "^7.12.13",
|
|
24
24
|
"@types/assert": "^1.5.6",
|
|
25
25
|
"@types/cross-spawn": "^6.0.2",
|
|
26
|
+
"@types/koa": "^2.15.0",
|
|
27
|
+
"@types/koa-router": "^7.4.8",
|
|
26
28
|
"@types/fs-extra": "^9.0.13",
|
|
27
29
|
"@types/lodash": "^4.14.182",
|
|
28
30
|
"@types/mocha": "^8.2.0",
|
|
@@ -45,6 +47,8 @@
|
|
|
45
47
|
},
|
|
46
48
|
"dependencies": {
|
|
47
49
|
"dayjs": "^1.11.9",
|
|
50
|
+
"koa": "^2.16.1",
|
|
51
|
+
"koa-body": "^5.0.0",
|
|
48
52
|
"node-schedule": "^2.1.1",
|
|
49
53
|
"socket.io": "^4.8.1",
|
|
50
54
|
"uuid": "^9.0.0",
|