@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.
Files changed (210) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +223 -0
  3. package/dist/cli/consumer-cli.d.ts +8 -0
  4. package/dist/cli/consumer-cli.d.ts.map +1 -0
  5. package/dist/cli/consumer-cli.js +180 -0
  6. package/dist/cli/producer-cli.d.ts +8 -0
  7. package/dist/cli/producer-cli.d.ts.map +1 -0
  8. package/dist/cli/producer-cli.js +249 -0
  9. package/dist/cli/query-object.d.ts +3 -0
  10. package/dist/cli/query-object.d.ts.map +1 -0
  11. package/dist/cli/query-object.js +486 -0
  12. package/dist/common/FilterCache.d.ts +62 -0
  13. package/dist/common/FilterCache.d.ts.map +1 -0
  14. package/dist/common/FilterCache.js +119 -0
  15. package/dist/common/RedisQueueManager.d.ts +170 -0
  16. package/dist/common/RedisQueueManager.d.ts.map +1 -0
  17. package/dist/common/RedisQueueManager.js +663 -0
  18. package/dist/common/abapStructures.d.ts +391 -0
  19. package/dist/common/abapStructures.d.ts.map +1 -0
  20. package/dist/common/abapStructures.js +2 -0
  21. package/dist/common/config.d.ts +66 -0
  22. package/dist/common/config.d.ts.map +1 -0
  23. package/dist/common/config.js +56 -0
  24. package/dist/common/index.d.ts +13 -0
  25. package/dist/common/index.d.ts.map +1 -0
  26. package/dist/common/index.js +38 -0
  27. package/dist/common/recursiveQueryConfig.d.ts +77 -0
  28. package/dist/common/recursiveQueryConfig.d.ts.map +1 -0
  29. package/dist/common/recursiveQueryConfig.js +129 -0
  30. package/dist/common/tableStructures.d.ts +176 -0
  31. package/dist/common/tableStructures.d.ts.map +1 -0
  32. package/dist/common/tableStructures.js +10 -0
  33. package/dist/common/types.d.ts +104 -0
  34. package/dist/common/types.d.ts.map +1 -0
  35. package/dist/common/types.js +31 -0
  36. package/dist/common/utils.d.ts +57 -0
  37. package/dist/common/utils.d.ts.map +1 -0
  38. package/dist/common/utils.js +300 -0
  39. package/dist/consumer/FileDownloadConsumer.d.ts +127 -0
  40. package/dist/consumer/FileDownloadConsumer.d.ts.map +1 -0
  41. package/dist/consumer/FileDownloadConsumer.js +1003 -0
  42. package/dist/consumer/generators/baseGenerator.d.ts +38 -0
  43. package/dist/consumer/generators/baseGenerator.d.ts.map +1 -0
  44. package/dist/consumer/generators/baseGenerator.js +103 -0
  45. package/dist/consumer/generators/domainGenerator.d.ts +78 -0
  46. package/dist/consumer/generators/domainGenerator.d.ts.map +1 -0
  47. package/dist/consumer/generators/domainGenerator.js +241 -0
  48. package/dist/consumer/generators/guiStatusGenerator.d.ts +16 -0
  49. package/dist/consumer/generators/guiStatusGenerator.d.ts.map +1 -0
  50. package/dist/consumer/generators/guiStatusGenerator.js +48 -0
  51. package/dist/consumer/generators/guiTitleGenerator.d.ts +16 -0
  52. package/dist/consumer/generators/guiTitleGenerator.d.ts.map +1 -0
  53. package/dist/consumer/generators/guiTitleGenerator.js +48 -0
  54. package/dist/consumer/generators/index.d.ts +14 -0
  55. package/dist/consumer/generators/index.d.ts.map +1 -0
  56. package/dist/consumer/generators/index.js +38 -0
  57. package/dist/consumer/generators/messageGenerator.d.ts +16 -0
  58. package/dist/consumer/generators/messageGenerator.d.ts.map +1 -0
  59. package/dist/consumer/generators/messageGenerator.js +73 -0
  60. package/dist/consumer/generators/metadataGenerator.d.ts +29 -0
  61. package/dist/consumer/generators/metadataGenerator.d.ts.map +1 -0
  62. package/dist/consumer/generators/metadataGenerator.js +135 -0
  63. package/dist/consumer/generators/screenGenerator.d.ts +173 -0
  64. package/dist/consumer/generators/screenGenerator.d.ts.map +1 -0
  65. package/dist/consumer/generators/screenGenerator.js +859 -0
  66. package/dist/consumer/generators/structureGenerator.d.ts +36 -0
  67. package/dist/consumer/generators/structureGenerator.d.ts.map +1 -0
  68. package/dist/consumer/generators/structureGenerator.js +131 -0
  69. package/dist/consumer/generators/textElementGenerator.d.ts +16 -0
  70. package/dist/consumer/generators/textElementGenerator.d.ts.map +1 -0
  71. package/dist/consumer/generators/textElementGenerator.js +70 -0
  72. package/dist/consumer/handlers/handleGetClass.d.ts +8 -0
  73. package/dist/consumer/handlers/handleGetClass.d.ts.map +1 -0
  74. package/dist/consumer/handlers/handleGetClass.js +18 -0
  75. package/dist/consumer/handlers/handleGetFunction.d.ts +8 -0
  76. package/dist/consumer/handlers/handleGetFunction.d.ts.map +1 -0
  77. package/dist/consumer/handlers/handleGetFunction.js +19 -0
  78. package/dist/consumer/handlers/handleGetFunctionGroup.d.ts +8 -0
  79. package/dist/consumer/handlers/handleGetFunctionGroup.d.ts.map +1 -0
  80. package/dist/consumer/handlers/handleGetFunctionGroup.js +19 -0
  81. package/dist/consumer/handlers/handleGetInclude.d.ts +8 -0
  82. package/dist/consumer/handlers/handleGetInclude.d.ts.map +1 -0
  83. package/dist/consumer/handlers/handleGetInclude.js +18 -0
  84. package/dist/consumer/handlers/handleGetProgram.d.ts +8 -0
  85. package/dist/consumer/handlers/handleGetProgram.d.ts.map +1 -0
  86. package/dist/consumer/handlers/handleGetProgram.js +27 -0
  87. package/dist/consumer/handlers/handleZTableQuery.d.ts +8 -0
  88. package/dist/consumer/handlers/handleZTableQuery.d.ts.map +1 -0
  89. package/dist/consumer/handlers/handleZTableQuery.js +20 -0
  90. package/dist/consumer/handlers/index.d.ts +10 -0
  91. package/dist/consumer/handlers/index.d.ts.map +1 -0
  92. package/dist/consumer/handlers/index.js +27 -0
  93. package/dist/consumer/index.d.ts +9 -0
  94. package/dist/consumer/index.d.ts.map +1 -0
  95. package/dist/consumer/index.js +24 -0
  96. package/dist/consumer/utils/download.d.ts +13 -0
  97. package/dist/consumer/utils/download.d.ts.map +1 -0
  98. package/dist/consumer/utils/download.js +38 -0
  99. package/dist/consumer/utils/index.d.ts +5 -0
  100. package/dist/consumer/utils/index.d.ts.map +1 -0
  101. package/dist/consumer/utils/index.js +20 -0
  102. package/dist/handlers/handleGetClass.d.ts +8 -0
  103. package/dist/handlers/handleGetClass.d.ts.map +1 -0
  104. package/dist/handlers/handleGetClass.js +19 -0
  105. package/dist/handlers/handleGetFunction.d.ts +8 -0
  106. package/dist/handlers/handleGetFunction.d.ts.map +1 -0
  107. package/dist/handlers/handleGetFunction.js +20 -0
  108. package/dist/handlers/handleGetFunctionGroup.d.ts +8 -0
  109. package/dist/handlers/handleGetFunctionGroup.d.ts.map +1 -0
  110. package/dist/handlers/handleGetFunctionGroup.js +19 -0
  111. package/dist/handlers/handleGetInclude.d.ts +8 -0
  112. package/dist/handlers/handleGetInclude.d.ts.map +1 -0
  113. package/dist/handlers/handleGetInclude.js +19 -0
  114. package/dist/handlers/handleGetInterface.d.ts +8 -0
  115. package/dist/handlers/handleGetInterface.d.ts.map +1 -0
  116. package/dist/handlers/handleGetInterface.js +19 -0
  117. package/dist/handlers/handleGetPackage.d.ts +8 -0
  118. package/dist/handlers/handleGetPackage.d.ts.map +1 -0
  119. package/dist/handlers/handleGetPackage.js +42 -0
  120. package/dist/handlers/handleGetProgram.d.ts +8 -0
  121. package/dist/handlers/handleGetProgram.d.ts.map +1 -0
  122. package/dist/handlers/handleGetProgram.js +19 -0
  123. package/dist/handlers/handleGetStructure.d.ts +8 -0
  124. package/dist/handlers/handleGetStructure.d.ts.map +1 -0
  125. package/dist/handlers/handleGetStructure.js +19 -0
  126. package/dist/handlers/handleGetTable.d.ts +8 -0
  127. package/dist/handlers/handleGetTable.d.ts.map +1 -0
  128. package/dist/handlers/handleGetTable.js +19 -0
  129. package/dist/handlers/handleGetTableContents.d.ts +8 -0
  130. package/dist/handlers/handleGetTableContents.d.ts.map +1 -0
  131. package/dist/handlers/handleGetTableContents.js +22 -0
  132. package/dist/handlers/handleGetTransaction.d.ts +8 -0
  133. package/dist/handlers/handleGetTransaction.d.ts.map +1 -0
  134. package/dist/handlers/handleGetTransaction.js +19 -0
  135. package/dist/handlers/handleGetTypeInfo.d.ts +8 -0
  136. package/dist/handlers/handleGetTypeInfo.d.ts.map +1 -0
  137. package/dist/handlers/handleGetTypeInfo.js +32 -0
  138. package/dist/handlers/handleSearchObject.d.ts +8 -0
  139. package/dist/handlers/handleSearchObject.d.ts.map +1 -0
  140. package/dist/handlers/handleSearchObject.js +20 -0
  141. package/dist/handlers/handleZObjectQuery.d.ts +8 -0
  142. package/dist/handlers/handleZObjectQuery.d.ts.map +1 -0
  143. package/dist/handlers/handleZObjectQuery.js +25 -0
  144. package/dist/handlers/handleZTableQuery.d.ts +8 -0
  145. package/dist/handlers/handleZTableQuery.d.ts.map +1 -0
  146. package/dist/handlers/handleZTableQuery.js +20 -0
  147. package/dist/index.d.ts +17 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +45 -0
  150. package/dist/lib/download.d.ts +49 -0
  151. package/dist/lib/download.d.ts.map +1 -0
  152. package/dist/lib/download.js +78 -0
  153. package/dist/lib/index.d.ts +9 -0
  154. package/dist/lib/index.d.ts.map +1 -0
  155. package/dist/lib/index.js +23 -0
  156. package/dist/lib/utils.d.ts +31 -0
  157. package/dist/lib/utils.d.ts.map +1 -0
  158. package/dist/lib/utils.js +272 -0
  159. package/dist/producer/RecursiveQueryProducer.d.ts +92 -0
  160. package/dist/producer/RecursiveQueryProducer.d.ts.map +1 -0
  161. package/dist/producer/RecursiveQueryProducer.js +496 -0
  162. package/dist/producer/handlers/handleZObjectQuery.d.ts +8 -0
  163. package/dist/producer/handlers/handleZObjectQuery.d.ts.map +1 -0
  164. package/dist/producer/handlers/handleZObjectQuery.js +24 -0
  165. package/dist/producer/handlers/index.d.ts +6 -0
  166. package/dist/producer/handlers/index.d.ts.map +1 -0
  167. package/dist/producer/handlers/index.js +21 -0
  168. package/dist/producer/index.d.ts +7 -0
  169. package/dist/producer/index.d.ts.map +1 -0
  170. package/dist/producer/index.js +22 -0
  171. package/dist/recursive/abapStructures.d.ts +377 -0
  172. package/dist/recursive/abapStructures.d.ts.map +1 -0
  173. package/dist/recursive/abapStructures.js +2 -0
  174. package/dist/recursive/generate/baseGenerator.d.ts +34 -0
  175. package/dist/recursive/generate/baseGenerator.d.ts.map +1 -0
  176. package/dist/recursive/generate/baseGenerator.js +112 -0
  177. package/dist/recursive/generate/domainGenerator.d.ts +26 -0
  178. package/dist/recursive/generate/domainGenerator.d.ts.map +1 -0
  179. package/dist/recursive/generate/domainGenerator.js +128 -0
  180. package/dist/recursive/generate/functionGroupGenerator.d.ts +30 -0
  181. package/dist/recursive/generate/functionGroupGenerator.d.ts.map +1 -0
  182. package/dist/recursive/generate/functionGroupGenerator.js +90 -0
  183. package/dist/recursive/generate/index.d.ts +12 -0
  184. package/dist/recursive/generate/index.d.ts.map +1 -0
  185. package/dist/recursive/generate/index.js +34 -0
  186. package/dist/recursive/generate/messageGenerator.d.ts +16 -0
  187. package/dist/recursive/generate/messageGenerator.d.ts.map +1 -0
  188. package/dist/recursive/generate/messageGenerator.js +73 -0
  189. package/dist/recursive/generate/screenGenerator.d.ts +173 -0
  190. package/dist/recursive/generate/screenGenerator.d.ts.map +1 -0
  191. package/dist/recursive/generate/screenGenerator.js +858 -0
  192. package/dist/recursive/generate/structureGenerator.d.ts +22 -0
  193. package/dist/recursive/generate/structureGenerator.d.ts.map +1 -0
  194. package/dist/recursive/generate/structureGenerator.js +88 -0
  195. package/dist/recursive/generate/textElementGenerator.d.ts +16 -0
  196. package/dist/recursive/generate/textElementGenerator.d.ts.map +1 -0
  197. package/dist/recursive/generate/textElementGenerator.js +68 -0
  198. package/dist/recursive/handleRecursiveObjectQuery.d.ts +94 -0
  199. package/dist/recursive/handleRecursiveObjectQuery.d.ts.map +1 -0
  200. package/dist/recursive/handleRecursiveObjectQuery.js +219 -0
  201. package/dist/recursive/recursiveObjectQuery.d.ts +159 -0
  202. package/dist/recursive/recursiveObjectQuery.d.ts.map +1 -0
  203. package/dist/recursive/recursiveObjectQuery.js +1358 -0
  204. package/dist/recursive/recursiveQueryConfig.d.ts +129 -0
  205. package/dist/recursive/recursiveQueryConfig.d.ts.map +1 -0
  206. package/dist/recursive/recursiveQueryConfig.js +133 -0
  207. package/dist/recursive/tableStructures.d.ts +196 -0
  208. package/dist/recursive/tableStructures.d.ts.map +1 -0
  209. package/dist/recursive/tableStructures.js +10 -0
  210. package/package.json +47 -0
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ /**
3
+ * 域生成器
4
+ * 生成ABAP域定义文件
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.inferDomainType = inferDomainType;
8
+ exports.generateConstantName = generateConstantName;
9
+ exports.generateDomainContent = generateDomainContent;
10
+ /**
11
+ * 推断域类型
12
+ */
13
+ function inferDomainType(domainData) {
14
+ if (!domainData || domainData.length === 0) {
15
+ return 'c LENGTH 1';
16
+ }
17
+ // 分析所有值的长度和类型
18
+ let maxLength = 0;
19
+ let hasNumeric = true;
20
+ let hasAlpha = false;
21
+ let hasDate = true;
22
+ let hasTime = true;
23
+ for (const item of domainData) {
24
+ const value = item.DOMVALUE_L || '';
25
+ maxLength = Math.max(maxLength, value.length);
26
+ // 检查是否为数字
27
+ if (!/^\d+$/.test(value)) {
28
+ hasNumeric = false;
29
+ }
30
+ // 检查是否包含字母
31
+ if (/[a-zA-Z]/.test(value)) {
32
+ hasAlpha = true;
33
+ }
34
+ // 检查是否为日期格式 (YYYYMMDD)
35
+ if (!/^\d{8}$/.test(value)) {
36
+ hasDate = false;
37
+ }
38
+ // 检查是否为时间格式 (HHMMSS)
39
+ if (!/^\d{6}$/.test(value)) {
40
+ hasTime = false;
41
+ }
42
+ }
43
+ // 根据分析结果确定类型
44
+ if (hasDate && maxLength === 8) {
45
+ return 'd';
46
+ }
47
+ if (hasTime && maxLength === 6) {
48
+ return 't';
49
+ }
50
+ if (hasNumeric && !hasAlpha) {
51
+ if (maxLength <= 3) {
52
+ return 'n LENGTH 3';
53
+ }
54
+ else {
55
+ return `n LENGTH ${maxLength}`;
56
+ }
57
+ }
58
+ if (maxLength <= 1) {
59
+ return 'c LENGTH 1';
60
+ }
61
+ else {
62
+ return `c LENGTH ${maxLength}`;
63
+ }
64
+ }
65
+ /**
66
+ * 生成常量名
67
+ */
68
+ function generateConstantName(description) {
69
+ if (!description) {
70
+ return '';
71
+ }
72
+ // 移除特殊字符,转换为大写
73
+ let name = description
74
+ .replace(/[^\w\s]/g, '')
75
+ .replace(/\s+/g, '_')
76
+ .toUpperCase()
77
+ .substring(0, 20); // SAP常量名长度限制
78
+ // 确保以字母开头
79
+ if (!/^[A-Za-z]/.test(name)) {
80
+ name = 'C_' + name;
81
+ }
82
+ return name;
83
+ }
84
+ /**
85
+ * 生成域文件内容 - 生成符合ABAP标准的域定义(传统ABAP语法)
86
+ */
87
+ function generateDomainContent(domainName, domainData) {
88
+ let content = `*----------------------------------------------------------------------*\n`;
89
+ content += `* ${domainName}\n`;
90
+ content += `*----------------------------------------------------------------------*\n`;
91
+ // 如果有固定值,创建域定义
92
+ if (domainData && domainData.length > 0) {
93
+ // 去重处理,避免重复值
94
+ const uniqueValues = new Map();
95
+ domainData.forEach(item => {
96
+ const key = item.DOMVALUE_H ? `${item.DOMVALUE_L}-${item.DOMVALUE_H}` : item.DOMVALUE_L;
97
+ if (!uniqueValues.has(key)) {
98
+ uniqueValues.set(key, item);
99
+ }
100
+ });
101
+ const uniqueDomainData = Array.from(uniqueValues.values());
102
+ content += `TYPES: ${domainName.toLowerCase()} TYPE ${inferDomainType(uniqueDomainData)}.\n\n`;
103
+ // 添加固定值定义
104
+ if (uniqueDomainData.length > 0) {
105
+ content += `CONSTANTS: BEGIN OF ${domainName.toLowerCase()}_values,\n`;
106
+ uniqueDomainData.forEach((item, index) => {
107
+ const constName = generateConstantName(item.DDTEXT) || `value_${index + 1}`;
108
+ content += ` ${constName.toLowerCase()} TYPE ${domainName.toLowerCase()}`;
109
+ if (item.DOMVALUE_H) {
110
+ content += ` VALUE '${item.DOMVALUE_L}' TO '${item.DOMVALUE_H}'`;
111
+ }
112
+ else {
113
+ content += ` VALUE '${item.DOMVALUE_L}'`;
114
+ }
115
+ if (item.DDTEXT) {
116
+ content += ` ## "${item.DDTEXT.replace(/"/g, '""')}"`;
117
+ }
118
+ content += ',\n';
119
+ });
120
+ content += ` END OF ${domainName.toLowerCase()}_values.\n`;
121
+ }
122
+ }
123
+ else {
124
+ // 没有固定值的域定义
125
+ content += `TYPES: ${domainName.toLowerCase()} TYPE c LENGTH 1.\n`;
126
+ }
127
+ return content;
128
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 函数组生成器
3
+ * 生成函数组相关文件
4
+ */
5
+ /**
6
+ * 提取函数组
7
+ * 从函数组名称中提取函数组前缀
8
+ */
9
+ export declare function extractFunctionGroup(functionGroupName: string): string;
10
+ /**
11
+ * 生成函数组XML内容
12
+ * 遵循abapGit协议格式
13
+ */
14
+ export declare function generateFunctionGroupXmlContent(functionGroupName: string, functions: Array<{
15
+ FUNCNAME: string;
16
+ FMODE?: string;
17
+ STEXT?: string;
18
+ REMOTE_CALL?: string;
19
+ }>): string;
20
+ /**
21
+ * 生成函数组文件
22
+ * 符合abapGit协议规范
23
+ */
24
+ export declare function generateFunctionGroupFiles(functionGroupName: string, functions: Array<{
25
+ FUNCNAME: string;
26
+ FMODE?: string;
27
+ STEXT?: string;
28
+ REMOTE_CALL?: string;
29
+ }>, downloadRootPath: string, resultDownloadedFiles: any[]): Promise<void>;
30
+ //# sourceMappingURL=functionGroupGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functionGroupGenerator.d.ts","sourceRoot":"","sources":["../../../src/recursive/generate/functionGroupGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAItE;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC3C,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,GACH,MAAM,CAwCR;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC5C,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,EACF,gBAAgB,EAAE,MAAM,EACxB,qBAAqB,EAAE,GAAG,EAAE,GAC7B,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ /**
3
+ * 函数组生成器
4
+ * 生成函数组相关文件
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.extractFunctionGroup = extractFunctionGroup;
8
+ exports.generateFunctionGroupXmlContent = generateFunctionGroupXmlContent;
9
+ exports.generateFunctionGroupFiles = generateFunctionGroupFiles;
10
+ const fs_1 = require("fs");
11
+ const path_1 = require("path");
12
+ const baseGenerator_1 = require("./baseGenerator");
13
+ /**
14
+ * 提取函数组
15
+ * 从函数组名称中提取函数组前缀
16
+ */
17
+ function extractFunctionGroup(functionGroupName) {
18
+ // 函数组名称格式:FG_{GROUP_NAME}
19
+ const match = functionGroupName.match(/^FG_(.+)$/);
20
+ return match ? match[1] : functionGroupName;
21
+ }
22
+ /**
23
+ * 生成函数组XML内容
24
+ * 遵循abapGit协议格式
25
+ */
26
+ function generateFunctionGroupXmlContent(functionGroupName, functions) {
27
+ let xml = '<?xml version="1.0" encoding="utf-8"?>\n';
28
+ xml += '<abapGit version="v1.0.0" serializer="LCL_OBJECT_FUGR" serializer_version="v1.0.0">\n';
29
+ xml += ' <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">\n';
30
+ xml += ' <asx:values>\n';
31
+ xml += ' <AREAT>Function Group</AREAT>\n';
32
+ xml += ' <INCLUDES>\n';
33
+ // 包含函数组包含文件
34
+ const groupPrefix = extractFunctionGroup(functionGroupName);
35
+ const includes = [
36
+ `L${groupPrefix}TOP`,
37
+ `L${groupPrefix}UXX`,
38
+ `L${groupPrefix}F01`,
39
+ `L${groupPrefix}F02`
40
+ ];
41
+ includes.forEach(include => {
42
+ xml = (0, baseGenerator_1.addXmlField)(xml, 'INCL', include, ' ');
43
+ });
44
+ xml += ' </INCLUDES>\n';
45
+ xml += ' <FUNCTIONS>\n';
46
+ // 添加函数定义
47
+ functions.forEach(func => {
48
+ xml += ' <FUNCTION>\n';
49
+ xml = (0, baseGenerator_1.addXmlField)(xml, 'FUNCNAME', func.FUNCNAME, ' ');
50
+ xml = (0, baseGenerator_1.addXmlField)(xml, 'FMODE', func.FMODE, ' ');
51
+ xml = (0, baseGenerator_1.addXmlField)(xml, 'STEXT', func.STEXT, ' ');
52
+ xml = (0, baseGenerator_1.addXmlField)(xml, 'REMOTE_CALL', func.REMOTE_CALL, ' ');
53
+ xml += ' </FUNCTION>\n';
54
+ });
55
+ xml += ' </FUNCTIONS>\n';
56
+ xml += ' </asx:values>\n';
57
+ xml += ' </asx:abap>\n';
58
+ xml += '</abapGit>\n';
59
+ return xml;
60
+ }
61
+ /**
62
+ * 生成函数组文件
63
+ * 符合abapGit协议规范
64
+ */
65
+ async function generateFunctionGroupFiles(functionGroupName, functions, downloadRootPath, resultDownloadedFiles) {
66
+ const safeGroupName = functionGroupName.replace(/[/\\]/g, '_');
67
+ // 函数组文件路径:/function_groups目录下
68
+ const baseDir = (0, path_1.join)(downloadRootPath, 'function_groups');
69
+ if (!(0, fs_1.existsSync)(baseDir)) {
70
+ (0, fs_1.mkdirSync)(baseDir, { recursive: true });
71
+ }
72
+ // 生成函数组主文件
73
+ const xmlContent = generateFunctionGroupXmlContent(functionGroupName, functions);
74
+ const xmlFileName = `${safeGroupName}.fagr.xml`;
75
+ const xmlFilePath = (0, path_1.join)(baseDir, xmlFileName);
76
+ (0, fs_1.writeFileSync)(xmlFilePath, xmlContent, 'utf-8');
77
+ console.error(`导出函数组 ${functionGroupName} 到: ${xmlFilePath}`);
78
+ // 记录下载统计
79
+ resultDownloadedFiles.push({
80
+ objectName: functionGroupName,
81
+ objectType: 'FUGR',
82
+ filePath: xmlFilePath,
83
+ success: true,
84
+ metadata: {
85
+ functionCount: functions.length,
86
+ exportType: 'separate',
87
+ objectType: 'FUGR'
88
+ }
89
+ });
90
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 主生成器索引文件
3
+ * 导出所有生成器模块
4
+ */
5
+ export * from './baseGenerator';
6
+ export * from './screenGenerator';
7
+ export * from './structureGenerator';
8
+ export * from './domainGenerator';
9
+ export * from './messageGenerator';
10
+ export * from './textElementGenerator';
11
+ export * from './functionGroupGenerator';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/recursive/generate/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * 主生成器索引文件
4
+ * 导出所有生成器模块
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ // 基础工具
22
+ __exportStar(require("./baseGenerator"), exports);
23
+ // 统一屏幕生成器(推荐使用)
24
+ __exportStar(require("./screenGenerator"), exports);
25
+ // 结构体生成器
26
+ __exportStar(require("./structureGenerator"), exports);
27
+ // 域生成器
28
+ __exportStar(require("./domainGenerator"), exports);
29
+ // 消息类生成器
30
+ __exportStar(require("./messageGenerator"), exports);
31
+ // 文本元素生成器
32
+ __exportStar(require("./textElementGenerator"), exports);
33
+ // 函数组生成器
34
+ __exportStar(require("./functionGroupGenerator"), exports);
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 消息类生成器
3
+ * 生成消息类XML文件
4
+ */
5
+ import { Message } from '../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/recursive/generate/messageGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAG5C;;;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 += ' <MASTERLANG>E</MASTERLANG>\n';
24
+ xml += ' <FUMSG>N</FUMSG>\n';
25
+ xml += ' <STMSG>N</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,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 '../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/recursive/generate/screenGenerator.ts"],"names":[],"mappings":"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"}