@abapify/adt-plugin-abapgit 0.4.0 → 0.4.1
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/dist/index.d.mts +223 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +4518 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +7 -7
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,4518 @@
|
|
|
1
|
+
import { createPlugin, registerFormatPlugin } from "@abapify/adt-plugin";
|
|
2
|
+
import { AdkClass, AdkDataElement, AdkDomain, AdkFunctionGroup, AdkInterface, AdkPackage, AdkProgram, AdkStructure, AdkTable, AdkTableType, createAdk, getMainType, getTypeForKind } from "@abapify/adk";
|
|
3
|
+
import { typedSchema } from "@abapify/ts-xsd";
|
|
4
|
+
import { parse } from "@abapify/acds";
|
|
5
|
+
import { tablesettings } from "@abapify/adt-schemas";
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "fs";
|
|
7
|
+
import { basename, join, relative } from "path";
|
|
8
|
+
import { createAbapGitResolver as createFindingResolver } from "@abapify/adt-atc";
|
|
9
|
+
|
|
10
|
+
//#region src/lib/handlers/xml-format.ts
|
|
11
|
+
/**
|
|
12
|
+
* XML formatting utilities for abapGit serialization.
|
|
13
|
+
*
|
|
14
|
+
* Centralizes XML post-processing that was previously duplicated
|
|
15
|
+
* across base.ts, fugr.ts, tabl.ts, and roundtrip.ts.
|
|
16
|
+
*
|
|
17
|
+
* Uses indexOf-based parsing instead of regex to avoid
|
|
18
|
+
* super-linear backtracking (SonarQube S5852).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Extract `name="value"` attribute pairs from an XML attribute string
|
|
22
|
+
* using indexOf-based scanning (no regex).
|
|
23
|
+
*/
|
|
24
|
+
function extractAttributes(content) {
|
|
25
|
+
const attrs = [];
|
|
26
|
+
let i = 0;
|
|
27
|
+
while (i < content.length) {
|
|
28
|
+
while (i < content.length && (content[i] === " " || content[i] === "\n" || content[i] === " ")) i++;
|
|
29
|
+
if (i >= content.length) break;
|
|
30
|
+
const eqIdx = content.indexOf("=", i);
|
|
31
|
+
if (eqIdx === -1) break;
|
|
32
|
+
const openQuote = content.indexOf("\"", eqIdx + 1);
|
|
33
|
+
if (openQuote === -1) break;
|
|
34
|
+
const closeQuote = content.indexOf("\"", openQuote + 1);
|
|
35
|
+
if (closeQuote === -1) break;
|
|
36
|
+
attrs.push(content.slice(i, closeQuote + 1));
|
|
37
|
+
i = closeQuote + 1;
|
|
38
|
+
}
|
|
39
|
+
return attrs;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Format XML attributes on separate lines for better diff readability.
|
|
43
|
+
*
|
|
44
|
+
* Turns `<tag a="1" b="2">` into:
|
|
45
|
+
* ```
|
|
46
|
+
* <tag
|
|
47
|
+
* a="1"
|
|
48
|
+
* b="2"
|
|
49
|
+
* >
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* Uses indexOf-based scanning to avoid regex backtracking (S5852).
|
|
53
|
+
*/
|
|
54
|
+
function formatXmlAttributes(xml) {
|
|
55
|
+
let result = "";
|
|
56
|
+
let pos = 0;
|
|
57
|
+
while (pos < xml.length) {
|
|
58
|
+
const openBracket = xml.indexOf("<", pos);
|
|
59
|
+
if (openBracket === -1) {
|
|
60
|
+
result += xml.slice(pos);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
result += xml.slice(pos, openBracket);
|
|
64
|
+
const closeBracket = xml.indexOf(">", openBracket);
|
|
65
|
+
if (closeBracket === -1) {
|
|
66
|
+
result += xml.slice(openBracket);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
const tagContent = xml.slice(openBracket + 1, closeBracket);
|
|
70
|
+
const spaceIdx = tagContent.indexOf(" ");
|
|
71
|
+
if (spaceIdx === -1 || tagContent[0] === "/" || tagContent[0] === "!" || tagContent[0] === "?") {
|
|
72
|
+
result += xml.slice(openBracket, closeBracket + 1);
|
|
73
|
+
pos = closeBracket + 1;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const tag = tagContent.slice(0, spaceIdx);
|
|
77
|
+
const attrPart = tagContent.slice(spaceIdx + 1);
|
|
78
|
+
const isSelfClosing = attrPart.trimEnd().endsWith("/");
|
|
79
|
+
const attrs = extractAttributes(isSelfClosing ? attrPart.slice(0, attrPart.lastIndexOf("/")) : attrPart);
|
|
80
|
+
if (attrs.length === 0) result += xml.slice(openBracket, closeBracket + 1);
|
|
81
|
+
else {
|
|
82
|
+
const attrsJoined = attrs.map((a) => `\n ${a}`).join("");
|
|
83
|
+
result += `<${tag}${attrsJoined}\n${isSelfClosing ? "/" : ""}>`;
|
|
84
|
+
}
|
|
85
|
+
pos = closeBracket + 1;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Move `xmlns:asx` declaration from root `<abapGit>` to nested `<asx:abap>`.
|
|
91
|
+
*
|
|
92
|
+
* Uses indexOf-based approach instead of regex to avoid backtracking on
|
|
93
|
+
* the `[\s\S]*?` pattern that SonarQube flags.
|
|
94
|
+
*/
|
|
95
|
+
function moveNamespaceToAbap(xml) {
|
|
96
|
+
const nsDecl = " xmlns:asx=\"http://www.sap.com/abapxml\"";
|
|
97
|
+
const nsIdx = xml.indexOf(nsDecl);
|
|
98
|
+
if (nsIdx === -1) return xml;
|
|
99
|
+
if (xml.lastIndexOf("<abapGit", nsIdx) === -1) return xml;
|
|
100
|
+
const stripped = xml.slice(0, nsIdx) + xml.slice(nsIdx + 39);
|
|
101
|
+
const asxIdx = stripped.indexOf("<asx:abap");
|
|
102
|
+
if (asxIdx === -1) return stripped;
|
|
103
|
+
return stripped.slice(0, asxIdx + 9) + "\n " + nsDecl.trim() + stripped.slice(asxIdx + 9);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Apply standard abapGit XML formatting:
|
|
107
|
+
* 1. Format attributes on separate lines
|
|
108
|
+
* 2. Move xmlns:asx to asx:abap element
|
|
109
|
+
*/
|
|
110
|
+
function formatAbapGitXml(xml) {
|
|
111
|
+
return moveNamespaceToAbap(formatXmlAttributes(xml));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/lib/handlers/base.ts
|
|
116
|
+
const handlerRegistry = /* @__PURE__ */ new Map();
|
|
117
|
+
/**
|
|
118
|
+
* Get handler for object type
|
|
119
|
+
*
|
|
120
|
+
* Tries the full type first (e.g., 'TABL/DS'), then falls back to the
|
|
121
|
+
* main type (e.g., 'CLAS/OC' → 'CLAS'). This matches ADK's resolveType()
|
|
122
|
+
* behaviour and handles quickSearch results that return subtypes.
|
|
123
|
+
*/
|
|
124
|
+
function getHandler(type) {
|
|
125
|
+
return handlerRegistry.get(type) ?? handlerRegistry.get(getMainType(type));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Check if object type is supported
|
|
129
|
+
*
|
|
130
|
+
* Tries the full type first, then falls back to the main type.
|
|
131
|
+
*/
|
|
132
|
+
function isSupported(type) {
|
|
133
|
+
return handlerRegistry.has(type) || handlerRegistry.has(getMainType(type));
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get all supported object types
|
|
137
|
+
*/
|
|
138
|
+
function getSupportedTypes() {
|
|
139
|
+
return [...handlerRegistry.keys()];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Create an object handler
|
|
143
|
+
*
|
|
144
|
+
* @param adkClassOrType - ADK object class or ABAP type string
|
|
145
|
+
* @param definition - Handler definition with schema, toAbapGit, serialize
|
|
146
|
+
* @returns ObjectHandler that is auto-registered
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* // With ADK class (preferred)
|
|
151
|
+
* import { AdkPackage } from '@abapify/adk';
|
|
152
|
+
* export const packageHandler = createHandler(AdkPackage, { ... });
|
|
153
|
+
*
|
|
154
|
+
* // With ABAP type string (for objects without ADK class)
|
|
155
|
+
* export const dataElementHandler = createHandler('DTEL', { ... });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
function createHandler(adkClassOrType, definition) {
|
|
159
|
+
let type;
|
|
160
|
+
if (typeof adkClassOrType === "string") type = adkClassOrType;
|
|
161
|
+
else {
|
|
162
|
+
const kind = adkClassOrType.kind;
|
|
163
|
+
const derivedType = getTypeForKind(kind);
|
|
164
|
+
if (!derivedType) throw new Error(`Unknown ADK kind: ${kind}. Make sure the ADK class has a static 'kind' property.`);
|
|
165
|
+
type = derivedType;
|
|
166
|
+
}
|
|
167
|
+
const fileExtension = getMainType(type).toLowerCase();
|
|
168
|
+
const ctx = {
|
|
169
|
+
type,
|
|
170
|
+
fileExtension,
|
|
171
|
+
getObjectName(object) {
|
|
172
|
+
return object.name.toLowerCase();
|
|
173
|
+
},
|
|
174
|
+
getData(object) {
|
|
175
|
+
return object.dataSync;
|
|
176
|
+
},
|
|
177
|
+
async resolveContent(content) {
|
|
178
|
+
if (!content) return "";
|
|
179
|
+
if (typeof content === "string") return content;
|
|
180
|
+
if (typeof content === "function") return await content();
|
|
181
|
+
return "";
|
|
182
|
+
},
|
|
183
|
+
toAbapGitXml(object) {
|
|
184
|
+
const fullPayload = {
|
|
185
|
+
abap: {
|
|
186
|
+
version: "1.0",
|
|
187
|
+
values: definition.toAbapGit(object)
|
|
188
|
+
},
|
|
189
|
+
version: definition.version,
|
|
190
|
+
serializer: definition.serializer,
|
|
191
|
+
serializer_version: definition.serializer_version
|
|
192
|
+
};
|
|
193
|
+
return formatAbapGitXml(definition.schema.build(fullPayload, { pretty: true }));
|
|
194
|
+
},
|
|
195
|
+
createFile(path, content, encoding) {
|
|
196
|
+
return {
|
|
197
|
+
path,
|
|
198
|
+
content,
|
|
199
|
+
encoding
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
createXmlFile(objectName, xmlContent) {
|
|
203
|
+
return {
|
|
204
|
+
path: `${objectName}.${fileExtension}.xml`,
|
|
205
|
+
content: xmlContent
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
createAbapFile(objectName, content, suffix) {
|
|
209
|
+
return {
|
|
210
|
+
path: suffix ? `${objectName}.${fileExtension}.${suffix}.abap` : `${objectName}.${fileExtension}.abap`,
|
|
211
|
+
content
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const defaultSerialize = async (object) => {
|
|
216
|
+
const objectName = ctx.getObjectName(object);
|
|
217
|
+
const files = [];
|
|
218
|
+
if (definition.getSources) {
|
|
219
|
+
const rawSources = definition.getSources(object);
|
|
220
|
+
const sources = await Promise.all(rawSources.map(async ({ suffix, content }) => ({
|
|
221
|
+
suffix,
|
|
222
|
+
content: await content
|
|
223
|
+
})));
|
|
224
|
+
for (const { suffix, content } of sources) if (content) files.push(ctx.createAbapFile(objectName, content, suffix));
|
|
225
|
+
} else if (definition.getSource) {
|
|
226
|
+
const source = await definition.getSource(object);
|
|
227
|
+
files.push(ctx.createAbapFile(objectName, source));
|
|
228
|
+
}
|
|
229
|
+
const xmlContent = ctx.toAbapGitXml(object);
|
|
230
|
+
let xmlFileName;
|
|
231
|
+
if (definition.xmlFileName) xmlFileName = typeof definition.xmlFileName === "function" ? definition.xmlFileName(object, ctx) : definition.xmlFileName;
|
|
232
|
+
else xmlFileName = `${objectName}.${fileExtension}.xml`;
|
|
233
|
+
files.push(ctx.createFile(xmlFileName, xmlContent));
|
|
234
|
+
return files;
|
|
235
|
+
};
|
|
236
|
+
const defaultFromAbapGit = definition.fromAbapGit ? (values) => {
|
|
237
|
+
return definition.fromAbapGit(values);
|
|
238
|
+
} : void 0;
|
|
239
|
+
const handler = {
|
|
240
|
+
type,
|
|
241
|
+
fileExtension,
|
|
242
|
+
schema: definition.schema,
|
|
243
|
+
suffixToSourceKey: definition.suffixToSourceKey,
|
|
244
|
+
serialize: definition.serialize ? (object) => definition.serialize(object, ctx) : defaultSerialize,
|
|
245
|
+
fromAbapGit: defaultFromAbapGit,
|
|
246
|
+
setSources: definition.setSources
|
|
247
|
+
};
|
|
248
|
+
handlerRegistry.set(type, handler);
|
|
249
|
+
return handler;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/lib/handlers/abapgit-schema.ts
|
|
254
|
+
/**
|
|
255
|
+
* AbapGit Schema - extends TypedSchema with values type
|
|
256
|
+
*
|
|
257
|
+
* Provides both:
|
|
258
|
+
* - _type: Full AbapGitType (for XML build/parse)
|
|
259
|
+
* - _values: Inner values type (for handler mapping)
|
|
260
|
+
*/
|
|
261
|
+
/**
|
|
262
|
+
* Create an AbapGit typed schema wrapper from raw schema
|
|
263
|
+
*
|
|
264
|
+
* @param rawSchema - Raw schema literal (with `as const`)
|
|
265
|
+
* @returns AbapGitSchema with both _type and _values
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```typescript
|
|
269
|
+
* import _devc from './schemas/devc';
|
|
270
|
+
*
|
|
271
|
+
* const devc = abapGitSchema<DevcAbapGitType, DevcType>(_devc);
|
|
272
|
+
*
|
|
273
|
+
* // Access types:
|
|
274
|
+
* type Full = typeof devc._type; // DevcAbapGitType
|
|
275
|
+
* type Values = typeof devc._values; // DevcType
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
function abapGitSchema(rawSchema) {
|
|
279
|
+
const base = typedSchema(rawSchema);
|
|
280
|
+
return {
|
|
281
|
+
_type: base._type,
|
|
282
|
+
_values: null,
|
|
283
|
+
schema: base.schema,
|
|
284
|
+
parse: base.parse,
|
|
285
|
+
build: base.build
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/schemas/generated/schemas/clas.ts
|
|
291
|
+
/**
|
|
292
|
+
* Auto-generated schema from XSD
|
|
293
|
+
*
|
|
294
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
295
|
+
* Source: abapgit/clas.xsd
|
|
296
|
+
*/
|
|
297
|
+
var clas_default = {
|
|
298
|
+
$xmlns: {
|
|
299
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
300
|
+
asx: "http://www.sap.com/abapxml"
|
|
301
|
+
},
|
|
302
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
303
|
+
elementFormDefault: "unqualified",
|
|
304
|
+
element: [
|
|
305
|
+
{
|
|
306
|
+
name: "abapGit",
|
|
307
|
+
complexType: {
|
|
308
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
309
|
+
attribute: [
|
|
310
|
+
{
|
|
311
|
+
name: "version",
|
|
312
|
+
type: "xs:string",
|
|
313
|
+
use: "required"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: "serializer",
|
|
317
|
+
type: "xs:string",
|
|
318
|
+
use: "required"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: "serializer_version",
|
|
322
|
+
type: "xs:string",
|
|
323
|
+
use: "required"
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
name: "Schema",
|
|
330
|
+
abstract: true
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: "values",
|
|
334
|
+
type: "asx:AbapValuesType"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
name: "abap",
|
|
338
|
+
type: "asx:AbapType"
|
|
339
|
+
}
|
|
340
|
+
],
|
|
341
|
+
complexType: [
|
|
342
|
+
{
|
|
343
|
+
name: "AbapValuesType",
|
|
344
|
+
all: { element: [{
|
|
345
|
+
name: "VSEOCLASS",
|
|
346
|
+
type: "asx:VseoClassType",
|
|
347
|
+
minOccurs: "0"
|
|
348
|
+
}] }
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: "VseoClassType",
|
|
352
|
+
all: { element: [
|
|
353
|
+
{
|
|
354
|
+
name: "CLSNAME",
|
|
355
|
+
type: "xs:string"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: "LANGU",
|
|
359
|
+
type: "xs:string",
|
|
360
|
+
minOccurs: "0"
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
name: "DESCRIPT",
|
|
364
|
+
type: "xs:string",
|
|
365
|
+
minOccurs: "0"
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: "STATE",
|
|
369
|
+
type: "xs:string",
|
|
370
|
+
minOccurs: "0"
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
name: "CATEGORY",
|
|
374
|
+
type: "xs:string",
|
|
375
|
+
minOccurs: "0"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
name: "EXPOSURE",
|
|
379
|
+
type: "xs:string",
|
|
380
|
+
minOccurs: "0"
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
name: "CLSFINAL",
|
|
384
|
+
type: "xs:string",
|
|
385
|
+
minOccurs: "0"
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
name: "CLSABSTRCT",
|
|
389
|
+
type: "xs:string",
|
|
390
|
+
minOccurs: "0"
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
name: "CLSCCINCL",
|
|
394
|
+
type: "xs:string",
|
|
395
|
+
minOccurs: "0"
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
name: "FIXPT",
|
|
399
|
+
type: "xs:string",
|
|
400
|
+
minOccurs: "0"
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
name: "UNICODE",
|
|
404
|
+
type: "xs:string",
|
|
405
|
+
minOccurs: "0"
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
name: "WITH_UNIT_TESTS",
|
|
409
|
+
type: "xs:string",
|
|
410
|
+
minOccurs: "0"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
name: "DURATION",
|
|
414
|
+
type: "xs:string",
|
|
415
|
+
minOccurs: "0"
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
name: "RISK",
|
|
419
|
+
type: "xs:string",
|
|
420
|
+
minOccurs: "0"
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
name: "MSG_ID",
|
|
424
|
+
type: "xs:string",
|
|
425
|
+
minOccurs: "0"
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
name: "REFCLSNAME",
|
|
429
|
+
type: "xs:string",
|
|
430
|
+
minOccurs: "0"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
name: "SHRM_ENABLED",
|
|
434
|
+
type: "xs:string",
|
|
435
|
+
minOccurs: "0"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
name: "ABAP_LANGUAGE_VERSION",
|
|
439
|
+
type: "xs:string",
|
|
440
|
+
minOccurs: "0"
|
|
441
|
+
}
|
|
442
|
+
] }
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
name: "AbapType",
|
|
446
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
447
|
+
attribute: [{
|
|
448
|
+
name: "version",
|
|
449
|
+
type: "xs:string",
|
|
450
|
+
"default": "1.0"
|
|
451
|
+
}]
|
|
452
|
+
}
|
|
453
|
+
]
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
//#endregion
|
|
457
|
+
//#region src/schemas/generated/schemas/devc.ts
|
|
458
|
+
/**
|
|
459
|
+
* Auto-generated schema from XSD
|
|
460
|
+
*
|
|
461
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
462
|
+
* Source: abapgit/devc.xsd
|
|
463
|
+
*/
|
|
464
|
+
var devc_default = {
|
|
465
|
+
$xmlns: {
|
|
466
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
467
|
+
asx: "http://www.sap.com/abapxml"
|
|
468
|
+
},
|
|
469
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
470
|
+
elementFormDefault: "unqualified",
|
|
471
|
+
element: [
|
|
472
|
+
{
|
|
473
|
+
name: "abapGit",
|
|
474
|
+
complexType: {
|
|
475
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
476
|
+
attribute: [
|
|
477
|
+
{
|
|
478
|
+
name: "version",
|
|
479
|
+
type: "xs:string",
|
|
480
|
+
use: "required"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: "serializer",
|
|
484
|
+
type: "xs:string",
|
|
485
|
+
use: "required"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
name: "serializer_version",
|
|
489
|
+
type: "xs:string",
|
|
490
|
+
use: "required"
|
|
491
|
+
}
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
name: "Schema",
|
|
497
|
+
abstract: true
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
name: "values",
|
|
501
|
+
type: "asx:AbapValuesType"
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
name: "abap",
|
|
505
|
+
type: "asx:AbapType"
|
|
506
|
+
}
|
|
507
|
+
],
|
|
508
|
+
complexType: [
|
|
509
|
+
{
|
|
510
|
+
name: "AbapValuesType",
|
|
511
|
+
all: { element: [{
|
|
512
|
+
name: "DEVC",
|
|
513
|
+
type: "asx:DevcType",
|
|
514
|
+
minOccurs: "0"
|
|
515
|
+
}] }
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
name: "DevcType",
|
|
519
|
+
all: { element: [{
|
|
520
|
+
name: "CTEXT",
|
|
521
|
+
type: "xs:string"
|
|
522
|
+
}] }
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
name: "AbapType",
|
|
526
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
527
|
+
attribute: [{
|
|
528
|
+
name: "version",
|
|
529
|
+
type: "xs:string",
|
|
530
|
+
"default": "1.0"
|
|
531
|
+
}]
|
|
532
|
+
}
|
|
533
|
+
]
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
//#endregion
|
|
537
|
+
//#region src/schemas/generated/schemas/doma.ts
|
|
538
|
+
/**
|
|
539
|
+
* Auto-generated schema from XSD
|
|
540
|
+
*
|
|
541
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
542
|
+
* Source: abapgit/doma.xsd
|
|
543
|
+
*/
|
|
544
|
+
var doma_default = {
|
|
545
|
+
$xmlns: {
|
|
546
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
547
|
+
asx: "http://www.sap.com/abapxml"
|
|
548
|
+
},
|
|
549
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
550
|
+
elementFormDefault: "unqualified",
|
|
551
|
+
element: [
|
|
552
|
+
{
|
|
553
|
+
name: "abapGit",
|
|
554
|
+
complexType: {
|
|
555
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
556
|
+
attribute: [
|
|
557
|
+
{
|
|
558
|
+
name: "version",
|
|
559
|
+
type: "xs:string",
|
|
560
|
+
use: "required"
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
name: "serializer",
|
|
564
|
+
type: "xs:string",
|
|
565
|
+
use: "required"
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
name: "serializer_version",
|
|
569
|
+
type: "xs:string",
|
|
570
|
+
use: "required"
|
|
571
|
+
}
|
|
572
|
+
]
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
name: "Schema",
|
|
577
|
+
abstract: true
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
name: "values",
|
|
581
|
+
type: "asx:AbapValuesType"
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
name: "abap",
|
|
585
|
+
type: "asx:AbapType"
|
|
586
|
+
}
|
|
587
|
+
],
|
|
588
|
+
complexType: [
|
|
589
|
+
{
|
|
590
|
+
name: "AbapValuesType",
|
|
591
|
+
all: { element: [{
|
|
592
|
+
name: "DD01V",
|
|
593
|
+
type: "asx:Dd01vType",
|
|
594
|
+
minOccurs: "0"
|
|
595
|
+
}, {
|
|
596
|
+
name: "DD07V_TAB",
|
|
597
|
+
type: "asx:Dd07vTabType",
|
|
598
|
+
minOccurs: "0"
|
|
599
|
+
}] }
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
name: "Dd01vType",
|
|
603
|
+
all: { element: [
|
|
604
|
+
{
|
|
605
|
+
name: "DOMNAME",
|
|
606
|
+
type: "xs:string"
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
name: "DDLANGUAGE",
|
|
610
|
+
type: "xs:string",
|
|
611
|
+
minOccurs: "0"
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
name: "DATATYPE",
|
|
615
|
+
type: "xs:string",
|
|
616
|
+
minOccurs: "0"
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
name: "LENG",
|
|
620
|
+
type: "xs:string",
|
|
621
|
+
minOccurs: "0"
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
name: "OUTPUTLEN",
|
|
625
|
+
type: "xs:string",
|
|
626
|
+
minOccurs: "0"
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
name: "DECIMALS",
|
|
630
|
+
type: "xs:string",
|
|
631
|
+
minOccurs: "0"
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
name: "LOWERCASE",
|
|
635
|
+
type: "xs:string",
|
|
636
|
+
minOccurs: "0"
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
name: "SIGNFLAG",
|
|
640
|
+
type: "xs:string",
|
|
641
|
+
minOccurs: "0"
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
name: "VALEXI",
|
|
645
|
+
type: "xs:string",
|
|
646
|
+
minOccurs: "0"
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
name: "ENTITYTAB",
|
|
650
|
+
type: "xs:string",
|
|
651
|
+
minOccurs: "0"
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
name: "CONVEXIT",
|
|
655
|
+
type: "xs:string",
|
|
656
|
+
minOccurs: "0"
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
name: "DDTEXT",
|
|
660
|
+
type: "xs:string",
|
|
661
|
+
minOccurs: "0"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
name: "DOMMASTER",
|
|
665
|
+
type: "xs:string",
|
|
666
|
+
minOccurs: "0"
|
|
667
|
+
}
|
|
668
|
+
] }
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
name: "Dd07vType",
|
|
672
|
+
all: { element: [
|
|
673
|
+
{
|
|
674
|
+
name: "DOMNAME",
|
|
675
|
+
type: "xs:string",
|
|
676
|
+
minOccurs: "0"
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
name: "VALPOS",
|
|
680
|
+
type: "xs:string",
|
|
681
|
+
minOccurs: "0"
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
name: "DDLANGUAGE",
|
|
685
|
+
type: "xs:string",
|
|
686
|
+
minOccurs: "0"
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
name: "DOMVALUE_L",
|
|
690
|
+
type: "xs:string",
|
|
691
|
+
minOccurs: "0"
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
name: "DOMVALUE_H",
|
|
695
|
+
type: "xs:string",
|
|
696
|
+
minOccurs: "0"
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
name: "DDTEXT",
|
|
700
|
+
type: "xs:string",
|
|
701
|
+
minOccurs: "0"
|
|
702
|
+
}
|
|
703
|
+
] }
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
name: "Dd07vTabType",
|
|
707
|
+
sequence: { element: [{
|
|
708
|
+
name: "DD07V",
|
|
709
|
+
type: "Dd07vType",
|
|
710
|
+
minOccurs: "0",
|
|
711
|
+
maxOccurs: "unbounded"
|
|
712
|
+
}] }
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
name: "AbapType",
|
|
716
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
717
|
+
attribute: [{
|
|
718
|
+
name: "version",
|
|
719
|
+
type: "xs:string",
|
|
720
|
+
"default": "1.0"
|
|
721
|
+
}]
|
|
722
|
+
}
|
|
723
|
+
]
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
//#endregion
|
|
727
|
+
//#region src/schemas/generated/schemas/dtel.ts
|
|
728
|
+
/**
|
|
729
|
+
* Auto-generated schema from XSD
|
|
730
|
+
*
|
|
731
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
732
|
+
* Source: abapgit/dtel.xsd
|
|
733
|
+
*/
|
|
734
|
+
var dtel_default = {
|
|
735
|
+
$xmlns: {
|
|
736
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
737
|
+
asx: "http://www.sap.com/abapxml"
|
|
738
|
+
},
|
|
739
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
740
|
+
elementFormDefault: "unqualified",
|
|
741
|
+
element: [
|
|
742
|
+
{
|
|
743
|
+
name: "abapGit",
|
|
744
|
+
complexType: {
|
|
745
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
746
|
+
attribute: [
|
|
747
|
+
{
|
|
748
|
+
name: "version",
|
|
749
|
+
type: "xs:string",
|
|
750
|
+
use: "required"
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
name: "serializer",
|
|
754
|
+
type: "xs:string",
|
|
755
|
+
use: "required"
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
name: "serializer_version",
|
|
759
|
+
type: "xs:string",
|
|
760
|
+
use: "required"
|
|
761
|
+
}
|
|
762
|
+
]
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
{
|
|
766
|
+
name: "Schema",
|
|
767
|
+
abstract: true
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
name: "values",
|
|
771
|
+
type: "asx:AbapValuesType"
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
name: "abap",
|
|
775
|
+
type: "asx:AbapType"
|
|
776
|
+
}
|
|
777
|
+
],
|
|
778
|
+
complexType: [
|
|
779
|
+
{
|
|
780
|
+
name: "AbapValuesType",
|
|
781
|
+
all: { element: [{
|
|
782
|
+
name: "DD04V",
|
|
783
|
+
type: "asx:Dd04vType",
|
|
784
|
+
minOccurs: "0"
|
|
785
|
+
}] }
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
name: "Dd04vType",
|
|
789
|
+
sequence: { element: [
|
|
790
|
+
{
|
|
791
|
+
name: "ROLLNAME",
|
|
792
|
+
type: "xs:string"
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
name: "DDLANGUAGE",
|
|
796
|
+
type: "xs:string",
|
|
797
|
+
minOccurs: "0"
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
name: "DOMNAME",
|
|
801
|
+
type: "xs:string",
|
|
802
|
+
minOccurs: "0"
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
name: "HEADLEN",
|
|
806
|
+
type: "xs:string",
|
|
807
|
+
minOccurs: "0"
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
name: "SCRLEN1",
|
|
811
|
+
type: "xs:string",
|
|
812
|
+
minOccurs: "0"
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
name: "SCRLEN2",
|
|
816
|
+
type: "xs:string",
|
|
817
|
+
minOccurs: "0"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
name: "SCRLEN3",
|
|
821
|
+
type: "xs:string",
|
|
822
|
+
minOccurs: "0"
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
name: "DDTEXT",
|
|
826
|
+
type: "xs:string",
|
|
827
|
+
minOccurs: "0"
|
|
828
|
+
},
|
|
829
|
+
{
|
|
830
|
+
name: "REPTEXT",
|
|
831
|
+
type: "xs:string",
|
|
832
|
+
minOccurs: "0"
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
name: "SCRTEXT_S",
|
|
836
|
+
type: "xs:string",
|
|
837
|
+
minOccurs: "0"
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
name: "SCRTEXT_M",
|
|
841
|
+
type: "xs:string",
|
|
842
|
+
minOccurs: "0"
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
name: "SCRTEXT_L",
|
|
846
|
+
type: "xs:string",
|
|
847
|
+
minOccurs: "0"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
name: "DTELMASTER",
|
|
851
|
+
type: "xs:string",
|
|
852
|
+
minOccurs: "0"
|
|
853
|
+
},
|
|
854
|
+
{
|
|
855
|
+
name: "DATATYPE",
|
|
856
|
+
type: "xs:string",
|
|
857
|
+
minOccurs: "0"
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
name: "LENG",
|
|
861
|
+
type: "xs:string",
|
|
862
|
+
minOccurs: "0"
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
name: "DECIMALS",
|
|
866
|
+
type: "xs:string",
|
|
867
|
+
minOccurs: "0"
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
name: "OUTPUTLEN",
|
|
871
|
+
type: "xs:string",
|
|
872
|
+
minOccurs: "0"
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
name: "REFKIND",
|
|
876
|
+
type: "xs:string",
|
|
877
|
+
minOccurs: "0"
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
name: "REFTYPE",
|
|
881
|
+
type: "xs:string",
|
|
882
|
+
minOccurs: "0"
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
name: "ABAP_LANGUAGE_VERSION",
|
|
886
|
+
type: "xs:string",
|
|
887
|
+
minOccurs: "0"
|
|
888
|
+
}
|
|
889
|
+
] }
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
name: "AbapType",
|
|
893
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
894
|
+
attribute: [{
|
|
895
|
+
name: "version",
|
|
896
|
+
type: "xs:string",
|
|
897
|
+
"default": "1.0"
|
|
898
|
+
}]
|
|
899
|
+
}
|
|
900
|
+
]
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
//#endregion
|
|
904
|
+
//#region src/schemas/generated/schemas/intf.ts
|
|
905
|
+
/**
|
|
906
|
+
* Auto-generated schema from XSD
|
|
907
|
+
*
|
|
908
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
909
|
+
* Source: abapgit/intf.xsd
|
|
910
|
+
*/
|
|
911
|
+
var intf_default = {
|
|
912
|
+
$xmlns: {
|
|
913
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
914
|
+
asx: "http://www.sap.com/abapxml"
|
|
915
|
+
},
|
|
916
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
917
|
+
elementFormDefault: "unqualified",
|
|
918
|
+
element: [
|
|
919
|
+
{
|
|
920
|
+
name: "abapGit",
|
|
921
|
+
complexType: {
|
|
922
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
923
|
+
attribute: [
|
|
924
|
+
{
|
|
925
|
+
name: "version",
|
|
926
|
+
type: "xs:string",
|
|
927
|
+
use: "required"
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
name: "serializer",
|
|
931
|
+
type: "xs:string",
|
|
932
|
+
use: "required"
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
name: "serializer_version",
|
|
936
|
+
type: "xs:string",
|
|
937
|
+
use: "required"
|
|
938
|
+
}
|
|
939
|
+
]
|
|
940
|
+
}
|
|
941
|
+
},
|
|
942
|
+
{
|
|
943
|
+
name: "Schema",
|
|
944
|
+
abstract: true
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
name: "values",
|
|
948
|
+
type: "asx:AbapValuesType"
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
name: "abap",
|
|
952
|
+
type: "asx:AbapType"
|
|
953
|
+
}
|
|
954
|
+
],
|
|
955
|
+
complexType: [
|
|
956
|
+
{
|
|
957
|
+
name: "AbapValuesType",
|
|
958
|
+
all: { element: [{
|
|
959
|
+
name: "VSEOINTERF",
|
|
960
|
+
type: "asx:VseoInterfType",
|
|
961
|
+
minOccurs: "0"
|
|
962
|
+
}] }
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
name: "VseoInterfType",
|
|
966
|
+
all: { element: [
|
|
967
|
+
{
|
|
968
|
+
name: "CLSNAME",
|
|
969
|
+
type: "xs:string"
|
|
970
|
+
},
|
|
971
|
+
{
|
|
972
|
+
name: "LANGU",
|
|
973
|
+
type: "xs:string",
|
|
974
|
+
minOccurs: "0"
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
name: "DESCRIPT",
|
|
978
|
+
type: "xs:string",
|
|
979
|
+
minOccurs: "0"
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
name: "EXPOSURE",
|
|
983
|
+
type: "xs:string",
|
|
984
|
+
minOccurs: "0"
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
name: "STATE",
|
|
988
|
+
type: "xs:string",
|
|
989
|
+
minOccurs: "0"
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
name: "UNICODE",
|
|
993
|
+
type: "xs:string",
|
|
994
|
+
minOccurs: "0"
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
name: "ABAP_LANGUAGE_VERSION",
|
|
998
|
+
type: "xs:string",
|
|
999
|
+
minOccurs: "0"
|
|
1000
|
+
}
|
|
1001
|
+
] }
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
name: "AbapType",
|
|
1005
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
1006
|
+
attribute: [{
|
|
1007
|
+
name: "version",
|
|
1008
|
+
type: "xs:string",
|
|
1009
|
+
"default": "1.0"
|
|
1010
|
+
}]
|
|
1011
|
+
}
|
|
1012
|
+
]
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
//#endregion
|
|
1016
|
+
//#region src/schemas/generated/schemas/prog.ts
|
|
1017
|
+
/**
|
|
1018
|
+
* Auto-generated schema from XSD
|
|
1019
|
+
*
|
|
1020
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
1021
|
+
* Source: abapgit/prog.xsd
|
|
1022
|
+
*/
|
|
1023
|
+
var prog_default = {
|
|
1024
|
+
$xmlns: {
|
|
1025
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
1026
|
+
asx: "http://www.sap.com/abapxml"
|
|
1027
|
+
},
|
|
1028
|
+
elementFormDefault: "unqualified",
|
|
1029
|
+
element: [{
|
|
1030
|
+
name: "abapGit",
|
|
1031
|
+
complexType: {
|
|
1032
|
+
sequence: { element: [{
|
|
1033
|
+
name: "abap",
|
|
1034
|
+
type: "ProgAbapType"
|
|
1035
|
+
}] },
|
|
1036
|
+
attribute: [
|
|
1037
|
+
{
|
|
1038
|
+
name: "version",
|
|
1039
|
+
type: "xs:string",
|
|
1040
|
+
use: "required"
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
name: "serializer",
|
|
1044
|
+
type: "xs:string",
|
|
1045
|
+
use: "required"
|
|
1046
|
+
},
|
|
1047
|
+
{
|
|
1048
|
+
name: "serializer_version",
|
|
1049
|
+
type: "xs:string",
|
|
1050
|
+
use: "required"
|
|
1051
|
+
}
|
|
1052
|
+
]
|
|
1053
|
+
}
|
|
1054
|
+
}, {
|
|
1055
|
+
name: "Schema",
|
|
1056
|
+
abstract: true
|
|
1057
|
+
}],
|
|
1058
|
+
complexType: [
|
|
1059
|
+
{
|
|
1060
|
+
name: "ProgValuesType",
|
|
1061
|
+
all: { element: [{
|
|
1062
|
+
name: "PROGDIR",
|
|
1063
|
+
type: "ProgdirType",
|
|
1064
|
+
minOccurs: "0"
|
|
1065
|
+
}, {
|
|
1066
|
+
name: "TPOOL",
|
|
1067
|
+
type: "TpoolType",
|
|
1068
|
+
minOccurs: "0"
|
|
1069
|
+
}] }
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
name: "ProgAbapType",
|
|
1073
|
+
sequence: { element: [{
|
|
1074
|
+
name: "values",
|
|
1075
|
+
type: "ProgValuesType"
|
|
1076
|
+
}] },
|
|
1077
|
+
attribute: [{
|
|
1078
|
+
name: "version",
|
|
1079
|
+
type: "xs:string",
|
|
1080
|
+
"default": "1.0"
|
|
1081
|
+
}]
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
name: "AbapValuesType",
|
|
1085
|
+
sequence: { element: [{
|
|
1086
|
+
ref: "asx:Schema",
|
|
1087
|
+
minOccurs: "0",
|
|
1088
|
+
maxOccurs: "unbounded"
|
|
1089
|
+
}] }
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
name: "AbapType",
|
|
1093
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
1094
|
+
attribute: [{
|
|
1095
|
+
name: "version",
|
|
1096
|
+
type: "xs:string",
|
|
1097
|
+
"default": "1.0"
|
|
1098
|
+
}]
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
name: "ProgdirType",
|
|
1102
|
+
all: { element: [
|
|
1103
|
+
{
|
|
1104
|
+
name: "NAME",
|
|
1105
|
+
type: "xs:string"
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
name: "STATE",
|
|
1109
|
+
type: "xs:string",
|
|
1110
|
+
minOccurs: "0"
|
|
1111
|
+
},
|
|
1112
|
+
{
|
|
1113
|
+
name: "SUBC",
|
|
1114
|
+
type: "xs:string",
|
|
1115
|
+
minOccurs: "0"
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
name: "FIXPT",
|
|
1119
|
+
type: "xs:string",
|
|
1120
|
+
minOccurs: "0"
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
name: "UNICODE",
|
|
1124
|
+
type: "xs:string",
|
|
1125
|
+
minOccurs: "0"
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
name: "DTEFUNC",
|
|
1129
|
+
type: "xs:string",
|
|
1130
|
+
minOccurs: "0"
|
|
1131
|
+
},
|
|
1132
|
+
{
|
|
1133
|
+
name: "RLOAD",
|
|
1134
|
+
type: "xs:string",
|
|
1135
|
+
minOccurs: "0"
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
name: "UCCHECK",
|
|
1139
|
+
type: "xs:string",
|
|
1140
|
+
minOccurs: "0"
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
name: "ABAP_LANGUAGE_VERSION",
|
|
1144
|
+
type: "xs:string",
|
|
1145
|
+
minOccurs: "0"
|
|
1146
|
+
}
|
|
1147
|
+
] }
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
name: "TpoolItemType",
|
|
1151
|
+
all: { element: [
|
|
1152
|
+
{
|
|
1153
|
+
name: "ID",
|
|
1154
|
+
type: "xs:string"
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
name: "ENTRY",
|
|
1158
|
+
type: "xs:string",
|
|
1159
|
+
minOccurs: "0"
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
name: "LENGTH",
|
|
1163
|
+
type: "xs:string",
|
|
1164
|
+
minOccurs: "0"
|
|
1165
|
+
}
|
|
1166
|
+
] }
|
|
1167
|
+
},
|
|
1168
|
+
{
|
|
1169
|
+
name: "TpoolType",
|
|
1170
|
+
sequence: { element: [{
|
|
1171
|
+
name: "item",
|
|
1172
|
+
type: "TpoolItemType",
|
|
1173
|
+
minOccurs: "0",
|
|
1174
|
+
maxOccurs: "unbounded"
|
|
1175
|
+
}] }
|
|
1176
|
+
}
|
|
1177
|
+
]
|
|
1178
|
+
};
|
|
1179
|
+
|
|
1180
|
+
//#endregion
|
|
1181
|
+
//#region src/schemas/generated/schemas/fugr.ts
|
|
1182
|
+
/**
|
|
1183
|
+
* Auto-generated schema from XSD
|
|
1184
|
+
*
|
|
1185
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
1186
|
+
* Source: abapgit/fugr.xsd
|
|
1187
|
+
*/
|
|
1188
|
+
var fugr_default = {
|
|
1189
|
+
$xmlns: {
|
|
1190
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
1191
|
+
asx: "http://www.sap.com/abapxml"
|
|
1192
|
+
},
|
|
1193
|
+
elementFormDefault: "unqualified",
|
|
1194
|
+
element: [{
|
|
1195
|
+
name: "abapGit",
|
|
1196
|
+
complexType: {
|
|
1197
|
+
sequence: { element: [{
|
|
1198
|
+
name: "abap",
|
|
1199
|
+
type: "FugrAbapType"
|
|
1200
|
+
}] },
|
|
1201
|
+
attribute: [
|
|
1202
|
+
{
|
|
1203
|
+
name: "version",
|
|
1204
|
+
type: "xs:string",
|
|
1205
|
+
use: "required"
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
name: "serializer",
|
|
1209
|
+
type: "xs:string",
|
|
1210
|
+
use: "required"
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
name: "serializer_version",
|
|
1214
|
+
type: "xs:string",
|
|
1215
|
+
use: "required"
|
|
1216
|
+
}
|
|
1217
|
+
]
|
|
1218
|
+
}
|
|
1219
|
+
}, {
|
|
1220
|
+
name: "Schema",
|
|
1221
|
+
abstract: true
|
|
1222
|
+
}],
|
|
1223
|
+
complexType: [
|
|
1224
|
+
{
|
|
1225
|
+
name: "FugrValuesType",
|
|
1226
|
+
all: { element: [
|
|
1227
|
+
{
|
|
1228
|
+
name: "AREAT",
|
|
1229
|
+
type: "xs:string",
|
|
1230
|
+
minOccurs: "0"
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
name: "INCLUDES",
|
|
1234
|
+
type: "FugrIncludesType",
|
|
1235
|
+
minOccurs: "0"
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
name: "FUNCTIONS",
|
|
1239
|
+
type: "FugrFunctionsType",
|
|
1240
|
+
minOccurs: "0"
|
|
1241
|
+
}
|
|
1242
|
+
] }
|
|
1243
|
+
},
|
|
1244
|
+
{
|
|
1245
|
+
name: "FugrAbapType",
|
|
1246
|
+
sequence: { element: [{
|
|
1247
|
+
name: "values",
|
|
1248
|
+
type: "FugrValuesType"
|
|
1249
|
+
}] },
|
|
1250
|
+
attribute: [{
|
|
1251
|
+
name: "version",
|
|
1252
|
+
type: "xs:string",
|
|
1253
|
+
"default": "1.0"
|
|
1254
|
+
}]
|
|
1255
|
+
},
|
|
1256
|
+
{
|
|
1257
|
+
name: "AbapValuesType",
|
|
1258
|
+
sequence: { element: [{
|
|
1259
|
+
ref: "asx:Schema",
|
|
1260
|
+
minOccurs: "0",
|
|
1261
|
+
maxOccurs: "unbounded"
|
|
1262
|
+
}] }
|
|
1263
|
+
},
|
|
1264
|
+
{
|
|
1265
|
+
name: "AbapType",
|
|
1266
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
1267
|
+
attribute: [{
|
|
1268
|
+
name: "version",
|
|
1269
|
+
type: "xs:string",
|
|
1270
|
+
"default": "1.0"
|
|
1271
|
+
}]
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
name: "FugrParamType",
|
|
1275
|
+
all: { element: [
|
|
1276
|
+
{
|
|
1277
|
+
name: "PARAMETER",
|
|
1278
|
+
type: "xs:string",
|
|
1279
|
+
minOccurs: "0"
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
name: "TYP",
|
|
1283
|
+
type: "xs:string",
|
|
1284
|
+
minOccurs: "0"
|
|
1285
|
+
},
|
|
1286
|
+
{
|
|
1287
|
+
name: "DBFIELD",
|
|
1288
|
+
type: "xs:string",
|
|
1289
|
+
minOccurs: "0"
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
name: "DEFAULT",
|
|
1293
|
+
type: "xs:string",
|
|
1294
|
+
minOccurs: "0"
|
|
1295
|
+
},
|
|
1296
|
+
{
|
|
1297
|
+
name: "OPTIONAL",
|
|
1298
|
+
type: "xs:string",
|
|
1299
|
+
minOccurs: "0"
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
name: "REFERENCE",
|
|
1303
|
+
type: "xs:string",
|
|
1304
|
+
minOccurs: "0"
|
|
1305
|
+
}
|
|
1306
|
+
] }
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
name: "FugrTableParamType",
|
|
1310
|
+
all: { element: [
|
|
1311
|
+
{
|
|
1312
|
+
name: "PARAMETER",
|
|
1313
|
+
type: "xs:string",
|
|
1314
|
+
minOccurs: "0"
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
name: "DBSTRUCT",
|
|
1318
|
+
type: "xs:string",
|
|
1319
|
+
minOccurs: "0"
|
|
1320
|
+
},
|
|
1321
|
+
{
|
|
1322
|
+
name: "TYP",
|
|
1323
|
+
type: "xs:string",
|
|
1324
|
+
minOccurs: "0"
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
name: "OPTIONAL",
|
|
1328
|
+
type: "xs:string",
|
|
1329
|
+
minOccurs: "0"
|
|
1330
|
+
}
|
|
1331
|
+
] }
|
|
1332
|
+
},
|
|
1333
|
+
{
|
|
1334
|
+
name: "FugrExceptionType",
|
|
1335
|
+
all: { element: [{
|
|
1336
|
+
name: "EXCEPTION",
|
|
1337
|
+
type: "xs:string",
|
|
1338
|
+
minOccurs: "0"
|
|
1339
|
+
}] }
|
|
1340
|
+
},
|
|
1341
|
+
{
|
|
1342
|
+
name: "FugrDocParamType",
|
|
1343
|
+
all: { element: [
|
|
1344
|
+
{
|
|
1345
|
+
name: "PARAMETER",
|
|
1346
|
+
type: "xs:string",
|
|
1347
|
+
minOccurs: "0"
|
|
1348
|
+
},
|
|
1349
|
+
{
|
|
1350
|
+
name: "KIND",
|
|
1351
|
+
type: "xs:string",
|
|
1352
|
+
minOccurs: "0"
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
name: "STEXT",
|
|
1356
|
+
type: "xs:string",
|
|
1357
|
+
minOccurs: "0"
|
|
1358
|
+
}
|
|
1359
|
+
] }
|
|
1360
|
+
},
|
|
1361
|
+
{
|
|
1362
|
+
name: "FugrImportType",
|
|
1363
|
+
sequence: { element: [{
|
|
1364
|
+
name: "RSIMP",
|
|
1365
|
+
type: "FugrParamType",
|
|
1366
|
+
minOccurs: "0",
|
|
1367
|
+
maxOccurs: "unbounded"
|
|
1368
|
+
}] }
|
|
1369
|
+
},
|
|
1370
|
+
{
|
|
1371
|
+
name: "FugrExportType",
|
|
1372
|
+
sequence: { element: [{
|
|
1373
|
+
name: "RSEXP",
|
|
1374
|
+
type: "FugrParamType",
|
|
1375
|
+
minOccurs: "0",
|
|
1376
|
+
maxOccurs: "unbounded"
|
|
1377
|
+
}] }
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
name: "FugrChangingType",
|
|
1381
|
+
sequence: { element: [{
|
|
1382
|
+
name: "RSCHA",
|
|
1383
|
+
type: "FugrParamType",
|
|
1384
|
+
minOccurs: "0",
|
|
1385
|
+
maxOccurs: "unbounded"
|
|
1386
|
+
}] }
|
|
1387
|
+
},
|
|
1388
|
+
{
|
|
1389
|
+
name: "FugrTablesType",
|
|
1390
|
+
sequence: { element: [{
|
|
1391
|
+
name: "RSTBL",
|
|
1392
|
+
type: "FugrTableParamType",
|
|
1393
|
+
minOccurs: "0",
|
|
1394
|
+
maxOccurs: "unbounded"
|
|
1395
|
+
}] }
|
|
1396
|
+
},
|
|
1397
|
+
{
|
|
1398
|
+
name: "FugrExceptionsType",
|
|
1399
|
+
sequence: { element: [{
|
|
1400
|
+
name: "RSEXC",
|
|
1401
|
+
type: "FugrExceptionType",
|
|
1402
|
+
minOccurs: "0",
|
|
1403
|
+
maxOccurs: "unbounded"
|
|
1404
|
+
}] }
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
name: "FugrDocumentationType",
|
|
1408
|
+
sequence: { element: [{
|
|
1409
|
+
name: "RSFDO",
|
|
1410
|
+
type: "FugrDocParamType",
|
|
1411
|
+
minOccurs: "0",
|
|
1412
|
+
maxOccurs: "unbounded"
|
|
1413
|
+
}] }
|
|
1414
|
+
},
|
|
1415
|
+
{
|
|
1416
|
+
name: "FugrFunctionItemType",
|
|
1417
|
+
all: { element: [
|
|
1418
|
+
{
|
|
1419
|
+
name: "FUNCNAME",
|
|
1420
|
+
type: "xs:string"
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
name: "GLOBAL_FLAG",
|
|
1424
|
+
type: "xs:string",
|
|
1425
|
+
minOccurs: "0"
|
|
1426
|
+
},
|
|
1427
|
+
{
|
|
1428
|
+
name: "REMOTE_CALL",
|
|
1429
|
+
type: "xs:string",
|
|
1430
|
+
minOccurs: "0"
|
|
1431
|
+
},
|
|
1432
|
+
{
|
|
1433
|
+
name: "UPDATE_TASK",
|
|
1434
|
+
type: "xs:string",
|
|
1435
|
+
minOccurs: "0"
|
|
1436
|
+
},
|
|
1437
|
+
{
|
|
1438
|
+
name: "SHORT_TEXT",
|
|
1439
|
+
type: "xs:string",
|
|
1440
|
+
minOccurs: "0"
|
|
1441
|
+
},
|
|
1442
|
+
{
|
|
1443
|
+
name: "REMOTE_BASXML",
|
|
1444
|
+
type: "xs:string",
|
|
1445
|
+
minOccurs: "0"
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
name: "EXCEPTION_CLASSES",
|
|
1449
|
+
type: "xs:string",
|
|
1450
|
+
minOccurs: "0"
|
|
1451
|
+
},
|
|
1452
|
+
{
|
|
1453
|
+
name: "IMPORT",
|
|
1454
|
+
type: "FugrImportType",
|
|
1455
|
+
minOccurs: "0"
|
|
1456
|
+
},
|
|
1457
|
+
{
|
|
1458
|
+
name: "CHANGING",
|
|
1459
|
+
type: "FugrChangingType",
|
|
1460
|
+
minOccurs: "0"
|
|
1461
|
+
},
|
|
1462
|
+
{
|
|
1463
|
+
name: "EXPORT",
|
|
1464
|
+
type: "FugrExportType",
|
|
1465
|
+
minOccurs: "0"
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
name: "TABLES",
|
|
1469
|
+
type: "FugrTablesType",
|
|
1470
|
+
minOccurs: "0"
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
name: "EXCEPTION",
|
|
1474
|
+
type: "FugrExceptionsType",
|
|
1475
|
+
minOccurs: "0"
|
|
1476
|
+
},
|
|
1477
|
+
{
|
|
1478
|
+
name: "DOCUMENTATION",
|
|
1479
|
+
type: "FugrDocumentationType",
|
|
1480
|
+
minOccurs: "0"
|
|
1481
|
+
}
|
|
1482
|
+
] }
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
name: "FugrFunctionsType",
|
|
1486
|
+
sequence: { element: [{
|
|
1487
|
+
name: "item",
|
|
1488
|
+
type: "FugrFunctionItemType",
|
|
1489
|
+
minOccurs: "0",
|
|
1490
|
+
maxOccurs: "unbounded"
|
|
1491
|
+
}] }
|
|
1492
|
+
},
|
|
1493
|
+
{
|
|
1494
|
+
name: "FugrIncludesType",
|
|
1495
|
+
sequence: { element: [{
|
|
1496
|
+
name: "SOBJ_NAME",
|
|
1497
|
+
type: "xs:string",
|
|
1498
|
+
minOccurs: "0",
|
|
1499
|
+
maxOccurs: "unbounded"
|
|
1500
|
+
}] }
|
|
1501
|
+
}
|
|
1502
|
+
]
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
//#endregion
|
|
1506
|
+
//#region src/schemas/generated/schemas/tabl.ts
|
|
1507
|
+
/**
|
|
1508
|
+
* Auto-generated schema from XSD
|
|
1509
|
+
*
|
|
1510
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
1511
|
+
* Source: abapgit/tabl.xsd
|
|
1512
|
+
*/
|
|
1513
|
+
var tabl_default = {
|
|
1514
|
+
$xmlns: {
|
|
1515
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
1516
|
+
asx: "http://www.sap.com/abapxml"
|
|
1517
|
+
},
|
|
1518
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
1519
|
+
elementFormDefault: "unqualified",
|
|
1520
|
+
element: [
|
|
1521
|
+
{
|
|
1522
|
+
name: "abapGit",
|
|
1523
|
+
complexType: {
|
|
1524
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
1525
|
+
attribute: [
|
|
1526
|
+
{
|
|
1527
|
+
name: "version",
|
|
1528
|
+
type: "xs:string",
|
|
1529
|
+
use: "required"
|
|
1530
|
+
},
|
|
1531
|
+
{
|
|
1532
|
+
name: "serializer",
|
|
1533
|
+
type: "xs:string",
|
|
1534
|
+
use: "required"
|
|
1535
|
+
},
|
|
1536
|
+
{
|
|
1537
|
+
name: "serializer_version",
|
|
1538
|
+
type: "xs:string",
|
|
1539
|
+
use: "required"
|
|
1540
|
+
}
|
|
1541
|
+
]
|
|
1542
|
+
}
|
|
1543
|
+
},
|
|
1544
|
+
{
|
|
1545
|
+
name: "Schema",
|
|
1546
|
+
abstract: true
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
name: "values",
|
|
1550
|
+
type: "asx:AbapValuesType"
|
|
1551
|
+
},
|
|
1552
|
+
{
|
|
1553
|
+
name: "abap",
|
|
1554
|
+
type: "asx:AbapType"
|
|
1555
|
+
}
|
|
1556
|
+
],
|
|
1557
|
+
complexType: [
|
|
1558
|
+
{
|
|
1559
|
+
name: "AbapValuesType",
|
|
1560
|
+
all: { element: [
|
|
1561
|
+
{
|
|
1562
|
+
name: "DD02V",
|
|
1563
|
+
type: "asx:Dd02vType",
|
|
1564
|
+
minOccurs: "0"
|
|
1565
|
+
},
|
|
1566
|
+
{
|
|
1567
|
+
name: "DD09L",
|
|
1568
|
+
type: "asx:Dd09lType",
|
|
1569
|
+
minOccurs: "0"
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
name: "DD03P_TABLE",
|
|
1573
|
+
type: "asx:Dd03pTableType",
|
|
1574
|
+
minOccurs: "0"
|
|
1575
|
+
},
|
|
1576
|
+
{
|
|
1577
|
+
name: "TABL_EXTRAS",
|
|
1578
|
+
type: "asx:TablExtrasType",
|
|
1579
|
+
minOccurs: "0"
|
|
1580
|
+
}
|
|
1581
|
+
] }
|
|
1582
|
+
},
|
|
1583
|
+
{
|
|
1584
|
+
name: "Dd02vType",
|
|
1585
|
+
sequence: { element: [
|
|
1586
|
+
{
|
|
1587
|
+
name: "TABNAME",
|
|
1588
|
+
type: "xs:string"
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
name: "DDLANGUAGE",
|
|
1592
|
+
type: "xs:string",
|
|
1593
|
+
minOccurs: "0"
|
|
1594
|
+
},
|
|
1595
|
+
{
|
|
1596
|
+
name: "TABCLASS",
|
|
1597
|
+
type: "xs:string",
|
|
1598
|
+
minOccurs: "0"
|
|
1599
|
+
},
|
|
1600
|
+
{
|
|
1601
|
+
name: "LANGDEP",
|
|
1602
|
+
type: "xs:string",
|
|
1603
|
+
minOccurs: "0"
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
name: "CLIDEP",
|
|
1607
|
+
type: "xs:string",
|
|
1608
|
+
minOccurs: "0"
|
|
1609
|
+
},
|
|
1610
|
+
{
|
|
1611
|
+
name: "SQLTAB",
|
|
1612
|
+
type: "xs:string",
|
|
1613
|
+
minOccurs: "0"
|
|
1614
|
+
},
|
|
1615
|
+
{
|
|
1616
|
+
name: "DATCLASS",
|
|
1617
|
+
type: "xs:string",
|
|
1618
|
+
minOccurs: "0"
|
|
1619
|
+
},
|
|
1620
|
+
{
|
|
1621
|
+
name: "DDTEXT",
|
|
1622
|
+
type: "xs:string",
|
|
1623
|
+
minOccurs: "0"
|
|
1624
|
+
},
|
|
1625
|
+
{
|
|
1626
|
+
name: "MASTERLANG",
|
|
1627
|
+
type: "xs:string",
|
|
1628
|
+
minOccurs: "0"
|
|
1629
|
+
},
|
|
1630
|
+
{
|
|
1631
|
+
name: "BUFFERED",
|
|
1632
|
+
type: "xs:string",
|
|
1633
|
+
minOccurs: "0"
|
|
1634
|
+
},
|
|
1635
|
+
{
|
|
1636
|
+
name: "MATEFLAG",
|
|
1637
|
+
type: "xs:string",
|
|
1638
|
+
minOccurs: "0"
|
|
1639
|
+
},
|
|
1640
|
+
{
|
|
1641
|
+
name: "CONTFLAG",
|
|
1642
|
+
type: "xs:string",
|
|
1643
|
+
minOccurs: "0"
|
|
1644
|
+
},
|
|
1645
|
+
{
|
|
1646
|
+
name: "SHLPEXI",
|
|
1647
|
+
type: "xs:string",
|
|
1648
|
+
minOccurs: "0"
|
|
1649
|
+
},
|
|
1650
|
+
{
|
|
1651
|
+
name: "EXCLASS",
|
|
1652
|
+
type: "xs:string",
|
|
1653
|
+
minOccurs: "0"
|
|
1654
|
+
},
|
|
1655
|
+
{
|
|
1656
|
+
name: "AUTHCLASS",
|
|
1657
|
+
type: "xs:string",
|
|
1658
|
+
minOccurs: "0"
|
|
1659
|
+
}
|
|
1660
|
+
] }
|
|
1661
|
+
},
|
|
1662
|
+
{
|
|
1663
|
+
name: "Dd09lType",
|
|
1664
|
+
sequence: { element: [
|
|
1665
|
+
{
|
|
1666
|
+
name: "TABNAME",
|
|
1667
|
+
type: "xs:string",
|
|
1668
|
+
minOccurs: "0"
|
|
1669
|
+
},
|
|
1670
|
+
{
|
|
1671
|
+
name: "AS4LOCAL",
|
|
1672
|
+
type: "xs:string",
|
|
1673
|
+
minOccurs: "0"
|
|
1674
|
+
},
|
|
1675
|
+
{
|
|
1676
|
+
name: "TABKAT",
|
|
1677
|
+
type: "xs:string",
|
|
1678
|
+
minOccurs: "0"
|
|
1679
|
+
},
|
|
1680
|
+
{
|
|
1681
|
+
name: "TABART",
|
|
1682
|
+
type: "xs:string",
|
|
1683
|
+
minOccurs: "0"
|
|
1684
|
+
},
|
|
1685
|
+
{
|
|
1686
|
+
name: "BUFALLOW",
|
|
1687
|
+
type: "xs:string",
|
|
1688
|
+
minOccurs: "0"
|
|
1689
|
+
},
|
|
1690
|
+
{
|
|
1691
|
+
name: "PUFFERUNG",
|
|
1692
|
+
type: "xs:string",
|
|
1693
|
+
minOccurs: "0"
|
|
1694
|
+
},
|
|
1695
|
+
{
|
|
1696
|
+
name: "SCHFELDANZ",
|
|
1697
|
+
type: "xs:string",
|
|
1698
|
+
minOccurs: "0"
|
|
1699
|
+
},
|
|
1700
|
+
{
|
|
1701
|
+
name: "PROTOKOLL",
|
|
1702
|
+
type: "xs:string",
|
|
1703
|
+
minOccurs: "0"
|
|
1704
|
+
},
|
|
1705
|
+
{
|
|
1706
|
+
name: "SPEESSION",
|
|
1707
|
+
type: "xs:string",
|
|
1708
|
+
minOccurs: "0"
|
|
1709
|
+
},
|
|
1710
|
+
{
|
|
1711
|
+
name: "UESSION",
|
|
1712
|
+
type: "xs:string",
|
|
1713
|
+
minOccurs: "0"
|
|
1714
|
+
},
|
|
1715
|
+
{
|
|
1716
|
+
name: "ROESSION",
|
|
1717
|
+
type: "xs:string",
|
|
1718
|
+
minOccurs: "0"
|
|
1719
|
+
}
|
|
1720
|
+
] }
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
name: "Dd03pType",
|
|
1724
|
+
sequence: { element: [
|
|
1725
|
+
{
|
|
1726
|
+
name: "FIELDNAME",
|
|
1727
|
+
type: "xs:string",
|
|
1728
|
+
minOccurs: "0"
|
|
1729
|
+
},
|
|
1730
|
+
{
|
|
1731
|
+
name: "POSITION",
|
|
1732
|
+
type: "xs:string",
|
|
1733
|
+
minOccurs: "0"
|
|
1734
|
+
},
|
|
1735
|
+
{
|
|
1736
|
+
name: "KEYFLAG",
|
|
1737
|
+
type: "xs:string",
|
|
1738
|
+
minOccurs: "0"
|
|
1739
|
+
},
|
|
1740
|
+
{
|
|
1741
|
+
name: "ROLLNAME",
|
|
1742
|
+
type: "xs:string",
|
|
1743
|
+
minOccurs: "0"
|
|
1744
|
+
},
|
|
1745
|
+
{
|
|
1746
|
+
name: "ADMINFIELD",
|
|
1747
|
+
type: "xs:string",
|
|
1748
|
+
minOccurs: "0"
|
|
1749
|
+
},
|
|
1750
|
+
{
|
|
1751
|
+
name: "INTTYPE",
|
|
1752
|
+
type: "xs:string",
|
|
1753
|
+
minOccurs: "0"
|
|
1754
|
+
},
|
|
1755
|
+
{
|
|
1756
|
+
name: "INTLEN",
|
|
1757
|
+
type: "xs:string",
|
|
1758
|
+
minOccurs: "0"
|
|
1759
|
+
},
|
|
1760
|
+
{
|
|
1761
|
+
name: "REFTABLE",
|
|
1762
|
+
type: "xs:string",
|
|
1763
|
+
minOccurs: "0"
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
name: "REFFIELD",
|
|
1767
|
+
type: "xs:string",
|
|
1768
|
+
minOccurs: "0"
|
|
1769
|
+
},
|
|
1770
|
+
{
|
|
1771
|
+
name: "PRECFIELD",
|
|
1772
|
+
type: "xs:string",
|
|
1773
|
+
minOccurs: "0"
|
|
1774
|
+
},
|
|
1775
|
+
{
|
|
1776
|
+
name: "NOTNULL",
|
|
1777
|
+
type: "xs:string",
|
|
1778
|
+
minOccurs: "0"
|
|
1779
|
+
},
|
|
1780
|
+
{
|
|
1781
|
+
name: "DATATYPE",
|
|
1782
|
+
type: "xs:string",
|
|
1783
|
+
minOccurs: "0"
|
|
1784
|
+
},
|
|
1785
|
+
{
|
|
1786
|
+
name: "LENG",
|
|
1787
|
+
type: "xs:string",
|
|
1788
|
+
minOccurs: "0"
|
|
1789
|
+
},
|
|
1790
|
+
{
|
|
1791
|
+
name: "DECIMALS",
|
|
1792
|
+
type: "xs:string",
|
|
1793
|
+
minOccurs: "0"
|
|
1794
|
+
},
|
|
1795
|
+
{
|
|
1796
|
+
name: "DOMNAME",
|
|
1797
|
+
type: "xs:string",
|
|
1798
|
+
minOccurs: "0"
|
|
1799
|
+
},
|
|
1800
|
+
{
|
|
1801
|
+
name: "MASK",
|
|
1802
|
+
type: "xs:string",
|
|
1803
|
+
minOccurs: "0"
|
|
1804
|
+
},
|
|
1805
|
+
{
|
|
1806
|
+
name: "SHLPORIGIN",
|
|
1807
|
+
type: "xs:string",
|
|
1808
|
+
minOccurs: "0"
|
|
1809
|
+
},
|
|
1810
|
+
{
|
|
1811
|
+
name: "DDTEXT",
|
|
1812
|
+
type: "xs:string",
|
|
1813
|
+
minOccurs: "0"
|
|
1814
|
+
},
|
|
1815
|
+
{
|
|
1816
|
+
name: "COMPTYPE",
|
|
1817
|
+
type: "xs:string",
|
|
1818
|
+
minOccurs: "0"
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
name: "TABNAME",
|
|
1822
|
+
type: "xs:string",
|
|
1823
|
+
minOccurs: "0"
|
|
1824
|
+
},
|
|
1825
|
+
{
|
|
1826
|
+
name: "DDLANGUAGE",
|
|
1827
|
+
type: "xs:string",
|
|
1828
|
+
minOccurs: "0"
|
|
1829
|
+
},
|
|
1830
|
+
{
|
|
1831
|
+
name: "CONRFLAG",
|
|
1832
|
+
type: "xs:string",
|
|
1833
|
+
minOccurs: "0"
|
|
1834
|
+
}
|
|
1835
|
+
] }
|
|
1836
|
+
},
|
|
1837
|
+
{
|
|
1838
|
+
name: "Dd03pTableType",
|
|
1839
|
+
sequence: { element: [{
|
|
1840
|
+
name: "DD03P",
|
|
1841
|
+
type: "Dd03pType",
|
|
1842
|
+
minOccurs: "0",
|
|
1843
|
+
maxOccurs: "unbounded"
|
|
1844
|
+
}] }
|
|
1845
|
+
},
|
|
1846
|
+
{
|
|
1847
|
+
name: "TddatType",
|
|
1848
|
+
sequence: { element: [
|
|
1849
|
+
{
|
|
1850
|
+
name: "TABNAME",
|
|
1851
|
+
type: "xs:string",
|
|
1852
|
+
minOccurs: "0"
|
|
1853
|
+
},
|
|
1854
|
+
{
|
|
1855
|
+
name: "CCLASS",
|
|
1856
|
+
type: "xs:string",
|
|
1857
|
+
minOccurs: "0"
|
|
1858
|
+
},
|
|
1859
|
+
{
|
|
1860
|
+
name: "VIEWGRANT",
|
|
1861
|
+
type: "xs:string",
|
|
1862
|
+
minOccurs: "0"
|
|
1863
|
+
},
|
|
1864
|
+
{
|
|
1865
|
+
name: "TVDIR",
|
|
1866
|
+
type: "xs:string",
|
|
1867
|
+
minOccurs: "0"
|
|
1868
|
+
},
|
|
1869
|
+
{
|
|
1870
|
+
name: "GENERICRANGE",
|
|
1871
|
+
type: "xs:string",
|
|
1872
|
+
minOccurs: "0"
|
|
1873
|
+
}
|
|
1874
|
+
] }
|
|
1875
|
+
},
|
|
1876
|
+
{
|
|
1877
|
+
name: "TablExtrasType",
|
|
1878
|
+
sequence: { element: [{
|
|
1879
|
+
name: "TDDAT",
|
|
1880
|
+
type: "TddatType",
|
|
1881
|
+
minOccurs: "0"
|
|
1882
|
+
}] }
|
|
1883
|
+
},
|
|
1884
|
+
{
|
|
1885
|
+
name: "AbapType",
|
|
1886
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
1887
|
+
attribute: [{
|
|
1888
|
+
name: "version",
|
|
1889
|
+
type: "xs:string",
|
|
1890
|
+
"default": "1.0"
|
|
1891
|
+
}]
|
|
1892
|
+
}
|
|
1893
|
+
]
|
|
1894
|
+
};
|
|
1895
|
+
|
|
1896
|
+
//#endregion
|
|
1897
|
+
//#region src/schemas/generated/schemas/ttyp.ts
|
|
1898
|
+
/**
|
|
1899
|
+
* Auto-generated schema from XSD
|
|
1900
|
+
*
|
|
1901
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
1902
|
+
* Source: abapgit/ttyp.xsd
|
|
1903
|
+
*/
|
|
1904
|
+
var ttyp_default = {
|
|
1905
|
+
$xmlns: {
|
|
1906
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
1907
|
+
asx: "http://www.sap.com/abapxml"
|
|
1908
|
+
},
|
|
1909
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
1910
|
+
elementFormDefault: "unqualified",
|
|
1911
|
+
element: [
|
|
1912
|
+
{
|
|
1913
|
+
name: "abapGit",
|
|
1914
|
+
complexType: {
|
|
1915
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
1916
|
+
attribute: [
|
|
1917
|
+
{
|
|
1918
|
+
name: "version",
|
|
1919
|
+
type: "xs:string",
|
|
1920
|
+
use: "required"
|
|
1921
|
+
},
|
|
1922
|
+
{
|
|
1923
|
+
name: "serializer",
|
|
1924
|
+
type: "xs:string",
|
|
1925
|
+
use: "required"
|
|
1926
|
+
},
|
|
1927
|
+
{
|
|
1928
|
+
name: "serializer_version",
|
|
1929
|
+
type: "xs:string",
|
|
1930
|
+
use: "required"
|
|
1931
|
+
}
|
|
1932
|
+
]
|
|
1933
|
+
}
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
name: "Schema",
|
|
1937
|
+
abstract: true
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
name: "values",
|
|
1941
|
+
type: "asx:AbapValuesType"
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
name: "abap",
|
|
1945
|
+
type: "asx:AbapType"
|
|
1946
|
+
}
|
|
1947
|
+
],
|
|
1948
|
+
complexType: [
|
|
1949
|
+
{
|
|
1950
|
+
name: "AbapValuesType",
|
|
1951
|
+
all: { element: [{
|
|
1952
|
+
name: "DD40V",
|
|
1953
|
+
type: "asx:Dd40vType",
|
|
1954
|
+
minOccurs: "0"
|
|
1955
|
+
}] }
|
|
1956
|
+
},
|
|
1957
|
+
{
|
|
1958
|
+
name: "Dd40vType",
|
|
1959
|
+
all: { element: [
|
|
1960
|
+
{
|
|
1961
|
+
name: "TYPENAME",
|
|
1962
|
+
type: "xs:string"
|
|
1963
|
+
},
|
|
1964
|
+
{
|
|
1965
|
+
name: "DDLANGUAGE",
|
|
1966
|
+
type: "xs:string",
|
|
1967
|
+
minOccurs: "0"
|
|
1968
|
+
},
|
|
1969
|
+
{
|
|
1970
|
+
name: "ROWTYPE",
|
|
1971
|
+
type: "xs:string",
|
|
1972
|
+
minOccurs: "0"
|
|
1973
|
+
},
|
|
1974
|
+
{
|
|
1975
|
+
name: "ROWKIND",
|
|
1976
|
+
type: "xs:string",
|
|
1977
|
+
minOccurs: "0"
|
|
1978
|
+
},
|
|
1979
|
+
{
|
|
1980
|
+
name: "DATATYPE",
|
|
1981
|
+
type: "xs:string",
|
|
1982
|
+
minOccurs: "0"
|
|
1983
|
+
},
|
|
1984
|
+
{
|
|
1985
|
+
name: "ACCESSMODE",
|
|
1986
|
+
type: "xs:string",
|
|
1987
|
+
minOccurs: "0"
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
name: "KEYDEF",
|
|
1991
|
+
type: "xs:string",
|
|
1992
|
+
minOccurs: "0"
|
|
1993
|
+
},
|
|
1994
|
+
{
|
|
1995
|
+
name: "KEYKIND",
|
|
1996
|
+
type: "xs:string",
|
|
1997
|
+
minOccurs: "0"
|
|
1998
|
+
},
|
|
1999
|
+
{
|
|
2000
|
+
name: "GENERIC",
|
|
2001
|
+
type: "xs:string",
|
|
2002
|
+
minOccurs: "0"
|
|
2003
|
+
},
|
|
2004
|
+
{
|
|
2005
|
+
name: "LENG",
|
|
2006
|
+
type: "xs:string",
|
|
2007
|
+
minOccurs: "0"
|
|
2008
|
+
},
|
|
2009
|
+
{
|
|
2010
|
+
name: "DECIMALS",
|
|
2011
|
+
type: "xs:string",
|
|
2012
|
+
minOccurs: "0"
|
|
2013
|
+
},
|
|
2014
|
+
{
|
|
2015
|
+
name: "DDTEXT",
|
|
2016
|
+
type: "xs:string",
|
|
2017
|
+
minOccurs: "0"
|
|
2018
|
+
},
|
|
2019
|
+
{
|
|
2020
|
+
name: "TYPELEN",
|
|
2021
|
+
type: "xs:string",
|
|
2022
|
+
minOccurs: "0"
|
|
2023
|
+
},
|
|
2024
|
+
{
|
|
2025
|
+
name: "DEFFDNAME",
|
|
2026
|
+
type: "xs:string",
|
|
2027
|
+
minOccurs: "0"
|
|
2028
|
+
},
|
|
2029
|
+
{
|
|
2030
|
+
name: "ABAP_LANGUAGE_VERSION",
|
|
2031
|
+
type: "xs:string",
|
|
2032
|
+
minOccurs: "0"
|
|
2033
|
+
}
|
|
2034
|
+
] }
|
|
2035
|
+
},
|
|
2036
|
+
{
|
|
2037
|
+
name: "AbapType",
|
|
2038
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2039
|
+
attribute: [{
|
|
2040
|
+
name: "version",
|
|
2041
|
+
type: "xs:string",
|
|
2042
|
+
"default": "1.0"
|
|
2043
|
+
}]
|
|
2044
|
+
}
|
|
2045
|
+
]
|
|
2046
|
+
};
|
|
2047
|
+
|
|
2048
|
+
//#endregion
|
|
2049
|
+
//#region src/schemas/generated/schemas/bdef.ts
|
|
2050
|
+
/**
|
|
2051
|
+
* Auto-generated schema from XSD
|
|
2052
|
+
*
|
|
2053
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2054
|
+
* Source: abapgit/bdef.xsd
|
|
2055
|
+
*/
|
|
2056
|
+
var bdef_default = {
|
|
2057
|
+
$xmlns: {
|
|
2058
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2059
|
+
asx: "http://www.sap.com/abapxml"
|
|
2060
|
+
},
|
|
2061
|
+
elementFormDefault: "unqualified",
|
|
2062
|
+
element: [{
|
|
2063
|
+
name: "abapGit",
|
|
2064
|
+
complexType: {
|
|
2065
|
+
sequence: { element: [{
|
|
2066
|
+
name: "abap",
|
|
2067
|
+
type: "BdefAbapType"
|
|
2068
|
+
}] },
|
|
2069
|
+
attribute: [
|
|
2070
|
+
{
|
|
2071
|
+
name: "version",
|
|
2072
|
+
type: "xs:string",
|
|
2073
|
+
use: "required"
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
name: "serializer",
|
|
2077
|
+
type: "xs:string",
|
|
2078
|
+
use: "required"
|
|
2079
|
+
},
|
|
2080
|
+
{
|
|
2081
|
+
name: "serializer_version",
|
|
2082
|
+
type: "xs:string",
|
|
2083
|
+
use: "required"
|
|
2084
|
+
}
|
|
2085
|
+
]
|
|
2086
|
+
}
|
|
2087
|
+
}, {
|
|
2088
|
+
name: "Schema",
|
|
2089
|
+
abstract: true
|
|
2090
|
+
}],
|
|
2091
|
+
complexType: [
|
|
2092
|
+
{
|
|
2093
|
+
name: "SkeyType",
|
|
2094
|
+
all: { element: [{
|
|
2095
|
+
name: "TYPE",
|
|
2096
|
+
type: "xs:string",
|
|
2097
|
+
minOccurs: "0"
|
|
2098
|
+
}, {
|
|
2099
|
+
name: "NAME",
|
|
2100
|
+
type: "xs:string",
|
|
2101
|
+
minOccurs: "0"
|
|
2102
|
+
}] }
|
|
2103
|
+
},
|
|
2104
|
+
{
|
|
2105
|
+
name: "BdefValuesType",
|
|
2106
|
+
all: { element: [{
|
|
2107
|
+
name: "SKEY",
|
|
2108
|
+
type: "SkeyType",
|
|
2109
|
+
minOccurs: "0"
|
|
2110
|
+
}] }
|
|
2111
|
+
},
|
|
2112
|
+
{
|
|
2113
|
+
name: "BdefAbapType",
|
|
2114
|
+
sequence: { element: [{
|
|
2115
|
+
name: "values",
|
|
2116
|
+
type: "BdefValuesType"
|
|
2117
|
+
}] },
|
|
2118
|
+
attribute: [{
|
|
2119
|
+
name: "version",
|
|
2120
|
+
type: "xs:string",
|
|
2121
|
+
"default": "1.0"
|
|
2122
|
+
}]
|
|
2123
|
+
},
|
|
2124
|
+
{
|
|
2125
|
+
name: "AbapValuesType",
|
|
2126
|
+
sequence: { element: [{
|
|
2127
|
+
ref: "asx:Schema",
|
|
2128
|
+
minOccurs: "0",
|
|
2129
|
+
maxOccurs: "unbounded"
|
|
2130
|
+
}] }
|
|
2131
|
+
},
|
|
2132
|
+
{
|
|
2133
|
+
name: "AbapType",
|
|
2134
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2135
|
+
attribute: [{
|
|
2136
|
+
name: "version",
|
|
2137
|
+
type: "xs:string",
|
|
2138
|
+
"default": "1.0"
|
|
2139
|
+
}]
|
|
2140
|
+
}
|
|
2141
|
+
]
|
|
2142
|
+
};
|
|
2143
|
+
|
|
2144
|
+
//#endregion
|
|
2145
|
+
//#region src/schemas/generated/schemas/srvd.ts
|
|
2146
|
+
/**
|
|
2147
|
+
* Auto-generated schema from XSD
|
|
2148
|
+
*
|
|
2149
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2150
|
+
* Source: abapgit/srvd.xsd
|
|
2151
|
+
*/
|
|
2152
|
+
var srvd_default = {
|
|
2153
|
+
$xmlns: {
|
|
2154
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2155
|
+
asx: "http://www.sap.com/abapxml"
|
|
2156
|
+
},
|
|
2157
|
+
elementFormDefault: "unqualified",
|
|
2158
|
+
element: [{
|
|
2159
|
+
name: "abapGit",
|
|
2160
|
+
complexType: {
|
|
2161
|
+
sequence: { element: [{
|
|
2162
|
+
name: "abap",
|
|
2163
|
+
type: "SrvdAbapType"
|
|
2164
|
+
}] },
|
|
2165
|
+
attribute: [
|
|
2166
|
+
{
|
|
2167
|
+
name: "version",
|
|
2168
|
+
type: "xs:string",
|
|
2169
|
+
use: "required"
|
|
2170
|
+
},
|
|
2171
|
+
{
|
|
2172
|
+
name: "serializer",
|
|
2173
|
+
type: "xs:string",
|
|
2174
|
+
use: "required"
|
|
2175
|
+
},
|
|
2176
|
+
{
|
|
2177
|
+
name: "serializer_version",
|
|
2178
|
+
type: "xs:string",
|
|
2179
|
+
use: "required"
|
|
2180
|
+
}
|
|
2181
|
+
]
|
|
2182
|
+
}
|
|
2183
|
+
}, {
|
|
2184
|
+
name: "Schema",
|
|
2185
|
+
abstract: true
|
|
2186
|
+
}],
|
|
2187
|
+
complexType: [
|
|
2188
|
+
{
|
|
2189
|
+
name: "SkeyType",
|
|
2190
|
+
all: { element: [{
|
|
2191
|
+
name: "TYPE",
|
|
2192
|
+
type: "xs:string",
|
|
2193
|
+
minOccurs: "0"
|
|
2194
|
+
}, {
|
|
2195
|
+
name: "NAME",
|
|
2196
|
+
type: "xs:string",
|
|
2197
|
+
minOccurs: "0"
|
|
2198
|
+
}] }
|
|
2199
|
+
},
|
|
2200
|
+
{
|
|
2201
|
+
name: "SrvdValuesType",
|
|
2202
|
+
all: { element: [{
|
|
2203
|
+
name: "SKEY",
|
|
2204
|
+
type: "SkeyType",
|
|
2205
|
+
minOccurs: "0"
|
|
2206
|
+
}] }
|
|
2207
|
+
},
|
|
2208
|
+
{
|
|
2209
|
+
name: "SrvdAbapType",
|
|
2210
|
+
sequence: { element: [{
|
|
2211
|
+
name: "values",
|
|
2212
|
+
type: "SrvdValuesType"
|
|
2213
|
+
}] },
|
|
2214
|
+
attribute: [{
|
|
2215
|
+
name: "version",
|
|
2216
|
+
type: "xs:string",
|
|
2217
|
+
"default": "1.0"
|
|
2218
|
+
}]
|
|
2219
|
+
},
|
|
2220
|
+
{
|
|
2221
|
+
name: "AbapValuesType",
|
|
2222
|
+
sequence: { element: [{
|
|
2223
|
+
ref: "asx:Schema",
|
|
2224
|
+
minOccurs: "0",
|
|
2225
|
+
maxOccurs: "unbounded"
|
|
2226
|
+
}] }
|
|
2227
|
+
},
|
|
2228
|
+
{
|
|
2229
|
+
name: "AbapType",
|
|
2230
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2231
|
+
attribute: [{
|
|
2232
|
+
name: "version",
|
|
2233
|
+
type: "xs:string",
|
|
2234
|
+
"default": "1.0"
|
|
2235
|
+
}]
|
|
2236
|
+
}
|
|
2237
|
+
]
|
|
2238
|
+
};
|
|
2239
|
+
|
|
2240
|
+
//#endregion
|
|
2241
|
+
//#region src/schemas/generated/schemas/srvb.ts
|
|
2242
|
+
/**
|
|
2243
|
+
* Auto-generated schema from XSD
|
|
2244
|
+
*
|
|
2245
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2246
|
+
* Source: abapgit/srvb.xsd
|
|
2247
|
+
*/
|
|
2248
|
+
var srvb_default = {
|
|
2249
|
+
$xmlns: {
|
|
2250
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2251
|
+
asx: "http://www.sap.com/abapxml"
|
|
2252
|
+
},
|
|
2253
|
+
elementFormDefault: "unqualified",
|
|
2254
|
+
element: [{
|
|
2255
|
+
name: "abapGit",
|
|
2256
|
+
complexType: {
|
|
2257
|
+
sequence: { element: [{
|
|
2258
|
+
name: "abap",
|
|
2259
|
+
type: "SrvbAbapType"
|
|
2260
|
+
}] },
|
|
2261
|
+
attribute: [
|
|
2262
|
+
{
|
|
2263
|
+
name: "version",
|
|
2264
|
+
type: "xs:string",
|
|
2265
|
+
use: "required"
|
|
2266
|
+
},
|
|
2267
|
+
{
|
|
2268
|
+
name: "serializer",
|
|
2269
|
+
type: "xs:string",
|
|
2270
|
+
use: "required"
|
|
2271
|
+
},
|
|
2272
|
+
{
|
|
2273
|
+
name: "serializer_version",
|
|
2274
|
+
type: "xs:string",
|
|
2275
|
+
use: "required"
|
|
2276
|
+
}
|
|
2277
|
+
]
|
|
2278
|
+
}
|
|
2279
|
+
}, {
|
|
2280
|
+
name: "Schema",
|
|
2281
|
+
abstract: true
|
|
2282
|
+
}],
|
|
2283
|
+
complexType: [
|
|
2284
|
+
{
|
|
2285
|
+
name: "SkeyType",
|
|
2286
|
+
all: { element: [{
|
|
2287
|
+
name: "TYPE",
|
|
2288
|
+
type: "xs:string",
|
|
2289
|
+
minOccurs: "0"
|
|
2290
|
+
}, {
|
|
2291
|
+
name: "NAME",
|
|
2292
|
+
type: "xs:string",
|
|
2293
|
+
minOccurs: "0"
|
|
2294
|
+
}] }
|
|
2295
|
+
},
|
|
2296
|
+
{
|
|
2297
|
+
name: "BindingType",
|
|
2298
|
+
all: { element: [
|
|
2299
|
+
{
|
|
2300
|
+
name: "TYPE",
|
|
2301
|
+
type: "xs:string",
|
|
2302
|
+
minOccurs: "0"
|
|
2303
|
+
},
|
|
2304
|
+
{
|
|
2305
|
+
name: "VERSION",
|
|
2306
|
+
type: "xs:string",
|
|
2307
|
+
minOccurs: "0"
|
|
2308
|
+
},
|
|
2309
|
+
{
|
|
2310
|
+
name: "CATEGORY",
|
|
2311
|
+
type: "xs:string",
|
|
2312
|
+
minOccurs: "0"
|
|
2313
|
+
}
|
|
2314
|
+
] }
|
|
2315
|
+
},
|
|
2316
|
+
{
|
|
2317
|
+
name: "SrvbValuesType",
|
|
2318
|
+
all: { element: [{
|
|
2319
|
+
name: "SKEY",
|
|
2320
|
+
type: "SkeyType",
|
|
2321
|
+
minOccurs: "0"
|
|
2322
|
+
}, {
|
|
2323
|
+
name: "BINDING",
|
|
2324
|
+
type: "BindingType",
|
|
2325
|
+
minOccurs: "0"
|
|
2326
|
+
}] }
|
|
2327
|
+
},
|
|
2328
|
+
{
|
|
2329
|
+
name: "SrvbAbapType",
|
|
2330
|
+
sequence: { element: [{
|
|
2331
|
+
name: "values",
|
|
2332
|
+
type: "SrvbValuesType"
|
|
2333
|
+
}] },
|
|
2334
|
+
attribute: [{
|
|
2335
|
+
name: "version",
|
|
2336
|
+
type: "xs:string",
|
|
2337
|
+
"default": "1.0"
|
|
2338
|
+
}]
|
|
2339
|
+
},
|
|
2340
|
+
{
|
|
2341
|
+
name: "AbapValuesType",
|
|
2342
|
+
sequence: { element: [{
|
|
2343
|
+
ref: "asx:Schema",
|
|
2344
|
+
minOccurs: "0",
|
|
2345
|
+
maxOccurs: "unbounded"
|
|
2346
|
+
}] }
|
|
2347
|
+
},
|
|
2348
|
+
{
|
|
2349
|
+
name: "AbapType",
|
|
2350
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2351
|
+
attribute: [{
|
|
2352
|
+
name: "version",
|
|
2353
|
+
type: "xs:string",
|
|
2354
|
+
"default": "1.0"
|
|
2355
|
+
}]
|
|
2356
|
+
}
|
|
2357
|
+
]
|
|
2358
|
+
};
|
|
2359
|
+
|
|
2360
|
+
//#endregion
|
|
2361
|
+
//#region src/schemas/generated/index.ts
|
|
2362
|
+
/**
|
|
2363
|
+
* AbapGit Typed Schemas
|
|
2364
|
+
*
|
|
2365
|
+
* Auto-generated by ts-xsd codegen - DO NOT EDIT
|
|
2366
|
+
*
|
|
2367
|
+
* Each schema provides:
|
|
2368
|
+
* - _type: Full AbapGitType (for XML build/parse)
|
|
2369
|
+
* - _values: Inner values type (for handler mapping)
|
|
2370
|
+
* - parse(xml) → fully typed object
|
|
2371
|
+
* - build(data) → XML string
|
|
2372
|
+
* - schema → raw schema literal
|
|
2373
|
+
*/
|
|
2374
|
+
const clas = abapGitSchema(clas_default);
|
|
2375
|
+
const devc = abapGitSchema(devc_default);
|
|
2376
|
+
const doma = abapGitSchema(doma_default);
|
|
2377
|
+
const dtel = abapGitSchema(dtel_default);
|
|
2378
|
+
const intf = abapGitSchema(intf_default);
|
|
2379
|
+
const prog = abapGitSchema(prog_default);
|
|
2380
|
+
const fugr = abapGitSchema(fugr_default);
|
|
2381
|
+
const tabl = abapGitSchema(tabl_default);
|
|
2382
|
+
const ttyp = abapGitSchema(ttyp_default);
|
|
2383
|
+
const bdef = abapGitSchema(bdef_default);
|
|
2384
|
+
const srvd = abapGitSchema(srvd_default);
|
|
2385
|
+
const srvb = abapGitSchema(srvb_default);
|
|
2386
|
+
|
|
2387
|
+
//#endregion
|
|
2388
|
+
//#region src/lib/handlers/lang.ts
|
|
2389
|
+
/**
|
|
2390
|
+
* SAP 1-character language code ↔ ISO 639-1 mapping
|
|
2391
|
+
*
|
|
2392
|
+
* abapGit stores SAP internal 1-char codes (e.g. "E" for English).
|
|
2393
|
+
* SAP ADT REST API expects ISO 639-1 codes (e.g. "EN").
|
|
2394
|
+
*/
|
|
2395
|
+
const SAP_TO_ISO = {
|
|
2396
|
+
E: "EN",
|
|
2397
|
+
D: "DE",
|
|
2398
|
+
F: "FR",
|
|
2399
|
+
I: "IT",
|
|
2400
|
+
S: "ES",
|
|
2401
|
+
P: "PT",
|
|
2402
|
+
J: "JA",
|
|
2403
|
+
K: "KO",
|
|
2404
|
+
"1": "ZH",
|
|
2405
|
+
W: "RU",
|
|
2406
|
+
T: "TR",
|
|
2407
|
+
N: "NL",
|
|
2408
|
+
H: "HU",
|
|
2409
|
+
L: "PL",
|
|
2410
|
+
Q: "CS",
|
|
2411
|
+
R: "SK",
|
|
2412
|
+
U: "SV",
|
|
2413
|
+
V: "DA",
|
|
2414
|
+
Y: "FI",
|
|
2415
|
+
X: "NO",
|
|
2416
|
+
G: "EL",
|
|
2417
|
+
B: "HE",
|
|
2418
|
+
A: "AR",
|
|
2419
|
+
"3": "TH",
|
|
2420
|
+
M: "UK",
|
|
2421
|
+
"6": "HR",
|
|
2422
|
+
O: "SL",
|
|
2423
|
+
"7": "BG",
|
|
2424
|
+
"8": "SR",
|
|
2425
|
+
C: "RO"
|
|
2426
|
+
};
|
|
2427
|
+
const ISO_TO_SAP = Object.fromEntries(Object.entries(SAP_TO_ISO).map(([k, v]) => [v, k]));
|
|
2428
|
+
/**
|
|
2429
|
+
* Convert SAP 1-char language code to ISO 639-1.
|
|
2430
|
+
* Returns the input uppercased if no mapping exists (may already be ISO).
|
|
2431
|
+
*/
|
|
2432
|
+
function sapLangToIso(sapLang) {
|
|
2433
|
+
if (!sapLang) return "EN";
|
|
2434
|
+
const upper = sapLang.toUpperCase();
|
|
2435
|
+
if (upper.length >= 2) return upper;
|
|
2436
|
+
return SAP_TO_ISO[upper] ?? upper;
|
|
2437
|
+
}
|
|
2438
|
+
/**
|
|
2439
|
+
* Convert ISO 639-1 language code to SAP 1-char code.
|
|
2440
|
+
* Returns "E" (English) if no mapping exists.
|
|
2441
|
+
*/
|
|
2442
|
+
function isoToSapLang(isoLang) {
|
|
2443
|
+
if (!isoLang) return "E";
|
|
2444
|
+
const upper = isoLang.toUpperCase();
|
|
2445
|
+
if (upper.length === 1) return upper;
|
|
2446
|
+
return ISO_TO_SAP[upper] ?? "E";
|
|
2447
|
+
}
|
|
2448
|
+
/**
|
|
2449
|
+
* abapGit numeric code → ADT API string value
|
|
2450
|
+
*
|
|
2451
|
+
* abapGit serializes ABAP_LANGUAGE_VERSION as a numeric string (e.g. "5").
|
|
2452
|
+
* SAP ADT REST API expects descriptive strings (e.g. "cloudDevelopment").
|
|
2453
|
+
*/
|
|
2454
|
+
const ABAP_LANG_VER_TO_ADT = {
|
|
2455
|
+
"2": "keyUser",
|
|
2456
|
+
"5": "cloudDevelopment"
|
|
2457
|
+
};
|
|
2458
|
+
const ABAP_LANG_VER_FROM_ADT = Object.fromEntries(Object.entries(ABAP_LANG_VER_TO_ADT).map(([k, v]) => [v, k]));
|
|
2459
|
+
/**
|
|
2460
|
+
* Convert abapGit ABAP_LANGUAGE_VERSION code to ADT API value.
|
|
2461
|
+
* Returns undefined if not set or standard ABAP.
|
|
2462
|
+
* Passes through values that are already in ADT format (e.g. "cloudDevelopment").
|
|
2463
|
+
*/
|
|
2464
|
+
function abapLangVerToAdt(abapGitCode) {
|
|
2465
|
+
if (!abapGitCode) return void 0;
|
|
2466
|
+
return ABAP_LANG_VER_TO_ADT[abapGitCode] ?? abapGitCode;
|
|
2467
|
+
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Convert ADT API abapLanguageVersion to abapGit ABAP_LANGUAGE_VERSION code.
|
|
2470
|
+
* Returns undefined if not set or standard ABAP (default — should not be emitted).
|
|
2471
|
+
*/
|
|
2472
|
+
function abapLangVerFromAdt(adtValue) {
|
|
2473
|
+
if (!adtValue) return void 0;
|
|
2474
|
+
if (adtValue === "standard" || adtValue === "X") return void 0;
|
|
2475
|
+
return ABAP_LANG_VER_FROM_ADT[adtValue] ?? adtValue;
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
//#endregion
|
|
2479
|
+
//#region src/lib/handlers/objects/clas.ts
|
|
2480
|
+
/**
|
|
2481
|
+
* Class (CLAS) object handler for abapGit format
|
|
2482
|
+
*/
|
|
2483
|
+
/**
|
|
2484
|
+
* Map ADK ClassIncludeType to abapGit file suffix convention
|
|
2485
|
+
* Used for serialization (SAP → Git)
|
|
2486
|
+
*/
|
|
2487
|
+
const ABAPGIT_SUFFIX = {
|
|
2488
|
+
main: void 0,
|
|
2489
|
+
definitions: "locals_def",
|
|
2490
|
+
implementations: "locals_imp",
|
|
2491
|
+
localtypes: "locals_types",
|
|
2492
|
+
macros: "macros",
|
|
2493
|
+
testclasses: "testclasses"
|
|
2494
|
+
};
|
|
2495
|
+
/**
|
|
2496
|
+
* Reverse mapping: abapGit file suffix to ADK source key
|
|
2497
|
+
* Derived from ABAPGIT_SUFFIX to avoid duplication
|
|
2498
|
+
*/
|
|
2499
|
+
const SUFFIX_TO_SOURCE_KEY = Object.fromEntries(Object.entries(ABAPGIT_SUFFIX).filter(([, suffix]) => suffix !== void 0).map(([key, suffix]) => [suffix, key]));
|
|
2500
|
+
/**
|
|
2501
|
+
* Map ADT category enum → abapGit numeric code
|
|
2502
|
+
* SAP ADT returns string names, abapGit uses numeric codes from SEOCLASSDF-CATEGORY
|
|
2503
|
+
*/
|
|
2504
|
+
const CATEGORY_FROM_ADT = {
|
|
2505
|
+
generalObjectType: "00",
|
|
2506
|
+
exitClass: "01",
|
|
2507
|
+
testClass: "02",
|
|
2508
|
+
areaClass: "03",
|
|
2509
|
+
factoryClass: "04",
|
|
2510
|
+
persistentClass: "30",
|
|
2511
|
+
exceptionClass: "40",
|
|
2512
|
+
bspClass: "60",
|
|
2513
|
+
staticTypedLcpClass: "70",
|
|
2514
|
+
behaviorPool: "80",
|
|
2515
|
+
rfcProxyClass: "90",
|
|
2516
|
+
entityEventHandler: "100",
|
|
2517
|
+
communicationConnectionClass: "110"
|
|
2518
|
+
};
|
|
2519
|
+
/**
|
|
2520
|
+
* Map visibility to EXPOSURE code (ADK → abapGit)
|
|
2521
|
+
*/
|
|
2522
|
+
const VISIBILITY_TO_EXPOSURE = {
|
|
2523
|
+
private: "0",
|
|
2524
|
+
protected: "1",
|
|
2525
|
+
public: "2"
|
|
2526
|
+
};
|
|
2527
|
+
/**
|
|
2528
|
+
* Reverse mapping: EXPOSURE code to visibility (abapGit → ADK)
|
|
2529
|
+
*/
|
|
2530
|
+
const EXPOSURE_TO_VISIBILITY = Object.fromEntries(Object.entries(VISIBILITY_TO_EXPOSURE).map(([k, v]) => [v, k]));
|
|
2531
|
+
const classHandler = createHandler(AdkClass, {
|
|
2532
|
+
schema: clas,
|
|
2533
|
+
version: "v1.0.0",
|
|
2534
|
+
serializer: "LCL_OBJECT_CLAS",
|
|
2535
|
+
serializer_version: "v1.0.0",
|
|
2536
|
+
suffixToSourceKey: SUFFIX_TO_SOURCE_KEY,
|
|
2537
|
+
toAbapGit: (cls) => {
|
|
2538
|
+
const data = cls.dataSync;
|
|
2539
|
+
const hasTestClasses = (data.include ?? []).some((inc) => String(inc.includeType) === "testclasses") || data.hasTests === true || data.withUnitTests === true;
|
|
2540
|
+
const categoryCode = CATEGORY_FROM_ADT[data.category ?? ""] ?? data.category ?? "00";
|
|
2541
|
+
const exposureCode = VISIBILITY_TO_EXPOSURE[data.visibility ?? "public"] ?? "2";
|
|
2542
|
+
return { VSEOCLASS: {
|
|
2543
|
+
CLSNAME: cls.name ?? "",
|
|
2544
|
+
LANGU: isoToSapLang(data.language),
|
|
2545
|
+
DESCRIPT: data.description ?? "",
|
|
2546
|
+
STATE: "1",
|
|
2547
|
+
CATEGORY: categoryCode !== "00" ? categoryCode : void 0,
|
|
2548
|
+
EXPOSURE: exposureCode !== "2" ? exposureCode : void 0,
|
|
2549
|
+
CLSFINAL: data.final ? "X" : void 0,
|
|
2550
|
+
CLSABSTRCT: data.abstract ? "X" : void 0,
|
|
2551
|
+
SHRM_ENABLED: data.sharedMemoryEnabled ? "X" : void 0,
|
|
2552
|
+
CLSCCINCL: "X",
|
|
2553
|
+
FIXPT: data.fixPointArithmetic ? "X" : void 0,
|
|
2554
|
+
UNICODE: "X",
|
|
2555
|
+
REFCLSNAME: data.superClassRef?.name,
|
|
2556
|
+
MSG_ID: data.messageClassRef?.name,
|
|
2557
|
+
ABAP_LANGUAGE_VERSION: abapLangVerFromAdt(data.abapLanguageVersion),
|
|
2558
|
+
...hasTestClasses ? { WITH_UNIT_TESTS: "X" } : {}
|
|
2559
|
+
} };
|
|
2560
|
+
},
|
|
2561
|
+
getSources: (cls) => {
|
|
2562
|
+
return (cls.dataSync.include ?? []).map((inc) => ({
|
|
2563
|
+
suffix: ABAPGIT_SUFFIX[String(inc.includeType ?? "main")],
|
|
2564
|
+
content: cls.getIncludeSource(String(inc.includeType ?? "main"))
|
|
2565
|
+
}));
|
|
2566
|
+
},
|
|
2567
|
+
fromAbapGit: ({ VSEOCLASS }) => ({
|
|
2568
|
+
name: (VSEOCLASS?.CLSNAME ?? "").toUpperCase(),
|
|
2569
|
+
type: "CLAS/OC",
|
|
2570
|
+
description: VSEOCLASS?.DESCRIPT,
|
|
2571
|
+
language: sapLangToIso(VSEOCLASS?.LANGU),
|
|
2572
|
+
masterLanguage: sapLangToIso(VSEOCLASS?.LANGU),
|
|
2573
|
+
category: VSEOCLASS?.CATEGORY,
|
|
2574
|
+
final: VSEOCLASS?.CLSFINAL === "X",
|
|
2575
|
+
abstract: VSEOCLASS?.CLSABSTRCT === "X",
|
|
2576
|
+
visibility: EXPOSURE_TO_VISIBILITY[VSEOCLASS?.EXPOSURE ?? "2"] ?? "public",
|
|
2577
|
+
sharedMemoryEnabled: VSEOCLASS?.SHRM_ENABLED === "X",
|
|
2578
|
+
fixPointArithmetic: VSEOCLASS?.FIXPT === "X",
|
|
2579
|
+
activeUnicodeCheck: VSEOCLASS?.UNICODE === "X",
|
|
2580
|
+
withUnitTests: VSEOCLASS?.WITH_UNIT_TESTS === "X",
|
|
2581
|
+
superClassRef: VSEOCLASS?.REFCLSNAME ? { name: VSEOCLASS.REFCLSNAME } : void 0,
|
|
2582
|
+
messageClassRef: VSEOCLASS?.MSG_ID ? { name: VSEOCLASS.MSG_ID } : void 0,
|
|
2583
|
+
abapLanguageVersion: abapLangVerToAdt(VSEOCLASS?.ABAP_LANGUAGE_VERSION)
|
|
2584
|
+
}),
|
|
2585
|
+
setSources: (cls, sources) => {
|
|
2586
|
+
cls._pendingSources = sources;
|
|
2587
|
+
if (sources.main) cls._pendingSource = sources.main;
|
|
2588
|
+
}
|
|
2589
|
+
});
|
|
2590
|
+
|
|
2591
|
+
//#endregion
|
|
2592
|
+
//#region src/lib/handlers/objects/intf.ts
|
|
2593
|
+
/**
|
|
2594
|
+
* Interface (INTF) object handler for abapGit format
|
|
2595
|
+
*/
|
|
2596
|
+
const interfaceHandler = createHandler(AdkInterface, {
|
|
2597
|
+
schema: intf,
|
|
2598
|
+
version: "v1.0.0",
|
|
2599
|
+
serializer: "LCL_OBJECT_INTF",
|
|
2600
|
+
serializer_version: "v1.0.0",
|
|
2601
|
+
toAbapGit: (obj) => ({ VSEOINTERF: {
|
|
2602
|
+
CLSNAME: obj.name ?? "",
|
|
2603
|
+
LANGU: isoToSapLang(obj.dataSync?.language),
|
|
2604
|
+
DESCRIPT: obj.description ?? "",
|
|
2605
|
+
EXPOSURE: "2",
|
|
2606
|
+
STATE: "1",
|
|
2607
|
+
UNICODE: "X"
|
|
2608
|
+
} }),
|
|
2609
|
+
getSource: (obj) => obj.getSource(),
|
|
2610
|
+
fromAbapGit: ({ VSEOINTERF }) => ({
|
|
2611
|
+
name: (VSEOINTERF?.CLSNAME ?? "").toUpperCase(),
|
|
2612
|
+
type: "INTF/OI",
|
|
2613
|
+
description: VSEOINTERF?.DESCRIPT,
|
|
2614
|
+
language: sapLangToIso(VSEOINTERF?.LANGU),
|
|
2615
|
+
masterLanguage: sapLangToIso(VSEOINTERF?.LANGU),
|
|
2616
|
+
abapLanguageVersion: abapLangVerToAdt(VSEOINTERF?.ABAP_LANGUAGE_VERSION)
|
|
2617
|
+
}),
|
|
2618
|
+
setSources: (intf, sources) => {
|
|
2619
|
+
if (sources.main) intf._pendingSource = sources.main;
|
|
2620
|
+
}
|
|
2621
|
+
});
|
|
2622
|
+
|
|
2623
|
+
//#endregion
|
|
2624
|
+
//#region src/lib/handlers/objects/devc.ts
|
|
2625
|
+
/**
|
|
2626
|
+
* Package (DEVC) object handler for abapGit format
|
|
2627
|
+
*/
|
|
2628
|
+
/**
|
|
2629
|
+
* Package handler for abapGit serialization
|
|
2630
|
+
*
|
|
2631
|
+
* Note: Packages in abapGit use "package.devc.xml" as filename,
|
|
2632
|
+
* not "$packagename.devc.xml"
|
|
2633
|
+
*/
|
|
2634
|
+
const packageHandler = createHandler(AdkPackage, {
|
|
2635
|
+
schema: devc,
|
|
2636
|
+
version: "v1.0.0",
|
|
2637
|
+
serializer: "LCL_OBJECT_DEVC",
|
|
2638
|
+
serializer_version: "v1.0.0",
|
|
2639
|
+
xmlFileName: "package.devc.xml",
|
|
2640
|
+
toAbapGit: (pkg) => ({ DEVC: { CTEXT: pkg.description ?? "" } }),
|
|
2641
|
+
fromAbapGit: ({ DEVC }) => ({
|
|
2642
|
+
name: "",
|
|
2643
|
+
description: DEVC?.CTEXT
|
|
2644
|
+
})
|
|
2645
|
+
});
|
|
2646
|
+
|
|
2647
|
+
//#endregion
|
|
2648
|
+
//#region src/lib/handlers/objects/prog.ts
|
|
2649
|
+
/**
|
|
2650
|
+
* Program (PROG) object handler for abapGit format
|
|
2651
|
+
*/
|
|
2652
|
+
const programHandler = createHandler(AdkProgram, {
|
|
2653
|
+
schema: prog,
|
|
2654
|
+
version: "v1.0.0",
|
|
2655
|
+
serializer: "LCL_OBJECT_PROG",
|
|
2656
|
+
serializer_version: "v1.0.0",
|
|
2657
|
+
toAbapGit: (obj) => ({ PROGDIR: {
|
|
2658
|
+
NAME: obj.name ?? "",
|
|
2659
|
+
STATE: "A",
|
|
2660
|
+
SUBC: "1",
|
|
2661
|
+
FIXPT: "X",
|
|
2662
|
+
UNICODE: "X"
|
|
2663
|
+
} }),
|
|
2664
|
+
getSource: (obj) => obj.getSource(),
|
|
2665
|
+
fromAbapGit: ({ PROGDIR, TPOOL }) => {
|
|
2666
|
+
const rawItems = TPOOL?.item ?? [];
|
|
2667
|
+
const descriptionEntry = (Array.isArray(rawItems) ? rawItems : [rawItems]).find((t) => t.ID === "R");
|
|
2668
|
+
const subc = String(PROGDIR?.SUBC ?? "");
|
|
2669
|
+
return {
|
|
2670
|
+
name: (PROGDIR?.NAME ?? "").toUpperCase(),
|
|
2671
|
+
type: "PROG/P",
|
|
2672
|
+
description: descriptionEntry?.ENTRY ?? "Program",
|
|
2673
|
+
fixPointArithmetic: PROGDIR?.FIXPT === "X",
|
|
2674
|
+
activeUnicodeCheck: PROGDIR?.UNICODE === "X",
|
|
2675
|
+
programType: subc === "1" ? "executableProgram" : "subroutinePool"
|
|
2676
|
+
};
|
|
2677
|
+
},
|
|
2678
|
+
setSources: (obj, sources) => {
|
|
2679
|
+
if (sources.main) obj._pendingSource = sources.main;
|
|
2680
|
+
}
|
|
2681
|
+
});
|
|
2682
|
+
|
|
2683
|
+
//#endregion
|
|
2684
|
+
//#region src/lib/handlers/objects/fugr.ts
|
|
2685
|
+
/**
|
|
2686
|
+
* Function Group (FUGR) object handler for abapGit format
|
|
2687
|
+
*
|
|
2688
|
+
* FUGR is a compound object — abapGit serializes it as multiple files:
|
|
2689
|
+
* {name}.fugr.xml — Main metadata (AREAT + INCLUDES + FUNCTIONS)
|
|
2690
|
+
* {name}.fugr.l{name}top.abap — TOP-include source (editable)
|
|
2691
|
+
* {name}.fugr.l{name}top.xml — TOP-include PROGDIR metadata
|
|
2692
|
+
* {name}.fugr.sapl{name}.abap — Main program source (system-generated)
|
|
2693
|
+
* {name}.fugr.sapl{name}.xml — Main program PROGDIR metadata
|
|
2694
|
+
* {name}.fugr.{funcname}.abap — Function module source (per FM)
|
|
2695
|
+
*
|
|
2696
|
+
* Note: FM metadata is stored INSIDE the main XML under <FUNCTIONS>,
|
|
2697
|
+
* NOT in separate per-FM XML files (that's how abapGit works).
|
|
2698
|
+
*/
|
|
2699
|
+
/**
|
|
2700
|
+
* Map ADT processingType to abapGit REMOTE_CALL flag
|
|
2701
|
+
*/
|
|
2702
|
+
function processingTypeToRemoteCall(processingType) {
|
|
2703
|
+
switch (processingType) {
|
|
2704
|
+
case "rfc": return "R";
|
|
2705
|
+
case "update": return;
|
|
2706
|
+
default: return;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
/**
|
|
2710
|
+
* Map abapGit REMOTE_CALL flag to ADT processingType
|
|
2711
|
+
*/
|
|
2712
|
+
function remoteCallToProcessingType(remoteCall, updateTask) {
|
|
2713
|
+
if (remoteCall === "R") return "rfc";
|
|
2714
|
+
if (updateTask && updateTask !== "" && updateTask !== " ") return "update";
|
|
2715
|
+
return "normal";
|
|
2716
|
+
}
|
|
2717
|
+
const functionGroupHandler = createHandler(AdkFunctionGroup, {
|
|
2718
|
+
schema: fugr,
|
|
2719
|
+
version: "v1.0.0",
|
|
2720
|
+
serializer: "LCL_OBJECT_FUGR",
|
|
2721
|
+
serializer_version: "v1.0.0",
|
|
2722
|
+
toAbapGit: (obj) => {
|
|
2723
|
+
const name = obj.name.toUpperCase();
|
|
2724
|
+
return {
|
|
2725
|
+
AREAT: obj.description ?? "",
|
|
2726
|
+
INCLUDES: { SOBJ_NAME: [`L${name}TOP`, `SAPL${name}`] }
|
|
2727
|
+
};
|
|
2728
|
+
},
|
|
2729
|
+
serialize: async (obj, ctx) => {
|
|
2730
|
+
const objectName = ctx.getObjectName(obj);
|
|
2731
|
+
const nameUpper = obj.name.toUpperCase();
|
|
2732
|
+
const files = [];
|
|
2733
|
+
const fmItems = await discoverFunctionModules(obj);
|
|
2734
|
+
const functions = await serializeFunctions(obj, fmItems);
|
|
2735
|
+
const values = {
|
|
2736
|
+
AREAT: obj.description ?? "",
|
|
2737
|
+
INCLUDES: { SOBJ_NAME: [`L${nameUpper}TOP`, `SAPL${nameUpper}`] }
|
|
2738
|
+
};
|
|
2739
|
+
if (functions.length > 0) values.FUNCTIONS = { item: functions };
|
|
2740
|
+
const fullPayload = { abapGit: {
|
|
2741
|
+
abap: {
|
|
2742
|
+
version: "1.0",
|
|
2743
|
+
values
|
|
2744
|
+
},
|
|
2745
|
+
version: "v1.0.0",
|
|
2746
|
+
serializer: "LCL_OBJECT_FUGR",
|
|
2747
|
+
serializer_version: "v1.0.0"
|
|
2748
|
+
} };
|
|
2749
|
+
let xmlContent = fugr.build(fullPayload, { pretty: true });
|
|
2750
|
+
xmlContent = formatAbapGitXml(xmlContent);
|
|
2751
|
+
files.push(ctx.createFile(`${objectName}.fugr.xml`, xmlContent));
|
|
2752
|
+
try {
|
|
2753
|
+
const topSource = await obj.getSource();
|
|
2754
|
+
if (topSource) files.push(ctx.createFile(`${objectName}.fugr.l${objectName}top.abap`, topSource));
|
|
2755
|
+
} catch {}
|
|
2756
|
+
const fixpt = ctx.getData(obj).fixPointArithmetic ? "X" : "";
|
|
2757
|
+
files.push(ctx.createFile(`${objectName}.fugr.l${objectName}top.xml`, buildProgdirXml(`L${nameUpper}TOP`, "I", fixpt)));
|
|
2758
|
+
files.push(ctx.createFile(`${objectName}.fugr.sapl${objectName}.abap`, buildMainProgramSource(nameUpper)), ctx.createFile(`${objectName}.fugr.sapl${objectName}.xml`, buildProgdirXml(`SAPL${nameUpper}`, "F", fixpt)));
|
|
2759
|
+
for (const fm of fmItems) {
|
|
2760
|
+
const funcName = fm.name.toLowerCase();
|
|
2761
|
+
try {
|
|
2762
|
+
const source = await obj.client.adt.functions.groups.fmodules.source.main.get(obj.name, fm.name);
|
|
2763
|
+
if (source) files.push(ctx.createFile(`${objectName}.fugr.${funcName}.abap`, source));
|
|
2764
|
+
} catch {}
|
|
2765
|
+
}
|
|
2766
|
+
return files;
|
|
2767
|
+
},
|
|
2768
|
+
fromAbapGit: ({ AREAT, FUNCTIONS }) => ({
|
|
2769
|
+
name: "",
|
|
2770
|
+
type: "FUGR/F",
|
|
2771
|
+
description: AREAT,
|
|
2772
|
+
language: "EN",
|
|
2773
|
+
masterLanguage: "EN",
|
|
2774
|
+
_functions: FUNCTIONS
|
|
2775
|
+
}),
|
|
2776
|
+
setSources: (obj, sources) => {
|
|
2777
|
+
const name = obj.name.toLowerCase();
|
|
2778
|
+
const topKey = `l${name}top`;
|
|
2779
|
+
const mainSource = sources.main ?? sources[topKey];
|
|
2780
|
+
if (mainSource) obj._pendingSource = mainSource;
|
|
2781
|
+
const fmSources = {};
|
|
2782
|
+
for (const [suffix, content] of Object.entries(sources)) {
|
|
2783
|
+
if (suffix === "main" || suffix === topKey || suffix.startsWith(`l${name}`) || suffix.startsWith(`sapl${name}`)) continue;
|
|
2784
|
+
fmSources[suffix] = content;
|
|
2785
|
+
}
|
|
2786
|
+
if (Object.keys(fmSources).length > 0) obj._pendingFmSources = fmSources;
|
|
2787
|
+
}
|
|
2788
|
+
});
|
|
2789
|
+
/**
|
|
2790
|
+
* Discover child function modules via object structure endpoint.
|
|
2791
|
+
* Falls back to empty list if the endpoint is unavailable.
|
|
2792
|
+
*/
|
|
2793
|
+
async function discoverFunctionModules(obj) {
|
|
2794
|
+
try {
|
|
2795
|
+
const response = await obj.client.adt.functions.groups.objectstructure(obj.name);
|
|
2796
|
+
const responseStr = String(response);
|
|
2797
|
+
const fmNames = [];
|
|
2798
|
+
const regex = /type="FUGR\/FF"[^>]*adtcore:name="([^"]+)"/g;
|
|
2799
|
+
let match;
|
|
2800
|
+
while ((match = regex.exec(responseStr)) !== null) fmNames.push({ name: match[1] });
|
|
2801
|
+
const regex2 = /adtcore:name="([^"]+)"[^>]*type="FUGR\/FF"/g;
|
|
2802
|
+
while ((match = regex2.exec(responseStr)) !== null) if (!fmNames.some((f) => f.name === match[1])) fmNames.push({ name: match[1] });
|
|
2803
|
+
return fmNames;
|
|
2804
|
+
} catch {
|
|
2805
|
+
return [];
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
/**
|
|
2809
|
+
* Serialize function module metadata into abapGit FUNCTIONS format.
|
|
2810
|
+
* Fetches each FM's metadata via the ADT fmodules contract.
|
|
2811
|
+
*/
|
|
2812
|
+
async function serializeFunctions(obj, fmItems) {
|
|
2813
|
+
const functions = [];
|
|
2814
|
+
for (const fm of fmItems) try {
|
|
2815
|
+
const fmData = (await obj.client.adt.functions.groups.fmodules.get(obj.name, fm.name))?.abapFunctionModule;
|
|
2816
|
+
if (!fmData) continue;
|
|
2817
|
+
const item = {
|
|
2818
|
+
FUNCNAME: fm.name.toUpperCase(),
|
|
2819
|
+
SHORT_TEXT: fmData.description ?? ""
|
|
2820
|
+
};
|
|
2821
|
+
const remoteCall = processingTypeToRemoteCall(fmData.processingType);
|
|
2822
|
+
if (remoteCall) item.REMOTE_CALL = remoteCall;
|
|
2823
|
+
if (fmData.basXMLEnabled) item.REMOTE_BASXML = "X";
|
|
2824
|
+
functions.push(item);
|
|
2825
|
+
} catch {
|
|
2826
|
+
functions.push({ FUNCNAME: fm.name.toUpperCase() });
|
|
2827
|
+
}
|
|
2828
|
+
return functions;
|
|
2829
|
+
}
|
|
2830
|
+
function extractFunctionDescriptors(functions) {
|
|
2831
|
+
if (!functions) return [];
|
|
2832
|
+
return (Array.isArray(functions) ? functions : Array.isArray(functions?.item) ? functions.item : functions?.item ? [functions.item] : []).map((fm) => ({
|
|
2833
|
+
funcName: String(fm.FUNCNAME ?? ""),
|
|
2834
|
+
shortText: fm.SHORT_TEXT ? String(fm.SHORT_TEXT) : void 0,
|
|
2835
|
+
processingType: remoteCallToProcessingType(fm.REMOTE_CALL, fm.UPDATE_TASK),
|
|
2836
|
+
basXMLEnabled: fm.REMOTE_BASXML === "X"
|
|
2837
|
+
}));
|
|
2838
|
+
}
|
|
2839
|
+
/**
|
|
2840
|
+
* Build PROGDIR XML for an include program (best-effort defaults).
|
|
2841
|
+
* PROGDIR is SAP-internal metadata that abapGit stores but ADT doesn't expose.
|
|
2842
|
+
*/
|
|
2843
|
+
function buildProgdirXml(programName, subc, fixpt) {
|
|
2844
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
2845
|
+
<abapGit version="v1.0.0">
|
|
2846
|
+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
2847
|
+
<asx:values>
|
|
2848
|
+
<PROGDIR>
|
|
2849
|
+
<NAME>${programName}</NAME>
|
|
2850
|
+
<SUBC>${subc}</SUBC>${subc === "F" ? "\n <RLOAD>E</RLOAD>" : ""}
|
|
2851
|
+
<FIXPT>${fixpt}</FIXPT>
|
|
2852
|
+
<UCCHECK>X</UCCHECK>
|
|
2853
|
+
</PROGDIR>
|
|
2854
|
+
</asx:values>
|
|
2855
|
+
</asx:abap>
|
|
2856
|
+
</abapGit>
|
|
2857
|
+
`;
|
|
2858
|
+
}
|
|
2859
|
+
/**
|
|
2860
|
+
* Build the standard main program source (SAPL{NAME}).
|
|
2861
|
+
* This is system-generated and contains INCLUDE declarations.
|
|
2862
|
+
*/
|
|
2863
|
+
function buildMainProgramSource(nameUpper) {
|
|
2864
|
+
return `*******************************************************************
|
|
2865
|
+
* System-defined Include-files. *
|
|
2866
|
+
*******************************************************************
|
|
2867
|
+
INCLUDE L${nameUpper}TOP. " Global Declarations
|
|
2868
|
+
INCLUDE L${nameUpper}UXX. " Function Modules
|
|
2869
|
+
|
|
2870
|
+
*******************************************************************
|
|
2871
|
+
* User-defined Include-files (if necessary). *
|
|
2872
|
+
*******************************************************************
|
|
2873
|
+
* INCLUDE L${nameUpper}F... " Subroutines
|
|
2874
|
+
* INCLUDE L${nameUpper}O... " PBO-Modules
|
|
2875
|
+
* INCLUDE L${nameUpper}I... " PAI-Modules
|
|
2876
|
+
* INCLUDE L${nameUpper}E... " Events
|
|
2877
|
+
* INCLUDE L${nameUpper}P... " Local class implement.
|
|
2878
|
+
* INCLUDE L${nameUpper}T99. " ABAP Unit tests
|
|
2879
|
+
`;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
//#endregion
|
|
2883
|
+
//#region src/lib/handlers/objects/doma.ts
|
|
2884
|
+
/**
|
|
2885
|
+
* Domain (DOMA) object handler for abapGit format
|
|
2886
|
+
*/
|
|
2887
|
+
const domainHandler = createHandler(AdkDomain, {
|
|
2888
|
+
schema: doma,
|
|
2889
|
+
version: "v1.0.0",
|
|
2890
|
+
serializer: "LCL_OBJECT_DOMA",
|
|
2891
|
+
serializer_version: "v1.0.0",
|
|
2892
|
+
toAbapGit: (obj) => {
|
|
2893
|
+
const data = obj.dataSync;
|
|
2894
|
+
const typeInfo = data?.content?.typeInformation;
|
|
2895
|
+
const outInfo = data?.content?.outputInformation;
|
|
2896
|
+
const valueInfo = data?.content?.valueInformation;
|
|
2897
|
+
const fixValues = valueInfo?.fixValues?.fixValue;
|
|
2898
|
+
const DD07V_TAB = fixValues && fixValues.length > 0 ? { DD07V: fixValues.map((fv) => {
|
|
2899
|
+
const entry = {
|
|
2900
|
+
DOMNAME: obj.name ?? "",
|
|
2901
|
+
VALPOS: String(fv.position ?? "").padStart(4, "0"),
|
|
2902
|
+
DDLANGUAGE: isoToSapLang(data?.language),
|
|
2903
|
+
DOMVALUE_L: fv.low ?? "",
|
|
2904
|
+
DDTEXT: fv.text ?? ""
|
|
2905
|
+
};
|
|
2906
|
+
if (fv.high) entry.DOMVALUE_H = fv.high;
|
|
2907
|
+
return entry;
|
|
2908
|
+
}) } : void 0;
|
|
2909
|
+
return {
|
|
2910
|
+
DD01V: {
|
|
2911
|
+
DOMNAME: obj.name ?? "",
|
|
2912
|
+
DDLANGUAGE: isoToSapLang(data?.language),
|
|
2913
|
+
DATATYPE: typeInfo?.datatype ?? "",
|
|
2914
|
+
LENG: String(typeInfo?.length ?? "").padStart(6, "0"),
|
|
2915
|
+
DECIMALS: typeInfo?.decimals ? String(typeInfo.decimals).padStart(6, "0") : void 0,
|
|
2916
|
+
OUTPUTLEN: String(outInfo?.length ?? "").padStart(6, "0"),
|
|
2917
|
+
LOWERCASE: outInfo?.lowercase ? "X" : void 0,
|
|
2918
|
+
SIGNFLAG: outInfo?.signExists ? "X" : void 0,
|
|
2919
|
+
CONVEXIT: outInfo?.conversionExit || void 0,
|
|
2920
|
+
ENTITYTAB: valueInfo?.valueTableRef?.name || void 0,
|
|
2921
|
+
VALEXI: fixValues && fixValues.length > 0 ? "X" : void 0,
|
|
2922
|
+
DDTEXT: obj.description ?? "",
|
|
2923
|
+
DOMMASTER: isoToSapLang(obj.masterLanguage)
|
|
2924
|
+
},
|
|
2925
|
+
DD07V_TAB
|
|
2926
|
+
};
|
|
2927
|
+
},
|
|
2928
|
+
fromAbapGit: ({ DD01V, DD07V_TAB }) => {
|
|
2929
|
+
const fixValues = DD07V_TAB?.DD07V?.map((fv, idx) => ({
|
|
2930
|
+
position: Number(fv.VALPOS ?? idx + 1),
|
|
2931
|
+
low: fv.DOMVALUE_L ?? "",
|
|
2932
|
+
high: fv.DOMVALUE_H ?? "",
|
|
2933
|
+
text: fv.DDTEXT ?? ""
|
|
2934
|
+
})) ?? [];
|
|
2935
|
+
return {
|
|
2936
|
+
name: (DD01V?.DOMNAME ?? "").toUpperCase(),
|
|
2937
|
+
type: "DOMA/DD",
|
|
2938
|
+
description: DD01V?.DDTEXT,
|
|
2939
|
+
language: sapLangToIso(DD01V?.DDLANGUAGE),
|
|
2940
|
+
masterLanguage: sapLangToIso(DD01V?.DDLANGUAGE),
|
|
2941
|
+
content: {
|
|
2942
|
+
typeInformation: {
|
|
2943
|
+
datatype: DD01V?.DATATYPE ?? "",
|
|
2944
|
+
length: Number(DD01V?.LENG ?? 0),
|
|
2945
|
+
decimals: Number(DD01V?.DECIMALS ?? 0)
|
|
2946
|
+
},
|
|
2947
|
+
outputInformation: {
|
|
2948
|
+
length: Number(DD01V?.OUTPUTLEN ?? 0),
|
|
2949
|
+
style: "",
|
|
2950
|
+
conversionExit: DD01V?.CONVEXIT || void 0,
|
|
2951
|
+
signExists: DD01V?.SIGNFLAG === "X",
|
|
2952
|
+
lowercase: DD01V?.LOWERCASE === "X"
|
|
2953
|
+
},
|
|
2954
|
+
valueInformation: {
|
|
2955
|
+
valueTableRef: { name: DD01V?.ENTITYTAB || void 0 },
|
|
2956
|
+
fixValues: { fixValue: fixValues.length > 0 ? fixValues : void 0 }
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
};
|
|
2960
|
+
}
|
|
2961
|
+
});
|
|
2962
|
+
|
|
2963
|
+
//#endregion
|
|
2964
|
+
//#region src/lib/handlers/objects/dtel.ts
|
|
2965
|
+
/**
|
|
2966
|
+
* Data Element (DTEL) object handler for abapGit format
|
|
2967
|
+
*/
|
|
2968
|
+
/**
|
|
2969
|
+
* Map ADT typeKind → abapGit REFKIND
|
|
2970
|
+
*/
|
|
2971
|
+
const TYPEKIND_TO_REFKIND = {
|
|
2972
|
+
domain: "D",
|
|
2973
|
+
predefinedAbapType: "",
|
|
2974
|
+
refToPredefinedAbapType: "R",
|
|
2975
|
+
refToDictionaryType: "R",
|
|
2976
|
+
refToClifType: "R"
|
|
2977
|
+
};
|
|
2978
|
+
/**
|
|
2979
|
+
* Map ADT typeKind → abapGit REFTYPE (only for reference types)
|
|
2980
|
+
*/
|
|
2981
|
+
const TYPEKIND_TO_REFTYPE = {
|
|
2982
|
+
refToClifType: "C",
|
|
2983
|
+
refToDictionaryType: "E",
|
|
2984
|
+
refToPredefinedAbapType: "E"
|
|
2985
|
+
};
|
|
2986
|
+
/**
|
|
2987
|
+
* Derive OUTPUTLEN from ABAP data type + length + decimals.
|
|
2988
|
+
*
|
|
2989
|
+
* The ADT REST API for data elements does not return OUTPUTLEN — SAP derives
|
|
2990
|
+
* it internally from the type definition. This function replicates SAP's
|
|
2991
|
+
* output length calculation for standard ABAP dictionary types.
|
|
2992
|
+
*/
|
|
2993
|
+
function deriveOutputLength(dataType, length, decimals) {
|
|
2994
|
+
if (!dataType || !length) return void 0;
|
|
2995
|
+
const type = dataType.toUpperCase();
|
|
2996
|
+
const len = length;
|
|
2997
|
+
const dec = decimals ?? 0;
|
|
2998
|
+
switch (type) {
|
|
2999
|
+
case "CHAR":
|
|
3000
|
+
case "NUMC":
|
|
3001
|
+
case "UNIT":
|
|
3002
|
+
case "CUKY":
|
|
3003
|
+
case "LCHR":
|
|
3004
|
+
case "SSTRING": return String(len).padStart(6, "0");
|
|
3005
|
+
case "CLNT": return "000003";
|
|
3006
|
+
case "LANG": return "000001";
|
|
3007
|
+
case "DATS": return "000010";
|
|
3008
|
+
case "TIMS": return "000008";
|
|
3009
|
+
case "INT1": return "000003";
|
|
3010
|
+
case "INT2": return "000005";
|
|
3011
|
+
case "INT4": return "000010";
|
|
3012
|
+
case "INT8": return "000019";
|
|
3013
|
+
case "FLTP": return "000022";
|
|
3014
|
+
case "DEC":
|
|
3015
|
+
case "CURR":
|
|
3016
|
+
case "QUAN": {
|
|
3017
|
+
const intDigits = len - dec;
|
|
3018
|
+
const separators = intDigits > 1 ? Math.floor((intDigits - 1) / 3) : 0;
|
|
3019
|
+
const outputLen = len + 1 + separators;
|
|
3020
|
+
return String(outputLen).padStart(6, "0");
|
|
3021
|
+
}
|
|
3022
|
+
case "RAW":
|
|
3023
|
+
case "LRAW": return String(len * 2).padStart(6, "0");
|
|
3024
|
+
case "STRING":
|
|
3025
|
+
case "RAWSTRING":
|
|
3026
|
+
case "GEOM_EWKB": return;
|
|
3027
|
+
default: return;
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
const dataElementHandler = createHandler(AdkDataElement, {
|
|
3031
|
+
schema: dtel,
|
|
3032
|
+
version: "v1.0.0",
|
|
3033
|
+
serializer: "LCL_OBJECT_DTEL",
|
|
3034
|
+
serializer_version: "v1.0.0",
|
|
3035
|
+
toAbapGit: (obj) => {
|
|
3036
|
+
const data = obj.dataSync;
|
|
3037
|
+
const de = data?.dataElement;
|
|
3038
|
+
const typeKind = de?.typeKind ?? "";
|
|
3039
|
+
const isDomain = typeKind === "domain";
|
|
3040
|
+
const dataType = typeKind.startsWith("refTo") ? "REF" : de?.dataType || void 0;
|
|
3041
|
+
const effectiveDataType = isDomain ? void 0 : dataType;
|
|
3042
|
+
const effectiveLeng = isDomain || !de?.dataTypeLength ? void 0 : String(de.dataTypeLength).padStart(6, "0");
|
|
3043
|
+
const effectiveDecimals = isDomain || !de?.dataTypeDecimals ? void 0 : String(de.dataTypeDecimals).padStart(6, "0");
|
|
3044
|
+
const effectiveOutputLen = isDomain ? void 0 : deriveOutputLength(de?.dataType, de?.dataTypeLength, de?.dataTypeDecimals);
|
|
3045
|
+
return { DD04V: {
|
|
3046
|
+
ROLLNAME: obj.name ?? "",
|
|
3047
|
+
DDLANGUAGE: isoToSapLang(obj.language || void 0),
|
|
3048
|
+
DOMNAME: de?.typeName || void 0,
|
|
3049
|
+
HEADLEN: de?.headingFieldLength ? String(de.headingFieldLength) : void 0,
|
|
3050
|
+
SCRLEN1: de?.shortFieldLength ? String(de.shortFieldLength) : void 0,
|
|
3051
|
+
SCRLEN2: de?.mediumFieldLength ? String(de.mediumFieldLength) : void 0,
|
|
3052
|
+
SCRLEN3: de?.longFieldLength ? String(de.longFieldLength) : void 0,
|
|
3053
|
+
DDTEXT: obj.description ?? "",
|
|
3054
|
+
REPTEXT: de?.headingFieldLabel || void 0,
|
|
3055
|
+
SCRTEXT_S: de?.shortFieldLabel || void 0,
|
|
3056
|
+
SCRTEXT_M: de?.mediumFieldLabel || void 0,
|
|
3057
|
+
SCRTEXT_L: de?.longFieldLabel || void 0,
|
|
3058
|
+
DTELMASTER: isoToSapLang(obj.masterLanguage || void 0),
|
|
3059
|
+
DATATYPE: effectiveDataType,
|
|
3060
|
+
LENG: effectiveLeng,
|
|
3061
|
+
DECIMALS: effectiveDecimals,
|
|
3062
|
+
OUTPUTLEN: effectiveOutputLen,
|
|
3063
|
+
REFKIND: TYPEKIND_TO_REFKIND[typeKind] || void 0,
|
|
3064
|
+
REFTYPE: TYPEKIND_TO_REFTYPE[typeKind],
|
|
3065
|
+
ABAP_LANGUAGE_VERSION: abapLangVerFromAdt(data?.abapLanguageVersion)
|
|
3066
|
+
} };
|
|
3067
|
+
},
|
|
3068
|
+
fromAbapGit: ({ DD04V }) => {
|
|
3069
|
+
const refKind = DD04V?.REFKIND ?? "";
|
|
3070
|
+
const refType = DD04V?.REFTYPE ?? "";
|
|
3071
|
+
let typeKind;
|
|
3072
|
+
if (refKind === "D") typeKind = "domain";
|
|
3073
|
+
else if (refKind === "R") typeKind = refType === "C" ? "refToClifType" : "refToDictionaryType";
|
|
3074
|
+
else typeKind = DD04V?.DATATYPE ? "predefinedAbapType" : "domain";
|
|
3075
|
+
return {
|
|
3076
|
+
name: (DD04V?.ROLLNAME ?? "").toUpperCase(),
|
|
3077
|
+
type: "DTEL/DE",
|
|
3078
|
+
description: DD04V?.DDTEXT,
|
|
3079
|
+
language: sapLangToIso(DD04V?.DDLANGUAGE),
|
|
3080
|
+
masterLanguage: sapLangToIso(DD04V?.DDLANGUAGE),
|
|
3081
|
+
abapLanguageVersion: abapLangVerToAdt(DD04V?.ABAP_LANGUAGE_VERSION),
|
|
3082
|
+
dataElement: {
|
|
3083
|
+
typeKind,
|
|
3084
|
+
typeName: DD04V?.DOMNAME || "",
|
|
3085
|
+
dataType: DD04V?.DATATYPE || "",
|
|
3086
|
+
dataTypeLength: DD04V?.LENG ? Number(DD04V.LENG) : 0,
|
|
3087
|
+
dataTypeLengthEnabled: false,
|
|
3088
|
+
dataTypeDecimals: DD04V?.DECIMALS ? Number(DD04V.DECIMALS) : 0,
|
|
3089
|
+
dataTypeDecimalsEnabled: false,
|
|
3090
|
+
shortFieldLabel: DD04V?.SCRTEXT_S || "",
|
|
3091
|
+
shortFieldLength: DD04V?.SCRLEN1 ? Number(DD04V.SCRLEN1) : 0,
|
|
3092
|
+
shortFieldMaxLength: DD04V?.SCRLEN1 ? Number(DD04V.SCRLEN1) : 0,
|
|
3093
|
+
mediumFieldLabel: DD04V?.SCRTEXT_M || "",
|
|
3094
|
+
mediumFieldLength: DD04V?.SCRLEN2 ? Number(DD04V.SCRLEN2) : 0,
|
|
3095
|
+
mediumFieldMaxLength: DD04V?.SCRLEN2 ? Number(DD04V.SCRLEN2) : 0,
|
|
3096
|
+
longFieldLabel: DD04V?.SCRTEXT_L || "",
|
|
3097
|
+
longFieldLength: DD04V?.SCRLEN3 ? Number(DD04V.SCRLEN3) : 0,
|
|
3098
|
+
longFieldMaxLength: DD04V?.SCRLEN3 ? Number(DD04V.SCRLEN3) : 0,
|
|
3099
|
+
headingFieldLabel: DD04V?.REPTEXT || "",
|
|
3100
|
+
headingFieldLength: DD04V?.HEADLEN ? Number(DD04V.HEADLEN) : 0,
|
|
3101
|
+
headingFieldMaxLength: DD04V?.HEADLEN ? Number(DD04V.HEADLEN) : 0,
|
|
3102
|
+
searchHelp: "",
|
|
3103
|
+
searchHelpParameter: "",
|
|
3104
|
+
setGetParameter: "",
|
|
3105
|
+
defaultComponentName: "",
|
|
3106
|
+
deactivateInputHistory: false,
|
|
3107
|
+
changeDocument: false,
|
|
3108
|
+
leftToRightDirection: false,
|
|
3109
|
+
deactivateBIDIFiltering: false,
|
|
3110
|
+
documentationStatus: ""
|
|
3111
|
+
}
|
|
3112
|
+
};
|
|
3113
|
+
}
|
|
3114
|
+
});
|
|
3115
|
+
|
|
3116
|
+
//#endregion
|
|
3117
|
+
//#region src/lib/handlers/cds-to-abapgit.ts
|
|
3118
|
+
/** Extract the string value from an annotation value node */
|
|
3119
|
+
function annotationStringValue(val) {
|
|
3120
|
+
switch (val.kind) {
|
|
3121
|
+
case "string": return val.value;
|
|
3122
|
+
case "enum": return val.value;
|
|
3123
|
+
case "boolean": return val.value ? "X" : "";
|
|
3124
|
+
case "number": return String(val.value);
|
|
3125
|
+
default: return "";
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
/** Find annotation by key and return its string value */
|
|
3129
|
+
function getAnnotation(annotations, key) {
|
|
3130
|
+
const ann = annotations.find((a) => a.key === key);
|
|
3131
|
+
return ann ? annotationStringValue(ann.value) : void 0;
|
|
3132
|
+
}
|
|
3133
|
+
const TABLE_CATEGORY_MAP = {
|
|
3134
|
+
TRANSPARENT: "TRANSP",
|
|
3135
|
+
CLUSTER: "CLUSTER",
|
|
3136
|
+
POOL: "POOL",
|
|
3137
|
+
APPEND: "APPEND"
|
|
3138
|
+
};
|
|
3139
|
+
const ENHANCEMENT_CATEGORY_MAP = {
|
|
3140
|
+
NOT_EXTENSIBLE: "1",
|
|
3141
|
+
EXTENSIBLE_CHARACTER_NUMERIC: "2",
|
|
3142
|
+
EXTENSIBLE_CHARACTER: "3",
|
|
3143
|
+
EXTENSIBLE_ANY: "4",
|
|
3144
|
+
NOT_CLASSIFIED: "0"
|
|
3145
|
+
};
|
|
3146
|
+
const DATA_MAINTENANCE_MAP = {
|
|
3147
|
+
RESTRICTED: "X",
|
|
3148
|
+
NOT_ALLOWED: "N",
|
|
3149
|
+
ALLOWED: ""
|
|
3150
|
+
};
|
|
3151
|
+
/**
|
|
3152
|
+
* Build DD02V data from a parsed CDS table/structure definition
|
|
3153
|
+
*/
|
|
3154
|
+
function buildDD02V(def, language, description) {
|
|
3155
|
+
let tabclass = def.kind === "structure" ? "INTTAB" : "TRANSP";
|
|
3156
|
+
const tableCategory = getAnnotation(def.annotations, "AbapCatalog.tableCategory");
|
|
3157
|
+
if (tableCategory) tabclass = TABLE_CATEGORY_MAP[tableCategory] || tabclass;
|
|
3158
|
+
const deliveryClass = getAnnotation(def.annotations, "AbapCatalog.deliveryClass");
|
|
3159
|
+
const enhancementCategory = getAnnotation(def.annotations, "AbapCatalog.enhancement.category");
|
|
3160
|
+
const dataMaintenance = getAnnotation(def.annotations, "AbapCatalog.dataMaintenance");
|
|
3161
|
+
const hasLanguageField = def.members.some((m) => {
|
|
3162
|
+
if ("kind" in m && m.kind === "include") return false;
|
|
3163
|
+
const f = m;
|
|
3164
|
+
if (f.type.kind === "named") return f.type.name.toUpperCase() === "SPRAS";
|
|
3165
|
+
if (f.type.kind === "builtin") return f.type.name === "lang";
|
|
3166
|
+
return false;
|
|
3167
|
+
});
|
|
3168
|
+
const hasClientKeyField = def.members.some((m) => {
|
|
3169
|
+
if ("kind" in m && m.kind === "include") return false;
|
|
3170
|
+
const f = m;
|
|
3171
|
+
if (!f.isKey) return false;
|
|
3172
|
+
if (f.type.kind === "named") return f.type.name.toUpperCase() === "MANDT";
|
|
3173
|
+
if (f.type.kind === "builtin") return f.type.name === "clnt";
|
|
3174
|
+
return false;
|
|
3175
|
+
});
|
|
3176
|
+
const result = {};
|
|
3177
|
+
result.TABNAME = def.name.toUpperCase();
|
|
3178
|
+
result.DDLANGUAGE = language;
|
|
3179
|
+
result.TABCLASS = tabclass;
|
|
3180
|
+
if (hasLanguageField) result.LANGDEP = "X";
|
|
3181
|
+
if (hasClientKeyField) result.CLIDEP = "X";
|
|
3182
|
+
result.DDTEXT = description;
|
|
3183
|
+
result.MASTERLANG = language;
|
|
3184
|
+
if (deliveryClass) result.CONTFLAG = deliveryClass;
|
|
3185
|
+
if (enhancementCategory) result.EXCLASS = ENHANCEMENT_CATEGORY_MAP[enhancementCategory];
|
|
3186
|
+
if (dataMaintenance) result.MATEFLAG = DATA_MAINTENANCE_MAP[dataMaintenance] ?? "";
|
|
3187
|
+
return result;
|
|
3188
|
+
}
|
|
3189
|
+
const BUILTIN_TYPES = {
|
|
3190
|
+
char: {
|
|
3191
|
+
datatype: "CHAR",
|
|
3192
|
+
inttype: "C"
|
|
3193
|
+
},
|
|
3194
|
+
clnt: {
|
|
3195
|
+
datatype: "CLNT",
|
|
3196
|
+
inttype: "C",
|
|
3197
|
+
length: 3
|
|
3198
|
+
},
|
|
3199
|
+
numc: {
|
|
3200
|
+
datatype: "NUMC",
|
|
3201
|
+
inttype: "N"
|
|
3202
|
+
},
|
|
3203
|
+
dats: {
|
|
3204
|
+
datatype: "DATS",
|
|
3205
|
+
inttype: "D",
|
|
3206
|
+
length: 8,
|
|
3207
|
+
fixedIntlen: 16,
|
|
3208
|
+
shlporigin: "T"
|
|
3209
|
+
},
|
|
3210
|
+
datn: {
|
|
3211
|
+
datatype: "DATN",
|
|
3212
|
+
inttype: "D",
|
|
3213
|
+
length: 8,
|
|
3214
|
+
fixedIntlen: 16,
|
|
3215
|
+
shlporigin: "T"
|
|
3216
|
+
},
|
|
3217
|
+
tims: {
|
|
3218
|
+
datatype: "TIMS",
|
|
3219
|
+
inttype: "T",
|
|
3220
|
+
length: 6,
|
|
3221
|
+
fixedIntlen: 12,
|
|
3222
|
+
shlporigin: "T"
|
|
3223
|
+
},
|
|
3224
|
+
timn: {
|
|
3225
|
+
datatype: "TIMN",
|
|
3226
|
+
inttype: "T",
|
|
3227
|
+
length: 6,
|
|
3228
|
+
fixedIntlen: 12,
|
|
3229
|
+
shlporigin: "T"
|
|
3230
|
+
},
|
|
3231
|
+
string: {
|
|
3232
|
+
datatype: "STRG",
|
|
3233
|
+
inttype: "g",
|
|
3234
|
+
fixedIntlen: 8,
|
|
3235
|
+
noLeng: true
|
|
3236
|
+
},
|
|
3237
|
+
xstring: {
|
|
3238
|
+
datatype: "RSTR",
|
|
3239
|
+
inttype: "y",
|
|
3240
|
+
fixedIntlen: 8,
|
|
3241
|
+
noLeng: true
|
|
3242
|
+
},
|
|
3243
|
+
int1: {
|
|
3244
|
+
datatype: "INT1",
|
|
3245
|
+
inttype: "X",
|
|
3246
|
+
length: 3,
|
|
3247
|
+
fixedIntlen: 1
|
|
3248
|
+
},
|
|
3249
|
+
int2: {
|
|
3250
|
+
datatype: "INT2",
|
|
3251
|
+
inttype: "X",
|
|
3252
|
+
length: 5,
|
|
3253
|
+
fixedIntlen: 2
|
|
3254
|
+
},
|
|
3255
|
+
int4: {
|
|
3256
|
+
datatype: "INT4",
|
|
3257
|
+
inttype: "X",
|
|
3258
|
+
length: 10,
|
|
3259
|
+
fixedIntlen: 4
|
|
3260
|
+
},
|
|
3261
|
+
int8: {
|
|
3262
|
+
datatype: "INT8",
|
|
3263
|
+
inttype: "8",
|
|
3264
|
+
length: 19,
|
|
3265
|
+
fixedIntlen: 8
|
|
3266
|
+
},
|
|
3267
|
+
fltp: {
|
|
3268
|
+
datatype: "FLTP",
|
|
3269
|
+
inttype: "F",
|
|
3270
|
+
length: 16,
|
|
3271
|
+
decimals: 16,
|
|
3272
|
+
fixedIntlen: 8
|
|
3273
|
+
},
|
|
3274
|
+
dec: {
|
|
3275
|
+
datatype: "DEC",
|
|
3276
|
+
inttype: "P"
|
|
3277
|
+
},
|
|
3278
|
+
curr: {
|
|
3279
|
+
datatype: "CURR",
|
|
3280
|
+
inttype: "P"
|
|
3281
|
+
},
|
|
3282
|
+
quan: {
|
|
3283
|
+
datatype: "QUAN",
|
|
3284
|
+
inttype: "P"
|
|
3285
|
+
},
|
|
3286
|
+
raw: {
|
|
3287
|
+
datatype: "RAW",
|
|
3288
|
+
inttype: "X"
|
|
3289
|
+
},
|
|
3290
|
+
rawstring: {
|
|
3291
|
+
datatype: "RSTR",
|
|
3292
|
+
inttype: "y",
|
|
3293
|
+
fixedIntlen: 8,
|
|
3294
|
+
noLeng: true
|
|
3295
|
+
},
|
|
3296
|
+
lang: {
|
|
3297
|
+
datatype: "LANG",
|
|
3298
|
+
inttype: "C",
|
|
3299
|
+
length: 1
|
|
3300
|
+
},
|
|
3301
|
+
unit: {
|
|
3302
|
+
datatype: "UNIT",
|
|
3303
|
+
inttype: "C",
|
|
3304
|
+
length: 3
|
|
3305
|
+
},
|
|
3306
|
+
cuky: {
|
|
3307
|
+
datatype: "CUKY",
|
|
3308
|
+
inttype: "C",
|
|
3309
|
+
length: 5
|
|
3310
|
+
},
|
|
3311
|
+
d16n: {
|
|
3312
|
+
datatype: "D16N",
|
|
3313
|
+
inttype: "a",
|
|
3314
|
+
fixedIntlen: 8
|
|
3315
|
+
},
|
|
3316
|
+
d34n: {
|
|
3317
|
+
datatype: "D34N",
|
|
3318
|
+
inttype: "e",
|
|
3319
|
+
fixedIntlen: 16
|
|
3320
|
+
},
|
|
3321
|
+
utclong: {
|
|
3322
|
+
datatype: "UTCL",
|
|
3323
|
+
inttype: "p",
|
|
3324
|
+
length: 27,
|
|
3325
|
+
fixedIntlen: 8
|
|
3326
|
+
}
|
|
3327
|
+
};
|
|
3328
|
+
/** Zero-pad number to given width */
|
|
3329
|
+
function zeroPad(n, width) {
|
|
3330
|
+
return String(n).padStart(width, "0");
|
|
3331
|
+
}
|
|
3332
|
+
/** Compute internal length from type info */
|
|
3333
|
+
function computeIntlen(builtin, length) {
|
|
3334
|
+
if (builtin.fixedIntlen !== void 0) return builtin.fixedIntlen;
|
|
3335
|
+
if (builtin.inttype === "P" && length !== void 0) return Math.ceil((length + 1) / 2);
|
|
3336
|
+
if (builtin.inttype === "X" && length !== void 0) return length;
|
|
3337
|
+
if (length !== void 0) return length * 2;
|
|
3338
|
+
if (builtin.length !== void 0) return builtin.length * 2;
|
|
3339
|
+
return 0;
|
|
3340
|
+
}
|
|
3341
|
+
/** Build a DD03P entry from a single field definition */
|
|
3342
|
+
async function buildFieldDD03P(field, tableName, resolver) {
|
|
3343
|
+
const isKey = field.isKey;
|
|
3344
|
+
const notNull = field.notNull;
|
|
3345
|
+
let rollname;
|
|
3346
|
+
let comptype;
|
|
3347
|
+
let inttype;
|
|
3348
|
+
let intlen;
|
|
3349
|
+
let datatype;
|
|
3350
|
+
let leng;
|
|
3351
|
+
let decimals;
|
|
3352
|
+
let mask;
|
|
3353
|
+
let shlporigin;
|
|
3354
|
+
let reftable;
|
|
3355
|
+
let reffield;
|
|
3356
|
+
if (field.type.kind === "builtin") {
|
|
3357
|
+
const bt = field.type;
|
|
3358
|
+
const typeInfo = BUILTIN_TYPES[bt.name];
|
|
3359
|
+
if (typeInfo) {
|
|
3360
|
+
const length = bt.length ?? typeInfo.length;
|
|
3361
|
+
inttype = typeInfo.inttype;
|
|
3362
|
+
intlen = zeroPad(computeIntlen(typeInfo, length), 6);
|
|
3363
|
+
datatype = typeInfo.datatype;
|
|
3364
|
+
if (!typeInfo.noLeng && length !== void 0) leng = zeroPad(length, 6);
|
|
3365
|
+
const dec = bt.decimals ?? typeInfo.decimals;
|
|
3366
|
+
if (dec !== void 0) decimals = zeroPad(dec, 6);
|
|
3367
|
+
mask = ` ${typeInfo.datatype}`;
|
|
3368
|
+
if (typeInfo.shlporigin) shlporigin = typeInfo.shlporigin;
|
|
3369
|
+
if (bt.name === "curr" || bt.name === "quan") {
|
|
3370
|
+
const refAnnotation = getAnnotation(field.annotations, bt.name === "curr" ? "Semantics.amount.currencyCode" : "Semantics.quantity.unitOfMeasure");
|
|
3371
|
+
if (refAnnotation) {
|
|
3372
|
+
reftable = tableName;
|
|
3373
|
+
const parts = refAnnotation.split(".");
|
|
3374
|
+
reffield = parts[parts.length - 1].toUpperCase();
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
} else {
|
|
3379
|
+
rollname = field.type.name.toUpperCase();
|
|
3380
|
+
comptype = "E";
|
|
3381
|
+
if (resolver) {
|
|
3382
|
+
const resolved = await resolver.resolve(field.type.name);
|
|
3383
|
+
comptype = resolved.comptype;
|
|
3384
|
+
if (resolved.shlporigin) shlporigin = resolved.shlporigin;
|
|
3385
|
+
if (resolved.comptype === "S") {
|
|
3386
|
+
datatype = "STRU";
|
|
3387
|
+
mask = " STRUS";
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
const result = {};
|
|
3392
|
+
result.FIELDNAME = field.name.toUpperCase();
|
|
3393
|
+
if (isKey) result.KEYFLAG = "X";
|
|
3394
|
+
if (rollname) result.ROLLNAME = rollname;
|
|
3395
|
+
result.ADMINFIELD = "0";
|
|
3396
|
+
if (inttype) result.INTTYPE = inttype;
|
|
3397
|
+
if (intlen) result.INTLEN = intlen;
|
|
3398
|
+
if (notNull) result.NOTNULL = "X";
|
|
3399
|
+
if (datatype) result.DATATYPE = datatype;
|
|
3400
|
+
if (leng) result.LENG = leng;
|
|
3401
|
+
if (decimals) result.DECIMALS = decimals;
|
|
3402
|
+
if (shlporigin) result.SHLPORIGIN = shlporigin;
|
|
3403
|
+
if (reftable) result.REFTABLE = reftable;
|
|
3404
|
+
if (reffield) result.REFFIELD = reffield;
|
|
3405
|
+
if (mask) result.MASK = mask;
|
|
3406
|
+
if (comptype) result.COMPTYPE = comptype;
|
|
3407
|
+
return result;
|
|
3408
|
+
}
|
|
3409
|
+
/**
|
|
3410
|
+
* Build DD03P entries from table/structure members
|
|
3411
|
+
*/
|
|
3412
|
+
async function buildDD03P(members, tableName = "", resolver) {
|
|
3413
|
+
const entries = [];
|
|
3414
|
+
for (const member of members) if ("kind" in member && member.kind === "include") {
|
|
3415
|
+
const inc = member;
|
|
3416
|
+
const includeName = inc.name.toUpperCase();
|
|
3417
|
+
let ddtext;
|
|
3418
|
+
if (resolver) ddtext = (await resolver.resolve(inc.name)).description;
|
|
3419
|
+
if (inc.suffix) {
|
|
3420
|
+
const entry = {
|
|
3421
|
+
FIELDNAME: `.INCLU-${inc.suffix.toUpperCase()}`,
|
|
3422
|
+
ADMINFIELD: "0",
|
|
3423
|
+
PRECFIELD: includeName,
|
|
3424
|
+
MASK: " S",
|
|
3425
|
+
COMPTYPE: "S"
|
|
3426
|
+
};
|
|
3427
|
+
if (ddtext) entry.DDTEXT = ddtext;
|
|
3428
|
+
entries.push(entry);
|
|
3429
|
+
} else {
|
|
3430
|
+
const entry = {
|
|
3431
|
+
FIELDNAME: ".INCLUDE",
|
|
3432
|
+
ADMINFIELD: "0",
|
|
3433
|
+
PRECFIELD: includeName,
|
|
3434
|
+
MASK: " S",
|
|
3435
|
+
COMPTYPE: "S"
|
|
3436
|
+
};
|
|
3437
|
+
if (ddtext) entry.DDTEXT = ddtext;
|
|
3438
|
+
entries.push(entry);
|
|
3439
|
+
}
|
|
3440
|
+
} else {
|
|
3441
|
+
const field = member;
|
|
3442
|
+
entries.push(await buildFieldDD03P(field, tableName, resolver));
|
|
3443
|
+
}
|
|
3444
|
+
return entries;
|
|
3445
|
+
}
|
|
3446
|
+
|
|
3447
|
+
//#endregion
|
|
3448
|
+
//#region src/lib/handlers/objects/tabl.ts
|
|
3449
|
+
/**
|
|
3450
|
+
* Table/Structure (TABL) object handlers for abapGit format
|
|
3451
|
+
*
|
|
3452
|
+
* Serializes SAP tables (TABL/DT) and structures (TABL/DS) to
|
|
3453
|
+
* abapGit-compatible XML format by fetching the CDS-style source code
|
|
3454
|
+
* from SAP, parsing it with @abapify/acds, and mapping the AST into
|
|
3455
|
+
* DD02V/DD03P structures.
|
|
3456
|
+
*
|
|
3457
|
+
* Tables and structures share the same serialization logic but use
|
|
3458
|
+
* different ADT endpoints (ddic/tables vs ddic/structures).
|
|
3459
|
+
*
|
|
3460
|
+
* Data sources:
|
|
3461
|
+
* - blueSource GET: name, type, description, language
|
|
3462
|
+
* - source/main GET: CDS source with annotations and field definitions
|
|
3463
|
+
* → parsed via @abapify/acds into AST
|
|
3464
|
+
* → mapped into DD02V annotations and DD03P field entries
|
|
3465
|
+
* - Per named type: /sap/bc/adt/ddic/dataelements/{name} or /structures/{name}
|
|
3466
|
+
* → resolves COMPTYPE (E vs S), SHLPORIGIN, description (DDTEXT)
|
|
3467
|
+
*/
|
|
3468
|
+
/**
|
|
3469
|
+
* Strip undefined/empty-string values from an object
|
|
3470
|
+
* to avoid emitting empty XML elements
|
|
3471
|
+
*/
|
|
3472
|
+
function stripEmpty(obj) {
|
|
3473
|
+
const result = {};
|
|
3474
|
+
for (const [key, value] of Object.entries(obj)) if (value !== void 0 && value !== "") result[key] = value;
|
|
3475
|
+
return result;
|
|
3476
|
+
}
|
|
3477
|
+
/**
|
|
3478
|
+
* Create a TypeResolver that resolves named types via ADT endpoints.
|
|
3479
|
+
* Tries data element first, then structure. Caches results.
|
|
3480
|
+
*/
|
|
3481
|
+
function createAdtTypeResolver(obj) {
|
|
3482
|
+
const cache = /* @__PURE__ */ new Map();
|
|
3483
|
+
return { async resolve(name) {
|
|
3484
|
+
const key = name.toLowerCase();
|
|
3485
|
+
if (cache.has(key)) return cache.get(key);
|
|
3486
|
+
const dtelXml = await obj.fetchText(`/sap/bc/adt/ddic/dataelements/${encodeURIComponent(key)}`);
|
|
3487
|
+
if (dtelXml) {
|
|
3488
|
+
const result = { comptype: "E" };
|
|
3489
|
+
if (dtelXml.match(/<dtel:searchHelp>[^<]+<\/dtel:searchHelp>/)) result.shlporigin = "D";
|
|
3490
|
+
const descMatch = dtelXml.match(/adtcore:description="([^"]+)"/);
|
|
3491
|
+
if (descMatch) result.description = descMatch[1];
|
|
3492
|
+
cache.set(key, result);
|
|
3493
|
+
return result;
|
|
3494
|
+
}
|
|
3495
|
+
const structXml = await obj.fetchText(`/sap/bc/adt/ddic/structures/${encodeURIComponent(key)}`);
|
|
3496
|
+
if (structXml) {
|
|
3497
|
+
const result = { comptype: "S" };
|
|
3498
|
+
const descMatch = structXml.match(/adtcore:description="([^"]+)"/);
|
|
3499
|
+
if (descMatch) result.description = descMatch[1];
|
|
3500
|
+
cache.set(key, result);
|
|
3501
|
+
return result;
|
|
3502
|
+
}
|
|
3503
|
+
const fallback = { comptype: "E" };
|
|
3504
|
+
cache.set(key, fallback);
|
|
3505
|
+
return fallback;
|
|
3506
|
+
} };
|
|
3507
|
+
}
|
|
3508
|
+
/**
|
|
3509
|
+
* Parse ADT table settings XML into DD09L data for abapGit serialization.
|
|
3510
|
+
*
|
|
3511
|
+
* Uses the typed `tablesettings` schema from @abapify/adt-schemas to parse
|
|
3512
|
+
* the ADT endpoint response (/sap/bc/adt/ddic/db/settings/{name}).
|
|
3513
|
+
*
|
|
3514
|
+
* Mapping:
|
|
3515
|
+
* tableSettings.sizeCategory → DD09L.TABKAT
|
|
3516
|
+
* tableSettings.dataClassCategory → DD09L.TABART
|
|
3517
|
+
* tableSettings.buffering.allowed → DD09L.BUFALLOW
|
|
3518
|
+
* tableSettings.buffering.type → DD09L.PUFFERUNG
|
|
3519
|
+
* tableSettings.buffering.areaKeyFields → DD09L.SCHFELDANZ
|
|
3520
|
+
* tableSettings.loggingEnabled → DD09L.PROTOKOLL
|
|
3521
|
+
*/
|
|
3522
|
+
function parseSettingsToDD09L(settingsXml, tableName) {
|
|
3523
|
+
let settings;
|
|
3524
|
+
try {
|
|
3525
|
+
const parsed = tablesettings.parse(settingsXml);
|
|
3526
|
+
if (!("tableSettings" in parsed)) return void 0;
|
|
3527
|
+
settings = parsed.tableSettings;
|
|
3528
|
+
} catch {
|
|
3529
|
+
return;
|
|
3530
|
+
}
|
|
3531
|
+
const dd09l = {};
|
|
3532
|
+
dd09l.TABNAME = tableName;
|
|
3533
|
+
dd09l.AS4LOCAL = "A";
|
|
3534
|
+
if (settings.sizeCategory) dd09l.TABKAT = settings.sizeCategory;
|
|
3535
|
+
if (settings.dataClassCategory) dd09l.TABART = settings.dataClassCategory;
|
|
3536
|
+
if (settings.buffering?.allowed) dd09l.BUFALLOW = settings.buffering.allowed;
|
|
3537
|
+
const bufType = settings.buffering?.type;
|
|
3538
|
+
if (bufType) dd09l.PUFFERUNG = bufType;
|
|
3539
|
+
const areaKeyFields = settings.buffering?.areaKeyFields;
|
|
3540
|
+
if (areaKeyFields && areaKeyFields !== "0") dd09l.SCHFELDANZ = areaKeyFields;
|
|
3541
|
+
if (settings.loggingEnabled) dd09l.PROTOKOLL = "X";
|
|
3542
|
+
return dd09l;
|
|
3543
|
+
}
|
|
3544
|
+
/**
|
|
3545
|
+
* Shared serialize logic for tables and structures.
|
|
3546
|
+
* Both use CDS source → DD02V/DD03P mapping.
|
|
3547
|
+
*/
|
|
3548
|
+
async function serializeTabl(obj, ctx) {
|
|
3549
|
+
const objectName = ctx.getObjectName(obj);
|
|
3550
|
+
const lang = isoToSapLang(obj.language || void 0);
|
|
3551
|
+
let cdsSource;
|
|
3552
|
+
try {
|
|
3553
|
+
cdsSource = await obj.getSource();
|
|
3554
|
+
} catch {
|
|
3555
|
+
const xmlContent = ctx.toAbapGitXml(obj);
|
|
3556
|
+
return [ctx.createFile(`${objectName}.tabl.xml`, xmlContent)];
|
|
3557
|
+
}
|
|
3558
|
+
const { ast, errors } = parse(cdsSource);
|
|
3559
|
+
if (errors.length > 0 || ast.definitions.length === 0) {
|
|
3560
|
+
const xmlContent = ctx.toAbapGitXml(obj);
|
|
3561
|
+
return [ctx.createFile(`${objectName}.tabl.xml`, xmlContent)];
|
|
3562
|
+
}
|
|
3563
|
+
const def = ast.definitions[0];
|
|
3564
|
+
const dd02v = buildDD02V(def, lang, obj.description ?? "");
|
|
3565
|
+
const resolver = createAdtTypeResolver(obj);
|
|
3566
|
+
const dd03pEntries = await buildDD03P(def.members, def.name.toUpperCase(), resolver);
|
|
3567
|
+
const values = { DD02V: stripEmpty(dd02v) };
|
|
3568
|
+
if ("getSettings" in obj && typeof obj.getSettings === "function") try {
|
|
3569
|
+
const settingsXml = await obj.getSettings();
|
|
3570
|
+
if (settingsXml) {
|
|
3571
|
+
const dd09l = parseSettingsToDD09L(settingsXml, def.name.toUpperCase());
|
|
3572
|
+
if (dd09l) values.DD09L = stripEmpty(dd09l);
|
|
3573
|
+
}
|
|
3574
|
+
} catch {}
|
|
3575
|
+
if (dd03pEntries.length > 0) values.DD03P_TABLE = { DD03P: dd03pEntries.map((entry) => stripEmpty(entry)) };
|
|
3576
|
+
const fullPayload = {
|
|
3577
|
+
abap: {
|
|
3578
|
+
version: "1.0",
|
|
3579
|
+
values
|
|
3580
|
+
},
|
|
3581
|
+
version: "v1.0.0",
|
|
3582
|
+
serializer: "LCL_OBJECT_TABL",
|
|
3583
|
+
serializer_version: "v1.0.0"
|
|
3584
|
+
};
|
|
3585
|
+
const xml = formatAbapGitXml(tabl.build(fullPayload, { pretty: true }));
|
|
3586
|
+
return [ctx.createFile(`${objectName}.tabl.xml`, xml)];
|
|
3587
|
+
}
|
|
3588
|
+
/** Shared fromAbapGit logic for both tables and structures */
|
|
3589
|
+
function fromAbapGitTabl({ DD02V } = {}) {
|
|
3590
|
+
return {
|
|
3591
|
+
name: (DD02V?.TABNAME ?? "").toUpperCase(),
|
|
3592
|
+
type: DD02V?.TABCLASS === "INTTAB" ? "TABL/DS" : "TABL/DT",
|
|
3593
|
+
description: DD02V?.DDTEXT,
|
|
3594
|
+
language: sapLangToIso(DD02V?.DDLANGUAGE),
|
|
3595
|
+
masterLanguage: sapLangToIso(DD02V?.DDLANGUAGE)
|
|
3596
|
+
};
|
|
3597
|
+
}
|
|
3598
|
+
const tableHandler = createHandler(AdkTable, {
|
|
3599
|
+
schema: tabl,
|
|
3600
|
+
version: "v1.0.0",
|
|
3601
|
+
serializer: "LCL_OBJECT_TABL",
|
|
3602
|
+
serializer_version: "v1.0.0",
|
|
3603
|
+
toAbapGit: (obj) => ({ DD02V: {
|
|
3604
|
+
TABNAME: obj.name ?? "",
|
|
3605
|
+
DDLANGUAGE: isoToSapLang(obj.language || void 0),
|
|
3606
|
+
TABCLASS: "TRANSP",
|
|
3607
|
+
DDTEXT: obj.description ?? ""
|
|
3608
|
+
} }),
|
|
3609
|
+
serialize: (obj, ctx) => serializeTabl(obj, ctx),
|
|
3610
|
+
fromAbapGit: fromAbapGitTabl
|
|
3611
|
+
});
|
|
3612
|
+
const structureHandler = createHandler(AdkStructure, {
|
|
3613
|
+
schema: tabl,
|
|
3614
|
+
version: "v1.0.0",
|
|
3615
|
+
serializer: "LCL_OBJECT_TABL",
|
|
3616
|
+
serializer_version: "v1.0.0",
|
|
3617
|
+
toAbapGit: (obj) => ({ DD02V: {
|
|
3618
|
+
TABNAME: obj.name ?? "",
|
|
3619
|
+
DDLANGUAGE: isoToSapLang(obj.language || void 0),
|
|
3620
|
+
TABCLASS: "INTTAB",
|
|
3621
|
+
DDTEXT: obj.description ?? ""
|
|
3622
|
+
} }),
|
|
3623
|
+
serialize: (obj, ctx) => serializeTabl(obj, ctx),
|
|
3624
|
+
fromAbapGit: fromAbapGitTabl
|
|
3625
|
+
});
|
|
3626
|
+
|
|
3627
|
+
//#endregion
|
|
3628
|
+
//#region src/lib/handlers/objects/ttyp.ts
|
|
3629
|
+
/**
|
|
3630
|
+
* Table Type (TTYP) object handler for abapGit format
|
|
3631
|
+
*
|
|
3632
|
+
* Maps between abapGit DD40V codes and ADT API enum values.
|
|
3633
|
+
*/
|
|
3634
|
+
/** DD40V ACCESSMODE → ADT accessType */
|
|
3635
|
+
const ACCESS_MODE_TO_ADT = {
|
|
3636
|
+
T: "standard",
|
|
3637
|
+
S: "sorted",
|
|
3638
|
+
H: "hashed"
|
|
3639
|
+
};
|
|
3640
|
+
const ACCESS_MODE_FROM_ADT = Object.fromEntries(Object.entries(ACCESS_MODE_TO_ADT).map(([k, v]) => [v, k]));
|
|
3641
|
+
/** DD40V KEYDEF → ADT primaryKey.definition */
|
|
3642
|
+
const KEY_DEF_TO_ADT = {
|
|
3643
|
+
D: "standard",
|
|
3644
|
+
K: "keyComponents",
|
|
3645
|
+
T: "rowType"
|
|
3646
|
+
};
|
|
3647
|
+
const KEY_DEF_FROM_ADT = Object.fromEntries(Object.entries(KEY_DEF_TO_ADT).map(([k, v]) => [v, k]));
|
|
3648
|
+
/** DD40V KEYKIND → ADT primaryKey.kind */
|
|
3649
|
+
const KEY_KIND_TO_ADT = {
|
|
3650
|
+
N: "nonUnique",
|
|
3651
|
+
U: "unique",
|
|
3652
|
+
G: "notSpecified"
|
|
3653
|
+
};
|
|
3654
|
+
const KEY_KIND_FROM_ADT = Object.fromEntries(Object.entries(KEY_KIND_TO_ADT).map(([k, v]) => [v, k]));
|
|
3655
|
+
/**
|
|
3656
|
+
* DD40V ROWKIND → ADT rowType.typeKind
|
|
3657
|
+
*
|
|
3658
|
+
* ROWKIND='' (empty) + DATATYPE set → predefinedAbapType (built-in like STRING, INT4)
|
|
3659
|
+
* ROWKIND='S' → dictionaryType (references a structure/table/data element)
|
|
3660
|
+
* ROWKIND='R' → ref type
|
|
3661
|
+
*/
|
|
3662
|
+
const ROW_KIND_TO_ADT = {
|
|
3663
|
+
"": "predefinedAbapType",
|
|
3664
|
+
S: "dictionaryType",
|
|
3665
|
+
R: "refToDictionaryType"
|
|
3666
|
+
};
|
|
3667
|
+
const ROW_KIND_FROM_ADT = Object.fromEntries(Object.entries(ROW_KIND_TO_ADT).map(([k, v]) => [v, k]));
|
|
3668
|
+
/**
|
|
3669
|
+
* DD40V DATATYPE (DDIC code) → ADT builtInType.dataType (ABAP type name)
|
|
3670
|
+
*
|
|
3671
|
+
* abapGit stores 4-char DDIC internal codes (e.g. STRG, RSTR).
|
|
3672
|
+
* SAP ADT REST API uses ABAP type names (e.g. STRING, XSTRING).
|
|
3673
|
+
* Most types use the same name in both (CHAR, NUMC, INT4, etc.);
|
|
3674
|
+
* only a few differ.
|
|
3675
|
+
*/
|
|
3676
|
+
const DATATYPE_TO_ADT = {
|
|
3677
|
+
STRG: "STRING",
|
|
3678
|
+
SSTR: "SSTRING",
|
|
3679
|
+
RSTR: "XSTRING",
|
|
3680
|
+
UTCL: "UTCLONG"
|
|
3681
|
+
};
|
|
3682
|
+
const DATATYPE_FROM_ADT = Object.fromEntries(Object.entries(DATATYPE_TO_ADT).map(([k, v]) => [v, k]));
|
|
3683
|
+
/**
|
|
3684
|
+
* DD40V TYPELEN — fixed internal byte length for predefined types.
|
|
3685
|
+
*
|
|
3686
|
+
* Variable-length types (STRING, XSTRING) have a fixed pointer size (8 bytes)
|
|
3687
|
+
* that abapGit stores as TYPELEN. This is not the same as LENG (display length).
|
|
3688
|
+
* We only need to emit TYPELEN for types that have noLeng=true (no external LENG).
|
|
3689
|
+
*/
|
|
3690
|
+
const FIXED_TYPELEN = {
|
|
3691
|
+
STRG: 8,
|
|
3692
|
+
RSTR: 8
|
|
3693
|
+
};
|
|
3694
|
+
const tableTypeHandler = createHandler(AdkTableType, {
|
|
3695
|
+
schema: ttyp,
|
|
3696
|
+
version: "v1.0.0",
|
|
3697
|
+
serializer: "LCL_OBJECT_TTYP",
|
|
3698
|
+
serializer_version: "v1.0.0",
|
|
3699
|
+
toAbapGit: (obj) => {
|
|
3700
|
+
const data = obj.dataSync;
|
|
3701
|
+
const accessMode = ACCESS_MODE_FROM_ADT[data?.accessType ?? ""] ?? data?.accessType ?? "";
|
|
3702
|
+
const keyDef = KEY_DEF_FROM_ADT[data?.primaryKey?.definition ?? ""] ?? data?.primaryKey?.definition ?? "";
|
|
3703
|
+
const keyKind = KEY_KIND_FROM_ADT[data?.primaryKey?.kind ?? ""] ?? data?.primaryKey?.kind ?? "";
|
|
3704
|
+
const rowKind = ROW_KIND_FROM_ADT[data?.rowType?.typeKind ?? ""] ?? data?.rowType?.typeKind ?? "";
|
|
3705
|
+
const adtDataType = data?.rowType?.builtInType?.dataType ?? "";
|
|
3706
|
+
const ddicDataType = DATATYPE_FROM_ADT[adtDataType] ?? adtDataType;
|
|
3707
|
+
const typeLen = FIXED_TYPELEN[ddicDataType];
|
|
3708
|
+
return { DD40V: {
|
|
3709
|
+
TYPENAME: obj.name ?? "",
|
|
3710
|
+
DDLANGUAGE: isoToSapLang(data?.language || void 0),
|
|
3711
|
+
ROWTYPE: data?.rowType?.typeName || void 0,
|
|
3712
|
+
ROWKIND: rowKind || void 0,
|
|
3713
|
+
DATATYPE: ddicDataType,
|
|
3714
|
+
LENG: data?.rowType?.builtInType?.length ? String(data.rowType.builtInType.length).padStart(6, "0") : void 0,
|
|
3715
|
+
DECIMALS: data?.rowType?.builtInType?.decimals ? String(data.rowType.builtInType.decimals).padStart(6, "0") : void 0,
|
|
3716
|
+
ACCESSMODE: accessMode,
|
|
3717
|
+
KEYDEF: keyDef,
|
|
3718
|
+
KEYKIND: keyKind,
|
|
3719
|
+
DDTEXT: obj.description ?? "",
|
|
3720
|
+
TYPELEN: typeLen ? String(typeLen).padStart(6, "0") : void 0,
|
|
3721
|
+
ABAP_LANGUAGE_VERSION: abapLangVerFromAdt(data?.abapLanguageVersion)
|
|
3722
|
+
} };
|
|
3723
|
+
},
|
|
3724
|
+
fromAbapGit: ({ DD40V }) => {
|
|
3725
|
+
const accessType = ACCESS_MODE_TO_ADT[DD40V?.ACCESSMODE ?? ""] ?? DD40V?.ACCESSMODE;
|
|
3726
|
+
const keyDef = KEY_DEF_TO_ADT[DD40V?.KEYDEF ?? ""] ?? DD40V?.KEYDEF;
|
|
3727
|
+
const keyKind = KEY_KIND_TO_ADT[DD40V?.KEYKIND ?? ""] ?? DD40V?.KEYKIND;
|
|
3728
|
+
const rowKind = ROW_KIND_TO_ADT[DD40V?.ROWKIND ?? ""] ?? DD40V?.ROWKIND;
|
|
3729
|
+
const ddicCode = DD40V?.DATATYPE ?? "";
|
|
3730
|
+
const adtDataType = DATATYPE_TO_ADT[ddicCode] ?? ddicCode;
|
|
3731
|
+
const isPredefined = rowKind === "predefinedAbapType";
|
|
3732
|
+
return {
|
|
3733
|
+
name: (DD40V?.TYPENAME ?? "").toUpperCase(),
|
|
3734
|
+
type: "TTYP/DA",
|
|
3735
|
+
description: DD40V?.DDTEXT,
|
|
3736
|
+
language: sapLangToIso(DD40V?.DDLANGUAGE),
|
|
3737
|
+
masterLanguage: sapLangToIso(DD40V?.DDLANGUAGE),
|
|
3738
|
+
abapLanguageVersion: abapLangVerToAdt(DD40V?.ABAP_LANGUAGE_VERSION),
|
|
3739
|
+
rowType: {
|
|
3740
|
+
typeKind: rowKind,
|
|
3741
|
+
typeName: isPredefined ? "" : DD40V?.ROWTYPE || "",
|
|
3742
|
+
builtInType: {
|
|
3743
|
+
dataType: ddicCode ? adtDataType : "",
|
|
3744
|
+
length: DD40V?.LENG ? Number(DD40V.LENG) : 0,
|
|
3745
|
+
decimals: DD40V?.DECIMALS ? Number(DD40V.DECIMALS) : 0
|
|
3746
|
+
},
|
|
3747
|
+
rangeType: ""
|
|
3748
|
+
},
|
|
3749
|
+
accessType,
|
|
3750
|
+
primaryKey: {
|
|
3751
|
+
definition: keyDef,
|
|
3752
|
+
kind: keyKind,
|
|
3753
|
+
components: { component: [] },
|
|
3754
|
+
alias: ""
|
|
3755
|
+
},
|
|
3756
|
+
secondaryKeys: { allowed: "notSpecified" }
|
|
3757
|
+
};
|
|
3758
|
+
}
|
|
3759
|
+
});
|
|
3760
|
+
|
|
3761
|
+
//#endregion
|
|
3762
|
+
//#region src/lib/handlers/objects/bdef.ts
|
|
3763
|
+
/**
|
|
3764
|
+
* BDEF (RAP Behavior Definition) object handler for abapGit format
|
|
3765
|
+
*
|
|
3766
|
+
* BDEF is source-driven: the semantic content lives in a `.abdl` file
|
|
3767
|
+
* (the RAP behavior definition language) and abapGit stores it alongside
|
|
3768
|
+
* a minimal SKEY metadata block.
|
|
3769
|
+
*
|
|
3770
|
+
* File layout:
|
|
3771
|
+
* src/zbp_foo.bdef.abdl — behavior source (.abdl text)
|
|
3772
|
+
* src/zbp_foo.bdef.xml — minimal metadata wrapper
|
|
3773
|
+
*
|
|
3774
|
+
* The handler uses the string form of `createHandler` ('BDEF') because
|
|
3775
|
+
* the ADK object (`AdkBehaviorDefinition`) is a lightweight class without
|
|
3776
|
+
* the AdkObject save/lock machinery — all lifecycle is source-based.
|
|
3777
|
+
*
|
|
3778
|
+
* We override `serialize` so the source file gets the `.abdl` extension
|
|
3779
|
+
* instead of the default `.abap`.
|
|
3780
|
+
*/
|
|
3781
|
+
const behaviorDefinitionHandler = createHandler("BDEF", {
|
|
3782
|
+
schema: bdef,
|
|
3783
|
+
version: "v1.0.0",
|
|
3784
|
+
serializer: "LCL_OBJECT_BDEF",
|
|
3785
|
+
serializer_version: "v1.0.0",
|
|
3786
|
+
toAbapGit: (obj) => ({ SKEY: {
|
|
3787
|
+
TYPE: "BDEF",
|
|
3788
|
+
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3789
|
+
} }),
|
|
3790
|
+
getSource: (obj) => typeof obj?.getSource === "function" ? obj.getSource() : Promise.resolve(""),
|
|
3791
|
+
fromAbapGit: ({ SKEY }) => ({ name: String(SKEY?.NAME ?? "").toUpperCase() }),
|
|
3792
|
+
async serialize(object, ctx) {
|
|
3793
|
+
const files = [];
|
|
3794
|
+
const objectName = ctx.getObjectName(object);
|
|
3795
|
+
const source = await (typeof object?.getSource === "function" ? object.getSource() : Promise.resolve(""));
|
|
3796
|
+
if (source) files.push(ctx.createFile(`${objectName}.${ctx.fileExtension}.abdl`, source));
|
|
3797
|
+
const xmlContent = ctx.toAbapGitXml(object);
|
|
3798
|
+
files.push(ctx.createFile(`${objectName}.${ctx.fileExtension}.xml`, xmlContent));
|
|
3799
|
+
return files;
|
|
3800
|
+
},
|
|
3801
|
+
setSources: (obj, sources) => {
|
|
3802
|
+
if (sources.main) obj._pendingSource = sources.main;
|
|
3803
|
+
}
|
|
3804
|
+
});
|
|
3805
|
+
|
|
3806
|
+
//#endregion
|
|
3807
|
+
//#region src/lib/handlers/objects/srvd.ts
|
|
3808
|
+
/**
|
|
3809
|
+
* SRVD (RAP Service Definition) object handler for abapGit format
|
|
3810
|
+
*
|
|
3811
|
+
* SRVD is source-driven: the semantic content lives in a `.asrvd` file
|
|
3812
|
+
* (CDS-like service definition) and abapGit stores it alongside
|
|
3813
|
+
* a minimal SKEY metadata block.
|
|
3814
|
+
*
|
|
3815
|
+
* File layout:
|
|
3816
|
+
* src/zui_foo.srvd.asrvd — service source (.asrvd text)
|
|
3817
|
+
* src/zui_foo.srvd.xml — minimal metadata wrapper
|
|
3818
|
+
*
|
|
3819
|
+
* The handler uses the string form of `createHandler` ('SRVD') because
|
|
3820
|
+
* the ADK object (`AdkServiceDefinition`) is a lightweight class without
|
|
3821
|
+
* the AdkObject save/lock machinery — all lifecycle is source-based.
|
|
3822
|
+
*
|
|
3823
|
+
* We override `serialize` so the source file gets the `.asrvd` extension
|
|
3824
|
+
* instead of the default `.abap`.
|
|
3825
|
+
*/
|
|
3826
|
+
const serviceDefinitionHandler = createHandler("SRVD", {
|
|
3827
|
+
schema: srvd,
|
|
3828
|
+
version: "v1.0.0",
|
|
3829
|
+
serializer: "LCL_OBJECT_SRVD",
|
|
3830
|
+
serializer_version: "v1.0.0",
|
|
3831
|
+
toAbapGit: (obj) => ({ SKEY: {
|
|
3832
|
+
TYPE: "SRVD",
|
|
3833
|
+
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3834
|
+
} }),
|
|
3835
|
+
getSource: (obj) => typeof obj?.getSource === "function" ? obj.getSource() : Promise.resolve(""),
|
|
3836
|
+
fromAbapGit: ({ SKEY }) => ({ name: String(SKEY?.NAME ?? "").toUpperCase() }),
|
|
3837
|
+
async serialize(object, ctx) {
|
|
3838
|
+
const files = [];
|
|
3839
|
+
const objectName = ctx.getObjectName(object);
|
|
3840
|
+
const source = await (typeof object?.getSource === "function" ? object.getSource() : Promise.resolve(""));
|
|
3841
|
+
if (source) files.push(ctx.createFile(`${objectName}.${ctx.fileExtension}.asrvd`, source));
|
|
3842
|
+
const xmlContent = ctx.toAbapGitXml(object);
|
|
3843
|
+
files.push(ctx.createFile(`${objectName}.${ctx.fileExtension}.xml`, xmlContent));
|
|
3844
|
+
return files;
|
|
3845
|
+
},
|
|
3846
|
+
setSources: (obj, sources) => {
|
|
3847
|
+
if (sources.main) obj._pendingSource = sources.main;
|
|
3848
|
+
}
|
|
3849
|
+
});
|
|
3850
|
+
|
|
3851
|
+
//#endregion
|
|
3852
|
+
//#region src/lib/handlers/objects/srvb.ts
|
|
3853
|
+
/**
|
|
3854
|
+
* SRVB (RAP Service Binding) object handler for abapGit format
|
|
3855
|
+
*
|
|
3856
|
+
* Unlike BDEF/SRVD, SRVB is **metadata-only** — there is no `.abdl`/
|
|
3857
|
+
* `.asrvd`-style source text. The handler writes a single
|
|
3858
|
+
* `<name>.srvb.xml` file carrying a minimal SKEY + BINDING block.
|
|
3859
|
+
*
|
|
3860
|
+
* File layout:
|
|
3861
|
+
* src/zui_foo.srvb.xml — metadata only
|
|
3862
|
+
*
|
|
3863
|
+
* Mirrors the minimal-block approach used by
|
|
3864
|
+
* zcl_abapgit_object_srvb (abapGit upstream serialiser).
|
|
3865
|
+
*/
|
|
3866
|
+
const serviceBindingHandler = createHandler("SRVB", {
|
|
3867
|
+
schema: srvb,
|
|
3868
|
+
version: "v1.0.0",
|
|
3869
|
+
serializer: "LCL_OBJECT_SRVB",
|
|
3870
|
+
serializer_version: "v1.0.0",
|
|
3871
|
+
toAbapGit: (obj) => ({
|
|
3872
|
+
SKEY: {
|
|
3873
|
+
TYPE: "SRVB",
|
|
3874
|
+
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3875
|
+
},
|
|
3876
|
+
BINDING: {
|
|
3877
|
+
TYPE: "odataV4",
|
|
3878
|
+
VERSION: "4",
|
|
3879
|
+
CATEGORY: "odata_v4_ui"
|
|
3880
|
+
}
|
|
3881
|
+
}),
|
|
3882
|
+
fromAbapGit: ({ SKEY }) => ({ name: String(SKEY?.NAME ?? "").toUpperCase() }),
|
|
3883
|
+
async serialize(object, ctx) {
|
|
3884
|
+
const objectName = ctx.getObjectName(object);
|
|
3885
|
+
const xmlContent = ctx.toAbapGitXml(object);
|
|
3886
|
+
return [ctx.createFile(`${objectName}.${ctx.fileExtension}.xml`, xmlContent)];
|
|
3887
|
+
}
|
|
3888
|
+
});
|
|
3889
|
+
|
|
3890
|
+
//#endregion
|
|
3891
|
+
//#region src/lib/folder-logic.ts
|
|
3892
|
+
function stripSlashes(s) {
|
|
3893
|
+
let start = 0;
|
|
3894
|
+
let end = s.length;
|
|
3895
|
+
while (start < end && s[start] === "/") start++;
|
|
3896
|
+
while (end > start && s[end - 1] === "/") end--;
|
|
3897
|
+
return s.slice(start, end);
|
|
3898
|
+
}
|
|
3899
|
+
/**
|
|
3900
|
+
* Parse FOLDER_LOGIC from .abapgit.xml content
|
|
3901
|
+
*/
|
|
3902
|
+
function parseFolderLogicFromAbapGitXml(xmlContent) {
|
|
3903
|
+
const match = /<FOLDER_LOGIC>([^<]+)<\/FOLDER_LOGIC>/i.exec(xmlContent);
|
|
3904
|
+
if (!match) return;
|
|
3905
|
+
const normalized = match[1].trim().toUpperCase();
|
|
3906
|
+
if (normalized === "PREFIX") return "prefix";
|
|
3907
|
+
if (normalized === "FULL") return "full";
|
|
3908
|
+
}
|
|
3909
|
+
/**
|
|
3910
|
+
* Parse STARTING_FOLDER from .abapgit.xml content
|
|
3911
|
+
*/
|
|
3912
|
+
function parseStartingFolderFromAbapGitXml(xmlContent) {
|
|
3913
|
+
const match = /<STARTING_FOLDER>([^<]+)<\/STARTING_FOLDER>/i.exec(xmlContent);
|
|
3914
|
+
return match ? match[1].trim() : void 0;
|
|
3915
|
+
}
|
|
3916
|
+
/**
|
|
3917
|
+
* Parse abapGit repository metadata from .abapgit.xml content
|
|
3918
|
+
*/
|
|
3919
|
+
function parseAbapGitMetadata(xmlContent) {
|
|
3920
|
+
return {
|
|
3921
|
+
folderLogic: parseFolderLogicFromAbapGitXml(xmlContent) ?? "prefix",
|
|
3922
|
+
startingFolder: parseStartingFolderFromAbapGitXml(xmlContent) ?? "/src/"
|
|
3923
|
+
};
|
|
3924
|
+
}
|
|
3925
|
+
/**
|
|
3926
|
+
* Reverse of calculatePackageDir — compute SAP package name from directory path
|
|
3927
|
+
*
|
|
3928
|
+
* Given a directory path relative to the starting folder, the folder logic,
|
|
3929
|
+
* and the root package name, compute the SAP package name.
|
|
3930
|
+
*
|
|
3931
|
+
* PREFIX mode: root 'ZABAPGIT_EXAMPLES' + dir 'clas' → 'ZABAPGIT_EXAMPLES_CLAS'
|
|
3932
|
+
* FULL mode: dir 'zabapgit_examples_clas' → 'ZABAPGIT_EXAMPLES_CLAS'
|
|
3933
|
+
*
|
|
3934
|
+
* @param dirPath - Directory path relative to starting folder
|
|
3935
|
+
* @param folderLogic - Folder logic mode (prefix or full)
|
|
3936
|
+
* @param rootPackage - Root SAP package name
|
|
3937
|
+
* @returns SAP package name
|
|
3938
|
+
*/
|
|
3939
|
+
function resolvePackageFromDir(dirPath, folderLogic, rootPackage) {
|
|
3940
|
+
if (!dirPath || dirPath === "." || dirPath === "/") return rootPackage;
|
|
3941
|
+
const normalized = stripSlashes(dirPath);
|
|
3942
|
+
if (!normalized) return rootPackage;
|
|
3943
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
3944
|
+
if (parts.length === 0) return rootPackage;
|
|
3945
|
+
switch (folderLogic) {
|
|
3946
|
+
case "prefix": {
|
|
3947
|
+
let pkg = rootPackage;
|
|
3948
|
+
for (const part of parts) pkg = pkg + "_" + part.toUpperCase();
|
|
3949
|
+
return pkg;
|
|
3950
|
+
}
|
|
3951
|
+
case "full":
|
|
3952
|
+
case "full-with-root": return parts.at(-1).toUpperCase();
|
|
3953
|
+
default: return rootPackage;
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
/**
|
|
3957
|
+
* Reverse of resolvePackageFromDir — given a SAP package name and the
|
|
3958
|
+
* relative directory of an object, back-derive the root package.
|
|
3959
|
+
*
|
|
3960
|
+
* PREFIX mode: sapPackage 'ZABAPGIT_EXAMPLES_FUGR' + dir 'fugr' → 'ZABAPGIT_EXAMPLES'
|
|
3961
|
+
* FULL mode: cannot derive root (returns undefined)
|
|
3962
|
+
*
|
|
3963
|
+
* @param sapPackage - Actual SAP package name (from GET response)
|
|
3964
|
+
* @param relDir - Directory path relative to starting folder
|
|
3965
|
+
* @param folderLogic - Folder logic mode
|
|
3966
|
+
* @returns Root package name, or undefined if it cannot be derived
|
|
3967
|
+
*/
|
|
3968
|
+
function reverseResolveRootPackage(sapPackage, relDir, folderLogic) {
|
|
3969
|
+
if (!relDir || relDir === "." || relDir === "/") return sapPackage;
|
|
3970
|
+
const normalized = stripSlashes(relDir);
|
|
3971
|
+
if (!normalized) return sapPackage;
|
|
3972
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
3973
|
+
if (parts.length === 0) return sapPackage;
|
|
3974
|
+
switch (folderLogic) {
|
|
3975
|
+
case "prefix": {
|
|
3976
|
+
const suffix = "_" + parts.map((p) => p.toUpperCase()).join("_");
|
|
3977
|
+
if (sapPackage.toUpperCase().endsWith(suffix)) return sapPackage.slice(0, -suffix.length);
|
|
3978
|
+
return;
|
|
3979
|
+
}
|
|
3980
|
+
case "full":
|
|
3981
|
+
case "full-with-root": return;
|
|
3982
|
+
default: return;
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
/**
|
|
3986
|
+
* Parse folder logic from a string value (CLI option or config)
|
|
3987
|
+
*/
|
|
3988
|
+
function parseFolderLogic(value) {
|
|
3989
|
+
if (typeof value !== "string") return;
|
|
3990
|
+
const normalized = value.trim().toLowerCase();
|
|
3991
|
+
if (normalized === "prefix" || normalized === "full" || normalized === "full-with-root") return normalized;
|
|
3992
|
+
}
|
|
3993
|
+
/**
|
|
3994
|
+
* Calculate package directory based on folder logic (for import/serialization)
|
|
3995
|
+
*
|
|
3996
|
+
* @param packagePath - Full package hierarchy from root to current
|
|
3997
|
+
* @param folderLogic - Folder logic mode
|
|
3998
|
+
* @returns Package directory relative to src/
|
|
3999
|
+
*/
|
|
4000
|
+
function calculatePackageDir(packagePath, folderLogic) {
|
|
4001
|
+
if (packagePath.length === 0) return "";
|
|
4002
|
+
switch (folderLogic) {
|
|
4003
|
+
case "prefix": {
|
|
4004
|
+
if (packagePath.length === 1) return "";
|
|
4005
|
+
const parts = [];
|
|
4006
|
+
for (let i = 1; i < packagePath.length; i++) {
|
|
4007
|
+
const fullName = packagePath[i];
|
|
4008
|
+
const prefix = packagePath[i - 1] + "_";
|
|
4009
|
+
const relativeName = fullName.startsWith(prefix) ? fullName.slice(prefix.length) : fullName;
|
|
4010
|
+
parts.push(relativeName.toLowerCase());
|
|
4011
|
+
}
|
|
4012
|
+
return parts.join("/");
|
|
4013
|
+
}
|
|
4014
|
+
case "full": return packagePath.map((p) => p.toLowerCase()).join("/");
|
|
4015
|
+
case "full-with-root": return packagePath.map((p) => p.toLowerCase()).join("/");
|
|
4016
|
+
default: return "";
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
/**
|
|
4020
|
+
* Generate .abapgit.xml repository metadata file
|
|
4021
|
+
*/
|
|
4022
|
+
function generateAbapGitXml(folderLogic) {
|
|
4023
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
4024
|
+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
4025
|
+
<asx:values>
|
|
4026
|
+
<DATA>
|
|
4027
|
+
<MASTER_LANGUAGE>E</MASTER_LANGUAGE>
|
|
4028
|
+
<STARTING_FOLDER>/src/</STARTING_FOLDER>
|
|
4029
|
+
<FOLDER_LOGIC>${folderLogic === "prefix" ? "PREFIX" : "FULL"}</FOLDER_LOGIC>
|
|
4030
|
+
</DATA>
|
|
4031
|
+
</asx:values>
|
|
4032
|
+
</asx:abap>
|
|
4033
|
+
`;
|
|
4034
|
+
}
|
|
4035
|
+
|
|
4036
|
+
//#endregion
|
|
4037
|
+
//#region src/lib/deserializer.ts
|
|
4038
|
+
/**
|
|
4039
|
+
* abapGit file naming convention:
|
|
4040
|
+
* - XML metadata: {name}.{type}.xml (e.g., zcl_myclass.clas.xml)
|
|
4041
|
+
* - Source code: {name}.{type}.abap (e.g., zcl_myclass.clas.abap)
|
|
4042
|
+
* - Source includes: {name}.{type}.{suffix}.abap (e.g., zcl_myclass.clas.testclasses.abap)
|
|
4043
|
+
*/
|
|
4044
|
+
/**
|
|
4045
|
+
* Parse abapGit filename to extract object info
|
|
4046
|
+
*/
|
|
4047
|
+
function parseAbapGitFilename(filename) {
|
|
4048
|
+
const match = filename.match(/^([^.]+)\.([^.]+)(?:\.([^.]+))?\.(\w+)$/);
|
|
4049
|
+
if (!match) return null;
|
|
4050
|
+
const [, name, type, suffixOrExt, extension] = match;
|
|
4051
|
+
if (extension === "xml" || extension === "abap") return {
|
|
4052
|
+
name: name.toUpperCase(),
|
|
4053
|
+
type: type.toUpperCase(),
|
|
4054
|
+
suffix: suffixOrExt && suffixOrExt !== extension ? suffixOrExt : void 0,
|
|
4055
|
+
extension
|
|
4056
|
+
};
|
|
4057
|
+
return null;
|
|
4058
|
+
}
|
|
4059
|
+
/**
|
|
4060
|
+
* Deserialize abapGit files to ADK objects
|
|
4061
|
+
*
|
|
4062
|
+
* True generator - yields objects one at a time as they're discovered.
|
|
4063
|
+
* Resolves packageRef using abapGit folder logic when rootPackage is provided.
|
|
4064
|
+
*
|
|
4065
|
+
* @param fileTree - Virtual file system to read from
|
|
4066
|
+
* @param client - ADT client for creating ADK objects
|
|
4067
|
+
* @param options - Export options (root package, language version, etc.)
|
|
4068
|
+
*/
|
|
4069
|
+
async function* deserialize(fileTree, client, options) {
|
|
4070
|
+
const adk = createAdk(client);
|
|
4071
|
+
let folderLogic = "prefix";
|
|
4072
|
+
let startDir = "";
|
|
4073
|
+
const hasAbapGitXml = await fileTree.exists(".abapgit.xml");
|
|
4074
|
+
if (hasAbapGitXml) try {
|
|
4075
|
+
const meta = parseAbapGitMetadata(await fileTree.read(".abapgit.xml"));
|
|
4076
|
+
folderLogic = meta.folderLogic;
|
|
4077
|
+
startDir = stripSlashes(meta.startingFolder);
|
|
4078
|
+
} catch {}
|
|
4079
|
+
const xmlFiles = await fileTree.glob("**/*.xml");
|
|
4080
|
+
const objectMap = /* @__PURE__ */ new Map();
|
|
4081
|
+
const supportedTypes = new Set(getSupportedTypes().map((t) => t.toLowerCase()));
|
|
4082
|
+
for (const xmlPath of xmlFiles) {
|
|
4083
|
+
if (xmlPath.endsWith(".abapgit.xml")) continue;
|
|
4084
|
+
if (xmlPath.endsWith("package.devc.xml")) continue;
|
|
4085
|
+
const parsed = parseAbapGitFilename(xmlPath.split("/").pop());
|
|
4086
|
+
if (!parsed) continue;
|
|
4087
|
+
if (!supportedTypes.has(parsed.type.toLowerCase())) continue;
|
|
4088
|
+
if (parsed.suffix) continue;
|
|
4089
|
+
const key = `${parsed.name}:${parsed.type}`;
|
|
4090
|
+
if (!objectMap.has(key)) objectMap.set(key, {
|
|
4091
|
+
name: parsed.name,
|
|
4092
|
+
type: parsed.type,
|
|
4093
|
+
sourceFiles: []
|
|
4094
|
+
});
|
|
4095
|
+
const obj = objectMap.get(key);
|
|
4096
|
+
obj.xmlFile = xmlPath;
|
|
4097
|
+
}
|
|
4098
|
+
const abapFiles = await fileTree.glob("**/*.abap");
|
|
4099
|
+
for (const abapPath of abapFiles) {
|
|
4100
|
+
const parsed = parseAbapGitFilename(abapPath.split("/").pop());
|
|
4101
|
+
if (!parsed) continue;
|
|
4102
|
+
const key = `${parsed.name}:${parsed.type}`;
|
|
4103
|
+
const obj = objectMap.get(key);
|
|
4104
|
+
if (obj) obj.sourceFiles.push({
|
|
4105
|
+
path: abapPath,
|
|
4106
|
+
suffix: parsed.suffix
|
|
4107
|
+
});
|
|
4108
|
+
}
|
|
4109
|
+
for (const [, objFiles] of objectMap) {
|
|
4110
|
+
if (!objFiles.xmlFile) continue;
|
|
4111
|
+
const handler = getHandler(objFiles.type);
|
|
4112
|
+
if (!handler) continue;
|
|
4113
|
+
try {
|
|
4114
|
+
const xmlContent = await fileTree.read(objFiles.xmlFile);
|
|
4115
|
+
const values = handler.schema.parse(xmlContent)?.abapGit?.abap?.values ?? {};
|
|
4116
|
+
const sources = {};
|
|
4117
|
+
for (const { path, suffix } of objFiles.sourceFiles) {
|
|
4118
|
+
const content = await fileTree.read(path);
|
|
4119
|
+
const sourceKey = suffix ? handler.suffixToSourceKey?.[suffix] ?? suffix : "main";
|
|
4120
|
+
sources[sourceKey] = content;
|
|
4121
|
+
}
|
|
4122
|
+
const payload = handler.fromAbapGit ? handler.fromAbapGit(values) : { name: objFiles.name };
|
|
4123
|
+
const objectName = payload.name || objFiles.name;
|
|
4124
|
+
const fullData = {
|
|
4125
|
+
...payload,
|
|
4126
|
+
name: objectName
|
|
4127
|
+
};
|
|
4128
|
+
const adkType = typeof payload.type === "string" ? payload.type : objFiles.type;
|
|
4129
|
+
const adkObject = adk.getWithData(fullData, adkType);
|
|
4130
|
+
if (Object.keys(sources).length > 0) if (handler.setSources) handler.setSources(adkObject, sources);
|
|
4131
|
+
else {
|
|
4132
|
+
if (sources["main"]) adkObject._pendingSource = sources["main"];
|
|
4133
|
+
if (Object.keys(sources).length > 1) adkObject._pendingSources = sources;
|
|
4134
|
+
}
|
|
4135
|
+
if (payload.description) adkObject._pendingDescription = payload.description;
|
|
4136
|
+
if (hasAbapGitXml) {
|
|
4137
|
+
const sourceDir = objFiles.xmlFile.split("/").slice(0, -1).join("/");
|
|
4138
|
+
adkObject._relDir = sourceDir.startsWith(startDir) ? sourceDir.slice(startDir.length).replace(/^\/+/, "") : sourceDir;
|
|
4139
|
+
adkObject._folderLogic = folderLogic;
|
|
4140
|
+
}
|
|
4141
|
+
if (options?.rootPackage) {
|
|
4142
|
+
const data = adkObject._data;
|
|
4143
|
+
if (data && !data.packageRef) if (hasAbapGitXml) data.packageRef = { name: resolvePackageFromDir(adkObject._relDir ?? "", folderLogic, options.rootPackage) };
|
|
4144
|
+
else data.packageRef = { name: options.rootPackage };
|
|
4145
|
+
}
|
|
4146
|
+
if (options?.abapLanguageVersion) {
|
|
4147
|
+
const data = adkObject._data;
|
|
4148
|
+
if (data && !data.abapLanguageVersion) data.abapLanguageVersion = abapLangVerToAdt(options.abapLanguageVersion) ?? options.abapLanguageVersion;
|
|
4149
|
+
}
|
|
4150
|
+
yield adkObject;
|
|
4151
|
+
if (objFiles.type === "FUGR" && payload._functions) {
|
|
4152
|
+
const fmDescriptors = extractFunctionDescriptors(payload._functions);
|
|
4153
|
+
const fmSources = adkObject._pendingFmSources;
|
|
4154
|
+
for (const fm of fmDescriptors) try {
|
|
4155
|
+
const fmData = {
|
|
4156
|
+
name: fm.funcName,
|
|
4157
|
+
type: "FUGR/FF",
|
|
4158
|
+
_groupName: objectName,
|
|
4159
|
+
description: fm.shortText ?? "",
|
|
4160
|
+
processingType: fm.processingType,
|
|
4161
|
+
basXMLEnabled: fm.basXMLEnabled
|
|
4162
|
+
};
|
|
4163
|
+
const fmObject = adk.getWithData(fmData, "FUGR/FF");
|
|
4164
|
+
const fmSourceKey = fm.funcName.toLowerCase();
|
|
4165
|
+
const fmSource = fmSources?.[fmSourceKey];
|
|
4166
|
+
if (fmSource) fmObject._pendingSource = fmSource;
|
|
4167
|
+
if (options?.abapLanguageVersion) {
|
|
4168
|
+
const fmObjData = fmObject._data;
|
|
4169
|
+
if (fmObjData && !fmObjData.abapLanguageVersion) fmObjData.abapLanguageVersion = abapLangVerToAdt(options.abapLanguageVersion) ?? options.abapLanguageVersion;
|
|
4170
|
+
}
|
|
4171
|
+
yield fmObject;
|
|
4172
|
+
} catch (fmError) {
|
|
4173
|
+
console.error(`Failed to deserialize FM ${fm.funcName} in FUGR ${objectName}:`, fmError);
|
|
4174
|
+
}
|
|
4175
|
+
}
|
|
4176
|
+
} catch (error) {
|
|
4177
|
+
console.error(`Failed to deserialize ${objFiles.type} ${objFiles.name}:`, error);
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
|
|
4182
|
+
//#endregion
|
|
4183
|
+
//#region src/lib/format-plugin.ts
|
|
4184
|
+
const abapgitFormatPlugin = {
|
|
4185
|
+
id: "abapgit",
|
|
4186
|
+
description: "abapGit serialization format",
|
|
4187
|
+
get supportedTypes() {
|
|
4188
|
+
return getSupportedTypes();
|
|
4189
|
+
},
|
|
4190
|
+
getHandler(type) {
|
|
4191
|
+
return getHandler(type);
|
|
4192
|
+
},
|
|
4193
|
+
parseFilename(filename) {
|
|
4194
|
+
return parseAbapGitFilename(filename) ?? void 0;
|
|
4195
|
+
}
|
|
4196
|
+
};
|
|
4197
|
+
|
|
4198
|
+
//#endregion
|
|
4199
|
+
//#region src/lib/serializer.ts
|
|
4200
|
+
/**
|
|
4201
|
+
* Serialize ADK objects to abapGit format
|
|
4202
|
+
*
|
|
4203
|
+
* This class uses the handler registry to delegate serialization
|
|
4204
|
+
* to type-specific handlers.
|
|
4205
|
+
*/
|
|
4206
|
+
var AbapGitSerializer = class {
|
|
4207
|
+
/**
|
|
4208
|
+
* Serialize a single object (called by plugin API)
|
|
4209
|
+
*/
|
|
4210
|
+
async serializeObjectPublic(obj, targetPath, packageDir) {
|
|
4211
|
+
const fullPackageDir = join(targetPath, "src", packageDir);
|
|
4212
|
+
mkdirSync(fullPackageDir, { recursive: true });
|
|
4213
|
+
const objectType = getTypeForKind(obj.kind) ?? obj.type;
|
|
4214
|
+
const handler = getHandler(objectType);
|
|
4215
|
+
if (!handler) throw new Error(`No handler available for object type: ${objectType} (kind: ${obj.kind})`);
|
|
4216
|
+
const serializedFiles = await handler.serialize(obj);
|
|
4217
|
+
const writtenFiles = [];
|
|
4218
|
+
for (const file of serializedFiles) {
|
|
4219
|
+
const filePath = join(fullPackageDir, file.path);
|
|
4220
|
+
writeFileSync(filePath, file.content, file.encoding ?? "utf8");
|
|
4221
|
+
writtenFiles.push(filePath);
|
|
4222
|
+
}
|
|
4223
|
+
return writtenFiles;
|
|
4224
|
+
}
|
|
4225
|
+
};
|
|
4226
|
+
|
|
4227
|
+
//#endregion
|
|
4228
|
+
//#region src/lib/abapgit.ts
|
|
4229
|
+
const serializer = new AbapGitSerializer();
|
|
4230
|
+
let currentFolderLogic = "prefix";
|
|
4231
|
+
/**
|
|
4232
|
+
* Recursively collect all file paths under a directory.
|
|
4233
|
+
*/
|
|
4234
|
+
function walkDir(dir, results = []) {
|
|
4235
|
+
if (!existsSync(dir)) return results;
|
|
4236
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
4237
|
+
const full = join(dir, entry.name);
|
|
4238
|
+
if (entry.isDirectory()) walkDir(full, results);
|
|
4239
|
+
else results.push(full);
|
|
4240
|
+
}
|
|
4241
|
+
return results;
|
|
4242
|
+
}
|
|
4243
|
+
/**
|
|
4244
|
+
* Lazy per-srcDir file index.
|
|
4245
|
+
*
|
|
4246
|
+
* Maps srcDir → (prefix → [absolute file paths]), where prefix is
|
|
4247
|
+
* `${name}.${type}.` in lower-case. Built at most once per srcDir per
|
|
4248
|
+
* process, so the O(repo-size) directory walk is amortised across all
|
|
4249
|
+
* `format.delete()` calls in a single import run instead of repeated for
|
|
4250
|
+
* every deleted object.
|
|
4251
|
+
*/
|
|
4252
|
+
const srcDirIndexCache = /* @__PURE__ */ new Map();
|
|
4253
|
+
function getOrBuildSrcIndex(srcDir) {
|
|
4254
|
+
const cached = srcDirIndexCache.get(srcDir);
|
|
4255
|
+
if (cached) return cached;
|
|
4256
|
+
const index = /* @__PURE__ */ new Map();
|
|
4257
|
+
for (const filePath of walkDir(srcDir)) {
|
|
4258
|
+
const fname = basename(filePath).toLowerCase();
|
|
4259
|
+
const first = fname.indexOf(".");
|
|
4260
|
+
if (first === -1) continue;
|
|
4261
|
+
const second = fname.indexOf(".", first + 1);
|
|
4262
|
+
if (second === -1) continue;
|
|
4263
|
+
const key = fname.substring(0, second + 1);
|
|
4264
|
+
const bucket = index.get(key);
|
|
4265
|
+
if (bucket) bucket.push(filePath);
|
|
4266
|
+
else index.set(key, [filePath]);
|
|
4267
|
+
}
|
|
4268
|
+
srcDirIndexCache.set(srcDir, index);
|
|
4269
|
+
return index;
|
|
4270
|
+
}
|
|
4271
|
+
/**
|
|
4272
|
+
* Find all abapGit files for a given object name and type.
|
|
4273
|
+
*
|
|
4274
|
+
* abapGit naming convention: `{name}.{type}[.suffix].{ext}`
|
|
4275
|
+
* e.g. `zcl_foo.clas.xml`, `zcl_foo.clas.locals_def.abap`
|
|
4276
|
+
*
|
|
4277
|
+
* Matching is done on the filename base: `{name}.{type}.`. SAP ABAP object
|
|
4278
|
+
* names and types **never contain a dot**, so the prefix is unambiguous —
|
|
4279
|
+
* `ztabl_del.tabl.` cannot accidentally match `ztabl_del_ext.tabl.xml`
|
|
4280
|
+
* because the separator after `ztabl_del` in the prefix is `.` while the
|
|
4281
|
+
* other file has `_ext.`.
|
|
4282
|
+
*
|
|
4283
|
+
* Uses a lazy per-srcDir index so the directory tree is walked at most once
|
|
4284
|
+
* per deletion batch rather than once per object.
|
|
4285
|
+
*/
|
|
4286
|
+
function findObjectFiles(srcDir, name, type) {
|
|
4287
|
+
const prefix = `${name.toLowerCase()}.${type.toLowerCase()}.`;
|
|
4288
|
+
return getOrBuildSrcIndex(srcDir).get(prefix) ?? [];
|
|
4289
|
+
}
|
|
4290
|
+
function readFolderLogicFromExistingRepo(targetPath) {
|
|
4291
|
+
const abapgitXmlPath = join(targetPath, ".abapgit.xml");
|
|
4292
|
+
if (!existsSync(abapgitXmlPath)) return;
|
|
4293
|
+
try {
|
|
4294
|
+
return parseFolderLogicFromAbapGitXml(readFileSync(abapgitXmlPath, "utf-8"));
|
|
4295
|
+
} catch {
|
|
4296
|
+
return;
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
function resolveFolderLogic(context, targetPath) {
|
|
4300
|
+
const cliFolderLogic = parseFolderLogic(context.formatOptions?.folderLogic);
|
|
4301
|
+
if (cliFolderLogic) return cliFolderLogic;
|
|
4302
|
+
const existingRepoFolderLogic = readFolderLogicFromExistingRepo(targetPath);
|
|
4303
|
+
if (existingRepoFolderLogic) return existingRepoFolderLogic;
|
|
4304
|
+
const configuredFolderLogic = parseFolderLogic(context.configFormatOptions?.folderLogic);
|
|
4305
|
+
if (configuredFolderLogic) return configuredFolderLogic;
|
|
4306
|
+
return "prefix";
|
|
4307
|
+
}
|
|
4308
|
+
/**
|
|
4309
|
+
* abapGit Plugin
|
|
4310
|
+
*
|
|
4311
|
+
* Provides import/export of ADK objects to abapGit repository format.
|
|
4312
|
+
*/
|
|
4313
|
+
const abapGitPlugin = createPlugin({
|
|
4314
|
+
name: "abapGit",
|
|
4315
|
+
version: "1.0.0",
|
|
4316
|
+
description: "abapGit format plugin for ADK objects",
|
|
4317
|
+
registry: {
|
|
4318
|
+
isSupported,
|
|
4319
|
+
getSupportedTypes
|
|
4320
|
+
},
|
|
4321
|
+
format: {
|
|
4322
|
+
async import(object, targetPath, context) {
|
|
4323
|
+
try {
|
|
4324
|
+
const objPackage = object.type?.startsWith("DEVC") ? object.name : object.package || object.name || "ROOT";
|
|
4325
|
+
const packagePath = await context.resolvePackagePath(objPackage);
|
|
4326
|
+
const folderLogic = resolveFolderLogic(context, targetPath);
|
|
4327
|
+
currentFolderLogic = folderLogic;
|
|
4328
|
+
const packageDir = calculatePackageDir(packagePath, folderLogic);
|
|
4329
|
+
return {
|
|
4330
|
+
success: true,
|
|
4331
|
+
filesCreated: await serializer.serializeObjectPublic(object, targetPath, packageDir)
|
|
4332
|
+
};
|
|
4333
|
+
} catch (error) {
|
|
4334
|
+
return {
|
|
4335
|
+
success: false,
|
|
4336
|
+
filesCreated: [],
|
|
4337
|
+
errors: [error instanceof Error ? error.message : String(error)]
|
|
4338
|
+
};
|
|
4339
|
+
}
|
|
4340
|
+
},
|
|
4341
|
+
export: (fileTree, client, options) => deserialize(fileTree, client, options),
|
|
4342
|
+
async delete(objectRef, targetPath, _context) {
|
|
4343
|
+
try {
|
|
4344
|
+
const matchedFiles = findObjectFiles(join(targetPath, "src"), objectRef.name, objectRef.type);
|
|
4345
|
+
const filesRemoved = [];
|
|
4346
|
+
const errors = [];
|
|
4347
|
+
for (const filePath of matchedFiles) try {
|
|
4348
|
+
unlinkSync(filePath);
|
|
4349
|
+
filesRemoved.push(relative(targetPath, filePath));
|
|
4350
|
+
} catch (error) {
|
|
4351
|
+
if (error.code === "ENOENT") {
|
|
4352
|
+
filesRemoved.push(relative(targetPath, filePath));
|
|
4353
|
+
continue;
|
|
4354
|
+
}
|
|
4355
|
+
errors.push(error instanceof Error ? `Failed to delete ${relative(targetPath, filePath)}: ${error.message}` : `Failed to delete ${relative(targetPath, filePath)}: ${String(error)}`);
|
|
4356
|
+
}
|
|
4357
|
+
return {
|
|
4358
|
+
success: errors.length === 0,
|
|
4359
|
+
filesRemoved,
|
|
4360
|
+
...errors.length > 0 ? { errors } : {}
|
|
4361
|
+
};
|
|
4362
|
+
} catch (error) {
|
|
4363
|
+
return {
|
|
4364
|
+
success: false,
|
|
4365
|
+
filesRemoved: [],
|
|
4366
|
+
errors: [error instanceof Error ? error.message : String(error)]
|
|
4367
|
+
};
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
},
|
|
4371
|
+
hooks: { async afterImport(targetPath) {
|
|
4372
|
+
mkdirSync(targetPath, { recursive: true });
|
|
4373
|
+
writeFileSync(join(targetPath, ".abapgit.xml"), generateAbapGitXml(currentFolderLogic), "utf-8");
|
|
4374
|
+
} }
|
|
4375
|
+
});
|
|
4376
|
+
|
|
4377
|
+
//#endregion
|
|
4378
|
+
//#region src/lib/filename/adt-uri-to-path.ts
|
|
4379
|
+
/**
|
|
4380
|
+
* Convert an ADT URI to an on-disk abapGit filename.
|
|
4381
|
+
*
|
|
4382
|
+
* abapGit stores objects as `<name>.<type>.<ext>` inside `src/`.
|
|
4383
|
+
* Classes have additional includes serialised as
|
|
4384
|
+
* `<name>.clas.<suffix>.abap`. Function modules become
|
|
4385
|
+
* `<group>.fugr.<fm_name>.abap`. Namespaces are rendered as
|
|
4386
|
+
* `(namespace)name`.
|
|
4387
|
+
*
|
|
4388
|
+
* Returns `null` for URIs we don't recognise; callers may warn or fall
|
|
4389
|
+
* back to a synthetic path.
|
|
4390
|
+
*/
|
|
4391
|
+
/**
|
|
4392
|
+
* Apply abapGit namespace transform: `/MYNS/zcl_foo` → `(myns)zcl_foo`.
|
|
4393
|
+
* Case is lower-cased afterwards; name without namespace returned as-is
|
|
4394
|
+
* (lower-cased).
|
|
4395
|
+
*/
|
|
4396
|
+
function applyNamespace(raw) {
|
|
4397
|
+
const nsMatch = /^\/([^/]+)\/(.*)$/.exec(raw);
|
|
4398
|
+
if (nsMatch) {
|
|
4399
|
+
const [, ns, rest] = nsMatch;
|
|
4400
|
+
return `(${ns.toLowerCase()})${rest.toLowerCase()}`;
|
|
4401
|
+
}
|
|
4402
|
+
return raw.toLowerCase();
|
|
4403
|
+
}
|
|
4404
|
+
function stripFragment(uri) {
|
|
4405
|
+
const hashIndex = uri.indexOf("#");
|
|
4406
|
+
return hashIndex >= 0 ? uri.slice(0, hashIndex) : uri;
|
|
4407
|
+
}
|
|
4408
|
+
const CLASS_INCLUDE_TO_SUFFIX = {
|
|
4409
|
+
testclasses: ABAPGIT_SUFFIX.testclasses,
|
|
4410
|
+
definitions: ABAPGIT_SUFFIX.definitions,
|
|
4411
|
+
implementations: ABAPGIT_SUFFIX.implementations,
|
|
4412
|
+
macros: ABAPGIT_SUFFIX.macros,
|
|
4413
|
+
localtypes: ABAPGIT_SUFFIX.localtypes
|
|
4414
|
+
};
|
|
4415
|
+
const RULES = [
|
|
4416
|
+
{
|
|
4417
|
+
test: /^\/sap\/bc\/adt\/oo\/classes\/([^/]+)\/includes\/([^/]+)$/,
|
|
4418
|
+
build: (m) => {
|
|
4419
|
+
const name = applyNamespace(decodeURIComponent(m[1]));
|
|
4420
|
+
const include = m[2].toLowerCase();
|
|
4421
|
+
const suffix = CLASS_INCLUDE_TO_SUFFIX[include];
|
|
4422
|
+
return suffix ? `src/${name}.clas.${suffix}.abap` : `src/${name}.clas.${include}.abap`;
|
|
4423
|
+
}
|
|
4424
|
+
},
|
|
4425
|
+
{
|
|
4426
|
+
test: /^\/sap\/bc\/adt\/oo\/classes\/([^/]+)\/source\/main$/,
|
|
4427
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.clas.abap`
|
|
4428
|
+
},
|
|
4429
|
+
{
|
|
4430
|
+
test: /^\/sap\/bc\/adt\/oo\/classes\/([^/]+)$/,
|
|
4431
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.clas.abap`
|
|
4432
|
+
},
|
|
4433
|
+
{
|
|
4434
|
+
test: /^\/sap\/bc\/adt\/oo\/interfaces\/([^/]+?)(?:\/source\/main)?$/,
|
|
4435
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.intf.abap`
|
|
4436
|
+
},
|
|
4437
|
+
{
|
|
4438
|
+
test: /^\/sap\/bc\/adt\/programs\/programs\/([^/]+?)(?:\/source\/main)?$/,
|
|
4439
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.prog.abap`
|
|
4440
|
+
},
|
|
4441
|
+
{
|
|
4442
|
+
test: /^\/sap\/bc\/adt\/functions\/groups\/([^/]+)$/,
|
|
4443
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.fugr.xml`
|
|
4444
|
+
},
|
|
4445
|
+
{
|
|
4446
|
+
test: /^\/sap\/bc\/adt\/functions\/groups\/([^/]+)\/fmodules\/([^/]+?)(?:\/source\/main)?$/,
|
|
4447
|
+
build: (m) => {
|
|
4448
|
+
return `src/${applyNamespace(decodeURIComponent(m[1]))}.fugr.${applyNamespace(decodeURIComponent(m[2]))}.abap`;
|
|
4449
|
+
}
|
|
4450
|
+
},
|
|
4451
|
+
{
|
|
4452
|
+
test: /^\/sap\/bc\/adt\/functions\/groups\/([^/]+)\/includes\/([^/]+?)(?:\/source\/main)?$/,
|
|
4453
|
+
build: (m) => {
|
|
4454
|
+
return `src/${applyNamespace(decodeURIComponent(m[1]))}.fugr.${applyNamespace(decodeURIComponent(m[2]))}.abap`;
|
|
4455
|
+
}
|
|
4456
|
+
},
|
|
4457
|
+
{
|
|
4458
|
+
test: /^\/sap\/bc\/adt\/ddic\/ddl\/sources\/([^/]+?)(?:\/source\/main)?$/,
|
|
4459
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.ddls.asddls`
|
|
4460
|
+
},
|
|
4461
|
+
{
|
|
4462
|
+
test: /^\/sap\/bc\/adt\/acm\/dcl\/sources\/([^/]+?)(?:\/source\/main)?$/,
|
|
4463
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.dcls.asdcls`
|
|
4464
|
+
},
|
|
4465
|
+
{
|
|
4466
|
+
test: /^\/sap\/bc\/adt\/bo\/behaviordefinitions\/([^/]+?)(?:\/source\/main)?$/,
|
|
4467
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.bdef.abdl`
|
|
4468
|
+
},
|
|
4469
|
+
{
|
|
4470
|
+
test: /^\/sap\/bc\/adt\/ddic\/srvd\/sources\/([^/]+?)(?:\/source\/main)?$/,
|
|
4471
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.srvd.asrvd`
|
|
4472
|
+
},
|
|
4473
|
+
{
|
|
4474
|
+
test: /^\/sap\/bc\/adt\/businessservices\/bindings\/([^/]+?)(?:\/publishedstates)?$/,
|
|
4475
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.srvb.xml`
|
|
4476
|
+
},
|
|
4477
|
+
{
|
|
4478
|
+
test: /^\/sap\/bc\/adt\/ddic\/domains\/([^/]+)$/,
|
|
4479
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.doma.xml`
|
|
4480
|
+
},
|
|
4481
|
+
{
|
|
4482
|
+
test: /^\/sap\/bc\/adt\/ddic\/dataelements\/([^/]+)$/,
|
|
4483
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.dtel.xml`
|
|
4484
|
+
},
|
|
4485
|
+
{
|
|
4486
|
+
test: /^\/sap\/bc\/adt\/ddic\/structures\/([^/]+)$/,
|
|
4487
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.tabl.xml`
|
|
4488
|
+
},
|
|
4489
|
+
{
|
|
4490
|
+
test: /^\/sap\/bc\/adt\/ddic\/tables\/([^/]+)$/,
|
|
4491
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.tabl.xml`
|
|
4492
|
+
},
|
|
4493
|
+
{
|
|
4494
|
+
test: /^\/sap\/bc\/adt\/packages\/([^/]+)$/,
|
|
4495
|
+
build: (m) => `src/${applyNamespace(decodeURIComponent(m[1]))}.devc.xml`
|
|
4496
|
+
}
|
|
4497
|
+
];
|
|
4498
|
+
/**
|
|
4499
|
+
* Convert an ADT URI to the abapGit on-disk filename (lower-cased,
|
|
4500
|
+
* namespace-aware). Returns `null` when the URI shape is not recognised.
|
|
4501
|
+
*/
|
|
4502
|
+
function adtUriToAbapGitPath(uri) {
|
|
4503
|
+
if (!uri) return null;
|
|
4504
|
+
const clean = stripFragment(uri).trim();
|
|
4505
|
+
for (const rule of RULES) {
|
|
4506
|
+
const m = rule.test.exec(clean);
|
|
4507
|
+
if (m) return rule.build(m);
|
|
4508
|
+
}
|
|
4509
|
+
return null;
|
|
4510
|
+
}
|
|
4511
|
+
|
|
4512
|
+
//#endregion
|
|
4513
|
+
//#region src/index.ts
|
|
4514
|
+
registerFormatPlugin(abapgitFormatPlugin);
|
|
4515
|
+
|
|
4516
|
+
//#endregion
|
|
4517
|
+
export { abapGitPlugin as AbapGitPlugin, abapGitPlugin, abapGitPlugin as default, abapgitFormatPlugin, adtUriToAbapGitPath, createFindingResolver, formatAbapGitXml, formatXmlAttributes, getHandler, getSupportedTypes, isSupported, moveNamespaceToAbap, parseAbapGitFilename, parseAbapGitMetadata, resolvePackageFromDir, reverseResolveRootPackage };
|
|
4518
|
+
//# sourceMappingURL=index.mjs.map
|