Skip to content

Commit e4318f4

Browse files
committed
Handle dependencies with @ in constraint for npm manifest files #3931
Signed-off-by: Jono Yang <jyang@nexb.com>
1 parent c43ec34 commit e4318f4

File tree

4 files changed

+165
-0
lines changed

4 files changed

+165
-0
lines changed

src/packagedcode/npm.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,9 @@ def deps_mapper(deps, package, field_name, is_direct=True):
17801780
ns, name = split_scoped_package_name(fqname)
17811781
if not name:
17821782
continue
1783+
if '@' in requirement:
1784+
requirement_package, _, requirement = requirement.partition('@')
1785+
name = f'{name}@{requirement_package}'
17831786
purl = PackageURL(type='npm', namespace=ns, name=name).to_string()
17841787

17851788
# optionalDependencies override the dependencies with the same name
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"name": "@tapjs/tapjs",
3+
"private": true,
4+
"workspaces": [
5+
"src/*"
6+
],
7+
"type": "module",
8+
"prettier": {
9+
"experimentalTernaries": true,
10+
"semi": false,
11+
"printWidth": 70,
12+
"tabWidth": 2,
13+
"useTabs": false,
14+
"singleQuote": true,
15+
"jsxSingleQuote": false,
16+
"bracketSameLine": true,
17+
"arrowParens": "avoid",
18+
"endOfLine": "lf"
19+
},
20+
"devDependencies": {
21+
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1"
22+
},
23+
"scripts": {
24+
"start": "npm run start -w src/docs",
25+
"predocsbuild": "npm run bootstrap",
26+
"docsbuild": "npm run build -w src/docs",
27+
"pretest": "rimraf src/test/test-built/dist/node_modules",
28+
"presnap": "rimraf src/test/test-built/dist/node_modules",
29+
"test": "nx run-many -t test",
30+
"test:bootstrap": "bash ./scripts/test-bootstrap.sh",
31+
"snap": "TAP_TYPECHECK=0 TAP_TIMEOUT=240 nx run-many -t snap",
32+
"format": "nx run-many -t format",
33+
"typedoc": "typedoc",
34+
"bootstrap": "bash ./scripts/bootstrap.sh",
35+
"build": "node ./scripts/default-build.mjs",
36+
"pindeps": "node ./scripts/version.mjs pindeps",
37+
"v": "node ./scripts/version.mjs",
38+
"p": "bash ./scripts/bump-changed.sh",
39+
"pub": "npm run v -- pub",
40+
"deploy:docs": "npm run deploy:prod -w src/docs",
41+
"postv": "npm run deploy:docs",
42+
"pj": "node scripts/normalize-package-json.js src/*/package.json"
43+
},
44+
"repository": "https://github.com/tapjs/tapjs",
45+
"license": "BlueOak-1.0.0",
46+
"engines": {
47+
"node": "20 || >=22"
48+
},
49+
"overrides": {
50+
"braces@3": "^3.0.3",
51+
"axios@1.0.0 - 1.5.1": "^1.7.2",
52+
"netlify-cli": {
53+
"braces": "^3.0.3",
54+
"micromatch": "^4.0.7",
55+
"chokidar": {
56+
"braces": "^3.0.3"
57+
},
58+
"http-proxy-middleware": {
59+
"micromatch": {
60+
".": "^4.0.7",
61+
"braces": "^3.0.3"
62+
}
63+
}
64+
},
65+
"micromatch@4.0.5": "^4.0.7",
66+
"tar@6.1.11": "6.2"
67+
}
68+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
[
2+
{
3+
"type": "npm",
4+
"namespace": "@tapjs",
5+
"name": "tapjs",
6+
"version": null,
7+
"qualifiers": {},
8+
"subpath": null,
9+
"primary_language": "JavaScript",
10+
"description": null,
11+
"release_date": null,
12+
"parties": [],
13+
"keywords": [],
14+
"homepage_url": null,
15+
"download_url": null,
16+
"size": null,
17+
"sha1": null,
18+
"md5": null,
19+
"sha256": null,
20+
"sha512": null,
21+
"bug_tracking_url": null,
22+
"code_view_url": null,
23+
"vcs_url": "https://github.com/tapjs/tapjs",
24+
"copyright": null,
25+
"holder": null,
26+
"declared_license_expression": "blueoak-1.0.0",
27+
"declared_license_expression_spdx": "BlueOak-1.0.0",
28+
"license_detections": [
29+
{
30+
"license_expression": "blueoak-1.0.0",
31+
"license_expression_spdx": "BlueOak-1.0.0",
32+
"matches": [
33+
{
34+
"license_expression": "blueoak-1.0.0",
35+
"spdx_license_expression": "BlueOak-1.0.0",
36+
"from_file": null,
37+
"start_line": 1,
38+
"end_line": 1,
39+
"matcher": "1-spdx-id",
40+
"score": 100.0,
41+
"matched_length": 4,
42+
"match_coverage": 100.0,
43+
"rule_relevance": 100,
44+
"rule_identifier": "spdx-license-identifier-blueoak_1_0_0-a27d3d91aab5047de087c05901869c5f4a1f12e7",
45+
"rule_url": null,
46+
"matched_text": "BlueOak-1.0.0"
47+
}
48+
],
49+
"identifier": "blueoak_1_0_0-3c25fef0-5634-6497-b6c8-0c16ab8320b3"
50+
}
51+
],
52+
"other_license_expression": null,
53+
"other_license_expression_spdx": null,
54+
"other_license_detections": [],
55+
"extracted_license_statement": "- BlueOak-1.0.0\n",
56+
"notice_text": null,
57+
"source_packages": [],
58+
"file_references": [],
59+
"is_private": true,
60+
"is_virtual": false,
61+
"extra_data": {
62+
"workspaces": [
63+
"src/*"
64+
],
65+
"engines": {
66+
"node": "20 || >=22"
67+
}
68+
},
69+
"dependencies": [
70+
{
71+
"purl": "pkg:npm/strip-ansi-cjs%40npm:strip-ansi",
72+
"extracted_requirement": "^6.0.1",
73+
"scope": "devDependencies",
74+
"is_runtime": false,
75+
"is_optional": true,
76+
"is_resolved": false,
77+
"is_direct": true,
78+
"resolved_package": {},
79+
"extra_data": {}
80+
}
81+
],
82+
"repository_homepage_url": null,
83+
"repository_download_url": null,
84+
"api_data_url": null,
85+
"datasource_id": "npm_package_json",
86+
"purl": "pkg:npm/%40tapjs/tapjs"
87+
}
88+
]

tests/packagedcode/test_npm.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,12 @@ def test_parse_pnpm_shrinkwrap_yaml(self):
393393
packages = npm.PnpmLockYamlHandler.parse(test_file)
394394
self.check_packages_data(packages, expected_loc, regen=REGEN_TEST_FIXTURES)
395395

396+
def test_parse_package_json_special_dep_requirements(self):
397+
test_file = self.get_test_loc('npm/special_extracted_requirements/package.json')
398+
expected_loc = self.get_test_loc('npm/special_extracted_requirements/package.json.expected')
399+
packages = npm.NpmPackageJsonHandler.parse(test_file)
400+
self.check_packages_data(packages, expected_loc, regen=REGEN_TEST_FIXTURES)
401+
396402
def test_pnpm_scan_with_workspace_package_json(self):
397403
test_folder = self.get_test_loc('npm/pnpm/pnpm-lock/v5/cobe/')
398404
expected_file = self.get_test_loc('npm/pnpm/pnpm-lock/v5/cobe-scan.expected.json')

0 commit comments

Comments
 (0)