Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 21, 2026

Consolidates eslint-plugin-primer-react from its standalone repository into packages/eslint-plugin-primer-react/ within the monorepo.

Package Structure

  • Location: packages/eslint-plugin-primer-react/
  • Testing: Retained Jest (ESLint RuleTester pattern requires CommonJS)
  • Configuration: Removed redundant config files managed at root (.prettierignore, .nvmrc, .changeset/, etc.)
  • Dependencies: Removed from root devDependencies, now workspace-linked

ESLint Configuration

Added exceptions in eslint.config.mjs for the plugin package:

  • Allow CommonJS modules (require/module.exports) - standard for ESLint plugins
  • Disable linting for JSX code examples in rule files
  • Add Jest globals for test files

Documentation

  • Updated all repository URLs from primer/eslint-plugin-primer-react to primer/react
  • Updated rule documentation links to reflect new monorepo path

Changelog

Changed

  • Moved eslint-plugin-primer-react from standalone repository to packages/eslint-plugin-primer-react/
  • Updated package.json repository URLs and metadata
  • Updated ESLint configuration to support CommonJS in plugin package

Rollout strategy

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; internal repository reorganization, no API changes

Testing & Reviewing

All 23 ESLint rules with 376 tests maintained and passing. Plugin loads correctly as workspace package.

Merge checklist

Original prompt

move github.com/primer/eslint-plugin-primer-react as a package inside primer/react


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@changeset-bot
Copy link

changeset-bot bot commented Jan 21, 2026

⚠️ No Changeset found

Latest commit: f177c01

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copilot AI and others added 2 commits January 21, 2026 22:20
…repo

Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
… README

Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
@@ -0,0 +1,19 @@
const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/

Check failure

Code scanning / CodeQL

Inefficient regular expression High

This part of the regular expression may cause exponential backtracking on strings starting with 'a0' and containing many repetitions of '00'.

Copilot Autofix

AI 2 days ago

In general, to fix inefficient regular expressions with nested quantifiers, you either (1) restructure the pattern to avoid ambiguous or overlapping quantified pieces, or (2) remove unnecessary laziness/quantifiers so the engine does a single, straightforward pass. Here, the camelReg, pascalReg, and kebabReg patterns all use a trailing *? or +? where a simple greedy */+ is sufficient, and the groups they wrap are not actually ambiguous. Removing the laziness and unnecessary non‑capturing groups yields simpler, strictly linear patterns that avoid the flagged nested‑quantifier shape.

Concretely, we can:

  • Replace camelReg with a standard camelCase pattern that does not use a lazy outer quantifier: ^[a-z]+(?:[A-Z0-9][a-z0-9]+)*$.
  • Replace pascalReg similarly: ^(?:[A-Z0-9][a-z0-9]+)+$.
  • Replace kebabReg with ^[a-z]+(?:-[a-z0-9]+)*$.

These are equivalent to the originals except that the outer repetition is greedy rather than lazy, which does not change matching behavior in these anchored (^...$) patterns. No additional imports or helper methods are required; we only update the three regex literals on lines 1–3 in packages/eslint-plugin-primer-react/src/utils/casing-matches.js.

Suggested changeset 1
packages/eslint-plugin-primer-react/src/utils/casing-matches.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/eslint-plugin-primer-react/src/utils/casing-matches.js b/packages/eslint-plugin-primer-react/src/utils/casing-matches.js
--- a/packages/eslint-plugin-primer-react/src/utils/casing-matches.js
+++ b/packages/eslint-plugin-primer-react/src/utils/casing-matches.js
@@ -1,6 +1,6 @@
-const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/
-const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/
-const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*?$/
+const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*$/
+const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+$/
+const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*$/
 
 function casingMatches(name, type) {
   switch (type) {
EOF
@@ -1,6 +1,6 @@
const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/
const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/
const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*?$/
const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*$/
const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+$/
const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*$/

function casingMatches(name, type) {
switch (type) {
Copilot is powered by AI and may make mistakes. Always verify output.
@@ -0,0 +1,19 @@
const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/
const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/

Check failure

Code scanning / CodeQL

Inefficient regular expression High

This part of the regular expression may cause exponential backtracking on strings starting with '0' and containing many repetitions of '00'.

Copilot Autofix

AI 2 days ago

In general, to fix inefficient regular expressions you should remove ambiguous nested quantifiers—patterns like (...+)+ or (...*)*—by simplifying the grouping or restructuring the expression so the engine does not need to backtrack exponentially. Often, removing an unnecessary outer */+ or converting a repeated complex group into a simpler character class or linear sequence is enough.

In this file, the problematic regex is:

const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/

The outer +? applies to the whole group (?:[A-Z0-9][a-z0-9]+), and inside that group [a-z0-9]+ is itself quantified. This nested “one or more of (one uppercase/digit followed by one or more lowercase/digit)” can lead to heavy backtracking when the match fails late (as described by CodeQL). Functionally, this pattern is intended to match PascalCase identifiers: a leading capital or digit, followed by any number of lowercase letters/digits, and then repeated for multiple “words”. However, the outer +? is redundant for the semantics you want: multiple repetitions of that group are already covered by allowing the inner “tail” to be arbitrarily long.

A simpler, equivalent, and safer expression is to require exactly one leading [A-Z0-9] and then allow any number of [a-z0-9] characters after it:

const pascalReg = /^[A-Z0-9][a-z0-9]*$/

This matches any non-empty string whose first character is an uppercase letter or digit and whose remaining characters (possibly none) are lowercase letters or digits. That is consistent with the intended Pascal-style casing used here (and also slightly more permissive than the original, since the original required at least one trailing [a-z0-9]; if preserving that exact behavior is required, you can instead use ^[A-Z0-9][a-z0-9]+$, which still removes the nested quantifier). This change only affects line 2 in packages/eslint-plugin-primer-react/src/utils/casing-matches.js; no imports or helper methods are needed.

Suggested changeset 1
packages/eslint-plugin-primer-react/src/utils/casing-matches.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/eslint-plugin-primer-react/src/utils/casing-matches.js b/packages/eslint-plugin-primer-react/src/utils/casing-matches.js
--- a/packages/eslint-plugin-primer-react/src/utils/casing-matches.js
+++ b/packages/eslint-plugin-primer-react/src/utils/casing-matches.js
@@ -1,5 +1,5 @@
 const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/
-const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/
+const pascalReg = /^[A-Z0-9][a-z0-9]*$/
 const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*?$/
 
 function casingMatches(name, type) {
EOF
@@ -1,5 +1,5 @@
const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/
const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/
const pascalReg = /^[A-Z0-9][a-z0-9]*$/
const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*?$/

function casingMatches(name, type) {
Copilot is powered by AI and may make mistakes. Always verify output.
function casingMatches(name, type) {
switch (type) {
case 'camel':
return camelReg.test(name)

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings starting with 'a' and with many repetitions of '00'.
This
regular expression
that depends on
library input
may run slow on strings starting with 'a0' and with many repetitions of '00'.
This
regular expression
that depends on
library input
may run slow on strings starting with 'a' and with many repetitions of '00'.
This
regular expression
that depends on
library input
may run slow on strings starting with 'a0' and with many repetitions of '00'.
case 'camel':
return camelReg.test(name)
case 'pascal':
return pascalReg.test(name)

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings with many repetitions of '00'.
This
regular expression
that depends on
library input
may run slow on strings starting with '0' and with many repetitions of '00'.
This
regular expression
that depends on
library input
may run slow on strings with many repetitions of '00'.
This
regular expression
that depends on
library input
may run slow on strings starting with '0' and with many repetitions of '00'.
Copilot AI changed the title [WIP] Move eslint plugin primer-react as a package Move eslint-plugin-primer-react into monorepo Jan 21, 2026
Copilot AI requested a review from siddharthkp January 21, 2026 22:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants