diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/docs/hello.md b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/docs/hello.md new file mode 100644 index 000000000000..6e39f0eb8588 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/docs/hello.md @@ -0,0 +1 @@ +# Current documentation diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versioned_docs/version-1.0.0/hello.md b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versioned_docs/version-1.0.0/hello.md new file mode 100644 index 000000000000..362c2726d8c9 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versioned_docs/version-1.0.0/hello.md @@ -0,0 +1 @@ +# Version 1 documentation diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versioned_sidebars/version-1.0.0-sidebars.js b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versioned_sidebars/version-1.0.0-sidebars.js new file mode 100644 index 000000000000..a2c5cc51a3b3 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versioned_sidebars/version-1.0.0-sidebars.js @@ -0,0 +1,3 @@ +module.exports = { + docs: ['hello'], +}; diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versions.json b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versions.json new file mode 100644 index 000000000000..64de05e14b9e --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/__fixtures__/site-js-sidebar/versions.json @@ -0,0 +1 @@ +["1.0.0"] diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/files.test.ts b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/files.test.ts new file mode 100644 index 000000000000..08e352a95f34 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/files.test.ts @@ -0,0 +1,41 @@ +import {describe, expect, it} from 'vitest'; +import path from 'path'; +import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils'; +import {getVersionSidebarsPath, resolveVersionSidebarsPath} from '../files'; + +describe('getVersionSidebarsPath', () => { + it('returns the JSON versioned sidebar path', async () => { + expect(getVersionSidebarsPath('/site', DEFAULT_PLUGIN_ID, '1.0.0')).toBe( + path.join('/site', 'versioned_sidebars', 'version-1.0.0-sidebars.json'), + ); + }); + it('returns the JSON versioned sidebar path when using a version name', async () => { + expect(getVersionSidebarsPath('/site', DEFAULT_PLUGIN_ID, '2.0.0')).toBe( + path.join('/site', 'versioned_sidebars', 'version-2.0.0-sidebars.json'), + ); + }); + it('returns the JavaScript versioned sidebar path when it exists', async () => { + const siteDir = path.join(__dirname, 'fixtures'); + const expectedPath = path.join( + siteDir, + 'versioned_sidebars', + 'version-1.0.0-sidebars.js', + ); + + await expect( + resolveVersionSidebarsPath(siteDir, DEFAULT_PLUGIN_ID, '1.0.0'), + ).resolves.toBe(expectedPath); + }); + it('falls back to the JSON versioned sidebar path when no JavaScript file exists', async () => { + const siteDir = '/site'; + const expectedPath = path.join( + siteDir, + 'versioned_sidebars', + 'version-1.0.0-sidebars.json', + ); + + await expect( + resolveVersionSidebarsPath(siteDir, DEFAULT_PLUGIN_ID, '1.0.0'), + ).resolves.toBe(expectedPath); + }); +}); diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/fixtures/versioned_sidebars/version-1.0.0-sidebars.js b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/fixtures/versioned_sidebars/version-1.0.0-sidebars.js new file mode 100644 index 000000000000..ad43adfde190 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/fixtures/versioned_sidebars/version-1.0.0-sidebars.js @@ -0,0 +1,6 @@ +module.exports = { + docs: { + Test: ['foo/bar', 'foo/baz'], + Guides: ['hello'], + }, +}; diff --git a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/loadVersion.test.ts b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/loadVersion.test.ts index 0beb0c6b8f3e..4bc1d591891d 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions/__tests__/loadVersion.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions/__tests__/loadVersion.test.ts @@ -59,6 +59,25 @@ async function siteFixture(fixture: string) { } describe('loadVersion', () => { + describe('site with JavaScript versioned sidebar', () => { + it('loads a versioned sidebar from a JavaScript file', async () => { + const {options, context, versions} = await siteFixture('site-js-sidebar'); + + const version = versions.find((v) => v.versionName === '1.0.0'); + expect(version).toBeDefined(); + + const loadedVersion = await loadVersion({ + context, + options, + versionMetadata: version!, + env: 'production', + }); + + expect(loadedVersion.sidebars).toEqual({ + docs: [{type: 'doc', id: 'hello'}], + }); + }); + }); describe('minimal site', () => { it('can load current version', async () => { const {options, context, versions} = await siteFixture('site-minimal'); diff --git a/packages/docusaurus-plugin-content-docs/src/versions/files.ts b/packages/docusaurus-plugin-content-docs/src/versions/files.ts index 824c8092eef3..17c581c112e8 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions/files.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions/files.ts @@ -51,11 +51,31 @@ export function getVersionSidebarsPath( pluginId: string, versionName: string, ): string { - return path.join( + const sidebarsDir = path.join( + siteDir, + addPluginIdPrefix(VERSIONED_SIDEBARS_DIR, pluginId), + ); + + return path.join(sidebarsDir, `version-${versionName}-sidebars.json`); +} + +/** Resolves a versioned sidebar, supporting both `.js` and `.json` files. */ +export async function resolveVersionSidebarsPath( + siteDir: string, + pluginId: string, + versionName: string, +): Promise { + const sidebarsDir = path.join( siteDir, addPluginIdPrefix(VERSIONED_SIDEBARS_DIR, pluginId), - `version-${versionName}-sidebars.json`, ); + + const baseName = `version-${versionName}-sidebars`; + const jsPath = path.join(sidebarsDir, `${baseName}.js`); + + return (await fs.pathExists(jsPath)) + ? jsPath + : getVersionSidebarsPath(siteDir, pluginId, versionName); } export function getDocsDirPathLocalized({ @@ -205,7 +225,11 @@ export async function getVersionMetadataPaths({ : getVersionDocsDirPath(context.siteDir, options.id, versionName); const sidebarFilePath = isCurrent ? options.sidebarPath - : getVersionSidebarsPath(context.siteDir, options.id, versionName); + : await resolveVersionSidebarsPath( + context.siteDir, + options.id, + versionName, + ); if (!(await fs.pathExists(contentPath))) { throw new Error(