@principal-ai/control-tower-core 0.1.21 → 0.1.23
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/dist/abstractions/AuthAdapter.d.ts +1 -3
- package/dist/abstractions/AuthAdapter.d.ts.map +1 -1
- package/dist/adapters/mock/MockAuthAdapter.d.ts +12 -6
- package/dist/adapters/mock/MockAuthAdapter.d.ts.map +1 -1
- package/dist/adapters/mock/MockAuthAdapter.js +20 -114
- package/dist/adapters/websocket/WebSocketClientTransportAdapter.d.ts.map +1 -1
- package/dist/adapters/websocket/WebSocketClientTransportAdapter.js +9 -1
- package/dist/adapters/websocket/WebSocketServerTransportAdapter.d.ts.map +1 -1
- package/dist/adapters/websocket/WebSocketServerTransportAdapter.js +65 -114
- package/dist/client/BaseClient.d.ts +9 -3
- package/dist/client/BaseClient.d.ts.map +1 -1
- package/dist/client/BaseClient.js +24 -26
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +6 -6
- package/dist/index.mjs +96 -230
- package/dist/index.mjs.map +6 -6
- package/dist/types/auth.d.ts +0 -21
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { TokenPayload
|
|
1
|
+
import type { TokenPayload } from '../types/index.js';
|
|
2
2
|
export interface IAuthAdapter {
|
|
3
|
-
authenticate(credentials: Credentials): Promise<AuthResult>;
|
|
4
3
|
validateToken(token: string): Promise<TokenPayload>;
|
|
5
4
|
generateToken?(payload: TokenPayload): Promise<string>;
|
|
6
5
|
refreshToken?(token: string): Promise<string>;
|
|
@@ -8,6 +7,5 @@ export interface IAuthAdapter {
|
|
|
8
7
|
getCurrentToken?(): string | null;
|
|
9
8
|
isAuthRequired?(): boolean;
|
|
10
9
|
getAuthTimeout?(): number;
|
|
11
|
-
getSupportedCredentialTypes?(): CredentialType[];
|
|
12
10
|
}
|
|
13
11
|
//# 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,
|
|
1
|
+
{"version":3,"file":"AuthAdapter.d.ts","sourceRoot":"","sources":["../../src/abstractions/AuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,YAAY;IAE3B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAGpD,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,eAAe,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC;IAGlC,cAAc,CAAC,IAAI,OAAO,CAAC;IAC3B,cAAc,CAAC,IAAI,MAAM,CAAC;CAC3B"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { IAuthAdapter } from '../../abstractions/AuthAdapter.js';
|
|
2
|
-
import type { TokenPayload
|
|
2
|
+
import type { TokenPayload } from '../../types/index.js';
|
|
3
3
|
export declare class MockAuthAdapter implements IAuthAdapter {
|
|
4
4
|
private tokens;
|
|
5
5
|
private revokedTokens;
|
|
6
|
-
private users;
|
|
7
6
|
private simulateLatency;
|
|
8
7
|
private shouldFailAuth;
|
|
9
8
|
private tokenCounter;
|
|
9
|
+
private currentToken;
|
|
10
10
|
constructor(options?: {
|
|
11
11
|
simulateLatency?: number;
|
|
12
12
|
shouldFailAuth?: boolean;
|
|
@@ -15,16 +15,22 @@ export declare class MockAuthAdapter implements IAuthAdapter {
|
|
|
15
15
|
generateToken(payload: TokenPayload): Promise<string>;
|
|
16
16
|
refreshToken(token: string): Promise<string>;
|
|
17
17
|
revokeToken(token: string): Promise<void>;
|
|
18
|
-
|
|
18
|
+
getCurrentToken(): string | null;
|
|
19
19
|
isAuthRequired(): boolean;
|
|
20
20
|
getAuthTimeout(): number;
|
|
21
|
-
getSupportedCredentialTypes(): CredentialType[];
|
|
22
21
|
private simulateDelay;
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Create and store a test token for a user
|
|
24
|
+
*/
|
|
25
|
+
createTestToken(userId: string, options?: {
|
|
26
|
+
permissions?: string[];
|
|
27
|
+
metadata?: Record<string, unknown>;
|
|
28
|
+
expiresIn?: number;
|
|
29
|
+
}): Promise<string>;
|
|
25
30
|
getTokenCount(): number;
|
|
26
31
|
getRevokedTokenCount(): number;
|
|
27
32
|
clearTokens(): void;
|
|
28
33
|
setFailAuth(fail: boolean): void;
|
|
34
|
+
setCurrentToken(token: string | null): void;
|
|
29
35
|
}
|
|
30
36
|
//# sourceMappingURL=MockAuthAdapter.d.ts.map
|
|
@@ -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,mCAAmC,CAAC;AACtE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"MockAuthAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockAuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,YAAY,CAAuB;gBAE/B,OAAO,CAAC,EAAE;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B;IAKK,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;IAW/C,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,cAAc,IAAI,OAAO;IAIzB,cAAc,IAAI,MAAM;YAKV,aAAa;IAM3B;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAC9C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,MAAM,CAAC;IAYnB,aAAa,IAAI,MAAM;IAIvB,oBAAoB,IAAI,MAAM;IAI9B,WAAW,IAAI,IAAI;IAMnB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAIhC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAG5C"}
|
|
@@ -5,25 +5,12 @@ class MockAuthAdapter {
|
|
|
5
5
|
constructor(options) {
|
|
6
6
|
this.tokens = new Map();
|
|
7
7
|
this.revokedTokens = new Set();
|
|
8
|
-
this.users = new Map();
|
|
9
8
|
this.simulateLatency = 0;
|
|
10
9
|
this.shouldFailAuth = false;
|
|
11
10
|
this.tokenCounter = 0;
|
|
11
|
+
this.currentToken = null;
|
|
12
12
|
this.simulateLatency = options?.simulateLatency ?? 0;
|
|
13
13
|
this.shouldFailAuth = options?.shouldFailAuth ?? false;
|
|
14
|
-
// Add some default test users
|
|
15
|
-
this.addUser('testuser', 'password123', {
|
|
16
|
-
userId: 'user-1',
|
|
17
|
-
email: 'test@example.com',
|
|
18
|
-
username: 'testuser',
|
|
19
|
-
permissions: ['read', 'write']
|
|
20
|
-
});
|
|
21
|
-
this.addUser('admin', 'admin123', {
|
|
22
|
-
userId: 'user-admin',
|
|
23
|
-
email: 'admin@example.com',
|
|
24
|
-
username: 'admin',
|
|
25
|
-
permissions: ['read', 'write', 'admin']
|
|
26
|
-
});
|
|
27
14
|
}
|
|
28
15
|
async validateToken(token) {
|
|
29
16
|
await this.simulateDelay();
|
|
@@ -78,119 +65,34 @@ class MockAuthAdapter {
|
|
|
78
65
|
this.tokens.delete(token);
|
|
79
66
|
this.revokedTokens.add(token);
|
|
80
67
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (this.shouldFailAuth) {
|
|
84
|
-
return {
|
|
85
|
-
success: false,
|
|
86
|
-
error: 'Mock authentication failed'
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
switch (credentials.type) {
|
|
90
|
-
case 'password': {
|
|
91
|
-
if (!credentials.username || !credentials.password) {
|
|
92
|
-
return {
|
|
93
|
-
success: false,
|
|
94
|
-
error: 'Username and password required'
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
const user = this.users.get(credentials.username);
|
|
98
|
-
if (!user || user.password !== credentials.password) {
|
|
99
|
-
return {
|
|
100
|
-
success: false,
|
|
101
|
-
error: 'Invalid credentials'
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
const token = await this.generateToken(user.payload);
|
|
105
|
-
const refreshToken = `refresh-${token}`;
|
|
106
|
-
this.tokens.set(refreshToken, user.payload);
|
|
107
|
-
return {
|
|
108
|
-
success: true,
|
|
109
|
-
token,
|
|
110
|
-
refreshToken,
|
|
111
|
-
user: user.payload,
|
|
112
|
-
userId: user.payload.userId,
|
|
113
|
-
expiresIn: 3600
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
case 'token':
|
|
117
|
-
case 'jwt':
|
|
118
|
-
case 'bearer': {
|
|
119
|
-
if (!credentials.token) {
|
|
120
|
-
return {
|
|
121
|
-
success: false,
|
|
122
|
-
error: 'Token required'
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
try {
|
|
126
|
-
const payload = await this.validateToken(credentials.token);
|
|
127
|
-
return {
|
|
128
|
-
success: true,
|
|
129
|
-
token: credentials.token,
|
|
130
|
-
user: payload,
|
|
131
|
-
userId: payload.userId,
|
|
132
|
-
expiresIn: 3600
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
return {
|
|
137
|
-
success: false,
|
|
138
|
-
error: error.message
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
case 'oauth': {
|
|
143
|
-
// Simulate OAuth flow
|
|
144
|
-
if (!credentials.code) {
|
|
145
|
-
return {
|
|
146
|
-
success: false,
|
|
147
|
-
error: 'OAuth code required'
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
// Create a mock OAuth user
|
|
151
|
-
const payload = {
|
|
152
|
-
userId: `oauth-user-${Date.now()}`,
|
|
153
|
-
email: 'oauth@example.com',
|
|
154
|
-
username: 'oauthuser',
|
|
155
|
-
permissions: ['read', 'write']
|
|
156
|
-
};
|
|
157
|
-
const token = await this.generateToken(payload);
|
|
158
|
-
return {
|
|
159
|
-
success: true,
|
|
160
|
-
token,
|
|
161
|
-
user: payload,
|
|
162
|
-
userId: payload.userId,
|
|
163
|
-
expiresIn: 3600
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
default:
|
|
167
|
-
return {
|
|
168
|
-
success: false,
|
|
169
|
-
error: 'Unsupported credential type'
|
|
170
|
-
};
|
|
171
|
-
}
|
|
68
|
+
getCurrentToken() {
|
|
69
|
+
return this.currentToken;
|
|
172
70
|
}
|
|
173
|
-
// New methods for enhanced auth interface
|
|
174
71
|
isAuthRequired() {
|
|
175
72
|
return false; // Mock adapter doesn't require auth by default
|
|
176
73
|
}
|
|
177
74
|
getAuthTimeout() {
|
|
178
75
|
return 10000; // 10 seconds for testing
|
|
179
76
|
}
|
|
180
|
-
getSupportedCredentialTypes() {
|
|
181
|
-
return ['password', 'token', 'jwt', 'bearer', 'oauth'];
|
|
182
|
-
}
|
|
183
77
|
// Test helper methods
|
|
184
78
|
async simulateDelay() {
|
|
185
79
|
if (this.simulateLatency > 0) {
|
|
186
80
|
await new Promise(resolve => setTimeout(resolve, this.simulateLatency));
|
|
187
81
|
}
|
|
188
82
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Create and store a test token for a user
|
|
85
|
+
*/
|
|
86
|
+
async createTestToken(userId, options) {
|
|
87
|
+
const payload = {
|
|
88
|
+
userId,
|
|
89
|
+
permissions: options?.permissions ?? ['read', 'write'],
|
|
90
|
+
metadata: options?.metadata,
|
|
91
|
+
expiresAt: options?.expiresIn ? Date.now() + options.expiresIn : undefined
|
|
92
|
+
};
|
|
93
|
+
const token = await this.generateToken(payload);
|
|
94
|
+
this.currentToken = token;
|
|
95
|
+
return token;
|
|
194
96
|
}
|
|
195
97
|
getTokenCount() {
|
|
196
98
|
return this.tokens.size;
|
|
@@ -201,9 +103,13 @@ class MockAuthAdapter {
|
|
|
201
103
|
clearTokens() {
|
|
202
104
|
this.tokens.clear();
|
|
203
105
|
this.revokedTokens.clear();
|
|
106
|
+
this.currentToken = null;
|
|
204
107
|
}
|
|
205
108
|
setFailAuth(fail) {
|
|
206
109
|
this.shouldFailAuth = fail;
|
|
207
110
|
}
|
|
111
|
+
setCurrentToken(token) {
|
|
112
|
+
this.currentToken = token;
|
|
113
|
+
}
|
|
208
114
|
}
|
|
209
115
|
exports.MockAuthAdapter = MockAuthAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocketClientTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketClientTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,+BAAgC,YAAW,iBAAiB;IACvE,OAAO,CAAC,EAAE,CAAC,CAAY;IACvB,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAC,CAAiB;gBAE7B,MAAM,CAAC,EAAE,qBAAqB;IASpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2GhE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB3C,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;IAItB;;;OAGG;IACH,YAAY,IAAI,SAAS,GAAG,SAAS;IAIrC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOjD;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMjC,OAAO,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"WebSocketClientTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketClientTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,+BAAgC,YAAW,iBAAiB;IACvE,OAAO,CAAC,EAAE,CAAC,CAAY;IACvB,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAC,CAAiB;gBAE7B,MAAM,CAAC,EAAE,qBAAqB;IASpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2GhE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB3C,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;IAItB;;;OAGG;IACH,YAAY,IAAI,SAAS,GAAG,SAAS;IAIrC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOjD;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMjC,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,aAAa;CAMtB"}
|
|
@@ -213,7 +213,15 @@ class WebSocketClientTransportAdapter {
|
|
|
213
213
|
}
|
|
214
214
|
this.heartbeatTimer = setInterval(() => {
|
|
215
215
|
if (this.ws && this.ws.readyState === ws_1.WebSocket.OPEN) {
|
|
216
|
-
|
|
216
|
+
// Send an actual heartbeat message instead of just a WebSocket ping
|
|
217
|
+
// This ensures the server processes it and updates presence activity
|
|
218
|
+
const heartbeatMessage = {
|
|
219
|
+
id: `heartbeat-${Date.now()}`,
|
|
220
|
+
type: 'heartbeat',
|
|
221
|
+
payload: { timestamp: Date.now() },
|
|
222
|
+
timestamp: Date.now()
|
|
223
|
+
};
|
|
224
|
+
this.ws.send(JSON.stringify(heartbeatMessage));
|
|
217
225
|
}
|
|
218
226
|
}, this.config.heartbeatInterval);
|
|
219
227
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocketServerTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketServerTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,
|
|
1
|
+
{"version":3,"file":"WebSocketServerTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/websocket/WebSocketServerTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,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,8BAA8B;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,+BAAgC,YAAW,iBAAiB;IACvE,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,CAAiC;gBAEnC,MAAM,CAAC,EAAE,8BAA8B;IAUnD,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAclC,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;YA8EhB,mBAAmB;YAuCnB,iBAAiB;IAiF/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;IA4C3C,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"}
|
|
@@ -115,21 +115,22 @@ class WebSocketServerTransportAdapter {
|
|
|
115
115
|
}
|
|
116
116
|
async handleConnection(ws, req) {
|
|
117
117
|
const clientId = this.generateId();
|
|
118
|
-
// Step 1: Try
|
|
118
|
+
// Step 1: Try token authentication via Authorization header
|
|
119
119
|
let authenticated = false;
|
|
120
|
-
let
|
|
120
|
+
let userId;
|
|
121
|
+
let metadata;
|
|
121
122
|
if (this.authAdapter && req.headers.authorization) {
|
|
122
123
|
const token = this.extractBearerToken(req.headers.authorization);
|
|
123
124
|
if (token) {
|
|
124
125
|
try {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
authenticated = authResult.success;
|
|
126
|
+
const tokenPayload = await this.authAdapter.validateToken(token);
|
|
127
|
+
authenticated = true;
|
|
128
|
+
userId = tokenPayload.userId;
|
|
129
|
+
metadata = tokenPayload.metadata;
|
|
130
130
|
}
|
|
131
131
|
catch {
|
|
132
|
-
// Header auth failed but don't reject connection
|
|
132
|
+
// Header auth failed but don't reject connection yet
|
|
133
|
+
// Client can still authenticate via message
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
}
|
|
@@ -138,8 +139,8 @@ class WebSocketServerTransportAdapter {
|
|
|
138
139
|
id: clientId,
|
|
139
140
|
ws,
|
|
140
141
|
authenticated,
|
|
141
|
-
userId
|
|
142
|
-
metadata
|
|
142
|
+
userId,
|
|
143
|
+
metadata,
|
|
143
144
|
connectedAt: Date.now()
|
|
144
145
|
};
|
|
145
146
|
this.clients.set(clientId, client);
|
|
@@ -219,122 +220,72 @@ class WebSocketServerTransportAdapter {
|
|
|
219
220
|
if (!this.authAdapter) {
|
|
220
221
|
this.sendToClient(client, {
|
|
221
222
|
id: this.generateId(),
|
|
222
|
-
type: '
|
|
223
|
-
payload: { error: 'No auth adapter configured' },
|
|
223
|
+
type: 'auth_result',
|
|
224
|
+
payload: { success: false, error: 'No auth adapter configured' },
|
|
225
|
+
timestamp: Date.now()
|
|
226
|
+
});
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const payload = message.payload;
|
|
230
|
+
// Token-based authentication only
|
|
231
|
+
if (!payload.token || typeof payload.token !== 'string') {
|
|
232
|
+
this.sendToClient(client, {
|
|
233
|
+
id: this.generateId(),
|
|
234
|
+
type: 'auth_result',
|
|
235
|
+
payload: { success: false, error: 'Token required for authentication' },
|
|
224
236
|
timestamp: Date.now()
|
|
225
237
|
});
|
|
226
238
|
return;
|
|
227
239
|
}
|
|
228
240
|
try {
|
|
229
|
-
const
|
|
230
|
-
//
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
// Clear auth timeout
|
|
235
|
-
if (client.authTimeout) {
|
|
236
|
-
clearTimeout(client.authTimeout);
|
|
237
|
-
client.authTimeout = undefined;
|
|
238
|
-
}
|
|
239
|
-
// Update client state
|
|
240
|
-
client.authenticated = true;
|
|
241
|
-
client.userId = tokenPayload.userId;
|
|
242
|
-
client.metadata = tokenPayload.metadata;
|
|
243
|
-
// Send success response (using auth_result for consistency with BaseServer)
|
|
244
|
-
this.sendToClient(client, {
|
|
245
|
-
id: this.generateId(),
|
|
246
|
-
type: 'auth_result',
|
|
247
|
-
payload: {
|
|
248
|
-
success: true,
|
|
249
|
-
userId: client.userId
|
|
250
|
-
},
|
|
251
|
-
timestamp: Date.now()
|
|
252
|
-
});
|
|
253
|
-
// Notify handlers about authentication
|
|
254
|
-
const authMessage = {
|
|
255
|
-
id: this.generateId(),
|
|
256
|
-
type: 'client_authenticated',
|
|
257
|
-
payload: {
|
|
258
|
-
clientId: client.id,
|
|
259
|
-
userId: client.userId,
|
|
260
|
-
metadata: client.metadata
|
|
261
|
-
},
|
|
262
|
-
timestamp: Date.now()
|
|
263
|
-
};
|
|
264
|
-
this.messageHandlers.forEach(handler => handler(authMessage));
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
catch (error) {
|
|
268
|
-
this.sendToClient(client, {
|
|
269
|
-
id: this.generateId(),
|
|
270
|
-
type: 'auth_result',
|
|
271
|
-
payload: {
|
|
272
|
-
success: false,
|
|
273
|
-
error: error.message
|
|
274
|
-
},
|
|
275
|
-
timestamp: Date.now()
|
|
276
|
-
});
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
// Handle credential-based authentication
|
|
281
|
-
const credentials = payload;
|
|
282
|
-
const result = await this.authAdapter.authenticate(credentials);
|
|
283
|
-
if (result.success) {
|
|
284
|
-
// Clear auth timeout
|
|
285
|
-
if (client.authTimeout) {
|
|
286
|
-
clearTimeout(client.authTimeout);
|
|
287
|
-
client.authTimeout = undefined;
|
|
288
|
-
}
|
|
289
|
-
// Update client state
|
|
290
|
-
client.authenticated = true;
|
|
291
|
-
client.userId = result.userId || result.user?.userId;
|
|
292
|
-
client.metadata = result.metadata || result.user?.metadata;
|
|
293
|
-
// Send success response
|
|
294
|
-
this.sendToClient(client, {
|
|
295
|
-
id: this.generateId(),
|
|
296
|
-
type: 'auth_success',
|
|
297
|
-
payload: {
|
|
298
|
-
userId: client.userId,
|
|
299
|
-
metadata: client.metadata
|
|
300
|
-
},
|
|
301
|
-
timestamp: Date.now()
|
|
302
|
-
});
|
|
303
|
-
// Notify handlers about authentication
|
|
304
|
-
const authMessage = {
|
|
305
|
-
id: this.generateId(),
|
|
306
|
-
type: 'client_authenticated',
|
|
307
|
-
payload: {
|
|
308
|
-
clientId: client.id,
|
|
309
|
-
userId: client.userId,
|
|
310
|
-
metadata: client.metadata
|
|
311
|
-
},
|
|
312
|
-
timestamp: Date.now()
|
|
313
|
-
};
|
|
314
|
-
this.messageHandlers.forEach(handler => handler(authMessage));
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
// Send error response
|
|
318
|
-
this.sendToClient(client, {
|
|
319
|
-
id: this.generateId(),
|
|
320
|
-
type: 'auth_error',
|
|
321
|
-
payload: { error: result.error || 'Authentication failed' },
|
|
322
|
-
timestamp: Date.now()
|
|
323
|
-
});
|
|
324
|
-
// Optionally close connection
|
|
325
|
-
if (this.config.closeOnAuthFailure) {
|
|
326
|
-
client.ws.close(1008, 'Authentication failed');
|
|
327
|
-
this.clients.delete(client.id);
|
|
328
|
-
}
|
|
241
|
+
const tokenPayload = await this.authAdapter.validateToken(payload.token);
|
|
242
|
+
// Clear auth timeout
|
|
243
|
+
if (client.authTimeout) {
|
|
244
|
+
clearTimeout(client.authTimeout);
|
|
245
|
+
client.authTimeout = undefined;
|
|
329
246
|
}
|
|
247
|
+
// Update client state
|
|
248
|
+
client.authenticated = true;
|
|
249
|
+
client.userId = tokenPayload.userId;
|
|
250
|
+
client.metadata = tokenPayload.metadata;
|
|
251
|
+
// Send success response
|
|
252
|
+
this.sendToClient(client, {
|
|
253
|
+
id: this.generateId(),
|
|
254
|
+
type: 'auth_result',
|
|
255
|
+
payload: {
|
|
256
|
+
success: true,
|
|
257
|
+
userId: client.userId
|
|
258
|
+
},
|
|
259
|
+
timestamp: Date.now()
|
|
260
|
+
});
|
|
261
|
+
// Notify handlers about authentication
|
|
262
|
+
const authMessage = {
|
|
263
|
+
id: this.generateId(),
|
|
264
|
+
type: 'client_authenticated',
|
|
265
|
+
payload: {
|
|
266
|
+
clientId: client.id,
|
|
267
|
+
userId: client.userId,
|
|
268
|
+
metadata: client.metadata
|
|
269
|
+
},
|
|
270
|
+
timestamp: Date.now()
|
|
271
|
+
};
|
|
272
|
+
this.messageHandlers.forEach(handler => handler(authMessage));
|
|
330
273
|
}
|
|
331
274
|
catch (error) {
|
|
332
275
|
this.sendToClient(client, {
|
|
333
276
|
id: this.generateId(),
|
|
334
|
-
type: '
|
|
335
|
-
payload: {
|
|
277
|
+
type: 'auth_result',
|
|
278
|
+
payload: {
|
|
279
|
+
success: false,
|
|
280
|
+
error: error.message
|
|
281
|
+
},
|
|
336
282
|
timestamp: Date.now()
|
|
337
283
|
});
|
|
284
|
+
// Optionally close connection on auth failure
|
|
285
|
+
if (this.config.closeOnAuthFailure) {
|
|
286
|
+
client.ws.close(1008, 'Authentication failed');
|
|
287
|
+
this.clients.delete(client.id);
|
|
288
|
+
}
|
|
338
289
|
}
|
|
339
290
|
}
|
|
340
291
|
extractBearerToken(authHeader) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConnectionState, Event, RoomState, RoomUser, LockRequest, Lock,
|
|
1
|
+
import type { ConnectionState, Event, RoomState, RoomUser, LockRequest, Lock, AuthenticatePayload } from '../types/index.js';
|
|
2
2
|
import type { ITransportAdapter } from '../abstractions/TransportAdapter.js';
|
|
3
3
|
import type { IAuthAdapter } from '../abstractions/AuthAdapter.js';
|
|
4
4
|
import type { IStorageAdapter } from '../abstractions/StorageAdapter.js';
|
|
@@ -77,9 +77,15 @@ export declare class BaseClient extends TypedEventEmitter<ClientEvents> {
|
|
|
77
77
|
private reconnectAttempts;
|
|
78
78
|
private reconnectTimer;
|
|
79
79
|
private lastConnectionUrl;
|
|
80
|
-
private
|
|
80
|
+
private lastToken;
|
|
81
81
|
constructor(config: ClientConfig);
|
|
82
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Connect to the server with an optional authentication token.
|
|
84
|
+
*
|
|
85
|
+
* @param url The WebSocket URL to connect to
|
|
86
|
+
* @param token Optional JWT token for authentication
|
|
87
|
+
*/
|
|
88
|
+
connect(url: string, token?: string): Promise<void>;
|
|
83
89
|
disconnect(): Promise<void>;
|
|
84
90
|
reconnect(): Promise<void>;
|
|
85
91
|
/**
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
1
|
+
{"version":3,"file":"BaseClient.d.ts","sourceRoot":"","sources":["../../src/client/BaseClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ class BaseClient extends EventEmitter_js_1.TypedEventEmitter {
|
|
|
15
15
|
this.reconnectAttempts = 0;
|
|
16
16
|
this.reconnectTimer = null;
|
|
17
17
|
this.lastConnectionUrl = null;
|
|
18
|
-
this.
|
|
18
|
+
this.lastToken = null;
|
|
19
19
|
this.config = config;
|
|
20
20
|
this.transport = config.transport;
|
|
21
21
|
this.auth = config.auth;
|
|
@@ -26,43 +26,41 @@ class BaseClient extends EventEmitter_js_1.TypedEventEmitter {
|
|
|
26
26
|
this.transport.onClose(this.handleClose.bind(this));
|
|
27
27
|
}
|
|
28
28
|
// Connection Management
|
|
29
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Connect to the server with an optional authentication token.
|
|
31
|
+
*
|
|
32
|
+
* @param url The WebSocket URL to connect to
|
|
33
|
+
* @param token Optional JWT token for authentication
|
|
34
|
+
*/
|
|
35
|
+
async connect(url, token) {
|
|
30
36
|
if (this.connectionState !== 'disconnected') {
|
|
31
37
|
throw new Error('Client is already connected or connecting');
|
|
32
38
|
}
|
|
33
39
|
this.connectionState = 'connecting';
|
|
34
40
|
this.lastConnectionUrl = url;
|
|
35
|
-
this.
|
|
41
|
+
this.lastToken = token || null;
|
|
36
42
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
if (authResult.success && authResult.token) {
|
|
42
|
-
this.authToken = authResult.token;
|
|
43
|
-
this.userId = authResult.user?.userId || authResult.userId || '';
|
|
44
|
-
tokenToApply = authResult.token;
|
|
45
|
-
}
|
|
43
|
+
// Use provided token or try to get existing token from auth adapter
|
|
44
|
+
let tokenToApply = token || null;
|
|
45
|
+
if (!tokenToApply && this.auth && typeof this.auth.getCurrentToken === 'function') {
|
|
46
|
+
tokenToApply = this.auth.getCurrentToken();
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
this.authToken = currentToken;
|
|
52
|
-
tokenToApply = currentToken;
|
|
53
|
-
// Try to validate and get user info from token
|
|
48
|
+
if (tokenToApply) {
|
|
49
|
+
this.authToken = tokenToApply;
|
|
50
|
+
// Try to validate and get user info from token
|
|
51
|
+
if (this.auth) {
|
|
54
52
|
try {
|
|
55
|
-
const payload = await this.auth.validateToken(
|
|
53
|
+
const payload = await this.auth.validateToken(tokenToApply);
|
|
56
54
|
this.userId = payload.userId;
|
|
57
55
|
}
|
|
58
56
|
catch {
|
|
59
|
-
// Token validation failed,
|
|
57
|
+
// Token validation failed locally, server will validate
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
// Apply token to transport if it supports it
|
|
61
|
+
if (typeof this.transport.setAuthToken === 'function') {
|
|
62
|
+
this.transport.setAuthToken(tokenToApply);
|
|
63
|
+
}
|
|
66
64
|
}
|
|
67
65
|
const options = {
|
|
68
66
|
url,
|
|
@@ -113,7 +111,7 @@ class BaseClient extends EventEmitter_js_1.TypedEventEmitter {
|
|
|
113
111
|
if (this.connectionState !== 'disconnected') {
|
|
114
112
|
await this.disconnect();
|
|
115
113
|
}
|
|
116
|
-
await this.connect(this.lastConnectionUrl, this.
|
|
114
|
+
await this.connect(this.lastConnectionUrl, this.lastToken || undefined);
|
|
117
115
|
}
|
|
118
116
|
// Authentication
|
|
119
117
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { EventType, BaseEvent, FileAction, FileChangeEvent, GitStatusEvent, CommitEvent, BranchChangeEvent, CursorPositionEvent, Event, TokenPayload, AuthResult,
|
|
1
|
+
export { EventType, BaseEvent, FileAction, FileChangeEvent, GitStatusEvent, CommitEvent, BranchChangeEvent, CursorPositionEvent, Event, TokenPayload, AuthResult, JWTConfig, AuthenticatePayload, AuthenticateResult, RoomPermission, Room, RoomUser, UserStatus, RoomState, RoomConfig, LockType, LockPriority, Lock, LockRequest, LockQueueItem, LockState, ConnectionState, ConnectionOptions, Message, MessageHandler, ErrorHandler, CloseHandler, ExperimentalFeatureConfig, ClientPredicate, BroadcastResult, BroadcastOptions, ExperimentalUsageEvent, ExperimentalFeatureError, PresenceStatus, DeviceInfo, UserPresence, PresenceConfig, PresenceChangeEvent, ActivityUpdate } from './types/index.js';
|
|
2
2
|
export { ITransportAdapter, IStorageAdapter, StorageOperation, IAuthAdapter, TypedEventEmitter, EventListener, UnsubscribeFn, RoomManager, LockManager, DefaultRoomManager, DefaultLockManager, PresenceManager, DefaultPresenceManager, PresenceExtension, ExtendedUserPresence } from './abstractions/index.js';
|
|
3
3
|
export { MockTransportAdapter, MockStorageAdapter, MockAuthAdapter } from './adapters/mock/index.js';
|
|
4
4
|
export { WebSocketServerTransportAdapter, type WebSocketServerTransportConfig, WebSocketClientTransportAdapter, type WebSocketClientConfig } from './adapters/websocket/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,EAEL,YAAY,EACZ,UAAU,EACV,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,EAEL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,kBAAkB,EAElB,cAAc,EACd,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,EAEV,QAAQ,EACR,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,aAAa,EACb,SAAS,EAET,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EAEZ,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,EAExB,cAAc,EACd,UAAU,EACV,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,+BAA+B,EAC/B,KAAK,8BAA8B,EACnC,+BAA+B,EAC/B,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,UAAU,EACV,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC"}
|