Skip to content

[WIP] Fix NPM detector to differentiate packages by namespace#1713

Open
Copilot wants to merge 8 commits intomainfrom
copilot/fix-npm-detector-namespace-issue
Open

[WIP] Fix NPM detector to differentiate packages by namespace#1713
Copilot wants to merge 8 commits intomainfrom
copilot/fix-npm-detector-namespace-issue

Conversation

Copy link
Contributor

Copilot AI commented Mar 13, 2026

  • Add Name property to PackageLockV3Package model to capture the real package name for aliased packages
  • Update NpmLockfile3Detector to prefer Name field over path-derived name when available
  • Add Name property to PackageLockV2Package model for consistency
  • Add test for aliased scoped packages with npm:@namespace/packagename@version format in v3 lockfiles (top-level and transitive)
  • Add TryParseNpmAlias utility method to NpmComponentUtilities to parse npm:@scope/name@version format from v1/v2 lockfile version fields
  • Update NpmComponentDetectorWithRoots to use TryParseNpmAlias when creating components from v1/v2 lockfile dependencies section
  • Add unit tests for TryParseNpmAlias in NpmUtilitiesTests
  • Add integration tests for aliased scoped packages in v1/v2 lockfiles in NpmDetectorWithRootsTests
  • Run build and all npm tests to verify (808 tests pass)
  • Run code review (no issues found) and CodeQL checks
Original prompt

This section details on the original issue you should resolve

<issue_title>NPM detector fails to differentiate packages by namespace in some circumstance</issue_title>
<issue_description>When using NPM components, it is possible to have a lockfile that looks like the following (excerpted):

        "license": "MIT",
        "dependencies": {
            "@pnpm/constants": "1001.3.1",
            "@pnpm/dependency-path": "1001.1.9",
            "@pnpm/object.key-sorting": "1000.0.1",
            "@pnpm/types": "1001.3.0",
            "@zkochan/rimraf": "^3.0.2",
            "comver-to-semver": "^1.0.0",
            "js-yaml": "npm:@zkochan/js-yaml@0.0.9",
            "ramda": "npm:@pnpm/ramda@0.28.1",

In this file, Component detection will not use the namespace portion of the js-yaml or ramda packages, and will instead assume the dependencies are the base js-yaml and ramda packages.

It does detect namespaces correct if they are indicated in the name portion of the property, as they are in the @pnpm packages, or in other sections of the file where the direct name of the package contains the namespace, but when used as above, with the npm:@namesapce/packagename format, it will only use the packagename.

The fix would seem to be looking for a @packagename prefix when examining these references, and if found using it with the package name to determine the actual dependency.</issue_description>

<agent_instructions>The issue is fully described, along with a suggested solution. Review the description and proposed solution, look for alternate solutions, and then implement the one that will best solve the problem described.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 3 commits March 13, 2026 17:13
When npm aliases like `npm:@scope/pkg@version` are used, the lockfile
v3 `packages` section stores the real package name in a `name` field
while the path key uses the alias. The detector now prefers the `name`
field over the path-derived name, correctly identifying the real scoped
package instead of the alias.

Co-authored-by: nickmarston <55464672+nickmarston@users.noreply.github.com>
Co-authored-by: nickmarston <55464672+nickmarston@users.noreply.github.com>
Co-authored-by: nickmarston <55464672+nickmarston@users.noreply.github.com>
Copilot AI and others added 3 commits March 13, 2026 17:36
In v1/v2 lockfile `dependencies` sections, aliased packages have a
version field like `npm:@scope/name@version`. Previously these were
silently skipped because the version couldn't be parsed as semver.

Add TryParseNpmAlias to extract the real package name and version
from this format, and use it in NpmComponentDetectorWithRoots.

Co-authored-by: nickmarston <55464672+nickmarston@users.noreply.github.com>
Co-authored-by: nickmarston <55464672+nickmarston@users.noreply.github.com>
Co-authored-by: nickmarston <55464672+nickmarston@users.noreply.github.com>
@nickmarston nickmarston marked this pull request as ready for review March 13, 2026 19:51
@nickmarston nickmarston requested a review from a team as a code owner March 13, 2026 19:51
@nickmarston nickmarston requested review from Copilot and jasonpaulos and removed request for Copilot March 13, 2026 19:51
@github-actions
Copy link

👋 Hi! It looks like you modified some files in the Detectors folder.
You may need to bump the detector versions if any of the following scenarios apply:

  • The detector detects more or fewer components than before
  • The detector generates different parent/child graph relationships than before
  • The detector generates different devDependencies values than before

If none of the above scenarios apply, feel free to ignore this comment 🙂

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.

NPM detector fails to differentiate packages by namespace in some circumstance

2 participants