@shin1ohno/sage 0.7.9 → 0.8.6

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.
Files changed (149) hide show
  1. package/README.md +26 -8
  2. package/dist/cli/mcp-handler.d.ts.map +1 -1
  3. package/dist/cli/mcp-handler.js +141 -987
  4. package/dist/cli/mcp-handler.js.map +1 -1
  5. package/dist/config/loader.d.ts.map +1 -1
  6. package/dist/config/loader.js +30 -1
  7. package/dist/config/loader.js.map +1 -1
  8. package/dist/config/update-validation.d.ts +52 -0
  9. package/dist/config/update-validation.d.ts.map +1 -0
  10. package/dist/config/update-validation.js +133 -0
  11. package/dist/config/update-validation.js.map +1 -0
  12. package/dist/config/validation.d.ts +130 -0
  13. package/dist/config/validation.d.ts.map +1 -0
  14. package/dist/config/validation.js +53 -0
  15. package/dist/config/validation.js.map +1 -0
  16. package/dist/index.js +443 -1632
  17. package/dist/index.js.map +1 -1
  18. package/dist/integrations/calendar-event-creator.d.ts +2 -3
  19. package/dist/integrations/calendar-event-creator.d.ts.map +1 -1
  20. package/dist/integrations/calendar-event-creator.js +3 -4
  21. package/dist/integrations/calendar-event-creator.js.map +1 -1
  22. package/dist/integrations/calendar-event-deleter.d.ts +2 -3
  23. package/dist/integrations/calendar-event-deleter.d.ts.map +1 -1
  24. package/dist/integrations/calendar-event-deleter.js +3 -4
  25. package/dist/integrations/calendar-event-deleter.js.map +1 -1
  26. package/dist/integrations/calendar-event-response.d.ts +4 -17
  27. package/dist/integrations/calendar-event-response.d.ts.map +1 -1
  28. package/dist/integrations/calendar-event-response.js +3 -4
  29. package/dist/integrations/calendar-event-response.js.map +1 -1
  30. package/dist/integrations/calendar-service.d.ts +6 -3
  31. package/dist/integrations/calendar-service.d.ts.map +1 -1
  32. package/dist/integrations/calendar-service.js +26 -4
  33. package/dist/integrations/calendar-service.js.map +1 -1
  34. package/dist/integrations/calendar-source-manager.d.ts +302 -0
  35. package/dist/integrations/calendar-source-manager.d.ts.map +1 -0
  36. package/dist/integrations/calendar-source-manager.js +862 -0
  37. package/dist/integrations/calendar-source-manager.js.map +1 -0
  38. package/dist/integrations/google-calendar-service.d.ts +176 -0
  39. package/dist/integrations/google-calendar-service.d.ts.map +1 -0
  40. package/dist/integrations/google-calendar-service.js +745 -0
  41. package/dist/integrations/google-calendar-service.js.map +1 -0
  42. package/dist/integrations/notion-mcp.d.ts +28 -3
  43. package/dist/integrations/notion-mcp.d.ts.map +1 -1
  44. package/dist/integrations/notion-mcp.js +21 -5
  45. package/dist/integrations/notion-mcp.js.map +1 -1
  46. package/dist/integrations/reminder-manager.d.ts.map +1 -1
  47. package/dist/integrations/reminder-manager.js +2 -0
  48. package/dist/integrations/reminder-manager.js.map +1 -1
  49. package/dist/oauth/google-oauth-handler.d.ts +149 -0
  50. package/dist/oauth/google-oauth-handler.d.ts.map +1 -0
  51. package/dist/oauth/google-oauth-handler.js +365 -0
  52. package/dist/oauth/google-oauth-handler.js.map +1 -0
  53. package/dist/services/container.d.ts +56 -0
  54. package/dist/services/container.d.ts.map +1 -0
  55. package/dist/services/container.js +76 -0
  56. package/dist/services/container.js.map +1 -0
  57. package/dist/tools/calendar/handlers.d.ts +186 -0
  58. package/dist/tools/calendar/handlers.d.ts.map +1 -0
  59. package/dist/tools/calendar/handlers.js +525 -0
  60. package/dist/tools/calendar/handlers.js.map +1 -0
  61. package/dist/tools/calendar/index.d.ts +11 -0
  62. package/dist/tools/calendar/index.d.ts.map +1 -0
  63. package/dist/tools/calendar/index.js +10 -0
  64. package/dist/tools/calendar/index.js.map +1 -0
  65. package/dist/tools/index.d.ts +23 -0
  66. package/dist/tools/index.d.ts.map +1 -0
  67. package/dist/tools/index.js +24 -0
  68. package/dist/tools/index.js.map +1 -0
  69. package/dist/tools/integrations/handlers.d.ts +57 -0
  70. package/dist/tools/integrations/handlers.d.ts.map +1 -0
  71. package/dist/tools/integrations/handlers.js +159 -0
  72. package/dist/tools/integrations/handlers.js.map +1 -0
  73. package/dist/tools/integrations/index.d.ts +11 -0
  74. package/dist/tools/integrations/index.d.ts.map +1 -0
  75. package/dist/tools/integrations/index.js +10 -0
  76. package/dist/tools/integrations/index.js.map +1 -0
  77. package/dist/tools/registry.d.ts +8 -0
  78. package/dist/tools/registry.d.ts.map +1 -0
  79. package/dist/tools/registry.js +10 -0
  80. package/dist/tools/registry.js.map +1 -0
  81. package/dist/tools/reminders/handlers.d.ts +61 -0
  82. package/dist/tools/reminders/handlers.d.ts.map +1 -0
  83. package/dist/tools/reminders/handlers.js +148 -0
  84. package/dist/tools/reminders/handlers.js.map +1 -0
  85. package/dist/tools/reminders/index.d.ts +11 -0
  86. package/dist/tools/reminders/index.d.ts.map +1 -0
  87. package/dist/tools/reminders/index.js +10 -0
  88. package/dist/tools/reminders/index.js.map +1 -0
  89. package/dist/tools/setup/handlers.d.ts +81 -0
  90. package/dist/tools/setup/handlers.d.ts.map +1 -0
  91. package/dist/tools/setup/handlers.js +172 -0
  92. package/dist/tools/setup/handlers.js.map +1 -0
  93. package/dist/tools/setup/index.d.ts +11 -0
  94. package/dist/tools/setup/index.d.ts.map +1 -0
  95. package/dist/tools/setup/index.js +10 -0
  96. package/dist/tools/setup/index.js.map +1 -0
  97. package/dist/tools/tasks/handlers.d.ts +95 -0
  98. package/dist/tools/tasks/handlers.d.ts.map +1 -0
  99. package/dist/tools/tasks/handlers.js +197 -0
  100. package/dist/tools/tasks/handlers.js.map +1 -0
  101. package/dist/tools/tasks/index.d.ts +11 -0
  102. package/dist/tools/tasks/index.d.ts.map +1 -0
  103. package/dist/tools/tasks/index.js +10 -0
  104. package/dist/tools/tasks/index.js.map +1 -0
  105. package/dist/tools/types.d.ts +54 -0
  106. package/dist/tools/types.d.ts.map +1 -0
  107. package/dist/tools/types.js +9 -0
  108. package/dist/tools/types.js.map +1 -0
  109. package/dist/types/calendar.d.ts +41 -0
  110. package/dist/types/calendar.d.ts.map +1 -0
  111. package/dist/types/calendar.js +18 -0
  112. package/dist/types/calendar.js.map +1 -0
  113. package/dist/types/config.d.ts +15 -0
  114. package/dist/types/config.d.ts.map +1 -1
  115. package/dist/types/config.js +21 -0
  116. package/dist/types/config.js.map +1 -1
  117. package/dist/types/google-calendar-types.d.ts +139 -0
  118. package/dist/types/google-calendar-types.d.ts.map +1 -0
  119. package/dist/types/google-calendar-types.js +46 -0
  120. package/dist/types/google-calendar-types.js.map +1 -0
  121. package/dist/types/index.d.ts +1 -0
  122. package/dist/types/index.d.ts.map +1 -1
  123. package/dist/types/index.js +1 -0
  124. package/dist/types/index.js.map +1 -1
  125. package/dist/utils/estimation.d.ts +34 -0
  126. package/dist/utils/estimation.d.ts.map +1 -1
  127. package/dist/utils/estimation.js +38 -1
  128. package/dist/utils/estimation.js.map +1 -1
  129. package/dist/utils/mcp-response.d.ts +89 -0
  130. package/dist/utils/mcp-response.d.ts.map +1 -0
  131. package/dist/utils/mcp-response.js +103 -0
  132. package/dist/utils/mcp-response.js.map +1 -0
  133. package/dist/utils/task-splitter.d.ts +65 -4
  134. package/dist/utils/task-splitter.d.ts.map +1 -1
  135. package/dist/utils/task-splitter.js +69 -5
  136. package/dist/utils/task-splitter.js.map +1 -1
  137. package/dist/version.d.ts +2 -2
  138. package/dist/version.d.ts.map +1 -1
  139. package/dist/version.js +22 -4
  140. package/dist/version.js.map +1 -1
  141. package/package.json +4 -3
  142. package/dist/cli/http-server.d.ts +0 -74
  143. package/dist/cli/http-server.d.ts.map +0 -1
  144. package/dist/cli/http-server.js +0 -407
  145. package/dist/cli/http-server.js.map +0 -1
  146. package/dist/remote/remote-mcp-server.d.ts +0 -244
  147. package/dist/remote/remote-mcp-server.d.ts.map +0 -1
  148. package/dist/remote/remote-mcp-server.js +0 -507
  149. package/dist/remote/remote-mcp-server.js.map +0 -1
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Google OAuth Handler
3
+ * Requirements: 1 (Google Calendar OAuth Authentication)
4
+ *
5
+ * Handles OAuth 2.0 flow for Google Calendar API integration.
6
+ * Uses PKCE (Proof Key for Code Exchange) with S256 method.
7
+ */
8
+ import { google } from 'googleapis';
9
+ import { generateCodeVerifier, generateCodeChallenge } from './pkce.js';
10
+ import { createCipheriv, createDecipheriv, randomBytes, scrypt } from 'crypto';
11
+ import { promisify } from 'util';
12
+ import { readFile, writeFile, mkdir } from 'fs/promises';
13
+ import { join } from 'path';
14
+ import { homedir } from 'os';
15
+ const scryptAsync = promisify(scrypt);
16
+ /**
17
+ * Google Calendar API Scopes
18
+ */
19
+ export const GOOGLE_CALENDAR_SCOPES = [
20
+ 'https://www.googleapis.com/auth/calendar',
21
+ 'https://www.googleapis.com/auth/calendar.readonly',
22
+ ];
23
+ /**
24
+ * Google OAuth Handler Class
25
+ *
26
+ * Manages OAuth 2.0 authentication flow with Google Calendar API.
27
+ * Implements PKCE for enhanced security.
28
+ */
29
+ export class GoogleOAuthHandler {
30
+ codeVerifier = null;
31
+ config;
32
+ encryptionKey;
33
+ tokensStoragePath;
34
+ constructor(config, encryptionKey, userId) {
35
+ this.config = config;
36
+ // Use provided encryption key or generate from environment
37
+ this.encryptionKey = encryptionKey || process.env.SAGE_ENCRYPTION_KEY || 'sage-default-encryption-key-change-me';
38
+ // Store tokens at ~/.sage/google_oauth_tokens_{userId}.enc
39
+ const sageDir = join(homedir(), '.sage');
40
+ const userIdSuffix = userId ? `_${userId}` : '';
41
+ this.tokensStoragePath = join(sageDir, `google_oauth_tokens${userIdSuffix}.enc`);
42
+ }
43
+ /**
44
+ * Create OAuth2Client instance
45
+ */
46
+ createOAuth2Client(redirectUri) {
47
+ return new google.auth.OAuth2(this.config.clientId, this.config.clientSecret, redirectUri || this.config.redirectUri);
48
+ }
49
+ /**
50
+ * Encrypt data using AES-256-GCM
51
+ */
52
+ async encrypt(data) {
53
+ // Derive key from encryption key using scrypt
54
+ const salt = randomBytes(16);
55
+ const key = (await scryptAsync(this.encryptionKey, salt, 32));
56
+ // Generate IV
57
+ const iv = randomBytes(16);
58
+ // Create cipher
59
+ const cipher = createCipheriv('aes-256-gcm', key, iv);
60
+ // Encrypt data
61
+ let encrypted = cipher.update(data, 'utf8', 'hex');
62
+ encrypted += cipher.final('hex');
63
+ // Get auth tag
64
+ const authTag = cipher.getAuthTag();
65
+ // Combine: salt:iv:authTag:encrypted
66
+ return `${salt.toString('hex')}:${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
67
+ }
68
+ /**
69
+ * Decrypt data using AES-256-GCM
70
+ */
71
+ async decrypt(encryptedData) {
72
+ // Split encrypted data
73
+ const parts = encryptedData.split(':');
74
+ if (parts.length !== 4) {
75
+ throw new Error('Invalid encrypted data format');
76
+ }
77
+ const [saltHex, ivHex, authTagHex, encrypted] = parts;
78
+ // Convert from hex
79
+ const salt = Buffer.from(saltHex, 'hex');
80
+ const iv = Buffer.from(ivHex, 'hex');
81
+ const authTag = Buffer.from(authTagHex, 'hex');
82
+ // Derive key from encryption key using scrypt
83
+ const key = (await scryptAsync(this.encryptionKey, salt, 32));
84
+ // Create decipher
85
+ const decipher = createDecipheriv('aes-256-gcm', key, iv);
86
+ decipher.setAuthTag(authTag);
87
+ // Decrypt data
88
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
89
+ decrypted += decipher.final('utf8');
90
+ return decrypted;
91
+ }
92
+ /**
93
+ * Generate authorization URL with PKCE code_challenge
94
+ *
95
+ * Generates a code_verifier and code_challenge (S256), stores the verifier
96
+ * for later token exchange, and returns the authorization URL.
97
+ *
98
+ * @param redirectUri - Redirect URI for OAuth callback
99
+ * @returns Authorization URL for user to visit
100
+ */
101
+ async getAuthorizationUrl(redirectUri) {
102
+ // Generate PKCE parameters
103
+ this.codeVerifier = generateCodeVerifier();
104
+ const codeChallenge = generateCodeChallenge(this.codeVerifier);
105
+ // Create OAuth2 client with redirect URI
106
+ const oauth2Client = this.createOAuth2Client(redirectUri);
107
+ // Generate authorization URL with PKCE
108
+ const authUrl = oauth2Client.generateAuthUrl({
109
+ access_type: 'offline', // Request refresh token
110
+ scope: GOOGLE_CALENDAR_SCOPES,
111
+ code_challenge: codeChallenge,
112
+ code_challenge_method: 'S256',
113
+ prompt: 'consent', // Force consent screen to get refresh token
114
+ });
115
+ return authUrl;
116
+ }
117
+ /**
118
+ * Exchange authorization code for tokens
119
+ *
120
+ * Exchanges the authorization code received from OAuth callback
121
+ * for access and refresh tokens. Uses the stored code_verifier
122
+ * for PKCE verification.
123
+ *
124
+ * @param code - Authorization code from OAuth callback
125
+ * @param redirectUri - Redirect URI (must match authorization request)
126
+ * @returns Google OAuth tokens
127
+ * @throws Error if code_verifier is not found or token exchange fails
128
+ */
129
+ async exchangeCodeForTokens(code, redirectUri) {
130
+ if (!this.codeVerifier) {
131
+ throw new Error('code_verifier not found. Call getAuthorizationUrl() first.');
132
+ }
133
+ // Create OAuth2 client with redirect URI
134
+ const oauth2Client = this.createOAuth2Client(redirectUri);
135
+ try {
136
+ // Exchange code for tokens with PKCE verifier
137
+ const { tokens } = await oauth2Client.getToken({
138
+ code,
139
+ codeVerifier: this.codeVerifier,
140
+ });
141
+ // Clear stored code_verifier
142
+ this.codeVerifier = null;
143
+ if (!tokens.access_token || !tokens.refresh_token) {
144
+ throw new Error('Failed to retrieve access_token or refresh_token');
145
+ }
146
+ return {
147
+ accessToken: tokens.access_token,
148
+ refreshToken: tokens.refresh_token,
149
+ expiresAt: tokens.expiry_date || Date.now() + 3600 * 1000,
150
+ scope: tokens.scope ? tokens.scope.split(' ') : GOOGLE_CALENDAR_SCOPES,
151
+ };
152
+ }
153
+ catch (error) {
154
+ // Clear code_verifier on error
155
+ this.codeVerifier = null;
156
+ throw new Error(`Failed to exchange code for tokens: ${error instanceof Error ? error.message : 'Unknown error'}`);
157
+ }
158
+ }
159
+ /**
160
+ * Refresh access token using refresh token
161
+ *
162
+ * @param refreshToken - Refresh token
163
+ * @returns Updated Google OAuth tokens
164
+ * @throws Error if token refresh fails
165
+ */
166
+ async refreshAccessToken(refreshToken) {
167
+ const oauth2Client = this.createOAuth2Client();
168
+ try {
169
+ // Set refresh token
170
+ oauth2Client.setCredentials({
171
+ refresh_token: refreshToken,
172
+ });
173
+ // Refresh access token
174
+ const { credentials } = await oauth2Client.refreshAccessToken();
175
+ if (!credentials.access_token) {
176
+ throw new Error('Failed to refresh access_token');
177
+ }
178
+ return {
179
+ accessToken: credentials.access_token,
180
+ refreshToken: credentials.refresh_token || refreshToken,
181
+ expiresAt: credentials.expiry_date || Date.now() + 3600 * 1000,
182
+ scope: credentials.scope ? credentials.scope.split(' ') : GOOGLE_CALENDAR_SCOPES,
183
+ };
184
+ }
185
+ catch (error) {
186
+ throw new Error(`Failed to refresh access token: ${error instanceof Error ? error.message : 'Unknown error'}`);
187
+ }
188
+ }
189
+ /**
190
+ * Revoke access token
191
+ *
192
+ * @param accessToken - Access token to revoke
193
+ * @throws Error if token revocation fails
194
+ */
195
+ async revokeToken(accessToken) {
196
+ const oauth2Client = this.createOAuth2Client();
197
+ try {
198
+ await oauth2Client.revokeToken(accessToken);
199
+ }
200
+ catch (error) {
201
+ throw new Error(`Failed to revoke token: ${error instanceof Error ? error.message : 'Unknown error'}`);
202
+ }
203
+ }
204
+ /**
205
+ * Store tokens securely with encryption
206
+ *
207
+ * Encrypts tokens using AES-256-GCM and stores them in ~/.sage/google_oauth_tokens_{userId}.enc
208
+ *
209
+ * @param tokens - Google OAuth tokens to store
210
+ * @throws Error if token storage fails
211
+ */
212
+ async storeTokens(tokens) {
213
+ try {
214
+ // Convert to stored format
215
+ const storedTokens = {
216
+ accessToken: tokens.accessToken,
217
+ refreshToken: tokens.refreshToken,
218
+ expiresAt: new Date(tokens.expiresAt).toISOString(),
219
+ scope: tokens.scope,
220
+ };
221
+ // Encrypt tokens
222
+ const tokensJson = JSON.stringify(storedTokens);
223
+ const encrypted = await this.encrypt(tokensJson);
224
+ // Ensure ~/.sage directory exists
225
+ const sageDir = join(homedir(), '.sage');
226
+ await mkdir(sageDir, { recursive: true });
227
+ // Write encrypted tokens to file
228
+ await writeFile(this.tokensStoragePath, encrypted, 'utf8');
229
+ }
230
+ catch (error) {
231
+ throw new Error(`Failed to store tokens: ${error instanceof Error ? error.message : 'Unknown error'}`);
232
+ }
233
+ }
234
+ /**
235
+ * Get stored tokens with decryption
236
+ *
237
+ * Reads and decrypts tokens from ~/.sage/google_oauth_tokens_{userId}.enc
238
+ *
239
+ * @returns Google OAuth tokens or null if not found
240
+ * @throws Error if token retrieval or decryption fails
241
+ */
242
+ async getTokens() {
243
+ try {
244
+ // Read encrypted tokens from file
245
+ const encrypted = await readFile(this.tokensStoragePath, 'utf8');
246
+ // Decrypt tokens
247
+ const tokensJson = await this.decrypt(encrypted);
248
+ const storedTokens = JSON.parse(tokensJson);
249
+ // Convert to GoogleOAuthTokens format
250
+ return {
251
+ accessToken: storedTokens.accessToken,
252
+ refreshToken: storedTokens.refreshToken,
253
+ expiresAt: new Date(storedTokens.expiresAt).getTime(),
254
+ scope: storedTokens.scope,
255
+ };
256
+ }
257
+ catch (error) {
258
+ // Return null if file not found (user hasn't authenticated yet)
259
+ if (error.code === 'ENOENT') {
260
+ return null;
261
+ }
262
+ throw new Error(`Failed to get tokens: ${error instanceof Error ? error.message : 'Unknown error'}`);
263
+ }
264
+ }
265
+ /**
266
+ * Revoke tokens and clear local storage
267
+ *
268
+ * Calls Google's token revocation endpoint AND removes locally stored tokens
269
+ *
270
+ * @throws Error if token revocation fails
271
+ */
272
+ async revokeTokens() {
273
+ try {
274
+ // Get current tokens
275
+ const tokens = await this.getTokens();
276
+ if (tokens) {
277
+ // Revoke token at Google
278
+ await this.revokeToken(tokens.accessToken);
279
+ }
280
+ // Clear local storage (remove file)
281
+ const fs = await import('fs/promises');
282
+ try {
283
+ await fs.unlink(this.tokensStoragePath);
284
+ }
285
+ catch (error) {
286
+ // Ignore if file doesn't exist
287
+ if (error.code !== 'ENOENT') {
288
+ throw error;
289
+ }
290
+ }
291
+ }
292
+ catch (error) {
293
+ throw new Error(`Failed to revoke tokens: ${error instanceof Error ? error.message : 'Unknown error'}`);
294
+ }
295
+ }
296
+ /**
297
+ * Validate access token
298
+ *
299
+ * Checks if the access token is valid and not expired (or expiring soon).
300
+ * Token is considered expiring if it expires within 5 minutes.
301
+ *
302
+ * @param tokens - Google OAuth tokens to validate
303
+ * @returns True if token is valid and not expiring soon
304
+ */
305
+ async validateToken(tokens) {
306
+ // Check if expiresAt timestamp is in the future
307
+ const now = Date.now();
308
+ const fiveMinutesInMs = 5 * 60 * 1000;
309
+ // Token is valid if it expires more than 5 minutes from now
310
+ return tokens.expiresAt > now + fiveMinutesInMs;
311
+ }
312
+ /**
313
+ * Ensure valid token
314
+ *
315
+ * Gets stored tokens, validates expiry, refreshes if needed,
316
+ * stores updated tokens, and returns valid access token.
317
+ * This method should be called before each Google Calendar API call.
318
+ *
319
+ * @returns Valid access token
320
+ * @throws Error if no tokens found or refresh fails
321
+ */
322
+ async ensureValidToken() {
323
+ // 1. Get stored tokens
324
+ const tokens = await this.getTokens();
325
+ if (!tokens) {
326
+ throw new Error('No stored tokens found. Please authenticate with Google Calendar first.');
327
+ }
328
+ // 2. Validate expiry
329
+ const isValid = await this.validateToken(tokens);
330
+ // 3. Refresh if needed
331
+ if (!isValid) {
332
+ try {
333
+ const refreshedTokens = await this.refreshAccessToken(tokens.refreshToken);
334
+ // 4. Store updated tokens
335
+ await this.storeTokens(refreshedTokens);
336
+ // 5. Return valid access token
337
+ return refreshedTokens.accessToken;
338
+ }
339
+ catch (error) {
340
+ throw new Error(`Failed to refresh expired token: ${error instanceof Error ? error.message : 'Unknown error'}`);
341
+ }
342
+ }
343
+ // 5. Return valid access token (no refresh needed)
344
+ return tokens.accessToken;
345
+ }
346
+ /**
347
+ * Get OAuth2 client instance
348
+ *
349
+ * Returns the configured OAuth2Client for use in Google API calls.
350
+ *
351
+ * @param tokens - Google OAuth tokens
352
+ * @returns Configured OAuth2Client
353
+ */
354
+ getOAuth2Client(tokens) {
355
+ const client = new google.auth.OAuth2(this.config.clientId, this.config.clientSecret, this.config.redirectUri);
356
+ client.setCredentials({
357
+ access_token: tokens.accessToken,
358
+ refresh_token: tokens.refreshToken,
359
+ expiry_date: tokens.expiresAt,
360
+ scope: tokens.scope.join(' '),
361
+ });
362
+ return client;
363
+ }
364
+ }
365
+ //# sourceMappingURL=google-oauth-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-oauth-handler.js","sourceRoot":"","sources":["../../src/oauth/google-oauth-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Service Container
3
+ *
4
+ * Manages service lifecycle and provides type-safe access to services.
5
+ * Services are lazily initialized on first access after config is loaded.
6
+ */
7
+ import type { UserConfig } from '../types/index.js';
8
+ /**
9
+ * Service initialization status
10
+ */
11
+ export type ServiceStatus = 'uninitialized' | 'initializing' | 'ready' | 'error';
12
+ /**
13
+ * Service container state
14
+ *
15
+ * Tracks which services have been initialized and their current status.
16
+ */
17
+ export interface ServiceContainerState {
18
+ status: ServiceStatus;
19
+ config: UserConfig | null;
20
+ error?: Error;
21
+ }
22
+ /**
23
+ * Creates a service getter that lazily initializes the service
24
+ *
25
+ * @param initializer - Function that creates the service instance
26
+ * @returns Getter function that returns the service or null if not initialized
27
+ *
28
+ * @example
29
+ * const getCalendarService = createLazyService(() => new CalendarService());
30
+ * // Later, when needed:
31
+ * const service = getCalendarService();
32
+ */
33
+ export declare function createLazyService<T>(initializer: () => T): () => T | null;
34
+ /**
35
+ * Creates a service getter that requires config
36
+ *
37
+ * @param initializer - Function that creates the service with config
38
+ * @returns Getter function that accepts config and returns the service
39
+ *
40
+ * @example
41
+ * const getReminderManager = createConfiguredService(
42
+ * (config) => new ReminderManager({ ... })
43
+ * );
44
+ * // Later, when config is available:
45
+ * const manager = getReminderManager(userConfig);
46
+ */
47
+ export declare function createConfiguredService<T>(initializer: (config: UserConfig) => T): (config: UserConfig) => T | null;
48
+ /**
49
+ * Resets a lazy service to uninitialized state
50
+ *
51
+ * Useful for testing or when config changes require service re-initialization.
52
+ *
53
+ * @param resetter - Function that resets the service state
54
+ */
55
+ export declare function resetLazyService(resetter: () => void): void;
56
+ //# sourceMappingURL=container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/services/container.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,cAAc,GAAG,OAAO,GAAG,OAAO,CAAC;AAEjF;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,WAAW,EAAE,MAAM,CAAC,GACnB,MAAM,CAAC,GAAG,IAAI,CAgBhB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,GACrC,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,GAAG,IAAI,CAiBlC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAE3D"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Service Container
3
+ *
4
+ * Manages service lifecycle and provides type-safe access to services.
5
+ * Services are lazily initialized on first access after config is loaded.
6
+ */
7
+ /**
8
+ * Creates a service getter that lazily initializes the service
9
+ *
10
+ * @param initializer - Function that creates the service instance
11
+ * @returns Getter function that returns the service or null if not initialized
12
+ *
13
+ * @example
14
+ * const getCalendarService = createLazyService(() => new CalendarService());
15
+ * // Later, when needed:
16
+ * const service = getCalendarService();
17
+ */
18
+ export function createLazyService(initializer) {
19
+ let instance = null;
20
+ let initialized = false;
21
+ return () => {
22
+ if (!initialized) {
23
+ try {
24
+ instance = initializer();
25
+ initialized = true;
26
+ }
27
+ catch (error) {
28
+ console.error('Failed to initialize service:', error);
29
+ return null;
30
+ }
31
+ }
32
+ return instance;
33
+ };
34
+ }
35
+ /**
36
+ * Creates a service getter that requires config
37
+ *
38
+ * @param initializer - Function that creates the service with config
39
+ * @returns Getter function that accepts config and returns the service
40
+ *
41
+ * @example
42
+ * const getReminderManager = createConfiguredService(
43
+ * (config) => new ReminderManager({ ... })
44
+ * );
45
+ * // Later, when config is available:
46
+ * const manager = getReminderManager(userConfig);
47
+ */
48
+ export function createConfiguredService(initializer) {
49
+ let instance = null;
50
+ let initializedWithConfig = null;
51
+ return (config) => {
52
+ // Re-initialize if config changed
53
+ if (!instance || initializedWithConfig !== config) {
54
+ try {
55
+ instance = initializer(config);
56
+ initializedWithConfig = config;
57
+ }
58
+ catch (error) {
59
+ console.error('Failed to initialize configured service:', error);
60
+ return null;
61
+ }
62
+ }
63
+ return instance;
64
+ };
65
+ }
66
+ /**
67
+ * Resets a lazy service to uninitialized state
68
+ *
69
+ * Useful for testing or when config changes require service re-initialization.
70
+ *
71
+ * @param resetter - Function that resets the service state
72
+ */
73
+ export function resetLazyService(resetter) {
74
+ resetter();
75
+ }
76
+ //# sourceMappingURL=container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/services/container.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,WAAoB;IAEpB,IAAI,QAAQ,GAAa,IAAI,CAAC;IAC9B,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,QAAQ,GAAG,WAAW,EAAE,CAAC;gBACzB,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;gBACtD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CACrC,WAAsC;IAEtC,IAAI,QAAQ,GAAa,IAAI,CAAC;IAC9B,IAAI,qBAAqB,GAAsB,IAAI,CAAC;IAEpD,OAAO,CAAC,MAAkB,EAAE,EAAE;QAC5B,kCAAkC;QAClC,IAAI,CAAC,QAAQ,IAAI,qBAAqB,KAAK,MAAM,EAAE,CAAC;YAClD,IAAI,CAAC;gBACH,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;gBAC/B,qBAAqB,GAAG,MAAM,CAAC;YACjC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;gBACjE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAoB;IACnD,QAAQ,EAAE,CAAC;AACb,CAAC"}