@abapify/adt-contracts 0.4.0 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-BfUrFNlD.d.mts +31109 -0
- package/dist/base-BfUrFNlD.d.mts.map +1 -0
- package/dist/base-CJ5t6dbP.mjs +3056 -0
- package/dist/base-CJ5t6dbP.mjs.map +1 -0
- package/dist/base.d.mts +2 -0
- package/dist/base.mjs +3 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +56 -0
- package/dist/index.mjs.map +1 -0
- package/dist/schemas-DjN7IPy_.d.mts +9607 -0
- package/dist/schemas-DjN7IPy_.d.mts.map +1 -0
- package/dist/schemas.d.mts +2 -0
- package/dist/schemas.mjs +92 -0
- package/dist/schemas.mjs.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,3056 @@
|
|
|
1
|
+
import { acoverageResult, acoverageStatements, adtcore, atc, atcRun, atcworklist, atomFeed, aunitResult, aunitRun, badi, blueSource, checkrun, classes, configuration, configurations as configurations$1, dataelementWrapper, dclSource, ddlSource, ddlxSource, discovery, domain, dtebSource, fmodules, groups as groups$1, http as http$2, includes, interfaces, objectProperties, packagesV1, programs, servicebinding, srvdSource, systeminformation, tabletype, transportUseraction, transportfind, transportmanagment, transportmanagmentCreate, transportmanagmentSingle } from "./schemas.mjs";
|
|
2
|
+
import { createClient, http, http as http$1 } from "@abapify/speci/rest";
|
|
3
|
+
|
|
4
|
+
//#region src/helpers/text-schema.ts
|
|
5
|
+
/**
|
|
6
|
+
* Serializable<string> for text/plain request/response bodies.
|
|
7
|
+
*
|
|
8
|
+
* `parse` coerces the raw response to string; `build` returns the string as-is.
|
|
9
|
+
* The `_infer` marker is the key piece — speci checks for it with `'_infer' in value`
|
|
10
|
+
* to decide whether the descriptor carries a body schema.
|
|
11
|
+
*/
|
|
12
|
+
const textPlain = {
|
|
13
|
+
parse: (x) => String(x),
|
|
14
|
+
build: (x) => x,
|
|
15
|
+
_infer: void 0
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/helpers/crud.ts
|
|
20
|
+
/**
|
|
21
|
+
* CRUD Contract Helper
|
|
22
|
+
*
|
|
23
|
+
* Generates full CRUD contracts for ADT repository objects following the
|
|
24
|
+
* standard SAP ADT URL template pattern:
|
|
25
|
+
*
|
|
26
|
+
* {basePath}/{object_name}{?corrNr,lockHandle,version,accessMode,_action}
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { crud } from '../helpers/crud';
|
|
31
|
+
* import { classes } from '../schemas';
|
|
32
|
+
*
|
|
33
|
+
* export const classesContract = crud({
|
|
34
|
+
* basePath: '/sap/bc/adt/oo/classes',
|
|
35
|
+
* schema: classes,
|
|
36
|
+
* contentType: 'application/vnd.sap.adt.oo.classes.v4+xml',
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* // Usage:
|
|
40
|
+
* // classesContract.get('zcl_my_class')
|
|
41
|
+
* // classesContract.post({ corrNr: 'DEVK900001' })
|
|
42
|
+
* // classesContract.put('zcl_my_class', { lockHandle: '...' })
|
|
43
|
+
* // classesContract.delete('zcl_my_class')
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Create source operations for a given source type
|
|
48
|
+
*/
|
|
49
|
+
function createSourceOperations(basePath, sourceType, nameTransform) {
|
|
50
|
+
return {
|
|
51
|
+
get: (name) => http.get(`${basePath}/${nameTransform(name)}/source/${sourceType}`, {
|
|
52
|
+
responses: { 200: void 0 },
|
|
53
|
+
headers: { Accept: "text/plain" }
|
|
54
|
+
}),
|
|
55
|
+
put: (name, options) => http.put(`${basePath}/${nameTransform(name)}/source/${sourceType}`, {
|
|
56
|
+
body: textPlain,
|
|
57
|
+
responses: { 200: void 0 },
|
|
58
|
+
headers: {
|
|
59
|
+
Accept: "text/plain",
|
|
60
|
+
"Content-Type": "text/plain"
|
|
61
|
+
},
|
|
62
|
+
query: {
|
|
63
|
+
...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
|
|
64
|
+
...options?.corrNr ? { corrNr: options.corrNr } : {}
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create include operations for a given include type
|
|
71
|
+
*/
|
|
72
|
+
function createIncludeOperations(basePath, includeType, nameTransform) {
|
|
73
|
+
return {
|
|
74
|
+
get: (name) => http.get(`${basePath}/${nameTransform(name)}/includes/${includeType}`, {
|
|
75
|
+
responses: { 200: void 0 },
|
|
76
|
+
headers: { Accept: "text/plain" }
|
|
77
|
+
}),
|
|
78
|
+
put: (name, options) => http.put(`${basePath}/${nameTransform(name)}/includes/${includeType}`, {
|
|
79
|
+
body: textPlain,
|
|
80
|
+
responses: { 200: void 0 },
|
|
81
|
+
headers: {
|
|
82
|
+
Accept: "text/plain",
|
|
83
|
+
"Content-Type": "text/plain"
|
|
84
|
+
},
|
|
85
|
+
query: {
|
|
86
|
+
...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
|
|
87
|
+
...options?.corrNr ? { corrNr: options.corrNr } : {}
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create a full CRUD contract for an ADT repository object
|
|
94
|
+
*
|
|
95
|
+
* Follows the standard SAP ADT URL template pattern:
|
|
96
|
+
* {basePath}/{object_name}{?corrNr,lockHandle,version,accessMode,_action}
|
|
97
|
+
*
|
|
98
|
+
* @example Basic CRUD
|
|
99
|
+
* ```ts
|
|
100
|
+
* const packagesContract = crud({
|
|
101
|
+
* basePath: '/sap/bc/adt/packages',
|
|
102
|
+
* schema: packages,
|
|
103
|
+
* contentType: 'application/vnd.sap.adt.packages.v1+xml',
|
|
104
|
+
* });
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @example With source code support
|
|
108
|
+
* ```ts
|
|
109
|
+
* const interfacesContract = crud({
|
|
110
|
+
* basePath: '/sap/bc/adt/oo/interfaces',
|
|
111
|
+
* schema: interfaces,
|
|
112
|
+
* contentType: 'application/vnd.sap.adt.oo.interfaces.v5+xml',
|
|
113
|
+
* sources: ['main'],
|
|
114
|
+
* });
|
|
115
|
+
* // interfacesContract.source.main.get('zif_my_interface')
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @example With includes support (classes)
|
|
119
|
+
* ```ts
|
|
120
|
+
* const classesContract = crud({
|
|
121
|
+
* basePath: '/sap/bc/adt/oo/classes',
|
|
122
|
+
* schema: classes,
|
|
123
|
+
* contentType: 'application/vnd.sap.adt.oo.classes.v4+xml',
|
|
124
|
+
* sources: ['main'],
|
|
125
|
+
* includes: ['definitions', 'implementations', 'macros'],
|
|
126
|
+
* });
|
|
127
|
+
* // classesContract.source.main.get('zcl_my_class')
|
|
128
|
+
* // classesContract.includes.definitions.get('zcl_my_class')
|
|
129
|
+
* // classesContract.includes.get('zcl_my_class', 'implementations')
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
function crud(options) {
|
|
133
|
+
const { basePath, schema, contentType, accept = contentType, nameTransform = (n) => n.toLowerCase(), sources, includes } = options;
|
|
134
|
+
return {
|
|
135
|
+
/** Schema for XML serialization/deserialization */
|
|
136
|
+
bodySchema: schema,
|
|
137
|
+
/**
|
|
138
|
+
* GET {basePath}/{name}
|
|
139
|
+
* Retrieve object metadata
|
|
140
|
+
*/
|
|
141
|
+
get: (name, queryOptions) => http.get(`${basePath}/${nameTransform(name)}`, {
|
|
142
|
+
responses: { 200: schema },
|
|
143
|
+
headers: { Accept: accept },
|
|
144
|
+
query: queryOptions?.version ? { version: queryOptions.version } : void 0
|
|
145
|
+
}),
|
|
146
|
+
/**
|
|
147
|
+
* POST {basePath}
|
|
148
|
+
* Create a new object
|
|
149
|
+
*/
|
|
150
|
+
post: (queryOptions) => http.post(basePath, {
|
|
151
|
+
body: schema,
|
|
152
|
+
responses: { 200: schema },
|
|
153
|
+
headers: {
|
|
154
|
+
Accept: accept,
|
|
155
|
+
"Content-Type": contentType
|
|
156
|
+
},
|
|
157
|
+
query: queryOptions?.corrNr ? { corrNr: queryOptions.corrNr } : void 0
|
|
158
|
+
}),
|
|
159
|
+
/**
|
|
160
|
+
* PUT {basePath}/{name}
|
|
161
|
+
* Update object metadata
|
|
162
|
+
*/
|
|
163
|
+
put: (name, queryOptions) => http.put(`${basePath}/${nameTransform(name)}`, {
|
|
164
|
+
body: schema,
|
|
165
|
+
responses: { 200: schema },
|
|
166
|
+
headers: {
|
|
167
|
+
Accept: accept,
|
|
168
|
+
"Content-Type": contentType
|
|
169
|
+
},
|
|
170
|
+
query: {
|
|
171
|
+
...queryOptions?.corrNr ? { corrNr: queryOptions.corrNr } : {},
|
|
172
|
+
...queryOptions?.lockHandle ? { lockHandle: queryOptions.lockHandle } : {}
|
|
173
|
+
}
|
|
174
|
+
}),
|
|
175
|
+
/**
|
|
176
|
+
* DELETE {basePath}/{name}
|
|
177
|
+
* Delete object
|
|
178
|
+
*/
|
|
179
|
+
delete: (name, queryOptions) => http.delete(`${basePath}/${nameTransform(name)}`, {
|
|
180
|
+
responses: { 204: void 0 },
|
|
181
|
+
query: {
|
|
182
|
+
...queryOptions?.corrNr ? { corrNr: queryOptions.corrNr } : {},
|
|
183
|
+
...queryOptions?.lockHandle ? { lockHandle: queryOptions.lockHandle } : {}
|
|
184
|
+
}
|
|
185
|
+
}),
|
|
186
|
+
/**
|
|
187
|
+
* POST {basePath}/{name}?_action=LOCK
|
|
188
|
+
* Lock object for modification
|
|
189
|
+
*
|
|
190
|
+
* Response contains lock handle in XML format:
|
|
191
|
+
* <asx:abap>...<DATA><LOCK_HANDLE>xxx</LOCK_HANDLE><CORRNR>yyy</CORRNR>...</DATA>...</asx:abap>
|
|
192
|
+
*/
|
|
193
|
+
lock: (name, lockOptions) => http.post(`${basePath}/${nameTransform(name)}`, {
|
|
194
|
+
responses: { 200: void 0 },
|
|
195
|
+
headers: {
|
|
196
|
+
"X-sap-adt-sessiontype": "stateful",
|
|
197
|
+
"x-sap-security-session": "use",
|
|
198
|
+
Accept: "application/*,application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.lock.result"
|
|
199
|
+
},
|
|
200
|
+
query: {
|
|
201
|
+
_action: "LOCK",
|
|
202
|
+
accessMode: lockOptions?.accessMode ?? "MODIFY",
|
|
203
|
+
...lockOptions?.corrNr ? { corrNr: lockOptions.corrNr } : {}
|
|
204
|
+
}
|
|
205
|
+
}),
|
|
206
|
+
/**
|
|
207
|
+
* POST {basePath}/{name}?_action=UNLOCK
|
|
208
|
+
* Unlock object
|
|
209
|
+
*/
|
|
210
|
+
unlock: (name, unlockOptions) => http.post(`${basePath}/${nameTransform(name)}`, {
|
|
211
|
+
responses: { 200: void 0 },
|
|
212
|
+
headers: {
|
|
213
|
+
"X-sap-adt-sessiontype": "stateful",
|
|
214
|
+
"x-sap-security-session": "use"
|
|
215
|
+
},
|
|
216
|
+
query: {
|
|
217
|
+
_action: "UNLOCK",
|
|
218
|
+
accessMode: "MODIFY",
|
|
219
|
+
lockHandle: unlockOptions.lockHandle
|
|
220
|
+
}
|
|
221
|
+
}),
|
|
222
|
+
/**
|
|
223
|
+
* GET {basePath}/{name}/objectstructure
|
|
224
|
+
* Get object structure (includes, methods, attributes, etc.)
|
|
225
|
+
*/
|
|
226
|
+
objectstructure: (name, structureOptions) => http.get(`${basePath}/${nameTransform(name)}/objectstructure`, {
|
|
227
|
+
responses: { 200: void 0 },
|
|
228
|
+
query: {
|
|
229
|
+
...structureOptions?.version ? { version: structureOptions.version } : {},
|
|
230
|
+
...structureOptions?.withShortDescriptions !== void 0 ? { withShortDescriptions: String(structureOptions.withShortDescriptions) } : {}
|
|
231
|
+
}
|
|
232
|
+
}),
|
|
233
|
+
...sources ? { source: Object.fromEntries(sources.map((sourceType) => [sourceType, createSourceOperations(basePath, sourceType, nameTransform)])) } : {},
|
|
234
|
+
...includes ? { includes: {
|
|
235
|
+
get: (name, includeType) => http.get(`${basePath}/${nameTransform(name)}/includes/${includeType}`, {
|
|
236
|
+
responses: { 200: void 0 },
|
|
237
|
+
headers: { Accept: "text/plain" }
|
|
238
|
+
}),
|
|
239
|
+
put: (name, includeType, options) => http.put(`${basePath}/${nameTransform(name)}/includes/${includeType}`, {
|
|
240
|
+
body: textPlain,
|
|
241
|
+
responses: { 200: void 0 },
|
|
242
|
+
headers: {
|
|
243
|
+
Accept: "text/plain",
|
|
244
|
+
"Content-Type": "text/plain"
|
|
245
|
+
},
|
|
246
|
+
query: {
|
|
247
|
+
...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
|
|
248
|
+
...options?.corrNr ? { corrNr: options.corrNr } : {}
|
|
249
|
+
}
|
|
250
|
+
}),
|
|
251
|
+
...Object.fromEntries(includes.map((includeType) => [includeType, createIncludeOperations(basePath, includeType, nameTransform)]))
|
|
252
|
+
} } : {}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Shorthand alias for crud()
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* export const classesContract = repo('/sap/bc/adt/oo/classes', classes, 'application/vnd.sap.adt.oo.classes.v4+xml');
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
function repo(basePath, schema, contentType, nameTransform, accept) {
|
|
264
|
+
return crud({
|
|
265
|
+
basePath,
|
|
266
|
+
schema,
|
|
267
|
+
contentType,
|
|
268
|
+
accept,
|
|
269
|
+
nameTransform
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/adt/cts/transportrequests/valuehelp/attribute.ts
|
|
275
|
+
/**
|
|
276
|
+
* /sap/bc/adt/cts/transportrequests/valuehelp/attribute
|
|
277
|
+
*/
|
|
278
|
+
const attribute = {
|
|
279
|
+
/**
|
|
280
|
+
* GET /sap/bc/adt/cts/transportrequests/valuehelp/attribute{?maxItemCount}{&name}
|
|
281
|
+
*/
|
|
282
|
+
get: (params) => http.get("/sap/bc/adt/cts/transportrequests/valuehelp/attribute", {
|
|
283
|
+
query: params,
|
|
284
|
+
responses: { 200: void 0 },
|
|
285
|
+
headers: { Accept: "application/xml" }
|
|
286
|
+
}) };
|
|
287
|
+
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/adt/cts/transportrequests/valuehelp/target.ts
|
|
290
|
+
/**
|
|
291
|
+
* /sap/bc/adt/cts/transportrequests/valuehelp/target
|
|
292
|
+
*/
|
|
293
|
+
const target = {
|
|
294
|
+
/**
|
|
295
|
+
* GET /sap/bc/adt/cts/transportrequests/valuehelp/target{?maxItemCount}{&name}
|
|
296
|
+
*/
|
|
297
|
+
get: (params) => http.get("/sap/bc/adt/cts/transportrequests/valuehelp/target", {
|
|
298
|
+
query: params,
|
|
299
|
+
responses: { 200: void 0 },
|
|
300
|
+
headers: { Accept: "application/xml" }
|
|
301
|
+
}) };
|
|
302
|
+
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region src/adt/cts/transportrequests/valuehelp/ctsproject.ts
|
|
305
|
+
/**
|
|
306
|
+
* /sap/bc/adt/cts/transportrequests/valuehelp/ctsproject
|
|
307
|
+
*/
|
|
308
|
+
const ctsproject = {
|
|
309
|
+
/**
|
|
310
|
+
* GET /sap/bc/adt/cts/transportrequests/valuehelp/ctsproject{?maxItemCount}{&name}
|
|
311
|
+
*/
|
|
312
|
+
get: (params) => http.get("/sap/bc/adt/cts/transportrequests/valuehelp/ctsproject", {
|
|
313
|
+
query: params,
|
|
314
|
+
responses: { 200: void 0 },
|
|
315
|
+
headers: { Accept: "application/xml" }
|
|
316
|
+
}) };
|
|
317
|
+
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/adt/cts/transportrequests/valuehelp/object.ts
|
|
320
|
+
/**
|
|
321
|
+
* /sap/bc/adt/cts/transportrequests/valuehelp/object
|
|
322
|
+
*/
|
|
323
|
+
const object = {
|
|
324
|
+
/**
|
|
325
|
+
* GET /sap/bc/adt/cts/transportrequests/valuehelp/object/{field}{?maxItemCount}{&name}
|
|
326
|
+
*/
|
|
327
|
+
get: (field, params) => http.get(`/sap/bc/adt/cts/transportrequests/valuehelp/object/${field}`, {
|
|
328
|
+
query: params,
|
|
329
|
+
responses: { 200: void 0 },
|
|
330
|
+
headers: { Accept: "application/xml" }
|
|
331
|
+
}) };
|
|
332
|
+
|
|
333
|
+
//#endregion
|
|
334
|
+
//#region src/adt/cts/transportrequests/valuehelp/index.ts
|
|
335
|
+
/**
|
|
336
|
+
* /sap/bc/adt/cts/transportrequests/valuehelp
|
|
337
|
+
*/
|
|
338
|
+
const valuehelp = {
|
|
339
|
+
attribute,
|
|
340
|
+
target,
|
|
341
|
+
ctsproject,
|
|
342
|
+
object
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
//#endregion
|
|
346
|
+
//#region src/adt/cts/transportrequests/reference.ts
|
|
347
|
+
/**
|
|
348
|
+
* /sap/bc/adt/cts/transportrequests/reference
|
|
349
|
+
* @source transportmanagementref.json
|
|
350
|
+
*/
|
|
351
|
+
const reference = { get: () => http.get("/sap/bc/adt/cts/transportrequests/reference", {
|
|
352
|
+
responses: { 200: void 0 },
|
|
353
|
+
headers: { Accept: "application/xml" }
|
|
354
|
+
}) };
|
|
355
|
+
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/adt/cts/transportrequests/searchconfiguration/configurations.ts
|
|
358
|
+
/**
|
|
359
|
+
* /sap/bc/adt/cts/transportrequests/searchconfiguration/configurations
|
|
360
|
+
* @schema configurations.xsd, configuration.xsd
|
|
361
|
+
*/
|
|
362
|
+
const configurations = contract({
|
|
363
|
+
/** GET list of search configurations */
|
|
364
|
+
get: () => http$1.get("/sap/bc/adt/cts/transportrequests/searchconfiguration/configurations", {
|
|
365
|
+
responses: { 200: configurations$1 },
|
|
366
|
+
headers: { Accept: "application/vnd.sap.adt.configurations.v1+xml" }
|
|
367
|
+
}),
|
|
368
|
+
/** GET a specific configuration by ID */
|
|
369
|
+
getById: (_configId) => http$1.get("/sap/bc/adt/cts/transportrequests/searchconfiguration/configurations/${configId}", {
|
|
370
|
+
responses: { 200: configuration },
|
|
371
|
+
headers: { Accept: "application/vnd.sap.adt.configuration.v1+xml" }
|
|
372
|
+
}),
|
|
373
|
+
/** PUT update a specific configuration by ID - body type inferred from schema
|
|
374
|
+
* Note: If-Match header is automatically added by the adapter from cached ETag
|
|
375
|
+
*/
|
|
376
|
+
put: (_configId) => http$1.put("/sap/bc/adt/cts/transportrequests/searchconfiguration/configurations/${configId}", {
|
|
377
|
+
responses: { 200: configuration },
|
|
378
|
+
headers: {
|
|
379
|
+
"Content-Type": "application/vnd.sap.adt.configuration.v1+xml",
|
|
380
|
+
Accept: "application/vnd.sap.adt.configuration.v1+xml"
|
|
381
|
+
},
|
|
382
|
+
body: configuration
|
|
383
|
+
})
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
//#endregion
|
|
387
|
+
//#region src/adt/cts/transportrequests/searchconfiguration/metadata.ts
|
|
388
|
+
/**
|
|
389
|
+
* /sap/bc/adt/cts/transportrequests/searchconfiguration/metadata
|
|
390
|
+
* @schema configuration.xsd
|
|
391
|
+
*/
|
|
392
|
+
const metadata = contract({
|
|
393
|
+
/** GET default search configuration metadata */
|
|
394
|
+
get: () => http$1.get("/sap/bc/adt/cts/transportrequests/searchconfiguration/metadata", {
|
|
395
|
+
responses: { 200: configuration },
|
|
396
|
+
headers: { Accept: "application/vnd.sap.adt.configuration.metadata.v1+xml" }
|
|
397
|
+
}) });
|
|
398
|
+
|
|
399
|
+
//#endregion
|
|
400
|
+
//#region src/adt/cts/transportrequests/searchconfiguration/index.ts
|
|
401
|
+
/**
|
|
402
|
+
* /sap/bc/adt/cts/transportrequests/searchconfiguration
|
|
403
|
+
*/
|
|
404
|
+
const searchconfiguration = {
|
|
405
|
+
configurations,
|
|
406
|
+
metadata
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
//#endregion
|
|
410
|
+
//#region src/adt/cts/transportrequests/change-owner-schema.ts
|
|
411
|
+
function isChangeOwnerRoot(root) {
|
|
412
|
+
if (typeof root !== "object" || root === null) return false;
|
|
413
|
+
const { useraction, number, targetuser } = root;
|
|
414
|
+
return useraction === "changeowner" && typeof number === "string" && number.length > 0 && typeof targetuser === "string" && targetuser.length > 0;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Narrow request schema for the CTS change-owner action.
|
|
418
|
+
*
|
|
419
|
+
* SAP models these attributes on the broader transport-management root. This
|
|
420
|
+
* wrapper keeps the call-site body narrow while delegating XML parsing and
|
|
421
|
+
* serialization to that generated SAP schema.
|
|
422
|
+
*/
|
|
423
|
+
const changeOwnerBodySchema = {
|
|
424
|
+
_infer: void 0,
|
|
425
|
+
parse: (raw) => {
|
|
426
|
+
const root = transportmanagment.parse(raw)?.root;
|
|
427
|
+
if (!isChangeOwnerRoot(root)) throw new Error("Invalid CTS change-owner body");
|
|
428
|
+
return { root: {
|
|
429
|
+
number: root.number,
|
|
430
|
+
targetuser: root.targetuser,
|
|
431
|
+
useraction: "changeowner"
|
|
432
|
+
} };
|
|
433
|
+
},
|
|
434
|
+
build: (body) => transportmanagment.build(body)
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
//#endregion
|
|
438
|
+
//#region src/adt/cts/transportrequests/add-task-schema.ts
|
|
439
|
+
/** Narrow body used by SAP's hypermedia `newtask` relation. */
|
|
440
|
+
const addTaskBodySchema = {
|
|
441
|
+
_infer: void 0,
|
|
442
|
+
parse: (raw) => {
|
|
443
|
+
const root = transportmanagment.parse(raw)?.root;
|
|
444
|
+
if (!root || !root.targetuser) throw new Error("Invalid CTS add-task body");
|
|
445
|
+
return { root: { targetuser: root.targetuser } };
|
|
446
|
+
},
|
|
447
|
+
build: (body) => transportmanagment.build(body)
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
//#endregion
|
|
451
|
+
//#region src/adt/cts/transportrequests/useraction.ts
|
|
452
|
+
/**
|
|
453
|
+
* /sap/bc/adt/cts/transportrequests - user-action body endpoints
|
|
454
|
+
*
|
|
455
|
+
* SAP ADT uses distinct lifecycle endpoints for release, changeowner, and
|
|
456
|
+
* newrequest and newtask actions. This file exposes typed contracts for them.
|
|
457
|
+
*
|
|
458
|
+
* release → POST /{trkorr}/newreleasejobs (no body)
|
|
459
|
+
* changeowner → PUT /{trkorr} (requires tm:number and tm:targetuser)
|
|
460
|
+
* newtask → POST /{trkorr}/tasks (requires tm:targetuser)
|
|
461
|
+
* newrequest → POST / (creates a new transport request)
|
|
462
|
+
*/
|
|
463
|
+
const CONTENT_TYPE = "application/vnd.sap.adt.transportorganizer.v1+xml";
|
|
464
|
+
const useraction = {
|
|
465
|
+
/**
|
|
466
|
+
* Start and synchronously report a transport/task release job.
|
|
467
|
+
*/
|
|
468
|
+
release: (trkorr) => http$1.post(`/sap/bc/adt/cts/transportrequests/${trkorr}/newreleasejobs`, {
|
|
469
|
+
responses: { 200: transportmanagment },
|
|
470
|
+
headers: { Accept: CONTENT_TYPE }
|
|
471
|
+
}),
|
|
472
|
+
/**
|
|
473
|
+
* PUT /{trkorr} with useraction="changeowner".
|
|
474
|
+
*/
|
|
475
|
+
reassign: (trkorr, _options) => http$1.put(`/sap/bc/adt/cts/transportrequests/${trkorr}`, {
|
|
476
|
+
body: changeOwnerBodySchema,
|
|
477
|
+
responses: { 200: transportmanagmentSingle },
|
|
478
|
+
headers: {
|
|
479
|
+
Accept: CONTENT_TYPE,
|
|
480
|
+
"Content-Type": CONTENT_TYPE
|
|
481
|
+
}
|
|
482
|
+
}),
|
|
483
|
+
/** Create a modifiable task below an existing request. */
|
|
484
|
+
addTask: (trkorr, _options) => http$1.post(`/sap/bc/adt/cts/transportrequests/${trkorr}/tasks`, {
|
|
485
|
+
body: addTaskBodySchema,
|
|
486
|
+
responses: { 200: transportmanagment },
|
|
487
|
+
headers: {
|
|
488
|
+
Accept: CONTENT_TYPE,
|
|
489
|
+
"Content-Type": CONTENT_TYPE
|
|
490
|
+
}
|
|
491
|
+
}),
|
|
492
|
+
/**
|
|
493
|
+
* POST / with useraction="newrequest"
|
|
494
|
+
*
|
|
495
|
+
* Creates a brand-new transport request. Body carries the nested
|
|
496
|
+
* tm:request / tm:task with desc / type / target / owner.
|
|
497
|
+
*/
|
|
498
|
+
create: (_options) => http$1.post("/sap/bc/adt/cts/transportrequests", {
|
|
499
|
+
body: transportUseraction,
|
|
500
|
+
responses: { 200: transportmanagmentSingle },
|
|
501
|
+
headers: {
|
|
502
|
+
Accept: CONTENT_TYPE,
|
|
503
|
+
"Content-Type": CONTENT_TYPE
|
|
504
|
+
}
|
|
505
|
+
})
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
//#endregion
|
|
509
|
+
//#region src/adt/cts/transportrequests/index.ts
|
|
510
|
+
/**
|
|
511
|
+
* /sap/bc/adt/cts/transportrequests
|
|
512
|
+
* @source transportmanagement.json
|
|
513
|
+
*/
|
|
514
|
+
/** Re-export schema for consumers that need direct parsing */
|
|
515
|
+
const transportrequests = {
|
|
516
|
+
/** GET / - List transports */
|
|
517
|
+
list: (params) => http$1.get("/sap/bc/adt/cts/transportrequests", {
|
|
518
|
+
query: params,
|
|
519
|
+
responses: { 200: transportmanagment },
|
|
520
|
+
headers: { Accept: "*/*" }
|
|
521
|
+
}),
|
|
522
|
+
/** GET /{trkorr} - Get single transport */
|
|
523
|
+
get: (trkorr) => http$1.get(`/sap/bc/adt/cts/transportrequests/${trkorr}`, {
|
|
524
|
+
responses: { 200: transportmanagmentSingle },
|
|
525
|
+
headers: { Accept: "application/vnd.sap.adt.transportorganizer.v1+xml" }
|
|
526
|
+
}),
|
|
527
|
+
/** POST / - Create new transport (response has root/request structure like single) */
|
|
528
|
+
create: () => http$1.post("/sap/bc/adt/cts/transportrequests", {
|
|
529
|
+
body: transportmanagmentCreate,
|
|
530
|
+
responses: { 200: transportmanagmentSingle },
|
|
531
|
+
headers: {
|
|
532
|
+
Accept: "application/vnd.sap.adt.transportorganizer.v1+xml",
|
|
533
|
+
"Content-Type": "application/xml"
|
|
534
|
+
}
|
|
535
|
+
}),
|
|
536
|
+
/** POST /{trkorr} - Action on transport (release, etc.) */
|
|
537
|
+
post: (trkorr) => http$1.post(`/sap/bc/adt/cts/transportrequests/${trkorr}`, {
|
|
538
|
+
body: transportmanagment,
|
|
539
|
+
responses: { 200: transportmanagment },
|
|
540
|
+
headers: {
|
|
541
|
+
Accept: "application/vnd.sap.adt.transportorganizer.v1+xml",
|
|
542
|
+
"Content-Type": "application/xml"
|
|
543
|
+
}
|
|
544
|
+
}),
|
|
545
|
+
/** PUT /{trkorr} - Update transport */
|
|
546
|
+
put: (trkorr) => http$1.put(`/sap/bc/adt/cts/transportrequests/${trkorr}`, {
|
|
547
|
+
body: transportmanagment,
|
|
548
|
+
responses: { 200: transportmanagment },
|
|
549
|
+
headers: {
|
|
550
|
+
Accept: "application/vnd.sap.adt.transportorganizer.v1+xml",
|
|
551
|
+
"Content-Type": "application/xml"
|
|
552
|
+
}
|
|
553
|
+
}),
|
|
554
|
+
/** DELETE /{trkorr} - Delete transport */
|
|
555
|
+
delete: (trkorr) => http$1.delete(`/sap/bc/adt/cts/transportrequests/${trkorr}`, { responses: { 204: void 0 } }),
|
|
556
|
+
reference,
|
|
557
|
+
valuehelp,
|
|
558
|
+
searchconfiguration,
|
|
559
|
+
useraction
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
//#endregion
|
|
563
|
+
//#region src/adt/cts/transports.ts
|
|
564
|
+
/**
|
|
565
|
+
* /sap/bc/adt/cts/transports/**
|
|
566
|
+
* ADT CTS Transports Contract
|
|
567
|
+
*
|
|
568
|
+
* GET with _action=FIND - Search transports (undocumented but works)
|
|
569
|
+
*
|
|
570
|
+
* Uses manual ts-xsd schema from adt-schemas for proper XML parsing.
|
|
571
|
+
*/
|
|
572
|
+
/**
|
|
573
|
+
* Transport function codes (TRFUNCTION field)
|
|
574
|
+
*/
|
|
575
|
+
const TransportFunction = {
|
|
576
|
+
/** Workbench request - development objects */
|
|
577
|
+
WORKBENCH: "K",
|
|
578
|
+
/** Customizing request - configuration */
|
|
579
|
+
CUSTOMIZING: "W",
|
|
580
|
+
/** Transport of copies */
|
|
581
|
+
TRANSPORT_OF_COPIES: "T",
|
|
582
|
+
/** Development/correction task */
|
|
583
|
+
DEVELOPMENT_CORRECTION: "S",
|
|
584
|
+
/** Repair task */
|
|
585
|
+
REPAIR: "R",
|
|
586
|
+
/** Unclassified task */
|
|
587
|
+
UNCLASSIFIED: "X",
|
|
588
|
+
/** Customizing task */
|
|
589
|
+
CUSTOMIZING_TASK: "Q",
|
|
590
|
+
/** Wildcard - all types */
|
|
591
|
+
ALL: "*"
|
|
592
|
+
};
|
|
593
|
+
/**
|
|
594
|
+
* Transport status codes (TRSTATUS field) - for response parsing
|
|
595
|
+
*/
|
|
596
|
+
const TransportStatus = {
|
|
597
|
+
/** Modifiable - can be edited */
|
|
598
|
+
MODIFIABLE: "D",
|
|
599
|
+
/** Release started - in progress */
|
|
600
|
+
RELEASE_STARTED: "O",
|
|
601
|
+
/** Release in preparation */
|
|
602
|
+
RELEASE_IN_PREPARATION: "P",
|
|
603
|
+
/** Released - locked, cannot be edited */
|
|
604
|
+
RELEASED: "R",
|
|
605
|
+
/** Locked */
|
|
606
|
+
LOCKED: "L"
|
|
607
|
+
};
|
|
608
|
+
/**
|
|
609
|
+
* Normalize response to always return array of headers
|
|
610
|
+
* Works with the parsed transportfind schema response
|
|
611
|
+
*/
|
|
612
|
+
function normalizeTransportFindResponse(response) {
|
|
613
|
+
const headers = response?.values?.DATA?.CTS_REQ_HEADER;
|
|
614
|
+
if (!headers) return [];
|
|
615
|
+
return Array.isArray(headers) ? headers : [headers];
|
|
616
|
+
}
|
|
617
|
+
const transports = {
|
|
618
|
+
/**
|
|
619
|
+
* Search transports with filters
|
|
620
|
+
*
|
|
621
|
+
* GET /sap/bc/adt/cts/transports?_action=FIND&user=X&trfunction=*
|
|
622
|
+
*
|
|
623
|
+
* @example
|
|
624
|
+
* // Find all modifiable workbench requests for current user
|
|
625
|
+
* const result = await client.cts.transports.find({
|
|
626
|
+
* _action: 'FIND',
|
|
627
|
+
* user: 'PPLENKOV',
|
|
628
|
+
* trfunction: '*',
|
|
629
|
+
* });
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* // Find with status filter
|
|
633
|
+
* const result = await client.cts.transports.find({
|
|
634
|
+
* _action: 'FIND',
|
|
635
|
+
* user: '*',
|
|
636
|
+
* trfunction: 'K',
|
|
637
|
+
* requestStatus: 'D', // Modifiable only
|
|
638
|
+
* });
|
|
639
|
+
*/
|
|
640
|
+
find: (params) => http.get("/sap/bc/adt/cts/transports", {
|
|
641
|
+
query: params,
|
|
642
|
+
responses: { 200: transportfind },
|
|
643
|
+
headers: { Accept: "*/*" }
|
|
644
|
+
}) };
|
|
645
|
+
|
|
646
|
+
//#endregion
|
|
647
|
+
//#region src/adt/cts/transportchecks.ts
|
|
648
|
+
/**
|
|
649
|
+
* /sap/bc/adt/cts/transportchecks
|
|
650
|
+
* @source transportchecks.json
|
|
651
|
+
*/
|
|
652
|
+
const transportchecks = {
|
|
653
|
+
/**
|
|
654
|
+
* GET /sap/bc/adt/cts/transportchecks
|
|
655
|
+
*/
|
|
656
|
+
get: () => http.get("/sap/bc/adt/cts/transportchecks", {
|
|
657
|
+
responses: { 200: void 0 },
|
|
658
|
+
headers: { Accept: "application/xml" }
|
|
659
|
+
}) };
|
|
660
|
+
|
|
661
|
+
//#endregion
|
|
662
|
+
//#region src/adt/cts/index.ts
|
|
663
|
+
/**
|
|
664
|
+
* ADT CTS (Change and Transport System) Contracts
|
|
665
|
+
*
|
|
666
|
+
* Structure mirrors URL tree:
|
|
667
|
+
* - /sap/bc/adt/cts/transportrequests → cts.transportrequests
|
|
668
|
+
* - /sap/bc/adt/cts/transports → cts.transports
|
|
669
|
+
* - /sap/bc/adt/cts/transportchecks → cts.transportchecks
|
|
670
|
+
*
|
|
671
|
+
* Based on collections in: e2e/adt-codegen/generated/collections/sap/bc/adt/cts/
|
|
672
|
+
*/
|
|
673
|
+
const ctsContract = {
|
|
674
|
+
transportrequests,
|
|
675
|
+
transports,
|
|
676
|
+
transportchecks
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
//#endregion
|
|
680
|
+
//#region src/generated/adt/sap/bc/adt/atc/worklists.ts
|
|
681
|
+
/**
|
|
682
|
+
* ATC worklist
|
|
683
|
+
*
|
|
684
|
+
* Endpoint: /sap/bc/adt/atc/worklists
|
|
685
|
+
* Category: atcworklists
|
|
686
|
+
*
|
|
687
|
+
* @generated - DO NOT EDIT MANUALLY
|
|
688
|
+
*/
|
|
689
|
+
const worklistsContract = contract({
|
|
690
|
+
/**
|
|
691
|
+
* GET ATC worklist
|
|
692
|
+
*/
|
|
693
|
+
get: (worklistId, params) => http$1.get(`/sap/bc/adt/atc/worklists/${worklistId}`, {
|
|
694
|
+
query: params,
|
|
695
|
+
responses: { 200: atcworklist },
|
|
696
|
+
headers: { Accept: "*/*" }
|
|
697
|
+
}),
|
|
698
|
+
/**
|
|
699
|
+
* GET ATC worklist
|
|
700
|
+
*/
|
|
701
|
+
objectset: (worklistId, objectSetName, params) => http$1.get(`/sap/bc/adt/atc/worklists/${worklistId}/${objectSetName}`, {
|
|
702
|
+
query: params,
|
|
703
|
+
responses: { 200: atcworklist },
|
|
704
|
+
headers: { Accept: "*/*" }
|
|
705
|
+
})
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
//#endregion
|
|
709
|
+
//#region src/generated/adt/sap/bc/adt/atc/results.ts
|
|
710
|
+
/**
|
|
711
|
+
* ATC results
|
|
712
|
+
*
|
|
713
|
+
* Endpoint: /sap/bc/adt/atc/results
|
|
714
|
+
* Category: atcresults
|
|
715
|
+
*
|
|
716
|
+
* @generated - DO NOT EDIT MANUALLY
|
|
717
|
+
*/
|
|
718
|
+
const resultsContract = contract({
|
|
719
|
+
/**
|
|
720
|
+
* GET ATC results
|
|
721
|
+
*/
|
|
722
|
+
active: (params) => http$1.get("/sap/bc/adt/atc/results", {
|
|
723
|
+
query: params,
|
|
724
|
+
responses: { 200: atcworklist },
|
|
725
|
+
headers: { Accept: "application/xml" }
|
|
726
|
+
}),
|
|
727
|
+
/**
|
|
728
|
+
* GET ATC results
|
|
729
|
+
*/
|
|
730
|
+
activeforsysid: (params) => http$1.get("/sap/bc/adt/atc/results", {
|
|
731
|
+
query: params,
|
|
732
|
+
responses: { 200: atcworklist },
|
|
733
|
+
headers: { Accept: "application/xml" }
|
|
734
|
+
}),
|
|
735
|
+
/**
|
|
736
|
+
* GET ATC results
|
|
737
|
+
*/
|
|
738
|
+
user: (params) => http$1.get("/sap/bc/adt/atc/results", {
|
|
739
|
+
query: params,
|
|
740
|
+
responses: { 200: atcworklist },
|
|
741
|
+
headers: { Accept: "application/xml" }
|
|
742
|
+
}),
|
|
743
|
+
/**
|
|
744
|
+
* GET ATC results
|
|
745
|
+
*/
|
|
746
|
+
central: (params) => http$1.get("/sap/bc/adt/atc/results", {
|
|
747
|
+
query: params,
|
|
748
|
+
responses: { 200: atcworklist },
|
|
749
|
+
headers: { Accept: "application/xml" }
|
|
750
|
+
}),
|
|
751
|
+
/**
|
|
752
|
+
* GET ATC results
|
|
753
|
+
*/
|
|
754
|
+
centralforsysid: (params) => http$1.get("/sap/bc/adt/atc/results", {
|
|
755
|
+
query: params,
|
|
756
|
+
responses: { 200: atcworklist },
|
|
757
|
+
headers: { Accept: "application/xml" }
|
|
758
|
+
}),
|
|
759
|
+
/**
|
|
760
|
+
* GET ATC results
|
|
761
|
+
*/
|
|
762
|
+
displayid: (displayId, params) => http$1.get(`/sap/bc/adt/atc/results/${displayId}`, {
|
|
763
|
+
query: params,
|
|
764
|
+
responses: { 200: atcworklist },
|
|
765
|
+
headers: { Accept: "application/xml" }
|
|
766
|
+
})
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
//#endregion
|
|
770
|
+
//#region src/adt/atc/index.ts
|
|
771
|
+
/**
|
|
772
|
+
* ADT ATC (ABAP Test Cockpit) Contracts
|
|
773
|
+
*
|
|
774
|
+
* Combines generated contracts with manually-defined endpoints not in discovery.
|
|
775
|
+
*
|
|
776
|
+
* Structure mirrors URL tree:
|
|
777
|
+
* - /sap/bc/adt/atc/customizing → atc.customizing (manual - not in discovery)
|
|
778
|
+
* - /sap/bc/adt/atc/runs → atc.runs (manual - POST with body)
|
|
779
|
+
* - /sap/bc/adt/atc/results → atc.results (generated)
|
|
780
|
+
* - /sap/bc/adt/atc/worklists → atc.worklists (generated + manual create)
|
|
781
|
+
*/
|
|
782
|
+
/**
|
|
783
|
+
* /sap/bc/adt/atc/customizing
|
|
784
|
+
* Get ATC customizing settings (check variants, exemption reasons, etc.)
|
|
785
|
+
*
|
|
786
|
+
* NOTE: Not in SAP discovery - manually defined
|
|
787
|
+
*/
|
|
788
|
+
const customizing = contract({
|
|
789
|
+
/**
|
|
790
|
+
* GET /sap/bc/adt/atc/customizing
|
|
791
|
+
*/
|
|
792
|
+
get: () => http$1.get("/sap/bc/adt/atc/customizing", {
|
|
793
|
+
responses: { 200: atc },
|
|
794
|
+
headers: { Accept: "application/xml" }
|
|
795
|
+
}) });
|
|
796
|
+
/**
|
|
797
|
+
* /sap/bc/adt/atc/runs
|
|
798
|
+
*
|
|
799
|
+
* NOTE: POST endpoint with body - not in SAP discovery
|
|
800
|
+
* @source atcruns.json
|
|
801
|
+
*/
|
|
802
|
+
const runs = contract({
|
|
803
|
+
/**
|
|
804
|
+
* POST /sap/bc/adt/atc/runs{?worklistId,clientWait}
|
|
805
|
+
* Run ATC checks on objects specified in the request body
|
|
806
|
+
*/
|
|
807
|
+
post: (params) => http$1.post("/sap/bc/adt/atc/runs", {
|
|
808
|
+
query: params,
|
|
809
|
+
body: atcRun,
|
|
810
|
+
responses: { 200: atcworklist },
|
|
811
|
+
headers: {
|
|
812
|
+
Accept: "application/xml",
|
|
813
|
+
"Content-Type": "application/xml"
|
|
814
|
+
}
|
|
815
|
+
}) });
|
|
816
|
+
/**
|
|
817
|
+
* /sap/bc/adt/atc/worklists - Extended
|
|
818
|
+
*
|
|
819
|
+
* Adds POST (create) endpoint not in generated contract
|
|
820
|
+
*/
|
|
821
|
+
const worklistsExtended = contract({
|
|
822
|
+
/**
|
|
823
|
+
* POST /sap/bc/adt/atc/worklists{?checkVariant}
|
|
824
|
+
* Create a new ATC worklist
|
|
825
|
+
*
|
|
826
|
+
* NOTE: Not in SAP discovery - manually defined
|
|
827
|
+
*/
|
|
828
|
+
create: (params) => http$1.post("/sap/bc/adt/atc/worklists", {
|
|
829
|
+
query: params,
|
|
830
|
+
responses: { 200: atcworklist },
|
|
831
|
+
headers: { Accept: "*/*" }
|
|
832
|
+
}) });
|
|
833
|
+
/**
|
|
834
|
+
* Combined ATC contract
|
|
835
|
+
*
|
|
836
|
+
* Uses generated contracts where available, adds manual endpoints for:
|
|
837
|
+
* - customizing (not in discovery)
|
|
838
|
+
* - runs POST (not in discovery)
|
|
839
|
+
* - worklists.create (not in discovery)
|
|
840
|
+
*/
|
|
841
|
+
const atcContract = {
|
|
842
|
+
customizing,
|
|
843
|
+
runs,
|
|
844
|
+
results: resultsContract,
|
|
845
|
+
worklists: {
|
|
846
|
+
...worklistsContract,
|
|
847
|
+
...worklistsExtended
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
//#endregion
|
|
852
|
+
//#region src/adt/aunit/index.ts
|
|
853
|
+
/**
|
|
854
|
+
* ADT AUnit (ABAP Unit) Contracts
|
|
855
|
+
*
|
|
856
|
+
* Manually-defined endpoints for ABAP Unit test runs.
|
|
857
|
+
*
|
|
858
|
+
* Structure mirrors URL tree:
|
|
859
|
+
* - /sap/bc/adt/abapunit/testruns → aunit.testruns (POST with body)
|
|
860
|
+
*/
|
|
861
|
+
/**
|
|
862
|
+
* /sap/bc/adt/abapunit/testruns
|
|
863
|
+
*
|
|
864
|
+
* Run ABAP Unit tests on objects specified in the request body.
|
|
865
|
+
*
|
|
866
|
+
* NOTE: Not in SAP discovery - manually defined
|
|
867
|
+
*/
|
|
868
|
+
const testruns = contract({
|
|
869
|
+
/**
|
|
870
|
+
* POST /sap/bc/adt/abapunit/testruns
|
|
871
|
+
* Execute ABAP Unit test run with a runConfiguration body
|
|
872
|
+
*
|
|
873
|
+
* @returns runResult with programs, test classes, methods, and alerts
|
|
874
|
+
*/
|
|
875
|
+
post: () => http$1.post("/sap/bc/adt/abapunit/testruns", {
|
|
876
|
+
body: aunitRun,
|
|
877
|
+
responses: { 200: aunitResult },
|
|
878
|
+
headers: {
|
|
879
|
+
Accept: "application/vnd.sap.adt.abapunit.testruns.result.v2+xml",
|
|
880
|
+
"Content-Type": "application/vnd.sap.adt.abapunit.testruns.config.v4+xml"
|
|
881
|
+
}
|
|
882
|
+
}) });
|
|
883
|
+
/**
|
|
884
|
+
* Combined AUnit contract
|
|
885
|
+
*/
|
|
886
|
+
const aunitContract = { testruns };
|
|
887
|
+
|
|
888
|
+
//#endregion
|
|
889
|
+
//#region src/adt/oo/classes.ts
|
|
890
|
+
/**
|
|
891
|
+
* ADT OO Classes Contract
|
|
892
|
+
*
|
|
893
|
+
* Endpoint: /sap/bc/adt/oo/classes
|
|
894
|
+
* Full CRUD operations for ABAP classes including source code management.
|
|
895
|
+
*
|
|
896
|
+
* Uses the crud() helper with sources and includes options for complete
|
|
897
|
+
* class operations including metadata, source code, and class includes.
|
|
898
|
+
*/
|
|
899
|
+
/**
|
|
900
|
+
* /sap/bc/adt/oo/classes
|
|
901
|
+
* Full CRUD operations for ABAP classes
|
|
902
|
+
*
|
|
903
|
+
* Includes:
|
|
904
|
+
* - Basic CRUD: get, post, put, delete
|
|
905
|
+
* - Lock/Unlock: lock, unlock
|
|
906
|
+
* - Object structure: objectstructure
|
|
907
|
+
* - Source code: source.main.get/put
|
|
908
|
+
* - Class includes: includes.{definitions,implementations,macros,testclasses,localtypes}.get/put
|
|
909
|
+
*/
|
|
910
|
+
const classesContract = crud({
|
|
911
|
+
basePath: "/sap/bc/adt/oo/classes",
|
|
912
|
+
schema: classes,
|
|
913
|
+
contentType: "application/vnd.sap.adt.oo.classes.v4+xml",
|
|
914
|
+
accept: "application/vnd.sap.adt.oo.classes.v4+xml, application/vnd.sap.adt.oo.classes.v3+xml, application/vnd.sap.adt.oo.classes.v2+xml, application/vnd.sap.adt.oo.classes.v1+xml",
|
|
915
|
+
sources: ["main"],
|
|
916
|
+
includes: [
|
|
917
|
+
"definitions",
|
|
918
|
+
"implementations",
|
|
919
|
+
"macros",
|
|
920
|
+
"testclasses",
|
|
921
|
+
"localtypes"
|
|
922
|
+
]
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
//#endregion
|
|
926
|
+
//#region src/adt/oo/interfaces.ts
|
|
927
|
+
/**
|
|
928
|
+
* ADT OO Interfaces Contract
|
|
929
|
+
*
|
|
930
|
+
* Endpoint: /sap/bc/adt/oo/interfaces
|
|
931
|
+
* Full CRUD operations for ABAP interfaces including source code management.
|
|
932
|
+
*
|
|
933
|
+
* Uses the crud() helper with sources option for complete
|
|
934
|
+
* interface operations including metadata and source code.
|
|
935
|
+
*/
|
|
936
|
+
/**
|
|
937
|
+
* /sap/bc/adt/oo/interfaces
|
|
938
|
+
* Full CRUD operations for ABAP interfaces
|
|
939
|
+
*
|
|
940
|
+
* Includes:
|
|
941
|
+
* - Basic CRUD: get, post, put, delete
|
|
942
|
+
* - Lock/Unlock: lock, unlock
|
|
943
|
+
* - Object structure: objectstructure
|
|
944
|
+
* - Source code: source.main.get/put
|
|
945
|
+
*/
|
|
946
|
+
const interfacesContract = crud({
|
|
947
|
+
basePath: "/sap/bc/adt/oo/interfaces",
|
|
948
|
+
schema: interfaces,
|
|
949
|
+
contentType: "application/vnd.sap.adt.oo.interfaces.v5+xml",
|
|
950
|
+
accept: "application/vnd.sap.adt.oo.interfaces.v5+xml, application/vnd.sap.adt.oo.interfaces.v4+xml, application/vnd.sap.adt.oo.interfaces.v3+xml, application/vnd.sap.adt.oo.interfaces.v2+xml, application/vnd.sap.adt.oo.interfaces+xml",
|
|
951
|
+
sources: ["main"]
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
//#endregion
|
|
955
|
+
//#region src/adt/oo/classrun.ts
|
|
956
|
+
/**
|
|
957
|
+
* ADT OO Classrun Contract
|
|
958
|
+
*
|
|
959
|
+
* Endpoint: /sap/bc/adt/oo/classrun
|
|
960
|
+
* Execute console application classes implementing IF_OO_ADT_CLASSRUN.
|
|
961
|
+
*/
|
|
962
|
+
/**
|
|
963
|
+
* /sap/bc/adt/oo/classrun
|
|
964
|
+
* Execute console application classes (IF_OO_ADT_CLASSRUN)
|
|
965
|
+
*/
|
|
966
|
+
const classrunContract = contract({
|
|
967
|
+
/**
|
|
968
|
+
* POST /sap/bc/adt/oo/classrun/{classname}{?profilerId}
|
|
969
|
+
* Execute a class implementing IF_OO_ADT_CLASSRUN
|
|
970
|
+
*/
|
|
971
|
+
post: (classname, params) => http$1.post(`/sap/bc/adt/oo/classrun/${classname.toLowerCase()}`, {
|
|
972
|
+
query: params,
|
|
973
|
+
responses: { 200: void 0 },
|
|
974
|
+
headers: { Accept: "text/plain" }
|
|
975
|
+
}) });
|
|
976
|
+
|
|
977
|
+
//#endregion
|
|
978
|
+
//#region src/adt/oo/index.ts
|
|
979
|
+
const ooContract = {
|
|
980
|
+
classes: classesContract,
|
|
981
|
+
interfaces: interfacesContract,
|
|
982
|
+
classrun: classrunContract
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
//#endregion
|
|
986
|
+
//#region src/adt/discovery/index.ts
|
|
987
|
+
/**
|
|
988
|
+
* ADT Discovery Contract
|
|
989
|
+
*
|
|
990
|
+
* Endpoint: GET /sap/bc/adt/discovery
|
|
991
|
+
* Returns AtomPub service document describing available ADT services.
|
|
992
|
+
*/
|
|
993
|
+
const discoveryContract = {
|
|
994
|
+
/**
|
|
995
|
+
* Get Discovery Information
|
|
996
|
+
*
|
|
997
|
+
* Returns the ADT service discovery document in AtomPub format.
|
|
998
|
+
* This document describes all available ADT services, workspaces, and collections.
|
|
999
|
+
*
|
|
1000
|
+
* @endpoint GET /sap/bc/adt/discovery
|
|
1001
|
+
* @returns AtomPub service document with workspace and collection information
|
|
1002
|
+
*/
|
|
1003
|
+
getDiscovery: () => http$1.get("/sap/bc/adt/discovery", {
|
|
1004
|
+
responses: { 200: discovery },
|
|
1005
|
+
headers: { Accept: "application/atomsvc+xml" }
|
|
1006
|
+
}) };
|
|
1007
|
+
|
|
1008
|
+
//#endregion
|
|
1009
|
+
//#region src/adt/packages/index.ts
|
|
1010
|
+
/**
|
|
1011
|
+
* /sap/bc/adt/packages/**
|
|
1012
|
+
* ADT Packages Contract
|
|
1013
|
+
*
|
|
1014
|
+
* Full CRUD operations for ABAP packages (DEVC).
|
|
1015
|
+
*
|
|
1016
|
+
* Uses the crud() helper with packagesV1 schema.
|
|
1017
|
+
* Package names are case-sensitive (uppercase) — no lowercase transform.
|
|
1018
|
+
*
|
|
1019
|
+
* @example
|
|
1020
|
+
* const pkg = await client.adt.packages.get('ZABAPGIT_EXAMPLES');
|
|
1021
|
+
* console.log(pkg.package?.name, pkg.package?.attributes?.packageType);
|
|
1022
|
+
*
|
|
1023
|
+
* // Create a new package
|
|
1024
|
+
* await client.adt.packages.post({ corrNr: 'DEVK900001' });
|
|
1025
|
+
*/
|
|
1026
|
+
const packageCrudContract = crud({
|
|
1027
|
+
basePath: "/sap/bc/adt/packages",
|
|
1028
|
+
schema: packagesV1,
|
|
1029
|
+
contentType: "application/vnd.sap.adt.packages.v2+xml",
|
|
1030
|
+
accept: "application/vnd.sap.adt.packages.v2+xml, application/vnd.sap.adt.packages.v1+xml",
|
|
1031
|
+
nameTransform: (n) => encodeURIComponent(n)
|
|
1032
|
+
});
|
|
1033
|
+
/**
|
|
1034
|
+
* Typed package operations which are not CRUD-shaped. The discovery document
|
|
1035
|
+
* advertises this as `/sap/bc/adt/packages/$tree{?packagename,type}`.
|
|
1036
|
+
*/
|
|
1037
|
+
const packagesContract = contract({
|
|
1038
|
+
...packageCrudContract,
|
|
1039
|
+
tree: (params) => http$1.get("/sap/bc/adt/packages/$tree", {
|
|
1040
|
+
query: params,
|
|
1041
|
+
responses: { 200: packagesV1 },
|
|
1042
|
+
headers: { Accept: "application/vnd.sap.adt.packages.v2+xml" }
|
|
1043
|
+
})
|
|
1044
|
+
});
|
|
1045
|
+
|
|
1046
|
+
//#endregion
|
|
1047
|
+
//#region src/adt/core/http/sessions.ts
|
|
1048
|
+
/**
|
|
1049
|
+
* SAP ADT Sessions Contract
|
|
1050
|
+
*
|
|
1051
|
+
* HTTP session management and CSRF token initialization.
|
|
1052
|
+
* Path: /sap/bc/adt/core/http/sessions
|
|
1053
|
+
*/
|
|
1054
|
+
const sessionsContract = {
|
|
1055
|
+
/**
|
|
1056
|
+
* Get or create an HTTP session
|
|
1057
|
+
* Also initializes CSRF token for subsequent requests
|
|
1058
|
+
*
|
|
1059
|
+
* Uses x-sap-security-session: create to establish a proper security session.
|
|
1060
|
+
* All subsequent operations should use x-sap-security-session: use to stay
|
|
1061
|
+
* within the same security session (required for lock/unlock).
|
|
1062
|
+
*
|
|
1063
|
+
* @returns Session information with CSRF token and links
|
|
1064
|
+
*/
|
|
1065
|
+
getSession: () => http$1.get("/sap/bc/adt/core/http/sessions", {
|
|
1066
|
+
responses: { 200: http$2 },
|
|
1067
|
+
headers: {
|
|
1068
|
+
Accept: "application/vnd.sap.adt.core.http.session.v3+xml",
|
|
1069
|
+
"x-csrf-token": "Fetch",
|
|
1070
|
+
"X-sap-adt-sessiontype": "stateful",
|
|
1071
|
+
"x-sap-security-session": "create"
|
|
1072
|
+
}
|
|
1073
|
+
}) };
|
|
1074
|
+
|
|
1075
|
+
//#endregion
|
|
1076
|
+
//#region src/adt/core/http/systeminformation.ts
|
|
1077
|
+
/**
|
|
1078
|
+
* SAP ADT System Information Contract
|
|
1079
|
+
*
|
|
1080
|
+
* Returns system information including SAP release, client, user details.
|
|
1081
|
+
* Path: /sap/bc/adt/core/http/systeminformation
|
|
1082
|
+
*/
|
|
1083
|
+
const systeminformationContract = contract({
|
|
1084
|
+
/**
|
|
1085
|
+
* Get system information
|
|
1086
|
+
*
|
|
1087
|
+
* @returns System information (systemID, client, userName, etc.)
|
|
1088
|
+
*/
|
|
1089
|
+
getSystemInfo: () => http$1.get("/sap/bc/adt/core/http/systeminformation", {
|
|
1090
|
+
responses: { 200: systeminformation },
|
|
1091
|
+
headers: { Accept: "application/vnd.sap.adt.core.http.systeminformation.v1+json" }
|
|
1092
|
+
}) });
|
|
1093
|
+
|
|
1094
|
+
//#endregion
|
|
1095
|
+
//#region src/adt/core/http/index.ts
|
|
1096
|
+
const httpContract = {
|
|
1097
|
+
sessions: sessionsContract,
|
|
1098
|
+
systeminformation: systeminformationContract
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1101
|
+
//#endregion
|
|
1102
|
+
//#region src/adt/core/index.ts
|
|
1103
|
+
const coreContract = { http: httpContract };
|
|
1104
|
+
|
|
1105
|
+
//#endregion
|
|
1106
|
+
//#region src/adt/repository/informationsystem/search.ts
|
|
1107
|
+
/**
|
|
1108
|
+
* ADT Repository Information System - Search Contract
|
|
1109
|
+
*
|
|
1110
|
+
* ABAP object search operations.
|
|
1111
|
+
* Path: /sap/bc/adt/repository/informationsystem/search
|
|
1112
|
+
*/
|
|
1113
|
+
const searchContract = {
|
|
1114
|
+
/**
|
|
1115
|
+
* Quick search for ABAP objects
|
|
1116
|
+
*
|
|
1117
|
+
* @param query - Search query (supports wildcards like *)
|
|
1118
|
+
* @param maxResults - Maximum number of results (default: 50)
|
|
1119
|
+
* @param packageName - Filter by package name
|
|
1120
|
+
* @param objectType - Filter by object type (e.g., 'CLAS', 'INTF')
|
|
1121
|
+
* @returns Object references matching the search query (union of all adtcore element types)
|
|
1122
|
+
*
|
|
1123
|
+
* @example
|
|
1124
|
+
* // Search for classes starting with ZCL
|
|
1125
|
+
* const results = await client.repository.informationsystem.search.quickSearch({
|
|
1126
|
+
* query: 'zcl*',
|
|
1127
|
+
* maxResults: 10
|
|
1128
|
+
* });
|
|
1129
|
+
*
|
|
1130
|
+
* @example
|
|
1131
|
+
* // List all objects in a package
|
|
1132
|
+
* const results = await client.repository.informationsystem.search.quickSearch({
|
|
1133
|
+
* query: '*',
|
|
1134
|
+
* packageName: 'ZABAPGIT_EXAMPLES',
|
|
1135
|
+
* maxResults: 200
|
|
1136
|
+
* });
|
|
1137
|
+
*/
|
|
1138
|
+
quickSearch: (options) => http$1.get("/sap/bc/adt/repository/informationsystem/search", {
|
|
1139
|
+
query: {
|
|
1140
|
+
operation: "quickSearch",
|
|
1141
|
+
query: options.query,
|
|
1142
|
+
maxResults: options.maxResults || 50,
|
|
1143
|
+
...options.packageName && { packageName: options.packageName },
|
|
1144
|
+
...options.objectType && { objectType: options.objectType }
|
|
1145
|
+
},
|
|
1146
|
+
responses: { 200: adtcore },
|
|
1147
|
+
headers: { Accept: "application/xml" }
|
|
1148
|
+
}) };
|
|
1149
|
+
|
|
1150
|
+
//#endregion
|
|
1151
|
+
//#region src/adt/repository/informationsystem/usagereferences.ts
|
|
1152
|
+
/**
|
|
1153
|
+
* ADT Repository Information System – Usage References (Where-Used List)
|
|
1154
|
+
*
|
|
1155
|
+
* The SAP ADT "where-used" service is NOT a simple GET — it is a two-step
|
|
1156
|
+
* POST flow discovered via sapcli (`sap/adt/whereused.py`) and confirmed
|
|
1157
|
+
* against a real TRL ABAP trial system:
|
|
1158
|
+
*
|
|
1159
|
+
* 1. POST /sap/bc/adt/repository/informationsystem/usageReferences/scope
|
|
1160
|
+
* + query: uri=<objectUri>&version=active
|
|
1161
|
+
* + Content-Type: application/vnd.sap.adt.repository.usagereferences.scope.request.v1+xml
|
|
1162
|
+
* + Accept: application/vnd.sap.adt.repository.usagereferences.scope.response.v1+xml
|
|
1163
|
+
* + body: <usagereferences:usageScopeRequest>…</>
|
|
1164
|
+
* → returns a <usagereferences:usageScopeResult> containing the
|
|
1165
|
+
* backend-chosen object types, grade flags and an opaque `payload`
|
|
1166
|
+
* blob (gzip-encoded) that must be echoed back in step 2.
|
|
1167
|
+
*
|
|
1168
|
+
* 2. POST /sap/bc/adt/repository/informationsystem/usageReferences
|
|
1169
|
+
* + query: uri=<objectUri>&version=active
|
|
1170
|
+
* + Content-Type: application/vnd.sap.adt.repository.usagereferences.request.v1+xml
|
|
1171
|
+
* + Accept: application/vnd.sap.adt.repository.usagereferences.result.v1+xml
|
|
1172
|
+
* + body: <usagereferences:usageReferenceRequest>
|
|
1173
|
+
* <usagereferences:affectedObjects/>
|
|
1174
|
+
* <usagereferences:scope>…copy from step 1 result…</>
|
|
1175
|
+
* </>
|
|
1176
|
+
* → returns a <usagereferences:usageReferenceResult> with all hits.
|
|
1177
|
+
*
|
|
1178
|
+
* Body/response are passed as plain-text XML because the usagereferences
|
|
1179
|
+
* namespace is not yet represented as a typed `adt-schemas` XSD. Callers
|
|
1180
|
+
* parse the response themselves (see `find-references` MCP tool).
|
|
1181
|
+
*/
|
|
1182
|
+
/** Vendor MIME types — must match real SAP verbatim. */
|
|
1183
|
+
const SCOPE_REQUEST_MIME = "application/vnd.sap.adt.repository.usagereferences.scope.request.v1+xml";
|
|
1184
|
+
const SCOPE_RESPONSE_MIME = "application/vnd.sap.adt.repository.usagereferences.scope.response.v1+xml";
|
|
1185
|
+
const SEARCH_REQUEST_MIME = "application/vnd.sap.adt.repository.usagereferences.request.v1+xml";
|
|
1186
|
+
const SEARCH_RESPONSE_MIME = "application/vnd.sap.adt.repository.usagereferences.result.v1+xml";
|
|
1187
|
+
const USAGEREFS_NAMESPACE = "http://www.sap.com/adt/ris/usageReferences";
|
|
1188
|
+
/**
|
|
1189
|
+
* Build the XML body for the step-1 scope request. sapcli always sends
|
|
1190
|
+
* an empty `<affectedObjects/>`; the backend doesn't inspect its content
|
|
1191
|
+
* and populates the result from the URI query parameter.
|
|
1192
|
+
*/
|
|
1193
|
+
function buildUsageScopeRequestXml() {
|
|
1194
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1195
|
+
<usagereferences:usageScopeRequest xmlns:usagereferences="${USAGEREFS_NAMESPACE}">\n <usagereferences:affectedObjects/>
|
|
1196
|
+
</usagereferences:usageScopeRequest>`;
|
|
1197
|
+
}
|
|
1198
|
+
/**
|
|
1199
|
+
* Build the XML body for the step-2 search request by wrapping the raw
|
|
1200
|
+
* step-1 scope-result XML as a `<usagereferences:scope>` element inside
|
|
1201
|
+
* a `<usageReferenceRequest>`.
|
|
1202
|
+
*
|
|
1203
|
+
* We deliberately do string surgery instead of DOM manipulation because
|
|
1204
|
+
* the `payload` element contains base64-gzip content we must not perturb.
|
|
1205
|
+
*/
|
|
1206
|
+
function buildUsageReferenceRequestXml(scopeResultXml) {
|
|
1207
|
+
let noProlog = scopeResultXml;
|
|
1208
|
+
if (noProlog.startsWith("<?xml")) {
|
|
1209
|
+
const prologEnd = noProlog.indexOf("?>");
|
|
1210
|
+
if (prologEnd !== -1) noProlog = noProlog.slice(prologEnd + 2).replace(/^\s+/, "");
|
|
1211
|
+
}
|
|
1212
|
+
const scopeElement = noProlog.replaceAll(/usagereferences:usageScopeResult/g, "usagereferences:scope");
|
|
1213
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1214
|
+
<usagereferences:usageReferenceRequest xmlns:usagereferences="${USAGEREFS_NAMESPACE}">\n <usagereferences:affectedObjects/>
|
|
1215
|
+
${scopeElement}\n</usagereferences:usageReferenceRequest>`;
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Step 1: fetch the default scope for a given object URI.
|
|
1219
|
+
*
|
|
1220
|
+
* Typed body/response are plain XML strings — the contract provides
|
|
1221
|
+
* URL/header/method shape, callers provide the marshalled body via
|
|
1222
|
+
* {@link buildUsageScopeRequestXml}.
|
|
1223
|
+
*/
|
|
1224
|
+
const scope = contract({ post: (params) => http$1.post("/sap/bc/adt/repository/informationsystem/usageReferences/scope", {
|
|
1225
|
+
query: {
|
|
1226
|
+
uri: params.uri,
|
|
1227
|
+
version: params.version ?? "active"
|
|
1228
|
+
},
|
|
1229
|
+
body: textPlain,
|
|
1230
|
+
responses: { 200: void 0 },
|
|
1231
|
+
headers: {
|
|
1232
|
+
Accept: SCOPE_RESPONSE_MIME,
|
|
1233
|
+
"Content-Type": SCOPE_REQUEST_MIME
|
|
1234
|
+
}
|
|
1235
|
+
}) });
|
|
1236
|
+
/**
|
|
1237
|
+
* Step 2: execute the where-used search using the scope blob from step 1.
|
|
1238
|
+
*/
|
|
1239
|
+
const search = contract({ post: (params) => http$1.post("/sap/bc/adt/repository/informationsystem/usageReferences", {
|
|
1240
|
+
query: {
|
|
1241
|
+
uri: params.uri,
|
|
1242
|
+
version: params.version ?? "active"
|
|
1243
|
+
},
|
|
1244
|
+
body: textPlain,
|
|
1245
|
+
responses: { 200: void 0 },
|
|
1246
|
+
headers: {
|
|
1247
|
+
Accept: SEARCH_RESPONSE_MIME,
|
|
1248
|
+
"Content-Type": SEARCH_REQUEST_MIME
|
|
1249
|
+
}
|
|
1250
|
+
}) });
|
|
1251
|
+
const usageReferencesContract = {
|
|
1252
|
+
scope,
|
|
1253
|
+
search
|
|
1254
|
+
};
|
|
1255
|
+
|
|
1256
|
+
//#endregion
|
|
1257
|
+
//#region src/adt/repository/sourceversions.ts
|
|
1258
|
+
/**
|
|
1259
|
+
* ADT Repository source-history contracts.
|
|
1260
|
+
*
|
|
1261
|
+
* Both operations follow URIs supplied by SAP ADT responses. They deliberately
|
|
1262
|
+
* do not construct version paths from an object URI.
|
|
1263
|
+
*/
|
|
1264
|
+
const ADT_ORIGIN = "https://adt.invalid";
|
|
1265
|
+
const ADT_PATH = "/sap/bc/adt";
|
|
1266
|
+
const INVALID_URI_MESSAGE = "Expected an ADT-relative URI under /sap/bc/adt";
|
|
1267
|
+
/**
|
|
1268
|
+
* Guard an opaque ADT URI supplied by SAP before we turn it into an
|
|
1269
|
+
* authenticated request. Other contracts which accept SAP-discovered URIs
|
|
1270
|
+
* share this boundary rather than reimplementing a slightly different URL
|
|
1271
|
+
* policy.
|
|
1272
|
+
*/
|
|
1273
|
+
function assertAdtRelativeUri(uri) {
|
|
1274
|
+
let parsed;
|
|
1275
|
+
try {
|
|
1276
|
+
parsed = new URL(uri, ADT_ORIGIN);
|
|
1277
|
+
} catch {
|
|
1278
|
+
throw new TypeError(INVALID_URI_MESSAGE);
|
|
1279
|
+
}
|
|
1280
|
+
const isRootRelative = uri.startsWith("/") && !uri.startsWith("//");
|
|
1281
|
+
const isAdtPath = parsed.pathname === ADT_PATH || parsed.pathname.startsWith(`${ADT_PATH}/`);
|
|
1282
|
+
if (uri !== uri.trim() || !isRootRelative || parsed.origin !== ADT_ORIGIN || !isAdtPath || parsed.hash) throw new TypeError(INVALID_URI_MESSAGE);
|
|
1283
|
+
}
|
|
1284
|
+
const sourceversionsContract = contract({
|
|
1285
|
+
list: (params) => {
|
|
1286
|
+
assertAdtRelativeUri(params.versionsUri);
|
|
1287
|
+
return http$1.get(params.versionsUri, {
|
|
1288
|
+
responses: { 200: atomFeed },
|
|
1289
|
+
headers: { Accept: "application/atom+xml;type=feed" }
|
|
1290
|
+
});
|
|
1291
|
+
},
|
|
1292
|
+
get: (params) => {
|
|
1293
|
+
assertAdtRelativeUri(params.sourceUri);
|
|
1294
|
+
return http$1.get(params.sourceUri, {
|
|
1295
|
+
responses: { 200: void 0 },
|
|
1296
|
+
headers: { Accept: "text/plain" }
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
});
|
|
1300
|
+
|
|
1301
|
+
//#endregion
|
|
1302
|
+
//#region src/adt/repository/informationsystem/objectproperties.ts
|
|
1303
|
+
/**
|
|
1304
|
+
* ADT Repository Information System — object properties.
|
|
1305
|
+
*
|
|
1306
|
+
* SAP supplies the canonical object URI through quick search or object
|
|
1307
|
+
* metadata. This endpoint enriches it with generic facets such as package
|
|
1308
|
+
* and application component; it does not construct an object-specific URL.
|
|
1309
|
+
*/
|
|
1310
|
+
const OBJECT_PROPERTIES_RESULT_MIME = "application/vnd.sap.adt.repository.objproperties.result.v1+xml";
|
|
1311
|
+
const objectPropertiesContract = { values: (params) => {
|
|
1312
|
+
assertAdtRelativeUri(params.uri);
|
|
1313
|
+
const facets = [...new Set(params.facets ?? [])].filter((facet) => facet.trim().length > 0);
|
|
1314
|
+
return http$1.get("/sap/bc/adt/repository/informationsystem/objectproperties/values", {
|
|
1315
|
+
query: {
|
|
1316
|
+
uri: params.uri,
|
|
1317
|
+
...facets.length > 0 ? { facet: facets } : {}
|
|
1318
|
+
},
|
|
1319
|
+
responses: { 200: objectProperties },
|
|
1320
|
+
headers: { Accept: OBJECT_PROPERTIES_RESULT_MIME }
|
|
1321
|
+
});
|
|
1322
|
+
} };
|
|
1323
|
+
|
|
1324
|
+
//#endregion
|
|
1325
|
+
//#region src/adt/repository/informationsystem/index.ts
|
|
1326
|
+
const informationsystemContract = {
|
|
1327
|
+
search: searchContract,
|
|
1328
|
+
usageReferences: usageReferencesContract,
|
|
1329
|
+
objectProperties: objectPropertiesContract
|
|
1330
|
+
};
|
|
1331
|
+
|
|
1332
|
+
//#endregion
|
|
1333
|
+
//#region src/adt/repository/objectstructure.ts
|
|
1334
|
+
/**
|
|
1335
|
+
* ADT Repository – generic Object Structure endpoint.
|
|
1336
|
+
*
|
|
1337
|
+
* Most typed object contracts (`programs`, `classes`, …) already expose
|
|
1338
|
+
* their own `.objectstructure()` method via the CRUD helper. This
|
|
1339
|
+
* contract handles the *generic* case used by the workbench outline
|
|
1340
|
+
* CLI / MCP surfaces: an arbitrary object URI whose type does not have
|
|
1341
|
+
* a dedicated typed contract (e.g. DOMA, DTEL, DEVC, BDEF, SRVD, …).
|
|
1342
|
+
*
|
|
1343
|
+
* ADT endpoint:
|
|
1344
|
+
* GET {objectUri}/objectstructure?version=<active|inactive>
|
|
1345
|
+
*
|
|
1346
|
+
* The response shape varies wildly between object types, so the
|
|
1347
|
+
* returned type is `unknown` — callers handle downstream. Keeping this
|
|
1348
|
+
* as a typed contract (instead of a raw `client.fetch()` call) ensures
|
|
1349
|
+
* the generic outline path still goes through the contract layer.
|
|
1350
|
+
*/
|
|
1351
|
+
const objectstructureContract = contract({ get: (params) => http$1.get(`${params.objectUri}/objectstructure`, {
|
|
1352
|
+
query: { ...params.version ? { version: params.version } : {} },
|
|
1353
|
+
responses: { 200: void 0 },
|
|
1354
|
+
headers: { Accept: "application/json" }
|
|
1355
|
+
}) });
|
|
1356
|
+
|
|
1357
|
+
//#endregion
|
|
1358
|
+
//#region src/adt/repository/index.ts
|
|
1359
|
+
const repositoryContract = {
|
|
1360
|
+
informationsystem: informationsystemContract,
|
|
1361
|
+
objectstructure: objectstructureContract,
|
|
1362
|
+
sourceversions: sourceversionsContract
|
|
1363
|
+
};
|
|
1364
|
+
|
|
1365
|
+
//#endregion
|
|
1366
|
+
//#region src/adt/programs/programs.ts
|
|
1367
|
+
/**
|
|
1368
|
+
* ADT Programs Contract
|
|
1369
|
+
*
|
|
1370
|
+
* Endpoint: /sap/bc/adt/programs/programs
|
|
1371
|
+
* Full CRUD operations for ABAP programs including source code management.
|
|
1372
|
+
*/
|
|
1373
|
+
/**
|
|
1374
|
+
* /sap/bc/adt/programs/programs
|
|
1375
|
+
* Full CRUD operations for ABAP programs
|
|
1376
|
+
*
|
|
1377
|
+
* Includes:
|
|
1378
|
+
* - Basic CRUD: get, post, put, delete
|
|
1379
|
+
* - Lock/Unlock: lock, unlock
|
|
1380
|
+
* - Object structure: objectstructure
|
|
1381
|
+
* - Source code: source.main.get/put
|
|
1382
|
+
*/
|
|
1383
|
+
const programsContract = crud({
|
|
1384
|
+
basePath: "/sap/bc/adt/programs/programs",
|
|
1385
|
+
schema: programs,
|
|
1386
|
+
contentType: "application/vnd.sap.adt.programs.programs.v2+xml",
|
|
1387
|
+
accept: "application/vnd.sap.adt.programs.programs.v2+xml, application/vnd.sap.adt.programs.programs.v1+xml",
|
|
1388
|
+
sources: ["main"]
|
|
1389
|
+
});
|
|
1390
|
+
|
|
1391
|
+
//#endregion
|
|
1392
|
+
//#region src/adt/programs/includes.ts
|
|
1393
|
+
/**
|
|
1394
|
+
* ADT Program Includes Contract
|
|
1395
|
+
*
|
|
1396
|
+
* Endpoint: /sap/bc/adt/programs/includes
|
|
1397
|
+
* Full CRUD operations for ABAP program includes (PROG/I) including source
|
|
1398
|
+
* code management.
|
|
1399
|
+
*
|
|
1400
|
+
* Mirrors the shape of `programs.ts` but targets the `/programs/includes`
|
|
1401
|
+
* URL space and the `include:abapInclude` XML payload.
|
|
1402
|
+
*/
|
|
1403
|
+
/**
|
|
1404
|
+
* /sap/bc/adt/programs/includes
|
|
1405
|
+
* Full CRUD operations for ABAP program includes
|
|
1406
|
+
*
|
|
1407
|
+
* Includes:
|
|
1408
|
+
* - Basic CRUD: get, post, put, delete
|
|
1409
|
+
* - Lock/Unlock: lock, unlock
|
|
1410
|
+
* - Object structure: objectstructure
|
|
1411
|
+
* - Source code: source.main.get/put
|
|
1412
|
+
*
|
|
1413
|
+
* Content types follow the same "v2 preferred, v1 fallback" pattern SAP
|
|
1414
|
+
* uses for includes (observed from real responses; matches sapcli's
|
|
1415
|
+
* `sap.adt.programs.Include` OBJTYPE).
|
|
1416
|
+
*/
|
|
1417
|
+
const includesContract = crud({
|
|
1418
|
+
basePath: "/sap/bc/adt/programs/includes",
|
|
1419
|
+
schema: includes,
|
|
1420
|
+
contentType: "application/vnd.sap.adt.programs.includes.v2+xml",
|
|
1421
|
+
accept: "application/vnd.sap.adt.programs.includes.v2+xml, application/vnd.sap.adt.programs.includes.v1+xml, application/vnd.sap.adt.programs.includes+xml",
|
|
1422
|
+
sources: ["main"]
|
|
1423
|
+
});
|
|
1424
|
+
|
|
1425
|
+
//#endregion
|
|
1426
|
+
//#region src/adt/programs/index.ts
|
|
1427
|
+
const programsModuleContract = {
|
|
1428
|
+
programs: programsContract,
|
|
1429
|
+
includes: includesContract
|
|
1430
|
+
};
|
|
1431
|
+
|
|
1432
|
+
//#endregion
|
|
1433
|
+
//#region src/adt/functions/groups.ts
|
|
1434
|
+
/**
|
|
1435
|
+
* ADT Functions Groups Contract
|
|
1436
|
+
*
|
|
1437
|
+
* Endpoint: /sap/bc/adt/functions/groups
|
|
1438
|
+
* Full CRUD operations for ABAP function groups including source code management.
|
|
1439
|
+
*/
|
|
1440
|
+
/**
|
|
1441
|
+
* /sap/bc/adt/functions/groups
|
|
1442
|
+
* Full CRUD operations for ABAP function groups
|
|
1443
|
+
*
|
|
1444
|
+
* Includes:
|
|
1445
|
+
* - Basic CRUD: get, post, put, delete
|
|
1446
|
+
* - Lock/Unlock: lock, unlock
|
|
1447
|
+
* - Object structure: objectstructure
|
|
1448
|
+
* - Source code: source.main.get/put
|
|
1449
|
+
*/
|
|
1450
|
+
const functionGroupsContract = crud({
|
|
1451
|
+
basePath: "/sap/bc/adt/functions/groups",
|
|
1452
|
+
schema: groups$1,
|
|
1453
|
+
contentType: "application/vnd.sap.adt.functions.groups.v3+xml",
|
|
1454
|
+
accept: "application/vnd.sap.adt.functions.groups.v3+xml, application/vnd.sap.adt.functions.groups.v2+xml, application/vnd.sap.adt.functions.groups.v1+xml",
|
|
1455
|
+
sources: ["main"]
|
|
1456
|
+
});
|
|
1457
|
+
|
|
1458
|
+
//#endregion
|
|
1459
|
+
//#region src/adt/functions/fmodules.ts
|
|
1460
|
+
/**
|
|
1461
|
+
* ADT Function Modules Contract
|
|
1462
|
+
*
|
|
1463
|
+
* Endpoint: /sap/bc/adt/functions/groups/{groupName}/fmodules/{fmName}
|
|
1464
|
+
* Sub-resource of function groups.
|
|
1465
|
+
*
|
|
1466
|
+
* Function modules are child objects of function groups. They have their own
|
|
1467
|
+
* lock lifecycle, source code, and metadata but are accessed through the
|
|
1468
|
+
* parent group's URL path.
|
|
1469
|
+
*/
|
|
1470
|
+
const contentType$2 = "application/vnd.sap.adt.functions.fmodules.v3+xml";
|
|
1471
|
+
const accept$2 = "application/vnd.sap.adt.functions.fmodules.v3+xml, application/vnd.sap.adt.functions.fmodules.v2+xml, application/vnd.sap.adt.functions.fmodules.v1+xml";
|
|
1472
|
+
const basePath$4 = "/sap/bc/adt/functions/groups/${groupName}/fmodules";
|
|
1473
|
+
/**
|
|
1474
|
+
* /sap/bc/adt/functions/groups/{groupName}/fmodules
|
|
1475
|
+
* CRUD operations for function modules within a function group
|
|
1476
|
+
*/
|
|
1477
|
+
const functionModulesContract = contract({
|
|
1478
|
+
/** GET .../fmodules/{fmName} - Get function module metadata */
|
|
1479
|
+
get: (_groupName, _fmName) => http$1.get(basePath$4 + "/${fmName}", {
|
|
1480
|
+
responses: { 200: fmodules },
|
|
1481
|
+
headers: { Accept: accept$2 }
|
|
1482
|
+
}),
|
|
1483
|
+
/** POST .../fmodules - Create function module */
|
|
1484
|
+
post: (groupName, queryOptions) => http$1.post(basePath$4, {
|
|
1485
|
+
body: fmodules,
|
|
1486
|
+
responses: { 200: fmodules },
|
|
1487
|
+
headers: {
|
|
1488
|
+
Accept: accept$2,
|
|
1489
|
+
"Content-Type": contentType$2
|
|
1490
|
+
},
|
|
1491
|
+
query: queryOptions?.corrNr ? { corrNr: queryOptions.corrNr } : void 0
|
|
1492
|
+
}),
|
|
1493
|
+
/** PUT .../fmodules/{fmName} - Update function module metadata */
|
|
1494
|
+
put: (groupName, fmName, options) => http$1.put(basePath$4 + "/${fmName}", {
|
|
1495
|
+
body: fmodules,
|
|
1496
|
+
responses: { 200: fmodules },
|
|
1497
|
+
headers: {
|
|
1498
|
+
Accept: accept$2,
|
|
1499
|
+
"Content-Type": contentType$2
|
|
1500
|
+
},
|
|
1501
|
+
query: {
|
|
1502
|
+
...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
|
|
1503
|
+
...options?.corrNr ? { corrNr: options.corrNr } : {}
|
|
1504
|
+
}
|
|
1505
|
+
}),
|
|
1506
|
+
/** DELETE .../fmodules/{fmName} - Delete function module */
|
|
1507
|
+
delete: (groupName, fmName, options) => http$1.delete(basePath$4 + "/${fmName}", {
|
|
1508
|
+
responses: { 204: void 0 },
|
|
1509
|
+
query: {
|
|
1510
|
+
...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
|
|
1511
|
+
...options?.corrNr ? { corrNr: options.corrNr } : {}
|
|
1512
|
+
}
|
|
1513
|
+
}),
|
|
1514
|
+
/** POST .../fmodules/{fmName}?_action=LOCK - Lock function module */
|
|
1515
|
+
lock: (groupName, fmName, options) => http$1.post(basePath$4 + "/${fmName}", {
|
|
1516
|
+
responses: { 200: void 0 },
|
|
1517
|
+
headers: {
|
|
1518
|
+
"X-sap-adt-sessiontype": "stateful",
|
|
1519
|
+
"x-sap-security-session": "use",
|
|
1520
|
+
Accept: "application/*,application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.lock.result"
|
|
1521
|
+
},
|
|
1522
|
+
query: {
|
|
1523
|
+
_action: "LOCK",
|
|
1524
|
+
accessMode: options?.accessMode ?? "MODIFY",
|
|
1525
|
+
...options?.corrNr ? { corrNr: options.corrNr } : {}
|
|
1526
|
+
}
|
|
1527
|
+
}),
|
|
1528
|
+
/** POST .../fmodules/{fmName}?_action=UNLOCK - Unlock function module */
|
|
1529
|
+
unlock: (groupName, fmName, options) => http$1.post(basePath$4 + "/${fmName}", {
|
|
1530
|
+
responses: { 200: void 0 },
|
|
1531
|
+
headers: {
|
|
1532
|
+
"X-sap-adt-sessiontype": "stateful",
|
|
1533
|
+
"x-sap-security-session": "use"
|
|
1534
|
+
},
|
|
1535
|
+
query: {
|
|
1536
|
+
_action: "UNLOCK",
|
|
1537
|
+
accessMode: "MODIFY",
|
|
1538
|
+
lockHandle: options.lockHandle
|
|
1539
|
+
}
|
|
1540
|
+
}),
|
|
1541
|
+
/** Source code operations */
|
|
1542
|
+
source: { main: {
|
|
1543
|
+
/** GET .../fmodules/{fmName}/source/main - Get source code */
|
|
1544
|
+
get: (_groupName, _fmName) => http$1.get(basePath$4 + "/${fmName}/source/main", {
|
|
1545
|
+
responses: { 200: void 0 },
|
|
1546
|
+
headers: { Accept: "text/plain" }
|
|
1547
|
+
}),
|
|
1548
|
+
/** PUT .../fmodules/{fmName}/source/main - Update source code */
|
|
1549
|
+
put: (groupName, fmName, options) => http$1.put(basePath$4 + "/${fmName}/source/main", {
|
|
1550
|
+
body: textPlain,
|
|
1551
|
+
responses: { 200: void 0 },
|
|
1552
|
+
headers: {
|
|
1553
|
+
Accept: "text/plain",
|
|
1554
|
+
"Content-Type": "text/plain"
|
|
1555
|
+
},
|
|
1556
|
+
query: {
|
|
1557
|
+
...options?.lockHandle ? { lockHandle: options.lockHandle } : {},
|
|
1558
|
+
...options?.corrNr ? { corrNr: options.corrNr } : {}
|
|
1559
|
+
}
|
|
1560
|
+
})
|
|
1561
|
+
} }
|
|
1562
|
+
});
|
|
1563
|
+
|
|
1564
|
+
//#endregion
|
|
1565
|
+
//#region src/adt/functions/index.ts
|
|
1566
|
+
const functionsContract = { groups: {
|
|
1567
|
+
...functionGroupsContract,
|
|
1568
|
+
fmodules: functionModulesContract
|
|
1569
|
+
} };
|
|
1570
|
+
|
|
1571
|
+
//#endregion
|
|
1572
|
+
//#region src/adt/ddic/domains.ts
|
|
1573
|
+
/**
|
|
1574
|
+
* DDIC Domain Contract
|
|
1575
|
+
*
|
|
1576
|
+
* ADT endpoint: /sap/bc/adt/ddic/domains
|
|
1577
|
+
* Content-Type: application/vnd.sap.adt.domains.v2+xml
|
|
1578
|
+
* Object type: DOMA/DD (domadd)
|
|
1579
|
+
*/
|
|
1580
|
+
const domainsContract = crud({
|
|
1581
|
+
basePath: "/sap/bc/adt/ddic/domains",
|
|
1582
|
+
schema: domain,
|
|
1583
|
+
contentType: "application/vnd.sap.adt.domains.v2+xml",
|
|
1584
|
+
accept: "application/vnd.sap.adt.domains.v2+xml, application/vnd.sap.adt.domains.v1+xml"
|
|
1585
|
+
});
|
|
1586
|
+
|
|
1587
|
+
//#endregion
|
|
1588
|
+
//#region src/adt/ddic/dataelements.ts
|
|
1589
|
+
/**
|
|
1590
|
+
* DDIC Data Element Contract
|
|
1591
|
+
*
|
|
1592
|
+
* ADT endpoint: /sap/bc/adt/ddic/dataelements
|
|
1593
|
+
* Content-Type: application/vnd.sap.adt.dataelements.v2+xml
|
|
1594
|
+
* Object type: DTEL/DE (dtelde)
|
|
1595
|
+
*/
|
|
1596
|
+
const dataelementsContract = crud({
|
|
1597
|
+
basePath: "/sap/bc/adt/ddic/dataelements",
|
|
1598
|
+
schema: dataelementWrapper,
|
|
1599
|
+
contentType: "application/vnd.sap.adt.dataelements.v2+xml",
|
|
1600
|
+
accept: "application/vnd.sap.adt.dataelements.v2+xml, application/vnd.sap.adt.dataelements.v1+xml"
|
|
1601
|
+
});
|
|
1602
|
+
|
|
1603
|
+
//#endregion
|
|
1604
|
+
//#region src/adt/ddic/structures.ts
|
|
1605
|
+
/**
|
|
1606
|
+
* DDIC Structure Contract
|
|
1607
|
+
*
|
|
1608
|
+
* ADT endpoint: /sap/bc/adt/ddic/structures
|
|
1609
|
+
* Content-Type: application/vnd.sap.adt.structures.v2+xml
|
|
1610
|
+
* Object type: TABL/DS (tablds)
|
|
1611
|
+
*
|
|
1612
|
+
* Uses the custom blueSource wrapper schema because SAP wraps
|
|
1613
|
+
* structure responses in a blue:blueSource root element
|
|
1614
|
+
* (namespace http://www.sap.com/wbobj/blue) extending AbapSourceMainObject.
|
|
1615
|
+
*/
|
|
1616
|
+
const basePath$3 = "/sap/bc/adt/ddic/structures";
|
|
1617
|
+
const contentType$1 = "application/vnd.sap.adt.structures.v2+xml";
|
|
1618
|
+
const accept$1 = "application/vnd.sap.adt.structures.v2+xml, application/vnd.sap.adt.structures.v1+xml";
|
|
1619
|
+
const structuresContract = {
|
|
1620
|
+
...crud({
|
|
1621
|
+
basePath: basePath$3,
|
|
1622
|
+
schema: blueSource,
|
|
1623
|
+
contentType: contentType$1,
|
|
1624
|
+
accept: accept$1,
|
|
1625
|
+
sources: ["main"]
|
|
1626
|
+
}),
|
|
1627
|
+
objectstructure: (name, options) => http.get(`${basePath$3}/${name.toLowerCase()}/objectstructure`, {
|
|
1628
|
+
responses: { 200: void 0 },
|
|
1629
|
+
query: options?.version ? { version: options.version } : void 0
|
|
1630
|
+
})
|
|
1631
|
+
};
|
|
1632
|
+
|
|
1633
|
+
//#endregion
|
|
1634
|
+
//#region src/adt/ddic/tables.ts
|
|
1635
|
+
/**
|
|
1636
|
+
* DDIC Database Table Contract
|
|
1637
|
+
*
|
|
1638
|
+
* ADT endpoint: /sap/bc/adt/ddic/tables
|
|
1639
|
+
* Content-Type: application/vnd.sap.adt.tables.v2+xml
|
|
1640
|
+
* Object type: TABL/DT (tabldt)
|
|
1641
|
+
*
|
|
1642
|
+
* Uses the custom blueSource wrapper schema because SAP wraps
|
|
1643
|
+
* TABL responses in a blue:blueSource root element
|
|
1644
|
+
* (namespace http://www.sap.com/wbobj/blue) extending AbapSourceMainObject.
|
|
1645
|
+
*/
|
|
1646
|
+
const basePath$2 = "/sap/bc/adt/ddic/tables";
|
|
1647
|
+
const contentType = "application/vnd.sap.adt.tables.v2+xml";
|
|
1648
|
+
const accept = "application/vnd.sap.adt.blues.v1+xml, application/vnd.sap.adt.tables.v2+xml";
|
|
1649
|
+
const tablesContract = {
|
|
1650
|
+
...crud({
|
|
1651
|
+
basePath: basePath$2,
|
|
1652
|
+
schema: blueSource,
|
|
1653
|
+
contentType,
|
|
1654
|
+
accept,
|
|
1655
|
+
sources: ["main"]
|
|
1656
|
+
}),
|
|
1657
|
+
objectstructure: (name, options) => http.get(`${basePath$2}/${name.toLowerCase()}/objectstructure`, {
|
|
1658
|
+
responses: { 200: void 0 },
|
|
1659
|
+
query: options?.version ? { version: options.version } : void 0
|
|
1660
|
+
})
|
|
1661
|
+
};
|
|
1662
|
+
|
|
1663
|
+
//#endregion
|
|
1664
|
+
//#region src/adt/ddic/tablesettings.ts
|
|
1665
|
+
/**
|
|
1666
|
+
* DDIC Database Table Settings Contract
|
|
1667
|
+
*
|
|
1668
|
+
* ADT endpoint: /sap/bc/adt/ddic/db/settings/{name}
|
|
1669
|
+
* Content-Type: application/vnd.sap.adt.table.settings.v2+xml
|
|
1670
|
+
*
|
|
1671
|
+
* Returns the technical DD09L settings for a database table as an XML
|
|
1672
|
+
* document. ADK currently consumes this as raw text, so the contract is
|
|
1673
|
+
* typed as a plain-text endpoint.
|
|
1674
|
+
*/
|
|
1675
|
+
const basePath$1 = "/sap/bc/adt/ddic/db/settings";
|
|
1676
|
+
const tablesettingsContract = contract({
|
|
1677
|
+
/** GET /sap/bc/adt/ddic/db/settings/{name} - Retrieve table settings XML */
|
|
1678
|
+
get: (name) => http$1.get(`${basePath$1}/${name.toLowerCase()}`, {
|
|
1679
|
+
responses: { 200: void 0 },
|
|
1680
|
+
headers: { Accept: "application/vnd.sap.adt.table.settings.v2+xml" }
|
|
1681
|
+
}) });
|
|
1682
|
+
|
|
1683
|
+
//#endregion
|
|
1684
|
+
//#region src/adt/ddic/tabletypes.ts
|
|
1685
|
+
/**
|
|
1686
|
+
* DDIC Table Type Contract
|
|
1687
|
+
*
|
|
1688
|
+
* ADT endpoint: /sap/bc/adt/ddic/tabletypes
|
|
1689
|
+
* Content-Type: application/vnd.sap.adt.tabletype.v1+xml
|
|
1690
|
+
* Object type: TTYP/TT
|
|
1691
|
+
*/
|
|
1692
|
+
const tabletypesContract = crud({
|
|
1693
|
+
basePath: "/sap/bc/adt/ddic/tabletypes",
|
|
1694
|
+
schema: tabletype,
|
|
1695
|
+
contentType: "application/vnd.sap.adt.tabletype.v1+xml",
|
|
1696
|
+
accept: "application/vnd.sap.adt.tabletype.v1+xml"
|
|
1697
|
+
});
|
|
1698
|
+
|
|
1699
|
+
//#endregion
|
|
1700
|
+
//#region src/adt/ddic/ddl/sources.ts
|
|
1701
|
+
/**
|
|
1702
|
+
* ADT CDS DDL Source Contract
|
|
1703
|
+
*
|
|
1704
|
+
* Endpoint: /sap/bc/adt/ddic/ddl/sources
|
|
1705
|
+
* Content-Type: application/vnd.sap.adt.ddlSource+xml
|
|
1706
|
+
* Object type: DDLS
|
|
1707
|
+
*
|
|
1708
|
+
* CDS Data Definition sources — the SAP endpoint for CDS views / data
|
|
1709
|
+
* definitions. The metadata document lives at `{basePath}/{name}` and
|
|
1710
|
+
* the source text at `{basePath}/{name}/source/main`.
|
|
1711
|
+
*/
|
|
1712
|
+
const ddlSourcesContract = crud({
|
|
1713
|
+
basePath: "/sap/bc/adt/ddic/ddl/sources",
|
|
1714
|
+
schema: ddlSource,
|
|
1715
|
+
contentType: "application/vnd.sap.adt.ddlSource+xml",
|
|
1716
|
+
accept: "application/vnd.sap.adt.ddlSource+xml",
|
|
1717
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase()),
|
|
1718
|
+
sources: ["main"]
|
|
1719
|
+
});
|
|
1720
|
+
|
|
1721
|
+
//#endregion
|
|
1722
|
+
//#region src/adt/ddic/ddl/index.ts
|
|
1723
|
+
const ddlContract = { sources: ddlSourcesContract };
|
|
1724
|
+
|
|
1725
|
+
//#endregion
|
|
1726
|
+
//#region src/adt/ddic/dcl/sources.ts
|
|
1727
|
+
/**
|
|
1728
|
+
* ADT CDS DCL (Access Control) Source Contract
|
|
1729
|
+
*
|
|
1730
|
+
* Endpoint: /sap/bc/adt/acm/dcl/sources
|
|
1731
|
+
* (Note: the SAP endpoint for DCL sources lives under `acm/dcl`, not
|
|
1732
|
+
* `ddic/dcl`. The contract is exported under `ddic.dcl` for API
|
|
1733
|
+
* parity with the ADK and the sibling DDL contract.)
|
|
1734
|
+
* Content-Type: application/vnd.sap.adt.dclSource+xml
|
|
1735
|
+
* Object type: DCLS
|
|
1736
|
+
*/
|
|
1737
|
+
const dclSourcesContract = crud({
|
|
1738
|
+
basePath: "/sap/bc/adt/acm/dcl/sources",
|
|
1739
|
+
schema: dclSource,
|
|
1740
|
+
contentType: "application/vnd.sap.adt.dclSource+xml",
|
|
1741
|
+
accept: "application/vnd.sap.adt.dclSource+xml",
|
|
1742
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase()),
|
|
1743
|
+
sources: ["main"]
|
|
1744
|
+
});
|
|
1745
|
+
|
|
1746
|
+
//#endregion
|
|
1747
|
+
//#region src/adt/ddic/dcl/index.ts
|
|
1748
|
+
const dclContract = { sources: dclSourcesContract };
|
|
1749
|
+
|
|
1750
|
+
//#endregion
|
|
1751
|
+
//#region src/adt/ddic/ddlx/sources.ts
|
|
1752
|
+
const ddlxSourcesContract = crud({
|
|
1753
|
+
basePath: "/sap/bc/adt/ddic/ddlx/sources",
|
|
1754
|
+
schema: ddlxSource,
|
|
1755
|
+
contentType: "application/vnd.sap.adt.ddic.ddlx.v1+xml",
|
|
1756
|
+
accept: "application/vnd.sap.adt.ddic.ddlx.v1+xml",
|
|
1757
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase()),
|
|
1758
|
+
sources: ["main"]
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
//#endregion
|
|
1762
|
+
//#region src/adt/ddic/ddlx/index.ts
|
|
1763
|
+
const ddlxContract = { sources: ddlxSourcesContract };
|
|
1764
|
+
|
|
1765
|
+
//#endregion
|
|
1766
|
+
//#region src/adt/ddic/dsfd/sources.ts
|
|
1767
|
+
const dsfdSourcesContract = crud({
|
|
1768
|
+
basePath: "/sap/bc/adt/ddic/dsfd/sources",
|
|
1769
|
+
schema: blueSource,
|
|
1770
|
+
contentType: "application/vnd.sap.adt.blues.v1+xml",
|
|
1771
|
+
accept: "application/vnd.sap.adt.blues.v1+xml",
|
|
1772
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase()),
|
|
1773
|
+
sources: ["main"]
|
|
1774
|
+
});
|
|
1775
|
+
|
|
1776
|
+
//#endregion
|
|
1777
|
+
//#region src/adt/ddic/dsfd/index.ts
|
|
1778
|
+
const dsfdContract = { sources: dsfdSourcesContract };
|
|
1779
|
+
|
|
1780
|
+
//#endregion
|
|
1781
|
+
//#region src/adt/ddic/dsfi/index.ts
|
|
1782
|
+
const dsfiDefinitionSchema = {
|
|
1783
|
+
_infer: void 0,
|
|
1784
|
+
parse: (raw) => JSON.parse(raw),
|
|
1785
|
+
build: (value) => JSON.stringify(value)
|
|
1786
|
+
};
|
|
1787
|
+
const baseContract$1 = crud({
|
|
1788
|
+
basePath: "/sap/bc/adt/ddic/dsfi",
|
|
1789
|
+
schema: blueSource,
|
|
1790
|
+
contentType: "application/vnd.sap.adt.blues.v1+xml",
|
|
1791
|
+
accept: "application/vnd.sap.adt.blues.v1+xml",
|
|
1792
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase())
|
|
1793
|
+
});
|
|
1794
|
+
const dsfiContract = {
|
|
1795
|
+
...baseContract$1,
|
|
1796
|
+
source: { main: { get: (name) => http.get(`/sap/bc/adt/ddic/dsfi/${encodeURIComponent(name.toLowerCase())}/source/main`, {
|
|
1797
|
+
responses: { 200: dsfiDefinitionSchema },
|
|
1798
|
+
headers: { Accept: "application/json" }
|
|
1799
|
+
}) } }
|
|
1800
|
+
};
|
|
1801
|
+
|
|
1802
|
+
//#endregion
|
|
1803
|
+
//#region src/adt/ddic/dteb/sources.ts
|
|
1804
|
+
const dtebSourcesContract = crud({
|
|
1805
|
+
basePath: "/sap/bc/adt/ddic/dteb/sources",
|
|
1806
|
+
schema: dtebSource,
|
|
1807
|
+
contentType: "application/vnd.sap.adt.ddic.dteb.v1+xml",
|
|
1808
|
+
accept: "application/vnd.sap.adt.ddic.dteb.v1+xml",
|
|
1809
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase()),
|
|
1810
|
+
sources: ["main"]
|
|
1811
|
+
});
|
|
1812
|
+
|
|
1813
|
+
//#endregion
|
|
1814
|
+
//#region src/adt/ddic/dteb/index.ts
|
|
1815
|
+
const dtebContract = { sources: dtebSourcesContract };
|
|
1816
|
+
|
|
1817
|
+
//#endregion
|
|
1818
|
+
//#region src/adt/ddic/srvd/sources.ts
|
|
1819
|
+
/**
|
|
1820
|
+
* ADT RAP Service Definition (SRVD) Source Contract
|
|
1821
|
+
*
|
|
1822
|
+
* Endpoint: /sap/bc/adt/ddic/srvd/sources
|
|
1823
|
+
* Content-Type: application/vnd.sap.adt.ddic.srvd.v1+xml
|
|
1824
|
+
* Object type: SRVD/SRV
|
|
1825
|
+
*
|
|
1826
|
+
* RAP Service Definition — CDS-like source that exposes CDS root
|
|
1827
|
+
* entities/behaviors via OData. Mirrors the DDL sources shape: metadata
|
|
1828
|
+
* document at `{basePath}/{name}`, source text (`.asrvd`) at
|
|
1829
|
+
* `{basePath}/{name}/source/main`.
|
|
1830
|
+
*
|
|
1831
|
+
* Reference: abapGit handler zcl_abapgit_object_srvd.
|
|
1832
|
+
*/
|
|
1833
|
+
const srvdSourcesContract = crud({
|
|
1834
|
+
basePath: "/sap/bc/adt/ddic/srvd/sources",
|
|
1835
|
+
schema: srvdSource,
|
|
1836
|
+
contentType: "application/vnd.sap.adt.ddic.srvd.v1+xml",
|
|
1837
|
+
accept: "application/vnd.sap.adt.ddic.srvd.v1+xml",
|
|
1838
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase()),
|
|
1839
|
+
sources: ["main"]
|
|
1840
|
+
});
|
|
1841
|
+
|
|
1842
|
+
//#endregion
|
|
1843
|
+
//#region src/adt/ddic/srvd/index.ts
|
|
1844
|
+
const srvdContract = { sources: srvdSourcesContract };
|
|
1845
|
+
|
|
1846
|
+
//#endregion
|
|
1847
|
+
//#region src/adt/ddic/index.ts
|
|
1848
|
+
const ddicContract = {
|
|
1849
|
+
domains: domainsContract,
|
|
1850
|
+
dataelements: dataelementsContract,
|
|
1851
|
+
structures: structuresContract,
|
|
1852
|
+
tables: tablesContract,
|
|
1853
|
+
tablesettings: tablesettingsContract,
|
|
1854
|
+
tabletypes: tabletypesContract,
|
|
1855
|
+
ddl: ddlContract,
|
|
1856
|
+
dcl: dclContract,
|
|
1857
|
+
ddlx: ddlxContract,
|
|
1858
|
+
dsfd: dsfdContract,
|
|
1859
|
+
dsfi: dsfiContract,
|
|
1860
|
+
dteb: dtebContract,
|
|
1861
|
+
srvd: srvdContract
|
|
1862
|
+
};
|
|
1863
|
+
|
|
1864
|
+
//#endregion
|
|
1865
|
+
//#region src/adt/system/users.ts
|
|
1866
|
+
/**
|
|
1867
|
+
* ADT System Users Contract
|
|
1868
|
+
*
|
|
1869
|
+
* User lookup and search operations.
|
|
1870
|
+
* Path: /sap/bc/adt/system/users
|
|
1871
|
+
*/
|
|
1872
|
+
const usersContract = {
|
|
1873
|
+
/**
|
|
1874
|
+
* Search for users by query string
|
|
1875
|
+
*
|
|
1876
|
+
* @param options.querystring - Search query (supports wildcards like *)
|
|
1877
|
+
* @param options.maxcount - Maximum number of results
|
|
1878
|
+
* @returns Atom feed with matching user entries (id = username, title = full name)
|
|
1879
|
+
*
|
|
1880
|
+
* @example
|
|
1881
|
+
* const results = await client.system.users.search({ querystring: 'DEV*', maxcount: 10 });
|
|
1882
|
+
*/
|
|
1883
|
+
search: (options) => http$1.get("/sap/bc/adt/system/users", {
|
|
1884
|
+
query: {
|
|
1885
|
+
querystring: options.querystring,
|
|
1886
|
+
...options.maxcount !== void 0 && { maxcount: options.maxcount }
|
|
1887
|
+
},
|
|
1888
|
+
responses: { 200: atomFeed },
|
|
1889
|
+
headers: { Accept: "application/atom+xml;type=feed" }
|
|
1890
|
+
}),
|
|
1891
|
+
/**
|
|
1892
|
+
* Get a specific user by username
|
|
1893
|
+
*
|
|
1894
|
+
* @param username - SAP username (e.g., 'DEVELOPER')
|
|
1895
|
+
* @returns Atom feed with a single user entry
|
|
1896
|
+
*
|
|
1897
|
+
* @example
|
|
1898
|
+
* const user = await client.system.users.get('DEVELOPER');
|
|
1899
|
+
*/
|
|
1900
|
+
get: (username) => http$1.get(`/sap/bc/adt/system/users/${encodeURIComponent(username)}`, {
|
|
1901
|
+
responses: { 200: atomFeed },
|
|
1902
|
+
headers: { Accept: "application/atom+xml;type=feed" }
|
|
1903
|
+
})
|
|
1904
|
+
};
|
|
1905
|
+
|
|
1906
|
+
//#endregion
|
|
1907
|
+
//#region src/adt/system/security/pses.ts
|
|
1908
|
+
/**
|
|
1909
|
+
* ADT System Security / STRUST Contracts
|
|
1910
|
+
*
|
|
1911
|
+
* Contract surface for SAP STRUST (SSL Personal Security Environment)
|
|
1912
|
+
* over the ADT REST API. Paths under `/sap/bc/adt/system/security/pses`.
|
|
1913
|
+
*
|
|
1914
|
+
* NOTE: sapcli (jfilak/sapcli) drives STRUST via RFC function modules
|
|
1915
|
+
* (`sap/rfc/strust.py`), not ADT. The paths below follow the
|
|
1916
|
+
* `/sap/bc/adt/system/...` convention used elsewhere in the SAP ADT
|
|
1917
|
+
* REST surface (see `system/users`). See the accompanying TODO-synthetic
|
|
1918
|
+
* fixtures in `@abapify/adt-fixtures` — replace with real captures when
|
|
1919
|
+
* available.
|
|
1920
|
+
*/
|
|
1921
|
+
/**
|
|
1922
|
+
* Inferrable schema wrapper for a PEM (plain-text) request body.
|
|
1923
|
+
* Makes `uploadCertificate` accept a `pem: string` argument at the client
|
|
1924
|
+
* call-site — speci's `BuildParams` only appends a body parameter when
|
|
1925
|
+
* the body is marked Inferrable via the `_infer` tag.
|
|
1926
|
+
*/
|
|
1927
|
+
const pemBody = { _infer: void 0 };
|
|
1928
|
+
const psesContract = {
|
|
1929
|
+
/**
|
|
1930
|
+
* List all Personal Security Environments (identities).
|
|
1931
|
+
*
|
|
1932
|
+
* `GET /sap/bc/adt/system/security/pses`
|
|
1933
|
+
*/
|
|
1934
|
+
list: () => http$1.get("/sap/bc/adt/system/security/pses", {
|
|
1935
|
+
responses: { 200: atomFeed },
|
|
1936
|
+
headers: { Accept: "application/atom+xml;type=feed" }
|
|
1937
|
+
}),
|
|
1938
|
+
/**
|
|
1939
|
+
* Get a single PSE identified by `{context}/{applic}`.
|
|
1940
|
+
*
|
|
1941
|
+
* `GET /sap/bc/adt/system/security/pses/{context}/{applic}`
|
|
1942
|
+
*/
|
|
1943
|
+
get: (context, applic) => http$1.get(`/sap/bc/adt/system/security/pses/${encodeURIComponent(context)}/${encodeURIComponent(applic)}`, {
|
|
1944
|
+
responses: { 200: atomFeed },
|
|
1945
|
+
headers: { Accept: "application/atom+xml;type=feed" }
|
|
1946
|
+
}),
|
|
1947
|
+
/**
|
|
1948
|
+
* List certificates inside a PSE.
|
|
1949
|
+
*
|
|
1950
|
+
* `GET /sap/bc/adt/system/security/pses/{context}/{applic}/certificates`
|
|
1951
|
+
*/
|
|
1952
|
+
listCertificates: (context, applic) => http$1.get(`/sap/bc/adt/system/security/pses/${encodeURIComponent(context)}/${encodeURIComponent(applic)}/certificates`, {
|
|
1953
|
+
responses: { 200: atomFeed },
|
|
1954
|
+
headers: { Accept: "application/atom+xml;type=feed" }
|
|
1955
|
+
}),
|
|
1956
|
+
/**
|
|
1957
|
+
* Fetch the PEM of a single certificate in a PSE.
|
|
1958
|
+
*
|
|
1959
|
+
* `GET /sap/bc/adt/system/security/pses/{context}/{applic}/certificates/{id}`
|
|
1960
|
+
*/
|
|
1961
|
+
getCertificate: (context, applic, id) => http$1.get(`/sap/bc/adt/system/security/pses/${encodeURIComponent(context)}/${encodeURIComponent(applic)}/certificates/${encodeURIComponent(id)}`, {
|
|
1962
|
+
responses: { 200: void 0 },
|
|
1963
|
+
headers: { Accept: "application/x-pem-file" }
|
|
1964
|
+
}),
|
|
1965
|
+
/**
|
|
1966
|
+
* Upload a PEM certificate into a PSE. The body is the PEM text.
|
|
1967
|
+
*
|
|
1968
|
+
* `POST /sap/bc/adt/system/security/pses/{context}/{applic}/certificates`
|
|
1969
|
+
*/
|
|
1970
|
+
uploadCertificate: (context, applic) => http$1.post(`/sap/bc/adt/system/security/pses/${encodeURIComponent(context)}/${encodeURIComponent(applic)}/certificates`, {
|
|
1971
|
+
body: pemBody,
|
|
1972
|
+
responses: { 200: atomFeed },
|
|
1973
|
+
headers: {
|
|
1974
|
+
Accept: "application/atom+xml;type=feed",
|
|
1975
|
+
"Content-Type": "application/x-pem-file"
|
|
1976
|
+
}
|
|
1977
|
+
}),
|
|
1978
|
+
/**
|
|
1979
|
+
* Delete a certificate from a PSE.
|
|
1980
|
+
*
|
|
1981
|
+
* `DELETE /sap/bc/adt/system/security/pses/{context}/{applic}/certificates/{id}`
|
|
1982
|
+
*/
|
|
1983
|
+
deleteCertificate: (context, applic, id) => http$1.delete(`/sap/bc/adt/system/security/pses/${encodeURIComponent(context)}/${encodeURIComponent(applic)}/certificates/${encodeURIComponent(id)}`, { responses: { 204: void 0 } })
|
|
1984
|
+
};
|
|
1985
|
+
|
|
1986
|
+
//#endregion
|
|
1987
|
+
//#region src/adt/system/index.ts
|
|
1988
|
+
const systemContract = {
|
|
1989
|
+
users: usersContract,
|
|
1990
|
+
security: { pses: psesContract }
|
|
1991
|
+
};
|
|
1992
|
+
|
|
1993
|
+
//#endregion
|
|
1994
|
+
//#region src/adt/checkruns/index.ts
|
|
1995
|
+
/**
|
|
1996
|
+
* ADT Checkruns Contract
|
|
1997
|
+
*
|
|
1998
|
+
* Manually-defined endpoint for ABAP syntax check runs.
|
|
1999
|
+
*
|
|
2000
|
+
* Structure mirrors URL tree:
|
|
2001
|
+
* - /sap/bc/adt/checkruns → checkruns.checkObjects (POST with body)
|
|
2002
|
+
*
|
|
2003
|
+
* NOTE: Not in SAP discovery - manually defined
|
|
2004
|
+
*/
|
|
2005
|
+
/**
|
|
2006
|
+
* /sap/bc/adt/checkruns
|
|
2007
|
+
*
|
|
2008
|
+
* Run a syntax/check-run on a list of ABAP objects.
|
|
2009
|
+
* Request body: checkObjectList (chkrun:CheckObjectList)
|
|
2010
|
+
* Response: checkRunReports (chkrun:CheckReportList)
|
|
2011
|
+
*/
|
|
2012
|
+
const checkObjects = contract({
|
|
2013
|
+
/**
|
|
2014
|
+
* POST /sap/bc/adt/checkruns
|
|
2015
|
+
* Submit a checkObjectList and receive checkRunReports.
|
|
2016
|
+
*
|
|
2017
|
+
* Both request and response use the same `checkrun` schema (union discriminated
|
|
2018
|
+
* by the root element: `checkObjectList` for requests, `checkRunReports` for responses).
|
|
2019
|
+
*/
|
|
2020
|
+
post: () => http$1.post("/sap/bc/adt/checkruns", {
|
|
2021
|
+
body: checkrun,
|
|
2022
|
+
responses: { 200: checkrun },
|
|
2023
|
+
headers: {
|
|
2024
|
+
Accept: "application/vnd.sap.adt.checkmessages+xml",
|
|
2025
|
+
"Content-Type": "application/vnd.sap.adt.checkobjects+xml"
|
|
2026
|
+
}
|
|
2027
|
+
}) });
|
|
2028
|
+
/**
|
|
2029
|
+
* Combined Checkruns contract
|
|
2030
|
+
*/
|
|
2031
|
+
const checkrunsContract = { checkObjects };
|
|
2032
|
+
|
|
2033
|
+
//#endregion
|
|
2034
|
+
//#region src/adt/activation/index.ts
|
|
2035
|
+
/**
|
|
2036
|
+
* ADT Activation Contract
|
|
2037
|
+
*
|
|
2038
|
+
* Manually-defined endpoint for ABAP object activation.
|
|
2039
|
+
*
|
|
2040
|
+
* Structure mirrors URL tree:
|
|
2041
|
+
* - /sap/bc/adt/activation → activation.activate (POST with body)
|
|
2042
|
+
*
|
|
2043
|
+
* NOTE: Not in SAP discovery - manually defined
|
|
2044
|
+
*/
|
|
2045
|
+
/**
|
|
2046
|
+
* /sap/bc/adt/activation
|
|
2047
|
+
*
|
|
2048
|
+
* Activate one or more ABAP objects.
|
|
2049
|
+
* Request body: adtcore:objectReferences (AdtcoreSchema variant)
|
|
2050
|
+
*/
|
|
2051
|
+
const activate = contract({
|
|
2052
|
+
/**
|
|
2053
|
+
* POST /sap/bc/adt/activation{?method,preauditRequested}
|
|
2054
|
+
*
|
|
2055
|
+
* Submit an objectReferences body to activate the listed objects.
|
|
2056
|
+
* The `method` query param selects the action (default: "activate").
|
|
2057
|
+
* The response XML is not strictly typed here – callers may ignore it.
|
|
2058
|
+
*/
|
|
2059
|
+
post: (params) => http$1.post("/sap/bc/adt/activation", {
|
|
2060
|
+
query: params,
|
|
2061
|
+
body: adtcore,
|
|
2062
|
+
responses: { 200: adtcore },
|
|
2063
|
+
headers: {
|
|
2064
|
+
Accept: "application/xml",
|
|
2065
|
+
"Content-Type": "application/xml"
|
|
2066
|
+
}
|
|
2067
|
+
}) });
|
|
2068
|
+
/**
|
|
2069
|
+
* Combined Activation contract
|
|
2070
|
+
*/
|
|
2071
|
+
const activationContract = { activate };
|
|
2072
|
+
|
|
2073
|
+
//#endregion
|
|
2074
|
+
//#region src/adt/datapreview/schema.ts
|
|
2075
|
+
/**
|
|
2076
|
+
* Hand-built Serializable schema for the data preview freestyle response.
|
|
2077
|
+
*
|
|
2078
|
+
* Shape mirrors the ts-xsd `TypedSchema` pattern so it plugs into speci's
|
|
2079
|
+
* `Inferrable`/`Serializable` type inference (`_infer`, `parse`, `build`).
|
|
2080
|
+
*
|
|
2081
|
+
* The adapter calls `schema.parse(raw)` / `schema.build(data)`, so we keep
|
|
2082
|
+
* both sides as plain JSON (de)serialisation.
|
|
2083
|
+
*/
|
|
2084
|
+
const dataPreviewFreestyleResponseSchema = {
|
|
2085
|
+
_infer: void 0,
|
|
2086
|
+
parse: (raw) => {
|
|
2087
|
+
if (raw == null || raw === "") return {};
|
|
2088
|
+
return JSON.parse(raw);
|
|
2089
|
+
},
|
|
2090
|
+
build: (data) => JSON.stringify(data)
|
|
2091
|
+
};
|
|
2092
|
+
/**
|
|
2093
|
+
* Request-body schema: the endpoint accepts a raw SQL SELECT string as
|
|
2094
|
+
* `text/plain`. We still model it as a Serializable so speci correctly
|
|
2095
|
+
* infers the `string` body parameter at the client call site.
|
|
2096
|
+
*/
|
|
2097
|
+
const dataPreviewFreestyleRequestSchema = {
|
|
2098
|
+
_infer: void 0,
|
|
2099
|
+
parse: (raw) => raw,
|
|
2100
|
+
build: (data) => data
|
|
2101
|
+
};
|
|
2102
|
+
|
|
2103
|
+
//#endregion
|
|
2104
|
+
//#region src/adt/datapreview/freestyle.ts
|
|
2105
|
+
/**
|
|
2106
|
+
* /sap/bc/adt/datapreview/freestyle
|
|
2107
|
+
*
|
|
2108
|
+
* Executes an ABAP Open SQL SELECT statement and returns the result set as
|
|
2109
|
+
* JSON. Mirrors sapcli's `datapreview osql` command and the adt CLI
|
|
2110
|
+
* `datapreview osql` command.
|
|
2111
|
+
*
|
|
2112
|
+
* POST /sap/bc/adt/datapreview/freestyle?rowCount=<n>&outputFormat=json[&noaging=true]
|
|
2113
|
+
* Content-Type: text/plain
|
|
2114
|
+
* Accept: application/json
|
|
2115
|
+
* Body: raw ABAP SQL SELECT statement
|
|
2116
|
+
*/
|
|
2117
|
+
const freestyle = {
|
|
2118
|
+
/** POST /datapreview/freestyle - execute a free-style SQL query */
|
|
2119
|
+
post: (query) => http$1.post("/sap/bc/adt/datapreview/freestyle", {
|
|
2120
|
+
body: dataPreviewFreestyleRequestSchema,
|
|
2121
|
+
responses: { 200: dataPreviewFreestyleResponseSchema },
|
|
2122
|
+
headers: {
|
|
2123
|
+
Accept: "application/json",
|
|
2124
|
+
"Content-Type": "text/plain"
|
|
2125
|
+
},
|
|
2126
|
+
query: {
|
|
2127
|
+
outputFormat: query?.outputFormat ?? "json",
|
|
2128
|
+
...query?.rowCount != null ? { rowCount: query.rowCount } : {},
|
|
2129
|
+
...query?.noaging ? { noaging: true } : {}
|
|
2130
|
+
}
|
|
2131
|
+
}) };
|
|
2132
|
+
|
|
2133
|
+
//#endregion
|
|
2134
|
+
//#region src/adt/datapreview/index.ts
|
|
2135
|
+
/**
|
|
2136
|
+
* /sap/bc/adt/datapreview
|
|
2137
|
+
*
|
|
2138
|
+
* ADT Data Preview endpoints (ABAP SQL execution, value helps, etc.)
|
|
2139
|
+
*/
|
|
2140
|
+
const datapreviewContract = { freestyle };
|
|
2141
|
+
|
|
2142
|
+
//#endregion
|
|
2143
|
+
//#region src/adt/runtime/traces/coverage/request.ts
|
|
2144
|
+
const COVERAGE_NAMESPACE = "http://www.sap.com/adt/cov";
|
|
2145
|
+
const ADT_CORE_NAMESPACE = "http://www.sap.com/adt/core";
|
|
2146
|
+
const STATEMENTS_RELATION = "http://www.sap.com/adt/relations/runtime/traces/coverage/results/statements";
|
|
2147
|
+
const coverageXmlBody = {
|
|
2148
|
+
parse: (value) => String(value),
|
|
2149
|
+
build: (value) => value,
|
|
2150
|
+
_infer: void 0
|
|
2151
|
+
};
|
|
2152
|
+
function escapeXmlAttribute(value) {
|
|
2153
|
+
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
2154
|
+
}
|
|
2155
|
+
function buildCoverageQuery(objectUris) {
|
|
2156
|
+
const objectReferences = objectUris.map((uri) => `<adtcore:objectReference adtcore:uri="${escapeXmlAttribute(uri)}"/>`).join("\n");
|
|
2157
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2158
|
+
<cov:query xmlns:cov="${COVERAGE_NAMESPACE}">
|
|
2159
|
+
<adtcore:objectSets xmlns:adtcore="${ADT_CORE_NAMESPACE}">
|
|
2160
|
+
<objectSet kind="inclusive">
|
|
2161
|
+
<adtcore:objectReferences>
|
|
2162
|
+
${objectReferences}
|
|
2163
|
+
</adtcore:objectReferences>
|
|
2164
|
+
</objectSet>
|
|
2165
|
+
</adtcore:objectSets>
|
|
2166
|
+
</cov:query>`;
|
|
2167
|
+
}
|
|
2168
|
+
function takeUnseenRecord(value, seenValues) {
|
|
2169
|
+
if (!value || typeof value !== "object" || seenValues.has(value)) return;
|
|
2170
|
+
seenValues.add(value);
|
|
2171
|
+
return value;
|
|
2172
|
+
}
|
|
2173
|
+
function takeStatementUri(record, seenUris) {
|
|
2174
|
+
const { rel, href } = record;
|
|
2175
|
+
if (rel !== STATEMENTS_RELATION || typeof href !== "string" || seenUris.has(href)) return;
|
|
2176
|
+
seenUris.add(href);
|
|
2177
|
+
return href;
|
|
2178
|
+
}
|
|
2179
|
+
function enqueueChildObjects(record, queue) {
|
|
2180
|
+
for (const child of Object.values(record)) {
|
|
2181
|
+
if (Array.isArray(child)) {
|
|
2182
|
+
queue.push(...child);
|
|
2183
|
+
continue;
|
|
2184
|
+
}
|
|
2185
|
+
if (child && typeof child === "object") queue.push(child);
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
function extractCoverageStatementUris(value) {
|
|
2189
|
+
const statementUris = [];
|
|
2190
|
+
const seenUris = /* @__PURE__ */ new Set();
|
|
2191
|
+
const seenValues = /* @__PURE__ */ new Set();
|
|
2192
|
+
const queue = [value];
|
|
2193
|
+
while (queue.length > 0) {
|
|
2194
|
+
const record = takeUnseenRecord(queue.shift(), seenValues);
|
|
2195
|
+
if (!record) continue;
|
|
2196
|
+
const statementUri = takeStatementUri(record, seenUris);
|
|
2197
|
+
if (statementUri) statementUris.push(statementUri);
|
|
2198
|
+
enqueueChildObjects(record, queue);
|
|
2199
|
+
}
|
|
2200
|
+
return statementUris;
|
|
2201
|
+
}
|
|
2202
|
+
function buildStatementsBulkRequest(statementUris) {
|
|
2203
|
+
const requests = statementUris.map((uri) => `<statementsRequest get="${escapeXmlAttribute(uri)}"/>`).join("\n");
|
|
2204
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2205
|
+
<cov:statementsBulkRequest xmlns:cov="${COVERAGE_NAMESPACE}">
|
|
2206
|
+
${requests}
|
|
2207
|
+
</cov:statementsBulkRequest>`;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
//#endregion
|
|
2211
|
+
//#region src/adt/runtime/traces/coverage/measurements.ts
|
|
2212
|
+
/**
|
|
2213
|
+
* /sap/bc/adt/runtime/traces/coverage/measurements/{id}
|
|
2214
|
+
*
|
|
2215
|
+
* POST returns the ABAP coverage tree (cov:result) for a previously
|
|
2216
|
+
* created measurement. Used as the second step of the aunit → coverage
|
|
2217
|
+
* flow: aunit run → atom:link to measurement → POST this endpoint.
|
|
2218
|
+
*
|
|
2219
|
+
* Content-Type: application/xml
|
|
2220
|
+
* Accept: application/xml
|
|
2221
|
+
*/
|
|
2222
|
+
const XML_CONTENT_TYPE$1 = "application/xml";
|
|
2223
|
+
const measurements = contract({
|
|
2224
|
+
/**
|
|
2225
|
+
* POST /sap/bc/adt/runtime/traces/coverage/measurements/{identifier}
|
|
2226
|
+
* ?withAdditionalTypeInfo=true
|
|
2227
|
+
*
|
|
2228
|
+
* Returns the coverage tree rooted at ADT_ROOT_NODE with coverage
|
|
2229
|
+
* totals (branch/procedure/statement) for each object reference.
|
|
2230
|
+
*/
|
|
2231
|
+
post: (identifier) => http$1.post(`/sap/bc/adt/runtime/traces/coverage/measurements/${identifier}`, {
|
|
2232
|
+
query: { withAdditionalTypeInfo: true },
|
|
2233
|
+
body: coverageXmlBody,
|
|
2234
|
+
responses: { 200: acoverageResult },
|
|
2235
|
+
headers: {
|
|
2236
|
+
Accept: XML_CONTENT_TYPE$1,
|
|
2237
|
+
"Content-Type": "application/xml"
|
|
2238
|
+
}
|
|
2239
|
+
}) });
|
|
2240
|
+
|
|
2241
|
+
//#endregion
|
|
2242
|
+
//#region src/adt/runtime/traces/coverage/statements.ts
|
|
2243
|
+
/**
|
|
2244
|
+
* /sap/bc/adt/runtime/traces/coverage/results/{id}/statements
|
|
2245
|
+
*
|
|
2246
|
+
* POST returns the cov:statementsBulkResponse with per-method statement
|
|
2247
|
+
* / branch / procedure coverage details.
|
|
2248
|
+
*
|
|
2249
|
+
* Content-Type: application/xml
|
|
2250
|
+
* Accept: application/xml
|
|
2251
|
+
*/
|
|
2252
|
+
const XML_CONTENT_TYPE = "application/xml";
|
|
2253
|
+
const statements = contract({
|
|
2254
|
+
/**
|
|
2255
|
+
* POST /sap/bc/adt/runtime/traces/coverage/results/{identifier}/statements
|
|
2256
|
+
*/
|
|
2257
|
+
post: (identifier) => http$1.post(`/sap/bc/adt/runtime/traces/coverage/results/${identifier}/statements`, {
|
|
2258
|
+
body: coverageXmlBody,
|
|
2259
|
+
responses: { 200: acoverageStatements },
|
|
2260
|
+
headers: {
|
|
2261
|
+
Accept: XML_CONTENT_TYPE,
|
|
2262
|
+
"Content-Type": "application/xml"
|
|
2263
|
+
}
|
|
2264
|
+
}) });
|
|
2265
|
+
|
|
2266
|
+
//#endregion
|
|
2267
|
+
//#region src/adt/runtime/traces/coverage/index.ts
|
|
2268
|
+
/**
|
|
2269
|
+
* /sap/bc/adt/runtime/traces/coverage
|
|
2270
|
+
*
|
|
2271
|
+
* ABAP Coverage endpoints. Used as a follow-up to ABAP Unit runs that
|
|
2272
|
+
* request coverage — the aunit runResult contains an atom:link pointing
|
|
2273
|
+
* to a measurement ID which is then POSTed here.
|
|
2274
|
+
*/
|
|
2275
|
+
const coverageContract = {
|
|
2276
|
+
measurements,
|
|
2277
|
+
statements
|
|
2278
|
+
};
|
|
2279
|
+
|
|
2280
|
+
//#endregion
|
|
2281
|
+
//#region src/adt/runtime/schema.ts
|
|
2282
|
+
function parseJsonOrRaw$1(raw) {
|
|
2283
|
+
if (!raw) return {};
|
|
2284
|
+
const trimmed = raw.trim();
|
|
2285
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) return JSON.parse(trimmed);
|
|
2286
|
+
return { raw };
|
|
2287
|
+
}
|
|
2288
|
+
function buildJson(value) {
|
|
2289
|
+
return JSON.stringify(value);
|
|
2290
|
+
}
|
|
2291
|
+
const runtimeDumpListSchema = {
|
|
2292
|
+
_infer: void 0,
|
|
2293
|
+
parse: (raw) => parseJsonOrRaw$1(raw),
|
|
2294
|
+
build: (value) => buildJson(value)
|
|
2295
|
+
};
|
|
2296
|
+
const runtimeDumpDetailSchema = {
|
|
2297
|
+
_infer: void 0,
|
|
2298
|
+
parse: (raw) => parseJsonOrRaw$1(raw),
|
|
2299
|
+
build: (value) => buildJson(value)
|
|
2300
|
+
};
|
|
2301
|
+
const runtimeTraceListSchema = {
|
|
2302
|
+
_infer: void 0,
|
|
2303
|
+
parse: (raw) => parseJsonOrRaw$1(raw),
|
|
2304
|
+
build: (value) => buildJson(value)
|
|
2305
|
+
};
|
|
2306
|
+
const runtimeTraceDetailSchema = {
|
|
2307
|
+
_infer: void 0,
|
|
2308
|
+
parse: (raw) => parseJsonOrRaw$1(raw),
|
|
2309
|
+
build: (value) => buildJson(value)
|
|
2310
|
+
};
|
|
2311
|
+
|
|
2312
|
+
//#endregion
|
|
2313
|
+
//#region src/adt/runtime/traces/profile.ts
|
|
2314
|
+
/**
|
|
2315
|
+
* /sap/bc/adt/runtime/traces
|
|
2316
|
+
*
|
|
2317
|
+
* Runtime trace list and detail endpoints used by diagnostics tooling.
|
|
2318
|
+
*/
|
|
2319
|
+
const profile = contract({
|
|
2320
|
+
list: () => http$1.get("/sap/bc/adt/runtime/traces", {
|
|
2321
|
+
responses: { 200: runtimeTraceListSchema },
|
|
2322
|
+
headers: { Accept: "application/json" }
|
|
2323
|
+
}),
|
|
2324
|
+
hitlist: (id) => http$1.get(`/sap/bc/adt/runtime/traces/${id}/hitlist`, {
|
|
2325
|
+
responses: { 200: runtimeTraceDetailSchema },
|
|
2326
|
+
headers: { Accept: "application/json" }
|
|
2327
|
+
}),
|
|
2328
|
+
dbAccesses: (id) => http$1.get(`/sap/bc/adt/runtime/traces/${id}/dbaccesses`, {
|
|
2329
|
+
responses: { 200: runtimeTraceDetailSchema },
|
|
2330
|
+
headers: { Accept: "application/json" }
|
|
2331
|
+
})
|
|
2332
|
+
});
|
|
2333
|
+
|
|
2334
|
+
//#endregion
|
|
2335
|
+
//#region src/adt/runtime/traces/index.ts
|
|
2336
|
+
/**
|
|
2337
|
+
* /sap/bc/adt/runtime/traces
|
|
2338
|
+
*
|
|
2339
|
+
* Runtime trace endpoints (currently only ABAP coverage).
|
|
2340
|
+
*/
|
|
2341
|
+
const tracesContract = {
|
|
2342
|
+
coverage: coverageContract,
|
|
2343
|
+
profile
|
|
2344
|
+
};
|
|
2345
|
+
|
|
2346
|
+
//#endregion
|
|
2347
|
+
//#region src/adt/runtime/dumps.ts
|
|
2348
|
+
/**
|
|
2349
|
+
* /sap/bc/adt/runtime/dumps
|
|
2350
|
+
*
|
|
2351
|
+
* Short dump listing and details.
|
|
2352
|
+
*/
|
|
2353
|
+
const dumps = contract({
|
|
2354
|
+
list: (query) => http$1.get("/sap/bc/adt/runtime/dumps", {
|
|
2355
|
+
responses: { 200: runtimeDumpListSchema },
|
|
2356
|
+
headers: { Accept: "application/json" },
|
|
2357
|
+
query: {
|
|
2358
|
+
...query?.user ? { user: query.user } : {},
|
|
2359
|
+
...query?.maxResults != null ? { maxResults: query.maxResults } : {}
|
|
2360
|
+
}
|
|
2361
|
+
}),
|
|
2362
|
+
get: (id) => http$1.get(`/sap/bc/adt/runtime/dumps/${id}`, {
|
|
2363
|
+
responses: { 200: runtimeDumpDetailSchema },
|
|
2364
|
+
headers: { Accept: "application/json" }
|
|
2365
|
+
})
|
|
2366
|
+
});
|
|
2367
|
+
|
|
2368
|
+
//#endregion
|
|
2369
|
+
//#region src/adt/runtime/index.ts
|
|
2370
|
+
/**
|
|
2371
|
+
* /sap/bc/adt/runtime
|
|
2372
|
+
*
|
|
2373
|
+
* ABAP runtime endpoints (traces, coverage, …).
|
|
2374
|
+
*/
|
|
2375
|
+
const runtimeContract = {
|
|
2376
|
+
traces: tracesContract,
|
|
2377
|
+
dumps
|
|
2378
|
+
};
|
|
2379
|
+
|
|
2380
|
+
//#endregion
|
|
2381
|
+
//#region src/adt/gcts/schema.ts
|
|
2382
|
+
function jsonSchema$1() {
|
|
2383
|
+
return {
|
|
2384
|
+
_infer: void 0,
|
|
2385
|
+
parse: (raw) => {
|
|
2386
|
+
if (raw == null || raw === "") return {};
|
|
2387
|
+
return JSON.parse(raw);
|
|
2388
|
+
},
|
|
2389
|
+
build: (data) => JSON.stringify(data)
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
const gctsRepositoriesSchema = jsonSchema$1();
|
|
2393
|
+
const gctsRepositorySchema = jsonSchema$1();
|
|
2394
|
+
const gctsCreateRepositoryBodySchema = jsonSchema$1();
|
|
2395
|
+
const gctsSetItemBodySchema = jsonSchema$1();
|
|
2396
|
+
const gctsBranchesSchema = jsonSchema$1();
|
|
2397
|
+
const gctsCreateBranchBodySchema = jsonSchema$1();
|
|
2398
|
+
const gctsCreateBranchResponseSchema = jsonSchema$1();
|
|
2399
|
+
const gctsSetConfigBodySchema = jsonSchema$1();
|
|
2400
|
+
const gctsConfigSchema = jsonSchema$1();
|
|
2401
|
+
const gctsLogSchema = jsonSchema$1();
|
|
2402
|
+
const gctsPullSchema = jsonSchema$1();
|
|
2403
|
+
const gctsObjectsSchema = jsonSchema$1();
|
|
2404
|
+
const gctsCommitBodySchema = jsonSchema$1();
|
|
2405
|
+
const gctsCommitResponseSchema = jsonSchema$1();
|
|
2406
|
+
const gctsGenericOkSchema = jsonSchema$1();
|
|
2407
|
+
|
|
2408
|
+
//#endregion
|
|
2409
|
+
//#region src/adt/gcts/repository.ts
|
|
2410
|
+
/**
|
|
2411
|
+
* /sap/bc/cts_abapvcs/repository/**
|
|
2412
|
+
*
|
|
2413
|
+
* gCTS repository endpoints. Shapes mirror sapcli's
|
|
2414
|
+
* `Repository` / `simple.fetch_repos` behaviour.
|
|
2415
|
+
*/
|
|
2416
|
+
const BASE$3 = "/sap/bc/cts_abapvcs/repository";
|
|
2417
|
+
/** List all repositories (GET /repository). */
|
|
2418
|
+
const list$4 = () => http$1.get(BASE$3, {
|
|
2419
|
+
responses: { 200: gctsRepositoriesSchema },
|
|
2420
|
+
headers: { Accept: "application/json" }
|
|
2421
|
+
});
|
|
2422
|
+
/** Get a single repository (GET /repository/<rid>). */
|
|
2423
|
+
const get$4 = (rid) => http$1.get(`${BASE$3}/${rid}`, {
|
|
2424
|
+
responses: { 200: gctsRepositorySchema },
|
|
2425
|
+
headers: { Accept: "application/json" }
|
|
2426
|
+
});
|
|
2427
|
+
/** Create a new repository (POST /repository). */
|
|
2428
|
+
const create$1 = () => http$1.post(BASE$3, {
|
|
2429
|
+
body: gctsCreateRepositoryBodySchema,
|
|
2430
|
+
responses: {
|
|
2431
|
+
201: gctsRepositorySchema,
|
|
2432
|
+
200: gctsRepositorySchema
|
|
2433
|
+
},
|
|
2434
|
+
headers: {
|
|
2435
|
+
Accept: "application/json",
|
|
2436
|
+
"Content-Type": "application/json"
|
|
2437
|
+
}
|
|
2438
|
+
});
|
|
2439
|
+
/** Delete a repository (DELETE /repository/<rid>). */
|
|
2440
|
+
const del$2 = (rid) => http$1.delete(`${BASE$3}/${rid}`, {
|
|
2441
|
+
responses: {
|
|
2442
|
+
200: gctsGenericOkSchema,
|
|
2443
|
+
204: gctsGenericOkSchema
|
|
2444
|
+
},
|
|
2445
|
+
headers: { Accept: "application/json" }
|
|
2446
|
+
});
|
|
2447
|
+
/** Clone (POST /repository/<rid>/clone). */
|
|
2448
|
+
const clone = (rid) => http$1.post(`${BASE$3}/${rid}/clone`, {
|
|
2449
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2450
|
+
headers: { Accept: "application/json" }
|
|
2451
|
+
});
|
|
2452
|
+
/** Pull (GET /repository/<rid>/pullByCommit). */
|
|
2453
|
+
const pull = (rid) => http$1.get(`${BASE$3}/${rid}/pullByCommit`, {
|
|
2454
|
+
responses: { 200: gctsPullSchema },
|
|
2455
|
+
headers: { Accept: "application/json" }
|
|
2456
|
+
});
|
|
2457
|
+
/** Push (GET /repository/<rid>/push) — gCTS uses GET, not POST. */
|
|
2458
|
+
const push = (rid) => http$1.get(`${BASE$3}/${rid}/push`, {
|
|
2459
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2460
|
+
headers: { Accept: "application/json" }
|
|
2461
|
+
});
|
|
2462
|
+
/**
|
|
2463
|
+
* Checkout (GET /repository/<rid>/branches/<currentBranch>/switch?branch=X).
|
|
2464
|
+
* Caller must supply both the *current* branch (path) and the *target* branch
|
|
2465
|
+
* (query) — mirrors sapcli's `Repository.checkout`.
|
|
2466
|
+
*/
|
|
2467
|
+
const checkout = (rid, currentBranch, targetBranch) => http$1.get(`${BASE$3}/${rid}/branches/${currentBranch}/switch`, {
|
|
2468
|
+
query: { branch: targetBranch },
|
|
2469
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2470
|
+
headers: { Accept: "application/json" }
|
|
2471
|
+
});
|
|
2472
|
+
/** Commit history (GET /repository/<rid>/getCommit). */
|
|
2473
|
+
const log = (rid) => http$1.get(`${BASE$3}/${rid}/getCommit`, {
|
|
2474
|
+
responses: { 200: gctsLogSchema },
|
|
2475
|
+
headers: { Accept: "application/json" }
|
|
2476
|
+
});
|
|
2477
|
+
/** Object list (GET /repository/<rid>/getObjects). */
|
|
2478
|
+
const objects = (rid) => http$1.get(`${BASE$3}/${rid}/getObjects`, {
|
|
2479
|
+
responses: { 200: gctsObjectsSchema },
|
|
2480
|
+
headers: { Accept: "application/json" }
|
|
2481
|
+
});
|
|
2482
|
+
/**
|
|
2483
|
+
* Set a repository property (POST /repository/<rid>).
|
|
2484
|
+
* Body is `{ <property>: <value> }`, e.g. `{ role: 'TARGET' }` or
|
|
2485
|
+
* `{ url: 'https://…' }`.
|
|
2486
|
+
*/
|
|
2487
|
+
const setItem = (rid) => http$1.post(`${BASE$3}/${rid}`, {
|
|
2488
|
+
body: gctsSetItemBodySchema,
|
|
2489
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2490
|
+
headers: {
|
|
2491
|
+
Accept: "application/json",
|
|
2492
|
+
"Content-Type": "application/json"
|
|
2493
|
+
}
|
|
2494
|
+
});
|
|
2495
|
+
const repository = {
|
|
2496
|
+
list: list$4,
|
|
2497
|
+
get: get$4,
|
|
2498
|
+
create: create$1,
|
|
2499
|
+
delete: del$2,
|
|
2500
|
+
clone,
|
|
2501
|
+
pull,
|
|
2502
|
+
push,
|
|
2503
|
+
checkout,
|
|
2504
|
+
log,
|
|
2505
|
+
objects,
|
|
2506
|
+
setItem
|
|
2507
|
+
};
|
|
2508
|
+
|
|
2509
|
+
//#endregion
|
|
2510
|
+
//#region src/adt/gcts/branches.ts
|
|
2511
|
+
/**
|
|
2512
|
+
* /sap/bc/cts_abapvcs/repository/<rid>/branches
|
|
2513
|
+
*
|
|
2514
|
+
* Branch management endpoints.
|
|
2515
|
+
*/
|
|
2516
|
+
const base$1 = (rid) => `/sap/bc/cts_abapvcs/repository/${rid}/branches`;
|
|
2517
|
+
const list$3 = (rid) => http$1.get(base$1(rid), {
|
|
2518
|
+
responses: { 200: gctsBranchesSchema },
|
|
2519
|
+
headers: { Accept: "application/json" }
|
|
2520
|
+
});
|
|
2521
|
+
const create = (rid) => http$1.post(base$1(rid), {
|
|
2522
|
+
body: gctsCreateBranchBodySchema,
|
|
2523
|
+
responses: { 200: gctsCreateBranchResponseSchema },
|
|
2524
|
+
headers: {
|
|
2525
|
+
Accept: "application/json",
|
|
2526
|
+
"Content-Type": "application/json"
|
|
2527
|
+
}
|
|
2528
|
+
});
|
|
2529
|
+
const del$1 = (rid, name) => http$1.delete(`${base$1(rid)}/${name}`, {
|
|
2530
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2531
|
+
headers: { Accept: "application/json" }
|
|
2532
|
+
});
|
|
2533
|
+
/**
|
|
2534
|
+
* Switch branches (GET /repository/<rid>/branches/<current>/switch?branch=X).
|
|
2535
|
+
* Alias of `repository.checkout` — exposed here for discoverability when
|
|
2536
|
+
* working with the `branches` sub-surface.
|
|
2537
|
+
*/
|
|
2538
|
+
const switchBranch = (rid, currentBranch, target) => http$1.get(`${base$1(rid)}/${currentBranch}/switch`, {
|
|
2539
|
+
query: { branch: target },
|
|
2540
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2541
|
+
headers: { Accept: "application/json" }
|
|
2542
|
+
});
|
|
2543
|
+
const branches = {
|
|
2544
|
+
list: list$3,
|
|
2545
|
+
create,
|
|
2546
|
+
delete: del$1,
|
|
2547
|
+
switch: switchBranch
|
|
2548
|
+
};
|
|
2549
|
+
|
|
2550
|
+
//#endregion
|
|
2551
|
+
//#region src/adt/gcts/commits.ts
|
|
2552
|
+
/**
|
|
2553
|
+
* /sap/bc/cts_abapvcs/repository/<rid>/commit
|
|
2554
|
+
*
|
|
2555
|
+
* Commit endpoint. Shapes mirror sapcli's
|
|
2556
|
+
* `Repository.commit` / `commit_package` / `commit_transport`.
|
|
2557
|
+
*/
|
|
2558
|
+
const commit = (rid) => http$1.post(`/sap/bc/cts_abapvcs/repository/${rid}/commit`, {
|
|
2559
|
+
body: gctsCommitBodySchema,
|
|
2560
|
+
responses: { 200: gctsCommitResponseSchema },
|
|
2561
|
+
headers: {
|
|
2562
|
+
Accept: "application/json",
|
|
2563
|
+
"Content-Type": "application/json"
|
|
2564
|
+
}
|
|
2565
|
+
});
|
|
2566
|
+
const commits = { commit };
|
|
2567
|
+
|
|
2568
|
+
//#endregion
|
|
2569
|
+
//#region src/adt/gcts/config.ts
|
|
2570
|
+
/**
|
|
2571
|
+
* /sap/bc/cts_abapvcs/repository/<rid>/config
|
|
2572
|
+
*
|
|
2573
|
+
* Repository configuration endpoints (key/value pairs).
|
|
2574
|
+
*/
|
|
2575
|
+
const base = (rid) => `/sap/bc/cts_abapvcs/repository/${rid}/config`;
|
|
2576
|
+
/** GET single config value: /repository/<rid>/config/<key>. */
|
|
2577
|
+
const get$3 = (rid, key) => http$1.get(`${base(rid)}/${key}`, {
|
|
2578
|
+
responses: { 200: gctsConfigSchema },
|
|
2579
|
+
headers: { Accept: "application/json" }
|
|
2580
|
+
});
|
|
2581
|
+
/** POST /repository/<rid>/config — body `{ key, value }`. */
|
|
2582
|
+
const set = (rid) => http$1.post(base(rid), {
|
|
2583
|
+
body: gctsSetConfigBodySchema,
|
|
2584
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2585
|
+
headers: {
|
|
2586
|
+
Accept: "application/json",
|
|
2587
|
+
"Content-Type": "application/json"
|
|
2588
|
+
}
|
|
2589
|
+
});
|
|
2590
|
+
/** DELETE /repository/<rid>/config/<key>. */
|
|
2591
|
+
const del = (rid, key) => http$1.delete(`${base(rid)}/${key}`, {
|
|
2592
|
+
responses: { 200: gctsGenericOkSchema },
|
|
2593
|
+
headers: { Accept: "application/json" }
|
|
2594
|
+
});
|
|
2595
|
+
const config = {
|
|
2596
|
+
get: get$3,
|
|
2597
|
+
set,
|
|
2598
|
+
delete: del
|
|
2599
|
+
};
|
|
2600
|
+
|
|
2601
|
+
//#endregion
|
|
2602
|
+
//#region src/adt/gcts/index.ts
|
|
2603
|
+
/**
|
|
2604
|
+
* /sap/bc/cts_abapvcs — gCTS (git-enabled CTS) contracts.
|
|
2605
|
+
*
|
|
2606
|
+
* Separate REST surface from /sap/bc/adt. Exposed as `client.adt.gcts.*`
|
|
2607
|
+
* for parity with sapcli's `sap gcts` CLI surface.
|
|
2608
|
+
*/
|
|
2609
|
+
const gctsContract = {
|
|
2610
|
+
repository,
|
|
2611
|
+
branches,
|
|
2612
|
+
commits,
|
|
2613
|
+
config
|
|
2614
|
+
};
|
|
2615
|
+
|
|
2616
|
+
//#endregion
|
|
2617
|
+
//#region src/adt/bo/behaviordefinitions.ts
|
|
2618
|
+
/**
|
|
2619
|
+
* ADT Behavior Definition (BDEF) Contract
|
|
2620
|
+
*
|
|
2621
|
+
* Endpoint: /sap/bc/adt/bo/behaviordefinitions/{name}
|
|
2622
|
+
* /sap/bc/adt/bo/behaviordefinitions/{name}/source/main
|
|
2623
|
+
*
|
|
2624
|
+
* Object type: BDEF/BDO
|
|
2625
|
+
* Content-Type: application/vnd.sap.adt.blues.v1+xml
|
|
2626
|
+
*
|
|
2627
|
+
* SAP wraps BDEF metadata in the shared `blue:blueSource` wrapper
|
|
2628
|
+
* (namespace http://www.sap.com/wbobj/blue) that extends
|
|
2629
|
+
* abapsource:AbapSourceMainObject — the same envelope used by
|
|
2630
|
+
* DDIC TABL/Structure responses. The BDEF source (`.abdl`) is
|
|
2631
|
+
* served as text/plain via `source/main`.
|
|
2632
|
+
*
|
|
2633
|
+
* Reference: sapcli `sap/adt/objects.py` (class BehaviorDefinition).
|
|
2634
|
+
*/
|
|
2635
|
+
/**
|
|
2636
|
+
* /sap/bc/adt/bo/behaviordefinitions
|
|
2637
|
+
* Full CRUD operations for ABAP Behavior Definitions (RAP).
|
|
2638
|
+
*
|
|
2639
|
+
* Includes:
|
|
2640
|
+
* - Basic CRUD: get, post, put, delete
|
|
2641
|
+
* - Lock/Unlock: lock, unlock
|
|
2642
|
+
* - Object structure: objectstructure
|
|
2643
|
+
* - Source code: source.main.get/put (text/plain .abdl)
|
|
2644
|
+
*/
|
|
2645
|
+
const behaviordefinitionsContract = crud({
|
|
2646
|
+
basePath: "/sap/bc/adt/bo/behaviordefinitions",
|
|
2647
|
+
schema: blueSource,
|
|
2648
|
+
contentType: "application/vnd.sap.adt.blues.v1+xml",
|
|
2649
|
+
accept: "application/vnd.sap.adt.blues.v1+xml",
|
|
2650
|
+
nameTransform: (name) => encodeURIComponent(name.toLowerCase()),
|
|
2651
|
+
sources: ["main"]
|
|
2652
|
+
});
|
|
2653
|
+
|
|
2654
|
+
//#endregion
|
|
2655
|
+
//#region src/adt/bo/index.ts
|
|
2656
|
+
const boContract = { behaviordefinitions: behaviordefinitionsContract };
|
|
2657
|
+
|
|
2658
|
+
//#endregion
|
|
2659
|
+
//#region src/adt/businessservices/bindings.ts
|
|
2660
|
+
/**
|
|
2661
|
+
* ADT RAP Service Binding (SRVB) Contract
|
|
2662
|
+
*
|
|
2663
|
+
* Endpoint: /sap/bc/adt/businessservices/bindings
|
|
2664
|
+
* Content-Type: application/vnd.sap.adt.businessservices.servicebinding.v2+xml
|
|
2665
|
+
* Object type: SRVB/SVB
|
|
2666
|
+
*
|
|
2667
|
+
* RAP Service Binding — binds a Service Definition (SRVD) to a runtime
|
|
2668
|
+
* protocol (OData V2/V4, INA, SQL). Unlike BDEF/SRVD, SRVB is **metadata
|
|
2669
|
+
* only** — there is no `.abdl`/`.asrvd`-style source text. The binding
|
|
2670
|
+
* XML carries the service + protocol references.
|
|
2671
|
+
*
|
|
2672
|
+
* Extra operations vs plain `crud()`:
|
|
2673
|
+
* - publish → POST {basePath}/{name}/publishedstates
|
|
2674
|
+
* - unpublish → DELETE {basePath}/{name}/publishedstates
|
|
2675
|
+
*
|
|
2676
|
+
* Reference: abapGit handler zcl_abapgit_object_srvb.
|
|
2677
|
+
*/
|
|
2678
|
+
const basePath = "/sap/bc/adt/businessservices/bindings";
|
|
2679
|
+
const nameTransform = (n) => encodeURIComponent(n.toLowerCase());
|
|
2680
|
+
const baseContract = crud({
|
|
2681
|
+
basePath,
|
|
2682
|
+
schema: servicebinding,
|
|
2683
|
+
contentType: "application/vnd.sap.adt.businessservices.servicebinding.v2+xml",
|
|
2684
|
+
accept: "application/vnd.sap.adt.businessservices.servicebinding.v2+xml",
|
|
2685
|
+
nameTransform
|
|
2686
|
+
});
|
|
2687
|
+
/**
|
|
2688
|
+
* Publish/unpublish extension for SRVB.
|
|
2689
|
+
*
|
|
2690
|
+
* - publish: POST {basePath}/{name}/publishedstates
|
|
2691
|
+
* Activates the binding in the SAP Gateway.
|
|
2692
|
+
* - unpublish: DELETE {basePath}/{name}/publishedstates
|
|
2693
|
+
* Deactivates the binding.
|
|
2694
|
+
*/
|
|
2695
|
+
const bindingsContract = {
|
|
2696
|
+
...baseContract,
|
|
2697
|
+
publish: (name) => http.post(`${basePath}/${nameTransform(name)}/publishedstates`, {
|
|
2698
|
+
responses: { 200: void 0 },
|
|
2699
|
+
headers: {
|
|
2700
|
+
Accept: "application/json",
|
|
2701
|
+
"Content-Type": "application/json"
|
|
2702
|
+
}
|
|
2703
|
+
}),
|
|
2704
|
+
unpublish: (name) => http.delete(`${basePath}/${nameTransform(name)}/publishedstates`, {
|
|
2705
|
+
responses: { 204: void 0 },
|
|
2706
|
+
headers: { Accept: "application/json" }
|
|
2707
|
+
})
|
|
2708
|
+
};
|
|
2709
|
+
|
|
2710
|
+
//#endregion
|
|
2711
|
+
//#region src/adt/businessservices/index.ts
|
|
2712
|
+
const businessservicesContract = { bindings: bindingsContract };
|
|
2713
|
+
|
|
2714
|
+
//#endregion
|
|
2715
|
+
//#region src/adt/enhancements/enhoxhh.ts
|
|
2716
|
+
/**
|
|
2717
|
+
* ADT BAdI / Enhancement Implementation (ENHO) Contract
|
|
2718
|
+
*
|
|
2719
|
+
* Endpoints:
|
|
2720
|
+
* /sap/bc/adt/enhancements/enhoxhh/{name}
|
|
2721
|
+
* /sap/bc/adt/enhancements/enhoxhh/{name}/source/main
|
|
2722
|
+
*
|
|
2723
|
+
* Object type: ENHO/XHH (enhancement implementation, BAdI container)
|
|
2724
|
+
* Content-Type: application/vnd.sap.adt.enhancements.enhoxhh.v1+xml
|
|
2725
|
+
*
|
|
2726
|
+
* SAP wraps the enhancement implementation in an
|
|
2727
|
+
* `enh:enhancementImplementation` element extending
|
|
2728
|
+
* `adtcore:AdtMainObject`. The BAdI implementations themselves live
|
|
2729
|
+
* inside the text payload served via `source/main`.
|
|
2730
|
+
*
|
|
2731
|
+
* The full XSD at `packages/adt-schemas/.xsd/sap/enhancements.xsd`
|
|
2732
|
+
* models the heavyweight emf tree (sourceCodePlugin, BAdI entries,
|
|
2733
|
+
* etc.). For CLI / MCP use we only need the AdtMainObject envelope —
|
|
2734
|
+
* same pattern as bdef's `blueSource` wrapper.
|
|
2735
|
+
*
|
|
2736
|
+
* sapcli reference: `sap/cli/badi.py`. In sapcli, `sap badi` lists the
|
|
2737
|
+
* BAdIs carried by a given Enhancement Implementation name (`-i` flag).
|
|
2738
|
+
*/
|
|
2739
|
+
/**
|
|
2740
|
+
* /sap/bc/adt/enhancements/enhoxhh
|
|
2741
|
+
*
|
|
2742
|
+
* CRUD + lock/unlock + source/main (`/source/main` text body).
|
|
2743
|
+
*/
|
|
2744
|
+
const enhoxhhContract = crud({
|
|
2745
|
+
basePath: "/sap/bc/adt/enhancements/enhoxhh",
|
|
2746
|
+
schema: badi,
|
|
2747
|
+
contentType: "application/vnd.sap.adt.enhancements.enhoxhh.v1+xml",
|
|
2748
|
+
accept: "application/vnd.sap.adt.enhancements.enhoxhh.v1+xml",
|
|
2749
|
+
sources: ["main"]
|
|
2750
|
+
});
|
|
2751
|
+
|
|
2752
|
+
//#endregion
|
|
2753
|
+
//#region src/adt/enhancements/index.ts
|
|
2754
|
+
const enhancementsContract = { enhoxhh: enhoxhhContract };
|
|
2755
|
+
|
|
2756
|
+
//#endregion
|
|
2757
|
+
//#region src/adt/uifsa/schema.ts
|
|
2758
|
+
function jsonSchema() {
|
|
2759
|
+
return {
|
|
2760
|
+
_infer: void 0,
|
|
2761
|
+
parse: (raw) => {
|
|
2762
|
+
if (raw == null || raw === "") return {};
|
|
2763
|
+
return JSON.parse(raw);
|
|
2764
|
+
},
|
|
2765
|
+
build: (data) => JSON.stringify(data)
|
|
2766
|
+
};
|
|
2767
|
+
}
|
|
2768
|
+
const flpCatalogListSchema = jsonSchema();
|
|
2769
|
+
const flpCatalogSchema = jsonSchema();
|
|
2770
|
+
const flpGroupListSchema = jsonSchema();
|
|
2771
|
+
const flpGroupSchema = jsonSchema();
|
|
2772
|
+
const flpTileListSchema = jsonSchema();
|
|
2773
|
+
const flpTileSchema = jsonSchema();
|
|
2774
|
+
/** Extract `d.results` from an OData feed response. */
|
|
2775
|
+
function normalizeOdataFeed(response) {
|
|
2776
|
+
return response?.d?.results ?? [];
|
|
2777
|
+
}
|
|
2778
|
+
/** Extract `d` from an OData single-entity response. */
|
|
2779
|
+
function normalizeOdataEntity(response) {
|
|
2780
|
+
return response?.d;
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
//#endregion
|
|
2784
|
+
//#region src/adt/uifsa/catalogs.ts
|
|
2785
|
+
/**
|
|
2786
|
+
* Fiori Launchpad catalogs — `/sap/opu/odata/UI2/PAGE_BUILDER_PERS/Catalogs`.
|
|
2787
|
+
*
|
|
2788
|
+
* Read-only in v1 (E14 scope). Create/delete are handled by
|
|
2789
|
+
* `sap/flp/service.py` in sapcli but are out of scope here.
|
|
2790
|
+
*/
|
|
2791
|
+
const BASE$2 = "/sap/opu/odata/UI2/PAGE_BUILDER_PERS/Catalogs";
|
|
2792
|
+
/** Encode an OData entity key for use in the URL segment `Catalogs('<id>')`. */
|
|
2793
|
+
function encodeKey$2(id) {
|
|
2794
|
+
return `'${encodeURIComponent(id)}'`;
|
|
2795
|
+
}
|
|
2796
|
+
/** List all catalogs. */
|
|
2797
|
+
const list$2 = () => http$1.get(BASE$2, {
|
|
2798
|
+
query: { $format: "json" },
|
|
2799
|
+
responses: { 200: flpCatalogListSchema },
|
|
2800
|
+
headers: { Accept: "application/json" }
|
|
2801
|
+
});
|
|
2802
|
+
/** Get a single catalog by its ID (e.g. `X-SAP-UI2-CATALOGPAGE:SAP_A4C…`). */
|
|
2803
|
+
const get$2 = (id) => http$1.get(`${BASE$2}(${encodeKey$2(id)})`, {
|
|
2804
|
+
query: { $format: "json" },
|
|
2805
|
+
responses: { 200: flpCatalogSchema },
|
|
2806
|
+
headers: { Accept: "application/json" }
|
|
2807
|
+
});
|
|
2808
|
+
/** List tiles (chips) that belong to a specific catalog. */
|
|
2809
|
+
const tiles$1 = (id) => http$1.get(`${BASE$2}(${encodeKey$2(id)})/Chips`, {
|
|
2810
|
+
query: { $format: "json" },
|
|
2811
|
+
responses: { 200: flpTileListSchema },
|
|
2812
|
+
headers: { Accept: "application/json" }
|
|
2813
|
+
});
|
|
2814
|
+
const catalogs = {
|
|
2815
|
+
list: list$2,
|
|
2816
|
+
get: get$2,
|
|
2817
|
+
tiles: tiles$1
|
|
2818
|
+
};
|
|
2819
|
+
|
|
2820
|
+
//#endregion
|
|
2821
|
+
//#region src/adt/uifsa/groups.ts
|
|
2822
|
+
/**
|
|
2823
|
+
* Fiori Launchpad groups / pages — `/sap/opu/odata/UI2/PAGE_BUILDER_PERS/Pages`.
|
|
2824
|
+
*
|
|
2825
|
+
* Read-only in v1 (E14 scope).
|
|
2826
|
+
*/
|
|
2827
|
+
const BASE$1 = "/sap/opu/odata/UI2/PAGE_BUILDER_PERS/Pages";
|
|
2828
|
+
function encodeKey$1(id) {
|
|
2829
|
+
return `'${encodeURIComponent(id)}'`;
|
|
2830
|
+
}
|
|
2831
|
+
/** List all pages / groups. */
|
|
2832
|
+
const list$1 = () => http$1.get(BASE$1, {
|
|
2833
|
+
query: { $format: "json" },
|
|
2834
|
+
responses: { 200: flpGroupListSchema },
|
|
2835
|
+
headers: { Accept: "application/json" }
|
|
2836
|
+
});
|
|
2837
|
+
/** Get a single page / group by ID (e.g. `/UI2/SAMPLE_PAGE`). */
|
|
2838
|
+
const get$1 = (id) => http$1.get(`${BASE$1}(${encodeKey$1(id)})`, {
|
|
2839
|
+
query: { $format: "json" },
|
|
2840
|
+
responses: { 200: flpGroupSchema },
|
|
2841
|
+
headers: { Accept: "application/json" }
|
|
2842
|
+
});
|
|
2843
|
+
const groups = {
|
|
2844
|
+
list: list$1,
|
|
2845
|
+
get: get$1
|
|
2846
|
+
};
|
|
2847
|
+
|
|
2848
|
+
//#endregion
|
|
2849
|
+
//#region src/adt/uifsa/tiles.ts
|
|
2850
|
+
/**
|
|
2851
|
+
* Fiori Launchpad tiles (CHIPs) — `/sap/opu/odata/UI2/PAGE_BUILDER_PERS/Chips`.
|
|
2852
|
+
*
|
|
2853
|
+
* A "tile" in FLP is actually a CHIP (Collaborative Human Interface Part)
|
|
2854
|
+
* instance attached to a catalog / page. The Page Builder OData service
|
|
2855
|
+
* exposes them through the `Chips` entity set.
|
|
2856
|
+
*
|
|
2857
|
+
* Read-only in v1 (E14 scope).
|
|
2858
|
+
*/
|
|
2859
|
+
const BASE = "/sap/opu/odata/UI2/PAGE_BUILDER_PERS/Chips";
|
|
2860
|
+
function encodeKey(id) {
|
|
2861
|
+
return `'${encodeURIComponent(id)}'`;
|
|
2862
|
+
}
|
|
2863
|
+
/** List all tiles known to the system. */
|
|
2864
|
+
const list = () => http$1.get(BASE, {
|
|
2865
|
+
query: { $format: "json" },
|
|
2866
|
+
responses: { 200: flpTileListSchema },
|
|
2867
|
+
headers: { Accept: "application/json" }
|
|
2868
|
+
});
|
|
2869
|
+
/** Get a single tile by its CHIP ID (e.g. `X-SAP-UI2-CHIP:/UI2/STATIC_APPLAUNCHER`). */
|
|
2870
|
+
const get = (id) => http$1.get(`${BASE}(${encodeKey(id)})`, {
|
|
2871
|
+
query: { $format: "json" },
|
|
2872
|
+
responses: { 200: flpTileSchema },
|
|
2873
|
+
headers: { Accept: "application/json" }
|
|
2874
|
+
});
|
|
2875
|
+
const tiles = {
|
|
2876
|
+
list,
|
|
2877
|
+
get
|
|
2878
|
+
};
|
|
2879
|
+
|
|
2880
|
+
//#endregion
|
|
2881
|
+
//#region src/adt/uifsa/index.ts
|
|
2882
|
+
/**
|
|
2883
|
+
* FLP (Fiori Launchpad) contracts — `client.adt.flp.*`.
|
|
2884
|
+
*
|
|
2885
|
+
* NOTE: The directory is named `uifsa` to match the epic spec
|
|
2886
|
+
* (E14 pointed at `/sap/bc/adt/uifsa/`), but the actual endpoints
|
|
2887
|
+
* live on the Page Builder OData service (`/sap/opu/odata/UI2/
|
|
2888
|
+
* PAGE_BUILDER_PERS/`). The namespace on the client is `flp` —
|
|
2889
|
+
* matching sapcli's user-facing command name.
|
|
2890
|
+
*/
|
|
2891
|
+
const flpContract = {
|
|
2892
|
+
catalogs,
|
|
2893
|
+
groups,
|
|
2894
|
+
tiles
|
|
2895
|
+
};
|
|
2896
|
+
|
|
2897
|
+
//#endregion
|
|
2898
|
+
//#region src/adt/codeassistance/schema.ts
|
|
2899
|
+
function parseJsonOrRaw(raw) {
|
|
2900
|
+
if (!raw) return {};
|
|
2901
|
+
const trimmed = raw.trim();
|
|
2902
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) return JSON.parse(trimmed);
|
|
2903
|
+
return { raw };
|
|
2904
|
+
}
|
|
2905
|
+
const completionResponseSchema = {
|
|
2906
|
+
_infer: void 0,
|
|
2907
|
+
parse: parseJsonOrRaw,
|
|
2908
|
+
build: (value) => JSON.stringify(value)
|
|
2909
|
+
};
|
|
2910
|
+
const completionRequestSchema = {
|
|
2911
|
+
_infer: void 0,
|
|
2912
|
+
parse: (raw) => {
|
|
2913
|
+
if (!raw) return {};
|
|
2914
|
+
const trimmed = raw.trim();
|
|
2915
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) return JSON.parse(trimmed);
|
|
2916
|
+
return { source: raw };
|
|
2917
|
+
},
|
|
2918
|
+
build: (value) => JSON.stringify(value)
|
|
2919
|
+
};
|
|
2920
|
+
|
|
2921
|
+
//#endregion
|
|
2922
|
+
//#region src/adt/codeassistance/completion.ts
|
|
2923
|
+
/**
|
|
2924
|
+
* /sap/bc/adt/codeassistance/completion
|
|
2925
|
+
*/
|
|
2926
|
+
const completion = contract({ post: (query) => http$1.post("/sap/bc/adt/codeassistance/completion", {
|
|
2927
|
+
body: completionRequestSchema,
|
|
2928
|
+
responses: { 200: completionResponseSchema },
|
|
2929
|
+
headers: {
|
|
2930
|
+
Accept: "application/json",
|
|
2931
|
+
"Content-Type": "application/json"
|
|
2932
|
+
},
|
|
2933
|
+
query
|
|
2934
|
+
}) });
|
|
2935
|
+
|
|
2936
|
+
//#endregion
|
|
2937
|
+
//#region src/adt/codeassistance/index.ts
|
|
2938
|
+
const codeassistanceContract = { completion };
|
|
2939
|
+
|
|
2940
|
+
//#endregion
|
|
2941
|
+
//#region src/adt/vit/wb/objectproperties.ts
|
|
2942
|
+
/**
|
|
2943
|
+
* ADT vit/wb — Basic Object Properties (classic Workbench metadata).
|
|
2944
|
+
*
|
|
2945
|
+
* Endpoint template (from ADT discovery):
|
|
2946
|
+
* GET /sap/bc/adt/vit/wb/object_type/{type}/object_name/{name}
|
|
2947
|
+
*
|
|
2948
|
+
* Accept: application/vnd.sap.adt.basic.object.properties+xml
|
|
2949
|
+
* Response: adtcore:mainObject
|
|
2950
|
+
*
|
|
2951
|
+
* Classic BAdI uses vit types:
|
|
2952
|
+
* sxsdxd — BAdI definition (repository type SXSD/XD)
|
|
2953
|
+
* sxcixi — BAdI implementation (repository type SXCI/XI)
|
|
2954
|
+
*/
|
|
2955
|
+
const BASIC_OBJECT_PROPERTIES_MIME = "application/vnd.sap.adt.basic.object.properties+xml";
|
|
2956
|
+
/** vit/wb object_type segment for classic BAdI definitions. */
|
|
2957
|
+
const CLASSIC_BADI_DEFINITION_VIT_TYPE = "sxsdxd";
|
|
2958
|
+
/** vit/wb object_type segment for classic BAdI implementations. */
|
|
2959
|
+
const CLASSIC_BADI_IMPLEMENTATION_VIT_TYPE = "sxcixi";
|
|
2960
|
+
function objectPropertiesPath(vitType, objectName) {
|
|
2961
|
+
const normalizedType = vitType.trim().toLowerCase();
|
|
2962
|
+
const normalizedName = objectName.trim().toLowerCase();
|
|
2963
|
+
return `/sap/bc/adt/vit/wb/object_type/${encodeURIComponent(normalizedType)}/object_name/${encodeURIComponent(normalizedName)}`;
|
|
2964
|
+
}
|
|
2965
|
+
function getByVitType(vitType) {
|
|
2966
|
+
return (objectName) => http$1.get(objectPropertiesPath(vitType, objectName), {
|
|
2967
|
+
responses: { 200: adtcore },
|
|
2968
|
+
headers: { Accept: BASIC_OBJECT_PROPERTIES_MIME }
|
|
2969
|
+
});
|
|
2970
|
+
}
|
|
2971
|
+
/**
|
|
2972
|
+
* /sap/bc/adt/vit/wb/object_type/{type}/object_name/{name}
|
|
2973
|
+
*/
|
|
2974
|
+
const vitWbObjectPropertiesContract = contract({
|
|
2975
|
+
/** Generic read for any vit/wb object_type segment. */
|
|
2976
|
+
get: (params) => http$1.get(objectPropertiesPath(params.vitType, params.objectName), {
|
|
2977
|
+
responses: { 200: adtcore },
|
|
2978
|
+
headers: { Accept: BASIC_OBJECT_PROPERTIES_MIME }
|
|
2979
|
+
}),
|
|
2980
|
+
/** Classic BAdI definition (SXSD/XD). */
|
|
2981
|
+
getDefinition: getByVitType(CLASSIC_BADI_DEFINITION_VIT_TYPE),
|
|
2982
|
+
/** Classic BAdI implementation (SXCI/XI). */
|
|
2983
|
+
getImplementation: getByVitType(CLASSIC_BADI_IMPLEMENTATION_VIT_TYPE)
|
|
2984
|
+
});
|
|
2985
|
+
|
|
2986
|
+
//#endregion
|
|
2987
|
+
//#region src/adt/vit/index.ts
|
|
2988
|
+
const vitContract = { wb: { objectProperties: vitWbObjectPropertiesContract } };
|
|
2989
|
+
|
|
2990
|
+
//#endregion
|
|
2991
|
+
//#region src/adt/index.ts
|
|
2992
|
+
/**
|
|
2993
|
+
* Complete ADT Contract
|
|
2994
|
+
*/
|
|
2995
|
+
const adtContract = {
|
|
2996
|
+
cts: ctsContract,
|
|
2997
|
+
atc: atcContract,
|
|
2998
|
+
aunit: aunitContract,
|
|
2999
|
+
oo: ooContract,
|
|
3000
|
+
discovery: discoveryContract,
|
|
3001
|
+
packages: packagesContract,
|
|
3002
|
+
core: coreContract,
|
|
3003
|
+
repository: repositoryContract,
|
|
3004
|
+
programs: programsModuleContract,
|
|
3005
|
+
functions: functionsContract,
|
|
3006
|
+
ddic: ddicContract,
|
|
3007
|
+
system: systemContract,
|
|
3008
|
+
checkruns: checkrunsContract,
|
|
3009
|
+
activation: activationContract,
|
|
3010
|
+
datapreview: datapreviewContract,
|
|
3011
|
+
runtime: runtimeContract,
|
|
3012
|
+
gcts: gctsContract,
|
|
3013
|
+
bo: boContract,
|
|
3014
|
+
businessservices: businessservicesContract,
|
|
3015
|
+
enhancements: enhancementsContract,
|
|
3016
|
+
flp: flpContract,
|
|
3017
|
+
codeassistance: codeassistanceContract,
|
|
3018
|
+
vit: vitContract
|
|
3019
|
+
};
|
|
3020
|
+
|
|
3021
|
+
//#endregion
|
|
3022
|
+
//#region src/base.ts
|
|
3023
|
+
/**
|
|
3024
|
+
* Create a typed ADT REST client.
|
|
3025
|
+
*
|
|
3026
|
+
* Contract is already known - just pass adapter options.
|
|
3027
|
+
*/
|
|
3028
|
+
function createAdtClient(options) {
|
|
3029
|
+
return createClient(adtContract, options);
|
|
3030
|
+
}
|
|
3031
|
+
/**
|
|
3032
|
+
* Identity function for contract definitions.
|
|
3033
|
+
*
|
|
3034
|
+
* Schemas from ./schemas are already speci-compatible,
|
|
3035
|
+
* so this is just a pass-through for type safety and documentation.
|
|
3036
|
+
*
|
|
3037
|
+
* @example
|
|
3038
|
+
* ```ts
|
|
3039
|
+
* import { configurations } from './schemas';
|
|
3040
|
+
* import { contract, http } from '../base';
|
|
3041
|
+
*
|
|
3042
|
+
* export const myContract = contract({
|
|
3043
|
+
* get: () => http.get('/endpoint', {
|
|
3044
|
+
* responses: { 200: configurations },
|
|
3045
|
+
* }),
|
|
3046
|
+
* });
|
|
3047
|
+
* // Type is automatically inferred from configurations.parse() return type
|
|
3048
|
+
* ```
|
|
3049
|
+
*/
|
|
3050
|
+
function contract(definition) {
|
|
3051
|
+
return definition;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
3054
|
+
//#endregion
|
|
3055
|
+
export { coverageContract as $, usageReferencesContract as $t, gctsBranchesSchema as A, structuresContract as At, gctsPullSchema as B, objectstructureContract as Bt, enhancementsContract as C, dclContract as Ct, boContract as D, tabletypesContract as Dt, bindingsContract as E, ddlSourcesContract as Et, gctsCreateBranchResponseSchema as F, functionGroupsContract as Ft, runtimeContract as G, sourceversionsContract as Gt, gctsRepositorySchema as H, OBJECT_PROPERTIES_RESULT_MIME as Ht, gctsCreateRepositoryBodySchema as I, programsModuleContract as It, profile as J, SEARCH_REQUEST_MIME as Jt, dumps as K, SCOPE_REQUEST_MIME as Kt, gctsGenericOkSchema as L, includesContract as Lt, gctsCommitResponseSchema as M, domainsContract as Mt, gctsConfigSchema as N, functionsContract as Nt, behaviordefinitionsContract as O, tablesettingsContract as Ot, gctsCreateBranchBodySchema as P, functionModulesContract as Pt, runtimeTraceListSchema as Q, buildUsageScopeRequestXml as Qt, gctsLogSchema as R, programsContract as Rt, normalizeOdataFeed as S, ddlxSourcesContract as St, businessservicesContract as T, ddlContract as Tt, gctsSetConfigBodySchema as U, objectPropertiesContract as Ut, gctsRepositoriesSchema as V, informationsystemContract as Vt, gctsSetItemBodySchema as W, assertAdtRelativeUri as Wt, runtimeDumpListSchema as X, USAGEREFS_NAMESPACE as Xt, runtimeDumpDetailSchema as Y, SEARCH_RESPONSE_MIME as Yt, runtimeTraceDetailSchema as Z, buildUsageReferenceRequestXml as Zt, flpGroupListSchema as _, TransportStatus as _n, dtebSourcesContract as _t, vitContract as a, packagesContract as an, extractCoverageStatementUris as at, flpTileSchema as b, crud as bn, dsfdSourcesContract as bt, CLASSIC_BADI_IMPLEMENTATION_VIT_TYPE as c, classrunContract as cn, activationContract as ct, completion as d, aunitContract as dn, psesContract as dt, searchContract as en, statements as et, completionRequestSchema as f, atcContract as fn, usersContract as ft, flpCatalogSchema as g, TransportFunction as gn, dtebContract as gt, flpCatalogListSchema as h, ctsContract as hn, srvdSourcesContract as ht, adtContract as i, sessionsContract as in, coverageXmlBody as it, gctsCommitBodySchema as j, dataelementsContract as jt, gctsContract as k, tablesContract as kt, vitWbObjectPropertiesContract as l, interfacesContract as ln, checkrunsContract as lt, flpContract as m, worklistsContract as mn, srvdContract as mt, createAdtClient as n, httpContract as nn, buildCoverageQuery as nt, BASIC_OBJECT_PROPERTIES_MIME as o, discoveryContract as on, datapreviewContract as ot, completionResponseSchema as p, resultsContract as pn, ddicContract as pt, tracesContract as q, SCOPE_RESPONSE_MIME as qt, http$1 as r, systeminformationContract as rn, buildStatementsBulkRequest as rt, CLASSIC_BADI_DEFINITION_VIT_TYPE as s, ooContract as sn, freestyle as st, contract as t, coreContract as tn, measurements as tt, codeassistanceContract as u, classesContract as un, systemContract as ut, flpGroupSchema as v, normalizeTransportFindResponse as vn, dsfiContract as vt, enhoxhhContract as w, dclSourcesContract as wt, normalizeOdataEntity as x, repo as xn, ddlxContract as xt, flpTileListSchema as y, transports as yn, dsfdContract as yt, gctsObjectsSchema as z, repositoryContract as zt };
|
|
3056
|
+
//# sourceMappingURL=base-CJ5t6dbP.mjs.map
|