Package Version constraints

main
Paul Schneider 1 year ago
parent fa6272ac28
commit cea05fe8ff
14 changed files with 593 additions and 186 deletions

@ -1,3 +1,4 @@
using Microsoft.VisualBasic.CompilerServices;
using System.Linq.Expressions;
using System;
@ -21,6 +22,8 @@ using isnd.Data.Packages;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using isn;
using isnd.Helpers;
using Microsoft.EntityFrameworkCore;
namespace isnd.Controllers
{
@ -52,7 +55,7 @@ namespace isnd.Controllers
TimeStamp = DateTimeOffset.Now.ToUniversalTime()
};
dbContext.Commits.Add(commit);
foreach (IFormFile file in Request.Form.Files)
{
@ -108,7 +111,7 @@ namespace isnd.Controllers
Id = pkgid,
Description = pkgdesc,
OwnerId = apikey.UserId,
LatestVersion = commit
LatestCommit = commit
};
dbContext.Packages.Add(pkg);
}
@ -119,22 +122,26 @@ namespace isnd.Controllers
var destdir = new DirectoryInfo(dest.DirectoryName);
if (dest.Exists)
{
logger.LogWarning($"Existant package in disk : {dest.FullName}");
// La version existe sur le disque,
// mais si elle ne l'est pas en base de donnéés,
// on remplace la version sur disque.
string exFullString = version.ToFullString();
var pkgv = dbContext.PackageVersions.Where(
var pkgv = dbContext.PackageVersions.
Include(v=>v.LatestCommit)
.Single(
v => v.PackageId == pkg.Id && v.FullString == exFullString
);
if (pkgv !=null && !pkgv.Any())
if (pkgv!=null && pkgv.IsDeleted)
{
dest.Delete();
}
else {
string msg = $"existant {pkg.Id}-{exFullString}";
else if (pkgv != null)
{
string msg = $"existant : {pkg.Id}-{exFullString}";
logger.LogWarning("400 : {msg}", msg);
ModelState.AddModelError("pkgversion", msg);
return BadRequest(CreateAPIKO("existant", ModelState));
return BadRequest(this.CreateAPIKO("existant"));
}
}
{
@ -182,8 +189,9 @@ namespace isnd.Controllers
dbContext.PackageVersions.Add(pkgver);
}
dbContext.Commits.Add(commit);
await dbContext.SaveChangesAsync();
packageManager.ÛpdateCatalogForAsync(commit);
await packageManager.ÛpdateCatalogForAsync(commit);
logger.LogInformation($"new paquet : {spec.Name}");
}
@ -204,7 +212,7 @@ namespace isnd.Controllers
}
}
string nuspecfullpath = Path.Combine(pkgpath, pkgid + "." + Constants.SpecFileEstension);
FileInfo nfpi = new FileInfo(nuspecfullpath);
FileInfo nfpi = new(nuspecfullpath);
if (nfpi.Exists)
nfpi.Delete();
@ -215,23 +223,12 @@ namespace isnd.Controllers
}
catch (Exception ex)
{
logger.LogError(ex.Message);
logger.LogError("Stack Trace: " + ex.StackTrace);
logger.LogError("PUT exception : " + ex.Message);
logger.LogError("Stack Trace : " + ex.StackTrace);
return new ObjectResult(new { ViewData, ex.Message })
{ StatusCode = 500 };
}
}
public APIKO CreateAPIKO(string context, ModelStateDictionary modelState)
{
Dictionary<string,string[]> errors = new();
foreach (var elt in modelState)
{
errors[elt.Key] = elt.Value.Errors.Select( e => e.ErrorMessage).ToArray();
}
return new APIKO{ Context = context, Errors = errors };
}
}
}

@ -9,19 +9,21 @@ using isnd.Interfaces;
namespace isnd.Data.Catalog
{
public class CatalogEntry : Permalink, IObject// , IPackageDetails
public class PackageDetails : Permalink, IObject
{
/// <summary>
/// Creates a catalog entry
/// </summary>
/// <param name="id">package details url</param>
/// <returns></returns>
public CatalogEntry(string id): base(id)
{
public PackageDetails(PackageVersion pkg, string apiBase, string uri): base(uri)
{
PackageId = pkg.Package.Id;
Version = pkg.FullString;
authors = $"{pkg.Package.Owner.FullName} <${pkg.Package.Owner.Email}>";
packageContent = apiBase + pkg.NugetLink;
}
[JsonProperty("@type")]
public string[] RefType { get; protected set; } = new string[] { "PackageDetails" };
@ -99,5 +101,8 @@ namespace isnd.Data.Catalog
[JsonProperty("version")]
public string Version { get; set; }
[Required,JsonRequired]
[JsonProperty("id")]
public string PackageId { get; set; }
}
}

@ -14,18 +14,17 @@ namespace isnd.Data.Catalog
Items = new List<CatalogPage>();
}
public PackageRegistration(string bid, string id, string apiBase, Packages.Package pkg) : base(bid + $"/{id}/index.json")
public PackageRegistration(string bid, string apiBase, Packages.Package pkg) : base(bid + $"/{pkg.Id}/index.json")
{
Items = new List<CatalogPage>
{
new CatalogPage(bid, id, apiBase, pkg.Versions)
new CatalogPage(bid, pkg.Id, apiBase, pkg.Versions)
};
if (pkg.Versions.Count>0)
{
CommitId = pkg.Versions.Max(v=>v.CommitNId).ToString();
CommitTimeStamp = pkg.Versions.Max(v=>v.LatestCommit.CommitTimeStamp);
}
CommitId = pkg.LatestCommit.CommitId;
CommitTimeStamp = pkg.LatestCommit.CommitTimeStamp;
}
[JsonProperty("count")]

@ -11,9 +11,11 @@ namespace isnd.Data.Catalog
/// </summary>
public class Package
{
public Package(string apiBase, string pkgId, string fullVersionString, CatalogEntry entry)
public Package(string apiBase, string pkgId, string fullVersionString, PackageDetails entry)
{
this.registration = apiBase + ApiConfig.Registration + "/" + pkgId + "/index.json";
this.registration = apiBase + ApiConfig.Registration + "/" + pkgId + "/" + fullVersionString + ".json";
Id = registration;
this.PackageContent = apiBase + ApiConfig.Nuget + "/" + pkgId + "/" + fullVersionString
+ "/" + pkgId + "-" + fullVersionString + "." + Constants.PaquetFileEstension;
Entry = entry;
@ -38,7 +40,7 @@ namespace isnd.Data.Catalog
/// </summary>
/// <value></value>
[JsonProperty("catalogEntry")]
public CatalogEntry Entry { get; set; }
public PackageDetails Entry { get; set; }
/// <summary>
/// The URL to the package content (.nupkg)

@ -20,7 +20,7 @@ namespace isnd.Data.Packages
List<PackageVersion> Versions { get; set; }
long CommitNId { get; set; }
string CommitId { get; }
Commit LatestVersion { get; set; }
Commit LatestCommit { get; set; }
DateTimeOffset CommitTimeStamp { get; set; }
}
@ -61,7 +61,7 @@ namespace isnd.Data.Packages
[ForeignKey("CommitNId")]
public virtual Commit LatestVersion { get; set; }
public virtual Commit LatestCommit { get; set; }
public DateTimeOffset CommitTimeStamp { get; set; }
}

@ -6,11 +6,13 @@ using isnd.Data.Catalog;
using isnd.Data.Packages;
using isnd.Data.Packages.Catalog;
using isnd.Entities;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NuGet.Versioning;
namespace isnd.Data
{
[PrimaryKey("PackageId", "FullString")]
public class PackageVersion
{
[Required]
@ -37,7 +39,6 @@ namespace isnd.Data
/// <value></value>
[StringLength(256)]
[Required]
[Key]
public string FullString { get; set; }
public bool IsPrerelease { get; set; }
@ -67,14 +68,8 @@ namespace isnd.Data
public Catalog.Package ToPackage(string apiBase)
{
return new Catalog.Package(apiBase ,this.PackageId , FullString,
new CatalogEntry(apiBase + ApiConfig.Registration + "/" + this.PackageId + "/" + FullString + ".json")
{
Version = FullString,
authors = $"{this.Package.Owner.FullName} <${Package.Owner.Email}>",
packageContent = apiBase + this.NugetLink
}
);
return new Catalog.Package(apiBase, this.PackageId , FullString,
new Catalog.PackageDetails(this, apiBase, apiBase + ApiConfig.Registration + "/" + this.PackageId + "/" + FullString + ".json"));
}
public bool IsDeleted => LatestCommit.Action == PackageAction.DeletePackage;
}

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using isn;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace isnd.Helpers
{
public static class ApiHelpers
{
static public APIKO CreateAPIKO(this Controller controller, string context)
{
Dictionary<string,string[]> errors = new();
foreach (var elt in controller.ModelState)
{
errors[elt.Key] = elt.Value.Errors.Select( e => e.ErrorMessage).ToArray();
}
return new APIKO{ Context = context, Errors = errors };
}
}
}

@ -0,0 +1,455 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using isnd.Data;
#nullable disable
namespace isnd.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20230430192411_pkgversions")]
partial class pkgversions
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("text");
b.Property<string>("ClaimValue")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("ProviderKey")
.HasColumnType("text");
b.Property<string>("ProviderDisplayName")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("text");
b.Property<string>("RoleId")
.HasColumnType("text");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("text");
b.Property<string>("LoginProvider")
.HasColumnType("text");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Value")
.HasColumnType("text");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("text");
b.Property<DateTimeOffset>("CreationDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("text");
b.Property<int>("ValidityPeriodInDays")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ApiKeys");
});
modelBuilder.Entity("isnd.Data.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("AccessFailedCount")
.HasColumnType("integer");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("text");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("LockoutEnabled")
.HasColumnType("boolean");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("timestamp with time zone");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.HasColumnType("text");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("boolean");
b.Property<string>("SecurityStamp")
.HasColumnType("text");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("boolean");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.Property<string>("PackageId")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<string>("FullString")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<long>("CommitNId")
.HasColumnType("bigint");
b.Property<bool>("IsPrerelease")
.HasColumnType("boolean");
b.Property<int>("Major")
.HasColumnType("integer");
b.Property<int>("Minor")
.HasColumnType("integer");
b.Property<int>("Patch")
.HasColumnType("integer");
b.Property<int>("Revision")
.HasColumnType("integer");
b.Property<string>("Type")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("PackageId", "FullString");
b.HasIndex("CommitNId");
b.ToTable("PackageVersions");
});
modelBuilder.Entity("isnd.Data.Packages.Commit", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<int>("Action")
.HasColumnType("integer");
b.Property<DateTimeOffset>("TimeStamp")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.ToTable("Commits");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.Property<string>("Id")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<long>("CommitNId")
.HasColumnType("bigint");
b.Property<DateTimeOffset>("CommitTimeStamp")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<string>("OwnerId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("Public")
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("CommitNId");
b.HasIndex("OwnerId");
b.ToTable("Packages");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isnd.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany("Versions")
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("isnd.Data.Packages.Package", "Package")
.WithMany("Versions")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LatestCommit");
b.Navigation("Package");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany()
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("isnd.Data.ApplicationUser", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LatestCommit");
b.Navigation("Owner");
});
modelBuilder.Entity("isnd.Data.Packages.Commit", b =>
{
b.Navigation("Versions");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.Navigation("Versions");
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,45 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace isnd.Migrations
{
/// <inheritdoc />
public partial class pkgversions : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions");
migrationBuilder.DropIndex(
name: "IX_PackageVersions_PackageId",
table: "PackageVersions");
migrationBuilder.AddPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions",
columns: new[] { "PackageId", "FullString" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions");
migrationBuilder.AddPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions",
column: "FullString");
migrationBuilder.CreateIndex(
name: "IX_PackageVersions_PackageId",
table: "PackageVersions",
column: "PackageId");
}
}
}

@ -160,7 +160,7 @@ namespace isnd.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("text");
b.Property<DateTime>("CreationDate")
b.Property<DateTimeOffset>("CreationDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
@ -249,6 +249,10 @@ namespace isnd.Migrations
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.Property<string>("PackageId")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<string>("FullString")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
@ -265,11 +269,6 @@ namespace isnd.Migrations
b.Property<int>("Minor")
.HasColumnType("integer");
b.Property<string>("PackageId")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<int>("Patch")
.HasColumnType("integer");
@ -280,12 +279,10 @@ namespace isnd.Migrations
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("FullString");
b.HasKey("PackageId", "FullString");
b.HasIndex("CommitNId");
b.HasIndex("PackageId");
b.ToTable("PackageVersions");
});
@ -423,7 +420,7 @@ namespace isnd.Migrations
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestVersion")
b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany()
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade)
@ -435,7 +432,7 @@ namespace isnd.Migrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("LatestVersion");
b.Navigation("LatestCommit");
b.Navigation("Owner");
});

@ -7,7 +7,7 @@ namespace isnd
{
internal class NSJWebApiReferenceResolver : IReferenceResolver
{
private int delautIdCounter;
private int delautIdCounter;
Dictionary<string, Permalink> HappyIdOwners { get; set; }

@ -150,7 +150,7 @@ namespace isnd.Services
var validPkgs = (await dbContext.Packages
.Include(po => po.Owner)
.Include(pkg => pkg.Versions)
.Include(pkg => pkg.LatestVersion)
.Include(pkg => pkg.LatestCommit)
.ToArrayAsync())
.GroupBy((q) => q.Id);
@ -274,13 +274,15 @@ namespace isnd.Services
// RegistrationPageIndexAndQuery
if (string.IsNullOrWhiteSpace(query.Query)) return null;
query.Query = query.Query.ToLower();
var scope = await dbContext.Packages.Include(p => p.Versions).Include(p => p.Owner)
.Include(p=>p.LatestVersion)
var scope = await dbContext.Packages
.Include(p => p.Versions)
.Include(p => p.Owner)
.Include(p=>p.LatestCommit)
.SingleAsync(p => p.Id.ToLower() == query.Query);
if (scope.Versions.Count==0) return null;
string bid = $"{apiBase}{ApiConfig.Registration}";
return
new PackageRegistration(bid, query.Query, apiBase, scope);
new PackageRegistration(bid, apiBase, scope);
}
public async Task<IEnumerable<PackageRegistration>> SearchPackageAsync(PackageRegistrationQuery query)
{
@ -288,17 +290,16 @@ namespace isnd.Services
if (query.Query == null) query.Query = "";
var scope = (await dbContext.Packages
.Include(p => p.Versions)
.Include(p => p.Owner)
.Include(p=>p.LatestVersion)
.Where(p => p.Id == query.Query
&& (p.Versions.Any() && query.Prerelease || p.Versions.Any(v => !v.IsPrerelease)))
.ToListAsync());
var total = scope.Count();
var pkgs = scope.Skip(query.Skip).Take(query.Take);
return pkgs.Select(p => new PackageRegistration(bid, query.Query, apiBase, p));
.Include(p => p.Versions)
.Include(p => p.LatestCommit)
.Where(p => p.Id.StartsWith(query.Query)
&& (query.Prerelease || p.Versions.Any(p => !p.IsPrerelease)))
.Skip(query.Skip).Take(query.Take)
.ToListAsync()
);
var pkgs = scope;
return pkgs.Select(p => new PackageRegistration(bid, apiBase, p));
}

@ -1,14 +0,0 @@
using System.Text.Json;
namespace isnd
{
internal class TypeIdNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name)
{
if (name == "Id") return "@id";
if (name == "Type") return "@type";
return "" + char.ToLower(name[0]) + name[1..];
}
}
}

@ -1,98 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using isnd.Data.Catalog;
namespace isnd
{
class WebApiReferenceHandler : ReferenceHandler
{
public WebApiReferenceHandler() => Reset();
private ReferenceResolver? _rootedResolver;
public override ReferenceResolver CreateResolver() => _rootedResolver!;
public void Reset() => _rootedResolver = new WebApiReferenceResolver();
}
public class WebApiReferenceResolver : ReferenceResolver
{
private int delautIdCounter;
Dictionary<string, Permalink> HappyIdOwners { get; set; }
Dictionary<int,object> Objects {get; set;}
public WebApiReferenceResolver()
{
delautIdCounter = 0;
HappyIdOwners = new Dictionary<string, Permalink>();
Objects = new Dictionary<int, object>();
}
public override void AddReference(string referenceId, object value)
{
if (value is Permalink)
{
string hoi = (value as Permalink).GetId();
if (HappyIdOwners.ContainsKey(hoi))
{
return;
}
HappyIdOwners[hoi] = value as Permalink;
}
else
{
if (Objects.ContainsValue(value))
{
return;
}
delautIdCounter++;
Objects[delautIdCounter] = value;
}
}
public override string GetReference(object value, out bool alreadyExists)
{
if (value is Permalink)
{
string oid = (value as Permalink).GetId();
if (oid == null)
throw new System.Exception("HappyIdOwner Id property is null");
if (HappyIdOwners.ContainsKey(oid))
{
alreadyExists=true;
return oid;
}
alreadyExists=false;
AddReference(oid, value);
return oid;
}
alreadyExists=false;
if (Objects.ContainsValue(value))
{
alreadyExists=true;
return Objects.First( ode => ode.Value ==value).Key.ToString();
}
alreadyExists=false;
delautIdCounter++;
Objects[delautIdCounter]=value;
return delautIdCounter.ToString();
}
public override object ResolveReference(string referenceId)
{
if (HappyIdOwners.ContainsKey(referenceId))
return HappyIdOwners[referenceId];
int refNId;
if (int.TryParse(referenceId, out refNId))
{
if (Objects.ContainsKey(refNId))
{
return Objects[refNId];
}
}
return null;
}
}
}
Loading…