@trustify-da/trustify-da-javascript-client 0.3.0-ea.d71f957 → 0.3.0-ea.d8ec262

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.
Files changed (50) hide show
  1. package/README.md +56 -2
  2. package/dist/package.json +2 -2
  3. package/dist/src/analysis.js +3 -2
  4. package/dist/src/cli.js +51 -2
  5. package/dist/src/cyclone_dx_sbom.d.ts +7 -1
  6. package/dist/src/cyclone_dx_sbom.js +29 -8
  7. package/dist/src/index.d.ts +74 -3
  8. package/dist/src/index.js +92 -7
  9. package/dist/src/oci_image/utils.js +11 -2
  10. package/dist/src/provider.d.ts +3 -2
  11. package/dist/src/provider.js +9 -1
  12. package/dist/src/providers/base_java.d.ts +12 -10
  13. package/dist/src/providers/base_java.js +18 -44
  14. package/dist/src/providers/base_javascript.d.ts +11 -0
  15. package/dist/src/providers/base_javascript.js +10 -3
  16. package/dist/src/providers/base_pyproject.d.ts +158 -0
  17. package/dist/src/providers/base_pyproject.js +322 -0
  18. package/dist/src/providers/golang_gomodules.d.ts +10 -0
  19. package/dist/src/providers/golang_gomodules.js +65 -8
  20. package/dist/src/providers/java_gradle.d.ts +19 -0
  21. package/dist/src/providers/java_gradle.js +116 -2
  22. package/dist/src/providers/java_maven.d.ts +8 -0
  23. package/dist/src/providers/java_maven.js +165 -1
  24. package/dist/src/providers/javascript_bun.d.ts +10 -0
  25. package/dist/src/providers/javascript_bun.js +100 -0
  26. package/dist/src/providers/javascript_npm.d.ts +1 -0
  27. package/dist/src/providers/javascript_npm.js +21 -0
  28. package/dist/src/providers/javascript_pnpm.js +6 -2
  29. package/dist/src/providers/marker_evaluator.d.ts +14 -0
  30. package/dist/src/providers/marker_evaluator.js +191 -0
  31. package/dist/src/providers/processors/yarn_berry_processor.js +6 -2
  32. package/dist/src/providers/python_controller.d.ts +5 -1
  33. package/dist/src/providers/python_controller.js +65 -7
  34. package/dist/src/providers/python_pip.d.ts +5 -0
  35. package/dist/src/providers/python_pip.js +5 -5
  36. package/dist/src/providers/python_pip_pyproject.d.ts +61 -0
  37. package/dist/src/providers/python_pip_pyproject.js +146 -0
  38. package/dist/src/providers/python_poetry.d.ts +97 -0
  39. package/dist/src/providers/python_poetry.js +271 -0
  40. package/dist/src/providers/python_uv.d.ts +55 -0
  41. package/dist/src/providers/python_uv.js +227 -0
  42. package/dist/src/providers/rust_cargo.d.ts +5 -1
  43. package/dist/src/providers/rust_cargo.js +31 -4
  44. package/dist/src/sbom.d.ts +7 -1
  45. package/dist/src/sbom.js +4 -2
  46. package/dist/src/tools.d.ts +26 -0
  47. package/dist/src/tools.js +58 -0
  48. package/dist/src/workspace.d.ts +9 -0
  49. package/dist/src/workspace.js +1 -1
  50. package/package.json +3 -3
@@ -3,13 +3,17 @@ import golangGomodulesProvider from './providers/golang_gomodules.js';
3
3
  import Java_gradle_groovy from "./providers/java_gradle_groovy.js";
4
4
  import Java_gradle_kotlin from "./providers/java_gradle_kotlin.js";
5
5
  import Java_maven from "./providers/java_maven.js";
6
+ import Javascript_bun from './providers/javascript_bun.js';
6
7
  import Javascript_npm from './providers/javascript_npm.js';
7
8
  import Javascript_pnpm from './providers/javascript_pnpm.js';
8
9
  import Javascript_yarn from './providers/javascript_yarn.js';
9
10
  import pythonPipProvider from './providers/python_pip.js';
11
+ import Python_pip_pyproject from './providers/python_pip_pyproject.js';
12
+ import Python_poetry from './providers/python_poetry.js';
13
+ import Python_uv from './providers/python_uv.js';
10
14
  import rustCargoProvider from './providers/rust_cargo.js';
11
15
  /** @typedef {{ecosystem: string, contentType: string, content: string}} Provided */
12
- /** @typedef {{isSupported: function(string): boolean, validateLockFile: function(string, Object): void, provideComponent: function(string, {}): Provided | Promise<Provided>, provideStack: function(string, {}): Provided | Promise<Provided>, readLicenseFromManifest: function(string): string | null}} Provider */
16
+ /** @typedef {{isSupported: function(string): boolean, validateLockFile: function(string, Object): void, provideComponent: function(string, {}): Provided | Promise<Provided>, provideStack: function(string, {}): Provided | Promise<Provided>, readLicenseFromManifest: function(string, Object=): string | null, packageManagerName: function(): string}} Provider */
13
17
  /**
14
18
  * MUST include all providers here.
15
19
  * @type {[Provider]}
@@ -18,11 +22,15 @@ export const availableProviders = [
18
22
  new Java_maven(),
19
23
  new Java_gradle_groovy(),
20
24
  new Java_gradle_kotlin(),
25
+ new Javascript_bun(),
21
26
  new Javascript_pnpm(),
22
27
  new Javascript_yarn(),
23
28
  new Javascript_npm(),
24
29
  golangGomodulesProvider,
25
30
  pythonPipProvider,
31
+ new Python_poetry(),
32
+ new Python_uv(),
33
+ new Python_pip_pyproject(),
26
34
  rustCargoProvider
27
35
  ];
28
36
  /**
@@ -20,6 +20,11 @@ export default class Base_Java {
20
20
  CONFLICT_REGEX: RegExp;
21
21
  globalBinary: string;
22
22
  localWrapper: string;
23
+ /**
24
+ * Returns the package manager name (e.g. mvn, gradle)
25
+ * @returns {string}
26
+ */
27
+ packageManagerName(): string;
23
28
  /**
24
29
  * Recursively populates the SBOM instance with the parsed graph
25
30
  * @param {string} src - Source dependency to start the calculations from
@@ -28,6 +33,13 @@ export default class Base_Java {
28
33
  * @param {Sbom} sbom - The SBOM where the dependencies are being added
29
34
  */
30
35
  parseDependencyTree(src: string, srcDepth: number, lines: any[], sbom: Sbom): void;
36
+ /**
37
+ * Calculates how deep in the graph is the given line
38
+ * @param {string} line - line to calculate the depth from
39
+ * @returns {number} The calculated depth
40
+ * @protected
41
+ */
42
+ protected _getDepth(line: string): number;
31
43
  /**
32
44
  * Create a PackageURL from any line in a Text Graph dependency tree for a manifest path.
33
45
  * @param {string} line - line to parse from a dependencies.txt file
@@ -57,16 +69,6 @@ export default class Base_Java {
57
69
  * @returns string
58
70
  */
59
71
  selectToolBinary(manifestPath: string, opts: {}): string | null;
60
- /**
61
- *
62
- * @param {string} startingManifest - the path of the manifest from which to start searching for the wrapper
63
- * @param {string} repoRoot - the root of the repository at which point to stop searching for mvnw, derived via git if unset and then fallsback
64
- * to the root of the drive the manifest is on (assumes absolute path is given)
65
- * @returns {string|undefined}
66
- */
67
- traverseForWrapper(startingManifest: string, repoRoot?: string): string | undefined;
68
- normalizePath(thePath: any): string;
69
- #private;
70
72
  }
71
73
  export type Provided = import("../provider").Provided;
72
74
  export type Package = {
@@ -1,7 +1,6 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
3
2
  import { PackageURL } from 'packageurl-js';
4
- import { getCustomPath, getGitRootDir, getWrapperPreference, invokeCommand } from "../tools.js";
3
+ import { getCustomPath, getWrapperPreference, invokeCommand, traverseForWrapper } from "../tools.js";
5
4
  /** @typedef {import('../provider').Provider} */
6
5
  /** @typedef {import('../provider').Provided} Provided */
7
6
  /** @typedef {{name: string, version: string}} Package */
@@ -26,6 +25,13 @@ export default class Base_Java {
26
25
  this.globalBinary = globalBinary;
27
26
  this.localWrapper = localWrapper;
28
27
  }
28
+ /**
29
+ * Returns the package manager name (e.g. mvn, gradle)
30
+ * @returns {string}
31
+ */
32
+ packageManagerName() {
33
+ return this.globalBinary;
34
+ }
29
35
  /**
30
36
  * Recursively populates the SBOM instance with the parsed graph
31
37
  * @param {string} src - Source dependency to start the calculations from
@@ -42,7 +48,7 @@ export default class Base_Java {
42
48
  }
43
49
  let index = 0;
44
50
  let target = lines[index];
45
- let targetDepth = this.#getDepth(target);
51
+ let targetDepth = this._getDepth(target);
46
52
  while (targetDepth > srcDepth && index < lines.length) {
47
53
  if (targetDepth === srcDepth + 1) {
48
54
  let from = this.parseDep(src);
@@ -55,22 +61,25 @@ export default class Base_Java {
55
61
  }
56
62
  }
57
63
  else {
58
- this.parseDependencyTree(lines[index - 1], this.#getDepth(lines[index - 1]), lines.slice(index), sbom);
64
+ this.parseDependencyTree(lines[index - 1], this._getDepth(lines[index - 1]), lines.slice(index), sbom);
59
65
  }
60
66
  target = lines[++index];
61
- targetDepth = this.#getDepth(target);
67
+ targetDepth = this._getDepth(target);
62
68
  }
63
69
  }
64
70
  /**
65
71
  * Calculates how deep in the graph is the given line
66
72
  * @param {string} line - line to calculate the depth from
67
73
  * @returns {number} The calculated depth
68
- * @private
74
+ * @protected
69
75
  */
70
- #getDepth(line) {
71
- if (line === undefined) {
76
+ _getDepth(line) {
77
+ if (!line || line.trim() === '') {
72
78
  return -1;
73
79
  }
80
+ if (line.match(/^\w/)) {
81
+ return 0;
82
+ }
74
83
  return ((line.indexOf('-') - 1) / 3) + 1;
75
84
  }
76
85
  /**
@@ -131,7 +140,7 @@ export default class Base_Java {
131
140
  const toolPath = getCustomPath(this.globalBinary, opts);
132
141
  const useWrapper = getWrapperPreference(this.globalBinary, opts);
133
142
  if (useWrapper) {
134
- const wrapper = this.traverseForWrapper(manifestPath);
143
+ const wrapper = traverseForWrapper(manifestDir, this.localWrapper);
135
144
  if (wrapper !== undefined) {
136
145
  try {
137
146
  this._invokeCommand(wrapper, ['--version'], { cwd: manifestDir });
@@ -156,39 +165,4 @@ export default class Base_Java {
156
165
  }
157
166
  return toolPath;
158
167
  }
159
- /**
160
- *
161
- * @param {string} startingManifest - the path of the manifest from which to start searching for the wrapper
162
- * @param {string} repoRoot - the root of the repository at which point to stop searching for mvnw, derived via git if unset and then fallsback
163
- * to the root of the drive the manifest is on (assumes absolute path is given)
164
- * @returns {string|undefined}
165
- */
166
- traverseForWrapper(startingManifest, repoRoot = undefined) {
167
- const normalizedManifest = this.normalizePath(startingManifest);
168
- const currentDir = this.normalizePath(path.dirname(normalizedManifest));
169
- repoRoot = repoRoot || getGitRootDir(currentDir) || path.parse(normalizedManifest).root;
170
- const wrapperPath = path.join(currentDir, this.localWrapper);
171
- try {
172
- fs.accessSync(wrapperPath, fs.constants.X_OK);
173
- return wrapperPath;
174
- }
175
- catch (error) {
176
- if (error.code === 'ENOENT') {
177
- const rootDir = path.parse(currentDir).root;
178
- if (currentDir === repoRoot || currentDir === rootDir) {
179
- return undefined;
180
- }
181
- const parentDir = path.dirname(currentDir);
182
- if (parentDir === currentDir || parentDir === rootDir) {
183
- return undefined;
184
- }
185
- return this.traverseForWrapper(path.join(parentDir, path.basename(normalizedManifest)), repoRoot);
186
- }
187
- throw new Error(`failure searching for ${this.localWrapper}`, { cause: error });
188
- }
189
- }
190
- normalizePath(thePath) {
191
- const normalized = path.resolve(thePath).normalize();
192
- return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
193
- }
194
168
  }
@@ -47,6 +47,11 @@ export default class Base_javascript {
47
47
  */
48
48
  protected _cmdName(): string;
49
49
  /**
50
+ * Returns the package manager name (e.g. npm, yarn, pnpm, bun)
51
+ * @returns {string} The package manager name
52
+ */
53
+ packageManagerName(): string;
54
+ /**
50
55
  * Returns the command arguments for listing dependencies
51
56
  * @returns {Array<string>} The command arguments
52
57
  * @abstract
@@ -136,6 +141,12 @@ export default class Base_javascript {
136
141
  */
137
142
  protected _version(): string;
138
143
  /**
144
+ * Creates or updates the lock file for the package manager
145
+ * @param {string} manifestDir - Directory containing the manifest file
146
+ * @protected
147
+ */
148
+ protected _createLockFile(manifestDir: string): void;
149
+ /**
139
150
  * Parses the dependency tree output
140
151
  * @param {string} output - The output to parse
141
152
  * @returns {string} The parsed output
@@ -71,6 +71,13 @@ export default class Base_javascript {
71
71
  throw new TypeError("_cmdName must be implemented");
72
72
  }
73
73
  /**
74
+ * Returns the package manager name (e.g. npm, yarn, pnpm, bun)
75
+ * @returns {string} The package manager name
76
+ */
77
+ packageManagerName() {
78
+ return this._cmdName();
79
+ }
80
+ /**
74
81
  * Returns the command arguments for listing dependencies
75
82
  * @returns {Array<string>} The command arguments
76
83
  * @abstract
@@ -217,7 +224,7 @@ export default class Base_javascript {
217
224
  this._version();
218
225
  const manifestDir = path.dirname(this.#manifest.manifestPath);
219
226
  const cmdDir = this._findLockFileDir(manifestDir, opts) || manifestDir;
220
- this.#createLockFile(cmdDir);
227
+ this._createLockFile(cmdDir);
221
228
  let output = this.#executeListCmd(includeTransitive, cmdDir);
222
229
  output = this._parseDepTreeOutput(output);
223
230
  return JSON.parse(output);
@@ -363,9 +370,9 @@ export default class Base_javascript {
363
370
  /**
364
371
  * Creates or updates the lock file for the package manager
365
372
  * @param {string} manifestDir - Directory containing the manifest file
366
- * @private
373
+ * @protected
367
374
  */
368
- #createLockFile(manifestDir) {
375
+ _createLockFile(manifestDir) {
369
376
  const originalDir = process.cwd();
370
377
  const isWindows = os.platform() === 'win32';
371
378
  if (isWindows) {
@@ -0,0 +1,158 @@
1
+ /** @typedef {{name: string, version: string, children: string[], hashes?: Array<{alg: string, content: string}>}} GraphEntry */
2
+ /** @typedef {{name: string, version: string, dependencies: DepTreeEntry[]}} DepTreeEntry */
3
+ /** @typedef {{directDeps: string[], graph: Map<string, GraphEntry>}} DependencyData */
4
+ /** @typedef {{ecosystem: string, content: string, contentType: string}} Provided */
5
+ export default class Base_pyproject {
6
+ /**
7
+ * @param {string} manifestName
8
+ * @returns {boolean}
9
+ */
10
+ isSupported(manifestName: string): boolean;
11
+ /**
12
+ * @param {string} manifestDir
13
+ * @param {Object} [opts={}]
14
+ * @returns {boolean}
15
+ */
16
+ validateLockFile(manifestDir: string, opts?: any): boolean;
17
+ /**
18
+ * Walk up from manifestDir to find the directory containing the lock file.
19
+ * Follows the same pattern as Base_javascript._findLockFileDir().
20
+ * @param {string} manifestDir
21
+ * @param {Object} [opts={}]
22
+ * @returns {string|null}
23
+ * @protected
24
+ */
25
+ protected _findLockFileDir(manifestDir: string, opts?: any): string | null;
26
+ /**
27
+ * Detect workspace root boundaries.
28
+ * Currently only uv has native workspace support ([tool.uv.workspace] in pyproject.toml).
29
+ * Poetry has no workspace/monorepo support (python-poetry/poetry#2270), so each
30
+ * poetry project is treated independently — see Python_poetry._findLockFileDir().
31
+ * @param {string} dir
32
+ * @returns {boolean}
33
+ * @protected
34
+ */
35
+ protected _isWorkspaceRoot(dir: string): boolean;
36
+ /**
37
+ * Read project license from pyproject.toml, with fallback to LICENSE file.
38
+ * @param {string} manifestPath
39
+ * @returns {string|null}
40
+ */
41
+ readLicenseFromManifest(manifestPath: string): string | null;
42
+ /**
43
+ * @param {string} manifest - path to pyproject.toml
44
+ * @param {Object} [opts={}]
45
+ * @returns {Promise<Provided>}
46
+ */
47
+ provideStack(manifest: string, opts?: any): Promise<Provided>;
48
+ /**
49
+ * @param {string} manifest - path to pyproject.toml
50
+ * @param {Object} [opts={}]
51
+ * @returns {Promise<Provided>}
52
+ */
53
+ provideComponent(manifest: string, opts?: any): Promise<Provided>;
54
+ /**
55
+ * @returns {string}
56
+ * @protected
57
+ */
58
+ protected _lockFileName(): string;
59
+ /**
60
+ * @returns {string}
61
+ * @protected
62
+ */
63
+ protected _cmdName(): string;
64
+ /**
65
+ * Returns the package manager name (e.g. pip, poetry, uv)
66
+ * @returns {string}
67
+ */
68
+ packageManagerName(): string;
69
+ /**
70
+ * Resolve dependencies using the tool-specific command and parser.
71
+ *
72
+ * @param {string} manifestDir - directory containing the target pyproject.toml
73
+ * @param {string} workspaceDir - workspace root (where the lock file lives);
74
+ * only used by providers that need workspace-level resolution (e.g. uv)
75
+ * @param {object} parsed - parsed pyproject.toml
76
+ * @param {Object} opts
77
+ * @returns {Promise<DependencyData>}
78
+ * @protected
79
+ */
80
+ protected _getDependencyData(manifestDir: string, workspaceDir: string, parsed: object, opts: any): Promise<DependencyData>;
81
+ /**
82
+ * Canonicalize a Python package name per PEP 503.
83
+ * @param {string} name
84
+ * @returns {string}
85
+ * @protected
86
+ */
87
+ protected _canonicalize(name: string): string;
88
+ /**
89
+ * Get the project name from pyproject.toml.
90
+ * @param {object} parsed
91
+ * @returns {string|null}
92
+ * @protected
93
+ */
94
+ protected _getProjectName(parsed: object): string | null;
95
+ /**
96
+ * Get the project version from pyproject.toml.
97
+ * @param {object} parsed
98
+ * @returns {string|null}
99
+ * @protected
100
+ */
101
+ protected _getProjectVersion(parsed: object): string | null;
102
+ /**
103
+ * Scan raw pyproject.toml text for dependencies with ignore markers.
104
+ * @param {string} manifestPath
105
+ * @returns {Set<string>}
106
+ * @protected
107
+ */
108
+ protected _getIgnoredDeps(manifestPath: string): Set<string>;
109
+ /**
110
+ * Compute the set of graph nodes reachable from direct deps, excluding ignored.
111
+ * @param {Map<string, GraphEntry>} graph
112
+ * @param {string[]} directDeps
113
+ * @param {Set<string>} ignoredDeps
114
+ * @returns {Set<string>}
115
+ * @protected
116
+ */
117
+ protected _reachableNodes(graph: Map<string, GraphEntry>, directDeps: string[], ignoredDeps: Set<string>): Set<string>;
118
+ /**
119
+ * @param {string} name
120
+ * @param {string} version
121
+ * @returns {PackageURL}
122
+ * @protected
123
+ */
124
+ protected _toPurl(name: string, version: string): PackageURL;
125
+ /**
126
+ * Create SBOM json string for a pyproject.toml project.
127
+ * @param {string} manifest - path to pyproject.toml
128
+ * @param {Object} opts
129
+ * @param {boolean} includeTransitive
130
+ * @returns {Promise<string>}
131
+ * @private
132
+ */
133
+ private _createSbom;
134
+ }
135
+ export type GraphEntry = {
136
+ name: string;
137
+ version: string;
138
+ children: string[];
139
+ hashes?: Array<{
140
+ alg: string;
141
+ content: string;
142
+ }>;
143
+ };
144
+ export type DepTreeEntry = {
145
+ name: string;
146
+ version: string;
147
+ dependencies: DepTreeEntry[];
148
+ };
149
+ export type DependencyData = {
150
+ directDeps: string[];
151
+ graph: Map<string, GraphEntry>;
152
+ };
153
+ export type Provided = {
154
+ ecosystem: string;
155
+ content: string;
156
+ contentType: string;
157
+ };
158
+ import { PackageURL } from 'packageurl-js';