diff --git a/src/Microsoft.ComponentDetection.Detectors/linux/Contracts/SyftOutput.cs b/src/Microsoft.ComponentDetection.Detectors/linux/Contracts/SyftOutput.cs
index 2f0fd3f77..ae185e3df 100644
--- a/src/Microsoft.ComponentDetection.Detectors/linux/Contracts/SyftOutput.cs
+++ b/src/Microsoft.ComponentDetection.Detectors/linux/Contracts/SyftOutput.cs
@@ -1,576 +1,3251 @@
-#nullable disable
-
// Take schema from https://github.com/anchore/syft/tree/main/schema/json.
// Match version to tag used i.e. https://github.com/anchore/syft/blob/v1.37.0/internal/constants.go#L6
// Can convert JSON Schema to C# using quicktype.io.
// (change name of top Coordinate class to SyftOutput)
//
+#nullable enable
+#pragma warning disable CS8618
+#pragma warning disable CS8601
+#pragma warning disable CS8603
namespace Microsoft.ComponentDetection.Detectors.Linux.Contracts;
using System;
using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Globalization;
+
+///
+/// Document represents the syft cataloging findings as a JSON document
+///
public partial class SyftOutput
{
+ [JsonPropertyName("artifactRelationships")]
public ArtifactRelationshipElement[] ArtifactRelationships { get; set; }
+
+ [JsonPropertyName("artifacts")]
public ArtifactElement[] Artifacts { get; set; }
+
+ [JsonPropertyName("descriptor")]
public Descriptor Descriptor { get; set; }
+
+ [JsonPropertyName("distro")]
public Distro Distro { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("files")]
public FileElement[] Files { get; set; }
+
+ [JsonPropertyName("schema")]
public Schema Schema { get; set; }
+
+ [JsonPropertyName("source")]
public SourceClass Source { get; set; }
}
public partial class ArtifactRelationshipElement
{
+ [JsonPropertyName("child")]
public string Child { get; set; }
+
+ [JsonPropertyName("metadata")]
public object Metadata { get; set; }
+
+ [JsonPropertyName("parent")]
public string Parent { get; set; }
+
+ [JsonPropertyName("type")]
public string Type { get; set; }
}
+///
+/// Package represents a pkg.Package object specialized for JSON marshaling and unmarshalling.
+///
public partial class ArtifactElement
{
+ [JsonPropertyName("cpes")]
public CpeElement[] Cpes { get; set; }
+
+ [JsonPropertyName("foundBy")]
public string FoundBy { get; set; }
+
+ [JsonPropertyName("id")]
public string Id { get; set; }
+
+ [JsonPropertyName("language")]
public string Language { get; set; }
+
+ [JsonPropertyName("licenses")]
public ArtifactLicense[] Licenses { get; set; }
+
+ [JsonPropertyName("locations")]
public LocationElement[] Locations { get; set; }
+
+ [JsonPropertyName("metadata")]
public MetadataClass Metadata { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("metadataType")]
public string MetadataType { get; set; }
+
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ [JsonPropertyName("purl")]
public string Purl { get; set; }
+
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
public partial class CpeElement
{
+ [JsonPropertyName("cpe")]
public string Cpe { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("source")]
public string Source { get; set; }
}
public partial class ArtifactLicense
{
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("contents")]
public string Contents { get; set; }
+
+ [JsonPropertyName("locations")]
public LocationElement[] Locations { get; set; }
+
+ [JsonPropertyName("spdxExpression")]
public string SpdxExpression { get; set; }
+
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ [JsonPropertyName("urls")]
public string[] Urls { get; set; }
+
+ [JsonPropertyName("value")]
public string Value { get; set; }
}
+///
+/// Location represents a path relative to a particular filesystem resolved to a specific
+/// file.Reference.
+///
public partial class LocationElement
{
+ ///
+ /// AccessPath is the path used to retrieve file contents (which may or may not have
+ /// hardlinks / symlinks in the path)
+ ///
+ [JsonPropertyName("accessPath")]
public string AccessPath { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("annotations")]
public Dictionary Annotations { get; set; }
+
+ ///
+ /// FileSystemID is an ID representing and entire filesystem. For container images, this is a
+ /// layer digest. For directories or a root filesystem, this is blank.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("layerID")]
public string LayerId { get; set; }
+
+ ///
+ /// RealPath is the canonical absolute form of the path accessed (all symbolic links have
+ /// been followed and relative path components like '.' and '..' have been removed).
+ ///
+ [JsonPropertyName("path")]
public string Path { get; set; }
}
+///
+/// AlpmDBEntry is a struct that represents the package data stored in the pacman flat-file
+/// stores for arch linux.
+///
+/// ApkDBEntry represents all captured data for the alpine linux package manager flat-file
+/// store.
+///
+/// BinarySignature represents a set of matched values within a binary file.
+///
+/// BitnamiSBOMEntry represents all captured data from Bitnami packages described in Bitnami'
+/// SPDX files.
+///
+/// ConanfileEntry represents a single "Requires" entry from a conanfile.txt.
+///
+/// ConaninfoEntry represents a single "full_requires" entry from a conaninfo.txt.
+///
+/// ConanV1LockEntry represents a single "node" entry from a conan.lock V1 file.
+///
+/// ConanV2LockEntry represents a single "node" entry from a conan.lock V2 file.
+///
+/// CocoaPodfileLockEntry represents a single entry from the "Pods" section of a Podfile.lock
+/// file.
+///
+/// CondaMetaPackage represents metadata for a Conda package extracted from the
+/// conda-meta/*.json files.
+///
+/// DartPubspec is a struct that represents a package described in a pubspec.yaml file
+///
+/// DartPubspecLockEntry is a struct that represents a single entry found in the "packages"
+/// section in a Dart pubspec.lock file.
+///
+/// DotnetDepsEntry is a struct that represents a single entry found in the "libraries"
+/// section in a .NET [*.]deps.json file.
+///
+/// DotnetPackagesLockEntry is a struct that represents a single entry found in the
+/// "dependencies" section in a .NET packages.lock.json file.
+///
+/// DotnetPortableExecutableEntry is a struct that represents a single entry found within
+/// "VersionResources" section of a .NET Portable Executable binary file.
+///
+/// DpkgArchiveEntry represents package metadata extracted from a .deb archive file.
+///
+/// DpkgDBEntry represents all captured data for a Debian package DB entry; available fields
+/// are described at http://manpages.ubuntu.com/manpages/xenial/man1/dpkg-query.1.html in the
+/// --showformat section.
+///
+/// ELFBinaryPackageNoteJSONPayload Represents metadata captured from the .note.package
+/// section of an ELF-formatted binary
+///
+/// ElixirMixLockEntry is a struct that represents a single entry in a mix.lock file
+///
+/// ErlangRebarLockEntry represents a single package entry from the "deps" section within an
+/// Erlang rebar.lock file.
+///
+/// GitHubActionsUseStatement represents a single 'uses' statement in a GitHub Actions
+/// workflow file referencing an action or reusable workflow.
+///
+/// GolangBinaryBuildinfoEntry represents all captured data for a Golang binary
+///
+/// GolangModuleEntry represents all captured data for a Golang source scan with
+/// go.mod/go.sum
+///
+/// GolangSourceEntry represents all captured data for a Golang package found through source
+/// analysis
+///
+/// HackageStackYamlEntry represents a single entry from the "extra-deps" section of a
+/// stack.yaml file.
+///
+/// HackageStackYamlLockEntry represents a single entry from the "packages" section of a
+/// stack.yaml.lock file.
+///
+/// HomebrewFormula represents metadata about a Homebrew formula package extracted from
+/// formula JSON files.
+///
+/// JavaArchive encapsulates all Java ecosystem metadata for a package as well as an
+/// (optional) parent relationship.
+///
+/// JavaVMInstallation represents a Java Virtual Machine installation discovered on the
+/// system with its release information and file list.
+///
+/// NpmPackage represents the contents of a javascript package.json file.
+///
+/// NpmPackageLockEntry represents a single entry within the "packages" section of a
+/// package-lock.json file.
+///
+/// YarnLockEntry represents a single entry section of a yarn.lock file.
+///
+/// LinuxKernel represents all captured data for a Linux kernel
+///
+/// LinuxKernelModule represents a loadable kernel module (.ko file) with its metadata,
+/// parameters, and dependencies.
+///
+/// LuaRocksPackage represents a Lua package managed by the LuaRocks package manager with
+/// metadata from .rockspec files.
+///
+/// MicrosoftKbPatch is slightly odd in how it is expected to map onto data.
+///
+/// NixStoreEntry represents a package in the Nix store (/nix/store) with its derivation
+/// information and metadata.
+///
+/// OpamPackage represents an OCaml package managed by the OPAM package manager with metadata
+/// from .opam files.
+///
+/// PEBinary represents metadata captured from a Portable Executable formatted binary (dll,
+/// exe, etc.)
+///
+/// PhpComposerInstalledEntry represents a single package entry from a composer v1/v2
+/// "installed.json" files (very similar to composer.lock files).
+///
+/// PhpComposerLockEntry represents a single package entry found from a composer.lock file.
+///
+/// PhpPearEntry represents a single package entry found within php pear metadata files.
+///
+/// PhpPeclEntry represents a single package entry found within php pecl metadata files.
+///
+/// PortageEntry represents a single package entry in the portage DB flat-file store.
+///
+/// PythonPackage represents all captured data for a python egg or wheel package
+/// (specifically as outlined in the PyPA core metadata specification
+/// https://packaging.python.org/en/latest/specifications/core-metadata/).
+///
+/// PythonPdmLockEntry represents a single package entry within a pdm.lock file.
+///
+/// PythonRequirementsEntry represents a single entry within a [*-]requirements.txt file.
+///
+/// PythonPipfileLockEntry represents a single package entry within a Pipfile.lock file.
+///
+/// PythonPoetryLockEntry represents a single package entry within a Pipfile.lock file.
+///
+/// PythonUvLockEntry represents a single package entry within a uv.lock file.
+///
+/// RDescription represents metadata from an R package DESCRIPTION file containing package
+/// information, dependencies, and author details.
+///
+/// RpmArchive represents package metadata extracted directly from a .rpm archive file,
+/// containing the same information as an RPM database entry.
+///
+/// RpmDBEntry represents all captured data from a RPM DB package entry.
+///
+/// RubyGemspec represents all metadata parsed from the *.gemspec file
+///
+/// RustBinaryAuditEntry represents Rust crate metadata extracted from a compiled binary
+/// using cargo-auditable format.
+///
+/// RustCargoLockEntry represents a locked dependency from a Cargo.lock file with precise
+/// version and checksum information.
+///
+/// SnapEntry represents metadata for a Snap package extracted from snap.yaml or
+/// snapcraft.yaml files.
+///
+/// SwiftPackageManagerResolvedEntry represents a resolved dependency from a Package.resolved
+/// file with its locked version and source location.
+///
+/// SwiplPackEntry represents a SWI-Prolog package from the pack system with metadata about
+/// the package and its dependencies.
+///
+/// TerraformLockProviderEntry represents a single provider entry in a Terraform dependency
+/// lock file (.terraform.lock.hcl).
+///
+/// WordpressPluginEntry represents all metadata parsed from the wordpress plugin file
+///
public partial class MetadataClass
{
+ ///
+ /// Architecture is the target CPU architecture as defined in Arch architecture spec (e.g.
+ /// x86_64, aarch64, or "any" for arch-independent packages)
+ ///
+ /// Architecture is the target CPU architecture
+ ///
+ /// Architecture is the target architecture per Debian spec (specific arch like amd64/arm64,
+ /// wildcard like any, architecture-independent "all", or "source" for source packages)
+ ///
+ /// Architecture of the binary package (e.g. "amd64", "arm", etc.)
+ ///
+ /// Architecture is the target CPU architecture for the binary (extracted from GOARCH build
+ /// setting).
+ ///
+ /// Architecture is the target CPU architecture for build constraints (e.g., "amd64",
+ /// "arm64").
+ ///
+ /// Arch is the target CPU architecture (e.g., "x86_64", "aarch64", "noarch").
+ ///
+ /// Architecture is the target CPU architecture (e.g., "amd64", "arm64").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("architecture")]
public string Architecture { get; set; }
+
+ ///
+ /// Backup is the list of configuration files that pacman backs up before upgrades
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("backup")]
public BackupElement[] Backup { get; set; }
+
+ ///
+ /// BasePackage is the base package name this package was built from (source package in Arch
+ /// build system)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("basepackage")]
public string Basepackage { get; set; }
+
+ ///
+ /// Depends are the runtime dependencies required by this package
+ ///
+ /// Depends is the list of runtime dependencies with version constraints.
+ ///
+ /// Depends are the packages required for this package to function (will not be installed
+ /// unless these requirements are met, creates strict ordering constraint)
+ ///
+ /// Depends are the packages this package depends on
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("depends")]
public string[] Depends { get; set; }
+
+ ///
+ /// Description is a human-readable package description
+ ///
+ /// Description is a human-readable formula description
+ ///
+ /// Description is a human-readable module description
+ ///
+ /// Description is detailed package description
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("description")]
public string Description { get; set; }
+
+ ///
+ /// Files are the files installed by this package
+ ///
+ /// Files are the file paths owned by this package (tracked via SPDX relationships)
+ ///
+ /// Files is the list of files installed by this package.
+ ///
+ /// Files are the list of files that are part of this JVM installation
+ ///
+ /// Files are the list of files under the nix/store path for this package
+ ///
+ /// Files are the files installed by this package (tracked in CONTENTS file)
+ ///
+ /// Files are the installed files listed in the RECORD file for wheels or installed-files.txt
+ /// for eggs.
+ ///
+ /// Files are the package files with their paths and hash digests
+ ///
+ /// Files are the file records for all files owned by this package.
+ ///
+ /// Files is logical list of files in the gem (NOT directly usable as filesystem paths.
+ /// Example: bundler gem lists "lib/bundler/vendor/uri/lib/uri/ldap.rb" but actual path is
+ /// "/usr/local/lib/ruby/3.2.0/bundler/vendor/uri/lib/uri/ldap.rb". Would need gem
+ /// installation path, ruby version, and env vars like GEM_HOME to resolve actual paths.)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("files")]
public File[] Files { get; set; }
+
+ ///
+ /// Package is the package name as found in the desc file
+ ///
+ /// Package is the package name as found in the installed file
+ ///
+ /// Package is the package name as found in the status file
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("package")]
public string Package { get; set; }
+
+ ///
+ /// Packager is the name and email of the person who packaged this (RFC822 format)
+ ///
+ /// Packager is packager name (if different from author)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("packager")]
public string Packager { get; set; }
+
+ ///
+ /// Provides are virtual packages provided by this package (allows other packages to depend
+ /// on capabilities rather than specific packages)
+ ///
+ /// Provides are virtual packages provided by this package (for capability-based
+ /// dependencies)
+ ///
+ /// Provides are the virtual packages provided by this package (allows other packages to
+ /// depend on capabilities. Can include versioned provides like "libdigest-md5-perl (=
+ /// 2.55.01)")
+ ///
+ /// Provides lists the virtual packages and capabilities this package provides.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("provides")]
public string[] Provides { get; set; }
+
+ ///
+ /// Reason is the installation reason tracked by pacman (0=explicitly installed by user,
+ /// 1=installed as dependency)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("reason")]
public long? Reason { get; set; }
+
+ ///
+ /// Size is the installed size in bytes
+ ///
+ /// Size is the package archive size in bytes (.apk file size)
+ ///
+ /// Size is the package archive size in bytes.
+ ///
+ /// Size is the total installed size of the package in bytes.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("size")]
public long? Size { get; set; }
+
+ ///
+ /// URL is the upstream project URL
+ ///
+ /// URL is the full download URL for the package archive.
+ ///
+ /// URL is repository or project URL
+ ///
+ /// URL is the source download URL
+ ///
+ /// URL is download URL for the package source
+ ///
+ /// URL is the direct download URL or VCS URL if specified instead of a PyPI package.
+ ///
+ /// URL is the list of related URLs
+ ///
+ /// URL is the provider source address (e.g., "registry.terraform.io/hashicorp/aws").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("url")]
public Checksum? Url { get; set; }
+
+ ///
+ /// Validation is the validation method used for package integrity (e.g. pgp signature,
+ /// sha256 checksum)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("validation")]
public string Validation { get; set; }
+
+ ///
+ /// Version is the package version as found in the desc file
+ ///
+ /// Version is the package version as found in the installed file
+ ///
+ /// Version is the package version as found in the Bitnami SPDX file
+ ///
+ /// Version is the package version as found in the conda-meta JSON file.
+ ///
+ /// Version is the package version as found in the pubspec.lock file
+ ///
+ /// Version is the package version as found in the deps.json file
+ ///
+ /// Version is the package version as found in the packages.lock.json file
+ ///
+ /// Version is the binary package version as found in the status file
+ ///
+ /// Version is the package version as found in the mix.lock file
+ ///
+ /// Version is the package version as found in the rebar.lock file
+ ///
+ /// Version is the package version as found in package.json
+ ///
+ /// Version is kernel version string
+ ///
+ /// Version is module version string
+ ///
+ /// Version is the package version as found in the .rockspec file
+ ///
+ /// Version is the package version as found in the .opam file
+ ///
+ /// Version is the package version
+ ///
+ /// Version is the package version from the Version field in PKG-INFO or METADATA.
+ ///
+ /// Version is the upstream version of the package.
+ ///
+ /// Version is gem version as specified in the gemspec
+ ///
+ /// Version is crate version as specified in audit section of the build binary
+ ///
+ /// Version is crate version as specified in Cargo.toml
+ ///
+ /// Version is the package version as found in the .toml file
+ ///
+ /// Version is the locked provider version selected during terraform init.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("version")]
public string Version { get; set; }
+
+ ///
+ /// GitCommit is the git commit hash of the APK port definition in Alpine's aports repository
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("gitCommitOfApkPort")]
public string GitCommitOfApkPort { get; set; }
+
+ ///
+ /// InstalledSize is the total size of installed files in bytes
+ ///
+ /// InstalledSize is the total size of installed files in kilobytes
+ ///
+ /// InstalledSize is total size of installed files in bytes
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("installedSize")]
public long? InstalledSize { get; set; }
+
+ ///
+ /// Maintainer is the package maintainer name and email
+ ///
+ /// Maintainer is the package maintainer's name and email in RFC822 format (name must come
+ /// first, then email in angle brackets)
+ ///
+ /// Maintainer is current package maintainer
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("maintainer")]
public string Maintainer { get; set; }
+
+ ///
+ /// OriginPackage is the original source package name this binary was built from (used to
+ /// track which aport/source built this)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("originPackage")]
public string OriginPackage { get; set; }
+
+ ///
+ /// Checksum is the package content checksum for integrity verification
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("pullChecksum")]
public string PullChecksum { get; set; }
+
+ ///
+ /// Dependencies are the runtime dependencies required by this package
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("pullDependencies")]
public string[] PullDependencies { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("matches")]
public MatchElement[] Matches { get; set; }
+
+ ///
+ /// Architecture is the target CPU architecture (amd64 or arm64 in Bitnami images)
+ ///
+ /// Arch is the target CPU architecture for the package (e.g., "arm64", "x86_64").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("arch")]
public string Arch { get; set; }
+
+ ///
+ /// Distro is the distribution name this package is for (base OS like debian, ubuntu, etc.)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("distro")]
public string Distro { get; set; }
+
+ ///
+ /// Name is the package name as found in the Bitnami SPDX file
+ ///
+ /// Name is the package name as found in the conda-meta JSON file.
+ ///
+ /// Name is the package name as found in the pubspec.lock file
+ ///
+ /// Name is the package name as found in the deps.json file
+ ///
+ /// Name is the package name as found in the packages.lock.json file
+ ///
+ /// Name is the package name as found in the mix.lock file
+ ///
+ /// Name is the package name as found in the rebar.lock file
+ ///
+ /// Name is the package name as found in package.json
+ ///
+ /// Name is kernel name (typically "Linux")
+ ///
+ /// Name is module name
+ ///
+ /// Name is the package name as found in the .rockspec file
+ ///
+ /// Name is the package name as found in the .opam file
+ ///
+ /// Name is package name in vendor/package format (e.g. symfony/console)
+ ///
+ /// Name is the package name
+ ///
+ /// Name is the package name from the Name field in PKG-INFO or METADATA.
+ ///
+ /// Name is the package name from the requirements file.
+ ///
+ /// Name is the RPM package name as found in the RPM database.
+ ///
+ /// Name is gem name as specified in the gemspec
+ ///
+ /// Name is crate name as specified in audit section of the build binary
+ ///
+ /// Name is crate name as specified in Cargo.toml
+ ///
+ /// Name is the package name as found in the .toml file
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ ///
+ /// Path is the installation path in the filesystem where the package is located
+ ///
+ /// Path is the filesystem path to the package in Conan cache
+ ///
+ /// Path is the relative path to the package within the deps structure (e.g.
+ /// "app.metrics/3.0.0")
+ ///
+ /// Path is the filesystem path to the .ko kernel object file (absolute path)
+ ///
+ /// Path is full store path for this output (e.g. /nix/store/abc123...-package-1.0)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("path")]
public string Path { get; set; }
+
+ ///
+ /// Revision is the Bitnami-specific package revision number (incremented for Bitnami
+ /// rebuilds of same upstream version)
+ ///
+ /// Revision is git commit hash of the resolved package
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("revision")]
public string Revision { get; set; }
+
+ ///
+ /// Ref is the package reference string in format name/version@user/channel
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("ref")]
public string Ref { get; set; }
- public string SyftOutpuPackageId { get; set; }
+
+ ///
+ /// PackageID is a unique package variant identifier
+ ///
+ /// PackageID is a unique package variant identifier computed from settings/options (static
+ /// hash in Conan 1.x, can have collisions with complex dependency graphs)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("package_id")]
+ public string SyftOutputPackageId { get; set; }
+
+ ///
+ /// BuildRequires are the build-time dependencies (e.g. cmake, compilers)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("build_requires")]
public string[] BuildRequires { get; set; }
+
+ ///
+ /// Context is the build context information
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("context")]
public string Context { get; set; }
+
+ ///
+ /// Options are package configuration options as key-value pairs (e.g. shared=True, fPIC=True)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("options")]
public VersionResourceElement[] Options { get; set; }
+
+ ///
+ /// Prev is the previous lock entry reference for versioning
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("prev")]
public string Prev { get; set; }
+
+ ///
+ /// PythonRequires are the Python dependencies needed for Conan recipes
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("py_requires")]
public string[] PyRequires { get; set; }
+
+ ///
+ /// Requires are the runtime package dependencies
+ ///
+ /// Requires lists the dependencies required by this package.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("requires")]
public string[] Requires { get; set; }
+
+ ///
+ /// Channel is the Conan channel name indicating stability/purpose (e.g. stable, testing,
+ /// experimental)
+ ///
+ /// Channel is the Conda channel URL where the package was retrieved from.
+ ///
+ /// Channel is PEAR channel this package is from
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("channel")]
public string Channel { get; set; }
+
+ ///
+ /// PackageID is a unique package variant identifier (dynamic in Conan 2.0, more accurate
+ /// than V1)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("packageID")]
public string PackageId { get; set; }
+
+ ///
+ /// PackageRevision is a git-like revision hash of the built binary package
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("packageRevision")]
public string PackageRevision { get; set; }
+
+ ///
+ /// RecipeRevision is a git-like revision hash (RREV) of the recipe
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("recipeRevision")]
public string RecipeRevision { get; set; }
+
+ ///
+ /// TimeStamp is when this package was built/locked
+ ///
+ /// Timestamp is the Unix timestamp when the package was built.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("timestamp")]
public Timestamp? Timestamp { get; set; }
+
+ ///
+ /// Username is the Conan user/organization name
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("username")]
public string Username { get; set; }
+
+ ///
+ /// Checksum is the SHA-1 hash of the podspec file for integrity verification (generated via
+ /// `pod ipc spec ... | openssl sha1`), ensuring all team members use the same pod
+ /// specification version
+ ///
+ /// Checksums are the list of checksums for verification
+ ///
+ /// Checksum is content checksum for registry packages only (hexadecimal string). Cargo
+ /// doesn't require or include checksums for git dependencies. Used to detect MITM attacks by
+ /// verifying downloaded crate matches lockfile checksum.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("checksum")]
public Checksum? Checksum { get; set; }
+
+ ///
+ /// Build is the build string identifier (e.g., "h90dfc92_1014").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("build")]
public string Build { get; set; }
+
+ ///
+ /// BuildNumber is the sequential build number for this version.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("build_number")]
public long? BuildNumber { get; set; }
+
+ ///
+ /// ExtractedPackageDir is the local cache directory where the package was extracted.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("extracted_package_dir")]
public string ExtractedPackageDir { get; set; }
+
+ ///
+ /// Filename is the original package archive filename (e.g.,
+ /// "zlib-1.2.11-h90dfc92_1014.tar.bz2").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("fn")]
public string Fn { get; set; }
+
+ ///
+ /// License is the package license identifier.
+ ///
+ /// License is module license (e.g. GPL, BSD) which must be compatible with kernel
+ ///
+ /// License is license identifier
+ ///
+ /// License is the list of license identifiers (SPDX format)
+ ///
+ /// License is the list of applicable licenses
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("license")]
public Checksum? License { get; set; }
+
+ ///
+ /// LicenseFamily is the general license category (e.g., "MIT", "Apache", "GPL").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("license_family")]
public string LicenseFamily { get; set; }
+
+ ///
+ /// Link contains installation source metadata from the link.json file.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("link")]
public Link Link { get; set; }
+
+ ///
+ /// MD5 is the MD5 hash of the package archive.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("md5")]
public string Md5 { get; set; }
+
+ ///
+ /// Noarch indicates if the package is platform-independent (e.g., "python", "generic").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("noarch")]
public string Noarch { get; set; }
+
+ ///
+ /// PathsData contains detailed file metadata from the paths.json file.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("paths_data")]
public PathsData PathsData { get; set; }
+
+ ///
+ /// SHA256 is the SHA-256 hash of the package archive.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sha256")]
public string Sha256 { get; set; }
+
+ ///
+ /// Subdir is the subdirectory within the channel (e.g., "osx-arm64", "linux-64").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("subdir")]
public string Subdir { get; set; }
+
+ ///
+ /// Documentation is the documentation site URL
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("documentation")]
public string Documentation { get; set; }
+
+ ///
+ /// Environment is SDK version constraints for Dart and Flutter
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("environment")]
public Environment Environment { get; set; }
+
+ ///
+ /// Homepage is the package homepage URL
+ ///
+ /// Homepage is the upstream project homepage URL
+ ///
+ /// Homepage is project homepage URL
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("homepage")]
public string Homepage { get; set; }
+
+ ///
+ /// IgnoredAdvisories are the security advisories to explicitly ignore for this package
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("ignored_advisories")]
public string[] IgnoredAdvisories { get; set; }
+
+ ///
+ /// Platforms are the supported platforms (Android, iOS, web, etc.)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("platforms")]
public string[] Platforms { get; set; }
+
+ ///
+ /// PublishTo is the package repository to publish to, or "none" to prevent accidental
+ /// publishing
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("publish_to")]
public string PublishTo { get; set; }
+
+ ///
+ /// Repository is the source code repository URL
+ ///
+ /// Repository is CRAN or other repository name
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("repository")]
public string Repository { get; set; }
+
+ ///
+ /// HostedURL is the URL of the package repository for hosted packages (typically pub.dev,
+ /// but can be custom repository identified by hosted-url). When PUB_HOSTED_URL environment
+ /// variable changes, lockfile tracks the source.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("hosted_url")]
public string HostedUrl { get; set; }
+
+ ///
+ /// VcsURL is the URL of the VCS repository for git/path dependencies (for packages fetched
+ /// from version control systems like Git)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("vcs_url")]
public string VcsUrl { get; set; }
+
+ ///
+ /// Executables are the map of .NET Portable Executable files within this package with their
+ /// version resources
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("executables")]
public Dictionary Executables { get; set; }
+
+ ///
+ /// HashPath is the relative path to the .nupkg.sha512 hash file (e.g.
+ /// "app.metrics.3.0.0.nupkg.sha512")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("hashPath")]
public string HashPath { get; set; }
+
+ ///
+ /// Sha512 is the SHA-512 hash of the NuGet package content WITHOUT the signed content for
+ /// verification (won't match hash from NuGet API or manual calculation of .nupkg file)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sha512")]
public string Sha512 { get; set; }
+
+ ///
+ /// ContentHash is the hash of the package content for verification
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("contentHash")]
public string ContentHash { get; set; }
+
+ ///
+ /// Type is the dependency type indicating how this dependency was added (Direct=explicit in
+ /// project file, Transitive=pulled in by another package, Project=project reference)
+ ///
+ /// Type is the type of the package (e.g. "rpm", "deb", "apk", etc.)
+ ///
+ /// Type is package type indicating purpose (library=reusable code, project=application,
+ /// metapackage=aggregates dependencies, etc.)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ ///
+ /// AssemblyVersion is the .NET assembly version number (strong-named version)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("assemblyVersion")]
public string AssemblyVersion { get; set; }
+
+ ///
+ /// Comments are additional comments or description embedded in PE resources
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("comments")]
public string Comments { get; set; }
+
+ ///
+ /// CompanyName is the company that produced the file
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("companyName")]
public string CompanyName { get; set; }
+
+ ///
+ /// InternalName is the internal name of the file
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("internalName")]
public string InternalName { get; set; }
+
+ ///
+ /// LegalCopyright is the copyright notice string
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("legalCopyright")]
public string LegalCopyright { get; set; }
+
+ ///
+ /// ProductName is the name of the product this file is part of
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("productName")]
public string ProductName { get; set; }
+
+ ///
+ /// ProductVersion is the version of the product (may differ from AssemblyVersion)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("productVersion")]
public string ProductVersion { get; set; }
+
+ ///
+ /// PreDepends are the packages that must be installed and configured BEFORE even starting
+ /// installation of this package (stronger than Depends, discouraged unless absolutely
+ /// necessary as it adds strict constraints for apt)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("preDepends")]
public string[] PreDepends { get; set; }
+
+ ///
+ /// Source is the source package name this binary was built from (one source can produce
+ /// multiple binary packages)
+ ///
+ /// Source is the source repository information for development (typically git repo, used
+ /// when passing --prefer-source). Originates from source code repository.
+ ///
+ /// Source is the source registry or repository where this crate came from
+ ///
+ /// Source is the source registry or repository URL in format
+ /// "registry+https://github.com/rust-lang/crates.io-index" for registry packages
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("source")]
public SourceUnion? Source { get; set; }
+
+ ///
+ /// SourceVersion is the source package version (may differ from binary version when binNMU
+ /// rebuilds occur)
+ ///
+ /// SourceVersion is the source code version identifier
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sourceVersion")]
public string SourceVersion { get; set; }
+
+ ///
+ /// Commit is the commit hash of the source repository for which the binary was built from
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("commit")]
public string Commit { get; set; }
+
+ ///
+ /// OS is the OS name, typically corresponding to ID in os-release (e.g. "fedora")
+ ///
+ /// OperatingSystem is the target OS for build constraints (e.g., "linux", "darwin",
+ /// "windows").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("os")]
public string Os { get; set; }
+
+ ///
+ /// OSCPE is a CPE name for the OS, typically corresponding to CPE_NAME in os-release (e.g.
+ /// cpe:/o:fedoraproject:fedora:33)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("osCPE")]
public string OsCpe { get; set; }
+
+ ///
+ /// osVersion is the version of the OS, typically corresponding to VERSION_ID in os-release
+ /// (e.g. "33")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("osVersion")]
public string OsVersion { get; set; }
+
+ ///
+ /// SourceRepo is the URL to the source repository for which the binary was built from
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sourceRepo")]
public string SourceRepo { get; set; }
+
+ ///
+ /// System is a context-specific name for the system that the binary package is intended to
+ /// run on or a part of
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("system")]
public string System { get; set; }
+
+ ///
+ /// Vendor is the individual or organization that produced the source code for the binary
+ ///
+ /// Vendor is the organization that packaged the software.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("vendor")]
public string Vendor { get; set; }
+
+ ///
+ /// PkgHash is the outer checksum (SHA-256) of the entire Hex package tarball for integrity
+ /// verification (preferred method, replaces deprecated inner checksum)
+ ///
+ /// PkgHash is the outer checksum (SHA-256) of the entire Hex package tarball for integrity
+ /// verification (preferred method over deprecated inner checksum)
+ ///
+ /// PkgHash is the package content hash for verification
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("pkgHash")]
public string PkgHash { get; set; }
+
+ ///
+ /// PkgHashExt is the extended package hash format (inner checksum is deprecated - SHA-256 of
+ /// concatenated file contents excluding CHECKSUM file, now replaced by outer checksum)
+ ///
+ /// PkgHashExt is the extended package hash format (inner checksum deprecated - was SHA-256
+ /// of concatenated file contents)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("pkgHashExt")]
public string PkgHashExt { get; set; }
+
+ ///
+ /// Comment is the inline comment associated with this uses statement
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("comment")]
public string Comment { get; set; }
+
+ ///
+ /// Value is the action reference (e.g. "actions/checkout@v3")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("value")]
public string Value { get; set; }
+
+ ///
+ /// BuildSettings contains the Go build settings and flags used to compile the binary (e.g.,
+ /// GOARCH, GOOS, CGO_ENABLED).
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("goBuildSettings")]
public VersionResourceElement[] GoBuildSettings { get; set; }
+
+ ///
+ /// GoCompiledVersion is the version of Go used to compile the binary.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("goCompiledVersion")]
public string GoCompiledVersion { get; set; }
+
+ ///
+ /// GoCryptoSettings contains FIPS and cryptographic configuration settings if present.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("goCryptoSettings")]
public string[] GoCryptoSettings { get; set; }
+
+ ///
+ /// GoExperiments lists experimental Go features enabled during compilation (e.g., "arenas",
+ /// "cgocheck2").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("goExperiments")]
public string[] GoExperiments { get; set; }
+
+ ///
+ /// H1Digest is the Go module hash in h1: format for the main module from go.sum.
+ ///
+ /// H1Digest is the Go module hash in h1: format from go.sum for verifying module contents.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("h1Digest")]
public string H1Digest { get; set; }
+
+ ///
+ /// MainModule is the main module path for the binary (e.g., "github.com/anchore/syft").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("mainModule")]
public string MainModule { get; set; }
+
+ ///
+ /// BuildTags are the build tags used to conditionally compile code (e.g.,
+ /// "integration,debug").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("buildTags")]
public string BuildTags { get; set; }
+
+ ///
+ /// CgoEnabled indicates whether CGO was enabled for this package.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("cgoEnabled")]
public bool? CgoEnabled { get; set; }
+
+ ///
+ /// SnapshotURL is the URL to the Stack snapshot this package came from
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("snapshotURL")]
public string SnapshotUrl { get; set; }
+
+ ///
+ /// Tap is Homebrew tap this formula belongs to (e.g. "homebrew/core")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("tap")]
public string Tap { get; set; }
+
+ ///
+ /// ArchiveDigests is cryptographic hashes of the archive file
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("digest")]
public DigestElement[] Digest { get; set; }
+
+ ///
+ /// Manifest is parsed META-INF/MANIFEST.MF contents
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("manifest")]
public Manifest Manifest { get; set; }
+
+ ///
+ /// PomProject is parsed pom.xml file contents
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("pomProject")]
public PomProject PomProject { get; set; }
+
+ ///
+ /// PomProperties is parsed pom.properties file contents
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("pomProperties")]
public PomProperties PomProperties { get; set; }
+
+ ///
+ /// VirtualPath is path within the archive hierarchy, where nested entries are delimited with
+ /// ':' (for nested JARs)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("virtualPath")]
public string VirtualPath { get; set; }
+
+ ///
+ /// Release is JVM release information and version details
+ ///
+ /// Release is the package release number or distribution-specific version suffix.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("release")]
public ReleaseUnion? Release { get; set; }
+
+ ///
+ /// Author is package author name
+ ///
+ /// Author is who built the kernel
+ ///
+ /// Author is module author name and email
+ ///
+ /// Author is the package author name from the Author field.
+ ///
+ /// Author is package author(s)
+ ///
+ /// Author is author name
+ ///
+ /// Author is plugin author name
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("author")]
public string Author { get; set; }
+
+ ///
+ /// Private is whether this is a private package
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("private")]
public bool? Private { get; set; }
+
+ ///
+ /// Integrity is Subresource Integrity hash for verification using standard SRI format
+ /// (sha512-... or sha1-...). npm changed from SHA-1 to SHA-512 in newer versions. For
+ /// registry sources this is the integrity from registry, for remote tarballs it's SHA-512 of
+ /// the file. npm verifies tarball matches this hash before unpacking, throwing EINTEGRITY
+ /// error if mismatch detected.
+ ///
+ /// Integrity is Subresource Integrity hash for verification (SRI format)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("integrity")]
public string Integrity { get; set; }
+
+ ///
+ /// Resolved is URL where this package was downloaded from (registry source)
+ ///
+ /// Resolved is URL where this package was downloaded from
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("resolved")]
public string Resolved { get; set; }
+
+ ///
+ /// BuildTime is when the kernel was built
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("buildTime")]
public string BuildTime { get; set; }
+
+ ///
+ /// ExtendedVersion is additional version information
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("extendedVersion")]
public string ExtendedVersion { get; set; }
+
+ ///
+ /// Format is kernel image format (e.g. bzImage, zImage)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("format")]
public string Format { get; set; }
+
+ ///
+ /// RootDevice is root device number
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("rootDevice")]
public long? RootDevice { get; set; }
+
+ ///
+ /// RWRootFS is whether root filesystem is mounted read-write
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("rwRootFS")]
public bool? RwRootFs { get; set; }
+
+ ///
+ /// SwapDevice is swap device number
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("swapDevice")]
public long? SwapDevice { get; set; }
+
+ ///
+ /// VideoMode is default video mode setting
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("videoMode")]
public string VideoMode { get; set; }
+
+ ///
+ /// KernelVersion is kernel version this module was built for
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("kernelVersion")]
public string KernelVersion { get; set; }
+
+ ///
+ /// Parameters are the module parameters that can be configured at load time (user-settable
+ /// values like module options)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("parameters")]
public Dictionary Parameters { get; set; }
+
+ ///
+ /// VersionMagic is version magic string for compatibility checking (includes kernel version,
+ /// SMP status, module loading capabilities like "3.17.4-302.fc21.x86_64 SMP mod_unload
+ /// modversions"). Module will NOT load if vermagic doesn't match running kernel.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("versionMagic")]
public string VersionMagic { get; set; }
+
+ ///
+ /// Dependencies are the map of dependency names to version constraints
+ ///
+ /// Dependencies are the list of required dependencies
+ ///
+ /// Dependencies are the dependency specifications, without environment qualifiers
+ ///
+ /// Dependencies are the package's runtime dependencies with version constraints.
+ ///
+ /// Dependencies are the list of dependencies with version constraints
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("dependencies")]
public Dependencies? Dependencies { get; set; }
+
+ ///
+ /// Kb is Knowledge Base article number (e.g. "5001028")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("kb")]
public string Kb { get; set; }
+
+ ///
+ /// ProductID is MSRC Product ID (e.g. "Windows 10 Version 1703 for 32-bit Systems")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("product_id")]
public string ProductId { get; set; }
+
+ ///
+ /// Derivation is information about the .drv file that describes how this package was built
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("derivation")]
public Derivation Derivation { get; set; }
+
+ ///
+ /// Output is the specific output name for multi-output packages (empty string for default
+ /// "out" output, can be "bin", "dev", "doc", etc.)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("output")]
public string Output { get; set; }
+
+ ///
+ /// OutputHash is hash prefix of the store path basename (first part before the dash)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("outputHash")]
public string OutputHash { get; set; }
+
+ ///
+ /// Licenses are the list of applicable licenses
+ ///
+ /// Licenses is license string which may be an expression (e.g. "GPL-2 OR Apache-2.0")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("licenses")]
public Checksum? Licenses { get; set; }
+
+ ///
+ /// VersionResources contains key-value pairs extracted from the PE file's version resource
+ /// section (e.g., FileVersion, ProductName, CompanyName).
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("VersionResources")]
public VersionResourceElement[] VersionResources { get; set; }
+
+ ///
+ /// Authors are the list of package authors with name/email/homepage
+ ///
+ /// Authors are the list of gem authors (stored as array regardless of using `author` or
+ /// `authors` method in gemspec)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("authors")]
public Author[] Authors { get; set; }
+
+ ///
+ /// Bin is the list of binary/executable files that should be added to PATH
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("bin")]
public string[] Bin { get; set; }
+
+ ///
+ /// Dist is distribution archive information for production (typically zip/tar, default
+ /// install method). Packaged version of released code.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("dist")]
public Dist Dist { get; set; }
+
+ ///
+ /// Keywords are the list of keywords for package discovery/search
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("keywords")]
public string[] Keywords { get; set; }
+
+ ///
+ /// NotificationURL is the URL to notify when package is installed (for tracking/statistics)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("notification-url")]
public string NotificationUrl { get; set; }
+
+ ///
+ /// Provide is virtual packages/functionality provided by this package (allows other packages
+ /// to depend on capabilities)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("provide")]
public Dictionary Provide { get; set; }
+
+ ///
+ /// Require is runtime dependencies with version constraints (package will not install unless
+ /// these requirements can be met)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("require")]
public Dictionary Require { get; set; }
+
+ ///
+ /// RequireDev is development-only dependencies (not installed in production, only when
+ /// developing this package or running tests)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("require-dev")]
public Dictionary RequireDev { get; set; }
+
+ ///
+ /// Suggest is optional but recommended dependencies (suggestions for packages that would
+ /// extend functionality)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("suggest")]
public Dictionary Suggest { get; set; }
+
+ ///
+ /// Time is timestamp when this package version was released
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("time")]
public string Time { get; set; }
+
+ ///
+ /// AuthorEmail is the package author's email address from the Author-Email field.
+ ///
+ /// AuthorEmail is author email address
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("authorEmail")]
public string AuthorEmail { get; set; }
+
+ ///
+ /// DirectURLOrigin contains VCS or direct URL installation information from direct_url.json.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("directUrlOrigin")]
public DirectUrlOrigin DirectUrlOrigin { get; set; }
+
+ ///
+ /// Platform indicates the target platform for the package (e.g., "any", "linux", "win32").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("platform")]
public string Platform { get; set; }
+
+ ///
+ /// ProvidesExtra lists optional feature names that can be installed via extras (e.g., "dev",
+ /// "test").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("providesExtra")]
public string[] ProvidesExtra { get; set; }
+
+ ///
+ /// RequiresDist lists the package dependencies with version specifiers from Requires-Dist
+ /// fields.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("requiresDist")]
public string[] RequiresDist { get; set; }
+
+ ///
+ /// RequiresPython specifies the Python version requirement (e.g., ">=3.6").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("requiresPython")]
public string RequiresPython { get; set; }
+
+ ///
+ /// SitePackagesRootPath is the root directory path containing the package (e.g.,
+ /// "/usr/lib/python3.9/site-packages").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sitePackagesRootPath")]
public string SitePackagesRootPath { get; set; }
+
+ ///
+ /// TopLevelPackages are the top-level Python module names from top_level.txt file.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("topLevelPackages")]
public string[] TopLevelPackages { get; set; }
+
+ ///
+ /// Summary provides a description of the package
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("summary")]
public string Summary { get; set; }
+
+ ///
+ /// Extras are the optional features to install from the package (e.g., package[dev,test]).
+ ///
+ /// Extras are optional feature groups that include additional dependencies.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("extras")]
public Extra[] Extras { get; set; }
+
+ ///
+ /// Markers are environment marker expressions for conditional installation (e.g.,
+ /// "python_version >= '3.8'").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("markers")]
public string Markers { get; set; }
+
+ ///
+ /// VersionConstraint specifies version requirements.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("versionConstraint")]
public string VersionConstraint { get; set; }
+
+ ///
+ /// Hashes are the package file hash values in the format "algorithm:digest" for integrity
+ /// verification.
+ ///
+ /// Hashes are cryptographic checksums for the provider plugin archives across different
+ /// platforms.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("hashes")]
public string[] Hashes { get; set; }
+
+ ///
+ /// Index is the PyPI index name where the package should be fetched from.
+ ///
+ /// Index is the package repository name where the package should be fetched from.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("index")]
public string Index { get; set; }
+
+ ///
+ /// Built is R version and platform this was built with
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("built")]
public string Built { get; set; }
+
+ ///
+ /// Imports are the packages imported in the NAMESPACE
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("imports")]
public string[] Imports { get; set; }
+
+ ///
+ /// NeedsCompilation is whether this package requires compilation
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("needsCompilation")]
public bool? NeedsCompilation { get; set; }
+
+ ///
+ /// Suggests are the optional packages that extend functionality
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("suggests")]
public string[] Suggests { get; set; }
+
+ ///
+ /// Title is short one-line package title
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("title")]
public string Title { get; set; }
+ [JsonPropertyName("epoch")]
public long? Epoch { get; set; }
+
+ ///
+ /// ModularityLabel identifies the module stream for modular RPM packages (e.g.,
+ /// "nodejs:12:20200101").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("modularityLabel")]
public string ModularityLabel { get; set; }
+
+ ///
+ /// Signatures contains GPG signature metadata for package verification.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("signatures")]
public SignatureElement[] Signatures { get; set; }
+
+ ///
+ /// SourceRpm is the source RPM filename that was used to build this package.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sourceRpm")]
public string SourceRpm { get; set; }
+
+ ///
+ /// Base is the base snap name that this snap depends on (e.g., "core20", "core22").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("base")]
public string Base { get; set; }
+
+ ///
+ /// SnapName is the snap package name.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("snapName")]
public string SnapName { get; set; }
+
+ ///
+ /// SnapType indicates the snap type (base, kernel, app, gadget, or snapd).
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("snapType")]
public string SnapType { get; set; }
+
+ ///
+ /// SnapVersion is the snap package version.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("snapVersion")]
public string SnapVersion { get; set; }
+
+ ///
+ /// PackagerEmail is packager email address
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("packagerEmail")]
public string PackagerEmail { get; set; }
+
+ ///
+ /// Constraints specifies the version constraints for the provider (e.g., "~> 4.0").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("constraints")]
public string Constraints { get; set; }
+
+ ///
+ /// AuthorURI is author's website URL
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("authorUri")]
public string AuthorUri { get; set; }
+
+ ///
+ /// PluginInstallDirectory is directory name where the plugin is installed
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("pluginInstallDirectory")]
public string PluginInstallDirectory { get; set; }
}
+///
+/// PhpComposerAuthors represents author information for a PHP Composer package from the
+/// authors field in composer.json.
+///
public partial class AuthorClass
{
+ ///
+ /// Email is author's email address
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("email")]
public string Email { get; set; }
+
+ ///
+ /// Homepage is author's personal or company website
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("homepage")]
public string Homepage { get; set; }
+
+ ///
+ /// Name is author's full name
+ ///
+ [JsonPropertyName("name")]
public string Name { get; set; }
}
public partial class BackupElement
{
+ ///
+ /// Digests contains file content hashes for integrity verification
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("digest")]
public DigestElement[] Digest { get; set; }
+
+ ///
+ /// GID is the file owner group ID as recorded by pacman
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("gid")]
public string Gid { get; set; }
+
+ ///
+ /// Link is the symlink target path if this is a symlink
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("link")]
public string Link { get; set; }
+
+ ///
+ /// Path is the file path relative to the filesystem root
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("path")]
public string Path { get; set; }
+
+ ///
+ /// Size is the file size in bytes
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("size")]
public string Size { get; set; }
+
+ ///
+ /// Time is the file modification timestamp
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("time")]
public DateTimeOffset? Time { get; set; }
+
+ ///
+ /// Type is the file type (e.g. regular file, directory, symlink)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ ///
+ /// UID is the file owner user ID as recorded by pacman
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("uid")]
public string Uid { get; set; }
}
+///
+/// Digest represents a cryptographic hash of file contents.
+///
+/// Digest is the file content hash for integrity verification
+///
+/// Digest is the file content hash (typically MD5 for dpkg compatibility with legacy
+/// systems)
+///
+/// Digest is file content hash (MD5 for regular files in CONTENTS format: "obj filename
+/// md5hash mtime")
+///
+/// Digest contains the hash algorithm and value for file integrity verification.
+///
public partial class DigestElement
{
+ ///
+ /// Algorithm specifies the hash algorithm used (e.g., "sha256", "md5").
+ ///
+ [JsonPropertyName("algorithm")]
public string Algorithm { get; set; }
+
+ ///
+ /// Value is the hexadecimal string representation of the hash.
+ ///
+ [JsonPropertyName("value")]
public string Value { get; set; }
}
+///
+/// PythonPoetryLockDependencyEntry represents a single dependency entry within a Poetry lock
+/// file.
+///
+/// PythonUvLockDependencyEntry represents a single dependency entry within a uv lock file.
+///
public partial class DependencyClass
{
+ ///
+ /// Extras are the optional feature names from the dependency that should be installed.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("extras")]
public string[] Extras { get; set; }
+
+ ///
+ /// Markers are environment marker expressions that conditionally enable the dependency
+ /// (e.g., "python_version >= '3.8'").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("markers")]
public string Markers { get; set; }
+
+ ///
+ /// Name is the dependency package name.
+ ///
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ ///
+ /// Optional indicates whether this dependency is optional (only needed for certain extras).
+ ///
+ [JsonPropertyName("optional")]
public bool Optional { get; set; }
+
+ ///
+ /// Version is the locked version or version constraint for the dependency.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
+///
+/// Derivation is information about the .drv file that describes how this package was built
+///
+/// NixDerivation represents a Nix .drv file that describes how to build a package including
+/// inputs, outputs, and build instructions.
+///
public partial class Derivation
{
+ ///
+ /// InputDerivations are the list of other derivations that were inputs to this build
+ /// (dependencies)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("inputDerivations")]
public InputDerivationElement[] InputDerivations { get; set; }
+
+ ///
+ /// InputSources are the list of source file paths that were inputs to this build
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("inputSources")]
public string[] InputSources { get; set; }
+
+ ///
+ /// Path is path to the .drv file in Nix store
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("path")]
public string Path { get; set; }
+
+ ///
+ /// System is target system string indicating where derivation can be built (e.g.
+ /// "x86_64-linux", "aarch64-darwin"). Must match current system for local builds.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("system")]
public string System { get; set; }
}
+///
+/// NixDerivationReference represents a reference to another derivation used as a build input
+/// or runtime dependency.
+///
public partial class InputDerivationElement
{
+ ///
+ /// Outputs are which outputs of the referenced derivation were used (e.g. ["out"], ["bin",
+ /// "dev"])
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("outputs")]
public string[] Outputs { get; set; }
+
+ ///
+ /// Path is path to the referenced .drv file
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("path")]
public string Path { get; set; }
}
+///
+/// DirectURLOrigin contains VCS or direct URL installation information from
+/// direct_url.json.
+///
+/// PythonDirectURLOriginInfo represents installation source metadata from direct_url.json
+/// for packages installed from VCS or direct URLs.
+///
public partial class DirectUrlOrigin
{
+ ///
+ /// CommitID is the VCS commit hash if installed from version control.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("commitId")]
public string CommitId { get; set; }
+
+ ///
+ /// URL is the source URL from which the package was installed.
+ ///
+ [JsonPropertyName("url")]
public string Url { get; set; }
+
+ ///
+ /// VCS is the version control system type (e.g., "git", "hg").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("vcs")]
public string Vcs { get; set; }
}
+///
+/// Dist is distribution archive information for production (typically zip/tar, default
+/// install method). Packaged version of released code.
+///
+/// PhpComposerExternalReference represents source or distribution information for a PHP
+/// package, indicating where the package code is retrieved from.
+///
+/// Source is the source repository information for development (typically git repo, used
+/// when passing --prefer-source). Originates from source code repository.
+///
public partial class Dist
{
+ ///
+ /// Reference is git commit hash or version tag for source, or archive version for dist
+ ///
+ [JsonPropertyName("reference")]
public string Reference { get; set; }
+
+ ///
+ /// Shasum is SHA hash of the archive file for integrity verification (dist only)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("shasum")]
public string Shasum { get; set; }
+
+ ///
+ /// Type is reference type (git for source VCS, zip/tar for dist archives)
+ ///
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ ///
+ /// URL is the URL to the resource (git repository URL or archive download URL)
+ ///
+ [JsonPropertyName("url")]
public string Url { get; set; }
}
+///
+/// Environment is SDK version constraints for Dart and Flutter
+///
+/// DartPubspecEnvironment represents SDK version constraints from the environment section of
+/// pubspec.yaml.
+///
public partial class Environment
{
+ ///
+ /// Flutter is the Flutter SDK version constraint if this is a Flutter package
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("flutter")]
public string Flutter { get; set; }
+
+ ///
+ /// SDK is the Dart SDK version constraint
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sdk")]
public string Sdk { get; set; }
}
+///
+/// DotnetPortableExecutableEntry is a struct that represents a single entry found within
+/// "VersionResources" section of a .NET Portable Executable binary file.
+///
public partial class ExecutableValue
{
+ ///
+ /// AssemblyVersion is the .NET assembly version number (strong-named version)
+ ///
+ [JsonPropertyName("assemblyVersion")]
public string AssemblyVersion { get; set; }
+
+ ///
+ /// Comments are additional comments or description embedded in PE resources
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("comments")]
public string Comments { get; set; }
+
+ ///
+ /// CompanyName is the company that produced the file
+ ///
+ [JsonPropertyName("companyName")]
public string CompanyName { get; set; }
+
+ ///
+ /// InternalName is the internal name of the file
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("internalName")]
public string InternalName { get; set; }
+
+ ///
+ /// LegalCopyright is the copyright notice string
+ ///
+ [JsonPropertyName("legalCopyright")]
public string LegalCopyright { get; set; }
+
+ ///
+ /// ProductName is the name of the product this file is part of
+ ///
+ [JsonPropertyName("productName")]
public string ProductName { get; set; }
+
+ ///
+ /// ProductVersion is the version of the product (may differ from AssemblyVersion)
+ ///
+ [JsonPropertyName("productVersion")]
public string ProductVersion { get; set; }
}
+///
+/// PythonPoetryLockExtraEntry represents an optional feature group in a Poetry lock file.
+///
+/// PythonUvLockExtraEntry represents an optional feature group in a uv lock file.
+///
public partial class ExtraClass
{
+ ///
+ /// Dependencies are the package names required when this extra is installed.
+ ///
+ [JsonPropertyName("dependencies")]
public string[] Dependencies { get; set; }
+
+ ///
+ /// Name is the optional feature name (e.g., "dev", "test").
+ ///
+ [JsonPropertyName("name")]
public string Name { get; set; }
}
+///
+/// ApkFileRecord represents a single file listing and metadata from a APK DB entry (which
+/// may have many of these file records).
+///
+/// DpkgFileRecord represents a single file attributed to a debian package.
+///
+/// PortageFileRecord represents a single file attributed to a portage package.
+///
+/// PythonFileRecord represents a single entry within a RECORD file for a python wheel or egg
+/// package
+///
+/// RpmFileRecord represents the file metadata for a single file attributed to a RPM package.
+///
public partial class FileFile
{
+ ///
+ /// Digests contains file content hashes for integrity verification
+ ///
+ /// Digest is the file content hash for integrity verification
+ ///
+ /// Digest is the file content hash (typically MD5 for dpkg compatibility with legacy
+ /// systems)
+ ///
+ /// Digest is file content hash (MD5 for regular files in CONTENTS format: "obj filename
+ /// md5hash mtime")
+ ///
+ /// Digest contains the hash algorithm and value for file integrity verification.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("digest")]
public Digest? Digest { get; set; }
+
+ ///
+ /// GID is the file owner group ID as recorded by pacman
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("gid")]
public string Gid { get; set; }
+
+ ///
+ /// Link is the symlink target path if this is a symlink
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("link")]
public string Link { get; set; }
+
+ ///
+ /// Path is the file path relative to the filesystem root
+ ///
+ /// Path is the installed file path from the RECORD file.
+ ///
+ /// Path is the absolute file path where the file is installed.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("path")]
public string Path { get; set; }
+
+ ///
+ /// Size is the file size in bytes
+ ///
+ /// Size is the file size in bytes as a string.
+ ///
+ /// Size is the file size in bytes.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("size")]
public Timestamp? Size { get; set; }
+
+ ///
+ /// Time is the file modification timestamp
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("time")]
public DateTimeOffset? Time { get; set; }
+
+ ///
+ /// Type is the file type (e.g. regular file, directory, symlink)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ ///
+ /// UID is the file owner user ID as recorded by pacman
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("uid")]
public string Uid { get; set; }
+
+ ///
+ /// OwnerGID is the file owner group ID
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("ownerGid")]
public string OwnerGid { get; set; }
+
+ ///
+ /// OwnerUID is the file owner user ID
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("ownerUid")]
public string OwnerUid { get; set; }
+
+ ///
+ /// Permissions is the file permission mode string (e.g. "0755", "0644")
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("permissions")]
public string Permissions { get; set; }
+
+ ///
+ /// IsConfigFile is whether this file is marked as a configuration file (dpkg will preserve
+ /// user modifications during upgrades)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("isConfigFile")]
public bool? IsConfigFile { get; set; }
+
+ ///
+ /// Flags indicates the file type (e.g., "%config", "%doc", "%ghost").
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("flags")]
public string Flags { get; set; }
+
+ ///
+ /// GroupName is the group name for the file.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("groupName")]
public string GroupName { get; set; }
+
+ ///
+ /// Mode is the file permission mode bits following Unix stat.h conventions.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("mode")]
public long? Mode { get; set; }
+
+ ///
+ /// UserName is the owner username for the file.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("userName")]
public string UserName { get; set; }
}
-public partial class PurpleSyftOutpu
+///
+/// Digest represents a cryptographic hash of file contents.
+///
+/// Digest is the file content hash for integrity verification
+///
+/// Digest is the file content hash (typically MD5 for dpkg compatibility with legacy
+/// systems)
+///
+/// Digest is file content hash (MD5 for regular files in CONTENTS format: "obj filename
+/// md5hash mtime")
+///
+/// Digest contains the hash algorithm and value for file integrity verification.
+///
+/// PythonFileDigest represents the file metadata for a single file attributed to a python
+/// package.
+///
+public partial class PurpleSyftOutput
{
+ ///
+ /// Algorithm specifies the hash algorithm used (e.g., "sha256", "md5").
+ ///
+ /// Algorithm is the hash algorithm used (e.g., "sha256").
+ ///
+ [JsonPropertyName("algorithm")]
public string Algorithm { get; set; }
+
+ ///
+ /// Value is the hexadecimal string representation of the hash.
+ ///
+ /// Value is the hex-encoded hash digest value.
+ ///
+ [JsonPropertyName("value")]
public string Value { get; set; }
}
+///
+/// Options are package configuration options as key-value pairs (e.g. shared=True,
+/// fPIC=True)
+///
+/// KeyValues represents an ordered collection of key-value pairs that preserves insertion
+/// order.
+///
+/// KeyValue represents a single key-value pair.
+///
public partial class VersionResourceElement
{
+ ///
+ /// Key is the key name
+ ///
+ [JsonPropertyName("key")]
public string Key { get; set; }
+
+ ///
+ /// Value is the value associated with the key
+ ///
+ [JsonPropertyName("value")]
public string Value { get; set; }
}
+///
+/// Link contains installation source metadata from the link.json file.
+///
+/// CondaLink represents link metadata from a Conda package's link.json file describing
+/// package installation source.
+///
public partial class Link
{
+ ///
+ /// Source is the original path where the package was extracted from cache.
+ ///
+ [JsonPropertyName("source")]
public string Source { get; set; }
+
+ ///
+ /// Type indicates the link type (1 for hard link, 2 for soft link, 3 for copy).
+ ///
+ [JsonPropertyName("type")]
public long Type { get; set; }
}
+///
+/// Manifest is parsed META-INF/MANIFEST.MF contents
+///
+/// JavaManifest represents the fields of interest extracted from a Java archive's
+/// META-INF/MANIFEST.MF file.
+///
public partial class Manifest
{
+ ///
+ /// Main is main manifest attributes as key-value pairs
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("main")]
public VersionResourceElement[] Main { get; set; }
+
+ ///
+ /// Sections are the named sections from the manifest (e.g. per-entry attributes)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sections")]
public VersionResourceElement[][] Sections { get; set; }
}
+///
+/// ClassifierMatch represents a single matched value within a binary file and the "class"
+/// name the search pattern represents.
+///
public partial class MatchElement
{
+ [JsonPropertyName("classifier")]
public string Classifier { get; set; }
+
+ [JsonPropertyName("location")]
public LocationElement Location { get; set; }
}
+///
+/// LinuxKernelModuleParameter represents a configurable parameter for a kernel module with
+/// its type and description.
+///
public partial class ParameterValue
{
+ ///
+ /// Description is a human-readable parameter description explaining what the parameter
+ /// controls
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("description")]
public string Description { get; set; }
+
+ ///
+ /// Type is parameter data type (e.g. int, string, bool, array types)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("type")]
public string Type { get; set; }
}
+///
+/// PathsData contains detailed file metadata from the paths.json file.
+///
+/// CondaPathsData represents the paths.json file structure from a Conda package containing
+/// file metadata.
+///
public partial class PathsData
{
+ ///
+ /// Paths is the list of file metadata entries for all files in the package.
+ ///
+ [JsonPropertyName("paths")]
public PathElement[] Paths { get; set; }
+
+ ///
+ /// PathsVersion is the schema version of the paths data format.
+ ///
+ [JsonPropertyName("paths_version")]
public long PathsVersion { get; set; }
}
+///
+/// CondaPathData represents metadata for a single file within a Conda package from the
+/// paths.json file.
+///
public partial class PathElement
{
+ ///
+ /// Path is the file path relative to the Conda environment root.
+ ///
+ [JsonPropertyName("_path")]
public string Path { get; set; }
+
+ ///
+ /// PathType indicates the link type for the file (e.g., "hardlink", "softlink", "directory").
+ ///
+ [JsonPropertyName("path_type")]
public string PathType { get; set; }
+
+ ///
+ /// SHA256 is the SHA-256 hash of the file contents.
+ ///
+ [JsonPropertyName("sha256")]
public string Sha256 { get; set; }
+
+ ///
+ /// SHA256InPrefix is the SHA-256 hash of the file after prefix replacement during
+ /// installation.
+ ///
+ [JsonPropertyName("sha256_in_prefix")]
public string Sha256InPrefix { get; set; }
+
+ ///
+ /// SizeInBytes is the file size in bytes.
+ ///
+ [JsonPropertyName("size_in_bytes")]
public long SizeInBytes { get; set; }
}
+///
+/// PomProject is parsed pom.xml file contents
+///
+/// JavaPomProject represents fields of interest extracted from a Java archive's pom.xml file.
+///
public partial class PomProject
{
+ ///
+ /// ArtifactID is Maven artifact identifier (project name)
+ ///
+ [JsonPropertyName("artifactId")]
public string ArtifactId { get; set; }
+
+ ///
+ /// Description is detailed project description
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("description")]
public string Description { get; set; }
+
+ ///
+ /// GroupID is Maven group identifier (reversed domain name like org.apache.maven)
+ ///
+ [JsonPropertyName("groupId")]
public string GroupId { get; set; }
+
+ ///
+ /// Name is a human-readable project name (displayed in Maven-generated documentation)
+ ///
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ ///
+ /// Parent is the parent POM reference for inheritance (child POMs inherit configuration from
+ /// parent)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("parent")]
public Parent Parent { get; set; }
+
+ ///
+ /// Path is path to the pom.xml file within the archive
+ ///
+ [JsonPropertyName("path")]
public string Path { get; set; }
+
+ ///
+ /// URL is the project URL (typically project website or repository)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("url")]
public string Url { get; set; }
+
+ ///
+ /// Version is project version (together with groupId and artifactId forms Maven coordinates
+ /// groupId:artifactId:version)
+ ///
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
+///
+/// Parent is the parent POM reference for inheritance (child POMs inherit configuration from
+/// parent)
+///
+/// JavaPomParent contains the fields within the parent tag in a pom.xml file
+///
public partial class Parent
{
+ ///
+ /// ArtifactID is the parent Maven artifact identifier
+ ///
+ [JsonPropertyName("artifactId")]
public string ArtifactId { get; set; }
+
+ ///
+ /// GroupID is the parent Maven group identifier
+ ///
+ [JsonPropertyName("groupId")]
public string GroupId { get; set; }
+
+ ///
+ /// Version is the parent version (child inherits configuration from this specific version of
+ /// parent POM)
+ ///
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
+///
+/// PomProperties is parsed pom.properties file contents
+///
+/// JavaPomProperties represents the fields of interest extracted from a Java archive's
+/// pom.properties file.
+///
public partial class PomProperties
{
+ ///
+ /// ArtifactID is Maven artifact identifier, the name of the jar/artifact (unique within the
+ /// groupId scope)
+ ///
+ [JsonPropertyName("artifactId")]
public string ArtifactId { get; set; }
+
+ ///
+ /// Extra is additional custom properties not in standard Maven coordinates
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("extraFields")]
public Dictionary ExtraFields { get; set; }
+
+ ///
+ /// GroupID is Maven group identifier uniquely identifying the project across all projects
+ /// (follows reversed domain name convention like com.company.project)
+ ///
+ [JsonPropertyName("groupId")]
public string GroupId { get; set; }
+
+ ///
+ /// Name is the project name
+ ///
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ ///
+ /// Path is path to the pom.properties file within the archive
+ ///
+ [JsonPropertyName("path")]
public string Path { get; set; }
+
+ ///
+ /// Scope is dependency scope determining when dependency is available (compile=default all
+ /// phases, test=test compilation/execution only, runtime=runtime and test not compile,
+ /// provided=expected from JDK or container)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("scope")]
public string Scope { get; set; }
+
+ ///
+ /// Version is artifact version
+ ///
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
+///
+/// Release is JVM release information and version details
+///
+/// JavaVMRelease represents JVM version and build information extracted from the release
+/// file in a Java installation.
+///
public partial class ReleaseClass
{
+ ///
+ /// BuildInfo contains additional build information
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("buildInfo")]
public string BuildInfo { get; set; }
+
+ ///
+ /// BuildSource Git SHA of the build repository
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("buildSource")]
public string BuildSource { get; set; }
+
+ ///
+ /// BuildSourceRepo refers to rhe repository URL for the build source
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("buildSourceRepo")]
public string BuildSourceRepo { get; set; }
+
+ ///
+ /// BuildType can be 'commercial' (used in some older oracle JDK distributions)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("buildType")]
public string BuildType { get; set; }
+
+ ///
+ /// FullVersion is extracted from the 'java.runtime.version' JVM property
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("fullVersion")]
public string FullVersion { get; set; }
+
+ ///
+ /// ImageType can be 'JDK' or 'JRE'
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("imageType")]
public string ImageType { get; set; }
+
+ ///
+ /// Implementor is extracted with the `java.vendor` JVM property
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("implementor")]
public string Implementor { get; set; }
+
+ ///
+ /// ImplementorVersion is extracted with the `java.vendor.version` JVM property
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("implementorVersion")]
public string ImplementorVersion { get; set; }
+
+ ///
+ /// JavaRuntimeVersion is extracted from the 'java.runtime.version' JVM property
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("javaRuntimeVersion")]
public string JavaRuntimeVersion { get; set; }
+
+ ///
+ /// JavaVersion matches that from `java -version` command output
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("javaVersion")]
public string JavaVersion { get; set; }
+
+ ///
+ /// JavaVersionDate is extracted from the 'java.version.date' JVM property
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("javaVersionDate")]
public string JavaVersionDate { get; set; }
+
+ ///
+ /// JvmVariant specifies the JVM variant (e.g., Hotspot or OpenJ9)
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("jvmVariant")]
public string JvmVariant { get; set; }
+
+ ///
+ /// JvmVersion is extracted from the 'java.vm.version' JVM property
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("jvmVersion")]
public string JvmVersion { get; set; }
+
+ ///
+ /// Libc can either be 'glibc' or 'musl'
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("libc")]
public string Libc { get; set; }
+
+ ///
+ /// Modules is a list of JVM modules that are packaged
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("modules")]
public string[] Modules { get; set; }
+
+ ///
+ /// OsArch is the target CPU architecture
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("osArch")]
public string OsArch { get; set; }
+
+ ///
+ /// OsName is the name of the target runtime operating system environment
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("osName")]
public string OsName { get; set; }
+
+ ///
+ /// OsVersion is the version of the target runtime operating system environment
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("osVersion")]
public string OsVersion { get; set; }
+
+ ///
+ /// SemanticVersion is derived from the OpenJDK version
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("semanticVersion")]
public string SemanticVersion { get; set; }
+
+ ///
+ /// Source refers to the origin repository of OpenJDK source
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("source")]
public string Source { get; set; }
+
+ ///
+ /// SourceRepo refers to the OpenJDK repository URL
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sourceRepo")]
public string SourceRepo { get; set; }
}
+///
+/// RpmSignature represents a GPG signature for an RPM package used for authenticity
+/// verification.
+///
public partial class SignatureElement
{
+ ///
+ /// PublicKeyAlgorithm is the public key algorithm used for signing (e.g., "RSA").
+ ///
+ [JsonPropertyName("algo")]
public string Algo { get; set; }
+
+ ///
+ /// Created is the timestamp when the signature was created.
+ ///
+ [JsonPropertyName("created")]
public string Created { get; set; }
+
+ ///
+ /// HashAlgorithm is the hash algorithm used for the signature (e.g., "SHA256").
+ ///
+ [JsonPropertyName("hash")]
public string Hash { get; set; }
+
+ ///
+ /// IssuerKeyID is the GPG key ID that created the signature.
+ ///
+ [JsonPropertyName("issuer")]
public string Issuer { get; set; }
}
+///
+/// Descriptor describes what created the document as well as surrounding metadata
+///
public partial class Descriptor
{
+ [JsonPropertyName("configuration")]
public object Configuration { get; set; }
+
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
public partial class Distro
{
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("bugReportURL")]
public string BugReportUrl { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("buildID")]
public string BuildId { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("cpeName")]
public string CpeName { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("extendedSupport")]
public bool? ExtendedSupport { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("homeURL")]
public string HomeUrl { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("id")]
public string Id { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("idLike")]
public string[] IdLike { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("imageID")]
public string ImageId { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("imageVersion")]
public string ImageVersion { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("prettyName")]
public string PrettyName { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("privacyPolicyURL")]
public string PrivacyPolicyUrl { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("supportEnd")]
public string SupportEnd { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("supportURL")]
public string SupportUrl { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("variant")]
public string Variant { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("variantID")]
public string VariantId { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("version")]
public string Version { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("versionCodename")]
public string VersionCodename { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("versionID")]
public string VersionId { get; set; }
}
public partial class FileElement
{
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("contents")]
public string Contents { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("digests")]
public DigestElement[] Digests { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("executable")]
public Executable Executable { get; set; }
+
+ [JsonPropertyName("id")]
public string Id { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("licenses")]
public FileLicense[] Licenses { get; set; }
+
+ [JsonPropertyName("location")]
public Location Location { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("metadata")]
public Metadata Metadata { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("unknowns")]
public string[] Unknowns { get; set; }
}
+///
+/// Executable contains metadata about binary files and their security features.
+///
public partial class Executable
{
+ ///
+ /// ELFSecurityFeatures contains ELF-specific security hardening information when Format is
+ /// ELF.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("elfSecurityFeatures")]
public ElfSecurityFeatures ElfSecurityFeatures { get; set; }
+
+ ///
+ /// Format denotes either ELF, Mach-O, or PE
+ ///
+ [JsonPropertyName("format")]
public string Format { get; set; }
+
+ ///
+ /// HasEntrypoint indicates whether the binary has an entry point function.
+ ///
+ [JsonPropertyName("hasEntrypoint")]
public bool HasEntrypoint { get; set; }
+
+ ///
+ /// HasExports indicates whether the binary exports symbols.
+ ///
+ [JsonPropertyName("hasExports")]
public bool HasExports { get; set; }
+
+ ///
+ /// ImportedLibraries lists the shared libraries required by this executable.
+ ///
+ [JsonPropertyName("importedLibraries")]
public string[] ImportedLibraries { get; set; }
}
+///
+/// ELFSecurityFeatures contains ELF-specific security hardening information when Format is
+/// ELF.
+///
+/// ELFSecurityFeatures captures security hardening and protection mechanisms in ELF binaries.
+///
public partial class ElfSecurityFeatures
{
+ ///
+ /// ControlFlowIntegrity represents runtime checks to ensure a program's control flow adheres
+ /// to the legal paths determined at compile time, thus protecting against various types of
+ /// control-flow hijacking attacks
+ /// see https://clang.llvm.org/docs/ControlFlowIntegrity.html
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("cfi")]
public bool? Cfi { get; set; }
+
+ ///
+ /// DynamicSharedObject indicates whether the binary is a shared library.
+ ///
+ [JsonPropertyName("dso")]
public bool Dso { get; set; }
+
+ ///
+ /// ClangFortifySource is a broad suite of extensions to libc aimed at catching misuses of
+ /// common library functions
+ /// see
+ /// https://android.googlesource.com/platform//bionic/+/d192dbecf0b2a371eb127c0871f77a9caf81c4d2/docs/clang_fortify_anatomy.md
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("fortify")]
public bool? Fortify { get; set; }
+
+ ///
+ /// NoExecutable indicates whether NX (no-execute) protection is enabled for the stack.
+ ///
+ [JsonPropertyName("nx")]
public bool Nx { get; set; }
+
+ ///
+ /// PositionIndependentExecutable indicates whether the binary is compiled as PIE.
+ ///
+ [JsonPropertyName("pie")]
public bool Pie { get; set; }
+
+ ///
+ /// RelocationReadOnly indicates the RELRO protection level.
+ ///
+ [JsonPropertyName("relRO")]
public string RelRo { get; set; }
+
+ ///
+ /// LlvmSafeStack represents a compiler-based security mechanism that separates the stack
+ /// into a safe stack for storing return addresses and other critical data, and an unsafe
+ /// stack for everything else, to mitigate stack-based memory corruption errors
+ /// see https://clang.llvm.org/docs/SafeStack.html
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("safeStack")]
public bool? SafeStack { get; set; }
+
+ ///
+ /// StackCanary indicates whether stack smashing protection is enabled.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("stackCanary")]
public bool? StackCanary { get; set; }
+
+ ///
+ /// SymbolTableStripped indicates whether debugging symbols have been removed.
+ ///
+ [JsonPropertyName("symbolTableStripped")]
public bool SymbolTableStripped { get; set; }
}
public partial class FileLicense
{
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("evidence")]
public Evidence Evidence { get; set; }
+
+ [JsonPropertyName("spdxExpression")]
public string SpdxExpression { get; set; }
+
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ [JsonPropertyName("value")]
public string Value { get; set; }
}
public partial class Evidence
{
+ [JsonPropertyName("confidence")]
public long Confidence { get; set; }
+
+ [JsonPropertyName("extent")]
public long Extent { get; set; }
+
+ [JsonPropertyName("offset")]
public long Offset { get; set; }
}
+///
+/// Coordinates contains the minimal information needed to describe how to find a file within
+/// any possible source object (e.g.
+///
public partial class Location
{
+ ///
+ /// FileSystemID is an ID representing and entire filesystem. For container images, this is a
+ /// layer digest. For directories or a root filesystem, this is blank.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("layerID")]
public string LayerId { get; set; }
+
+ ///
+ /// RealPath is the canonical absolute form of the path accessed (all symbolic links have
+ /// been followed and relative path components like '.' and '..' have been removed).
+ ///
+ [JsonPropertyName("path")]
public string Path { get; set; }
}
public partial class Metadata
{
+ [JsonPropertyName("groupID")]
public long GroupId { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("linkDestination")]
public string LinkDestination { get; set; }
+
+ [JsonPropertyName("mimeType")]
public string MimeType { get; set; }
+
+ [JsonPropertyName("mode")]
public long Mode { get; set; }
+
+ [JsonPropertyName("size")]
public long Size { get; set; }
+
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ [JsonPropertyName("userID")]
public long UserId { get; set; }
}
public partial class Schema
{
+ [JsonPropertyName("url")]
public string Url { get; set; }
+
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
+///
+/// Instead, the Supplier can be determined by the user of syft and passed as a config or
+/// flag to help fulfill the NTIA minimum elements.
+///
public partial class SourceClass
{
+ [JsonPropertyName("id")]
public string Id { get; set; }
+
+ [JsonPropertyName("metadata")]
public object Metadata { get; set; }
+
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("supplier")]
public string Supplier { get; set; }
+
+ [JsonPropertyName("type")]
public string Type { get; set; }
+
+ [JsonPropertyName("version")]
public string Version { get; set; }
}
@@ -622,10 +3297,10 @@ public partial struct Extra
public partial struct Digest
{
public DigestElement[] DigestElementArray;
- public PurpleSyftOutpu PurpleSyftOutpu;
+ public PurpleSyftOutput PurpleSyftOutput;
public static implicit operator Digest(DigestElement[] DigestElementArray) => new Digest { DigestElementArray = DigestElementArray };
- public static implicit operator Digest(PurpleSyftOutpu PurpleSyftOutpu) => new Digest { PurpleSyftOutpu = PurpleSyftOutpu };
+ public static implicit operator Digest(PurpleSyftOutput PurpleSyftOutput) => new Digest { PurpleSyftOutput = PurpleSyftOutput };
}
public partial struct Timestamp
@@ -663,3 +3338,509 @@ public partial struct SourceUnion
public static implicit operator SourceUnion(Dist Dist) => new SourceUnion { Dist = Dist };
public static implicit operator SourceUnion(string String) => new SourceUnion { String = String };
}
+
+public partial class SyftOutput
+{
+ public static SyftOutput FromJson(string json) => JsonSerializer.Deserialize(json, Microsoft.ComponentDetection.Detectors.Linux.Contracts.Converter.Settings);
+}
+
+public static class Serialize
+{
+ public static string ToJson(this SyftOutput self) => JsonSerializer.Serialize(self, Microsoft.ComponentDetection.Detectors.Linux.Contracts.Converter.Settings);
+}
+
+internal static class Converter
+{
+ public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)
+ {
+ Converters =
+ {
+ AuthorConverter.Singleton,
+ ChecksumConverter.Singleton,
+ DependenciesConverter.Singleton,
+ DependencyConverter.Singleton,
+ ExtraConverter.Singleton,
+ FileConverter.Singleton,
+ DigestConverter.Singleton,
+ TimestampConverter.Singleton,
+ ReleaseUnionConverter.Singleton,
+ SourceUnionConverter.Singleton,
+ new DateOnlyConverter(),
+ new TimeOnlyConverter(),
+ IsoDateTimeOffsetConverter.Singleton
+ },
+ };
+}
+
+internal class AuthorConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(Author);
+
+ public override Author Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new Author { String = stringValue };
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize(ref reader, options);
+ return new Author { AuthorClass = objectValue };
+ }
+ throw new Exception("Cannot unmarshal type Author");
+ }
+
+ public override void Write(Utf8JsonWriter writer, Author value, JsonSerializerOptions options)
+ {
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ if (value.AuthorClass != null)
+ {
+ JsonSerializer.Serialize(writer, value.AuthorClass, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type Author");
+ }
+
+ public static readonly AuthorConverter Singleton = new AuthorConverter();
+}
+
+internal class ChecksumConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(Checksum);
+
+ public override Checksum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new Checksum { String = stringValue };
+ case JsonTokenType.StartArray:
+ var arrayValue = JsonSerializer.Deserialize(ref reader, options);
+ return new Checksum { StringArray = arrayValue };
+ }
+ throw new Exception("Cannot unmarshal type Checksum");
+ }
+
+ public override void Write(Utf8JsonWriter writer, Checksum value, JsonSerializerOptions options)
+ {
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ if (value.StringArray != null)
+ {
+ JsonSerializer.Serialize(writer, value.StringArray, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type Checksum");
+ }
+
+ public static readonly ChecksumConverter Singleton = new ChecksumConverter();
+}
+
+internal class DependenciesConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(Dependencies);
+
+ public override Dependencies Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize>(ref reader, options);
+ return new Dependencies { StringMap = objectValue };
+ case JsonTokenType.StartArray:
+ var arrayValue = JsonSerializer.Deserialize(ref reader, options);
+ return new Dependencies { AnythingArray = arrayValue };
+ }
+ throw new Exception("Cannot unmarshal type Dependencies");
+ }
+
+ public override void Write(Utf8JsonWriter writer, Dependencies value, JsonSerializerOptions options)
+ {
+ if (value.AnythingArray != null)
+ {
+ JsonSerializer.Serialize(writer, value.AnythingArray, options);
+ return;
+ }
+ if (value.StringMap != null)
+ {
+ JsonSerializer.Serialize(writer, value.StringMap, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type Dependencies");
+ }
+
+ public static readonly DependenciesConverter Singleton = new DependenciesConverter();
+}
+
+internal class DependencyConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(Dependency);
+
+ public override Dependency Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new Dependency { String = stringValue };
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize(ref reader, options);
+ return new Dependency { DependencyClass = objectValue };
+ }
+ throw new Exception("Cannot unmarshal type Dependency");
+ }
+
+ public override void Write(Utf8JsonWriter writer, Dependency value, JsonSerializerOptions options)
+ {
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ if (value.DependencyClass != null)
+ {
+ JsonSerializer.Serialize(writer, value.DependencyClass, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type Dependency");
+ }
+
+ public static readonly DependencyConverter Singleton = new DependencyConverter();
+}
+
+internal class ExtraConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(Extra);
+
+ public override Extra Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new Extra { String = stringValue };
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize(ref reader, options);
+ return new Extra { ExtraClass = objectValue };
+ }
+ throw new Exception("Cannot unmarshal type Extra");
+ }
+
+ public override void Write(Utf8JsonWriter writer, Extra value, JsonSerializerOptions options)
+ {
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ if (value.ExtraClass != null)
+ {
+ JsonSerializer.Serialize(writer, value.ExtraClass, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type Extra");
+ }
+
+ public static readonly ExtraConverter Singleton = new ExtraConverter();
+}
+
+internal class FileConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(File);
+
+ public override File Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new File { String = stringValue };
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize(ref reader, options);
+ return new File { FileFile = objectValue };
+ }
+ throw new Exception("Cannot unmarshal type File");
+ }
+
+ public override void Write(Utf8JsonWriter writer, File value, JsonSerializerOptions options)
+ {
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ if (value.FileFile != null)
+ {
+ JsonSerializer.Serialize(writer, value.FileFile, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type File");
+ }
+
+ public static readonly FileConverter Singleton = new FileConverter();
+}
+
+internal class DigestConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(Digest);
+
+ public override Digest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize(ref reader, options);
+ return new Digest { PurpleSyftOutput = objectValue };
+ case JsonTokenType.StartArray:
+ var arrayValue = JsonSerializer.Deserialize(ref reader, options);
+ return new Digest { DigestElementArray = arrayValue };
+ }
+ throw new Exception("Cannot unmarshal type Digest");
+ }
+
+ public override void Write(Utf8JsonWriter writer, Digest value, JsonSerializerOptions options)
+ {
+ if (value.DigestElementArray != null)
+ {
+ JsonSerializer.Serialize(writer, value.DigestElementArray, options);
+ return;
+ }
+ if (value.PurpleSyftOutput != null)
+ {
+ JsonSerializer.Serialize(writer, value.PurpleSyftOutput, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type Digest");
+ }
+
+ public static readonly DigestConverter Singleton = new DigestConverter();
+}
+
+internal class TimestampConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(Timestamp);
+
+ public override Timestamp Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.Number:
+ var integerValue = reader.GetInt64();
+ return new Timestamp { Integer = integerValue };
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new Timestamp { String = stringValue };
+ }
+ throw new Exception("Cannot unmarshal type Timestamp");
+ }
+
+ public override void Write(Utf8JsonWriter writer, Timestamp value, JsonSerializerOptions options)
+ {
+ if (value.Integer != null)
+ {
+ JsonSerializer.Serialize(writer, value.Integer.Value, options);
+ return;
+ }
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type Timestamp");
+ }
+
+ public static readonly TimestampConverter Singleton = new TimestampConverter();
+}
+
+internal class ReleaseUnionConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(ReleaseUnion);
+
+ public override ReleaseUnion Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new ReleaseUnion { String = stringValue };
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize(ref reader, options);
+ return new ReleaseUnion { ReleaseClass = objectValue };
+ }
+ throw new Exception("Cannot unmarshal type ReleaseUnion");
+ }
+
+ public override void Write(Utf8JsonWriter writer, ReleaseUnion value, JsonSerializerOptions options)
+ {
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ if (value.ReleaseClass != null)
+ {
+ JsonSerializer.Serialize(writer, value.ReleaseClass, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type ReleaseUnion");
+ }
+
+ public static readonly ReleaseUnionConverter Singleton = new ReleaseUnionConverter();
+}
+
+internal class SourceUnionConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(SourceUnion);
+
+ public override SourceUnion Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ switch (reader.TokenType)
+ {
+ case JsonTokenType.String:
+ var stringValue = reader.GetString();
+ return new SourceUnion { String = stringValue };
+ case JsonTokenType.StartObject:
+ var objectValue = JsonSerializer.Deserialize(ref reader, options);
+ return new SourceUnion { Dist = objectValue };
+ }
+ throw new Exception("Cannot unmarshal type SourceUnion");
+ }
+
+ public override void Write(Utf8JsonWriter writer, SourceUnion value, JsonSerializerOptions options)
+ {
+ if (value.String != null)
+ {
+ JsonSerializer.Serialize(writer, value.String, options);
+ return;
+ }
+ if (value.Dist != null)
+ {
+ JsonSerializer.Serialize(writer, value.Dist, options);
+ return;
+ }
+ throw new Exception("Cannot marshal type SourceUnion");
+ }
+
+ public static readonly SourceUnionConverter Singleton = new SourceUnionConverter();
+}
+
+public class DateOnlyConverter : JsonConverter
+{
+ private readonly string serializationFormat;
+ public DateOnlyConverter() : this(null) { }
+
+ public DateOnlyConverter(string? serializationFormat)
+ {
+ this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
+ }
+
+ public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var value = reader.GetString();
+ return DateOnly.Parse(value!);
+ }
+
+ public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
+ => writer.WriteStringValue(value.ToString(serializationFormat));
+}
+
+public class TimeOnlyConverter : JsonConverter
+{
+ private readonly string serializationFormat;
+
+ public TimeOnlyConverter() : this(null) { }
+
+ public TimeOnlyConverter(string? serializationFormat)
+ {
+ this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
+ }
+
+ public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var value = reader.GetString();
+ return TimeOnly.Parse(value!);
+ }
+
+ public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
+ => writer.WriteStringValue(value.ToString(serializationFormat));
+}
+
+internal class IsoDateTimeOffsetConverter : JsonConverter
+{
+ public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);
+
+ private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
+
+ private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
+ private string? _dateTimeFormat;
+ private CultureInfo? _culture;
+
+ public DateTimeStyles DateTimeStyles
+ {
+ get => _dateTimeStyles;
+ set => _dateTimeStyles = value;
+ }
+
+ public string? DateTimeFormat
+ {
+ get => _dateTimeFormat ?? string.Empty;
+ set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
+ }
+
+ public CultureInfo Culture
+ {
+ get => _culture ?? CultureInfo.CurrentCulture;
+ set => _culture = value;
+ }
+
+ public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
+ {
+ string text;
+
+
+ if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
+ || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
+ {
+ value = value.ToUniversalTime();
+ }
+
+ text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
+
+ writer.WriteStringValue(text);
+ }
+
+ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ string? dateText = reader.GetString();
+
+ if (string.IsNullOrEmpty(dateText) == false)
+ {
+ if (!string.IsNullOrEmpty(_dateTimeFormat))
+ {
+ return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
+ }
+ else
+ {
+ return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
+ }
+ }
+ else
+ {
+ return default(DateTimeOffset);
+ }
+ }
+
+
+ public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
+}
+#pragma warning restore CS8618
+#pragma warning restore CS8601
+#pragma warning restore CS8603
diff --git a/src/Microsoft.ComponentDetection.Detectors/linux/LinuxScanner.cs b/src/Microsoft.ComponentDetection.Detectors/linux/LinuxScanner.cs
index e83340149..38817916c 100644
--- a/src/Microsoft.ComponentDetection.Detectors/linux/LinuxScanner.cs
+++ b/src/Microsoft.ComponentDetection.Detectors/linux/LinuxScanner.cs
@@ -4,6 +4,7 @@ namespace Microsoft.ComponentDetection.Detectors.Linux;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.ComponentDetection.Common.Telemetry.Records;
@@ -14,7 +15,6 @@ namespace Microsoft.ComponentDetection.Detectors.Linux;
using Microsoft.ComponentDetection.Detectors.Linux.Factories;
using Microsoft.ComponentDetection.Detectors.Linux.Filters;
using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
///
/// Scanner for Linux container layers using Syft.
@@ -129,7 +129,7 @@ public async Task> ScanLinuxAsync(
}
catch (Exception e)
{
- syftTelemetryRecord.Exception = JsonConvert.SerializeObject(e);
+ syftTelemetryRecord.Exception = JsonSerializer.Serialize(e);
this.logger.LogError(e, "Failed to run syft");
throw;
}
@@ -167,7 +167,7 @@ public async Task> ScanLinuxAsync(
try
{
- var syftOutput = JsonConvert.DeserializeObject(stdout);
+ var syftOutput = SyftOutput.FromJson(stdout);
// Apply artifact filters (e.g., Mariner 2.0 workaround)
var validArtifacts = syftOutput.Artifacts.AsEnumerable();
@@ -230,7 +230,7 @@ public async Task> ScanLinuxAsync(
});
// Track detected components in telemetry
- syftTelemetryRecord.Components = JsonConvert.SerializeObject(
+ syftTelemetryRecord.Components = JsonSerializer.Serialize(
componentsWithLayers.Select(c => c.Component.Id)
);
diff --git a/test/Microsoft.ComponentDetection.Detectors.Tests/LinuxScannerTests.cs b/test/Microsoft.ComponentDetection.Detectors.Tests/LinuxScannerTests.cs
index 230018a5d..eaa2c2bb4 100644
--- a/test/Microsoft.ComponentDetection.Detectors.Tests/LinuxScannerTests.cs
+++ b/test/Microsoft.ComponentDetection.Detectors.Tests/LinuxScannerTests.cs
@@ -21,198 +21,203 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
[TestCategory("Governance/ComponentDetection")]
public class LinuxScannerTests
{
- private const string SyftOutputLicensesFieldAndAuthor =
- @"{
- ""distro"": {
- ""id"":""test-distribution"",
- ""versionId"":""1.0.0""
- },
- ""artifacts"": [
- {
- ""name"":""test"",
- ""version"":""1.0.0"",
- ""type"":""deb"",
- ""locations"": [
- {
- ""path"": ""/var/lib/dpkg/status"",
- ""layerID"": ""sha256:f95fc50d21d981f1efe1f04109c2c3287c271794f5d9e4fdf9888851a174a971""
- }
- ],
- ""metadata"": {
- ""author"": ""John Doe""
+ private const string SyftOutputLicensesFieldAndAuthor = """
+ {
+ "distro": {
+ "id":"test-distribution",
+ "versionID":"1.0.0"
+ },
+ "artifacts": [
+ {
+ "name":"test",
+ "version":"1.0.0",
+ "type":"deb",
+ "locations": [
+ {
+ "path": "/var/lib/dpkg/status",
+ "layerID": "sha256:f95fc50d21d981f1efe1f04109c2c3287c271794f5d9e4fdf9888851a174a971"
+ }
+ ],
+ "metadata": {
+ "author": "John Doe"
+ },
+ "licenses": [
+ {
+ "value": "MIT"
},
- ""licenses"": [
- {
- ""value"": ""MIT"",
- },
- {
- ""value"": ""GPLv2"",
- },
- {
- ""value"": ""GPLv3"",
- }
- ]
- }
- ]
- }";
+ {
+ "value": "GPLv2"
+ },
+ {
+ "value": "GPLv3"
+ }
+ ]
+ }
+ ]
+ }
+ """;
- private const string SyftOutputLicenseFieldAndMaintainer =
- @"{
- ""distro"": {
- ""id"":""test-distribution"",
- ""versionId"":""1.0.0""
- },
- ""artifacts"": [
- {
- ""name"":""test"",
- ""version"":""1.0.0"",
- ""type"":""deb"",
- ""locations"": [
- {
- ""path"": ""/var/lib/dpkg/status"",
- ""layerID"": ""sha256:f95fc50d21d981f1efe1f04109c2c3287c271794f5d9e4fdf9888851a174a971""
- }
- ],
- ""metadata"": {
- ""maintainer"": ""John Doe"",
- ""license"": ""MIT, GPLv2, GPLv3""
+ private const string SyftOutputLicenseFieldAndMaintainer = """
+ {
+ "distro": {
+ "id":"test-distribution",
+ "versionID":"1.0.0"
+ },
+ "artifacts": [
+ {
+ "name":"test",
+ "version":"1.0.0",
+ "type":"deb",
+ "locations": [
+ {
+ "path": "/var/lib/dpkg/status",
+ "layerID": "sha256:f95fc50d21d981f1efe1f04109c2c3287c271794f5d9e4fdf9888851a174a971"
}
+ ],
+ "metadata": {
+ "maintainer": "John Doe",
+ "license": "MIT, GPLv2, GPLv3"
}
- ]
- }";
+ }
+ ]
+ }
+ """;
+
+ private const string SyftOutputNoAuthorOrLicense = """
+ {
+ "distro": {
+ "id":"test-distribution",
+ "versionID":"1.0.0"
+ },
+ "artifacts": [
+ {
+ "name":"test",
+ "version":"1.0.0",
+ "type":"deb",
+ "locations": [
+ {
+ "path": "/var/lib/dpkg/status",
+ "layerID": "sha256:f95fc50d21d981f1efe1f04109c2c3287c271794f5d9e4fdf9888851a174a971"
+ }
+ ]
+ }
+ ]
+ }
+ """;
- private const string SyftOutputNoAuthorOrLicense =
- @"{
- ""distro"": {
- ""id"":""test-distribution"",
- ""versionId"":""1.0.0""
+ private const string SyftOutputIgnoreInvalidMarinerPackages = """
+ {
+ "distro": {
+ "prettyName": "CBL-Mariner/Linux",
+ "name": "Common Base Linux Mariner",
+ "id": "mariner",
+ "version": "2.0.20250304",
+ "versionID": "2.0"
+ },
+ "artifacts": [
+ {
+ "id": "4af20256df269904",
+ "name": "busybox",
+ "version": "1.35.0",
+ "type": "rpm",
+ "foundBy": "elf-binary-package-cataloger",
+ "locations": [
+ {
+ "path": "/usr/sbin/busybox",
+ "layerID": "sha256:81caca2c07d9859b258a9cdfb1b1ab9d063f30ab73a4de9ea2ae760fd175bac6",
+ "accessPath": "/usr/sbin/busybox",
+ "annotations": { "evidence": "primary" }
+ }
+ ],
+ "cpes": [
+ {
+ "cpe": "cpe:2.3:a:busybox:busybox:1.35.0:*:*:*:*:*:*:*",
+ "source": "syft-generated"
+ }
+ ],
+ "purl": "pkg:rpm/mariner/busybox@1.35.0?distro=mariner-2.0",
+ "metadataType": "elf-binary-package-note-json-payload",
+ "metadata": { "type": "rpm", "os": "mariner", "osVersion": "2.0" }
},
- ""artifacts"": [
- {
- ""name"":""test"",
- ""version"":""1.0.0"",
- ""type"":""deb"",
- ""locations"": [
- {
- ""path"": ""/var/lib/dpkg/status"",
- ""layerID"": ""sha256:f95fc50d21d981f1efe1f04109c2c3287c271794f5d9e4fdf9888851a174a971""
- }
- ],
+ {
+ "id": "45849b2d67d236b0",
+ "name": "busybox",
+ "version": "1.35.0-13.cm2",
+ "type": "rpm",
+ "foundBy": "rpm-db-cataloger",
+ "locations": [
+ {
+ "path": "/var/lib/rpmmanifest/container-manifest-2",
+ "layerID": "sha256:81caca2c07d9859b258a9cdfb1b1ab9d063f30ab73a4de9ea2ae760fd175bac6",
+ "accessPath": "/var/lib/rpmmanifest/container-manifest-2",
+ "annotations": { "evidence": "primary" }
+ }
+ ],
+ "cpes": [
+ {
+ "cpe": "cpe:2.3:a:microsoftcorporation:busybox:1.35.0-13.cm2:*:*:*:*:*:*:*",
+ "source": "syft-generated"
+ },
+ {
+ "cpe": "cpe:2.3:a:busybox:busybox:1.35.0-13.cm2:*:*:*:*:*:*:*",
+ "source": "syft-generated"
+ }
+ ],
+ "purl": "pkg:rpm/busybox@1.35.0-13.cm2?arch=x86_64&upstream=busybox-1.35.0-13.cm2.src.rpm",
+ "metadataType": "rpm-db-entry",
+ "metadata": {
+ "name": "busybox",
+ "version": "1.35.0",
+ "epoch": null,
+ "architecture": "x86_64",
+ "release": "13.cm2",
+ "sourceRpm": "busybox-1.35.0-13.cm2.src.rpm",
+ "size": 3512551,
+ "vendor": "Microsoft Corporation",
+ "files": null
}
- ]
- }";
-
- private const string SyftOutputIgnoreInvalidMarinerPackages =
- @"{
- ""distro"": {
- ""prettyName"": ""CBL-Mariner/Linux"",
- ""name"": ""Common Base Linux Mariner"",
- ""id"": ""mariner"",
- ""version"": ""2.0.20250304"",
- ""versionID"": ""2.0"",
- },
- ""artifacts"": [
- {
- ""id"": ""4af20256df269904"",
- ""name"": ""busybox"",
- ""version"": ""1.35.0"",
- ""type"": ""rpm"",
- ""foundBy"": ""elf-binary-package-cataloger"",
- ""locations"": [
- {
- ""path"": ""/usr/sbin/busybox"",
- ""layerID"": ""sha256:81caca2c07d9859b258a9cdfb1b1ab9d063f30ab73a4de9ea2ae760fd175bac6"",
- ""accessPath"": ""/usr/sbin/busybox"",
- ""annotations"": { ""evidence"": ""primary"" }
- }
- ],
- ""cpes"": [
- {
- ""cpe"": ""cpe:2.3:a:busybox:busybox:1.35.0:*:*:*:*:*:*:*"",
- ""source"": ""syft-generated""
- }
- ],
- ""purl"": ""pkg:rpm/mariner/busybox@1.35.0?distro=mariner-2.0"",
- ""metadataType"": ""elf-binary-package-note-json-payload"",
- ""metadata"": { ""type"": ""rpm"", ""os"": ""mariner"", ""osVersion"": ""2.0"" }
- },
- {
- ""id"": ""45849b2d67d236b0"",
- ""name"": ""busybox"",
- ""version"": ""1.35.0-13.cm2"",
- ""type"": ""rpm"",
- ""foundBy"": ""rpm-db-cataloger"",
- ""locations"": [
- {
- ""path"": ""/var/lib/rpmmanifest/container-manifest-2"",
- ""layerID"": ""sha256:81caca2c07d9859b258a9cdfb1b1ab9d063f30ab73a4de9ea2ae760fd175bac6"",
- ""accessPath"": ""/var/lib/rpmmanifest/container-manifest-2"",
- ""annotations"": { ""evidence"": ""primary"" }
- }
- ],
- ""cpes"": [
- {
- ""cpe"": ""cpe:2.3:a:microsoftcorporation:busybox:1.35.0-13.cm2:*:*:*:*:*:*:*"",
- ""source"": ""syft-generated""
- },
- {
- ""cpe"": ""cpe:2.3:a:busybox:busybox:1.35.0-13.cm2:*:*:*:*:*:*:*"",
- ""source"": ""syft-generated""
- }
- ],
- ""purl"": ""pkg:rpm/busybox@1.35.0-13.cm2?arch=x86_64&upstream=busybox-1.35.0-13.cm2.src.rpm"",
- ""metadataType"": ""rpm-db-entry"",
- ""metadata"": {
- ""name"": ""busybox"",
- ""version"": ""1.35.0"",
- ""epoch"": null,
- ""architecture"": ""x86_64"",
- ""release"": ""13.cm2"",
- ""sourceRpm"": ""busybox-1.35.0-13.cm2.src.rpm"",
- ""size"": 3512551,
- ""vendor"": ""Microsoft Corporation"",
- ""files"": null
+ }
+ ]
+ }
+ """;
+
+ private const string SyftOutputRemoveNonduplicatedMarinerPackages = """
+ {
+ "distro": {
+ "prettyName": "CBL-Mariner/Linux",
+ "name": "Common Base Linux Mariner",
+ "id": "mariner",
+ "version": "2.0.20250304",
+ "versionID": "2.0"
+ },
+ "artifacts": [
+ {
+ "id": "4af20256df269904",
+ "name": "busybox",
+ "version": "1.35.0",
+ "type": "rpm",
+ "foundBy": "elf-binary-package-cataloger",
+ "locations": [
+ {
+ "path": "/usr/sbin/busybox",
+ "layerID": "sha256:81caca2c07d9859b258a9cdfb1b1ab9d063f30ab73a4de9ea2ae760fd175bac6",
+ "accessPath": "/usr/sbin/busybox",
+ "annotations": { "evidence": "primary" }
}
- },
- ]
- }";
-
- private const string SyftOutputRemoveNonduplicatedMarinerPackages =
- @"{
- ""distro"": {
- ""prettyName"": ""CBL-Mariner/Linux"",
- ""name"": ""Common Base Linux Mariner"",
- ""id"": ""mariner"",
- ""version"": ""2.0.20250304"",
- ""versionID"": ""2.0"",
- },
- ""artifacts"": [
- {
- ""id"": ""4af20256df269904"",
- ""name"": ""busybox"",
- ""version"": ""1.35.0"",
- ""type"": ""rpm"",
- ""foundBy"": ""elf-binary-package-cataloger"",
- ""locations"": [
- {
- ""path"": ""/usr/sbin/busybox"",
- ""layerID"": ""sha256:81caca2c07d9859b258a9cdfb1b1ab9d063f30ab73a4de9ea2ae760fd175bac6"",
- ""accessPath"": ""/usr/sbin/busybox"",
- ""annotations"": { ""evidence"": ""primary"" }
- }
- ],
- ""cpes"": [
- {
- ""cpe"": ""cpe:2.3:a:busybox:busybox:1.35.0:*:*:*:*:*:*:*"",
- ""source"": ""syft-generated""
- }
- ],
- ""purl"": ""pkg:rpm/mariner/busybox@1.35.0?distro=mariner-2.0"",
- ""metadataType"": ""elf-binary-package-note-json-payload"",
- ""metadata"": { ""type"": ""rpm"", ""os"": ""mariner"", ""osVersion"": ""2.0"" }
- },
- ]
- }";
+ ],
+ "cpes": [
+ {
+ "cpe": "cpe:2.3:a:busybox:busybox:1.35.0:*:*:*:*:*:*:*",
+ "source": "syft-generated"
+ }
+ ],
+ "purl": "pkg:rpm/mariner/busybox@1.35.0?distro=mariner-2.0",
+ "metadataType": "elf-binary-package-note-json-payload",
+ "metadata": { "type": "rpm", "os": "mariner", "osVersion": "2.0" }
+ }
+ ]
+ }
+ """;
private readonly LinuxScanner linuxScanner;
private readonly Mock mockDockerService;
@@ -440,59 +445,60 @@ await this.linuxScanner.ScanLinuxAsync(
[TestMethod]
public async Task TestLinuxScanner_SupportsMultipleComponentTypes_Async()
{
- const string syftOutputWithMixedTypes =
- @"{
- ""distro"": {
- ""id"":""ubuntu"",
- ""versionId"":""22.04""
+ const string syftOutputWithMixedTypes = """
+ {
+ "distro": {
+ "id":"ubuntu",
+ "versionID":"22.04"
},
- ""artifacts"": [
+ "artifacts": [
{
- ""name"":""curl"",
- ""version"":""7.81.0-1ubuntu1.10"",
- ""type"":""deb"",
- ""locations"": [
+ "name":"curl",
+ "version":"7.81.0-1ubuntu1.10",
+ "type":"deb",
+ "locations": [
{
- ""path"": ""/var/lib/dpkg/status"",
- ""layerID"": ""sha256:layer1""
+ "path": "/var/lib/dpkg/status",
+ "layerID": "sha256:layer1"
}
],
- ""metadata"": {
- ""maintainer"": ""Ubuntu Developers""
+ "metadata": {
+ "maintainer": "Ubuntu Developers"
}
},
{
- ""name"":""express"",
- ""version"":""4.18.2"",
- ""type"":""npm"",
- ""locations"": [
+ "name":"express",
+ "version":"4.18.2",
+ "type":"npm",
+ "locations": [
{
- ""path"": ""/app/node_modules/express/package.json"",
- ""layerID"": ""sha256:layer2""
+ "path": "/app/node_modules/express/package.json",
+ "layerID": "sha256:layer2"
}
],
- ""metadata"": {
- ""author"": ""TJ Holowaychuk"",
- ""integrity"": ""sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==""
+ "metadata": {
+ "author": "TJ Holowaychuk",
+ "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ=="
}
},
{
- ""name"":""requests"",
- ""version"":""2.31.0"",
- ""type"":""python"",
- ""locations"": [
+ "name":"requests",
+ "version":"2.31.0",
+ "type":"python",
+ "locations": [
{
- ""path"": ""/usr/local/lib/python3.10/site-packages/requests-2.31.0.dist-info/METADATA"",
- ""layerID"": ""sha256:layer2""
+ "path": "/usr/local/lib/python3.10/site-packages/requests-2.31.0.dist-info/METADATA",
+ "layerID": "sha256:layer2"
}
],
- ""metadata"": {
- ""author"": ""Kenneth Reitz"",
- ""license"": ""Apache-2.0""
+ "metadata": {
+ "author": "Kenneth Reitz",
+ "license": "Apache-2.0"
}
}
]
- }";
+ }
+ """;
this.mockDockerService.Setup(service =>
service.CreateAndRunContainerAsync(
@@ -548,54 +554,55 @@ public async Task TestLinuxScanner_SupportsMultipleComponentTypes_Async()
[TestMethod]
public async Task TestLinuxScanner_FiltersComponentsByEnabledTypes_OnlyLinux_Async()
{
- const string syftOutputWithMixedTypes =
- @"{
- ""distro"": {
- ""id"":""ubuntu"",
- ""versionId"":""22.04""
+ const string syftOutputWithMixedTypes = """
+ {
+ "distro": {
+ "id":"ubuntu",
+ "versionID":"22.04"
},
- ""artifacts"": [
+ "artifacts": [
{
- ""name"":""curl"",
- ""version"":""7.81.0-1ubuntu1.10"",
- ""type"":""deb"",
- ""locations"": [
+ "name":"curl",
+ "version":"7.81.0-1ubuntu1.10",
+ "type":"deb",
+ "locations": [
{
- ""path"": ""/var/lib/dpkg/status"",
- ""layerID"": ""sha256:layer1""
+ "path": "/var/lib/dpkg/status",
+ "layerID": "sha256:layer1"
}
],
- ""metadata"": {
- ""maintainer"": ""Ubuntu Developers""
+ "metadata": {
+ "maintainer": "Ubuntu Developers"
}
},
{
- ""name"":""express"",
- ""version"":""4.18.2"",
- ""type"":""npm"",
- ""locations"": [
+ "name":"express",
+ "version":"4.18.2",
+ "type":"npm",
+ "locations": [
{
- ""path"": ""/app/node_modules/express/package.json"",
- ""layerID"": ""sha256:layer2""
+ "path": "/app/node_modules/express/package.json",
+ "layerID": "sha256:layer2"
}
],
- ""metadata"": {
- ""author"": ""TJ Holowaychuk""
+ "metadata": {
+ "author": "TJ Holowaychuk"
}
},
{
- ""name"":""requests"",
- ""version"":""2.31.0"",
- ""type"":""python"",
- ""locations"": [
+ "name":"requests",
+ "version":"2.31.0",
+ "type":"python",
+ "locations": [
{
- ""path"": ""/usr/local/lib/python3.10/site-packages/requests-2.31.0.dist-info/METADATA"",
- ""layerID"": ""sha256:layer2""
+ "path": "/usr/local/lib/python3.10/site-packages/requests-2.31.0.dist-info/METADATA",
+ "layerID": "sha256:layer2"
}
]
}
]
- }";
+ }
+ """;
this.mockDockerService.Setup(service =>
service.CreateAndRunContainerAsync(
@@ -632,54 +639,55 @@ public async Task TestLinuxScanner_FiltersComponentsByEnabledTypes_OnlyLinux_Asy
[TestMethod]
public async Task TestLinuxScanner_FiltersComponentsByEnabledTypes_OnlyNpmAndPip_Async()
{
- const string syftOutputWithMixedTypes =
- @"{
- ""distro"": {
- ""id"":""ubuntu"",
- ""versionId"":""22.04""
+ const string syftOutputWithMixedTypes = """
+ {
+ "distro": {
+ "id":"ubuntu",
+ "versionId":"22.04"
},
- ""artifacts"": [
+ "artifacts": [
{
- ""name"":""curl"",
- ""version"":""7.81.0-1ubuntu1.10"",
- ""type"":""deb"",
- ""locations"": [
+ "name":"curl",
+ "version":"7.81.0-1ubuntu1.10",
+ "type":"deb",
+ "locations": [
{
- ""path"": ""/var/lib/dpkg/status"",
- ""layerID"": ""sha256:layer1""
+ "path": "/var/lib/dpkg/status",
+ "layerID": "sha256:layer1"
}
],
- ""metadata"": {
- ""maintainer"": ""Ubuntu Developers""
+ "metadata": {
+ "maintainer": "Ubuntu Developers"
}
},
{
- ""name"":""express"",
- ""version"":""4.18.2"",
- ""type"":""npm"",
- ""locations"": [
+ "name":"express",
+ "version":"4.18.2",
+ "type":"npm",
+ "locations": [
{
- ""path"": ""/app/node_modules/express/package.json"",
- ""layerID"": ""sha256:layer2""
+ "path": "/app/node_modules/express/package.json",
+ "layerID": "sha256:layer2"
}
],
- ""metadata"": {
- ""author"": ""TJ Holowaychuk""
+ "metadata": {
+ "author": "TJ Holowaychuk"
}
},
{
- ""name"":""requests"",
- ""version"":""2.31.0"",
- ""type"":""python"",
- ""locations"": [
+ "name":"requests",
+ "version":"2.31.0",
+ "type":"python",
+ "locations": [
{
- ""path"": ""/usr/local/lib/python3.10/site-packages/requests-2.31.0.dist-info/METADATA"",
- ""layerID"": ""sha256:layer2""
+ "path": "/usr/local/lib/python3.10/site-packages/requests-2.31.0.dist-info/METADATA",
+ "layerID": "sha256:layer2"
}
]
}
]
- }";
+ }
+ """;
this.mockDockerService.Setup(service =>
service.CreateAndRunContainerAsync(