feat(trigger): plugin category type

This commit is contained in:
yessenia 2025-10-16 15:03:14 +08:00
parent 671aba6ab7
commit b04f92715c
18 changed files with 104 additions and 136 deletions

View File

@ -8,7 +8,7 @@ import {
useMarketplacePlugins,
} from '@/app/components/plugins/marketplace/hooks'
import type { Plugin } from '@/app/components/plugins/types'
import { PluginType } from '@/app/components/plugins/types'
import { PluginCategoryEnum } from '@/app/components/plugins/types'
import { getMarketplacePluginsByCollectionId } from '@/app/components/plugins/marketplace/utils'
export const useMarketplaceAllPlugins = (providers: any[], searchText: string) => {
@ -38,7 +38,7 @@ export const useMarketplaceAllPlugins = (providers: any[], searchText: string) =
if (searchText) {
queryPluginsWithDebounced({
query: searchText,
category: PluginType.datasource,
category: PluginCategoryEnum.datasource,
exclude,
type: 'plugin',
sortBy: 'install_count',
@ -48,7 +48,7 @@ export const useMarketplaceAllPlugins = (providers: any[], searchText: string) =
else {
queryPlugins({
query: '',
category: PluginType.datasource,
category: PluginCategoryEnum.datasource,
type: 'plugin',
pageSize: 1000,
exclude,

View File

@ -35,7 +35,7 @@ import {
useMarketplacePlugins,
} from '@/app/components/plugins/marketplace/hooks'
import type { Plugin } from '@/app/components/plugins/types'
import { PluginType } from '@/app/components/plugins/types'
import { PluginCategoryEnum } from '@/app/components/plugins/types'
import { getMarketplacePluginsByCollectionId } from '@/app/components/plugins/marketplace/utils'
import { useModalContextSelector } from '@/context/modal-context'
import { useEventEmitterContextContext } from '@/context/event-emitter'
@ -278,7 +278,7 @@ export const useMarketplaceAllPlugins = (providers: ModelProvider[], searchText:
if (searchText) {
queryPluginsWithDebounced({
query: searchText,
category: PluginType.model,
category: PluginCategoryEnum.model,
exclude,
type: 'plugin',
sortBy: 'install_count',
@ -288,7 +288,7 @@ export const useMarketplaceAllPlugins = (providers: ModelProvider[], searchText:
else {
queryPlugins({
query: '',
category: PluginType.model,
category: PluginCategoryEnum.model,
type: 'plugin',
pageSize: 1000,
exclude,

View File

@ -1,21 +1,21 @@
'use client'
import React from 'react'
import type { Plugin } from '../types'
import Icon from '../card/base/card-icon'
import CornerMark from './base/corner-mark'
import Title from './base/title'
import OrgInfo from './base/org-info'
import Description from './base/description'
import Placeholder from './base/placeholder'
import cn from '@/utils/classnames'
import { useGetLanguage } from '@/context/i18n'
import { getLanguage } from '@/i18n-config/language'
import { useSingleCategories } from '../hooks'
import { renderI18nObject } from '@/i18n-config'
import { useMixedTranslation } from '@/app/components/plugins/marketplace/hooks'
import { useGetLanguage } from '@/context/i18n'
import { renderI18nObject } from '@/i18n-config'
import { getLanguage } from '@/i18n-config/language'
import cn from '@/utils/classnames'
import { RiAlertFill } from '@remixicon/react'
import React from 'react'
import Partner from '../base/badges/partner'
import Verified from '../base/badges/verified'
import { RiAlertFill } from '@remixicon/react'
import Icon from '../card/base/card-icon'
import { useCategories } from '../hooks'
import type { Plugin } from '../types'
import CornerMark from './base/corner-mark'
import Description from './base/description'
import OrgInfo from './base/org-info'
import Placeholder from './base/placeholder'
import Title from './base/title'
export type Props = {
className?: string
@ -49,10 +49,8 @@ const Card = ({
const defaultLocale = useGetLanguage()
const locale = localeFromProps ? getLanguage(localeFromProps) : defaultLocale
const { t } = useMixedTranslation(localeFromProps)
const { categoriesMap } = useSingleCategories(t)
const { categoriesMap } = useCategories(t, true)
const { category, type, name, org, label, brief, icon, verified, badges = [] } = payload
const isBundle = !['plugin', 'model', 'tool', 'datasource', 'extension', 'agent-strategy'].includes(type)
const cornerMark = isBundle ? categoriesMap.bundle?.label : categoriesMap[category]?.label
const getLocalizedText = (obj: Record<string, string> | undefined) =>
obj ? renderI18nObject(obj, locale) : ''
const isPartner = badges.includes('partner')
@ -70,7 +68,7 @@ const Card = ({
return (
<div className={wrapClassName}>
<div className={cn('p-4 pb-3', limitedInstall && 'pb-1')}>
{!hideCornerMark && <CornerMark text={cornerMark} />}
{!hideCornerMark && <CornerMark text={categoriesMap[type === 'bundle' ? type : category]?.label} />}
{/* Header */}
<div className="flex">
<Icon src={icon} installed={installed} installFailed={installFailed} />

View File

@ -1,3 +1,5 @@
import { PluginCategoryEnum } from './types'
export const tagKeys = [
'agent',
'rag',
@ -20,11 +22,11 @@ export const tagKeys = [
]
export const categoryKeys = [
'model',
'tool',
'datasource',
'agent-strategy',
'extension',
PluginCategoryEnum.model,
PluginCategoryEnum.tool,
PluginCategoryEnum.datasource,
PluginCategoryEnum.agent,
PluginCategoryEnum.extension,
'bundle',
'trigger',
PluginCategoryEnum.trigger,
]

View File

@ -1,10 +1,11 @@
import type { TFunction } from 'i18next'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import type { TFunction } from 'i18next'
import {
categoryKeys,
tagKeys,
} from './constants'
import { PluginCategoryEnum } from './types'
export type Tag = {
name: string
@ -51,56 +52,24 @@ type Category = {
label: string
}
export const useCategories = (translateFromOut?: TFunction) => {
export const useCategories = (translateFromOut?: TFunction, isSingle?: boolean) => {
const { t: translation } = useTranslation()
const t = translateFromOut || translation
const categories = useMemo(() => {
return categoryKeys.map((category) => {
if (category === 'agent-strategy') {
if (category === PluginCategoryEnum.agent) {
return {
name: 'agent-strategy',
label: t('plugin.category.agents'),
name: PluginCategoryEnum.agent,
label: isSingle ? t('plugin.categorySingle.agent') : t('plugin.category.agents'),
}
}
return {
name: category,
label: t(`plugin.category.${category}s`),
label: isSingle ? t(`plugin.categorySingle.${category}`) : t(`plugin.category.${category}s`),
}
})
}, [t])
const categoriesMap = useMemo(() => {
return categories.reduce((acc, category) => {
acc[category.name] = category
return acc
}, {} as Record<string, Category>)
}, [categories])
return {
categories,
categoriesMap,
}
}
export const useSingleCategories = (translateFromOut?: TFunction) => {
const { t: translation } = useTranslation()
const t = translateFromOut || translation
const categories = useMemo(() => {
return categoryKeys.map((category) => {
if (category === 'agent-strategy') {
return {
name: 'agent-strategy',
label: t('plugin.categorySingle.agent'),
}
}
return {
name: category,
label: t(`plugin.categorySingle.${category}`),
}
})
}, [t])
}, [t, isSingle])
const categoriesMap = useMemo(() => {
return categories.reduce((acc, category) => {

View File

@ -5,7 +5,7 @@ import { useInvalidateInstalledPluginList } from '@/service/use-plugins'
import { useInvalidateAllBuiltInTools, useInvalidateAllToolProviders } from '@/service/use-tools'
import { useInvalidateStrategyProviders } from '@/service/use-strategy'
import type { Plugin, PluginDeclaration, PluginManifestInMarket } from '../../types'
import { PluginType } from '../../types'
import { PluginCategoryEnum } from '../../types'
import { useInvalidDataSourceList } from '@/service/use-pipeline'
import { useInvalidDataSourceListAuth } from '@/service/use-datasource'
@ -29,19 +29,19 @@ const useRefreshPluginList = () => {
invalidateInstalledPluginList()
// tool page, tool select
if ((manifest && PluginType.tool.includes(manifest.category)) || refreshAllType) {
if ((manifest && PluginCategoryEnum.tool.includes(manifest.category)) || refreshAllType) {
invalidateAllToolProviders()
invalidateAllBuiltInTools()
// TODO: update suggested tools. It's a function in hook useMarketplacePlugins,handleUpdatePlugins
}
if ((manifest && PluginType.datasource.includes(manifest.category)) || refreshAllType) {
if ((manifest && PluginCategoryEnum.datasource.includes(manifest.category)) || refreshAllType) {
invalidateAllDataSources()
invalidateDataSourceListAuth()
}
// model select
if ((manifest && PluginType.model.includes(manifest.category)) || refreshAllType) {
if ((manifest && PluginCategoryEnum.model.includes(manifest.category)) || refreshAllType) {
refreshModelProviders()
refetchLLMModelList()
refetchEmbeddingModelList()
@ -49,7 +49,7 @@ const useRefreshPluginList = () => {
}
// agent select
if ((manifest && PluginType.agent.includes(manifest.category)) || refreshAllType)
if ((manifest && PluginCategoryEnum.agent.includes(manifest.category)) || refreshAllType)
invalidateStrategyProviders()
},
}

View File

@ -7,7 +7,7 @@ import {
RiPuzzle2Line,
RiSpeakAiLine,
} from '@remixicon/react'
import { PluginType } from '../types'
import { PluginCategoryEnum } from '../types'
import { useMarketplaceContext } from './context'
import {
useMixedTranslation,
@ -18,11 +18,11 @@ import { useCallback, useEffect } from 'react'
export const PLUGIN_TYPE_SEARCH_MAP = {
all: 'all',
model: PluginType.model,
tool: PluginType.tool,
agent: PluginType.agent,
extension: PluginType.extension,
datasource: PluginType.datasource,
model: PluginCategoryEnum.model,
tool: PluginCategoryEnum.tool,
agent: PluginCategoryEnum.agent,
extension: PluginCategoryEnum.extension,
datasource: PluginCategoryEnum.datasource,
bundle: 'bundle',
}
type PluginTypeSwitchProps = {

View File

@ -1,6 +1,6 @@
import { PLUGIN_TYPE_SEARCH_MAP } from './plugin-type-switch'
import type { Plugin } from '@/app/components/plugins/types'
import { PluginType } from '@/app/components/plugins/types'
import { PluginCategoryEnum } from '@/app/components/plugins/types'
import type {
CollectionsAndPluginsSearchParams,
MarketplaceCollection,
@ -113,19 +113,19 @@ export const getMarketplaceCollectionsAndPlugins = async (query?: CollectionsAnd
}
export const getMarketplaceListCondition = (pluginType: string) => {
if (pluginType === PluginType.tool)
if (pluginType === PluginCategoryEnum.tool)
return 'category=tool'
if (pluginType === PluginType.agent)
if (pluginType === PluginCategoryEnum.agent)
return 'category=agent-strategy'
if (pluginType === PluginType.model)
if (pluginType === PluginCategoryEnum.model)
return 'category=model'
if (pluginType === PluginType.extension)
if (pluginType === PluginCategoryEnum.extension)
return 'category=endpoint'
if (pluginType === PluginType.datasource)
if (pluginType === PluginCategoryEnum.datasource)
return 'category=datasource'
if (pluginType === 'bundle')

View File

@ -10,7 +10,7 @@ import {
RiVerifiedBadgeLine,
} from '@remixicon/react'
import type { PluginDetail } from '../types'
import { PluginSource, PluginType } from '../types'
import { PluginCategoryEnum, PluginSource } from '../types'
import Description from '../card/base/description'
import Icon from '../card/base/card-icon'
import Title from '../card/base/title'
@ -86,7 +86,7 @@ const DetailHeader = ({
alternative_plugin_id,
} = detail
const { author, category, name, label, description, icon, verified, tool } = detail.declaration
const isTool = category === PluginType.tool
const isTool = category === PluginCategoryEnum.tool
const providerBriefInfo = tool?.identity
const providerKey = `${plugin_id}/${providerBriefInfo?.name}`
const { data: collectionList = [] } = useAllToolProviders(isTool)
@ -202,9 +202,9 @@ const DetailHeader = ({
if (res.success) {
hideDeleteConfirm()
onUpdate(true)
if (PluginType.model.includes(category))
if (PluginCategoryEnum.model.includes(category))
refreshModelProviders()
if (PluginType.tool.includes(category))
if (PluginCategoryEnum.tool.includes(category))
invalidateAllToolProviders()
}
}, [showDeleting, installation_id, hideDeleting, hideDeleteConfirm, onUpdate, category, refreshModelProviders, invalidateAllToolProviders])
@ -326,7 +326,7 @@ const DetailHeader = ({
)}
<Description className='mb-2 mt-3 h-auto' text={description[locale]} descriptionLineRows={2}></Description>
{
category === PluginType.tool && (
category === PluginCategoryEnum.tool && (
<PluginAuth
pluginPayload={{
provider: provider?.name || '',

View File

@ -1,6 +1,6 @@
'use client'
import Drawer from '@/app/components/base/drawer'
import { type PluginDetail, PluginType } from '@/app/components/plugins/types'
import { PluginCategoryEnum, type PluginDetail } from '@/app/components/plugins/types'
import cn from '@/utils/classnames'
import type { FC } from 'react'
import { useEffect } from 'react'
@ -62,7 +62,7 @@ const PluginDetailPanel: FC<Props> = ({
onUpdate={handleUpdate}
/>
<div className='grow overflow-y-auto'>
{detail.declaration.category === PluginType.trigger && (
{detail.declaration.category === PluginCategoryEnum.trigger && (
<>
<SubscriptionList />
<TriggerEventsList />

View File

@ -14,7 +14,7 @@ import { useGitHubReleases } from '../install-plugin/hooks'
import Toast from '@/app/components/base/toast'
import { useModalContext } from '@/context/modal-context'
import { useInvalidateInstalledPluginList } from '@/service/use-plugins'
import type { PluginType } from '@/app/components/plugins/types'
import type { PluginCategoryEnum } from '@/app/components/plugins/types'
const i18nPrefix = 'plugin.action'
@ -23,7 +23,7 @@ type Props = {
installationId: string
pluginUniqueIdentifier: string
pluginName: string
category: PluginType
category: PluginCategoryEnum
usedInApps: number
isShowFetchNewVersion: boolean
isShowInfo: boolean

View File

@ -1,7 +1,12 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useMemo } from 'react'
import { useTheme } from 'next-themes'
import Tooltip from '@/app/components/base/tooltip'
import useRefreshPluginList from '@/app/components/plugins/install-plugin/hooks/use-refresh-plugin-list'
import { API_PREFIX } from '@/config'
import { useAppContext } from '@/context/app-context'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { useRenderI18nObject } from '@/hooks/use-i18n'
import cn from '@/utils/classnames'
import { getMarketplaceUrl } from '@/utils/var'
import {
RiArrowRightUpLine,
RiBugLine,
@ -10,26 +15,21 @@ import {
RiLoginCircleLine,
RiVerifiedBadgeLine,
} from '@remixicon/react'
import { useTheme } from 'next-themes'
import type { FC } from 'react'
import React, { useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { usePluginPageContext } from '../plugin-page/context'
import { Github } from '../../base/icons/src/public/common'
import { gte } from 'semver'
import Badge from '../../base/badge'
import { type PluginDetail, PluginSource, PluginType } from '../types'
import { Github } from '../../base/icons/src/public/common'
import CornerMark from '../card/base/corner-mark'
import Description from '../card/base/description'
import OrgInfo from '../card/base/org-info'
import Title from '../card/base/title'
import { useCategories } from '../hooks'
import { usePluginPageContext } from '../plugin-page/context'
import { PluginCategoryEnum, type PluginDetail, PluginSource } from '../types'
import Action from './action'
import cn from '@/utils/classnames'
import { API_PREFIX } from '@/config'
import { useSingleCategories } from '../hooks'
import { useRenderI18nObject } from '@/hooks/use-i18n'
import useRefreshPluginList from '@/app/components/plugins/install-plugin/hooks/use-refresh-plugin-list'
import { useAppContext } from '@/context/app-context'
import { gte } from 'semver'
import Tooltip from '@/app/components/base/tooltip'
import { getMarketplaceUrl } from '@/utils/var'
import { useGlobalPublicStore } from '@/context/global-public-context'
type Props = {
className?: string
@ -42,7 +42,7 @@ const PluginItem: FC<Props> = ({
}) => {
const { t } = useTranslation()
const { theme } = useTheme()
const { categoriesMap } = useSingleCategories()
const { categoriesMap } = useCategories(t, true)
const currentPluginID = usePluginPageContext(v => v.currentPluginID)
const setCurrentPluginID = usePluginPageContext(v => v.setCurrentPluginID)
const { refreshPluginList } = useRefreshPluginList()
@ -150,7 +150,7 @@ const PluginItem: FC<Props> = ({
packageName={name}
packageNameClassName='w-auto max-w-[150px]'
/>
{category === PluginType.extension && (
{category === PluginCategoryEnum.extension && (
<>
<div className='system-xs-regular mx-2 text-text-quaternary'>·</div>
<div className='system-xs-regular flex items-center gap-x-1 overflow-hidden text-text-tertiary'>

View File

@ -5,7 +5,7 @@ import type { AgentFeature } from '@/app/components/workflow/nodes/agent/types'
import type { AutoUpdateConfig } from './reference-setting-modal/auto-update-setting/types'
import type { FormTypeEnum } from '../base/form/types'
export enum PluginType {
export enum PluginCategoryEnum {
tool = 'tool',
model = 'model',
extension = 'extension',
@ -71,7 +71,7 @@ export type PluginDeclaration = {
author: string
icon: string
name: string
category: PluginType
category: PluginCategoryEnum
label: Record<Locale, string>
description: Record<Locale, string>
created_at: string
@ -190,7 +190,7 @@ export type PluginManifestInMarket = {
org: string
icon: string
label: Record<Locale, string>
category: PluginType
category: PluginCategoryEnum
version: string // combine the other place to it
latest_version: string
brief: Record<Locale, string>
@ -233,7 +233,7 @@ export type PluginDetail = {
}
export type PluginInfoFromMarketPlace = {
category: PluginType
category: PluginCategoryEnum
latest_package_identifier: string
latest_version: string
}
@ -255,7 +255,7 @@ export type Plugin = {
// Repo readme.md content
introduction: string
repository: string
category: PluginType
category: PluginCategoryEnum
install_count: number
endpoint: {
settings: CredentialFormSchemaBase[]
@ -285,7 +285,7 @@ export type ReferenceSetting = {
}
export type UpdateFromMarketPlacePayload = {
category: PluginType
category: PluginCategoryEnum
originalPackageInfo: {
id: string
payload: PluginDeclaration
@ -308,7 +308,7 @@ export type UpdateFromGitHubPayload = {
export type UpdatePluginPayload = {
type: PluginSource
category: PluginType
category: PluginCategoryEnum
marketPlace?: UpdateFromMarketPlacePayload
github?: UpdateFromGitHubPayload
}

View File

@ -9,7 +9,7 @@ import {
useMarketplaceCollectionsAndPlugins,
useMarketplacePlugins,
} from '@/app/components/plugins/marketplace/hooks'
import { PluginType } from '@/app/components/plugins/types'
import { PluginCategoryEnum } from '@/app/components/plugins/types'
import { getMarketplaceListCondition } from '@/app/components/plugins/marketplace/utils'
import { useAllToolProviders } from '@/service/use-tools'
@ -49,7 +49,7 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
if (searchPluginText) {
queryPluginsWithDebounced({
category: PluginType.tool,
category: PluginCategoryEnum.tool,
query: searchPluginText,
tags: filterPluginTags,
exclude,
@ -59,7 +59,7 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
return
}
queryPlugins({
category: PluginType.tool,
category: PluginCategoryEnum.tool,
query: searchPluginText,
tags: filterPluginTags,
exclude,
@ -70,8 +70,8 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
else {
if (isSuccess) {
queryMarketplaceCollectionsAndPlugins({
category: PluginType.tool,
condition: getMarketplaceListCondition(PluginType.tool),
category: PluginCategoryEnum.tool,
condition: getMarketplaceListCondition(PluginCategoryEnum.tool),
exclude,
type: 'plugin',
})
@ -95,7 +95,7 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
pageRef.current++
queryPlugins({
category: PluginType.tool,
category: PluginCategoryEnum.tool,
query: searchPluginText,
tags: filterPluginTags,
exclude,

View File

@ -22,7 +22,7 @@ import cn from '@/utils/classnames'
import { useGetLanguage } from '@/context/i18n'
import type { ListRef } from '@/app/components/workflow/block-selector/market-place-plugin/list'
import PluginList, { type ListProps } from '@/app/components/workflow/block-selector/market-place-plugin/list'
import { PluginType } from '../../plugins/types'
import { PluginCategoryEnum } from '../../plugins/types'
import { useMarketplacePlugins } from '../../plugins/marketplace/hooks'
import { useGlobalPublicStore } from '@/context/global-public-context'
import RAGToolSuggestions from './rag-tool-suggestions'
@ -107,7 +107,7 @@ const AllTools = ({
fetchPlugins({
query: searchText,
tags,
category: PluginType.tool,
category: PluginCategoryEnum.tool,
})
}
}, [searchText, tags, enable_marketplace])

View File

@ -17,7 +17,7 @@ import PluginList, { type ListRef } from '@/app/components/workflow/block-select
import { useGlobalPublicStore } from '@/context/global-public-context'
import { DEFAULT_FILE_EXTENSIONS_IN_LOCAL_FILE_DATA_SOURCE } from './constants'
import { useMarketplacePlugins } from '../../plugins/marketplace/hooks'
import { PluginType } from '../../plugins/types'
import { PluginCategoryEnum } from '../../plugins/types'
import { useGetLanguage } from '@/context/i18n'
type AllToolsProps = {
@ -86,7 +86,7 @@ const DataSources = ({
if (searchText) {
fetchPlugins({
query: searchText,
category: PluginType.datasource,
category: PluginCategoryEnum.datasource,
})
}
}, [searchText, enable_marketplace])

View File

@ -12,7 +12,7 @@ import SearchInput from '@/app/components/base/search-input'
import Tools from '../../../block-selector/tools'
import { useTranslation } from 'react-i18next'
import { useStrategyProviders } from '@/service/use-strategy'
import { PluginType, type StrategyPluginDetail } from '@/app/components/plugins/types'
import { PluginCategoryEnum, type StrategyPluginDetail } from '@/app/components/plugins/types'
import type { ToolWithProvider } from '../../../types'
import { CollectionType } from '@/app/components/tools/types'
import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
@ -140,7 +140,7 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
if (query) {
fetchPlugins({
query,
category: PluginType.agent,
category: PluginCategoryEnum.agent,
})
}
}, [query])

View File

@ -18,7 +18,6 @@ import type {
PluginDetail,
PluginInfoFromMarketPlace,
PluginTask,
PluginType,
PluginsFromMarketplaceByInfoResponse,
PluginsFromMarketplaceResponse,
ReferenceSetting,
@ -27,7 +26,7 @@ import type {
uploadGitHubResponse,
} from '@/app/components/plugins/types'
import { TaskStatus } from '@/app/components/plugins/types'
import { PluginType as PluginTypeEnum } from '@/app/components/plugins/types'
import { PluginCategoryEnum } from '@/app/components/plugins/types'
import type {
PluginsSearchParams,
} from '@/app/components/plugins/marketplace/types'
@ -488,7 +487,7 @@ export const useFetchPluginsInMarketPlaceByInfo = (infos: Record<string, any>[])
}
const usePluginTaskListKey = [NAME_SPACE, 'pluginTaskList']
export const usePluginTaskList = (category?: PluginType) => {
export const usePluginTaskList = (category?: PluginCategoryEnum) => {
const {
canManagement,
} = useReferenceSetting()
@ -605,7 +604,7 @@ export const usePluginInfo = (providerName?: string) => {
const name = parts[1]
try {
const response = await fetchPluginInfoFromMarketPlace({ org, name })
return response.data.plugin.category === PluginTypeEnum.model ? response.data.plugin : null
return response.data.plugin.category === PluginCategoryEnum.model ? response.data.plugin : null
}
catch {
return null