From 4111fc3c68c2431e8a974c27f162dd60c6269078 Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Thu, 12 Mar 2026 15:18:41 +0200 Subject: [PATCH 1/7] feat: rust analysis support --- CONTRIBUTING.md | 1 + README.md | 23 +- src/index.js | 1 + src/provider.js | 4 +- src/providers/rust_cargo.js | 647 ++++++++++++++++++ .../cargo/with_lock_file/Cargo.lock | 1 + .../cargo/with_lock_file/Cargo.toml | 7 + .../cargo/without_lock_file/Cargo.toml | 7 + .../workspace_member_with_lock/Cargo.lock | 7 + .../workspace_member_with_lock/Cargo.toml | 6 + .../member1/Cargo.toml | 7 + .../workspace_member_without_lock/Cargo.toml | 2 + .../member1/Cargo.toml | 7 + test/providers/rust_cargo.test.js | 485 +++++++++++++ .../cargo_single_crate_no_ignore/Cargo.lock | 2 + .../cargo_single_crate_no_ignore/Cargo.toml | 11 + .../cargo_metadata.json | 110 +++ .../expected_sbom_component_analysis.json | 55 ++ .../expected_sbom_stack_analysis.json | 81 +++ .../Cargo.lock | 2 + .../Cargo.toml | 11 + .../cargo_metadata.json | 110 +++ .../expected_sbom_component_analysis.json | 43 ++ .../expected_sbom_stack_analysis.json | 56 ++ .../Cargo.lock | 1 + .../Cargo.toml | 14 + .../cargo_metadata.json | 108 +++ .../cargo_single_crate_with_ignore/Cargo.lock | 2 + .../cargo_single_crate_with_ignore/Cargo.toml | 11 + .../cargo_metadata.json | 110 +++ .../expected_sbom_component_analysis.json | 43 ++ .../expected_sbom_stack_analysis.json | 56 ++ .../cargo/cargo_virtual_workspace/Cargo.lock | 2 + .../cargo/cargo_virtual_workspace/Cargo.toml | 6 + .../cargo_metadata.json | 90 +++ .../crate-a/Cargo.toml | 7 + .../crate-b/Cargo.toml | 7 + .../expected_sbom_component_analysis.json | 25 + .../expected_sbom_stack_analysis.json | 94 +++ .../Cargo.lock | 1 + .../Cargo.toml | 5 + .../cargo_metadata.json | 90 +++ .../crates/crate-a/Cargo.toml | 7 + .../crates/crate-b/Cargo.toml | 7 + .../expected_sbom_component_analysis.json | 25 + .../expected_sbom_stack_analysis.json | 81 +++ .../Cargo.lock | 2 + .../Cargo.toml | 6 + .../cargo_metadata.json | 90 +++ .../crate-a/Cargo.toml | 7 + .../crate-b/Cargo.toml | 7 + .../expected_sbom_component_analysis.json | 25 + .../expected_sbom_stack_analysis.json | 81 +++ .../Cargo.lock | 2 + .../Cargo.toml | 6 + .../cargo_metadata.json | 90 +++ .../crate-a/Cargo.toml | 7 + .../crate-b/Cargo.toml | 7 + .../expected_sbom_component_analysis.json | 25 + .../expected_sbom_stack_analysis.json | 81 +++ .../Cargo.lock | 1 + .../Cargo.toml | 10 + .../cargo_metadata.json | 90 +++ .../expected_sbom_component_analysis.json | 55 ++ .../expected_sbom_stack_analysis.json | 94 +++ .../cargo_workspace_with_root/Cargo.lock | 2 + .../cargo_workspace_with_root/Cargo.toml | 16 + .../cargo_metadata.json | 106 +++ .../expected_sbom_component_analysis.json | 43 ++ .../expected_sbom_stack_analysis.json | 43 ++ .../sub-crate/Cargo.toml | 7 + .../Cargo.lock | 2 + .../Cargo.toml | 16 + .../cargo_metadata.json | 106 +++ .../expected_sbom_component_analysis.json | 25 + .../expected_sbom_stack_analysis.json | 25 + .../sub-crate/Cargo.toml | 7 + .../Cargo.lock | 2 + .../Cargo.toml | 16 + .../cargo_metadata.json | 106 +++ .../expected_sbom_component_analysis.json | 25 + .../expected_sbom_stack_analysis.json | 25 + .../sub-crate/Cargo.toml | 7 + 83 files changed, 3741 insertions(+), 2 deletions(-) create mode 100644 src/providers/rust_cargo.js create mode 100644 test/providers/provider_manifests/cargo/with_lock_file/Cargo.lock create mode 100644 test/providers/provider_manifests/cargo/with_lock_file/Cargo.toml create mode 100644 test/providers/provider_manifests/cargo/without_lock_file/Cargo.toml create mode 100644 test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.lock create mode 100644 test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.toml create mode 100644 test/providers/provider_manifests/cargo/workspace_member_with_lock/member1/Cargo.toml create mode 100644 test/providers/provider_manifests/cargo/workspace_member_without_lock/Cargo.toml create mode 100644 test/providers/provider_manifests/cargo/workspace_member_without_lock/member1/Cargo.toml create mode 100644 test/providers/rust_cargo.test.js create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-a/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-b/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-a/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-b/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-a/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-b/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-a/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-b/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root/sub-crate/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/sub-crate/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.lock create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.toml create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/cargo_metadata.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_component_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_stack_analysis.json create mode 100644 test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/sub-crate/Cargo.toml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index adbb4648..2f497eb2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,6 +42,7 @@ The OpenAPI specification is located in the [`trustify-da-api-spec`](https://git which will provide data that we can send to the _Backend_ using _analysis.js_. See the [Adding a Provider](#adding-a-provider) section. * [java_maven.js](src/providers/java_maven.js) is the provider for the _Java_ _Maven_ ecosystem. + * [rust_cargo.js](src/providers/rust_cargo.js) is the provider for the _Rust_ _Cargo_ ecosystem. #### Types diff --git a/README.md b/README.md index 56e6f5d5..092b9fb9 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,7 @@ $ trustify-da-javascript-client image httpd:2.4.49^^amd64
  • Golang - Go Modules
  • Python - pip Installer
  • Gradle (Groovy and Kotlin DSL) - Gradle Installation
  • +
  • Rust - Cargo
  • Excluding Packages

    @@ -297,7 +298,21 @@ test { } ``` -All of the 5 above examples are valid for marking a package to be ignored +Rust Cargo users can add a comment with # trustify-da-ignore (or # exhortignore) in Cargo.toml next to the dependency to be ignored. This works for inline declarations, table-based declarations, and workspace-level dependency sections: + +```toml +[dependencies] +serde = "1.0" # trustify-da-ignore +tokio = { version = "1.35", features = ["full"] } + +[dependencies.regex] # trustify-da-ignore +version = "1.10" + +[workspace.dependencies] +log = "0.4" # trustify-da-ignore +``` + +All of the 6 above examples are valid for marking a package to be ignored @@ -329,6 +344,7 @@ let options = { 'TRUSTIFY_DA_PYTHON_PATH' : '/path/to/python', 'TRUSTIFY_DA_PIP_PATH' : '/path/to/pip', 'TRUSTIFY_DA_GRADLE_PATH' : '/path/to/gradle', + 'TRUSTIFY_DA_CARGO_PATH' : '/path/to/cargo', // Configure proxy for all requests 'TRUSTIFY_DA_PROXY_URL': 'http://proxy.example.com:8080' } @@ -445,6 +461,11 @@ following keys for setting custom paths for the said executables. gradle TRUSTIFY_DA_PREFER_GRADLEW + +Rust Cargo +cargo +TRUSTIFY_DA_CARGO_PATH + #### Match Manifest Versions Feature diff --git a/src/index.js b/src/index.js index 4ff21804..95ade525 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ export default { componentAnalysis, stackAnalysis, imageAnalysis, validateToken /** * @typedef {{ + * TRUSTIFY_DA_CARGO_PATH?: string | undefined, * TRUSTIFY_DA_DOCKER_PATH?: string | undefined, * TRUSTIFY_DA_GO_MVS_LOGIC_ENABLED?: string | undefined, * TRUSTIFY_DA_GO_PATH?: string | undefined, diff --git a/src/provider.js b/src/provider.js index 4bb6c30b..993d6e3a 100644 --- a/src/provider.js +++ b/src/provider.js @@ -8,6 +8,7 @@ import Javascript_npm from './providers/javascript_npm.js'; import Javascript_pnpm from './providers/javascript_pnpm.js'; import Javascript_yarn from './providers/javascript_yarn.js'; import pythonPipProvider from './providers/python_pip.js' +import rustCargoProvider from './providers/rust_cargo.js' /** @typedef {{ecosystem: string, contentType: string, content: string}} Provided */ /** @typedef {{isSupported: function(string): boolean, validateLockFile: function(string): void, provideComponent: function(string, {}): Provided, provideStack: function(string, {}): Provided}} Provider */ @@ -24,7 +25,8 @@ export const availableProviders = [ new Javascript_pnpm(), new Javascript_yarn(), golangGomodulesProvider, - pythonPipProvider] + pythonPipProvider, + rustCargoProvider] /** * Match a provider from a list or providers based on file type. diff --git a/src/providers/rust_cargo.js b/src/providers/rust_cargo.js new file mode 100644 index 00000000..528810cf --- /dev/null +++ b/src/providers/rust_cargo.js @@ -0,0 +1,647 @@ +import fs from 'node:fs' +import path from 'node:path' + +import { PackageURL } from 'packageurl-js' + +import Sbom from '../sbom.js' +import { getCustomPath, invokeCommand } from '../tools.js' + +export default { isSupported, validateLockFile, provideComponent, provideStack } + +/** @typedef {import('../provider').Provider} */ + +/** @typedef {import('../provider').Provided} Provided */ + +/** + * @type {string} ecosystem identifier for cargo/crates packages + * @private + */ +const ecosystem = 'cargo' + +/** + * Ignore markers recognised in Cargo.toml comments. + * Supports both the legacy `exhortignore` marker and the new `trustify-da-ignore` marker. + * @type {string[]} + * @private + */ +const IGNORE_MARKERS = ['exhortignore', 'trustify-da-ignore'] + +/** + * Checks whether a line contains any of the recognised ignore markers. + * @param {string} line - the line to check + * @returns {boolean} true if the line contains at least one ignore marker + * @private + */ +function hasIgnoreMarker(line) { + return IGNORE_MARKERS.some(marker => line.includes(marker)) +} + +/** + * Checks whether a dependency name is in the ignored set, accounting for + * Cargo's underscore/hyphen equivalence + * @param {string} name - the dependency name to check + * @param {Set} ignoredDeps - set of ignored dependency names + * @returns {boolean} true if the dependency should be ignored + * @private + */ +function isDepIgnored(name, ignoredDeps) { + if (ignoredDeps.has(name)) {return true} + let normalized = name.replace(/_/g, '-') + if (normalized !== name && ignoredDeps.has(normalized)) {return true} + normalized = name.replace(/-/g, '_') + if (normalized !== name && ignoredDeps.has(normalized)) {return true} + return false +} + +/** + * Enum-like constants for Cargo project types. + * @private + */ +const CrateType = { + SINGLE_CRATE: 'SINGLE_CRATE', + WORKSPACE_VIRTUAL: 'WORKSPACE_VIRTUAL', + WORKSPACE_WITH_ROOT_CRATE: 'WORKSPACE_WITH_ROOT_CRATE' +} + +/** + * @param {string} manifestName - the subject manifest name-type + * @returns {boolean} - return true if `Cargo.toml` is the manifest name-type + */ +function isSupported(manifestName) { + return 'Cargo.toml' === manifestName +} + +/** + * Validates that Cargo.lock exists in the manifest directory or in a parent + * workspace root directory. In Cargo workspaces the lock file always lives at + * the workspace root, so when a member crate's Cargo.toml is provided we walk + * up the directory tree looking for Cargo.lock (stopping when we find a + * Cargo.toml that contains a [workspace] section, or when we reach the + * filesystem root). + * @param {string} manifestDir - the directory where the manifest lies + * @returns {boolean} true if Cargo.lock is found + */ +function validateLockFile(manifestDir) { + let dir = path.resolve(manifestDir) + let parent = dir + + do { + dir = parent + + if (fs.existsSync(path.join(dir, 'Cargo.lock'))) { + return true + } + + // If this directory has a Cargo.toml with [workspace], the lock file + // should have been here — stop searching. + let cargoToml = path.join(dir, 'Cargo.toml') + if (fs.existsSync(cargoToml)) { + try { + let content = fs.readFileSync(cargoToml, 'utf-8') + if (/\[workspace\]/.test(content)) { + return false + } + } catch (_) { + // ignore read errors, keep searching + } + } + + parent = path.dirname(dir) + } while (parent !== dir) + + return false +} + +/** + * Provide content and content type for Cargo stack analysis. + * @param {string} manifest - the manifest path + * @param {{}} [opts={}] - optional various options to pass along the application + * @returns {Provided} + */ +function provideStack(manifest, opts = {}) { + return { + ecosystem, + content: getSBOM(manifest, opts, true), + contentType: 'application/vnd.cyclonedx+json' + } +} + +/** + * Provide content and content type for Cargo component analysis. + * @param {string} manifest - path to Cargo.toml for component report + * @param {{}} [opts={}] - optional various options to pass along the application + * @returns {Provided} + */ +function provideComponent(manifest, opts = {}) { + return { + ecosystem, + content: getSBOM(manifest, opts, false), + contentType: 'application/vnd.cyclonedx+json' + } +} + +/** + * Create SBOM json string for a Cargo project. + * @param {string} manifest - path to Cargo.toml + * @param {{}} [opts={}] - optional various options to pass along the application + * @param {boolean} includeTransitive - whether the sbom should contain transitive dependencies + * @returns {string} the SBOM json content + * @private + */ +function getSBOM(manifest, opts = {}, includeTransitive) { + let cargoBin = getCustomPath('cargo', opts) + verifyCargoAccessible(cargoBin) + + let manifestDir = path.dirname(manifest) + let metadata = executeCargoMetadata(cargoBin, manifestDir) + let ignoredDeps = getIgnoredDeps(manifest, metadata) + let crateType = detectCrateType(metadata) + + let sbom + if (crateType === CrateType.WORKSPACE_VIRTUAL) { + sbom = handleVirtualWorkspace(manifest, metadata, ignoredDeps, includeTransitive, opts) + } else if (crateType === CrateType.WORKSPACE_WITH_ROOT_CRATE) { + sbom = handleWorkspaceWithRoot(metadata, ignoredDeps, includeTransitive, opts) + } else { + sbom = handleSingleCrate(metadata, ignoredDeps, includeTransitive, opts) + } + + return sbom +} + +/** + * Verifies that the cargo binary is accessible. + * @param {string} cargoBin - path to cargo binary + * @throws {Error} if cargo is not accessible + * @private + */ +function verifyCargoAccessible(cargoBin) { + try { + invokeCommand(cargoBin, ['--version']) + } catch (error) { + if (error.code === 'ENOENT') { + throw new Error(`cargo binary is not accessible at "${cargoBin}"`) + } + throw new Error('failed to check for cargo binary', { cause: error }) + } +} + +/** + * Executes `cargo metadata` and returns the parsed JSON. + * @param {string} cargoBin - path to cargo binary + * @param {string} manifestDir - directory containing Cargo.toml + * @returns {object} parsed cargo metadata JSON + * @throws {Error} if cargo metadata fails + * @private + */ +function executeCargoMetadata(cargoBin, manifestDir) { + try { + let output = invokeCommand(cargoBin, ['metadata', '--format-version', '1'], { cwd: manifestDir }) + return JSON.parse(output.toString().trim()) + } catch (error) { + throw new Error('failed to execute cargo metadata', { cause: error }) + } +} + +/** + * Detects the type of Cargo project from metadata. + * @param {object} metadata - parsed cargo metadata + * @returns {string} one of CrateType values + * @private + */ +function detectCrateType(metadata) { + let rootPackageId = metadata.resolve?.root + let workspaceMembers = metadata.workspace_members || [] + + if (!rootPackageId && workspaceMembers.length > 0) { + return CrateType.WORKSPACE_VIRTUAL + } + + if (rootPackageId && workspaceMembers.length > 1) { + return CrateType.WORKSPACE_WITH_ROOT_CRATE + } + + return CrateType.SINGLE_CRATE +} + +/** + * Handles SBOM generation for single crate projects (no workspace members beyond the root). + * @param {object} metadata - parsed cargo metadata + * @param {Set} ignoredDeps - set of ignored dependency names + * @param {boolean} includeTransitive - whether to include transitive dependencies + * @param {{}} opts - options + * @returns {string} SBOM json string + * @private + */ +function handleSingleCrate(metadata, ignoredDeps, includeTransitive, opts) { + let rootPackageId = metadata.resolve.root + let rootPackage = findPackageById(metadata, rootPackageId) + let rootPurl = toPurl(rootPackage.name, rootPackage.version) + + let sbom = new Sbom() + sbom.addRoot(rootPurl) + + let resolveNode = findResolveNode(metadata, rootPackageId) + if (!resolveNode) { + return sbom.getAsJsonString(opts) + } + + if (includeTransitive) { + addTransitiveDeps(sbom, metadata, rootPackageId, ignoredDeps, new Set()) + } else { + addDirectDeps(sbom, metadata, rootPackageId, rootPurl, ignoredDeps) + } + + return sbom.getAsJsonString(opts) +} + +/** + * Handles SBOM generation for workspace-with-root-crate projects. + * Processes root crate dependencies — this naturally includes any workspace + * members that are actual dependencies via the cargo dependency graph. + * Workspace members are only included if they appear in the root crate's + * dependency graph from cargo metadata. We don't automatically add all + * members as dependencies since most workspace members (examples, tools, + * benchmarks) depend ON the root crate, not the other way around. + * @param {object} metadata - parsed cargo metadata + * @param {Set} ignoredDeps - set of ignored dependency names + * @param {boolean} includeTransitive - whether to include transitive dependencies + * @param {{}} opts - options + * @returns {string} SBOM json string + * @private + */ +function handleWorkspaceWithRoot(metadata, ignoredDeps, includeTransitive, opts) { + let rootPackageId = metadata.resolve.root + let rootPackage = findPackageById(metadata, rootPackageId) + let rootPurl = toPurl(rootPackage.name, rootPackage.version) + + let sbom = new Sbom() + sbom.addRoot(rootPurl) + + let resolveNode = findResolveNode(metadata, rootPackageId) + if (!resolveNode) { + return sbom.getAsJsonString(opts) + } + + if (includeTransitive) { + addTransitiveDeps(sbom, metadata, rootPackageId, ignoredDeps, new Set()) + } else { + addDirectDeps(sbom, metadata, rootPackageId, rootPurl, ignoredDeps) + } + + return sbom.getAsJsonString(opts) +} + +/** + * Handles SBOM generation for virtual workspace projects. + * + * For stack analysis (includeTransitive=true): + * Iterates all workspace members and walks their full dependency trees. + * + * For component analysis (includeTransitive=false): + * Only includes dependencies explicitly listed in [workspace.dependencies] + * of the root Cargo.toml. If that section is absent the SBOM contains only + * the synthetic workspace root with no dependencies — this matches the Java + * client behaviour where CA "just analyzes direct dependencies defined in + * Cargo.toml". + * + * @param {string} manifest - path to the root Cargo.toml + * @param {object} metadata - parsed cargo metadata + * @param {Set} ignoredDeps - set of ignored dependency names + * @param {boolean} includeTransitive - whether to include transitive dependencies + * @param {{}} opts - options + * @returns {string} SBOM json string + * @private + */ +function handleVirtualWorkspace(manifest, metadata, ignoredDeps, includeTransitive, opts) { + let workspaceRoot = metadata.workspace_root + let rootName = path.basename(workspaceRoot) + let workspaceVersion = getWorkspaceVersion(metadata) + let rootPurl = toPurl(rootName, workspaceVersion) + + let sbom = new Sbom() + sbom.addRoot(rootPurl) + + if (includeTransitive) { + // Stack analysis: walk all members and their full dependency trees + let workspaceMembers = metadata.workspace_members || [] + + for (let memberId of workspaceMembers) { + let memberPackage = findPackageById(metadata, memberId) + if (!memberPackage) {continue} + + let memberPurl = toPurl(memberPackage.name, memberPackage.version) + sbom.addDependency(rootPurl, memberPurl) + addTransitiveDeps(sbom, metadata, memberId, ignoredDeps, new Set()) + } + } else { + // Component analysis: only [workspace.dependencies] from root Cargo.toml + let workspaceDeps = getWorkspaceDepsFromManifest(manifest) + + for (let depName of workspaceDeps) { + if (isDepIgnored(depName, ignoredDeps)) {continue} + + let pkg = metadata.packages.find(p => p.name === depName && p.source != null) + if (!pkg) { + let altName = depName.replace(/-/g, '_') + pkg = metadata.packages.find(p => p.name === altName && p.source != null) + } + if (!pkg) {continue} + + let depPurl = toPurl(pkg.name, pkg.version) + sbom.addDependency(rootPurl, depPurl) + } + } + + return sbom.getAsJsonString(opts) +} + +/** + * Recursively adds transitive dependencies to the SBOM. + * @param {Sbom} sbom - the SBOM to add dependencies to + * @param {object} metadata - parsed cargo metadata + * @param {string} packageId - the package ID to resolve dependencies for + * @param {Set} ignoredDeps - set of ignored dependency names + * @param {Set} visited - set of already-visited package IDs to prevent cycles + * @private + */ +function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited) { + if (visited.has(packageId)) {return} + visited.add(packageId) + + let resolveNode = findResolveNode(metadata, packageId) + if (!resolveNode) {return} + + let sourcePackage = findPackageById(metadata, packageId) + if (!sourcePackage) {return} + let sourcePurl = toPurl(sourcePackage.name, sourcePackage.version) + + let runtimeDeps = filterRuntimeDeps(resolveNode) + + for (let depId of runtimeDeps) { + let depPackage = findPackageById(metadata, depId) + if (!depPackage) {continue} + if (isDepIgnored(depPackage.name, ignoredDeps)) {continue} + + let depPurl = toPurl(depPackage.name, depPackage.version) + sbom.addDependency(sourcePurl, depPurl) + addTransitiveDeps(sbom, metadata, depId, ignoredDeps, visited) + } +} + +/** + * Adds only direct (non-transitive) dependencies to the SBOM. + * @param {Sbom} sbom - the SBOM to add dependencies to + * @param {object} metadata - parsed cargo metadata + * @param {string} packageId - the package ID to resolve dependencies for + * @param {PackageURL} parentPurl - the parent purl to attach dependencies to + * @param {Set} ignoredDeps - set of ignored dependency names + * @private + */ +function addDirectDeps(sbom, metadata, packageId, parentPurl, ignoredDeps) { + let resolveNode = findResolveNode(metadata, packageId) + if (!resolveNode) {return} + + let runtimeDeps = filterRuntimeDeps(resolveNode) + + for (let depId of runtimeDeps) { + let depPackage = findPackageById(metadata, depId) + if (!depPackage) {continue} + if (isDepIgnored(depPackage.name, ignoredDeps)) {continue} + + let depPurl = toPurl(depPackage.name, depPackage.version) + sbom.addDependency(parentPurl, depPurl) + } +} + +/** + * Filters the deps of a resolve node to only include runtime (normal) dependencies. + * @param {object} resolveNode - a node from metadata.resolve.nodes + * @returns {string[]} array of package IDs for runtime dependencies + * @private + */ +function filterRuntimeDeps(resolveNode) { + if (!resolveNode.deps) {return []} + + return resolveNode.deps + .filter(dep => { + if (!dep.dep_kinds || dep.dep_kinds.length === 0) {return true} + return dep.dep_kinds.some(dk => dk.kind == null || dk.kind === 'normal') + }) + .map(dep => dep.pkg) +} + +/** + * Finds a package in the metadata by its ID. + * @param {object} metadata - parsed cargo metadata + * @param {string} packageId - the package ID to find + * @returns {object|undefined} the found package or undefined + * @private + */ +function findPackageById(metadata, packageId) { + return metadata.packages.find(pkg => pkg.id === packageId) +} + +/** + * Finds a resolve node by package ID. + * @param {object} metadata - parsed cargo metadata + * @param {string} packageId - the package ID to find + * @returns {object|undefined} the found resolve node or undefined + * @private + */ +function findResolveNode(metadata, packageId) { + return metadata.resolve.nodes.find(node => node.id === packageId) +} + +/** + * Parses the root Cargo.toml and returns the dependency names listed in the + * [workspace.dependencies] section. Returns an empty array when the section + * does not exist. + * @param {string} manifest - path to the root Cargo.toml + * @returns {string[]} list of dependency names + * @private + */ +function getWorkspaceDepsFromManifest(manifest) { + let content + try { + content = fs.readFileSync(manifest, 'utf-8') + } catch (_) { + return [] + } + + let lines = content.split(/\r?\n/) + let inSection = false + let names = [] + + for (let line of lines) { + let trimmed = line.trim() + + let sectionMatch = trimmed.match(/^\[([^\]]+)\]\s*(?:#.*)?$/) + if (sectionMatch) { + inSection = sectionMatch[1] === 'workspace.dependencies' + continue + } + + if (inSection) { + let nameMatch = trimmed.match(/^([a-zA-Z0-9_-]+)\s*=/) + if (nameMatch) { + names.push(nameMatch[1]) + } + } + } + + return names +} + +/** + * Extracts the workspace version from metadata if defined. + * @param {object} metadata - parsed cargo metadata + * @returns {string} the workspace version or a placeholder + * @private + */ +function getWorkspaceVersion(metadata) { + let workspaceRoot = metadata.workspace_root + let cargoTomlPath = path.join(workspaceRoot, 'Cargo.toml') + try { + let content = fs.readFileSync(cargoTomlPath, 'utf-8') + let versionMatch = content.match(/\[workspace\.package\][\s\S]*?version\s*=\s*"([^"]+)"/) + if (versionMatch) { + return versionMatch[1] + } + } catch (_) { + // fall through to default + } + return '0.0.0' +} + +/** + * Parses Cargo.toml for dependencies annotated with an ignore marker. + * Supports both `exhortignore` and `trustify-da-ignore` markers. + * Supports inline deps, table-based deps, and workspace-level dependency sections. + * Uses cargo metadata to discover workspace members (which already handles glob + * expansion and exclude filtering) instead of parsing workspace member paths ourselves. + * @param {string} manifest - path to Cargo.toml + * @param {object} metadata - parsed cargo metadata + * @returns {Set} set of dependency names to ignore + * @private + */ +function getIgnoredDeps(manifest, metadata) { + let ignored = new Set() + + scanManifestForIgnored(manifest, ignored) + + // Scan workspace member manifests using metadata + let manifestDir = path.dirname(manifest) + let workspaceRoot = metadata.workspace_root + let workspaceMembers = metadata.workspace_members || [] + + for (let memberId of workspaceMembers) { + let memberRelDir = getMemberRelativeDir(memberId, workspaceRoot) + if (memberRelDir == null) {continue} + + let memberManifest = path.join(manifestDir, memberRelDir, 'Cargo.toml') + if (path.resolve(memberManifest) === path.resolve(manifest)) {continue} + + if (fs.existsSync(memberManifest)) { + scanManifestForIgnored(memberManifest, ignored) + } + } + + return ignored +} + +/** + * Extracts a workspace member's directory path relative to the workspace root + * from its cargo package ID. Workspace member IDs use the `path+file://` scheme, + * e.g. `path+file:///workspace/root/crates/member#0.1.0`. + * @param {string} packageId - the cargo package ID + * @param {string} workspaceRoot - the workspace root path from cargo metadata + * @returns {string|null} relative directory path, or null if it cannot be determined + * @private + */ +function getMemberRelativeDir(packageId, workspaceRoot) { + let pathMatch = packageId.match(/path\+file:\/\/(.+?)#/) + if (!pathMatch) {return null} + + let pkgPath = pathMatch[1] + if (!pkgPath.startsWith(workspaceRoot)) {return null} + + let relPath = pkgPath.substring(workspaceRoot.length) + if (relPath.startsWith('/')) {relPath = relPath.substring(1)} + + return relPath || null +} + +/** + * Scans a single Cargo.toml for ignored dependencies and adds them to the set. + * @param {string} manifest - path to Cargo.toml + * @param {Set} ignored - the set to add ignored dependency names to + * @private + */ +function scanManifestForIgnored(manifest, ignored) { + let content = fs.readFileSync(manifest, 'utf-8') + let lines = content.split(/\r?\n/) + + let currentSection = '' + let currentDepName = null + + for (let line of lines) { + let trimmed = line.trim() + + let sectionMatch = trimmed.match(/^\[([^\]]+)\]\s*(?:#.*)?$/) + if (sectionMatch) { + currentSection = sectionMatch[1] + currentDepName = null + + let tableDep = currentSection.match(/^(?:dependencies|dev-dependencies|build-dependencies|workspace\.dependencies)\.(.+)$/) + if (tableDep) { + currentDepName = tableDep[1] + // If the section header line itself carries an ignore marker, + // immediately add the dep + if (hasIgnoreMarker(line)) { + ignored.add(currentDepName) + } + } + continue + } + + let isIgnored = hasIgnoreMarker(line) + + if (isIgnored && isInDependencySection(currentSection)) { + let inlineMatch = trimmed.match(/^([a-zA-Z0-9_-]+)\s*=/) + if (inlineMatch) { + ignored.add(inlineMatch[1]) + continue + } + } + + if (isIgnored && currentDepName) { + ignored.add(currentDepName) + continue + } + } +} + +/** + * Checks if a section name is a dependency section. + * @param {string} section - the TOML section name + * @returns {boolean} + * @private + */ +function isInDependencySection(section) { + return section === 'dependencies' || + section === 'dev-dependencies' || + section === 'build-dependencies' || + section === 'workspace.dependencies' +} + +/** + * Creates a PackageURL for a Cargo/crates.io package. + * @param {string} name - the crate name + * @param {string} version - the crate version + * @returns {PackageURL} the package URL + * @private + */ +function toPurl(name, version) { + return new PackageURL(ecosystem, undefined, name, version, undefined, undefined) +} diff --git a/test/providers/provider_manifests/cargo/with_lock_file/Cargo.lock b/test/providers/provider_manifests/cargo/with_lock_file/Cargo.lock new file mode 100644 index 00000000..fdffa2a0 --- /dev/null +++ b/test/providers/provider_manifests/cargo/with_lock_file/Cargo.lock @@ -0,0 +1 @@ +# placeholder diff --git a/test/providers/provider_manifests/cargo/with_lock_file/Cargo.toml b/test/providers/provider_manifests/cargo/with_lock_file/Cargo.toml new file mode 100644 index 00000000..d8aaeee2 --- /dev/null +++ b/test/providers/provider_manifests/cargo/with_lock_file/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "test-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0" diff --git a/test/providers/provider_manifests/cargo/without_lock_file/Cargo.toml b/test/providers/provider_manifests/cargo/without_lock_file/Cargo.toml new file mode 100644 index 00000000..d8aaeee2 --- /dev/null +++ b/test/providers/provider_manifests/cargo/without_lock_file/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "test-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0" diff --git a/test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.lock b/test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.lock new file mode 100644 index 00000000..51b227f7 --- /dev/null +++ b/test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "member1" +version = "1.0.0" diff --git a/test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.toml b/test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.toml new file mode 100644 index 00000000..598f5c61 --- /dev/null +++ b/test/providers/provider_manifests/cargo/workspace_member_with_lock/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = ["member1"] + +[workspace.package] +version = "1.0.0" +edition = "2021" diff --git a/test/providers/provider_manifests/cargo/workspace_member_with_lock/member1/Cargo.toml b/test/providers/provider_manifests/cargo/workspace_member_with_lock/member1/Cargo.toml new file mode 100644 index 00000000..9fd83a80 --- /dev/null +++ b/test/providers/provider_manifests/cargo/workspace_member_with_lock/member1/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "member1" +version = "1.0.0" +edition = "2021" + +[dependencies] +serde = "1.0" diff --git a/test/providers/provider_manifests/cargo/workspace_member_without_lock/Cargo.toml b/test/providers/provider_manifests/cargo/workspace_member_without_lock/Cargo.toml new file mode 100644 index 00000000..4478f8d4 --- /dev/null +++ b/test/providers/provider_manifests/cargo/workspace_member_without_lock/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["member1"] diff --git a/test/providers/provider_manifests/cargo/workspace_member_without_lock/member1/Cargo.toml b/test/providers/provider_manifests/cargo/workspace_member_without_lock/member1/Cargo.toml new file mode 100644 index 00000000..9fd83a80 --- /dev/null +++ b/test/providers/provider_manifests/cargo/workspace_member_without_lock/member1/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "member1" +version = "1.0.0" +edition = "2021" + +[dependencies] +serde = "1.0" diff --git a/test/providers/rust_cargo.test.js b/test/providers/rust_cargo.test.js new file mode 100644 index 00000000..bff0aadf --- /dev/null +++ b/test/providers/rust_cargo.test.js @@ -0,0 +1,485 @@ +import fs from 'fs' +import path from 'path' + +import { expect } from 'chai' +import esmock from 'esmock' +import { useFakeTimers } from 'sinon' + +import { availableProviders, match } from '../../src/provider.js' +import rustCargo from '../../src/providers/rust_cargo.js' + +let clock + +/** + * Creates a mocked rust_cargo provider that uses a pre-built cargo_metadata.json + * instead of actually invoking the `cargo` binary. + * @param {string} testDir - the test directory containing cargo_metadata.json and Cargo.toml + * @returns {Promise} the mocked provider module + */ +async function createMockProvider(testDir) { + const metadataPath = path.join(testDir, 'cargo_metadata.json') + const metadataJson = fs.readFileSync(metadataPath, 'utf-8') + + return esmock('../../src/providers/rust_cargo.js', { + '../../src/tools.js': { + getCustomPath: () => 'cargo', + invokeCommand: (bin, args) => { + if (args.includes('--version')) { + return 'cargo 1.75.0 (1d8b05cdd 2023-11-20)' + } + if (args.includes('metadata')) { + return metadataJson + } + return '' + } + } + }) +} + +/** + * Asserts that the provider output for a given analysis type matches the expected SBOM file. + * @param {string} testDir - the test fixture directory + * @param {'stack'|'component'} analysisType - 'stack' or 'component' + */ +async function assertSbomMatchesExpected(testDir, analysisType) { + let expectedSbom = fs.readFileSync(`${testDir}/expected_sbom_${analysisType}_analysis.json`).toString() + expectedSbom = JSON.stringify(JSON.parse(expectedSbom), null, 4) + + let provider = await createMockProvider(testDir) + let manifest = `${testDir}/Cargo.toml` + let providedData = analysisType === 'stack' + ? provider.provideStack(manifest) + : provider.provideComponent(manifest) + + expect(providedData.ecosystem).equal('cargo') + expect(providedData.contentType).equal('application/vnd.cyclonedx+json') + expect(JSON.stringify(JSON.parse(providedData.content), null, 4).trim()).to.deep.equal(expectedSbom.trim()) +} + +/** + * Creates a mock provider and returns the parsed SBOM for a given analysis type. + * @param {string} testDir - the test fixture directory + * @param {'stack'|'component'} analysisType - 'stack' or 'component' + * @returns {Promise} the parsed SBOM object + */ +async function getParsedSbom(testDir, analysisType) { + let provider = await createMockProvider(testDir) + let manifest = `${testDir}/Cargo.toml` + let providedData = analysisType === 'stack' + ? provider.provideStack(manifest) + : provider.provideComponent(manifest) + return JSON.parse(providedData.content) +} + +suite('testing the rust-cargo data provider', () => { + [ + { name: 'Cargo.toml', expected: true }, + { name: 'package.json', expected: false }, + { name: 'pom.xml', expected: false }, + { name: 'go.mod', expected: false }, + { name: 'cargo.toml', expected: false }, + ].forEach(testCase => { + test(`verify isSupported returns ${testCase.expected} for ${testCase.name}`, () => + expect(rustCargo.isSupported(testCase.name)).to.equal(testCase.expected) + ) + }); + + test('verify validateLockFile returns true when Cargo.lock exists', () => { + expect(rustCargo.validateLockFile('test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore')).to.equal(true) + }) + + test('verify validateLockFile returns true for member crate when Cargo.lock is at workspace root', () => { + expect(rustCargo.validateLockFile('test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-a')).to.equal(true) + }) + + test('verify validateLockFile returns false when Cargo.lock does not exist anywhere', () => { + expect(rustCargo.validateLockFile('test/providers/provider_manifests/cargo/without_lock_file')).to.equal(false) + }) + + test('verify match function finds Cargo provider with lock file', () => { + let provider = match('test/providers/provider_manifests/cargo/with_lock_file/Cargo.toml', availableProviders) + expect(provider).to.not.be.null + expect(provider.isSupported('Cargo.toml')).to.be.true + }) + + test('verify match function throws when Cargo.lock is missing', () => { + expect(() => match('test/providers/provider_manifests/cargo/without_lock_file/Cargo.toml', availableProviders)) + .to.throw('Cargo.toml requires a lock file') + }) + + test('verify workspace member crate finds Cargo.lock at workspace root', () => { + let provider = match('test/providers/provider_manifests/cargo/workspace_member_with_lock/member1/Cargo.toml', availableProviders) + expect(provider).to.not.be.null + expect(provider.isSupported('Cargo.toml')).to.be.true + }) + + test('verify workspace member crate throws when workspace root has no Cargo.lock', () => { + expect(() => match('test/providers/provider_manifests/cargo/workspace_member_without_lock/member1/Cargo.toml', availableProviders)) + .to.throw('Cargo.toml requires a lock file') + }) + + test('verify validateLockFile returns true for workspace member when Cargo.lock is at workspace root', () => { + expect(rustCargo.validateLockFile('test/providers/provider_manifests/cargo/workspace_member_with_lock/member1')).to.equal(true) + }) + + test('verify validateLockFile returns false for workspace member when workspace root has no Cargo.lock', () => { + expect(rustCargo.validateLockFile('test/providers/provider_manifests/cargo/workspace_member_without_lock/member1')).to.equal(false) + }) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing the rust-cargo single crate without ignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore' + + test('verify Cargo.toml sbom provided for stack analysis', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify Cargo.toml sbom provided for component analysis', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing the rust-cargo single crate with ignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore' + + test('verify Cargo.toml sbom provided for stack analysis with ignored deps', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify Cargo.toml sbom provided for component analysis with ignored deps', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing the rust-cargo virtual workspace', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_virtual_workspace' + + test('verify Cargo.toml sbom provided for stack analysis with virtual workspace', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify Cargo.toml sbom provided for component analysis with virtual workspace', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing the rust-cargo workspace with root package', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_workspace_with_root' + + test('verify Cargo.toml sbom provided for stack analysis with workspace root package', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify Cargo.toml sbom provided for component analysis with workspace root package', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo dependency filtering', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore' + + test('verify dev dependencies are excluded from stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + // tempfile is a dev dependency and should not appear in the SBOM + expect(sbom.components.find(c => c.name === 'tempfile')).to.be.undefined + + // serde and tokio (normal deps) should be present + expect(sbom.components.find(c => c.name === 'serde')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + }).timeout(10000) + + test('verify dev dependencies are excluded from component analysis', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + expect(sbom.components.find(c => c.name === 'tempfile')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo error handling', () => { + test('verify error when cargo binary is not accessible', async () => { + let provider = await esmock('../../src/providers/rust_cargo.js', { + '../../src/tools.js': { + getCustomPath: () => '/nonexistent/cargo', + invokeCommand: () => { + let err = new Error('spawn /nonexistent/cargo ENOENT') + err.code = 'ENOENT' + throw err + } + } + }) + + expect(() => provider.provideStack('test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.toml')) + .to.throw('cargo binary is not accessible at "/nonexistent/cargo"') + }).timeout(10000) + + test('verify error when cargo metadata fails (e.g. invalid Cargo.toml)', async () => { + let provider = await esmock('../../src/providers/rust_cargo.js', { + '../../src/tools.js': { + getCustomPath: () => 'cargo', + invokeCommand: (bin, args) => { + if (args.includes('--version')) { + return 'cargo 1.75.0 (1d8b05cdd 2023-11-20)' + } + if (args.includes('metadata')) { + throw new Error('error: failed to parse manifest at `/fake/Cargo.toml`\n\nCaused by:\n missing field `name`') + } + return '' + } + } + }) + + expect(() => provider.provideStack('test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.toml')) + .to.throw('failed to execute cargo metadata') + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo ignore with underscore/hyphen normalization', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore' + + test('verify hyphenated ignore name matches underscored crate in stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + // Cargo.toml uses "serde-derive" (hyphen) but metadata reports "serde_derive" (underscore) + expect(sbom.components.find(c => c.name === 'serde_derive')).to.be.undefined + + // serde and tokio should still be present + expect(sbom.components.find(c => c.name === 'serde')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + }).timeout(10000) + + test('verify hyphenated ignore name matches underscored crate in component analysis', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + expect(sbom.components.find(c => c.name === 'serde_derive')).to.be.undefined + expect(sbom.components.find(c => c.name === 'serde')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo ignore annotations with trustify-da-ignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore' + + test('verify trustify-da-ignore dependency is excluded from stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + // serde is annotated with trustify-da-ignore and should not appear + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'serde_derive')).to.be.undefined + + // tokio should still be present + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + }).timeout(10000) + + test('verify trustify-da-ignore dependency is excluded from component analysis', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo ignore annotations with exhortignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore' + + test('verify exhortignore dependency is excluded from stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + // serde is annotated with exhortignore and should not appear + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'serde_derive')).to.be.undefined + + // tokio should still be present + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + }).timeout(10000) + + test('verify exhortignore dependency is excluded from component analysis', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo virtual workspace ignore with trustify-da-ignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore' + + test('verify sbom matches expected for stack analysis', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify sbom matches expected for component analysis', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) + + test('verify serde is excluded and tokio is present in stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'crate-a')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.not.be.undefined + }).timeout(10000) + + test('verify component analysis has no member deps (no [workspace.dependencies])', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + // No [workspace.dependencies] → CA returns only the synthetic root + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'crate-a')).to.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo virtual workspace ignore with exhortignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore' + + test('verify sbom matches expected for stack analysis', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify sbom matches expected for component analysis', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) + + test('verify serde is excluded and tokio is present in stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'crate-a')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.not.be.undefined + }).timeout(10000) + + test('verify component analysis has no member deps (no [workspace.dependencies])', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + // No [workspace.dependencies] → CA returns only the synthetic root + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'crate-a')).to.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo workspace with root ignore with trustify-da-ignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore' + + test('verify sbom matches expected for stack analysis', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify sbom matches expected for component analysis', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) + + test('verify serde is excluded and sub-crate not in graph in stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + // sub-crate is a workspace member but NOT in the root's dependency graph + expect(sbom.components.find(c => c.name === 'sub-crate')).to.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.be.undefined + }).timeout(10000) + + test('verify serde is excluded and sub-crate not in graph in component analysis', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'sub-crate')).to.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo virtual workspace with glob member patterns', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members' + + test('verify sbom matches expected for stack analysis', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify sbom matches expected for component analysis', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) + + test('verify serde is excluded via glob-resolved member ignore', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'crate-a')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.not.be.undefined + }).timeout(10000) + + test('verify component analysis has no member deps (no [workspace.dependencies])', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + // No [workspace.dependencies] → CA returns only the synthetic root + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'crate-a')).to.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo virtual workspace with [workspace.dependencies]', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps' + + test('verify sbom matches expected for stack analysis', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify sbom matches expected for component analysis', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) + + test('verify CA includes only [workspace.dependencies] entries', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + // serde and tokio are in [workspace.dependencies] → should be present + expect(sbom.components.find(c => c.name === 'serde')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + + // crate-a and crate-b are workspace members, not in [workspace.dependencies] + expect(sbom.components.find(c => c.name === 'crate-a')).to.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.be.undefined + + // pin-project-lite is transitive, should not appear in CA + expect(sbom.components.find(c => c.name === 'pin-project-lite')).to.be.undefined + }).timeout(10000) + + test('verify SA includes full member trees', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + expect(sbom.components.find(c => c.name === 'crate-a')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'crate-b')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'serde')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.not.be.undefined + expect(sbom.components.find(c => c.name === 'pin-project-lite')).to.not.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); + +suite('testing rust-cargo workspace with root ignore with exhortignore', () => { + const testDir = 'test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore' + + test('verify sbom matches expected for stack analysis', async () => { + await assertSbomMatchesExpected(testDir, 'stack') + }).timeout(10000) + + test('verify sbom matches expected for component analysis', async () => { + await assertSbomMatchesExpected(testDir, 'component') + }).timeout(10000) + + test('verify serde is excluded and sub-crate not in graph in stack analysis', async () => { + let sbom = await getParsedSbom(testDir, 'stack') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + // sub-crate is a workspace member but NOT in the root's dependency graph + expect(sbom.components.find(c => c.name === 'sub-crate')).to.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.be.undefined + }).timeout(10000) + + test('verify serde is excluded and sub-crate not in graph in component analysis', async () => { + let sbom = await getParsedSbom(testDir, 'component') + + expect(sbom.components.find(c => c.name === 'serde')).to.be.undefined + expect(sbom.components.find(c => c.name === 'sub-crate')).to.be.undefined + expect(sbom.components.find(c => c.name === 'tokio')).to.be.undefined + }).timeout(10000) +}).beforeAll(() => clock = useFakeTimers(new Date('2023-08-07T00:00:00.000Z'))).afterAll(() => clock.restore()); diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.toml new file mode 100644 index 00000000..c3206cfc --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "my-test-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" +tokio = { version = "1.35.0", features = ["full"] } + +[dev-dependencies] +tempfile = "3.8.0" diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/cargo_metadata.json new file mode 100644 index 00000000..1239801d --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/cargo_metadata.json @@ -0,0 +1,110 @@ +{ + "packages": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null }, + { "name": "tokio", "kind": null }, + { "name": "tempfile", "kind": "dev" } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "serde_derive", "kind": null } + ] + }, + { + "name": "serde_derive", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tempfile", + "version": "3.8.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/my-test-crate#0.1.0" + ], + "workspace_root": "/fake/path/my-test-crate", + "resolve": { + "root": "path+file:///fake/path/my-test-crate#0.1.0", + "nodes": [ + { + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "dep_kinds": [{ "kind": "dev", "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_component_analysis.json new file mode 100644 index 00000000..4fc7de2c --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_component_analysis.json @@ -0,0 +1,55 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + } + }, + "components": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + }, + { + "name": "serde", + "version": "1.0.193", + "purl": "pkg:cargo/serde@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde@1.0.193" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-test-crate@0.1.0", + "dependsOn": [ + "pkg:cargo/serde@1.0.193", + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/serde@1.0.193", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..3773710d --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_no_ignore/expected_sbom_stack_analysis.json @@ -0,0 +1,81 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + } + }, + "components": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + }, + { + "name": "serde", + "version": "1.0.193", + "purl": "pkg:cargo/serde@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde@1.0.193" + }, + { + "name": "serde_derive", + "version": "1.0.193", + "purl": "pkg:cargo/serde_derive@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde_derive@1.0.193" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-test-crate@0.1.0", + "dependsOn": [ + "pkg:cargo/serde@1.0.193", + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/serde@1.0.193", + "dependsOn": [ + "pkg:cargo/serde_derive@1.0.193" + ] + }, + { + "ref": "pkg:cargo/serde_derive@1.0.193", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.toml new file mode 100644 index 00000000..4799e2c4 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "my-test-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" # exhortignore +tokio = { version = "1.35.0", features = ["full"] } + +[dev-dependencies] +tempfile = "3.8.0" diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/cargo_metadata.json new file mode 100644 index 00000000..1239801d --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/cargo_metadata.json @@ -0,0 +1,110 @@ +{ + "packages": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null }, + { "name": "tokio", "kind": null }, + { "name": "tempfile", "kind": "dev" } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "serde_derive", "kind": null } + ] + }, + { + "name": "serde_derive", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tempfile", + "version": "3.8.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/my-test-crate#0.1.0" + ], + "workspace_root": "/fake/path/my-test-crate", + "resolve": { + "root": "path+file:///fake/path/my-test-crate#0.1.0", + "nodes": [ + { + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "dep_kinds": [{ "kind": "dev", "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_component_analysis.json new file mode 100644 index 00000000..1511cb4d --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_component_analysis.json @@ -0,0 +1,43 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + } + }, + "components": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-test-crate@0.1.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..289b00a7 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_exhortignore/expected_sbom_stack_analysis.json @@ -0,0 +1,56 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + } + }, + "components": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-test-crate@0.1.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.lock new file mode 100644 index 00000000..fdffa2a0 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.lock @@ -0,0 +1 @@ +# placeholder diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.toml new file mode 100644 index 00000000..a9c8050e --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "my-test-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" +tokio = { version = "1.35.0", features = ["full"] } + +[dependencies.serde-derive] # trustify-da-ignore +version = "1.0.193" + +[dev-dependencies] +tempfile = "3.8.0" diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/cargo_metadata.json new file mode 100644 index 00000000..476e04d5 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_hyphen_ignore/cargo_metadata.json @@ -0,0 +1,108 @@ +{ + "packages": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null }, + { "name": "serde_derive", "kind": null }, + { "name": "tokio", "kind": null }, + { "name": "tempfile", "kind": "dev" } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "serde_derive", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tempfile", + "version": "3.8.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/my-test-crate#0.1.0" + ], + "workspace_root": "/fake/path/my-test-crate", + "resolve": { + "root": "path+file:///fake/path/my-test-crate#0.1.0", + "nodes": [ + { + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "dep_kinds": [{ "kind": "dev", "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.toml new file mode 100644 index 00000000..54b20ca8 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "my-test-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" # trustify-da-ignore +tokio = { version = "1.35.0", features = ["full"] } + +[dev-dependencies] +tempfile = "3.8.0" diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/cargo_metadata.json new file mode 100644 index 00000000..1239801d --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/cargo_metadata.json @@ -0,0 +1,110 @@ +{ + "packages": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null }, + { "name": "tokio", "kind": null }, + { "name": "tempfile", "kind": "dev" } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "serde_derive", "kind": null } + ] + }, + { + "name": "serde_derive", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tempfile", + "version": "3.8.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/my-test-crate#0.1.0" + ], + "workspace_root": "/fake/path/my-test-crate", + "resolve": { + "root": "path+file:///fake/path/my-test-crate#0.1.0", + "nodes": [ + { + "id": "path+file:///fake/path/my-test-crate#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "dep_kinds": [{ "kind": "dev", "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_component_analysis.json new file mode 100644 index 00000000..1511cb4d --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_component_analysis.json @@ -0,0 +1,43 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + } + }, + "components": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-test-crate@0.1.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..289b00a7 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_single_crate_with_ignore/expected_sbom_stack_analysis.json @@ -0,0 +1,56 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + } + }, + "components": [ + { + "name": "my-test-crate", + "version": "0.1.0", + "purl": "pkg:cargo/my-test-crate@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-test-crate@0.1.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-test-crate@0.1.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.toml new file mode 100644 index 00000000..76c52381 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = [ + "crate-a", + "crate-b", +] +resolver = "2" diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/cargo_metadata.json new file mode 100644 index 00000000..7e520d60 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/cargo_metadata.json @@ -0,0 +1,90 @@ +{ + "packages": [ + { + "name": "crate-a", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_virtual_workspace/crate-a#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null } + ] + }, + { + "name": "crate-b", + "version": "0.2.0", + "id": "path+file:///fake/path/cargo_virtual_workspace/crate-b#0.2.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_virtual_workspace/crate-a#0.1.0", + "path+file:///fake/path/cargo_virtual_workspace/crate-b#0.2.0" + ], + "workspace_root": "/fake/path/cargo_virtual_workspace", + "resolve": { + "root": null, + "nodes": [ + { + "id": "path+file:///fake/path/cargo_virtual_workspace/crate-a#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_virtual_workspace/crate-b#0.2.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-a/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-a/Cargo.toml new file mode 100644 index 00000000..4c79e6eb --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-a/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-a" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-b/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-b/Cargo.toml new file mode 100644 index 00000000..8974ad47 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/crate-b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-b" +version = "0.2.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.0", features = ["full"] } diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_component_analysis.json new file mode 100644 index 00000000..78d8b1a6 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_component_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace@0.0.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..b97922ad --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json @@ -0,0 +1,94 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace@0.0.0" + }, + { + "name": "crate-a", + "version": "0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-a@0.1.0" + }, + { + "name": "serde", + "version": "1.0.193", + "purl": "pkg:cargo/serde@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde@1.0.193" + }, + { + "name": "crate-b", + "version": "0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-b@0.2.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/cargo_virtual_workspace@0.0.0", + "dependsOn": [ + "pkg:cargo/crate-a@0.1.0", + "pkg:cargo/crate-b@0.2.0" + ] + }, + { + "ref": "pkg:cargo/crate-a@0.1.0", + "dependsOn": [ + "pkg:cargo/serde@1.0.193" + ] + }, + { + "ref": "pkg:cargo/serde@1.0.193", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/crate-b@0.2.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.lock new file mode 100644 index 00000000..fdffa2a0 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.lock @@ -0,0 +1 @@ +# placeholder diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.toml new file mode 100644 index 00000000..a7cff588 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = [ + "crates/*", +] +resolver = "2" diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/cargo_metadata.json new file mode 100644 index 00000000..4a07cedb --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/cargo_metadata.json @@ -0,0 +1,90 @@ +{ + "packages": [ + { + "name": "crate-a", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_glob_members/crates/crate-a#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null } + ] + }, + { + "name": "crate-b", + "version": "0.2.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_glob_members/crates/crate-b#0.2.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_virtual_workspace_glob_members/crates/crate-a#0.1.0", + "path+file:///fake/path/cargo_virtual_workspace_glob_members/crates/crate-b#0.2.0" + ], + "workspace_root": "/fake/path/cargo_virtual_workspace_glob_members", + "resolve": { + "root": null, + "nodes": [ + { + "id": "path+file:///fake/path/cargo_virtual_workspace_glob_members/crates/crate-a#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_virtual_workspace_glob_members/crates/crate-b#0.2.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-a/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-a/Cargo.toml new file mode 100644 index 00000000..226e8c62 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-a/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-a" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" # trustify-da-ignore diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-b/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-b/Cargo.toml new file mode 100644 index 00000000..8974ad47 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/crates/crate-b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-b" +version = "0.2.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.0", features = ["full"] } diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_component_analysis.json new file mode 100644 index 00000000..8fa1c7a5 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_component_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_glob_members", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_glob_members", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..58357615 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json @@ -0,0 +1,81 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_glob_members", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_glob_members", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0" + }, + { + "name": "crate-a", + "version": "0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-a@0.1.0" + }, + { + "name": "crate-b", + "version": "0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-b@0.2.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0", + "dependsOn": [ + "pkg:cargo/crate-a@0.1.0", + "pkg:cargo/crate-b@0.2.0" + ] + }, + { + "ref": "pkg:cargo/crate-a@0.1.0", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/crate-b@0.2.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.toml new file mode 100644 index 00000000..76c52381 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = [ + "crate-a", + "crate-b", +] +resolver = "2" diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/cargo_metadata.json new file mode 100644 index 00000000..71d02678 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/cargo_metadata.json @@ -0,0 +1,90 @@ +{ + "packages": [ + { + "name": "crate-a", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_with_exhortignore/crate-a#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null } + ] + }, + { + "name": "crate-b", + "version": "0.2.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_with_exhortignore/crate-b#0.2.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_virtual_workspace_with_exhortignore/crate-a#0.1.0", + "path+file:///fake/path/cargo_virtual_workspace_with_exhortignore/crate-b#0.2.0" + ], + "workspace_root": "/fake/path/cargo_virtual_workspace_with_exhortignore", + "resolve": { + "root": null, + "nodes": [ + { + "id": "path+file:///fake/path/cargo_virtual_workspace_with_exhortignore/crate-a#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_virtual_workspace_with_exhortignore/crate-b#0.2.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-a/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-a/Cargo.toml new file mode 100644 index 00000000..aad0c0e0 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-a/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-a" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" # exhortignore diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-b/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-b/Cargo.toml new file mode 100644 index 00000000..8974ad47 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/crate-b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-b" +version = "0.2.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.0", features = ["full"] } diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_component_analysis.json new file mode 100644 index 00000000..e61b9b94 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_component_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_with_exhortignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_with_exhortignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..f4454239 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json @@ -0,0 +1,81 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_with_exhortignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_with_exhortignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0" + }, + { + "name": "crate-a", + "version": "0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-a@0.1.0" + }, + { + "name": "crate-b", + "version": "0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-b@0.2.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0", + "dependsOn": [ + "pkg:cargo/crate-a@0.1.0", + "pkg:cargo/crate-b@0.2.0" + ] + }, + { + "ref": "pkg:cargo/crate-a@0.1.0", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/crate-b@0.2.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.toml new file mode 100644 index 00000000..76c52381 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = [ + "crate-a", + "crate-b", +] +resolver = "2" diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/cargo_metadata.json new file mode 100644 index 00000000..25957c60 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/cargo_metadata.json @@ -0,0 +1,90 @@ +{ + "packages": [ + { + "name": "crate-a", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_with_ignore/crate-a#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null } + ] + }, + { + "name": "crate-b", + "version": "0.2.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_with_ignore/crate-b#0.2.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_virtual_workspace_with_ignore/crate-a#0.1.0", + "path+file:///fake/path/cargo_virtual_workspace_with_ignore/crate-b#0.2.0" + ], + "workspace_root": "/fake/path/cargo_virtual_workspace_with_ignore", + "resolve": { + "root": null, + "nodes": [ + { + "id": "path+file:///fake/path/cargo_virtual_workspace_with_ignore/crate-a#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_virtual_workspace_with_ignore/crate-b#0.2.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-a/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-a/Cargo.toml new file mode 100644 index 00000000..226e8c62 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-a/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-a" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = "1.0.193" # trustify-da-ignore diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-b/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-b/Cargo.toml new file mode 100644 index 00000000..8974ad47 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/crate-b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "crate-b" +version = "0.2.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.0", features = ["full"] } diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_component_analysis.json new file mode 100644 index 00000000..79032065 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_component_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_with_ignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_with_ignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..c1bab0b4 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json @@ -0,0 +1,81 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_with_ignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_with_ignore", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0" + }, + { + "name": "crate-a", + "version": "0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-a@0.1.0" + }, + { + "name": "crate-b", + "version": "0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-b@0.2.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0", + "dependsOn": [ + "pkg:cargo/crate-a@0.1.0", + "pkg:cargo/crate-b@0.2.0" + ] + }, + { + "ref": "pkg:cargo/crate-a@0.1.0", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/crate-b@0.2.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.lock new file mode 100644 index 00000000..fdffa2a0 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.lock @@ -0,0 +1 @@ +# placeholder diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.toml new file mode 100644 index 00000000..144ece21 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +members = [ + "crate-a", + "crate-b", +] +resolver = "2" + +[workspace.dependencies] +serde = "1.0.193" +tokio = { version = "1.35.0", features = ["full"] } diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/cargo_metadata.json new file mode 100644 index 00000000..5adcdd56 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/cargo_metadata.json @@ -0,0 +1,90 @@ +{ + "packages": [ + { + "name": "crate-a", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_with_workspace_deps/crate-a#0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null } + ] + }, + { + "name": "crate-b", + "version": "0.2.0", + "id": "path+file:///fake/path/cargo_virtual_workspace_with_workspace_deps/crate-b#0.2.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_virtual_workspace_with_workspace_deps/crate-a#0.1.0", + "path+file:///fake/path/cargo_virtual_workspace_with_workspace_deps/crate-b#0.2.0" + ], + "workspace_root": "/fake/path/cargo_virtual_workspace_with_workspace_deps", + "resolve": { + "root": null, + "nodes": [ + { + "id": "path+file:///fake/path/cargo_virtual_workspace_with_workspace_deps/crate-a#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_virtual_workspace_with_workspace_deps/crate-b#0.2.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_component_analysis.json new file mode 100644 index 00000000..86799afa --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_component_analysis.json @@ -0,0 +1,55 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_with_workspace_deps", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_with_workspace_deps", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0" + }, + { + "name": "serde", + "version": "1.0.193", + "purl": "pkg:cargo/serde@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde@1.0.193" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0", + "dependsOn": [ + "pkg:cargo/serde@1.0.193", + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/serde@1.0.193", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..0bcfbf08 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json @@ -0,0 +1,94 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "cargo_virtual_workspace_with_workspace_deps", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0" + } + }, + "components": [ + { + "name": "cargo_virtual_workspace_with_workspace_deps", + "version": "0.0.0", + "purl": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0", + "type": "application", + "bom-ref": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0" + }, + { + "name": "crate-a", + "version": "0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-a@0.1.0" + }, + { + "name": "serde", + "version": "1.0.193", + "purl": "pkg:cargo/serde@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde@1.0.193" + }, + { + "name": "crate-b", + "version": "0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0", + "type": "library", + "bom-ref": "pkg:cargo/crate-b@0.2.0" + }, + { + "name": "tokio", + "version": "1.35.0", + "purl": "pkg:cargo/tokio@1.35.0", + "type": "library", + "bom-ref": "pkg:cargo/tokio@1.35.0" + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "purl": "pkg:cargo/pin-project-lite@0.2.13", + "type": "library", + "bom-ref": "pkg:cargo/pin-project-lite@0.2.13" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0", + "dependsOn": [ + "pkg:cargo/crate-a@0.1.0", + "pkg:cargo/crate-b@0.2.0" + ] + }, + { + "ref": "pkg:cargo/crate-a@0.1.0", + "dependsOn": [ + "pkg:cargo/serde@1.0.193" + ] + }, + { + "ref": "pkg:cargo/serde@1.0.193", + "dependsOn": [] + }, + { + "ref": "pkg:cargo/crate-b@0.2.0", + "dependsOn": [ + "pkg:cargo/tokio@1.35.0" + ] + }, + { + "ref": "pkg:cargo/tokio@1.35.0", + "dependsOn": [ + "pkg:cargo/pin-project-lite@0.2.13" + ] + }, + { + "ref": "pkg:cargo/pin-project-lite@0.2.13", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.toml new file mode 100644 index 00000000..b740cbb4 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "my-workspace-root" +version = "0.1.0" +edition = "2021" + +[workspace] +members = [ + "sub-crate", +] +resolver = "2" + +[dependencies] +serde = "1.0.193" + +[dev-dependencies] +tempfile = "3.8.0" diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/cargo_metadata.json new file mode 100644 index 00000000..ccd5d651 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/cargo_metadata.json @@ -0,0 +1,106 @@ +{ + "packages": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null }, + { "name": "tempfile", "kind": "dev" } + ] + }, + { + "name": "sub-crate", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tempfile", + "version": "3.8.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0" + ], + "workspace_root": "/fake/path/cargo_workspace_with_root", + "resolve": { + "root": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "nodes": [ + { + "id": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "dep_kinds": [{ "kind": "dev", "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_component_analysis.json new file mode 100644 index 00000000..b6fd4381 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_component_analysis.json @@ -0,0 +1,43 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + }, + "components": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + }, + { + "name": "serde", + "version": "1.0.193", + "purl": "pkg:cargo/serde@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde@1.0.193" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-workspace-root@0.1.0", + "dependsOn": [ + "pkg:cargo/serde@1.0.193" + ] + }, + { + "ref": "pkg:cargo/serde@1.0.193", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..b6fd4381 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/expected_sbom_stack_analysis.json @@ -0,0 +1,43 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + }, + "components": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + }, + { + "name": "serde", + "version": "1.0.193", + "purl": "pkg:cargo/serde@1.0.193", + "type": "library", + "bom-ref": "pkg:cargo/serde@1.0.193" + } + ], + "dependencies": [ + { + "ref": "pkg:cargo/my-workspace-root@0.1.0", + "dependsOn": [ + "pkg:cargo/serde@1.0.193" + ] + }, + { + "ref": "pkg:cargo/serde@1.0.193", + "dependsOn": [] + } + ] +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root/sub-crate/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/sub-crate/Cargo.toml new file mode 100644 index 00000000..2ffba0bf --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root/sub-crate/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "sub-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.0", features = ["full"] } diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.toml new file mode 100644 index 00000000..d206dacc --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "my-workspace-root" +version = "0.1.0" +edition = "2021" + +[workspace] +members = [ + "sub-crate", +] +resolver = "2" + +[dependencies] +serde = "1.0.193" # exhortignore + +[dev-dependencies] +tempfile = "3.8.0" diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/cargo_metadata.json new file mode 100644 index 00000000..ccd5d651 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/cargo_metadata.json @@ -0,0 +1,106 @@ +{ + "packages": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null }, + { "name": "tempfile", "kind": "dev" } + ] + }, + { + "name": "sub-crate", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tempfile", + "version": "3.8.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0" + ], + "workspace_root": "/fake/path/cargo_workspace_with_root", + "resolve": { + "root": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "nodes": [ + { + "id": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "dep_kinds": [{ "kind": "dev", "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_component_analysis.json new file mode 100644 index 00000000..d28a4508 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_component_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + }, + "components": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..d28a4508 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/expected_sbom_stack_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + }, + "components": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/sub-crate/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/sub-crate/Cargo.toml new file mode 100644 index 00000000..2ffba0bf --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_exhortignore/sub-crate/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "sub-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.0", features = ["full"] } diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.lock b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.lock new file mode 100644 index 00000000..1fcedc5a --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.lock @@ -0,0 +1,2 @@ +# This file is a placeholder for lock file validation. +# The actual dependency resolution is done by `cargo metadata`. diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.toml new file mode 100644 index 00000000..b744b480 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "my-workspace-root" +version = "0.1.0" +edition = "2021" + +[workspace] +members = [ + "sub-crate", +] +resolver = "2" + +[dependencies] +serde = "1.0.193" # trustify-da-ignore + +[dev-dependencies] +tempfile = "3.8.0" diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/cargo_metadata.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/cargo_metadata.json new file mode 100644 index 00000000..ccd5d651 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/cargo_metadata.json @@ -0,0 +1,106 @@ +{ + "packages": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "source": null, + "dependencies": [ + { "name": "serde", "kind": null }, + { "name": "tempfile", "kind": "dev" } + ] + }, + { + "name": "sub-crate", + "version": "0.1.0", + "id": "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0", + "source": null, + "dependencies": [ + { "name": "tokio", "kind": null } + ] + }, + { + "name": "serde", + "version": "1.0.193", + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tokio", + "version": "1.35.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { "name": "pin-project-lite", "kind": null } + ] + }, + { + "name": "pin-project-lite", + "version": "0.2.13", + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + }, + { + "name": "tempfile", + "version": "3.8.0", + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [] + } + ], + "workspace_members": [ + "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0" + ], + "workspace_root": "/fake/path/cargo_workspace_with_root", + "resolve": { + "root": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "nodes": [ + { + "id": "path+file:///fake/path/cargo_workspace_with_root#my-workspace-root@0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "dep_kinds": [{ "kind": null, "target": null }] + }, + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "dep_kinds": [{ "kind": "dev", "target": null }] + } + ] + }, + { + "id": "path+file:///fake/path/cargo_workspace_with_root/sub-crate#0.1.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.193", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.35.0", + "deps": [ + { + "pkg": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "dep_kinds": [{ "kind": null, "target": null }] + } + ] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.13", + "deps": [] + }, + { + "id": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.8.0", + "deps": [] + } + ] + } +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_component_analysis.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_component_analysis.json new file mode 100644 index 00000000..d28a4508 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_component_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + }, + "components": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_stack_analysis.json new file mode 100644 index 00000000..d28a4508 --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/expected_sbom_stack_analysis.json @@ -0,0 +1,25 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "version": 1, + "metadata": { + "timestamp": "2023-08-07T00:00:00.000Z", + "component": { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + }, + "components": [ + { + "name": "my-workspace-root", + "version": "0.1.0", + "purl": "pkg:cargo/my-workspace-root@0.1.0", + "type": "application", + "bom-ref": "pkg:cargo/my-workspace-root@0.1.0" + } + ], + "dependencies": [] +} diff --git a/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/sub-crate/Cargo.toml b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/sub-crate/Cargo.toml new file mode 100644 index 00000000..2ffba0bf --- /dev/null +++ b/test/providers/tst_manifests/cargo/cargo_workspace_with_root_ignore/sub-crate/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "sub-crate" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.0", features = ["full"] } From 7b4f376f60072f4d6fa07fd016767d7e6b7e33aa Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Sun, 15 Mar 2026 11:41:28 +0200 Subject: [PATCH 2/7] fix: use a proper toml parser --- package-lock.json | 13 ++++++++ package.json | 1 + src/providers/rust_cargo.js | 61 +++++++------------------------------ 3 files changed, 25 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 64468568..9b3cef0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "https-proxy-agent": "^7.0.6", "node-fetch": "^3.3.2", "packageurl-js": "~1.0.2", + "smol-toml": "^1.6.0", "tree-sitter-requirements": "github:Strum355/tree-sitter-requirements#d0261ee76b84253997fe70d7d397e78c006c3801", "web-tree-sitter": "^0.26.6", "yargs": "^18.0.0" @@ -6878,6 +6879,18 @@ "npm": ">= 3.0.0" } }, + "node_modules/smol-toml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz", + "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, "node_modules/smtp-address-parser": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/smtp-address-parser/-/smtp-address-parser-1.1.0.tgz", diff --git a/package.json b/package.json index 92b6e144..31d072fd 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "https-proxy-agent": "^7.0.6", "node-fetch": "^3.3.2", "packageurl-js": "~1.0.2", + "smol-toml": "^1.6.0", "tree-sitter-requirements": "github:Strum355/tree-sitter-requirements#d0261ee76b84253997fe70d7d397e78c006c3801", "web-tree-sitter": "^0.26.6", "yargs": "^18.0.0" diff --git a/src/providers/rust_cargo.js b/src/providers/rust_cargo.js index 80cf798c..378a1838 100644 --- a/src/providers/rust_cargo.js +++ b/src/providers/rust_cargo.js @@ -2,6 +2,7 @@ import fs from 'node:fs' import path from 'node:path' import { PackageURL } from 'packageurl-js' +import { parse as parseToml } from 'smol-toml' import { getLicense } from '../license/license_utils.js' import Sbom from '../sbom.js' @@ -83,26 +84,11 @@ function readLicenseFromManifest(manifestPath) { let fromManifest = null try { let content = fs.readFileSync(manifestPath, 'utf-8') - let lines = content.split(/\r?\n/) - let currentSection = '' + let parsed = parseToml(content) - for (let line of lines) { - let trimmed = line.trim() - - let sectionMatch = trimmed.match(/^\[([^\]]+)\]\s*(?:#.*)?$/) - if (sectionMatch) { - currentSection = sectionMatch[1] - continue - } - - if (currentSection === 'package' || currentSection === 'workspace.package') { - let licenseMatch = trimmed.match(/^license\s*=\s*"([^"]+)"/) - if (licenseMatch) { - fromManifest = licenseMatch[1].trim() - break - } - } - } + fromManifest = parsed.package?.license + || parsed.workspace?.package?.license + || null } catch (_) { // leave fromManifest as null } @@ -504,35 +490,13 @@ function findResolveNode(metadata, packageId) { * @private */ function getWorkspaceDepsFromManifest(manifest) { - let content try { - content = fs.readFileSync(manifest, 'utf-8') + let content = fs.readFileSync(manifest, 'utf-8') + let parsed = parseToml(content) + return Object.keys(parsed.workspace?.dependencies || {}) } catch (_) { return [] } - - let lines = content.split(/\r?\n/) - let inSection = false - let names = [] - - for (let line of lines) { - let trimmed = line.trim() - - let sectionMatch = trimmed.match(/^\[([^\]]+)\]\s*(?:#.*)?$/) - if (sectionMatch) { - inSection = sectionMatch[1] === 'workspace.dependencies' - continue - } - - if (inSection) { - let nameMatch = trimmed.match(/^([a-zA-Z0-9_-]+)\s*=/) - if (nameMatch) { - names.push(nameMatch[1]) - } - } - } - - return names } /** @@ -546,14 +510,11 @@ function getWorkspaceVersion(metadata) { let cargoTomlPath = path.join(workspaceRoot, 'Cargo.toml') try { let content = fs.readFileSync(cargoTomlPath, 'utf-8') - let versionMatch = content.match(/\[workspace\.package\][\s\S]*?version\s*=\s*"([^"]+)"/) - if (versionMatch) { - return versionMatch[1] - } + let parsed = parseToml(content) + return parsed.workspace?.package?.version || '0.0.0' } catch (_) { - // fall through to default + return '0.0.0' } - return '0.0.0' } /** From 80c7920d48551050cfb9313df147c9844936dd46 Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Sun, 15 Mar 2026 12:04:28 +0200 Subject: [PATCH 3/7] fix: remove duplicate functions --- src/providers/rust_cargo.js | 46 ++++--------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/src/providers/rust_cargo.js b/src/providers/rust_cargo.js index 378a1838..a05ba943 100644 --- a/src/providers/rust_cargo.js +++ b/src/providers/rust_cargo.js @@ -185,8 +185,6 @@ function getSBOM(manifest, opts = {}, includeTransitive) { let sbom if (crateType === CrateType.WORKSPACE_VIRTUAL) { sbom = handleVirtualWorkspace(manifest, metadata, ignoredDeps, includeTransitive, opts, license) - } else if (crateType === CrateType.WORKSPACE_WITH_ROOT_CRATE) { - sbom = handleWorkspaceWithRoot(metadata, ignoredDeps, includeTransitive, opts, license) } else { sbom = handleSingleCrate(metadata, ignoredDeps, includeTransitive, opts, license) } @@ -250,7 +248,11 @@ function detectCrateType(metadata) { } /** - * Handles SBOM generation for single crate projects (no workspace members beyond the root). + * Handles SBOM generation for single crate and workspace-with-root-crate projects. + * For workspace-with-root-crate, workspace members are only included if they + * appear in the root crate's dependency graph from cargo metadata. We don't + * automatically add all members as dependencies since most workspace members + * (examples, tools, benchmarks) depend ON the root crate, not the other way around. * @param {object} metadata - parsed cargo metadata * @param {Set} ignoredDeps - set of ignored dependency names * @param {boolean} includeTransitive - whether to include transitive dependencies @@ -281,44 +283,6 @@ function handleSingleCrate(metadata, ignoredDeps, includeTransitive, opts, licen return sbom.getAsJsonString(opts) } -/** - * Handles SBOM generation for workspace-with-root-crate projects. - * Processes root crate dependencies — this naturally includes any workspace - * members that are actual dependencies via the cargo dependency graph. - * Workspace members are only included if they appear in the root crate's - * dependency graph from cargo metadata. We don't automatically add all - * members as dependencies since most workspace members (examples, tools, - * benchmarks) depend ON the root crate, not the other way around. - * @param {object} metadata - parsed cargo metadata - * @param {Set} ignoredDeps - set of ignored dependency names - * @param {boolean} includeTransitive - whether to include transitive dependencies - * @param {{}} opts - options - * @param {string|null} license - SPDX license identifier for the root component - * @returns {string} SBOM json string - * @private - */ -function handleWorkspaceWithRoot(metadata, ignoredDeps, includeTransitive, opts, license) { - let rootPackageId = metadata.resolve.root - let rootPackage = findPackageById(metadata, rootPackageId) - let rootPurl = toPurl(rootPackage.name, rootPackage.version) - - let sbom = new Sbom() - sbom.addRoot(rootPurl, license) - - let resolveNode = findResolveNode(metadata, rootPackageId) - if (!resolveNode) { - return sbom.getAsJsonString(opts) - } - - if (includeTransitive) { - addTransitiveDeps(sbom, metadata, rootPackageId, ignoredDeps, new Set()) - } else { - addDirectDeps(sbom, metadata, rootPackageId, rootPurl, ignoredDeps) - } - - return sbom.getAsJsonString(opts) -} - /** * Handles SBOM generation for virtual workspace projects. * From 067ee97f72a95c2c3581b795659b664f1346593b Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Mon, 16 Mar 2026 13:38:27 +0200 Subject: [PATCH 4/7] fix: update after review --- src/providers/rust_cargo.js | 17 +- .../package-lock.json | 814 +++++++++++++++++- 2 files changed, 798 insertions(+), 33 deletions(-) diff --git a/src/providers/rust_cargo.js b/src/providers/rust_cargo.js index a05ba943..035a8711 100644 --- a/src/providers/rust_cargo.js +++ b/src/providers/rust_cargo.js @@ -375,6 +375,12 @@ function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited) { if (!depPackage) {continue} if (isDepIgnored(depPackage.name, ignoredDeps)) {continue} + if (depPackage.source == null) { + // Path dependency — don't add to SBOM, but still walk its deps + addTransitiveDeps(sbom, metadata, depId, ignoredDeps, visited) + continue + } + let depPurl = toPurl(depPackage.name, depPackage.version) sbom.addDependency(sourcePurl, depPurl) addTransitiveDeps(sbom, metadata, depId, ignoredDeps, visited) @@ -400,6 +406,7 @@ function addDirectDeps(sbom, metadata, packageId, parentPurl, ignoredDeps) { let depPackage = findPackageById(metadata, depId) if (!depPackage) {continue} if (isDepIgnored(depPackage.name, ignoredDeps)) {continue} + if (depPackage.source == null) {continue} let depPurl = toPurl(depPackage.name, depPackage.version) sbom.addDependency(parentPurl, depPurl) @@ -454,13 +461,9 @@ function findResolveNode(metadata, packageId) { * @private */ function getWorkspaceDepsFromManifest(manifest) { - try { - let content = fs.readFileSync(manifest, 'utf-8') - let parsed = parseToml(content) - return Object.keys(parsed.workspace?.dependencies || {}) - } catch (_) { - return [] - } + let content = fs.readFileSync(manifest, 'utf-8') + let parsed = parseToml(content) + return Object.keys(parsed.workspace?.dependencies || {}) } /** diff --git a/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json b/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json index 869eddb4..c33f65e2 100644 --- a/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json +++ b/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json @@ -15,6 +15,7 @@ "bcryptjs": "^2.4.3", "dotenv": "^8.2.0", "express": "^4.17.1", + "jsdom": "^19.0.0", "jsonwebtoken": "^8.5.1", "mongoose": "^5.9.18", "nodemon": "^2.0.4" @@ -66,6 +67,15 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/@types/bson": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", @@ -88,6 +98,13 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.8.tgz", "integrity": "sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==" }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "license": "BSD-3-Clause" + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -105,6 +122,84 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -122,6 +217,12 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/axios": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", @@ -211,6 +312,12 @@ "node": ">=8" } }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "license": "BSD-2-Clause" + }, "node_modules/bson": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", @@ -244,6 +351,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -270,6 +390,18 @@ "fsevents": "~2.3.2" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -312,6 +444,57 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -320,6 +503,21 @@ "ms": "2.0.0" } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/denque": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", @@ -345,6 +543,19 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "license": "MIT", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/dotenv": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", @@ -353,6 +564,20 @@ "node": ">=10" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -374,11 +599,108 @@ "node": ">= 0.8" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -475,6 +797,22 @@ "ms": "2.0.0" } }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -505,24 +843,51 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -534,15 +899,16 @@ "node": ">= 6" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", "engines": { - "node": ">= 0.4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { @@ -553,10 +919,11 @@ "node": ">=4" } }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -564,10 +931,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { "node": ">= 0.4" }, @@ -575,6 +946,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -590,6 +985,79 @@ "node": ">= 0.8" } }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -657,11 +1125,63 @@ "node": ">=0.12.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, + "node_modules/jsdom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-19.0.0.tgz", + "integrity": "sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.5.0", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.1", + "decimal.js": "^10.3.1", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^10.0.0", + "ws": "^8.2.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -747,6 +1267,15 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1016,6 +1545,12 @@ "node": ">=0.10.0" } }, + "node_modules/nwsapi": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "license": "MIT" + }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -1043,6 +1578,12 @@ "node": ">=4" } }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1084,11 +1625,32 @@ "node": ">= 0.10" } }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1103,6 +1665,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1168,6 +1736,12 @@ "node": ">=4" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1204,6 +1778,18 @@ "node": ">=6" } }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -1301,6 +1887,16 @@ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -1342,6 +1938,12 @@ "node": ">=4" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1372,6 +1974,33 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1389,6 +2018,15 @@ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1397,6 +2035,16 @@ "node": ">= 0.8" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1417,6 +2065,120 @@ "engines": { "node": ">= 0.8" } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "license": "MIT", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", + "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==", + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" } } } From 1afda20a6b619d690c8999ec712997a9f5b96d96 Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Mon, 16 Mar 2026 13:53:30 +0200 Subject: [PATCH 5/7] fix: revert accidental changes to package-lock.json --- .../package-lock.json | 814 +----------------- 1 file changed, 26 insertions(+), 788 deletions(-) diff --git a/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json b/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json index c33f65e2..869eddb4 100644 --- a/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json +++ b/test/providers/tst_manifests/npm/package_json_deps_without_exhortignore_object/package-lock.json @@ -15,7 +15,6 @@ "bcryptjs": "^2.4.3", "dotenv": "^8.2.0", "express": "^4.17.1", - "jsdom": "^19.0.0", "jsonwebtoken": "^8.5.1", "mongoose": "^5.9.18", "nodemon": "^2.0.4" @@ -67,15 +66,6 @@ "@hapi/hoek": "^9.0.0" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, "node_modules/@types/bson": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", @@ -98,13 +88,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.8.tgz", "integrity": "sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==" }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead", - "license": "BSD-3-Clause" - }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -122,84 +105,6 @@ "node": ">= 0.6" } }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -217,12 +122,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, "node_modules/axios": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", @@ -312,12 +211,6 @@ "node": ">=8" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "license": "BSD-2-Clause" - }, "node_modules/bson": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", @@ -351,19 +244,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -390,18 +270,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -444,57 +312,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, - "node_modules/cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "license": "MIT" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "license": "MIT", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "license": "MIT" - }, - "node_modules/data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "license": "MIT", - "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "license": "MIT", - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -503,21 +320,6 @@ "ms": "2.0.0" } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "license": "MIT" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/denque": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", @@ -543,19 +345,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "deprecated": "Use your platform's native DOMException instead", - "license": "MIT", - "dependencies": { - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/dotenv": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", @@ -564,20 +353,6 @@ "node": ">=10" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -599,108 +374,11 @@ "node": ">= 0.8" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -797,22 +475,6 @@ "ms": "2.0.0" } }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -843,51 +505,24 @@ } }, "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -899,16 +534,15 @@ "node": ">= 6" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.4.0" } }, "node_modules/has-flag": { @@ -919,11 +553,10 @@ "node": ">=4" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "engines": { "node": ">= 0.4" }, @@ -931,14 +564,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -946,30 +575,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -985,79 +590,6 @@ "node": ">= 0.8" } }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1125,63 +657,11 @@ "node": ">=0.12.0" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "license": "MIT" - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, - "node_modules/jsdom": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-19.0.0.tgz", - "integrity": "sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==", - "license": "MIT", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.5.0", - "acorn-globals": "^6.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.1", - "decimal.js": "^10.3.1", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^3.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^10.0.0", - "ws": "^8.2.3", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, "node_modules/jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -1267,15 +747,6 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1545,12 +1016,6 @@ "node": ">=0.10.0" } }, - "node_modules/nwsapi": { - "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", - "license": "MIT" - }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -1578,12 +1043,6 @@ "node": ">=4" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "license": "MIT" - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1625,32 +1084,11 @@ "node": ">= 0.10" } }, - "node_modules/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } - }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1665,12 +1103,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "license": "MIT" - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1736,12 +1168,6 @@ "node": ">=4" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1778,18 +1204,6 @@ "node": ">=6" } }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -1887,16 +1301,6 @@ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -1938,12 +1342,6 @@ "node": ">=4" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "license": "MIT" - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1974,33 +1372,6 @@ "nodetouch": "bin/nodetouch.js" } }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -2018,15 +1389,6 @@ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -2035,16 +1397,6 @@ "node": ">= 0.8" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2065,120 +1417,6 @@ "engines": { "node": ">= 0.8" } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", - "license": "MIT", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", - "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", - "license": "MIT", - "dependencies": { - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-url": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz", - "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==", - "license": "MIT", - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "license": "Apache-2.0", - "engines": { - "node": ">=12" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "license": "MIT" } } } From ef2ab377e5e9957a2f7b5bd5d4313e67b2a0b668 Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Tue, 17 Mar 2026 10:48:14 +0200 Subject: [PATCH 6/7] fix: broken sboms --- src/providers/rust_cargo.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/providers/rust_cargo.js b/src/providers/rust_cargo.js index 035a8711..19a8a1d8 100644 --- a/src/providers/rust_cargo.js +++ b/src/providers/rust_cargo.js @@ -350,14 +350,19 @@ function handleVirtualWorkspace(manifest, metadata, ignoredDeps, includeTransiti /** * Recursively adds transitive dependencies to the SBOM. + * Path dependencies (source == null) are not added to the SBOM, but their + * subtrees are still walked. Any registry dependencies found under a path + * dep are attached to the nearest non-path ancestor via {@link effectiveParentPurl}. * @param {Sbom} sbom - the SBOM to add dependencies to * @param {object} metadata - parsed cargo metadata * @param {string} packageId - the package ID to resolve dependencies for * @param {Set} ignoredDeps - set of ignored dependency names * @param {Set} visited - set of already-visited package IDs to prevent cycles + * @param {PackageURL} [effectiveParentPurl] - when walking through a path dep, + * the purl of the nearest registry ancestor to attach discovered deps to * @private */ -function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited) { +function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited, effectiveParentPurl) { if (visited.has(packageId)) {return} visited.add(packageId) @@ -366,7 +371,12 @@ function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited) { let sourcePackage = findPackageById(metadata, packageId) if (!sourcePackage) {return} - let sourcePurl = toPurl(sourcePackage.name, sourcePackage.version) + + // For path deps use the effective parent purl so their children attach + // to the nearest real (registry) ancestor in the SBOM. + let sourcePurl = (sourcePackage.source == null && effectiveParentPurl) + ? effectiveParentPurl + : toPurl(sourcePackage.name, sourcePackage.version) let runtimeDeps = filterRuntimeDeps(resolveNode) @@ -376,8 +386,9 @@ function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited) { if (isDepIgnored(depPackage.name, ignoredDeps)) {continue} if (depPackage.source == null) { - // Path dependency — don't add to SBOM, but still walk its deps - addTransitiveDeps(sbom, metadata, depId, ignoredDeps, visited) + // Path dependency — don't add to SBOM, but walk its deps + // passing our sourcePurl so its children attach correctly + addTransitiveDeps(sbom, metadata, depId, ignoredDeps, visited, sourcePurl) continue } From e570866ad2274d1ec13a2836a733ece0d49b66f3 Mon Sep 17 00:00:00 2001 From: Adva Oren Date: Wed, 18 Mar 2026 13:22:57 +0200 Subject: [PATCH 7/7] feat: include path dependencies in SBOM with repository_url=local qualifier --- src/providers/rust_cargo.js | 68 ++++++++++++------- .../expected_sbom_stack_analysis.json | 16 ++--- .../expected_sbom_stack_analysis.json | 16 ++--- .../expected_sbom_stack_analysis.json | 16 ++--- .../expected_sbom_stack_analysis.json | 16 ++--- .../expected_sbom_stack_analysis.json | 16 ++--- .../expected_sbom_stack_analysis.json | 16 ++--- 7 files changed, 90 insertions(+), 74 deletions(-) diff --git a/src/providers/rust_cargo.js b/src/providers/rust_cargo.js index 19a8a1d8..bbe52c10 100644 --- a/src/providers/rust_cargo.js +++ b/src/providers/rust_cargo.js @@ -275,7 +275,7 @@ function handleSingleCrate(metadata, ignoredDeps, includeTransitive, opts, licen } if (includeTransitive) { - addTransitiveDeps(sbom, metadata, rootPackageId, ignoredDeps, new Set()) + addTransitiveDeps(sbom, metadata, rootPackageId, ignoredDeps, new Set(), rootPurl) } else { addDirectDeps(sbom, metadata, rootPackageId, rootPurl, ignoredDeps) } @@ -322,9 +322,12 @@ function handleVirtualWorkspace(manifest, metadata, ignoredDeps, includeTransiti let memberPackage = findPackageById(metadata, memberId) if (!memberPackage) {continue} - let memberPurl = toPurl(memberPackage.name, memberPackage.version) + let memberPurl = memberPackage.source == null + ? toPathDepPurl(memberPackage.name, memberPackage.version) + : toPurl(memberPackage.name, memberPackage.version) + sbom.addDependency(rootPurl, memberPurl) - addTransitiveDeps(sbom, metadata, memberId, ignoredDeps, new Set()) + addTransitiveDeps(sbom, metadata, memberId, ignoredDeps, new Set(), memberPurl) } } else { // Component analysis: only [workspace.dependencies] from root Cargo.toml @@ -333,14 +336,17 @@ function handleVirtualWorkspace(manifest, metadata, ignoredDeps, includeTransiti for (let depName of workspaceDeps) { if (isDepIgnored(depName, ignoredDeps)) {continue} - let pkg = metadata.packages.find(p => p.name === depName && p.source != null) + let pkg = metadata.packages.find(p => p.name === depName) if (!pkg) { let altName = depName.replace(/-/g, '_') - pkg = metadata.packages.find(p => p.name === altName && p.source != null) + pkg = metadata.packages.find(p => p.name === altName) } if (!pkg) {continue} - let depPurl = toPurl(pkg.name, pkg.version) + let depPurl = pkg.source == null + ? toPathDepPurl(pkg.name, pkg.version) + : toPurl(pkg.name, pkg.version) + sbom.addDependency(rootPurl, depPurl) } } @@ -350,19 +356,19 @@ function handleVirtualWorkspace(manifest, metadata, ignoredDeps, includeTransiti /** * Recursively adds transitive dependencies to the SBOM. - * Path dependencies (source == null) are not added to the SBOM, but their - * subtrees are still walked. Any registry dependencies found under a path - * dep are attached to the nearest non-path ancestor via {@link effectiveParentPurl}. + * Path dependencies (source == null) are included with a + * {@code repository_url=local} qualifier so the backend can skip + * vulnerability checks while still showing them in the dependency tree. * @param {Sbom} sbom - the SBOM to add dependencies to * @param {object} metadata - parsed cargo metadata * @param {string} packageId - the package ID to resolve dependencies for * @param {Set} ignoredDeps - set of ignored dependency names * @param {Set} visited - set of already-visited package IDs to prevent cycles - * @param {PackageURL} [effectiveParentPurl] - when walking through a path dep, - * the purl of the nearest registry ancestor to attach discovered deps to + * @param {PackageURL} [startingPurl] - purl to use for the starting package, + * so callers can ensure it matches the purl already added to the SBOM * @private */ -function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited, effectiveParentPurl) { +function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited, startingPurl) { if (visited.has(packageId)) {return} visited.add(packageId) @@ -372,11 +378,9 @@ function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited, effe let sourcePackage = findPackageById(metadata, packageId) if (!sourcePackage) {return} - // For path deps use the effective parent purl so their children attach - // to the nearest real (registry) ancestor in the SBOM. - let sourcePurl = (sourcePackage.source == null && effectiveParentPurl) - ? effectiveParentPurl - : toPurl(sourcePackage.name, sourcePackage.version) + let sourcePurl = startingPurl || (sourcePackage.source == null + ? toPathDepPurl(sourcePackage.name, sourcePackage.version) + : toPurl(sourcePackage.name, sourcePackage.version)) let runtimeDeps = filterRuntimeDeps(resolveNode) @@ -385,14 +389,10 @@ function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited, effe if (!depPackage) {continue} if (isDepIgnored(depPackage.name, ignoredDeps)) {continue} - if (depPackage.source == null) { - // Path dependency — don't add to SBOM, but walk its deps - // passing our sourcePurl so its children attach correctly - addTransitiveDeps(sbom, metadata, depId, ignoredDeps, visited, sourcePurl) - continue - } + let depPurl = depPackage.source == null + ? toPathDepPurl(depPackage.name, depPackage.version) + : toPurl(depPackage.name, depPackage.version) - let depPurl = toPurl(depPackage.name, depPackage.version) sbom.addDependency(sourcePurl, depPurl) addTransitiveDeps(sbom, metadata, depId, ignoredDeps, visited) } @@ -400,6 +400,7 @@ function addTransitiveDeps(sbom, metadata, packageId, ignoredDeps, visited, effe /** * Adds only direct (non-transitive) dependencies to the SBOM. + * Path dependencies are included with a {@code repository_url=local} qualifier. * @param {Sbom} sbom - the SBOM to add dependencies to * @param {object} metadata - parsed cargo metadata * @param {string} packageId - the package ID to resolve dependencies for @@ -417,9 +418,11 @@ function addDirectDeps(sbom, metadata, packageId, parentPurl, ignoredDeps) { let depPackage = findPackageById(metadata, depId) if (!depPackage) {continue} if (isDepIgnored(depPackage.name, ignoredDeps)) {continue} - if (depPackage.source == null) {continue} - let depPurl = toPurl(depPackage.name, depPackage.version) + let depPurl = depPackage.source == null + ? toPathDepPurl(depPackage.name, depPackage.version) + : toPurl(depPackage.name, depPackage.version) + sbom.addDependency(parentPurl, depPurl) } } @@ -626,3 +629,16 @@ function isInDependencySection(section) { function toPurl(name, version) { return new PackageURL(ecosystem, undefined, name, version, undefined, undefined) } + +/** + * Creates a PackageURL for a local path dependency, marked with a + * {@code repository_url=local} qualifier so the backend can distinguish + * it from registry packages and skip vulnerability checks. + * @param {string} name - the crate name + * @param {string} version - the crate version + * @returns {PackageURL} the package URL with local qualifier + * @private + */ +function toPathDepPurl(name, version) { + return new PackageURL(ecosystem, undefined, name, version, { repository_url: 'local' }, undefined) +} diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json index b97922ad..06639d2f 100644 --- a/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace/expected_sbom_stack_analysis.json @@ -23,9 +23,9 @@ { "name": "crate-a", "version": "0.1.0", - "purl": "pkg:cargo/crate-a@0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-a@0.1.0" + "bom-ref": "pkg:cargo/crate-a@0.1.0?repository_url=local" }, { "name": "serde", @@ -37,9 +37,9 @@ { "name": "crate-b", "version": "0.2.0", - "purl": "pkg:cargo/crate-b@0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-b@0.2.0" + "bom-ref": "pkg:cargo/crate-b@0.2.0?repository_url=local" }, { "name": "tokio", @@ -60,12 +60,12 @@ { "ref": "pkg:cargo/cargo_virtual_workspace@0.0.0", "dependsOn": [ - "pkg:cargo/crate-a@0.1.0", - "pkg:cargo/crate-b@0.2.0" + "pkg:cargo/crate-a@0.1.0?repository_url=local", + "pkg:cargo/crate-b@0.2.0?repository_url=local" ] }, { - "ref": "pkg:cargo/crate-a@0.1.0", + "ref": "pkg:cargo/crate-a@0.1.0?repository_url=local", "dependsOn": [ "pkg:cargo/serde@1.0.193" ] @@ -75,7 +75,7 @@ "dependsOn": [] }, { - "ref": "pkg:cargo/crate-b@0.2.0", + "ref": "pkg:cargo/crate-b@0.2.0?repository_url=local", "dependsOn": [ "pkg:cargo/tokio@1.35.0" ] diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json index 58357615..3da42dad 100644 --- a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_glob_members/expected_sbom_stack_analysis.json @@ -23,16 +23,16 @@ { "name": "crate-a", "version": "0.1.0", - "purl": "pkg:cargo/crate-a@0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-a@0.1.0" + "bom-ref": "pkg:cargo/crate-a@0.1.0?repository_url=local" }, { "name": "crate-b", "version": "0.2.0", - "purl": "pkg:cargo/crate-b@0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-b@0.2.0" + "bom-ref": "pkg:cargo/crate-b@0.2.0?repository_url=local" }, { "name": "tokio", @@ -53,16 +53,16 @@ { "ref": "pkg:cargo/cargo_virtual_workspace_glob_members@0.0.0", "dependsOn": [ - "pkg:cargo/crate-a@0.1.0", - "pkg:cargo/crate-b@0.2.0" + "pkg:cargo/crate-a@0.1.0?repository_url=local", + "pkg:cargo/crate-b@0.2.0?repository_url=local" ] }, { - "ref": "pkg:cargo/crate-a@0.1.0", + "ref": "pkg:cargo/crate-a@0.1.0?repository_url=local", "dependsOn": [] }, { - "ref": "pkg:cargo/crate-b@0.2.0", + "ref": "pkg:cargo/crate-b@0.2.0?repository_url=local", "dependsOn": [ "pkg:cargo/tokio@1.35.0" ] diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json index f4454239..4b88eb4f 100644 --- a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_exhortignore/expected_sbom_stack_analysis.json @@ -23,16 +23,16 @@ { "name": "crate-a", "version": "0.1.0", - "purl": "pkg:cargo/crate-a@0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-a@0.1.0" + "bom-ref": "pkg:cargo/crate-a@0.1.0?repository_url=local" }, { "name": "crate-b", "version": "0.2.0", - "purl": "pkg:cargo/crate-b@0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-b@0.2.0" + "bom-ref": "pkg:cargo/crate-b@0.2.0?repository_url=local" }, { "name": "tokio", @@ -53,16 +53,16 @@ { "ref": "pkg:cargo/cargo_virtual_workspace_with_exhortignore@0.0.0", "dependsOn": [ - "pkg:cargo/crate-a@0.1.0", - "pkg:cargo/crate-b@0.2.0" + "pkg:cargo/crate-a@0.1.0?repository_url=local", + "pkg:cargo/crate-b@0.2.0?repository_url=local" ] }, { - "ref": "pkg:cargo/crate-a@0.1.0", + "ref": "pkg:cargo/crate-a@0.1.0?repository_url=local", "dependsOn": [] }, { - "ref": "pkg:cargo/crate-b@0.2.0", + "ref": "pkg:cargo/crate-b@0.2.0?repository_url=local", "dependsOn": [ "pkg:cargo/tokio@1.35.0" ] diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json index c1bab0b4..46b781e8 100644 --- a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_ignore/expected_sbom_stack_analysis.json @@ -23,16 +23,16 @@ { "name": "crate-a", "version": "0.1.0", - "purl": "pkg:cargo/crate-a@0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-a@0.1.0" + "bom-ref": "pkg:cargo/crate-a@0.1.0?repository_url=local" }, { "name": "crate-b", "version": "0.2.0", - "purl": "pkg:cargo/crate-b@0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-b@0.2.0" + "bom-ref": "pkg:cargo/crate-b@0.2.0?repository_url=local" }, { "name": "tokio", @@ -53,16 +53,16 @@ { "ref": "pkg:cargo/cargo_virtual_workspace_with_ignore@0.0.0", "dependsOn": [ - "pkg:cargo/crate-a@0.1.0", - "pkg:cargo/crate-b@0.2.0" + "pkg:cargo/crate-a@0.1.0?repository_url=local", + "pkg:cargo/crate-b@0.2.0?repository_url=local" ] }, { - "ref": "pkg:cargo/crate-a@0.1.0", + "ref": "pkg:cargo/crate-a@0.1.0?repository_url=local", "dependsOn": [] }, { - "ref": "pkg:cargo/crate-b@0.2.0", + "ref": "pkg:cargo/crate-b@0.2.0?repository_url=local", "dependsOn": [ "pkg:cargo/tokio@1.35.0" ] diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_license/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_license/expected_sbom_stack_analysis.json index c9f53736..cd248f0d 100644 --- a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_license/expected_sbom_stack_analysis.json +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_license/expected_sbom_stack_analysis.json @@ -37,9 +37,9 @@ { "name": "crate-a", "version": "0.1.0", - "purl": "pkg:cargo/crate-a@0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-a@0.1.0" + "bom-ref": "pkg:cargo/crate-a@0.1.0?repository_url=local" }, { "name": "serde", @@ -51,9 +51,9 @@ { "name": "crate-b", "version": "0.2.0", - "purl": "pkg:cargo/crate-b@0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-b@0.2.0" + "bom-ref": "pkg:cargo/crate-b@0.2.0?repository_url=local" }, { "name": "tokio", @@ -74,12 +74,12 @@ { "ref": "pkg:cargo/cargo_virtual_workspace_with_license@0.0.0", "dependsOn": [ - "pkg:cargo/crate-a@0.1.0", - "pkg:cargo/crate-b@0.2.0" + "pkg:cargo/crate-a@0.1.0?repository_url=local", + "pkg:cargo/crate-b@0.2.0?repository_url=local" ] }, { - "ref": "pkg:cargo/crate-a@0.1.0", + "ref": "pkg:cargo/crate-a@0.1.0?repository_url=local", "dependsOn": [ "pkg:cargo/serde@1.0.193" ] @@ -89,7 +89,7 @@ "dependsOn": [] }, { - "ref": "pkg:cargo/crate-b@0.2.0", + "ref": "pkg:cargo/crate-b@0.2.0?repository_url=local", "dependsOn": [ "pkg:cargo/tokio@1.35.0" ] diff --git a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json index 0bcfbf08..21bb6607 100644 --- a/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json +++ b/test/providers/tst_manifests/cargo/cargo_virtual_workspace_with_workspace_deps/expected_sbom_stack_analysis.json @@ -23,9 +23,9 @@ { "name": "crate-a", "version": "0.1.0", - "purl": "pkg:cargo/crate-a@0.1.0", + "purl": "pkg:cargo/crate-a@0.1.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-a@0.1.0" + "bom-ref": "pkg:cargo/crate-a@0.1.0?repository_url=local" }, { "name": "serde", @@ -37,9 +37,9 @@ { "name": "crate-b", "version": "0.2.0", - "purl": "pkg:cargo/crate-b@0.2.0", + "purl": "pkg:cargo/crate-b@0.2.0?repository_url=local", "type": "library", - "bom-ref": "pkg:cargo/crate-b@0.2.0" + "bom-ref": "pkg:cargo/crate-b@0.2.0?repository_url=local" }, { "name": "tokio", @@ -60,12 +60,12 @@ { "ref": "pkg:cargo/cargo_virtual_workspace_with_workspace_deps@0.0.0", "dependsOn": [ - "pkg:cargo/crate-a@0.1.0", - "pkg:cargo/crate-b@0.2.0" + "pkg:cargo/crate-a@0.1.0?repository_url=local", + "pkg:cargo/crate-b@0.2.0?repository_url=local" ] }, { - "ref": "pkg:cargo/crate-a@0.1.0", + "ref": "pkg:cargo/crate-a@0.1.0?repository_url=local", "dependsOn": [ "pkg:cargo/serde@1.0.193" ] @@ -75,7 +75,7 @@ "dependsOn": [] }, { - "ref": "pkg:cargo/crate-b@0.2.0", + "ref": "pkg:cargo/crate-b@0.2.0?repository_url=local", "dependsOn": [ "pkg:cargo/tokio@1.35.0" ]