/
githubmirror
/
docusaurus
Обзор
Документация
Войти
/
githubmirror
/
docusaurus
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/docusaurus-plugin-content-docs/src/versions/version.ts
300 строк
8 KB
Sébastien Lorber
feat(core): add `i18n.localeConfigs.translate` + skip translation process if `i18n/<locale>` dir doesn't exist (#11304)
07 июл 2025, 15:55
Не верифицирован
07 июл 2025, 15:55
1808945
Код
Авторство
О чём код?
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import path from 'path'; import {getContentPathList, normalizeUrl, posixPath} from '@docusaurus/utils'; import {CURRENT_VERSION_NAME} from '../constants'; import {validateVersionsOptions} from './validation'; import { getDocsDirPathLocalized, getVersionMetadataPaths, readVersionNames, } from './files'; import {createSidebarsUtils} from '../sidebars/utils'; import {getCategoryGeneratedIndexMetadataList} from '../categoryGeneratedIndex'; import type {FullVersion} from '../types'; import type {LoadContext} from '@docusaurus/types'; import type { LoadedVersion, PluginOptions, VersionBanner, VersionMetadata, } from '@docusaurus/plugin-content-docs'; export type VersionContext = { /** The version name to get banner of. */ versionName: string; /** All versions, ordered from newest to oldest. */ versionNames: string[]; lastVersionName: string; context: LoadContext; options: PluginOptions; }; function getVersionEditUrls({ contentPath, contentPathLocalized, context, options, }: Pick<VersionMetadata, 'contentPath' | 'contentPathLocalized'> & { context: LoadContext; options: PluginOptions; }): Pick<VersionMetadata, 'editUrl' | 'editUrlLocalized'> { // If the user is using the functional form of editUrl, // she has total freedom and we can't compute a "version edit url" if (!options.editUrl || typeof options.editUrl === 'function') { return {editUrl: undefined, editUrlLocalized: undefined}; } // Intermediate var just to please TS not narrowing to "string" const editUrlOption = options.editUrl; const getEditUrl = () => { const editDirPath = options.editCurrentVersion ? options.path : contentPath; return normalizeUrl([ editUrlOption, posixPath( path.relative( context.siteDir, path.resolve(context.siteDir, editDirPath), ), ), ]); }; const getEditUrlLocalized = () => { if (!contentPathLocalized) { return undefined; } const editDirPathLocalized = options.editCurrentVersion ? getDocsDirPathLocalized({ localizationDir: context.localizationDir, versionName: CURRENT_VERSION_NAME, pluginId: options.id, }) : contentPathLocalized; return normalizeUrl([ editUrlOption, posixPath( path.relative( context.siteDir, path.resolve(context.siteDir, editDirPathLocalized), ), ), ]); }; return {editUrl: getEditUrl(), editUrlLocalized: getEditUrlLocalized()}; } /** * The default version banner depends on the version's relative position to the * latest version. More recent ones are "unreleased", and older ones are * "unmaintained". */ export function getDefaultVersionBanner({ versionName, versionNames, lastVersionName, }: VersionContext): VersionBanner | null { // Current version: good, no banner if (versionName === lastVersionName) { return null; } // Upcoming versions: unreleased banner if ( versionNames.indexOf(versionName) < versionNames.indexOf(lastVersionName) ) { return 'unreleased'; } // Older versions: display unmaintained banner return 'unmaintained'; } export function getVersionBanner( context: VersionContext, ): VersionMetadata['banner'] { const {versionName, options} = context; const versionBannerOption = options.versions[versionName]?.banner; if (versionBannerOption) { return versionBannerOption === 'none' ? null : versionBannerOption; } return getDefaultVersionBanner(context); } export function getVersionBadge({ versionName, versionNames, options, }: VersionContext): VersionMetadata['badge'] { // If site is not versioned or only one version is included // we don't show the version badge by default // See https://github.com/facebook/docusaurus/issues/3362 const defaultVersionBadge = versionNames.length !== 1; return options.versions[versionName]?.badge ?? defaultVersionBadge; } export function getVersionNoIndex({ versionName, options, }: VersionContext): VersionMetadata['noIndex'] { return options.versions[versionName]?.noIndex ?? false; } function getVersionClassName({ versionName, options, }: VersionContext): VersionMetadata['className'] { const defaultVersionClassName = `docs-version-${versionName}`; return options.versions[versionName]?.className ?? defaultVersionClassName; } function getVersionLabel({ versionName, options, }: VersionContext): VersionMetadata['label'] { const defaultVersionLabel = versionName === CURRENT_VERSION_NAME ? 'Next' : versionName; return options.versions[versionName]?.label ?? defaultVersionLabel; } function getVersionPathPart({ versionName, options, lastVersionName, }: VersionContext): string { function getDefaultVersionPathPart() { if (versionName === lastVersionName) { return ''; } return versionName === CURRENT_VERSION_NAME ? 'next' : versionName; } return options.versions[versionName]?.path ?? getDefaultVersionPathPart(); } async function createVersionMetadata( context: VersionContext, ): Promise<VersionMetadata> { const {versionName, lastVersionName, options, context: loadContext} = context; const {sidebarFilePath, contentPath, contentPathLocalized} = await getVersionMetadataPaths(context); const versionPathPart = getVersionPathPart(context); const routePath = normalizeUrl([ loadContext.baseUrl, options.routeBasePath, versionPathPart, ]); const versionEditUrls = getVersionEditUrls({ contentPath, contentPathLocalized, context: loadContext, options, }); return { versionName, label: getVersionLabel(context), banner: getVersionBanner(context), badge: getVersionBadge(context), noIndex: getVersionNoIndex(context), className: getVersionClassName(context), path: routePath, tagsPath: normalizeUrl([routePath, options.tagsBasePath]), ...versionEditUrls, isLast: versionName === lastVersionName, routePriority: versionPathPart === '' ? -1 : undefined, sidebarFilePath, contentPath, contentPathLocalized, }; } /** * Filter versions according to provided options (i.e. `onlyIncludeVersions`). * * Note: we preserve the order in which versions are provided; the order of the * `onlyIncludeVersions` array does not matter */ export function filterVersions( versionNamesUnfiltered: string[], options: PluginOptions, ): string[] { if (options.onlyIncludeVersions) { return versionNamesUnfiltered.filter((name) => options.onlyIncludeVersions!.includes(name), ); } return versionNamesUnfiltered; } function getLastVersionName({ versionNames, options, }: Pick<VersionContext, 'versionNames' | 'options'>) { return ( options.lastVersion ?? versionNames.find((name) => name !== CURRENT_VERSION_NAME) ?? CURRENT_VERSION_NAME ); } export async function readVersionsMetadata({ context, options, }: { context: LoadContext; options: PluginOptions; }): Promise<VersionMetadata[]> { const allVersionNames = await readVersionNames(context.siteDir, options); validateVersionsOptions(allVersionNames, options); const versionNames = filterVersions(allVersionNames, options); const lastVersionName = getLastVersionName({versionNames, options}); return Promise.all( versionNames.map((versionName) => createVersionMetadata({ versionName, versionNames, lastVersionName, context, options, }), ), ); } export function toFullVersion(version: LoadedVersion): FullVersion { const sidebarsUtils = createSidebarsUtils(version.sidebars); return { ...version, sidebarsUtils, categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({ docs: version.docs, sidebarsUtils, }), }; } export function getVersionFromSourceFilePath( filePath: string, versionsMetadata: VersionMetadata[], ): VersionMetadata { const versionFound = versionsMetadata.find((version) => getContentPathList(version).some((docsDirPath) => filePath.startsWith(docsDirPath), ), ); if (!versionFound) { throw new Error( `Unexpected error: file at "${filePath}" does not belong to any docs version!`, ); } return versionFound; }