@trustify-da/trustify-da-javascript-client 0.3.0-ea.ab5949f → 0.3.0-ea.b0e2843

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 CHANGED
@@ -695,7 +695,7 @@ By default, The API algorithm will use native commands of PIP installer as data
695
695
  It's also possible to use the lightweight Python PIP utility [pipdeptree](https://pypi.org/project/pipdeptree/) as data source instead. In order to activate this, you need to set the environment variable/option `TRUSTIFY_DA_PIP_USE_DEP_TREE` to 'true'.
696
696
 
697
697
  #### Toggle Red Hat Trusted Content recommendations
698
- Both the HTML-based report and JSON response will by default contain recommendations for migrating to Red Hat-based Trusted Content repositories. This feature can be disabled by setting `TRUSTIFY_DA_RECOMMENDATIONS_ENABLED` to 'false' via environment variables or options.
698
+ Both the HTML-based report and JSON response will by default contain recommendations for migrating to Red Hat-based Trusted Content repositories. This feature can be disabled by setting `TRUSTIFY_DA_RECOMMEND` to 'false' via environment variables or options.
699
699
 
700
700
  #### Additional CLI arguments
701
701
  For some ecosystems we support passing additional CLI arguments to the underlying tools. The following table outlines the supported ecosystems and the environment variable/option that configures this. Note that the arguments are expected to be in the format of a JSON array.
package/dist/package.json CHANGED
@@ -40,11 +40,11 @@
40
40
  "test": "c8 npm run tests",
41
41
  "tests": "mocha --config .mocharc.json",
42
42
  "tests:rep": "mocha --reporter-option maxDiffSize=0 --reporter json > unit-tests-result.json",
43
- "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",
43
+ "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",
44
44
  "precompile": "rm -rf dist",
45
45
  "compile": "tsc -p tsconfig.json",
46
46
  "compile:dev": "tsc -p tsconfig.dev.json",
47
- "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"
47
+ "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"
48
48
  },
49
49
  "dependencies": {
50
50
  "@babel/core": "^7.23.2",
@@ -61,6 +61,7 @@
61
61
  "p-limit": "^7.3.0",
62
62
  "packageurl-js": "~1.0.2",
63
63
  "smol-toml": "^1.6.0",
64
+ "tree-sitter-containerfile": "^0.8.1",
64
65
  "tree-sitter-gomod": "github:strum355/tree-sitter-go-mod#56326f2ad478892ace58ff247a97d492a3cbcdda",
65
66
  "tree-sitter-requirements": "github:Strum355/tree-sitter-requirements#d0261ee76b84253997fe70d7d397e78c006c3801",
66
67
  "web-tree-sitter": "^0.26.7",
@@ -68,18 +69,18 @@
68
69
  },
69
70
  "devDependencies": {
70
71
  "@babel/core": "^7.23.2",
71
- "@trustify-da/trustify-da-api-model": "^2.0.9",
72
+ "@eslint/js": "^10.0.0",
73
+ "@trustify-da/trustify-da-api-model": "^2.0.12",
72
74
  "@types/node": "^25.9.1",
73
75
  "@types/which": "^3.0.4",
74
76
  "babel-plugin-rewire": "^1.2.0",
75
77
  "c8": "^11.0.0",
76
78
  "chai": "^6.2.2",
77
- "@eslint/js": "^10.0.0",
78
79
  "eslint": "^10.4.1",
79
80
  "eslint-import-resolver-typescript": "^4.4.4",
80
81
  "eslint-plugin-import-x": "^4.16.2",
81
- "globals": "^17.6.0",
82
82
  "esmock": "^2.6.2",
83
+ "globals": "^17.6.0",
83
84
  "mocha": "^11.7.6",
84
85
  "msw": "^2.12.7",
85
86
  "sinon": "^22.0.0",
@@ -117,6 +118,9 @@
117
118
  "text"
118
119
  ]
119
120
  },
121
+ "overrides": {
122
+ "tree-sitter": "0.22.4"
123
+ },
120
124
  "resolutions": {
121
125
  "@hapi/joi": "17.1.1"
122
126
  }
@@ -20,6 +20,9 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
20
20
  opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
21
21
  opts["manifest-type"] = path.parse(manifest).base;
22
22
  let provided = await provider.provideStack(manifest, opts); // throws error if content providing failed
23
+ if (provided.batch) {
24
+ return requestStackBatch(JSON.parse(provided.content), url, html, opts);
25
+ }
23
26
  opts["source-manifest"] = "";
24
27
  opts[TRUSTIFY_DA_OPERATION_TYPE_HEADER.toUpperCase().replaceAll("-", "_")] = "stack-analysis";
25
28
  let startTime = new Date();
@@ -38,7 +41,7 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
38
41
  body: provided.content
39
42
  }, opts);
40
43
  const finalUrl = new URL(`${url}/api/v5/analysis`);
41
- if (opts['TRUSTIFY_DA_RECOMMENDATIONS_ENABLED'] === 'false') {
44
+ if (getCustom('TRUSTIFY_DA_RECOMMEND', 'true', opts) === 'false') {
42
45
  finalUrl.searchParams.append('recommend', 'false');
43
46
  }
44
47
  let resp = await fetch(finalUrl, fetchOptions);
@@ -79,6 +82,9 @@ async function requestStack(provider, manifest, url, html = false, opts = {}) {
79
82
  async function requestComponent(provider, manifest, url, opts = {}) {
80
83
  opts["source-manifest"] = Buffer.from(fs.readFileSync(manifest).toString()).toString('base64');
81
84
  let provided = await provider.provideComponent(manifest, opts); // throws error if content providing failed
85
+ if (provided.batch) {
86
+ return requestStackBatch(JSON.parse(provided.content), url, false, opts);
87
+ }
82
88
  opts["source-manifest"] = "";
83
89
  opts[TRUSTIFY_DA_OPERATION_TYPE_HEADER.toUpperCase().replaceAll("-", "_")] = "component-analysis";
84
90
  if (process.env["TRUSTIFY_DA_DEBUG"] === "true") {
@@ -95,7 +101,7 @@ async function requestComponent(provider, manifest, url, opts = {}) {
95
101
  body: provided.content
96
102
  }, opts);
97
103
  const finalUrl = new URL(`${url}/api/v5/analysis`);
98
- if (opts['TRUSTIFY_DA_RECOMMENDATIONS_ENABLED'] === 'false') {
104
+ if (getCustom('TRUSTIFY_DA_RECOMMEND', 'true', opts) === 'false') {
99
105
  finalUrl.searchParams.append('recommend', 'false');
100
106
  }
101
107
  let resp = await fetch(finalUrl, fetchOptions);
@@ -136,7 +142,7 @@ async function requestComponent(provider, manifest, url, opts = {}) {
136
142
  */
137
143
  async function requestStackBatch(sbomByPurl, url, html = false, opts = {}) {
138
144
  const finalUrl = new URL(`${url}/api/v5/batch-analysis`);
139
- if (opts['TRUSTIFY_DA_RECOMMENDATIONS_ENABLED'] === 'false') {
145
+ if (getCustom('TRUSTIFY_DA_RECOMMEND', 'true', opts) === 'false') {
140
146
  finalUrl.searchParams.append('recommend', 'false');
141
147
  }
142
148
  const fetchOptions = addProxyAgent({
@@ -186,7 +192,7 @@ async function requestImages(imageRefs, url, html = false, opts = {}) {
186
192
  imageSboms[parsedImageRef.getPackageURL().toString()] = generateImageSBOM(parsedImageRef, opts);
187
193
  }
188
194
  const finalUrl = new URL(`${url}/api/v5/batch-analysis`);
189
- if (opts['TRUSTIFY_DA_RECOMMENDATIONS_ENABLED'] === 'false') {
195
+ if (getCustom('TRUSTIFY_DA_RECOMMEND', 'true', opts) === 'false') {
190
196
  finalUrl.searchParams.append('recommend', 'false');
191
197
  }
192
198
  const fetchOptions = addProxyAgent({
@@ -53,7 +53,7 @@ export type Options = {
53
53
  TRUSTIFY_DA_PYTHON_PATH?: string | undefined;
54
54
  TRUSTIFY_DA_PYTHON_VIRTUAL_ENV?: string | undefined;
55
55
  TRUSTIFY_DA_PYTHON3_PATH?: string | undefined;
56
- TRUSTIFY_DA_RECOMMENDATIONS_ENABLED?: string | undefined;
56
+ TRUSTIFY_DA_RECOMMEND?: string | undefined;
57
57
  TRUSTIFY_DA_SKOPEO_CONFIG_PATH?: string | undefined;
58
58
  TRUSTIFY_DA_SKOPEO_PATH?: string | undefined;
59
59
  TRUSTIFY_DA_SYFT_CONFIG_PATH?: string | undefined;
package/dist/src/index.js CHANGED
@@ -39,7 +39,7 @@ export { discoverMavenModules, discoverGradleSubprojects, discoverGoWorkspaceMod
39
39
  * TRUSTIFY_DA_PYTHON_PATH?: string | undefined,
40
40
  * TRUSTIFY_DA_PYTHON_VIRTUAL_ENV?: string | undefined,
41
41
  * TRUSTIFY_DA_PYTHON3_PATH?: string | undefined,
42
- * TRUSTIFY_DA_RECOMMENDATIONS_ENABLED?: string | undefined,
42
+ * TRUSTIFY_DA_RECOMMEND?: string | undefined,
43
43
  * TRUSTIFY_DA_SKOPEO_CONFIG_PATH?: string | undefined,
44
44
  * TRUSTIFY_DA_SKOPEO_PATH?: string | undefined,
45
45
  * TRUSTIFY_DA_SYFT_CONFIG_PATH?: string | undefined,
@@ -242,8 +242,22 @@ export class ImageRef {
242
242
  getPackageURL() {
243
243
  /** @type {Object.<string, string>} */
244
244
  const qualifiers = {};
245
- const repositoryUrl = this.image.getNameWithoutTag();
245
+ let repositoryUrl = this.image.getNameWithoutTag();
246
246
  const simpleName = this.image.getSimpleName();
247
+ // Normalize Docker Hub image references so all forms produce the same PURL:
248
+ // node → docker.io/node
249
+ // docker.io/library/node → docker.io/node
250
+ if (repositoryUrl != null) {
251
+ const lower = repositoryUrl.toLowerCase();
252
+ if (lower === simpleName.toLowerCase()) {
253
+ // Bare name (e.g. "node") — default to docker.io
254
+ repositoryUrl = `docker.io/${simpleName}`;
255
+ }
256
+ else if (lower.startsWith('docker.io/library/')) {
257
+ // Official image with library/ prefix — strip it
258
+ repositoryUrl = `docker.io/${lower.substring('docker.io/library/'.length)}`;
259
+ }
260
+ }
247
261
  if (repositoryUrl != null && repositoryUrl.toLowerCase() !== simpleName.toLowerCase()) {
248
262
  qualifiers[ImageRef.REPOSITORY_QUALIFIER] = repositoryUrl.toLowerCase();
249
263
  }
@@ -7,6 +7,7 @@ import Javascript_bun from './providers/javascript_bun.js';
7
7
  import Javascript_npm from './providers/javascript_npm.js';
8
8
  import Javascript_pnpm from './providers/javascript_pnpm.js';
9
9
  import Javascript_yarn from './providers/javascript_yarn.js';
10
+ import dockerfileProvider from './providers/oci_dockerfile.js';
10
11
  import pythonPipProvider from './providers/python_pip.js';
11
12
  import Python_pip_pyproject from './providers/python_pip_pyproject.js';
12
13
  import Python_poetry from './providers/python_poetry.js';
@@ -31,7 +32,8 @@ export const availableProviders = [
31
32
  new Python_poetry(),
32
33
  new Python_uv(),
33
34
  new Python_pip_pyproject(),
34
- rustCargoProvider
35
+ rustCargoProvider,
36
+ dockerfileProvider
35
37
  ];
36
38
  /**
37
39
  * Match a provider by manifest type only (no lock file check). Used for license reading.
@@ -0,0 +1,5 @@
1
+ export function getParser(): Promise<Parser>;
2
+ export function getFromQuery(): Promise<Query>;
3
+ export function getArgQuery(): Promise<Query>;
4
+ import { Parser } from 'web-tree-sitter';
5
+ import { Query } from 'web-tree-sitter';
@@ -0,0 +1,20 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { Language, Parser, Query } from 'web-tree-sitter';
3
+ const wasmUrl = new URL('./tree-sitter-containerfile.wasm', import.meta.url);
4
+ async function init() {
5
+ await Parser.init();
6
+ const wasmBytes = new Uint8Array(await readFile(wasmUrl));
7
+ return await Language.load(wasmBytes);
8
+ }
9
+ export async function getParser() {
10
+ const language = await init();
11
+ return new Parser().setLanguage(language);
12
+ }
13
+ export async function getFromQuery() {
14
+ const language = await init();
15
+ return new Query(language, '(from_instruction (image_spec) @image)');
16
+ }
17
+ export async function getArgQuery() {
18
+ const language = await init();
19
+ return new Query(language, '(arg_instruction (arg_pair name: (_) @name default: (_) @default))');
20
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Parse all FROM instructions from a Dockerfile using tree-sitter to extract base image references.
3
+ * In multi-stage builds, every FROM line is returned so each image can be analyzed independently.
4
+ * ARG substitutions are resolved using declared default values. FROM lines with unresolvable
5
+ * variables (ARGs without defaults) are silently skipped.
6
+ * @param {string} manifestContent the content of the Dockerfile
7
+ * @returns {Promise<string[]>} array of image references from all resolvable FROM instructions
8
+ * @throws {Error} when no FROM instruction is found or when no FROM lines can be resolved
9
+ */
10
+ export function parseAllFromImages(manifestContent: string): Promise<string[]>;
11
+ declare namespace _default {
12
+ export { isSupported };
13
+ export { validateLockFile };
14
+ export { provideComponent };
15
+ export { provideStack };
16
+ export { readLicenseFromManifest };
17
+ export function packageManagerName(): string;
18
+ }
19
+ export default _default;
20
+ export type Provided = any;
21
+ /**
22
+ * Check if the given manifest name is a Dockerfile or Containerfile.
23
+ * Supports dot-suffixed variants such as Dockerfile.dev or Containerfile.prod.
24
+ * @param {string} manifestName the manifest file name to check
25
+ * @returns {boolean} true if the manifest is a Dockerfile or Containerfile
26
+ */
27
+ declare function isSupported(manifestName: string): boolean;
28
+ /**
29
+ * Dockerfiles have no lock file, so validation always passes.
30
+ * @returns {boolean} always true
31
+ */
32
+ declare function validateLockFile(): boolean;
33
+ /**
34
+ * Provide content and content type for Dockerfile component analysis.
35
+ * @param {string} manifest path to the Dockerfile
36
+ * @param {{}} [opts={}] optional various options to pass along the application
37
+ * @returns {Promise<Provided>}
38
+ */
39
+ declare function provideComponent(manifest: string, opts?: {}): Promise<Provided>;
40
+ /**
41
+ * Provide content and content type for Dockerfile stack analysis.
42
+ * @param {string} manifest path to the Dockerfile
43
+ * @param {{}} [opts={}] optional various options to pass along the application
44
+ * @returns {Promise<Provided>}
45
+ */
46
+ declare function provideStack(manifest: string, opts?: {}): Promise<Provided>;
47
+ /**
48
+ * Dockerfiles contain no license information.
49
+ * @returns {null} always null
50
+ */
51
+ declare function readLicenseFromManifest(): null;
@@ -0,0 +1,177 @@
1
+ import fs from 'node:fs';
2
+ import { generateImageSBOM, parseImageRef } from '../oci_image/utils.js';
3
+ import { getArgQuery, getFromQuery, getParser } from './containerfile_parser.js';
4
+ export default { isSupported, validateLockFile, provideComponent, provideStack, readLicenseFromManifest, packageManagerName() { return 'oci'; } };
5
+ /** @typedef {import('../provider').Provider} */
6
+ /** @typedef {import('../provider').Provided} Provided */
7
+ /**
8
+ * @type {string} ecosystem identifier for OCI image packages
9
+ * @private
10
+ */
11
+ const ecosystem = 'oci';
12
+ /**
13
+ * Check if the given manifest name is a Dockerfile or Containerfile.
14
+ * Supports dot-suffixed variants such as Dockerfile.dev or Containerfile.prod.
15
+ * @param {string} manifestName the manifest file name to check
16
+ * @returns {boolean} true if the manifest is a Dockerfile or Containerfile
17
+ */
18
+ function isSupported(manifestName) {
19
+ return /^(Dockerfile|Containerfile)(\..+)?$/.test(manifestName);
20
+ }
21
+ /**
22
+ * Dockerfiles have no lock file, so validation always passes.
23
+ * @returns {boolean} always true
24
+ */
25
+ function validateLockFile() { return true; }
26
+ /**
27
+ * Check whether a syntax node contains any expansion (variable substitution) children.
28
+ * @param {import('web-tree-sitter').SyntaxNode} node
29
+ * @returns {boolean}
30
+ * @private
31
+ */
32
+ function containsExpansion(node) {
33
+ if (node.type === 'expansion') {
34
+ return true;
35
+ }
36
+ for (let i = 0; i < node.childCount; i++) {
37
+ if (containsExpansion(node.child(i))) {
38
+ return true;
39
+ }
40
+ }
41
+ return false;
42
+ }
43
+ /**
44
+ * Strip surrounding single or double quotes from a string.
45
+ * @param {string} text
46
+ * @returns {string}
47
+ * @private
48
+ */
49
+ function stripQuotes(text) {
50
+ if ((text.startsWith('"') && text.endsWith('"')) || (text.startsWith("'") && text.endsWith("'"))) {
51
+ return text.slice(1, -1);
52
+ }
53
+ return text;
54
+ }
55
+ /**
56
+ * Collect ARG key-value pairs from the Dockerfile AST.
57
+ * Only ARGs with a default value are collected (ARGs without defaults cannot be resolved statically).
58
+ * @param {import('web-tree-sitter').Tree} tree the parsed Dockerfile tree
59
+ * @param {import('web-tree-sitter').Query} argQuery the tree-sitter query for arg_instruction nodes
60
+ * @returns {Map<string, string>} map of ARG names to their default values
61
+ * @private
62
+ */
63
+ function collectArgs(tree, argQuery) {
64
+ const args = new Map();
65
+ for (const match of argQuery.matches(tree.rootNode)) {
66
+ const name = match.captures.find(c => c.name === 'name')?.node.text;
67
+ const defaultValue = match.captures.find(c => c.name === 'default')?.node.text;
68
+ if (name && defaultValue) {
69
+ args.set(name, stripQuotes(defaultValue));
70
+ }
71
+ }
72
+ return args;
73
+ }
74
+ /**
75
+ * Resolve ARG substitutions in an image spec text using the collected ARG map.
76
+ * Replaces ${VAR} and $VAR patterns with their ARG default values.
77
+ * @param {string} text the image spec text potentially containing variable references
78
+ * @param {Map<string, string>} args map of ARG names to their default values
79
+ * @returns {string|null} the resolved text, or null if any variable could not be resolved
80
+ * @private
81
+ */
82
+ function resolveArgs(text, args) {
83
+ let resolved = text;
84
+ let hasUnresolved = false;
85
+ resolved = resolved.replace(/\$\{([^}]+)\}|\$([A-Za-z_]\w*)/g, (_match, braced, plain) => {
86
+ const key = braced || plain;
87
+ if (args.has(key)) {
88
+ return args.get(key);
89
+ }
90
+ hasUnresolved = true;
91
+ return _match;
92
+ });
93
+ return hasUnresolved ? null : resolved;
94
+ }
95
+ /**
96
+ * Parse all FROM instructions from a Dockerfile using tree-sitter to extract base image references.
97
+ * In multi-stage builds, every FROM line is returned so each image can be analyzed independently.
98
+ * ARG substitutions are resolved using declared default values. FROM lines with unresolvable
99
+ * variables (ARGs without defaults) are silently skipped.
100
+ * @param {string} manifestContent the content of the Dockerfile
101
+ * @returns {Promise<string[]>} array of image references from all resolvable FROM instructions
102
+ * @throws {Error} when no FROM instruction is found or when no FROM lines can be resolved
103
+ */
104
+ export async function parseAllFromImages(manifestContent) {
105
+ const [parser, fromQuery, argQuery] = await Promise.all([getParser(), getFromQuery(), getArgQuery()]);
106
+ const tree = parser.parse(manifestContent);
107
+ const matches = fromQuery.matches(tree.rootNode);
108
+ if (matches.length === 0) {
109
+ throw new Error('No FROM line found in Dockerfile');
110
+ }
111
+ const args = collectArgs(tree, argQuery);
112
+ const images = [];
113
+ for (const match of matches) {
114
+ const imageSpec = match.captures.find(c => c.name === 'image').node;
115
+ if (containsExpansion(imageSpec)) {
116
+ const resolved = resolveArgs(imageSpec.text, args);
117
+ if (resolved != null) {
118
+ images.push(resolved);
119
+ }
120
+ continue;
121
+ }
122
+ images.push(imageSpec.text);
123
+ }
124
+ if (images.length === 0) {
125
+ throw new Error('Dockerfile uses ARG substitution in all FROM lines — cannot resolve variable references');
126
+ }
127
+ return images;
128
+ }
129
+ /**
130
+ * Generate image SBOMs for all FROM instructions in a Dockerfile manifest using syft.
131
+ * Returns a batch result with a purl-to-SBOM map suitable for the batch-analysis endpoint.
132
+ * @param {string} manifest path to the Dockerfile
133
+ * @param {{}} [opts={}] optional various options to pass along the application
134
+ * @returns {Promise<{ecosystem: string, content: string, contentType: string, batch: boolean}>}
135
+ * @private
136
+ */
137
+ async function getImageSBOM(manifest, opts = {}) {
138
+ const manifestContent = fs.readFileSync(manifest, 'utf-8');
139
+ const images = await parseAllFromImages(manifestContent);
140
+ const sbomByPurl = {};
141
+ for (const image of images) {
142
+ const imageRef = parseImageRef(image, opts);
143
+ const purl = imageRef.getPackageURL().toString();
144
+ if (purl in sbomByPurl)
145
+ continue;
146
+ sbomByPurl[purl] = generateImageSBOM(imageRef, opts);
147
+ }
148
+ return {
149
+ ecosystem,
150
+ content: JSON.stringify(sbomByPurl),
151
+ contentType: 'application/vnd.cyclonedx+json',
152
+ batch: true
153
+ };
154
+ }
155
+ /**
156
+ * Provide content and content type for Dockerfile component analysis.
157
+ * @param {string} manifest path to the Dockerfile
158
+ * @param {{}} [opts={}] optional various options to pass along the application
159
+ * @returns {Promise<Provided>}
160
+ */
161
+ async function provideComponent(manifest, opts = {}) {
162
+ return getImageSBOM(manifest, opts);
163
+ }
164
+ /**
165
+ * Provide content and content type for Dockerfile stack analysis.
166
+ * @param {string} manifest path to the Dockerfile
167
+ * @param {{}} [opts={}] optional various options to pass along the application
168
+ * @returns {Promise<Provided>}
169
+ */
170
+ async function provideStack(manifest, opts = {}) {
171
+ return getImageSBOM(manifest, opts);
172
+ }
173
+ /**
174
+ * Dockerfiles contain no license information.
175
+ * @returns {null} always null
176
+ */
177
+ function readLicenseFromManifest() { return null; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustify-da/trustify-da-javascript-client",
3
- "version": "0.3.0-ea.ab5949f",
3
+ "version": "0.3.0-ea.b0e2843",
4
4
  "description": "Code-Ready Dependency Analytics JavaScript API.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/guacsec/trustify-da-javascript-client#README.md",
@@ -40,11 +40,11 @@
40
40
  "test": "c8 npm run tests",
41
41
  "tests": "mocha --config .mocharc.json",
42
42
  "tests:rep": "mocha --reporter-option maxDiffSize=0 --reporter json > unit-tests-result.json",
43
- "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",
43
+ "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",
44
44
  "precompile": "rm -rf dist",
45
45
  "compile": "tsc -p tsconfig.json",
46
46
  "compile:dev": "tsc -p tsconfig.dev.json",
47
- "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"
47
+ "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"
48
48
  },
49
49
  "dependencies": {
50
50
  "@babel/core": "^7.23.2",
@@ -61,6 +61,7 @@
61
61
  "p-limit": "^7.3.0",
62
62
  "packageurl-js": "~1.0.2",
63
63
  "smol-toml": "^1.6.0",
64
+ "tree-sitter-containerfile": "^0.8.1",
64
65
  "tree-sitter-gomod": "github:strum355/tree-sitter-go-mod#56326f2ad478892ace58ff247a97d492a3cbcdda",
65
66
  "tree-sitter-requirements": "github:Strum355/tree-sitter-requirements#d0261ee76b84253997fe70d7d397e78c006c3801",
66
67
  "web-tree-sitter": "^0.26.7",
@@ -68,18 +69,18 @@
68
69
  },
69
70
  "devDependencies": {
70
71
  "@babel/core": "^7.23.2",
71
- "@trustify-da/trustify-da-api-model": "^2.0.9",
72
+ "@eslint/js": "^10.0.0",
73
+ "@trustify-da/trustify-da-api-model": "^2.0.12",
72
74
  "@types/node": "^25.9.1",
73
75
  "@types/which": "^3.0.4",
74
76
  "babel-plugin-rewire": "^1.2.0",
75
77
  "c8": "^11.0.0",
76
78
  "chai": "^6.2.2",
77
- "@eslint/js": "^10.0.0",
78
79
  "eslint": "^10.4.1",
79
80
  "eslint-import-resolver-typescript": "^4.4.4",
80
81
  "eslint-plugin-import-x": "^4.16.2",
81
- "globals": "^17.6.0",
82
82
  "esmock": "^2.6.2",
83
+ "globals": "^17.6.0",
83
84
  "mocha": "^11.7.6",
84
85
  "msw": "^2.12.7",
85
86
  "sinon": "^22.0.0",
@@ -117,6 +118,9 @@
117
118
  "text"
118
119
  ]
119
120
  },
121
+ "overrides": {
122
+ "tree-sitter": "0.22.4"
123
+ },
120
124
  "resolutions": {
121
125
  "@hapi/joi": "17.1.1"
122
126
  }