@principal-ai/control-tower-core 0.1.4 → 0.1.5

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.
@@ -1,9 +1,12 @@
1
- import type { TokenPayload, AuthResult, Credentials } from '../types';
1
+ import type { TokenPayload, AuthResult, Credentials, CredentialType } from '../types';
2
2
  export interface IAuthAdapter {
3
- validateToken(token: string): Promise<TokenPayload>;
4
- generateToken(payload: TokenPayload): Promise<string>;
5
- refreshToken(token: string): Promise<string>;
6
- revokeToken(token: string): Promise<void>;
7
3
  authenticate(credentials: Credentials): Promise<AuthResult>;
4
+ validateToken(token: string): Promise<TokenPayload>;
5
+ generateToken?(payload: TokenPayload): Promise<string>;
6
+ refreshToken?(token: string): Promise<string>;
7
+ revokeToken?(token: string): Promise<void>;
8
+ isAuthRequired?(): boolean;
9
+ getAuthTimeout?(): number;
10
+ getSupportedCredentialTypes?(): CredentialType[];
8
11
  }
9
12
  //# sourceMappingURL=AuthAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthAdapter.d.ts","sourceRoot":"","sources":["../../src/abstractions/AuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACZ,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACpD,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7D"}
1
+ {"version":3,"file":"AuthAdapter.d.ts","sourceRoot":"","sources":["../../src/abstractions/AuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,YAAY;IAE3B,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAG5D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACpD,aAAa,CAAC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,YAAY,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,WAAW,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG3C,cAAc,CAAC,IAAI,OAAO,CAAC;IAC3B,cAAc,CAAC,IAAI,MAAM,CAAC;IAC1B,2BAA2B,CAAC,IAAI,cAAc,EAAE,CAAC;CAClD"}
@@ -1,4 +1,7 @@
1
1
  import type { ConnectionState, ConnectionOptions, Message, MessageHandler, ErrorHandler, CloseHandler } from '../types';
2
+ import type { Server as HttpServer } from 'http';
3
+ import type { Server as HttpsServer } from 'https';
4
+ import type { WebSocketServer } from 'ws';
2
5
  export interface ITransportAdapter {
3
6
  connect(url: string, options?: ConnectionOptions): Promise<void>;
4
7
  disconnect(): Promise<void>;
@@ -8,5 +11,7 @@ export interface ITransportAdapter {
8
11
  onClose(handler: CloseHandler): void;
9
12
  getState(): ConnectionState;
10
13
  isConnected(): boolean;
14
+ attach?(server: HttpServer | HttpsServer, path?: string): Promise<void>;
15
+ attachToWebSocketServer?(wss: WebSocketServer): Promise<void>;
11
16
  }
12
17
  //# sourceMappingURL=TransportAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TransportAdapter.d.ts","sourceRoot":"","sources":["../../src/abstractions/TransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACrC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACrC,QAAQ,IAAI,eAAe,CAAC;IAC5B,WAAW,IAAI,OAAO,CAAC;CACxB"}
1
+ {"version":3,"file":"TransportAdapter.d.ts","sourceRoot":"","sources":["../../src/abstractions/TransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAEhC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACrC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACrC,QAAQ,IAAI,eAAe,CAAC;IAC5B,WAAW,IAAI,OAAO,CAAC;IAGvB,MAAM,CAAC,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,uBAAuB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D"}
@@ -1,5 +1,5 @@
1
1
  import type { IAuthAdapter } from '../../abstractions/AuthAdapter';
2
- import type { TokenPayload, AuthResult, Credentials } from '../../types';
2
+ import type { TokenPayload, AuthResult, Credentials, CredentialType } from '../../types';
3
3
  export declare class MockAuthAdapter implements IAuthAdapter {
4
4
  private tokens;
5
5
  private revokedTokens;
@@ -16,6 +16,9 @@ export declare class MockAuthAdapter implements IAuthAdapter {
16
16
  refreshToken(token: string): Promise<string>;
17
17
  revokeToken(token: string): Promise<void>;
18
18
  authenticate(credentials: Credentials): Promise<AuthResult>;
19
+ isAuthRequired(): boolean;
20
+ getAuthTimeout(): number;
21
+ getSupportedCredentialTypes(): CredentialType[];
19
22
  private simulateDelay;
20
23
  addUser(username: string, password: string, payload: TokenPayload): void;
21
24
  removeUser(username: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"MockAuthAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockAuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,KAAK,CAAuE;IACpF,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,YAAY,CAAa;gBAErB,OAAO,CAAC,EAAE;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B;IAoBK,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAyBnD,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBrD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB5C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWzC,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;YAuEnD,aAAa;IAM3B,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAIxE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIlC,aAAa,IAAI,MAAM;IAIvB,oBAAoB,IAAI,MAAM;IAI9B,WAAW,IAAI,IAAI;IAKnB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CAGjC"}
1
+ {"version":3,"file":"MockAuthAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockAuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,KAAK,CAAuE;IACpF,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,YAAY,CAAa;gBAErB,OAAO,CAAC,EAAE;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B;IAoBK,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAyBnD,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBrD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB5C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWzC,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAwGjE,cAAc,IAAI,OAAO;IAIzB,cAAc,IAAI,MAAM;IAIxB,2BAA2B,IAAI,cAAc,EAAE;YAKjC,aAAa;IAM3B,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAIxE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIlC,aAAa,IAAI,MAAM;IAIvB,oBAAoB,IAAI,MAAM;IAI9B,WAAW,IAAI,IAAI;IAKnB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CAGjC"}
@@ -78,42 +78,71 @@ export class MockAuthAdapter {
78
78
  async authenticate(credentials) {
79
79
  await this.simulateDelay();
80
80
  if (this.shouldFailAuth) {
81
- throw new Error('Mock authentication failed');
81
+ return {
82
+ success: false,
83
+ error: 'Mock authentication failed'
84
+ };
82
85
  }
83
86
  switch (credentials.type) {
84
87
  case 'password': {
85
88
  if (!credentials.username || !credentials.password) {
86
- throw new Error('Username and password required');
89
+ return {
90
+ success: false,
91
+ error: 'Username and password required'
92
+ };
87
93
  }
88
94
  const user = this.users.get(credentials.username);
89
95
  if (!user || user.password !== credentials.password) {
90
- throw new Error('Invalid credentials');
96
+ return {
97
+ success: false,
98
+ error: 'Invalid credentials'
99
+ };
91
100
  }
92
101
  const token = await this.generateToken(user.payload);
93
102
  const refreshToken = `refresh-${token}`;
94
103
  this.tokens.set(refreshToken, user.payload);
95
104
  return {
105
+ success: true,
96
106
  token,
97
107
  refreshToken,
98
108
  user: user.payload,
109
+ userId: user.payload.userId,
99
110
  expiresIn: 3600
100
111
  };
101
112
  }
102
- case 'token': {
113
+ case 'token':
114
+ case 'jwt':
115
+ case 'bearer': {
103
116
  if (!credentials.token) {
104
- throw new Error('Token required');
117
+ return {
118
+ success: false,
119
+ error: 'Token required'
120
+ };
121
+ }
122
+ try {
123
+ const payload = await this.validateToken(credentials.token);
124
+ return {
125
+ success: true,
126
+ token: credentials.token,
127
+ user: payload,
128
+ userId: payload.userId,
129
+ expiresIn: 3600
130
+ };
131
+ }
132
+ catch (error) {
133
+ return {
134
+ success: false,
135
+ error: error.message
136
+ };
105
137
  }
106
- const payload = await this.validateToken(credentials.token);
107
- return {
108
- token: credentials.token,
109
- user: payload,
110
- expiresIn: 3600
111
- };
112
138
  }
113
139
  case 'oauth': {
114
140
  // Simulate OAuth flow
115
141
  if (!credentials.code) {
116
- throw new Error('OAuth code required');
142
+ return {
143
+ success: false,
144
+ error: 'OAuth code required'
145
+ };
117
146
  }
118
147
  // Create a mock OAuth user
119
148
  const payload = {
@@ -124,15 +153,30 @@ export class MockAuthAdapter {
124
153
  };
125
154
  const token = await this.generateToken(payload);
126
155
  return {
156
+ success: true,
127
157
  token,
128
158
  user: payload,
159
+ userId: payload.userId,
129
160
  expiresIn: 3600
130
161
  };
131
162
  }
132
163
  default:
133
- throw new Error('Unsupported credential type');
164
+ return {
165
+ success: false,
166
+ error: 'Unsupported credential type'
167
+ };
134
168
  }
135
169
  }
170
+ // New methods for enhanced auth interface
171
+ isAuthRequired() {
172
+ return false; // Mock adapter doesn't require auth by default
173
+ }
174
+ getAuthTimeout() {
175
+ return 10000; // 10 seconds for testing
176
+ }
177
+ getSupportedCredentialTypes() {
178
+ return ['password', 'token', 'jwt', 'bearer', 'oauth'];
179
+ }
136
180
  // Test helper methods
137
181
  async simulateDelay() {
138
182
  if (this.simulateLatency > 0) {
@@ -0,0 +1,60 @@
1
+ import type { ITransportAdapter } from '../../abstractions/TransportAdapter';
2
+ import type { IAuthAdapter } from '../../abstractions/AuthAdapter';
3
+ import type { ConnectionState, ConnectionOptions, Message, MessageHandler, ErrorHandler, CloseHandler } from '../../types';
4
+ import type { Server as HttpServer } from 'http';
5
+ import type { Server as HttpsServer } from 'https';
6
+ import { WebSocketServer, WebSocket } from 'ws';
7
+ interface ClientConnection {
8
+ id: string;
9
+ ws: WebSocket;
10
+ userId?: string;
11
+ authenticated: boolean;
12
+ metadata?: Record<string, unknown>;
13
+ authTimeout?: NodeJS.Timeout;
14
+ connectedAt: number;
15
+ }
16
+ export interface WebSocketTransportConfig {
17
+ authTimeout?: number;
18
+ closeOnAuthFailure?: boolean;
19
+ requireAuth?: boolean;
20
+ }
21
+ export declare class WebSocketTransportAdapter implements ITransportAdapter {
22
+ private state;
23
+ private messageHandlers;
24
+ private errorHandlers;
25
+ private closeHandlers;
26
+ private wss?;
27
+ private serverUrl?;
28
+ private attachedServer?;
29
+ private attachedWss?;
30
+ private webSocketPath?;
31
+ private clients;
32
+ private mode;
33
+ private authAdapter?;
34
+ private config;
35
+ constructor(config?: WebSocketTransportConfig);
36
+ setAuthAdapter(auth: IAuthAdapter): void;
37
+ connect(url: string, _options?: ConnectionOptions): Promise<void>;
38
+ attach(server: HttpServer | HttpsServer, path?: string): Promise<void>;
39
+ attachToWebSocketServer(wss: WebSocketServer): Promise<void>;
40
+ private handleConnection;
41
+ private handleClientMessage;
42
+ private handleAuthMessage;
43
+ private extractBearerToken;
44
+ private sendToClient;
45
+ disconnect(): Promise<void>;
46
+ send(message: Message): Promise<void>;
47
+ onMessage(handler: MessageHandler): void;
48
+ onError(handler: ErrorHandler): void;
49
+ onClose(handler: CloseHandler): void;
50
+ getState(): ConnectionState;
51
+ isConnected(): boolean;
52
+ getConnectedClients(): ClientConnection[];
53
+ getAuthenticatedClients(): ClientConnection[];
54
+ getClientCount(): number;
55
+ getMode(): 'standalone' | 'integration';
56
+ isAuthRequired(): boolean;
57
+ private generateId;
58
+ }
59
+ export {};
60
+ //# sourceMappingURL=WebSocketTransportAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EAGb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEhD,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,yBAA0B,YAAW,iBAAiB;IACjE,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IAGrD,OAAO,CAAC,GAAG,CAAC,CAAkB;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAS;IAG3B,OAAO,CAAC,cAAc,CAAC,CAA2B;IAClD,OAAO,CAAC,WAAW,CAAC,CAAkB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAS;IAG/B,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,IAAI,CAA8C;IAG1D,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,CAAC,EAAE,wBAAwB;IAU7C,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAYlC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCjE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,GAAE,MAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC7E,uBAAuB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BpD,gBAAgB;YA6EhB,mBAAmB;YAuCnB,iBAAiB;IA4E/B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,YAAY;IAMd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B3C,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,QAAQ,IAAI,eAAe;IAI3B,WAAW,IAAI,OAAO;IAKtB,mBAAmB,IAAI,gBAAgB,EAAE;IAIzC,uBAAuB,IAAI,gBAAgB,EAAE;IAI7C,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,YAAY,GAAG,aAAa;IAIvC,cAAc,IAAI,OAAO;IAIzB,OAAO,CAAC,UAAU;CAGnB"}
@@ -0,0 +1,380 @@
1
+ import { WebSocketServer, WebSocket } from 'ws';
2
+ export class WebSocketTransportAdapter {
3
+ constructor(config) {
4
+ this.state = 'disconnected';
5
+ this.messageHandlers = new Set();
6
+ this.errorHandlers = new Set();
7
+ this.closeHandlers = new Set();
8
+ // Client management
9
+ this.clients = new Map();
10
+ this.mode = 'standalone';
11
+ this.config = {
12
+ authTimeout: config?.authTimeout ?? 5000,
13
+ closeOnAuthFailure: config?.closeOnAuthFailure ?? false,
14
+ requireAuth: config?.requireAuth ?? false,
15
+ ...config
16
+ };
17
+ }
18
+ // Set the auth adapter
19
+ setAuthAdapter(auth) {
20
+ this.authAdapter = auth;
21
+ // Update requireAuth based on auth adapter's preference
22
+ if (auth.isAuthRequired) {
23
+ this.config.requireAuth = auth.isAuthRequired();
24
+ }
25
+ if (auth.getAuthTimeout) {
26
+ this.config.authTimeout = auth.getAuthTimeout();
27
+ }
28
+ }
29
+ // Standalone mode implementation
30
+ async connect(url, _options) {
31
+ if (this.state === 'connected' || this.state === 'connecting') {
32
+ throw new Error('Already connected or connecting');
33
+ }
34
+ this.state = 'connecting';
35
+ this.serverUrl = url;
36
+ this.mode = 'standalone';
37
+ try {
38
+ // Extract port from URL
39
+ const urlObj = new URL(url);
40
+ const port = parseInt(urlObj.port) || (urlObj.protocol === 'wss:' ? 443 : 80);
41
+ // Create WebSocket server
42
+ this.wss = new WebSocketServer({ port });
43
+ this.wss.on('connection', (ws, req) => {
44
+ this.handleConnection(ws, req);
45
+ });
46
+ this.wss.on('error', (error) => {
47
+ this.errorHandlers.forEach(handler => handler(error));
48
+ });
49
+ this.wss.on('close', () => {
50
+ this.state = 'disconnected';
51
+ this.closeHandlers.forEach(handler => handler(1000, 'Server closed'));
52
+ });
53
+ this.state = 'connected';
54
+ }
55
+ catch (error) {
56
+ this.state = 'disconnected';
57
+ throw error;
58
+ }
59
+ }
60
+ // Integration mode implementation
61
+ async attach(server, path = '/ws') {
62
+ if (this.state === 'connected' || this.state === 'connecting') {
63
+ throw new Error('Already connected or connecting');
64
+ }
65
+ this.state = 'connecting';
66
+ this.attachedServer = server;
67
+ this.webSocketPath = path;
68
+ this.mode = 'integration';
69
+ try {
70
+ // Create WebSocket server attached to the existing HTTP server
71
+ this.wss = new WebSocketServer({
72
+ server,
73
+ path,
74
+ perMessageDeflate: false
75
+ });
76
+ this.wss.on('connection', (ws, req) => {
77
+ this.handleConnection(ws, req);
78
+ });
79
+ this.wss.on('error', (error) => {
80
+ this.errorHandlers.forEach(handler => handler(error));
81
+ });
82
+ this.state = 'connected';
83
+ }
84
+ catch (error) {
85
+ this.state = 'disconnected';
86
+ throw error;
87
+ }
88
+ }
89
+ async attachToWebSocketServer(wss) {
90
+ if (this.state === 'connected' || this.state === 'connecting') {
91
+ throw new Error('Already connected or connecting');
92
+ }
93
+ this.state = 'connecting';
94
+ this.attachedWss = wss;
95
+ this.mode = 'integration';
96
+ try {
97
+ this.wss = wss;
98
+ this.wss.on('connection', (ws, req) => {
99
+ this.handleConnection(ws, req);
100
+ });
101
+ this.wss.on('error', (error) => {
102
+ this.errorHandlers.forEach(handler => handler(error));
103
+ });
104
+ this.state = 'connected';
105
+ }
106
+ catch (error) {
107
+ this.state = 'disconnected';
108
+ throw error;
109
+ }
110
+ }
111
+ async handleConnection(ws, req) {
112
+ const clientId = this.generateId();
113
+ // Step 1: Try header authentication if auth adapter is available
114
+ let authenticated = false;
115
+ let authResult = null;
116
+ if (this.authAdapter && req.headers.authorization) {
117
+ const token = this.extractBearerToken(req.headers.authorization);
118
+ if (token) {
119
+ try {
120
+ authResult = await this.authAdapter.authenticate({
121
+ type: 'bearer',
122
+ token: token
123
+ });
124
+ authenticated = authResult.success;
125
+ }
126
+ catch {
127
+ // Header auth failed but don't reject connection
128
+ }
129
+ }
130
+ }
131
+ // Step 2: Create client with auth state
132
+ const client = {
133
+ id: clientId,
134
+ ws,
135
+ authenticated,
136
+ userId: authResult?.userId || (authResult?.user?.userId),
137
+ metadata: authResult?.metadata || authResult?.user?.metadata,
138
+ connectedAt: Date.now()
139
+ };
140
+ this.clients.set(clientId, client);
141
+ // Step 3: Set up message handling
142
+ ws.on('message', (data) => {
143
+ this.handleClientMessage(clientId, data);
144
+ });
145
+ ws.on('error', (error) => {
146
+ this.errorHandlers.forEach(handler => handler(error));
147
+ });
148
+ ws.on('close', (_code, _reason) => {
149
+ // Clear auth timeout if exists
150
+ if (client.authTimeout) {
151
+ clearTimeout(client.authTimeout);
152
+ }
153
+ this.clients.delete(clientId);
154
+ });
155
+ // Step 4: Set auth timeout if not authenticated and auth is required
156
+ if (!authenticated && this.config.requireAuth && this.authAdapter) {
157
+ client.authTimeout = setTimeout(() => {
158
+ if (!client.authenticated) {
159
+ ws.close(1008, 'Authentication timeout');
160
+ this.clients.delete(clientId);
161
+ }
162
+ }, this.config.authTimeout);
163
+ }
164
+ // Step 5: Notify about connection (with auth status)
165
+ const connectionMessage = {
166
+ id: this.generateId(),
167
+ type: 'connection',
168
+ payload: {
169
+ clientId,
170
+ authenticated,
171
+ userId: client.userId,
172
+ metadata: client.metadata
173
+ },
174
+ timestamp: Date.now()
175
+ };
176
+ this.messageHandlers.forEach(handler => handler(connectionMessage));
177
+ }
178
+ async handleClientMessage(clientId, data) {
179
+ const client = this.clients.get(clientId);
180
+ if (!client)
181
+ return;
182
+ try {
183
+ const message = JSON.parse(data.toString());
184
+ // Special handling for authentication messages
185
+ if (message.type === 'authenticate' && !client.authenticated && this.authAdapter) {
186
+ await this.handleAuthMessage(client, message);
187
+ return;
188
+ }
189
+ // Reject messages from unauthenticated clients if auth is required
190
+ if (this.config.requireAuth && !client.authenticated) {
191
+ this.sendToClient(client, {
192
+ id: this.generateId(),
193
+ type: 'error',
194
+ payload: { error: 'Authentication required' },
195
+ timestamp: Date.now()
196
+ });
197
+ return;
198
+ }
199
+ // Add clientId to message payload for routing
200
+ const enrichedMessage = {
201
+ ...message,
202
+ payload: {
203
+ ...message.payload,
204
+ clientId
205
+ }
206
+ };
207
+ this.messageHandlers.forEach(handler => handler(enrichedMessage));
208
+ }
209
+ catch (error) {
210
+ this.errorHandlers.forEach(handler => handler(error));
211
+ }
212
+ }
213
+ async handleAuthMessage(client, message) {
214
+ if (!this.authAdapter) {
215
+ this.sendToClient(client, {
216
+ id: this.generateId(),
217
+ type: 'auth_error',
218
+ payload: { error: 'No auth adapter configured' },
219
+ timestamp: Date.now()
220
+ });
221
+ return;
222
+ }
223
+ try {
224
+ const credentials = message.payload;
225
+ const result = await this.authAdapter.authenticate(credentials);
226
+ if (result.success) {
227
+ // Clear auth timeout
228
+ if (client.authTimeout) {
229
+ clearTimeout(client.authTimeout);
230
+ client.authTimeout = undefined;
231
+ }
232
+ // Update client state
233
+ client.authenticated = true;
234
+ client.userId = result.userId || result.user?.userId;
235
+ client.metadata = result.metadata || result.user?.metadata;
236
+ // Send success response
237
+ this.sendToClient(client, {
238
+ id: this.generateId(),
239
+ type: 'auth_success',
240
+ payload: {
241
+ userId: client.userId,
242
+ metadata: client.metadata
243
+ },
244
+ timestamp: Date.now()
245
+ });
246
+ // Notify handlers about authentication
247
+ const authMessage = {
248
+ id: this.generateId(),
249
+ type: 'client_authenticated',
250
+ payload: {
251
+ clientId: client.id,
252
+ userId: client.userId,
253
+ metadata: client.metadata
254
+ },
255
+ timestamp: Date.now()
256
+ };
257
+ this.messageHandlers.forEach(handler => handler(authMessage));
258
+ }
259
+ else {
260
+ // Send error response
261
+ this.sendToClient(client, {
262
+ id: this.generateId(),
263
+ type: 'auth_error',
264
+ payload: { error: result.error || 'Authentication failed' },
265
+ timestamp: Date.now()
266
+ });
267
+ // Optionally close connection
268
+ if (this.config.closeOnAuthFailure) {
269
+ client.ws.close(1008, 'Authentication failed');
270
+ this.clients.delete(client.id);
271
+ }
272
+ }
273
+ }
274
+ catch (error) {
275
+ this.sendToClient(client, {
276
+ id: this.generateId(),
277
+ type: 'auth_error',
278
+ payload: { error: error.message },
279
+ timestamp: Date.now()
280
+ });
281
+ }
282
+ }
283
+ extractBearerToken(authHeader) {
284
+ if (authHeader.startsWith('Bearer ')) {
285
+ return authHeader.substring(7);
286
+ }
287
+ return null;
288
+ }
289
+ sendToClient(client, message) {
290
+ if (client.ws.readyState === WebSocket.OPEN) {
291
+ client.ws.send(JSON.stringify(message));
292
+ }
293
+ }
294
+ async disconnect() {
295
+ if (this.state === 'disconnected') {
296
+ return;
297
+ }
298
+ this.state = 'disconnecting';
299
+ // Close all client connections
300
+ for (const [_clientId, client] of this.clients) {
301
+ try {
302
+ if (client.authTimeout) {
303
+ clearTimeout(client.authTimeout);
304
+ }
305
+ client.ws.close(1000, 'Server shutting down');
306
+ }
307
+ catch {
308
+ // Ignore errors when closing individual connections
309
+ }
310
+ }
311
+ this.clients.clear();
312
+ // Close the WebSocket server (only if we created it)
313
+ if (this.wss && this.mode === 'standalone') {
314
+ await new Promise((resolve) => {
315
+ this.wss.close(() => resolve());
316
+ });
317
+ }
318
+ this.state = 'disconnected';
319
+ this.wss = undefined;
320
+ this.attachedServer = undefined;
321
+ this.attachedWss = undefined;
322
+ }
323
+ async send(message) {
324
+ if (this.state !== 'connected') {
325
+ throw new Error('Not connected');
326
+ }
327
+ // Extract clientId from message payload for routing
328
+ const payload = message.payload;
329
+ const { clientId, ...clientMessage } = payload;
330
+ if (!clientId) {
331
+ throw new Error('Message must contain clientId in payload for routing');
332
+ }
333
+ const client = this.clients.get(clientId);
334
+ if (!client) {
335
+ throw new Error(`Client ${clientId} not found`);
336
+ }
337
+ if (client.ws.readyState !== WebSocket.OPEN) {
338
+ throw new Error(`Client ${clientId} connection is not open`);
339
+ }
340
+ const messageToSend = {
341
+ ...message,
342
+ payload: clientMessage
343
+ };
344
+ client.ws.send(JSON.stringify(messageToSend));
345
+ }
346
+ onMessage(handler) {
347
+ this.messageHandlers.add(handler);
348
+ }
349
+ onError(handler) {
350
+ this.errorHandlers.add(handler);
351
+ }
352
+ onClose(handler) {
353
+ this.closeHandlers.add(handler);
354
+ }
355
+ getState() {
356
+ return this.state;
357
+ }
358
+ isConnected() {
359
+ return this.state === 'connected';
360
+ }
361
+ // Utility methods
362
+ getConnectedClients() {
363
+ return Array.from(this.clients.values());
364
+ }
365
+ getAuthenticatedClients() {
366
+ return Array.from(this.clients.values()).filter(c => c.authenticated);
367
+ }
368
+ getClientCount() {
369
+ return this.clients.size;
370
+ }
371
+ getMode() {
372
+ return this.mode;
373
+ }
374
+ isAuthRequired() {
375
+ return this.config.requireAuth ?? false;
376
+ }
377
+ generateId() {
378
+ return Math.random().toString(36).substring(2) + Date.now().toString(36);
379
+ }
380
+ }
@@ -0,0 +1,2 @@
1
+ export { WebSocketTransportAdapter, type WebSocketTransportConfig } from './WebSocketTransportAdapter';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,KAAK,wBAAwB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1 @@
1
+ export { WebSocketTransportAdapter } from './WebSocketTransportAdapter';
@@ -1 +1 @@
1
- {"version":3,"file":"BaseClient.d.ts","sourceRoot":"","sources":["../../src/client/BaseClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseClient.d.ts","sourceRoot":"","sources":["../../src/client/BaseClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAGf,KAAK,EACL,SAAS,EACT,QAAQ,EACR,WAAW,EACX,IAAI,EACJ,WAAW,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,YAAY,CAAC,EAAE;QACb,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7B,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IACxB,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IAClD,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,cAAc,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IACjC,aAAa,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;IAC9B,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,WAAW,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,gBAAgB,EAAE;QAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;KAAE,CAAC;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,qBAAa,UAAW,SAAQ,iBAAiB,CAAC,YAAY,CAAC;IAC7D,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,IAAI,CAAC,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAC,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAe;IAE7B,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,MAAM,CAAuB;IAGrC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,eAAe,CAA4B;gBAEvC,MAAM,EAAE,YAAY;IAc1B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC9D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC3B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAa1B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBvC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB1B,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBtC,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAehD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhD,kBAAkB,IAAI,eAAe;IAIrC,YAAY,IAAI,SAAS,GAAG,IAAI;IAIhC,WAAW,IAAI,QAAQ,EAAE;IAIzB,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,SAAS,IAAI,MAAM,GAAG,IAAI;YAKZ,aAAa;YAkCb,WAAW;YAIX,WAAW;YAcX,gBAAgB;YAMhB,cAAc;YAQd,oBAAoB;YAIpB,kBAAkB;YAIlB,kBAAkB;YAIlB,gBAAgB;YAIhB,qBAAqB;YAQrB,iBAAiB;YAKjB,iBAAiB;IA0B/B,OAAO,CAAC,UAAU;CAGnB"}