@matimo/core 0.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/src/auth/oauth2-config.d.ts +104 -0
- package/dist/src/auth/oauth2-config.d.ts.map +1 -0
- package/dist/src/auth/oauth2-config.js +38 -0
- package/dist/src/auth/oauth2-config.js.map +1 -0
- package/dist/src/auth/oauth2-handler.d.ts +130 -0
- package/dist/src/auth/oauth2-handler.d.ts.map +1 -0
- package/dist/src/auth/oauth2-handler.js +265 -0
- package/dist/src/auth/oauth2-handler.js.map +1 -0
- package/dist/src/auth/oauth2-provider-loader.d.ts +68 -0
- package/dist/src/auth/oauth2-provider-loader.d.ts.map +1 -0
- package/dist/src/auth/oauth2-provider-loader.js +120 -0
- package/dist/src/auth/oauth2-provider-loader.js.map +1 -0
- package/dist/src/core/schema.d.ts +248 -0
- package/dist/src/core/schema.d.ts.map +1 -0
- package/dist/src/core/schema.js +182 -0
- package/dist/src/core/schema.js.map +1 -0
- package/dist/src/core/tool-loader.d.ts +45 -0
- package/dist/src/core/tool-loader.d.ts.map +1 -0
- package/dist/src/core/tool-loader.js +205 -0
- package/dist/src/core/tool-loader.js.map +1 -0
- package/dist/src/core/tool-registry.d.ts +48 -0
- package/dist/src/core/tool-registry.d.ts.map +1 -0
- package/dist/src/core/tool-registry.js +93 -0
- package/dist/src/core/tool-registry.js.map +1 -0
- package/dist/src/core/types.d.ts +157 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +5 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/decorators/index.d.ts +2 -0
- package/dist/src/decorators/index.d.ts.map +1 -0
- package/dist/src/decorators/index.js +2 -0
- package/dist/src/decorators/index.js.map +1 -0
- package/dist/src/decorators/tool-decorator.d.ts +97 -0
- package/dist/src/decorators/tool-decorator.d.ts.map +1 -0
- package/dist/src/decorators/tool-decorator.js +157 -0
- package/dist/src/decorators/tool-decorator.js.map +1 -0
- package/dist/src/encodings/parameter-encoding.d.ts +51 -0
- package/dist/src/encodings/parameter-encoding.d.ts.map +1 -0
- package/dist/src/encodings/parameter-encoding.js +123 -0
- package/dist/src/encodings/parameter-encoding.js.map +1 -0
- package/dist/src/errors/matimo-error.d.ts +34 -0
- package/dist/src/errors/matimo-error.d.ts.map +1 -0
- package/dist/src/errors/matimo-error.js +49 -0
- package/dist/src/errors/matimo-error.js.map +1 -0
- package/dist/src/executors/command-executor.d.ts +19 -0
- package/dist/src/executors/command-executor.d.ts.map +1 -0
- package/dist/src/executors/command-executor.js +98 -0
- package/dist/src/executors/command-executor.js.map +1 -0
- package/dist/src/executors/function-executor.d.ts +23 -0
- package/dist/src/executors/function-executor.d.ts.map +1 -0
- package/dist/src/executors/function-executor.js +164 -0
- package/dist/src/executors/function-executor.js.map +1 -0
- package/dist/src/executors/http-executor.d.ts +26 -0
- package/dist/src/executors/http-executor.d.ts.map +1 -0
- package/dist/src/executors/http-executor.js +137 -0
- package/dist/src/executors/http-executor.js.map +1 -0
- package/dist/src/index.d.ts +26 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/integrations/langchain.d.ts +46 -0
- package/dist/src/integrations/langchain.d.ts.map +1 -0
- package/dist/src/integrations/langchain.js +197 -0
- package/dist/src/integrations/langchain.js.map +1 -0
- package/dist/src/matimo-instance.d.ts +124 -0
- package/dist/src/matimo-instance.d.ts.map +1 -0
- package/dist/src/matimo-instance.js +313 -0
- package/dist/src/matimo-instance.js.map +1 -0
- package/dist/tools/calculator/calculator.d.ts +26 -0
- package/dist/tools/calculator/calculator.d.ts.map +1 -0
- package/dist/tools/calculator/calculator.js +104 -0
- package/dist/tools/calculator/calculator.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +94 -0
- package/tools/calculator/calculator.ts +125 -0
- package/tools/calculator/definition.yaml +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tallclub
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 Configuration Types - PROVIDER-AGNOSTIC + YAML-DRIVEN
|
|
3
|
+
*
|
|
4
|
+
* Matimo supports OAuth2 for any provider via YAML configuration.
|
|
5
|
+
* Provider definitions are loaded from tools/[provider]/definition.yaml files.
|
|
6
|
+
*
|
|
7
|
+
* Matimo's Responsibility:
|
|
8
|
+
* - Help obtain tokens via standard OAuth2 flow
|
|
9
|
+
* - Support automatic token refresh
|
|
10
|
+
* - Work with Google, GitHub, Slack, or any OAuth2 provider
|
|
11
|
+
* - Load provider configs from YAML (no hardcoded endpoints)
|
|
12
|
+
*
|
|
13
|
+
* User's Responsibility:
|
|
14
|
+
* - Store tokens (DB, file, cache, wherever you want)
|
|
15
|
+
* - Retrieve and pass tokens to Matimo tools
|
|
16
|
+
*
|
|
17
|
+
* Adding a New Provider (e.g., Microsoft Teams):
|
|
18
|
+
* 1. Create: tools/microsoft/definition.yaml
|
|
19
|
+
* 2. Add provider section with OAuth endpoints
|
|
20
|
+
* 3. Done! OAuth2Handler automatically recognizes it.
|
|
21
|
+
*
|
|
22
|
+
* Configuration Priority (highest to lowest):
|
|
23
|
+
* 1. config.endpoints - Runtime override (user provides directly)
|
|
24
|
+
* 2. OAUTH_PROVIDER_AUTH_URL env var - Deployment override
|
|
25
|
+
* 3. YAML definition (tools/[provider]/definition.yaml) - Default from config
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Supported OAuth2 providers
|
|
29
|
+
*
|
|
30
|
+
* Type is string (not enum) because providers are discovered from YAML.
|
|
31
|
+
* Tools define which provider they use via authentication.provider field.
|
|
32
|
+
*/
|
|
33
|
+
export type OAuth2Provider = string;
|
|
34
|
+
/**
|
|
35
|
+
* OAuth2 token - Returned by OAuth2Handler
|
|
36
|
+
*
|
|
37
|
+
* This is what you get after successful authorization.
|
|
38
|
+
* Store this in your DB/file/cache (Matimo doesn't store it).
|
|
39
|
+
* Pass accessToken to any Matimo tool that needs OAuth.
|
|
40
|
+
*/
|
|
41
|
+
export interface OAuth2Token {
|
|
42
|
+
accessToken: string;
|
|
43
|
+
refreshToken?: string;
|
|
44
|
+
expiresAt: number;
|
|
45
|
+
scopes: string[];
|
|
46
|
+
provider: OAuth2Provider;
|
|
47
|
+
userId: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* OAuth2 configuration - PROVIDER-AGNOSTIC + YAML-DRIVEN
|
|
51
|
+
*
|
|
52
|
+
* Same interface works for Google, GitHub, Slack, or any OAuth2 provider.
|
|
53
|
+
* Provider endpoints come from YAML definitions (tools/[provider]/definition.yaml).
|
|
54
|
+
* Users can override endpoints without touching code.
|
|
55
|
+
*
|
|
56
|
+
* Configuration Priority:
|
|
57
|
+
* 1. endpoints property (runtime override - user provides directly)
|
|
58
|
+
* 2. OAUTH_PROVIDER_AUTH_URL environment variable (deployment config)
|
|
59
|
+
* 3. YAML definition from tools/[provider]/definition.yaml (default configuration)
|
|
60
|
+
*/
|
|
61
|
+
export interface OAuth2Config {
|
|
62
|
+
provider: OAuth2Provider;
|
|
63
|
+
clientId: string;
|
|
64
|
+
clientSecret: string;
|
|
65
|
+
redirectUri: string;
|
|
66
|
+
endpoints?: OAuth2Endpoints;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Authorization request options
|
|
70
|
+
*/
|
|
71
|
+
export interface AuthorizationOptions {
|
|
72
|
+
scopes: string[];
|
|
73
|
+
userId: string;
|
|
74
|
+
state?: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Token exchange response from OAuth2 provider
|
|
78
|
+
*/
|
|
79
|
+
export interface TokenResponse {
|
|
80
|
+
access_token: string;
|
|
81
|
+
refresh_token?: string;
|
|
82
|
+
expires_in: number;
|
|
83
|
+
token_type: string;
|
|
84
|
+
scope?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* OAuth2 endpoints for a provider
|
|
88
|
+
*/
|
|
89
|
+
export interface OAuth2Endpoints {
|
|
90
|
+
authorizationUrl: string;
|
|
91
|
+
tokenUrl: string;
|
|
92
|
+
revokeUrl?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* NOTE: Provider endpoints are loaded from YAML files, not hardcoded here.
|
|
96
|
+
* See: tools/[provider]/definition.yaml for provider configurations
|
|
97
|
+
*
|
|
98
|
+
* This enables:
|
|
99
|
+
* - Infinite provider support
|
|
100
|
+
* - Configuration-driven design
|
|
101
|
+
* - Easy provider additions without code changes
|
|
102
|
+
* - Centralized endpoint management
|
|
103
|
+
*/
|
|
104
|
+
//# sourceMappingURL=oauth2-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2-config.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth2-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 Configuration Types - PROVIDER-AGNOSTIC + YAML-DRIVEN
|
|
3
|
+
*
|
|
4
|
+
* Matimo supports OAuth2 for any provider via YAML configuration.
|
|
5
|
+
* Provider definitions are loaded from tools/[provider]/definition.yaml files.
|
|
6
|
+
*
|
|
7
|
+
* Matimo's Responsibility:
|
|
8
|
+
* - Help obtain tokens via standard OAuth2 flow
|
|
9
|
+
* - Support automatic token refresh
|
|
10
|
+
* - Work with Google, GitHub, Slack, or any OAuth2 provider
|
|
11
|
+
* - Load provider configs from YAML (no hardcoded endpoints)
|
|
12
|
+
*
|
|
13
|
+
* User's Responsibility:
|
|
14
|
+
* - Store tokens (DB, file, cache, wherever you want)
|
|
15
|
+
* - Retrieve and pass tokens to Matimo tools
|
|
16
|
+
*
|
|
17
|
+
* Adding a New Provider (e.g., Microsoft Teams):
|
|
18
|
+
* 1. Create: tools/microsoft/definition.yaml
|
|
19
|
+
* 2. Add provider section with OAuth endpoints
|
|
20
|
+
* 3. Done! OAuth2Handler automatically recognizes it.
|
|
21
|
+
*
|
|
22
|
+
* Configuration Priority (highest to lowest):
|
|
23
|
+
* 1. config.endpoints - Runtime override (user provides directly)
|
|
24
|
+
* 2. OAUTH_PROVIDER_AUTH_URL env var - Deployment override
|
|
25
|
+
* 3. YAML definition (tools/[provider]/definition.yaml) - Default from config
|
|
26
|
+
*/
|
|
27
|
+
export {};
|
|
28
|
+
/**
|
|
29
|
+
* NOTE: Provider endpoints are loaded from YAML files, not hardcoded here.
|
|
30
|
+
* See: tools/[provider]/definition.yaml for provider configurations
|
|
31
|
+
*
|
|
32
|
+
* This enables:
|
|
33
|
+
* - Infinite provider support
|
|
34
|
+
* - Configuration-driven design
|
|
35
|
+
* - Easy provider additions without code changes
|
|
36
|
+
* - Centralized endpoint management
|
|
37
|
+
*/
|
|
38
|
+
//# sourceMappingURL=oauth2-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2-config.js","sourceRoot":"","sources":["../../../src/auth/oauth2-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;AA2EH;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 Handler
|
|
3
|
+
* Manages OAuth2 authentication flows and token exchange
|
|
4
|
+
*/
|
|
5
|
+
import { OAuth2Config, OAuth2Token, OAuth2Endpoints, AuthorizationOptions } from './oauth2-config';
|
|
6
|
+
import { OAuth2ProviderLoader } from './oauth2-provider-loader';
|
|
7
|
+
/**
|
|
8
|
+
* OAuth2Handler - Provider-Agnostic OAuth2 Flow Manager
|
|
9
|
+
*
|
|
10
|
+
* Matimo's OAuth2 Scope:
|
|
11
|
+
* ✅ Help complete OAuth2 authorization with any provider
|
|
12
|
+
* ✅ Exchange authorization codes for tokens
|
|
13
|
+
* ✅ Support automatic token refresh if needed
|
|
14
|
+
* ✅ Work with Google, GitHub, Slack, or any OAuth2 provider
|
|
15
|
+
* ❌ Store tokens (User's responsibility)
|
|
16
|
+
* ❌ Manage token lifecycle (User's responsibility)
|
|
17
|
+
*
|
|
18
|
+
* Pattern: Config → Get Auth URL → Exchange Code → Return Token → User Stores It
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // 1. Create handler (works for any OAuth2 provider)
|
|
23
|
+
* const oauth2 = new OAuth2Handler({
|
|
24
|
+
* provider: 'google', // or 'github', 'slack', etc.
|
|
25
|
+
* clientId: process.env.CLIENT_ID,
|
|
26
|
+
* clientSecret: process.env.CLIENT_SECRET,
|
|
27
|
+
* redirectUri: 'http://localhost:3000/callback',
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // 2. Generate authorization URL
|
|
31
|
+
* const authUrl = oauth2.getAuthorizationUrl({
|
|
32
|
+
* userId: 'user-123',
|
|
33
|
+
* scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
|
|
34
|
+
* });
|
|
35
|
+
* // Send user to authUrl
|
|
36
|
+
*
|
|
37
|
+
* // 3. Exchange authorization code for token
|
|
38
|
+
* const token = await oauth2.exchangeCodeForToken('user-123', authCode);
|
|
39
|
+
* // Token: { accessToken, refreshToken, expiresAt, ... }
|
|
40
|
+
*
|
|
41
|
+
* // 4. User stores token (in DB, file, cache, or wherever they choose)
|
|
42
|
+
* // Matimo does NOT store tokens - that's the user's responsibility
|
|
43
|
+
* await myDatabase.saveToken('user-123', token);
|
|
44
|
+
*
|
|
45
|
+
* // 5. User retrieves token from their storage and passes to tools
|
|
46
|
+
* const stored = await myDatabase.getToken('user-123');
|
|
47
|
+
* await matimo.execute('gmail-send-email', {
|
|
48
|
+
* to: 'user@example.com',
|
|
49
|
+
* GMAIL_ACCESS_TOKEN: stored.accessToken, // ← User provides token
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare class OAuth2Handler {
|
|
54
|
+
private config;
|
|
55
|
+
private tokenRefreshBuffer;
|
|
56
|
+
private endpoints;
|
|
57
|
+
private providerLoader;
|
|
58
|
+
/**
|
|
59
|
+
* Constructor
|
|
60
|
+
* @param config - OAuth2 configuration (provider, clientId, clientSecret, redirectUri)
|
|
61
|
+
* @param providerLoader - Optional provider loader (loads from YAML files)
|
|
62
|
+
*/
|
|
63
|
+
constructor(config: OAuth2Config, providerLoader?: OAuth2ProviderLoader);
|
|
64
|
+
/**
|
|
65
|
+
* Resolve OAuth2 endpoints with layered configuration
|
|
66
|
+
*
|
|
67
|
+
* Priority (highest to lowest):
|
|
68
|
+
* 1. config.endpoints - user provided at runtime
|
|
69
|
+
* 2. Environment variables: OAUTH_{PROVIDER}_AUTH_URL, OAUTH_{PROVIDER}_TOKEN_URL, etc.
|
|
70
|
+
* 3. YAML definition from provider loader (tools/[provider]/definition.yaml)
|
|
71
|
+
*
|
|
72
|
+
* This design allows:
|
|
73
|
+
* - Runtime override via config
|
|
74
|
+
* - Deployment-time override via env vars
|
|
75
|
+
* - Default configuration from YAML files
|
|
76
|
+
* - Support for infinite providers without code changes
|
|
77
|
+
*/
|
|
78
|
+
private resolveEndpoints;
|
|
79
|
+
/**
|
|
80
|
+
* Get resolved endpoints (for testing or debugging)
|
|
81
|
+
*/
|
|
82
|
+
getEndpoints(): OAuth2Endpoints;
|
|
83
|
+
/**
|
|
84
|
+
* Generate authorization URL for user to visit
|
|
85
|
+
* @param options - Authorization options (scopes, userId, optional state)
|
|
86
|
+
* @returns Authorization URL
|
|
87
|
+
*/
|
|
88
|
+
getAuthorizationUrl(options: AuthorizationOptions): string;
|
|
89
|
+
/**
|
|
90
|
+
* Exchange authorization code for access token
|
|
91
|
+
* @param code - Authorization code from provider
|
|
92
|
+
* @param userId - User ID to associate token with
|
|
93
|
+
* @returns OAuth2Token with access and optional refresh token
|
|
94
|
+
*/
|
|
95
|
+
exchangeCodeForToken(code: string, userId: string): Promise<OAuth2Token>;
|
|
96
|
+
/**
|
|
97
|
+
* Refresh a token if it's expired or expiring soon
|
|
98
|
+
* @param userId - User ID (for context only)
|
|
99
|
+
* @param currentToken - Current OAuth2Token to refresh
|
|
100
|
+
* @returns Refreshed OAuth2Token (same token if not expiring soon)
|
|
101
|
+
*/
|
|
102
|
+
refreshTokenIfNeeded(userId: string, currentToken: OAuth2Token): Promise<OAuth2Token>;
|
|
103
|
+
/**
|
|
104
|
+
* Revoke a token (logout)
|
|
105
|
+
* @param token - OAuth2Token to revoke
|
|
106
|
+
*/
|
|
107
|
+
revokeToken(token: OAuth2Token): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Check if a token is expired or expiring soon (within 5 minute buffer)
|
|
110
|
+
*/
|
|
111
|
+
private isTokenExpiringSoon;
|
|
112
|
+
/**
|
|
113
|
+
* Parse token response from provider
|
|
114
|
+
*/
|
|
115
|
+
private parseTokenResponse;
|
|
116
|
+
/**
|
|
117
|
+
* Generate random state token for CSRF protection
|
|
118
|
+
*/
|
|
119
|
+
private generateRandomState;
|
|
120
|
+
/**
|
|
121
|
+
* Check if a token is valid (not expired)
|
|
122
|
+
*/
|
|
123
|
+
isTokenValid(token: OAuth2Token): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Set custom token refresh buffer (milliseconds before expiration)
|
|
126
|
+
*/
|
|
127
|
+
setTokenRefreshBuffer(milliseconds: number): void;
|
|
128
|
+
}
|
|
129
|
+
export default OAuth2Handler;
|
|
130
|
+
//# sourceMappingURL=oauth2-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2-handler.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth2-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,YAAY,EACZ,WAAW,EACX,eAAe,EAEf,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,cAAc,CAAuB;IAE7C;;;;OAIG;gBACS,MAAM,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,oBAAoB;IAoBvE;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;OAEG;IACH,YAAY,IAAI,eAAe;IAI/B;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM;IAmB1D;;;;;OAKG;IACG,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA2B9E;;;;;OAKG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAuC3F;;;OAGG;IACG,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBpD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAKzC;;OAEG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;CAGlD;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2 Handler
|
|
3
|
+
* Manages OAuth2 authentication flows and token exchange
|
|
4
|
+
*/
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
import { OAuth2ProviderLoader } from './oauth2-provider-loader';
|
|
7
|
+
import { MatimoError, ErrorCode } from '../errors/matimo-error';
|
|
8
|
+
/**
|
|
9
|
+
* OAuth2Handler - Provider-Agnostic OAuth2 Flow Manager
|
|
10
|
+
*
|
|
11
|
+
* Matimo's OAuth2 Scope:
|
|
12
|
+
* ✅ Help complete OAuth2 authorization with any provider
|
|
13
|
+
* ✅ Exchange authorization codes for tokens
|
|
14
|
+
* ✅ Support automatic token refresh if needed
|
|
15
|
+
* ✅ Work with Google, GitHub, Slack, or any OAuth2 provider
|
|
16
|
+
* ❌ Store tokens (User's responsibility)
|
|
17
|
+
* ❌ Manage token lifecycle (User's responsibility)
|
|
18
|
+
*
|
|
19
|
+
* Pattern: Config → Get Auth URL → Exchange Code → Return Token → User Stores It
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // 1. Create handler (works for any OAuth2 provider)
|
|
24
|
+
* const oauth2 = new OAuth2Handler({
|
|
25
|
+
* provider: 'google', // or 'github', 'slack', etc.
|
|
26
|
+
* clientId: process.env.CLIENT_ID,
|
|
27
|
+
* clientSecret: process.env.CLIENT_SECRET,
|
|
28
|
+
* redirectUri: 'http://localhost:3000/callback',
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // 2. Generate authorization URL
|
|
32
|
+
* const authUrl = oauth2.getAuthorizationUrl({
|
|
33
|
+
* userId: 'user-123',
|
|
34
|
+
* scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
|
|
35
|
+
* });
|
|
36
|
+
* // Send user to authUrl
|
|
37
|
+
*
|
|
38
|
+
* // 3. Exchange authorization code for token
|
|
39
|
+
* const token = await oauth2.exchangeCodeForToken('user-123', authCode);
|
|
40
|
+
* // Token: { accessToken, refreshToken, expiresAt, ... }
|
|
41
|
+
*
|
|
42
|
+
* // 4. User stores token (in DB, file, cache, or wherever they choose)
|
|
43
|
+
* // Matimo does NOT store tokens - that's the user's responsibility
|
|
44
|
+
* await myDatabase.saveToken('user-123', token);
|
|
45
|
+
*
|
|
46
|
+
* // 5. User retrieves token from their storage and passes to tools
|
|
47
|
+
* const stored = await myDatabase.getToken('user-123');
|
|
48
|
+
* await matimo.execute('gmail-send-email', {
|
|
49
|
+
* to: 'user@example.com',
|
|
50
|
+
* GMAIL_ACCESS_TOKEN: stored.accessToken, // ← User provides token
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export class OAuth2Handler {
|
|
55
|
+
/**
|
|
56
|
+
* Constructor
|
|
57
|
+
* @param config - OAuth2 configuration (provider, clientId, clientSecret, redirectUri)
|
|
58
|
+
* @param providerLoader - Optional provider loader (loads from YAML files)
|
|
59
|
+
*/
|
|
60
|
+
constructor(config, providerLoader) {
|
|
61
|
+
if (!config.clientId || !config.clientSecret) {
|
|
62
|
+
throw new MatimoError('OAuth2 clientId and clientSecret are required', ErrorCode.AUTH_FAILED, { provider: config.provider });
|
|
63
|
+
}
|
|
64
|
+
this.config = config;
|
|
65
|
+
this.tokenRefreshBuffer = 5 * 60 * 1000; // Refresh 5 minutes before expiration
|
|
66
|
+
this.providerLoader = providerLoader || new OAuth2ProviderLoader('tools');
|
|
67
|
+
// Resolve endpoints with priority:
|
|
68
|
+
// 1. Runtime config (highest priority - user provides endpoints directly)
|
|
69
|
+
// 2. Environment variables (deployment config)
|
|
70
|
+
// 3. YAML definition (provider loader - configuration-driven)
|
|
71
|
+
this.endpoints = this.resolveEndpoints(config);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Resolve OAuth2 endpoints with layered configuration
|
|
75
|
+
*
|
|
76
|
+
* Priority (highest to lowest):
|
|
77
|
+
* 1. config.endpoints - user provided at runtime
|
|
78
|
+
* 2. Environment variables: OAUTH_{PROVIDER}_AUTH_URL, OAUTH_{PROVIDER}_TOKEN_URL, etc.
|
|
79
|
+
* 3. YAML definition from provider loader (tools/[provider]/definition.yaml)
|
|
80
|
+
*
|
|
81
|
+
* This design allows:
|
|
82
|
+
* - Runtime override via config
|
|
83
|
+
* - Deployment-time override via env vars
|
|
84
|
+
* - Default configuration from YAML files
|
|
85
|
+
* - Support for infinite providers without code changes
|
|
86
|
+
*/
|
|
87
|
+
resolveEndpoints(config) {
|
|
88
|
+
// Priority 1: Runtime config (user provides endpoints directly)
|
|
89
|
+
if (config.endpoints) {
|
|
90
|
+
return config.endpoints;
|
|
91
|
+
}
|
|
92
|
+
// Priority 2: Environment variables
|
|
93
|
+
const envAuthUrl = process.env[`OAUTH_${config.provider.toUpperCase()}_AUTH_URL`];
|
|
94
|
+
const envTokenUrl = process.env[`OAUTH_${config.provider.toUpperCase()}_TOKEN_URL`];
|
|
95
|
+
if (envAuthUrl || envTokenUrl) {
|
|
96
|
+
if (!envAuthUrl || !envTokenUrl) {
|
|
97
|
+
throw new MatimoError(`Incomplete OAuth environment config for ${config.provider}. Both OAUTH_${config.provider.toUpperCase()}_AUTH_URL and OAUTH_${config.provider.toUpperCase()}_TOKEN_URL must be set.`, ErrorCode.AUTH_FAILED, { provider: config.provider });
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
authorizationUrl: envAuthUrl,
|
|
101
|
+
tokenUrl: envTokenUrl,
|
|
102
|
+
revokeUrl: process.env[`OAUTH_${config.provider.toUpperCase()}_REVOKE_URL`],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// Priority 3: YAML definition from provider loader
|
|
106
|
+
const yamlEndpoints = this.providerLoader.getProvider(config.provider);
|
|
107
|
+
if (yamlEndpoints) {
|
|
108
|
+
return yamlEndpoints;
|
|
109
|
+
}
|
|
110
|
+
// No endpoints found
|
|
111
|
+
throw new MatimoError(`Unsupported OAuth2 provider: ${config.provider}. Provide endpoints via:
|
|
112
|
+
1. config.endpoints (runtime override)
|
|
113
|
+
2. OAUTH_${config.provider.toUpperCase()}_AUTH_URL env var (deployment config)
|
|
114
|
+
3. tools/${config.provider}/definition.yaml (YAML configuration)`, ErrorCode.AUTH_FAILED, { provider: config.provider });
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get resolved endpoints (for testing or debugging)
|
|
118
|
+
*/
|
|
119
|
+
getEndpoints() {
|
|
120
|
+
return this.endpoints;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Generate authorization URL for user to visit
|
|
124
|
+
* @param options - Authorization options (scopes, userId, optional state)
|
|
125
|
+
* @returns Authorization URL
|
|
126
|
+
*/
|
|
127
|
+
getAuthorizationUrl(options) {
|
|
128
|
+
const state = options.state || this.generateRandomState();
|
|
129
|
+
const params = new URLSearchParams({
|
|
130
|
+
client_id: this.config.clientId,
|
|
131
|
+
redirect_uri: this.config.redirectUri,
|
|
132
|
+
response_type: 'code',
|
|
133
|
+
scope: options.scopes.join(' '),
|
|
134
|
+
state,
|
|
135
|
+
// Provider-specific parameters
|
|
136
|
+
...(this.config.provider === 'google' && {
|
|
137
|
+
access_type: 'offline', // Request refresh token
|
|
138
|
+
prompt: 'consent', // Force consent screen
|
|
139
|
+
}),
|
|
140
|
+
});
|
|
141
|
+
return `${this.endpoints.authorizationUrl}?${params.toString()}`;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Exchange authorization code for access token
|
|
145
|
+
* @param code - Authorization code from provider
|
|
146
|
+
* @param userId - User ID to associate token with
|
|
147
|
+
* @returns OAuth2Token with access and optional refresh token
|
|
148
|
+
*/
|
|
149
|
+
async exchangeCodeForToken(code, userId) {
|
|
150
|
+
try {
|
|
151
|
+
const response = await axios.post(this.endpoints.tokenUrl, {
|
|
152
|
+
client_id: this.config.clientId,
|
|
153
|
+
client_secret: this.config.clientSecret,
|
|
154
|
+
code,
|
|
155
|
+
redirect_uri: this.config.redirectUri,
|
|
156
|
+
grant_type: 'authorization_code',
|
|
157
|
+
});
|
|
158
|
+
const tokenResponse = response.data;
|
|
159
|
+
const token = this.parseTokenResponse(tokenResponse, userId);
|
|
160
|
+
// Return token - user is responsible for storing it
|
|
161
|
+
return token;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
throw new MatimoError('Failed to exchange authorization code for token', ErrorCode.AUTH_FAILED, {
|
|
165
|
+
provider: this.config.provider,
|
|
166
|
+
error: error.message,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Refresh a token if it's expired or expiring soon
|
|
172
|
+
* @param userId - User ID (for context only)
|
|
173
|
+
* @param currentToken - Current OAuth2Token to refresh
|
|
174
|
+
* @returns Refreshed OAuth2Token (same token if not expiring soon)
|
|
175
|
+
*/
|
|
176
|
+
async refreshTokenIfNeeded(userId, currentToken) {
|
|
177
|
+
if (!this.isTokenExpiringSoon(currentToken)) {
|
|
178
|
+
return currentToken; // Token still valid
|
|
179
|
+
}
|
|
180
|
+
if (!currentToken.refreshToken) {
|
|
181
|
+
throw new MatimoError(`Cannot refresh token for user: ${userId} - no refreshToken available`, ErrorCode.AUTH_FAILED, { userId, provider: this.config.provider });
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
const response = await axios.post(this.endpoints.tokenUrl, {
|
|
185
|
+
client_id: this.config.clientId,
|
|
186
|
+
client_secret: this.config.clientSecret,
|
|
187
|
+
refresh_token: currentToken.refreshToken,
|
|
188
|
+
grant_type: 'refresh_token',
|
|
189
|
+
});
|
|
190
|
+
const tokenResponse = response.data;
|
|
191
|
+
const refreshedToken = this.parseTokenResponse(tokenResponse, userId, currentToken.refreshToken);
|
|
192
|
+
// Return refreshed token - user is responsible for storing it
|
|
193
|
+
return refreshedToken;
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
throw new MatimoError('Failed to refresh token', ErrorCode.AUTH_FAILED, {
|
|
197
|
+
userId,
|
|
198
|
+
provider: this.config.provider,
|
|
199
|
+
error: error.message,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Revoke a token (logout)
|
|
205
|
+
* @param token - OAuth2Token to revoke
|
|
206
|
+
*/
|
|
207
|
+
async revokeToken(token) {
|
|
208
|
+
if (!this.endpoints.revokeUrl) {
|
|
209
|
+
// Provider doesn't support revocation
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
await axios.post(this.endpoints.revokeUrl, {
|
|
214
|
+
client_id: this.config.clientId,
|
|
215
|
+
client_secret: this.config.clientSecret,
|
|
216
|
+
token: token.accessToken,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// Log but don't fail - token may already be revoked
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Check if a token is expired or expiring soon (within 5 minute buffer)
|
|
225
|
+
*/
|
|
226
|
+
isTokenExpiringSoon(token) {
|
|
227
|
+
const now = Date.now();
|
|
228
|
+
const expiresAt = token.expiresAt;
|
|
229
|
+
return now >= expiresAt - this.tokenRefreshBuffer;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Parse token response from provider
|
|
233
|
+
*/
|
|
234
|
+
parseTokenResponse(response, userId, existingRefreshToken) {
|
|
235
|
+
return {
|
|
236
|
+
accessToken: response.access_token,
|
|
237
|
+
refreshToken: response.refresh_token || existingRefreshToken,
|
|
238
|
+
expiresAt: Date.now() + response.expires_in * 1000,
|
|
239
|
+
scopes: response.scope ? response.scope.split(' ') : [],
|
|
240
|
+
provider: this.config.provider,
|
|
241
|
+
userId,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Generate random state token for CSRF protection
|
|
246
|
+
*/
|
|
247
|
+
generateRandomState() {
|
|
248
|
+
return (Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15));
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Check if a token is valid (not expired)
|
|
252
|
+
*/
|
|
253
|
+
isTokenValid(token) {
|
|
254
|
+
const now = Date.now();
|
|
255
|
+
return now < token.expiresAt;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Set custom token refresh buffer (milliseconds before expiration)
|
|
259
|
+
*/
|
|
260
|
+
setTokenRefreshBuffer(milliseconds) {
|
|
261
|
+
this.tokenRefreshBuffer = milliseconds;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
export default OAuth2Handler;
|
|
265
|
+
//# sourceMappingURL=oauth2-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2-handler.js","sourceRoot":"","sources":["../../../src/auth/oauth2-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth2ProviderLoader - Loads provider definitions from YAML files
|
|
3
|
+
*
|
|
4
|
+
* Pattern: Configuration-driven providers
|
|
5
|
+
* - Loads provider definitions from tools/[provider]/definition.yaml
|
|
6
|
+
* - Discovers providers with type: provider
|
|
7
|
+
* - Makes endpoints available to OAuth2Handler
|
|
8
|
+
* - Supports infinite providers without code changes
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const loader = new OAuth2ProviderLoader('./tools');
|
|
13
|
+
* const providers = await loader.loadProviders();
|
|
14
|
+
* const googleEndpoints = providers.get('google');
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { OAuth2Endpoints } from './oauth2-config';
|
|
18
|
+
import { type ProviderDefinition } from '../core/schema';
|
|
19
|
+
/**
|
|
20
|
+
* OAuth2ProviderLoader - Loads OAuth2 provider configurations from YAML
|
|
21
|
+
*
|
|
22
|
+
* Design Principle:
|
|
23
|
+
* - Configuration-driven: All provider config in YAML files
|
|
24
|
+
* - Discoverable: Automatically finds tools/[provider]/definition.yaml with type: provider
|
|
25
|
+
* - Extensible: Add new providers by adding YAML file, no code changes
|
|
26
|
+
* - Overridable: Users can override via env vars or runtime config
|
|
27
|
+
*/
|
|
28
|
+
export declare class OAuth2ProviderLoader {
|
|
29
|
+
private toolsPath;
|
|
30
|
+
private providers;
|
|
31
|
+
private definitions;
|
|
32
|
+
constructor(toolsPath: string);
|
|
33
|
+
/**
|
|
34
|
+
* Load all provider definitions from tools directory
|
|
35
|
+
*
|
|
36
|
+
* Discovers tools/[provider]/definition.yaml files with type: provider
|
|
37
|
+
* Validates and stores provider endpoint configurations
|
|
38
|
+
*
|
|
39
|
+
* @returns Map of provider name → OAuth2Endpoints
|
|
40
|
+
* @throws MatimoError if invalid provider definition found
|
|
41
|
+
*/
|
|
42
|
+
loadProviders(): Promise<Map<string, OAuth2Endpoints>>;
|
|
43
|
+
/**
|
|
44
|
+
* Get endpoints for a specific provider
|
|
45
|
+
* @param providerName - Name of the provider (e.g., 'google', 'github')
|
|
46
|
+
* @returns OAuth2Endpoints or undefined if provider not found
|
|
47
|
+
*/
|
|
48
|
+
getProvider(providerName: string): OAuth2Endpoints | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Get full provider definition
|
|
51
|
+
* @param providerName - Name of the provider
|
|
52
|
+
* @returns ProviderDefinition or undefined if provider not found
|
|
53
|
+
*/
|
|
54
|
+
getDefinition(providerName: string): ProviderDefinition | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* List all loaded providers
|
|
57
|
+
*/
|
|
58
|
+
listProviders(): string[];
|
|
59
|
+
/**
|
|
60
|
+
* Validate provider definition structure using Zod schema
|
|
61
|
+
*/
|
|
62
|
+
protected validateProviderDefinition(definition: ProviderDefinition): void;
|
|
63
|
+
/**
|
|
64
|
+
* Register a provider definition
|
|
65
|
+
*/
|
|
66
|
+
private registerProvider;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=oauth2-provider-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2-provider-loader.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth2-provider-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAA8B,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAErF;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,WAAW,CAA8C;gBAErD,SAAS,EAAE,MAAM;IAI7B;;;;;;;;OAQG;IACG,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAqC5D;;;;OAIG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI9D;;;;OAIG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAInE;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;OAEG;IACH,SAAS,CAAC,0BAA0B,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAU1E;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAMzB"}
|