@mcp-abap-adt/connection 0.1.13 → 0.1.15

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
@@ -46,6 +46,58 @@ The package uses a clean separation of concerns:
46
46
  - Permission vs auth error detection
47
47
  - Suitable for SAP BTP ABAP Environment
48
48
 
49
+ ## Responsibilities and Design Principles
50
+
51
+ ### Core Development Principle
52
+
53
+ **Interface-Only Communication**: This package follows a fundamental development principle: **all interactions with external dependencies happen ONLY through interfaces**. The code knows **NOTHING beyond what is defined in the interfaces**.
54
+
55
+ This means:
56
+ - Does not know about concrete implementation classes from other packages
57
+ - Does not know about internal data structures or methods not defined in interfaces
58
+ - Does not make assumptions about implementation behavior beyond interface contracts
59
+ - Does not access properties or methods not explicitly defined in interfaces
60
+
61
+ This principle ensures:
62
+ - **Loose coupling**: Connection classes are decoupled from concrete implementations in other packages
63
+ - **Flexibility**: New implementations can be added without modifying connection classes
64
+ - **Testability**: Easy to mock dependencies for testing
65
+ - **Maintainability**: Changes to implementations don't affect connection classes
66
+
67
+ ### Package Responsibilities
68
+
69
+ This package is responsible for:
70
+
71
+ 1. **HTTP communication with SAP systems**: Makes HTTP requests to SAP ABAP systems via ADT protocol
72
+ 2. **Authentication handling**: Supports Basic Auth and JWT/OAuth2 authentication methods
73
+ 3. **Session management**: Manages cookies, CSRF tokens, and session state
74
+ 4. **Token refresh**: Automatically refreshes expired JWT tokens (for `JwtAbapConnection`)
75
+ 5. **Error handling**: Distinguishes between authentication errors and permission errors
76
+
77
+ #### What This Package Does
78
+
79
+ - **Provides connection abstraction**: `AbapConnection` interface for interacting with SAP systems
80
+ - **Handles HTTP requests**: Makes requests to SAP ADT endpoints with proper headers and authentication
81
+ - **Manages sessions**: Handles cookies, CSRF tokens, and session state persistence
82
+ - **Refreshes tokens**: Automatically refreshes expired JWT tokens when detected
83
+ - **Validates tokens**: Detects expired tokens by analyzing HTTP response codes (401/403)
84
+
85
+ #### What This Package Does NOT Do
86
+
87
+ - **Does NOT obtain tokens**: Token acquisition is handled by `@mcp-abap-adt/auth-providers` and `@mcp-abap-adt/auth-broker`
88
+ - **Does NOT store tokens**: Token storage is handled by `@mcp-abap-adt/auth-stores`
89
+ - **Does NOT orchestrate authentication**: Token lifecycle management is handled by `@mcp-abap-adt/auth-broker`
90
+ - **Does NOT know about destinations**: Destination-based authentication is handled by consumers
91
+ - **Does NOT handle OAuth2 flows**: OAuth2 flows are handled by token providers
92
+
93
+ ### External Dependencies
94
+
95
+ This package interacts with external packages **ONLY through interfaces**:
96
+
97
+ - **Logger interface**: Uses `ILogger` interface for logging - does not know about concrete logger implementation
98
+ - **Session storage interface**: Uses `ISessionStorage` interface for session persistence - does not know about concrete storage implementation
99
+ - **No direct dependencies on auth packages**: All token-related operations are handled through configuration (`SapConfig`) passed by consumers
100
+
49
101
  ## Documentation
50
102
 
51
103
  - 📦 **[Installation Guide](./docs/INSTALLATION.md)** - Setup and installation instructions
@@ -1,15 +1,5 @@
1
- export type SapAuthType = "basic" | "jwt";
2
- export interface SapConfig {
3
- url: string;
4
- client?: string;
5
- authType: SapAuthType;
6
- username?: string;
7
- password?: string;
8
- jwtToken?: string;
9
- refreshToken?: string;
10
- uaaUrl?: string;
11
- uaaClientId?: string;
12
- uaaClientSecret?: string;
13
- }
14
- export declare function sapConfigSignature(config: SapConfig): string;
1
+ import type { ISapConfig, SapAuthType } from '@mcp-abap-adt/interfaces';
2
+ export type { SapAuthType };
3
+ export type SapConfig = ISapConfig;
4
+ export declare function sapConfigSignature(config: ISapConfig): string;
15
5
  //# sourceMappingURL=sapConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sapConfig.d.ts","sourceRoot":"","sources":["../../src/config/sapConfig.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAmB5D"}
1
+ {"version":3,"file":"sapConfig.d.ts","sourceRoot":"","sources":["../../src/config/sapConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGxE,YAAY,EAAE,WAAW,EAAE,CAAC;AAC5B,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC;AAEnC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAmB7D"}
@@ -1,24 +1,4 @@
1
- import { AxiosResponse } from "axios";
2
- import { SapConfig } from "../config/sapConfig.js";
3
- import { SessionState } from "../logger.js";
4
- export interface AbapRequestOptions {
5
- url: string;
6
- method: string;
7
- timeout: number;
8
- data?: any;
9
- params?: any;
10
- headers?: Record<string, string>;
11
- }
12
- export interface AbapConnection {
13
- getConfig(): SapConfig;
14
- getBaseUrl(): Promise<string>;
15
- getAuthHeaders(): Promise<Record<string, string>>;
16
- getSessionId(): string | null;
17
- setSessionType(type: "stateful" | "stateless"): void;
18
- makeAdtRequest(options: AbapRequestOptions): Promise<AxiosResponse>;
19
- connect(): Promise<void>;
20
- reset(): void;
21
- getSessionState(): SessionState | null;
22
- setSessionState(state: SessionState): void;
23
- }
1
+ import type { IAbapRequestOptions, IAbapConnection } from '@mcp-abap-adt/interfaces';
2
+ export type AbapRequestOptions = IAbapRequestOptions;
3
+ export type AbapConnection = IAbapConnection;
24
4
  //# sourceMappingURL=AbapConnection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/AbapConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,IAAI,SAAS,CAAC;IACvB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC;IACrD,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACpE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,eAAe,IAAI,YAAY,GAAG,IAAI,CAAC;IACvC,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5C"}
1
+ {"version":3,"file":"AbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/AbapConnection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGrF,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AACrD,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/AbstractAbapConnection.ts"],"names":[],"mappings":"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"}
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,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,uBAAe,sBAAuB,YAAW,cAAc;IAW3D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;IAXpC,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,cAAc,CAAgC;IACtD,OAAO,CAAC,WAAW,CAAyC;IAE5D,SAAS,aACU,MAAM,EAAE,SAAS,EACf,MAAM,EAAE,OAAO,EAClC,cAAc,CAAC,EAAE,eAAe,EAChC,SAAS,CAAC,EAAE,MAAM;IAmBpB;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAQpD;;;;;OAKG;IACH,qBAAqB,IAAI,IAAI;IAI7B;;;;OAIG;IACG,sBAAsB,CAAC,iBAAiB,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB/E;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,UAAU;IAI1C;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IASrC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B;;;OAGG;IACG,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvE;;OAEG;IACH,iBAAiB,IAAI,eAAe,GAAG,IAAI;IAI3C;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBvC;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBvC;;;;OAIG;IACH,eAAe,IAAI,YAAY,GAAG,IAAI;IAYtC;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAY1C;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBxC,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;IAmNzE,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;IAoKlB;;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"}
@@ -404,12 +404,10 @@ class AbstractAbapConnection {
404
404
  }
405
405
  // Retry logic for CSRF token errors (403 with CSRF message)
406
406
  if (this.shouldRetryCsrf(error)) {
407
- if (this.logger.csrfToken) {
408
- this.logger.csrfToken("retry", "CSRF token validation failed, fetching new token and retrying request", {
409
- url: requestUrl,
410
- method: normalizedMethod
411
- });
412
- }
407
+ this.logger.debug("CSRF token validation failed, fetching new token and retrying request", {
408
+ url: requestUrl,
409
+ method: normalizedMethod
410
+ });
413
411
  this.csrfToken = await this.fetchCsrfToken(requestUrl, 5, 2000);
414
412
  if (this.csrfToken) {
415
413
  requestHeaders["x-csrf-token"] = this.csrfToken;
@@ -478,13 +476,11 @@ class AbstractAbapConnection {
478
476
  csrfUrl = `${base}${csrfConfig_js_1.CSRF_CONFIG.ENDPOINT}`;
479
477
  }
480
478
  // If URL already contains the endpoint, use it as is
481
- if (this.logger.csrfToken) {
482
- this.logger.csrfToken("fetch", `Fetching CSRF token from: ${csrfUrl}`);
483
- }
479
+ this.logger.debug(`Fetching CSRF token from: ${csrfUrl}`);
484
480
  for (let attempt = 0; attempt <= retryCount; attempt++) {
485
481
  try {
486
- if (attempt > 0 && this.logger.csrfToken) {
487
- this.logger.csrfToken("retry", `Retry attempt ${attempt}/${retryCount} for CSRF token`);
482
+ if (attempt > 0) {
483
+ this.logger.debug(`Retry attempt ${attempt}/${retryCount} for CSRF token`);
488
484
  }
489
485
  const authHeaders = await this.getAuthHeaders();
490
486
  const headers = {
@@ -511,12 +507,10 @@ class AbstractAbapConnection {
511
507
  this.updateCookiesFromResponse(response.headers);
512
508
  const token = response.headers["x-csrf-token"];
513
509
  if (!token) {
514
- if (this.logger.csrfToken) {
515
- this.logger.csrfToken("error", "No CSRF token in response headers", {
516
- headers: response.headers,
517
- status: response.status
518
- });
519
- }
510
+ this.logger.error("No CSRF token in response headers", {
511
+ headers: response.headers,
512
+ status: response.status
513
+ });
520
514
  if (attempt < retryCount) {
521
515
  await new Promise((resolve) => setTimeout(resolve, retryDelay));
522
516
  continue;
@@ -527,18 +521,14 @@ class AbstractAbapConnection {
527
521
  this.updateCookiesFromResponse(response.headers);
528
522
  if (this.cookies) {
529
523
  this.logger.debug(`[DEBUG] BaseAbapConnection - Cookies received from CSRF response (first 100 chars): ${this.cookies.substring(0, 100)}...`);
530
- if (this.logger.csrfToken) {
531
- this.logger.csrfToken("success", "Cookies extracted from response", {
532
- cookieLength: this.cookies.length
533
- });
534
- }
524
+ this.logger.debug("Cookies extracted from response", {
525
+ cookieLength: this.cookies.length
526
+ });
535
527
  }
536
528
  }
537
529
  // Save session state after CSRF token fetch (cookies and token are now available)
538
530
  await this.saveSessionState();
539
- if (this.logger.csrfToken) {
540
- this.logger.csrfToken("success", "CSRF token successfully obtained");
541
- }
531
+ this.logger.debug("CSRF token successfully obtained");
542
532
  return token;
543
533
  }
544
534
  catch (error) {
@@ -554,18 +544,14 @@ class AbstractAbapConnection {
554
544
  });
555
545
  }
556
546
  }
557
- if (this.logger.csrfToken) {
558
- this.logger.csrfToken("error", `CSRF token error: ${error.message}`, {
559
- url: csrfUrl,
560
- status: error.response?.status,
561
- attempt: attempt + 1,
562
- maxAttempts: retryCount + 1
563
- });
564
- }
547
+ this.logger.error(`CSRF token error: ${error.message}`, {
548
+ url: csrfUrl,
549
+ status: error.response?.status,
550
+ attempt: attempt + 1,
551
+ maxAttempts: retryCount + 1
552
+ });
565
553
  if (error.response?.status === 405 && error.response?.headers["x-csrf-token"]) {
566
- if (this.logger.csrfToken) {
567
- this.logger.csrfToken("retry", "CSRF: SAP returned 405 (Method Not Allowed) — not critical, token found in header");
568
- }
554
+ this.logger.debug("CSRF: SAP returned 405 (Method Not Allowed) — not critical, token found in header");
569
555
  const token = error.response.headers["x-csrf-token"];
570
556
  if (token) {
571
557
  this.updateCookiesFromResponse(error.response.headers);
@@ -573,15 +559,13 @@ class AbstractAbapConnection {
573
559
  }
574
560
  }
575
561
  if (error.response?.headers["x-csrf-token"]) {
576
- if (this.logger.csrfToken) {
577
- this.logger.csrfToken("success", `Got CSRF token despite error (status: ${error.response?.status})`);
578
- }
562
+ this.logger.debug(`Got CSRF token despite error (status: ${error.response?.status})`);
579
563
  const token = error.response.headers["x-csrf-token"];
580
564
  this.updateCookiesFromResponse(error.response.headers);
581
565
  return token;
582
566
  }
583
- if (error.response && this.logger.csrfToken) {
584
- this.logger.csrfToken("error", "CSRF error details", {
567
+ if (error.response) {
568
+ this.logger.error("CSRF error details", {
585
569
  status: error.response.status,
586
570
  statusText: error.response.statusText,
587
571
  headers: Object.keys(error.response.headers),
@@ -590,14 +574,14 @@ class AbstractAbapConnection {
590
574
  : JSON.stringify(error.response.data).slice(0, 200)
591
575
  });
592
576
  }
593
- else if (error.request && this.logger.csrfToken) {
594
- this.logger.csrfToken("error", "CSRF request error - no response received", {
577
+ else if (error.request) {
578
+ this.logger.error("CSRF request error - no response received", {
595
579
  request: error.request.path
596
580
  });
597
581
  }
598
582
  }
599
- else if (this.logger.csrfToken) {
600
- this.logger.csrfToken("error", "CSRF non-axios error", {
583
+ else {
584
+ this.logger.error("CSRF non-axios error", {
601
585
  error: error instanceof Error ? error.message : String(error)
602
586
  });
603
587
  }
@@ -678,9 +662,7 @@ class AbstractAbapConnection {
678
662
  const rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED === "1" ||
679
663
  (process.env.TLS_REJECT_UNAUTHORIZED === "1" &&
680
664
  process.env.NODE_TLS_REJECT_UNAUTHORIZED !== "0");
681
- if (this.logger.tlsConfig) {
682
- this.logger.tlsConfig(rejectUnauthorized);
683
- }
665
+ this.logger.debug(`TLS configuration: rejectUnauthorized=${rejectUnauthorized}`);
684
666
  this.axiosInstance = axios_1.default.create({
685
667
  httpsAgent: new https_1.Agent({
686
668
  rejectUnauthorized
package/dist/logger.d.ts CHANGED
@@ -1,67 +1,4 @@
1
- /**
2
- * Logger interface for connection layer
3
- * Allows connection layer to be independent of specific logger implementation
4
- */
5
- export interface ILogger {
6
- /**
7
- * Log informational message
8
- */
9
- info(message: string, meta?: any): void;
10
- /**
11
- * Log error message
12
- */
13
- error(message: string, meta?: any): void;
14
- /**
15
- * Log warning message
16
- */
17
- warn(message: string, meta?: any): void;
18
- /**
19
- * Log debug message
20
- */
21
- debug(message: string, meta?: any): void;
22
- /**
23
- * Log CSRF token operations
24
- * @param action - Type of CSRF operation: "fetch", "retry", "success", or "error"
25
- * @param message - Log message
26
- * @param meta - Additional metadata
27
- */
28
- csrfToken?(action: "fetch" | "retry" | "success" | "error", message: string, meta?: any): void;
29
- /**
30
- * Log TLS configuration
31
- * @param rejectUnauthorized - Whether TLS certificate validation is enabled
32
- */
33
- tlsConfig?(rejectUnauthorized: boolean): void;
34
- }
35
- /**
36
- * Session state interface for stateful connections
37
- * Contains cookies and CSRF token that need to be preserved across requests
38
- */
39
- export interface SessionState {
40
- cookies: string | null;
41
- csrfToken: string | null;
42
- cookieStore: Record<string, string>;
43
- }
44
- /**
45
- * Interface for storing and retrieving session state
46
- * Allows connection layer to persist session state (cookies, CSRF token) externally
47
- */
48
- export interface ISessionStorage {
49
- /**
50
- * Save session state for a given session ID
51
- * @param sessionId - Unique session identifier
52
- * @param state - Session state to save
53
- */
54
- save(sessionId: string, state: SessionState): Promise<void>;
55
- /**
56
- * Load session state for a given session ID
57
- * @param sessionId - Unique session identifier
58
- * @returns Session state or null if not found
59
- */
60
- load(sessionId: string): Promise<SessionState | null>;
61
- /**
62
- * Delete session state for a given session ID
63
- * @param sessionId - Unique session identifier
64
- */
65
- delete(sessionId: string): Promise<void>;
66
- }
1
+ import type { ILogger, ISessionStorage, ISessionState } from '@mcp-abap-adt/interfaces';
2
+ export type { ILogger, ISessionStorage };
3
+ export type SessionState = ISessionState;
67
4
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAExC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAEzC;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAExC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAEzC;;;;;OAKG;IACH,SAAS,CAAC,CACR,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,EAC/C,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,GAAG,GACT,IAAI,CAAC;IAER;;;OAGG;IACH,SAAS,CAAC,CAAC,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/C;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D;;;;OAIG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAEtD;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C"}
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,8 +1,5 @@
1
- export interface TimeoutConfig {
2
- default: number;
3
- csrf: number;
4
- long: number;
5
- }
6
- export declare function getTimeoutConfig(): TimeoutConfig;
1
+ import type { ITimeoutConfig } from '@mcp-abap-adt/interfaces';
2
+ export type TimeoutConfig = ITimeoutConfig;
3
+ export declare function getTimeoutConfig(): ITimeoutConfig;
7
4
  export declare function getTimeout(type?: "default" | "csrf" | "long" | number): number;
8
5
  //# sourceMappingURL=timeouts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeouts.d.ts","sourceRoot":"","sources":["../../src/utils/timeouts.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAUhD;AAED,wBAAgB,UAAU,CAAC,IAAI,GAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAkB,GAAG,MAAM,CAOzF"}
1
+ {"version":3,"file":"timeouts.d.ts","sourceRoot":"","sources":["../../src/utils/timeouts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAE3C,wBAAgB,gBAAgB,IAAI,cAAc,CAUjD;AAED,wBAAgB,UAAU,CAAC,IAAI,GAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAkB,GAAG,MAAM,CAOzF"}
@@ -1,10 +1,8 @@
1
1
  /**
2
2
  * Token refresh utilities for JWT authentication
3
3
  */
4
- export interface TokenRefreshResult {
5
- accessToken: string;
6
- refreshToken?: string;
7
- }
4
+ import type { ITokenRefreshResult } from '@mcp-abap-adt/interfaces';
5
+ export type TokenRefreshResult = ITokenRefreshResult;
8
6
  /**
9
7
  * Refreshes the access token using refresh token
10
8
  * @param refreshToken Refresh token
@@ -13,5 +11,5 @@ export interface TokenRefreshResult {
13
11
  * @param clientSecret UAA client secret
14
12
  * @returns Promise that resolves to new tokens
15
13
  */
16
- export declare function refreshJwtToken(refreshToken: string, uaaUrl: string, clientId: string, clientSecret: string): Promise<TokenRefreshResult>;
14
+ export declare function refreshJwtToken(refreshToken: string, uaaUrl: string, clientId: string, clientSecret: string): Promise<ITokenRefreshResult>;
17
15
  //# sourceMappingURL=tokenRefresh.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../../src/utils/tokenRefresh.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAqC7B"}
1
+ {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../../src/utils/tokenRefresh.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAErD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAqC9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/connection",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
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,6 +43,7 @@
43
43
  "node": ">=18.0.0"
44
44
  },
45
45
  "dependencies": {
46
+ "@mcp-abap-adt/interfaces": "^0.1.1",
46
47
  "axios": "^1.11.0",
47
48
  "commander": "^14.0.2",
48
49
  "express": "^5.1.0",