@vybestack/llxprt-code 0.1.18-nightly.250808.f9b79d74 → 0.1.18-nightly.250812.12fa8ad2
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 +49 -2
- package/dist/package.json +5 -3
- package/dist/src/auth/anthropic-oauth-provider.d.ts +33 -0
- package/dist/src/auth/anthropic-oauth-provider.js +129 -0
- package/dist/src/auth/anthropic-oauth-provider.js.map +1 -0
- package/dist/src/auth/gemini-oauth-provider.d.ts +15 -0
- package/dist/src/auth/gemini-oauth-provider.js +33 -0
- package/dist/src/auth/gemini-oauth-provider.js.map +1 -0
- package/dist/src/auth/oauth-manager.d.ts +109 -0
- package/dist/src/auth/oauth-manager.js +334 -0
- package/dist/src/auth/oauth-manager.js.map +1 -0
- package/dist/src/auth/oauth-manager.spec.d.ts +6 -0
- package/dist/src/auth/oauth-manager.spec.js +523 -0
- package/dist/src/auth/oauth-manager.spec.js.map +1 -0
- package/dist/src/auth/qwen-oauth-provider.d.ts +14 -0
- package/dist/src/auth/qwen-oauth-provider.js +75 -0
- package/dist/src/auth/qwen-oauth-provider.js.map +1 -0
- package/dist/src/auth/types.d.ts +7 -0
- package/dist/src/auth/types.js +7 -0
- package/dist/src/auth/types.js.map +1 -0
- package/dist/src/config/auth.js +11 -0
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.js +93 -43
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +66 -0
- package/dist/src/config/keyBindings.js +136 -0
- package/dist/src/config/keyBindings.js.map +1 -0
- package/dist/src/config/settings.d.ts +3 -59
- package/dist/src/config/settings.js +17 -1
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +587 -0
- package/dist/src/config/settingsSchema.js +565 -0
- package/dist/src/config/settingsSchema.js.map +1 -0
- package/dist/src/gemini.js +12 -109
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/nonInteractiveCli.js +0 -1
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/providers/logging/git-stats-service-impl.d.ts +19 -0
- package/dist/src/providers/logging/git-stats-service-impl.js +25 -0
- package/dist/src/providers/logging/git-stats-service-impl.js.map +1 -0
- package/dist/src/providers/logging/git-stats.d.ts +43 -0
- package/dist/src/providers/logging/git-stats.js +137 -0
- package/dist/src/providers/logging/git-stats.js.map +1 -0
- package/dist/src/providers/providerManagerInstance.d.ts +2 -0
- package/dist/src/providers/providerManagerInstance.js +49 -5
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +4 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/todo-continuation/todoContinuationService.d.ts +172 -0
- package/dist/src/services/todo-continuation/todoContinuationService.js +387 -0
- package/dist/src/services/todo-continuation/todoContinuationService.js.map +1 -0
- package/dist/src/services/todo-continuation/todoContinuationService.spec.d.ts +6 -0
- package/dist/src/services/todo-continuation/todoContinuationService.spec.js +385 -0
- package/dist/src/services/todo-continuation/todoContinuationService.spec.js.map +1 -0
- package/dist/src/ui/App.js +156 -35
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/colors.d.ts +5 -0
- package/dist/src/ui/colors.js +51 -0
- package/dist/src/ui/colors.js.map +1 -1
- package/dist/src/ui/commands/authCommand.d.ts +11 -1
- package/dist/src/ui/commands/authCommand.js +145 -48
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +16 -0
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.js +94 -10
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +67 -31
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +32 -2
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +15 -12
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/loggingCommand.d.ts +15 -0
- package/dist/src/ui/commands/loggingCommand.js +421 -0
- package/dist/src/ui/commands/loggingCommand.js.map +1 -0
- package/dist/src/ui/commands/modelCommand.js +21 -3
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/privacyCommand.d.ts +3 -0
- package/dist/src/ui/commands/privacyCommand.js +6 -3
- package/dist/src/ui/commands/privacyCommand.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +52 -14
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.js +17 -1
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/settingsCommand.d.ts +7 -0
- package/dist/src/ui/commands/settingsCommand.js +16 -0
- package/dist/src/ui/commands/settingsCommand.js.map +1 -0
- package/dist/src/ui/commands/setupGithubCommand.js +21 -2
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
- package/dist/src/ui/commands/toolformatCommand.js +79 -23
- package/dist/src/ui/commands/toolformatCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +14 -2
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.js +15 -54
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/AuthInProgress.js +3 -3
- package/dist/src/ui/components/AuthInProgress.js.map +1 -1
- package/dist/src/ui/components/ContextUsageDisplay.d.ts +10 -0
- package/dist/src/ui/components/ContextUsageDisplay.js +27 -0
- package/dist/src/ui/components/ContextUsageDisplay.js.map +1 -0
- package/dist/src/ui/components/FolderTrustDialog.d.ts +16 -0
- package/dist/src/ui/components/FolderTrustDialog.js +38 -0
- package/dist/src/ui/components/FolderTrustDialog.js.map +1 -0
- package/dist/src/ui/components/Footer.js +132 -15
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +1 -0
- package/dist/src/ui/components/InputPrompt.js +87 -31
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/LoggingDialog.d.ts +37 -0
- package/dist/src/ui/components/LoggingDialog.js +155 -0
- package/dist/src/ui/components/LoggingDialog.js.map +1 -0
- package/dist/src/ui/components/MemoryUsageDisplay.js +6 -4
- package/dist/src/ui/components/MemoryUsageDisplay.js.map +1 -1
- package/dist/src/ui/components/OAuthCodeDialog.d.ts +13 -0
- package/dist/src/ui/components/OAuthCodeDialog.js +54 -0
- package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -0
- package/dist/src/ui/components/ProviderDialog.js +100 -26
- package/dist/src/ui/components/ProviderDialog.js.map +1 -1
- package/dist/src/ui/components/ProviderModelDialog.js +99 -27
- package/dist/src/ui/components/ProviderModelDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.d.ts +14 -0
- package/dist/src/ui/components/SettingsDialog.js +247 -0
- package/dist/src/ui/components/SettingsDialog.js.map +1 -0
- package/dist/src/ui/components/ThemeDialog.js +4 -15
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/TodoPanel.js +93 -18
- package/dist/src/ui/components/TodoPanel.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +85 -7
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/contexts/SettingsContext.d.ts +9 -0
- package/dist/src/ui/contexts/SettingsContext.js +15 -0
- package/dist/src/ui/contexts/SettingsContext.js.map +1 -0
- package/dist/src/ui/hooks/atCommandProcessor.js +21 -0
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +6 -2
- package/dist/src/ui/hooks/slashCommandProcessor.js +142 -113
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.js +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +48 -2
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.js +7 -0
- package/dist/src/ui/hooks/useConsoleMessages.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.d.ts +11 -0
- package/dist/src/ui/hooks/useFolderTrust.js +22 -0
- package/dist/src/ui/hooks/useFolderTrust.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +35 -10
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useResponsive.d.ts +14 -0
- package/dist/src/ui/hooks/useResponsive.js +19 -0
- package/dist/src/ui/hooks/useResponsive.js.map +1 -0
- package/dist/src/ui/hooks/useSettingsCommand.d.ts +10 -0
- package/dist/src/ui/hooks/useSettingsCommand.js +21 -0
- package/dist/src/ui/hooks/useSettingsCommand.js.map +1 -0
- package/dist/src/ui/hooks/useTodoContinuation.d.ts +31 -0
- package/dist/src/ui/hooks/useTodoContinuation.js +148 -0
- package/dist/src/ui/hooks/useTodoContinuation.js.map +1 -0
- package/dist/src/ui/hooks/useTodoContinuation.spec.d.ts +6 -0
- package/dist/src/ui/hooks/useTodoContinuation.spec.js +378 -0
- package/dist/src/ui/hooks/useTodoContinuation.spec.js.map +1 -0
- package/dist/src/ui/keyMatchers.d.ts +26 -0
- package/dist/src/ui/keyMatchers.js +68 -0
- package/dist/src/ui/keyMatchers.js.map +1 -0
- package/dist/src/ui/privacy/PrivacyNotice.js +10 -4
- package/dist/src/ui/privacy/PrivacyNotice.js.map +1 -1
- package/dist/src/ui/reducers/appReducer.d.ts +3 -2
- package/dist/src/ui/reducers/appReducer.js +1 -0
- package/dist/src/ui/reducers/appReducer.js.map +1 -1
- package/dist/src/ui/themes/semantic-resolver.d.ts +12 -0
- package/dist/src/ui/themes/semantic-resolver.js +32 -0
- package/dist/src/ui/themes/semantic-resolver.js.map +1 -0
- package/dist/src/ui/themes/semantic-tokens.d.ts +52 -0
- package/dist/src/ui/themes/semantic-tokens.js +7 -0
- package/dist/src/ui/themes/semantic-tokens.js.map +1 -0
- package/dist/src/ui/themes/theme-compat.d.ts +34 -0
- package/dist/src/ui/themes/theme-compat.js +65 -0
- package/dist/src/ui/themes/theme-compat.js.map +1 -0
- package/dist/src/ui/themes/theme-manager.d.ts +8 -0
- package/dist/src/ui/themes/theme-manager.js +18 -0
- package/dist/src/ui/themes/theme-manager.js.map +1 -1
- package/dist/src/ui/utils/CodeColorizer.d.ts +2 -1
- package/dist/src/ui/utils/CodeColorizer.js +4 -3
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.js +4 -2
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.d.ts +1 -0
- package/dist/src/ui/utils/commandUtils.js +22 -1
- package/dist/src/ui/utils/commandUtils.js.map +1 -1
- package/dist/src/ui/utils/responsive.d.ts +16 -0
- package/dist/src/ui/utils/responsive.js +111 -0
- package/dist/src/ui/utils/responsive.js.map +1 -0
- package/dist/src/utils/cleanup.d.ts +2 -2
- package/dist/src/utils/cleanup.js +2 -2
- package/dist/src/utils/cleanup.js.map +1 -1
- package/dist/src/utils/dialogScopeUtils.d.ts +31 -0
- package/dist/src/utils/dialogScopeUtils.js +48 -0
- package/dist/src/utils/dialogScopeUtils.js.map +1 -0
- package/dist/src/utils/gitUtils.d.ts +9 -0
- package/dist/src/utils/gitUtils.js +17 -0
- package/dist/src/utils/gitUtils.js.map +1 -1
- package/dist/src/utils/privacy/ConversationDataRedactor.d.ts +75 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.js +412 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.js.map +1 -0
- package/dist/src/utils/privacy/PrivacyManager.d.ts +58 -0
- package/dist/src/utils/privacy/PrivacyManager.js +133 -0
- package/dist/src/utils/privacy/PrivacyManager.js.map +1 -0
- package/dist/src/utils/sandbox.js +10 -0
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/settingsUtils.d.ts +126 -0
- package/dist/src/utils/settingsUtils.js +327 -0
- package/dist/src/utils/settingsUtils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/dist/src/ui/components/IDEContextDetailDisplay.d.ts +0 -12
- package/dist/src/ui/components/IDEContextDetailDisplay.js +0 -17
- package/dist/src/ui/components/IDEContextDetailDisplay.js.map +0 -1
@@ -0,0 +1,523 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { OAuthManager } from './oauth-manager.js';
|
7
|
+
/**
|
8
|
+
* Mock OAuth provider for testing
|
9
|
+
* Implements real OAuthProvider interface for coordination testing
|
10
|
+
*/
|
11
|
+
class MockOAuthProvider {
|
12
|
+
initialToken;
|
13
|
+
name;
|
14
|
+
token = null;
|
15
|
+
authInitiated = false;
|
16
|
+
constructor(name, initialToken) {
|
17
|
+
this.initialToken = initialToken;
|
18
|
+
this.name = name;
|
19
|
+
this.token = initialToken || null;
|
20
|
+
}
|
21
|
+
async initiateAuth() {
|
22
|
+
this.authInitiated = true;
|
23
|
+
// Simulate successful auth flow
|
24
|
+
if (!this.token) {
|
25
|
+
this.token = {
|
26
|
+
access_token: `access_${this.name}_${Date.now()}`,
|
27
|
+
refresh_token: `refresh_${this.name}_${Date.now()}`,
|
28
|
+
expiry: Date.now() + 3600000, // 1 hour from now
|
29
|
+
token_type: 'Bearer',
|
30
|
+
scope: 'read write',
|
31
|
+
};
|
32
|
+
}
|
33
|
+
}
|
34
|
+
async getToken() {
|
35
|
+
return this.token;
|
36
|
+
}
|
37
|
+
async refreshIfNeeded() {
|
38
|
+
if (this.token && this.token.expiry < Date.now() + 300000) {
|
39
|
+
// Refresh if expires in less than 5 minutes
|
40
|
+
this.token = {
|
41
|
+
...this.token,
|
42
|
+
access_token: `refreshed_${this.name}_${Date.now()}`,
|
43
|
+
expiry: Date.now() + 3600000, // 1 hour from now
|
44
|
+
};
|
45
|
+
}
|
46
|
+
return this.token;
|
47
|
+
}
|
48
|
+
// Test helpers
|
49
|
+
setToken(token) {
|
50
|
+
this.token = token;
|
51
|
+
}
|
52
|
+
setExpiringToken() {
|
53
|
+
this.token = {
|
54
|
+
access_token: `expiring_${this.name}`,
|
55
|
+
refresh_token: `refresh_${this.name}`,
|
56
|
+
expiry: Date.now() + 10000, // Expires in 10 seconds
|
57
|
+
token_type: 'Bearer',
|
58
|
+
scope: 'read',
|
59
|
+
};
|
60
|
+
}
|
61
|
+
wasAuthInitiated() {
|
62
|
+
return this.authInitiated;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
/**
|
66
|
+
* Mock token store for testing
|
67
|
+
* Implements real TokenStore interface for coordination testing
|
68
|
+
*/
|
69
|
+
class MockTokenStore {
|
70
|
+
tokens = new Map();
|
71
|
+
async saveToken(provider, token) {
|
72
|
+
this.tokens.set(provider, token);
|
73
|
+
}
|
74
|
+
async getToken(provider) {
|
75
|
+
return this.tokens.get(provider) || null;
|
76
|
+
}
|
77
|
+
async removeToken(provider) {
|
78
|
+
this.tokens.delete(provider);
|
79
|
+
}
|
80
|
+
async listProviders() {
|
81
|
+
return Array.from(this.tokens.keys()).sort();
|
82
|
+
}
|
83
|
+
// Test helpers
|
84
|
+
clear() {
|
85
|
+
this.tokens.clear();
|
86
|
+
}
|
87
|
+
}
|
88
|
+
describe('OAuthManager with OAuth Enablement and Lazy Authentication', () => {
|
89
|
+
let manager;
|
90
|
+
let tokenStore;
|
91
|
+
let qwenProvider;
|
92
|
+
let geminiProvider;
|
93
|
+
beforeEach(() => {
|
94
|
+
tokenStore = new MockTokenStore();
|
95
|
+
manager = new OAuthManager(tokenStore);
|
96
|
+
qwenProvider = new MockOAuthProvider('qwen');
|
97
|
+
geminiProvider = new MockOAuthProvider('gemini');
|
98
|
+
});
|
99
|
+
describe('Provider Registration', () => {
|
100
|
+
/**
|
101
|
+
* @requirement REQ-001.1
|
102
|
+
* @scenario Register OAuth provider
|
103
|
+
* @given OAuthManager instance
|
104
|
+
* @when registerProvider(qwenProvider) called
|
105
|
+
* @then Provider available for authentication
|
106
|
+
* @and Listed in getSupportedProviders()
|
107
|
+
*/
|
108
|
+
it('should register OAuth provider and make it available', () => {
|
109
|
+
expect(() => {
|
110
|
+
manager.registerProvider(qwenProvider);
|
111
|
+
}).not.toThrow();
|
112
|
+
// Provider should be available in getSupportedProviders()
|
113
|
+
const providers = manager.getSupportedProviders();
|
114
|
+
expect(providers).toContain('qwen');
|
115
|
+
});
|
116
|
+
/**
|
117
|
+
* @requirement REQ-001.3
|
118
|
+
* @scenario Multiple provider registration
|
119
|
+
* @given Empty OAuth manager
|
120
|
+
* @when Register qwen and gemini providers
|
121
|
+
* @then Both providers available
|
122
|
+
* @and Can authenticate with either
|
123
|
+
*/
|
124
|
+
it('should register multiple providers independently', () => {
|
125
|
+
expect(() => {
|
126
|
+
manager.registerProvider(qwenProvider);
|
127
|
+
manager.registerProvider(geminiProvider);
|
128
|
+
}).not.toThrow();
|
129
|
+
// Both providers should be available
|
130
|
+
const providers = manager.getSupportedProviders();
|
131
|
+
expect(providers).toContain('qwen');
|
132
|
+
expect(providers).toContain('gemini');
|
133
|
+
expect(providers).toHaveLength(2);
|
134
|
+
});
|
135
|
+
/**
|
136
|
+
* @requirement REQ-001.1
|
137
|
+
* @scenario List OAuth-capable providers
|
138
|
+
* @given Qwen and Gemini registered
|
139
|
+
* @when getSupportedProviders() called
|
140
|
+
* @then Returns ['gemini', 'qwen'] sorted
|
141
|
+
*/
|
142
|
+
it('should list registered providers in sorted order', () => {
|
143
|
+
manager.registerProvider(qwenProvider);
|
144
|
+
manager.registerProvider(geminiProvider);
|
145
|
+
const providers = manager.getSupportedProviders();
|
146
|
+
expect(providers).toEqual(['gemini', 'qwen']); // Should be sorted
|
147
|
+
});
|
148
|
+
});
|
149
|
+
describe('OAuth Enablement Management', () => {
|
150
|
+
/**
|
151
|
+
* @requirement REQ-001.3
|
152
|
+
* @scenario Toggle OAuth enablement for provider
|
153
|
+
* @given Registered qwen provider with OAuth disabled
|
154
|
+
* @when toggleOAuthEnabled('qwen') called
|
155
|
+
* @then OAuth is enabled for qwen
|
156
|
+
* @and No OAuth flow is triggered immediately
|
157
|
+
*/
|
158
|
+
it('should toggle OAuth enablement without triggering auth flow', async () => {
|
159
|
+
manager.registerProvider(qwenProvider);
|
160
|
+
// Mock the toggle method (would be implemented in real OAuthManager)
|
161
|
+
const mockToggle = vi.fn().mockResolvedValue(true);
|
162
|
+
manager.toggleOAuthEnabled = mockToggle;
|
163
|
+
const result = await manager.toggleOAuthEnabled('qwen');
|
164
|
+
expect(result).toBe(true);
|
165
|
+
// Verify provider's initiateAuth was NOT called
|
166
|
+
expect(qwenProvider.wasAuthInitiated()).toBe(false);
|
167
|
+
});
|
168
|
+
/**
|
169
|
+
* @requirement REQ-001.1
|
170
|
+
* @scenario OAuth enablement check
|
171
|
+
* @given Provider registered with OAuth enabled
|
172
|
+
* @when isOAuthEnabled('qwen') called
|
173
|
+
* @then Returns current enablement state
|
174
|
+
* @and No OAuth flow is triggered
|
175
|
+
*/
|
176
|
+
it('should check OAuth enablement status without triggering auth', async () => {
|
177
|
+
manager.registerProvider(qwenProvider);
|
178
|
+
// Mock the enablement check method
|
179
|
+
const mockIsEnabled = vi.fn().mockResolvedValue(false);
|
180
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
181
|
+
const result = await manager.isOAuthEnabled('qwen');
|
182
|
+
expect(result).toBe(false);
|
183
|
+
// Verify OAuth flow was not initiated
|
184
|
+
expect(qwenProvider.wasAuthInitiated()).toBe(false);
|
185
|
+
});
|
186
|
+
/**
|
187
|
+
* @requirement REQ-001.3
|
188
|
+
* @scenario Toggle multiple providers independently
|
189
|
+
* @given Multiple providers registered
|
190
|
+
* @when toggleOAuthEnabled() called for each provider
|
191
|
+
* @then Each provider toggles independently
|
192
|
+
* @and Enablement state persists separately
|
193
|
+
*/
|
194
|
+
it('should toggle OAuth enablement for multiple providers independently', async () => {
|
195
|
+
manager.registerProvider(qwenProvider);
|
196
|
+
manager.registerProvider(geminiProvider);
|
197
|
+
// Mock toggle methods for both providers
|
198
|
+
const mockToggle = vi
|
199
|
+
.fn()
|
200
|
+
.mockResolvedValueOnce(true) // Enable qwen
|
201
|
+
.mockResolvedValueOnce(false); // Disable gemini
|
202
|
+
manager.toggleOAuthEnabled = mockToggle;
|
203
|
+
const qwenResult = await manager.toggleOAuthEnabled('qwen');
|
204
|
+
const geminiResult = await manager.toggleOAuthEnabled('gemini');
|
205
|
+
expect(qwenResult).toBe(true); // OAuth enabled for qwen
|
206
|
+
expect(geminiResult).toBe(false); // OAuth disabled for gemini
|
207
|
+
// Neither provider should have auth initiated
|
208
|
+
expect(qwenProvider.wasAuthInitiated()).toBe(false);
|
209
|
+
expect(geminiProvider.wasAuthInitiated()).toBe(false);
|
210
|
+
});
|
211
|
+
});
|
212
|
+
describe('Lazy Authentication Flow', () => {
|
213
|
+
/**
|
214
|
+
* @requirement REQ-003.1
|
215
|
+
* @scenario Lazy OAuth triggering on API call
|
216
|
+
* @given OAuth enabled for qwen but not authenticated
|
217
|
+
* @when getToken('qwen') called during API request
|
218
|
+
* @then Triggers OAuth flow lazily
|
219
|
+
* @and Returns token after authentication
|
220
|
+
*/
|
221
|
+
it('should trigger OAuth flow lazily when token needed for API call', async () => {
|
222
|
+
manager.registerProvider(qwenProvider);
|
223
|
+
// Mock OAuth as enabled but provider not authenticated yet
|
224
|
+
const mockIsEnabled = vi.fn().mockResolvedValue(true);
|
225
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
226
|
+
// When getToken is called, it should trigger authentication
|
227
|
+
const token = await manager.getToken('qwen');
|
228
|
+
expect(token).not.toBeNull();
|
229
|
+
expect(token).toBeDefined();
|
230
|
+
// OAuth flow should have been initiated lazily
|
231
|
+
expect(qwenProvider.wasAuthInitiated()).toBe(true);
|
232
|
+
});
|
233
|
+
/**
|
234
|
+
* @requirement REQ-003.1
|
235
|
+
* @scenario Independent lazy OAuth triggering
|
236
|
+
* @given OAuth enabled for qwen and gemini, neither authenticated
|
237
|
+
* @when getToken('qwen') called
|
238
|
+
* @then Triggers OAuth for qwen only
|
239
|
+
* @and Gemini remains unauthenticated until needed
|
240
|
+
*/
|
241
|
+
it('should trigger OAuth independently for each provider when needed', async () => {
|
242
|
+
manager.registerProvider(qwenProvider);
|
243
|
+
manager.registerProvider(geminiProvider);
|
244
|
+
// Mock OAuth as enabled for both
|
245
|
+
const mockIsEnabled = vi.fn().mockReturnValue(true);
|
246
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
247
|
+
// Only request qwen token
|
248
|
+
const qwenToken = await manager.getToken('qwen');
|
249
|
+
expect(qwenToken).not.toBeNull();
|
250
|
+
expect(qwenProvider.wasAuthInitiated()).toBe(true);
|
251
|
+
// Gemini should not have been triggered
|
252
|
+
expect(geminiProvider.wasAuthInitiated()).toBe(false);
|
253
|
+
});
|
254
|
+
/**
|
255
|
+
* @requirement REQ-002.5
|
256
|
+
* @scenario Auto-refresh expired token
|
257
|
+
* @given Token expires in 10 seconds
|
258
|
+
* @when getToken() called
|
259
|
+
* @then Automatically refreshes token
|
260
|
+
* @and Returns new valid token
|
261
|
+
*/
|
262
|
+
it('should automatically refresh expiring tokens', async () => {
|
263
|
+
manager.registerProvider(qwenProvider);
|
264
|
+
// Mock OAuth as enabled
|
265
|
+
const mockIsEnabled = vi.fn().mockReturnValue(true);
|
266
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
267
|
+
// First authenticate to get a token
|
268
|
+
await manager.authenticate('qwen');
|
269
|
+
// Set an expiring token in the token store
|
270
|
+
const expiringToken = {
|
271
|
+
access_token: 'expiring_token',
|
272
|
+
refresh_token: 'refresh_token',
|
273
|
+
expiry: Date.now() + 10000, // Expires in 10 seconds
|
274
|
+
token_type: 'Bearer',
|
275
|
+
scope: 'read',
|
276
|
+
};
|
277
|
+
await tokenStore.saveToken('qwen', expiringToken);
|
278
|
+
// Set the provider to return a refreshed token
|
279
|
+
qwenProvider.setExpiringToken(); // This will trigger refresh logic in the provider
|
280
|
+
const token = await manager.getToken('qwen');
|
281
|
+
// Should get a refreshed token (access token string)
|
282
|
+
expect(token).not.toBeNull();
|
283
|
+
expect(token).toMatch(/refreshed_/);
|
284
|
+
});
|
285
|
+
/**
|
286
|
+
* @requirement REQ-003.1
|
287
|
+
* @scenario Get token for OAuth disabled provider
|
288
|
+
* @given Provider registered with OAuth disabled
|
289
|
+
* @when getToken() called
|
290
|
+
* @then Returns null without triggering OAuth
|
291
|
+
*/
|
292
|
+
it('should return null for OAuth disabled provider without triggering auth', async () => {
|
293
|
+
manager.registerProvider(qwenProvider);
|
294
|
+
// Mock OAuth as disabled
|
295
|
+
const mockIsEnabled = vi.fn().mockReturnValue(false);
|
296
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
297
|
+
const token = await manager.getToken('qwen');
|
298
|
+
expect(token).toBeNull();
|
299
|
+
// OAuth should not have been triggered
|
300
|
+
expect(qwenProvider.wasAuthInitiated()).toBe(false);
|
301
|
+
});
|
302
|
+
});
|
303
|
+
describe('Status Reporting with OAuth Enablement', () => {
|
304
|
+
/**
|
305
|
+
* @requirement REQ-005.4
|
306
|
+
* @scenario Get auth status including OAuth enablement
|
307
|
+
* @given Qwen OAuth enabled and authenticated, Gemini OAuth disabled
|
308
|
+
* @when getAuthStatus() called
|
309
|
+
* @then Returns status for both providers
|
310
|
+
* @and Shows OAuth enablement state
|
311
|
+
*/
|
312
|
+
it('should report OAuth enablement status for all providers', async () => {
|
313
|
+
manager.registerProvider(qwenProvider);
|
314
|
+
manager.registerProvider(geminiProvider);
|
315
|
+
// Mock OAuth enabled for qwen, disabled for gemini
|
316
|
+
const mockIsEnabled = vi
|
317
|
+
.fn()
|
318
|
+
.mockImplementation((provider) => provider === 'qwen');
|
319
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
320
|
+
// Authenticate qwen through lazy triggering
|
321
|
+
await manager.getToken('qwen');
|
322
|
+
const statuses = await manager.getAuthStatus();
|
323
|
+
expect(statuses).toHaveLength(2);
|
324
|
+
const qwenStatus = statuses.find((s) => s.provider === 'qwen');
|
325
|
+
const geminiStatus = statuses.find((s) => s.provider === 'gemini');
|
326
|
+
expect(qwenStatus?.authenticated).toBe(true);
|
327
|
+
expect(qwenStatus?.oauthEnabled).toBe(true);
|
328
|
+
expect(geminiStatus?.authenticated).toBe(false);
|
329
|
+
expect(geminiStatus?.oauthEnabled).toBe(false);
|
330
|
+
});
|
331
|
+
/**
|
332
|
+
* @requirement REQ-005.4
|
333
|
+
* @scenario Show token expiry in status
|
334
|
+
* @given Authenticated provider with expiry
|
335
|
+
* @when getAuthStatus() called
|
336
|
+
* @then Includes time until expiry
|
337
|
+
*/
|
338
|
+
it('should include token expiry time in status', async () => {
|
339
|
+
manager.registerProvider(qwenProvider);
|
340
|
+
await manager.authenticate('qwen');
|
341
|
+
const statuses = await manager.getAuthStatus();
|
342
|
+
const qwenStatus = statuses.find((s) => s.provider === 'qwen');
|
343
|
+
expect(qwenStatus?.authenticated).toBe(true);
|
344
|
+
expect(qwenStatus?.expiresIn).toBeDefined();
|
345
|
+
expect(qwenStatus?.expiresIn).toBeGreaterThan(0);
|
346
|
+
});
|
347
|
+
/**
|
348
|
+
* @requirement REQ-005.4
|
349
|
+
* @scenario Status for mixed OAuth enablement and authentication states
|
350
|
+
* @given Some providers OAuth enabled/authenticated, others disabled
|
351
|
+
* @when getAuthStatus() called
|
352
|
+
* @then Returns accurate status for each provider
|
353
|
+
* @and Differentiates between OAuth enablement and auth types
|
354
|
+
*/
|
355
|
+
it('should report mixed OAuth enablement and authentication states accurately', async () => {
|
356
|
+
manager.registerProvider(qwenProvider);
|
357
|
+
manager.registerProvider(geminiProvider);
|
358
|
+
// Mock mixed OAuth enablement states
|
359
|
+
const mockIsEnabled = vi
|
360
|
+
.fn()
|
361
|
+
.mockImplementation((provider) => provider === 'qwen');
|
362
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
363
|
+
// Only trigger authentication for qwen
|
364
|
+
await manager.getToken('qwen');
|
365
|
+
const statuses = await manager.getAuthStatus();
|
366
|
+
expect(statuses).toHaveLength(2);
|
367
|
+
const qwenStatus = statuses.find((s) => s.provider === 'qwen');
|
368
|
+
const geminiStatus = statuses.find((s) => s.provider === 'gemini');
|
369
|
+
expect(qwenStatus?.authType).toBe('oauth');
|
370
|
+
expect(qwenStatus?.oauthEnabled).toBe(true);
|
371
|
+
expect(geminiStatus?.authType).toBe('none');
|
372
|
+
expect(geminiStatus?.oauthEnabled).toBe(false);
|
373
|
+
});
|
374
|
+
});
|
375
|
+
describe('Error Handling', () => {
|
376
|
+
/**
|
377
|
+
* @requirement REQ-001.3
|
378
|
+
* @scenario Toggle OAuth for unknown provider
|
379
|
+
* @given Provider 'unknown' not registered
|
380
|
+
* @when toggleOAuthEnabled('unknown') called
|
381
|
+
* @then Throws provider not found error
|
382
|
+
*/
|
383
|
+
it('should throw error for unknown provider OAuth toggle', async () => {
|
384
|
+
const mockToggle = vi
|
385
|
+
.fn()
|
386
|
+
.mockRejectedValue(new Error('Unknown provider: unknown'));
|
387
|
+
manager.toggleOAuthEnabled = mockToggle;
|
388
|
+
await expect(manager.toggleOAuthEnabled('unknown')).rejects.toThrow('Unknown provider: unknown');
|
389
|
+
});
|
390
|
+
/**
|
391
|
+
* @requirement REQ-003.1
|
392
|
+
* @scenario Get token for unknown provider
|
393
|
+
* @given Provider 'unknown' not registered
|
394
|
+
* @when getToken('unknown') called
|
395
|
+
* @then Throws provider not found error
|
396
|
+
*/
|
397
|
+
it('should return null for unknown provider token request', async () => {
|
398
|
+
const token = await manager.getToken('unknown');
|
399
|
+
expect(token).toBeNull();
|
400
|
+
});
|
401
|
+
/**
|
402
|
+
* @requirement REQ-001.3
|
403
|
+
* @scenario Handle lazy authentication failure
|
404
|
+
* @given Provider OAuth enabled but authentication fails when triggered
|
405
|
+
* @when getToken() called (triggering lazy auth)
|
406
|
+
* @then Propagates authentication error
|
407
|
+
* @and Provider remains unauthenticated
|
408
|
+
*/
|
409
|
+
it('should handle lazy authentication failures gracefully', async () => {
|
410
|
+
const failingProvider = new MockOAuthProvider('failing');
|
411
|
+
failingProvider.initiateAuth = async () => {
|
412
|
+
throw new Error('OAuth flow failed');
|
413
|
+
};
|
414
|
+
manager.registerProvider(failingProvider);
|
415
|
+
// Mock OAuth as enabled
|
416
|
+
const mockIsEnabled = vi.fn().mockResolvedValue(true);
|
417
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
418
|
+
await expect(manager.getToken('failing')).rejects.toThrow('OAuth flow failed');
|
419
|
+
});
|
420
|
+
});
|
421
|
+
describe('Provider Discovery', () => {
|
422
|
+
/**
|
423
|
+
* @requirement REQ-001.1
|
424
|
+
* @scenario List empty providers initially
|
425
|
+
* @given Newly created OAuth manager
|
426
|
+
* @when getSupportedProviders() called
|
427
|
+
* @then Returns empty array
|
428
|
+
*/
|
429
|
+
it('should return empty list when no providers registered', () => {
|
430
|
+
const providers = manager.getSupportedProviders();
|
431
|
+
expect(providers).toEqual([]);
|
432
|
+
});
|
433
|
+
/**
|
434
|
+
* @requirement REQ-001.2
|
435
|
+
* @scenario Filter OAuth-only providers
|
436
|
+
* @given OAuth and API key providers registered
|
437
|
+
* @when getSupportedProviders() called
|
438
|
+
* @then Returns only OAuth-capable providers
|
439
|
+
*/
|
440
|
+
it('should filter and return only OAuth-capable providers', () => {
|
441
|
+
manager.registerProvider(qwenProvider);
|
442
|
+
manager.registerProvider(geminiProvider);
|
443
|
+
const providers = manager.getSupportedProviders();
|
444
|
+
expect(providers).toContain('qwen');
|
445
|
+
expect(providers).toContain('gemini');
|
446
|
+
// Only OAuth providers should be returned
|
447
|
+
});
|
448
|
+
/**
|
449
|
+
* @requirement REQ-001.1
|
450
|
+
* @scenario Provider registration order independence
|
451
|
+
* @given Providers registered in different orders
|
452
|
+
* @when getSupportedProviders() called
|
453
|
+
* @then Always returns sorted list
|
454
|
+
* @and Order independent of registration sequence
|
455
|
+
*/
|
456
|
+
it('should return providers in consistent sorted order regardless of registration order', () => {
|
457
|
+
// Register in different order
|
458
|
+
manager.registerProvider(qwenProvider);
|
459
|
+
manager.registerProvider(geminiProvider);
|
460
|
+
const firstOrder = manager.getSupportedProviders();
|
461
|
+
const manager2 = new OAuthManager(tokenStore);
|
462
|
+
manager2.registerProvider(geminiProvider);
|
463
|
+
manager2.registerProvider(qwenProvider);
|
464
|
+
const secondOrder = manager2.getSupportedProviders();
|
465
|
+
expect(firstOrder).toEqual(secondOrder);
|
466
|
+
expect(firstOrder).toEqual(['gemini', 'qwen']);
|
467
|
+
});
|
468
|
+
});
|
469
|
+
describe('Integration Scenarios', () => {
|
470
|
+
/**
|
471
|
+
* @requirement REQ-001.3
|
472
|
+
* @scenario Complete OAuth enablement and lazy authentication lifecycle
|
473
|
+
* @given Fresh OAuth manager
|
474
|
+
* @when Register provider, enable OAuth, then retrieve token
|
475
|
+
* @then OAuth enablement persists and lazy authentication succeeds
|
476
|
+
* @and Token is available after lazy authentication
|
477
|
+
*/
|
478
|
+
it('should support complete OAuth enablement and lazy auth lifecycle', async () => {
|
479
|
+
manager.registerProvider(qwenProvider);
|
480
|
+
// Enable OAuth (would persist in real implementation)
|
481
|
+
const mockToggle = vi.fn().mockResolvedValue(true);
|
482
|
+
const mockIsEnabled = vi.fn().mockResolvedValue(true);
|
483
|
+
manager.toggleOAuthEnabled = mockToggle;
|
484
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
485
|
+
await manager.toggleOAuthEnabled('qwen');
|
486
|
+
// Lazy authentication should trigger when token is needed
|
487
|
+
const token = await manager.getToken('qwen');
|
488
|
+
expect(token).not.toBeNull();
|
489
|
+
expect(token).toBeDefined();
|
490
|
+
expect(qwenProvider.wasAuthInitiated()).toBe(true);
|
491
|
+
});
|
492
|
+
/**
|
493
|
+
* @requirement REQ-003.1
|
494
|
+
* @scenario OAuth enablement and token persistence across manager instances
|
495
|
+
* @given OAuth enabled and authenticated provider with stored token
|
496
|
+
* @when New manager instance created
|
497
|
+
* @then OAuth enablement and token remain accessible
|
498
|
+
* @and No additional authentication needed
|
499
|
+
*/
|
500
|
+
it('should persist OAuth enablement and tokens across manager instances', async () => {
|
501
|
+
// Enable OAuth and authenticate with first manager
|
502
|
+
manager.registerProvider(qwenProvider);
|
503
|
+
const mockToggle = vi.fn().mockResolvedValue(true);
|
504
|
+
const mockIsEnabled = vi.fn().mockResolvedValue(true);
|
505
|
+
manager.toggleOAuthEnabled = mockToggle;
|
506
|
+
manager.isOAuthEnabled = mockIsEnabled;
|
507
|
+
await manager.toggleOAuthEnabled('qwen');
|
508
|
+
await manager.getToken('qwen'); // Triggers lazy auth
|
509
|
+
// Create new manager with same token store
|
510
|
+
const newManager = new OAuthManager(tokenStore);
|
511
|
+
const newProvider = new MockOAuthProvider('qwen');
|
512
|
+
newManager.registerProvider(newProvider);
|
513
|
+
// Mock OAuth as still enabled in new manager
|
514
|
+
newManager.isOAuthEnabled = mockIsEnabled;
|
515
|
+
const token = await newManager.getToken('qwen');
|
516
|
+
expect(token).not.toBeNull();
|
517
|
+
expect(token).toBeDefined();
|
518
|
+
// New provider shouldn't need to authenticate since token exists
|
519
|
+
expect(newProvider.wasAuthInitiated()).toBe(false);
|
520
|
+
});
|
521
|
+
});
|
522
|
+
});
|
523
|
+
//# sourceMappingURL=oauth-manager.spec.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"oauth-manager.spec.js","sourceRoot":"","sources":["../../../src/auth/oauth-manager.spec.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* Qwen OAuth Provider Implementation
|
3
|
+
*/
|
4
|
+
import { OAuthProvider } from './oauth-manager.js';
|
5
|
+
import { OAuthToken } from '@vybestack/llxprt-code-core';
|
6
|
+
export declare class QwenOAuthProvider implements OAuthProvider {
|
7
|
+
name: string;
|
8
|
+
private deviceFlow;
|
9
|
+
private currentToken;
|
10
|
+
constructor();
|
11
|
+
initiateAuth(): Promise<void>;
|
12
|
+
getToken(): Promise<OAuthToken | null>;
|
13
|
+
refreshIfNeeded(): Promise<OAuthToken | null>;
|
14
|
+
}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
/**
|
2
|
+
* Qwen OAuth Provider Implementation
|
3
|
+
*/
|
4
|
+
import { QwenDeviceFlow, openBrowserSecurely, shouldLaunchBrowser, } from '@vybestack/llxprt-code-core';
|
5
|
+
export class QwenOAuthProvider {
|
6
|
+
name = 'qwen';
|
7
|
+
deviceFlow;
|
8
|
+
currentToken = null;
|
9
|
+
constructor() {
|
10
|
+
const config = {
|
11
|
+
clientId: 'f0304373b74a44d2b584a3fb70ca9e56',
|
12
|
+
authorizationEndpoint: 'https://chat.qwen.ai/api/v1/oauth2/device/code',
|
13
|
+
tokenEndpoint: 'https://chat.qwen.ai/api/v1/oauth2/token',
|
14
|
+
scopes: ['openid', 'profile', 'email', 'model.completion'],
|
15
|
+
};
|
16
|
+
this.deviceFlow = new QwenDeviceFlow(config);
|
17
|
+
}
|
18
|
+
async initiateAuth() {
|
19
|
+
// Start device flow
|
20
|
+
const deviceCodeResponse = await this.deviceFlow.initiateDeviceFlow();
|
21
|
+
// Construct the authorization URL
|
22
|
+
const authUrl = deviceCodeResponse.verification_uri_complete ||
|
23
|
+
`${deviceCodeResponse.verification_uri}?user_code=${deviceCodeResponse.user_code}`;
|
24
|
+
// Display user instructions
|
25
|
+
console.log('\nQwen OAuth Authentication');
|
26
|
+
console.log('─'.repeat(40));
|
27
|
+
// Try to open browser if appropriate
|
28
|
+
if (shouldLaunchBrowser()) {
|
29
|
+
console.log('Opening browser for authentication...');
|
30
|
+
console.log('If the browser does not open, please visit:');
|
31
|
+
console.log(authUrl);
|
32
|
+
try {
|
33
|
+
await openBrowserSecurely(authUrl);
|
34
|
+
}
|
35
|
+
catch (_error) {
|
36
|
+
// If browser fails to open, just show the URL
|
37
|
+
console.log('Failed to open browser automatically.');
|
38
|
+
}
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
// In non-interactive environments, just show the URL
|
42
|
+
console.log('Visit this URL to authorize:');
|
43
|
+
console.log(authUrl);
|
44
|
+
}
|
45
|
+
console.log('─'.repeat(40));
|
46
|
+
console.log('Waiting for authorization...\n');
|
47
|
+
// Poll for token
|
48
|
+
this.currentToken = await this.deviceFlow.pollForToken(deviceCodeResponse.device_code);
|
49
|
+
}
|
50
|
+
async getToken() {
|
51
|
+
return this.currentToken;
|
52
|
+
}
|
53
|
+
async refreshIfNeeded() {
|
54
|
+
if (!this.currentToken) {
|
55
|
+
return null;
|
56
|
+
}
|
57
|
+
// Check if token needs refresh (30 second buffer)
|
58
|
+
const now = Date.now() / 1000;
|
59
|
+
const expiresAt = this.currentToken.expiry;
|
60
|
+
if (expiresAt && expiresAt - now < 30) {
|
61
|
+
// Token expires soon, refresh it
|
62
|
+
if (this.currentToken.refresh_token) {
|
63
|
+
try {
|
64
|
+
this.currentToken = await this.deviceFlow.refreshToken(this.currentToken.refresh_token);
|
65
|
+
}
|
66
|
+
catch (error) {
|
67
|
+
console.error('Failed to refresh Qwen token:', error);
|
68
|
+
return null;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
return this.currentToken;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
//# sourceMappingURL=qwen-oauth-provider.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"qwen-oauth-provider.js","sourceRoot":"","sources":["../../../src/auth/qwen-oauth-provider.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC"}
|