diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-22 14:58:26 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-22 14:59:09 +0300 |
| commit | c234f221f9be698bc0501c60459e1ae8e67df6c3 (patch) | |
| tree | 944b4dec10fada8d93456dc5a85e6bfdb36a8b8b /website/src/docs-path.ts | |
| parent | ef85fa0c7ebb48bb59fe7593af5a67f3e02ff3d4 (diff) | |
feat(docs): publish versioned release documentation
Diffstat (limited to 'website/src/docs-path.ts')
| -rw-r--r-- | website/src/docs-path.ts | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/website/src/docs-path.ts b/website/src/docs-path.ts index be022a4b..53ace41d 100644 --- a/website/src/docs-path.ts +++ b/website/src/docs-path.ts @@ -1,20 +1,87 @@ const docsLocales = new Set(['ja', 'zh-cn']); +const docsVersionPattern = /^\d+\.\d+\.\d+$/; -export function docsChannel(pathname: string) { - return /^\/(?:ja\/|zh-cn\/)?docs\/preview(?:\/|$)/.test(pathname) ? 'preview' : 'stable'; +export type DocsTarget = 'stable' | 'preview' | string; + +export interface DocsRoute { + isDocs: boolean; + locale: string | undefined; + target: DocsTarget; + page: string; +} + +export interface DocsScope { + locales: Record<string, string[]>; +} + +export function docsRoute(pathname: string): DocsRoute { + const segments = pathname.split('/').filter(Boolean); + let locale: string | undefined; + + if (segments[0] && docsLocales.has(segments[0])) { + locale = segments.shift(); + } + + if (segments.shift() !== 'docs') { + return { isDocs: false, locale, target: 'stable', page: '' }; + } + + let target: DocsTarget = 'stable'; + if (segments[0] === 'preview') { + target = 'preview'; + segments.shift(); + } else if (segments[0] && docsVersionPattern.test(segments[0])) { + target = segments.shift()!; + } + + return { + isDocs: true, + locale, + target, + page: segments.join('/'), + }; +} + +export function docsVersion(pathname: string) { + return docsRoute(pathname).target; +} + +export function docsTargetHref( + route: DocsRoute, + target: DocsTarget, + scopes?: Record<string, DocsScope>, +) { + if (!route.isDocs) throw new Error('cannot build a documentation target from a non-docs route'); + + const localeKey = route.locale ?? 'root'; + const availablePages = scopes?.[target]?.locales[localeKey]; + const page = availablePages?.includes(route.page) === false ? '' : route.page; + const prefix = route.locale ? `/${route.locale}` : ''; + const targetSegment = target === 'stable' ? '' : `/${target}`; + return `${prefix}/docs${targetSegment}${page ? `/${page}` : ''}/`; } export function docsPath({ entry }: { entry: string }) { const slug = entry.replace(/\.(md|mdx|markdown|mdown|mkdn|mkd|mdwn)$/i, ''); const normalized = slug.replace(/\/index$/, ''); const segments = normalized.split('/'); - const localeIndex = segments[0] === 'preview' ? 1 : 0; - const locale = segments[localeIndex]; - if (locale && docsLocales.has(locale)) { - segments.splice(localeIndex, 1); - return `${locale}/docs${segments.length > 0 ? `/${segments.join('/')}` : ''}`; + let targetSegment = ''; + if (segments[0] === 'preview') { + targetSegment = 'preview'; + segments.shift(); + } else if (segments[0] === '_versions' && segments[1] && docsVersionPattern.test(segments[1])) { + segments.shift(); + targetSegment = segments.shift()!; + } + + let locale: string | undefined; + if (segments[0] && docsLocales.has(segments[0])) { + locale = segments.shift(); } - return normalized === 'index' ? 'docs' : `docs/${normalized}`; + const page = segments.join('/'); + const prefix = locale ? `${locale}/` : ''; + const target = targetSegment ? `/${targetSegment}` : ''; + return `${prefix}docs${target}${page && page !== 'index' ? `/${page}` : ''}`; } |
