oak-domain 5.1.22 → 5.1.23
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/compiler/schemalBuilder.d.ts +22 -0
- package/lib/compiler/schemalBuilder.js +153 -1
- package/lib/store/RelationAuth.js +5 -3
- package/lib/types/Exception.d.ts +1 -0
- package/lib/types/Exception.js +1 -0
- package/lib/utils/SimpleConnector.d.ts +2 -2
- package/lib/utils/SimpleConnector.js +16 -12
- package/package.json +1 -1
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
declare const Schema: Record<string, {
|
|
3
|
+
schemaAttrs: Array<ts.PropertySignature>;
|
|
4
|
+
fulltextIndex?: true;
|
|
5
|
+
indexes?: ts.ArrayLiteralExpression;
|
|
6
|
+
sourceFile: ts.SourceFile;
|
|
7
|
+
enumAttributes: Record<string, string[]>;
|
|
8
|
+
locale: ts.ObjectLiteralExpression;
|
|
9
|
+
toModi: boolean;
|
|
10
|
+
toLog: boolean;
|
|
11
|
+
actionType: string;
|
|
12
|
+
static: boolean;
|
|
13
|
+
inModi: boolean;
|
|
14
|
+
relations: false | string[];
|
|
15
|
+
extendsFrom: string[];
|
|
16
|
+
importAttrFrom: Record<string, [string, string | undefined]>;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function constructAttributes(entity: string): ts.PropertyAssignment[];
|
|
19
|
+
export declare function translateLocaleObject(locale: ts.ObjectLiteralExpression): Record<string, any>;
|
|
1
20
|
/**
|
|
2
21
|
* 此函数不再使用
|
|
3
22
|
* @param map
|
|
@@ -23,6 +42,9 @@ export declare function registerFixedDestinationPathMap(map: Record<string, stri
|
|
|
23
42
|
* @param map
|
|
24
43
|
*/
|
|
25
44
|
export declare function registerDeducedRelationMap(map: Record<string, string>): void;
|
|
45
|
+
export declare const getAnalizedSchema: () => typeof Schema;
|
|
26
46
|
export declare function analyzeEntities(inputDir: string, relativePath?: string): void;
|
|
27
47
|
export declare function buildSchemaBackup(outputDir: string): void;
|
|
48
|
+
export declare function getProjectionKeys(entity: string): string[];
|
|
28
49
|
export declare function buildSchema(outputDir: string): void;
|
|
50
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildSchema = exports.buildSchemaBackup = exports.analyzeEntities = exports.registerDeducedRelationMap = exports.registerFixedDestinationPathMap = exports.registerIgnoredRelationPathMap = exports.registerFreeEntities = exports.registerIgnoredForeignKeyMap = void 0;
|
|
3
|
+
exports.buildSchema = exports.getProjectionKeys = exports.buildSchemaBackup = exports.analyzeEntities = exports.getAnalizedSchema = exports.registerDeducedRelationMap = exports.registerFixedDestinationPathMap = exports.registerIgnoredRelationPathMap = exports.registerFreeEntities = exports.registerIgnoredForeignKeyMap = exports.translateLocaleObject = exports.constructAttributes = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
6
6
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
@@ -2256,6 +2256,64 @@ function _constructOpProjection(statements, entity) {
|
|
|
2256
2256
|
exprNode,
|
|
2257
2257
|
])));
|
|
2258
2258
|
}
|
|
2259
|
+
function getOpProjectionKeys(entity) {
|
|
2260
|
+
const { schemaAttrs, enumAttributes } = Schema[entity];
|
|
2261
|
+
const { [entity]: manyToOneSet } = ManyToOne;
|
|
2262
|
+
const result = [
|
|
2263
|
+
'id',
|
|
2264
|
+
'$$createAt$$',
|
|
2265
|
+
'$$updateAt$$',
|
|
2266
|
+
'$$seq$$',
|
|
2267
|
+
];
|
|
2268
|
+
for (const attr of schemaAttrs) {
|
|
2269
|
+
const { type, name } = attr;
|
|
2270
|
+
const attrName = name.text;
|
|
2271
|
+
if (ts.isTypeReferenceNode(type)) {
|
|
2272
|
+
const { typeName } = type;
|
|
2273
|
+
if (ts.isIdentifier(typeName)) {
|
|
2274
|
+
const typeStr = typeName.text;
|
|
2275
|
+
switch (typeStr) {
|
|
2276
|
+
case 'String':
|
|
2277
|
+
case 'Text':
|
|
2278
|
+
case 'Int':
|
|
2279
|
+
case 'Uint':
|
|
2280
|
+
case 'Float':
|
|
2281
|
+
case 'Double':
|
|
2282
|
+
case 'Boolean':
|
|
2283
|
+
case 'Datetime':
|
|
2284
|
+
case 'Image':
|
|
2285
|
+
case 'File':
|
|
2286
|
+
case 'SingleGeo':
|
|
2287
|
+
case 'Geo':
|
|
2288
|
+
case 'Price':
|
|
2289
|
+
case 'Decimal':
|
|
2290
|
+
result.push(attrName);
|
|
2291
|
+
break;
|
|
2292
|
+
case 'Object':
|
|
2293
|
+
result.push(attrName);
|
|
2294
|
+
break;
|
|
2295
|
+
default: {
|
|
2296
|
+
const refEntity = typeStr === 'Schema' ? entity : typeStr;
|
|
2297
|
+
const isManyToOne = manyToOneSet?.some(([e]) => e === refEntity);
|
|
2298
|
+
if (isManyToOne) {
|
|
2299
|
+
result.push(`${attrName}Id`);
|
|
2300
|
+
}
|
|
2301
|
+
else if (!enumAttributes?.[attrName]) {
|
|
2302
|
+
result.push(attrName);
|
|
2303
|
+
}
|
|
2304
|
+
else {
|
|
2305
|
+
result.push(attrName);
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
else {
|
|
2312
|
+
result.push(attrName);
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
return result;
|
|
2316
|
+
}
|
|
2259
2317
|
/**
|
|
2260
2318
|
* 构造Query
|
|
2261
2319
|
* @param statements
|
|
@@ -3951,6 +4009,26 @@ function constructAttributes(entity) {
|
|
|
3951
4009
|
});
|
|
3952
4010
|
return result;
|
|
3953
4011
|
}
|
|
4012
|
+
exports.constructAttributes = constructAttributes;
|
|
4013
|
+
function translateLocaleObject(locale) {
|
|
4014
|
+
const result = {};
|
|
4015
|
+
locale.properties.forEach((ele) => {
|
|
4016
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele) && (ts.isIdentifier(ele.name) || ts.isStringLiteral(ele.name)), `locale对象中的属性定义不正确`);
|
|
4017
|
+
const name = ele.name.text;
|
|
4018
|
+
if (ts.isStringLiteral(ele.initializer)) {
|
|
4019
|
+
result[name] = ele.initializer.text;
|
|
4020
|
+
}
|
|
4021
|
+
else if (ts.isObjectLiteralExpression(ele.initializer)) {
|
|
4022
|
+
const subObj = translateLocaleObject(ele.initializer);
|
|
4023
|
+
result[name] = subObj;
|
|
4024
|
+
}
|
|
4025
|
+
else {
|
|
4026
|
+
throw new Error(`locale对象中的属性${name}的定义不正确`);
|
|
4027
|
+
}
|
|
4028
|
+
});
|
|
4029
|
+
return result;
|
|
4030
|
+
}
|
|
4031
|
+
exports.translateLocaleObject = translateLocaleObject;
|
|
3954
4032
|
function outputLocale(outputDir, printer) {
|
|
3955
4033
|
const locales = {};
|
|
3956
4034
|
const entities = [];
|
|
@@ -4768,6 +4846,10 @@ function outputStyleDict(outputDir, printer) {
|
|
|
4768
4846
|
const filename = path_1.default.join(outputDir, 'StyleDict.ts');
|
|
4769
4847
|
(0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
|
|
4770
4848
|
}
|
|
4849
|
+
const getAnalizedSchema = () => {
|
|
4850
|
+
return Schema;
|
|
4851
|
+
};
|
|
4852
|
+
exports.getAnalizedSchema = getAnalizedSchema;
|
|
4771
4853
|
function analyzeEntities(inputDir, relativePath) {
|
|
4772
4854
|
const files = (0, fs_1.readdirSync)(inputDir);
|
|
4773
4855
|
const fullFilenames = files.map(ele => {
|
|
@@ -5474,6 +5556,76 @@ function _outputEntityDict(outputDir, printer) {
|
|
|
5474
5556
|
const fileName = path_1.default.join(outputDir, 'EntityDict.ts');
|
|
5475
5557
|
(0, fs_1.writeFileSync)(fileName, result, { flag: 'w' });
|
|
5476
5558
|
}
|
|
5559
|
+
function getProjectionKeys(entity) {
|
|
5560
|
+
const keys = [];
|
|
5561
|
+
const { schemaAttrs } = Schema[entity];
|
|
5562
|
+
const { [entity]: manyToOneSet = [] } = ManyToOne;
|
|
5563
|
+
for (const attr of schemaAttrs) {
|
|
5564
|
+
const { type, name } = attr;
|
|
5565
|
+
const attrName = name.text;
|
|
5566
|
+
if (ts.isTypeReferenceNode(type)) {
|
|
5567
|
+
const typeName = type.typeName;
|
|
5568
|
+
if (ts.isIdentifier(typeName)) {
|
|
5569
|
+
const text = typeName.text;
|
|
5570
|
+
switch (text) {
|
|
5571
|
+
case 'String':
|
|
5572
|
+
case 'Text':
|
|
5573
|
+
case 'Int':
|
|
5574
|
+
case 'Uint':
|
|
5575
|
+
case 'Float':
|
|
5576
|
+
case 'Double':
|
|
5577
|
+
case 'Boolean':
|
|
5578
|
+
case 'Datetime':
|
|
5579
|
+
case 'Image':
|
|
5580
|
+
case 'File':
|
|
5581
|
+
case 'SingleGeo':
|
|
5582
|
+
case 'Geo':
|
|
5583
|
+
case 'Price':
|
|
5584
|
+
case 'Decimal':
|
|
5585
|
+
case 'Object':
|
|
5586
|
+
break;
|
|
5587
|
+
default:
|
|
5588
|
+
const text2 = text === 'Schema' ? entity : text;
|
|
5589
|
+
const manyToOneItem = manyToOneSet.find(([refEntity]) => refEntity === text2);
|
|
5590
|
+
if (manyToOneItem) {
|
|
5591
|
+
keys.push(attrName); // 外键属性
|
|
5592
|
+
}
|
|
5593
|
+
}
|
|
5594
|
+
}
|
|
5595
|
+
}
|
|
5596
|
+
}
|
|
5597
|
+
if (ReversePointerRelations[entity]) {
|
|
5598
|
+
for (const one of ReversePointerRelations[entity]) {
|
|
5599
|
+
const text2 = one === 'Schema' ? entity : one;
|
|
5600
|
+
keys.push((0, string_1.firstLetterLowerCase)(one));
|
|
5601
|
+
}
|
|
5602
|
+
}
|
|
5603
|
+
const { [entity]: oneToManySet = [] } = OneToMany;
|
|
5604
|
+
const foreignKeySet = {};
|
|
5605
|
+
for (const [entityName, foreignKey] of oneToManySet) {
|
|
5606
|
+
if (!foreignKeySet[entityName]) {
|
|
5607
|
+
foreignKeySet[entityName] = [];
|
|
5608
|
+
}
|
|
5609
|
+
foreignKeySet[entityName].push(foreignKey);
|
|
5610
|
+
}
|
|
5611
|
+
for (const entityName in foreignKeySet) {
|
|
5612
|
+
const entityNameLc = (0, string_1.firstLetterLowerCase)(entityName);
|
|
5613
|
+
for (const foreignKey of foreignKeySet[entityName]) {
|
|
5614
|
+
const identifier = `${entityNameLc}$${foreignKey}`;
|
|
5615
|
+
keys.push(identifier);
|
|
5616
|
+
const aggrKey = _getAggrKey(entityNameLc, foreignKey);
|
|
5617
|
+
if (typeof aggrKey === 'string') {
|
|
5618
|
+
keys.push(aggrKey);
|
|
5619
|
+
}
|
|
5620
|
+
else {
|
|
5621
|
+
// 如果是 union 类型,用映射表达式模拟(如 ["xxx$$aggr", `xxx$$${number}$$aggr`])
|
|
5622
|
+
keys.push(`${identifier}$$aggr`);
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
return [...new Set([...keys, ...getOpProjectionKeys(entity)])];
|
|
5627
|
+
}
|
|
5628
|
+
exports.getProjectionKeys = getProjectionKeys;
|
|
5477
5629
|
function _outputSchema(outputDir, printer) {
|
|
5478
5630
|
for (const entity in Schema) {
|
|
5479
5631
|
const statements = [
|
|
@@ -1045,6 +1045,11 @@ class RelationAuth {
|
|
|
1045
1045
|
if (actionAuths && actionAuths.length > 0) {
|
|
1046
1046
|
return checkChildren(actionAuths);
|
|
1047
1047
|
}
|
|
1048
|
+
// 如果这个entity是updateFree,直接过掉到子结点判定
|
|
1049
|
+
const { action, entity } = node;
|
|
1050
|
+
if (this.updateFreeDict[entity] && this.updateFreeDict[entity].includes(action)) {
|
|
1051
|
+
return checkChildren([]);
|
|
1052
|
+
}
|
|
1048
1053
|
// 没有能根据父亲传下来的actionAuth判定,只能自己找
|
|
1049
1054
|
const result = this.findActionAuthsOnNode(node, context);
|
|
1050
1055
|
const checkResult = (result2) => {
|
|
@@ -1083,9 +1088,6 @@ class RelationAuth {
|
|
|
1083
1088
|
}
|
|
1084
1089
|
checkOperation(entity, operation, context) {
|
|
1085
1090
|
const { action, filter, data } = operation;
|
|
1086
|
-
if (this.updateFreeDict[entity] && this.updateFreeDict[entity].includes(action)) {
|
|
1087
|
-
return true;
|
|
1088
|
-
}
|
|
1089
1091
|
const userId = context.getCurrentUserId();
|
|
1090
1092
|
if (!userId) {
|
|
1091
1093
|
throw new types_1.OakUnloggedInException();
|
package/lib/types/Exception.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare class OakException<ED extends EntityDict & BaseEntityDict> extend
|
|
|
12
12
|
name: string;
|
|
13
13
|
message: string;
|
|
14
14
|
_module: string | undefined;
|
|
15
|
+
params: Record<string, any> | undefined;
|
|
15
16
|
opRecords: OpRecord<ED>[];
|
|
16
17
|
tag1: string | undefined;
|
|
17
18
|
tag2: boolean | undefined;
|
package/lib/types/Exception.js
CHANGED
|
@@ -36,7 +36,7 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
36
36
|
opRecords: any;
|
|
37
37
|
message: string | null;
|
|
38
38
|
} | {
|
|
39
|
-
result:
|
|
39
|
+
result: ReadableStream<Uint8Array> | null;
|
|
40
40
|
message: string | null;
|
|
41
41
|
opRecords?: undefined;
|
|
42
42
|
}>;
|
|
@@ -45,7 +45,7 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
45
45
|
opRecords: any;
|
|
46
46
|
message: string | null;
|
|
47
47
|
} | {
|
|
48
|
-
result:
|
|
48
|
+
result: ReadableStream<Uint8Array> | null;
|
|
49
49
|
message: string | null;
|
|
50
50
|
opRecords?: undefined;
|
|
51
51
|
}>;
|
|
@@ -81,8 +81,7 @@ class SimpleConnector {
|
|
|
81
81
|
throw new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
|
|
82
82
|
}
|
|
83
83
|
const message = response.headers.get('oak-message');
|
|
84
|
-
const responseType = response.headers.get('Content-Type') ||
|
|
85
|
-
response.headers.get('content-type');
|
|
84
|
+
const responseType = response.headers.get('Content-Type') || response.headers.get('content-type');
|
|
86
85
|
if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
|
|
87
86
|
const { exception, result, opRecords } = await response.json();
|
|
88
87
|
if (exception) {
|
|
@@ -94,18 +93,24 @@ class SimpleConnector {
|
|
|
94
93
|
message,
|
|
95
94
|
};
|
|
96
95
|
}
|
|
97
|
-
else if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
// else if (
|
|
97
|
+
// responseType
|
|
98
|
+
// ?.toLocaleLowerCase()
|
|
99
|
+
// .match(/application\/octet-stream/i)
|
|
100
|
+
// ) {
|
|
101
|
+
// const result = await response.arrayBuffer();
|
|
102
|
+
// return {
|
|
103
|
+
// result,
|
|
104
|
+
// message,
|
|
105
|
+
// };
|
|
106
|
+
// }
|
|
107
|
+
else {
|
|
108
|
+
const result = response.body;
|
|
101
109
|
return {
|
|
102
110
|
result,
|
|
103
111
|
message,
|
|
104
112
|
};
|
|
105
113
|
}
|
|
106
|
-
else {
|
|
107
|
-
throw new Error(`尚不支持的content-type类型${responseType}`);
|
|
108
|
-
}
|
|
109
114
|
}
|
|
110
115
|
async callAspect(name, params, context) {
|
|
111
116
|
const { headers, body } = await this.makeHeadersAndBody(name, params, context);
|
|
@@ -153,8 +158,7 @@ class SimpleConnector {
|
|
|
153
158
|
throw new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
|
|
154
159
|
}
|
|
155
160
|
const message = response.headers.get('oak-message');
|
|
156
|
-
const responseType = response.headers.get('Content-Type') ||
|
|
157
|
-
response.headers.get('content-type');
|
|
161
|
+
const responseType = response.headers.get('Content-Type') || response.headers.get('content-type');
|
|
158
162
|
if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
|
|
159
163
|
const { socketUrl, subscribeUrl, path } = await response.json();
|
|
160
164
|
return {
|
|
@@ -185,7 +189,7 @@ class SimpleConnector {
|
|
|
185
189
|
};
|
|
186
190
|
}
|
|
187
191
|
async serializeResult(result, opRecords, headers, body, message) {
|
|
188
|
-
if (result instanceof stream_1.Stream || result instanceof Buffer) {
|
|
192
|
+
if (result instanceof stream_1.Stream || result instanceof Buffer || result instanceof ReadableStream) {
|
|
189
193
|
return {
|
|
190
194
|
body: result,
|
|
191
195
|
headers: {
|