mirror of
https://github.com/DependencyTrack/dependency-track.git
synced 2025-10-19 07:53:18 +00:00
Compare commits
36 commits
eae1642f7d
...
91afb56705
Author | SHA1 | Date | |
---|---|---|---|
![]() |
91afb56705 | ||
![]() |
880caffa0c | ||
![]() |
09ffb65d70 | ||
![]() |
efd19c6492 | ||
![]() |
e0c2fe7a08 | ||
![]() |
e138589976 | ||
![]() |
25e9e83a34 | ||
![]() |
d36f5b045a | ||
![]() |
45b0799f1e | ||
![]() |
f9740a2f05 | ||
![]() |
50fdb1871c | ||
![]() |
f77a8363a5 | ||
![]() |
1db4a4c671 | ||
![]() |
2e8ed53949 | ||
![]() |
5e369a4e97 | ||
![]() |
db4c4d1503 | ||
![]() |
2b8c531abc | ||
![]() |
cb3a360913 | ||
![]() |
851ba164ba | ||
![]() |
335e4be757 | ||
![]() |
d5f76d8b51 | ||
![]() |
5ab48bdbf6 | ||
![]() |
57e256b333 | ||
![]() |
7b2398079e | ||
![]() |
82fc4962dc | ||
![]() |
da70954471 | ||
![]() |
d3af42d2e8 | ||
![]() |
14ccf7ba97 | ||
![]() |
9f2f906bef | ||
![]() |
58855c3b55 | ||
![]() |
128b0b1d17 | ||
![]() |
6cbafd3bef | ||
![]() |
93109a5249 | ||
![]() |
e130776fc9 | ||
![]() |
d924b7e940 | ||
![]() |
a522553690 |
31 changed files with 30593 additions and 311 deletions
1
.github/ISSUE_TEMPLATE/defect-report.yml
vendored
1
.github/ISSUE_TEMPLATE/defect-report.yml
vendored
|
@ -71,6 +71,7 @@ body:
|
|||
- 4.13.2
|
||||
- 4.13.3
|
||||
- 4.13.4
|
||||
- 4.13.5
|
||||
- 4.14.0-SNAPSHOT
|
||||
validations:
|
||||
required: true
|
||||
|
|
4
.github/workflows/_meta-build.yaml
vendored
4
.github/workflows/_meta-build.yaml
vendored
|
@ -95,7 +95,7 @@ jobs:
|
|||
install: true
|
||||
|
||||
- name: Login to Docker.io
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # tag=v3.5.0
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # tag=v3.6.0
|
||||
if: ${{ inputs.publish-container }}
|
||||
with:
|
||||
registry: docker.io
|
||||
|
@ -166,6 +166,6 @@ jobs:
|
|||
|
||||
- name: Upload Trivy Scan Results to GitHub Security Tab
|
||||
if: ${{ inputs.publish-container }}
|
||||
uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # tag=v3.29.5
|
||||
uses: github/codeql-action/upload-sarif@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # tag=v3.29.5
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
|
|
2
.github/workflows/dependency-review.yaml
vendored
2
.github/workflows/dependency-review.yaml
vendored
|
@ -12,4 +12,4 @@ jobs:
|
|||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # tag=v5.0.0
|
||||
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 # tag=v4.8.0
|
||||
uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # tag=v4.8.1
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=47937257-839d-491d-b693-703d11b910ad" style="display:none" />
|
||||
<header>
|
||||
<h1>
|
||||
<a href="{{ site.baseurl }}/"><img src="{{ site.baseurl }}/images/dt-logo-white-text.svg" alt="{{ site.title }} logo"></a>{{ site.version }}
|
||||
|
|
97
docs/_posts/2025-10-07-v4.13.5.md
Normal file
97
docs/_posts/2025-10-07-v4.13.5.md
Normal file
|
@ -0,0 +1,97 @@
|
|||
---
|
||||
title: v4.13.5
|
||||
type: patch
|
||||
---
|
||||
|
||||
**Important Notice:**
|
||||
|
||||
Sonatype has started to enforce an authentication requirement for OSS Index.
|
||||
|
||||
The [OSS Index analyzer] has historically been enabled by default for Dependency-Track,
|
||||
and configuration of credentials for authentication was not strictly necessary.
|
||||
|
||||
This has now changed, and users who wish to continue using OSS Index will
|
||||
need to register for a free account, and configure credentials in the analyzer's settings.
|
||||
|
||||
Please refer to [Sonatype's announcement] for further details.
|
||||
|
||||
In the midterm, we'll be looking into enabling OSV per default
|
||||
to compensate for this change.
|
||||
|
||||
**Fixes:**
|
||||
|
||||
* Fix CPE matching not being fully case-insensitive - [apiserver/#5299]
|
||||
* Improve detection whether version of a github PURL is a commit SHA or release tag - [apiserver/#5350]
|
||||
* Make OSS Index credentials required - [apiserver/#5351]
|
||||
* Fix occasional NullPointerException when mirroring the NVD via REST API - [apiserver/#5352]
|
||||
* Fix `/api/v1/tag/policy/{uuid}` endpoint returning more tags than are assigned to a policy - [apiserver/#5353]
|
||||
* Fix possible failure of NVD mirroring due to corrupted timestamp files - [apiserver/#5354]
|
||||
* Fix BOM validation failing due to unrecognized new SPDX license IDs - [apiserver/#5355]
|
||||
* Fix new SPDX license IDs not being recognized - [apiserver/#5356]
|
||||
* Fix high CPU utilization when watchdog logger is configured - [apiserver/#5357]
|
||||
* Fix NullPointerException in GithubMetaAnalyzer when analyzing GitHub Actions - [apiserver/#5359]
|
||||
* Fix connection reset during OSV mirroring - [apiserver/#5360]
|
||||
* Fix compatibility of custom NuGet repositories with JFrog Artifactory - [apiserver/#5381]
|
||||
* Fix custom NuGet repositories not working with Sonatype Nexus - [apiserver/#5381]
|
||||
* Fix possible disclosure of private NuGet repository credentials to api.nuget.org - [apiserver/#5381] / [GHSA-83g2-vgqh-mgxc]
|
||||
|
||||
For a complete list of changes, refer to the respective GitHub milestones:
|
||||
|
||||
* [API server milestone 4.13.5](https://github.com/DependencyTrack/dependency-track/milestone/59?closed=1)
|
||||
* [Frontend milestone 4.13.5](https://github.com/DependencyTrack/frontend/milestone/44?closed=1)
|
||||
|
||||
We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes.
|
||||
|
||||
Special thanks to everyone who contributed code to implement enhancements and fix defects:
|
||||
|
||||
[@colinfyfe], [@framayo], [@jonbally], [@snieguu], [@stohrendorf]
|
||||
|
||||
###### dependency-track-apiserver.jar
|
||||
|
||||
| Algorithm | Checksum |
|
||||
|:----------|:---------|
|
||||
| SHA-1 | f38abe7b93f7cb88f3bba4c78c30a9ce7dc45c0d |
|
||||
| SHA-256 | bf55097e63b46ed16042024636b855f676ba67e6e5824e7da80f3cec863a3f77 |
|
||||
|
||||
###### dependency-track-bundled.jar
|
||||
|
||||
| Algorithm | Checksum |
|
||||
|:----------|:---------|
|
||||
| SHA-1 | 5aea8e0662f8aa4d9e53b52c14367c5345602e34 |
|
||||
| SHA-256 | 4a373de4d5aca924fb533ebfc7e1eb4fb5a249d81c948bd367a52fa53125a610 |
|
||||
|
||||
###### frontend-dist.zip
|
||||
|
||||
| Algorithm | Checksum |
|
||||
|:----------|:-----------------------------------------------------------------|
|
||||
| SHA-1 | e441f28a656b710766a9fd85360872bc9330d14c |
|
||||
| SHA-256 | fb67bf767e2142b72dbd226b984a1faee9e491d108ccfd29860a49e0b5b15a12 |
|
||||
|
||||
###### Software Bill of Materials (SBOM)
|
||||
|
||||
* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.13.5/bom.json)
|
||||
* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.13.5/bom.json)
|
||||
|
||||
[apiserver/#5299]: https://github.com/DependencyTrack/dependency-track/pull/5299
|
||||
[apiserver/#5350]: https://github.com/DependencyTrack/dependency-track/pull/5350
|
||||
[apiserver/#5351]: https://github.com/DependencyTrack/dependency-track/pull/5351
|
||||
[apiserver/#5352]: https://github.com/DependencyTrack/dependency-track/pull/5352
|
||||
[apiserver/#5353]: https://github.com/DependencyTrack/dependency-track/pull/5353
|
||||
[apiserver/#5354]: https://github.com/DependencyTrack/dependency-track/pull/5354
|
||||
[apiserver/#5355]: https://github.com/DependencyTrack/dependency-track/pull/5355
|
||||
[apiserver/#5356]: https://github.com/DependencyTrack/dependency-track/pull/5356
|
||||
[apiserver/#5357]: https://github.com/DependencyTrack/dependency-track/pull/5357
|
||||
[apiserver/#5359]: https://github.com/DependencyTrack/dependency-track/pull/5359
|
||||
[apiserver/#5360]: https://github.com/DependencyTrack/dependency-track/pull/5360
|
||||
[apiserver/#5381]: https://github.com/DependencyTrack/dependency-track/pull/5381
|
||||
|
||||
[GHSA-83g2-vgqh-mgxc]: https://github.com/DependencyTrack/dependency-track/security/advisories/GHSA-83g2-vgqh-mgxc
|
||||
|
||||
[OSS Index analyzer]: {{ site.baseurl }}{% link _docs/datasources/ossindex.md %}
|
||||
[Sonatype's announcement]: https://ossindex.sonatype.org/doc/auth-required
|
||||
|
||||
[@colinfyfe]: https://github.com/colinfyfe
|
||||
[@framayo]: https://github.com/framayo
|
||||
[@jonbally]: https://github.com/jonbally
|
||||
[@snieguu]: https://github.com/snieguu
|
||||
[@stohrendorf]: https://github.com/stohrendorf
|
16
pom.xml
16
pom.xml
|
@ -85,24 +85,24 @@
|
|||
<maven.compiler.target>21</maven.compiler.target>
|
||||
|
||||
<!-- Dependency Versions -->
|
||||
<frontend.version>4.13.4</frontend.version>
|
||||
<frontend.version>4.13.5</frontend.version>
|
||||
<lib.alpine.version>${project.parent.version}</lib.alpine.version>
|
||||
<lib.awaitility.version>4.3.0</lib.awaitility.version>
|
||||
<lib.brotli-decoder.version>0.1.2</lib.brotli-decoder.version>
|
||||
<lib.checkstyle.version>11.1.0</lib.checkstyle.version>
|
||||
<lib.checkstyle.version>12.0.0</lib.checkstyle.version>
|
||||
<lib.cloud-sql-connector-jdbc-sqlserver.version>1.25.3</lib.cloud-sql-connector-jdbc-sqlserver.version>
|
||||
<lib.cloud-sql-mysql-socket-factory-connector-j-8.version>1.25.3</lib.cloud-sql-mysql-socket-factory-connector-j-8.version>
|
||||
<lib.cloud-sql-postgres-socket-factory.version>1.25.3</lib.cloud-sql-postgres-socket-factory.version>
|
||||
<lib.cpe-parser.version>3.0.0</lib.cpe-parser.version>
|
||||
<lib.commons-compress.version>1.28.0</lib.commons-compress.version>
|
||||
<lib.commons-text.version>1.14.0</lib.commons-text.version>
|
||||
<lib.ae-security.version>0.144.1</lib.ae-security.version>
|
||||
<lib.ae-security.version>0.145.2</lib.ae-security.version>
|
||||
<lib.owasp-rr-calculator.version>1.0.1</lib.owasp-rr-calculator.version>
|
||||
<lib.cyclonedx-java.version>11.0.0</lib.cyclonedx-java.version>
|
||||
<lib.jakarta-validation.version>3.1.1</lib.jakarta-validation.version>
|
||||
<lib.greenmail.version>2.1.6</lib.greenmail.version>
|
||||
<lib.greenmail.version>2.1.7</lib.greenmail.version>
|
||||
<lib.json-java.version>20250517</lib.json-java.version>
|
||||
<lib.json-unit.version>4.1.1</lib.json-unit.version>
|
||||
<lib.json-unit.version>5.0.0</lib.json-unit.version>
|
||||
<lib.junit.version>6.0.0</lib.junit.version>
|
||||
<lib.lucene.version>8.11.4</lib.lucene.version>
|
||||
<lib.maven-artifact.version>3.9.11</lib.maven-artifact.version>
|
||||
|
@ -129,7 +129,7 @@
|
|||
<lib.jdbc-driver.postgresql.version>42.7.8</lib.jdbc-driver.postgresql.version>
|
||||
<!-- Maven Plugin Properties -->
|
||||
<plugin.retirejs.breakOnFailure>false</plugin.retirejs.breakOnFailure>
|
||||
<plugin.jetty.version>12.1.1</plugin.jetty.version>
|
||||
<plugin.jetty.version>12.1.2</plugin.jetty.version>
|
||||
<plugin.protoc-jar.version>3.11.4</plugin.protoc-jar.version>
|
||||
<!-- SonarCloud properties -->
|
||||
<sonar.exclusions>src/main/webapp/**</sonar.exclusions>
|
||||
|
@ -581,7 +581,7 @@
|
|||
<plugin>
|
||||
<groupId>io.github.ascopes</groupId>
|
||||
<artifactId>protobuf-maven-plugin</artifactId>
|
||||
<version>3.9.1</version>
|
||||
<version>3.10.1</version>
|
||||
<configuration>
|
||||
<protocVersion>${lib.protobuf-java.version}</protocVersion>
|
||||
<sourceDirectories>
|
||||
|
@ -679,7 +679,7 @@
|
|||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>merge-services-bom</id>
|
||||
|
|
|
@ -36,7 +36,7 @@ COPY ./target/${WAR_FILENAME} ./
|
|||
|
||||
RUN ./create-jre.sh -i "./${WAR_FILENAME}" -o ./jre
|
||||
|
||||
FROM alpine:3.22@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
|
||||
FROM alpine:3.22@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
|
||||
|
||||
ARG COMMIT_SHA
|
||||
ARG APP_VERSION
|
||||
|
|
|
@ -88,7 +88,9 @@ public abstract class AbstractMetaAnalyzer implements IMetaAnalyzer {
|
|||
final String statusText, final Component component) {
|
||||
logger.debug("HTTP Status : " + statusCode + " " + statusText);
|
||||
logger.debug(" - RepositoryType URL : " + url);
|
||||
if(component != null && component.getPurl() != null) {
|
||||
logger.debug(" - Package URL : " + component.getPurl().canonicalize());
|
||||
}
|
||||
Notification.dispatch(new Notification()
|
||||
.scope(NotificationScope.SYSTEM)
|
||||
.group(NotificationGroup.REPOSITORY)
|
||||
|
@ -100,7 +102,6 @@ public abstract class AbstractMetaAnalyzer implements IMetaAnalyzer {
|
|||
|
||||
protected void handleRequestException(final Logger logger, final Exception e) {
|
||||
logger.error("Request failure for repository URL: " + baseUrl, e);
|
||||
e.printStackTrace();
|
||||
Notification.dispatch(new Notification()
|
||||
.scope(NotificationScope.SYSTEM)
|
||||
.group(NotificationGroup.REPOSITORY)
|
||||
|
|
|
@ -51,4 +51,14 @@ public class MetaModel {
|
|||
public void setPublishedTimestamp(final Date publishedTimestamp) {
|
||||
this.publishedTimestamp = publishedTimestamp;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MetaModel{" +
|
||||
"component=" + component +
|
||||
", latestVersion='" + latestVersion + '\'' +
|
||||
", publishedTimestamp=" + publishedTimestamp +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
package org.dependencytrack.tasks.repositories;
|
||||
|
||||
import alpine.common.logging.Logger;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.packageurl.PackageURL;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
|
@ -31,50 +33,110 @@ import org.json.JSONArray;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* An IMetaAnalyzer implementation that supports Nuget.
|
||||
* <p>
|
||||
* Excludes pre-release and unlisted versions. Pre-release versions will be considered if no stable release exists.
|
||||
* Unlisted versions are excluded because they have been deliberately hidden for a specific safety reason.
|
||||
* To quote <a href="https://learn.microsoft.com/en-us/nuget/nuget-org/policies/deleting-packages">the Microsoft Nuget
|
||||
* docs</a>:
|
||||
* <blockquote>"Unlisting a package version hides it from search and from nuget.org package details page. This allows
|
||||
* existing users of the package to continue using it but reduces new adoption since the package is not visible in
|
||||
* search".</blockquote>
|
||||
* For an example package, see
|
||||
* <a href="https://www.nuget.org/packages/Microsoft.Data.SqlClient/6.1.0">Microsoft.Data.SqlClient/6.1.0</a>
|
||||
* which states:
|
||||
* <blockquote>This package has been deprecated as it has critical bugs</blockquote> and
|
||||
* <blockquote>The owner has unlisted this package. This could mean that the package is deprecated, has security
|
||||
* vulnerabilities or shouldn't be used anymore.</blockquote>
|
||||
* Dependency Track won't prevent users from using an unlisted package, but it won't encourage it.
|
||||
* <p>
|
||||
* We do not use the PackageBaseAddress resource to retrieve version information - it would be faster and simpler
|
||||
* but, to <a href="https://learn.microsoft.com/en-us/nuget/api/package-base-address-resource">quote Microsoft</a>:
|
||||
* <blockquote>This list contains both listed and unlisted package versions.</blockquote>
|
||||
* Artifactory doesn't provide the PackageBaseAddress resource,
|
||||
* <a href="https://learn.microsoft.com/en-us/nuget/api/overview">despite Microsoft stating it is required</a>. JFrog
|
||||
* <a href="https://jfrog.com/help/r/jfrog-artifactory-documentation/nuget-repositories">state here it is not supported
|
||||
* as at September 2025./a>.
|
||||
* <p>
|
||||
* Artifactory also doesn't provide "published" data as of August 2025 so no dates will be included in the response from
|
||||
* those feeds. Other third party feeds may also omit the published dates.
|
||||
*
|
||||
* @author Steve Springett
|
||||
* @since 3.4.0
|
||||
*/
|
||||
public class NugetMetaAnalyzer extends AbstractMetaAnalyzer {
|
||||
|
||||
public static final DateFormat[] SUPPORTED_DATE_FORMATS = new DateFormat[]{
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"),
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"),
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
|
||||
};
|
||||
private static final Logger LOGGER = Logger.getLogger(NugetMetaAnalyzer.class);
|
||||
private static final String DEFAULT_BASE_URL = "https://api.nuget.org";
|
||||
|
||||
private static final String INDEX_URL = "/v3/index.json";
|
||||
private static final String DEFAULT_BASE_URL = "https://api.nuget.org/v3/index.json";
|
||||
private static final String NUGET_KEY_UPPER = "upper";
|
||||
private static final String NUGET_KEY_ITEMS = "items";
|
||||
|
||||
private static final String DEFAULT_VERSION_QUERY_ENDPOINT = "/v3-flatcontainer/%s/index.json";
|
||||
private static final Cache<String, String> REPO_REGISTRATION_URL_CACHE = Caffeine.newBuilder()
|
||||
.maximumSize(100)
|
||||
.expireAfterWrite(15, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
private static final String DEFAULT_REGISTRATION_ENDPOINT = "/v3/registration5-gz-semver2/%s/%s.json";
|
||||
private String serviceIndexUrl;
|
||||
private String registrationsBaseUrl = "";
|
||||
|
||||
private String versionQueryUrl;
|
||||
|
||||
private String registrationUrl;
|
||||
|
||||
NugetMetaAnalyzer() {
|
||||
this.baseUrl = DEFAULT_BASE_URL;
|
||||
|
||||
// Set defaults that work with NuGet.org just in case the index endpoint is not available
|
||||
this.versionQueryUrl = baseUrl + DEFAULT_VERSION_QUERY_ENDPOINT;
|
||||
this.registrationUrl = baseUrl + DEFAULT_REGISTRATION_ENDPOINT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the repository base URL which will then be used to retrieve and parse the service index. If the user has
|
||||
* specified a repo URL ending with index.json, it should be considered "fully qualified" and used as is to maximise
|
||||
* compatability with non-nuget.org repos such as Artifactory. If not, preserve the previous Dependency Track
|
||||
* behaviour of appending the nuget.org index to the supplied URL.
|
||||
* @param baseUrl the base URL to the repository
|
||||
*/
|
||||
@Override
|
||||
public void setRepositoryBaseUrl(String baseUrl) {
|
||||
super.setRepositoryBaseUrl(baseUrl);
|
||||
|
||||
initializeEndpoints();
|
||||
if (baseUrl.toLowerCase().endsWith("index.json")) {
|
||||
this.serviceIndexUrl = baseUrl;
|
||||
} else {
|
||||
this.serviceIndexUrl = stripTrailingSlash(baseUrl) + "/v3/index.json";
|
||||
}
|
||||
|
||||
this.setRegistrationsBaseUrl(REPO_REGISTRATION_URL_CACHE.get(this.serviceIndexUrl, key -> findRegistrationsBaseUrl()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RegistrationsBaseUrl to be used to retrieve package metadata. This is primarily intended
|
||||
* for testing as setRepositoryBaseUrl should find and set the best URL automatically. Call this method AFTER
|
||||
* setRepositoryBaseUrl to ensure your value is not overridden.
|
||||
*
|
||||
* @param registrationsBaseUrlStem Registrations URL to be set
|
||||
*/
|
||||
public void setRegistrationsBaseUrl(String registrationsBaseUrlStem) {
|
||||
if(registrationsBaseUrlStem == null || registrationsBaseUrlStem.isBlank()) {
|
||||
return;
|
||||
}
|
||||
this.registrationsBaseUrl = stripTrailingSlash(registrationsBaseUrlStem) + "/%s/%s.json";
|
||||
}
|
||||
|
||||
private static String stripTrailingSlash(String input) {
|
||||
if (input == null || input.isBlank()) {
|
||||
return input;
|
||||
}
|
||||
return input.endsWith("/") ? input.substring(0, input.length() - 1) : input;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,117 +157,313 @@ public class NugetMetaAnalyzer extends AbstractMetaAnalyzer {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
public MetaModel analyze(final Component component) {
|
||||
|
||||
if(component == null) {
|
||||
throw new IllegalArgumentException("Component cannot be null");
|
||||
}
|
||||
|
||||
final MetaModel meta = new MetaModel(component);
|
||||
if (component.getPurl() != null) {
|
||||
if (performVersionCheck(meta, component)) {
|
||||
performLastPublishedCheck(meta, component);
|
||||
}
|
||||
LOGGER.debug("Analyzing component: " + component.getPurl().getName() + " (Internal: " + component.isInternal() + ")");
|
||||
performVersionCheck(meta, component);
|
||||
}
|
||||
LOGGER.debug("Results: " + meta);
|
||||
return meta;
|
||||
}
|
||||
|
||||
private boolean performVersionCheck(final MetaModel meta, final Component component) {
|
||||
final String url = String.format(versionQueryUrl, urlEncode(component.getPurl().getName().toLowerCase()));
|
||||
try (final CloseableHttpResponse response = processHttpRequest(url)) {
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
if (response.getEntity() != null) {
|
||||
String responseString = EntityUtils.toString(response.getEntity());
|
||||
var jsonObject = new JSONObject(responseString);
|
||||
final JSONArray versions = jsonObject.getJSONArray("versions");
|
||||
/**
|
||||
* Attempts to find the latest version of the supplied component and return its published date, if one exists.
|
||||
* Ignores pre-release and unlisted versions.
|
||||
* @param meta {@link MetaModel} to be updated with detected version information
|
||||
* @param component {@link Component} to be looked up in the NuGet repo
|
||||
*/
|
||||
private void performVersionCheck(final MetaModel meta, final Component component) {
|
||||
|
||||
String latest = findLatestVersion(filterPreReleaseVersions(versions));
|
||||
if (latest == null) {
|
||||
latest = findLatestVersion(versions);
|
||||
if (registrationsBaseUrl == null || registrationsBaseUrl.isBlank()) {
|
||||
LOGGER.debug("Registration URL not defined for repo " + this.serviceIndexUrl + " - skipping version check");
|
||||
return;
|
||||
}
|
||||
meta.setLatestVersion(latest);
|
||||
|
||||
LOGGER.debug("Performing version check for: " + component.getPurl().getName() + " using " + registrationsBaseUrl);
|
||||
|
||||
try {
|
||||
final var packageRegistrationRoot = fetchPackageRegistrationIndex(registrationsBaseUrl, component);
|
||||
|
||||
if(packageRegistrationRoot == null) {
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component);
|
||||
|
||||
// Search for a release version first...
|
||||
AbridgedNugetCatalogEntry abridgedNugetCatalogEntry = findLatestViaRegistrations(packageRegistrationRoot, false);
|
||||
|
||||
// ... then try again if none found, looking for the latest pre-release version
|
||||
if (abridgedNugetCatalogEntry == null) {
|
||||
abridgedNugetCatalogEntry = findLatestViaRegistrations(packageRegistrationRoot, true);
|
||||
}
|
||||
|
||||
if (abridgedNugetCatalogEntry != null) {
|
||||
meta.setLatestVersion(abridgedNugetCatalogEntry.getVersion());
|
||||
meta.setPublishedTimestamp(abridgedNugetCatalogEntry.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
handleRequestException(LOGGER, e);
|
||||
} catch (Exception ex) {
|
||||
throw new MetaAnalyzerException(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String findLatestVersion(JSONArray versions) {
|
||||
/**
|
||||
* Retrieves the package registration index for the specified component
|
||||
* (e.g. https://api.nuget.org/v3/registration5-gz-semver2/microsoft.data.sqlclient/index.json) and converts to JSON
|
||||
* @param registrationsBaseUrl Registration base URL to look up package info
|
||||
* @param component Component for which retrieve package registration data should be retrieved
|
||||
* @return JSONObject containing package data if found or null if data not found
|
||||
* @throws IOException if HTTP request errors
|
||||
*/
|
||||
private JSONObject fetchPackageRegistrationIndex(final String registrationsBaseUrl, final Component component) throws IOException {
|
||||
final String idLower = urlEncode(component.getPurl().getName().toLowerCase());
|
||||
final String indexUrl = String.format(registrationsBaseUrl, idLower, "index");
|
||||
|
||||
if (versions.isEmpty()) {
|
||||
try (final CloseableHttpResponse resp = processHttpRequest(indexUrl)) {
|
||||
if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK || resp.getEntity() == null) {
|
||||
handleUnexpectedHttpResponse(LOGGER, indexUrl, resp.getStatusLine().getStatusCode(), resp.getStatusLine().getReasonPhrase(), component);
|
||||
return null;
|
||||
}
|
||||
return new JSONObject(EntityUtils.toString(resp.getEntity()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the NuGet Registrations to find latest version information. Handles both inline items and paged items.
|
||||
* Sorts pages in descending order by the upper version number - if a listed, final version can be found in that
|
||||
* page, it will be returned or pages will be searched in descending order until a match is found.
|
||||
* @param registrationData Registrations to be searched
|
||||
* @return Version metadata if a suitable version found, or null if not
|
||||
* @throws IOException if network error occurs
|
||||
*/
|
||||
private AbridgedNugetCatalogEntry findLatestViaRegistrations(final JSONObject registrationData, final boolean includePreRelease) throws IOException {
|
||||
|
||||
final JSONArray pages = registrationData == null ? null : registrationData.optJSONArray(NUGET_KEY_ITEMS);
|
||||
|
||||
if (pages == null || pages.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ComparableVersion latestVersion = new ComparableVersion(versions.getString(0));
|
||||
|
||||
for (int i = 1; i < versions.length(); i++) {
|
||||
ComparableVersion version = new ComparableVersion(versions.getString(i));
|
||||
if (version.compareTo(latestVersion) > 0) {
|
||||
latestVersion = version;
|
||||
// Build a list of pages sorted by descending "upper" property.
|
||||
final List<JSONObject> pageUpperBounds = new ArrayList<>();
|
||||
for (int i = 0; i < pages.length(); i++) {
|
||||
final JSONObject page = pages.optJSONObject(i);
|
||||
if (page != null && page.has(NUGET_KEY_UPPER)) {
|
||||
pageUpperBounds.add(page);
|
||||
}
|
||||
}
|
||||
|
||||
return latestVersion.toString();
|
||||
}
|
||||
// Sort upper page bounds in descending order to get newest page first e.g, [ "6.1.0", "5.1.0" ]
|
||||
pageUpperBounds.sort((pageOne, pageTwo) -> {
|
||||
final ComparableVersion pageOneUpper = new ComparableVersion(pageOne.optString(NUGET_KEY_UPPER, "0"));
|
||||
final ComparableVersion pageTwoUpper = new ComparableVersion(pageTwo.optString(NUGET_KEY_UPPER, "0"));
|
||||
return pageTwoUpper.compareTo(pageOneUpper); // descending
|
||||
});
|
||||
|
||||
private JSONArray filterPreReleaseVersions(JSONArray versions) {
|
||||
JSONArray filteredVersions = new JSONArray();
|
||||
for (int i = 0; i < versions.length(); i++) {
|
||||
if (!versions.getString(i).contains("-")) {
|
||||
filteredVersions.put(versions.getString(i));
|
||||
}
|
||||
}
|
||||
return filteredVersions;
|
||||
}
|
||||
|
||||
private boolean performLastPublishedCheck(final MetaModel meta, final Component component) {
|
||||
final String url = String.format(registrationUrl, urlEncode(component.getPurl().getName().toLowerCase()), urlEncode(meta.getLatestVersion()));
|
||||
try (final CloseableHttpResponse response = processHttpRequest(url)) {
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
if (response.getEntity() != null) {
|
||||
String stringResponse = EntityUtils.toString(response.getEntity());
|
||||
if (!stringResponse.equalsIgnoreCase("") && !stringResponse.equalsIgnoreCase("{}")) {
|
||||
JSONObject jsonResponse = new JSONObject(stringResponse);
|
||||
final String updateTime = jsonResponse.optString("published", null);
|
||||
if (updateTime != null) {
|
||||
meta.setPublishedTimestamp(parseUpdateTime(updateTime));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handleUnexpectedHttpResponse(LOGGER, url, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(), component);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
handleRequestException(LOGGER, e);
|
||||
} catch (Exception ex) {
|
||||
throw new MetaAnalyzerException(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initializeEndpoints() {
|
||||
final String url = baseUrl + INDEX_URL;
|
||||
for (final JSONObject page : pageUpperBounds) {
|
||||
try {
|
||||
try (final CloseableHttpResponse response = processHttpRequest(url)) {
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
if(response.getEntity()!=null){
|
||||
String responseString = EntityUtils.toString(response.getEntity());
|
||||
JSONObject responseJson = new JSONObject(responseString);
|
||||
final JSONArray resources = responseJson.getJSONArray("resources");
|
||||
final JSONObject packageBaseResource = findResourceByType(resources, "PackageBaseAddress");
|
||||
final JSONObject registrationsBaseResource = findResourceByType(resources, "RegistrationsBaseUrl/Versioned");
|
||||
if (packageBaseResource != null && registrationsBaseResource != null) {
|
||||
versionQueryUrl = packageBaseResource.getString("@id") + "%s/index.json";
|
||||
registrationUrl = registrationsBaseResource.getString("@id") + "%s/%s.json";
|
||||
final JSONArray leaves = resolveLeaves(page);
|
||||
final AbridgedNugetCatalogEntry bestOnPage = findHighestVersionFromLeaves(leaves, includePreRelease);
|
||||
if (bestOnPage != null) {
|
||||
return bestOnPage;
|
||||
}
|
||||
} catch (MetaAnalyzerException ex) {
|
||||
// Reporting handled in resolveLeaves - return null to avoid returning incorrect version from any page
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// No suitable version found
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the page JSON to find item leaves, retrieving data from the repo if needed. Returns null if neither
|
||||
* inline items nor a fetchable @id exist/succeed.
|
||||
* @param page Page to be parsed
|
||||
* @return JSONArray containing leaf data if available, null if not
|
||||
* @throws IOException if network error occurs
|
||||
* @throws MetaAnalyzerException if the repo returns an unexpected result
|
||||
*/
|
||||
private JSONArray resolveLeaves(final JSONObject page) throws IOException, MetaAnalyzerException {
|
||||
if (page == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final JSONArray inline = page.optJSONArray(NUGET_KEY_ITEMS);
|
||||
if (inline != null && !inline.isEmpty()) {
|
||||
LOGGER.trace("Processing inline catalog entries");
|
||||
return inline;
|
||||
}
|
||||
|
||||
final String pageUrl = page.optString("@id", null);
|
||||
if (pageUrl == null || pageUrl.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LOGGER.trace("Retrieving catalog entry page " + pageUrl);
|
||||
try (final CloseableHttpResponse resp = processHttpRequest(pageUrl)) {
|
||||
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK && resp.getEntity() != null) {
|
||||
final var pageJson = new JSONObject(EntityUtils.toString(resp.getEntity()));
|
||||
return pageJson.optJSONArray(NUGET_KEY_ITEMS);
|
||||
} else {
|
||||
handleUnexpectedHttpResponse(LOGGER, pageUrl, resp.getStatusLine().getStatusCode(), resp.getStatusLine().getReasonPhrase(), null);
|
||||
throw new MetaAnalyzerException("Could not retrieve catalog entry page when processing " + pageUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the supplied leaves to extract the latest listed version. NuGet does not guarantee release order
|
||||
* so scan the entire array although, anecdotally, the collection does generally appear to be in ascending order
|
||||
* @param leaves Items to be scanned
|
||||
* @param includePreRelease include pre-release versions in latest version lookup
|
||||
* @return {@link AbridgedNugetCatalogEntry containing the latest version found in the leaves collection
|
||||
*/
|
||||
private AbridgedNugetCatalogEntry findHighestVersionFromLeaves(final JSONArray leaves, final boolean includePreRelease) {
|
||||
|
||||
if (leaves == null || leaves.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AbridgedNugetCatalogEntry bestEntry = null;
|
||||
ComparableVersion newestVersionFound = null;
|
||||
|
||||
for (int i = 0; i < leaves.length(); i++) {
|
||||
final JSONObject leaf = leaves.optJSONObject(i);
|
||||
AbridgedNugetCatalogEntry entry = null;
|
||||
|
||||
if (leaf.has("catalogEntry")) {
|
||||
entry = parseCatalogEntry(leaf.optJSONObject("catalogEntry"));
|
||||
}
|
||||
|
||||
if (entry == null || entry.getVersion() == null || (isPreRelease(entry.getVersion()) && !includePreRelease)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final ComparableVersion entryVersion = new ComparableVersion(entry.getVersion());
|
||||
if (newestVersionFound == null || entryVersion.compareTo(newestVersionFound) > 0) {
|
||||
newestVersionFound = entryVersion;
|
||||
bestEntry = entry;
|
||||
}
|
||||
}
|
||||
|
||||
return bestEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a single catalog entry to extract the version and published information. Could be extended to include other
|
||||
* fields (such as listed) if required. Returns null immediately if the entry is unlisted.
|
||||
* @param catalogEntry Catalog entry to be parsed
|
||||
* @return {@link AbridgedNugetCatalogEntry} if version is valid, null if not
|
||||
*/
|
||||
private AbridgedNugetCatalogEntry parseCatalogEntry(final JSONObject catalogEntry) {
|
||||
|
||||
// Listed is optional so assume package is listed unless explicitly hidden
|
||||
boolean listed = catalogEntry.optBoolean("listed", true);
|
||||
|
||||
if(!listed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var version = catalogEntry.optString("version", null);
|
||||
if (version == null || version.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
AbridgedNugetCatalogEntry entry = new AbridgedNugetCatalogEntry();
|
||||
entry.setVersion(version);
|
||||
|
||||
var updateTime = catalogEntry.optString("published", null);
|
||||
if (updateTime != null) {
|
||||
entry.setPublishedTimestamp(parseUpdateTime(updateTime));
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* NuGet considers a version string with any suffix after a hyphen to be pre-release according to <a
|
||||
* href="https://learn.microsoft.com/en-us/nuget/concepts/package-versioning?tabs=semver20sort#pre-release-versions">
|
||||
* the documentation</a>. This method could be expanded if we need to cover other rules.
|
||||
* @param version Version string to be tested
|
||||
* @return True if version matches pre-release conventions, false otherwise
|
||||
*/
|
||||
private boolean isPreRelease(final String version) {
|
||||
return version.contains("-");
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the NuGet repo, retrieves the service index and attempts to find the best RegistrationsBaseUrl
|
||||
* @return RegistrationsBaseUrl if found, null otherwise
|
||||
*/
|
||||
private String findRegistrationsBaseUrl() {
|
||||
|
||||
JSONObject responseJson = null;
|
||||
|
||||
try (final CloseableHttpResponse resp = processHttpRequest(this.serviceIndexUrl)) {
|
||||
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK && resp.getEntity() != null) {
|
||||
responseJson = new JSONObject(EntityUtils.toString(resp.getEntity()));
|
||||
} else {
|
||||
handleUnexpectedHttpResponse(LOGGER, this.serviceIndexUrl, resp.getStatusLine().getStatusCode(), resp.getStatusLine().getReasonPhrase(), null);
|
||||
throw new MetaAnalyzerException("Could not initialize NugetMetaAnalyzer - unexpected response from NuGet service. Response code was " + resp.getStatusLine().getStatusCode() + ".");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
handleRequestException(LOGGER, e);
|
||||
}
|
||||
|
||||
if (responseJson != null) {
|
||||
final JSONArray resources = responseJson.optJSONArray("resources");
|
||||
final String regBaseUrl = extractRegistrationBaseUrlFromJson(resources);
|
||||
if (regBaseUrl != null) {
|
||||
LOGGER.debug("RegistrationsBaseUrl selected: " + regBaseUrl);
|
||||
return regBaseUrl;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.debug("Could not find the RegistrationsBaseUrl at " + this.serviceIndexUrl);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find the "best" RegistrationsBaseUrl from the NuGet service index preferring SemVer 2 with
|
||||
* compression, SemVer 2 without compression then non-compressed, non-SemVer2.
|
||||
* See <a href="https://learn.microsoft.com/en-us/nuget/api/registration-base-url-resource>for versioning
|
||||
* details</a>
|
||||
* @param serviceIndexJson JSONArray containing the NuGet repo service index
|
||||
* @return RegistrationsBaseUrl or null if none found
|
||||
*/
|
||||
private String extractRegistrationBaseUrlFromJson(JSONArray serviceIndexJson) {
|
||||
|
||||
if (serviceIndexJson == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Prefer SemVer2 registrations if available
|
||||
final JSONObject regsSemver2 = findResourceByType(serviceIndexJson, "RegistrationsBaseUrl/3.6.0");
|
||||
if (regsSemver2 != null) {
|
||||
return regsSemver2.optString("@id", null);
|
||||
}
|
||||
|
||||
// Failing that, check for the gzipped registration hive
|
||||
final JSONObject regsGzipped = findResourceByType(serviceIndexJson, "RegistrationsBaseUrl/3.4.0");
|
||||
if (regsGzipped != null) {
|
||||
return regsGzipped.optString("@id", null);
|
||||
}
|
||||
|
||||
// Worst case, check for the non-gzipped version
|
||||
final JSONObject fallback = findResourceByType(serviceIndexJson, "RegistrationsBaseUrl");
|
||||
if (fallback != null) {
|
||||
return fallback.optString("@id", null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private JSONObject findResourceByType(JSONArray resources, String type) {
|
||||
|
@ -219,20 +477,66 @@ public class NugetMetaAnalyzer extends AbstractMetaAnalyzer {
|
|||
return null;
|
||||
}
|
||||
|
||||
private Date parseUpdateTime(String updateTime) {
|
||||
if (updateTime == null) {
|
||||
/**
|
||||
* Attempts to parse a NuGet date time string to a {@link Date}. NuGet repositories may use differing date formats
|
||||
* so this method tries a couple of attempts. The
|
||||
* <a href="https://learn.microsoft.com/en-us/nuget/api/registration-base-url-resource#catalog-entry">MS
|
||||
* spec states that ISO8601 should be used</a> but that standard is flexible when it comes to timezone info.
|
||||
* <p>
|
||||
* The ISO_INSTANT formatter handles time with timezone and milliseconds ("yyyy-MM-dd'T'HH:mm:ss.SSSXXX") and
|
||||
* UTC-only ("yyyy-MM-dd'T'HH:mm:ss'Z'"). A fallback LocalDateTime parser handles cases without a timezone
|
||||
* ("yyyy-MM-dd'T'HH:mm:ss").
|
||||
* @param nugetDateTimeString Date time string in one of NuGet's permitted formats
|
||||
* @return Date if input could be parsed, null if date could not be parsed
|
||||
*/
|
||||
protected Date parseUpdateTime(String nugetDateTimeString) {
|
||||
if (nugetDateTimeString == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NuGet repositories may use differing date formats, so we try a few date formats that are commonly used until the right one is found.
|
||||
for (DateFormat dateFormat : SUPPORTED_DATE_FORMATS) {
|
||||
try {
|
||||
return dateFormat.parse(updateTime);
|
||||
} catch (ParseException e) {
|
||||
LOGGER.warn("An error occurred while parsing upload time for a NuGet component - Repo returned: " + updateTime);
|
||||
}
|
||||
}
|
||||
|
||||
TemporalAccessor ta = DateTimeFormatter.ISO_INSTANT.parse(nugetDateTimeString);
|
||||
return Date.from(Instant.from(ta));
|
||||
} catch (DateTimeParseException e) {
|
||||
try {
|
||||
LocalDateTime localDateTime = LocalDateTime.parse(nugetDateTimeString);
|
||||
return Date.from(localDateTime.atOffset(ZoneOffset.UTC).toInstant());
|
||||
} catch (DateTimeParseException e2) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal class to collate useful version information from the larger NuGet catalog entry
|
||||
*/
|
||||
private static class AbridgedNugetCatalogEntry {
|
||||
private String version;
|
||||
private Date publishedTimestamp;
|
||||
|
||||
private String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
private void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
private Date getPublishedTimestamp() {
|
||||
return publishedTimestamp;
|
||||
}
|
||||
|
||||
private void setPublishedTimestamp(Date publishedTimestamp) {
|
||||
this.publishedTimestamp = publishedTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AbridgedNugetCatalogEntry{" +
|
||||
"version='" + version + '\'' +
|
||||
", publishedTimestamp=" + publishedTimestamp +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,148 +22,550 @@ import com.github.packageurl.PackageURL;
|
|||
import org.apache.http.HttpHeaders;
|
||||
import org.dependencytrack.model.Component;
|
||||
import org.dependencytrack.model.RepositoryType;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockserver.client.MockServerClient;
|
||||
import org.mockserver.integration.ClientAndServer;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
import org.mockserver.model.Header;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.dependencytrack.tasks.repositories.NugetMetaAnalyzer.SUPPORTED_DATE_FORMATS;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
class NugetMetaAnalyzerTest {
|
||||
|
||||
public static final String LOCALHOST_REPO_INDEX = "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/index.json";
|
||||
private static ClientAndServer mockServer;
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() {
|
||||
static void beforeClass() throws Exception {
|
||||
mockServer = ClientAndServer.startClientAndServer(1080);
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/index.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.v3-index.json",
|
||||
null, "application/json", 200
|
||||
);
|
||||
}
|
||||
|
||||
private static void setupMockServerClient(
|
||||
String path,
|
||||
String responseFile,
|
||||
String encodedBasicHeader
|
||||
) throws Exception {
|
||||
setupMockServerClient(path, responseFile, encodedBasicHeader, "application/json", 200);
|
||||
}
|
||||
|
||||
private static void setupMockServerClient(
|
||||
String path,
|
||||
String responseFile,
|
||||
String encodedBasicHeader,
|
||||
String contentType,
|
||||
int statusCode
|
||||
) throws Exception {
|
||||
|
||||
List<Header> headers = new ArrayList<>();
|
||||
if (encodedBasicHeader != null) {
|
||||
headers.add(new Header("Authorization", encodedBasicHeader));
|
||||
}
|
||||
|
||||
new MockServerClient("localhost", 1080)
|
||||
.when(
|
||||
request()
|
||||
.withMethod("GET")
|
||||
.withPath(path)
|
||||
.withHeaders(headers)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(statusCode)
|
||||
.withHeader(HttpHeaders.CONTENT_TYPE, contentType)
|
||||
.withBody(Files.readString(Paths.get(NugetMetaAnalyzerTest.class.getResource(responseFile).toURI())))
|
||||
);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClass() {
|
||||
static void afterClass() {
|
||||
mockServer.stop();
|
||||
}
|
||||
|
||||
// This test is to check if the analyzer is:
|
||||
// * excluding pre-release versions if a release version exists,
|
||||
// * including pre-release versions if no release version exists
|
||||
// The test is transient depending on the current version of the package
|
||||
// retrieved from the repository at the time of running.
|
||||
// For example, when it was created, the latest released version of:
|
||||
// * Microsoft.Extensions.DependencyInjection was 9.0.0-preview.1.24080.9
|
||||
// * OpenTelemetry.Instrumentation.SqlClient was 1.12.0-beta.2 (no release version exists)
|
||||
@ParameterizedTest
|
||||
@MethodSource("testAnalyzerData")
|
||||
void testAnalyzer(String purl, boolean isLatestVersionPreRelease) throws Exception {
|
||||
Component component = new Component();
|
||||
component.setPurl(new PackageURL(purl));
|
||||
NugetMetaAnalyzer analyzer = new NugetMetaAnalyzer();
|
||||
/**
|
||||
* Various tests to confirm error handling behaviour when, e.g. the repo or package cannot
|
||||
* be found. The analyzer should still return a MetaModel in these cases with null version and
|
||||
* published. The analyzer should NOT crash.
|
||||
*/
|
||||
@Nested
|
||||
class ErrorHandlingTests {
|
||||
|
||||
@Test
|
||||
void testBaseUrlNotFoundBehaviourWhenSettingRepoUrl() {
|
||||
Assertions.assertDoesNotThrow(() -> {
|
||||
var analyzer = new NugetMetaAnalyzer();
|
||||
analyzer.setRepositoryBaseUrl("http://no-such-api.this-host-does-not-exist-nuget-repo.invalid");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBaseUrlNotFoundBehaviourWhenCallingAnalyze() {
|
||||
Assertions.assertDoesNotThrow(() -> {
|
||||
var analyzer = new NugetMetaAnalyzer();
|
||||
analyzer.setRepositoryBaseUrl("http://no-such-api.this-host-does-not-exist-nuget-repo.invalid");
|
||||
|
||||
Component component = new Component();
|
||||
component.setPurl(new PackageURL("pkg:nuget/CycloneDX.Core@5.4.0"));
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
|
||||
Assertions.assertTrue(analyzer.isApplicable(component));
|
||||
assertMetaModelExistsButEmpty(analyzer, metaModel);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRepoValidButPackageNotFoundBehaviour() throws Exception {
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/testing.no.such.package/index.json",
|
||||
"/unit/tasks/repositories/https---nuget.org.no-such-package.xml",
|
||||
null,
|
||||
"application/xml",
|
||||
404
|
||||
);
|
||||
|
||||
Component component = new Component();
|
||||
component.setPurl(new PackageURL("pkg:nuget/Testing.No.Such.Package@8.0.0"));
|
||||
|
||||
var analyzer = new NugetMetaAnalyzer();
|
||||
analyzer.setRepositoryBaseUrl(LOCALHOST_REPO_INDEX);
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
|
||||
assertMetaModelExistsButEmpty(analyzer, metaModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testErrorBetweenPageRequestsReturnsNullData() throws Exception {
|
||||
|
||||
var analyzer = new NugetMetaAnalyzer();
|
||||
analyzer.setRepositoryBaseUrl(LOCALHOST_REPO_INDEX);
|
||||
|
||||
var component = new Component();
|
||||
component.setName("Microsoft.Data.SqlClient");
|
||||
component.setPurl(new PackageURL("pkg:nuget/Microsoft.Data.SqlClient@5.1.0"));
|
||||
|
||||
mockServer.reset();
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/index.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.v3-index.json",
|
||||
null, "application/json", 200
|
||||
);
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/index.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.index.json",
|
||||
null
|
||||
);
|
||||
|
||||
// Page 2
|
||||
new MockServerClient("localhost", 1080)
|
||||
.when(
|
||||
request()
|
||||
.withMethod("GET")
|
||||
.withPath("/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/5.1.1/6.1.0.json")
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(401)
|
||||
.withHeader(HttpHeaders.CONTENT_TYPE, "application/xml")
|
||||
.withBody("<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>TestError</Code><Message>Not Authorised</Message></Error>")
|
||||
);
|
||||
|
||||
// Page 1
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/1.0.19123.2-preview/5.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page1.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertNull(metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullComponentThrowsIllegalArgumentException() {
|
||||
var analyzer = new NugetMetaAnalyzer();
|
||||
analyzer.setRepositoryBaseUrl(LOCALHOST_REPO_INDEX);
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> analyzer.analyze(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void assertMetaModelExistsButEmpty(NugetMetaAnalyzer analyzer, MetaModel metaModel) {
|
||||
Assertions.assertEquals(RepositoryType.NUGET, analyzer.supportedRepositoryType());
|
||||
Assertions.assertNull(metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests against JSON files captured from nuget.org to avoid making live calls and to control test data state. Main
|
||||
* difference between Nuget and the Artifactory tests is Nuget includes a published date value. To run these tests
|
||||
* against the live nuget feed, simply change the URL in the setup method to api.nuget.org - you can ignore the
|
||||
* MockServerClient calls because they won't be invoked.
|
||||
*/
|
||||
@Nested
|
||||
class NugetTests {
|
||||
|
||||
private Component component;
|
||||
private NugetMetaAnalyzer analyzer;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
this.component = new Component();
|
||||
this.component.setInternal(false);
|
||||
this.component.setName("Microsoft.Data.SqlClient");
|
||||
this.component.setPurl(new PackageURL("pkg:nuget/Microsoft.Data.SqlClient@5.0.1"));
|
||||
|
||||
this.analyzer = new NugetMetaAnalyzer();
|
||||
this.analyzer.setRepositoryBaseUrl("https://api.nuget.org");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithMultipleInlinePages() throws Exception {
|
||||
|
||||
// This test also effectively covers pre-release versions (e.g. 6.1.0-preview2.25178.5)
|
||||
// and unlisted versions (6.1.0) by returning 6.0.2
|
||||
|
||||
setupMockServerClient(
|
||||
"/v3/index.json",
|
||||
"/unit/tasks/repositories/https---nuget.org.v3-index.json",
|
||||
null
|
||||
);
|
||||
|
||||
setupMockServerClient(
|
||||
"/v3/registration5-gz-semver2/microsoft.data.sqlclient/index.json",
|
||||
"/unit/tasks/repositories/https---nuget.org.registration-semver2.mds.index-inline-pages.json",
|
||||
null
|
||||
);
|
||||
|
||||
this.analyzer.setRepositoryBaseUrl("http://localhost:1080/v3/index.json");
|
||||
|
||||
analyzer.setRepositoryBaseUrl("https://api.nuget.org");
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
|
||||
Assertions.assertTrue(analyzer.isApplicable(component));
|
||||
Assertions.assertEquals(RepositoryType.NUGET, analyzer.supportedRepositoryType());
|
||||
Assertions.assertNotNull(metaModel.getLatestVersion());
|
||||
|
||||
Assertions.assertEquals("6.0.2", metaModel.getLatestVersion());
|
||||
|
||||
// nuget feeds should return a published date
|
||||
Assertions.assertNotNull(metaModel.getPublishedTimestamp());
|
||||
Assertions.assertEquals(isLatestVersionPreRelease, metaModel.getLatestVersion().contains("-"));
|
||||
Date expected = analyzer.parseUpdateTime("2025-04-25T21:29:47.897+00:00");
|
||||
Assertions.assertEquals(expected, metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
static Stream<Arguments> testAnalyzerData() {
|
||||
return Stream.of(
|
||||
Arguments.of("pkg:nuget/CycloneDX.Core@5.4.0", false),
|
||||
Arguments.of("pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0", false),
|
||||
Arguments.of("pkg:nuget/Microsoft.Extensions.DependencyInjection@8.0.0-beta.21301.5", false),
|
||||
Arguments.of("pkg:nuget/OpenTelemetry.Instrumentation.SqlClient@1.12.0-beta.1", true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Artifactory doesn't provide published dates and favours (only uses?) paged registration data.
|
||||
* This collection uses the service index to find the best RegistrationsBaseUrl, in this case
|
||||
* for semver2
|
||||
*/
|
||||
@Nested
|
||||
class ArtifactoryTestsSemver2Tests {
|
||||
|
||||
NugetMetaAnalyzer analyzer;
|
||||
Component component;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
|
||||
this.analyzer = new NugetMetaAnalyzer();
|
||||
this.analyzer.setRepositoryBaseUrl(LOCALHOST_REPO_INDEX);
|
||||
|
||||
this.component = new Component();
|
||||
this.component.setName("Microsoft.Data.SqlClient");
|
||||
this.component.setPurl(new PackageURL("pkg:nuget/Microsoft.Data.SqlClient@5.1.0"));
|
||||
|
||||
mockServer.reset();
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/index.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.v3-index.json",
|
||||
null, "application/json", 200
|
||||
);
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/index.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.index.json",
|
||||
null
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithPrivatePackageRepository() throws Exception {
|
||||
String mockIndexResponse = readResourceFileToString("/unit/tasks/repositories/https---localhost-1080-v3-index.json");
|
||||
new MockServerClient("localhost", mockServer.getPort())
|
||||
.when(
|
||||
request()
|
||||
.withMethod("GET")
|
||||
.withPath("/v3/index.json")
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(200)
|
||||
.withHeader(HttpHeaders.CONTENT_TYPE, "application/json")
|
||||
.withBody(mockIndexResponse)
|
||||
);
|
||||
String encodedBasicHeader = "Basic OnBhc3N3b3Jk";
|
||||
void testAnalyzerWithMultipageRegistrationInfo() throws Exception {
|
||||
|
||||
String mockVersionResponse = readResourceFileToString("/unit/tasks/repositories/https---localhost-1080-v3-flat2" +
|
||||
"-nunitprivate-index.json");
|
||||
new MockServerClient("localhost", mockServer.getPort())
|
||||
.when(
|
||||
request()
|
||||
.withMethod("GET")
|
||||
.withPath("/v3/flat2/nunitprivate/index.json")
|
||||
.withHeader("Authorization", encodedBasicHeader)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(200)
|
||||
.withHeader(HttpHeaders.CONTENT_TYPE, "application/json")
|
||||
.withBody(mockVersionResponse)
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/5.1.1/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page2.json",
|
||||
null
|
||||
);
|
||||
|
||||
String mockRegistrationResponse = readResourceFileToString("/unit/tasks/repositories/https---localhost-1080-v3" +
|
||||
"-registrations2-nunitprivate-502.json");
|
||||
new MockServerClient("localhost", mockServer.getPort())
|
||||
.when(
|
||||
request()
|
||||
.withMethod("GET")
|
||||
.withPath("/v3/registrations2-semver2/nunitprivate/5.0.2.json")
|
||||
.withHeader("Authorization", encodedBasicHeader)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(200)
|
||||
.withHeader(HttpHeaders.CONTENT_TYPE, "application/json")
|
||||
.withBody(mockRegistrationResponse)
|
||||
// Page 1
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/1.0.19123.2-preview/5.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page1.json",
|
||||
null
|
||||
);
|
||||
Component component = new Component();
|
||||
component.setPurl(new PackageURL("pkg:nuget/NUnitPrivate@5.0.1"));
|
||||
NugetMetaAnalyzer analyzer = new NugetMetaAnalyzer();
|
||||
analyzer.setRepositoryUsernameAndPassword(null, "password");
|
||||
analyzer.setRepositoryBaseUrl("http://localhost:1080");
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("5.0.2", metaModel.getLatestVersion());
|
||||
Assertions.assertNotNull(metaModel.getPublishedTimestamp());
|
||||
Assertions.assertEquals("6.0.2", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPublishedDateTimeFormat() throws ParseException {
|
||||
Date dateParsed = null;
|
||||
for (DateFormat dateFormat : SUPPORTED_DATE_FORMATS) {
|
||||
try {
|
||||
dateParsed = dateFormat.parse("1900-01-01T00:00:00+00:00");
|
||||
} catch (ParseException e) {}
|
||||
}
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
Assertions.assertEquals(dateFormat.parse("1900-01-01T00:00:00+00:00"), dateParsed);
|
||||
void testAnalyzerWithMultipageRegistrationInfoIgnorePreReleaseAndUnlisted() throws Exception {
|
||||
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/5.1.1/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page2-check-pre-release.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("5.1.2", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
private String readResourceFileToString(String fileName) throws Exception {
|
||||
return Files.readString(Paths.get(getClass().getResource(fileName).toURI()));
|
||||
@Test
|
||||
void testAnalyzerWithMultipageRegistrationInfoWhenPage2AllUnlisted() throws Exception {
|
||||
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/5.1.1/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page2-all-unlisted.json",
|
||||
null
|
||||
);
|
||||
|
||||
// Page 1
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/1.0.19123.2-preview/5.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page1.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("5.1.0", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithMultipageRegistrationInfoWhenPage2AllPreRelease() throws Exception {
|
||||
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/5.1.1/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page2-all-pre-release.json",
|
||||
null
|
||||
);
|
||||
|
||||
// Page 1
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/1.0.19123.2-preview/5.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver2.mds.page1.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("5.1.0", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithPreReleaseOnlyVersionsReturnsLatestPreReleaseVersion() throws Exception {
|
||||
|
||||
// Test for log warning covered in 5075 - ensure no errors are thrown / logged
|
||||
// when no release versions exist
|
||||
|
||||
setupMockServerClient(
|
||||
"/v3/index.json",
|
||||
"/unit/tasks/repositories/https---nuget.org.v3-index.json",
|
||||
null
|
||||
);
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration-semver2/opentelemetry.instrumentation.sqlclient/index.json",
|
||||
"/unit/tasks/repositories/https---nuget.org.registration-semver2.beta-releases-only.index-inline-pages.json",
|
||||
null
|
||||
);
|
||||
|
||||
var betaOnlyComponent = new Component();
|
||||
betaOnlyComponent.setInternal(false);
|
||||
betaOnlyComponent.setName("OpenTelemetry.Instrumentation.SqlClient");
|
||||
betaOnlyComponent.setPurl(new PackageURL("pkg:nuget/OpenTelemetry.Instrumentation.SqlClient@1.12.0-beta.2"));
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(betaOnlyComponent);
|
||||
|
||||
Assertions.assertTrue(analyzer.isApplicable(betaOnlyComponent));
|
||||
Assertions.assertEquals(RepositoryType.NUGET, analyzer.supportedRepositoryType());
|
||||
Assertions.assertNotNull(metaModel.getLatestVersion());
|
||||
Assertions.assertEquals("1.12.0-beta.2", metaModel.getLatestVersion());
|
||||
Date expected = analyzer.parseUpdateTime("2025-07-15T04:42:33.33+00:00");
|
||||
Assertions.assertEquals(expected, metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Artifactory doesn't provide published dates and favours (only uses?) paged registration data.
|
||||
* This collection forces a semver1 RegistrationsBaseUrl. The chosen test package,
|
||||
* microsoft.data.sqlclient, returns the same number of items (64) as the semver2 version but the
|
||||
* results appear on a single page instead of 2 with the semver2 version.
|
||||
*/
|
||||
@Nested
|
||||
class ArtifactoryTestsSemver1Tests {
|
||||
|
||||
NugetMetaAnalyzer analyzer;
|
||||
Component component;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
|
||||
this.analyzer = new NugetMetaAnalyzer();
|
||||
this.analyzer.setRepositoryBaseUrl(LOCALHOST_REPO_INDEX);
|
||||
this.analyzer.setRegistrationsBaseUrl("http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/");
|
||||
|
||||
this.component = new Component();
|
||||
this.component.setName("Microsoft.Data.SqlClient");
|
||||
this.component.setPurl(new PackageURL("pkg:nuget/Microsoft.Data.SqlClient@5.1.0"));
|
||||
|
||||
mockServer.reset();
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/index.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.v3-index.json",
|
||||
null, "application/json", 200
|
||||
);
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/index.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver1.mds.index.json",
|
||||
null
|
||||
);
|
||||
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/page/1.0.19123.2-preview/1.1.2.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver1.mds.page1.json",
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithMultipageRegistrationInfo() throws Exception {
|
||||
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/page/5.2.2/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver1.mds.page2.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("6.0.2", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithMultipageRegistrationInfoIgnorePreReleaseAndUnlisted() throws Exception {
|
||||
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/page/5.2.2/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver1.mds.page2-check-pre-release.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("6.0.1", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithMultipageRegistrationInfoWhenPage2AllUnlisted() throws Exception {
|
||||
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/page/5.2.2/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver1.mds.page2-all-unlisted.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("1.1.2", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAnalyzerWithMultipageRegistrationInfoWhenPage2AllPreRelease() throws Exception {
|
||||
|
||||
// Page 2
|
||||
setupMockServerClient(
|
||||
"/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/page/5.2.2/6.1.0.json",
|
||||
"/unit/tasks/repositories/https---localhost-nuget-artifactory.registration-semver1.mds.page2-all-pre-release.json",
|
||||
null
|
||||
);
|
||||
|
||||
MetaModel metaModel = analyzer.analyze(component);
|
||||
Assertions.assertEquals("1.1.2", metaModel.getLatestVersion());
|
||||
Assertions.assertNull(metaModel.getPublishedTimestamp());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class DateParserTests {
|
||||
|
||||
NugetMetaAnalyzer analyzer = new NugetMetaAnalyzer();
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"1900-01-01T00:00:00+00:00",
|
||||
"2025-08-13T23:22:21.20+01:00",
|
||||
"2025-08-13T23:22:21Z",
|
||||
"2020-08-04T10:39:03.7136823",
|
||||
"2025-08-13T23:22:21",
|
||||
"2020-08-04T10:39:03.7136823",
|
||||
"2023-03-28T22:26:40.43+00:00",
|
||||
"2025-08-14T08:12:23.8207879Z"
|
||||
})
|
||||
void shouldParseValidDateFormats(String dateString) {
|
||||
Date result = this.analyzer.parseUpdateTime(dateString);
|
||||
Assertions.assertNotNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnNullForBlankString() {
|
||||
Assertions.assertNull(this.analyzer.parseUpdateTime(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnNullForInvalidDate() {
|
||||
Assertions.assertNull(this.analyzer.parseUpdateTime("not-a-date"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnNullForNullInput() {
|
||||
Assertions.assertNull(this.analyzer.parseUpdateTime(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"versions": [
|
||||
"5.0.2",
|
||||
"5.0.1"
|
||||
]
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
{
|
||||
"@context": {
|
||||
"@vocab": "http://schema.nuget.org/services#",
|
||||
"comment": "http://www.w3.org/2000/01/rdf-schema#comment",
|
||||
"label": "http://www.w3.org/2000/01/rdf-schema#label"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"@id": "http://localhost:1080/v2/",
|
||||
"@type": "PackagePublish/2.0.0"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v2/",
|
||||
"@type": "LegacyGallery/2.0.0"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registrations2/",
|
||||
"@type": "RegistrationsBaseUrl/3.0.0-beta"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registrations2-semver2/",
|
||||
"@type": "RegistrationsBaseUrl/3.6.0",
|
||||
"comment": "This base URL includes SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registrations2-semver2/",
|
||||
"@type": "RegistrationsBaseUrl/Versioned",
|
||||
"comment": "This base URL includes SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/query2/",
|
||||
"@type": "SearchQueryService/3.0.0-beta"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/flat2/",
|
||||
"@type": "PackageBaseAddress/3.0.0"
|
||||
}
|
||||
],
|
||||
"version": "3.0.0-beta"
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"@id": "http://localhost:1080/v3/registrations2/nugetprivate/5.0.2.json",
|
||||
"@type": [
|
||||
"Package",
|
||||
"http://schema.nuget.org/catalog#Permalink"
|
||||
],
|
||||
"catalogEntry": "http://localhost:1080/commitLog/82a44df5f3474a989c4ffc1fba9ffff4",
|
||||
"listed": true,
|
||||
"packageContent": "http://localhost:1080/v3/flat2/nugetprivate/5.0.2/nugetprivate.5.0.2.nupkg",
|
||||
"published": "2022-04-13T13:30:25Z",
|
||||
"registration": "http://localhost:1080/v3/registrations2/nugetprivate/index.json",
|
||||
"@context": {
|
||||
"@vocab": "http://schema.nuget.org/schema#",
|
||||
"xsd": "http://www.w3.org/2001/XMLSchema#",
|
||||
"catalogEntry": {
|
||||
"@type": "@id"
|
||||
},
|
||||
"registration": {
|
||||
"@type": "@id"
|
||||
},
|
||||
"packageContent": {
|
||||
"type": "@id"
|
||||
},
|
||||
"published": {
|
||||
"@type": "xsd:dateTime"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"count": 2,
|
||||
"items": [
|
||||
{
|
||||
"count": 10,
|
||||
"lower": "1.0.19123.2-Preview",
|
||||
"upper": "1.1.2",
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/page/1.0.19123.2-preview/1.1.2.json"
|
||||
},
|
||||
{
|
||||
"count": 6,
|
||||
"lower": "5.2.2",
|
||||
"upper": "6.1.0",
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/page/5.2.2/6.1.0.json"
|
||||
}
|
||||
],
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/microsoft.data.sqlclient/index.json"
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"count": 2,
|
||||
"items": [
|
||||
{
|
||||
"count": 64,
|
||||
"lower": "1.0.19123.2-Preview",
|
||||
"upper": "5.1.0",
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/1.0.19123.2-preview/5.1.0.json"
|
||||
},
|
||||
{
|
||||
"count": 25,
|
||||
"lower": "5.1.1",
|
||||
"upper": "6.1.0",
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/5.1.1/6.1.0.json"
|
||||
}
|
||||
],
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/index.json"
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,924 @@
|
|||
{
|
||||
"count": 3,
|
||||
"lower": "5.1.1",
|
||||
"parent": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/index.json",
|
||||
"upper": "6.1.0",
|
||||
"items": [
|
||||
{
|
||||
"catalogEntry": {
|
||||
"authors": "Microsoft",
|
||||
"description": "Provides the data provider for SQL Server. These classes provide access to versions of SQL Server and encapsulate database-specific protocols, including tabular data stream (TDS)\n \nCommonly Used Types:\nMicrosoft.Data.SqlClient.SqlConnection\nMicrosoft.Data.SqlClient.SqlException\nMicrosoft.Data.SqlClient.SqlParameter\nMicrosoft.Data.SqlClient.SqlDataReader\nMicrosoft.Data.SqlClient.SqlCommand\nMicrosoft.Data.SqlClient.SqlTransaction\nMicrosoft.Data.SqlClient.SqlParameterCollection\nMicrosoft.Data.SqlClient.SqlClientFactory\n\nWhen using NuGet 3.x this package requires at least version 3.4.",
|
||||
"iconUrl": "https://api.nuget.org/v3-flatcontainer/microsoft.data.sqlclient/5.1.1/icon",
|
||||
"deprecation": {
|
||||
"reasons": [
|
||||
"CriticalBugs"
|
||||
],
|
||||
"message": "An important security issue exists in this version of the package. It is recommended to update to a newer version.\nhttps://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-0056"
|
||||
},
|
||||
"language": "",
|
||||
"licenseUrl": "https://www.nuget.org/packages/Microsoft.Data.SqlClient/5.1.1/license",
|
||||
"listed": true,
|
||||
"packageContent": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/Download/microsoft.data.sqlclient/5.1.1",
|
||||
"projectUrl": "https://aka.ms/sqlclientproject",
|
||||
"requireLicenseAcceptance": true,
|
||||
"summary": "",
|
||||
"tags": [
|
||||
"sqlclient",
|
||||
"microsoft.data.sqlclient"
|
||||
],
|
||||
"title": "Microsoft.Data.SqlClient",
|
||||
"version": "5.1.1-pre-release-test",
|
||||
"dependencyGroups": [
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[4.5.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.buffers/index.json",
|
||||
"id": "System.Buffers"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.interopservices.runtimeinformation/index.json",
|
||||
"id": "System.Runtime.InteropServices.RuntimeInformation"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETFramework4.6.2"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.diagnostics.diagnosticsource/index.json",
|
||||
"id": "System.Diagnostics.DiagnosticSource"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": "net6.0"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.win32.registry/index.json",
|
||||
"id": "Microsoft.Win32.Registry"
|
||||
},
|
||||
{
|
||||
"range": "[4.5.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.buffers/index.json",
|
||||
"id": "System.Buffers"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.loader/index.json",
|
||||
"id": "System.Runtime.Loader"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETStandard2.0"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.win32.registry/index.json",
|
||||
"id": "Microsoft.Win32.Registry"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.loader/index.json",
|
||||
"id": "System.Runtime.Loader"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETStandard2.1"
|
||||
}
|
||||
],
|
||||
"id": "Microsoft.Data.SqlClient"
|
||||
},
|
||||
"packageContent": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/Download/microsoft.data.sqlclient/5.1.1",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient/index.json",
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient/5.1.1.json"
|
||||
},
|
||||
{
|
||||
"catalogEntry": {
|
||||
"authors": "Microsoft",
|
||||
"description": "Provides the data provider for SQL Server. These classes provide access to versions of SQL Server and encapsulate database-specific protocols, including tabular data stream (TDS)\n \nCommonly Used Types:\nMicrosoft.Data.SqlClient.SqlConnection\nMicrosoft.Data.SqlClient.SqlException\nMicrosoft.Data.SqlClient.SqlParameter\nMicrosoft.Data.SqlClient.SqlDataReader\nMicrosoft.Data.SqlClient.SqlCommand\nMicrosoft.Data.SqlClient.SqlTransaction\nMicrosoft.Data.SqlClient.SqlParameterCollection\nMicrosoft.Data.SqlClient.SqlClientFactory\n\nWhen using NuGet 3.x this package requires at least version 3.4.",
|
||||
"iconUrl": "https://api.nuget.org/v3-flatcontainer/microsoft.data.sqlclient/5.1.2/icon",
|
||||
"deprecation": {
|
||||
"reasons": [
|
||||
"CriticalBugs"
|
||||
],
|
||||
"message": "An important security issue exists in this version of the package. It is recommended to update to a newer version.\nhttps://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-0056"
|
||||
},
|
||||
"language": "",
|
||||
"licenseUrl": "https://www.nuget.org/packages/Microsoft.Data.SqlClient/5.1.2/license",
|
||||
"listed": true,
|
||||
"packageContent": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/Download/microsoft.data.sqlclient/5.1.2",
|
||||
"projectUrl": "https://aka.ms/sqlclientproject",
|
||||
"requireLicenseAcceptance": true,
|
||||
"summary": "",
|
||||
"tags": [
|
||||
"sqlclient",
|
||||
"microsoft.data.sqlclient"
|
||||
],
|
||||
"title": "Microsoft.Data.SqlClient",
|
||||
"version": "5.1.2-pre-release-test",
|
||||
"dependencyGroups": [
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[4.5.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.buffers/index.json",
|
||||
"id": "System.Buffers"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.interopservices.runtimeinformation/index.json",
|
||||
"id": "System.Runtime.InteropServices.RuntimeInformation"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETFramework4.6.2"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.diagnostics.diagnosticsource/index.json",
|
||||
"id": "System.Diagnostics.DiagnosticSource"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": "net6.0"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.win32.registry/index.json",
|
||||
"id": "Microsoft.Win32.Registry"
|
||||
},
|
||||
{
|
||||
"range": "[4.5.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.buffers/index.json",
|
||||
"id": "System.Buffers"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.loader/index.json",
|
||||
"id": "System.Runtime.Loader"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETStandard2.0"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.win32.registry/index.json",
|
||||
"id": "Microsoft.Win32.Registry"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.loader/index.json",
|
||||
"id": "System.Runtime.Loader"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETStandard2.1"
|
||||
}
|
||||
],
|
||||
"id": "Microsoft.Data.SqlClient"
|
||||
},
|
||||
"packageContent": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/Download/microsoft.data.sqlclient/5.1.2",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient/index.json",
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient/5.1.2.json"
|
||||
},
|
||||
{
|
||||
"catalogEntry": {
|
||||
"authors": "Microsoft",
|
||||
"description": "Provides the data provider for SQL Server. These classes provide access to versions of SQL Server and encapsulate database-specific protocols, including tabular data stream (TDS)\n \nCommonly Used Types:\nMicrosoft.Data.SqlClient.SqlConnection\nMicrosoft.Data.SqlClient.SqlException\nMicrosoft.Data.SqlClient.SqlParameter\nMicrosoft.Data.SqlClient.SqlDataReader\nMicrosoft.Data.SqlClient.SqlCommand\nMicrosoft.Data.SqlClient.SqlTransaction\nMicrosoft.Data.SqlClient.SqlParameterCollection\nMicrosoft.Data.SqlClient.SqlClientFactory\n\nWhen using NuGet 3.x this package requires at least version 3.4.",
|
||||
"iconUrl": "https://api.nuget.org/v3-flatcontainer/microsoft.data.sqlclient/5.1.3/icon",
|
||||
"language": "",
|
||||
"licenseUrl": "https://www.nuget.org/packages/Microsoft.Data.SqlClient/5.1.3/license",
|
||||
"listed": true,
|
||||
"packageContent": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/Download/microsoft.data.sqlclient/5.1.3",
|
||||
"projectUrl": "https://aka.ms/sqlclientproject",
|
||||
"requireLicenseAcceptance": true,
|
||||
"summary": "",
|
||||
"tags": [
|
||||
"sqlclient",
|
||||
"microsoft.data.sqlclient"
|
||||
],
|
||||
"title": "Microsoft.Data.SqlClient",
|
||||
"version": "5.1.3-pre-release-test",
|
||||
"dependencyGroups": [
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[4.5.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.buffers/index.json",
|
||||
"id": "System.Buffers"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.interopservices.runtimeinformation/index.json",
|
||||
"id": "System.Runtime.InteropServices.RuntimeInformation"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETFramework4.6.2"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.diagnostics.diagnosticsource/index.json",
|
||||
"id": "System.Diagnostics.DiagnosticSource"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": "net6.0"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.win32.registry/index.json",
|
||||
"id": "Microsoft.Win32.Registry"
|
||||
},
|
||||
{
|
||||
"range": "[4.5.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.buffers/index.json",
|
||||
"id": "System.Buffers"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.loader/index.json",
|
||||
"id": "System.Runtime.Loader"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETStandard2.0"
|
||||
},
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"range": "[5.1.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient.sni.runtime/index.json",
|
||||
"id": "Microsoft.Data.SqlClient.SNI.runtime"
|
||||
},
|
||||
{
|
||||
"range": "[1.7.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/azure.identity/index.json",
|
||||
"id": "Azure.Identity"
|
||||
},
|
||||
{
|
||||
"range": "[4.47.2, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identity.client/index.json",
|
||||
"id": "Microsoft.Identity.Client"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.protocols.openidconnect/index.json",
|
||||
"id": "Microsoft.IdentityModel.Protocols.OpenIdConnect"
|
||||
},
|
||||
{
|
||||
"range": "[6.24.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.identitymodel.jsonwebtokens/index.json",
|
||||
"id": "Microsoft.IdentityModel.JsonWebTokens"
|
||||
},
|
||||
{
|
||||
"range": "[1.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.sqlserver.server/index.json",
|
||||
"id": "Microsoft.SqlServer.Server"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.win32.registry/index.json",
|
||||
"id": "Microsoft.Win32.Registry"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.1, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.configuration.configurationmanager/index.json",
|
||||
"id": "System.Configuration.ConfigurationManager"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.caching/index.json",
|
||||
"id": "System.Runtime.Caching"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encoding.codepages/index.json",
|
||||
"id": "System.Text.Encoding.CodePages"
|
||||
},
|
||||
{
|
||||
"range": "[6.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.text.encodings.web/index.json",
|
||||
"id": "System.Text.Encodings.Web"
|
||||
},
|
||||
{
|
||||
"range": "[4.3.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.runtime.loader/index.json",
|
||||
"id": "System.Runtime.Loader"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.cryptography.cng/index.json",
|
||||
"id": "System.Security.Cryptography.Cng"
|
||||
},
|
||||
{
|
||||
"range": "[5.0.0, )",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/system.security.principal.windows/index.json",
|
||||
"id": "System.Security.Principal.Windows"
|
||||
}
|
||||
],
|
||||
"targetFramework": ".NETStandard2.1"
|
||||
}
|
||||
],
|
||||
"id": "Microsoft.Data.SqlClient"
|
||||
},
|
||||
"packageContent": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/Download/microsoft.data.sqlclient/5.1.3",
|
||||
"registration": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient/index.json",
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/registration-semver2/microsoft.data.sqlclient/5.1.3.json"
|
||||
}
|
||||
],
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/microsoft.data.sqlclient/page/5.1.1/6.1.0.json"
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"version": "3.0.0",
|
||||
"resources": [
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/query",
|
||||
"@type": "SearchQueryService",
|
||||
"comment": "Query endpoint of NuGet Search service (primary)"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/",
|
||||
"@type": "RegistrationsBaseUrl",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/nuget-repo",
|
||||
"@type": "LegacyGallery"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/nuget-repo",
|
||||
"@type": "LegacyGallery/2.0.0"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/nuget-repo",
|
||||
"@type": "PackagePublish/2.0.0"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/symbols",
|
||||
"@type": "SymbolPackagePublish/4.9.0"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/query",
|
||||
"@type": "SearchQueryService/3.0.0-rc",
|
||||
"comment": "Query endpoint of NuGet Search service (primary) used by RC clients"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/",
|
||||
"@type": "RegistrationsBaseUrl/3.0.0-rc",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by RC clients. This base URL does not include SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/{id-lower}/index.json",
|
||||
"@type": "PackageDisplayMetadataUriTemplate/3.0.0-rc",
|
||||
"comment": "URI template used by NuGet Client to construct display metadata for Packages using ID"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/{id-lower}/{version-lower}.json",
|
||||
"@type": "PackageVersionDisplayMetadataUriTemplate/3.0.0-rc",
|
||||
"comment": "URI template used by NuGet Client to construct display metadata for Packages using ID, Version"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/query",
|
||||
"@type": "SearchQueryService/3.0.0-beta",
|
||||
"comment": "Query endpoint of NuGet Search service (primary) used by beta clients"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/",
|
||||
"@type": "RegistrationsBaseUrl/3.0.0-beta",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by Beta clients. This base URL does not include SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration/",
|
||||
"@type": "RegistrationsBaseUrl/3.4.0",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL does not include SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/",
|
||||
"@type": "RegistrationsBaseUrl/3.6.0",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/artifactory/api/nuget/v3/nuget-repo/registration-semver2/",
|
||||
"@type": "RegistrationsBaseUrl/Versioned",
|
||||
"clientVersion": "4.3.0-alpha",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><Error><Code>BlobNotFound</Code><Message>The specified blob does not exist.
|
||||
RequestId:21575f5c-3b02-45a4-81a6-5e09fd2099db
|
||||
Time:2025-08-12T23:22:21.2000000Z</Message></Error>
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,207 @@
|
|||
{
|
||||
"version": "3.0.0",
|
||||
"resources": [
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/query",
|
||||
"@type": "SearchQueryService",
|
||||
"comment": "Query endpoint of NuGet Search service (primary)"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/query",
|
||||
"@type": "SearchQueryService",
|
||||
"comment": "Query endpoint of NuGet Search service (secondary)"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (primary)"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (secondary)"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/",
|
||||
"@type": "SearchGalleryQueryService/3.0.0-rc",
|
||||
"comment": "Azure Website based Search Service used by Gallery (primary)"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/",
|
||||
"@type": "SearchGalleryQueryService/3.0.0-rc",
|
||||
"comment": "Azure Website based Search Service used by Gallery (secondary)"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-semver1/",
|
||||
"@type": "RegistrationsBaseUrl",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3-flatcontainer/",
|
||||
"@type": "PackageBaseAddress/3.0.0",
|
||||
"comment": "Base URL of where NuGet packages are stored, in the format http://localhost:1080/v3-flatcontainer/{id-lower}/{version-lower}/{id-lower}.{version-lower}.nupkg"
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/api/v2",
|
||||
"@type": "LegacyGallery"
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/api/v2",
|
||||
"@type": "LegacyGallery/2.0.0"
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/api/v2/package",
|
||||
"@type": "PackagePublish/2.0.0"
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/api/v2/symbolpackage",
|
||||
"@type": "SymbolPackagePublish/4.9.0",
|
||||
"comment": "The gallery symbol publish endpoint."
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/query",
|
||||
"@type": "SearchQueryService/3.0.0-rc",
|
||||
"comment": "Query endpoint of NuGet Search service (primary) used by RC clients"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/query",
|
||||
"@type": "SearchQueryService/3.0.0-rc",
|
||||
"comment": "Query endpoint of NuGet Search service (secondary) used by RC clients"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/query",
|
||||
"@type": "SearchQueryService/3.5.0",
|
||||
"comment": "Query endpoint of NuGet Search service (primary) that supports package type filtering"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/query",
|
||||
"@type": "SearchQueryService/3.5.0",
|
||||
"comment": "Query endpoint of NuGet Search service (secondary) that supports package type filtering"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService/3.0.0-rc",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (primary) used by RC clients"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService/3.0.0-rc",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (secondary) used by RC clients"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService/3.5.0",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (primary) that supports package type filtering"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService/3.5.0",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (secondary) that supports package type filtering"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-semver1/",
|
||||
"@type": "RegistrationsBaseUrl/3.0.0-rc",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by RC clients. This base URL does not include SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/packages/{id}/{version}/ReportAbuse",
|
||||
"@type": "ReportAbuseUriTemplate/3.0.0-rc",
|
||||
"comment": "URI template used by NuGet Client to construct Report Abuse URL for packages used by RC clients"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-semver1/{id-lower}/index.json",
|
||||
"@type": "PackageDisplayMetadataUriTemplate/3.0.0-rc",
|
||||
"comment": "URI template used by NuGet Client to construct display metadata for Packages using ID"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-semver1/{id-lower}/{version-lower}.json",
|
||||
"@type": "PackageVersionDisplayMetadataUriTemplate/3.0.0-rc",
|
||||
"comment": "URI template used by NuGet Client to construct display metadata for Packages using ID, Version"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/query",
|
||||
"@type": "SearchQueryService/3.0.0-beta",
|
||||
"comment": "Query endpoint of NuGet Search service (primary) used by beta clients"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/query",
|
||||
"@type": "SearchQueryService/3.0.0-beta",
|
||||
"comment": "Query endpoint of NuGet Search service (secondary) used by beta clients"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-usnc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService/3.0.0-beta",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (primary) used by beta clients"
|
||||
},
|
||||
{
|
||||
"@id": "https://azuresearch-ussc.nuget.org/autocomplete",
|
||||
"@type": "SearchAutocompleteService/3.0.0-beta",
|
||||
"comment": "Autocomplete endpoint of NuGet Search service (secondary) used by beta clients"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-semver1/",
|
||||
"@type": "RegistrationsBaseUrl/3.0.0-beta",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by Beta clients. This base URL does not include SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/packages/{id}/{version}/ReportAbuse",
|
||||
"@type": "ReportAbuseUriTemplate/3.0.0-beta",
|
||||
"comment": "URI template used by NuGet Client to construct Report Abuse URL for packages"
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/packages/{id}/{version}?_src=template",
|
||||
"@type": "PackageDetailsUriTemplate/5.1.0",
|
||||
"comment": "URI template used by NuGet Client to construct details URL for packages"
|
||||
},
|
||||
{
|
||||
"@id": "https://www.nuget.org/profiles/{owner}?_src=template",
|
||||
"@type": "OwnerDetailsUriTemplate/6.11.0",
|
||||
"comment": "URI template used by NuGet Client to construct owner URL for packages"
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-gz-semver1/",
|
||||
"@type": "RegistrationsBaseUrl/3.4.0",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL does not include SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-gz-semver2/",
|
||||
"@type": "RegistrationsBaseUrl/3.6.0",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/registration5-gz-semver2/",
|
||||
"@type": "RegistrationsBaseUrl/Versioned",
|
||||
"clientVersion": "4.3.0-alpha",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3-index/repository-signatures/4.7.0/index.json",
|
||||
"@type": "RepositorySignatures/4.7.0",
|
||||
"comment": "The endpoint for discovering information about this package source's repository signatures."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3-index/repository-signatures/5.0.0/index.json",
|
||||
"@type": "RepositorySignatures/5.0.0",
|
||||
"comment": "The endpoint for discovering information about this package source's repository signatures."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/vulnerabilities/index.json",
|
||||
"@type": "VulnerabilityInfo/6.7.0",
|
||||
"comment": "The endpoint for discovering information about vulnerabilities of packages in this package source."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3/catalog0/index.json",
|
||||
"@type": "Catalog/3.0.0",
|
||||
"comment": "Index of the NuGet package catalog."
|
||||
},
|
||||
{
|
||||
"@id": "http://localhost:1080/v3-flatcontainer/{lower_id}/{lower_version}/readme",
|
||||
"@type": "ReadmeUriTemplate/6.13.0",
|
||||
"comment": "URI template used by NuGet Client to construct a URL for downloading a package's README."
|
||||
}
|
||||
],
|
||||
"@context": {
|
||||
"@vocab": "http://schema.nuget.org/services#",
|
||||
"comment": "http://www.w3.org/2000/01/rdf-schema#comment"
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue