oak-domain 5.1.7 → 5.1.9
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.js +137 -105
- package/lib/entities/I18n.js +1 -1
- package/lib/store/IntrinsicCheckers.js +2 -1
- package/lib/store/TriggerExecutor.js +9 -6
- package/lib/store/filter.js +1 -1
- package/lib/store/triggers.js +11 -27
- package/lib/types/Configuration.d.ts +2 -2
- package/lib/types/Connector.d.ts +6 -4
- package/lib/types/Exception.d.ts +3 -1
- package/lib/types/Exception.js +11 -3
- package/lib/types/Timer.d.ts +8 -5
- package/lib/types/Watcher.d.ts +1 -0
- package/lib/utils/SimpleConnector.d.ts +14 -8
- package/lib/utils/SimpleConnector.js +22 -10
- package/lib/utils/row.js +2 -2
- package/package.json +3 -1
- package/src/entities/I18n.ts +1 -1
|
@@ -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;
|
|
@@ -173,7 +173,8 @@ function checkActionDefNameConsistent(filename, actionDefNode) {
|
|
|
173
173
|
const adfName = name.text.slice(0, name.text.length - 9);
|
|
174
174
|
const aName = actionNode.typeName.text.slice(0, actionNode.typeName.text.length - 6);
|
|
175
175
|
const sName = stateNode.typeName.text.slice(0, stateNode.typeName.text.length - 5);
|
|
176
|
-
(0, assert_1.default)(adfName === aName && aName === sName, `文件${filename}中的ActionDef${name.text}中ActionDef, Action和State
|
|
176
|
+
(0, assert_1.default)(adfName === aName && aName === sName, `文件${filename}中的ActionDef${name.text}中ActionDef, Action和State的命名规则不一致, 需要
|
|
177
|
+
${adfName}ActionDef, ${adfName}Action, ${adfName}State`);
|
|
177
178
|
}
|
|
178
179
|
function checkStringLiteralLegal(filename, obj, text, ele) {
|
|
179
180
|
(0, assert_1.default)(ts.isLiteralTypeNode(ele) && ts.isStringLiteral(ele.literal), `${filename}中引用的${obj} ${text}中存在不是stringliteral的类型`);
|
|
@@ -188,13 +189,13 @@ function addImportedFrom(moduleName, name, node) {
|
|
|
188
189
|
let propertyName;
|
|
189
190
|
if (typeof node === 'object') {
|
|
190
191
|
const { moduleSpecifier, importClause } = node;
|
|
191
|
-
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier));
|
|
192
|
-
(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`);
|
|
193
194
|
const { namedBindings } = importClause;
|
|
194
|
-
(0, assert_1.default)(namedBindings);
|
|
195
|
+
(0, assert_1.default)(namedBindings, `${moduleName}中的${name}未引用正确的namedBindings`);
|
|
195
196
|
(0, assert_1.default)(ts.isNamedImports(namedBindings));
|
|
196
197
|
const importSpecifier = namedBindings.elements.find((ele) => ele.name.text === name);
|
|
197
|
-
(0, assert_1.default)(importSpecifier);
|
|
198
|
+
(0, assert_1.default)(importSpecifier, `${moduleName}中的${name}未引用正确的importSpecifier`);
|
|
198
199
|
propertyName = importSpecifier.propertyName && importSpecifier.propertyName.text;
|
|
199
200
|
importFrom = moduleSpecifier.text;
|
|
200
201
|
}
|
|
@@ -209,7 +210,7 @@ function addImportedFrom(moduleName, name, node) {
|
|
|
209
210
|
});
|
|
210
211
|
}
|
|
211
212
|
else {
|
|
212
|
-
(0, assert_1.default)(name.endsWith("State"));
|
|
213
|
+
(0, assert_1.default)(name.endsWith("State"), `${moduleName}中的${name}未以State结尾`);
|
|
213
214
|
(0, lodash_1.assign)(ast.importStateFrom, {
|
|
214
215
|
[name]: [importFrom, propertyName],
|
|
215
216
|
});
|
|
@@ -225,15 +226,15 @@ function analyzeExternalAttrImport(node, program, importAttrFrom, relativePath)
|
|
|
225
226
|
if (ts.isImportSpecifier(declaration)) {
|
|
226
227
|
const name = declaration.name.text;
|
|
227
228
|
const importDeclartion = declaration.parent.parent.parent;
|
|
228
|
-
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion));
|
|
229
|
+
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion), `未找到${name}的importDeclaration`);
|
|
229
230
|
const { moduleSpecifier, importClause } = importDeclartion;
|
|
230
|
-
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier));
|
|
231
|
-
(0, assert_1.default)(importClause);
|
|
231
|
+
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier), `未找到${name}的moduleSpecifier`);
|
|
232
|
+
(0, assert_1.default)(importClause, `未找到${name}的importClause`);
|
|
232
233
|
const { namedBindings } = importClause;
|
|
233
|
-
(0, assert_1.default)(namedBindings);
|
|
234
|
-
(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`);
|
|
235
236
|
const importSpecifier = namedBindings.elements.find((ele) => ele.name.text === name);
|
|
236
|
-
(0, assert_1.default)(importSpecifier);
|
|
237
|
+
(0, assert_1.default)(importSpecifier, `未找到${name}的importSpecifier`);
|
|
237
238
|
const propertyName = importSpecifier.propertyName && importSpecifier.propertyName.text;
|
|
238
239
|
const importFrom = moduleSpecifier.text;
|
|
239
240
|
const importFromRelatively = importFrom.startsWith('.') ? (relativePath
|
|
@@ -279,9 +280,9 @@ function tryGetStringLiteralValues(moduleName, filename, obj, node, program) {
|
|
|
279
280
|
}).filter(ele => !!ele));
|
|
280
281
|
}
|
|
281
282
|
if (['state', 'action'].includes(obj)) {
|
|
282
|
-
(0, assert_1.default)(values.length > 0);
|
|
283
|
+
(0, assert_1.default)(values.length > 0, `${filename}中的${obj} ${node.typeName.getText()}未定义`);
|
|
283
284
|
const importDeclartion = declaration.parent.parent.parent;
|
|
284
|
-
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion));
|
|
285
|
+
(0, assert_1.default)(ts.isImportDeclaration(importDeclartion), '未找到importDeclaration');
|
|
285
286
|
addImportedFrom(moduleName, declaration.name.text, importDeclartion);
|
|
286
287
|
}
|
|
287
288
|
}
|
|
@@ -306,7 +307,7 @@ function tryGetStringLiteralValues(moduleName, filename, obj, node, program) {
|
|
|
306
307
|
values.push(action);
|
|
307
308
|
}
|
|
308
309
|
if (['state', 'action'].includes(obj)) {
|
|
309
|
-
(0, assert_1.default)(values.length > 0);
|
|
310
|
+
(0, assert_1.default)(values.length > 0, `${filename}中的${obj} ${node.typeName.getText()}未定义`);
|
|
310
311
|
const ast = ActionAsts[moduleName];
|
|
311
312
|
addImportedFrom(moduleName, declaration.name.text, './');
|
|
312
313
|
}
|
|
@@ -339,8 +340,9 @@ function dealWithActionTypeNode(moduleName, filename, actionTypeNode, program, s
|
|
|
339
340
|
(0, assert_1.default)((0, lodash_1.intersection)(actionNames, RESERVED_ACTION_NAMES).length === 0, `${filename}中的Action命名不能是「${RESERVED_ACTION_NAMES.join(',')}」之一`);
|
|
340
341
|
actionTypeNode.types.forEach(ele => {
|
|
341
342
|
if (ts.isTypeReferenceNode(ele)) {
|
|
343
|
+
// 这里递归了类型定义,去查找所有的action字符串
|
|
342
344
|
const actionStrings = tryGetStringLiteralValues(moduleName, filename, 'action', ele, program);
|
|
343
|
-
(0, assert_1.default)(actionStrings.length > 0);
|
|
345
|
+
(0, assert_1.default)(actionStrings.length > 0, `${filename}中的Action所引用的Type定义为空`);
|
|
344
346
|
actionTexts.push(...actionStrings);
|
|
345
347
|
}
|
|
346
348
|
else {
|
|
@@ -354,7 +356,7 @@ function dealWithActionTypeNode(moduleName, filename, actionTypeNode, program, s
|
|
|
354
356
|
(0, assert_1.default)(!RESERVED_ACTION_NAMES.includes(actionTypeNode.typeName.text), `${filename}中的Action命名不能是「${RESERVED_ACTION_NAMES.join(',')}」之一`);
|
|
355
357
|
}
|
|
356
358
|
const actionStrings = tryGetStringLiteralValues(moduleName, filename, 'action', actionTypeNode, program);
|
|
357
|
-
(0, assert_1.default)(actionStrings.length > 0);
|
|
359
|
+
(0, assert_1.default)(actionStrings.length > 0, `${filename}中的Action定义为空`);
|
|
358
360
|
actionTexts.push(...actionStrings);
|
|
359
361
|
}
|
|
360
362
|
else {
|
|
@@ -382,10 +384,10 @@ function dealWithActionDefInitializer(moduleName, initializer, program) {
|
|
|
382
384
|
// 是从别处的引用,注入到mportActionDefFrom
|
|
383
385
|
const checker = program.getTypeChecker();
|
|
384
386
|
const identifier = ts.isIdentifier(initializer) ? initializer : initializer.expression;
|
|
385
|
-
(0, assert_1.default)(ts.isIdentifier(identifier));
|
|
387
|
+
(0, assert_1.default)(ts.isIdentifier(identifier), "ActionDef的initializer不是一个Identifier");
|
|
386
388
|
const symbol = checker.getSymbolAtLocation(identifier);
|
|
387
389
|
const declaration = symbol?.getDeclarations()[0];
|
|
388
|
-
(0, assert_1.default)(ts.isImportSpecifier(declaration));
|
|
390
|
+
(0, assert_1.default)(ts.isImportSpecifier(declaration), "ActionDef的initializer不是一个ImportSpecifier");
|
|
389
391
|
const importDeclartion = declaration.parent.parent.parent;
|
|
390
392
|
addImportedFrom(moduleName, identifier.text, importDeclartion);
|
|
391
393
|
}
|
|
@@ -418,7 +420,7 @@ function getEntityImported(declaration) {
|
|
|
418
420
|
function checkLocaleEnumAttrs(node, attrs, filename) {
|
|
419
421
|
const { members } = node;
|
|
420
422
|
const memberKeys = members.map((ele) => {
|
|
421
|
-
(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');
|
|
422
424
|
return ele.name.text;
|
|
423
425
|
});
|
|
424
426
|
const lack = (0, lodash_1.difference)(attrs, memberKeys);
|
|
@@ -432,7 +434,7 @@ function checkLocaleExpressionPropertyExists(root, attr, exists, filename) {
|
|
|
432
434
|
(0, assert_1.default)(ts.isPropertyAssignment(ele) && (ts.isIdentifier(ele.name) || ts.isStringLiteral(ele.name)) && ts.isObjectLiteralExpression(ele.initializer));
|
|
433
435
|
const { properties: p2 } = ele.initializer;
|
|
434
436
|
const pp = p2.find((ele2) => {
|
|
435
|
-
(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');
|
|
436
438
|
return ele2.name.text === attr;
|
|
437
439
|
});
|
|
438
440
|
if (exists && !pp) {
|
|
@@ -565,14 +567,9 @@ function analyzeImportDeclaration(node, referencedSchemas, additionalImports, fi
|
|
|
565
567
|
}
|
|
566
568
|
}
|
|
567
569
|
/**
|
|
568
|
-
*
|
|
569
|
-
* 这里关键是要处理形如file:的依赖声明
|
|
570
|
-
* @param path
|
|
571
|
-
* @param fileSpecifierPath
|
|
572
|
-
* @param filename
|
|
573
|
-
* @returns
|
|
570
|
+
* 处理模块的导入,得到导入文件的sourcefile
|
|
574
571
|
*/
|
|
575
|
-
function
|
|
572
|
+
function dealImportedFile(path, fileSpecifierPath, filename, program) {
|
|
576
573
|
let importedFilepath = '';
|
|
577
574
|
const getExistedFileName = () => {
|
|
578
575
|
if ((0, fs_1.existsSync)(`${importedFilepath}.ts`)) {
|
|
@@ -587,39 +584,76 @@ function getImportedFilePath(path, fileSpecifierPath, filename) {
|
|
|
587
584
|
importedFilepath = path_1.default.join(path, fileSpecifierPath);
|
|
588
585
|
const importedFilename = getExistedFileName();
|
|
589
586
|
(0, assert_1.default)(importedFilename, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
const cwd = process.cwd();
|
|
594
|
-
const fileSpecifierPaths = fileSpecifierPath.split('/');
|
|
595
|
-
const moduleName = fileSpecifierPaths[0] || fileSpecifierPaths[1];
|
|
596
|
-
(0, assert_1.default)(moduleName);
|
|
597
|
-
// 从path向外找package.json -> node_modules直至找到fileSpecifier
|
|
598
|
-
const paths = path.split('/');
|
|
599
|
-
for (let iter = paths.length; iter >= 0; iter--) {
|
|
600
|
-
const paths2 = paths.slice(0, iter);
|
|
601
|
-
const pkgJsonPath = path_1.default.join(cwd, ...paths2, 'package.json');
|
|
602
|
-
if ((0, fs_1.existsSync)(pkgJsonPath)) {
|
|
603
|
-
const pkgJson = require(pkgJsonPath);
|
|
604
|
-
if (pkgJson.dependencies?.hasOwnProperty(moduleName)) {
|
|
605
|
-
const dependentPath = pkgJson.dependencies[moduleName];
|
|
606
|
-
if (dependentPath.trimStart().startsWith('file:')) {
|
|
607
|
-
const dependentFilePath = dependentPath.trimStart().slice(5);
|
|
608
|
-
importedFilepath = path_1.default.join(pkgJsonPath, '..', dependentFilePath, ...(fileSpecifierPaths[0] ? fileSpecifierPaths.slice(1) : (fileSpecifierPaths.slice(2))));
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
importedFilepath = path_1.default.join(pkgJsonPath, '..', 'node_modules', fileSpecifierPath);
|
|
612
|
-
}
|
|
613
|
-
const importedFilename = getExistedFileName();
|
|
614
|
-
if (importedFilename) {
|
|
615
|
-
return importedFilename;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
}
|
|
587
|
+
const sourceFile = program.getSourceFile(importedFilename);
|
|
588
|
+
(0, assert_1.default)(sourceFile, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
589
|
+
return [sourceFile, importedFilename];
|
|
620
590
|
}
|
|
621
|
-
|
|
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];
|
|
622
600
|
}
|
|
601
|
+
/**
|
|
602
|
+
* 在path下的filename文件中import了fileSpecifierPath,要找到其对应的引用路径
|
|
603
|
+
* 这里关键是要处理形如file:的依赖声明
|
|
604
|
+
* @param path
|
|
605
|
+
* @param fileSpecifierPath
|
|
606
|
+
* @param filename
|
|
607
|
+
* @returns
|
|
608
|
+
*/
|
|
609
|
+
// function getImportedFilePath(path: string, fileSpecifierPath: string, filename: string) {
|
|
610
|
+
// let importedFilepath = '';
|
|
611
|
+
// const getExistedFileName = () => {
|
|
612
|
+
// if (existsSync(`${importedFilepath}.ts`)) {
|
|
613
|
+
// return `${importedFilepath}.ts`;
|
|
614
|
+
// }
|
|
615
|
+
// else if (existsSync(`${importedFilepath}.d.ts`)) {
|
|
616
|
+
// return `${importedFilepath}.d.ts`;
|
|
617
|
+
// }
|
|
618
|
+
// return '';
|
|
619
|
+
// };
|
|
620
|
+
// if (fileSpecifierPath.startsWith('.')) {
|
|
621
|
+
// importedFilepath = PathLib.join(path, fileSpecifierPath);
|
|
622
|
+
// const importedFilename = getExistedFileName();
|
|
623
|
+
// assert(importedFilename, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
624
|
+
// return importedFilename;
|
|
625
|
+
// }
|
|
626
|
+
// else {
|
|
627
|
+
// const cwd = process.cwd();
|
|
628
|
+
// const fileSpecifierPaths = fileSpecifierPath.split('/');
|
|
629
|
+
// const moduleName = fileSpecifierPaths[0] || fileSpecifierPaths[1];
|
|
630
|
+
// assert(moduleName, '「${filename}」中import路径不合法');
|
|
631
|
+
// // 从path向外找package.json -> node_modules直至找到fileSpecifier
|
|
632
|
+
// const paths = path.split('/');
|
|
633
|
+
// for (let iter = paths.length; iter >= 0; iter--) {
|
|
634
|
+
// const paths2 = paths.slice(0, iter);
|
|
635
|
+
// const pkgJsonPath = PathLib.join(cwd, ...paths2, 'package.json');
|
|
636
|
+
// if (existsSync(pkgJsonPath)) {
|
|
637
|
+
// const pkgJson = require(pkgJsonPath);
|
|
638
|
+
// if (pkgJson.dependencies?.hasOwnProperty(moduleName)) {
|
|
639
|
+
// const dependentPath = pkgJson.dependencies[moduleName] as string;
|
|
640
|
+
// if (dependentPath.trimStart().startsWith('file:')) {
|
|
641
|
+
// const dependentFilePath = dependentPath.trimStart().slice(5);
|
|
642
|
+
// importedFilepath = PathLib.join(pkgJsonPath, '..', dependentFilePath, ...(fileSpecifierPaths[0] ? fileSpecifierPaths.slice(1) : (fileSpecifierPaths.slice(2))));
|
|
643
|
+
// }
|
|
644
|
+
// else {
|
|
645
|
+
// importedFilepath = PathLib.join(pkgJsonPath, '..', 'node_modules', fileSpecifierPath);
|
|
646
|
+
// }
|
|
647
|
+
// const importedFilename = getExistedFileName();
|
|
648
|
+
// if (importedFilename) {
|
|
649
|
+
// return importedFilename;
|
|
650
|
+
// }
|
|
651
|
+
// }
|
|
652
|
+
// }
|
|
653
|
+
// }
|
|
654
|
+
// }
|
|
655
|
+
// assert(false, `「${filename}」中import路径${fileSpecifierPath}找不到对应的声明`);
|
|
656
|
+
// }
|
|
623
657
|
function analyzeSchemaDefinition(node, moduleName, filename, path, program, referencedSchemas, schemaAttrs, enumAttributes, importAttrFrom, relativePath) {
|
|
624
658
|
let hasEntityAttr = false;
|
|
625
659
|
let hasEntityIdAttr = false;
|
|
@@ -627,30 +661,28 @@ function analyzeSchemaDefinition(node, moduleName, filename, path, program, refe
|
|
|
627
661
|
let toLog = false;
|
|
628
662
|
const extendsFrom = [];
|
|
629
663
|
const { members, heritageClauses } = node;
|
|
630
|
-
(0, assert_1.default)(heritageClauses);
|
|
664
|
+
(0, assert_1.default)(heritageClauses, `「${filename}」中的Schema定义需要继承EntityShape或者其他Entity`);
|
|
631
665
|
const heritagedResult = heritageClauses.map((clause) => {
|
|
632
666
|
const { expression } = clause.types[0];
|
|
633
|
-
(0, assert_1.default)(ts.isIdentifier(expression));
|
|
667
|
+
(0, assert_1.default)(ts.isIdentifier(expression), `${expression}不是一个合法的继承类型`);
|
|
634
668
|
if (expression.text === 'EntityShape') {
|
|
635
669
|
// import { EntityShape } from 'oak-domain/lib/types/Entities; 所有schema的公共祖先类型,不用处理
|
|
636
670
|
return;
|
|
637
671
|
}
|
|
638
672
|
// 从其它文件的Schema类继承,这里需要将所继承的对象的属性进行访问并展开
|
|
639
|
-
(0, assert_1.default)(referencedSchemas.includes(expression.text));
|
|
673
|
+
(0, assert_1.default)(referencedSchemas.includes(expression.text), `「${filename}」中的Schema继承了未定义的实体「${expression.text}」`);
|
|
640
674
|
const checker = program.getTypeChecker();
|
|
641
675
|
const symbol = checker.getSymbolAtLocation(expression);
|
|
642
676
|
let declaration = symbol?.getDeclarations()[0];
|
|
643
|
-
(0, assert_1.default)(ts.isImportSpecifier(declaration));
|
|
677
|
+
(0, assert_1.default)(ts.isImportSpecifier(declaration), `${declaration.getText()}应该是导入的类型`);
|
|
644
678
|
const importDeclaration = declaration.parent.parent.parent;
|
|
645
|
-
(0, assert_1.default)(ts.isImportDeclaration(importDeclaration));
|
|
679
|
+
(0, assert_1.default)(ts.isImportDeclaration(importDeclaration), `${declaration.getText()}应该是导入的类型`);
|
|
646
680
|
const { moduleSpecifier } = importDeclaration;
|
|
647
|
-
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier));
|
|
681
|
+
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier), `${declaration.getText()}应该是导入的类型`);
|
|
648
682
|
const { text: from } = moduleSpecifier;
|
|
649
683
|
extendsFrom.push(from);
|
|
650
|
-
const
|
|
651
|
-
const
|
|
652
|
-
(0, assert_1.default)(sourceFile, `「${filename}」找不到相应的sourceFile:${importedFilename}`);
|
|
653
|
-
const relativeFilename = path_1.default.relative(process.cwd(), importedFilename);
|
|
684
|
+
const [sourceFile, pathName] = dealImportedFile(path, from, filename, program);
|
|
685
|
+
const relativeFilename = path_1.default.relative(process.cwd(), pathName);
|
|
654
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, '..'));
|
|
655
687
|
return result;
|
|
656
688
|
}).filter(ele => !!ele);
|
|
@@ -730,7 +762,7 @@ function analyzeSchemaDefinition(node, moduleName, filename, path, program, refe
|
|
|
730
762
|
else {
|
|
731
763
|
schemaAttrs.push(attrNode);
|
|
732
764
|
if (ts.isUnionTypeNode(type) && ts.isLiteralTypeNode(type.types[0]) && ts.isStringLiteral(type.types[0].literal)) {
|
|
733
|
-
(0, assert_1.default)(ts.isIdentifier(name));
|
|
765
|
+
(0, assert_1.default)(ts.isIdentifier(name), `「${filename}」中的属性定义不是String类型`);
|
|
734
766
|
const { types } = type;
|
|
735
767
|
const enumValues = types.map((ele) => checkStringLiteralLegal(filename, '属性', name.text, ele));
|
|
736
768
|
enumAttributes[name.text] = enumValues;
|
|
@@ -825,13 +857,13 @@ function analyzeReferenceSchemaFile(moduleName, filename, path, sourceFile, prog
|
|
|
825
857
|
}
|
|
826
858
|
}
|
|
827
859
|
});
|
|
828
|
-
(0, assert_1.default)(result);
|
|
860
|
+
(0, assert_1.default)(result, `「${filename}」中没有找到Schema定义`);
|
|
829
861
|
return result;
|
|
830
862
|
}
|
|
831
863
|
function analyzeEntity(filename, path, program, relativePath) {
|
|
832
864
|
const fullPath = `${path}/${filename}`;
|
|
833
865
|
const sourceFile = program.getSourceFile(fullPath);
|
|
834
|
-
(0, assert_1.default)(sourceFile);
|
|
866
|
+
(0, assert_1.default)(sourceFile, `「${filename}」文件不存在`);
|
|
835
867
|
const moduleName = filename.split('.')[0];
|
|
836
868
|
if (Schema.hasOwnProperty(moduleName)) {
|
|
837
869
|
delete ActionAsts[moduleName];
|
|
@@ -918,13 +950,13 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
918
950
|
(0, assert_1.default)(!localeDef, `【${filename}】locale定义须在Relation之后`);
|
|
919
951
|
const relationValues = [];
|
|
920
952
|
if (ts.isLiteralTypeNode(node.type)) {
|
|
921
|
-
(0, assert_1.default)(ts.isStringLiteral(node.type.literal));
|
|
953
|
+
(0, assert_1.default)(ts.isStringLiteral(node.type.literal), `${filename}中的Relation的定义只能是string类型`);
|
|
922
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})`);
|
|
923
955
|
relationValues.push(node.type.literal.text);
|
|
924
956
|
}
|
|
925
957
|
else if (ts.isTypeReferenceNode(node.type)) {
|
|
926
958
|
const relationStrings = tryGetStringLiteralValues(moduleName, filename, 'relation', node.type, program);
|
|
927
|
-
(0, assert_1.default)(relationStrings.length > 0);
|
|
959
|
+
(0, assert_1.default)(relationStrings.length > 0, `文件${filename}中的relation${node.type.typeName.text}定义未找到字符串类型`);
|
|
928
960
|
relationValues.push(...relationStrings);
|
|
929
961
|
}
|
|
930
962
|
else {
|
|
@@ -938,7 +970,7 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
938
970
|
else {
|
|
939
971
|
(0, assert_1.default)(ts.isTypeReferenceNode(ele), `Relation的定义只能是string类型,或者string union类型,或者两者的union(${filename})`);
|
|
940
972
|
const relationStrings = tryGetStringLiteralValues(moduleName, filename, 'relation', ele, program);
|
|
941
|
-
(0, assert_1.default)(relationStrings.length > 0);
|
|
973
|
+
(0, assert_1.default)(relationStrings.length > 0, `文件${filename}中的relation${ele.typeName.text}定义未找到字符串类型`);
|
|
942
974
|
relationValues.push(...relationStrings);
|
|
943
975
|
}
|
|
944
976
|
});
|
|
@@ -990,7 +1022,7 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
990
1022
|
]) : type), sourceFile);
|
|
991
1023
|
}
|
|
992
1024
|
else {
|
|
993
|
-
(0, assert_1.default)(ts.isLiteralTypeNode(type) || ts.isTypeReferenceNode(type),
|
|
1025
|
+
(0, assert_1.default)(ts.isLiteralTypeNode(type) || ts.isTypeReferenceNode(type), `文件${filename}中的${type.getText()}应该是字面量或引用类型`);
|
|
994
1026
|
pushStatementIntoActionAst(moduleName, factory.updateTypeAliasDeclaration(node, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], node.name, node.typeParameters, process.env.COMPLING_AS_LIB ? factory.createUnionTypeNode([
|
|
995
1027
|
type,
|
|
996
1028
|
factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
|
|
@@ -1007,12 +1039,12 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1007
1039
|
const dealWithActionDef = (declaration) => {
|
|
1008
1040
|
checkActionDefNameConsistent(filename, declaration);
|
|
1009
1041
|
const { typeArguments } = declaration.type;
|
|
1010
|
-
(0, assert_1.default)(typeArguments.length === 2);
|
|
1042
|
+
(0, assert_1.default)(typeArguments.length === 2, `文件${filename}中的action定义不是两个泛型参数`);
|
|
1011
1043
|
const [actionNode, stateNode] = typeArguments;
|
|
1012
|
-
(0, assert_1.default)(ts.isTypeReferenceNode(actionNode));
|
|
1044
|
+
(0, assert_1.default)(ts.isTypeReferenceNode(actionNode), `文件${filename}中的action定义不是TypeReferenceNode`);
|
|
1013
1045
|
// 这里有可能引用的Action不是本文件的定义,要调用这个函数加到importFrom中
|
|
1014
1046
|
tryGetStringLiteralValues(moduleName, filename, 'action', actionNode, program);
|
|
1015
|
-
(0, assert_1.default)(ts.isTypeReferenceNode(stateNode));
|
|
1047
|
+
(0, assert_1.default)(ts.isTypeReferenceNode(stateNode), `文件${filename}中的action定义不是TypeReferenceNode`);
|
|
1016
1048
|
const enumStateValues = tryGetStringLiteralValues(moduleName, filename, 'state', stateNode, program);
|
|
1017
1049
|
(0, assert_1.default)(enumStateValues.length > 0, `文件${filename}中的state${stateNode.typeName.text}定义不是字符串类型`);
|
|
1018
1050
|
pushStatementIntoActionAst(moduleName, node, sourceFile);
|
|
@@ -1029,18 +1061,18 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1029
1061
|
const { elements } = declaration;
|
|
1030
1062
|
elements.forEach((ele) => {
|
|
1031
1063
|
let isFulltextIndex = false;
|
|
1032
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(ele));
|
|
1064
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(ele), `「${filename}」中索引定义应该是对象字面量`);
|
|
1033
1065
|
const { properties } = ele;
|
|
1034
1066
|
const attrProperty = properties.find((ele2) => {
|
|
1035
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1067
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele2), `「${filename}」中索引的属性不为PropertyAssignment`);
|
|
1036
1068
|
return ele2.name.getText() === 'attributes';
|
|
1037
1069
|
});
|
|
1038
|
-
(0, assert_1.default)(ts.isArrayLiteralExpression(attrProperty.initializer));
|
|
1070
|
+
(0, assert_1.default)(ts.isArrayLiteralExpression(attrProperty.initializer), `「${filename}」中索引的attributes属性应该是数组字面量`);
|
|
1039
1071
|
const nameProperty = properties.find((ele2) => {
|
|
1040
1072
|
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1041
1073
|
return ele2.name.getText() === 'name';
|
|
1042
1074
|
});
|
|
1043
|
-
(0, assert_1.default)(ts.isStringLiteral(nameProperty.initializer));
|
|
1075
|
+
(0, assert_1.default)(ts.isStringLiteral(nameProperty.initializer), '「${filename}」中索引的name属性应该是字符串字面量');
|
|
1044
1076
|
const nameText = nameProperty.initializer.text;
|
|
1045
1077
|
if (indexNameDict[nameText]) {
|
|
1046
1078
|
throw new Error(`「${filename}」索引定义重名「${nameText}」`);
|
|
@@ -1049,14 +1081,14 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1049
1081
|
[nameText]: true,
|
|
1050
1082
|
});
|
|
1051
1083
|
const configProperty = properties.find((ele2) => {
|
|
1052
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1084
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele2), `「${filename}」中索引的属性不为PropertyAssignment`);
|
|
1053
1085
|
return ele2.name.getText() === 'config';
|
|
1054
1086
|
});
|
|
1055
1087
|
if (configProperty) {
|
|
1056
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(configProperty.initializer));
|
|
1088
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(configProperty.initializer), `「${filename}」中索引的config属性应该是对象字面量`);
|
|
1057
1089
|
const { properties: properties2 } = configProperty.initializer;
|
|
1058
1090
|
const typeProperty = properties2.find((ele2) => {
|
|
1059
|
-
(0, assert_1.default)(ts.isPropertyAssignment(ele2));
|
|
1091
|
+
(0, assert_1.default)(ts.isPropertyAssignment(ele2), `「${filename}」中索引的属性不为PropertyAssignment`);
|
|
1060
1092
|
return ele2.name.getText() === 'type';
|
|
1061
1093
|
});
|
|
1062
1094
|
if (typeProperty && typeProperty.initializer.text === 'fulltext') {
|
|
@@ -1171,21 +1203,21 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1171
1203
|
if (ts.isObjectLiteralExpression(declaration)) {
|
|
1172
1204
|
const { properties } = declaration;
|
|
1173
1205
|
const localesProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'locales');
|
|
1174
|
-
(0, assert_1.default)(ts.isPropertyAssignment(localesProperty));
|
|
1206
|
+
(0, assert_1.default)(ts.isPropertyAssignment(localesProperty), `「${filename}」中entityDesc的locales应该是属性声明`);
|
|
1175
1207
|
dealWithLocales(localesProperty.initializer);
|
|
1176
1208
|
const indexesProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'indexes');
|
|
1177
1209
|
if (indexesProperty) {
|
|
1178
|
-
(0, assert_1.default)(ts.isPropertyAssignment(indexesProperty));
|
|
1210
|
+
(0, assert_1.default)(ts.isPropertyAssignment(indexesProperty), `「${filename}」中entityDesc的indexes应该是属性声明`);
|
|
1179
1211
|
dealWithIndexes(indexesProperty.initializer);
|
|
1180
1212
|
}
|
|
1181
1213
|
const configurationProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'configuration');
|
|
1182
1214
|
if (configurationProperty) {
|
|
1183
|
-
(0, assert_1.default)(ts.isPropertyAssignment(configurationProperty));
|
|
1215
|
+
(0, assert_1.default)(ts.isPropertyAssignment(configurationProperty), `「${filename}」中entityDesc的configuration应该是属性声明`);
|
|
1184
1216
|
dealWithConfiguration(configurationProperty.initializer);
|
|
1185
1217
|
}
|
|
1186
1218
|
const styleDescProperty = properties.find(ele => ts.isPropertyAssignment(ele) && ts.isIdentifier(ele.name) && ele.name.text === 'style');
|
|
1187
1219
|
if (styleDescProperty) {
|
|
1188
|
-
(0, assert_1.default)(ts.isPropertyAssignment(styleDescProperty));
|
|
1220
|
+
(0, assert_1.default)(ts.isPropertyAssignment(styleDescProperty), `「${filename}」中entityDesc的style应该是属性声明`);
|
|
1189
1221
|
dealWithStyleDesc(styleDescProperty.initializer);
|
|
1190
1222
|
}
|
|
1191
1223
|
}
|
|
@@ -1216,14 +1248,14 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1216
1248
|
&& declaration.type.typeArguments[0].typeName.text === 'Index')) {
|
|
1217
1249
|
// 对索引Index的定义
|
|
1218
1250
|
console.log(`「${filename}」直接定义indexes的写法已经过时,请定义在entityDesc中`);
|
|
1219
|
-
(0, assert_1.default)(ts.isArrayLiteralExpression(declaration.initializer));
|
|
1251
|
+
(0, assert_1.default)(ts.isArrayLiteralExpression(declaration.initializer), `「${filename}」中索引定义应该是数组字面量`);
|
|
1220
1252
|
dealWithIndexes(declaration.initializer);
|
|
1221
1253
|
}
|
|
1222
1254
|
else if (declaration.type && ts.isTypeReferenceNode(declaration.type) && ts.isIdentifier(declaration.type.typeName) && declaration.type.typeName.text === 'LocaleDef') {
|
|
1223
1255
|
// locale定义
|
|
1224
1256
|
console.log(`「${filename}」直接定义locales的写法已经过时,请定义在entityDesc中`);
|
|
1225
1257
|
const { type, initializer } = declaration;
|
|
1226
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(initializer));
|
|
1258
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(initializer), `「${filename}」中locale定义应该是对象字面量`);
|
|
1227
1259
|
const { properties } = initializer;
|
|
1228
1260
|
(0, assert_1.default)(properties.length > 0, `${filename}至少需要有一种locale定义`);
|
|
1229
1261
|
const allEnumStringAttrs = Object.keys(enumAttributes);
|
|
@@ -1260,12 +1292,12 @@ function analyzeEntity(filename, path, program, relativePath) {
|
|
|
1260
1292
|
}
|
|
1261
1293
|
else if (declaration.type && ts.isTypeReferenceNode(declaration.type) && ts.isIdentifier(declaration.type.typeName) && declaration.type.typeName.text === 'Configuration') {
|
|
1262
1294
|
console.log(`「${filename}」直接定义configuration的写法已经过时,请定义在entityDesc中`);
|
|
1263
|
-
(0, assert_1.default)(ts.isObjectLiteralExpression(declaration.initializer));
|
|
1295
|
+
(0, assert_1.default)(ts.isObjectLiteralExpression(declaration.initializer), `「${filename}」中configuration定义应该是对象字面量`);
|
|
1264
1296
|
dealWithConfiguration(declaration.initializer);
|
|
1265
1297
|
}
|
|
1266
1298
|
else if (declaration.type && ts.isTypeReferenceNode(declaration.type) && ts.isIdentifier(declaration.type.typeName) && declaration.type.typeName.text === 'EntityDesc') {
|
|
1267
1299
|
const { initializer } = declaration;
|
|
1268
|
-
(0, assert_1.default)(initializer);
|
|
1300
|
+
(0, assert_1.default)(initializer, `「${filename}」中entityDesc的定义不应该为空`);
|
|
1269
1301
|
dealWithEntityDesc(initializer);
|
|
1270
1302
|
}
|
|
1271
1303
|
else {
|
|
@@ -1609,7 +1641,7 @@ function constructFilter(statements, entity) {
|
|
|
1609
1641
|
}
|
|
1610
1642
|
else {
|
|
1611
1643
|
// 此时应当是引用本地定义的shape
|
|
1612
|
-
(0, assert_1.default)(type);
|
|
1644
|
+
(0, assert_1.default)(type, `${entity}中的属性${name.toString()}有非法的属性类型定义`);
|
|
1613
1645
|
members.push(factory.createPropertySignature(undefined, name, undefined, factory.createTypeReferenceNode(factory.createIdentifier('JsonFilter'), [
|
|
1614
1646
|
type
|
|
1615
1647
|
])));
|
|
@@ -3110,7 +3142,7 @@ function outputSchema(outputDir, printer) {
|
|
|
3110
3142
|
const fromLocalActionSpecifiers = ['Action', 'ParticularAction'];
|
|
3111
3143
|
const fromExtenalStates = {};
|
|
3112
3144
|
for (const state in importStateFrom) {
|
|
3113
|
-
(0, assert_1.default)(state.endsWith('State'));
|
|
3145
|
+
(0, assert_1.default)(state.endsWith('State'), `${state} should end with State`);
|
|
3114
3146
|
if (importStateFrom[state][0] === './') {
|
|
3115
3147
|
// 本地定义的State从 ./Action 中获取
|
|
3116
3148
|
fromLocalActionSpecifiers.push(state);
|
|
@@ -3239,7 +3271,7 @@ function outputAction(outputDir, printer) {
|
|
|
3239
3271
|
const importStatements = [];
|
|
3240
3272
|
const fromExternalImports = {};
|
|
3241
3273
|
for (const state in importStateFrom) {
|
|
3242
|
-
(0, assert_1.default)(state.endsWith('State'));
|
|
3274
|
+
(0, assert_1.default)(state.endsWith('State'), `${state} should end with State`);
|
|
3243
3275
|
const [from, propertyName] = importStateFrom[state];
|
|
3244
3276
|
if (from !== './') {
|
|
3245
3277
|
if (fromExternalImports[from]) {
|
|
@@ -3251,7 +3283,7 @@ function outputAction(outputDir, printer) {
|
|
|
3251
3283
|
}
|
|
3252
3284
|
}
|
|
3253
3285
|
for (const action in importActionFrom) {
|
|
3254
|
-
(0, assert_1.default)(action.endsWith('Action'));
|
|
3286
|
+
(0, assert_1.default)(action.endsWith('Action'), `${action} should end with Action`);
|
|
3255
3287
|
const [from, propertyName] = importActionFrom[action];
|
|
3256
3288
|
if (from !== './') {
|
|
3257
3289
|
if (fromExternalImports[from]) {
|
|
@@ -3263,7 +3295,7 @@ function outputAction(outputDir, printer) {
|
|
|
3263
3295
|
}
|
|
3264
3296
|
}
|
|
3265
3297
|
for (const def in importActionDefFrom) {
|
|
3266
|
-
(0, assert_1.default)(def.endsWith('ActionDef'));
|
|
3298
|
+
(0, assert_1.default)(def.endsWith('ActionDef'), `${def} should end with ActionDef`);
|
|
3267
3299
|
const [from, propertyName] = importActionDefFrom[def];
|
|
3268
3300
|
if (from !== './') {
|
|
3269
3301
|
if (fromExternalImports[from]) {
|
|
@@ -3405,11 +3437,11 @@ function constructAttributes(entity) {
|
|
|
3405
3437
|
if (ts.isUnionTypeNode(type)) {
|
|
3406
3438
|
if (ts.isLiteralTypeNode(type.types[0])) {
|
|
3407
3439
|
if (ts.isStringLiteral(type.types[0].literal)) {
|
|
3408
|
-
(0, assert_1.default)(enumAttributes && enumAttributes[name.text]);
|
|
3440
|
+
(0, assert_1.default)(enumAttributes && enumAttributes[name.text], `${entity}对象中的${name.text}属性没有定义enumAttributes`);
|
|
3409
3441
|
attrAssignments.push(factory.createPropertyAssignment('type', factory.createStringLiteral("enum")), factory.createPropertyAssignment('enumeration', factory.createArrayLiteralExpression(enumAttributes[name.text].map(ele => factory.createStringLiteral(ele)))));
|
|
3410
3442
|
}
|
|
3411
3443
|
else {
|
|
3412
|
-
(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()}属性不是数字`);
|
|
3413
3445
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("int")), factory.createPropertyAssignment(factory.createIdentifier("params"), factory.createObjectLiteralExpression([
|
|
3414
3446
|
factory.createPropertyAssignment(factory.createIdentifier("width"), factory.createNumericLiteral(env_1.INT_LITERL_DEFAULT_WIDTH))
|
|
3415
3447
|
], true)));
|
|
@@ -3426,7 +3458,7 @@ function constructAttributes(entity) {
|
|
|
3426
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)));
|
|
3427
3459
|
}
|
|
3428
3460
|
else {
|
|
3429
|
-
(0, assert_1.default)(ts.isNumericLiteral(type.literal));
|
|
3461
|
+
(0, assert_1.default)(ts.isNumericLiteral(type.literal), `${entity}对象中的${name.text}属性不是数字`);
|
|
3430
3462
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("precision")), factory.createPropertyAssignment(factory.createIdentifier("params"), factory.createObjectLiteralExpression([
|
|
3431
3463
|
factory.createPropertyAssignment(factory.createIdentifier("precision"), factory.createNumericLiteral(env_1.NUMERICAL_LITERL_DEFAULT_PRECISION)),
|
|
3432
3464
|
factory.createPropertyAssignment(factory.createIdentifier("scale"), factory.createNumericLiteral(env_1.NUMERICAL_LITERL_DEFAULT_SCALE))
|
|
@@ -3451,14 +3483,14 @@ function outputLocale(outputDir, printer) {
|
|
|
3451
3483
|
if (locale) {
|
|
3452
3484
|
const { properties } = locale;
|
|
3453
3485
|
properties.forEach((ele) => {
|
|
3454
|
-
(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属性定义不正确`);
|
|
3455
3487
|
const lng = ele.name.text;
|
|
3456
3488
|
const result = printer.printList(ts.ListFormat.SourceFileStatements, factory.createNodeArray([
|
|
3457
3489
|
factory.createReturnStatement(ele.initializer)
|
|
3458
3490
|
]), sourceFile);
|
|
3459
3491
|
const data = Function(result)();
|
|
3460
3492
|
const filename = path_1.default.join(outputDir, entity, 'locales', `${lng}.json`);
|
|
3461
|
-
(0, fs_1.writeFileSync)(filename, JSON.stringify(data), { flag: 'w' });
|
|
3493
|
+
(0, fs_1.writeFileSync)(filename, JSON.stringify(data, null, 2), { flag: 'w' });
|
|
3462
3494
|
if (locales[lng]) {
|
|
3463
3495
|
locales[lng].push(entity);
|
|
3464
3496
|
}
|
package/lib/entities/I18n.js
CHANGED
|
@@ -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
|
}
|
|
@@ -331,6 +331,7 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
|
|
|
331
331
|
const actions = condition.map(ele => ele?.actions).filter(ele => !!ele);
|
|
332
332
|
const a = actions.length > 0 && (0, lodash_1.intersection)(actions.flat());
|
|
333
333
|
if (a) {
|
|
334
|
+
(0, assert_1.default)(action);
|
|
334
335
|
if (!a.includes(action)) {
|
|
335
336
|
// 找到不满足的那个attr
|
|
336
337
|
const attrsIllegal = attrs.filter((attr) => matrix[attr]?.actions && !matrix[attr]?.actions?.includes(action));
|
|
@@ -253,10 +253,13 @@ class TriggerExecutor {
|
|
|
253
253
|
cxtStr2 = data.$$triggerData$$?.cxtStr;
|
|
254
254
|
}
|
|
255
255
|
const record = opRecords.find(ele => ele.id === operation.id);
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
256
|
+
if (record) {
|
|
257
|
+
// 目前框架在operation时,一定会将ids记录在operation当中(见CascadeStore中的doUpdateSingleRowAsync函数
|
|
258
|
+
// 但也有一种可能,此operation没有更新任何一行。by Xc 20241022
|
|
259
|
+
(0, assert_1.default)(record.a !== 'c');
|
|
260
|
+
const { f } = record;
|
|
261
|
+
ids = f.id.$in;
|
|
262
|
+
}
|
|
260
263
|
}
|
|
261
264
|
// 此时项目的上下文,和执行此trigger时的上下文可能不一致(rootMode),采用当时的上下文cxtStr来执行
|
|
262
265
|
this.onVolatileTrigger(entity, trigger, ids, cxtStr2, option);
|
|
@@ -348,12 +351,12 @@ class TriggerExecutor {
|
|
|
348
351
|
async execVolatileTrigger(entity, name, ids, context, option) {
|
|
349
352
|
const trigger = this.triggerNameMap[name];
|
|
350
353
|
(0, assert_1.default)(trigger && trigger.when === 'commit');
|
|
351
|
-
|
|
354
|
+
// assert(ids.length > 0);
|
|
352
355
|
const { fn } = trigger;
|
|
353
356
|
const closeRoot = trigger.asRoot && context.openRootMode();
|
|
354
357
|
try {
|
|
355
358
|
const callback = await fn({ ids }, context, option);
|
|
356
|
-
if (trigger.strict === 'makeSure') {
|
|
359
|
+
if (trigger.strict === 'makeSure' && ids.length) {
|
|
357
360
|
// 这里开root模式,否则还可能有权限问题
|
|
358
361
|
const closeRoot2 = context.openRootMode();
|
|
359
362
|
try {
|
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') {
|
package/lib/store/triggers.js
CHANGED
|
@@ -362,41 +362,25 @@ exports.logTriggers = [
|
|
|
362
362
|
return (result.oper?.remove || 0) + (result2.log?.remove || 0);
|
|
363
363
|
}
|
|
364
364
|
},
|
|
365
|
-
// 在删除log
|
|
365
|
+
// 在删除log时,删除与此log关联的oper
|
|
366
366
|
{
|
|
367
|
-
name: '当删除log
|
|
367
|
+
name: '当删除log时,删除与此log关联的oper',
|
|
368
368
|
entity: 'log',
|
|
369
369
|
action: 'remove',
|
|
370
370
|
when: 'before',
|
|
371
371
|
fn: async ({ operation }, context) => {
|
|
372
372
|
const { filter } = operation;
|
|
373
373
|
(0, assert_1.default)(filter);
|
|
374
|
-
// 查询这次删除操作涉及到的所有log
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
},
|
|
383
|
-
},
|
|
384
|
-
},
|
|
385
|
-
filter,
|
|
374
|
+
// 查询这次删除操作涉及到的所有log
|
|
375
|
+
const result = await context.operate('oper', {
|
|
376
|
+
id: "dummy",
|
|
377
|
+
action: 'remove',
|
|
378
|
+
data: {},
|
|
379
|
+
filter: {
|
|
380
|
+
log: filter,
|
|
381
|
+
}
|
|
386
382
|
}, {});
|
|
387
|
-
|
|
388
|
-
let result = 0;
|
|
389
|
-
for (const operId of operIds) {
|
|
390
|
-
const result2 = await context.operate('oper', {
|
|
391
|
-
id: operId,
|
|
392
|
-
action: 'update',
|
|
393
|
-
data: {
|
|
394
|
-
logId: null,
|
|
395
|
-
},
|
|
396
|
-
}, {});
|
|
397
|
-
result += result2.oper?.update || 0;
|
|
398
|
-
}
|
|
399
|
-
return result;
|
|
383
|
+
return result.oper?.remove || 0;
|
|
400
384
|
}
|
|
401
385
|
},
|
|
402
386
|
];
|
|
@@ -29,7 +29,7 @@ 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
|
};
|
|
@@ -42,10 +42,10 @@ export type AccessConfiguration = {
|
|
|
42
42
|
routerPrefixes?: {
|
|
43
43
|
aspect?: string;
|
|
44
44
|
endpoint?: string;
|
|
45
|
-
subscribe?: string;
|
|
46
45
|
getSubscribePoint?: string;
|
|
47
46
|
bridge?: string;
|
|
48
47
|
};
|
|
48
|
+
socketPath?: string;
|
|
49
49
|
http: {
|
|
50
50
|
hostname: string;
|
|
51
51
|
port?: number;
|
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;
|
|
@@ -42,4 +43,5 @@ export interface Connector<ED extends EntityDict & BaseEntityDict, FrontCxt exte
|
|
|
42
43
|
getFullData: (keys?: (keyof ED)[]) => Promise<{
|
|
43
44
|
[T in keyof ED]?: ED[T]['OpSchema'][];
|
|
44
45
|
}>;
|
|
46
|
+
getCorsHeader: () => string[];
|
|
45
47
|
}
|
package/lib/types/Exception.d.ts
CHANGED
|
@@ -72,6 +72,8 @@ export declare class OakNetworkException<ED extends EntityDict & BaseEntityDict>
|
|
|
72
72
|
}
|
|
73
73
|
export declare class OakServerProxyException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
74
74
|
}
|
|
75
|
+
export declare class OakClockDriftException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
|
|
76
|
+
}
|
|
75
77
|
/**
|
|
76
78
|
* 数据不一致异常,系统认为现有的数据不允许相应的动作时抛此异常
|
|
77
79
|
*
|
|
@@ -128,7 +130,7 @@ export declare class OakUnloggedInException<ED extends EntityDict & BaseEntityDi
|
|
|
128
130
|
constructor(message?: string);
|
|
129
131
|
}
|
|
130
132
|
/**
|
|
131
|
-
*
|
|
133
|
+
* 行数据被锁抛的异常
|
|
132
134
|
*/
|
|
133
135
|
export declare class OakRowLockedException<ED extends EntityDict & BaseEntityDict> extends OakUserException<ED> {
|
|
134
136
|
constructor(message?: string);
|
package/lib/types/Exception.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.makeException = exports.OakSocketConnectException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = exports.OakException = void 0;
|
|
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;
|
|
4
4
|
const relation_1 = require("../store/relation");
|
|
5
5
|
const lodash_1 = require("../utils/lodash");
|
|
6
6
|
class OakException extends Error {
|
|
@@ -173,10 +173,14 @@ exports.OakImportDataParseException = OakImportDataParseException;
|
|
|
173
173
|
class OakNetworkException extends OakException {
|
|
174
174
|
}
|
|
175
175
|
exports.OakNetworkException = OakNetworkException;
|
|
176
|
-
//
|
|
176
|
+
// 请求未到达应用服务程序
|
|
177
177
|
class OakServerProxyException extends OakException {
|
|
178
178
|
}
|
|
179
179
|
exports.OakServerProxyException = OakServerProxyException;
|
|
180
|
+
// 时钟漂移过久(重放攻击)
|
|
181
|
+
class OakClockDriftException extends OakException {
|
|
182
|
+
}
|
|
183
|
+
exports.OakClockDriftException = OakClockDriftException;
|
|
180
184
|
// 在系统更新数据时,以下三个异常应按规范依次抛出。
|
|
181
185
|
/**
|
|
182
186
|
* 数据不一致异常,系统认为现有的数据不允许相应的动作时抛此异常
|
|
@@ -294,7 +298,7 @@ class OakUnloggedInException extends OakUserException {
|
|
|
294
298
|
exports.OakUnloggedInException = OakUnloggedInException;
|
|
295
299
|
;
|
|
296
300
|
/**
|
|
297
|
-
*
|
|
301
|
+
* 行数据被锁抛的异常
|
|
298
302
|
*/
|
|
299
303
|
class OakRowLockedException extends OakUserException {
|
|
300
304
|
constructor(message) {
|
|
@@ -479,6 +483,10 @@ function makeException(data) {
|
|
|
479
483
|
e = new OakNetworkException(data.message);
|
|
480
484
|
break;
|
|
481
485
|
}
|
|
486
|
+
case 'OakClockDriftException': {
|
|
487
|
+
e = new OakClockDriftException(data.message);
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
482
490
|
case 'OakServerProxyException': {
|
|
483
491
|
e = new OakServerProxyException(data.message);
|
|
484
492
|
break;
|
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;
|
|
@@ -17,11 +18,15 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
17
18
|
private configuration;
|
|
18
19
|
private makeException;
|
|
19
20
|
constructor(configuration: AccessConfiguration, makeException: (exceptionData: any) => OakException<ED>);
|
|
21
|
+
getCorsHeader(): string[];
|
|
20
22
|
protected makeHeadersAndBody(name: string, data: any, context?: FrontCxt): Promise<{
|
|
21
|
-
headers:
|
|
23
|
+
headers: {
|
|
24
|
+
'oak-cxt': string;
|
|
25
|
+
'oak-aspect': string;
|
|
26
|
+
};
|
|
22
27
|
body: FormData;
|
|
23
28
|
} | {
|
|
24
|
-
headers:
|
|
29
|
+
headers: Record<string, string>;
|
|
25
30
|
body: string;
|
|
26
31
|
}>;
|
|
27
32
|
protected parseAspectResult(response: Response): Promise<{
|
|
@@ -43,11 +48,12 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
|
|
|
43
48
|
opRecords?: undefined;
|
|
44
49
|
}>;
|
|
45
50
|
getRouter(): string;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
url: any;
|
|
51
|
+
getSocketPath(): string;
|
|
52
|
+
getSocketPointRouter(): string;
|
|
53
|
+
getSocketPoint(): Promise<{
|
|
50
54
|
path: any;
|
|
55
|
+
subscribeUrl: any;
|
|
56
|
+
socketUrl: any;
|
|
51
57
|
}>;
|
|
52
58
|
getEndpointRouter(): string;
|
|
53
59
|
parseRequest(headers: IncomingHttpHeaders, body?: any, files?: any): {
|
|
@@ -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;
|
|
@@ -38,9 +39,15 @@ class SimpleConnector {
|
|
|
38
39
|
this.serverAspectUrl = `${serverUrl}${routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER}`;
|
|
39
40
|
this.serverBridgeUrl = `${serverUrl}${routerPrefixes?.bridge || SimpleConnector.BRIDGE_ROUTER}`;
|
|
40
41
|
this.serverSubscribePointUrl = `${serverUrl}${routerPrefixes?.getSubscribePoint ||
|
|
41
|
-
SimpleConnector.
|
|
42
|
+
SimpleConnector.SOCKET_POINT_ROUTER}`;
|
|
42
43
|
this.makeException = makeException;
|
|
43
44
|
}
|
|
45
|
+
getCorsHeader() {
|
|
46
|
+
return [
|
|
47
|
+
'oak-cxt',
|
|
48
|
+
'oak-aspect'
|
|
49
|
+
];
|
|
50
|
+
}
|
|
44
51
|
async makeHeadersAndBody(name, data, context) {
|
|
45
52
|
const cxtStr = context ? await context.toString() : '{}';
|
|
46
53
|
const headers = {
|
|
@@ -48,6 +55,7 @@ class SimpleConnector {
|
|
|
48
55
|
'oak-aspect': name,
|
|
49
56
|
};
|
|
50
57
|
if (process.env.OAK_PLATFORM !== 'wechatMp') {
|
|
58
|
+
// 小程序环境下没有FormData,跑到这里会挂
|
|
51
59
|
if (data instanceof FormData) {
|
|
52
60
|
return {
|
|
53
61
|
headers,
|
|
@@ -115,13 +123,16 @@ class SimpleConnector {
|
|
|
115
123
|
getRouter() {
|
|
116
124
|
return this.configuration.routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER;
|
|
117
125
|
}
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
/* getSubscribePath(): string {
|
|
127
|
+
return this.configuration.socketPath?.subscribe || SimpleConnector.SUBSCRIBE_PATH;
|
|
128
|
+
} */
|
|
129
|
+
getSocketPath() {
|
|
130
|
+
return this.configuration.socketPath || SimpleConnector.SOCKET_PATH;
|
|
120
131
|
}
|
|
121
|
-
|
|
122
|
-
return this.configuration.routerPrefixes?.getSubscribePoint || SimpleConnector.
|
|
132
|
+
getSocketPointRouter() {
|
|
133
|
+
return this.configuration.routerPrefixes?.getSubscribePoint || SimpleConnector.SOCKET_POINT_ROUTER;
|
|
123
134
|
}
|
|
124
|
-
async
|
|
135
|
+
async getSocketPoint() {
|
|
125
136
|
let response;
|
|
126
137
|
try {
|
|
127
138
|
response = await global.fetch(this.serverSubscribePointUrl);
|
|
@@ -137,10 +148,11 @@ class SimpleConnector {
|
|
|
137
148
|
const responseType = response.headers.get('Content-Type') ||
|
|
138
149
|
response.headers.get('content-type');
|
|
139
150
|
if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
|
|
140
|
-
const {
|
|
151
|
+
const { socketUrl, subscribeUrl, path } = await response.json();
|
|
141
152
|
return {
|
|
142
|
-
url,
|
|
143
153
|
path,
|
|
154
|
+
subscribeUrl,
|
|
155
|
+
socketUrl,
|
|
144
156
|
};
|
|
145
157
|
}
|
|
146
158
|
else {
|
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.9",
|
|
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
|
}
|