@abapify/adt-plugin-abapgit 0.4.33 → 0.4.36
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 +22 -173
- package/dist/index.d.mts +10 -12
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +233 -196
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -68,7 +68,7 @@ function formatXmlAttributes(xml) {
|
|
|
68
68
|
}
|
|
69
69
|
const tagContent = xml.slice(openBracket + 1, closeBracket);
|
|
70
70
|
const spaceIdx = tagContent.indexOf(" ");
|
|
71
|
-
if (spaceIdx === -1 || tagContent
|
|
71
|
+
if (spaceIdx === -1 || tagContent.startsWith("/") || tagContent.startsWith("!") || tagContent.startsWith("?")) {
|
|
72
72
|
result += xml.slice(openBracket, closeBracket + 1);
|
|
73
73
|
pos = closeBracket + 1;
|
|
74
74
|
continue;
|
|
@@ -257,7 +257,8 @@ function createHandler(adkClassOrType, definition) {
|
|
|
257
257
|
const suffixBySourceKey = new Map([["main", void 0], ...Object.entries(definition.suffixToSourceKey ?? {}).map(([suffix, sourceKey]) => [sourceKey, suffix])]);
|
|
258
258
|
const objectName = ctx.getObjectName(object);
|
|
259
259
|
const files = [];
|
|
260
|
-
|
|
260
|
+
sourceKeys.sort((left, right) => left.localeCompare(right, "en-US"));
|
|
261
|
+
for (const sourceKey of sourceKeys) {
|
|
261
262
|
const file = createExplicitSourceFile(sourceKey, sources[sourceKey], suffixBySourceKey, objectName);
|
|
262
263
|
if (file) files.push(file);
|
|
263
264
|
}
|
|
@@ -19478,10 +19479,11 @@ const programHandler = createHandler("PROG", {
|
|
|
19478
19479
|
...data,
|
|
19479
19480
|
type: "PROG/I"
|
|
19480
19481
|
};
|
|
19482
|
+
const baseProgramType = subc === "S" ? "subroutinePool" : "executableProgram";
|
|
19481
19483
|
return {
|
|
19482
19484
|
...data,
|
|
19483
19485
|
type: "PROG/P",
|
|
19484
|
-
programType: subc === "M" ? "modulePool" :
|
|
19486
|
+
programType: subc === "M" ? "modulePool" : baseProgramType
|
|
19485
19487
|
};
|
|
19486
19488
|
},
|
|
19487
19489
|
setSources: (obj, sources) => {
|
|
@@ -19567,7 +19569,7 @@ async function buildFunctionModuleFiles(obj, fmItems, suppliedSources, ctx) {
|
|
|
19567
19569
|
const suppliedFmSource = suppliedSources?.[sourceKey];
|
|
19568
19570
|
if (hasExplicitSources && suppliedFmSource === void 0) continue;
|
|
19569
19571
|
try {
|
|
19570
|
-
const source = suppliedFmSource
|
|
19572
|
+
const source = suppliedFmSource ?? await obj.client.adt.functions.groups.fmodules.source.main.get(obj.name, fm.name);
|
|
19571
19573
|
if (shouldIncludeSource(source, suppliedFmSource)) files.push(ctx.createFile(`${objectName}.${ctx.fileExtension}.${funcName}.abap`, source));
|
|
19572
19574
|
} catch {}
|
|
19573
19575
|
}
|
|
@@ -19664,7 +19666,10 @@ async function discoverFunctionModules(obj) {
|
|
|
19664
19666
|
let match;
|
|
19665
19667
|
while ((match = regex.exec(responseStr)) !== null) fmNames.push({ name: match[1] });
|
|
19666
19668
|
const regex2 = /adtcore:name="([^"]+)"[^>]*type="FUGR\/FF"/g;
|
|
19667
|
-
while ((match = regex2.exec(responseStr)) !== null)
|
|
19669
|
+
while ((match = regex2.exec(responseStr)) !== null) {
|
|
19670
|
+
const name = match[1];
|
|
19671
|
+
if (name && !fmNames.some((f) => f.name === name)) fmNames.push({ name });
|
|
19672
|
+
}
|
|
19668
19673
|
return fmNames;
|
|
19669
19674
|
} catch {
|
|
19670
19675
|
return [];
|
|
@@ -19694,7 +19699,13 @@ async function serializeFunctions(obj, fmItems) {
|
|
|
19694
19699
|
}
|
|
19695
19700
|
function extractFunctionDescriptors(functions) {
|
|
19696
19701
|
if (!functions) return [];
|
|
19697
|
-
|
|
19702
|
+
const functionsRecord = functions;
|
|
19703
|
+
let items;
|
|
19704
|
+
if (Array.isArray(functions)) items = functions;
|
|
19705
|
+
else if (Array.isArray(functionsRecord?.item)) items = functionsRecord.item;
|
|
19706
|
+
else if (functionsRecord?.item) items = [functionsRecord.item];
|
|
19707
|
+
else items = [];
|
|
19708
|
+
return items.map((fm) => ({
|
|
19698
19709
|
funcName: String(fm.FUNCNAME ?? ""),
|
|
19699
19710
|
shortText: fm.SHORT_TEXT ? String(fm.SHORT_TEXT) : void 0,
|
|
19700
19711
|
processingType: remoteCallToProcessingType(fm.REMOTE_CALL, fm.UPDATE_TASK),
|
|
@@ -19847,6 +19858,18 @@ const TYPEKIND_TO_REFTYPE = {
|
|
|
19847
19858
|
refToPredefinedAbapType: "E"
|
|
19848
19859
|
};
|
|
19849
19860
|
/**
|
|
19861
|
+
* Map abapGit REFKIND/REFTYPE back to the ADT `typeKind` enum.
|
|
19862
|
+
*/
|
|
19863
|
+
function typeKindFromRef(refKind, refType, dataType) {
|
|
19864
|
+
if (refKind === "D") return "domain";
|
|
19865
|
+
if (refKind === "R") return refType === "C" ? "refToClifType" : "refToDictionaryType";
|
|
19866
|
+
return dataType ? "predefinedAbapType" : "domain";
|
|
19867
|
+
}
|
|
19868
|
+
/** Numeric DD04V field → number (empty/absent → 0). */
|
|
19869
|
+
function numOr0(value) {
|
|
19870
|
+
return value ? Number(value) : 0;
|
|
19871
|
+
}
|
|
19872
|
+
/**
|
|
19850
19873
|
* Derive OUTPUTLEN from ABAP data type + length + decimals.
|
|
19851
19874
|
*
|
|
19852
19875
|
* The ADT REST API for data elements does not return OUTPUTLEN — SAP derives
|
|
@@ -19929,12 +19952,7 @@ const dataElementHandler = createHandler(AdkDataElement, {
|
|
|
19929
19952
|
} };
|
|
19930
19953
|
},
|
|
19931
19954
|
fromAbapGit: ({ DD04V }) => {
|
|
19932
|
-
const
|
|
19933
|
-
const refType = DD04V?.REFTYPE ?? "";
|
|
19934
|
-
let typeKind;
|
|
19935
|
-
if (refKind === "D") typeKind = "domain";
|
|
19936
|
-
else if (refKind === "R") typeKind = refType === "C" ? "refToClifType" : "refToDictionaryType";
|
|
19937
|
-
else typeKind = DD04V?.DATATYPE ? "predefinedAbapType" : "domain";
|
|
19955
|
+
const typeKind = typeKindFromRef(DD04V?.REFKIND ?? "", DD04V?.REFTYPE ?? "", DD04V?.DATATYPE);
|
|
19938
19956
|
return {
|
|
19939
19957
|
name: (DD04V?.ROLLNAME ?? "").toUpperCase(),
|
|
19940
19958
|
type: "DTEL/DE",
|
|
@@ -19946,22 +19964,22 @@ const dataElementHandler = createHandler(AdkDataElement, {
|
|
|
19946
19964
|
typeKind,
|
|
19947
19965
|
typeName: DD04V?.DOMNAME || "",
|
|
19948
19966
|
dataType: DD04V?.DATATYPE || "",
|
|
19949
|
-
dataTypeLength: DD04V?.LENG
|
|
19967
|
+
dataTypeLength: numOr0(DD04V?.LENG),
|
|
19950
19968
|
dataTypeLengthEnabled: false,
|
|
19951
|
-
dataTypeDecimals: DD04V?.DECIMALS
|
|
19969
|
+
dataTypeDecimals: numOr0(DD04V?.DECIMALS),
|
|
19952
19970
|
dataTypeDecimalsEnabled: false,
|
|
19953
19971
|
shortFieldLabel: DD04V?.SCRTEXT_S || "",
|
|
19954
|
-
shortFieldLength: DD04V?.SCRLEN1
|
|
19955
|
-
shortFieldMaxLength: DD04V?.SCRLEN1
|
|
19972
|
+
shortFieldLength: numOr0(DD04V?.SCRLEN1),
|
|
19973
|
+
shortFieldMaxLength: numOr0(DD04V?.SCRLEN1),
|
|
19956
19974
|
mediumFieldLabel: DD04V?.SCRTEXT_M || "",
|
|
19957
|
-
mediumFieldLength: DD04V?.SCRLEN2
|
|
19958
|
-
mediumFieldMaxLength: DD04V?.SCRLEN2
|
|
19975
|
+
mediumFieldLength: numOr0(DD04V?.SCRLEN2),
|
|
19976
|
+
mediumFieldMaxLength: numOr0(DD04V?.SCRLEN2),
|
|
19959
19977
|
longFieldLabel: DD04V?.SCRTEXT_L || "",
|
|
19960
|
-
longFieldLength: DD04V?.SCRLEN3
|
|
19961
|
-
longFieldMaxLength: DD04V?.SCRLEN3
|
|
19978
|
+
longFieldLength: numOr0(DD04V?.SCRLEN3),
|
|
19979
|
+
longFieldMaxLength: numOr0(DD04V?.SCRLEN3),
|
|
19962
19980
|
headingFieldLabel: DD04V?.REPTEXT || "",
|
|
19963
|
-
headingFieldLength: DD04V?.HEADLEN
|
|
19964
|
-
headingFieldMaxLength: DD04V?.HEADLEN
|
|
19981
|
+
headingFieldLength: numOr0(DD04V?.HEADLEN),
|
|
19982
|
+
headingFieldMaxLength: numOr0(DD04V?.HEADLEN),
|
|
19965
19983
|
searchHelp: "",
|
|
19966
19984
|
searchHelpParameter: "",
|
|
19967
19985
|
setGetParameter: "",
|
|
@@ -20200,109 +20218,98 @@ function computeIntlen(builtin, length) {
|
|
|
20200
20218
|
if (builtin.length !== void 0) return builtin.length * 2;
|
|
20201
20219
|
return 0;
|
|
20202
20220
|
}
|
|
20203
|
-
/**
|
|
20204
|
-
|
|
20205
|
-
const
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
|
|
20217
|
-
|
|
20218
|
-
|
|
20219
|
-
|
|
20220
|
-
|
|
20221
|
-
|
|
20222
|
-
const length = bt.length ?? typeInfo.length;
|
|
20223
|
-
inttype = typeInfo.inttype;
|
|
20224
|
-
intlen = zeroPad(computeIntlen(typeInfo, length), 6);
|
|
20225
|
-
datatype = typeInfo.datatype;
|
|
20226
|
-
if (!typeInfo.noLeng && length !== void 0) leng = zeroPad(length, 6);
|
|
20227
|
-
const dec = bt.decimals ?? typeInfo.decimals;
|
|
20228
|
-
if (dec !== void 0) decimals = zeroPad(dec, 6);
|
|
20229
|
-
mask = ` ${typeInfo.datatype}`;
|
|
20230
|
-
if (typeInfo.shlporigin) shlporigin = typeInfo.shlporigin;
|
|
20231
|
-
if (bt.name === "curr" || bt.name === "quan") {
|
|
20232
|
-
const refAnnotation = getAnnotation(field.annotations, bt.name === "curr" ? "Semantics.amount.currencyCode" : "Semantics.quantity.unitOfMeasure");
|
|
20233
|
-
if (refAnnotation) {
|
|
20234
|
-
reftable = tableName;
|
|
20235
|
-
const parts = refAnnotation.split(".");
|
|
20236
|
-
reffield = parts[parts.length - 1].toUpperCase();
|
|
20237
|
-
}
|
|
20238
|
-
}
|
|
20221
|
+
/** Type columns derived from a builtin CDS type reference. */
|
|
20222
|
+
function builtinFieldColumns(bt, field, tableName) {
|
|
20223
|
+
const typeInfo = BUILTIN_TYPES[bt.name];
|
|
20224
|
+
if (!typeInfo) return {};
|
|
20225
|
+
const out = {};
|
|
20226
|
+
const length = bt.length ?? typeInfo.length;
|
|
20227
|
+
out.inttype = typeInfo.inttype;
|
|
20228
|
+
out.intlen = zeroPad(computeIntlen(typeInfo, length), 6);
|
|
20229
|
+
out.datatype = typeInfo.datatype;
|
|
20230
|
+
if (!typeInfo.noLeng && length !== void 0) out.leng = zeroPad(length, 6);
|
|
20231
|
+
const dec = bt.decimals ?? typeInfo.decimals;
|
|
20232
|
+
if (dec !== void 0) out.decimals = zeroPad(dec, 6);
|
|
20233
|
+
out.mask = ` ${typeInfo.datatype}`;
|
|
20234
|
+
if (typeInfo.shlporigin) out.shlporigin = typeInfo.shlporigin;
|
|
20235
|
+
if (bt.name === "curr" || bt.name === "quan") {
|
|
20236
|
+
const refAnnotation = getAnnotation(field.annotations, bt.name === "curr" ? "Semantics.amount.currencyCode" : "Semantics.quantity.unitOfMeasure");
|
|
20237
|
+
if (refAnnotation) {
|
|
20238
|
+
out.reftable = tableName;
|
|
20239
|
+
out.reffield = refAnnotation.split(".").at(-1).toUpperCase();
|
|
20239
20240
|
}
|
|
20240
|
-
}
|
|
20241
|
-
|
|
20242
|
-
|
|
20243
|
-
|
|
20244
|
-
|
|
20245
|
-
|
|
20246
|
-
|
|
20247
|
-
|
|
20248
|
-
|
|
20249
|
-
|
|
20250
|
-
|
|
20241
|
+
}
|
|
20242
|
+
return out;
|
|
20243
|
+
}
|
|
20244
|
+
/** Type columns derived from a named type reference (resolved via ADT). */
|
|
20245
|
+
async function namedFieldColumns(field, resolver) {
|
|
20246
|
+
const out = {
|
|
20247
|
+
rollname: field.type.name.toUpperCase(),
|
|
20248
|
+
comptype: "E"
|
|
20249
|
+
};
|
|
20250
|
+
if (resolver) {
|
|
20251
|
+
const resolved = await resolver.resolve(field.type.name);
|
|
20252
|
+
out.comptype = resolved.comptype;
|
|
20253
|
+
if (resolved.shlporigin) out.shlporigin = resolved.shlporigin;
|
|
20254
|
+
if (resolved.comptype === "S") {
|
|
20255
|
+
out.datatype = "STRU";
|
|
20256
|
+
out.mask = " STRUS";
|
|
20251
20257
|
}
|
|
20252
20258
|
}
|
|
20259
|
+
return out;
|
|
20260
|
+
}
|
|
20261
|
+
/**
|
|
20262
|
+
* Assemble the DD03P entry in standard abapGit DD03P field order.
|
|
20263
|
+
*
|
|
20264
|
+
* NOTE: POSITION is a real DD03P database value. abapGit emits it
|
|
20265
|
+
* inconsistently (only for some transparent tables). We omit it to
|
|
20266
|
+
* avoid roundtrip mismatches — SAP auto-computes it on import.
|
|
20267
|
+
*/
|
|
20268
|
+
function assembleDD03P(field, col) {
|
|
20253
20269
|
const result = {};
|
|
20254
20270
|
result.FIELDNAME = field.name.toUpperCase();
|
|
20255
|
-
if (isKey) result.KEYFLAG = "X";
|
|
20256
|
-
if (rollname) result.ROLLNAME = rollname;
|
|
20271
|
+
if (field.isKey) result.KEYFLAG = "X";
|
|
20272
|
+
if (col.rollname) result.ROLLNAME = col.rollname;
|
|
20257
20273
|
result.ADMINFIELD = "0";
|
|
20258
|
-
if (inttype) result.INTTYPE = inttype;
|
|
20259
|
-
if (intlen) result.INTLEN = intlen;
|
|
20260
|
-
if (notNull) result.NOTNULL = "X";
|
|
20261
|
-
if (datatype) result.DATATYPE = datatype;
|
|
20262
|
-
if (leng) result.LENG = leng;
|
|
20263
|
-
if (decimals) result.DECIMALS = decimals;
|
|
20264
|
-
if (shlporigin) result.SHLPORIGIN = shlporigin;
|
|
20265
|
-
if (reftable) result.REFTABLE = reftable;
|
|
20266
|
-
if (reffield) result.REFFIELD = reffield;
|
|
20267
|
-
if (mask) result.MASK = mask;
|
|
20268
|
-
if (comptype) result.COMPTYPE = comptype;
|
|
20274
|
+
if (col.inttype) result.INTTYPE = col.inttype;
|
|
20275
|
+
if (col.intlen) result.INTLEN = col.intlen;
|
|
20276
|
+
if (field.notNull) result.NOTNULL = "X";
|
|
20277
|
+
if (col.datatype) result.DATATYPE = col.datatype;
|
|
20278
|
+
if (col.leng) result.LENG = col.leng;
|
|
20279
|
+
if (col.decimals) result.DECIMALS = col.decimals;
|
|
20280
|
+
if (col.shlporigin) result.SHLPORIGIN = col.shlporigin;
|
|
20281
|
+
if (col.reftable) result.REFTABLE = col.reftable;
|
|
20282
|
+
if (col.reffield) result.REFFIELD = col.reffield;
|
|
20283
|
+
if (col.mask) result.MASK = col.mask;
|
|
20284
|
+
if (col.comptype) result.COMPTYPE = col.comptype;
|
|
20269
20285
|
return result;
|
|
20270
20286
|
}
|
|
20287
|
+
/** Build a DD03P entry from a single field definition */
|
|
20288
|
+
async function buildFieldDD03P(field, tableName, resolver) {
|
|
20289
|
+
return assembleDD03P(field, field.type.kind === "builtin" ? builtinFieldColumns(field.type, field, tableName) : await namedFieldColumns(field, resolver));
|
|
20290
|
+
}
|
|
20291
|
+
/** Build the DD03P entry for an INCLUDE directive (with or without suffix). */
|
|
20292
|
+
async function buildIncludeDD03P(inc, resolver) {
|
|
20293
|
+
const includeName = inc.name.toUpperCase();
|
|
20294
|
+
let ddtext;
|
|
20295
|
+
if (resolver) ddtext = (await resolver.resolve(inc.name)).description;
|
|
20296
|
+
const entry = {
|
|
20297
|
+
FIELDNAME: inc.suffix ? `.INCLU-${inc.suffix.toUpperCase()}` : ".INCLUDE",
|
|
20298
|
+
ADMINFIELD: "0",
|
|
20299
|
+
PRECFIELD: includeName,
|
|
20300
|
+
MASK: " S",
|
|
20301
|
+
COMPTYPE: "S"
|
|
20302
|
+
};
|
|
20303
|
+
if (ddtext) entry.DDTEXT = ddtext;
|
|
20304
|
+
return entry;
|
|
20305
|
+
}
|
|
20271
20306
|
/**
|
|
20272
20307
|
* Build DD03P entries from table/structure members
|
|
20273
20308
|
*/
|
|
20274
20309
|
async function buildDD03P(members, tableName = "", resolver) {
|
|
20275
20310
|
const entries = [];
|
|
20276
|
-
for (const member of members) if ("kind" in member && member.kind === "include")
|
|
20277
|
-
|
|
20278
|
-
const includeName = inc.name.toUpperCase();
|
|
20279
|
-
let ddtext;
|
|
20280
|
-
if (resolver) ddtext = (await resolver.resolve(inc.name)).description;
|
|
20281
|
-
if (inc.suffix) {
|
|
20282
|
-
const entry = {
|
|
20283
|
-
FIELDNAME: `.INCLU-${inc.suffix.toUpperCase()}`,
|
|
20284
|
-
ADMINFIELD: "0",
|
|
20285
|
-
PRECFIELD: includeName,
|
|
20286
|
-
MASK: " S",
|
|
20287
|
-
COMPTYPE: "S"
|
|
20288
|
-
};
|
|
20289
|
-
if (ddtext) entry.DDTEXT = ddtext;
|
|
20290
|
-
entries.push(entry);
|
|
20291
|
-
} else {
|
|
20292
|
-
const entry = {
|
|
20293
|
-
FIELDNAME: ".INCLUDE",
|
|
20294
|
-
ADMINFIELD: "0",
|
|
20295
|
-
PRECFIELD: includeName,
|
|
20296
|
-
MASK: " S",
|
|
20297
|
-
COMPTYPE: "S"
|
|
20298
|
-
};
|
|
20299
|
-
if (ddtext) entry.DDTEXT = ddtext;
|
|
20300
|
-
entries.push(entry);
|
|
20301
|
-
}
|
|
20302
|
-
} else {
|
|
20303
|
-
const field = member;
|
|
20304
|
-
entries.push(await buildFieldDD03P(field, tableName, resolver));
|
|
20305
|
-
}
|
|
20311
|
+
for (const member of members) if ("kind" in member && member.kind === "include") entries.push(await buildIncludeDD03P(member, resolver));
|
|
20312
|
+
else entries.push(await buildFieldDD03P(member, tableName, resolver));
|
|
20306
20313
|
return entries;
|
|
20307
20314
|
}
|
|
20308
20315
|
|
|
@@ -20323,8 +20330,8 @@ const XML_NAMED_ENTITIES = {
|
|
|
20323
20330
|
};
|
|
20324
20331
|
function decodeNumericCode(decimal, hex) {
|
|
20325
20332
|
const base = decimal !== void 0 ? 10 : 16;
|
|
20326
|
-
const value = decimal
|
|
20327
|
-
return String.
|
|
20333
|
+
const value = decimal ?? hex ?? "";
|
|
20334
|
+
return String.fromCodePoint(Number.parseInt(value, base));
|
|
20328
20335
|
}
|
|
20329
20336
|
function decodeXmlEntities(text) {
|
|
20330
20337
|
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);
|
|
@@ -20367,7 +20374,7 @@ function parseSettingsToDD09L(settingsXml, def) {
|
|
|
20367
20374
|
function resolveReferencedType(xml, comptype) {
|
|
20368
20375
|
const result = { comptype };
|
|
20369
20376
|
if (comptype === "E" && /<dtel:searchHelp>[^<]+<\/dtel:searchHelp>/.test(xml)) result.shlporigin = "D";
|
|
20370
|
-
const descMatch =
|
|
20377
|
+
const descMatch = /adtcore:description="([^"]+)"/.exec(xml);
|
|
20371
20378
|
if (descMatch) result.description = decodeXmlEntities(descMatch[1]);
|
|
20372
20379
|
return result;
|
|
20373
20380
|
}
|
|
@@ -20891,7 +20898,7 @@ const serviceBindingHandler = createHandler("SRVB", {
|
|
|
20891
20898
|
services: binding?.services
|
|
20892
20899
|
};
|
|
20893
20900
|
},
|
|
20894
|
-
|
|
20901
|
+
serialize(object, ctx, options) {
|
|
20895
20902
|
const objectName = ctx.getObjectName(object);
|
|
20896
20903
|
if (options?.format === "aff") {
|
|
20897
20904
|
const bindingType = String(object?.bindingType ?? object?.data?.bindingType ?? "odataV4");
|
|
@@ -20902,10 +20909,10 @@ const serviceBindingHandler = createHandler("SRVB", {
|
|
|
20902
20909
|
bindingTypeCategory,
|
|
20903
20910
|
...Array.isArray(services) && services.length > 0 ? { services } : {}
|
|
20904
20911
|
} });
|
|
20905
|
-
return [ctx.createFile(`${objectName}.${ctx.fileExtension}.json`, jsonContent)];
|
|
20912
|
+
return Promise.resolve([ctx.createFile(`${objectName}.${ctx.fileExtension}.json`, jsonContent)]);
|
|
20906
20913
|
}
|
|
20907
20914
|
const xmlContent = ctx.toAbapGitXml(object);
|
|
20908
|
-
return [ctx.createFile(`${objectName}.${ctx.fileExtension}.xml`, xmlContent)];
|
|
20915
|
+
return Promise.resolve([ctx.createFile(`${objectName}.${ctx.fileExtension}.xml`, xmlContent)]);
|
|
20909
20916
|
}
|
|
20910
20917
|
});
|
|
20911
20918
|
|
|
@@ -21713,15 +21720,15 @@ const externalSchemaHandler = createHandler("DESD", {
|
|
|
21713
21720
|
} };
|
|
21714
21721
|
},
|
|
21715
21722
|
fromAffJson: (json) => affFromAffJson(json, ""),
|
|
21716
|
-
|
|
21723
|
+
serialize(object, ctx) {
|
|
21717
21724
|
const header = {
|
|
21718
21725
|
description: object.description || String(object.name ?? ""),
|
|
21719
21726
|
originalLanguage: (object.originalLanguage ?? "en").toLowerCase()
|
|
21720
21727
|
};
|
|
21721
|
-
return [ctx.createFile(`${ctx.getObjectName(object)}.desd.json`, `${JSON.stringify({
|
|
21728
|
+
return Promise.resolve([ctx.createFile(`${ctx.getObjectName(object)}.desd.json`, `${JSON.stringify({
|
|
21722
21729
|
formatVersion: "1",
|
|
21723
21730
|
header
|
|
21724
|
-
}, null, 2)}\n`)];
|
|
21731
|
+
}, null, 2)}\n`)]);
|
|
21725
21732
|
}
|
|
21726
21733
|
});
|
|
21727
21734
|
|
|
@@ -21751,15 +21758,15 @@ function createAffFirstHandler(type, ext) {
|
|
|
21751
21758
|
NAME: String(obj?.name ?? "").toUpperCase()
|
|
21752
21759
|
} }),
|
|
21753
21760
|
fromAffJson: (json) => affFromAffJson(json, ""),
|
|
21754
|
-
|
|
21761
|
+
serialize(object, ctx) {
|
|
21755
21762
|
const header = {
|
|
21756
21763
|
description: object.description || String(object.name ?? ""),
|
|
21757
21764
|
originalLanguage: (object.originalLanguage ?? "en").toLowerCase()
|
|
21758
21765
|
};
|
|
21759
|
-
return [ctx.createFile(`${ctx.getObjectName(object)}.${ext}.json`, `${JSON.stringify({
|
|
21766
|
+
return Promise.resolve([ctx.createFile(`${ctx.getObjectName(object)}.${ext}.json`, `${JSON.stringify({
|
|
21760
21767
|
formatVersion: "1",
|
|
21761
21768
|
header
|
|
21762
|
-
}, null, 2)}\n`)];
|
|
21769
|
+
}, null, 2)}\n`)]);
|
|
21763
21770
|
}
|
|
21764
21771
|
});
|
|
21765
21772
|
}
|
|
@@ -21837,12 +21844,19 @@ const httpServiceHandler = createHandler("HTTP", {
|
|
|
21837
21844
|
toAbapGit: (raw) => {
|
|
21838
21845
|
const obj = unwrapData(raw);
|
|
21839
21846
|
const name = String(obj.name ?? "").toUpperCase();
|
|
21847
|
+
const lang = isoToSapLang(obj.masterLanguage || obj.language);
|
|
21848
|
+
const handlerClassFallback = obj.handlerClass ? { UCONSERVHANDLER: {
|
|
21849
|
+
ID: name,
|
|
21850
|
+
VERSION: "A",
|
|
21851
|
+
SERVICEORDER: obj.serviceOrder ?? "01",
|
|
21852
|
+
SERVICEHANDLER: obj.handlerClass
|
|
21853
|
+
} } : void 0;
|
|
21840
21854
|
return {
|
|
21841
21855
|
HTTPID: name,
|
|
21842
21856
|
HTTPTEXT: {
|
|
21843
21857
|
ID: name,
|
|
21844
21858
|
VERSION: "A",
|
|
21845
|
-
LANG:
|
|
21859
|
+
LANG: lang,
|
|
21846
21860
|
SHORTTEXT: obj.description ?? ""
|
|
21847
21861
|
},
|
|
21848
21862
|
HTTPHDL: obj.handlers?.length ? { UCONSERVHANDLER: obj.handlers.map((h, i) => ({
|
|
@@ -21850,12 +21864,7 @@ const httpServiceHandler = createHandler("HTTP", {
|
|
|
21850
21864
|
VERSION: "A",
|
|
21851
21865
|
SERVICEORDER: h.serviceOrder ?? String(i + 1).padStart(2, "0"),
|
|
21852
21866
|
SERVICEHANDLER: h.handler
|
|
21853
|
-
})) } :
|
|
21854
|
-
ID: name,
|
|
21855
|
-
VERSION: "A",
|
|
21856
|
-
SERVICEORDER: obj.serviceOrder ?? "01",
|
|
21857
|
-
SERVICEHANDLER: obj.handlerClass
|
|
21858
|
-
} } : void 0
|
|
21867
|
+
})) } : handlerClassFallback
|
|
21859
21868
|
};
|
|
21860
21869
|
},
|
|
21861
21870
|
fromAbapGit: ({ HTTPID, HTTPTEXT, HTTPHDL }) => {
|
|
@@ -21903,9 +21912,7 @@ const numberRangeObjectHandler = createHandler("NROB", {
|
|
|
21903
21912
|
CODE: obj.code,
|
|
21904
21913
|
GAP: obj.gap,
|
|
21905
21914
|
ROLLNR: obj.rollNr,
|
|
21906
|
-
YEARLY: obj.yearly
|
|
21907
|
-
NRLVL: obj.nrLvl,
|
|
21908
|
-
PROCIND: obj.procInd
|
|
21915
|
+
YEARLY: obj.yearly
|
|
21909
21916
|
},
|
|
21910
21917
|
TEXT: {
|
|
21911
21918
|
LANGU: isoToSapLang(obj.masterLanguage || obj.language),
|
|
@@ -21929,9 +21936,7 @@ const numberRangeObjectHandler = createHandler("NROB", {
|
|
|
21929
21936
|
code: ATTRIBUTES?.CODE,
|
|
21930
21937
|
gap: ATTRIBUTES?.GAP,
|
|
21931
21938
|
rollNr: ATTRIBUTES?.ROLLNR,
|
|
21932
|
-
yearly: ATTRIBUTES?.YEARLY
|
|
21933
|
-
nrLvl: ATTRIBUTES?.NRLVL,
|
|
21934
|
-
procInd: ATTRIBUTES?.PROCIND
|
|
21939
|
+
yearly: ATTRIBUTES?.YEARLY
|
|
21935
21940
|
})
|
|
21936
21941
|
});
|
|
21937
21942
|
|
|
@@ -21949,6 +21954,11 @@ const changeDocumentObjectHandler = createHandler("CHDO", {
|
|
|
21949
21954
|
serializer_version: "v1.0.0",
|
|
21950
21955
|
toAbapGit: (obj) => {
|
|
21951
21956
|
const name = String(obj.name ?? "").toUpperCase();
|
|
21957
|
+
const objectTextFallback = obj.description ? { TCDOBTS: [{
|
|
21958
|
+
SPRAS: isoToSapLang(obj.masterLanguage || obj.language),
|
|
21959
|
+
OBJECT: name,
|
|
21960
|
+
OBTEXT: obj.description
|
|
21961
|
+
}] } : void 0;
|
|
21952
21962
|
return { CHDO: {
|
|
21953
21963
|
REPORTS_GENERATED: obj.generatedReports?.length ? { TCDRPS: obj.generatedReports.map((r) => ({
|
|
21954
21964
|
OBJECT: r.object ?? name,
|
|
@@ -21967,11 +21977,7 @@ const changeDocumentObjectHandler = createHandler("CHDO", {
|
|
|
21967
21977
|
SPRAS: isoToSapLang(t.language || obj.masterLanguage || obj.language),
|
|
21968
21978
|
OBJECT: t.object ?? name,
|
|
21969
21979
|
OBTEXT: t.text
|
|
21970
|
-
})) } :
|
|
21971
|
-
SPRAS: isoToSapLang(obj.masterLanguage || obj.language),
|
|
21972
|
-
OBJECT: name,
|
|
21973
|
-
OBTEXT: obj.description
|
|
21974
|
-
}] } : void 0
|
|
21980
|
+
})) } : objectTextFallback
|
|
21975
21981
|
} };
|
|
21976
21982
|
},
|
|
21977
21983
|
fromAbapGit: ({ CHDO }) => {
|
|
@@ -22208,7 +22214,8 @@ const icfServiceHandler = createHandler("SICF", {
|
|
|
22208
22214
|
const obj = unwrapData(raw);
|
|
22209
22215
|
const name = String(obj.name ?? "").toUpperCase();
|
|
22210
22216
|
const lang = isoToSapLang(obj.language);
|
|
22211
|
-
const
|
|
22217
|
+
const fallbackHandlers = obj.handlerClass ? [{ handler: obj.handlerClass }] : [];
|
|
22218
|
+
const handlers = obj.handlers?.length ? obj.handlers : fallbackHandlers;
|
|
22212
22219
|
return {
|
|
22213
22220
|
URL: obj.url ?? "",
|
|
22214
22221
|
ICFSERVICE: {
|
|
@@ -22811,11 +22818,11 @@ const mimeObjectHandler = createHandler("SMIM", {
|
|
|
22811
22818
|
PARENT_FOLDER_ID: obj.parentFolderId
|
|
22812
22819
|
}
|
|
22813
22820
|
}),
|
|
22814
|
-
serialize:
|
|
22821
|
+
serialize: (obj, ctx) => {
|
|
22815
22822
|
const objectName = ctx.getObjectName(obj);
|
|
22816
22823
|
const files = [ctx.createFile(`${objectName}.smim.xml`, formatAbapGitXml(ctx.toAbapGitXml(obj)))];
|
|
22817
22824
|
if (obj.content && obj.fileName) files.push(ctx.createFile(`${objectName}.smim.${obj.fileName.toLowerCase()}`, obj.content, "base64"));
|
|
22818
|
-
return files;
|
|
22825
|
+
return Promise.resolve(files);
|
|
22819
22826
|
},
|
|
22820
22827
|
setSources: (obj, sources) => {
|
|
22821
22828
|
const data = unwrapData(obj);
|
|
@@ -23146,7 +23153,7 @@ const formHandler = createHandler("FORM", {
|
|
|
23146
23153
|
})) } : void 0
|
|
23147
23154
|
}] } };
|
|
23148
23155
|
},
|
|
23149
|
-
serialize:
|
|
23156
|
+
serialize: (obj, ctx) => {
|
|
23150
23157
|
const objectName = ctx.getObjectName(obj);
|
|
23151
23158
|
const files = [ctx.createFile(`${objectName}.form.xml`, formatAbapGitXml(ctx.toAbapGitXml(obj)))];
|
|
23152
23159
|
for (const [lang, lines] of Object.entries(obj.tdlines ?? {})) {
|
|
@@ -23165,13 +23172,13 @@ const formHandler = createHandler("FORM", {
|
|
|
23165
23172
|
}, { pretty: true });
|
|
23166
23173
|
files.push(ctx.createFile(`${objectName}.form.tdlines_${isoToSapLang(lang).toLowerCase()}.xml`, formatAbapGitXml(xml)));
|
|
23167
23174
|
}
|
|
23168
|
-
return files;
|
|
23175
|
+
return Promise.resolve(files);
|
|
23169
23176
|
},
|
|
23170
23177
|
setSources: (obj, sources) => {
|
|
23171
23178
|
const data = unwrapData(obj);
|
|
23172
23179
|
const tdlinesData = data.tdlines ?? {};
|
|
23173
23180
|
for (const [key, content] of Object.entries(sources)) {
|
|
23174
|
-
const match =
|
|
23181
|
+
const match = /^tdlines_([a-zA-Z0-9]+)$/.exec(key);
|
|
23175
23182
|
if (!match) continue;
|
|
23176
23183
|
const parsed = tdlines.parse(content);
|
|
23177
23184
|
const items = normalizeItems(parsed.abapGit?.abap?.values?.TDLINES?.item);
|
|
@@ -24954,7 +24961,7 @@ const compositeTemplateHandler = createHandler("CMPT", {
|
|
|
24954
24961
|
NAME: String(obj.name ?? "").toUpperCase(),
|
|
24955
24962
|
DESCRIPTION: obj.description
|
|
24956
24963
|
},
|
|
24957
|
-
...obj.extra
|
|
24964
|
+
...obj.extra
|
|
24958
24965
|
} };
|
|
24959
24966
|
},
|
|
24960
24967
|
fromAbapGit: ({ CMPT }) => {
|
|
@@ -25304,12 +25311,12 @@ const iatuHandler = createHandler("IATU", {
|
|
|
25304
25311
|
DEVCLASS: obj.packageName
|
|
25305
25312
|
} };
|
|
25306
25313
|
},
|
|
25307
|
-
serialize:
|
|
25314
|
+
serialize: (raw, ctx) => {
|
|
25308
25315
|
const obj = unwrapData(raw);
|
|
25309
25316
|
const objectName = ctx.getObjectName(obj);
|
|
25310
25317
|
const files = [ctx.createFile(`${objectName}.iatu.xml`, formatAbapGitXml(ctx.toAbapGitXml(obj)))];
|
|
25311
25318
|
if (obj.html) files.push(ctx.createFile(`${objectName}.iatu.html`, obj.html));
|
|
25312
|
-
return files;
|
|
25319
|
+
return Promise.resolve(files);
|
|
25313
25320
|
},
|
|
25314
25321
|
setSources: (obj, sources) => {
|
|
25315
25322
|
const data = unwrapData(obj);
|
|
@@ -25390,7 +25397,7 @@ function createGenericObjslHandler(type, schema) {
|
|
|
25390
25397
|
serializer: `LCL_OBJECT_${type}`,
|
|
25391
25398
|
serializer_version: "v1.0.0",
|
|
25392
25399
|
toAbapGit: (raw) => {
|
|
25393
|
-
return { ...unwrapData(raw).tables
|
|
25400
|
+
return { ...unwrapData(raw).tables };
|
|
25394
25401
|
},
|
|
25395
25402
|
fromAbapGit: (values) => ({
|
|
25396
25403
|
name: "",
|
|
@@ -25426,20 +25433,20 @@ function createRawXmlHandler(type, schema) {
|
|
|
25426
25433
|
serializer: `LCL_OBJECT_${type}`,
|
|
25427
25434
|
serializer_version: "v1.0.0",
|
|
25428
25435
|
toAbapGit: (raw) => {
|
|
25429
|
-
return { ...unwrapData(raw).raw
|
|
25436
|
+
return { ...unwrapData(raw).raw };
|
|
25430
25437
|
},
|
|
25431
25438
|
fromAbapGit: (values) => ({
|
|
25432
25439
|
name: "",
|
|
25433
25440
|
raw: { ...values }
|
|
25434
25441
|
}),
|
|
25435
|
-
serialize:
|
|
25442
|
+
serialize: (obj, ctx) => {
|
|
25436
25443
|
const xml = schema.build({
|
|
25437
|
-
...obj.raw
|
|
25444
|
+
...obj.raw,
|
|
25438
25445
|
version: "v1.0.0",
|
|
25439
25446
|
serializer: `LCL_OBJECT_${type}`,
|
|
25440
25447
|
serializer_version: "v1.0.0"
|
|
25441
25448
|
});
|
|
25442
|
-
return [ctx.createFile(`${ctx.getObjectName(obj)}.${ctx.fileExtension}.xml`, formatAbapGitXml(xml))];
|
|
25449
|
+
return Promise.resolve([ctx.createFile(`${ctx.getObjectName(obj)}.${ctx.fileExtension}.xml`, formatAbapGitXml(xml))]);
|
|
25443
25450
|
}
|
|
25444
25451
|
});
|
|
25445
25452
|
}
|
|
@@ -25620,7 +25627,7 @@ function generateAbapGitXml(folderLogic) {
|
|
|
25620
25627
|
* plus source file extensions (.abap, .abdl, .acds, .asrvd).
|
|
25621
25628
|
*/
|
|
25622
25629
|
function parseAbapGitFilename(filename) {
|
|
25623
|
-
const match =
|
|
25630
|
+
const match = /^([^.]+)\.([^.]+)(?:\.([^.]+))?\.(xml|json|abap|abdl|acds|asrvd)$/.exec(filename);
|
|
25624
25631
|
if (!match) return null;
|
|
25625
25632
|
const [, name, type, suffixOrExt, extension] = match;
|
|
25626
25633
|
return {
|
|
@@ -25729,7 +25736,7 @@ function collectXmlCompanions(xmlFiles, objectMap) {
|
|
|
25729
25736
|
function collectBinaryCompanions(allFiles, objectMap) {
|
|
25730
25737
|
for (const sourcePath of allFiles) {
|
|
25731
25738
|
const filename = sourcePath.slice(sourcePath.lastIndexOf("/") + 1);
|
|
25732
|
-
const match =
|
|
25739
|
+
const match = /^([^.]+)\.([^.]+)\..+$/.exec(filename);
|
|
25733
25740
|
if (!match) continue;
|
|
25734
25741
|
const key = `${match[1].toUpperCase()}:${match[2].toUpperCase()}`;
|
|
25735
25742
|
const obj = objectMap.get(key);
|
|
@@ -25817,6 +25824,58 @@ function setAbapLanguageVersion(adkObject, options) {
|
|
|
25817
25824
|
if (data && !data.abapLanguageVersion) data.abapLanguageVersion = abapLangVerToAdt(options.abapLanguageVersion) ?? options.abapLanguageVersion;
|
|
25818
25825
|
}
|
|
25819
25826
|
/**
|
|
25827
|
+
* Read all source files of an object into a source-key → content map.
|
|
25828
|
+
* Binary companions travel base64-encoded.
|
|
25829
|
+
*/
|
|
25830
|
+
async function loadObjectSources(fileTree, objFiles, handler) {
|
|
25831
|
+
const contents = await Promise.all(objFiles.sourceFiles.map(({ path, binary }) => binary ? fileTree.readBuffer(path).then((buffer) => buffer.toString("base64")) : fileTree.read(path)));
|
|
25832
|
+
const sources = {};
|
|
25833
|
+
for (const [index, { suffix }] of objFiles.sourceFiles.entries()) {
|
|
25834
|
+
const sourceKey = suffix ? handler.suffixToSourceKey?.[suffix] ?? suffix : "main";
|
|
25835
|
+
sources[sourceKey] = contents[index];
|
|
25836
|
+
}
|
|
25837
|
+
return sources;
|
|
25838
|
+
}
|
|
25839
|
+
/**
|
|
25840
|
+
* Compute the relative directory for package resolution and attach the
|
|
25841
|
+
* folder-logic hints to the ADK object.
|
|
25842
|
+
*/
|
|
25843
|
+
function applyFolderInfo(adkObject, objFiles, folderConfig) {
|
|
25844
|
+
if (!folderConfig.hasAbapGitXml) return;
|
|
25845
|
+
const sourceDir = (objFiles.xmlFile ?? objFiles.jsonFile ?? "").split("/").slice(0, -1).join("/");
|
|
25846
|
+
adkObject._relDir = sourceDir.startsWith(folderConfig.startDir) ? sourceDir.slice(folderConfig.startDir.length).replace(/^\/+/, "") : sourceDir;
|
|
25847
|
+
adkObject._folderLogic = folderConfig.folderLogic;
|
|
25848
|
+
}
|
|
25849
|
+
/**
|
|
25850
|
+
* Build one object (plus its FUGR children) from a metadata/source file
|
|
25851
|
+
* group. A failure inside one object is logged and swallowed, mirroring
|
|
25852
|
+
* the abapGit log-and-continue rule.
|
|
25853
|
+
*/
|
|
25854
|
+
async function* buildObject(fileTree, adk, objFiles, handler, options, folderConfig) {
|
|
25855
|
+
try {
|
|
25856
|
+
const meta = await parseMetadata(fileTree, objFiles, handler);
|
|
25857
|
+
if (!meta) return;
|
|
25858
|
+
const { values, isAffJson } = meta;
|
|
25859
|
+
const sources = await loadObjectSources(fileTree, objFiles, handler);
|
|
25860
|
+
const payload = buildPayload(handler, values, isAffJson, objFiles);
|
|
25861
|
+
const objectName = payload.name || objFiles.name;
|
|
25862
|
+
const adkType = typeof payload.type === "string" ? payload.type : objFiles.type;
|
|
25863
|
+
const adkObject = adk.getWithData({
|
|
25864
|
+
...payload,
|
|
25865
|
+
name: objectName
|
|
25866
|
+
}, adkType);
|
|
25867
|
+
setObjectSources(handler, adkObject, sources);
|
|
25868
|
+
if (payload.description) adkObject._pendingDescription = payload.description;
|
|
25869
|
+
applyFolderInfo(adkObject, objFiles, folderConfig);
|
|
25870
|
+
resolvePackageRef(adkObject, options, folderConfig.hasAbapGitXml, folderConfig.folderLogic);
|
|
25871
|
+
setAbapLanguageVersion(adkObject, options);
|
|
25872
|
+
yield adkObject;
|
|
25873
|
+
if (objFiles.type === "FUGR" && payload._functions) yield* yieldFugrChildren(adk, payload, objectName, options, adkObject);
|
|
25874
|
+
} catch (error) {
|
|
25875
|
+
console.error(`Failed to deserialize ${objFiles.type} ${objFiles.name}:`, error);
|
|
25876
|
+
}
|
|
25877
|
+
}
|
|
25878
|
+
/**
|
|
25820
25879
|
* Deserialize abapGit files to ADK objects
|
|
25821
25880
|
*
|
|
25822
25881
|
* True generator - yields objects one at a time as they're discovered.
|
|
@@ -25843,37 +25902,11 @@ async function* deserialize(fileTree, client, options) {
|
|
|
25843
25902
|
if (!objFiles.xmlFile && !objFiles.jsonFile) continue;
|
|
25844
25903
|
const handler = getHandler(objFiles.type);
|
|
25845
25904
|
if (!handler) continue;
|
|
25846
|
-
|
|
25847
|
-
|
|
25848
|
-
|
|
25849
|
-
|
|
25850
|
-
|
|
25851
|
-
for (const { path, suffix, binary } of objFiles.sourceFiles) {
|
|
25852
|
-
const content = binary ? (await fileTree.readBuffer(path)).toString("base64") : await fileTree.read(path);
|
|
25853
|
-
const sourceKey = suffix ? handler.suffixToSourceKey?.[suffix] ?? suffix : "main";
|
|
25854
|
-
sources[sourceKey] = content;
|
|
25855
|
-
}
|
|
25856
|
-
const payload = buildPayload(handler, values, isAffJson, objFiles);
|
|
25857
|
-
const objectName = payload.name || objFiles.name;
|
|
25858
|
-
const adkType = typeof payload.type === "string" ? payload.type : objFiles.type;
|
|
25859
|
-
const adkObject = adk.getWithData({
|
|
25860
|
-
...payload,
|
|
25861
|
-
name: objectName
|
|
25862
|
-
}, adkType);
|
|
25863
|
-
setObjectSources(handler, adkObject, sources);
|
|
25864
|
-
if (payload.description) adkObject._pendingDescription = payload.description;
|
|
25865
|
-
if (hasAbapGitXml) {
|
|
25866
|
-
const sourceDir = (objFiles.xmlFile ?? objFiles.jsonFile ?? "").split("/").slice(0, -1).join("/");
|
|
25867
|
-
adkObject._relDir = sourceDir.startsWith(startDir) ? sourceDir.slice(startDir.length).replace(/^\/+/, "") : sourceDir;
|
|
25868
|
-
adkObject._folderLogic = folderLogic;
|
|
25869
|
-
}
|
|
25870
|
-
resolvePackageRef(adkObject, options, hasAbapGitXml, folderLogic);
|
|
25871
|
-
setAbapLanguageVersion(adkObject, options);
|
|
25872
|
-
yield adkObject;
|
|
25873
|
-
if (objFiles.type === "FUGR" && payload._functions) yield* yieldFugrChildren(adk, payload, objectName, options, adkObject);
|
|
25874
|
-
} catch (error) {
|
|
25875
|
-
console.error(`Failed to deserialize ${objFiles.type} ${objFiles.name}:`, error);
|
|
25876
|
-
}
|
|
25905
|
+
yield* buildObject(fileTree, adk, objFiles, handler, options, {
|
|
25906
|
+
hasAbapGitXml,
|
|
25907
|
+
startDir,
|
|
25908
|
+
folderLogic
|
|
25909
|
+
});
|
|
25877
25910
|
}
|
|
25878
25911
|
}
|
|
25879
25912
|
/**
|
|
@@ -25950,7 +25983,10 @@ async function buildMaterializedFiles(handler, object, packageDir, sources, form
|
|
|
25950
25983
|
path,
|
|
25951
25984
|
...classification
|
|
25952
25985
|
};
|
|
25953
|
-
}).sort((left, right) =>
|
|
25986
|
+
}).sort((left, right) => {
|
|
25987
|
+
if (left.path < right.path) return -1;
|
|
25988
|
+
return left.path > right.path ? 1 : 0;
|
|
25989
|
+
});
|
|
25954
25990
|
}
|
|
25955
25991
|
const abapgitFormatPlugin = {
|
|
25956
25992
|
id: "abapgit",
|
|
@@ -26175,7 +26211,7 @@ const abapGitPlugin = createPlugin({
|
|
|
26175
26211
|
* PROG deletions without obj_func=D), no files are present and nothing
|
|
26176
26212
|
* happens. This is expected behavior.
|
|
26177
26213
|
*/
|
|
26178
|
-
|
|
26214
|
+
delete(objectRef, targetPath, _context) {
|
|
26179
26215
|
try {
|
|
26180
26216
|
const srcDir = resolve(targetPath, "src");
|
|
26181
26217
|
const matchedFiles = findObjectFiles(srcDir, objectRef.name, objectRef.type);
|
|
@@ -26192,21 +26228,21 @@ const abapGitPlugin = createPlugin({
|
|
|
26192
26228
|
errors.push(error instanceof Error ? `Failed to delete ${relative(targetPath, filePath)}: ${error.message}` : `Failed to delete ${relative(targetPath, filePath)}: ${String(error)}`);
|
|
26193
26229
|
}
|
|
26194
26230
|
srcDirIndexCache.get(srcDir)?.set(`${objectRef.name.toLowerCase()}.${objectRef.type.toLowerCase()}.`, matchedFiles.filter((filePath) => existsSync(filePath)));
|
|
26195
|
-
return {
|
|
26231
|
+
return Promise.resolve({
|
|
26196
26232
|
success: errors.length === 0,
|
|
26197
26233
|
filesRemoved,
|
|
26198
26234
|
...errors.length > 0 ? { errors } : {}
|
|
26199
|
-
};
|
|
26235
|
+
});
|
|
26200
26236
|
} catch (error) {
|
|
26201
|
-
return {
|
|
26237
|
+
return Promise.resolve({
|
|
26202
26238
|
success: false,
|
|
26203
26239
|
filesRemoved: [],
|
|
26204
26240
|
errors: [error instanceof Error ? error.message : String(error)]
|
|
26205
|
-
};
|
|
26241
|
+
});
|
|
26206
26242
|
}
|
|
26207
26243
|
}
|
|
26208
26244
|
},
|
|
26209
|
-
hooks: {
|
|
26245
|
+
hooks: { afterImport(targetPath) {
|
|
26210
26246
|
const target = resolve(targetPath);
|
|
26211
26247
|
const folderLogic = folderLogicByTarget.get(target) ?? readFolderLogicFromExistingRepo(targetPath) ?? "prefix";
|
|
26212
26248
|
try {
|
|
@@ -26217,6 +26253,7 @@ const abapGitPlugin = createPlugin({
|
|
|
26217
26253
|
folderLogicByTarget.delete(target);
|
|
26218
26254
|
srcDirIndexCache.delete(resolve(targetPath, "src"));
|
|
26219
26255
|
}
|
|
26256
|
+
return Promise.resolve();
|
|
26220
26257
|
} }
|
|
26221
26258
|
});
|
|
26222
26259
|
|