mirror of
https://github.com/langgenius/dify.git
synced 2026-01-27 22:22:18 +08:00
227 lines
6.4 KiB
TypeScript
227 lines
6.4 KiB
TypeScript
import type { ActivePluginType } from './constants'
|
|
import type {
|
|
CollectionsAndPluginsSearchParams,
|
|
MarketplaceCollection,
|
|
PluginsSearchParams,
|
|
} from '@/app/components/plugins/marketplace/types'
|
|
import type { Plugin, PluginsFromMarketplaceResponse } from '@/app/components/plugins/types'
|
|
import { PluginCategoryEnum } from '@/app/components/plugins/types'
|
|
import {
|
|
APP_VERSION,
|
|
IS_MARKETPLACE,
|
|
MARKETPLACE_API_PREFIX,
|
|
} from '@/config'
|
|
import { postMarketplace } from '@/service/base'
|
|
import { getMarketplaceUrl } from '@/utils/var'
|
|
import { PLUGIN_TYPE_SEARCH_MAP } from './constants'
|
|
|
|
type MarketplaceFetchOptions = {
|
|
signal?: AbortSignal
|
|
}
|
|
|
|
const getMarketplaceHeaders = () => new Headers({
|
|
'X-Dify-Version': !IS_MARKETPLACE ? APP_VERSION : '999.0.0',
|
|
})
|
|
|
|
export const getPluginIconInMarketplace = (plugin: Plugin) => {
|
|
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') {
|
|
return {
|
|
...bundle,
|
|
icon: getPluginIconInMarketplace(bundle),
|
|
brief: bundle.description,
|
|
// @ts-expect-error I do not have enough information
|
|
label: bundle.labels,
|
|
}
|
|
}
|
|
return {
|
|
...bundle,
|
|
icon: getPluginIconInMarketplace(bundle),
|
|
}
|
|
}
|
|
|
|
export const getPluginLinkInMarketplace = (plugin: Plugin, params?: Record<string, string | undefined>) => {
|
|
if (plugin.type === 'bundle')
|
|
return getMarketplaceUrl(`/bundles/${plugin.org}/${plugin.name}`, params)
|
|
return getMarketplaceUrl(`/plugins/${plugin.org}/${plugin.name}`, params)
|
|
}
|
|
|
|
export const getPluginDetailLinkInMarketplace = (plugin: Plugin) => {
|
|
if (plugin.type === 'bundle')
|
|
return `/bundles/${plugin.org}/${plugin.name}`
|
|
return `/plugins/${plugin.org}/${plugin.name}`
|
|
}
|
|
|
|
export const getMarketplacePluginsByCollectionId = async (
|
|
collectionId: string,
|
|
query?: CollectionsAndPluginsSearchParams,
|
|
options?: MarketplaceFetchOptions,
|
|
) => {
|
|
let plugins: Plugin[] = []
|
|
|
|
try {
|
|
const url = `${MARKETPLACE_API_PREFIX}/collections/${collectionId}/plugins`
|
|
const headers = getMarketplaceHeaders()
|
|
const marketplaceCollectionPluginsData = await globalThis.fetch(
|
|
url,
|
|
{
|
|
cache: 'no-store',
|
|
method: 'POST',
|
|
headers,
|
|
signal: options?.signal,
|
|
body: JSON.stringify({
|
|
category: query?.category,
|
|
exclude: query?.exclude,
|
|
type: query?.type,
|
|
}),
|
|
},
|
|
)
|
|
const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json()
|
|
plugins = (marketplaceCollectionPluginsDataJson.data.plugins || []).map((plugin: Plugin) => getFormattedPlugin(plugin))
|
|
}
|
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
catch (e) {
|
|
plugins = []
|
|
}
|
|
|
|
return plugins
|
|
}
|
|
|
|
export const getMarketplaceCollectionsAndPlugins = async (
|
|
query?: CollectionsAndPluginsSearchParams,
|
|
options?: MarketplaceFetchOptions,
|
|
) => {
|
|
let marketplaceCollections: MarketplaceCollection[] = []
|
|
let marketplaceCollectionPluginsMap: Record<string, Plugin[]> = {}
|
|
try {
|
|
let marketplaceUrl = `${MARKETPLACE_API_PREFIX}/collections?page=1&page_size=100`
|
|
if (query?.condition)
|
|
marketplaceUrl += `&condition=${query.condition}`
|
|
if (query?.type)
|
|
marketplaceUrl += `&type=${query.type}`
|
|
const headers = getMarketplaceHeaders()
|
|
const marketplaceCollectionsData = await globalThis.fetch(
|
|
marketplaceUrl,
|
|
{
|
|
headers,
|
|
cache: 'no-store',
|
|
signal: options?.signal,
|
|
},
|
|
)
|
|
const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json()
|
|
marketplaceCollections = marketplaceCollectionsDataJson.data.collections || []
|
|
await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => {
|
|
const plugins = await getMarketplacePluginsByCollectionId(collection.name, query, options)
|
|
|
|
marketplaceCollectionPluginsMap[collection.name] = plugins
|
|
}))
|
|
}
|
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
catch (e) {
|
|
marketplaceCollections = []
|
|
marketplaceCollectionPluginsMap = {}
|
|
}
|
|
|
|
return {
|
|
marketplaceCollections,
|
|
marketplaceCollectionPluginsMap,
|
|
}
|
|
}
|
|
|
|
export const getMarketplacePlugins = async (
|
|
queryParams: PluginsSearchParams | undefined,
|
|
pageParam: number,
|
|
signal?: AbortSignal,
|
|
) => {
|
|
if (!queryParams) {
|
|
return {
|
|
plugins: [] as Plugin[],
|
|
total: 0,
|
|
page: 1,
|
|
pageSize: 40,
|
|
}
|
|
}
|
|
|
|
const {
|
|
query,
|
|
sortBy,
|
|
sortOrder,
|
|
category,
|
|
tags,
|
|
type,
|
|
pageSize = 40,
|
|
} = queryParams
|
|
const pluginOrBundle = type === 'bundle' ? 'bundles' : 'plugins'
|
|
|
|
try {
|
|
const res = await postMarketplace<{ data: PluginsFromMarketplaceResponse }>(`/${pluginOrBundle}/search/advanced`, {
|
|
body: {
|
|
page: pageParam,
|
|
page_size: pageSize,
|
|
query,
|
|
sort_by: sortBy,
|
|
sort_order: sortOrder,
|
|
category: category !== 'all' ? category : '',
|
|
tags,
|
|
type,
|
|
},
|
|
signal,
|
|
})
|
|
const resPlugins = res.data.bundles || res.data.plugins || []
|
|
|
|
return {
|
|
plugins: resPlugins.map(plugin => getFormattedPlugin(plugin)),
|
|
total: res.data.total,
|
|
page: pageParam,
|
|
pageSize,
|
|
}
|
|
}
|
|
catch {
|
|
return {
|
|
plugins: [],
|
|
total: 0,
|
|
page: pageParam,
|
|
pageSize,
|
|
}
|
|
}
|
|
}
|
|
|
|
export const getMarketplaceListCondition = (pluginType: string) => {
|
|
if ([PluginCategoryEnum.tool, PluginCategoryEnum.agent, PluginCategoryEnum.model, PluginCategoryEnum.datasource, PluginCategoryEnum.trigger].includes(pluginType as PluginCategoryEnum))
|
|
return `category=${pluginType}`
|
|
|
|
if (pluginType === PluginCategoryEnum.extension)
|
|
return 'category=endpoint'
|
|
|
|
if (pluginType === 'bundle')
|
|
return 'type=bundle'
|
|
|
|
return ''
|
|
}
|
|
|
|
export const getMarketplaceListFilterType = (category: ActivePluginType) => {
|
|
if (category === PLUGIN_TYPE_SEARCH_MAP.all)
|
|
return undefined
|
|
|
|
if (category === PLUGIN_TYPE_SEARCH_MAP.bundle)
|
|
return 'bundle'
|
|
|
|
return 'plugin'
|
|
}
|
|
|
|
export function getCollectionsParams(category: ActivePluginType): CollectionsAndPluginsSearchParams {
|
|
if (category === PLUGIN_TYPE_SEARCH_MAP.all) {
|
|
return {}
|
|
}
|
|
return {
|
|
category,
|
|
condition: getMarketplaceListCondition(category),
|
|
type: getMarketplaceListFilterType(category),
|
|
}
|
|
}
|