@linkup-ai/abap-ai 2.0.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 (114) hide show
  1. package/README.md +384 -0
  2. package/dist/adt-client.js +364 -0
  3. package/dist/cli/activate.js +113 -0
  4. package/dist/cli/init.js +333 -0
  5. package/dist/cli/remove.js +80 -0
  6. package/dist/cli/status.js +229 -0
  7. package/dist/cli/systems.js +68 -0
  8. package/dist/cli.js +81 -0
  9. package/dist/index.js +1318 -0
  10. package/dist/knowledge/abap/abap-dictionary.md +199 -0
  11. package/dist/knowledge/abap/abap-sql.md +296 -0
  12. package/dist/knowledge/abap/amdp.md +273 -0
  13. package/dist/knowledge/abap/clean-code.md +293 -0
  14. package/dist/knowledge/abap/cloud-background-processing.md +250 -0
  15. package/dist/knowledge/abap/cloud-communication.md +265 -0
  16. package/dist/knowledge/abap/cloud-development.md +176 -0
  17. package/dist/knowledge/abap/cloud-extensibility.md +252 -0
  18. package/dist/knowledge/abap/cloud-released-apis.md +261 -0
  19. package/dist/knowledge/abap/constructor-expressions.md +289 -0
  20. package/dist/knowledge/abap/enhancements.md +232 -0
  21. package/dist/knowledge/abap/exceptions.md +271 -0
  22. package/dist/knowledge/abap/internal-tables.md +205 -0
  23. package/dist/knowledge/abap/object-orientation.md +298 -0
  24. package/dist/knowledge/abap/performance.md +216 -0
  25. package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
  26. package/dist/knowledge/abap/rap-business-events.md +216 -0
  27. package/dist/knowledge/abap/rap-draft.md +191 -0
  28. package/dist/knowledge/abap/rap-eml.md +453 -0
  29. package/dist/knowledge/abap/rap-end-to-end.md +486 -0
  30. package/dist/knowledge/abap/rap-feature-control.md +185 -0
  31. package/dist/knowledge/abap/rap-numbering.md +280 -0
  32. package/dist/knowledge/abap/rap-service-exposure.md +163 -0
  33. package/dist/knowledge/abap/rap-unmanaged.md +468 -0
  34. package/dist/knowledge/abap/string-processing.md +180 -0
  35. package/dist/knowledge/abap/unit-testing.md +303 -0
  36. package/dist/knowledge/abap-cds/access-control.md +241 -0
  37. package/dist/knowledge/abap-cds/annotations.md +331 -0
  38. package/dist/knowledge/abap-cds/associations.md +254 -0
  39. package/dist/knowledge/abap-cds/expressions.md +230 -0
  40. package/dist/knowledge/abap-cds/functions.md +245 -0
  41. package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
  42. package/dist/knowledge/cap/authentication.md +278 -0
  43. package/dist/knowledge/cap/cdl-syntax.md +247 -0
  44. package/dist/knowledge/cap/cql-queries.md +266 -0
  45. package/dist/knowledge/cap/deployment.md +343 -0
  46. package/dist/knowledge/cap/event-handlers.md +287 -0
  47. package/dist/knowledge/cap/fiori-integration.md +303 -0
  48. package/dist/knowledge/cap/service-definitions.md +287 -0
  49. package/dist/knowledge/fiori/annotations.md +347 -0
  50. package/dist/knowledge/fiori/deployment.md +340 -0
  51. package/dist/knowledge/fiori/fiori-elements.md +332 -0
  52. package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
  53. package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
  54. package/dist/knowledge/fiori/ui5-controllers.md +358 -0
  55. package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
  56. package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
  57. package/dist/knowledge/fiori/ui5-manifest.md +411 -0
  58. package/dist/knowledge/fiori/ui5-routing.md +303 -0
  59. package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
  60. package/dist/logger.js +114 -0
  61. package/dist/system-profile.js +207 -0
  62. package/dist/tools/abap-doc.js +72 -0
  63. package/dist/tools/abapgit.js +161 -0
  64. package/dist/tools/activate.js +68 -0
  65. package/dist/tools/atc-check.js +117 -0
  66. package/dist/tools/auth-object.js +56 -0
  67. package/dist/tools/breakpoints.js +76 -0
  68. package/dist/tools/call-hierarchy.js +84 -0
  69. package/dist/tools/cds-annotations.js +98 -0
  70. package/dist/tools/cds-dependencies.js +65 -0
  71. package/dist/tools/check.js +47 -0
  72. package/dist/tools/code-completion.js +70 -0
  73. package/dist/tools/code-coverage.js +111 -0
  74. package/dist/tools/create-amdp.js +111 -0
  75. package/dist/tools/create-dcl.js +81 -0
  76. package/dist/tools/create-transport.js +38 -0
  77. package/dist/tools/create.js +285 -0
  78. package/dist/tools/data-preview.js +37 -0
  79. package/dist/tools/delete.js +45 -0
  80. package/dist/tools/deploy-bsp.js +298 -0
  81. package/dist/tools/discovery.js +59 -0
  82. package/dist/tools/element-info.js +93 -0
  83. package/dist/tools/enhancements.js +186 -0
  84. package/dist/tools/extract-method.js +44 -0
  85. package/dist/tools/function-group.js +59 -0
  86. package/dist/tools/knowledge.js +275 -0
  87. package/dist/tools/lock-object.js +75 -0
  88. package/dist/tools/message-class.js +67 -0
  89. package/dist/tools/navigate.js +80 -0
  90. package/dist/tools/number-range.js +57 -0
  91. package/dist/tools/object-documentation.js +43 -0
  92. package/dist/tools/object-structure.js +78 -0
  93. package/dist/tools/object-versions.js +57 -0
  94. package/dist/tools/package-contents.js +60 -0
  95. package/dist/tools/pretty-printer.js +35 -0
  96. package/dist/tools/publish-binding.js +49 -0
  97. package/dist/tools/quick-fix.js +69 -0
  98. package/dist/tools/read.js +167 -0
  99. package/dist/tools/refactor-rename.js +60 -0
  100. package/dist/tools/release-transport.js +24 -0
  101. package/dist/tools/released-apis.js +51 -0
  102. package/dist/tools/repository-tree.js +90 -0
  103. package/dist/tools/scaffold-rap.js +642 -0
  104. package/dist/tools/search.js +73 -0
  105. package/dist/tools/shared/data-format.js +101 -0
  106. package/dist/tools/sql-console.js +17 -0
  107. package/dist/tools/system-info.js +270 -0
  108. package/dist/tools/traces.js +66 -0
  109. package/dist/tools/transport-contents.js +83 -0
  110. package/dist/tools/transports.js +67 -0
  111. package/dist/tools/unit-test.js +135 -0
  112. package/dist/tools/where-used.js +59 -0
  113. package/dist/tools/write.js +101 -0
  114. package/package.json +49 -0
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.abapCreateTool = void 0;
4
+ exports.abapCreate = abapCreate;
5
+ const adt_client_js_1 = require("../adt-client.js");
6
+ // Content-Types para criação — S/4HANA (v2/v3) com fallback para ECC (v1)
7
+ const CONTENT_TYPE = {
8
+ "PROG/P": ["application/vnd.sap.adt.programs.programs.v2+xml"],
9
+ "CLAS/OC": ["application/vnd.sap.adt.oo.classes.v2+xml"],
10
+ "INTF/OI": ["application/vnd.sap.adt.oo.interfaces.v2+xml"],
11
+ "FUGR/F": ["application/vnd.sap.adt.functions.groups.v3+xml", "application/vnd.sap.adt.functions.groups.v2+xml"],
12
+ "DOMA/D": ["application/vnd.sap.adt.domains.v2+xml"],
13
+ "DTEL/D": ["application/vnd.sap.adt.dataelements.v2+xml", "application/vnd.sap.adt.dataelements.v1+xml"],
14
+ "TABL/DT": ["application/vnd.sap.adt.tables.v2+xml"],
15
+ "TABL/DS": ["application/vnd.sap.adt.structures.v2+xml"],
16
+ "TTYP/TT": ["application/vnd.sap.adt.tabletype.v1+xml"],
17
+ "MSAG/N": ["application/vnd.sap.adt.messageclass.v2+xml", "application/vnd.sap.adt.messageclass.v1+xml"],
18
+ "DDLS/DF": ["application/vnd.sap.adt.ddlSource+xml"],
19
+ "DDLX/MX": ["application/vnd.sap.adt.ddic.ddlx.v1+xml"],
20
+ "SRVD/SRV": ["application/vnd.sap.adt.ddic.srvd.v1+xml"],
21
+ "BDEF/BDO": ["application/vnd.sap.adt.blues.v1+xml"],
22
+ "SRVB/SVB": ["application/vnd.sap.adt.businessservices.servicebinding.v2+xml"],
23
+ };
24
+ const PROGRAM_TYPE = {
25
+ "PROG/P": "executableProgram",
26
+ };
27
+ function buildPayload(input) {
28
+ const { object_type, object_name, description, package: pkg = "$TMP", srvd_name, binding_type = "ODATA;V4;UI" } = input;
29
+ const name = object_name.toUpperCase();
30
+ switch (object_type) {
31
+ case "PROG/P":
32
+ return `<?xml version="1.0" encoding="UTF-8"?>
33
+ <program:abapProgram
34
+ xmlns:program="http://www.sap.com/adt/programs/programs"
35
+ xmlns:adtcore="http://www.sap.com/adt/core"
36
+ adtcore:description="${description}"
37
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
38
+ adtcore:name="${name}"
39
+ adtcore:responsible="${adt_client_js_1.SAP_USER}"
40
+ program:programType="${PROGRAM_TYPE[object_type]}">
41
+ <adtcore:packageRef adtcore:name="${pkg}"/>
42
+ </program:abapProgram>`;
43
+ case "CLAS/OC":
44
+ return `<?xml version="1.0" encoding="UTF-8"?>
45
+ <class:abapClass
46
+ xmlns:class="http://www.sap.com/adt/oo/classes"
47
+ xmlns:adtcore="http://www.sap.com/adt/core"
48
+ adtcore:description="${description}"
49
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
50
+ adtcore:name="${name}"
51
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
52
+ <adtcore:packageRef adtcore:name="${pkg}"/>
53
+ </class:abapClass>`;
54
+ case "INTF/OI":
55
+ return `<?xml version="1.0" encoding="UTF-8"?>
56
+ <intf:abapInterface
57
+ xmlns:intf="http://www.sap.com/adt/oo/interfaces"
58
+ xmlns:adtcore="http://www.sap.com/adt/core"
59
+ adtcore:description="${description}"
60
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
61
+ adtcore:name="${name}"
62
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
63
+ <adtcore:packageRef adtcore:name="${pkg}"/>
64
+ </intf:abapInterface>`;
65
+ case "FUGR/F":
66
+ return `<?xml version="1.0" encoding="UTF-8"?>
67
+ <group:abapFunctionGroup
68
+ xmlns:group="http://www.sap.com/adt/functions/groups"
69
+ xmlns:adtcore="http://www.sap.com/adt/core"
70
+ adtcore:description="${description}"
71
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
72
+ adtcore:name="${name}"
73
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
74
+ <adtcore:packageRef adtcore:name="${pkg}"/>
75
+ </group:abapFunctionGroup>`;
76
+ case "DOMA/D":
77
+ return `<?xml version="1.0" encoding="UTF-8"?>
78
+ <domain:domain
79
+ xmlns:domain="http://www.sap.com/dictionary/domain"
80
+ xmlns:adtcore="http://www.sap.com/adt/core"
81
+ adtcore:description="${description}"
82
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
83
+ adtcore:name="${name}"
84
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
85
+ <adtcore:packageRef adtcore:name="${pkg}"/>
86
+ </domain:domain>`;
87
+ case "DTEL/D":
88
+ return `<?xml version="1.0" encoding="UTF-8"?>
89
+ <dtel:wbobj
90
+ xmlns:dtel="http://www.sap.com/wbobj/dictionary/dtel"
91
+ xmlns:adtcore="http://www.sap.com/adt/core"
92
+ adtcore:description="${description}"
93
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
94
+ adtcore:name="${name}"
95
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
96
+ <adtcore:packageRef adtcore:name="${pkg}"/>
97
+ </dtel:wbobj>`;
98
+ case "TABL/DT":
99
+ return `<?xml version="1.0" encoding="UTF-8"?>
100
+ <blue:blueSource
101
+ xmlns:blue="http://www.sap.com/wbobj/blue"
102
+ xmlns:adtcore="http://www.sap.com/adt/core"
103
+ adtcore:description="${description}"
104
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
105
+ adtcore:name="${name}"
106
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
107
+ <adtcore:packageRef adtcore:name="${pkg}"/>
108
+ </blue:blueSource>`;
109
+ case "TABL/DS":
110
+ return `<?xml version="1.0" encoding="UTF-8"?>
111
+ <blue:blueSource
112
+ xmlns:blue="http://www.sap.com/wbobj/blue"
113
+ xmlns:adtcore="http://www.sap.com/adt/core"
114
+ adtcore:description="${description}"
115
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
116
+ adtcore:name="${name}"
117
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
118
+ <adtcore:packageRef adtcore:name="${pkg}"/>
119
+ </blue:blueSource>`;
120
+ case "TTYP/TT":
121
+ return `<?xml version="1.0" encoding="UTF-8"?>
122
+ <tabletype:tableType
123
+ xmlns:tabletype="http://www.sap.com/dictionary/tabletype"
124
+ xmlns:adtcore="http://www.sap.com/adt/core"
125
+ adtcore:description="${description}"
126
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
127
+ adtcore:name="${name}"
128
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
129
+ <adtcore:packageRef adtcore:name="${pkg}"/>
130
+ </tabletype:tableType>`;
131
+ case "MSAG/N":
132
+ return `<?xml version="1.0" encoding="UTF-8"?>
133
+ <mc:messageClass
134
+ xmlns:mc="http://www.sap.com/adt/MessageClass"
135
+ xmlns:adtcore="http://www.sap.com/adt/core"
136
+ adtcore:description="${description}"
137
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
138
+ adtcore:name="${name}"
139
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
140
+ <adtcore:packageRef adtcore:name="${pkg}"/>
141
+ </mc:messageClass>`;
142
+ case "DDLS/DF":
143
+ return `<?xml version="1.0" encoding="UTF-8"?>
144
+ <ddlSource:ddlSource
145
+ xmlns:ddlSource="http://www.sap.com/adt/ddic/ddlsources"
146
+ xmlns:adtcore="http://www.sap.com/adt/core"
147
+ adtcore:description="${description}"
148
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
149
+ adtcore:name="${name}"
150
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
151
+ <adtcore:packageRef adtcore:name="${pkg}"/>
152
+ </ddlSource:ddlSource>`;
153
+ case "DDLX/MX":
154
+ return `<?xml version="1.0" encoding="UTF-8"?>
155
+ <ddlxSource:ddlxSource
156
+ xmlns:ddlxSource="http://www.sap.com/adt/ddic/ddlxsources"
157
+ xmlns:adtcore="http://www.sap.com/adt/core"
158
+ adtcore:description="${description}"
159
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
160
+ adtcore:name="${name}"
161
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
162
+ <adtcore:packageRef adtcore:name="${pkg}"/>
163
+ </ddlxSource:ddlxSource>`;
164
+ case "SRVD/SRV":
165
+ return `<?xml version="1.0" encoding="UTF-8"?>
166
+ <srvdSource:srvdSource
167
+ xmlns:srvdSource="http://www.sap.com/adt/ddic/srvdsources"
168
+ xmlns:adtcore="http://www.sap.com/adt/core"
169
+ adtcore:description="${description}"
170
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
171
+ adtcore:name="${name}"
172
+ adtcore:responsible="${adt_client_js_1.SAP_USER}"
173
+ srvdSource:srvdSourceType="S">
174
+ <adtcore:packageRef adtcore:name="${pkg}"/>
175
+ </srvdSource:srvdSource>`;
176
+ case "BDEF/BDO":
177
+ return `<?xml version="1.0" encoding="UTF-8"?>
178
+ <blue:blueSource
179
+ xmlns:blue="http://www.sap.com/wbobj/blue"
180
+ xmlns:adtcore="http://www.sap.com/adt/core"
181
+ adtcore:description="${description}"
182
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
183
+ adtcore:name="${name}"
184
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
185
+ <adtcore:packageRef adtcore:name="${pkg}"/>
186
+ </blue:blueSource>`;
187
+ case "SRVB/SVB": {
188
+ if (!srvd_name)
189
+ throw new Error("srvd_name é obrigatório para criar um Service Binding (SRVB/SVB).");
190
+ const [bindProto = "ODATA", bindVersion = "V4", bindCategory = "UI"] = (binding_type ?? "ODATA;V4;UI").split(";");
191
+ const category = bindCategory === "WEB_API" ? "1" : "0";
192
+ return `<?xml version="1.0" encoding="UTF-8"?>
193
+ <srvb:serviceBinding
194
+ xmlns:srvb="http://www.sap.com/adt/ddic/ServiceBindings"
195
+ xmlns:adtcore="http://www.sap.com/adt/core"
196
+ adtcore:description="${description}"
197
+ adtcore:language="${adt_client_js_1.SAP_LANGUAGE}"
198
+ adtcore:name="${name}"
199
+ adtcore:responsible="${adt_client_js_1.SAP_USER}">
200
+ <adtcore:packageRef adtcore:name="${pkg}"/>
201
+ <srvb:services srvb:name="${name}">
202
+ <srvb:content>
203
+ <srvb:serviceDefinition adtcore:name="${srvd_name.toUpperCase()}" adtcore:type="SRVD/SRV"/>
204
+ </srvb:content>
205
+ </srvb:services>
206
+ <srvb:binding srvb:type="${bindProto}" srvb:version="${bindVersion}" srvb:category="${category}"/>
207
+ </srvb:serviceBinding>`;
208
+ }
209
+ default:
210
+ throw new Error(`Criação de objetos do tipo ${object_type} não suportada.`);
211
+ }
212
+ }
213
+ async function abapCreate(input) {
214
+ const { object_type, object_name, package: pkg = "$TMP", transport_request } = input;
215
+ const name = object_name.toUpperCase();
216
+ const adtPath = (0, adt_client_js_1.resolveAdtPath)(object_type);
217
+ const contentTypes = CONTENT_TYPE[object_type];
218
+ if (!contentTypes || contentTypes.length === 0) {
219
+ throw new Error(`Criação de objetos do tipo ${object_type} não suportada.`);
220
+ }
221
+ const csrf = await (0, adt_client_js_1.ensureSession)();
222
+ const payload = buildPayload(input);
223
+ // Tentar cada Content-Type (v2 primeiro, fallback para v1 no ECC)
224
+ let lastResponse = null;
225
+ for (const contentType of contentTypes) {
226
+ const response = await adt_client_js_1.http.post(`/${adtPath}`, payload, {
227
+ headers: {
228
+ "Content-Type": contentType,
229
+ "X-CSRF-Token": csrf,
230
+ },
231
+ params: { corrNr: transport_request ?? "" },
232
+ validateStatus: (status) => status >= 200 && status < 500,
233
+ });
234
+ if (response.status === 200 || response.status === 201) {
235
+ if (object_type === "SRVB/SVB") {
236
+ return `Service Binding ${name} criado com sucesso no pacote ${pkg}.\nUse abap_activate para ativar.`;
237
+ }
238
+ return `Objeto ${name} (${object_type}) criado com sucesso no pacote ${pkg}.\nUse abap_write para adicionar o código-fonte e abap_activate para ativar.`;
239
+ }
240
+ lastResponse = response;
241
+ // Se 415 (Unsupported Media Type) e temos mais Content-Types para tentar, continua
242
+ if (response.status === 415 && contentTypes.indexOf(contentType) < contentTypes.length - 1) {
243
+ continue;
244
+ }
245
+ break;
246
+ }
247
+ const errorBody = typeof lastResponse?.data === "string" ? lastResponse.data : JSON.stringify(lastResponse?.data ?? "");
248
+ throw new Error(`Erro ao criar objeto (HTTP ${lastResponse?.status}): ${errorBody.slice(0, 500)}`);
249
+ }
250
+ exports.abapCreateTool = {
251
+ name: "abap_create",
252
+ description: "Cria um novo objeto ABAP no sistema SAP via ADT API. Suporta programas, classes, interfaces, objetos DDIC e objetos RAP/Fiori.",
253
+ inputSchema: {
254
+ type: "object",
255
+ properties: {
256
+ object_type: {
257
+ type: "string",
258
+ description: "Tipo do objeto SAP a criar.",
259
+ enum: ["PROG/P", "CLAS/OC", "INTF/OI", "FUGR/F", "DOMA/D", "DTEL/D", "TABL/DT", "TABL/DS", "TTYP/TT", "MSAG/N", "DDLS/DF", "DDLX/MX", "SRVD/SRV", "BDEF/BDO", "SRVB/SVB"],
260
+ },
261
+ object_name: {
262
+ type: "string",
263
+ description: "Nome do novo objeto ABAP (ex: ZR_SD_PEDIDOS). Deve seguir convenção de nomenclatura do projeto.",
264
+ },
265
+ description: {
266
+ type: "string",
267
+ description: "Descrição curta do objeto (aparece no SAP GUI).",
268
+ },
269
+ package: {
270
+ type: "string",
271
+ description: "Pacote SAP onde criar o objeto. Use '$TMP' para objetos locais (padrão) ou um pacote de desenvolvimento como 'ZDEV'.",
272
+ },
273
+ srvd_name: {
274
+ type: "string",
275
+ description: "Nome da Service Definition (SRVD/SRV) associada. Obrigatório para SRVB/SVB.",
276
+ },
277
+ binding_type: {
278
+ type: "string",
279
+ description: "Protocolo do Service Binding. Padrão: ODATA;V4;UI.",
280
+ enum: ["ODATA;V4;UI", "ODATA;V2;UI", "ODATA;V4;WEB_API"],
281
+ },
282
+ },
283
+ required: ["object_type", "object_name", "description"],
284
+ },
285
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.abapDataPreview = abapDataPreview;
4
+ const adt_client_js_1 = require("../adt-client.js");
5
+ const data_format_js_1 = require("./shared/data-format.js");
6
+ async function abapDataPreview(input) {
7
+ const { object_name, max_rows = 100, where_clause, order_by, columns } = input;
8
+ const name = object_name.toUpperCase();
9
+ const csrf = await (0, adt_client_js_1.ensureSession)();
10
+ const params = {
11
+ ddicEntityName: name,
12
+ maxRows: String(max_rows),
13
+ };
14
+ if (where_clause)
15
+ params.filterValue = where_clause;
16
+ if (order_by)
17
+ params.orderBy = order_by;
18
+ if (columns)
19
+ params.selectedColumns = columns;
20
+ const response = await adt_client_js_1.http.post("/datapreview/ddic", "", {
21
+ params,
22
+ headers: {
23
+ Accept: "application/vnd.sap.adt.datapreview.table.v1+xml",
24
+ "X-CSRF-Token": csrf,
25
+ },
26
+ responseType: "text",
27
+ validateStatus: (status) => status < 500,
28
+ });
29
+ if (response.status >= 400) {
30
+ const errMsg = typeof response.data === "string"
31
+ ? (response.data.match(/<message[^>]*>([^<]+)<\/message>/i)?.[1] ?? response.data)
32
+ : `HTTP ${response.status}`;
33
+ throw new Error(errMsg);
34
+ }
35
+ const result = (0, data_format_js_1.parseDataPreview)(response.data);
36
+ return (0, data_format_js_1.formatDataPreview)(name, result);
37
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.abapDeleteObject = abapDeleteObject;
4
+ const adt_client_js_1 = require("../adt-client.js");
5
+ async function abapDeleteObject(input) {
6
+ const { object_type, object_name, transport_request } = input;
7
+ const name = object_name.toUpperCase();
8
+ const adtPath = (0, adt_client_js_1.resolveAdtPath)(object_type);
9
+ const objectPath = `/${adtPath}/${name}`;
10
+ const csrf = await (0, adt_client_js_1.ensureSession)();
11
+ // Lock — obter lockHandle
12
+ const lockResp = await adt_client_js_1.http.post(objectPath, "", {
13
+ headers: { "X-CSRF-Token": csrf },
14
+ params: { _action: "LOCK", accessMode: "MODIFY" },
15
+ validateStatus: (status) => status < 500,
16
+ responseType: "text",
17
+ });
18
+ const lockData = typeof lockResp.data === "string" ? lockResp.data : "";
19
+ const handleMatch = lockData.match(/<LOCK_HANDLE>([^<]+)<\/LOCK_HANDLE>/);
20
+ const lockHandle = handleMatch?.[1] ?? "";
21
+ if (!lockHandle) {
22
+ throw new Error(`Falha ao obter lock para ${name}. O objeto pode estar bloqueado por outro usuário.`);
23
+ }
24
+ // Delete com lockHandle
25
+ const params = { lockHandle };
26
+ if (transport_request)
27
+ params.corrNr = transport_request;
28
+ const delResp = await adt_client_js_1.http.delete(objectPath, {
29
+ headers: { "X-CSRF-Token": csrf },
30
+ params,
31
+ validateStatus: (status) => status < 500,
32
+ });
33
+ if (delResp.status >= 400) {
34
+ // Unlock em caso de erro
35
+ await adt_client_js_1.http.post(objectPath, "", {
36
+ headers: { "X-CSRF-Token": csrf },
37
+ params: { _action: "UNLOCK" },
38
+ validateStatus: () => true,
39
+ });
40
+ const data = typeof delResp.data === "string" ? delResp.data : "";
41
+ const msg = data.match(/<message[^>]*>([^<]+)<\/message>/i)?.[1] ?? `HTTP ${delResp.status}`;
42
+ throw new Error(`Erro ao excluir ${name}: ${msg}`);
43
+ }
44
+ return `Objeto ${name} (${object_type}) excluído com sucesso.`;
45
+ }
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.abapDeployBsp = abapDeployBsp;
40
+ const axios_1 = __importDefault(require("axios"));
41
+ const axios_cookiejar_support_1 = require("axios-cookiejar-support");
42
+ const tough_cookie_1 = require("tough-cookie");
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const zlib = __importStar(require("zlib"));
46
+ const system_profile_js_1 = require("../system-profile.js");
47
+ const SAP_URL = process.env.SAP_URL ?? "";
48
+ const SAP_USER = process.env.SAP_USER ?? "";
49
+ const SAP_PASS = process.env.SAP_PASS ?? "";
50
+ const SAP_CLIENT = process.env.SAP_CLIENT ?? "100";
51
+ const SAP_LANGUAGE = process.env.SAP_LANGUAGE ?? "PT";
52
+ // Cria cliente HTTP para o OData ABAP_REPOSITORY_SRV (separado do ADT)
53
+ function createRepoClient() {
54
+ const jar = new tough_cookie_1.CookieJar();
55
+ return (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({
56
+ baseURL: `${SAP_URL}/sap/opu/odata/UI5/ABAP_REPOSITORY_SRV`,
57
+ jar,
58
+ withCredentials: true,
59
+ auth: { username: SAP_USER, password: SAP_PASS },
60
+ params: { "sap-client": SAP_CLIENT, "sap-language": SAP_LANGUAGE },
61
+ }));
62
+ }
63
+ // Fetch CSRF token via HEAD request
64
+ async function fetchCsrf(client) {
65
+ const response = await client.head("/", {
66
+ headers: { "X-CSRF-Token": "Fetch" },
67
+ validateStatus: (s) => s < 500,
68
+ });
69
+ const token = response.headers["x-csrf-token"];
70
+ if (!token)
71
+ throw new Error("Falha ao obter CSRF token do ABAP_REPOSITORY_SRV");
72
+ return token;
73
+ }
74
+ // Verifica se a BSP já existe
75
+ async function bspExists(client, name) {
76
+ try {
77
+ await client.get(`/Repositories('${encodeURIComponent(name)}')`, {
78
+ headers: { Accept: "application/json" },
79
+ });
80
+ return true;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ // Cria ZIP em memória com os arquivos da pasta
87
+ function createZipFromFolder(folderPath) {
88
+ // Implementação simples de ZIP (deflate store) sem dependências externas
89
+ // Formato: local file headers + data + central directory + end of central directory
90
+ const files = [];
91
+ function walkDir(dir, prefix) {
92
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
93
+ for (const entry of entries) {
94
+ const fullPath = path.join(dir, entry.name);
95
+ const zipPath = prefix ? `${prefix}/${entry.name}` : entry.name;
96
+ if (entry.isDirectory()) {
97
+ walkDir(fullPath, zipPath);
98
+ }
99
+ else {
100
+ files.push({ name: zipPath, data: fs.readFileSync(fullPath) });
101
+ }
102
+ }
103
+ }
104
+ walkDir(folderPath, "");
105
+ // Build ZIP binary
106
+ const localHeaders = [];
107
+ const centralHeaders = [];
108
+ let offset = 0;
109
+ for (const file of files) {
110
+ const nameBuffer = Buffer.from(file.name, "utf-8");
111
+ const compressed = zlib.deflateRawSync(file.data);
112
+ // CRC32
113
+ const crc = crc32(file.data);
114
+ // Local file header (30 bytes + name + compressed data)
115
+ const local = Buffer.alloc(30 + nameBuffer.length);
116
+ local.writeUInt32LE(0x04034b50, 0); // signature
117
+ local.writeUInt16LE(20, 4); // version needed
118
+ local.writeUInt16LE(0, 6); // flags
119
+ local.writeUInt16LE(8, 8); // compression: deflate
120
+ local.writeUInt16LE(0, 10); // mod time
121
+ local.writeUInt16LE(0, 12); // mod date
122
+ local.writeUInt32LE(crc, 14); // crc32
123
+ local.writeUInt32LE(compressed.length, 18); // compressed size
124
+ local.writeUInt32LE(file.data.length, 22); // uncompressed size
125
+ local.writeUInt16LE(nameBuffer.length, 26); // name length
126
+ local.writeUInt16LE(0, 28); // extra field length
127
+ nameBuffer.copy(local, 30);
128
+ localHeaders.push(local);
129
+ localHeaders.push(compressed);
130
+ // Central directory header (46 bytes + name)
131
+ const central = Buffer.alloc(46 + nameBuffer.length);
132
+ central.writeUInt32LE(0x02014b50, 0); // signature
133
+ central.writeUInt16LE(20, 4); // version made by
134
+ central.writeUInt16LE(20, 6); // version needed
135
+ central.writeUInt16LE(0, 8); // flags
136
+ central.writeUInt16LE(8, 10); // compression: deflate
137
+ central.writeUInt16LE(0, 12); // mod time
138
+ central.writeUInt16LE(0, 14); // mod date
139
+ central.writeUInt32LE(crc, 16); // crc32
140
+ central.writeUInt32LE(compressed.length, 20); // compressed size
141
+ central.writeUInt32LE(file.data.length, 24); // uncompressed size
142
+ central.writeUInt16LE(nameBuffer.length, 28); // name length
143
+ central.writeUInt16LE(0, 30); // extra field length
144
+ central.writeUInt16LE(0, 32); // comment length
145
+ central.writeUInt16LE(0, 34); // disk number start
146
+ central.writeUInt16LE(0, 36); // internal attrs
147
+ central.writeUInt32LE(0, 38); // external attrs
148
+ central.writeUInt32LE(offset, 42); // offset of local header
149
+ nameBuffer.copy(central, 46);
150
+ centralHeaders.push(central);
151
+ offset += local.length + compressed.length;
152
+ }
153
+ const centralDirOffset = offset;
154
+ const centralDirSize = centralHeaders.reduce((s, b) => s + b.length, 0);
155
+ // End of central directory (22 bytes)
156
+ const eocd = Buffer.alloc(22);
157
+ eocd.writeUInt32LE(0x06054b50, 0); // signature
158
+ eocd.writeUInt16LE(0, 4); // disk number
159
+ eocd.writeUInt16LE(0, 6); // disk with central dir
160
+ eocd.writeUInt16LE(files.length, 8); // entries on this disk
161
+ eocd.writeUInt16LE(files.length, 10); // total entries
162
+ eocd.writeUInt32LE(centralDirSize, 12); // central dir size
163
+ eocd.writeUInt32LE(centralDirOffset, 16); // central dir offset
164
+ eocd.writeUInt16LE(0, 20); // comment length
165
+ return Buffer.concat([...localHeaders, ...centralHeaders, eocd]);
166
+ }
167
+ // CRC32 implementation
168
+ function crc32(buf) {
169
+ let crc = 0xffffffff;
170
+ for (let i = 0; i < buf.length; i++) {
171
+ crc = (crc >>> 8) ^ crc32Table[(crc ^ buf[i]) & 0xff];
172
+ }
173
+ return (crc ^ 0xffffffff) >>> 0;
174
+ }
175
+ const crc32Table = (() => {
176
+ const table = new Uint32Array(256);
177
+ for (let i = 0; i < 256; i++) {
178
+ let c = i;
179
+ for (let j = 0; j < 8; j++) {
180
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
181
+ }
182
+ table[i] = c;
183
+ }
184
+ return table;
185
+ })();
186
+ function escapeXml(str) {
187
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
188
+ }
189
+ async function abapDeployBsp(input) {
190
+ const { bsp_name, folder_path, package: pkg = "$TMP", description = `BSP ${bsp_name}`, transport_request = "", } = input;
191
+ const name = bsp_name.toUpperCase();
192
+ // Valida pasta
193
+ if (!fs.existsSync(folder_path)) {
194
+ throw new Error(`Pasta não encontrada: ${folder_path}`);
195
+ }
196
+ if (!fs.statSync(folder_path).isDirectory()) {
197
+ throw new Error(`Caminho não é uma pasta: ${folder_path}`);
198
+ }
199
+ // Cria ZIP e converte para base64
200
+ const zipBuffer = createZipFromFolder(folder_path);
201
+ const base64Data = zipBuffer.toString("base64");
202
+ // Cria cliente OData
203
+ const client = createRepoClient();
204
+ const csrf = await fetchCsrf(client);
205
+ // Verifica se BSP já existe
206
+ const exists = await bspExists(client, name);
207
+ // Payload Atom para ABAP_REPOSITORY_SRV
208
+ const publicUrl = `${SAP_URL}/sap/opu/odata/UI5/ABAP_REPOSITORY_SRV`;
209
+ const time = new Date().toISOString();
210
+ const escapedName = escapeXml(name);
211
+ const payload = `<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="${publicUrl}">
212
+ <id>${publicUrl}/Repositories('${escapedName}')</id>
213
+ <title type="text">Repositories('${escapedName}')</title>
214
+ <updated>${time}</updated>
215
+ <category term="/UI5/ABAP_REPOSITORY_SRV.Repository" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
216
+ <link href="Repositories('${escapedName}')" rel="edit" title="Repository"/>
217
+ <content type="application/xml">
218
+ <m:properties>
219
+ <d:Name>${escapedName}</d:Name>
220
+ <d:Package>${escapeXml(pkg.toUpperCase())}</d:Package>
221
+ <d:Description>${escapeXml(description)}</d:Description>
222
+ <d:ZipArchive>${base64Data}</d:ZipArchive>
223
+ <d:Info/>
224
+ </m:properties>
225
+ </content>
226
+ </entry>`;
227
+ // Params
228
+ const params = {
229
+ CodePage: "UTF8",
230
+ SafeMode: "true",
231
+ };
232
+ if (transport_request) {
233
+ params.TransportRequest = transport_request;
234
+ }
235
+ // POST (criar) ou PUT (atualizar)
236
+ const method = exists ? "put" : "post";
237
+ const url = exists
238
+ ? `/Repositories('${encodeURIComponent(name)}')`
239
+ : `/Repositories`;
240
+ const response = await client.request({
241
+ method,
242
+ url,
243
+ data: payload,
244
+ headers: {
245
+ "Content-Type": "application/atom+xml",
246
+ "Accept": "application/atom+xml,application/json",
247
+ "X-CSRF-Token": csrf,
248
+ },
249
+ params,
250
+ validateStatus: (s) => s >= 200 && s < 500,
251
+ });
252
+ if (response.status >= 200 && response.status < 300) {
253
+ // Extrai mensagens SAP do header sap-message
254
+ const sapMsg = response.headers["sap-message"];
255
+ let messages = "";
256
+ if (sapMsg) {
257
+ try {
258
+ const parsed = JSON.parse(sapMsg);
259
+ messages = parsed.message || "";
260
+ }
261
+ catch {
262
+ messages = sapMsg.slice(0, 200);
263
+ }
264
+ }
265
+ const profile = (0, system_profile_js_1.getProfile)();
266
+ const bspPath = (0, system_profile_js_1.resolveBspUrl)(name);
267
+ const appUrl = bspPath ? `${SAP_URL}${bspPath}` : `${SAP_URL}/sap/bc/ui5_ui5/sap/${name.toLowerCase()}?sap-client=${SAP_CLIENT}`;
268
+ const infoLines = [
269
+ `BSP ${name} ${exists ? "atualizada" : "criada"} com sucesso.`,
270
+ `Pacote: ${pkg.toUpperCase()}`,
271
+ `Arquivos: ${countFiles(folder_path)}`,
272
+ `URL: ${appUrl}`,
273
+ `UI5 Bootstrap: ${profile.ui5.bootstrapPath}sap-ui-core.js`,
274
+ messages ? `Mensagens SAP: ${messages}` : "",
275
+ ];
276
+ return infoLines.filter(Boolean).join("\n");
277
+ }
278
+ // Erro — extrair mensagem
279
+ const errorBody = typeof response.data === "string"
280
+ ? response.data
281
+ : JSON.stringify(response.data);
282
+ const errorMsg = errorBody.match(/<message[^>]*>([^<]*)<\/message>/i)?.[1]
283
+ || errorBody.slice(0, 500);
284
+ throw new Error(`Deploy falhou (HTTP ${response.status}): ${errorMsg}`);
285
+ }
286
+ function countFiles(dir) {
287
+ let count = 0;
288
+ function walk(d) {
289
+ for (const entry of fs.readdirSync(d, { withFileTypes: true })) {
290
+ if (entry.isDirectory())
291
+ walk(path.join(d, entry.name));
292
+ else
293
+ count++;
294
+ }
295
+ }
296
+ walk(dir);
297
+ return count;
298
+ }