Multi-feed UI components
The unified multi-feed platform extends AvantiPoint.Packages.UI.Razor so hosts can expose NuGet, npm, and OCI registries from a single public origin.
Today the Razor library provides a NuGet-focused operator and consumer experience:
| Component | Purpose |
|---|---|
FeedInfo | NuGet feed URL, dotnet nuget / NuGet.Config snippets |
PackageSearch | Full-text search, filters, pagination |
PackageDetail | Versions, README, dependencies, install commands |
Multi-feed hosts add parallel npm and OCI experiences on the same public origin, using IFeedRegistry / IPublicBaseUrlProvider for correct URLs behind reverse proxies.
Design principles
- Protocol isolation — npm and OCI UI must not depend on NuGet
Packageentities orINuGetSearchService. - Surface-aware URLs — components derive registry roots from
IFeedRegistry+IPublicBaseUrlProvider(not hard-coded/v3or/npm). - Reuse patterns, not domain models — mirror NuGet component structure (connection card → browse → detail) with protocol-specific services.
- Optional surfaces — navigation and pages hide when
UseNpm()/UseOci*is not registered. - Blazor/Razor first — Primary UI components ship in the Razor library; a React surface is optional and maintained separately.
npm UI (FeedProtocol.Npm)
Registry root: {origin}/npm/ (from surface RoutePrefix via IPublicBaseUrlProvider).
Components
| Component | NuGet analogue | Responsibility |
|---|---|---|
NpmFeedInfo | FeedInfo | Registry URL, .npmrc, npm config set registry, auth hints |
NpmPackageSearch | PackageSearch | DB-backed browse/search |
NpmPackageDetail | PackageDetail | Versions, dist-tags, install commands |
Services
INpmPackageBrowseService— list/search packages for UI (usesNpmPackage/NpmVersionentities).
Register in startup:
builder.Services.AddNpmPackageBrowseUi();
OCI UI (FeedProtocol.Oci)
Registry roots: {origin}/v2/ (default) or {origin}/{segment}/v2/ (named).
Components
| Component | NuGet analogue | Responsibility |
|---|---|---|
OciFeedInfo | FeedInfo | docker login, helm registry login, ORAS hints |
OciRepositoryCatalog | PackageSearch | Repository catalog from Distribution API |
OciRepositoryDetail | — | Tag list for a repository |
OciArtifactDetail | PackageDetail | Manifest metadata and pull commands |
Services
IOciRepositoryBrowseService— wraps Distribution API (catalog, tags, manifest summary).
Register in startup:
builder.Services.AddOciRepositoryBrowseUi();
Multi-surface shell
MultiFeedNavigation reads IFeedRegistry at render time and shows tabs only for registered surfaces:
- NuGet —
/,/feed,/packages/{id} - npm —
/npm,/npm/feed,/npm/packages/{name} - OCI —
/oci,/oci/{segment},/oci/repos/{name}
Sample hosts: OpenFeed (reference), Packages.Host (production host).
Component coverage
Multi-feed UI spans three areas, each mirroring the NuGet component pattern (connection card → browse → detail):
| Area | Components | Registration |
|---|---|---|
| npm UI | NpmFeedInfo, NpmPackageSearch, NpmPackageDetail | AddNpmPackageBrowseUi() |
| OCI UI | OciFeedInfo, OciRepositoryCatalog, OciRepositoryDetail, OciArtifactDetail | AddOciRepositoryBrowseUi() |
| Host shell | MultiFeedNavigation | Register surfaces via IFeedRegistry; see sample hosts below |