chore: clean up ESLint config, enable a few rules (#6514)

* chore: clean up ESLint config, enable a few rules

* enable max-len for comments

* fix build
This commit is contained in:
Joshua Chen 2022-01-31 10:31:24 +08:00 committed by GitHub
parent b8ccb869f1
commit aa446b7a9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
167 changed files with 1157 additions and 960 deletions

View file

@ -95,7 +95,8 @@ Entries created:
},
expectSnapshot: () => {
// Sort the route config like in src/server/plugins/index.ts for consistent snapshot ordering
// Sort the route config like in src/server/plugins/index.ts for
// consistent snapshot ordering
sortConfig(routeConfigs);
expect(routeConfigs).not.toEqual([]);
expect(routeConfigs).toMatchSnapshot('route config');
@ -249,7 +250,8 @@ describe('simple website', () => {
.spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation();
const cli = new commander.Command();
// @ts-expect-error: in actual usage, we pass the static commander instead of the new command
// @ts-expect-error: in actual usage, we pass the static commander instead
// of the new command
plugin.extendCli!(cli);
cli.parse(['node', 'test', 'docs:version', '1.0.0']);
expect(mock).toHaveBeenCalledTimes(1);
@ -373,7 +375,8 @@ describe('versioned website', () => {
.spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation();
const cli = new commander.Command();
// @ts-expect-error: in actual usage, we pass the static commander instead of the new command
// @ts-expect-error: in actual usage, we pass the static commander instead
// of the new command
plugin.extendCli!(cli);
cli.parse(['node', 'test', 'docs:version', '2.0.0']);
expect(mock).toHaveBeenCalledTimes(1);
@ -522,7 +525,8 @@ describe('versioned website (community)', () => {
.spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation();
const cli = new commander.Command();
// @ts-expect-error: in actual usage, we pass the static commander instead of the new command
// @ts-expect-error: in actual usage, we pass the static commander instead
// of the new command
plugin.extendCli!(cli);
cli.parse(['node', 'test', `docs:version:${pluginId}`, '2.0.0']);
expect(mock).toHaveBeenCalledTimes(1);
@ -726,7 +730,8 @@ describe('site with partial autogenerated sidebars', () => {
const {content} = await loadSite();
const version = content.loadedVersions[0];
// Only looking at the docs of the autogen sidebar, others metadata should not be affected
// Only looking at the docs of the autogen sidebar, others metadata should
// not be affected
expect(getDocById(version, 'API/api-end')).toMatchSnapshot();
expect(getDocById(version, 'API/api-overview')).toMatchSnapshot();
@ -803,7 +808,8 @@ describe('site with custom sidebar items generator', () => {
const generatorArg: SidebarItemsGeneratorOptionArgs =
customSidebarItemsGeneratorMock.mock.calls[0][0];
// Make test pass even if docs are in different order and paths are absolutes
// Make test pass even if docs are in different order and paths are
// absolutes
function makeDeterministic(
arg: SidebarItemsGeneratorOptionArgs,
): SidebarItemsGeneratorOptionArgs {

View file

@ -32,10 +32,12 @@ function createVersionedSidebarFile({
version: string;
}) {
// Load current sidebar and create a new versioned sidebars file (if needed).
// Note: we don't need the sidebars file to be normalized: it's ok to let plugin option changes to impact older, versioned sidebars
// Note: we don't need the sidebars file to be normalized: it's ok to let
// plugin option changes to impact older, versioned sidebars
const sidebars = loadSidebarsFile(sidebarPath);
// Do not create a useless versioned sidebars file if sidebars file is empty or sidebars are disabled/false)
// Do not create a useless versioned sidebars file if sidebars file is empty
// or sidebars are disabled/false)
const shouldCreateVersionedSidebarFile = Object.keys(sidebars).length > 0;
if (shouldCreateVersionedSidebarFile) {

View file

@ -28,7 +28,7 @@ export function getActivePlugin(
options: GetActivePluginOptions = {},
): ActivePlugin | undefined {
const activeEntry = Object.entries(allPluginDatas)
// A quick route sorting: '/android/foo' should match '/android' instead of '/'
// Route sorting: '/android/foo' should match '/android' instead of '/'
.sort((a, b) => b[1].path.localeCompare(a[1].path))
.find(
([, pluginData]) =>
@ -67,7 +67,7 @@ export const getActiveVersion = (
): GlobalVersion | undefined => {
const lastVersion = getLatestVersion(data);
// Last version is a route like /docs/*,
// we need to try to match it last or it would match /docs/version-1.0/* as well
// we need to match it last or it would match /docs/version-1.0/* as well
const orderedVersionsMetadata = [
...data.versions.filter((version) => version !== lastVersion),
lastVersion,

View file

@ -27,12 +27,13 @@ import type {
GetActivePluginOptions,
} from '@docusaurus/plugin-content-docs/client';
// Important to use a constant object to avoid React useEffect executions etc...,
// Important to use a constant object to avoid React useEffect executions etc.
// see https://github.com/facebook/docusaurus/issues/5089
const StableEmptyObject = {};
// Not using useAllPluginInstancesData() because in blog-only mode, docs hooks are still used by the theme
// We need a fail-safe fallback when the docs plugin is not in use
// Not using useAllPluginInstancesData() because in blog-only mode, docs hooks
// are still used by the theme. We need a fail-safe fallback when the docs
// plugin is not in use
export const useAllDocsData = (): Record<string, GlobalPluginData> =>
// useAllPluginInstancesData('docusaurus-plugin-content-docs');
useGlobalData()['docusaurus-plugin-content-docs'] ?? StableEmptyObject;

View file

@ -139,7 +139,8 @@ function doProcessDocMetadata({
const {
custom_edit_url: customEditURL,
// Strip number prefixes by default (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc) by default,
// Strip number prefixes by default
// (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc)
// but allow to disable this behavior with front matter
parse_number_prefixes: parseNumberPrefixes = true,
} = frontMatter;
@ -164,7 +165,8 @@ function doProcessDocMetadata({
throw new Error(`Document id "${baseID}" cannot include slash.`);
}
// For autogenerated sidebars, sidebar position can come from filename number prefix or front matter
// For autogenerated sidebars, sidebar position can come from filename number
// prefix or front matter
const sidebarPosition: number | undefined =
frontMatter.sidebar_position ?? numberPrefix;
@ -205,8 +207,9 @@ function doProcessDocMetadata({
numberPrefixParser: options.numberPrefixParser,
});
// Note: the title is used by default for page title, sidebar label, pagination buttons...
// frontMatter.title should be used in priority over contentTitle (because it can contain markdown/JSX syntax)
// Note: the title is used by default for page title, sidebar label,
// pagination buttons... frontMatter.title should be used in priority over
// contentTitle (because it can contain markdown/JSX syntax)
const title: string = frontMatter.title ?? contentTitle ?? baseID;
const description: string = frontMatter.description ?? excerpt ?? '';
@ -233,9 +236,8 @@ function doProcessDocMetadata({
? versionMetadata.versionEditUrlLocalized
: versionMetadata.versionEditUrl;
return getEditUrl(relativeFilePath, baseVersionEditUrl);
} else {
return undefined;
}
return undefined;
}
// Assign all of object properties during instantiation (if possible) for
@ -361,9 +363,8 @@ export function getMainDocId({
doc.id === firstDocIdOfFirstSidebar ||
doc.unversionedId === firstDocIdOfFirstSidebar,
)!;
} else {
return docs[0];
}
return docs[0];
}
return getMainDoc().unversionedId;
@ -407,7 +408,8 @@ export function toCategoryIndexMatcherParam({
}
/**
* guides/sidebar/autogenerated.md -> 'autogenerated', '.md', ['sidebar', 'guides']
* `guides/sidebar/autogenerated.md` ->
* `'autogenerated', '.md', ['sidebar', 'guides']`
*/
export function splitPath(str: string): {
/**
@ -428,15 +430,17 @@ export function splitPath(str: string): {
}
// Return both doc ids
// TODO legacy retro-compatibility due to old versioned sidebars using versioned doc ids
// ("id" should be removed & "versionedId" should be renamed to "id")
// TODO legacy retro-compatibility due to old versioned sidebars using
// versioned doc ids ("id" should be removed & "versionedId" should be renamed
// to "id")
export function getDocIds(doc: DocMetadataBase): [string, string] {
return [doc.unversionedId, doc.id];
}
// docs are indexed by both versioned and unversioned ids at the same time
// TODO legacy retro-compatibility due to old versioned sidebars using versioned doc ids
// ("id" should be removed & "versionedId" should be renamed to "id")
// TODO legacy retro-compatibility due to old versioned sidebars using
// versioned doc ids ("id" should be removed & "versionedId" should be renamed
// to "id")
export function createDocsByIdIndex<
Doc extends {id: string; unversionedId: string},
>(docs: Doc[]): Record<string, Doc> {

View file

@ -8,15 +8,16 @@
import type {NumberPrefixParser} from '@docusaurus/plugin-content-docs';
// Best-effort to avoid parsing some patterns as number prefix
const IgnoredPrefixPatterns = (function () {
const IgnoredPrefixPatterns = (() => {
// ignore common date-like patterns: https://github.com/facebook/docusaurus/issues/4640
const DateLikePrefixRegex =
/^((\d{2}|\d{4})[-_.]\d{2}([-_.](\d{2}|\d{4}))?)(.*)$/;
// ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653
// note: we could try to parse float numbers in filenames but that is probably not worth it
// as a version such as "8.0" can be interpreted as both a version and a float
// User can configure his own NumberPrefixParser if he wants 8.0 to be interpreted as a float
// note: we could try to parse float numbers in filenames but that is
// probably not worth it as a version such as "8.0" can be interpreted as both
// a version and a float. User can configure her own NumberPrefixParser if
// she wants 8.0 to be interpreted as a float
const VersionLikePrefixRegex = /^(\d+[-_.]\d+)(.*)$/;
return new RegExp(

View file

@ -148,8 +148,9 @@ export function validateOptions({
let options = userOptions;
if (options.sidebarCollapsible === false) {
// When sidebarCollapsible=false and sidebarCollapsed=undefined, we don't want to have the inconsistency warning
// We let options.sidebarCollapsible become the default value for options.sidebarCollapsed
// When sidebarCollapsible=false and sidebarCollapsed=undefined, we don't
// want to have the inconsistency warning. We let options.sidebarCollapsible
// become the default value for options.sidebarCollapsed
if (typeof options.sidebarCollapsed === 'undefined') {
options = {
...options,

View file

@ -45,7 +45,8 @@ declare module '@docusaurus/plugin-content-docs' {
sidebarPath?: string | false | undefined;
};
// TODO support custom version banner? {type: "error", content: "html content"}
// TODO support custom version banner?
// {type: "error", content: "html content"}
export type VersionBanner = 'unreleased' | 'unmaintained';
export type VersionOptions = {
path?: string;

View file

@ -73,7 +73,8 @@ export async function createCategoryGeneratedIndexRoutes({
modules: {
categoryGeneratedIndex: aliasedSource(propData),
},
// Same as doc, this sidebar route attribute permits to associate this subpage to the given sidebar
// Same as doc, this sidebar route attribute permits to associate this
// subpage to the given sidebar
...(sidebar && {sidebar}),
};
}
@ -109,7 +110,8 @@ export async function createDocRoutes({
content: metadataItem.source,
},
// Because the parent (DocPage) comp need to access it easily
// This permits to render the sidebar once without unmount/remount when navigating (and preserve sidebar state)
// This permits to render the sidebar once without unmount/remount when
// navigating (and preserve sidebar state)
...(metadataItem.sidebar && {
sidebar: metadataItem.sidebar,
}),

View file

@ -205,7 +205,8 @@ describe('processSidebars', () => {
link: {
type: 'generated-index',
slug: 'generated-cat-index-slug',
// @ts-expect-error: TODO undefined should be allowed here, typing error needing refactor
// @ts-expect-error: TODO undefined should be allowed here,
// typing error needing refactor
permalink: undefined,
},
},

View file

@ -47,7 +47,8 @@ export type CategoryMetadataFile = {
className?: string;
link?: SidebarItemCategoryLinkConfig | null;
// TODO should we allow "items" here? how would this work? would an "autogenerated" type be allowed?
// TODO should we allow "items" here? how would this work? would an
// "autogenerated" type be allowed?
// This mkdocs plugin do something like that: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin/
// cf comment: https://github.com/facebook/docusaurus/issues/3464#issuecomment-784765199
};
@ -56,16 +57,20 @@ type WithPosition<T> = T & {position?: number};
/**
* A representation of the fs structure. For each object entry:
* If it's a folder, the key is the directory name, and value is the directory content;
* If it's a doc file, the key is the doc id prefixed with '$doc$/', and value is null
* If it's a folder, the key is the directory name, and value is the directory
* content; If it's a doc file, the key is the doc id prefixed with '$doc$/',
* and value is null
*/
type Dir = {
[item: string]: Dir | null;
};
// TODO I now believe we should read all the category metadata files ahead of time: we may need this metadata to customize docs metadata
// Example use-case being able to disable number prefix parsing at the folder level, or customize the default route path segment for an intermediate directory...
// TODO later if there is `CategoryFolder/with-category-name-doc.md`, we may want to read the metadata as yaml on it
// TODO I now believe we should read all the category metadata files ahead of
// time: we may need this metadata to customize docs metadata
// Example use-case being able to disable number prefix parsing at the folder
// level, or customize the default base slug for an intermediate directory
// TODO later if there is `CategoryFolder/with-category-name-doc.md`, we may
// want to read the metadata as yaml on it
// see https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
async function readCategoryMetadataFile(
categoryDirPath: string,
@ -142,7 +147,8 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
* Step 2. Turn the linear file list into a tree structure.
*/
function treeify(docs: SidebarItemsGeneratorDoc[]): Dir {
// Get the category breadcrumb of a doc (relative to the dir of the autogenerated sidebar item)
// Get the category breadcrumb of a doc (relative to the dir of the
// autogenerated sidebar item)
// autogenDir=a/b and docDir=a/b/c/d => returns [c, d]
// autogenDir=a/b and docDir=a/b => returns []
// TODO: try to use path.relative()
@ -169,7 +175,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
}
/**
* Step 3. Recursively transform the tree-like file structure to sidebar items.
* Step 3. Recursively transform the tree-like structure to sidebar items.
* (From a record to an array of items, akin to normalizing shorthand)
*/
function generateSidebar(fsModel: Dir): Promise<WithPosition<SidebarItem>[]> {
@ -182,7 +188,8 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
type: 'doc',
id,
position,
// We don't want these fields to magically appear in the generated sidebar
// We don't want these fields to magically appear in the generated
// sidebar
...(label !== undefined && {label}),
...(className !== undefined && {className}),
};
@ -225,13 +232,12 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
if (link !== undefined) {
if (link && link.type === 'doc') {
return findDocByLocalId(link.id)?.id || getDoc(link.id).id;
} else {
// We don't continue for other link types on purpose!
// IE if user decide to use type "generated-index", we should not pick a README.md file as the linked doc
return undefined;
}
// If a link is explicitly specified, we won't apply conventions
return undefined;
}
// Apply default convention to pick index.md, README.md or <categoryName>.md as the category doc
// Apply default convention to pick index.md, README.md or
// <categoryName>.md as the category doc
return findConventionalCategoryDocLink()?.id;
}
@ -279,10 +285,11 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
}
/**
* Step 4. Recursively sort the categories/docs + remove the "position" attribute from final output.
* Note: the "position" is only used to sort "inside" a sidebar slice. It is not
* used to sort across multiple consecutive sidebar slices (ie a whole Category
* composed of multiple autogenerated items)
* Step 4. Recursively sort the categories/docs + remove the "position"
* attribute from final output. Note: the "position" is only used to sort
* "inside" a sidebar slice. It is not used to sort across multiple
* consecutive sidebar slices (i.e. a whole category composed of multiple
* autogenerated items)
*/
function sortItems(sidebarItems: WithPosition<SidebarItem>[]): SidebarItem[] {
const processedSidebarItems = sidebarItems.map((item) => {
@ -298,7 +305,6 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
return sortedSidebarItems.map(({position, ...item}) => item);
}
// TODO: the whole code is designed for pipeline operator
// return getAutogenDocs() |> treeify |> await generateSidebar(^) |> sortItems;
const docs = getAutogenDocs();
const fsModel = treeify(docs);
const sidebarWithPosition = await generateSidebar(fsModel);

View file

@ -60,7 +60,8 @@ function toSidebarItemsGeneratorVersion(
return pick(version, ['versionName', 'contentPath']);
}
// Handle the generation of autogenerated sidebar items and other post-processing checks
// Handle the generation of autogenerated sidebar items and other
// post-processing checks
async function processSidebar(
unprocessedSidebar: NormalizedSidebar,
params: SidebarProcessorParams,
@ -91,7 +92,8 @@ async function processSidebar(
async function processAutoGeneratedItem(
item: SidebarItemAutogenerated,
): Promise<SidebarItem[]> {
// TODO the returned type can't be trusted in practice (generator can be user-provided)
// TODO the returned type can't be trusted in practice (generator can be
// user-provided)
const generatedItems = await sidebarItemsGenerator({
item,
numberPrefixParser,
@ -106,7 +108,8 @@ async function processSidebar(
normalizeItem(generatedItem, {...params, ...sidebarOptions}),
);
// Process again... weird but sidebar item generated might generate some auto-generated items?
// Process again... weird but sidebar item generated might generate some
// auto-generated items?
return processItems(generatedItemsNormalized);
}

View file

@ -205,7 +205,8 @@ export type SidebarItemsGenerator = (
Promise<SidebarItem[]>;
// Promise<SidebarItemConfig[]>;
// Also inject the default generator to conveniently wrap/enhance/sort the default sidebar gen logic
// Also inject the default generator to conveniently wrap/enhance/sort the
// default sidebar gen logic
// see https://github.com/facebook/docusaurus/issues/4640#issuecomment-822292320
export type SidebarItemsGeneratorOptionArgs = {
defaultSidebarItemsGenerator: SidebarItemsGenerator;

View file

@ -16,7 +16,6 @@ import type {
SidebarCategoriesShorthand,
SidebarItemConfig,
SidebarItemCategoryWithGeneratedIndex,
SidebarItemCategoryWithLink,
SidebarNavigationItem,
} from './types';
@ -46,8 +45,11 @@ export function transformSidebarItems(
return sidebar.map(transformRecursive);
}
// Flatten sidebar items into a single flat array (containing categories/docs on the same level)
// /!\ order matters (useful for next/prev nav), top categories appear before their child elements
/**
* Flatten sidebar items into a single flat array (containing categories/docs on
* the same level). Order matters (useful for next/prev nav), top categories
* appear before their child elements
*/
function flattenSidebarItems(items: SidebarItem[]): SidebarItem[] {
function flattenRecursive(item: SidebarItem): SidebarItem[] {
return item.type === 'category'
@ -196,34 +198,33 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
sidebarName = getSidebarNameByDocId(docId);
}
if (sidebarName) {
if (!sidebarNameToNavigationItems[sidebarName]) {
throw new Error(
`Doc with ID ${docId} wants to display sidebar ${sidebarName} but a sidebar with this name doesn't exist`,
);
}
const navigationItems = sidebarNameToNavigationItems[sidebarName];
const currentItemIndex = navigationItems.findIndex((item) => {
if (item.type === 'doc') {
return item.id === docId;
}
if (item.type === 'category' && item.link.type === 'doc') {
return item.link.id === docId;
}
return false;
});
if (currentItemIndex === -1) {
return {sidebarName, next: undefined, previous: undefined};
}
const {previous, next} = getElementsAround(
navigationItems,
currentItemIndex,
);
return {sidebarName, previous, next};
} else {
if (!sidebarName) {
return emptySidebarNavigation();
}
if (!sidebarNameToNavigationItems[sidebarName]) {
throw new Error(
`Doc with ID ${docId} wants to display sidebar ${sidebarName} but a sidebar with this name doesn't exist`,
);
}
const navigationItems = sidebarNameToNavigationItems[sidebarName];
const currentItemIndex = navigationItems.findIndex((item) => {
if (item.type === 'doc') {
return item.id === docId;
}
if (item.type === 'category' && item.link.type === 'doc') {
return item.link.id === docId;
}
return false;
});
if (currentItemIndex === -1) {
return {sidebarName, next: undefined, previous: undefined};
}
const {previous, next} = getElementsAround(
navigationItems,
currentItemIndex,
);
return {sidebarName, previous, next};
}
function getCategoryGeneratedIndexList(): SidebarItemCategoryWithGeneratedIndex[] {
@ -237,8 +238,10 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
});
}
// We identity the category generated index by its permalink (should be unique)
// More reliable than using object identity
/**
* We identity the category generated index by its permalink (should be
* unique). More reliable than using object identity
*/
function getCategoryGeneratedIndexNavigation(
categoryGeneratedIndexPermalink: string,
): SidebarNavigation {
@ -257,19 +260,18 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
navigationItems.find(isCurrentCategoryGeneratedIndexItem),
)?.[0];
if (sidebarName) {
const navigationItems = sidebarNameToNavigationItems[sidebarName];
const currentItemIndex = navigationItems.findIndex(
isCurrentCategoryGeneratedIndexItem,
);
const {previous, next} = getElementsAround(
navigationItems,
currentItemIndex,
);
return {sidebarName, previous, next};
} else {
if (!sidebarName) {
return emptySidebarNavigation();
}
const navigationItems = sidebarNameToNavigationItems[sidebarName];
const currentItemIndex = navigationItems.findIndex(
isCurrentCategoryGeneratedIndexItem,
);
const {previous, next} = getElementsAround(
navigationItems,
currentItemIndex,
);
return {sidebarName, previous, next};
}
function checkSidebarsDocIds(validDocIds: string[], sidebarFilePath: string) {
@ -322,11 +324,10 @@ Available document ids are:
slug: item.link.slug,
label: item.label,
};
} else {
const firstSubItem = getFirstLink(item.items);
if (firstSubItem) {
return firstSubItem;
}
}
const firstSubItem = getFirstLink(item.items);
if (firstSubItem) {
return firstSubItem;
}
}
}
@ -371,18 +372,6 @@ export function toNavigationLink(
return doc;
}
function handleCategory(category: SidebarItemCategoryWithLink): DocNavLink {
if (category.link.type === 'doc') {
return toDocNavigationLink(getDocById(category.link.id));
} else if (category.link.type === 'generated-index') {
return {
title: category.label,
permalink: category.link.permalink,
};
} else {
throw new Error('unexpected category link type');
}
}
if (!navigationItem) {
return undefined;
}
@ -390,8 +379,15 @@ export function toNavigationLink(
if (navigationItem.type === 'doc') {
return toDocNavigationLink(getDocById(navigationItem.id));
} else if (navigationItem.type === 'category') {
return handleCategory(navigationItem);
} else {
throw new Error('unexpected navigation item');
if (navigationItem.link.type === 'doc') {
return toDocNavigationLink(getDocById(navigationItem.link.id));
} else if (navigationItem.link.type === 'generated-index') {
return {
title: navigationItem.label,
permalink: navigationItem.link.permalink,
};
}
throw new Error('unexpected category link type');
}
throw new Error('unexpected navigation item');
}

View file

@ -23,7 +23,8 @@ import {isCategoriesShorthand} from './utils';
import type {CategoryMetadataFile} from './generator';
// NOTE: we don't add any default values during validation on purpose!
// Config types are exposed to users for typechecking and we use the same type in normalization
// Config types are exposed to users for typechecking and we use the same type
// in normalization
const sidebarItemBaseSchema = Joi.object<SidebarItemBase>({
className: Joi.string(),
@ -71,7 +72,8 @@ const sidebarItemCategoryLinkSchema = Joi.object<SidebarItemCategoryLink>()
then: Joi.object<SidebarItemCategoryLinkGeneratedIndex>({
type: 'generated-index',
slug: Joi.string().optional(),
// permalink: Joi.string().optional(), // No, this one is not in the user config, only in the normalized version
// This one is not in the user config, only in the normalized version
// permalink: Joi.string().optional(),
title: Joi.string().optional(),
description: Joi.string().optional(),
image: Joi.string().optional(),
@ -132,7 +134,8 @@ function validateSidebarItem(item: unknown): asserts item is SidebarItemConfig {
return;
}
// TODO: remove once with proper Joi support
// Because we can't use Joi to validate nested items (see above), we do it manually
// Because we can't use Joi to validate nested items (see above), we do it
// manually
if (isCategoriesShorthand(item as SidebarItemConfig)) {
Object.values(item as SidebarCategoriesShorthand).forEach((category) =>
category.forEach(validateSidebarItem),

View file

@ -48,17 +48,16 @@ export default function getSlug({
function computeSlug(): string {
if (frontMatterSlug?.startsWith('/')) {
return frontMatterSlug;
} else {
const dirNameSlug = getDirNameSlug();
if (
!frontMatterSlug &&
isCategoryIndex(toCategoryIndexMatcherParam({source, sourceDirName}))
) {
return dirNameSlug;
}
const baseSlug = frontMatterSlug || baseID;
return resolvePathname(baseSlug, getDirNameSlug());
}
const dirNameSlug = getDirNameSlug();
if (
!frontMatterSlug &&
isCategoryIndex(toCategoryIndexMatcherParam({source, sourceDirName}))
) {
return dirNameSlug;
}
const baseSlug = frontMatterSlug || baseID;
return resolvePathname(baseSlug, getDirNameSlug());
}
function ensureValidSlug(slug: string): string {

View file

@ -31,11 +31,10 @@ import {CURRENT_VERSION_NAME} from './constants';
function getVersionFileName(versionName: string): string {
if (versionName === CURRENT_VERSION_NAME) {
return versionName;
} else {
// I don't like this "version-" prefix,
// but it's for consistency with site/versioned_docs
return `version-${versionName}`;
}
// I don't like this "version-" prefix,
// but it's for consistency with site/versioned_docs
return `version-${versionName}`;
}
// TODO legacy, the sidebar name is like "version-2.0.0-alpha.66/docs"
@ -68,7 +67,8 @@ function getDocTranslations(doc: DocMetadata): TranslationFileContent {
? {
[`${doc.unversionedId}.sidebar_label`]: {
message: doc.sidebar_label,
description: `The sidebar label for doc with id=${doc.unversionedId}`,
description:
`The sidebar label for doc with id=${doc.unversionedId}`,
},
}
: undefined),
@ -253,7 +253,8 @@ function getVersionTranslationFiles(version: LoadedVersion): TranslationFiles {
const sidebarsTranslations: TranslationFileContent =
getSidebarsTranslations(version);
// const docsTranslations: TranslationFileContent = getDocsTranslations(version);
// const docsTranslations: TranslationFileContent =
// getDocsTranslations(version);
return [
{

View file

@ -33,11 +33,9 @@ import {resolveSidebarPathOption} from './sidebars';
// retro-compatibility: no prefix for the default plugin id
function addPluginIdPrefix(fileOrDir: string, pluginId: string): string {
if (pluginId === DEFAULT_PLUGIN_ID) {
return fileOrDir;
} else {
return `${pluginId}_${fileOrDir}`;
}
return pluginId === DEFAULT_PLUGIN_ID
? fileOrDir
: `${pluginId}_${fileOrDir}`;
}
export function getVersionedDocsDirPath(
@ -96,9 +94,8 @@ async function readVersionsFile(
const content = JSON.parse(await fs.readFile(versionsFilePath, 'utf8'));
ensureValidVersionArray(content);
return content;
} else {
return null;
}
return null;
}
async function readVersionNames(
@ -274,15 +271,13 @@ function getDefaultVersionBanner({
return null;
}
// Upcoming versions: unreleased banner
else if (
if (
versionNames.indexOf(versionName) < versionNames.indexOf(lastVersionName)
) {
return 'unreleased';
}
// Older versions: display unmaintained banner
else {
return 'unmaintained';
}
return 'unmaintained';
}
function getVersionBanner({
@ -443,8 +438,9 @@ function checkVersionMetadataPaths({
);
}
// If the current version defines a path to a sidebar file that does not exist, we throw!
// Note: for versioned sidebars, the file may not exist (as we prefer to not create it rather than to create an empty file)
// If the current version defines a path to a sidebar file that does not
// exist, we throw! Note: for versioned sidebars, the file may not exist (as
// we prefer to not create it rather than to create an empty file)
// See https://github.com/facebook/docusaurus/issues/3366
// See https://github.com/facebook/docusaurus/pull/4775
if (
@ -469,11 +465,10 @@ Please set the docs "sidebarPath" field in your config file to:
function getDefaultLastVersionName(versionNames: string[]) {
if (versionNames.length === 1) {
return versionNames[0];
} else {
return versionNames.filter(
(versionName) => versionName !== CURRENT_VERSION_NAME,
)[0];
}
return versionNames.filter(
(versionName) => versionName !== CURRENT_VERSION_NAME,
)[0];
}
function checkVersionsOptions(
@ -544,9 +539,8 @@ function filterVersions(
return versionNamesUnfiltered.filter((name) =>
(options.onlyIncludeVersions || []).includes(name),
);
} else {
return versionNamesUnfiltered;
}
return versionNamesUnfiltered;
}
export async function readVersionsMetadata({