@cyclonedx/cdxgen 10.3.4 → 10.4.0

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/evinser.js CHANGED
@@ -1,3 +1,11 @@
1
+ import fs from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import path from "node:path";
4
+ import process from "node:process";
5
+ import { PackageURL } from "packageurl-js";
6
+ import { Op } from "sequelize";
7
+ import { findCryptoAlgos } from "./cbomutils.js";
8
+ import * as db from "./db.js";
1
9
  import {
2
10
  DEBUG_MODE,
3
11
  collectGradleDependencies,
@@ -5,16 +13,9 @@ import {
5
13
  executeAtom,
6
14
  getAllFiles,
7
15
  getGradleCommand,
8
- getMavenCommand
16
+ getMavenCommand,
17
+ getTimestamp,
9
18
  } from "./utils.js";
10
- import { findCryptoAlgos } from "./cbomutils.js";
11
- import { tmpdir } from "node:os";
12
- import path from "node:path";
13
- import fs from "node:fs";
14
- import * as db from "./db.js";
15
- import { PackageURL } from "packageurl-js";
16
- import { Op } from "sequelize";
17
- import process from "node:process";
18
19
  const DB_NAME = "evinser.db";
19
20
  const typePurlsCache = {};
20
21
 
@@ -35,11 +36,11 @@ export const prepareDB = async (options) => {
35
36
  const bomJsonFile = options.input;
36
37
  if (!fs.existsSync(bomJsonFile)) {
37
38
  console.log(
38
- "Bom file doesn't exist. Check if cdxgen was invoked with the correct type argument."
39
+ "Bom file doesn't exist. Check if cdxgen was invoked with the correct type argument.",
39
40
  );
40
41
  if (!process.env.CDXGEN_DEBUG_MODE) {
41
42
  console.log(
42
- "Set the environment variable CDXGEN_DEBUG_MODE to debug to troubleshoot the issue further."
43
+ "Set the environment variable CDXGEN_DEBUG_MODE to debug to troubleshoot the issue further.",
43
44
  );
44
45
  }
45
46
  return;
@@ -47,14 +48,14 @@ export const prepareDB = async (options) => {
47
48
  const bomJson = JSON.parse(fs.readFileSync(bomJsonFile, "utf8"));
48
49
  if (bomJson.specVersion < 1.5) {
49
50
  console.log(
50
- "Evinse requires the input SBOM in CycloneDX 1.5 format or above. You can generate one by invoking cdxgen without any --spec-version argument."
51
+ "Evinse requires the input SBOM in CycloneDX 1.5 format or above. You can generate one by invoking cdxgen without any --spec-version argument.",
51
52
  );
52
53
  process.exit(0);
53
54
  }
54
55
  const components = bomJson.components || [];
55
56
  const { sequelize, Namespaces, Usages, DataFlows } = await db.createOrLoad(
56
57
  DB_NAME,
57
- options.dbPath
58
+ options.dbPath,
58
59
  );
59
60
  let hasMavenPkgs = false;
60
61
  // We need to slice only non-maven packages
@@ -94,13 +95,13 @@ export const catalogMavenDeps = async (
94
95
  dirPath,
95
96
  purlsJars,
96
97
  Namespaces,
97
- options = {}
98
+ options = {},
98
99
  ) => {
99
100
  let jarNSMapping = undefined;
100
101
  if (fs.existsSync(path.join(dirPath, "bom.json.map"))) {
101
102
  try {
102
103
  const mapData = JSON.parse(
103
- fs.readFileSync(path.join(dirPath, "bom.json.map"), "utf-8")
104
+ fs.readFileSync(path.join(dirPath, "bom.json.map"), "utf-8"),
104
105
  );
105
106
  if (mapData && Object.keys(mapData).length) {
106
107
  jarNSMapping = mapData;
@@ -117,7 +118,7 @@ export const catalogMavenDeps = async (
117
118
  mavenCmd,
118
119
  dirPath,
119
120
  false,
120
- options.withDeepJarCollector
121
+ options.withDeepJarCollector,
121
122
  );
122
123
  }
123
124
  if (jarNSMapping) {
@@ -130,12 +131,12 @@ export const catalogMavenDeps = async (
130
131
  data: JSON.stringify(
131
132
  {
132
133
  pom: jarNSMapping[purl].pom,
133
- namespaces: jarNSMapping[purl].namespaces
134
+ namespaces: jarNSMapping[purl].namespaces,
134
135
  },
135
136
  null,
136
- null
137
- )
138
- }
137
+ null,
138
+ ),
139
+ },
139
140
  });
140
141
  }
141
142
  }
@@ -143,7 +144,7 @@ export const catalogMavenDeps = async (
143
144
 
144
145
  export const catalogGradleDeps = async (dirPath, purlsJars, Namespaces) => {
145
146
  console.log(
146
- "About to collect jar dependencies from the gradle cache. This would take a while ..."
147
+ "About to collect jar dependencies from the gradle cache. This would take a while ...",
147
148
  );
148
149
  const gradleCmd = getGradleCommand(dirPath, dirPath);
149
150
  // collect all jars including from the cache if data-flow mode is enabled
@@ -151,7 +152,7 @@ export const catalogGradleDeps = async (dirPath, purlsJars, Namespaces) => {
151
152
  gradleCmd,
152
153
  dirPath,
153
154
  false,
154
- true
155
+ true,
155
156
  );
156
157
  if (jarNSMapping) {
157
158
  for (const purl of Object.keys(jarNSMapping)) {
@@ -163,17 +164,17 @@ export const catalogGradleDeps = async (dirPath, purlsJars, Namespaces) => {
163
164
  data: JSON.stringify(
164
165
  {
165
166
  pom: jarNSMapping[purl].pom,
166
- namespaces: jarNSMapping[purl].namespaces
167
+ namespaces: jarNSMapping[purl].namespaces,
167
168
  },
168
169
  null,
169
- null
170
- )
171
- }
170
+ null,
171
+ ),
172
+ },
172
173
  });
173
174
  }
174
175
  }
175
176
  console.log(
176
- "To speed up successive re-runs, pass the argument --skip-maven-collector to evinse command."
177
+ "To speed up successive re-runs, pass the argument --skip-maven-collector to evinse command.",
177
178
  );
178
179
  };
179
180
 
@@ -181,7 +182,7 @@ export const createAndStoreSlice = async (
181
182
  purl,
182
183
  purlsJars,
183
184
  Usages,
184
- options = {}
185
+ options = {},
185
186
  ) => {
186
187
  const retMap = createSlice(purl, purlsJars[purl], "usages", options);
187
188
  let sliceData = undefined;
@@ -190,8 +191,8 @@ export const createAndStoreSlice = async (
190
191
  where: { purl },
191
192
  defaults: {
192
193
  purl,
193
- data: fs.readFileSync(retMap.slicesFile, "utf-8")
194
- }
194
+ data: fs.readFileSync(retMap.slicesFile, "utf-8"),
195
+ },
195
196
  });
196
197
  }
197
198
  if (retMap && retMap.tempDir && retMap.tempDir.startsWith(tmpdir())) {
@@ -204,13 +205,13 @@ export const createSlice = (
204
205
  purlOrLanguage,
205
206
  filePath,
206
207
  sliceType = "usages",
207
- options = {}
208
+ options = {},
208
209
  ) => {
209
210
  if (!filePath) {
210
211
  return;
211
212
  }
212
213
  console.log(
213
- `Create ${sliceType} slice for ${path.resolve(filePath)}. Please wait ...`
214
+ `Create ${sliceType} slice for ${path.resolve(filePath)}. Please wait ...`,
214
215
  );
215
216
  const language = purlOrLanguage.startsWith("pkg:")
216
217
  ? purlToLanguage(purlOrLanguage, filePath)
@@ -219,7 +220,7 @@ export const createSlice = (
219
220
  return undefined;
220
221
  }
221
222
  let sliceOutputDir = fs.mkdtempSync(
222
- path.join(tmpdir(), `atom-${sliceType}-`)
223
+ path.join(tmpdir(), `atom-${sliceType}-`),
223
224
  );
224
225
  if (options && options.output) {
225
226
  sliceOutputDir =
@@ -241,7 +242,7 @@ export const createSlice = (
241
242
  "-o",
242
243
  path.resolve(atomFile),
243
244
  "--slice-outfile",
244
- path.resolve(slicesFile)
245
+ path.resolve(slicesFile),
245
246
  ]);
246
247
  // For projects with several layers, slice depth needs to be increased from the default 7 to 15 or 20
247
248
  // This would increase the time but would yield more deeper paths
@@ -254,16 +255,16 @@ export const createSlice = (
254
255
  const result = executeAtom(filePath, args);
255
256
  if (!result || !fs.existsSync(slicesFile)) {
256
257
  console.warn(
257
- `Unable to generate ${sliceType} slice using atom. Check if this is a supported language.`
258
+ `Unable to generate ${sliceType} slice using atom. Check if this is a supported language.`,
258
259
  );
259
260
  console.log(
260
- "Set the environment variable CDXGEN_DEBUG_MODE=debug to troubleshoot."
261
+ "Set the environment variable CDXGEN_DEBUG_MODE=debug to troubleshoot.",
261
262
  );
262
263
  }
263
264
  return {
264
265
  tempDir: sliceOutputDir,
265
266
  slicesFile,
266
- atomFile
267
+ atomFile,
267
268
  };
268
269
  };
269
270
 
@@ -311,13 +312,13 @@ export const initFromSbom = (components, language) => {
311
312
  }
312
313
  if (comp.evidence.occurrences) {
313
314
  purlLocationMap[comp.purl] = new Set(
314
- comp.evidence.occurrences.map((v) => v.location)
315
+ comp.evidence.occurrences.map((v) => v.location),
315
316
  );
316
317
  }
317
318
  }
318
319
  return {
319
320
  purlLocationMap,
320
- purlImportsMap
321
+ purlImportsMap,
321
322
  };
322
323
  };
323
324
 
@@ -356,14 +357,14 @@ export const analyzeProject = async (dbObjMap, options) => {
356
357
  ) {
357
358
  reachablesSlicesFile = options.reachablesSlicesFile;
358
359
  reachablesSlice = JSON.parse(
359
- fs.readFileSync(options.reachablesSlicesFile, "utf-8")
360
+ fs.readFileSync(options.reachablesSlicesFile, "utf-8"),
360
361
  );
361
362
  } else {
362
363
  retMap = createSlice(language, dirPath, "reachables", options);
363
364
  if (retMap && retMap.slicesFile && fs.existsSync(retMap.slicesFile)) {
364
365
  reachablesSlicesFile = retMap.slicesFile;
365
366
  reachablesSlice = JSON.parse(
366
- fs.readFileSync(retMap.slicesFile, "utf-8")
367
+ fs.readFileSync(retMap.slicesFile, "utf-8"),
367
368
  );
368
369
  }
369
370
  }
@@ -393,7 +394,7 @@ export const analyzeProject = async (dbObjMap, options) => {
393
394
  dbObjMap,
394
395
  servicesMap,
395
396
  purlLocationMap,
396
- purlImportsMap
397
+ purlImportsMap,
397
398
  );
398
399
  purlLocationMap = retMap.purlLocationMap;
399
400
  servicesMap = retMap.servicesMap;
@@ -406,7 +407,7 @@ export const analyzeProject = async (dbObjMap, options) => {
406
407
  ) {
407
408
  dataFlowSlicesFile = options.dataFlowSlicesFile;
408
409
  dataFlowSlice = JSON.parse(
409
- fs.readFileSync(options.dataFlowSlicesFile, "utf-8")
410
+ fs.readFileSync(options.dataFlowSlicesFile, "utf-8"),
410
411
  );
411
412
  } else {
412
413
  retMap = createSlice(language, dirPath, "data-flow", options);
@@ -423,7 +424,7 @@ export const analyzeProject = async (dbObjMap, options) => {
423
424
  dataFlowSlice,
424
425
  dbObjMap,
425
426
  purlLocationMap,
426
- purlImportsMap
427
+ purlImportsMap,
427
428
  );
428
429
  }
429
430
  return {
@@ -437,7 +438,7 @@ export const analyzeProject = async (dbObjMap, options) => {
437
438
  tempDir: retMap.tempDir,
438
439
  userDefinedTypesMap,
439
440
  cryptoComponents,
440
- cryptoGeneratePurls
441
+ cryptoGeneratePurls,
441
442
  };
442
443
  };
443
444
 
@@ -447,7 +448,7 @@ export const parseObjectSlices = async (
447
448
  dbObjMap,
448
449
  servicesMap = {},
449
450
  purlLocationMap = {},
450
- purlImportsMap = {}
451
+ purlImportsMap = {},
451
452
  ) => {
452
453
  if (!usageSlice || !Object.keys(usageSlice).length) {
453
454
  return purlLocationMap;
@@ -458,7 +459,7 @@ export const parseObjectSlices = async (
458
459
  });
459
460
  for (const slice of [
460
461
  ...(usageSlice.objectSlices || []),
461
- ...(usageSlice.userDefinedTypes || [])
462
+ ...(usageSlice.userDefinedTypes || []),
462
463
  ]) {
463
464
  // Skip the library code typically without filename
464
465
  if (
@@ -475,7 +476,7 @@ export const parseObjectSlices = async (
475
476
  slice,
476
477
  dbObjMap,
477
478
  purlLocationMap,
478
- purlImportsMap
479
+ purlImportsMap,
479
480
  );
480
481
  detectServicesFromUsages(language, slice, servicesMap);
481
482
  }
@@ -483,7 +484,7 @@ export const parseObjectSlices = async (
483
484
  return {
484
485
  purlLocationMap,
485
486
  servicesMap,
486
- userDefinedTypesMap
487
+ userDefinedTypesMap,
487
488
  };
488
489
  };
489
490
 
@@ -505,7 +506,7 @@ export const parseSliceUsages = async (
505
506
  slice,
506
507
  dbObjMap,
507
508
  purlLocationMap,
508
- purlImportsMap
509
+ purlImportsMap,
509
510
  ) => {
510
511
  const fileName = slice.fileName;
511
512
  const typesToLookup = new Set();
@@ -530,7 +531,7 @@ export const parseSliceUsages = async (
530
531
  [ausage?.targetObj?.isExternal, ausage?.targetObj?.resolvedMethod],
531
532
  [ausage?.definedBy?.isExternal, ausage?.definedBy?.typeFullName],
532
533
  [ausage?.definedBy?.isExternal, ausage?.definedBy?.resolvedMethod],
533
- ...(ausage?.fields || []).map((f) => [f?.isExternal, f?.typeFullName])
534
+ ...(ausage?.fields || []).map((f) => [f?.isExternal, f?.typeFullName]),
534
535
  ]) {
535
536
  if (
536
537
  atype[0] !== false &&
@@ -545,7 +546,7 @@ export const parseSliceUsages = async (
545
546
  ) {
546
547
  if (atype[1].includes(":")) {
547
548
  typesToLookup.add(
548
- simplifyType(atype[1].split("::")[0].replace(/:/g, "/"))
549
+ simplifyType(atype[1].split("::")[0].replace(/:/g, "/")),
549
550
  );
550
551
  }
551
552
  addToOverrides(lKeyOverrides, atype[1], fileName, ausageLine);
@@ -570,7 +571,7 @@ export const parseSliceUsages = async (
570
571
  lKeyOverrides,
571
572
  acall.callName,
572
573
  fileName,
573
- acall.lineNumber
574
+ acall.lineNumber,
574
575
  );
575
576
  }
576
577
  } else if (acall.isExternal == false) {
@@ -590,13 +591,13 @@ export const parseSliceUsages = async (
590
591
  lKeyOverrides,
591
592
  acall?.resolvedMethod,
592
593
  fileName,
593
- acall.lineNumber
594
+ acall.lineNumber,
594
595
  );
595
596
  }
596
597
  }
597
598
  const maybeClassType = getClassTypeFromSignature(
598
599
  language,
599
- acall?.resolvedMethod
600
+ acall?.resolvedMethod,
600
601
  );
601
602
  typesToLookup.add(maybeClassType);
602
603
  if (acall.lineNumber) {
@@ -604,7 +605,7 @@ export const parseSliceUsages = async (
604
605
  lKeyOverrides,
605
606
  maybeClassType,
606
607
  fileName,
607
- acall.lineNumber
608
+ acall.lineNumber,
608
609
  );
609
610
  }
610
611
  }
@@ -615,20 +616,20 @@ export const parseSliceUsages = async (
615
616
  if (acall.lineNumber) {
616
617
  if (aparamType.includes(":")) {
617
618
  typesToLookup.add(
618
- simplifyType(aparamType.split("::")[0].replace(/:/g, "/"))
619
+ simplifyType(aparamType.split("::")[0].replace(/:/g, "/")),
619
620
  );
620
621
  }
621
622
  addToOverrides(
622
623
  lKeyOverrides,
623
624
  aparamType,
624
625
  fileName,
625
- acall.lineNumber
626
+ acall.lineNumber,
626
627
  );
627
628
  }
628
629
  }
629
630
  const maybeClassType = getClassTypeFromSignature(
630
631
  language,
631
- aparamType
632
+ aparamType,
632
633
  );
633
634
  typesToLookup.add(maybeClassType);
634
635
  if (acall.lineNumber) {
@@ -636,7 +637,7 @@ export const parseSliceUsages = async (
636
637
  lKeyOverrides,
637
638
  maybeClassType,
638
639
  fileName,
639
- acall.lineNumber
640
+ acall.lineNumber,
640
641
  );
641
642
  }
642
643
  }
@@ -680,9 +681,9 @@ export const parseSliceUsages = async (
680
681
  attributes: ["purl"],
681
682
  where: {
682
683
  data: {
683
- [Op.like]: `%${atype}%`
684
- }
685
- }
684
+ [Op.like]: `%${atype}%`,
685
+ },
686
+ },
686
687
  });
687
688
  }
688
689
  if (nsHits && nsHits.length) {
@@ -706,7 +707,7 @@ export const parseSliceUsages = async (
706
707
  export const isFilterableType = (
707
708
  language,
708
709
  userDefinedTypesMap,
709
- typeFullName
710
+ typeFullName,
710
711
  ) => {
711
712
  if (
712
713
  !typeFullName ||
@@ -720,7 +721,7 @@ export const isFilterableType = (
720
721
  "<unknownFullName",
721
722
  "__builtin",
722
723
  "LAMBDA",
723
- "../"
724
+ "../",
724
725
  ]) {
725
726
  if (typeFullName.startsWith(ab)) {
726
727
  return true;
@@ -811,7 +812,7 @@ export const detectServicesFromUsages = (language, slice, servicesMap = {}) => {
811
812
  if (language != "php") {
812
813
  const tmpEndpoints = extractEndpoints(
813
814
  language,
814
- acall.resolvedMethod
815
+ acall.resolvedMethod,
815
816
  );
816
817
  if (acall.resolvedMethod.toLowerCase().includes("auth")) {
817
818
  authenticated = true;
@@ -829,7 +830,7 @@ export const detectServicesFromUsages = (language, slice, servicesMap = {}) => {
829
830
  servicesMap[serviceName] = {
830
831
  endpoints: new Set(),
831
832
  authenticated,
832
- xTrustBoundary: authenticated === true ? true : undefined
833
+ xTrustBoundary: authenticated === true ? true : undefined,
833
834
  };
834
835
  }
835
836
  for (const endpoint of endpoints) {
@@ -849,7 +850,7 @@ export const detectServicesFromUsages = (language, slice, servicesMap = {}) => {
849
850
  export const detectServicesFromUDT = (
850
851
  language,
851
852
  userDefinedTypes,
852
- servicesMap
853
+ servicesMap,
853
854
  ) => {
854
855
  if (
855
856
  ["python", "py", "c", "cpp", "c++", "php"].includes(language) &&
@@ -885,7 +886,7 @@ export const detectServicesFromUDT = (
885
886
  let serviceName = "service";
886
887
  if (audt.fileName) {
887
888
  serviceName = `${path.basename(
888
- audt.fileName.replace(".py", "")
889
+ audt.fileName.replace(".py", ""),
889
890
  )}-service`;
890
891
  }
891
892
  if (endpoints && endpoints.length) {
@@ -893,7 +894,7 @@ export const detectServicesFromUDT = (
893
894
  servicesMap[serviceName] = {
894
895
  endpoints: new Set(),
895
896
  authenticated: false,
896
- xTrustBoundary: undefined
897
+ xTrustBoundary: undefined,
897
898
  };
898
899
  }
899
900
  for (const endpoint of endpoints) {
@@ -940,7 +941,7 @@ export const extractEndpoints = (language, code) => {
940
941
  v.length &&
941
942
  !v.startsWith(".") &&
942
943
  v.includes("/") &&
943
- !v.startsWith("@")
944
+ !v.startsWith("@"),
944
945
  );
945
946
  }
946
947
  break;
@@ -959,7 +960,7 @@ export const extractEndpoints = (language, code) => {
959
960
  v.includes("/") &&
960
961
  !v.startsWith("@") &&
961
962
  !v.startsWith("application/") &&
962
- !v.startsWith("text/")
963
+ !v.startsWith("text/"),
963
964
  );
964
965
  }
965
966
  break;
@@ -989,7 +990,7 @@ export const createEvinseFile = (sliceArtefacts, options) => {
989
990
  servicesMap,
990
991
  dataFlowFrames,
991
992
  cryptoComponents,
992
- cryptoGeneratePurls
993
+ cryptoGeneratePurls,
993
994
  } = sliceArtefacts;
994
995
  const bomFile = options.input;
995
996
  const evinseOutFile = options.output;
@@ -1004,7 +1005,7 @@ export const createEvinseFile = (sliceArtefacts, options) => {
1004
1005
  }
1005
1006
  delete comp.signature;
1006
1007
  const locationOccurrences = Array.from(
1007
- purlLocationMap[comp.purl] || []
1008
+ purlLocationMap[comp.purl] || [],
1008
1009
  ).sort();
1009
1010
  if (locationOccurrences.length) {
1010
1011
  if (!comp.evidence) {
@@ -1015,7 +1016,7 @@ export const createEvinseFile = (sliceArtefacts, options) => {
1015
1016
  comp.evidence.occurrences = locationOccurrences
1016
1017
  .filter((l) => !!l)
1017
1018
  .map((l) => ({
1018
- location: l
1019
+ location: l,
1019
1020
  }));
1020
1021
  occEvidencePresent = true;
1021
1022
  }
@@ -1048,7 +1049,7 @@ export const createEvinseFile = (sliceArtefacts, options) => {
1048
1049
  name: serviceName,
1049
1050
  endpoints: Array.from(servicesMap[serviceName].endpoints),
1050
1051
  authenticated: servicesMap[serviceName].authenticated,
1051
- "x-trust-boundary": servicesMap[serviceName].xTrustBoundary
1052
+ "x-trust-boundary": servicesMap[serviceName].xTrustBoundary,
1052
1053
  });
1053
1054
  }
1054
1055
  // Add to existing services
@@ -1085,38 +1086,38 @@ export const createEvinseFile = (sliceArtefacts, options) => {
1085
1086
  bomJson.annotations.push({
1086
1087
  subjects: [bomJson.serialNumber],
1087
1088
  annotator: { component: bomJson.metadata.tools.components[0] },
1088
- timestamp: new Date().toISOString(),
1089
- text: fs.readFileSync(usagesSlicesFile, "utf8")
1089
+ timestamp: getTimestamp(),
1090
+ text: fs.readFileSync(usagesSlicesFile, "utf8"),
1090
1091
  });
1091
1092
  }
1092
1093
  if (dataFlowSlicesFile && fs.existsSync(dataFlowSlicesFile)) {
1093
1094
  bomJson.annotations.push({
1094
1095
  subjects: [bomJson.serialNumber],
1095
1096
  annotator: { component: bomJson.metadata.tools.components[0] },
1096
- timestamp: new Date().toISOString(),
1097
- text: fs.readFileSync(dataFlowSlicesFile, "utf8")
1097
+ timestamp: getTimestamp(),
1098
+ text: fs.readFileSync(dataFlowSlicesFile, "utf8"),
1098
1099
  });
1099
1100
  }
1100
1101
  if (reachablesSlicesFile && fs.existsSync(reachablesSlicesFile)) {
1101
1102
  bomJson.annotations.push({
1102
1103
  subjects: [bomJson.serialNumber],
1103
1104
  annotator: { component: bomJson.metadata.tools.components[0] },
1104
- timestamp: new Date().toISOString(),
1105
- text: fs.readFileSync(reachablesSlicesFile, "utf8")
1105
+ timestamp: getTimestamp(),
1106
+ text: fs.readFileSync(reachablesSlicesFile, "utf8"),
1106
1107
  });
1107
1108
  }
1108
1109
  }
1109
1110
  // Increment the version
1110
1111
  bomJson.version = (bomJson.version || 1) + 1;
1111
1112
  // Set the current timestamp to indicate this is newer
1112
- bomJson.metadata.timestamp = new Date().toISOString();
1113
+ bomJson.metadata.timestamp = getTimestamp();
1113
1114
  delete bomJson.signature;
1114
1115
  fs.writeFileSync(evinseOutFile, JSON.stringify(bomJson, null, null));
1115
1116
  if (occEvidencePresent || csEvidencePresent || servicesPresent) {
1116
1117
  console.log(evinseOutFile, "created successfully.");
1117
1118
  } else {
1118
1119
  console.log(
1119
- "Unable to identify component evidence for the input SBOM. Only java, javascript, python, and php projects are supported by evinse."
1120
+ "Unable to identify component evidence for the input SBOM. Only java, javascript, python, and php projects are supported by evinse.",
1120
1121
  );
1121
1122
  }
1122
1123
  if (tempDir && tempDir.startsWith(tmpdir())) {
@@ -1142,7 +1143,7 @@ export const collectDataFlowFrames = async (
1142
1143
  dataFlowSlice,
1143
1144
  dbObjMap,
1144
1145
  purlLocationMap,
1145
- purlImportsMap
1146
+ purlImportsMap,
1146
1147
  ) => {
1147
1148
  const nodes = dataFlowSlice?.graph?.nodes || [];
1148
1149
  // Cache the nodes based on the id to improve lookup
@@ -1199,9 +1200,9 @@ export const collectDataFlowFrames = async (
1199
1200
  attributes: ["purl"],
1200
1201
  where: {
1201
1202
  data: {
1202
- [Op.like]: `%${typeFullName}%`
1203
- }
1204
- }
1203
+ [Op.like]: `%${typeFullName}%`,
1204
+ },
1205
+ },
1205
1206
  });
1206
1207
  }
1207
1208
  if (nsHits && nsHits.length) {
@@ -1235,7 +1236,7 @@ export const collectDataFlowFrames = async (
1235
1236
  function: theNode.parentMethodName || "",
1236
1237
  line: theNode.lineNumber || undefined,
1237
1238
  column: theNode.columnNumber || undefined,
1238
- fullFilename: theNode.parentFileName || ""
1239
+ fullFilename: theNode.parentFileName || "",
1239
1240
  });
1240
1241
  }
1241
1242
  referredPurls = Array.from(referredPurls);
@@ -1298,7 +1299,7 @@ export const collectReachableFrames = (language, reachablesSlice) => {
1298
1299
  function: fnode.parentMethodName || "",
1299
1300
  line: fnode.lineNumber || undefined,
1300
1301
  column: fnode.columnNumber || undefined,
1301
- fullFilename: fnode.parentFileName || ""
1302
+ fullFilename: fnode.parentFileName || "",
1302
1303
  });
1303
1304
  }
1304
1305
  referredPurls = Array.from(referredPurls);
@@ -1332,14 +1333,14 @@ export const collectReachableFrames = (language, reachablesSlice) => {
1332
1333
  description: algoObj.description || "",
1333
1334
  cryptoProperties: {
1334
1335
  assetType: "algorithm",
1335
- oid: algoObj.oid
1336
- }
1336
+ oid: algoObj.oid,
1337
+ },
1337
1338
  });
1338
1339
  }
1339
1340
  return {
1340
1341
  dataFlowFrames: dfFrames,
1341
1342
  cryptoComponents,
1342
- cryptoGeneratePurls
1343
+ cryptoGeneratePurls,
1343
1344
  };
1344
1345
  };
1345
1346