mirror of
https://github.com/langgenius/dify.git
synced 2026-03-10 01:46:14 +08:00
fix(plugin-install): support bundle marketplace dependency shape
This commit is contained in:
@ -266,6 +266,29 @@ describe('useInstallMultiState', () => {
|
||||
expect(result.current.plugins[1]).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
it('should resolve marketplace dependency from organization and plugin fields', async () => {
|
||||
mockMarketplaceData = createMarketplaceApiData([0])
|
||||
|
||||
const params = createDefaultParams({
|
||||
allPlugins: [
|
||||
{
|
||||
type: 'marketplace',
|
||||
value: {
|
||||
organization: 'test-org',
|
||||
plugin: 'plugin-0',
|
||||
version: '1.0.0',
|
||||
},
|
||||
} as GitHubItemAndMarketPlaceDependency,
|
||||
] as Dependency[],
|
||||
})
|
||||
const { result } = renderHook(() => useInstallMultiState(params))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.plugins[0]).toBeDefined()
|
||||
expect(result.current.errorIndexes).not.toContain(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// ==================== Error Handling ====================
|
||||
|
||||
@ -20,6 +20,12 @@ type MarketplacePluginInfo = {
|
||||
version?: string
|
||||
}
|
||||
|
||||
type MarketplaceRequest = {
|
||||
dslIndex: number
|
||||
dependency: GitHubItemAndMarketPlaceDependency
|
||||
info: MarketplacePluginInfo
|
||||
}
|
||||
|
||||
export function getPluginKey(plugin: Plugin | undefined): string {
|
||||
return `${plugin?.org || plugin?.author}/${plugin?.name}`
|
||||
}
|
||||
@ -40,6 +46,25 @@ function parseMarketplaceIdentifier(identifier?: string): MarketplacePluginInfo
|
||||
return { organization, plugin, version }
|
||||
}
|
||||
|
||||
function getMarketplacePluginInfo(
|
||||
value: GitHubItemAndMarketPlaceDependency['value'],
|
||||
): MarketplacePluginInfo | null {
|
||||
const parsedInfo = parseMarketplaceIdentifier(
|
||||
value.marketplace_plugin_unique_identifier || value.plugin_unique_identifier,
|
||||
)
|
||||
if (parsedInfo)
|
||||
return parsedInfo
|
||||
|
||||
if (!value.organization || !value.plugin)
|
||||
return null
|
||||
|
||||
return {
|
||||
organization: value.organization,
|
||||
plugin: value.plugin,
|
||||
version: value.version,
|
||||
}
|
||||
}
|
||||
|
||||
function initPluginsFromDependencies(allPlugins: Dependency[]): (Plugin | undefined)[] {
|
||||
if (!allPlugins.some(d => d.type === 'package'))
|
||||
return []
|
||||
@ -77,33 +102,35 @@ export function useInstallMultiState({
|
||||
}, [])
|
||||
}, [allPlugins])
|
||||
|
||||
const { marketplacePayloadByIdentifier, invalidMarketplaceIndexes } = useMemo(() => {
|
||||
const { marketplaceRequests, invalidMarketplaceIndexes } = useMemo(() => {
|
||||
return marketplacePlugins.reduce<{
|
||||
marketplacePayloadByIdentifier: MarketplacePluginInfo[]
|
||||
marketplaceRequests: MarketplaceRequest[]
|
||||
invalidMarketplaceIndexes: number[]
|
||||
}>((acc, d, marketplaceIndex) => {
|
||||
const parsedIdentifier = parseMarketplaceIdentifier(
|
||||
d.value.marketplace_plugin_unique_identifier || d.value.plugin_unique_identifier,
|
||||
)
|
||||
}>((acc, dependency, marketplaceIndex) => {
|
||||
const dslIndex = marketPlaceInDSLIndex[marketplaceIndex]
|
||||
if (parsedIdentifier)
|
||||
acc.marketplacePayloadByIdentifier.push(parsedIdentifier)
|
||||
else if (dslIndex !== undefined)
|
||||
if (dslIndex === undefined)
|
||||
return acc
|
||||
|
||||
const marketplaceInfo = getMarketplacePluginInfo(dependency.value)
|
||||
if (!marketplaceInfo)
|
||||
acc.invalidMarketplaceIndexes.push(dslIndex)
|
||||
else
|
||||
acc.marketplaceRequests.push({ dslIndex, dependency, info: marketplaceInfo })
|
||||
|
||||
return acc
|
||||
}, {
|
||||
marketplacePayloadByIdentifier: [],
|
||||
marketplaceRequests: [],
|
||||
invalidMarketplaceIndexes: [],
|
||||
})
|
||||
}, [marketPlaceInDSLIndex, marketplacePlugins])
|
||||
|
||||
// Marketplace data fetching: by unique identifier
|
||||
// Marketplace data fetching: by normalized marketplace info
|
||||
const {
|
||||
isLoading: isFetchingById,
|
||||
data: infoGetById,
|
||||
error: infoByIdError,
|
||||
} = useFetchPluginsInMarketPlaceByInfo(
|
||||
marketplacePayloadByIdentifier,
|
||||
marketplaceRequests.map(request => request.info),
|
||||
)
|
||||
|
||||
// Derive marketplace plugin data and errors from API responses
|
||||
@ -113,22 +140,26 @@ export function useInstallMultiState({
|
||||
|
||||
// Process "by ID" response
|
||||
if (!isFetchingById && infoGetById?.data.list) {
|
||||
const payloads = infoGetById.data.list
|
||||
const pluginById = new Map(
|
||||
infoGetById.data.list.map(item => [item.plugin.plugin_id, item.plugin]),
|
||||
payloads.map(item => [item.plugin.plugin_id, item.plugin]),
|
||||
)
|
||||
|
||||
marketPlaceInDSLIndex.forEach((index, i) => {
|
||||
const dependency = marketplacePlugins[i]
|
||||
const pluginId = (dependency?.value.marketplace_plugin_unique_identifier || dependency?.value.plugin_unique_identifier)?.split(':')[0]
|
||||
const pluginInfo = pluginId ? pluginById.get(pluginId) : undefined
|
||||
marketplaceRequests.forEach((request, requestIndex) => {
|
||||
const pluginId = (
|
||||
request.dependency.value.marketplace_plugin_unique_identifier
|
||||
|| request.dependency.value.plugin_unique_identifier
|
||||
)?.split(':')[0]
|
||||
const pluginInfo = (pluginId ? pluginById.get(pluginId) : undefined) || payloads[requestIndex]?.plugin
|
||||
|
||||
if (pluginInfo) {
|
||||
pluginMap.set(index, {
|
||||
pluginMap.set(request.dslIndex, {
|
||||
...pluginInfo,
|
||||
from: dependency.type,
|
||||
from: request.dependency.type,
|
||||
version: pluginInfo.version || pluginInfo.latest_version,
|
||||
})
|
||||
}
|
||||
else { errorSet.add(index) }
|
||||
else { errorSet.add(request.dslIndex) }
|
||||
})
|
||||
}
|
||||
|
||||
@ -137,7 +168,7 @@ export function useInstallMultiState({
|
||||
marketPlaceInDSLIndex.forEach(index => errorSet.add(index))
|
||||
|
||||
return { marketplacePluginMap: pluginMap, marketplaceErrorIndexes: errorSet }
|
||||
}, [invalidMarketplaceIndexes, isFetchingById, infoGetById, infoByIdError, marketPlaceInDSLIndex, marketplacePlugins])
|
||||
}, [invalidMarketplaceIndexes, isFetchingById, infoGetById, infoByIdError, marketPlaceInDSLIndex, marketplaceRequests])
|
||||
|
||||
// GitHub-fetched plugins and errors (imperative state from child callbacks)
|
||||
const [githubPluginMap, setGithubPluginMap] = useState<Map<number, Plugin>>(() => new Map())
|
||||
|
||||
@ -508,6 +508,8 @@ export type GitHubItemAndMarketPlaceDependency = {
|
||||
type: 'github' | 'marketplace' | 'package'
|
||||
value: {
|
||||
repo?: string
|
||||
organization?: string // from bundle marketplace dependency
|
||||
plugin?: string // from bundle marketplace dependency
|
||||
version?: string // from app DSL
|
||||
package?: string // from app DSL
|
||||
release?: string // from local package. same to the version
|
||||
|
||||
Reference in New Issue
Block a user