@mcp-abap-adt/adt-backup 1.2.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +6 -0
  2. package/dist/lib/backup/readBasicMetadata.d.ts.map +1 -1
  3. package/dist/lib/backup/readBasicMetadata.js +7 -0
  4. package/dist/lib/backup/readMetadataXmlForType.d.ts +1 -1
  5. package/dist/lib/backup/readMetadataXmlForType.d.ts.map +1 -1
  6. package/dist/lib/backup/readMetadataXmlForType.js +11 -1
  7. package/dist/lib/backup/readSourceText.d.ts.map +1 -1
  8. package/dist/lib/backup/readSourceText.js +17 -0
  9. package/dist/lib/constants/typeOrder.d.ts.map +1 -1
  10. package/dist/lib/constants/typeOrder.js +2 -0
  11. package/dist/lib/dependencies/collectTreeDependencies.d.ts.map +1 -1
  12. package/dist/lib/dependencies/collectTreeDependencies.js +1 -0
  13. package/dist/lib/restore/analyzeDependencies.d.ts.map +1 -1
  14. package/dist/lib/restore/analyzeDependencies.js +6 -4
  15. package/dist/lib/restore/restoreObject.d.ts.map +1 -1
  16. package/dist/lib/restore/restoreObject.js +35 -0
  17. package/dist/lib/restore/restoreObjects.d.ts.map +1 -1
  18. package/dist/lib/restore/restoreObjects.js +2 -0
  19. package/dist/lib/restore/restoreTreeBackup.d.ts.map +1 -1
  20. package/dist/lib/restore/restoreTreeBackup.js +6 -1
  21. package/dist/lib/restore/restoreTreeNode.d.ts.map +1 -1
  22. package/dist/lib/restore/restoreTreeNode.js +32 -0
  23. package/dist/lib/tree/enrichTreeNode.d.ts.map +1 -1
  24. package/dist/lib/tree/enrichTreeNode.js +28 -2
  25. package/dist/lib/tree/getNodeFunctionGroupName.js +1 -1
  26. package/dist/lib/tree/getNodeObjectSpec.js +1 -1
  27. package/dist/lib/tree/isRestoreImplemented.d.ts.map +1 -1
  28. package/dist/lib/tree/isRestoreImplemented.js +2 -0
  29. package/dist/lib/tree/mapAdtTypeToSupported.d.ts.map +1 -1
  30. package/dist/lib/tree/mapAdtTypeToSupported.js +7 -0
  31. package/dist/lib/tree/readPayloadForType.d.ts.map +1 -1
  32. package/dist/lib/tree/readPayloadForType.js +2 -0
  33. package/dist/lib/types.d.ts +1 -1
  34. package/dist/lib/types.d.ts.map +1 -1
  35. package/dist/lib/utils/applyConfigName.d.ts.map +1 -1
  36. package/dist/lib/utils/applyConfigName.js +7 -0
  37. package/dist/lib/utils/detectTransformationType.d.ts +3 -0
  38. package/dist/lib/utils/detectTransformationType.d.ts.map +1 -0
  39. package/dist/lib/utils/detectTransformationType.js +9 -0
  40. package/dist/lib/utils/formatObjectSpec.js +1 -1
  41. package/dist/lib/utils/normalizeType.d.ts.map +1 -1
  42. package/dist/lib/utils/normalizeType.js +6 -0
  43. package/dist/lib/utils/objectId.js +1 -1
  44. package/dist/lib/utils/parseObjectSpec.d.ts.map +1 -1
  45. package/dist/lib/utils/parseObjectSpec.js +2 -2
  46. package/dist/lib/verify/findOtherType.d.ts.map +1 -1
  47. package/dist/lib/verify/findOtherType.js +1 -0
  48. package/dist/lib/xml/parseServiceBindingConfig.d.ts.map +1 -1
  49. package/dist/lib/xml/parseServiceBindingConfig.js +24 -5
  50. package/package.json +10 -10
package/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # @mcp-abap-adt/adt-backup
2
+ [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
2
3
 
3
4
  CLI for recursive ADT backups and restores using `@mcp-abap-adt/adt-clients`.
4
5
 
@@ -78,6 +79,7 @@ See `docs/roadmap.yaml` for per-object backup/restore status and the plan for re
78
79
  | `interface` | implemented | implemented | source |
79
80
  | `class` | implemented | implemented | source |
80
81
  | `program` | implemented | implemented | source |
82
+ | `transformation` | implemented | implemented | source |
81
83
  | `serviceDefinition` | implemented | implemented | source |
82
84
  | `serviceBinding` | implemented | implemented | metadata-xml |
83
85
  | `metadataExtension` | implemented | implemented | source |
@@ -89,6 +91,10 @@ See `docs/roadmap.yaml` for per-object backup/restore status and the plan for re
89
91
 
90
92
  > **Note**: Unit tests are stored as classes in backups. When restoring, they are created as test classes in the system.
91
93
 
94
+ > **Note**: For `transformation`, the subtype (`SimpleTransformation` for `XSLT/VT` vs `XSLTProgram` for `XSLT/ST`) is detected from the source header (`<?sap.transform simple?>`).
95
+
96
+ > **Note**: For `serviceBinding`, the publication state (`srvb:published`) is preserved in the backup and re-applied during restore — published bindings are re-published, unpublished bindings are unpublished.
97
+
92
98
  ## Smoke Checklist
93
99
 
94
100
  When your landscape is ready, use `docs/SMOKE_CHECKLIST.md` for a focused backup/restore/verify checklist.
@@ -1 +1 @@
1
- {"version":3,"file":"readBasicMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readBasicMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA0DzD"}
1
+ {"version":3,"file":"readBasicMetadata.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readBasicMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiEzD"}
@@ -26,6 +26,13 @@ async function readBasicMetadata(client, spec) {
26
26
  const xml = (0, responseToText_1.responseToText)(state.metadataResult);
27
27
  return xml ? (0, extractMetadata_1.extractMetadata)(xml) : {};
28
28
  }
29
+ case 'transformation': {
30
+ const state = await client
31
+ .getTransformation()
32
+ .readMetadata({ transformationName: spec.name });
33
+ const xml = (0, responseToText_1.responseToText)(state.metadataResult);
34
+ return xml ? (0, extractMetadata_1.extractMetadata)(xml) : {};
35
+ }
29
36
  case 'structure': {
30
37
  const state = await client
31
38
  .getStructure()
@@ -1,4 +1,4 @@
1
1
  import type { AdtClient } from '@mcp-abap-adt/adt-clients';
2
2
  import type { SupportedType } from '../types';
3
- export declare function readMetadataXmlForType(client: AdtClient, type: SupportedType, name: string, _functionGroupName?: string): Promise<string | null | undefined>;
3
+ export declare function readMetadataXmlForType(client: AdtClient, type: SupportedType, name: string, functionGroupName?: string): Promise<string | null | undefined>;
4
4
  //# sourceMappingURL=readMetadataXmlForType.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readMetadataXmlForType.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readMetadataXmlForType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CA0IpC"}
1
+ {"version":3,"file":"readMetadataXmlForType.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readMetadataXmlForType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAoJpC"}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.readMetadataXmlForType = readMetadataXmlForType;
4
4
  const responseToText_1 = require("../utils/responseToText");
5
- async function readMetadataXmlForType(client, type, name, _functionGroupName) {
5
+ async function readMetadataXmlForType(client, type, name, functionGroupName) {
6
6
  try {
7
7
  let result;
8
8
  switch (type) {
@@ -105,6 +105,16 @@ async function readMetadataXmlForType(client, type, name, _functionGroupName) {
105
105
  result = (0, responseToText_1.responseToText)(state.metadataResult);
106
106
  break;
107
107
  }
108
+ case 'functionInclude': {
109
+ if (!functionGroupName) {
110
+ return undefined;
111
+ }
112
+ const state = await client
113
+ .getFunctionInclude()
114
+ .readMetadata({ functionGroupName, includeName: name });
115
+ result = (0, responseToText_1.responseToText)(state.metadataResult);
116
+ break;
117
+ }
108
118
  case 'enhancement': {
109
119
  const state = await client
110
120
  .getEnhancement()
@@ -1 +1 @@
1
- {"version":3,"file":"readSourceText.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readSourceText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,QAAQ,GAAG,UAAqB,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAwGpC"}
1
+ {"version":3,"file":"readSourceText.d.ts","sourceRoot":"","sources":["../../../src/lib/backup/readSourceText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,QAAQ,GAAG,UAAqB,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CA2HpC"}
@@ -23,6 +23,12 @@ async function readSourceText(client, spec, version = 'active') {
23
23
  .read({ programName: spec.name }, version);
24
24
  return (0, responseToText_1.responseToText)(state?.readResult);
25
25
  }
26
+ case 'transformation': {
27
+ const state = await client
28
+ .getTransformation()
29
+ .read({ transformationName: spec.name }, version);
30
+ return (0, responseToText_1.responseToText)(state?.readResult);
31
+ }
26
32
  case 'view': {
27
33
  const state = await client
28
34
  .getView()
@@ -80,6 +86,17 @@ async function readSourceText(client, spec, version = 'active') {
80
86
  }, version);
81
87
  return (0, responseToText_1.responseToText)(state?.readResult);
82
88
  }
89
+ case 'functionInclude': {
90
+ if (!spec.functionGroupName)
91
+ return undefined;
92
+ // read() returns the include source (adt-clients >= 5.8.0), consistent
93
+ // with class/program/functionModule.
94
+ const state = await client.getFunctionInclude().read({
95
+ functionGroupName: spec.functionGroupName,
96
+ includeName: spec.name,
97
+ }, version);
98
+ return (0, responseToText_1.responseToText)(state?.readResult);
99
+ }
83
100
  case 'enhancement': {
84
101
  const state = await client
85
102
  .getEnhancement()
@@ -1 +1 @@
1
- {"version":3,"file":"typeOrder.d.ts","sourceRoot":"","sources":["../../../src/lib/constants/typeOrder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,eAAO,MAAM,SAAS,EAAE,aAAa,EAmBpC,CAAC"}
1
+ {"version":3,"file":"typeOrder.d.ts","sourceRoot":"","sources":["../../../src/lib/constants/typeOrder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,eAAO,MAAM,SAAS,EAAE,aAAa,EAqBpC,CAAC"}
@@ -10,10 +10,12 @@ exports.typeOrder = [
10
10
  'tableType',
11
11
  'view',
12
12
  'functionGroup',
13
+ 'functionInclude',
13
14
  'functionModule',
14
15
  'interface',
15
16
  'class',
16
17
  'program',
18
+ 'transformation',
17
19
  'serviceDefinition',
18
20
  'serviceBinding',
19
21
  'metadataExtension',
@@ -1 +1 @@
1
- {"version":3,"file":"collectTreeDependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/dependencies/collectTreeDependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,KAAK,EAAE,cAAc,EAA6B,MAAM,UAAU,CAAC;AAmC1E,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Ff"}
1
+ {"version":3,"file":"collectTreeDependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/dependencies/collectTreeDependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,KAAK,EAAE,cAAc,EAA6B,MAAM,UAAU,CAAC;AAoC1E,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Ff"}
@@ -17,6 +17,7 @@ const WHERE_USED_TYPE_MAP = {
17
17
  class: 'CLAS/OC',
18
18
  interface: 'INTF/IF',
19
19
  program: 'PROG/P',
20
+ transformation: 'XSLT/VT',
20
21
  functionGroup: 'FUGR/F',
21
22
  functionModule: 'FUGR/FF',
22
23
  serviceDefinition: 'SRVD/SRV',
@@ -1 +1 @@
1
- {"version":3,"file":"analyzeDependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/analyzeDependencies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;CACrB;AA+MD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,YAAY,EAAE,CA2B3E;AA2BD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,GACtB,YAAY,EAAE,CA8DhB"}
1
+ {"version":3,"file":"analyzeDependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/analyzeDependencies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;CACrB;AA+MD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,YAAY,EAAE,CA2B3E;AA6BD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,GACtB,YAAY,EAAE,CA8DhB"}
@@ -218,11 +218,13 @@ const TYPE_CREATION_ORDER = {
218
218
  accessControl: 6,
219
219
  metadataExtension: 6,
220
220
  program: 7,
221
+ transformation: 7,
221
222
  functionGroup: 7,
222
- functionModule: 8,
223
- serviceDefinition: 9,
224
- serviceBinding: 10,
225
- enhancement: 11,
223
+ functionInclude: 8,
224
+ functionModule: 9,
225
+ serviceDefinition: 10,
226
+ serviceBinding: 11,
227
+ enhancement: 12,
226
228
  };
227
229
  /**
228
230
  * Analyzes dependencies and merges SCCs at the same dependency level
@@ -1 +1 @@
1
- {"version":3,"file":"restoreObject.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAmBV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAM1D,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,CAqSf"}
1
+ {"version":3,"file":"restoreObject.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreObject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAqBV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAO1D,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,CA2Uf"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.restoreObject = restoreObject;
4
4
  const applyConfigName_1 = require("../utils/applyConfigName");
5
5
  const asConfig_1 = require("../utils/asConfig");
6
+ const detectTransformationType_1 = require("../utils/detectTransformationType");
6
7
  const ensureDescription_1 = require("../utils/ensureDescription");
7
8
  const applyTransportRequest_1 = require("./applyTransportRequest");
8
9
  async function restoreObject(client, obj, mode, activate, transportRequest) {
@@ -128,6 +129,25 @@ async function restoreObject(client, obj, mode, activate, transportRequest) {
128
129
  }
129
130
  return;
130
131
  }
132
+ case 'transformation': {
133
+ const transformationType = (0, detectTransformationType_1.detectTransformationType)(obj.source);
134
+ const baseTxConfig = {
135
+ ...config,
136
+ transformationType,
137
+ };
138
+ if (mode !== 'update') {
139
+ await client
140
+ .getTransformation()
141
+ .create((0, asConfig_1.asConfig)(baseTxConfig), options);
142
+ }
143
+ if (obj.source) {
144
+ await client.getTransformation().update((0, asConfig_1.asConfig)({
145
+ ...baseTxConfig,
146
+ sourceCode: obj.source,
147
+ }), options);
148
+ }
149
+ return;
150
+ }
131
151
  case 'functionGroup': {
132
152
  if (mode !== 'update') {
133
153
  await client
@@ -155,6 +175,21 @@ async function restoreObject(client, obj, mode, activate, transportRequest) {
155
175
  }
156
176
  return;
157
177
  }
178
+ case 'functionInclude': {
179
+ const fgn = (obj.functionGroupName ?? '').toUpperCase();
180
+ // The TOP include is auto-created with the function group, so it can only
181
+ // be updated (a create would fail "already exists"). Custom includes are
182
+ // created — the create chain uploads source and activates.
183
+ const isTop = obj.name.toUpperCase() === `L${fgn}TOP`;
184
+ const cfg = (0, asConfig_1.asConfig)(obj.source ? { ...config, sourceCode: obj.source } : config);
185
+ if (!isTop && mode !== 'update') {
186
+ await client.getFunctionInclude().create(cfg, options);
187
+ }
188
+ else if (obj.source) {
189
+ await client.getFunctionInclude().update(cfg, options);
190
+ }
191
+ return;
192
+ }
158
193
  case 'serviceDefinition': {
159
194
  if (mode !== 'update') {
160
195
  await client
@@ -1 +1 @@
1
- {"version":3,"file":"restoreObjects.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreObjects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,2BAA2B,CAAC;AAE5E,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA2B1D,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,YAAY,EAAE,EACvB,IAAI,EAAE,WAAW,EACjB,gBAAgB,EAAE,OAAO,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,gBAAgB,UAAO,GACtB,OAAO,CAAC,IAAI,CAAC,CA+Df"}
1
+ {"version":3,"file":"restoreObjects.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreObjects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,2BAA2B,CAAC;AAE5E,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA6B1D,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,YAAY,EAAE,EACvB,IAAI,EAAE,WAAW,EACjB,gBAAgB,EAAE,OAAO,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,gBAAgB,UAAO,GACtB,OAAO,CAAC,IAAI,CAAC,CA+Df"}
@@ -16,8 +16,10 @@ const ADT_TYPE_MAP = {
16
16
  class: 'CLAS/OC',
17
17
  interface: 'INTF/OI',
18
18
  program: 'PROG/P',
19
+ transformation: 'XSLT/VT',
19
20
  functionGroup: 'FUGR/FF',
20
21
  functionModule: 'FUGR/I',
22
+ functionInclude: 'FUGR/I',
21
23
  serviceDefinition: 'SRVD/SRV',
22
24
  serviceBinding: 'SRVB/SRV',
23
25
  metadataExtension: 'DDLX/PX',
@@ -1 +1 @@
1
- {"version":3,"file":"restoreTreeBackup.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreTreeBackup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,2BAA2B,CAAC;AAK5E,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAEjB,MAAM,UAAU,CAAC;AA8DlB,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,CAAC,EAAE,MAAM,EACzB,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,gBAAgB,UAAO,EACvB,iBAAiB,CAAC,EAAE,MAAM,EAC1B,oBAAoB,CAAC,EAAE,MAAM,EAC7B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAiZf"}
1
+ {"version":3,"file":"restoreTreeBackup.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreTreeBackup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,2BAA2B,CAAC;AAK5E,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,gBAAgB,EAEjB,MAAM,UAAU,CAAC;AAmElB,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,CAAC,EAAE,MAAM,EACzB,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,gBAAgB,UAAO,EACvB,iBAAiB,CAAC,EAAE,MAAM,EAC1B,oBAAoB,CAAC,EAAE,MAAM,EAC7B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAiZf"}
@@ -27,6 +27,11 @@ const RESTORE_PHASES = [
27
27
  { name: 'Classes', types: ['class'], activation: 'individual' },
28
28
  { name: 'Interfaces', types: ['interface'], activation: 'individual' },
29
29
  { name: 'Programs', types: ['program'], activation: 'individual' },
30
+ {
31
+ name: 'Transformations',
32
+ types: ['transformation'],
33
+ activation: 'individual',
34
+ },
30
35
  {
31
36
  name: 'Function Groups',
32
37
  types: ['functionGroup'],
@@ -88,7 +93,7 @@ async function restoreTreeBackup(client, root, mode, activate, transportRequest,
88
93
  if (refs.length === 0)
89
94
  return;
90
95
  // Check which objects are actually inactive
91
- let toActivate = await findInactiveRefs(refs);
96
+ const toActivate = await findInactiveRefs(refs);
92
97
  if (toActivate.length === 0) {
93
98
  (0, logVerbose_1.logVerbose)(2, ` [*] ${phaseName}: all ${refs.length} objects already active`);
94
99
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"restoreTreeNode.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreTreeNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAoBV,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAO5D,wBAAsB,eAAe,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,CAAC,EAAE,MAAM,EACzB,yBAAyB,CAAC,EAAE,MAAM,EAClC,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAChC,oBAAoB,CAAC,EAAE,MAAM,EAC7B,sBAAsB,CAAC,EAAE,MAAM,GAC9B,OAAO,CAAC,IAAI,CAAC,CA8Zf"}
1
+ {"version":3,"file":"restoreTreeNode.d.ts","sourceRoot":"","sources":["../../../src/lib/restore/restoreTreeNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAsBV,MAAM,2BAA2B,CAAC;AAGnC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5D,wBAAsB,eAAe,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,CAAC,EAAE,MAAM,EACzB,yBAAyB,CAAC,EAAE,MAAM,EAClC,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAChC,oBAAoB,CAAC,EAAE,MAAM,EAC7B,sBAAsB,CAAC,EAAE,MAAM,GAC9B,OAAO,CAAC,IAAI,CAAC,CAicf"}
@@ -4,6 +4,7 @@ exports.restoreTreeNode = restoreTreeNode;
4
4
  const logVerbose_1 = require("../cli/logVerbose");
5
5
  const decodeBase64_1 = require("../crypto/decodeBase64");
6
6
  const asConfig_1 = require("../utils/asConfig");
7
+ const detectTransformationType_1 = require("../utils/detectTransformationType");
7
8
  const ensureDescription_1 = require("../utils/ensureDescription");
8
9
  const parseBdefSource_1 = require("../utils/parseBdefSource");
9
10
  const parsePackageConfig_1 = require("../xml/parsePackageConfig");
@@ -190,6 +191,22 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
190
191
  }
191
192
  return;
192
193
  }
194
+ case 'transformation': {
195
+ const transformationType = (0, detectTransformationType_1.detectTransformationType)(payload);
196
+ const baseTxConfig = { ...config, transformationType };
197
+ if (mode !== 'update') {
198
+ await client
199
+ .getTransformation()
200
+ .create((0, asConfig_1.asConfig)(baseTxConfig), options);
201
+ }
202
+ if (payload) {
203
+ await client.getTransformation().update((0, asConfig_1.asConfig)({
204
+ ...baseTxConfig,
205
+ sourceCode: payload,
206
+ }), options);
207
+ }
208
+ return;
209
+ }
193
210
  case 'functionGroup': {
194
211
  if (mode !== 'update') {
195
212
  await client
@@ -216,6 +233,21 @@ async function restoreTreeNode(client, node, mode, activate, transportRequest, s
216
233
  }
217
234
  return;
218
235
  }
236
+ case 'functionInclude': {
237
+ const fgn = (node.functionGroupName ?? '').toUpperCase();
238
+ // The TOP include is auto-created with the function group, so it can
239
+ // only be updated (a create would fail "already exists"). Custom
240
+ // includes are created — the create chain uploads source and activates.
241
+ const isTop = node.name.toUpperCase() === `L${fgn}TOP`;
242
+ const cfg = (0, asConfig_1.asConfig)(payload ? { ...config, sourceCode: payload } : config);
243
+ if (!isTop && mode !== 'update') {
244
+ await client.getFunctionInclude().create(cfg, options);
245
+ }
246
+ else if (payload) {
247
+ await client.getFunctionInclude().update(cfg, options);
248
+ }
249
+ return;
250
+ }
219
251
  case 'serviceDefinition': {
220
252
  if (mode !== 'update') {
221
253
  await client
@@ -1 +1 @@
1
- {"version":3,"file":"enrichTreeNode.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/enrichTreeNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAU/C,wBAAsB,cAAc,CAClC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,OAAO,EACpB,uBAAuB,CAAC,EAAE,MAAM,GAC/B,OAAO,CAAC,cAAc,CAAC,CAkGzB"}
1
+ {"version":3,"file":"enrichTreeNode.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/enrichTreeNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAU/C,wBAAsB,cAAc,CAClC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,OAAO,EACpB,uBAAuB,CAAC,EAAE,MAAM,GAC/B,OAAO,CAAC,cAAc,CAAC,CAgIzB"}
@@ -74,9 +74,35 @@ async function enrichTreeNode(node, client, includeCode, parentFunctionGroupName
74
74
  }
75
75
  }
76
76
  }
77
- if (node.children && node.children.length > 0) {
77
+ // A function group's function modules (FUGR/FF) and includes (FUGR/I) are not
78
+ // returned by the package hierarchy — enumerate them and attach as children so
79
+ // their source is captured. Skip the generated `L<FUGR>UXX` collector (no
80
+ // developer content; regenerated on restore).
81
+ const childNodes = node.children ? [...node.children] : [];
82
+ if (mappedType === 'functionGroup' && includeCode) {
83
+ const utils = client.getUtils();
84
+ const [fmNames, includeNames] = await Promise.all([
85
+ utils.listFunctionModules(node.name),
86
+ utils.listFunctionGroupIncludes(node.name),
87
+ ]);
88
+ const generatedCollector = `L${node.name.toUpperCase()}UXX`;
89
+ const enumerated = [
90
+ ...fmNames.map((name) => ({ name, adtType: 'FUGR/FF' })),
91
+ ...includeNames
92
+ .filter((name) => name.toUpperCase() !== generatedCollector)
93
+ .map((name) => ({ name, adtType: 'FUGR/I' })),
94
+ ];
95
+ const present = new Set(childNodes.map((c) => c.name.toUpperCase()));
96
+ for (const child of enumerated) {
97
+ if (!present.has(child.name.toUpperCase())) {
98
+ childNodes.push(child);
99
+ }
100
+ }
101
+ (0, logVerbose_1.logVerbose)(2, ` FUGR ${node.name}: +${fmNames.length} FM, +${enumerated.length - fmNames.length} include(s)`);
102
+ }
103
+ if (childNodes.length > 0) {
78
104
  const children = [];
79
- for (const child of node.children) {
105
+ for (const child of childNodes) {
80
106
  children.push(await enrichTreeNode(child, client, includeCode, functionGroupName));
81
107
  }
82
108
  nextNode.children = children;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getNodeFunctionGroupName = getNodeFunctionGroupName;
4
4
  function getNodeFunctionGroupName(node) {
5
- if (node.type !== 'functionModule') {
5
+ if (node.type !== 'functionModule' && node.type !== 'functionInclude') {
6
6
  return undefined;
7
7
  }
8
8
  const configGroup = node.config && typeof node.config.functionGroupName === 'string'
@@ -6,7 +6,7 @@ function getNodeObjectSpec(node) {
6
6
  if (!node.type) {
7
7
  return undefined;
8
8
  }
9
- if (node.type === 'functionModule') {
9
+ if (node.type === 'functionModule' || node.type === 'functionInclude') {
10
10
  const group = (0, getNodeFunctionGroupName_1.getNodeFunctionGroupName)(node);
11
11
  if (!group) {
12
12
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"isRestoreImplemented.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/isRestoreImplemented.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAyBlE"}
1
+ {"version":3,"file":"isRestoreImplemented.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/isRestoreImplemented.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CA2BlE"}
@@ -12,9 +12,11 @@ function isRestoreImplemented(type) {
12
12
  case 'view':
13
13
  case 'functionGroup':
14
14
  case 'functionModule':
15
+ case 'functionInclude':
15
16
  case 'interface':
16
17
  case 'class':
17
18
  case 'program':
19
+ case 'transformation':
18
20
  case 'serviceDefinition':
19
21
  case 'serviceBinding':
20
22
  case 'metadataExtension':
@@ -1 +1 @@
1
- {"version":3,"file":"mapAdtTypeToSupported.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/mapAdtTypeToSupported.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,qBAAqB,CACnC,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,GAAG,SAAS,CAgE3B"}
1
+ {"version":3,"file":"mapAdtTypeToSupported.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/mapAdtTypeToSupported.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,qBAAqB,CACnC,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,GAAG,SAAS,CAqE3B"}
@@ -23,7 +23,10 @@ function mapAdtTypeToSupported(adtType) {
23
23
  'INTF/IF': 'interface',
24
24
  'INTF/OI': 'interface',
25
25
  'PROG/P': 'program',
26
+ 'XSLT/VT': 'transformation',
27
+ 'XSLT/ST': 'transformation',
26
28
  'FUGR/FF': 'functionModule',
29
+ 'FUGR/I': 'functionInclude',
27
30
  'FUGR/F': 'functionGroup',
28
31
  FUGR: 'functionGroup',
29
32
  'SRVD/SRV': 'serviceDefinition',
@@ -45,6 +48,8 @@ function mapAdtTypeToSupported(adtType) {
45
48
  return 'interface';
46
49
  if (normalized.startsWith('PROG/'))
47
50
  return 'program';
51
+ if (normalized.startsWith('XSLT/'))
52
+ return 'transformation';
48
53
  if (normalized.startsWith('DDLS/'))
49
54
  return 'view';
50
55
  if (normalized.startsWith('DDLX/'))
@@ -65,6 +70,8 @@ function mapAdtTypeToSupported(adtType) {
65
70
  return 'tableType';
66
71
  if (normalized.startsWith('FUGR/FF'))
67
72
  return 'functionModule';
73
+ if (normalized.startsWith('FUGR/I'))
74
+ return 'functionInclude';
68
75
  if (normalized.startsWith('FUGR/'))
69
76
  return 'functionGroup';
70
77
  if (normalized.startsWith('DEVC/'))
@@ -1 +1 @@
1
- {"version":3,"file":"readPayloadForType.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/readPayloadForType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAG3D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,cAAc,CAAC,YAAY,CAAC,CAAA;CAAE,CAAC,CAuCtE"}
1
+ {"version":3,"file":"readPayloadForType.d.ts","sourceRoot":"","sources":["../../../src/lib/tree/readPayloadForType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAG3D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,cAAc,CAAC,YAAY,CAAC,CAAA;CAAE,CAAC,CAyCtE"}
@@ -8,10 +8,12 @@ async function readPayloadForType(client, type, name, functionGroupName) {
8
8
  case 'class':
9
9
  case 'interface':
10
10
  case 'program':
11
+ case 'transformation':
11
12
  case 'view':
12
13
  case 'structure':
13
14
  case 'table':
14
15
  case 'functionModule':
16
+ case 'functionInclude':
15
17
  case 'serviceDefinition':
16
18
  case 'metadataExtension':
17
19
  case 'behaviorDefinition':
@@ -1,4 +1,4 @@
1
- export type SupportedType = 'package' | 'domain' | 'dataElement' | 'structure' | 'table' | 'tableType' | 'view' | 'class' | 'interface' | 'program' | 'functionGroup' | 'functionModule' | 'serviceDefinition' | 'serviceBinding' | 'metadataExtension' | 'behaviorDefinition' | 'behaviorImplementation' | 'enhancement' | 'accessControl' | 'unitTest' | 'cdsUnitTest';
1
+ export type SupportedType = 'package' | 'domain' | 'dataElement' | 'structure' | 'table' | 'tableType' | 'view' | 'class' | 'interface' | 'program' | 'transformation' | 'functionGroup' | 'functionModule' | 'functionInclude' | 'serviceDefinition' | 'serviceBinding' | 'metadataExtension' | 'behaviorDefinition' | 'behaviorImplementation' | 'enhancement' | 'accessControl' | 'unitTest' | 'cdsUnitTest';
2
2
  export type RestoreMode = 'create' | 'update' | 'upsert' | 'skip';
3
3
  export type BackupConfig = Record<string, unknown>;
4
4
  export interface ObjectSpec {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,SAAS,GACT,QAAQ,GACR,aAAa,GACb,WAAW,GACX,OAAO,GACP,WAAW,GACX,MAAM,GACN,OAAO,GACP,WAAW,GACX,SAAS,GACT,gBAAgB,GAChB,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,wBAAwB,GACxB,aAAa,GACb,eAAe,GACf,UAAU,GACV,aAAa,CAAC;AAElB,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,CAAC,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,IAAI,GAAG,iBAAiB,CAAC;IACzC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,CAAC,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,CAAC,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,MAAM,MAAM,SAAS,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,EAAE,GACT,MAAM,GACN,MAAM,GACN,IAAI,CAAC;AACT,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"applyConfigName.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/applyConfigName.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5D,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,MAAM,EAC1B,MAAM,CAAC,EAAE,YAAY,GACpB,YAAY,CAqEd"}
1
+ {"version":3,"file":"applyConfigName.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/applyConfigName.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5D,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,MAAM,EAC1B,MAAM,CAAC,EAAE,YAAY,GACpB,YAAY,CA4Ed"}
@@ -34,6 +34,9 @@ function applyConfigName(type, name, functionGroupName, config) {
34
34
  case 'program':
35
35
  finalConfig.programName = name;
36
36
  break;
37
+ case 'transformation':
38
+ finalConfig.transformationName = name;
39
+ break;
37
40
  case 'functionGroup':
38
41
  finalConfig.functionGroupName = name;
39
42
  break;
@@ -41,6 +44,10 @@ function applyConfigName(type, name, functionGroupName, config) {
41
44
  finalConfig.functionModuleName = name;
42
45
  finalConfig.functionGroupName = functionGroupName;
43
46
  break;
47
+ case 'functionInclude':
48
+ finalConfig.includeName = name;
49
+ finalConfig.functionGroupName = functionGroupName;
50
+ break;
44
51
  case 'serviceDefinition':
45
52
  finalConfig.serviceDefinitionName = name;
46
53
  break;
@@ -0,0 +1,3 @@
1
+ import type { ITransformationConfig } from '@mcp-abap-adt/adt-clients';
2
+ export declare function detectTransformationType(source?: string): ITransformationConfig['transformationType'];
3
+ //# sourceMappingURL=detectTransformationType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectTransformationType.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/detectTransformationType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,wBAAgB,wBAAwB,CACtC,MAAM,CAAC,EAAE,MAAM,GACd,qBAAqB,CAAC,oBAAoB,CAAC,CAK7C"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectTransformationType = detectTransformationType;
4
+ function detectTransformationType(source) {
5
+ if (source && /<\?sap\.transform\s+simple\s*\?>/i.test(source)) {
6
+ return 'SimpleTransformation';
7
+ }
8
+ return 'XSLTProgram';
9
+ }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.formatObjectSpec = formatObjectSpec;
4
4
  function formatObjectSpec(spec) {
5
- if (spec.type === 'functionModule') {
5
+ if (spec.type === 'functionModule' || spec.type === 'functionInclude') {
6
6
  return `${spec.type}:${spec.functionGroupName}|${spec.name}`;
7
7
  }
8
8
  return `${spec.type}:${spec.name}`;
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeType.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/normalizeType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAyC5D"}
1
+ {"version":3,"file":"normalizeType.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/normalizeType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CA+C5D"}
@@ -17,10 +17,16 @@ function normalizeType(rawType) {
17
17
  class: 'class',
18
18
  interface: 'interface',
19
19
  program: 'program',
20
+ transformation: 'transformation',
21
+ xslt: 'transformation',
22
+ simpletransformation: 'transformation',
23
+ simple_transformation: 'transformation',
20
24
  functiongroup: 'functionGroup',
21
25
  function_group: 'functionGroup',
22
26
  functionmodule: 'functionModule',
23
27
  function_module: 'functionModule',
28
+ functioninclude: 'functionInclude',
29
+ function_include: 'functionInclude',
24
30
  servicedefinition: 'serviceDefinition',
25
31
  service_definition: 'serviceDefinition',
26
32
  servicebinding: 'serviceBinding',
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.objectId = objectId;
4
4
  function objectId(spec) {
5
- if (spec.type === 'functionModule') {
5
+ if (spec.type === 'functionModule' || spec.type === 'functionInclude') {
6
6
  return `${spec.type}:${spec.functionGroupName}|${spec.name}`;
7
7
  }
8
8
  return `${spec.type}:${spec.name}`;
@@ -1 +1 @@
1
- {"version":3,"file":"parseObjectSpec.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/parseObjectSpec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CA0BxD"}
1
+ {"version":3,"file":"parseObjectSpec.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/parseObjectSpec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAwBxD"}
@@ -12,10 +12,10 @@ function parseObjectSpec(spec) {
12
12
  if (!namePart) {
13
13
  throw new Error(`Missing name in object spec: ${spec}`);
14
14
  }
15
- if (type === 'functionModule') {
15
+ if (type === 'functionModule' || type === 'functionInclude') {
16
16
  const split = namePart.split(/[|/]/);
17
17
  if (split.length !== 2) {
18
- throw new Error(`Function module spec must be GROUP|NAME or GROUP/NAME: ${spec}`);
18
+ throw new Error(`${type} spec must be GROUP|NAME or GROUP/NAME: ${spec}`);
19
19
  }
20
20
  return {
21
21
  type,
@@ -1 +1 @@
1
- {"version":3,"file":"findOtherType.d.ts","sourceRoot":"","sources":["../../../src/lib/verify/findOtherType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAwB9C,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,aAAa,EAC3B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAepC"}
1
+ {"version":3,"file":"findOtherType.d.ts","sourceRoot":"","sources":["../../../src/lib/verify/findOtherType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAyB9C,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,aAAa,EAC3B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAepC"}
@@ -13,6 +13,7 @@ const supportedTypes = [
13
13
  'class',
14
14
  'interface',
15
15
  'program',
16
+ 'transformation',
16
17
  'functionGroup',
17
18
  'serviceDefinition',
18
19
  'serviceBinding',
@@ -1 +1 @@
1
- {"version":3,"file":"parseServiceBindingConfig.d.ts","sourceRoot":"","sources":["../../../src/lib/xml/parseServiceBindingConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAOvE,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,qBAAqB,CAAC,CAsFhC"}
1
+ {"version":3,"file":"parseServiceBindingConfig.d.ts","sourceRoot":"","sources":["../../../src/lib/xml/parseServiceBindingConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAOvE,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,qBAAqB,CAAC,CA2GhC"}
@@ -42,8 +42,20 @@ function parseServiceBindingConfig(xml) {
42
42
  (0, findAttribute_1.findAttribute)(binding, 'srvb:version');
43
43
  const bindingCategory = (0, getNodeAttribute_1.getNodeAttribute)(binding, 'srvb:category') ||
44
44
  (0, findAttribute_1.findAttribute)(binding, 'srvb:category');
45
- // Keep publication state unchanged by default during restore updates.
46
- const desiredPublicationState = 'unchanged';
45
+ // Reflect the published state from ADT so restore re-publishes/unpublishes
46
+ // the binding to match the source system. Attribute: srvb:published="true|false".
47
+ const publishedAttr = (0, getNodeAttribute_1.getNodeAttribute)(root, 'srvb:published') ||
48
+ (0, findAttribute_1.findAttribute)(root, 'srvb:published');
49
+ let desiredPublicationState = 'unchanged';
50
+ if (publishedAttr !== undefined && publishedAttr !== null) {
51
+ const normalized = String(publishedAttr).toLowerCase();
52
+ if (normalized === 'true') {
53
+ desiredPublicationState = 'published';
54
+ }
55
+ else if (normalized === 'false') {
56
+ desiredPublicationState = 'unpublished';
57
+ }
58
+ }
47
59
  const normalizedBindingType = bindingType?.toUpperCase();
48
60
  const normalizedBindingVersion = bindingVersion?.toUpperCase();
49
61
  const serviceType = normalizedBindingType === 'ODATA'
@@ -51,6 +63,15 @@ function parseServiceBindingConfig(xml) {
51
63
  ? 'odatav2'
52
64
  : 'odatav4'
53
65
  : undefined;
66
+ const bindingVariant = normalizedBindingType === 'ODATA'
67
+ ? normalizedBindingVersion === 'V2'
68
+ ? bindingCategory === '1'
69
+ ? 'ODATA_V2_WEB_API'
70
+ : 'ODATA_V2_UI'
71
+ : bindingCategory === '1'
72
+ ? 'ODATA_V4_WEB_API'
73
+ : 'ODATA_V4_UI'
74
+ : undefined;
54
75
  return {
55
76
  bindingName,
56
77
  packageName,
@@ -58,9 +79,7 @@ function parseServiceBindingConfig(xml) {
58
79
  serviceDefinitionName,
59
80
  serviceName,
60
81
  serviceVersion,
61
- bindingType: normalizedBindingType,
62
- bindingVersion,
63
- bindingCategory,
82
+ bindingVariant,
64
83
  masterLanguage,
65
84
  masterSystem,
66
85
  responsible,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/adt-backup",
3
- "version": "1.2.0",
3
+ "version": "1.5.0",
4
4
  "description": "ADT backup CLI for SAP ABAP objects (recursive package backups and restores)",
5
5
  "main": "dist/bin/adt-backup.js",
6
6
  "types": "dist/bin/adt-backup.d.ts",
@@ -45,20 +45,20 @@
45
45
  "debug:deps": "npx ts-node scripts/debug-where-used-list.ts"
46
46
  },
47
47
  "engines": {
48
- "node": ">=18.0.0"
48
+ "node": ">=20.0.0"
49
49
  },
50
50
  "dependencies": {
51
- "@mcp-abap-adt/adt-clients": "^2.2.0",
51
+ "@mcp-abap-adt/adt-clients": "^5.8.0",
52
52
  "@mcp-abap-adt/auth-broker": "^1.0.5",
53
53
  "@mcp-abap-adt/auth-providers": "^1.0.5",
54
- "@mcp-abap-adt/auth-stores": "^1.0.2",
55
- "@mcp-abap-adt/connection": "^1.1.0",
56
- "fast-xml-parser": "^5.4.1",
57
- "yaml": "^2.8.2"
54
+ "@mcp-abap-adt/auth-stores": "^1.0.4",
55
+ "@mcp-abap-adt/connection": "^1.8.0",
56
+ "fast-xml-parser": "^5.7.1",
57
+ "yaml": "^2.8.3"
58
58
  },
59
59
  "devDependencies": {
60
- "@biomejs/biome": "^2.4.4",
61
- "@types/node": "^25.3.1",
62
- "typescript": "^5.9.2"
60
+ "@biomejs/biome": "^2.4.12",
61
+ "@types/node": "^25.6.0",
62
+ "typescript": "^6.0.3"
63
63
  }
64
64
  }