mirror of https://github.com/langgenius/dify.git
Merge remote-tracking branch 'origin/main' into feat/end-user-oauth
This commit is contained in:
commit
16dc744908
|
|
@ -1,8 +1,8 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { usePathname, useRouter } from 'next/navigation'
|
||||
import {
|
||||
RiBook2Line,
|
||||
RiFileEditLine,
|
||||
|
|
@ -25,6 +25,8 @@ import { EDUCATION_VERIFYING_LOCALSTORAGE_ITEM } from '@/app/education-apply/con
|
|||
import { useEducationVerify } from '@/service/use-education'
|
||||
import { useModalContextSelector } from '@/context/modal-context'
|
||||
import { Enterprise, Professional, Sandbox, Team } from './assets'
|
||||
import { Loading } from '../../base/icons/src/public/thought'
|
||||
import { useUnmountedRef } from 'ahooks'
|
||||
|
||||
type Props = {
|
||||
loc: string
|
||||
|
|
@ -35,6 +37,7 @@ const PlanComp: FC<Props> = ({
|
|||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const router = useRouter()
|
||||
const path = usePathname()
|
||||
const { userProfile } = useAppContext()
|
||||
const { plan, enableEducationPlan, allowRefreshEducationVerify, isEducationAccount } = useProviderContext()
|
||||
const isAboutToExpire = allowRefreshEducationVerify
|
||||
|
|
@ -61,17 +64,24 @@ const PlanComp: FC<Props> = ({
|
|||
})()
|
||||
|
||||
const [showModal, setShowModal] = React.useState(false)
|
||||
const { mutateAsync } = useEducationVerify()
|
||||
const { mutateAsync, isPending } = useEducationVerify()
|
||||
const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal)
|
||||
const unmountedRef = useUnmountedRef()
|
||||
const handleVerify = () => {
|
||||
if (isPending) return
|
||||
mutateAsync().then((res) => {
|
||||
localStorage.removeItem(EDUCATION_VERIFYING_LOCALSTORAGE_ITEM)
|
||||
if (unmountedRef.current) return
|
||||
router.push(`/education-apply?token=${res.token}`)
|
||||
setShowAccountSettingModal(null)
|
||||
}).catch(() => {
|
||||
setShowModal(true)
|
||||
})
|
||||
}
|
||||
useEffect(() => {
|
||||
// setShowAccountSettingModal would prevent navigation
|
||||
if (path.startsWith('/education-apply'))
|
||||
setShowAccountSettingModal(null)
|
||||
}, [path, setShowAccountSettingModal])
|
||||
return (
|
||||
<div className='relative rounded-2xl border-[0.5px] border-effects-highlight-lightmode-off bg-background-section-burn'>
|
||||
<div className='p-6 pb-2'>
|
||||
|
|
@ -96,9 +106,10 @@ const PlanComp: FC<Props> = ({
|
|||
</div>
|
||||
<div className='flex shrink-0 items-center gap-1'>
|
||||
{enableEducationPlan && (!isEducationAccount || isAboutToExpire) && (
|
||||
<Button variant='ghost' onClick={handleVerify}>
|
||||
<Button variant='ghost' onClick={handleVerify} disabled={isPending} >
|
||||
<RiGraduationCapLine className='mr-1 h-4 w-4' />
|
||||
{t('education.toVerified')}
|
||||
{isPending && <Loading className='ml-1 animate-spin-slow' />}
|
||||
</Button>
|
||||
)}
|
||||
{(plan.type as any) !== SelfHostedPlan.enterprise && (
|
||||
|
|
|
|||
|
|
@ -1,39 +1,28 @@
|
|||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react'
|
||||
import {
|
||||
useMarketplacePlugins,
|
||||
useMarketplacePluginsByCollectionId,
|
||||
} from '@/app/components/plugins/marketplace/hooks'
|
||||
import type { Plugin } 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) => {
|
||||
const exclude = useMemo(() => {
|
||||
return providers.map(provider => provider.plugin_id)
|
||||
}, [providers])
|
||||
const [collectionPlugins, setCollectionPlugins] = useState<Plugin[]>([])
|
||||
|
||||
const {
|
||||
plugins: collectionPlugins = [],
|
||||
isLoading: isCollectionLoading,
|
||||
} = useMarketplacePluginsByCollectionId('__datasource-settings-pinned-datasources')
|
||||
const {
|
||||
plugins,
|
||||
queryPlugins,
|
||||
queryPluginsWithDebounced,
|
||||
isLoading,
|
||||
isLoading: isPluginsLoading,
|
||||
} = useMarketplacePlugins()
|
||||
|
||||
const getCollectionPlugins = useCallback(async () => {
|
||||
const collectionPlugins = await getMarketplacePluginsByCollectionId('__datasource-settings-pinned-datasources')
|
||||
|
||||
setCollectionPlugins(collectionPlugins)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
getCollectionPlugins()
|
||||
}, [getCollectionPlugins])
|
||||
|
||||
useEffect(() => {
|
||||
if (searchText) {
|
||||
queryPluginsWithDebounced({
|
||||
|
|
@ -75,6 +64,6 @@ export const useMarketplaceAllPlugins = (providers: any[], searchText: string) =
|
|||
|
||||
return {
|
||||
plugins: allPlugins,
|
||||
isLoading,
|
||||
isLoading: isCollectionLoading || isPluginsLoading,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,9 @@ import {
|
|||
import { useProviderContext } from '@/context/provider-context'
|
||||
import {
|
||||
useMarketplacePlugins,
|
||||
useMarketplacePluginsByCollectionId,
|
||||
} from '@/app/components/plugins/marketplace/hooks'
|
||||
import type { Plugin } 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'
|
||||
import { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card'
|
||||
|
|
@ -255,25 +254,17 @@ export const useMarketplaceAllPlugins = (providers: ModelProvider[], searchText:
|
|||
const exclude = useMemo(() => {
|
||||
return providers.map(provider => provider.provider.replace(/(.+)\/([^/]+)$/, '$1'))
|
||||
}, [providers])
|
||||
const [collectionPlugins, setCollectionPlugins] = useState<Plugin[]>([])
|
||||
|
||||
const {
|
||||
plugins: collectionPlugins = [],
|
||||
isLoading: isCollectionLoading,
|
||||
} = useMarketplacePluginsByCollectionId('__model-settings-pinned-models')
|
||||
const {
|
||||
plugins,
|
||||
queryPlugins,
|
||||
queryPluginsWithDebounced,
|
||||
isLoading,
|
||||
isLoading: isPluginsLoading,
|
||||
} = useMarketplacePlugins()
|
||||
|
||||
const getCollectionPlugins = useCallback(async () => {
|
||||
const collectionPlugins = await getMarketplacePluginsByCollectionId('__model-settings-pinned-models')
|
||||
|
||||
setCollectionPlugins(collectionPlugins)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
getCollectionPlugins()
|
||||
}, [getCollectionPlugins])
|
||||
|
||||
useEffect(() => {
|
||||
if (searchText) {
|
||||
queryPluginsWithDebounced({
|
||||
|
|
@ -315,7 +306,7 @@ export const useMarketplaceAllPlugins = (providers: ModelProvider[], searchText:
|
|||
|
||||
return {
|
||||
plugins: allPlugins,
|
||||
isLoading,
|
||||
isLoading: isCollectionLoading || isPluginsLoading,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,3 +2,5 @@ export const DEFAULT_SORT = {
|
|||
sortBy: 'install_count',
|
||||
sortOrder: 'DESC',
|
||||
}
|
||||
|
||||
export const SCROLL_BOTTOM_THRESHOLD = 100
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export type MarketplaceContextValue = {
|
|||
activePluginType: string
|
||||
handleActivePluginTypeChange: (type: string) => void
|
||||
page: number
|
||||
handlePageChange: (page: number) => void
|
||||
handlePageChange: () => void
|
||||
plugins?: Plugin[]
|
||||
pluginsTotal?: number
|
||||
resetPlugins: () => void
|
||||
|
|
@ -128,8 +128,6 @@ export const MarketplaceContextProvider = ({
|
|||
const filterPluginTagsRef = useRef(filterPluginTags)
|
||||
const [activePluginType, setActivePluginType] = useState(categoryFromSearchParams)
|
||||
const activePluginTypeRef = useRef(activePluginType)
|
||||
const [page, setPage] = useState(1)
|
||||
const pageRef = useRef(page)
|
||||
const [sort, setSort] = useState(DEFAULT_SORT)
|
||||
const sortRef = useRef(sort)
|
||||
const {
|
||||
|
|
@ -149,7 +147,11 @@ export const MarketplaceContextProvider = ({
|
|||
queryPluginsWithDebounced,
|
||||
cancelQueryPluginsWithDebounced,
|
||||
isLoading: isPluginsLoading,
|
||||
fetchNextPage: fetchNextPluginsPage,
|
||||
hasNextPage: hasNextPluginsPage,
|
||||
page: pluginsPage,
|
||||
} = useMarketplacePlugins()
|
||||
const page = Math.max(pluginsPage || 0, 1)
|
||||
|
||||
useEffect(() => {
|
||||
if (queryFromSearchParams || hasValidTags || hasValidCategory) {
|
||||
|
|
@ -160,7 +162,6 @@ export const MarketplaceContextProvider = ({
|
|||
sortBy: sortRef.current.sortBy,
|
||||
sortOrder: sortRef.current.sortOrder,
|
||||
type: getMarketplaceListFilterType(activePluginTypeRef.current),
|
||||
page: pageRef.current,
|
||||
})
|
||||
const url = new URL(window.location.href)
|
||||
if (searchParams?.language)
|
||||
|
|
@ -221,7 +222,6 @@ export const MarketplaceContextProvider = ({
|
|||
sortOrder: sortRef.current.sortOrder,
|
||||
exclude,
|
||||
type: getMarketplaceListFilterType(activePluginTypeRef.current),
|
||||
page: pageRef.current,
|
||||
})
|
||||
}
|
||||
else {
|
||||
|
|
@ -233,7 +233,6 @@ export const MarketplaceContextProvider = ({
|
|||
sortOrder: sortRef.current.sortOrder,
|
||||
exclude,
|
||||
type: getMarketplaceListFilterType(activePluginTypeRef.current),
|
||||
page: pageRef.current,
|
||||
})
|
||||
}
|
||||
}, [exclude, queryPluginsWithDebounced, queryPlugins, handleUpdateSearchParams])
|
||||
|
|
@ -252,8 +251,6 @@ export const MarketplaceContextProvider = ({
|
|||
const handleSearchPluginTextChange = useCallback((text: string) => {
|
||||
setSearchPluginText(text)
|
||||
searchPluginTextRef.current = text
|
||||
setPage(1)
|
||||
pageRef.current = 1
|
||||
|
||||
handleQuery(true)
|
||||
}, [handleQuery])
|
||||
|
|
@ -261,8 +258,6 @@ export const MarketplaceContextProvider = ({
|
|||
const handleFilterPluginTagsChange = useCallback((tags: string[]) => {
|
||||
setFilterPluginTags(tags)
|
||||
filterPluginTagsRef.current = tags
|
||||
setPage(1)
|
||||
pageRef.current = 1
|
||||
|
||||
handleQuery()
|
||||
}, [handleQuery])
|
||||
|
|
@ -270,8 +265,6 @@ export const MarketplaceContextProvider = ({
|
|||
const handleActivePluginTypeChange = useCallback((type: string) => {
|
||||
setActivePluginType(type)
|
||||
activePluginTypeRef.current = type
|
||||
setPage(1)
|
||||
pageRef.current = 1
|
||||
|
||||
handleQuery()
|
||||
}, [handleQuery])
|
||||
|
|
@ -279,20 +272,14 @@ export const MarketplaceContextProvider = ({
|
|||
const handleSortChange = useCallback((sort: PluginsSort) => {
|
||||
setSort(sort)
|
||||
sortRef.current = sort
|
||||
setPage(1)
|
||||
pageRef.current = 1
|
||||
|
||||
handleQueryPlugins()
|
||||
}, [handleQueryPlugins])
|
||||
|
||||
const handlePageChange = useCallback(() => {
|
||||
if (pluginsTotal && plugins && pluginsTotal > plugins.length) {
|
||||
setPage(pageRef.current + 1)
|
||||
pageRef.current++
|
||||
|
||||
handleQueryPlugins()
|
||||
}
|
||||
}, [handleQueryPlugins, plugins, pluginsTotal])
|
||||
if (hasNextPluginsPage)
|
||||
fetchNextPluginsPage()
|
||||
}, [fetchNextPluginsPage, hasNextPluginsPage])
|
||||
|
||||
const handleMoreClick = useCallback((searchParams: SearchParamsFromCollection) => {
|
||||
setSearchPluginText(searchParams?.query || '')
|
||||
|
|
@ -305,9 +292,6 @@ export const MarketplaceContextProvider = ({
|
|||
sortBy: searchParams?.sort_by || DEFAULT_SORT.sortBy,
|
||||
sortOrder: searchParams?.sort_order || DEFAULT_SORT.sortOrder,
|
||||
}
|
||||
setPage(1)
|
||||
pageRef.current = 1
|
||||
|
||||
handleQueryPlugins()
|
||||
}, [handleQueryPlugins])
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ import {
|
|||
useEffect,
|
||||
useState,
|
||||
} from 'react'
|
||||
import {
|
||||
useInfiniteQuery,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useDebounceFn } from 'ahooks'
|
||||
import type {
|
||||
|
|
@ -16,39 +21,41 @@ import type {
|
|||
import {
|
||||
getFormattedPlugin,
|
||||
getMarketplaceCollectionsAndPlugins,
|
||||
getMarketplacePluginsByCollectionId,
|
||||
} from './utils'
|
||||
import { SCROLL_BOTTOM_THRESHOLD } from './constants'
|
||||
import i18n from '@/i18n-config/i18next-config'
|
||||
import {
|
||||
useMutationPluginsFromMarketplace,
|
||||
} from '@/service/use-plugins'
|
||||
import { postMarketplace } from '@/service/base'
|
||||
import type { PluginsFromMarketplaceResponse } from '@/app/components/plugins/types'
|
||||
|
||||
export const useMarketplaceCollectionsAndPlugins = () => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [isSuccess, setIsSuccess] = useState(false)
|
||||
const [marketplaceCollections, setMarketplaceCollections] = useState<MarketplaceCollection[]>()
|
||||
const [marketplaceCollectionPluginsMap, setMarketplaceCollectionPluginsMap] = useState<Record<string, Plugin[]>>()
|
||||
const [queryParams, setQueryParams] = useState<CollectionsAndPluginsSearchParams>()
|
||||
const [marketplaceCollectionsOverride, setMarketplaceCollections] = useState<MarketplaceCollection[]>()
|
||||
const [marketplaceCollectionPluginsMapOverride, setMarketplaceCollectionPluginsMap] = useState<Record<string, Plugin[]>>()
|
||||
|
||||
const queryMarketplaceCollectionsAndPlugins = useCallback(async (query?: CollectionsAndPluginsSearchParams) => {
|
||||
try {
|
||||
setIsLoading(true)
|
||||
setIsSuccess(false)
|
||||
const { marketplaceCollections, marketplaceCollectionPluginsMap } = await getMarketplaceCollectionsAndPlugins(query)
|
||||
setIsLoading(false)
|
||||
setIsSuccess(true)
|
||||
setMarketplaceCollections(marketplaceCollections)
|
||||
setMarketplaceCollectionPluginsMap(marketplaceCollectionPluginsMap)
|
||||
}
|
||||
// eslint-disable-next-line unused-imports/no-unused-vars
|
||||
catch (e) {
|
||||
setIsLoading(false)
|
||||
setIsSuccess(false)
|
||||
}
|
||||
const {
|
||||
data,
|
||||
isFetching,
|
||||
isSuccess,
|
||||
isPending,
|
||||
} = useQuery({
|
||||
queryKey: ['marketplaceCollectionsAndPlugins', queryParams],
|
||||
queryFn: ({ signal }) => getMarketplaceCollectionsAndPlugins(queryParams, { signal }),
|
||||
enabled: queryParams !== undefined,
|
||||
staleTime: 1000 * 60 * 5,
|
||||
gcTime: 1000 * 60 * 10,
|
||||
retry: false,
|
||||
})
|
||||
|
||||
const queryMarketplaceCollectionsAndPlugins = useCallback((query?: CollectionsAndPluginsSearchParams) => {
|
||||
setQueryParams(query ? { ...query } : {})
|
||||
}, [])
|
||||
const isLoading = !!queryParams && (isFetching || isPending)
|
||||
|
||||
return {
|
||||
marketplaceCollections,
|
||||
marketplaceCollections: marketplaceCollectionsOverride ?? data?.marketplaceCollections,
|
||||
setMarketplaceCollections,
|
||||
marketplaceCollectionPluginsMap,
|
||||
marketplaceCollectionPluginsMap: marketplaceCollectionPluginsMapOverride ?? data?.marketplaceCollectionPluginsMap,
|
||||
setMarketplaceCollectionPluginsMap,
|
||||
queryMarketplaceCollectionsAndPlugins,
|
||||
isLoading,
|
||||
|
|
@ -56,37 +63,128 @@ export const useMarketplaceCollectionsAndPlugins = () => {
|
|||
}
|
||||
}
|
||||
|
||||
export const useMarketplacePlugins = () => {
|
||||
export const useMarketplacePluginsByCollectionId = (
|
||||
collectionId?: string,
|
||||
query?: CollectionsAndPluginsSearchParams,
|
||||
) => {
|
||||
const {
|
||||
data,
|
||||
mutateAsync,
|
||||
reset,
|
||||
isFetching,
|
||||
isSuccess,
|
||||
isPending,
|
||||
} = useMutationPluginsFromMarketplace()
|
||||
} = useQuery({
|
||||
queryKey: ['marketplaceCollectionPlugins', collectionId, query],
|
||||
queryFn: ({ signal }) => {
|
||||
if (!collectionId)
|
||||
return Promise.resolve<Plugin[]>([])
|
||||
return getMarketplacePluginsByCollectionId(collectionId, query, { signal })
|
||||
},
|
||||
enabled: !!collectionId,
|
||||
staleTime: 1000 * 60 * 5,
|
||||
gcTime: 1000 * 60 * 10,
|
||||
retry: false,
|
||||
})
|
||||
|
||||
const [prevPlugins, setPrevPlugins] = useState<Plugin[] | undefined>()
|
||||
return {
|
||||
plugins: data || [],
|
||||
isLoading: !!collectionId && (isFetching || isPending),
|
||||
isSuccess,
|
||||
}
|
||||
}
|
||||
|
||||
export const useMarketplacePlugins = () => {
|
||||
const queryClient = useQueryClient()
|
||||
const [queryParams, setQueryParams] = useState<PluginsSearchParams>()
|
||||
|
||||
const normalizeParams = useCallback((pluginsSearchParams: PluginsSearchParams) => {
|
||||
const pageSize = pluginsSearchParams.pageSize || 40
|
||||
|
||||
return {
|
||||
...pluginsSearchParams,
|
||||
pageSize,
|
||||
}
|
||||
}, [])
|
||||
|
||||
const marketplacePluginsQuery = useInfiniteQuery({
|
||||
queryKey: ['marketplacePlugins', queryParams],
|
||||
queryFn: async ({ pageParam = 1, signal }) => {
|
||||
if (!queryParams) {
|
||||
return {
|
||||
plugins: [] as Plugin[],
|
||||
total: 0,
|
||||
page: 1,
|
||||
pageSize: 40,
|
||||
}
|
||||
}
|
||||
|
||||
const params = normalizeParams(queryParams)
|
||||
const {
|
||||
query,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
category,
|
||||
tags,
|
||||
exclude,
|
||||
type,
|
||||
pageSize,
|
||||
} = params
|
||||
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,
|
||||
exclude,
|
||||
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,
|
||||
}
|
||||
}
|
||||
},
|
||||
getNextPageParam: (lastPage) => {
|
||||
const nextPage = lastPage.page + 1
|
||||
const loaded = lastPage.page * lastPage.pageSize
|
||||
return loaded < (lastPage.total || 0) ? nextPage : undefined
|
||||
},
|
||||
initialPageParam: 1,
|
||||
enabled: !!queryParams,
|
||||
staleTime: 1000 * 60 * 5,
|
||||
gcTime: 1000 * 60 * 10,
|
||||
retry: false,
|
||||
})
|
||||
|
||||
const resetPlugins = useCallback(() => {
|
||||
reset()
|
||||
setPrevPlugins(undefined)
|
||||
}, [reset])
|
||||
setQueryParams(undefined)
|
||||
queryClient.removeQueries({
|
||||
queryKey: ['marketplacePlugins'],
|
||||
})
|
||||
}, [queryClient])
|
||||
|
||||
const handleUpdatePlugins = useCallback((pluginsSearchParams: PluginsSearchParams) => {
|
||||
mutateAsync(pluginsSearchParams).then((res) => {
|
||||
const currentPage = pluginsSearchParams.page || 1
|
||||
const resPlugins = res.data.bundles || res.data.plugins
|
||||
if (currentPage > 1) {
|
||||
setPrevPlugins(prevPlugins => [...(prevPlugins || []), ...resPlugins.map((plugin) => {
|
||||
return getFormattedPlugin(plugin)
|
||||
})])
|
||||
}
|
||||
else {
|
||||
setPrevPlugins(resPlugins.map((plugin) => {
|
||||
return getFormattedPlugin(plugin)
|
||||
}))
|
||||
}
|
||||
})
|
||||
}, [mutateAsync])
|
||||
setQueryParams(normalizeParams(pluginsSearchParams))
|
||||
}, [normalizeParams])
|
||||
|
||||
const { run: queryPluginsWithDebounced, cancel: cancelQueryPluginsWithDebounced } = useDebounceFn((pluginsSearchParams: PluginsSearchParams) => {
|
||||
handleUpdatePlugins(pluginsSearchParams)
|
||||
|
|
@ -94,14 +192,29 @@ export const useMarketplacePlugins = () => {
|
|||
wait: 500,
|
||||
})
|
||||
|
||||
const hasQuery = !!queryParams
|
||||
const hasData = marketplacePluginsQuery.data !== undefined
|
||||
const plugins = hasQuery && hasData
|
||||
? marketplacePluginsQuery.data.pages.flatMap(page => page.plugins)
|
||||
: undefined
|
||||
const total = hasQuery && hasData ? marketplacePluginsQuery.data.pages?.[0]?.total : undefined
|
||||
const isPluginsLoading = hasQuery && (
|
||||
marketplacePluginsQuery.isPending
|
||||
|| (marketplacePluginsQuery.isFetching && !marketplacePluginsQuery.data)
|
||||
)
|
||||
|
||||
return {
|
||||
plugins: prevPlugins,
|
||||
total: data?.data?.total,
|
||||
plugins,
|
||||
total,
|
||||
resetPlugins,
|
||||
queryPlugins: handleUpdatePlugins,
|
||||
queryPluginsWithDebounced,
|
||||
cancelQueryPluginsWithDebounced,
|
||||
isLoading: isPending,
|
||||
isLoading: isPluginsLoading,
|
||||
isFetchingNextPage: marketplacePluginsQuery.isFetchingNextPage,
|
||||
hasNextPage: marketplacePluginsQuery.hasNextPage,
|
||||
fetchNextPage: marketplacePluginsQuery.fetchNextPage,
|
||||
page: marketplacePluginsQuery.data?.pages?.length || (marketplacePluginsQuery.isPending && hasQuery ? 1 : 0),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +244,7 @@ export const useMarketplaceContainerScroll = (
|
|||
scrollHeight,
|
||||
clientHeight,
|
||||
} = target
|
||||
if (scrollTop + clientHeight >= scrollHeight - 5 && scrollTop > 0)
|
||||
if (scrollTop + clientHeight >= scrollHeight - SCROLL_BOTTOM_THRESHOLD && scrollTop > 0)
|
||||
callback()
|
||||
}, [callback])
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import IntersectionLine from './intersection-line'
|
|||
import SearchBoxWrapper from './search-box/search-box-wrapper'
|
||||
import PluginTypeSwitch from './plugin-type-switch'
|
||||
import ListWrapper from './list/list-wrapper'
|
||||
import type { SearchParams } from './types'
|
||||
import type { MarketplaceCollection, SearchParams } from './types'
|
||||
import type { Plugin } from '@/app/components/plugins/types'
|
||||
import { getMarketplaceCollectionsAndPlugins } from './utils'
|
||||
import { TanstackQueryInitializer } from '@/context/query-client'
|
||||
|
||||
|
|
@ -30,8 +31,8 @@ const Marketplace = async ({
|
|||
scrollContainerId,
|
||||
showSearchParams = true,
|
||||
}: MarketplaceProps) => {
|
||||
let marketplaceCollections: any = []
|
||||
let marketplaceCollectionPluginsMap = {}
|
||||
let marketplaceCollections: MarketplaceCollection[] = []
|
||||
let marketplaceCollectionPluginsMap: Record<string, Plugin[]> = {}
|
||||
if (!shouldExclude) {
|
||||
const marketplaceCollectionsAndPluginsData = await getMarketplaceCollectionsAndPlugins()
|
||||
marketplaceCollections = marketplaceCollectionsAndPluginsData.marketplaceCollections
|
||||
|
|
|
|||
|
|
@ -28,13 +28,20 @@ const ListWrapper = ({
|
|||
const isLoading = useMarketplaceContext(v => v.isLoading)
|
||||
const isSuccessCollections = useMarketplaceContext(v => v.isSuccessCollections)
|
||||
const handleQueryPlugins = useMarketplaceContext(v => v.handleQueryPlugins)
|
||||
const searchPluginText = useMarketplaceContext(v => v.searchPluginText)
|
||||
const filterPluginTags = useMarketplaceContext(v => v.filterPluginTags)
|
||||
const page = useMarketplaceContext(v => v.page)
|
||||
const handleMoreClick = useMarketplaceContext(v => v.handleMoreClick)
|
||||
|
||||
useEffect(() => {
|
||||
if (!marketplaceCollectionsFromClient?.length && isSuccessCollections)
|
||||
if (
|
||||
!marketplaceCollectionsFromClient?.length
|
||||
&& isSuccessCollections
|
||||
&& !searchPluginText
|
||||
&& !filterPluginTags.length
|
||||
)
|
||||
handleQueryPlugins()
|
||||
}, [handleQueryPlugins, marketplaceCollections, marketplaceCollectionsFromClient, isSuccessCollections])
|
||||
}, [handleQueryPlugins, marketplaceCollections, marketplaceCollectionsFromClient, isSuccessCollections, searchPluginText, filterPluginTags])
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -13,6 +13,14 @@ import {
|
|||
} from '@/config'
|
||||
import { getMarketplaceUrl } from '@/utils/var'
|
||||
|
||||
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`
|
||||
|
|
@ -46,20 +54,23 @@ export const getPluginDetailLinkInMarketplace = (plugin: Plugin) => {
|
|||
return `/plugins/${plugin.org}/${plugin.name}`
|
||||
}
|
||||
|
||||
export const getMarketplacePluginsByCollectionId = async (collectionId: string, query?: CollectionsAndPluginsSearchParams) => {
|
||||
let plugins: Plugin[]
|
||||
export const getMarketplacePluginsByCollectionId = async (
|
||||
collectionId: string,
|
||||
query?: CollectionsAndPluginsSearchParams,
|
||||
options?: MarketplaceFetchOptions,
|
||||
) => {
|
||||
let plugins: Plugin[] = []
|
||||
|
||||
try {
|
||||
const url = `${MARKETPLACE_API_PREFIX}/collections/${collectionId}/plugins`
|
||||
const headers = new Headers({
|
||||
'X-Dify-Version': !IS_MARKETPLACE ? APP_VERSION : '999.0.0',
|
||||
})
|
||||
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,
|
||||
|
|
@ -68,9 +79,7 @@ export const getMarketplacePluginsByCollectionId = async (collectionId: string,
|
|||
},
|
||||
)
|
||||
const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json()
|
||||
plugins = marketplaceCollectionPluginsDataJson.data.plugins.map((plugin: Plugin) => {
|
||||
return getFormattedPlugin(plugin)
|
||||
})
|
||||
plugins = (marketplaceCollectionPluginsDataJson.data.plugins || []).map((plugin: Plugin) => getFormattedPlugin(plugin))
|
||||
}
|
||||
// eslint-disable-next-line unused-imports/no-unused-vars
|
||||
catch (e) {
|
||||
|
|
@ -80,23 +89,31 @@ export const getMarketplacePluginsByCollectionId = async (collectionId: string,
|
|||
return plugins
|
||||
}
|
||||
|
||||
export const getMarketplaceCollectionsAndPlugins = async (query?: CollectionsAndPluginsSearchParams) => {
|
||||
let marketplaceCollections = [] as MarketplaceCollection[]
|
||||
let marketplaceCollectionPluginsMap = {} as Record<string, Plugin[]>
|
||||
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 = new Headers({
|
||||
'X-Dify-Version': !IS_MARKETPLACE ? APP_VERSION : '999.0.0',
|
||||
})
|
||||
const marketplaceCollectionsData = await globalThis.fetch(marketplaceUrl, { headers, cache: 'no-store' })
|
||||
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
|
||||
marketplaceCollections = marketplaceCollectionsDataJson.data.collections || []
|
||||
await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => {
|
||||
const plugins = await getMarketplacePluginsByCollectionId(collection.name, query)
|
||||
const plugins = await getMarketplacePluginsByCollectionId(collection.name, query, options)
|
||||
|
||||
marketplaceCollectionPluginsMap[collection.name] = plugins
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
'use client'
|
||||
|
||||
import { scan } from 'react-scan'
|
||||
import { useEffect } from 'react'
|
||||
import { IS_DEV } from '@/config'
|
||||
|
||||
export function ReactScan() {
|
||||
useEffect(() => {
|
||||
if (IS_DEV) {
|
||||
scan({
|
||||
enabled: true,
|
||||
// HACK: react-scan's getIsProduction() incorrectly detects Next.js dev as production
|
||||
// because Next.js devtools overlay uses production React build
|
||||
// Issue: https://github.com/aidenybai/react-scan/issues/402
|
||||
// TODO: remove this option after upstream fix
|
||||
dangerouslyForceRunInProduction: true,
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
|
@ -3,12 +3,12 @@ import {
|
|||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
import {
|
||||
useMarketplaceCollectionsAndPlugins,
|
||||
useMarketplacePlugins,
|
||||
} from '@/app/components/plugins/marketplace/hooks'
|
||||
import { SCROLL_BOTTOM_THRESHOLD } from '@/app/components/plugins/marketplace/constants'
|
||||
import { PluginCategoryEnum } from '@/app/components/plugins/types'
|
||||
import { getMarketplaceListCondition } from '@/app/components/plugins/marketplace/utils'
|
||||
import { useAllToolProviders } from '@/service/use-tools'
|
||||
|
|
@ -31,10 +31,10 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||
queryPlugins,
|
||||
queryPluginsWithDebounced,
|
||||
isLoading: isPluginsLoading,
|
||||
total: pluginsTotal,
|
||||
fetchNextPage,
|
||||
hasNextPage,
|
||||
page: pluginsPage,
|
||||
} = useMarketplacePlugins()
|
||||
const [page, setPage] = useState(1)
|
||||
const pageRef = useRef(page)
|
||||
const searchPluginTextRef = useRef(searchPluginText)
|
||||
const filterPluginTagsRef = useRef(filterPluginTags)
|
||||
|
||||
|
|
@ -44,9 +44,6 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||
}, [searchPluginText, filterPluginTags])
|
||||
useEffect(() => {
|
||||
if ((searchPluginText || filterPluginTags.length) && isSuccess) {
|
||||
setPage(1)
|
||||
pageRef.current = 1
|
||||
|
||||
if (searchPluginText) {
|
||||
queryPluginsWithDebounced({
|
||||
category: PluginCategoryEnum.tool,
|
||||
|
|
@ -54,7 +51,6 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||
tags: filterPluginTags,
|
||||
exclude,
|
||||
type: 'plugin',
|
||||
page: pageRef.current,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
|
@ -64,7 +60,6 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||
tags: filterPluginTags,
|
||||
exclude,
|
||||
type: 'plugin',
|
||||
page: pageRef.current,
|
||||
})
|
||||
}
|
||||
else {
|
||||
|
|
@ -87,24 +82,13 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||
scrollHeight,
|
||||
clientHeight,
|
||||
} = target
|
||||
if (scrollTop + clientHeight >= scrollHeight - 5 && scrollTop > 0) {
|
||||
if (scrollTop + clientHeight >= scrollHeight - SCROLL_BOTTOM_THRESHOLD && scrollTop > 0) {
|
||||
const searchPluginText = searchPluginTextRef.current
|
||||
const filterPluginTags = filterPluginTagsRef.current
|
||||
if (pluginsTotal && plugins && pluginsTotal > plugins.length && (!!searchPluginText || !!filterPluginTags.length)) {
|
||||
setPage(pageRef.current + 1)
|
||||
pageRef.current++
|
||||
|
||||
queryPlugins({
|
||||
category: PluginCategoryEnum.tool,
|
||||
query: searchPluginText,
|
||||
tags: filterPluginTags,
|
||||
exclude,
|
||||
type: 'plugin',
|
||||
page: pageRef.current,
|
||||
})
|
||||
}
|
||||
if (hasNextPage && (!!searchPluginText || !!filterPluginTags.length))
|
||||
fetchNextPage()
|
||||
}
|
||||
}, [exclude, plugins, pluginsTotal, queryPlugins])
|
||||
}, [exclude, fetchNextPage, hasNextPage, plugins, queryPlugins])
|
||||
|
||||
return {
|
||||
isLoading: isLoading || isPluginsLoading,
|
||||
|
|
@ -112,6 +96,6 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin
|
|||
marketplaceCollectionPluginsMap,
|
||||
plugins,
|
||||
handleScroll,
|
||||
page,
|
||||
page: Math.max(pluginsPage || 0, 1),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { ReactScan } from './components/react-scan'
|
||||
import RoutePrefixHandle from './routePrefixHandle'
|
||||
import type { Viewport } from 'next'
|
||||
import I18nServer from './components/i18n-server'
|
||||
|
|
@ -86,6 +87,7 @@ const LocaleLayout = async ({
|
|||
className='color-scheme h-full select-auto'
|
||||
{...datasetMap}
|
||||
>
|
||||
<ReactScan />
|
||||
<ThemeProvider
|
||||
attribute='data-theme'
|
||||
defaultTheme='system'
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ const EDITION = getStringConfig(
|
|||
export const IS_CE_EDITION = EDITION === 'SELF_HOSTED'
|
||||
export const IS_CLOUD_EDITION = EDITION === 'CLOUD'
|
||||
|
||||
export const IS_DEV = process.env.NODE_ENV === 'development'
|
||||
export const IS_PROD = process.env.NODE_ENV === 'production'
|
||||
|
||||
export const SUPPORT_MAIL_LOGIN = !!(
|
||||
process.env.NEXT_PUBLIC_SUPPORT_MAIL_LOGIN
|
||||
|| globalThis.document?.body?.getAttribute('data-public-support-mail-login')
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@ export type ConversationListResponse = {
|
|||
logs: Conversation[]
|
||||
}
|
||||
|
||||
export const fetchLogs = (url: string) =>
|
||||
fetch(url).then<ConversationListResponse>(r => r.json())
|
||||
|
||||
export const CompletionParams = ['temperature', 'top_p', 'presence_penalty', 'max_token', 'stop', 'frequency_penalty'] as const
|
||||
|
||||
export type CompletionParamType = typeof CompletionParams[number]
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
export type User = {
|
||||
id: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
name: string
|
||||
phone: string
|
||||
username: string
|
||||
email: string
|
||||
avatar: string
|
||||
}
|
||||
|
||||
export type UserResponse = {
|
||||
users: User[]
|
||||
}
|
||||
|
||||
export const fetchUsers = (url: string) =>
|
||||
fetch(url).then<UserResponse>(r => r.json())
|
||||
|
|
@ -201,6 +201,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"magicast": "^0.3.5",
|
||||
"postcss": "^8.5.6",
|
||||
"react-scan": "^0.4.3",
|
||||
"sass": "^1.93.2",
|
||||
"storybook": "9.1.13",
|
||||
"tailwindcss": "^3.4.18",
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ importers:
|
|||
version: 3.2.5
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.19
|
||||
version: 0.5.19(tailwindcss@3.4.18(yaml@2.8.2))
|
||||
version: 0.5.19(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2))
|
||||
'@tanstack/react-form':
|
||||
specifier: ^1.23.7
|
||||
version: 1.27.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
|
|
@ -498,7 +498,7 @@ importers:
|
|||
version: 9.1.16(eslint@9.39.1(jiti@1.21.7))(storybook@9.1.13(@testing-library/dom@10.4.1))(typescript@5.9.3)
|
||||
eslint-plugin-tailwindcss:
|
||||
specifier: ^3.18.2
|
||||
version: 3.18.2(tailwindcss@3.4.18(yaml@2.8.2))
|
||||
version: 3.18.2(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2))
|
||||
globals:
|
||||
specifier: ^15.15.0
|
||||
version: 15.15.0
|
||||
|
|
@ -523,6 +523,9 @@ importers:
|
|||
postcss:
|
||||
specifier: ^8.5.6
|
||||
version: 8.5.6
|
||||
react-scan:
|
||||
specifier: ^0.4.3
|
||||
version: 0.4.3(@types/react@19.1.17)(next@15.5.6(@babel/core@7.28.5)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.94.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(rollup@2.79.2)
|
||||
sass:
|
||||
specifier: ^1.93.2
|
||||
version: 1.94.2
|
||||
|
|
@ -531,7 +534,7 @@ importers:
|
|||
version: 9.1.13(@testing-library/dom@10.4.1)
|
||||
tailwindcss:
|
||||
specifier: ^3.4.18
|
||||
version: 3.4.18(yaml@2.8.2)
|
||||
version: 3.4.18(tsx@4.21.0)(yaml@2.8.2)
|
||||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@types/node@18.15.0)(typescript@5.9.3)
|
||||
|
|
@ -1349,12 +1352,18 @@ packages:
|
|||
peerDependencies:
|
||||
storybook: ^0.0.0-0 || ^9.0.0 || ^9.1.0-0 || ^9.2.0-0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0
|
||||
|
||||
'@clack/core@0.3.5':
|
||||
resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==}
|
||||
|
||||
'@clack/core@0.5.0':
|
||||
resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==}
|
||||
|
||||
'@clack/prompts@0.11.0':
|
||||
resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==}
|
||||
|
||||
'@clack/prompts@0.8.2':
|
||||
resolution: {integrity: sha512-6b9Ab2UiZwJYA9iMyboYyW9yJvAO9V753ZhS+DHKEjZRKAxPPOb7MXXu84lsPFG+vZt6FRFniZ8rXi+zCIw4yQ==}
|
||||
|
||||
'@code-inspector/core@1.2.9':
|
||||
resolution: {integrity: sha512-A1w+G73HlTB6S8X6sA6tT+ziWHTAcTyH+7FZ1Sgd3ZLXF/E/jT+hgRbKposjXMwxcbodRc6hBG6UyiV+VxwE6Q==}
|
||||
|
||||
|
|
@ -2591,6 +2600,12 @@ packages:
|
|||
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
|
||||
'@pivanov/utils@0.0.2':
|
||||
resolution: {integrity: sha512-q9CN0bFWxWgMY5hVVYyBgez1jGiLBa6I+LkG37ycylPhFvEGOOeaADGtUSu46CaZasPnlY8fCdVJZmrgKb1EPA==}
|
||||
peerDependencies:
|
||||
react: '>=18'
|
||||
react-dom: '>=18'
|
||||
|
||||
'@pkgr/core@0.2.9':
|
||||
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
|
||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||
|
|
@ -2627,6 +2642,11 @@ packages:
|
|||
'@preact/signals-core@1.12.1':
|
||||
resolution: {integrity: sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA==}
|
||||
|
||||
'@preact/signals@1.3.2':
|
||||
resolution: {integrity: sha512-naxcJgUJ6BTOROJ7C3QML7KvwKwCXQJYTc5L/b0eEsdYgPB6SxwoQ1vDGcS0Q7GVjAenVq/tXrybVdFShHYZWg==}
|
||||
peerDependencies:
|
||||
preact: 10.x
|
||||
|
||||
'@radix-ui/primitive@1.1.3':
|
||||
resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==}
|
||||
|
||||
|
|
@ -3457,6 +3477,11 @@ packages:
|
|||
peerDependencies:
|
||||
'@types/react': ~19.1.17
|
||||
|
||||
'@types/react-reconciler@0.28.9':
|
||||
resolution: {integrity: sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==}
|
||||
peerDependencies:
|
||||
'@types/react': ~19.1.17
|
||||
|
||||
'@types/react-slider@1.3.6':
|
||||
resolution: {integrity: sha512-RS8XN5O159YQ6tu3tGZIQz1/9StMLTg/FCIPxwqh2gwVixJnlfIodtVx+fpXVMZHe7A58lAX1Q4XTgAGOQaCQg==}
|
||||
|
||||
|
|
@ -3951,6 +3976,11 @@ packages:
|
|||
bing-translate-api@4.2.0:
|
||||
resolution: {integrity: sha512-7a9yo1NbGcHPS8zXTdz8tCOymHZp2pvCuYOChCaXKjOX8EIwdV3SLd4D7RGIqZt1UhffypYBUcAV2gDcTgK0rA==}
|
||||
|
||||
bippy@0.3.34:
|
||||
resolution: {integrity: sha512-vmptmU/20UdIWHHhq7qCSHhHzK7Ro3YJ1utU0fBG7ujUc58LEfTtilKxcF0IOgSjT5XLcm7CBzDjbv4lcKApGQ==}
|
||||
peerDependencies:
|
||||
react: '>=17.0.1'
|
||||
|
||||
birecord@0.1.1:
|
||||
resolution: {integrity: sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==}
|
||||
|
||||
|
|
@ -5374,6 +5404,11 @@ packages:
|
|||
fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
|
|
@ -6118,6 +6153,10 @@ packages:
|
|||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
kleur@4.1.5:
|
||||
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
knip@5.71.0:
|
||||
resolution: {integrity: sha512-hwgdqEJ+7DNJ5jE8BCPu7b57TY7vUwP6MzWYgCgPpg6iPCee/jKPShDNIlFER2koti4oz5xF88VJbKCb4Wl71g==}
|
||||
engines: {node: '>=18.18.0'}
|
||||
|
|
@ -6568,6 +6607,10 @@ packages:
|
|||
monaco-editor@0.55.1:
|
||||
resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==}
|
||||
|
||||
mri@1.2.0:
|
||||
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
mrmime@2.0.1:
|
||||
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -6920,6 +6963,16 @@ packages:
|
|||
pkg-types@2.3.0:
|
||||
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
|
||||
|
||||
playwright-core@1.57.0:
|
||||
resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.57.0:
|
||||
resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
pluralize@8.0.0:
|
||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||
engines: {node: '>=4'}
|
||||
|
|
@ -7033,6 +7086,9 @@ packages:
|
|||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
preact@10.28.0:
|
||||
resolution: {integrity: sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -7271,6 +7327,26 @@ packages:
|
|||
react: '>=16.3.0'
|
||||
react-dom: '>=16.3.0'
|
||||
|
||||
react-scan@0.4.3:
|
||||
resolution: {integrity: sha512-jhAQuQ1nja6HUYrSpbmNFHqZPsRCXk8Yqu0lHoRIw9eb8N96uTfXCpVyQhTTnJ/nWqnwuvxbpKVG/oWZT8+iTQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@remix-run/react': '>=1.0.0'
|
||||
next: '>=13.0.0'
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-router: ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||
react-router-dom: ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||
peerDependenciesMeta:
|
||||
'@remix-run/react':
|
||||
optional: true
|
||||
next:
|
||||
optional: true
|
||||
react-router:
|
||||
optional: true
|
||||
react-router-dom:
|
||||
optional: true
|
||||
|
||||
react-slider@2.0.6:
|
||||
resolution: {integrity: sha512-gJxG1HwmuMTJ+oWIRCmVWvgwotNCbByTwRkFZC6U4MBsHqJBmxwbYRJUmxy4Tke1ef8r9jfXjgkmY/uHOCEvbA==}
|
||||
peerDependencies:
|
||||
|
|
@ -8080,6 +8156,11 @@ packages:
|
|||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
tsx@4.21.0:
|
||||
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
tty-browserify@0.0.1:
|
||||
resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==}
|
||||
|
||||
|
|
@ -8188,6 +8269,10 @@ packages:
|
|||
resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
unplugin@2.1.0:
|
||||
resolution: {integrity: sha512-us4j03/499KhbGP8BU7Hrzrgseo+KdfJYWcbcajCOqsAyb8Gk0Yn2kiUIcZISYCb1JFaZfIuG3b42HmguVOKCQ==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
|
||||
upath@1.2.0:
|
||||
resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==}
|
||||
engines: {node: '>=4'}
|
||||
|
|
@ -9663,6 +9748,11 @@ snapshots:
|
|||
- '@chromatic-com/cypress'
|
||||
- '@chromatic-com/playwright'
|
||||
|
||||
'@clack/core@0.3.5':
|
||||
dependencies:
|
||||
picocolors: 1.1.1
|
||||
sisteransi: 1.0.5
|
||||
|
||||
'@clack/core@0.5.0':
|
||||
dependencies:
|
||||
picocolors: 1.1.1
|
||||
|
|
@ -9674,6 +9764,12 @@ snapshots:
|
|||
picocolors: 1.1.1
|
||||
sisteransi: 1.0.5
|
||||
|
||||
'@clack/prompts@0.8.2':
|
||||
dependencies:
|
||||
'@clack/core': 0.3.5
|
||||
picocolors: 1.1.1
|
||||
sisteransi: 1.0.5
|
||||
|
||||
'@code-inspector/core@1.2.9':
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.25
|
||||
|
|
@ -11063,6 +11159,11 @@ snapshots:
|
|||
'@parcel/watcher-win32-x64': 2.5.1
|
||||
optional: true
|
||||
|
||||
'@pivanov/utils@0.0.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
|
||||
dependencies:
|
||||
react: 19.1.1
|
||||
react-dom: 19.1.1(react@19.1.1)
|
||||
|
||||
'@pkgr/core@0.2.9': {}
|
||||
|
||||
'@pmmmwh/react-refresh-webpack-plugin@0.5.17(react-refresh@0.14.2)(type-fest@4.2.0)(webpack-hot-middleware@2.26.1)(webpack@5.103.0(esbuild@0.25.0)(uglify-js@3.19.3))':
|
||||
|
|
@ -11084,6 +11185,11 @@ snapshots:
|
|||
|
||||
'@preact/signals-core@1.12.1': {}
|
||||
|
||||
'@preact/signals@1.3.2(preact@10.28.0)':
|
||||
dependencies:
|
||||
'@preact/signals-core': 1.12.1
|
||||
preact: 10.28.0
|
||||
|
||||
'@radix-ui/primitive@1.1.3': {}
|
||||
|
||||
'@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.17)(react@19.1.1)':
|
||||
|
|
@ -11690,10 +11796,10 @@ snapshots:
|
|||
dependencies:
|
||||
defer-to-connect: 2.0.1
|
||||
|
||||
'@tailwindcss/typography@0.5.19(tailwindcss@3.4.18(yaml@2.8.2))':
|
||||
'@tailwindcss/typography@0.5.19(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
postcss-selector-parser: 6.0.10
|
||||
tailwindcss: 3.4.18(yaml@2.8.2)
|
||||
tailwindcss: 3.4.18(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
'@tanstack/devtools-event-client@0.3.5': {}
|
||||
|
||||
|
|
@ -12065,6 +12171,10 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/react': 19.1.17
|
||||
|
||||
'@types/react-reconciler@0.28.9(@types/react@19.1.17)':
|
||||
dependencies:
|
||||
'@types/react': 19.1.17
|
||||
|
||||
'@types/react-slider@1.3.6':
|
||||
dependencies:
|
||||
'@types/react': 19.1.17
|
||||
|
|
@ -12644,6 +12754,13 @@ snapshots:
|
|||
dependencies:
|
||||
got: 11.8.6
|
||||
|
||||
bippy@0.3.34(@types/react@19.1.17)(react@19.1.1):
|
||||
dependencies:
|
||||
'@types/react-reconciler': 0.28.9(@types/react@19.1.17)
|
||||
react: 19.1.1
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
|
||||
birecord@0.1.1: {}
|
||||
|
||||
bl@4.1.0:
|
||||
|
|
@ -13898,11 +14015,11 @@ snapshots:
|
|||
- supports-color
|
||||
- typescript
|
||||
|
||||
eslint-plugin-tailwindcss@3.18.2(tailwindcss@3.4.18(yaml@2.8.2)):
|
||||
eslint-plugin-tailwindcss@3.18.2(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
fast-glob: 3.3.3
|
||||
postcss: 8.5.6
|
||||
tailwindcss: 3.4.18(yaml@2.8.2)
|
||||
tailwindcss: 3.4.18(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
eslint-plugin-toml@0.12.0(eslint@9.39.1(jiti@1.21.7)):
|
||||
dependencies:
|
||||
|
|
@ -14307,6 +14424,9 @@ snapshots:
|
|||
|
||||
fs.realpath@1.0.0: {}
|
||||
|
||||
fsevents@2.3.2:
|
||||
optional: true
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
|
|
@ -15257,6 +15377,8 @@ snapshots:
|
|||
|
||||
kleur@3.0.3: {}
|
||||
|
||||
kleur@4.1.5: {}
|
||||
|
||||
knip@5.71.0(@types/node@18.15.0)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
|
|
@ -16029,6 +16151,8 @@ snapshots:
|
|||
dompurify: 3.2.7
|
||||
marked: 14.0.0
|
||||
|
||||
mri@1.2.0: {}
|
||||
|
||||
mrmime@2.0.1: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
|
@ -16414,6 +16538,14 @@ snapshots:
|
|||
exsolve: 1.0.8
|
||||
pathe: 2.0.3
|
||||
|
||||
playwright-core@1.57.0: {}
|
||||
|
||||
playwright@1.57.0:
|
||||
dependencies:
|
||||
playwright-core: 1.57.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
|
||||
pluralize@8.0.0: {}
|
||||
|
||||
pnpm-workspace-yaml@1.3.0:
|
||||
|
|
@ -16446,12 +16578,13 @@ snapshots:
|
|||
camelcase-css: 2.0.1
|
||||
postcss: 8.5.6
|
||||
|
||||
postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2):
|
||||
postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
lilconfig: 3.1.3
|
||||
optionalDependencies:
|
||||
jiti: 1.21.7
|
||||
postcss: 8.5.6
|
||||
tsx: 4.21.0
|
||||
yaml: 2.8.2
|
||||
|
||||
postcss-loader@8.2.0(postcss@8.5.6)(typescript@5.9.3)(webpack@5.103.0(esbuild@0.25.0)(uglify-js@3.19.3)):
|
||||
|
|
@ -16520,6 +16653,8 @@ snapshots:
|
|||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
preact@10.28.0: {}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
dependencies:
|
||||
detect-libc: 2.1.2
|
||||
|
|
@ -16782,6 +16917,35 @@ snapshots:
|
|||
react-draggable: 4.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
tslib: 2.6.2
|
||||
|
||||
react-scan@0.4.3(@types/react@19.1.17)(next@15.5.6(@babel/core@7.28.5)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.94.2))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(rollup@2.79.2):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/generator': 7.28.5
|
||||
'@babel/types': 7.28.5
|
||||
'@clack/core': 0.3.5
|
||||
'@clack/prompts': 0.8.2
|
||||
'@pivanov/utils': 0.0.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
|
||||
'@preact/signals': 1.3.2(preact@10.28.0)
|
||||
'@rollup/pluginutils': 5.3.0(rollup@2.79.2)
|
||||
'@types/node': 20.19.25
|
||||
bippy: 0.3.34(@types/react@19.1.17)(react@19.1.1)
|
||||
esbuild: 0.25.0
|
||||
estree-walker: 3.0.3
|
||||
kleur: 4.1.5
|
||||
mri: 1.2.0
|
||||
playwright: 1.57.0
|
||||
preact: 10.28.0
|
||||
react: 19.1.1
|
||||
react-dom: 19.1.1(react@19.1.1)
|
||||
tsx: 4.21.0
|
||||
optionalDependencies:
|
||||
next: 15.5.6(@babel/core@7.28.5)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.94.2)
|
||||
unplugin: 2.1.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- rollup
|
||||
- supports-color
|
||||
|
||||
react-slider@2.0.6(react@19.1.1):
|
||||
dependencies:
|
||||
prop-types: 15.8.1
|
||||
|
|
@ -17536,7 +17700,7 @@ snapshots:
|
|||
|
||||
tailwind-merge@2.6.0: {}
|
||||
|
||||
tailwindcss@3.4.18(yaml@2.8.2):
|
||||
tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
'@alloc/quick-lru': 5.2.0
|
||||
arg: 5.0.2
|
||||
|
|
@ -17555,7 +17719,7 @@ snapshots:
|
|||
postcss: 8.5.6
|
||||
postcss-import: 15.1.0(postcss@8.5.6)
|
||||
postcss-js: 4.1.0(postcss@8.5.6)
|
||||
postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(yaml@2.8.2)
|
||||
postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2)
|
||||
postcss-nested: 6.2.0(postcss@8.5.6)
|
||||
postcss-selector-parser: 6.1.2
|
||||
resolve: 1.22.11
|
||||
|
|
@ -17732,6 +17896,13 @@ snapshots:
|
|||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tsx@4.21.0:
|
||||
dependencies:
|
||||
esbuild: 0.25.0
|
||||
get-tsconfig: 4.13.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
tty-browserify@0.0.1: {}
|
||||
|
||||
tunnel-agent@0.6.0:
|
||||
|
|
@ -17834,6 +18005,12 @@ snapshots:
|
|||
acorn: 8.15.0
|
||||
webpack-virtual-modules: 0.6.2
|
||||
|
||||
unplugin@2.1.0:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
webpack-virtual-modules: 0.6.2
|
||||
optional: true
|
||||
|
||||
upath@1.2.0: {}
|
||||
|
||||
update-browserslist-db@1.1.4(browserslist@4.28.0):
|
||||
|
|
|
|||
Loading…
Reference in New Issue