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