mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-11 16:17:25 +02:00
refactor: reduce number of leaked anys (#7465)
This commit is contained in:
parent
6e62bba30f
commit
89b0fff128
39 changed files with 121 additions and 89 deletions
|
@ -28,7 +28,11 @@ type PackageJsonFile = {
|
||||||
async function getPackagesJsonFiles(): Promise<PackageJsonFile[]> {
|
async function getPackagesJsonFiles(): Promise<PackageJsonFile[]> {
|
||||||
const files = await Globby('packages/*/package.json');
|
const files = await Globby('packages/*/package.json');
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
files.map((file) => fs.readJSON(file).then((content) => ({file, content}))),
|
files.map((file) =>
|
||||||
|
fs
|
||||||
|
.readJSON(file)
|
||||||
|
.then((content: PackageJsonFile['content']) => ({file, content})),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,11 @@ type TsconfigFile = {
|
||||||
async function getTsconfigFiles(): Promise<TsconfigFile[]> {
|
async function getTsconfigFiles(): Promise<TsconfigFile[]> {
|
||||||
const files = await Globby('packages/*/tsconfig.*');
|
const files = await Globby('packages/*/tsconfig.*');
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
files.map((file) => fs.readJSON(file).then((content) => ({file, content}))),
|
files.map((file) =>
|
||||||
|
fs
|
||||||
|
.readJSON(file)
|
||||||
|
.then((content: TsconfigFile['content']) => ({file, content})),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ async function askForPackageManagerChoice(): Promise<PackageManager> {
|
||||||
.map((p) => ({title: p, value: p}));
|
.map((p) => ({title: p, value: p}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
await prompts(
|
(await prompts(
|
||||||
{
|
{
|
||||||
type: 'select',
|
type: 'select',
|
||||||
name: 'packageManager',
|
name: 'packageManager',
|
||||||
|
@ -77,7 +77,7 @@ async function askForPackageManagerChoice(): Promise<PackageManager> {
|
||||||
logger.info`Falling back to name=${defaultPackageManager}`;
|
logger.info`Falling back to name=${defaultPackageManager}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)) as {packageManager: PackageManager}
|
||||||
).packageManager;
|
).packageManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ async function getGitCommand(gitStrategy: GitStrategy): Promise<string> {
|
||||||
case 'copy':
|
case 'copy':
|
||||||
return 'git clone --recursive --depth 1';
|
return 'git clone --recursive --depth 1';
|
||||||
case 'custom': {
|
case 'custom': {
|
||||||
const {command} = await prompts(
|
const {command} = (await prompts(
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'command',
|
name: 'command',
|
||||||
|
@ -215,7 +215,7 @@ async function getGitCommand(gitStrategy: GitStrategy): Promise<string> {
|
||||||
logger.info`Falling back to code=${'git clone'}`;
|
logger.info`Falling back to code=${'git clone'}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
)) as {command: string};
|
||||||
return command ?? 'git clone';
|
return command ?? 'git clone';
|
||||||
}
|
}
|
||||||
case 'deep':
|
case 'deep':
|
||||||
|
@ -245,7 +245,7 @@ async function getSiteName(
|
||||||
}
|
}
|
||||||
return reqName;
|
return reqName;
|
||||||
}
|
}
|
||||||
const {siteName} = await prompts(
|
const {siteName} = (await prompts(
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'siteName',
|
name: 'siteName',
|
||||||
|
@ -259,7 +259,7 @@ async function getSiteName(
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
)) as {siteName: string};
|
||||||
return siteName;
|
return siteName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ async function getSource(
|
||||||
const template = cliOptions.gitStrategy
|
const template = cliOptions.gitStrategy
|
||||||
? 'Git repository'
|
? 'Git repository'
|
||||||
: (
|
: (
|
||||||
await prompts(
|
(await prompts(
|
||||||
{
|
{
|
||||||
type: 'select',
|
type: 'select',
|
||||||
name: 'template',
|
name: 'template',
|
||||||
|
@ -337,10 +337,10 @@ async function getSource(
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)) as {template: Template | 'Git repository' | 'Local template'}
|
||||||
).template;
|
).template;
|
||||||
if (template === 'Git repository') {
|
if (template === 'Git repository') {
|
||||||
const {gitRepoUrl} = await prompts(
|
const {gitRepoUrl} = (await prompts(
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'gitRepoUrl',
|
name: 'gitRepoUrl',
|
||||||
|
@ -359,7 +359,7 @@ async function getSource(
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
)) as {gitRepoUrl: string};
|
||||||
let strategy = cliOptions.gitStrategy;
|
let strategy = cliOptions.gitStrategy;
|
||||||
if (!strategy) {
|
if (!strategy) {
|
||||||
({strategy} = await prompts(
|
({strategy} = await prompts(
|
||||||
|
@ -393,7 +393,7 @@ async function getSource(
|
||||||
strategy: strategy ?? 'deep',
|
strategy: strategy ?? 'deep',
|
||||||
};
|
};
|
||||||
} else if (template === 'Local template') {
|
} else if (template === 'Local template') {
|
||||||
const {templateDir} = await prompts(
|
const {templateDir} = (await prompts(
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
name: 'templateDir',
|
name: 'templateDir',
|
||||||
|
@ -418,7 +418,7 @@ async function getSource(
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
)) as {templateDir: string};
|
||||||
return {
|
return {
|
||||||
type: 'local',
|
type: 'local',
|
||||||
path: templateDir,
|
path: templateDir,
|
||||||
|
@ -442,7 +442,7 @@ async function getSource(
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePkg(pkgPath: string, obj: {[key: string]: unknown}) {
|
async function updatePkg(pkgPath: string, obj: {[key: string]: unknown}) {
|
||||||
const pkg = await fs.readJSON(pkgPath);
|
const pkg = (await fs.readJSON(pkgPath)) as {[key: string]: unknown};
|
||||||
const newPkg = Object.assign(pkg, obj);
|
const newPkg = Object.assign(pkg, obj);
|
||||||
|
|
||||||
await fs.outputFile(pkgPath, `${JSON.stringify(newPkg, null, 2)}\n`);
|
await fs.outputFile(pkgPath, `${JSON.stringify(newPkg, null, 2)}\n`);
|
||||||
|
|
|
@ -92,8 +92,12 @@ async function readMetadataPath(metadataPath: string) {
|
||||||
*
|
*
|
||||||
* `{image: "./myImage.png"}` => `{image: require("./myImage.png")}`
|
* `{image: "./myImage.png"}` => `{image: require("./myImage.png")}`
|
||||||
*/
|
*/
|
||||||
function createAssetsExportCode(assets: {[key: string]: unknown}) {
|
function createAssetsExportCode(assets: unknown) {
|
||||||
if (Object.keys(assets).length === 0) {
|
if (
|
||||||
|
typeof assets !== 'object' ||
|
||||||
|
!assets ||
|
||||||
|
Object.keys(assets).length === 0
|
||||||
|
) {
|
||||||
return 'undefined';
|
return 'undefined';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +105,7 @@ function createAssetsExportCode(assets: {[key: string]: unknown}) {
|
||||||
function createAssetValueCode(assetValue: unknown): string | undefined {
|
function createAssetValueCode(assetValue: unknown): string | undefined {
|
||||||
if (Array.isArray(assetValue)) {
|
if (Array.isArray(assetValue)) {
|
||||||
const arrayItemCodes = assetValue.map(
|
const arrayItemCodes = assetValue.map(
|
||||||
(item) => createAssetValueCode(item) ?? 'undefined',
|
(item: unknown) => createAssetValueCode(item) ?? 'undefined',
|
||||||
);
|
);
|
||||||
return `[${arrayItemCodes.join(', ')}]`;
|
return `[${arrayItemCodes.join(', ')}]`;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +123,7 @@ function createAssetsExportCode(assets: {[key: string]: unknown}) {
|
||||||
const assetEntries = Object.entries(assets);
|
const assetEntries = Object.entries(assets);
|
||||||
|
|
||||||
const codeLines = assetEntries
|
const codeLines = assetEntries
|
||||||
.map(([key, value]) => {
|
.map(([key, value]: [string, unknown]) => {
|
||||||
const assetRequireCode = createAssetValueCode(value);
|
const assetRequireCode = createAssetValueCode(value);
|
||||||
return assetRequireCode ? `"${key}": ${assetRequireCode},` : undefined;
|
return assetRequireCode ? `"${key}": ${assetRequireCode},` : undefined;
|
||||||
})
|
})
|
||||||
|
@ -227,7 +231,7 @@ ${JSON.stringify(frontMatter, null, 2)}`;
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const metadata = metadataJsonString
|
const metadata = metadataJsonString
|
||||||
? JSON.parse(metadataJsonString)
|
? (JSON.parse(metadataJsonString) as {[key: string]: unknown})
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const assets =
|
const assets =
|
||||||
|
|
|
@ -13,13 +13,14 @@ import removePosition from 'unist-util-remove-position';
|
||||||
import toString from 'mdast-util-to-string';
|
import toString from 'mdast-util-to-string';
|
||||||
import visit from 'unist-util-visit';
|
import visit from 'unist-util-visit';
|
||||||
import slug from '../index';
|
import slug from '../index';
|
||||||
|
import type {Plugin} from 'unified';
|
||||||
|
|
||||||
function process(doc, plugins = []) {
|
function process(doc: string, plugins: Plugin[] = []) {
|
||||||
const processor = remark().use({plugins: [...plugins, slug]});
|
const processor = remark().use({plugins: [...plugins, slug]});
|
||||||
return removePosition(processor.runSync(processor.parse(doc)), true);
|
return removePosition(processor.runSync(processor.parse(doc)), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function heading(label, id) {
|
function heading(label: string, id: string) {
|
||||||
return u(
|
return u(
|
||||||
'heading',
|
'heading',
|
||||||
{depth: 2, data: {id, hProperties: {id}}},
|
{depth: 2, data: {id, hProperties: {id}}},
|
||||||
|
|
|
@ -35,9 +35,11 @@ declare module '@generated/registry' {
|
||||||
|
|
||||||
declare module '@generated/routes' {
|
declare module '@generated/routes' {
|
||||||
import type {RouteConfig as RRRouteConfig} from 'react-router-config';
|
import type {RouteConfig as RRRouteConfig} from 'react-router-config';
|
||||||
|
import type Loadable from 'react-loadable';
|
||||||
|
|
||||||
type RouteConfig = RRRouteConfig & {
|
type RouteConfig = RRRouteConfig & {
|
||||||
path: string;
|
path: string;
|
||||||
|
component: ReturnType<typeof Loadable>;
|
||||||
};
|
};
|
||||||
const routes: RouteConfig[];
|
const routes: RouteConfig[];
|
||||||
export default routes;
|
export default routes;
|
||||||
|
|
|
@ -13,7 +13,11 @@ import {
|
||||||
URISchema,
|
URISchema,
|
||||||
} from '@docusaurus/utils-validation';
|
} from '@docusaurus/utils-validation';
|
||||||
import {GlobExcludeDefault} from '@docusaurus/utils';
|
import {GlobExcludeDefault} from '@docusaurus/utils';
|
||||||
import type {PluginOptions, Options} from '@docusaurus/plugin-content-blog';
|
import type {
|
||||||
|
PluginOptions,
|
||||||
|
Options,
|
||||||
|
FeedType,
|
||||||
|
} from '@docusaurus/plugin-content-blog';
|
||||||
import type {OptionValidationContext} from '@docusaurus/types';
|
import type {OptionValidationContext} from '@docusaurus/types';
|
||||||
|
|
||||||
export const DEFAULT_OPTIONS: PluginOptions = {
|
export const DEFAULT_OPTIONS: PluginOptions = {
|
||||||
|
@ -101,7 +105,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
|
||||||
Joi.alternatives().conditional(
|
Joi.alternatives().conditional(
|
||||||
Joi.string().equal('all', 'rss', 'atom', 'json'),
|
Joi.string().equal('all', 'rss', 'atom', 'json'),
|
||||||
{
|
{
|
||||||
then: Joi.custom((val) =>
|
then: Joi.custom((val: FeedType | 'all') =>
|
||||||
val === 'all' ? ['rss', 'atom', 'json'] : [val],
|
val === 'all' ? ['rss', 'atom', 'json'] : [val],
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -53,7 +53,7 @@ async function createVersionedSidebarFile({
|
||||||
|
|
||||||
// Tests depend on non-default export for mocking.
|
// Tests depend on non-default export for mocking.
|
||||||
export async function cliDocsVersionCommand(
|
export async function cliDocsVersionCommand(
|
||||||
version: string,
|
version: unknown,
|
||||||
{id: pluginId, path: docsPath, sidebarPath}: PluginOptions,
|
{id: pluginId, path: docsPath, sidebarPath}: PluginOptions,
|
||||||
{siteDir, i18n}: LoadContext,
|
{siteDir, i18n}: LoadContext,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
@ -70,7 +70,7 @@ export async function cliDocsVersionCommand(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load existing versions.
|
// Load existing versions.
|
||||||
let versions = [];
|
let versions: string[] = [];
|
||||||
const versionsJSONFile = getVersionsFilePath(siteDir, pluginId);
|
const versionsJSONFile = getVersionsFilePath(siteDir, pluginId);
|
||||||
if (await fs.pathExists(versionsJSONFile)) {
|
if (await fs.pathExists(versionsJSONFile)) {
|
||||||
versions = await fs.readJSON(versionsJSONFile);
|
versions = await fs.readJSON(versionsJSONFile);
|
||||||
|
|
|
@ -100,7 +100,7 @@ export default async function pluginContentDocs(
|
||||||
.command(command)
|
.command(command)
|
||||||
.arguments('<version>')
|
.arguments('<version>')
|
||||||
.description(commandDescription)
|
.description(commandDescription)
|
||||||
.action((version) => {
|
.action((version: unknown) => {
|
||||||
cliDocsVersionCommand(version, options, context);
|
cliDocsVersionCommand(version, options, context);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -98,7 +98,7 @@ const OptionsSchema = Joi.object<PluginOptions>({
|
||||||
Joi.function(),
|
Joi.function(),
|
||||||
// Convert boolean values to functions
|
// Convert boolean values to functions
|
||||||
Joi.alternatives().conditional(Joi.boolean(), {
|
Joi.alternatives().conditional(Joi.boolean(), {
|
||||||
then: Joi.custom((val) =>
|
then: Joi.custom((val: boolean) =>
|
||||||
val ? DefaultNumberPrefixParser : DisabledNumberPrefixParser,
|
val ? DefaultNumberPrefixParser : DisabledNumberPrefixParser,
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -95,7 +95,7 @@ async function readVersionsFile(
|
||||||
): Promise<string[] | null> {
|
): Promise<string[] | null> {
|
||||||
const versionsFilePath = getVersionsFilePath(siteDir, pluginId);
|
const versionsFilePath = getVersionsFilePath(siteDir, pluginId);
|
||||||
if (await fs.pathExists(versionsFilePath)) {
|
if (await fs.pathExists(versionsFilePath)) {
|
||||||
const content = await fs.readJSON(versionsFilePath);
|
const content: unknown = await fs.readJSON(versionsFilePath);
|
||||||
validateVersionNames(content);
|
validateVersionNames(content);
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,9 @@ function BrowserOnlyReactJson(props: ReactJsonViewProps) {
|
||||||
return (
|
return (
|
||||||
<BrowserOnly>
|
<BrowserOnly>
|
||||||
{() => {
|
{() => {
|
||||||
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
const {default: ReactJson} =
|
||||||
const ReactJson = require('react-json-view').default;
|
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
||||||
|
require('react-json-view') as typeof import('react-json-view');
|
||||||
return <ReactJson {...props} />;
|
return <ReactJson {...props} />;
|
||||||
}}
|
}}
|
||||||
</BrowserOnly>
|
</BrowserOnly>
|
||||||
|
|
|
@ -320,6 +320,6 @@ if (typeof window !== 'undefined') {
|
||||||
addLegacyAppInstalledEventsListeners();
|
addLegacyAppInstalledEventsListeners();
|
||||||
|
|
||||||
// Then try to register the SW using lazy/dynamic imports
|
// Then try to register the SW using lazy/dynamic imports
|
||||||
registerSW().catch((e) => console.error('registerSW failed', e));
|
registerSW().catch((e: unknown) => console.error('registerSW failed', e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default async function createSitemap(
|
||||||
}
|
}
|
||||||
// https://github.com/staylor/react-helmet-async/pull/167
|
// https://github.com/staylor/react-helmet-async/pull/167
|
||||||
const meta = head[route]?.meta.toComponent() as unknown as
|
const meta = head[route]?.meta.toComponent() as unknown as
|
||||||
| ReactElement[]
|
| ReactElement<{name?: string; content?: string}>[]
|
||||||
| undefined;
|
| undefined;
|
||||||
return !meta?.some(
|
return !meta?.some(
|
||||||
(tag) => tag.props.name === 'robots' && tag.props.content === 'noindex',
|
(tag) => tag.props.name === 'robots' && tag.props.content === 'noindex',
|
||||||
|
|
|
@ -25,8 +25,10 @@ import styles from './styles.module.css';
|
||||||
|
|
||||||
// A very rough duck type, but good enough to guard against mistakes while
|
// A very rough duck type, but good enough to guard against mistakes while
|
||||||
// allowing customization
|
// allowing customization
|
||||||
function isTabItem(comp: ReactElement): comp is ReactElement<TabItemProps> {
|
function isTabItem(
|
||||||
return typeof comp.props.value !== 'undefined';
|
comp: ReactElement<object>,
|
||||||
|
): comp is ReactElement<TabItemProps> {
|
||||||
|
return 'value' in comp.props;
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabsComponent(props: Props): JSX.Element {
|
function TabsComponent(props: Props): JSX.Element {
|
||||||
|
|
|
@ -196,9 +196,7 @@ function CollapsibleBase({
|
||||||
className,
|
className,
|
||||||
disableSSRStyle,
|
disableSSRStyle,
|
||||||
}: CollapsibleBaseProps) {
|
}: CollapsibleBaseProps) {
|
||||||
// any because TS is a pain for HTML element refs, see https://twitter.com/sebastienlorber/status/1412784677795110914
|
const collapsibleRef = useRef<HTMLElement>(null);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const collapsibleRef = useRef<any>(null);
|
|
||||||
|
|
||||||
useCollapseAnimation({collapsibleRef, collapsed, animation});
|
useCollapseAnimation({collapsibleRef, collapsed, animation});
|
||||||
|
|
||||||
|
@ -206,7 +204,7 @@ function CollapsibleBase({
|
||||||
<As
|
<As
|
||||||
// @ts-expect-error: the "too complicated type" is produced from
|
// @ts-expect-error: the "too complicated type" is produced from
|
||||||
// "CollapsibleElementType" being a huge union
|
// "CollapsibleElementType" being a huge union
|
||||||
ref={collapsibleRef}
|
ref={collapsibleRef as RefObject<never>} // Refs are contravariant, which is not expressible in TS
|
||||||
style={disableSSRStyle ? undefined : getSSRStyle(collapsed)}
|
style={disableSSRStyle ? undefined : getSSRStyle(collapsed)}
|
||||||
onTransitionEnd={(e: React.TransitionEvent) => {
|
onTransitionEnd={(e: React.TransitionEvent) => {
|
||||||
if (e.propertyName !== 'height') {
|
if (e.propertyName !== 'height') {
|
||||||
|
|
|
@ -318,7 +318,7 @@ export function useDocRouteMetadata({
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, the sidebarName is added as route config: not ideal!
|
// For now, the sidebarName is added as route config: not ideal!
|
||||||
const sidebarName = currentDocRoute.sidebar;
|
const sidebarName = currentDocRoute.sidebar as string;
|
||||||
|
|
||||||
const sidebarItems = sidebarName
|
const sidebarItems = sidebarName
|
||||||
? versionMetadata.docsSidebars[sidebarName]
|
? versionMetadata.docsSidebars[sidebarName]
|
||||||
|
|
|
@ -23,7 +23,7 @@ import type {TranslationFileContent} from '@docusaurus/types';
|
||||||
async function getPackageCodePath(packageName: string) {
|
async function getPackageCodePath(packageName: string) {
|
||||||
const packagePath = path.join(__dirname, '../..', packageName);
|
const packagePath = path.join(__dirname, '../..', packageName);
|
||||||
const packageJsonPath = path.join(packagePath, 'package.json');
|
const packageJsonPath = path.join(packagePath, 'package.json');
|
||||||
const {main} = await fs.readJSON(packageJsonPath);
|
const {main} = (await fs.readJSON(packageJsonPath)) as {main: string};
|
||||||
const packageSrcPath = path.join(packagePath, path.dirname(main));
|
const packageSrcPath = path.join(packagePath, path.dirname(main));
|
||||||
return packageSrcPath;
|
return packageSrcPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const JoiFrontMatterString: Joi.Extension = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
base: Joi.string(),
|
base: Joi.string(),
|
||||||
// Fix Yaml that tries to auto-convert many things to string out of the box
|
// Fix Yaml that tries to auto-convert many things to string out of the box
|
||||||
prepare: (value) => {
|
prepare: (value: unknown) => {
|
||||||
if (typeof value === 'number' || value instanceof Date) {
|
if (typeof value === 'number' || value instanceof Date) {
|
||||||
return {value: value.toString()};
|
return {value: value.toString()};
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,10 @@ export const URISchema = Joi.alternatives(
|
||||||
Joi.string().uri({allowRelative: true}),
|
Joi.string().uri({allowRelative: true}),
|
||||||
// This custom validation logic is required notably because Joi does not
|
// This custom validation logic is required notably because Joi does not
|
||||||
// accept paths like /a/b/c ...
|
// accept paths like /a/b/c ...
|
||||||
Joi.custom((val, helpers) => {
|
Joi.custom((val: unknown, helpers) => {
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-new
|
// eslint-disable-next-line no-new
|
||||||
new URL(val);
|
new URL(String(val));
|
||||||
return val;
|
return val;
|
||||||
} catch {
|
} catch {
|
||||||
return helpers.error('any.invalid');
|
return helpers.error('any.invalid');
|
||||||
|
@ -55,7 +55,7 @@ export const URISchema = Joi.alternatives(
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PathnameSchema = Joi.string()
|
export const PathnameSchema = Joi.string()
|
||||||
.custom((val) => {
|
.custom((val: string) => {
|
||||||
if (!isValidPathname(val)) {
|
if (!isValidPathname(val)) {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,9 @@ export const NODE_MINOR_VERSION = parseInt(
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Docusaurus core version. */
|
/** Docusaurus core version. */
|
||||||
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
export const DOCUSAURUS_VERSION =
|
||||||
export const DOCUSAURUS_VERSION = require('../package.json').version;
|
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
||||||
|
(require('../package.json') as {version: string}).version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be overridden with cli option `--out-dir`. Code should generally use
|
* Can be overridden with cli option `--out-dir`. Code should generally use
|
||||||
|
|
|
@ -280,7 +280,10 @@ This can happen if you use special characters in front matter values (try using
|
||||||
}
|
}
|
||||||
|
|
||||||
function unwrapMarkdownLinks(line: string): string {
|
function unwrapMarkdownLinks(line: string): string {
|
||||||
return line.replace(/\[(?<alt>[^\]]+)\]\([^)]+\)/g, (match, p1) => p1);
|
return line.replace(
|
||||||
|
/\[(?<alt>[^\]]+)\]\([^)]+\)/g,
|
||||||
|
(match, p1: string) => p1,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addHeadingId(
|
function addHeadingId(
|
||||||
|
|
|
@ -53,7 +53,8 @@ function getTransformOptions(isServer: boolean): TransformOptions {
|
||||||
// better to explicitly specify the version so that it can reuse the
|
// better to explicitly specify the version so that it can reuse the
|
||||||
// helper better. See https://github.com/babel/babel/issues/10261
|
// helper better. See https://github.com/babel/babel/issues/10261
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
||||||
version: require('@babel/runtime/package.json').version,
|
version: (require('@babel/runtime/package.json') as {version: string})
|
||||||
|
.version,
|
||||||
regenerator: true,
|
regenerator: true,
|
||||||
useESModules: true,
|
useESModules: true,
|
||||||
// Undocumented option that lets us encapsulate our runtime, ensuring
|
// Undocumented option that lets us encapsulate our runtime, ensuring
|
||||||
|
|
|
@ -70,7 +70,7 @@ class PendingNavigation extends React.Component<Props, State> {
|
||||||
this.routeUpdateCleanupCb?.();
|
this.routeUpdateCleanupCb?.();
|
||||||
this.setState({nextRouteHasLoaded: true});
|
this.setState({nextRouteHasLoaded: true});
|
||||||
})
|
})
|
||||||
.catch((e) => console.warn(e));
|
.catch((e: unknown) => console.warn(e));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,5 @@ import {matchRoutes} from 'react-router-config';
|
||||||
export default function preload(pathname: string): Promise<void[]> {
|
export default function preload(pathname: string): Promise<void[]> {
|
||||||
const matches = matchRoutes(routes, pathname);
|
const matches = matchRoutes(routes, pathname);
|
||||||
|
|
||||||
return Promise.all(
|
return Promise.all(matches.map((match) => match.route.component.preload?.()));
|
||||||
// @ts-expect-error: ComponentCreator injected this method.
|
|
||||||
matches.map((match) => match.route.component?.preload?.()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ export default function Loading({
|
||||||
maxWidth: '50%',
|
maxWidth: '50%',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
}}>
|
}}>
|
||||||
<p>{error.message}</p>
|
<p>{String(error)}</p>
|
||||||
<div>
|
<div>
|
||||||
<button type="button" onClick={retry}>
|
<button type="button" onClick={retry}>
|
||||||
Retry
|
Retry
|
||||||
|
|
|
@ -78,7 +78,7 @@ export async function start(
|
||||||
logger.success`Docusaurus website is running at url=${newOpenUrl}.`;
|
logger.success`Docusaurus website is running at url=${newOpenUrl}.`;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err: Error) => {
|
||||||
logger.error(err.stack);
|
logger.error(err.stack);
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
|
@ -14,14 +14,14 @@ import type {SwizzleAction, SwizzleComponentConfig} from '@docusaurus/types';
|
||||||
const ExitTitle = logger.yellow('[Exit]');
|
const ExitTitle = logger.yellow('[Exit]');
|
||||||
|
|
||||||
export async function askThemeName(themeNames: string[]): Promise<string> {
|
export async function askThemeName(themeNames: string[]): Promise<string> {
|
||||||
const {themeName} = await prompts({
|
const {themeName} = (await prompts({
|
||||||
type: 'select',
|
type: 'select',
|
||||||
name: 'themeName',
|
name: 'themeName',
|
||||||
message: 'Select a theme to swizzle:',
|
message: 'Select a theme to swizzle:',
|
||||||
choices: themeNames
|
choices: themeNames
|
||||||
.map((theme) => ({title: theme, value: theme}))
|
.map((theme) => ({title: theme, value: theme}))
|
||||||
.concat({title: ExitTitle, value: '[Exit]'}),
|
.concat({title: ExitTitle, value: '[Exit]'}),
|
||||||
});
|
})) as {themeName?: string};
|
||||||
if (!themeName || themeName === '[Exit]') {
|
if (!themeName || themeName === '[Exit]') {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ export async function askComponentName(
|
||||||
})}`;
|
})}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {componentName} = await prompts({
|
const {componentName} = (await prompts({
|
||||||
type: 'autocomplete',
|
type: 'autocomplete',
|
||||||
name: 'componentName',
|
name: 'componentName',
|
||||||
message: `
|
message: `
|
||||||
|
@ -58,12 +58,12 @@ ${PartiallySafeHint} = not safe for all swizzle actions
|
||||||
value: compName,
|
value: compName,
|
||||||
}))
|
}))
|
||||||
.concat({title: ExitTitle, value: '[Exit]'}),
|
.concat({title: ExitTitle, value: '[Exit]'}),
|
||||||
async suggest(input, choices) {
|
async suggest(input: string, choices) {
|
||||||
return choices.filter((choice) =>
|
return choices.filter((choice) =>
|
||||||
choice.title.toLowerCase().includes(input.toLowerCase()),
|
choice.title.toLowerCase().includes(input.toLowerCase()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
})) as {componentName?: string};
|
||||||
logger.newLine();
|
logger.newLine();
|
||||||
|
|
||||||
if (!componentName || componentName === '[Exit]') {
|
if (!componentName || componentName === '[Exit]') {
|
||||||
|
@ -74,7 +74,7 @@ ${PartiallySafeHint} = not safe for all swizzle actions
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function askSwizzleDangerousComponent(): Promise<boolean> {
|
export async function askSwizzleDangerousComponent(): Promise<boolean> {
|
||||||
const {switchToDanger} = await prompts({
|
const {switchToDanger} = (await prompts({
|
||||||
type: 'select',
|
type: 'select',
|
||||||
name: 'switchToDanger',
|
name: 'switchToDanger',
|
||||||
message: `Do you really want to swizzle this unsafe internal component?`,
|
message: `Do you really want to swizzle this unsafe internal component?`,
|
||||||
|
@ -86,7 +86,7 @@ export async function askSwizzleDangerousComponent(): Promise<boolean> {
|
||||||
},
|
},
|
||||||
{title: ExitTitle, value: '[Exit]'},
|
{title: ExitTitle, value: '[Exit]'},
|
||||||
],
|
],
|
||||||
});
|
})) as {switchToDanger?: boolean | '[Exit]'};
|
||||||
|
|
||||||
if (typeof switchToDanger === 'undefined' || switchToDanger === '[Exit]') {
|
if (typeof switchToDanger === 'undefined' || switchToDanger === '[Exit]') {
|
||||||
return process.exit(0);
|
return process.exit(0);
|
||||||
|
@ -98,7 +98,7 @@ export async function askSwizzleDangerousComponent(): Promise<boolean> {
|
||||||
export async function askSwizzleAction(
|
export async function askSwizzleAction(
|
||||||
componentConfig: SwizzleComponentConfig,
|
componentConfig: SwizzleComponentConfig,
|
||||||
): Promise<SwizzleAction> {
|
): Promise<SwizzleAction> {
|
||||||
const {action} = await prompts({
|
const {action} = (await prompts({
|
||||||
type: 'select',
|
type: 'select',
|
||||||
name: 'action',
|
name: 'action',
|
||||||
message: `Which swizzle action do you want to do?`,
|
message: `Which swizzle action do you want to do?`,
|
||||||
|
@ -117,7 +117,7 @@ export async function askSwizzleAction(
|
||||||
},
|
},
|
||||||
{title: ExitTitle, value: '[Exit]'},
|
{title: ExitTitle, value: '[Exit]'},
|
||||||
],
|
],
|
||||||
});
|
})) as {action?: SwizzleAction | '[Exit]'};
|
||||||
|
|
||||||
if (typeof action === 'undefined' || action === '[Exit]') {
|
if (typeof action === 'undefined' || action === '[Exit]') {
|
||||||
return process.exit(0);
|
return process.exit(0);
|
||||||
|
|
|
@ -30,7 +30,7 @@ export async function loadSiteConfig({
|
||||||
|
|
||||||
const importedConfig = importFresh(siteConfigPath);
|
const importedConfig = importFresh(siteConfigPath);
|
||||||
|
|
||||||
const loadedConfig =
|
const loadedConfig: unknown =
|
||||||
typeof importedConfig === 'function'
|
typeof importedConfig === 'function'
|
||||||
? await importedConfig()
|
? await importedConfig()
|
||||||
: await importedConfig;
|
: await importedConfig;
|
||||||
|
|
|
@ -144,9 +144,9 @@ const I18N_CONFIG_SCHEMA = Joi.object<I18nConfig>({
|
||||||
.optional()
|
.optional()
|
||||||
.default(DEFAULT_I18N_CONFIG);
|
.default(DEFAULT_I18N_CONFIG);
|
||||||
|
|
||||||
const SiteUrlSchema = URISchema.required().custom((value, helpers) => {
|
const SiteUrlSchema = URISchema.required().custom((value: unknown, helpers) => {
|
||||||
try {
|
try {
|
||||||
const {pathname} = new URL(value);
|
const {pathname} = new URL(String(value));
|
||||||
if (pathname !== '/') {
|
if (pathname !== '/') {
|
||||||
helpers.warn('docusaurus.configValidationWarning', {
|
helpers.warn('docusaurus.configValidationWarning', {
|
||||||
warningMessage: `the url is not supposed to contain a sub-path like '${pathname}', please use the baseUrl field for sub-paths`,
|
warningMessage: `the url is not supposed to contain a sub-path like '${pathname}', please use the baseUrl field for sub-paths`,
|
||||||
|
@ -157,7 +157,7 @@ const SiteUrlSchema = URISchema.required().custom((value, helpers) => {
|
||||||
}, 'siteUrlCustomValidation');
|
}, 'siteUrlCustomValidation');
|
||||||
|
|
||||||
// TODO move to @docusaurus/utils-validation
|
// TODO move to @docusaurus/utils-validation
|
||||||
export const ConfigSchema = Joi.object({
|
export const ConfigSchema = Joi.object<DocusaurusConfig>({
|
||||||
baseUrl: Joi.string()
|
baseUrl: Joi.string()
|
||||||
.required()
|
.required()
|
||||||
.regex(/\/$/m)
|
.regex(/\/$/m)
|
||||||
|
@ -237,9 +237,7 @@ export const ConfigSchema = Joi.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO move to @docusaurus/utils-validation
|
// TODO move to @docusaurus/utils-validation
|
||||||
export function validateConfig(
|
export function validateConfig(config: unknown): DocusaurusConfig {
|
||||||
config: Partial<DocusaurusConfig>,
|
|
||||||
): DocusaurusConfig {
|
|
||||||
const {error, warning, value} = ConfigSchema.validate(config, {
|
const {error, warning, value} = ConfigSchema.validate(config, {
|
||||||
abortEarly: false,
|
abortEarly: false,
|
||||||
});
|
});
|
||||||
|
|
|
@ -70,7 +70,7 @@ async function choosePort(
|
||||||
}
|
}
|
||||||
clearConsole();
|
clearConsole();
|
||||||
const existingProcess = getProcessForPort(defaultPort);
|
const existingProcess = getProcessForPort(defaultPort);
|
||||||
const {shouldChangePort} = await prompts({
|
const {shouldChangePort} = (await prompts({
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
name: 'shouldChangePort',
|
name: 'shouldChangePort',
|
||||||
message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${
|
message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${
|
||||||
|
@ -79,7 +79,7 @@ async function choosePort(
|
||||||
|
|
||||||
Would you like to run the app on another port instead?`),
|
Would you like to run the app on another port instead?`),
|
||||||
initial: true,
|
initial: true,
|
||||||
});
|
})) as {shouldChangePort: boolean};
|
||||||
return shouldChangePort ? port : null;
|
return shouldChangePort ? port : null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error`Could not find an open port at ${host}.`;
|
logger.error`Could not find an open port at ${host}.`;
|
||||||
|
|
|
@ -20,7 +20,7 @@ async function getPackageJsonVersion(
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
if (await fs.pathExists(packageJsonPath)) {
|
if (await fs.pathExists(packageJsonPath)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
|
||||||
return require(packageJsonPath).version;
|
return (require(packageJsonPath) as {version?: string}).version;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ async function getPackageJsonName(
|
||||||
packageJsonPath: string,
|
packageJsonPath: string,
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
|
||||||
return require(packageJsonPath).name;
|
return (require(packageJsonPath) as {name?: string}).name;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPluginVersion(
|
export async function getPluginVersion(
|
||||||
|
|
|
@ -58,7 +58,7 @@ async function readTranslationFileContent(
|
||||||
): Promise<TranslationFileContent | undefined> {
|
): Promise<TranslationFileContent | undefined> {
|
||||||
if (await fs.pathExists(filePath)) {
|
if (await fs.pathExists(filePath)) {
|
||||||
try {
|
try {
|
||||||
const content = await fs.readJSON(filePath);
|
const content: unknown = await fs.readJSON(filePath);
|
||||||
ensureTranslationFileContent(content);
|
ensureTranslationFileContent(content);
|
||||||
return content;
|
return content;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -347,10 +347,12 @@ ${sourceWarningPart(path.node)}`,
|
||||||
firstArgEvaluated.confident &&
|
firstArgEvaluated.confident &&
|
||||||
typeof firstArgEvaluated.value === 'object'
|
typeof firstArgEvaluated.value === 'object'
|
||||||
) {
|
) {
|
||||||
const {message, id, description} = firstArgEvaluated.value;
|
const {message, id, description} = firstArgEvaluated.value as {
|
||||||
translations[id ?? message] = {
|
[propName: string]: unknown;
|
||||||
message: message ?? id,
|
};
|
||||||
...(description && {description}),
|
translations[String(id ?? message)] = {
|
||||||
|
message: String(message ?? id),
|
||||||
|
...(Boolean(description) && {description: String(description)}),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
warnings.push(
|
warnings.push(
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/file-loader": "^5.0.1",
|
||||||
"@types/sharp": "^0.30.2"
|
"@types/sharp": "^0.30.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default async function lqipLoader(
|
||||||
} else {
|
} else {
|
||||||
if (!contentIsFileExport) {
|
if (!contentIsFileExport) {
|
||||||
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
||||||
const fileLoader = require('file-loader');
|
const fileLoader = require('file-loader') as typeof import('file-loader');
|
||||||
content = fileLoader.call(this, contentBuffer);
|
content = fileLoader.call(this, contentBuffer);
|
||||||
}
|
}
|
||||||
source = content.match(
|
source = content.match(
|
||||||
|
|
|
@ -9,8 +9,8 @@ import path from 'path';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
||||||
const {version} = require('../package.json');
|
const {version} = require('../package.json') as {version: string};
|
||||||
|
|
||||||
const ERROR_EXT = `Error: Input file is missing or uses unsupported image format, lqip v${version}`;
|
const ERROR_EXT = `Error: Input file is missing or uses unsupported image format, lqip v${version}`;
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,13 @@ export function VersionsProvider({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch('https://registry.npmjs.org/@docusaurus/core')
|
fetch('https://registry.npmjs.org/@docusaurus/core')
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((data) => {
|
.then(
|
||||||
const name = Object.keys(data.versions).at(-1)!;
|
(data: {versions: string[]; time: {[versionName: string]: string}}) => {
|
||||||
const time = data.time[name];
|
const name = Object.keys(data.versions).at(-1)!;
|
||||||
setCanaryVersion({name, time});
|
const time = data.time[name];
|
||||||
});
|
setCanaryVersion({name, time});
|
||||||
|
},
|
||||||
|
);
|
||||||
}, []);
|
}, []);
|
||||||
return <Context.Provider value={canaryVersion}>{children}</Context.Provider>;
|
return <Context.Provider value={canaryVersion}>{children}</Context.Provider>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3308,6 +3308,13 @@
|
||||||
"@types/qs" "*"
|
"@types/qs" "*"
|
||||||
"@types/serve-static" "*"
|
"@types/serve-static" "*"
|
||||||
|
|
||||||
|
"@types/file-loader@^5.0.1":
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/file-loader/-/file-loader-5.0.1.tgz#300b7c729e4f0c523783b865b287e3459135bf22"
|
||||||
|
integrity sha512-FHPPuRb/Ts/25qvNU/mQGwRZUp793nBxYqXd/KwApykxATagqrO4+2EEcGDm/DuXyV/EkOa04umS1DQ8tQSomg==
|
||||||
|
dependencies:
|
||||||
|
"@types/webpack" "^4"
|
||||||
|
|
||||||
"@types/fs-extra@^9.0.13":
|
"@types/fs-extra@^9.0.13":
|
||||||
version "9.0.13"
|
version "9.0.13"
|
||||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45"
|
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue