@trustify-da/trustify-da-javascript-client 0.3.0-ea.2ea1d77 → 0.3.0-ea.328523e
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 +272 -19
- package/dist/package.json +33 -28
- package/dist/src/analysis.d.ts +52 -22
- package/dist/src/analysis.js +77 -22
- package/dist/src/cli.js +238 -7
- package/dist/src/config.d.ts +120 -0
- package/dist/src/config.js +260 -0
- package/dist/src/cyclone_dx_sbom.d.ts +27 -1
- package/dist/src/cyclone_dx_sbom.js +82 -9
- package/dist/src/index.d.ts +97 -22
- package/dist/src/index.js +115 -42
- package/dist/src/license/index.d.ts +4 -4
- package/dist/src/license/index.js +13 -7
- package/dist/src/license/license_utils.js +4 -1
- package/dist/src/license/licenses_api.d.ts +3 -3
- package/dist/src/license/licenses_api.js +1 -1
- 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 +4 -3
- package/dist/src/provider.js +12 -2
- 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 +90 -15
- package/dist/src/providers/base_javascript.js +206 -24
- 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 +23 -13
- package/dist/src/providers/golang_gomodules.js +208 -120
- 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 +67 -0
- package/dist/src/providers/java_gradle.js +320 -22
- 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 +37 -9
- package/dist/src/providers/java_maven.js +269 -11
- 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 +13 -0
- package/dist/src/providers/javascript_pnpm.js +53 -3
- 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 +5 -0
- package/dist/src/providers/python_pip.js +6 -6
- 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 +1 -1
- package/dist/src/providers/rust_cargo.d.ts +6 -2
- package/dist/src/providers/rust_cargo.js +101 -33
- package/dist/src/providers/tree-sitter-containerfile.wasm +0 -0
- package/dist/src/providers/tree-sitter-gomod.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 +25 -1
- package/dist/src/sbom.js +23 -2
- package/dist/src/tools.d.ts +37 -13
- package/dist/src/tools.js +92 -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 +11 -1
- package/dist/src/workspace.js +3 -2
- package/package.json +34 -29
package/dist/src/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* 1. Environment Variable
|
|
5
|
-
* 2. (key,value) from opts object
|
|
2
|
+
* Selects the Trustify DA backend URL from opts.TRUSTIFY_DA_BACKEND_URL, then environment
|
|
3
|
+
* variable TRUSTIFY_DA_BACKEND_URL. Options take precedence over environment variables.
|
|
6
4
|
* If TRUSTIFY_DA_BACKEND_URL is not set, the function will throw an error.
|
|
7
5
|
* @param {{TRUSTIFY_DA_DEBUG?: string | undefined; TRUSTIFY_DA_BACKEND_URL?: string | undefined}} [opts={}]
|
|
8
6
|
* @return {string} - The selected Trustify DA backend URL
|
|
@@ -13,6 +11,15 @@ export function selectTrustifyDABackend(opts?: {
|
|
|
13
11
|
TRUSTIFY_DA_DEBUG?: string | undefined;
|
|
14
12
|
TRUSTIFY_DA_BACKEND_URL?: string | undefined;
|
|
15
13
|
}): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generate a CycloneDX SBOM from a manifest file. No backend HTTP request is made.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} manifestPath - path to the manifest file (e.g. pom.xml, package.json)
|
|
18
|
+
* @param {Options} [opts={}] - optional options (e.g. workspace dir, tool paths)
|
|
19
|
+
* @returns {Promise<object>} parsed CycloneDX SBOM JSON object
|
|
20
|
+
* @throws {Error} if the manifest is unsupported or SBOM generation fails
|
|
21
|
+
*/
|
|
22
|
+
export function generateSbom(manifestPath: string, opts?: Options): Promise<object>;
|
|
16
23
|
export { parseImageRef } from "./oci_image/utils.js";
|
|
17
24
|
export { ImageRef } from "./oci_image/images.js";
|
|
18
25
|
declare namespace _default {
|
|
@@ -21,6 +28,7 @@ declare namespace _default {
|
|
|
21
28
|
export { stackAnalysisBatch };
|
|
22
29
|
export { imageAnalysis };
|
|
23
30
|
export { validateToken };
|
|
31
|
+
export { generateSbom };
|
|
24
32
|
}
|
|
25
33
|
export default _default;
|
|
26
34
|
export type Options = {
|
|
@@ -43,7 +51,9 @@ export type Options = {
|
|
|
43
51
|
TRUSTIFY_DA_PYTHON_PATH?: string | undefined;
|
|
44
52
|
TRUSTIFY_DA_PYTHON_VIRTUAL_ENV?: string | undefined;
|
|
45
53
|
TRUSTIFY_DA_PYTHON3_PATH?: string | undefined;
|
|
46
|
-
|
|
54
|
+
TRUSTIFY_DA_PROVIDERS?: string | undefined;
|
|
55
|
+
TRUSTIFY_DA_RECOMMEND?: string | undefined;
|
|
56
|
+
TRUSTIFY_DA_SOURCES?: string | undefined;
|
|
47
57
|
TRUSTIFY_DA_SKOPEO_CONFIG_PATH?: string | undefined;
|
|
48
58
|
TRUSTIFY_DA_SKOPEO_PATH?: string | undefined;
|
|
49
59
|
TRUSTIFY_DA_SYFT_CONFIG_PATH?: string | undefined;
|
|
@@ -51,11 +61,11 @@ export type Options = {
|
|
|
51
61
|
TRUSTIFY_DA_YARN_PATH?: string | undefined;
|
|
52
62
|
TRUSTIFY_DA_WORKSPACE_DIR?: string | undefined;
|
|
53
63
|
TRUSTIFY_DA_LICENSE_CHECK?: string | undefined;
|
|
64
|
+
licenseCheck?: boolean | undefined;
|
|
54
65
|
MATCH_MANIFEST_VERSIONS?: string | undefined;
|
|
55
66
|
TRUSTIFY_DA_SOURCE?: string | undefined;
|
|
56
67
|
TRUSTIFY_DA_TOKEN?: string | undefined;
|
|
57
68
|
TRUSTIFY_DA_TELEMETRY_ID?: string | undefined;
|
|
58
|
-
TRUSTIFY_DA_WORKSPACE_DIR?: string | undefined;
|
|
59
69
|
batchConcurrency?: number | undefined;
|
|
60
70
|
TRUSTIFY_DA_BATCH_CONCURRENCY?: string | undefined;
|
|
61
71
|
workspaceDiscoveryIgnore?: string[] | undefined;
|
|
@@ -64,11 +74,13 @@ export type Options = {
|
|
|
64
74
|
TRUSTIFY_DA_CONTINUE_ON_ERROR?: string | undefined;
|
|
65
75
|
batchMetadata?: boolean | undefined;
|
|
66
76
|
TRUSTIFY_DA_BATCH_METADATA?: string | undefined;
|
|
77
|
+
TRUSTIFY_DA_UV_PATH?: string | undefined;
|
|
78
|
+
TRUSTIFY_DA_POETRY_PATH?: string | undefined;
|
|
67
79
|
[key: string]: string | number | boolean | string[] | undefined;
|
|
68
80
|
};
|
|
69
81
|
export type BatchAnalysisMetadata = {
|
|
70
82
|
workspaceRoot: string;
|
|
71
|
-
ecosystem: "javascript" | "cargo" | "unknown";
|
|
83
|
+
ecosystem: "javascript" | "cargo" | "pyproject" | "unknown";
|
|
72
84
|
total: number;
|
|
73
85
|
successful: number;
|
|
74
86
|
failed: number;
|
|
@@ -91,10 +103,10 @@ export type SbomResult = {
|
|
|
91
103
|
* Get component analysis report for a manifest content.
|
|
92
104
|
* @param {string} manifest - path to the manifest
|
|
93
105
|
* @param {Options} [opts={}] - optional various options to pass along the application
|
|
94
|
-
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
106
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
95
107
|
* @throws {Error} if no matching provider, failed to get create content, or backend request failed
|
|
96
108
|
*/
|
|
97
|
-
declare function componentAnalysis(manifest: string, opts?: Options): Promise<import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport>;
|
|
109
|
+
declare function componentAnalysis(manifest: string, opts?: Options): Promise<import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport>;
|
|
98
110
|
/**
|
|
99
111
|
* @overload
|
|
100
112
|
* @param {string} manifest
|
|
@@ -109,38 +121,93 @@ declare function stackAnalysis(manifest: string, html: true, opts?: Options | un
|
|
|
109
121
|
* @param {string} manifest
|
|
110
122
|
* @param {false} html
|
|
111
123
|
* @param {Options} [opts={}]
|
|
112
|
-
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
124
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
113
125
|
* @throws {Error}
|
|
114
126
|
*/
|
|
115
|
-
declare function stackAnalysis(manifest: string, html: false, opts?: Options | undefined): Promise<import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport>;
|
|
127
|
+
declare function stackAnalysis(manifest: string, html: false, opts?: Options | undefined): Promise<import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport>;
|
|
116
128
|
/**
|
|
117
129
|
* Get stack analysis report for a manifest file.
|
|
118
130
|
* @overload
|
|
119
131
|
* @param {string} manifest - path for the manifest
|
|
120
132
|
* @param {boolean} [html=false] - true will return a html string, false will return AnalysisReport object.
|
|
121
133
|
* @param {Options} [opts={}] - optional various options to pass along the application
|
|
122
|
-
* @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
134
|
+
* @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
123
135
|
* @throws {Error} if manifest inaccessible, no matching provider, failed to get create content,
|
|
124
136
|
* or backend request failed
|
|
125
137
|
*/
|
|
126
|
-
declare function stackAnalysis(manifest: string, html?: boolean | undefined, opts?: Options | undefined): Promise<string | import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport>;
|
|
138
|
+
declare function stackAnalysis(manifest: string, html?: boolean | undefined, opts?: Options | undefined): Promise<string | import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport>;
|
|
139
|
+
/**
|
|
140
|
+
* @overload
|
|
141
|
+
* @param {string} workspaceRoot
|
|
142
|
+
* @param {true} html
|
|
143
|
+
* @param {Options & { batchMetadata: true }} opts
|
|
144
|
+
* @returns {Promise<{ analysis: string, metadata: BatchAnalysisMetadata }>}
|
|
145
|
+
* @throws {Error}
|
|
146
|
+
*/
|
|
147
|
+
declare function stackAnalysisBatch(workspaceRoot: string, html: true, opts: Options & {
|
|
148
|
+
batchMetadata: true;
|
|
149
|
+
}): Promise<{
|
|
150
|
+
analysis: string;
|
|
151
|
+
metadata: BatchAnalysisMetadata;
|
|
152
|
+
}>;
|
|
153
|
+
/**
|
|
154
|
+
* @overload
|
|
155
|
+
* @param {string} workspaceRoot
|
|
156
|
+
* @param {true} html
|
|
157
|
+
* @param {Options & { batchMetadata?: false }} [opts={}]
|
|
158
|
+
* @returns {Promise<string>}
|
|
159
|
+
* @throws {Error}
|
|
160
|
+
*/
|
|
161
|
+
declare function stackAnalysisBatch(workspaceRoot: string, html: true, opts?: (Options & {
|
|
162
|
+
batchMetadata?: false;
|
|
163
|
+
}) | undefined): Promise<string>;
|
|
164
|
+
/**
|
|
165
|
+
* @overload
|
|
166
|
+
* @param {string} workspaceRoot
|
|
167
|
+
* @param {false} html
|
|
168
|
+
* @param {Options & { batchMetadata: true }} opts
|
|
169
|
+
* @returns {Promise<{ analysis: Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>, metadata: BatchAnalysisMetadata }>}
|
|
170
|
+
* @throws {Error}
|
|
171
|
+
*/
|
|
172
|
+
declare function stackAnalysisBatch(workspaceRoot: string, html: false, opts: Options & {
|
|
173
|
+
batchMetadata: true;
|
|
174
|
+
}): Promise<{
|
|
175
|
+
analysis: {
|
|
176
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
177
|
+
};
|
|
178
|
+
metadata: BatchAnalysisMetadata;
|
|
179
|
+
}>;
|
|
180
|
+
/**
|
|
181
|
+
* @overload
|
|
182
|
+
* @param {string} workspaceRoot
|
|
183
|
+
* @param {false} html
|
|
184
|
+
* @param {Options & { batchMetadata?: false }} [opts={}]
|
|
185
|
+
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
186
|
+
* @throws {Error}
|
|
187
|
+
*/
|
|
188
|
+
declare function stackAnalysisBatch(workspaceRoot: string, html: false, opts?: (Options & {
|
|
189
|
+
batchMetadata?: false;
|
|
190
|
+
}) | undefined): Promise<{
|
|
191
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
192
|
+
}>;
|
|
127
193
|
/**
|
|
128
194
|
* Get stack analysis for all workspace packages/crates (batch).
|
|
129
195
|
* Detects ecosystem from workspace root: Cargo (Cargo.toml + Cargo.lock) or JS/TS (package.json + lock file).
|
|
130
196
|
* SBOMs are generated in parallel (see `batchConcurrency`) unless `continueOnError: false` (fail-fast sequential).
|
|
131
197
|
* With `opts.batchMetadata` / `TRUSTIFY_DA_BATCH_METADATA`, returns `{ analysis, metadata }` including validation and SBOM errors.
|
|
132
198
|
*
|
|
199
|
+
* @overload
|
|
133
200
|
* @param {string} workspaceRoot - Path to workspace root (containing lock file and workspace config)
|
|
134
201
|
* @param {boolean} [html=false] - true returns HTML, false returns JSON report
|
|
135
202
|
* @param {Options} [opts={}] - `batchConcurrency`, discovery ignores, `continueOnError` (default true), `batchMetadata` (default false)
|
|
136
|
-
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>|{ analysis: string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>, metadata: BatchAnalysisMetadata }>}
|
|
203
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>|{ analysis: string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>, metadata: BatchAnalysisMetadata }>}
|
|
137
204
|
* @throws {Error} if workspace root invalid, no manifests found, no packages pass validation, no SBOMs produced, or backend request failed. When `opts.batchMetadata` is set, `error.batchMetadata` may be set on thrown errors.
|
|
138
205
|
*/
|
|
139
|
-
declare function stackAnalysisBatch(workspaceRoot: string, html?: boolean, opts?: Options): Promise<string | {
|
|
140
|
-
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport;
|
|
206
|
+
declare function stackAnalysisBatch(workspaceRoot: string, html?: boolean | undefined, opts?: Options | undefined): Promise<string | {
|
|
207
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
141
208
|
} | {
|
|
142
209
|
analysis: string | {
|
|
143
|
-
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport;
|
|
210
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
144
211
|
};
|
|
145
212
|
metadata: BatchAnalysisMetadata;
|
|
146
213
|
}>;
|
|
@@ -158,11 +225,11 @@ declare function imageAnalysis(imageRefs: Array<string>, html: true, opts?: Opti
|
|
|
158
225
|
* @param {Array<string>} imageRefs
|
|
159
226
|
* @param {false} html
|
|
160
227
|
* @param {Options} [opts={}]
|
|
161
|
-
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
228
|
+
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
162
229
|
* @throws {Error}
|
|
163
230
|
*/
|
|
164
231
|
declare function imageAnalysis(imageRefs: Array<string>, html: false, opts?: Options | undefined): Promise<{
|
|
165
|
-
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport;
|
|
232
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
166
233
|
}>;
|
|
167
234
|
/**
|
|
168
235
|
* Get image analysis report for a set of OCI image references.
|
|
@@ -170,12 +237,12 @@ declare function imageAnalysis(imageRefs: Array<string>, html: false, opts?: Opt
|
|
|
170
237
|
* @param {Array<string>} imageRefs - OCI image references
|
|
171
238
|
* @param {boolean} [html=false] - true will return a html string, false will return AnalysisReport
|
|
172
239
|
* @param {Options} [opts={}] - optional various options to pass along the application
|
|
173
|
-
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
240
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
174
241
|
* @throws {Error} if manifest inaccessible, no matching provider, failed to get create content,
|
|
175
242
|
* or backend request failed
|
|
176
243
|
*/
|
|
177
244
|
declare function imageAnalysis(imageRefs: Array<string>, html?: boolean | undefined, opts?: Options | undefined): Promise<string | {
|
|
178
|
-
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport;
|
|
245
|
+
[x: string]: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport;
|
|
179
246
|
}>;
|
|
180
247
|
/**
|
|
181
248
|
* Validates the Exhort token.
|
|
@@ -184,6 +251,10 @@ declare function imageAnalysis(imageRefs: Array<string>, html?: boolean | undefi
|
|
|
184
251
|
* @throws {Error} if the backend request failed.
|
|
185
252
|
*/
|
|
186
253
|
declare function validateToken(opts?: Options): Promise<object>;
|
|
254
|
+
import { discoverMavenModules } from './providers/java_maven.js';
|
|
255
|
+
import { discoverGradleSubprojects } from './providers/java_gradle.js';
|
|
256
|
+
import { discoverGoWorkspaceModules } from './providers/golang_gomodules.js';
|
|
257
|
+
import { discoverUvWorkspaceMembers } from './providers/python_uv.js';
|
|
187
258
|
import { discoverWorkspacePackages } from './workspace.js';
|
|
188
259
|
import { discoverWorkspaceCrates } from './workspace.js';
|
|
189
260
|
import { validatePackageJson } from './workspace.js';
|
|
@@ -191,5 +262,9 @@ import { resolveWorkspaceDiscoveryIgnore } from './workspace.js';
|
|
|
191
262
|
import { filterManifestPathsByDiscoveryIgnore } from './workspace.js';
|
|
192
263
|
import { resolveContinueOnError } from './batch_opts.js';
|
|
193
264
|
import { resolveBatchMetadata } from './batch_opts.js';
|
|
194
|
-
export { discoverWorkspacePackages, discoverWorkspaceCrates, validatePackageJson, resolveWorkspaceDiscoveryIgnore, filterManifestPathsByDiscoveryIgnore, resolveContinueOnError, resolveBatchMetadata };
|
|
265
|
+
export { discoverMavenModules, discoverGradleSubprojects, discoverGoWorkspaceModules, discoverUvWorkspaceMembers, discoverWorkspacePackages, discoverWorkspaceCrates, validatePackageJson, resolveWorkspaceDiscoveryIgnore, filterManifestPathsByDiscoveryIgnore, resolveContinueOnError, resolveBatchMetadata };
|
|
195
266
|
export { getProjectLicense, findLicenseFilePath, identifyLicense, getLicenseDetails, licensesFromReport, normalizeLicensesResponse, runLicenseCheck, getCompatibility } from "./license/index.js";
|
|
267
|
+
export { extractRemediations, maxSeverity } from "./remediation.js";
|
|
268
|
+
export { generateReport, generateDeduplicationKey } from "./remediation_report.js";
|
|
269
|
+
export { loadConfig, mergeConfig, resolveConfig, CONFIG_FILENAMES } from "./config.js";
|
|
270
|
+
export { runRemediation, findManifests } from "./remediate.js";
|
package/dist/src/index.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
1
2
|
import path from "node:path";
|
|
2
3
|
import { EOL } from "os";
|
|
3
4
|
import pLimit from 'p-limit';
|
|
4
|
-
import { availableProviders, match } from './provider.js';
|
|
5
5
|
import analysis from './analysis.js';
|
|
6
|
-
import fs from 'node:fs';
|
|
7
|
-
import { getCustom } from "./tools.js";
|
|
8
6
|
import { resolveBatchMetadata, resolveContinueOnError } from './batch_opts.js';
|
|
7
|
+
import { getPackageVersion } from './package_version.js';
|
|
8
|
+
import { availableProviders, match } from './provider.js';
|
|
9
|
+
import { discoverGoWorkspaceModules } from './providers/golang_gomodules.js';
|
|
10
|
+
import { discoverGradleSubprojects } from './providers/java_gradle.js';
|
|
11
|
+
import { discoverMavenModules } from './providers/java_maven.js';
|
|
12
|
+
import { discoverUvWorkspaceMembers } from './providers/python_uv.js';
|
|
13
|
+
import { getCustom } from "./tools.js";
|
|
9
14
|
import { discoverWorkspaceCrates, discoverWorkspacePackages, filterManifestPathsByDiscoveryIgnore, resolveWorkspaceDiscoveryIgnore, validatePackageJson, } from './workspace.js';
|
|
10
|
-
import.meta.dirname;
|
|
11
|
-
import * as url from 'url';
|
|
12
15
|
export { parseImageRef } from "./oci_image/utils.js";
|
|
13
16
|
export { ImageRef } from "./oci_image/images.js";
|
|
14
17
|
export { getProjectLicense, findLicenseFilePath, identifyLicense, getLicenseDetails, licensesFromReport, normalizeLicensesResponse, runLicenseCheck, getCompatibility } from "./license/index.js";
|
|
15
|
-
export
|
|
16
|
-
export {
|
|
18
|
+
export { extractRemediations, maxSeverity } from "./remediation.js";
|
|
19
|
+
export { generateReport, generateDeduplicationKey } from './remediation_report.js';
|
|
20
|
+
export { loadConfig, mergeConfig, resolveConfig, CONFIG_FILENAMES } from './config.js';
|
|
21
|
+
export { runRemediation, findManifests } from './remediate.js';
|
|
22
|
+
export default { componentAnalysis, stackAnalysis, stackAnalysisBatch, imageAnalysis, validateToken, generateSbom };
|
|
23
|
+
export { discoverMavenModules, discoverGradleSubprojects, discoverGoWorkspaceModules, discoverUvWorkspaceMembers, discoverWorkspacePackages, discoverWorkspaceCrates, validatePackageJson, resolveWorkspaceDiscoveryIgnore, filterManifestPathsByDiscoveryIgnore, resolveContinueOnError, resolveBatchMetadata, };
|
|
17
24
|
/**
|
|
18
25
|
* @typedef {{
|
|
19
26
|
* TRUSTIFY_DA_CARGO_PATH?: string | undefined,
|
|
@@ -35,7 +42,9 @@ export { discoverWorkspacePackages, discoverWorkspaceCrates, validatePackageJson
|
|
|
35
42
|
* TRUSTIFY_DA_PYTHON_PATH?: string | undefined,
|
|
36
43
|
* TRUSTIFY_DA_PYTHON_VIRTUAL_ENV?: string | undefined,
|
|
37
44
|
* TRUSTIFY_DA_PYTHON3_PATH?: string | undefined,
|
|
38
|
-
*
|
|
45
|
+
* TRUSTIFY_DA_PROVIDERS?: string | undefined,
|
|
46
|
+
* TRUSTIFY_DA_RECOMMEND?: string | undefined,
|
|
47
|
+
* TRUSTIFY_DA_SOURCES?: string | undefined,
|
|
39
48
|
* TRUSTIFY_DA_SKOPEO_CONFIG_PATH?: string | undefined,
|
|
40
49
|
* TRUSTIFY_DA_SKOPEO_PATH?: string | undefined,
|
|
41
50
|
* TRUSTIFY_DA_SYFT_CONFIG_PATH?: string | undefined,
|
|
@@ -43,11 +52,11 @@ export { discoverWorkspacePackages, discoverWorkspaceCrates, validatePackageJson
|
|
|
43
52
|
* TRUSTIFY_DA_YARN_PATH?: string | undefined,
|
|
44
53
|
* TRUSTIFY_DA_WORKSPACE_DIR?: string | undefined,
|
|
45
54
|
* TRUSTIFY_DA_LICENSE_CHECK?: string | undefined,
|
|
55
|
+
* licenseCheck?: boolean | undefined,
|
|
46
56
|
* MATCH_MANIFEST_VERSIONS?: string | undefined,
|
|
47
57
|
* TRUSTIFY_DA_SOURCE?: string | undefined,
|
|
48
58
|
* TRUSTIFY_DA_TOKEN?: string | undefined,
|
|
49
59
|
* TRUSTIFY_DA_TELEMETRY_ID?: string | undefined,
|
|
50
|
-
* TRUSTIFY_DA_WORKSPACE_DIR?: string | undefined,
|
|
51
60
|
* batchConcurrency?: number | undefined,
|
|
52
61
|
* TRUSTIFY_DA_BATCH_CONCURRENCY?: string | undefined,
|
|
53
62
|
* workspaceDiscoveryIgnore?: string[] | undefined,
|
|
@@ -56,13 +65,15 @@ export { discoverWorkspacePackages, discoverWorkspaceCrates, validatePackageJson
|
|
|
56
65
|
* TRUSTIFY_DA_CONTINUE_ON_ERROR?: string | undefined,
|
|
57
66
|
* batchMetadata?: boolean | undefined,
|
|
58
67
|
* TRUSTIFY_DA_BATCH_METADATA?: string | undefined,
|
|
68
|
+
* TRUSTIFY_DA_UV_PATH?: string | undefined,
|
|
69
|
+
* TRUSTIFY_DA_POETRY_PATH?: string | undefined,
|
|
59
70
|
* [key: string]: string | number | boolean | string[] | undefined,
|
|
60
71
|
* }} Options
|
|
61
72
|
*/
|
|
62
73
|
/**
|
|
63
74
|
* @typedef {{
|
|
64
75
|
* workspaceRoot: string,
|
|
65
|
-
* ecosystem: 'javascript' | 'cargo' | 'unknown',
|
|
76
|
+
* ecosystem: 'javascript' | 'cargo' | 'pyproject' | 'unknown',
|
|
66
77
|
* total: number,
|
|
67
78
|
* successful: number,
|
|
68
79
|
* failed: number,
|
|
@@ -85,29 +96,11 @@ function logOptionsAndEnvironmentsVariables(alongsideText, valueToBePrinted) {
|
|
|
85
96
|
* @private
|
|
86
97
|
*/
|
|
87
98
|
function readAndPrintVersionFromPackageJson() {
|
|
88
|
-
|
|
89
|
-
// new ESM way in nodeJS ( since node version 22 ) to bring module directory.
|
|
90
|
-
dirName = import.meta.dirname;
|
|
91
|
-
// old ESM way in nodeJS ( before node versions 22.00 to bring module directory)
|
|
92
|
-
if (!dirName) {
|
|
93
|
-
dirName = url.fileURLToPath(new URL('.', import.meta.url));
|
|
94
|
-
}
|
|
95
|
-
try {
|
|
96
|
-
if (__dirname) {
|
|
97
|
-
dirName = __dirname;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch (e) {
|
|
101
|
-
console.log("__dirname is not defined, continue with fileUrlPath");
|
|
102
|
-
}
|
|
103
|
-
let packageJson = JSON.parse(fs.readFileSync(path.join(dirName, "..", "package.json")).toString());
|
|
104
|
-
logOptionsAndEnvironmentsVariables("trustify-da-javascript-client analysis started, version: ", packageJson.version);
|
|
99
|
+
logOptionsAndEnvironmentsVariables("trustify-da-javascript-client analysis started, version: ", getPackageVersion());
|
|
105
100
|
}
|
|
106
101
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* 1. Environment Variable
|
|
110
|
-
* 2. (key,value) from opts object
|
|
102
|
+
* Selects the Trustify DA backend URL from opts.TRUSTIFY_DA_BACKEND_URL, then environment
|
|
103
|
+
* variable TRUSTIFY_DA_BACKEND_URL. Options take precedence over environment variables.
|
|
111
104
|
* If TRUSTIFY_DA_BACKEND_URL is not set, the function will throw an error.
|
|
112
105
|
* @param {{TRUSTIFY_DA_DEBUG?: string | undefined; TRUSTIFY_DA_BACKEND_URL?: string | undefined}} [opts={}]
|
|
113
106
|
* @return {string} - The selected Trustify DA backend URL
|
|
@@ -138,7 +131,7 @@ export function selectTrustifyDABackend(opts = {}) {
|
|
|
138
131
|
* @param {string} manifest
|
|
139
132
|
* @param {false} html
|
|
140
133
|
* @param {Options} [opts={}]
|
|
141
|
-
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
134
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
142
135
|
* @throws {Error}
|
|
143
136
|
*/
|
|
144
137
|
/**
|
|
@@ -147,7 +140,7 @@ export function selectTrustifyDABackend(opts = {}) {
|
|
|
147
140
|
* @param {string} manifest - path for the manifest
|
|
148
141
|
* @param {boolean} [html=false] - true will return a html string, false will return AnalysisReport object.
|
|
149
142
|
* @param {Options} [opts={}] - optional various options to pass along the application
|
|
150
|
-
* @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
143
|
+
* @returns {Promise<string|import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
151
144
|
* @throws {Error} if manifest inaccessible, no matching provider, failed to get create content,
|
|
152
145
|
* or backend request failed
|
|
153
146
|
*/
|
|
@@ -161,7 +154,7 @@ async function stackAnalysis(manifest, html = false, opts = {}) {
|
|
|
161
154
|
* Get component analysis report for a manifest content.
|
|
162
155
|
* @param {string} manifest - path to the manifest
|
|
163
156
|
* @param {Options} [opts={}] - optional various options to pass along the application
|
|
164
|
-
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>}
|
|
157
|
+
* @returns {Promise<import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>}
|
|
165
158
|
* @throws {Error} if no matching provider, failed to get create content, or backend request failed
|
|
166
159
|
*/
|
|
167
160
|
async function componentAnalysis(manifest, opts = {}) {
|
|
@@ -169,7 +162,9 @@ async function componentAnalysis(manifest, opts = {}) {
|
|
|
169
162
|
fs.accessSync(manifest, fs.constants.R_OK);
|
|
170
163
|
opts["manifest-type"] = path.basename(manifest);
|
|
171
164
|
let provider = match(manifest, availableProviders, opts); // throws error if no matching provider
|
|
172
|
-
|
|
165
|
+
const result = await analysis.requestComponent(provider, manifest, theUrl, opts); // throws error request sending failed
|
|
166
|
+
result.packageManager = provider.packageManagerName();
|
|
167
|
+
return result;
|
|
173
168
|
}
|
|
174
169
|
/**
|
|
175
170
|
* @overload
|
|
@@ -184,7 +179,7 @@ async function componentAnalysis(manifest, opts = {}) {
|
|
|
184
179
|
* @param {Array<string>} imageRefs
|
|
185
180
|
* @param {false} html
|
|
186
181
|
* @param {Options} [opts={}]
|
|
187
|
-
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
182
|
+
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
188
183
|
* @throws {Error}
|
|
189
184
|
*/
|
|
190
185
|
/**
|
|
@@ -193,7 +188,7 @@ async function componentAnalysis(manifest, opts = {}) {
|
|
|
193
188
|
* @param {Array<string>} imageRefs - OCI image references
|
|
194
189
|
* @param {boolean} [html=false] - true will return a html string, false will return AnalysisReport
|
|
195
190
|
* @param {Options} [opts={}] - optional various options to pass along the application
|
|
196
|
-
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>>}
|
|
191
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
197
192
|
* @throws {Error} if manifest inaccessible, no matching provider, failed to get create content,
|
|
198
193
|
* or backend request failed
|
|
199
194
|
*/
|
|
@@ -202,7 +197,8 @@ async function imageAnalysis(imageRefs, html = false, opts = {}) {
|
|
|
202
197
|
return await analysis.requestImages(imageRefs, theUrl, html, opts);
|
|
203
198
|
}
|
|
204
199
|
/**
|
|
205
|
-
* Max concurrent SBOM generations for batch workspace analysis.
|
|
200
|
+
* Max concurrent SBOM generations for batch workspace analysis. Options override environment;
|
|
201
|
+
* environment overrides the default of 10.
|
|
206
202
|
* @param {Options} opts
|
|
207
203
|
* @returns {number}
|
|
208
204
|
* @private
|
|
@@ -235,6 +231,22 @@ function buildBatchAnalysisMetadata(root, ecosystem, totalSbomAttempts, successf
|
|
|
235
231
|
errors: [...errors],
|
|
236
232
|
};
|
|
237
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Generate a CycloneDX SBOM from a manifest file. No backend HTTP request is made.
|
|
236
|
+
*
|
|
237
|
+
* @param {string} manifestPath - path to the manifest file (e.g. pom.xml, package.json)
|
|
238
|
+
* @param {Options} [opts={}] - optional options (e.g. workspace dir, tool paths)
|
|
239
|
+
* @returns {Promise<object>} parsed CycloneDX SBOM JSON object
|
|
240
|
+
* @throws {Error} if the manifest is unsupported or SBOM generation fails
|
|
241
|
+
*/
|
|
242
|
+
export async function generateSbom(manifestPath, opts = {}) {
|
|
243
|
+
fs.accessSync(manifestPath, fs.constants.R_OK);
|
|
244
|
+
const result = await generateOneSbom(manifestPath, opts);
|
|
245
|
+
if (!result.ok) {
|
|
246
|
+
throw new Error(`Failed to generate SBOM for ${result.manifestPath}: ${result.reason}`);
|
|
247
|
+
}
|
|
248
|
+
return result.sbom;
|
|
249
|
+
}
|
|
238
250
|
/**
|
|
239
251
|
* @typedef {{ ok: true, purl: string, sbom: object } | { ok: false, manifestPath: string, reason: string }} SbomResult
|
|
240
252
|
*/
|
|
@@ -261,17 +273,45 @@ async function generateOneSbom(manifestPath, workspaceOpts) {
|
|
|
261
273
|
*
|
|
262
274
|
* @param {string} root - Resolved workspace root
|
|
263
275
|
* @param {Options} opts
|
|
264
|
-
* @returns {Promise<{ ecosystem: 'javascript' | 'cargo' | 'unknown', manifestPaths: string[] }>}
|
|
276
|
+
* @returns {Promise<{ ecosystem: 'javascript' | 'cargo' | 'maven' | 'gradle' | 'gomodules' | 'pyproject' | 'unknown', manifestPaths: string[] }>}
|
|
265
277
|
* @private
|
|
266
278
|
*/
|
|
267
279
|
async function detectWorkspaceManifests(root, opts) {
|
|
268
280
|
const cargoToml = path.join(root, 'Cargo.toml');
|
|
269
281
|
const cargoLock = path.join(root, 'Cargo.lock');
|
|
270
282
|
const packageJson = path.join(root, 'package.json');
|
|
283
|
+
const pomXml = path.join(root, 'pom.xml');
|
|
271
284
|
if (fs.existsSync(cargoToml) && fs.existsSync(cargoLock)) {
|
|
272
285
|
return { ecosystem: 'cargo', manifestPaths: await discoverWorkspaceCrates(root, opts) };
|
|
273
286
|
}
|
|
274
|
-
|
|
287
|
+
if (fs.existsSync(pomXml)) {
|
|
288
|
+
const manifestPaths = await discoverMavenModules(root, opts);
|
|
289
|
+
if (manifestPaths.length > 0) {
|
|
290
|
+
return { ecosystem: 'maven', manifestPaths };
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const hasGradleSettings = fs.existsSync(path.join(root, 'settings.gradle'))
|
|
294
|
+
|| fs.existsSync(path.join(root, 'settings.gradle.kts'));
|
|
295
|
+
if (hasGradleSettings) {
|
|
296
|
+
const manifestPaths = await discoverGradleSubprojects(root, opts);
|
|
297
|
+
if (manifestPaths.length > 0) {
|
|
298
|
+
return { ecosystem: 'gradle', manifestPaths };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (fs.existsSync(path.join(root, 'go.work'))) {
|
|
302
|
+
const manifestPaths = await discoverGoWorkspaceModules(root, opts);
|
|
303
|
+
if (manifestPaths.length > 0) {
|
|
304
|
+
return { ecosystem: 'gomodules', manifestPaths };
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (fs.existsSync(path.join(root, 'pyproject.toml')) && fs.existsSync(path.join(root, 'uv.lock'))) {
|
|
308
|
+
const manifestPaths = await discoverUvWorkspaceMembers(root, opts);
|
|
309
|
+
if (manifestPaths.length > 0) {
|
|
310
|
+
return { ecosystem: 'pyproject', manifestPaths };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const hasJsLock = fs.existsSync(path.join(root, 'bun.lock'))
|
|
314
|
+
|| fs.existsSync(path.join(root, 'pnpm-lock.yaml'))
|
|
275
315
|
|| fs.existsSync(path.join(root, 'yarn.lock'))
|
|
276
316
|
|| fs.existsSync(path.join(root, 'package-lock.json'));
|
|
277
317
|
if (fs.existsSync(packageJson) && hasJsLock) {
|
|
@@ -380,16 +420,49 @@ function batchError(message, wantMetadata, metadata) {
|
|
|
380
420
|
}
|
|
381
421
|
return err;
|
|
382
422
|
}
|
|
423
|
+
/**
|
|
424
|
+
* @overload
|
|
425
|
+
* @param {string} workspaceRoot
|
|
426
|
+
* @param {true} html
|
|
427
|
+
* @param {Options & { batchMetadata: true }} opts
|
|
428
|
+
* @returns {Promise<{ analysis: string, metadata: BatchAnalysisMetadata }>}
|
|
429
|
+
* @throws {Error}
|
|
430
|
+
*/
|
|
431
|
+
/**
|
|
432
|
+
* @overload
|
|
433
|
+
* @param {string} workspaceRoot
|
|
434
|
+
* @param {true} html
|
|
435
|
+
* @param {Options & { batchMetadata?: false }} [opts={}]
|
|
436
|
+
* @returns {Promise<string>}
|
|
437
|
+
* @throws {Error}
|
|
438
|
+
*/
|
|
439
|
+
/**
|
|
440
|
+
* @overload
|
|
441
|
+
* @param {string} workspaceRoot
|
|
442
|
+
* @param {false} html
|
|
443
|
+
* @param {Options & { batchMetadata: true }} opts
|
|
444
|
+
* @returns {Promise<{ analysis: Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>, metadata: BatchAnalysisMetadata }>}
|
|
445
|
+
* @throws {Error}
|
|
446
|
+
*/
|
|
447
|
+
/**
|
|
448
|
+
* @overload
|
|
449
|
+
* @param {string} workspaceRoot
|
|
450
|
+
* @param {false} html
|
|
451
|
+
* @param {Options & { batchMetadata?: false }} [opts={}]
|
|
452
|
+
* @returns {Promise<Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>>}
|
|
453
|
+
* @throws {Error}
|
|
454
|
+
*/
|
|
383
455
|
/**
|
|
384
456
|
* Get stack analysis for all workspace packages/crates (batch).
|
|
385
457
|
* Detects ecosystem from workspace root: Cargo (Cargo.toml + Cargo.lock) or JS/TS (package.json + lock file).
|
|
386
458
|
* SBOMs are generated in parallel (see `batchConcurrency`) unless `continueOnError: false` (fail-fast sequential).
|
|
387
459
|
* With `opts.batchMetadata` / `TRUSTIFY_DA_BATCH_METADATA`, returns `{ analysis, metadata }` including validation and SBOM errors.
|
|
388
460
|
*
|
|
461
|
+
* @overload
|
|
389
462
|
* @param {string} workspaceRoot - Path to workspace root (containing lock file and workspace config)
|
|
390
463
|
* @param {boolean} [html=false] - true returns HTML, false returns JSON report
|
|
391
464
|
* @param {Options} [opts={}] - `batchConcurrency`, discovery ignores, `continueOnError` (default true), `batchMetadata` (default false)
|
|
392
|
-
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>|{ analysis: string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport>, metadata: BatchAnalysisMetadata }>}
|
|
465
|
+
* @returns {Promise<string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>|{ analysis: string|Object.<string, import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport>, metadata: BatchAnalysisMetadata }>}
|
|
393
466
|
* @throws {Error} if workspace root invalid, no manifests found, no packages pass validation, no SBOMs produced, or backend request failed. When `opts.batchMetadata` is set, `error.batchMetadata` may be set on thrown errors.
|
|
394
467
|
*/
|
|
395
468
|
async function stackAnalysisBatch(workspaceRoot, html = false, opts = {}) {
|
|
@@ -416,7 +489,7 @@ async function stackAnalysisBatch(workspaceRoot, html = false, opts = {}) {
|
|
|
416
489
|
}
|
|
417
490
|
}
|
|
418
491
|
if (manifestPaths.length === 0) {
|
|
419
|
-
throw new Error(`No workspace manifests found at ${root}. Ensure Cargo.toml+Cargo.lock or package.json+lock file
|
|
492
|
+
throw new Error(`No workspace manifests found at ${root}. Ensure a supported workspace root exists (Cargo.toml+Cargo.lock, pom.xml, build.gradle, go.work, pyproject.toml+uv.lock, or package.json+lock file).`);
|
|
420
493
|
}
|
|
421
494
|
const workspaceOpts = { ...opts, TRUSTIFY_DA_WORKSPACE_DIR: root };
|
|
422
495
|
const concurrency = resolveBatchConcurrency(opts);
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
* @param {string} manifestPath - path to manifest
|
|
7
7
|
* @param {string} url - the backend url to send the request to
|
|
8
8
|
* @param {import('../index.js').Options} [opts={}]
|
|
9
|
-
* @param {import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport} [analysisResult] - analysis result that includes licenses array from backend
|
|
9
|
+
* @param {import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport} [analysisResult] - analysis result that includes licenses array from backend
|
|
10
10
|
* @returns {Promise<{ projectLicense: { manifest: Object|null, file: Object|null, mismatch: boolean }, incompatibleDependencies: Array<{ purl: string, licenses: string[], category?: string, reason: string }>, error?: string }>}
|
|
11
11
|
*/
|
|
12
|
-
export function runLicenseCheck(sbomContent: string, manifestPath: string, url: string, opts?: import("../index.js").Options, analysisResult?: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport").AnalysisReport): Promise<{
|
|
12
|
+
export function runLicenseCheck(sbomContent: string, manifestPath: string, url: string, opts?: import("../index.js").Options, analysisResult?: import("@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts").AnalysisReport): Promise<{
|
|
13
13
|
projectLicense: {
|
|
14
|
-
manifest:
|
|
15
|
-
file:
|
|
14
|
+
manifest: Object | null;
|
|
15
|
+
file: Object | null;
|
|
16
16
|
mismatch: boolean;
|
|
17
17
|
};
|
|
18
18
|
incompatibleDependencies: Array<{
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* License resolution and dependency license compatibility for component analysis.
|
|
3
3
|
*/
|
|
4
|
-
import { getProjectLicense, findLicenseFilePath, identifyLicense } from './project_license.js';
|
|
5
|
-
import { licensesFromReport, getLicenseDetails } from './licenses_api.js';
|
|
6
4
|
import { getCompatibility } from './license_utils.js';
|
|
5
|
+
import { licensesFromReport, getLicenseDetails } from './licenses_api.js';
|
|
6
|
+
import { getProjectLicense, findLicenseFilePath, identifyLicense } from './project_license.js';
|
|
7
7
|
export { getProjectLicense, findLicenseFilePath, identifyLicense } from './project_license.js';
|
|
8
8
|
export { licensesFromReport, normalizeLicensesResponse, getLicenseDetails } from './licenses_api.js';
|
|
9
9
|
export { getCompatibility } from './license_utils.js';
|
|
@@ -15,7 +15,7 @@ export { getCompatibility } from './license_utils.js';
|
|
|
15
15
|
* @param {string} manifestPath - path to manifest
|
|
16
16
|
* @param {string} url - the backend url to send the request to
|
|
17
17
|
* @param {import('../index.js').Options} [opts={}]
|
|
18
|
-
* @param {import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport').AnalysisReport} [analysisResult] - analysis result that includes licenses array from backend
|
|
18
|
+
* @param {import('@trustify-da/trustify-da-api-model/model/v5/AnalysisReport.ts').AnalysisReport} [analysisResult] - analysis result that includes licenses array from backend
|
|
19
19
|
* @returns {Promise<{ projectLicense: { manifest: Object|null, file: Object|null, mismatch: boolean }, incompatibleDependencies: Array<{ purl: string, licenses: string[], category?: string, reason: string }>, error?: string }>}
|
|
20
20
|
*/
|
|
21
21
|
export async function runLicenseCheck(sbomContent, manifestPath, url, opts = {}, analysisResult = null) {
|
|
@@ -39,10 +39,12 @@ export async function runLicenseCheck(sbomContent, manifestPath, url, opts = {},
|
|
|
39
39
|
// Fetch detailed license info from backend (avoid duplicate calls if same license)
|
|
40
40
|
const licenseDetailsCache = new Map();
|
|
41
41
|
async function getDetails(spdxId) {
|
|
42
|
-
if (!spdxId || !url)
|
|
42
|
+
if (!spdxId || !url) {
|
|
43
43
|
return null;
|
|
44
|
-
|
|
44
|
+
}
|
|
45
|
+
if (licenseDetailsCache.has(spdxId)) {
|
|
45
46
|
return licenseDetailsCache.get(spdxId);
|
|
47
|
+
}
|
|
46
48
|
try {
|
|
47
49
|
const details = await getLicenseDetails(spdxId, { ...opts, TRUSTIFY_DA_BACKEND_URL: url });
|
|
48
50
|
licenseDetailsCache.set(spdxId, details);
|
|
@@ -81,15 +83,19 @@ export async function runLicenseCheck(sbomContent, manifestPath, url, opts = {},
|
|
|
81
83
|
const incompatibleDependencies = [];
|
|
82
84
|
for (const purl of purls) {
|
|
83
85
|
const entry = licenseByPurl.get(purl);
|
|
84
|
-
if (!entry)
|
|
86
|
+
if (!entry) {
|
|
85
87
|
continue;
|
|
88
|
+
}
|
|
86
89
|
const status = getCompatibility(projectCategory, entry.category);
|
|
87
90
|
if (status === 'incompatible') {
|
|
91
|
+
const reason = entry.category?.toUpperCase() === 'UNKNOWN'
|
|
92
|
+
? 'License not recognized as a standard SPDX identifier. Manual review recommended to verify compatibility.'
|
|
93
|
+
: 'Dependency license(s) are incompatible with the project license.';
|
|
88
94
|
incompatibleDependencies.push({
|
|
89
95
|
purl,
|
|
90
96
|
licenses: entry.licenses,
|
|
91
97
|
category: entry.category,
|
|
92
|
-
reason
|
|
98
|
+
reason
|
|
93
99
|
});
|
|
94
100
|
}
|
|
95
101
|
}
|
|
@@ -114,9 +114,12 @@ export function getCompatibility(projectCategory, dependencyCategory) {
|
|
|
114
114
|
}
|
|
115
115
|
const proj = projectCategory.toUpperCase();
|
|
116
116
|
const dep = dependencyCategory.toUpperCase();
|
|
117
|
-
if (proj === 'UNKNOWN'
|
|
117
|
+
if (proj === 'UNKNOWN') {
|
|
118
118
|
return 'unknown';
|
|
119
119
|
}
|
|
120
|
+
if (dep === 'UNKNOWN') {
|
|
121
|
+
return 'incompatible';
|
|
122
|
+
}
|
|
120
123
|
const restrictiveness = {
|
|
121
124
|
'PERMISSIVE': 1,
|
|
122
125
|
'WEAK_COPYLEFT': 2,
|