@cyclonedx/cdxgen 12.3.0 → 12.3.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 +15 -5
- package/bin/audit.js +7 -0
- package/bin/cdxgen.js +241 -81
- package/bin/repl.js +138 -0
- package/data/rules/ai-agent-governance.yaml +249 -0
- package/data/rules/dependency-sources.yaml +41 -0
- package/data/rules/mcp-servers.yaml +304 -0
- package/data/rules/package-integrity.yaml +123 -0
- package/lib/audit/index.js +353 -29
- package/lib/audit/index.poku.js +247 -7
- package/lib/audit/reporters.js +26 -0
- package/lib/audit/scoring.js +262 -13
- package/lib/audit/scoring.poku.js +179 -0
- package/lib/audit/targets.js +391 -2
- package/lib/audit/targets.poku.js +416 -3
- package/lib/cli/index.js +588 -45
- package/lib/cli/index.poku.js +735 -1
- package/lib/evinser/evinser.js +8 -5
- package/lib/helpers/agentFormulationParser.js +318 -0
- package/lib/helpers/aiInventory.js +262 -0
- package/lib/helpers/aiInventory.poku.js +111 -0
- package/lib/helpers/analyzer.js +1769 -0
- package/lib/helpers/analyzer.poku.js +284 -3
- package/lib/helpers/auditCategories.js +76 -0
- package/lib/helpers/ciParsers/githubActions.js +140 -16
- package/lib/helpers/ciParsers/githubActions.poku.js +110 -0
- package/lib/helpers/communityAiConfigParser.js +672 -0
- package/lib/helpers/communityAiConfigParser.poku.js +63 -0
- package/lib/helpers/depsUtils.js +108 -0
- package/lib/helpers/depsUtils.poku.js +72 -1
- package/lib/helpers/display.js +325 -3
- package/lib/helpers/display.poku.js +301 -0
- package/lib/helpers/formulationParsers.js +28 -0
- package/lib/helpers/formulationParsers.poku.js +504 -1
- package/lib/helpers/jsonLike.js +102 -0
- package/lib/helpers/jsonLike.poku.js +34 -0
- package/lib/helpers/mcp.js +248 -0
- package/lib/helpers/mcp.poku.js +101 -0
- package/lib/helpers/mcpConfigParser.js +656 -0
- package/lib/helpers/mcpConfigParser.poku.js +126 -0
- package/lib/helpers/mcpDiscovery.js +84 -0
- package/lib/helpers/mcpDiscovery.poku.js +21 -0
- package/lib/helpers/protobom.js +3 -3
- package/lib/helpers/provenanceUtils.js +29 -4
- package/lib/helpers/provenanceUtils.poku.js +29 -3
- package/lib/helpers/registryProvenance.js +210 -0
- package/lib/helpers/registryProvenance.poku.js +144 -0
- package/lib/helpers/rustFormulationParser.js +330 -0
- package/lib/helpers/source.js +21 -2
- package/lib/helpers/source.poku.js +38 -0
- package/lib/helpers/utils.js +1331 -83
- package/lib/helpers/utils.poku.js +599 -188
- package/lib/helpers/vsixutils.js +12 -4
- package/lib/helpers/vsixutils.poku.js +34 -0
- package/lib/managers/binary.js +36 -12
- package/lib/managers/binary.poku.js +68 -0
- package/lib/managers/docker.js +59 -9
- package/lib/managers/docker.poku.js +61 -0
- package/lib/managers/piptree.js +12 -7
- package/lib/managers/piptree.poku.js +44 -0
- package/lib/stages/postgen/annotator.js +2 -1
- package/lib/stages/postgen/annotator.poku.js +15 -0
- package/lib/stages/postgen/auditBom.js +20 -6
- package/lib/stages/postgen/auditBom.poku.js +694 -1
- package/lib/stages/postgen/postgen.js +262 -11
- package/lib/stages/postgen/postgen.poku.js +306 -2
- package/lib/stages/postgen/ruleEngine.js +49 -1
- package/lib/stages/postgen/spdxConverter.poku.js +70 -0
- package/lib/stages/pregen/pregen.js +6 -4
- package/package.json +1 -1
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/audit/reporters.d.ts.map +1 -1
- package/types/lib/audit/scoring.d.ts.map +1 -1
- package/types/lib/audit/targets.d.ts +12 -0
- package/types/lib/audit/targets.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +2 -8
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/agentFormulationParser.d.ts +19 -0
- package/types/lib/helpers/agentFormulationParser.d.ts.map +1 -0
- package/types/lib/helpers/aiInventory.d.ts +23 -0
- package/types/lib/helpers/aiInventory.d.ts.map +1 -0
- package/types/lib/helpers/analyzer.d.ts +10 -0
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/auditCategories.d.ts +12 -0
- package/types/lib/helpers/auditCategories.d.ts.map +1 -0
- package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
- package/types/lib/helpers/communityAiConfigParser.d.ts +29 -0
- package/types/lib/helpers/communityAiConfigParser.d.ts.map +1 -0
- package/types/lib/helpers/depsUtils.d.ts +8 -0
- package/types/lib/helpers/depsUtils.d.ts.map +1 -1
- package/types/lib/helpers/display.d.ts +17 -1
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/formulationParsers.d.ts.map +1 -1
- package/types/lib/helpers/jsonLike.d.ts +4 -0
- package/types/lib/helpers/jsonLike.d.ts.map +1 -0
- package/types/lib/helpers/mcp.d.ts +29 -0
- package/types/lib/helpers/mcp.d.ts.map +1 -0
- package/types/lib/helpers/mcpConfigParser.d.ts +30 -0
- package/types/lib/helpers/mcpConfigParser.d.ts.map +1 -0
- package/types/lib/helpers/mcpDiscovery.d.ts +5 -0
- package/types/lib/helpers/mcpDiscovery.d.ts.map +1 -0
- package/types/lib/helpers/provenanceUtils.d.ts +5 -3
- package/types/lib/helpers/provenanceUtils.d.ts.map +1 -1
- package/types/lib/helpers/registryProvenance.d.ts +9 -0
- package/types/lib/helpers/registryProvenance.d.ts.map +1 -1
- package/types/lib/helpers/rustFormulationParser.d.ts +17 -0
- package/types/lib/helpers/rustFormulationParser.d.ts.map +1 -0
- package/types/lib/helpers/source.d.ts.map +1 -1
- package/types/lib/helpers/utils.d.ts +31 -1
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/helpers/vsixutils.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/piptree.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { readFileSync
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
2
|
import { basename, join, relative, sep } from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
|
|
5
5
|
import { PackageURL } from "packageurl-js";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
AI_INVENTORY_PROJECT_TYPES,
|
|
9
|
+
matchesAiInventoryExcludeType,
|
|
10
|
+
optionIncludesAiInventoryProjectType,
|
|
11
|
+
} from "../../helpers/aiInventory.js";
|
|
12
|
+
import { mergeDependencies, mergeServices } from "../../helpers/depsUtils.js";
|
|
8
13
|
import { addFormulationSection } from "../../helpers/formulationParsers.js";
|
|
9
14
|
import { thoughtLog } from "../../helpers/logger.js";
|
|
10
15
|
import { buildReleaseNotesFromGit } from "../../helpers/source.js";
|
|
@@ -14,7 +19,11 @@ import {
|
|
|
14
19
|
getTimestamp,
|
|
15
20
|
getTmpDir,
|
|
16
21
|
hasAnyProjectType,
|
|
22
|
+
isDryRun,
|
|
23
|
+
resetActivityContext,
|
|
17
24
|
safeExistsSync,
|
|
25
|
+
safeRmSync,
|
|
26
|
+
setActivityContext,
|
|
18
27
|
} from "../../helpers/utils.js";
|
|
19
28
|
import { extractTags, findBomType, textualMetadata } from "./annotator.js";
|
|
20
29
|
|
|
@@ -68,11 +77,29 @@ function applyFormulation(bomJson, options, filePath, formulationList) {
|
|
|
68
77
|
return bomJson;
|
|
69
78
|
}
|
|
70
79
|
const context = formulationList?.length ? { formulationList } : {};
|
|
71
|
-
|
|
80
|
+
setActivityContext({
|
|
81
|
+
projectType: "Formulation",
|
|
82
|
+
sourcePath: filePath || options.filePath || process.cwd(),
|
|
83
|
+
});
|
|
84
|
+
let formulationData;
|
|
85
|
+
try {
|
|
86
|
+
formulationData = addFormulationSection(filePath, options, context);
|
|
87
|
+
} finally {
|
|
88
|
+
resetActivityContext();
|
|
89
|
+
}
|
|
72
90
|
if (!formulationData) {
|
|
73
91
|
return bomJson;
|
|
74
92
|
}
|
|
75
93
|
bomJson.formulation = formulationData.formulation;
|
|
94
|
+
const formulationServices = formulationData.formulation.flatMap(
|
|
95
|
+
(entry) => entry?.services || [],
|
|
96
|
+
);
|
|
97
|
+
if (formulationServices.length) {
|
|
98
|
+
bomJson.services = mergeServices(
|
|
99
|
+
bomJson.services || [],
|
|
100
|
+
formulationServices,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
76
103
|
if (formulationData.dependencies?.length) {
|
|
77
104
|
bomJson.dependencies = mergeDependencies(
|
|
78
105
|
bomJson.dependencies || [],
|
|
@@ -82,6 +109,189 @@ function applyFormulation(bomJson, options, filePath, formulationList) {
|
|
|
82
109
|
return bomJson;
|
|
83
110
|
}
|
|
84
111
|
|
|
112
|
+
const WEAK_TLP_CLASSIFICATIONS = new Set(["CLEAR", "GREEN", "AMBER"]);
|
|
113
|
+
const SENSITIVE_PROPERTY_NAMES = new Set([
|
|
114
|
+
"cdx:agent:description",
|
|
115
|
+
"cdx:agent:hiddenMcpUrls",
|
|
116
|
+
"cdx:agent:permission",
|
|
117
|
+
"cdx:mcp:command",
|
|
118
|
+
"cdx:mcp:configuredEndpoints",
|
|
119
|
+
"cdx:mcp:description",
|
|
120
|
+
"cdx:mcp:resourceUri",
|
|
121
|
+
"cdx:skill:metadata",
|
|
122
|
+
]);
|
|
123
|
+
const SENSITIVE_PROPERTY_PREFIXES = ["cdx:crewai:", "cdx:mcp:auth:"];
|
|
124
|
+
const SECRET_ASSIGNMENT_PATTERN =
|
|
125
|
+
/(?:^|[\s,{\[])(?:authorization|password|passwd|pwd|token|access[_-]?token|id[_-]?token|refresh[_-]?token|api[_-]?key|client[_-]?secret|secret|session(?:id)?|cookie)\s*(?:[:=]|=>)\s*["'`]?[^"'`\s,}\]]{4,}/iu;
|
|
126
|
+
const ENV_SECRET_PATTERN =
|
|
127
|
+
/\b[A-Z0-9_]*(?:TOKEN|PASSWORD|SECRET|API_KEY|CLIENT_SECRET|SESSION|COOKIE)[A-Z0-9_]*=\S+/u;
|
|
128
|
+
const AUTH_HEADER_PATTERN =
|
|
129
|
+
/\bAuthorization\s*:\s*(?:Bearer|Basic)\s+[A-Za-z0-9._~+/=-]{8,}/iu;
|
|
130
|
+
const BEARER_TOKEN_PATTERN = /\b(?:Bearer|Basic)\s+[A-Za-z0-9._~+/=-]{12,}/u;
|
|
131
|
+
const PRIVATE_KEY_PATTERN =
|
|
132
|
+
/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/u;
|
|
133
|
+
const SIGNED_URL_PARAM_NAMES = new Set([
|
|
134
|
+
"access_token",
|
|
135
|
+
"api_key",
|
|
136
|
+
"client_secret",
|
|
137
|
+
"id_token",
|
|
138
|
+
"signature",
|
|
139
|
+
"sig",
|
|
140
|
+
"token",
|
|
141
|
+
"x-amz-signature",
|
|
142
|
+
"x-goog-signature",
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
function normalizeSpecVersion(specVersion) {
|
|
146
|
+
return Number.parseFloat(String(specVersion || 0));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function normalizeTlpClassification(tlpClassification) {
|
|
150
|
+
return String(tlpClassification || "")
|
|
151
|
+
.trim()
|
|
152
|
+
.toUpperCase();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function hasSensitivePropertyName(propertyName) {
|
|
156
|
+
if (SENSITIVE_PROPERTY_NAMES.has(propertyName)) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
return SENSITIVE_PROPERTY_PREFIXES.some((prefix) =>
|
|
160
|
+
propertyName.startsWith(prefix),
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function extractUrlCandidates(value) {
|
|
165
|
+
return Array.from(value.matchAll(/https?:\/\/[^\s]+/gu), (match) =>
|
|
166
|
+
match[0].replace(/[),.;]+$/u, ""),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function hasSensitiveUrlValue(value) {
|
|
171
|
+
for (const candidate of extractUrlCandidates(value)) {
|
|
172
|
+
if (!URL.canParse(candidate)) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const parsedUrl = new URL(candidate);
|
|
176
|
+
if (parsedUrl.username || parsedUrl.password || parsedUrl.hash) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
for (const [paramName] of parsedUrl.searchParams) {
|
|
180
|
+
if (SIGNED_URL_PARAM_NAMES.has(paramName.toLowerCase())) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function hasKnownSensitiveText(value) {
|
|
189
|
+
return (
|
|
190
|
+
SECRET_ASSIGNMENT_PATTERN.test(value) ||
|
|
191
|
+
ENV_SECRET_PATTERN.test(value) ||
|
|
192
|
+
AUTH_HEADER_PATTERN.test(value) ||
|
|
193
|
+
BEARER_TOKEN_PATTERN.test(value) ||
|
|
194
|
+
PRIVATE_KEY_PATTERN.test(value)
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function propertyContainsSensitiveValue(propertyName, propertyValue) {
|
|
199
|
+
if (!hasSensitivePropertyName(propertyName) || !propertyValue?.trim()) {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
return (
|
|
203
|
+
hasSensitiveUrlValue(propertyValue) || hasKnownSensitiveText(propertyValue)
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function collectSensitivePropertyViolations(
|
|
208
|
+
subject,
|
|
209
|
+
violations = [],
|
|
210
|
+
location = "bom",
|
|
211
|
+
seen = new Set(),
|
|
212
|
+
) {
|
|
213
|
+
if (!subject || typeof subject !== "object" || seen.has(subject)) {
|
|
214
|
+
return violations;
|
|
215
|
+
}
|
|
216
|
+
seen.add(subject);
|
|
217
|
+
if (Array.isArray(subject.properties)) {
|
|
218
|
+
const subjectLabel = subject["bom-ref"] || subject.name || location;
|
|
219
|
+
for (const property of subject.properties) {
|
|
220
|
+
if (
|
|
221
|
+
typeof property?.name === "string" &&
|
|
222
|
+
typeof property?.value === "string" &&
|
|
223
|
+
propertyContainsSensitiveValue(property.name, property.value)
|
|
224
|
+
) {
|
|
225
|
+
violations.push({
|
|
226
|
+
propertyName: property.name,
|
|
227
|
+
subjectLabel,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (Array.isArray(subject)) {
|
|
233
|
+
subject.forEach((entry, index) => {
|
|
234
|
+
collectSensitivePropertyViolations(
|
|
235
|
+
entry,
|
|
236
|
+
violations,
|
|
237
|
+
`${location}[${index}]`,
|
|
238
|
+
seen,
|
|
239
|
+
);
|
|
240
|
+
});
|
|
241
|
+
return violations;
|
|
242
|
+
}
|
|
243
|
+
for (const [key, value] of Object.entries(subject)) {
|
|
244
|
+
if (key === "properties") {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
collectSensitivePropertyViolations(
|
|
248
|
+
value,
|
|
249
|
+
violations,
|
|
250
|
+
`${location}.${key}`,
|
|
251
|
+
seen,
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
return violations;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function validateTlpClassification(bomJson, options) {
|
|
258
|
+
const specVersion = normalizeSpecVersion(
|
|
259
|
+
bomJson?.specVersion || options?.specVersion,
|
|
260
|
+
);
|
|
261
|
+
if (specVersion < 1.7) {
|
|
262
|
+
return bomJson;
|
|
263
|
+
}
|
|
264
|
+
const tlpClassification = normalizeTlpClassification(
|
|
265
|
+
bomJson?.metadata?.distributionConstraints?.tlp ||
|
|
266
|
+
bomJson?.metadata?.distribution ||
|
|
267
|
+
options?.tlpClassification,
|
|
268
|
+
);
|
|
269
|
+
if (!WEAK_TLP_CLASSIFICATIONS.has(tlpClassification)) {
|
|
270
|
+
return bomJson;
|
|
271
|
+
}
|
|
272
|
+
const violations = collectSensitivePropertyViolations(bomJson);
|
|
273
|
+
if (!violations.length) {
|
|
274
|
+
return bomJson;
|
|
275
|
+
}
|
|
276
|
+
const uniqueViolations = [
|
|
277
|
+
...new Set(
|
|
278
|
+
violations.map(
|
|
279
|
+
({ propertyName, subjectLabel }) =>
|
|
280
|
+
`${propertyName} on ${subjectLabel}`,
|
|
281
|
+
),
|
|
282
|
+
),
|
|
283
|
+
];
|
|
284
|
+
const errorMessage =
|
|
285
|
+
`CycloneDX 1.7+ BOMs with TLP classification '${tlpClassification}' must not include known sensitive property values. ` +
|
|
286
|
+
"Redact the values or raise the TLP classification to AMBER_AND_STRICT or RED. " +
|
|
287
|
+
`Found: ${uniqueViolations.slice(0, 5).join("; ")}${uniqueViolations.length > 5 ? `; and ${uniqueViolations.length - 5} more` : ""}`;
|
|
288
|
+
if (options?.failOnError) {
|
|
289
|
+
throw new Error(errorMessage);
|
|
290
|
+
}
|
|
291
|
+
console.warn(errorMessage);
|
|
292
|
+
return bomJson;
|
|
293
|
+
}
|
|
294
|
+
|
|
85
295
|
/**
|
|
86
296
|
* Filter and enhance BOM post generation.
|
|
87
297
|
*
|
|
@@ -109,6 +319,7 @@ export function postProcess(bomNSData, options, filePath) {
|
|
|
109
319
|
bomNSData.formulationList,
|
|
110
320
|
);
|
|
111
321
|
bomNSData.bomJson = applyReleaseNotes(bomNSData.bomJson, options, filePath);
|
|
322
|
+
bomNSData.bomJson = validateTlpClassification(bomNSData.bomJson, options);
|
|
112
323
|
// Support for automatic annotations
|
|
113
324
|
if (options.specVersion >= 1.6) {
|
|
114
325
|
bomNSData.bomJson = annotate(bomNSData.bomJson, options);
|
|
@@ -409,12 +620,17 @@ function getIdentityTechniques(comp) {
|
|
|
409
620
|
*/
|
|
410
621
|
export function filterBom(bomJson, options) {
|
|
411
622
|
const newPkgMap = {};
|
|
623
|
+
const newServices = [];
|
|
412
624
|
let filtered = false;
|
|
413
625
|
let anyFiltered = false;
|
|
414
626
|
if (!bomJson?.components) {
|
|
415
627
|
return bomJson;
|
|
416
628
|
}
|
|
417
629
|
for (const comp of bomJson.components) {
|
|
630
|
+
if (shouldExcludeInventoryType(comp, options)) {
|
|
631
|
+
filtered = true;
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
418
634
|
// minimum confidence filter
|
|
419
635
|
if (options?.minConfidence > 0) {
|
|
420
636
|
const confidence = Math.min(options.minConfidence, 1);
|
|
@@ -448,6 +664,7 @@ export function filterBom(bomJson, options) {
|
|
|
448
664
|
) {
|
|
449
665
|
filtered = true;
|
|
450
666
|
} else if (options.only?.length) {
|
|
667
|
+
const componentPurl = comp.purl?.toLowerCase?.() || "";
|
|
451
668
|
if (!Array.isArray(options.only)) {
|
|
452
669
|
options.only = [options.only];
|
|
453
670
|
}
|
|
@@ -456,7 +673,7 @@ export function filterBom(bomJson, options) {
|
|
|
456
673
|
for (const filterstr of options.only) {
|
|
457
674
|
if (
|
|
458
675
|
filterstr.length &&
|
|
459
|
-
|
|
676
|
+
componentPurl.includes(filterstr.toLowerCase())
|
|
460
677
|
) {
|
|
461
678
|
filtered = true;
|
|
462
679
|
purlfiltered = false;
|
|
@@ -471,11 +688,12 @@ export function filterBom(bomJson, options) {
|
|
|
471
688
|
options.filter = [options.filter];
|
|
472
689
|
}
|
|
473
690
|
let purlfiltered = false;
|
|
691
|
+
const componentPurl = comp.purl?.toLowerCase?.() || "";
|
|
474
692
|
for (const filterstr of options.filter) {
|
|
475
693
|
// Check the purl
|
|
476
694
|
if (
|
|
477
695
|
filterstr.length &&
|
|
478
|
-
|
|
696
|
+
componentPurl.includes(filterstr.toLowerCase())
|
|
479
697
|
) {
|
|
480
698
|
filtered = true;
|
|
481
699
|
purlfiltered = true;
|
|
@@ -500,40 +718,59 @@ export function filterBom(bomJson, options) {
|
|
|
500
718
|
newPkgMap[comp["bom-ref"]] = comp;
|
|
501
719
|
}
|
|
502
720
|
}
|
|
721
|
+
for (const service of bomJson.services || []) {
|
|
722
|
+
if (shouldExcludeInventoryType(service, options)) {
|
|
723
|
+
filtered = true;
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
newServices.push(service);
|
|
727
|
+
}
|
|
503
728
|
if (filtered) {
|
|
504
729
|
if (!anyFiltered) {
|
|
505
730
|
anyFiltered = true;
|
|
506
731
|
}
|
|
507
732
|
const newcomponents = [];
|
|
508
733
|
const newdependencies = [];
|
|
734
|
+
const retainedRefs = new Set();
|
|
509
735
|
for (const aref of Object.keys(newPkgMap).sort()) {
|
|
510
736
|
newcomponents.push(newPkgMap[aref]);
|
|
737
|
+
retainedRefs.add(aref);
|
|
738
|
+
}
|
|
739
|
+
for (const service of newServices) {
|
|
740
|
+
if (service?.["bom-ref"]) {
|
|
741
|
+
retainedRefs.add(service["bom-ref"]);
|
|
742
|
+
}
|
|
511
743
|
}
|
|
512
744
|
if (bomJson.metadata?.component?.["bom-ref"]) {
|
|
513
745
|
newPkgMap[bomJson.metadata.component["bom-ref"]] =
|
|
514
746
|
bomJson.metadata.component;
|
|
747
|
+
retainedRefs.add(bomJson.metadata.component["bom-ref"]);
|
|
515
748
|
}
|
|
516
749
|
if (bomJson.metadata?.component?.components) {
|
|
517
750
|
for (const comp of bomJson.metadata.component.components) {
|
|
518
751
|
newPkgMap[comp["bom-ref"]] = comp;
|
|
752
|
+
retainedRefs.add(comp["bom-ref"]);
|
|
519
753
|
}
|
|
520
754
|
}
|
|
521
|
-
for (const adep of bomJson.dependencies) {
|
|
522
|
-
if (
|
|
523
|
-
const newdepson = (adep.dependsOn || []).filter((d) =>
|
|
755
|
+
for (const adep of bomJson.dependencies || []) {
|
|
756
|
+
if (retainedRefs.has(adep.ref)) {
|
|
757
|
+
const newdepson = (adep.dependsOn || []).filter((d) =>
|
|
758
|
+
retainedRefs.has(d),
|
|
759
|
+
);
|
|
524
760
|
const obj = {
|
|
525
761
|
ref: adep.ref,
|
|
526
762
|
dependsOn: newdepson,
|
|
527
763
|
};
|
|
528
764
|
// Filter provides array if needed
|
|
529
765
|
if (adep.provides?.length) {
|
|
530
|
-
obj.provides = adep.provides.filter((d) =>
|
|
766
|
+
obj.provides = adep.provides.filter((d) => retainedRefs.has(d));
|
|
531
767
|
}
|
|
532
768
|
newdependencies.push(obj);
|
|
533
769
|
}
|
|
534
770
|
}
|
|
535
771
|
bomJson.components = newcomponents;
|
|
536
772
|
bomJson.dependencies = newdependencies;
|
|
773
|
+
bomJson.services = newServices;
|
|
537
774
|
// We set the compositions.aggregate to incomplete by default
|
|
538
775
|
if (
|
|
539
776
|
options.specVersion >= 1.5 &&
|
|
@@ -571,12 +808,23 @@ export function filterBom(bomJson, options) {
|
|
|
571
808
|
return bomJson;
|
|
572
809
|
}
|
|
573
810
|
|
|
811
|
+
function shouldExcludeInventoryType(subject, options) {
|
|
812
|
+
return AI_INVENTORY_PROJECT_TYPES.some(
|
|
813
|
+
(type) =>
|
|
814
|
+
optionIncludesAiInventoryProjectType(options?.excludeType, type) &&
|
|
815
|
+
matchesAiInventoryExcludeType(subject, type),
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
|
|
574
819
|
/**
|
|
575
820
|
* Clean up
|
|
576
821
|
*/
|
|
577
822
|
export function cleanupEnv(_options) {
|
|
823
|
+
if (isDryRun) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
578
826
|
if (process.env?.PIP_TARGET?.startsWith(getTmpDir())) {
|
|
579
|
-
|
|
827
|
+
safeRmSync(process.env.PIP_TARGET, { recursive: true, force: true });
|
|
580
828
|
}
|
|
581
829
|
}
|
|
582
830
|
|
|
@@ -588,8 +836,11 @@ export function cleanupEnv(_options) {
|
|
|
588
836
|
* @returns {void}
|
|
589
837
|
*/
|
|
590
838
|
export function cleanupTmpDir() {
|
|
839
|
+
if (isDryRun) {
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
591
842
|
if (process.env?.CDXGEN_TMP_DIR?.startsWith(getTmpDir())) {
|
|
592
|
-
|
|
843
|
+
safeRmSync(process.env.CDXGEN_TMP_DIR, { recursive: true, force: true });
|
|
593
844
|
}
|
|
594
845
|
}
|
|
595
846
|
|