Skip to content

Commit bffa22b

Browse files
reeyjkowalleck
andauthored
feat: enhance package.json finder (#1286)
implements #1284 For assets loaded from a subdirectory of `node_modules`, it will pick the first `package.json` that actually has `name` and `version` attributes. Added a testcase for this, which verifies this functionality for the `luxon` and `libphonenumber-js` packages. The `package.json` for `libphonenumber-js/max` [misses a version number](https://unpkg.com/browse/[email protected]/max/package.json) while for `luxon` [the name is missing](https://unpkg.com/browse/[email protected]/src/package.json). The snapshot has quite a lot of changes: - For some reason the `purl` entries are no longer url encoded. - The `@apollo/client/*` entries have been merged into a single `@apollo/client` entry - The `@babel/runtime` was added as dependency --------- Signed-off-by: Tristan Bastian <[email protected]> Signed-off-by: Jan Kowalleck <[email protected]> Co-authored-by: Jan Kowalleck <[email protected]>
1 parent 42ad6cb commit bffa22b

18 files changed

+6477
-598
lines changed

HISTORY.md

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file.
66

77
<!-- unreleased changes go here -->
88

9+
* Changed
10+
* Improved package detection ([#1284] via [#1286])
11+
12+
[#1284]: https://github.com/CycloneDX/cyclonedx-webpack-plugin/issues/1284
13+
[#1286]: https://github.com/CycloneDX/cyclonedx-webpack-plugin/pull/1286
14+
915
## 3.11.0 - 2024-05-08
1016

1117
* Added

package.json

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
{
4141
"name": "Jan Kowalleck",
4242
"email": "[email protected]"
43+
},
44+
{
45+
"name": "Tristan Bastian",
46+
"url": "https://github.com/reey"
4347
}
4448
],
4549
"type": "commonjs",

src/_helpers.ts

+27-7
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,56 @@ Copyright (c) OWASP Foundation. All Rights Reserved.
1818
*/
1919

2020
import { existsSync, readFileSync } from 'fs'
21-
import { dirname, isAbsolute, join } from 'path'
21+
import { dirname, isAbsolute, join, sep } from 'path'
2222

2323
export interface PackageDescription {
2424
path: string
2525
packageJson: any
2626
}
2727

2828
export function getPackageDescription (path: string): PackageDescription | undefined {
29+
const isSubDirOfNodeModules = isSubDirectoryOfNodeModulesFolder(path)
30+
2931
while (isAbsolute(path)) {
30-
const packageJson = join(path, 'package.json')
31-
if (existsSync(packageJson)) {
32+
const pathToPackageJson = join(path, 'package.json')
33+
if (existsSync(pathToPackageJson)) {
3234
try {
33-
return {
34-
path: packageJson,
35-
packageJson: loadJsonFile(packageJson) ?? {}
35+
const contentOfPackageJson = loadJsonFile(pathToPackageJson) ?? {}
36+
// only look for valid candidate if we are in a node_modules subdirectory
37+
if (!isSubDirOfNodeModules || isValidPackageJSON(contentOfPackageJson)) {
38+
return {
39+
path: pathToPackageJson,
40+
packageJson: loadJsonFile(pathToPackageJson) ?? {}
41+
}
3642
}
3743
} catch {
3844
return undefined
3945
}
4046
}
4147

4248
const nextPath = dirname(path)
43-
if (nextPath === path) {
49+
if (nextPath === path || isNodeModulesFolder(nextPath)) {
4450
return undefined
4551
}
4652
path = nextPath
4753
}
4854
return undefined
4955
}
5056

57+
function isNodeModulesFolder (path: string): boolean {
58+
return path.endsWith(`${sep}node_modules`)
59+
}
60+
61+
function isSubDirectoryOfNodeModulesFolder (path: string): boolean {
62+
return path.includes(`${sep}node_modules${sep}`)
63+
}
64+
65+
export function isValidPackageJSON (pkg: any): boolean {
66+
// checking for the existence of name and version properties
67+
// both are required for a valid package.json according to https://docs.npmjs.com/cli/v10/configuring-npm/package-json
68+
return typeof pkg.name === 'string' && typeof pkg.version === 'string'
69+
}
70+
5171
export function loadJsonFile (path: string): any {
5272
return JSON.parse(readFileSync(path, 'utf8'))
5373
// may be replaced by `require(f, { with: { type: "json" } })`

0 commit comments

Comments
 (0)