mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
- security: XSS sanitization with DOMPurify in Markdown/Mermaid/PermissionDialog; path whitelist in filesystem API; fake keys in test/config files - perf: fine-grained Zustand selectors in Sidebar/StatusBar/ContentRouter; 50ms throttle on streaming deltas; React.memo + useMemo in MessageList; useRef for frequent keyboard shortcut state; AbortController 30s timeout - leaks: WS session TTL timers (5-min cleanup on close); batch splice for sdkMessages/stderrLines; folderPath validation in cronScheduler - quality: optimistic update rollback in settingsStore; error state in providerStore/teamStore; i18n for all hardcoded English strings - docs: desktop architecture and features docs updated; VitePress nav fixed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
// desktop/src/stores/providerStore.ts
|
|
|
|
import { create } from 'zustand'
|
|
import { providersApi } from '../api/providers'
|
|
import type {
|
|
SavedProvider,
|
|
CreateProviderInput,
|
|
UpdateProviderInput,
|
|
TestProviderConfigInput,
|
|
ProviderTestResult,
|
|
} from '../types/provider'
|
|
|
|
type ProviderStore = {
|
|
providers: SavedProvider[]
|
|
activeId: string | null
|
|
isLoading: boolean
|
|
error: string | null
|
|
|
|
fetchProviders: () => Promise<void>
|
|
createProvider: (input: CreateProviderInput) => Promise<SavedProvider>
|
|
updateProvider: (id: string, input: UpdateProviderInput) => Promise<SavedProvider>
|
|
deleteProvider: (id: string) => Promise<void>
|
|
activateProvider: (id: string) => Promise<void>
|
|
activateOfficial: () => Promise<void>
|
|
testProvider: (id: string, overrides?: { baseUrl?: string; modelId?: string; apiFormat?: string }) => Promise<ProviderTestResult>
|
|
testConfig: (input: TestProviderConfigInput) => Promise<ProviderTestResult>
|
|
}
|
|
|
|
export const useProviderStore = create<ProviderStore>((set, get) => ({
|
|
providers: [],
|
|
activeId: null,
|
|
isLoading: false,
|
|
error: null,
|
|
|
|
fetchProviders: async () => {
|
|
set({ isLoading: true, error: null })
|
|
try {
|
|
const { providers, activeId } = await providersApi.list()
|
|
set({ providers, activeId, isLoading: false })
|
|
} catch (err) {
|
|
set({ isLoading: false, error: err instanceof Error ? err.message : String(err) })
|
|
}
|
|
},
|
|
|
|
createProvider: async (input) => {
|
|
const { provider } = await providersApi.create(input)
|
|
await get().fetchProviders()
|
|
return provider
|
|
},
|
|
|
|
updateProvider: async (id, input) => {
|
|
const { provider } = await providersApi.update(id, input)
|
|
await get().fetchProviders()
|
|
return provider
|
|
},
|
|
|
|
deleteProvider: async (id) => {
|
|
await providersApi.delete(id)
|
|
await get().fetchProviders()
|
|
},
|
|
|
|
activateProvider: async (id) => {
|
|
await providersApi.activate(id)
|
|
await get().fetchProviders()
|
|
},
|
|
|
|
activateOfficial: async () => {
|
|
await providersApi.activateOfficial()
|
|
await get().fetchProviders()
|
|
},
|
|
|
|
testProvider: async (id, overrides?) => {
|
|
const { result } = await providersApi.test(id, overrides)
|
|
return result
|
|
},
|
|
|
|
testConfig: async (input) => {
|
|
const { result } = await providersApi.testConfig(input)
|
|
return result
|
|
},
|
|
}))
|