Skip to content

Commit f13279e

Browse files
authored
chore: add eslint-plugin-regexp (#1123)
1 parent 8bcb171 commit f13279e

File tree

18 files changed

+146
-20
lines changed

18 files changed

+146
-20
lines changed

.oxlintrc.json

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://unpkg.com/oxlint/configuration_schema.json",
33
"plugins": ["unicorn", "typescript", "oxc", "vue", "vitest"],
4-
"jsPlugins": ["@e18e/eslint-plugin"],
4+
"jsPlugins": ["@e18e/eslint-plugin", "eslint-plugin-regexp"],
55
"categories": {
66
"correctness": "error",
77
"suspicious": "warn",
@@ -17,7 +17,72 @@
1717
"e18e/prefer-timer-args": "error",
1818
"e18e/prefer-date-now": "error",
1919
"e18e/prefer-regex-test": "error",
20-
"e18e/prefer-array-some": "error"
20+
"e18e/prefer-array-some": "error",
21+
// RegExp - Possible Errors (most critical)
22+
"regexp/no-contradiction-with-assertion": "error",
23+
"regexp/no-dupe-disjunctions": "error",
24+
"regexp/no-empty-alternative": "error",
25+
"regexp/no-empty-capturing-group": "error",
26+
"regexp/no-empty-character-class": "error",
27+
"regexp/no-empty-group": "error",
28+
"regexp/no-empty-lookarounds-assertion": "error",
29+
"regexp/no-escape-backspace": "error",
30+
"regexp/no-invalid-regexp": "error",
31+
"regexp/no-lazy-ends": "error",
32+
"regexp/no-misleading-capturing-group": "error",
33+
"regexp/no-misleading-unicode-character": "error",
34+
"regexp/no-missing-g-flag": "error",
35+
"regexp/no-optional-assertion": "error",
36+
"regexp/no-potentially-useless-backreference": "error",
37+
"regexp/no-super-linear-backtracking": "error",
38+
"regexp/no-useless-assertions": "error",
39+
"regexp/no-useless-backreference": "error",
40+
"regexp/no-useless-dollar-replacements": "error",
41+
"regexp/strict": "error",
42+
// RegExp - Best Practices
43+
"regexp/confusing-quantifier": "warn",
44+
"regexp/control-character-escape": "error",
45+
"regexp/negation": "error",
46+
"regexp/no-dupe-characters-character-class": "error",
47+
"regexp/no-empty-string-literal": "error",
48+
"regexp/no-extra-lookaround-assertions": "error",
49+
"regexp/no-invisible-character": "error",
50+
"regexp/no-legacy-features": "error",
51+
"regexp/no-non-standard-flag": "error",
52+
"regexp/no-obscure-range": "error",
53+
"regexp/no-octal": "error",
54+
"regexp/no-standalone-backslash": "error",
55+
"regexp/no-trivially-nested-assertion": "error",
56+
"regexp/no-trivially-nested-quantifier": "error",
57+
"regexp/no-unused-capturing-group": "warn",
58+
"regexp/no-useless-character-class": "error",
59+
"regexp/no-useless-flag": "error",
60+
"regexp/no-useless-lazy": "error",
61+
"regexp/no-useless-quantifier": "error",
62+
"regexp/no-useless-range": "error",
63+
"regexp/no-useless-set-operand": "error",
64+
"regexp/no-useless-string-literal": "error",
65+
"regexp/no-useless-two-nums-quantifier": "error",
66+
"regexp/no-zero-quantifier": "error",
67+
"regexp/optimal-lookaround-quantifier": "warn",
68+
"regexp/optimal-quantifier-concatenation": "error",
69+
"regexp/prefer-predefined-assertion": "error",
70+
"regexp/prefer-range": "error",
71+
"regexp/prefer-set-operation": "error",
72+
"regexp/simplify-set-operations": "error",
73+
"regexp/use-ignore-case": "error",
74+
// RegExp - Stylistic Issues (less critical, focused on consistency)
75+
"regexp/match-any": "warn",
76+
"regexp/no-useless-escape": "warn",
77+
"regexp/no-useless-non-capturing-group": "warn",
78+
"regexp/prefer-character-class": "warn",
79+
"regexp/prefer-d": "warn",
80+
"regexp/prefer-plus-quantifier": "warn",
81+
"regexp/prefer-question-quantifier": "warn",
82+
"regexp/prefer-star-quantifier": "warn",
83+
"regexp/prefer-unicode-codepoint-escapes": "warn",
84+
"regexp/prefer-w": "warn",
85+
"regexp/sort-flags": "warn"
2186
},
2287
"overrides": [
2388
{

app/composables/useStructuredFilters.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function parseSearchOperators(input: string): ParsedSearchOperators {
4242

4343
// Regex to match operators: name:value, desc:value, description:value, kw:value, keyword:value
4444
// Value continues until whitespace or next operator
45-
const operatorRegex = /\b(name|desc|description|kw|keyword):([^\s]+)/gi
45+
const operatorRegex = /\b(name|desc|description|kw|keyword):(\S+)/gi
4646

4747
let remaining = input
4848
let match

app/pages/search.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ function isValidNpmName(name: string): boolean {
303303
// Must start with alphanumeric
304304
if (!/^[a-z0-9]/i.test(name)) return false
305305
// Can contain alphanumeric, hyphen, underscore
306-
return /^[a-z0-9_-]+$/i.test(name)
306+
return /^[\w-]+$/.test(name)
307307
}
308308
309309
/** Validated user/org suggestion */

app/utils/formatters.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,9 @@ export function formatCompactNumber(
3131

3232
const fmt = (n: number) => {
3333
if (decimals <= 0) return Math.round(n).toString()
34-
return n
35-
.toFixed(decimals)
36-
.replace(/\.0+$/, '')
37-
.replace(/(\.\d*?)0+$/, '$1')
34+
const fixed = n.toFixed(decimals)
35+
// Remove trailing zeros after decimal point
36+
return fixed.includes('.') ? fixed.replace(/0+$/, '').replace(/\.$/, '') : fixed
3837
}
3938

4039
const join = (suffix: string, n: number) => `${sign}${fmt(n)}${space ? ' ' : ''}${suffix}`

app/utils/npm/outdated-dependencies.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface OutdatedDependencyInfo {
2020
*/
2121
export function constraintIncludesPrerelease(constraint: string): boolean {
2222
return (
23-
/-(alpha|beta|rc|next|canary|dev|preview|pre|experimental)/i.test(constraint) ||
23+
/-(?:alpha|beta|rc|next|canary|dev|preview|pre|experimental)/i.test(constraint) ||
2424
/-\d/.test(constraint)
2525
)
2626
}

cli/src/schemas.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import validateNpmPackageName from 'validate-npm-package-name'
33

44
// Validation pattern for npm usernames/org names
55
// These follow similar rules: lowercase alphanumeric with hyphens, can't start/end with hyphen
6-
const NPM_USERNAME_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/i
6+
const NPM_USERNAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i
77

88
// ============================================================================
99
// Base Schemas

knip.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const config: KnipConfig = {
4242

4343
/** Oxlint plugins don't get picked up yet */
4444
'@e18e/eslint-plugin',
45+
'eslint-plugin-regexp',
4546
],
4647
ignoreUnresolved: ['#components', '#oauth/config'],
4748
},

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"@vitest/coverage-v8": "4.0.18",
117117
"@vue/test-utils": "2.4.6",
118118
"axe-core": "4.11.1",
119+
"eslint-plugin-regexp": "3.0.0",
119120
"fast-check": "4.5.3",
120121
"h3": "1.15.5",
121122
"knip": "5.83.0",

pnpm-lock.yaml

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/api/registry/org/[org]/packages.get.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { CACHE_MAX_AGE_ONE_HOUR } from '#shared/utils/constants'
33
const NPM_REGISTRY = 'https://registry.npmjs.org'
44

55
// Validation pattern for npm org names (alphanumeric with hyphens)
6-
const NPM_ORG_NAME_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/i
6+
const NPM_ORG_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i
77

88
function validateOrgName(name: string): void {
99
if (!name || name.length > 50 || !NPM_ORG_NAME_RE.test(name)) {

0 commit comments

Comments
 (0)