retire 5.6.0 → 6.0.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.
@@ -1,209 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
- const retire = __importStar(require("../retire"));
37
- const fs = __importStar(require("fs"));
38
- const utils_1 = require("./utils");
39
- const path = __importStar(require("path"));
40
- const crypto = __importStar(require("crypto"));
41
- function configureCycloneDXJSONLogger(logger, writer, config, hash) {
42
- let vulnsFound = false;
43
- const finalResults = {
44
- version: retire.version,
45
- start: new Date().toISOString(),
46
- data: [],
47
- messages: [],
48
- errors: [],
49
- };
50
- logger.info = finalResults.messages.push;
51
- logger.debug = config.verbose
52
- ? finalResults.messages.push
53
- : function () {
54
- return;
55
- };
56
- logger.warn = logger.error = finalResults.errors.push;
57
- logger.logVulnerableDependency = function (finding) {
58
- vulnsFound = true;
59
- finalResults.data.push(finding);
60
- };
61
- logger.logDependency = function (finding) {
62
- if (finding.results.length > 0) {
63
- finalResults.data.push(finding);
64
- }
65
- };
66
- logger.close = function (callback) {
67
- const write = vulnsFound ? writer.err : writer.out;
68
- const seen = new Map();
69
- const vulnerabilitiesCyclone = new Map();
70
- const includeVEX = config.outputformat === 'cyclonedxJSON1_6_VEX';
71
- const vulnerabilityRepositoriesList = (0, utils_1.vulnerabilityRepositories)(config.jsRepo);
72
- // Only attributable to a single URL when exactly one repository was used
73
- const retireSource = {
74
- name: 'Retire.js',
75
- url: vulnerabilityRepositoriesList.length === 1 ? vulnerabilityRepositoriesList[0] : undefined,
76
- };
77
- const properties = vulnerabilityRepositoriesList.map((repo) => ({ name: 'retirejs:vulnerability-repository', value: repo }));
78
- if (config.insecure) {
79
- properties.push({ name: 'retirejs:ignore-repository-certificate-errors', value: 'true' });
80
- }
81
- const components = finalResults.data
82
- .filter((d) => d.results)
83
- .map((r) => r.results
84
- .map((dep) => {
85
- dep.version = (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.');
86
- let hashes;
87
- const filepath = r.file;
88
- const evidence = { occurrences: [] };
89
- if (filepath) {
90
- const file = fs.readFileSync(filepath);
91
- const relativePath = path.relative(process.cwd(), filepath);
92
- evidence.occurrences.push({ location: relativePath });
93
- hashes = [
94
- { alg: 'MD5', content: hash.md5(file) },
95
- { alg: 'SHA-1', content: hash.sha1(file) },
96
- { alg: 'SHA-256', content: hash.sha256(file) },
97
- { alg: 'SHA-512', content: hash.sha512(file) },
98
- ];
99
- }
100
- const purl = (0, utils_1.generatePURL)(dep);
101
- const existing = seen.get(purl);
102
- if (existing) {
103
- const missing = evidence.occurrences.filter((x) => !existing.evidence.occurrences.some((y) => y.location == x.location));
104
- existing.evidence.occurrences.push(...missing);
105
- return undefined;
106
- }
107
- const nameParts = dep.component.split('/').reverse();
108
- const bomRef = purl;
109
- dep.vulnerabilities?.forEach((vuln) => {
110
- // Pick valid identifiers for VEX
111
- const ids = vuln.identifiers?.CVE ?? (vuln.identifiers?.githubID ? [vuln.identifiers.githubID] : undefined);
112
- if (!ids)
113
- return;
114
- ids.forEach((id) => {
115
- if (!vulnerabilitiesCyclone.has(id)) {
116
- const { references, advisories } = mapUrls(vuln);
117
- vulnerabilitiesCyclone.set(id, {
118
- id,
119
- source: retireSource,
120
- cwes: vuln.cwe.map((c) => parseInt(c.split("-")[1])),
121
- description: vuln.identifiers.summary,
122
- advisories: advisories,
123
- references: references,
124
- ratings: [
125
- {
126
- source: retireSource,
127
- severity: vuln.severity,
128
- },
129
- ],
130
- affects: [],
131
- });
132
- }
133
- vulnerabilitiesCyclone.get(id).affects.push({
134
- ref: bomRef,
135
- versions: [
136
- {
137
- // "vers:npm/1.2.3|>=2.0.0|<5.0.0"
138
- range: 'vers:npm/' + (vuln.atOrAbove ? '>=' + vuln.atOrAbove + '|' : '') + '<' + vuln.below,
139
- status: 'affected',
140
- },
141
- ],
142
- });
143
- });
144
- });
145
- const result = {
146
- "bom-ref": bomRef,
147
- type: 'library',
148
- name: nameParts[0],
149
- group: nameParts[1],
150
- version: dep.version,
151
- purl: purl,
152
- hashes: hashes,
153
- evidence,
154
- licenses: mapLicenses(dep.licenses),
155
- };
156
- seen.set(purl, result);
157
- return result;
158
- })
159
- .filter((x) => x != undefined))
160
- .reduce((a, b) => a.concat(b), []);
161
- write(JSON.stringify({
162
- bomFormat: 'CycloneDX',
163
- specVersion: '1.6',
164
- serialNumber: `urn:uuid:${crypto.randomUUID()}`,
165
- version: 1,
166
- metadata: {
167
- timestamp: finalResults.start,
168
- tools: [
169
- {
170
- vendor: 'RetireJS',
171
- name: 'retire',
172
- version: retire.version,
173
- },
174
- ],
175
- properties: properties.length ? properties : undefined,
176
- },
177
- components: components,
178
- vulnerabilities: includeVEX ? Array.from(vulnerabilitiesCyclone.values()) : undefined,
179
- }, undefined, 2));
180
- writer.close(callback);
181
- };
182
- }
183
- function mapLicenses(licenses) {
184
- if (!licenses)
185
- return [];
186
- if (licenses.length == 0)
187
- return [];
188
- if (licenses[0] == 'commercial')
189
- return [{ license: { name: 'Commercial' } }];
190
- return [{ expression: licenses[0] }];
191
- }
192
- function mapUrls(vulnerability) {
193
- const references = [];
194
- if (vulnerability.identifiers.CVE) {
195
- const nvdlink = `https://nvd.nist.gov/vuln/detail/${vulnerability.identifiers.CVE[0]}`;
196
- references.push({ id: vulnerability.identifiers.CVE[0], source: { name: 'NVD', url: nvdlink } });
197
- }
198
- if (vulnerability.identifiers.githubID) {
199
- const ghsa = `https://github.com/advisories/${vulnerability.identifiers.githubID}`;
200
- references.push({ id: vulnerability.identifiers.githubID, source: { name: 'GitHub Advisories', url: ghsa } });
201
- }
202
- const advisories = vulnerability.info
203
- .filter((url) => !url.startsWith('https://nvd.nist.gov/vuln/detail/') && !url.startsWith('https://github.com/advisories/'))
204
- .map((u) => ({ url: u }));
205
- return { references, advisories };
206
- }
207
- exports.default = {
208
- configure: configureCycloneDXJSONLogger,
209
- };
3
+ const cyclonedx_json_builder_1 = require("./cyclonedx-json-builder");
4
+ exports.default = (0, cyclonedx_json_builder_1.cycloneDXJSONLogger)('1.6');
@@ -0,0 +1,2 @@
1
+ declare const _default: import("../reporting").ConfigurableLogger;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cyclonedx_json_builder_1 = require("./cyclonedx-json-builder");
4
+ exports.default = (0, cyclonedx_json_builder_1.cycloneDXJSONLogger)('1.7');
@@ -0,0 +1,7 @@
1
+ import { ConfigurableLogger } from '../reporting';
2
+ /**
3
+ * Spec versions sharing this implementation. The 1.4 reporters are kept separate, as the
4
+ * modern object form of metadata.tools was only introduced in 1.5.
5
+ */
6
+ export type CycloneDXSpecVersion = '1.6' | '1.7';
7
+ export declare function cycloneDXJSONLogger(specVersion: CycloneDXSpecVersion): ConfigurableLogger;
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.cycloneDXJSONLogger = cycloneDXJSONLogger;
37
+ const retire = __importStar(require("../retire"));
38
+ const fs = __importStar(require("fs"));
39
+ const utils_1 = require("./utils");
40
+ const path = __importStar(require("path"));
41
+ const crypto = __importStar(require("crypto"));
42
+ const TOOL_BOM_REF = 'retirejs-tool';
43
+ const SCAN_TARGET_BOM_REF = 'retirejs:scan-target';
44
+ /**
45
+ * Retire.js has no native confidence score, so the mapping from the detection method to a
46
+ * CycloneDX identity technique and confidence is a heuristic. Both technique and confidence
47
+ * are required by the schema.
48
+ */
49
+ const identityTechniques = {
50
+ hash: { technique: 'hash-comparison', confidence: 1 },
51
+ ast: { technique: 'ast-fingerprint', confidence: 0.9 },
52
+ filecontent: { technique: 'source-code-analysis', confidence: 0.8 },
53
+ filecontentreplace: { technique: 'source-code-analysis', confidence: 0.8 },
54
+ func: { technique: 'dynamic-analysis', confidence: 0.8 },
55
+ filename: { technique: 'filename', confidence: 0.5 },
56
+ uri: { technique: 'filename', confidence: 0.5 },
57
+ };
58
+ function configureCycloneDXJSONLogger(specVersion, logger, writer, config, hash) {
59
+ let vulnsFound = false;
60
+ const finalResults = {
61
+ version: retire.version,
62
+ start: new Date().toISOString(),
63
+ data: [],
64
+ messages: [],
65
+ errors: [],
66
+ };
67
+ logger.info = finalResults.messages.push;
68
+ logger.debug = config.verbose
69
+ ? finalResults.messages.push
70
+ : function () {
71
+ return;
72
+ };
73
+ logger.warn = logger.error = finalResults.errors.push;
74
+ logger.logVulnerableDependency = function (finding) {
75
+ vulnsFound = true;
76
+ finalResults.data.push(finding);
77
+ };
78
+ logger.logDependency = function (finding) {
79
+ if (finding.results.length > 0) {
80
+ finalResults.data.push(finding);
81
+ }
82
+ };
83
+ logger.close = function (callback) {
84
+ const write = vulnsFound ? writer.err : writer.out;
85
+ const seen = new Map();
86
+ const vulnerabilitiesCyclone = new Map();
87
+ const includeVEX = config.outputformat?.endsWith('_VEX') ?? false;
88
+ const vulnerabilityRepositoriesList = (0, utils_1.vulnerabilityRepositories)(config.jsRepo);
89
+ // Only attributable to a single URL when exactly one repository was used
90
+ const retireSource = {
91
+ name: 'Retire.js',
92
+ url: vulnerabilityRepositoriesList.length === 1 ? vulnerabilityRepositoriesList[0] : undefined,
93
+ };
94
+ const properties = vulnerabilityRepositoriesList.map((repo) => ({
95
+ name: 'retirejs:vulnerability-repository',
96
+ value: repo,
97
+ }));
98
+ if (config.insecure) {
99
+ properties.push({ name: 'retirejs:ignore-repository-certificate-errors', value: 'true' });
100
+ }
101
+ const components = finalResults.data
102
+ .filter((d) => d.results)
103
+ .map((r) => r.results
104
+ .map((dep) => {
105
+ dep = {
106
+ ...dep,
107
+ version: (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.'),
108
+ };
109
+ let hashes;
110
+ const filepath = r.file;
111
+ const evidence = { occurrences: [] };
112
+ if (filepath) {
113
+ const file = fs.readFileSync(filepath);
114
+ const relativePath = path.relative(process.cwd(), filepath);
115
+ evidence.occurrences.push({ location: relativePath });
116
+ hashes = [
117
+ { alg: 'MD5', content: hash.md5(file) },
118
+ { alg: 'SHA-1', content: hash.sha1(file) },
119
+ { alg: 'SHA-256', content: hash.sha256(file) },
120
+ { alg: 'SHA-512', content: hash.sha512(file) },
121
+ ];
122
+ }
123
+ const purl = (0, utils_1.generatePURL)(dep);
124
+ const existing = seen.get(purl);
125
+ const identity = mapIdentity(dep);
126
+ if (identity)
127
+ evidence.identity = [identity];
128
+ const nameParts = dep.component.split('/').reverse();
129
+ const bomRef = purl;
130
+ dep.vulnerabilities?.forEach((vuln) => {
131
+ // Pick valid identifiers for VEX
132
+ const ids = vuln.identifiers?.CVE ?? (vuln.identifiers?.githubID ? [vuln.identifiers.githubID] : undefined);
133
+ if (!ids)
134
+ return;
135
+ ids.forEach((id) => {
136
+ if (!vulnerabilitiesCyclone.has(id)) {
137
+ const { references, advisories } = mapUrls(vuln);
138
+ const cwes = vuln.cwe?.map((c) => parseInt(c.split('-')[1]));
139
+ vulnerabilitiesCyclone.set(id, {
140
+ id,
141
+ source: retireSource,
142
+ cwes: cwes?.length ? cwes : undefined,
143
+ description: vuln.identifiers?.summary,
144
+ detail: vuln.details,
145
+ advisories: advisories,
146
+ references: references,
147
+ ratings: [
148
+ {
149
+ source: retireSource,
150
+ severity: vuln.severity,
151
+ },
152
+ ],
153
+ affects: [],
154
+ });
155
+ }
156
+ const affects = vulnerabilitiesCyclone.get(id).affects;
157
+ let affected = affects.find((entry) => entry.ref === bomRef);
158
+ if (!affected) {
159
+ affected = { ref: bomRef, versions: [] };
160
+ affects.push(affected);
161
+ }
162
+ const range = 'vers:npm/' + (vuln.atOrAbove ? '>=' + vuln.atOrAbove + '|' : '') + '<' + vuln.below;
163
+ if (!affected.versions.some((entry) => entry.range === range)) {
164
+ affected.versions.push({ range, status: 'affected' });
165
+ }
166
+ });
167
+ });
168
+ if (existing) {
169
+ const missing = evidence.occurrences.filter((x) => !existing.evidence.occurrences.some((y) => y.location == x.location));
170
+ existing.evidence.occurrences.push(...missing);
171
+ if (identity) {
172
+ const identities = existing.evidence.identity ?? (existing.evidence.identity = []);
173
+ if (!identities.some((entry) => entry.methods[0].value === identity.methods[0].value)) {
174
+ identities.push(identity);
175
+ }
176
+ }
177
+ return undefined;
178
+ }
179
+ const result = {
180
+ 'bom-ref': bomRef,
181
+ type: 'library',
182
+ name: nameParts[0],
183
+ group: nameParts[1],
184
+ version: dep.version,
185
+ purl: purl,
186
+ hashes: hashes,
187
+ evidence,
188
+ licenses: mapLicenses(dep.licenses, specVersion),
189
+ };
190
+ seen.set(purl, result);
191
+ return result;
192
+ })
193
+ .filter((x) => x != undefined))
194
+ .reduce((a, b) => a.concat(b), []);
195
+ const dependencies = [
196
+ { ref: SCAN_TARGET_BOM_REF, dependsOn: components.map((c) => c['bom-ref']) },
197
+ ...components.map((c) => ({ ref: c['bom-ref'], dependsOn: [] })),
198
+ ];
199
+ write(JSON.stringify({
200
+ $schema: `http://cyclonedx.org/schema/bom-${specVersion}.schema.json`,
201
+ bomFormat: 'CycloneDX',
202
+ specVersion,
203
+ serialNumber: `urn:uuid:${crypto.randomUUID()}`,
204
+ version: 1,
205
+ metadata: {
206
+ timestamp: finalResults.start,
207
+ tools: {
208
+ components: [
209
+ {
210
+ type: 'application',
211
+ 'bom-ref': TOOL_BOM_REF,
212
+ group: 'RetireJS',
213
+ name: 'retire',
214
+ version: retire.version,
215
+ },
216
+ ],
217
+ },
218
+ component: {
219
+ type: 'application',
220
+ 'bom-ref': SCAN_TARGET_BOM_REF,
221
+ name: scanTargetName(config.path),
222
+ },
223
+ properties: properties.length ? properties : undefined,
224
+ },
225
+ components: components,
226
+ dependencies,
227
+ vulnerabilities: includeVEX ? Array.from(vulnerabilitiesCyclone.values()) : undefined,
228
+ }, undefined, 2));
229
+ writer.close(callback);
230
+ };
231
+ }
232
+ function scanTargetName(scanPath) {
233
+ return path.basename(path.resolve(scanPath ?? '.'));
234
+ }
235
+ function mapIdentity(component) {
236
+ if (!component.detection)
237
+ return undefined;
238
+ const mapped = identityTechniques[component.detection];
239
+ if (!mapped)
240
+ return undefined;
241
+ return {
242
+ field: 'version',
243
+ confidence: mapped.confidence,
244
+ concludedValue: component.version,
245
+ methods: [{ technique: mapped.technique, confidence: mapped.confidence, value: component.detection }],
246
+ };
247
+ }
248
+ function mapLicense(license) {
249
+ return license == 'commercial' ? { license: { name: 'Commercial' } } : { expression: license };
250
+ }
251
+ function mapLicenses(licenses, specVersion) {
252
+ if (!licenses)
253
+ return [];
254
+ if (licenses.length == 0)
255
+ return [];
256
+ // Before 1.7, the licenses array could hold at most one SPDX expression, and expressions
257
+ // could not be mixed with named licenses.
258
+ if (specVersion === '1.6')
259
+ return [mapLicense(licenses[0])];
260
+ return licenses.map(mapLicense);
261
+ }
262
+ function mapUrls(vulnerability) {
263
+ const references = [];
264
+ if (vulnerability.identifiers?.CVE) {
265
+ const nvdlink = `https://nvd.nist.gov/vuln/detail/${vulnerability.identifiers.CVE[0]}`;
266
+ references.push({ id: vulnerability.identifiers.CVE[0], source: { name: 'NVD', url: nvdlink } });
267
+ }
268
+ if (vulnerability.identifiers?.githubID) {
269
+ const ghsa = `https://github.com/advisories/${vulnerability.identifiers.githubID}`;
270
+ references.push({ id: vulnerability.identifiers.githubID, source: { name: 'GitHub Advisories', url: ghsa } });
271
+ }
272
+ const advisories = vulnerability.info
273
+ .filter((url) => !url.startsWith('https://nvd.nist.gov/vuln/detail/') && !url.startsWith('https://github.com/advisories/'))
274
+ .map((u) => ({ url: u }));
275
+ return { references, advisories };
276
+ }
277
+ function cycloneDXJSONLogger(specVersion) {
278
+ return {
279
+ configure: (logger, writer, config, hash) => configureCycloneDXJSONLogger(specVersion, logger, writer, config, hash),
280
+ };
281
+ }
@@ -65,7 +65,10 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
65
65
  };
66
66
  logger.close = function (callback) {
67
67
  const write = vulnsFound ? writer.err : writer.out;
68
- const properties = (0, utils_1.vulnerabilityRepositories)(config.jsRepo).map((repo) => ({ name: 'retirejs:vulnerability-repository', value: repo }));
68
+ const properties = (0, utils_1.vulnerabilityRepositories)(config.jsRepo).map((repo) => ({
69
+ name: 'retirejs:vulnerability-repository',
70
+ value: repo,
71
+ }));
69
72
  if (config.insecure) {
70
73
  properties.push({ name: 'retirejs:ignore-repository-certificate-errors', value: 'true' });
71
74
  }
@@ -74,7 +77,10 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
74
77
  .filter((d) => d.results)
75
78
  .map((r) => r.results
76
79
  .map((dep) => {
77
- dep.version = (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.');
80
+ dep = {
81
+ ...dep,
82
+ version: (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.'),
83
+ };
78
84
  let hashes;
79
85
  const filepath = r.file;
80
86
  const properties = [];
@@ -81,7 +81,10 @@ function configureCycloneDXLogger(logger, writer, config, hash) {
81
81
  .filter((d) => d.results.length > 0)
82
82
  .map((r) => r.results
83
83
  .map((dep) => {
84
- dep.version = (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.');
84
+ dep = {
85
+ ...dep,
86
+ version: (dep.version.split('.').length >= 3 ? dep.version : dep.version + '.0').replace(/-/g, '.'),
87
+ };
85
88
  const filepath = r.file;
86
89
  let hashes = '';
87
90
  if (filepath) {
@@ -120,9 +123,11 @@ function configureCycloneDXLogger(logger, writer, config, hash) {
120
123
  <name>retire.js</name>
121
124
  <version>${retire.version}</version>
122
125
  </tool>
123
- </tools>${properties ? `
126
+ </tools>${properties
127
+ ? `
124
128
  <properties>${properties}
125
- </properties>` : ''}
129
+ </properties>`
130
+ : ''}
126
131
  </metadata>
127
132
  <components>${components}
128
133
  </components>
@@ -131,11 +136,7 @@ function configureCycloneDXLogger(logger, writer, config, hash) {
131
136
  };
132
137
  }
133
138
  function escapeXml(value) {
134
- return value
135
- .replace(/&/g, '&amp;')
136
- .replace(/</g, '&lt;')
137
- .replace(/>/g, '&gt;')
138
- .replace(/"/g, '&quot;');
139
+ return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
139
140
  }
140
141
  function mapLicenses(licenses) {
141
142
  if (!licenses)
package/lib/reporting.js CHANGED
@@ -46,6 +46,7 @@ const depcheck_1 = __importDefault(require("./reporters/depcheck"));
46
46
  const cyclonedx_1 = __importDefault(require("./reporters/cyclonedx"));
47
47
  const cyclonedx_json_1 = __importDefault(require("./reporters/cyclonedx-json"));
48
48
  const cyclonedx_1_6_json_1 = __importDefault(require("./reporters/cyclonedx-1_6-json"));
49
+ const cyclonedx_1_7_json_1 = __importDefault(require("./reporters/cyclonedx-1_7-json"));
49
50
  const loggers = {
50
51
  console: console_1.default,
51
52
  text: console_1.default,
@@ -55,6 +56,8 @@ const loggers = {
55
56
  cyclonedxJSON: cyclonedx_json_1.default,
56
57
  cyclonedxJSON1_6: cyclonedx_1_6_json_1.default,
57
58
  cyclonedxJSON1_6_VEX: cyclonedx_1_6_json_1.default,
59
+ cyclonedxJSON1_7: cyclonedx_1_7_json_1.default,
60
+ cyclonedxJSON1_7_VEX: cyclonedx_1_7_json_1.default,
58
61
  clean: console_1.default,
59
62
  jsonsimple: json_1.default,
60
63
  };
package/lib/resolve.js CHANGED
@@ -43,7 +43,7 @@ function scanJsFiles(path, options) {
43
43
  if (ext.some((e) => file.endsWith(e))) {
44
44
  finder.emit('jsfile', file);
45
45
  }
46
- if (file.match(/\/bower.json$/)) {
46
+ if (file.match(/[\\/]bower\.json$/)) {
47
47
  finder.emit('bowerfile', file);
48
48
  }
49
49
  }
package/lib/retire.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  var exports = exports || {};
7
- exports.version = '5.6.0';
7
+ exports.version = '6.0.0';
8
8
 
9
9
  function isDefined(o) {
10
10
  return typeof o !== 'undefined';
package/lib/scanner.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { Finding, Options, Repository } from './types';
2
- export declare function scanJsFile(file: string, repo: Repository, options: Options): void;
3
- export declare function scanBowerFile(file: string, repo: Repository, options: Options): void;
2
+ export declare function scanJsFile(file: string, repo: Repository, options: Options): Promise<void>;
3
+ export declare function scanBowerFile(file: string, repo: Repository, options: Options): Promise<void>;
4
4
  export declare function on(event: 'vulnerable-dependency-found' | 'dependency-found', handler: (finding: Finding) => void): void;