npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@adeloi/edi-fixtures

v1.0.0

Published

Realistic X12 EDI test documents for integration testing — including the ways they break in production.

Readme

edi-fixtures

Realistic X12 test documents for integration testing — including the ways they break in production.

Real EDI files are confidential. Spec examples are sterile: one line item, round numbers, every segment present. This library generates deterministic, realistic 850/855/856/810/997 documents — and lets you inject the 18 failure modes we keep seeing in real trading-partner relationships: nonstandard UOMs, missing partner-required REFs, duplicate control numbers, orphaned HL loops, 997s that never arrive.

Built by Adeloi, an engineering partner for industrial suppliers and manufacturers.

CI npm License: Apache 2.0

Status: Stable. Feature-complete for the 004010 order-to-invoice flow.


See it in action

po850({ seed: 42, lines: 2 }).build();
ISA*00*          *00*          *ZZ*SENDERID       *ZZ*RECEIVERID     *240404*0538*U*00401*530335606*0*P*:~
GS*PO*SENDERID*RECEIVERID*20240404*0518*27124*X*004010~
ST*850*0001~
BEG*00*NE*PO173006**20240404~
REF*DP*809~
DTM*002*20240412~
N1*ST*Vantage Supply Co*92*LOC4005~
N3*6007 Industrial Pkwy~
N4*Ontario*CA*91761~
PO1*1*228*EA*220.64*PE*BP*AX-31566~
PID*F****Hex Bolt 3/8-16 x 2in Zinc~
PO1*2*5*CS*209.50*PE*BP*SKU-50201~
PID*F****Shop Towel Roll Blue~
CTT*2~
SE*13*0001~
GE*1*27124~
IEA*1*530335606~

Now the same seed with two faults from the catalog applied:

po850({ seed: 42, lines: 2 })
  .with(faults.uomNonstandard())
  .with(faults.missingRef("DP"))
  .build();
 ISA*00*          *00*          *ZZ*SENDERID       *ZZ*RECEIVERID     *240404*0538*U*00401*530335606*0*P*:~
 GS*PO*SENDERID*RECEIVERID*20240404*0518*27124*X*004010~
 ST*850*0001~
 BEG*00*NE*PO173006**20240404~
-REF*DP*809~
 DTM*002*20240412~
 N1*ST*Vantage Supply Co*92*LOC4005~
 N3*6007 Industrial Pkwy~
 N4*Ontario*CA*91761~
-PO1*1*228*EA*220.64*PE*BP*AX-31566~
+PO1*1*228*EACH*220.64*PE*BP*AX-31566~
 PID*F****Hex Bolt 3/8-16 x 2in Zinc~
-PO1*2*5*CS*209.50*PE*BP*SKU-50201~
+PO1*2*5*CASE*209.50*PE*BP*SKU-50201~
 PID*F****Shop Towel Roll Blue~
 CTT*2~
-SE*13*0001~
+SE*12*0001~
 GE*1*27124~
 IEA*1*530335606~

Same envelope, same control numbers, same line data — just the department REF gone (and SE01 correctly recounted to 12, not left stale at 13 — removing a segment is only ever that fault, never an accidental second one) and two UOM codes swapped for the nonstandard synonyms partners actually send. That's the whole idea: a document that's wrong in one specific, realistic way instead of unrecognizable.

Contents

Install

npm install --save-dev @adeloi/edi-fixtures

Zero runtime dependencies. Works in Node ≥20, Bun, Deno, and the browser — it's pure string generation in, string out.

Quickstart

import { po850, scenario, faults, definePartner } from "@adeloi/edi-fixtures";

// 1. A valid document, deterministic — same seed, byte-identical output, forever.
const doc = po850({ seed: 42, lines: 5 }).build();

// 2. A deliberately broken document — the core of this library.
const broken = po850({ seed: 42 })
  .with(faults.uomNonstandard())   // "EACH" instead of "EA" in PO1-03
  .with(faults.missingRef("DP"))   // a partner-required REF is missing
  .build();

// 3. A consistent chain of documents across an order-to-invoice flow.
const flow = scenario.orderToInvoice({ seed: 7, lines: 3 }).build();
// -> { po, ack, asn, invoice, fa }
// Same PO number and line items end to end; each doc keeps its own
// interchange control numbers, exactly as five real transmissions would.

// 4. A chain with a realistic production fault injected.
const messy = scenario
  .orderToInvoice({ seed: 7 })
  .with(faults.asnQtyMismatch())   // the 856 reports more than the 850 ordered
  .with(faults.fa997Missing())     // and the 997 never arrives
  .build();

// 5. Parametrize for a trading partner, without pretending to be their real implementation guide.
const partner = definePartner({
  isaQualifier: "ZZ",
  requiredRefs: ["DP", "IA"],
  uomWhitelist: ["EA", "CS"],
});
const forPartner = po850({ seed: 1, partner }).build();

What this is

Deterministic, realistic X12 test documents for integration testing — plus a curated catalog of the failures that actually show up in real trading-partner relationships, each one composable onto an otherwise-valid document.

  • Deterministic. Same seed → byte-identical document, today and five years from now. Fixtures belong in snapshot tests and CI, and non-determinism there is poison. Seeded PRNG, not Math.random(); dates derived from the seed, not the system clock. See docs/design.md.
  • Realistic. Plausible part numbers, mixed UOMs, crooked quantities and prices, a correct fixed-width ISA envelope, consistent control numbers across ISA/GS/ST/SE/GE/IEA, valid GS1 SSCC-18 check digits.
  • Fault injection. Every fault in the catalog is a pure, composable function applied on top of an otherwise-valid document.
  • Scenario presets. scenario.orderToInvoice(...) produces a consistent document chain — same PO number, same line items — across the full order-to-invoice flow.
  • Zero dependencies. Pure strings in, pure strings out. No parser lock-in, no framework assumptions.

What this is NOT

  • Not a parser or validator. This library only generates documents. For parsing/validating incoming X12, see node-x12 or the Stedi EDI ecosystem.
  • Not a mapper or translator.
  • Not a source of trading-partner implementation guides. Guides for specific partners (Walmart, Grainger, etc.) are proprietary. definePartner() gives you a generic, configurable partner profile instead.
  • Not EDIFACT, TRADACOMS, or HIPAA transactions (270/271/837/...).
  • Not an AS2/SFTP/VAN transport client.
  • Not a UI.

Document types

X12 Release 004010 — the de facto standard in US retail/industrial EDI.

| Type | Name | Role in the flow | |---|---|---| | 850 | Purchase Order | Buyer places an order | | 855 | PO Acknowledgment | Seller confirms/changes it | | 856 | Advance Ship Notice | Shipment notice, with a full HL hierarchy (Shipment → Order → Pack → Item) | | 810 | Invoice | Seller bills for it | | 997 | Functional Acknowledgment | Receipt confirmation at the functional-group level |

Together these cover the complete order-to-invoice flow of a distributor or manufacturer. 860/865 (Change Orders) are on the roadmap, not in v1.0.

The fault catalog

18 faults across 4 categories. Each one exists as code (faults.*), as a documented entry in docs/faults.md — what happens, why it happens in production, and what it costs — and as a test case.

| Category | Faults | |---|---| | A — Structure/Envelope | isaTruncated · seCountWrong · controlNumberMismatch · duplicateIsaControl · nonstandardSeparators | | B — Semantics/Content | uomNonstandard · impliedDecimals · dateFormatShort · cttMismatch · missingRef | | C — Sequence/Acknowledgment | fa997Missing · fa997Rejected · fa997UnknownGroup · outOfOrderInterchange | | D — 856-specific | hlOrphan · ssccInvalid · asnQtyMismatch · asnAfterDelivery |

Faults in categories A, B, and most of D operate on a single document via .with(...). Faults in category C, plus asnQtyMismatch, need more than one document (or the absence of one) to mean anything, so they apply to a scenario.orderToInvoice(...) chain instead. See docs/faults.md for the full writeup of each one.

API

po850(options): DocBuilder
ack855(options): DocBuilder
asn856(options): DocBuilder
invoice810(options): DocBuilder
fa997(options): DocBuilder    // options.target identifies what's being acknowledged

interface DocBuilder {
  with(fault: Fault): DocBuilder;   // composable, chainable
  build(): string;                  // the final ISA...IEA string
  buildDocument(): EdiDocument;     // pre-serialization model, for assertions
}

scenario.orderToInvoice(options): ScenarioBuilder
interface ScenarioBuilder {
  with(fault: ScenarioFault): ScenarioBuilder;
  build(): { po: string; ack: string; asn: string; invoice: string; fa: string | null };
}

definePartner(overrides: Partial<PartnerProfile>): PartnerProfile

Every document builder shares an options shape along the lines of:

interface DocOptions {
  seed: number;
  lines?: number;          // default 3
  poNumber?: string;       // auto-generated from the seed if omitted
  partner?: PartnerProfile;
  referenceDate?: Date;
}

See docs/design.md for the determinism guarantees and why this library has zero runtime dependencies.

Contributing

Issues and PRs welcome — especially new faults backed by something you've actually seen in production. Run npm test before opening a PR; every document type and every fault has test coverage, including a cross-check against an independent X12 parser (node-x12, dev-only) in test/spec-conformance.test.ts.

License

Apache License 2.0. Copyright 2026 Olevis LLC.