@cyclonedx/cdxgen 12.2.0 → 12.2.1
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 +5 -2
- package/bin/cdxgen.js +19 -1
- package/lib/cli/index.js +122 -57
- package/lib/cli/index.poku.js +117 -0
- package/lib/helpers/analyzer.js +606 -3
- package/lib/helpers/analyzer.poku.js +230 -0
- package/lib/helpers/depsUtils.js +16 -0
- package/lib/helpers/depsUtils.poku.js +58 -1
- package/lib/helpers/display.js +4 -2
- package/lib/helpers/remote/dependency-track.js +84 -0
- package/lib/helpers/remote/dependency-track.poku.js +119 -0
- package/lib/helpers/table.js +384 -0
- package/lib/helpers/table.poku.js +186 -0
- package/lib/helpers/utils.js +184 -10
- package/lib/helpers/utils.poku.js +118 -11
- package/lib/server/openapi.yaml +33 -0
- package/lib/server/server.js +10 -2
- package/lib/server/server.poku.js +209 -0
- package/lib/stages/postgen/auditBom.js +1 -2
- package/lib/validator/reporters/console.js +2 -2
- package/package.json +1 -2
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/depsUtils.d.ts.map +1 -1
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/remote/dependency-track.d.ts +16 -0
- package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -0
- package/types/lib/helpers/table.d.ts +6 -0
- package/types/lib/helpers/table.d.ts.map +1 -0
- package/types/lib/helpers/utils.d.ts +1 -0
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
package/lib/helpers/utils.js
CHANGED
|
@@ -337,6 +337,13 @@ export const DEBUG_MODE =
|
|
|
337
337
|
["debug", "verbose"].includes(process.env.CDXGEN_DEBUG_MODE) ||
|
|
338
338
|
process.env.SCAN_DEBUG_MODE === "debug";
|
|
339
339
|
|
|
340
|
+
// Table border style for console output.
|
|
341
|
+
export const TABLE_BORDER_STYLE = ["ascii", "unicode", "auto"].includes(
|
|
342
|
+
`${process.env.CDXGEN_TABLE_BORDER || ""}`.toLowerCase(),
|
|
343
|
+
)
|
|
344
|
+
? `${process.env.CDXGEN_TABLE_BORDER}`.toLowerCase()
|
|
345
|
+
: "auto";
|
|
346
|
+
|
|
340
347
|
// Timeout milliseconds. Default 20 mins
|
|
341
348
|
export const TIMEOUT_MS =
|
|
342
349
|
Number.parseInt(process.env.CDXGEN_TIMEOUT_MS, 10) || 20 * 60 * 1000;
|
|
@@ -1120,7 +1127,44 @@ export function getLicenses(pkg) {
|
|
|
1120
1127
|
licenseContent.name = l;
|
|
1121
1128
|
}
|
|
1122
1129
|
} else if (Object.keys(l).length) {
|
|
1123
|
-
licenseContent = l;
|
|
1130
|
+
licenseContent = { ...l };
|
|
1131
|
+
if (
|
|
1132
|
+
licenseContent.type &&
|
|
1133
|
+
!licenseContent.id &&
|
|
1134
|
+
!licenseContent.name &&
|
|
1135
|
+
!licenseContent.expression
|
|
1136
|
+
) {
|
|
1137
|
+
if (spdxLicenses.includes(licenseContent.type)) {
|
|
1138
|
+
licenseContent.id = licenseContent.type;
|
|
1139
|
+
} else if (isSpdxLicenseExpression(licenseContent.type)) {
|
|
1140
|
+
licenseContent.expression = licenseContent.type;
|
|
1141
|
+
} else {
|
|
1142
|
+
licenseContent.name = licenseContent.type;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
if (
|
|
1146
|
+
!licenseContent.id &&
|
|
1147
|
+
!licenseContent.name &&
|
|
1148
|
+
!licenseContent.expression &&
|
|
1149
|
+
licenseContent.url?.startsWith("http")
|
|
1150
|
+
) {
|
|
1151
|
+
const knownLicense = getKnownLicense(licenseContent.url, pkg);
|
|
1152
|
+
if (knownLicense) {
|
|
1153
|
+
if (knownLicense.id) {
|
|
1154
|
+
licenseContent.id = knownLicense.id;
|
|
1155
|
+
} else if (knownLicense.name) {
|
|
1156
|
+
licenseContent.name = knownLicense.name;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
if (
|
|
1161
|
+
!licenseContent.id &&
|
|
1162
|
+
!licenseContent.name &&
|
|
1163
|
+
!licenseContent.expression
|
|
1164
|
+
) {
|
|
1165
|
+
licenseContent.name = "CUSTOM";
|
|
1166
|
+
}
|
|
1167
|
+
delete licenseContent.type;
|
|
1124
1168
|
} else {
|
|
1125
1169
|
return undefined;
|
|
1126
1170
|
}
|
|
@@ -1572,7 +1616,8 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
1572
1616
|
const srcFilePath = node.path.includes(`${_sep}node_modules`)
|
|
1573
1617
|
? node.path.split(`${_sep}node_modules`)[0]
|
|
1574
1618
|
: node.path;
|
|
1575
|
-
const scope =
|
|
1619
|
+
const scope =
|
|
1620
|
+
node.dev === true || node.optional === true ? "optional" : undefined;
|
|
1576
1621
|
const integrity = node.integrity ? node.integrity : undefined;
|
|
1577
1622
|
|
|
1578
1623
|
let pkg;
|
|
@@ -1645,6 +1690,9 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
1645
1690
|
purl: purlString,
|
|
1646
1691
|
"bom-ref": decodeURIComponent(purlString),
|
|
1647
1692
|
};
|
|
1693
|
+
if (node.dev === true) {
|
|
1694
|
+
_setNpmDevelopmentProperty(pkg);
|
|
1695
|
+
}
|
|
1648
1696
|
if (node.resolved) {
|
|
1649
1697
|
if (node.resolved.startsWith("file:")) {
|
|
1650
1698
|
pkg.properties.push({
|
|
@@ -2826,6 +2874,51 @@ function _markTreeOptional(
|
|
|
2826
2874
|
}
|
|
2827
2875
|
}
|
|
2828
2876
|
|
|
2877
|
+
function _markTreeDevelopment(
|
|
2878
|
+
dbomRef,
|
|
2879
|
+
dependenciesMap,
|
|
2880
|
+
possibleDevelopmentDeps,
|
|
2881
|
+
visited,
|
|
2882
|
+
) {
|
|
2883
|
+
// Production-required packages set this map entry to false, and that wins
|
|
2884
|
+
// over any later attempt to propagate a development-only marking.
|
|
2885
|
+
if (possibleDevelopmentDeps[dbomRef] === undefined) {
|
|
2886
|
+
possibleDevelopmentDeps[dbomRef] = true;
|
|
2887
|
+
}
|
|
2888
|
+
if (dependenciesMap[dbomRef] && !visited[dbomRef]) {
|
|
2889
|
+
visited[dbomRef] = true;
|
|
2890
|
+
for (const eachDep of dependenciesMap[dbomRef]) {
|
|
2891
|
+
// Undefined means we have not classified this dependency yet, so we
|
|
2892
|
+
// continue propagating the dev-only marking unless it was already proven
|
|
2893
|
+
// to be non-development via a false entry.
|
|
2894
|
+
if (possibleDevelopmentDeps[eachDep] !== false) {
|
|
2895
|
+
_markTreeDevelopment(
|
|
2896
|
+
eachDep,
|
|
2897
|
+
dependenciesMap,
|
|
2898
|
+
possibleDevelopmentDeps,
|
|
2899
|
+
visited,
|
|
2900
|
+
);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
function _setNpmDevelopmentProperty(pkg) {
|
|
2907
|
+
if (!pkg.properties) {
|
|
2908
|
+
pkg.properties = [];
|
|
2909
|
+
}
|
|
2910
|
+
if (
|
|
2911
|
+
!pkg.properties.some((property) => {
|
|
2912
|
+
return property.name === "cdx:npm:package:development";
|
|
2913
|
+
})
|
|
2914
|
+
) {
|
|
2915
|
+
pkg.properties.push({
|
|
2916
|
+
name: "cdx:npm:package:development",
|
|
2917
|
+
value: "true",
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2829
2922
|
function _setTreeWorkspaceRef(
|
|
2830
2923
|
dependenciesMap,
|
|
2831
2924
|
depref,
|
|
@@ -3201,6 +3294,7 @@ export async function parsePnpmLock(
|
|
|
3201
3294
|
// See: #1163
|
|
3202
3295
|
// Moreover, we have changed >= 9 for >= 6
|
|
3203
3296
|
// See: discussion #1359
|
|
3297
|
+
const possibleDevelopmentDeps = {};
|
|
3204
3298
|
const possibleOptionalDeps = {};
|
|
3205
3299
|
const dependenciesMap = {};
|
|
3206
3300
|
let ppurl = "";
|
|
@@ -3293,7 +3387,7 @@ export async function parsePnpmLock(
|
|
|
3293
3387
|
null,
|
|
3294
3388
|
null,
|
|
3295
3389
|
).toString();
|
|
3296
|
-
|
|
3390
|
+
possibleDevelopmentDeps[decodeURIComponent(dpurl)] = true;
|
|
3297
3391
|
}
|
|
3298
3392
|
// Find the root optional and peer dependencies
|
|
3299
3393
|
for (const rdk of Object.keys({ ...rootOptionalDeps, ...rootPeerDeps })) {
|
|
@@ -3317,6 +3411,7 @@ export async function parsePnpmLock(
|
|
|
3317
3411
|
null,
|
|
3318
3412
|
).toString();
|
|
3319
3413
|
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
|
|
3414
|
+
possibleDevelopmentDeps[decodeURIComponent(dpurl)] = false;
|
|
3320
3415
|
}
|
|
3321
3416
|
// Find the root direct dependencies
|
|
3322
3417
|
for (const dk of Object.keys(rootDirectDeps)) {
|
|
@@ -3344,6 +3439,7 @@ export async function parsePnpmLock(
|
|
|
3344
3439
|
// These are direct dependencies so cannot be optional
|
|
3345
3440
|
possibleOptionalDeps[decodeURIComponent(dpurl)] = false;
|
|
3346
3441
|
}
|
|
3442
|
+
possibleDevelopmentDeps[decodeURIComponent(dpurl)] = false;
|
|
3347
3443
|
}
|
|
3348
3444
|
// pnpm-lock.yaml contains more than root dependencies in importers
|
|
3349
3445
|
// we do what we did above but for all the other components
|
|
@@ -3469,6 +3565,7 @@ export async function parsePnpmLock(
|
|
|
3469
3565
|
// This is a definite dependency of this component
|
|
3470
3566
|
comDepList.add(depRef);
|
|
3471
3567
|
possibleOptionalDeps[depRef] = false;
|
|
3568
|
+
possibleDevelopmentDeps[depRef] = false;
|
|
3472
3569
|
// Track the package.json files
|
|
3473
3570
|
if (pkgSrcFile) {
|
|
3474
3571
|
if (!srcFilesMap[depRef]) {
|
|
@@ -3488,7 +3585,7 @@ export async function parsePnpmLock(
|
|
|
3488
3585
|
null,
|
|
3489
3586
|
).toString();
|
|
3490
3587
|
const devDpRef = decodeURIComponent(dpurl);
|
|
3491
|
-
|
|
3588
|
+
possibleDevelopmentDeps[devDpRef] = true;
|
|
3492
3589
|
// This is also a dependency of this component
|
|
3493
3590
|
comDepList.add(devDpRef);
|
|
3494
3591
|
}
|
|
@@ -3506,6 +3603,7 @@ export async function parsePnpmLock(
|
|
|
3506
3603
|
null,
|
|
3507
3604
|
).toString();
|
|
3508
3605
|
possibleOptionalDeps[decodeURIComponent(dpurl)] = true;
|
|
3606
|
+
possibleDevelopmentDeps[decodeURIComponent(dpurl)] = false;
|
|
3509
3607
|
}
|
|
3510
3608
|
dependenciesList.push({
|
|
3511
3609
|
ref: decodeURIComponent(compPurl),
|
|
@@ -3708,7 +3806,21 @@ export async function parsePnpmLock(
|
|
|
3708
3806
|
null,
|
|
3709
3807
|
).toString();
|
|
3710
3808
|
const bomRef = decodeURIComponent(purlString);
|
|
3809
|
+
if (
|
|
3810
|
+
packageNode.dev === true &&
|
|
3811
|
+
possibleDevelopmentDeps[bomRef] === undefined
|
|
3812
|
+
) {
|
|
3813
|
+
possibleDevelopmentDeps[bomRef] = true;
|
|
3814
|
+
}
|
|
3711
3815
|
const isBaseOptional = possibleOptionalDeps[bomRef];
|
|
3816
|
+
// optionalDependencies are tracked separately because they may still
|
|
3817
|
+
// be runtime-relevant and should keep the CycloneDX optional scope.
|
|
3818
|
+
// packageNode.dev captures explicit dev-only packages from the lock
|
|
3819
|
+
// entry, while possibleDevelopmentDeps lets that marking propagate to
|
|
3820
|
+
// transitive dependencies discovered through the dependency graph.
|
|
3821
|
+
const isBaseDevelopment =
|
|
3822
|
+
packageNode.dev === true ||
|
|
3823
|
+
possibleDevelopmentDeps[bomRef] === true;
|
|
3712
3824
|
const deplist = [];
|
|
3713
3825
|
for (let dpkgName of Object.keys(deps)) {
|
|
3714
3826
|
let vers = deps[dpkgName];
|
|
@@ -3751,6 +3863,18 @@ export async function parsePnpmLock(
|
|
|
3751
3863
|
{},
|
|
3752
3864
|
);
|
|
3753
3865
|
}
|
|
3866
|
+
if (
|
|
3867
|
+
isBaseDevelopment &&
|
|
3868
|
+
possibleDevelopmentDeps[dbomRef] === undefined
|
|
3869
|
+
) {
|
|
3870
|
+
possibleDevelopmentDeps[dbomRef] = true;
|
|
3871
|
+
_markTreeDevelopment(
|
|
3872
|
+
dbomRef,
|
|
3873
|
+
dependenciesMap,
|
|
3874
|
+
possibleDevelopmentDeps,
|
|
3875
|
+
{},
|
|
3876
|
+
);
|
|
3877
|
+
}
|
|
3754
3878
|
}
|
|
3755
3879
|
if (!dependenciesMap[bomRef]) {
|
|
3756
3880
|
dependenciesMap[bomRef] = [];
|
|
@@ -3910,6 +4034,19 @@ export async function parsePnpmLock(
|
|
|
3910
4034
|
}
|
|
3911
4035
|
}
|
|
3912
4036
|
}
|
|
4037
|
+
// Repeat development dependency detection after the dependency graph is fully
|
|
4038
|
+
// built, since a single package iteration can encounter a dev-only component
|
|
4039
|
+
// before its own dependency list has been captured in dependenciesMap.
|
|
4040
|
+
for (const dependencyRef of Object.keys(possibleDevelopmentDeps)) {
|
|
4041
|
+
if (possibleDevelopmentDeps[dependencyRef] === true) {
|
|
4042
|
+
_markTreeDevelopment(
|
|
4043
|
+
dependencyRef,
|
|
4044
|
+
dependenciesMap,
|
|
4045
|
+
possibleDevelopmentDeps,
|
|
4046
|
+
{},
|
|
4047
|
+
);
|
|
4048
|
+
}
|
|
4049
|
+
}
|
|
3913
4050
|
|
|
3914
4051
|
// Problem: We might have over aggressively marked a package as optional even it is both required and optional
|
|
3915
4052
|
// The below loops ensure required packages continue to stay required
|
|
@@ -3940,6 +4077,15 @@ export async function parsePnpmLock(
|
|
|
3940
4077
|
if (requiredDependencies[apkg["bom-ref"]]) {
|
|
3941
4078
|
apkg.scope = undefined;
|
|
3942
4079
|
}
|
|
4080
|
+
if (
|
|
4081
|
+
!requiredDependencies[apkg["bom-ref"]] &&
|
|
4082
|
+
possibleDevelopmentDeps[apkg["bom-ref"]]
|
|
4083
|
+
) {
|
|
4084
|
+
if (!apkg.scope) {
|
|
4085
|
+
apkg.scope = "optional";
|
|
4086
|
+
}
|
|
4087
|
+
_setNpmDevelopmentProperty(apkg);
|
|
4088
|
+
}
|
|
3943
4089
|
if (possibleAliasesRefs[apkg["bom-ref"]]) {
|
|
3944
4090
|
apkg.properties.push({
|
|
3945
4091
|
name: "cdx:pnpm:alias",
|
|
@@ -16447,6 +16593,7 @@ export async function addEvidenceForImports(
|
|
|
16447
16593
|
: [name];
|
|
16448
16594
|
let isImported = false;
|
|
16449
16595
|
for (const alias of aliases) {
|
|
16596
|
+
const isWasmAlias = /\.wasm([?#].*)?$/i.test(alias);
|
|
16450
16597
|
const all_includes = impPkgs.filter(
|
|
16451
16598
|
(find_pkg) =>
|
|
16452
16599
|
find_pkg.startsWith(alias) &&
|
|
@@ -16456,12 +16603,20 @@ export async function addEvidenceForImports(
|
|
|
16456
16603
|
find_pkg.startsWith(alias),
|
|
16457
16604
|
);
|
|
16458
16605
|
if (all_exports?.length) {
|
|
16459
|
-
let exportedModules = new Set(all_exports);
|
|
16606
|
+
let exportedModules = new Set(isWasmAlias ? [] : all_exports);
|
|
16460
16607
|
pkg.properties = pkg.properties || [];
|
|
16461
16608
|
for (const subevidence of all_exports) {
|
|
16462
16609
|
const evidences = allExports[subevidence];
|
|
16463
16610
|
for (const evidence of evidences) {
|
|
16464
16611
|
if (evidence && Object.keys(evidence).length) {
|
|
16612
|
+
if (isWasmAlias) {
|
|
16613
|
+
for (const wasmImportedModule of evidence.importedModules ||
|
|
16614
|
+
[]) {
|
|
16615
|
+
if (wasmImportedModule?.length) {
|
|
16616
|
+
exportedModules.add(wasmImportedModule);
|
|
16617
|
+
}
|
|
16618
|
+
}
|
|
16619
|
+
}
|
|
16465
16620
|
if (evidence.exportedModules.length > 1) {
|
|
16466
16621
|
for (const aexpsubm of evidence.exportedModules) {
|
|
16467
16622
|
// Be selective on the submodule names
|
|
@@ -16496,6 +16651,8 @@ export async function addEvidenceForImports(
|
|
|
16496
16651
|
if (impPkgs.includes(alias) || all_includes.length) {
|
|
16497
16652
|
isImported = true;
|
|
16498
16653
|
let importedModules = new Set();
|
|
16654
|
+
let wasmExportedModules = new Set();
|
|
16655
|
+
const seenOccurrenceLocations = new Set();
|
|
16499
16656
|
pkg.scope = "required";
|
|
16500
16657
|
for (const subevidence of all_includes) {
|
|
16501
16658
|
const evidences = allImports[subevidence];
|
|
@@ -16503,16 +16660,23 @@ export async function addEvidenceForImports(
|
|
|
16503
16660
|
if (evidence && Object.keys(evidence).length && evidence.fileName) {
|
|
16504
16661
|
pkg.evidence = pkg.evidence || {};
|
|
16505
16662
|
pkg.evidence.occurrences = pkg.evidence.occurrences || [];
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16663
|
+
const occurrenceLocation = `${evidence.fileName}${
|
|
16664
|
+
evidence.lineNumber ? `#${evidence.lineNumber}` : ""
|
|
16665
|
+
}`;
|
|
16666
|
+
if (!seenOccurrenceLocations.has(occurrenceLocation)) {
|
|
16667
|
+
pkg.evidence.occurrences.push({
|
|
16668
|
+
location: occurrenceLocation,
|
|
16669
|
+
});
|
|
16670
|
+
seenOccurrenceLocations.add(occurrenceLocation);
|
|
16671
|
+
}
|
|
16511
16672
|
importedModules.add(evidence.importedAs);
|
|
16512
16673
|
for (const importedSm of evidence.importedModules || []) {
|
|
16513
16674
|
if (!importedSm) {
|
|
16514
16675
|
continue;
|
|
16515
16676
|
}
|
|
16677
|
+
if (isWasmAlias) {
|
|
16678
|
+
wasmExportedModules.add(importedSm);
|
|
16679
|
+
}
|
|
16516
16680
|
// Store both the short and long form of the imported sub modules
|
|
16517
16681
|
if (importedSm.length > 3) {
|
|
16518
16682
|
importedModules.add(importedSm);
|
|
@@ -16523,6 +16687,7 @@ export async function addEvidenceForImports(
|
|
|
16523
16687
|
}
|
|
16524
16688
|
}
|
|
16525
16689
|
importedModules = Array.from(importedModules);
|
|
16690
|
+
wasmExportedModules = Array.from(wasmExportedModules);
|
|
16526
16691
|
if (importedModules.length) {
|
|
16527
16692
|
pkg.properties = pkg.properties || [];
|
|
16528
16693
|
pkg.properties.push({
|
|
@@ -16530,6 +16695,15 @@ export async function addEvidenceForImports(
|
|
|
16530
16695
|
value: importedModules.join(","),
|
|
16531
16696
|
});
|
|
16532
16697
|
}
|
|
16698
|
+
if (isWasmAlias && wasmExportedModules.length) {
|
|
16699
|
+
pkg.properties = pkg.properties || [];
|
|
16700
|
+
if (!pkg.properties.some((p) => p.name === "ExportedModules")) {
|
|
16701
|
+
pkg.properties.push({
|
|
16702
|
+
name: "ExportedModules",
|
|
16703
|
+
value: wasmExportedModules.join(","),
|
|
16704
|
+
});
|
|
16705
|
+
}
|
|
16706
|
+
}
|
|
16533
16707
|
break;
|
|
16534
16708
|
}
|
|
16535
16709
|
if (
|
|
@@ -2671,7 +2671,7 @@ it("parse github actions workflow data", () => {
|
|
|
2671
2671
|
dep_list = parseGitHubWorkflowData("./test/data/github-actions-tj.yaml");
|
|
2672
2672
|
assert.deepStrictEqual(dep_list.length, 4);
|
|
2673
2673
|
dep_list = parseGitHubWorkflowData("./.github/workflows/repotests.yml");
|
|
2674
|
-
assert.deepStrictEqual(dep_list.length,
|
|
2674
|
+
assert.deepStrictEqual(dep_list.length, 91);
|
|
2675
2675
|
});
|
|
2676
2676
|
// biome-ignore-end lint/suspicious/noTemplateCurlyInString: fp
|
|
2677
2677
|
|
|
@@ -3575,6 +3575,23 @@ it("get licenses", () => {
|
|
|
3575
3575
|
},
|
|
3576
3576
|
]);
|
|
3577
3577
|
|
|
3578
|
+
licenses = getLicenses({
|
|
3579
|
+
license: [
|
|
3580
|
+
{
|
|
3581
|
+
type: "MIT",
|
|
3582
|
+
url: "https://github.com/harvesthq/chosen/blob/master/LICENSE.md",
|
|
3583
|
+
},
|
|
3584
|
+
],
|
|
3585
|
+
});
|
|
3586
|
+
assert.deepStrictEqual(licenses, [
|
|
3587
|
+
{
|
|
3588
|
+
license: {
|
|
3589
|
+
id: "MIT",
|
|
3590
|
+
url: "https://github.com/harvesthq/chosen/blob/master/LICENSE.md",
|
|
3591
|
+
},
|
|
3592
|
+
},
|
|
3593
|
+
]);
|
|
3594
|
+
|
|
3578
3595
|
licenses = getLicenses({
|
|
3579
3596
|
license: "GPL-2.0+",
|
|
3580
3597
|
});
|
|
@@ -3677,6 +3694,30 @@ it("parsePkgLock v2", async () => {
|
|
|
3677
3694
|
],
|
|
3678
3695
|
},
|
|
3679
3696
|
});
|
|
3697
|
+
const devOnlyPkg = deps.find(
|
|
3698
|
+
(pkg) => pkg["bom-ref"] === "pkg:npm/@types/shelljs@0.8.11",
|
|
3699
|
+
);
|
|
3700
|
+
assert.ok(devOnlyPkg);
|
|
3701
|
+
assert.deepStrictEqual(devOnlyPkg.scope, "optional");
|
|
3702
|
+
assert.ok(
|
|
3703
|
+
devOnlyPkg.properties.some(
|
|
3704
|
+
(property) =>
|
|
3705
|
+
property.name === "cdx:npm:package:development" &&
|
|
3706
|
+
property.value === "true",
|
|
3707
|
+
),
|
|
3708
|
+
);
|
|
3709
|
+
const devOptionalPkg = deps.find(
|
|
3710
|
+
(pkg) => pkg["bom-ref"] === "pkg:npm/@esbuild/android-arm@0.15.12",
|
|
3711
|
+
);
|
|
3712
|
+
assert.ok(devOptionalPkg);
|
|
3713
|
+
assert.deepStrictEqual(devOptionalPkg.scope, "optional");
|
|
3714
|
+
assert.ok(
|
|
3715
|
+
devOptionalPkg.properties.some(
|
|
3716
|
+
(property) =>
|
|
3717
|
+
property.name === "cdx:npm:package:development" &&
|
|
3718
|
+
property.value === "true",
|
|
3719
|
+
),
|
|
3720
|
+
);
|
|
3680
3721
|
assert.deepStrictEqual(parsedList.dependenciesList.length, 134);
|
|
3681
3722
|
});
|
|
3682
3723
|
|
|
@@ -3865,10 +3906,8 @@ it("parsePnpmLock", async () => {
|
|
|
3865
3906
|
type: "library",
|
|
3866
3907
|
version: "7.16.7",
|
|
3867
3908
|
properties: [
|
|
3868
|
-
{
|
|
3869
|
-
|
|
3870
|
-
value: "./test/data/pnpm-lock.yaml",
|
|
3871
|
-
},
|
|
3909
|
+
{ name: "SrcFile", value: "./test/data/pnpm-lock.yaml" },
|
|
3910
|
+
{ name: "cdx:npm:package:development", value: "true" },
|
|
3872
3911
|
],
|
|
3873
3912
|
evidence: {
|
|
3874
3913
|
identity: {
|
|
@@ -3970,7 +4009,10 @@ it("parsePnpmLock", async () => {
|
|
|
3970
4009
|
type: "library",
|
|
3971
4010
|
_integrity:
|
|
3972
4011
|
"sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
|
3973
|
-
properties: [
|
|
4012
|
+
properties: [
|
|
4013
|
+
{ name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" },
|
|
4014
|
+
{ name: "cdx:npm:package:development", value: "true" },
|
|
4015
|
+
],
|
|
3974
4016
|
evidence: {
|
|
3975
4017
|
identity: {
|
|
3976
4018
|
field: "purl",
|
|
@@ -3995,7 +4037,10 @@ it("parsePnpmLock", async () => {
|
|
|
3995
4037
|
type: "library",
|
|
3996
4038
|
_integrity:
|
|
3997
4039
|
"sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
|
|
3998
|
-
properties: [
|
|
4040
|
+
properties: [
|
|
4041
|
+
{ name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" },
|
|
4042
|
+
{ name: "cdx:npm:package:development", value: "true" },
|
|
4043
|
+
],
|
|
3999
4044
|
evidence: {
|
|
4000
4045
|
identity: {
|
|
4001
4046
|
field: "purl",
|
|
@@ -4023,7 +4068,10 @@ it("parsePnpmLock", async () => {
|
|
|
4023
4068
|
type: "library",
|
|
4024
4069
|
_integrity:
|
|
4025
4070
|
"sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
|
|
4026
|
-
properties: [
|
|
4071
|
+
properties: [
|
|
4072
|
+
{ name: "SrcFile", value: "./test/data/pnpm-lock6a.yaml" },
|
|
4073
|
+
{ name: "cdx:npm:package:development", value: "true" },
|
|
4074
|
+
],
|
|
4027
4075
|
evidence: {
|
|
4028
4076
|
identity: {
|
|
4029
4077
|
field: "purl",
|
|
@@ -4038,6 +4086,18 @@ it("parsePnpmLock", async () => {
|
|
|
4038
4086
|
},
|
|
4039
4087
|
},
|
|
4040
4088
|
});
|
|
4089
|
+
const pnpmDevOptionalPkg = parsedList.pkgList.find(
|
|
4090
|
+
(pkg) => pkg["bom-ref"] === "pkg:npm/@cyclonedx/cdxgen-plugins-bin@1.0.5",
|
|
4091
|
+
);
|
|
4092
|
+
assert.ok(pnpmDevOptionalPkg);
|
|
4093
|
+
assert.deepStrictEqual(pnpmDevOptionalPkg.scope, "optional");
|
|
4094
|
+
assert.ok(
|
|
4095
|
+
pnpmDevOptionalPkg.properties.some(
|
|
4096
|
+
(property) =>
|
|
4097
|
+
property.name === "cdx:npm:package:development" &&
|
|
4098
|
+
property.value === "true",
|
|
4099
|
+
),
|
|
4100
|
+
);
|
|
4041
4101
|
// Test case to see if parsePnpmLock is finding all root deps
|
|
4042
4102
|
const dummpyParent = {
|
|
4043
4103
|
name: "rush",
|
|
@@ -4079,7 +4139,15 @@ it("parsePnpmLock", async () => {
|
|
|
4079
4139
|
assert.deepStrictEqual(parsedList.pkgList.length, 1007);
|
|
4080
4140
|
assert.deepStrictEqual(parsedList.dependenciesList.length, 1006);
|
|
4081
4141
|
assert.deepStrictEqual(
|
|
4082
|
-
parsedList.pkgList.filter(
|
|
4142
|
+
parsedList.pkgList.filter(
|
|
4143
|
+
(pkg) =>
|
|
4144
|
+
!pkg.scope &&
|
|
4145
|
+
!pkg.properties?.some(
|
|
4146
|
+
(property) =>
|
|
4147
|
+
property.name === "cdx:npm:package:development" &&
|
|
4148
|
+
property.value === "true",
|
|
4149
|
+
),
|
|
4150
|
+
).length,
|
|
4083
4151
|
0,
|
|
4084
4152
|
);
|
|
4085
4153
|
parsedList = await parsePnpmLock("./test/data/pnpm-lock9b.yaml", {
|
|
@@ -4089,7 +4157,15 @@ it("parsePnpmLock", async () => {
|
|
|
4089
4157
|
assert.deepStrictEqual(parsedList.pkgList.length, 1366);
|
|
4090
4158
|
assert.deepStrictEqual(parsedList.dependenciesList.length, 1353);
|
|
4091
4159
|
assert.deepStrictEqual(
|
|
4092
|
-
parsedList.pkgList.filter(
|
|
4160
|
+
parsedList.pkgList.filter(
|
|
4161
|
+
(pkg) =>
|
|
4162
|
+
!pkg.scope &&
|
|
4163
|
+
!pkg.properties?.some(
|
|
4164
|
+
(property) =>
|
|
4165
|
+
property.name === "cdx:npm:package:development" &&
|
|
4166
|
+
property.value === "true",
|
|
4167
|
+
),
|
|
4168
|
+
).length,
|
|
4093
4169
|
12,
|
|
4094
4170
|
);
|
|
4095
4171
|
parsedList = await parsePnpmLock("./test/data/pnpm-lock9c.yaml", {
|
|
@@ -4099,9 +4175,40 @@ it("parsePnpmLock", async () => {
|
|
|
4099
4175
|
assert.deepStrictEqual(parsedList.pkgList.length, 461);
|
|
4100
4176
|
assert.deepStrictEqual(parsedList.dependenciesList.length, 462);
|
|
4101
4177
|
assert.deepStrictEqual(
|
|
4102
|
-
parsedList.pkgList.filter(
|
|
4178
|
+
parsedList.pkgList.filter(
|
|
4179
|
+
(pkg) =>
|
|
4180
|
+
!pkg.scope &&
|
|
4181
|
+
!pkg.properties?.some(
|
|
4182
|
+
(property) =>
|
|
4183
|
+
property.name === "cdx:npm:package:development" &&
|
|
4184
|
+
property.value === "true",
|
|
4185
|
+
),
|
|
4186
|
+
).length,
|
|
4103
4187
|
3,
|
|
4104
4188
|
);
|
|
4189
|
+
parsedList = await parsePnpmLock(
|
|
4190
|
+
"./test/data/pnpm-lock-dev-propagation.yaml",
|
|
4191
|
+
);
|
|
4192
|
+
assert.deepStrictEqual(parsedList.pkgList.length, 4);
|
|
4193
|
+
assert.deepStrictEqual(parsedList.dependenciesList.length, 4);
|
|
4194
|
+
assert.deepStrictEqual(
|
|
4195
|
+
parsedList.pkgList.filter(
|
|
4196
|
+
(pkg) =>
|
|
4197
|
+
pkg.scope === "optional" &&
|
|
4198
|
+
pkg.properties?.some(
|
|
4199
|
+
(property) =>
|
|
4200
|
+
property.name === "cdx:npm:package:development" &&
|
|
4201
|
+
property.value === "true",
|
|
4202
|
+
),
|
|
4203
|
+
).length,
|
|
4204
|
+
4,
|
|
4205
|
+
);
|
|
4206
|
+
assert.ok(
|
|
4207
|
+
parsedList.pkgList.find((pkg) => pkg["bom-ref"] === "pkg:npm/gamma@1.0.0"),
|
|
4208
|
+
);
|
|
4209
|
+
assert.ok(
|
|
4210
|
+
parsedList.pkgList.find((pkg) => pkg["bom-ref"] === "pkg:npm/delta@1.0.0"),
|
|
4211
|
+
);
|
|
4105
4212
|
parsedList = await parsePnpmLock(
|
|
4106
4213
|
"./test/data/pnpm_locks/bytemd-pnpm-lock.yaml",
|
|
4107
4214
|
);
|
package/lib/server/openapi.yaml
CHANGED
|
@@ -94,11 +94,31 @@ paths:
|
|
|
94
94
|
required: false
|
|
95
95
|
schema:
|
|
96
96
|
$ref: '#/components/schemas/CDXGEN/properties/projectVersion'
|
|
97
|
+
- name: autoCreate
|
|
98
|
+
in: query
|
|
99
|
+
required: false
|
|
100
|
+
schema:
|
|
101
|
+
$ref: '#/components/schemas/CDXGEN/properties/autoCreate'
|
|
102
|
+
- name: isLatest
|
|
103
|
+
in: query
|
|
104
|
+
required: false
|
|
105
|
+
schema:
|
|
106
|
+
$ref: '#/components/schemas/CDXGEN/properties/isLatest'
|
|
97
107
|
- name: parentUUID
|
|
98
108
|
in: query
|
|
99
109
|
required: false
|
|
100
110
|
schema:
|
|
101
111
|
$ref: '#/components/schemas/CDXGEN/properties/parentUUID'
|
|
112
|
+
- name: parentProjectName
|
|
113
|
+
in: query
|
|
114
|
+
required: false
|
|
115
|
+
schema:
|
|
116
|
+
$ref: '#/components/schemas/CDXGEN/properties/parentProjectName'
|
|
117
|
+
- name: parentProjectVersion
|
|
118
|
+
in: query
|
|
119
|
+
required: false
|
|
120
|
+
schema:
|
|
121
|
+
$ref: '#/components/schemas/CDXGEN/properties/parentProjectVersion'
|
|
102
122
|
- name: serverUrl
|
|
103
123
|
in: query
|
|
104
124
|
required: false
|
|
@@ -252,9 +272,22 @@ components:
|
|
|
252
272
|
type: string
|
|
253
273
|
description: Dependency Track project version
|
|
254
274
|
default: ""
|
|
275
|
+
autoCreate:
|
|
276
|
+
type: boolean
|
|
277
|
+
description: Dependency Track autoCreate value for BOM submissions
|
|
278
|
+
default: true
|
|
279
|
+
isLatest:
|
|
280
|
+
type: boolean
|
|
281
|
+
description: Dependency Track isLatest value for BOM submissions
|
|
255
282
|
parentUUID:
|
|
256
283
|
type: string
|
|
257
284
|
description: UUID of the parent Dependency Track project
|
|
285
|
+
parentProjectName:
|
|
286
|
+
type: string
|
|
287
|
+
description: Name of the parent Dependency Track project
|
|
288
|
+
parentProjectVersion:
|
|
289
|
+
type: string
|
|
290
|
+
description: Version of the parent Dependency Track project
|
|
258
291
|
serverUrl:
|
|
259
292
|
type: string
|
|
260
293
|
description: URL to the Dependency Track API server
|
package/lib/server/server.js
CHANGED
|
@@ -36,7 +36,11 @@ const ALLOWED_PARAMS = [
|
|
|
36
36
|
"projectGroup",
|
|
37
37
|
"projectTag",
|
|
38
38
|
"projectVersion",
|
|
39
|
+
"autoCreate",
|
|
40
|
+
"isLatest",
|
|
39
41
|
"parentUUID",
|
|
42
|
+
"parentProjectName",
|
|
43
|
+
"parentProjectVersion",
|
|
40
44
|
"serverUrl",
|
|
41
45
|
"apiKey",
|
|
42
46
|
"specVersion",
|
|
@@ -270,7 +274,10 @@ function gitClone(repoUrl, branch = null) {
|
|
|
270
274
|
"core.fsmonitor=false",
|
|
271
275
|
"-c",
|
|
272
276
|
"safe.bareRepository=explicit",
|
|
277
|
+
"-c",
|
|
278
|
+
"core.hooksPath=/dev/null",
|
|
273
279
|
"clone",
|
|
280
|
+
"--template=",
|
|
274
281
|
repoUrl,
|
|
275
282
|
"--depth",
|
|
276
283
|
"1",
|
|
@@ -297,13 +304,14 @@ function gitClone(repoUrl, branch = null) {
|
|
|
297
304
|
GIT_CONFIG_VALUE_0: "false",
|
|
298
305
|
GIT_CONFIG_KEY_1: "safe.bareRepository",
|
|
299
306
|
GIT_CONFIG_VALUE_1: "explicit",
|
|
307
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
300
308
|
};
|
|
301
309
|
const env = isSecureMode
|
|
302
310
|
? {
|
|
303
311
|
...process.env,
|
|
304
312
|
...envConfigs,
|
|
305
313
|
GIT_CONFIG_NOSYSTEM: "1",
|
|
306
|
-
|
|
314
|
+
GIT_CONFIG_GLOBAL: "/dev/null",
|
|
307
315
|
GIT_ALLOW_PROTOCOL: gitAllowProtocol,
|
|
308
316
|
}
|
|
309
317
|
: {
|
|
@@ -676,4 +684,4 @@ const start = (options) => {
|
|
|
676
684
|
});
|
|
677
685
|
};
|
|
678
686
|
|
|
679
|
-
export { configureServer, start };
|
|
687
|
+
export { configureServer, gitClone, start };
|