@mcp-abap-adt/core 6.4.0 → 6.4.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [6.4.1] - 2026-04-21
6
+
7
+ ### Fixed
8
+ - `docker/Dockerfile`: switch default `MCP_TRANSPORT` from `stdio` to `http` so the image runs as an HTTP MCP server out of the box
9
+ - `docker/Dockerfile`: correct launcher path (`dist/server/v2/launcher.js` → `dist/server/launcher.js`) — previous path did not exist and prevented the container from starting
10
+ - `docker/Dockerfile`: pass `--allow-destination-header` so callers can supply SAP connection parameters via request headers (no default SAP connection baked into the image)
11
+ - `docker/Dockerfile`: fix healthcheck endpoint (`/health` → `/mcp/health`) to match the actual route exposed by `StreamableHttpServer`
12
+ - `docker/Dockerfile`: use `npm run build:fast` in the builder stage — the full `build` runs Biome which requires `.gitignore`, but `.dockerignore` excludes it
13
+
5
14
  ## [6.4.0] - 2026-04-20
6
15
 
7
16
  ### Added
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/core",
3
3
  "mcpName": "io.github.fr0ster/mcp-abap-adt",
4
- "version": "6.4.0",
4
+ "version": "6.4.1",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -43,9 +43,9 @@
43
43
  "test:init": "node -e \"const fs=require('fs'),s='tests/test-config.yaml',t=s+'.template';if(fs.existsSync(s)){console.log(s+' already exists, skipping (use test:reinit to overwrite)')}else{fs.copyFileSync(t,s);console.log('Created '+s+' — edit lines marked CHANGE')}\"",
44
44
  "test:reinit": "node -e \"const fs=require('fs'),s='tests/test-config.yaml',t=s+'.template';fs.copyFileSync(t,s);console.log('Recreated '+s+' from template')\"",
45
45
  "test": "jest --passWithNoTests",
46
- "test:integration": "jest --testPathPatterns=integration --runInBand --passWithNoTests --forceExit",
47
- "test:high": "jest --testPathPatterns='integration.*High' --runInBand --passWithNoTests --forceExit",
48
- "test:low": "jest --testPathPatterns='integration.*Low' --runInBand --passWithNoTests --forceExit",
46
+ "test:integration": "jest --testPathPatterns=integration --testPathIgnorePatterns='__tests__/admin/' --runInBand --passWithNoTests --forceExit",
47
+ "test:high": "jest --testPathPatterns='integration.*High' --testPathIgnorePatterns='__tests__/admin/' --runInBand --passWithNoTests --forceExit",
48
+ "test:low": "jest --testPathPatterns='integration.*Low' --testPathIgnorePatterns='__tests__/admin/' --runInBand --passWithNoTests --forceExit",
49
49
  "test:check": "npx tsc --noEmit -p tsconfig.test.json",
50
50
  "shared:setup": "jest --testPathPatterns='admin/shared-deps/setup' --testPathIgnorePatterns='[]' --runInBand --passWithNoTests",
51
51
  "shared:teardown": "jest --testPathPatterns='admin/shared-deps/teardown' --testPathIgnorePatterns='[]' --runInBand --passWithNoTests",
@@ -204,7 +204,8 @@
204
204
  "!src/**/index.ts"
205
205
  ],
206
206
  "testPathIgnorePatterns": [
207
- "__tests__/admin/"
207
+ "__tests__/admin/",
208
+ "__tests__/integration/"
208
209
  ],
209
210
  "maxWorkers": 1,
210
211
  "testTimeout": 600000,
@@ -1,220 +0,0 @@
1
- # Guaranteed Unlock on Error — Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Replace try-catch unlock-on-error with try-finally in all update handlers to guarantee unlock regardless of error path.
6
-
7
- **Architecture:** Move lock() inside the same try block that has the finally-unlock. Use the existing safe pattern from `handleUpdateFunctionGroup.ts` and `handleUpdateFunctionModule.ts` as reference. Activate stays AFTER the finally block (after unlock).
8
-
9
- **Tech Stack:** TypeScript, existing ADT client methods
10
-
11
- ---
12
-
13
- ## Reference Pattern (from handleUpdateFunctionModule.ts)
14
-
15
- ```typescript
16
- let lockHandle: string | undefined;
17
- try {
18
- lockHandle = await client.getXxx().lock({ ... });
19
- // ... check, update, etc.
20
- } finally {
21
- if (lockHandle) {
22
- try {
23
- await client.getXxx().unlock({ ... }, lockHandle);
24
- } catch (unlockError: any) {
25
- logger?.warn(`Failed to unlock after error: ${unlockError?.message || unlockError}`);
26
- }
27
- }
28
- }
29
- // activate AFTER finally (unlock already done)
30
- ```
31
-
32
- ## Key transformation
33
-
34
- **Before (vulnerable):**
35
- ```typescript
36
- lockHandle = await client.getXxx().lock({ ... }); // OUTSIDE try
37
- try {
38
- // check → update → unlock (happy path)
39
- } catch (workflowError) {
40
- // unlock-on-error (catch only)
41
- if (lockHandle) await client.getXxx().unlock({ ... }, lockHandle);
42
- throw workflowError;
43
- }
44
- ```
45
-
46
- **After (safe):**
47
- ```typescript
48
- let lockHandle: string | undefined;
49
- try {
50
- lockHandle = await client.getXxx().lock({ ... });
51
- // check → update (NO unlock in happy path — finally handles it)
52
- } finally {
53
- if (lockHandle) {
54
- try {
55
- await client.getXxx().unlock({ ... }, lockHandle);
56
- logger?.info(`Unlocked: ${objectName}`);
57
- } catch (unlockError: any) {
58
- logger?.warn(`Failed to unlock ${objectName}: ${unlockError?.message || unlockError}`);
59
- }
60
- }
61
- }
62
- // check inactive + activate AFTER finally
63
- ```
64
-
65
- **Important:** Remove the explicit `unlock()` call from the happy path — `finally` handles both happy and error paths. Check-inactive and activate move AFTER the finally block since they don't need the lock.
66
-
67
- ---
68
-
69
- ## Vulnerable Handlers (9 files)
70
-
71
- ### Task 1: handleUpdateProgram.ts
72
-
73
- **Files:**
74
- - Modify: `src/handlers/program/high/handleUpdateProgram.ts`
75
-
76
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
77
-
78
- Move `lock()` (line 111) inside the inner try. Replace inner `try { ... } catch (workflowError) { unlock; }` with `try { ... } finally { unlock; }`. Remove explicit `unlock()` from happy path (line 167). Move check-inactive (lines 171-191) and activate (lines 194-212) after the finally block.
79
-
80
- - [ ] **Step 2: Verify build**
81
-
82
- Run: `npx tsc --noEmit`
83
- Expected: no errors
84
-
85
- - [ ] **Step 3: Commit**
86
-
87
- ```bash
88
- git commit -m "fix(UpdateProgram): guarantee unlock via try-finally (#22)"
89
- ```
90
-
91
- ### Task 2: handleUpdateClass.ts
92
-
93
- **Files:**
94
- - Modify: `src/handlers/class/high/handleUpdateClass.ts`
95
-
96
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
97
-
98
- Same transformation: lock inside try, finally for unlock, remove happy-path unlock, move check-inactive + activate after finally.
99
-
100
- - [ ] **Step 2: Verify build**
101
-
102
- Run: `npx tsc --noEmit`
103
-
104
- - [ ] **Step 3: Commit**
105
-
106
- ```bash
107
- git commit -m "fix(UpdateClass): guarantee unlock via try-finally (#22)"
108
- ```
109
-
110
- ### Task 3: handleUpdateInterface.ts
111
-
112
- **Files:**
113
- - Modify: `src/handlers/interface/high/handleUpdateInterface.ts`
114
-
115
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
116
- - [ ] **Step 2: Verify build**
117
- - [ ] **Step 3: Commit**
118
-
119
- ```bash
120
- git commit -m "fix(UpdateInterface): guarantee unlock via try-finally (#22)"
121
- ```
122
-
123
- ### Task 4: handleUpdateView.ts
124
-
125
- **Files:**
126
- - Modify: `src/handlers/view/high/handleUpdateView.ts`
127
-
128
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
129
- - [ ] **Step 2: Verify build**
130
- - [ ] **Step 3: Commit**
131
-
132
- ```bash
133
- git commit -m "fix(UpdateView): guarantee unlock via try-finally (#22)"
134
- ```
135
-
136
- ### Task 5: handleUpdateTable.ts
137
-
138
- **Files:**
139
- - Modify: `src/handlers/table/high/handleUpdateTable.ts`
140
-
141
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
142
- - [ ] **Step 2: Verify build**
143
- - [ ] **Step 3: Commit**
144
-
145
- ```bash
146
- git commit -m "fix(UpdateTable): guarantee unlock via try-finally (#22)"
147
- ```
148
-
149
- ### Task 6: handleUpdateStructure.ts
150
-
151
- **Files:**
152
- - Modify: `src/handlers/structure/high/handleUpdateStructure.ts`
153
-
154
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
155
- - [ ] **Step 2: Verify build**
156
- - [ ] **Step 3: Commit**
157
-
158
- ```bash
159
- git commit -m "fix(UpdateStructure): guarantee unlock via try-finally (#22)"
160
- ```
161
-
162
- ### Task 7: handleUpdateDomain.ts
163
-
164
- **Files:**
165
- - Modify: `src/handlers/domain/high/handleUpdateDomain.ts`
166
-
167
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
168
- - [ ] **Step 2: Verify build**
169
- - [ ] **Step 3: Commit**
170
-
171
- ```bash
172
- git commit -m "fix(UpdateDomain): guarantee unlock via try-finally (#22)"
173
- ```
174
-
175
- ### Task 8: handleUpdateServiceDefinition.ts
176
-
177
- **Files:**
178
- - Modify: `src/handlers/service_definition/high/handleUpdateServiceDefinition.ts`
179
-
180
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
181
- - [ ] **Step 2: Verify build**
182
- - [ ] **Step 3: Commit**
183
-
184
- ```bash
185
- git commit -m "fix(UpdateServiceDefinition): guarantee unlock via try-finally (#22)"
186
- ```
187
-
188
- ### Task 9: handleUpdateDataElement.ts
189
-
190
- **Files:**
191
- - Modify: `src/handlers/data_element/high/handleUpdateDataElement.ts`
192
-
193
- - [ ] **Step 1: Refactor lock/unlock to try-finally**
194
- - [ ] **Step 2: Verify build**
195
- - [ ] **Step 3: Commit**
196
-
197
- ```bash
198
- git commit -m "fix(UpdateDataElement): guarantee unlock via try-finally (#22)"
199
- ```
200
-
201
- ### Task 10: Final verification
202
-
203
- - [ ] **Step 1: Full build check**
204
-
205
- Run: `npx tsc --noEmit`
206
-
207
- - [ ] **Step 2: Squash into single commit**
208
-
209
- Squash all 9 fix commits into one:
210
- ```bash
211
- git commit -m "fix: guarantee unlock via try-finally in all update handlers (#22)"
212
- ```
213
-
214
- - [ ] **Step 3: Update CHANGELOG.md**
215
-
216
- Add entry under `[Unreleased]`:
217
- ```markdown
218
- ### Fixed
219
- - Guarantee unlock via `try-finally` in all update handlers — prevents locked objects when errors occur between lock and unlock (#22). Affected: UpdateProgram, UpdateClass, UpdateInterface, UpdateView, UpdateTable, UpdateStructure, UpdateDomain, UpdateServiceDefinition, UpdateDataElement.
220
- ```