diff --git a/package-lock.json b/package-lock.json
index 78fe85db..e03a3ffa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2163,14 +2163,6 @@
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
- "packageurl-js": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/packageurl-js/-/packageurl-js-0.0.1.tgz",
- "integrity": "sha512-hjMzq6XuAxMMiV55UOIhf6byXKR9Fc046ybroGCpjGtJ5EI9QJG9g/ErYoPt0RGUaAr51C6x+pwUG9pXgLnaqg==",
- "requires": {
- "urijs": "^1.19.1"
- }
- },
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -2180,11 +2172,6 @@
"callsites": "^3.0.0"
}
},
- "parse-packagejson-name": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parse-packagejson-name/-/parse-packagejson-name-1.0.1.tgz",
- "integrity": "sha1-q1syLNOMh7SgFiBoPMpWrXTABqA="
- },
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -2250,11 +2237,6 @@
"fast-diff": "^1.1.2"
}
},
- "prettify-xml": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/prettify-xml/-/prettify-xml-1.2.0.tgz",
- "integrity": "sha1-Rtzx7oqNi3PbMLfgbvJtyc8/bxg="
- },
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -2804,11 +2786,6 @@
"punycode": "^2.1.0"
}
},
- "urijs": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.2.tgz",
- "integrity": "sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w=="
- },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index c24df245..26007a3e 100644
--- a/package.json
+++ b/package.json
@@ -81,9 +81,6 @@
"node-fetch": "^2.6.0",
"node-persist": "^3.0.5",
"ora": "^4.0.3",
- "packageurl-js": "^0.0.1",
- "parse-packagejson-name": "^1.0.1",
- "prettify-xml": "^1.2.0",
"read-installed": "~4.0.3",
"spdx-license-ids": "^3.0.5",
"ssri": "^6.0.0",
diff --git a/src/CycloneDX/CycloneDXSbomCreator.ts b/src/CycloneDX/CycloneDXSbomCreator.ts
index 25d6155b..928b4545 100644
--- a/src/CycloneDX/CycloneDXSbomCreator.ts
+++ b/src/CycloneDX/CycloneDXSbomCreator.ts
@@ -1,5 +1,3 @@
-///
-///
///
///
/*
@@ -21,8 +19,6 @@ import { Options } from './Options';
import uuidv4 from 'uuid/v4';
import builder from 'xmlbuilder';
import readInstalled from 'read-installed';
-import PackageURL from 'packageurl-js';
-import parsePackageJsonName from 'parse-packagejson-name';
import * as ssri from 'ssri';
import * as fs from 'fs';
import { LicenseContent } from './Types/LicenseContent';
@@ -31,6 +27,7 @@ import { ExternalReference } from './Types/ExternalReference';
import { Hash } from './Types/Hash';
import spdxLicensesNonDeprecated = require('spdx-license-ids');
import spdxLicensesDeprecated = require('spdx-license-ids/deprecated');
+import { toPurl } from './Helpers/Helpers';
export class CycloneDXSbomCreator {
readonly licenseFilenames: Array = [
@@ -113,11 +110,11 @@ export class CycloneDXSbomCreator {
return;
}
if (!isRootPkg) {
- const pkgIdentifier = parsePackageJsonName(pkg.name);
- const group: string = pkgIdentifier.scope == null ? '' : `@${pkgIdentifier.scope}`;
+ const pkgIdentifier = this.parsePackageJsonName(pkg.name);
+ const group: string = pkgIdentifier.scope == undefined ? '' : `@${pkgIdentifier.scope}`;
const name: string = pkgIdentifier.fullName as string;
const version: string = pkg.version as string;
- const purl: string = new PackageURL('npm', group, name, version, null, null).toString();
+ const purl: string = toPurl(name, version, group);
const description: GenericDescription = { '#cdata': pkg.description };
const component: Component = {
@@ -302,4 +299,31 @@ export class CycloneDXSbomCreator {
}
return undefined;
}
+
+ private parsePackageJsonName(name: string): Result {
+ const result: Result = {
+ scope: undefined,
+ fullName: '',
+ projectName: '',
+ moduleName: '',
+ };
+
+ const regexp = new RegExp(/^(?:@([^/]+)\/)?(([^\.]+)(?:\.(.*))?)$/);
+
+ const matches = name.match(regexp);
+ if (matches) {
+ result.scope = matches[1] || undefined;
+ result.fullName = matches[2] || matches[0];
+ result.projectName = matches[3] === matches[2] ? undefined : matches[3];
+ result.moduleName = matches[4] || matches[2] || undefined;
+ }
+ return result;
+ }
+}
+
+interface Result {
+ scope?: string;
+ fullName: string;
+ projectName?: string;
+ moduleName?: string;
}
diff --git a/src/CycloneDX/Helpers/Helpers.ts b/src/CycloneDX/Helpers/Helpers.ts
new file mode 100644
index 00000000..2adc7c41
--- /dev/null
+++ b/src/CycloneDX/Helpers/Helpers.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020-present Sonatype, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const toPurl = (name: string, version: string, group = ''): string => {
+ if (group != '') {
+ return `pkg:npm/${encodeURIComponent(group)}/${name}@${version}`;
+ }
+ return `pkg:npm/${name}@${version}`;
+};
diff --git a/src/CycloneDX/typings/packageurl-js/index.d.ts b/src/CycloneDX/typings/packageurl-js/index.d.ts
deleted file mode 100644
index acbac5d5..00000000
--- a/src/CycloneDX/typings/packageurl-js/index.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module 'packageurl-js';