plugin ui
All checks were successful
Build / Compute Version (push) Successful in 17s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 3m5s
Build / Build Nuget package (NuGet) (push) Successful in 2m34s
Build / Build Nuget package (CringePlugins) (push) Successful in 2m56s
Build / Build Nuget package (SharedCringe) (push) Successful in 1m52s
Build / Build Launcher (push) Successful in 3m52s

This commit is contained in:
zznty
2024-11-03 01:58:04 +07:00
parent 271e8a1dde
commit aac79af331
22 changed files with 573 additions and 40 deletions

View File

@@ -0,0 +1,54 @@
using System.Collections.Immutable;
using System.Text.Json;
using System.Text.Json.Serialization;
using NuGet.Models;
namespace NuGet.Converters;
public class PackageAuthorsJsonConverter : JsonConverter<PackageAuthors>
{
public override PackageAuthors? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
{
var author = reader.GetString()!;
return new PackageAuthors(author, [author]);
}
case JsonTokenType.StartArray:
{
var builder = ImmutableArray.CreateBuilder<string>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
builder.Add(reader.GetString()!);
}
return new PackageAuthors(string.Join(", ", builder), builder.ToImmutable());
}
case JsonTokenType.Null:
return null;
default:
throw new JsonException("String or array of strings expected");
}
}
public override void Write(Utf8JsonWriter writer, PackageAuthors value, JsonSerializerOptions options)
{
if (value.Authors.Length == 1)
{
writer.WriteStringValue(value.Author);
return;
}
writer.WriteStartArray();
foreach (var author in value.Authors)
{
writer.WriteStringValue(author);
}
writer.WriteEndArray();
}
}

View File

@@ -0,0 +1,48 @@
using System.Collections.Immutable;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace NuGet.Converters;
public class StringOrStringArrayConverter : JsonConverter<ImmutableArray<string>>
{
public override ImmutableArray<string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
return [reader.GetString()!];
case JsonTokenType.StartArray:
{
var builder = ImmutableArray.CreateBuilder<string>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
builder.Add(reader.GetString()!);
}
return builder.ToImmutable();
}
default:
throw new JsonException("String or array of strings expected");
}
}
public override void Write(Utf8JsonWriter writer, ImmutableArray<string> value, JsonSerializerOptions options)
{
if (value.Length == 1)
{
writer.WriteStringValue(value[0]);
return;
}
writer.WriteStartArray();
foreach (var author in value)
{
writer.WriteStringValue(author);
}
writer.WriteEndArray();
}
}

View File

@@ -88,10 +88,10 @@ public class DependencyManifestBuilder(DirectoryInfo cacheDirectory, PackageSour
private async Task MapCatalogEntryAsync(CatalogEntry catalogEntry, NuGetFramework targetFramework,
ImmutableDictionary<ManifestPackageKey, DependencyTarget>.Builder targets)
{
if (targets.ContainsKey(new(catalogEntry.Id, catalogEntry.Version)))
if (targets.ContainsKey(new(catalogEntry.Id, catalogEntry.Version)) || !catalogEntry.DependencyGroups.HasValue)
return;
var nearest = NuGetFrameworkUtility.GetNearest(catalogEntry.DependencyGroups, targetFramework,
var nearest = NuGetFrameworkUtility.GetNearest(catalogEntry.DependencyGroups.Value, targetFramework,
group => group.TargetFramework);
if (nearest is null)
@@ -103,9 +103,18 @@ public class DependencyManifestBuilder(DirectoryInfo cacheDirectory, PackageSour
foreach (var dependency in nearest.Dependencies ?? [])
{
var client = await packageSources.GetClientAsync(dependency.Id);
var (url, entry) = await client.GetPackageRegistrationAsync(dependency.Id, versionResolver(dependency)!);
var registrationRoot = await client.GetPackageRegistrationRootAsync(dependency.Id);
entry ??= await client.GetPackageCatalogEntryAsync(url);
var version = versionResolver(dependency)!;
var entry = registrationRoot.Items.SelectMany(b => b.Items ?? []).FirstOrDefault(b => b.CatalogEntry.Version == version)?.CatalogEntry;
if (entry is null)
{
var (url, sleetEntry) = await client.GetPackageRegistrationAsync(dependency.Id, versionResolver(dependency)!);
entry = sleetEntry;
entry ??= await client.GetPackageCatalogEntryAsync(url);
}
await MapCatalogEntryAsync(entry, targetFramework, targets);
}

View File

@@ -3,7 +3,7 @@ using NuGet.Versioning;
namespace NuGet.Models;
public record CatalogEntry(string Id, NuGetVersion Version, ImmutableArray<DependencyGroup> DependencyGroups, ImmutableArray<string>? PackageTypes,
public record CatalogEntry(string Id, NuGetVersion Version, ImmutableArray<DependencyGroup>? DependencyGroups, ImmutableArray<string>? PackageTypes,
ImmutableArray<CatalogPackageEntry>? PackageEntries);
public record CatalogPackageEntry(string Name, string FullName, long CompressedLength, long Length);

View File

@@ -0,0 +1,8 @@
using System.Collections.Immutable;
using System.Text.Json.Serialization;
using NuGet.Converters;
namespace NuGet.Models;
[JsonConverter(typeof(PackageAuthorsJsonConverter))]
public record PackageAuthors(string Author, ImmutableArray<string> Authors);

View File

@@ -0,0 +1,3 @@
namespace NuGet.Models;
public record PackageType(string Name);

View File

@@ -2,4 +2,4 @@
namespace NuGet.Models;
public record RegistrationPage(int Count, NuGetVersion Lower, NuGetVersion Upper, RegistrationEntry[] Items);
public record RegistrationPage(int Count, NuGetVersion Lower, NuGetVersion Upper, RegistrationEntry[]? Items);

View File

@@ -0,0 +1,33 @@
using System.Collections.Immutable;
using System.Text.Json.Serialization;
using NuGet.Converters;
using NuGet.Versioning;
namespace NuGet.Models;
public record SearchResult(int TotalHits, [property: JsonPropertyName("data")] ImmutableArray<SearchResultEntry> Entries);
public record SearchResultEntry(
string Id,
NuGetVersion Version,
string? Description,
ImmutableArray<SearchResultPackageVersion> Versions,
PackageAuthors? Authors,
string? IconUrl,
string? LicenseUrl,
[property: JsonConverter(typeof(StringOrStringArrayConverter))]
ImmutableArray<string>? Owners,
string? ProjectUrl,
Uri Registration,
string? Summary,
[property: JsonConverter(typeof(StringOrStringArrayConverter))]
ImmutableArray<string>? Tags,
string? Title,
int? TotalDownloads,
ImmutableArray<PackageType> PackageTypes,
bool Verified = false);
public record SearchResultPackageVersion(
NuGetVersion Version,
int Downloads,
[property: JsonPropertyName("@id")] Uri Registration);

View File

@@ -1,6 +1,7 @@
using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;
using NuGet.Converters;
using NuGet.Models;
using NuGet.Versioning;
@@ -9,9 +10,11 @@ namespace NuGet;
public class NuGetClient
{
private readonly Uri _index;
private readonly HttpClient _client;
private readonly Uri _packageBaseAddress;
private readonly Uri _registration;
private readonly Uri _search;
public static JsonSerializerOptions SerializerOptions { get; } = new(JsonSerializerDefaults.Web)
{
@@ -24,11 +27,13 @@ public class NuGetClient
WriteIndented = true
};
private NuGetClient(HttpClient client, Uri packageBaseAddress, Uri registration)
private NuGetClient(Uri index, HttpClient client, Uri packageBaseAddress, Uri registration, Uri search)
{
_index = index;
_client = client;
_packageBaseAddress = packageBaseAddress;
_registration = registration;
_search = search;
}
public Task<Stream> GetPackageContentStreamAsync(string id, NuGetVersion version)
@@ -61,6 +66,37 @@ public class NuGetClient
return _client.GetFromJsonAsync<CatalogEntry>(url, SerializerOptions)!;
}
public Task<SearchResult> SearchPackagesAsync(string? query = null, int? skip = null, int? take = null,
bool? includePrerelease = null, NuGetVersion? minVersion = null, string? packageType = null)
{
var queryParameters = HttpUtility.ParseQueryString(string.Empty);
if (!string.IsNullOrEmpty(query))
queryParameters.Add("q", query);
if (skip.HasValue)
queryParameters.Add("skip", skip.Value.ToString());
if (take.HasValue)
queryParameters.Add("take", take.Value.ToString());
if (includePrerelease.HasValue)
queryParameters.Add("prerelease", includePrerelease.Value.ToString());
if (minVersion is not null)
queryParameters.Add("semVerLevel", minVersion.ToString());
if (!string.IsNullOrEmpty(packageType))
queryParameters.Add("packageType", packageType);
var builder = new UriBuilder(_search)
{
Query = queryParameters.ToString()
};
return _client.GetFromJsonAsync<SearchResult>(builder.Uri, SerializerOptions)!;
}
public static async Task<NuGetClient> CreateFromIndexUrlAsync(string indexUrl)
{
var client = new HttpClient(new HttpClientHandler
@@ -71,13 +107,20 @@ public class NuGetClient
var index = await client.GetFromJsonAsync<NuGetIndex>(indexUrl, SerializerOptions);
var (packageBaseAddress, _, _) = index!.Resources.First(b => b.Type.Id == "PackageBaseAddress");
var (registration, _, _) = index!.Resources.First(b => b.Type.Id == "RegistrationsBaseUrl");
var (registration, _, _) = index.Resources.First(b => b.Type.Id == "RegistrationsBaseUrl");
var (search, _, _) = index.Resources.First(b => b.Type.Id == "SearchQueryService");
if (!packageBaseAddress.EndsWith('/'))
packageBaseAddress += '/';
if (!registration.EndsWith('/'))
registration += '/';
return new NuGetClient(client, new Uri(packageBaseAddress), new Uri(registration));
return new NuGetClient(new Uri(indexUrl), client, new Uri(packageBaseAddress), new Uri(registration), new Uri(search));
}
public override string ToString() => _index.ToString();
public override bool Equals(object? obj) => obj is NuGetClient { _index: { } index } && index == _index;
public override int GetHashCode() => _index.GetHashCode();
}

View File

@@ -1,4 +1,7 @@
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace NuGet;
@@ -11,7 +14,15 @@ public class PackageSourceMapping(ImmutableArray<PackageSource> sources)
];
public Task<NuGetClient> GetClientAsync(string packageId) =>
_clients.FirstOrDefault(b => packageId.StartsWith(b.pattern)).client;
_clients.FirstOrDefault(b => Regex.IsMatch(packageId, b.pattern)).client;
public ConfiguredCancelableAsyncEnumerable<NuGetClient>.Enumerator GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return _clients.ToAsyncEnumerable()
.SelectAwait(b => new ValueTask<NuGetClient>(b.client))
.WithCancellation(cancellationToken)
.GetAsyncEnumerator();
}
}
public record PackageSource(string Pattern, string Url);
public record PackageSource([StringSyntax("Regex")] string Pattern, [StringSyntax("Uri")] string Url);