refactor: init orpc contract (#30885)

Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
This commit is contained in:
Stephen Zhou
2026-01-13 22:38:28 +08:00
committed by GitHub
parent a129e684cc
commit 91da784f84
29 changed files with 520 additions and 229 deletions
+5
View File
@@ -81,6 +81,11 @@ export type IOtherOptions = {
needAllResponseContent?: boolean
deleteContentType?: boolean
silent?: boolean
/** If true, behaves like standard fetch: no URL prefix, returns raw Response */
fetchCompat?: boolean
request?: Request
onData?: IOnData // for stream
onThought?: IOnThought
onFile?: IOnFile
+1 -15
View File
@@ -1,5 +1,5 @@
import type { CurrentPlanInfoBackend, SubscriptionUrlsBackend } from '@/app/components/billing/type'
import { get, put } from './base'
import { get } from './base'
export const fetchCurrentPlanInfo = () => {
return get<CurrentPlanInfoBackend>('/features')
@@ -8,17 +8,3 @@ export const fetchCurrentPlanInfo = () => {
export const fetchSubscriptionUrls = (plan: string, interval: string) => {
return get<SubscriptionUrlsBackend>(`/billing/subscription?plan=${plan}&interval=${interval}`)
}
export const fetchBillingUrl = () => {
return get<{ url: string }>('/billing/invoices')
}
export const bindPartnerStackInfo = (partnerKey: string, clickId: string) => {
return put(`/billing/partners/${partnerKey}/tenants`, {
body: {
click_id: clickId,
},
}, {
silent: true,
})
}
+61
View File
@@ -0,0 +1,61 @@
import type { ContractRouterClient } from '@orpc/contract'
import type { JsonifiedClient } from '@orpc/openapi-client'
import { createORPCClient, onError } from '@orpc/client'
import { OpenAPILink } from '@orpc/openapi-client/fetch'
import { createTanstackQueryUtils } from '@orpc/tanstack-query'
import {
API_PREFIX,
APP_VERSION,
IS_MARKETPLACE,
MARKETPLACE_API_PREFIX,
} from '@/config'
import {
consoleRouterContract,
marketplaceRouterContract,
} from '@/contract/router'
import { request } from './base'
const getMarketplaceHeaders = () => new Headers({
'X-Dify-Version': !IS_MARKETPLACE ? APP_VERSION : '999.0.0',
})
const marketplaceLink = new OpenAPILink(marketplaceRouterContract, {
url: MARKETPLACE_API_PREFIX,
headers: () => (getMarketplaceHeaders()),
fetch: (request, init) => {
return globalThis.fetch(request, {
...init,
cache: 'no-store',
})
},
interceptors: [
onError((error) => {
console.error(error)
}),
],
})
export const marketplaceClient: JsonifiedClient<ContractRouterClient<typeof marketplaceRouterContract>> = createORPCClient(marketplaceLink)
export const marketplaceQuery = createTanstackQueryUtils(marketplaceClient, { path: ['marketplace'] })
const consoleLink = new OpenAPILink(consoleRouterContract, {
url: API_PREFIX,
fetch: (input, init) => {
return request(
input.url,
init,
{
fetchCompat: true,
request: input,
},
)
},
interceptors: [
onError((error) => {
console.error(error)
}),
],
})
export const consoleClient: JsonifiedClient<ContractRouterClient<typeof consoleRouterContract>> = createORPCClient(consoleLink)
export const consoleQuery = createTanstackQueryUtils(consoleClient, { path: ['console'] })
-5
View File
@@ -34,7 +34,6 @@ import type {
UserProfileOriginResponse,
} from '@/models/common'
import type { RETRIEVE_METHOD } from '@/types/app'
import type { SystemFeatures } from '@/types/feature'
import { del, get, patch, post, put } from './base'
type LoginSuccess = {
@@ -307,10 +306,6 @@ export const fetchSupportRetrievalMethods = (url: string): Promise<RetrievalMeth
return get<RetrievalMethodsRes>(url)
}
export const getSystemFeatures = (): Promise<SystemFeatures> => {
return get<SystemFeatures>('/system-features')
}
export const enableModel = (url: string, body: { model: string, model_type: ModelTypeEnum }): Promise<CommonResponse> =>
patch<CommonResponse>(url, { body })
+6 -4
View File
@@ -136,6 +136,8 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
needAllResponseContent,
deleteContentType,
getAbortController,
fetchCompat = false,
request,
} = otherOptions
let base: string
@@ -181,7 +183,7 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
},
})
const res = await client(fetchPathname, {
const res = await client(request || fetchPathname, {
...init,
headers,
credentials: isMarketplaceAPI
@@ -190,8 +192,8 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
retry: {
methods: [],
},
...(bodyStringify ? { json: body } : { body: body as BodyInit }),
searchParams: params,
...(bodyStringify && !fetchCompat ? { json: body } : { body: body as BodyInit }),
searchParams: !fetchCompat ? params : undefined,
fetch(resource: RequestInfo | URL, options?: RequestInit) {
if (resource instanceof Request && options) {
const mergedHeaders = new Headers(options.headers || {})
@@ -204,7 +206,7 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
},
})
if (needAllResponseContent)
if (needAllResponseContent || fetchCompat)
return res as T
const contentType = res.headers.get('content-type')
if (
+8 -7
View File
@@ -1,21 +1,22 @@
import { useMutation, useQuery } from '@tanstack/react-query'
import { bindPartnerStackInfo, fetchBillingUrl } from '@/service/billing'
const NAME_SPACE = 'billing'
import { consoleClient, consoleQuery } from '@/service/client'
export const useBindPartnerStackInfo = () => {
return useMutation({
mutationKey: [NAME_SPACE, 'bind-partner-stack'],
mutationFn: (data: { partnerKey: string, clickId: string }) => bindPartnerStackInfo(data.partnerKey, data.clickId),
mutationKey: consoleQuery.bindPartnerStack.mutationKey(),
mutationFn: (data: { partnerKey: string, clickId: string }) => consoleClient.bindPartnerStack({
params: { partnerKey: data.partnerKey },
body: { click_id: data.clickId },
}),
})
}
export const useBillingUrl = (enabled: boolean) => {
return useQuery({
queryKey: [NAME_SPACE, 'url'],
queryKey: consoleQuery.billingUrl.queryKey(),
enabled,
queryFn: async () => {
const res = await fetchBillingUrl()
const res = await consoleClient.billingUrl()
return res.url
},
})
+12 -12
View File
@@ -488,23 +488,23 @@ export const useMutationPluginsFromMarketplace = () => {
mutationFn: (pluginsSearchParams: PluginsSearchParams) => {
const {
query,
sortBy,
sortOrder,
sort_by,
sort_order,
category,
tags,
exclude,
type,
page = 1,
pageSize = 40,
page_size = 40,
} = pluginsSearchParams
const pluginOrBundle = type === 'bundle' ? 'bundles' : 'plugins'
return postMarketplace<{ data: PluginsFromMarketplaceResponse }>(`/${pluginOrBundle}/search/advanced`, {
body: {
page,
page_size: pageSize,
page_size,
query,
sort_by: sortBy,
sort_order: sortOrder,
sort_by,
sort_order,
category: category !== 'all' ? category : '',
tags,
exclude,
@@ -535,23 +535,23 @@ export const useFetchPluginListOrBundleList = (pluginsSearchParams: PluginsSearc
queryFn: () => {
const {
query,
sortBy,
sortOrder,
sort_by,
sort_order,
category,
tags,
exclude,
type,
page = 1,
pageSize = 40,
page_size = 40,
} = pluginsSearchParams
const pluginOrBundle = type === 'bundle' ? 'bundles' : 'plugins'
return postMarketplace<{ data: PluginsFromMarketplaceResponse }>(`/${pluginOrBundle}/search/advanced`, {
body: {
page,
page_size: pageSize,
page_size,
query,
sort_by: sortBy,
sort_order: sortOrder,
sort_by,
sort_order,
category: category !== 'all' ? category : '',
tags,
exclude,