mirror of
https://github.com/langgenius/dify.git
synced 2026-06-24 13:01:16 +08:00
refactor: adapt docs links for product prefixes (#37565)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
parent
f380bbaa10
commit
855bb32306
@ -17,7 +17,7 @@ vi.mock('@/next/navigation', () => ({
|
||||
|
||||
// Mock useDocLink hook
|
||||
vi.mock('@/context/i18n', () => ({
|
||||
useDocLink: () => (path?: string) => `https://docs.dify.ai/en${path || ''}`,
|
||||
useDocLink: () => (path?: string) => `https://docs.dify.ai/en${path?.startsWith('/use-dify/') ? `/cloud${path}` : path || ''}`,
|
||||
}))
|
||||
|
||||
// Mock external context providers (these are external dependencies)
|
||||
@ -155,7 +155,7 @@ describe('ExternalKnowledgeBaseCreate', () => {
|
||||
renderComponent()
|
||||
|
||||
const docLink = screen.getByText('dataset.connectHelper.helper4')
|
||||
expect(docLink)!.toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/knowledge/connect-external-knowledge-base')
|
||||
expect(docLink)!.toHaveAttribute('href', 'https://docs.dify.ai/en/cloud/use-dify/knowledge/connect-external-knowledge-base')
|
||||
expect(docLink)!.toHaveAttribute('target', '_blank')
|
||||
expect(docLink)!.toHaveAttribute('rel', 'noopener noreferrer')
|
||||
})
|
||||
|
||||
@ -22,6 +22,7 @@ vi.mock('react-i18next', () => ({
|
||||
|
||||
vi.mock('@/context/i18n', () => ({
|
||||
defaultDocBaseUrl: 'https://docs.dify.ai',
|
||||
getDocHomePath: () => '/home',
|
||||
}))
|
||||
|
||||
vi.mock('@/i18n-config/language', () => ({
|
||||
@ -45,7 +46,7 @@ describe('docsCommand', () => {
|
||||
docsCommand.execute?.()
|
||||
|
||||
expect(openSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining('https://docs.dify.ai'),
|
||||
'https://docs.dify.ai/en/home',
|
||||
'_blank',
|
||||
'noopener,noreferrer',
|
||||
)
|
||||
@ -85,7 +86,11 @@ describe('docsCommand', () => {
|
||||
const handlers = vi.mocked(registerCommands).mock.calls[0]![0]
|
||||
await handlers['navigation.doc']!()
|
||||
|
||||
expect(openSpy).toHaveBeenCalledWith('https://docs.dify.ai/en', '_blank', 'noopener,noreferrer')
|
||||
expect(openSpy).toHaveBeenCalledWith(
|
||||
'https://docs.dify.ai/en/home',
|
||||
'_blank',
|
||||
'noopener,noreferrer',
|
||||
)
|
||||
openSpy.mockRestore()
|
||||
})
|
||||
|
||||
|
||||
@ -2,13 +2,20 @@ import type { SlashCommandHandler } from './types'
|
||||
import { RiBookOpenLine } from '@remixicon/react'
|
||||
import * as React from 'react'
|
||||
import { getI18n } from 'react-i18next'
|
||||
import { defaultDocBaseUrl } from '@/context/i18n'
|
||||
import { defaultDocBaseUrl, getDocHomePath } from '@/context/i18n'
|
||||
import { getDocLanguage } from '@/i18n-config/language'
|
||||
import { registerCommands, unregisterCommands } from './command-bus'
|
||||
|
||||
// Documentation command dependency types - no external dependencies needed
|
||||
type DocDeps = Record<string, never>
|
||||
|
||||
const getDocsHomeUrl = () => {
|
||||
const i18n = getI18n()
|
||||
const currentLocale = i18n.language
|
||||
const docLanguage = getDocLanguage(currentLocale)
|
||||
return `${defaultDocBaseUrl}/${docLanguage}${getDocHomePath()}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Documentation command - Opens help documentation
|
||||
*/
|
||||
@ -19,11 +26,7 @@ export const docsCommand: SlashCommandHandler<DocDeps> = {
|
||||
|
||||
// Direct execution function
|
||||
execute: () => {
|
||||
const i18n = getI18n()
|
||||
const currentLocale = i18n.language
|
||||
const docLanguage = getDocLanguage(currentLocale)
|
||||
const url = `${defaultDocBaseUrl}/${docLanguage}`
|
||||
window.open(url, '_blank', 'noopener,noreferrer')
|
||||
window.open(getDocsHomeUrl(), '_blank', 'noopener,noreferrer')
|
||||
},
|
||||
|
||||
async search(args: string, locale: string = 'en') {
|
||||
@ -43,14 +46,9 @@ export const docsCommand: SlashCommandHandler<DocDeps> = {
|
||||
},
|
||||
|
||||
register(_deps: DocDeps) {
|
||||
const i18n = getI18n()
|
||||
registerCommands({
|
||||
'navigation.doc': async (_args) => {
|
||||
// Get the current language from i18n
|
||||
const currentLocale = i18n.language
|
||||
const docLanguage = getDocLanguage(currentLocale)
|
||||
const url = `${defaultDocBaseUrl}/${docLanguage}`
|
||||
window.open(url, '_blank', 'noopener,noreferrer')
|
||||
window.open(getDocsHomeUrl(), '_blank', 'noopener,noreferrer')
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
@ -11,8 +11,8 @@ describe('Empty State', () => {
|
||||
expect(screen.getByText('common.apiBasedExtension.title')).toBeInTheDocument()
|
||||
const link = screen.getByText('common.apiBasedExtension.link')
|
||||
expect(link).toBeInTheDocument()
|
||||
// The real useDocLink includes the language prefix (defaulting to /en in tests)
|
||||
expect(link.closest('a')).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/api-extension/api-extension')
|
||||
// The real useDocLink includes language and product prefixes in tests.
|
||||
expect(link.closest('a')).toHaveAttribute('href', 'https://docs.dify.ai/en/self-host/use-dify/workspace/api-extension/api-extension')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -578,7 +578,7 @@ describe('IntegrationsPage', () => {
|
||||
expect(screen.getAllByText('common.toolsPage.toolPlugin')).toHaveLength(2)
|
||||
expect(screen.getByText('common.toolsPage.description')).toBeInTheDocument()
|
||||
expect(screen.getByText('common.toolsPage.description').closest('[class*="max-w-[1600px]"]')).toHaveClass('px-6')
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/tools')
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/self-host/use-dify/workspace/tools')
|
||||
})
|
||||
|
||||
it('aligns model provider headers to the unified content frame', () => {
|
||||
@ -600,7 +600,7 @@ describe('IntegrationsPage', () => {
|
||||
|
||||
expect(screen.getAllByText('MCP')).toHaveLength(2)
|
||||
expect(screen.getByText('common.mcpPage.description')).toBeInTheDocument()
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/build/mcp')
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/self-host/use-dify/build/mcp')
|
||||
expect(screen.queryByText('common.toolsPage.description')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
@ -609,7 +609,7 @@ describe('IntegrationsPage', () => {
|
||||
|
||||
expect(screen.getAllByText('common.settings.swaggerAPIAsTool')).toHaveLength(2)
|
||||
expect(screen.getByText('common.swaggerAPIAsToolPage.description')).toBeInTheDocument()
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/tools#custom-tool')
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/self-host/use-dify/workspace/tools#custom-tool')
|
||||
expect(screen.queryByText('common.toolsPage.description')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
@ -630,7 +630,7 @@ describe('IntegrationsPage', () => {
|
||||
expect(screen.getAllByText('common.settings.customEndpoint')).toHaveLength(2)
|
||||
expect(screen.getByText('common.apiBasedExtensionPage.description')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('api-extension-toolbar')).toBeInTheDocument()
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/api-extension/api-extension')
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/self-host/use-dify/workspace/api-extension/api-extension')
|
||||
expect(screen.queryByText('common.toolsPage.description')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
@ -652,7 +652,7 @@ describe('IntegrationsPage', () => {
|
||||
|
||||
expect(screen.getAllByText('workflow.common.workflowAsTool')).toHaveLength(2)
|
||||
expect(screen.getByText('common.workflowAsToolPage.description')).toBeInTheDocument()
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/tools#workflow-tool')
|
||||
expect(screen.getByRole('link', { name: /common\.modelProvider\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/self-host/use-dify/workspace/tools#workflow-tool')
|
||||
expect(screen.queryByText('common.toolsPage.description')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ vi.mock('@/context/app-context', () => ({
|
||||
// Mock useLocale and useDocLink
|
||||
vi.mock('@/context/i18n', () => ({
|
||||
useLocale: () => 'en-US',
|
||||
useDocLink: () => (path: string) => `https://docs.dify.ai/en/${path?.startsWith('/') ? path.slice(1) : path}`,
|
||||
useDocLink: () => (path?: string) => `https://docs.dify.ai/en${path?.startsWith('/use-dify/') ? `/cloud${path}` : path || ''}`,
|
||||
}))
|
||||
|
||||
// Mock getLanguage
|
||||
@ -132,7 +132,7 @@ describe('CustomCreateCard', () => {
|
||||
render(<CustomCreateCard onRefreshData={mockOnRefreshData} />)
|
||||
|
||||
const docLink = screen.getByText('tools.swaggerAPIAsToolTip').closest('a')
|
||||
expect(docLink).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/tools#custom-tool')
|
||||
expect(docLink).toHaveAttribute('href', 'https://docs.dify.ai/en/cloud/use-dify/workspace/tools#custom-tool')
|
||||
expect(docLink).toHaveAttribute('target', '_blank')
|
||||
expect(docLink).toHaveAttribute('rel', 'noopener noreferrer')
|
||||
})
|
||||
|
||||
@ -84,7 +84,7 @@ describe('Empty', () => {
|
||||
|
||||
expect(screen.getByRole('link', { name: /tools\.workflowToolEmpty\.goToStudio/i })).toHaveAttribute('href', '/apps')
|
||||
expect(screen.getByRole('link', { name: /tools\.workflowToolEmpty\.learnMore/i })).toHaveAttribute('target', '_blank')
|
||||
expect(screen.getByRole('link', { name: /tools\.workflowToolEmpty\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/tools#workflow-tool')
|
||||
expect(screen.getByRole('link', { name: /tools\.workflowToolEmpty\.learnMore/i })).toHaveAttribute('href', 'https://docs.dify.ai/en/self-host/use-dify/workspace/tools#workflow-tool')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -54,6 +54,18 @@ describe('useAvailableNodesMetaData', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should use explicit docs pages and skip nodes without generated docs pages', () => {
|
||||
mockUseIsChatMode.mockReturnValue(false)
|
||||
|
||||
const { result } = renderHook(() => useAvailableNodesMetaData())
|
||||
|
||||
expect(result.current.nodesMap?.[BlockEnum.End]?.metaData.helpLinkUri).toBe('/docs/use-dify/nodes/output')
|
||||
expect(result.current.nodesMap?.[BlockEnum.IterationStart]?.metaData.helpLinkUri).toBeUndefined()
|
||||
expect(result.current.nodesMap?.[BlockEnum.LoopStart]?.metaData.helpLinkUri).toBeUndefined()
|
||||
expect(result.current.nodesMap?.[BlockEnum.LoopEnd]?.metaData.helpLinkUri).toBeUndefined()
|
||||
expect(result.current.nodesMap?.[BlockEnum.Start]?.metaData.helpLinkUri).toBe('/docs/use-dify/nodes/user-input')
|
||||
})
|
||||
|
||||
it('should expose Agent v2 instead of legacy Agent when Agent v2 is enabled', () => {
|
||||
mockUseIsChatMode.mockReturnValue(false)
|
||||
|
||||
|
||||
@ -14,8 +14,20 @@ import TriggerWebhookDefault from '@/app/components/workflow/nodes/trigger-webho
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { useDocLink } from '@/context/i18n'
|
||||
import { isAgentV2Enabled } from '@/features/agent-v2/feature-flag'
|
||||
import { docPathProductAvailability } from '@/types/doc-paths'
|
||||
import { useIsChatMode } from './use-is-chat-mode'
|
||||
|
||||
const getNodeHelpLinkPath = (helpLinkUri?: string): DocPathWithoutLang | undefined => {
|
||||
if (!helpLinkUri)
|
||||
return undefined
|
||||
|
||||
const helpLinkPath = `/use-dify/nodes/${helpLinkUri}`
|
||||
if (!docPathProductAvailability[helpLinkPath])
|
||||
return undefined
|
||||
|
||||
return helpLinkPath as DocPathWithoutLang
|
||||
}
|
||||
|
||||
export const useAvailableNodesMetaData = () => {
|
||||
const { t } = useTranslation()
|
||||
const isChatMode = useIsChatMode()
|
||||
@ -57,14 +69,14 @@ export const useAvailableNodesMetaData = () => {
|
||||
const { metaData } = node
|
||||
const title = t(`blocks.${metaData.type}`, { ns: 'workflow' })
|
||||
const description = t(`blocksAbout.${metaData.type}` as I18nKeysWithPrefix<'workflow', 'blocksAbout.'>, { ns: 'workflow' })
|
||||
const helpLinkPath = `/use-dify/nodes/${metaData.helpLinkUri}` as DocPathWithoutLang
|
||||
const helpLinkPath = getNodeHelpLinkPath(metaData.helpLinkUri)
|
||||
return {
|
||||
...node,
|
||||
metaData: {
|
||||
...metaData,
|
||||
title,
|
||||
description,
|
||||
helpLinkUri: docLink(helpLinkPath),
|
||||
helpLinkUri: helpLinkPath ? docLink(helpLinkPath) : undefined,
|
||||
},
|
||||
defaultValue: {
|
||||
...node.defaultValue,
|
||||
|
||||
@ -318,7 +318,7 @@ describe('NodeSelector', () => {
|
||||
expect(await screen.findByText('workflow.tabs.unconfiguredStartDisabledTip')).toBeInTheDocument()
|
||||
expect(screen.getByRole('link', { name: 'workflow.tabs.startDisabledTipLearnMore' })).toHaveAttribute(
|
||||
'href',
|
||||
'https://docs.dify.ai/en/use-dify/nodes/trigger/overview',
|
||||
'https://docs.dify.ai/en/self-host/use-dify/nodes/trigger/overview',
|
||||
)
|
||||
expect(screen.getByPlaceholderText('workflow.tabs.searchBlock')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
@ -6,6 +6,7 @@ import { genNodeMetaData } from '@/app/components/workflow/utils'
|
||||
const metaData = genNodeMetaData({
|
||||
sort: 2.1,
|
||||
type: BlockEnum.End,
|
||||
helpLinkUri: 'output',
|
||||
isRequired: false,
|
||||
})
|
||||
const nodeDefault: NodeDefault<EndNodeType> = {
|
||||
|
||||
@ -5,6 +5,10 @@ import { useTranslation } from '#i18n'
|
||||
import { getDocLanguage } from '@/i18n-config/language'
|
||||
import { defaultDocBaseUrl, useDocLink } from './i18n'
|
||||
|
||||
const mockConfig = vi.hoisted(() => ({
|
||||
IS_CLOUD_EDITION: true,
|
||||
}))
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock('#i18n', () => ({
|
||||
useTranslation: vi.fn(() => ({
|
||||
@ -12,6 +16,12 @@ vi.mock('#i18n', () => ({
|
||||
})),
|
||||
}))
|
||||
|
||||
vi.mock('@/config', () => ({
|
||||
get IS_CLOUD_EDITION() {
|
||||
return mockConfig.IS_CLOUD_EDITION
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/i18n-config/language', () => ({
|
||||
getDocLanguage: vi.fn((locale: string) => {
|
||||
const map: Record<string, string> = {
|
||||
@ -28,6 +38,7 @@ vi.mock('@/i18n-config/language', () => ({
|
||||
describe('useDocLink', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockConfig.IS_CLOUD_EDITION = true
|
||||
vi.mocked(useTranslation).mockReturnValue({
|
||||
i18n: { language: 'en-US' },
|
||||
} as ReturnType<typeof useTranslation>)
|
||||
@ -45,28 +56,28 @@ describe('useDocLink', () => {
|
||||
it('should use default base URL when no baseUrl provided', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current()
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en`)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/home`)
|
||||
})
|
||||
|
||||
it('should use custom base URL when provided', () => {
|
||||
const customBaseUrl = 'https://custom.docs.com'
|
||||
const { result } = renderHook(() => useDocLink(customBaseUrl))
|
||||
const url = result.current()
|
||||
expect(url).toBe(`${customBaseUrl}/en`)
|
||||
expect(url).toBe(`${customBaseUrl}/en/home`)
|
||||
})
|
||||
|
||||
it('should remove trailing slash from base URL', () => {
|
||||
const baseUrlWithSlash = 'https://docs.dify.ai/'
|
||||
const { result } = renderHook(() => useDocLink(baseUrlWithSlash))
|
||||
const url = result.current('/use-dify/getting-started/introduction')
|
||||
expect(url).toBe('https://docs.dify.ai/en/use-dify/getting-started/introduction')
|
||||
expect(url).toBe('https://docs.dify.ai/en/cloud/use-dify/getting-started/introduction')
|
||||
})
|
||||
|
||||
it('should handle base URL without trailing slash', () => {
|
||||
const baseUrlWithoutSlash = 'https://docs.dify.ai'
|
||||
const { result } = renderHook(() => useDocLink(baseUrlWithoutSlash))
|
||||
const url = result.current('/use-dify/getting-started/introduction')
|
||||
expect(url).toBe('https://docs.dify.ai/en/use-dify/getting-started/introduction')
|
||||
expect(url).toBe('https://docs.dify.ai/en/cloud/use-dify/getting-started/introduction')
|
||||
})
|
||||
})
|
||||
|
||||
@ -74,19 +85,31 @@ describe('useDocLink', () => {
|
||||
it('should handle path parameter', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/getting-started/introduction')
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/use-dify/getting-started/introduction`)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/getting-started/introduction`)
|
||||
})
|
||||
|
||||
it('should handle empty path', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current()
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en`)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/home`)
|
||||
})
|
||||
|
||||
it('should handle undefined path', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current(undefined)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en`)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/home`)
|
||||
})
|
||||
|
||||
it('should keep common docs path without product prefix', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/learn/key-concepts' as DocPathWithoutLang)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/learn/key-concepts`)
|
||||
})
|
||||
|
||||
it('should keep explicit product docs path without adding another product prefix', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/cloud/use-dify/build/mcp' as DocPathWithoutLang)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/build/mcp`)
|
||||
})
|
||||
})
|
||||
|
||||
@ -99,12 +122,12 @@ describe('useDocLink', () => {
|
||||
|
||||
const pathMap: DocPathMap = {
|
||||
'zh-Hans': '/use-dify/getting-started/introduction',
|
||||
'en-US': '/use-dify/getting-started/quick-start',
|
||||
'en-US': '/use-dify/build/mcp',
|
||||
}
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/getting-started/quick-start' as DocPathWithoutLang, pathMap)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/zh/use-dify/getting-started/introduction`)
|
||||
const url = result.current('/use-dify/build/mcp', pathMap)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/zh/cloud/use-dify/getting-started/introduction`)
|
||||
})
|
||||
|
||||
it('should use default path when locale not in pathMap', () => {
|
||||
@ -115,18 +138,76 @@ describe('useDocLink', () => {
|
||||
|
||||
const pathMap: DocPathMap = {
|
||||
'zh-Hans': '/use-dify/getting-started/introduction',
|
||||
'en-US': '/use-dify/getting-started/quick-start',
|
||||
'en-US': '/use-dify/build/mcp',
|
||||
}
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/getting-started/quick-start' as DocPathWithoutLang, pathMap)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/ja/use-dify/getting-started/quick-start`)
|
||||
const url = result.current('/use-dify/build/mcp', pathMap)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/ja/cloud/use-dify/build/mcp`)
|
||||
})
|
||||
|
||||
it('should handle undefined pathMap', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/getting-started/introduction', undefined)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/use-dify/getting-started/introduction`)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/getting-started/introduction`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Product prefix handling', () => {
|
||||
it('should add cloud product prefix for product docs available in both editions', () => {
|
||||
mockConfig.IS_CLOUD_EDITION = true
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/build/mcp')
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/build/mcp`)
|
||||
})
|
||||
|
||||
it('should add self-host product prefix for product docs available in both editions outside cloud edition', () => {
|
||||
mockConfig.IS_CLOUD_EDITION = false
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/build/mcp')
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/self-host/use-dify/build/mcp`)
|
||||
})
|
||||
|
||||
it('should use the existing cloud docs path for cloud-only product docs outside cloud edition', () => {
|
||||
mockConfig.IS_CLOUD_EDITION = false
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/workspace/subscription-management#dify-for-education')
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/workspace/subscription-management#dify-for-education`)
|
||||
})
|
||||
|
||||
it('should use the existing self-host docs path for self-host-only product docs in cloud edition', () => {
|
||||
mockConfig.IS_CLOUD_EDITION = true
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/deploy/overview')
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/self-host/deploy/overview`)
|
||||
})
|
||||
|
||||
it('should not add a product prefix for unknown productless paths', () => {
|
||||
mockConfig.IS_CLOUD_EDITION = false
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/unknown-page' as DocPathWithoutLang)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/use-dify/unknown-page`)
|
||||
})
|
||||
|
||||
it('should open shared docs home when no path is provided outside cloud edition', () => {
|
||||
mockConfig.IS_CLOUD_EDITION = false
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current()
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/home`)
|
||||
})
|
||||
|
||||
it('should keep self-host deploy paths without adding use-dify product prefix', () => {
|
||||
mockConfig.IS_CLOUD_EDITION = true
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/self-host/deploy/overview' as DocPathWithoutLang)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/self-host/deploy/overview`)
|
||||
})
|
||||
})
|
||||
|
||||
@ -232,7 +313,7 @@ describe('useDocLink', () => {
|
||||
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/getting-started/introduction')
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/zh/use-dify/getting-started/introduction`)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/zh/cloud/use-dify/getting-started/introduction`)
|
||||
})
|
||||
})
|
||||
|
||||
@ -240,15 +321,15 @@ describe('useDocLink', () => {
|
||||
it('should handle path with anchor', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url = result.current('/use-dify/getting-started/introduction#overview' as DocPathWithoutLang)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/use-dify/getting-started/introduction#overview`)
|
||||
expect(url).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/getting-started/introduction#overview`)
|
||||
})
|
||||
|
||||
it('should handle multiple calls with same hook instance', () => {
|
||||
const { result } = renderHook(() => useDocLink())
|
||||
const url1 = result.current('/use-dify/getting-started/introduction')
|
||||
const url2 = result.current('/use-dify/getting-started/quick-start')
|
||||
expect(url1).toBe(`${defaultDocBaseUrl}/en/use-dify/getting-started/introduction`)
|
||||
expect(url2).toBe(`${defaultDocBaseUrl}/en/use-dify/getting-started/quick-start`)
|
||||
const url2 = result.current('/use-dify/build/mcp')
|
||||
expect(url1).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/getting-started/introduction`)
|
||||
expect(url2).toBe(`${defaultDocBaseUrl}/en/cloud/use-dify/build/mcp`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import type { Locale } from '@/i18n-config/language'
|
||||
import type { DocPathWithoutLang } from '@/types/doc-paths'
|
||||
import type { DocPathWithoutLang, DocsProduct } from '@/types/doc-paths'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from '#i18n'
|
||||
import { IS_CLOUD_EDITION } from '@/config'
|
||||
import { getDocLanguage, getLanguage, getPricingPageLanguage } from '@/i18n-config/language'
|
||||
import { apiReferencePathTranslations } from '@/types/doc-paths'
|
||||
import { apiReferencePathTranslations, docPathProductAvailability } from '@/types/doc-paths'
|
||||
|
||||
export const useLocale = () => {
|
||||
const { i18n } = useTranslation()
|
||||
@ -24,6 +25,44 @@ export const useGetPricingPageLanguage = () => {
|
||||
export const defaultDocBaseUrl = 'https://docs.dify.ai'
|
||||
export type DocPathMap = Partial<Record<Locale, DocPathWithoutLang>>
|
||||
|
||||
export const getDocHomePath = () => '/home'
|
||||
|
||||
const getCurrentDocsProduct = (): DocsProduct => {
|
||||
return IS_CLOUD_EDITION ? 'cloud' : 'self-host'
|
||||
}
|
||||
|
||||
const splitPathHash = (path: string) => {
|
||||
const hashIndex = path.indexOf('#')
|
||||
if (hashIndex === -1) {
|
||||
return {
|
||||
pathname: path,
|
||||
hash: '',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
pathname: path.slice(0, hashIndex),
|
||||
hash: path.slice(hashIndex),
|
||||
}
|
||||
}
|
||||
|
||||
const getProductAwarePath = (path: string): string => {
|
||||
const { pathname, hash } = splitPathHash(path)
|
||||
const availableProducts = docPathProductAvailability[pathname]
|
||||
if (!availableProducts?.length)
|
||||
return path
|
||||
|
||||
const currentProduct = getCurrentDocsProduct()
|
||||
const targetProduct = availableProducts.includes(currentProduct)
|
||||
? currentProduct
|
||||
: availableProducts[0]
|
||||
|
||||
if (!targetProduct)
|
||||
return path
|
||||
|
||||
return `/${targetProduct}${pathname}${hash}`
|
||||
}
|
||||
|
||||
export const useDocLink = (baseUrl?: string): ((path?: DocPathWithoutLang, pathMap?: DocPathMap) => string) => {
|
||||
let baseDocUrl = baseUrl || defaultDocBaseUrl
|
||||
baseDocUrl = (baseDocUrl.endsWith('/')) ? baseDocUrl.slice(0, -1) : baseDocUrl
|
||||
@ -44,6 +83,12 @@ export const useDocLink = (baseUrl?: string): ((path?: DocPathWithoutLang, pathM
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!targetPath) {
|
||||
targetPath = getDocHomePath()
|
||||
}
|
||||
else {
|
||||
targetPath = getProductAwarePath(targetPath)
|
||||
}
|
||||
|
||||
return `${baseDocUrl}${languagePrefix}${targetPath}`
|
||||
},
|
||||
|
||||
@ -84,7 +84,7 @@ export function AgentAccessPage({
|
||||
<p className="mt-1 flex min-w-0 flex-wrap items-center gap-x-0.5 system-xs-regular text-text-tertiary">
|
||||
<span>{t('agentDetail.access.description')}</span>
|
||||
<a
|
||||
href={docLink('/use-dify/publish/webapp/web-app-access')}
|
||||
href={docLink('/use-dify/publish/webapp/web-app-settings')}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="inline-flex shrink-0 items-center gap-0.5 rounded-sm text-text-accent hover:underline focus-visible:ring-2 focus-visible:ring-state-accent-solid focus-visible:outline-hidden"
|
||||
|
||||
@ -11,7 +11,8 @@ import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const DOCS_JSON_URL = 'https://raw.githubusercontent.com/langgenius/dify-docs/refs/heads/main/docs.json'
|
||||
const DEFAULT_DOCS_JSON_URL = 'https://raw.githubusercontent.com/langgenius/dify-docs/refs/heads/main/docs.json'
|
||||
const DOCS_JSON_URL = process.env.DOCS_JSON_URL || DEFAULT_DOCS_JSON_URL
|
||||
const OUTPUT_PATH = path.resolve(__dirname, '../types/doc-paths.ts')
|
||||
|
||||
type NavItem = string | NavObject | NavItem[]
|
||||
@ -21,6 +22,9 @@ type NavObject = {
|
||||
groups?: NavItem[]
|
||||
dropdowns?: NavItem[]
|
||||
languages?: NavItem[]
|
||||
products?: NavItem[]
|
||||
tabs?: NavItem[]
|
||||
menu?: NavItem[]
|
||||
versions?: NavItem[]
|
||||
openapi?: string
|
||||
[key: string]: unknown
|
||||
@ -58,7 +62,15 @@ type DocsJson = {
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
const OPENAPI_BASE_URL = 'https://raw.githubusercontent.com/langgenius/dify-docs/refs/heads/main/'
|
||||
const OPENAPI_BASE_URL = (process.env.DOCS_OPENAPI_BASE_URL || new URL('.', DOCS_JSON_URL).toString()).replace(/\/?$/, '/')
|
||||
const DOCS_PRODUCTS = ['cloud', 'self-host'] as const
|
||||
|
||||
type DocsProduct = typeof DOCS_PRODUCTS[number]
|
||||
type ProductAvailability = Record<string, Set<DocsProduct>>
|
||||
|
||||
function isDocsProduct(segment: string): segment is DocsProduct {
|
||||
return DOCS_PRODUCTS.includes(segment as DocsProduct)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert summary to URL slug
|
||||
@ -112,6 +124,15 @@ function extractOpenAPIPaths(item: NavItem | undefined, paths: Set<string> = new
|
||||
if (item.languages)
|
||||
extractOpenAPIPaths(item.languages, paths)
|
||||
|
||||
if (item.products)
|
||||
extractOpenAPIPaths(item.products, paths)
|
||||
|
||||
if (item.tabs)
|
||||
extractOpenAPIPaths(item.tabs, paths)
|
||||
|
||||
if (item.menu)
|
||||
extractOpenAPIPaths(item.menu, paths)
|
||||
|
||||
if (item.versions)
|
||||
extractOpenAPIPaths(item.versions, paths)
|
||||
}
|
||||
@ -199,6 +220,15 @@ function extractPaths(item: NavItem | undefined, paths: Set<string> = new Set())
|
||||
if (item.languages)
|
||||
extractPaths(item.languages, paths)
|
||||
|
||||
if (item.products)
|
||||
extractPaths(item.products, paths)
|
||||
|
||||
if (item.tabs)
|
||||
extractPaths(item.tabs, paths)
|
||||
|
||||
if (item.menu)
|
||||
extractPaths(item.menu, paths)
|
||||
|
||||
// Handle versions in navigation
|
||||
if (item.versions)
|
||||
extractPaths(item.versions, paths)
|
||||
@ -207,33 +237,68 @@ function extractPaths(item: NavItem | undefined, paths: Set<string> = new Set())
|
||||
return paths
|
||||
}
|
||||
|
||||
function addPathToGroup(groups: Record<string, Set<string>>, pathWithoutLang: string): void {
|
||||
const parts = pathWithoutLang.split('/')
|
||||
const section = parts[0]
|
||||
if (!section)
|
||||
return
|
||||
|
||||
if (!groups[section])
|
||||
groups[section] = new Set()
|
||||
|
||||
groups[section]!.add(pathWithoutLang)
|
||||
}
|
||||
|
||||
function getProductPathInfo(pathWithoutLang: string): { product: DocsProduct, pathWithoutProduct: string } | undefined {
|
||||
const parts = pathWithoutLang.split('/')
|
||||
const [product, ...rest] = parts
|
||||
|
||||
if (!product || !isDocsProduct(product) || rest.length === 0)
|
||||
return undefined
|
||||
|
||||
return {
|
||||
product,
|
||||
pathWithoutProduct: rest.join('/'),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Group paths by their prefix structure
|
||||
*/
|
||||
function groupPathsBySection(paths: Set<string>): Record<string, Set<string>> {
|
||||
function groupPathsBySection(paths: Set<string>): { groups: Record<string, Set<string>>, productAvailability: ProductAvailability } {
|
||||
const groups: Record<string, Set<string>> = {}
|
||||
const productAvailability: ProductAvailability = {}
|
||||
|
||||
for (const fullPath of paths) {
|
||||
// Skip non-doc paths (like .json files for OpenAPI)
|
||||
if (fullPath.endsWith('.json'))
|
||||
continue
|
||||
|
||||
// Remove language prefix (en/, zh/, ja/)
|
||||
const withoutLang = fullPath.replace(/^(en|zh|ja)\//, '')
|
||||
if (!withoutLang || withoutLang === fullPath)
|
||||
continue
|
||||
|
||||
// Get section (first part of path)
|
||||
const parts = withoutLang.split('/')
|
||||
const section = parts[0]
|
||||
// Skip non-doc paths (like .json files for OpenAPI)
|
||||
if (withoutLang.endsWith('.json') || withoutLang === 'None')
|
||||
continue
|
||||
|
||||
if (!groups[section!])
|
||||
groups[section!] = new Set()
|
||||
addPathToGroup(groups, withoutLang)
|
||||
|
||||
groups[section!]!.add(withoutLang)
|
||||
const productPathInfo = getProductPathInfo(withoutLang)
|
||||
if (productPathInfo) {
|
||||
const productlessPath = productPathInfo.pathWithoutProduct
|
||||
const normalizedPath = `/${productlessPath}`
|
||||
|
||||
addPathToGroup(groups, productlessPath)
|
||||
|
||||
if (!productAvailability[normalizedPath])
|
||||
productAvailability[normalizedPath] = new Set()
|
||||
|
||||
productAvailability[normalizedPath]!.add(productPathInfo.product)
|
||||
}
|
||||
}
|
||||
|
||||
return groups
|
||||
return {
|
||||
groups,
|
||||
productAvailability,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,6 +316,7 @@ function sectionToTypeName(section: string): string {
|
||||
*/
|
||||
function generateTypeDefinitions(
|
||||
groups: Record<string, Set<string>>,
|
||||
productAvailability: ProductAvailability,
|
||||
apiReferencePaths: string[],
|
||||
apiPathTranslations: Record<string, { zh?: string, ja?: string }>,
|
||||
): string {
|
||||
@ -258,11 +324,12 @@ function generateTypeDefinitions(
|
||||
'// GENERATE BY script',
|
||||
'// DON NOT EDIT IT MANUALLY',
|
||||
'//',
|
||||
'// Generated from: https://raw.githubusercontent.com/langgenius/dify-docs/refs/heads/main/docs.json',
|
||||
`// Generated from: ${DOCS_JSON_URL}`,
|
||||
`// Generated at: ${new Date().toISOString()}`,
|
||||
'',
|
||||
'// Language prefixes',
|
||||
'export type DocLanguage = \'en\' | \'zh\' | \'ja\'',
|
||||
'export type DocsProduct = \'cloud\' | \'self-host\'',
|
||||
'',
|
||||
]
|
||||
|
||||
@ -321,10 +388,14 @@ function generateTypeDefinitions(
|
||||
lines.push(' | `${DocPathWithoutLangBase}#${string}`')
|
||||
lines.push('')
|
||||
|
||||
// Generate full path type with language prefix
|
||||
lines.push('// Full documentation path with language prefix')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
lines.push('export type DifyDocPath = `${DocLanguage}/${DocPathWithoutLang}`')
|
||||
// Generate product availability map for productless runtime links.
|
||||
lines.push('// Product availability for productless docs paths')
|
||||
lines.push('export const docPathProductAvailability: Record<string, readonly DocsProduct[]> = {')
|
||||
for (const path of Object.keys(productAvailability).sort()) {
|
||||
const products = [...productAvailability[path]!].sort((a, b) => DOCS_PRODUCTS.indexOf(a) - DOCS_PRODUCTS.indexOf(b))
|
||||
lines.push(` '${path}': [${products.map(product => `'${product}'`).join(', ')}],`)
|
||||
}
|
||||
lines.push('}')
|
||||
lines.push('')
|
||||
|
||||
// Generate API reference path translations map
|
||||
@ -423,12 +494,13 @@ async function main(): Promise<void> {
|
||||
console.log(`Generated ${Object.keys(apiPathTranslations).length} API path translations`)
|
||||
|
||||
// Group by section
|
||||
const groups = groupPathsBySection(allPaths)
|
||||
const { groups, productAvailability } = groupPathsBySection(allPaths)
|
||||
|
||||
console.log(`Grouped into ${Object.keys(groups).length} sections:`, Object.keys(groups))
|
||||
console.log(`Found ${Object.keys(productAvailability).length} product-aware paths`)
|
||||
|
||||
// Generate TypeScript
|
||||
const tsContent = generateTypeDefinitions(groups, uniqueEnApiPaths, apiPathTranslations)
|
||||
const tsContent = generateTypeDefinitions(groups, productAvailability, uniqueEnApiPaths, apiPathTranslations)
|
||||
|
||||
// Write to file
|
||||
await writeFile(OUTPUT_PATH, tsContent, 'utf-8')
|
||||
|
||||
@ -1,28 +1,127 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
//
|
||||
// Generated from: https://raw.githubusercontent.com/langgenius/dify-docs/refs/heads/main/docs.json
|
||||
// Generated at: 2026-03-25T03:18:49.626Z
|
||||
// Generated from: https://raw.githubusercontent.com/langgenius/dify-docs/feat/audience-products/docs.json
|
||||
// Generated at: 2026-06-17T04:42:51.293Z
|
||||
|
||||
// Language prefixes
|
||||
export type DocLanguage = 'en' | 'zh' | 'ja'
|
||||
export type DocsProduct = 'cloud' | 'self-host'
|
||||
|
||||
// Cloud paths
|
||||
type CloudPath =
|
||||
| '/cloud/use-dify/build/additional-features'
|
||||
| '/cloud/use-dify/build/agent'
|
||||
| '/cloud/use-dify/build/chatbot'
|
||||
| '/cloud/use-dify/build/mcp'
|
||||
| '/cloud/use-dify/build/orchestrate-node'
|
||||
| '/cloud/use-dify/build/predefined-error-handling-logic'
|
||||
| '/cloud/use-dify/build/shortcut-key'
|
||||
| '/cloud/use-dify/build/text-generator'
|
||||
| '/cloud/use-dify/build/version-control'
|
||||
| '/cloud/use-dify/build/workflow-chatflow'
|
||||
| '/cloud/use-dify/build/workflow-collaboration'
|
||||
| '/cloud/use-dify/debug/error-type'
|
||||
| '/cloud/use-dify/debug/history-and-logs'
|
||||
| '/cloud/use-dify/debug/step-run'
|
||||
| '/cloud/use-dify/debug/variable-inspect'
|
||||
| '/cloud/use-dify/getting-started/introduction'
|
||||
| '/cloud/use-dify/knowledge/connect-external-knowledge-base'
|
||||
| '/cloud/use-dify/knowledge/create-knowledge/chunking-and-cleaning-text'
|
||||
| '/cloud/use-dify/knowledge/create-knowledge/import-text-data/readme'
|
||||
| '/cloud/use-dify/knowledge/create-knowledge/import-text-data/sync-from-notion'
|
||||
| '/cloud/use-dify/knowledge/create-knowledge/import-text-data/sync-from-website'
|
||||
| '/cloud/use-dify/knowledge/create-knowledge/introduction'
|
||||
| '/cloud/use-dify/knowledge/create-knowledge/setting-indexing-methods'
|
||||
| '/cloud/use-dify/knowledge/external-knowledge-api'
|
||||
| '/cloud/use-dify/knowledge/integrate-knowledge-within-application'
|
||||
| '/cloud/use-dify/knowledge/knowledge-pipeline/authorize-data-source'
|
||||
| '/cloud/use-dify/knowledge/knowledge-pipeline/create-knowledge-pipeline'
|
||||
| '/cloud/use-dify/knowledge/knowledge-pipeline/knowledge-pipeline-orchestration'
|
||||
| '/cloud/use-dify/knowledge/knowledge-pipeline/manage-knowledge-base'
|
||||
| '/cloud/use-dify/knowledge/knowledge-pipeline/publish-knowledge-pipeline'
|
||||
| '/cloud/use-dify/knowledge/knowledge-pipeline/readme'
|
||||
| '/cloud/use-dify/knowledge/knowledge-pipeline/upload-files'
|
||||
| '/cloud/use-dify/knowledge/knowledge-request-rate-limit'
|
||||
| '/cloud/use-dify/knowledge/manage-knowledge/introduction'
|
||||
| '/cloud/use-dify/knowledge/manage-knowledge/maintain-dataset-via-api'
|
||||
| '/cloud/use-dify/knowledge/manage-knowledge/maintain-knowledge-documents'
|
||||
| '/cloud/use-dify/knowledge/metadata'
|
||||
| '/cloud/use-dify/knowledge/readme'
|
||||
| '/cloud/use-dify/knowledge/test-retrieval'
|
||||
| '/cloud/use-dify/monitor/analysis'
|
||||
| '/cloud/use-dify/monitor/annotation-reply'
|
||||
| '/cloud/use-dify/monitor/integrations/integrate-aliyun'
|
||||
| '/cloud/use-dify/monitor/integrations/integrate-arize'
|
||||
| '/cloud/use-dify/monitor/integrations/integrate-langfuse'
|
||||
| '/cloud/use-dify/monitor/integrations/integrate-langsmith'
|
||||
| '/cloud/use-dify/monitor/integrations/integrate-opik'
|
||||
| '/cloud/use-dify/monitor/integrations/integrate-phoenix'
|
||||
| '/cloud/use-dify/monitor/integrations/integrate-weave'
|
||||
| '/cloud/use-dify/monitor/logs'
|
||||
| '/cloud/use-dify/nodes/agent'
|
||||
| '/cloud/use-dify/nodes/answer'
|
||||
| '/cloud/use-dify/nodes/code'
|
||||
| '/cloud/use-dify/nodes/doc-extractor'
|
||||
| '/cloud/use-dify/nodes/http-request'
|
||||
| '/cloud/use-dify/nodes/human-input'
|
||||
| '/cloud/use-dify/nodes/ifelse'
|
||||
| '/cloud/use-dify/nodes/iteration'
|
||||
| '/cloud/use-dify/nodes/knowledge-retrieval'
|
||||
| '/cloud/use-dify/nodes/list-operator'
|
||||
| '/cloud/use-dify/nodes/llm'
|
||||
| '/cloud/use-dify/nodes/loop'
|
||||
| '/cloud/use-dify/nodes/output'
|
||||
| '/cloud/use-dify/nodes/parameter-extractor'
|
||||
| '/cloud/use-dify/nodes/question-classifier'
|
||||
| '/cloud/use-dify/nodes/template'
|
||||
| '/cloud/use-dify/nodes/tools'
|
||||
| '/cloud/use-dify/nodes/trigger/overview'
|
||||
| '/cloud/use-dify/nodes/trigger/plugin-trigger'
|
||||
| '/cloud/use-dify/nodes/trigger/schedule-trigger'
|
||||
| '/cloud/use-dify/nodes/trigger/webhook-trigger'
|
||||
| '/cloud/use-dify/nodes/user-input'
|
||||
| '/cloud/use-dify/nodes/variable-aggregator'
|
||||
| '/cloud/use-dify/nodes/variable-assigner'
|
||||
| '/cloud/use-dify/publish/README'
|
||||
| '/cloud/use-dify/publish/developing-with-apis'
|
||||
| '/cloud/use-dify/publish/publish-mcp'
|
||||
| '/cloud/use-dify/publish/publish-to-marketplace'
|
||||
| '/cloud/use-dify/publish/webapp/chatflow-webapp'
|
||||
| '/cloud/use-dify/publish/webapp/embedding-in-websites'
|
||||
| '/cloud/use-dify/publish/webapp/web-app-settings'
|
||||
| '/cloud/use-dify/publish/webapp/workflow-webapp'
|
||||
| '/cloud/use-dify/workspace/api-extension/api-extension'
|
||||
| '/cloud/use-dify/workspace/api-extension/cloudflare-worker'
|
||||
| '/cloud/use-dify/workspace/api-extension/external-data-tool-api-extension'
|
||||
| '/cloud/use-dify/workspace/api-extension/moderation-api-extension'
|
||||
| '/cloud/use-dify/workspace/app-management'
|
||||
| '/cloud/use-dify/workspace/model-providers'
|
||||
| '/cloud/use-dify/workspace/personal-account-management'
|
||||
| '/cloud/use-dify/workspace/plugins'
|
||||
| '/cloud/use-dify/workspace/readme'
|
||||
| '/cloud/use-dify/workspace/subscription-management'
|
||||
| '/cloud/use-dify/workspace/team-members-management'
|
||||
| '/cloud/use-dify/workspace/tools'
|
||||
|
||||
// UseDify paths
|
||||
type UseDifyPath =
|
||||
| '/use-dify/build/additional-features'
|
||||
| '/use-dify/build/goto-anything'
|
||||
| '/use-dify/build/agent'
|
||||
| '/use-dify/build/chatbot'
|
||||
| '/use-dify/build/mcp'
|
||||
| '/use-dify/build/orchestrate-node'
|
||||
| '/use-dify/build/predefined-error-handling-logic'
|
||||
| '/use-dify/build/shortcut-key'
|
||||
| '/use-dify/build/text-generator'
|
||||
| '/use-dify/build/version-control'
|
||||
| '/use-dify/build/workflow-chatflow'
|
||||
| '/use-dify/build/workflow-collaboration'
|
||||
| '/use-dify/debug/error-type'
|
||||
| '/use-dify/debug/history-and-logs'
|
||||
| '/use-dify/debug/step-run'
|
||||
| '/use-dify/debug/variable-inspect'
|
||||
| '/use-dify/getting-started/introduction'
|
||||
| '/use-dify/getting-started/key-concepts'
|
||||
| '/use-dify/getting-started/quick-start'
|
||||
| '/use-dify/knowledge/connect-external-knowledge-base'
|
||||
| '/use-dify/knowledge/create-knowledge/chunking-and-cleaning-text'
|
||||
| '/use-dify/knowledge/create-knowledge/import-text-data/readme'
|
||||
@ -86,24 +185,8 @@ type UseDifyPath =
|
||||
| '/use-dify/publish/publish-to-marketplace'
|
||||
| '/use-dify/publish/webapp/chatflow-webapp'
|
||||
| '/use-dify/publish/webapp/embedding-in-websites'
|
||||
| '/use-dify/publish/webapp/web-app-access'
|
||||
| '/use-dify/publish/webapp/web-app-settings'
|
||||
| '/use-dify/publish/webapp/workflow-webapp'
|
||||
| '/use-dify/tutorials/article-reader'
|
||||
| '/use-dify/tutorials/build-ai-image-generation-app'
|
||||
| '/use-dify/tutorials/customer-service-bot'
|
||||
| '/use-dify/tutorials/simple-chatbot'
|
||||
| '/use-dify/tutorials/twitter-chatflow'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-01'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-02'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-03'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-04'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-05'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-06'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-07'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-08'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-09'
|
||||
| '/use-dify/tutorials/workflow-101/lesson-10'
|
||||
| '/use-dify/workspace/api-extension/api-extension'
|
||||
| '/use-dify/workspace/api-extension/cloudflare-worker'
|
||||
| '/use-dify/workspace/api-extension/external-data-tool-api-extension'
|
||||
@ -115,25 +198,42 @@ type UseDifyPath =
|
||||
| '/use-dify/workspace/readme'
|
||||
| '/use-dify/workspace/subscription-management'
|
||||
| '/use-dify/workspace/team-members-management'
|
||||
| '/use-dify/workspace/tools'
|
||||
|
||||
// UseDify node paths (without prefix)
|
||||
type ExtractNodesPath<T> = T extends `/use-dify/nodes/${infer Path}` ? Path : never
|
||||
export type UseDifyNodesPath = ExtractNodesPath<UseDifyPath>
|
||||
|
||||
// SelfHost paths
|
||||
type SelfHostPath =
|
||||
| '/self-host/advanced-deployments/local-source-code'
|
||||
| '/self-host/advanced-deployments/start-the-frontend-docker-container'
|
||||
| '/self-host/configuration/environments'
|
||||
| '/self-host/platform-guides/bt-panel'
|
||||
| '/self-host/platform-guides/dify-premium'
|
||||
| '/self-host/quick-start/docker-compose'
|
||||
| '/self-host/quick-start/faqs'
|
||||
| '/self-host/troubleshooting/common-issues'
|
||||
| '/self-host/troubleshooting/docker-issues'
|
||||
| '/self-host/troubleshooting/integrations'
|
||||
| '/self-host/troubleshooting/storage-and-migration'
|
||||
| '/self-host/troubleshooting/weaviate-v4-migration'
|
||||
// Home paths
|
||||
type HomePath =
|
||||
| '/home'
|
||||
|
||||
// Learn paths
|
||||
type LearnPath =
|
||||
| '/learn/key-concepts'
|
||||
| '/learn/tutorials/article-reader'
|
||||
| '/learn/tutorials/build-ai-image-generation-app'
|
||||
| '/learn/tutorials/customer-service-bot'
|
||||
| '/learn/tutorials/simple-chatbot'
|
||||
| '/learn/tutorials/twitter-chatflow'
|
||||
| '/learn/tutorials/workflow-101/lesson-01'
|
||||
| '/learn/tutorials/workflow-101/lesson-02'
|
||||
| '/learn/tutorials/workflow-101/lesson-03'
|
||||
| '/learn/tutorials/workflow-101/lesson-04'
|
||||
| '/learn/tutorials/workflow-101/lesson-05'
|
||||
| '/learn/tutorials/workflow-101/lesson-06'
|
||||
| '/learn/tutorials/workflow-101/lesson-07'
|
||||
| '/learn/tutorials/workflow-101/lesson-08'
|
||||
| '/learn/tutorials/workflow-101/lesson-09'
|
||||
| '/learn/tutorials/workflow-101/lesson-10'
|
||||
|
||||
// QuickStart paths
|
||||
type QuickStartPath =
|
||||
| '/quick-start'
|
||||
|
||||
// Cli paths
|
||||
type CliPath =
|
||||
| '/cli/coming-soon'
|
||||
|
||||
// DevelopPlugin paths
|
||||
type DevelopPluginPath =
|
||||
@ -165,6 +265,7 @@ type DevelopPluginPath =
|
||||
| '/develop-plugin/features-and-specs/plugin-types/plugin-logging'
|
||||
| '/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin'
|
||||
| '/develop-plugin/features-and-specs/plugin-types/tool'
|
||||
| '/develop-plugin/getting-started/choose-plugin-type'
|
||||
| '/develop-plugin/getting-started/cli'
|
||||
| '/develop-plugin/getting-started/getting-started-dify-plugin'
|
||||
| '/develop-plugin/publishing/faq/faq'
|
||||
@ -177,6 +278,129 @@ type DevelopPluginPath =
|
||||
| '/develop-plugin/publishing/standards/privacy-protection-guidelines'
|
||||
| '/develop-plugin/publishing/standards/third-party-signature-verification'
|
||||
|
||||
// SelfHost paths
|
||||
type SelfHostPath =
|
||||
| '/self-host/deploy/advanced-deployments/local-source-code'
|
||||
| '/self-host/deploy/advanced-deployments/start-the-frontend-docker-container'
|
||||
| '/self-host/deploy/configuration/environments'
|
||||
| '/self-host/deploy/overview'
|
||||
| '/self-host/deploy/platform-guides/bt-panel'
|
||||
| '/self-host/deploy/platform-guides/dify-premium'
|
||||
| '/self-host/deploy/quick-start/docker-compose'
|
||||
| '/self-host/deploy/quick-start/faqs'
|
||||
| '/self-host/deploy/troubleshooting/common-issues'
|
||||
| '/self-host/deploy/troubleshooting/docker-issues'
|
||||
| '/self-host/deploy/troubleshooting/integrations'
|
||||
| '/self-host/deploy/troubleshooting/storage-and-migration'
|
||||
| '/self-host/deploy/troubleshooting/weaviate-v4-migration'
|
||||
| '/self-host/use-dify/build/additional-features'
|
||||
| '/self-host/use-dify/build/agent'
|
||||
| '/self-host/use-dify/build/chatbot'
|
||||
| '/self-host/use-dify/build/mcp'
|
||||
| '/self-host/use-dify/build/orchestrate-node'
|
||||
| '/self-host/use-dify/build/predefined-error-handling-logic'
|
||||
| '/self-host/use-dify/build/shortcut-key'
|
||||
| '/self-host/use-dify/build/text-generator'
|
||||
| '/self-host/use-dify/build/version-control'
|
||||
| '/self-host/use-dify/build/workflow-chatflow'
|
||||
| '/self-host/use-dify/build/workflow-collaboration'
|
||||
| '/self-host/use-dify/debug/error-type'
|
||||
| '/self-host/use-dify/debug/history-and-logs'
|
||||
| '/self-host/use-dify/debug/step-run'
|
||||
| '/self-host/use-dify/debug/variable-inspect'
|
||||
| '/self-host/use-dify/getting-started/introduction'
|
||||
| '/self-host/use-dify/knowledge/connect-external-knowledge-base'
|
||||
| '/self-host/use-dify/knowledge/create-knowledge/chunking-and-cleaning-text'
|
||||
| '/self-host/use-dify/knowledge/create-knowledge/import-text-data/readme'
|
||||
| '/self-host/use-dify/knowledge/create-knowledge/import-text-data/sync-from-notion'
|
||||
| '/self-host/use-dify/knowledge/create-knowledge/import-text-data/sync-from-website'
|
||||
| '/self-host/use-dify/knowledge/create-knowledge/introduction'
|
||||
| '/self-host/use-dify/knowledge/create-knowledge/setting-indexing-methods'
|
||||
| '/self-host/use-dify/knowledge/external-knowledge-api'
|
||||
| '/self-host/use-dify/knowledge/integrate-knowledge-within-application'
|
||||
| '/self-host/use-dify/knowledge/knowledge-pipeline/authorize-data-source'
|
||||
| '/self-host/use-dify/knowledge/knowledge-pipeline/create-knowledge-pipeline'
|
||||
| '/self-host/use-dify/knowledge/knowledge-pipeline/knowledge-pipeline-orchestration'
|
||||
| '/self-host/use-dify/knowledge/knowledge-pipeline/manage-knowledge-base'
|
||||
| '/self-host/use-dify/knowledge/knowledge-pipeline/publish-knowledge-pipeline'
|
||||
| '/self-host/use-dify/knowledge/knowledge-pipeline/readme'
|
||||
| '/self-host/use-dify/knowledge/knowledge-pipeline/upload-files'
|
||||
| '/self-host/use-dify/knowledge/manage-knowledge/introduction'
|
||||
| '/self-host/use-dify/knowledge/manage-knowledge/maintain-dataset-via-api'
|
||||
| '/self-host/use-dify/knowledge/manage-knowledge/maintain-knowledge-documents'
|
||||
| '/self-host/use-dify/knowledge/metadata'
|
||||
| '/self-host/use-dify/knowledge/readme'
|
||||
| '/self-host/use-dify/knowledge/test-retrieval'
|
||||
| '/self-host/use-dify/monitor/analysis'
|
||||
| '/self-host/use-dify/monitor/annotation-reply'
|
||||
| '/self-host/use-dify/monitor/integrations/integrate-aliyun'
|
||||
| '/self-host/use-dify/monitor/integrations/integrate-arize'
|
||||
| '/self-host/use-dify/monitor/integrations/integrate-langfuse'
|
||||
| '/self-host/use-dify/monitor/integrations/integrate-langsmith'
|
||||
| '/self-host/use-dify/monitor/integrations/integrate-opik'
|
||||
| '/self-host/use-dify/monitor/integrations/integrate-phoenix'
|
||||
| '/self-host/use-dify/monitor/integrations/integrate-weave'
|
||||
| '/self-host/use-dify/monitor/logs'
|
||||
| '/self-host/use-dify/nodes/agent'
|
||||
| '/self-host/use-dify/nodes/answer'
|
||||
| '/self-host/use-dify/nodes/code'
|
||||
| '/self-host/use-dify/nodes/doc-extractor'
|
||||
| '/self-host/use-dify/nodes/http-request'
|
||||
| '/self-host/use-dify/nodes/human-input'
|
||||
| '/self-host/use-dify/nodes/ifelse'
|
||||
| '/self-host/use-dify/nodes/iteration'
|
||||
| '/self-host/use-dify/nodes/knowledge-retrieval'
|
||||
| '/self-host/use-dify/nodes/list-operator'
|
||||
| '/self-host/use-dify/nodes/llm'
|
||||
| '/self-host/use-dify/nodes/loop'
|
||||
| '/self-host/use-dify/nodes/output'
|
||||
| '/self-host/use-dify/nodes/parameter-extractor'
|
||||
| '/self-host/use-dify/nodes/question-classifier'
|
||||
| '/self-host/use-dify/nodes/template'
|
||||
| '/self-host/use-dify/nodes/tools'
|
||||
| '/self-host/use-dify/nodes/trigger/overview'
|
||||
| '/self-host/use-dify/nodes/trigger/plugin-trigger'
|
||||
| '/self-host/use-dify/nodes/trigger/schedule-trigger'
|
||||
| '/self-host/use-dify/nodes/trigger/webhook-trigger'
|
||||
| '/self-host/use-dify/nodes/user-input'
|
||||
| '/self-host/use-dify/nodes/variable-aggregator'
|
||||
| '/self-host/use-dify/nodes/variable-assigner'
|
||||
| '/self-host/use-dify/publish/README'
|
||||
| '/self-host/use-dify/publish/developing-with-apis'
|
||||
| '/self-host/use-dify/publish/publish-mcp'
|
||||
| '/self-host/use-dify/publish/publish-to-marketplace'
|
||||
| '/self-host/use-dify/publish/webapp/chatflow-webapp'
|
||||
| '/self-host/use-dify/publish/webapp/embedding-in-websites'
|
||||
| '/self-host/use-dify/publish/webapp/web-app-settings'
|
||||
| '/self-host/use-dify/publish/webapp/workflow-webapp'
|
||||
| '/self-host/use-dify/workspace/api-extension/api-extension'
|
||||
| '/self-host/use-dify/workspace/api-extension/cloudflare-worker'
|
||||
| '/self-host/use-dify/workspace/api-extension/external-data-tool-api-extension'
|
||||
| '/self-host/use-dify/workspace/api-extension/moderation-api-extension'
|
||||
| '/self-host/use-dify/workspace/app-management'
|
||||
| '/self-host/use-dify/workspace/model-providers'
|
||||
| '/self-host/use-dify/workspace/personal-account-management'
|
||||
| '/self-host/use-dify/workspace/plugins'
|
||||
| '/self-host/use-dify/workspace/readme'
|
||||
| '/self-host/use-dify/workspace/team-members-management'
|
||||
| '/self-host/use-dify/workspace/tools'
|
||||
|
||||
// Deploy paths
|
||||
type DeployPath =
|
||||
| '/deploy/advanced-deployments/local-source-code'
|
||||
| '/deploy/advanced-deployments/start-the-frontend-docker-container'
|
||||
| '/deploy/configuration/environments'
|
||||
| '/deploy/overview'
|
||||
| '/deploy/platform-guides/bt-panel'
|
||||
| '/deploy/platform-guides/dify-premium'
|
||||
| '/deploy/quick-start/docker-compose'
|
||||
| '/deploy/quick-start/faqs'
|
||||
| '/deploy/troubleshooting/common-issues'
|
||||
| '/deploy/troubleshooting/docker-issues'
|
||||
| '/deploy/troubleshooting/integrations'
|
||||
| '/deploy/troubleshooting/storage-and-migration'
|
||||
| '/deploy/troubleshooting/weaviate-v4-migration'
|
||||
|
||||
// API Reference paths (English, use apiReferencePathTranslations for other languages)
|
||||
type ApiReferencePath =
|
||||
| '/api-reference/annotations/configure-annotation-reply'
|
||||
@ -189,6 +413,12 @@ type ApiReferencePath =
|
||||
| '/api-reference/applications/get-app-meta'
|
||||
| '/api-reference/applications/get-app-parameters'
|
||||
| '/api-reference/applications/get-app-webapp-settings'
|
||||
| '/api-reference/chatflows/get-next-suggested-questions'
|
||||
| '/api-reference/chatflows/get-workflow-run-detail'
|
||||
| '/api-reference/chatflows/list-workflow-logs'
|
||||
| '/api-reference/chatflows/send-chat-message'
|
||||
| '/api-reference/chatflows/stop-chat-message-generation'
|
||||
| '/api-reference/chatflows/stream-workflow-events'
|
||||
| '/api-reference/chats/get-next-suggested-questions'
|
||||
| '/api-reference/chats/send-chat-message'
|
||||
| '/api-reference/chats/stop-chat-message-generation'
|
||||
@ -225,6 +455,8 @@ type ApiReferencePath =
|
||||
| '/api-reference/feedback/submit-message-feedback'
|
||||
| '/api-reference/files/download-file'
|
||||
| '/api-reference/files/upload-file'
|
||||
| '/api-reference/human-input/get-human-input-form'
|
||||
| '/api-reference/human-input/submit-human-input-form'
|
||||
| '/api-reference/knowledge-bases/create-an-empty-knowledge-base'
|
||||
| '/api-reference/knowledge-bases/delete-knowledge-base'
|
||||
| '/api-reference/knowledge-bases/get-knowledge-base'
|
||||
@ -252,19 +484,24 @@ type ApiReferencePath =
|
||||
| '/api-reference/tags/update-knowledge-tag'
|
||||
| '/api-reference/tts/convert-audio-to-text'
|
||||
| '/api-reference/tts/convert-text-to-audio'
|
||||
| '/api-reference/workflow-runs/get-workflow-run-detail'
|
||||
| '/api-reference/workflow-runs/list-workflow-logs'
|
||||
| '/api-reference/workflows/get-workflow-run-detail'
|
||||
| '/api-reference/workflows/list-workflow-logs'
|
||||
| '/api-reference/workflows/run-workflow'
|
||||
| '/api-reference/workflows/run-workflow-by-id'
|
||||
| '/api-reference/workflows/stop-workflow-task'
|
||||
| '/api-reference/workflows/stream-workflow-events'
|
||||
|
||||
// Base path without language prefix
|
||||
type DocPathWithoutLangBase =
|
||||
| CloudPath
|
||||
| UseDifyPath
|
||||
| SelfHostPath
|
||||
| HomePath
|
||||
| LearnPath
|
||||
| QuickStartPath
|
||||
| CliPath
|
||||
| DevelopPluginPath
|
||||
| SelfHostPath
|
||||
| DeployPath
|
||||
| ApiReferencePath
|
||||
|
||||
// Combined path without language prefix (supports optional #anchor)
|
||||
@ -272,6 +509,116 @@ export type DocPathWithoutLang =
|
||||
| DocPathWithoutLangBase
|
||||
| `${DocPathWithoutLangBase}#${string}`
|
||||
|
||||
// Product availability for productless docs paths
|
||||
export const docPathProductAvailability: Record<string, readonly DocsProduct[]> = {
|
||||
'/deploy/advanced-deployments/local-source-code': ['self-host'],
|
||||
'/deploy/advanced-deployments/start-the-frontend-docker-container': ['self-host'],
|
||||
'/deploy/configuration/environments': ['self-host'],
|
||||
'/deploy/overview': ['self-host'],
|
||||
'/deploy/platform-guides/bt-panel': ['self-host'],
|
||||
'/deploy/platform-guides/dify-premium': ['self-host'],
|
||||
'/deploy/quick-start/docker-compose': ['self-host'],
|
||||
'/deploy/quick-start/faqs': ['self-host'],
|
||||
'/deploy/troubleshooting/common-issues': ['self-host'],
|
||||
'/deploy/troubleshooting/docker-issues': ['self-host'],
|
||||
'/deploy/troubleshooting/integrations': ['self-host'],
|
||||
'/deploy/troubleshooting/storage-and-migration': ['self-host'],
|
||||
'/deploy/troubleshooting/weaviate-v4-migration': ['self-host'],
|
||||
'/use-dify/build/additional-features': ['cloud', 'self-host'],
|
||||
'/use-dify/build/agent': ['cloud', 'self-host'],
|
||||
'/use-dify/build/chatbot': ['cloud', 'self-host'],
|
||||
'/use-dify/build/mcp': ['cloud', 'self-host'],
|
||||
'/use-dify/build/orchestrate-node': ['cloud', 'self-host'],
|
||||
'/use-dify/build/predefined-error-handling-logic': ['cloud', 'self-host'],
|
||||
'/use-dify/build/shortcut-key': ['cloud', 'self-host'],
|
||||
'/use-dify/build/text-generator': ['cloud', 'self-host'],
|
||||
'/use-dify/build/version-control': ['cloud', 'self-host'],
|
||||
'/use-dify/build/workflow-chatflow': ['cloud', 'self-host'],
|
||||
'/use-dify/build/workflow-collaboration': ['cloud', 'self-host'],
|
||||
'/use-dify/debug/error-type': ['cloud', 'self-host'],
|
||||
'/use-dify/debug/history-and-logs': ['cloud', 'self-host'],
|
||||
'/use-dify/debug/step-run': ['cloud', 'self-host'],
|
||||
'/use-dify/debug/variable-inspect': ['cloud', 'self-host'],
|
||||
'/use-dify/getting-started/introduction': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/connect-external-knowledge-base': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/create-knowledge/chunking-and-cleaning-text': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/create-knowledge/import-text-data/readme': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/create-knowledge/import-text-data/sync-from-notion': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/create-knowledge/import-text-data/sync-from-website': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/create-knowledge/introduction': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/create-knowledge/setting-indexing-methods': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/external-knowledge-api': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/integrate-knowledge-within-application': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-pipeline/authorize-data-source': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-pipeline/create-knowledge-pipeline': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-pipeline/knowledge-pipeline-orchestration': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-pipeline/manage-knowledge-base': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-pipeline/publish-knowledge-pipeline': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-pipeline/readme': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-pipeline/upload-files': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/knowledge-request-rate-limit': ['cloud'],
|
||||
'/use-dify/knowledge/manage-knowledge/introduction': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/manage-knowledge/maintain-dataset-via-api': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/manage-knowledge/maintain-knowledge-documents': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/metadata': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/readme': ['cloud', 'self-host'],
|
||||
'/use-dify/knowledge/test-retrieval': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/analysis': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/annotation-reply': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/integrations/integrate-aliyun': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/integrations/integrate-arize': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/integrations/integrate-langfuse': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/integrations/integrate-langsmith': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/integrations/integrate-opik': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/integrations/integrate-phoenix': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/integrations/integrate-weave': ['cloud', 'self-host'],
|
||||
'/use-dify/monitor/logs': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/agent': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/answer': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/code': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/doc-extractor': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/http-request': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/human-input': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/ifelse': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/iteration': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/knowledge-retrieval': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/list-operator': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/llm': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/loop': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/output': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/parameter-extractor': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/question-classifier': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/template': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/tools': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/trigger/overview': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/trigger/plugin-trigger': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/trigger/schedule-trigger': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/trigger/webhook-trigger': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/user-input': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/variable-aggregator': ['cloud', 'self-host'],
|
||||
'/use-dify/nodes/variable-assigner': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/README': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/developing-with-apis': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/publish-mcp': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/publish-to-marketplace': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/webapp/chatflow-webapp': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/webapp/embedding-in-websites': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/webapp/web-app-settings': ['cloud', 'self-host'],
|
||||
'/use-dify/publish/webapp/workflow-webapp': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/api-extension/api-extension': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/api-extension/cloudflare-worker': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/api-extension/external-data-tool-api-extension': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/api-extension/moderation-api-extension': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/app-management': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/model-providers': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/personal-account-management': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/plugins': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/readme': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/subscription-management': ['cloud'],
|
||||
'/use-dify/workspace/team-members-management': ['cloud', 'self-host'],
|
||||
'/use-dify/workspace/tools': ['cloud', 'self-host'],
|
||||
}
|
||||
|
||||
// API Reference path translations (English -> other languages)
|
||||
export const apiReferencePathTranslations: Record<string, { zh?: string; ja?: string }> = {
|
||||
'/api-reference/annotations/configure-annotation-reply': { zh: '/api-reference/标注管理/配置标注回复', ja: '/api-reference/アノテーション管理/アノテーション返信を設定' },
|
||||
@ -284,6 +631,12 @@ export const apiReferencePathTranslations: Record<string, { zh?: string; ja?: st
|
||||
'/api-reference/applications/get-app-meta': { zh: '/api-reference/应用配置/获取应用元数据', ja: '/api-reference/アプリケーション設定/アプリケーションのメタ情報を取得' },
|
||||
'/api-reference/applications/get-app-parameters': { zh: '/api-reference/应用配置/获取应用参数', ja: '/api-reference/アプリケーション設定/アプリケーションのパラメータ情報を取得' },
|
||||
'/api-reference/applications/get-app-webapp-settings': { zh: '/api-reference/应用配置/获取应用-webapp-设置', ja: '/api-reference/アプリケーション設定/アプリの-webapp-設定を取得' },
|
||||
'/api-reference/chatflows/get-next-suggested-questions': { zh: '/api-reference/对话流/获取下一轮建议问题列表', ja: '/api-reference/チャットフロー/次の推奨質問を取得' },
|
||||
'/api-reference/chatflows/get-workflow-run-detail': { zh: '/api-reference/对话流/获取工作流执行情况', ja: '/api-reference/チャットフロー/ワークフロー実行詳細を取得' },
|
||||
'/api-reference/chatflows/list-workflow-logs': { zh: '/api-reference/对话流/获取工作流日志', ja: '/api-reference/チャットフロー/ワークフローログ一覧を取得' },
|
||||
'/api-reference/chatflows/send-chat-message': { zh: '/api-reference/对话流/发送对话消息', ja: '/api-reference/チャットフロー/チャットメッセージを送信' },
|
||||
'/api-reference/chatflows/stop-chat-message-generation': { zh: '/api-reference/对话流/停止响应', ja: '/api-reference/チャットフロー/生成を停止' },
|
||||
'/api-reference/chatflows/stream-workflow-events': { zh: '/api-reference/对话流/流式获取工作流事件', ja: '/api-reference/チャットフロー/ワークフローイベントをストリーム' },
|
||||
'/api-reference/chats/get-next-suggested-questions': { zh: '/api-reference/对话消息/获取下一轮建议问题列表', ja: '/api-reference/チャットメッセージ/次の推奨質問を取得' },
|
||||
'/api-reference/chats/send-chat-message': { zh: '/api-reference/对话消息/发送对话消息', ja: '/api-reference/チャットメッセージ/チャットメッセージを送信' },
|
||||
'/api-reference/chats/stop-chat-message-generation': { zh: '/api-reference/对话消息/停止响应', ja: '/api-reference/チャットメッセージ/生成を停止' },
|
||||
@ -320,6 +673,8 @@ export const apiReferencePathTranslations: Record<string, { zh?: string; ja?: st
|
||||
'/api-reference/feedback/submit-message-feedback': { zh: '/api-reference/消息反馈/提交消息反馈', ja: '/api-reference/メッセージフィードバック/メッセージフィードバックを送信' },
|
||||
'/api-reference/files/download-file': { zh: '/api-reference/文件操作/下载文件', ja: '/api-reference/ファイル操作/ファイルをダウンロード' },
|
||||
'/api-reference/files/upload-file': { zh: '/api-reference/文件操作/上传文件', ja: '/api-reference/ファイル操作/ファイルをアップロード' },
|
||||
'/api-reference/human-input/get-human-input-form': { zh: '/api-reference/人工介入/获取人工介入表单', ja: '/api-reference/人間の入力/人間の入力フォームを取得' },
|
||||
'/api-reference/human-input/submit-human-input-form': { zh: '/api-reference/人工介入/提交人工介入表单', ja: '/api-reference/人間の入力/人間の入力フォームを送信' },
|
||||
'/api-reference/knowledge-bases/create-an-empty-knowledge-base': { zh: '/api-reference/知识库/创建空知识库', ja: '/api-reference/データセット/空のナレッジベースを作成' },
|
||||
'/api-reference/knowledge-bases/delete-knowledge-base': { zh: '/api-reference/知识库/删除知识库', ja: '/api-reference/データセット/ナレッジベースを削除' },
|
||||
'/api-reference/knowledge-bases/get-knowledge-base': { zh: '/api-reference/知识库/获取知识库详情', ja: '/api-reference/データセット/ナレッジベース詳細を取得' },
|
||||
@ -347,11 +702,10 @@ export const apiReferencePathTranslations: Record<string, { zh?: string; ja?: st
|
||||
'/api-reference/tags/update-knowledge-tag': { zh: '/api-reference/标签/修改知识库标签', ja: '/api-reference/タグ管理/ナレッジベースタグを変更' },
|
||||
'/api-reference/tts/convert-audio-to-text': { zh: '/api-reference/语音与文字转换/语音转文字', ja: '/api-reference/音声・テキスト変換/音声をテキストに変換' },
|
||||
'/api-reference/tts/convert-text-to-audio': { zh: '/api-reference/语音与文字转换/文字转语音', ja: '/api-reference/音声・テキスト変換/テキストを音声に変換' },
|
||||
'/api-reference/workflow-runs/get-workflow-run-detail': { zh: '/api-reference/工作流执行/获取工作流执行情况', ja: '/api-reference/ワークフロー実行/ワークフロー実行詳細を取得' },
|
||||
'/api-reference/workflow-runs/list-workflow-logs': { zh: '/api-reference/工作流执行/获取工作流日志', ja: '/api-reference/ワークフロー実行/ワークフローログ一覧を取得' },
|
||||
'/api-reference/workflows/get-workflow-run-detail': { zh: '/api-reference/工作流/获取工作流执行情况', ja: '/api-reference/ワークフロー/ワークフロー実行詳細を取得' },
|
||||
'/api-reference/workflows/list-workflow-logs': { zh: '/api-reference/工作流/获取工作流日志', ja: '/api-reference/ワークフロー/ワークフローログ一覧を取得' },
|
||||
'/api-reference/workflows/run-workflow': { zh: '/api-reference/工作流/执行工作流', ja: '/api-reference/ワークフロー/ワークフローを実行' },
|
||||
'/api-reference/workflows/run-workflow-by-id': { zh: '/api-reference/工作流/按-id-执行工作流', ja: '/api-reference/ワークフロー/id-でワークフローを実行' },
|
||||
'/api-reference/workflows/stop-workflow-task': { zh: '/api-reference/工作流/停止工作流任务', ja: '/api-reference/ワークフロー/ワークフロータスクを停止' },
|
||||
'/api-reference/workflows/stream-workflow-events': { zh: '/api-reference/工作流/流式获取工作流事件', ja: '/api-reference/ワークフロー/ワークフローイベントをストリーム' },
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user