@qwe8652591/abap-recursive-query 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +223 -0
- package/dist/cli/consumer-cli.d.ts +8 -0
- package/dist/cli/consumer-cli.d.ts.map +1 -0
- package/dist/cli/consumer-cli.js +180 -0
- package/dist/cli/producer-cli.d.ts +8 -0
- package/dist/cli/producer-cli.d.ts.map +1 -0
- package/dist/cli/producer-cli.js +249 -0
- package/dist/cli/query-object.d.ts +3 -0
- package/dist/cli/query-object.d.ts.map +1 -0
- package/dist/cli/query-object.js +486 -0
- package/dist/common/FilterCache.d.ts +62 -0
- package/dist/common/FilterCache.d.ts.map +1 -0
- package/dist/common/FilterCache.js +119 -0
- package/dist/common/RedisQueueManager.d.ts +170 -0
- package/dist/common/RedisQueueManager.d.ts.map +1 -0
- package/dist/common/RedisQueueManager.js +663 -0
- package/dist/common/abapStructures.d.ts +391 -0
- package/dist/common/abapStructures.d.ts.map +1 -0
- package/dist/common/abapStructures.js +2 -0
- package/dist/common/config.d.ts +66 -0
- package/dist/common/config.d.ts.map +1 -0
- package/dist/common/config.js +56 -0
- package/dist/common/index.d.ts +13 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +38 -0
- package/dist/common/recursiveQueryConfig.d.ts +77 -0
- package/dist/common/recursiveQueryConfig.d.ts.map +1 -0
- package/dist/common/recursiveQueryConfig.js +129 -0
- package/dist/common/tableStructures.d.ts +176 -0
- package/dist/common/tableStructures.d.ts.map +1 -0
- package/dist/common/tableStructures.js +10 -0
- package/dist/common/types.d.ts +104 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/common/types.js +31 -0
- package/dist/common/utils.d.ts +57 -0
- package/dist/common/utils.d.ts.map +1 -0
- package/dist/common/utils.js +300 -0
- package/dist/consumer/FileDownloadConsumer.d.ts +127 -0
- package/dist/consumer/FileDownloadConsumer.d.ts.map +1 -0
- package/dist/consumer/FileDownloadConsumer.js +1003 -0
- package/dist/consumer/generators/baseGenerator.d.ts +38 -0
- package/dist/consumer/generators/baseGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/baseGenerator.js +103 -0
- package/dist/consumer/generators/domainGenerator.d.ts +78 -0
- package/dist/consumer/generators/domainGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/domainGenerator.js +241 -0
- package/dist/consumer/generators/guiStatusGenerator.d.ts +16 -0
- package/dist/consumer/generators/guiStatusGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/guiStatusGenerator.js +48 -0
- package/dist/consumer/generators/guiTitleGenerator.d.ts +16 -0
- package/dist/consumer/generators/guiTitleGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/guiTitleGenerator.js +48 -0
- package/dist/consumer/generators/index.d.ts +14 -0
- package/dist/consumer/generators/index.d.ts.map +1 -0
- package/dist/consumer/generators/index.js +38 -0
- package/dist/consumer/generators/messageGenerator.d.ts +16 -0
- package/dist/consumer/generators/messageGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/messageGenerator.js +73 -0
- package/dist/consumer/generators/metadataGenerator.d.ts +29 -0
- package/dist/consumer/generators/metadataGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/metadataGenerator.js +135 -0
- package/dist/consumer/generators/screenGenerator.d.ts +173 -0
- package/dist/consumer/generators/screenGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/screenGenerator.js +859 -0
- package/dist/consumer/generators/structureGenerator.d.ts +36 -0
- package/dist/consumer/generators/structureGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/structureGenerator.js +131 -0
- package/dist/consumer/generators/textElementGenerator.d.ts +16 -0
- package/dist/consumer/generators/textElementGenerator.d.ts.map +1 -0
- package/dist/consumer/generators/textElementGenerator.js +70 -0
- package/dist/consumer/handlers/handleGetClass.d.ts +8 -0
- package/dist/consumer/handlers/handleGetClass.d.ts.map +1 -0
- package/dist/consumer/handlers/handleGetClass.js +18 -0
- package/dist/consumer/handlers/handleGetFunction.d.ts +8 -0
- package/dist/consumer/handlers/handleGetFunction.d.ts.map +1 -0
- package/dist/consumer/handlers/handleGetFunction.js +19 -0
- package/dist/consumer/handlers/handleGetFunctionGroup.d.ts +8 -0
- package/dist/consumer/handlers/handleGetFunctionGroup.d.ts.map +1 -0
- package/dist/consumer/handlers/handleGetFunctionGroup.js +19 -0
- package/dist/consumer/handlers/handleGetInclude.d.ts +8 -0
- package/dist/consumer/handlers/handleGetInclude.d.ts.map +1 -0
- package/dist/consumer/handlers/handleGetInclude.js +18 -0
- package/dist/consumer/handlers/handleGetProgram.d.ts +8 -0
- package/dist/consumer/handlers/handleGetProgram.d.ts.map +1 -0
- package/dist/consumer/handlers/handleGetProgram.js +27 -0
- package/dist/consumer/handlers/handleZTableQuery.d.ts +8 -0
- package/dist/consumer/handlers/handleZTableQuery.d.ts.map +1 -0
- package/dist/consumer/handlers/handleZTableQuery.js +20 -0
- package/dist/consumer/handlers/index.d.ts +10 -0
- package/dist/consumer/handlers/index.d.ts.map +1 -0
- package/dist/consumer/handlers/index.js +27 -0
- package/dist/consumer/index.d.ts +9 -0
- package/dist/consumer/index.d.ts.map +1 -0
- package/dist/consumer/index.js +24 -0
- package/dist/consumer/utils/download.d.ts +13 -0
- package/dist/consumer/utils/download.d.ts.map +1 -0
- package/dist/consumer/utils/download.js +38 -0
- package/dist/consumer/utils/index.d.ts +5 -0
- package/dist/consumer/utils/index.d.ts.map +1 -0
- package/dist/consumer/utils/index.js +20 -0
- package/dist/handlers/handleGetClass.d.ts +8 -0
- package/dist/handlers/handleGetClass.d.ts.map +1 -0
- package/dist/handlers/handleGetClass.js +19 -0
- package/dist/handlers/handleGetFunction.d.ts +8 -0
- package/dist/handlers/handleGetFunction.d.ts.map +1 -0
- package/dist/handlers/handleGetFunction.js +20 -0
- package/dist/handlers/handleGetFunctionGroup.d.ts +8 -0
- package/dist/handlers/handleGetFunctionGroup.d.ts.map +1 -0
- package/dist/handlers/handleGetFunctionGroup.js +19 -0
- package/dist/handlers/handleGetInclude.d.ts +8 -0
- package/dist/handlers/handleGetInclude.d.ts.map +1 -0
- package/dist/handlers/handleGetInclude.js +19 -0
- package/dist/handlers/handleGetInterface.d.ts +8 -0
- package/dist/handlers/handleGetInterface.d.ts.map +1 -0
- package/dist/handlers/handleGetInterface.js +19 -0
- package/dist/handlers/handleGetPackage.d.ts +8 -0
- package/dist/handlers/handleGetPackage.d.ts.map +1 -0
- package/dist/handlers/handleGetPackage.js +42 -0
- package/dist/handlers/handleGetProgram.d.ts +8 -0
- package/dist/handlers/handleGetProgram.d.ts.map +1 -0
- package/dist/handlers/handleGetProgram.js +19 -0
- package/dist/handlers/handleGetStructure.d.ts +8 -0
- package/dist/handlers/handleGetStructure.d.ts.map +1 -0
- package/dist/handlers/handleGetStructure.js +19 -0
- package/dist/handlers/handleGetTable.d.ts +8 -0
- package/dist/handlers/handleGetTable.d.ts.map +1 -0
- package/dist/handlers/handleGetTable.js +19 -0
- package/dist/handlers/handleGetTableContents.d.ts +8 -0
- package/dist/handlers/handleGetTableContents.d.ts.map +1 -0
- package/dist/handlers/handleGetTableContents.js +22 -0
- package/dist/handlers/handleGetTransaction.d.ts +8 -0
- package/dist/handlers/handleGetTransaction.d.ts.map +1 -0
- package/dist/handlers/handleGetTransaction.js +19 -0
- package/dist/handlers/handleGetTypeInfo.d.ts +8 -0
- package/dist/handlers/handleGetTypeInfo.d.ts.map +1 -0
- package/dist/handlers/handleGetTypeInfo.js +32 -0
- package/dist/handlers/handleSearchObject.d.ts +8 -0
- package/dist/handlers/handleSearchObject.d.ts.map +1 -0
- package/dist/handlers/handleSearchObject.js +20 -0
- package/dist/handlers/handleZObjectQuery.d.ts +8 -0
- package/dist/handlers/handleZObjectQuery.d.ts.map +1 -0
- package/dist/handlers/handleZObjectQuery.js +25 -0
- package/dist/handlers/handleZTableQuery.d.ts +8 -0
- package/dist/handlers/handleZTableQuery.d.ts.map +1 -0
- package/dist/handlers/handleZTableQuery.js +20 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/lib/download.d.ts +49 -0
- package/dist/lib/download.d.ts.map +1 -0
- package/dist/lib/download.js +78 -0
- package/dist/lib/index.d.ts +9 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +23 -0
- package/dist/lib/utils.d.ts +31 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +272 -0
- package/dist/producer/RecursiveQueryProducer.d.ts +92 -0
- package/dist/producer/RecursiveQueryProducer.d.ts.map +1 -0
- package/dist/producer/RecursiveQueryProducer.js +496 -0
- package/dist/producer/handlers/handleZObjectQuery.d.ts +8 -0
- package/dist/producer/handlers/handleZObjectQuery.d.ts.map +1 -0
- package/dist/producer/handlers/handleZObjectQuery.js +24 -0
- package/dist/producer/handlers/index.d.ts +6 -0
- package/dist/producer/handlers/index.d.ts.map +1 -0
- package/dist/producer/handlers/index.js +21 -0
- package/dist/producer/index.d.ts +7 -0
- package/dist/producer/index.d.ts.map +1 -0
- package/dist/producer/index.js +22 -0
- package/dist/recursive/abapStructures.d.ts +377 -0
- package/dist/recursive/abapStructures.d.ts.map +1 -0
- package/dist/recursive/abapStructures.js +2 -0
- package/dist/recursive/generate/baseGenerator.d.ts +34 -0
- package/dist/recursive/generate/baseGenerator.d.ts.map +1 -0
- package/dist/recursive/generate/baseGenerator.js +112 -0
- package/dist/recursive/generate/domainGenerator.d.ts +26 -0
- package/dist/recursive/generate/domainGenerator.d.ts.map +1 -0
- package/dist/recursive/generate/domainGenerator.js +128 -0
- package/dist/recursive/generate/functionGroupGenerator.d.ts +30 -0
- package/dist/recursive/generate/functionGroupGenerator.d.ts.map +1 -0
- package/dist/recursive/generate/functionGroupGenerator.js +90 -0
- package/dist/recursive/generate/index.d.ts +12 -0
- package/dist/recursive/generate/index.d.ts.map +1 -0
- package/dist/recursive/generate/index.js +34 -0
- package/dist/recursive/generate/messageGenerator.d.ts +16 -0
- package/dist/recursive/generate/messageGenerator.d.ts.map +1 -0
- package/dist/recursive/generate/messageGenerator.js +73 -0
- package/dist/recursive/generate/screenGenerator.d.ts +173 -0
- package/dist/recursive/generate/screenGenerator.d.ts.map +1 -0
- package/dist/recursive/generate/screenGenerator.js +858 -0
- package/dist/recursive/generate/structureGenerator.d.ts +22 -0
- package/dist/recursive/generate/structureGenerator.d.ts.map +1 -0
- package/dist/recursive/generate/structureGenerator.js +88 -0
- package/dist/recursive/generate/textElementGenerator.d.ts +16 -0
- package/dist/recursive/generate/textElementGenerator.d.ts.map +1 -0
- package/dist/recursive/generate/textElementGenerator.js +68 -0
- package/dist/recursive/handleRecursiveObjectQuery.d.ts +94 -0
- package/dist/recursive/handleRecursiveObjectQuery.d.ts.map +1 -0
- package/dist/recursive/handleRecursiveObjectQuery.js +219 -0
- package/dist/recursive/recursiveObjectQuery.d.ts +159 -0
- package/dist/recursive/recursiveObjectQuery.d.ts.map +1 -0
- package/dist/recursive/recursiveObjectQuery.js +1358 -0
- package/dist/recursive/recursiveQueryConfig.d.ts +129 -0
- package/dist/recursive/recursiveQueryConfig.d.ts.map +1 -0
- package/dist/recursive/recursiveQueryConfig.js +133 -0
- package/dist/recursive/tableStructures.d.ts +196 -0
- package/dist/recursive/tableStructures.d.ts.map +1 -0
- package/dist/recursive/tableStructures.js +10 -0
- package/package.json +47 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 消息类生成器
|
|
3
|
+
* 生成消息类XML文件
|
|
4
|
+
*/
|
|
5
|
+
import { Message } from '../../common/abapStructures';
|
|
6
|
+
/**
|
|
7
|
+
* 生成消息类XML内容
|
|
8
|
+
* 遵循abapGit协议格式
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateMessageClassXmlContent(messages: Message[], objectName: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* 生成消息类XML文件
|
|
13
|
+
* 符合abapGit协议规范:{消息类名}.msag.xml
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateMessageClassXml(messages: Message[], objectName: string, downloadRootPath: string, resultDownloadedFiles: any[]): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=messageGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messageGenerator.d.ts","sourceRoot":"","sources":["../../../src/consumer/generators/messageGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAGtD;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CA6B9F;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CACzC,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,MAAM,EACxB,qBAAqB,EAAE,GAAG,EAAE,GAC7B,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 消息类生成器
|
|
4
|
+
* 生成消息类XML文件
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.generateMessageClassXmlContent = generateMessageClassXmlContent;
|
|
8
|
+
exports.generateMessageClassXml = generateMessageClassXml;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const baseGenerator_1 = require("./baseGenerator");
|
|
12
|
+
/**
|
|
13
|
+
* 生成消息类XML内容
|
|
14
|
+
* 遵循abapGit协议格式
|
|
15
|
+
*/
|
|
16
|
+
function generateMessageClassXmlContent(messages, objectName) {
|
|
17
|
+
let xml = '<?xml version="1.0" encoding="utf-8"?>\n';
|
|
18
|
+
xml += '<abapGit version="v1.0.0" serializer="LCL_OBJECT_MSAG" serializer_version="v1.0.0">\n';
|
|
19
|
+
xml += ' <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">\n';
|
|
20
|
+
xml += ' <asx:values>\n';
|
|
21
|
+
xml += ' <T100A>\n';
|
|
22
|
+
xml = (0, baseGenerator_1.addXmlField)(xml, 'ARBGB', objectName, ' ');
|
|
23
|
+
xml = (0, baseGenerator_1.addXmlField)(xml, 'MASTERLANG', 'E', ' ');
|
|
24
|
+
xml = (0, baseGenerator_1.addXmlField)(xml, 'FUMSG', 'N', ' ');
|
|
25
|
+
xml = (0, baseGenerator_1.addXmlField)(xml, 'STMSG', 'N', ' ');
|
|
26
|
+
xml += ' </T100A>\n';
|
|
27
|
+
xml += ' <T100>\n';
|
|
28
|
+
for (const message of messages) {
|
|
29
|
+
if (message.MSGNR && message.TEXT) {
|
|
30
|
+
xml += ' <T100>\n';
|
|
31
|
+
xml = (0, baseGenerator_1.addXmlField)(xml, 'ARBGB', objectName, ' ');
|
|
32
|
+
xml = (0, baseGenerator_1.addXmlField)(xml, 'MSGNR', message.MSGNR, ' ');
|
|
33
|
+
xml = (0, baseGenerator_1.addXmlField)(xml, 'TEXT', message.TEXT, ' ');
|
|
34
|
+
xml += ' </T100>\n';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
xml += ' </T100>\n';
|
|
38
|
+
xml += ' </asx:values>\n';
|
|
39
|
+
xml += ' </asx:abap>\n';
|
|
40
|
+
xml += '</abapGit>\n';
|
|
41
|
+
return xml;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 生成消息类XML文件
|
|
45
|
+
* 符合abapGit协议规范:{消息类名}.msag.xml
|
|
46
|
+
*/
|
|
47
|
+
async function generateMessageClassXml(messages, objectName, downloadRootPath, resultDownloadedFiles) {
|
|
48
|
+
const safeObjectName = objectName.replace(/[/\\]/g, '_');
|
|
49
|
+
// 消息类文件路径:/messages目录下
|
|
50
|
+
const baseDir = (0, path_1.join)(downloadRootPath, 'messages');
|
|
51
|
+
if (!(0, fs_1.existsSync)(baseDir)) {
|
|
52
|
+
(0, fs_1.mkdirSync)(baseDir, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
// 生成符合abapGit协议的XML内容
|
|
55
|
+
const xmlContent = generateMessageClassXmlContent(messages, objectName);
|
|
56
|
+
// 按照abapGit协议命名规范:{消息类名}.msag.xml
|
|
57
|
+
const xmlFileName = `${safeObjectName}.msag.xml`;
|
|
58
|
+
const xmlFilePath = (0, path_1.join)(baseDir, xmlFileName);
|
|
59
|
+
(0, fs_1.writeFileSync)(xmlFilePath, xmlContent, 'utf-8');
|
|
60
|
+
console.error(`导出消息类 ${objectName} 到: ${xmlFilePath}`);
|
|
61
|
+
// 记录下载统计
|
|
62
|
+
resultDownloadedFiles.push({
|
|
63
|
+
objectName: objectName,
|
|
64
|
+
objectType: 'MSAG',
|
|
65
|
+
filePath: xmlFilePath,
|
|
66
|
+
success: true,
|
|
67
|
+
metadata: {
|
|
68
|
+
messageCount: messages.length,
|
|
69
|
+
exportType: 'separate',
|
|
70
|
+
objectType: 'MSAG'
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 对象元数据生成器
|
|
3
|
+
* 生成对象的元数据 XML 文件(包括依赖关系等信息)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 对象元数据结构
|
|
7
|
+
*/
|
|
8
|
+
export interface ObjectMetadata {
|
|
9
|
+
ET_REFCLASS?: Array<{
|
|
10
|
+
CLSNAME: string;
|
|
11
|
+
}>;
|
|
12
|
+
ET_REFFUNCTION?: Array<{
|
|
13
|
+
FUNCTIONNAME: string;
|
|
14
|
+
PNAME?: string;
|
|
15
|
+
}>;
|
|
16
|
+
ET_REFPROGRAM?: Array<{
|
|
17
|
+
PROGNAME: string;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 生成对象元数据 XML
|
|
22
|
+
* @param metadata 元数据
|
|
23
|
+
* @param objectName 对象名称
|
|
24
|
+
* @param objectType 对象类型
|
|
25
|
+
* @param baseDir 基础目录
|
|
26
|
+
* @param downloadedFiles 下载文件列表(可选)
|
|
27
|
+
*/
|
|
28
|
+
export declare function generateMetadataXml(metadata: ObjectMetadata, objectName: string, objectType: string, baseDir: string, downloadedFiles?: Array<any>): Promise<void>;
|
|
29
|
+
//# sourceMappingURL=metadataGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadataGenerator.d.ts","sourceRoot":"","sources":["../../../src/consumer/generators/metadataGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,MAAM,WAAW,cAAc;IAE3B,WAAW,CAAC,EAAE,KAAK,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IAEH,cAAc,CAAC,EAAE,KAAK,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IAEH,aAAa,CAAC,EAAE,KAAK,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CAMN;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACrC,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAsIf"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 对象元数据生成器
|
|
4
|
+
* 生成对象的元数据 XML 文件(包括依赖关系等信息)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.generateMetadataXml = generateMetadataXml;
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const utils_1 = require("../../common/utils");
|
|
11
|
+
const baseGenerator_1 = require("./baseGenerator");
|
|
12
|
+
/**
|
|
13
|
+
* 生成对象元数据 XML
|
|
14
|
+
* @param metadata 元数据
|
|
15
|
+
* @param objectName 对象名称
|
|
16
|
+
* @param objectType 对象类型
|
|
17
|
+
* @param baseDir 基础目录
|
|
18
|
+
* @param downloadedFiles 下载文件列表(可选)
|
|
19
|
+
*/
|
|
20
|
+
async function generateMetadataXml(metadata, objectName, objectType, baseDir, downloadedFiles) {
|
|
21
|
+
try {
|
|
22
|
+
const hasRefClass = metadata.ET_REFCLASS && metadata.ET_REFCLASS.length > 0;
|
|
23
|
+
const hasRefFunction = metadata.ET_REFFUNCTION && metadata.ET_REFFUNCTION.length > 0;
|
|
24
|
+
const hasRefProgram = metadata.ET_REFPROGRAM && metadata.ET_REFPROGRAM.length > 0;
|
|
25
|
+
// 如果没有任何元数据,则不生成文件
|
|
26
|
+
if (!hasRefClass && !hasRefFunction && !hasRefProgram) {
|
|
27
|
+
console.error(`[元数据生成器] 对象 ${objectName} 没有元数据,跳过生成`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// 计算依赖总数
|
|
31
|
+
const totalDeps = (hasRefClass ? metadata.ET_REFCLASS.length : 0) +
|
|
32
|
+
(hasRefFunction ? metadata.ET_REFFUNCTION.length : 0) +
|
|
33
|
+
(hasRefProgram ? metadata.ET_REFPROGRAM.length : 0);
|
|
34
|
+
console.error(`[元数据生成器] 对象 ${objectName} 有 ${totalDeps} 个依赖项`);
|
|
35
|
+
console.error(`[元数据生成器] - 引用类: ${hasRefClass ? metadata.ET_REFCLASS.length : 0}`);
|
|
36
|
+
console.error(`[元数据生成器] - 引用函数: ${hasRefFunction ? metadata.ET_REFFUNCTION.length : 0}`);
|
|
37
|
+
console.error(`[元数据生成器] - 引用程序: ${hasRefProgram ? metadata.ET_REFPROGRAM.length : 0}`);
|
|
38
|
+
// 构建 XML 内容
|
|
39
|
+
let xmlContent = '<?xml version="1.0" encoding="utf-8"?>\n';
|
|
40
|
+
xmlContent += '<abapGit version="v1.0.0" serializer="LCL_OBJECT_METADATA" serializer_version="v1.0.0">\n';
|
|
41
|
+
xmlContent += ' <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">\n';
|
|
42
|
+
xmlContent += ' <asx:values>\n';
|
|
43
|
+
xmlContent += ' <METADATA>\n';
|
|
44
|
+
// 添加对象信息
|
|
45
|
+
xmlContent += ' <OBJECT_INFO>\n';
|
|
46
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'OBJECT_NAME', (0, utils_1.sanitizeObjectName)(objectName), ' ');
|
|
47
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'OBJECT_TYPE', objectType, ' ');
|
|
48
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'EXPORT_TIMESTAMP', new Date().toISOString(), ' ');
|
|
49
|
+
xmlContent += ' </OBJECT_INFO>\n';
|
|
50
|
+
// 依赖关系部分
|
|
51
|
+
xmlContent += ' <DEPENDENCIES>\n';
|
|
52
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'TOTAL_DEPENDENCIES', totalDeps, ' ');
|
|
53
|
+
// 添加引用的类
|
|
54
|
+
if (hasRefClass) {
|
|
55
|
+
xmlContent += ' <REFERENCED_CLASSES>\n';
|
|
56
|
+
for (const cls of metadata.ET_REFCLASS) {
|
|
57
|
+
if (!cls.CLSNAME)
|
|
58
|
+
continue;
|
|
59
|
+
xmlContent += ' <CLASS>\n';
|
|
60
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'CLSNAME', (0, utils_1.sanitizeObjectName)(cls.CLSNAME), ' ');
|
|
61
|
+
xmlContent += ' </CLASS>\n';
|
|
62
|
+
}
|
|
63
|
+
xmlContent += ' </REFERENCED_CLASSES>\n';
|
|
64
|
+
}
|
|
65
|
+
// 添加引用的函数
|
|
66
|
+
if (hasRefFunction) {
|
|
67
|
+
xmlContent += ' <REFERENCED_FUNCTIONS>\n';
|
|
68
|
+
for (const func of metadata.ET_REFFUNCTION) {
|
|
69
|
+
if (!func.FUNCTIONNAME)
|
|
70
|
+
continue;
|
|
71
|
+
xmlContent += ' <FUNCTION>\n';
|
|
72
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'FUNCTIONNAME', (0, utils_1.sanitizeObjectName)(func.FUNCTIONNAME), ' ');
|
|
73
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'PNAME', func.PNAME ? (0, utils_1.sanitizeObjectName)(func.PNAME) : func.PNAME, ' ');
|
|
74
|
+
xmlContent += ' </FUNCTION>\n';
|
|
75
|
+
}
|
|
76
|
+
xmlContent += ' </REFERENCED_FUNCTIONS>\n';
|
|
77
|
+
}
|
|
78
|
+
// 添加引用的程序
|
|
79
|
+
if (hasRefProgram) {
|
|
80
|
+
xmlContent += ' <REFERENCED_PROGRAMS>\n';
|
|
81
|
+
for (const prog of metadata.ET_REFPROGRAM) {
|
|
82
|
+
if (!prog.PROGNAME)
|
|
83
|
+
continue;
|
|
84
|
+
xmlContent += ' <PROGRAM>\n';
|
|
85
|
+
xmlContent = (0, baseGenerator_1.addXmlField)(xmlContent, 'PROGNAME', (0, utils_1.sanitizeObjectName)(prog.PROGNAME), ' ');
|
|
86
|
+
xmlContent += ' </PROGRAM>\n';
|
|
87
|
+
}
|
|
88
|
+
xmlContent += ' </REFERENCED_PROGRAMS>\n';
|
|
89
|
+
}
|
|
90
|
+
xmlContent += ' </DEPENDENCIES>\n';
|
|
91
|
+
// 🔮 未来可扩展的元数据部分
|
|
92
|
+
// xmlContent += ' <USED_TABLES>...</USED_TABLES>\n';
|
|
93
|
+
// xmlContent += ' <DDIC_OBJECTS>...</DDIC_OBJECTS>\n';
|
|
94
|
+
// xmlContent += ' <MESSAGE_CLASSES>...</MESSAGE_CLASSES>\n';
|
|
95
|
+
xmlContent += ' </METADATA>\n';
|
|
96
|
+
xmlContent += ' </asx:values>\n';
|
|
97
|
+
xmlContent += ' </asx:abap>\n';
|
|
98
|
+
xmlContent += '</abapGit>\n';
|
|
99
|
+
// 确保目录存在
|
|
100
|
+
const metadataDir = (0, path_1.join)(baseDir, 'metadata');
|
|
101
|
+
if (!(0, fs_1.existsSync)(metadataDir)) {
|
|
102
|
+
(0, fs_1.mkdirSync)(metadataDir, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
// 保存文件
|
|
105
|
+
const sanitizedName = (0, utils_1.sanitizeObjectName)(objectName);
|
|
106
|
+
const fileName = `${sanitizedName}.metadata.xml`;
|
|
107
|
+
const filePath = (0, path_1.join)(metadataDir, fileName);
|
|
108
|
+
(0, fs_1.writeFileSync)(filePath, xmlContent, 'utf-8');
|
|
109
|
+
console.error(`[元数据生成器] 元数据XML生成成功: ${filePath}`);
|
|
110
|
+
// 记录到下载文件列表
|
|
111
|
+
if (downloadedFiles) {
|
|
112
|
+
downloadedFiles.push({
|
|
113
|
+
objectName,
|
|
114
|
+
objectType: 'METADATA',
|
|
115
|
+
filePath,
|
|
116
|
+
success: true
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
122
|
+
console.error(`[元数据生成器] 生成元数据XML失败: ${errorMessage}`);
|
|
123
|
+
// 记录失败
|
|
124
|
+
if (downloadedFiles) {
|
|
125
|
+
downloadedFiles.push({
|
|
126
|
+
objectName,
|
|
127
|
+
objectType: 'METADATA',
|
|
128
|
+
filePath: '',
|
|
129
|
+
success: false,
|
|
130
|
+
error: errorMessage
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一屏幕生成器 (优化版)
|
|
3
|
+
* 整合屏幕字段和流程逻辑,生成完整的屏幕XML文件
|
|
4
|
+
* 遵循abapGit协议规范,完全符合SAP标准格式
|
|
5
|
+
*
|
|
6
|
+
* 功能说明:
|
|
7
|
+
* 1. 支持单屏幕和多屏幕XML生成
|
|
8
|
+
* 2. 完整的头部、容器、字段和流程逻辑整合
|
|
9
|
+
* 3. 数据验证和格式化
|
|
10
|
+
* 4. 向后兼容旧版本接口
|
|
11
|
+
*
|
|
12
|
+
* @author Unified Screen Generator
|
|
13
|
+
* @version 2.0.0
|
|
14
|
+
*/
|
|
15
|
+
import { ScreenField, ScreenFlow, ScreenDesc } from '../../common/abapStructures';
|
|
16
|
+
/**
|
|
17
|
+
* 屏幕完整数据接口
|
|
18
|
+
* 包含生成完整屏幕XML所需的所有信息
|
|
19
|
+
*/
|
|
20
|
+
export interface ScreenData {
|
|
21
|
+
screenNumber: string;
|
|
22
|
+
programName: string;
|
|
23
|
+
header?: ScreenHeader;
|
|
24
|
+
containers?: ScreenContainer[];
|
|
25
|
+
fields?: ScreenField[];
|
|
26
|
+
flowLogic?: ScreenFlow[];
|
|
27
|
+
screenDesc?: ScreenDesc;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 屏幕头部信息接口
|
|
31
|
+
* 定义屏幕的基本属性和元数据
|
|
32
|
+
*/
|
|
33
|
+
export interface ScreenHeader {
|
|
34
|
+
PROGRAM: string;
|
|
35
|
+
SCREEN: string;
|
|
36
|
+
LANGUAGE?: string;
|
|
37
|
+
DESCRIPT?: string;
|
|
38
|
+
TYPE?: string;
|
|
39
|
+
NEXTSCREEN?: string;
|
|
40
|
+
LINES?: string;
|
|
41
|
+
COLUMNS?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 屏幕容器接口
|
|
45
|
+
* 定义屏幕中的容器元素
|
|
46
|
+
*/
|
|
47
|
+
export interface ScreenContainer {
|
|
48
|
+
TYPE: string;
|
|
49
|
+
NAME: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 程序目录信息接口
|
|
53
|
+
* PROGDIR包含程序级别的元数据
|
|
54
|
+
*/
|
|
55
|
+
export interface ProgramDirectory {
|
|
56
|
+
NAME: string;
|
|
57
|
+
SUBC?: string;
|
|
58
|
+
RLOAD?: string;
|
|
59
|
+
FIXPT?: string;
|
|
60
|
+
UCCHECK?: string;
|
|
61
|
+
APPL?: string;
|
|
62
|
+
SECU?: string;
|
|
63
|
+
CNAM?: string;
|
|
64
|
+
CDAT?: string;
|
|
65
|
+
UNAM?: string;
|
|
66
|
+
UDAT?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 验证屏幕数据完整性
|
|
70
|
+
* 对所有输入数据进行严格验证,确保生成的XML符合规范
|
|
71
|
+
*/
|
|
72
|
+
export declare function validateScreenData(screenData: ScreenData): {
|
|
73
|
+
valid: boolean;
|
|
74
|
+
errors: string[];
|
|
75
|
+
warnings: string[];
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* 生成多屏幕XML内容
|
|
79
|
+
* 支持一个文件包含多个屏幕定义,符合abapGit标准格式
|
|
80
|
+
*
|
|
81
|
+
* XML结构:
|
|
82
|
+
* <?xml version="1.0" encoding="utf-8"?>
|
|
83
|
+
* <abapGit>
|
|
84
|
+
* <asx:abap>
|
|
85
|
+
* <asx:values>
|
|
86
|
+
* <PROGDIR>...</PROGDIR> (可选)
|
|
87
|
+
* <DYNPROS>
|
|
88
|
+
* <item>...</item> (屏幕1)
|
|
89
|
+
* <item>...</item> (屏幕2)
|
|
90
|
+
* ...
|
|
91
|
+
* </DYNPROS>
|
|
92
|
+
* </asx:values>
|
|
93
|
+
* </asx:abap>
|
|
94
|
+
* </abapGit>
|
|
95
|
+
*/
|
|
96
|
+
export declare function generateMultipleScreensXmlContent(screens: ScreenData[], programName: string, programType: string, includePROGDIR?: boolean): string;
|
|
97
|
+
/**
|
|
98
|
+
* 屏幕缓存管理器(多实例模式)
|
|
99
|
+
* 用于收集同一程序的多个屏幕,最后统一生成一个文件
|
|
100
|
+
*
|
|
101
|
+
* 优化说明:
|
|
102
|
+
* 1. 使用 Map<string, Map<string, ScreenData>> 结构提升查找性能(O(1))
|
|
103
|
+
* 2. 支持多个下载进程,每个进程创建独立的 ScreenCache 实例
|
|
104
|
+
* 3. 不再使用单例模式,避免多进程数据混乱
|
|
105
|
+
*/
|
|
106
|
+
export declare class ScreenCache {
|
|
107
|
+
private cache;
|
|
108
|
+
constructor();
|
|
109
|
+
/**
|
|
110
|
+
* 添加屏幕到缓存(只收集数据,不涉及文件生成)
|
|
111
|
+
* O(1) 时间复杂度的重复检测,如果屏幕号已存在则跳过
|
|
112
|
+
*/
|
|
113
|
+
addScreen(programName: string, screenData: ScreenData): void;
|
|
114
|
+
/**
|
|
115
|
+
* 获取缓存的屏幕数据
|
|
116
|
+
*/
|
|
117
|
+
getScreens(objectName: string): ScreenData[] | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* 生成指定程序的所有屏幕XML
|
|
120
|
+
*/
|
|
121
|
+
generateForProgram(programName: string, downloadRootPath: string, resultDownloadedFiles: any[]): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* 生成所有缓存的屏幕XML
|
|
124
|
+
*/
|
|
125
|
+
generateAll(downloadRootPath: string, resultDownloadedFiles: any[]): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* 清除指定程序的缓存
|
|
128
|
+
*/
|
|
129
|
+
clear(programName?: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* 获取缓存状态
|
|
132
|
+
*/
|
|
133
|
+
getStatus(): {
|
|
134
|
+
programName: string;
|
|
135
|
+
screenCount: number;
|
|
136
|
+
}[];
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 添加原始屏幕数据到缓存(简化版)
|
|
140
|
+
* 直接处理从 SAP 返回的原始数据,自动按屏幕号分组
|
|
141
|
+
*
|
|
142
|
+
* 【数据收集阶段】只负责收集和分组数据,不涉及文件生成
|
|
143
|
+
*
|
|
144
|
+
* @param cache ScreenCache 实例(每个下载进程使用独立实例)
|
|
145
|
+
* @param programName 程序名(PROGNAME)
|
|
146
|
+
* @param fields 屏幕字段数组(ISCREENFIELD,可选)
|
|
147
|
+
* @param flowLogic 流程逻辑数组(ISCREENFLOW,可选)
|
|
148
|
+
* @param screenDescs 屏幕描述数组(ISCREENDESC,可选)
|
|
149
|
+
*/
|
|
150
|
+
export declare function addScreenDataToCache(cache: ScreenCache, programName: string, fields?: ScreenField[], flowLogic?: ScreenFlow[], screenDescs?: ScreenDesc[]): void;
|
|
151
|
+
/**
|
|
152
|
+
* 完成屏幕收集,批量生成所有缓存的屏幕XML文件
|
|
153
|
+
*
|
|
154
|
+
* 【文件生成阶段】在处理完所有屏幕数据收集后调用此函数
|
|
155
|
+
*
|
|
156
|
+
* @param cache ScreenCache 实例(每个下载进程使用独立实例)
|
|
157
|
+
* @param downloadRootPath 下载根路径
|
|
158
|
+
* @param resultDownloadedFiles 下载结果记录数组
|
|
159
|
+
*/
|
|
160
|
+
export declare function finalizeScreenGeneration(cache: ScreenCache, downloadRootPath: string, resultDownloadedFiles: any[]): Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* 生成多屏幕XML文件
|
|
163
|
+
* 将多个屏幕定义整合到一个文件中,符合abapGit标准格式
|
|
164
|
+
*
|
|
165
|
+
* @param screens 屏幕数据数组
|
|
166
|
+
* @param programName 程序名称
|
|
167
|
+
* @param programType 程序类型(M=模块池等)
|
|
168
|
+
* @param downloadRootPath 下载根路径
|
|
169
|
+
* @param resultDownloadedFiles 下载结果记录数组
|
|
170
|
+
* @param includePROGDIR 是否包含PROGDIR节点(默认true)
|
|
171
|
+
*/
|
|
172
|
+
export declare function generateMultipleScreensXml(screens: ScreenData[], programName: string, downloadRootPath: string, resultDownloadedFiles: any[], includePROGDIR?: boolean, programType?: string): Promise<void>;
|
|
173
|
+
//# sourceMappingURL=screenGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenGenerator.d.ts","sourceRoot":"","sources":["../../../src/consumer/generators/screenGenerator.ts"],"names":[],"mappings":"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"}
|