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

neat-edifact-mapper

v0.7.1

Published

Schema-based EDIFACT message mapper for neat-edifact. Define a schema, get back structured data.

Readme

neat-edifact-mapper

A TypeScript schema mapper for UN/EDIFACT interchanges. Give it a raw EDIFACT string and a schema definition, get back a typed, queryable object. That's it. It handles the structure mapping layer only — no business logic, no transforms, no opinions about what your data means. If you need BAPLIE parsing with domain objects, build that on top of this.

Install

npm install neat-edifact-mapper
pnpm add neat-edifact-mapper

Usage

import { defineGroup, defineSchema, defineSegment, EdifactDocument } from "neat-edifact-mapper";

const rawMessage = `UNA:+.? '
UNB+UNOA:2+SENDER+RECIPIENT+240101:1200+00000001'
UNH+1+ORDERS:D:96A:UN:1A'
BGM+220+ORDER123+9'
DTM+137:202405011200:203'
LIN+1+20+ITEM001'
QTY+21:10:PCE'
UNT+6+1'
UNZ+1+00000001'`

const schema = defineSchema({
  items: [
    defineSegment('BGM', { required: true }),
    defineSegment('DTM', { required: true }),
    defineGroup({
      head: defineSegment('LIN', { required: true }),
      items: [
        defineSegment('QTY', { required: false })
      ],
      required: false
    })
  ],
  strict: true
});

EdifactDocument.useStrict().fromString(rawMessage, schema).map() // MappedMessage[];

map() always returns MappedMessage[] — even for single interchange files. Just use the first array item for the common case.

Strict mode

By default the mapper is lenient. It'll do its best with whatever you give it, collecting unrecognised segments into an unknown bucket and stopping if things go too far off the rails.

If you want it to throw on any of that, pass strict: true when creating the schema and use .useStrict() on the EdifactDocument.

const schema = defineSchema({
  items: [...],
  strict: true
});

EdifactDocument.useStrict().fromString('', schema).map()

Strict mode enforces:

  • Required segments — if a segment is marked required: true and is missing, an error is thrown
  • Unknown segments — any segment not defined in your schema will throw rather than being collected

API

EdifactDocument

EdifactDocument.useStrict()
EdifactDocument.fromString(raw: string, schema: Schema): EdifactDocument
EdifactDocument.map(): MappedMessage[]

MappedMessage

mappedMessage.get('BGM')           // MappedSegment | MappedGroup | undefined
mappedMessage.get('LIN')           // MappedGroup | undefined
mappedMessage.unknown              // Segment[] — unrecognised segments (lenient mode only)

MappedSegment

mappedSegment.tag
mappedSegment.getDataElement(0)
mappedSegment.getDataElement(0)?.value
mappedSegment.getDataElement(0)?.getComponent(1)?.value

MappedGroup

mappedGroup.head                   // MappedSegment
mappedGroup.get('QTY')             // MappedSegment | undefined
mappedGroup.unknown                // Segment[]

Schema helpers

defineSchema({ items: SegmentDefinition[], strict?: boolean }): Schema
defineSegment(tag: string, options?: SegmentOptions): SegmentDefinition
defineGroup({ head: SegmentDefinition, items: SegmentDefinition[], required?: boolean }): GroupDefinition

SegmentOptions

{
  required?: boolean       // default: false
  repeatable?: number      // default: 1
  qualifier?: string       // match on first data element value
  ignore?: boolean         // parse but discard
}

Errors

import { EdifactSyntaxError, EdifactEnvelopeError, EdifactValidationError } from 'neat-edifact'
import { EdifactMappingError } from 'neat-edifact-schema'
  • EdifactSyntaxError — malformed input from the parser layer
  • EdifactEnvelopeError — broken UNB/UNZ/UNH/UNT structure
  • EdifactValidationError — count or reference mismatches (strict mode only)
  • EdifactMappingError — required segment missing or unknown segment encountered (strict mode only)

Notes

  • map() always returns MappedMessage[] — use .first() or index [0] for the common single-message case
  • In lenient mode, unrecognised segments are collected into .unknown on the MappedMessage or MappedGroup — position is preserved relative to surrounding mapped segments
  • The scan limit in lenient mode is 999 consecutive unmatched segments — at that point the mapper returns whatever it has built so far
  • Zero runtime dependencies beyond neat-edifact