@mcp-abap-adt/adt-clients 7.3.1 → 7.4.2
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/clients/AdtClient.d.ts +32 -0
- package/dist/clients/AdtClient.d.ts.map +1 -1
- package/dist/clients/AdtClient.js +75 -30
- package/dist/core/accessControl/AdtAccessControl.d.ts +3 -1
- package/dist/core/accessControl/AdtAccessControl.d.ts.map +1 -1
- package/dist/core/accessControl/AdtAccessControl.js +11 -2
- package/dist/core/appendStructure/AdtAppendStructure.d.ts +3 -1
- package/dist/core/appendStructure/AdtAppendStructure.d.ts.map +1 -1
- package/dist/core/appendStructure/AdtAppendStructure.js +11 -2
- package/dist/core/authorizationField/AdtAuthorizationField.d.ts +3 -1
- package/dist/core/authorizationField/AdtAuthorizationField.d.ts.map +1 -1
- package/dist/core/authorizationField/AdtAuthorizationField.js +14 -3
- package/dist/core/behaviorDefinition/AdtBehaviorDefinition.d.ts +3 -1
- package/dist/core/behaviorDefinition/AdtBehaviorDefinition.d.ts.map +1 -1
- package/dist/core/behaviorDefinition/AdtBehaviorDefinition.js +11 -2
- package/dist/core/behaviorImplementation/AdtBehaviorImplementation.d.ts +2 -1
- package/dist/core/behaviorImplementation/AdtBehaviorImplementation.d.ts.map +1 -1
- package/dist/core/behaviorImplementation/AdtBehaviorImplementation.js +6 -3
- package/dist/core/class/AdtClass.d.ts +3 -1
- package/dist/core/class/AdtClass.d.ts.map +1 -1
- package/dist/core/class/AdtClass.js +16 -3
- package/dist/core/dataElement/AdtDataElement.d.ts +3 -1
- package/dist/core/dataElement/AdtDataElement.d.ts.map +1 -1
- package/dist/core/dataElement/AdtDataElement.js +9 -1
- package/dist/core/ddl/AdtDdl.d.ts +3 -1
- package/dist/core/ddl/AdtDdl.d.ts.map +1 -1
- package/dist/core/ddl/AdtDdl.js +11 -2
- package/dist/core/domain/AdtDomain.d.ts +3 -1
- package/dist/core/domain/AdtDomain.d.ts.map +1 -1
- package/dist/core/domain/AdtDomain.js +11 -1
- package/dist/core/enhancement/AdtEnhancement.d.ts +12 -1
- package/dist/core/enhancement/AdtEnhancement.d.ts.map +1 -1
- package/dist/core/enhancement/AdtEnhancement.js +35 -4
- package/dist/core/featureToggle/AdtFeatureToggle.d.ts +3 -1
- package/dist/core/featureToggle/AdtFeatureToggle.d.ts.map +1 -1
- package/dist/core/featureToggle/AdtFeatureToggle.js +14 -2
- package/dist/core/functionGroup/AdtFunctionGroup.d.ts +3 -1
- package/dist/core/functionGroup/AdtFunctionGroup.d.ts.map +1 -1
- package/dist/core/functionGroup/AdtFunctionGroup.js +9 -1
- package/dist/core/functionInclude/AdtFunctionInclude.d.ts +9 -1
- package/dist/core/functionInclude/AdtFunctionInclude.d.ts.map +1 -1
- package/dist/core/functionInclude/AdtFunctionInclude.js +33 -3
- package/dist/core/functionModule/AdtFunctionModule.d.ts +9 -1
- package/dist/core/functionModule/AdtFunctionModule.d.ts.map +1 -1
- package/dist/core/functionModule/AdtFunctionModule.js +27 -2
- package/dist/core/interface/AdtInterface.d.ts +3 -1
- package/dist/core/interface/AdtInterface.d.ts.map +1 -1
- package/dist/core/interface/AdtInterface.js +11 -2
- package/dist/core/messageClass/AdtMessageClass.d.ts +3 -1
- package/dist/core/messageClass/AdtMessageClass.d.ts.map +1 -1
- package/dist/core/messageClass/AdtMessageClass.js +11 -2
- package/dist/core/metadataExtension/AdtMetadataExtension.d.ts +3 -1
- package/dist/core/metadataExtension/AdtMetadataExtension.d.ts.map +1 -1
- package/dist/core/metadataExtension/AdtMetadataExtension.js +9 -1
- package/dist/core/package/AdtPackage.d.ts +3 -1
- package/dist/core/package/AdtPackage.d.ts.map +1 -1
- package/dist/core/package/AdtPackage.js +11 -2
- package/dist/core/program/AdtProgram.d.ts +3 -1
- package/dist/core/program/AdtProgram.d.ts.map +1 -1
- package/dist/core/program/AdtProgram.js +11 -2
- package/dist/core/scalarFunction/AdtScalarFunction.d.ts +3 -1
- package/dist/core/scalarFunction/AdtScalarFunction.d.ts.map +1 -1
- package/dist/core/scalarFunction/AdtScalarFunction.js +11 -2
- package/dist/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.d.ts +3 -1
- package/dist/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.d.ts.map +1 -1
- package/dist/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.js +14 -2
- package/dist/core/serviceDefinition/AdtServiceDefinition.d.ts +6 -3
- package/dist/core/serviceDefinition/AdtServiceDefinition.d.ts.map +1 -1
- package/dist/core/serviceDefinition/AdtServiceDefinition.js +14 -4
- package/dist/core/shared/LockRegistry.d.ts +77 -0
- package/dist/core/shared/LockRegistry.d.ts.map +1 -0
- package/dist/core/shared/LockRegistry.js +91 -0
- package/dist/core/structure/AdtStructure.d.ts +3 -1
- package/dist/core/structure/AdtStructure.d.ts.map +1 -1
- package/dist/core/structure/AdtStructure.js +11 -2
- package/dist/core/table/AdtTable.d.ts +3 -1
- package/dist/core/table/AdtTable.d.ts.map +1 -1
- package/dist/core/table/AdtTable.js +11 -2
- package/dist/core/tabletype/AdtDdicTableType.d.ts +3 -1
- package/dist/core/tabletype/AdtDdicTableType.d.ts.map +1 -1
- package/dist/core/tabletype/AdtDdicTableType.js +9 -1
- package/dist/core/transformation/AdtTransformation.d.ts +3 -1
- package/dist/core/transformation/AdtTransformation.d.ts.map +1 -1
- package/dist/core/transformation/AdtTransformation.js +11 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtFunctionModule.d.ts","sourceRoot":"","sources":["../../../src/core/functionModule/AdtFunctionModule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAS3E,qBAAa,iBACX,YAAW,UAAU,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;IAElE,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IACpD,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IACnD,SAAgB,UAAU,EAAE,MAAM,CAAoB;gBAGpD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"AdtFunctionModule.d.ts","sourceRoot":"","sources":["../../../src/core/functionModule/AdtFunctionModule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAS3E,qBAAa,iBACX,YAAW,UAAU,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;IAElE,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IACpD,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAe;IAC7C,SAAgB,UAAU,EAAE,MAAM,CAAoB;gBAGpD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,gBAAgB,EAC/B,YAAY,CAAC,EAAE,YAAY;IAS7B,6DAA6D;IAC7D,OAAO,CAAC,OAAO;IAIf,4EAA4E;IAC5E,OAAO,CAAC,SAAS;IAYjB,0DAA0D;IAC1D,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAmBhC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,qBAAqB,EAC7B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,oBAAoB,CAAC;IA0DhC;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IA6B5C;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,oBAAoB,CAAC;IA0ChC;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,oBAAoB,CAAC;IA8ChC;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,oBAAoB,CAAC;IA8OhC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAkChC;;;OAGG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAqBhC;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC;IAwBhC;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBnE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,CAAC;IAsBhC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC;IAIlD,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
|
|
@@ -36,12 +36,31 @@ class AdtFunctionModule {
|
|
|
36
36
|
logger;
|
|
37
37
|
systemContext;
|
|
38
38
|
contentTypes;
|
|
39
|
+
lockRegistry;
|
|
39
40
|
objectType = 'FunctionModule';
|
|
40
|
-
constructor(connection, logger, systemContext, contentTypes) {
|
|
41
|
+
constructor(connection, logger, systemContext, contentTypes, lockRegistry) {
|
|
41
42
|
this.connection = connection;
|
|
42
43
|
this.logger = logger;
|
|
43
44
|
this.systemContext = systemContext ?? {};
|
|
44
45
|
this.contentTypes = contentTypes;
|
|
46
|
+
this.lockRegistry = lockRegistry;
|
|
47
|
+
}
|
|
48
|
+
/** Registry key for a held lock (nested: group + module). */
|
|
49
|
+
lockKey(group, moduleName) {
|
|
50
|
+
return `${this.objectType}/${group.toUpperCase()}/${moduleName.toUpperCase()}`;
|
|
51
|
+
}
|
|
52
|
+
/** Record a held lock; the unlock thunk needs the parent function group. */
|
|
53
|
+
trackLock(group, moduleName, lockHandle) {
|
|
54
|
+
if (!group || !moduleName)
|
|
55
|
+
return;
|
|
56
|
+
// Raw unlock — LockRegistry.unlockAll() manages the session for the batch.
|
|
57
|
+
this.lockRegistry?.track(this.lockKey(group, moduleName), () => (0, unlock_1.unlockFunctionModule)(this.connection, group, moduleName, lockHandle));
|
|
58
|
+
}
|
|
59
|
+
/** Drop a lock from the registry after a clean unlock. */
|
|
60
|
+
untrackLock(group, moduleName) {
|
|
61
|
+
if (!group || !moduleName)
|
|
62
|
+
return;
|
|
63
|
+
this.lockRegistry?.untrack(this.lockKey(group, moduleName));
|
|
45
64
|
}
|
|
46
65
|
/**
|
|
47
66
|
* Validate function module configuration before creation
|
|
@@ -257,6 +276,7 @@ class AdtFunctionModule {
|
|
|
257
276
|
this.logger?.info?.('Step 1: Locking function module');
|
|
258
277
|
this.connection.setSessionType('stateful');
|
|
259
278
|
lockHandle = await (0, lock_1.lockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName);
|
|
279
|
+
this.trackLock(config.functionGroupName, config.functionModuleName, lockHandle);
|
|
260
280
|
this.logger?.info?.('Function module locked, handle:', lockHandle);
|
|
261
281
|
// 2. Check inactive with code for update (from options or config)
|
|
262
282
|
const codeToCheck = options?.sourceCode || config.sourceCode;
|
|
@@ -276,13 +296,14 @@ class AdtFunctionModule {
|
|
|
276
296
|
transportRequest: config.transportRequest,
|
|
277
297
|
}, this.contentTypes);
|
|
278
298
|
this.logger?.info?.('Function module updated');
|
|
299
|
+
// Poll the inactive version: the write above produced it; the active version may not exist yet.
|
|
279
300
|
// 3.5. Read with long polling (wait for object to be ready after update)
|
|
280
301
|
this.logger?.info?.('read (wait for object ready after update)');
|
|
281
302
|
try {
|
|
282
303
|
await this.read({
|
|
283
304
|
functionModuleName: config.functionModuleName,
|
|
284
305
|
functionGroupName: config.functionGroupName,
|
|
285
|
-
}, '
|
|
306
|
+
}, 'inactive', { withLongPolling: true });
|
|
286
307
|
this.logger?.info?.('object is ready after update');
|
|
287
308
|
}
|
|
288
309
|
catch (readError) {
|
|
@@ -296,6 +317,7 @@ class AdtFunctionModule {
|
|
|
296
317
|
this.connection.setSessionType('stateful');
|
|
297
318
|
await (0, unlock_1.unlockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName, lockHandle);
|
|
298
319
|
this.connection.setSessionType('stateless');
|
|
320
|
+
this.untrackLock(config.functionGroupName, config.functionModuleName);
|
|
299
321
|
lockHandle = undefined;
|
|
300
322
|
this.logger?.info?.('Function module unlocked');
|
|
301
323
|
}
|
|
@@ -344,6 +366,7 @@ class AdtFunctionModule {
|
|
|
344
366
|
this.connection.setSessionType('stateful');
|
|
345
367
|
await (0, unlock_1.unlockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName, lockHandle);
|
|
346
368
|
this.connection.setSessionType('stateless');
|
|
369
|
+
this.untrackLock(config.functionGroupName, config.functionModuleName);
|
|
347
370
|
}
|
|
348
371
|
catch (unlockError) {
|
|
349
372
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -451,6 +474,7 @@ class AdtFunctionModule {
|
|
|
451
474
|
}
|
|
452
475
|
this.connection.setSessionType('stateful');
|
|
453
476
|
const lockHandle = await (0, lock_1.lockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName);
|
|
477
|
+
this.trackLock(config.functionGroupName, config.functionModuleName, lockHandle);
|
|
454
478
|
return lockHandle;
|
|
455
479
|
}
|
|
456
480
|
/**
|
|
@@ -463,6 +487,7 @@ class AdtFunctionModule {
|
|
|
463
487
|
this.connection.setSessionType('stateful');
|
|
464
488
|
const result = await (0, unlock_1.unlockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName, lockHandle);
|
|
465
489
|
this.connection.setSessionType('stateless');
|
|
490
|
+
this.untrackLock(config.functionGroupName, config.functionModuleName);
|
|
466
491
|
return {
|
|
467
492
|
unlockResult: result,
|
|
468
493
|
errors: [],
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
21
21
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
22
22
|
import type { IAdtContentTypes } from '../shared/contentTypes';
|
|
23
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
23
24
|
import type { IReadOptions } from '../shared/types';
|
|
24
25
|
import type { IInterfaceConfig, IInterfaceState } from './types';
|
|
25
26
|
export declare class AdtInterface implements IAdtObject<IInterfaceConfig, IInterfaceState> {
|
|
@@ -27,8 +28,9 @@ export declare class AdtInterface implements IAdtObject<IInterfaceConfig, IInter
|
|
|
27
28
|
protected readonly logger?: ILogger;
|
|
28
29
|
protected readonly systemContext: IAdtSystemContext;
|
|
29
30
|
protected readonly contentTypes?: IAdtContentTypes;
|
|
31
|
+
private readonly lockTracker;
|
|
30
32
|
readonly objectType: string;
|
|
31
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes);
|
|
33
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes, lockRegistry?: LockRegistry);
|
|
32
34
|
/**
|
|
33
35
|
* Validate interface configuration before creation
|
|
34
36
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtInterface.d.ts","sourceRoot":"","sources":["../../../src/core/interface/AdtInterface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAMjE,qBAAa,YACX,YAAW,UAAU,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAExD,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IACpD,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IACnD,SAAgB,UAAU,EAAE,MAAM,CAAe;gBAG/C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"AdtInterface.d.ts","sourceRoot":"","sources":["../../../src/core/interface/AdtInterface.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.AdtInterface = void 0;
|
|
23
23
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
24
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
24
25
|
const activation_1 = require("./activation");
|
|
25
26
|
const check_1 = require("./check");
|
|
26
27
|
const create_1 = require("./create");
|
|
@@ -36,12 +37,14 @@ class AdtInterface {
|
|
|
36
37
|
logger;
|
|
37
38
|
systemContext;
|
|
38
39
|
contentTypes;
|
|
40
|
+
lockTracker;
|
|
39
41
|
objectType = 'Interface';
|
|
40
|
-
constructor(connection, logger, systemContext, contentTypes) {
|
|
42
|
+
constructor(connection, logger, systemContext, contentTypes, lockRegistry) {
|
|
41
43
|
this.connection = connection;
|
|
42
44
|
this.logger = logger;
|
|
43
45
|
this.systemContext = systemContext ?? {};
|
|
44
46
|
this.contentTypes = contentTypes;
|
|
47
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (interfaceName, lockHandle) => (0, unlock_1.unlockInterface)(this.connection, interfaceName, lockHandle));
|
|
45
48
|
}
|
|
46
49
|
/**
|
|
47
50
|
* Validate interface configuration before creation
|
|
@@ -198,6 +201,7 @@ class AdtInterface {
|
|
|
198
201
|
const lockResult = await (0, lock_1.lockInterface)(this.connection, config.interfaceName);
|
|
199
202
|
lockHandle = lockResult.lockHandle;
|
|
200
203
|
state.lockHandle = lockHandle;
|
|
204
|
+
this.lockTracker.track(config.interfaceName, lockHandle);
|
|
201
205
|
this.logger?.info?.('Interface locked, handle:', lockHandle);
|
|
202
206
|
// 2. Check inactive with code for update (from options or config)
|
|
203
207
|
const codeToCheck = options?.sourceCode || config.sourceCode;
|
|
@@ -213,10 +217,11 @@ class AdtInterface {
|
|
|
213
217
|
await (0, update_1.upload)(this.connection, config.interfaceName, codeToCheck, lockHandle, config.transportRequest, this.contentTypes?.sourceArtifactContentType());
|
|
214
218
|
// upload() returns void, so we don't store it in state
|
|
215
219
|
this.logger?.info?.('Interface updated');
|
|
220
|
+
// Poll the inactive version: the write above produced it; the active version may not exist yet.
|
|
216
221
|
// 3.5. Read with long polling to ensure object is ready after update
|
|
217
222
|
this.logger?.info?.('read (wait for object ready after update)');
|
|
218
223
|
try {
|
|
219
|
-
await this.read({ interfaceName: config.interfaceName }, '
|
|
224
|
+
await this.read({ interfaceName: config.interfaceName }, 'inactive', {
|
|
220
225
|
withLongPolling: true,
|
|
221
226
|
});
|
|
222
227
|
this.logger?.info?.('object is ready after update');
|
|
@@ -233,6 +238,7 @@ class AdtInterface {
|
|
|
233
238
|
const unlockResponse = await (0, unlock_1.unlockInterface)(this.connection, config.interfaceName, lockHandle);
|
|
234
239
|
state.unlockResult = unlockResponse;
|
|
235
240
|
this.connection.setSessionType('stateless');
|
|
241
|
+
this.lockTracker.untrack(config.interfaceName);
|
|
236
242
|
lockHandle = undefined;
|
|
237
243
|
this.logger?.info?.('Interface unlocked');
|
|
238
244
|
}
|
|
@@ -276,6 +282,7 @@ class AdtInterface {
|
|
|
276
282
|
this.connection.setSessionType('stateful');
|
|
277
283
|
await (0, unlock_1.unlockInterface)(this.connection, config.interfaceName, lockHandle);
|
|
278
284
|
this.connection.setSessionType('stateless');
|
|
285
|
+
this.lockTracker.untrack(config.interfaceName);
|
|
279
286
|
}
|
|
280
287
|
catch (unlockError) {
|
|
281
288
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -422,6 +429,7 @@ class AdtInterface {
|
|
|
422
429
|
}
|
|
423
430
|
this.connection.setSessionType('stateful');
|
|
424
431
|
const result = await (0, lock_1.lockInterface)(this.connection, config.interfaceName);
|
|
432
|
+
this.lockTracker.track(config.interfaceName, result.lockHandle);
|
|
425
433
|
return result.lockHandle;
|
|
426
434
|
}
|
|
427
435
|
/**
|
|
@@ -434,6 +442,7 @@ class AdtInterface {
|
|
|
434
442
|
this.connection.setSessionType('stateful');
|
|
435
443
|
const result = await (0, unlock_1.unlockInterface)(this.connection, config.interfaceName, lockHandle);
|
|
436
444
|
this.connection.setSessionType('stateless');
|
|
445
|
+
this.lockTracker.untrack(config.interfaceName);
|
|
437
446
|
return {
|
|
438
447
|
unlockResult: result,
|
|
439
448
|
errors: [],
|
|
@@ -15,13 +15,15 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger, IObjectVersion } from '@mcp-abap-adt/interfaces';
|
|
17
17
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
18
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
18
19
|
import type { IMessageClassConfig, IMessageClassState } from './types';
|
|
19
20
|
export declare class AdtMessageClass implements IAdtObject<IMessageClassConfig, IMessageClassState> {
|
|
20
21
|
private readonly connection;
|
|
21
22
|
private readonly logger?;
|
|
22
23
|
private readonly systemContext;
|
|
24
|
+
private readonly lockTracker;
|
|
23
25
|
readonly objectType: string;
|
|
24
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
|
|
26
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
|
|
25
27
|
/**
|
|
26
28
|
* Validate name + description via the ADT validation endpoint.
|
|
27
29
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtMessageClass.d.ts","sourceRoot":"","sources":["../../../src/core/messageClass/AdtMessageClass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"AdtMessageClass.d.ts","sourceRoot":"","sources":["../../../src/core/messageClass/AdtMessageClass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAOvE,qBAAa,eACX,YAAW,UAAU,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;IAE9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAkB;gBAGlD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAa7B;;OAEG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACnC,OAAO,CAAC,kBAAkB,CAAC;IAqB9B;;;OAGG;IACG,MAAM,CACV,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,kBAAkB,CAAC;IAoC9B;;;OAGG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACnC,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;IAsB1C;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACpC,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,kBAAkB,CAAC;IAwD9B;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACnC,OAAO,CAAC,kBAAkB,CAAC;IA2B9B;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACpC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;KAAE,GACvE,OAAO,CAAC,kBAAkB,CAAC;IAW9B;;;OAGG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACnC,OAAO,CAAC,kBAAkB,CAAC;IAO9B;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAUjE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACpC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC;IAc9B,yDAAyD;IACnD,QAAQ,CACZ,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACpC,OAAO,CAAC,kBAAkB,CAAC;IAO9B,yEAAyE;IACnE,KAAK,CACT,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACpC,OAAO,CAAC,kBAAkB,CAAC;IAI9B,4EAA4E;IACtE,WAAW,CACf,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACpC,OAAO,CAAC,cAAc,EAAE,CAAC;IAO5B,qFAAqF;IAC/E,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAG7D"}
|
|
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
18
|
exports.AdtMessageClass = void 0;
|
|
19
19
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
20
20
|
const timeouts_1 = require("../../utils/timeouts");
|
|
21
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
21
22
|
const unsupported_1 = require("../shared/unsupported");
|
|
22
23
|
const create_1 = require("./create");
|
|
23
24
|
const delete_1 = require("./delete");
|
|
@@ -31,11 +32,13 @@ class AdtMessageClass {
|
|
|
31
32
|
connection;
|
|
32
33
|
logger;
|
|
33
34
|
systemContext;
|
|
35
|
+
lockTracker;
|
|
34
36
|
objectType = 'MessageClass';
|
|
35
|
-
constructor(connection, logger, systemContext) {
|
|
37
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
36
38
|
this.connection = connection;
|
|
37
39
|
this.logger = logger;
|
|
38
40
|
this.systemContext = systemContext ?? {};
|
|
41
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockMessageClass)(this.connection, name, lockHandle));
|
|
39
42
|
}
|
|
40
43
|
/**
|
|
41
44
|
* Validate name + description via the ADT validation endpoint.
|
|
@@ -131,6 +134,7 @@ class AdtMessageClass {
|
|
|
131
134
|
this.logger?.info?.('lock');
|
|
132
135
|
this.connection.setSessionType('stateful');
|
|
133
136
|
lockHandle = await (0, lock_1.lockMessageClass)(this.connection, config.name);
|
|
137
|
+
this.lockTracker.track(config.name, lockHandle);
|
|
134
138
|
this.logger?.info?.('locked');
|
|
135
139
|
this.logger?.info?.('update');
|
|
136
140
|
const updateResult = await (0, update_1.updateMessageClass)(this.connection, config.name, lockHandle, config.description, config.transportRequest);
|
|
@@ -138,6 +142,7 @@ class AdtMessageClass {
|
|
|
138
142
|
this.logger?.info?.('unlock');
|
|
139
143
|
const unlockResult = await (0, unlock_1.unlockMessageClass)(this.connection, config.name, lockHandle);
|
|
140
144
|
this.connection.setSessionType('stateless');
|
|
145
|
+
this.lockTracker.untrack(config.name);
|
|
141
146
|
lockHandle = undefined;
|
|
142
147
|
this.logger?.info?.('unlocked');
|
|
143
148
|
return { updateResult, unlockResult, errors: [] };
|
|
@@ -148,6 +153,7 @@ class AdtMessageClass {
|
|
|
148
153
|
try {
|
|
149
154
|
this.logger?.warn?.('Unlocking message class during error cleanup');
|
|
150
155
|
await (0, unlock_1.unlockMessageClass)(this.connection, config.name, lockHandle);
|
|
156
|
+
this.lockTracker.untrack(config.name);
|
|
151
157
|
}
|
|
152
158
|
catch (unlockError) {
|
|
153
159
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -212,7 +218,9 @@ class AdtMessageClass {
|
|
|
212
218
|
throw new Error('Message class name is required');
|
|
213
219
|
}
|
|
214
220
|
this.connection.setSessionType('stateful');
|
|
215
|
-
|
|
221
|
+
const lockHandle = await (0, lock_1.lockMessageClass)(this.connection, config.name);
|
|
222
|
+
this.lockTracker.track(config.name, lockHandle);
|
|
223
|
+
return lockHandle;
|
|
216
224
|
}
|
|
217
225
|
/**
|
|
218
226
|
* Unlock message class (low-level).
|
|
@@ -223,6 +231,7 @@ class AdtMessageClass {
|
|
|
223
231
|
}
|
|
224
232
|
const unlockResult = await (0, unlock_1.unlockMessageClass)(this.connection, config.name, lockHandle);
|
|
225
233
|
this.connection.setSessionType('stateless');
|
|
234
|
+
this.lockTracker.untrack(config.name);
|
|
226
235
|
return { unlockResult, errors: [] };
|
|
227
236
|
}
|
|
228
237
|
/** Message classes are not activated — always throws. */
|
|
@@ -19,14 +19,16 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
21
21
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
22
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
22
23
|
import type { IReadOptions } from '../shared/types';
|
|
23
24
|
import type { IMetadataExtensionConfig, IMetadataExtensionState } from './types';
|
|
24
25
|
export declare class AdtMetadataExtension implements IAdtObject<IMetadataExtensionConfig, IMetadataExtensionState> {
|
|
25
26
|
private readonly connection;
|
|
26
27
|
private readonly logger?;
|
|
27
28
|
private readonly systemContext;
|
|
29
|
+
private readonly lockTracker;
|
|
28
30
|
readonly objectType: string;
|
|
29
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
|
|
31
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
|
|
30
32
|
/**
|
|
31
33
|
* Validate metadata extension configuration before creation
|
|
32
34
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtMetadataExtension.d.ts","sourceRoot":"","sources":["../../../src/core/metadataExtension/AdtMetadataExtension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AASjB,qBAAa,oBACX,YAAW,UAAU,CAAC,wBAAwB,EAAE,uBAAuB,CAAC;IAExE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,SAAgB,UAAU,EAAE,MAAM,CAAuB;gBAGvD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"AdtMetadataExtension.d.ts","sourceRoot":"","sources":["../../../src/core/metadataExtension/AdtMetadataExtension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AASjB,qBAAa,oBACX,YAAW,UAAU,CAAC,wBAAwB,EAAE,uBAAuB,CAAC;IAExE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAuB;gBAGvD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAa7B;;OAEG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAwBnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,wBAAwB,EAChC,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,uBAAuB,CAAC;IAyCnC;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC;IAqC/C;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,uBAAuB,CAAC;IAiCnC;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,uBAAuB,CAAC;IAoCnC;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC;IAoMnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAkCnC;;;OAGG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IA6BnC;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,uBAAuB,CAAC;IAoBnC;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IActE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,CAAC;IAmBnC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC;IAIrD,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.AdtMetadataExtension = void 0;
|
|
23
23
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
24
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
24
25
|
const activate_1 = require("./activate");
|
|
25
26
|
const check_1 = require("./check");
|
|
26
27
|
const create_1 = require("./create");
|
|
@@ -35,11 +36,13 @@ class AdtMetadataExtension {
|
|
|
35
36
|
connection;
|
|
36
37
|
logger;
|
|
37
38
|
systemContext;
|
|
39
|
+
lockTracker;
|
|
38
40
|
objectType = 'MetadataExtension';
|
|
39
|
-
constructor(connection, logger, systemContext) {
|
|
41
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
40
42
|
this.connection = connection;
|
|
41
43
|
this.logger = logger;
|
|
42
44
|
this.systemContext = systemContext ?? {};
|
|
45
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockMetadataExtension)(this.connection, name, lockHandle));
|
|
43
46
|
}
|
|
44
47
|
/**
|
|
45
48
|
* Validate metadata extension configuration before creation
|
|
@@ -232,6 +235,7 @@ class AdtMetadataExtension {
|
|
|
232
235
|
this.logger?.info?.('Step 1: Locking metadata extension');
|
|
233
236
|
this.connection.setSessionType('stateful');
|
|
234
237
|
lockHandle = await (0, lock_1.lockMetadataExtension)(this.connection, config.name);
|
|
238
|
+
this.lockTracker.track(config.name, lockHandle);
|
|
235
239
|
this.logger?.info?.('Metadata extension locked, handle:', lockHandle);
|
|
236
240
|
// 2. Check inactive with code for update (from options or config)
|
|
237
241
|
const codeToCheck = options?.sourceCode || config.sourceCode;
|
|
@@ -264,6 +268,7 @@ class AdtMetadataExtension {
|
|
|
264
268
|
this.connection.setSessionType('stateful');
|
|
265
269
|
await (0, unlock_1.unlockMetadataExtension)(this.connection, config.name, lockHandle);
|
|
266
270
|
this.connection.setSessionType('stateless');
|
|
271
|
+
this.lockTracker.untrack(config.name);
|
|
267
272
|
lockHandle = undefined;
|
|
268
273
|
this.logger?.info?.('Metadata extension unlocked');
|
|
269
274
|
}
|
|
@@ -311,6 +316,7 @@ class AdtMetadataExtension {
|
|
|
311
316
|
this.connection.setSessionType('stateful');
|
|
312
317
|
await (0, unlock_1.unlockMetadataExtension)(this.connection, config.name, lockHandle);
|
|
313
318
|
this.connection.setSessionType('stateless');
|
|
319
|
+
this.lockTracker.untrack(config.name);
|
|
314
320
|
}
|
|
315
321
|
catch (unlockError) {
|
|
316
322
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -419,6 +425,7 @@ class AdtMetadataExtension {
|
|
|
419
425
|
}
|
|
420
426
|
this.connection.setSessionType('stateful');
|
|
421
427
|
const lockHandle = await (0, lock_1.lockMetadataExtension)(this.connection, config.name);
|
|
428
|
+
this.lockTracker.track(config.name, lockHandle);
|
|
422
429
|
return lockHandle;
|
|
423
430
|
}
|
|
424
431
|
/**
|
|
@@ -431,6 +438,7 @@ class AdtMetadataExtension {
|
|
|
431
438
|
this.connection.setSessionType('stateful');
|
|
432
439
|
const result = await (0, unlock_1.unlockMetadataExtension)(this.connection, config.name, lockHandle);
|
|
433
440
|
this.connection.setSessionType('stateless');
|
|
441
|
+
this.lockTracker.untrack(config.name);
|
|
434
442
|
return {
|
|
435
443
|
unlockResult: result,
|
|
436
444
|
errors: [],
|
|
@@ -22,14 +22,16 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger, IObjectVersion } from '@mcp-abap-adt/interfaces';
|
|
24
24
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
25
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
25
26
|
import type { IReadOptions } from '../shared/types';
|
|
26
27
|
import type { IPackageConfig, IPackageState } from './types';
|
|
27
28
|
export declare class AdtPackage implements IAdtObject<IPackageConfig, IPackageState> {
|
|
28
29
|
protected readonly connection: IAbapConnection;
|
|
29
30
|
protected readonly logger?: ILogger;
|
|
30
31
|
protected readonly systemContext: IAdtSystemContext;
|
|
32
|
+
private readonly lockTracker;
|
|
31
33
|
readonly objectType: string;
|
|
32
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
|
|
34
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
|
|
33
35
|
/**
|
|
34
36
|
* Validate package configuration before creation
|
|
35
37
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtPackage.d.ts","sourceRoot":"","sources":["../../../src/core/package/AdtPackage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAOpD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7D,qBAAa,UAAW,YAAW,UAAU,CAAC,cAAc,EAAE,aAAa,CAAC;IAC1E,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IACpD,SAAgB,UAAU,EAAE,MAAM,CAAa;gBAG7C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"AdtPackage.d.ts","sourceRoot":"","sources":["../../../src/core/package/AdtPackage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAOpD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7D,qBAAa,UAAW,YAAW,UAAU,CAAC,cAAc,EAAE,aAAa,CAAC;IAC1E,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,SAAgB,UAAU,EAAE,MAAM,CAAa;gBAG7C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAa7B;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IA2BvE;;;OAGG;IACG,MAAM,CACV,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,aAAa,CAAC;IAsGzB;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAC/B,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IA0BrC;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,aAAa,CAAC;IAoCzB;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAC/B,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,aAAa,CAAC;IAkCzB;;;;;OAKG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAC/B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,aAAa,CAAC;IAyLzB;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IA6BrE;;;OAGG;IACG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IAMxE;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,CAAC;IAkBzB;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAW5D;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,EAC/B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;IAmBnB,WAAW,CACf,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,cAAc,EAAE,CAAC;IAItB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAG7D"}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.AdtPackage = void 0;
|
|
26
26
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
27
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
27
28
|
const versions_1 = require("../shared/versions");
|
|
28
29
|
const check_1 = require("./check");
|
|
29
30
|
const create_1 = require("./create");
|
|
@@ -37,11 +38,13 @@ class AdtPackage {
|
|
|
37
38
|
connection;
|
|
38
39
|
logger;
|
|
39
40
|
systemContext;
|
|
41
|
+
lockTracker;
|
|
40
42
|
objectType = 'Package';
|
|
41
|
-
constructor(connection, logger, systemContext) {
|
|
43
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
42
44
|
this.connection = connection;
|
|
43
45
|
this.logger = logger;
|
|
44
46
|
this.systemContext = systemContext ?? {};
|
|
47
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (packageName, lockHandle) => (0, unlock_1.unlockPackage)(this.connection, packageName, lockHandle));
|
|
45
48
|
}
|
|
46
49
|
/**
|
|
47
50
|
* Validate package configuration before creation
|
|
@@ -306,6 +309,7 @@ class AdtPackage {
|
|
|
306
309
|
const lockResult = await (0, lock_1.lockPackage)(this.connection, config.packageName);
|
|
307
310
|
lockHandle = lockResult.lockHandle;
|
|
308
311
|
lockCorrNr = lockResult.corrNr;
|
|
312
|
+
this.lockTracker.track(config.packageName, lockHandle);
|
|
309
313
|
this.logger?.info?.(`Package locked, handle: ${lockHandle}, corrNr: ${lockCorrNr}`);
|
|
310
314
|
// 2. Check inactive with XML for update (if provided)
|
|
311
315
|
const xmlToCheck = options?.xmlContent;
|
|
@@ -333,10 +337,11 @@ class AdtPackage {
|
|
|
333
337
|
record_changes: config.recordChanges,
|
|
334
338
|
}, lockHandle);
|
|
335
339
|
this.logger?.info?.('Package updated');
|
|
340
|
+
// Poll the inactive version: the write above produced it; the active version may not exist yet.
|
|
336
341
|
// 3.5. Read with long polling (wait for object to be ready after update)
|
|
337
342
|
this.logger?.info?.('read (wait for object ready after update)');
|
|
338
343
|
try {
|
|
339
|
-
await this.read({ packageName: config.packageName }, '
|
|
344
|
+
await this.read({ packageName: config.packageName }, 'inactive', {
|
|
340
345
|
withLongPolling: true,
|
|
341
346
|
});
|
|
342
347
|
this.logger?.info?.('object is ready after update');
|
|
@@ -352,6 +357,7 @@ class AdtPackage {
|
|
|
352
357
|
this.connection.setSessionType('stateful');
|
|
353
358
|
await (0, unlock_1.unlockPackage)(this.connection, config.packageName, lockHandle);
|
|
354
359
|
this.connection.setSessionType('stateless');
|
|
360
|
+
this.lockTracker.untrack(config.packageName);
|
|
355
361
|
lockHandle = undefined;
|
|
356
362
|
this.logger?.info?.('Package unlocked');
|
|
357
363
|
}
|
|
@@ -371,6 +377,7 @@ class AdtPackage {
|
|
|
371
377
|
this.connection.setSessionType('stateful');
|
|
372
378
|
await (0, unlock_1.unlockPackage)(this.connection, config.packageName, lockHandle);
|
|
373
379
|
this.connection.setSessionType('stateless');
|
|
380
|
+
this.lockTracker.untrack(config.packageName);
|
|
374
381
|
}
|
|
375
382
|
catch (unlockError) {
|
|
376
383
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -456,6 +463,7 @@ class AdtPackage {
|
|
|
456
463
|
}
|
|
457
464
|
this.connection.setSessionType('stateful');
|
|
458
465
|
const lockResult = await (0, lock_1.lockPackage)(this.connection, config.packageName);
|
|
466
|
+
this.lockTracker.track(config.packageName, lockResult.lockHandle);
|
|
459
467
|
return lockResult.lockHandle;
|
|
460
468
|
}
|
|
461
469
|
/**
|
|
@@ -468,6 +476,7 @@ class AdtPackage {
|
|
|
468
476
|
this.connection.setSessionType('stateful');
|
|
469
477
|
const result = await (0, unlock_1.unlockPackage)(this.connection, config.packageName, lockHandle);
|
|
470
478
|
this.connection.setSessionType('stateless');
|
|
479
|
+
this.lockTracker.untrack(config.packageName);
|
|
471
480
|
return {
|
|
472
481
|
unlockResult: result,
|
|
473
482
|
errors: [],
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
21
21
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
22
22
|
import type { IAdtContentTypes } from '../shared/contentTypes';
|
|
23
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
23
24
|
import type { IReadOptions } from '../shared/types';
|
|
24
25
|
import type { IProgramConfig, IProgramState } from './types';
|
|
25
26
|
export declare class AdtProgram implements IAdtObject<IProgramConfig, IProgramState> {
|
|
@@ -27,8 +28,9 @@ export declare class AdtProgram implements IAdtObject<IProgramConfig, IProgramSt
|
|
|
27
28
|
protected readonly logger?: ILogger;
|
|
28
29
|
protected readonly systemContext: IAdtSystemContext;
|
|
29
30
|
protected readonly contentTypes?: IAdtContentTypes;
|
|
31
|
+
private readonly lockTracker;
|
|
30
32
|
readonly objectType: string;
|
|
31
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes);
|
|
33
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes, lockRegistry?: LockRegistry);
|
|
32
34
|
/**
|
|
33
35
|
* Validate program configuration before creation
|
|
34
36
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtProgram.d.ts","sourceRoot":"","sources":["../../../src/core/program/AdtProgram.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAWpD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7D,qBAAa,UAAW,YAAW,UAAU,CAAC,cAAc,EAAE,aAAa,CAAC;IAC1E,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IACpD,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IACnD,SAAgB,UAAU,EAAE,MAAM,CAAa;gBAG7C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"AdtProgram.d.ts","sourceRoot":"","sources":["../../../src/core/program/AdtProgram.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.AdtProgram = void 0;
|
|
23
23
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
24
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
24
25
|
const activation_1 = require("./activation");
|
|
25
26
|
const check_1 = require("./check");
|
|
26
27
|
const create_1 = require("./create");
|
|
@@ -36,12 +37,14 @@ class AdtProgram {
|
|
|
36
37
|
logger;
|
|
37
38
|
systemContext;
|
|
38
39
|
contentTypes;
|
|
40
|
+
lockTracker;
|
|
39
41
|
objectType = 'Program';
|
|
40
|
-
constructor(connection, logger, systemContext, contentTypes) {
|
|
42
|
+
constructor(connection, logger, systemContext, contentTypes, lockRegistry) {
|
|
41
43
|
this.connection = connection;
|
|
42
44
|
this.logger = logger;
|
|
43
45
|
this.systemContext = systemContext ?? {};
|
|
44
46
|
this.contentTypes = contentTypes;
|
|
47
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (programName, lockHandle) => (0, unlock_1.unlockProgram)(this.connection, programName, lockHandle));
|
|
45
48
|
}
|
|
46
49
|
/**
|
|
47
50
|
* Validate program configuration before creation
|
|
@@ -219,6 +222,7 @@ class AdtProgram {
|
|
|
219
222
|
this.connection.setSessionType('stateful');
|
|
220
223
|
lockHandle = await (0, lock_1.lockProgram)(this.connection, config.programName);
|
|
221
224
|
state.lockHandle = lockHandle;
|
|
225
|
+
this.lockTracker.track(config.programName, lockHandle);
|
|
222
226
|
this.logger?.info?.('Program locked, handle:', lockHandle);
|
|
223
227
|
// 2. Check inactive with code for update (from options or config)
|
|
224
228
|
const codeToCheck = options?.sourceCode || config.sourceCode;
|
|
@@ -234,10 +238,11 @@ class AdtProgram {
|
|
|
234
238
|
const updateResponse = await (0, update_1.uploadProgramSource)(this.connection, config.programName, codeToCheck, lockHandle, sessionId, config.transportRequest);
|
|
235
239
|
state.updateResult = updateResponse;
|
|
236
240
|
this.logger?.info?.('Program updated');
|
|
241
|
+
// Poll the inactive version: the write above produced it; the active version may not exist yet.
|
|
237
242
|
// 3.5. Read with long polling to ensure object is ready after update
|
|
238
243
|
this.logger?.info?.('read (wait for object ready after update)');
|
|
239
244
|
try {
|
|
240
|
-
await this.read({ programName: config.programName }, '
|
|
245
|
+
await this.read({ programName: config.programName }, 'inactive', {
|
|
241
246
|
withLongPolling: true,
|
|
242
247
|
});
|
|
243
248
|
this.logger?.info?.('object is ready after update');
|
|
@@ -254,6 +259,7 @@ class AdtProgram {
|
|
|
254
259
|
const unlockResponse = await (0, unlock_1.unlockProgram)(this.connection, config.programName, lockHandle);
|
|
255
260
|
state.unlockResult = unlockResponse;
|
|
256
261
|
this.connection.setSessionType('stateless');
|
|
262
|
+
this.lockTracker.untrack(config.programName);
|
|
257
263
|
lockHandle = undefined;
|
|
258
264
|
this.logger?.info?.('Program unlocked');
|
|
259
265
|
}
|
|
@@ -292,6 +298,7 @@ class AdtProgram {
|
|
|
292
298
|
this.connection.setSessionType('stateful');
|
|
293
299
|
await (0, unlock_1.unlockProgram)(this.connection, config.programName, lockHandle);
|
|
294
300
|
this.connection.setSessionType('stateless');
|
|
301
|
+
this.lockTracker.untrack(config.programName);
|
|
295
302
|
}
|
|
296
303
|
catch (unlockError) {
|
|
297
304
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -453,6 +460,7 @@ class AdtProgram {
|
|
|
453
460
|
}
|
|
454
461
|
this.connection.setSessionType('stateful');
|
|
455
462
|
const lockHandle = await (0, lock_1.lockProgram)(this.connection, config.programName);
|
|
463
|
+
this.lockTracker.track(config.programName, lockHandle);
|
|
456
464
|
return lockHandle;
|
|
457
465
|
}
|
|
458
466
|
/**
|
|
@@ -465,6 +473,7 @@ class AdtProgram {
|
|
|
465
473
|
this.connection.setSessionType('stateful');
|
|
466
474
|
const result = await (0, unlock_1.unlockProgram)(this.connection, config.programName, lockHandle);
|
|
467
475
|
this.connection.setSessionType('stateless');
|
|
476
|
+
this.lockTracker.untrack(config.programName);
|
|
468
477
|
return {
|
|
469
478
|
unlockResult: result,
|
|
470
479
|
errors: [],
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
6
6
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
7
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
7
8
|
import type { IReadOptions } from '../shared/types';
|
|
8
9
|
import type { IScalarFunctionConfig, IScalarFunctionState } from './types';
|
|
9
10
|
export declare class AdtScalarFunction implements IAdtObject<IScalarFunctionConfig, IScalarFunctionState> {
|
|
10
11
|
private readonly connection;
|
|
11
12
|
private readonly logger?;
|
|
12
13
|
private readonly systemContext;
|
|
14
|
+
private readonly lockTracker;
|
|
13
15
|
readonly objectType: string;
|
|
14
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
|
|
16
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
|
|
15
17
|
validate(config: Partial<IScalarFunctionConfig>): Promise<IScalarFunctionState>;
|
|
16
18
|
create(config: IScalarFunctionConfig, _options?: IAdtOperationOptions): Promise<IScalarFunctionState>;
|
|
17
19
|
read(config: Partial<IScalarFunctionConfig>, version?: 'active' | 'inactive', options?: IReadOptions): Promise<IScalarFunctionState | undefined>;
|