@mcp-abap-adt/adt-clients 7.3.0 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +9 -1
- 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 +9 -1
- 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 +9 -1
- 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 +4 -2
- 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 +14 -2
- 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 +9 -1
- 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 +28 -1
- 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 +12 -1
- 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 +28 -1
- 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 +25 -1
- 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 +9 -1
- package/dist/core/messageClass/AdtMessageClass.d.ts +5 -4
- package/dist/core/messageClass/AdtMessageClass.d.ts.map +1 -1
- package/dist/core/messageClass/AdtMessageClass.js +16 -8
- package/dist/core/messageClass/AdtMessageClassMessage.d.ts +2 -1
- package/dist/core/messageClass/AdtMessageClassMessage.d.ts.map +1 -1
- package/dist/core/messageClass/AdtMessageClassMessage.js +10 -3
- package/dist/core/messageClass/create.d.ts +3 -5
- package/dist/core/messageClass/create.d.ts.map +1 -1
- package/dist/core/messageClass/create.js +7 -6
- package/dist/core/messageClass/delete.d.ts +3 -3
- package/dist/core/messageClass/delete.d.ts.map +1 -1
- package/dist/core/messageClass/delete.js +7 -4
- package/dist/core/messageClass/types.d.ts +2 -2
- package/dist/core/messageClass/types.d.ts.map +1 -1
- package/dist/core/messageClass/update.d.ts +1 -1
- package/dist/core/messageClass/update.d.ts.map +1 -1
- package/dist/core/messageClass/update.js +5 -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 +9 -1
- 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 +9 -1
- 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 +3 -1
- package/dist/core/serviceDefinition/AdtServiceDefinition.d.ts.map +1 -1
- package/dist/core/serviceDefinition/AdtServiceDefinition.js +9 -1
- 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 +9 -1
- 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 +9 -1
- 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 +9 -1
- package/package.json +1 -1
|
@@ -26,14 +26,25 @@
|
|
|
26
26
|
*/
|
|
27
27
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
28
28
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
29
|
+
import type { LockRegistry } from '../shared/LockRegistry';
|
|
29
30
|
import type { IReadOptions } from '../shared/types';
|
|
30
31
|
import { type IEnhancementConfig, type IEnhancementState } from './types';
|
|
31
32
|
export declare class AdtEnhancement implements IAdtObject<IEnhancementConfig, IEnhancementState> {
|
|
32
33
|
private readonly connection;
|
|
33
34
|
private readonly logger?;
|
|
34
35
|
private readonly systemContext;
|
|
36
|
+
private readonly lockRegistry?;
|
|
35
37
|
readonly objectType: string;
|
|
36
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
|
|
38
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
|
|
39
|
+
/** Registry key for a held enhancement lock (e.g. `Enhancement/ZFOO`). */
|
|
40
|
+
private lockKey;
|
|
41
|
+
/**
|
|
42
|
+
* Record a held lock. Enhancement unlock needs the enhancement type, so the
|
|
43
|
+
* unlock thunk captures it alongside the name and handle.
|
|
44
|
+
*/
|
|
45
|
+
private trackLock;
|
|
46
|
+
/** Drop a lock from the registry after a clean unlock. */
|
|
47
|
+
private untrackLock;
|
|
37
48
|
/**
|
|
38
49
|
* Validate enhancement configuration before creation
|
|
39
50
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtEnhancement.d.ts","sourceRoot":"","sources":["../../../src/core/enhancement/AdtEnhancement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;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,
|
|
1
|
+
{"version":3,"file":"AdtEnhancement.d.ts","sourceRoot":"","sources":["../../../src/core/enhancement/AdtEnhancement.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,11 +43,33 @@ class AdtEnhancement {
|
|
|
43
43
|
connection;
|
|
44
44
|
logger;
|
|
45
45
|
systemContext;
|
|
46
|
+
lockRegistry;
|
|
46
47
|
objectType = 'Enhancement';
|
|
47
|
-
constructor(connection, logger, systemContext) {
|
|
48
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
48
49
|
this.connection = connection;
|
|
49
50
|
this.logger = logger;
|
|
50
51
|
this.systemContext = systemContext ?? {};
|
|
52
|
+
this.lockRegistry = lockRegistry;
|
|
53
|
+
}
|
|
54
|
+
/** Registry key for a held enhancement lock (e.g. `Enhancement/ZFOO`). */
|
|
55
|
+
lockKey(name) {
|
|
56
|
+
return `${this.objectType}/${name.toUpperCase()}`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Record a held lock. Enhancement unlock needs the enhancement type, so the
|
|
60
|
+
* unlock thunk captures it alongside the name and handle.
|
|
61
|
+
*/
|
|
62
|
+
trackLock(type, name, lockHandle) {
|
|
63
|
+
if (!type || !name)
|
|
64
|
+
return;
|
|
65
|
+
// Raw unlock — LockRegistry.unlockAll() manages the session for the batch.
|
|
66
|
+
this.lockRegistry?.track(this.lockKey(name), () => (0, unlock_1.unlockEnhancement)(this.connection, type, name, lockHandle));
|
|
67
|
+
}
|
|
68
|
+
/** Drop a lock from the registry after a clean unlock. */
|
|
69
|
+
untrackLock(name) {
|
|
70
|
+
if (!name)
|
|
71
|
+
return;
|
|
72
|
+
this.lockRegistry?.untrack(this.lockKey(name));
|
|
51
73
|
}
|
|
52
74
|
/**
|
|
53
75
|
* Validate enhancement configuration before creation
|
|
@@ -327,6 +349,7 @@ class AdtEnhancement {
|
|
|
327
349
|
this.connection.setSessionType('stateful');
|
|
328
350
|
lockHandle = await (0, lock_1.lockEnhancement)(this.connection, config.enhancementType, config.enhancementName);
|
|
329
351
|
state.lockHandle = lockHandle;
|
|
352
|
+
this.trackLock(config.enhancementType, config.enhancementName, lockHandle);
|
|
330
353
|
this.logger?.info?.('Enhancement locked, handle:', lockHandle);
|
|
331
354
|
// 2. Check inactive with code for update (from options or config)
|
|
332
355
|
const codeToCheck = options?.sourceCode || config.sourceCode;
|
|
@@ -368,6 +391,7 @@ class AdtEnhancement {
|
|
|
368
391
|
const unlockResponse = await (0, unlock_1.unlockEnhancement)(this.connection, config.enhancementType, config.enhancementName, lockHandle);
|
|
369
392
|
state.unlockResult = unlockResponse;
|
|
370
393
|
this.connection.setSessionType('stateless');
|
|
394
|
+
this.untrackLock(config.enhancementName);
|
|
371
395
|
lockHandle = undefined;
|
|
372
396
|
this.logger?.info?.('Enhancement unlocked');
|
|
373
397
|
}
|
|
@@ -409,6 +433,7 @@ class AdtEnhancement {
|
|
|
409
433
|
this.connection.setSessionType('stateful');
|
|
410
434
|
await (0, unlock_1.unlockEnhancement)(this.connection, config.enhancementType, config.enhancementName, lockHandle);
|
|
411
435
|
this.connection.setSessionType('stateless');
|
|
436
|
+
this.untrackLock(config.enhancementName);
|
|
412
437
|
}
|
|
413
438
|
catch (unlockError) {
|
|
414
439
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -559,6 +584,7 @@ class AdtEnhancement {
|
|
|
559
584
|
}
|
|
560
585
|
this.connection.setSessionType('stateful');
|
|
561
586
|
const lockHandle = await (0, lock_1.lockEnhancement)(this.connection, config.enhancementType, config.enhancementName);
|
|
587
|
+
this.trackLock(config.enhancementType, config.enhancementName, lockHandle);
|
|
562
588
|
return lockHandle;
|
|
563
589
|
}
|
|
564
590
|
/**
|
|
@@ -571,6 +597,7 @@ class AdtEnhancement {
|
|
|
571
597
|
this.connection.setSessionType('stateful');
|
|
572
598
|
const result = await (0, unlock_1.unlockEnhancement)(this.connection, config.enhancementType, config.enhancementName, lockHandle);
|
|
573
599
|
this.connection.setSessionType('stateless');
|
|
600
|
+
this.untrackLock(config.enhancementName);
|
|
574
601
|
return {
|
|
575
602
|
unlockResult: result,
|
|
576
603
|
errors: [],
|
|
@@ -20,14 +20,16 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import type { IAbapConnection, IAdtOperationOptions, ILogger, IObjectVersion } from '@mcp-abap-adt/interfaces';
|
|
22
22
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
23
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
23
24
|
import { type IReadOptions } from './read';
|
|
24
25
|
import type { IFeatureToggleConfig, IFeatureToggleObject, IFeatureToggleState } from './types';
|
|
25
26
|
export declare class AdtFeatureToggle implements IFeatureToggleObject {
|
|
26
27
|
private readonly connection;
|
|
27
28
|
private readonly logger?;
|
|
28
29
|
private readonly systemContext;
|
|
30
|
+
private readonly lockTracker;
|
|
29
31
|
readonly objectType: string;
|
|
30
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
|
|
32
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
|
|
31
33
|
/**
|
|
32
34
|
* Map camelCase config to the snake_case low-level params.
|
|
33
35
|
* `source` is passed through unchanged (it is a structured JSON object,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtFeatureToggle.d.ts","sourceRoot":"","sources":["../../../src/core/featureToggle/AdtFeatureToggle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,oBAAoB,EACpB,OAAO,EACP,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"AdtFeatureToggle.d.ts","sourceRoot":"","sources":["../../../src/core/featureToggle/AdtFeatureToggle.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.AdtFeatureToggle = void 0;
|
|
24
24
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
25
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
25
26
|
const versions_1 = require("../shared/versions");
|
|
26
27
|
const activation_1 = require("./activation");
|
|
27
28
|
const check_1 = require("./check");
|
|
@@ -41,11 +42,13 @@ class AdtFeatureToggle {
|
|
|
41
42
|
connection;
|
|
42
43
|
logger;
|
|
43
44
|
systemContext;
|
|
45
|
+
lockTracker;
|
|
44
46
|
objectType = 'FeatureToggle';
|
|
45
|
-
constructor(connection, logger, systemContext) {
|
|
47
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
46
48
|
this.connection = connection;
|
|
47
49
|
this.logger = logger;
|
|
48
50
|
this.systemContext = systemContext ?? {};
|
|
51
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (featureToggleName, lockHandle) => (0, unlock_1.unlockFeatureToggle)(this.connection, featureToggleName, lockHandle));
|
|
49
52
|
}
|
|
50
53
|
/**
|
|
51
54
|
* Map camelCase config to the snake_case low-level params.
|
|
@@ -112,6 +115,7 @@ class AdtFeatureToggle {
|
|
|
112
115
|
this.connection.setSessionType('stateful');
|
|
113
116
|
lockHandle = await (0, lock_1.lockFeatureToggle)(this.connection, config.featureToggleName, this.logger);
|
|
114
117
|
state.lockHandle = lockHandle;
|
|
118
|
+
this.lockTracker.track(config.featureToggleName, lockHandle);
|
|
115
119
|
config.onLock?.(lockHandle);
|
|
116
120
|
this.logger?.info?.('Feature toggle locked, handle:', lockHandle);
|
|
117
121
|
// 2. Upload source
|
|
@@ -121,6 +125,7 @@ class AdtFeatureToggle {
|
|
|
121
125
|
this.connection.setSessionType('stateful');
|
|
122
126
|
await (0, unlock_1.unlockFeatureToggle)(this.connection, config.featureToggleName, lockHandle);
|
|
123
127
|
this.connection.setSessionType('stateless');
|
|
128
|
+
this.lockTracker.untrack(config.featureToggleName);
|
|
124
129
|
lockHandle = undefined;
|
|
125
130
|
this.logger?.info?.('Feature toggle unlocked');
|
|
126
131
|
// 4. Activate
|
|
@@ -137,6 +142,7 @@ class AdtFeatureToggle {
|
|
|
137
142
|
this.logger?.warn?.('Unlocking feature toggle during create error cleanup');
|
|
138
143
|
this.connection.setSessionType('stateful');
|
|
139
144
|
await (0, unlock_1.unlockFeatureToggle)(this.connection, config.featureToggleName, lockHandle);
|
|
145
|
+
this.lockTracker.untrack(config.featureToggleName);
|
|
140
146
|
}
|
|
141
147
|
catch (unlockError) {
|
|
142
148
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -259,6 +265,7 @@ class AdtFeatureToggle {
|
|
|
259
265
|
this.connection.setSessionType('stateful');
|
|
260
266
|
lockHandle = await (0, lock_1.lockFeatureToggle)(this.connection, fullConfig.featureToggleName, this.logger);
|
|
261
267
|
state.lockHandle = lockHandle;
|
|
268
|
+
this.lockTracker.track(fullConfig.featureToggleName, lockHandle);
|
|
262
269
|
fullConfig.onLock?.(lockHandle);
|
|
263
270
|
this.logger?.info?.('Feature toggle locked, handle:', lockHandle);
|
|
264
271
|
// 2. Check inactive with XML for update (if provided)
|
|
@@ -296,6 +303,7 @@ class AdtFeatureToggle {
|
|
|
296
303
|
this.connection.setSessionType('stateful');
|
|
297
304
|
await (0, unlock_1.unlockFeatureToggle)(this.connection, fullConfig.featureToggleName, lockHandle);
|
|
298
305
|
this.connection.setSessionType('stateless');
|
|
306
|
+
this.lockTracker.untrack(fullConfig.featureToggleName);
|
|
299
307
|
lockHandle = undefined;
|
|
300
308
|
this.logger?.info?.('Feature toggle unlocked');
|
|
301
309
|
// 5. Final check
|
|
@@ -331,6 +339,7 @@ class AdtFeatureToggle {
|
|
|
331
339
|
this.connection.setSessionType('stateful');
|
|
332
340
|
await (0, unlock_1.unlockFeatureToggle)(this.connection, fullConfig.featureToggleName, lockHandle);
|
|
333
341
|
this.connection.setSessionType('stateless');
|
|
342
|
+
this.lockTracker.untrack(fullConfig.featureToggleName);
|
|
334
343
|
}
|
|
335
344
|
catch (unlockError) {
|
|
336
345
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -431,6 +440,7 @@ class AdtFeatureToggle {
|
|
|
431
440
|
}
|
|
432
441
|
this.connection.setSessionType('stateful');
|
|
433
442
|
const lockHandle = await (0, lock_1.lockFeatureToggle)(this.connection, config.featureToggleName, this.logger);
|
|
443
|
+
this.lockTracker.track(config.featureToggleName, lockHandle);
|
|
434
444
|
return lockHandle;
|
|
435
445
|
}
|
|
436
446
|
/**
|
|
@@ -443,6 +453,7 @@ class AdtFeatureToggle {
|
|
|
443
453
|
this.connection.setSessionType('stateful');
|
|
444
454
|
await (0, unlock_1.unlockFeatureToggle)(this.connection, config.featureToggleName, lockHandle);
|
|
445
455
|
this.connection.setSessionType('stateless');
|
|
456
|
+
this.lockTracker.untrack(config.featureToggleName);
|
|
446
457
|
return { errors: [] };
|
|
447
458
|
}
|
|
448
459
|
// ---------------------------------------------------------------------------
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger, IObjectVersion } from '@mcp-abap-adt/interfaces';
|
|
24
24
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
25
25
|
import type { IAdtContentTypes } from '../shared/contentTypes';
|
|
26
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
26
27
|
import type { IReadOptions } from '../shared/types';
|
|
27
28
|
import type { IFunctionGroupConfig, IFunctionGroupState } from './types';
|
|
28
29
|
export declare class AdtFunctionGroup implements IAdtObject<IFunctionGroupConfig, IFunctionGroupState> {
|
|
@@ -30,8 +31,9 @@ export declare class AdtFunctionGroup implements IAdtObject<IFunctionGroupConfig
|
|
|
30
31
|
protected readonly logger?: ILogger;
|
|
31
32
|
protected readonly systemContext: IAdtSystemContext;
|
|
32
33
|
protected readonly contentTypes?: IAdtContentTypes;
|
|
34
|
+
private readonly lockTracker;
|
|
33
35
|
readonly objectType: string;
|
|
34
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes);
|
|
36
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes, lockRegistry?: LockRegistry);
|
|
35
37
|
/**
|
|
36
38
|
* Validate function group configuration before creation
|
|
37
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtFunctionGroup.d.ts","sourceRoot":"","sources":["../../../src/core/functionGroup/AdtFunctionGroup.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,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGzE,qBAAa,gBACX,YAAW,UAAU,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IAEhE,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,CAAmB;gBAGnD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"AdtFunctionGroup.d.ts","sourceRoot":"","sources":["../../../src/core/functionGroup/AdtFunctionGroup.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.AdtFunctionGroup = 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 activation_1 = require("./activation");
|
|
29
30
|
const check_1 = require("./check");
|
|
@@ -38,12 +39,14 @@ class AdtFunctionGroup {
|
|
|
38
39
|
logger;
|
|
39
40
|
systemContext;
|
|
40
41
|
contentTypes;
|
|
42
|
+
lockTracker;
|
|
41
43
|
objectType = 'FunctionGroup';
|
|
42
|
-
constructor(connection, logger, systemContext, contentTypes) {
|
|
44
|
+
constructor(connection, logger, systemContext, contentTypes, lockRegistry) {
|
|
43
45
|
this.connection = connection;
|
|
44
46
|
this.logger = logger;
|
|
45
47
|
this.systemContext = systemContext ?? {};
|
|
46
48
|
this.contentTypes = contentTypes;
|
|
49
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (functionGroupName, lockHandle) => (0, lock_1.unlockFunctionGroup)(this.connection, functionGroupName, lockHandle));
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
49
52
|
* Validate function group configuration before creation
|
|
@@ -345,6 +348,7 @@ class AdtFunctionGroup {
|
|
|
345
348
|
this.logger?.info?.('Step 1: Locking function group');
|
|
346
349
|
this.connection.setSessionType('stateful');
|
|
347
350
|
lockHandle = await (0, lock_1.lockFunctionGroup)(this.connection, config.functionGroupName, sessionId);
|
|
351
|
+
this.lockTracker.track(config.functionGroupName, lockHandle);
|
|
348
352
|
this.logger?.info?.('Function group locked, handle:', lockHandle);
|
|
349
353
|
// 2. Update metadata (description)
|
|
350
354
|
this.logger?.info?.('Step 2: Updating function group metadata');
|
|
@@ -371,6 +375,7 @@ class AdtFunctionGroup {
|
|
|
371
375
|
this.connection.setSessionType('stateful');
|
|
372
376
|
await (0, lock_1.unlockFunctionGroup)(this.connection, config.functionGroupName, lockHandle, sessionId);
|
|
373
377
|
this.connection.setSessionType('stateless');
|
|
378
|
+
this.lockTracker.untrack(config.functionGroupName);
|
|
374
379
|
lockHandle = undefined;
|
|
375
380
|
this.logger?.info?.('Function group unlocked');
|
|
376
381
|
}
|
|
@@ -420,6 +425,7 @@ class AdtFunctionGroup {
|
|
|
420
425
|
this.connection.setSessionType('stateful');
|
|
421
426
|
await (0, lock_1.unlockFunctionGroup)(this.connection, config.functionGroupName, lockHandle, sessionId);
|
|
422
427
|
this.connection.setSessionType('stateless');
|
|
428
|
+
this.lockTracker.untrack(config.functionGroupName);
|
|
423
429
|
}
|
|
424
430
|
catch (unlockError) {
|
|
425
431
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -515,6 +521,7 @@ class AdtFunctionGroup {
|
|
|
515
521
|
}
|
|
516
522
|
this.connection.setSessionType('stateful');
|
|
517
523
|
const lockHandle = await (0, lock_1.lockFunctionGroup)(this.connection, config.functionGroupName);
|
|
524
|
+
this.lockTracker.track(config.functionGroupName, lockHandle);
|
|
518
525
|
return lockHandle;
|
|
519
526
|
}
|
|
520
527
|
/**
|
|
@@ -527,6 +534,7 @@ class AdtFunctionGroup {
|
|
|
527
534
|
this.connection.setSessionType('stateful');
|
|
528
535
|
const result = await (0, lock_1.unlockFunctionGroup)(this.connection, config.functionGroupName, lockHandle);
|
|
529
536
|
this.connection.setSessionType('stateless');
|
|
537
|
+
this.lockTracker.untrack(config.functionGroupName);
|
|
530
538
|
return {
|
|
531
539
|
unlockResult: result,
|
|
532
540
|
errors: [],
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
18
18
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
19
19
|
import type { IAdtContentTypes } from '../shared/contentTypes';
|
|
20
|
+
import type { LockRegistry } from '../shared/LockRegistry';
|
|
20
21
|
import { type IReadOptions } from './read';
|
|
21
22
|
import type { IFunctionIncludeConfig, IFunctionIncludeState } from './types';
|
|
22
23
|
export declare class AdtFunctionInclude implements IAdtObject<IFunctionIncludeConfig, IFunctionIncludeState> {
|
|
@@ -24,8 +25,15 @@ export declare class AdtFunctionInclude implements IAdtObject<IFunctionIncludeCo
|
|
|
24
25
|
protected readonly logger?: ILogger;
|
|
25
26
|
protected readonly systemContext: IAdtSystemContext;
|
|
26
27
|
protected readonly contentTypes?: IAdtContentTypes;
|
|
28
|
+
private readonly lockRegistry?;
|
|
27
29
|
readonly objectType: string;
|
|
28
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes);
|
|
30
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, contentTypes?: IAdtContentTypes, lockRegistry?: LockRegistry);
|
|
31
|
+
/** Registry key for a held lock (nested: group + include). */
|
|
32
|
+
private lockKey;
|
|
33
|
+
/** Record a held lock; the unlock thunk needs the parent function group. */
|
|
34
|
+
private trackLock;
|
|
35
|
+
/** Drop a lock from the registry after a clean unlock. */
|
|
36
|
+
private untrackLock;
|
|
29
37
|
/**
|
|
30
38
|
* Map camelCase config to the snake_case low-level params.
|
|
31
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtFunctionInclude.d.ts","sourceRoot":"","sources":["../../../src/core/functionInclude/AdtFunctionInclude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;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;
|
|
1
|
+
{"version":3,"file":"AdtFunctionInclude.d.ts","sourceRoot":"","sources":["../../../src/core/functionInclude/AdtFunctionInclude.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,12 +35,31 @@ class AdtFunctionInclude {
|
|
|
35
35
|
logger;
|
|
36
36
|
systemContext;
|
|
37
37
|
contentTypes;
|
|
38
|
+
lockRegistry;
|
|
38
39
|
objectType = 'FunctionInclude';
|
|
39
|
-
constructor(connection, logger, systemContext, contentTypes) {
|
|
40
|
+
constructor(connection, logger, systemContext, contentTypes, lockRegistry) {
|
|
40
41
|
this.connection = connection;
|
|
41
42
|
this.logger = logger;
|
|
42
43
|
this.systemContext = systemContext ?? {};
|
|
43
44
|
this.contentTypes = contentTypes;
|
|
45
|
+
this.lockRegistry = lockRegistry;
|
|
46
|
+
}
|
|
47
|
+
/** Registry key for a held lock (nested: group + include). */
|
|
48
|
+
lockKey(group, includeName) {
|
|
49
|
+
return `${this.objectType}/${group.toUpperCase()}/${includeName.toUpperCase()}`;
|
|
50
|
+
}
|
|
51
|
+
/** Record a held lock; the unlock thunk needs the parent function group. */
|
|
52
|
+
trackLock(group, includeName, lockHandle) {
|
|
53
|
+
if (!group || !includeName)
|
|
54
|
+
return;
|
|
55
|
+
// Raw unlock — LockRegistry.unlockAll() manages the session for the batch.
|
|
56
|
+
this.lockRegistry?.track(this.lockKey(group, includeName), () => (0, unlock_1.unlockFunctionInclude)(this.connection, group, includeName, lockHandle));
|
|
57
|
+
}
|
|
58
|
+
/** Drop a lock from the registry after a clean unlock. */
|
|
59
|
+
untrackLock(group, includeName) {
|
|
60
|
+
if (!group || !includeName)
|
|
61
|
+
return;
|
|
62
|
+
this.lockRegistry?.untrack(this.lockKey(group, includeName));
|
|
44
63
|
}
|
|
45
64
|
/**
|
|
46
65
|
* Map camelCase config to the snake_case low-level params.
|
|
@@ -121,6 +140,7 @@ class AdtFunctionInclude {
|
|
|
121
140
|
this.logger?.info?.('Step 2: Locking function include for source upload');
|
|
122
141
|
this.connection.setSessionType('stateful');
|
|
123
142
|
lockHandle = await (0, lock_1.lockFunctionInclude)(this.connection, config.functionGroupName, config.includeName, this.logger);
|
|
143
|
+
this.trackLock(config.functionGroupName, config.includeName, lockHandle);
|
|
124
144
|
state.lockHandle = lockHandle;
|
|
125
145
|
config.onLock?.(lockHandle);
|
|
126
146
|
this.logger?.info?.('Step 3: Uploading function include source');
|
|
@@ -129,6 +149,7 @@ class AdtFunctionInclude {
|
|
|
129
149
|
this.connection.setSessionType('stateful');
|
|
130
150
|
await (0, unlock_1.unlockFunctionInclude)(this.connection, config.functionGroupName, config.includeName, lockHandle);
|
|
131
151
|
this.connection.setSessionType('stateless');
|
|
152
|
+
this.untrackLock(config.functionGroupName, config.includeName);
|
|
132
153
|
lockHandle = undefined;
|
|
133
154
|
this.logger?.info?.('Step 5: Activating function include');
|
|
134
155
|
const activateResponse = await (0, activation_1.activateFunctionInclude)(this.connection, config.functionGroupName, config.includeName);
|
|
@@ -144,6 +165,7 @@ class AdtFunctionInclude {
|
|
|
144
165
|
this.connection.setSessionType('stateful');
|
|
145
166
|
await (0, unlock_1.unlockFunctionInclude)(this.connection, config.functionGroupName, config.includeName, lockHandle);
|
|
146
167
|
this.connection.setSessionType('stateless');
|
|
168
|
+
this.untrackLock(config.functionGroupName, config.includeName);
|
|
147
169
|
}
|
|
148
170
|
catch (unlockError) {
|
|
149
171
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -310,6 +332,7 @@ class AdtFunctionInclude {
|
|
|
310
332
|
this.connection.setSessionType('stateful');
|
|
311
333
|
lockHandle = await (0, lock_1.lockFunctionInclude)(this.connection, fullConfig.functionGroupName, fullConfig.includeName, this.logger);
|
|
312
334
|
state.lockHandle = lockHandle;
|
|
335
|
+
this.trackLock(fullConfig.functionGroupName, fullConfig.includeName, lockHandle);
|
|
313
336
|
fullConfig.onLock?.(lockHandle);
|
|
314
337
|
this.logger?.info?.('Function include locked, handle:', lockHandle);
|
|
315
338
|
// 2. Check inactive with source code for update (if provided)
|
|
@@ -345,6 +368,7 @@ class AdtFunctionInclude {
|
|
|
345
368
|
this.connection.setSessionType('stateful');
|
|
346
369
|
await (0, unlock_1.unlockFunctionInclude)(this.connection, fullConfig.functionGroupName, fullConfig.includeName, lockHandle);
|
|
347
370
|
this.connection.setSessionType('stateless');
|
|
371
|
+
this.untrackLock(fullConfig.functionGroupName, fullConfig.includeName);
|
|
348
372
|
lockHandle = undefined;
|
|
349
373
|
// 5. Final check
|
|
350
374
|
this.logger?.info?.('Step 5: Final check');
|
|
@@ -381,6 +405,7 @@ class AdtFunctionInclude {
|
|
|
381
405
|
this.connection.setSessionType('stateful');
|
|
382
406
|
await (0, unlock_1.unlockFunctionInclude)(this.connection, fullConfig.functionGroupName, fullConfig.includeName, lockHandle);
|
|
383
407
|
this.connection.setSessionType('stateless');
|
|
408
|
+
this.untrackLock(fullConfig.functionGroupName, fullConfig.includeName);
|
|
384
409
|
}
|
|
385
410
|
catch (unlockError) {
|
|
386
411
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -482,6 +507,7 @@ class AdtFunctionInclude {
|
|
|
482
507
|
}
|
|
483
508
|
this.connection.setSessionType('stateful');
|
|
484
509
|
const lockHandle = await (0, lock_1.lockFunctionInclude)(this.connection, config.functionGroupName, config.includeName, this.logger);
|
|
510
|
+
this.trackLock(config.functionGroupName, config.includeName, lockHandle);
|
|
485
511
|
return lockHandle;
|
|
486
512
|
}
|
|
487
513
|
/**
|
|
@@ -494,6 +520,7 @@ class AdtFunctionInclude {
|
|
|
494
520
|
this.connection.setSessionType('stateful');
|
|
495
521
|
await (0, unlock_1.unlockFunctionInclude)(this.connection, config.functionGroupName, config.includeName, lockHandle);
|
|
496
522
|
this.connection.setSessionType('stateless');
|
|
523
|
+
this.untrackLock(config.functionGroupName, config.includeName);
|
|
497
524
|
return { errors: [] };
|
|
498
525
|
}
|
|
499
526
|
getVersions(config) {
|
|
@@ -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 { IFunctionModuleConfig, IFunctionModuleState } from './types';
|
|
25
26
|
export declare class AdtFunctionModule implements IAdtObject<IFunctionModuleConfig, IFunctionModuleState> {
|
|
@@ -27,8 +28,15 @@ export declare class AdtFunctionModule implements IAdtObject<IFunctionModuleConf
|
|
|
27
28
|
protected readonly logger?: ILogger;
|
|
28
29
|
protected readonly systemContext: IAdtSystemContext;
|
|
29
30
|
protected readonly contentTypes?: IAdtContentTypes;
|
|
31
|
+
private readonly lockRegistry?;
|
|
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);
|
|
34
|
+
/** Registry key for a held lock (nested: group + module). */
|
|
35
|
+
private lockKey;
|
|
36
|
+
/** Record a held lock; the unlock thunk needs the parent function group. */
|
|
37
|
+
private trackLock;
|
|
38
|
+
/** Drop a lock from the registry after a clean unlock. */
|
|
39
|
+
private untrackLock;
|
|
32
40
|
/**
|
|
33
41
|
* Validate function module configuration before creation
|
|
34
42
|
*/
|
|
@@ -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;IA6OhC;;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;
|
|
@@ -296,6 +316,7 @@ class AdtFunctionModule {
|
|
|
296
316
|
this.connection.setSessionType('stateful');
|
|
297
317
|
await (0, unlock_1.unlockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName, lockHandle);
|
|
298
318
|
this.connection.setSessionType('stateless');
|
|
319
|
+
this.untrackLock(config.functionGroupName, config.functionModuleName);
|
|
299
320
|
lockHandle = undefined;
|
|
300
321
|
this.logger?.info?.('Function module unlocked');
|
|
301
322
|
}
|
|
@@ -344,6 +365,7 @@ class AdtFunctionModule {
|
|
|
344
365
|
this.connection.setSessionType('stateful');
|
|
345
366
|
await (0, unlock_1.unlockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName, lockHandle);
|
|
346
367
|
this.connection.setSessionType('stateless');
|
|
368
|
+
this.untrackLock(config.functionGroupName, config.functionModuleName);
|
|
347
369
|
}
|
|
348
370
|
catch (unlockError) {
|
|
349
371
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -451,6 +473,7 @@ class AdtFunctionModule {
|
|
|
451
473
|
}
|
|
452
474
|
this.connection.setSessionType('stateful');
|
|
453
475
|
const lockHandle = await (0, lock_1.lockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName);
|
|
476
|
+
this.trackLock(config.functionGroupName, config.functionModuleName, lockHandle);
|
|
454
477
|
return lockHandle;
|
|
455
478
|
}
|
|
456
479
|
/**
|
|
@@ -463,6 +486,7 @@ class AdtFunctionModule {
|
|
|
463
486
|
this.connection.setSessionType('stateful');
|
|
464
487
|
const result = await (0, unlock_1.unlockFunctionModule)(this.connection, config.functionGroupName, config.functionModuleName, lockHandle);
|
|
465
488
|
this.connection.setSessionType('stateless');
|
|
489
|
+
this.untrackLock(config.functionGroupName, config.functionModuleName);
|
|
466
490
|
return {
|
|
467
491
|
unlockResult: result,
|
|
468
492
|
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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"}
|