refactor: migrate sandbox-provider API to ORPC

Replace manual fetch calls in use-sandbox-provider.ts with typed ORPC
contracts and client. Adds type definitions to types/sandbox-provider.ts
and registers contracts in the console router for consistent API handling.
This commit is contained in:
yyh
2026-01-14 10:07:27 +08:00
parent 7c029ce808
commit 3b78f9c2a5
4 changed files with 124 additions and 42 deletions

View File

@ -1,4 +1,5 @@
import type { SystemFeatures } from '@/types/feature'
import type { SandboxProvider } from '@/types/sandbox-provider'
import { type } from '@orpc/contract'
import { base } from './base'
@ -32,3 +33,71 @@ export const bindPartnerStackContract = base
}
}>())
.output(type<unknown>())
// Sandbox Provider contracts
export const getSandboxProviderListContract = base
.route({
path: '/workspaces/current/sandbox-providers',
method: 'GET',
})
.input(type<unknown>())
.output(type<SandboxProvider[]>())
export const getSandboxProviderContract = base
.route({
path: '/workspaces/current/sandbox-provider/{providerType}',
method: 'GET',
})
.input(type<{
params: {
providerType: string
}
}>())
.output(type<SandboxProvider>())
export const saveSandboxProviderConfigContract = base
.route({
path: '/workspaces/current/sandbox-provider/{providerType}/config',
method: 'POST',
})
.input(type<{
params: {
providerType: string
}
body: {
config: Record<string, string>
}
}>())
.output(type<{ result: string }>())
export const deleteSandboxProviderConfigContract = base
.route({
path: '/workspaces/current/sandbox-provider/{providerType}/config',
method: 'DELETE',
})
.input(type<{
params: {
providerType: string
}
}>())
.output(type<{ result: string }>())
export const activateSandboxProviderContract = base
.route({
path: '/workspaces/current/sandbox-provider/{providerType}/activate',
method: 'POST',
})
.input(type<{
params: {
providerType: string
}
}>())
.output(type<{ result: string }>())
export const getActiveSandboxProviderContract = base
.route({
path: '/workspaces/current/sandbox-provider/active',
method: 'GET',
})
.input(type<unknown>())
.output(type<{ provider_type: string | null }>())

View File

@ -1,5 +1,15 @@
import type { InferContractRouterInputs } from '@orpc/contract'
import { billingUrlContract, bindPartnerStackContract, systemFeaturesContract } from './console'
import {
activateSandboxProviderContract,
billingUrlContract,
bindPartnerStackContract,
deleteSandboxProviderConfigContract,
getActiveSandboxProviderContract,
getSandboxProviderContract,
getSandboxProviderListContract,
saveSandboxProviderConfigContract,
systemFeaturesContract,
} from './console'
import { collectionPluginsContract, collectionsContract, searchAdvancedContract } from './marketplace'
export const marketplaceRouterContract = {
@ -14,6 +24,12 @@ export const consoleRouterContract = {
systemFeatures: systemFeaturesContract,
billingUrl: billingUrlContract,
bindPartnerStack: bindPartnerStackContract,
getSandboxProviderList: getSandboxProviderListContract,
getSandboxProvider: getSandboxProviderContract,
saveSandboxProviderConfig: saveSandboxProviderConfigContract,
deleteSandboxProviderConfig: deleteSandboxProviderConfigContract,
activateSandboxProvider: activateSandboxProviderContract,
getActiveSandboxProvider: getActiveSandboxProviderContract,
}
export type ConsoleInputs = InferContractRouterInputs<typeof consoleRouterContract>

View File

@ -3,46 +3,22 @@ import {
useQuery,
useQueryClient,
} from '@tanstack/react-query'
import { del, get, post } from './base'
import { consoleClient, consoleQuery } from '@/service/client'
const NAME_SPACE = 'sandbox-provider'
export const sandboxProviderQueryKeys = {
all: [NAME_SPACE] as const,
list: [NAME_SPACE, 'list'] as const,
provider: (providerType: string) => [NAME_SPACE, 'provider', providerType] as const,
active: [NAME_SPACE, 'active'] as const,
}
export type ConfigSchema = {
name: string
type: string
}
export type SandboxProvider = {
provider_type: string
label: string
description: string
icon: string
is_system_configured: boolean
is_tenant_configured: boolean
is_active: boolean
config: Record<string, string>
config_schema: ConfigSchema[]
}
export type { ConfigSchema, SandboxProvider } from '@/types/sandbox-provider'
export const useGetSandboxProviderList = () => {
return useQuery({
queryKey: sandboxProviderQueryKeys.list,
queryFn: () => get<SandboxProvider[]>('/workspaces/current/sandbox-providers'),
queryKey: consoleQuery.getSandboxProviderList.queryKey(),
queryFn: () => consoleClient.getSandboxProviderList(),
retry: 0,
})
}
export const useGetSandboxProvider = (providerType: string) => {
return useQuery({
queryKey: sandboxProviderQueryKeys.provider(providerType),
queryFn: () => get<SandboxProvider>(`/workspaces/current/sandbox-provider/${providerType}`),
queryKey: consoleQuery.getSandboxProvider.queryKey({ input: { params: { providerType } } }),
queryFn: () => consoleClient.getSandboxProvider({ params: { providerType } }),
retry: 0,
enabled: !!providerType,
})
@ -51,14 +27,15 @@ export const useGetSandboxProvider = (providerType: string) => {
export const useSaveSandboxProviderConfig = () => {
const queryClient = useQueryClient()
return useMutation({
mutationKey: [NAME_SPACE, 'save-config'],
mutationKey: consoleQuery.saveSandboxProviderConfig.mutationKey(),
mutationFn: ({ providerType, config }: { providerType: string, config: Record<string, string> }) => {
return post<{ result: string }>(`/workspaces/current/sandbox-provider/${providerType}/config`, {
return consoleClient.saveSandboxProviderConfig({
params: { providerType },
body: { config },
})
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: sandboxProviderQueryKeys.list })
queryClient.invalidateQueries({ queryKey: consoleQuery.getSandboxProviderList.queryKey() })
},
})
}
@ -66,12 +43,14 @@ export const useSaveSandboxProviderConfig = () => {
export const useDeleteSandboxProviderConfig = () => {
const queryClient = useQueryClient()
return useMutation({
mutationKey: [NAME_SPACE, 'delete-config'],
mutationKey: consoleQuery.deleteSandboxProviderConfig.mutationKey(),
mutationFn: (providerType: string) => {
return del<{ result: string }>(`/workspaces/current/sandbox-provider/${providerType}/config`)
return consoleClient.deleteSandboxProviderConfig({
params: { providerType },
})
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: sandboxProviderQueryKeys.list })
queryClient.invalidateQueries({ queryKey: consoleQuery.getSandboxProviderList.queryKey() })
},
})
}
@ -79,20 +58,22 @@ export const useDeleteSandboxProviderConfig = () => {
export const useActivateSandboxProvider = () => {
const queryClient = useQueryClient()
return useMutation({
mutationKey: [NAME_SPACE, 'activate'],
mutationKey: consoleQuery.activateSandboxProvider.mutationKey(),
mutationFn: (providerType: string) => {
return post<{ result: string }>(`/workspaces/current/sandbox-provider/${providerType}/activate`)
return consoleClient.activateSandboxProvider({
params: { providerType },
})
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: sandboxProviderQueryKeys.list })
queryClient.invalidateQueries({ queryKey: consoleQuery.getSandboxProviderList.queryKey() })
},
})
}
export const useGetActiveSandboxProvider = () => {
return useQuery({
queryKey: sandboxProviderQueryKeys.active,
queryFn: () => get<{ provider_type: string | null }>('/workspaces/current/sandbox-provider/active'),
queryKey: consoleQuery.getActiveSandboxProvider.queryKey(),
queryFn: () => consoleClient.getActiveSandboxProvider(),
retry: 0,
})
}

View File

@ -0,0 +1,16 @@
export type ConfigSchema = {
name: string
type: string
}
export type SandboxProvider = {
provider_type: string
label: string
description: string
icon: string
is_system_configured: boolean
is_tenant_configured: boolean
is_active: boolean
config: Record<string, string>
config_schema: ConfigSchema[]
}