Ustin.Sales.Common.ImADes
0.1.0
dotnet add package Ustin.Sales.Common.ImADes --version 0.1.0
NuGet\Install-Package Ustin.Sales.Common.ImADes -Version 0.1.0
<PackageReference Include="Ustin.Sales.Common.ImADes" Version="0.1.0" />
<PackageVersion Include="Ustin.Sales.Common.ImADes" Version="0.1.0" />
<PackageReference Include="Ustin.Sales.Common.ImADes" />
paket add Ustin.Sales.Common.ImADes --version 0.1.0
#r "nuget: Ustin.Sales.Common.ImADes, 0.1.0"
#:package Ustin.Sales.Common.ImADes@0.1.0
#addin nuget:?package=Ustin.Sales.Common.ImADes&version=0.1.0
#tool nuget:?package=Ustin.Sales.Common.ImADes&version=0.1.0
Ustin.Sales.Common.ImADes
ImADe (Image + Advertisement) — a data contract for an image annotated with metadata about the product(s) it advertises: which items are on it, where they are (as normalized hotspot regions), and where they link to.
This package is the data model, JSON (de)serialization, a fluent builder, and structural
validation. It does not fetch, store, or render anything — pair it with the
@ustin/imade-react component (or your own
renderer) to draw the hotspots on a page.
Install
dotnet add package Ustin.Sales.Common.ImADes
Build an ImADe
using Ustin.Sales.Common.ImADes;
using Ustin.Sales.Common.ImADes.Building;
using Ustin.Sales.Common.ImADes.V1;
var imade = new ImADeBuilder(imageId: "img-1", width: 1200, height: 800)
.WithImageUrl("https://cdn.example.com/img-1.jpg")
.WithTags("fashion", "outdoor")
.AddItem(new AdItem
{
Id = Guid.NewGuid().ToString(),
Sku = "SKU-IPHONE-15",
Name = "iPhone 15",
Description = "The phone she's holding.",
Tags = ["iphone", "electronics"],
Links = [new AdLink { Url = "https://shop.example.com/iphone-15", Label = "Buy in our store" }],
Region = new RectRegion(X: 0.42, Y: 0.31, W: 0.08, H: 0.14)
})
.AddItem(new AdItem
{
Id = Guid.NewGuid().ToString(),
Sku = "SKU-EARRINGS-GOLD",
Links = [new AdLink { Url = "https://amazon.com/dp/xyz", Kind = LinkKind.External, Store = "Amazon" }],
Region = new CircleRegion(CenterX: 0.62, CenterY: 0.28, Radius: 0.015),
HoverPadding = 0.01 // small item — widen the hit area without widening the drawn outline
})
.Build();
Validate
using Ustin.Sales.Common.ImADes.Validation;
var errors = ImADeValidator.Validate(imade);
if (errors.Count > 0)
{
throw new InvalidOperationException(string.Join("; ", errors));
}
Serialize / deserialize
string json = ImADeSerializer.Serialize(imade);
// Throws UnsupportedSchemaVersionException if schemaVersion isn't one this library knows.
ImADe roundTripped = ImADeSerializer.Deserialize(json);
The JSON uses camelCase field names and matches
contract/v1/imade.schema.json
in the repo — the same contract the React client consumes.
Coordinates
Regions (RectRegion, CircleRegion, PolygonRegion) are normalized to [0, 1] against the
image's Width/Height, not raw pixels — so the same ImADe renders correctly at any display
size, including desktop → mobile viewport changes. See the repo's PLAN.MD for the full rationale.
Limitation: this only holds if the image keeps its natural aspect ratio wherever it's
displayed (the default width:100%; height:auto). If a host page instead crops the image
differently per breakpoint — e.g. object-fit: cover into a wide box on desktop and a square box
on mobile — a single normalized coordinate set can't represent both crops, since the visible
region isn't a uniform scale of the original. There's no per-breakpoint metadata or
crop-awareness in this library or @ustin/imade-react today; display the image at its natural
aspect ratio, or crop identically at every breakpoint.
Versioning
Every ImADe JSON payload carries a schemaVersion field. Models for each schema version live
in their own namespace (Ustin.Sales.Common.ImADes.V1 today); a future breaking shape change
ships as a V2 namespace alongside it rather than replacing it. ImADeSerializer is
schema-version-aware and rejects payloads it doesn't recognize instead of silently misreading them.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 47 | 9/14/2026 |