fix(project-detect): match packageKeys on boundaries, not substrings (#2181)

Framework detection matched a dependency against a framework's packageKeys
with unbounded substring containment (dep.includes(key)), so any dependency
whose name merely contained a key was misclassified: `preact` and even
`reactive` were both detected as `react`.

Match only when the dependency equals the key, or the key is a prefix
immediately followed by a delimiter (/ . _ -). This still matches every real
case (react-dom, @remix-run/node, spring-boot-starter, org.springframework.boot,
github.com/labstack/echo/v4, phoenix_live_view) while excluding preact/reactive
(and incidentally nextra). Adds regression tests.

Co-authored-by: bymle <229636660+bymle@users.noreply.github.com>
This commit is contained in:
bymle
2026-06-07 13:25:34 +08:00
committed by GitHub
parent 09e2bc58d3
commit 9c35aef60f
2 changed files with 47 additions and 1 deletions

View File

@@ -207,6 +207,39 @@ function runTests() {
}
})) passed++; else failed++;
if (test('does not misclassify preact as react (substring guard)', () => {
const dir = createTempDir();
try {
writeTestFile(dir, 'package.json', '{"dependencies":{"preact":"10.0.0"}}');
const result = detectProjectType(dir);
assert.ok(!result.frameworks.includes('react'), `preact wrongly detected as react: ${JSON.stringify(result.frameworks)}`);
} finally {
cleanupDir(dir);
}
})) passed++; else failed++;
if (test('does not misclassify reactive as react (substring guard)', () => {
const dir = createTempDir();
try {
writeTestFile(dir, 'package.json', '{"dependencies":{"reactive":"1.0.0"}}');
const result = detectProjectType(dir);
assert.ok(!result.frameworks.includes('react'), `reactive wrongly detected as react: ${JSON.stringify(result.frameworks)}`);
} finally {
cleanupDir(dir);
}
})) passed++; else failed++;
if (test('still detects react from react-dom alone (prefix-delimiter match preserved)', () => {
const dir = createTempDir();
try {
writeTestFile(dir, 'package.json', '{"dependencies":{"react-dom":"18.0.0"}}');
const result = detectProjectType(dir);
assert.ok(result.frameworks.includes('react'), `react-dom should still map to react: ${JSON.stringify(result.frameworks)}`);
} finally {
cleanupDir(dir);
}
})) passed++; else failed++;
if (test('detects angular from angular.json', () => {
const dir = createTempDir();
try {