fix: replace +(|x) patterns with {,x} for picomatch 2.3.2 compatibility#481
Conversation
…omatch 2.3.2 compatibility
picomatch 2.3.2 changed extglob behavior so that +(|x) no longer matches
an empty string, causing *.ts+(|x) to fail to match .ts files (without x).
Replace +(|x) with {,x} (brace expansion), which correctly matches both
*.ts and *.tsx in picomatch 2.3.1, 2.3.2, and v4.x.
Fixes ezolenko#480
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
+(|x) patterns with {,x} for picomatch 2.3.2 compatibility
|
Sorry for the confusion — that was not a hallucination, but my wording was misleading. When I ran This turned out to be because my Windows environment did not have Developer Mode enabled, which is required for non-elevated symlink creation. After enabling Developer Mode, all 44 tests pass (11 suites, 0 failures). I should not have described it as a "pre-existing issue" — it was purely a local environment configuration issue on my end. Apologies for the confusion. |
For reference, that would be from this line
Ah, I guess that might be because Windows doesn't support POSIX symlinks natively? I'm actually not entirely sure what Node uses under-the-hood for Windows envs. |
There was a problem hiding this comment.
Code LGTM. There is one more spot that needs updating though, the documentation for include's defaults
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
We should also update picomatch in rpt2's own package-lock.json so that self-builds use the newer version. In #480 (comment), I confirmed it breaks self-builds as well; so if it's updated in the package-lock.json, CI self-builds should continue to pass in this PR with the fix
Ensures self-builds use picomatch 2.3.2 so CI validates the fix against the affected version. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The macOS Node 20 CI job is failing with a build error. Looking at the log, it seems I'm not sure how the CI build chain is meant to work in this case — could you advise on what would be the right approach here? |
|
Yep just saw that failed build. |
… picomatch 2.3.2 The build bootstrap uses the installed rpt2 (0.35.x) from node_modules, which has the unfixed +(|x) patterns. By passing explicit include patterns to the rpt2 call in rollup.config.js, the build succeeds even when picomatch 2.3.2 is installed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The root cause of the CI failure was a bootstrap problem: To work around this, I added an explicit Does this approach look okay? |
I can't look at it right now, will check it in a couple of weeks, will be offline until then |
|
Oh, inopportune timing. There's at least 3 people who've hit the bug already, so, if possible, a hotfix would be good to push. I'm fine approving and merging it, but I don't have NPM access to publish. If you want to give me access, I can do it myself. Otherwise, it can wait, we're FOSS volunteers after all. |
|
Ok, published in 0.37.0, @agilgur5 could you do the release on github? |
|
Thanks for the assistance @ezolenko ! I think that was technically my first time pushing to Footnotes
|
My suggestion was to instead have two different But nbd, I've removed the temporary workaround in #483. Thanks again! |
Summary
Closes #480
picomatch 2.3.2 is a security release (CVE-2026-33671, CVE-2026-33672) that changed extglob behavior as part of its fix (see the 2.3.2 commit):
+(|x)no longer matches an empty string. This causes the defaultincludepattern*.ts+(|x)to fail to match plain.tsfiles, breaking TypeScript compilation for projects that have picomatch 2.3.2 installed.Root cause
The pattern
*.ts+(|x)uses an extglob+(...)which means "one or more of the contained alternatives". In picomatch 2.3.1,+(|x)matched an empty string (the|beforexmeans "empty string or x"). In picomatch 2.3.2, this behavior was corrected —+(...)no longer matches zero occurrences, so+(|x)with an empty alternative no longer matches an empty string. As a result,*.ts+(|x)only matches*.tsx, not*.ts.Fix
Replace
+(|x)with{,x}(brace expansion), which correctly matches both*.tsand*.tsxacross picomatch 2.3.1, 2.3.2, and v4.x.Changed patterns:
*.ts+(|x)→*.ts{,x}**/*.ts+(|x)→**/*.ts{,x}Files changed
src/index.ts: Fix defaultincludeoption__tests__/fixtures/options.ts: Fix test fixture__tests__/get-options-overrides.spec.ts: Fix test caseREADME.md: Update documented default patterns to matchpackage-lock.json: Update picomatch to 2.3.2 so CI self-builds validate the fix against the affected versionTesting
Unit tests: All 44 tests pass across 11 suites, verified locally with picomatch 2.3.2.
End-to-end verification using the reproduction repo (https://github.com/koizuka/rpt2-picomatch-repro):
Note: I used Claude (an AI assistant by Anthropic) to help with drafting and verification. The diagnosis and fix have been verified manually against the test suite and the reproduction repository.
🤖 Generated with Claude Code