diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index ffabac36d0a..00f80bb66b7 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -156,7 +156,7 @@ jobs: - name: Generate frontend contracts if: github.event_name != 'merge_group' && steps.frontend-contract-changes.outputs.any_changed == 'true' - run: pnpm --dir packages/contracts gen-api-contract-from-openapi + run: pnpm --dir packages/contracts gen-api-contract - name: ESLint autofix if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true' diff --git a/packages/contracts/marketplace.ts b/packages/contracts/marketplace.ts new file mode 100644 index 00000000000..92db51412b0 --- /dev/null +++ b/packages/contracts/marketplace.ts @@ -0,0 +1,233 @@ +import type { InferContractRouterInputs } from '@orpc/contract' +import { oc, type } from '@orpc/contract' + +// This Marketplace contract is manually maintained because these APIs are not generated from Dify OpenAPI specs. + +const base = oc.$route({ inputStructure: 'detailed' }) + +export type SearchParamsFromCollection = { + query?: string + sort_by?: string + sort_order?: string +} + +export type MarketplaceCollection = { + name: string + label: Record + description: Record + rule: string + created_at: string + updated_at: string + searchable?: boolean + search_params?: SearchParamsFromCollection +} + +export type PluginsSearchParams = { + query: string + page?: number + page_size?: number + sort_by?: string + sort_order?: string + category?: string + tags?: string[] + exclude?: string[] + type?: 'plugin' | 'bundle' +} + +export type PluginsSort = { + sortBy: string + sortOrder: string +} + +export type CollectionsAndPluginsSearchParams = { + category?: string + condition?: string + exclude?: string[] + type?: 'plugin' | 'bundle' +} + +export type MarketplaceTemplate = { + id: string + template_name: string + overview: string + icon: string + icon_background: string + icon_file_key: string + publisher_unique_handle: string + usage_count: number + categories: string[] +} + +export type MarketplacePluginCategory + = | 'tool' + | 'model' + | 'extension' + | 'agent-strategy' + | 'datasource' + | 'trigger' + +export type MarketplacePluginType + = | 'plugin' + | 'bundle' + | 'model' + | 'extension' + | 'tool' + | 'agent_strategy' + | 'datasource' + | 'trigger' + +export type MarketplacePluginDependencySource = 'github' | 'marketplace' | 'package' + +export type MarketplaceI18nObject = Partial> + +export type MarketplacePlugin = { + type: MarketplacePluginType + org: string + author?: string + name: string + plugin_id: string + version: string + latest_version: string + latest_package_identifier: string + icon: string + icon_dark?: string + verified: boolean + label?: MarketplaceI18nObject + labels?: MarketplaceI18nObject + brief?: MarketplaceI18nObject | string + description?: MarketplaceI18nObject | string + introduction: string + repository: string + category: MarketplacePluginCategory + install_count: number + endpoint: { + settings: Array> + } + tags: Array<{ name: string }> + badges: string[] | null + verification: { + authorized_category: 'langgenius' | 'partner' | 'community' + } + from: MarketplacePluginDependencySource +} + +export type PluginInfoFromMarketPlace = { + category: MarketplacePluginCategory + latest_package_identifier: string + latest_version: string +} + +export type PluginsFromMarketplaceResponse = { + plugins: MarketplacePlugin[] + bundles?: MarketplacePlugin[] + total: number +} + +export type PluginsFromMarketplaceByInfoResponse = { + list: Array<{ + plugin: MarketplacePlugin + version: { + plugin_name: string + plugin_org: string + unique_identifier: string + } + }> +} + +export type CollectionsResponse = { + data?: { + collections?: MarketplaceCollection[] + } +} + +export type CollectionPluginsResponse = { + data?: { + plugins?: MarketplacePlugin[] + } +} + +export type SearchAdvancedResponse = { + data: PluginsFromMarketplaceResponse +} + +export type TemplateDetailResponse = { + data: MarketplaceTemplate +} + +export type DownloadPluginResponse = Blob + +const collectionsContract = base + .route({ + path: '/collections', + method: 'GET', + }) + .input( + type<{ + query?: CollectionsAndPluginsSearchParams & { page?: number, page_size?: number } + }>(), + ) + .output(type()) + +const collectionPluginsContract = base + .route({ + path: '/collections/{collectionId}/plugins', + method: 'POST', + }) + .input( + type<{ + params: { + collectionId: string + } + body?: CollectionsAndPluginsSearchParams + }>(), + ) + .output(type()) + +const searchAdvancedContract = base + .route({ + path: '/{kind}/search/advanced', + method: 'POST', + }) + .input(type<{ + params: { + kind: 'plugins' | 'bundles' + } + body: Omit + }>()) + .output(type()) + +const templateDetailContract = base + .route({ + path: '/templates/{templateId}', + method: 'GET', + }) + .input(type<{ + params: { + templateId: string + } + }>()) + .output(type()) + +const downloadPluginContract = base + .route({ + path: '/plugins/{organization}/{pluginName}/{version}/download', + method: 'GET', + }) + .input(type<{ + params: { + organization: string + pluginName: string + version: string + } + }>()) + .output(type()) + +export const marketplaceRouterContract = { + collections: collectionsContract, + collectionPlugins: collectionPluginsContract, + searchAdvanced: searchAdvancedContract, + templateDetail: templateDetailContract, + downloadPlugin: downloadPluginContract, +} + +export type MarketPlaceInputs = InferContractRouterInputs diff --git a/packages/contracts/package.json b/packages/contracts/package.json index c2dd43e990c..23356cc83aa 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -4,6 +4,10 @@ "version": "0.0.0-private", "private": true, "exports": { + "./marketplace": { + "types": "./marketplace.ts", + "import": "./marketplace.ts" + }, "./api/*": { "types": "./generated/api/*.ts", "import": "./generated/api/*.ts" diff --git a/web/app/components/goto-anything/actions/__tests__/plugin.spec.ts b/web/app/components/goto-anything/actions/__tests__/plugin.spec.ts index dd40b1dc981..23ce798ba60 100644 --- a/web/app/components/goto-anything/actions/__tests__/plugin.spec.ts +++ b/web/app/components/goto-anything/actions/__tests__/plugin.spec.ts @@ -17,7 +17,7 @@ vi.mock('../../../plugins/card/base/card-icon', () => ({ })) vi.mock('../../../plugins/marketplace/utils', () => ({ - getPluginIconInMarketplace: vi.fn(() => 'icon-url'), + getFormattedPlugin: vi.fn(plugin => ({ ...plugin, icon: 'icon-url' })), })) describe('pluginAction', () => { diff --git a/web/app/components/goto-anything/actions/plugin.tsx b/web/app/components/goto-anything/actions/plugin.tsx index 07197b8198d..078666020a4 100644 --- a/web/app/components/goto-anything/actions/plugin.tsx +++ b/web/app/components/goto-anything/actions/plugin.tsx @@ -1,9 +1,10 @@ -import type { Plugin, PluginsFromMarketplaceResponse } from '../../plugins/types' +import type { PluginsFromMarketplaceResponse } from '@dify/contracts/marketplace' +import type { Plugin } from '../../plugins/types' import type { ActionItem, PluginSearchResult } from './types' import { renderI18nObject } from '@/i18n-config' import { postMarketplace } from '@/service/base' import Icon from '../../plugins/card/base/card-icon' -import { getPluginIconInMarketplace } from '../../plugins/marketplace/utils' +import { getFormattedPlugin } from '../../plugins/marketplace/utils' const parser = (plugins: Plugin[], locale: string): PluginSearchResult[] => { return plugins.map((plugin) => { @@ -39,10 +40,7 @@ export const pluginAction: ActionItem = { return [] } - const list = response.data.plugins.map(plugin => ({ - ...plugin, - icon: getPluginIconInMarketplace(plugin), - })) + const list = response.data.plugins.map(plugin => getFormattedPlugin(plugin)) return parser(list, locale!) } catch (error) { diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/hooks/use-install-multi-state.ts b/web/app/components/plugins/install-plugin/install-bundle/steps/hooks/use-install-multi-state.ts index 4d8751fd4a9..99df622d503 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/hooks/use-install-multi-state.ts +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/hooks/use-install-multi-state.ts @@ -5,6 +5,7 @@ import { useSuspenseQuery } from '@tanstack/react-query' import { useCallback, useEffect, useMemo, useState } from 'react' import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed' import { pluginInstallLimit } from '@/app/components/plugins/install-plugin/hooks/use-install-plugin-limit' +import { getFormattedPlugin } from '@/app/components/plugins/marketplace/utils' import { systemFeaturesQueryOptions } from '@/features/system-features/client' import { useFetchPluginsInMarketPlaceByInfo } from '@/service/use-plugins' @@ -154,11 +155,11 @@ export function useInstallMultiState({ const pluginInfo = (pluginId ? pluginById.get(pluginId) : undefined) || payloads[requestIndex]?.plugin if (pluginInfo) { - pluginMap.set(request.dslIndex, { + pluginMap.set(request.dslIndex, getFormattedPlugin({ ...pluginInfo, from: request.dependency.type, version: pluginInfo.version || pluginInfo.latest_version, - }) + })) } else { errorSet.add(request.dslIndex) } }) diff --git a/web/app/components/plugins/marketplace/atoms.ts b/web/app/components/plugins/marketplace/atoms.ts index 6dc3d24fcfb..7ae113f957d 100644 --- a/web/app/components/plugins/marketplace/atoms.ts +++ b/web/app/components/plugins/marketplace/atoms.ts @@ -1,4 +1,4 @@ -import type { PluginsSort, SearchParamsFromCollection } from './types' +import type { PluginsSort, SearchParamsFromCollection } from '@dify/contracts/marketplace' import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai' import { useQueryState } from 'nuqs' import { useCallback } from 'react' diff --git a/web/app/components/plugins/marketplace/hooks.ts b/web/app/components/plugins/marketplace/hooks.ts index 60ba0e0beed..a817a8d84a7 100644 --- a/web/app/components/plugins/marketplace/hooks.ts +++ b/web/app/components/plugins/marketplace/hooks.ts @@ -1,12 +1,12 @@ -import type { - Plugin, -} from '../types' import type { CollectionsAndPluginsSearchParams, MarketplaceCollection, + PluginsFromMarketplaceResponse, PluginsSearchParams, -} from './types' -import type { PluginsFromMarketplaceResponse } from '@/app/components/plugins/types' +} from '@dify/contracts/marketplace' +import type { + Plugin, +} from '../types' import { useInfiniteQuery, useQuery, diff --git a/web/app/components/plugins/marketplace/list/__tests__/index.spec.tsx b/web/app/components/plugins/marketplace/list/__tests__/index.spec.tsx index af2b6e384ac..dfbacb77954 100644 --- a/web/app/components/plugins/marketplace/list/__tests__/index.spec.tsx +++ b/web/app/components/plugins/marketplace/list/__tests__/index.spec.tsx @@ -1,4 +1,4 @@ -import type { MarketplaceCollection, SearchParamsFromCollection } from '../../types' +import type { MarketplaceCollection, SearchParamsFromCollection } from '@dify/contracts/marketplace' import type { Plugin } from '@/app/components/plugins/types' import { fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' diff --git a/web/app/components/plugins/marketplace/list/__tests__/list-with-collection.spec.tsx b/web/app/components/plugins/marketplace/list/__tests__/list-with-collection.spec.tsx index c30c3fde725..587c0597df4 100644 --- a/web/app/components/plugins/marketplace/list/__tests__/list-with-collection.spec.tsx +++ b/web/app/components/plugins/marketplace/list/__tests__/list-with-collection.spec.tsx @@ -1,4 +1,4 @@ -import type { MarketplaceCollection } from '../../types' +import type { MarketplaceCollection } from '@dify/contracts/marketplace' import type { Plugin } from '@/app/components/plugins/types' import { fireEvent, render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' diff --git a/web/app/components/plugins/marketplace/list/__tests__/list-wrapper.spec.tsx b/web/app/components/plugins/marketplace/list/__tests__/list-wrapper.spec.tsx index fecfea30076..c835c6a8404 100644 --- a/web/app/components/plugins/marketplace/list/__tests__/list-wrapper.spec.tsx +++ b/web/app/components/plugins/marketplace/list/__tests__/list-wrapper.spec.tsx @@ -1,4 +1,4 @@ -import type { MarketplaceCollection } from '../../types' +import type { MarketplaceCollection } from '@dify/contracts/marketplace' import type { Plugin } from '@/app/components/plugins/types' import { render, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index 3c02e708b32..17bcfcb653b 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -1,6 +1,6 @@ 'use client' +import type { MarketplaceCollection, SearchParamsFromCollection } from '@dify/contracts/marketplace' import type { Plugin } from '../../types' -import type { MarketplaceCollection, SearchParamsFromCollection } from '../types' import { cn } from '@langgenius/dify-ui/cn' import { PluginInstallPermissionProviderGuard } from '@/app/components/plugins/install-plugin/components/plugin-install-permission-provider' import Empty from '../empty' diff --git a/web/app/components/plugins/marketplace/list/list-with-collection.tsx b/web/app/components/plugins/marketplace/list/list-with-collection.tsx index 00cddd1a96f..07858d75fd7 100644 --- a/web/app/components/plugins/marketplace/list/list-with-collection.tsx +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -1,6 +1,6 @@ 'use client' -import type { MarketplaceCollection, SearchParamsFromCollection } from '../types' +import type { MarketplaceCollection, SearchParamsFromCollection } from '@dify/contracts/marketplace' import type { Plugin } from '@/app/components/plugins/types' import { cn } from '@langgenius/dify-ui/cn' import { useEffect, useMemo, useState } from 'react' diff --git a/web/app/components/plugins/marketplace/query.ts b/web/app/components/plugins/marketplace/query.ts index f6fda05e2d0..ce8353bfe5c 100644 --- a/web/app/components/plugins/marketplace/query.ts +++ b/web/app/components/plugins/marketplace/query.ts @@ -1,5 +1,4 @@ -import type { PluginsSearchParams } from './types' -import type { MarketPlaceInputs } from '@/contract/marketplace' +import type { MarketPlaceInputs, PluginsSearchParams } from '@dify/contracts/marketplace' import { useInfiniteQuery, useQuery } from '@tanstack/react-query' import { marketplaceQuery } from '@/service/client' import { getMarketplaceCollectionsAndPlugins, getMarketplacePlugins } from './utils' diff --git a/web/app/components/plugins/marketplace/state.ts b/web/app/components/plugins/marketplace/state.ts index 4954acd60c9..62f417c8e47 100644 --- a/web/app/components/plugins/marketplace/state.ts +++ b/web/app/components/plugins/marketplace/state.ts @@ -1,4 +1,4 @@ -import type { PluginsSearchParams } from './types' +import type { PluginsSearchParams } from '@dify/contracts/marketplace' import { useDebounce } from 'ahooks' import { useCallback, useMemo } from 'react' import { useActivePluginType, useFilterPluginTags, useMarketplaceSearchMode, useMarketplaceSortValue, useSearchPluginText } from './atoms' diff --git a/web/app/components/plugins/marketplace/types.ts b/web/app/components/plugins/marketplace/types.ts deleted file mode 100644 index b17ab5d9753..00000000000 --- a/web/app/components/plugins/marketplace/types.ts +++ /dev/null @@ -1,40 +0,0 @@ -export type SearchParamsFromCollection = { - query?: string - sort_by?: string - sort_order?: string -} - -export type MarketplaceCollection = { - name: string - label: Record - description: Record - rule: string - created_at: string - updated_at: string - searchable?: boolean - search_params?: SearchParamsFromCollection -} - -export type PluginsSearchParams = { - query: string - page?: number - page_size?: number - sort_by?: string - sort_order?: string - category?: string - tags?: string[] - exclude?: string[] - type?: 'plugin' | 'bundle' -} - -export type PluginsSort = { - sortBy: string - sortOrder: string -} - -export type CollectionsAndPluginsSearchParams = { - category?: string - condition?: string - exclude?: string[] - type?: 'plugin' | 'bundle' -} diff --git a/web/app/components/plugins/marketplace/utils.ts b/web/app/components/plugins/marketplace/utils.ts index 4c4603440dd..244e37b3676 100644 --- a/web/app/components/plugins/marketplace/utils.ts +++ b/web/app/components/plugins/marketplace/utils.ts @@ -1,9 +1,10 @@ -import type { ActivePluginType } from './constants' import type { CollectionsAndPluginsSearchParams, MarketplaceCollection, + MarketplacePlugin, PluginsSearchParams, -} from '@/app/components/plugins/marketplace/types' +} from '@dify/contracts/marketplace' +import type { ActivePluginType } from './constants' import type { Plugin } from '@/app/components/plugins/types' import { PluginCategoryEnum } from '@/app/components/plugins/types' import { @@ -26,29 +27,32 @@ export function buildCarouselPages(items: T[], itemsPerPage: number): T[][] { return pages } -export const getPluginIconInMarketplace = (plugin: Plugin) => { +type MarketplacePluginPayload = MarketplacePlugin | (Plugin & { labels?: Plugin['label'] }) + +export const getPluginIconInMarketplace = (plugin: Pick) => { if (plugin.type === 'bundle') return `${MARKETPLACE_API_PREFIX}/bundles/${plugin.org}/${plugin.name}/icon` return `${MARKETPLACE_API_PREFIX}/plugins/${plugin.org}/${plugin.name}/icon` } -export const getFormattedPlugin = (bundle: Plugin): Plugin => { - if (bundle.type === 'bundle') { +export const getFormattedPlugin = (payload: MarketplacePluginPayload): Plugin => { + const plugin = payload as unknown as Plugin + + if (payload.type === 'bundle') { return { - ...bundle, - icon: getPluginIconInMarketplace(bundle), - brief: bundle.description, - // @ts-expect-error I do not have enough information - label: bundle.labels, + ...plugin, + icon: getPluginIconInMarketplace(payload), + brief: payload.description as Plugin['brief'], + label: (payload.labels ?? payload.label) as Plugin['label'], } } return { - ...bundle, - icon: getPluginIconInMarketplace(bundle), + ...plugin, + icon: getPluginIconInMarketplace(payload), } } -export const getPluginLinkInMarketplace = (plugin: Plugin, params?: Record) => { +export const getPluginLinkInMarketplace = (plugin: Pick, params?: Record) => { if (plugin.type === 'bundle') return getMarketplaceUrl(`/bundles/${plugin.org}/${plugin.name}`, params) return getMarketplaceUrl(`/plugins/${plugin.org}/${plugin.name}`, params) diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/components/__tests__/error-plugin-item.spec.tsx b/web/app/components/plugins/plugin-page/plugin-tasks/components/__tests__/error-plugin-item.spec.tsx index 9d705185535..762a0de9cfa 100644 --- a/web/app/components/plugins/plugin-page/plugin-tasks/components/__tests__/error-plugin-item.spec.tsx +++ b/web/app/components/plugins/plugin-page/plugin-tasks/components/__tests__/error-plugin-item.spec.tsx @@ -1,4 +1,5 @@ -import type { PluginInfoFromMarketPlace, PluginStatus } from '@/app/components/plugins/types' +import type { PluginInfoFromMarketPlace } from '@dify/contracts/marketplace' +import type { PluginStatus } from '@/app/components/plugins/types' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { PluginCategoryEnum, PluginSource, TaskStatus } from '@/app/components/plugins/types' import { fetchPluginInfoFromMarketPlace } from '@/service/plugins' diff --git a/web/app/components/plugins/plugin-page/plugin-tasks/components/error-plugin-item.tsx b/web/app/components/plugins/plugin-page/plugin-tasks/components/error-plugin-item.tsx index ae332604963..12cf5305cd0 100644 --- a/web/app/components/plugins/plugin-page/plugin-tasks/components/error-plugin-item.tsx +++ b/web/app/components/plugins/plugin-page/plugin-tasks/components/error-plugin-item.tsx @@ -38,7 +38,7 @@ const ErrorPluginItem: FC = ({ plugin, getIconUrl, languag const manifest: Plugin = { plugin_id: plugin.plugin_id, type: info.category as Plugin['type'], - category: info.category, + category: info.category as Plugin['category'], name: name!, org: org!, version: info.latest_version, diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 0e744ea3f46..2e1ad4f89c5 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -224,12 +224,6 @@ export type PluginDetail = { alternative_plugin_id: string } -export type PluginInfoFromMarketPlace = { - category: PluginCategoryEnum - latest_package_identifier: string - latest_version: string -} - export type Plugin = { type: 'plugin' | 'bundle' | 'model' | 'extension' | 'tool' | 'agent_strategy' | 'datasource' | 'trigger' org: string @@ -454,22 +448,6 @@ export type UninstallPluginResponse = { success: boolean } -export type PluginsFromMarketplaceResponse = { - plugins: Plugin[] - bundles?: Plugin[] - total: number -} -export type PluginsFromMarketplaceByInfoResponse = { - list: { - plugin: Plugin - version: { - plugin_name: string - plugin_org: string - unique_identifier: string - } - }[] -} - export type GitHubItemAndMarketPlaceDependency = { type: 'github' | 'marketplace' | 'package' value: { diff --git a/web/app/components/tools/marketplace/__tests__/index.spec.tsx b/web/app/components/tools/marketplace/__tests__/index.spec.tsx index dea3e52dc3d..207cf72e974 100644 --- a/web/app/components/tools/marketplace/__tests__/index.spec.tsx +++ b/web/app/components/tools/marketplace/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ +import type { SearchParamsFromCollection } from '@dify/contracts/marketplace' import type { useMarketplace } from '../hooks' -import type { SearchParamsFromCollection } from '@/app/components/plugins/marketplace/types' import type { Plugin } from '@/app/components/plugins/types' import type { Collection } from '@/app/components/tools/types' import { render, screen } from '@testing-library/react' diff --git a/web/app/components/tools/marketplace/index.tsx b/web/app/components/tools/marketplace/index.tsx index f06b2cdceb1..030f83eda1b 100644 --- a/web/app/components/tools/marketplace/index.tsx +++ b/web/app/components/tools/marketplace/index.tsx @@ -1,6 +1,6 @@ +import type { SearchParamsFromCollection } from '@dify/contracts/marketplace' import type { ToolsContentInset } from '../content-inset' import type { useMarketplace } from './hooks' -import type { SearchParamsFromCollection } from '@/app/components/plugins/marketplace/types' import { cn } from '@langgenius/dify-ui/cn' import { RiArrowRightUpLine, diff --git a/web/contract/base.ts b/web/contract/base.ts deleted file mode 100644 index 764db9d5543..00000000000 --- a/web/contract/base.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { oc } from '@orpc/contract' - -export const base = oc.$route({ inputStructure: 'detailed' }) diff --git a/web/contract/marketplace.ts b/web/contract/marketplace.ts deleted file mode 100644 index f3bd953ef3f..00000000000 --- a/web/contract/marketplace.ts +++ /dev/null @@ -1,94 +0,0 @@ -import type { InferContractRouterInputs } from '@orpc/contract' -import type { CollectionsAndPluginsSearchParams, MarketplaceCollection, PluginsSearchParams } from '@/app/components/plugins/marketplace/types' -import type { Plugin, PluginsFromMarketplaceResponse } from '@/app/components/plugins/types' -import type { MarketplaceTemplate } from '@/types/marketplace-template' -import { type } from '@orpc/contract' -import { base } from './base' - -const collectionsContract = base - .route({ - path: '/collections', - method: 'GET', - }) - .input( - type<{ - query?: CollectionsAndPluginsSearchParams & { page?: number, page_size?: number } - }>(), - ) - .output( - type<{ - data?: { - collections?: MarketplaceCollection[] - } - }>(), - ) - -const collectionPluginsContract = base - .route({ - path: '/collections/{collectionId}/plugins', - method: 'POST', - }) - .input( - type<{ - params: { - collectionId: string - } - body?: CollectionsAndPluginsSearchParams - }>(), - ) - .output( - type<{ - data?: { - plugins?: Plugin[] - } - }>(), - ) - -const searchAdvancedContract = base - .route({ - path: '/{kind}/search/advanced', - method: 'POST', - }) - .input(type<{ - params: { - kind: 'plugins' | 'bundles' - } - body: Omit - }>()) - .output(type<{ data: PluginsFromMarketplaceResponse }>()) - -const templateDetailContract = base - .route({ - path: '/templates/{templateId}', - method: 'GET', - }) - .input(type<{ - params: { - templateId: string - } - }>()) - .output(type<{ data: MarketplaceTemplate }>()) - -const downloadPluginContract = base - .route({ - path: '/plugins/{organization}/{pluginName}/{version}/download', - method: 'GET', - }) - .input(type<{ - params: { - organization: string - pluginName: string - version: string - } - }>()) - .output(type()) - -export const marketplaceRouterContract = { - collections: collectionsContract, - collectionPlugins: collectionPluginsContract, - searchAdvanced: searchAdvancedContract, - templateDetail: templateDetailContract, - downloadPlugin: downloadPluginContract, -} - -export type MarketPlaceInputs = InferContractRouterInputs diff --git a/web/service/client.ts b/web/service/client.ts index 8c52b23e336..e1a55439433 100644 --- a/web/service/client.ts +++ b/web/service/client.ts @@ -12,6 +12,7 @@ import type { AnyContractRouter, ContractRouterClient } from '@orpc/contract' import type { JsonifiedClient } from '@orpc/openapi-client' import type { RouterUtils, TanstackQueryOperationContext } from '@orpc/tanstack-query' import type { InfiniteData, QueryClient, QueryKey } from '@tanstack/react-query' +import { marketplaceRouterContract } from '@dify/contracts/marketplace' import { createORPCClient, onError } from '@orpc/client' import { OpenAPILink } from '@orpc/openapi-client/fetch' import { createTanstackQueryUtils } from '@orpc/tanstack-query' @@ -21,7 +22,6 @@ import { IS_MARKETPLACE, MARKETPLACE_API_PREFIX, } from '@/config' -import { marketplaceRouterContract } from '@/contract/marketplace' import { isClient } from '@/utils/client' // eslint-disable-next-line no-restricted-imports import { request } from './base' diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 9062d3b5ecf..425937f9dcd 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -1,7 +1,7 @@ +import type { PluginInfoFromMarketPlace } from '@dify/contracts/marketplace' import type { Dependency, InstallPackageResponse, - PluginInfoFromMarketPlace, PluginManifestInMarket, TaskStatusResponse, UninstallPluginResponse, diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index b13fd0f4241..521f4093cec 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -1,4 +1,9 @@ import type { PluginInstallationItemResponse } from '@dify/contracts/api/console/workspaces/types.gen' +import type { + PluginInfoFromMarketPlace, + PluginsFromMarketplaceByInfoResponse, + PluginsFromMarketplaceResponse, +} from '@dify/contracts/marketplace' import type { MutateOptions, QueryClient, QueryOptions } from '@tanstack/react-query' import type { FormOption, @@ -21,9 +26,6 @@ import type { Plugin, PluginDeclaration, PluginDetail, - PluginInfoFromMarketPlace, - PluginsFromMarketplaceByInfoResponse, - PluginsFromMarketplaceResponse, PluginTask, PluginTaskStart, ReferenceSetting, diff --git a/web/types/marketplace-template.ts b/web/types/marketplace-template.ts deleted file mode 100644 index ac2b7cb2aac..00000000000 --- a/web/types/marketplace-template.ts +++ /dev/null @@ -1,11 +0,0 @@ -export type MarketplaceTemplate = { - id: string - template_name: string - overview: string - icon: string - icon_background: string - icon_file_key: string - publisher_unique_handle: string - usage_count: number - categories: string[] -}