@abapify/adk 0.4.1 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,6 +1,23 @@
1
- import { A as Package, C as Domain, D as Include, E as FunctionModule, F as TransportRequest, I as TransportTask, M as Structure, N as Table, O as Interface, P as TableType, S as DataElement, T as FunctionGroup, _ as parseAdtType, a as parseXmlIdentity, b as resolveType, c as getKindForType, d as getObjectUri, f as getRegisteredKinds, g as normalizeObjectName, h as isTypeRegistered, j as Program, k as MessageClass, l as getMainType, m as getTypeForKind, n as createAdk, o as ADT_TYPE_MAPPINGS, p as getRegisteredTypes, r as createAdkFactory, s as getEndpointForType, t as AdkGenericObject, u as getObjectRootUri, v as registerObjectType, w as EnhancementSpot, x as Class, y as resolveKind } from "./factory-DtyrTGlN.mjs";
2
- import { createLockService, createLockService as createLockService$1 } from "@abapify/adt-locks";
1
+ import { createLockService, createLockService as createLockService$1, resolveLockCorrelation } from "@abapify/adt-locks";
2
+ import { assertAdtUri } from "@abapify/adt-client";
3
3
 
4
+ //#region \0rolldown/runtime.js
5
+ var __defProp = Object.defineProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) {
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ }
14
+ if (!no_symbols) {
15
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ }
17
+ return target;
18
+ };
19
+
20
+ //#endregion
4
21
  //#region src/base/fetch-utils.ts
5
22
  /**
6
23
  * Utility for handling v2 client fetch responses.
@@ -30,6 +47,25 @@ async function toText(result) {
30
47
  //#endregion
31
48
  //#region src/base/model.ts
32
49
  /**
50
+ * SAP accepted the skeleton POST, but rejected the immediate follow-up lock.
51
+ *
52
+ * The object therefore exists in SAP, while the source or metadata supplied
53
+ * to the original save call has not yet been persisted. Callers must retry
54
+ * the same object with `mode: 'update'` after the CTS/editor lock is cleared;
55
+ * repeating `mode: 'create'` risks an "already exists" response.
56
+ */
57
+ var AdkPostCreateLockError = class extends Error {
58
+ objectUri;
59
+ transport;
60
+ code = "ADT_POST_CREATE_LOCKED";
61
+ name = "AdkPostCreateLockError";
62
+ constructor(objectUri, transport, cause) {
63
+ super(`SAP created ${objectUri}, but its post-create CTS lock is still active. Retry the pending change with mode: 'update' after the lock clears; do not create the object again.`, { cause });
64
+ this.objectUri = objectUri;
65
+ this.transport = transport;
66
+ }
67
+ };
68
+ /**
33
69
  * Base class for all ADK objects
34
70
  *
35
71
  * All ADK objects (AdkPackage, AdkTransportRequest, etc.) extend this.
@@ -263,10 +299,23 @@ var AdkObject = class {
263
299
  const { transport, mode = "update" } = options;
264
300
  this._unchanged = false;
265
301
  if (mode === "create") {
266
- if (!await this.checkObjectExists()) await this.saveViaContract("create", { transport });
302
+ if (!await this.checkObjectExists()) {
303
+ await this.saveViaContract("create", { transport });
304
+ try {
305
+ return await this.save({
306
+ ...options,
307
+ mode: "update",
308
+ postCreate: true
309
+ });
310
+ } catch (error) {
311
+ if (this.isPostCreateLockConflict(error)) throw new AdkPostCreateLockError(this.objectUri, transport, error);
312
+ throw error;
313
+ }
314
+ }
267
315
  return this.save({
268
316
  ...options,
269
- mode: "update"
317
+ mode: "update",
318
+ postCreate: options.postCreateLockRetry !== void 0
270
319
  });
271
320
  }
272
321
  const hasPendingSources = this.hasPendingSources();
@@ -285,13 +334,14 @@ var AdkObject = class {
285
334
  }
286
335
  const wasLocked = this.isLocked;
287
336
  if (!wasLocked) try {
288
- await this.lock(transport);
337
+ if (options.postCreate) await this.lockAfterCreate(transport, options.postCreateLockRetry);
338
+ else await this.lock(transport);
289
339
  } catch (e) {
290
340
  if (mode === "upsert" && !confirmedExists && this.shouldFallbackToCreate(e)) return this.fallbackToCreate(options);
291
341
  throw e;
292
342
  }
293
343
  try {
294
- const effectiveTransport = transport ?? this._lockHandle?.correlationNumber;
344
+ const effectiveTransport = resolveLockCorrelation(this._lockHandle ?? {}, transport);
295
345
  if (!wasLocked) await this.refreshETagsAfterLock();
296
346
  if (hasPendingSources) await this.savePendingSources({
297
347
  lockHandle: this._lockHandle?.handle,
@@ -417,6 +467,41 @@ var AdkObject = class {
417
467
  return false;
418
468
  }
419
469
  /**
470
+ * Some CTS backends can retain the lock created by a successful object POST
471
+ * long enough for the immediate follow-up LOCK to fail. This is distinct
472
+ * from an arbitrary edit conflict because this save invocation already
473
+ * created the skeleton successfully.
474
+ */
475
+ isPostCreateLockConflict(e) {
476
+ let message = "";
477
+ if (typeof e === "string") message = e;
478
+ else if (e instanceof Error) message = e.message;
479
+ else if (typeof e === "object" && e !== null && typeof e.message === "string") message = e.message;
480
+ const normalized = message.toLowerCase();
481
+ return normalized.includes("already locked in request") || normalized.includes("currently editing") || normalized.includes("is being edited");
482
+ }
483
+ /**
484
+ * Some backends retain the lock implicitly created by a successful POST for
485
+ * a short time. Retry only this known follow-up LOCK; no arbitrary update or
486
+ * source write is repeated, and each successful lock still uses the normal
487
+ * handle-backed save/unlock lifecycle.
488
+ */
489
+ async lockAfterCreate(transport, retry) {
490
+ const attempts = retry?.attempts ?? 1;
491
+ const delayMs = retry?.delayMs ?? 0;
492
+ if (!Number.isInteger(attempts) || attempts < 1) throw new RangeError("postCreateLockRetry.attempts must be a positive integer.");
493
+ if (!Number.isFinite(delayMs) || delayMs < 0) throw new RangeError("postCreateLockRetry.delayMs must be a non-negative number.");
494
+ let lastConflict;
495
+ for (let attempt = 1; attempt <= attempts; attempt += 1) try {
496
+ return await this.lock(transport);
497
+ } catch (error) {
498
+ if (!this.isPostCreateLockConflict(error) || attempt === attempts) throw error;
499
+ lastConflict = error;
500
+ if (delayMs > 0) await new Promise((resolve) => setTimeout(resolve, delayMs));
501
+ }
502
+ throw lastConflict;
503
+ }
504
+ /**
420
505
  * Upsert fallback: try POST (create), treat 422 "already exists" as unchanged.
421
506
  * Extracted to avoid duplication in lock-catch and saveViaContract-catch paths.
422
507
  */
@@ -486,10 +571,11 @@ var AdkObject = class {
486
571
  const self = this;
487
572
  if (!self._pendingSource) return;
488
573
  try {
489
- const currentSource = await toText(await this.ctx.client.fetch(`${this.objectUri}/source/main`, {
574
+ const response = await this.ctx.client.fetch(`${this.objectUri}/source/main`, {
490
575
  method: "GET",
491
576
  headers: { Accept: "text/plain" }
492
- }));
577
+ });
578
+ const currentSource = await toText(response);
493
579
  if (this.normalizeSource(currentSource) === this.normalizeSource(self._pendingSource)) {
494
580
  this._unchanged = true;
495
581
  delete self._pendingSource;
@@ -512,7 +598,7 @@ var AdkObject = class {
512
598
  const sapData = (await contract.get(this.name))?.[wrapperKey];
513
599
  if (!sapData) return;
514
600
  const localData = await this.data();
515
- const isEmpty = (v) => v == null || v === "" || Array.isArray(v) && v.length === 0 || typeof v === "object" && v !== null && Object.keys(v).length === 0;
601
+ const isEmpty = (v) => v == null || v === "" || Array.isArray(v) && v.length === 0 || typeof v === "object" && Object.keys(v).length === 0;
516
602
  const isSubsetMatch = (local, sap) => {
517
603
  if (local === sap) return true;
518
604
  if (isEmpty(local) && isEmpty(sap)) return true;
@@ -613,10 +699,11 @@ var AdkObject = class {
613
699
  async setSource(sourcePath, content, options = {}) {
614
700
  const { transport } = options;
615
701
  const wasLocked = this.isLocked;
616
- if (!wasLocked) await this.lock();
702
+ if (!wasLocked) await this.lock(transport);
617
703
  try {
618
704
  const params = new URLSearchParams();
619
- if (transport) params.set("corrNr", transport);
705
+ const effectiveTransport = resolveLockCorrelation(this._lockHandle ?? {}, transport);
706
+ if (effectiveTransport) params.set("corrNr", effectiveTransport);
620
707
  if (this._lockHandle) params.set("lockHandle", this._lockHandle.handle);
621
708
  const fullPath = `${this.objectUri}${sourcePath}`;
622
709
  const url = params.toString() ? `${fullPath}?${params.toString()}` : fullPath;
@@ -689,10 +776,11 @@ var AdkObject = class {
689
776
  */
690
777
  async fetchText(url, headers) {
691
778
  try {
692
- return toText(await this.ctx.client.fetch(url, {
779
+ const response = await this.ctx.client.fetch(url, {
693
780
  method: "GET",
694
781
  headers: headers ?? {}
695
- }));
782
+ });
783
+ return toText(response);
696
784
  } catch {
697
785
  return;
698
786
  }
@@ -971,16 +1059,23 @@ var AdkObjectSet = class AdkObjectSet {
971
1059
  const obj = r.object;
972
1060
  const deferred = obj._deferredSources;
973
1061
  if (deferred && deferred.length > 0) try {
974
- const lock = await r.object.lock();
1062
+ const lock = await r.object.lock(saveOptions.transport);
1063
+ const effectiveTransport = resolveLockCorrelation(lock, saveOptions.transport);
975
1064
  for (const [key, source] of deferred) await obj.saveIncludeSource(key, source, {
976
1065
  lockHandle: lock.handle,
977
- transport: saveOptions.transport
1066
+ transport: effectiveTransport
978
1067
  });
979
- delete obj._deferredSources;
980
1068
  const deferredSet = new AdkObjectSet(this.ctx);
981
1069
  deferredSet.add(r.object);
982
- await deferredSet.activateAll();
983
- } catch {} finally {
1070
+ const deferredActivation = await deferredSet.activateAll();
1071
+ if (deferredActivation.failed > 0) throw new Error(`Deferred activation failed: ${deferredActivation.messages.join("; ") || "unknown error"}`);
1072
+ delete obj._deferredSources;
1073
+ } catch (error) {
1074
+ r.success = false;
1075
+ r.error = `Deferred source deployment failed: ${error instanceof Error ? error.message : String(error)}`;
1076
+ saveResult.success--;
1077
+ saveResult.failed++;
1078
+ } finally {
984
1079
  try {
985
1080
  await r.object.unlock();
986
1081
  } catch {}
@@ -1102,7 +1197,7 @@ let globalContext = null;
1102
1197
  * initializeAdk(client);
1103
1198
  *
1104
1199
  * // Now ADK objects work without context
1105
- * const transport = await AdkTransportRequest.get('S0DK900001');
1200
+ * const transport = await AdkTransportRequest.get('TRLK900001');
1106
1201
  * ```
1107
1202
  */
1108
1203
  function initializeAdk(client, options) {
@@ -1165,6 +1260,271 @@ function tryGetGlobalContext() {
1165
1260
  return globalContext ?? void 0;
1166
1261
  }
1167
1262
 
1263
+ //#endregion
1264
+ //#region src/base/kinds.ts
1265
+ /**
1266
+ * ADK Object Kinds
1267
+ *
1268
+ * Central registry of all ADK object types.
1269
+ * Import specific kinds for type-safe usage:
1270
+ *
1271
+ * @example
1272
+ * import { TransportRequest } from '../base/kinds';
1273
+ * class AdkTransportRequest extends AdkObject<typeof TransportRequest> { ... }
1274
+ */
1275
+ const TransportRequest = "TransportRequest";
1276
+ const TransportTask = "TransportTask";
1277
+ const Package = "Package";
1278
+ const Class = "Class";
1279
+ const Interface = "Interface";
1280
+ const FunctionGroup = "FunctionGroup";
1281
+ const FunctionModule = "FunctionModule";
1282
+ const Program = "Program";
1283
+ const Include = "Include";
1284
+ const Table = "Table";
1285
+ const Structure = "Structure";
1286
+ const DataElement = "DataElement";
1287
+ const Domain = "Domain";
1288
+ const TableType = "TableType";
1289
+ const DdlSource = "DdlSource";
1290
+ const DclSource = "DclSource";
1291
+ const DdlExtension = "DdlExtension";
1292
+ const CdsAspect = "CdsAspect";
1293
+ const CdsType = "CdsType";
1294
+ const ScalarFunctionDefinition = "ScalarFunctionDefinition";
1295
+ const ScalarFunctionImplementation = "ScalarFunctionImplementation";
1296
+ const EntityBuffer = "EntityBuffer";
1297
+ const DynamicCache = "DynamicCache";
1298
+ const TuningIndex = "TuningIndex";
1299
+ const StaticCache = "StaticCache";
1300
+ const ExternalSchema = "ExternalSchema";
1301
+ const BehaviorDefinition = "BehaviorDefinition";
1302
+ const ServiceDefinition = "ServiceDefinition";
1303
+ const ServiceBinding = "ServiceBinding";
1304
+ const MessageClass = "MessageClass";
1305
+ const EnhancementSpot = "EnhancementSpot";
1306
+
1307
+ //#endregion
1308
+ //#region src/base/registry.ts
1309
+ /**
1310
+ * Parse ADT type into components
1311
+ *
1312
+ * @example
1313
+ * parseAdtType("DEVC/K") // { full: "DEVC/K", main: "DEVC", sub: "K" }
1314
+ * parseAdtType("DEVC") // { full: "DEVC", main: "DEVC", sub: undefined }
1315
+ */
1316
+ function parseAdtType(adtType) {
1317
+ const [main, sub] = adtType.split("/");
1318
+ return {
1319
+ full: adtType,
1320
+ main: main.toUpperCase(),
1321
+ sub: sub?.toUpperCase()
1322
+ };
1323
+ }
1324
+ /**
1325
+ * Get main type from ADT type
1326
+ *
1327
+ * @example
1328
+ * getMainType("DEVC/K") // "DEVC"
1329
+ * getMainType("CLAS") // "CLAS"
1330
+ */
1331
+ function getMainType(adtType) {
1332
+ return parseAdtType(adtType).main;
1333
+ }
1334
+ /** Internal registry storage */
1335
+ const registry = /* @__PURE__ */ new Map();
1336
+ /** ADT main type to ADK kind mapping */
1337
+ const adtToKind = /* @__PURE__ */ new Map();
1338
+ /** ADK kind to ADT main type mapping (reverse) */
1339
+ const kindToAdt = /* @__PURE__ */ new Map();
1340
+ /**
1341
+ * Register an ADK object type
1342
+ *
1343
+ * @param adtType - ADT type, either main (e.g., "CLAS") or full (e.g., "TABL/DS")
1344
+ * @param kind - ADK kind constant
1345
+ * @param constructor - Object constructor
1346
+ * @param options - Optional endpoint and name transform settings
1347
+ */
1348
+ function registerObjectType(adtType, kind, constructor, options) {
1349
+ const normalizedType = adtType.toUpperCase();
1350
+ registry.set(normalizedType, {
1351
+ kind,
1352
+ constructor,
1353
+ endpoint: options?.endpoint,
1354
+ nameTransform: options?.nameTransform,
1355
+ normalizeName: options?.normalizeName
1356
+ });
1357
+ adtToKind.set(normalizedType, kind);
1358
+ kindToAdt.set(kind, normalizedType);
1359
+ }
1360
+ /**
1361
+ * Resolve ADT type to registry entry
1362
+ *
1363
+ * Tries full type first (e.g., "TABL/DS"), then falls back to main type (e.g., "TABL").
1364
+ * This allows registering subtypes with different constructors/endpoints.
1365
+ *
1366
+ * @param adtType - Full or main ADT type (e.g., "DEVC/K" or "DEVC")
1367
+ * @returns Registry entry or undefined if not found
1368
+ */
1369
+ function resolveType(adtType) {
1370
+ const normalized = adtType.toUpperCase();
1371
+ const fullMatch = registry.get(normalized);
1372
+ if (fullMatch) return fullMatch;
1373
+ const mainType = getMainType(adtType);
1374
+ return registry.get(mainType);
1375
+ }
1376
+ /**
1377
+ * Resolve ADK kind to registry entry
1378
+ *
1379
+ * @param kind - ADK kind constant
1380
+ * @returns Registry entry or undefined if not found
1381
+ */
1382
+ function resolveKind(kind) {
1383
+ const adtType = kindToAdt.get(kind);
1384
+ if (!adtType) return void 0;
1385
+ return registry.get(adtType);
1386
+ }
1387
+ /**
1388
+ * Get ADK kind for ADT type
1389
+ */
1390
+ function getKindForType(adtType) {
1391
+ return adtToKind.get(getMainType(adtType));
1392
+ }
1393
+ /**
1394
+ * Get ADT main type for ADK kind
1395
+ */
1396
+ function getTypeForKind(kind) {
1397
+ return kindToAdt.get(kind);
1398
+ }
1399
+ /**
1400
+ * Check if ADT type is registered
1401
+ */
1402
+ function isTypeRegistered(adtType) {
1403
+ return registry.has(getMainType(adtType));
1404
+ }
1405
+ /**
1406
+ * Get all registered ADT types
1407
+ */
1408
+ function getRegisteredTypes() {
1409
+ return Array.from(registry.keys());
1410
+ }
1411
+ /**
1412
+ * Get all registered ADK kinds
1413
+ */
1414
+ function getRegisteredKinds() {
1415
+ return Array.from(kindToAdt.keys());
1416
+ }
1417
+ /**
1418
+ * Get ADT REST endpoint for a type (e.g., 'oo/classes', 'ddic/tabletypes')
1419
+ * Checks exact type first (e.g., 'TABL/DS') before falling back to main type.
1420
+ */
1421
+ function getEndpointForType(adtType) {
1422
+ return resolveType(adtType)?.endpoint;
1423
+ }
1424
+ /**
1425
+ * Build the full ADT object URI for a given type and name.
1426
+ *
1427
+ * @example
1428
+ * getObjectUri('CLAS', 'ZCL_MY_CLASS') // '/sap/bc/adt/oo/classes/zcl_my_class'
1429
+ * getObjectUri('DEVC', 'ZPACKAGE') // '/sap/bc/adt/packages/ZPACKAGE'
1430
+ * getObjectUri('TTYP', 'ZAGE_TTYP_STRTAB') // '/sap/bc/adt/ddic/tabletypes/zage_ttyp_strtab'
1431
+ */
1432
+ function getObjectUri(adtType, name) {
1433
+ const entry = resolveType(adtType);
1434
+ if (!entry?.endpoint) return void 0;
1435
+ const normalized = entry.normalizeName ? entry.normalizeName(name) : name;
1436
+ const transformedName = entry.nameTransform === "preserve" ? encodeURIComponent(normalized) : encodeURIComponent(normalized.toLowerCase());
1437
+ return `/sap/bc/adt/${entry.endpoint}/${transformedName}`;
1438
+ }
1439
+ /**
1440
+ * Normalize an object name using type-specific rules.
1441
+ *
1442
+ * If `adtType` is provided, applies that type's normalizer only.
1443
+ * Otherwise, collects all possible normalized forms from every registered type.
1444
+ *
1445
+ * @returns Array of candidate names (always includes the original).
1446
+ *
1447
+ * @example
1448
+ * normalizeObjectName('SAPLZAGE_FUGR') // ['SAPLZAGE_FUGR', 'ZAGE_FUGR']
1449
+ * normalizeObjectName('SAPLZAGE_FUGR', 'FUGR') // ['ZAGE_FUGR']
1450
+ * normalizeObjectName('ZCLAS_TEST') // ['ZCLAS_TEST'] (no normalizer matches)
1451
+ */
1452
+ function normalizeObjectName(name, adtType) {
1453
+ if (adtType) return [resolveType(adtType)?.normalizeName?.(name) ?? name];
1454
+ const candidates = /* @__PURE__ */ new Set([name]);
1455
+ for (const entry of registry.values()) if (entry.normalizeName) candidates.add(entry.normalizeName(name));
1456
+ return Array.from(candidates);
1457
+ }
1458
+ /**
1459
+ * Extract the root object URI from a full (possibly sub-resource) URI.
1460
+ *
1461
+ * SAP locks must target the object root, not sub-resources like `/source/main`.
1462
+ * This function matches against registered endpoint prefixes and strips
1463
+ * everything after the object name segment.
1464
+ *
1465
+ * @returns The root object URI, or the original URI unchanged if no endpoint matches.
1466
+ *
1467
+ * @example
1468
+ * getObjectRootUri('/sap/bc/adt/functions/groups/zage_fugr/source/main')
1469
+ * // → '/sap/bc/adt/functions/groups/zage_fugr'
1470
+ * getObjectRootUri('/sap/bc/adt/oo/classes/zcl_test/includes/testclasses')
1471
+ * // → '/sap/bc/adt/oo/classes/zcl_test'
1472
+ * getObjectRootUri('/sap/bc/adt/oo/classes/zcl_test')
1473
+ * // → '/sap/bc/adt/oo/classes/zcl_test' (already root)
1474
+ */
1475
+ function getObjectRootUri(uri) {
1476
+ const ADT_PREFIX = "/sap/bc/adt/";
1477
+ const endpoints = [];
1478
+ for (const entry of registry.values()) if (entry.endpoint) endpoints.push(entry.endpoint);
1479
+ endpoints.sort((a, b) => b.length - a.length);
1480
+ for (const endpoint of endpoints) {
1481
+ const prefix = `${ADT_PREFIX}${endpoint}/`;
1482
+ if (uri.startsWith(prefix)) return `${prefix}${uri.slice(prefix.length).split("/")[0]}`;
1483
+ }
1484
+ return uri;
1485
+ }
1486
+ /**
1487
+ * Known ADT type to ADK kind mappings
1488
+ *
1489
+ * Repository Objects:
1490
+ * - DEVC → Package
1491
+ * - CLAS → Class
1492
+ * - INTF → Interface
1493
+ * - FUGR → FunctionGroup
1494
+ * - FUNC → FunctionModule
1495
+ * - PROG → Program
1496
+ * - INCL → Include
1497
+ *
1498
+ * Data Dictionary:
1499
+ * - TABL → Table
1500
+ * - STRU → Structure (actually TABL with different category)
1501
+ * - DTEL → DataElement
1502
+ * - DOMA → Domain
1503
+ * - TTYP → TableType
1504
+ *
1505
+ * Other:
1506
+ * - MSAG → MessageClass
1507
+ * - ENHS → EnhancementSpot
1508
+ *
1509
+ * CTS:
1510
+ * - (Transport requests/tasks use different identification)
1511
+ */
1512
+ const ADT_TYPE_MAPPINGS = {
1513
+ DEVC: Package,
1514
+ CLAS: Class,
1515
+ INTF: Interface,
1516
+ FUGR: FunctionGroup,
1517
+ FUNC: FunctionModule,
1518
+ PROG: Program,
1519
+ INCL: Include,
1520
+ TABL: Table,
1521
+ DTEL: DataElement,
1522
+ DOMA: Domain,
1523
+ TTYP: TableType,
1524
+ MSAG: MessageClass,
1525
+ ENHS: EnhancementSpot
1526
+ };
1527
+
1168
1528
  //#endregion
1169
1529
  //#region src/objects/repository/devc/devc.model.ts
1170
1530
  /**
@@ -1330,7 +1690,8 @@ var AdkPackage = class AdkPackage extends AdkMainObject {
1330
1690
  * @param ctx - Optional ADK context (uses global context if not provided)
1331
1691
  */
1332
1692
  static async get(name, ctx) {
1333
- const pkg = new AdkPackage(ctx ?? getGlobalContext(), name);
1693
+ const context = ctx ?? getGlobalContext();
1694
+ const pkg = new AdkPackage(context, name);
1334
1695
  await pkg.load();
1335
1696
  return pkg;
1336
1697
  }
@@ -1343,7 +1704,8 @@ var AdkPackage = class AdkPackage extends AdkMainObject {
1343
1704
  */
1344
1705
  static async exists(name, ctx) {
1345
1706
  try {
1346
- await new AdkPackage(ctx ?? getGlobalContext(), name).load();
1707
+ const context = ctx ?? getGlobalContext();
1708
+ await new AdkPackage(context, name).load();
1347
1709
  return true;
1348
1710
  } catch {
1349
1711
  return false;
@@ -1360,7 +1722,8 @@ var AdkPackage = class AdkPackage extends AdkMainObject {
1360
1722
  * @param ctx - Optional ADK context (uses global context if not provided)
1361
1723
  */
1362
1724
  static async create(name, data, options, ctx) {
1363
- const pkg = new AdkPackage(ctx ?? getGlobalContext(), name);
1725
+ const context = ctx ?? getGlobalContext();
1726
+ const pkg = new AdkPackage(context, name);
1364
1727
  pkg.setData({
1365
1728
  name,
1366
1729
  type: "DEVC/K",
@@ -1395,7 +1758,8 @@ var AdkPackage = class AdkPackage extends AdkMainObject {
1395
1758
  * @param ctx - Optional ADK context (uses global context if not provided)
1396
1759
  */
1397
1760
  static async delete(name, options, ctx) {
1398
- await new AdkPackage(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
1761
+ const context = ctx ?? getGlobalContext();
1762
+ await new AdkPackage(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
1399
1763
  ...options?.transport && { corrNr: options.transport },
1400
1764
  ...options?.lockHandle && { lockHandle: options.lockHandle }
1401
1765
  });
@@ -1655,7 +2019,8 @@ var AdkClass = class AdkClass extends AdkMainObject {
1655
2019
  return this.ctx.client.adt.oo.classes;
1656
2020
  }
1657
2021
  static async get(name, ctx) {
1658
- return new AdkClass(ctx ?? getGlobalContext(), name).load();
2022
+ const context = ctx ?? getGlobalContext();
2023
+ return new AdkClass(context, name).load();
1659
2024
  }
1660
2025
  /**
1661
2026
  * Check if a class exists on SAP
@@ -1678,7 +2043,8 @@ var AdkClass = class AdkClass extends AdkMainObject {
1678
2043
  * @param ctx - Optional ADK context
1679
2044
  */
1680
2045
  static async create(name, description, packageName, options, ctx) {
1681
- const cls = new AdkClass(ctx ?? getGlobalContext(), name.toUpperCase());
2046
+ const context = ctx ?? getGlobalContext();
2047
+ const cls = new AdkClass(context, name.toUpperCase());
1682
2048
  cls.setData({
1683
2049
  name: name.toUpperCase(),
1684
2050
  type: "CLAS/OC",
@@ -1705,7 +2071,8 @@ var AdkClass = class AdkClass extends AdkMainObject {
1705
2071
  * @param ctx - Optional ADK context
1706
2072
  */
1707
2073
  static async delete(name, options, ctx) {
1708
- await new AdkClass(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2074
+ const context = ctx ?? getGlobalContext();
2075
+ await new AdkClass(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
1709
2076
  corrNr: options?.transport,
1710
2077
  lockHandle: options?.lockHandle
1711
2078
  });
@@ -1748,7 +2115,8 @@ var AdkInterface = class AdkInterface extends AdkMainObject {
1748
2115
  return this.ctx.client.adt.oo.interfaces;
1749
2116
  }
1750
2117
  static async get(name, ctx) {
1751
- return new AdkInterface(ctx ?? getGlobalContext(), name).load();
2118
+ const context = ctx ?? getGlobalContext();
2119
+ return new AdkInterface(context, name).load();
1752
2120
  }
1753
2121
  /**
1754
2122
  * Check if an interface exists on SAP
@@ -1771,7 +2139,8 @@ var AdkInterface = class AdkInterface extends AdkMainObject {
1771
2139
  * @param ctx - Optional ADK context
1772
2140
  */
1773
2141
  static async create(name, description, packageName, options, ctx) {
1774
- const intf = new AdkInterface(ctx ?? getGlobalContext(), name.toUpperCase());
2142
+ const context = ctx ?? getGlobalContext();
2143
+ const intf = new AdkInterface(context, name.toUpperCase());
1775
2144
  intf.setData({
1776
2145
  name: name.toUpperCase(),
1777
2146
  type: "INTF/OI",
@@ -1798,7 +2167,8 @@ var AdkInterface = class AdkInterface extends AdkMainObject {
1798
2167
  * @param ctx - Optional ADK context
1799
2168
  */
1800
2169
  static async delete(name, options, ctx) {
1801
- await new AdkInterface(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2170
+ const context = ctx ?? getGlobalContext();
2171
+ await new AdkInterface(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
1802
2172
  corrNr: options?.transport,
1803
2173
  lockHandle: options?.lockHandle
1804
2174
  });
@@ -1841,7 +2211,8 @@ var AdkProgram = class AdkProgram extends AdkMainObject {
1841
2211
  return this.ctx.client.adt.programs.programs;
1842
2212
  }
1843
2213
  static async get(name, ctx) {
1844
- return new AdkProgram(ctx ?? getGlobalContext(), name).load();
2214
+ const context = ctx ?? getGlobalContext();
2215
+ return new AdkProgram(context, name).load();
1845
2216
  }
1846
2217
  /**
1847
2218
  * Check if a program exists on SAP
@@ -1864,7 +2235,8 @@ var AdkProgram = class AdkProgram extends AdkMainObject {
1864
2235
  * @param ctx - Optional ADK context
1865
2236
  */
1866
2237
  static async create(name, description, packageName, options, ctx) {
1867
- const prog = new AdkProgram(ctx ?? getGlobalContext(), name.toUpperCase());
2238
+ const context = ctx ?? getGlobalContext();
2239
+ const prog = new AdkProgram(context, name.toUpperCase());
1868
2240
  prog.setData({
1869
2241
  name: name.toUpperCase(),
1870
2242
  type: "PROG/P",
@@ -1891,7 +2263,8 @@ var AdkProgram = class AdkProgram extends AdkMainObject {
1891
2263
  * @param ctx - Optional ADK context
1892
2264
  */
1893
2265
  static async delete(name, options, ctx) {
1894
- await new AdkProgram(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2266
+ const context = ctx ?? getGlobalContext();
2267
+ await new AdkProgram(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
1895
2268
  corrNr: options?.transport,
1896
2269
  lockHandle: options?.lockHandle
1897
2270
  });
@@ -1952,7 +2325,8 @@ var AdkInclude = class AdkInclude extends AdkMainObject {
1952
2325
  return base;
1953
2326
  }
1954
2327
  static async get(name, ctx) {
1955
- return new AdkInclude(ctx ?? getGlobalContext(), name).load();
2328
+ const context = ctx ?? getGlobalContext();
2329
+ return new AdkInclude(context, name).load();
1956
2330
  }
1957
2331
  /**
1958
2332
  * Check if an include exists on SAP
@@ -1975,7 +2349,8 @@ var AdkInclude = class AdkInclude extends AdkMainObject {
1975
2349
  * @param ctx - Optional ADK context
1976
2350
  */
1977
2351
  static async create(name, description, packageName, options, ctx) {
1978
- const incl = new AdkInclude(ctx ?? getGlobalContext(), name.toUpperCase());
2352
+ const context = ctx ?? getGlobalContext();
2353
+ const incl = new AdkInclude(context, name.toUpperCase());
1979
2354
  const data = {
1980
2355
  name: name.toUpperCase(),
1981
2356
  type: "PROG/I",
@@ -2011,7 +2386,8 @@ var AdkInclude = class AdkInclude extends AdkMainObject {
2011
2386
  * @param ctx - Optional ADK context
2012
2387
  */
2013
2388
  static async delete(name, options, ctx) {
2014
- await new AdkInclude(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2389
+ const context = ctx ?? getGlobalContext();
2390
+ await new AdkInclude(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2015
2391
  corrNr: options?.transport,
2016
2392
  lockHandle: options?.lockHandle
2017
2393
  });
@@ -2054,7 +2430,8 @@ var AdkFunctionGroup = class AdkFunctionGroup extends AdkMainObject {
2054
2430
  return this.ctx.client.adt.functions.groups;
2055
2431
  }
2056
2432
  static async get(name, ctx) {
2057
- return new AdkFunctionGroup(ctx ?? getGlobalContext(), name).load();
2433
+ const context = ctx ?? getGlobalContext();
2434
+ return new AdkFunctionGroup(context, name).load();
2058
2435
  }
2059
2436
  /**
2060
2437
  * Check if a function group exists on SAP
@@ -2071,7 +2448,8 @@ var AdkFunctionGroup = class AdkFunctionGroup extends AdkMainObject {
2071
2448
  * Create a new ABAP function group on SAP
2072
2449
  */
2073
2450
  static async create(name, description, packageName, options, ctx) {
2074
- const fugr = new AdkFunctionGroup(ctx ?? getGlobalContext(), name.toUpperCase());
2451
+ const context = ctx ?? getGlobalContext();
2452
+ const fugr = new AdkFunctionGroup(context, name.toUpperCase());
2075
2453
  fugr.setData({
2076
2454
  name: name.toUpperCase(),
2077
2455
  type: "FUGR/F",
@@ -2094,7 +2472,8 @@ var AdkFunctionGroup = class AdkFunctionGroup extends AdkMainObject {
2094
2472
  * Delete an ABAP function group from SAP
2095
2473
  */
2096
2474
  static async delete(name, options, ctx) {
2097
- await new AdkFunctionGroup(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2475
+ const context = ctx ?? getGlobalContext();
2476
+ await new AdkFunctionGroup(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2098
2477
  corrNr: options?.transport,
2099
2478
  lockHandle: options?.lockHandle
2100
2479
  });
@@ -2387,7 +2766,8 @@ var AdkFunctionModule = class AdkFunctionModule extends AdkObject {
2387
2766
  * @param ctx - Optional ADK context (uses global if not provided)
2388
2767
  */
2389
2768
  static async get(groupName, name, ctx) {
2390
- return new AdkFunctionModule(ctx ?? getGlobalContext(), groupName, name).load();
2769
+ const context = ctx ?? getGlobalContext();
2770
+ return new AdkFunctionModule(context, groupName, name).load();
2391
2771
  }
2392
2772
  /**
2393
2773
  * Check if a function module exists on SAP
@@ -2404,7 +2784,8 @@ var AdkFunctionModule = class AdkFunctionModule extends AdkObject {
2404
2784
  * Create a new ABAP function module on SAP
2405
2785
  */
2406
2786
  static async create(groupName, name, description, options, ctx) {
2407
- const fm = new AdkFunctionModule(ctx ?? getGlobalContext(), groupName.toUpperCase(), name.toUpperCase());
2787
+ const context = ctx ?? getGlobalContext();
2788
+ const fm = new AdkFunctionModule(context, groupName.toUpperCase(), name.toUpperCase());
2408
2789
  fm.setData({
2409
2790
  name: name.toUpperCase(),
2410
2791
  type: "FUGR/FF",
@@ -2421,7 +2802,8 @@ var AdkFunctionModule = class AdkFunctionModule extends AdkObject {
2421
2802
  * Delete a function module from SAP
2422
2803
  */
2423
2804
  static async delete(groupName, name, options, ctx) {
2424
- await new AdkFunctionModule(ctx ?? getGlobalContext(), groupName.toUpperCase(), name.toUpperCase()).crudContract.delete(groupName.toUpperCase(), name.toUpperCase(), {
2805
+ const context = ctx ?? getGlobalContext();
2806
+ await new AdkFunctionModule(context, groupName.toUpperCase(), name.toUpperCase()).crudContract.delete(groupName.toUpperCase(), name.toUpperCase(), {
2425
2807
  corrNr: options?.transport,
2426
2808
  lockHandle: options?.lockHandle
2427
2809
  });
@@ -2462,7 +2844,8 @@ var AdkDomain = class AdkDomain extends AdkMainObject {
2462
2844
  return this.ctx.client.adt.ddic.domains;
2463
2845
  }
2464
2846
  static async get(name, ctx) {
2465
- return new AdkDomain(ctx ?? getGlobalContext(), name).load();
2847
+ const context = ctx ?? getGlobalContext();
2848
+ return new AdkDomain(context, name).load();
2466
2849
  }
2467
2850
  static async exists(name, ctx) {
2468
2851
  try {
@@ -2480,7 +2863,8 @@ var AdkDomain = class AdkDomain extends AdkMainObject {
2480
2863
  * the domain properties (data type, field length, etc.).
2481
2864
  */
2482
2865
  static async create(name, description, packageName, options, ctx) {
2483
- const domain = new AdkDomain(ctx ?? getGlobalContext(), name.toUpperCase());
2866
+ const context = ctx ?? getGlobalContext();
2867
+ const domain = new AdkDomain(context, name.toUpperCase());
2484
2868
  domain.setData({
2485
2869
  name: name.toUpperCase(),
2486
2870
  type: "DOMA",
@@ -2500,7 +2884,8 @@ var AdkDomain = class AdkDomain extends AdkMainObject {
2500
2884
  return domain;
2501
2885
  }
2502
2886
  static async delete(name, options, ctx) {
2503
- await new AdkDomain(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2887
+ const context = ctx ?? getGlobalContext();
2888
+ await new AdkDomain(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2504
2889
  ...options?.transport && { corrNr: options.transport },
2505
2890
  ...options?.lockHandle && { lockHandle: options.lockHandle }
2506
2891
  });
@@ -2541,7 +2926,8 @@ var AdkDataElement = class AdkDataElement extends AdkMainObject {
2541
2926
  return this.ctx.client.adt.ddic.dataelements;
2542
2927
  }
2543
2928
  static async get(name, ctx) {
2544
- return new AdkDataElement(ctx ?? getGlobalContext(), name).load();
2929
+ const context = ctx ?? getGlobalContext();
2930
+ return new AdkDataElement(context, name).load();
2545
2931
  }
2546
2932
  static async exists(name, ctx) {
2547
2933
  try {
@@ -2555,7 +2941,8 @@ var AdkDataElement = class AdkDataElement extends AdkMainObject {
2555
2941
  * Create a new ABAP data element on SAP.
2556
2942
  */
2557
2943
  static async create(name, description, packageName, options, ctx) {
2558
- const dtel = new AdkDataElement(ctx ?? getGlobalContext(), name.toUpperCase());
2944
+ const context = ctx ?? getGlobalContext();
2945
+ const dtel = new AdkDataElement(context, name.toUpperCase());
2559
2946
  dtel.setData({
2560
2947
  name: name.toUpperCase(),
2561
2948
  type: "DTEL",
@@ -2575,7 +2962,8 @@ var AdkDataElement = class AdkDataElement extends AdkMainObject {
2575
2962
  return dtel;
2576
2963
  }
2577
2964
  static async delete(name, options, ctx) {
2578
- await new AdkDataElement(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2965
+ const context = ctx ?? getGlobalContext();
2966
+ await new AdkDataElement(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2579
2967
  ...options?.transport && { corrNr: options.transport },
2580
2968
  ...options?.lockHandle && { lockHandle: options.lockHandle }
2581
2969
  });
@@ -2634,7 +3022,8 @@ var AdkTable = class AdkTable extends AdkMainObject {
2634
3022
  return this.ctx.client.adt.ddic.tables;
2635
3023
  }
2636
3024
  static async get(name, ctx) {
2637
- return new AdkTable(ctx ?? getGlobalContext(), name).load();
3025
+ const context = ctx ?? getGlobalContext();
3026
+ return new AdkTable(context, name).load();
2638
3027
  }
2639
3028
  static async exists(name, ctx) {
2640
3029
  try {
@@ -2648,7 +3037,8 @@ var AdkTable = class AdkTable extends AdkMainObject {
2648
3037
  * Create a new ABAP database table on SAP.
2649
3038
  */
2650
3039
  static async create(name, description, packageName, options, ctx) {
2651
- const table = new AdkTable(ctx ?? getGlobalContext(), name.toUpperCase());
3040
+ const context = ctx ?? getGlobalContext();
3041
+ const table = new AdkTable(context, name.toUpperCase());
2652
3042
  table.setData({
2653
3043
  name: name.toUpperCase(),
2654
3044
  type: "TABL/DT",
@@ -2668,7 +3058,8 @@ var AdkTable = class AdkTable extends AdkMainObject {
2668
3058
  return table;
2669
3059
  }
2670
3060
  static async delete(name, options, ctx) {
2671
- await new AdkTable(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
3061
+ const context = ctx ?? getGlobalContext();
3062
+ await new AdkTable(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2672
3063
  ...options?.transport && { corrNr: options.transport },
2673
3064
  ...options?.lockHandle && { lockHandle: options.lockHandle }
2674
3065
  });
@@ -2699,7 +3090,8 @@ var AdkStructure = class AdkStructure extends AdkMainObject {
2699
3090
  return this.ctx.client.adt.ddic.structures;
2700
3091
  }
2701
3092
  static async get(name, ctx) {
2702
- return new AdkStructure(ctx ?? getGlobalContext(), name).load();
3093
+ const context = ctx ?? getGlobalContext();
3094
+ return new AdkStructure(context, name).load();
2703
3095
  }
2704
3096
  static async exists(name, ctx) {
2705
3097
  try {
@@ -2713,7 +3105,8 @@ var AdkStructure = class AdkStructure extends AdkMainObject {
2713
3105
  * Create a new ABAP structure on SAP.
2714
3106
  */
2715
3107
  static async create(name, description, packageName, options, ctx) {
2716
- const struct = new AdkStructure(ctx ?? getGlobalContext(), name.toUpperCase());
3108
+ const context = ctx ?? getGlobalContext();
3109
+ const struct = new AdkStructure(context, name.toUpperCase());
2717
3110
  struct.setData({
2718
3111
  name: name.toUpperCase(),
2719
3112
  type: "TABL/DS",
@@ -2733,7 +3126,8 @@ var AdkStructure = class AdkStructure extends AdkMainObject {
2733
3126
  return struct;
2734
3127
  }
2735
3128
  static async delete(name, options, ctx) {
2736
- await new AdkStructure(ctx ?? getGlobalContext(), name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
3129
+ const context = ctx ?? getGlobalContext();
3130
+ await new AdkStructure(context, name.toUpperCase()).crudContract.delete(name.toUpperCase(), {
2737
3131
  ...options?.transport && { corrNr: options.transport },
2738
3132
  ...options?.lockHandle && { lockHandle: options.lockHandle }
2739
3133
  });
@@ -2775,45 +3169,58 @@ var AdkTableType = class AdkTableType extends AdkMainObject {
2775
3169
  return this.ctx.client.adt.ddic.tabletypes;
2776
3170
  }
2777
3171
  static async get(name, ctx) {
2778
- return new AdkTableType(ctx ?? getGlobalContext(), name).load();
3172
+ const context = ctx ?? getGlobalContext();
3173
+ return new AdkTableType(context, name).load();
2779
3174
  }
2780
3175
  };
2781
3176
  registerObjectType("TTYP", TableType, AdkTableType, { endpoint: "ddic/tabletypes" });
2782
3177
 
2783
3178
  //#endregion
2784
- //#region src/objects/cds/ddl.model.ts
3179
+ //#region src/objects/cds/crud-source-object.ts
2785
3180
  /**
2786
- * DDL - CDS Data Definition Language Source (DDLS)
3181
+ * Shared implementation for standalone CDS/RAP source objects that support
3182
+ * full CRUD (get, source.main.get/put, post, delete) plus lock/unlock/activate.
2787
3183
  *
2788
- * ADK object for ABAP CDS Data Definition sources.
2789
- * These are source-based objects stored at:
2790
- * GET/PUT /sap/bc/adt/ddic/ddl/sources/<name>/source/main
2791
- *
2792
- * The metadata document is at:
2793
- * GET /sap/bc/adt/ddic/ddl/sources/<name>
2794
- *
2795
- * Lock/activate/create follow the same patterns as other source objects.
3184
+ * DDL, DCL, BDEF, and SRVD all follow the same lifecycle pattern:
3185
+ * create skeleton → PUT source → activate
3186
+ * This base eliminates the duplicated load/saveMainSource/lock/unlock/activate
3187
+ * boilerplate across those models.
2796
3188
  */
2797
- var AdkDdlSource = class AdkDdlSource {
3189
+ var AdkCrudSourceObject = class AdkCrudSourceObject {
2798
3190
  name;
2799
3191
  ctx;
3192
+ metadata;
2800
3193
  constructor(ctx, name) {
2801
3194
  this.ctx = ctx;
2802
3195
  this.name = name.toUpperCase();
2803
3196
  }
2804
3197
  get objectUri() {
2805
- return `/sap/bc/adt/ddic/ddl/sources/${encodeURIComponent(this.name.toLowerCase())}`;
3198
+ return `/sap/bc/adt/${this.endpoint}/${encodeURIComponent(this.name.toLowerCase())}`;
2806
3199
  }
2807
- /** Placeholder description — full metadata requires additional SAP fetch */
2808
3200
  get description() {
2809
- return this.name;
3201
+ const key = this.getMetadataKey();
3202
+ return (this.metadata?.[key])?.description ?? this.name;
2810
3203
  }
2811
- get contract() {
2812
- return this.ctx.client.adt.ddic.ddl.sources;
3204
+ get originalLanguage() {
3205
+ const key = this.getMetadataKey();
3206
+ return (this.metadata?.[key])?.masterLanguage;
3207
+ }
3208
+ get abapLanguageVersion() {
3209
+ const key = this.getMetadataKey();
3210
+ return (this.metadata?.[key])?.abapLanguageVersion;
3211
+ }
3212
+ get package() {
3213
+ const key = this.getMetadataKey();
3214
+ return (this.metadata?.[key])?.packageRef?.name;
2813
3215
  }
2814
3216
  async getSource() {
2815
3217
  return toText(await this.contract.source.main.get(this.name));
2816
3218
  }
3219
+ async load() {
3220
+ const [metadata] = await Promise.all([this.contract.get(this.name), this.getSource()]);
3221
+ this.metadata = metadata;
3222
+ return this;
3223
+ }
2817
3224
  async saveMainSource(source, options) {
2818
3225
  await this.contract.source.main.put(this.name, {
2819
3226
  ...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
@@ -2826,7 +3233,7 @@ var AdkDdlSource = class AdkDdlSource {
2826
3233
  return lockService.lock(this.objectUri, {
2827
3234
  transport,
2828
3235
  objectName: this.name,
2829
- objectType: "DDLS"
3236
+ objectType: this.objectType
2830
3237
  });
2831
3238
  }
2832
3239
  async unlock(lockHandle) {
@@ -2841,54 +3248,130 @@ var AdkDdlSource = class AdkDdlSource {
2841
3248
  }] } });
2842
3249
  return this;
2843
3250
  }
3251
+ static resolveContext(ctx) {
3252
+ return ctx ?? getGlobalContext();
3253
+ }
2844
3254
  /**
2845
- * Get a DDL source (does not fetch metadata, just returns handle)
3255
+ * Get a source object (validates it exists by fetching source).
3256
+ * Generic helper used by static `get()` on subclasses.
2846
3257
  */
2847
- static async get(name, ctx) {
2848
- const obj = new AdkDdlSource(ctx ?? getGlobalContext(), name);
3258
+ static async getSourceObject(name, ctx) {
3259
+ const context = AdkCrudSourceObject.resolveContext(ctx);
3260
+ const obj = new this(context, name);
2849
3261
  await obj.getSource();
2850
3262
  return obj;
2851
3263
  }
2852
- static async exists(name, ctx) {
3264
+ /**
3265
+ * Check if a source object exists.
3266
+ * Generic helper used by static `exists()` on subclasses.
3267
+ */
3268
+ static async sourceObjectExists(name, ctx) {
2853
3269
  try {
2854
- await AdkDdlSource.get(name, ctx);
3270
+ await this.getSourceObject(name, ctx);
2855
3271
  return true;
2856
3272
  } catch {
2857
3273
  return false;
2858
3274
  }
2859
3275
  }
2860
3276
  /**
2861
- * Create a new CDS DDL source on SAP
2862
- *
2863
- * POST /sap/bc/adt/ddic/ddl/sources?corrNr=...
2864
- * Body matches the `ddl:source` schema (extends abapsource:AbapSourceMainObject).
3277
+ * Shared skeleton-creation helper. Subclasses pass their contract's `post`
3278
+ * function and the root element name + type that their AFF schema expects.
2865
3279
  */
2866
- static async create(name, description, packageName, options, ctx) {
2867
- const context = ctx ?? getGlobalContext();
2868
- const nameU = name.toUpperCase();
2869
- const pkgU = packageName.toUpperCase();
2870
- await context.client.adt.ddic.ddl.sources.post(options?.transport ? { corrNr: options.transport } : {}, { source: {
3280
+ static async createSourceSkeleton(params, post) {
3281
+ const context = AdkCrudSourceObject.resolveContext(params.ctx);
3282
+ const nameU = params.name.toUpperCase();
3283
+ const pkgU = params.packageName.toUpperCase();
3284
+ await post(params.transport ? { corrNr: params.transport } : {}, { [params.rootKey]: {
2871
3285
  name: nameU,
2872
- description,
3286
+ ...params.objectTypeCode ? { type: params.objectTypeCode } : {},
3287
+ description: params.description,
2873
3288
  language: "EN",
2874
3289
  masterLanguage: "EN",
2875
- responsible: "$TMP",
3290
+ responsible: params.responsible ?? "$TMP",
2876
3291
  packageRef: {
2877
3292
  name: pkgU,
2878
3293
  type: "DEVC/K",
2879
3294
  uri: `/sap/bc/adt/packages/${pkgU.toLowerCase()}`
2880
3295
  }
2881
3296
  } });
2882
- return new AdkDdlSource(context, nameU);
3297
+ return new this(context, nameU);
2883
3298
  }
2884
- static async delete(name, options, ctx) {
2885
- await (ctx ?? getGlobalContext()).client.adt.ddic.ddl.sources.delete(name.toUpperCase(), {
3299
+ /**
3300
+ * Shared delete helper. Subclasses pass their contract's `delete` function.
3301
+ */
3302
+ static async deleteSource(name, options, deleteFn) {
3303
+ await deleteFn(name.toUpperCase(), {
2886
3304
  ...options?.transport ? { corrNr: options.transport } : {},
2887
3305
  ...options?.lockHandle ? { lockHandle: options.lockHandle } : {}
2888
3306
  });
2889
3307
  }
2890
3308
  };
2891
3309
 
3310
+ //#endregion
3311
+ //#region src/objects/cds/ddl.model.ts
3312
+ /**
3313
+ * DDL - CDS Data Definition Language Source (DDLS)
3314
+ *
3315
+ * ADK object for ABAP CDS Data Definition sources.
3316
+ * These are source-based objects stored at:
3317
+ * GET/PUT /sap/bc/adt/ddic/ddl/sources/<name>/source/main
3318
+ *
3319
+ * The metadata document is at:
3320
+ * GET /sap/bc/adt/ddic/ddl/sources/<name>
3321
+ *
3322
+ * Lock/activate/create follow the same patterns as other source objects.
3323
+ */
3324
+ var AdkDdlSource = class AdkDdlSource extends AdkCrudSourceObject {
3325
+ static kind = DdlSource;
3326
+ kind = AdkDdlSource.kind;
3327
+ objectType = "DDLS";
3328
+ endpoint = "ddic/ddl/sources";
3329
+ get contract() {
3330
+ return this.ctx.client.adt.ddic.ddl.sources;
3331
+ }
3332
+ getMetadataKey() {
3333
+ return "ddlSource";
3334
+ }
3335
+ get sourceOrigin() {
3336
+ return this.metadata?.ddlSource?.source_origin;
3337
+ }
3338
+ get sourceType() {
3339
+ return this.metadata?.ddlSource?.source_type;
3340
+ }
3341
+ /**
3342
+ * Get a DDL source (does not fetch metadata, just returns handle)
3343
+ */
3344
+ static async get(name, ctx) {
3345
+ return AdkCrudSourceObject.getSourceObject.call(this, name, ctx);
3346
+ }
3347
+ static async exists(name, ctx) {
3348
+ return AdkCrudSourceObject.sourceObjectExists.call(this, name, ctx);
3349
+ }
3350
+ /**
3351
+ * Create a new CDS DDL source on SAP
3352
+ *
3353
+ * POST /sap/bc/adt/ddic/ddl/sources?corrNr=...
3354
+ * Body matches the `ddl:source` schema (extends abapsource:AbapSourceMainObject).
3355
+ */
3356
+ static async create(name, description, packageName, options, ctx) {
3357
+ const context = ctx ?? getGlobalContext();
3358
+ return AdkCrudSourceObject.createSourceSkeleton.call(this, {
3359
+ name,
3360
+ description,
3361
+ packageName,
3362
+ transport: options?.transport,
3363
+ ctx,
3364
+ rootKey: "source",
3365
+ objectTypeCode: ""
3366
+ }, context.client.adt.ddic.ddl.sources.post.bind(context.client.adt.ddic.ddl.sources));
3367
+ }
3368
+ static async delete(name, options, ctx) {
3369
+ const context = ctx ?? getGlobalContext();
3370
+ return AdkCrudSourceObject.deleteSource(name, options, context.client.adt.ddic.ddl.sources.delete.bind(context.client.adt.ddic.ddl.sources));
3371
+ }
3372
+ };
3373
+ registerObjectType("DDLS", DdlSource, AdkDdlSource, { endpoint: "ddic/ddl/sources" });
3374
+
2892
3375
  //#endregion
2893
3376
  //#region src/objects/cds/dcl.model.ts
2894
3377
  /**
@@ -2903,94 +3386,304 @@ var AdkDdlSource = class AdkDdlSource {
2903
3386
  *
2904
3387
  * Lock/activate/create follow the same patterns as DDL sources.
2905
3388
  */
2906
- var AdkDclSource = class AdkDclSource {
3389
+ var AdkDclSource = class AdkDclSource extends AdkCrudSourceObject {
3390
+ static kind = DclSource;
3391
+ kind = AdkDclSource.kind;
3392
+ objectType = "DCLS";
3393
+ endpoint = "acm/dcl/sources";
3394
+ get contract() {
3395
+ return this.ctx.client.adt.ddic.dcl.sources;
3396
+ }
3397
+ getMetadataKey() {
3398
+ return "dclSource";
3399
+ }
3400
+ static async get(name, ctx) {
3401
+ return AdkCrudSourceObject.getSourceObject.call(this, name, ctx);
3402
+ }
3403
+ static async exists(name, ctx) {
3404
+ return AdkCrudSourceObject.sourceObjectExists.call(this, name, ctx);
3405
+ }
3406
+ /**
3407
+ * Create a new CDS DCL source on SAP
3408
+ */
3409
+ static async create(name, description, packageName, options, ctx) {
3410
+ const context = ctx ?? getGlobalContext();
3411
+ return AdkCrudSourceObject.createSourceSkeleton.call(this, {
3412
+ name,
3413
+ description,
3414
+ packageName,
3415
+ transport: options?.transport,
3416
+ ctx,
3417
+ rootKey: "source",
3418
+ objectTypeCode: ""
3419
+ }, context.client.adt.ddic.dcl.sources.post.bind(context.client.adt.ddic.dcl.sources));
3420
+ }
3421
+ static async delete(name, options, ctx) {
3422
+ const context = ctx ?? getGlobalContext();
3423
+ return AdkCrudSourceObject.deleteSource(name, options, context.client.adt.ddic.dcl.sources.delete.bind(context.client.adt.ddic.dcl.sources));
3424
+ }
3425
+ };
3426
+ registerObjectType("DCLS", DclSource, AdkDclSource, { endpoint: "acm/dcl/sources" });
3427
+
3428
+ //#endregion
3429
+ //#region src/objects/cds/ddlx.model.ts
3430
+ var AdkDdlExtension = class AdkDdlExtension {
3431
+ static kind = DdlExtension;
3432
+ kind = AdkDdlExtension.kind;
2907
3433
  name;
2908
3434
  ctx;
3435
+ metadata;
2909
3436
  constructor(ctx, name) {
2910
3437
  this.ctx = ctx;
2911
3438
  this.name = name.toUpperCase();
2912
3439
  }
2913
3440
  get objectUri() {
2914
- return `/sap/bc/adt/acm/dcl/sources/${encodeURIComponent(this.name.toLowerCase())}`;
3441
+ return `/sap/bc/adt/ddic/ddlx/sources/${encodeURIComponent(this.name.toLowerCase())}`;
2915
3442
  }
2916
- /** Placeholder description — full metadata requires additional SAP fetch */
2917
3443
  get description() {
2918
- return this.name;
3444
+ return this.metadata?.ddlxSource?.description ?? this.name;
3445
+ }
3446
+ get originalLanguage() {
3447
+ return this.metadata?.ddlxSource?.masterLanguage;
3448
+ }
3449
+ get abapLanguageVersion() {
3450
+ return this.metadata?.ddlxSource?.abapLanguageVersion;
3451
+ }
3452
+ get package() {
3453
+ return this.metadata?.ddlxSource?.packageRef?.name;
2919
3454
  }
2920
3455
  get contract() {
2921
- return this.ctx.client.adt.ddic.dcl.sources;
3456
+ return this.ctx.client.adt.ddic.ddlx.sources;
2922
3457
  }
2923
3458
  async getSource() {
2924
3459
  return toText(await this.contract.source.main.get(this.name));
2925
3460
  }
2926
- async saveMainSource(source, options) {
2927
- await this.contract.source.main.put(this.name, {
2928
- ...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
2929
- ...options?.transport ? { corrNr: options.transport } : {}
2930
- }, source);
3461
+ async load() {
3462
+ const [metadata] = await Promise.all([this.contract.get(this.name), this.getSource()]);
3463
+ this.metadata = metadata;
3464
+ return this;
2931
3465
  }
2932
- async lock(transport) {
2933
- const lockService = this.ctx.lockService;
2934
- if (!lockService) throw new Error("Lock not available: no lockService in context. Did you call initializeAdk()?");
2935
- return lockService.lock(this.objectUri, {
2936
- transport,
2937
- objectName: this.name,
2938
- objectType: "DCLS"
2939
- });
3466
+ };
3467
+ registerObjectType("DDLX", DdlExtension, AdkDdlExtension, { endpoint: "ddic/ddlx/sources" });
3468
+
3469
+ //#endregion
3470
+ //#region src/objects/cds/source-object.ts
3471
+ /** Minimal shared implementation for CDS source objects used by import. */
3472
+ var AdkCdsSourceObject = class {
3473
+ name;
3474
+ ctx;
3475
+ metadata;
3476
+ constructor(ctx, name) {
3477
+ this.ctx = ctx;
3478
+ this.name = name.toUpperCase();
2940
3479
  }
2941
- async unlock(lockHandle) {
2942
- const lockService = this.ctx.lockService;
2943
- if (!lockService) throw new Error("Unlock not available: no lockService in context. Did you call initializeAdk()?");
2944
- await lockService.unlock(this.objectUri, { lockHandle });
3480
+ get objectUri() {
3481
+ return `/sap/bc/adt/${this.endpoint}/${encodeURIComponent(this.name.toLowerCase())}`;
2945
3482
  }
2946
- async activate() {
2947
- await this.ctx.client.adt.activation.activate.post({}, { objectReferences: { objectReference: [{
2948
- uri: this.objectUri,
2949
- name: this.name
2950
- }] } });
3483
+ get description() {
3484
+ return this.metadata?.blueSource?.description ?? this.name;
3485
+ }
3486
+ get originalLanguage() {
3487
+ return this.metadata?.blueSource?.masterLanguage;
3488
+ }
3489
+ get abapLanguageVersion() {
3490
+ return this.metadata?.blueSource?.abapLanguageVersion;
3491
+ }
3492
+ get package() {
3493
+ return this.metadata?.blueSource?.packageRef?.name;
3494
+ }
3495
+ async getSource() {
3496
+ return toText(await this.contract.source.main.get(this.name));
3497
+ }
3498
+ async load() {
3499
+ const [metadata] = await Promise.all([this.contract.get(this.name), this.getSource()]);
3500
+ this.metadata = metadata;
2951
3501
  return this;
2952
3502
  }
2953
- static async get(name, ctx) {
2954
- const obj = new AdkDclSource(ctx ?? getGlobalContext(), name);
2955
- await obj.getSource();
2956
- return obj;
3503
+ };
3504
+
3505
+ //#endregion
3506
+ //#region src/objects/cds/dsfd.model.ts
3507
+ var AdkScalarFunctionDefinition = class AdkScalarFunctionDefinition extends AdkCdsSourceObject {
3508
+ static kind = ScalarFunctionDefinition;
3509
+ kind = AdkScalarFunctionDefinition.kind;
3510
+ endpoint = "ddic/dsfd/sources";
3511
+ constructor(ctx, name) {
3512
+ super(ctx, name);
2957
3513
  }
2958
- static async exists(name, ctx) {
2959
- try {
2960
- await AdkDclSource.get(name, ctx);
2961
- return true;
2962
- } catch {
2963
- return false;
2964
- }
3514
+ get contract() {
3515
+ return this.ctx.client.adt.ddic.dsfd.sources;
2965
3516
  }
2966
- /**
2967
- * Create a new CDS DCL source on SAP
2968
- */
2969
- static async create(name, description, packageName, options, ctx) {
2970
- const context = ctx ?? getGlobalContext();
2971
- const nameU = name.toUpperCase();
2972
- const pkgU = packageName.toUpperCase();
2973
- await context.client.adt.ddic.dcl.sources.post(options?.transport ? { corrNr: options.transport } : {}, { source: {
2974
- name: nameU,
2975
- description,
2976
- language: "EN",
2977
- masterLanguage: "EN",
2978
- responsible: "$TMP",
2979
- packageRef: {
2980
- name: pkgU,
2981
- type: "DEVC/K",
2982
- uri: `/sap/bc/adt/packages/${pkgU.toLowerCase()}`
2983
- }
2984
- } });
2985
- return new AdkDclSource(context, nameU);
3517
+ };
3518
+ registerObjectType("DSFD", ScalarFunctionDefinition, AdkScalarFunctionDefinition, { endpoint: "ddic/dsfd/sources" });
3519
+
3520
+ //#endregion
3521
+ //#region src/objects/cds/dsfi.model.ts
3522
+ var AdkScalarFunctionImplementation = class AdkScalarFunctionImplementation {
3523
+ static kind = ScalarFunctionImplementation;
3524
+ kind = AdkScalarFunctionImplementation.kind;
3525
+ name;
3526
+ ctx;
3527
+ definition;
3528
+ constructor(ctx, name) {
3529
+ this.ctx = ctx;
3530
+ this.name = name.toUpperCase();
2986
3531
  }
2987
- static async delete(name, options, ctx) {
2988
- await (ctx ?? getGlobalContext()).client.adt.ddic.dcl.sources.delete(name.toUpperCase(), {
2989
- ...options?.transport ? { corrNr: options.transport } : {},
2990
- ...options?.lockHandle ? { lockHandle: options.lockHandle } : {}
2991
- });
3532
+ get objectUri() {
3533
+ return `/sap/bc/adt/ddic/dsfi/${encodeURIComponent(this.name.toLowerCase())}`;
3534
+ }
3535
+ get contract() {
3536
+ return this.ctx.client.adt.ddic.dsfi;
3537
+ }
3538
+ async getSource() {
3539
+ return this.definition ?? this.contract.source.main.get(this.name);
3540
+ }
3541
+ async load() {
3542
+ const [, definition] = await Promise.all([this.contract.get(this.name), this.contract.source.main.get(this.name)]);
3543
+ this.definition = definition;
3544
+ return this;
3545
+ }
3546
+ };
3547
+ registerObjectType("DSFI", ScalarFunctionImplementation, AdkScalarFunctionImplementation, { endpoint: "ddic/dsfi" });
3548
+
3549
+ //#endregion
3550
+ //#region src/objects/cds/dteb.model.ts
3551
+ var AdkEntityBuffer = class AdkEntityBuffer extends AdkCdsSourceObject {
3552
+ static kind = EntityBuffer;
3553
+ kind = AdkEntityBuffer.kind;
3554
+ endpoint = "ddic/dteb/sources";
3555
+ constructor(ctx, name) {
3556
+ super(ctx, name);
3557
+ }
3558
+ get contract() {
3559
+ return this.ctx.client.adt.ddic.dteb.sources;
2992
3560
  }
2993
3561
  };
3562
+ registerObjectType("DTEB", EntityBuffer, AdkEntityBuffer, { endpoint: "ddic/dteb/sources" });
3563
+
3564
+ //#endregion
3565
+ //#region src/objects/cds/source-only-object.ts
3566
+ /**
3567
+ * CDS source object without a metadata schema in the connected ABAP release.
3568
+ *
3569
+ * DRAS and DRTY are absent from the reference system's repository search, so their source
3570
+ * endpoint is represented by the ADT DDIC naming convention and exercised
3571
+ * with official ABAP File Formats fixtures. The object is intentionally
3572
+ * source-first: import only needs the immutable source and a safe header.
3573
+ */
3574
+ var AdkSourceOnlyCdsObject = class {
3575
+ name;
3576
+ ctx;
3577
+ source;
3578
+ constructor(ctx, name) {
3579
+ this.ctx = ctx;
3580
+ this.name = name.toUpperCase();
3581
+ }
3582
+ get objectUri() {
3583
+ return `/sap/bc/adt/${this.endpoint}/${encodeURIComponent(this.name.toLowerCase())}`;
3584
+ }
3585
+ get description() {
3586
+ return this.name;
3587
+ }
3588
+ get originalLanguage() {
3589
+ return "EN";
3590
+ }
3591
+ async getSource() {
3592
+ this.source ??= await this.ctx.client.readTextBounded(`${this.objectUri}/source/main`, 5242880, { headers: { Accept: "text/plain" } });
3593
+ return this.source;
3594
+ }
3595
+ async load() {
3596
+ await this.getSource();
3597
+ return this;
3598
+ }
3599
+ };
3600
+
3601
+ //#endregion
3602
+ //#region src/objects/cds/dras.model.ts
3603
+ var AdkCdsAspect = class AdkCdsAspect extends AdkSourceOnlyCdsObject {
3604
+ static kind = CdsAspect;
3605
+ kind = AdkCdsAspect.kind;
3606
+ endpoint = "ddic/dras/sources";
3607
+ constructor(ctx, name) {
3608
+ super(ctx, name);
3609
+ }
3610
+ };
3611
+ registerObjectType("DRAS", CdsAspect, AdkCdsAspect, { endpoint: "ddic/dras/sources" });
3612
+
3613
+ //#endregion
3614
+ //#region src/objects/cds/drty.model.ts
3615
+ var AdkCdsType = class AdkCdsType extends AdkSourceOnlyCdsObject {
3616
+ static kind = CdsType;
3617
+ kind = AdkCdsType.kind;
3618
+ endpoint = "ddic/drty/sources";
3619
+ constructor(ctx, name) {
3620
+ super(ctx, name);
3621
+ }
3622
+ };
3623
+ registerObjectType("DRTY", CdsType, AdkCdsType, { endpoint: "ddic/drty/sources" });
3624
+
3625
+ //#endregion
3626
+ //#region src/objects/cds/dtdc.model.ts
3627
+ var AdkDynamicCache = class AdkDynamicCache extends AdkSourceOnlyCdsObject {
3628
+ static kind = DynamicCache;
3629
+ kind = AdkDynamicCache.kind;
3630
+ endpoint = "ddic/dtdc/sources";
3631
+ constructor(ctx, name) {
3632
+ super(ctx, name);
3633
+ }
3634
+ };
3635
+ registerObjectType("DTDC", DynamicCache, AdkDynamicCache, { endpoint: "ddic/dtdc/sources" });
3636
+
3637
+ //#endregion
3638
+ //#region src/objects/cds/dtix.model.ts
3639
+ var AdkTuningIndex = class AdkTuningIndex extends AdkSourceOnlyCdsObject {
3640
+ static kind = TuningIndex;
3641
+ kind = AdkTuningIndex.kind;
3642
+ endpoint = "ddic/dtix/sources";
3643
+ constructor(ctx, name) {
3644
+ super(ctx, name);
3645
+ }
3646
+ };
3647
+ registerObjectType("DTIX", TuningIndex, AdkTuningIndex, { endpoint: "ddic/dtix/sources" });
3648
+
3649
+ //#endregion
3650
+ //#region src/objects/cds/dtsc.model.ts
3651
+ var AdkStaticCache = class AdkStaticCache extends AdkSourceOnlyCdsObject {
3652
+ static kind = StaticCache;
3653
+ kind = AdkStaticCache.kind;
3654
+ endpoint = "ddic/dtsc/sources";
3655
+ constructor(ctx, name) {
3656
+ super(ctx, name);
3657
+ }
3658
+ };
3659
+ registerObjectType("DTSC", StaticCache, AdkStaticCache, { endpoint: "ddic/dtsc/sources" });
3660
+
3661
+ //#endregion
3662
+ //#region src/objects/cds/desd.model.ts
3663
+ var AdkExternalSchema = class AdkExternalSchema {
3664
+ static kind = ExternalSchema;
3665
+ kind = AdkExternalSchema.kind;
3666
+ name;
3667
+ ctx;
3668
+ constructor(ctx, name) {
3669
+ this.ctx = ctx;
3670
+ this.name = name.toUpperCase();
3671
+ }
3672
+ get objectUri() {
3673
+ return `/sap/bc/adt/ddic/desd/${encodeURIComponent(this.name.toLowerCase())}`;
3674
+ }
3675
+ get description() {
3676
+ return this.name;
3677
+ }
3678
+ get originalLanguage() {
3679
+ return "EN";
3680
+ }
3681
+ async load() {
3682
+ await this.ctx.client.readTextBounded(this.objectUri, 5242880, { headers: { Accept: "application/xml" } });
3683
+ return this;
3684
+ }
3685
+ };
3686
+ registerObjectType("DESD", ExternalSchema, AdkExternalSchema, { endpoint: "ddic/desd" });
2994
3687
 
2995
3688
  //#endregion
2996
3689
  //#region src/objects/repository/bdef/bdef.model.ts
@@ -3010,71 +3703,26 @@ var AdkDclSource = class AdkDclSource {
3010
3703
  * not a full AdkMainObject subclass) because BDEF metadata is source-driven
3011
3704
  * and the typical lifecycle is: create skeleton → PUT source → activate.
3012
3705
  */
3013
- var AdkBehaviorDefinition = class AdkBehaviorDefinition {
3706
+ var AdkBehaviorDefinition = class AdkBehaviorDefinition extends AdkCrudSourceObject {
3014
3707
  /** Static ADK kind marker — used by abapGit handler registry if needed. */
3015
- static kind = "BehaviorDefinition";
3708
+ static kind = BehaviorDefinition;
3016
3709
  kind = AdkBehaviorDefinition.kind;
3017
- name;
3018
- ctx;
3019
- constructor(ctx, name) {
3020
- this.ctx = ctx;
3021
- this.name = name.toUpperCase();
3022
- }
3023
- get objectUri() {
3024
- return `/sap/bc/adt/bo/behaviordefinitions/${encodeURIComponent(this.name.toLowerCase())}`;
3025
- }
3026
- /** Placeholder description — full metadata requires additional SAP fetch */
3027
- get description() {
3028
- return this.name;
3029
- }
3710
+ objectType = "BDEF";
3711
+ endpoint = "bo/behaviordefinitions";
3030
3712
  get contract() {
3031
3713
  return this.ctx.client.adt.bo.behaviordefinitions;
3032
3714
  }
3033
- async getSource() {
3034
- return toText(await this.contract.source.main.get(this.name));
3035
- }
3036
- async saveMainSource(source, options) {
3037
- await this.contract.source.main.put(this.name, {
3038
- ...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
3039
- ...options?.transport ? { corrNr: options.transport } : {}
3040
- }, source);
3041
- }
3042
- async lock(transport) {
3043
- const lockService = this.ctx.lockService;
3044
- if (!lockService) throw new Error("Lock not available: no lockService in context. Did you call initializeAdk()?");
3045
- return lockService.lock(this.objectUri, {
3046
- transport,
3047
- objectName: this.name,
3048
- objectType: "BDEF"
3049
- });
3050
- }
3051
- async unlock(lockHandle) {
3052
- const lockService = this.ctx.lockService;
3053
- if (!lockService) throw new Error("Unlock not available: no lockService in context. Did you call initializeAdk()?");
3054
- await lockService.unlock(this.objectUri, { lockHandle });
3055
- }
3056
- async activate() {
3057
- await this.ctx.client.adt.activation.activate.post({}, { objectReferences: { objectReference: [{
3058
- uri: this.objectUri,
3059
- name: this.name
3060
- }] } });
3061
- return this;
3715
+ getMetadataKey() {
3716
+ return "blueSource";
3062
3717
  }
3063
3718
  /**
3064
3719
  * Get a BDEF (validates it exists by fetching source).
3065
3720
  */
3066
3721
  static async get(name, ctx) {
3067
- const obj = new AdkBehaviorDefinition(ctx ?? getGlobalContext(), name);
3068
- await obj.getSource();
3069
- return obj;
3722
+ return AdkCrudSourceObject.getSourceObject.call(this, name, ctx);
3070
3723
  }
3071
3724
  static async exists(name, ctx) {
3072
- try {
3073
- await AdkBehaviorDefinition.get(name, ctx);
3074
- return true;
3075
- } catch {
3076
- return false;
3077
- }
3725
+ return AdkCrudSourceObject.sourceObjectExists.call(this, name, ctx);
3078
3726
  }
3079
3727
  /**
3080
3728
  * Create a new BDEF on SAP.
@@ -3085,30 +3733,23 @@ var AdkBehaviorDefinition = class AdkBehaviorDefinition {
3085
3733
  */
3086
3734
  static async create(name, description, packageName, options, ctx) {
3087
3735
  const context = ctx ?? getGlobalContext();
3088
- const nameU = name.toUpperCase();
3089
- const pkgU = packageName.toUpperCase();
3090
- await context.client.adt.bo.behaviordefinitions.post(options?.transport ? { corrNr: options.transport } : {}, { blueSource: {
3091
- name: nameU,
3092
- type: "BDEF/BDO",
3736
+ return AdkCrudSourceObject.createSourceSkeleton.call(this, {
3737
+ name,
3093
3738
  description,
3094
- language: "EN",
3095
- masterLanguage: "EN",
3096
- responsible: pkgU,
3097
- packageRef: {
3098
- name: pkgU,
3099
- type: "DEVC/K",
3100
- uri: `/sap/bc/adt/packages/${pkgU.toLowerCase()}`
3101
- }
3102
- } });
3103
- return new AdkBehaviorDefinition(context, nameU);
3739
+ packageName,
3740
+ transport: options?.transport,
3741
+ ctx,
3742
+ rootKey: "blueSource",
3743
+ objectTypeCode: "BDEF/BDO",
3744
+ responsible: packageName.toUpperCase()
3745
+ }, context.client.adt.bo.behaviordefinitions.post.bind(context.client.adt.bo.behaviordefinitions));
3104
3746
  }
3105
3747
  static async delete(name, options, ctx) {
3106
- await (ctx ?? getGlobalContext()).client.adt.bo.behaviordefinitions.delete(name.toUpperCase(), {
3107
- ...options?.transport ? { corrNr: options.transport } : {},
3108
- ...options?.lockHandle ? { lockHandle: options.lockHandle } : {}
3109
- });
3748
+ const context = ctx ?? getGlobalContext();
3749
+ return AdkCrudSourceObject.deleteSource(name, options, context.client.adt.bo.behaviordefinitions.delete.bind(context.client.adt.bo.behaviordefinitions));
3110
3750
  }
3111
3751
  };
3752
+ registerObjectType("BDEF", BehaviorDefinition, AdkBehaviorDefinition, { endpoint: "bo/behaviordefinitions" });
3112
3753
 
3113
3754
  //#endregion
3114
3755
  //#region src/objects/repository/badi/badi.model.ts
@@ -3134,6 +3775,8 @@ var AdkBadi = class AdkBadi {
3134
3775
  kind = AdkBadi.kind;
3135
3776
  name;
3136
3777
  ctx;
3778
+ _description;
3779
+ _package;
3137
3780
  constructor(ctx, name) {
3138
3781
  this.ctx = ctx;
3139
3782
  this.name = name.toUpperCase();
@@ -3142,18 +3785,27 @@ var AdkBadi = class AdkBadi {
3142
3785
  get objectUri() {
3143
3786
  return `/sap/bc/adt/enhancements/enhoxhh/${encodeURIComponent(this.name.toLowerCase())}`;
3144
3787
  }
3145
- /** Placeholder description — real metadata arrives via GET/objectstructure. */
3788
+ /** Description from the ENHO metadata, falling back to the object name. */
3146
3789
  get description() {
3147
- return this.name;
3790
+ return this._description || this.name;
3791
+ }
3792
+ /** Package name from the ENHO metadata. */
3793
+ get package() {
3794
+ return this._package || "";
3148
3795
  }
3149
3796
  get contract() {
3150
3797
  return this.ctx.client.adt.enhancements.enhoxhh;
3151
3798
  }
3152
3799
  async getMetadata() {
3153
- return await this.contract.get(this.name);
3800
+ const data = await this.contract.get(this.name);
3801
+ const impl = data?.enhancementImplementation ?? data;
3802
+ this._description = impl?.description ?? "";
3803
+ this._package = impl?.packageRef?.name ?? "";
3804
+ return data;
3154
3805
  }
3155
3806
  async getSource() {
3156
- return toText(await this.contract.source.main.get(this.name));
3807
+ const result = await this.contract.source.main.get(this.name);
3808
+ return toText(result);
3157
3809
  }
3158
3810
  async saveMainSource(source, options) {
3159
3811
  await this.contract.source.main.put(this.name, {
@@ -3184,7 +3836,8 @@ var AdkBadi = class AdkBadi {
3184
3836
  }
3185
3837
  /** Fetch a BAdI / ENHO, validating existence via a metadata GET. */
3186
3838
  static async get(name, ctx) {
3187
- const obj = new AdkBadi(ctx ?? getGlobalContext(), name);
3839
+ const context = ctx ?? getGlobalContext();
3840
+ const obj = new AdkBadi(context, name);
3188
3841
  await obj.getMetadata();
3189
3842
  return obj;
3190
3843
  }
@@ -3229,6 +3882,63 @@ var AdkBadi = class AdkBadi {
3229
3882
  }
3230
3883
  };
3231
3884
 
3885
+ //#endregion
3886
+ //#region src/objects/repository/classic-badi/classic-badi.model.ts
3887
+ /**
3888
+ * Classic BAdI — read-only ADK models for SXSD/XD and SXCI/XI metadata.
3889
+ *
3890
+ * Served via vit/wb Basic Object Properties:
3891
+ * GET /sap/bc/adt/vit/wb/object_type/sxsdxd/object_name/{name}
3892
+ * GET /sap/bc/adt/vit/wb/object_type/sxcixi/object_name/{name}
3893
+ */
3894
+ function isNotFound(error) {
3895
+ return typeof error === "object" && error !== null && error.status === 404;
3896
+ }
3897
+ var AdkClassicBadiBase = class {
3898
+ name;
3899
+ ctx;
3900
+ constructor(input) {
3901
+ this.ctx = input.ctx;
3902
+ this.name = input.name.toUpperCase();
3903
+ }
3904
+ static async get(input) {
3905
+ const context = input.ctx ?? getGlobalContext();
3906
+ const obj = new this({
3907
+ ctx: context,
3908
+ name: input.name
3909
+ });
3910
+ await obj.getMetadata();
3911
+ return obj;
3912
+ }
3913
+ static async exists(input) {
3914
+ try {
3915
+ await this.get(input);
3916
+ return true;
3917
+ } catch (error) {
3918
+ if (!isNotFound(error)) throw error;
3919
+ return false;
3920
+ }
3921
+ }
3922
+ };
3923
+ var AdkClassicBadiDefinition = class extends AdkClassicBadiBase {
3924
+ kind = "ClassicBadiDefinition";
3925
+ get objectUri() {
3926
+ return `/sap/bc/adt/vit/wb/object_type/sxsdxd/object_name/${encodeURIComponent(this.name.toLowerCase())}`;
3927
+ }
3928
+ async getMetadata() {
3929
+ return await this.ctx.client.adt.vit.wb.objectProperties.getDefinition(this.name);
3930
+ }
3931
+ };
3932
+ var AdkClassicBadiImplementation = class extends AdkClassicBadiBase {
3933
+ kind = "ClassicBadiImplementation";
3934
+ get objectUri() {
3935
+ return `/sap/bc/adt/vit/wb/object_type/sxcixi/object_name/${encodeURIComponent(this.name.toLowerCase())}`;
3936
+ }
3937
+ async getMetadata() {
3938
+ return await this.ctx.client.adt.vit.wb.objectProperties.getImplementation(this.name);
3939
+ }
3940
+ };
3941
+
3232
3942
  //#endregion
3233
3943
  //#region src/objects/repository/srvd/srvd.model.ts
3234
3944
  /**
@@ -3242,72 +3952,33 @@ var AdkBadi = class AdkBadi {
3242
3952
  * Lock/activate/create follow the same patterns as other source objects
3243
3953
  * (DDL, DCL, BDEF). Metadata envelope is the dedicated `srvd:source`
3244
3954
  * wrapper extending abapsource:AbapSourceMainObject (mirrors DDL).
3245
- */
3246
- var AdkServiceDefinition = class AdkServiceDefinition {
3247
- /** Static ADK kind marker — used by abapGit handler registry if needed. */
3248
- static kind = "ServiceDefinition";
3249
- kind = AdkServiceDefinition.kind;
3250
- name;
3251
- ctx;
3252
- constructor(ctx, name) {
3253
- this.ctx = ctx;
3254
- this.name = name.toUpperCase();
3255
- }
3256
- get objectUri() {
3257
- return `/sap/bc/adt/ddic/srvd/sources/${encodeURIComponent(this.name.toLowerCase())}`;
3258
- }
3259
- /** Placeholder description — full metadata requires additional SAP fetch */
3260
- get description() {
3261
- return this.name;
3262
- }
3263
- get contract() {
3264
- return this.ctx.client.adt.ddic.srvd.sources;
3265
- }
3266
- async getSource() {
3267
- return toText(await this.contract.source.main.get(this.name));
3268
- }
3269
- async saveMainSource(source, options) {
3270
- await this.contract.source.main.put(this.name, {
3271
- ...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
3272
- ...options?.transport ? { corrNr: options.transport } : {}
3273
- }, source);
3274
- }
3275
- async lock(transport) {
3276
- const lockService = this.ctx.lockService;
3277
- if (!lockService) throw new Error("Lock not available: no lockService in context. Did you call initializeAdk()?");
3278
- return lockService.lock(this.objectUri, {
3279
- transport,
3280
- objectName: this.name,
3281
- objectType: "SRVD"
3282
- });
3955
+ */
3956
+ var AdkServiceDefinition = class AdkServiceDefinition extends AdkCrudSourceObject {
3957
+ /** Static ADK kind marker — used by abapGit handler registry if needed. */
3958
+ static kind = ServiceDefinition;
3959
+ kind = AdkServiceDefinition.kind;
3960
+ objectType = "SRVD";
3961
+ endpoint = "ddic/srvd/sources";
3962
+ get contract() {
3963
+ return this.ctx.client.adt.ddic.srvd.sources;
3283
3964
  }
3284
- async unlock(lockHandle) {
3285
- const lockService = this.ctx.lockService;
3286
- if (!lockService) throw new Error("Unlock not available: no lockService in context. Did you call initializeAdk()?");
3287
- await lockService.unlock(this.objectUri, { lockHandle });
3965
+ getMetadataKey() {
3966
+ return "srvdSource";
3288
3967
  }
3289
- async activate() {
3290
- await this.ctx.client.adt.activation.activate.post({}, { objectReferences: { objectReference: [{
3291
- uri: this.objectUri,
3292
- name: this.name
3293
- }] } });
3294
- return this;
3968
+ get sourceOrigin() {
3969
+ return this.metadata?.srvdSource?.sourceOrigin;
3970
+ }
3971
+ get sourceType() {
3972
+ return this.metadata?.srvdSource?.srvdSourceType;
3295
3973
  }
3296
3974
  /**
3297
3975
  * Get a SRVD (validates it exists by fetching source).
3298
3976
  */
3299
3977
  static async get(name, ctx) {
3300
- const obj = new AdkServiceDefinition(ctx ?? getGlobalContext(), name);
3301
- await obj.getSource();
3302
- return obj;
3978
+ return AdkCrudSourceObject.getSourceObject.call(this, name, ctx);
3303
3979
  }
3304
3980
  static async exists(name, ctx) {
3305
- try {
3306
- await AdkServiceDefinition.get(name, ctx);
3307
- return true;
3308
- } catch {
3309
- return false;
3310
- }
3981
+ return AdkCrudSourceObject.sourceObjectExists.call(this, name, ctx);
3311
3982
  }
3312
3983
  /**
3313
3984
  * Create a new SRVD on SAP.
@@ -3318,30 +3989,23 @@ var AdkServiceDefinition = class AdkServiceDefinition {
3318
3989
  */
3319
3990
  static async create(name, description, packageName, options, ctx) {
3320
3991
  const context = ctx ?? getGlobalContext();
3321
- const nameU = name.toUpperCase();
3322
- const pkgU = packageName.toUpperCase();
3323
- await context.client.adt.ddic.srvd.sources.post(options?.transport ? { corrNr: options.transport } : {}, { source: {
3324
- name: nameU,
3325
- type: "SRVD/SRV",
3992
+ return AdkCrudSourceObject.createSourceSkeleton.call(this, {
3993
+ name,
3326
3994
  description,
3327
- language: "EN",
3328
- masterLanguage: "EN",
3329
- responsible: pkgU,
3330
- packageRef: {
3331
- name: pkgU,
3332
- type: "DEVC/K",
3333
- uri: `/sap/bc/adt/packages/${pkgU.toLowerCase()}`
3334
- }
3335
- } });
3336
- return new AdkServiceDefinition(context, nameU);
3995
+ packageName,
3996
+ transport: options?.transport,
3997
+ ctx,
3998
+ rootKey: "srvdSource",
3999
+ objectTypeCode: "SRVD/SRV",
4000
+ responsible: packageName.toUpperCase()
4001
+ }, context.client.adt.ddic.srvd.sources.post.bind(context.client.adt.ddic.srvd.sources));
3337
4002
  }
3338
4003
  static async delete(name, options, ctx) {
3339
- await (ctx ?? getGlobalContext()).client.adt.ddic.srvd.sources.delete(name.toUpperCase(), {
3340
- ...options?.transport ? { corrNr: options.transport } : {},
3341
- ...options?.lockHandle ? { lockHandle: options.lockHandle } : {}
3342
- });
4004
+ const context = ctx ?? getGlobalContext();
4005
+ return AdkCrudSourceObject.deleteSource(name, options, context.client.adt.ddic.srvd.sources.delete.bind(context.client.adt.ddic.srvd.sources));
3343
4006
  }
3344
4007
  };
4008
+ registerObjectType("SRVD", ServiceDefinition, AdkServiceDefinition, { endpoint: "ddic/srvd/sources" });
3345
4009
 
3346
4010
  //#endregion
3347
4011
  //#region src/objects/repository/srvb/srvb.model.ts
@@ -3363,7 +4027,7 @@ var AdkServiceDefinition = class AdkServiceDefinition {
3363
4027
  */
3364
4028
  var AdkServiceBinding = class AdkServiceBinding {
3365
4029
  /** Static ADK kind marker — used by abapGit handler registry if needed. */
3366
- static kind = "ServiceBinding";
4030
+ static kind = ServiceBinding;
3367
4031
  kind = AdkServiceBinding.kind;
3368
4032
  name;
3369
4033
  ctx;
@@ -3391,6 +4055,10 @@ var AdkServiceBinding = class AdkServiceBinding {
3391
4055
  async getSource() {
3392
4056
  return "";
3393
4057
  }
4058
+ async load() {
4059
+ await this.getMetadata();
4060
+ return this;
4061
+ }
3394
4062
  async lock(transport) {
3395
4063
  const lockService = this.ctx.lockService;
3396
4064
  if (!lockService) throw new Error("Lock not available: no lockService in context. Did you call initializeAdk()?");
@@ -3430,7 +4098,8 @@ var AdkServiceBinding = class AdkServiceBinding {
3430
4098
  * Get a SRVB (validates it exists by fetching metadata).
3431
4099
  */
3432
4100
  static async get(name, ctx) {
3433
- const obj = new AdkServiceBinding(ctx ?? getGlobalContext(), name);
4101
+ const context = ctx ?? getGlobalContext();
4102
+ const obj = new AdkServiceBinding(context, name);
3434
4103
  await obj.getMetadata();
3435
4104
  return obj;
3436
4105
  }
@@ -3474,12 +4143,15 @@ var AdkServiceBinding = class AdkServiceBinding {
3474
4143
  });
3475
4144
  }
3476
4145
  static async publish(name, ctx) {
3477
- await new AdkServiceBinding(ctx ?? getGlobalContext(), name).publish();
4146
+ const context = ctx ?? getGlobalContext();
4147
+ await new AdkServiceBinding(context, name).publish();
3478
4148
  }
3479
4149
  static async unpublish(name, ctx) {
3480
- await new AdkServiceBinding(ctx ?? getGlobalContext(), name).unpublish();
4150
+ const context = ctx ?? getGlobalContext();
4151
+ await new AdkServiceBinding(context, name).unpublish();
3481
4152
  }
3482
4153
  };
4154
+ registerObjectType("SRVB", ServiceBinding, AdkServiceBinding, { endpoint: "businessservices/bindings" });
3483
4155
 
3484
4156
  //#endregion
3485
4157
  //#region src/objects/cts/transport/transport-object.ts
@@ -3487,6 +4159,7 @@ var AdkServiceBinding = class AdkServiceBinding {
3487
4159
  * Transport Object - wrapper for ABAP objects in a transport
3488
4160
  */
3489
4161
  var AdkTransportObject = class {
4162
+ data;
3490
4163
  constructor(data) {
3491
4164
  this.data = data;
3492
4165
  }
@@ -3525,13 +4198,13 @@ var AdkTransportObject = class {
3525
4198
  };
3526
4199
 
3527
4200
  //#endregion
3528
- //#region \0@oxc-project+runtime@0.115.0/helpers/decorateMetadata.js
4201
+ //#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorateMetadata.js
3529
4202
  function __decorateMetadata(k, v) {
3530
4203
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3531
4204
  }
3532
4205
 
3533
4206
  //#endregion
3534
- //#region \0@oxc-project+runtime@0.115.0/helpers/decorate.js
4207
+ //#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorate.js
3535
4208
  function __decorate(decorators, target, key, desc) {
3536
4209
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3537
4210
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -3546,10 +4219,18 @@ const STATUS_TEXT = {
3546
4219
  R: "Released",
3547
4220
  N: "Not released"
3548
4221
  };
3549
- function asArray$1(val) {
4222
+ function asArray$2(val) {
3550
4223
  if (!val) return [];
3551
4224
  return Array.isArray(val) ? val : [val];
3552
4225
  }
4226
+ function transportResponseName(response) {
4227
+ if (response.object_type === "T") {
4228
+ const taskNumber = asArray$2(response.task)[0]?.number;
4229
+ if (taskNumber) return taskNumber;
4230
+ }
4231
+ if (response.name) return response.name;
4232
+ return response.request?.number || "";
4233
+ }
3553
4234
  let cachedConfigUri;
3554
4235
  async function getConfigUri(ctx) {
3555
4236
  if (cachedConfigUri) return cachedConfigUri;
@@ -3621,7 +4302,7 @@ var AdkTransportRequest = class AdkTransportRequest extends AdkObject {
3621
4302
  constructor(ctx, dataOrNumber) {
3622
4303
  if (typeof dataOrNumber === "string") super(ctx, dataOrNumber);
3623
4304
  else super(ctx, {
3624
- name: dataOrNumber.name || dataOrNumber.request?.number || "",
4305
+ name: transportResponseName(dataOrNumber),
3625
4306
  type: dataOrNumber.object_type === "T" ? "RQTQ" : "RQRQ",
3626
4307
  response: dataOrNumber
3627
4308
  });
@@ -3682,7 +4363,7 @@ var AdkTransportRequest = class AdkTransportRequest extends AdkObject {
3682
4363
  get tasks() {
3683
4364
  if (!this._tasks) {
3684
4365
  const taskData = this.itemData.task;
3685
- this._tasks = asArray$1(taskData).map((t) => {
4366
+ this._tasks = asArray$2(taskData).map((t) => {
3686
4367
  const { request, task: _existingTasks, ...rootProps } = this.response;
3687
4368
  const { task: _nestedTasks, ...requestWithoutTasks } = request || {};
3688
4369
  const taskResponse = {
@@ -3703,7 +4384,7 @@ var AdkTransportRequest = class AdkTransportRequest extends AdkObject {
3703
4384
  */
3704
4385
  get objects() {
3705
4386
  if (!this._objects) {
3706
- const directObjects = asArray$1(this.itemData.abap_object).map((o) => new AdkTransportObject(o));
4387
+ const directObjects = asArray$2(this.itemData.abap_object).map((o) => new AdkTransportObject(o));
3707
4388
  const taskObjects = this.tasks.flatMap((t) => t.objects);
3708
4389
  this._objects = [...directObjects, ...taskObjects];
3709
4390
  }
@@ -3711,9 +4392,26 @@ var AdkTransportRequest = class AdkTransportRequest extends AdkObject {
3711
4392
  }
3712
4393
  async release() {
3713
4394
  try {
3714
- await this.ctx.client.adt.cts.transportrequests.useraction.release(this.number, { root: { useraction: "release" } });
3715
- this.itemData.status = "R";
3716
- this.itemData.status_text = "Released";
4395
+ await this.ctx.client.fetch(`${this.objectUri}/newreleasejobs`, {
4396
+ method: "POST",
4397
+ headers: {
4398
+ "Content-Type": "application/vnd.sap.adt.transportorganizer.v1+xml",
4399
+ Accept: "application/vnd.sap.adt.transportorganizer.v1+xml"
4400
+ },
4401
+ body: ""
4402
+ });
4403
+ try {
4404
+ await this.load();
4405
+ } catch (reloadError) {
4406
+ return {
4407
+ success: false,
4408
+ message: `Released ${this.number} but failed to verify: ${reloadError instanceof Error ? reloadError.message : String(reloadError)}`
4409
+ };
4410
+ }
4411
+ if (this.status !== "R") return {
4412
+ success: false,
4413
+ message: `SAP did not release ${this.number} (status: ${this.statusText})`
4414
+ };
3717
4415
  return { success: true };
3718
4416
  } catch (error) {
3719
4417
  return {
@@ -3750,18 +4448,33 @@ var AdkTransportRequest = class AdkTransportRequest extends AdkObject {
3750
4448
  * @param recursive - When true, also reassign all modifiable tasks
3751
4449
  */
3752
4450
  async reassign(newOwner, recursive = false) {
3753
- await this.ctx.client.adt.cts.transportrequests.useraction.reassign(this.number, {
3754
- targetUser: newOwner,
3755
- recursive
3756
- }, { root: {
4451
+ await this.ctx.client.adt.cts.transportrequests.useraction.reassign(this.number, { targetUser: newOwner }, { root: {
4452
+ number: this.number,
3757
4453
  useraction: "changeowner",
3758
4454
  targetuser: newOwner
3759
4455
  } });
3760
- this.itemData.owner = newOwner;
4456
+ const verified = await AdkTransportRequest.get(this.number, this.ctx);
4457
+ if (verified.owner.toUpperCase() !== newOwner.toUpperCase()) throw new Error(`Transport ${this.number} owner verification failed: expected ${newOwner}, found ${verified.owner || "<empty>"}`);
4458
+ this.itemData.owner = verified.owner;
3761
4459
  if (recursive) {
3762
- for (const task of this.tasks) if (task.status !== "R") await task.reassign(newOwner);
4460
+ for (const task of this.tasks) if (task.status === "D") await task.reassign(newOwner);
3763
4461
  }
3764
4462
  }
4463
+ /** Create and verify a modifiable task under this request. */
4464
+ async addTask(owner) {
4465
+ if (this.itemType !== "request") throw new Error(`Transport ${this.number} is a task, not a request`);
4466
+ if (this.status !== "D") throw new Error(`Transport ${this.number} is not modifiable: expected status D, found ${this.status}`);
4467
+ const existingTasks = new Set(this.tasks.map((task) => task.number));
4468
+ const returnedNumber = (await this.ctx.client.adt.cts.transportrequests.useraction.addTask(this.number, { owner }, { root: { targetuser: owner } })).root.number;
4469
+ if (!returnedNumber) throw new Error(`Task creation verification failed for ${this.number}: SAP response did not contain a task number`);
4470
+ const verified = await AdkTransportRequest.get(this.number, this.ctx);
4471
+ const created = verified.tasks.find((task) => task.number === returnedNumber && !existingTasks.has(task.number) && task.owner.toUpperCase() === owner.toUpperCase());
4472
+ if (!created) throw new Error(`Task creation verification failed for ${this.number}: no new task owned by ${owner}`);
4473
+ if (created.status !== "D") throw new Error(`Task creation verification failed for ${created.number}: expected status D, found ${created.status}`);
4474
+ this._tasks = verified.tasks;
4475
+ this._objects = void 0;
4476
+ return created;
4477
+ }
3765
4478
  /**
3766
4479
  * Create a new transport request
3767
4480
  *
@@ -3795,7 +4508,7 @@ var AdkTransportRequest = class AdkTransportRequest extends AdkObject {
3795
4508
  /**
3796
4509
  * Get a transport request by number
3797
4510
  *
3798
- * @param number - Transport number (e.g., 'S0DK900001')
4511
+ * @param number - Transport number (e.g., 'TRLK900001')
3799
4512
  * @param ctx - Optional ADK context (uses global context if not provided)
3800
4513
  */
3801
4514
  static async get(number, ctx) {
@@ -3877,7 +4590,7 @@ var AdkTransportTask = class AdkTransportTask extends AdkTransportRequest {
3877
4590
  get objects() {
3878
4591
  if (!this._objects) {
3879
4592
  const taskData = this.itemData;
3880
- this._objects = asArray$1(taskData?.abap_object).map((o) => new AdkTransportObject(o));
4593
+ this._objects = asArray$2(taskData?.abap_object).map((o) => new AdkTransportObject(o));
3881
4594
  }
3882
4595
  return this._objects;
3883
4596
  }
@@ -3897,12 +4610,13 @@ var AdkTransportTask = class AdkTransportTask extends AdkTransportRequest {
3897
4610
  /**
3898
4611
  * Get a transport task by number
3899
4612
  *
3900
- * @param number - Task number (e.g., 'S0DK900001')
4613
+ * @param number - Task number (e.g., 'TRLK900001')
3901
4614
  * @param ctx - Optional ADK context (uses global context if not provided)
3902
4615
  */
3903
4616
  static async get(number, ctx) {
3904
4617
  const context = ctx ?? getGlobalContext();
3905
- return new AdkTransportTask(context, (await context.client.adt.cts.transportrequests.get(number)).root);
4618
+ const rawResponse = await context.client.adt.cts.transportrequests.get(number);
4619
+ return new AdkTransportTask(context, rawResponse.root);
3906
4620
  }
3907
4621
  };
3908
4622
 
@@ -3911,7 +4625,7 @@ var AdkTransportTask = class AdkTransportTask extends AdkTransportRequest {
3911
4625
  /**
3912
4626
  * Helper to normalize array/single value to array
3913
4627
  */
3914
- function asArray(val) {
4628
+ function asArray$1(val) {
3915
4629
  if (!val) return [];
3916
4630
  return Array.isArray(val) ? val : [val];
3917
4631
  }
@@ -3945,6 +4659,8 @@ function matchesSelector(obj, selector) {
3945
4659
  * Call load() to get the full ADK object.
3946
4660
  */
3947
4661
  var AdkTransportObjectRef = class {
4662
+ ctx;
4663
+ data;
3948
4664
  constructor(ctx, data) {
3949
4665
  this.ctx = ctx;
3950
4666
  this.data = data;
@@ -3997,7 +4713,7 @@ var AdkTransportObjectRef = class {
3997
4713
  * @returns The loaded ADK object, or undefined if type not supported
3998
4714
  */
3999
4715
  async load() {
4000
- const { createAdk } = await import("./factory-DtyrTGlN.mjs").then((n) => n.i);
4716
+ const { createAdk } = await Promise.resolve().then(() => factory_exports);
4001
4717
  const adk = createAdk(this.ctx.client);
4002
4718
  try {
4003
4719
  const obj = adk.get(this.name, this.type);
@@ -4016,6 +4732,8 @@ var AdkTransportObjectRef = class {
4016
4732
  * Transport task reference
4017
4733
  */
4018
4734
  var AdkTransportTaskRef = class {
4735
+ ctx;
4736
+ data;
4019
4737
  constructor(ctx, data) {
4020
4738
  this.ctx = ctx;
4021
4739
  this.data = data;
@@ -4037,7 +4755,7 @@ var AdkTransportTaskRef = class {
4037
4755
  }
4038
4756
  /** Objects in this task */
4039
4757
  get objects() {
4040
- return asArray(this.data.abap_object).map((obj) => new AdkTransportObjectRef(this.ctx, obj));
4758
+ return asArray$1(this.data.abap_object).map((obj) => new AdkTransportObjectRef(this.ctx, obj));
4041
4759
  }
4042
4760
  };
4043
4761
  /**
@@ -4060,35 +4778,47 @@ var AdkTransportTaskRef = class {
4060
4778
  * ```
4061
4779
  */
4062
4780
  var AdkTransport = class AdkTransport {
4781
+ ctx;
4782
+ data;
4783
+ requestedNumber;
4063
4784
  _objects;
4064
4785
  _tasks;
4065
- constructor(ctx, data) {
4786
+ constructor(ctx, data, requestedNumber) {
4066
4787
  this.ctx = ctx;
4067
4788
  this.data = data;
4789
+ this.requestedNumber = requestedNumber;
4068
4790
  }
4069
4791
  /** Transport number */
4070
4792
  get number() {
4071
- return this.data.name ?? this.data.request?.number ?? "";
4793
+ if (this.data.object_type === "T") return asArray$1(this.data.task).find((candidate) => candidate.number?.toUpperCase() === this.requestedNumber)?.number ?? this.requestedNumber;
4794
+ return this.data.request?.number ?? this.data.name ?? this.requestedNumber;
4795
+ }
4796
+ get itemData() {
4797
+ if (this.data.object_type === "T") {
4798
+ const directTasks = asArray$1(this.data.task);
4799
+ return directTasks.find((task) => task.number?.toUpperCase() === this.requestedNumber) ?? directTasks[0] ?? this.data.request ?? {};
4800
+ }
4801
+ return this.data.request ?? {};
4072
4802
  }
4073
4803
  /** Transport description */
4074
4804
  get description() {
4075
- return this.data.request?.desc ?? "";
4805
+ return this.itemData.desc ?? "";
4076
4806
  }
4077
4807
  /** Transport owner */
4078
4808
  get owner() {
4079
- return this.data.request?.owner ?? "";
4809
+ return this.itemData.owner ?? "";
4080
4810
  }
4081
4811
  /** Transport status (D=Modifiable, R=Released) */
4082
4812
  get status() {
4083
- return this.data.request?.status ?? "";
4813
+ return this.itemData.status ?? "";
4084
4814
  }
4085
4815
  /** Transport status text */
4086
4816
  get statusText() {
4087
- return this.data.request?.status_text ?? "";
4817
+ return this.itemData.status_text ?? "";
4088
4818
  }
4089
4819
  /** Transport target system */
4090
4820
  get target() {
4091
- return this.data.request?.target ?? "";
4821
+ return this.itemData.target ?? "";
4092
4822
  }
4093
4823
  /** Object type (K=Request, T=Task) */
4094
4824
  get objectType() {
@@ -4097,9 +4827,10 @@ var AdkTransport = class AdkTransport {
4097
4827
  /** Tasks belonging to this transport */
4098
4828
  get tasks() {
4099
4829
  if (!this._tasks) {
4100
- const requestTasks = asArray(this.data.request?.task);
4101
- const rootTasks = asArray(this.data.task);
4102
- this._tasks = [...requestTasks, ...rootTasks].map((t) => new AdkTransportTaskRef(this.ctx, t));
4830
+ const requestTasks = asArray$1(this.data.request?.task);
4831
+ const rootTasks = asArray$1(this.data.task);
4832
+ const allTasks = [...requestTasks, ...rootTasks];
4833
+ this._tasks = allTasks.map((t) => new AdkTransportTaskRef(this.ctx, t));
4103
4834
  }
4104
4835
  return this._tasks;
4105
4836
  }
@@ -4125,8 +4856,8 @@ var AdkTransport = class AdkTransport {
4125
4856
  objects.push(new AdkTransportObjectRef(this.ctx, obj));
4126
4857
  }
4127
4858
  };
4128
- for (const obj of asArray(this.data.request?.abap_object)) addObject(obj);
4129
- for (const obj of asArray(this.data.request?.all_objects?.abap_object)) addObject(obj);
4859
+ for (const obj of asArray$1(this.data.request?.abap_object)) addObject(obj);
4860
+ for (const obj of asArray$1(this.data.request?.all_objects?.abap_object)) addObject(obj);
4130
4861
  for (const task of this.tasks) for (const objRef of task.objects) addObject(objRef.raw);
4131
4862
  return objects;
4132
4863
  }
@@ -4194,7 +4925,9 @@ var AdkTransport = class AdkTransport {
4194
4925
  */
4195
4926
  static async get(number, ctx) {
4196
4927
  const context = ctx ?? getGlobalContext();
4197
- return new AdkTransport(context, (await context.client.adt.cts.transportrequests.get(number)).root);
4928
+ const requestedNumber = number.trim().toUpperCase();
4929
+ const response = await context.client.adt.cts.transportrequests.get(requestedNumber);
4930
+ return new AdkTransport(context, response.root, requestedNumber);
4198
4931
  }
4199
4932
  /**
4200
4933
  * Load multiple transports and merge their objects into a single view.
@@ -4214,7 +4947,8 @@ var AdkTransport = class AdkTransport {
4214
4947
  * ```
4215
4948
  */
4216
4949
  static async merge(numbers, ctx) {
4217
- return new MergedTransportView(await Promise.all(numbers.map((n) => AdkTransport.get(n, ctx))));
4950
+ const transports = await Promise.all(numbers.map((n) => AdkTransport.get(n, ctx)));
4951
+ return new MergedTransportView(transports);
4218
4952
  }
4219
4953
  };
4220
4954
  function getFilteredObjects(transport, selector) {
@@ -4226,6 +4960,31 @@ function addResolvedObject(object, sourceTransport, objects, sourceTransportMap,
4226
4960
  objects.push(object);
4227
4961
  sourceTransportMap.set(object.key, sourceTransport);
4228
4962
  }
4963
+ function getTransportObjectKey(object) {
4964
+ return `${object.pgmid ?? ""}/${object.type ?? ""}/${object.name ?? ""}`;
4965
+ }
4966
+ function getConcreteSourceTransportMap(transport, requestedNumber) {
4967
+ const sourceTransportMap = /* @__PURE__ */ new Map();
4968
+ const data = transport.raw;
4969
+ const requestNumber = data.request?.number || transport.number || requestedNumber;
4970
+ const addSource = (object, sourceTransport) => {
4971
+ const key = getTransportObjectKey(object);
4972
+ if (!sourceTransportMap.has(key)) sourceTransportMap.set(key, sourceTransport);
4973
+ };
4974
+ for (const object of asArray$1(data.request?.abap_object)) addSource(object, requestNumber);
4975
+ const tasks = [...asArray$1(data.request?.task), ...asArray$1(data.task)];
4976
+ for (const task of tasks) {
4977
+ const taskNumber = task.number || transport.number || requestedNumber;
4978
+ for (const object of asArray$1(task.abap_object)) addSource(object, taskNumber);
4979
+ }
4980
+ for (const object of asArray$1(data.request?.all_objects?.abap_object)) addSource(object, requestNumber);
4981
+ return sourceTransportMap;
4982
+ }
4983
+ function addScopeTransportNumber(number, scopeTransportNumbers, seenScopeTransportNumbers) {
4984
+ if (!number || seenScopeTransportNumbers.has(number)) return;
4985
+ seenScopeTransportNumbers.add(number);
4986
+ scopeTransportNumbers.push(number);
4987
+ }
4229
4988
  /**
4230
4989
  * Load and resolve objects from one or more transport numbers, with optional
4231
4990
  * selector-based filtering and deduplication across TRs.
@@ -4240,18 +4999,23 @@ function addResolvedObject(object, sourceTransport, objects, sourceTransportMap,
4240
4999
  async function resolveTransportObjects(transportNumbers, selector, ctx) {
4241
5000
  const objects = [];
4242
5001
  const sourceTransportMap = /* @__PURE__ */ new Map();
4243
- if (transportNumbers.length === 1) {
4244
- const primaryNumber = transportNumbers[0] ?? "";
4245
- const tr = await AdkTransport.get(primaryNumber, ctx);
4246
- for (const object of getFilteredObjects(tr, selector)) addResolvedObject(object, primaryNumber, objects, sourceTransportMap);
4247
- } else {
4248
- const transports = await Promise.all(transportNumbers.map((n) => AdkTransport.get(n, ctx)));
4249
- const seen = /* @__PURE__ */ new Set();
4250
- for (const tr of transports) for (const object of getFilteredObjects(tr, selector)) addResolvedObject(object, tr.number, objects, sourceTransportMap, seen);
5002
+ const scopeTransportNumbers = [];
5003
+ const seenScopeTransportNumbers = /* @__PURE__ */ new Set();
5004
+ const transports = await Promise.all(transportNumbers.map((number) => AdkTransport.get(number, ctx)));
5005
+ const seenObjectKeys = /* @__PURE__ */ new Set();
5006
+ for (const [index, transport] of transports.entries()) {
5007
+ const requestedNumber = transportNumbers[index] ?? "";
5008
+ const transportNumber = transport.number || requestedNumber;
5009
+ addScopeTransportNumber(transportNumber, scopeTransportNumbers, seenScopeTransportNumbers);
5010
+ addScopeTransportNumber(transport.raw.request?.number ?? "", scopeTransportNumbers, seenScopeTransportNumbers);
5011
+ for (const task of transport.tasks) addScopeTransportNumber(task.number, scopeTransportNumbers, seenScopeTransportNumbers);
5012
+ const concreteSources = getConcreteSourceTransportMap(transport, requestedNumber);
5013
+ for (const object of getFilteredObjects(transport, selector)) addResolvedObject(object, concreteSources.get(object.key) ?? transportNumber, objects, sourceTransportMap, seenObjectKeys);
4251
5014
  }
4252
5015
  return {
4253
5016
  objects,
4254
- sourceTransportMap
5017
+ sourceTransportMap,
5018
+ scopeTransportNumbers
4255
5019
  };
4256
5020
  }
4257
5021
  /**
@@ -4291,10 +5055,743 @@ var MergedTransportView = class MergedTransportView {
4291
5055
  * @param ctx - Optional ADK context
4292
5056
  */
4293
5057
  static async create(numbers, ctx) {
4294
- return new MergedTransportView(await Promise.all(numbers.map((n) => AdkTransport.get(n, ctx))));
5058
+ const transports = await Promise.all(numbers.map((n) => AdkTransport.get(n, ctx)));
5059
+ return new MergedTransportView(transports);
5060
+ }
5061
+ };
5062
+
5063
+ //#endregion
5064
+ //#region src/factory.ts
5065
+ var factory_exports = /* @__PURE__ */ __exportAll({
5066
+ AdkGenericObject: () => AdkGenericObject,
5067
+ createAdk: () => createAdk,
5068
+ createAdkFactory: () => createAdkFactory,
5069
+ parseXmlIdentity: () => parseXmlIdentity
5070
+ });
5071
+ /** Pattern to extract adtcore:type from XML */
5072
+ const TYPE_PATTERN = /adtcore:type="([^"]+)"/;
5073
+ /** Pattern to extract adtcore:name from XML */
5074
+ const NAME_PATTERN = /adtcore:name="([^"]+)"/;
5075
+ /**
5076
+ * Extract ADT type and name from XML
5077
+ *
5078
+ * Relies on adtcore:type and adtcore:name attributes which are
5079
+ * the standard identifiers in ADT XML responses.
5080
+ *
5081
+ * @param xml - XML string from ADT response
5082
+ * @returns Extracted type and name, or undefined if not found
5083
+ */
5084
+ function parseXmlIdentity(xml) {
5085
+ const typeMatch = xml.match(TYPE_PATTERN);
5086
+ const nameMatch = xml.match(NAME_PATTERN);
5087
+ if (typeMatch && nameMatch) return {
5088
+ type: typeMatch[1],
5089
+ name: nameMatch[1]
5090
+ };
5091
+ }
5092
+ /**
5093
+ * Generic ADK object for unregistered types
5094
+ *
5095
+ * Provides core functionality (adtcore attributes, links)
5096
+ * without type-specific features.
5097
+ */
5098
+ var AdkGenericObject = class {
5099
+ adtType;
5100
+ adtMainType;
5101
+ adtSubType;
5102
+ ctx;
5103
+ _name;
5104
+ _data;
5105
+ constructor(ctx, name, adtType) {
5106
+ this.ctx = ctx;
5107
+ this._name = name;
5108
+ const parsed = parseAdtType(adtType);
5109
+ this.adtType = parsed.full;
5110
+ this.adtMainType = parsed.main;
5111
+ this.adtSubType = parsed.sub;
5112
+ }
5113
+ get name() {
5114
+ return this._name;
5115
+ }
5116
+ get type() {
5117
+ return this.adtType;
5118
+ }
5119
+ /** Check if data is loaded */
5120
+ get isLoaded() {
5121
+ return this._data !== void 0;
5122
+ }
5123
+ /** Get raw data (if loaded) */
5124
+ get data() {
5125
+ return this._data;
5126
+ }
5127
+ /** Set data (for manual population) */
5128
+ setData(data) {
5129
+ this._data = data;
5130
+ }
5131
+ };
5132
+ /**
5133
+ * Create ADK factory
5134
+ *
5135
+ * @param ctx - ADK context with services
5136
+ * @returns Factory instance
5137
+ */
5138
+ function createAdkFactory(ctx) {
5139
+ return {
5140
+ ctx,
5141
+ get(name, adtType) {
5142
+ const entry = resolveType(adtType);
5143
+ if (entry) return new entry.constructor(ctx, name);
5144
+ return new AdkGenericObject(ctx, name, adtType);
5145
+ },
5146
+ getWithData(data, adtType) {
5147
+ const entry = resolveType(adtType);
5148
+ if (entry) return new entry.constructor(ctx, data);
5149
+ const obj = new AdkGenericObject(ctx, data.name ?? "", adtType);
5150
+ obj.setData(data);
5151
+ return obj;
5152
+ },
5153
+ byKind(kind, name) {
5154
+ const entry = resolveKind(kind);
5155
+ if (!entry) throw new Error(`No constructor registered for kind: ${kind}`);
5156
+ return new entry.constructor(ctx, name);
5157
+ },
5158
+ fromXml(xml) {
5159
+ const identity = parseXmlIdentity(xml);
5160
+ if (!identity) return;
5161
+ return this.get(identity.name, identity.type);
5162
+ },
5163
+ create(adtType) {
5164
+ return this.get("", adtType);
5165
+ }
5166
+ };
5167
+ }
5168
+ /**
5169
+ * Create ADK factory from ADT client
5170
+ *
5171
+ * Builds context from client and returns factory.
5172
+ * This is the main entry point for most users.
5173
+ *
5174
+ * @example
5175
+ * import { createAdtClient } from '@abapify/adt-client';
5176
+ * import { createAdk } from '@abapify/adk';
5177
+ *
5178
+ * const client = createAdtClient({ ... });
5179
+ * const adk = createAdk(client);
5180
+ *
5181
+ * const cls = adk.get('ZCL_TEST', 'CLAS');
5182
+ * await cls.load();
5183
+ */
5184
+ function createAdk(client) {
5185
+ return createAdkFactory({ client });
5186
+ }
5187
+
5188
+ //#endregion
5189
+ //#region src/transport-source-manifest.ts
5190
+ /** Stable public failure for errors that occur before a component result exists. */
5191
+ var ObjectSourceHistoryError = class extends Error {
5192
+ code;
5193
+ object;
5194
+ name = "ObjectSourceHistoryError";
5195
+ constructor(code, message, object) {
5196
+ super(message);
5197
+ this.code = code;
5198
+ this.object = object;
4295
5199
  }
4296
5200
  };
5201
+ const VERSIONS_RELATION = "http://www.sap.com/adt/relations/versions";
5202
+ const DEFAULT_CONCURRENCY = 4;
5203
+ const MAX_CONCURRENCY = 32;
5204
+ const RELATIVE_URI_TRAVERSAL = /(?:^|\/)(?:\.{1,2}|%2e(?:%2e)?)(?:\/|$)/i;
5205
+ const NON_SOURCE_CTS_OBJECT_KEYS = /* @__PURE__ */ new Set(["R3TR/SUSK"]);
5206
+ function asRecord(value) {
5207
+ return value !== null && typeof value === "object" ? value : void 0;
5208
+ }
5209
+ function asArray(value) {
5210
+ if (value === void 0 || value === null) return [];
5211
+ return Array.isArray(value) ? value : [value];
5212
+ }
5213
+ function nonEmptyString(value) {
5214
+ return typeof value === "string" && value.length > 0 ? value : void 0;
5215
+ }
5216
+ function uniqueStable(values) {
5217
+ const seen = /* @__PURE__ */ new Set();
5218
+ const result = [];
5219
+ for (const value of values) {
5220
+ const normalized = value.trim().toUpperCase();
5221
+ if (!normalized || seen.has(normalized)) continue;
5222
+ seen.add(normalized);
5223
+ result.push(normalized);
5224
+ }
5225
+ return result;
5226
+ }
5227
+ function compareText(left, right) {
5228
+ if (left < right) return -1;
5229
+ if (left > right) return 1;
5230
+ return 0;
5231
+ }
5232
+ /**
5233
+ * Some CTS entries represent SAP-maintained configuration rather than
5234
+ * repository source. They have neither an ADK source model nor an abapGit
5235
+ * representation, so they must not participate in a source-boundary manifest.
5236
+ */
5237
+ function isNonSourceCtsObject(reference) {
5238
+ return NON_SOURCE_CTS_OBJECT_KEYS.has(`${reference.pgmid.trim().toUpperCase()}/${reference.type.trim().toUpperCase()}`);
5239
+ }
5240
+ function isUnsafeRelativeHref(href) {
5241
+ return href.startsWith("//") || href.includes("\\") || href.includes(":") || RELATIVE_URI_TRAVERSAL.test(href);
5242
+ }
5243
+ function resolveAdtRelativeUri(href, objectUri) {
5244
+ try {
5245
+ const safeObjectUri = assertAdtUri(objectUri);
5246
+ if (href.startsWith("/")) return assertAdtUri(href);
5247
+ if (isUnsafeRelativeHref(href)) return void 0;
5248
+ const directoryBase = safeObjectUri.endsWith("/") ? safeObjectUri : `${safeObjectUri}/`;
5249
+ const resolved = new URL(href, `https://adt.invalid${directoryBase}`);
5250
+ return assertAdtUri(`${resolved.pathname}${resolved.search}${resolved.hash}`);
5251
+ } catch {
5252
+ return;
5253
+ }
5254
+ }
5255
+ function runtimeLinks(value) {
5256
+ return [...asArray(value["link"]), ...asArray(value["links"])].map(asRecord).filter((link) => Boolean(link));
5257
+ }
5258
+ function discoverComponent(value, id, objectUri) {
5259
+ const sourceHref = nonEmptyString(value["sourceUri"]);
5260
+ if (!sourceHref) return void 0;
5261
+ const sourceUri = resolveAdtRelativeUri(sourceHref, objectUri);
5262
+ const versionsHref = runtimeLinks(value).filter((link) => link.rel === VERSIONS_RELATION).map((link) => nonEmptyString(link.href)).find((href) => Boolean(href));
5263
+ const versionsUri = versionsHref ? resolveAdtRelativeUri(versionsHref, objectUri) : void 0;
5264
+ if (!sourceUri) return {
5265
+ id,
5266
+ diagnostic: {
5267
+ code: "SOURCE_COMPONENT_URI_UNSAFE",
5268
+ message: "The source component exposes an unsafe ADT URI."
5269
+ }
5270
+ };
5271
+ if (versionsHref && !versionsUri) return {
5272
+ id,
5273
+ diagnostic: {
5274
+ code: "SOURCE_COMPONENT_URI_UNSAFE",
5275
+ message: "The source component exposes an unsafe ADT URI."
5276
+ }
5277
+ };
5278
+ return {
5279
+ id,
5280
+ sourceUri,
5281
+ ...versionsUri ? { versionsUri } : {}
5282
+ };
5283
+ }
5284
+ function discoverSourceComponents(metadata, objectUri) {
5285
+ const candidates = [];
5286
+ const root = discoverComponent(metadata, "main", objectUri);
5287
+ if (root) candidates.push(root);
5288
+ for (const [index, rawInclude] of asArray(metadata["include"]).entries()) {
5289
+ const include = asRecord(rawInclude);
5290
+ if (!include) continue;
5291
+ const component = discoverComponent(include, nonEmptyString(include["includeType"]) ?? nonEmptyString(include["name"]) ?? `include-${index + 1}`, objectUri);
5292
+ if (component) candidates.push(component);
5293
+ }
5294
+ candidates.sort((left, right) => compareText(left.id, right.id) || compareText(left.sourceUri ?? "", right.sourceUri ?? "") || compareText(left.versionsUri ?? "", right.versionsUri ?? ""));
5295
+ const seen = /* @__PURE__ */ new Set();
5296
+ return candidates.filter((candidate) => {
5297
+ const key = `${candidate.sourceUri ?? ""}\u0000${candidate.versionsUri ?? ""}`;
5298
+ if (seen.has(key)) return false;
5299
+ seen.add(key);
5300
+ return true;
5301
+ });
5302
+ }
5303
+ function loadedMetadata(loaded) {
5304
+ const object = asRecord(loaded);
5305
+ if (!object) return void 0;
5306
+ const dataSync = asRecord(object["dataSync"]);
5307
+ if (dataSync) return dataSync;
5308
+ return asRecord(object["data"]);
5309
+ }
5310
+ function packageNameFrom(metadata) {
5311
+ return nonEmptyString(asRecord(metadata["packageRef"])?.["name"]) ?? nonEmptyString(metadata["packageName"]);
5312
+ }
5313
+ function normalizeSourceHistoryIdentity(objectName, objectType) {
5314
+ const type = objectType.trim().toUpperCase();
5315
+ const requestedName = objectName.trim().toUpperCase();
5316
+ return {
5317
+ name: normalizeObjectName(requestedName, type)[0] ?? requestedName,
5318
+ type
5319
+ };
5320
+ }
5321
+ function ensureObjectLoadable(modelRecord, object) {
5322
+ const load = modelRecord?.["load"];
5323
+ if (typeof load !== "function") throw new ObjectSourceHistoryError("OBJECT_TYPE_UNSUPPORTED", "The repository object type has no loadable ADK model.", object);
5324
+ return load;
5325
+ }
5326
+ async function loadObjectModel(model, load, object) {
5327
+ try {
5328
+ await load.call(model);
5329
+ } catch {
5330
+ throw new ObjectSourceHistoryError("OBJECT_METADATA_LOAD_FAILED", "SAP ADT rejected repository object metadata retrieval.", object);
5331
+ }
5332
+ }
5333
+ function ensureObjectMetadata(model, object) {
5334
+ const modelRecord = asRecord(model);
5335
+ const metadata = loadedMetadata(model);
5336
+ if (!metadata) throw new ObjectSourceHistoryError("OBJECT_METADATA_UNAVAILABLE", "The loaded object has no usable ADT metadata identity.", object);
5337
+ const objectUri = nonEmptyString(modelRecord?.["objectUri"]);
5338
+ if (!objectUri) throw new ObjectSourceHistoryError("OBJECT_METADATA_UNAVAILABLE", "The loaded object has no usable ADT metadata identity.", object);
5339
+ if (!resolveAdtRelativeUri("", objectUri)) throw new ObjectSourceHistoryError("OBJECT_METADATA_UNAVAILABLE", "The loaded object has no usable ADT metadata identity.", object);
5340
+ return {
5341
+ metadata,
5342
+ objectUri
5343
+ };
5344
+ }
5345
+ async function discoverObjectSourceHistory(objectName, objectType, ctx, normalizeIdentity = true, functionGroupName) {
5346
+ const object = normalizeIdentity ? normalizeSourceHistoryIdentity(objectName, objectType) : {
5347
+ name: objectName,
5348
+ type: objectType
5349
+ };
5350
+ let model;
5351
+ if (object.type === "FUGR/FF" && functionGroupName) try {
5352
+ model = await AdkFunctionModule.get(functionGroupName, object.name, ctx);
5353
+ } catch {
5354
+ throw new ObjectSourceHistoryError("OBJECT_METADATA_LOAD_FAILED", "SAP ADT rejected repository object metadata retrieval.", object);
5355
+ }
5356
+ else {
5357
+ model = createAdkFactory(ctx).get(object.name, object.type);
5358
+ const load = ensureObjectLoadable(asRecord(model), object);
5359
+ await loadObjectModel(model, load, object);
5360
+ }
5361
+ const { metadata, objectUri } = ensureObjectMetadata(model, object);
5362
+ let packageName = packageNameFrom(metadata);
5363
+ if (!packageName && functionGroupName) {
5364
+ const fugrModel = createAdkFactory(ctx).get(functionGroupName, "FUGR");
5365
+ await loadObjectModel(fugrModel, ensureObjectLoadable(asRecord(fugrModel), {
5366
+ name: functionGroupName,
5367
+ type: "FUGR"
5368
+ }), {
5369
+ name: functionGroupName,
5370
+ type: "FUGR"
5371
+ });
5372
+ const fugrMetadata = loadedMetadata(fugrModel);
5373
+ if (fugrMetadata) packageName = packageNameFrom(fugrMetadata);
5374
+ }
5375
+ const normalizedObject = {
5376
+ ...object,
5377
+ ...packageName ? { packageName } : {}
5378
+ };
5379
+ const components = discoverSourceComponents(metadata, objectUri);
5380
+ if (components.length === 0) throw new ObjectSourceHistoryError("SOURCE_COMPONENTS_UNAVAILABLE", "The object metadata exposes no source component.", normalizedObject);
5381
+ return {
5382
+ object: normalizedObject,
5383
+ components
5384
+ };
5385
+ }
5386
+ function normalizeConcurrency(value) {
5387
+ if (value === void 0) return DEFAULT_CONCURRENCY;
5388
+ if (!Number.isFinite(value)) return DEFAULT_CONCURRENCY;
5389
+ return Math.max(1, Math.min(MAX_CONCURRENCY, Math.floor(value)));
5390
+ }
5391
+ async function mapOrdered(values, concurrency, worker) {
5392
+ const results = new Array(values.length);
5393
+ let nextIndex = 0;
5394
+ const workers = Array.from({ length: Math.min(concurrency, values.length) }, async () => {
5395
+ while (nextIndex < values.length) {
5396
+ const index = nextIndex;
5397
+ nextIndex += 1;
5398
+ const value = values[index];
5399
+ if (value !== void 0) results[index] = await worker(value);
5400
+ }
5401
+ });
5402
+ await Promise.all(workers);
5403
+ return results;
5404
+ }
5405
+ function unavailableEntry(object, component, sourceTransport, changeKind, diagnostic) {
5406
+ return {
5407
+ object,
5408
+ component,
5409
+ sourceTransport,
5410
+ changeKind,
5411
+ exact: false,
5412
+ diagnostic
5413
+ };
5414
+ }
5415
+ function selectedRangeDiagnostic(ordered, newestIndex, oldestIndex, scope) {
5416
+ for (const candidate of ordered.slice(newestIndex, oldestIndex + 1)) {
5417
+ if (candidate.transports.some((transport) => scope.has(transport.toUpperCase()))) continue;
5418
+ return candidate.transports.length === 0 ? {
5419
+ code: "SOURCE_HISTORY_PROVENANCE_MISSING",
5420
+ message: "A source version in the selected history range has no transport provenance."
5421
+ } : {
5422
+ code: "SOURCE_HISTORY_INTERVENING_VERSION",
5423
+ message: "An unrelated source version occurs between in-scope versions."
5424
+ };
5425
+ }
5426
+ }
5427
+ /**
5428
+ * Select immutable before/after references using SAP's observed feed ordinal.
5429
+ */
5430
+ function selectTransportSourceVersions(versions, scopeTransportNumbers, deleted = false) {
5431
+ const scope = new Set(scopeTransportNumbers.map((transport) => transport.toUpperCase()));
5432
+ const ordinals = versions.map((version) => version.ordinal);
5433
+ if (ordinals.some((ordinal) => !Number.isSafeInteger(ordinal) || ordinal < 0) || new Set(ordinals).size !== ordinals.length) return {
5434
+ changeKind: "ambiguous",
5435
+ exact: false,
5436
+ diagnostic: {
5437
+ code: "SOURCE_HISTORY_ORDER_INVALID",
5438
+ message: "Source version ordinals do not define a unique feed order."
5439
+ }
5440
+ };
5441
+ const ordered = [...versions].sort((left, right) => left.ordinal - right.ordinal);
5442
+ const inScope = ordered.map((candidate, index) => ({
5443
+ candidate,
5444
+ index
5445
+ })).filter(({ candidate }) => candidate.transports.some((transport) => scope.has(transport.toUpperCase())));
5446
+ if (deleted) {
5447
+ if (ordered.length === 0) return {
5448
+ changeKind: "unsupported",
5449
+ exact: false,
5450
+ diagnostic: {
5451
+ code: "DELETED_SOURCE_BASE_UNAVAILABLE",
5452
+ message: "The deleted component has no recoverable historical source."
5453
+ }
5454
+ };
5455
+ const oldestInScope = inScope.at(-1);
5456
+ if (!oldestInScope) return {
5457
+ changeKind: "ambiguous",
5458
+ exact: false,
5459
+ diagnostic: {
5460
+ code: "SOURCE_HISTORY_SCOPE_VERSION_MISSING",
5461
+ message: "No source version is attributed to the requested transport scope."
5462
+ }
5463
+ };
5464
+ const base = ordered[oldestInScope.index + 1];
5465
+ const rangeDiagnostic = selectedRangeDiagnostic(ordered, inScope[0].index, oldestInScope.index, scope);
5466
+ if (rangeDiagnostic) return {
5467
+ changeKind: "ambiguous",
5468
+ exact: false,
5469
+ ...base ? { base } : {},
5470
+ diagnostic: rangeDiagnostic
5471
+ };
5472
+ return base ? {
5473
+ changeKind: "deleted",
5474
+ exact: true,
5475
+ base
5476
+ } : {
5477
+ changeKind: "unsupported",
5478
+ exact: false,
5479
+ diagnostic: {
5480
+ code: "DELETED_SOURCE_BASE_UNAVAILABLE",
5481
+ message: "The deleted component has no recoverable historical source."
5482
+ }
5483
+ };
5484
+ }
5485
+ if (inScope.length === 0) return {
5486
+ changeKind: "ambiguous",
5487
+ exact: false,
5488
+ diagnostic: {
5489
+ code: "SOURCE_HISTORY_SCOPE_VERSION_MISSING",
5490
+ message: "No source version is attributed to the requested transport scope."
5491
+ }
5492
+ };
5493
+ const newest = inScope[0];
5494
+ const oldest = inScope.at(-1);
5495
+ if (!newest || !oldest) throw new Error("Unreachable source-history selection state.");
5496
+ const head = newest.candidate;
5497
+ const base = ordered[oldest.index + 1];
5498
+ const rangeDiagnostic = selectedRangeDiagnostic(ordered, newest.index, oldest.index, scope);
5499
+ if (rangeDiagnostic) return {
5500
+ changeKind: "ambiguous",
5501
+ exact: false,
5502
+ ...base ? { base } : {},
5503
+ head,
5504
+ diagnostic: rangeDiagnostic
5505
+ };
5506
+ return base ? {
5507
+ changeKind: "modified",
5508
+ exact: true,
5509
+ base,
5510
+ head
5511
+ } : {
5512
+ changeKind: "added",
5513
+ exact: true,
5514
+ head
5515
+ };
5516
+ }
5517
+ function repositoryNameFromUri(uri, type) {
5518
+ if (!uri) return void 0;
5519
+ const endpoint = getEndpointForType(type);
5520
+ if (!endpoint) return void 0;
5521
+ const prefix = `/sap/bc/adt/${endpoint}/`;
5522
+ if (!uri.startsWith(prefix)) return void 0;
5523
+ const encodedName = uri.slice(prefix.length).split("/")[0];
5524
+ if (!encodedName) return void 0;
5525
+ try {
5526
+ return decodeURIComponent(encodedName).trim().toUpperCase() || void 0;
5527
+ } catch {
5528
+ return;
5529
+ }
5530
+ }
5531
+ function resolveFuncGroupReference(reference, rawType) {
5532
+ if (rawType !== "FUNC") return void 0;
5533
+ const ownerName = repositoryNameFromUri(reference.uri, "FUGR");
5534
+ if (!ownerName) return void 0;
5535
+ return {
5536
+ pgmid: "R3TR",
5537
+ type: "FUGR",
5538
+ name: ownerName,
5539
+ isDeleted: false
5540
+ };
5541
+ }
5542
+ async function resolveFuncGroupBySearch(reference, context) {
5543
+ if (reference.pgmid.trim().toUpperCase() !== "LIMU" || reference.type.trim().toUpperCase() !== "FUNC" || reference.wbtype?.trim().toUpperCase().split("/")[0] !== "FUGR") return void 0;
5544
+ try {
5545
+ const result = await context.client.adt.repository.informationsystem.search.quickSearch({
5546
+ query: reference.name,
5547
+ maxResults: 10
5548
+ });
5549
+ const raw = (asRecord(result["objectReferences"]) ?? asRecord(result["mainObject"]))?.["objectReference"] ?? result["objectReference"];
5550
+ const ownerName = (Array.isArray(raw) ? raw : [raw]).map(asRecord).filter((item) => Boolean(item)).filter((item) => nonEmptyString(item["name"])?.toUpperCase() === reference.name.trim().toUpperCase()).map((item) => repositoryNameFromUri(nonEmptyString(item["uri"]), "FUGR")).find((name) => Boolean(name));
5551
+ return ownerName ? {
5552
+ pgmid: "R3TR",
5553
+ type: "FUGR/FF",
5554
+ name: reference.name.trim().toUpperCase(),
5555
+ functionGroupName: ownerName,
5556
+ isDeleted: reference.isDeleted
5557
+ } : void 0;
5558
+ } catch {
5559
+ return;
5560
+ }
5561
+ }
5562
+ function resolveLimuReference(reference, pgmid, rawType) {
5563
+ if (pgmid !== "LIMU") return void 0;
5564
+ const ownerType = reference.wbtype?.trim().toUpperCase();
5565
+ const ownerName = ownerType ? repositoryNameFromUri(reference.uri, ownerType) : void 0;
5566
+ if (ownerType && ownerName) return {
5567
+ pgmid: "R3TR",
5568
+ type: ownerType,
5569
+ name: ownerName,
5570
+ isDeleted: rawType === "REPS" && reference.isDeleted
5571
+ };
5572
+ if (rawType === "REPS") return {
5573
+ pgmid: "R3TR",
5574
+ type: "PROG",
5575
+ name: reference.name.trim().toUpperCase(),
5576
+ isDeleted: reference.isDeleted
5577
+ };
5578
+ }
5579
+ function fallbackReference(reference, pgmid, rawTypeFull) {
5580
+ return {
5581
+ pgmid,
5582
+ type: rawTypeFull,
5583
+ name: reference.name.trim().toUpperCase(),
5584
+ isDeleted: reference.isDeleted
5585
+ };
5586
+ }
5587
+ /** Resolve a CTS object to the repository object that owns its source. */
5588
+ async function repositoryObjectReference(reference, context) {
5589
+ const pgmid = reference.pgmid.trim().toUpperCase();
5590
+ const rawTypeFull = reference.type.trim().toUpperCase();
5591
+ const rawType = rawTypeFull.split("/")[0] ?? "";
5592
+ return resolveFuncGroupReference(reference, rawType) ?? await resolveFuncGroupBySearch(reference, context) ?? resolveLimuReference(reference, pgmid, rawType) ?? fallbackReference(reference, pgmid, rawTypeFull);
5593
+ }
5594
+ function selectorValues(value) {
5595
+ if (value === void 0) return [];
5596
+ return (Array.isArray(value) ? value : [value]).map((item) => item.trim().toUpperCase());
5597
+ }
5598
+ function selectorDimensionMatches(candidates, expected) {
5599
+ const values = selectorValues(expected);
5600
+ if (values.length === 0) return true;
5601
+ return values.some((value) => value === "*" || candidates.includes(value));
5602
+ }
5603
+ function manifestSelectorMatches(original, repository, selector) {
5604
+ if (!selector) return true;
5605
+ const repositoryType = repository.type.trim().toUpperCase();
5606
+ const repositoryMainType = repositoryType.split("/")[0] ?? "";
5607
+ return selectorDimensionMatches([original.objFunc.trim().toUpperCase()], selector.objFunc) && selectorDimensionMatches([original.pgmid.trim().toUpperCase(), repository.pgmid], selector.pgmid) && selectorDimensionMatches([
5608
+ original.type.trim().toUpperCase(),
5609
+ repositoryType,
5610
+ ...repositoryMainType && repositoryMainType !== repositoryType ? [repositoryMainType] : []
5611
+ ], selector.type);
5612
+ }
5613
+ function inventoryEntry(reference, sourceTransport) {
5614
+ const wbtype = reference.wbtype?.trim().toUpperCase();
5615
+ const uri = reference.uri?.trim();
5616
+ return {
5617
+ pgmid: reference.pgmid.trim().toUpperCase(),
5618
+ type: reference.type.trim().toUpperCase(),
5619
+ name: reference.name.trim().toUpperCase(),
5620
+ ...wbtype ? { wbtype } : {},
5621
+ ...uri ? { uri } : {},
5622
+ objFunc: reference.objFunc.trim().toUpperCase(),
5623
+ sourceTransport
5624
+ };
5625
+ }
5626
+ /**
5627
+ * CTS exposes a program's main source as the LIMU/REPS sub-object, while ADT
5628
+ * exposes the same source history through the repository PROG resource. Keep
5629
+ * the CTS key in the public manifest, but use the ADT model identity for
5630
+ * metadata and immutable-version discovery.
5631
+ */
5632
+ function sourceHistoryDiscoveryType(reference) {
5633
+ const pgmid = reference.pgmid.trim().toUpperCase();
5634
+ const type = reference.type.trim().toUpperCase().split("/")[0];
5635
+ return pgmid === "LIMU" && type === "REPS" ? "PROG" : reference.type;
5636
+ }
5637
+ async function buildObjectEntries(original, repository, sourceTransport, scopeTransportNumbers, ctx) {
5638
+ const baseIdentity = {
5639
+ pgmid: original.pgmid,
5640
+ type: original.type,
5641
+ name: original.name
5642
+ };
5643
+ const hasRepositoryOwner = repository.pgmid !== baseIdentity.pgmid || repository.type !== baseIdentity.type || repository.name !== baseIdentity.name;
5644
+ const withRepositoryOwner = (entry, packageName) => hasRepositoryOwner ? {
5645
+ ...entry,
5646
+ repositoryObject: {
5647
+ pgmid: repository.pgmid,
5648
+ type: repository.functionGroupName ? "FUGR" : repository.type,
5649
+ name: repository.functionGroupName ?? repository.name,
5650
+ ...packageName ? { packageName } : {}
5651
+ }
5652
+ } : entry;
5653
+ let discovery;
5654
+ try {
5655
+ discovery = await discoverObjectSourceHistory(repository.name, sourceHistoryDiscoveryType(repository), ctx, false, repository.functionGroupName);
5656
+ } catch (error) {
5657
+ if (!(error instanceof ObjectSourceHistoryError)) throw error;
5658
+ return [withRepositoryOwner(unavailableEntry({
5659
+ ...baseIdentity,
5660
+ ...error.object.packageName ? { packageName: error.object.packageName } : {}
5661
+ }, { id: "object" }, sourceTransport, "unsupported", {
5662
+ code: error.code,
5663
+ message: error.message
5664
+ }))];
5665
+ }
5666
+ const identity = {
5667
+ ...baseIdentity,
5668
+ ...discovery.object.packageName ? { packageName: discovery.object.packageName } : {}
5669
+ };
5670
+ const manifestComponents = repository.type === "FUGR/FF" ? discovery.components.map((component) => component.id === "main" ? {
5671
+ ...component,
5672
+ id: repository.name.toLowerCase()
5673
+ } : component) : discovery.components;
5674
+ const entries = [];
5675
+ for (const component of manifestComponents) {
5676
+ const publicComponent = {
5677
+ id: component.id,
5678
+ ...component.sourceUri ? { sourceUri: component.sourceUri } : {},
5679
+ ...component.versionsUri ? { versionsUri: component.versionsUri } : {}
5680
+ };
5681
+ if (component.diagnostic) {
5682
+ entries.push(withRepositoryOwner(unavailableEntry(identity, publicComponent, sourceTransport, "unsupported", component.diagnostic), discovery.object.packageName));
5683
+ continue;
5684
+ }
5685
+ if (!component.versionsUri) {
5686
+ entries.push(withRepositoryOwner(unavailableEntry(identity, publicComponent, sourceTransport, "unsupported", {
5687
+ code: "SOURCE_COMPONENT_VERSIONS_UNAVAILABLE",
5688
+ message: "The source component has no exact versions relation."
5689
+ }), discovery.object.packageName));
5690
+ continue;
5691
+ }
5692
+ let versions;
5693
+ try {
5694
+ versions = await ctx.client.services.sourceHistory.listVersions(component.versionsUri);
5695
+ } catch {
5696
+ entries.push(withRepositoryOwner(unavailableEntry(identity, publicComponent, sourceTransport, "failed", {
5697
+ code: "SOURCE_HISTORY_RETRIEVAL_FAILED",
5698
+ message: "SAP ADT rejected source-history metadata retrieval."
5699
+ }), discovery.object.packageName));
5700
+ continue;
5701
+ }
5702
+ const selection = selectTransportSourceVersions(versions, scopeTransportNumbers, repository.isDeleted);
5703
+ entries.push(withRepositoryOwner({
5704
+ object: identity,
5705
+ component: publicComponent,
5706
+ sourceTransport,
5707
+ ...selection
5708
+ }, discovery.object.packageName));
5709
+ }
5710
+ return entries;
5711
+ }
5712
+ /**
5713
+ * List immutable source-version metadata for every discovered object component.
5714
+ * Source bodies remain lazy and are never read by this operation.
5715
+ */
5716
+ async function listObjectSourceVersions(objectName, objectType, options = {}, ctx) {
5717
+ const context = ctx ?? getGlobalContext();
5718
+ const discovery = await discoverObjectSourceHistory(objectName, objectType, context);
5719
+ const requestedComponent = options.component?.trim().toUpperCase();
5720
+ const components = options.component !== void 0 ? discovery.components.filter((component) => component.id.toUpperCase() === requestedComponent) : discovery.components;
5721
+ if (components.length === 0) throw new ObjectSourceHistoryError("SOURCE_COMPONENT_NOT_FOUND", "The requested source component was not exposed by object metadata.", discovery.object);
5722
+ const results = [];
5723
+ for (const component of components) {
5724
+ const publicComponent = {
5725
+ id: component.id,
5726
+ ...component.sourceUri ? { sourceUri: component.sourceUri } : {},
5727
+ ...component.versionsUri ? { versionsUri: component.versionsUri } : {}
5728
+ };
5729
+ if (component.diagnostic) {
5730
+ results.push({
5731
+ ...publicComponent,
5732
+ diagnostic: component.diagnostic
5733
+ });
5734
+ continue;
5735
+ }
5736
+ if (!component.versionsUri) {
5737
+ results.push({
5738
+ ...publicComponent,
5739
+ diagnostic: {
5740
+ code: "SOURCE_COMPONENT_VERSIONS_UNAVAILABLE",
5741
+ message: "The source component has no exact versions relation."
5742
+ }
5743
+ });
5744
+ continue;
5745
+ }
5746
+ try {
5747
+ const versions = await context.client.services.sourceHistory.listVersions(component.versionsUri);
5748
+ results.push({
5749
+ ...publicComponent,
5750
+ versions
5751
+ });
5752
+ } catch {
5753
+ results.push({
5754
+ ...publicComponent,
5755
+ diagnostic: {
5756
+ code: "SOURCE_HISTORY_RETRIEVAL_FAILED",
5757
+ message: "SAP ADT rejected source-history metadata retrieval."
5758
+ }
5759
+ });
5760
+ }
5761
+ }
5762
+ return {
5763
+ object: discovery.object,
5764
+ components: results
5765
+ };
5766
+ }
5767
+ /**
5768
+ * Resolve transport objects and produce immutable source-history references.
5769
+ * Source bodies remain lazy and are never read while building the manifest.
5770
+ */
5771
+ async function buildTransportSourceManifest(requestedTransports, options = {}, ctx) {
5772
+ const context = ctx ?? getGlobalContext();
5773
+ const requested = uniqueStable(requestedTransports);
5774
+ const resolved = await resolveTransportObjects(requested, {}, context);
5775
+ const scopeTransports = uniqueStable([...requested, ...resolved.scopeTransportNumbers]);
5776
+ const inventory = resolved.objects.map((reference) => inventoryEntry(reference, resolved.sourceTransportMap.get(reference.key) ?? requested[0] ?? "")).sort((left, right) => compareText(left.sourceTransport, right.sourceTransport) || compareText(left.pgmid, right.pgmid) || compareText(left.type, right.type) || compareText(left.name, right.name));
5777
+ const seenRepositoryObjects = /* @__PURE__ */ new Set();
5778
+ return {
5779
+ requestedTransports: requested,
5780
+ scopeTransports,
5781
+ inventory,
5782
+ entries: (await mapOrdered((await mapOrdered(resolved.objects.filter((reference) => !isNonSourceCtsObject(reference)), normalizeConcurrency(options.concurrency), async (original) => ({
5783
+ original,
5784
+ repository: await repositoryObjectReference(original, context),
5785
+ sourceTransport: resolved.sourceTransportMap.get(original.key) ?? requested[0] ?? ""
5786
+ }))).filter(({ original, repository }) => manifestSelectorMatches(original, repository, options.selector)).filter(({ repository }) => {
5787
+ const key = `${repository.pgmid}/${repository.type}/${repository.name}`;
5788
+ if (seenRepositoryObjects.has(key)) return false;
5789
+ seenRepositoryObjects.add(key);
5790
+ return true;
5791
+ }).sort((left, right) => compareText(left.repository.pgmid, right.repository.pgmid) || compareText(left.repository.type, right.repository.type) || compareText(left.repository.name, right.repository.name)), normalizeConcurrency(options.concurrency), ({ original, repository, sourceTransport }) => buildObjectEntries(original, repository, sourceTransport, scopeTransports, context))).flat()
5792
+ };
5793
+ }
4297
5794
 
4298
5795
  //#endregion
4299
- export { ADT_TYPE_MAPPINGS, AdkBadi, AdkBehaviorDefinition, AdkClass, AdkDataElement, AdkDclSource, AdkDdlSource, AdkDomain, AdkFunctionGroup, AdkFunctionModule, AdkGenericObject, AdkInclude, AdkInterface, AdkMainObject, AdkObject, AdkObjectSet, AdkPackage, AdkProgram, AdkServiceBinding, AdkServiceDefinition, AdkStructure, AdkTable, AdkTableType, AdkTransport, AdkTransportRequest as AdkTransportItem, AdkTransportRequest, AdkTransportObject, AdkTransportObjectRef, AdkTransportTask, AdkTransportTaskRef, Class, DataElement, Domain, EnhancementSpot, FunctionGroup, FunctionModule, Include, Interface, MergedTransportView, MessageClass, Package, Program, Structure, Table, TableType, TransportRequest, TransportTask, clearConfigCache, createAdk, createAdkContract, createAdkFactory, createLockService, getEndpointForType, getGlobalContext, getKindForType, getMainType, getObjectRootUri, getObjectUri, getRegisteredKinds, getRegisteredTypes, getTypeForKind, initializeAdk, isAdkInitialized, isTypeRegistered, matchesSelector, normalizeObjectName, parseAdtType, parseXmlIdentity, registerObjectType, resetAdk, resolveKind, resolveTransportObjects, resolveType, tryGetGlobalContext };
5796
+ export { ADT_TYPE_MAPPINGS, AdkBadi, AdkBehaviorDefinition, AdkCdsAspect, AdkCdsType, AdkClass, AdkClassicBadiDefinition, AdkClassicBadiImplementation, AdkDataElement, AdkDclSource, AdkDdlExtension, AdkDdlSource, AdkDomain, AdkDynamicCache, AdkEntityBuffer, AdkExternalSchema, AdkFunctionGroup, AdkFunctionModule, AdkGenericObject, AdkInclude, AdkInterface, AdkMainObject, AdkObject, AdkObjectSet, AdkPackage, AdkPostCreateLockError, AdkProgram, AdkScalarFunctionDefinition, AdkScalarFunctionImplementation, AdkServiceBinding, AdkServiceDefinition, AdkStaticCache, AdkStructure, AdkTable, AdkTableType, AdkTransport, AdkTransportRequest as AdkTransportItem, AdkTransportRequest, AdkTransportObject, AdkTransportObjectRef, AdkTransportTask, AdkTransportTaskRef, AdkTuningIndex, BehaviorDefinition, CdsAspect, CdsType, Class, DataElement, DclSource, DdlExtension, DdlSource, Domain, DynamicCache, EnhancementSpot, EntityBuffer, ExternalSchema, FunctionGroup, FunctionModule, Include, Interface, MergedTransportView, MessageClass, ObjectSourceHistoryError, Package, Program, ScalarFunctionDefinition, ScalarFunctionImplementation, ServiceBinding, ServiceDefinition, StaticCache, Structure, Table, TableType, TransportRequest, TransportTask, TuningIndex, buildTransportSourceManifest, clearConfigCache, createAdk, createAdkContract, createAdkFactory, createLockService, getEndpointForType, getGlobalContext, getKindForType, getMainType, getObjectRootUri, getObjectUri, getRegisteredKinds, getRegisteredTypes, getTypeForKind, initializeAdk, isAdkInitialized, isTypeRegistered, listObjectSourceVersions, matchesSelector, normalizeObjectName, parseAdtType, parseXmlIdentity, registerObjectType, resetAdk, resolveKind, resolveTransportObjects, resolveType, selectTransportSourceVersions, tryGetGlobalContext };
4300
5797
  //# sourceMappingURL=index.mjs.map