Edifact.Overlays
1.0.0-preview.6
dotnet add package Edifact.Overlays --version 1.0.0-preview.6
NuGet\Install-Package Edifact.Overlays -Version 1.0.0-preview.6
<PackageReference Include="Edifact.Overlays" Version="1.0.0-preview.6" />
<PackageVersion Include="Edifact.Overlays" Version="1.0.0-preview.6" />
<PackageReference Include="Edifact.Overlays" />
paket add Edifact.Overlays --version 1.0.0-preview.6
#r "nuget: Edifact.Overlays, 1.0.0-preview.6"
#:package Edifact.Overlays@1.0.0-preview.6
#addin nuget:?package=Edifact.Overlays&version=1.0.0-preview.6&prerelease
#tool nuget:?package=Edifact.Overlays&version=1.0.0-preview.6&prerelease
Edifact.Overlays
Trading partner and subset rules layered over a base directory — tightened cardinalities, restricted code values and conditional requirements — compiled into an effective message and evaluated with a ledger saying which overlay decided what.
An implementation guide (EANCOM, a partner's subset, a house standard) is a document, never C#. It is something a trading partner publishes, revises and argues about, maintained by people who do not build software, so a guide here is versioned JSON you can upload, diff and serve. Compiling one into a class would make every revision a release of your application.
Install
dotnet add package Edifact.Overlays --prerelease
net8.0 and net10.0, no external dependencies. Most callers get this transitively through
Edifact.Validation, which is where guides are
usually applied; take it directly to compose, inspect or serve guides without validating anything.
You supply the directory
No directory data ships in this package. A compiled pack is a derivative of the UN Directory, and shipping one would make every consumer a redistributor of it. Download a release from UNECE (https://unece.org/trade/uncefact/unedifact/download) and ingest it once:
dotnet tool install --global Edifact.Cli --prerelease
edifact ingest ~/Downloads/D01B --out ~/edifact/packs/compiled
That writes the pack to ~/edifact/packs/compiled/untdid-d01b, and puts the four ISO 9735 syntax
definitions in ~/edifact/packs/syntax beside it. Those four are the one input no ingestion can
produce — the UNTDID omits the service definitions — so they reach a machine only because the tool
ships them. Files already in that directory are left alone.
Guides themselves are yours to write. Two worked examples are in
packs/overlays/.
A guide, in the format this package reads
{
"schemaVersion": 1,
"id": "acme-orders-2024",
"name": "ACME ORDERS agreement",
"applies": [{ "type": "ORDERS", "version": "D", "release": "01B", "agency": "UN" }],
"changes": [
{ "path": "SG2/NAD/3035", "restrict": { "codes": ["BY", "SU", "DP"] },
"note": "We identify three roles and reject the rest." },
{ "path": "SG25/SG28", "restrict": { "excluded": true } }
],
"rules": [
{
"id": "ORDERED_QTY_REQUIRES_PRICE",
"scope": "SG25",
"when": { "op": "exists", "of": "QTY" },
"then": { "op": "exists", "of": "SG30/PRI" },
"severity": "Error",
"message": "Line item {LIN/1082} orders a quantity without a price."
}
]
}
restrict narrows and extend widens, and the direction is the verb rather than something inferred
from comparing against the base — a change that turns out to widen would otherwise be accepted
silently. A document that widens anything must also declare "policy": "Extending": two deliberate
acts, neither of which happens by accident. Rules are evaluated once per occurrence of scope,
which is what lets one speak about sibling segments inside a single line item.
Use it
using Edifact.Core.Diagnostics;
using Edifact.Overlays;
using Edifact.Overlays.Serialization;
using Edifact.Schema.Model;
using Edifact.Schema.Serialization;
var syntax = new SyntaxPackSet("/home/me/edifact/packs/syntax");
var pack = PackReader.Read("/home/me/edifact/packs/compiled/untdid-d01b", syntax.For);
var guide = OverlayJson.ReadFile("acme-orders-2024.json");
// In precedence order: a later guide overrules an earlier one where both speak about the same
// aspect of the same position, and the earlier is kept as a contributing authority.
var compilation = OverlayCompiler.Compile(pack, new MessageKey("ORDERS", "D", "01B"), [guide]);
if (!compilation.IsUsable)
{
// A guide taken from a stranger is input: read the findings rather than throwing.
foreach (var finding in compilation.Errors) Console.WriteLine(finding);
return;
}
var effective = compilation.Require(); // or catch OverlayCompilationException
// What the composition decided, and who decided it.
foreach (var entry in effective.Ledger.Entries)
{
var over = entry.Contributing.Length > 0 ? $", over {entry.Contributing[0]}" : "";
Console.WriteLine($"{entry.Path} {entry.Aspect} by {entry.Writer}{over}"
+ (entry.Widens ? " (widens)" : ""));
}
// One position, as the guide leaves it.
if (effective.SlotAt(EdiPath.Parse("SG2/NAD/3035")) is { } slot)
{
Console.WriteLine(slot.Codes is null
? "the directory's own list, unchanged"
: string.Join(", ", slot.Codes));
}
// The segment table with the guide's exclusions and cardinalities applied, ready for
// Edifact.Structure's matcher.
var compiled = effective.Compiled;
OverlayJson.Deserialise throws OverlayFormatException for a document that is not one; a document
that is well-formed but says something impossible — a path that addresses nothing, a restrict that
names a code the directory does not publish, an expression past the 256-node cap — comes back as
findings on the OverlayCompilation instead.
Where this sits
Edifact.Core → nothing the tokenizer, usable with no directory at all
Edifact.Schema → Core what a release says
Edifact.Structure → Core, Schema matching a segment table
Edifact.Overlays → Structure what a guide says on top of a release ← you are here
Edifact.Validation → Structure, Overlays the usual entry point
Why this is its own project, and the four decisions behind the rule language, are in DESIGN.md. Full documentation: https://github.com/101-semaphore/EDIFACT.
Licence
Apache-2.0. See the NOTICE in this package for what the wider project is derived from and under
what terms.
| 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 is compatible. 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. |
-
net10.0
- Edifact.Structure (>= 1.0.0-preview.6)
-
net8.0
- Edifact.Structure (>= 1.0.0-preview.6)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Edifact.Overlays:
| Package | Downloads |
|---|---|
|
Edifact.Validation
Validates an interchange against a directory and any overlays: envelope structure, segment and element cardinality, representation and code values, each finding carrying the rule that produced it and where in the source it applies. |
|
|
Edifact.Projection
Projects a matched message into JSON or XML, either as the document it describes or as a linked form in which every value still points at the directory definition it was read against. |
|
|
Edifact.Eancom
Reads the EANCOM implementation guides published by GS1 and writes them as overlay documents. Part II gives the positions the subset does not use, the data elements it requires, and the code values it restricts each element to; Part III gives the code values EANCOM publishes that the base UN/EDIFACT directory does not. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-preview.6 | 79 | 10/11/2026 |
| 1.0.0-preview.5 | 95 | 9/19/2026 |
| 1.0.0-preview.4 | 89 | 9/17/2026 |
| 1.0.0-preview.3 | 127 | 9/7/2026 |
| 1.0.0-preview.2 | 112 | 9/6/2026 |
| 1.0.0-preview.1 | 89 | 9/6/2026 |