refactor: migrate goto-anything service fetching to oRPC contract-first pattern

Replace direct service calls with typed oRPC contracts for apps, datasets,
and plugins search in the goto-anything feature. This provides better type
safety and consistent API patterns across the codebase.
This commit is contained in:
yyh 2026-01-15 22:03:13 +08:00
parent 9235bb0b79
commit 8b32800942
No known key found for this signature in database
6 changed files with 83 additions and 29 deletions

View File

@ -1,6 +1,6 @@
import type { AppSearchResult, ScopeDescriptor } from './types'
import type { App } from '@/types/app'
import { fetchAppList } from '@/service/apps'
import { searchApps } from '@/service/use-goto-anything'
import { getRedirectionPath } from '@/utils/app-redirection'
import { AppTypeIcon } from '../../app/type-selector'
import AppIcon from '../../base/app-icon'
@ -41,16 +41,9 @@ export const appScope: ScopeDescriptor = {
shortcut: ACTION_KEYS.APP,
title: 'Search Applications',
description: 'Search and navigate to your applications',
// action,
search: async (_, searchTerm = '', _locale) => {
try {
const response = await fetchAppList({
url: 'apps',
params: {
page: 1,
name: searchTerm,
},
})
const response = await searchApps(searchTerm)
const apps = response?.data || []
return parser(apps)
}

View File

@ -1,6 +1,6 @@
import type { KnowledgeSearchResult, ScopeDescriptor } from './types'
import type { DataSet } from '@/models/datasets'
import { fetchDatasets } from '@/service/datasets'
import { searchDatasets } from '@/service/use-goto-anything'
import { cn } from '@/utils/classnames'
import { Folder } from '../../base/icons/src/vender/solid/files'
import { ACTION_KEYS } from '../constants'
@ -37,17 +37,9 @@ export const knowledgeScope: ScopeDescriptor = {
aliases: ['@kb'],
title: 'Search Knowledge Bases',
description: 'Search and navigate to your knowledge bases',
// action,
search: async (_, searchTerm = '', _locale) => {
try {
const response = await fetchDatasets({
url: '/datasets',
params: {
page: 1,
limit: 10,
keyword: searchTerm,
},
})
const response = await searchDatasets(searchTerm)
const datasets = response?.data || []
return parser(datasets)
}

View File

@ -1,7 +1,7 @@
import type { Plugin, PluginsFromMarketplaceResponse } from '../../plugins/types'
import type { Plugin } from '../../plugins/types'
import type { PluginSearchResult, ScopeDescriptor } from './types'
import { renderI18nObject } from '@/i18n-config'
import { postMarketplace } from '@/service/base'
import { searchPlugins } from '@/service/use-goto-anything'
import Icon from '../../plugins/card/base/card-icon'
import { getPluginIconInMarketplace } from '../../plugins/marketplace/utils'
import { ACTION_KEYS } from '../constants'
@ -26,14 +26,7 @@ export const pluginScope: ScopeDescriptor = {
description: 'Search and navigate to your plugins',
search: async (_, searchTerm = '', locale) => {
try {
const response = await postMarketplace<{ data: PluginsFromMarketplaceResponse }>('/plugins/search/advanced', {
body: {
page: 1,
page_size: 10,
query: searchTerm,
type: 'plugin',
},
})
const response = await searchPlugins(searchTerm)
if (!response?.data?.plugins) {
console.warn('Plugin search: Unexpected response structure', response)

View File

@ -0,0 +1,32 @@
import type { AppListResponse } from '@/models/app'
import type { DataSetListResponse } from '@/models/datasets'
import { type } from '@orpc/contract'
import { base } from '../base'
export const searchAppsContract = base
.route({
path: '/apps',
method: 'GET',
})
.input(type<{
query?: {
page?: number
limit?: number
name?: string
}
}>())
.output(type<AppListResponse>())
export const searchDatasetsContract = base
.route({
path: '/datasets',
method: 'GET',
})
.input(type<{
query?: {
page?: number
limit?: number
keyword?: string
}
}>())
.output(type<DataSetListResponse>())

View File

@ -1,5 +1,6 @@
import type { InferContractRouterInputs } from '@orpc/contract'
import { bindPartnerStackContract, invoicesContract } from './console/billing'
import { searchAppsContract, searchDatasetsContract } from './console/goto-anything'
import { systemFeaturesContract } from './console/system'
import { collectionPluginsContract, collectionsContract, searchAdvancedContract } from './marketplace'
@ -17,6 +18,10 @@ export const consoleRouterContract = {
invoices: invoicesContract,
bindPartnerStack: bindPartnerStackContract,
},
gotoAnything: {
searchApps: searchAppsContract,
searchDatasets: searchDatasetsContract,
},
}
export type ConsoleInputs = InferContractRouterInputs<typeof consoleRouterContract>

View File

@ -0,0 +1,39 @@
import { consoleClient, consoleQuery, marketplaceClient, marketplaceQuery } from '@/service/client'
export const searchAppsQueryKey = consoleQuery.gotoAnything.searchApps.queryKey
export const searchApps = async (name?: string) => {
return consoleClient.gotoAnything.searchApps({
query: {
page: 1,
name,
},
})
}
export const searchDatasetsQueryKey = consoleQuery.gotoAnything.searchDatasets.queryKey
export const searchDatasets = async (keyword?: string) => {
return consoleClient.gotoAnything.searchDatasets({
query: {
page: 1,
limit: 10,
keyword,
},
})
}
export const searchPluginsQueryKey = marketplaceQuery.searchAdvanced.queryKey
export const searchPlugins = async (query?: string) => {
return marketplaceClient.searchAdvanced({
params: {
kind: 'plugins',
},
body: {
query: query || '',
page: 1,
page_size: 10,
},
})
}