@cyclonedx/cdxgen 11.1.0 → 11.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/bin/cdxgen.js +1 -1
- package/lib/cli/index.js +81 -2
- package/lib/evinser/evinser.js +1 -4
- package/lib/helpers/utils.js +485 -45
- package/lib/helpers/utils.test.js +18 -3
- package/lib/helpers/validator.js +64 -3
- package/package.json +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/helpers/utils.d.ts +15 -3
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/helpers/validator.d.ts +6 -0
- package/types/lib/helpers/validator.d.ts.map +1 -1
package/README.md
CHANGED
package/bin/cdxgen.js
CHANGED
|
@@ -167,6 +167,7 @@ const args = yargs(hideBin(process.argv))
|
|
|
167
167
|
})
|
|
168
168
|
.option("install-deps", {
|
|
169
169
|
type: "boolean",
|
|
170
|
+
default: true,
|
|
170
171
|
description:
|
|
171
172
|
"Install dependencies automatically for some projects. Defaults to true but disabled for containers and oci scans. Use --no-install-deps to disable this feature.",
|
|
172
173
|
})
|
|
@@ -506,7 +507,6 @@ const applyAdvancedOptions = (options) => {
|
|
|
506
507
|
options.installDeps = true;
|
|
507
508
|
break;
|
|
508
509
|
default:
|
|
509
|
-
options.installDeps = true;
|
|
510
510
|
break;
|
|
511
511
|
}
|
|
512
512
|
// When the user specifies source-code-analysis as a technique, then enable deep and evidence mode.
|
package/lib/cli/index.js
CHANGED
|
@@ -135,6 +135,7 @@ import {
|
|
|
135
135
|
parsePkgJson,
|
|
136
136
|
parsePkgLock,
|
|
137
137
|
parsePnpmLock,
|
|
138
|
+
parsePnpmWorkspace,
|
|
138
139
|
parsePom,
|
|
139
140
|
parsePrivadoFile,
|
|
140
141
|
parsePubLockData,
|
|
@@ -2310,6 +2311,11 @@ export async function createNodejsBom(path, options) {
|
|
|
2310
2311
|
`${options.multiProject ? "**/" : ""}pnpm-lock.yaml`,
|
|
2311
2312
|
options,
|
|
2312
2313
|
);
|
|
2314
|
+
const pnpmWorkspaceFiles = getAllFiles(
|
|
2315
|
+
path,
|
|
2316
|
+
`${options.multiProject ? "**/" : ""}pnpm-workspace.yaml`,
|
|
2317
|
+
options,
|
|
2318
|
+
);
|
|
2313
2319
|
const minJsFiles = getAllFiles(
|
|
2314
2320
|
path,
|
|
2315
2321
|
`${options.multiProject ? "**/" : ""}*min.js`,
|
|
@@ -2479,6 +2485,67 @@ export async function createNodejsBom(path, options) {
|
|
|
2479
2485
|
isPackageManagerAllowed("pnpm", ["npm", "yarn", "rush"], options)
|
|
2480
2486
|
) {
|
|
2481
2487
|
manifestFiles = manifestFiles.concat(pnpmLockFiles);
|
|
2488
|
+
const workspacePackages = [];
|
|
2489
|
+
const workspaceSrcFiles = {};
|
|
2490
|
+
const workspaceDirectDeps = {};
|
|
2491
|
+
const depsWorkspaceRefs = {};
|
|
2492
|
+
let workspaceCatalogs = {};
|
|
2493
|
+
let workspaceWarningShown = false;
|
|
2494
|
+
// Is this a pnpm workspace?
|
|
2495
|
+
for (const f of pnpmWorkspaceFiles) {
|
|
2496
|
+
if (DEBUG_MODE) {
|
|
2497
|
+
console.log(`Parsing workspace definition ${f}`);
|
|
2498
|
+
}
|
|
2499
|
+
const workspaceObj = parsePnpmWorkspace(f);
|
|
2500
|
+
if (workspaceObj?.packages) {
|
|
2501
|
+
// We need the precise purl for all workspace packages and their direct dependencies
|
|
2502
|
+
for (const awp of workspaceObj.packages) {
|
|
2503
|
+
const wpkgJsonFiles = getAllFiles(awp, "**/package.json", options);
|
|
2504
|
+
if (!wpkgJsonFiles?.length) {
|
|
2505
|
+
if (!workspaceWarningShown) {
|
|
2506
|
+
workspaceWarningShown = true;
|
|
2507
|
+
console.log(
|
|
2508
|
+
`Unable to find any package.json files belonging to the workspace '${awp}' referred in ${f}. To improve SBOM precision, run cdxgen from the directory containing the complete source code.`,
|
|
2509
|
+
);
|
|
2510
|
+
}
|
|
2511
|
+
continue;
|
|
2512
|
+
}
|
|
2513
|
+
for (const apj of wpkgJsonFiles) {
|
|
2514
|
+
const pkgData = JSON.parse(readFileSync(apj, "utf-8"));
|
|
2515
|
+
if (pkgData?.name) {
|
|
2516
|
+
let workspaceRef = `pkg:npm/${pkgData.name}`;
|
|
2517
|
+
if (pkgData?.version) {
|
|
2518
|
+
workspaceRef = `${workspaceRef}@${pkgData.version}`;
|
|
2519
|
+
}
|
|
2520
|
+
// Track all workspace purls
|
|
2521
|
+
workspacePackages.push(workspaceRef);
|
|
2522
|
+
workspaceSrcFiles[workspaceRef] = apj;
|
|
2523
|
+
// Track the direct dependencies of each workspace and workspace refs for each direct deps.
|
|
2524
|
+
const allDeps = {
|
|
2525
|
+
...(pkgData.dependencies || {}),
|
|
2526
|
+
...(pkgData.devDependencies || {}),
|
|
2527
|
+
...(pkgData.peerDependencies || {}),
|
|
2528
|
+
};
|
|
2529
|
+
for (const adep of Object.keys(allDeps)) {
|
|
2530
|
+
if (!workspaceDirectDeps[workspaceRef]) {
|
|
2531
|
+
workspaceDirectDeps[workspaceRef] = new Set();
|
|
2532
|
+
}
|
|
2533
|
+
const apkgRef = `pkg:npm/${adep}`;
|
|
2534
|
+
workspaceDirectDeps[workspaceRef].add(apkgRef);
|
|
2535
|
+
if (!depsWorkspaceRefs[apkgRef]) {
|
|
2536
|
+
depsWorkspaceRefs[apkgRef] = [];
|
|
2537
|
+
}
|
|
2538
|
+
depsWorkspaceRefs[apkgRef].push(workspaceRef);
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
workspaceCatalogs = {
|
|
2545
|
+
...workspaceCatalogs,
|
|
2546
|
+
...(workspaceObj.catalogs || {}),
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2482
2549
|
for (const f of pnpmLockFiles) {
|
|
2483
2550
|
if (DEBUG_MODE) {
|
|
2484
2551
|
console.log(`Parsing ${f}`);
|
|
@@ -2527,7 +2594,15 @@ export async function createNodejsBom(path, options) {
|
|
|
2527
2594
|
}
|
|
2528
2595
|
}
|
|
2529
2596
|
// Parse the pnpm file
|
|
2530
|
-
const parsedList = await parsePnpmLock(
|
|
2597
|
+
const parsedList = await parsePnpmLock(
|
|
2598
|
+
f,
|
|
2599
|
+
parentComponent,
|
|
2600
|
+
workspacePackages,
|
|
2601
|
+
workspaceSrcFiles,
|
|
2602
|
+
workspaceCatalogs,
|
|
2603
|
+
workspaceDirectDeps,
|
|
2604
|
+
depsWorkspaceRefs,
|
|
2605
|
+
);
|
|
2531
2606
|
const dlist = parsedList.pkgList;
|
|
2532
2607
|
if (dlist?.length) {
|
|
2533
2608
|
pkgList = pkgList.concat(dlist);
|
|
@@ -5911,7 +5986,11 @@ export function trimComponents(components) {
|
|
|
5911
5986
|
const keyCache = {};
|
|
5912
5987
|
const filteredComponents = [];
|
|
5913
5988
|
for (const comp of components) {
|
|
5914
|
-
const key =
|
|
5989
|
+
const key = (
|
|
5990
|
+
comp.purl ||
|
|
5991
|
+
comp["bom-ref"] ||
|
|
5992
|
+
comp.name + comp.version
|
|
5993
|
+
).toLowerCase();
|
|
5915
5994
|
if (!keyCache[key]) {
|
|
5916
5995
|
keyCache[key] = comp;
|
|
5917
5996
|
} else {
|
package/lib/evinser/evinser.js
CHANGED
|
@@ -1017,10 +1017,7 @@ export function isFilterableType(language, userDefinedTypesMap, typeFullName) {
|
|
|
1017
1017
|
return true;
|
|
1018
1018
|
}
|
|
1019
1019
|
}
|
|
1020
|
-
|
|
1021
|
-
return true;
|
|
1022
|
-
}
|
|
1023
|
-
return false;
|
|
1020
|
+
return !!userDefinedTypesMap[typeFullName];
|
|
1024
1021
|
}
|
|
1025
1022
|
|
|
1026
1023
|
/**
|
package/lib/helpers/utils.js
CHANGED
|
@@ -23,6 +23,7 @@ import path, {
|
|
|
23
23
|
extname,
|
|
24
24
|
join,
|
|
25
25
|
resolve,
|
|
26
|
+
relative,
|
|
26
27
|
sep as _sep,
|
|
27
28
|
} from "node:path";
|
|
28
29
|
import process from "node:process";
|
|
@@ -975,12 +976,12 @@ export async function parsePkgJson(pkgJsonFile, simple = false) {
|
|
|
975
976
|
try {
|
|
976
977
|
const pkgData = JSON.parse(readFileSync(pkgJsonFile, "utf8"));
|
|
977
978
|
const pkgIdentifier = parsePackageJsonName(pkgData.name);
|
|
978
|
-
|
|
979
|
+
let name = pkgIdentifier.fullName || pkgData.name;
|
|
979
980
|
if (DEBUG_MODE && !name && !pkgJsonFile.includes("node_modules")) {
|
|
981
|
+
name = dirname(pkgJsonFile);
|
|
980
982
|
console.log(
|
|
981
|
-
`${pkgJsonFile} doesn't contain the package name. Consider using the 'npm init' command to create a valid package.json file for this project.`,
|
|
983
|
+
`${pkgJsonFile} doesn't contain the package name. Consider using the 'npm init' command to create a valid package.json file for this project. Assuming the name as '${name}'.`,
|
|
982
984
|
);
|
|
983
|
-
return pkgList;
|
|
984
985
|
}
|
|
985
986
|
const group = pkgIdentifier.scope || "";
|
|
986
987
|
const purl = new PackageURL(
|
|
@@ -1967,6 +1968,59 @@ function _markTreeOptional(
|
|
|
1967
1968
|
}
|
|
1968
1969
|
}
|
|
1969
1970
|
|
|
1971
|
+
function _setTreeWorkspaceRef(
|
|
1972
|
+
dependenciesMap,
|
|
1973
|
+
depref,
|
|
1974
|
+
pkgRefMap,
|
|
1975
|
+
wref,
|
|
1976
|
+
wsrcFile,
|
|
1977
|
+
depsWorkspaceRefs,
|
|
1978
|
+
) {
|
|
1979
|
+
for (const dref of dependenciesMap[depref] || []) {
|
|
1980
|
+
const addedMap = {};
|
|
1981
|
+
const depPkg = pkgRefMap[dref];
|
|
1982
|
+
if (!depPkg) {
|
|
1983
|
+
continue;
|
|
1984
|
+
}
|
|
1985
|
+
const wsprops = depPkg.properties.filter(
|
|
1986
|
+
(p) => p.name === "internal:workspaceRef",
|
|
1987
|
+
);
|
|
1988
|
+
if (wsprops.length) {
|
|
1989
|
+
continue;
|
|
1990
|
+
}
|
|
1991
|
+
depPkg.properties = depPkg.properties || [];
|
|
1992
|
+
for (const prop of depPkg.properties) {
|
|
1993
|
+
addedMap[prop.value] = true;
|
|
1994
|
+
}
|
|
1995
|
+
if (!addedMap[wref]) {
|
|
1996
|
+
depPkg.properties.push({
|
|
1997
|
+
name: "internal:workspaceRef",
|
|
1998
|
+
value: wref,
|
|
1999
|
+
});
|
|
2000
|
+
addedMap[wref] = true;
|
|
2001
|
+
}
|
|
2002
|
+
if (wsrcFile && !addedMap[wsrcFile]) {
|
|
2003
|
+
depPkg.properties.push({
|
|
2004
|
+
name: "internal:workspaceSrcFile",
|
|
2005
|
+
value: wsrcFile,
|
|
2006
|
+
});
|
|
2007
|
+
addedMap[wsrcFile] = true;
|
|
2008
|
+
}
|
|
2009
|
+
depsWorkspaceRefs[dref] = depsWorkspaceRefs[dref] || [];
|
|
2010
|
+
depsWorkspaceRefs[dref] = depsWorkspaceRefs[dref].concat(
|
|
2011
|
+
dependenciesMap[depref] || [],
|
|
2012
|
+
);
|
|
2013
|
+
_setTreeWorkspaceRef(
|
|
2014
|
+
dependenciesMap,
|
|
2015
|
+
dref,
|
|
2016
|
+
pkgRefMap,
|
|
2017
|
+
wref,
|
|
2018
|
+
wsrcFile,
|
|
2019
|
+
depsWorkspaceRefs,
|
|
2020
|
+
);
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
|
|
1970
2024
|
async function getVersionNumPnpm(depPkg, relativePath) {
|
|
1971
2025
|
let version = depPkg;
|
|
1972
2026
|
if (typeof version === "object" && depPkg.version) {
|
|
@@ -2003,13 +2057,48 @@ async function getVersionNumPnpm(depPkg, relativePath) {
|
|
|
2003
2057
|
return version;
|
|
2004
2058
|
}
|
|
2005
2059
|
|
|
2060
|
+
/**
|
|
2061
|
+
* Parse pnpm workspace file
|
|
2062
|
+
*
|
|
2063
|
+
* @param {string} workspaceFile pnpm-workspace.yaml
|
|
2064
|
+
* @returns {object} Object containing packages and catalogs
|
|
2065
|
+
*/
|
|
2066
|
+
export function parsePnpmWorkspace(workspaceFile) {
|
|
2067
|
+
const workspaceData = readFileSync(workspaceFile, "utf-8");
|
|
2068
|
+
const yamlObj = _load(workspaceData);
|
|
2069
|
+
if (!yamlObj) {
|
|
2070
|
+
return {};
|
|
2071
|
+
}
|
|
2072
|
+
const packages = (yamlObj.packages || [])
|
|
2073
|
+
.filter((n) => !/^(!|\.|__)/.test(n))
|
|
2074
|
+
.map((n) => n.replaceAll("/**", "").replaceAll("/*", ""));
|
|
2075
|
+
const catalogs = yamlObj.catalog || {};
|
|
2076
|
+
return {
|
|
2077
|
+
packages,
|
|
2078
|
+
catalogs,
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2006
2082
|
/**
|
|
2007
2083
|
* Parse nodejs pnpm lock file
|
|
2008
2084
|
*
|
|
2009
2085
|
* @param {string} pnpmLock pnpm-lock.yaml file
|
|
2010
|
-
* @param {
|
|
2086
|
+
* @param {Object} parentComponent parent component
|
|
2087
|
+
* @param {Array[String]} workspacePackages Workspace packages
|
|
2088
|
+
* @param {Object} workspaceSrcFiles Workspace package.json files
|
|
2089
|
+
* @param {Object} workspaceCatalogs Workspace catalogs
|
|
2090
|
+
* @param {Object} workspaceDirectDeps Direct dependencies of each workspace
|
|
2091
|
+
* @param {Object} depsWorkspaceRefs Workspace references for each dependency
|
|
2011
2092
|
*/
|
|
2012
|
-
export async function parsePnpmLock(
|
|
2093
|
+
export async function parsePnpmLock(
|
|
2094
|
+
pnpmLock,
|
|
2095
|
+
parentComponent = null,
|
|
2096
|
+
workspacePackages = [],
|
|
2097
|
+
workspaceSrcFiles = {},
|
|
2098
|
+
_workspaceCatalogs = {},
|
|
2099
|
+
_workspaceDirectDeps = {},
|
|
2100
|
+
depsWorkspaceRefs = {},
|
|
2101
|
+
) {
|
|
2013
2102
|
let pkgList = [];
|
|
2014
2103
|
const dependenciesList = [];
|
|
2015
2104
|
// For lockfile >= 9, we need to track dev and optional packages manually
|
|
@@ -2022,6 +2111,16 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2022
2111
|
let lockfileVersion = 0;
|
|
2023
2112
|
const parentSubComponents = [];
|
|
2024
2113
|
const srcFilesMap = {};
|
|
2114
|
+
const workspacePackageNames = {};
|
|
2115
|
+
const pkgRefMap = {};
|
|
2116
|
+
// Track references to packages that are directly installed from github.com
|
|
2117
|
+
const gitPkgRefs = {};
|
|
2118
|
+
// pnpm could refer to packages from git sources
|
|
2119
|
+
const githubServerHost = process.env.CDXGEN_GIT_HOST || "github.com";
|
|
2120
|
+
// Convert workspace package names to an object to help with the lookup
|
|
2121
|
+
for (const w of workspacePackages || []) {
|
|
2122
|
+
workspacePackageNames[w] = true;
|
|
2123
|
+
}
|
|
2025
2124
|
if (parentComponent?.name) {
|
|
2026
2125
|
ppurl =
|
|
2027
2126
|
parentComponent.purl ||
|
|
@@ -2061,6 +2160,10 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2061
2160
|
lockfileVersion >= 6
|
|
2062
2161
|
? yamlObj.importers["."]?.optionalDependencies || {}
|
|
2063
2162
|
: {};
|
|
2163
|
+
const rootPeerDeps =
|
|
2164
|
+
lockfileVersion >= 6
|
|
2165
|
+
? yamlObj.importers["."]?.peerDependencies || {}
|
|
2166
|
+
: {};
|
|
2064
2167
|
const ddeplist = new Set();
|
|
2065
2168
|
// Find the root optional dependencies
|
|
2066
2169
|
for (const rdk of Object.keys(rootDevDeps)) {
|
|
@@ -2075,7 +2178,7 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2075
2178
|
).toString();
|
|
2076
2179
|
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
|
|
2077
2180
|
}
|
|
2078
|
-
for (const rdk of Object.keys(rootOptionalDeps)) {
|
|
2181
|
+
for (const rdk of Object.keys({ ...rootOptionalDeps, ...rootPeerDeps })) {
|
|
2079
2182
|
const version = await getVersionNumPnpm(rootOptionalDeps[rdk]);
|
|
2080
2183
|
const dpurl = new PackageURL(
|
|
2081
2184
|
"npm",
|
|
@@ -2117,6 +2220,8 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2117
2220
|
const componentOptionalDeps =
|
|
2118
2221
|
yamlObj?.importers[importedComponentName]["optionalDependencies"] ||
|
|
2119
2222
|
{};
|
|
2223
|
+
const componentPeerDeps =
|
|
2224
|
+
yamlObj?.importers[importedComponentName]["peerDependencies"] || {};
|
|
2120
2225
|
let compPurl = undefined;
|
|
2121
2226
|
let pkgSrcFile = undefined;
|
|
2122
2227
|
let fallbackMode = true;
|
|
@@ -2136,14 +2241,39 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2136
2241
|
const compRef = decodeURIComponent(compPurl);
|
|
2137
2242
|
// Add this package to the root dependency list and parent component
|
|
2138
2243
|
ddeplist.add(compRef);
|
|
2139
|
-
|
|
2244
|
+
const psObj = {
|
|
2140
2245
|
group: importedComponentObj[0]?.group,
|
|
2141
2246
|
name: importedComponentObj[0]?.name,
|
|
2142
2247
|
version,
|
|
2143
2248
|
type: "application",
|
|
2144
2249
|
purl: compPurl,
|
|
2145
2250
|
"bom-ref": compRef,
|
|
2146
|
-
}
|
|
2251
|
+
};
|
|
2252
|
+
const purlNoVersion = new PackageURL(
|
|
2253
|
+
"npm",
|
|
2254
|
+
importedComponentObj[0]?.group,
|
|
2255
|
+
importedComponentObj[0]?.name,
|
|
2256
|
+
version,
|
|
2257
|
+
).toString();
|
|
2258
|
+
const matchRef =
|
|
2259
|
+
workspacePackageNames[decodeURIComponent(purlNoVersion)] ||
|
|
2260
|
+
workspacePackageNames[compRef];
|
|
2261
|
+
const matchSrcFile =
|
|
2262
|
+
workspaceSrcFiles[decodeURIComponent(purlNoVersion)] ||
|
|
2263
|
+
workspaceSrcFiles[compRef];
|
|
2264
|
+
if (matchRef || matchSrcFile) {
|
|
2265
|
+
psObj.properties = [
|
|
2266
|
+
{ name: "internal:is_workspace", value: "true" },
|
|
2267
|
+
];
|
|
2268
|
+
}
|
|
2269
|
+
if (matchSrcFile) {
|
|
2270
|
+
psObj.properties.push({ name: "SrcFile", value: matchSrcFile });
|
|
2271
|
+
psObj.properties.push({
|
|
2272
|
+
name: "internal:virtual_path",
|
|
2273
|
+
value: relative(dirname(pnpmLock), dirname(matchSrcFile)),
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
parentSubComponents.push(psObj);
|
|
2147
2277
|
fallbackMode = false;
|
|
2148
2278
|
}
|
|
2149
2279
|
}
|
|
@@ -2167,20 +2297,37 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2167
2297
|
// Find the component optional dependencies
|
|
2168
2298
|
const comDepList = new Set();
|
|
2169
2299
|
for (const cdk of Object.keys(componentDeps)) {
|
|
2300
|
+
let name = cdk;
|
|
2301
|
+
let group = "";
|
|
2302
|
+
let version;
|
|
2170
2303
|
const versionObj = componentDeps[cdk];
|
|
2171
|
-
|
|
2172
|
-
versionObj
|
|
2173
|
-
|
|
2174
|
-
|
|
2304
|
+
if (versionObj?.version?.startsWith(githubServerHost)) {
|
|
2305
|
+
const parts = versionObj.version.split("/");
|
|
2306
|
+
version = parts.pop();
|
|
2307
|
+
name = parts.pop();
|
|
2308
|
+
group = parts.pop();
|
|
2309
|
+
if (group === githubServerHost) {
|
|
2310
|
+
group = "";
|
|
2311
|
+
} else {
|
|
2312
|
+
group = `@${group}`;
|
|
2313
|
+
}
|
|
2314
|
+
gitPkgRefs[versionObj.version] = { group, name, version };
|
|
2315
|
+
} else {
|
|
2316
|
+
version = await getVersionNumPnpm(
|
|
2317
|
+
versionObj,
|
|
2318
|
+
importedComponentName,
|
|
2319
|
+
);
|
|
2320
|
+
}
|
|
2175
2321
|
const dpurl = new PackageURL(
|
|
2176
2322
|
"npm",
|
|
2177
|
-
|
|
2178
|
-
|
|
2323
|
+
group,
|
|
2324
|
+
name,
|
|
2179
2325
|
version,
|
|
2180
2326
|
null,
|
|
2181
2327
|
null,
|
|
2182
2328
|
).toString();
|
|
2183
2329
|
const depRef = decodeURIComponent(dpurl);
|
|
2330
|
+
// This is a definite dependency of this component
|
|
2184
2331
|
comDepList.add(depRef);
|
|
2185
2332
|
possibleOptionalDeps[depRef] = false;
|
|
2186
2333
|
// Track the package.json files
|
|
@@ -2191,10 +2338,6 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2191
2338
|
srcFilesMap[depRef].push(pkgSrcFile);
|
|
2192
2339
|
}
|
|
2193
2340
|
}
|
|
2194
|
-
dependenciesList.push({
|
|
2195
|
-
ref: decodeURIComponent(compPurl),
|
|
2196
|
-
dependsOn: [...comDepList].sort(),
|
|
2197
|
-
});
|
|
2198
2341
|
for (const cdk of Object.keys(componentDevDeps)) {
|
|
2199
2342
|
const version = await getVersionNumPnpm(componentDevDeps[cdk]);
|
|
2200
2343
|
const dpurl = new PackageURL(
|
|
@@ -2205,9 +2348,15 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2205
2348
|
null,
|
|
2206
2349
|
null,
|
|
2207
2350
|
).toString();
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2351
|
+
const devDpRef = decodeURIComponent(dpurl);
|
|
2352
|
+
possibleOptionalDeps[devDpRef] = true;
|
|
2353
|
+
// This is also a dependency of this component
|
|
2354
|
+
comDepList.add(devDpRef);
|
|
2355
|
+
}
|
|
2356
|
+
for (const cdk of Object.keys({
|
|
2357
|
+
...componentOptionalDeps,
|
|
2358
|
+
...componentPeerDeps,
|
|
2359
|
+
})) {
|
|
2211
2360
|
const version = await getVersionNumPnpm(componentOptionalDeps[cdk]);
|
|
2212
2361
|
const dpurl = new PackageURL(
|
|
2213
2362
|
"npm",
|
|
@@ -2219,6 +2368,10 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2219
2368
|
).toString();
|
|
2220
2369
|
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
|
|
2221
2370
|
}
|
|
2371
|
+
dependenciesList.push({
|
|
2372
|
+
ref: decodeURIComponent(compPurl),
|
|
2373
|
+
dependsOn: [...comDepList].sort(),
|
|
2374
|
+
});
|
|
2222
2375
|
}
|
|
2223
2376
|
dependenciesList.push({
|
|
2224
2377
|
ref: decodeURIComponent(ppurl),
|
|
@@ -2356,12 +2509,28 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2356
2509
|
}
|
|
2357
2510
|
// Let's have some warnings till we fully support pnpm 8
|
|
2358
2511
|
if (!name) {
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
fullName
|
|
2363
|
-
)
|
|
2364
|
-
|
|
2512
|
+
if (gitPkgRefs[fullName]) {
|
|
2513
|
+
name = gitPkgRefs[fullName].name;
|
|
2514
|
+
group = gitPkgRefs[fullName].group;
|
|
2515
|
+
version = gitPkgRefs[fullName].version;
|
|
2516
|
+
} else if (parts?.length >= 3 && parts[0] === githubServerHost) {
|
|
2517
|
+
version = parts[parts.length - 1];
|
|
2518
|
+
name = parts[parts.length - 2];
|
|
2519
|
+
group = parts.length === 4 ? `@${parts[parts.length - 3]}` : "";
|
|
2520
|
+
gitPkgRefs[fullName] = {
|
|
2521
|
+
group,
|
|
2522
|
+
name,
|
|
2523
|
+
version,
|
|
2524
|
+
purl: new PackageURL("npm", group, name, version).toString(),
|
|
2525
|
+
};
|
|
2526
|
+
} else {
|
|
2527
|
+
console.warn(
|
|
2528
|
+
`Unable to extract name and version for string ${pkgKeys[k]}`,
|
|
2529
|
+
parts,
|
|
2530
|
+
fullName,
|
|
2531
|
+
);
|
|
2532
|
+
continue;
|
|
2533
|
+
}
|
|
2365
2534
|
}
|
|
2366
2535
|
if (name.indexOf("file:") !== 0) {
|
|
2367
2536
|
const purlString = new PackageURL(
|
|
@@ -2384,7 +2553,7 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2384
2553
|
if (dpkgName.endsWith("-cjs")) {
|
|
2385
2554
|
const tmpB = vers.split("@");
|
|
2386
2555
|
if (tmpB.length > 1) {
|
|
2387
|
-
dpkgName = tmpB[0];
|
|
2556
|
+
dpkgName = tmpB[0].replace(/^\//, "");
|
|
2388
2557
|
vers = tmpB[1];
|
|
2389
2558
|
}
|
|
2390
2559
|
}
|
|
@@ -2394,7 +2563,9 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2394
2563
|
// With overrides version could be like this: @nolyfill/side-channel@1.0.29
|
|
2395
2564
|
if (vers.includes("@")) {
|
|
2396
2565
|
const overrideVersion = vers.split("@").pop();
|
|
2397
|
-
dpkgName = vers
|
|
2566
|
+
dpkgName = vers
|
|
2567
|
+
.replace(`@${overrideVersion}`, "")
|
|
2568
|
+
.replace(/^\//, "");
|
|
2398
2569
|
vers = overrideVersion;
|
|
2399
2570
|
}
|
|
2400
2571
|
const dpurlString = new PackageURL(
|
|
@@ -2423,6 +2594,7 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2423
2594
|
if (!dependenciesMap[bomRef]) {
|
|
2424
2595
|
dependenciesMap[bomRef] = [];
|
|
2425
2596
|
}
|
|
2597
|
+
|
|
2426
2598
|
dependenciesMap[bomRef] = dependenciesMap[bomRef].concat(deplist);
|
|
2427
2599
|
const properties = [
|
|
2428
2600
|
{
|
|
@@ -2450,12 +2622,75 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2450
2622
|
});
|
|
2451
2623
|
}
|
|
2452
2624
|
}
|
|
2453
|
-
|
|
2625
|
+
const purlNoVersion = new PackageURL("npm", group, name).toString();
|
|
2626
|
+
let packageType = "library";
|
|
2627
|
+
const theBomRef = decodeURIComponent(purlString);
|
|
2628
|
+
if (
|
|
2629
|
+
workspacePackageNames[decodeURIComponent(purlNoVersion)] ||
|
|
2630
|
+
workspacePackageNames[theBomRef]
|
|
2631
|
+
) {
|
|
2632
|
+
properties.push({
|
|
2633
|
+
name: "internal:is_workspace",
|
|
2634
|
+
value: "true",
|
|
2635
|
+
});
|
|
2636
|
+
packageType = "application";
|
|
2637
|
+
const wsSrcFile =
|
|
2638
|
+
workspaceSrcFiles[decodeURIComponent(purlNoVersion)] ||
|
|
2639
|
+
workspaceSrcFiles[theBomRef];
|
|
2640
|
+
if (wsSrcFile) {
|
|
2641
|
+
properties.push({
|
|
2642
|
+
name: "internal:virtual_path",
|
|
2643
|
+
value: relative(dirname(pnpmLock), dirname(wsSrcFile)),
|
|
2644
|
+
});
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
// Capture all the workspaces that directly depend on this package and their source file
|
|
2648
|
+
for (const wref of Array.from(
|
|
2649
|
+
depsWorkspaceRefs[purlNoVersion] ||
|
|
2650
|
+
depsWorkspaceRefs[purlString] ||
|
|
2651
|
+
[],
|
|
2652
|
+
)) {
|
|
2653
|
+
// This cycle shouldn't happen, but we can't be sure
|
|
2654
|
+
if (wref === purlString) {
|
|
2655
|
+
continue;
|
|
2656
|
+
}
|
|
2657
|
+
properties.push({
|
|
2658
|
+
name: "internal:workspaceRef",
|
|
2659
|
+
value: wref,
|
|
2660
|
+
});
|
|
2661
|
+
if (workspaceSrcFiles[wref]) {
|
|
2662
|
+
properties.push({
|
|
2663
|
+
name: "internal:workspaceSrcFile",
|
|
2664
|
+
value: workspaceSrcFiles[wref],
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2667
|
+
// Add workspaceRef to the dependent components as well
|
|
2668
|
+
for (const dref of dependenciesMap[theBomRef]) {
|
|
2669
|
+
if (!depsWorkspaceRefs[dref]) {
|
|
2670
|
+
depsWorkspaceRefs[dref] = [];
|
|
2671
|
+
}
|
|
2672
|
+
if (!depsWorkspaceRefs[dref].includes(wref)) {
|
|
2673
|
+
depsWorkspaceRefs[dref].push(wref);
|
|
2674
|
+
}
|
|
2675
|
+
if (dependenciesMap[dref]) {
|
|
2676
|
+
for (const l2ref of dependenciesMap[dref]) {
|
|
2677
|
+
if (!depsWorkspaceRefs[l2ref]) {
|
|
2678
|
+
depsWorkspaceRefs[l2ref] = [];
|
|
2679
|
+
}
|
|
2680
|
+
if (!depsWorkspaceRefs[l2ref].includes(wref)) {
|
|
2681
|
+
depsWorkspaceRefs[l2ref].push(wref);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
const thePkg = {
|
|
2454
2688
|
group: group,
|
|
2455
2689
|
name: name,
|
|
2456
2690
|
version: version,
|
|
2457
2691
|
purl: purlString,
|
|
2458
|
-
"bom-ref":
|
|
2692
|
+
"bom-ref": theBomRef,
|
|
2693
|
+
type: packageType,
|
|
2459
2694
|
scope,
|
|
2460
2695
|
_integrity: integrity,
|
|
2461
2696
|
properties,
|
|
@@ -2472,7 +2707,12 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2472
2707
|
],
|
|
2473
2708
|
},
|
|
2474
2709
|
},
|
|
2475
|
-
}
|
|
2710
|
+
};
|
|
2711
|
+
// Don't add internal workspace packages to the components list
|
|
2712
|
+
if (thePkg.type !== "application") {
|
|
2713
|
+
pkgList.push(thePkg);
|
|
2714
|
+
}
|
|
2715
|
+
pkgRefMap[thePkg["bom-ref"]] = thePkg;
|
|
2476
2716
|
}
|
|
2477
2717
|
}
|
|
2478
2718
|
}
|
|
@@ -2524,6 +2764,55 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
2524
2764
|
if (requiredDependencies[apkg["bom-ref"]]) {
|
|
2525
2765
|
apkg.scope = undefined;
|
|
2526
2766
|
}
|
|
2767
|
+
// There are no workspaces so exit early
|
|
2768
|
+
if (!Object.keys(workspacePackageNames).length) {
|
|
2769
|
+
continue;
|
|
2770
|
+
}
|
|
2771
|
+
const purlNoVersion = decodeURIComponent(
|
|
2772
|
+
new PackageURL("npm", apkg.group, apkg.name).toString(),
|
|
2773
|
+
);
|
|
2774
|
+
const wsRefs =
|
|
2775
|
+
depsWorkspaceRefs[apkg["bom-ref"]] || depsWorkspaceRefs[purlNoVersion];
|
|
2776
|
+
// There is a workspace reference
|
|
2777
|
+
if (wsRefs?.length) {
|
|
2778
|
+
const wsprops = apkg.properties.filter(
|
|
2779
|
+
(p) => p.name === "internal:workspaceRef",
|
|
2780
|
+
);
|
|
2781
|
+
// workspace properties are already set.
|
|
2782
|
+
if (wsprops.length) {
|
|
2783
|
+
continue;
|
|
2784
|
+
}
|
|
2785
|
+
for (const wref of wsRefs) {
|
|
2786
|
+
// Such a cycle should never happen, but we can't sure
|
|
2787
|
+
if (wref === apkg["bom-ref"]) {
|
|
2788
|
+
continue;
|
|
2789
|
+
}
|
|
2790
|
+
apkg.properties.push({
|
|
2791
|
+
name: "internal:workspaceRef",
|
|
2792
|
+
value: wref,
|
|
2793
|
+
});
|
|
2794
|
+
const purlObj = PackageURL.fromString(apkg.purl);
|
|
2795
|
+
purlObj.version = undefined;
|
|
2796
|
+
const wrefNoVersion = decodeURIComponent(purlObj.toString());
|
|
2797
|
+
const wsrcFile =
|
|
2798
|
+
workspaceSrcFiles[wref] || workspaceSrcFiles[wrefNoVersion];
|
|
2799
|
+
if (wsrcFile) {
|
|
2800
|
+
apkg.properties.push({
|
|
2801
|
+
name: "internal:workspaceSrcFile",
|
|
2802
|
+
value: wsrcFile,
|
|
2803
|
+
});
|
|
2804
|
+
}
|
|
2805
|
+
// Repeat for the children
|
|
2806
|
+
_setTreeWorkspaceRef(
|
|
2807
|
+
dependenciesMap,
|
|
2808
|
+
apkg["bom-ref"],
|
|
2809
|
+
pkgRefMap,
|
|
2810
|
+
wref,
|
|
2811
|
+
wsrcFile,
|
|
2812
|
+
depsWorkspaceRefs,
|
|
2813
|
+
);
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2527
2816
|
}
|
|
2528
2817
|
|
|
2529
2818
|
if (Object.keys(dependenciesMap).length) {
|
|
@@ -4449,6 +4738,7 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
|
|
|
4449
4738
|
const dependenciesList = [];
|
|
4450
4739
|
const depsMap = {};
|
|
4451
4740
|
const existingPkgMap = {};
|
|
4741
|
+
const pkgBomRefMap = {};
|
|
4452
4742
|
let directDepsKeys = {};
|
|
4453
4743
|
let groupDepsKeys = {};
|
|
4454
4744
|
let parentComponent;
|
|
@@ -4503,6 +4793,20 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
|
|
|
4503
4793
|
// Nested workspace is not supported
|
|
4504
4794
|
const wcompMap = parsePyProjectTomlFile(awpyproj);
|
|
4505
4795
|
if (wcompMap?.parentComponent) {
|
|
4796
|
+
wcompMap.parentComponent.properties =
|
|
4797
|
+
wcompMap.parentComponent.properties || [];
|
|
4798
|
+
wcompMap.parentComponent.properties.push({
|
|
4799
|
+
name: "internal:is_workspace",
|
|
4800
|
+
value: "true",
|
|
4801
|
+
});
|
|
4802
|
+
wcompMap.parentComponent.properties.push({
|
|
4803
|
+
name: "SrcFile",
|
|
4804
|
+
value: awpyproj,
|
|
4805
|
+
});
|
|
4806
|
+
wcompMap.parentComponent.properties.push({
|
|
4807
|
+
name: "internal:virtual_path",
|
|
4808
|
+
value: relative(dirname(lockFile), dirname(awpyproj)),
|
|
4809
|
+
});
|
|
4506
4810
|
workspaceComponentMap[wcompMap.parentComponent.name] =
|
|
4507
4811
|
wcompMap.parentComponent;
|
|
4508
4812
|
workspacePyProjMap[wcompMap.parentComponent.name] = awpyproj;
|
|
@@ -4703,7 +5007,12 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
|
|
|
4703
5007
|
}
|
|
4704
5008
|
// This would help the lookup
|
|
4705
5009
|
existingPkgMap[pkg.name.toLowerCase()] = pkg["bom-ref"];
|
|
4706
|
-
|
|
5010
|
+
pkgBomRefMap[pkg["bom-ref"]] = pkg;
|
|
5011
|
+
// Do not repeat workspace components again under components
|
|
5012
|
+
// This will reduce false positives, when a downstream tool attempts to analyze all components
|
|
5013
|
+
if (pkg.type !== "application") {
|
|
5014
|
+
pkgList.push(pkg);
|
|
5015
|
+
}
|
|
4707
5016
|
if (!depsMap[pkg["bom-ref"]]) {
|
|
4708
5017
|
depsMap[pkg["bom-ref"]] = new Set();
|
|
4709
5018
|
}
|
|
@@ -4716,34 +5025,138 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
|
|
|
4716
5025
|
depsMap[pkgParentRef].add(pkg["bom-ref"]);
|
|
4717
5026
|
}
|
|
4718
5027
|
}
|
|
4719
|
-
|
|
5028
|
+
let optionalDependencies = [];
|
|
5029
|
+
let devDependencies = [];
|
|
5030
|
+
if (apkg["dev-dependencies"]) {
|
|
5031
|
+
for (const agroup of Object.keys(apkg["dev-dependencies"])) {
|
|
5032
|
+
devDependencies = devDependencies.concat(
|
|
5033
|
+
apkg["dev-dependencies"][agroup],
|
|
5034
|
+
);
|
|
5035
|
+
}
|
|
5036
|
+
}
|
|
5037
|
+
if (apkg["optional-dependencies"]) {
|
|
5038
|
+
for (const agroup of Object.keys(apkg["optional-dependencies"])) {
|
|
5039
|
+
optionalDependencies = optionalDependencies.concat(
|
|
5040
|
+
apkg["optional-dependencies"][agroup],
|
|
5041
|
+
);
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
5044
|
+
if (
|
|
5045
|
+
apkg.dependencies ||
|
|
5046
|
+
devDependencies.length ||
|
|
5047
|
+
optionalDependencies.length
|
|
5048
|
+
) {
|
|
4720
5049
|
if (Array.isArray(apkg.dependencies)) {
|
|
4721
5050
|
// pdm.lock files
|
|
4722
|
-
|
|
5051
|
+
let allDeps = apkg.dependencies;
|
|
5052
|
+
allDeps = allDeps.concat(devDependencies);
|
|
5053
|
+
allDeps = allDeps.concat(optionalDependencies);
|
|
5054
|
+
for (const apkgDep of allDeps) {
|
|
4723
5055
|
// Example: "msgpack>=0.5.2"
|
|
4724
5056
|
const nameStr =
|
|
4725
5057
|
apkgDep.name || apkgDep.split(/(==|<=|~=|>=)/)[0].split(" ")[0];
|
|
4726
5058
|
depsMap[pkg["bom-ref"]].add(existingPkgMap[nameStr] || nameStr);
|
|
5059
|
+
// Propagate the workspace properties to the child components
|
|
5060
|
+
if (
|
|
5061
|
+
existingPkgMap[nameStr] &&
|
|
5062
|
+
pkgBomRefMap[existingPkgMap[nameStr]]
|
|
5063
|
+
) {
|
|
5064
|
+
const dependentPkg = pkgBomRefMap[existingPkgMap[nameStr]];
|
|
5065
|
+
dependentPkg.properties = dependentPkg.properties || [];
|
|
5066
|
+
const addedValue = {};
|
|
5067
|
+
// Is the parent a workspace
|
|
5068
|
+
if (workspaceComponentMap[pkg.name]) {
|
|
5069
|
+
dependentPkg.properties.push({
|
|
5070
|
+
name: "internal:workspaceRef",
|
|
5071
|
+
value: pkg["bom-ref"],
|
|
5072
|
+
});
|
|
5073
|
+
dependentPkg.properties.push({
|
|
5074
|
+
name: "internal:workspaceSrcFile",
|
|
5075
|
+
value: workspaceRefPyProjMap[pkg["bom-ref"]],
|
|
5076
|
+
});
|
|
5077
|
+
addedValue[pkg["bom-ref"]] = true;
|
|
5078
|
+
}
|
|
5079
|
+
for (const pprop of pkg.properties) {
|
|
5080
|
+
if (
|
|
5081
|
+
pprop.name.startsWith("internal:workspace") &&
|
|
5082
|
+
!addedValue[pprop.value]
|
|
5083
|
+
) {
|
|
5084
|
+
dependentPkg.properties.push(pprop);
|
|
5085
|
+
addedValue[pprop.value] = true;
|
|
5086
|
+
}
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
4727
5089
|
}
|
|
4728
|
-
} else if (Object.keys(apkg.dependencies).length) {
|
|
5090
|
+
} else if (pkg.dependencies && Object.keys(apkg.dependencies).length) {
|
|
4729
5091
|
for (const apkgDep of Object.keys(apkg.dependencies)) {
|
|
4730
5092
|
depsMap[pkg["bom-ref"]].add(existingPkgMap[apkgDep] || apkgDep);
|
|
4731
5093
|
}
|
|
4732
5094
|
}
|
|
4733
5095
|
}
|
|
4734
5096
|
}
|
|
4735
|
-
pkgList = await getPyMetadata(pkgList, false);
|
|
4736
5097
|
for (const key of Object.keys(depsMap)) {
|
|
4737
5098
|
const dependsOnList = new Set();
|
|
5099
|
+
const parentPkg = pkgBomRefMap[key];
|
|
4738
5100
|
for (const adep of Array.from(depsMap[key])) {
|
|
5101
|
+
let depRef;
|
|
4739
5102
|
if (adep.startsWith("pkg:")) {
|
|
4740
|
-
|
|
5103
|
+
depRef = adep;
|
|
4741
5104
|
} else if (existingPkgMap[adep]) {
|
|
4742
|
-
|
|
5105
|
+
depRef = existingPkgMap[adep];
|
|
4743
5106
|
} else if (existingPkgMap[`py${adep}`]) {
|
|
4744
|
-
|
|
5107
|
+
depRef = existingPkgMap[`py${adep}`];
|
|
4745
5108
|
} else if (existingPkgMap[adep.replace(/-/g, "_")]) {
|
|
4746
|
-
|
|
5109
|
+
depRef = existingPkgMap[adep.replace(/-/g, "_")];
|
|
5110
|
+
}
|
|
5111
|
+
if (depRef) {
|
|
5112
|
+
dependsOnList.add(depRef);
|
|
5113
|
+
// We need to propagate the workspace properties from the parent
|
|
5114
|
+
const dependentPkg = pkgBomRefMap[depRef];
|
|
5115
|
+
dependentPkg.properties = dependentPkg.properties || [];
|
|
5116
|
+
const addedValue = {};
|
|
5117
|
+
for (const p of dependentPkg.properties) {
|
|
5118
|
+
if (p.name.startsWith("internal:workspace")) {
|
|
5119
|
+
addedValue[p.value] = true;
|
|
5120
|
+
}
|
|
5121
|
+
}
|
|
5122
|
+
for (const pprop of parentPkg.properties) {
|
|
5123
|
+
if (
|
|
5124
|
+
pprop.name.startsWith("internal:workspace") &&
|
|
5125
|
+
!addedValue[pprop.value]
|
|
5126
|
+
) {
|
|
5127
|
+
dependentPkg.properties.push(pprop);
|
|
5128
|
+
addedValue[pprop.value] = true;
|
|
5129
|
+
} else if (pprop.name === "internal:is_workspace") {
|
|
5130
|
+
dependentPkg.properties.push({
|
|
5131
|
+
name: "internal:workspaceRef",
|
|
5132
|
+
value: parentPkg["bom-ref"],
|
|
5133
|
+
});
|
|
5134
|
+
dependentPkg.properties.push({
|
|
5135
|
+
name: "internal:workspaceSrcFile",
|
|
5136
|
+
value: workspaceRefPyProjMap[parentPkg["bom-ref"]],
|
|
5137
|
+
});
|
|
5138
|
+
addedValue[parentPkg["bom-ref"]] = true;
|
|
5139
|
+
addedValue[workspaceRefPyProjMap[parentPkg["bom-ref"]]] = true;
|
|
5140
|
+
const childDeps = depsMap[dependentPkg["bom-ref"]];
|
|
5141
|
+
for (const childRef of childDeps) {
|
|
5142
|
+
if (!childRef.startsWith("pkg:")) {
|
|
5143
|
+
continue;
|
|
5144
|
+
}
|
|
5145
|
+
const childPkg = pkgBomRefMap[childRef];
|
|
5146
|
+
if (childPkg) {
|
|
5147
|
+
childPkg.properties = childPkg.properties || [];
|
|
5148
|
+
childPkg.properties.push({
|
|
5149
|
+
name: "internal:workspaceRef",
|
|
5150
|
+
value: parentPkg["bom-ref"],
|
|
5151
|
+
});
|
|
5152
|
+
childPkg.properties.push({
|
|
5153
|
+
name: "internal:workspaceSrcFile",
|
|
5154
|
+
value: workspaceRefPyProjMap[parentPkg["bom-ref"]],
|
|
5155
|
+
});
|
|
5156
|
+
}
|
|
5157
|
+
}
|
|
5158
|
+
}
|
|
5159
|
+
}
|
|
4747
5160
|
}
|
|
4748
5161
|
}
|
|
4749
5162
|
dependenciesList.push({
|
|
@@ -4751,6 +5164,7 @@ export async function parsePyLockData(lockData, lockFile, pyProjectFile) {
|
|
|
4751
5164
|
dependsOn: [...dependsOnList].sort(),
|
|
4752
5165
|
});
|
|
4753
5166
|
}
|
|
5167
|
+
pkgList = await getPyMetadata(pkgList, false);
|
|
4754
5168
|
return {
|
|
4755
5169
|
parentComponent,
|
|
4756
5170
|
pkgList,
|
|
@@ -9114,17 +9528,43 @@ export function parseCsProjAssetsData(csProjData, assetsJsonFile) {
|
|
|
9114
9528
|
continue;
|
|
9115
9529
|
}
|
|
9116
9530
|
const targetNameVersion = `${nameOperatorVersion.name}/${nameOperatorVersion.version}`;
|
|
9117
|
-
|
|
9118
|
-
//
|
|
9531
|
+
let nameToUse = nameOperatorVersion.name;
|
|
9532
|
+
// Due to the difference in casing, we might arrive this case where a simple lookup doesn't succeed.
|
|
9533
|
+
// Instead of skipping, let's work harder to find a match.
|
|
9119
9534
|
if (!csProjData.targets[frameworkTarget][targetNameVersion]) {
|
|
9120
|
-
|
|
9535
|
+
let matchFound = false;
|
|
9536
|
+
for (const fkeys of Object.keys(
|
|
9537
|
+
csProjData.targets[frameworkTarget],
|
|
9538
|
+
)) {
|
|
9539
|
+
const tmpParts = fkeys.split("/");
|
|
9540
|
+
const tname = tmpParts[0];
|
|
9541
|
+
const tversion = tmpParts[1];
|
|
9542
|
+
if (
|
|
9543
|
+
tname.toLowerCase() === nameOperatorVersion.name.toLowerCase() &&
|
|
9544
|
+
tversion === nameOperatorVersion.version
|
|
9545
|
+
) {
|
|
9546
|
+
nameToUse = tname;
|
|
9547
|
+
matchFound = true;
|
|
9548
|
+
break;
|
|
9549
|
+
}
|
|
9550
|
+
}
|
|
9551
|
+
if (!matchFound) {
|
|
9552
|
+
if (DEBUG_MODE) {
|
|
9553
|
+
console.log(
|
|
9554
|
+
"Unable to match",
|
|
9555
|
+
dependencyName,
|
|
9556
|
+
"with a target name. The dependency tree will be imprecise.",
|
|
9557
|
+
);
|
|
9558
|
+
}
|
|
9559
|
+
continue;
|
|
9560
|
+
}
|
|
9121
9561
|
}
|
|
9122
9562
|
|
|
9123
9563
|
const dpurl = decodeURIComponent(
|
|
9124
9564
|
new PackageURL(
|
|
9125
9565
|
"nuget",
|
|
9126
9566
|
"",
|
|
9127
|
-
|
|
9567
|
+
nameToUse,
|
|
9128
9568
|
nameOperatorVersion.version,
|
|
9129
9569
|
null,
|
|
9130
9570
|
null,
|
|
@@ -76,6 +76,7 @@ import {
|
|
|
76
76
|
parsePkgJson,
|
|
77
77
|
parsePkgLock,
|
|
78
78
|
parsePnpmLock,
|
|
79
|
+
parsePnpmWorkspace,
|
|
79
80
|
parsePom,
|
|
80
81
|
parsePrivadoFile,
|
|
81
82
|
parsePubLockData,
|
|
@@ -3479,6 +3480,12 @@ test("parseSetupPyFile", async () => {
|
|
|
3479
3480
|
]);
|
|
3480
3481
|
});
|
|
3481
3482
|
|
|
3483
|
+
test("parsePnpmWorkspace", async () => {
|
|
3484
|
+
const wobj = parsePnpmWorkspace("./test/data/pnpm_locks/pnpm-workspace.yaml");
|
|
3485
|
+
expect(wobj.packages.length).toEqual(31);
|
|
3486
|
+
expect(Object.keys(wobj.catalogs).length).toEqual(217);
|
|
3487
|
+
});
|
|
3488
|
+
|
|
3482
3489
|
test("parsePnpmLock", async () => {
|
|
3483
3490
|
let parsedList = await parsePnpmLock("./test/pnpm-lock.yaml");
|
|
3484
3491
|
expect(parsedList.pkgList.length).toEqual(1706);
|
|
@@ -3491,6 +3498,7 @@ test("parsePnpmLock", async () => {
|
|
|
3491
3498
|
"bom-ref": "pkg:npm/@babel/code-frame@7.10.1",
|
|
3492
3499
|
purl: "pkg:npm/%40babel/code-frame@7.10.1",
|
|
3493
3500
|
scope: undefined,
|
|
3501
|
+
type: "library",
|
|
3494
3502
|
version: "7.10.1",
|
|
3495
3503
|
properties: [
|
|
3496
3504
|
{
|
|
@@ -3523,6 +3531,7 @@ test("parsePnpmLock", async () => {
|
|
|
3523
3531
|
"bom-ref": "pkg:npm/@babel/code-frame@7.16.7",
|
|
3524
3532
|
purl: "pkg:npm/%40babel/code-frame@7.16.7",
|
|
3525
3533
|
scope: "optional",
|
|
3534
|
+
type: "library",
|
|
3526
3535
|
version: "7.16.7",
|
|
3527
3536
|
properties: [
|
|
3528
3537
|
{
|
|
@@ -3554,6 +3563,7 @@ test("parsePnpmLock", async () => {
|
|
|
3554
3563
|
"bom-ref": "pkg:npm/ansi-regex@2.1.1",
|
|
3555
3564
|
purl: "pkg:npm/ansi-regex@2.1.1",
|
|
3556
3565
|
scope: undefined,
|
|
3566
|
+
type: "library",
|
|
3557
3567
|
_integrity: "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
|
3558
3568
|
properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock2.yaml" }],
|
|
3559
3569
|
evidence: {
|
|
@@ -3590,6 +3600,7 @@ test("parsePnpmLock", async () => {
|
|
|
3590
3600
|
"bom-ref": "pkg:npm/@nodelib/fs.scandir@2.1.5",
|
|
3591
3601
|
purl: "pkg:npm/%40nodelib/fs.scandir@2.1.5",
|
|
3592
3602
|
scope: undefined,
|
|
3603
|
+
type: "library",
|
|
3593
3604
|
_integrity:
|
|
3594
3605
|
"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
|
3595
3606
|
properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock3.yaml" }],
|
|
@@ -3625,6 +3636,7 @@ test("parsePnpmLock", async () => {
|
|
|
3625
3636
|
"bom-ref": "pkg:npm/@babel/code-frame@7.18.6",
|
|
3626
3637
|
purl: "pkg:npm/%40babel/code-frame@7.18.6",
|
|
3627
3638
|
scope: "optional",
|
|
3639
|
+
type: "library",
|
|
3628
3640
|
_integrity:
|
|
3629
3641
|
"sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
|
3630
3642
|
properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" }],
|
|
@@ -3649,6 +3661,7 @@ test("parsePnpmLock", async () => {
|
|
|
3649
3661
|
"bom-ref": "pkg:npm/yargs@17.7.1",
|
|
3650
3662
|
purl: "pkg:npm/yargs@17.7.1",
|
|
3651
3663
|
scope: "optional",
|
|
3664
|
+
type: "library",
|
|
3652
3665
|
_integrity:
|
|
3653
3666
|
"sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
|
|
3654
3667
|
properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" }],
|
|
@@ -3676,6 +3689,7 @@ test("parsePnpmLock", async () => {
|
|
|
3676
3689
|
"bom-ref": "pkg:npm/@babel/code-frame@7.18.6",
|
|
3677
3690
|
purl: "pkg:npm/%40babel/code-frame@7.18.6",
|
|
3678
3691
|
scope: "optional",
|
|
3692
|
+
type: "library",
|
|
3679
3693
|
_integrity:
|
|
3680
3694
|
"sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
|
3681
3695
|
properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock6a.yaml" }],
|
|
@@ -3723,9 +3737,9 @@ test("parsePnpmLock", async () => {
|
|
|
3723
3737
|
obj["ref"] === "pkg:npm/rush/my-toolchain@latest#tools/my-toolchain",
|
|
3724
3738
|
);
|
|
3725
3739
|
expect(mainRootDependency["dependsOn"].length).toEqual(0);
|
|
3726
|
-
expect(myAppRootDependency["dependsOn"].length).toEqual(
|
|
3727
|
-
expect(myControlsRootDependency["dependsOn"].length).toEqual(
|
|
3728
|
-
expect(myToolChainRootDependency["dependsOn"].length).toEqual(
|
|
3740
|
+
expect(myAppRootDependency["dependsOn"].length).toEqual(4);
|
|
3741
|
+
expect(myControlsRootDependency["dependsOn"].length).toEqual(2);
|
|
3742
|
+
expect(myToolChainRootDependency["dependsOn"].length).toEqual(4);
|
|
3729
3743
|
|
|
3730
3744
|
parsedList = await parsePnpmLock("./test/data/pnpm-lock9a.yaml", {
|
|
3731
3745
|
name: "pnpm9",
|
|
@@ -3757,6 +3771,7 @@ test("parsePnpmLock", async () => {
|
|
|
3757
3771
|
version: "2.3.0",
|
|
3758
3772
|
purl: "pkg:npm/%40ampproject/remapping@2.3.0",
|
|
3759
3773
|
"bom-ref": "pkg:npm/@ampproject/remapping@2.3.0",
|
|
3774
|
+
type: "library",
|
|
3760
3775
|
_integrity:
|
|
3761
3776
|
"sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
|
|
3762
3777
|
properties: [{ name: "SrcFile", value: "./pnpm-lock.yaml" }],
|
package/lib/helpers/validator.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { join } from "node:path";
|
|
3
3
|
import Ajv from "ajv";
|
|
4
4
|
import addFormats from "ajv-formats";
|
|
5
5
|
import { PackageURL } from "packageurl-js";
|
|
6
6
|
import { DEBUG_MODE, dirNameStr, isPartialTree } from "./utils.js";
|
|
7
7
|
|
|
8
|
-
import { URL
|
|
8
|
+
import { URL } from "node:url";
|
|
9
9
|
let url = import.meta.url;
|
|
10
10
|
if (!url.startsWith("file://")) {
|
|
11
11
|
url = new URL(`file://${import.meta.url}`).toString();
|
|
@@ -58,7 +58,10 @@ export const validateBom = (bomJson) => {
|
|
|
58
58
|
}
|
|
59
59
|
// Deep validation tests
|
|
60
60
|
return (
|
|
61
|
-
validateMetadata(bomJson) &&
|
|
61
|
+
validateMetadata(bomJson) &&
|
|
62
|
+
validatePurls(bomJson) &&
|
|
63
|
+
validateRefs(bomJson) &&
|
|
64
|
+
validateProps(bomJson)
|
|
62
65
|
);
|
|
63
66
|
};
|
|
64
67
|
|
|
@@ -266,3 +269,61 @@ export const validateRefs = (bomJson) => {
|
|
|
266
269
|
}
|
|
267
270
|
return true;
|
|
268
271
|
};
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Validate the component properties
|
|
275
|
+
*
|
|
276
|
+
* @param {object} bomJson Bom json object
|
|
277
|
+
*/
|
|
278
|
+
export function validateProps(bomJson) {
|
|
279
|
+
const errorList = [];
|
|
280
|
+
const warningsList = [];
|
|
281
|
+
let isWorkspaceMode = false;
|
|
282
|
+
if (bomJson?.components) {
|
|
283
|
+
for (const comp of bomJson.components) {
|
|
284
|
+
if (!["library", "framework"].includes(comp.type)) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (!comp.properties) {
|
|
288
|
+
warningsList.push(`${comp["bom-ref"]} lacks properties.`);
|
|
289
|
+
} else {
|
|
290
|
+
let srcFilePropFound = false;
|
|
291
|
+
let workspacePropFound = false;
|
|
292
|
+
for (const p of comp.properties) {
|
|
293
|
+
if (p.name === "SrcFile") {
|
|
294
|
+
srcFilePropFound = true;
|
|
295
|
+
}
|
|
296
|
+
if (p.name === "internal:workspaceRef") {
|
|
297
|
+
isWorkspaceMode = true;
|
|
298
|
+
workspacePropFound = true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (
|
|
302
|
+
isWorkspaceMode &&
|
|
303
|
+
!workspacePropFound &&
|
|
304
|
+
!srcFilePropFound &&
|
|
305
|
+
comp?.scope !== "optional"
|
|
306
|
+
) {
|
|
307
|
+
warningsList.push(
|
|
308
|
+
`${comp["bom-ref"]} lacks workspace-related properties.`,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
if (!srcFilePropFound) {
|
|
312
|
+
warningsList.push(`${comp["bom-ref"]} lacks SrcFile property.`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (!comp.evidence) {
|
|
316
|
+
warningsList.push(`${comp["bom-ref"]} lacks evidence.`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (DEBUG_MODE && warningsList.length !== 0) {
|
|
321
|
+
console.log("===== WARNINGS =====");
|
|
322
|
+
console.log(warningsList);
|
|
323
|
+
}
|
|
324
|
+
if (errorList.length !== 0) {
|
|
325
|
+
console.log(errorList);
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
return true;
|
|
329
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "11.1.
|
|
3
|
+
"version": "11.1.2",
|
|
4
4
|
"description": "Creates CycloneDX Software Bill of Materials (SBOM) from source or container image",
|
|
5
5
|
"homepage": "http://github.com/cyclonedx/cdxgen",
|
|
6
6
|
"author": "Prabhu Subramanian <prabhu@appthreat.com>",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/cli/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/cli/index.js"],"names":[],"mappings":"AAqxBA;;;;;;;;GAQG;AACH,gFAFW,MAAM,SAchB;AAuXD;;;;;;;GAOG;AACH,mCALW,MAAM,qBAiEhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;EAKhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAs7BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BAopBhB;AAED;;;;;;;;;;GAUG;AACH,+DAsEC;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA+dhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BA+YhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqIhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAkEhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBA+KhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBAsHhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,0CAHW,MAAM,qBAuBhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,8BAqDhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,8BA4ChB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM,8BA6FhB;AAED;;;;;GAKG;AACH,iDAHW,MAAM,qBAmUhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBAiJhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqNhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BAkahB;AAED;;;;;GAKG;AACH,2CAHW,MAAM;;;;;;;;;;;;;;;;;;;;GAoChB;AAED;;;;;;;;KA+DC;AAED;;;;;;GAMG;AACH,yDAyFC;AAED;;;;;;;;;GASG;AACH,2GA6BC;AAED;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,8BA2iBlB;AAED;;;;;GAKG;AACH,iCAHW,MAAM,8BAgUhB;AAED;;;;;GAKG;AACH,gCAHW,MAAM,qBAiPhB;AAED;;;;;;GAMG;AACH,wDAFY,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAwHxE"}
|
|
@@ -147,13 +147,25 @@ export function parseYarnLock(yarnLockFile: string): Promise<{
|
|
|
147
147
|
* @param {string} swFile shrinkwrap-deps.json file
|
|
148
148
|
*/
|
|
149
149
|
export function parseNodeShrinkwrap(swFile: string): Promise<any[]>;
|
|
150
|
+
/**
|
|
151
|
+
* Parse pnpm workspace file
|
|
152
|
+
*
|
|
153
|
+
* @param {string} workspaceFile pnpm-workspace.yaml
|
|
154
|
+
* @returns {object} Object containing packages and catalogs
|
|
155
|
+
*/
|
|
156
|
+
export function parsePnpmWorkspace(workspaceFile: string): object;
|
|
150
157
|
/**
|
|
151
158
|
* Parse nodejs pnpm lock file
|
|
152
159
|
*
|
|
153
160
|
* @param {string} pnpmLock pnpm-lock.yaml file
|
|
154
|
-
* @param {
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
* @param {Object} parentComponent parent component
|
|
162
|
+
* @param {Array[String]} workspacePackages Workspace packages
|
|
163
|
+
* @param {Object} workspaceSrcFiles Workspace package.json files
|
|
164
|
+
* @param {Object} workspaceCatalogs Workspace catalogs
|
|
165
|
+
* @param {Object} workspaceDirectDeps Direct dependencies of each workspace
|
|
166
|
+
* @param {Object} depsWorkspaceRefs Workspace references for each dependency
|
|
167
|
+
*/
|
|
168
|
+
export function parsePnpmLock(pnpmLock: string, parentComponent?: any, workspacePackages?: any, workspaceSrcFiles?: any, _workspaceCatalogs?: {}, _workspaceDirectDeps?: {}, depsWorkspaceRefs?: any): Promise<{
|
|
157
169
|
pkgList?: undefined;
|
|
158
170
|
dependenciesList?: undefined;
|
|
159
171
|
parentSubComponents?: undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/helpers/utils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/helpers/utils.js"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate the component properties
|
|
3
|
+
*
|
|
4
|
+
* @param {object} bomJson Bom json object
|
|
5
|
+
*/
|
|
6
|
+
export function validateProps(bomJson: object): boolean;
|
|
1
7
|
export function validateBom(bomJson: object): boolean;
|
|
2
8
|
export function validateMetadata(bomJson: object): boolean;
|
|
3
9
|
export function validatePurls(bomJson: object): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../lib/helpers/validator.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../lib/helpers/validator.js"],"names":[],"mappings":"AAgRA;;;;GAIG;AACH,uCAFW,MAAM,WAqDhB;AArTM,qCAFI,MAAM,WAgDhB;AAOM,0CAFI,MAAM,WAwDhB;AAOM,uCAFI,MAAM,WAgEhB;AA6BM,sCAFI,MAAM,WAgDhB"}
|