mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 23:57:22 +02:00
refactor: enable a few TS flags (#6852)
* refactor: enable a few TS flags * refactor * revert to working version * fix * better * change
This commit is contained in:
parent
9f925a42bf
commit
4db0c620de
71 changed files with 210 additions and 174 deletions
|
@ -21,8 +21,8 @@ function interpolate(
|
|||
): string {
|
||||
let res = '';
|
||||
values.forEach((value, idx) => {
|
||||
const flag = msgs[idx].match(/[a-z]+=$/);
|
||||
res += msgs[idx].replace(/[a-z]+=$/, '');
|
||||
const flag = msgs[idx]!.match(/[a-z]+=$/);
|
||||
res += msgs[idx]!.replace(/[a-z]+=$/, '');
|
||||
const format = (() => {
|
||||
if (!flag) {
|
||||
return (a: string | number) => a;
|
||||
|
|
|
@ -94,7 +94,7 @@ export default function plugin(options: PluginOptions = {}): Transformer {
|
|||
const targetIndex = getOrCreateExistingTargetIndex(children, name);
|
||||
|
||||
if (headings && headings.length) {
|
||||
children[targetIndex].value = `export const ${name} = ${stringifyObject(
|
||||
children[targetIndex]!.value = `export const ${name} = ${stringifyObject(
|
||||
headings,
|
||||
)};`;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ export default function extractMetadata(content: string): Data {
|
|||
|
||||
// New line characters => to handle all operating systems.
|
||||
const lines = (both.header ?? '').split(/\r?\n/);
|
||||
for (let i = 0; i < lines.length - 1; i += 1) {
|
||||
const keyValue = lines[i].split(':');
|
||||
lines.slice(0, -1).forEach((line) => {
|
||||
const keyValue = line.split(':') as [string, ...string[]];
|
||||
const key = keyValue[0].trim();
|
||||
let value = keyValue.slice(1).join(':').trim();
|
||||
try {
|
||||
|
@ -47,7 +47,7 @@ export default function extractMetadata(content: string): Data {
|
|||
// Ignore the error as it means it's not a JSON value.
|
||||
}
|
||||
metadata[key] = value;
|
||||
}
|
||||
});
|
||||
return {metadata, rawContent: both.content};
|
||||
}
|
||||
|
||||
|
|
|
@ -535,7 +535,7 @@ async function migrateVersionedSidebar(
|
|||
// Order matters: if a sidebar file doesn't exist, we have to use the
|
||||
// previous version's
|
||||
for (let i = 0; i < versions.length; i += 1) {
|
||||
const version = versions[i];
|
||||
const version = versions[i]!;
|
||||
let sidebarEntries: SidebarEntries;
|
||||
const sidebarPath = path.join(
|
||||
siteDir,
|
||||
|
@ -545,7 +545,7 @@ async function migrateVersionedSidebar(
|
|||
try {
|
||||
sidebarEntries = JSON.parse(await fs.readFile(sidebarPath, 'utf-8'));
|
||||
} catch {
|
||||
sidebars.push({version, entries: sidebars[i - 1].entries});
|
||||
sidebars.push({version, entries: sidebars[i - 1]!.entries});
|
||||
return;
|
||||
}
|
||||
const newSidebar = Object.entries(sidebarEntries).reduce(
|
||||
|
|
|
@ -33,6 +33,9 @@ const property = (key: string, value: ArrowFunctionExpression) =>
|
|||
|
||||
const processCallExpression = (node: ASTPath<VariableDeclarator>) => {
|
||||
const args = (node?.value?.init as CallExpression)?.arguments[0];
|
||||
if (!args) {
|
||||
return;
|
||||
}
|
||||
if (args.type === 'Literal') {
|
||||
if (
|
||||
typeof args.value === 'string' &&
|
||||
|
@ -71,6 +74,9 @@ const processMemberExpression = (node: ASTPath<VariableDeclarator>) => {
|
|||
return;
|
||||
}
|
||||
const args = object.arguments[0];
|
||||
if (!args) {
|
||||
return;
|
||||
}
|
||||
if (args.type === 'Literal') {
|
||||
if (args.value === '../../core/CompLibrary.js') {
|
||||
const newDeclarator = jscodeshift.variableDeclarator(
|
||||
|
@ -117,7 +123,7 @@ export default function transformer(file: string): string {
|
|||
}
|
||||
});
|
||||
if (r[r.length - 1]) {
|
||||
jscodeshift(r[r.length - 1].parent).insertAfter(
|
||||
jscodeshift(r[r.length - 1]!.parent).insertAfter(
|
||||
jscodeshift.importDeclaration(
|
||||
[jscodeshift.importDefaultSpecifier(jscodeshift.identifier('Layout'))],
|
||||
jscodeshift.literal('@theme/Layout'),
|
||||
|
|
|
@ -139,10 +139,10 @@ export function parseBlogFileName(
|
|||
if (dateFilenameMatch) {
|
||||
const {folder, text, date: dateString} = dateFilenameMatch.groups!;
|
||||
// Always treat dates as UTC by adding the `Z`
|
||||
const date = new Date(`${dateString}Z`);
|
||||
const slugDate = dateString.replace(/-/g, '/');
|
||||
const slug = `/${slugDate}/${folder}${text}`;
|
||||
return {date, text, slug};
|
||||
const date = new Date(`${dateString!}Z`);
|
||||
const slugDate = dateString!.replace(/-/g, '/');
|
||||
const slug = `/${slugDate}/${folder!}${text!}`;
|
||||
return {date, text: text!, slug};
|
||||
}
|
||||
const text = blogSourceRelative.replace(/(?:\/index)?\.mdx?$/, '');
|
||||
const slug = `/${text}`;
|
||||
|
|
|
@ -307,7 +307,7 @@ export default async function pluginContentBlog(
|
|||
({
|
||||
content: {
|
||||
__import: true,
|
||||
path: blogItemsToMetadata[postID].source,
|
||||
path: blogItemsToMetadata[postID]!.source,
|
||||
query: {
|
||||
truncated: true,
|
||||
},
|
||||
|
@ -359,7 +359,7 @@ export default async function pluginContentBlog(
|
|||
modules: {
|
||||
sidebar: aliasedSource(sidebarProp),
|
||||
items: items.map((postID) => {
|
||||
const blogPostMetadata = blogItemsToMetadata[postID];
|
||||
const blogPostMetadata = blogItemsToMetadata[postID]!;
|
||||
return {
|
||||
content: {
|
||||
__import: true,
|
||||
|
|
|
@ -19,8 +19,9 @@ function translateListPage(
|
|||
items,
|
||||
metadata: {
|
||||
...metadata,
|
||||
blogTitle: translations.title.message,
|
||||
blogDescription: translations.description.message,
|
||||
blogTitle: translations.title?.message ?? page.metadata.blogTitle,
|
||||
blogDescription:
|
||||
translations.description?.message ?? page.metadata.blogDescription,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -52,10 +53,14 @@ export function translateContent(
|
|||
content: BlogContent,
|
||||
translationFiles: TranslationFiles,
|
||||
): BlogContent {
|
||||
const [{content: optionsTranslations}] = translationFiles;
|
||||
if (translationFiles.length === 0) {
|
||||
return content;
|
||||
}
|
||||
const {content: optionsTranslations} = translationFiles[0]!;
|
||||
return {
|
||||
...content,
|
||||
blogSidebarTitle: optionsTranslations['sidebar.title'].message,
|
||||
blogSidebarTitle:
|
||||
optionsTranslations['sidebar.title']?.message ?? content.blogSidebarTitle,
|
||||
blogListPaginated: translateListPage(
|
||||
content.blogListPaginated,
|
||||
optionsTranslations,
|
||||
|
|
|
@ -363,7 +363,7 @@ export function getMainDocId({
|
|||
doc.unversionedId === firstDocIdOfFirstSidebar,
|
||||
)!;
|
||||
}
|
||||
return docs[0];
|
||||
return docs[0]!;
|
||||
}
|
||||
|
||||
return getMainDoc().unversionedId;
|
||||
|
|
|
@ -49,7 +49,7 @@ async function readCategoriesMetadata(contentPath: string) {
|
|||
const categoryToFile = _.groupBy(categoryFiles, path.dirname);
|
||||
return combinePromises(
|
||||
_.mapValues(categoryToFile, async (files, folder) => {
|
||||
const [filePath] = files;
|
||||
const filePath = files[0]!;
|
||||
if (files.length > 1) {
|
||||
logger.warn`There are more than one category metadata files for path=${folder}: ${files.join(
|
||||
', ',
|
||||
|
|
|
@ -201,12 +201,12 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
|||
if (!sidebarName) {
|
||||
return emptySidebarNavigation();
|
||||
}
|
||||
if (!sidebarNameToNavigationItems[sidebarName]) {
|
||||
const navigationItems = sidebarNameToNavigationItems[sidebarName];
|
||||
if (!navigationItems) {
|
||||
throw new Error(
|
||||
`Doc with ID ${docId} wants to display sidebar ${sidebarName} but a sidebar with this name doesn't exist`,
|
||||
);
|
||||
}
|
||||
const navigationItems = sidebarNameToNavigationItems[sidebarName];
|
||||
const currentItemIndex = navigationItems.findIndex((item) => {
|
||||
if (item.type === 'doc') {
|
||||
return item.id === docId;
|
||||
|
@ -263,7 +263,7 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
|
|||
if (!sidebarName) {
|
||||
return emptySidebarNavigation();
|
||||
}
|
||||
const navigationItems = sidebarNameToNavigationItems[sidebarName];
|
||||
const navigationItems = sidebarNameToNavigationItems[sidebarName]!;
|
||||
const currentItemIndex = navigationItems.findIndex(
|
||||
isCurrentCategoryGeneratedIndexItem,
|
||||
);
|
||||
|
@ -341,7 +341,7 @@ Available document ids are:
|
|||
getCategoryGeneratedIndexList,
|
||||
getCategoryGeneratedIndexNavigation,
|
||||
checkSidebarsDocIds,
|
||||
getFirstLink: (id) => getFirstLink(sidebars[id]),
|
||||
getFirstLink: (id) => getFirstLink(sidebars[id]!),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -274,10 +274,14 @@ function translateVersion(
|
|||
translationFiles: Record<string, TranslationFile>,
|
||||
): LoadedVersion {
|
||||
const versionTranslations =
|
||||
translationFiles[getVersionFileName(version.versionName)].content;
|
||||
translationFiles[getVersionFileName(version.versionName)]?.content;
|
||||
if (!versionTranslations) {
|
||||
return version;
|
||||
}
|
||||
return {
|
||||
...version,
|
||||
versionLabel: versionTranslations['version.label']?.message,
|
||||
versionLabel:
|
||||
versionTranslations['version.label']?.message ?? version.versionLabel,
|
||||
sidebars: translateSidebars(version, versionTranslations),
|
||||
// docs: translateDocs(version.docs, versionTranslations),
|
||||
};
|
||||
|
|
|
@ -464,11 +464,11 @@ Please set the docs "sidebarPath" field in your config file to:
|
|||
// "last version" is not a very good concept nor api surface
|
||||
function getDefaultLastVersionName(versionNames: string[]) {
|
||||
if (versionNames.length === 1) {
|
||||
return versionNames[0];
|
||||
return versionNames[0]!;
|
||||
}
|
||||
return versionNames.filter(
|
||||
(versionName) => versionName !== CURRENT_VERSION_NAME,
|
||||
)[0];
|
||||
)[0]!;
|
||||
}
|
||||
|
||||
function checkVersionsOptions(
|
||||
|
|
|
@ -71,7 +71,7 @@ const plugin: Plugin<[PluginOptions?]> = (options = {}) => {
|
|||
if (isParent(node)) {
|
||||
let index = 0;
|
||||
while (index < node.children.length) {
|
||||
const child = node.children[index];
|
||||
const child = node.children[index]!;
|
||||
if (matchNode(child)) {
|
||||
const result = transformNode(child, sync);
|
||||
node.children.splice(index, 1, ...result);
|
||||
|
|
|
@ -107,7 +107,7 @@ export default function docusaurusThemeClassic(
|
|||
prism: {additionalLanguages = []} = {},
|
||||
} = themeConfig;
|
||||
const {customCss} = options || {};
|
||||
const {direction} = localeConfigs[currentLocale];
|
||||
const {direction} = localeConfigs[currentLocale]!;
|
||||
|
||||
return {
|
||||
name: 'docusaurus-theme-classic',
|
||||
|
|
|
@ -133,7 +133,7 @@ export default function BackToTopButton(): JSX.Element {
|
|||
ThemeClassNames.common.backToTopButton,
|
||||
styles.backToTopButton,
|
||||
{
|
||||
[styles.backToTopButtonShow]: show,
|
||||
[styles.backToTopButtonShow!]: show,
|
||||
},
|
||||
)}
|
||||
type="button"
|
||||
|
|
|
@ -114,7 +114,7 @@ export default function BlogPostItem(props: Props): JSX.Element {
|
|||
{(tagsExists || truncated) && (
|
||||
<footer
|
||||
className={clsx('row docusaurus-mt-lg', {
|
||||
[styles.blogPostDetailsFull]: isBlogPostPage,
|
||||
[styles.blogPostDetailsFull!]: isBlogPostPage,
|
||||
})}>
|
||||
{tagsExists && (
|
||||
<div className={clsx('col', {'col--9': truncatedPost})}>
|
||||
|
|
|
@ -128,8 +128,8 @@ export default function CodeBlock({
|
|||
style={style}>
|
||||
<code className={styles.codeBlockLines}>
|
||||
{tokens.map((line, i) => {
|
||||
if (line.length === 1 && line[0].content === '\n') {
|
||||
line[0].content = '';
|
||||
if (line.length === 1 && line[0]!.content === '\n') {
|
||||
line[0]!.content = '';
|
||||
}
|
||||
|
||||
const lineProps = getLineProps({line, key: i});
|
||||
|
|
|
@ -32,9 +32,9 @@ function ColorModeToggle({
|
|||
return (
|
||||
<div
|
||||
className={clsx(styles.toggle, className, {
|
||||
[styles.toggleChecked]: checked,
|
||||
[styles.toggleFocused]: focused,
|
||||
[styles.toggleDisabled]: !isBrowser,
|
||||
[styles.toggleChecked!]: checked,
|
||||
[styles.toggleFocused!]: focused,
|
||||
[styles.toggleDisabled!]: !isBrowser,
|
||||
})}>
|
||||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
|
||||
<div
|
||||
|
|
|
@ -54,7 +54,7 @@ export default function DocItem(props: Props): JSX.Element {
|
|||
<div className="row">
|
||||
<div
|
||||
className={clsx('col', {
|
||||
[styles.docItemCol]: !hideTableOfContents,
|
||||
[styles.docItemCol!]: !hideTableOfContents,
|
||||
})}>
|
||||
<DocVersionBanner />
|
||||
<div className={styles.docItemContainer}>
|
||||
|
|
|
@ -74,12 +74,12 @@ function DocPageContent({
|
|||
ThemeClassNames.docs.docSidebarContainer,
|
||||
styles.docSidebarContainer,
|
||||
{
|
||||
[styles.docSidebarContainerHidden]: hiddenSidebarContainer,
|
||||
[styles.docSidebarContainerHidden!]: hiddenSidebarContainer,
|
||||
},
|
||||
)}
|
||||
onTransitionEnd={(e) => {
|
||||
if (
|
||||
!e.currentTarget.classList.contains(styles.docSidebarContainer)
|
||||
!e.currentTarget.classList.contains(styles.docSidebarContainer!)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ function DocPageContent({
|
|||
)}
|
||||
<main
|
||||
className={clsx(styles.docMainContainer, {
|
||||
[styles.docMainContainerEnhanced]:
|
||||
[styles.docMainContainerEnhanced!]:
|
||||
hiddenSidebarContainer || !sidebar,
|
||||
})}>
|
||||
<div
|
||||
|
@ -134,7 +134,7 @@ function DocPageContent({
|
|||
'container padding-top--md padding-bottom--lg',
|
||||
styles.docItemWrapper,
|
||||
{
|
||||
[styles.docItemWrapperEnhanced]: hiddenSidebarContainer,
|
||||
[styles.docItemWrapperEnhanced!]: hiddenSidebarContainer,
|
||||
},
|
||||
)}>
|
||||
<MDXProvider components={MDXComponents}>{children}</MDXProvider>
|
||||
|
@ -172,7 +172,7 @@ export default function DocPage(props: Props): JSX.Element {
|
|||
<html className={versionMetadata.className} />
|
||||
</Head>
|
||||
<DocsVersionProvider version={versionMetadata}>
|
||||
<DocsSidebarProvider sidebar={sidebar}>
|
||||
<DocsSidebarProvider sidebar={sidebar ?? null}>
|
||||
<DocPageContent
|
||||
currentDocRoute={currentDocRoute}
|
||||
versionMetadata={versionMetadata}
|
||||
|
|
|
@ -73,13 +73,13 @@ function DocSidebarDesktop({path, sidebar, onCollapse, isHidden}: Props) {
|
|||
return (
|
||||
<div
|
||||
className={clsx(styles.sidebar, {
|
||||
[styles.sidebarWithHideableNavbar]: hideOnScroll,
|
||||
[styles.sidebarHidden]: isHidden,
|
||||
[styles.sidebarWithHideableNavbar!]: hideOnScroll,
|
||||
[styles.sidebarHidden!]: isHidden,
|
||||
})}>
|
||||
{hideOnScroll && <Logo tabIndex={-1} className={styles.sidebarLogo} />}
|
||||
<nav
|
||||
className={clsx('menu thin-scrollbar', styles.menu, {
|
||||
[styles.menuWithAnnouncementBar]: showAnnouncementBar,
|
||||
[styles.menuWithAnnouncementBar!]: showAnnouncementBar,
|
||||
})}>
|
||||
<ul className={clsx(ThemeClassNames.docs.docSidebarMenu, 'menu__list')}>
|
||||
<DocSidebarItems items={sidebar} activePath={path} level={1} />
|
||||
|
|
|
@ -131,7 +131,7 @@ function SimpleLinks({links}: {links: SimpleFooter['links']}) {
|
|||
function isMultiColumnFooterLinks(
|
||||
links: MultiColumnFooter['links'] | SimpleFooter['links'],
|
||||
): links is MultiColumnFooter['links'] {
|
||||
return 'title' in links[0];
|
||||
return 'title' in links[0]!;
|
||||
}
|
||||
|
||||
function Footer(): JSX.Element | null {
|
||||
|
|
|
@ -26,8 +26,8 @@ function AnchorHeading({as: As, id, ...props}: Props) {
|
|||
<As
|
||||
{...props}
|
||||
className={clsx('anchor', {
|
||||
[styles.anchorWithHideOnScrollNavbar]: hideOnScroll,
|
||||
[styles.anchorWithStickyNavbar]: !hideOnScroll,
|
||||
[styles.anchorWithHideOnScrollNavbar!]: hideOnScroll,
|
||||
[styles.anchorWithStickyNavbar!]: !hideOnScroll,
|
||||
})}
|
||||
id={id}>
|
||||
{props.children}
|
||||
|
|
|
@ -92,7 +92,7 @@ export default function LayoutHead(props: Props): JSX.Element {
|
|||
const {title, description, image, keywords, searchMetadata} = props;
|
||||
const faviconUrl = useBaseUrl(favicon);
|
||||
const pageTitle = useTitleFormatter(title);
|
||||
const {htmlLang, direction: htmlDir} = localeConfigs[currentLocale];
|
||||
const {htmlLang, direction: htmlDir} = localeConfigs[currentLocale]!;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -241,8 +241,8 @@ export default function Navbar(): JSX.Element {
|
|||
'navbar--dark': style === 'dark',
|
||||
'navbar--primary': style === 'primary',
|
||||
'navbar-sidebar--show': mobileSidebar.shown,
|
||||
[styles.navbarHideable]: hideOnScroll,
|
||||
[styles.navbarHidden]: hideOnScroll && !isNavbarVisible,
|
||||
[styles.navbarHideable!]: hideOnScroll,
|
||||
[styles.navbarHidden!]: hideOnScroll && !isNavbarVisible,
|
||||
})}>
|
||||
<div className="navbar__inner">
|
||||
<div className="navbar__items">
|
||||
|
|
|
@ -28,7 +28,7 @@ export default function LocaleDropdownNavbarItem({
|
|||
const alternatePageUtils = useAlternatePageUtils();
|
||||
|
||||
function getLocaleLabel(locale: string) {
|
||||
return localeConfigs[locale].label;
|
||||
return localeConfigs[locale]!.label;
|
||||
}
|
||||
|
||||
const localeItems = locales.map((locale): LinkLikeNavbarItemProps => {
|
||||
|
|
|
@ -28,7 +28,7 @@ export default function TOCCollapsible({
|
|||
className={clsx(
|
||||
styles.tocCollapsible,
|
||||
{
|
||||
[styles.tocCollapsibleExpanded]: !collapsed,
|
||||
[styles.tocCollapsibleExpanded!]: !collapsed,
|
||||
},
|
||||
className,
|
||||
)}>
|
||||
|
|
|
@ -108,7 +108,7 @@ function TabsComponent(props: Props): JSX.Element {
|
|||
) => {
|
||||
const newTab = event.currentTarget;
|
||||
const newTabIndex = tabRefs.indexOf(newTab);
|
||||
const newTabValue = values[newTabIndex].value;
|
||||
const newTabValue = values[newTabIndex]!.value;
|
||||
|
||||
if (newTabValue !== selectedValue) {
|
||||
blockElementScrollPositionUntilNextRender(newTab);
|
||||
|
@ -126,12 +126,12 @@ function TabsComponent(props: Props): JSX.Element {
|
|||
switch (event.key) {
|
||||
case 'ArrowRight': {
|
||||
const nextTab = tabRefs.indexOf(event.currentTarget) + 1;
|
||||
focusElement = tabRefs[nextTab] || tabRefs[0];
|
||||
focusElement = tabRefs[nextTab] || tabRefs[0]!;
|
||||
break;
|
||||
}
|
||||
case 'ArrowLeft': {
|
||||
const prevTab = tabRefs.indexOf(event.currentTarget) - 1;
|
||||
focusElement = tabRefs[prevTab] || tabRefs[tabRefs.length - 1];
|
||||
focusElement = tabRefs[prevTab] || tabRefs[tabRefs.length - 1]!;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -181,7 +181,7 @@ function TabsComponent(props: Props): JSX.Element {
|
|||
cloneElement(
|
||||
children.filter(
|
||||
(tabItem) => tabItem.props.value === selectedValue,
|
||||
)[0],
|
||||
)[0]!,
|
||||
{className: 'margin-vert--md'},
|
||||
)
|
||||
) : (
|
||||
|
|
|
@ -19,8 +19,8 @@ export default function Tag(props: Props): JSX.Element {
|
|||
<Link
|
||||
href={permalink}
|
||||
className={clsx(styles.tag, {
|
||||
[styles.tagRegular]: !count,
|
||||
[styles.tagWithCount]: count,
|
||||
[styles.tagRegular!]: !count,
|
||||
[styles.tagWithCount!]: count,
|
||||
})}>
|
||||
{name}
|
||||
{count && <span>{count}</span>}
|
||||
|
|
|
@ -50,8 +50,11 @@ function getNavbarTranslationFile(navbar: Navbar): TranslationFileContent {
|
|||
}
|
||||
function translateNavbar(
|
||||
navbar: Navbar,
|
||||
navbarTranslations: TranslationFileContent,
|
||||
navbarTranslations: TranslationFileContent | undefined,
|
||||
): Navbar {
|
||||
if (!navbarTranslations) {
|
||||
return navbar;
|
||||
}
|
||||
return {
|
||||
...navbar,
|
||||
title: navbarTranslations.title?.message ?? navbar.title,
|
||||
|
@ -76,7 +79,7 @@ function translateNavbar(
|
|||
function isMultiColumnFooterLinks(
|
||||
links: MultiColumnFooter['links'] | SimpleFooter['links'],
|
||||
): links is MultiColumnFooter['links'] {
|
||||
return links.length > 0 && 'title' in links[0];
|
||||
return links.length > 0 && 'title' in links[0]!;
|
||||
}
|
||||
|
||||
function getFooterTranslationFile(footer: Footer): TranslationFileContent {
|
||||
|
@ -121,8 +124,11 @@ function getFooterTranslationFile(footer: Footer): TranslationFileContent {
|
|||
}
|
||||
function translateFooter(
|
||||
footer: Footer,
|
||||
footerTranslations: TranslationFileContent,
|
||||
footerTranslations: TranslationFileContent | undefined,
|
||||
): Footer {
|
||||
if (!footerTranslations) {
|
||||
return footer;
|
||||
}
|
||||
const links = isMultiColumnFooterLinks(footer.links)
|
||||
? footer.links.map((link) => ({
|
||||
...link,
|
||||
|
@ -187,10 +193,10 @@ export function translateThemeConfig({
|
|||
...themeConfig,
|
||||
navbar: translateNavbar(
|
||||
themeConfig.navbar,
|
||||
translationFilesMap.navbar.content,
|
||||
translationFilesMap.navbar?.content,
|
||||
),
|
||||
footer: themeConfig.footer
|
||||
? translateFooter(themeConfig.footer, translationFilesMap.footer.content)
|
||||
? translateFooter(themeConfig.footer, translationFilesMap.footer?.content)
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"lib": ["DOM", "ES2019"],
|
||||
"module": "esnext",
|
||||
"noEmit": true,
|
||||
"jsx": "react",
|
||||
"jsx": "react-native",
|
||||
"baseUrl": "src"
|
||||
},
|
||||
"include": ["src/"]
|
||||
|
|
|
@ -58,7 +58,7 @@ export default function Details({
|
|||
data-collapsed={collapsed}
|
||||
className={clsx(
|
||||
styles.details,
|
||||
{[styles.isBrowser]: isBrowser},
|
||||
{[styles.isBrowser!]: isBrowser},
|
||||
props.className,
|
||||
)}
|
||||
onMouseDown={(e) => {
|
||||
|
|
|
@ -115,7 +115,7 @@ export function parseLines(
|
|||
// Highlighted lines specified in props: don't parse the content
|
||||
if (metastring && highlightLinesRangeRegex.test(metastring)) {
|
||||
const highlightLinesRange = metastring.match(highlightLinesRangeRegex)!
|
||||
.groups!.range;
|
||||
.groups!.range!;
|
||||
const highlightLines = rangeParser(highlightLinesRange)
|
||||
.filter((n) => n > 0)
|
||||
.map((n) => n - 1);
|
||||
|
@ -131,7 +131,7 @@ export function parseLines(
|
|||
let highlightRange = '';
|
||||
// loop through lines
|
||||
for (let lineNumber = 0; lineNumber < lines.length; ) {
|
||||
const line = lines[lineNumber];
|
||||
const line = lines[lineNumber]!;
|
||||
const match = line.match(directiveRegex);
|
||||
if (match !== null) {
|
||||
const directive = match.slice(1).find((item) => item !== undefined);
|
||||
|
|
|
@ -71,7 +71,7 @@ function readStorageState({
|
|||
pluginId,
|
||||
versionPersistence,
|
||||
);
|
||||
const pluginData = allDocsData[pluginId];
|
||||
const pluginData = allDocsData[pluginId]!;
|
||||
const versionExists = pluginData.versions.some(
|
||||
(version) => version.name === preferredVersionNameUnsafe,
|
||||
);
|
||||
|
|
|
@ -25,7 +25,7 @@ export function useDocsPreferredVersion(
|
|||
const docsData = useDocsData(pluginId);
|
||||
const [state, api] = useDocsPreferredVersionContext();
|
||||
|
||||
const {preferredVersionName} = state[pluginId];
|
||||
const {preferredVersionName} = state[pluginId]!;
|
||||
|
||||
const preferredVersion = preferredVersionName
|
||||
? docsData.versions.find((version) => version.name === preferredVersionName)
|
||||
|
@ -49,8 +49,8 @@ export function useDocsPreferredVersionByPluginId(): Record<
|
|||
const [state] = useDocsPreferredVersionContext();
|
||||
|
||||
function getPluginIdPreferredVersion(pluginId: string) {
|
||||
const docsData = allDocsData[pluginId];
|
||||
const {preferredVersionName} = state[pluginId];
|
||||
const docsData = allDocsData[pluginId]!;
|
||||
const {preferredVersionName} = state[pluginId]!;
|
||||
|
||||
return preferredVersionName
|
||||
? docsData.versions.find(
|
||||
|
|
|
@ -19,7 +19,7 @@ type TagsListItem = Readonly<{name: string; permalink: string; count: number}>;
|
|||
export type TagLetterEntry = Readonly<{letter: string; tags: TagsListItem[]}>;
|
||||
|
||||
function getTagLetter(tag: string): string {
|
||||
return tag[0].toUpperCase();
|
||||
return tag[0]!.toUpperCase();
|
||||
}
|
||||
|
||||
export function listTagsByLetters(
|
||||
|
@ -29,8 +29,8 @@ export function listTagsByLetters(
|
|||
const groups: Record<string, TagsListItem[]> = {};
|
||||
Object.values(tags).forEach((tag) => {
|
||||
const letter = getTagLetter(tag.name);
|
||||
groups[letter] = groups[letter] ?? [];
|
||||
groups[letter].push(tag);
|
||||
groups[letter] ??= [];
|
||||
groups[letter]!.push(tag);
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
|
@ -44,7 +44,7 @@ function treeifyTOC(flatTOC: readonly TOCItem[]): TOCTreeNode[] {
|
|||
headings.forEach((heading) => {
|
||||
const {parentIndex, ...rest} = heading;
|
||||
if (parentIndex >= 0) {
|
||||
headings[parentIndex].children.push(rest);
|
||||
headings[parentIndex]!.children.push(rest);
|
||||
} else {
|
||||
rootNodes.push(rest);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@ export function useContextualSearchFilters(): useContextualSearchFiltersReturns
|
|||
|
||||
const preferredVersion = docsPreferredVersionByPluginId[pluginId];
|
||||
|
||||
const latestVersion = allDocsData[pluginId].versions.find((v) => v.isLast)!;
|
||||
const latestVersion = allDocsData[pluginId]!.versions.find(
|
||||
(v) => v.isLast,
|
||||
)!;
|
||||
|
||||
const version = activeVersion ?? preferredVersion ?? latestVersion;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ function selectPluralMessage(
|
|||
const parts = pluralMessages.split(separator);
|
||||
|
||||
if (parts.length === 1) {
|
||||
return parts[0];
|
||||
return parts[0]!;
|
||||
}
|
||||
if (parts.length > localePluralForms.pluralForms.length) {
|
||||
console.error(
|
||||
|
@ -110,7 +110,7 @@ function selectPluralMessage(
|
|||
const pluralFormIndex = localePluralForms.pluralForms.indexOf(pluralForm);
|
||||
// In case of not enough plural form messages, we take the last one (other)
|
||||
// instead of returning undefined
|
||||
return parts[Math.min(pluralFormIndex, parts.length - 1)];
|
||||
return parts[Math.min(pluralFormIndex, parts.length - 1)]!;
|
||||
}
|
||||
|
||||
export function usePluralForm(): {
|
||||
|
|
|
@ -83,7 +83,7 @@ function getActiveAnchor(
|
|||
}
|
||||
// no anchor under viewport top? (ie we are at the bottom of the page)
|
||||
// => highlight the last anchor found
|
||||
return anchors[anchors.length - 1];
|
||||
return anchors[anchors.length - 1] ?? null;
|
||||
}
|
||||
|
||||
function getLinkAnchorValue(link: HTMLAnchorElement): string {
|
||||
|
|
|
@ -58,7 +58,7 @@ function useDocsSearchVersionsHelpers() {
|
|||
Object.entries(allDocsData).reduce(
|
||||
(acc, [pluginId, pluginData]) => ({
|
||||
...acc,
|
||||
[pluginId]: pluginData.versions[0].name,
|
||||
[pluginId]: pluginData.versions[0]!.name,
|
||||
}),
|
||||
{},
|
||||
),
|
||||
|
@ -277,7 +277,7 @@ export default function SearchPage(): JSX.Element {
|
|||
const {
|
||||
isIntersecting,
|
||||
boundingClientRect: {y: currentY},
|
||||
} = entries[0];
|
||||
} = entries[0]!;
|
||||
|
||||
if (isIntersecting && prevY.current > currentY) {
|
||||
searchResultStateDispatcher({type: 'advance'});
|
||||
|
|
|
@ -41,7 +41,7 @@ export default function applyTrailingSlash(
|
|||
}
|
||||
|
||||
// The trailing slash should be handled before the ?search#hash !
|
||||
const [pathname] = path.split(/[#?]/);
|
||||
const [pathname] = path.split(/[#?]/) as [string, ...string[]];
|
||||
|
||||
// Never transform '/' to ''
|
||||
// Never remove the baseUrl trailing slash!
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
*/
|
||||
|
||||
export const NODE_MAJOR_VERSION = parseInt(
|
||||
process.versions.node.split('.')[0],
|
||||
process.versions.node.split('.')[0]!,
|
||||
10,
|
||||
);
|
||||
export const NODE_MINOR_VERSION = parseInt(
|
||||
process.versions.node.split('.')[1],
|
||||
process.versions.node.split('.')[1]!,
|
||||
10,
|
||||
);
|
||||
|
||||
|
|
|
@ -48,12 +48,13 @@ export function replaceMarkdownLinks<T extends ContentPaths>({
|
|||
let lastCodeFence = '';
|
||||
const lines = fileString.split('\n').map((line) => {
|
||||
if (line.trim().startsWith('```')) {
|
||||
const codeFence = line.trim().match(/^`+/)![0]!;
|
||||
if (!fencedBlock) {
|
||||
fencedBlock = true;
|
||||
[lastCodeFence] = line.trim().match(/^`+/)!;
|
||||
lastCodeFence = codeFence;
|
||||
// If we are in a ````-fenced block, all ``` would be plain text instead
|
||||
// of fences
|
||||
} else if (line.trim().match(/^`+/)![0].length >= lastCodeFence.length) {
|
||||
} else if (codeFence.length >= lastCodeFence.length) {
|
||||
fencedBlock = false;
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +72,7 @@ export function replaceMarkdownLinks<T extends ContentPaths>({
|
|||
let mdMatch = mdRegex.exec(modifiedLine);
|
||||
while (mdMatch !== null) {
|
||||
// Replace it to correct html link.
|
||||
const mdLink = mdMatch.groups!.filename;
|
||||
const mdLink = mdMatch.groups!.filename!;
|
||||
|
||||
const sourcesToTry = [
|
||||
path.resolve(path.dirname(filePath), decodeURIComponent(mdLink)),
|
||||
|
|
|
@ -18,8 +18,8 @@ export function parseMarkdownHeadingId(heading: string): {
|
|||
const matches = customHeadingIdRegex.exec(heading);
|
||||
if (matches) {
|
||||
return {
|
||||
text: matches.groups!.text,
|
||||
id: matches.groups!.id,
|
||||
text: matches.groups!.text!,
|
||||
id: matches.groups!.id!,
|
||||
};
|
||||
}
|
||||
return {text: heading, id: undefined};
|
||||
|
@ -51,14 +51,13 @@ export function createExcerpt(fileString: string): string | undefined {
|
|||
|
||||
// Skip code block line.
|
||||
if (fileLine.trim().startsWith('```')) {
|
||||
const codeFence = fileLine.trim().match(/^`+/)![0]!;
|
||||
if (!inCode) {
|
||||
inCode = true;
|
||||
[lastCodeFence] = fileLine.trim().match(/^`+/)!;
|
||||
lastCodeFence = codeFence;
|
||||
// If we are in a ````-fenced block, all ``` would be plain text instead
|
||||
// of fences
|
||||
} else if (
|
||||
fileLine.trim().match(/^`+/)![0].length >= lastCodeFence.length
|
||||
) {
|
||||
} else if (codeFence.length >= lastCodeFence.length) {
|
||||
inCode = false;
|
||||
}
|
||||
continue;
|
||||
|
|
|
@ -80,13 +80,13 @@ export function groupTaggedItems<Item>(
|
|||
// TODO: it's not really clear what should be the behavior if 2 items have
|
||||
// the same tag but the permalink is different for each
|
||||
// For now, the first tag found wins
|
||||
result[tag.permalink] = result[tag.permalink] ?? {
|
||||
result[tag.permalink] ??= {
|
||||
tag,
|
||||
items: [],
|
||||
};
|
||||
|
||||
// Add item to group
|
||||
result[tag.permalink].items.push(item);
|
||||
result[tag.permalink]!.items.push(item);
|
||||
}
|
||||
|
||||
items.forEach((item) => {
|
||||
|
|
|
@ -15,10 +15,17 @@ export function normalizeUrl(rawUrls: string[]): string {
|
|||
let hasStartingSlash = false;
|
||||
let hasEndingSlash = false;
|
||||
|
||||
const isNonEmptyArray = (arr: string[]): arr is [string, ...string[]] =>
|
||||
arr.length > 0;
|
||||
|
||||
if (!isNonEmptyArray(urls)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// If the first part is a plain protocol, we combine it with the next part.
|
||||
if (urls[0].match(/^[^/:]+:\/*$/) && urls.length > 1) {
|
||||
const first = urls.shift();
|
||||
if (first!.startsWith('file:') && urls[0].startsWith('/')) {
|
||||
const first = urls.shift()!;
|
||||
if (first.startsWith('file:') && urls[0].startsWith('/')) {
|
||||
// Force a double slash here, else we lose the information that the next
|
||||
// segment is an absolute path
|
||||
urls[0] = `${first}//${urls[0]}`;
|
||||
|
|
|
@ -38,7 +38,7 @@ function clearConsole(): void {
|
|||
function getProcessIdOnPort(port: number): string {
|
||||
return execSync(`lsof -i:${port} -P -t -sTCP:LISTEN`, execOptions)
|
||||
.toString()
|
||||
.split('\n')[0]
|
||||
.split('\n')[0]!
|
||||
.trim();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class PendingNavigation extends React.Component<Props, State> {
|
|||
|
||||
// Intercept location update and still show current route until next route
|
||||
// is done loading.
|
||||
shouldComponentUpdate(nextProps: Props, nextState: State) {
|
||||
override shouldComponentUpdate(nextProps: Props, nextState: State) {
|
||||
const routeDidChange = nextProps.location !== this.props.location;
|
||||
const {routes, delay} = this.props;
|
||||
|
||||
|
@ -116,7 +116,7 @@ class PendingNavigation extends React.Component<Props, State> {
|
|||
nprogress.done();
|
||||
}
|
||||
|
||||
render() {
|
||||
override render() {
|
||||
const {children, location} = this.props;
|
||||
return (
|
||||
<Route location={normalizeLocation(location)} render={() => children} />
|
||||
|
|
|
@ -27,7 +27,7 @@ export default function ComponentCreator(
|
|||
}
|
||||
|
||||
const chunkNamesKey = `${path}-${hash}`;
|
||||
const chunkNames = routesChunkNames[chunkNamesKey];
|
||||
const chunkNames = routesChunkNames[chunkNamesKey]!;
|
||||
const optsModules: string[] = [];
|
||||
const optsWebpack: string[] = [];
|
||||
const optsLoader: OptsLoader = {};
|
||||
|
@ -47,8 +47,8 @@ export default function ComponentCreator(
|
|||
]
|
||||
*/
|
||||
const flatChunkNames = flat(chunkNames);
|
||||
Object.keys(flatChunkNames).forEach((key) => {
|
||||
const chunkRegistry = registry[flatChunkNames[key]];
|
||||
Object.entries(flatChunkNames).forEach(([key, chunkName]) => {
|
||||
const chunkRegistry = registry[chunkName];
|
||||
if (chunkRegistry) {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
optsLoader[key] = chunkRegistry[0];
|
||||
|
@ -68,16 +68,16 @@ export default function ComponentCreator(
|
|||
Object.keys(loaded).forEach((key) => {
|
||||
let val = loadedModules;
|
||||
const keyPath = key.split('.');
|
||||
for (let i = 0; i < keyPath.length - 1; i += 1) {
|
||||
val = val[keyPath[i]];
|
||||
}
|
||||
val[keyPath[keyPath.length - 1]] = loaded[key].default;
|
||||
keyPath.slice(0, -1).forEach((k) => {
|
||||
val = val[k];
|
||||
});
|
||||
val[keyPath[keyPath.length - 1]!] = loaded[key].default;
|
||||
const nonDefaultKeys = Object.keys(loaded[key]).filter(
|
||||
(k) => k !== 'default',
|
||||
);
|
||||
if (nonDefaultKeys && nonDefaultKeys.length) {
|
||||
nonDefaultKeys.forEach((nonDefaultKey) => {
|
||||
val[keyPath[keyPath.length - 1]][nonDefaultKey] =
|
||||
val[keyPath[keyPath.length - 1]!][nonDefaultKey] =
|
||||
loaded[key][nonDefaultKey];
|
||||
});
|
||||
}
|
||||
|
|
|
@ -21,14 +21,14 @@ export default class ErrorBoundary extends React.Component<Props, State> {
|
|||
this.state = {error: null};
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error): void {
|
||||
override componentDidCatch(error: Error): void {
|
||||
// Catch errors in any components below and re-render with error message
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
this.setState({error});
|
||||
}
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
override render(): ReactNode {
|
||||
const {children} = this.props;
|
||||
const {error} = this.state;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ function getLocalizedMessage({
|
|||
);
|
||||
}
|
||||
|
||||
return codeTranslations[(id ?? message)!] ?? message ?? id;
|
||||
return codeTranslations[(id ?? message)!] ?? message ?? id!;
|
||||
}
|
||||
|
||||
// Imperative translation API is useful for some edge-cases:
|
||||
|
|
|
@ -15,8 +15,7 @@ export default function flat(target: RouteChunksTree): Record<string, string> {
|
|||
const output: Record<string, string> = {};
|
||||
|
||||
function step(object: RouteChunksTree, prefix?: string | number) {
|
||||
Object.keys(object).forEach((key: string | number) => {
|
||||
const value = object[key];
|
||||
Object.entries(object).forEach(([key, value]) => {
|
||||
const newKey = prefix ? `${prefix}${delimiter}${key}` : key;
|
||||
|
||||
if (isTree(value)) {
|
||||
|
|
|
@ -37,9 +37,9 @@ function linkPrefetchStrategy(url: string) {
|
|||
link.onerror = reject;
|
||||
|
||||
const parentElement =
|
||||
document.getElementsByTagName('head')[0] ||
|
||||
document.getElementsByName('script')[0].parentNode;
|
||||
parentElement.appendChild(link);
|
||||
document.getElementsByTagName('head')[0] ??
|
||||
document.getElementsByName('script')[0]?.parentNode;
|
||||
parentElement?.appendChild(link);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ async function doRender(locals: Locals & {path: string}) {
|
|||
ssrTemplate,
|
||||
noIndex,
|
||||
} = locals;
|
||||
const location = routesLocation[locals.path];
|
||||
const location = routesLocation[locals.path]!;
|
||||
await preload(routes, location);
|
||||
const modules = new Set<string>();
|
||||
const context = {};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import type {ReactNode} from 'react';
|
||||
import React, {type ReactNode} from 'react';
|
||||
|
||||
// Wrapper at the very top of the app, that is applied constantly
|
||||
// and does not depend on current route (unlike the layout)
|
||||
|
@ -14,6 +14,6 @@ import type {ReactNode} from 'react';
|
|||
// and these providers won't reset state when we navigate
|
||||
//
|
||||
// See https://github.com/facebook/docusaurus/issues/3919
|
||||
export default function Root({children}: {children: ReactNode}): ReactNode {
|
||||
return children;
|
||||
export default function Root({children}: {children: ReactNode}): JSX.Element {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ export default async function build(
|
|||
|
||||
// We need the default locale to always be the 1st in the list. If we build it
|
||||
// last, it would "erase" the localized sites built in sub-folders
|
||||
const orderedLocales: string[] = [
|
||||
const orderedLocales: [string, ...string[]] = [
|
||||
i18n.defaultLocale,
|
||||
...i18n.locales.filter((locale) => locale !== i18n.defaultLocale),
|
||||
];
|
||||
|
@ -89,7 +89,7 @@ export default async function build(
|
|||
orderedLocales.indexOf(locale) === orderedLocales.length - 1;
|
||||
return tryToBuildLocale({locale, isLastLocale});
|
||||
});
|
||||
return results[0];
|
||||
return results[0]!;
|
||||
}
|
||||
|
||||
async function buildLocale({
|
||||
|
|
|
@ -30,7 +30,7 @@ export async function initSwizzleContext(
|
|||
|
||||
return {
|
||||
plugins: plugins.map((plugin, pluginIndex) => ({
|
||||
plugin: pluginsNormalized[pluginIndex],
|
||||
plugin: pluginsNormalized[pluginIndex]!,
|
||||
instance: plugin,
|
||||
})),
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ type BrokenLink = {
|
|||
|
||||
// matchRoutes does not support qs/anchors, so we remove it!
|
||||
function onlyPathname(link: string) {
|
||||
return link.split('#')[0].split('?')[0];
|
||||
return link.split('#')[0]!.split('?')[0]!;
|
||||
}
|
||||
|
||||
function getPageBrokenLinks({
|
||||
|
|
|
@ -359,13 +359,13 @@ export default ${JSON.stringify(siteConfig, null, 2)};`,
|
|||
generatedFilesDir,
|
||||
'registry.js',
|
||||
`export default {
|
||||
${Object.keys(registry)
|
||||
.sort()
|
||||
${Object.entries(registry)
|
||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||
.map(
|
||||
(key) =>
|
||||
` '${key}': [${registry[key].loader}, '${escapePath(
|
||||
registry[key].modulePath,
|
||||
)}', require.resolveWeak('${escapePath(registry[key].modulePath)}')],`,
|
||||
([key, chunk]) =>
|
||||
` '${key}': [${chunk.loader}, '${escapePath(
|
||||
chunk.modulePath,
|
||||
)}', require.resolveWeak('${escapePath(chunk.modulePath)}')],`,
|
||||
)
|
||||
.join('\n')}};\n`,
|
||||
);
|
||||
|
|
|
@ -126,7 +126,7 @@ export async function loadPlugins({
|
|||
.mapValues((nameItems) =>
|
||||
_.chain(nameItems)
|
||||
.groupBy((item) => item.options.id ?? DEFAULT_PLUGIN_ID)
|
||||
.mapValues((idItems) => idItems[0].content)
|
||||
.mapValues((idItems) => idItems[0]!.content)
|
||||
.value(),
|
||||
)
|
||||
.value();
|
||||
|
@ -177,7 +177,7 @@ export async function loadPlugins({
|
|||
data,
|
||||
) => {
|
||||
globalData[plugin.name] = globalData[plugin.name] ?? {};
|
||||
globalData[plugin.name][pluginId] = data;
|
||||
globalData[plugin.name]![pluginId] = data;
|
||||
};
|
||||
|
||||
const actions: PluginContentLoadedActions = {
|
||||
|
|
|
@ -249,8 +249,8 @@ function genRouteChunkNames(
|
|||
}
|
||||
|
||||
const newValue: ChunkNames = {};
|
||||
Object.keys(value).forEach((key) => {
|
||||
newValue[key] = genRouteChunkNames(registry, value[key], key, name);
|
||||
Object.entries(value).forEach(([key, v]) => {
|
||||
newValue[key] = genRouteChunkNames(registry, v, key, name);
|
||||
});
|
||||
return newValue;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ export async function loadThemeAliases(
|
|||
|
||||
for (const themePath of themePaths) {
|
||||
const themeAliases = await themeAlias(themePath, true);
|
||||
Object.keys(themeAliases).forEach((aliasKey) => {
|
||||
Object.entries(themeAliases).forEach(([aliasKey, alias]) => {
|
||||
// If this alias shadows a previous one, use @theme-init to preserve the
|
||||
// initial one. @theme-init is only applied once: to the initial theme
|
||||
// that provided this component
|
||||
|
@ -28,10 +28,10 @@ export async function loadThemeAliases(
|
|||
const componentName = aliasKey.substring(aliasKey.indexOf('/') + 1);
|
||||
const initAlias = `@theme-init/${componentName}`;
|
||||
if (!(initAlias in aliases)) {
|
||||
aliases[initAlias] = aliases[aliasKey];
|
||||
aliases[initAlias] = aliases[aliasKey]!;
|
||||
}
|
||||
}
|
||||
aliases[aliasKey] = themeAliases[aliasKey];
|
||||
aliases[aliasKey] = alias;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -340,7 +340,7 @@ ${sourceWarningPart(path.node)}`,
|
|||
|
||||
const args = path.get('arguments');
|
||||
if (args.length === 1 || args.length === 2) {
|
||||
const firstArgPath = args[0];
|
||||
const firstArgPath = args[0]!;
|
||||
|
||||
// translate("x" + "y"); => translate("xy");
|
||||
const firstArgEvaluated = firstArgPath.evaluate();
|
||||
|
|
|
@ -25,11 +25,12 @@ export default class ChunkAssetPlugin {
|
|||
compiler.hooks.thisCompilation.tap(pluginName, ({mainTemplate}) => {
|
||||
mainTemplate.hooks.requireExtensions.tap(pluginName, (source, chunk) => {
|
||||
const chunkIdToName = chunk.getChunkMaps(false).name;
|
||||
const chunkNameToId = Object.create(null);
|
||||
Object.keys(chunkIdToName).forEach((chunkId) => {
|
||||
const chunkName = chunkIdToName[chunkId];
|
||||
chunkNameToId[chunkName] = chunkId;
|
||||
});
|
||||
const chunkNameToId = Object.fromEntries(
|
||||
Object.entries(chunkIdToName).map(([chunkId, chunkName]) => [
|
||||
chunkName,
|
||||
chunkId,
|
||||
]),
|
||||
);
|
||||
const buf = [source];
|
||||
buf.push('// function to get chunk asset');
|
||||
buf.push(
|
||||
|
|
|
@ -14,7 +14,7 @@ function showError(arr: string[]) {
|
|||
}
|
||||
|
||||
export default class LogPlugin extends WebpackBar {
|
||||
apply(compiler: Compiler): void {
|
||||
override apply(compiler: Compiler): void {
|
||||
super.apply(compiler);
|
||||
|
||||
// TODO can't this be done in compile(configs) alongside the warnings???
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
"tsBuildInfoFile": "./lib/.tsbuildinfo",
|
||||
"rootDir": "src",
|
||||
"outDir": "lib",
|
||||
"jsx": "react",
|
||||
"allowJs": true
|
||||
},
|
||||
"include": ["src"],
|
||||
|
|
|
@ -39,7 +39,7 @@ export default async function lqipLoader(
|
|||
if (contentIsUrlExport) {
|
||||
source = content.match(
|
||||
/^(?:export default|module.exports =) (?<source>.*)/,
|
||||
)!.groups!.source;
|
||||
)!.groups!.source!;
|
||||
} else {
|
||||
if (!contentIsFileExport) {
|
||||
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
||||
|
@ -48,7 +48,7 @@ export default async function lqipLoader(
|
|||
}
|
||||
source = content.match(
|
||||
/^(?:export default|module.exports =) (?<source>.*);/,
|
||||
)!.groups!.source;
|
||||
)!.groups!.source!;
|
||||
}
|
||||
|
||||
const outputPromises: [Promise<string> | null, Promise<string[]> | null] = [
|
||||
|
|
|
@ -25,14 +25,15 @@ const SUPPORTED_MIMES: Record<string, string> = {
|
|||
export async function base64(file: string): Promise<string> {
|
||||
let extension = path.extname(file);
|
||||
extension = extension.split('.').pop()!;
|
||||
const mime = SUPPORTED_MIMES[extension];
|
||||
|
||||
if (!SUPPORTED_MIMES[extension]) {
|
||||
if (!mime) {
|
||||
throw new Error(ERROR_EXT);
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await sharp(file).resize(10).toBuffer();
|
||||
return toBase64(SUPPORTED_MIMES[extension], data);
|
||||
return toBase64(mime, data);
|
||||
} catch (err) {
|
||||
logger.error`Generation of base64 failed for image path=${file}.`;
|
||||
throw err;
|
||||
|
|
|
@ -1,42 +1,48 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Emit */
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"declaration": true,
|
||||
"declarationMap": false,
|
||||
"jsx": "react",
|
||||
"importHelpers": true,
|
||||
"noEmitHelpers": true,
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
|
||||
/* Additional Checks */
|
||||
"noUnusedLocals": false, // ensured by eslint, should not block compilation
|
||||
"noImplicitReturns": true,
|
||||
"allowUnreachableCode": false,
|
||||
// Too hard to turn on
|
||||
"exactOptionalPropertyTypes": false,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
/* Disabled on purpose (handled by ESLint, should not block compilation) */
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
// `process.env` is usually accessed as property
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
/* strict family */
|
||||
"strict": true,
|
||||
"alwaysStrict": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
/* Handled by ESLint */
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"importsNotUsedAsValues": "remove",
|
||||
|
||||
/* Module Resolution Options */
|
||||
/* Module Resolution */
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
|
||||
/* Advanced Options */
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true, // @types/webpack and webpack/types.d.ts are not the same thing
|
||||
|
||||
/* Use tslib */
|
||||
"importHelpers": true,
|
||||
"noEmitHelpers": true
|
||||
"skipLibCheck": true // @types/webpack and webpack/types.d.ts are not the same thing
|
||||
},
|
||||
"exclude": ["node_modules", "**/__tests__/**/*", "**/lib/**/*"]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue