@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":"AdtScalarFunction.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunction/AdtScalarFunction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,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,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW3E,qBAAa,iBACX,YAAW,UAAU,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;IAElE,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,CAAoB;gBAGpD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"AdtScalarFunction.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunction/AdtScalarFunction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,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,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAW3E,qBAAa,iBACX,YAAW,UAAU,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;IAElE,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,CAAoB;gBAGpD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAavB,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IA6B1B,MAAM,CACV,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,oBAAoB,CAAC;IAwB1B,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;IAkBtC,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,oBAAoB,CAAC;IAa1B,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,oBAAoB,CAAC;IAa1B,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,oBAAoB,CAAC;IAgJ1B,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAmB1B,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAU1B,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC;IAY1B,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAY7D,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,CAAC;IAiBhC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC;IAIlD,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AdtScalarFunction = void 0;
|
|
4
4
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
5
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
5
6
|
const activation_1 = require("./activation");
|
|
6
7
|
const check_1 = require("./check");
|
|
7
8
|
const create_1 = require("./create");
|
|
@@ -17,11 +18,13 @@ class AdtScalarFunction {
|
|
|
17
18
|
connection;
|
|
18
19
|
logger;
|
|
19
20
|
systemContext;
|
|
21
|
+
lockTracker;
|
|
20
22
|
objectType = 'ScalarFunction';
|
|
21
|
-
constructor(connection, logger, systemContext) {
|
|
23
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
22
24
|
this.connection = connection;
|
|
23
25
|
this.logger = logger;
|
|
24
26
|
this.systemContext = systemContext ?? {};
|
|
27
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockScalarFunction)(this.connection, name, lockHandle));
|
|
25
28
|
}
|
|
26
29
|
async validate(config) {
|
|
27
30
|
const state = { errors: [] };
|
|
@@ -116,6 +119,7 @@ class AdtScalarFunction {
|
|
|
116
119
|
try {
|
|
117
120
|
this.connection.setSessionType('stateful');
|
|
118
121
|
lockHandle = await (0, lock_1.lockScalarFunction)(this.connection, config.scalarFunctionName);
|
|
122
|
+
this.lockTracker.track(config.scalarFunctionName, lockHandle);
|
|
119
123
|
const codeToCheck = options?.sourceCode || config.sourceCode;
|
|
120
124
|
if (codeToCheck) {
|
|
121
125
|
await (0, check_1.checkScalarFunction)(this.connection, config.scalarFunctionName, 'inactive', codeToCheck);
|
|
@@ -139,6 +143,7 @@ class AdtScalarFunction {
|
|
|
139
143
|
finally {
|
|
140
144
|
this.connection.setSessionType('stateless');
|
|
141
145
|
}
|
|
146
|
+
this.lockTracker.untrack(config.scalarFunctionName);
|
|
142
147
|
lockHandle = undefined;
|
|
143
148
|
}
|
|
144
149
|
await (0, check_1.checkScalarFunction)(this.connection, config.scalarFunctionName, 'inactive');
|
|
@@ -160,6 +165,7 @@ class AdtScalarFunction {
|
|
|
160
165
|
try {
|
|
161
166
|
this.connection.setSessionType('stateful');
|
|
162
167
|
await (0, unlock_1.unlockScalarFunction)(this.connection, config.scalarFunctionName, lockHandle);
|
|
168
|
+
this.lockTracker.untrack(config.scalarFunctionName);
|
|
163
169
|
}
|
|
164
170
|
catch (unlockError) {
|
|
165
171
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -222,7 +228,9 @@ class AdtScalarFunction {
|
|
|
222
228
|
if (!config.scalarFunctionName)
|
|
223
229
|
throw new Error('Scalar function name is required');
|
|
224
230
|
this.connection.setSessionType('stateful');
|
|
225
|
-
|
|
231
|
+
const lockHandle = await (0, lock_1.lockScalarFunction)(this.connection, config.scalarFunctionName);
|
|
232
|
+
this.lockTracker.track(config.scalarFunctionName, lockHandle);
|
|
233
|
+
return lockHandle;
|
|
226
234
|
}
|
|
227
235
|
async unlock(config, lockHandle) {
|
|
228
236
|
if (!config.scalarFunctionName)
|
|
@@ -230,6 +238,7 @@ class AdtScalarFunction {
|
|
|
230
238
|
this.connection.setSessionType('stateful');
|
|
231
239
|
try {
|
|
232
240
|
const unlockResult = await (0, unlock_1.unlockScalarFunction)(this.connection, config.scalarFunctionName, lockHandle);
|
|
241
|
+
this.lockTracker.untrack(config.scalarFunctionName);
|
|
233
242
|
return { unlockResult, errors: [] };
|
|
234
243
|
}
|
|
235
244
|
finally {
|
|
@@ -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 { IScalarFunctionImplementationConfig, IScalarFunctionImplementationState } from './types';
|
|
9
10
|
export declare class AdtScalarFunctionImplementation implements IAdtObject<IScalarFunctionImplementationConfig, IScalarFunctionImplementationState> {
|
|
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<IScalarFunctionImplementationConfig>): Promise<IScalarFunctionImplementationState>;
|
|
16
18
|
create(config: IScalarFunctionImplementationConfig, _options?: IAdtOperationOptions): Promise<IScalarFunctionImplementationState>;
|
|
17
19
|
read(config: Partial<IScalarFunctionImplementationConfig>, version?: 'active' | 'inactive', options?: IReadOptions): Promise<IScalarFunctionImplementationState | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtScalarFunctionImplementation.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,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,mCAAmC,EACnC,kCAAkC,EACnC,MAAM,SAAS,CAAC;AAYjB,qBAAa,+BACX,YACE,UAAU,CACR,mCAAmC,EACnC,kCAAkC,CACnC;IAEH,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,CAAkC;gBAGlE,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"AdtScalarFunctionImplementation.d.ts","sourceRoot":"","sources":["../../../src/core/scalarFunctionImplementation/AdtScalarFunctionImplementation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,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,mCAAmC,EACnC,kCAAkC,EACnC,MAAM,SAAS,CAAC;AAYjB,qBAAa,+BACX,YACE,UAAU,CACR,mCAAmC,EACnC,kCAAkC,CACnC;IAEH,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,CAAkC;gBAGlE,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAavB,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IA2BxC,MAAM,CACV,MAAM,EAAE,mCAAmC,EAC3C,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,kCAAkC,CAAC;IA+BxC,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,kCAAkC,GAAG,SAAS,CAAC;IAkBpD,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,kCAAkC,CAAC;IAaxC,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,kCAAkC,CAAC;IAa9C;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kCAAkC,CAAC;IAoE9C;;;OAGG;IACG,cAAc,CAClB,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kCAAkC,CAAC;IAqExC,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IAsBxC,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,kCAAkC,CAAC;IAUxC,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,kCAAkC,CAAC;IAYxC,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,GACnD,OAAO,CAAC,MAAM,CAAC;IAYZ,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC,EACpD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kCAAkC,CAAC;IAiB9C,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,mCAAmC,CAAC;IAIhE,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAMpC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AdtScalarFunctionImplementation = void 0;
|
|
4
4
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
5
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
5
6
|
const activation_1 = require("./activation");
|
|
6
7
|
const check_1 = require("./check");
|
|
7
8
|
const create_1 = require("./create");
|
|
@@ -18,11 +19,13 @@ class AdtScalarFunctionImplementation {
|
|
|
18
19
|
connection;
|
|
19
20
|
logger;
|
|
20
21
|
systemContext;
|
|
22
|
+
lockTracker;
|
|
21
23
|
objectType = 'ScalarFunctionImplementation';
|
|
22
|
-
constructor(connection, logger, systemContext) {
|
|
24
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
23
25
|
this.connection = connection;
|
|
24
26
|
this.logger = logger;
|
|
25
27
|
this.systemContext = systemContext ?? {};
|
|
28
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, name, lockHandle));
|
|
26
29
|
}
|
|
27
30
|
async validate(config) {
|
|
28
31
|
const state = { errors: [] };
|
|
@@ -126,12 +129,14 @@ class AdtScalarFunctionImplementation {
|
|
|
126
129
|
try {
|
|
127
130
|
this.connection.setSessionType('stateful');
|
|
128
131
|
lockHandle = await (0, lock_1.lockScalarFunctionImplementation)(this.connection, config.implementationName);
|
|
132
|
+
this.lockTracker.track(config.implementationName, lockHandle);
|
|
129
133
|
const updateResult = await (0, update_1.updateScalarFunctionImplementation)(this.connection, {
|
|
130
134
|
implementation_name: config.implementationName,
|
|
131
135
|
source_code: sourceCode,
|
|
132
136
|
transport_request: config.transportRequest,
|
|
133
137
|
}, lockHandle);
|
|
134
138
|
await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
|
|
139
|
+
this.lockTracker.untrack(config.implementationName);
|
|
135
140
|
lockHandle = undefined;
|
|
136
141
|
return { updateResult, errors: [] };
|
|
137
142
|
}
|
|
@@ -139,6 +144,7 @@ class AdtScalarFunctionImplementation {
|
|
|
139
144
|
if (lockHandle) {
|
|
140
145
|
try {
|
|
141
146
|
await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
|
|
147
|
+
this.lockTracker.untrack(config.implementationName);
|
|
142
148
|
}
|
|
143
149
|
catch (unlockError) {
|
|
144
150
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -173,12 +179,14 @@ class AdtScalarFunctionImplementation {
|
|
|
173
179
|
try {
|
|
174
180
|
this.connection.setSessionType('stateful');
|
|
175
181
|
lockHandle = await (0, lock_1.lockScalarFunctionImplementation)(this.connection, config.implementationName);
|
|
182
|
+
this.lockTracker.track(config.implementationName, lockHandle);
|
|
176
183
|
const updateResult = await (0, updateMetadata_1.updateScalarFunctionImplementationMetadata)(this.connection, {
|
|
177
184
|
implementation_name: config.implementationName,
|
|
178
185
|
source_code: sourceCode,
|
|
179
186
|
transport_request: config.transportRequest,
|
|
180
187
|
}, lockHandle);
|
|
181
188
|
await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
|
|
189
|
+
this.lockTracker.untrack(config.implementationName);
|
|
182
190
|
lockHandle = undefined;
|
|
183
191
|
return { updateResult, errors: [] };
|
|
184
192
|
}
|
|
@@ -186,6 +194,7 @@ class AdtScalarFunctionImplementation {
|
|
|
186
194
|
if (lockHandle) {
|
|
187
195
|
try {
|
|
188
196
|
await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
|
|
197
|
+
this.lockTracker.untrack(config.implementationName);
|
|
189
198
|
}
|
|
190
199
|
catch (unlockError) {
|
|
191
200
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -234,7 +243,9 @@ class AdtScalarFunctionImplementation {
|
|
|
234
243
|
if (!config.implementationName)
|
|
235
244
|
throw new Error('Implementation name is required');
|
|
236
245
|
this.connection.setSessionType('stateful');
|
|
237
|
-
|
|
246
|
+
const lockHandle = await (0, lock_1.lockScalarFunctionImplementation)(this.connection, config.implementationName);
|
|
247
|
+
this.lockTracker.track(config.implementationName, lockHandle);
|
|
248
|
+
return lockHandle;
|
|
238
249
|
}
|
|
239
250
|
async unlock(config, lockHandle) {
|
|
240
251
|
if (!config.implementationName)
|
|
@@ -242,6 +253,7 @@ class AdtScalarFunctionImplementation {
|
|
|
242
253
|
this.connection.setSessionType('stateful');
|
|
243
254
|
try {
|
|
244
255
|
const unlockResult = await (0, unlock_1.unlockScalarFunctionImplementation)(this.connection, config.implementationName, lockHandle);
|
|
256
|
+
this.lockTracker.untrack(config.implementationName);
|
|
245
257
|
return { unlockResult, errors: [] };
|
|
246
258
|
}
|
|
247
259
|
finally {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AdtServiceDefinition - High-level CRUD operations for Service Definition (
|
|
2
|
+
* AdtServiceDefinition - High-level CRUD operations for Service Definition (SRVD/SRV) objects
|
|
3
3
|
*
|
|
4
4
|
* Implements IAdtObject interface with automatic operation chains,
|
|
5
5
|
* error handling, and resource cleanup.
|
|
@@ -13,20 +13,23 @@
|
|
|
13
13
|
* - activate uses same session/cookies (no stateful needed)
|
|
14
14
|
*
|
|
15
15
|
* Operation chains:
|
|
16
|
-
* - Create:
|
|
16
|
+
* - Create: create (POST metadata only — creates an empty source; the source
|
|
17
|
+
* code is written by a subsequent update(), mirroring what Eclipse ADT does)
|
|
17
18
|
* - Update: lock → check(inactive) → update → unlock → check → activate
|
|
18
19
|
* - Delete: check(deletion) → delete
|
|
19
20
|
*/
|
|
20
21
|
import type { IAbapConnection, IAdtObject, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
21
22
|
import type { IAdtSystemContext } from '../../clients/AdtClient';
|
|
23
|
+
import { type LockRegistry } from '../shared/LockRegistry';
|
|
22
24
|
import type { IReadOptions } from '../shared/types';
|
|
23
25
|
import type { IServiceDefinitionConfig, IServiceDefinitionState } from './types';
|
|
24
26
|
export declare class AdtServiceDefinition implements IAdtObject<IServiceDefinitionConfig, IServiceDefinitionState> {
|
|
25
27
|
private readonly connection;
|
|
26
28
|
private readonly logger?;
|
|
27
29
|
private readonly systemContext;
|
|
30
|
+
private readonly lockTracker;
|
|
28
31
|
readonly objectType: string;
|
|
29
|
-
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext);
|
|
32
|
+
constructor(connection: IAbapConnection, logger?: ILogger, systemContext?: IAdtSystemContext, lockRegistry?: LockRegistry);
|
|
30
33
|
/**
|
|
31
34
|
* Validate service definition configuration before creation
|
|
32
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtServiceDefinition.d.ts","sourceRoot":"","sources":["../../../src/core/serviceDefinition/AdtServiceDefinition.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"AdtServiceDefinition.d.ts","sourceRoot":"","sources":["../../../src/core/serviceDefinition/AdtServiceDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;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;IA8BnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,wBAAwB,EAChC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,uBAAuB,CAAC;IAsCnC;;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;IA2B/C;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,uBAAuB,CAAC;IAkCnC;;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;IAuNnC;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAmCnC;;;OAGG;IACG,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,GACxC,OAAO,CAAC,uBAAuB,CAAC;IAqBnC;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACzC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,uBAAuB,CAAC;IAkBnC;;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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* AdtServiceDefinition - High-level CRUD operations for Service Definition (
|
|
3
|
+
* AdtServiceDefinition - High-level CRUD operations for Service Definition (SRVD/SRV) objects
|
|
4
4
|
*
|
|
5
5
|
* Implements IAdtObject interface with automatic operation chains,
|
|
6
6
|
* error handling, and resource cleanup.
|
|
@@ -14,13 +14,15 @@
|
|
|
14
14
|
* - activate uses same session/cookies (no stateful needed)
|
|
15
15
|
*
|
|
16
16
|
* Operation chains:
|
|
17
|
-
* - Create:
|
|
17
|
+
* - Create: create (POST metadata only — creates an empty source; the source
|
|
18
|
+
* code is written by a subsequent update(), mirroring what Eclipse ADT does)
|
|
18
19
|
* - Update: lock → check(inactive) → update → unlock → check → activate
|
|
19
20
|
* - Delete: check(deletion) → delete
|
|
20
21
|
*/
|
|
21
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
23
|
exports.AdtServiceDefinition = void 0;
|
|
23
24
|
const internalUtils_1 = require("../../utils/internalUtils");
|
|
25
|
+
const LockRegistry_1 = require("../shared/LockRegistry");
|
|
24
26
|
const activation_1 = require("./activation");
|
|
25
27
|
const check_1 = require("./check");
|
|
26
28
|
const create_1 = require("./create");
|
|
@@ -35,11 +37,13 @@ class AdtServiceDefinition {
|
|
|
35
37
|
connection;
|
|
36
38
|
logger;
|
|
37
39
|
systemContext;
|
|
40
|
+
lockTracker;
|
|
38
41
|
objectType = 'ServiceDefinition';
|
|
39
|
-
constructor(connection, logger, systemContext) {
|
|
42
|
+
constructor(connection, logger, systemContext, lockRegistry) {
|
|
40
43
|
this.connection = connection;
|
|
41
44
|
this.logger = logger;
|
|
42
45
|
this.systemContext = systemContext ?? {};
|
|
46
|
+
this.lockTracker = (0, LockRegistry_1.createLockTracker)(lockRegistry, this.objectType, (name, lockHandle) => (0, unlock_1.unlockServiceDefinition)(this.connection, name, lockHandle));
|
|
43
47
|
}
|
|
44
48
|
/**
|
|
45
49
|
* Validate service definition configuration before creation
|
|
@@ -228,6 +232,7 @@ class AdtServiceDefinition {
|
|
|
228
232
|
this.logger?.info?.('Step 1: Locking service definition');
|
|
229
233
|
this.connection.setSessionType('stateful');
|
|
230
234
|
lockHandle = await (0, lock_1.lockServiceDefinition)(this.connection, config.serviceDefinitionName);
|
|
235
|
+
this.lockTracker.track(config.serviceDefinitionName, lockHandle);
|
|
231
236
|
this.logger?.info?.('Service definition locked, handle:', lockHandle);
|
|
232
237
|
// 2. Check inactive with code for update (from options or config)
|
|
233
238
|
const codeToCheck = options?.sourceCode || config.sourceCode;
|
|
@@ -246,9 +251,10 @@ class AdtServiceDefinition {
|
|
|
246
251
|
}, lockHandle);
|
|
247
252
|
this.logger?.info?.('Service definition updated');
|
|
248
253
|
// 3.5. Read with long polling (wait for object to be ready after update)
|
|
254
|
+
// Poll the inactive version: the write above produced it; the active version may not exist yet.
|
|
249
255
|
this.logger?.info?.('read (wait for object ready after update)');
|
|
250
256
|
try {
|
|
251
|
-
await this.read({ serviceDefinitionName: config.serviceDefinitionName }, '
|
|
257
|
+
await this.read({ serviceDefinitionName: config.serviceDefinitionName }, 'inactive', { withLongPolling: true });
|
|
252
258
|
this.logger?.info?.('object is ready after update');
|
|
253
259
|
}
|
|
254
260
|
catch (readError) {
|
|
@@ -262,6 +268,7 @@ class AdtServiceDefinition {
|
|
|
262
268
|
this.connection.setSessionType('stateful');
|
|
263
269
|
await (0, unlock_1.unlockServiceDefinition)(this.connection, config.serviceDefinitionName, lockHandle);
|
|
264
270
|
this.connection.setSessionType('stateless');
|
|
271
|
+
this.lockTracker.untrack(config.serviceDefinitionName);
|
|
265
272
|
lockHandle = undefined;
|
|
266
273
|
this.logger?.info?.('Service definition unlocked');
|
|
267
274
|
}
|
|
@@ -307,6 +314,7 @@ class AdtServiceDefinition {
|
|
|
307
314
|
this.connection.setSessionType('stateful');
|
|
308
315
|
await (0, unlock_1.unlockServiceDefinition)(this.connection, config.serviceDefinitionName, lockHandle);
|
|
309
316
|
this.connection.setSessionType('stateless');
|
|
317
|
+
this.lockTracker.untrack(config.serviceDefinitionName);
|
|
310
318
|
}
|
|
311
319
|
catch (unlockError) {
|
|
312
320
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -413,6 +421,7 @@ class AdtServiceDefinition {
|
|
|
413
421
|
}
|
|
414
422
|
this.connection.setSessionType('stateful');
|
|
415
423
|
const lockHandle = await (0, lock_1.lockServiceDefinition)(this.connection, config.serviceDefinitionName);
|
|
424
|
+
this.lockTracker.track(config.serviceDefinitionName, lockHandle);
|
|
416
425
|
return lockHandle;
|
|
417
426
|
}
|
|
418
427
|
/**
|
|
@@ -425,6 +434,7 @@ class AdtServiceDefinition {
|
|
|
425
434
|
this.connection.setSessionType('stateful');
|
|
426
435
|
const result = await (0, unlock_1.unlockServiceDefinition)(this.connection, config.serviceDefinitionName, lockHandle);
|
|
427
436
|
this.connection.setSessionType('stateless');
|
|
437
|
+
this.lockTracker.untrack(config.serviceDefinitionName);
|
|
428
438
|
return {
|
|
429
439
|
unlockResult: result,
|
|
430
440
|
errors: [],
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-scoped registry of held object locks.
|
|
3
|
+
*
|
|
4
|
+
* One registry per stateful session (owned by AdtClient). Handlers record a lock
|
|
5
|
+
* when they acquire it and remove it on a clean unlock. `unlockAll()` is the
|
|
6
|
+
* last-resort cleanup: it releases any lock still held (e.g. the consumer forgot
|
|
7
|
+
* to unlock, or a managed flow threw before its unlock), so a session is never
|
|
8
|
+
* abandoned with dangling enqueue locks.
|
|
9
|
+
*
|
|
10
|
+
* This is a safety net, NOT the primary defense. Preventing a timeout from
|
|
11
|
+
* interrupting the lock→unlock critical section is the caller's responsibility.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Releases a single held lock. Provided by the handler that acquired it.
|
|
15
|
+
*
|
|
16
|
+
* The thunk MUST NOT toggle the connection session type — `unlockAll()` keeps
|
|
17
|
+
* the session stateful for the whole batch and restores stateless once at the
|
|
18
|
+
* end (see {@link LockRegistry.unlockAll}).
|
|
19
|
+
*/
|
|
20
|
+
export type UnlockThunk = () => Promise<unknown>;
|
|
21
|
+
/** A lock that `unlockAll()` failed to release, kept for reporting / retry. */
|
|
22
|
+
export interface LockFailure {
|
|
23
|
+
key: string;
|
|
24
|
+
error: unknown;
|
|
25
|
+
}
|
|
26
|
+
/** Minimal session control the registry needs to run an unlock batch. */
|
|
27
|
+
export interface ISessionController {
|
|
28
|
+
setSessionType(type: 'stateful' | 'stateless'): void;
|
|
29
|
+
}
|
|
30
|
+
export declare class LockRegistry {
|
|
31
|
+
private readonly session?;
|
|
32
|
+
private readonly locks;
|
|
33
|
+
/**
|
|
34
|
+
* @param session Controls the shared connection's session type. `unlockAll()`
|
|
35
|
+
* uses it to keep the session stateful for the whole batch — some
|
|
36
|
+
* connections (RFC) clear the stateful cookie when switched to stateless,
|
|
37
|
+
* which would invalidate the remaining lock handles mid-batch.
|
|
38
|
+
*/
|
|
39
|
+
constructor(session?: ISessionController | undefined);
|
|
40
|
+
/** Record a held lock under a stable object key (e.g. `DOMA/ZFOO`). */
|
|
41
|
+
track(key: string, unlock: UnlockThunk): void;
|
|
42
|
+
/** Drop a lock after it has been released cleanly. */
|
|
43
|
+
untrack(key: string): void;
|
|
44
|
+
/** Keys of locks still held. */
|
|
45
|
+
get pending(): string[];
|
|
46
|
+
/**
|
|
47
|
+
* Release every lock still held. Successfully released locks are dropped;
|
|
48
|
+
* locks whose unlock throws are kept and returned as failures.
|
|
49
|
+
*
|
|
50
|
+
* The whole batch runs under a single stateful→stateless transition so that a
|
|
51
|
+
* per-unlock switch to stateless can't clear the session mid-batch and break
|
|
52
|
+
* the remaining lock handles.
|
|
53
|
+
*/
|
|
54
|
+
unlockAll(): Promise<LockFailure[]>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Per-handler view over a {@link LockRegistry}: records/removes locks under a
|
|
58
|
+
* stable, type-prefixed key. A no-op when no registry is present, so handlers
|
|
59
|
+
* work unchanged whether or not a registry was injected.
|
|
60
|
+
*/
|
|
61
|
+
export interface LockTracker {
|
|
62
|
+
/** Record a held lock for `objectName`. */
|
|
63
|
+
track(objectName: string, lockHandle: string): void;
|
|
64
|
+
/** Drop the lock for `objectName` after a clean unlock. */
|
|
65
|
+
untrack(objectName: string): void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build a {@link LockTracker} for one object type.
|
|
69
|
+
*
|
|
70
|
+
* @param registry Session registry to record into (undefined → no-op tracker).
|
|
71
|
+
* @param objectType Stable type prefix for the key (e.g. `Domain`).
|
|
72
|
+
* @param unlock Raw release of a held lock, invoked by `unlockAll()` for
|
|
73
|
+
* abandoned locks. MUST NOT toggle the session type —
|
|
74
|
+
* `unlockAll()` manages the session for the whole batch.
|
|
75
|
+
*/
|
|
76
|
+
export declare function createLockTracker(registry: LockRegistry | undefined, objectType: string, unlock: (objectName: string, lockHandle: string) => Promise<unknown>): LockTracker;
|
|
77
|
+
//# sourceMappingURL=LockRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LockRegistry.d.ts","sourceRoot":"","sources":["../../../src/core/shared/LockRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC;CACtD;AAED,qBAAa,YAAY;IASX,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IARrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IAExD;;;;;OAKG;gBAC0B,OAAO,CAAC,EAAE,kBAAkB,YAAA;IAEzD,uEAAuE;IACvE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAI7C,sDAAsD;IACtD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI1B,gCAAgC;IAChC,IAAI,OAAO,IAAI,MAAM,EAAE,CAEtB;IAED;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;CAmB1C;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACpD,2DAA2D;IAC3D,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,YAAY,GAAG,SAAS,EAClC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GACnE,WAAW,CAWb"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Session-scoped registry of held object locks.
|
|
4
|
+
*
|
|
5
|
+
* One registry per stateful session (owned by AdtClient). Handlers record a lock
|
|
6
|
+
* when they acquire it and remove it on a clean unlock. `unlockAll()` is the
|
|
7
|
+
* last-resort cleanup: it releases any lock still held (e.g. the consumer forgot
|
|
8
|
+
* to unlock, or a managed flow threw before its unlock), so a session is never
|
|
9
|
+
* abandoned with dangling enqueue locks.
|
|
10
|
+
*
|
|
11
|
+
* This is a safety net, NOT the primary defense. Preventing a timeout from
|
|
12
|
+
* interrupting the lock→unlock critical section is the caller's responsibility.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.LockRegistry = void 0;
|
|
16
|
+
exports.createLockTracker = createLockTracker;
|
|
17
|
+
class LockRegistry {
|
|
18
|
+
session;
|
|
19
|
+
locks = new Map();
|
|
20
|
+
/**
|
|
21
|
+
* @param session Controls the shared connection's session type. `unlockAll()`
|
|
22
|
+
* uses it to keep the session stateful for the whole batch — some
|
|
23
|
+
* connections (RFC) clear the stateful cookie when switched to stateless,
|
|
24
|
+
* which would invalidate the remaining lock handles mid-batch.
|
|
25
|
+
*/
|
|
26
|
+
constructor(session) {
|
|
27
|
+
this.session = session;
|
|
28
|
+
}
|
|
29
|
+
/** Record a held lock under a stable object key (e.g. `DOMA/ZFOO`). */
|
|
30
|
+
track(key, unlock) {
|
|
31
|
+
this.locks.set(key, unlock);
|
|
32
|
+
}
|
|
33
|
+
/** Drop a lock after it has been released cleanly. */
|
|
34
|
+
untrack(key) {
|
|
35
|
+
this.locks.delete(key);
|
|
36
|
+
}
|
|
37
|
+
/** Keys of locks still held. */
|
|
38
|
+
get pending() {
|
|
39
|
+
return [...this.locks.keys()];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Release every lock still held. Successfully released locks are dropped;
|
|
43
|
+
* locks whose unlock throws are kept and returned as failures.
|
|
44
|
+
*
|
|
45
|
+
* The whole batch runs under a single stateful→stateless transition so that a
|
|
46
|
+
* per-unlock switch to stateless can't clear the session mid-batch and break
|
|
47
|
+
* the remaining lock handles.
|
|
48
|
+
*/
|
|
49
|
+
async unlockAll() {
|
|
50
|
+
const failures = [];
|
|
51
|
+
if (this.locks.size === 0)
|
|
52
|
+
return failures;
|
|
53
|
+
this.session?.setSessionType('stateful');
|
|
54
|
+
try {
|
|
55
|
+
for (const [key, unlock] of [...this.locks]) {
|
|
56
|
+
try {
|
|
57
|
+
await unlock();
|
|
58
|
+
this.locks.delete(key);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
failures.push({ key, error });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
this.session?.setSessionType('stateless');
|
|
67
|
+
}
|
|
68
|
+
return failures;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.LockRegistry = LockRegistry;
|
|
72
|
+
/**
|
|
73
|
+
* Build a {@link LockTracker} for one object type.
|
|
74
|
+
*
|
|
75
|
+
* @param registry Session registry to record into (undefined → no-op tracker).
|
|
76
|
+
* @param objectType Stable type prefix for the key (e.g. `Domain`).
|
|
77
|
+
* @param unlock Raw release of a held lock, invoked by `unlockAll()` for
|
|
78
|
+
* abandoned locks. MUST NOT toggle the session type —
|
|
79
|
+
* `unlockAll()` manages the session for the whole batch.
|
|
80
|
+
*/
|
|
81
|
+
function createLockTracker(registry, objectType, unlock) {
|
|
82
|
+
const keyOf = (objectName) => `${objectType}/${objectName.toUpperCase()}`;
|
|
83
|
+
return {
|
|
84
|
+
track(objectName, lockHandle) {
|
|
85
|
+
registry?.track(keyOf(objectName), () => unlock(objectName, lockHandle));
|
|
86
|
+
},
|
|
87
|
+
untrack(objectName) {
|
|
88
|
+
registry?.untrack(keyOf(objectName));
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -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 { IStructureConfig, IStructureState } from './types';
|
|
24
25
|
export declare class AdtStructure implements IAdtObject<IStructureConfig, IStructureState> {
|
|
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 structure configuration before creation
|
|
32
34
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtStructure.d.ts","sourceRoot":"","sources":["../../../src/core/structure/AdtStructure.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,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAMjE,qBAAa,YACX,YAAW,UAAU,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAExD,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,CAAe;gBAG/C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"AdtStructure.d.ts","sourceRoot":"","sources":["../../../src/core/structure/AdtStructure.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,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAMjE,qBAAa,YACX,YAAW,UAAU,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAExD,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,CAAe;gBAG/C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAY7B;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAyB3E;;;OAGG;IACG,MAAM,CACV,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;IAuD3B;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAyBvC;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,CAAC;IAgC3B;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,eAAe,CAAC;IAkC3B;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;IAkN3B;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAgCzE;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAoB3E;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC;IAoB3B;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAc9D;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC;IAmB3B,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAI7C,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.AdtStructure = 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");
|
|
@@ -35,11 +36,13 @@ class AdtStructure {
|
|
|
35
36
|
connection;
|
|
36
37
|
logger;
|
|
37
38
|
systemContext;
|
|
39
|
+
lockTracker;
|
|
38
40
|
objectType = 'Structure';
|
|
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.unlockStructure)(this.connection, name, lockHandle));
|
|
43
46
|
}
|
|
44
47
|
/**
|
|
45
48
|
* Validate structure configuration before creation
|
|
@@ -235,6 +238,7 @@ class AdtStructure {
|
|
|
235
238
|
this.logger?.info?.('Step 1: Locking structure');
|
|
236
239
|
this.connection.setSessionType('stateful');
|
|
237
240
|
lockHandle = await (0, lock_1.lockStructure)(this.connection, config.structureName);
|
|
241
|
+
this.lockTracker.track(config.structureName, lockHandle);
|
|
238
242
|
this.logger?.info?.('Structure locked, handle:', lockHandle);
|
|
239
243
|
// 2. Check inactive with code for update (from options or config)
|
|
240
244
|
const codeToCheck = options?.sourceCode || config.ddlCode;
|
|
@@ -252,10 +256,11 @@ class AdtStructure {
|
|
|
252
256
|
transportRequest: config.transportRequest,
|
|
253
257
|
}, lockHandle);
|
|
254
258
|
this.logger?.info?.('Structure updated');
|
|
259
|
+
// Poll the inactive version: the write above produced it; the active version may not exist yet.
|
|
255
260
|
// 3.5. Read with long polling to ensure object is ready after update
|
|
256
261
|
this.logger?.info?.('read (wait for object ready after update)');
|
|
257
262
|
try {
|
|
258
|
-
await this.read({ structureName: config.structureName }, '
|
|
263
|
+
await this.read({ structureName: config.structureName }, 'inactive', {
|
|
259
264
|
withLongPolling: true,
|
|
260
265
|
});
|
|
261
266
|
this.logger?.info?.('object is ready after update');
|
|
@@ -271,6 +276,7 @@ class AdtStructure {
|
|
|
271
276
|
this.connection.setSessionType('stateful');
|
|
272
277
|
await (0, unlock_1.unlockStructure)(this.connection, config.structureName, lockHandle);
|
|
273
278
|
this.connection.setSessionType('stateless');
|
|
279
|
+
this.lockTracker.untrack(config.structureName);
|
|
274
280
|
lockHandle = undefined;
|
|
275
281
|
this.logger?.info?.('Structure unlocked');
|
|
276
282
|
}
|
|
@@ -320,6 +326,7 @@ class AdtStructure {
|
|
|
320
326
|
this.connection.setSessionType('stateful');
|
|
321
327
|
await (0, unlock_1.unlockStructure)(this.connection, config.structureName, lockHandle);
|
|
322
328
|
this.connection.setSessionType('stateless');
|
|
329
|
+
this.lockTracker.untrack(config.structureName);
|
|
323
330
|
}
|
|
324
331
|
catch (unlockError) {
|
|
325
332
|
this.logger?.warn?.('Failed to unlock during cleanup:', (0, internalUtils_1.safeErrorMessage)(unlockError));
|
|
@@ -421,6 +428,7 @@ class AdtStructure {
|
|
|
421
428
|
}
|
|
422
429
|
this.connection.setSessionType('stateful');
|
|
423
430
|
const lockHandle = await (0, lock_1.lockStructure)(this.connection, config.structureName);
|
|
431
|
+
this.lockTracker.track(config.structureName, lockHandle);
|
|
424
432
|
return lockHandle;
|
|
425
433
|
}
|
|
426
434
|
/**
|
|
@@ -433,6 +441,7 @@ class AdtStructure {
|
|
|
433
441
|
this.connection.setSessionType('stateful');
|
|
434
442
|
const result = await (0, unlock_1.unlockStructure)(this.connection, config.structureName, lockHandle);
|
|
435
443
|
this.connection.setSessionType('stateless');
|
|
444
|
+
this.lockTracker.untrack(config.structureName);
|
|
436
445
|
return {
|
|
437
446
|
unlockResult: result,
|
|
438
447
|
errors: [],
|
|
@@ -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 { ITableConfig, ITableState } from './types';
|
|
24
25
|
export declare class AdtTable implements IAdtObject<ITableConfig, ITableState> {
|
|
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 table configuration before creation
|
|
32
34
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtTable.d.ts","sourceRoot":"","sources":["../../../src/core/table/AdtTable.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;AAOpD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAMzD,qBAAa,QAAS,YAAW,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC;IACpE,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,CAAW;gBAG3C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"AdtTable.d.ts","sourceRoot":"","sources":["../../../src/core/table/AdtTable.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;AAOpD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAMzD,qBAAa,QAAS,YAAW,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC;IACpE,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,CAAW;gBAG3C,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,iBAAiB,EACjC,YAAY,CAAC,EAAE,YAAY;IAY7B;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAanE;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,WAAW,CAAC;IAuDvB;;OAEG;IACG,IAAI,CACR,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,EAC/B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC;IAsBvB;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC;IAgCvB;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,WAAW,CAAC;IAkCvB;;;;OAIG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,WAAW,CAAC;IA4MvB;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IA6BjE;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAcnE;;OAEG;IACG,KAAK,CACT,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC;IAmBvB;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAc1D;;OAEG;IACG,MAAM,CACV,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,EAC7B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC;IAmBvB,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC;IAIzC,gBAAgB,CAAC,UAAU,EAAE,MAAM;CAGpC"}
|