diff --git a/.eslintrc.js b/.eslintrc.js index d82bb95342..d0be97ad69 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,6 +30,7 @@ module.exports = { 'plugin:jest/recommended', 'airbnb', 'plugin:@typescript-eslint/recommended', + 'plugin:regexp/recommended', 'prettier', ], settings: { @@ -40,7 +41,7 @@ module.exports = { }, }, reportUnusedDisableDirectives: true, - plugins: ['react-hooks', 'header', 'jest', '@typescript-eslint'], + plugins: ['react-hooks', 'header', 'jest', '@typescript-eslint', 'regexp'], rules: { 'array-callback-return': WARNING, camelcase: WARNING, diff --git a/jest/snapshotPathNormalizer.js b/jest/snapshotPathNormalizer.js index 1db7669d01..7d3fcd7d26 100644 --- a/jest/snapshotPathNormalizer.js +++ b/jest/snapshotPathNormalizer.js @@ -146,7 +146,7 @@ function normalizePaths(value) { // Convert win32 backslash's to forward slashes, \ -> /; // ignore some that look like escape sequences. - (val) => val.replace(/\\(?!["])/g, '/'), + (val) => val.replace(/\\(?!")/g, '/'), ]; let result = value; diff --git a/package.json b/package.json index 50530105b8..a687ac54c4 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-react": "^7.29.3", "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-regexp": "^1.5.1", "husky": "^7.0.4", "image-size": "^1.0.1", "jest": "^27.5.1", diff --git a/packages/docusaurus-migrate/src/frontMatter.ts b/packages/docusaurus-migrate/src/frontMatter.ts index 4905863cf5..2d03fb0e40 100644 --- a/packages/docusaurus-migrate/src/frontMatter.ts +++ b/packages/docusaurus-migrate/src/frontMatter.ts @@ -69,7 +69,7 @@ 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( - // cSpell:ignore sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ - /^[\w .\-sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ!;,=+_?'`&#()[\]§%€$]+$/, + // cSpell:ignore àáâãäåçèéêëìíîïðòóôõöùúûüýÿ + /^[\w .\-àáâãäåçèéêëìíîïðòóôõöùúûüýÿ!;,=+?'`&#()[\]§%€$]+$/, ); } diff --git a/packages/docusaurus-migrate/src/index.ts b/packages/docusaurus-migrate/src/index.ts index 6d527e44db..30c20e8269 100644 --- a/packages/docusaurus-migrate/src/index.ts +++ b/packages/docusaurus-migrate/src/index.ts @@ -451,7 +451,7 @@ async function handleVersioning(context: MigrationContext) { path.join(newDir, 'versions.json'), ); const versions = loadedVersions.reverse(); - const versionRegex = new RegExp(`version-(${versions.join('|')})-`, 'mgi'); + const versionRegex = new RegExp(`version-(${versions.join('|')})-`, 'gim'); await migrateVersionedSidebar(context, versions, versionRegex); await fs.mkdirp(path.join(newDir, 'versioned_docs')); await migrateVersionedDocs(context, versions, versionRegex); diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts index 21d6faa7c0..8ca46aeb81 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts @@ -231,7 +231,7 @@ describe('docsVersion', () => { expect(versions).toEqual(['1.0.0']); expect(consoleMock).toHaveBeenCalledWith( expect.stringMatching( - /.*\[SUCCESS\].* .*\[docs\].*: version .*1\.0\.0.* created!.*/, + /.*\[SUCCESS\].*\[docs\].*: version .*1\.0\.0.* created!.*/, ), ); @@ -286,7 +286,7 @@ describe('docsVersion', () => { expect(versions).toEqual(['2.0.0', '1.0.1', '1.0.0', 'withSlugs']); expect(consoleMock).toHaveBeenCalledWith( expect.stringMatching( - /.*\[SUCCESS\].* .*\[docs\].*: version .*2\.0\.0.* created!.*/, + /.*\[SUCCESS\].*\[docs\].*: version .*2\.0\.0.* created!.*/, ), ); @@ -339,7 +339,7 @@ describe('docsVersion', () => { expect(versions).toEqual(['2.0.0', '1.0.0']); expect(consoleMock).toHaveBeenCalledWith( expect.stringMatching( - /.*\[SUCCESS\].* .*\[community\].*: version .*2.0.0.* created!.*/, + /.*\[SUCCESS\].*\[community\].*: version .*2.0.0.* created!.*/, ), ); diff --git a/packages/docusaurus-plugin-content-docs/src/cli.ts b/packages/docusaurus-plugin-content-docs/src/cli.ts index ecb5ab0e59..2aaceff79b 100644 --- a/packages/docusaurus-plugin-content-docs/src/cli.ts +++ b/packages/docusaurus-plugin-content-docs/src/cli.ts @@ -88,7 +88,7 @@ export async function cliDocsVersionCommand( // Since we are going to create `version-${version}` folder, we need to make // sure it's a valid pathname. // eslint-disable-next-line no-control-regex - if (/[<>:"|?*\x00-\x1F]/g.test(version)) { + if (/[<>:"|?*\x00-\x1F]/.test(version)) { throw new Error( `${pluginIdLogPrefix}: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0.`, ); diff --git a/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts b/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts index b91fc6d35b..a838d7667d 100644 --- a/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts +++ b/packages/docusaurus-plugin-content-docs/src/numberPrefix.ts @@ -8,43 +8,33 @@ import type {NumberPrefixParser} from '@docusaurus/plugin-content-docs'; // Best-effort to avoid parsing some patterns as number prefix -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}))?.*$/; +// ignore common date-like patterns: https://github.com/facebook/docusaurus/issues/4640 +// ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653 +// Both of them would look like 7.0-foo or 2021-11-foo +// 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 either a +// version or a float. User can configure her own NumberPrefixParser if she +// wants 8.0 to be interpreted as a float +const ignoredPrefixPattern = /^\d+[-_.]\d+/; - // 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+.*$/; - - return new RegExp( - `${DateLikePrefixRegex.source}|${VersionLikePrefixRegex.source}`, - ); -})(); - -const NumberPrefixRegex = - /^(?\d+)(?\s*[-_.]+\s*)(?.*)$/; +const numberPrefixPattern = + /^(?\d+)\s*[-_.]+\s*(?[^-_.\s].*)$/; // 0-myDoc => {filename: myDoc, numberPrefix: 0} // 003 - myDoc => {filename: myDoc, numberPrefix: 3} export const DefaultNumberPrefixParser: NumberPrefixParser = ( filename: string, ) => { - if (IgnoredPrefixPatterns.exec(filename)) { + if (ignoredPrefixPattern.test(filename)) { + return {filename, numberPrefix: undefined}; + } + const match = numberPrefixPattern.exec(filename); + if (!match) { return {filename, numberPrefix: undefined}; } - const match = NumberPrefixRegex.exec(filename); - const cleanFileName = match?.groups?.suffix ?? filename; - const numberPrefixString = match?.groups?.numberPrefix; - const numberPrefix = numberPrefixString - ? parseInt(numberPrefixString, 10) - : undefined; return { - filename: cleanFileName, - numberPrefix, + filename: match.groups!.suffix!, + numberPrefix: parseInt(match.groups!.numberPrefix!, 10), }; }; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts index a80aee0433..501774ef60 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts @@ -44,7 +44,7 @@ describe('DefaultSidebarItemsGenerator', () => { expect(sidebarSlice).toEqual([]); expect(consoleWarn).toHaveBeenCalledWith( expect.stringMatching( - /.*\[WARNING\].* No docs found in .*\..*: can't auto-generate a sidebar\..*/, + /.*\[WARNING\].* No docs found in [^.]*\..*: can't auto-generate a sidebar\..*/, ), ); }); diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts index b57a044bae..ec19a5c4fb 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts @@ -134,12 +134,12 @@ describe('loadSidebars', () => { ).rejects.toThrowErrorMatchingInlineSnapshot(`"\\"foo\\" is not allowed"`); expect(consoleWarnMock).toBeCalledWith( expect.stringMatching( - /.*\[WARNING].* There are more than one category metadata files for .*foo.*: foo\/_category_.json, foo\/_category_.yml. The behavior is undetermined./, + /.*\[WARNING\].* There are more than one category metadata files for .*foo.*: foo\/_category_.json, foo\/_category_.yml. The behavior is undetermined./, ), ); expect(consoleErrorMock).toBeCalledWith( expect.stringMatching( - /.*\[ERROR].* The docs sidebar category metadata file .*foo\/_category_.json.* looks invalid!/, + /.*\[ERROR\].* The docs sidebar category metadata file .*foo\/_category_.json.* looks invalid!/, ), ); }); diff --git a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts index 1734ae5beb..3f4b2d7a2e 100644 --- a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts @@ -8,7 +8,7 @@ import rangeParser from 'parse-numeric-range'; const codeBlockTitleRegex = /title=(?["'])(?.*?)\1/; -const highlightLinesRangeRegex = /{(?<range>[\d,-]+)}/; +const highlightLinesRangeRegex = /\{(?<range>[\d,-]+)\}/; const commentTypes = ['js', 'jsBlock', 'jsx', 'python', 'html'] as const; type CommentType = typeof commentTypes[number]; diff --git a/packages/docusaurus-utils-validation/src/validationSchemas.ts b/packages/docusaurus-utils-validation/src/validationSchemas.ts index d89f65da80..d7b23b7cc8 100644 --- a/packages/docusaurus-utils-validation/src/validationSchemas.ts +++ b/packages/docusaurus-utils-validation/src/validationSchemas.ts @@ -11,7 +11,7 @@ import type {Tag} from '@docusaurus/utils'; import {JoiFrontMatter} from './JoiFrontMatter'; export const PluginIdSchema = Joi.string() - .regex(/^[a-zA-Z0-9_-]+$/) + .regex(/^[\w-]+$/) .message( 'Illegal plugin ID value "{#value}": it should only contain alphanumerics, underscores, and dashes.', ) diff --git a/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts b/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts index 1092e85ff7..6e7e4c99e3 100644 --- a/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts +++ b/packages/docusaurus-utils/src/__tests__/jsUtils.test.ts @@ -169,14 +169,16 @@ describe('reportMessage', () => { `"Unexpected \\"reportingSeverity\\" value: foo."`, ); expect(consoleLog).toBeCalledTimes(1); - expect(consoleLog).toBeCalledWith(expect.stringMatching(/.*\[INFO].* hey/)); + expect(consoleLog).toBeCalledWith( + expect.stringMatching(/.*\[INFO\].* hey/), + ); expect(consoleWarn).toBeCalledTimes(1); expect(consoleWarn).toBeCalledWith( - expect.stringMatching(/.*\[WARNING].* hey/), + expect.stringMatching(/.*\[WARNING\].* hey/), ); expect(consoleError).toBeCalledTimes(1); expect(consoleError).toBeCalledWith( - expect.stringMatching(/.*\[ERROR].* hey/), + expect.stringMatching(/.*\[ERROR\].* hey/), ); }); }); diff --git a/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts b/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts index 01999c82c7..a3de772987 100644 --- a/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts +++ b/packages/docusaurus-utils/src/__tests__/markdownParser.test.ts @@ -404,7 +404,7 @@ Lorem Ipsum expect( parseMarkdownContentTitle(markdown, {removeContentTitle: true}), ).toEqual({ - content: markdown.trim().replace('# Markdown Title', ''), + content: markdown.trim().replace('# Markdown Title\n', ''), contentTitle: 'Markdown Title', }); }); @@ -444,7 +444,7 @@ Lorem Ipsum expect( parseMarkdownContentTitle(markdown, {removeContentTitle: true}), ).toEqual({ - content: markdown.replace('Markdown Title\n==============\n\n', ''), + content: markdown.replace('Markdown Title\n==============\n', ''), contentTitle: 'Markdown Title', }); }); @@ -547,7 +547,7 @@ Lorem Ipsum expect( parseMarkdownContentTitle(markdown, {removeContentTitle: true}), ).toEqual({ - content: markdown.replace('# Markdown Title', ''), + content: markdown.replace('# Markdown Title\n', ''), contentTitle: 'Markdown Title', }); }); diff --git a/packages/docusaurus-utils/src/markdownLinks.ts b/packages/docusaurus-utils/src/markdownLinks.ts index e9eed1a7e6..afbd7170ce 100644 --- a/packages/docusaurus-utils/src/markdownLinks.ts +++ b/packages/docusaurus-utils/src/markdownLinks.ts @@ -68,7 +68,7 @@ export function replaceMarkdownLinks<T extends ContentPaths>({ // ink // [doc1]: doc1.md -> we replace this doc1.md with correct link const mdRegex = - /(?:(?:\]\()|(?:\]:\s*))(?!https?:\/\/|@site\/)(?<filename>[^'")\]\s>]+\.mdx?)/g; + /(?:\]\(|\]:\s*)(?!https?:\/\/|@site\/)(?<filename>[^'")\]\s>]+\.mdx?)/g; let mdMatch = mdRegex.exec(modifiedLine); while (mdMatch !== null) { // Replace it to correct html link. diff --git a/packages/docusaurus-utils/src/markdownParser.ts b/packages/docusaurus-utils/src/markdownParser.ts index 108300c107..354461b414 100644 --- a/packages/docusaurus-utils/src/markdownParser.ts +++ b/packages/docusaurus-utils/src/markdownParser.ts @@ -14,11 +14,11 @@ export function parseMarkdownHeadingId(heading: string): { text: string; id?: string; } { - const customHeadingIdRegex = /^(?<text>.*?)\s*\{#(?<id>[\w-]+)\}$/; + const customHeadingIdRegex = /\s*\{#(?<id>[\w-]+)\}$/; const matches = customHeadingIdRegex.exec(heading); if (matches) { return { - text: matches.groups!.text!, + text: heading.replace(matches[0]!, ''), id: matches.groups!.id!, }; } @@ -69,9 +69,9 @@ export function createExcerpt(fileString: string): string | undefined { // Remove HTML tags. .replace(/<[^>]*>/g, '') // Remove Title headers - .replace(/^#\s*[^#]*\s*#?/gm, '') + .replace(/^#[^#]+#?/gm, '') // Remove Markdown + ATX-style headers - .replace(/^#{1,6}\s*(?<text>[^#]*)\s*(?:#{1,6})?/gm, '$1') + .replace(/^#{1,6}\s*(?<text>[^#]*)\s*#{0,6}/gm, '$1') // Remove emphasis. .replace(/(?<opening>[*_]{1,3})(?<text>.*?)\1/g, '$2') // Remove strikethroughs. @@ -79,7 +79,7 @@ export function createExcerpt(fileString: string): string | undefined { // Remove images. .replace(/!\[(?<alt>.*?)\][[(].*?[\])]/g, '$1') // Remove footnotes. - .replace(/\[\^.+?\](?:: .*?$)?/g, '') + .replace(/\[\^.+?\](?:: .*$)?/g, '') // Remove inline links. .replace(/\[(?<alt>.*?)\][[(].*?[\])]/g, '$1') // Remove inline code. @@ -91,7 +91,7 @@ export function createExcerpt(fileString: string): string | undefined { // Remove Emoji names within colons include preceding whitespace. .replace(/\s?:(?:::|[^:\n])+:/g, '') // Remove custom Markdown heading id. - .replace(/{#*[\w-]+}/, '') + .replace(/\{#*[\w-]+\}/, '') .trim(); if (cleanedLine) { @@ -132,35 +132,42 @@ export function parseMarkdownContentTitle( const removeContentTitleOption = options?.removeContentTitle ?? false; const content = contentUntrimmed.trim(); + // We only need to detect import statements that will be parsed by MDX as + // `import` nodes, as broken syntax can't render anyways. That means any block + // that has `import` at the very beginning and surrounded by empty lines. + const contentWithoutImport = content + .replace(/^(?:import\s(?:.|\n(?!\n))*\n{2,})*/, '') + .trim(); - const IMPORT_STATEMENT = - /import\s+(?:[\w*{}\s\n,]+from\s+)?["'\s][@\w/_.-]+["'\s];?|\n/.source; - const REGULAR_TITLE = - /(?<pattern>#\s*(?<title>[^#\n{]*)+[ \t]*(?<suffix>(?:{#*[\w-]+})|#)?\n*?)/ - .source; - const ALTERNATE_TITLE = /(?<pattern>\s*(?<title>[^\n]*)\s*\n[=]+)/.source; - - const regularTitleMatch = new RegExp( - `^(?:${IMPORT_STATEMENT})*?${REGULAR_TITLE}`, - 'g', - ).exec(content); - const alternateTitleMatch = new RegExp( - `^(?:${IMPORT_STATEMENT})*?${ALTERNATE_TITLE}`, - 'g', - ).exec(content); + const regularTitleMatch = /^#[ \t]+(?<title>[^ \t].*)(?:\n|$)/.exec( + contentWithoutImport, + ); + const alternateTitleMatch = /^(?<title>.*)\n=+(?:\n|$)/.exec( + contentWithoutImport, + ); const titleMatch = regularTitleMatch ?? alternateTitleMatch; - const {pattern, title} = titleMatch?.groups ?? {}; - - if (!pattern || !title) { + if (!titleMatch) { return {content, contentTitle: undefined}; } const newContent = removeContentTitleOption - ? content.replace(pattern, '') + ? content.replace(titleMatch[0]!, '') : content; + if (regularTitleMatch) { + return { + content: newContent.trim(), + contentTitle: toTextContentTitle( + regularTitleMatch + .groups!.title!.trim() + .replace(/\s*(?:\{#*[\w-]+\}|#+)$/, ''), + ).trim(), + }; + } return { content: newContent.trim(), - contentTitle: toTextContentTitle(title.trim()).trim(), + contentTitle: toTextContentTitle( + alternateTitleMatch!.groups!.title!.trim().replace(/\s*=+$/, ''), + ).trim(), }; } diff --git a/packages/docusaurus-utils/src/urlUtils.ts b/packages/docusaurus-utils/src/urlUtils.ts index 0f1d24f540..a083a330b8 100644 --- a/packages/docusaurus-utils/src/urlUtils.ts +++ b/packages/docusaurus-utils/src/urlUtils.ts @@ -58,7 +58,7 @@ export function normalizeUrl(rawUrls: string[]): string { if (i > 0) { // Removing the starting slashes for each component but the first. component = component.replace( - /^[/]+/, + /^\/+/, // Special case where the first element of rawUrls is empty // ["", "/hello"] => /hello component[0] === '/' && !hasStartingSlash ? '/' : '', @@ -68,7 +68,7 @@ export function normalizeUrl(rawUrls: string[]): string { hasEndingSlash = component[component.length - 1] === '/'; // Removing the ending slashes for each component but the last. For the // last component we will combine multiple slashes to a single one. - component = component.replace(/[/]+$/, i < urls.length - 1 ? '' : '/'); + component = component.replace(/\/+$/, i < urls.length - 1 ? '' : '/'); } hasStartingSlash = true; diff --git a/packages/docusaurus/src/client/exports/Interpolate.tsx b/packages/docusaurus/src/client/exports/Interpolate.tsx index 5b290d6054..076c7b1abc 100644 --- a/packages/docusaurus/src/client/exports/Interpolate.tsx +++ b/packages/docusaurus/src/client/exports/Interpolate.tsx @@ -18,7 +18,7 @@ We don't ship a markdown parser nor a feature-complete i18n library on purpose. More details here: https://github.com/facebook/docusaurus/pull/4295 */ -const ValueRegexp = /{\w+}/g; +const ValueRegexp = /\{\w+\}/g; const ValueFoundMarker = '{}'; // does not care much // If all the values are plain strings, then interpolate returns a simple string diff --git a/packages/docusaurus/src/commands/deploy.ts b/packages/docusaurus/src/commands/deploy.ts index fdd28ef0b2..6270eb3d29 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./_-]+/.test(sourceRepoUrl); // git@github.com:facebook/docusaurus.git + return /^(?:[\w-]+@)?[\w.-]+:[\w./-]+/.test(sourceRepoUrl); // git@github.com:facebook/docusaurus.git } } diff --git a/website/src/plugins/changelog/index.js b/website/src/plugins/changelog/index.js index 58a7bb2f65..310b1ebc36 100644 --- a/website/src/plugins/changelog/index.js +++ b/website/src/plugins/changelog/index.js @@ -37,7 +37,7 @@ function processSection(section) { .trim() .replace('running_woman', 'running'); - let authors = content.match(/## Committers: \d+.*/ms); + let authors = content.match(/## Committers: \d.*/s); if (authors) { authors = authors[0] .match(/- .*/g) @@ -105,7 +105,7 @@ async function ChangelogPlugin(context, options) { async loadContent() { const fileContent = await fs.readFile(changelogPath, 'utf-8'); const sections = fileContent - .split(/(?=\n## )/ms) + .split(/(?=\n## )/) .map(processSection) .filter(Boolean); await Promise.all( diff --git a/website/src/remark/configTabs.mjs b/website/src/remark/configTabs.mjs index ec4e8de8ce..3da56b4ba8 100644 --- a/website/src/remark/configTabs.mjs +++ b/website/src/remark/configTabs.mjs @@ -30,7 +30,7 @@ export default function plugin() { const { groups: {presetOptionName, presetOptionText}, } = presetMeta.match( - /\/\/(?<presetOptionText>.*?): (?<presetOptionName>[A-Za-z]+)/i, + /\/\/(?<presetOptionText>.*?): (?<presetOptionName>[A-Z]+)/i, ) ?? { groups: { presetOptionName: '[translation failure]', @@ -40,7 +40,7 @@ export default function plugin() { const { groups: {pluginName, pluginText}, } = pluginMeta.match( - /\/\/(?<pluginText>.*?): (?<pluginName>[A-Za-z@/-]+)/i, + /\/\/(?<pluginText>.*?): (?<pluginName>[A-Z@/-]+)/i, ) ?? { groups: { pluginName: '[translation failure]', diff --git a/website/src/utils/colorUtils.ts b/website/src/utils/colorUtils.ts index 431b233960..78c4895c4b 100644 --- a/website/src/utils/colorUtils.ts +++ b/website/src/utils/colorUtils.ts @@ -100,7 +100,7 @@ export function updateDOMColors( isDarkTheme: boolean, ): void { const styleSheet = Array.from(document.styleSheets).find((item) => - item.href?.match(/styles(?:\.[0-9a-f]+)?\.css/), + item.href?.match(/styles(?:\.[\da-f]+)?\.css/), )!; const rules = Array.from(styleSheet.cssRules) as CSSStyleRule[]; // The rule that looks the most like definition for custom theme colors diff --git a/yarn.lock b/yarn.lock index d09778ac0c..fdb25727eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6559,6 +6559,11 @@ comment-json@^4.2.2: has-own-prop "^2.0.0" repeat-string "^1.6.1" +comment-parser@^1.1.2: + version "1.3.0" + resolved "https://registry.npmmirror.com/comment-parser/-/comment-parser-1.3.0.tgz#68beb7dbe0849295309b376406730cd16c719c44" + integrity sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA== + common-path-prefix@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" @@ -8452,6 +8457,20 @@ eslint-plugin-react@^7.29.3: semver "^6.3.0" string.prototype.matchall "^4.0.6" +eslint-plugin-regexp@^1.5.1: + version "1.5.1" + resolved "https://registry.npmmirror.com/eslint-plugin-regexp/-/eslint-plugin-regexp-1.5.1.tgz#982ea8936283035897d6bb1ba32c0ea5d9a4dee0" + integrity sha512-5v0rQIi54m2KycQHqmOAHrZhvI56GHmI2acr6zEffAqfeifTtobAEapv9Uf4o8//lGvwVkHKyjLoSbBNEFcfOA== + dependencies: + comment-parser "^1.1.2" + eslint-utils "^3.0.0" + grapheme-splitter "^1.0.4" + jsdoctypeparser "^9.0.0" + refa "^0.9.0" + regexp-ast-analysis "^0.3.0" + regexpp "^3.2.0" + scslre "^0.1.6" + eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -9889,6 +9908,11 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1. resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + graphql@16.0.0: version "16.0.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.0.0.tgz#5724f2767aefa543418e83671372117c39408c8f" @@ -11869,6 +11893,11 @@ jscodeshift@^0.13.0: temp "^0.8.4" write-file-atomic "^2.3.0" +jsdoctypeparser@^9.0.0: + version "9.0.0" + resolved "https://registry.npmmirror.com/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz#8c97e2fb69315eb274b0f01377eaa5c940bd7b26" + integrity sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw== + jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" @@ -16204,6 +16233,13 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +refa@^0.9.0: + version "0.9.1" + resolved "https://registry.npmmirror.com/refa/-/refa-0.9.1.tgz#12731fce378d235731b1f73182b20083c8a75ca8" + integrity sha512-egU8LgFq2VXlAfUi8Jcbr5X38wEOadMFf8tCbshgcpVCYlE7k84pJOSlnvXF+muDB4igkdVMq7Z/kiNPqDT9TA== + dependencies: + regexpp "^3.2.0" + regenerate-unicode-properties@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" @@ -16243,6 +16279,22 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp-ast-analysis@^0.2.3: + version "0.2.4" + resolved "https://registry.npmmirror.com/regexp-ast-analysis/-/regexp-ast-analysis-0.2.4.tgz#a497a7c8bfbba51438693821e4b0e3ed43e20f1b" + integrity sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg== + dependencies: + refa "^0.9.0" + regexpp "^3.2.0" + +regexp-ast-analysis@^0.3.0: + version "0.3.0" + resolved "https://registry.npmmirror.com/regexp-ast-analysis/-/regexp-ast-analysis-0.3.0.tgz#386f177dfe5abc5ac58b51eb5962beac64e898ce" + integrity sha512-11PlbBSUxwWpdj6BdZUKfhDdV9g+cveqHB+BqBQDBD7ZermDBVgtyowUaXTvT0dO3tZYo2bDIr/GoED6X1aYSA== + dependencies: + refa "^0.9.0" + regexpp "^3.2.0" + regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: version "1.4.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" @@ -16868,6 +16920,15 @@ screenfull@^5.1.0: resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba" integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== +scslre@^0.1.6: + version "0.1.6" + resolved "https://registry.npmmirror.com/scslre/-/scslre-0.1.6.tgz#71a2832e4bf3a9254973a04fbed90aec94f75757" + integrity sha512-JORxVRlQTfjvlOAaiQKebgFElyAm5/W8b50lgaZ0OkEnKnagJW2ufDh3xRfU75UD9z3FGIu1gL1IyR3Poa6Qmw== + dependencies: + refa "^0.9.0" + regexp-ast-analysis "^0.2.3" + regexpp "^3.2.0" + section-matter@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167"