@vybestack/llxprt-code-core 0.1.18-nightly.250807.306d1939 → 0.1.18-nightly.250811.b0db22c6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/src/auth/auth-integration.spec.d.ts +6 -0
- package/dist/src/auth/auth-integration.spec.js +384 -0
- package/dist/src/auth/auth-integration.spec.js.map +1 -0
- package/dist/src/auth/precedence.d.ts +55 -0
- package/dist/src/auth/precedence.js +211 -0
- package/dist/src/auth/precedence.js.map +1 -0
- package/dist/src/auth/precedence.test.d.ts +6 -0
- package/dist/src/auth/precedence.test.js +374 -0
- package/dist/src/auth/precedence.test.js.map +1 -0
- package/dist/src/auth/qwen-device-flow.d.ts +45 -0
- package/dist/src/auth/qwen-device-flow.js +179 -0
- package/dist/src/auth/qwen-device-flow.js.map +1 -0
- package/dist/src/auth/qwen-device-flow.spec.d.ts +6 -0
- package/dist/src/auth/qwen-device-flow.spec.js +793 -0
- package/dist/src/auth/qwen-device-flow.spec.js.map +1 -0
- package/dist/src/auth/token-store.d.ts +66 -0
- package/dist/src/auth/token-store.js +147 -0
- package/dist/src/auth/token-store.js.map +1 -0
- package/dist/src/auth/token-store.spec.d.ts +6 -0
- package/dist/src/auth/token-store.spec.js +405 -0
- package/dist/src/auth/token-store.spec.js.map +1 -0
- package/dist/src/auth/types.d.ts +130 -0
- package/dist/src/auth/types.js +60 -0
- package/dist/src/auth/types.js.map +1 -0
- package/dist/src/code_assist/converter.d.ts +2 -1
- package/dist/src/code_assist/converter.js +1 -1
- package/dist/src/code_assist/converter.js.map +1 -1
- package/dist/src/code_assist/converter.test.js +48 -1
- package/dist/src/code_assist/converter.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.js +2 -1
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/server.test.js +4 -1
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/config/config.alwaysAllow.test.d.ts +6 -0
- package/dist/src/config/config.alwaysAllow.test.js +84 -0
- package/dist/src/config/config.alwaysAllow.test.js.map +1 -0
- package/dist/src/config/config.d.ts +80 -1
- package/dist/src/config/config.ephemeral.test.d.ts +6 -0
- package/dist/src/config/config.ephemeral.test.js +152 -0
- package/dist/src/config/config.ephemeral.test.js.map +1 -0
- package/dist/src/config/config.js +135 -0
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +8 -0
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/endpoints.d.ts +60 -0
- package/dist/src/config/endpoints.js +126 -0
- package/dist/src/config/endpoints.js.map +1 -0
- package/dist/src/config/endpoints.test.d.ts +6 -0
- package/dist/src/config/endpoints.test.js +196 -0
- package/dist/src/config/endpoints.test.js.map +1 -0
- package/dist/src/core/client.d.ts +0 -2
- package/dist/src/core/client.js +19 -97
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +13 -7
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +3 -1
- package/dist/src/core/contentGenerator.js +3 -1
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +17 -7
- package/dist/src/core/coreToolScheduler.js +121 -18
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +25 -37
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +3 -0
- package/dist/src/core/geminiChat.js +17 -13
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/logger.d.ts +1 -0
- package/dist/src/core/logger.js +18 -0
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/logger.test.js +29 -0
- package/dist/src/core/logger.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.d.ts +24 -0
- package/dist/src/core/loggingContentGenerator.js +89 -0
- package/dist/src/core/loggingContentGenerator.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.js +21 -1
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +8 -31
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/subagent.d.ts +230 -0
- package/dist/src/core/subagent.js +455 -0
- package/dist/src/core/subagent.js.map +1 -0
- package/dist/src/core/subagent.test.d.ts +6 -0
- package/dist/src/core/subagent.test.js +510 -0
- package/dist/src/core/subagent.test.js.map +1 -0
- package/dist/src/hooks/tool-render-suppression-hook.d.ts +16 -0
- package/dist/src/hooks/tool-render-suppression-hook.js +26 -0
- package/dist/src/hooks/tool-render-suppression-hook.js.map +1 -0
- package/dist/src/hooks/tool-render-suppression-hook.test.d.ts +6 -0
- package/dist/src/hooks/tool-render-suppression-hook.test.js +59 -0
- package/dist/src/hooks/tool-render-suppression-hook.test.js.map +1 -0
- package/dist/src/ide/ide-client.d.ts +22 -1
- package/dist/src/ide/ide-client.js +161 -17
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ideContext.d.ts +127 -32
- package/dist/src/ide/ideContext.js +45 -0
- package/dist/src/ide/ideContext.js.map +1 -1
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +10 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/integration-tests/oauth-integration.spec.d.ts +6 -0
- package/dist/src/integration-tests/oauth-integration.spec.js +518 -0
- package/dist/src/integration-tests/oauth-integration.spec.js.map +1 -0
- package/dist/src/integration-tests/oauth-simple-test.spec.d.ts +1 -0
- package/dist/src/integration-tests/oauth-simple-test.spec.js +88 -0
- package/dist/src/integration-tests/oauth-simple-test.spec.js.map +1 -0
- package/dist/src/integration-tests/todo-system.test.js +38 -602
- package/dist/src/integration-tests/todo-system.test.js.map +1 -1
- package/dist/src/providers/BaseProvider.d.ts +98 -0
- package/dist/src/providers/BaseProvider.js +180 -0
- package/dist/src/providers/BaseProvider.js.map +1 -0
- package/dist/src/providers/BaseProvider.test.d.ts +6 -0
- package/dist/src/providers/BaseProvider.test.js +472 -0
- package/dist/src/providers/BaseProvider.test.js.map +1 -0
- package/dist/src/providers/IProviderManager.d.ts +5 -0
- package/dist/src/providers/LoggingProviderWrapper.d.ts +53 -0
- package/dist/src/providers/LoggingProviderWrapper.js +347 -0
- package/dist/src/providers/LoggingProviderWrapper.js.map +1 -0
- package/dist/src/providers/ProviderManager.d.ts +20 -0
- package/dist/src/providers/ProviderManager.js +214 -1
- package/dist/src/providers/ProviderManager.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.d.ts +12 -7
- package/dist/src/providers/gemini/GeminiProvider.js +135 -152
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
- package/dist/src/providers/integration/multi-provider.integration.test.js +18 -2
- package/dist/src/providers/integration/multi-provider.integration.test.js.map +1 -1
- package/dist/src/providers/logging/ProviderContentExtractor.d.ts +27 -0
- package/dist/src/providers/logging/ProviderContentExtractor.js +198 -0
- package/dist/src/providers/logging/ProviderContentExtractor.js.map +1 -0
- package/dist/src/providers/logging/ProviderPerformanceTracker.d.ts +43 -0
- package/dist/src/providers/logging/ProviderPerformanceTracker.js +98 -0
- package/dist/src/providers/logging/ProviderPerformanceTracker.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.d.ts +21 -6
- package/dist/src/providers/openai/OpenAIProvider.js +180 -27
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/providers/openai/OpenAIProvider.test.js +109 -2
- package/dist/src/providers/openai/OpenAIProvider.test.js.map +1 -1
- package/dist/src/providers/openai/openai-oauth.spec.d.ts +16 -0
- package/dist/src/providers/openai/openai-oauth.spec.js +544 -0
- package/dist/src/providers/openai/openai-oauth.spec.js.map +1 -0
- package/dist/src/providers/types/IProviderConfig.d.ts +5 -0
- package/dist/src/providers/types.d.ts +47 -0
- package/dist/src/services/git-stats-service.d.ts +32 -0
- package/dist/src/services/git-stats-service.js +22 -0
- package/dist/src/services/git-stats-service.js.map +1 -0
- package/dist/src/services/loopDetectionService.js +10 -6
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +139 -0
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.js +69 -9
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +8 -0
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/services/todo-context-tracker.d.ts +31 -0
- package/dist/src/services/todo-context-tracker.js +45 -0
- package/dist/src/services/todo-context-tracker.js.map +1 -0
- package/dist/src/services/tool-call-tracker-service.d.ts +52 -0
- package/dist/src/services/tool-call-tracker-service.js +170 -0
- package/dist/src/services/tool-call-tracker-service.js.map +1 -0
- package/dist/src/services/tool-call-tracker-service.test.d.ts +6 -0
- package/dist/src/services/tool-call-tracker-service.test.js +99 -0
- package/dist/src/services/tool-call-tracker-service.test.js.map +1 -0
- package/dist/src/storage/ConversationFileWriter.d.ts +16 -0
- package/dist/src/storage/ConversationFileWriter.js +69 -0
- package/dist/src/storage/ConversationFileWriter.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +8 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +56 -3
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +6 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +187 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +5 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +11 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/constants.d.ts +5 -0
- package/dist/src/telemetry/constants.js +5 -0
- package/dist/src/telemetry/constants.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +5 -1
- package/dist/src/telemetry/loggers.js +87 -1
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.circular.js +7 -2
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +7 -2
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +3 -2
- package/dist/src/telemetry/metrics.js +7 -1
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +50 -0
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/tool-call-decision.d.ts +13 -0
- package/dist/src/telemetry/tool-call-decision.js +29 -0
- package/dist/src/telemetry/tool-call-decision.js.map +1 -0
- package/dist/src/telemetry/types.d.ts +58 -2
- package/dist/src/telemetry/types.js +126 -1
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +4 -1
- package/dist/src/telemetry/uiTelemetry.js +3 -1
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +13 -2
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/test-utils/tools.d.ts +23 -0
- package/dist/src/test-utils/tools.js +41 -0
- package/dist/src/test-utils/tools.js.map +1 -0
- package/dist/src/tools/diffOptions.d.ts +2 -0
- package/dist/src/tools/diffOptions.js +28 -0
- package/dist/src/tools/diffOptions.js.map +1 -1
- package/dist/src/tools/diffOptions.test.d.ts +6 -0
- package/dist/src/tools/diffOptions.test.js +119 -0
- package/dist/src/tools/diffOptions.test.js.map +1 -0
- package/dist/src/tools/edit.d.ts +9 -33
- package/dist/src/tools/edit.js +167 -132
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +124 -50
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +3 -10
- package/dist/src/tools/glob.js +97 -99
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +37 -26
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.d.ts +3 -35
- package/dist/src/tools/grep.js +117 -88
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +36 -22
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +14 -3
- package/dist/src/tools/mcp-client.js +82 -6
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +337 -2
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +2 -2
- package/dist/src/tools/memoryTool.js +1 -0
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.d.ts +8 -5
- package/dist/src/tools/modifiable-tool.js +4 -1
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.test.js +3 -3
- package/dist/src/tools/modifiable-tool.test.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +4 -6
- package/dist/src/tools/read-file.js +87 -46
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +207 -126
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.js +8 -2
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +16 -0
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/shell.test.js +17 -0
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/todo-events.d.ts +22 -0
- package/dist/src/tools/todo-events.js +24 -0
- package/dist/src/tools/todo-events.js.map +1 -0
- package/dist/src/tools/todo-pause.d.ts +22 -0
- package/dist/src/tools/todo-pause.js +93 -0
- package/dist/src/tools/todo-pause.js.map +1 -0
- package/dist/src/tools/todo-pause.spec.d.ts +6 -0
- package/dist/src/tools/todo-pause.spec.js +287 -0
- package/dist/src/tools/todo-pause.spec.js.map +1 -0
- package/dist/src/tools/todo-read.js.map +1 -1
- package/dist/src/tools/todo-schemas.d.ts +232 -4
- package/dist/src/tools/todo-schemas.js +13 -0
- package/dist/src/tools/todo-schemas.js.map +1 -1
- package/dist/src/tools/todo-schemas.test.js +190 -1
- package/dist/src/tools/todo-schemas.test.js.map +1 -1
- package/dist/src/tools/todo-store.d.ts +1 -4
- package/dist/src/tools/todo-store.js +41 -40
- package/dist/src/tools/todo-store.js.map +1 -1
- package/dist/src/tools/todo-store.test.js +34 -40
- package/dist/src/tools/todo-store.test.js.map +1 -1
- package/dist/src/tools/todo-write.d.ts +1 -1
- package/dist/src/tools/todo-write.js +84 -47
- package/dist/src/tools/todo-write.js.map +1 -1
- package/dist/src/tools/todo-write.test.js +23 -9
- package/dist/src/tools/todo-write.test.js.map +1 -1
- package/dist/src/tools/tool-context.d.ts +2 -0
- package/dist/src/tools/tool-error.d.ts +4 -0
- package/dist/src/tools/tool-error.js +4 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +12 -6
- package/dist/src/tools/tool-registry.js +19 -4
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +3 -20
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +134 -39
- package/dist/src/tools/tools.js +115 -10
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-search.test.js +1 -0
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +6 -2
- package/dist/src/tools/write-file.js +106 -16
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +25 -7
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/types/modelParams.d.ts +4 -0
- package/dist/src/utils/environmentContext.d.ts +21 -0
- package/dist/src/utils/environmentContext.js +90 -0
- package/dist/src/utils/environmentContext.js.map +1 -0
- package/dist/src/utils/environmentContext.test.d.ts +6 -0
- package/dist/src/utils/environmentContext.test.js +139 -0
- package/dist/src/utils/environmentContext.test.js.map +1 -0
- package/dist/src/utils/errors.d.ts +3 -0
- package/dist/src/utils/errors.js +6 -0
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/fileUtils.d.ts +7 -0
- package/dist/src/utils/fileUtils.js +11 -10
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +1 -4
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.d.ts +1 -0
- package/dist/src/utils/filesearch/fileSearch.js +27 -5
- package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.test.js +21 -1
- package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +4 -1
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/shell-utils.js +14 -2
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.shellReplacement.test.d.ts +6 -0
- package/dist/src/utils/shell-utils.shellReplacement.test.js +149 -0
- package/dist/src/utils/shell-utils.shellReplacement.test.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
7
|
+
import { promises as fs } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { tmpdir } from 'os';
|
|
10
|
+
import { MultiProviderTokenStore } from './token-store.js';
|
|
11
|
+
describe('MultiProviderTokenStore - Behavioral Tests', () => {
|
|
12
|
+
let tokenStore;
|
|
13
|
+
let tempDir;
|
|
14
|
+
let originalHome;
|
|
15
|
+
const validQwenToken = {
|
|
16
|
+
access_token: 'qwen-access-token-123',
|
|
17
|
+
refresh_token: 'qwen-refresh-token-456',
|
|
18
|
+
expiry: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
|
|
19
|
+
scope: 'read write',
|
|
20
|
+
token_type: 'Bearer',
|
|
21
|
+
};
|
|
22
|
+
const _validGeminiToken = {
|
|
23
|
+
access_token: 'gemini-access-token-789',
|
|
24
|
+
refresh_token: 'gemini-refresh-token-101',
|
|
25
|
+
expiry: Math.floor(Date.now() / 1000) + 7200, // 2 hours from now
|
|
26
|
+
scope: 'admin',
|
|
27
|
+
token_type: 'Bearer',
|
|
28
|
+
};
|
|
29
|
+
beforeEach(async () => {
|
|
30
|
+
// Create temporary directory for testing
|
|
31
|
+
tempDir = await fs.mkdtemp(join(tmpdir(), 'token-store-test-'));
|
|
32
|
+
// Mock HOME environment to point to temp directory
|
|
33
|
+
originalHome = process.env.HOME;
|
|
34
|
+
process.env.HOME = tempDir;
|
|
35
|
+
tokenStore = new MultiProviderTokenStore();
|
|
36
|
+
});
|
|
37
|
+
afterEach(async () => {
|
|
38
|
+
// Restore original HOME environment
|
|
39
|
+
if (originalHome) {
|
|
40
|
+
process.env.HOME = originalHome;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
delete process.env.HOME;
|
|
44
|
+
}
|
|
45
|
+
// Clean up temp directory
|
|
46
|
+
try {
|
|
47
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Ignore cleanup errors
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
describe('Token CRUD Operations', () => {
|
|
54
|
+
/**
|
|
55
|
+
* @requirement REQ-003.1
|
|
56
|
+
* @scenario Save token for new provider
|
|
57
|
+
* @given Empty token store
|
|
58
|
+
* @when saveToken('qwen', validToken) is called
|
|
59
|
+
* @then Token is persisted to ~/.llxprt/oauth/qwen.json
|
|
60
|
+
* @and File has 0600 permissions
|
|
61
|
+
*/
|
|
62
|
+
it('should save token for new provider with correct file permissions', async () => {
|
|
63
|
+
await tokenStore.saveToken('qwen', validQwenToken);
|
|
64
|
+
// Verify expected behavior when implemented:
|
|
65
|
+
const tokenPath = join(tempDir, '.llxprt', 'oauth', 'qwen.json');
|
|
66
|
+
await fs.access(tokenPath); // File exists
|
|
67
|
+
const stats = await fs.stat(tokenPath);
|
|
68
|
+
expect(stats.mode & 0o777).toBe(0o600); // File permissions are 0600
|
|
69
|
+
const content = JSON.parse(await fs.readFile(tokenPath, 'utf8'));
|
|
70
|
+
expect(content).toEqual(validQwenToken);
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* @requirement REQ-003.1
|
|
74
|
+
* @scenario Retrieve saved token
|
|
75
|
+
* @given Token saved for 'qwen' provider
|
|
76
|
+
* @when getToken('qwen') is called
|
|
77
|
+
* @then Returns the saved token with all fields
|
|
78
|
+
*/
|
|
79
|
+
it('should retrieve saved token with all fields intact', async () => {
|
|
80
|
+
await tokenStore.saveToken('qwen', validQwenToken);
|
|
81
|
+
const retrievedToken = await tokenStore.getToken('qwen');
|
|
82
|
+
expect(retrievedToken).toEqual(validQwenToken);
|
|
83
|
+
expect(retrievedToken?.access_token).toBe('qwen-access-token-123');
|
|
84
|
+
expect(retrievedToken?.refresh_token).toBe('qwen-refresh-token-456');
|
|
85
|
+
expect(retrievedToken?.expiry).toBe(validQwenToken.expiry);
|
|
86
|
+
expect(retrievedToken?.scope).toBe('read write');
|
|
87
|
+
expect(retrievedToken?.token_type).toBe('Bearer');
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* @requirement REQ-003.3
|
|
91
|
+
* @scenario Token structure validation
|
|
92
|
+
* @given Token with access_token, refresh_token, expiry
|
|
93
|
+
* @when saveToken is called
|
|
94
|
+
* @then All fields are preserved in storage
|
|
95
|
+
*/
|
|
96
|
+
it('should preserve all token fields when saving and retrieving', async () => {
|
|
97
|
+
const complexToken = {
|
|
98
|
+
access_token: 'complex-access-token-with-special-chars!@#$%',
|
|
99
|
+
refresh_token: 'complex-refresh-token-with-unicode-café',
|
|
100
|
+
expiry: 1735689600, // Fixed timestamp for testing
|
|
101
|
+
scope: 'read:user write:repo admin:org',
|
|
102
|
+
token_type: 'Bearer',
|
|
103
|
+
};
|
|
104
|
+
await tokenStore.saveToken('complex', complexToken);
|
|
105
|
+
const retrieved = await tokenStore.getToken('complex');
|
|
106
|
+
expect(retrieved).toEqual(complexToken);
|
|
107
|
+
expect(retrieved?.access_token).toContain('special-chars!@#$%');
|
|
108
|
+
expect(retrieved?.refresh_token).toContain('unicode-café');
|
|
109
|
+
});
|
|
110
|
+
/**
|
|
111
|
+
* @requirement REQ-003.1
|
|
112
|
+
* @scenario Remove provider token
|
|
113
|
+
* @given Token exists for 'qwen'
|
|
114
|
+
* @when removeToken('qwen') called
|
|
115
|
+
* @then File deleted, getToken returns null
|
|
116
|
+
*/
|
|
117
|
+
it('should remove token file and return null on subsequent gets', async () => {
|
|
118
|
+
await tokenStore.saveToken('qwen', validQwenToken);
|
|
119
|
+
await tokenStore.removeToken('qwen');
|
|
120
|
+
const retrieved = await tokenStore.getToken('qwen');
|
|
121
|
+
expect(retrieved).toBeNull();
|
|
122
|
+
const tokenPath = join(tempDir, '.llxprt', 'oauth', 'qwen.json');
|
|
123
|
+
await expect(fs.access(tokenPath)).rejects.toThrow();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
describe('Multi-Provider Scenarios', () => {
|
|
127
|
+
/**
|
|
128
|
+
* @requirement REQ-003.1
|
|
129
|
+
* @scenario Multiple providers coexist
|
|
130
|
+
* @given Tokens saved for 'qwen' and 'gemini'
|
|
131
|
+
* @when getToken('qwen') is called
|
|
132
|
+
* @then Returns only qwen token, gemini unaffected
|
|
133
|
+
*/
|
|
134
|
+
it('should handle multiple providers independently', async () => {
|
|
135
|
+
await tokenStore.saveToken('qwen', validQwenToken);
|
|
136
|
+
await tokenStore.saveToken('gemini', _validGeminiToken);
|
|
137
|
+
const qwenToken = await tokenStore.getToken('qwen');
|
|
138
|
+
const geminiToken = await tokenStore.getToken('gemini');
|
|
139
|
+
expect(qwenToken).toEqual(validQwenToken);
|
|
140
|
+
expect(geminiToken).toEqual(_validGeminiToken);
|
|
141
|
+
expect(qwenToken?.access_token).not.toBe(geminiToken?.access_token);
|
|
142
|
+
});
|
|
143
|
+
/**
|
|
144
|
+
* @requirement REQ-003.1
|
|
145
|
+
* @scenario List all authenticated providers
|
|
146
|
+
* @given Tokens for 'qwen', 'gemini' exist
|
|
147
|
+
* @when listProviders() is called
|
|
148
|
+
* @then Returns ['gemini', 'qwen'] sorted
|
|
149
|
+
*/
|
|
150
|
+
it('should list all providers with stored tokens in sorted order', async () => {
|
|
151
|
+
await tokenStore.saveToken('qwen', validQwenToken);
|
|
152
|
+
await tokenStore.saveToken('gemini', _validGeminiToken);
|
|
153
|
+
await tokenStore.saveToken('anthropic', validQwenToken); // Using same token structure
|
|
154
|
+
const providers = await tokenStore.listProviders();
|
|
155
|
+
expect(providers).toEqual(['anthropic', 'gemini', 'qwen']);
|
|
156
|
+
expect(providers).toHaveLength(3);
|
|
157
|
+
});
|
|
158
|
+
/**
|
|
159
|
+
* @requirement REQ-003.1
|
|
160
|
+
* @scenario Provider isolation
|
|
161
|
+
* @given Multiple providers have tokens
|
|
162
|
+
* @when one provider token is removed
|
|
163
|
+
* @then Other providers remain unaffected
|
|
164
|
+
*/
|
|
165
|
+
it('should maintain provider isolation when removing tokens', async () => {
|
|
166
|
+
await tokenStore.saveToken('qwen', validQwenToken);
|
|
167
|
+
await tokenStore.saveToken('gemini', _validGeminiToken);
|
|
168
|
+
await tokenStore.removeToken('qwen');
|
|
169
|
+
const qwenToken = await tokenStore.getToken('qwen');
|
|
170
|
+
const geminiToken = await tokenStore.getToken('gemini');
|
|
171
|
+
expect(qwenToken).toBeNull();
|
|
172
|
+
expect(geminiToken).toEqual(_validGeminiToken);
|
|
173
|
+
const providers = await tokenStore.listProviders();
|
|
174
|
+
expect(providers).toEqual(['gemini']);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
describe('Security & Permissions', () => {
|
|
178
|
+
/**
|
|
179
|
+
* @requirement REQ-003.2
|
|
180
|
+
* @scenario Secure file permissions
|
|
181
|
+
* @given New token being saved
|
|
182
|
+
* @when saveToken creates file
|
|
183
|
+
* @then File has 0600 (owner read/write only)
|
|
184
|
+
*/
|
|
185
|
+
it('should create token files with secure 0600 permissions', async () => {
|
|
186
|
+
await tokenStore.saveToken('security-test', validQwenToken);
|
|
187
|
+
const tokenPath = join(tempDir, '.llxprt', 'oauth', 'security-test.json');
|
|
188
|
+
const stats = await fs.stat(tokenPath);
|
|
189
|
+
expect(stats.mode & 0o777).toBe(0o600);
|
|
190
|
+
expect(stats.mode & 0o044).toBe(0); // No group/other read
|
|
191
|
+
expect(stats.mode & 0o022).toBe(0); // No group/other write
|
|
192
|
+
});
|
|
193
|
+
/**
|
|
194
|
+
* @requirement REQ-003.4
|
|
195
|
+
* @scenario Correct storage path
|
|
196
|
+
* @given Token for provider 'qwen'
|
|
197
|
+
* @when saved to filesystem
|
|
198
|
+
* @then Path is ~/.llxprt/oauth/qwen.json
|
|
199
|
+
*/
|
|
200
|
+
it('should store tokens in correct ~/.llxprt/oauth/ directory structure', async () => {
|
|
201
|
+
await tokenStore.saveToken('path-test', validQwenToken);
|
|
202
|
+
const expectedPath = join(tempDir, '.llxprt', 'oauth', 'path-test.json');
|
|
203
|
+
await fs.access(expectedPath); // Should not throw
|
|
204
|
+
const content = JSON.parse(await fs.readFile(expectedPath, 'utf8'));
|
|
205
|
+
expect(content).toEqual(validQwenToken);
|
|
206
|
+
});
|
|
207
|
+
/**
|
|
208
|
+
* @requirement REQ-003.2
|
|
209
|
+
* @scenario Directory creation with secure permissions
|
|
210
|
+
* @given ~/.llxprt/oauth directory doesn't exist
|
|
211
|
+
* @when first token is saved
|
|
212
|
+
* @then Directory is created with appropriate permissions
|
|
213
|
+
*/
|
|
214
|
+
it('should create oauth directory structure with secure permissions', async () => {
|
|
215
|
+
await tokenStore.saveToken('dir-test', validQwenToken);
|
|
216
|
+
const oauthDir = join(tempDir, '.llxprt', 'oauth');
|
|
217
|
+
const llxprtDir = join(tempDir, '.llxprt');
|
|
218
|
+
const oauthStats = await fs.stat(oauthDir);
|
|
219
|
+
const llxprtStats = await fs.stat(llxprtDir);
|
|
220
|
+
expect(oauthStats.isDirectory()).toBe(true);
|
|
221
|
+
expect(llxprtStats.isDirectory()).toBe(true);
|
|
222
|
+
expect(oauthStats.mode & 0o777).toBe(0o700); // Directory should be 0700
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
describe('Error Handling', () => {
|
|
226
|
+
/**
|
|
227
|
+
* @requirement REQ-003.1
|
|
228
|
+
* @scenario Get token for unauthenticated provider
|
|
229
|
+
* @given No token exists for 'anthropic'
|
|
230
|
+
* @when getToken('anthropic') is called
|
|
231
|
+
* @then Returns null, no error thrown
|
|
232
|
+
*/
|
|
233
|
+
it('should return null for non-existent provider without throwing error', async () => {
|
|
234
|
+
const token = await tokenStore.getToken('non-existent');
|
|
235
|
+
expect(token).toBeNull();
|
|
236
|
+
});
|
|
237
|
+
/**
|
|
238
|
+
* @requirement REQ-003.2
|
|
239
|
+
* @scenario Handle corrupted token file
|
|
240
|
+
* @given Malformed JSON in token file
|
|
241
|
+
* @when getToken is called
|
|
242
|
+
* @then Returns null and logs warning
|
|
243
|
+
*/
|
|
244
|
+
it('should handle corrupted token files gracefully', async () => {
|
|
245
|
+
// First save a valid token
|
|
246
|
+
await tokenStore.saveToken('corrupted', validQwenToken);
|
|
247
|
+
// Then corrupt the file
|
|
248
|
+
const tokenPath = join(tempDir, '.llxprt', 'oauth', 'corrupted.json');
|
|
249
|
+
await fs.writeFile(tokenPath, '{ invalid json }');
|
|
250
|
+
const token = await tokenStore.getToken('corrupted');
|
|
251
|
+
expect(token).toBeNull();
|
|
252
|
+
});
|
|
253
|
+
/**
|
|
254
|
+
* @requirement REQ-003.1
|
|
255
|
+
* @scenario Remove non-existent token
|
|
256
|
+
* @given No token exists for provider
|
|
257
|
+
* @when removeToken is called
|
|
258
|
+
* @then Operation succeeds silently
|
|
259
|
+
*/
|
|
260
|
+
it('should handle removal of non-existent tokens gracefully', async () => {
|
|
261
|
+
// Should not throw error
|
|
262
|
+
await expect(tokenStore.removeToken('non-existent')).resolves.not.toThrow();
|
|
263
|
+
});
|
|
264
|
+
/**
|
|
265
|
+
* @requirement REQ-003.2
|
|
266
|
+
* @scenario Handle filesystem permission errors
|
|
267
|
+
* @given Filesystem permission restrictions
|
|
268
|
+
* @when attempting to save token
|
|
269
|
+
* @then Throws appropriate error
|
|
270
|
+
*/
|
|
271
|
+
it('should handle filesystem permission errors appropriately', async () => {
|
|
272
|
+
// Create directory with no write permissions
|
|
273
|
+
const restrictedDir = join(tempDir, '.llxprt');
|
|
274
|
+
await fs.mkdir(restrictedDir, { recursive: true });
|
|
275
|
+
await fs.chmod(restrictedDir, 0o444); // Read-only
|
|
276
|
+
await expect(tokenStore.saveToken('permission-test', validQwenToken)).rejects.toThrow();
|
|
277
|
+
await fs.chmod(restrictedDir, 0o755); // Restore permissions for cleanup
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
describe('Token Updates', () => {
|
|
281
|
+
/**
|
|
282
|
+
* @requirement REQ-003.3
|
|
283
|
+
* @scenario Update existing token
|
|
284
|
+
* @given Existing token for 'qwen'
|
|
285
|
+
* @when saveToken with new token called
|
|
286
|
+
* @then Old token replaced completely
|
|
287
|
+
*/
|
|
288
|
+
it('should completely replace existing tokens when saving new ones', async () => {
|
|
289
|
+
const _updatedToken = {
|
|
290
|
+
access_token: 'updated-access-token',
|
|
291
|
+
refresh_token: 'updated-refresh-token',
|
|
292
|
+
expiry: Math.floor(Date.now() / 1000) + 1800, // 30 minutes
|
|
293
|
+
scope: 'limited-scope',
|
|
294
|
+
token_type: 'Bearer',
|
|
295
|
+
};
|
|
296
|
+
await tokenStore.saveToken('qwen', validQwenToken);
|
|
297
|
+
await tokenStore.saveToken('qwen', _updatedToken);
|
|
298
|
+
const retrieved = await tokenStore.getToken('qwen');
|
|
299
|
+
expect(retrieved).toEqual(_updatedToken);
|
|
300
|
+
expect(retrieved?.access_token).toBe('updated-access-token');
|
|
301
|
+
expect(retrieved?.scope).toBe('limited-scope');
|
|
302
|
+
expect(retrieved).not.toEqual(validQwenToken);
|
|
303
|
+
});
|
|
304
|
+
/**
|
|
305
|
+
* @requirement REQ-003.3
|
|
306
|
+
* @scenario Token update preserves file permissions
|
|
307
|
+
* @given Existing token file with 0600 permissions
|
|
308
|
+
* @when token is updated
|
|
309
|
+
* @then File permissions remain 0600
|
|
310
|
+
*/
|
|
311
|
+
it('should preserve secure file permissions when updating tokens', async () => {
|
|
312
|
+
const _updatedToken = {
|
|
313
|
+
access_token: 'permission-update-token',
|
|
314
|
+
expiry: Math.floor(Date.now() / 1000) + 900, // 15 minutes
|
|
315
|
+
token_type: 'Bearer',
|
|
316
|
+
};
|
|
317
|
+
await tokenStore.saveToken('permission-update', validQwenToken);
|
|
318
|
+
await tokenStore.saveToken('permission-update', _updatedToken);
|
|
319
|
+
const tokenPath = join(tempDir, '.llxprt', 'oauth', 'permission-update.json');
|
|
320
|
+
const stats = await fs.stat(tokenPath);
|
|
321
|
+
expect(stats.mode & 0o777).toBe(0o600);
|
|
322
|
+
});
|
|
323
|
+
/**
|
|
324
|
+
* @requirement REQ-003.1
|
|
325
|
+
* @scenario Partial token updates
|
|
326
|
+
* @given Token with optional refresh_token
|
|
327
|
+
* @when saving token without refresh_token
|
|
328
|
+
* @then Only required fields are stored
|
|
329
|
+
*/
|
|
330
|
+
it('should handle tokens with optional fields correctly', async () => {
|
|
331
|
+
const minimalToken = {
|
|
332
|
+
access_token: 'minimal-access-token',
|
|
333
|
+
expiry: Math.floor(Date.now() / 1000) + 600, // 10 minutes
|
|
334
|
+
token_type: 'Bearer',
|
|
335
|
+
// No refresh_token or scope
|
|
336
|
+
};
|
|
337
|
+
await tokenStore.saveToken('minimal', minimalToken);
|
|
338
|
+
const retrieved = await tokenStore.getToken('minimal');
|
|
339
|
+
expect(retrieved).toEqual(minimalToken);
|
|
340
|
+
expect(retrieved?.refresh_token).toBeUndefined();
|
|
341
|
+
expect(retrieved?.scope).toBeUndefined();
|
|
342
|
+
expect(retrieved?.access_token).toBe('minimal-access-token');
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
describe('Provider Name Validation', () => {
|
|
346
|
+
/**
|
|
347
|
+
* @requirement REQ-003.1
|
|
348
|
+
* @scenario Handle special characters in provider names
|
|
349
|
+
* @given Provider name with special characters
|
|
350
|
+
* @when saving token
|
|
351
|
+
* @then Sanitizes filename appropriately
|
|
352
|
+
*/
|
|
353
|
+
it('should handle provider names with special characters', async () => {
|
|
354
|
+
// Test with various special characters that might be problematic in filenames
|
|
355
|
+
const specialProviders = [
|
|
356
|
+
'provider-with-hyphens',
|
|
357
|
+
'provider_with_underscores',
|
|
358
|
+
'provider.with.dots',
|
|
359
|
+
];
|
|
360
|
+
for (const provider of specialProviders) {
|
|
361
|
+
await tokenStore.saveToken(provider, validQwenToken);
|
|
362
|
+
const retrieved = await tokenStore.getToken(provider);
|
|
363
|
+
expect(retrieved).toEqual(validQwenToken);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
/**
|
|
367
|
+
* @requirement REQ-003.1
|
|
368
|
+
* @scenario Handle empty or invalid provider names
|
|
369
|
+
* @given Empty or invalid provider name
|
|
370
|
+
* @when attempting to save token
|
|
371
|
+
* @then Throws appropriate error
|
|
372
|
+
*/
|
|
373
|
+
it('should reject empty or invalid provider names', async () => {
|
|
374
|
+
const invalidProviders = ['', ' ', '\t', '\n'];
|
|
375
|
+
for (const provider of invalidProviders) {
|
|
376
|
+
await expect(tokenStore.saveToken(provider, validQwenToken)).rejects.toThrow();
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
describe('Concurrent Operations', () => {
|
|
381
|
+
/**
|
|
382
|
+
* @requirement REQ-003.1
|
|
383
|
+
* @scenario Concurrent token operations
|
|
384
|
+
* @given Multiple simultaneous token operations
|
|
385
|
+
* @when operations are performed concurrently
|
|
386
|
+
* @then All operations complete successfully
|
|
387
|
+
*/
|
|
388
|
+
it('should handle concurrent token operations safely', async () => {
|
|
389
|
+
const providers = ['concurrent1', 'concurrent2', 'concurrent3'];
|
|
390
|
+
const tokens = providers.map((provider, index) => ({
|
|
391
|
+
...validQwenToken,
|
|
392
|
+
access_token: `concurrent-token-${index}`,
|
|
393
|
+
}));
|
|
394
|
+
// Test concurrent saves
|
|
395
|
+
const savePromises = providers.map((provider, index) => tokenStore.saveToken(provider, tokens[index]));
|
|
396
|
+
await Promise.all(savePromises);
|
|
397
|
+
const getPromises = providers.map((provider) => tokenStore.getToken(provider));
|
|
398
|
+
const retrievedTokens = await Promise.all(getPromises);
|
|
399
|
+
retrievedTokens.forEach((token, index) => {
|
|
400
|
+
expect(token?.access_token).toBe(`concurrent-token-${index}`);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
//# sourceMappingURL=token-store.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.spec.js","sourceRoot":"","sources":["../../../src/auth/token-store.spec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAG3D,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,IAAI,UAAmC,CAAC;IACxC,IAAI,OAAe,CAAC;IACpB,IAAI,YAAgC,CAAC;IAErC,MAAM,cAAc,GAAe;QACjC,YAAY,EAAE,uBAAuB;QACrC,aAAa,EAAE,wBAAwB;QACvC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,kBAAkB;QAChE,KAAK,EAAE,YAAY;QACnB,UAAU,EAAE,QAAiB;KAC9B,CAAC;IAEF,MAAM,iBAAiB,GAAe;QACpC,YAAY,EAAE,yBAAyB;QACvC,aAAa,EAAE,0BAA0B;QACzC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,mBAAmB;QACjE,KAAK,EAAE,OAAO;QACd,UAAU,EAAE,QAAiB;KAC9B,CAAC;IAEF,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,yCAAyC;QACzC,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAEhE,mDAAmD;QACnD,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC;QAE3B,UAAU,GAAG,IAAI,uBAAuB,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,oCAAoC;QACpC,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;QAC1B,CAAC;QAED,0BAA0B;QAC1B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC;;;;;;;WAOG;QACH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YAEnD,6CAA6C;YAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;YACjE,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc;YAC1C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,4BAA4B;YACpE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;YACjE,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACnD,MAAM,cAAc,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzD,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC/C,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACnE,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACrE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC3D,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACjD,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;YAC3E,MAAM,YAAY,GAAe;gBAC/B,YAAY,EAAE,8CAA8C;gBAC5D,aAAa,EAAE,yCAAyC;gBACxD,MAAM,EAAE,UAAU,EAAE,8BAA8B;gBAClD,KAAK,EAAE,gCAAgC;gBACvC,UAAU,EAAE,QAAiB;aAC9B,CAAC;YAEF,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACvD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YACxC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YAChE,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;YAC3E,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACnD,MAAM,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;YACjE,MAAM,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC;;;;;;WAMG;QACH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACnD,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;YACxD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACpD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC1C,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACnD,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;YACxD,MAAM,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,6BAA6B;YACtF,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,aAAa,EAAE,CAAC;YACnD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;YAC3D,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACnD,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;YACxD,MAAM,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACpD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,aAAa,EAAE,CAAC;YACnD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC;;;;;;WAMG;QACH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,UAAU,CAAC,SAAS,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC;YAC1E,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB;YAC1D,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;QAC7D,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;YACnF,MAAM,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YACxD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;YACzE,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,mBAAmB;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;YACpE,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;YAC/E,MAAM,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAC3C,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,2BAA2B;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B;;;;;;WAMG;QACH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;YACnF,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YACxD,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,2BAA2B;YAC3B,MAAM,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YACxD,wBAAwB;YACxB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;YACtE,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,yBAAyB;YACzB,MAAM,MAAM,CACV,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,CACvC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,6CAA6C;YAC7C,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACnD,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY;YAClD,MAAM,MAAM,CACV,UAAU,CAAC,SAAS,CAAC,iBAAiB,EAAE,cAAc,CAAC,CACxD,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,kCAAkC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B;;;;;;WAMG;QACH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;YAC9E,MAAM,aAAa,GAAe;gBAChC,YAAY,EAAE,sBAAsB;gBACpC,aAAa,EAAE,uBAAuB;gBACtC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,aAAa;gBAC3D,KAAK,EAAE,eAAe;gBACtB,UAAU,EAAE,QAAiB;aAC9B,CAAC;YAEF,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACnD,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAC7D,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC/C,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,aAAa,GAAe;gBAChC,YAAY,EAAE,yBAAyB;gBACvC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,EAAE,aAAa;gBAC1D,UAAU,EAAE,QAAiB;aAC9B,CAAC;YAEF,MAAM,UAAU,CAAC,SAAS,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;YAChE,MAAM,UAAU,CAAC,SAAS,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,IAAI,CACpB,OAAO,EACP,SAAS,EACT,OAAO,EACP,wBAAwB,CACzB,CAAC;YACF,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,MAAM,YAAY,GAAe;gBAC/B,YAAY,EAAE,sBAAsB;gBACpC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,EAAE,aAAa;gBAC1D,UAAU,EAAE,QAAiB;gBAC7B,4BAA4B;aAC7B,CAAC;YAEF,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACvD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YACxC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,aAAa,EAAE,CAAC;YACjD,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;YACzC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC;;;;;;WAMG;QACH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,8EAA8E;YAC9E,MAAM,gBAAgB,GAAG;gBACvB,uBAAuB;gBACvB,2BAA2B;gBAC3B,oBAAoB;aACrB,CAAC;YAEF,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;gBACxC,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;gBACrD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACtD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH;;;;;;WAMG;QACH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,gBAAgB,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAE/C,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;gBACxC,MAAM,MAAM,CACV,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,cAAc,CAAC,CAC/C,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC;;;;;;WAMG;QACH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,SAAS,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBACjD,GAAG,cAAc;gBACjB,YAAY,EAAE,oBAAoB,KAAK,EAAE;aAC1C,CAAC,CAAC,CAAC;YAEJ,wBAAwB;YACxB,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CACrD,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAC9C,CAAC;YAEF,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAChC,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC7C,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC9B,CAAC;YACF,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACvD,eAAe,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACvC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,oBAAoB,KAAK,EAAE,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
/**
|
|
8
|
+
* OAuth token storage schema
|
|
9
|
+
*/
|
|
10
|
+
export declare const OAuthTokenSchema: z.ZodObject<{
|
|
11
|
+
access_token: z.ZodString;
|
|
12
|
+
refresh_token: z.ZodOptional<z.ZodString>;
|
|
13
|
+
expiry: z.ZodNumber;
|
|
14
|
+
scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
15
|
+
token_type: z.ZodLiteral<"Bearer">;
|
|
16
|
+
resource_url: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
token_type: "Bearer";
|
|
19
|
+
access_token: string;
|
|
20
|
+
expiry: number;
|
|
21
|
+
scope?: string | null | undefined;
|
|
22
|
+
refresh_token?: string | undefined;
|
|
23
|
+
resource_url?: string | undefined;
|
|
24
|
+
}, {
|
|
25
|
+
token_type: "Bearer";
|
|
26
|
+
access_token: string;
|
|
27
|
+
expiry: number;
|
|
28
|
+
scope?: string | null | undefined;
|
|
29
|
+
refresh_token?: string | undefined;
|
|
30
|
+
resource_url?: string | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Provider OAuth configuration schema
|
|
34
|
+
*/
|
|
35
|
+
export declare const ProviderOAuthConfigSchema: z.ZodObject<{
|
|
36
|
+
provider: z.ZodEnum<["gemini", "qwen"]>;
|
|
37
|
+
clientId: z.ZodString;
|
|
38
|
+
authorizationEndpoint: z.ZodString;
|
|
39
|
+
tokenEndpoint: z.ZodString;
|
|
40
|
+
scopes: z.ZodArray<z.ZodString, "many">;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
clientId: string;
|
|
43
|
+
provider: "gemini" | "qwen";
|
|
44
|
+
scopes: string[];
|
|
45
|
+
authorizationEndpoint: string;
|
|
46
|
+
tokenEndpoint: string;
|
|
47
|
+
}, {
|
|
48
|
+
clientId: string;
|
|
49
|
+
provider: "gemini" | "qwen";
|
|
50
|
+
scopes: string[];
|
|
51
|
+
authorizationEndpoint: string;
|
|
52
|
+
tokenEndpoint: string;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Device code response schema
|
|
56
|
+
*/
|
|
57
|
+
export declare const DeviceCodeResponseSchema: z.ZodObject<{
|
|
58
|
+
device_code: z.ZodString;
|
|
59
|
+
user_code: z.ZodString;
|
|
60
|
+
verification_uri: z.ZodString;
|
|
61
|
+
verification_uri_complete: z.ZodOptional<z.ZodString>;
|
|
62
|
+
expires_in: z.ZodNumber;
|
|
63
|
+
interval: z.ZodOptional<z.ZodNumber>;
|
|
64
|
+
}, "strip", z.ZodTypeAny, {
|
|
65
|
+
device_code: string;
|
|
66
|
+
user_code: string;
|
|
67
|
+
verification_uri: string;
|
|
68
|
+
expires_in: number;
|
|
69
|
+
verification_uri_complete?: string | undefined;
|
|
70
|
+
interval?: number | undefined;
|
|
71
|
+
}, {
|
|
72
|
+
device_code: string;
|
|
73
|
+
user_code: string;
|
|
74
|
+
verification_uri: string;
|
|
75
|
+
expires_in: number;
|
|
76
|
+
verification_uri_complete?: string | undefined;
|
|
77
|
+
interval?: number | undefined;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Token response schema
|
|
81
|
+
*/
|
|
82
|
+
export declare const TokenResponseSchema: z.ZodObject<{
|
|
83
|
+
access_token: z.ZodString;
|
|
84
|
+
token_type: z.ZodString;
|
|
85
|
+
expires_in: z.ZodOptional<z.ZodNumber>;
|
|
86
|
+
refresh_token: z.ZodOptional<z.ZodString>;
|
|
87
|
+
scope: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
88
|
+
resource_url: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, "strip", z.ZodTypeAny, {
|
|
90
|
+
token_type: string;
|
|
91
|
+
access_token: string;
|
|
92
|
+
scope?: string | null | undefined;
|
|
93
|
+
refresh_token?: string | undefined;
|
|
94
|
+
resource_url?: string | undefined;
|
|
95
|
+
expires_in?: number | undefined;
|
|
96
|
+
}, {
|
|
97
|
+
token_type: string;
|
|
98
|
+
access_token: string;
|
|
99
|
+
scope?: string | null | undefined;
|
|
100
|
+
refresh_token?: string | undefined;
|
|
101
|
+
resource_url?: string | undefined;
|
|
102
|
+
expires_in?: number | undefined;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* Auth status schema
|
|
106
|
+
*/
|
|
107
|
+
export declare const AuthStatusSchema: z.ZodObject<{
|
|
108
|
+
provider: z.ZodString;
|
|
109
|
+
authenticated: z.ZodBoolean;
|
|
110
|
+
authType: z.ZodEnum<["oauth", "api-key", "none"]>;
|
|
111
|
+
expiresIn: z.ZodOptional<z.ZodNumber>;
|
|
112
|
+
oauthEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
113
|
+
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
authType: "none" | "oauth" | "api-key";
|
|
115
|
+
provider: string;
|
|
116
|
+
authenticated: boolean;
|
|
117
|
+
expiresIn?: number | undefined;
|
|
118
|
+
oauthEnabled?: boolean | undefined;
|
|
119
|
+
}, {
|
|
120
|
+
authType: "none" | "oauth" | "api-key";
|
|
121
|
+
provider: string;
|
|
122
|
+
authenticated: boolean;
|
|
123
|
+
expiresIn?: number | undefined;
|
|
124
|
+
oauthEnabled?: boolean | undefined;
|
|
125
|
+
}>;
|
|
126
|
+
export type OAuthToken = z.infer<typeof OAuthTokenSchema>;
|
|
127
|
+
export type ProviderOAuthConfig = z.infer<typeof ProviderOAuthConfigSchema>;
|
|
128
|
+
export type DeviceCodeResponse = z.infer<typeof DeviceCodeResponseSchema>;
|
|
129
|
+
export type TokenResponse = z.infer<typeof TokenResponseSchema>;
|
|
130
|
+
export type AuthStatus = z.infer<typeof AuthStatusSchema>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
/**
|
|
8
|
+
* OAuth token storage schema
|
|
9
|
+
*/
|
|
10
|
+
export const OAuthTokenSchema = z.object({
|
|
11
|
+
access_token: z.string(),
|
|
12
|
+
refresh_token: z.string().optional(),
|
|
13
|
+
expiry: z.number(), // Unix timestamp
|
|
14
|
+
scope: z.string().nullable().optional(),
|
|
15
|
+
token_type: z.literal('Bearer'),
|
|
16
|
+
resource_url: z.string().optional(), // For Qwen OAuth - indicates the API endpoint to use
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Provider OAuth configuration schema
|
|
20
|
+
*/
|
|
21
|
+
export const ProviderOAuthConfigSchema = z.object({
|
|
22
|
+
provider: z.enum(['gemini', 'qwen']),
|
|
23
|
+
clientId: z.string(),
|
|
24
|
+
authorizationEndpoint: z.string().url(),
|
|
25
|
+
tokenEndpoint: z.string().url(),
|
|
26
|
+
scopes: z.array(z.string()),
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Device code response schema
|
|
30
|
+
*/
|
|
31
|
+
export const DeviceCodeResponseSchema = z.object({
|
|
32
|
+
device_code: z.string(),
|
|
33
|
+
user_code: z.string(),
|
|
34
|
+
verification_uri: z.string().url(),
|
|
35
|
+
verification_uri_complete: z.string().url().optional(),
|
|
36
|
+
expires_in: z.number(),
|
|
37
|
+
interval: z.number().optional(), // Qwen doesn't include this field
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Token response schema
|
|
41
|
+
*/
|
|
42
|
+
export const TokenResponseSchema = z.object({
|
|
43
|
+
access_token: z.string(),
|
|
44
|
+
token_type: z.string(),
|
|
45
|
+
expires_in: z.number().optional(),
|
|
46
|
+
refresh_token: z.string().optional(),
|
|
47
|
+
scope: z.string().nullable().optional(), // Qwen may return null for scope
|
|
48
|
+
resource_url: z.string().optional(), // Qwen OAuth returns the API endpoint to use
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* Auth status schema
|
|
52
|
+
*/
|
|
53
|
+
export const AuthStatusSchema = z.object({
|
|
54
|
+
provider: z.string(),
|
|
55
|
+
authenticated: z.boolean(),
|
|
56
|
+
authType: z.enum(['oauth', 'api-key', 'none']),
|
|
57
|
+
expiresIn: z.number().optional(), // seconds until expiry
|
|
58
|
+
oauthEnabled: z.boolean().optional(), // whether OAuth is enabled for this provider
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,iBAAiB;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACvC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC/B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,qDAAqD;CAC3F,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACvC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAClC,yBAAyB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACtD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,kCAAkC;CACpE,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,iCAAiC;IAC1E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,6CAA6C;CACnF,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;IAC1B,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,uBAAuB;IACzD,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,6CAA6C;CACpF,CAAC,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { Content, GenerateContentParameters, CountTokensParameters, CountTokensResponse, GenerateContentResponse, GenerationConfigRoutingConfig, MediaResolution, Candidate, ModelSelectionConfig, GenerateContentResponsePromptFeedback, GenerateContentResponseUsageMetadata, SafetySetting, SchemaUnion, SpeechConfigUnion, ThinkingConfig, ToolListUnion, ToolConfig } from '@google/genai';
|
|
6
|
+
import { Content, ContentListUnion, GenerateContentParameters, CountTokensParameters, CountTokensResponse, GenerateContentResponse, GenerationConfigRoutingConfig, MediaResolution, Candidate, ModelSelectionConfig, GenerateContentResponsePromptFeedback, GenerateContentResponseUsageMetadata, SafetySetting, SchemaUnion, SpeechConfigUnion, ThinkingConfig, ToolListUnion, ToolConfig } from '@google/genai';
|
|
7
7
|
export interface CAGenerateContentRequest {
|
|
8
8
|
model: string;
|
|
9
9
|
project?: string;
|
|
@@ -66,4 +66,5 @@ export declare function toCountTokenRequest(req: CountTokensParameters): CaCount
|
|
|
66
66
|
export declare function fromCountTokenResponse(res: CaCountTokenResponse): CountTokensResponse;
|
|
67
67
|
export declare function toGenerateContentRequest(req: GenerateContentParameters, userPromptId: string, project?: string, sessionId?: string): CAGenerateContentRequest;
|
|
68
68
|
export declare function fromGenerateContentResponse(res: CaGenerateContentResponse): GenerateContentResponse;
|
|
69
|
+
export declare function toContents(contents: ContentListUnion): Content[];
|
|
69
70
|
export {};
|
|
@@ -47,7 +47,7 @@ function toVertexGenerateContentRequest(req, sessionId) {
|
|
|
47
47
|
session_id: sessionId,
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
function toContents(contents) {
|
|
50
|
+
export function toContents(contents) {
|
|
51
51
|
if (Array.isArray(contents)) {
|
|
52
52
|
// it's a Content[] or a PartsUnion[]
|
|
53
53
|
return contents.map(toContent);
|