From 1cefb643dd9616863bad9fc4d7a0e2307eb07506 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Tue, 1 Feb 2022 17:43:15 +0800 Subject: [PATCH] refactor: enforce named capture groups; clean up regexes (#6524) * refactor: enforce named capture groups; clean up regexes * fixes * fix --- .eslintrc.js | 1 + .../docusaurus-migrate/src/frontMatter.ts | 4 +-- .../src/blogUtils.ts | 4 +-- .../src/index.ts | 2 +- .../src/pluginOptionSchema.ts | 2 +- .../src/index.ts | 2 +- .../src/lastUpdate.ts | 10 +++--- .../src/numberPrefix.ts | 4 +-- .../src/sidebars/validation.ts | 2 +- .../src/index.ts | 2 +- .../src/index.ts | 2 +- packages/docusaurus-plugin-pwa/src/index.ts | 2 +- .../src/utils/codeBlockUtils.ts | 9 ++--- .../src/__tests__/markdownParser.test.ts | 2 +- packages/docusaurus-utils/src/index.ts | 4 +-- .../docusaurus-utils/src/markdownLinks.ts | 4 +-- .../docusaurus-utils/src/markdownParser.ts | 34 ++++++++++--------- packages/docusaurus-utils/src/urlUtils.ts | 6 ++-- packages/docusaurus-utils/src/webpackUtils.ts | 12 +++---- packages/docusaurus/src/client/docusaurus.ts | 2 +- .../src/client/exports/isInternalUrl.ts | 2 +- .../docusaurus/src/client/serverEntry.tsx | 2 +- packages/docusaurus/src/commands/deploy.ts | 2 +- packages/docusaurus/src/commands/swizzle.ts | 4 +-- .../src/commands/writeHeadingIds.ts | 2 +- .../src/server/__tests__/config.test.ts | 2 +- packages/docusaurus/src/server/index.ts | 2 +- .../docusaurus/src/server/moduleShorthand.ts | 2 +- packages/docusaurus/src/server/routes.ts | 2 +- packages/docusaurus/src/webpack/base.ts | 8 ++--- packages/lqip-loader/src/index.ts | 17 +++++----- website/src/plugins/changelog/index.js | 2 +- 32 files changed, 80 insertions(+), 77 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ec890ace34..d64979dbda 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -100,6 +100,7 @@ module.exports = { 'no-restricted-syntax': WARNING, 'no-unused-expressions': [WARNING, {allowTaggedTemplates: true}], 'prefer-destructuring': WARNING, + 'prefer-named-capture-group': WARNING, 'prefer-template': WARNING, yoda: WARNING, diff --git a/packages/docusaurus-migrate/src/frontMatter.ts b/packages/docusaurus-migrate/src/frontMatter.ts index cd83993f04..ca07bcad6b 100644 --- a/packages/docusaurus-migrate/src/frontMatter.ts +++ b/packages/docusaurus-migrate/src/frontMatter.ts @@ -59,7 +59,7 @@ export function shouldQuotifyFrontMatter([key, value]: [ if (key === 'tags') { return false; } - if (String(value).match(/^("|').+("|')$/)) { + if (String(value).match(/^(?["']).+\1$/)) { return false; } // title: !something needs quotes because otherwise it's a YAML tag. @@ -69,6 +69,6 @@ export function shouldQuotifyFrontMatter([key, value]: [ // TODO this is not ideal to have to maintain such a list of allowed chars // maybe we should quotify if gray-matter throws instead? return !String(value).match( - /^([\w .\-sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ!;,=+_?'`&#()[\]§%€$])+$/, + /^[\w .\-sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ!;,=+_?'`&#()[\]§%€$]+$/, ); } diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 34d315127c..e084edea3d 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -63,7 +63,7 @@ export function getBlogTags(blogPosts: BlogPost[]): BlogTags { } const DATE_FILENAME_REGEX = - /^(?.*)(?\d{4}[-/]\d{1,2}[-/]\d{1,2})[-/]?(?.*?)(\/index)?.mdx?$/; + /^(?.*)(?\d{4}[-/]\d{1,2}[-/]\d{1,2})[-/]?(?.*?)(?:\/index)?.mdx?$/; type ParsedBlogFileName = { date: Date | undefined; @@ -83,7 +83,7 @@ export function parseBlogFileName( const slug = `/${slugDate}/${folder}${text}`; return {date, text, slug}; } - const text = blogSourceRelative.replace(/(\/index)?\.mdx?$/, ''); + const text = blogSourceRelative.replace(/(?:\/index)?\.mdx?$/, ''); const slug = `/${text}`; return {date: undefined, text, slug}; } diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 750d0489ec..dd4eb9f34d 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -452,7 +452,7 @@ export default async function pluginContentBlog( module: { rules: [ { - test: /(\.mdx?)$/, + test: /\.mdx?$/i, include: contentDirs // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970 .map(addTrailingPathSeparator), diff --git a/packages/docusaurus-plugin-content-blog/src/pluginOptionSchema.ts b/packages/docusaurus-plugin-content-blog/src/pluginOptionSchema.ts index d72d9bea6e..f0f5a5cf82 100644 --- a/packages/docusaurus-plugin-content-blog/src/pluginOptionSchema.ts +++ b/packages/docusaurus-plugin-content-blog/src/pluginOptionSchema.ts @@ -20,7 +20,7 @@ export const DEFAULT_OPTIONS: PluginOptions = { beforeDefaultRehypePlugins: [], beforeDefaultRemarkPlugins: [], admonitions: {}, - truncateMarker: //, + truncateMarker: //, rehypePlugins: [], remarkPlugins: [], showReadingTime: true, diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index f15f0ca729..df71049e60 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -333,7 +333,7 @@ export default async function pluginContentDocs( function createMDXLoaderRule(): RuleSetRule { const contentDirs = versionsMetadata.flatMap(getDocsDirPaths); return { - test: /(\.mdx?)$/, + test: /\.mdx?$/i, include: contentDirs // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970 .map(addTrailingPathSeparator), diff --git a/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts b/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts index b78c4146c3..87dde70cf0 100644 --- a/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts +++ b/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts @@ -10,7 +10,7 @@ import logger from '@docusaurus/logger'; type FileLastUpdateData = {timestamp?: number; author?: string}; -const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+),(.+)$/; +const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(?\d+),(?.+)$/; let showedGitRequirementError = false; @@ -25,10 +25,10 @@ export async function getFileLastUpdate( return null; } - const temp = str.match(GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX); - return !temp || temp.length < 3 - ? null - : {timestamp: +temp[1], author: temp[2]}; + const temp = str.match(GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX)?.groups; + return temp + ? {timestamp: Number(temp.timestamp), author: temp.author} + : null; } // Wrap in try/catch in case the shell commands fail diff --git a/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts b/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts index 100b377830..b91fc6d35b 100644 --- a/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts +++ b/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts @@ -11,14 +11,14 @@ import type {NumberPrefixParser} from '@docusaurus/plugin-content-docs'; const IgnoredPrefixPatterns = (() => { // ignore common date-like patterns: https://github.com/facebook/docusaurus/issues/4640 const DateLikePrefixRegex = - /^((\d{2}|\d{4})[-_.]\d{2}([-_.](\d{2}|\d{4}))?)(.*)$/; + /^(?:\d{2}|\d{4})[-_.]\d{2}(?:[-_.](?:\d{2}|\d{4}))?.*$/; // ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653 // note: we could try to parse float numbers in filenames but that is // probably not worth it as a version such as "8.0" can be interpreted as both // a version and a float. User can configure her own NumberPrefixParser if // she wants 8.0 to be interpreted as a float - const VersionLikePrefixRegex = /^(\d+[-_.]\d+)(.*)$/; + const VersionLikePrefixRegex = /^\d+[-_.]\d+.*$/; return new RegExp( `${DateLikePrefixRegex.source}|${VersionLikePrefixRegex.source}`, diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts index 9b6845a877..ac00bf455c 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/validation.ts @@ -36,7 +36,7 @@ const sidebarItemAutogeneratedSchema = type: 'autogenerated', dirName: Joi.string() .required() - .pattern(/^[^/](.*[^/])?$/) + .pattern(/^[^/](?:.*[^/])?$/) .message( '"dirName" must be a dir path relative to the docs folder root, and should not start or end with slash', ), diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index b5cee171af..4a8fc3ca26 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -199,7 +199,7 @@ export default async function pluginContentPages( module: { rules: [ { - test: /(\.mdx?)$/, + test: /\.mdx?$/i, include: contentDirs // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970 .map(addTrailingPathSeparator), diff --git a/packages/docusaurus-plugin-ideal-image/src/index.ts b/packages/docusaurus-plugin-ideal-image/src/index.ts index 9b6630e14c..e82165e581 100644 --- a/packages/docusaurus-plugin-ideal-image/src/index.ts +++ b/packages/docusaurus-plugin-ideal-image/src/index.ts @@ -57,7 +57,7 @@ export default function pluginIdealImage( module: { rules: [ { - test: /\.(png|jpe?g|gif)$/i, + test: /\.(?:png|jpe?g|gif)$/i, use: [ require.resolve('@docusaurus/lqip-loader'), { diff --git a/packages/docusaurus-plugin-pwa/src/index.ts b/packages/docusaurus-plugin-pwa/src/index.ts index a03a1cfdb2..04142b2b3c 100644 --- a/packages/docusaurus-plugin-pwa/src/index.ts +++ b/packages/docusaurus-plugin-pwa/src/index.ts @@ -174,7 +174,7 @@ export default function pluginPWA( rules: [ { test: swSourceFileTest, - exclude: /(node_modules)/, + exclude: /node_modules/, use: getSWBabelLoader(), }, ], diff --git a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts index a279afc5fd..d7f239489a 100644 --- a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts @@ -7,8 +7,8 @@ import rangeParser from 'parse-numeric-range'; -const codeBlockTitleRegex = /title=(["'])(.*?)\1/; -const highlightLinesRangeRegex = /{([\d,-]+)}/; +const codeBlockTitleRegex = /title=(?["'])(?.*?)\1/; +const highlightLinesRangeRegex = /{(?<range>[\d,-]+)}/; const commentTypes = ['js', 'jsBlock', 'jsx', 'python', 'html'] as const; type CommentType = typeof commentTypes[number]; @@ -89,7 +89,7 @@ const magicCommentDirectiveRegex = (lang: string) => { }; export function parseCodeBlockTitle(metastring?: string): string { - return metastring?.match(codeBlockTitleRegex)?.[2] ?? ''; + return metastring?.match(codeBlockTitleRegex)?.groups!.title ?? ''; } export function parseLanguage(className: string): string | undefined { @@ -114,7 +114,8 @@ export function parseLines( let code = content.replace(/\n$/, ''); // Highlighted lines specified in props: don't parse the content if (metastring && highlightLinesRangeRegex.test(metastring)) { - const highlightLinesRange = metastring.match(highlightLinesRangeRegex)![1]; + const highlightLinesRange = metastring.match(highlightLinesRangeRegex)! + .groups!.range; const highlightLines = rangeParser(highlightLinesRange) .filter((n) => n > 0) .map((n) => n - 1); diff --git a/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts b/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts index 6b8579f8e4..1943593c3c 100644 --- a/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts +++ b/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts @@ -116,7 +116,7 @@ describe('createExcerpt', () => { export function ItemCol(props) { return <Item {...props} className={'col col--6 margin-bottom--lg'}/> }; - Lorem **ipsum** dolor sit \`amet\`[^1], consectetur _adipiscing_ elit. [**Vestibulum**](https://wiktionary.org/wiki/vestibulum) ex urna[^bignote], ~molestie~ et sagittis ut, varius ac justo :wink:. + Lorem **ipsum** dolor sit \`amet\`[^1], consectetur _adipiscing_ elit. [**Vestibulum**](https://wiktionary.org/wiki/vestibulum) ex urna[^bignote], ~~molestie~~ et sagittis ut, varius ac justo :wink:. Nunc porttitor libero nec vulputate venenatis. Nam nec rhoncus mauris. Morbi tempus est et nibh maximus, tempus venenatis arcu lobortis. `), diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 4e3b3538f3..4aed2648b2 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -69,8 +69,8 @@ export async function generate( } } -const indexRE = /(^|.*\/)index\.(md|mdx|js|jsx|ts|tsx)$/i; -const extRE = /\.(md|mdx|js|jsx|ts|tsx)$/; +const indexRE = /(?<dirname>^|.*\/)index\.(?:mdx?|jsx?|tsx?)$/i; +const extRE = /\.(?:mdx?|jsx?|tsx?)$/; /** * Convert filepath to url path. diff --git a/packages/docusaurus-utils/src/markdownLinks.ts b/packages/docusaurus-utils/src/markdownLinks.ts index bf3d5cbf4e..8831c05e0c 100644 --- a/packages/docusaurus-utils/src/markdownLinks.ts +++ b/packages/docusaurus-utils/src/markdownLinks.ts @@ -67,11 +67,11 @@ export function replaceMarkdownLinks<T extends ContentPaths>({ // ink // [doc1]: doc1.md -> we replace this doc1.md with correct link const mdRegex = - /(?:(?:\]\()|(?:\]:\s?))(?!https?:\/\/|@site\/)([^'")\]\s>]+\.mdx?)/g; + /(?:(?:\]\()|(?:\]:\s?))(?!https?:\/\/|@site\/)(?<filename>[^'")\]\s>]+\.mdx?)/g; let mdMatch = mdRegex.exec(modifiedLine); while (mdMatch !== null) { // Replace it to correct html link. - const mdLink = mdMatch[1]; + const mdLink = mdMatch.groups!.filename; const sourcesToTry = [ path.resolve(path.dirname(filePath), decodeURIComponent(mdLink)), diff --git a/packages/docusaurus-utils/src/markdownParser.ts b/packages/docusaurus-utils/src/markdownParser.ts index 5f25fd9415..44dc31f9ee 100644 --- a/packages/docusaurus-utils/src/markdownParser.ts +++ b/packages/docusaurus-utils/src/markdownParser.ts @@ -14,12 +14,12 @@ export function parseMarkdownHeadingId(heading: string): { text: string; id?: string; } { - const customHeadingIdRegex = /^(.*?)\s*\{#([\w-]+)\}$/; + const customHeadingIdRegex = /^(?<text>.*?)\s*\{#(?<id>[\w-]+)\}$/; const matches = customHeadingIdRegex.exec(heading); if (matches) { return { - text: matches[1], - id: matches[2], + text: matches.groups!.text, + id: matches.groups!.id, }; } return {text: heading, id: undefined}; @@ -46,7 +46,7 @@ export function createExcerpt(fileString: string): string | undefined { } // Skip import/export declaration. - if (/^\s*?import\s.*(from.*)?;?|export\s.*{.*};?/.test(fileLine)) { + if (/^(?:import|export)\s.*/.test(fileLine)) { continue; } @@ -71,25 +71,27 @@ export function createExcerpt(fileString: string): string | undefined { // Remove HTML tags. .replace(/<[^>]*>/g, '') // Remove Title headers - .replace(/^#\s*([^#]*)\s*#?/gm, '') + .replace(/^#\s*[^#]*\s*#?/gm, '') // Remove Markdown + ATX-style headers - .replace(/^#{1,6}\s*([^#]*)\s*(#{1,6})?/gm, '$1') - // Remove emphasis and strikethroughs. - .replace(/([*_~]{1,3})(\S.*?\S{0,1})\1/g, '$2') + .replace(/^#{1,6}\s*(?<text>[^#]*)\s*(?:#{1,6})?/gm, '$1') + // Remove emphasis. + .replace(/(?<opening>[*_]{1,3})(?<text>.*?)\1/g, '$2') + // Remove strikethroughs. + .replace(/~~(?<text>\S.*\S)~~/g, '$1') // Remove images. - .replace(/!\[(.*?)\][[(].*?[\])]/g, '$1') + .replace(/!\[(?<alt>.*?)\][[(].*?[\])]/g, '$1') // Remove footnotes. - .replace(/\[\^.+?\](: .*?$)?/g, '') + .replace(/\[\^.+?\](?:: .*?$)?/g, '') // Remove inline links. - .replace(/\[(.*?)\][[(].*?[\])]/g, '$1') + .replace(/\[(?<alt>.*?)\][[(].*?[\])]/g, '$1') // Remove inline code. - .replace(/`(.+?)`/g, '$1') + .replace(/`(?<text>.+?)`/g, '$1') // Remove blockquotes. .replace(/^\s{0,3}>\s?/g, '') // Remove admonition definition. - .replace(/(:{3}.*)/, '') + .replace(/:::.*/, '') // Remove Emoji names within colons include preceding whitespace. - .replace(/\s?(:(::|[^:\n])+:)/g, '') + .replace(/\s?:(?:::|[^:\n])+:/g, '') // Remove custom Markdown heading id. .replace(/{#*[\w-]+}/, '') .trim(); @@ -134,9 +136,9 @@ export function parseMarkdownContentTitle( const content = contentUntrimmed.trim(); const IMPORT_STATEMENT = - /import\s+(([\w*{}\s\n,]+)from\s+)?["'\s]([@\w/_.-]+)["'\s];?|\n/.source; + /import\s+(?:[\w*{}\s\n,]+from\s+)?["'\s][@\w/_.-]+["'\s];?|\n/.source; const REGULAR_TITLE = - /(?<pattern>#\s*(?<title>[^#\n{]*)+[ \t]*(?<suffix>({#*[\w-]+})|#)?\n*?)/ + /(?<pattern>#\s*(?<title>[^#\n{]*)+[ \t]*(?<suffix>(?:{#*[\w-]+})|#)?\n*?)/ .source; const ALTERNATE_TITLE = /(?<pattern>\s*(?<title>[^\n]*)\s*\n[=]+)/.source; diff --git a/packages/docusaurus-utils/src/urlUtils.ts b/packages/docusaurus-utils/src/urlUtils.ts index dacbd1f186..36417158fe 100644 --- a/packages/docusaurus-utils/src/urlUtils.ts +++ b/packages/docusaurus-utils/src/urlUtils.ts @@ -27,7 +27,7 @@ export function normalizeUrl(rawUrls: string[]): string { // There must be two or three slashes in the file protocol, // two slashes in anything else. const replacement = urls[0].match(/^file:\/\/\//) ? '$1:///' : '$1://'; - urls[0] = urls[0].replace(/^([^/:]+):\/*/, replacement); + urls[0] = urls[0].replace(/^(?<protocol>[^/:]+):\/*/, replacement); for (let i = 0; i < urls.length; i += 1) { let component = urls[i]; @@ -70,14 +70,14 @@ export function normalizeUrl(rawUrls: string[]): string { // except the possible first plain protocol part. // Remove trailing slash before parameters or hash. - str = str.replace(/\/(\?|&|#[^!])/g, '$1'); + str = str.replace(/\/(?<search>\?|&|#[^!])/g, '$1'); // Replace ? in parameters with &. const parts = str.split('?'); str = parts.shift() + (parts.length > 0 ? '?' : '') + parts.join('&'); // Dedupe forward slashes in the entire path, avoiding protocol slashes. - str = str.replace(/([^:/]\/)\/+/g, '$1'); + str = str.replace(/(?<textBefore>[^:/]\/)\/+/g, '$1'); // Dedupe forward slashes at the beginning of the path. str = str.replace(/^\/+/g, '/'); diff --git a/packages/docusaurus-utils/src/webpackUtils.ts b/packages/docusaurus-utils/src/webpackUtils.ts index 499365c400..0e231a121f 100644 --- a/packages/docusaurus-utils/src/webpackUtils.ts +++ b/packages/docusaurus-utils/src/webpackUtils.ts @@ -79,12 +79,12 @@ export function getFileLoaderUtils(): FileLoaderUtils { */ images: () => ({ use: [loaders.url({folder: 'images'})], - test: /\.(ico|jpg|jpeg|png|gif|webp)(\?.*)?$/, + test: /\.(?:ico|jpe?g|png|gif|webp)(?:\?.*)?$/i, }), fonts: () => ({ use: [loaders.url({folder: 'fonts'})], - test: /\.(woff|woff2|eot|ttf|otf)$/, + test: /\.(?:woff2?|eot|ttf|otf)$/i, }), /** @@ -93,11 +93,11 @@ export function getFileLoaderUtils(): FileLoaderUtils { */ media: () => ({ use: [loaders.url({folder: 'medias'})], - test: /\.(mp4|webm|ogv|wav|mp3|m4a|aac|oga|flac)$/, + test: /\.(?:mp4|webm|ogv|wav|mp3|m4a|aac|oga|flac)$/i, }), svg: () => ({ - test: /\.svg?$/, + test: /\.svg$/i, oneOf: [ { use: [ @@ -126,7 +126,7 @@ export function getFileLoaderUtils(): FileLoaderUtils { // We don't want to use SVGR loader for non-React source code // ie we don't want to use SVGR for CSS files... issuer: { - and: [/\.(ts|tsx|js|jsx|md|mdx)$/], + and: [/\.(?:tsx?|jsx?|mdx?)$/i], }, }, { @@ -137,7 +137,7 @@ export function getFileLoaderUtils(): FileLoaderUtils { otherAssets: () => ({ use: [loaders.file({folder: 'files'})], - test: /\.(pdf|doc|docx|xls|xlsx|zip|rar)$/, + test: /\.(?:pdf|docx?|xlsx?|zip|rar)$/i, }), }; diff --git a/packages/docusaurus/src/client/docusaurus.ts b/packages/docusaurus/src/client/docusaurus.ts index 92de4721d4..0c024c0fc4 100644 --- a/packages/docusaurus/src/client/docusaurus.ts +++ b/packages/docusaurus/src/client/docusaurus.ts @@ -37,7 +37,7 @@ const canPreload = (routePath: string) => // Remove the last part containing the route hash // input: /blog/2018/12/14/Happy-First-Birthday-Slash-fe9 // output: /blog/2018/12/14/Happy-First-Birthday-Slash -const removeRouteNameHash = (str: string) => str.replace(/(-[^-]+)$/, ''); +const removeRouteNameHash = (str: string) => str.replace(/-[^-]+$/, ''); const getChunkNamesToLoad = (path: string): string[] => Object.entries(routesChunkNames) diff --git a/packages/docusaurus/src/client/exports/isInternalUrl.ts b/packages/docusaurus/src/client/exports/isInternalUrl.ts index eb503cb54c..f3158e6e98 100644 --- a/packages/docusaurus/src/client/exports/isInternalUrl.ts +++ b/packages/docusaurus/src/client/exports/isInternalUrl.ts @@ -6,7 +6,7 @@ */ export function hasProtocol(url: string): boolean { - return /^(\w*:|\/\/)/.test(url) === true; + return /^(?:\w*:|\/\/)/.test(url) === true; } export default function isInternalUrl(url?: string): boolean { diff --git a/packages/docusaurus/src/client/serverEntry.tsx b/packages/docusaurus/src/client/serverEntry.tsx index f4c1642bc6..808e870b59 100644 --- a/packages/docusaurus/src/client/serverEntry.tsx +++ b/packages/docusaurus/src/client/serverEntry.tsx @@ -54,7 +54,7 @@ export default async function render( ${(e as Error).stack!}`; const isNotDefinedErrorRegex = - /(window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i; + /(?:window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i; if (isNotDefinedErrorRegex.test((e as Error).message)) { logger.info`It looks like you are using code that should run on the client-side only. diff --git a/packages/docusaurus/src/commands/deploy.ts b/packages/docusaurus/src/commands/deploy.ts index 43c42f7aa8..dbfcbbcde1 100644 --- a/packages/docusaurus/src/commands/deploy.ts +++ b/packages/docusaurus/src/commands/deploy.ts @@ -66,7 +66,7 @@ export function hasSSHProtocol(sourceRepoUrl: string): boolean { return false; } catch { // Fails when there isn't a protocol - return /^([\w-]+@)?[\w.-]+:[\w./_-]+(\.git)?/.test(sourceRepoUrl); // git@github.com:facebook/docusaurus.git + return /^(?:[\w-]+@)?[\w.-]+:[\w./_-]+/.test(sourceRepoUrl); // git@github.com:facebook/docusaurus.git } } diff --git a/packages/docusaurus/src/commands/swizzle.ts b/packages/docusaurus/src/commands/swizzle.ts index c14f4506de..bba9dc90ef 100644 --- a/packages/docusaurus/src/commands/swizzle.ts +++ b/packages/docusaurus/src/commands/swizzle.ts @@ -50,8 +50,8 @@ export function getPluginNames(plugins: PluginConfig[]): string[] { const formatComponentName = (componentName: string): string => componentName - .replace(/(\/|\\)index\.(js|tsx|ts|jsx)/, '') - .replace(/\.(js|tsx|ts|jsx)/, ''); + .replace(/[\\/]index\.(?:jsx?|tsx?)/, '') + .replace(/\.(?:jsx?|tsx?)/, ''); function readComponent(themePath: string) { function walk(dir: string): Array<string> { diff --git a/packages/docusaurus/src/commands/writeHeadingIds.ts b/packages/docusaurus/src/commands/writeHeadingIds.ts index 6f25200d53..da9b9a992d 100644 --- a/packages/docusaurus/src/commands/writeHeadingIds.ts +++ b/packages/docusaurus/src/commands/writeHeadingIds.ts @@ -23,7 +23,7 @@ type Options = { }; function unwrapMarkdownLinks(line: string): string { - return line.replace(/\[([^\]]+)\]\([^)]+\)/g, (match, p1) => p1); + return line.replace(/\[(?<alt>[^\]]+)\]\([^)]+\)/g, (match, p1) => p1); } function addHeadingId( diff --git a/packages/docusaurus/src/server/__tests__/config.test.ts b/packages/docusaurus/src/server/__tests__/config.test.ts index f31654598a..fa248987e9 100644 --- a/packages/docusaurus/src/server/__tests__/config.test.ts +++ b/packages/docusaurus/src/server/__tests__/config.test.ts @@ -85,7 +85,7 @@ describe('loadConfig', () => { 'docusaurus.config.js', ); await expect(loadConfig(siteDir)).rejects.toThrowError( - /Config file at "(.*?)__fixtures__[/\\]nonExisting[/\\]docusaurus.config.js" not found.$/, + /Config file at ".*?__fixtures__[/\\]nonExisting[/\\]docusaurus.config.js" not found.$/, ); }); }); diff --git a/packages/docusaurus/src/server/index.ts b/packages/docusaurus/src/server/index.ts index 12ae9501cf..8b693284ba 100644 --- a/packages/docusaurus/src/server/index.ts +++ b/packages/docusaurus/src/server/index.ts @@ -260,7 +260,7 @@ function createMDXFallbackPlugin({ module: { rules: [ { - test: /(\.mdx?)$/, + test: /\.mdx?$/i, exclude: getMDXFallbackExcludedPaths(), use: [ getJSLoader({isServer}), diff --git a/packages/docusaurus/src/server/moduleShorthand.ts b/packages/docusaurus/src/server/moduleShorthand.ts index 37a50e5027..df0ab5570d 100644 --- a/packages/docusaurus/src/server/moduleShorthand.ts +++ b/packages/docusaurus/src/server/moduleShorthand.ts @@ -14,7 +14,7 @@ export function getNamePatterns( if (!moduleName.includes('/')) { return [`${moduleName}/docusaurus-${moduleType}`]; } - const [scope, packageName] = moduleName.split(/\/(.*)/); + const [scope, packageName] = moduleName.split(/\/(?<rest>.*)/); return [ `${scope}/${packageName}`, `${scope}/docusaurus-${moduleType}-${packageName}`, diff --git a/packages/docusaurus/src/server/routes.ts b/packages/docusaurus/src/server/routes.ts index f18c6c1128..35ad9af0fd 100644 --- a/packages/docusaurus/src/server/routes.ts +++ b/packages/docusaurus/src/server/routes.ts @@ -28,7 +28,7 @@ type RegistryMap = { function indent(str: string) { const spaces = ' '; - return `${spaces}${str.replace(/(\n)/g, `\n${spaces}`)}`; + return `${spaces}${str.replace(/\n/g, `\n${spaces}`)}`; } const createRouteCodeString = ({ diff --git a/packages/docusaurus/src/webpack/base.ts b/packages/docusaurus/src/webpack/base.ts index 11db878c16..1a2b57f1d8 100644 --- a/packages/docusaurus/src/webpack/base.ts +++ b/packages/docusaurus/src/webpack/base.ts @@ -19,8 +19,8 @@ import { import {loadPluginsThemeAliases} from '../server/themes'; import {md5Hash, getFileLoaderUtils} from '@docusaurus/utils'; -const CSS_REGEX = /\.css$/; -const CSS_MODULE_REGEX = /\.module\.css$/; +const CSS_REGEX = /\.css$/i; +const CSS_MODULE_REGEX = /\.module\.css$/i; export const clientDir = path.join(__dirname, '..', 'client'); const LibrariesToTranspile = [ @@ -39,7 +39,7 @@ export function excludeJS(modulePath: string): boolean { // Don't transpile node_modules except any docusaurus npm package return ( /node_modules/.test(modulePath) && - !/(docusaurus)((?!node_modules).)*\.jsx?$/.test(modulePath) && + !/docusaurus(?:(?!node_modules).)*\.jsx?$/.test(modulePath) && !LibrariesToTranspileRegex.test(modulePath) ); } @@ -220,7 +220,7 @@ export function createBaseConfig( fileLoaderUtils.rules.svg(), fileLoaderUtils.rules.otherAssets(), { - test: /\.(j|t)sx?$/, + test: /\.[jt]sx?$/i, exclude: excludeJS, use: [ getCustomizableJSLoader(siteConfig.webpack?.jsLoader)({ diff --git a/packages/lqip-loader/src/index.ts b/packages/lqip-loader/src/index.ts index 7f20e3b240..c5ee2ac1cc 100644 --- a/packages/lqip-loader/src/index.ts +++ b/packages/lqip-loader/src/index.ts @@ -29,27 +29,26 @@ async function lqipLoader( let content = contentBuffer.toString('utf8'); const contentIsUrlExport = - /^(?:export default|module.exports =) "data:(.*)base64,(.*)/.test(content); - const contentIsFileExport = /^(?:export default|module.exports =) (.*)/.test( + /^(?:export default|module.exports =) "data:.*base64,.*/.test(content); + const contentIsFileExport = /^(?:export default|module.exports =) .*/.test( content, ); let source = ''; - const SOURCE_CHUNK = 1; if (contentIsUrlExport) { - source = content.match(/^(?:export default|module.exports =) (.*)/)![ - SOURCE_CHUNK - ]; + source = content.match( + /^(?:export default|module.exports =) (?<source>.*)/, + )!.groups!.source; } else { if (!contentIsFileExport) { // eslint-disable-next-line global-require, @typescript-eslint/no-var-requires const fileLoader = require('file-loader'); content = fileLoader.call(this, contentBuffer); } - source = content.match(/^(?:export default|module.exports =) (.*);/)![ - SOURCE_CHUNK - ]; + source = content.match( + /^(?:export default|module.exports =) (?<source>.*);/, + )!.groups!.source; } const outputPromises: [Promise<string> | null, Promise<string[]> | null] = [ diff --git a/website/src/plugins/changelog/index.js b/website/src/plugins/changelog/index.js index 9559cc5fae..54194eed00 100644 --- a/website/src/plugins/changelog/index.js +++ b/website/src/plugins/changelog/index.js @@ -60,7 +60,7 @@ function processSection(section) { }); } let hour = 20; - const date = title.match(/ \((.*)\)/)[1]; + const date = title.match(/ \((?<date>.*)\)/)?.groups.date; while (publishTimes.has(`${date}T${hour}:00`)) { hour -= 1; }