@mcp-abap-adt/connection 0.1.15 → 0.2.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.
@@ -2,156 +2,37 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.JwtAbapConnection = void 0;
4
4
  const AbstractAbapConnection_js_1 = require("./AbstractAbapConnection.js");
5
- const tokenRefresh_js_1 = require("../utils/tokenRefresh.js");
6
5
  const axios_1 = require("axios");
7
6
  /**
8
7
  * JWT Authentication connection for SAP BTP Cloud systems
9
- * Supports automatic token refresh using OAuth2 refresh tokens
8
+ * Note: Token refresh functionality is not supported in this package.
9
+ * Use @mcp-abap-adt/auth-broker for token refresh functionality.
10
10
  */
11
11
  class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnection {
12
- tokenRefreshInProgress = false;
13
- constructor(config, logger, sessionStorage, sessionId) {
12
+ constructor(config, logger, sessionId) {
14
13
  JwtAbapConnection.validateConfig(config);
15
- super(config, logger, sessionStorage, sessionId);
14
+ super(config, logger || null, sessionId);
16
15
  }
17
16
  buildAuthorizationHeader() {
18
17
  const config = this.getConfig();
19
18
  const { jwtToken } = config;
20
19
  // Log token preview for debugging (first 10 and last 4 chars)
21
20
  const tokenPreview = jwtToken ? `${jwtToken.substring(0, 10)}...${jwtToken.substring(Math.max(0, jwtToken.length - 4))}` : 'null';
22
- this.logger.debug(`[DEBUG] JwtAbapConnection.buildAuthorizationHeader - Using token: ${tokenPreview}`);
21
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.buildAuthorizationHeader - Using token: ${tokenPreview}`);
23
22
  return `Bearer ${jwtToken}`;
24
23
  }
25
- /**
26
- * Refresh JWT token using refresh token
27
- * @returns Promise that resolves when token is refreshed
28
- */
29
- async refreshToken() {
30
- const config = this.getConfig();
31
- if (!config.refreshToken) {
32
- throw new Error("Refresh token is not available. Please re-authenticate.");
33
- }
34
- if (!config.uaaUrl || !config.uaaClientId || !config.uaaClientSecret) {
35
- throw new Error("UAA credentials are not available for token refresh. " +
36
- "Please provide UAA_URL, UAA_CLIENT_ID, and UAA_CLIENT_SECRET in configuration or re-authenticate.");
37
- }
38
- // Prevent concurrent refresh attempts
39
- if (this.tokenRefreshInProgress) {
40
- this.logger.debug("Token refresh already in progress, waiting...");
41
- // Wait for ongoing refresh to complete
42
- while (this.tokenRefreshInProgress) {
43
- await new Promise(resolve => setTimeout(resolve, 100));
44
- }
45
- return;
46
- }
47
- this.tokenRefreshInProgress = true;
48
- try {
49
- this.logger.debug("Refreshing JWT token...");
50
- const tokens = await (0, tokenRefresh_js_1.refreshJwtToken)(config.refreshToken, config.uaaUrl, config.uaaClientId, config.uaaClientSecret);
51
- // Update config with new tokens
52
- // NOTE: This updates the config object directly, which is shared with the connection cache
53
- // The connection cache will be invalidated on next getManagedConnection() call because
54
- // sapConfigSignature includes token preview, so signature will change
55
- const oldTokenPreview = config.jwtToken ? `${config.jwtToken.substring(0, 10)}...${config.jwtToken.substring(Math.max(0, config.jwtToken.length - 4))}` : 'null';
56
- config.jwtToken = tokens.accessToken;
57
- if (tokens.refreshToken) {
58
- config.refreshToken = tokens.refreshToken;
59
- }
60
- const newTokenPreview = config.jwtToken ? `${config.jwtToken.substring(0, 10)}...${config.jwtToken.substring(Math.max(0, config.jwtToken.length - 4))}` : 'null';
61
- this.logger.debug(`[DEBUG] JwtAbapConnection.refreshToken - Token updated in config: ${oldTokenPreview} -> ${newTokenPreview}`);
62
- this.logger.debug(`[DEBUG] JwtAbapConnection.refreshToken - Config object reference check: ${config === this.getConfig() ? 'same object ✓' : 'different object ✗'}`);
63
- // Clear CSRF token and cookies to force new session with new token
64
- // IMPORTANT: After token refresh, we must clear saved session state because
65
- // old cookies/CSRF token are tied to the old JWT token and won't work with new token
66
- this.reset();
67
- // Also clear saved session state from storage if using stateful session
68
- // This prevents reloading old cookies/CSRF token that are tied to old JWT token
69
- const sessionStorage = this.getSessionStorage();
70
- const sessionId = this.getSessionId();
71
- if (sessionStorage && sessionId) {
72
- try {
73
- await this.clearSessionState();
74
- this.logger.debug(`[DEBUG] JwtAbapConnection.refreshToken - Cleared saved session state from storage`);
75
- }
76
- catch (error) {
77
- this.logger.warn(`[DEBUG] JwtAbapConnection.refreshToken - Failed to clear session state: ${error instanceof Error ? error.message : String(error)}`);
78
- }
79
- }
80
- this.logger.debug("JWT token refreshed successfully");
81
- this.logger.debug("NOTE: Connection cache will be invalidated on next getManagedConnection() call due to changed token signature");
82
- }
83
- catch (error) {
84
- this.logger.error(`Failed to refresh JWT token: ${error.message}`);
85
- throw error;
86
- }
87
- finally {
88
- this.tokenRefreshInProgress = false;
89
- }
90
- }
91
- /**
92
- * Check if token refresh is possible
93
- */
94
- canRefreshToken() {
95
- const config = this.getConfig();
96
- return !!(config.refreshToken &&
97
- config.uaaUrl &&
98
- config.uaaClientId &&
99
- config.uaaClientSecret);
100
- }
101
24
  /**
102
25
  * Override connect to handle JWT token refresh on errors
103
26
  */
104
27
  async connect() {
105
28
  const baseUrl = await this.getBaseUrl();
106
29
  const discoveryUrl = `${baseUrl}/sap/bc/adt/discovery`;
107
- this.logger.debug(`[DEBUG] JwtAbapConnection - Connecting to SAP system: ${discoveryUrl}`);
108
- // If we have saved session state, load it first to compare later
109
- const sessionStorage = this.getSessionStorage();
110
- const sessionId = this.getSessionId();
111
- let savedState = null;
112
- if (sessionStorage && sessionId) {
113
- try {
114
- savedState = await sessionStorage.load(sessionId);
115
- if (savedState) {
116
- this.logger.debug(`[DEBUG] JwtAbapConnection.connect - Loaded saved session state for comparison`);
117
- }
118
- }
119
- catch (error) {
120
- this.logger.debug(`[DEBUG] JwtAbapConnection.connect - No saved session state found or failed to load`);
121
- }
122
- }
30
+ this.logger?.debug(`[DEBUG] JwtAbapConnection - Connecting to SAP system: ${discoveryUrl}`);
123
31
  try {
124
32
  // Try to get CSRF token (this will also get cookies)
125
33
  const token = await this.fetchCsrfToken(discoveryUrl, 3, 1000);
126
34
  this.setCsrfToken(token);
127
- // Compare new session state with saved state
128
- const newState = {
129
- cookies: this.getCookies(),
130
- csrfToken: this.getCsrfToken(),
131
- cookieStore: Object.fromEntries(this.cookieStore || new Map())
132
- };
133
- // Only save if session state changed
134
- if (savedState) {
135
- const cookiesChanged = savedState.cookies !== newState.cookies;
136
- const csrfTokenChanged = savedState.csrfToken !== newState.csrfToken;
137
- const cookieStoreChanged = JSON.stringify(savedState.cookieStore) !== JSON.stringify(newState.cookieStore);
138
- if (cookiesChanged || csrfTokenChanged || cookieStoreChanged) {
139
- this.logger.debug(`[DEBUG] JwtAbapConnection.connect - Session state changed, saving new state`, {
140
- cookiesChanged,
141
- csrfTokenChanged,
142
- cookieStoreChanged
143
- });
144
- await this.saveSessionState();
145
- }
146
- else {
147
- this.logger.debug(`[DEBUG] JwtAbapConnection.connect - Session state unchanged, not saving`);
148
- }
149
- }
150
- else {
151
- // No saved state, save new one
152
- await this.saveSessionState();
153
- }
154
- this.logger.debug("Successfully connected to SAP system", {
35
+ this.logger?.debug("Successfully connected to SAP system", {
155
36
  hasCsrfToken: !!this.getCsrfToken(),
156
37
  hasCookies: !!this.getCookies(),
157
38
  cookieLength: this.getCookies()?.length || 0
@@ -170,52 +51,31 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
170
51
  responseText.includes("Missing authorization")) {
171
52
  throw error;
172
53
  }
173
- // Try token refresh if possible
174
- if (this.canRefreshToken()) {
175
- try {
176
- this.logger.debug(`Received ${error.response.status} during connect, attempting JWT token refresh...`);
177
- await this.refreshToken();
178
- this.logger.debug(`✓ Token refreshed successfully, retrying connect...`);
179
- // Retry CSRF token fetch with new JWT token
180
- const token = await this.fetchCsrfToken(discoveryUrl, 3, 1000);
181
- this.setCsrfToken(token);
182
- await this.saveSessionState();
183
- this.logger.debug("Successfully connected after JWT refresh", {
184
- hasCsrfToken: !!this.getCsrfToken(),
185
- hasCookies: !!this.getCookies()
186
- });
187
- return;
188
- }
189
- catch (refreshError) {
190
- this.logger.error(`❌ Token refresh failed during connect: ${refreshError.message}`);
191
- throw new Error("Refresh token has expired. Please re-authenticate.");
192
- }
193
- }
194
- else {
195
- // No refresh token available - JWT token expired, need to re-authenticate
196
- throw new Error("JWT token has expired. Please re-authenticate.");
197
- }
54
+ // Token refresh is not supported in connection package
55
+ // Use auth-broker for token refresh functionality
56
+ throw new Error("JWT token has expired. Please re-authenticate.");
198
57
  }
199
58
  // Re-throw other errors
200
59
  throw error;
201
60
  }
202
61
  }
203
62
  /**
204
- * Override makeAdtRequest to handle JWT token refresh on 401/403
63
+ * Override makeAdtRequest to handle JWT auth errors
64
+ * Note: Token refresh is not supported in connection package - use auth-broker instead
205
65
  */
206
66
  async makeAdtRequest(options) {
207
- this.logger.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Starting request: ${options.method} ${options.url}`);
67
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Starting request: ${options.method} ${options.url}`);
208
68
  try {
209
69
  const response = await super.makeAdtRequest(options);
210
- this.logger.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Request succeeded: ${response.status}`);
70
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Request succeeded: ${response.status}`);
211
71
  return response;
212
72
  }
213
73
  catch (error) {
214
- this.logger.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Request failed: ${error instanceof Error ? error.message : String(error)}`);
74
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Request failed: ${error instanceof Error ? error.message : String(error)}`);
215
75
  // Handle JWT auth errors (401/403)
216
76
  if (error instanceof axios_1.AxiosError &&
217
77
  (error.response?.status === 401 || error.response?.status === 403)) {
218
- this.logger.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Got ${error.response.status}, checking if refresh is possible...`);
78
+ this.logger?.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - Got ${error.response.status}, checking if refresh is possible...`);
219
79
  // Check if this is really an auth error, not a permissions error
220
80
  const responseData = error.response?.data;
221
81
  const responseText = typeof responseData === "string" ? responseData : JSON.stringify(responseData || "");
@@ -225,85 +85,16 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
225
85
  responseText.includes("Missing authorization")) {
226
86
  throw error;
227
87
  }
228
- // Try token refresh if possible
229
- const canRefresh = this.canRefreshToken();
230
- const config = this.getConfig();
231
- this.logger.debug(`[DEBUG] JwtAbapConnection.makeAdtRequest - canRefreshToken: ${canRefresh}`, {
232
- hasRefreshToken: !!config.refreshToken,
233
- hasUaaUrl: !!config.uaaUrl,
234
- hasUaaClientId: !!config.uaaClientId,
235
- hasUaaClientSecret: !!config.uaaClientSecret
236
- });
237
- if (canRefresh) {
238
- // Step 1: Refresh token
239
- try {
240
- this.logger.debug(`Received ${error.response.status}, attempting JWT token refresh...`);
241
- await this.refreshToken();
242
- this.logger.debug(`✓ Token refreshed successfully, reconnecting to get new CSRF token...`);
243
- }
244
- catch (refreshError) {
245
- // Only catch errors from refreshToken()
246
- this.logger.error(`❌ Token refresh failed: ${refreshError.message}`);
247
- throw new Error("Refresh token has expired. Please re-authenticate.");
248
- }
249
- // Step 2: Reconnect to get new CSRF token and cookies
250
- try {
251
- this.logger.debug(`[DEBUG] JwtAbapConnection - Calling connect() after token refresh to get CSRF token...`);
252
- await this.connect();
253
- const hasCsrf = !!this.getCsrfToken();
254
- const hasCookies = !!this.getCookies();
255
- this.logger.debug(`✓ Reconnected successfully after token refresh`, {
256
- hasCsrfToken: hasCsrf,
257
- hasCookies: hasCookies,
258
- csrfTokenLength: this.getCsrfToken()?.length || 0,
259
- cookiesLength: this.getCookies()?.length || 0
260
- });
261
- if (!hasCsrf) {
262
- this.logger.error(`❌ CRITICAL: CSRF token not obtained after reconnect! Request may fail.`);
263
- }
264
- }
265
- catch (connectError) {
266
- // If connect() fails after token refresh, it means the refresh token was invalid
267
- // Check if it's an auth error (401/403)
268
- if (connectError instanceof axios_1.AxiosError &&
269
- (connectError.response?.status === 401 || connectError.response?.status === 403)) {
270
- this.logger.error(`❌ Failed to reconnect after token refresh: ${connectError.message}`);
271
- throw new Error("Refresh token has expired. Please re-authenticate.");
272
- }
273
- // For other errors, log but continue - ensureFreshCsrfToken will try to get CSRF token during request retry
274
- this.logger.error(`❌ Failed to reconnect after token refresh: ${connectError.message}`);
275
- this.logger.error(`❌ This means CSRF token will not be available for POST/PUT/DELETE requests`);
276
- }
277
- // Step 3: Retry the request with new token
278
- // ensureFreshCsrfToken will be called automatically if CSRF token is missing
279
- this.logger.debug(`[DEBUG] JwtAbapConnection - Retrying ADT request after token refresh...`);
280
- try {
281
- return await super.makeAdtRequest(options);
282
- }
283
- catch (retryError) {
284
- // If retry fails with 401/403, it means token refresh didn't help - re-throw as auth error
285
- if (retryError instanceof axios_1.AxiosError &&
286
- (retryError.response?.status === 401 || retryError.response?.status === 403)) {
287
- this.logger.error(`❌ Token refresh didn't help - still getting ${retryError.response.status}`);
288
- throw new Error("Refresh token has expired. Please re-authenticate.");
289
- }
290
- // For other errors (400, 500, etc.), re-throw the original error
291
- // These are not auth errors, so they should be handled by the caller
292
- this.logger.debug(`[DEBUG] JwtAbapConnection - Retry request failed with non-auth error: ${retryError.response?.status || 'unknown'}`);
293
- throw retryError;
294
- }
295
- }
296
- else {
297
- // No refresh token available - JWT token expired, need to re-authenticate
298
- throw new Error("JWT token has expired. Please re-authenticate.");
299
- }
88
+ // Token refresh is not supported in connection package
89
+ // Use auth-broker for token refresh functionality
90
+ throw new Error("JWT token has expired. Please re-authenticate.");
300
91
  }
301
92
  throw error;
302
93
  }
303
94
  }
304
95
  /**
305
- * Override fetchCsrfToken to handle JWT token refresh on 401/403 errors
306
- * This ensures that token refresh works even when CSRF token is fetched during makeAdtRequest
96
+ * Override fetchCsrfToken to handle JWT auth errors
97
+ * Note: Token refresh is not supported in connection package - use auth-broker instead
307
98
  */
308
99
  async fetchCsrfToken(url, retryCount = 3, retryDelay = 1000) {
309
100
  try {
@@ -323,24 +114,9 @@ class JwtAbapConnection extends AbstractAbapConnection_js_1.AbstractAbapConnecti
323
114
  responseText.includes("Missing authorization")) {
324
115
  throw error;
325
116
  }
326
- // Try token refresh if possible
327
- if (this.canRefreshToken()) {
328
- try {
329
- this.logger.debug(`Received ${error.response.status} during CSRF token fetch, attempting JWT token refresh...`);
330
- await this.refreshToken();
331
- this.logger.debug(`✓ Token refreshed successfully, retrying CSRF token fetch...`);
332
- // Retry CSRF token fetch with new JWT token
333
- return await super.fetchCsrfToken(url, retryCount, retryDelay);
334
- }
335
- catch (refreshError) {
336
- this.logger.error(`❌ Token refresh failed during CSRF token fetch: ${refreshError.message}`);
337
- throw new Error("Refresh token has expired. Please re-authenticate.");
338
- }
339
- }
340
- else {
341
- // No refresh token available - JWT token expired, need to re-authenticate
342
- throw new Error("JWT token has expired. Please re-authenticate.");
343
- }
117
+ // Token refresh is not supported in connection package
118
+ // Use auth-broker for token refresh functionality
119
+ throw new Error("JWT token has expired. Please re-authenticate.");
344
120
  }
345
121
  // Re-throw other errors
346
122
  throw error;
@@ -1,5 +1,5 @@
1
1
  import { SapConfig } from "../config/sapConfig.js";
2
2
  import { AbapConnection } from "./AbapConnection.js";
3
- import { ILogger, ISessionStorage } from "../logger.js";
4
- export declare function createAbapConnection(config: SapConfig, logger: ILogger, sessionStorage?: ISessionStorage, sessionId?: string): AbapConnection;
3
+ import { ILogger } from "../logger.js";
4
+ export declare function createAbapConnection(config: SapConfig, logger?: ILogger | null, sessionId?: string): AbapConnection;
5
5
  //# sourceMappingURL=connectionFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connectionFactory.d.ts","sourceRoot":"","sources":["../../src/connection/connectionFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAExD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,OAAO,EACf,cAAc,CAAC,EAAE,eAAe,EAChC,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,CAShB"}
1
+ {"version":3,"file":"connectionFactory.d.ts","sourceRoot":"","sources":["../../src/connection/connectionFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,EACvB,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,CAShB"}
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createAbapConnection = createAbapConnection;
4
4
  const JwtAbapConnection_js_1 = require("./JwtAbapConnection.js");
5
5
  const BaseAbapConnection_js_1 = require("./BaseAbapConnection.js");
6
- function createAbapConnection(config, logger, sessionStorage, sessionId) {
6
+ function createAbapConnection(config, logger, sessionId) {
7
7
  switch (config.authType) {
8
8
  case "basic":
9
- return new BaseAbapConnection_js_1.BaseAbapConnection(config, logger, sessionStorage, sessionId);
9
+ return new BaseAbapConnection_js_1.BaseAbapConnection(config, logger, sessionId);
10
10
  case "jwt":
11
- return new JwtAbapConnection_js_1.JwtAbapConnection(config, logger, sessionStorage, sessionId);
11
+ return new JwtAbapConnection_js_1.JwtAbapConnection(config, logger, sessionId);
12
12
  default:
13
13
  throw new Error(`Unsupported SAP authentication type: ${config.authType}`);
14
14
  }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  export type { SapConfig, SapAuthType, } from "./config/sapConfig.js";
2
2
  export type { AbapRequestOptions } from "./connection/AbapConnection.js";
3
3
  export { type AbapConnection } from "./connection/AbapConnection.js";
4
- export type { ILogger, SessionState, ISessionStorage } from "./logger.js";
5
- export { FileSessionStorage, type FileSessionStorageOptions } from "./utils/FileSessionStorage.js";
4
+ export type { ILogger } from "./logger.js";
6
5
  export { BaseAbapConnection } from "./connection/BaseAbapConnection.js";
7
6
  export { JwtAbapConnection } from "./connection/JwtAbapConnection.js";
8
7
  export { BaseAbapConnection as OnPremAbapConnection } from "./connection/BaseAbapConnection.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAGnG,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGtE,OAAO,EAAE,kBAAkB,IAAI,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAE,iBAAiB,IAAI,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAG7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGtE,OAAO,EAAE,kBAAkB,IAAI,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAE,iBAAiB,IAAI,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAG7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CSRF_ERROR_MESSAGES = exports.CSRF_CONFIG = exports.getTimeoutConfig = exports.getTimeout = exports.sapConfigSignature = exports.createAbapConnection = exports.CloudAbapConnection = exports.OnPremAbapConnection = exports.JwtAbapConnection = exports.BaseAbapConnection = exports.FileSessionStorage = void 0;
4
- // Session storage implementations
5
- var FileSessionStorage_js_1 = require("./utils/FileSessionStorage.js");
6
- Object.defineProperty(exports, "FileSessionStorage", { enumerable: true, get: function () { return FileSessionStorage_js_1.FileSessionStorage; } });
3
+ exports.CSRF_ERROR_MESSAGES = exports.CSRF_CONFIG = exports.getTimeoutConfig = exports.getTimeout = exports.sapConfigSignature = exports.createAbapConnection = exports.CloudAbapConnection = exports.OnPremAbapConnection = exports.JwtAbapConnection = exports.BaseAbapConnection = void 0;
7
4
  // Connection classes - only final implementations
8
5
  var BaseAbapConnection_js_1 = require("./connection/BaseAbapConnection.js");
9
6
  Object.defineProperty(exports, "BaseAbapConnection", { enumerable: true, get: function () { return BaseAbapConnection_js_1.BaseAbapConnection; } });
package/dist/logger.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { ILogger, ISessionStorage, ISessionState } from '@mcp-abap-adt/interfaces';
2
- export type { ILogger, ISessionStorage };
3
- export type SessionState = ISessionState;
1
+ import type { ILogger } from '@mcp-abap-adt/interfaces';
2
+ export type { ILogger };
4
3
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGxF,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;AACzC,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAGxD,YAAY,EAAE,OAAO,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/connection",
3
- "version": "0.1.15",
3
+ "version": "0.2.0",
4
4
  "description": "ABAP connection layer for MCP ABAP ADT server",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,7 +43,7 @@
43
43
  "node": ">=18.0.0"
44
44
  },
45
45
  "dependencies": {
46
- "@mcp-abap-adt/interfaces": "^0.1.1",
46
+ "@mcp-abap-adt/interfaces": "^0.1.4",
47
47
  "axios": "^1.11.0",
48
48
  "commander": "^14.0.2",
49
49
  "express": "^5.1.0",
@@ -1,73 +0,0 @@
1
- /**
2
- * File-based session storage implementation
3
- * Stores session state (cookies, CSRF tokens) in JSON files on disk
4
- */
5
- import { ISessionStorage, SessionState } from '../logger.js';
6
- export interface FileSessionStorageOptions {
7
- /**
8
- * Directory to store session files
9
- * @default '.sessions'
10
- */
11
- sessionDir?: string;
12
- /**
13
- * Whether to create session directory if it doesn't exist
14
- * @default true
15
- */
16
- createDir?: boolean;
17
- /**
18
- * Pretty-print JSON files (for debugging)
19
- * @default false
20
- */
21
- prettyPrint?: boolean;
22
- }
23
- /**
24
- * File-based session storage
25
- * Stores each session in a separate JSON file: .sessions/<sessionId>.json
26
- */
27
- export declare class FileSessionStorage implements ISessionStorage {
28
- private readonly sessionDir;
29
- private readonly prettyPrint;
30
- constructor(options?: FileSessionStorageOptions);
31
- /**
32
- * Get file path for session
33
- */
34
- private getSessionFilePath;
35
- /**
36
- * Save session state to file
37
- */
38
- save(sessionId: string, state: SessionState): Promise<void>;
39
- /**
40
- * Load session state from file
41
- */
42
- load(sessionId: string): Promise<SessionState | null>;
43
- /**
44
- * Delete session state file
45
- */
46
- delete(sessionId: string): Promise<void>;
47
- /**
48
- * List all session IDs
49
- */
50
- listSessions(): Promise<string[]>;
51
- /**
52
- * Get session metadata (without loading full state)
53
- */
54
- getSessionMetadata(sessionId: string): Promise<{
55
- sessionId: string;
56
- timestamp: number;
57
- pid: number;
58
- age: number;
59
- } | null>;
60
- /**
61
- * Clean up stale sessions (older than maxAge)
62
- */
63
- cleanupStaleSessions(maxAgeMs?: number): Promise<string[]>;
64
- /**
65
- * Clean up sessions from dead processes
66
- */
67
- cleanupDeadProcessSessions(): Promise<string[]>;
68
- /**
69
- * Clear all sessions
70
- */
71
- clearAll(): Promise<void>;
72
- }
73
- //# sourceMappingURL=FileSessionStorage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileSessionStorage.d.ts","sourceRoot":"","sources":["../../src/utils/FileSessionStorage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE7D,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;gBAE1B,OAAO,GAAE,yBAA8B;IAenD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBjE;;OAEG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAiB3D;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAWvC;;OAEG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QACnD,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,GAAG,IAAI,CAAC;IAqBT;;OAEG;IACG,oBAAoB,CAAC,QAAQ,GAAE,MAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgBhF;;OAEG;IACG,0BAA0B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAqBrD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAMhC"}