mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-02 01:17:53 +02:00
refactor: ensure lodash is default-imported (#6716)
This commit is contained in:
parent
47c9a37c5f
commit
ea6ceaa371
44 changed files with 239 additions and 221 deletions
57
.eslintrc.js
57
.eslintrc.js
|
@ -69,31 +69,44 @@ module.exports = {
|
||||||
'no-param-reassign': [WARNING, {props: false}],
|
'no-param-reassign': [WARNING, {props: false}],
|
||||||
'no-prototype-builtins': WARNING,
|
'no-prototype-builtins': WARNING,
|
||||||
'no-restricted-exports': OFF,
|
'no-restricted-exports': OFF,
|
||||||
'no-restricted-imports': [
|
'no-restricted-properties': [
|
||||||
ERROR,
|
ERROR,
|
||||||
{
|
...[
|
||||||
paths: [
|
|
||||||
{
|
|
||||||
name: 'lodash',
|
|
||||||
importNames: [
|
|
||||||
// TODO: TS doesn't make Boolean a narrowing function yet,
|
// TODO: TS doesn't make Boolean a narrowing function yet,
|
||||||
// so filter(Boolean) is problematic type-wise
|
// so filter(Boolean) is problematic type-wise
|
||||||
// 'compact',
|
// ['compact', 'Array#filter(Boolean)'],
|
||||||
'filter',
|
['concat', 'Array#concat'],
|
||||||
'flatten',
|
['drop', 'Array#slice(n)'],
|
||||||
'flatMap',
|
['dropRight', 'Array#slice(0, -n)'],
|
||||||
'map',
|
['fill', 'Array#fill'],
|
||||||
'reduce',
|
['filter', 'Array#filter'],
|
||||||
'take',
|
['find', 'Array#find'],
|
||||||
'takeRight',
|
['findIndex', 'Array#findIndex'],
|
||||||
'head',
|
['first', 'foo[0]'],
|
||||||
'tail',
|
['flatten', 'Array#flat'],
|
||||||
'initial',
|
['flattenDeep', 'Array#flat(Infinity)'],
|
||||||
],
|
['flatMap', 'Array#flatMap'],
|
||||||
message: 'These APIs have their ES counterparts.',
|
['fromPairs', 'Object.fromEntries'],
|
||||||
},
|
['head', 'foo[0]'],
|
||||||
],
|
['indexOf', 'Array#indexOf'],
|
||||||
},
|
['initial', 'Array#slice(0, -1)'],
|
||||||
|
['join', 'Array#join'],
|
||||||
|
// Unfortunately there's no great alternative to _.last yet
|
||||||
|
// Candidates: foo.slice(-1)[0]; foo[foo.length - 1]
|
||||||
|
// Array#at is ES2022; could replace _.nth as well
|
||||||
|
// ['last'],
|
||||||
|
['map', 'Array#map'],
|
||||||
|
['reduce', 'Array#reduce'],
|
||||||
|
['reverse', 'Array#reverse'],
|
||||||
|
['slice', 'Array#slice'],
|
||||||
|
['take', 'Array#slice(0, n)'],
|
||||||
|
['takeRight', 'Array#slice(-n)'],
|
||||||
|
['tail', 'Array#slice(1)'],
|
||||||
|
].map(([property, alternative]) => ({
|
||||||
|
object: '_',
|
||||||
|
property,
|
||||||
|
message: `Use ${alternative} instead.`,
|
||||||
|
})),
|
||||||
],
|
],
|
||||||
'no-restricted-syntax': [
|
'no-restricted-syntax': [
|
||||||
WARNING,
|
WARNING,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {uniqBy, difference, groupBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {
|
import type {
|
||||||
PluginOptions,
|
PluginOptions,
|
||||||
RedirectOption,
|
RedirectOption,
|
||||||
|
@ -79,7 +79,7 @@ function validateCollectedRedirects(
|
||||||
|
|
||||||
const allowedToPaths = pluginContext.relativeRoutesPaths;
|
const allowedToPaths = pluginContext.relativeRoutesPaths;
|
||||||
const toPaths = redirects.map((redirect) => redirect.to);
|
const toPaths = redirects.map((redirect) => redirect.to);
|
||||||
const illegalToPaths = difference(toPaths, allowedToPaths);
|
const illegalToPaths = _.difference(toPaths, allowedToPaths);
|
||||||
if (illegalToPaths.length > 0) {
|
if (illegalToPaths.length > 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`You are trying to create client-side redirections to paths that do not exist:
|
`You are trying to create client-side redirections to paths that do not exist:
|
||||||
|
@ -98,7 +98,7 @@ function filterUnwantedRedirects(
|
||||||
): RedirectMetadata[] {
|
): RedirectMetadata[] {
|
||||||
// we don't want to create twice the same redirect
|
// we don't want to create twice the same redirect
|
||||||
// that would lead to writing twice the same html redirection file
|
// that would lead to writing twice the same html redirection file
|
||||||
Object.entries(groupBy(redirects, (redirect) => redirect.from)).forEach(
|
Object.entries(_.groupBy(redirects, (redirect) => redirect.from)).forEach(
|
||||||
([from, groupedFromRedirects]) => {
|
([from, groupedFromRedirects]) => {
|
||||||
if (groupedFromRedirects.length > 1) {
|
if (groupedFromRedirects.length > 1) {
|
||||||
logger.error`name=${'@docusaurus/plugin-client-redirects'}: multiple redirects are created with the same "from" pathname: path=${from}
|
logger.error`name=${'@docusaurus/plugin-client-redirects'}: multiple redirects are created with the same "from" pathname: path=${from}
|
||||||
|
@ -108,7 +108,7 @@ It is not possible to redirect the same pathname to multiple destinations: ${gro
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const collectedRedirects = uniqBy(redirects, (redirect) => redirect.from);
|
const collectedRedirects = _.uniqBy(redirects, (redirect) => redirect.from);
|
||||||
|
|
||||||
// We don't want to override an already existing route with a redirect file!
|
// We don't want to override an already existing route with a redirect file!
|
||||||
const redirectsOverridingExistingPath = collectedRedirects.filter(
|
const redirectsOverridingExistingPath = collectedRedirects.filter(
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
|
|
||||||
import * as eta from 'eta';
|
import * as eta from 'eta';
|
||||||
import redirectPageTemplate from './templates/redirectPage.template.html';
|
import redirectPageTemplate from './templates/redirectPage.template.html';
|
||||||
import {memoize} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
type CreateRedirectPageOptions = {
|
type CreateRedirectPageOptions = {
|
||||||
toUrl: string;
|
toUrl: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCompiledRedirectPageTemplate = memoize(() =>
|
const getCompiledRedirectPageTemplate = _.memoize(() =>
|
||||||
eta.compile(redirectPageTemplate.trim()),
|
eta.compile(redirectPageTemplate.trim()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {memoize} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import type {PluginContext, RedirectMetadata} from './types';
|
import type {PluginContext, RedirectMetadata} from './types';
|
||||||
import createRedirectPageContent from './createRedirectPageContent';
|
import createRedirectPageContent from './createRedirectPageContent';
|
||||||
|
@ -63,7 +63,7 @@ export function toRedirectFilesMetadata(
|
||||||
// Perf: avoid rendering the template twice with the exact same "props"
|
// Perf: avoid rendering the template twice with the exact same "props"
|
||||||
// We might create multiple redirect pages for the same destination url
|
// We might create multiple redirect pages for the same destination url
|
||||||
// note: the first fn arg is the cache key!
|
// note: the first fn arg is the cache key!
|
||||||
const createPageContentMemoized = memoize((toUrl: string) =>
|
const createPageContentMemoized = _.memoize((toUrl: string) =>
|
||||||
createRedirectPageContent({toUrl}),
|
createRedirectPageContent({toUrl}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import readingTime from 'reading-time';
|
import readingTime from 'reading-time';
|
||||||
import {keyBy, mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {
|
import type {
|
||||||
BlogPost,
|
BlogPost,
|
||||||
BlogContentPaths,
|
BlogContentPaths,
|
||||||
|
@ -46,9 +46,8 @@ export function truncate(fileString: string, truncateMarker: RegExp): string {
|
||||||
export function getSourceToPermalink(
|
export function getSourceToPermalink(
|
||||||
blogPosts: BlogPost[],
|
blogPosts: BlogPost[],
|
||||||
): Record<string, string> {
|
): Record<string, string> {
|
||||||
return mapValues(
|
return Object.fromEntries(
|
||||||
keyBy(blogPosts, (item) => item.metadata.source),
|
blogPosts.map(({metadata: {source, permalink}}) => [source, permalink]),
|
||||||
(v) => v.metadata.permalink,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,19 +111,16 @@ export function getBlogTags({
|
||||||
(blogPost) => blogPost.metadata.tags,
|
(blogPost) => blogPost.metadata.tags,
|
||||||
);
|
);
|
||||||
|
|
||||||
return mapValues(groups, (group) => {
|
return _.mapValues(groups, ({tag, items: tagBlogPosts}) => ({
|
||||||
const {tag, items: tagBlogPosts} = group;
|
|
||||||
return {
|
|
||||||
name: tag.label,
|
name: tag.label,
|
||||||
items: tagBlogPosts.map((item) => item.id),
|
items: tagBlogPosts.map((item) => item.id),
|
||||||
permalink: tag.permalink,
|
permalink: tag.permalink,
|
||||||
pages: paginateBlogPosts({
|
pages: paginateBlogPosts({
|
||||||
blogPosts: tagBlogPosts,
|
blogPosts: tagBlogPosts,
|
||||||
basePageUrl: group.tag.permalink,
|
basePageUrl: tag.permalink,
|
||||||
...params,
|
...params,
|
||||||
}),
|
}),
|
||||||
};
|
}));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DATE_FILENAME_REGEX =
|
const DATE_FILENAME_REGEX =
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {isMatch} from 'picomatch';
|
import {isMatch} from 'picomatch';
|
||||||
import commander from 'commander';
|
import commander from 'commander';
|
||||||
import {kebabCase, orderBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import pluginContentDocs from '../index';
|
import pluginContentDocs from '../index';
|
||||||
|
@ -89,7 +89,7 @@ Entries created:
|
||||||
|
|
||||||
checkVersionMetadataPropCreated: (version: LoadedVersion) => {
|
checkVersionMetadataPropCreated: (version: LoadedVersion) => {
|
||||||
const versionMetadataProp = getCreatedDataByPrefix(
|
const versionMetadataProp = getCreatedDataByPrefix(
|
||||||
`version-${kebabCase(version.versionName)}-metadata-prop`,
|
`version-${_.kebabCase(version.versionName)}-metadata-prop`,
|
||||||
);
|
);
|
||||||
expect(versionMetadataProp.docsSidebars).toEqual(toSidebarsProp(version));
|
expect(versionMetadataProp.docsSidebars).toEqual(toSidebarsProp(version));
|
||||||
},
|
},
|
||||||
|
@ -815,7 +815,7 @@ describe('site with custom sidebar items generator', () => {
|
||||||
): SidebarItemsGeneratorOptionArgs {
|
): SidebarItemsGeneratorOptionArgs {
|
||||||
return {
|
return {
|
||||||
...arg,
|
...arg,
|
||||||
docs: orderBy(arg.docs, 'id'),
|
docs: _.orderBy(arg.docs, 'id'),
|
||||||
version: {
|
version: {
|
||||||
...arg.version,
|
...arg.version,
|
||||||
contentPath: path.relative(siteDir, arg.version.contentPath),
|
contentPath: path.relative(siteDir, arg.version.contentPath),
|
||||||
|
|
|
@ -17,7 +17,7 @@ import type {
|
||||||
GlobalVersion,
|
GlobalVersion,
|
||||||
ActivePlugin,
|
ActivePlugin,
|
||||||
} from '@docusaurus/plugin-content-docs/client';
|
} from '@docusaurus/plugin-content-docs/client';
|
||||||
import {shuffle} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
describe('docsClientUtils', () => {
|
describe('docsClientUtils', () => {
|
||||||
test('getActivePlugin', () => {
|
test('getActivePlugin', () => {
|
||||||
|
@ -227,7 +227,7 @@ describe('docsClientUtils', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// shuffle, because order shouldn't matter
|
// shuffle, because order shouldn't matter
|
||||||
const versions: GlobalVersion[] = shuffle([
|
const versions: GlobalVersion[] = _.shuffle([
|
||||||
versionNext,
|
versionNext,
|
||||||
version2,
|
version2,
|
||||||
version1,
|
version1,
|
||||||
|
@ -356,7 +356,7 @@ describe('docsClientUtils', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// shuffle, because order shouldn't matter
|
// shuffle, because order shouldn't matter
|
||||||
const versions: GlobalVersion[] = shuffle([
|
const versions: GlobalVersion[] = _.shuffle([
|
||||||
versionNext,
|
versionNext,
|
||||||
version2,
|
version2,
|
||||||
version1,
|
version1,
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import {keyBy} from 'lodash';
|
|
||||||
import {
|
import {
|
||||||
aliasedSitePath,
|
aliasedSitePath,
|
||||||
getEditUrl,
|
getEditUrl,
|
||||||
|
@ -444,8 +443,10 @@ export function getDocIds(doc: DocMetadataBase): [string, string] {
|
||||||
export function createDocsByIdIndex<
|
export function createDocsByIdIndex<
|
||||||
Doc extends {id: string; unversionedId: string},
|
Doc extends {id: string; unversionedId: string},
|
||||||
>(docs: Doc[]): Record<string, Doc> {
|
>(docs: Doc[]): Record<string, Doc> {
|
||||||
return {
|
return Object.fromEntries(
|
||||||
...keyBy(docs, (doc) => doc.unversionedId),
|
docs.flatMap((doc) => [
|
||||||
...keyBy(docs, (doc) => doc.id),
|
[doc.unversionedId, doc],
|
||||||
};
|
[doc.id, doc],
|
||||||
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {normalizeUrl} from '@docusaurus/utils';
|
import {normalizeUrl} from '@docusaurus/utils';
|
||||||
import type {Sidebars} from './sidebars/types';
|
import type {Sidebars} from './sidebars/types';
|
||||||
import {createSidebarsUtils} from './sidebars/utils';
|
import {createSidebarsUtils} from './sidebars/utils';
|
||||||
|
@ -43,7 +43,7 @@ export function toGlobalSidebars(
|
||||||
version: LoadedVersion,
|
version: LoadedVersion,
|
||||||
): Record<string, GlobalSidebar> {
|
): Record<string, GlobalSidebar> {
|
||||||
const {getFirstLink} = createSidebarsUtils(sidebars);
|
const {getFirstLink} = createSidebarsUtils(sidebars);
|
||||||
return mapValues(sidebars, (sidebar, sidebarId) => {
|
return _.mapValues(sidebars, (sidebar, sidebarId) => {
|
||||||
const firstLink = getFirstLink(sidebarId);
|
const firstLink = getFirstLink(sidebarId);
|
||||||
if (!firstLink) {
|
if (!firstLink) {
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -42,7 +42,6 @@ import type {
|
||||||
import type {RuleSetRule} from 'webpack';
|
import type {RuleSetRule} from 'webpack';
|
||||||
import {cliDocsVersionCommand} from './cli';
|
import {cliDocsVersionCommand} from './cli';
|
||||||
import {VERSIONS_JSON_FILE} from './constants';
|
import {VERSIONS_JSON_FILE} from './constants';
|
||||||
import {keyBy, mapValues} from 'lodash';
|
|
||||||
import {toGlobalDataVersion} from './globalData';
|
import {toGlobalDataVersion} from './globalData';
|
||||||
import {toTagDocListProp} from './props';
|
import {toTagDocListProp} from './props';
|
||||||
import {
|
import {
|
||||||
|
@ -311,9 +310,8 @@ export default async function pluginContentDocs(
|
||||||
|
|
||||||
function getSourceToPermalink(): SourceToPermalink {
|
function getSourceToPermalink(): SourceToPermalink {
|
||||||
const allDocs = content.loadedVersions.flatMap((v) => v.docs);
|
const allDocs = content.loadedVersions.flatMap((v) => v.docs);
|
||||||
return mapValues(
|
return Object.fromEntries(
|
||||||
keyBy(allDocs, (d) => d.source),
|
allDocs.map(({source, permalink}) => [source, permalink]),
|
||||||
(d) => d.permalink,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import type {
|
||||||
PropTagDocListDoc,
|
PropTagDocListDoc,
|
||||||
PropSidebarItemLink,
|
PropSidebarItemLink,
|
||||||
} from '@docusaurus/plugin-content-docs';
|
} from '@docusaurus/plugin-content-docs';
|
||||||
import {compact, keyBy, mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {createDocsByIdIndex} from './docs';
|
import {createDocsByIdIndex} from './docs';
|
||||||
|
|
||||||
export function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars {
|
export function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars {
|
||||||
|
@ -93,18 +93,22 @@ Available document ids are:
|
||||||
// Transform the sidebar so that all sidebar item will be in the
|
// Transform the sidebar so that all sidebar item will be in the
|
||||||
// form of 'link' or 'category' only.
|
// form of 'link' or 'category' only.
|
||||||
// This is what will be passed as props to the UI component.
|
// This is what will be passed as props to the UI component.
|
||||||
return mapValues(loadedVersion.sidebars, (items) => items.map(normalizeItem));
|
return _.mapValues(loadedVersion.sidebars, (items) =>
|
||||||
|
items.map(normalizeItem),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVersionDocsProp(loadedVersion: LoadedVersion): PropVersionDocs {
|
function toVersionDocsProp(loadedVersion: LoadedVersion): PropVersionDocs {
|
||||||
return mapValues(
|
return Object.fromEntries(
|
||||||
keyBy(loadedVersion.docs, (doc) => doc.unversionedId),
|
loadedVersion.docs.map((doc) => [
|
||||||
(doc) => ({
|
doc.unversionedId,
|
||||||
|
{
|
||||||
id: doc.unversionedId,
|
id: doc.unversionedId,
|
||||||
title: doc.title,
|
title: doc.title,
|
||||||
description: doc.description,
|
description: doc.description,
|
||||||
sidebar: doc.sidebar,
|
sidebar: doc.sidebar,
|
||||||
}),
|
},
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +139,7 @@ export function toTagDocListProp({
|
||||||
docs: Pick<DocMetadata, 'id' | 'title' | 'description' | 'permalink'>[];
|
docs: Pick<DocMetadata, 'id' | 'title' | 'description' | 'permalink'>[];
|
||||||
}): PropTagDocList {
|
}): PropTagDocList {
|
||||||
function toDocListProp(): PropTagDocListDoc[] {
|
function toDocListProp(): PropTagDocListDoc[] {
|
||||||
const list = compact(
|
const list = _.compact(
|
||||||
tag.docIds.map((id) => docs.find((doc) => doc.id === id)),
|
tag.docIds.map((id) => docs.find((doc) => doc.id === id)),
|
||||||
);
|
);
|
||||||
// Sort docs by title
|
// Sort docs by title
|
||||||
|
|
|
@ -13,7 +13,7 @@ import type {
|
||||||
NormalizedSidebarItem,
|
NormalizedSidebarItem,
|
||||||
SidebarItemCategoryLinkConfig,
|
SidebarItemCategoryLinkConfig,
|
||||||
} from './types';
|
} from './types';
|
||||||
import {sortBy, last} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {addTrailingSlash, posixPath} from '@docusaurus/utils';
|
import {addTrailingSlash, posixPath} from '@docusaurus/utils';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
@ -25,7 +25,7 @@ const docIdPrefix = '$doc$/';
|
||||||
|
|
||||||
// Just an alias to the make code more explicit
|
// Just an alias to the make code more explicit
|
||||||
function getLocalDocId(docId: string): string {
|
function getLocalDocId(docId: string): string {
|
||||||
return last(docId.split('/'))!;
|
return _.last(docId.split('/'))!;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CategoryMetadataFilenameBase = '_category_';
|
export const CategoryMetadataFilenameBase = '_category_';
|
||||||
|
@ -248,7 +248,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
const sortedSidebarItems = sortBy(
|
const sortedSidebarItems = _.sortBy(
|
||||||
processedSidebarItems,
|
processedSidebarItems,
|
||||||
(item) => item.position,
|
(item) => item.position,
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {Globby} from '@docusaurus/utils';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import type {PluginOptions} from '@docusaurus/plugin-content-docs';
|
import type {PluginOptions} from '@docusaurus/plugin-content-docs';
|
||||||
import Yaml from 'js-yaml';
|
import Yaml from 'js-yaml';
|
||||||
import {groupBy, mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
import combinePromises from 'combine-promises';
|
import combinePromises from 'combine-promises';
|
||||||
|
|
||||||
export const DefaultSidebars: SidebarsConfig = {
|
export const DefaultSidebars: SidebarsConfig = {
|
||||||
|
@ -46,9 +46,9 @@ async function readCategoriesMetadata(contentPath: string) {
|
||||||
const categoryFiles = await Globby('**/_category_.{json,yml,yaml}', {
|
const categoryFiles = await Globby('**/_category_.{json,yml,yaml}', {
|
||||||
cwd: contentPath,
|
cwd: contentPath,
|
||||||
});
|
});
|
||||||
const categoryToFile = groupBy(categoryFiles, path.dirname);
|
const categoryToFile = _.groupBy(categoryFiles, path.dirname);
|
||||||
return combinePromises(
|
return combinePromises(
|
||||||
mapValues(categoryToFile, async (files, folder) => {
|
_.mapValues(categoryToFile, async (files, folder) => {
|
||||||
const [filePath] = files;
|
const [filePath] = files;
|
||||||
if (files.length > 1) {
|
if (files.length > 1) {
|
||||||
logger.warn`There are more than one category metadata files for path=${folder}: ${files.join(
|
logger.warn`There are more than one category metadata files for path=${folder}: ${files.join(
|
||||||
|
|
|
@ -17,7 +17,7 @@ import type {
|
||||||
NormalizedSidebarItemCategory,
|
NormalizedSidebarItemCategory,
|
||||||
} from './types';
|
} from './types';
|
||||||
import {isCategoriesShorthand} from './utils';
|
import {isCategoriesShorthand} from './utils';
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
function normalizeCategoriesShorthand(
|
function normalizeCategoriesShorthand(
|
||||||
sidebar: SidebarCategoriesShorthand,
|
sidebar: SidebarCategoriesShorthand,
|
||||||
|
@ -81,5 +81,5 @@ function normalizeSidebar(sidebar: SidebarConfig): NormalizedSidebar {
|
||||||
export function normalizeSidebars(
|
export function normalizeSidebars(
|
||||||
sidebars: SidebarsConfig,
|
sidebars: SidebarsConfig,
|
||||||
): NormalizedSidebars {
|
): NormalizedSidebars {
|
||||||
return mapValues(sidebars, normalizeSidebar);
|
return _.mapValues(sidebars, normalizeSidebar);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import type {
|
||||||
ProcessedSidebars,
|
ProcessedSidebars,
|
||||||
SidebarItemCategoryLink,
|
SidebarItemCategoryLink,
|
||||||
} from './types';
|
} from './types';
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
function normalizeCategoryLink(
|
function normalizeCategoryLink(
|
||||||
category: ProcessedSidebarItemCategory,
|
category: ProcessedSidebarItemCategory,
|
||||||
|
@ -88,7 +88,7 @@ export function postProcessSidebars(
|
||||||
sidebars: ProcessedSidebars,
|
sidebars: ProcessedSidebars,
|
||||||
params: SidebarProcessorParams,
|
params: SidebarProcessorParams,
|
||||||
): Sidebars {
|
): Sidebars {
|
||||||
return mapValues(sidebars, (sidebar) =>
|
return _.mapValues(sidebars, (sidebar) =>
|
||||||
sidebar.map((item) => postProcessSidebarItem(item, params)),
|
sidebar.map((item) => postProcessSidebarItem(item, params)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,14 @@ import type {
|
||||||
} from './types';
|
} from './types';
|
||||||
import {DefaultSidebarItemsGenerator} from './generator';
|
import {DefaultSidebarItemsGenerator} from './generator';
|
||||||
import {validateSidebars} from './validation';
|
import {validateSidebars} from './validation';
|
||||||
import {mapValues, memoize, pick} from 'lodash';
|
import _ from 'lodash';
|
||||||
import combinePromises from 'combine-promises';
|
import combinePromises from 'combine-promises';
|
||||||
import {isCategoryIndex} from '../docs';
|
import {isCategoryIndex} from '../docs';
|
||||||
|
|
||||||
function toSidebarItemsGeneratorDoc(
|
function toSidebarItemsGeneratorDoc(
|
||||||
doc: DocMetadataBase,
|
doc: DocMetadataBase,
|
||||||
): SidebarItemsGeneratorDoc {
|
): SidebarItemsGeneratorDoc {
|
||||||
return pick(doc, [
|
return _.pick(doc, [
|
||||||
'id',
|
'id',
|
||||||
'unversionedId',
|
'unversionedId',
|
||||||
'frontMatter',
|
'frontMatter',
|
||||||
|
@ -41,7 +41,7 @@ function toSidebarItemsGeneratorDoc(
|
||||||
function toSidebarItemsGeneratorVersion(
|
function toSidebarItemsGeneratorVersion(
|
||||||
version: VersionMetadata,
|
version: VersionMetadata,
|
||||||
): SidebarItemsGeneratorVersion {
|
): SidebarItemsGeneratorVersion {
|
||||||
return pick(version, ['versionName', 'contentPath']);
|
return _.pick(version, ['versionName', 'contentPath']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the generation of autogenerated sidebar items and other
|
// Handle the generation of autogenerated sidebar items and other
|
||||||
|
@ -60,7 +60,7 @@ async function processSidebar(
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
// Just a minor lazy transformation optimization
|
// Just a minor lazy transformation optimization
|
||||||
const getSidebarItemsGeneratorDocsAndVersion = memoize(() => ({
|
const getSidebarItemsGeneratorDocsAndVersion = _.memoize(() => ({
|
||||||
docs: docs.map(toSidebarItemsGeneratorDoc),
|
docs: docs.map(toSidebarItemsGeneratorDoc),
|
||||||
version: toSidebarItemsGeneratorVersion(version),
|
version: toSidebarItemsGeneratorVersion(version),
|
||||||
}));
|
}));
|
||||||
|
@ -117,7 +117,7 @@ export async function processSidebars(
|
||||||
params: SidebarProcessorParams,
|
params: SidebarProcessorParams,
|
||||||
): Promise<ProcessedSidebars> {
|
): Promise<ProcessedSidebars> {
|
||||||
const processedSidebars = await combinePromises(
|
const processedSidebars = await combinePromises(
|
||||||
mapValues(unprocessedSidebars, (unprocessedSidebar) =>
|
_.mapValues(unprocessedSidebars, (unprocessedSidebar) =>
|
||||||
processSidebar(unprocessedSidebar, categoriesMetadata, params),
|
processSidebar(unprocessedSidebar, categoriesMetadata, params),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,7 +19,7 @@ import type {
|
||||||
SidebarNavigationItem,
|
SidebarNavigationItem,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
import {mapValues, difference, uniq} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {getElementsAround, toMessageRelativeFilePath} from '@docusaurus/utils';
|
import {getElementsAround, toMessageRelativeFilePath} from '@docusaurus/utils';
|
||||||
import type {DocMetadataBase, DocNavLink} from '../types';
|
import type {DocMetadataBase, DocNavLink} from '../types';
|
||||||
|
|
||||||
|
@ -110,13 +110,13 @@ export function collectSidebarNavigation(
|
||||||
export function collectSidebarsDocIds(
|
export function collectSidebarsDocIds(
|
||||||
sidebars: Sidebars,
|
sidebars: Sidebars,
|
||||||
): Record<string, string[]> {
|
): Record<string, string[]> {
|
||||||
return mapValues(sidebars, collectSidebarDocIds);
|
return _.mapValues(sidebars, collectSidebarDocIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function collectSidebarsNavigations(
|
export function collectSidebarsNavigations(
|
||||||
sidebars: Sidebars,
|
sidebars: Sidebars,
|
||||||
): Record<string, SidebarNavigationItem[]> {
|
): Record<string, SidebarNavigationItem[]> {
|
||||||
return mapValues(sidebars, collectSidebarNavigation);
|
return _.mapValues(sidebars, collectSidebarNavigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SidebarNavigation = {
|
export type SidebarNavigation = {
|
||||||
|
@ -276,7 +276,7 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
||||||
|
|
||||||
function checkSidebarsDocIds(validDocIds: string[], sidebarFilePath: string) {
|
function checkSidebarsDocIds(validDocIds: string[], sidebarFilePath: string) {
|
||||||
const allSidebarDocIds = Object.values(sidebarNameToDocIds).flat();
|
const allSidebarDocIds = Object.values(sidebarNameToDocIds).flat();
|
||||||
const invalidSidebarDocIds = difference(allSidebarDocIds, validDocIds);
|
const invalidSidebarDocIds = _.difference(allSidebarDocIds, validDocIds);
|
||||||
if (invalidSidebarDocIds.length > 0) {
|
if (invalidSidebarDocIds.length > 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Invalid sidebar file at "${toMessageRelativeFilePath(
|
`Invalid sidebar file at "${toMessageRelativeFilePath(
|
||||||
|
@ -286,7 +286,7 @@ These sidebar document ids do not exist:
|
||||||
- ${invalidSidebarDocIds.sort().join('\n- ')}
|
- ${invalidSidebarDocIds.sort().join('\n- ')}
|
||||||
|
|
||||||
Available document ids are:
|
Available document ids are:
|
||||||
- ${uniq(validDocIds).sort().join('\n- ')}`,
|
- ${_.uniq(validDocIds).sort().join('\n- ')}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
|
|
||||||
import {groupTaggedItems} from '@docusaurus/utils';
|
import {groupTaggedItems} from '@docusaurus/utils';
|
||||||
import type {VersionTags, DocMetadata} from './types';
|
import type {VersionTags, DocMetadata} from './types';
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
export function getVersionTags(docs: DocMetadata[]): VersionTags {
|
export function getVersionTags(docs: DocMetadata[]): VersionTags {
|
||||||
const groups = groupTaggedItems(docs, (doc) => doc.tags);
|
const groups = groupTaggedItems(docs, (doc) => doc.tags);
|
||||||
return mapValues(groups, (group) => ({
|
return _.mapValues(groups, (group) => ({
|
||||||
name: group.tag.label,
|
name: group.tag.label,
|
||||||
docIds: group.items.map((item) => item.id),
|
docIds: group.items.map((item) => item.id),
|
||||||
permalink: group.tag.permalink,
|
permalink: group.tag.permalink,
|
||||||
|
|
|
@ -13,7 +13,7 @@ import type {
|
||||||
Sidebars,
|
Sidebars,
|
||||||
} from './sidebars/types';
|
} from './sidebars/types';
|
||||||
|
|
||||||
import {chain, mapValues, keyBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {
|
import {
|
||||||
collectSidebarCategories,
|
collectSidebarCategories,
|
||||||
transformSidebarItems,
|
transformSidebarItems,
|
||||||
|
@ -146,13 +146,15 @@ function getSidebarTranslationFileContent(
|
||||||
);
|
);
|
||||||
|
|
||||||
const links = collectSidebarLinks(sidebar);
|
const links = collectSidebarLinks(sidebar);
|
||||||
const linksContent: TranslationFileContent = chain(links)
|
const linksContent: TranslationFileContent = Object.fromEntries(
|
||||||
.keyBy((link) => `sidebar.${sidebarName}.link.${link.label}`)
|
links.map((link) => [
|
||||||
.mapValues((link) => ({
|
`sidebar.${sidebarName}.link.${link.label}`,
|
||||||
|
{
|
||||||
message: link.label,
|
message: link.label,
|
||||||
description: `The label for link ${link.label} in sidebar ${sidebarName}, linking to ${link.href}`,
|
description: `The label for link ${link.label} in sidebar ${sidebarName}, linking to ${link.href}`,
|
||||||
}))
|
},
|
||||||
.value();
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
return mergeTranslations([categoryContent, linksContent]);
|
return mergeTranslations([categoryContent, linksContent]);
|
||||||
}
|
}
|
||||||
|
@ -230,7 +232,7 @@ function translateSidebars(
|
||||||
version: LoadedVersion,
|
version: LoadedVersion,
|
||||||
sidebarsTranslations: TranslationFileContent,
|
sidebarsTranslations: TranslationFileContent,
|
||||||
): Sidebars {
|
): Sidebars {
|
||||||
return mapValues(version.sidebars, (sidebar, sidebarName) =>
|
return _.mapValues(version.sidebars, (sidebar, sidebarName) =>
|
||||||
translateSidebar({
|
translateSidebar({
|
||||||
sidebar,
|
sidebar,
|
||||||
sidebarName: getNormalizedSidebarName({
|
sidebarName: getNormalizedSidebarName({
|
||||||
|
@ -302,7 +304,7 @@ export function translateLoadedContent(
|
||||||
loadedContent: LoadedContent,
|
loadedContent: LoadedContent,
|
||||||
translationFiles: TranslationFile[],
|
translationFiles: TranslationFile[],
|
||||||
): LoadedContent {
|
): LoadedContent {
|
||||||
const translationFilesMap: Record<string, TranslationFile> = keyBy(
|
const translationFilesMap: Record<string, TranslationFile> = _.keyBy(
|
||||||
translationFiles,
|
translationFiles,
|
||||||
(f) => f.path,
|
(f) => f.path,
|
||||||
);
|
);
|
||||||
|
|
|
@ -28,7 +28,7 @@ import {
|
||||||
posixPath,
|
posixPath,
|
||||||
DEFAULT_PLUGIN_ID,
|
DEFAULT_PLUGIN_ID,
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import {difference} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {resolveSidebarPathOption} from './sidebars';
|
import {resolveSidebarPathOption} from './sidebars';
|
||||||
|
|
||||||
// retro-compatibility: no prefix for the default plugin id
|
// retro-compatibility: no prefix for the default plugin id
|
||||||
|
@ -486,7 +486,7 @@ function checkVersionsOptions(
|
||||||
`Docs option lastVersion: ${options.lastVersion} is invalid. ${availableVersionNamesMsg}`,
|
`Docs option lastVersion: ${options.lastVersion} is invalid. ${availableVersionNamesMsg}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const unknownVersionConfigNames = difference(
|
const unknownVersionConfigNames = _.difference(
|
||||||
Object.keys(options.versions),
|
Object.keys(options.versions),
|
||||||
availableVersionNames,
|
availableVersionNames,
|
||||||
);
|
);
|
||||||
|
@ -504,7 +504,7 @@ function checkVersionsOptions(
|
||||||
`Invalid docs option "onlyIncludeVersions": an empty array is not allowed, at least one version is needed.`,
|
`Invalid docs option "onlyIncludeVersions": an empty array is not allowed, at least one version is needed.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const unknownOnlyIncludeVersionNames = difference(
|
const unknownOnlyIncludeVersionNames = _.difference(
|
||||||
options.onlyIncludeVersions,
|
options.onlyIncludeVersions,
|
||||||
availableVersionNames,
|
availableVersionNames,
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {merge} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {ThemeConfigSchema, DEFAULT_CONFIG} from '../validateThemeConfig';
|
import {ThemeConfigSchema, DEFAULT_CONFIG} from '../validateThemeConfig';
|
||||||
|
|
||||||
import {normalizeThemeConfig} from '@docusaurus/utils-validation';
|
import {normalizeThemeConfig} from '@docusaurus/utils-validation';
|
||||||
|
@ -507,7 +507,7 @@ describe('themeConfig', () => {
|
||||||
|
|
||||||
describe('color mode config', () => {
|
describe('color mode config', () => {
|
||||||
const withDefaultValues = (colorMode) =>
|
const withDefaultValues = (colorMode) =>
|
||||||
merge({}, DEFAULT_CONFIG.colorMode, colorMode);
|
_.merge({}, DEFAULT_CONFIG.colorMode, colorMode);
|
||||||
|
|
||||||
test('minimal config', () => {
|
test('minimal config', () => {
|
||||||
const colorMode = {
|
const colorMode = {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import type {
|
||||||
SimpleFooter,
|
SimpleFooter,
|
||||||
} from '@docusaurus/theme-common';
|
} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
import {keyBy, chain} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {mergeTranslations} from '@docusaurus/utils';
|
import {mergeTranslations} from '@docusaurus/utils';
|
||||||
|
|
||||||
function getNavbarTranslationFile(navbar: Navbar): TranslationFileContent {
|
function getNavbarTranslationFile(navbar: Navbar): TranslationFileContent {
|
||||||
|
@ -30,15 +30,17 @@ function getNavbarTranslationFile(navbar: Navbar): TranslationFileContent {
|
||||||
|
|
||||||
const allNavbarItems = flattenNavbarItems(navbar.items);
|
const allNavbarItems = flattenNavbarItems(navbar.items);
|
||||||
|
|
||||||
const navbarItemsTranslations: TranslationFileContent = chain(
|
const navbarItemsTranslations: TranslationFileContent = Object.fromEntries(
|
||||||
allNavbarItems.filter((navbarItem) => !!navbarItem.label),
|
allNavbarItems
|
||||||
)
|
.filter((navbarItem) => navbarItem.label)
|
||||||
.keyBy((navbarItem) => `item.label.${navbarItem.label}`)
|
.map((navbarItem) => [
|
||||||
.mapValues((navbarItem) => ({
|
`item.label.${navbarItem.label}`,
|
||||||
|
{
|
||||||
message: navbarItem.label!,
|
message: navbarItem.label!,
|
||||||
description: `Navbar item with label ${navbarItem.label}`,
|
description: `Navbar item with label ${navbarItem.label}`,
|
||||||
}))
|
},
|
||||||
.value();
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
const titleTranslations: TranslationFileContent = navbar.title
|
const titleTranslations: TranslationFileContent = navbar.title
|
||||||
? {title: {message: navbar.title, description: 'The title in the navbar'}}
|
? {title: {message: navbar.title, description: 'The title in the navbar'}}
|
||||||
|
@ -78,33 +80,33 @@ function isMultiColumnFooterLinks(
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFooterTranslationFile(footer: Footer): TranslationFileContent {
|
function getFooterTranslationFile(footer: Footer): TranslationFileContent {
|
||||||
const footerLinkTitles: TranslationFileContent = chain(
|
const footerLinkTitles: TranslationFileContent = Object.fromEntries(
|
||||||
isMultiColumnFooterLinks(footer.links)
|
(isMultiColumnFooterLinks(footer.links)
|
||||||
? footer.links.filter((link) => !!link.title)
|
? footer.links.filter((link) => link.title)
|
||||||
: [],
|
: []
|
||||||
)
|
).map((link) => [
|
||||||
.keyBy((link) => `link.title.${link.title}`)
|
`link.title.${link.title}`,
|
||||||
.mapValues((link) => ({
|
{
|
||||||
message: link.title!,
|
message: link.title!,
|
||||||
description: `The title of the footer links column with title=${link.title} in the footer`,
|
description: `The title of the footer links column with title=${link.title} in the footer`,
|
||||||
}))
|
},
|
||||||
.value();
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
const footerLinkLabels: TranslationFileContent = chain(
|
const footerLinkLabels: TranslationFileContent = Object.fromEntries(
|
||||||
isMultiColumnFooterLinks(footer.links)
|
(isMultiColumnFooterLinks(footer.links)
|
||||||
? footer.links
|
? footer.links.flatMap((link) => link.items).filter((link) => link.label)
|
||||||
.flatMap((link) => link.items)
|
: footer.links.filter((link) => link.label)
|
||||||
.filter((link) => !!link.label)
|
).map((link) => [
|
||||||
: footer.links.filter((link) => !!link.label),
|
`link.item.label.${link.label}`,
|
||||||
)
|
{
|
||||||
.keyBy((linkItem) => `link.item.label.${linkItem.label}`)
|
message: link.label!,
|
||||||
.mapValues((linkItem) => ({
|
|
||||||
message: linkItem.label!,
|
|
||||||
description: `The label of footer link with label=${
|
description: `The label of footer link with label=${
|
||||||
linkItem.label
|
link.label
|
||||||
} linking to ${linkItem.to ?? linkItem.href}`,
|
} linking to ${link.to ?? link.href}`,
|
||||||
}))
|
},
|
||||||
.value();
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
const copyright: TranslationFileContent = footer.copyright
|
const copyright: TranslationFileContent = footer.copyright
|
||||||
? {
|
? {
|
||||||
|
@ -176,7 +178,7 @@ export function translateThemeConfig({
|
||||||
themeConfig: ThemeConfig;
|
themeConfig: ThemeConfig;
|
||||||
translationFiles: TranslationFile[];
|
translationFiles: TranslationFile[];
|
||||||
}): ThemeConfig {
|
}): ThemeConfig {
|
||||||
const translationFilesMap: Record<string, TranslationFile> = keyBy(
|
const translationFilesMap: Record<string, TranslationFile> = _.keyBy(
|
||||||
translationFiles,
|
translationFiles,
|
||||||
(f) => f.path,
|
(f) => f.path,
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {shuffle} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {listTagsByLetters} from '../tagsUtils';
|
import {listTagsByLetters} from '../tagsUtils';
|
||||||
|
|
||||||
describe('listTagsByLetters', () => {
|
describe('listTagsByLetters', () => {
|
||||||
|
@ -60,7 +60,9 @@ describe('listTagsByLetters', () => {
|
||||||
listTagsByLetters([tagzxy, tagdef, tagaaa, tag2, tagAbc, tag1]),
|
listTagsByLetters([tagzxy, tagdef, tagaaa, tag2, tagAbc, tag1]),
|
||||||
).toEqual(expectedResult);
|
).toEqual(expectedResult);
|
||||||
expect(
|
expect(
|
||||||
listTagsByLetters(shuffle([tagzxy, tagdef, tagaaa, tag2, tagAbc, tag1])),
|
listTagsByLetters(
|
||||||
|
_.shuffle([tagzxy, tagdef, tagaaa, tag2, tagAbc, tag1]),
|
||||||
|
),
|
||||||
).toEqual(expectedResult);
|
).toEqual(expectedResult);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,12 +12,12 @@ import {normalizeUrl} from '@docusaurus/utils';
|
||||||
import {readDefaultCodeTranslationMessages} from '@docusaurus/theme-translations';
|
import {readDefaultCodeTranslationMessages} from '@docusaurus/theme-translations';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import openSearchTemplate from './templates/opensearch';
|
import openSearchTemplate from './templates/opensearch';
|
||||||
import {memoize} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import type {LoadContext, Plugin} from '@docusaurus/types';
|
import type {LoadContext, Plugin} from '@docusaurus/types';
|
||||||
import type {ThemeConfig} from '@docusaurus/theme-search-algolia';
|
import type {ThemeConfig} from '@docusaurus/theme-search-algolia';
|
||||||
|
|
||||||
const getCompiledOpenSearchTemplate = memoize(() =>
|
const getCompiledOpenSearchTemplate = _.memoize(() =>
|
||||||
compile(openSearchTemplate.trim()),
|
compile(openSearchTemplate.trim()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import {extractThemeCodeMessages} from '../update';
|
import {extractThemeCodeMessages} from '../update';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
// Seems the 5s default timeout fails sometimes
|
// Seems the 5s default timeout fails sometimes
|
||||||
jest.setTimeout(15000);
|
jest.setTimeout(15000);
|
||||||
|
@ -37,7 +37,7 @@ describe('theme-translations package', () => {
|
||||||
.flat()
|
.flat()
|
||||||
.filter(([key]) => !key.endsWith('___DESCRIPTION')),
|
.filter(([key]) => !key.endsWith('___DESCRIPTION')),
|
||||||
);
|
);
|
||||||
const codeMessages = mapValues(
|
const codeMessages = _.mapValues(
|
||||||
await extractThemeCodeMessages(),
|
await extractThemeCodeMessages(),
|
||||||
(translation) => translation.message,
|
(translation) => translation.message,
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
const logger = require('@docusaurus/logger').default;
|
const logger = require('@docusaurus/logger').default;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const {mapValues, pickBy, difference, orderBy} = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
||||||
const LocalesDirPath = path.join(__dirname, 'locales');
|
const LocalesDirPath = path.join(__dirname, 'locales');
|
||||||
const Themes = [
|
const Themes = [
|
||||||
|
@ -80,7 +80,7 @@ function removeDescriptionSuffix(key) {
|
||||||
*/
|
*/
|
||||||
function sortObjectKeys(obj) {
|
function sortObjectKeys(obj) {
|
||||||
let keys = Object.keys(obj);
|
let keys = Object.keys(obj);
|
||||||
keys = orderBy(keys, [(k) => removeDescriptionSuffix(k)]);
|
keys = _.orderBy(keys, [(k) => removeDescriptionSuffix(k)]);
|
||||||
return keys.reduce((acc, key) => {
|
return keys.reduce((acc, key) => {
|
||||||
acc[key] = obj[key];
|
acc[key] = obj[key];
|
||||||
return acc;
|
return acc;
|
||||||
|
@ -179,18 +179,18 @@ const DescriptionSuffix = '___DESCRIPTION';
|
||||||
*/
|
*/
|
||||||
async function updateBaseFile(baseFile, targetDirs) {
|
async function updateBaseFile(baseFile, targetDirs) {
|
||||||
const baseMessagesWithDescriptions = await readMessagesFile(baseFile);
|
const baseMessagesWithDescriptions = await readMessagesFile(baseFile);
|
||||||
const baseMessages = pickBy(
|
const baseMessages = _.pickBy(
|
||||||
baseMessagesWithDescriptions,
|
baseMessagesWithDescriptions,
|
||||||
(_, key) => !key.endsWith(DescriptionSuffix),
|
(v, key) => !key.endsWith(DescriptionSuffix),
|
||||||
);
|
);
|
||||||
|
|
||||||
const codeExtractedTranslations = await extractThemeCodeMessages(targetDirs);
|
const codeExtractedTranslations = await extractThemeCodeMessages(targetDirs);
|
||||||
const codeMessages = mapValues(
|
const codeMessages = _.mapValues(
|
||||||
codeExtractedTranslations,
|
codeExtractedTranslations,
|
||||||
(translation) => translation.message,
|
(translation) => translation.message,
|
||||||
);
|
);
|
||||||
|
|
||||||
const unknownMessages = difference(
|
const unknownMessages = _.difference(
|
||||||
Object.keys(baseMessages),
|
Object.keys(baseMessages),
|
||||||
Object.keys(codeMessages),
|
Object.keys(codeMessages),
|
||||||
);
|
);
|
||||||
|
@ -236,7 +236,7 @@ They won't be removed automatically, so do the cleanup manually if necessary! co
|
||||||
async function updateLocaleCodeTranslations(localeFile, baseFileMessages) {
|
async function updateLocaleCodeTranslations(localeFile, baseFileMessages) {
|
||||||
const localeFileMessages = await readMessagesFile(localeFile);
|
const localeFileMessages = await readMessagesFile(localeFile);
|
||||||
|
|
||||||
const unknownMessages = difference(
|
const unknownMessages = _.difference(
|
||||||
Object.keys(localeFileMessages),
|
Object.keys(localeFileMessages),
|
||||||
Object.keys(baseFileMessages),
|
Object.keys(baseFileMessages),
|
||||||
);
|
);
|
||||||
|
|
|
@ -28,7 +28,7 @@ import {
|
||||||
posixPath,
|
posixPath,
|
||||||
readOutputHTMLFile,
|
readOutputHTMLFile,
|
||||||
} from '../index';
|
} from '../index';
|
||||||
import {sum} from 'lodash';
|
import _ from 'lodash';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ describe('mapAsyncSequential', () => {
|
||||||
|
|
||||||
const timeTotal = timeAfter - timeBefore;
|
const timeTotal = timeAfter - timeBefore;
|
||||||
|
|
||||||
const totalTimeouts = sum(Object.values(itemToTimeout));
|
const totalTimeouts = _.sum(Object.values(itemToTimeout));
|
||||||
expect(timeTotal).toBeGreaterThanOrEqual(totalTimeouts - 20);
|
expect(timeTotal).toBeGreaterThanOrEqual(totalTimeouts - 20);
|
||||||
|
|
||||||
expect(itemMapStartsAt['1']).toBeGreaterThanOrEqual(0);
|
expect(itemMapStartsAt['1']).toBeGreaterThanOrEqual(0);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {createHash} from 'crypto';
|
import {createHash} from 'crypto';
|
||||||
import {kebabCase} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {shortName, isNameTooLong} from './pathUtils';
|
import {shortName, isNameTooLong} from './pathUtils';
|
||||||
|
|
||||||
export function md5Hash(str: string): string {
|
export function md5Hash(str: string): string {
|
||||||
|
@ -29,9 +29,9 @@ export function docuHash(str: string): string {
|
||||||
return 'index';
|
return 'index';
|
||||||
}
|
}
|
||||||
const shortHash = simpleHash(str, 3);
|
const shortHash = simpleHash(str, 3);
|
||||||
const parsedPath = `${kebabCase(str)}-${shortHash}`;
|
const parsedPath = `${_.kebabCase(str)}-${shortHash}`;
|
||||||
if (isNameTooLong(parsedPath)) {
|
if (isNameTooLong(parsedPath)) {
|
||||||
return `${shortName(kebabCase(str))}-${shortHash}`;
|
return `${shortName(_.kebabCase(str))}-${shortHash}`;
|
||||||
}
|
}
|
||||||
return parsedPath;
|
return parsedPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {createHash} from 'crypto';
|
import {createHash} from 'crypto';
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {URL} from 'url';
|
import {URL} from 'url';
|
||||||
import type {
|
import type {
|
||||||
|
@ -361,7 +361,7 @@ export function updateTranslationFileMessages(
|
||||||
): TranslationFile {
|
): TranslationFile {
|
||||||
return {
|
return {
|
||||||
...translationFile,
|
...translationFile,
|
||||||
content: mapValues(translationFile.content, (translation) => ({
|
content: _.mapValues(translationFile.content, (translation) => ({
|
||||||
...translation,
|
...translation,
|
||||||
message: updateMessage(translation.message),
|
message: updateMessage(translation.message),
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {kebabCase, uniq, uniqBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {normalizeUrl} from './urlUtils';
|
import {normalizeUrl} from './urlUtils';
|
||||||
|
|
||||||
export type Tag = {
|
export type Tag = {
|
||||||
|
@ -22,7 +22,7 @@ export function normalizeFrontMatterTag(
|
||||||
function toTagObject(tagString: string): Tag {
|
function toTagObject(tagString: string): Tag {
|
||||||
return {
|
return {
|
||||||
label: tagString,
|
label: tagString,
|
||||||
permalink: kebabCase(tagString),
|
permalink: _.kebabCase(tagString),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ export function normalizeFrontMatterTags(
|
||||||
normalizeFrontMatterTag(tagsPath, tag),
|
normalizeFrontMatterTag(tagsPath, tag),
|
||||||
);
|
);
|
||||||
|
|
||||||
return uniqBy(tags, (tag) => tag.permalink);
|
return _.uniqBy(tags, (tag) => tag.permalink);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TaggedItemGroup<Item> = {
|
export type TaggedItemGroup<Item> = {
|
||||||
|
@ -98,7 +98,7 @@ export function groupTaggedItems<Item>(
|
||||||
// If user add twice the same tag to a md doc (weird but possible),
|
// If user add twice the same tag to a md doc (weird but possible),
|
||||||
// we don't want the item to appear twice in the list...
|
// we don't want the item to appear twice in the list...
|
||||||
Object.values(result).forEach((group) => {
|
Object.values(result).forEach((group) => {
|
||||||
group.items = uniq(group.items);
|
group.items = _.uniq(group.items);
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -25,13 +25,13 @@ import {
|
||||||
} from './LinksCollector';
|
} from './LinksCollector';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import {memoize} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {Locals} from '@slorber/static-site-generator-webpack-plugin';
|
import type {Locals} from '@slorber/static-site-generator-webpack-plugin';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const packageJson = require('../../package.json');
|
const packageJson = require('../../package.json');
|
||||||
|
|
||||||
const getCompiledSSRTemplate = memoize((template: string) =>
|
const getCompiledSSRTemplate = _.memoize((template: string) =>
|
||||||
eta.compile(template.trim(), {
|
eta.compile(template.trim(), {
|
||||||
rmWhitespace: true,
|
rmWhitespace: true,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -10,7 +10,7 @@ import logger from '@docusaurus/logger';
|
||||||
import chokidar from 'chokidar';
|
import chokidar from 'chokidar';
|
||||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {debounce} from 'lodash';
|
import _ from 'lodash';
|
||||||
import openBrowser from 'react-dev-utils/openBrowser';
|
import openBrowser from 'react-dev-utils/openBrowser';
|
||||||
import {prepareUrls} from 'react-dev-utils/WebpackDevServerUtils';
|
import {prepareUrls} from 'react-dev-utils/WebpackDevServerUtils';
|
||||||
import evalSourceMapMiddleware from 'react-dev-utils/evalSourceMapMiddleware';
|
import evalSourceMapMiddleware from 'react-dev-utils/evalSourceMapMiddleware';
|
||||||
|
@ -63,7 +63,7 @@ export default async function start(
|
||||||
logger.success`Docusaurus website is running at path=${openUrl}.`;
|
logger.success`Docusaurus website is running at path=${openUrl}.`;
|
||||||
|
|
||||||
// Reload files processing.
|
// Reload files processing.
|
||||||
const reload = debounce(() => {
|
const reload = _.debounce(() => {
|
||||||
loadSite()
|
loadSite()
|
||||||
.then(({baseUrl: newBaseUrl}) => {
|
.then(({baseUrl: newBaseUrl}) => {
|
||||||
const newOpenUrl = normalizeUrl([urls.localUrlForBrowser, newBaseUrl]);
|
const newOpenUrl = normalizeUrl([urls.localUrlForBrowser, newBaseUrl]);
|
||||||
|
|
|
@ -13,14 +13,12 @@ import {
|
||||||
} from '../i18n';
|
} from '../i18n';
|
||||||
import {DEFAULT_I18N_CONFIG} from '../configValidation';
|
import {DEFAULT_I18N_CONFIG} from '../configValidation';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {chain, identity} from 'lodash';
|
|
||||||
import type {I18nConfig} from '@docusaurus/types';
|
import type {I18nConfig} from '@docusaurus/types';
|
||||||
|
|
||||||
function testLocaleConfigsFor(locales: string[]) {
|
function testLocaleConfigsFor(locales: string[]) {
|
||||||
return chain(locales)
|
return Object.fromEntries(
|
||||||
.keyBy(identity)
|
locales.map((locale) => [locale, getDefaultLocaleConfig(locale)]),
|
||||||
.mapValues(getDefaultLocaleConfig)
|
);
|
||||||
.value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadI18nTest(i18nConfig: I18nConfig, locale?: string) {
|
function loadI18nTest(i18nConfig: I18nConfig, locale?: string) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
type RouteConfig as RRRouteConfig,
|
type RouteConfig as RRRouteConfig,
|
||||||
} from 'react-router-config';
|
} from 'react-router-config';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {mapValues, pickBy, countBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {RouteConfig, ReportingSeverity} from '@docusaurus/types';
|
import type {RouteConfig, ReportingSeverity} from '@docusaurus/types';
|
||||||
import {
|
import {
|
||||||
removePrefix,
|
removePrefix,
|
||||||
|
@ -84,12 +84,12 @@ export function getAllBrokenLinks({
|
||||||
}): Record<string, BrokenLink[]> {
|
}): Record<string, BrokenLink[]> {
|
||||||
const filteredRoutes = filterIntermediateRoutes(routes);
|
const filteredRoutes = filterIntermediateRoutes(routes);
|
||||||
|
|
||||||
const allBrokenLinks = mapValues(allCollectedLinks, (pageLinks, pagePath) =>
|
const allBrokenLinks = _.mapValues(allCollectedLinks, (pageLinks, pagePath) =>
|
||||||
getPageBrokenLinks({pageLinks, pagePath, routes: filteredRoutes}),
|
getPageBrokenLinks({pageLinks, pagePath, routes: filteredRoutes}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// remove pages without any broken link
|
// remove pages without any broken link
|
||||||
return pickBy(allBrokenLinks, (brokenLinks) => brokenLinks.length > 0);
|
return _.pickBy(allBrokenLinks, (brokenLinks) => brokenLinks.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBrokenLinksErrorMessage(
|
export function getBrokenLinksErrorMessage(
|
||||||
|
@ -126,7 +126,7 @@ export function getBrokenLinksErrorMessage(
|
||||||
brokenLinks.map((brokenLink) => ({pagePage, brokenLink})),
|
brokenLinks.map((brokenLink) => ({pagePage, brokenLink})),
|
||||||
);
|
);
|
||||||
|
|
||||||
const countedBrokenLinks = countBy(
|
const countedBrokenLinks = _.countBy(
|
||||||
flatList,
|
flatList,
|
||||||
(item) => item.brokenLink.link,
|
(item) => item.brokenLink.link,
|
||||||
);
|
);
|
||||||
|
@ -197,7 +197,7 @@ export async function filterExistingFileLinks({
|
||||||
return filePathsToTry.some(isExistingFile);
|
return filePathsToTry.some(isExistingFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapValues(allCollectedLinks, (links) =>
|
return _.mapValues(allCollectedLinks, (links) =>
|
||||||
links.filter((link) => !linkFileExists(link)),
|
links.filter((link) => !linkFileExists(link)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {isPlainObject} from 'lodash';
|
|
||||||
import type {HtmlTagObject} from '@docusaurus/types';
|
import type {HtmlTagObject} from '@docusaurus/types';
|
||||||
import htmlTags from 'html-tags';
|
import htmlTags from 'html-tags';
|
||||||
import voidHtmlTags from 'html-tags/void';
|
import voidHtmlTags from 'html-tags/void';
|
||||||
import escapeHTML from 'escape-html';
|
import escapeHTML from 'escape-html';
|
||||||
|
|
||||||
function assertIsHtmlTagObject(val: unknown): asserts val is HtmlTagObject {
|
function assertIsHtmlTagObject(val: unknown): asserts val is HtmlTagObject {
|
||||||
if (!isPlainObject(val)) {
|
if (typeof val !== 'object' || !val) {
|
||||||
throw new Error(`"${val}" is not a valid HTML tag object.`);
|
throw new Error(`"${val}" is not a valid HTML tag object.`);
|
||||||
}
|
}
|
||||||
if (typeof (val as HtmlTagObject).tagName !== 'string') {
|
if (typeof (val as HtmlTagObject).tagName !== 'string') {
|
||||||
|
|
|
@ -37,7 +37,7 @@ import {
|
||||||
readCodeTranslationFileContent,
|
readCodeTranslationFileContent,
|
||||||
getPluginsDefaultCodeTranslationMessages,
|
getPluginsDefaultCodeTranslationMessages,
|
||||||
} from './translations/translations';
|
} from './translations/translations';
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {RuleSetRule} from 'webpack';
|
import type {RuleSetRule} from 'webpack';
|
||||||
import admonitions from 'remark-admonitions';
|
import admonitions from 'remark-admonitions';
|
||||||
import {createRequire} from 'module';
|
import {createRequire} from 'module';
|
||||||
|
@ -111,7 +111,7 @@ export async function loadContext(
|
||||||
})) ?? {};
|
})) ?? {};
|
||||||
|
|
||||||
// We only need key->message for code translations
|
// We only need key->message for code translations
|
||||||
const codeTranslations = mapValues(
|
const codeTranslations = _.mapValues(
|
||||||
codeTranslationFileContent,
|
codeTranslationFileContent,
|
||||||
(value) => value.message,
|
(value) => value.message,
|
||||||
);
|
);
|
||||||
|
|
|
@ -21,7 +21,7 @@ import type {
|
||||||
} from '@docusaurus/types';
|
} from '@docusaurus/types';
|
||||||
import initPlugins from './init';
|
import initPlugins from './init';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import {chain} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {localizePluginTranslationFile} from '../translations/translations';
|
import {localizePluginTranslationFile} from '../translations/translations';
|
||||||
import applyRouteTrailingSlash from './applyRouteTrailingSlash';
|
import applyRouteTrailingSlash from './applyRouteTrailingSlash';
|
||||||
|
|
||||||
|
@ -121,10 +121,10 @@ export async function loadPlugins({
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const allContent: AllContent = chain(loadedPlugins)
|
const allContent: AllContent = _.chain(loadedPlugins)
|
||||||
.groupBy((item) => item.name)
|
.groupBy((item) => item.name)
|
||||||
.mapValues((nameItems) =>
|
.mapValues((nameItems) =>
|
||||||
chain(nameItems)
|
_.chain(nameItems)
|
||||||
.groupBy((item) => item.options.id ?? DEFAULT_PLUGIN_ID)
|
.groupBy((item) => item.options.id ?? DEFAULT_PLUGIN_ID)
|
||||||
.mapValues((idItems) => idItems[0].content)
|
.mapValues((idItems) => idItems[0].content)
|
||||||
.value(),
|
.value(),
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {groupBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils';
|
import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils';
|
||||||
import type {InitializedPlugin} from '@docusaurus/types';
|
import type {InitializedPlugin} from '@docusaurus/types';
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ import type {InitializedPlugin} from '@docusaurus/types';
|
||||||
export function ensureUniquePluginInstanceIds(
|
export function ensureUniquePluginInstanceIds(
|
||||||
plugins: InitializedPlugin[],
|
plugins: InitializedPlugin[],
|
||||||
): void {
|
): void {
|
||||||
const pluginsByName = groupBy(plugins, (p) => p.name);
|
const pluginsByName = _.groupBy(plugins, (p) => p.name);
|
||||||
Object.entries(pluginsByName).forEach(([pluginName, pluginInstances]) => {
|
Object.entries(pluginsByName).forEach(([pluginName, pluginInstances]) => {
|
||||||
const pluginInstancesById = groupBy(
|
const pluginInstancesById = _.groupBy(
|
||||||
pluginInstances,
|
pluginInstances,
|
||||||
(p) => p.options.id ?? DEFAULT_PLUGIN_ID,
|
(p) => p.options.id ?? DEFAULT_PLUGIN_ID,
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
simpleHash,
|
simpleHash,
|
||||||
escapePath,
|
escapePath,
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import {has, isPlainObject, isString} from 'lodash';
|
|
||||||
import {stringify} from 'querystring';
|
import {stringify} from 'querystring';
|
||||||
import type {
|
import type {
|
||||||
ChunkRegistry,
|
ChunkRegistry,
|
||||||
|
@ -85,10 +84,15 @@ const RoutesImportsCode = [
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
function isModule(value: unknown): value is Module {
|
function isModule(value: unknown): value is Module {
|
||||||
if (isString(value)) {
|
if (typeof value === 'string') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isPlainObject(value) && has(value, '__import') && has(value, 'path')) {
|
if (
|
||||||
|
typeof value === 'object' &&
|
||||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
(value as Record<string, unknown>)?.__import &&
|
||||||
|
(value as Record<string, unknown>)?.path
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -137,11 +141,10 @@ export default async function loadRoutes(
|
||||||
...props
|
...props
|
||||||
} = routeConfig;
|
} = routeConfig;
|
||||||
|
|
||||||
if (!isString(routePath) || !component) {
|
if (typeof routePath !== 'string' || !component) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Invalid route config: path must be a string and component is required.\n${JSON.stringify(
|
`Invalid route config: path must be a string and component is required.
|
||||||
routeConfig,
|
${JSON.stringify(routeConfig)}`,
|
||||||
)}`,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {fileToPath, posixPath, normalizeUrl, Globby} from '@docusaurus/utils';
|
import {fileToPath, posixPath, normalizeUrl, Globby} from '@docusaurus/utils';
|
||||||
import type {ThemeAliases} from '@docusaurus/types';
|
import type {ThemeAliases} from '@docusaurus/types';
|
||||||
import {sortBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
// Order of Webpack aliases is important because one alias can shadow another
|
// Order of Webpack aliases is important because one alias can shadow another
|
||||||
// This ensure @theme/NavbarItem alias is after @theme/NavbarItem/LocaleDropdown
|
// This ensure @theme/NavbarItem alias is after @theme/NavbarItem/LocaleDropdown
|
||||||
|
@ -17,7 +17,7 @@ import {sortBy} from 'lodash';
|
||||||
// See https://github.com/facebook/docusaurus/issues/5382
|
// See https://github.com/facebook/docusaurus/issues/5382
|
||||||
export function sortAliases(aliases: ThemeAliases): ThemeAliases {
|
export function sortAliases(aliases: ThemeAliases): ThemeAliases {
|
||||||
// Alphabetical order by default
|
// Alphabetical order by default
|
||||||
const entries = sortBy(Object.entries(aliases), ([alias]) => alias);
|
const entries = _.sortBy(Object.entries(aliases), ([alias]) => alias);
|
||||||
// @theme/NavbarItem should be after @theme/NavbarItem/LocaleDropdown
|
// @theme/NavbarItem should be after @theme/NavbarItem/LocaleDropdown
|
||||||
entries.sort(([alias1], [alias2]) =>
|
entries.sort(([alias1], [alias2]) =>
|
||||||
alias1.includes(`${alias2}/`) ? -1 : 0,
|
alias1.includes(`${alias2}/`) ? -1 : 0,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {mapValues, difference} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {
|
import type {
|
||||||
TranslationFileContent,
|
TranslationFileContent,
|
||||||
TranslationFile,
|
TranslationFile,
|
||||||
|
@ -75,7 +75,7 @@ function mergeTranslationFileContent({
|
||||||
options: WriteTranslationsOptions;
|
options: WriteTranslationsOptions;
|
||||||
}): TranslationFileContent {
|
}): TranslationFileContent {
|
||||||
// Apply messagePrefix to all messages
|
// Apply messagePrefix to all messages
|
||||||
const newContentTransformed = mapValues(newContent, (value) => ({
|
const newContentTransformed = _.mapValues(newContent, (value) => ({
|
||||||
...value,
|
...value,
|
||||||
message: `${options.messagePrefix ?? ''}${value.message}`,
|
message: `${options.messagePrefix ?? ''}${value.message}`,
|
||||||
}));
|
}));
|
||||||
|
@ -110,7 +110,7 @@ export async function writeTranslationFileContent({
|
||||||
const existingContent = await readTranslationFileContent(filePath);
|
const existingContent = await readTranslationFileContent(filePath);
|
||||||
|
|
||||||
// Warn about potential legacy keys
|
// Warn about potential legacy keys
|
||||||
const unknownKeys = difference(
|
const unknownKeys = _.difference(
|
||||||
Object.keys(existingContent ?? {}),
|
Object.keys(existingContent ?? {}),
|
||||||
Object.keys(newContent),
|
Object.keys(newContent),
|
||||||
);
|
);
|
||||||
|
@ -276,7 +276,7 @@ export function applyDefaultCodeTranslations({
|
||||||
extractedCodeTranslations: Record<string, TranslationMessage>;
|
extractedCodeTranslations: Record<string, TranslationMessage>;
|
||||||
defaultCodeMessages: Record<string, string>;
|
defaultCodeMessages: Record<string, string>;
|
||||||
}): Record<string, TranslationMessage> {
|
}): Record<string, TranslationMessage> {
|
||||||
const unusedDefaultCodeMessages = difference(
|
const unusedDefaultCodeMessages = _.difference(
|
||||||
Object.keys(defaultCodeMessages),
|
Object.keys(defaultCodeMessages),
|
||||||
Object.keys(extractedCodeTranslations),
|
Object.keys(extractedCodeTranslations),
|
||||||
);
|
);
|
||||||
|
@ -285,7 +285,7 @@ export function applyDefaultCodeTranslations({
|
||||||
Please report this Docusaurus issue. name=${unusedDefaultCodeMessages}`;
|
Please report this Docusaurus issue. name=${unusedDefaultCodeMessages}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapValues(
|
return _.mapValues(
|
||||||
extractedCodeTranslations,
|
extractedCodeTranslations,
|
||||||
(messageTranslation, messageId) => ({
|
(messageTranslation, messageId) => ({
|
||||||
...messageTranslation,
|
...messageTranslation,
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
} from '../base';
|
} from '../base';
|
||||||
import * as utils from '@docusaurus/utils/lib/webpackUtils';
|
import * as utils from '@docusaurus/utils/lib/webpackUtils';
|
||||||
import {posixPath} from '@docusaurus/utils';
|
import {posixPath} from '@docusaurus/utils';
|
||||||
import {mapValues} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {Props, ThemeAliases} from '@docusaurus/types';
|
import type {Props, ThemeAliases} from '@docusaurus/types';
|
||||||
|
|
||||||
describe('babel transpilation exclude logic', () => {
|
describe('babel transpilation exclude logic', () => {
|
||||||
|
@ -70,7 +70,7 @@ describe('babel transpilation exclude logic', () => {
|
||||||
describe('getDocusaurusAliases()', () => {
|
describe('getDocusaurusAliases()', () => {
|
||||||
test('return appropriate webpack aliases', () => {
|
test('return appropriate webpack aliases', () => {
|
||||||
// using relative paths makes tests work everywhere
|
// using relative paths makes tests work everywhere
|
||||||
const relativeDocusaurusAliases = mapValues(
|
const relativeDocusaurusAliases = _.mapValues(
|
||||||
getDocusaurusAliases(),
|
getDocusaurusAliases(),
|
||||||
(aliasValue) => posixPath(path.relative(__dirname, aliasValue)),
|
(aliasValue) => posixPath(path.relative(__dirname, aliasValue)),
|
||||||
);
|
);
|
||||||
|
@ -125,7 +125,7 @@ describe('base webpack config', () => {
|
||||||
const aliases: ThemeAliases =
|
const aliases: ThemeAliases =
|
||||||
createBaseConfig(props, true).resolve?.alias ?? {};
|
createBaseConfig(props, true).resolve?.alias ?? {};
|
||||||
// Make aliases relative so that test work on all computers
|
// Make aliases relative so that test work on all computers
|
||||||
const relativeAliases = mapValues(aliases, (a) =>
|
const relativeAliases = _.mapValues(aliases, (a) =>
|
||||||
posixPath(path.relative(props.siteDir, a)),
|
posixPath(path.relative(props.siteDir, a)),
|
||||||
);
|
);
|
||||||
expect(relativeAliases).toMatchSnapshot();
|
expect(relativeAliases).toMatchSnapshot();
|
||||||
|
|
|
@ -31,7 +31,7 @@ import type {
|
||||||
ConfigureWebpackUtils,
|
ConfigureWebpackUtils,
|
||||||
} from '@docusaurus/types';
|
} from '@docusaurus/types';
|
||||||
import {BABEL_CONFIG_FILE_NAME} from '@docusaurus/utils';
|
import {BABEL_CONFIG_FILE_NAME} from '@docusaurus/utils';
|
||||||
import {memoize} from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
// Utility method to get style loaders
|
// Utility method to get style loaders
|
||||||
export function getStyleLoaders(
|
export function getStyleLoaders(
|
||||||
|
@ -164,7 +164,7 @@ export const getCustomizableJSLoader =
|
||||||
: jsLoader(isServer);
|
: jsLoader(isServer);
|
||||||
|
|
||||||
// TODO remove this before end of 2021?
|
// TODO remove this before end of 2021?
|
||||||
const warnBabelLoaderOnce = memoize(() => {
|
const warnBabelLoaderOnce = _.memoize(() => {
|
||||||
logger.warn`Docusaurus plans to support multiple JS loader strategies (Babel, esbuild...): code=${'getBabelLoader(isServer)'} is now deprecated in favor of code=${'getJSLoader(isServer)'}.`;
|
logger.warn`Docusaurus plans to support multiple JS loader strategies (Babel, esbuild...): code=${'getBabelLoader(isServer)'} is now deprecated in favor of code=${'getJSLoader(isServer)'}.`;
|
||||||
});
|
});
|
||||||
const getBabelLoaderDeprecated = function getBabelLoaderDeprecated(
|
const getBabelLoaderDeprecated = function getBabelLoaderDeprecated(
|
||||||
|
@ -176,7 +176,7 @@ const getBabelLoaderDeprecated = function getBabelLoaderDeprecated(
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO remove this before end of 2021 ?
|
// TODO remove this before end of 2021 ?
|
||||||
const warnCacheLoaderOnce = memoize(() => {
|
const warnCacheLoaderOnce = _.memoize(() => {
|
||||||
logger.warn`Docusaurus uses Webpack 5 and code=${'getCacheLoader()'} usage is now deprecated.`;
|
logger.warn`Docusaurus uses Webpack 5 and code=${'getCacheLoader()'} usage is now deprecated.`;
|
||||||
});
|
});
|
||||||
function getCacheLoaderDeprecated() {
|
function getCacheLoaderDeprecated() {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {sortBy} from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {Palette} from 'node-vibrant/lib/color';
|
import type {Palette} from 'node-vibrant/lib/color';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +29,7 @@ const toPalette = (swatch: Palette): string[] => {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}, [] as {popularity: number; hex: string}[]);
|
}, [] as {popularity: number; hex: string}[]);
|
||||||
palette = sortBy(palette, ['popularity']);
|
palette = _.sortBy(palette, ['popularity']);
|
||||||
return palette.map((color) => color.hex).reverse();
|
return palette.map((color) => color.hex).reverse();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue