@abapify/adt-plugin-abapgit 0.4.1 → 0.4.3
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/README.md +24 -0
- package/dist/index.d.mts +26 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3422 -705
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/xsd/dcls.xsd +11 -0
- package/xsd/ddls.xsd +8 -0
- package/xsd/ddlx.xsd +32 -0
- package/xsd/enqu.xsd +38 -0
- package/xsd/msag.xsd +37 -0
- package/xsd/shlp.xsd +41 -0
- package/xsd/tran.xsd +38 -0
- package/xsd/type.xsd +34 -0
- package/xsd/types/dd25v.xsd +18 -0
- package/xsd/types/dd26v.xsd +22 -0
- package/xsd/types/dd27p.xsd +30 -0
- package/xsd/types/dd28v.xsd +23 -0
- package/xsd/types/dd30v.xsd +20 -0
- package/xsd/types/dd31v.xsd +15 -0
- package/xsd/types/dd32p.xsd +28 -0
- package/xsd/types/dd33v.xsd +22 -0
- package/xsd/types/t100.xsd +20 -0
- package/xsd/types/t100a.xsd +13 -0
- package/xsd/types/tstc.xsd +15 -0
- package/xsd/types/tstcc.xsd +15 -0
- package/xsd/types/tstct.xsd +19 -0
- package/xsd/types/typepool.xsd +12 -0
- package/xsd/types/xslt.xsd +12 -0
- package/xsd/view.xsd +41 -0
- package/xsd/xslt.xsd +34 -0
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { createPlugin, registerFormatPlugin } from "@abapify/adt-plugin";
|
|
1
|
+
import { FormatMaterializationError, createPlugin, registerFormatPlugin } from "@abapify/adt-plugin";
|
|
2
|
+
import { basename, dirname, isAbsolute, join, posix, relative, sep } from "node:path";
|
|
2
3
|
import { AdkClass, AdkDataElement, AdkDomain, AdkFunctionGroup, AdkInterface, AdkPackage, AdkProgram, AdkStructure, AdkTable, AdkTableType, createAdk, getMainType, getTypeForKind } from "@abapify/adk";
|
|
3
4
|
import { typedSchema } from "@abapify/ts-xsd";
|
|
4
5
|
import { parse } from "@abapify/acds";
|
|
5
6
|
import { tablesettings } from "@abapify/adt-schemas";
|
|
6
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "fs";
|
|
7
|
-
import {
|
|
8
|
-
import { createAbapGitResolver as createFindingResolver } from "@abapify/adt-atc";
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { adtUriToAbapGitPath, createAbapGitResolver as createFindingResolver } from "@abapify/adt-atc";
|
|
9
9
|
|
|
10
10
|
//#region src/lib/handlers/xml-format.ts
|
|
11
11
|
/**
|
|
@@ -190,7 +190,8 @@ function createHandler(adkClassOrType, definition) {
|
|
|
190
190
|
serializer: definition.serializer,
|
|
191
191
|
serializer_version: definition.serializer_version
|
|
192
192
|
};
|
|
193
|
-
|
|
193
|
+
const xml = definition.schema.build(fullPayload, { pretty: true });
|
|
194
|
+
return formatAbapGitXml(xml);
|
|
194
195
|
},
|
|
195
196
|
createFile(path, content, encoding) {
|
|
196
197
|
return {
|
|
@@ -212,37 +213,67 @@ function createHandler(adkClassOrType, definition) {
|
|
|
212
213
|
};
|
|
213
214
|
}
|
|
214
215
|
};
|
|
215
|
-
|
|
216
|
+
function resolveXmlFileName(object) {
|
|
217
|
+
if (definition.xmlFileName) return typeof definition.xmlFileName === "function" ? definition.xmlFileName(object, ctx) : definition.xmlFileName;
|
|
218
|
+
return `${ctx.getObjectName(object)}.${fileExtension}.xml`;
|
|
219
|
+
}
|
|
220
|
+
function createExplicitSourceFile(sourceKey, content, suffixBySourceKey, objectName) {
|
|
221
|
+
if (content === void 0) return void 0;
|
|
222
|
+
if (!suffixBySourceKey.has(sourceKey)) throw new FormatMaterializationError("FORMAT_SOURCE_COMPONENT_UNSUPPORTED", `The ${type} format handler cannot map source component "${sourceKey}".`);
|
|
223
|
+
return ctx.createAbapFile(objectName, content, suffixBySourceKey.get(sourceKey));
|
|
224
|
+
}
|
|
225
|
+
function buildExplicitSourceFiles(object, sources) {
|
|
226
|
+
const sourceKeys = Object.keys(sources);
|
|
227
|
+
if (sourceKeys.length === 0) return [];
|
|
228
|
+
if (!definition.getSource && !definition.getSources) throw new FormatMaterializationError("FORMAT_SOURCE_COMPONENT_UNSUPPORTED", `The ${type} format handler does not serialize source components.`);
|
|
229
|
+
const suffixBySourceKey = new Map([["main", void 0], ...Object.entries(definition.suffixToSourceKey ?? {}).map(([suffix, sourceKey]) => [sourceKey, suffix])]);
|
|
216
230
|
const objectName = ctx.getObjectName(object);
|
|
217
231
|
const files = [];
|
|
232
|
+
for (const sourceKey of sourceKeys.sort((left, right) => left.localeCompare(right, "en-US"))) {
|
|
233
|
+
const file = createExplicitSourceFile(sourceKey, sources[sourceKey], suffixBySourceKey, objectName);
|
|
234
|
+
if (file) files.push(file);
|
|
235
|
+
}
|
|
236
|
+
return files;
|
|
237
|
+
}
|
|
238
|
+
async function buildMutableSourceFiles(object) {
|
|
239
|
+
const objectName = ctx.getObjectName(object);
|
|
218
240
|
if (definition.getSources) {
|
|
219
241
|
const rawSources = definition.getSources(object);
|
|
220
|
-
|
|
242
|
+
return (await Promise.all(rawSources.map(async ({ suffix, content }) => ({
|
|
221
243
|
suffix,
|
|
222
244
|
content: await content
|
|
223
|
-
})));
|
|
224
|
-
|
|
225
|
-
|
|
245
|
+
})))).filter(({ content }) => content).map(({ suffix, content }) => ctx.createAbapFile(objectName, content, suffix));
|
|
246
|
+
}
|
|
247
|
+
if (definition.getSource) {
|
|
226
248
|
const source = await definition.getSource(object);
|
|
227
|
-
|
|
249
|
+
return source ? [ctx.createAbapFile(objectName, source)] : [];
|
|
228
250
|
}
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
const defaultSerialize = async (object, options) => {
|
|
254
|
+
const sourceFiles = options?.sources !== void 0 ? buildExplicitSourceFiles(object, options.sources) : await buildMutableSourceFiles(object);
|
|
255
|
+
const xmlFileName = resolveXmlFileName(object);
|
|
229
256
|
const xmlContent = ctx.toAbapGitXml(object);
|
|
230
|
-
|
|
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;
|
|
257
|
+
return [...sourceFiles, ctx.createFile(xmlFileName, xmlContent)];
|
|
235
258
|
};
|
|
236
259
|
const defaultFromAbapGit = definition.fromAbapGit ? (values) => {
|
|
237
260
|
return definition.fromAbapGit(values);
|
|
238
261
|
} : void 0;
|
|
262
|
+
const explicitSupports = definition.supportsExplicitSources;
|
|
263
|
+
const serializeAcceptsOptions = explicitSupports ?? (definition.serialize !== void 0 && definition.serialize.length >= 3);
|
|
264
|
+
const supportsExplicitSources = explicitSupports ?? (definition.getSource !== void 0 || definition.getSources !== void 0 || serializeAcceptsOptions);
|
|
239
265
|
const handler = {
|
|
240
266
|
type,
|
|
241
267
|
fileExtension,
|
|
242
268
|
schema: definition.schema,
|
|
243
269
|
suffixToSourceKey: definition.suffixToSourceKey,
|
|
244
|
-
|
|
270
|
+
supportsExplicitSources,
|
|
271
|
+
serialize: definition.serialize ? async (object, options) => {
|
|
272
|
+
if (serializeAcceptsOptions) return await definition.serialize(object, ctx, options);
|
|
273
|
+
return await definition.serialize(object, ctx);
|
|
274
|
+
} : defaultSerialize,
|
|
245
275
|
fromAbapGit: defaultFromAbapGit,
|
|
276
|
+
fromAffJson: definition.fromAffJson,
|
|
246
277
|
setSources: definition.setSources
|
|
247
278
|
};
|
|
248
279
|
handlerRegistry.set(type, handler);
|
|
@@ -2358,89 +2389,1718 @@ var srvb_default = {
|
|
|
2358
2389
|
};
|
|
2359
2390
|
|
|
2360
2391
|
//#endregion
|
|
2361
|
-
//#region src/schemas/generated/
|
|
2392
|
+
//#region src/schemas/generated/schemas/dcls.ts
|
|
2362
2393
|
/**
|
|
2363
|
-
*
|
|
2364
|
-
*
|
|
2365
|
-
*
|
|
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
|
|
2394
|
+
* Auto-generated schema from XSD
|
|
2395
|
+
*
|
|
2396
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2397
|
+
* Source: abapgit/dcls.xsd
|
|
2373
2398
|
*/
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2399
|
+
var dcls_default = {
|
|
2400
|
+
$xmlns: {
|
|
2401
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2402
|
+
asx: "http://www.sap.com/abapxml"
|
|
2403
|
+
},
|
|
2404
|
+
elementFormDefault: "unqualified",
|
|
2405
|
+
element: [{
|
|
2406
|
+
name: "abapGit",
|
|
2407
|
+
complexType: {
|
|
2408
|
+
sequence: { element: [{
|
|
2409
|
+
name: "abap",
|
|
2410
|
+
type: "DclsAbapType"
|
|
2411
|
+
}] },
|
|
2412
|
+
attribute: [
|
|
2413
|
+
{
|
|
2414
|
+
name: "version",
|
|
2415
|
+
type: "xs:string",
|
|
2416
|
+
use: "required"
|
|
2417
|
+
},
|
|
2418
|
+
{
|
|
2419
|
+
name: "serializer",
|
|
2420
|
+
type: "xs:string",
|
|
2421
|
+
use: "required"
|
|
2422
|
+
},
|
|
2423
|
+
{
|
|
2424
|
+
name: "serializer_version",
|
|
2425
|
+
type: "xs:string",
|
|
2426
|
+
use: "required"
|
|
2427
|
+
}
|
|
2428
|
+
]
|
|
2429
|
+
}
|
|
2430
|
+
}, {
|
|
2431
|
+
name: "Schema",
|
|
2432
|
+
abstract: true
|
|
2433
|
+
}],
|
|
2434
|
+
complexType: [
|
|
2435
|
+
{
|
|
2436
|
+
name: "SkeyType",
|
|
2437
|
+
all: { element: [{
|
|
2438
|
+
name: "TYPE",
|
|
2439
|
+
type: "xs:string",
|
|
2440
|
+
minOccurs: "0"
|
|
2441
|
+
}, {
|
|
2442
|
+
name: "NAME",
|
|
2443
|
+
type: "xs:string",
|
|
2444
|
+
minOccurs: "0"
|
|
2445
|
+
}] }
|
|
2446
|
+
},
|
|
2447
|
+
{
|
|
2448
|
+
name: "DclsValuesType",
|
|
2449
|
+
all: { element: [{
|
|
2450
|
+
name: "SKEY",
|
|
2451
|
+
type: "SkeyType",
|
|
2452
|
+
minOccurs: "0"
|
|
2453
|
+
}] }
|
|
2454
|
+
},
|
|
2455
|
+
{
|
|
2456
|
+
name: "DclsAbapType",
|
|
2457
|
+
sequence: { element: [{
|
|
2458
|
+
name: "values",
|
|
2459
|
+
type: "DclsValuesType"
|
|
2460
|
+
}] },
|
|
2461
|
+
attribute: [{
|
|
2462
|
+
name: "version",
|
|
2463
|
+
type: "xs:string",
|
|
2464
|
+
"default": "1.0"
|
|
2465
|
+
}]
|
|
2466
|
+
},
|
|
2467
|
+
{
|
|
2468
|
+
name: "AbapValuesType",
|
|
2469
|
+
sequence: { element: [{
|
|
2470
|
+
ref: "asx:Schema",
|
|
2471
|
+
minOccurs: "0",
|
|
2472
|
+
maxOccurs: "unbounded"
|
|
2473
|
+
}] }
|
|
2474
|
+
},
|
|
2475
|
+
{
|
|
2476
|
+
name: "AbapType",
|
|
2477
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2478
|
+
attribute: [{
|
|
2479
|
+
name: "version",
|
|
2480
|
+
type: "xs:string",
|
|
2481
|
+
"default": "1.0"
|
|
2482
|
+
}]
|
|
2483
|
+
}
|
|
2484
|
+
]
|
|
2485
|
+
};
|
|
2386
2486
|
|
|
2387
2487
|
//#endregion
|
|
2388
|
-
//#region src/
|
|
2488
|
+
//#region src/schemas/generated/schemas/ddls.ts
|
|
2389
2489
|
/**
|
|
2390
|
-
*
|
|
2490
|
+
* Auto-generated schema from XSD
|
|
2391
2491
|
*
|
|
2392
|
-
*
|
|
2393
|
-
*
|
|
2492
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2493
|
+
* Source: abapgit/ddls.xsd
|
|
2394
2494
|
*/
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2495
|
+
var ddls_default = {
|
|
2496
|
+
$xmlns: {
|
|
2497
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2498
|
+
asx: "http://www.sap.com/abapxml"
|
|
2499
|
+
},
|
|
2500
|
+
elementFormDefault: "unqualified",
|
|
2501
|
+
element: [{
|
|
2502
|
+
name: "abapGit",
|
|
2503
|
+
complexType: {
|
|
2504
|
+
sequence: { element: [{
|
|
2505
|
+
name: "abap",
|
|
2506
|
+
type: "DdlsAbapType"
|
|
2507
|
+
}] },
|
|
2508
|
+
attribute: [
|
|
2509
|
+
{
|
|
2510
|
+
name: "version",
|
|
2511
|
+
type: "xs:string",
|
|
2512
|
+
use: "required"
|
|
2513
|
+
},
|
|
2514
|
+
{
|
|
2515
|
+
name: "serializer",
|
|
2516
|
+
type: "xs:string",
|
|
2517
|
+
use: "required"
|
|
2518
|
+
},
|
|
2519
|
+
{
|
|
2520
|
+
name: "serializer_version",
|
|
2521
|
+
type: "xs:string",
|
|
2522
|
+
use: "required"
|
|
2523
|
+
}
|
|
2524
|
+
]
|
|
2525
|
+
}
|
|
2526
|
+
}, {
|
|
2527
|
+
name: "Schema",
|
|
2528
|
+
abstract: true
|
|
2529
|
+
}],
|
|
2530
|
+
complexType: [
|
|
2531
|
+
{
|
|
2532
|
+
name: "SkeyType",
|
|
2533
|
+
all: { element: [{
|
|
2534
|
+
name: "TYPE",
|
|
2535
|
+
type: "xs:string",
|
|
2536
|
+
minOccurs: "0"
|
|
2537
|
+
}, {
|
|
2538
|
+
name: "NAME",
|
|
2539
|
+
type: "xs:string",
|
|
2540
|
+
minOccurs: "0"
|
|
2541
|
+
}] }
|
|
2542
|
+
},
|
|
2543
|
+
{
|
|
2544
|
+
name: "DdlsValuesType",
|
|
2545
|
+
all: { element: [{
|
|
2546
|
+
name: "SKEY",
|
|
2547
|
+
type: "SkeyType",
|
|
2548
|
+
minOccurs: "0"
|
|
2549
|
+
}] }
|
|
2550
|
+
},
|
|
2551
|
+
{
|
|
2552
|
+
name: "DdlsAbapType",
|
|
2553
|
+
sequence: { element: [{
|
|
2554
|
+
name: "values",
|
|
2555
|
+
type: "DdlsValuesType"
|
|
2556
|
+
}] },
|
|
2557
|
+
attribute: [{
|
|
2558
|
+
name: "version",
|
|
2559
|
+
type: "xs:string",
|
|
2560
|
+
"default": "1.0"
|
|
2561
|
+
}]
|
|
2562
|
+
},
|
|
2563
|
+
{
|
|
2564
|
+
name: "AbapValuesType",
|
|
2565
|
+
sequence: { element: [{
|
|
2566
|
+
ref: "asx:Schema",
|
|
2567
|
+
minOccurs: "0",
|
|
2568
|
+
maxOccurs: "unbounded"
|
|
2569
|
+
}] }
|
|
2570
|
+
},
|
|
2571
|
+
{
|
|
2572
|
+
name: "AbapType",
|
|
2573
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2574
|
+
attribute: [{
|
|
2575
|
+
name: "version",
|
|
2576
|
+
type: "xs:string",
|
|
2577
|
+
"default": "1.0"
|
|
2578
|
+
}]
|
|
2579
|
+
}
|
|
2580
|
+
]
|
|
2426
2581
|
};
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
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
|
-
}
|
|
2582
|
+
|
|
2583
|
+
//#endregion
|
|
2584
|
+
//#region src/schemas/generated/schemas/ddlx.ts
|
|
2438
2585
|
/**
|
|
2439
|
-
*
|
|
2440
|
-
*
|
|
2586
|
+
* Auto-generated schema from XSD
|
|
2587
|
+
*
|
|
2588
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2589
|
+
* Source: abapgit/ddlx.xsd
|
|
2441
2590
|
*/
|
|
2442
|
-
|
|
2443
|
-
|
|
2591
|
+
var ddlx_default = {
|
|
2592
|
+
$xmlns: {
|
|
2593
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2594
|
+
asx: "http://www.sap.com/abapxml"
|
|
2595
|
+
},
|
|
2596
|
+
elementFormDefault: "unqualified",
|
|
2597
|
+
element: [{
|
|
2598
|
+
name: "abapGit",
|
|
2599
|
+
complexType: {
|
|
2600
|
+
sequence: { element: [{
|
|
2601
|
+
name: "abap",
|
|
2602
|
+
type: "DdlxAbapType"
|
|
2603
|
+
}] },
|
|
2604
|
+
attribute: [
|
|
2605
|
+
{
|
|
2606
|
+
name: "version",
|
|
2607
|
+
type: "xs:string",
|
|
2608
|
+
use: "required"
|
|
2609
|
+
},
|
|
2610
|
+
{
|
|
2611
|
+
name: "serializer",
|
|
2612
|
+
type: "xs:string",
|
|
2613
|
+
use: "required"
|
|
2614
|
+
},
|
|
2615
|
+
{
|
|
2616
|
+
name: "serializer_version",
|
|
2617
|
+
type: "xs:string",
|
|
2618
|
+
use: "required"
|
|
2619
|
+
}
|
|
2620
|
+
]
|
|
2621
|
+
}
|
|
2622
|
+
}, {
|
|
2623
|
+
name: "Schema",
|
|
2624
|
+
abstract: true
|
|
2625
|
+
}],
|
|
2626
|
+
complexType: [
|
|
2627
|
+
{
|
|
2628
|
+
name: "SkeyType",
|
|
2629
|
+
all: { element: [{
|
|
2630
|
+
name: "TYPE",
|
|
2631
|
+
type: "xs:string",
|
|
2632
|
+
minOccurs: "0"
|
|
2633
|
+
}, {
|
|
2634
|
+
name: "NAME",
|
|
2635
|
+
type: "xs:string",
|
|
2636
|
+
minOccurs: "0"
|
|
2637
|
+
}] }
|
|
2638
|
+
},
|
|
2639
|
+
{
|
|
2640
|
+
name: "DdlxValuesType",
|
|
2641
|
+
all: { element: [{
|
|
2642
|
+
name: "SKEY",
|
|
2643
|
+
type: "SkeyType",
|
|
2644
|
+
minOccurs: "0"
|
|
2645
|
+
}] }
|
|
2646
|
+
},
|
|
2647
|
+
{
|
|
2648
|
+
name: "DdlxAbapType",
|
|
2649
|
+
sequence: { element: [{
|
|
2650
|
+
name: "values",
|
|
2651
|
+
type: "DdlxValuesType"
|
|
2652
|
+
}] },
|
|
2653
|
+
attribute: [{
|
|
2654
|
+
name: "version",
|
|
2655
|
+
type: "xs:string",
|
|
2656
|
+
"default": "1.0"
|
|
2657
|
+
}]
|
|
2658
|
+
},
|
|
2659
|
+
{
|
|
2660
|
+
name: "AbapValuesType",
|
|
2661
|
+
sequence: { element: [{
|
|
2662
|
+
ref: "asx:Schema",
|
|
2663
|
+
minOccurs: "0",
|
|
2664
|
+
maxOccurs: "unbounded"
|
|
2665
|
+
}] }
|
|
2666
|
+
},
|
|
2667
|
+
{
|
|
2668
|
+
name: "AbapType",
|
|
2669
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2670
|
+
attribute: [{
|
|
2671
|
+
name: "version",
|
|
2672
|
+
type: "xs:string",
|
|
2673
|
+
"default": "1.0"
|
|
2674
|
+
}]
|
|
2675
|
+
}
|
|
2676
|
+
]
|
|
2677
|
+
};
|
|
2678
|
+
|
|
2679
|
+
//#endregion
|
|
2680
|
+
//#region src/schemas/generated/schemas/msag.ts
|
|
2681
|
+
/**
|
|
2682
|
+
* Auto-generated schema from XSD
|
|
2683
|
+
*
|
|
2684
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2685
|
+
* Source: abapgit/msag.xsd
|
|
2686
|
+
*/
|
|
2687
|
+
var msag_default = {
|
|
2688
|
+
$xmlns: {
|
|
2689
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2690
|
+
asx: "http://www.sap.com/abapxml"
|
|
2691
|
+
},
|
|
2692
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
2693
|
+
elementFormDefault: "unqualified",
|
|
2694
|
+
element: [
|
|
2695
|
+
{
|
|
2696
|
+
name: "abapGit",
|
|
2697
|
+
complexType: {
|
|
2698
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
2699
|
+
attribute: [
|
|
2700
|
+
{
|
|
2701
|
+
name: "version",
|
|
2702
|
+
type: "xs:string",
|
|
2703
|
+
use: "required"
|
|
2704
|
+
},
|
|
2705
|
+
{
|
|
2706
|
+
name: "serializer",
|
|
2707
|
+
type: "xs:string",
|
|
2708
|
+
use: "required"
|
|
2709
|
+
},
|
|
2710
|
+
{
|
|
2711
|
+
name: "serializer_version",
|
|
2712
|
+
type: "xs:string",
|
|
2713
|
+
use: "required"
|
|
2714
|
+
}
|
|
2715
|
+
]
|
|
2716
|
+
}
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
name: "Schema",
|
|
2720
|
+
abstract: true
|
|
2721
|
+
},
|
|
2722
|
+
{
|
|
2723
|
+
name: "values",
|
|
2724
|
+
type: "asx:AbapValuesType"
|
|
2725
|
+
},
|
|
2726
|
+
{
|
|
2727
|
+
name: "abap",
|
|
2728
|
+
type: "asx:AbapType"
|
|
2729
|
+
}
|
|
2730
|
+
],
|
|
2731
|
+
complexType: [
|
|
2732
|
+
{
|
|
2733
|
+
name: "AbapValuesType",
|
|
2734
|
+
all: { element: [{
|
|
2735
|
+
name: "T100A",
|
|
2736
|
+
type: "asx:T100aType",
|
|
2737
|
+
minOccurs: "0"
|
|
2738
|
+
}, {
|
|
2739
|
+
name: "T100",
|
|
2740
|
+
type: "asx:T100TabType",
|
|
2741
|
+
minOccurs: "0"
|
|
2742
|
+
}] }
|
|
2743
|
+
},
|
|
2744
|
+
{
|
|
2745
|
+
name: "T100aType",
|
|
2746
|
+
all: { element: [
|
|
2747
|
+
{
|
|
2748
|
+
name: "ARBGB",
|
|
2749
|
+
type: "xs:string"
|
|
2750
|
+
},
|
|
2751
|
+
{
|
|
2752
|
+
name: "MASTERLANG",
|
|
2753
|
+
type: "xs:string",
|
|
2754
|
+
minOccurs: "0"
|
|
2755
|
+
},
|
|
2756
|
+
{
|
|
2757
|
+
name: "STEXT",
|
|
2758
|
+
type: "xs:string",
|
|
2759
|
+
minOccurs: "0"
|
|
2760
|
+
}
|
|
2761
|
+
] }
|
|
2762
|
+
},
|
|
2763
|
+
{
|
|
2764
|
+
name: "T100Type",
|
|
2765
|
+
sequence: { element: [
|
|
2766
|
+
{
|
|
2767
|
+
name: "SPRSL",
|
|
2768
|
+
type: "xs:string",
|
|
2769
|
+
minOccurs: "0"
|
|
2770
|
+
},
|
|
2771
|
+
{
|
|
2772
|
+
name: "ARBGB",
|
|
2773
|
+
type: "xs:string",
|
|
2774
|
+
minOccurs: "0"
|
|
2775
|
+
},
|
|
2776
|
+
{
|
|
2777
|
+
name: "MSGNR",
|
|
2778
|
+
type: "xs:string",
|
|
2779
|
+
minOccurs: "0"
|
|
2780
|
+
},
|
|
2781
|
+
{
|
|
2782
|
+
name: "TEXT",
|
|
2783
|
+
type: "xs:string",
|
|
2784
|
+
minOccurs: "0"
|
|
2785
|
+
}
|
|
2786
|
+
] }
|
|
2787
|
+
},
|
|
2788
|
+
{
|
|
2789
|
+
name: "T100TabType",
|
|
2790
|
+
sequence: { element: [{
|
|
2791
|
+
name: "item",
|
|
2792
|
+
type: "T100Type",
|
|
2793
|
+
minOccurs: "0",
|
|
2794
|
+
maxOccurs: "unbounded"
|
|
2795
|
+
}] }
|
|
2796
|
+
},
|
|
2797
|
+
{
|
|
2798
|
+
name: "AbapType",
|
|
2799
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
2800
|
+
attribute: [{
|
|
2801
|
+
name: "version",
|
|
2802
|
+
type: "xs:string",
|
|
2803
|
+
"default": "1.0"
|
|
2804
|
+
}]
|
|
2805
|
+
}
|
|
2806
|
+
]
|
|
2807
|
+
};
|
|
2808
|
+
|
|
2809
|
+
//#endregion
|
|
2810
|
+
//#region src/schemas/generated/schemas/view.ts
|
|
2811
|
+
/**
|
|
2812
|
+
* Auto-generated schema from XSD
|
|
2813
|
+
*
|
|
2814
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
2815
|
+
* Source: abapgit/view.xsd
|
|
2816
|
+
*/
|
|
2817
|
+
var view_default = {
|
|
2818
|
+
$xmlns: {
|
|
2819
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
2820
|
+
asx: "http://www.sap.com/abapxml"
|
|
2821
|
+
},
|
|
2822
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
2823
|
+
elementFormDefault: "unqualified",
|
|
2824
|
+
element: [
|
|
2825
|
+
{
|
|
2826
|
+
name: "abapGit",
|
|
2827
|
+
complexType: {
|
|
2828
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
2829
|
+
attribute: [
|
|
2830
|
+
{
|
|
2831
|
+
name: "version",
|
|
2832
|
+
type: "xs:string",
|
|
2833
|
+
use: "required"
|
|
2834
|
+
},
|
|
2835
|
+
{
|
|
2836
|
+
name: "serializer",
|
|
2837
|
+
type: "xs:string",
|
|
2838
|
+
use: "required"
|
|
2839
|
+
},
|
|
2840
|
+
{
|
|
2841
|
+
name: "serializer_version",
|
|
2842
|
+
type: "xs:string",
|
|
2843
|
+
use: "required"
|
|
2844
|
+
}
|
|
2845
|
+
]
|
|
2846
|
+
}
|
|
2847
|
+
},
|
|
2848
|
+
{
|
|
2849
|
+
name: "Schema",
|
|
2850
|
+
abstract: true
|
|
2851
|
+
},
|
|
2852
|
+
{
|
|
2853
|
+
name: "values",
|
|
2854
|
+
type: "asx:AbapValuesType"
|
|
2855
|
+
},
|
|
2856
|
+
{
|
|
2857
|
+
name: "abap",
|
|
2858
|
+
type: "asx:AbapType"
|
|
2859
|
+
}
|
|
2860
|
+
],
|
|
2861
|
+
complexType: [
|
|
2862
|
+
{
|
|
2863
|
+
name: "AbapValuesType",
|
|
2864
|
+
all: { element: [
|
|
2865
|
+
{
|
|
2866
|
+
name: "DD25V",
|
|
2867
|
+
type: "asx:Dd25vType",
|
|
2868
|
+
minOccurs: "0"
|
|
2869
|
+
},
|
|
2870
|
+
{
|
|
2871
|
+
name: "DD26V_TABLE",
|
|
2872
|
+
type: "asx:Dd26vTabType",
|
|
2873
|
+
minOccurs: "0"
|
|
2874
|
+
},
|
|
2875
|
+
{
|
|
2876
|
+
name: "DD27P_TABLE",
|
|
2877
|
+
type: "asx:Dd27pTabType",
|
|
2878
|
+
minOccurs: "0"
|
|
2879
|
+
},
|
|
2880
|
+
{
|
|
2881
|
+
name: "DD28V_TABLE",
|
|
2882
|
+
type: "asx:Dd28vTabType",
|
|
2883
|
+
minOccurs: "0"
|
|
2884
|
+
}
|
|
2885
|
+
] }
|
|
2886
|
+
},
|
|
2887
|
+
{
|
|
2888
|
+
name: "Dd25vType",
|
|
2889
|
+
all: { element: [
|
|
2890
|
+
{
|
|
2891
|
+
name: "VIEWNAME",
|
|
2892
|
+
type: "xs:string"
|
|
2893
|
+
},
|
|
2894
|
+
{
|
|
2895
|
+
name: "DDLANGUAGE",
|
|
2896
|
+
type: "xs:string",
|
|
2897
|
+
minOccurs: "0"
|
|
2898
|
+
},
|
|
2899
|
+
{
|
|
2900
|
+
name: "DDTEXT",
|
|
2901
|
+
type: "xs:string",
|
|
2902
|
+
minOccurs: "0"
|
|
2903
|
+
},
|
|
2904
|
+
{
|
|
2905
|
+
name: "VIEWCLASS",
|
|
2906
|
+
type: "xs:string",
|
|
2907
|
+
minOccurs: "0"
|
|
2908
|
+
},
|
|
2909
|
+
{
|
|
2910
|
+
name: "ROOTTAB",
|
|
2911
|
+
type: "xs:string",
|
|
2912
|
+
minOccurs: "0"
|
|
2913
|
+
},
|
|
2914
|
+
{
|
|
2915
|
+
name: "ROOTFIELD",
|
|
2916
|
+
type: "xs:string",
|
|
2917
|
+
minOccurs: "0"
|
|
2918
|
+
},
|
|
2919
|
+
{
|
|
2920
|
+
name: "ACTFLAG",
|
|
2921
|
+
type: "xs:string",
|
|
2922
|
+
minOccurs: "0"
|
|
2923
|
+
},
|
|
2924
|
+
{
|
|
2925
|
+
name: "MULTITAB",
|
|
2926
|
+
type: "xs:string",
|
|
2927
|
+
minOccurs: "0"
|
|
2928
|
+
}
|
|
2929
|
+
] }
|
|
2930
|
+
},
|
|
2931
|
+
{
|
|
2932
|
+
name: "Dd26vType",
|
|
2933
|
+
sequence: { element: [
|
|
2934
|
+
{
|
|
2935
|
+
name: "VIEWNAME",
|
|
2936
|
+
type: "xs:string",
|
|
2937
|
+
minOccurs: "0"
|
|
2938
|
+
},
|
|
2939
|
+
{
|
|
2940
|
+
name: "TABNAME",
|
|
2941
|
+
type: "xs:string",
|
|
2942
|
+
minOccurs: "0"
|
|
2943
|
+
},
|
|
2944
|
+
{
|
|
2945
|
+
name: "TABPOS",
|
|
2946
|
+
type: "xs:string",
|
|
2947
|
+
minOccurs: "0"
|
|
2948
|
+
},
|
|
2949
|
+
{
|
|
2950
|
+
name: "FVIEWNAME",
|
|
2951
|
+
type: "xs:string",
|
|
2952
|
+
minOccurs: "0"
|
|
2953
|
+
},
|
|
2954
|
+
{
|
|
2955
|
+
name: "FFIELDNAME",
|
|
2956
|
+
type: "xs:string",
|
|
2957
|
+
minOccurs: "0"
|
|
2958
|
+
},
|
|
2959
|
+
{
|
|
2960
|
+
name: "READONLY",
|
|
2961
|
+
type: "xs:string",
|
|
2962
|
+
minOccurs: "0"
|
|
2963
|
+
}
|
|
2964
|
+
] }
|
|
2965
|
+
},
|
|
2966
|
+
{
|
|
2967
|
+
name: "Dd26vTabType",
|
|
2968
|
+
sequence: { element: [{
|
|
2969
|
+
name: "item",
|
|
2970
|
+
type: "Dd26vType",
|
|
2971
|
+
minOccurs: "0",
|
|
2972
|
+
maxOccurs: "unbounded"
|
|
2973
|
+
}] }
|
|
2974
|
+
},
|
|
2975
|
+
{
|
|
2976
|
+
name: "Dd27pType",
|
|
2977
|
+
sequence: { element: [
|
|
2978
|
+
{
|
|
2979
|
+
name: "VIEWNAME",
|
|
2980
|
+
type: "xs:string",
|
|
2981
|
+
minOccurs: "0"
|
|
2982
|
+
},
|
|
2983
|
+
{
|
|
2984
|
+
name: "VIEWFIELD",
|
|
2985
|
+
type: "xs:string",
|
|
2986
|
+
minOccurs: "0"
|
|
2987
|
+
},
|
|
2988
|
+
{
|
|
2989
|
+
name: "TABNAME",
|
|
2990
|
+
type: "xs:string",
|
|
2991
|
+
minOccurs: "0"
|
|
2992
|
+
},
|
|
2993
|
+
{
|
|
2994
|
+
name: "FIELDNAME",
|
|
2995
|
+
type: "xs:string",
|
|
2996
|
+
minOccurs: "0"
|
|
2997
|
+
},
|
|
2998
|
+
{
|
|
2999
|
+
name: "KEYFLAG",
|
|
3000
|
+
type: "xs:string",
|
|
3001
|
+
minOccurs: "0"
|
|
3002
|
+
},
|
|
3003
|
+
{
|
|
3004
|
+
name: "READONLY",
|
|
3005
|
+
type: "xs:string",
|
|
3006
|
+
minOccurs: "0"
|
|
3007
|
+
},
|
|
3008
|
+
{
|
|
3009
|
+
name: "ROLLNAME",
|
|
3010
|
+
type: "xs:string",
|
|
3011
|
+
minOccurs: "0"
|
|
3012
|
+
},
|
|
3013
|
+
{
|
|
3014
|
+
name: "CHECKTABLE",
|
|
3015
|
+
type: "xs:string",
|
|
3016
|
+
minOccurs: "0"
|
|
3017
|
+
},
|
|
3018
|
+
{
|
|
3019
|
+
name: "LOGFLAG",
|
|
3020
|
+
type: "xs:string",
|
|
3021
|
+
minOccurs: "0"
|
|
3022
|
+
},
|
|
3023
|
+
{
|
|
3024
|
+
name: "REFTABLE",
|
|
3025
|
+
type: "xs:string",
|
|
3026
|
+
minOccurs: "0"
|
|
3027
|
+
},
|
|
3028
|
+
{
|
|
3029
|
+
name: "REFFIELD",
|
|
3030
|
+
type: "xs:string",
|
|
3031
|
+
minOccurs: "0"
|
|
3032
|
+
},
|
|
3033
|
+
{
|
|
3034
|
+
name: "OUTPUTLEN",
|
|
3035
|
+
type: "xs:string",
|
|
3036
|
+
minOccurs: "0"
|
|
3037
|
+
},
|
|
3038
|
+
{
|
|
3039
|
+
name: "CONVEXIT",
|
|
3040
|
+
type: "xs:string",
|
|
3041
|
+
minOccurs: "0"
|
|
3042
|
+
},
|
|
3043
|
+
{
|
|
3044
|
+
name: "DDTEXT",
|
|
3045
|
+
type: "xs:string",
|
|
3046
|
+
minOccurs: "0"
|
|
3047
|
+
}
|
|
3048
|
+
] }
|
|
3049
|
+
},
|
|
3050
|
+
{
|
|
3051
|
+
name: "Dd27pTabType",
|
|
3052
|
+
sequence: { element: [{
|
|
3053
|
+
name: "item",
|
|
3054
|
+
type: "Dd27pType",
|
|
3055
|
+
minOccurs: "0",
|
|
3056
|
+
maxOccurs: "unbounded"
|
|
3057
|
+
}] }
|
|
3058
|
+
},
|
|
3059
|
+
{
|
|
3060
|
+
name: "Dd28vType",
|
|
3061
|
+
sequence: { element: [
|
|
3062
|
+
{
|
|
3063
|
+
name: "VIEWNAME",
|
|
3064
|
+
type: "xs:string",
|
|
3065
|
+
minOccurs: "0"
|
|
3066
|
+
},
|
|
3067
|
+
{
|
|
3068
|
+
name: "ANDOR",
|
|
3069
|
+
type: "xs:string",
|
|
3070
|
+
minOccurs: "0"
|
|
3071
|
+
},
|
|
3072
|
+
{
|
|
3073
|
+
name: "LEFTBRACKET",
|
|
3074
|
+
type: "xs:string",
|
|
3075
|
+
minOccurs: "0"
|
|
3076
|
+
},
|
|
3077
|
+
{
|
|
3078
|
+
name: "FIELDNAME",
|
|
3079
|
+
type: "xs:string",
|
|
3080
|
+
minOccurs: "0"
|
|
3081
|
+
},
|
|
3082
|
+
{
|
|
3083
|
+
name: "OPERATOR",
|
|
3084
|
+
type: "xs:string",
|
|
3085
|
+
minOccurs: "0"
|
|
3086
|
+
},
|
|
3087
|
+
{
|
|
3088
|
+
name: "CONST_VALUE",
|
|
3089
|
+
type: "xs:string",
|
|
3090
|
+
minOccurs: "0"
|
|
3091
|
+
},
|
|
3092
|
+
{
|
|
3093
|
+
name: "RIGHTBRACKET",
|
|
3094
|
+
type: "xs:string",
|
|
3095
|
+
minOccurs: "0"
|
|
3096
|
+
}
|
|
3097
|
+
] }
|
|
3098
|
+
},
|
|
3099
|
+
{
|
|
3100
|
+
name: "Dd28vTabType",
|
|
3101
|
+
sequence: { element: [{
|
|
3102
|
+
name: "item",
|
|
3103
|
+
type: "Dd28vType",
|
|
3104
|
+
minOccurs: "0",
|
|
3105
|
+
maxOccurs: "unbounded"
|
|
3106
|
+
}] }
|
|
3107
|
+
},
|
|
3108
|
+
{
|
|
3109
|
+
name: "AbapType",
|
|
3110
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
3111
|
+
attribute: [{
|
|
3112
|
+
name: "version",
|
|
3113
|
+
type: "xs:string",
|
|
3114
|
+
"default": "1.0"
|
|
3115
|
+
}]
|
|
3116
|
+
}
|
|
3117
|
+
]
|
|
3118
|
+
};
|
|
3119
|
+
|
|
3120
|
+
//#endregion
|
|
3121
|
+
//#region src/schemas/generated/schemas/enqu.ts
|
|
3122
|
+
/**
|
|
3123
|
+
* Auto-generated schema from XSD
|
|
3124
|
+
*
|
|
3125
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
3126
|
+
* Source: abapgit/enqu.xsd
|
|
3127
|
+
*/
|
|
3128
|
+
var enqu_default = {
|
|
3129
|
+
$xmlns: {
|
|
3130
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
3131
|
+
asx: "http://www.sap.com/abapxml"
|
|
3132
|
+
},
|
|
3133
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
3134
|
+
elementFormDefault: "unqualified",
|
|
3135
|
+
element: [
|
|
3136
|
+
{
|
|
3137
|
+
name: "abapGit",
|
|
3138
|
+
complexType: {
|
|
3139
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
3140
|
+
attribute: [
|
|
3141
|
+
{
|
|
3142
|
+
name: "version",
|
|
3143
|
+
type: "xs:string",
|
|
3144
|
+
use: "required"
|
|
3145
|
+
},
|
|
3146
|
+
{
|
|
3147
|
+
name: "serializer",
|
|
3148
|
+
type: "xs:string",
|
|
3149
|
+
use: "required"
|
|
3150
|
+
},
|
|
3151
|
+
{
|
|
3152
|
+
name: "serializer_version",
|
|
3153
|
+
type: "xs:string",
|
|
3154
|
+
use: "required"
|
|
3155
|
+
}
|
|
3156
|
+
]
|
|
3157
|
+
}
|
|
3158
|
+
},
|
|
3159
|
+
{
|
|
3160
|
+
name: "Schema",
|
|
3161
|
+
abstract: true
|
|
3162
|
+
},
|
|
3163
|
+
{
|
|
3164
|
+
name: "values",
|
|
3165
|
+
type: "asx:AbapValuesType"
|
|
3166
|
+
},
|
|
3167
|
+
{
|
|
3168
|
+
name: "abap",
|
|
3169
|
+
type: "asx:AbapType"
|
|
3170
|
+
}
|
|
3171
|
+
],
|
|
3172
|
+
complexType: [
|
|
3173
|
+
{
|
|
3174
|
+
name: "AbapValuesType",
|
|
3175
|
+
all: { element: [
|
|
3176
|
+
{
|
|
3177
|
+
name: "DD25V",
|
|
3178
|
+
type: "asx:Dd25vType",
|
|
3179
|
+
minOccurs: "0"
|
|
3180
|
+
},
|
|
3181
|
+
{
|
|
3182
|
+
name: "DD26V_TABLE",
|
|
3183
|
+
type: "asx:Dd26vTabType",
|
|
3184
|
+
minOccurs: "0"
|
|
3185
|
+
},
|
|
3186
|
+
{
|
|
3187
|
+
name: "DD27P_TABLE",
|
|
3188
|
+
type: "asx:Dd27pTabType",
|
|
3189
|
+
minOccurs: "0"
|
|
3190
|
+
}
|
|
3191
|
+
] }
|
|
3192
|
+
},
|
|
3193
|
+
{
|
|
3194
|
+
name: "Dd25vType",
|
|
3195
|
+
all: { element: [
|
|
3196
|
+
{
|
|
3197
|
+
name: "VIEWNAME",
|
|
3198
|
+
type: "xs:string"
|
|
3199
|
+
},
|
|
3200
|
+
{
|
|
3201
|
+
name: "DDLANGUAGE",
|
|
3202
|
+
type: "xs:string",
|
|
3203
|
+
minOccurs: "0"
|
|
3204
|
+
},
|
|
3205
|
+
{
|
|
3206
|
+
name: "DDTEXT",
|
|
3207
|
+
type: "xs:string",
|
|
3208
|
+
minOccurs: "0"
|
|
3209
|
+
},
|
|
3210
|
+
{
|
|
3211
|
+
name: "VIEWCLASS",
|
|
3212
|
+
type: "xs:string",
|
|
3213
|
+
minOccurs: "0"
|
|
3214
|
+
},
|
|
3215
|
+
{
|
|
3216
|
+
name: "ROOTTAB",
|
|
3217
|
+
type: "xs:string",
|
|
3218
|
+
minOccurs: "0"
|
|
3219
|
+
},
|
|
3220
|
+
{
|
|
3221
|
+
name: "ROOTFIELD",
|
|
3222
|
+
type: "xs:string",
|
|
3223
|
+
minOccurs: "0"
|
|
3224
|
+
},
|
|
3225
|
+
{
|
|
3226
|
+
name: "ACTFLAG",
|
|
3227
|
+
type: "xs:string",
|
|
3228
|
+
minOccurs: "0"
|
|
3229
|
+
},
|
|
3230
|
+
{
|
|
3231
|
+
name: "MULTITAB",
|
|
3232
|
+
type: "xs:string",
|
|
3233
|
+
minOccurs: "0"
|
|
3234
|
+
}
|
|
3235
|
+
] }
|
|
3236
|
+
},
|
|
3237
|
+
{
|
|
3238
|
+
name: "Dd26vType",
|
|
3239
|
+
sequence: { element: [
|
|
3240
|
+
{
|
|
3241
|
+
name: "VIEWNAME",
|
|
3242
|
+
type: "xs:string",
|
|
3243
|
+
minOccurs: "0"
|
|
3244
|
+
},
|
|
3245
|
+
{
|
|
3246
|
+
name: "TABNAME",
|
|
3247
|
+
type: "xs:string",
|
|
3248
|
+
minOccurs: "0"
|
|
3249
|
+
},
|
|
3250
|
+
{
|
|
3251
|
+
name: "TABPOS",
|
|
3252
|
+
type: "xs:string",
|
|
3253
|
+
minOccurs: "0"
|
|
3254
|
+
},
|
|
3255
|
+
{
|
|
3256
|
+
name: "FVIEWNAME",
|
|
3257
|
+
type: "xs:string",
|
|
3258
|
+
minOccurs: "0"
|
|
3259
|
+
},
|
|
3260
|
+
{
|
|
3261
|
+
name: "FFIELDNAME",
|
|
3262
|
+
type: "xs:string",
|
|
3263
|
+
minOccurs: "0"
|
|
3264
|
+
},
|
|
3265
|
+
{
|
|
3266
|
+
name: "READONLY",
|
|
3267
|
+
type: "xs:string",
|
|
3268
|
+
minOccurs: "0"
|
|
3269
|
+
}
|
|
3270
|
+
] }
|
|
3271
|
+
},
|
|
3272
|
+
{
|
|
3273
|
+
name: "Dd26vTabType",
|
|
3274
|
+
sequence: { element: [{
|
|
3275
|
+
name: "item",
|
|
3276
|
+
type: "Dd26vType",
|
|
3277
|
+
minOccurs: "0",
|
|
3278
|
+
maxOccurs: "unbounded"
|
|
3279
|
+
}] }
|
|
3280
|
+
},
|
|
3281
|
+
{
|
|
3282
|
+
name: "Dd27pType",
|
|
3283
|
+
sequence: { element: [
|
|
3284
|
+
{
|
|
3285
|
+
name: "VIEWNAME",
|
|
3286
|
+
type: "xs:string",
|
|
3287
|
+
minOccurs: "0"
|
|
3288
|
+
},
|
|
3289
|
+
{
|
|
3290
|
+
name: "VIEWFIELD",
|
|
3291
|
+
type: "xs:string",
|
|
3292
|
+
minOccurs: "0"
|
|
3293
|
+
},
|
|
3294
|
+
{
|
|
3295
|
+
name: "TABNAME",
|
|
3296
|
+
type: "xs:string",
|
|
3297
|
+
minOccurs: "0"
|
|
3298
|
+
},
|
|
3299
|
+
{
|
|
3300
|
+
name: "FIELDNAME",
|
|
3301
|
+
type: "xs:string",
|
|
3302
|
+
minOccurs: "0"
|
|
3303
|
+
},
|
|
3304
|
+
{
|
|
3305
|
+
name: "KEYFLAG",
|
|
3306
|
+
type: "xs:string",
|
|
3307
|
+
minOccurs: "0"
|
|
3308
|
+
},
|
|
3309
|
+
{
|
|
3310
|
+
name: "READONLY",
|
|
3311
|
+
type: "xs:string",
|
|
3312
|
+
minOccurs: "0"
|
|
3313
|
+
},
|
|
3314
|
+
{
|
|
3315
|
+
name: "ROLLNAME",
|
|
3316
|
+
type: "xs:string",
|
|
3317
|
+
minOccurs: "0"
|
|
3318
|
+
},
|
|
3319
|
+
{
|
|
3320
|
+
name: "CHECKTABLE",
|
|
3321
|
+
type: "xs:string",
|
|
3322
|
+
minOccurs: "0"
|
|
3323
|
+
},
|
|
3324
|
+
{
|
|
3325
|
+
name: "LOGFLAG",
|
|
3326
|
+
type: "xs:string",
|
|
3327
|
+
minOccurs: "0"
|
|
3328
|
+
},
|
|
3329
|
+
{
|
|
3330
|
+
name: "REFTABLE",
|
|
3331
|
+
type: "xs:string",
|
|
3332
|
+
minOccurs: "0"
|
|
3333
|
+
},
|
|
3334
|
+
{
|
|
3335
|
+
name: "REFFIELD",
|
|
3336
|
+
type: "xs:string",
|
|
3337
|
+
minOccurs: "0"
|
|
3338
|
+
},
|
|
3339
|
+
{
|
|
3340
|
+
name: "OUTPUTLEN",
|
|
3341
|
+
type: "xs:string",
|
|
3342
|
+
minOccurs: "0"
|
|
3343
|
+
},
|
|
3344
|
+
{
|
|
3345
|
+
name: "CONVEXIT",
|
|
3346
|
+
type: "xs:string",
|
|
3347
|
+
minOccurs: "0"
|
|
3348
|
+
},
|
|
3349
|
+
{
|
|
3350
|
+
name: "DDTEXT",
|
|
3351
|
+
type: "xs:string",
|
|
3352
|
+
minOccurs: "0"
|
|
3353
|
+
}
|
|
3354
|
+
] }
|
|
3355
|
+
},
|
|
3356
|
+
{
|
|
3357
|
+
name: "Dd27pTabType",
|
|
3358
|
+
sequence: { element: [{
|
|
3359
|
+
name: "item",
|
|
3360
|
+
type: "Dd27pType",
|
|
3361
|
+
minOccurs: "0",
|
|
3362
|
+
maxOccurs: "unbounded"
|
|
3363
|
+
}] }
|
|
3364
|
+
},
|
|
3365
|
+
{
|
|
3366
|
+
name: "AbapType",
|
|
3367
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
3368
|
+
attribute: [{
|
|
3369
|
+
name: "version",
|
|
3370
|
+
type: "xs:string",
|
|
3371
|
+
"default": "1.0"
|
|
3372
|
+
}]
|
|
3373
|
+
}
|
|
3374
|
+
]
|
|
3375
|
+
};
|
|
3376
|
+
|
|
3377
|
+
//#endregion
|
|
3378
|
+
//#region src/schemas/generated/schemas/shlp.ts
|
|
3379
|
+
/**
|
|
3380
|
+
* Auto-generated schema from XSD
|
|
3381
|
+
*
|
|
3382
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
3383
|
+
* Source: abapgit/shlp.xsd
|
|
3384
|
+
*/
|
|
3385
|
+
var shlp_default = {
|
|
3386
|
+
$xmlns: {
|
|
3387
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
3388
|
+
asx: "http://www.sap.com/abapxml"
|
|
3389
|
+
},
|
|
3390
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
3391
|
+
elementFormDefault: "unqualified",
|
|
3392
|
+
element: [
|
|
3393
|
+
{
|
|
3394
|
+
name: "abapGit",
|
|
3395
|
+
complexType: {
|
|
3396
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
3397
|
+
attribute: [
|
|
3398
|
+
{
|
|
3399
|
+
name: "version",
|
|
3400
|
+
type: "xs:string",
|
|
3401
|
+
use: "required"
|
|
3402
|
+
},
|
|
3403
|
+
{
|
|
3404
|
+
name: "serializer",
|
|
3405
|
+
type: "xs:string",
|
|
3406
|
+
use: "required"
|
|
3407
|
+
},
|
|
3408
|
+
{
|
|
3409
|
+
name: "serializer_version",
|
|
3410
|
+
type: "xs:string",
|
|
3411
|
+
use: "required"
|
|
3412
|
+
}
|
|
3413
|
+
]
|
|
3414
|
+
}
|
|
3415
|
+
},
|
|
3416
|
+
{
|
|
3417
|
+
name: "Schema",
|
|
3418
|
+
abstract: true
|
|
3419
|
+
},
|
|
3420
|
+
{
|
|
3421
|
+
name: "values",
|
|
3422
|
+
type: "asx:AbapValuesType"
|
|
3423
|
+
},
|
|
3424
|
+
{
|
|
3425
|
+
name: "abap",
|
|
3426
|
+
type: "asx:AbapType"
|
|
3427
|
+
}
|
|
3428
|
+
],
|
|
3429
|
+
complexType: [
|
|
3430
|
+
{
|
|
3431
|
+
name: "AbapValuesType",
|
|
3432
|
+
all: { element: [
|
|
3433
|
+
{
|
|
3434
|
+
name: "DD30V",
|
|
3435
|
+
type: "asx:Dd30vType",
|
|
3436
|
+
minOccurs: "0"
|
|
3437
|
+
},
|
|
3438
|
+
{
|
|
3439
|
+
name: "DD31V",
|
|
3440
|
+
type: "asx:Dd31vType",
|
|
3441
|
+
minOccurs: "0"
|
|
3442
|
+
},
|
|
3443
|
+
{
|
|
3444
|
+
name: "DD32P_TABLE",
|
|
3445
|
+
type: "asx:Dd32pTabType",
|
|
3446
|
+
minOccurs: "0"
|
|
3447
|
+
},
|
|
3448
|
+
{
|
|
3449
|
+
name: "DD33V_TABLE",
|
|
3450
|
+
type: "asx:Dd33vTabType",
|
|
3451
|
+
minOccurs: "0"
|
|
3452
|
+
}
|
|
3453
|
+
] }
|
|
3454
|
+
},
|
|
3455
|
+
{
|
|
3456
|
+
name: "Dd30vType",
|
|
3457
|
+
all: { element: [
|
|
3458
|
+
{
|
|
3459
|
+
name: "SHLPNAME",
|
|
3460
|
+
type: "xs:string"
|
|
3461
|
+
},
|
|
3462
|
+
{
|
|
3463
|
+
name: "DDLANGUAGE",
|
|
3464
|
+
type: "xs:string",
|
|
3465
|
+
minOccurs: "0"
|
|
3466
|
+
},
|
|
3467
|
+
{
|
|
3468
|
+
name: "DDTEXT",
|
|
3469
|
+
type: "xs:string",
|
|
3470
|
+
minOccurs: "0"
|
|
3471
|
+
},
|
|
3472
|
+
{
|
|
3473
|
+
name: "SHLPTYPE",
|
|
3474
|
+
type: "xs:string",
|
|
3475
|
+
minOccurs: "0"
|
|
3476
|
+
},
|
|
3477
|
+
{
|
|
3478
|
+
name: "SHLPINPUT",
|
|
3479
|
+
type: "xs:string",
|
|
3480
|
+
minOccurs: "0"
|
|
3481
|
+
},
|
|
3482
|
+
{
|
|
3483
|
+
name: "DEFLOOKUP",
|
|
3484
|
+
type: "xs:string",
|
|
3485
|
+
minOccurs: "0"
|
|
3486
|
+
},
|
|
3487
|
+
{
|
|
3488
|
+
name: "DIALOGTYPE",
|
|
3489
|
+
type: "xs:string",
|
|
3490
|
+
minOccurs: "0"
|
|
3491
|
+
},
|
|
3492
|
+
{
|
|
3493
|
+
name: "SELEXT",
|
|
3494
|
+
type: "xs:string",
|
|
3495
|
+
minOccurs: "0"
|
|
3496
|
+
},
|
|
3497
|
+
{
|
|
3498
|
+
name: "ACTMETHOD",
|
|
3499
|
+
type: "xs:string",
|
|
3500
|
+
minOccurs: "0"
|
|
3501
|
+
},
|
|
3502
|
+
{
|
|
3503
|
+
name: "HOTKEY",
|
|
3504
|
+
type: "xs:string",
|
|
3505
|
+
minOccurs: "0"
|
|
3506
|
+
}
|
|
3507
|
+
] }
|
|
3508
|
+
},
|
|
3509
|
+
{
|
|
3510
|
+
name: "Dd31vType",
|
|
3511
|
+
all: { element: [
|
|
3512
|
+
{
|
|
3513
|
+
name: "SHLPNAME",
|
|
3514
|
+
type: "xs:string",
|
|
3515
|
+
minOccurs: "0"
|
|
3516
|
+
},
|
|
3517
|
+
{
|
|
3518
|
+
name: "TABNAME",
|
|
3519
|
+
type: "xs:string",
|
|
3520
|
+
minOccurs: "0"
|
|
3521
|
+
},
|
|
3522
|
+
{
|
|
3523
|
+
name: "FIELDNAME",
|
|
3524
|
+
type: "xs:string",
|
|
3525
|
+
minOccurs: "0"
|
|
3526
|
+
},
|
|
3527
|
+
{
|
|
3528
|
+
name: "FLDLOCATION",
|
|
3529
|
+
type: "xs:string",
|
|
3530
|
+
minOccurs: "0"
|
|
3531
|
+
},
|
|
3532
|
+
{
|
|
3533
|
+
name: "ROLLNAME",
|
|
3534
|
+
type: "xs:string",
|
|
3535
|
+
minOccurs: "0"
|
|
3536
|
+
}
|
|
3537
|
+
] }
|
|
3538
|
+
},
|
|
3539
|
+
{
|
|
3540
|
+
name: "Dd32pType",
|
|
3541
|
+
sequence: { element: [
|
|
3542
|
+
{
|
|
3543
|
+
name: "SHLPNAME",
|
|
3544
|
+
type: "xs:string",
|
|
3545
|
+
minOccurs: "0"
|
|
3546
|
+
},
|
|
3547
|
+
{
|
|
3548
|
+
name: "FIELDNAME",
|
|
3549
|
+
type: "xs:string",
|
|
3550
|
+
minOccurs: "0"
|
|
3551
|
+
},
|
|
3552
|
+
{
|
|
3553
|
+
name: "SHLPINPUT",
|
|
3554
|
+
type: "xs:string",
|
|
3555
|
+
minOccurs: "0"
|
|
3556
|
+
},
|
|
3557
|
+
{
|
|
3558
|
+
name: "SHLPOUTPUT",
|
|
3559
|
+
type: "xs:string",
|
|
3560
|
+
minOccurs: "0"
|
|
3561
|
+
},
|
|
3562
|
+
{
|
|
3563
|
+
name: "SHLPSELPOS",
|
|
3564
|
+
type: "xs:string",
|
|
3565
|
+
minOccurs: "0"
|
|
3566
|
+
},
|
|
3567
|
+
{
|
|
3568
|
+
name: "SHLPLISPOS",
|
|
3569
|
+
type: "xs:string",
|
|
3570
|
+
minOccurs: "0"
|
|
3571
|
+
},
|
|
3572
|
+
{
|
|
3573
|
+
name: "DEFAULTVAL",
|
|
3574
|
+
type: "xs:string",
|
|
3575
|
+
minOccurs: "0"
|
|
3576
|
+
},
|
|
3577
|
+
{
|
|
3578
|
+
name: "ROLLNAME",
|
|
3579
|
+
type: "xs:string",
|
|
3580
|
+
minOccurs: "0"
|
|
3581
|
+
},
|
|
3582
|
+
{
|
|
3583
|
+
name: "DATATYPE",
|
|
3584
|
+
type: "xs:string",
|
|
3585
|
+
minOccurs: "0"
|
|
3586
|
+
},
|
|
3587
|
+
{
|
|
3588
|
+
name: "LENG",
|
|
3589
|
+
type: "xs:string",
|
|
3590
|
+
minOccurs: "0"
|
|
3591
|
+
},
|
|
3592
|
+
{
|
|
3593
|
+
name: "DECIMALS",
|
|
3594
|
+
type: "xs:string",
|
|
3595
|
+
minOccurs: "0"
|
|
3596
|
+
},
|
|
3597
|
+
{
|
|
3598
|
+
name: "DDTEXT",
|
|
3599
|
+
type: "xs:string",
|
|
3600
|
+
minOccurs: "0"
|
|
3601
|
+
}
|
|
3602
|
+
] }
|
|
3603
|
+
},
|
|
3604
|
+
{
|
|
3605
|
+
name: "Dd32pTabType",
|
|
3606
|
+
sequence: { element: [{
|
|
3607
|
+
name: "item",
|
|
3608
|
+
type: "Dd32pType",
|
|
3609
|
+
minOccurs: "0",
|
|
3610
|
+
maxOccurs: "unbounded"
|
|
3611
|
+
}] }
|
|
3612
|
+
},
|
|
3613
|
+
{
|
|
3614
|
+
name: "Dd33vType",
|
|
3615
|
+
sequence: { element: [
|
|
3616
|
+
{
|
|
3617
|
+
name: "SHLPNAME",
|
|
3618
|
+
type: "xs:string",
|
|
3619
|
+
minOccurs: "0"
|
|
3620
|
+
},
|
|
3621
|
+
{
|
|
3622
|
+
name: "SHLPFIELD",
|
|
3623
|
+
type: "xs:string",
|
|
3624
|
+
minOccurs: "0"
|
|
3625
|
+
},
|
|
3626
|
+
{
|
|
3627
|
+
name: "TABNAME",
|
|
3628
|
+
type: "xs:string",
|
|
3629
|
+
minOccurs: "0"
|
|
3630
|
+
},
|
|
3631
|
+
{
|
|
3632
|
+
name: "FIELDNAME",
|
|
3633
|
+
type: "xs:string",
|
|
3634
|
+
minOccurs: "0"
|
|
3635
|
+
},
|
|
3636
|
+
{
|
|
3637
|
+
name: "SHLPINPUT",
|
|
3638
|
+
type: "xs:string",
|
|
3639
|
+
minOccurs: "0"
|
|
3640
|
+
},
|
|
3641
|
+
{
|
|
3642
|
+
name: "SHLPOUTPUT",
|
|
3643
|
+
type: "xs:string",
|
|
3644
|
+
minOccurs: "0"
|
|
3645
|
+
}
|
|
3646
|
+
] }
|
|
3647
|
+
},
|
|
3648
|
+
{
|
|
3649
|
+
name: "Dd33vTabType",
|
|
3650
|
+
sequence: { element: [{
|
|
3651
|
+
name: "item",
|
|
3652
|
+
type: "Dd33vType",
|
|
3653
|
+
minOccurs: "0",
|
|
3654
|
+
maxOccurs: "unbounded"
|
|
3655
|
+
}] }
|
|
3656
|
+
},
|
|
3657
|
+
{
|
|
3658
|
+
name: "AbapType",
|
|
3659
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
3660
|
+
attribute: [{
|
|
3661
|
+
name: "version",
|
|
3662
|
+
type: "xs:string",
|
|
3663
|
+
"default": "1.0"
|
|
3664
|
+
}]
|
|
3665
|
+
}
|
|
3666
|
+
]
|
|
3667
|
+
};
|
|
3668
|
+
|
|
3669
|
+
//#endregion
|
|
3670
|
+
//#region src/schemas/generated/schemas/tran.ts
|
|
3671
|
+
/**
|
|
3672
|
+
* Auto-generated schema from XSD
|
|
3673
|
+
*
|
|
3674
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
3675
|
+
* Source: abapgit/tran.xsd
|
|
3676
|
+
*/
|
|
3677
|
+
var tran_default = {
|
|
3678
|
+
$xmlns: {
|
|
3679
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
3680
|
+
asx: "http://www.sap.com/abapxml"
|
|
3681
|
+
},
|
|
3682
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
3683
|
+
elementFormDefault: "unqualified",
|
|
3684
|
+
element: [
|
|
3685
|
+
{
|
|
3686
|
+
name: "abapGit",
|
|
3687
|
+
complexType: {
|
|
3688
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
3689
|
+
attribute: [
|
|
3690
|
+
{
|
|
3691
|
+
name: "version",
|
|
3692
|
+
type: "xs:string",
|
|
3693
|
+
use: "required"
|
|
3694
|
+
},
|
|
3695
|
+
{
|
|
3696
|
+
name: "serializer",
|
|
3697
|
+
type: "xs:string",
|
|
3698
|
+
use: "required"
|
|
3699
|
+
},
|
|
3700
|
+
{
|
|
3701
|
+
name: "serializer_version",
|
|
3702
|
+
type: "xs:string",
|
|
3703
|
+
use: "required"
|
|
3704
|
+
}
|
|
3705
|
+
]
|
|
3706
|
+
}
|
|
3707
|
+
},
|
|
3708
|
+
{
|
|
3709
|
+
name: "Schema",
|
|
3710
|
+
abstract: true
|
|
3711
|
+
},
|
|
3712
|
+
{
|
|
3713
|
+
name: "values",
|
|
3714
|
+
type: "asx:AbapValuesType"
|
|
3715
|
+
},
|
|
3716
|
+
{
|
|
3717
|
+
name: "abap",
|
|
3718
|
+
type: "asx:AbapType"
|
|
3719
|
+
}
|
|
3720
|
+
],
|
|
3721
|
+
complexType: [
|
|
3722
|
+
{
|
|
3723
|
+
name: "AbapValuesType",
|
|
3724
|
+
all: { element: [
|
|
3725
|
+
{
|
|
3726
|
+
name: "TSTC",
|
|
3727
|
+
type: "asx:TstcType",
|
|
3728
|
+
minOccurs: "0"
|
|
3729
|
+
},
|
|
3730
|
+
{
|
|
3731
|
+
name: "TSTCC",
|
|
3732
|
+
type: "asx:TstccType",
|
|
3733
|
+
minOccurs: "0"
|
|
3734
|
+
},
|
|
3735
|
+
{
|
|
3736
|
+
name: "TSTCT",
|
|
3737
|
+
type: "asx:TstctTabType",
|
|
3738
|
+
minOccurs: "0"
|
|
3739
|
+
}
|
|
3740
|
+
] }
|
|
3741
|
+
},
|
|
3742
|
+
{
|
|
3743
|
+
name: "TstcType",
|
|
3744
|
+
all: { element: [
|
|
3745
|
+
{
|
|
3746
|
+
name: "TCODE",
|
|
3747
|
+
type: "xs:string"
|
|
3748
|
+
},
|
|
3749
|
+
{
|
|
3750
|
+
name: "PGMNA",
|
|
3751
|
+
type: "xs:string",
|
|
3752
|
+
minOccurs: "0"
|
|
3753
|
+
},
|
|
3754
|
+
{
|
|
3755
|
+
name: "DYPNO",
|
|
3756
|
+
type: "xs:string",
|
|
3757
|
+
minOccurs: "0"
|
|
3758
|
+
},
|
|
3759
|
+
{
|
|
3760
|
+
name: "TYPE",
|
|
3761
|
+
type: "xs:string",
|
|
3762
|
+
minOccurs: "0"
|
|
3763
|
+
},
|
|
3764
|
+
{
|
|
3765
|
+
name: "CINFO",
|
|
3766
|
+
type: "xs:string",
|
|
3767
|
+
minOccurs: "0"
|
|
3768
|
+
}
|
|
3769
|
+
] }
|
|
3770
|
+
},
|
|
3771
|
+
{
|
|
3772
|
+
name: "TstccType",
|
|
3773
|
+
all: { element: [
|
|
3774
|
+
{
|
|
3775
|
+
name: "TCODE",
|
|
3776
|
+
type: "xs:string",
|
|
3777
|
+
minOccurs: "0"
|
|
3778
|
+
},
|
|
3779
|
+
{
|
|
3780
|
+
name: "S_WEBGUI",
|
|
3781
|
+
type: "xs:string",
|
|
3782
|
+
minOccurs: "0"
|
|
3783
|
+
},
|
|
3784
|
+
{
|
|
3785
|
+
name: "S_PLATIN",
|
|
3786
|
+
type: "xs:string",
|
|
3787
|
+
minOccurs: "0"
|
|
3788
|
+
},
|
|
3789
|
+
{
|
|
3790
|
+
name: "S_WIN32",
|
|
3791
|
+
type: "xs:string",
|
|
3792
|
+
minOccurs: "0"
|
|
3793
|
+
},
|
|
3794
|
+
{
|
|
3795
|
+
name: "S_MAC",
|
|
3796
|
+
type: "xs:string",
|
|
3797
|
+
minOccurs: "0"
|
|
3798
|
+
}
|
|
3799
|
+
] }
|
|
3800
|
+
},
|
|
3801
|
+
{
|
|
3802
|
+
name: "TstctType",
|
|
3803
|
+
sequence: { element: [
|
|
3804
|
+
{
|
|
3805
|
+
name: "SPRSL",
|
|
3806
|
+
type: "xs:string",
|
|
3807
|
+
minOccurs: "0"
|
|
3808
|
+
},
|
|
3809
|
+
{
|
|
3810
|
+
name: "TCODE",
|
|
3811
|
+
type: "xs:string",
|
|
3812
|
+
minOccurs: "0"
|
|
3813
|
+
},
|
|
3814
|
+
{
|
|
3815
|
+
name: "TTEXT",
|
|
3816
|
+
type: "xs:string",
|
|
3817
|
+
minOccurs: "0"
|
|
3818
|
+
}
|
|
3819
|
+
] }
|
|
3820
|
+
},
|
|
3821
|
+
{
|
|
3822
|
+
name: "TstctTabType",
|
|
3823
|
+
sequence: { element: [{
|
|
3824
|
+
name: "item",
|
|
3825
|
+
type: "TstctType",
|
|
3826
|
+
minOccurs: "0",
|
|
3827
|
+
maxOccurs: "unbounded"
|
|
3828
|
+
}] }
|
|
3829
|
+
},
|
|
3830
|
+
{
|
|
3831
|
+
name: "AbapType",
|
|
3832
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
3833
|
+
attribute: [{
|
|
3834
|
+
name: "version",
|
|
3835
|
+
type: "xs:string",
|
|
3836
|
+
"default": "1.0"
|
|
3837
|
+
}]
|
|
3838
|
+
}
|
|
3839
|
+
]
|
|
3840
|
+
};
|
|
3841
|
+
|
|
3842
|
+
//#endregion
|
|
3843
|
+
//#region src/schemas/generated/schemas/type.ts
|
|
3844
|
+
/**
|
|
3845
|
+
* Auto-generated schema from XSD
|
|
3846
|
+
*
|
|
3847
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
3848
|
+
* Source: abapgit/type.xsd
|
|
3849
|
+
*/
|
|
3850
|
+
var type_default = {
|
|
3851
|
+
$xmlns: {
|
|
3852
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
3853
|
+
asx: "http://www.sap.com/abapxml"
|
|
3854
|
+
},
|
|
3855
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
3856
|
+
elementFormDefault: "unqualified",
|
|
3857
|
+
element: [
|
|
3858
|
+
{
|
|
3859
|
+
name: "abapGit",
|
|
3860
|
+
complexType: {
|
|
3861
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
3862
|
+
attribute: [
|
|
3863
|
+
{
|
|
3864
|
+
name: "version",
|
|
3865
|
+
type: "xs:string",
|
|
3866
|
+
use: "required"
|
|
3867
|
+
},
|
|
3868
|
+
{
|
|
3869
|
+
name: "serializer",
|
|
3870
|
+
type: "xs:string",
|
|
3871
|
+
use: "required"
|
|
3872
|
+
},
|
|
3873
|
+
{
|
|
3874
|
+
name: "serializer_version",
|
|
3875
|
+
type: "xs:string",
|
|
3876
|
+
use: "required"
|
|
3877
|
+
}
|
|
3878
|
+
]
|
|
3879
|
+
}
|
|
3880
|
+
},
|
|
3881
|
+
{
|
|
3882
|
+
name: "Schema",
|
|
3883
|
+
abstract: true
|
|
3884
|
+
},
|
|
3885
|
+
{
|
|
3886
|
+
name: "values",
|
|
3887
|
+
type: "asx:AbapValuesType"
|
|
3888
|
+
},
|
|
3889
|
+
{
|
|
3890
|
+
name: "abap",
|
|
3891
|
+
type: "asx:AbapType"
|
|
3892
|
+
}
|
|
3893
|
+
],
|
|
3894
|
+
complexType: [
|
|
3895
|
+
{
|
|
3896
|
+
name: "AbapValuesType",
|
|
3897
|
+
all: { element: [{
|
|
3898
|
+
name: "TYPE",
|
|
3899
|
+
type: "asx:TypeGroupType",
|
|
3900
|
+
minOccurs: "0"
|
|
3901
|
+
}] }
|
|
3902
|
+
},
|
|
3903
|
+
{
|
|
3904
|
+
name: "TypeGroupType",
|
|
3905
|
+
all: { element: [{
|
|
3906
|
+
name: "TYPEGROUP",
|
|
3907
|
+
type: "xs:string"
|
|
3908
|
+
}, {
|
|
3909
|
+
name: "DESCRIPT",
|
|
3910
|
+
type: "xs:string",
|
|
3911
|
+
minOccurs: "0"
|
|
3912
|
+
}] }
|
|
3913
|
+
},
|
|
3914
|
+
{
|
|
3915
|
+
name: "AbapType",
|
|
3916
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
3917
|
+
attribute: [{
|
|
3918
|
+
name: "version",
|
|
3919
|
+
type: "xs:string",
|
|
3920
|
+
"default": "1.0"
|
|
3921
|
+
}]
|
|
3922
|
+
}
|
|
3923
|
+
]
|
|
3924
|
+
};
|
|
3925
|
+
|
|
3926
|
+
//#endregion
|
|
3927
|
+
//#region src/schemas/generated/schemas/xslt.ts
|
|
3928
|
+
/**
|
|
3929
|
+
* Auto-generated schema from XSD
|
|
3930
|
+
*
|
|
3931
|
+
* DO NOT EDIT - Generated by ts-xsd codegen
|
|
3932
|
+
* Source: abapgit/xslt.xsd
|
|
3933
|
+
*/
|
|
3934
|
+
var xslt_default = {
|
|
3935
|
+
$xmlns: {
|
|
3936
|
+
xs: "http://www.w3.org/2001/XMLSchema",
|
|
3937
|
+
asx: "http://www.sap.com/abapxml"
|
|
3938
|
+
},
|
|
3939
|
+
targetNamespace: "http://www.sap.com/abapxml",
|
|
3940
|
+
elementFormDefault: "unqualified",
|
|
3941
|
+
element: [
|
|
3942
|
+
{
|
|
3943
|
+
name: "abapGit",
|
|
3944
|
+
complexType: {
|
|
3945
|
+
sequence: { element: [{ ref: "asx:abap" }] },
|
|
3946
|
+
attribute: [
|
|
3947
|
+
{
|
|
3948
|
+
name: "version",
|
|
3949
|
+
type: "xs:string",
|
|
3950
|
+
use: "required"
|
|
3951
|
+
},
|
|
3952
|
+
{
|
|
3953
|
+
name: "serializer",
|
|
3954
|
+
type: "xs:string",
|
|
3955
|
+
use: "required"
|
|
3956
|
+
},
|
|
3957
|
+
{
|
|
3958
|
+
name: "serializer_version",
|
|
3959
|
+
type: "xs:string",
|
|
3960
|
+
use: "required"
|
|
3961
|
+
}
|
|
3962
|
+
]
|
|
3963
|
+
}
|
|
3964
|
+
},
|
|
3965
|
+
{
|
|
3966
|
+
name: "Schema",
|
|
3967
|
+
abstract: true
|
|
3968
|
+
},
|
|
3969
|
+
{
|
|
3970
|
+
name: "values",
|
|
3971
|
+
type: "asx:AbapValuesType"
|
|
3972
|
+
},
|
|
3973
|
+
{
|
|
3974
|
+
name: "abap",
|
|
3975
|
+
type: "asx:AbapType"
|
|
3976
|
+
}
|
|
3977
|
+
],
|
|
3978
|
+
complexType: [
|
|
3979
|
+
{
|
|
3980
|
+
name: "AbapValuesType",
|
|
3981
|
+
all: { element: [{
|
|
3982
|
+
name: "XSLT",
|
|
3983
|
+
type: "asx:XsltType",
|
|
3984
|
+
minOccurs: "0"
|
|
3985
|
+
}] }
|
|
3986
|
+
},
|
|
3987
|
+
{
|
|
3988
|
+
name: "XsltType",
|
|
3989
|
+
all: { element: [{
|
|
3990
|
+
name: "PROGNAME",
|
|
3991
|
+
type: "xs:string"
|
|
3992
|
+
}, {
|
|
3993
|
+
name: "DESCRIPT",
|
|
3994
|
+
type: "xs:string",
|
|
3995
|
+
minOccurs: "0"
|
|
3996
|
+
}] }
|
|
3997
|
+
},
|
|
3998
|
+
{
|
|
3999
|
+
name: "AbapType",
|
|
4000
|
+
sequence: { element: [{ ref: "asx:values" }] },
|
|
4001
|
+
attribute: [{
|
|
4002
|
+
name: "version",
|
|
4003
|
+
type: "xs:string",
|
|
4004
|
+
"default": "1.0"
|
|
4005
|
+
}]
|
|
4006
|
+
}
|
|
4007
|
+
]
|
|
4008
|
+
};
|
|
4009
|
+
|
|
4010
|
+
//#endregion
|
|
4011
|
+
//#region src/schemas/generated/index.ts
|
|
4012
|
+
/**
|
|
4013
|
+
* AbapGit Typed Schemas
|
|
4014
|
+
*
|
|
4015
|
+
* Auto-generated by ts-xsd codegen - DO NOT EDIT
|
|
4016
|
+
*
|
|
4017
|
+
* Each schema provides:
|
|
4018
|
+
* - _type: Full AbapGitType (for XML build/parse)
|
|
4019
|
+
* - _values: Inner values type (for handler mapping)
|
|
4020
|
+
* - parse(xml) → fully typed object
|
|
4021
|
+
* - build(data) → XML string
|
|
4022
|
+
* - schema → raw schema literal
|
|
4023
|
+
*/
|
|
4024
|
+
const clas = abapGitSchema(clas_default);
|
|
4025
|
+
const devc = abapGitSchema(devc_default);
|
|
4026
|
+
const doma = abapGitSchema(doma_default);
|
|
4027
|
+
const dtel = abapGitSchema(dtel_default);
|
|
4028
|
+
const intf = abapGitSchema(intf_default);
|
|
4029
|
+
const prog = abapGitSchema(prog_default);
|
|
4030
|
+
const fugr = abapGitSchema(fugr_default);
|
|
4031
|
+
const tabl = abapGitSchema(tabl_default);
|
|
4032
|
+
const ttyp = abapGitSchema(ttyp_default);
|
|
4033
|
+
const bdef = abapGitSchema(bdef_default);
|
|
4034
|
+
const srvd = abapGitSchema(srvd_default);
|
|
4035
|
+
const srvb = abapGitSchema(srvb_default);
|
|
4036
|
+
const dcls = abapGitSchema(dcls_default);
|
|
4037
|
+
const ddls = abapGitSchema(ddls_default);
|
|
4038
|
+
const ddlx = abapGitSchema(ddlx_default);
|
|
4039
|
+
const msag = abapGitSchema(msag_default);
|
|
4040
|
+
const view = abapGitSchema(view_default);
|
|
4041
|
+
const enqu = abapGitSchema(enqu_default);
|
|
4042
|
+
const shlp = abapGitSchema(shlp_default);
|
|
4043
|
+
const tran = abapGitSchema(tran_default);
|
|
4044
|
+
const type = abapGitSchema(type_default);
|
|
4045
|
+
const xslt = abapGitSchema(xslt_default);
|
|
4046
|
+
|
|
4047
|
+
//#endregion
|
|
4048
|
+
//#region src/lib/handlers/lang.ts
|
|
4049
|
+
/**
|
|
4050
|
+
* SAP 1-character language code ↔ ISO 639-1 mapping
|
|
4051
|
+
*
|
|
4052
|
+
* abapGit stores SAP internal 1-char codes (e.g. "E" for English).
|
|
4053
|
+
* SAP ADT REST API expects ISO 639-1 codes (e.g. "EN").
|
|
4054
|
+
*/
|
|
4055
|
+
const SAP_TO_ISO = {
|
|
4056
|
+
E: "EN",
|
|
4057
|
+
D: "DE",
|
|
4058
|
+
F: "FR",
|
|
4059
|
+
I: "IT",
|
|
4060
|
+
S: "ES",
|
|
4061
|
+
P: "PT",
|
|
4062
|
+
J: "JA",
|
|
4063
|
+
K: "KO",
|
|
4064
|
+
"1": "ZH",
|
|
4065
|
+
W: "RU",
|
|
4066
|
+
T: "TR",
|
|
4067
|
+
N: "NL",
|
|
4068
|
+
H: "HU",
|
|
4069
|
+
L: "PL",
|
|
4070
|
+
Q: "CS",
|
|
4071
|
+
R: "SK",
|
|
4072
|
+
U: "SV",
|
|
4073
|
+
V: "DA",
|
|
4074
|
+
Y: "FI",
|
|
4075
|
+
X: "NO",
|
|
4076
|
+
G: "EL",
|
|
4077
|
+
B: "HE",
|
|
4078
|
+
A: "AR",
|
|
4079
|
+
"3": "TH",
|
|
4080
|
+
M: "UK",
|
|
4081
|
+
"6": "HR",
|
|
4082
|
+
O: "SL",
|
|
4083
|
+
"7": "BG",
|
|
4084
|
+
"8": "SR",
|
|
4085
|
+
C: "RO"
|
|
4086
|
+
};
|
|
4087
|
+
const ISO_TO_SAP = Object.fromEntries(Object.entries(SAP_TO_ISO).map(([k, v]) => [v, k]));
|
|
4088
|
+
/**
|
|
4089
|
+
* Convert SAP 1-char language code to ISO 639-1.
|
|
4090
|
+
* Returns the input uppercased if no mapping exists (may already be ISO).
|
|
4091
|
+
*/
|
|
4092
|
+
function sapLangToIso(sapLang) {
|
|
4093
|
+
if (!sapLang) return "EN";
|
|
4094
|
+
const upper = sapLang.toUpperCase();
|
|
4095
|
+
if (upper.length >= 2) return upper;
|
|
4096
|
+
return SAP_TO_ISO[upper] ?? upper;
|
|
4097
|
+
}
|
|
4098
|
+
/**
|
|
4099
|
+
* Convert ISO 639-1 language code to SAP 1-char code.
|
|
4100
|
+
* Returns "E" (English) if no mapping exists.
|
|
4101
|
+
*/
|
|
4102
|
+
function isoToSapLang(isoLang) {
|
|
4103
|
+
if (!isoLang) return "E";
|
|
2444
4104
|
const upper = isoLang.toUpperCase();
|
|
2445
4105
|
if (upper.length === 1) return upper;
|
|
2446
4106
|
return ISO_TO_SAP[upper] ?? "E";
|
|
@@ -2680,6 +4340,19 @@ const programHandler = createHandler(AdkProgram, {
|
|
|
2680
4340
|
}
|
|
2681
4341
|
});
|
|
2682
4342
|
|
|
4343
|
+
//#endregion
|
|
4344
|
+
//#region src/lib/handlers/source-inclusion.ts
|
|
4345
|
+
/**
|
|
4346
|
+
* Shared source-inclusion rule for abapGit object handlers.
|
|
4347
|
+
*
|
|
4348
|
+
* A source is included when it is defined and either supplied by the caller
|
|
4349
|
+
* or non-empty on the object.
|
|
4350
|
+
*/
|
|
4351
|
+
function shouldIncludeSource(source, suppliedSource) {
|
|
4352
|
+
if (source === void 0) return false;
|
|
4353
|
+
return suppliedSource !== void 0 || source !== "";
|
|
4354
|
+
}
|
|
4355
|
+
|
|
2683
4356
|
//#endregion
|
|
2684
4357
|
//#region src/lib/handlers/objects/fugr.ts
|
|
2685
4358
|
/**
|
|
@@ -2696,6 +4369,75 @@ const programHandler = createHandler(AdkProgram, {
|
|
|
2696
4369
|
* Note: FM metadata is stored INSIDE the main XML under <FUNCTIONS>,
|
|
2697
4370
|
* NOT in separate per-FM XML files (that's how abapGit works).
|
|
2698
4371
|
*/
|
|
4372
|
+
function buildMainXmlFile(obj, objectName, nameUpper, functions, ctx) {
|
|
4373
|
+
const values = {
|
|
4374
|
+
AREAT: obj.description ?? "",
|
|
4375
|
+
INCLUDES: { SOBJ_NAME: [`L${nameUpper}TOP`, `SAPL${nameUpper}`] }
|
|
4376
|
+
};
|
|
4377
|
+
if (functions.length > 0) values.FUNCTIONS = { item: functions };
|
|
4378
|
+
const fullPayload = { abapGit: {
|
|
4379
|
+
abap: {
|
|
4380
|
+
version: "1.0",
|
|
4381
|
+
values
|
|
4382
|
+
},
|
|
4383
|
+
version: "v1.0.0",
|
|
4384
|
+
serializer: "LCL_OBJECT_FUGR",
|
|
4385
|
+
serializer_version: "v1.0.0"
|
|
4386
|
+
} };
|
|
4387
|
+
const xmlContent = formatAbapGitXml(fugr.build(fullPayload, { pretty: true }));
|
|
4388
|
+
return ctx.createFile(`${objectName}.fugr.xml`, xmlContent);
|
|
4389
|
+
}
|
|
4390
|
+
function deriveFmList(suppliedSources, objectName) {
|
|
4391
|
+
if (!suppliedSources) return {
|
|
4392
|
+
fmItems: [],
|
|
4393
|
+
functions: []
|
|
4394
|
+
};
|
|
4395
|
+
const lowerTopKey = `l${objectName}top`;
|
|
4396
|
+
const lowerSap = `sapl${objectName}`;
|
|
4397
|
+
const fmItems = Object.keys(suppliedSources).filter((key) => {
|
|
4398
|
+
const lower = key.toLowerCase();
|
|
4399
|
+
return lower !== "main" && lower !== lowerTopKey && lower !== lowerSap;
|
|
4400
|
+
}).map((key) => ({
|
|
4401
|
+
key,
|
|
4402
|
+
name: key.toLowerCase()
|
|
4403
|
+
}));
|
|
4404
|
+
return {
|
|
4405
|
+
fmItems,
|
|
4406
|
+
functions: fmItems.map((fm) => ({ FUNCNAME: fm.key.toUpperCase() }))
|
|
4407
|
+
};
|
|
4408
|
+
}
|
|
4409
|
+
async function buildTopSourceFile(obj, objectName, suppliedSources, ctx) {
|
|
4410
|
+
const hasExplicitSources = suppliedSources !== void 0;
|
|
4411
|
+
const topKey = `l${objectName}top`;
|
|
4412
|
+
const suppliedTopSource = suppliedSources ? suppliedSources.main ?? suppliedSources[topKey] : void 0;
|
|
4413
|
+
try {
|
|
4414
|
+
const topSource = suppliedTopSource !== void 0 || !hasExplicitSources ? suppliedTopSource ?? await obj.getSource() : void 0;
|
|
4415
|
+
if (shouldIncludeSource(topSource, suppliedTopSource)) return ctx.createFile(`${objectName}.fugr.l${objectName}top.abap`, topSource);
|
|
4416
|
+
} catch {}
|
|
4417
|
+
}
|
|
4418
|
+
function buildProgramFiles(objectName, nameUpper, fixpt, ctx) {
|
|
4419
|
+
return [
|
|
4420
|
+
ctx.createFile(`${objectName}.fugr.l${objectName}top.xml`, buildProgdirXml(`L${nameUpper}TOP`, "I", fixpt)),
|
|
4421
|
+
ctx.createFile(`${objectName}.fugr.sapl${objectName}.abap`, buildMainProgramSource(nameUpper)),
|
|
4422
|
+
ctx.createFile(`${objectName}.fugr.sapl${objectName}.xml`, buildProgdirXml(`SAPL${nameUpper}`, "F", fixpt))
|
|
4423
|
+
];
|
|
4424
|
+
}
|
|
4425
|
+
async function buildFunctionModuleFiles(obj, fmItems, suppliedSources, ctx) {
|
|
4426
|
+
const objectName = ctx.getObjectName(obj);
|
|
4427
|
+
const files = [];
|
|
4428
|
+
const hasExplicitSources = suppliedSources !== void 0;
|
|
4429
|
+
for (const fm of fmItems) {
|
|
4430
|
+
const sourceKey = fm.key ?? fm.name;
|
|
4431
|
+
const funcName = fm.name.toLowerCase();
|
|
4432
|
+
const suppliedFmSource = suppliedSources?.[sourceKey];
|
|
4433
|
+
if (hasExplicitSources && suppliedFmSource === void 0) continue;
|
|
4434
|
+
try {
|
|
4435
|
+
const source = suppliedFmSource !== void 0 ? suppliedFmSource : await obj.client.adt.functions.groups.fmodules.source.main.get(obj.name, fm.name);
|
|
4436
|
+
if (shouldIncludeSource(source, suppliedFmSource)) files.push(ctx.createFile(`${objectName}.fugr.${funcName}.abap`, source));
|
|
4437
|
+
} catch {}
|
|
4438
|
+
}
|
|
4439
|
+
return files;
|
|
4440
|
+
}
|
|
2699
4441
|
/**
|
|
2700
4442
|
* Map ADT processingType to abapGit REMOTE_CALL flag
|
|
2701
4443
|
*/
|
|
@@ -2726,44 +4468,26 @@ const functionGroupHandler = createHandler(AdkFunctionGroup, {
|
|
|
2726
4468
|
INCLUDES: { SOBJ_NAME: [`L${name}TOP`, `SAPL${name}`] }
|
|
2727
4469
|
};
|
|
2728
4470
|
},
|
|
2729
|
-
serialize: async (obj, ctx) => {
|
|
4471
|
+
serialize: async (obj, ctx, options) => {
|
|
2730
4472
|
const objectName = ctx.getObjectName(obj);
|
|
2731
4473
|
const nameUpper = obj.name.toUpperCase();
|
|
2732
|
-
const
|
|
2733
|
-
const
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
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 {}
|
|
4474
|
+
const suppliedSources = options?.sources;
|
|
4475
|
+
const hasExplicitSources = suppliedSources !== void 0;
|
|
4476
|
+
let fmItems;
|
|
4477
|
+
let functions;
|
|
4478
|
+
if (hasExplicitSources) ({fmItems, functions} = deriveFmList(suppliedSources, objectName));
|
|
4479
|
+
else {
|
|
4480
|
+
fmItems = await discoverFunctionModules(obj);
|
|
4481
|
+
functions = await serializeFunctions(obj, fmItems);
|
|
2765
4482
|
}
|
|
2766
|
-
|
|
4483
|
+
const fixpt = ctx.getData(obj).fixPointArithmetic ? "X" : "";
|
|
4484
|
+
const topFile = await buildTopSourceFile(obj, objectName, suppliedSources, ctx);
|
|
4485
|
+
return [
|
|
4486
|
+
buildMainXmlFile(obj, objectName, nameUpper, functions, ctx),
|
|
4487
|
+
...topFile ? [topFile] : [],
|
|
4488
|
+
...buildProgramFiles(objectName, nameUpper, fixpt, ctx),
|
|
4489
|
+
...await buildFunctionModuleFiles(obj, fmItems, suppliedSources, ctx)
|
|
4490
|
+
];
|
|
2767
4491
|
},
|
|
2768
4492
|
fromAbapGit: ({ AREAT, FUNCTIONS }) => ({
|
|
2769
4493
|
name: "",
|
|
@@ -2779,8 +4503,9 @@ const functionGroupHandler = createHandler(AdkFunctionGroup, {
|
|
|
2779
4503
|
const mainSource = sources.main ?? sources[topKey];
|
|
2780
4504
|
if (mainSource) obj._pendingSource = mainSource;
|
|
2781
4505
|
const fmSources = {};
|
|
4506
|
+
const mainProgramKey = `sapl${name}`;
|
|
2782
4507
|
for (const [suffix, content] of Object.entries(sources)) {
|
|
2783
|
-
if (suffix === "main" || suffix === topKey || suffix
|
|
4508
|
+
if (suffix === "main" || suffix === topKey || suffix === mainProgramKey) continue;
|
|
2784
4509
|
fmSources[suffix] = content;
|
|
2785
4510
|
}
|
|
2786
4511
|
if (Object.keys(fmSources).length > 0) obj._pendingFmSources = fmSources;
|
|
@@ -2799,7 +4524,7 @@ async function discoverFunctionModules(obj) {
|
|
|
2799
4524
|
let match;
|
|
2800
4525
|
while ((match = regex.exec(responseStr)) !== null) fmNames.push({ name: match[1] });
|
|
2801
4526
|
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] });
|
|
4527
|
+
while ((match = regex2.exec(responseStr)) !== null) if (match?.[1] && !fmNames.some((f) => f.name === match[1])) fmNames.push({ name: match[1] });
|
|
2803
4528
|
return fmNames;
|
|
2804
4529
|
} catch {
|
|
2805
4530
|
return [];
|
|
@@ -3441,451 +5166,1377 @@ async function buildDD03P(members, tableName = "", resolver) {
|
|
|
3441
5166
|
const field = member;
|
|
3442
5167
|
entries.push(await buildFieldDD03P(field, tableName, resolver));
|
|
3443
5168
|
}
|
|
3444
|
-
return entries;
|
|
3445
|
-
}
|
|
5169
|
+
return entries;
|
|
5170
|
+
}
|
|
5171
|
+
|
|
5172
|
+
//#endregion
|
|
5173
|
+
//#region src/lib/handlers/objects/tabl-serialize.ts
|
|
5174
|
+
/**
|
|
5175
|
+
* Table/Structure serialization helpers for abapGit format.
|
|
5176
|
+
*
|
|
5177
|
+
* This file contains the source-to-XML conversion used by the TABL handler.
|
|
5178
|
+
* It is intentionally separate from the handler definition file, which keeps
|
|
5179
|
+
* the handler surface focused on schema mapping (`toAbapGit`/`fromAbapGit`).
|
|
5180
|
+
*/
|
|
5181
|
+
const XML_NAMED_ENTITIES = {
|
|
5182
|
+
amp: "&",
|
|
5183
|
+
lt: "<",
|
|
5184
|
+
gt: ">",
|
|
5185
|
+
quot: "\"",
|
|
5186
|
+
apos: "'"
|
|
5187
|
+
};
|
|
5188
|
+
function decodeNumericCode(decimal, hex) {
|
|
5189
|
+
const base = decimal !== void 0 ? 10 : 16;
|
|
5190
|
+
const value = decimal !== void 0 ? decimal : hex ?? "";
|
|
5191
|
+
return String.fromCharCode(parseInt(value, base));
|
|
5192
|
+
}
|
|
5193
|
+
function decodeXmlEntities(text) {
|
|
5194
|
+
return text.replace(/&(?:#(\d+)|#x([0-9a-fA-F]+)|([a-zA-Z][a-zA-Z0-9]*));/g, (match, decimal, hex, name) => decimal !== void 0 || hex !== void 0 ? decodeNumericCode(decimal, hex) : XML_NAMED_ENTITIES[name] ?? match);
|
|
5195
|
+
}
|
|
5196
|
+
/**
|
|
5197
|
+
* Strip undefined/empty-string values from an object
|
|
5198
|
+
* to avoid emitting empty XML elements
|
|
5199
|
+
*/
|
|
5200
|
+
function stripEmpty(obj) {
|
|
5201
|
+
const result = {};
|
|
5202
|
+
for (const [key, value] of Object.entries(obj)) if (value !== void 0 && value !== "") result[key] = value;
|
|
5203
|
+
return result;
|
|
5204
|
+
}
|
|
5205
|
+
/**
|
|
5206
|
+
* Parse ADT table settings XML into DD09L data for abapGit serialization.
|
|
5207
|
+
*/
|
|
5208
|
+
function parseSettingsToDD09L(settingsXml, def) {
|
|
5209
|
+
let settings;
|
|
5210
|
+
try {
|
|
5211
|
+
const parsed = tablesettings.parse(settingsXml);
|
|
5212
|
+
if (!("tableSettings" in parsed)) return void 0;
|
|
5213
|
+
settings = parsed.tableSettings;
|
|
5214
|
+
} catch {
|
|
5215
|
+
return;
|
|
5216
|
+
}
|
|
5217
|
+
return stripEmpty({
|
|
5218
|
+
TABNAME: def.name.toUpperCase(),
|
|
5219
|
+
AS4LOCAL: "A",
|
|
5220
|
+
TABKAT: settings.sizeCategory,
|
|
5221
|
+
TABART: settings.dataClassCategory,
|
|
5222
|
+
BUFALLOW: settings.buffering?.allowed,
|
|
5223
|
+
PUFFERUNG: settings.buffering?.type,
|
|
5224
|
+
SCHFELDANZ: settings.buffering?.areaKeyFields && settings.buffering.areaKeyFields !== "0" ? settings.buffering.areaKeyFields : void 0,
|
|
5225
|
+
PROTOKOLL: settings.loggingEnabled ? "X" : void 0
|
|
5226
|
+
});
|
|
5227
|
+
}
|
|
5228
|
+
/**
|
|
5229
|
+
* Create a TypeResolver that resolves named types via ADT endpoints.
|
|
5230
|
+
*/
|
|
5231
|
+
function resolveReferencedType(xml, comptype) {
|
|
5232
|
+
const result = { comptype };
|
|
5233
|
+
if (comptype === "E" && /<dtel:searchHelp>[^<]+<\/dtel:searchHelp>/.test(xml)) result.shlporigin = "D";
|
|
5234
|
+
const descMatch = xml.match(/adtcore:description="([^"]+)"/);
|
|
5235
|
+
if (descMatch) result.description = decodeXmlEntities(descMatch[1]);
|
|
5236
|
+
return result;
|
|
5237
|
+
}
|
|
5238
|
+
function createAdtTypeResolver(obj) {
|
|
5239
|
+
const cache = /* @__PURE__ */ new Map();
|
|
5240
|
+
return { async resolve(name) {
|
|
5241
|
+
const key = name.toLowerCase();
|
|
5242
|
+
const cached = cache.get(key);
|
|
5243
|
+
if (cached) return cached;
|
|
5244
|
+
const dtelXml = await obj.fetchText(`/sap/bc/adt/ddic/dataelements/${encodeURIComponent(key)}`);
|
|
5245
|
+
if (dtelXml) {
|
|
5246
|
+
const result = resolveReferencedType(dtelXml, "E");
|
|
5247
|
+
cache.set(key, result);
|
|
5248
|
+
return result;
|
|
5249
|
+
}
|
|
5250
|
+
const structXml = await obj.fetchText(`/sap/bc/adt/ddic/structures/${encodeURIComponent(key)}`);
|
|
5251
|
+
const result = structXml ? resolveReferencedType(structXml, "S") : { comptype: "E" };
|
|
5252
|
+
cache.set(key, result);
|
|
5253
|
+
return result;
|
|
5254
|
+
} };
|
|
5255
|
+
}
|
|
5256
|
+
async function resolveCdsSource(obj, sources) {
|
|
5257
|
+
if (sources !== void 0) {
|
|
5258
|
+
if (sources.main === void 0) return { fallback: true };
|
|
5259
|
+
return { source: sources.main };
|
|
5260
|
+
}
|
|
5261
|
+
try {
|
|
5262
|
+
return { source: await obj.getSource() };
|
|
5263
|
+
} catch {
|
|
5264
|
+
return { fallback: true };
|
|
5265
|
+
}
|
|
5266
|
+
}
|
|
5267
|
+
function createFallbackFile(obj, ctx) {
|
|
5268
|
+
const objectName = ctx.getObjectName(obj);
|
|
5269
|
+
return [ctx.createFile(`${objectName}.tabl.xml`, ctx.toAbapGitXml(obj))];
|
|
5270
|
+
}
|
|
5271
|
+
async function buildTablValues(obj, def) {
|
|
5272
|
+
const lang = isoToSapLang(obj.language || void 0);
|
|
5273
|
+
const dd02v = buildDD02V(def, lang, obj.description ?? "");
|
|
5274
|
+
const resolver = createAdtTypeResolver(obj);
|
|
5275
|
+
const dd03pEntries = await buildDD03P(def.members, def.name.toUpperCase(), resolver);
|
|
5276
|
+
const values = { DD02V: stripEmpty(dd02v) };
|
|
5277
|
+
if ("getSettings" in obj && typeof obj.getSettings === "function") try {
|
|
5278
|
+
const settingsXml = await obj.getSettings();
|
|
5279
|
+
if (settingsXml) {
|
|
5280
|
+
const dd09l = parseSettingsToDD09L(settingsXml, def);
|
|
5281
|
+
if (dd09l) values.DD09L = stripEmpty(dd09l);
|
|
5282
|
+
}
|
|
5283
|
+
} catch {}
|
|
5284
|
+
if (dd03pEntries.length > 0) values.DD03P_TABLE = { DD03P: dd03pEntries.map((entry) => stripEmpty(entry)) };
|
|
5285
|
+
return values;
|
|
5286
|
+
}
|
|
5287
|
+
function buildTablXml(obj, ctx, values) {
|
|
5288
|
+
const fullPayload = {
|
|
5289
|
+
abap: {
|
|
5290
|
+
version: "1.0",
|
|
5291
|
+
values
|
|
5292
|
+
},
|
|
5293
|
+
version: "v1.0.0",
|
|
5294
|
+
serializer: "LCL_OBJECT_TABL",
|
|
5295
|
+
serializer_version: "v1.0.0"
|
|
5296
|
+
};
|
|
5297
|
+
return formatAbapGitXml(tabl.build(fullPayload, { pretty: true }));
|
|
5298
|
+
}
|
|
5299
|
+
async function serializeTabl(obj, ctx, options) {
|
|
5300
|
+
const objectName = ctx.getObjectName(obj);
|
|
5301
|
+
const resolved = await resolveCdsSource(obj, options?.sources);
|
|
5302
|
+
if ("fallback" in resolved) return createFallbackFile(obj, ctx);
|
|
5303
|
+
const { ast, errors } = parse(resolved.source);
|
|
5304
|
+
if (errors.length > 0 || ast.definitions.length === 0) return createFallbackFile(obj, ctx);
|
|
5305
|
+
const def = ast.definitions[0];
|
|
5306
|
+
const xml = buildTablXml(obj, ctx, await buildTablValues(obj, def));
|
|
5307
|
+
return [ctx.createFile(`${objectName}.tabl.xml`, xml)];
|
|
5308
|
+
}
|
|
5309
|
+
function fromAbapGitTabl({ DD02V } = {}) {
|
|
5310
|
+
return {
|
|
5311
|
+
name: (DD02V?.TABNAME ?? "").toUpperCase(),
|
|
5312
|
+
type: DD02V?.TABCLASS === "INTTAB" ? "TABL/DS" : "TABL/DT",
|
|
5313
|
+
description: DD02V?.DDTEXT,
|
|
5314
|
+
language: sapLangToIso(DD02V?.DDLANGUAGE),
|
|
5315
|
+
masterLanguage: sapLangToIso(DD02V?.DDLANGUAGE)
|
|
5316
|
+
};
|
|
5317
|
+
}
|
|
5318
|
+
|
|
5319
|
+
//#endregion
|
|
5320
|
+
//#region src/lib/handlers/objects/tabl.ts
|
|
5321
|
+
/**
|
|
5322
|
+
* Table/Structure (TABL) object handlers for abapGit format
|
|
5323
|
+
*
|
|
5324
|
+
* Serializes SAP tables (TABL/DT) and structures (TABL/DS) to
|
|
5325
|
+
* abapGit-compatible XML format by fetching the CDS-style source code
|
|
5326
|
+
* from SAP, parsing it with @abapify/acds, and mapping the AST into
|
|
5327
|
+
* DD02V/DD03P structures.
|
|
5328
|
+
*
|
|
5329
|
+
* Tables and structures share the same serialization logic but use
|
|
5330
|
+
* different ADT endpoints (ddic/tables vs ddic/structures).
|
|
5331
|
+
*
|
|
5332
|
+
* Data sources:
|
|
5333
|
+
* - blueSource GET: name, type, description, language
|
|
5334
|
+
* - source/main GET: CDS source with annotations and field definitions
|
|
5335
|
+
* → parsed via @abapify/acds into AST
|
|
5336
|
+
* → mapped into DD02V annotations and DD03P field entries
|
|
5337
|
+
* - Per named type: /sap/bc/adt/ddic/dataelements/{name} or /structures/{name}
|
|
5338
|
+
* → resolves COMPTYPE (E vs S), SHLPORIGIN, description (DDTEXT)
|
|
5339
|
+
*/
|
|
5340
|
+
const tableHandler = createHandler(AdkTable, {
|
|
5341
|
+
schema: tabl,
|
|
5342
|
+
version: "v1.0.0",
|
|
5343
|
+
serializer: "LCL_OBJECT_TABL",
|
|
5344
|
+
serializer_version: "v1.0.0",
|
|
5345
|
+
toAbapGit: (obj) => ({ DD02V: {
|
|
5346
|
+
TABNAME: obj.name ?? "",
|
|
5347
|
+
DDLANGUAGE: isoToSapLang(obj.language || void 0),
|
|
5348
|
+
TABCLASS: "TRANSP",
|
|
5349
|
+
DDTEXT: obj.description ?? ""
|
|
5350
|
+
} }),
|
|
5351
|
+
serialize: (obj, ctx, options) => serializeTabl(obj, ctx, options),
|
|
5352
|
+
fromAbapGit: fromAbapGitTabl
|
|
5353
|
+
});
|
|
5354
|
+
const structureHandler = createHandler(AdkStructure, {
|
|
5355
|
+
schema: tabl,
|
|
5356
|
+
version: "v1.0.0",
|
|
5357
|
+
serializer: "LCL_OBJECT_TABL",
|
|
5358
|
+
serializer_version: "v1.0.0",
|
|
5359
|
+
toAbapGit: (obj) => ({ DD02V: {
|
|
5360
|
+
TABNAME: obj.name ?? "",
|
|
5361
|
+
DDLANGUAGE: isoToSapLang(obj.language || void 0),
|
|
5362
|
+
TABCLASS: "INTTAB",
|
|
5363
|
+
DDTEXT: obj.description ?? ""
|
|
5364
|
+
} }),
|
|
5365
|
+
serialize: (obj, ctx, options) => serializeTabl(obj, ctx, options),
|
|
5366
|
+
fromAbapGit: fromAbapGitTabl
|
|
5367
|
+
});
|
|
5368
|
+
|
|
5369
|
+
//#endregion
|
|
5370
|
+
//#region src/lib/handlers/objects/ttyp.ts
|
|
5371
|
+
/**
|
|
5372
|
+
* Table Type (TTYP) object handler for abapGit format
|
|
5373
|
+
*
|
|
5374
|
+
* Maps between abapGit DD40V codes and ADT API enum values.
|
|
5375
|
+
*/
|
|
5376
|
+
/** DD40V ACCESSMODE → ADT accessType */
|
|
5377
|
+
const ACCESS_MODE_TO_ADT = {
|
|
5378
|
+
T: "standard",
|
|
5379
|
+
S: "sorted",
|
|
5380
|
+
H: "hashed"
|
|
5381
|
+
};
|
|
5382
|
+
const ACCESS_MODE_FROM_ADT = Object.fromEntries(Object.entries(ACCESS_MODE_TO_ADT).map(([k, v]) => [v, k]));
|
|
5383
|
+
/** DD40V KEYDEF → ADT primaryKey.definition */
|
|
5384
|
+
const KEY_DEF_TO_ADT = {
|
|
5385
|
+
D: "standard",
|
|
5386
|
+
K: "keyComponents",
|
|
5387
|
+
T: "rowType"
|
|
5388
|
+
};
|
|
5389
|
+
const KEY_DEF_FROM_ADT = Object.fromEntries(Object.entries(KEY_DEF_TO_ADT).map(([k, v]) => [v, k]));
|
|
5390
|
+
/** DD40V KEYKIND → ADT primaryKey.kind */
|
|
5391
|
+
const KEY_KIND_TO_ADT = {
|
|
5392
|
+
N: "nonUnique",
|
|
5393
|
+
U: "unique",
|
|
5394
|
+
G: "notSpecified"
|
|
5395
|
+
};
|
|
5396
|
+
const KEY_KIND_FROM_ADT = Object.fromEntries(Object.entries(KEY_KIND_TO_ADT).map(([k, v]) => [v, k]));
|
|
5397
|
+
/**
|
|
5398
|
+
* DD40V ROWKIND → ADT rowType.typeKind
|
|
5399
|
+
*
|
|
5400
|
+
* ROWKIND='' (empty) + DATATYPE set → predefinedAbapType (built-in like STRING, INT4)
|
|
5401
|
+
* ROWKIND='S' → dictionaryType (references a structure/table/data element)
|
|
5402
|
+
* ROWKIND='R' → ref type
|
|
5403
|
+
*/
|
|
5404
|
+
const ROW_KIND_TO_ADT = {
|
|
5405
|
+
"": "predefinedAbapType",
|
|
5406
|
+
S: "dictionaryType",
|
|
5407
|
+
R: "refToDictionaryType"
|
|
5408
|
+
};
|
|
5409
|
+
const ROW_KIND_FROM_ADT = Object.fromEntries(Object.entries(ROW_KIND_TO_ADT).map(([k, v]) => [v, k]));
|
|
5410
|
+
/**
|
|
5411
|
+
* DD40V DATATYPE (DDIC code) → ADT builtInType.dataType (ABAP type name)
|
|
5412
|
+
*
|
|
5413
|
+
* abapGit stores 4-char DDIC internal codes (e.g. STRG, RSTR).
|
|
5414
|
+
* SAP ADT REST API uses ABAP type names (e.g. STRING, XSTRING).
|
|
5415
|
+
* Most types use the same name in both (CHAR, NUMC, INT4, etc.);
|
|
5416
|
+
* only a few differ.
|
|
5417
|
+
*/
|
|
5418
|
+
const DATATYPE_TO_ADT = {
|
|
5419
|
+
STRG: "STRING",
|
|
5420
|
+
SSTR: "SSTRING",
|
|
5421
|
+
RSTR: "XSTRING",
|
|
5422
|
+
UTCL: "UTCLONG"
|
|
5423
|
+
};
|
|
5424
|
+
const DATATYPE_FROM_ADT = Object.fromEntries(Object.entries(DATATYPE_TO_ADT).map(([k, v]) => [v, k]));
|
|
5425
|
+
/**
|
|
5426
|
+
* DD40V TYPELEN — fixed internal byte length for predefined types.
|
|
5427
|
+
*
|
|
5428
|
+
* Variable-length types (STRING, XSTRING) have a fixed pointer size (8 bytes)
|
|
5429
|
+
* that abapGit stores as TYPELEN. This is not the same as LENG (display length).
|
|
5430
|
+
* We only need to emit TYPELEN for types that have noLeng=true (no external LENG).
|
|
5431
|
+
*/
|
|
5432
|
+
const FIXED_TYPELEN = {
|
|
5433
|
+
STRG: 8,
|
|
5434
|
+
RSTR: 8
|
|
5435
|
+
};
|
|
5436
|
+
const tableTypeHandler = createHandler(AdkTableType, {
|
|
5437
|
+
schema: ttyp,
|
|
5438
|
+
version: "v1.0.0",
|
|
5439
|
+
serializer: "LCL_OBJECT_TTYP",
|
|
5440
|
+
serializer_version: "v1.0.0",
|
|
5441
|
+
toAbapGit: (obj) => {
|
|
5442
|
+
const data = obj.dataSync;
|
|
5443
|
+
const accessMode = ACCESS_MODE_FROM_ADT[data?.accessType ?? ""] ?? data?.accessType ?? "";
|
|
5444
|
+
const keyDef = KEY_DEF_FROM_ADT[data?.primaryKey?.definition ?? ""] ?? data?.primaryKey?.definition ?? "";
|
|
5445
|
+
const keyKind = KEY_KIND_FROM_ADT[data?.primaryKey?.kind ?? ""] ?? data?.primaryKey?.kind ?? "";
|
|
5446
|
+
const rowKind = ROW_KIND_FROM_ADT[data?.rowType?.typeKind ?? ""] ?? data?.rowType?.typeKind ?? "";
|
|
5447
|
+
const adtDataType = data?.rowType?.builtInType?.dataType ?? "";
|
|
5448
|
+
const ddicDataType = DATATYPE_FROM_ADT[adtDataType] ?? adtDataType;
|
|
5449
|
+
const typeLen = FIXED_TYPELEN[ddicDataType];
|
|
5450
|
+
return { DD40V: {
|
|
5451
|
+
TYPENAME: obj.name ?? "",
|
|
5452
|
+
DDLANGUAGE: isoToSapLang(data?.language || void 0),
|
|
5453
|
+
ROWTYPE: data?.rowType?.typeName || void 0,
|
|
5454
|
+
ROWKIND: rowKind || void 0,
|
|
5455
|
+
DATATYPE: ddicDataType,
|
|
5456
|
+
LENG: data?.rowType?.builtInType?.length ? String(data.rowType.builtInType.length).padStart(6, "0") : void 0,
|
|
5457
|
+
DECIMALS: data?.rowType?.builtInType?.decimals ? String(data.rowType.builtInType.decimals).padStart(6, "0") : void 0,
|
|
5458
|
+
ACCESSMODE: accessMode,
|
|
5459
|
+
KEYDEF: keyDef,
|
|
5460
|
+
KEYKIND: keyKind,
|
|
5461
|
+
DDTEXT: obj.description ?? "",
|
|
5462
|
+
TYPELEN: typeLen ? String(typeLen).padStart(6, "0") : void 0,
|
|
5463
|
+
ABAP_LANGUAGE_VERSION: abapLangVerFromAdt(data?.abapLanguageVersion)
|
|
5464
|
+
} };
|
|
5465
|
+
},
|
|
5466
|
+
fromAbapGit: ({ DD40V }) => {
|
|
5467
|
+
const accessType = ACCESS_MODE_TO_ADT[DD40V?.ACCESSMODE ?? ""] ?? DD40V?.ACCESSMODE;
|
|
5468
|
+
const keyDef = KEY_DEF_TO_ADT[DD40V?.KEYDEF ?? ""] ?? DD40V?.KEYDEF;
|
|
5469
|
+
const keyKind = KEY_KIND_TO_ADT[DD40V?.KEYKIND ?? ""] ?? DD40V?.KEYKIND;
|
|
5470
|
+
const rowKind = ROW_KIND_TO_ADT[DD40V?.ROWKIND ?? ""] ?? DD40V?.ROWKIND;
|
|
5471
|
+
const ddicCode = DD40V?.DATATYPE ?? "";
|
|
5472
|
+
const adtDataType = DATATYPE_TO_ADT[ddicCode] ?? ddicCode;
|
|
5473
|
+
const isPredefined = rowKind === "predefinedAbapType";
|
|
5474
|
+
return {
|
|
5475
|
+
name: (DD40V?.TYPENAME ?? "").toUpperCase(),
|
|
5476
|
+
type: "TTYP/DA",
|
|
5477
|
+
description: DD40V?.DDTEXT,
|
|
5478
|
+
language: sapLangToIso(DD40V?.DDLANGUAGE),
|
|
5479
|
+
masterLanguage: sapLangToIso(DD40V?.DDLANGUAGE),
|
|
5480
|
+
abapLanguageVersion: abapLangVerToAdt(DD40V?.ABAP_LANGUAGE_VERSION),
|
|
5481
|
+
rowType: {
|
|
5482
|
+
typeKind: rowKind,
|
|
5483
|
+
typeName: isPredefined ? "" : DD40V?.ROWTYPE || "",
|
|
5484
|
+
builtInType: {
|
|
5485
|
+
dataType: ddicCode ? adtDataType : "",
|
|
5486
|
+
length: DD40V?.LENG ? Number(DD40V.LENG) : 0,
|
|
5487
|
+
decimals: DD40V?.DECIMALS ? Number(DD40V.DECIMALS) : 0
|
|
5488
|
+
},
|
|
5489
|
+
rangeType: ""
|
|
5490
|
+
},
|
|
5491
|
+
accessType,
|
|
5492
|
+
primaryKey: {
|
|
5493
|
+
definition: keyDef,
|
|
5494
|
+
kind: keyKind,
|
|
5495
|
+
components: { component: [] },
|
|
5496
|
+
alias: ""
|
|
5497
|
+
},
|
|
5498
|
+
secondaryKeys: { allowed: "notSpecified" }
|
|
5499
|
+
};
|
|
5500
|
+
}
|
|
5501
|
+
});
|
|
3446
5502
|
|
|
3447
5503
|
//#endregion
|
|
3448
|
-
//#region src/lib/handlers/
|
|
5504
|
+
//#region src/lib/handlers/source-resolver.ts
|
|
3449
5505
|
/**
|
|
3450
|
-
*
|
|
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).
|
|
5506
|
+
* Resolve the `main` source component for an AFF source handler.
|
|
3459
5507
|
*
|
|
3460
|
-
*
|
|
3461
|
-
*
|
|
3462
|
-
*
|
|
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)
|
|
5508
|
+
* If `sources` is supplied, only the `main` key is accepted — any other
|
|
5509
|
+
* key throws `FORMAT_SOURCE_COMPONENT_UNSUPPORTED`. When `sources` is
|
|
5510
|
+
* absent, falls back to `object.getSource()`.
|
|
3467
5511
|
*/
|
|
5512
|
+
async function resolveMainSource(object, sources, typeLabel) {
|
|
5513
|
+
if (sources !== void 0) {
|
|
5514
|
+
const keys = Object.keys(sources);
|
|
5515
|
+
if (keys.some((key) => key !== "main")) throw new FormatMaterializationError("FORMAT_SOURCE_COMPONENT_UNSUPPORTED", `${typeLabel} only supports the 'main' source component; received ${keys.join(", ")}.`);
|
|
5516
|
+
return sources.main;
|
|
5517
|
+
}
|
|
5518
|
+
return typeof object.getSource === "function" ? await object.getSource() : "";
|
|
5519
|
+
}
|
|
3468
5520
|
/**
|
|
3469
|
-
*
|
|
3470
|
-
*
|
|
5521
|
+
* Build an AFF JSON metadata file. `extra` fields are merged at the
|
|
5522
|
+
* top level alongside `formatVersion` and `header`.
|
|
3471
5523
|
*/
|
|
3472
|
-
function
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
5524
|
+
function buildAffJson(description, originalLanguage, abapLanguageVersion, extra = {}) {
|
|
5525
|
+
return `${JSON.stringify({
|
|
5526
|
+
formatVersion: "1",
|
|
5527
|
+
header: {
|
|
5528
|
+
description,
|
|
5529
|
+
originalLanguage: originalLanguage.toLowerCase(),
|
|
5530
|
+
...abapLanguageVersion ? { abapLanguageVersion } : {}
|
|
5531
|
+
},
|
|
5532
|
+
...extra
|
|
5533
|
+
}, null, 2)}\n`;
|
|
3476
5534
|
}
|
|
3477
5535
|
/**
|
|
3478
|
-
* Create
|
|
3479
|
-
*
|
|
5536
|
+
* Create the source file for an AFF handler if the source should be
|
|
5537
|
+
* included. Returns an empty array if the source is absent or empty.
|
|
3480
5538
|
*/
|
|
3481
|
-
function
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
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
|
-
} };
|
|
5539
|
+
function createAffSourceFile(ctx, params) {
|
|
5540
|
+
if (params.source === void 0) return [];
|
|
5541
|
+
if (params.suppliedSource === void 0 && params.source === "") return [];
|
|
5542
|
+
const name = ctx.getObjectName(params.object);
|
|
5543
|
+
return [ctx.createFile(`${name}.${ctx.fileExtension}.${params.sourceExt}`, params.source)];
|
|
3507
5544
|
}
|
|
3508
5545
|
/**
|
|
3509
|
-
*
|
|
5546
|
+
* Full serialize implementation for AFF source handlers.
|
|
3510
5547
|
*
|
|
3511
|
-
*
|
|
3512
|
-
*
|
|
5548
|
+
* Handles the complete source+metadata file layout in one call:
|
|
5549
|
+
* `<name>.<ext>.<sourceExt>` — source text (when included)
|
|
5550
|
+
* `<name>.<jsonExt>` — metadata JSON
|
|
3513
5551
|
*
|
|
3514
|
-
*
|
|
3515
|
-
*
|
|
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
|
|
5552
|
+
* `extra` is merged into the JSON body for handler-specific fields
|
|
5553
|
+
* (e.g. SRVD's `generalInformation`, DDLS's `sourceOrigin`).
|
|
3521
5554
|
*/
|
|
3522
|
-
function
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
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;
|
|
5555
|
+
async function serializeAffSource(object, ctx, options, config) {
|
|
5556
|
+
const source = await resolveMainSource(object, options, config.typeLabel);
|
|
5557
|
+
const name = ctx.getObjectName(object);
|
|
5558
|
+
return [...createAffSourceFile(ctx, {
|
|
5559
|
+
object,
|
|
5560
|
+
source,
|
|
5561
|
+
suppliedSource: options?.main,
|
|
5562
|
+
sourceExt: config.sourceExt
|
|
5563
|
+
}), ctx.createFile(`${name}.${config.jsonExt}`, buildAffJson(object.description || String(object.name ?? ""), object.originalLanguage ?? "en", object.abapLanguageVersion, config.extra))];
|
|
3543
5564
|
}
|
|
3544
5565
|
/**
|
|
3545
|
-
* Shared
|
|
3546
|
-
*
|
|
5566
|
+
* Shared `getSource` handler function for source-driven AFF objects
|
|
5567
|
+
* (BDEF, SRVD). Delegates to `obj.getSource()` when available.
|
|
3547
5568
|
*/
|
|
3548
|
-
|
|
3549
|
-
|
|
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)];
|
|
5569
|
+
function affGetSource(obj) {
|
|
5570
|
+
return typeof obj?.getSource === "function" ? Promise.resolve(obj.getSource()) : Promise.resolve("");
|
|
3587
5571
|
}
|
|
3588
|
-
/**
|
|
3589
|
-
|
|
5572
|
+
/**
|
|
5573
|
+
* Shared `fromAbapGit` handler function for source-driven AFF objects.
|
|
5574
|
+
* Extracts the uppercased name from the SKEY envelope.
|
|
5575
|
+
*/
|
|
5576
|
+
function affFromAbapGit(SKEY) {
|
|
5577
|
+
return { name: String(SKEY?.NAME ?? "").toUpperCase() };
|
|
5578
|
+
}
|
|
5579
|
+
/**
|
|
5580
|
+
* Shared `setSources` handler function for source-driven AFF objects.
|
|
5581
|
+
* Stores the `main` source on a `_pendingSource` property.
|
|
5582
|
+
*/
|
|
5583
|
+
function affSetSources(obj, sources) {
|
|
5584
|
+
if (sources.main !== void 0) obj._pendingSource = sources.main;
|
|
5585
|
+
}
|
|
5586
|
+
/**
|
|
5587
|
+
* Shared `fromAffJson` handler function for source-driven AFF objects.
|
|
5588
|
+
* Extracts the object name from the JSON header or falls back to the
|
|
5589
|
+
* filename-derived name passed in. The AFF JSON format stores the
|
|
5590
|
+
* description in `header.description` and the original language in
|
|
5591
|
+
* `header.originalLanguage`. Both are preserved for round-trip fidelity.
|
|
5592
|
+
*/
|
|
5593
|
+
function affFromAffJson(json, fallbackName) {
|
|
5594
|
+
const header = json.header;
|
|
3590
5595
|
return {
|
|
3591
|
-
name:
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
masterLanguage: sapLangToIso(DD02V?.DDLANGUAGE)
|
|
5596
|
+
name: fallbackName,
|
|
5597
|
+
description: header?.description,
|
|
5598
|
+
originalLanguage: header?.originalLanguage,
|
|
5599
|
+
abapLanguageVersion: header?.abapLanguageVersion
|
|
3596
5600
|
};
|
|
3597
5601
|
}
|
|
3598
|
-
|
|
3599
|
-
|
|
5602
|
+
/**
|
|
5603
|
+
* Dual-format serialize for objects that support both AFF JSON and legacy XML.
|
|
5604
|
+
*
|
|
5605
|
+
* When `options.format === 'legacy'`, produces a legacy abapGit XML metadata
|
|
5606
|
+
* file (via `ctx.toAbapGitXml`) plus the source file. Otherwise (default or
|
|
5607
|
+
* `format === 'aff'`), delegates to `serializeAffSource` to produce the AFF
|
|
5608
|
+
* JSON sidecar plus source.
|
|
5609
|
+
*/
|
|
5610
|
+
async function serializeDualFormat(object, ctx, options, config) {
|
|
5611
|
+
if (options?.format === "legacy") {
|
|
5612
|
+
const source = await resolveMainSource(object, options?.sources, config.typeLabel);
|
|
5613
|
+
const name = ctx.getObjectName(object);
|
|
5614
|
+
const files = [];
|
|
5615
|
+
if (source !== void 0) files.push(ctx.createFile(`${name}.${ctx.fileExtension}.${config.sourceExt}`, source));
|
|
5616
|
+
files.push(ctx.createFile(`${name}.${ctx.fileExtension}.xml`, ctx.toAbapGitXml(object)));
|
|
5617
|
+
return files;
|
|
5618
|
+
}
|
|
5619
|
+
return serializeAffSource(object, ctx, options?.sources, config);
|
|
5620
|
+
}
|
|
5621
|
+
|
|
5622
|
+
//#endregion
|
|
5623
|
+
//#region src/lib/handlers/objects/bdef.ts
|
|
5624
|
+
/**
|
|
5625
|
+
* BDEF (RAP Behavior Definition) object handler for abapGit format
|
|
5626
|
+
*
|
|
5627
|
+
* BDEF is source-driven: the semantic content lives in an `.abdl` file.
|
|
5628
|
+
* Supports BOTH formats:
|
|
5629
|
+
* - AFF (default): `.bdef.abdl` source + `.bdef.json` metadata sidecar
|
|
5630
|
+
* - Legacy XML: `.bdef.abdl` source + `.bdef.xml` metadata
|
|
5631
|
+
*
|
|
5632
|
+
* File layout (AFF):
|
|
5633
|
+
* src/zbp_foo.bdef.abdl — behavior source text
|
|
5634
|
+
* src/zbp_foo.bdef.json — ABAP File Formats metadata
|
|
5635
|
+
*
|
|
5636
|
+
* File layout (legacy):
|
|
5637
|
+
* src/zbp_foo.bdef.abdl — behavior source text
|
|
5638
|
+
* src/zbp_foo.bdef.xml — legacy abapGit XML metadata
|
|
5639
|
+
*/
|
|
5640
|
+
const behaviorDefinitionHandler = createHandler("BDEF", {
|
|
5641
|
+
schema: bdef,
|
|
3600
5642
|
version: "v1.0.0",
|
|
3601
|
-
serializer: "
|
|
5643
|
+
serializer: "LCL_OBJECT_BDEF",
|
|
3602
5644
|
serializer_version: "v1.0.0",
|
|
3603
|
-
toAbapGit: (obj) => ({
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
TABCLASS: "TRANSP",
|
|
3607
|
-
DDTEXT: obj.description ?? ""
|
|
5645
|
+
toAbapGit: (obj) => ({ SKEY: {
|
|
5646
|
+
TYPE: "BDEF",
|
|
5647
|
+
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3608
5648
|
} }),
|
|
3609
|
-
|
|
3610
|
-
fromAbapGit:
|
|
5649
|
+
getSource: affGetSource,
|
|
5650
|
+
fromAbapGit: ({ SKEY }) => affFromAbapGit(SKEY),
|
|
5651
|
+
fromAffJson: (json) => affFromAffJson(json, ""),
|
|
5652
|
+
serialize: (object, ctx, options) => serializeDualFormat(object, ctx, options, {
|
|
5653
|
+
typeLabel: "BDEF",
|
|
5654
|
+
sourceExt: "abdl",
|
|
5655
|
+
jsonExt: `${ctx.fileExtension}.json`
|
|
5656
|
+
}),
|
|
5657
|
+
setSources: affSetSources
|
|
3611
5658
|
});
|
|
3612
|
-
|
|
3613
|
-
|
|
5659
|
+
|
|
5660
|
+
//#endregion
|
|
5661
|
+
//#region src/lib/handlers/objects/srvd.ts
|
|
5662
|
+
/**
|
|
5663
|
+
* SRVD (RAP Service Definition) object handler for abapGit format
|
|
5664
|
+
*
|
|
5665
|
+
* SRVD is source-driven: the semantic content lives in an `.acds` file.
|
|
5666
|
+
* Supports BOTH formats:
|
|
5667
|
+
* - AFF (default): `.srvd.acds` source + `.srvd.json` metadata sidecar
|
|
5668
|
+
* - Legacy XML: `.srvd.acds` source + `.srvd.xml` metadata
|
|
5669
|
+
*
|
|
5670
|
+
* File layout (AFF):
|
|
5671
|
+
* src/zui_foo.srvd.acds — service source text
|
|
5672
|
+
* src/zui_foo.srvd.json — ABAP File Formats metadata
|
|
5673
|
+
*
|
|
5674
|
+
* File layout (legacy):
|
|
5675
|
+
* src/zui_foo.srvd.acds — service source text
|
|
5676
|
+
* src/zui_foo.srvd.xml — legacy abapGit XML metadata
|
|
5677
|
+
*/
|
|
5678
|
+
const serviceDefinitionHandler = createHandler("SRVD", {
|
|
5679
|
+
schema: srvd,
|
|
3614
5680
|
version: "v1.0.0",
|
|
3615
|
-
serializer: "
|
|
5681
|
+
serializer: "LCL_OBJECT_SRVD",
|
|
3616
5682
|
serializer_version: "v1.0.0",
|
|
3617
|
-
toAbapGit: (obj) => ({
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
TABCLASS: "INTTAB",
|
|
3621
|
-
DDTEXT: obj.description ?? ""
|
|
5683
|
+
toAbapGit: (obj) => ({ SKEY: {
|
|
5684
|
+
TYPE: "SRVD",
|
|
5685
|
+
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3622
5686
|
} }),
|
|
3623
|
-
|
|
3624
|
-
fromAbapGit:
|
|
5687
|
+
getSource: affGetSource,
|
|
5688
|
+
fromAbapGit: ({ SKEY }) => affFromAbapGit(SKEY),
|
|
5689
|
+
fromAffJson: (json) => ({
|
|
5690
|
+
...affFromAffJson(json, ""),
|
|
5691
|
+
sourceOrigin: json?.generalInformation?.sourceOrigin,
|
|
5692
|
+
sourceType: json?.generalInformation?.sourceType
|
|
5693
|
+
}),
|
|
5694
|
+
serialize: (object, ctx, options) => serializeDualFormat(object, ctx, options, {
|
|
5695
|
+
typeLabel: "SRVD",
|
|
5696
|
+
sourceExt: "acds",
|
|
5697
|
+
jsonExt: `${ctx.fileExtension}.json`,
|
|
5698
|
+
extra: { generalInformation: {
|
|
5699
|
+
sourceOrigin: object.sourceOrigin ?? "abapDevelopmentTools",
|
|
5700
|
+
sourceType: object.sourceType ?? "definition"
|
|
5701
|
+
} }
|
|
5702
|
+
}),
|
|
5703
|
+
setSources: affSetSources
|
|
5704
|
+
});
|
|
5705
|
+
|
|
5706
|
+
//#endregion
|
|
5707
|
+
//#region src/lib/handlers/objects/srvb.ts
|
|
5708
|
+
/**
|
|
5709
|
+
* SRVB (RAP Service Binding) object handler for abapGit format
|
|
5710
|
+
*
|
|
5711
|
+
* Unlike BDEF/SRVD, SRVB is **metadata-only** — there is no source text.
|
|
5712
|
+
* Supports BOTH formats:
|
|
5713
|
+
* - Legacy XML (default): `<name>.srvb.xml` with SKEY + BINDING block
|
|
5714
|
+
* - AFF JSON: `<name>.srvb.json` with formatVersion + header
|
|
5715
|
+
*
|
|
5716
|
+
* File layout (legacy):
|
|
5717
|
+
* src/zui_foo.srvb.xml — metadata only
|
|
5718
|
+
*
|
|
5719
|
+
* File layout (AFF):
|
|
5720
|
+
* src/zui_foo.srvb.json — metadata only
|
|
5721
|
+
*
|
|
5722
|
+
* Mirrors the minimal-block approach used by
|
|
5723
|
+
* zcl_abapgit_object_srvb (abapGit upstream serialiser).
|
|
5724
|
+
*/
|
|
5725
|
+
const serviceBindingHandler = createHandler("SRVB", {
|
|
5726
|
+
schema: srvb,
|
|
5727
|
+
version: "v1.0.0",
|
|
5728
|
+
serializer: "LCL_OBJECT_SRVB",
|
|
5729
|
+
serializer_version: "v1.0.0",
|
|
5730
|
+
toAbapGit: (obj) => ({
|
|
5731
|
+
SKEY: {
|
|
5732
|
+
TYPE: "SRVB",
|
|
5733
|
+
NAME: String(obj?.name ?? "").toUpperCase()
|
|
5734
|
+
},
|
|
5735
|
+
BINDING: {
|
|
5736
|
+
TYPE: "odataV4",
|
|
5737
|
+
VERSION: "4",
|
|
5738
|
+
CATEGORY: "odata_v4_ui"
|
|
5739
|
+
}
|
|
5740
|
+
}),
|
|
5741
|
+
fromAbapGit: ({ SKEY }) => ({ name: String(SKEY?.NAME ?? "").toUpperCase() }),
|
|
5742
|
+
fromAffJson: (json) => {
|
|
5743
|
+
const header = json?.header;
|
|
5744
|
+
const binding = json?.binding;
|
|
5745
|
+
return {
|
|
5746
|
+
name: "",
|
|
5747
|
+
description: header?.description,
|
|
5748
|
+
originalLanguage: header?.originalLanguage,
|
|
5749
|
+
abapLanguageVersion: header?.abapLanguageVersion,
|
|
5750
|
+
bindingType: binding?.bindingType,
|
|
5751
|
+
bindingTypeCategory: binding?.bindingTypeCategory,
|
|
5752
|
+
services: binding?.services
|
|
5753
|
+
};
|
|
5754
|
+
},
|
|
5755
|
+
async serialize(object, ctx, options) {
|
|
5756
|
+
const objectName = ctx.getObjectName(object);
|
|
5757
|
+
if (options?.format === "aff") {
|
|
5758
|
+
const bindingType = String(object?.bindingType ?? object?.data?.bindingType ?? "odataV4");
|
|
5759
|
+
const bindingTypeCategory = String(object?.bindingTypeCategory ?? object?.data?.bindingTypeCategory ?? "odata_v4_ui");
|
|
5760
|
+
const services = object?.services ?? object?.data?.services ?? [];
|
|
5761
|
+
const jsonContent = buildAffJson(String(object?.description ?? object?.name ?? ""), String(object?.originalLanguage ?? "en"), object?.abapLanguageVersion, { binding: {
|
|
5762
|
+
bindingType,
|
|
5763
|
+
bindingTypeCategory,
|
|
5764
|
+
...Array.isArray(services) && services.length > 0 ? { services } : {}
|
|
5765
|
+
} });
|
|
5766
|
+
return [ctx.createFile(`${objectName}.${ctx.fileExtension}.json`, jsonContent)];
|
|
5767
|
+
}
|
|
5768
|
+
const xmlContent = ctx.toAbapGitXml(object);
|
|
5769
|
+
return [ctx.createFile(`${objectName}.${ctx.fileExtension}.xml`, xmlContent)];
|
|
5770
|
+
}
|
|
3625
5771
|
});
|
|
3626
5772
|
|
|
3627
5773
|
//#endregion
|
|
3628
|
-
//#region src/lib/handlers/objects/
|
|
5774
|
+
//#region src/lib/handlers/objects/cds-aff-source.ts
|
|
5775
|
+
/** Create the shared dual-format source-and-metadata layout used by CDS source types.
|
|
5776
|
+
* Supports both AFF JSON (default) and legacy abapGit XML metadata. */
|
|
5777
|
+
function createCdsAffSourceHandler(type, options) {
|
|
5778
|
+
const schema = options?.schema ?? bdef;
|
|
5779
|
+
return createHandler(type, {
|
|
5780
|
+
schema,
|
|
5781
|
+
version: "v1.0.0",
|
|
5782
|
+
serializer: `LCL_OBJECT_${type}`,
|
|
5783
|
+
serializer_version: "v1.0.0",
|
|
5784
|
+
toAbapGit: (obj) => ({ SKEY: {
|
|
5785
|
+
TYPE: type,
|
|
5786
|
+
NAME: String(obj?.name ?? "").toUpperCase()
|
|
5787
|
+
} }),
|
|
5788
|
+
getSource: affGetSource,
|
|
5789
|
+
fromAbapGit: ({ SKEY }) => affFromAbapGit(SKEY),
|
|
5790
|
+
fromAffJson: (json) => options?.fromAffJsonExtra ? {
|
|
5791
|
+
...affFromAffJson(json, ""),
|
|
5792
|
+
...options.fromAffJsonExtra(json)
|
|
5793
|
+
} : affFromAffJson(json, ""),
|
|
5794
|
+
setSources: affSetSources,
|
|
5795
|
+
serialize: (object, ctx, opts) => serializeDualFormat(object, ctx, opts, {
|
|
5796
|
+
typeLabel: type,
|
|
5797
|
+
sourceExt: "acds",
|
|
5798
|
+
jsonExt: `${ctx.fileExtension}.json`,
|
|
5799
|
+
extra: options?.serializeExtra?.(object)
|
|
5800
|
+
})
|
|
5801
|
+
});
|
|
5802
|
+
}
|
|
5803
|
+
|
|
5804
|
+
//#endregion
|
|
5805
|
+
//#region src/lib/handlers/objects/dcls.ts
|
|
3629
5806
|
/**
|
|
3630
|
-
*
|
|
5807
|
+
* DCLS (ABAP Data Control Language Source) object handler for abapGit format
|
|
3631
5808
|
*
|
|
3632
|
-
*
|
|
5809
|
+
* DCLS is source-driven: the semantic content lives in an `.acds` file.
|
|
5810
|
+
* Supports BOTH formats:
|
|
5811
|
+
* - AFF (default): `.dcls.acds` source + `.dcls.json` metadata sidecar
|
|
5812
|
+
* - Legacy XML: `.dcls.acds` source + `.dcls.xml` metadata
|
|
3633
5813
|
*/
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
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]));
|
|
5814
|
+
const dclSourceHandler = createCdsAffSourceHandler("DCLS", { schema: dcls });
|
|
5815
|
+
|
|
5816
|
+
//#endregion
|
|
5817
|
+
//#region src/lib/handlers/objects/ddls.ts
|
|
3655
5818
|
/**
|
|
3656
|
-
*
|
|
5819
|
+
* DDLS (Data Definition Language Source) object handler for abapGit format
|
|
3657
5820
|
*
|
|
3658
|
-
*
|
|
3659
|
-
*
|
|
3660
|
-
*
|
|
5821
|
+
* DDLS is source-driven: the semantic content lives in an `.acds` file.
|
|
5822
|
+
* Supports BOTH formats:
|
|
5823
|
+
* - AFF (default): `.ddls.acds` source + `.ddls.json` metadata sidecar
|
|
5824
|
+
* - Legacy XML: `.ddls.acds` source + `.ddls.xml` metadata
|
|
3661
5825
|
*/
|
|
3662
|
-
const
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
5826
|
+
const ddlSourceHandler = createCdsAffSourceHandler("DDLS", {
|
|
5827
|
+
schema: ddls,
|
|
5828
|
+
fromAffJsonExtra: (json) => ({
|
|
5829
|
+
sourceOrigin: json?.sourceOrigin,
|
|
5830
|
+
sourceType: json?.sourceType
|
|
5831
|
+
}),
|
|
5832
|
+
serializeExtra: (object) => ({
|
|
5833
|
+
sourceOrigin: object.sourceOrigin ?? "abapDevelopmentTools",
|
|
5834
|
+
sourceType: object.sourceType ?? "unknown"
|
|
5835
|
+
})
|
|
5836
|
+
});
|
|
5837
|
+
|
|
5838
|
+
//#endregion
|
|
5839
|
+
//#region src/lib/handlers/objects/ddlx.ts
|
|
3668
5840
|
/**
|
|
3669
|
-
*
|
|
5841
|
+
* DDLX (CDS Metadata Extension) object handler for abapGit format
|
|
3670
5842
|
*
|
|
3671
|
-
*
|
|
3672
|
-
*
|
|
3673
|
-
*
|
|
3674
|
-
*
|
|
5843
|
+
* DDLX is source-driven: the semantic content lives in an `.acds` file.
|
|
5844
|
+
* Supports BOTH formats:
|
|
5845
|
+
* - AFF (default): `.ddlx.acds` source + `.ddlx.json` metadata sidecar
|
|
5846
|
+
* - Legacy XML: `.ddlx.acds` source + `.ddlx.xml` metadata
|
|
3675
5847
|
*/
|
|
3676
|
-
const
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
UTCL: "UTCLONG"
|
|
3681
|
-
};
|
|
3682
|
-
const DATATYPE_FROM_ADT = Object.fromEntries(Object.entries(DATATYPE_TO_ADT).map(([k, v]) => [v, k]));
|
|
5848
|
+
const ddlExtensionHandler = createCdsAffSourceHandler("DDLX", { schema: ddlx });
|
|
5849
|
+
|
|
5850
|
+
//#endregion
|
|
5851
|
+
//#region src/lib/handlers/objects/msag.ts
|
|
3683
5852
|
/**
|
|
3684
|
-
*
|
|
5853
|
+
* MSAG (Message Class) object handler for abapGit format
|
|
3685
5854
|
*
|
|
3686
|
-
*
|
|
3687
|
-
*
|
|
3688
|
-
*
|
|
5855
|
+
* Message classes are XML-only (no source code). The abapGit format stores
|
|
5856
|
+
* the class header in T100A and the individual message lines in the T100
|
|
5857
|
+
* table (wrapped in <item> elements).
|
|
3689
5858
|
*/
|
|
3690
|
-
const
|
|
3691
|
-
|
|
3692
|
-
RSTR: 8
|
|
3693
|
-
};
|
|
3694
|
-
const tableTypeHandler = createHandler(AdkTableType, {
|
|
3695
|
-
schema: ttyp,
|
|
5859
|
+
const messageClassHandler = createHandler("MSAG", {
|
|
5860
|
+
schema: msag,
|
|
3696
5861
|
version: "v1.0.0",
|
|
3697
|
-
serializer: "
|
|
5862
|
+
serializer: "LCL_OBJECT_MSAG",
|
|
3698
5863
|
serializer_version: "v1.0.0",
|
|
3699
5864
|
toAbapGit: (obj) => {
|
|
3700
|
-
const
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
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
|
-
} };
|
|
5865
|
+
const messages = obj.messages ?? [];
|
|
5866
|
+
return {
|
|
5867
|
+
T100A: {
|
|
5868
|
+
ARBGB: String(obj.name ?? "").toUpperCase(),
|
|
5869
|
+
MASTERLANG: isoToSapLang(obj.masterLanguage || obj.language),
|
|
5870
|
+
STEXT: obj.description ?? ""
|
|
5871
|
+
},
|
|
5872
|
+
T100: messages.length > 0 ? { item: messages.map((m) => ({
|
|
5873
|
+
SPRSL: isoToSapLang(m.language || obj.masterLanguage || obj.language),
|
|
5874
|
+
ARBGB: String(obj.name ?? "").toUpperCase(),
|
|
5875
|
+
MSGNR: String(m.number ?? "").padStart(3, "0"),
|
|
5876
|
+
TEXT: m.text ?? ""
|
|
5877
|
+
})) } : void 0
|
|
5878
|
+
};
|
|
3723
5879
|
},
|
|
3724
|
-
fromAbapGit: ({
|
|
3725
|
-
const
|
|
3726
|
-
const
|
|
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";
|
|
5880
|
+
fromAbapGit: ({ T100A, T100 }) => {
|
|
5881
|
+
const rawItems = T100?.item ?? [];
|
|
5882
|
+
const items = Array.isArray(rawItems) ? rawItems : [rawItems];
|
|
3732
5883
|
return {
|
|
3733
|
-
name: (
|
|
3734
|
-
type: "
|
|
3735
|
-
description:
|
|
3736
|
-
language: sapLangToIso(
|
|
3737
|
-
masterLanguage: sapLangToIso(
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
5884
|
+
name: (T100A?.ARBGB ?? "").toUpperCase(),
|
|
5885
|
+
type: "MSAG/MS",
|
|
5886
|
+
description: T100A?.STEXT,
|
|
5887
|
+
language: sapLangToIso(T100A?.MASTERLANG),
|
|
5888
|
+
masterLanguage: sapLangToIso(T100A?.MASTERLANG),
|
|
5889
|
+
messages: items.map((m) => ({
|
|
5890
|
+
number: m.MSGNR ?? "",
|
|
5891
|
+
text: m.TEXT ?? "",
|
|
5892
|
+
language: sapLangToIso(m.SPRSL)
|
|
5893
|
+
}))
|
|
5894
|
+
};
|
|
5895
|
+
}
|
|
5896
|
+
});
|
|
5897
|
+
|
|
5898
|
+
//#endregion
|
|
5899
|
+
//#region src/lib/handlers/objects/view.ts
|
|
5900
|
+
/**
|
|
5901
|
+
* VIEW (Database View) object handler for abapGit format
|
|
5902
|
+
*
|
|
5903
|
+
* Database views are XML-only (no source code). The abapGit format stores
|
|
5904
|
+
* the view header in DD25V, table assignments in DD26V_TABLE, view fields
|
|
5905
|
+
* in DD27P_TABLE and selection conditions in DD28V_TABLE.
|
|
5906
|
+
*/
|
|
5907
|
+
const viewHandler = createHandler("VIEW", {
|
|
5908
|
+
schema: view,
|
|
5909
|
+
version: "v1.0.0",
|
|
5910
|
+
serializer: "LCL_OBJECT_VIEW",
|
|
5911
|
+
serializer_version: "v1.0.0",
|
|
5912
|
+
toAbapGit: (obj) => {
|
|
5913
|
+
const tables = obj.tables ?? [];
|
|
5914
|
+
const fields = obj.fields ?? [];
|
|
5915
|
+
const conditions = obj.selectionConditions ?? [];
|
|
5916
|
+
return {
|
|
5917
|
+
DD25V: {
|
|
5918
|
+
VIEWNAME: String(obj.name ?? "").toUpperCase(),
|
|
5919
|
+
DDLANGUAGE: isoToSapLang(obj.language),
|
|
5920
|
+
DDTEXT: obj.description ?? "",
|
|
5921
|
+
VIEWCLASS: obj.viewClass ?? void 0,
|
|
5922
|
+
ROOTTAB: obj.baseTable ?? void 0,
|
|
5923
|
+
ROOTFIELD: obj.baseTableField ?? void 0
|
|
3748
5924
|
},
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
5925
|
+
DD26V_TABLE: tables.length > 0 ? { item: tables.map((t) => ({
|
|
5926
|
+
VIEWNAME: String(obj.name ?? "").toUpperCase(),
|
|
5927
|
+
TABNAME: t.tableName ?? void 0,
|
|
5928
|
+
TABPOS: t.position ?? void 0,
|
|
5929
|
+
FVIEWNAME: t.foreignView ?? void 0,
|
|
5930
|
+
FFIELDNAME: t.foreignField ?? void 0,
|
|
5931
|
+
READONLY: t.readOnly ? "X" : void 0
|
|
5932
|
+
})) } : void 0,
|
|
5933
|
+
DD27P_TABLE: fields.length > 0 ? { item: fields.map((f) => ({
|
|
5934
|
+
VIEWNAME: String(obj.name ?? "").toUpperCase(),
|
|
5935
|
+
VIEWFIELD: f.viewField ?? void 0,
|
|
5936
|
+
TABNAME: f.tableName ?? void 0,
|
|
5937
|
+
FIELDNAME: f.fieldName ?? void 0,
|
|
5938
|
+
KEYFLAG: f.keyFlag ? "X" : void 0,
|
|
5939
|
+
READONLY: f.readOnly ? "X" : void 0,
|
|
5940
|
+
ROLLNAME: f.rollName ?? void 0,
|
|
5941
|
+
CHECKTABLE: f.checkTable ?? void 0,
|
|
5942
|
+
DDTEXT: f.description ?? void 0
|
|
5943
|
+
})) } : void 0,
|
|
5944
|
+
DD28V_TABLE: conditions.length > 0 ? { item: conditions.map((c) => ({
|
|
5945
|
+
VIEWNAME: String(obj.name ?? "").toUpperCase(),
|
|
5946
|
+
ANDOR: c.andOr ?? void 0,
|
|
5947
|
+
LEFTBRACKET: c.leftBracket ?? void 0,
|
|
5948
|
+
FIELDNAME: c.fieldName ?? void 0,
|
|
5949
|
+
OPERATOR: c.operator ?? void 0,
|
|
5950
|
+
CONST_VALUE: c.constantValue ?? void 0,
|
|
5951
|
+
RIGHTBRACKET: c.rightBracket ?? void 0
|
|
5952
|
+
})) } : void 0
|
|
5953
|
+
};
|
|
5954
|
+
},
|
|
5955
|
+
fromAbapGit: parseViewFromAbapGit
|
|
5956
|
+
});
|
|
5957
|
+
function normalizeItems$3(raw) {
|
|
5958
|
+
if (!raw) return [];
|
|
5959
|
+
return Array.isArray(raw) ? raw : [raw];
|
|
5960
|
+
}
|
|
5961
|
+
function parseViewTable(t) {
|
|
5962
|
+
return {
|
|
5963
|
+
tableName: t.TABNAME,
|
|
5964
|
+
position: t.TABPOS,
|
|
5965
|
+
foreignView: t.FVIEWNAME,
|
|
5966
|
+
foreignField: t.FFIELDNAME,
|
|
5967
|
+
readOnly: t.READONLY === "X"
|
|
5968
|
+
};
|
|
5969
|
+
}
|
|
5970
|
+
function parseViewField(f) {
|
|
5971
|
+
return {
|
|
5972
|
+
viewField: f.VIEWFIELD,
|
|
5973
|
+
tableName: f.TABNAME,
|
|
5974
|
+
fieldName: f.FIELDNAME,
|
|
5975
|
+
keyFlag: f.KEYFLAG === "X",
|
|
5976
|
+
readOnly: f.READONLY === "X",
|
|
5977
|
+
rollName: f.ROLLNAME,
|
|
5978
|
+
checkTable: f.CHECKTABLE,
|
|
5979
|
+
description: f.DDTEXT
|
|
5980
|
+
};
|
|
5981
|
+
}
|
|
5982
|
+
function parseViewCondition(c) {
|
|
5983
|
+
return {
|
|
5984
|
+
andOr: c.ANDOR,
|
|
5985
|
+
leftBracket: c.LEFTBRACKET,
|
|
5986
|
+
fieldName: c.FIELDNAME,
|
|
5987
|
+
operator: c.OPERATOR,
|
|
5988
|
+
constantValue: c.CONST_VALUE,
|
|
5989
|
+
rightBracket: c.RIGHTBRACKET
|
|
5990
|
+
};
|
|
5991
|
+
}
|
|
5992
|
+
function parseViewFromAbapGit({ DD25V, DD26V_TABLE, DD27P_TABLE, DD28V_TABLE }) {
|
|
5993
|
+
const tableItems = normalizeItems$3(DD26V_TABLE?.item);
|
|
5994
|
+
const fieldItems = normalizeItems$3(DD27P_TABLE?.item);
|
|
5995
|
+
const condItems = normalizeItems$3(DD28V_TABLE?.item);
|
|
5996
|
+
return {
|
|
5997
|
+
name: (DD25V?.VIEWNAME ?? "").toUpperCase(),
|
|
5998
|
+
type: "VIEW/VD",
|
|
5999
|
+
description: DD25V?.DDTEXT,
|
|
6000
|
+
language: sapLangToIso(DD25V?.DDLANGUAGE),
|
|
6001
|
+
masterLanguage: sapLangToIso(DD25V?.DDLANGUAGE),
|
|
6002
|
+
viewClass: DD25V?.VIEWCLASS,
|
|
6003
|
+
baseTable: DD25V?.ROOTTAB,
|
|
6004
|
+
baseTableField: DD25V?.ROOTFIELD,
|
|
6005
|
+
tables: tableItems.map(parseViewTable),
|
|
6006
|
+
fields: fieldItems.map(parseViewField),
|
|
6007
|
+
selectionConditions: condItems.map(parseViewCondition)
|
|
6008
|
+
};
|
|
6009
|
+
}
|
|
6010
|
+
|
|
6011
|
+
//#endregion
|
|
6012
|
+
//#region src/lib/handlers/objects/enqu.ts
|
|
6013
|
+
/**
|
|
6014
|
+
* ENQU (Lock Object) object handler for abapGit format
|
|
6015
|
+
*
|
|
6016
|
+
* Lock objects are XML-only (no source code). The abapGit format stores
|
|
6017
|
+
* the lock object header in DD25V, table assignments in DD26V_TABLE and
|
|
6018
|
+
* lock parameters in DD27P_TABLE.
|
|
6019
|
+
*/
|
|
6020
|
+
const lockObjectHandler = createHandler("ENQU", {
|
|
6021
|
+
schema: enqu,
|
|
6022
|
+
version: "v1.0.0",
|
|
6023
|
+
serializer: "LCL_OBJECT_ENQU",
|
|
6024
|
+
serializer_version: "v1.0.0",
|
|
6025
|
+
toAbapGit: (obj) => {
|
|
6026
|
+
const tables = obj.tables ?? [];
|
|
6027
|
+
const parameters = obj.parameters ?? [];
|
|
6028
|
+
return {
|
|
6029
|
+
DD25V: {
|
|
6030
|
+
VIEWNAME: String(obj.name ?? "").toUpperCase(),
|
|
6031
|
+
DDLANGUAGE: isoToSapLang(obj.masterLanguage || obj.language),
|
|
6032
|
+
DDTEXT: obj.description ?? "",
|
|
6033
|
+
ROOTTAB: obj.baseTable ?? void 0,
|
|
6034
|
+
ROOTFIELD: obj.baseTableField ?? void 0
|
|
3755
6035
|
},
|
|
3756
|
-
|
|
6036
|
+
DD26V_TABLE: tables.length > 0 ? { item: tables.map((t) => ({
|
|
6037
|
+
VIEWNAME: String(obj.name ?? "").toUpperCase(),
|
|
6038
|
+
TABNAME: t.tableName ?? void 0,
|
|
6039
|
+
TABPOS: t.position ?? void 0,
|
|
6040
|
+
FVIEWNAME: t.foreignView ?? void 0,
|
|
6041
|
+
FFIELDNAME: t.foreignField ?? void 0,
|
|
6042
|
+
READONLY: t.readOnly ? "X" : void 0
|
|
6043
|
+
})) } : void 0,
|
|
6044
|
+
DD27P_TABLE: parameters.length > 0 ? { item: parameters.map((p) => ({
|
|
6045
|
+
VIEWNAME: String(obj.name ?? "").toUpperCase(),
|
|
6046
|
+
VIEWFIELD: p.viewField ?? void 0,
|
|
6047
|
+
TABNAME: p.tableName ?? void 0,
|
|
6048
|
+
FIELDNAME: p.fieldName ?? void 0,
|
|
6049
|
+
KEYFLAG: p.keyFlag ? "X" : void 0,
|
|
6050
|
+
ROLLNAME: p.rollName ?? void 0,
|
|
6051
|
+
CHECKTABLE: p.checkTable ?? void 0,
|
|
6052
|
+
DDTEXT: p.description ?? void 0
|
|
6053
|
+
})) } : void 0
|
|
3757
6054
|
};
|
|
3758
|
-
}
|
|
6055
|
+
},
|
|
6056
|
+
fromAbapGit: parseLockObjectFromAbapGit
|
|
3759
6057
|
});
|
|
6058
|
+
function normalizeItems$2(raw) {
|
|
6059
|
+
if (!raw) return [];
|
|
6060
|
+
return Array.isArray(raw) ? raw : [raw];
|
|
6061
|
+
}
|
|
6062
|
+
function parseEnquTable(t) {
|
|
6063
|
+
return {
|
|
6064
|
+
tableName: t.TABNAME,
|
|
6065
|
+
position: t.TABPOS,
|
|
6066
|
+
foreignView: t.FVIEWNAME,
|
|
6067
|
+
foreignField: t.FFIELDNAME,
|
|
6068
|
+
readOnly: t.READONLY === "X"
|
|
6069
|
+
};
|
|
6070
|
+
}
|
|
6071
|
+
function parseEnquParam(p) {
|
|
6072
|
+
return {
|
|
6073
|
+
viewField: p.VIEWFIELD,
|
|
6074
|
+
tableName: p.TABNAME,
|
|
6075
|
+
fieldName: p.FIELDNAME,
|
|
6076
|
+
keyFlag: p.KEYFLAG === "X",
|
|
6077
|
+
rollName: p.ROLLNAME,
|
|
6078
|
+
checkTable: p.CHECKTABLE,
|
|
6079
|
+
description: p.DDTEXT
|
|
6080
|
+
};
|
|
6081
|
+
}
|
|
6082
|
+
function parseLockObjectFromAbapGit({ DD25V, DD26V_TABLE, DD27P_TABLE }) {
|
|
6083
|
+
const tableItems = normalizeItems$2(DD26V_TABLE?.item);
|
|
6084
|
+
const paramItems = normalizeItems$2(DD27P_TABLE?.item);
|
|
6085
|
+
return {
|
|
6086
|
+
name: (DD25V?.VIEWNAME ?? "").toUpperCase(),
|
|
6087
|
+
type: "ENQU/LO",
|
|
6088
|
+
description: DD25V?.DDTEXT,
|
|
6089
|
+
language: sapLangToIso(DD25V?.DDLANGUAGE),
|
|
6090
|
+
masterLanguage: sapLangToIso(DD25V?.DDLANGUAGE),
|
|
6091
|
+
baseTable: DD25V?.ROOTTAB,
|
|
6092
|
+
baseTableField: DD25V?.ROOTFIELD,
|
|
6093
|
+
tables: tableItems.map(parseEnquTable),
|
|
6094
|
+
parameters: paramItems.map(parseEnquParam)
|
|
6095
|
+
};
|
|
6096
|
+
}
|
|
3760
6097
|
|
|
3761
6098
|
//#endregion
|
|
3762
|
-
//#region src/lib/handlers/objects/
|
|
6099
|
+
//#region src/lib/handlers/objects/shlp.ts
|
|
3763
6100
|
/**
|
|
3764
|
-
*
|
|
6101
|
+
* SHLP (Search Help) object handler for abapGit format
|
|
3765
6102
|
*
|
|
3766
|
-
*
|
|
3767
|
-
*
|
|
3768
|
-
*
|
|
6103
|
+
* Search helps are XML-only (no source code). The abapGit format stores
|
|
6104
|
+
* the search help header in DD30V, the text table info in DD31V,
|
|
6105
|
+
* parameters in DD32P_TABLE and field assignments in DD33V_TABLE.
|
|
6106
|
+
*/
|
|
6107
|
+
const searchHelpHandler = createHandler("SHLP", {
|
|
6108
|
+
schema: shlp,
|
|
6109
|
+
version: "v1.0.0",
|
|
6110
|
+
serializer: "LCL_OBJECT_SHLP",
|
|
6111
|
+
serializer_version: "v1.0.0",
|
|
6112
|
+
toAbapGit: (obj) => {
|
|
6113
|
+
const parameters = obj.parameters ?? [];
|
|
6114
|
+
const assignments = obj.fieldAssignments ?? [];
|
|
6115
|
+
return {
|
|
6116
|
+
DD30V: {
|
|
6117
|
+
SHLPNAME: String(obj.name ?? "").toUpperCase(),
|
|
6118
|
+
DDLANGUAGE: isoToSapLang(obj.language),
|
|
6119
|
+
DDTEXT: obj.description ?? "",
|
|
6120
|
+
SHLPTYPE: obj.helpType ?? void 0,
|
|
6121
|
+
DIALOGTYPE: obj.dialogType ?? void 0
|
|
6122
|
+
},
|
|
6123
|
+
DD31V: obj.textTable ? {
|
|
6124
|
+
SHLPNAME: String(obj.name ?? "").toUpperCase(),
|
|
6125
|
+
TABNAME: obj.textTable.tableName ?? void 0,
|
|
6126
|
+
FIELDNAME: obj.textTable.fieldName ?? void 0,
|
|
6127
|
+
FLDLOCATION: obj.textTable.fieldLocation ?? void 0,
|
|
6128
|
+
ROLLNAME: obj.textTable.rollName ?? void 0
|
|
6129
|
+
} : void 0,
|
|
6130
|
+
DD32P_TABLE: parameters.length > 0 ? { item: parameters.map((p) => ({
|
|
6131
|
+
SHLPNAME: String(obj.name ?? "").toUpperCase(),
|
|
6132
|
+
FIELDNAME: p.fieldName ?? void 0,
|
|
6133
|
+
SHLPINPUT: p.input ? "X" : void 0,
|
|
6134
|
+
SHLPOUTPUT: p.output ? "X" : void 0,
|
|
6135
|
+
SHLPSELPOS: p.selectionPosition ?? void 0,
|
|
6136
|
+
SHLPLISPOS: p.listPosition ?? void 0,
|
|
6137
|
+
DEFAULTVAL: p.defaultValue ?? void 0,
|
|
6138
|
+
ROLLNAME: p.rollName ?? void 0,
|
|
6139
|
+
DDTEXT: p.description ?? void 0
|
|
6140
|
+
})) } : void 0,
|
|
6141
|
+
DD33V_TABLE: assignments.length > 0 ? { item: assignments.map((a) => ({
|
|
6142
|
+
SHLPNAME: String(obj.name ?? "").toUpperCase(),
|
|
6143
|
+
SHLPFIELD: a.helpField ?? void 0,
|
|
6144
|
+
TABNAME: a.tableName ?? void 0,
|
|
6145
|
+
FIELDNAME: a.fieldName ?? void 0,
|
|
6146
|
+
SHLPINPUT: a.input ? "X" : void 0,
|
|
6147
|
+
SHLPOUTPUT: a.output ? "X" : void 0
|
|
6148
|
+
})) } : void 0
|
|
6149
|
+
};
|
|
6150
|
+
},
|
|
6151
|
+
fromAbapGit: parseSearchHelpFromAbapGit
|
|
6152
|
+
});
|
|
6153
|
+
function normalizeItems$1(raw) {
|
|
6154
|
+
if (!raw) return [];
|
|
6155
|
+
return Array.isArray(raw) ? raw : [raw];
|
|
6156
|
+
}
|
|
6157
|
+
function parseShlpParam(p) {
|
|
6158
|
+
return {
|
|
6159
|
+
fieldName: p.FIELDNAME,
|
|
6160
|
+
input: p.SHLPINPUT === "X",
|
|
6161
|
+
output: p.SHLPOUTPUT === "X",
|
|
6162
|
+
selectionPosition: p.SHLPSELPOS,
|
|
6163
|
+
listPosition: p.SHLPLISPOS,
|
|
6164
|
+
defaultValue: p.DEFAULTVAL,
|
|
6165
|
+
rollName: p.ROLLNAME,
|
|
6166
|
+
description: p.DDTEXT
|
|
6167
|
+
};
|
|
6168
|
+
}
|
|
6169
|
+
function parseShlpAssign(a) {
|
|
6170
|
+
return {
|
|
6171
|
+
helpField: a.SHLPFIELD,
|
|
6172
|
+
tableName: a.TABNAME,
|
|
6173
|
+
fieldName: a.FIELDNAME,
|
|
6174
|
+
input: a.SHLPINPUT === "X",
|
|
6175
|
+
output: a.SHLPOUTPUT === "X"
|
|
6176
|
+
};
|
|
6177
|
+
}
|
|
6178
|
+
function parseSearchHelpFromAbapGit({ DD30V, DD31V, DD32P_TABLE, DD33V_TABLE }) {
|
|
6179
|
+
const paramItems = normalizeItems$1(DD32P_TABLE?.item);
|
|
6180
|
+
const assignItems = normalizeItems$1(DD33V_TABLE?.item);
|
|
6181
|
+
return {
|
|
6182
|
+
name: (DD30V?.SHLPNAME ?? "").toUpperCase(),
|
|
6183
|
+
type: "SHLP/SH",
|
|
6184
|
+
description: DD30V?.DDTEXT,
|
|
6185
|
+
language: sapLangToIso(DD30V?.DDLANGUAGE),
|
|
6186
|
+
masterLanguage: sapLangToIso(DD30V?.DDLANGUAGE),
|
|
6187
|
+
helpType: DD30V?.SHLPTYPE,
|
|
6188
|
+
dialogType: DD30V?.DIALOGTYPE,
|
|
6189
|
+
textTable: DD31V ? {
|
|
6190
|
+
tableName: DD31V.TABNAME,
|
|
6191
|
+
fieldName: DD31V.FIELDNAME,
|
|
6192
|
+
fieldLocation: DD31V.FLDLOCATION,
|
|
6193
|
+
rollName: DD31V.ROLLNAME
|
|
6194
|
+
} : void 0,
|
|
6195
|
+
parameters: paramItems.map(parseShlpParam),
|
|
6196
|
+
fieldAssignments: assignItems.map(parseShlpAssign)
|
|
6197
|
+
};
|
|
6198
|
+
}
|
|
6199
|
+
|
|
6200
|
+
//#endregion
|
|
6201
|
+
//#region src/lib/handlers/objects/tran.ts
|
|
6202
|
+
/**
|
|
6203
|
+
* TRAN (Transaction) object handler for abapGit format
|
|
3769
6204
|
*
|
|
3770
|
-
*
|
|
3771
|
-
*
|
|
3772
|
-
*
|
|
6205
|
+
* Transactions are XML-only (no source code). The abapGit format stores
|
|
6206
|
+
* the transaction code in TSTC, GUI attributes in TSTCC and texts in
|
|
6207
|
+
* the TSTCT table (wrapped in <item> elements).
|
|
6208
|
+
*/
|
|
6209
|
+
const transactionHandler = createHandler("TRAN", {
|
|
6210
|
+
schema: tran,
|
|
6211
|
+
version: "v1.0.0",
|
|
6212
|
+
serializer: "LCL_OBJECT_TRAN",
|
|
6213
|
+
serializer_version: "v1.0.0",
|
|
6214
|
+
toAbapGit: buildTransactionToAbapGit,
|
|
6215
|
+
fromAbapGit: parseTransactionFromAbapGit
|
|
6216
|
+
});
|
|
6217
|
+
function normalizeItems(raw) {
|
|
6218
|
+
if (!raw) return [];
|
|
6219
|
+
return Array.isArray(raw) ? raw : [raw];
|
|
6220
|
+
}
|
|
6221
|
+
function parseGuiAttributes(TSTCC) {
|
|
6222
|
+
if (!TSTCC) return void 0;
|
|
6223
|
+
return {
|
|
6224
|
+
webGui: TSTCC.S_WEBGUI === "X",
|
|
6225
|
+
platinumGui: TSTCC.S_PLATIN === "X",
|
|
6226
|
+
win32Gui: TSTCC.S_WIN32 === "X",
|
|
6227
|
+
macGui: TSTCC.S_MAC === "X"
|
|
6228
|
+
};
|
|
6229
|
+
}
|
|
6230
|
+
function parseTransactionFromAbapGit({ TSTC, TSTCC, TSTCT }) {
|
|
6231
|
+
const textItems = normalizeItems(TSTCT?.item);
|
|
6232
|
+
const firstText = textItems[0];
|
|
6233
|
+
return {
|
|
6234
|
+
name: (TSTC?.TCODE ?? "").toUpperCase(),
|
|
6235
|
+
type: "TRAN/ST",
|
|
6236
|
+
description: firstText?.TTEXT,
|
|
6237
|
+
language: sapLangToIso(firstText?.SPRSL),
|
|
6238
|
+
masterLanguage: sapLangToIso(firstText?.SPRSL),
|
|
6239
|
+
programName: TSTC?.PGMNA,
|
|
6240
|
+
dynproNumber: TSTC?.DYPNO,
|
|
6241
|
+
transactionType: TSTC?.TYPE,
|
|
6242
|
+
guiAttributes: parseGuiAttributes(TSTCC),
|
|
6243
|
+
texts: textItems.map((t) => ({
|
|
6244
|
+
language: sapLangToIso(t.SPRSL),
|
|
6245
|
+
text: t.TTEXT
|
|
6246
|
+
}))
|
|
6247
|
+
};
|
|
6248
|
+
}
|
|
6249
|
+
function buildTstc(obj) {
|
|
6250
|
+
return {
|
|
6251
|
+
TCODE: String(obj.name ?? "").toUpperCase(),
|
|
6252
|
+
PGMNA: obj.programName ?? void 0,
|
|
6253
|
+
DYPNO: obj.dynproNumber ?? void 0,
|
|
6254
|
+
TYPE: obj.transactionType ?? void 0
|
|
6255
|
+
};
|
|
6256
|
+
}
|
|
6257
|
+
function buildTstcc(gui, tcode) {
|
|
6258
|
+
return {
|
|
6259
|
+
TCODE: tcode,
|
|
6260
|
+
S_WEBGUI: gui.webGui ? "X" : void 0,
|
|
6261
|
+
S_PLATIN: gui.platinumGui ? "X" : void 0,
|
|
6262
|
+
S_WIN32: gui.win32Gui ? "X" : void 0,
|
|
6263
|
+
S_MAC: gui.macGui ? "X" : void 0
|
|
6264
|
+
};
|
|
6265
|
+
}
|
|
6266
|
+
function buildTstct(texts, obj) {
|
|
6267
|
+
if (texts.length === 0) return void 0;
|
|
6268
|
+
return { item: texts.map((t) => ({
|
|
6269
|
+
SPRSL: isoToSapLang(t.language || obj.masterLanguage || obj.language),
|
|
6270
|
+
TCODE: String(obj.name ?? "").toUpperCase(),
|
|
6271
|
+
TTEXT: t.text ?? ""
|
|
6272
|
+
})) };
|
|
6273
|
+
}
|
|
6274
|
+
function buildTransactionToAbapGit(obj) {
|
|
6275
|
+
const texts = obj.texts ?? [];
|
|
6276
|
+
const tcode = String(obj.name ?? "").toUpperCase();
|
|
6277
|
+
return {
|
|
6278
|
+
TSTC: buildTstc(obj),
|
|
6279
|
+
TSTCC: obj.guiAttributes ? buildTstcc(obj.guiAttributes, tcode) : void 0,
|
|
6280
|
+
TSTCT: buildTstct(texts, obj)
|
|
6281
|
+
};
|
|
6282
|
+
}
|
|
6283
|
+
|
|
6284
|
+
//#endregion
|
|
6285
|
+
//#region src/lib/handlers/objects/type.ts
|
|
6286
|
+
/**
|
|
6287
|
+
* TYPE (Type Group / Type Pool) object handler for abapGit format
|
|
3773
6288
|
*
|
|
3774
|
-
*
|
|
3775
|
-
*
|
|
3776
|
-
|
|
6289
|
+
* Type groups have both XML metadata (TYPE structure) and ABAP source
|
|
6290
|
+
* (<name>.type.abap). The abapGit format stores the header in TYPE.
|
|
6291
|
+
*/
|
|
6292
|
+
const typeGroupHandler = createHandler("TYPE", {
|
|
6293
|
+
schema: type,
|
|
6294
|
+
version: "v1.0.0",
|
|
6295
|
+
serializer: "LCL_OBJECT_TYPE",
|
|
6296
|
+
serializer_version: "v1.0.0",
|
|
6297
|
+
toAbapGit: (obj) => ({ TYPE: {
|
|
6298
|
+
TYPEGROUP: String(obj.name ?? "").toUpperCase(),
|
|
6299
|
+
DESCRIPT: obj.description ?? ""
|
|
6300
|
+
} }),
|
|
6301
|
+
getSource: (obj) => typeof obj?.getSource === "function" ? Promise.resolve(obj.getSource()) : Promise.resolve(""),
|
|
6302
|
+
fromAbapGit: ({ TYPE }) => ({
|
|
6303
|
+
name: (TYPE?.TYPEGROUP ?? "").toUpperCase(),
|
|
6304
|
+
type: "TYPE/TY",
|
|
6305
|
+
description: TYPE?.DESCRIPT
|
|
6306
|
+
}),
|
|
6307
|
+
setSources: (obj, sources) => {
|
|
6308
|
+
if (sources.main) obj._pendingSource = sources.main;
|
|
6309
|
+
}
|
|
6310
|
+
});
|
|
6311
|
+
|
|
6312
|
+
//#endregion
|
|
6313
|
+
//#region src/lib/handlers/objects/xslt.ts
|
|
6314
|
+
/**
|
|
6315
|
+
* XSLT (Transformation) object handler for abapGit format
|
|
3777
6316
|
*
|
|
3778
|
-
*
|
|
3779
|
-
*
|
|
6317
|
+
* Transformations have both XML metadata (XSLT structure) and ABAP source
|
|
6318
|
+
* (<name>.xslt.abap). The abapGit format stores the header in XSLT.
|
|
3780
6319
|
*/
|
|
3781
|
-
const
|
|
6320
|
+
const transformationHandler = createHandler("XSLT", {
|
|
6321
|
+
schema: xslt,
|
|
6322
|
+
version: "v1.0.0",
|
|
6323
|
+
serializer: "LCL_OBJECT_XSLT",
|
|
6324
|
+
serializer_version: "v1.0.0",
|
|
6325
|
+
toAbapGit: (obj) => ({ XSLT: {
|
|
6326
|
+
PROGNAME: String(obj.name ?? "").toUpperCase(),
|
|
6327
|
+
DESCRIPT: obj.description ?? ""
|
|
6328
|
+
} }),
|
|
6329
|
+
getSource: (obj) => typeof obj?.getSource === "function" ? Promise.resolve(obj.getSource()) : Promise.resolve(""),
|
|
6330
|
+
fromAbapGit: ({ XSLT }) => ({
|
|
6331
|
+
name: (XSLT?.PROGNAME ?? "").toUpperCase(),
|
|
6332
|
+
type: "XSLT/TX",
|
|
6333
|
+
description: XSLT?.DESCRIPT
|
|
6334
|
+
}),
|
|
6335
|
+
setSources: (obj, sources) => {
|
|
6336
|
+
if (sources.main) obj._pendingSource = sources.main;
|
|
6337
|
+
}
|
|
6338
|
+
});
|
|
6339
|
+
|
|
6340
|
+
//#endregion
|
|
6341
|
+
//#region src/lib/handlers/objects/dras.ts
|
|
6342
|
+
const cdsAspectHandler = createCdsAffSourceHandler("DRAS");
|
|
6343
|
+
|
|
6344
|
+
//#endregion
|
|
6345
|
+
//#region src/lib/handlers/objects/drty.ts
|
|
6346
|
+
const cdsTypeHandler = createCdsAffSourceHandler("DRTY");
|
|
6347
|
+
|
|
6348
|
+
//#endregion
|
|
6349
|
+
//#region src/lib/handlers/objects/dsfd.ts
|
|
6350
|
+
const scalarFunctionDefinitionHandler = createCdsAffSourceHandler("DSFD");
|
|
6351
|
+
|
|
6352
|
+
//#endregion
|
|
6353
|
+
//#region src/lib/handlers/objects/dsfi.ts
|
|
6354
|
+
const VALID_ENGINES = /* @__PURE__ */ new Set(["analyticalEngine", "sqlEngine"]);
|
|
6355
|
+
function isDsfiDefinition(value) {
|
|
6356
|
+
const candidate = value;
|
|
6357
|
+
return !!candidate && candidate.formatVersion === "1" && typeof candidate.scalarFunctionName === "string" && VALID_ENGINES.has(candidate.engine ?? "") && typeof candidate.header?.description === "string" && typeof candidate.header?.originalLanguage === "string";
|
|
6358
|
+
}
|
|
6359
|
+
function parseDsfiDefinition(value) {
|
|
6360
|
+
let parsed;
|
|
6361
|
+
try {
|
|
6362
|
+
parsed = typeof value === "string" ? JSON.parse(value) : value;
|
|
6363
|
+
} catch {
|
|
6364
|
+
throw new FormatMaterializationError("FORMAT_SOURCE_COMPONENT_UNSUPPORTED", "DSFI source/main did not return valid JSON.");
|
|
6365
|
+
}
|
|
6366
|
+
if (!isDsfiDefinition(parsed)) throw new FormatMaterializationError("FORMAT_SOURCE_COMPONENT_UNSUPPORTED", "DSFI source/main did not return the required ABAP File Format JSON document.");
|
|
6367
|
+
return parsed;
|
|
6368
|
+
}
|
|
6369
|
+
const scalarFunctionImplementationHandler = createHandler("DSFI", {
|
|
3782
6370
|
schema: bdef,
|
|
3783
6371
|
version: "v1.0.0",
|
|
3784
|
-
serializer: "
|
|
6372
|
+
serializer: "LCL_OBJECT_DSFI",
|
|
3785
6373
|
serializer_version: "v1.0.0",
|
|
3786
6374
|
toAbapGit: (obj) => ({ SKEY: {
|
|
3787
|
-
TYPE: "
|
|
6375
|
+
TYPE: "DSFI",
|
|
3788
6376
|
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3789
6377
|
} }),
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
files.push(ctx.createFile(`${objectName}.${ctx.fileExtension}.xml`, xmlContent));
|
|
3799
|
-
return files;
|
|
6378
|
+
fromAffJson: (json) => {
|
|
6379
|
+
const def = json;
|
|
6380
|
+
return {
|
|
6381
|
+
name: "",
|
|
6382
|
+
description: def?.header?.description,
|
|
6383
|
+
originalLanguage: def?.header?.originalLanguage,
|
|
6384
|
+
abapLanguageVersion: def?.header?.abapLanguageVersion
|
|
6385
|
+
};
|
|
3800
6386
|
},
|
|
3801
|
-
|
|
3802
|
-
|
|
6387
|
+
async serialize(object, ctx) {
|
|
6388
|
+
const definition = parseDsfiDefinition(typeof object.getSource === "function" ? await object.getSource() : void 0);
|
|
6389
|
+
return [ctx.createFile(`${ctx.getObjectName(object)}.dsfi.json`, `${JSON.stringify(definition, null, 2)}\n`)];
|
|
3803
6390
|
}
|
|
3804
6391
|
});
|
|
3805
6392
|
|
|
3806
6393
|
//#endregion
|
|
3807
|
-
//#region src/lib/handlers/objects/
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
const serviceDefinitionHandler = createHandler("SRVD", {
|
|
3827
|
-
schema: srvd,
|
|
6394
|
+
//#region src/lib/handlers/objects/dteb.ts
|
|
6395
|
+
const entityBufferHandler = createCdsAffSourceHandler("DTEB");
|
|
6396
|
+
|
|
6397
|
+
//#endregion
|
|
6398
|
+
//#region src/lib/handlers/objects/dtdc.ts
|
|
6399
|
+
const dynamicCacheHandler = createCdsAffSourceHandler("DTDC");
|
|
6400
|
+
|
|
6401
|
+
//#endregion
|
|
6402
|
+
//#region src/lib/handlers/objects/dtix.ts
|
|
6403
|
+
const tuningIndexHandler = createCdsAffSourceHandler("DTIX");
|
|
6404
|
+
|
|
6405
|
+
//#endregion
|
|
6406
|
+
//#region src/lib/handlers/objects/dtsc.ts
|
|
6407
|
+
const staticCacheHandler = createCdsAffSourceHandler("DTSC");
|
|
6408
|
+
|
|
6409
|
+
//#endregion
|
|
6410
|
+
//#region src/lib/handlers/objects/desd.ts
|
|
6411
|
+
const externalSchemaHandler = createHandler("DESD", {
|
|
6412
|
+
schema: bdef,
|
|
3828
6413
|
version: "v1.0.0",
|
|
3829
|
-
serializer: "
|
|
6414
|
+
serializer: "LCL_OBJECT_DESD",
|
|
3830
6415
|
serializer_version: "v1.0.0",
|
|
3831
6416
|
toAbapGit: (obj) => ({ SKEY: {
|
|
3832
|
-
TYPE: "
|
|
6417
|
+
TYPE: "DESD",
|
|
3833
6418
|
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3834
6419
|
} }),
|
|
3835
|
-
|
|
3836
|
-
fromAbapGit: ({ SKEY }) => ({ name: String(SKEY?.NAME ?? "").toUpperCase() }),
|
|
6420
|
+
fromAffJson: (json) => affFromAffJson(json, ""),
|
|
3837
6421
|
async serialize(object, ctx) {
|
|
3838
|
-
const
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
setSources: (obj, sources) => {
|
|
3847
|
-
if (sources.main) obj._pendingSource = sources.main;
|
|
6422
|
+
const header = {
|
|
6423
|
+
description: object.description || String(object.name ?? ""),
|
|
6424
|
+
originalLanguage: (object.originalLanguage ?? "en").toLowerCase()
|
|
6425
|
+
};
|
|
6426
|
+
return [ctx.createFile(`${ctx.getObjectName(object)}.desd.json`, `${JSON.stringify({
|
|
6427
|
+
formatVersion: "1",
|
|
6428
|
+
header
|
|
6429
|
+
}, null, 2)}\n`)];
|
|
3848
6430
|
}
|
|
3849
6431
|
});
|
|
3850
6432
|
|
|
3851
6433
|
//#endregion
|
|
3852
|
-
//#region src/lib/handlers/
|
|
6434
|
+
//#region src/lib/handlers/aff-handler.ts
|
|
3853
6435
|
/**
|
|
3854
|
-
*
|
|
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.
|
|
6436
|
+
* Shared factory for AFF-first object handlers.
|
|
3859
6437
|
*
|
|
3860
|
-
*
|
|
3861
|
-
*
|
|
6438
|
+
* The 17 AFF-first types (APLO, BGQC, CDBO, CHKC, CHKO, CHKV, COTA, EVTB,
|
|
6439
|
+
* GSMP, NONT, RONT, SAJC, SAJT, SMBC, UIAD, UIPG, UIST) all share the same
|
|
6440
|
+
* serialization logic — only the type code and file extension differ.
|
|
6441
|
+
* This factory eliminates the per-handler duplication.
|
|
6442
|
+
*/
|
|
6443
|
+
/**
|
|
6444
|
+
* Create an AFF-first handler that serializes to JSON metadata only.
|
|
3862
6445
|
*
|
|
3863
|
-
*
|
|
3864
|
-
*
|
|
6446
|
+
* @param type ABAP object type code (e.g. 'APLO')
|
|
6447
|
+
* @param ext Lowercase file extension for the JSON sidecar (e.g. 'aplo')
|
|
3865
6448
|
*/
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
SKEY: {
|
|
3873
|
-
TYPE:
|
|
6449
|
+
function createAffFirstHandler(type, ext) {
|
|
6450
|
+
return createHandler(type, {
|
|
6451
|
+
schema: bdef,
|
|
6452
|
+
version: "v1.0.0",
|
|
6453
|
+
serializer: `LCL_OBJECT_${type}`,
|
|
6454
|
+
serializer_version: "v1.0.0",
|
|
6455
|
+
toAbapGit: (obj) => ({ SKEY: {
|
|
6456
|
+
TYPE: type,
|
|
3874
6457
|
NAME: String(obj?.name ?? "").toUpperCase()
|
|
3875
|
-
},
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
6458
|
+
} }),
|
|
6459
|
+
fromAffJson: (json) => affFromAffJson(json, ""),
|
|
6460
|
+
async serialize(object, ctx) {
|
|
6461
|
+
const header = {
|
|
6462
|
+
description: object.description || String(object.name ?? ""),
|
|
6463
|
+
originalLanguage: (object.originalLanguage ?? "en").toLowerCase()
|
|
6464
|
+
};
|
|
6465
|
+
return [ctx.createFile(`${ctx.getObjectName(object)}.${ext}.json`, `${JSON.stringify({
|
|
6466
|
+
formatVersion: "1",
|
|
6467
|
+
header
|
|
6468
|
+
}, null, 2)}\n`)];
|
|
3880
6469
|
}
|
|
3881
|
-
})
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
6470
|
+
});
|
|
6471
|
+
}
|
|
6472
|
+
|
|
6473
|
+
//#endregion
|
|
6474
|
+
//#region src/lib/handlers/objects/aplo.ts
|
|
6475
|
+
const applicationLogObjectHandler = createAffFirstHandler("APLO", "aplo");
|
|
6476
|
+
|
|
6477
|
+
//#endregion
|
|
6478
|
+
//#region src/lib/handlers/objects/bgqc.ts
|
|
6479
|
+
const bgqcHandler = createAffFirstHandler("BGQC", "bgqc");
|
|
6480
|
+
|
|
6481
|
+
//#endregion
|
|
6482
|
+
//#region src/lib/handlers/objects/cdbo.ts
|
|
6483
|
+
const cdboHandler = createAffFirstHandler("CDBO", "cdbo");
|
|
6484
|
+
|
|
6485
|
+
//#endregion
|
|
6486
|
+
//#region src/lib/handlers/objects/chkc.ts
|
|
6487
|
+
const checkCategoryHandler = createAffFirstHandler("CHKC", "chkc");
|
|
6488
|
+
|
|
6489
|
+
//#endregion
|
|
6490
|
+
//#region src/lib/handlers/objects/chko.ts
|
|
6491
|
+
const checkObjectHandler = createAffFirstHandler("CHKO", "chko");
|
|
6492
|
+
|
|
6493
|
+
//#endregion
|
|
6494
|
+
//#region src/lib/handlers/objects/chkv.ts
|
|
6495
|
+
const checkVariantHandler = createAffFirstHandler("CHKV", "chkv");
|
|
6496
|
+
|
|
6497
|
+
//#endregion
|
|
6498
|
+
//#region src/lib/handlers/objects/cota.ts
|
|
6499
|
+
const communicationTargetHandler = createAffFirstHandler("COTA", "cota");
|
|
6500
|
+
|
|
6501
|
+
//#endregion
|
|
6502
|
+
//#region src/lib/handlers/objects/evtb.ts
|
|
6503
|
+
const eventBindingHandler = createAffFirstHandler("EVTB", "evtb");
|
|
6504
|
+
|
|
6505
|
+
//#endregion
|
|
6506
|
+
//#region src/lib/handlers/objects/gsmp.ts
|
|
6507
|
+
const gsmpHandler = createAffFirstHandler("GSMP", "gsmp");
|
|
6508
|
+
|
|
6509
|
+
//#endregion
|
|
6510
|
+
//#region src/lib/handlers/objects/nont.ts
|
|
6511
|
+
const objectTypeNodeHandler = createAffFirstHandler("NONT", "nont");
|
|
6512
|
+
|
|
6513
|
+
//#endregion
|
|
6514
|
+
//#region src/lib/handlers/objects/ront.ts
|
|
6515
|
+
const objectTypeHandler = createAffFirstHandler("RONT", "ront");
|
|
6516
|
+
|
|
6517
|
+
//#endregion
|
|
6518
|
+
//#region src/lib/handlers/objects/sajc.ts
|
|
6519
|
+
const jobCatalogHandler = createAffFirstHandler("SAJC", "sajc");
|
|
6520
|
+
|
|
6521
|
+
//#endregion
|
|
6522
|
+
//#region src/lib/handlers/objects/sajt.ts
|
|
6523
|
+
const jobTemplateHandler = createAffFirstHandler("SAJT", "sajt");
|
|
6524
|
+
|
|
6525
|
+
//#endregion
|
|
6526
|
+
//#region src/lib/handlers/objects/smbc.ts
|
|
6527
|
+
const bcmHandler = createAffFirstHandler("SMBC", "smbc");
|
|
6528
|
+
|
|
6529
|
+
//#endregion
|
|
6530
|
+
//#region src/lib/handlers/objects/uiad.ts
|
|
6531
|
+
const launchpadAppDescriptorHandler = createAffFirstHandler("UIAD", "uiad");
|
|
6532
|
+
|
|
6533
|
+
//#endregion
|
|
6534
|
+
//#region src/lib/handlers/objects/uipg.ts
|
|
6535
|
+
const launchpadPageTemplateHandler = createAffFirstHandler("UIPG", "uipg");
|
|
6536
|
+
|
|
6537
|
+
//#endregion
|
|
6538
|
+
//#region src/lib/handlers/objects/uist.ts
|
|
6539
|
+
const launchpadSpaceTemplateHandler = createAffFirstHandler("UIST", "uist");
|
|
3889
6540
|
|
|
3890
6541
|
//#endregion
|
|
3891
6542
|
//#region src/lib/folder-logic.ts
|
|
@@ -4034,29 +6685,180 @@ function generateAbapGitXml(folderLogic) {
|
|
|
4034
6685
|
}
|
|
4035
6686
|
|
|
4036
6687
|
//#endregion
|
|
4037
|
-
//#region src/lib/
|
|
6688
|
+
//#region src/lib/filename-parser.ts
|
|
6689
|
+
/**
|
|
6690
|
+
* abapGit filename parsing utilities.
|
|
6691
|
+
*
|
|
6692
|
+
* Extracted into a standalone module so it can be unit-tested without
|
|
6693
|
+
* pulling in the full handler/schema dependency chain.
|
|
6694
|
+
*/
|
|
4038
6695
|
/**
|
|
4039
6696
|
* abapGit file naming convention:
|
|
4040
6697
|
* - XML metadata: {name}.{type}.xml (e.g., zcl_myclass.clas.xml)
|
|
6698
|
+
* - AFF JSON metadata: {name}.{type}.json (e.g., zfoo.bdef.json)
|
|
4041
6699
|
* - Source code: {name}.{type}.abap (e.g., zcl_myclass.clas.abap)
|
|
4042
6700
|
* - Source includes: {name}.{type}.{suffix}.abap (e.g., zcl_myclass.clas.testclasses.abap)
|
|
6701
|
+
* - AFF source files: {name}.{type}.abdl, {name}.{type}.acds, {name}.{type}.asrvd
|
|
4043
6702
|
*/
|
|
4044
6703
|
/**
|
|
4045
6704
|
* Parse abapGit filename to extract object info
|
|
6705
|
+
*
|
|
6706
|
+
* Supports both legacy XML metadata (.xml) and AFF JSON metadata (.json),
|
|
6707
|
+
* plus source file extensions (.abap, .abdl, .acds, .asrvd).
|
|
4046
6708
|
*/
|
|
4047
6709
|
function parseAbapGitFilename(filename) {
|
|
4048
|
-
const match = filename.match(/^([^.]+)\.([^.]+)(?:\.([^.]+))?\.(
|
|
6710
|
+
const match = filename.match(/^([^.]+)\.([^.]+)(?:\.([^.]+))?\.(xml|json|abap|abdl|acds|asrvd)$/);
|
|
4049
6711
|
if (!match) return null;
|
|
4050
6712
|
const [, name, type, suffixOrExt, extension] = match;
|
|
4051
|
-
|
|
6713
|
+
return {
|
|
4052
6714
|
name: name.toUpperCase(),
|
|
4053
6715
|
type: type.toUpperCase(),
|
|
4054
6716
|
suffix: suffixOrExt && suffixOrExt !== extension ? suffixOrExt : void 0,
|
|
4055
6717
|
extension
|
|
4056
6718
|
};
|
|
6719
|
+
}
|
|
6720
|
+
|
|
6721
|
+
//#endregion
|
|
6722
|
+
//#region src/lib/deserializer.ts
|
|
6723
|
+
/**
|
|
6724
|
+
* abapGit file naming convention:
|
|
6725
|
+
* - XML metadata: {name}.{type}.xml (e.g., zcl_myclass.clas.xml)
|
|
6726
|
+
* - AFF JSON metadata: {name}.{type}.json (e.g., zfoo.bdef.json)
|
|
6727
|
+
* - Source code: {name}.{type}.abap (e.g., zcl_myclass.clas.abap)
|
|
6728
|
+
* - Source includes: {name}.{type}.{suffix}.abap (e.g., zcl_myclass.clas.testclasses.abap)
|
|
6729
|
+
* - AFF source files: {name}.{type}.abdl, {name}.{type}.acds, {name}.{type}.asrvd
|
|
6730
|
+
*/
|
|
6731
|
+
/**
|
|
6732
|
+
* Resolve folder logic and start dir from .abapgit.xml
|
|
6733
|
+
*/
|
|
6734
|
+
async function resolveFolderConfig(fileTree) {
|
|
6735
|
+
let folderLogic = "prefix";
|
|
6736
|
+
let startDir = "";
|
|
6737
|
+
const hasAbapGitXml = await fileTree.exists(".abapgit.xml");
|
|
6738
|
+
if (hasAbapGitXml) try {
|
|
6739
|
+
const xml = await fileTree.read(".abapgit.xml");
|
|
6740
|
+
const meta = parseAbapGitMetadata(xml);
|
|
6741
|
+
folderLogic = meta.folderLogic;
|
|
6742
|
+
startDir = stripSlashes(meta.startingFolder);
|
|
6743
|
+
} catch {}
|
|
6744
|
+
return {
|
|
6745
|
+
folderLogic,
|
|
6746
|
+
startDir,
|
|
6747
|
+
hasAbapGitXml
|
|
6748
|
+
};
|
|
6749
|
+
}
|
|
6750
|
+
/**
|
|
6751
|
+
* Parse a metadata file path into an object key and register it in the map.
|
|
6752
|
+
*/
|
|
6753
|
+
function registerMetadataFile(path, supportedTypes, objectMap, field) {
|
|
6754
|
+
const filename = path.slice(path.lastIndexOf("/") + 1);
|
|
6755
|
+
const parsed = parseAbapGitFilename(filename);
|
|
6756
|
+
if (!parsed) return;
|
|
6757
|
+
if (!supportedTypes.has(parsed.type.toLowerCase())) return;
|
|
6758
|
+
if (parsed.suffix) return;
|
|
6759
|
+
const key = `${parsed.name}:${parsed.type}`;
|
|
6760
|
+
if (!objectMap.has(key)) objectMap.set(key, {
|
|
6761
|
+
name: parsed.name,
|
|
6762
|
+
type: parsed.type,
|
|
6763
|
+
sourceFiles: []
|
|
6764
|
+
});
|
|
6765
|
+
objectMap.get(key)[field] = path;
|
|
6766
|
+
}
|
|
6767
|
+
/**
|
|
6768
|
+
* Collect all source files and attach them to their objects in the map.
|
|
6769
|
+
*/
|
|
6770
|
+
async function collectSourceFiles(fileTree, objectMap) {
|
|
6771
|
+
const [abapFiles, abdlFiles, acdsFiles, asrvdFiles] = await Promise.all([
|
|
6772
|
+
fileTree.glob("**/*.abap"),
|
|
6773
|
+
fileTree.glob("**/*.abdl"),
|
|
6774
|
+
fileTree.glob("**/*.acds"),
|
|
6775
|
+
fileTree.glob("**/*.asrvd")
|
|
6776
|
+
]);
|
|
6777
|
+
for (const sourcePath of [
|
|
6778
|
+
...abapFiles,
|
|
6779
|
+
...abdlFiles,
|
|
6780
|
+
...acdsFiles,
|
|
6781
|
+
...asrvdFiles
|
|
6782
|
+
]) {
|
|
6783
|
+
const filename = sourcePath.slice(sourcePath.lastIndexOf("/") + 1);
|
|
6784
|
+
const parsed = parseAbapGitFilename(filename);
|
|
6785
|
+
if (!parsed) continue;
|
|
6786
|
+
const obj = objectMap.get(`${parsed.name}:${parsed.type}`);
|
|
6787
|
+
if (obj) obj.sourceFiles.push({
|
|
6788
|
+
path: sourcePath,
|
|
6789
|
+
suffix: parsed.suffix
|
|
6790
|
+
});
|
|
6791
|
+
}
|
|
6792
|
+
}
|
|
6793
|
+
/**
|
|
6794
|
+
* Parse metadata (XML or JSON) and return values + isAffJson flag.
|
|
6795
|
+
*/
|
|
6796
|
+
async function parseMetadata(fileTree, objFiles, handler) {
|
|
6797
|
+
if (objFiles.jsonFile) {
|
|
6798
|
+
const jsonContent = await fileTree.read(objFiles.jsonFile);
|
|
6799
|
+
let jsonData;
|
|
6800
|
+
try {
|
|
6801
|
+
jsonData = JSON.parse(jsonContent);
|
|
6802
|
+
} catch (parseError) {
|
|
6803
|
+
console.error(`Failed to parse AFF JSON ${objFiles.jsonFile}:`, parseError);
|
|
6804
|
+
return null;
|
|
6805
|
+
}
|
|
6806
|
+
return {
|
|
6807
|
+
values: handler?.fromAffJson ? handler.fromAffJson(jsonData) : jsonData,
|
|
6808
|
+
isAffJson: true
|
|
6809
|
+
};
|
|
6810
|
+
}
|
|
6811
|
+
if (objFiles.xmlFile) {
|
|
6812
|
+
const xmlContent = await fileTree.read(objFiles.xmlFile);
|
|
6813
|
+
return {
|
|
6814
|
+
values: handler.schema.parse(xmlContent)?.abapGit?.abap?.values ?? {},
|
|
6815
|
+
isAffJson: false
|
|
6816
|
+
};
|
|
6817
|
+
}
|
|
4057
6818
|
return null;
|
|
4058
6819
|
}
|
|
4059
6820
|
/**
|
|
6821
|
+
* Build the payload from handler or filename fallback.
|
|
6822
|
+
*/
|
|
6823
|
+
function buildPayload(handler, values, isAffJson, objFiles) {
|
|
6824
|
+
if (isAffJson && handler?.fromAffJson) return values;
|
|
6825
|
+
if (isAffJson) return { name: objFiles.name };
|
|
6826
|
+
if (handler?.fromAbapGit) return handler.fromAbapGit(values);
|
|
6827
|
+
return { name: objFiles.name };
|
|
6828
|
+
}
|
|
6829
|
+
/**
|
|
6830
|
+
* Set sources on an ADK object using handler or fallback.
|
|
6831
|
+
*/
|
|
6832
|
+
function setObjectSources(handler, adkObject, sources) {
|
|
6833
|
+
if (Object.keys(sources).length === 0) return;
|
|
6834
|
+
if (handler?.setSources) {
|
|
6835
|
+
handler.setSources(adkObject, sources);
|
|
6836
|
+
return;
|
|
6837
|
+
}
|
|
6838
|
+
if (sources["main"]) adkObject._pendingSource = sources["main"];
|
|
6839
|
+
if (Object.keys(sources).length > 1) adkObject._pendingSources = sources;
|
|
6840
|
+
}
|
|
6841
|
+
/**
|
|
6842
|
+
* Resolve packageRef on an ADK object from folder logic or rootPackage.
|
|
6843
|
+
*/
|
|
6844
|
+
function resolvePackageRef(adkObject, options, hasAbapGitXml, folderLogic) {
|
|
6845
|
+
if (!options?.rootPackage) return;
|
|
6846
|
+
const data = adkObject._data;
|
|
6847
|
+
if (!data || data.packageRef) return;
|
|
6848
|
+
if (hasAbapGitXml) {
|
|
6849
|
+
const relDir = adkObject._relDir ?? "";
|
|
6850
|
+
data.packageRef = { name: resolvePackageFromDir(relDir, folderLogic, options.rootPackage) };
|
|
6851
|
+
} else data.packageRef = { name: options.rootPackage };
|
|
6852
|
+
}
|
|
6853
|
+
/**
|
|
6854
|
+
* Set abapLanguageVersion on an ADK object if provided in options.
|
|
6855
|
+
*/
|
|
6856
|
+
function setAbapLanguageVersion(adkObject, options) {
|
|
6857
|
+
if (!options?.abapLanguageVersion) return;
|
|
6858
|
+
const data = adkObject._data;
|
|
6859
|
+
if (data && !data.abapLanguageVersion) data.abapLanguageVersion = abapLangVerToAdt(options.abapLanguageVersion) ?? options.abapLanguageVersion;
|
|
6860
|
+
}
|
|
6861
|
+
/**
|
|
4060
6862
|
* Deserialize abapGit files to ADK objects
|
|
4061
6863
|
*
|
|
4062
6864
|
* True generator - yields objects one at a time as they're discovered.
|
|
@@ -4068,119 +6870,131 @@ function parseAbapGitFilename(filename) {
|
|
|
4068
6870
|
*/
|
|
4069
6871
|
async function* deserialize(fileTree, client, options) {
|
|
4070
6872
|
const adk = createAdk(client);
|
|
4071
|
-
|
|
4072
|
-
|
|
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");
|
|
6873
|
+
const { folderLogic, startDir, hasAbapGitXml } = await resolveFolderConfig(fileTree);
|
|
6874
|
+
const [xmlFiles, jsonFiles] = await Promise.all([fileTree.glob("**/*.xml"), fileTree.glob("**/*.json")]);
|
|
4080
6875
|
const objectMap = /* @__PURE__ */ new Map();
|
|
4081
6876
|
const supportedTypes = new Set(getSupportedTypes().map((t) => t.toLowerCase()));
|
|
4082
6877
|
for (const xmlPath of xmlFiles) {
|
|
4083
6878
|
if (xmlPath.endsWith(".abapgit.xml")) continue;
|
|
4084
6879
|
if (xmlPath.endsWith("package.devc.xml")) continue;
|
|
4085
|
-
|
|
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
|
-
});
|
|
6880
|
+
registerMetadataFile(xmlPath, supportedTypes, objectMap, "xmlFile");
|
|
4108
6881
|
}
|
|
6882
|
+
for (const jsonPath of jsonFiles) registerMetadataFile(jsonPath, supportedTypes, objectMap, "jsonFile");
|
|
6883
|
+
await collectSourceFiles(fileTree, objectMap);
|
|
4109
6884
|
for (const [, objFiles] of objectMap) {
|
|
4110
|
-
if (!objFiles.xmlFile) continue;
|
|
6885
|
+
if (!objFiles.xmlFile && !objFiles.jsonFile) continue;
|
|
4111
6886
|
const handler = getHandler(objFiles.type);
|
|
4112
6887
|
if (!handler) continue;
|
|
4113
6888
|
try {
|
|
4114
|
-
const
|
|
4115
|
-
|
|
6889
|
+
const meta = await parseMetadata(fileTree, objFiles, handler);
|
|
6890
|
+
if (!meta) continue;
|
|
6891
|
+
const { values, isAffJson } = meta;
|
|
4116
6892
|
const sources = {};
|
|
4117
6893
|
for (const { path, suffix } of objFiles.sourceFiles) {
|
|
4118
6894
|
const content = await fileTree.read(path);
|
|
4119
6895
|
const sourceKey = suffix ? handler.suffixToSourceKey?.[suffix] ?? suffix : "main";
|
|
4120
6896
|
sources[sourceKey] = content;
|
|
4121
6897
|
}
|
|
4122
|
-
const payload = handler
|
|
6898
|
+
const payload = buildPayload(handler, values, isAffJson, objFiles);
|
|
4123
6899
|
const objectName = payload.name || objFiles.name;
|
|
4124
|
-
const
|
|
6900
|
+
const adkType = typeof payload.type === "string" ? payload.type : objFiles.type;
|
|
6901
|
+
const adkObject = adk.getWithData({
|
|
4125
6902
|
...payload,
|
|
4126
6903
|
name: objectName
|
|
4127
|
-
};
|
|
4128
|
-
|
|
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
|
-
}
|
|
6904
|
+
}, adkType);
|
|
6905
|
+
setObjectSources(handler, adkObject, sources);
|
|
4135
6906
|
if (payload.description) adkObject._pendingDescription = payload.description;
|
|
4136
6907
|
if (hasAbapGitXml) {
|
|
4137
|
-
const sourceDir = objFiles.xmlFile.split("/").slice(0, -1).join("/");
|
|
6908
|
+
const sourceDir = (objFiles.xmlFile ?? objFiles.jsonFile ?? "").split("/").slice(0, -1).join("/");
|
|
4138
6909
|
adkObject._relDir = sourceDir.startsWith(startDir) ? sourceDir.slice(startDir.length).replace(/^\/+/, "") : sourceDir;
|
|
4139
6910
|
adkObject._folderLogic = folderLogic;
|
|
4140
6911
|
}
|
|
4141
|
-
|
|
4142
|
-
|
|
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
|
-
}
|
|
6912
|
+
resolvePackageRef(adkObject, options, hasAbapGitXml, folderLogic);
|
|
6913
|
+
setAbapLanguageVersion(adkObject, options);
|
|
4150
6914
|
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
|
-
}
|
|
6915
|
+
if (objFiles.type === "FUGR" && payload._functions) yield* yieldFugrChildren(adk, payload, objectName, options, adkObject);
|
|
4176
6916
|
} catch (error) {
|
|
4177
6917
|
console.error(`Failed to deserialize ${objFiles.type} ${objFiles.name}:`, error);
|
|
4178
6918
|
}
|
|
4179
6919
|
}
|
|
4180
6920
|
}
|
|
6921
|
+
/**
|
|
6922
|
+
* Yield FUGR child function modules as separate ADK objects.
|
|
6923
|
+
*/
|
|
6924
|
+
async function* yieldFugrChildren(adk, payload, parentName, options, parentObject) {
|
|
6925
|
+
const fmDescriptors = extractFunctionDescriptors(payload._functions);
|
|
6926
|
+
const fmSources = parentObject._pendingFmSources;
|
|
6927
|
+
for (const fm of fmDescriptors) try {
|
|
6928
|
+
const fmObject = adk.getWithData({
|
|
6929
|
+
name: fm.funcName,
|
|
6930
|
+
type: "FUGR/FF",
|
|
6931
|
+
_groupName: parentName,
|
|
6932
|
+
description: fm.shortText ?? "",
|
|
6933
|
+
processingType: fm.processingType,
|
|
6934
|
+
basXMLEnabled: fm.basXMLEnabled
|
|
6935
|
+
}, "FUGR/FF");
|
|
6936
|
+
const fmSource = fmSources?.[fm.funcName.toLowerCase()];
|
|
6937
|
+
if (fmSource) fmObject._pendingSource = fmSource;
|
|
6938
|
+
setAbapLanguageVersion(fmObject, options);
|
|
6939
|
+
yield fmObject;
|
|
6940
|
+
} catch (fmError) {
|
|
6941
|
+
console.error(`Failed to deserialize FM ${fm.funcName} in FUGR ${parentName}:`, fmError);
|
|
6942
|
+
}
|
|
6943
|
+
}
|
|
4181
6944
|
|
|
4182
6945
|
//#endregion
|
|
4183
6946
|
//#region src/lib/format-plugin.ts
|
|
6947
|
+
/**
|
|
6948
|
+
* abapGit as a FormatPlugin.
|
|
6949
|
+
*
|
|
6950
|
+
* This is the thin adapter that plugs the abapGit handler registry into the
|
|
6951
|
+
* generic `FormatPlugin` contract defined by `@abapify/adt-plugin`. External
|
|
6952
|
+
* consumers (adt-export, adt-diff, adt-cli) interact with this plugin
|
|
6953
|
+
* **through the registry only** — they look it up with
|
|
6954
|
+
* `getFormatPlugin('abapgit')` and never import this package directly.
|
|
6955
|
+
*
|
|
6956
|
+
* Registration happens as a side-effect of importing `@abapify/adt-plugin-abapgit`;
|
|
6957
|
+
* the CLI bootstraps the registration once in `adt-cli/src/lib/cli.ts`.
|
|
6958
|
+
*/
|
|
6959
|
+
function classifyFile(parsed, handler) {
|
|
6960
|
+
if (parsed.extension === "xml" || parsed.extension === "json") return { role: "metadata" };
|
|
6961
|
+
if (!parsed.suffix) return {
|
|
6962
|
+
role: "source",
|
|
6963
|
+
sourceComponent: "main"
|
|
6964
|
+
};
|
|
6965
|
+
if (parsed.type.toLowerCase() === "fugr" && parsed.suffix.toLowerCase() === `l${parsed.name.toLowerCase()}top`) return {
|
|
6966
|
+
role: "source",
|
|
6967
|
+
sourceComponent: "main"
|
|
6968
|
+
};
|
|
6969
|
+
return {
|
|
6970
|
+
role: "source",
|
|
6971
|
+
sourceComponent: handler.suffixToSourceKey?.[parsed.suffix] ?? parsed.suffix
|
|
6972
|
+
};
|
|
6973
|
+
}
|
|
6974
|
+
function assertSupportsExplicitSources(handler, objectType, sources) {
|
|
6975
|
+
if (!sources) return;
|
|
6976
|
+
if (Object.keys(sources).length === 0) return;
|
|
6977
|
+
if (handler.supportsExplicitSources) return;
|
|
6978
|
+
throw new FormatMaterializationError("FORMAT_SOURCE_COMPONENT_UNSUPPORTED", `abapGit handler for "${objectType}" does not support explicit source selection.`);
|
|
6979
|
+
}
|
|
6980
|
+
async function buildMaterializedFiles(handler, object, packageDir, sources, format) {
|
|
6981
|
+
return (await handler.serialize(object, {
|
|
6982
|
+
...sources !== void 0 ? { sources } : {},
|
|
6983
|
+
...format !== void 0 ? { format } : {}
|
|
6984
|
+
})).map((file) => {
|
|
6985
|
+
const parsed = parseAbapGitFilename(file.path);
|
|
6986
|
+
const classification = parsed ? classifyFile(parsed, handler) : {
|
|
6987
|
+
role: "source",
|
|
6988
|
+
sourceComponent: "main"
|
|
6989
|
+
};
|
|
6990
|
+
const path = posix.join("src", packageDir, file.path);
|
|
6991
|
+
return {
|
|
6992
|
+
...file,
|
|
6993
|
+
path,
|
|
6994
|
+
...classification
|
|
6995
|
+
};
|
|
6996
|
+
}).sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
|
|
6997
|
+
}
|
|
4184
6998
|
const abapgitFormatPlugin = {
|
|
4185
6999
|
id: "abapgit",
|
|
4186
7000
|
description: "abapGit serialization format",
|
|
@@ -4188,7 +7002,19 @@ const abapgitFormatPlugin = {
|
|
|
4188
7002
|
return getSupportedTypes();
|
|
4189
7003
|
},
|
|
4190
7004
|
getHandler(type) {
|
|
4191
|
-
|
|
7005
|
+
const handler = getHandler(type);
|
|
7006
|
+
return handler ? {
|
|
7007
|
+
...handler,
|
|
7008
|
+
supportsExplicitSources: handler.supportsExplicitSources ?? false
|
|
7009
|
+
} : void 0;
|
|
7010
|
+
},
|
|
7011
|
+
async materialize(input) {
|
|
7012
|
+
const handler = this.getHandler(input.objectType);
|
|
7013
|
+
if (!handler) throw new FormatMaterializationError("FORMAT_OBJECT_TYPE_UNSUPPORTED", `abapGit does not support object type "${input.objectType}".`);
|
|
7014
|
+
assertSupportsExplicitSources(handler, input.objectType, input.sources);
|
|
7015
|
+
const folderLogic = parseFolderLogic(input.formatOptions?.folderLogic) ?? "prefix";
|
|
7016
|
+
const packageDir = calculatePackageDir([...input.packagePath], folderLogic);
|
|
7017
|
+
return { files: await buildMaterializedFiles(handler, input.object, packageDir, input.sources, input.formatOptions?.format) };
|
|
4192
7018
|
},
|
|
4193
7019
|
parseFilename(filename) {
|
|
4194
7020
|
return parseAbapGitFilename(filename) ?? void 0;
|
|
@@ -4217,6 +7043,9 @@ var AbapGitSerializer = class {
|
|
|
4217
7043
|
const writtenFiles = [];
|
|
4218
7044
|
for (const file of serializedFiles) {
|
|
4219
7045
|
const filePath = join(fullPackageDir, file.path);
|
|
7046
|
+
const relativePath = relative(fullPackageDir, filePath);
|
|
7047
|
+
if (!relativePath || isAbsolute(relativePath) || relativePath === ".." || relativePath.startsWith(`..${sep}`)) throw new Error(`Invalid serialized file path: ${file.path}`);
|
|
7048
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
4220
7049
|
writeFileSync(filePath, file.content, file.encoding ?? "utf8");
|
|
4221
7050
|
writtenFiles.push(filePath);
|
|
4222
7051
|
}
|
|
@@ -4291,7 +7120,8 @@ function readFolderLogicFromExistingRepo(targetPath) {
|
|
|
4291
7120
|
const abapgitXmlPath = join(targetPath, ".abapgit.xml");
|
|
4292
7121
|
if (!existsSync(abapgitXmlPath)) return;
|
|
4293
7122
|
try {
|
|
4294
|
-
|
|
7123
|
+
const xmlContent = readFileSync(abapgitXmlPath, "utf-8");
|
|
7124
|
+
return parseFolderLogicFromAbapGitXml(xmlContent);
|
|
4295
7125
|
} catch {
|
|
4296
7126
|
return;
|
|
4297
7127
|
}
|
|
@@ -4338,7 +7168,27 @@ const abapGitPlugin = createPlugin({
|
|
|
4338
7168
|
};
|
|
4339
7169
|
}
|
|
4340
7170
|
},
|
|
7171
|
+
/**
|
|
7172
|
+
* Export abapGit files to SAP
|
|
7173
|
+
*
|
|
7174
|
+
* Reads abapGit format files from FileTree and yields AdkObject instances.
|
|
7175
|
+
* True generator - streams objects one at a time for memory efficiency.
|
|
7176
|
+
*
|
|
7177
|
+
* @param fileTree - Virtual file system abstraction
|
|
7178
|
+
* @param client - ADT client for creating ADK objects
|
|
7179
|
+
*/
|
|
4341
7180
|
export: (fileTree, client, options) => deserialize(fileTree, client, options),
|
|
7181
|
+
/**
|
|
7182
|
+
* Delete local abapGit files for an object marked for deletion in SAP.
|
|
7183
|
+
*
|
|
7184
|
+
* Searches the `<targetPath>/src/` directory tree for files matching
|
|
7185
|
+
* the abapGit naming pattern `{name}.{type}[.suffix].{ext}` and removes
|
|
7186
|
+
* each one.
|
|
7187
|
+
*
|
|
7188
|
+
* Known limitation: if the object never made it into the repository (e.g.
|
|
7189
|
+
* PROG deletions without obj_func=D), no files are present and nothing
|
|
7190
|
+
* happens. This is expected behavior.
|
|
7191
|
+
*/
|
|
4342
7192
|
async delete(objectRef, targetPath, _context) {
|
|
4343
7193
|
try {
|
|
4344
7194
|
const matchedFiles = findObjectFiles(join(targetPath, "src"), objectRef.name, objectRef.type);
|
|
@@ -4370,145 +7220,12 @@ const abapGitPlugin = createPlugin({
|
|
|
4370
7220
|
},
|
|
4371
7221
|
hooks: { async afterImport(targetPath) {
|
|
4372
7222
|
mkdirSync(targetPath, { recursive: true });
|
|
4373
|
-
|
|
7223
|
+
const abapgitXmlPath = join(targetPath, ".abapgit.xml");
|
|
7224
|
+
const abapgitXmlContent = generateAbapGitXml(currentFolderLogic);
|
|
7225
|
+
writeFileSync(abapgitXmlPath, abapgitXmlContent, "utf-8");
|
|
4374
7226
|
} }
|
|
4375
7227
|
});
|
|
4376
7228
|
|
|
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
7229
|
//#endregion
|
|
4513
7230
|
//#region src/index.ts
|
|
4514
7231
|
registerFormatPlugin(abapgitFormatPlugin);
|