@mcp-abap-adt/connection 0.2.2 → 0.2.4

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/README.md CHANGED
@@ -105,6 +105,7 @@ This package interacts with external packages **ONLY through interfaces**:
105
105
  - 📝 **Custom Logging**: Pluggable logger interface for integration with any logging system (optional)
106
106
  - 📦 **TypeScript**: Full TypeScript support with type definitions included
107
107
  - ⚡ **Timeout Management**: Configurable timeouts for different operation types
108
+ - 🌐 **Network Error Detection**: Automatic detection and proper handling of network-level errors (connection refused, timeout, DNS failures)
108
109
 
109
110
  ## Installation
110
111
 
@@ -177,6 +178,38 @@ const response = await connection.makeAdtRequest({
177
178
  });
178
179
  ```
179
180
 
181
+ ### Cloud Usage with Automatic Token Refresh
182
+
183
+ For automatic token refresh on 401/403 errors, inject `ITokenRefresher`:
184
+
185
+ ```typescript
186
+ import { JwtAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
187
+ import type { ITokenRefresher } from "@mcp-abap-adt/interfaces";
188
+
189
+ // Token refresher provides token acquisition and refresh
190
+ // (created by @mcp-abap-adt/auth-broker or custom implementation)
191
+ const tokenRefresher: ITokenRefresher = {
192
+ getToken: async () => { /* return current token */ },
193
+ refreshToken: async () => { /* refresh and return new token */ },
194
+ };
195
+
196
+ // JWT configuration
197
+ const config: SapConfig = {
198
+ url: "https://your-instance.abap.cloud.sap",
199
+ authType: "jwt",
200
+ jwtToken: await tokenRefresher.getToken(), // Get initial token
201
+ };
202
+
203
+ // Create connection with token refresher - 401/403 handled automatically
204
+ const connection = new JwtAbapConnection(config, logger, undefined, tokenRefresher);
205
+
206
+ // Requests automatically retry with refreshed token on auth errors
207
+ const response = await connection.makeAdtRequest({
208
+ method: "GET",
209
+ url: "/sap/bc/adt/programs/programs/your-program",
210
+ });
211
+ ```
212
+
180
213
  ### Stateful Sessions
181
214
 
182
215
  For operations that require session state (e.g., object modifications), you can enable stateful sessions:
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/AbstractAbapConnection.ts"],"names":[],"mappings":"AAAA,OAAc,EAAiD,aAAa,EAAE,MAAM,OAAO,CAAC;AAG5F,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,uBAAe,sBAAuB,YAAW,cAAc;IAU3D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAV3C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAAyC;IAE5D,SAAS,aACU,MAAM,EAAE,SAAS,EACf,MAAM,EAAE,OAAO,GAAG,IAAI,EACzC,SAAS,CAAC,EAAE,MAAM;IAgBpB;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAOpD;;;;OAIG;IACH,qBAAqB,IAAI,IAAI;IAI7B;;;OAGG;IACH,sBAAsB,IAAI,IAAI;IAU9B;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,UAAU;IAI1C;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKrC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAK7B,SAAS,IAAI,SAAS;IAItB,KAAK,IAAI,IAAI;IAYP,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAevD;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE3B,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IA2MzE,SAAS,CAAC,QAAQ,CAAC,wBAAwB,IAAI,MAAM;IAErD;;;OAGG;cACa,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAgC,EAC5C,UAAU,GAAE,MAAgC,GAC3C,OAAO,CAAC,MAAM,CAAC;IAkKlB;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIlD;;OAEG;IACH,SAAS,CAAC,UAAU,IAAI,MAAM,GAAG,IAAI;IAIrC,OAAO,CAAC,yBAAyB;IAuDjC,OAAO,CAAC,gBAAgB;YAmBV,oBAAoB;IAwBlC,OAAO,CAAC,eAAe;CAyBxB;AAGD,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"AbstractAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/AbstractAbapConnection.ts"],"names":[],"mappings":"AAAA,OAAc,EAAiD,aAAa,EAAE,MAAM,OAAO,CAAC;AAI5F,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,uBAAe,sBAAuB,YAAW,cAAc;IAU3D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAV3C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAAyC;IAE5D,SAAS,aACU,MAAM,EAAE,SAAS,EACf,MAAM,EAAE,OAAO,GAAG,IAAI,EACzC,SAAS,CAAC,EAAE,MAAM;IAgBpB;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAOpD;;;;OAIG;IACH,qBAAqB,IAAI,IAAI;IAI7B;;;OAGG;IACH,sBAAsB,IAAI,IAAI;IAU9B;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,UAAU;IAI1C;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKrC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAK7B,SAAS,IAAI,SAAS;IAItB,KAAK,IAAI,IAAI;IAYP,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAevD;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAE3B,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAoNzE,SAAS,CAAC,QAAQ,CAAC,wBAAwB,IAAI,MAAM;IAErD;;;OAGG;cACa,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAgC,EAC5C,UAAU,GAAE,MAAgC,GAC3C,OAAO,CAAC,MAAM,CAAC;IAkKlB;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIlD;;OAEG;IACH,SAAS,CAAC,UAAU,IAAI,MAAM,GAAG,IAAI;IAIrC,OAAO,CAAC,yBAAyB;IAuDjC,OAAO,CAAC,gBAAgB;YAmBV,oBAAoB;IAwBlC,OAAO,CAAC,eAAe;CAyBxB;AAGD,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -37,6 +37,7 @@ exports.AbstractAbapConnection = void 0;
37
37
  const axios_1 = __importStar(require("axios"));
38
38
  const https_1 = require("https");
39
39
  const crypto_1 = require("crypto");
40
+ const interfaces_1 = require("@mcp-abap-adt/interfaces");
40
41
  const timeouts_js_1 = require("../utils/timeouts.js");
41
42
  const csrfConfig_js_1 = require("./csrfConfig.js");
42
43
  class AbstractAbapConnection {
@@ -247,6 +248,13 @@ class AbstractAbapConnection {
247
248
  : JSON.stringify(error.response.data).slice(0, 200);
248
249
  this.updateCookiesFromResponse(error.response.headers);
249
250
  }
251
+ // Check if this is a network error (connection refused, timeout, DNS, etc.)
252
+ // Don't retry for network errors - these indicate infrastructure/VPN issues
253
+ const networkError = (0, interfaces_1.isNetworkError)(error);
254
+ if (networkError) {
255
+ this.logger?.error(`Network error - cannot connect to SAP system: ${errorDetails.message}`, errorDetails);
256
+ throw error;
257
+ }
250
258
  // Log 404 as debug (common for existence checks), other errors as error
251
259
  if (errorDetails.status === 404) {
252
260
  this.logger?.debug(errorDetails.message, errorDetails);
@@ -3,26 +3,34 @@ import { AbstractAbapConnection } from "./AbstractAbapConnection.js";
3
3
  import { AbapRequestOptions } from "./AbapConnection.js";
4
4
  import { ILogger } from "../logger.js";
5
5
  import { AxiosResponse } from "axios";
6
+ import type { ITokenRefresher } from "@mcp-abap-adt/interfaces";
6
7
  /**
7
8
  * JWT Authentication connection for SAP BTP Cloud systems
8
- * Note: Token refresh functionality is not supported in this package.
9
- * Use @mcp-abap-adt/auth-broker for token refresh functionality.
9
+ *
10
+ * Supports automatic token refresh via ITokenRefresher injection:
11
+ * - If tokenRefresher is provided, 401/403 errors trigger automatic token refresh
12
+ * - If tokenRefresher is not provided, 401/403 errors throw an error (legacy behavior)
10
13
  */
11
14
  export declare class JwtAbapConnection extends AbstractAbapConnection {
12
- constructor(config: SapConfig, logger?: ILogger | null, sessionId?: string);
15
+ private tokenRefresher?;
16
+ private currentToken;
17
+ constructor(config: SapConfig, logger?: ILogger | null, sessionId?: string, tokenRefresher?: ITokenRefresher);
13
18
  protected buildAuthorizationHeader(): string;
19
+ /**
20
+ * Refresh the JWT token using the injected tokenRefresher
21
+ * @returns true if token was refreshed, false if no refresher available
22
+ */
23
+ private tryRefreshToken;
14
24
  /**
15
25
  * Override connect to handle JWT token refresh on errors
16
26
  */
17
27
  connect(): Promise<void>;
18
28
  /**
19
- * Override makeAdtRequest to handle JWT auth errors
20
- * Note: Token refresh is not supported in connection package - use auth-broker instead
29
+ * Override makeAdtRequest to handle JWT auth errors with automatic token refresh
21
30
  */
22
31
  makeAdtRequest(options: AbapRequestOptions): Promise<AxiosResponse>;
23
32
  /**
24
- * Override fetchCsrfToken to handle JWT auth errors
25
- * Note: Token refresh is not supported in connection package - use auth-broker instead
33
+ * Override fetchCsrfToken to handle JWT auth errors with automatic token refresh
26
34
  */
27
35
  protected fetchCsrfToken(url: string, retryCount?: number, retryDelay?: number): Promise<string>;
28
36
  private static validateConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"JwtAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/JwtAbapConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAc,aAAa,EAAE,MAAM,OAAO,CAAC;AAElD;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,sBAAsB;gBAGzD,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM;IAMpB,SAAS,CAAC,wBAAwB,IAAI,MAAM;IAW5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C9B;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAkCzE;;;OAGG;cACa,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAI,EAAE,UAAU,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IA8B/F,OAAO,CAAC,MAAM,CAAC,cAAc;CAS9B"}
1
+ {"version":3,"file":"JwtAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/JwtAbapConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAc,aAAa,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAkB;IACzC,OAAO,CAAC,YAAY,CAAS;gBAG3B,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,eAAe;IAQlC,SAAS,CAAC,wBAAwB,IAAI,MAAM;IAO5C;;;OAGG;YACW,eAAe;IAmB7B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgD9B;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAwCzE;;OAEG;cACa,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAI,EAAE,UAAU,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC/F,OAAO,CAAC,MAAM,CAAC,cAAc;CAS9B"}
@@ -5,21 +5,46 @@ const AbstractAbapConnection_js_1 = require("./AbstractAbapConnection.js");
5
5
  const axios_1 = require("axios");
6
6
  /**
7
7
  * JWT Authentication connection for SAP BTP Cloud systems
8
- * Note: Token refresh functionality is not supported in this package.
9
- * Use @mcp-abap-adt/auth-broker for token refresh functionality.
8
+ *
9
+ * Supports automatic token refresh via ITokenRefresher injection:
10
+ * - If tokenRefresher is provided, 401/403 errors trigger automatic token refresh
11
+ * - If tokenRefresher is not provided, 401/403 errors throw an error (legacy behavior)
10
12
  */
11
13
  class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnection {
12
- constructor(config, logger, sessionId) {
14
+ tokenRefresher;
15
+ currentToken;
16
+ constructor(config, logger, sessionId, tokenRefresher) {
13
17
  JwtAbapConnection.validateConfig(config);
14
18
  super(config, logger || null, sessionId);
19
+ this.tokenRefresher = tokenRefresher;
20
+ this.currentToken = config.jwtToken;
15
21
  }
16
22
  buildAuthorizationHeader() {
17
- const config = this.getConfig();
18
- const { jwtToken } = config;
19
- // Log token preview for debugging (first 10 and last 4 chars)
20
- const tokenPreview = jwtToken ? `${jwtToken.substring(0, 10)}...${jwtToken.substring(Math.max(0, jwtToken.length - 4))}` : 'null';
23
+ // Use currentToken which may have been refreshed
24
+ const tokenPreview = this.currentToken ? `${this.currentToken.substring(0, 10)}...${this.currentToken.substring(Math.max(0, this.currentToken.length - 4))}` : 'null';
21
25
  this.logger?.debug(`[DEBUG] JwtAbapConnection.buildAuthorizationHeader - Using token: ${tokenPreview}`);
22
- return `Bearer ${jwtToken}`;
26
+ return `Bearer ${this.currentToken}`;
27
+ }
28
+ /**
29
+ * Refresh the JWT token using the injected tokenRefresher
30
+ * @returns true if token was refreshed, false if no refresher available
31
+ */
32
+ async tryRefreshToken() {
33
+ if (!this.tokenRefresher) {
34
+ this.logger?.debug(`[DEBUG] JwtAbapConnection - No tokenRefresher available, cannot refresh token`);
35
+ return false;
36
+ }
37
+ try {
38
+ this.logger?.debug(`[DEBUG] JwtAbapConnection - Refreshing token via tokenRefresher...`);
39
+ const newToken = await this.tokenRefresher.refreshToken();
40
+ this.currentToken = newToken;
41
+ this.logger?.debug(`[DEBUG] JwtAbapConnection - Token refreshed successfully`);
42
+ return true;
43
+ }
44
+ catch (error) {
45
+ this.logger?.error(`[ERROR] JwtAbapConnection - Failed to refresh token: ${error instanceof Error ? error.message : String(error)}`);
46
+ return false;
47
+ }
23
48
  }
24
49
  /**
25
50
  * Override connect to handle JWT token refresh on errors
@@ -51,8 +76,12 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
51
76
  responseText.includes("Missing authorization")) {
52
77
  throw error;
53
78
  }
54
- // Token refresh is not supported in connection package
55
- // Use auth-broker for token refresh functionality
79
+ // Try to refresh token if tokenRefresher is available
80
+ if (await this.tryRefreshToken()) {
81
+ // Retry connect with new token
82
+ this.logger?.debug(`[DEBUG] JwtAbapConnection - Retrying connect after token refresh...`);
83
+ return this.connect();
84
+ }
56
85
  throw new Error("JWT token has expired. Please re-authenticate.");
57
86
  }
58
87
  // Re-throw other errors
@@ -60,8 +89,7 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
60
89
  }
61
90
  }
62
91
  /**
63
- * Override makeAdtRequest to handle JWT auth errors
64
- * Note: Token refresh is not supported in connection package - use auth-broker instead
92
+ * Override makeAdtRequest to handle JWT auth errors with automatic token refresh
65
93
  */
66
94
  async makeAdtRequest(options) {
67
95
  this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Starting request: ${options.method} ${options.url}`);
@@ -75,7 +103,7 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
75
103
  // Handle JWT auth errors (401/403)
76
104
  if (error instanceof axios_1.AxiosError &&
77
105
  (error.response?.status === 401 || error.response?.status === 403)) {
78
- this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Got ${error.response.status}, checking if refresh is possible...`);
106
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Got ${error.response.status}, attempting token refresh...`);
79
107
  // Check if this is really an auth error, not a permissions error
80
108
  const responseData = error.response?.data;
81
109
  const responseText = typeof responseData === "string" ? responseData : JSON.stringify(responseData || "");
@@ -85,16 +113,20 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
85
113
  responseText.includes("Missing authorization")) {
86
114
  throw error;
87
115
  }
88
- // Token refresh is not supported in connection package
89
- // Use auth-broker for token refresh functionality
116
+ // Try to refresh token if tokenRefresher is available
117
+ if (await this.tryRefreshToken()) {
118
+ // Reset connection state and retry request with new token
119
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Retrying request after token refresh...`);
120
+ this.reset();
121
+ return super.makeAdtRequest(options);
122
+ }
90
123
  throw new Error("JWT token has expired. Please re-authenticate.");
91
124
  }
92
125
  throw error;
93
126
  }
94
127
  }
95
128
  /**
96
- * Override fetchCsrfToken to handle JWT auth errors
97
- * Note: Token refresh is not supported in connection package - use auth-broker instead
129
+ * Override fetchCsrfToken to handle JWT auth errors with automatic token refresh
98
130
  */
99
131
  async fetchCsrfToken(url, retryCount = 3, retryDelay = 1000) {
100
132
  try {
@@ -114,8 +146,12 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
114
146
  responseText.includes("Missing authorization")) {
115
147
  throw error;
116
148
  }
117
- // Token refresh is not supported in connection package
118
- // Use auth-broker for token refresh functionality
149
+ // Try to refresh token if tokenRefresher is available
150
+ if (await this.tryRefreshToken()) {
151
+ // Retry CSRF token fetch with new token
152
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.fetchCsrfToken - Retrying after token refresh...`);
153
+ return super.fetchCsrfToken(url, retryCount, retryDelay);
154
+ }
119
155
  throw new Error("JWT token has expired. Please re-authenticate.");
120
156
  }
121
157
  // Re-throw other errors
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/connection",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "ABAP connection layer for MCP ABAP ADT server",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -42,7 +42,7 @@
42
42
  "node": ">=18.0.0"
43
43
  },
44
44
  "dependencies": {
45
- "@mcp-abap-adt/interfaces": "^0.1.16",
45
+ "@mcp-abap-adt/interfaces": "^0.2.5",
46
46
  "axios": "^1.11.0",
47
47
  "commander": "^14.0.2",
48
48
  "express": "^5.1.0",
@@ -52,6 +52,7 @@
52
52
  "@types/jest": "^30.0.0",
53
53
  "@types/node": "^24.2.1",
54
54
  "jest": "^30.2.0",
55
+ "jest-util": "^30.2.0",
55
56
  "ts-jest": "^29.2.5",
56
57
  "typescript": "^5.9.2"
57
58
  }