aboutsummaryrefslogtreecommitdiff
path: root/website/src/docs-path.ts
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-22 14:58:26 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-22 14:59:09 +0300
commitc234f221f9be698bc0501c60459e1ae8e67df6c3 (patch)
tree944b4dec10fada8d93456dc5a85e6bfdb36a8b8b /website/src/docs-path.ts
parentef85fa0c7ebb48bb59fe7593af5a67f3e02ff3d4 (diff)
feat(docs): publish versioned release documentation
Diffstat (limited to 'website/src/docs-path.ts')
-rw-r--r--website/src/docs-path.ts83
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}` : ''}`;
}