mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-06 10:20:09 +02:00
refactor(utils): reorganize functions; move authors file resolution to utils (#6229)
* refactor(utils): reorganize functions; move authors file resolution to utils * More refactor
This commit is contained in:
parent
7adc1c0cdb
commit
24d65d9bdd
39 changed files with 533 additions and 747 deletions
|
@ -8,8 +8,7 @@
|
|||
import logger from '@docusaurus/logger';
|
||||
import path from 'path';
|
||||
import {createHash} from 'crypto';
|
||||
import {camelCase, mapValues} from 'lodash';
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
import {mapValues} from 'lodash';
|
||||
import fs from 'fs-extra';
|
||||
import {URL} from 'url';
|
||||
import {
|
||||
|
@ -20,30 +19,21 @@ import {
|
|||
|
||||
import resolvePathnameUnsafe from 'resolve-pathname';
|
||||
|
||||
import {posixPath as posixPathImport} from './posixPath';
|
||||
import {simpleHash, docuHash} from './hashUtils';
|
||||
import {normalizeUrl} from './normalizeUrl';
|
||||
import {DEFAULT_PLUGIN_ID} from './constants';
|
||||
|
||||
export * from './constants';
|
||||
export * from './mdxUtils';
|
||||
export * from './normalizeUrl';
|
||||
export * from './urlUtils';
|
||||
export * from './tags';
|
||||
|
||||
export const posixPath = posixPathImport;
|
||||
|
||||
export * from './markdownParser';
|
||||
export * from './markdownLinks';
|
||||
export * from './escapePath';
|
||||
export * from './slugger';
|
||||
export {md5Hash, simpleHash, docuHash} from './hashUtils';
|
||||
export {
|
||||
Globby,
|
||||
GlobExcludeDefault,
|
||||
createMatcher,
|
||||
createAbsoluteFilePathMatcher,
|
||||
} from './globUtils';
|
||||
export * from './pathUtils';
|
||||
export * from './hashUtils';
|
||||
export * from './globUtils';
|
||||
export * from './webpackUtils';
|
||||
export * from './dataFileUtils';
|
||||
|
||||
const fileHash = new Map();
|
||||
export async function generate(
|
||||
|
@ -80,18 +70,6 @@ export async function generate(
|
|||
}
|
||||
}
|
||||
|
||||
export function objectWithKeySorted<T>(
|
||||
obj: Record<string, T>,
|
||||
): Record<string, T> {
|
||||
// https://github.com/lodash/lodash/issues/1459#issuecomment-460941233
|
||||
return Object.keys(obj)
|
||||
.sort()
|
||||
.reduce((acc: Record<string, T>, key: string) => {
|
||||
acc[key] = obj[key];
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
const indexRE = /(^|.*\/)index\.(md|mdx|js|jsx|ts|tsx)$/i;
|
||||
const extRE = /\.(md|mdx|js|jsx|ts|tsx)$/;
|
||||
|
||||
|
@ -113,37 +91,6 @@ export function encodePath(userpath: string): string {
|
|||
.join('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert first string character to the upper case.
|
||||
* E.g: docusaurus -> Docusaurus
|
||||
*/
|
||||
export function upperFirst(str: string): string {
|
||||
return str ? str.charAt(0).toUpperCase() + str.slice(1) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate unique React Component Name.
|
||||
* E.g: /foo-bar -> FooBar096
|
||||
*/
|
||||
export function genComponentName(pagePath: string): string {
|
||||
if (pagePath === '/') {
|
||||
return 'index';
|
||||
}
|
||||
const pageHash = docuHash(pagePath);
|
||||
return upperFirst(camelCase(pageHash));
|
||||
}
|
||||
|
||||
// When you want to display a path in a message/warning/error,
|
||||
// it's more convenient to:
|
||||
// - make it relative to cwd()
|
||||
// - convert to posix (ie not using windows \ path separator)
|
||||
// This way, Jest tests can run more reliably on any computer/CI
|
||||
// on both Unix/Windows
|
||||
// For Windows users this is not perfect (as they see / instead of \) but it's probably good enough
|
||||
export function toMessageRelativeFilePath(filePath: string): string {
|
||||
return posixPath(path.relative(process.cwd(), filePath));
|
||||
}
|
||||
|
||||
const chunkNameCache = new Map();
|
||||
/**
|
||||
* Generate unique chunk name given a module path.
|
||||
|
@ -172,52 +119,6 @@ export function genChunkName(
|
|||
return chunkName;
|
||||
}
|
||||
|
||||
// Too dynamic
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
||||
export function idx(target: any, keyPaths?: string | (string | number)[]): any {
|
||||
return (
|
||||
target &&
|
||||
keyPaths &&
|
||||
(Array.isArray(keyPaths)
|
||||
? keyPaths.reduce((obj, key) => obj && obj[key], target)
|
||||
: target[keyPaths])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a filepath and dirpath, get the first directory.
|
||||
*/
|
||||
export function getSubFolder(file: string, refDir: string): string | null {
|
||||
const separator = escapeStringRegexp(path.sep);
|
||||
const baseDir = escapeStringRegexp(path.basename(refDir));
|
||||
const regexSubFolder = new RegExp(
|
||||
`${baseDir}${separator}(.*?)${separator}.*`,
|
||||
);
|
||||
const match = regexSubFolder.exec(file);
|
||||
return match && match[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias filepath relative to site directory, very useful so that we
|
||||
* don't expose user's site structure.
|
||||
* Example: some/path/to/website/docs/foo.md -> @site/docs/foo.md
|
||||
*/
|
||||
export function aliasedSitePath(filePath: string, siteDir: string): string {
|
||||
const relativePath = posixPath(path.relative(siteDir, filePath));
|
||||
// Cannot use path.join() as it resolves '../' and removes
|
||||
// the '@site'. Let webpack loader resolve it.
|
||||
return `@site/${relativePath}`;
|
||||
}
|
||||
|
||||
export function getEditUrl(
|
||||
fileRelativePath: string,
|
||||
editUrl?: string,
|
||||
): string | undefined {
|
||||
return editUrl
|
||||
? normalizeUrl([editUrl, posixPath(fileRelativePath)])
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function isValidPathname(str: string): boolean {
|
||||
if (!str.startsWith('/')) {
|
||||
return false;
|
||||
|
@ -306,7 +207,7 @@ export function getPluginI18nPath({
|
|||
);
|
||||
}
|
||||
|
||||
export async function mapAsyncSequencial<T, R>(
|
||||
export async function mapAsyncSequential<T, R>(
|
||||
array: T[],
|
||||
action: (t: T) => Promise<R>,
|
||||
): Promise<R[]> {
|
||||
|
@ -332,35 +233,6 @@ export async function findAsyncSequential<T>(
|
|||
return undefined;
|
||||
}
|
||||
|
||||
// return the first folder path in which the file exists in
|
||||
export async function findFolderContainingFile(
|
||||
folderPaths: string[],
|
||||
relativeFilePath: string,
|
||||
): Promise<string | undefined> {
|
||||
return findAsyncSequential(folderPaths, (folderPath) =>
|
||||
fs.pathExists(path.join(folderPath, relativeFilePath)),
|
||||
);
|
||||
}
|
||||
|
||||
export async function getFolderContainingFile(
|
||||
folderPaths: string[],
|
||||
relativeFilePath: string,
|
||||
): Promise<string> {
|
||||
const maybeFolderPath = await findFolderContainingFile(
|
||||
folderPaths,
|
||||
relativeFilePath,
|
||||
);
|
||||
// should never happen, as the source was read from the FS anyway...
|
||||
if (!maybeFolderPath) {
|
||||
throw new Error(
|
||||
`File "${relativeFilePath}" does not exist in any of these folders:\n- ${folderPaths.join(
|
||||
'\n- ',
|
||||
)}]`,
|
||||
);
|
||||
}
|
||||
return maybeFolderPath;
|
||||
}
|
||||
|
||||
export function reportMessage(
|
||||
message: string,
|
||||
reportingSeverity: ReportingSeverity,
|
||||
|
@ -420,21 +292,3 @@ export function updateTranslationFileMessages(
|
|||
})),
|
||||
};
|
||||
}
|
||||
|
||||
// Input: ## Some heading {#some-heading}
|
||||
// Output: {text: "## Some heading", id: "some-heading"}
|
||||
export function parseMarkdownHeadingId(heading: string): {
|
||||
text: string;
|
||||
id?: string;
|
||||
} {
|
||||
const customHeadingIdRegex = /^(.*?)\s*\{#([\w-]+)\}$/;
|
||||
const matches = customHeadingIdRegex.exec(heading);
|
||||
if (matches) {
|
||||
return {
|
||||
text: matches[1],
|
||||
id: matches[2],
|
||||
};
|
||||
} else {
|
||||
return {text: heading, id: undefined};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue