oak-domain 5.1.8 → 5.1.10
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/dependencyBuilder.js +56 -3
- package/lib/compiler/schemalBuilder.js +96 -72
- package/lib/store/IntrinsicCheckers.js +1 -1
- package/lib/store/filter.js +1 -1
- package/lib/types/Configuration.d.ts +6 -2
- package/lib/types/Connector.d.ts +5 -4
- package/lib/types/Exception.d.ts +3 -0
- package/lib/types/Exception.js +16 -1
- package/lib/types/Sync.d.ts +1 -0
- package/lib/types/Timer.d.ts +8 -5
- package/lib/types/Watcher.d.ts +1 -0
- package/lib/utils/SimpleConnector.d.ts +10 -6
- package/lib/utils/SimpleConnector.js +45 -14
- package/lib/utils/geo.d.ts +30 -0
- package/lib/utils/geo.js +123 -1
- package/lib/utils/row.js +2 -2
- package/package.json +3 -1
|
@@ -461,7 +461,7 @@ function outputIntializeDev(cwd, dependencies, briefNames, sourceFile, printer,
|
|
|
461
461
|
}
|
|
462
462
|
});
|
|
463
463
|
// startRoutine
|
|
464
|
-
if ((0, fs_1.existsSync)(join(destDir, 'routines', 'start'))) {
|
|
464
|
+
if ((0, fs_1.existsSync)(join(destDir, 'routines', 'start.js'))) {
|
|
465
465
|
const variableName = `${briefNames[idx]}StartRoutines`;
|
|
466
466
|
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, factory.createIdentifier(variableName), undefined), factory.createStringLiteral(join(dep, destDirName, 'routines/start')), undefined));
|
|
467
467
|
if (objectDict.startRoutines) {
|
|
@@ -583,11 +583,30 @@ function outputFeatureIndex(dependencies, briefNames, sourceFile, printer, filen
|
|
|
583
583
|
if (dependencies.length > 0) {
|
|
584
584
|
const importStatements = [];
|
|
585
585
|
const fdNames = [];
|
|
586
|
+
const adNames = [];
|
|
586
587
|
dependencies.forEach((dep, idx) => {
|
|
587
588
|
const fdName = `${(0, string_1.firstLetterUpperCase)(briefNames[idx])}FeatureDict`;
|
|
588
|
-
|
|
589
|
+
const adName = `${(0, string_1.firstLetterUpperCase)(briefNames[idx])}AspectDict`;
|
|
590
|
+
// 导入FeatureDict和AspectDict
|
|
591
|
+
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
|
|
592
|
+
factory.createImportSpecifier(false, factory.createIdentifier("FeatureDict"), factory.createIdentifier(fdName)),
|
|
593
|
+
factory.createImportSpecifier(false, factory.createIdentifier("AspectDict"), factory.createIdentifier(adName))
|
|
594
|
+
])), factory.createStringLiteral(dep), undefined));
|
|
589
595
|
fdNames.push(fdName);
|
|
596
|
+
adNames.push(adName);
|
|
590
597
|
});
|
|
598
|
+
// 导入自己的AspectDict:import { AspectDict } from '../aspects/AspectDict';
|
|
599
|
+
importStatements.push(factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, factory.createIdentifier("AspectDict"), factory.createIdentifier("ProjectAspectDict"))])), factory.createStringLiteral("../aspects/AspectDict"), undefined),
|
|
600
|
+
// import { createService } from 'oak-frontend-base/es/aspects/AspectService';
|
|
601
|
+
factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports([factory.createImportSpecifier(false, undefined, factory.createIdentifier("createService"))])), factory.createStringLiteral("oak-frontend-base/es/aspects/AspectService"), undefined));
|
|
602
|
+
// 创建一个这样的type: type MergeAspectDict = ProjectAspectDict & GenernalAspectDict<EntityDict>;
|
|
603
|
+
// 除了ProjectAspectDict,还有其他的AspectDict,需要<EntityDict>参数
|
|
604
|
+
const adTypeDeclaration = factory.createTypeAliasDeclaration(undefined, factory.createIdentifier("MergeAspectDict"), undefined, factory.createIntersectionTypeNode([
|
|
605
|
+
factory.createTypeReferenceNode(factory.createIdentifier("ProjectAspectDict"), undefined),
|
|
606
|
+
...adNames.map(ad => {
|
|
607
|
+
return factory.createTypeReferenceNode(factory.createIdentifier(ad), [factory.createTypeReferenceNode(factory.createIdentifier("EntityDict"), undefined)]);
|
|
608
|
+
})
|
|
609
|
+
]));
|
|
591
610
|
let i = 0;
|
|
592
611
|
while (true) {
|
|
593
612
|
const stmt = statements[i];
|
|
@@ -599,7 +618,7 @@ function outputFeatureIndex(dependencies, briefNames, sourceFile, printer, filen
|
|
|
599
618
|
const stmt3 = statements[i - 1], stmt4 = statements[i];
|
|
600
619
|
(0, assert_1.default)(ts.isImportDeclaration(stmt3) && ts.isFunctionDeclaration(stmt4));
|
|
601
620
|
const { name, parameters } = stmt4;
|
|
602
|
-
(0, assert_1.default)(ts.isIdentifier(name) && name.text === 'create' && parameters.length === 1);
|
|
621
|
+
(0, assert_1.default)(name && ts.isIdentifier(name) && name.text === 'create' && parameters.length === 1);
|
|
603
622
|
const [param] = parameters;
|
|
604
623
|
const { name: paramName, type } = param;
|
|
605
624
|
(0, assert_1.default)(ts.isIdentifier(paramName) && paramName.text === 'features' && ts.isTypeReferenceNode(type));
|
|
@@ -611,9 +630,43 @@ function outputFeatureIndex(dependencies, briefNames, sourceFile, printer, filen
|
|
|
611
630
|
]))
|
|
612
631
|
])
|
|
613
632
|
});
|
|
633
|
+
const functionBlock = stmt4.body;
|
|
634
|
+
(0, assert_1.default)(functionBlock && ts.isBlock(functionBlock));
|
|
635
|
+
let returnI = 0;
|
|
636
|
+
while (true) {
|
|
637
|
+
const stmt = functionBlock.statements[returnI];
|
|
638
|
+
if (ts.isReturnStatement(stmt)) {
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
641
|
+
returnI++;
|
|
642
|
+
}
|
|
643
|
+
// 在return之前,插入const aspect = createService<EntityDict, MergeAspectDict>(cache);
|
|
644
|
+
const aspectDeclaration = factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("aspect"), undefined, undefined, factory.createCallExpression(factory.createIdentifier("createService"), [
|
|
645
|
+
factory.createTypeReferenceNode(factory.createIdentifier("EntityDict"), undefined),
|
|
646
|
+
factory.createTypeReferenceNode(factory.createIdentifier("MergeAspectDict"), undefined)
|
|
647
|
+
], [factory.createIdentifier("cache")]))], ts.NodeFlags.Const));
|
|
648
|
+
const returnStmt = functionBlock.statements[returnI];
|
|
649
|
+
(0, assert_1.default)(returnStmt.expression && ts.isObjectLiteralExpression(returnStmt.expression));
|
|
650
|
+
// 在里面添加aspect
|
|
651
|
+
const { properties } = returnStmt.expression;
|
|
652
|
+
Object.assign(returnStmt.expression, {
|
|
653
|
+
properties: [
|
|
654
|
+
...properties,
|
|
655
|
+
factory.createShorthandPropertyAssignment(factory.createIdentifier("aspect"))
|
|
656
|
+
]
|
|
657
|
+
});
|
|
658
|
+
// 把aspectDeclaration 插入到return之前
|
|
659
|
+
const newFunctionStatements = [
|
|
660
|
+
...functionBlock.statements.slice(0, returnI),
|
|
661
|
+
aspectDeclaration,
|
|
662
|
+
...functionBlock.statements.slice(returnI)
|
|
663
|
+
];
|
|
664
|
+
const newBlock = factory.createBlock(newFunctionStatements);
|
|
665
|
+
Object.assign(functionBlock, newBlock);
|
|
614
666
|
statements2 = [
|
|
615
667
|
...statements.slice(0, i),
|
|
616
668
|
...importStatements,
|
|
669
|
+
adTypeDeclaration,
|
|
617
670
|
...statements.slice(i)
|
|
618
671
|
];
|
|
619
672
|
if (isModule) {
|
|
@@ -160,7 +160,7 @@ function pushStatementIntoSchemaAst(moduleName, statement, sourceFile) {
|
|
|
160
160
|
*/
|
|
161
161
|
function checkActionDefNameConsistent(filename, actionDefNode) {
|
|
162
162
|
const { name, type } = actionDefNode;
|
|
163
|
-
(0, assert_1.default)(ts.isTypeReferenceNode(type));
|
|
163
|
+
(0, assert_1.default)(ts.isTypeReferenceNode(type), "ActionDef应该是一个类型引用");
|
|
164
164
|
const { typeArguments } = type;
|
|
165
165
|
(0, assert_1.default)(typeArguments.length === 2);
|
|
166
166
|
const [actionNode, stateNode] = typeArguments;
|
|
@@ -189,13 +189,13 @@ function addImportedFrom(moduleName, name, node) {
|
|
|
189
189
|
let propertyName;
|
|
190
190
|
if (typeof node === 'object') {
|
|
191
191
|
const { moduleSpecifier, importClause } = node;
|
|
192
|
-
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier));
|
|
193
|
-
(0, assert_1.default)(importClause);
|
|
192
|
+
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier), `${moduleName}中的${name}未引用正确的moduleSpecifier`);
|
|
193
|
+
(0, assert_1.default)(importClause, `${moduleName}中的${name}未引用正确的importClause`);
|
|
194
194
|
const { namedBindings } = importClause;
|
|
195
|
-
(0, assert_1.default)(namedBindings);
|
|
195
|
+
(0, assert_1.default)(namedBindings, `${moduleName}中的${name}未引用正确的namedBindings`);
|
|
196
196
|
(0, assert_1.default)(ts.isNamedImports(namedBindings));
|
|
197
197
|
const importSpecifier = namedBindings.elements.find((ele) => ele.name.text === name);
|
|
198
|
-
(0, assert_1.default)(importSpecifier);
|
|
198
|
+
(0, assert_1.default)(importSpecifier, `${moduleName}中的${name}未引用正确的importSpecifier`);
|
|
199
199
|
propertyName = importSpecifier.propertyName && importSpecifier.propertyName.text;
|
|
200
200
|
importFrom = moduleSpecifier.text;
|
|
201
201
|
}
|
|
@@ -210,7 +210,7 @@ function addImportedFrom(moduleName, name, node) {
|
|
|
210
210
|
});
|
|
211
211
|
}
|
|
212
212
|
else {
|
|
213
|
-
(0, assert_1.default)(name.endsWith("State"));
|
|
213
|
+
(0, assert_1.default)(name.endsWith("State"), `${moduleName}中的${name}未以State结尾`);
|
|
214
214
|
(0, lodash_1.assign)(ast.importStateFrom, {
|
|
215
215
|
[name]: [importFrom, propertyName],
|
|
216
216
|
});
|
|
@@ -226,15 +226,15 @@ function analyzeExternalAttrImport(node, program, importAttrFrom, relativePath)
|
|
|
226
226
|
if (ts.isImportSpecifier(declaration)) {
|
|
227
227
|
const name = declaration.name.text;
|
|
228
228
|
const importDeclartion = declaration.parent.parent.parent;
|
|
229
|
-
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion));
|
|
229
|
+
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion), `未找到${name}的importDeclaration`);
|
|
230
230
|
const { moduleSpecifier, importClause } = importDeclartion;
|
|
231
|
-
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier));
|
|
232
|
-
(0, assert_1.default)(importClause);
|
|
231
|
+
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier), `未找到${name}的moduleSpecifier`);
|
|
232
|
+
(0, assert_1.default)(importClause, `未找到${name}的importClause`);
|
|
233
233
|
const { namedBindings } = importClause;
|
|
234
|
-
(0, assert_1.default)(namedBindings);
|
|
235
|
-
(0, assert_1.default)(ts.isNamedImports(namedBindings));
|
|
234
|
+
(0, assert_1.default)(namedBindings, `未找到${name}的namedBindings`);
|
|
235
|
+
(0, assert_1.default)(ts.isNamedImports(namedBindings), `未找到${name}的namedImports`);
|
|
236
236
|
const importSpecifier = namedBindings.elements.find((ele) => ele.name.text === name);
|
|
237
|
-
(0, assert_1.default)(importSpecifier);
|
|
237
|
+
(0, assert_1.default)(importSpecifier, `未找到${name}的importSpecifier`);
|
|
238
238
|
const propertyName = importSpecifier.propertyName && importSpecifier.propertyName.text;
|
|
239
239
|
const importFrom = moduleSpecifier.text;
|
|
240
240
|
const importFromRelatively = importFrom.startsWith('.') ? (relativePath
|
|
@@ -282,7 +282,7 @@ function tryGetStringLiteralValues(moduleName, filename, obj, node, program) {
|
|
|
282
282
|
if (['state', 'action'].includes(obj)) {
|
|
283
283
|
(0, assert_1.default)(values.length > 0, `${filename}中的${obj} ${node.typeName.getText()}未定义`);
|
|
284
284
|
const importDeclartion = declaration.parent.parent.parent;
|
|
285
|
-
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion));
|
|
285
|
+
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion), '未找到importDeclaration');
|
|
286
286
|
addImportedFrom(moduleName, declaration.name.text, importDeclartion);
|
|
287
287
|
}
|
|
288
288
|
}
|
|
@@ -307,7 +307,7 @@ function tryGetStringLiteralValues(moduleName, filename, obj, node, program) {
|
|
|
307
307
|
values.push(action);
|
|
308
308
|
}
|
|
309
309
|
if (['state', 'action'].includes(obj)) {
|
|
310
|
-
(0, assert_1.default)(values.length > 0);
|
|
310
|
+
(0, assert_1.default)(values.length > 0, `${filename}中的${obj} ${node.typeName.getText()}未定义`);
|
|
311
311
|
const ast = ActionAsts[moduleName];
|
|
312
312
|
addImportedFrom(moduleName, declaration.name.text, './');
|
|
313
313
|
}
|
|
@@ -340,8 +340,9 @@ function dealWithActionTypeNode(moduleName, filename, actionTypeNode, program, s
|
|
|
340
340
|
(0, assert_1.default)((0, lodash_1.intersection)(actionNames, RESERVED_ACTION_NAMES).length === 0, `${filename}中的Action命名不能是「${RESERVED_ACTION_NAMES.join(',')}」之一`);
|
|
341
341
|
actionTypeNode.types.forEach(ele => {
|
|
342
342
|
if (ts.isTypeReferenceNode(ele)) {
|
|
343
|
+
// 这里递归了类型定义,去查找所有的action字符串
|
|
343
344
|
const actionStrings = tryGetStringLiteralValues(moduleName, filename, 'action', ele, program);
|
|
344
|
-
(0, assert_1.default)(actionStrings.length > 0);
|
|
345
|
+
(0, assert_1.default)(actionStrings.length > 0, `${filename}中的Action所引用的Type定义为空`);
|
|
345
346
|
actionTexts.push(...actionStrings);
|
|
346
347
|
}
|
|
347
348
|
else {
|
|
@@ -355,7 +356,7 @@ function dealWithActionTypeNode(moduleName, filename, actionTypeNode, program, s
|
|
|
355
356
|
(0, assert_1.default)(!RESERVED_ACTION_NAMES.includes(actionTypeNode.typeName.text), `${filename}中的Action命名不能是「${RESERVED_ACTION_NAMES.join(',')}」之一`);
|
|
356
357
|
}
|
|
357
358
|
const actionStrings = tryGetStringLiteralValues(moduleName, filename, 'action', actionTypeNode, program);
|
|
358
|
-
(0, assert_1.default)(actionStrings.length > 0);
|
|
359
|
+
(0, assert_1.default)(actionStrings.length > 0, `${filename}中的Action定义为空`);
|
|
359
360
|
actionTexts.push(...actionStrings);
|
|
360
361
|
}
|
|
361
362
|
else {
|
|
@@ -383,10 +384,10 @@ function dealWithActionDefInitializer(moduleName, initializer, program) {
|
|
|
383
384
|
// 是从别处的引用,注入到mportActionDefFrom
|
|
384
385
|
const checker = program.getTypeChecker();
|
|
385
386
|
const identifier = ts.isIdentifier(initializer) ? initializer : initializer.expression;
|
|
386
|
-
(0, assert_1.default)(ts.isIdentifier(identifier));
|
|
387
|
+
(0, assert_1.default)(ts.isIdentifier(identifier), "ActionDef的initializer不是一个Identifier");
|
|
387
388
|
const symbol = checker.getSymbolAtLocation(identifier);
|
|
388
389
|
const declaration = symbol?.getDeclarations()[0];
|
|
389
|
-
(0, assert_1.default)(ts.isImportSpecifier(declaration));
|
|
390
|
+
(0, assert_1.default)(ts.isImportSpecifier(declaration), "ActionDef的initializer不是一个ImportSpecifier");
|
|
390
391
|
const importDeclartion = declaration.parent.parent.parent;
|
|
391
392
|
addImportedFrom(moduleName, identifier.text, importDeclartion);
|
|
392
393
|
}
|
|
@@ -419,7 +420,7 @@ function getEntityImported(declaration) {
|
|
|
419
420
|
function checkLocaleEnumAttrs(node, attrs, filename) {
|
|
420
421
|
const { members } = node;
|
|
421
422
|
const memberKeys = members.map((ele) => {
|
|
422
|
-
(0, assert_1.default)(ts.isPropertySignature(ele) && ts.isIdentifier(ele.name));
|
|
423
|
+
(0, assert_1.default)(ts.isPropertySignature(ele) && ts.isIdentifier(ele.name), 'locale定义中的属性必须是identifier');
|
|
423
424
|
return ele.name.text;
|
|
424
425
|
});
|
|
425
426
|
const lack = (0, lodash_1.difference)(attrs, memberKeys);
|
|
@@ -433,7 +434,7 @@ function checkLocaleExpressionPropertyExists(root, attr, exists, filename) {
|
|
|
433
434
|
(0, assert_1.default)(ts.isPropertyAssignment(ele) && (ts.isIdentifier(ele.name) || ts.isStringLiteral(ele.name)) && ts.isObjectLiteralExpression(ele.initializer));
|
|
434
435
|
const { properties: p2 } = ele.initializer;
|
|
435
436
|
const pp = p2.find((ele2) => {
|
|
436
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele2) && ts.isIdentifier(ele2.name));
|
|
437
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele2) && ts.isIdentifier(ele2.name), 'locale定义中的属性必须是identifier');
|
|
437
438
|
return ele2.name.text === attr;
|
|
438
439
|
});
|
|
439
440
|
if (exists && !pp) {
|
|
@@ -565,6 +566,38 @@ function analyzeImportDeclaration(node, referencedSchemas, additionalImports, fi
|
|
|
565
566
|
} */
|
|
566
567
|
}
|
|
567
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* 处理模块的导入,得到导入文件的sourcefile
|
|
571
|
+
*/
|
|
572
|
+
function dealImportedFile(path, fileSpecifierPath, filename, program) {
|
|
573
|
+
let importedFilepath = '';
|
|
574
|
+
const getExistedFileName = () => {
|
|
575
|
+
if ((0, fs_1.existsSync)(`${importedFilepath}.ts`)) {
|
|
576
|
+
return `${importedFilepath}.ts`;
|
|
577
|
+
}
|
|
578
|
+
else if ((0, fs_1.existsSync)(`${importedFilepath}.d.ts`)) {
|
|
579
|
+
return `${importedFilepath}.d.ts`;
|
|
580
|
+
}
|
|
581
|
+
return '';
|
|
582
|
+
};
|
|
583
|
+
if (fileSpecifierPath.startsWith('.')) {
|
|
584
|
+
importedFilepath = path_1.default.join(path, fileSpecifierPath);
|
|
585
|
+
const importedFilename = getExistedFileName();
|
|
586
|
+
(0, assert_1.default)(importedFilename, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
587
|
+
const sourceFile = program.getSourceFile(importedFilename);
|
|
588
|
+
(0, assert_1.default)(sourceFile, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
589
|
+
return [sourceFile, importedFilename];
|
|
590
|
+
}
|
|
591
|
+
// 创建编译器主机
|
|
592
|
+
const compilerHost = ts.createCompilerHost(program.getCompilerOptions());
|
|
593
|
+
// 解析模块
|
|
594
|
+
const resolvedModule = ts.resolveModuleName(fileSpecifierPath, filename, program.getCompilerOptions(), compilerHost);
|
|
595
|
+
(0, assert_1.default)(resolvedModule.resolvedModule, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
596
|
+
const pathName = resolvedModule.resolvedModule.resolvedFileName;
|
|
597
|
+
const sourceFile = program.getSourceFile(pathName);
|
|
598
|
+
(0, assert_1.default)(sourceFile, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
599
|
+
return [sourceFile, pathName];
|
|
600
|
+
}
|
|
568
601
|
/**
|
|
569
602
|
* 在path下的filename文件中import了fileSpecifierPath,要找到其对应的引用路径
|
|
570
603
|
* 这里关键是要处理形如file:的依赖声明
|
|
@@ -594,7 +627,7 @@ function analyzeImportDeclaration(node, referencedSchemas, additionalImports, fi
|
|
|
594
627
|
// const cwd = process.cwd();
|
|
595
628
|
// const fileSpecifierPaths = fileSpecifierPath.split('/');
|
|
596
629
|
// const moduleName = fileSpecifierPaths[0] || fileSpecifierPaths[1];
|
|
597
|
-
// assert(moduleName);
|
|
630
|
+
// assert(moduleName, '「${filename}」中import路径不合法');
|
|
598
631
|
// // 从path向外找package.json -> node_modules直至找到fileSpecifier
|
|
599
632
|
// const paths = path.split('/');
|
|
600
633
|
// for (let iter = paths.length; iter >= 0; iter--) {
|
|
@@ -628,37 +661,28 @@ function analyzeSchemaDefinition(node, moduleName, filename, path, program, refe
|
|
|
628
661
|
let toLog = false;
|
|
629
662
|
const extendsFrom = [];
|
|
630
663
|
const { members, heritageClauses } = node;
|
|
631
|
-
(0, assert_1.default)(heritageClauses);
|
|
664
|
+
(0, assert_1.default)(heritageClauses, `「${filename}」中的Schema定义需要继承EntityShape或者其他Entity`);
|
|
632
665
|
const heritagedResult = heritageClauses.map((clause) => {
|
|
633
666
|
const { expression } = clause.types[0];
|
|
634
|
-
(0, assert_1.default)(ts.isIdentifier(expression));
|
|
667
|
+
(0, assert_1.default)(ts.isIdentifier(expression), `${expression}不是一个合法的继承类型`);
|
|
635
668
|
if (expression.text === 'EntityShape') {
|
|
636
669
|
// import { EntityShape } from 'oak-domain/lib/types/Entities; 所有schema的公共祖先类型,不用处理
|
|
637
670
|
return;
|
|
638
671
|
}
|
|
639
672
|
// 从其它文件的Schema类继承,这里需要将所继承的对象的属性进行访问并展开
|
|
640
|
-
(0, assert_1.default)(referencedSchemas.includes(expression.text));
|
|
673
|
+
(0, assert_1.default)(referencedSchemas.includes(expression.text), `「${filename}」中的Schema继承了未定义的实体「${expression.text}」`);
|
|
641
674
|
const checker = program.getTypeChecker();
|
|
642
675
|
const symbol = checker.getSymbolAtLocation(expression);
|
|
643
676
|
let declaration = symbol?.getDeclarations()[0];
|
|
644
|
-
(0, assert_1.default)(ts.isImportSpecifier(declaration));
|
|
677
|
+
(0, assert_1.default)(ts.isImportSpecifier(declaration), `${declaration.getText()}应该是导入的类型`);
|
|
645
678
|
const importDeclaration = declaration.parent.parent.parent;
|
|
646
|
-
(0, assert_1.default)(ts.isImportDeclaration(importDeclaration));
|
|
679
|
+
(0, assert_1.default)(ts.isImportDeclaration(importDeclaration), `${declaration.getText()}应该是导入的类型`);
|
|
647
680
|
const { moduleSpecifier } = importDeclaration;
|
|
648
|
-
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier));
|
|
681
|
+
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier), `${declaration.getText()}应该是导入的类型`);
|
|
649
682
|
const { text: from } = moduleSpecifier;
|
|
650
683
|
extendsFrom.push(from);
|
|
651
|
-
|
|
652
|
-
const
|
|
653
|
-
// 解析模块
|
|
654
|
-
const resolvedModule = ts.resolveModuleName(from, filename, program.getCompilerOptions(), compilerHost);
|
|
655
|
-
(0, assert_1.default)(resolvedModule.resolvedModule, "找不到module定义");
|
|
656
|
-
const resolvedFileName = resolvedModule.resolvedModule.resolvedFileName;
|
|
657
|
-
const sourceFile = program.getSourceFile(resolvedFileName);
|
|
658
|
-
// const importedFilename = getImportedFilePath(path, from, filename);
|
|
659
|
-
// const sourceFile = program.getSourceFile(importedFilename);
|
|
660
|
-
(0, assert_1.default)(sourceFile, `「${filename}」找不到相应的sourceFile:${resolvedFileName}`);
|
|
661
|
-
const relativeFilename = path_1.default.relative(process.cwd(), resolvedFileName);
|
|
684
|
+
const [sourceFile, pathName] = dealImportedFile(path, from, filename, program);
|
|
685
|
+
const relativeFilename = path_1.default.relative(process.cwd(), pathName);
|
|
662
686
|
const result = analyzeReferenceSchemaFile(moduleName, path_1.default.basename(relativeFilename), path_1.default.dirname(relativeFilename), sourceFile, program, referencedSchemas, schemaAttrs, enumAttributes, importAttrFrom, path_1.default.join(from, '..'));
|
|
663
687
|
return result;
|
|
664
688
|
}).filter(ele => !!ele);
|
|
@@ -738,7 +762,7 @@ function analyzeSchemaDefinition(node, moduleName, filename, path, program, refe
|
|
|
738
762
|
else {
|
|
739
763
|
schemaAttrs.push(attrNode);
|
|
740
764
|
if (ts.isUnionTypeNode(type) && ts.isLiteralTypeNode(type.types[0]) && ts.isStringLiteral(type.types[0].literal)) {
|
|
741
|
-
(0, assert_1.default)(ts.isIdentifier(name));
|
|
765
|
+
(0, assert_1.default)(ts.isIdentifier(name), `「${filename}」中的属性定义不是String类型`);
|
|
742
766
|
const { types } = type;
|
|
743
767
|
const enumValues = types.map((ele) => checkStringLiteralLegal(filename, '属性', name.text, ele));
|
|
744
768
|
enumAttributes[name.text] = enumValues;
|
|
@@ -833,13 +857,13 @@ function analyzeReferenceSchemaFile(moduleName, filename, path, sourceFile, prog
|
|
|
833
857
|
}
|
|
834
858
|
}
|
|
835
859
|
});
|
|
836
|
-
(0, assert_1.default)(result);
|
|
860
|
+
(0, assert_1.default)(result, `「${filename}」中没有找到Schema定义`);
|
|
837
861
|
return result;
|
|
838
862
|
}
|
|
839
863
|
function analyzeEntity(filename, path, program, relativePath) {
|
|
840
864
|
const fullPath = `${path}/${filename}`;
|
|
841
865
|
const sourceFile = program.getSourceFile(fullPath);
|
|
842
|
-
(0, assert_1.default)(sourceFile);
|
|
866
|
+
(0, assert_1.default)(sourceFile, `「${filename}」文件不存在`);
|
|
843
867
|
const moduleName = filename.split('.')[0];
|
|
844
868
|
if (Schema.hasOwnProperty(moduleName)) {
|
|
845
869
|
delete ActionAsts[moduleName];
|
|
@@ -926,13 +950,13 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
926
950
|
(0, assert_1.default)(!localeDef, `【${filename}】locale定义须在Relation之后`);
|
|
927
951
|
const relationValues = [];
|
|
928
952
|
if (ts.isLiteralTypeNode(node.type)) {
|
|
929
|
-
(0, assert_1.default)(ts.isStringLiteral(node.type.literal));
|
|
953
|
+
(0, assert_1.default)(ts.isStringLiteral(node.type.literal), `${filename}中的Relation的定义只能是string类型`);
|
|
930
954
|
(0, assert_1.default)(node.type.literal.text.length < env_1.STRING_LITERAL_MAX_LENGTH, `Relation定义的字符串长度不长于${env_1.STRING_LITERAL_MAX_LENGTH}(${filename},${node.type.literal.text})`);
|
|
931
955
|
relationValues.push(node.type.literal.text);
|
|
932
956
|
}
|
|
933
957
|
else if (ts.isTypeReferenceNode(node.type)) {
|
|
934
958
|
const relationStrings = tryGetStringLiteralValues(moduleName, filename, 'relation', node.type, program);
|
|
935
|
-
(0, assert_1.default)(relationStrings.length > 0);
|
|
959
|
+
(0, assert_1.default)(relationStrings.length > 0, `文件${filename}中的relation${node.type.typeName.text}定义未找到字符串类型`);
|
|
936
960
|
relationValues.push(...relationStrings);
|
|
937
961
|
}
|
|
938
962
|
else {
|
|
@@ -946,7 +970,7 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
946
970
|
else {
|
|
947
971
|
(0, assert_1.default)(ts.isTypeReferenceNode(ele), `Relation的定义只能是string类型,或者string union类型,或者两者的union(${filename})`);
|
|
948
972
|
const relationStrings = tryGetStringLiteralValues(moduleName, filename, 'relation', ele, program);
|
|
949
|
-
(0, assert_1.default)(relationStrings.length > 0);
|
|
973
|
+
(0, assert_1.default)(relationStrings.length > 0, `文件${filename}中的relation${ele.typeName.text}定义未找到字符串类型`);
|
|
950
974
|
relationValues.push(...relationStrings);
|
|
951
975
|
}
|
|
952
976
|
});
|
|
@@ -998,7 +1022,7 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
998
1022
|
]) : type), sourceFile);
|
|
999
1023
|
}
|
|
1000
1024
|
else {
|
|
1001
|
-
(0, assert_1.default)(ts.isLiteralTypeNode(type) || ts.isTypeReferenceNode(type),
|
|
1025
|
+
(0, assert_1.default)(ts.isLiteralTypeNode(type) || ts.isTypeReferenceNode(type), `文件${filename}中的${type.getText()}应该是字面量或引用类型`);
|
|
1002
1026
|
pushStatementIntoActionAst(moduleName, factory.updateTypeAliasDeclaration(node, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], node.name, node.typeParameters, process.env.COMPLING_AS_LIB ? factory.createUnionTypeNode([
|
|
1003
1027
|
type,
|
|
1004
1028
|
factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
@@ -1015,12 +1039,12 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1015
1039
|
const dealWithActionDef = (declaration) => {
|
|
1016
1040
|
checkActionDefNameConsistent(filename, declaration);
|
|
1017
1041
|
const { typeArguments } = declaration.type;
|
|
1018
|
-
(0, assert_1.default)(typeArguments.length === 2);
|
|
1042
|
+
(0, assert_1.default)(typeArguments.length === 2, `文件${filename}中的action定义不是两个泛型参数`);
|
|
1019
1043
|
const [actionNode, stateNode] = typeArguments;
|
|
1020
|
-
(0, assert_1.default)(ts.isTypeReferenceNode(actionNode));
|
|
1044
|
+
(0, assert_1.default)(ts.isTypeReferenceNode(actionNode), `文件${filename}中的action定义不是TypeReferenceNode`);
|
|
1021
1045
|
// 这里有可能引用的Action不是本文件的定义,要调用这个函数加到importFrom中
|
|
1022
1046
|
tryGetStringLiteralValues(moduleName, filename, 'action', actionNode, program);
|
|
1023
|
-
(0, assert_1.default)(ts.isTypeReferenceNode(stateNode));
|
|
1047
|
+
(0, assert_1.default)(ts.isTypeReferenceNode(stateNode), `文件${filename}中的action定义不是TypeReferenceNode`);
|
|
1024
1048
|
const enumStateValues = tryGetStringLiteralValues(moduleName, filename, 'state', stateNode, program);
|
|
1025
1049
|
(0, assert_1.default)(enumStateValues.length > 0, `文件${filename}中的state${stateNode.typeName.text}定义不是字符串类型`);
|
|
1026
1050
|
pushStatementIntoActionAst(moduleName, node, sourceFile);
|
|
@@ -1037,18 +1061,18 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1037
1061
|
const { elements } = declaration;
|
|
1038
1062
|
elements.forEach((ele) => {
|
|
1039
1063
|
let isFulltextIndex = false;
|
|
1040
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(ele));
|
|
1064
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(ele), `「${filename}」中索引定义应该是对象字面量`);
|
|
1041
1065
|
const { properties } = ele;
|
|
1042
1066
|
const attrProperty = properties.find((ele2) => {
|
|
1043
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1067
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele2), `「${filename}」中索引的属性不为PropertyAssignment`);
|
|
1044
1068
|
return ele2.name.getText() === 'attributes';
|
|
1045
1069
|
});
|
|
1046
|
-
(0, assert_1.default)(ts.isArrayLiteralExpression(attrProperty.initializer));
|
|
1070
|
+
(0, assert_1.default)(ts.isArrayLiteralExpression(attrProperty.initializer), `「${filename}」中索引的attributes属性应该是数组字面量`);
|
|
1047
1071
|
const nameProperty = properties.find((ele2) => {
|
|
1048
1072
|
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1049
1073
|
return ele2.name.getText() === 'name';
|
|
1050
1074
|
});
|
|
1051
|
-
(0, assert_1.default)(ts.isStringLiteral(nameProperty.initializer));
|
|
1075
|
+
(0, assert_1.default)(ts.isStringLiteral(nameProperty.initializer), '「${filename}」中索引的name属性应该是字符串字面量');
|
|
1052
1076
|
const nameText = nameProperty.initializer.text;
|
|
1053
1077
|
if (indexNameDict[nameText]) {
|
|
1054
1078
|
throw new Error(`「${filename}」索引定义重名「${nameText}」`);
|
|
@@ -1057,14 +1081,14 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1057
1081
|
[nameText]: true,
|
|
1058
1082
|
});
|
|
1059
1083
|
const configProperty = properties.find((ele2) => {
|
|
1060
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1084
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele2), `「${filename}」中索引的属性不为PropertyAssignment`);
|
|
1061
1085
|
return ele2.name.getText() === 'config';
|
|
1062
1086
|
});
|
|
1063
1087
|
if (configProperty) {
|
|
1064
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(configProperty.initializer));
|
|
1088
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(configProperty.initializer), `「${filename}」中索引的config属性应该是对象字面量`);
|
|
1065
1089
|
const { properties: properties2 } = configProperty.initializer;
|
|
1066
1090
|
const typeProperty = properties2.find((ele2) => {
|
|
1067
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1091
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele2), `「${filename}」中索引的属性不为PropertyAssignment`);
|
|
1068
1092
|
return ele2.name.getText() === 'type';
|
|
1069
1093
|
});
|
|
1070
1094
|
if (typeProperty && typeProperty.initializer.text === 'fulltext') {
|
|
@@ -1179,21 +1203,21 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1179
1203
|
if (ts.isObjectLiteralExpression(declaration)) {
|
|
1180
1204
|
const { properties } = declaration;
|
|
1181
1205
|
const localesProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'locales');
|
|
1182
|
-
(0, assert_1.default)(ts.isPropertyAssignment(localesProperty));
|
|
1206
|
+
(0, assert_1.default)(ts.isPropertyAssignment(localesProperty), `「${filename}」中entityDesc的locales应该是属性声明`);
|
|
1183
1207
|
dealWithLocales(localesProperty.initializer);
|
|
1184
1208
|
const indexesProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'indexes');
|
|
1185
1209
|
if (indexesProperty) {
|
|
1186
|
-
(0, assert_1.default)(ts.isPropertyAssignment(indexesProperty));
|
|
1210
|
+
(0, assert_1.default)(ts.isPropertyAssignment(indexesProperty), `「${filename}」中entityDesc的indexes应该是属性声明`);
|
|
1187
1211
|
dealWithIndexes(indexesProperty.initializer);
|
|
1188
1212
|
}
|
|
1189
1213
|
const configurationProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'configuration');
|
|
1190
1214
|
if (configurationProperty) {
|
|
1191
|
-
(0, assert_1.default)(ts.isPropertyAssignment(configurationProperty));
|
|
1215
|
+
(0, assert_1.default)(ts.isPropertyAssignment(configurationProperty), `「${filename}」中entityDesc的configuration应该是属性声明`);
|
|
1192
1216
|
dealWithConfiguration(configurationProperty.initializer);
|
|
1193
1217
|
}
|
|
1194
1218
|
const styleDescProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'style');
|
|
1195
1219
|
if (styleDescProperty) {
|
|
1196
|
-
(0, assert_1.default)(ts.isPropertyAssignment(styleDescProperty));
|
|
1220
|
+
(0, assert_1.default)(ts.isPropertyAssignment(styleDescProperty), `「${filename}」中entityDesc的style应该是属性声明`);
|
|
1197
1221
|
dealWithStyleDesc(styleDescProperty.initializer);
|
|
1198
1222
|
}
|
|
1199
1223
|
}
|
|
@@ -1224,14 +1248,14 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1224
1248
|
&& declaration.type.typeArguments[0].typeName.text === 'Index')) {
|
|
1225
1249
|
// 对索引Index的定义
|
|
1226
1250
|
console.log(`「${filename}」直接定义indexes的写法已经过时,请定义在entityDesc中`);
|
|
1227
|
-
(0, assert_1.default)(ts.isArrayLiteralExpression(declaration.initializer));
|
|
1251
|
+
(0, assert_1.default)(ts.isArrayLiteralExpression(declaration.initializer), `「${filename}」中索引定义应该是数组字面量`);
|
|
1228
1252
|
dealWithIndexes(declaration.initializer);
|
|
1229
1253
|
}
|
|
1230
1254
|
else if (declaration.type && ts.isTypeReferenceNode(declaration.type) && ts.isIdentifier(declaration.type.typeName) && declaration.type.typeName.text === 'LocaleDef') {
|
|
1231
1255
|
// locale定义
|
|
1232
1256
|
console.log(`「${filename}」直接定义locales的写法已经过时,请定义在entityDesc中`);
|
|
1233
1257
|
const { type, initializer } = declaration;
|
|
1234
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(initializer));
|
|
1258
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(initializer), `「${filename}」中locale定义应该是对象字面量`);
|
|
1235
1259
|
const { properties } = initializer;
|
|
1236
1260
|
(0, assert_1.default)(properties.length > 0, `${filename}至少需要有一种locale定义`);
|
|
1237
1261
|
const allEnumStringAttrs = Object.keys(enumAttributes);
|
|
@@ -1268,12 +1292,12 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1268
1292
|
}
|
|
1269
1293
|
else if (declaration.type && ts.isTypeReferenceNode(declaration.type) && ts.isIdentifier(declaration.type.typeName) && declaration.type.typeName.text === 'Configuration') {
|
|
1270
1294
|
console.log(`「${filename}」直接定义configuration的写法已经过时,请定义在entityDesc中`);
|
|
1271
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(declaration.initializer));
|
|
1295
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(declaration.initializer), `「${filename}」中configuration定义应该是对象字面量`);
|
|
1272
1296
|
dealWithConfiguration(declaration.initializer);
|
|
1273
1297
|
}
|
|
1274
1298
|
else if (declaration.type && ts.isTypeReferenceNode(declaration.type) && ts.isIdentifier(declaration.type.typeName) && declaration.type.typeName.text === 'EntityDesc') {
|
|
1275
1299
|
const { initializer } = declaration;
|
|
1276
|
-
(0, assert_1.default)(initializer);
|
|
1300
|
+
(0, assert_1.default)(initializer, `「${filename}」中entityDesc的定义不应该为空`);
|
|
1277
1301
|
dealWithEntityDesc(initializer);
|
|
1278
1302
|
}
|
|
1279
1303
|
else {
|
|
@@ -1617,7 +1641,7 @@ function constructFilter(statements, entity) {
|
|
|
1617
1641
|
}
|
|
1618
1642
|
else {
|
|
1619
1643
|
// 此时应当是引用本地定义的shape
|
|
1620
|
-
(0, assert_1.default)(type);
|
|
1644
|
+
(0, assert_1.default)(type, `${entity}中的属性${name.toString()}有非法的属性类型定义`);
|
|
1621
1645
|
members.push(factory.createPropertySignature(undefined, name, undefined, factory.createTypeReferenceNode(factory.createIdentifier('JsonFilter'), [
|
|
1622
1646
|
type
|
|
1623
1647
|
])));
|
|
@@ -3118,7 +3142,7 @@ function outputSchema(outputDir, printer) {
|
|
|
3118
3142
|
const fromLocalActionSpecifiers = ['Action', 'ParticularAction'];
|
|
3119
3143
|
const fromExtenalStates = {};
|
|
3120
3144
|
for (const state in importStateFrom) {
|
|
3121
|
-
(0, assert_1.default)(state.endsWith('State'));
|
|
3145
|
+
(0, assert_1.default)(state.endsWith('State'), `${state} should end with State`);
|
|
3122
3146
|
if (importStateFrom[state][0] === './') {
|
|
3123
3147
|
// 本地定义的State从 ./Action 中获取
|
|
3124
3148
|
fromLocalActionSpecifiers.push(state);
|
|
@@ -3247,7 +3271,7 @@ function outputAction(outputDir, printer) {
|
|
|
3247
3271
|
const importStatements = [];
|
|
3248
3272
|
const fromExternalImports = {};
|
|
3249
3273
|
for (const state in importStateFrom) {
|
|
3250
|
-
(0, assert_1.default)(state.endsWith('State'));
|
|
3274
|
+
(0, assert_1.default)(state.endsWith('State'), `${state} should end with State`);
|
|
3251
3275
|
const [from, propertyName] = importStateFrom[state];
|
|
3252
3276
|
if (from !== './') {
|
|
3253
3277
|
if (fromExternalImports[from]) {
|
|
@@ -3259,7 +3283,7 @@ function outputAction(outputDir, printer) {
|
|
|
3259
3283
|
}
|
|
3260
3284
|
}
|
|
3261
3285
|
for (const action in importActionFrom) {
|
|
3262
|
-
(0, assert_1.default)(action.endsWith('Action'));
|
|
3286
|
+
(0, assert_1.default)(action.endsWith('Action'), `${action} should end with Action`);
|
|
3263
3287
|
const [from, propertyName] = importActionFrom[action];
|
|
3264
3288
|
if (from !== './') {
|
|
3265
3289
|
if (fromExternalImports[from]) {
|
|
@@ -3271,7 +3295,7 @@ function outputAction(outputDir, printer) {
|
|
|
3271
3295
|
}
|
|
3272
3296
|
}
|
|
3273
3297
|
for (const def in importActionDefFrom) {
|
|
3274
|
-
(0, assert_1.default)(def.endsWith('ActionDef'));
|
|
3298
|
+
(0, assert_1.default)(def.endsWith('ActionDef'), `${def} should end with ActionDef`);
|
|
3275
3299
|
const [from, propertyName] = importActionDefFrom[def];
|
|
3276
3300
|
if (from !== './') {
|
|
3277
3301
|
if (fromExternalImports[from]) {
|
|
@@ -3413,11 +3437,11 @@ function constructAttributes(entity) {
|
|
|
3413
3437
|
if (ts.isUnionTypeNode(type)) {
|
|
3414
3438
|
if (ts.isLiteralTypeNode(type.types[0])) {
|
|
3415
3439
|
if (ts.isStringLiteral(type.types[0].literal)) {
|
|
3416
|
-
(0, assert_1.default)(enumAttributes && enumAttributes[name.text]);
|
|
3440
|
+
(0, assert_1.default)(enumAttributes && enumAttributes[name.text], `${entity}对象中的${name.text}属性没有定义enumAttributes`);
|
|
3417
3441
|
attrAssignments.push(factory.createPropertyAssignment('type', factory.createStringLiteral("enum")), factory.createPropertyAssignment('enumeration', factory.createArrayLiteralExpression(enumAttributes[name.text].map(ele => factory.createStringLiteral(ele)))));
|
|
3418
3442
|
}
|
|
3419
3443
|
else {
|
|
3420
|
-
(0, assert_1.default)(ts.isNumericLiteral(type.types[0].literal));
|
|
3444
|
+
(0, assert_1.default)(ts.isNumericLiteral(type.types[0].literal), `${entity}对象中的${type.types[0].literal.getText()}属性不是数字`);
|
|
3421
3445
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("int")), factory.createPropertyAssignment(factory.createIdentifier("params"), factory.createObjectLiteralExpression([
|
|
3422
3446
|
factory.createPropertyAssignment(factory.createIdentifier("width"), factory.createNumericLiteral(env_1.INT_LITERL_DEFAULT_WIDTH))
|
|
3423
3447
|
], true)));
|
|
@@ -3434,7 +3458,7 @@ function constructAttributes(entity) {
|
|
|
3434
3458
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("varchar")), factory.createPropertyAssignment(factory.createIdentifier("params"), factory.createObjectLiteralExpression([factory.createPropertyAssignment(factory.createIdentifier("length"), factory.createNumericLiteral(env_1.STRING_LITERAL_MAX_LENGTH))], true)));
|
|
3435
3459
|
}
|
|
3436
3460
|
else {
|
|
3437
|
-
(0, assert_1.default)(ts.isNumericLiteral(type.literal));
|
|
3461
|
+
(0, assert_1.default)(ts.isNumericLiteral(type.literal), `${entity}对象中的${name.text}属性不是数字`);
|
|
3438
3462
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("precision")), factory.createPropertyAssignment(factory.createIdentifier("params"), factory.createObjectLiteralExpression([
|
|
3439
3463
|
factory.createPropertyAssignment(factory.createIdentifier("precision"), factory.createNumericLiteral(env_1.NUMERICAL_LITERL_DEFAULT_PRECISION)),
|
|
3440
3464
|
factory.createPropertyAssignment(factory.createIdentifier("scale"), factory.createNumericLiteral(env_1.NUMERICAL_LITERL_DEFAULT_SCALE))
|
|
@@ -3459,7 +3483,7 @@ function outputLocale(outputDir, printer) {
|
|
|
3459
3483
|
if (locale) {
|
|
3460
3484
|
const { properties } = locale;
|
|
3461
3485
|
properties.forEach((ele) => {
|
|
3462
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele) && (ts.isIdentifier(ele.name) || ts.isStringLiteral(ele.name)) && ts.isObjectLiteralExpression(ele.initializer));
|
|
3486
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele) && (ts.isIdentifier(ele.name) || ts.isStringLiteral(ele.name)) && ts.isObjectLiteralExpression(ele.initializer), `${entity}对象中的locale属性定义不正确`);
|
|
3463
3487
|
const lng = ele.name.text;
|
|
3464
3488
|
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray([
|
|
3465
3489
|
factory.createReturnStatement(ele.initializer)
|
|
@@ -269,7 +269,7 @@ function cascadelyCheckUpdateFilters(entity, schema, data, filter, matrix, restA
|
|
|
269
269
|
* 先找到能直接更新成功的属性
|
|
270
270
|
*/
|
|
271
271
|
const legalAttrResult = restAttrs.map((attr) => {
|
|
272
|
-
const { filter: f } = matrix[attr];
|
|
272
|
+
const { filter: f } = matrix[attr] || {};
|
|
273
273
|
if (!f) {
|
|
274
274
|
return true;
|
|
275
275
|
}
|
package/lib/store/filter.js
CHANGED
|
@@ -1621,7 +1621,7 @@ function checkDeduceFilters(dfc, context) {
|
|
|
1621
1621
|
* @returns
|
|
1622
1622
|
*/
|
|
1623
1623
|
function checkFilterContains(entity, context, contained, filter, dataCompare, warningOnDataCompare) {
|
|
1624
|
-
(0, assert_1.default)(filter);
|
|
1624
|
+
(0, assert_1.default)(filter, `对${entity}的访问必须有filter`);
|
|
1625
1625
|
const schema = context.getSchema();
|
|
1626
1626
|
const result = contains(entity, schema, filter, contained);
|
|
1627
1627
|
if (typeof result === 'boolean') {
|
|
@@ -29,11 +29,14 @@ export type ServerConfiguration = {
|
|
|
29
29
|
socketPath: string;
|
|
30
30
|
};
|
|
31
31
|
cors?: {
|
|
32
|
-
origin: string;
|
|
32
|
+
origin: string | string[];
|
|
33
33
|
headers?: string[];
|
|
34
34
|
methods?: string[];
|
|
35
35
|
};
|
|
36
36
|
internalExceptionMask?: string;
|
|
37
|
+
koaBody?: {
|
|
38
|
+
maxFileSize?: number;
|
|
39
|
+
};
|
|
37
40
|
};
|
|
38
41
|
/**
|
|
39
42
|
* 前后台访问配置
|
|
@@ -42,16 +45,17 @@ export type AccessConfiguration = {
|
|
|
42
45
|
routerPrefixes?: {
|
|
43
46
|
aspect?: string;
|
|
44
47
|
endpoint?: string;
|
|
45
|
-
subscribe?: string;
|
|
46
48
|
getSubscribePoint?: string;
|
|
47
49
|
bridge?: string;
|
|
48
50
|
};
|
|
51
|
+
socketPath?: string;
|
|
49
52
|
http: {
|
|
50
53
|
hostname: string;
|
|
51
54
|
port?: number;
|
|
52
55
|
ssl?: boolean;
|
|
53
56
|
path?: string;
|
|
54
57
|
};
|
|
58
|
+
timeout?: number;
|
|
55
59
|
};
|
|
56
60
|
/**
|
|
57
61
|
* 业务逻辑的通用配置
|
package/lib/types/Connector.d.ts
CHANGED
|
@@ -26,10 +26,11 @@ export interface Connector<ED extends EntityDict & BaseEntityDict, FrontCxt exte
|
|
|
26
26
|
};
|
|
27
27
|
headers?: Record<string, any>;
|
|
28
28
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
getSocketPath: () => string;
|
|
30
|
+
getSocketPointRouter: () => string;
|
|
31
|
+
getSocketPoint: () => Promise<{
|
|
32
|
+
socketUrl: string;
|
|
33
|
+
subscribeUrl: string;
|
|
33
34
|
path: string;
|
|
34
35
|
}>;
|
|
35
36
|
getBridgeRouter: () => string;
|
package/lib/types/Exception.d.ts
CHANGED
|
@@ -19,6 +19,9 @@ export declare class OakException<ED extends EntityDict & BaseEntityDict> extend
|
|
|
19
19
|
tag2?: boolean;
|
|
20
20
|
tag3?: any;
|
|
21
21
|
}
|
|
22
|
+
export declare class OakRequestTimeoutException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
23
|
+
constructor(message?: string);
|
|
24
|
+
}
|
|
22
25
|
export declare class OakMakeSureByMySelfException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
23
26
|
}
|
|
24
27
|
export declare class OakPartialSuccess<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
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.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.OakClockDriftException = 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.OakClockDriftException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = exports.OakRequestTimeoutException = exports.OakException = void 0;
|
|
4
4
|
const relation_1 = require("../store/relation");
|
|
5
5
|
const lodash_1 = require("../utils/lodash");
|
|
6
6
|
class OakException extends Error {
|
|
@@ -90,6 +90,13 @@ class OakException extends Error {
|
|
|
90
90
|
tag3;
|
|
91
91
|
}
|
|
92
92
|
exports.OakException = OakException;
|
|
93
|
+
// 请求超时
|
|
94
|
+
class OakRequestTimeoutException extends OakException {
|
|
95
|
+
constructor(message) {
|
|
96
|
+
super(message || '请求超时');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.OakRequestTimeoutException = OakRequestTimeoutException;
|
|
93
100
|
// 这个异常表示模块自己处理跨事务一致性,框架pass(在分布式数据传递时会用到)(backend-base老版本有使用先保留)
|
|
94
101
|
class OakMakeSureByMySelfException extends OakException {
|
|
95
102
|
}
|
|
@@ -495,6 +502,14 @@ function makeException(data) {
|
|
|
495
502
|
e = new OakSocketConnectException(data.message);
|
|
496
503
|
break;
|
|
497
504
|
}
|
|
505
|
+
case 'OakPartialSuccess': {
|
|
506
|
+
e = new OakPartialSuccess(data.message);
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
case 'OakRequestTimeoutException': {
|
|
510
|
+
e = new OakRequestTimeoutException(data.message);
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
498
513
|
default:
|
|
499
514
|
return;
|
|
500
515
|
}
|
package/lib/types/Sync.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export interface SyncRemoteConfig<ED extends EntityDict & BaseEntityDict, Cxt ex
|
|
|
76
76
|
}[];
|
|
77
77
|
reason: Error;
|
|
78
78
|
}, context: Cxt) => Promise<void>;
|
|
79
|
+
timeout?: number;
|
|
79
80
|
}
|
|
80
81
|
export interface SyncSelfConfigBase<ED extends EntityDict & BaseEntityDict> {
|
|
81
82
|
endpoint?: string;
|
package/lib/types/Timer.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { RecurrenceRule, RecurrenceSpecDateRange, RecurrenceSpecObjLit } from 'node-schedule';
|
|
2
|
-
import { EntityDict } from './Entity';
|
|
2
|
+
import { EntityDict, OperationResult } from './Entity';
|
|
3
3
|
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
4
4
|
import { AsyncContext } from '../store/AsyncRowStore';
|
|
5
5
|
import { Watcher } from './Watcher';
|
|
6
|
-
import {
|
|
7
|
-
type
|
|
6
|
+
import { Namespace } from 'socket.io';
|
|
7
|
+
type FreeRoutineFn<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = (context: Cxt, env: {
|
|
8
|
+
socket: Namespace;
|
|
9
|
+
}) => Promise<OperationResult<ED>>;
|
|
10
|
+
type FreeTimerFn<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = (context: Cxt) => Promise<OperationResult<ED>>;
|
|
8
11
|
export type FreeRoutine<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = {
|
|
9
12
|
name: string;
|
|
10
|
-
routine:
|
|
13
|
+
routine: FreeRoutineFn<ED, Cxt>;
|
|
11
14
|
};
|
|
12
15
|
export type FreeTimer<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = {
|
|
13
16
|
name: string;
|
|
14
17
|
cron: RecurrenceRule | RecurrenceSpecDateRange | RecurrenceSpecObjLit | Date | string | number;
|
|
15
|
-
timer:
|
|
18
|
+
timer: FreeTimerFn<ED, Cxt>;
|
|
16
19
|
singleton?: true;
|
|
17
20
|
};
|
|
18
21
|
export type Routine<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> = FreeRoutine<ED, Cxt> | Watcher<ED, T, Cxt>;
|
package/lib/types/Watcher.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface WBWatcher<ED extends EntityDict & BaseEntityDict, T extends key
|
|
|
17
17
|
filter: ED[T]['Selection']['filter'] | (() => Promise<ED[T]['Selection']['filter']>);
|
|
18
18
|
projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>);
|
|
19
19
|
fn: (context: Cxt, data: Partial<ED[T]['Schema']>[]) => Promise<OperationResult<ED>>;
|
|
20
|
+
forUpdate?: true;
|
|
20
21
|
singleton?: true;
|
|
21
22
|
}
|
|
22
23
|
export type Watcher<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> = BBWatcher<ED, T> | WBWatcher<ED, T, Cxt>;
|
|
@@ -7,8 +7,9 @@ import { AccessConfiguration } from '../types/Configuration';
|
|
|
7
7
|
export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, FrontCxt extends SyncContext<ED>> implements Connector<ED, FrontCxt> {
|
|
8
8
|
static ASPECT_ROUTER: string;
|
|
9
9
|
static BRIDGE_ROUTER: string;
|
|
10
|
-
static
|
|
11
|
-
static
|
|
10
|
+
static SUBSCRIBE_PATH: string;
|
|
11
|
+
static SOCKET_PATH: string;
|
|
12
|
+
static SOCKET_POINT_ROUTER: string;
|
|
12
13
|
static ENDPOINT_ROUTER: string;
|
|
13
14
|
private serverUrl;
|
|
14
15
|
private serverAspectUrl;
|
|
@@ -16,6 +17,7 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
16
17
|
private serverSubscribePointUrl;
|
|
17
18
|
private configuration;
|
|
18
19
|
private makeException;
|
|
20
|
+
private timeout;
|
|
19
21
|
constructor(configuration: AccessConfiguration, makeException: (exceptionData: any) => OakException<ED>);
|
|
20
22
|
getCorsHeader(): string[];
|
|
21
23
|
protected makeHeadersAndBody(name: string, data: any, context?: FrontCxt): Promise<{
|
|
@@ -47,11 +49,12 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
47
49
|
opRecords?: undefined;
|
|
48
50
|
}>;
|
|
49
51
|
getRouter(): string;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
url: any;
|
|
52
|
+
getSocketPath(): string;
|
|
53
|
+
getSocketPointRouter(): string;
|
|
54
|
+
getSocketPoint(): Promise<{
|
|
54
55
|
path: any;
|
|
56
|
+
subscribeUrl: any;
|
|
57
|
+
socketUrl: any;
|
|
55
58
|
}>;
|
|
56
59
|
getEndpointRouter(): string;
|
|
57
60
|
parseRequest(headers: IncomingHttpHeaders, body?: any, files?: any): {
|
|
@@ -80,4 +83,5 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
80
83
|
headers?: Record<string, string> | undefined;
|
|
81
84
|
};
|
|
82
85
|
getFullData(): Promise<{}>;
|
|
86
|
+
private fetchWithTimeout;
|
|
83
87
|
}
|
|
@@ -8,8 +8,9 @@ const types_1 = require("../types");
|
|
|
8
8
|
class SimpleConnector {
|
|
9
9
|
static ASPECT_ROUTER = '/aspect';
|
|
10
10
|
static BRIDGE_ROUTER = '/bridge';
|
|
11
|
-
static
|
|
12
|
-
static
|
|
11
|
+
static SUBSCRIBE_PATH = process.env.OAK_SUBSCRIBE_PATH || '/subscribe';
|
|
12
|
+
static SOCKET_PATH = process.env.OAK_SOCKET_PATH || '/socket';
|
|
13
|
+
static SOCKET_POINT_ROUTER = '/socketPoint';
|
|
13
14
|
static ENDPOINT_ROUTER = '/endpoint';
|
|
14
15
|
serverUrl;
|
|
15
16
|
serverAspectUrl;
|
|
@@ -17,9 +18,11 @@ class SimpleConnector {
|
|
|
17
18
|
serverSubscribePointUrl;
|
|
18
19
|
configuration;
|
|
19
20
|
makeException;
|
|
21
|
+
timeout;
|
|
20
22
|
constructor(configuration, makeException) {
|
|
21
23
|
this.configuration = configuration;
|
|
22
|
-
const { routerPrefixes, http } = configuration;
|
|
24
|
+
const { routerPrefixes, http, timeout } = configuration;
|
|
25
|
+
this.timeout = timeout || 5000;
|
|
23
26
|
const { ssl, hostname, port, path } = http;
|
|
24
27
|
const protocol = ssl ? 'https:' : 'http:';
|
|
25
28
|
let serverUrl = `${protocol}//${hostname}`;
|
|
@@ -38,7 +41,7 @@ class SimpleConnector {
|
|
|
38
41
|
this.serverAspectUrl = `${serverUrl}${routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER}`;
|
|
39
42
|
this.serverBridgeUrl = `${serverUrl}${routerPrefixes?.bridge || SimpleConnector.BRIDGE_ROUTER}`;
|
|
40
43
|
this.serverSubscribePointUrl = `${serverUrl}${routerPrefixes?.getSubscribePoint ||
|
|
41
|
-
SimpleConnector.
|
|
44
|
+
SimpleConnector.SOCKET_POINT_ROUTER}`;
|
|
42
45
|
this.makeException = makeException;
|
|
43
46
|
}
|
|
44
47
|
getCorsHeader() {
|
|
@@ -107,11 +110,11 @@ class SimpleConnector {
|
|
|
107
110
|
const { headers, body } = await this.makeHeadersAndBody(name, params, context);
|
|
108
111
|
let response;
|
|
109
112
|
try {
|
|
110
|
-
response = await
|
|
113
|
+
response = await this.fetchWithTimeout(this.serverAspectUrl, {
|
|
111
114
|
method: 'POST',
|
|
112
115
|
headers,
|
|
113
116
|
body,
|
|
114
|
-
});
|
|
117
|
+
}, this.timeout);
|
|
115
118
|
}
|
|
116
119
|
catch (err) {
|
|
117
120
|
// fetch返回异常一定是网络异常
|
|
@@ -122,16 +125,19 @@ class SimpleConnector {
|
|
|
122
125
|
getRouter() {
|
|
123
126
|
return this.configuration.routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER;
|
|
124
127
|
}
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
/* getSubscribePath(): string {
|
|
129
|
+
return this.configuration.socketPath?.subscribe || SimpleConnector.SUBSCRIBE_PATH;
|
|
130
|
+
} */
|
|
131
|
+
getSocketPath() {
|
|
132
|
+
return this.configuration.socketPath || SimpleConnector.SOCKET_PATH;
|
|
127
133
|
}
|
|
128
|
-
|
|
129
|
-
return this.configuration.routerPrefixes?.getSubscribePoint || SimpleConnector.
|
|
134
|
+
getSocketPointRouter() {
|
|
135
|
+
return this.configuration.routerPrefixes?.getSubscribePoint || SimpleConnector.SOCKET_POINT_ROUTER;
|
|
130
136
|
}
|
|
131
|
-
async
|
|
137
|
+
async getSocketPoint() {
|
|
132
138
|
let response;
|
|
133
139
|
try {
|
|
134
|
-
response = await
|
|
140
|
+
response = await this.fetchWithTimeout(this.serverSubscribePointUrl, {}, this.timeout);
|
|
135
141
|
}
|
|
136
142
|
catch (err) {
|
|
137
143
|
throw new types_1.OakNetworkException();
|
|
@@ -144,10 +150,11 @@ class SimpleConnector {
|
|
|
144
150
|
const responseType = response.headers.get('Content-Type') ||
|
|
145
151
|
response.headers.get('content-type');
|
|
146
152
|
if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
|
|
147
|
-
const {
|
|
153
|
+
const { socketUrl, subscribeUrl, path } = await response.json();
|
|
148
154
|
return {
|
|
149
|
-
url,
|
|
150
155
|
path,
|
|
156
|
+
subscribeUrl,
|
|
157
|
+
socketUrl,
|
|
151
158
|
};
|
|
152
159
|
}
|
|
153
160
|
else {
|
|
@@ -226,5 +233,29 @@ class SimpleConnector {
|
|
|
226
233
|
console.error('前后台模式下暂时不支持此操作,请到数据库查看数据');
|
|
227
234
|
return {};
|
|
228
235
|
}
|
|
236
|
+
async fetchWithTimeout(url, options, timeout = 5000) {
|
|
237
|
+
if (typeof AbortController === 'undefined') {
|
|
238
|
+
return global.fetch(url, options);
|
|
239
|
+
}
|
|
240
|
+
const controller = new AbortController();
|
|
241
|
+
const signal = controller.signal;
|
|
242
|
+
// 设置超时
|
|
243
|
+
const timeoutId = setTimeout(() => {
|
|
244
|
+
controller.abort();
|
|
245
|
+
}, timeout);
|
|
246
|
+
// 发起 fetch 请求并传递 signal
|
|
247
|
+
return global.fetch(url, Object.assign({}, options, { signal }))
|
|
248
|
+
.then(response => {
|
|
249
|
+
clearTimeout(timeoutId); // 如果请求成功,清除超时
|
|
250
|
+
return response;
|
|
251
|
+
})
|
|
252
|
+
.catch(error => {
|
|
253
|
+
clearTimeout(timeoutId); // 如果请求失败,清除超时
|
|
254
|
+
if (error.name === 'AbortError') {
|
|
255
|
+
throw new types_1.OakRequestTimeoutException();
|
|
256
|
+
}
|
|
257
|
+
throw error; // 其他错误
|
|
258
|
+
});
|
|
259
|
+
}
|
|
229
260
|
}
|
|
230
261
|
exports.default = SimpleConnector;
|
package/lib/utils/geo.d.ts
CHANGED
|
@@ -2,3 +2,33 @@
|
|
|
2
2
|
* 计算地球上两点之间的球面距离
|
|
3
3
|
*/
|
|
4
4
|
export declare function getDistanceBetweenPoints(lat1: number, lon1: number, lat2: number, lon2: number): number;
|
|
5
|
+
/**
|
|
6
|
+
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
|
|
7
|
+
* 即 百度 转 谷歌、高德
|
|
8
|
+
* @param bd_lon
|
|
9
|
+
* @param bd_lat
|
|
10
|
+
* @returns {*[]}
|
|
11
|
+
*/
|
|
12
|
+
export declare function bd09togcj02(coord: [number, number]): number[];
|
|
13
|
+
/**
|
|
14
|
+
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
|
|
15
|
+
* 即谷歌、高德 转 百度
|
|
16
|
+
* @param lng
|
|
17
|
+
* @param lat
|
|
18
|
+
* @returns {*[]}
|
|
19
|
+
*/
|
|
20
|
+
export declare function gcj02tobd09(coord: [number, number]): number[];
|
|
21
|
+
/**
|
|
22
|
+
* WGS84转GCj02
|
|
23
|
+
* @param lng
|
|
24
|
+
* @param lat
|
|
25
|
+
* @returns {*[]}
|
|
26
|
+
*/
|
|
27
|
+
export declare function wgs84togcj02(coord: [number, number]): number[];
|
|
28
|
+
/**
|
|
29
|
+
* GCJ02 转换为 WGS84
|
|
30
|
+
* @param lng
|
|
31
|
+
* @param lat
|
|
32
|
+
* @returns {*[]}
|
|
33
|
+
*/
|
|
34
|
+
export declare function gcj02towgs84(coord: [number, number]): number[];
|
package/lib/utils/geo.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDistanceBetweenPoints = void 0;
|
|
3
|
+
exports.gcj02towgs84 = exports.wgs84togcj02 = exports.gcj02tobd09 = exports.bd09togcj02 = exports.getDistanceBetweenPoints = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* 计算地球上两点之间的球面距离
|
|
6
6
|
*/
|
|
@@ -22,3 +22,125 @@ function getDistanceBetweenPoints(lat1, lon1, lat2, lon2) {
|
|
|
22
22
|
return d * 1000;
|
|
23
23
|
}
|
|
24
24
|
exports.getDistanceBetweenPoints = getDistanceBetweenPoints;
|
|
25
|
+
//定义一些常量
|
|
26
|
+
const x_PI = 3.14159265358979324 * 3000.0 / 180.0;
|
|
27
|
+
const PI = 3.1415926535897932384626;
|
|
28
|
+
const a = 6378245.0;
|
|
29
|
+
const ee = 0.00669342162296594323;
|
|
30
|
+
function transformlat(lng, lat) {
|
|
31
|
+
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
|
|
32
|
+
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
|
|
33
|
+
ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
|
|
34
|
+
ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
|
|
35
|
+
return ret;
|
|
36
|
+
}
|
|
37
|
+
;
|
|
38
|
+
function transformlng(lng, lat) {
|
|
39
|
+
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
|
|
40
|
+
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
|
|
41
|
+
ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
|
|
42
|
+
ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
|
|
43
|
+
return ret;
|
|
44
|
+
}
|
|
45
|
+
;
|
|
46
|
+
/**
|
|
47
|
+
* 判断是否在国内,不在国内则不做偏移
|
|
48
|
+
* @param lng
|
|
49
|
+
* @param lat
|
|
50
|
+
* @returns {boolean}
|
|
51
|
+
*/
|
|
52
|
+
function out_of_china(lng, lat) {
|
|
53
|
+
// 纬度3.86~53.55,经度73.66~135.05
|
|
54
|
+
return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
|
|
55
|
+
}
|
|
56
|
+
;
|
|
57
|
+
/**
|
|
58
|
+
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
|
|
59
|
+
* 即 百度 转 谷歌、高德
|
|
60
|
+
* @param bd_lon
|
|
61
|
+
* @param bd_lat
|
|
62
|
+
* @returns {*[]}
|
|
63
|
+
*/
|
|
64
|
+
function bd09togcj02(coord) {
|
|
65
|
+
const [bd_lon, bd_lat] = coord;
|
|
66
|
+
const x = bd_lon - 0.0065;
|
|
67
|
+
const y = bd_lat - 0.006;
|
|
68
|
+
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
|
|
69
|
+
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
|
|
70
|
+
const gg_lng = z * Math.cos(theta);
|
|
71
|
+
const gg_lat = z * Math.sin(theta);
|
|
72
|
+
return [gg_lng, gg_lat];
|
|
73
|
+
}
|
|
74
|
+
exports.bd09togcj02 = bd09togcj02;
|
|
75
|
+
;
|
|
76
|
+
/**
|
|
77
|
+
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
|
|
78
|
+
* 即谷歌、高德 转 百度
|
|
79
|
+
* @param lng
|
|
80
|
+
* @param lat
|
|
81
|
+
* @returns {*[]}
|
|
82
|
+
*/
|
|
83
|
+
function gcj02tobd09(coord) {
|
|
84
|
+
const [lng, lat] = coord;
|
|
85
|
+
const z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
|
|
86
|
+
const theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
|
|
87
|
+
const bd_lng = z * Math.cos(theta) + 0.0065;
|
|
88
|
+
const bd_lat = z * Math.sin(theta) + 0.006;
|
|
89
|
+
return [bd_lng, bd_lat];
|
|
90
|
+
}
|
|
91
|
+
exports.gcj02tobd09 = gcj02tobd09;
|
|
92
|
+
;
|
|
93
|
+
/**
|
|
94
|
+
* WGS84转GCj02
|
|
95
|
+
* @param lng
|
|
96
|
+
* @param lat
|
|
97
|
+
* @returns {*[]}
|
|
98
|
+
*/
|
|
99
|
+
function wgs84togcj02(coord) {
|
|
100
|
+
const [lng, lat] = coord;
|
|
101
|
+
if (out_of_china(lng, lat)) {
|
|
102
|
+
return [lng, lat];
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
let dlat = transformlat(lng - 105.0, lat - 35.0);
|
|
106
|
+
let dlng = transformlng(lng - 105.0, lat - 35.0);
|
|
107
|
+
const radlat = lat / 180.0 * PI;
|
|
108
|
+
let magic = Math.sin(radlat);
|
|
109
|
+
magic = 1 - ee * magic * magic;
|
|
110
|
+
const sqrtmagic = Math.sqrt(magic);
|
|
111
|
+
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
|
|
112
|
+
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
|
|
113
|
+
const mglat = lat + dlat;
|
|
114
|
+
const mglng = lng + dlng;
|
|
115
|
+
return [mglng, mglat];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.wgs84togcj02 = wgs84togcj02;
|
|
119
|
+
;
|
|
120
|
+
/**
|
|
121
|
+
* GCJ02 转换为 WGS84
|
|
122
|
+
* @param lng
|
|
123
|
+
* @param lat
|
|
124
|
+
* @returns {*[]}
|
|
125
|
+
*/
|
|
126
|
+
function gcj02towgs84(coord) {
|
|
127
|
+
const [lng, lat] = coord;
|
|
128
|
+
if (out_of_china(lng, lat)) {
|
|
129
|
+
return [lng, lat];
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
let dlat = transformlat(lng - 105.0, lat - 35.0);
|
|
133
|
+
let dlng = transformlng(lng - 105.0, lat - 35.0);
|
|
134
|
+
const radlat = lat / 180.0 * PI;
|
|
135
|
+
let magic = Math.sin(radlat);
|
|
136
|
+
magic = 1 - ee * magic * magic;
|
|
137
|
+
const sqrtmagic = Math.sqrt(magic);
|
|
138
|
+
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
|
|
139
|
+
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
|
|
140
|
+
const mglat = lat + dlat;
|
|
141
|
+
const mglng = lng + dlng;
|
|
142
|
+
return [lng * 2 - mglng, lat * 2 - mglat];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.gcj02towgs84 = gcj02towgs84;
|
|
146
|
+
;
|
package/lib/utils/row.js
CHANGED
|
@@ -6,8 +6,8 @@ const lodash_1 = require("./lodash");
|
|
|
6
6
|
const relation_1 = require("../store/relation");
|
|
7
7
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
8
8
|
function compareRow(schema, entity, row1, row2) {
|
|
9
|
-
const attrs1 = Object.keys(row1).filter(ele => !ele.startsWith('$$'));
|
|
10
|
-
const attrs2 = Object.keys(row2).filter(ele => !ele.startsWith('$$'));
|
|
9
|
+
const attrs1 = Object.keys(row1 || {}).filter(ele => !ele.startsWith('$$'));
|
|
10
|
+
const attrs2 = Object.keys(row2 || {}).filter(ele => !ele.startsWith('$$'));
|
|
11
11
|
if ((0, lodash_1.difference)(attrs1, attrs2).length > 0) {
|
|
12
12
|
return false;
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oak-domain",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.10",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "XuChang"
|
|
6
6
|
},
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"@types/node": "^20.6.1",
|
|
30
30
|
"@types/node-schedule": "^2.1.0",
|
|
31
31
|
"@types/react": "^17.0.2",
|
|
32
|
+
"@types/socket.io": "^3.0.2",
|
|
32
33
|
"@types/uuid": "^8.3.0",
|
|
33
34
|
"@types/wechat-miniprogram": "^3.4.1",
|
|
34
35
|
"assert": "^2.0.0",
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
"dependencies": {
|
|
46
47
|
"dayjs": "^1.11.9",
|
|
47
48
|
"node-schedule": "^2.1.1",
|
|
49
|
+
"socket.io": "^4.7.2",
|
|
48
50
|
"uuid": "^9.0.0",
|
|
49
51
|
"webidl-conversions": "^5.0.0"
|
|
50
52
|
}
|