summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.cjs6
-rw-r--r--package.json3
-rw-r--r--packages/astro-prism/src/plugin.ts9
-rw-r--r--packages/astro-rss/src/util.ts4
-rw-r--r--packages/astro/src/assets/services/vendor/squoosh/codecs.ts4
-rw-r--r--packages/astro/src/cli/add/index.ts4
-rw-r--r--packages/astro/src/core/build/css-asset-name.ts2
-rw-r--r--packages/astro/src/core/build/plugins/plugin-manifest.ts2
-rw-r--r--packages/astro/src/core/build/static-build.ts2
-rw-r--r--packages/astro/src/core/create-vite.ts2
-rw-r--r--packages/astro/src/core/dev/restart.ts4
-rw-r--r--packages/astro/src/core/errors/dev/utils.ts22
-rw-r--r--packages/astro/src/core/errors/errors-data.ts2
-rw-r--r--packages/astro/src/core/logger/vite.ts9
-rw-r--r--packages/astro/src/core/messages.ts2
-rw-r--r--packages/astro/src/core/preview/vite-plugin-astro-preview.ts2
-rw-r--r--packages/astro/src/core/routing/manifest/create.ts4
-rw-r--r--packages/astro/src/events/error.ts4
-rw-r--r--packages/astro/src/i18n/middleware.ts7
-rw-r--r--packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts2
-rw-r--r--packages/astro/src/runtime/server/render/component.ts6
-rw-r--r--packages/astro/src/runtime/server/render/util.ts10
-rw-r--r--packages/astro/src/virtual-modules/content.ts1
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts4
-rw-r--r--packages/astro/src/vite-plugin-astro/compile.ts5
-rw-r--r--packages/astro/src/vite-plugin-astro/hmr.ts5
-rw-r--r--packages/astro/src/vite-plugin-astro/utils.ts1
-rw-r--r--packages/astro/src/vite-plugin-env/index.ts2
-rw-r--r--packages/astro/src/vite-plugin-head/index.ts2
-rw-r--r--packages/astro/src/vite-plugin-html/transform/utils.ts4
-rw-r--r--packages/astro/src/vite-plugin-scanner/scan.ts2
-rw-r--r--packages/astro/src/vite-plugin-utils/index.ts2
-rw-r--r--packages/astro/test/0-css.test.js38
-rw-r--r--packages/astro/test/astro-css-bundling.test.js2
-rw-r--r--packages/astro/test/astro-doctype.test.js5
-rw-r--r--packages/astro/test/astro-partial-html.test.js4
-rw-r--r--packages/astro/test/component-library.test.js4
-rw-r--r--packages/astro/test/config-vite-css-target.test.js2
-rw-r--r--packages/astro/test/config-vite.test.js2
-rw-r--r--packages/astro/test/core-image.test.js4
-rw-r--r--packages/astro/test/css-dangling-references.test.js2
-rw-r--r--packages/astro/test/hoisted-imports.test.js2
-rw-r--r--packages/astro/test/markdown.test.js2
-rw-r--r--packages/astro/test/minification-html.test.js2
-rw-r--r--packages/astro/test/postcss.test.js10
-rw-r--r--packages/astro/test/root-srcdir-css.test.js2
-rw-r--r--packages/astro/test/ssr-api-route.test.js2
-rw-r--r--packages/astro/test/static-build.test.js4
-rw-r--r--packages/astro/test/tailwindcss.test.js14
-rw-r--r--packages/astro/test/test-utils.js2
-rw-r--r--packages/astro/test/units/correct-path.js2
-rw-r--r--packages/create-astro/src/actions/verify.ts2
-rw-r--r--packages/integrations/markdoc/src/html/css/parse-inline-css-to-react.ts2
-rw-r--r--packages/integrations/markdoc/src/html/css/parse-inline-styles.ts6
-rw-r--r--packages/integrations/mdx/src/index.ts2
-rw-r--r--packages/integrations/mdx/src/utils.ts2
-rw-r--r--packages/integrations/partytown/src/sirv.ts10
-rw-r--r--packages/integrations/preact/src/server.ts2
-rw-r--r--packages/integrations/sitemap/test/staticPaths.test.js2
-rw-r--r--packages/integrations/vue/src/editor.cts4
-rw-r--r--packages/integrations/vue/test/app-entrypoint.test.js8
-rw-r--r--packages/internal-helpers/src/path.ts4
-rw-r--r--packages/markdown/remark/src/shiki.ts2
-rw-r--r--packages/telemetry/src/project-info.ts2
-rw-r--r--pnpm-lock.yaml53
65 files changed, 207 insertions, 139 deletions
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index c3e825cfc..a5e9f80d8 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -7,13 +7,14 @@ module.exports = {
'plugin:@typescript-eslint/recommended-type-checked',
'plugin:@typescript-eslint/stylistic-type-checked',
'prettier',
+ 'plugin:regexp/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./packages/*/tsconfig.json', './tsconfig.eslint.json'],
tsconfigRootDir: __dirname,
},
- plugins: ['@typescript-eslint', 'prettier', 'no-only-tests'],
+ plugins: ['@typescript-eslint', 'prettier', 'no-only-tests', 'regexp'],
rules: {
// These off/configured-differently-by-default rules fit well for us
'@typescript-eslint/switch-exhaustiveness-check': 'error',
@@ -72,6 +73,9 @@ module.exports = {
// These rules enabled by the preset configs don't work well for us
'@typescript-eslint/await-thenable': 'off',
'prefer-const': 'off',
+
+ // In some cases, using explicit letter-casing is more performant than the `i` flag
+ 'regexp/use-ignore-case': 'off',
},
overrides: [
{
diff --git a/package.json b/package.json
index f85212d92..d26d4fac2 100644
--- a/package.json
+++ b/package.json
@@ -59,12 +59,13 @@
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-prettier": "^5.0.0",
+ "eslint-plugin-regexp": "^2.2.0",
+ "globby": "^14.0.0",
"only-allow": "^1.1.1",
"organize-imports-cli": "^0.10.0",
"prettier": "^3.1.0",
"prettier-plugin-astro": "^0.12.2",
"tiny-glob": "^0.2.9",
- "globby": "^14.0.0",
"turbo": "^1.10.12",
"typescript": "~5.2.2"
},
diff --git a/packages/astro-prism/src/plugin.ts b/packages/astro-prism/src/plugin.ts
index cbee66c33..a50b9d7ef 100644
--- a/packages/astro-prism/src/plugin.ts
+++ b/packages/astro-prism/src/plugin.ts
@@ -16,6 +16,7 @@ export function addAstro(Prism: typeof import('prismjs')) {
let script = Prism.util.clone(Prism.languages[scriptLang]);
+ // eslint-disable-next-line regexp/no-useless-assertions
let space = /(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source;
let braces = /(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source;
let spread = /(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;
@@ -39,13 +40,13 @@ export function addAstro(Prism: typeof import('prismjs')) {
Prism.languages.astro = Prism.languages.extend('markup', script);
(Prism.languages.astro as any).tag.pattern = re(
- /<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/
+ /<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/
.source
);
- (Prism.languages.astro as any).tag.inside['tag'].pattern = /^<\/?[^\s>\/]*/i;
+ (Prism.languages.astro as any).tag.inside['tag'].pattern = /^<\/?[^\s>/]*/;
(Prism.languages.astro as any).tag.inside['attr-value'].pattern =
- /=(?!\{)(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s'">]+)/i;
+ /=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/;
(Prism.languages.astro as any).tag.inside['tag'].inside['class-name'] =
/^[A-Z]\w*(?:\.[A-Z]\w*)*$/;
(Prism.languages.astro as any).tag.inside['comment'] = script['comment'];
@@ -71,7 +72,7 @@ export function addAstro(Prism: typeof import('prismjs')) {
pattern: re(/=<BRACES>/.source),
inside: {
'script-punctuation': {
- pattern: /^=(?={)/,
+ pattern: /^=(?=\{)/,
alias: 'punctuation',
},
rest: Prism.languages.astro,
diff --git a/packages/astro-rss/src/util.ts b/packages/astro-rss/src/util.ts
index bc1589780..1e49b3d77 100644
--- a/packages/astro-rss/src/util.ts
+++ b/packages/astro-rss/src/util.ts
@@ -10,10 +10,10 @@ export function createCanonicalURL(
let pathname = url.replace(/\/index.html$/, ''); // index.html is not canonical
if (trailingSlash === false) {
// remove the trailing slash
- pathname = pathname.replace(/(\/+)?$/, '');
+ pathname = pathname.replace(/\/*$/, '');
} else if (!getUrlExtension(url)) {
// add trailing slash if there’s no extension or `trailingSlash` is true
- pathname = pathname.replace(/(\/+)?$/, '/');
+ pathname = pathname.replace(/\/*$/, '/');
}
pathname = pathname.replace(/\/+/g, '/'); // remove duplicate slashes (URL() won’t)
diff --git a/packages/astro/src/assets/services/vendor/squoosh/codecs.ts b/packages/astro/src/assets/services/vendor/squoosh/codecs.ts
index 80aae7520..e4705e10b 100644
--- a/packages/astro/src/assets/services/vendor/squoosh/codecs.ts
+++ b/packages/astro/src/assets/services/vendor/squoosh/codecs.ts
@@ -291,6 +291,8 @@ export const codecs = {
avif: {
name: 'AVIF',
extension: 'avif',
+ // Disable eslint rule to not touch the original code
+ // eslint-disable-next-line no-control-regex, regexp/control-character-escape
detectors: [/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/],
dec: () =>
instantiateEmscriptenWasm(avifDec as DecodeModuleFactory, avifDecWasm),
@@ -321,6 +323,8 @@ export const codecs = {
oxipng: {
name: 'OxiPNG',
extension: 'png',
+ // Disable eslint rule to not touch the original code
+ // eslint-disable-next-line no-control-regex, regexp/control-character-escape
detectors: [/^\x89PNG\x0D\x0A\x1A\x0A/],
dec: async () => {
await pngEncDecInit()
diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts
index b8cb1949c..e1b64eb18 100644
--- a/packages/astro/src/cli/add/index.ts
+++ b/packages/astro/src/cli/add/index.ts
@@ -384,11 +384,11 @@ const toIdent = (name: string) => {
const ident = name
.trim()
// Remove astro or (astrojs) prefix and suffix
- .replace(/[-_\.\/]?astro(?:js)?[-_\.]?/g, '')
+ .replace(/[-_./]?astro(?:js)?[-_.]?/g, '')
// drop .js suffix
.replace(/\.js/, '')
// convert to camel case
- .replace(/(?:[\.\-\_\/]+)([a-zA-Z])/g, (_, w) => w.toUpperCase())
+ .replace(/[.\-_/]+([a-zA-Z])/g, (_, w) => w.toUpperCase())
// drop invalid first characters
.replace(/^[^a-zA-Z$_]+/, '');
return `${ident[0].toLowerCase()}${ident.slice(1)}`;
diff --git a/packages/astro/src/core/build/css-asset-name.ts b/packages/astro/src/core/build/css-asset-name.ts
index 29fc14294..64852b366 100644
--- a/packages/astro/src/core/build/css-asset-name.ts
+++ b/packages/astro/src/core/build/css-asset-name.ts
@@ -103,7 +103,7 @@ function getFirstParentId(parents: [ModuleInfo, number, number][]) {
return parents[0]?.[0].id;
}
-const charsToReplaceRe = /[.\[\]]/g;
+const charsToReplaceRe = /[.[\]]/g;
const underscoresRe = /_+/g;
/**
* Prettify base names so they're easier to read:
diff --git a/packages/astro/src/core/build/plugins/plugin-manifest.ts b/packages/astro/src/core/build/plugins/plugin-manifest.ts
index e5a1c1b06..6b5413583 100644
--- a/packages/astro/src/core/build/plugins/plugin-manifest.ts
+++ b/packages/astro/src/core/build/plugins/plugin-manifest.ts
@@ -19,7 +19,7 @@ import type { StaticBuildOptions } from '../types.js';
import { normalizeTheLocale } from '../../../i18n/index.js';
const manifestReplace = '@@ASTRO_MANIFEST_REPLACE@@';
-const replaceExp = new RegExp(`['"](${manifestReplace})['"]`, 'g');
+const replaceExp = new RegExp(`['"]${manifestReplace}['"]`, 'g');
export const SSR_MANIFEST_VIRTUAL_MODULE_ID = '@astrojs-manifest';
export const RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID = '\0' + SSR_MANIFEST_VIRTUAL_MODULE_ID;
diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts
index a1278c803..3fc40035d 100644
--- a/packages/astro/src/core/build/static-build.ts
+++ b/packages/astro/src/core/build/static-build.ts
@@ -524,7 +524,7 @@ export function makeAstroPageEntryPointFileName(
const name = route?.route ?? pageModuleId;
return `pages${name
.replace(/\/$/, '/index')
- .replaceAll(/[\[\]]/g, '_')
+ .replaceAll(/[[\]]/g, '_')
.replaceAll('...', '---')}.astro.mjs`;
}
diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts
index 0b0c7d47f..b2de6afb5 100644
--- a/packages/astro/src/core/create-vite.ts
+++ b/packages/astro/src/core/create-vite.ts
@@ -90,7 +90,7 @@ export async function createVite(
pkgJson.keywords?.includes('astro') ||
pkgJson.keywords?.includes('astro-component') ||
// Attempt: package is named `astro-something` or `@scope/astro-something`. ✅ Likely a community package
- /^(@[^\/]+\/)?astro\-/.test(pkgJson.name)
+ /^(?:@[^/]+\/)?astro-/.test(pkgJson.name)
);
},
isFrameworkPkgByName(pkgName) {
diff --git a/packages/astro/src/core/dev/restart.ts b/packages/astro/src/core/dev/restart.ts
index 23e6af369..7a1b15ed0 100644
--- a/packages/astro/src/core/dev/restart.ts
+++ b/packages/astro/src/core/dev/restart.ts
@@ -29,8 +29,8 @@ async function createRestartedContainer(
return newContainer;
}
-const configRE = new RegExp(`.*astro\.config\.((mjs)|(cjs)|(js)|(ts))$`);
-const preferencesRE = new RegExp(`.*\.astro\/settings\.json$`);
+const configRE = /.*astro.config.(?:mjs|cjs|js|ts)$/;
+const preferencesRE = /.*\.astro\/settings.json$/;
export function shouldRestartContainer(
{ settings, inlineConfig, restartInFlight }: Container,
diff --git a/packages/astro/src/core/errors/dev/utils.ts b/packages/astro/src/core/errors/dev/utils.ts
index cda9e4227..c391e462b 100644
--- a/packages/astro/src/core/errors/dev/utils.ts
+++ b/packages/astro/src/core/errors/dev/utils.ts
@@ -132,7 +132,7 @@ export function collectErrorMetadata(e: any, rootFolder?: URL | undefined): Erro
function generateHint(err: ErrorWithMetadata): string | undefined {
const commonBrowserAPIs = ['document', 'window'];
- if (/Unknown file extension \"\.(jsx|vue|svelte|astro|css)\" for /.test(err.message)) {
+ if (/Unknown file extension "\.(?:jsx|vue|svelte|astro|css)" for /.test(err.message)) {
return 'You likely need to add this package to `vite.ssr.noExternal` in your astro config file.';
} else if (commonBrowserAPIs.some((api) => err.toString().includes(api))) {
const hint = `Browser APIs are not available on the server.
@@ -172,10 +172,12 @@ function collectInfoFromStacktrace(error: SSRError & { stack: string }): StackIn
error.id ||
// TODO: this could be better, `src` might be something else
stackText.split('\n').find((ln) => ln.includes('src') || ln.includes('node_modules'));
+ // Disable eslint as we're not sure how to improve this regex yet
+ // eslint-disable-next-line regexp/no-super-linear-backtracking
const source = possibleFilePath?.replace(/^[^(]+\(([^)]+).*$/, '$1').replace(/^\s+at\s+/, '');
- let file = source?.replace(/(:[0-9]+)/g, '');
- const location = /:([0-9]+):([0-9]+)/g.exec(source!) ?? [];
+ let file = source?.replace(/:\d+/g, '');
+ const location = /:(\d+):(\d+)/.exec(source!) ?? [];
const line = location[1];
const column = location[2];
@@ -195,8 +197,8 @@ function collectInfoFromStacktrace(error: SSRError & { stack: string }): StackIn
// Derive plugin from stack (if possible)
if (!stackInfo.plugin) {
stackInfo.plugin =
- /withastro\/astro\/packages\/integrations\/([\w-]+)/gim.exec(stackText)?.at(1) ||
- /(@astrojs\/[\w-]+)\/(server|client|index)/gim.exec(stackText)?.at(1) ||
+ /withastro\/astro\/packages\/integrations\/([\w-]+)/i.exec(stackText)?.at(1) ||
+ /(@astrojs\/[\w-]+)\/(server|client|index)/i.exec(stackText)?.at(1) ||
undefined;
}
@@ -208,7 +210,7 @@ function collectInfoFromStacktrace(error: SSRError & { stack: string }): StackIn
function cleanErrorStack(stack: string) {
return stack
- .split(/\n/g)
+ .split(/\n/)
.map((l) => l.replace(/\/@fs\//g, '/'))
.join('\n');
}
@@ -233,10 +235,10 @@ export function getDocsForError(err: ErrorWithMetadata): string | undefined {
* Render a subset of Markdown to HTML or a CLI output
*/
export function renderErrorMarkdown(markdown: string, target: 'html' | 'cli') {
- const linkRegex = /\[([^\[]+)\]\((.*)\)/gm;
- const boldRegex = /\*\*(.+)\*\*/gm;
- const urlRegex = / (\b(https?|ftp):\/\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])/gim;
- const codeRegex = /`([^`]+)`/gim;
+ const linkRegex = /\[([^[]+)\]\((.*)\)/g;
+ const boldRegex = /\*\*(.+)\*\*/g;
+ const urlRegex = / ((?:https?|ftp):\/\/[-\w+&@#\\/%?=~|!:,.;]*[-\w+&@#\\/%=~|])/gi;
+ const codeRegex = /`([^`]+)`/g;
if (target === 'html') {
return escape(markdown)
diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts
index 11bc3570d..aaa71b02c 100644
--- a/packages/astro/src/core/errors/errors-data.ts
+++ b/packages/astro/src/core/errors/errors-data.ts
@@ -587,7 +587,7 @@ export const PrerenderDynamicEndpointPathCollide = {
message: (pathname: string) =>
`Could not render \`${pathname}\` with an \`undefined\` param as the generated path will collide during prerendering. Prevent passing \`undefined\` as \`params\` for the endpoint's \`getStaticPaths()\` function, or add an additional extension to the endpoint's filename.`,
hint: (filename: string) =>
- `Rename \`${filename}\` to \`${filename.replace(/\.(js|ts)/, (m) => `.json` + m)}\``,
+ `Rename \`${filename}\` to \`${filename.replace(/\.(?:js|ts)/, (m) => `.json` + m)}\``,
} satisfies ErrorData;
/**
* @docs
diff --git a/packages/astro/src/core/logger/vite.ts b/packages/astro/src/core/logger/vite.ts
index 9604a68f0..ca803e0ff 100644
--- a/packages/astro/src/core/logger/vite.ts
+++ b/packages/astro/src/core/logger/vite.ts
@@ -12,15 +12,15 @@ function isAstroSrcFile(id: string | null) {
}
// capture "page reload some/Component.vue (additional info)" messages
-const vitePageReloadMsg = /page reload (.*)( \(.*\))?/;
+const vitePageReloadMsg = /page reload (.*)/;
// capture "hmr update some/Component.vue" messages
const viteHmrUpdateMsg = /hmr update (.*)/;
// capture "vite v5.0.0 building SSR bundle for production..." and "vite v5.0.0 building for production..." messages
const viteBuildMsg = /vite.*building.*for production/;
// capture "\n Shortcuts" messages
-const viteShortcutTitleMsg = /^\s*Shortcuts\s*$/s;
+const viteShortcutTitleMsg = /^\s*Shortcuts\s*$/;
// capture "press * + enter to ..." messages
-const viteShortcutHelpMsg = /press\s+(.*?)\s+to\s+(.*)$/s;
+const viteShortcutHelpMsg = /press (.+?) to (.+)$/s;
export function createViteLogger(
astroLogger: AstroLogger,
@@ -39,8 +39,7 @@ export function createViteLogger(
// Rewrite HMR page reload message
if ((m = vitePageReloadMsg.exec(stripped))) {
if (isAstroSrcFile(m[1])) return;
- const extra = m[2] ?? '';
- astroLogger.info('watch', m[1] + extra);
+ astroLogger.info('watch', m[1]);
}
// Rewrite HMR update message
else if ((m = viteHmrUpdateMsg.exec(stripped))) {
diff --git a/packages/astro/src/core/messages.ts b/packages/astro/src/core/messages.ts
index 5b424944f..f69b84697 100644
--- a/packages/astro/src/core/messages.ts
+++ b/packages/astro/src/core/messages.ts
@@ -225,7 +225,7 @@ export function formatConfigErrorMessage(err: ZodError) {
// a regex to match the first line of a stack trace
const STACK_LINE_REGEXP = /^\s+at /g;
-const IRRELEVANT_STACK_REGEXP = /(node_modules|astro[\/\\]dist)/g;
+const IRRELEVANT_STACK_REGEXP = /node_modules|astro[/\\]dist/g;
function formatErrorStackTrace(
err: Error | ErrorWithMetadata,
showFullStacktrace: boolean
diff --git a/packages/astro/src/core/preview/vite-plugin-astro-preview.ts b/packages/astro/src/core/preview/vite-plugin-astro-preview.ts
index 9ec940c68..a425807dc 100644
--- a/packages/astro/src/core/preview/vite-plugin-astro-preview.ts
+++ b/packages/astro/src/core/preview/vite-plugin-astro-preview.ts
@@ -7,7 +7,7 @@ import { notFoundTemplate, subpathNotUsedTemplate } from '../../template/4xx.js'
import { cleanUrl } from '../../vite-plugin-utils/index.js';
import { stripBase } from './util.js';
-const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/;
+const HAS_FILE_EXTENSION_REGEXP = /\.[^/]+$/;
export function vitePluginAstroPreview(settings: AstroSettings): Plugin {
const { base, outDir, trailingSlash } = settings.config;
diff --git a/packages/astro/src/core/routing/manifest/create.ts b/packages/astro/src/core/routing/manifest/create.ts
index 3818f08c7..6a1064c05 100644
--- a/packages/astro/src/core/routing/manifest/create.ts
+++ b/packages/astro/src/core/routing/manifest/create.ts
@@ -43,13 +43,15 @@ function countOccurrences(needle: string, haystack: string) {
function getParts(part: string, file: string) {
const result: RoutePart[] = [];
+ // Disable eslint as we're not sure how to improve this regex yet
+ // eslint-disable-next-line regexp/no-super-linear-backtracking
part.split(/\[(.+?\(.+?\)|.+?)\]/).map((str, i) => {
if (!str) return;
const dynamic = i % 2 === 1;
const [, content] = dynamic ? /([^(]+)$/.exec(str) || [null, null] : [null, str];
- if (!content || (dynamic && !/^(\.\.\.)?[a-zA-Z0-9_$]+$/.test(content))) {
+ if (!content || (dynamic && !/^(?:\.\.\.)?[\w$]+$/.test(content))) {
throw new Error(`Invalid route ${file} — parameter name must match /^[a-zA-Z0-9_$]+$/`);
}
diff --git a/packages/astro/src/events/error.ts b/packages/astro/src/events/error.ts
index b3326091d..8b8e9767e 100644
--- a/packages/astro/src/events/error.ts
+++ b/packages/astro/src/events/error.ts
@@ -26,7 +26,7 @@ interface ConfigErrorEventPayload extends ErrorEventPayload {
* This is only used for errors that do not come from us so we can get a basic
* and anonymous idea of what the error is about.
*/
-const ANONYMIZE_MESSAGE_REGEX = /^(\w| )+/;
+const ANONYMIZE_MESSAGE_REGEX = /^(?:\w| )+/;
function anonymizeErrorMessage(msg: string): string | undefined {
const matchedMessage = msg.match(ANONYMIZE_MESSAGE_REGEX);
if (!matchedMessage?.[0]) {
@@ -100,7 +100,7 @@ function getSafeErrorMessage(message: string | Function): string {
.trim()
.slice(1, -1)
.replace(
- /\${([^}]+)}/gm,
+ /\$\{([^}]+)\}/g,
(str, match1) =>
`${match1
.split(/\.?(?=[A-Z])/)
diff --git a/packages/astro/src/i18n/middleware.ts b/packages/astro/src/i18n/middleware.ts
index 9fabff13a..5e9f17a6a 100644
--- a/packages/astro/src/i18n/middleware.ts
+++ b/packages/astro/src/i18n/middleware.ts
@@ -32,13 +32,6 @@ function pathnameHasLocale(pathname: string, locales: Locales): boolean {
return false;
}
-type MiddlewareOptions = {
- i18n: SSRManifest['i18n'];
- base: SSRManifest['base'];
- trailingSlash: SSRManifest['trailingSlash'];
- buildFormat: SSRManifest['buildFormat'];
-};
-
export function createI18nMiddleware(
i18n: SSRManifest['i18n'],
base: SSRManifest['base'],
diff --git a/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts b/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts
index ac1624cd9..2b4943908 100644
--- a/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts
+++ b/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts
@@ -240,7 +240,7 @@ export const a11y: AuditRuleWithSelector[] = [
message:
'Screen readers already announce `img` elements as an image. There is no need to use words such as "image", "photo", and/or "picture".',
selector: 'img[alt]:not([aria-hidden])',
- match: (img: HTMLImageElement) => /\b(image|picture|photo)\b/i.test(img.alt),
+ match: (img: HTMLImageElement) => /\b(?:image|picture|photo)\b/i.test(img.alt),
},
{
code: 'a11y-incorrect-aria-attribute-type',
diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts
index 3fcb6f2aa..6d2117545 100644
--- a/packages/astro/src/runtime/server/render/component.ts
+++ b/packages/astro/src/runtime/server/render/component.ts
@@ -65,8 +65,8 @@ function isHTMLComponent(Component: unknown) {
return Component && (Component as any)['astro:html'] === true;
}
-const ASTRO_SLOT_EXP = /\<\/?astro-slot\b[^>]*>/g;
-const ASTRO_STATIC_SLOT_EXP = /\<\/?astro-static-slot\b[^>]*>/g;
+const ASTRO_SLOT_EXP = /<\/?astro-slot\b[^>]*>/g;
+const ASTRO_STATIC_SLOT_EXP = /<\/?astro-static-slot\b[^>]*>/g;
function removeStaticAstroSlot(html: string, supportsAstroStaticSlot: boolean) {
const exp = supportsAstroStaticSlot ? ASTRO_STATIC_SLOT_EXP : ASTRO_SLOT_EXP;
return html.replace(exp, '');
@@ -390,7 +390,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
}
function sanitizeElementName(tag: string) {
- const unsafe = /[&<>'"\s]+/g;
+ const unsafe = /[&<>'"\s]+/;
if (!unsafe.test(tag)) return tag;
return tag.trim().split(unsafe)[0].trim();
}
diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts
index 0e3f41383..91883024e 100644
--- a/packages/astro/src/runtime/server/render/util.ts
+++ b/packages/astro/src/runtime/server/render/util.ts
@@ -7,17 +7,17 @@ import { HTMLString, markHTMLString } from '../escape.js';
export const voidElementNames =
/^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i;
const htmlBooleanAttributes =
- /^(allowfullscreen|async|autofocus|autoplay|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|itemscope)$/i;
-const htmlEnumAttributes = /^(contenteditable|draggable|spellcheck|value)$/i;
+ /^(?:allowfullscreen|async|autofocus|autoplay|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|itemscope)$/i;
+const htmlEnumAttributes = /^(?:contenteditable|draggable|spellcheck|value)$/i;
// Note: SVG is case-sensitive!
-const svgEnumAttributes = /^(autoReverse|externalResourcesRequired|focusable|preserveAlpha)$/i;
+const svgEnumAttributes = /^(?:autoReverse|externalResourcesRequired|focusable|preserveAlpha)$/i;
const STATIC_DIRECTIVES = new Set(['set:html', 'set:text']);
// converts (most) arbitrary strings to valid JS identifiers
const toIdent = (k: string) =>
- k.trim().replace(/(?:(?!^)\b\w|\s+|[^\w]+)/g, (match, index) => {
- if (/[^\w]|\s/.test(match)) return '';
+ k.trim().replace(/(?!^)\b\w|\s+|\W+/g, (match, index) => {
+ if (/\W/.test(match)) return '';
return index === 0 ? match : match.toUpperCase();
});
diff --git a/packages/astro/src/virtual-modules/content.ts b/packages/astro/src/virtual-modules/content.ts
index a3e9a6828..8424f3b06 100644
--- a/packages/astro/src/virtual-modules/content.ts
+++ b/packages/astro/src/virtual-modules/content.ts
@@ -66,6 +66,7 @@ export const reference = noop;
/** Run `astro sync` to generate high fidelity types */
export type CollectionKey = any;
/** Run `astro sync` to generate high fidelity types */
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
export type CollectionEntry<C> = any;
/** Run `astro sync` to generate high fidelity types */
export type ContentCollectionKey = any;
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index f04e23641..0cc8a8193 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -108,7 +108,7 @@ export async function matchRoute(
// Try without `.html` extensions or `index.html` in request URLs to mimic
// routing behavior in production builds. This supports both file and directory
// build formats, and is necessary based on how the manifest tracks build targets.
- const altPathname = pathname.replace(/(index)?\.html$/, '');
+ const altPathname = pathname.replace(/(?:index)?\.html$/, '');
if (altPathname !== pathname) {
return await matchRoute(altPathname, manifestData, pipeline);
}
@@ -229,6 +229,8 @@ export async function handleRoute({
return '';
},
params: [],
+ // Disable eslint as we only want to generate an empty RegExp
+ // eslint-disable-next-line prefer-regex-literals
pattern: new RegExp(''),
prerender: false,
segments: [],
diff --git a/packages/astro/src/vite-plugin-astro/compile.ts b/packages/astro/src/vite-plugin-astro/compile.ts
index 15fc9ba73..3a1d4c6f6 100644
--- a/packages/astro/src/vite-plugin-astro/compile.ts
+++ b/packages/astro/src/vite-plugin-astro/compile.ts
@@ -4,6 +4,7 @@ import { compile, type CompileProps, type CompileResult } from '../core/compile/
import type { Logger } from '../core/logger/core.js';
import { getFileInfo } from '../vite-plugin-utils/index.js';
import type { CompileMetadata } from './types.js';
+import { frontmatterRE } from './utils.js';
interface CompileAstroOption {
compileProps: CompileProps;
@@ -23,8 +24,6 @@ interface EnhanceCompilerErrorOptions {
logger: Logger;
}
-const FRONTMATTER_PARSE_REGEXP = /^\-\-\-(.*)^\-\-\-/ms;
-
export async function compileAstro({
compileProps,
astroFileToCompileMetadata,
@@ -107,7 +106,7 @@ async function enhanceCompileError({
// Before throwing, it is better to verify the frontmatter here, and
// let esbuild throw a more specific exception if the code is invalid.
// If frontmatter is valid or cannot be parsed, then continue.
- const scannedFrontmatter = FRONTMATTER_PARSE_REGEXP.exec(source);
+ const scannedFrontmatter = frontmatterRE.exec(source);
if (scannedFrontmatter) {
// Top-level return is not supported, so replace `return` with throw
const frontmatter = scannedFrontmatter[1].replace(/\breturn\b/g, 'throw');
diff --git a/packages/astro/src/vite-plugin-astro/hmr.ts b/packages/astro/src/vite-plugin-astro/hmr.ts
index 949fc1d6c..28527f90e 100644
--- a/packages/astro/src/vite-plugin-astro/hmr.ts
+++ b/packages/astro/src/vite-plugin-astro/hmr.ts
@@ -4,6 +4,7 @@ import type { HmrContext } from 'vite';
import type { Logger } from '../core/logger/core.js';
import type { CompileAstroResult } from './compile.js';
import type { CompileMetadata } from './types.js';
+import { frontmatterRE } from './utils.js';
export interface HandleHotUpdateOptions {
logger: Logger;
@@ -58,8 +59,10 @@ export async function handleHotUpdate(
}
}
-const frontmatterRE = /^\-\-\-.*?^\-\-\-/ms;
+// Disable eslint as we're not sure how to improve this regex yet
+// eslint-disable-next-line regexp/no-super-linear-backtracking
const scriptRE = /<script(?:\s.*?)?>.*?<\/script>/gs;
+// eslint-disable-next-line regexp/no-super-linear-backtracking
const styleRE = /<style(?:\s.*?)?>.*?<\/style>/gs;
function isStyleOnlyChanged(oldCode: string, newCode: string) {
diff --git a/packages/astro/src/vite-plugin-astro/utils.ts b/packages/astro/src/vite-plugin-astro/utils.ts
new file mode 100644
index 000000000..8bb5b617a
--- /dev/null
+++ b/packages/astro/src/vite-plugin-astro/utils.ts
@@ -0,0 +1 @@
+export const frontmatterRE = /^---(.*?)^---/ms;
diff --git a/packages/astro/src/vite-plugin-env/index.ts b/packages/astro/src/vite-plugin-env/index.ts
index 2e16cc5bf..6621d2179 100644
--- a/packages/astro/src/vite-plugin-env/index.ts
+++ b/packages/astro/src/vite-plugin-env/index.ts
@@ -13,7 +13,7 @@ interface EnvPluginOptions {
const importMetaEnvOnlyRe = /\bimport\.meta\.env\b(?!\.)/;
// Match valid JS variable names (identifiers), which accepts most alphanumeric characters,
// except that the first character cannot be a number.
-const isValidIdentifierRe = /^[_$a-zA-Z][_$a-zA-Z0-9]*$/;
+const isValidIdentifierRe = /^[_$a-zA-Z][\w$]*$/;
// Match `export const prerender = import.meta.env.*` since `vite=plugin-scanner` requires
// the `import.meta.env.*` to always be replaced.
const exportConstPrerenderRe = /\bexport\s+const\s+prerender\s*=\s*import\.meta\.env\.(.+?)\b/;
diff --git a/packages/astro/src/vite-plugin-head/index.ts b/packages/astro/src/vite-plugin-head/index.ts
index 228e4e437..0350e9d77 100644
--- a/packages/astro/src/vite-plugin-head/index.ts
+++ b/packages/astro/src/vite-plugin-head/index.ts
@@ -9,7 +9,7 @@ import type { BuildInternals } from '../core/build/internal.js';
import { getAstroMetadata } from '../vite-plugin-astro/index.js';
// Detect this in comments, both in .astro components and in js/ts files.
-const injectExp = /(^\/\/|\/\/!)\s*astro-head-inject/;
+const injectExp = /(?:^\/\/|\/\/!)\s*astro-head-inject/;
export default function configHeadVitePlugin(): vite.Plugin {
let server: vite.ViteDevServer;
diff --git a/packages/astro/src/vite-plugin-html/transform/utils.ts b/packages/astro/src/vite-plugin-html/transform/utils.ts
index 88cb226e5..dd0ebcd14 100644
--- a/packages/astro/src/vite-plugin-html/transform/utils.ts
+++ b/packages/astro/src/vite-plugin-html/transform/utils.ts
@@ -1,7 +1,7 @@
import type { Element } from 'hast';
import type MagicString from 'magic-string';
-const splitAttrsTokenizer = /([\$\{\}\@a-z0-9_\:\-]*)\s*?=\s*?(['"]?)(.*?)\2\s+/gim;
+const splitAttrsTokenizer = /([${}@\w:\-]*)\s*=\s*?(['"]?)(.*?)\2\s+/g;
export function replaceAttribute(s: MagicString, node: Element, key: string, newValue: string) {
splitAttrsTokenizer.lastIndex = 0;
@@ -12,7 +12,7 @@ export function replaceAttribute(s: MagicString, node: Element, key: string, new
if (offset === -1) return;
const start = node.position!.start.offset! + offset;
const tokens = text.slice(offset).split(splitAttrsTokenizer);
- const token = tokens[0].replace(/([^>])(\>[\s\S]*$)/gim, '$1');
+ const token = tokens[0].replace(/([^>])>[\s\S]*$/gm, '$1');
if (token.trim() === key) {
const end = start + key.length;
return s.overwrite(start, end, newValue, { contentOnly: true });
diff --git a/packages/astro/src/vite-plugin-scanner/scan.ts b/packages/astro/src/vite-plugin-scanner/scan.ts
index 6c277567d..4e0e5fbfe 100644
--- a/packages/astro/src/vite-plugin-scanner/scan.ts
+++ b/packages/astro/src/vite-plugin-scanner/scan.ts
@@ -65,7 +65,7 @@ export async function scan(
.trim();
// For a given export, check the value of the first non-whitespace token.
// Basically extract the `true` from the statement `export const prerender = true`
- const suffix = code.slice(endOfLocalName).trim().replace(/\=/, '').trim().split(/[;\n]/)[0];
+ const suffix = code.slice(endOfLocalName).trim().replace(/=/, '').trim().split(/[;\n]/)[0];
if (prefix !== 'const' || !(isTruthy(suffix) || isFalsy(suffix))) {
throw new AstroError({
...AstroErrorData.InvalidPrerenderExport,
diff --git a/packages/astro/src/vite-plugin-utils/index.ts b/packages/astro/src/vite-plugin-utils/index.ts
index 6f672d7d9..21ade5b0a 100644
--- a/packages/astro/src/vite-plugin-utils/index.ts
+++ b/packages/astro/src/vite-plugin-utils/index.ts
@@ -17,7 +17,7 @@ export function getFileInfo(id: string, config: AstroConfig) {
let fileUrl = fileId.includes('/pages/')
? fileId
.replace(/^.*?\/pages\//, sitePathname)
- .replace(/(\/index)?\.(md|markdown|mdown|mkdn|mkd|mdwn|md|astro)$/, '')
+ .replace(/(?:\/index)?\.(?:md|markdown|mdown|mkdn|mkd|mdwn|astro)$/, '')
: undefined;
if (fileUrl && config.trailingSlash === 'always') {
fileUrl = appendForwardSlash(fileUrl);
diff --git a/packages/astro/test/0-css.test.js b/packages/astro/test/0-css.test.js
index 3a4b9241d..c8c5af6d8 100644
--- a/packages/astro/test/0-css.test.js
+++ b/packages/astro/test/0-css.test.js
@@ -42,7 +42,7 @@ describe('CSS', function () {
const classes = $('#class');
let scopedAttribute;
for (const [key] of Object.entries(classes[0].attribs)) {
- if (/^data-astro-cid-[A-Za-z0-9-]+/.test(key)) {
+ if (/^data-astro-cid-[A-Za-z\d-]+/.test(key)) {
// Ema: this is ugly, but for reasons that I don't want to explore, cheerio
// lower case the hash of the attribute
scopedAttribute = key;
@@ -72,7 +72,7 @@ describe('CSS', function () {
it('Child inheritance', (done) => {
for (const [key] of Object.entries($('#passed-in')[0].attribs)) {
- if (/^data-astro-cid-[A-Za-z0-9-]+/.test(key)) {
+ if (/^data-astro-cid-[A-Za-z\d-]+/.test(key)) {
done();
}
}
@@ -84,25 +84,25 @@ describe('CSS', function () {
});
it('<style lang="sass">', async () => {
- expect(bundledCSS).to.match(new RegExp('h1\\[data-astro-cid-[^{]*{color:#90ee90}'));
+ expect(bundledCSS).to.match(/h1\[data-astro-cid-[^{]*\{color:#90ee90\}/);
});
it('<style lang="scss">', async () => {
- expect(bundledCSS).to.match(new RegExp('h1\\[data-astro-cid-[^{]*{color:#ff69b4}'));
+ expect(bundledCSS).to.match(/h1\[data-astro-cid-[^{]*\{color:#ff69b4\}/);
});
});
describe('Styles in src/', () => {
it('.css', async () => {
- expect(bundledCSS).to.match(new RegExp('.linked-css[^{]*{color:gold'));
+ expect(bundledCSS).to.match(/.linked-css[^{]*\{color:gold/);
});
it('.sass', async () => {
- expect(bundledCSS).to.match(new RegExp('.linked-sass[^{]*{color:#789'));
+ expect(bundledCSS).to.match(/.linked-sass[^{]*\{color:#789/);
});
it('.scss', async () => {
- expect(bundledCSS).to.match(new RegExp('.linked-scss[^{]*{color:#6b8e23'));
+ expect(bundledCSS).to.match(/.linked-scss[^{]*\{color:#6b8e23/);
});
});
@@ -118,7 +118,7 @@ describe('CSS', function () {
it('.module.css', async () => {
const el = $('#react-module-css');
const classes = el.attr('class').split(' ');
- const moduleClass = classes.find((name) => /^_title_[A-Za-z0-9-_]+/.test(name));
+ const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name));
// 1. check HTML
expect(el.attr('class')).to.include(moduleClass);
@@ -134,7 +134,7 @@ describe('CSS', function () {
expect(el.attr('class')).to.include('react-sass-title');
// 2. check CSS
- expect(bundledCSS).to.match(new RegExp(`.react-sass-title[^{]*{font-family:fantasy`));
+ expect(bundledCSS).to.match(/.react-sass-title[^{]*\{font-family:fantasy/);
});
it('.scss', async () => {
@@ -144,13 +144,13 @@ describe('CSS', function () {
expect(el.attr('class')).to.include('react-scss-title');
// 2. check CSS
- expect(bundledCSS).to.match(new RegExp(`.react-scss-title[^{]*{font-family:fantasy`));
+ expect(bundledCSS).to.match(/.react-scss-title[^{]*\{font-family:fantasy/);
});
it('.module.sass', async () => {
const el = $('#react-module-sass');
const classes = el.attr('class').split(' ');
- const moduleClass = classes.find((name) => /^_title_[A-Za-z0-9-_]+/.test(name));
+ const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name));
// 1. check HTML
expect(el.attr('class')).to.include(moduleClass);
@@ -162,7 +162,7 @@ describe('CSS', function () {
it('.module.scss', async () => {
const el = $('#react-module-scss');
const classes = el.attr('class').split(' ');
- const moduleClass = classes.find((name) => /^_title_[A-Za-z0-9-_]+/.test(name));
+ const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name));
// 1. check HTML
expect(el.attr('class')).to.include(moduleClass);
@@ -189,7 +189,7 @@ describe('CSS', function () {
expect(el.attr('class')).to.include('vue-css');
// 2. check CSS
- expect(bundledCSS).to.match(new RegExp(`.vue-css[^{]*{font-family:cursive`));
+ expect(bundledCSS).to.match(/.vue-css[^{]*\{font-family:cursive/);
});
it('<style scoped>', async () => {
@@ -210,7 +210,7 @@ describe('CSS', function () {
it('<style module>', async () => {
const el = $('#vue-modules');
const classes = el.attr('class').split(' ');
- const moduleClass = classes.find((name) => /^_title_[A-Za-z0-9-_]+/.test(name));
+ const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name));
// 1. check HTML
expect(el.attr('class')).to.include(moduleClass);
@@ -226,7 +226,7 @@ describe('CSS', function () {
expect(el.attr('class')).to.include('vue-sass');
// 2. check CSS
- expect(bundledCSS).to.match(new RegExp(`.vue-sass[^{]*{font-family:cursive`));
+ expect(bundledCSS).to.match(/.vue-sass[^{]*\{font-family:cursive/);
});
it('<style lang="scss">', async () => {
@@ -236,7 +236,7 @@ describe('CSS', function () {
expect(el.attr('class')).to.include('vue-scss');
// 2. check CSS
- expect(bundledCSS).to.match(new RegExp(`.vue-scss[^{]*{font-family:cursive`));
+ expect(bundledCSS).to.match(/.vue-scss[^{]*\{font-family:cursive/);
});
});
@@ -245,7 +245,7 @@ describe('CSS', function () {
const el = $('#svelte-css');
const classes = el.attr('class').split(' ');
const scopedClass = classes.find(
- (name) => name !== 'svelte-css' && /^svelte-[A-Za-z0-9-]+/.test(name)
+ (name) => name !== 'svelte-css' && /^svelte-[A-Za-z\d-]+/.test(name)
);
// 1. check HTML
@@ -261,7 +261,7 @@ describe('CSS', function () {
const el = $('#svelte-sass');
const classes = el.attr('class').split(' ');
const scopedClass = classes.find(
- (name) => name !== 'svelte-sass' && /^svelte-[A-Za-z0-9-]+/.test(name)
+ (name) => name !== 'svelte-sass' && /^svelte-[A-Za-z\d-]+/.test(name)
);
// 1. check HTML
@@ -277,7 +277,7 @@ describe('CSS', function () {
const el = $('#svelte-scss');
const classes = el.attr('class').split(' ');
const scopedClass = classes.find(
- (name) => name !== 'svelte-scss' && /^svelte-[A-Za-z0-9-]+/.test(name)
+ (name) => name !== 'svelte-scss' && /^svelte-[A-Za-z\d-]+/.test(name)
);
// 1. check HTML
diff --git a/packages/astro/test/astro-css-bundling.test.js b/packages/astro/test/astro-css-bundling.test.js
index ae66ea838..9143a782b 100644
--- a/packages/astro/test/astro-css-bundling.test.js
+++ b/packages/astro/test/astro-css-bundling.test.js
@@ -102,7 +102,7 @@ describe('CSS Bundling', function () {
it('CSS does not include hashes', async () => {
const [firstFound] = await fixture.readdir('/assets');
- expect(firstFound).to.not.match(/[a-z]+\.[0-9a-z]{8}\.css/);
+ expect(firstFound).to.not.match(/[a-z]+\.[\da-z]{8}\.css/);
});
it('there are 2 index named CSS files', async () => {
diff --git a/packages/astro/test/astro-doctype.test.js b/packages/astro/test/astro-doctype.test.js
index 65c0a5543..8c954141e 100644
--- a/packages/astro/test/astro-doctype.test.js
+++ b/packages/astro/test/astro-doctype.test.js
@@ -29,10 +29,7 @@ describe('Doctype', () => {
// test that Doctype included was preserved
expect(html).to.match(
- new RegExp(
- '^<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
- 'i'
- )
+ /^<!DOCTYPE html PUBLIC "-\/\/W3C\/\/DTD HTML 4.01 Transitional\/\/EN" "http:\/\/www.w3.org\/TR\/html4\/loose.dtd">/i
);
});
diff --git a/packages/astro/test/astro-partial-html.test.js b/packages/astro/test/astro-partial-html.test.js
index 162c6985d..83dccaf80 100644
--- a/packages/astro/test/astro-partial-html.test.js
+++ b/packages/astro/test/astro-partial-html.test.js
@@ -26,7 +26,7 @@ describe('Partial HTML', async () => {
// test 2: correct CSS present
const allInjectedStyles = $('style').text();
- expect(allInjectedStyles).to.match(/\[data-astro-cid-[^{]+{color:red}/);
+ expect(allInjectedStyles).to.match(/\[data-astro-cid-[^{]+\{color:red\}/);
});
it('injects framework styles', async () => {
@@ -38,7 +38,7 @@ describe('Partial HTML', async () => {
// test 2: link tag present
const allInjectedStyles = $('style').text().replace(/\s*/g, '');
- expect(allInjectedStyles).to.match(/h1{color:red;}/);
+ expect(allInjectedStyles).to.match(/h1\{color:red;\}/);
});
it('pages with a head, injection happens inside', async () => {
diff --git a/packages/astro/test/component-library.test.js b/packages/astro/test/component-library.test.js
index c11f9eed6..a135c40cb 100644
--- a/packages/astro/test/component-library.test.js
+++ b/packages/astro/test/component-library.test.js
@@ -58,7 +58,7 @@ describe('Component Libraries', () => {
expect($('button').text()).to.equal('Click me', "Rendered the component's slot");
- const findEvidence = createFindEvidence(/border-radius:( )*1rem/);
+ const findEvidence = createFindEvidence(/border-radius:\s*1rem/);
expect(await findEvidence('with-astro/index.html')).to.equal(
true,
"Included the .astro component's <style>"
@@ -136,7 +136,7 @@ describe('Component Libraries', () => {
expect($('button').text()).to.equal('Click me', "Rendered the component's slot");
- const findEvidence = createFindEvidence(/border-radius:( )*1rem/);
+ const findEvidence = createFindEvidence(/border-radius:\s*1rem/);
expect(await findEvidence('/with-astro/')).to.equal(
true,
"Included the .astro component's <style>"
diff --git a/packages/astro/test/config-vite-css-target.test.js b/packages/astro/test/config-vite-css-target.test.js
index 94fa74e74..52e6d4c7f 100644
--- a/packages/astro/test/config-vite-css-target.test.js
+++ b/packages/astro/test/config-vite-css-target.test.js
@@ -36,7 +36,7 @@ describe('CSS', function () {
it('vite.build.cssTarget is respected', async () => {
expect(bundledCSS).to.match(
- new RegExp('.class\\[data-astro-[^{]*{top:0;right:0;bottom:0;left:0}')
+ /\.class\[data-astro-[^{]*\{top:0;right:0;bottom:0;left:0\}/
);
});
});
diff --git a/packages/astro/test/config-vite.test.js b/packages/astro/test/config-vite.test.js
index b15729dd7..1b4eaf11c 100644
--- a/packages/astro/test/config-vite.test.js
+++ b/packages/astro/test/config-vite.test.js
@@ -17,6 +17,6 @@ describe('Vite Config', async () => {
it('Allows overriding bundle naming options in the build', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
- expect($('link').attr('href')).to.match(/\/assets\/testing-[a-z0-9]+\.css/);
+ expect($('link').attr('href')).to.match(/\/assets\/testing-[a-z\d]+\.css/);
});
});
diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js
index 447079fa2..1b5618349 100644
--- a/packages/astro/test/core-image.test.js
+++ b/packages/astro/test/core-image.test.js
@@ -955,7 +955,7 @@ describe('astro:image', () => {
let $script = $('script');
// Find image
- const regex = /src:"([^"]*)/gm;
+ const regex = /src:"([^"]*)/;
const imageSrc = regex.exec($script.html())[1];
const data = await fixture.readFile(imageSrc, null);
expect(data).to.be.an.instanceOf(Buffer);
@@ -967,7 +967,7 @@ describe('astro:image', () => {
const srcset = $('#local-2-widths-with-spaces img').attr('srcset');
// Find image
- const regex = /^(.+?) [0-9]+[wx]$/gm;
+ const regex = /^(.+?) \d+[wx]$/m;
const imageSrcset = regex.exec(srcset)[1];
expect(imageSrcset).to.not.contain(' ');
});
diff --git a/packages/astro/test/css-dangling-references.test.js b/packages/astro/test/css-dangling-references.test.js
index c38aa854d..9aa9b2828 100644
--- a/packages/astro/test/css-dangling-references.test.js
+++ b/packages/astro/test/css-dangling-references.test.js
@@ -1,7 +1,7 @@
import { expect } from 'chai';
import { loadFixture } from './test-utils.js';
-const cssAssetReferenceRegExp = /_astro\/[A-Za-z0-9\-]+\.[a0-9a-f]{8}\.css/g;
+const cssAssetReferenceRegExp = /_astro\/[A-Za-z\d\-]+\.[\da-f]{8}\.css/g;
describe("When Vite's preloadModule polyfill is used", async () => {
let fixture;
diff --git a/packages/astro/test/hoisted-imports.test.js b/packages/astro/test/hoisted-imports.test.js
index c5ce98e05..9fc76cac1 100644
--- a/packages/astro/test/hoisted-imports.test.js
+++ b/packages/astro/test/hoisted-imports.test.js
@@ -19,7 +19,7 @@ describe('Hoisted Imports', () => {
const $ = cheerio.load(html);
const scriptText = [];
- const importRegex = /import\s*?['"]([^'"]+?)['"]/g;
+ const importRegex = /import\s*['"]([^'"]+)['"]/g;
async function resolveImports(text) {
const matches = text.matchAll(importRegex);
for (const match of matches) {
diff --git a/packages/astro/test/markdown.test.js b/packages/astro/test/markdown.test.js
index 471205844..1df89715b 100644
--- a/packages/astro/test/markdown.test.js
+++ b/packages/astro/test/markdown.test.js
@@ -70,7 +70,7 @@ describe('Markdown tests', () => {
it('Does not unescape entities', async () => {
const html = await fixture.readFile('/entities/index.html');
- expect(html).to.match(new RegExp('&#x3C;i>This should NOT be italic&#x3C;/i>'));
+ expect(html).to.match(/&#x3C;i>This should NOT be italic&#x3C;\/i>/);
});
});
});
diff --git a/packages/astro/test/minification-html.test.js b/packages/astro/test/minification-html.test.js
index cd3e70a1d..eec388321 100644
--- a/packages/astro/test/minification-html.test.js
+++ b/packages/astro/test/minification-html.test.js
@@ -2,7 +2,7 @@ import { expect } from 'chai';
import { loadFixture } from './test-utils.js';
import testAdapter from './test-adapter.js';
-const NEW_LINES = /[\r\n]+/gm;
+const NEW_LINES = /[\r\n]+/g;
/**
* The doctype declaration is on a line between the rest of the HTML in SSG.
diff --git a/packages/astro/test/postcss.test.js b/packages/astro/test/postcss.test.js
index 0fcc60409..2ef15c4e1 100644
--- a/packages/astro/test/postcss.test.js
+++ b/packages/astro/test/postcss.test.js
@@ -26,23 +26,23 @@ describe('PostCSS', function () {
/** All test cases check whether nested styles (i.e. &.nested {}) are correctly transformed */
it('works in Astro page styles', () => {
- expect(bundledCSS).to.match(new RegExp(`\.astro-page(\.(\w|-)*)*\.nested`));
+ expect(bundledCSS).to.match(/\.astro-page\[data-astro-cid-.*?\]\.nested/);
});
it('works in Astro component styles', () => {
- expect(bundledCSS).to.match(new RegExp(`\.astro-component(\.(\w|-)*)*\.nested`));
+ expect(bundledCSS).to.match(/\.astro-component\[data-astro-cid-.*?\]\.nested/);
});
it('works in JSX', () => {
- expect(bundledCSS).to.match(new RegExp(`\.solid(\.(\w|-)*)*\.nested`));
+ expect(bundledCSS).to.match(/\.solid(\.(w|-)*)*\.nested/);
});
it('works in Vue', () => {
- expect(bundledCSS).to.match(new RegExp(`\.vue(\.(\w|-)*)*\.nested`));
+ expect(bundledCSS).to.match(/\.vue(\.(w|-)*)*\.nested/);
});
it('works in Svelte', () => {
- expect(bundledCSS).to.match(new RegExp(`\.svelte(\.(\w|-)*)*\.nested`));
+ expect(bundledCSS).to.match(/\.svelte(\.(w|-)*)*\.nested/);
});
it('ignores CSS in public/', async () => {
diff --git a/packages/astro/test/root-srcdir-css.test.js b/packages/astro/test/root-srcdir-css.test.js
index e033ff35b..abb452db1 100644
--- a/packages/astro/test/root-srcdir-css.test.js
+++ b/packages/astro/test/root-srcdir-css.test.js
@@ -20,6 +20,6 @@ describe('srcDir', () => {
const relPath = $('link').attr('href');
const css = await fixture.readFile(relPath);
- expect(css).to.match(/body{color:green}/);
+ expect(css).to.match(/body\{color:green\}/);
});
});
diff --git a/packages/astro/test/ssr-api-route.test.js b/packages/astro/test/ssr-api-route.test.js
index e15993b88..d6ea4ac84 100644
--- a/packages/astro/test/ssr-api-route.test.js
+++ b/packages/astro/test/ssr-api-route.test.js
@@ -108,7 +108,7 @@ describe('API routes in SSR', () => {
});
let count = 0;
- let exp = /set-cookie\:/g;
+ let exp = /set-cookie:/g;
while (exp.exec(response)) {
count++;
}
diff --git a/packages/astro/test/static-build.test.js b/packages/astro/test/static-build.test.js
index 5ec225133..79aff0ef0 100644
--- a/packages/astro/test/static-build.test.js
+++ b/packages/astro/test/static-build.test.js
@@ -128,7 +128,7 @@ describe('Static build', () => {
}
describe('Page CSS', () => {
- const findEvidence = createFindEvidence(/height:( )*45vw/);
+ const findEvidence = createFindEvidence(/height:\s*45vw/);
it('Page level CSS is added', async () => {
const found = await findEvidence('/index.html');
@@ -186,7 +186,7 @@ describe('Static build', () => {
let found = false;
for (const log of logs) {
if (
- /\`Astro\.request\.headers\` is not available in "static" output mode/.test(log.message)
+ /`Astro\.request\.headers` is not available in "static" output mode/.test(log.message)
) {
found = true;
}
diff --git a/packages/astro/test/tailwindcss.test.js b/packages/astro/test/tailwindcss.test.js
index 3c249cc2c..dd41e5a63 100644
--- a/packages/astro/test/tailwindcss.test.js
+++ b/packages/astro/test/tailwindcss.test.js
@@ -28,20 +28,20 @@ describe('Tailwind', () => {
});
it('resolves CSS in src/styles', async () => {
- expect(bundledCSS, 'includes used component classes').to.match(/\.bg-purple-600{/);
+ expect(bundledCSS, 'includes used component classes').to.match(/\.bg-purple-600\{/);
// tests a random tailwind class that isn't used on the page
- expect(bundledCSS, 'purges unused classes').not.to.match(/\.bg-blue-600{/);
+ expect(bundledCSS, 'purges unused classes').not.to.match(/\.bg-blue-600\{/);
// tailwind escapes colons, `lg:py-3` compiles to `lg\:py-3`
- expect(bundledCSS, 'includes responsive classes').to.match(/\.lg\\:py-3{/);
+ expect(bundledCSS, 'includes responsive classes').to.match(/\.lg\\:py-3\{/);
// tailwind escapes brackets, `font-[900]` compiles to `font-\[900\]`
- expect(bundledCSS, 'supports arbitrary value classes').to.match(/\.font-\\\[900\\\]{/);
+ expect(bundledCSS, 'supports arbitrary value classes').to.match(/\.font-\\\[900\\\]\{/);
// custom theme colors were included
- expect(bundledCSS, 'includes custom theme colors').to.match(/\.text-midnight{/);
- expect(bundledCSS, 'includes custom theme colors').to.match(/\.bg-dawn{/);
+ expect(bundledCSS, 'includes custom theme colors').to.match(/\.text-midnight\{/);
+ expect(bundledCSS, 'includes custom theme colors').to.match(/\.bg-dawn\{/);
});
it('maintains classes in HTML', async () => {
@@ -64,7 +64,7 @@ describe('Tailwind', () => {
const $md = cheerio.load(html);
const bundledCSSHREF = $md('link[rel=stylesheet][href^=/_astro/]').attr('href');
const mdBundledCSS = await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'));
- expect(mdBundledCSS, 'includes used component classes').to.match(/\.bg-purple-600{/);
+ expect(mdBundledCSS, 'includes used component classes').to.match(/\.bg-purple-600\{/);
});
});
});
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index 213c98711..2d97969be 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -302,7 +302,7 @@ export async function parseCliDevStart(proc) {
const messages = stdout
.split('\n')
.filter((ln) => !!ln.trim())
- .map((ln) => ln.replace(/[🚀┃]/g, '').replace(/\s+/g, ' ').trim());
+ .map((ln) => ln.replace(/[🚀┃]/gu, '').replace(/\s+/g, ' ').trim());
return { messages };
}
diff --git a/packages/astro/test/units/correct-path.js b/packages/astro/test/units/correct-path.js
index ff741414d..026baeaf6 100644
--- a/packages/astro/test/units/correct-path.js
+++ b/packages/astro/test/units/correct-path.js
@@ -40,7 +40,7 @@ function normalizePath(str, stripTrailing) {
if (typeof str !== 'string') {
throw new TypeError('expected a string');
}
- str = str.replace(/[\\\/]+/g, '/');
+ str = str.replace(/[\\/]+/g, '/');
if (stripTrailing !== false) {
str = removeTrailingSeparator(str);
}
diff --git a/packages/create-astro/src/actions/verify.ts b/packages/create-astro/src/actions/verify.ts
index ac3eae484..a567e1d1f 100644
--- a/packages/create-astro/src/actions/verify.ts
+++ b/packages/create-astro/src/actions/verify.ts
@@ -79,6 +79,8 @@ async function verifyTemplate(tmpl: string, ref?: string) {
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
+// Disable eslint rule to not touch the original code
+// eslint-disable-next-line regexp/no-misleading-capturing-group
const GIT_RE = /^(?<repo>[\w.-]+\/[\w.-]+)(?<subdir>[^#]+)?(?<ref>#[\w.-]+)?/;
function parseGitURI(input: string) {
diff --git a/packages/integrations/markdoc/src/html/css/parse-inline-css-to-react.ts b/packages/integrations/markdoc/src/html/css/parse-inline-css-to-react.ts
index dd429788a..2e445d35f 100644
--- a/packages/integrations/markdoc/src/html/css/parse-inline-css-to-react.ts
+++ b/packages/integrations/markdoc/src/html/css/parse-inline-css-to-react.ts
@@ -17,7 +17,7 @@ export function parseInlineCSSToReactLikeObject(
function convertCssDirectiveNameToReactCamelCase(original: string): string {
// capture group 1 is the character to capitalize, the hyphen is omitted by virtue of being outside the capture group
- const replaced = original.replace(/-([a-z0-9])/gi, (_match, char) => {
+ const replaced = original.replace(/-([a-z\d])/gi, (_match, char) => {
return char.toUpperCase();
});
return replaced;
diff --git a/packages/integrations/markdoc/src/html/css/parse-inline-styles.ts b/packages/integrations/markdoc/src/html/css/parse-inline-styles.ts
index 623b560af..fa3217c89 100644
--- a/packages/integrations/markdoc/src/html/css/parse-inline-styles.ts
+++ b/packages/integrations/markdoc/src/html/css/parse-inline-styles.ts
@@ -23,9 +23,11 @@ const NEWLINE_REGEX = /\n/g;
const WHITESPACE_REGEX = /^\s*/;
// declaration
-const PROPERTY_REGEX = /^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/;
+const PROPERTY_REGEX = /^([-#/*\\\w]+(\[[\da-z_-]+\])?)\s*/;
const COLON_REGEX = /^:\s*/;
-const VALUE_REGEX = /^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/;
+// Disable eslint as we're not sure how to improve this regex yet
+// eslint-disable-next-line regexp/no-super-linear-backtracking
+const VALUE_REGEX = /^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*\)|[^};])+)/;
const SEMICOLON_REGEX = /^[;\s]*/;
// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts
index 78c8ce889..80d8c1b76 100644
--- a/packages/integrations/mdx/src/index.ts
+++ b/packages/integrations/mdx/src/index.ts
@@ -153,7 +153,7 @@ export default function mdx(partialMdxOptions: Partial<MdxOptions> = {}): AstroI
.filter(({ n }) => n === 'astro/jsx-runtime')
.map(({ ss, se }) => code.substring(ss, se));
const hasFragmentImport = importsFromJSXRuntime.some((statement) =>
- /[\s,{](Fragment,|Fragment\s*})/.test(statement)
+ /[\s,{](?:Fragment,|Fragment\s*\})/.test(statement)
);
if (!hasFragmentImport) {
code = 'import { Fragment } from "astro/jsx-runtime"\n' + code;
diff --git a/packages/integrations/mdx/src/utils.ts b/packages/integrations/mdx/src/utils.ts
index a5b198116..199929dc8 100644
--- a/packages/integrations/mdx/src/utils.ts
+++ b/packages/integrations/mdx/src/utils.ts
@@ -31,7 +31,7 @@ export function getFileInfo(id: string, config: AstroConfig): FileInfo {
let fileUrl: string;
const isPage = fileId.includes('/pages/');
if (isPage) {
- fileUrl = fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.mdx$/, '');
+ fileUrl = fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(?:\/index)?\.mdx$/, '');
} else if (url?.pathname.startsWith(config.root.pathname)) {
fileUrl = url.pathname.slice(config.root.pathname.length);
} else {
diff --git a/packages/integrations/partytown/src/sirv.ts b/packages/integrations/partytown/src/sirv.ts
index 7bba54b66..e6f7c6218 100644
--- a/packages/integrations/partytown/src/sirv.ts
+++ b/packages/integrations/partytown/src/sirv.ts
@@ -175,7 +175,9 @@ export default function (dir, opts = {}) {
let ignores = [];
if (opts.ignores !== false) {
- ignores.push(/[/]([A-Za-z\s\d~$._-]+\.\w+){1,}$/); // any extn
+ // Disable eslint as we're not sure how to improve this regex yet
+ // eslint-disable-next-line regexp/no-super-linear-backtracking
+ ignores.push(/\/([\w\s~$.-]+\.\w+)+$/); // any extn
if (opts.dotfiles) ignores.push(/\/\.\w/);
else ignores.push(/\/\.well-known/);
[].concat(opts.ignores || []).forEach((x) => {
@@ -189,9 +191,9 @@ export default function (dir, opts = {}) {
if (!opts.dev) {
totalist(dir, (name, abs, stats) => {
- if (/\.well-known[\\+\/]/.test(name)) {
+ if (/\.well-known[\\+/]/.test(name)) {
} // keep
- else if (!opts.dotfiles && /(^\.|[\\+|\/+]\.)/.test(name)) return;
+ else if (!opts.dotfiles && /^\.|[\\+|/]\./.test(name)) return;
let headers = toHeaders(name, stats, isEtag);
if (cc) headers['Cache-Control'] = cc;
@@ -212,7 +214,7 @@ export default function (dir, opts = {}) {
// NEW END
let val = req.headers['accept-encoding'] || '';
if (gzips && val.includes('gzip')) extns.unshift(...gzips);
- if (brots && /(br|brotli)/i.test(val)) extns.unshift(...brots);
+ if (brots && /br/i.test(val)) extns.unshift(...brots);
extns.push(...extensions); // [...br, ...gz, orig, ...exts]
if (pathname.indexOf('%') !== -1) {
diff --git a/packages/integrations/preact/src/server.ts b/packages/integrations/preact/src/server.ts
index 79461c572..01b2ba100 100644
--- a/packages/integrations/preact/src/server.ts
+++ b/packages/integrations/preact/src/server.ts
@@ -37,7 +37,7 @@ async function check(
// There are edge cases (SolidJS) where Preact *might* render a string,
// but components would be <undefined></undefined>
// It also might render an empty sting.
- return html == '' ? false : !/\<undefined\>/.test(html);
+ return html == '' ? false : !/<undefined>/.test(html);
} catch (err) {
return false;
}
diff --git a/packages/integrations/sitemap/test/staticPaths.test.js b/packages/integrations/sitemap/test/staticPaths.test.js
index 0e7353765..4054ad930 100644
--- a/packages/integrations/sitemap/test/staticPaths.test.js
+++ b/packages/integrations/sitemap/test/staticPaths.test.js
@@ -38,6 +38,6 @@ describe('getStaticPaths support', () => {
it('should render the endpoint', async () => {
const page = await fixture.readFile('./it/manifest');
- assert.match(page, /I\'m a route in the "it" language./);
+ assert.match(page, /I'm a route in the "it" language./);
});
});
diff --git a/packages/integrations/vue/src/editor.cts b/packages/integrations/vue/src/editor.cts
index 0b62e899e..0c9642d67 100644
--- a/packages/integrations/vue/src/editor.cts
+++ b/packages/integrations/vue/src/editor.cts
@@ -23,7 +23,7 @@ export function toTSX(code: string, className: string): string {
const { scriptSetup } = parsedResult.descriptor;
if (scriptSetup) {
- const definePropsType = scriptSetup.content.match(/defineProps<([\S\s]+?)>\s?\(\)/m);
+ const definePropsType = scriptSetup.content.match(/defineProps<([\s\S]+?)>\s?\(\)/);
const propsGeneric = scriptSetup.attrs.generic;
const propsGenericType = propsGeneric ? `<${propsGeneric}>` : '';
@@ -40,7 +40,7 @@ export function toTSX(code: string, className: string): string {
// TODO. Find a way to support generics when using defineProps without passing explicit types.
// Right now something like this `defineProps({ prop: { type: Array as PropType<T[]> } })`
// won't be correctly typed in Astro.
- const defineProps = scriptSetup.content.match(/defineProps\([\s\S]+\)/m);
+ const defineProps = scriptSetup.content.match(/defineProps\([\s\S]+\)/);
if (defineProps) {
result = `
diff --git a/packages/integrations/vue/test/app-entrypoint.test.js b/packages/integrations/vue/test/app-entrypoint.test.js
index 5cdae3c04..5c0437636 100644
--- a/packages/integrations/vue/test/app-entrypoint.test.js
+++ b/packages/integrations/vue/test/app-entrypoint.test.js
@@ -41,7 +41,7 @@ describe('App Entrypoint', () => {
assert.notEqual(client, undefined);
const js = await fixture.readFile(client);
- assert.match(js, /\w+\.component\(\"Bar\"/gm);
+ assert.match(js, /\w+\.component\("Bar"/g);
});
it('loads svg components without transforming them to assets', async () => {
@@ -112,7 +112,7 @@ describe('App Entrypoint no export default', () => {
const client = island.getAttribute('renderer-url');
assert.notEqual(client, undefined);
const js = await fixture.readFile(client);
- assert.doesNotMatch(js, /\w+\.component\(\"Bar\"/gm);
+ assert.doesNotMatch(js, /\w+\.component\("Bar"/g);
});
it('loads svg components without transforming them to assets', async () => {
@@ -151,7 +151,7 @@ describe('App Entrypoint relative', () => {
assert.notEqual(client, undefined);
const js = await fixture.readFile(client);
- assert.doesNotMatch(js, /\w+\.component\(\"Bar\"/gm);
+ assert.doesNotMatch(js, /\w+\.component\("Bar"/g);
});
});
@@ -182,7 +182,7 @@ describe('App Entrypoint /src/absolute', () => {
assert.notEqual(client, undefined);
const js = await fixture.readFile(client);
- assert.doesNotMatch(js, /\w+\.component\(\"Bar\"/gm);
+ assert.doesNotMatch(js, /\w+\.component\("Bar"/g);
});
});
diff --git a/packages/internal-helpers/src/path.ts b/packages/internal-helpers/src/path.ts
index cc9954ef2..fbbebc7c9 100644
--- a/packages/internal-helpers/src/path.ts
+++ b/packages/internal-helpers/src/path.ts
@@ -16,7 +16,7 @@ export function prependForwardSlash(path: string) {
}
export function collapseDuplicateSlashes(path: string) {
- return path.replace(/(?<!:)\/\/+/g, '/');
+ return path.replace(/(?<!:)\/{2,}/g, '/');
}
export function removeTrailingForwardSlash(path: string) {
@@ -86,7 +86,7 @@ export function removeQueryString(path: string) {
}
export function isRemotePath(src: string) {
- return /^(http|ftp|https|ws):?\/\//.test(src) || src.startsWith('data:');
+ return /^(?:http|ftp|https|ws):?\/\//.test(src) || src.startsWith('data:');
}
export function slash(path: string) {
diff --git a/packages/markdown/remark/src/shiki.ts b/packages/markdown/remark/src/shiki.ts
index 492d5a821..4024d4bc1 100644
--- a/packages/markdown/remark/src/shiki.ts
+++ b/packages/markdown/remark/src/shiki.ts
@@ -13,7 +13,7 @@ const ASTRO_COLOR_REPLACEMENTS: Record<string, string> = {
'--astro-code-background': '--astro-code-color-background',
};
const COLOR_REPLACEMENT_REGEX = new RegExp(
- `(${Object.keys(ASTRO_COLOR_REPLACEMENTS).join('|')})`,
+ `${Object.keys(ASTRO_COLOR_REPLACEMENTS).join('|')}`,
'g'
);
diff --git a/packages/telemetry/src/project-info.ts b/packages/telemetry/src/project-info.ts
index 16ea50f3b..79b9e4f44 100644
--- a/packages/telemetry/src/project-info.ts
+++ b/packages/telemetry/src/project-info.ts
@@ -91,7 +91,7 @@ function getProjectId(isCI: boolean): Pick<ProjectInfo, 'anonymousProjectId' | '
// If we're running in CI, the current working directory is not unique.
// If the cwd is a single level deep (ex: '/app'), it's probably not unique.
const cwd = process.cwd();
- const isCwdGeneric = (cwd.match(/[\/|\\]/g) || []).length === 1;
+ const isCwdGeneric = (cwd.match(/[/|\\]/g) || []).length === 1;
if (isCI || isCwdGeneric) {
return {
isGit: false,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 61ee0ecac..007f9239d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -51,6 +51,9 @@ importers:
eslint-plugin-prettier:
specifier: ^5.0.0
version: 5.1.2(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1)
+ eslint-plugin-regexp:
+ specifier: ^2.2.0
+ version: 2.2.0(eslint@8.56.0)
globby:
specifier: ^14.0.0
version: 14.0.0
@@ -8894,6 +8897,11 @@ packages:
engines: {node: ^12.20.0 || >=14}
dev: true
+ /comment-parser@1.4.1:
+ resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==}
+ engines: {node: '>= 12.0.0'}
+ dev: true
+
/common-ancestor-path@1.0.1:
resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==}
dev: false
@@ -9633,6 +9641,22 @@ packages:
synckit: 0.8.8
dev: true
+ /eslint-plugin-regexp@2.2.0(eslint@8.56.0):
+ resolution: {integrity: sha512-0kwpiWiLRVBkVr3oIRQLl196sXP/NF6DQFefv9jtR4ZOgQR+6WID2pIZ0I+wIt54qgBPwBB7Gm2a+ueh8/WsFQ==}
+ engines: {node: ^18 || >=20}
+ peerDependencies:
+ eslint: '>=8.44.0'
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
+ '@eslint-community/regexpp': 4.10.0
+ comment-parser: 1.4.1
+ eslint: 8.56.0
+ jsdoc-type-pratt-parser: 4.0.0
+ refa: 0.12.1
+ regexp-ast-analysis: 0.7.1
+ scslre: 0.3.0
+ dev: true
+
/eslint-scope@7.2.2:
resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -11165,6 +11189,11 @@ packages:
dependencies:
argparse: 2.0.1
+ /jsdoc-type-pratt-parser@4.0.0:
+ resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==}
+ engines: {node: '>=12.0.0'}
+ dev: true
+
/jsdom@22.1.0:
resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==}
engines: {node: '>=16'}
@@ -13755,6 +13784,13 @@ packages:
strip-indent: 3.0.0
dev: true
+ /refa@0.12.1:
+ resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+ dependencies:
+ '@eslint-community/regexpp': 4.10.0
+ dev: true
+
/regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: true
@@ -13763,6 +13799,14 @@ packages:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
dev: true
+ /regexp-ast-analysis@0.7.1:
+ resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+ dependencies:
+ '@eslint-community/regexpp': 4.10.0
+ refa: 0.12.1
+ dev: true
+
/regexp.prototype.flags@1.5.1:
resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==}
engines: {node: '>= 0.4'}
@@ -14162,6 +14206,15 @@ packages:
dependencies:
loose-envify: 1.4.0
+ /scslre@0.3.0:
+ resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==}
+ engines: {node: ^14.0.0 || >=16.0.0}
+ dependencies:
+ '@eslint-community/regexpp': 4.10.0
+ refa: 0.12.1
+ regexp-ast-analysis: 0.7.1
+ dev: true
+
/section-matter@1.0.0:
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
engines: {node: '>=4'}