retire 4.1.0 → 4.2.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/CHANGELOG.md CHANGED
@@ -1,28 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.2.0]
4
+
5
+ ### Changes
6
+
7
+ - Use prettier to get formatting of code
8
+ - Add provenance
9
+
10
+ ## Security fixes
11
+
12
+ - Upgrade dependencies
13
+
14
+ ## [4.1.1]
15
+
16
+ ### Bugfixes
17
+
18
+ - Handle error if OSV does not have library or version
3
19
 
4
20
  ## [4.1.0]
5
21
 
6
22
  ### Additions
23
+
7
24
  - Option to check results for the component from OSV
8
25
  - Option to use more than one JS repository
9
26
 
10
27
  ### Bugfixes
28
+
11
29
  - Remove dropexternal as it never worked
12
30
 
13
31
  ## [4.0.1]
14
32
 
15
33
  ### Breaking changes
34
+
16
35
  - Not really a breaking change as the change was introduced in 4.0.0, but node.js >= 14.0.0 is required to run retire.js >= 4.0.0 going forward
17
36
 
18
37
  ## [4.0.0]
19
38
 
20
39
  ### Breaking changes
40
+
21
41
  - npm scanning no longer supported
22
42
 
23
43
  ### Changes
24
- - Complete rewrite to typescript
25
44
 
45
+ - Complete rewrite to typescript
26
46
 
27
47
  ## [3.2.3]
28
48
 
@@ -64,7 +84,6 @@
64
84
 
65
85
  - Updating proxy library to fix proxy issues
66
86
 
67
-
68
87
  ## [3.0.6]
69
88
 
70
89
  ### Security
package/lib/cli.js CHANGED
@@ -45,8 +45,8 @@ const z = __importStar(require("zod"));
45
45
  const events = new events_1.EventEmitter();
46
46
  let failProcess = false;
47
47
  const defaultIgnoreFiles = ['.retireignore', '.retireignore.json'];
48
- if (process.argv.includes("--node") || process.argv.includes("-n")) {
49
- console.log("Error: retire.js no longer supports scanning node packages. Use npm audit instead.");
48
+ if (process.argv.includes('--node') || process.argv.includes('-n')) {
49
+ console.log('Error: retire.js no longer supports scanning node packages. Use npm audit instead.');
50
50
  process.exit(1);
51
51
  }
52
52
  /*
@@ -58,7 +58,7 @@ const prg = commander_1.program
58
58
  .option('-c, --nocache', "Don't use local cache")
59
59
  .option('--jspath <path>', 'Folder to scan for javascript files')
60
60
  .option('--path <path>', 'Folder to scan for both')
61
- .option('--jsrepo <path|url>', 'Local or internal version of repo. Can be multiple comma separated. Default: \'central\')')
61
+ .option('--jsrepo <path|url>', "Local or internal version of repo. Can be multiple comma separated. Default: 'central')")
62
62
  .option('--cachedir <path>', 'Path to use for local cache instead of /tmp/.retire-cache')
63
63
  .option('--proxy <url>', 'Proxy url (http://some.host:8080)')
64
64
  .option('--outputformat <format>', 'Valid formats: text, json, jsonsimple, depcheck (experimental), cyclonedx and cyclonedxJSON')
@@ -75,29 +75,30 @@ const prg = commander_1.program
75
75
  .parse()
76
76
  .opts();
77
77
  const colorwarn = prg.colors ? ansi_colors_1.default.red : (x) => x;
78
- const jsrepolocation = ((_a = prg.jsrepo) !== null && _a !== void 0 ? _a : "'central'").split(",")
79
- .map((x) => x === "'central'" ? "https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/jsrepository.json" : x);
78
+ const jsrepolocation = ((_a = prg.jsrepo) !== null && _a !== void 0 ? _a : "'central'")
79
+ .split(',')
80
+ .map((x) => x === "'central'" ? 'https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/jsrepository.json' : x);
80
81
  const ignorefile = (_b = prg.ignoreFile) !== null && _b !== void 0 ? _b : defaultIgnoreFiles.filter((x) => fs_1.default.existsSync(x))[0];
81
- const scanpath = (_c = prg.path) !== null && _c !== void 0 ? _c : ".";
82
+ const scanpath = (_c = prg.path) !== null && _c !== void 0 ? _c : '.';
82
83
  const log = reporting.open({
83
84
  colors: !!prg.colors,
84
85
  colorwarn,
85
- jsRepo: jsrepolocation.join(", "),
86
+ jsRepo: jsrepolocation.join(', '),
86
87
  outputformat: prg.outputformat,
87
88
  outputpath: prg.outputpath,
88
89
  path: scanpath,
89
90
  verbose: !!prg.verbose,
90
91
  });
91
- const severity = (_d = prg.severity) !== null && _d !== void 0 ? _d : "none";
92
+ const severity = (_d = prg.severity) !== null && _d !== void 0 ? _d : 'none';
92
93
  if (!(severity in types_1.severityLevels)) {
93
94
  exitWithError(`Error: Invalid severity level (${severity}). Valid levels are: ${Object.keys(types_1.severityLevels).join(', ')}`);
94
95
  }
95
96
  const config = {
96
97
  path: scanpath,
97
98
  ignore: {
98
- paths: (_g = (_f = (_e = prg.ignore) === null || _e === void 0 ? void 0 : _e.split(",")) === null || _f === void 0 ? void 0 : _f.map((x) => path_1.default.resolve(x))) !== null && _g !== void 0 ? _g : [],
99
+ paths: (_g = (_f = (_e = prg.ignore) === null || _e === void 0 ? void 0 : _e.split(',')) === null || _f === void 0 ? void 0 : _f.map((x) => path_1.default.resolve(x))) !== null && _g !== void 0 ? _g : [],
99
100
  pathsAsString: [],
100
- descriptors: []
101
+ descriptors: [],
101
102
  },
102
103
  colorwarn,
103
104
  nocache: prg.nocache ? true : false,
@@ -120,11 +121,15 @@ if (prg.cacert) {
120
121
  }
121
122
  config.cacertbuf = fs_1.default.readFileSync(prg.cacert);
122
123
  }
123
- const ignoreFileParser = z.array(z.object({
124
- justification: z.string()
125
- }).and(z.object({
124
+ const ignoreFileParser = z.array(z
125
+ .object({
126
+ justification: z.string(),
127
+ })
128
+ .and(z
129
+ .object({
126
130
  path: z.string(),
127
- }).or(z.object({
131
+ })
132
+ .or(z.object({
128
133
  component: z.string(),
129
134
  version: z.string().optional(),
130
135
  identifiers: z.record(z.string(), z.string()).optional(),
@@ -133,35 +138,41 @@ if (ignorefile) {
133
138
  if (!fs_1.default.existsSync(ignorefile)) {
134
139
  exitWithError(`Error: Could not read ignore file: ${ignorefile}`);
135
140
  }
136
- if (ignorefile.substr(-5) === ".json") {
141
+ if (ignorefile.substr(-5) === '.json') {
137
142
  try {
138
- config.ignore.descriptors = ignoreFileParser.parse(JSON.parse(fs_1.default.readFileSync(ignorefile, "utf-8")));
143
+ config.ignore.descriptors = ignoreFileParser.parse(JSON.parse(fs_1.default.readFileSync(ignorefile, 'utf-8')));
139
144
  }
140
145
  catch (e) {
141
146
  exitWithError(`Error: Invalid ignore file: ${ignorefile}`);
142
147
  }
143
- const ignoredPaths = (_m = (_l = (_k = config.ignore.descriptors) === null || _k === void 0 ? void 0 : _k.map((x) => "path" in x ? x.path : undefined)) === null || _l === void 0 ? void 0 : _l.filter((x) => x != undefined)) !== null && _m !== void 0 ? _m : [];
148
+ const ignoredPaths = (_m = (_l = (_k = config.ignore.descriptors) === null || _k === void 0 ? void 0 : _k.map((x) => ('path' in x ? x.path : undefined))) === null || _l === void 0 ? void 0 : _l.filter((x) => x != undefined)) !== null && _m !== void 0 ? _m : [];
144
149
  config.ignore.pathsAsString = config.ignore.pathsAsString.concat(ignoredPaths);
145
150
  }
146
151
  else {
147
- const lines = fs_1.default.readFileSync(ignorefile, "utf-8").split(/\r\n|\n/g).filter((e) => e !== '');
148
- const ignored = lines.map(e => { return e[0] === '@' ? e.slice(1) : path_1.default.resolve(e); });
152
+ const lines = fs_1.default
153
+ .readFileSync(ignorefile, 'utf-8')
154
+ .split(/\r\n|\n/g)
155
+ .filter((e) => e !== '');
156
+ const ignored = lines.map((e) => {
157
+ return e[0] === '@' ? e.slice(1) : path_1.default.resolve(e);
158
+ });
149
159
  config.ignore.pathsAsString = config.ignore.pathsAsString.concat(ignored);
150
160
  }
151
161
  }
152
162
  config.ignore.paths = config.ignore.pathsAsString
153
- .map(p => p.replace(/[.+?^${}()|[\]\\]/g, '\\$&'))
154
- .map(p => p.replace(/[*]{1,2}/g, (a) => a.length == 2 ? ".*" : "[^/]*"))
155
- .map(s => new RegExp(s));
163
+ .map((p) => p.replace(/[.+?^${}()|[\]\\]/g, '\\$&'))
164
+ .map((p) => p.replace(/[*]{1,2}/g, (a) => (a.length == 2 ? '.*' : '[^/]*')))
165
+ .map((s) => new RegExp(s));
156
166
  scanner.on('vulnerable-dependency-found', (result) => {
157
- const levels = result.results
158
- .map((r) => {
159
- return r.vulnerabilities ? r.vulnerabilities.map((v) => {
160
- var _a;
161
- return types_1.severityLevels[(_a = v.severity) !== null && _a !== void 0 ? _a : 'critical'];
162
- }) : [];
167
+ const levels = result.results.map((r) => {
168
+ return r.vulnerabilities
169
+ ? r.vulnerabilities.map((v) => {
170
+ var _a;
171
+ return types_1.severityLevels[(_a = v.severity) !== null && _a !== void 0 ? _a : 'critical'];
172
+ })
173
+ : [];
163
174
  });
164
- const severity = utils.flatten(levels).reduce((x, y) => x > y ? x : y);
175
+ const severity = utils.flatten(levels).reduce((x, y) => (x > y ? x : y));
165
176
  if (severity >= types_1.severityLevels[config.severity]) {
166
177
  failProcess = true;
167
178
  }
@@ -180,10 +191,10 @@ process.on('uncaughtException', (err, ...rest) => {
180
191
  events.on('stop', (err) => {
181
192
  exitWithError(err);
182
193
  });
183
- Promise.all(jsrepolocation.map((jsr) => (jsr.match(/^https?:\/\//)
184
- ? repo.loadrepository(jsr, config)
185
- : repo.loadrepositoryFromFile(jsr, config)))).then((jsRepos) => {
186
- resolve.scanJsFiles(config.path, config)
194
+ Promise.all(jsrepolocation.map((jsr) => jsr.match(/^https?:\/\//) ? repo.loadrepository(jsr, config) : repo.loadrepositoryFromFile(jsr, config)))
195
+ .then((jsRepos) => {
196
+ resolve
197
+ .scanJsFiles(config.path, config)
187
198
  .on('jsfile', (file) => {
188
199
  jsRepos.forEach((jsRepo) => {
189
200
  scanner.scanJsFile(file, jsRepo, config);
@@ -198,4 +209,5 @@ Promise.all(jsrepolocation.map((jsr) => (jsr.match(/^https?:\/\//)
198
209
  .on('end', () => {
199
210
  events.emit('scan-done');
200
211
  });
201
- }).catch((e) => events.emit('stop', e));
212
+ })
213
+ .catch((e) => events.emit('stop', e));
package/lib/depsdev.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { Options } from "./types";
2
- import { Vulnerability } from "./types";
1
+ import { Options } from './types';
2
+ import { Vulnerability } from './types';
3
3
  export declare function checkOSV(packageName: string, version: string, options: Options): Promise<Vulnerability[]>;
package/lib/depsdev.js CHANGED
@@ -16,17 +16,22 @@ exports.checkOSV = void 0;
16
16
  const https_1 = __importDefault(require("https"));
17
17
  const retire_1 = require("./retire");
18
18
  function loadJson(url, options) {
19
- options.log.debug("Downloading " + url + " ...");
19
+ options.log.debug('Downloading ' + url + ' ...');
20
20
  return new Promise((resolve, reject) => {
21
- const req = https_1.default.request(url, res => {
21
+ const req = https_1.default.request(url, (res) => {
22
+ if (res.statusCode == 404)
23
+ return resolve(undefined);
24
+ if (res.statusCode != 200) {
25
+ return reject('HTTP ' + res.statusCode + ' ' + res.statusMessage + ' for ' + url);
26
+ }
22
27
  const data = [];
23
- res.on('data', c => data.push(c));
28
+ res.on('data', (c) => data.push(c));
24
29
  res.on('end', () => {
25
30
  const result = Buffer.concat(data).toString();
26
31
  resolve(JSON.parse(result));
27
32
  });
28
33
  });
29
- req.on('error', err => {
34
+ req.on('error', (err) => {
30
35
  reject(err);
31
36
  });
32
37
  req.end();
@@ -37,42 +42,58 @@ function getVulnerabilities(packageName, version, options) {
37
42
  }
38
43
  function scoreToSeverity(score) {
39
44
  if (score > 7)
40
- return "high";
45
+ return 'high';
41
46
  if (score > 4)
42
- return "medium";
43
- return "low";
47
+ return 'medium';
48
+ return 'low';
44
49
  }
45
50
  function loadAdvisory(packageName, version, id, options) {
46
51
  return __awaiter(this, void 0, void 0, function* () {
47
52
  const osvAdvisory = yield loadJson(`https://api.osv.dev/v1/vulns/${id}`, options);
48
53
  const advisory = yield loadJson(`https://api.deps.dev/v3alpha/advisories/${id}`, options);
54
+ if (!advisory || !osvAdvisory)
55
+ return [];
49
56
  const simplifiedRepo = {
50
57
  [packageName]: {
51
- vulnerabilities: osvAdvisory.affected.map(({ ranges }) => ranges.map(({ events }) => ({
52
- atOrAbove: events[0].introduced,
53
- below: events[0].fixed,
54
- severity: scoreToSeverity(advisory.cvss3Score),
55
- identifiers: {
56
- githubID: id,
57
- CVE: osvAdvisory.aliases.filter(x => x.startsWith("CVE-")),
58
- summary: advisory.title
59
- },
60
- info: osvAdvisory.references.map(({ url }) => url)
61
- }))).reduce((a, b) => a.concat(b), []),
62
- extractors: {}
63
- }
58
+ vulnerabilities: osvAdvisory.affected
59
+ .map(({ ranges }) => ranges.map(({ events }) => {
60
+ var _a, _b;
61
+ return ({
62
+ atOrAbove: events[0].introduced,
63
+ below: events[0].fixed,
64
+ severity: scoreToSeverity(advisory.cvss3Score),
65
+ cwe: (_b = (_a = osvAdvisory.database_specific) === null || _a === void 0 ? void 0 : _a.cwe_ids) !== null && _b !== void 0 ? _b : [],
66
+ identifiers: {
67
+ githubID: id,
68
+ CVE: osvAdvisory.aliases.filter((x) => x.startsWith('CVE-')),
69
+ summary: advisory.title,
70
+ },
71
+ info: osvAdvisory.references.map(({ url }) => url),
72
+ });
73
+ }))
74
+ .reduce((a, b) => a.concat(b), []),
75
+ extractors: {},
76
+ },
64
77
  };
65
78
  return (0, retire_1.check)(packageName, version, simplifiedRepo);
66
79
  });
67
80
  }
68
81
  function checkOSV(packageName, version, options) {
69
82
  return __awaiter(this, void 0, void 0, function* () {
70
- const versionInfo = yield getVulnerabilities(packageName, version, options);
71
- if (versionInfo.advisoryKeys.length == 0)
83
+ try {
84
+ const versionInfo = yield getVulnerabilities(packageName, version, options);
85
+ if (!versionInfo)
86
+ return [];
87
+ if (versionInfo.advisoryKeys.length == 0)
88
+ return [];
89
+ const comps = yield Promise.all(versionInfo.advisoryKeys.map(({ id }) => loadAdvisory(packageName, version, id, options)));
90
+ const flattened = comps.reduce((a, b) => a.concat(b), []);
91
+ return flattened.map((x) => { var _a; return (_a = x.vulnerabilities) !== null && _a !== void 0 ? _a : []; }).reduce((a, b) => a.concat(b), []);
92
+ }
93
+ catch (e) {
94
+ options.log.warn('Error checking OSV: ' + e);
72
95
  return [];
73
- const comps = yield Promise.all(versionInfo.advisoryKeys.map(({ id }) => loadAdvisory(packageName, version, id, options)));
74
- const flattened = comps.reduce((a, b) => a.concat(b), []);
75
- return flattened.map(x => { var _a; return (_a = x.vulnerabilities) !== null && _a !== void 0 ? _a : []; }).reduce((a, b) => a.concat(b), []);
96
+ }
76
97
  });
77
98
  }
78
99
  exports.checkOSV = checkOSV;
package/lib/repo.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Options, Repository } from "./types";
1
+ import { Options, Repository } from './types';
2
2
  export declare function asbowerrepo(jsRepo: Repository): Repository;
3
3
  export declare function loadrepository(repoUrl: string, options: Options): Promise<Repository>;
4
4
  export declare function loadrepositoryFromFile(filepath: string, options: Options): Promise<Repository>;
package/lib/repo.js CHANGED
@@ -58,18 +58,18 @@ function loadJson(url, options) {
58
58
  if (options.cacertbuf) {
59
59
  reqOptions.ca = [options.cacertbuf];
60
60
  }
61
- const req = (url.startsWith("http:") ? http : https).get(reqOptions, (res) => {
61
+ const req = (url.startsWith('http:') ? http : https).get(reqOptions, (res) => {
62
62
  if (res.statusCode != 200)
63
63
  return reject(`Error downloading: ${url}: HTTP ${res.statusCode} ${res.statusMessage}`);
64
64
  const data = [];
65
- res.on('data', c => data.push(c));
65
+ res.on('data', (c) => data.push(c));
66
66
  res.on('end', () => {
67
67
  let d = Buffer.concat(data).toString();
68
68
  d = options.process ? options.process(d) : d;
69
69
  resolve(JSON.parse(d));
70
70
  });
71
71
  });
72
- req.on('error', e => reject(`Error downloading: ${url}: ${e}`));
72
+ req.on('error', (e) => reject(`Error downloading: ${url}: ${e}`));
73
73
  req.end();
74
74
  });
75
75
  });
@@ -93,7 +93,7 @@ function loadFromCache(url, cachedir, options) {
93
93
  const cacheIndex = path.resolve(cachedir, 'index.json');
94
94
  if (!fs.existsSync(cachedir))
95
95
  fs.mkdirSync(cachedir);
96
- const cache = fs.existsSync(cacheIndex) ? JSON.parse(fs.readFileSync(cacheIndex, "utf-8")) : {};
96
+ const cache = fs.existsSync(cacheIndex) ? JSON.parse(fs.readFileSync(cacheIndex, 'utf-8')) : {};
97
97
  const now = new Date().getTime();
98
98
  if (cache[url]) {
99
99
  if (now - cache[url].date < 60 * 60 * 1000) {
@@ -106,11 +106,11 @@ function loadFromCache(url, cachedir, options) {
106
106
  fs.unlinkSync(path.resolve(cachedir, cache[url].date + '.json'));
107
107
  }
108
108
  catch (error) {
109
- if (error != null && typeof error == "object" && "code" in error && error.code !== 'ENOENT') {
109
+ if (error != null && typeof error == 'object' && 'code' in error && error.code !== 'ENOENT') {
110
110
  throw error;
111
111
  }
112
112
  else {
113
- console.warn("Could not delete cache. Ignore this error if you are running multiple retire.js in parallel");
113
+ console.warn('Could not delete cache. Ignore this error if you are running multiple retire.js in parallel');
114
114
  }
115
115
  }
116
116
  }
@@ -126,7 +126,7 @@ function loadFromCache(url, cachedir, options) {
126
126
  function asbowerrepo(jsRepo) {
127
127
  const result = {};
128
128
  Object.keys(jsRepo).map((k) => {
129
- ([jsRepo[k].bowername || k]).map((b) => {
129
+ [jsRepo[k].bowername || k].map((b) => {
130
130
  result[b] = result[b] || { vulnerabilities: [] };
131
131
  result[b].vulnerabilities = result[b].vulnerabilities.concat(jsRepo[k].vulnerabilities);
132
132
  });
@@ -134,7 +134,6 @@ function asbowerrepo(jsRepo) {
134
134
  return result;
135
135
  }
136
136
  exports.asbowerrepo = asbowerrepo;
137
- ;
138
137
  function loadrepository(repoUrl, options) {
139
138
  return __awaiter(this, void 0, void 0, function* () {
140
139
  //options = utils.extend(options, { process : retire.replaceVersion });
@@ -146,7 +145,6 @@ function loadrepository(repoUrl, options) {
146
145
  });
147
146
  }
148
147
  exports.loadrepository = loadrepository;
149
- ;
150
148
  function loadrepositoryFromFile(filepath, options) {
151
149
  return __awaiter(this, void 0, void 0, function* () {
152
150
  options = Object.assign(Object.assign({}, options), { process: retire.replaceVersion });
@@ -154,4 +152,3 @@ function loadrepositoryFromFile(filepath, options) {
154
152
  });
155
153
  }
156
154
  exports.loadrepositoryFromFile = loadrepositoryFromFile;
157
- ;
@@ -1,3 +1,3 @@
1
- import { type ConfigurableLogger } from "../reporting";
1
+ import { type ConfigurableLogger } from '../reporting';
2
2
  declare const _default: ConfigurableLogger;
3
3
  export default _default;
@@ -53,9 +53,12 @@ function printVulnerability(component, config) {
53
53
  string += `severity: ${vulnerability.severity}; `;
54
54
  }
55
55
  if (vulnerability.identifiers) {
56
- string += Object.entries(vulnerability.identifiers).map(([name, id]) => {
57
- return `${name}: ${utils.flatten([Array.isArray(id) ? id : [id]]).join(' ')}`;
58
- }).join(', ') + '; ';
56
+ string +=
57
+ Object.entries(vulnerability.identifiers)
58
+ .map(([name, id]) => {
59
+ return `${name}: ${utils.flatten([Array.isArray(id) ? id : [id]]).join(' ')}`;
60
+ })
61
+ .join(', ') + '; ';
59
62
  }
60
63
  string += vulnerability.info.join(config.outputformat === 'clean' ? '\n' : ' ');
61
64
  });
@@ -63,8 +66,12 @@ function printVulnerability(component, config) {
63
66
  }
64
67
  exports.default = {
65
68
  configure: (logger, _, config) => {
66
- logger.logDependency = (finding) => { if (config.verbose)
67
- printResults(logger, finding, config); };
68
- logger.logVulnerableDependency = (component) => { printResults(logger, component, config); };
69
- }
69
+ logger.logDependency = (finding) => {
70
+ if (config.verbose)
71
+ printResults(logger, finding, config);
72
+ };
73
+ logger.logVulnerableDependency = (component) => {
74
+ printResults(logger, component, config);
75
+ };
76
+ },
70
77
  };
@@ -1,3 +1,3 @@
1
- import { ConfigurableLogger } from "../reporting";
1
+ import { ConfigurableLogger } from '../reporting';
2
2
  declare const _default: ConfigurableLogger;
3
3
  export default _default;
@@ -34,10 +34,14 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
34
34
  start: new Date().toISOString(),
35
35
  data: [],
36
36
  messages: [],
37
- errors: []
37
+ errors: [],
38
38
  };
39
39
  logger.info = finalResults.messages.push;
40
- logger.debug = config.verbose ? finalResults.messages.push : function () { return; };
40
+ logger.debug = config.verbose
41
+ ? finalResults.messages.push
42
+ : function () {
43
+ return;
44
+ };
41
45
  logger.warn = logger.error = finalResults.errors.push;
42
46
  logger.logVulnerableDependency = function (finding) {
43
47
  vulnsFound = true;
@@ -51,17 +55,20 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
51
55
  logger.close = function (callback) {
52
56
  const write = vulnsFound ? writer.err : writer.out;
53
57
  const seen = new Set();
54
- const components = finalResults.data.filter(d => d.results).map(r => r.results.map(dep => {
55
- dep.version = (dep.version.split(".").length >= 3 ? dep.version : dep.version + ".0").replace(/-/g, ".");
58
+ const components = finalResults.data
59
+ .filter((d) => d.results)
60
+ .map((r) => r.results
61
+ .map((dep) => {
62
+ dep.version = (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.');
56
63
  let hashes;
57
64
  const filepath = r.file;
58
65
  if (filepath) {
59
66
  const file = fs.readFileSync(filepath);
60
67
  hashes = [
61
- { "alg": "MD5", "content": hash.md5(file) },
62
- { "alg": "SHA-1", "content": hash.sha1(file) },
63
- { "alg": "SHA-256", "content": hash.sha256(file) },
64
- { "alg": "SHA-512", "content": hash.sha512(file) },
68
+ { alg: 'MD5', content: hash.md5(file) },
69
+ { alg: 'SHA-1', content: hash.sha1(file) },
70
+ { alg: 'SHA-256', content: hash.sha256(file) },
71
+ { alg: 'SHA-512', content: hash.sha512(file) },
65
72
  ];
66
73
  }
67
74
  const purl = `pkg:npm/${dep.component}@${dep.version}`;
@@ -69,33 +76,35 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
69
76
  return undefined;
70
77
  seen.add(purl);
71
78
  return {
72
- type: "library",
79
+ type: 'library',
73
80
  name: dep.component,
74
81
  version: dep.version,
75
82
  purl: purl,
76
- hashes: hashes
83
+ hashes: hashes,
77
84
  };
78
- }).filter(x => x != undefined)).reduce((a, b) => a.concat(b));
85
+ })
86
+ .filter((x) => x != undefined))
87
+ .reduce((a, b) => a.concat(b));
79
88
  write(JSON.stringify({
80
- bomFormat: "CycloneDX",
81
- specVersion: "1.4",
89
+ bomFormat: 'CycloneDX',
90
+ specVersion: '1.4',
82
91
  serialNumber: `urn:uuid:${(0, uuid_1.v4)()}`,
83
92
  version: 1,
84
93
  metadata: {
85
94
  timestamp: finalResults.start,
86
95
  tools: [
87
96
  {
88
- vendor: "RetireJS",
89
- name: "retire.js",
90
- version: retire.version
91
- }
92
- ]
97
+ vendor: 'RetireJS',
98
+ name: 'retire.js',
99
+ version: retire.version,
100
+ },
101
+ ],
93
102
  },
94
- components: components
103
+ components: components,
95
104
  }, undefined, 2));
96
105
  writer.close(callback);
97
106
  };
98
107
  }
99
108
  exports.default = {
100
- configure: configureCycloneDXJSONLogger
109
+ configure: configureCycloneDXJSONLogger,
101
110
  };
@@ -1,3 +1,3 @@
1
- import { ConfigurableLogger } from "../reporting";
1
+ import { ConfigurableLogger } from '../reporting';
2
2
  declare const _default: ConfigurableLogger;
3
3
  export default _default;
@@ -34,10 +34,14 @@ function configureCycloneDXLogger(logger, writer, config, hash) {
34
34
  start: new Date(),
35
35
  data: [],
36
36
  messages: [],
37
- errors: []
37
+ errors: [],
38
38
  };
39
39
  logger.info = finalResults.messages.push;
40
- logger.debug = config.verbose ? finalResults.messages.push : () => { return; };
40
+ logger.debug = config.verbose
41
+ ? finalResults.messages.push
42
+ : () => {
43
+ return;
44
+ };
41
45
  logger.warn = logger.error = finalResults.errors.push;
42
46
  logger.logVulnerableDependency = function (finding) {
43
47
  vulnsFound = true;
@@ -51,10 +55,13 @@ function configureCycloneDXLogger(logger, writer, config, hash) {
51
55
  logger.close = function (callback) {
52
56
  const write = vulnsFound ? writer.err : writer.out;
53
57
  const seen = new Set();
54
- const components = finalResults.data.filter(d => d.results).map(r => r.results.map(dep => {
55
- dep.version = (dep.version.split(".").length >= 3 ? dep.version : dep.version + ".0").replace(/-/g, ".");
58
+ const components = finalResults.data
59
+ .filter((d) => d.results)
60
+ .map((r) => r.results
61
+ .map((dep) => {
62
+ dep.version = (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.');
56
63
  const filepath = r.file;
57
- let hashes = "";
64
+ let hashes = '';
58
65
  if (filepath) {
59
66
  const file = fs.readFileSync(filepath);
60
67
  hashes = `
@@ -76,7 +83,9 @@ function configureCycloneDXLogger(logger, writer, config, hash) {
76
83
  <purl>${purl}</purl>
77
84
  <modified>false</modified>
78
85
  </component>`;
79
- }).join("")).join("");
86
+ })
87
+ .join(''))
88
+ .join('');
80
89
  write(`<?xml version="1.0"?>
81
90
  <bom xmlns="http://cyclonedx.org/schema/bom/1.4" serialNumber="urn:uuid:${(0, uuid_1.v4)()}" version="1">
82
91
  <metadata>
@@ -96,5 +105,5 @@ function configureCycloneDXLogger(logger, writer, config, hash) {
96
105
  };
97
106
  }
98
107
  exports.default = {
99
- configure: configureCycloneDXLogger
108
+ configure: configureCycloneDXLogger,
100
109
  };
@@ -1,3 +1,3 @@
1
- import { ConfigurableLogger } from "../reporting";
1
+ import { ConfigurableLogger } from '../reporting';
2
2
  declare const _default: ConfigurableLogger;
3
3
  export default _default;