@trustify-da/trustify-da-javascript-client 0.3.0-ea.7ed8d8c → 0.3.0-ea.7ee4047
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 +388 -20
- package/dist/package.json +39 -26
- package/dist/src/analysis.d.ts +58 -20
- package/dist/src/analysis.js +134 -78
- package/dist/src/batch_opts.d.ts +24 -0
- package/dist/src/batch_opts.js +35 -0
- package/dist/src/cli.js +427 -12
- package/dist/src/config.d.ts +120 -0
- package/dist/src/config.js +260 -0
- package/dist/src/cyclone_dx_sbom.d.ts +30 -2
- package/dist/src/cyclone_dx_sbom.js +95 -9
- package/dist/src/index.d.ts +154 -16
- package/dist/src/index.js +372 -36
- package/dist/src/license/index.d.ts +28 -0
- package/dist/src/license/index.js +106 -0
- package/dist/src/license/license_utils.d.ts +40 -0
- package/dist/src/license/license_utils.js +137 -0
- package/dist/src/license/licenses_api.d.ts +34 -0
- package/dist/src/license/licenses_api.js +98 -0
- package/dist/src/license/project_license.d.ts +20 -0
- package/dist/src/license/project_license.js +62 -0
- package/dist/src/oci_image/images.d.ts +1 -1
- package/dist/src/oci_image/images.js +15 -1
- package/dist/src/oci_image/utils.d.ts +5 -5
- package/dist/src/oci_image/utils.js +11 -2
- package/dist/src/package_version.d.ts +8 -0
- package/dist/src/package_version.js +31 -0
- package/dist/src/provider.d.ts +16 -3
- package/dist/src/provider.js +33 -5
- package/dist/src/providers/base_java.d.ts +67 -12
- package/dist/src/providers/base_java.js +82 -61
- package/dist/src/providers/base_javascript.d.ts +99 -12
- package/dist/src/providers/base_javascript.js +244 -28
- package/dist/src/providers/base_pyproject.d.ts +158 -0
- package/dist/src/providers/base_pyproject.js +322 -0
- package/dist/src/providers/containerfile_parser.d.ts +5 -0
- package/dist/src/providers/containerfile_parser.js +20 -0
- package/dist/src/providers/golang_gomodules.d.ts +30 -13
- package/dist/src/providers/golang_gomodules.js +219 -122
- package/dist/src/providers/gomod_parser.d.ts +4 -0
- package/dist/src/providers/gomod_parser.js +16 -0
- package/dist/src/providers/java_gradle.d.ts +73 -0
- package/dist/src/providers/java_gradle.js +331 -23
- package/dist/src/providers/java_gradle_groovy.d.ts +1 -1
- package/dist/src/providers/java_gradle_kotlin.d.ts +1 -1
- package/dist/src/providers/java_maven.d.ts +44 -9
- package/dist/src/providers/java_maven.js +299 -13
- package/dist/src/providers/javascript_bun.d.ts +22 -0
- package/dist/src/providers/javascript_bun.js +141 -0
- package/dist/src/providers/javascript_npm.d.ts +19 -0
- package/dist/src/providers/javascript_npm.js +61 -1
- package/dist/src/providers/javascript_pnpm.d.ts +14 -1
- package/dist/src/providers/javascript_pnpm.js +55 -5
- package/dist/src/providers/javascript_yarn.d.ts +12 -0
- package/dist/src/providers/javascript_yarn.js +75 -2
- package/dist/src/providers/manifest.d.ts +2 -0
- package/dist/src/providers/manifest.js +28 -7
- package/dist/src/providers/marker_evaluator.d.ts +14 -0
- package/dist/src/providers/marker_evaluator.js +191 -0
- package/dist/src/providers/oci_dockerfile.d.ts +51 -0
- package/dist/src/providers/oci_dockerfile.js +177 -0
- package/dist/src/providers/processors/yarn_berry_processor.d.ts +6 -2
- package/dist/src/providers/processors/yarn_berry_processor.js +91 -7
- package/dist/src/providers/processors/yarn_classic_processor.d.ts +6 -2
- package/dist/src/providers/processors/yarn_classic_processor.js +8 -6
- package/dist/src/providers/python_controller.d.ts +5 -1
- package/dist/src/providers/python_controller.js +69 -8
- package/dist/src/providers/python_pip.d.ts +12 -0
- package/dist/src/providers/python_pip.js +18 -8
- package/dist/src/providers/python_pip_pyproject.d.ts +61 -0
- package/dist/src/providers/python_pip_pyproject.js +146 -0
- package/dist/src/providers/python_poetry.d.ts +98 -0
- package/dist/src/providers/python_poetry.js +286 -0
- package/dist/src/providers/python_uv.d.ts +46 -0
- package/dist/src/providers/python_uv.js +275 -0
- package/dist/src/providers/requirements_parser.js +6 -9
- package/dist/src/providers/rust_cargo.d.ts +56 -0
- package/dist/src/providers/rust_cargo.js +682 -0
- package/dist/src/providers/tree-sitter-containerfile.wasm +0 -0
- package/dist/src/providers/tree-sitter-gomod.wasm +0 -0
- package/dist/src/providers/tree-sitter-requirements.wasm +0 -0
- package/dist/src/remediate.d.ts +107 -0
- package/dist/src/remediate.js +244 -0
- package/dist/src/remediation.d.ts +81 -0
- package/dist/src/remediation.js +475 -0
- package/dist/src/remediation_report.d.ts +23 -0
- package/dist/src/remediation_report.js +180 -0
- package/dist/src/sbom.d.ts +28 -2
- package/dist/src/sbom.js +26 -4
- package/dist/src/tools.d.ts +53 -11
- package/dist/src/tools.js +147 -13
- package/dist/src/updaters/maven_updater.d.ts +58 -0
- package/dist/src/updaters/maven_updater.js +345 -0
- package/dist/src/updaters/toml_updater.d.ts +62 -0
- package/dist/src/updaters/toml_updater.js +276 -0
- package/dist/src/workspace.d.ts +71 -0
- package/dist/src/workspace.js +257 -0
- package/package.json +40 -27
package/dist/package.json
CHANGED
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
"provenance": true
|
|
26
26
|
},
|
|
27
27
|
"type": "module",
|
|
28
|
-
"bin":
|
|
28
|
+
"bin": {
|
|
29
|
+
"trustify-da": "dist/src/cli.js"
|
|
30
|
+
},
|
|
29
31
|
"main": "dist/src/index.js",
|
|
30
32
|
"module": "dist/src/index.js",
|
|
31
33
|
"types": "dist/src/index.d.ts",
|
|
@@ -35,47 +37,57 @@
|
|
|
35
37
|
"config/**/*"
|
|
36
38
|
],
|
|
37
39
|
"scripts": {
|
|
38
|
-
"lint": "eslint src test
|
|
39
|
-
"lint:fix": "eslint src test --
|
|
40
|
+
"lint": "eslint src test",
|
|
41
|
+
"lint:fix": "eslint src test --fix",
|
|
40
42
|
"test": "c8 npm run tests",
|
|
41
|
-
"tests": "mocha --config .mocharc.json
|
|
43
|
+
"tests": "mocha --config .mocharc.json",
|
|
42
44
|
"tests:rep": "mocha --reporter-option maxDiffSize=0 --reporter json > unit-tests-result.json",
|
|
45
|
+
"pretest": "cp node_modules/tree-sitter-requirements/tree-sitter-requirements.wasm src/providers/tree-sitter-requirements.wasm && cp node_modules/tree-sitter-gomod/tree-sitter-gomod.wasm src/providers/tree-sitter-gomod.wasm && cp node_modules/tree-sitter-containerfile/tree-sitter-containerfile.wasm src/providers/tree-sitter-containerfile.wasm",
|
|
43
46
|
"precompile": "rm -rf dist",
|
|
44
|
-
"compile": "tsc -p tsconfig.json"
|
|
47
|
+
"compile": "tsc -p tsconfig.json",
|
|
48
|
+
"compile:dev": "tsc -p tsconfig.dev.json",
|
|
49
|
+
"postcompile": "cp node_modules/tree-sitter-requirements/tree-sitter-requirements.wasm dist/src/providers/tree-sitter-requirements.wasm && cp node_modules/tree-sitter-gomod/tree-sitter-gomod.wasm dist/src/providers/tree-sitter-gomod.wasm && cp node_modules/tree-sitter-containerfile/tree-sitter-containerfile.wasm dist/src/providers/tree-sitter-containerfile.wasm"
|
|
45
50
|
},
|
|
46
51
|
"dependencies": {
|
|
47
|
-
"@
|
|
48
|
-
"@cyclonedx/cyclonedx-library": "^6.13.0",
|
|
52
|
+
"@yarnpkg/parsers": "^3.1.0",
|
|
49
53
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
50
|
-
"fast-
|
|
54
|
+
"fast-glob": "^3.3.3",
|
|
51
55
|
"fast-xml-parser": "^5.3.4",
|
|
52
56
|
"help": "^3.0.2",
|
|
53
|
-
"https-proxy-agent": "^
|
|
57
|
+
"https-proxy-agent": "^9.0.0",
|
|
58
|
+
"js-yaml": "^4.1.1",
|
|
59
|
+
"jsonc-parser": "^3.3.1",
|
|
60
|
+
"micromatch": "^4.0.8",
|
|
54
61
|
"node-fetch": "^3.3.2",
|
|
62
|
+
"p-limit": "^7.3.0",
|
|
55
63
|
"packageurl-js": "~1.0.2",
|
|
64
|
+
"smol-toml": "^1.6.0",
|
|
65
|
+
"tree-sitter-containerfile": "^0.8.1",
|
|
66
|
+
"tree-sitter-gomod": "github:strum355/tree-sitter-go-mod#56326f2ad478892ace58ff247a97d492a3cbcdda",
|
|
56
67
|
"tree-sitter-requirements": "github:Strum355/tree-sitter-requirements#d0261ee76b84253997fe70d7d397e78c006c3801",
|
|
57
|
-
"web-tree-sitter": "^0.26.
|
|
68
|
+
"web-tree-sitter": "^0.26.7",
|
|
58
69
|
"yargs": "^18.0.0"
|
|
59
70
|
},
|
|
60
71
|
"devDependencies": {
|
|
61
|
-
"@
|
|
62
|
-
"@
|
|
63
|
-
"@
|
|
72
|
+
"@cyclonedx/cyclonedx-library": "^10.2.0",
|
|
73
|
+
"@eslint/js": "^10.0.0",
|
|
74
|
+
"@trustify-da/trustify-da-api-model": "^2.0.12",
|
|
75
|
+
"@types/node": "^25.9.1",
|
|
64
76
|
"@types/which": "^3.0.4",
|
|
65
|
-
"
|
|
77
|
+
"ajv": "^8.20.0",
|
|
66
78
|
"c8": "^11.0.0",
|
|
67
|
-
"chai": "^
|
|
68
|
-
"eslint": "^
|
|
79
|
+
"chai": "^6.2.2",
|
|
80
|
+
"eslint": "^10.4.1",
|
|
69
81
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
70
|
-
"eslint-plugin-
|
|
71
|
-
"eslint-plugin-import": "^2.29.1",
|
|
82
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
72
83
|
"esmock": "^2.6.2",
|
|
73
|
-
"
|
|
84
|
+
"globals": "^17.6.0",
|
|
85
|
+
"mocha": "^11.7.6",
|
|
74
86
|
"msw": "^2.12.7",
|
|
75
|
-
"sinon": "^
|
|
76
|
-
"sinon-chai": "^
|
|
77
|
-
"typescript": "^
|
|
78
|
-
"which": "^
|
|
87
|
+
"sinon": "^22.0.0",
|
|
88
|
+
"sinon-chai": "^4.0.1",
|
|
89
|
+
"typescript": "^6.0.3",
|
|
90
|
+
"which": "^7.0.0"
|
|
79
91
|
},
|
|
80
92
|
"mocha": {
|
|
81
93
|
"check-leaks": false,
|
|
@@ -103,12 +115,13 @@
|
|
|
103
115
|
"reporter": [
|
|
104
116
|
"html",
|
|
105
117
|
"json",
|
|
118
|
+
"lcov",
|
|
106
119
|
"text"
|
|
107
120
|
]
|
|
108
121
|
},
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
|
|
122
|
+
"overrides": {
|
|
123
|
+
"tree-sitter": "0.22.4"
|
|
124
|
+
},
|
|
112
125
|
"resolutions": {
|
|
113
126
|
"@hapi/joi": "17.1.1"
|
|
114
127
|
}
|
package/dist/src/analysis.d.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
4
|
-
* @returns {{}}
|
|
5
|
-
*/
|
|
6
|
-
export function getTokenHeaders(opts?: import("index.js").Options): {};
|
|
1
|
+
/** Media type for CycloneDX JSON batch payloads (batch-analysis API). */
|
|
2
|
+
export const CYCLONEDX_JSON_MEDIA_TYPE: "application/vnd.cyclonedx+json";
|
|
7
3
|
declare namespace _default {
|
|
8
4
|
export { requestComponent };
|
|
9
5
|
export { requestStack };
|
|
6
|
+
export { requestStackBatch };
|
|
10
7
|
export { requestImages };
|
|
11
8
|
export { validateToken };
|
|
9
|
+
export { appendAnalysisQueryParams };
|
|
12
10
|
}
|
|
13
11
|
export default _default;
|
|
14
12
|
/**
|
|
@@ -17,28 +15,62 @@ export default _default;
|
|
|
17
15
|
* @param {string} manifest - path for the manifest
|
|
18
16
|
* @param {string} url - the backend url to send the request to
|
|
19
17
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
20
|
-
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
18
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
21
19
|
*/
|
|
22
|
-
declare function requestComponent(provider:
|
|
20
|
+
declare function requestComponent(provider: any, manifest: string, url: string, opts?: any): Promise<import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport>;
|
|
23
21
|
/**
|
|
24
|
-
*
|
|
25
|
-
* @param {import('./provider').Provider} provider
|
|
26
|
-
* @param {string} manifest
|
|
27
|
-
* @param {string} url
|
|
28
|
-
* @param {
|
|
29
|
-
* @param {import("index.js").Options} [opts={}]
|
|
30
|
-
* @returns {Promise<string
|
|
22
|
+
* @overload
|
|
23
|
+
* @param {import('./provider').Provider} provider
|
|
24
|
+
* @param {string} manifest
|
|
25
|
+
* @param {string} url
|
|
26
|
+
* @param {true} [html]
|
|
27
|
+
* @param {import("index.js").Options} [opts={}]
|
|
28
|
+
* @returns {Promise<string>}
|
|
29
|
+
*/
|
|
30
|
+
declare function requestStack(provider: any, manifest: string, url: string, html?: true | undefined, opts?: any): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* @overload
|
|
33
|
+
* @param {import('./provider').Provider} provider
|
|
34
|
+
* @param {string} manifest
|
|
35
|
+
* @param {string} url
|
|
36
|
+
* @param {false} [html]
|
|
37
|
+
* @param {import("index.js").Options} [opts={}]
|
|
38
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
39
|
+
*/
|
|
40
|
+
declare function requestStack(provider: any, manifest: string, url: string, html?: false | undefined, opts?: any): Promise<import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport>;
|
|
41
|
+
/**
|
|
42
|
+
* @overload
|
|
43
|
+
* @param {Object.<string, object>} sbomByPurl
|
|
44
|
+
* @param {string} url
|
|
45
|
+
* @param {true} [html=false]
|
|
46
|
+
* @param {import("index.js").Options} [opts={}]
|
|
47
|
+
* @returns {Promise<string>}
|
|
48
|
+
*/
|
|
49
|
+
declare function requestStackBatch(sbomByPurl: {
|
|
50
|
+
[x: string]: object;
|
|
51
|
+
}, url: string, html?: true | undefined, opts?: any): Promise<string>;
|
|
52
|
+
/**
|
|
53
|
+
* @overload
|
|
54
|
+
* @param {Object.<string, object>} sbomByPurl
|
|
55
|
+
* @param {string} url
|
|
56
|
+
* @param {false} [html=false]
|
|
57
|
+
* @param {import("index.js").Options} [opts={}]
|
|
58
|
+
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
31
59
|
*/
|
|
32
|
-
declare function
|
|
60
|
+
declare function requestStackBatch(sbomByPurl: {
|
|
61
|
+
[x: string]: object;
|
|
62
|
+
}, url: string, html?: false | undefined, opts?: any): Promise<{
|
|
63
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
64
|
+
}>;
|
|
33
65
|
/**
|
|
34
66
|
*
|
|
35
67
|
* @param {Array<string>} imageRefs
|
|
36
68
|
* @param {string} url
|
|
37
69
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
38
|
-
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
70
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
39
71
|
*/
|
|
40
|
-
declare function requestImages(imageRefs: Array<string>, url: string, html?: boolean, opts?:
|
|
41
|
-
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport;
|
|
72
|
+
declare function requestImages(imageRefs: Array<string>, url: string, html?: boolean, opts?: any): Promise<string | {
|
|
73
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
42
74
|
}>;
|
|
43
75
|
/**
|
|
44
76
|
*
|
|
@@ -46,4 +78,10 @@ declare function requestImages(imageRefs: Array<string>, url: string, html?: boo
|
|
|
46
78
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass headers for t he validateToken Request
|
|
47
79
|
* @return {Promise<number>} return the HTTP status Code of the response from the validate token request.
|
|
48
80
|
*/
|
|
49
|
-
declare function validateToken(url: any, opts?:
|
|
81
|
+
declare function validateToken(url: any, opts?: any): Promise<number>;
|
|
82
|
+
/**
|
|
83
|
+
* Append common analysis query parameters (recommend, providers, sources) to a URL.
|
|
84
|
+
* @param {URL} url - the URL object to append query parameters to
|
|
85
|
+
* @param {import("index.js").Options} [opts={}] - options containing parameter overrides
|
|
86
|
+
*/
|
|
87
|
+
declare function appendAnalysisQueryParams(url: URL, opts?: any): void;
|
package/dist/src/analysis.js
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { EOL } from "os";
|
|
4
|
-
import {
|
|
4
|
+
import { runLicenseCheck } from "./license/index.js";
|
|
5
5
|
import { generateImageSBOM, parseImageRef } from "./oci_image/utils.js";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const rhdaSourceHeader = "trust-da-source";
|
|
11
|
-
const rhdaOperationTypeHeader = "trust-da-operation-type";
|
|
12
|
-
const rhdaPackageManagerHeader = "trust-da-pkg-manager";
|
|
6
|
+
import { addProxyAgent, getCustom, getTokenHeaders, TRUSTIFY_DA_OPERATION_TYPE_HEADER, TRUSTIFY_DA_PACKAGE_MANAGER_HEADER } from "./tools.js";
|
|
7
|
+
/** Media type for CycloneDX JSON batch payloads (batch-analysis API). */
|
|
8
|
+
export const CYCLONEDX_JSON_MEDIA_TYPE = 'application/vnd.cyclonedx+json';
|
|
9
|
+
export default { requestComponent, requestStack, requestStackBatch, requestImages, validateToken, appendAnalysisQueryParams };
|
|
13
10
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {
|
|
16
|
-
* @param {
|
|
17
|
-
* @
|
|
11
|
+
* @overload
|
|
12
|
+
* @param {import('./provider').Provider} provider
|
|
13
|
+
* @param {string} manifest
|
|
14
|
+
* @param {string} url
|
|
15
|
+
* @param {true} [html]
|
|
16
|
+
* @param {import("index.js").Options} [opts={}]
|
|
17
|
+
* @returns {Promise<string>}
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* @overload
|
|
21
|
+
* @param {import('./provider').Provider} provider
|
|
22
|
+
* @param {string} manifest
|
|
23
|
+
* @param {string} url
|
|
24
|
+
* @param {false} [html]
|
|
25
|
+
* @param {import("index.js").Options} [opts={}]
|
|
26
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
18
27
|
*/
|
|
19
|
-
function addProxyAgent(options, opts) {
|
|
20
|
-
const proxyUrl = getCustom('TRUSTIFY_DA_PROXY_URL', null, opts);
|
|
21
|
-
if (proxyUrl) {
|
|
22
|
-
options.agent = new HttpsProxyAgent(proxyUrl);
|
|
23
|
-
}
|
|
24
|
-
return options;
|
|
25
|
-
}
|
|
26
28
|
/**
|
|
27
29
|
* Send a stack analysis request and get the report as 'text/html' or 'application/json'.
|
|
28
30
|
* @param {import('./provider').Provider} provider - the provided data for constructing the request
|
|
@@ -30,20 +32,23 @@ function addProxyAgent(options, opts) {
|
|
|
30
32
|
* @param {string} url - the backend url to send the request to
|
|
31
33
|
* @param {boolean} [html=false] - true will return 'text/html', false will return 'application/json'
|
|
32
34
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
33
|
-
* @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
35
|
+
* @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
34
36
|
*/
|
|
35
37
|
async function requestStack(provider, manifest, url, html = false, opts = {}) {
|
|
36
38
|
opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
|
|
37
39
|
opts["manifest-type"] = path.parse(manifest).base;
|
|
38
40
|
let provided = await provider.provideStack(manifest, opts); // throws error if content providing failed
|
|
41
|
+
if (provided.batch) {
|
|
42
|
+
return requestStackBatch(JSON.parse(provided.content), url, html, opts);
|
|
43
|
+
}
|
|
39
44
|
opts["source-manifest"] = "";
|
|
40
|
-
opts[
|
|
45
|
+
opts[TRUSTIFY_DA_OPERATION_TYPE_HEADER.toUpperCase().replaceAll("-", "_")] = "stack-analysis";
|
|
41
46
|
let startTime = new Date();
|
|
42
47
|
let endTime;
|
|
43
48
|
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
44
49
|
console.log("Starting time of sending stack analysis request to the dependency analytics server= " + startTime);
|
|
45
50
|
}
|
|
46
|
-
opts[
|
|
51
|
+
opts[TRUSTIFY_DA_PACKAGE_MANAGER_HEADER.toUpperCase().replaceAll("-", "_")] = provided.ecosystem;
|
|
47
52
|
const fetchOptions = addProxyAgent({
|
|
48
53
|
method: 'POST',
|
|
49
54
|
headers: {
|
|
@@ -53,10 +58,8 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
|
|
|
53
58
|
},
|
|
54
59
|
body: provided.content
|
|
55
60
|
}, opts);
|
|
56
|
-
const finalUrl = new URL(`${url}/api/
|
|
57
|
-
|
|
58
|
-
finalUrl.searchParams.append('recommend', 'false');
|
|
59
|
-
}
|
|
61
|
+
const finalUrl = new URL(`${url}/api/v5/analysis`);
|
|
62
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
60
63
|
let resp = await fetch(finalUrl, fetchOptions);
|
|
61
64
|
let result;
|
|
62
65
|
if (resp.status === 200) {
|
|
@@ -90,17 +93,20 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
|
|
|
90
93
|
* @param {string} manifest - path for the manifest
|
|
91
94
|
* @param {string} url - the backend url to send the request to
|
|
92
95
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
93
|
-
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
96
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
94
97
|
*/
|
|
95
98
|
async function requestComponent(provider, manifest, url, opts = {}) {
|
|
96
99
|
opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
|
|
97
100
|
let provided = await provider.provideComponent(manifest, opts); // throws error if content providing failed
|
|
101
|
+
if (provided.batch) {
|
|
102
|
+
return requestStackBatch(JSON.parse(provided.content), url, false, opts);
|
|
103
|
+
}
|
|
98
104
|
opts["source-manifest"] = "";
|
|
99
|
-
opts[
|
|
105
|
+
opts[TRUSTIFY_DA_OPERATION_TYPE_HEADER.toUpperCase().replaceAll("-", "_")] = "component-analysis";
|
|
100
106
|
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
101
107
|
console.log("Starting time of sending component analysis request to Trustify DA backend server= " + new Date());
|
|
102
108
|
}
|
|
103
|
-
opts[
|
|
109
|
+
opts[TRUSTIFY_DA_PACKAGE_MANAGER_HEADER.toUpperCase().replaceAll("-", "_")] = provided.ecosystem;
|
|
104
110
|
const fetchOptions = addProxyAgent({
|
|
105
111
|
method: 'POST',
|
|
106
112
|
headers: {
|
|
@@ -110,10 +116,8 @@ async function requestComponent(provider, manifest, url, opts = {}) {
|
|
|
110
116
|
},
|
|
111
117
|
body: provided.content
|
|
112
118
|
}, opts);
|
|
113
|
-
const finalUrl = new URL(`${url}/api/
|
|
114
|
-
|
|
115
|
-
finalUrl.searchParams.append('recommend', 'false');
|
|
116
|
-
}
|
|
119
|
+
const finalUrl = new URL(`${url}/api/v5/analysis`);
|
|
120
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
117
121
|
let resp = await fetch(finalUrl, fetchOptions);
|
|
118
122
|
let result;
|
|
119
123
|
if (resp.status === 200) {
|
|
@@ -127,18 +131,89 @@ async function requestComponent(provider, manifest, url, opts = {}) {
|
|
|
127
131
|
console.log(JSON.stringify(result, null, 4));
|
|
128
132
|
console.log("Ending time of sending component analysis request to Trustify DA backend server= " + new Date());
|
|
129
133
|
}
|
|
134
|
+
const licenseCheckEnabled = typeof opts.licenseCheck === 'boolean'
|
|
135
|
+
? opts.licenseCheck
|
|
136
|
+
: getCustom('TRUSTIFY_DA_LICENSE_CHECK', 'true', opts) !== 'false';
|
|
137
|
+
if (licenseCheckEnabled) {
|
|
138
|
+
try {
|
|
139
|
+
result.licenseSummary = await runLicenseCheck(provided.content, manifest, url, opts, result);
|
|
140
|
+
}
|
|
141
|
+
catch (licenseErr) {
|
|
142
|
+
result.licenseSummary = { error: licenseErr.message };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
130
145
|
}
|
|
131
146
|
else {
|
|
132
147
|
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
|
|
133
148
|
}
|
|
134
149
|
return Promise.resolve(result);
|
|
135
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* @overload
|
|
153
|
+
* @param {Object.<string, object>} sbomByPurl
|
|
154
|
+
* @param {string} url
|
|
155
|
+
* @param {true} [html=false]
|
|
156
|
+
* @param {import("index.js").Options} [opts={}]
|
|
157
|
+
* @returns {Promise<string>}
|
|
158
|
+
*/
|
|
159
|
+
/**
|
|
160
|
+
* @overload
|
|
161
|
+
* @param {Object.<string, object>} sbomByPurl
|
|
162
|
+
* @param {string} url
|
|
163
|
+
* @param {false} [html=false]
|
|
164
|
+
* @param {import("index.js").Options} [opts={}]
|
|
165
|
+
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
166
|
+
*/
|
|
167
|
+
/**
|
|
168
|
+
* Send a batch stack analysis request for multiple manifests (SBOMs keyed by purl).
|
|
169
|
+
* @param {Object.<string, object>} sbomByPurl - Map of root purl to CycloneDX SBOM object
|
|
170
|
+
* @param {string} url - the backend url
|
|
171
|
+
* @param {boolean} [html=false] - true returns HTML, false returns JSON
|
|
172
|
+
* @param {import("index.js").Options} [opts={}]
|
|
173
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
174
|
+
*/
|
|
175
|
+
async function requestStackBatch(sbomByPurl, url, html = false, opts = {}) {
|
|
176
|
+
const finalUrl = new URL(`${url}/api/v5/batch-analysis`);
|
|
177
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
178
|
+
const fetchOptions = addProxyAgent({
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers: {
|
|
181
|
+
'Accept': html ? 'text/html' : 'application/json',
|
|
182
|
+
'Content-Type': CYCLONEDX_JSON_MEDIA_TYPE,
|
|
183
|
+
...getTokenHeaders(opts)
|
|
184
|
+
},
|
|
185
|
+
body: JSON.stringify(sbomByPurl)
|
|
186
|
+
}, opts);
|
|
187
|
+
const resp = await fetch(finalUrl, fetchOptions);
|
|
188
|
+
if (resp.status === 200) {
|
|
189
|
+
let result;
|
|
190
|
+
if (!html) {
|
|
191
|
+
result = await resp.json();
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
result = await resp.text();
|
|
195
|
+
}
|
|
196
|
+
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
197
|
+
const exRequestId = resp.headers.get("ex-request-id");
|
|
198
|
+
if (exRequestId) {
|
|
199
|
+
console.log("Unique Identifier associated with this request - ex-request-id=" + exRequestId);
|
|
200
|
+
}
|
|
201
|
+
console.log("Response body received from Trustify DA backend server : " + EOL + EOL);
|
|
202
|
+
console.log(JSON.stringify(result, null, 4));
|
|
203
|
+
console.log("Ending time of sending batch stack analysis request to Trustify DA backend server= " + new Date());
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
136
211
|
/**
|
|
137
212
|
*
|
|
138
213
|
* @param {Array<string>} imageRefs
|
|
139
214
|
* @param {string} url
|
|
140
215
|
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
141
|
-
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
216
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
142
217
|
*/
|
|
143
218
|
async function requestImages(imageRefs, url, html = false, opts = {}) {
|
|
144
219
|
const imageSboms = {};
|
|
@@ -146,19 +221,18 @@ async function requestImages(imageRefs, url, html = false, opts = {}) {
|
|
|
146
221
|
const parsedImageRef = parseImageRef(image, opts);
|
|
147
222
|
imageSboms[parsedImageRef.getPackageURL().toString()] = generateImageSBOM(parsedImageRef, opts);
|
|
148
223
|
}
|
|
149
|
-
const finalUrl = new URL(`${url}/api/
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
const resp = await fetch(finalUrl, {
|
|
224
|
+
const finalUrl = new URL(`${url}/api/v5/batch-analysis`);
|
|
225
|
+
appendAnalysisQueryParams(finalUrl, opts);
|
|
226
|
+
const fetchOptions = addProxyAgent({
|
|
154
227
|
method: 'POST',
|
|
155
228
|
headers: {
|
|
156
229
|
'Accept': html ? 'text/html' : 'application/json',
|
|
157
|
-
'Content-Type':
|
|
230
|
+
'Content-Type': CYCLONEDX_JSON_MEDIA_TYPE,
|
|
158
231
|
...getTokenHeaders(opts)
|
|
159
232
|
},
|
|
160
233
|
body: JSON.stringify(imageSboms),
|
|
161
|
-
});
|
|
234
|
+
}, opts);
|
|
235
|
+
const resp = await fetch(finalUrl, fetchOptions);
|
|
162
236
|
if (resp.status === 200) {
|
|
163
237
|
let result;
|
|
164
238
|
if (!html) {
|
|
@@ -182,6 +256,24 @@ async function requestImages(imageRefs, url, html = false, opts = {}) {
|
|
|
182
256
|
throw new Error(`Got error response from Trustify DA backend - http return code : ${resp.status}, ex-request-id: ${resp.headers.get("ex-request-id")} error message => ${await resp.text()}`);
|
|
183
257
|
}
|
|
184
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Append common analysis query parameters (recommend, providers, sources) to a URL.
|
|
261
|
+
* @param {URL} url - the URL object to append query parameters to
|
|
262
|
+
* @param {import("index.js").Options} [opts={}] - options containing parameter overrides
|
|
263
|
+
*/
|
|
264
|
+
function appendAnalysisQueryParams(url, opts = {}) {
|
|
265
|
+
if (getCustom('TRUSTIFY_DA_RECOMMEND', 'true', opts) === 'false') {
|
|
266
|
+
url.searchParams.append('recommend', 'false');
|
|
267
|
+
}
|
|
268
|
+
const providers = getCustom('TRUSTIFY_DA_PROVIDERS', null, opts);
|
|
269
|
+
if (providers) {
|
|
270
|
+
url.searchParams.append('providers', providers);
|
|
271
|
+
}
|
|
272
|
+
const sources = getCustom('TRUSTIFY_DA_SOURCES', null, opts);
|
|
273
|
+
if (sources) {
|
|
274
|
+
url.searchParams.append('sources', sources);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
185
277
|
/**
|
|
186
278
|
*
|
|
187
279
|
* @param url the backend url to send the request to
|
|
@@ -195,7 +287,7 @@ async function validateToken(url, opts = {}) {
|
|
|
195
287
|
...getTokenHeaders(opts),
|
|
196
288
|
}
|
|
197
289
|
}, opts);
|
|
198
|
-
let resp = await fetch(`${url}/api/
|
|
290
|
+
let resp = await fetch(`${url}/api/v5/token`, fetchOptions);
|
|
199
291
|
if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
|
|
200
292
|
let exRequestId = resp.headers.get("ex-request-id");
|
|
201
293
|
if (exRequestId) {
|
|
@@ -204,39 +296,3 @@ async function validateToken(url, opts = {}) {
|
|
|
204
296
|
}
|
|
205
297
|
return resp.status;
|
|
206
298
|
}
|
|
207
|
-
/**
|
|
208
|
-
*
|
|
209
|
-
* @param {string} headerName - the header name to populate in request
|
|
210
|
-
* @param headers
|
|
211
|
-
* @param {string} optsKey - key in the options object to use the value for
|
|
212
|
-
* @param {import("index.js").Options} [opts={}] - options input object to fetch header values from
|
|
213
|
-
* @private
|
|
214
|
-
*/
|
|
215
|
-
function setRhdaHeader(headerName, headers, optsKey, opts) {
|
|
216
|
-
let rhdaHeaderValue = getCustom(optsKey, null, opts);
|
|
217
|
-
if (rhdaHeaderValue) {
|
|
218
|
-
headers[headerName] = rhdaHeaderValue;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Utility function for fetching vendor tokens
|
|
223
|
-
* @param {import("index.js").Options} [opts={}] - optional various options to pass along the application
|
|
224
|
-
* @returns {{}}
|
|
225
|
-
*/
|
|
226
|
-
export function getTokenHeaders(opts = {}) {
|
|
227
|
-
let headers = {};
|
|
228
|
-
setRhdaHeader(rhdaTokenHeader, headers, 'TRUSTIFY_DA_TOKEN', opts);
|
|
229
|
-
setRhdaHeader(rhdaSourceHeader, headers, 'TRUSTIFY_DA_SOURCE', opts);
|
|
230
|
-
setRhdaHeader(rhdaOperationTypeHeader, headers, rhdaOperationTypeHeader.toUpperCase().replaceAll("-", "_"), opts);
|
|
231
|
-
setRhdaHeader(rhdaPackageManagerHeader, headers, rhdaPackageManagerHeader.toUpperCase().replaceAll("-", "_"), opts);
|
|
232
|
-
setRhdaHeader(rhdaTelemetryId, headers, 'TRUSTIFY_DA_TELEMETRY_ID', opts);
|
|
233
|
-
if (getCustom("TRUSTIFY_DA_DEBUG", null, opts) === "true") {
|
|
234
|
-
console.log("Headers Values to be sent to Trustify DA backend:" + EOL);
|
|
235
|
-
for (const headerKey in headers) {
|
|
236
|
-
if (!headerKey.match(RegexNotToBeLogged)) {
|
|
237
|
-
console.log(`${headerKey}: ${headers[headerKey]}`);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return headers;
|
|
242
|
-
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether to skip failed manifests and continue (default), or fail on first SBOM/validation error.
|
|
3
|
+
* `opts.continueOnError` overrides; env `TRUSTIFY_DA_CONTINUE_ON_ERROR=false` disables continuation.
|
|
4
|
+
*
|
|
5
|
+
* @param {{ continueOnError?: boolean, TRUSTIFY_DA_CONTINUE_ON_ERROR?: string, [key: string]: unknown }} [opts={}]
|
|
6
|
+
* @returns {boolean} true = collect errors (default), false = fail-fast
|
|
7
|
+
*/
|
|
8
|
+
export function resolveContinueOnError(opts?: {
|
|
9
|
+
continueOnError?: boolean;
|
|
10
|
+
TRUSTIFY_DA_CONTINUE_ON_ERROR?: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* When true, `stackAnalysisBatch` returns `{ analysis, metadata }` instead of the backend response only.
|
|
15
|
+
* `opts.batchMetadata` overrides; env `TRUSTIFY_DA_BATCH_METADATA=true` enables.
|
|
16
|
+
*
|
|
17
|
+
* @param {{ batchMetadata?: boolean, TRUSTIFY_DA_BATCH_METADATA?: string, [key: string]: unknown }} [opts={}]
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
export function resolveBatchMetadata(opts?: {
|
|
21
|
+
batchMetadata?: boolean;
|
|
22
|
+
TRUSTIFY_DA_BATCH_METADATA?: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getCustom } from './tools.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether to skip failed manifests and continue (default), or fail on first SBOM/validation error.
|
|
4
|
+
* `opts.continueOnError` overrides; env `TRUSTIFY_DA_CONTINUE_ON_ERROR=false` disables continuation.
|
|
5
|
+
*
|
|
6
|
+
* @param {{ continueOnError?: boolean, TRUSTIFY_DA_CONTINUE_ON_ERROR?: string, [key: string]: unknown }} [opts={}]
|
|
7
|
+
* @returns {boolean} true = collect errors (default), false = fail-fast
|
|
8
|
+
*/
|
|
9
|
+
export function resolveContinueOnError(opts = {}) {
|
|
10
|
+
if (typeof opts.continueOnError === 'boolean') {
|
|
11
|
+
return opts.continueOnError;
|
|
12
|
+
}
|
|
13
|
+
const v = getCustom('TRUSTIFY_DA_CONTINUE_ON_ERROR', null, opts);
|
|
14
|
+
if (v != null && String(v).trim() !== '') {
|
|
15
|
+
return String(v).toLowerCase() !== 'false';
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* When true, `stackAnalysisBatch` returns `{ analysis, metadata }` instead of the backend response only.
|
|
21
|
+
* `opts.batchMetadata` overrides; env `TRUSTIFY_DA_BATCH_METADATA=true` enables.
|
|
22
|
+
*
|
|
23
|
+
* @param {{ batchMetadata?: boolean, TRUSTIFY_DA_BATCH_METADATA?: string, [key: string]: unknown }} [opts={}]
|
|
24
|
+
* @returns {boolean}
|
|
25
|
+
*/
|
|
26
|
+
export function resolveBatchMetadata(opts = {}) {
|
|
27
|
+
if (typeof opts.batchMetadata === 'boolean') {
|
|
28
|
+
return opts.batchMetadata;
|
|
29
|
+
}
|
|
30
|
+
const v = getCustom('TRUSTIFY_DA_BATCH_METADATA', null, opts);
|
|
31
|
+
if (v != null && String(v).trim() !== '') {
|
|
32
|
+
return String(v).toLowerCase() === 'true';
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|