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

@flaks/onerecord

v0.2.0

Published

Zero-dependency Zod-first JSON-LD mapper for IATA OneRecord cargo data model 3.2 + API spec 2.2.0

Readme

@flaks/onerecord

Zero-dependency Zod-first TypeScript mapper for the IATA OneRecord cargo data model 3.2 and API spec 2.2.0.

What it is

@flaks/onerecord provides round-trip-safe serialization and deserialization for 32 OneRecord cargo data model classes. Each class ships with a Zod schema, an application-layer TypeScript type, a JsonLd<T> brand, serialize / serializeStrict / deserialize functions, and a Codec bundle. A factory (createMapper) and a namespaced facade (onerecord) cover the two main consumption patterns. Safety primitives (depth, node, string, array, payload limits; prototype-pollution defense; IRI validation) run before Zod so that invalid JSON-LD graphs never reach schema evaluation. All 22 parse-error variants are typed as a discriminated union (ParseError) so callers handle every failure mode exhaustively.

Why use this library?

Air cargo is migrating to OneRecord — IATA's JSON-LD-based replacement for EDIFACT / Cargo-IMP messaging. As of January 2026, roughly 8% of the industry has adopted; the standard is endorsed but the TypeScript tooling ecosystem is sparse. @flaks/onerecord fills that gap.

Use this library if you're building cargo software that needs to:

  • Accept OneRecord JSON-LD from external endpoints with strict validation (Zod schemas + cardinality + IRI + a pre-Zod safety pass).
  • Emit spec-compliant JSON-LD with stable round-trip semantics (serialize(deserialize(x)) == x per spec §7.1).
  • Refuse malformed graphs early — depth bombs, prototype-pollution attempts, empty arrays on the wire, circular references — before they reach Zod or your downstream code.
  • Catch cross-node graph violations with createMapper({ graphWalk: true }) or the onerecord.dispatch.deserialize.<Class> namespace — duplicate_id_in_graph, missing_id, wrong_type_for_endpoint, missing_type, all surfaced as typed ParseError variants. Default per-class deserializers stay structural-only for v0.1.x compatibility; graph-walk is opt-in.
  • Type-check every parse-failure path: ParseError is a 22-variant discriminated union, so the compiler tells you when you've forgotten a failure mode.

Skip it if you want a generic JSON-LD or RDF toolkit; this is purpose-built for the IATA cargo ontology and the ONE Record API spec 2.2.0.

Publicly verifiable

This library publishes verifiable artifacts so consumers can audit the conformance claim independently:

  • All releases are GPG-signed git tags + signed npm tarballs (per MAINTENANCE.md).
  • Every spec deviation is documented in docs/spec-deviations.md with status banners (CLOSED, PARTIAL, deferred-to-v0.3) and explicit guidance on what consumers should do today.
  • Property-based round-trip tests for the eight Ring 1+2 classes (Waybill, Shipment, Piece, Address, Person, Organization, Party, AccountNumber) — serialize(deserialize(x)) is field-equivalent for any value an Arbitrary produces.
  • Contract tests at test/contract/ exercise the wire format end-to-end against the OLF-hosted reference NE:ONE Server (the IATA OneRecord reference implementation). See CONTRIBUTING.md for how to run them.

Status

v0.2.0 ships:

  • The 32 canonical cargo data model classes (Ring 1–5 plus booking-flow) with full round-trip codecs, Zod schemas, snapshot tests, and pre-Zod safety primitives.
  • Opt-in graph-walk dispatcher (createMapper({ graphWalk: true }) or onerecord.dispatch.deserialize.<Class>) emitting all four cross-node integrity ParseError kinds.
  • Spec-correct acceptBookingOptionViaRequest transition that returns the BookingOptionRequest intermediate per spec §5.4. The legacy acceptBookingOption is @deprecated (removal v0.3 unless IATA §5.4 reconciliation restores the §5.2 shortcut).
  • Property-based round-trip tests for all 8 Ring 1+2 classes.
  • FSU code fixture regenerated with a real sha256: blob hash, sourced from upstream IATA-Cargo via the sibling tjo099/onerecord-xlsx-tools tool. Library no longer carries the xlsx devDep — closes the two high-severity Prototype Pollution + ReDoS advisories.
  • See docs/roadmap.md for what's next.

The library is Apache-2.0 and ready for use within the v0.x stability policy described in MIGRATING.md.

Spec compliance: cargo data model 3.2 (2025-07 endorsed standard), API spec 2.2.0. A small number of deliberate divergences from canonical spec behavior are documented in docs/spec-deviations.md; read that before adopting if your integration must match the spec verbatim.

Install

npm install @flaks/onerecord
# or
bun add @flaks/onerecord
# or
pnpm add @flaks/onerecord

Pin a minor range in production (e.g. "@flaks/onerecord": "^0.2.0"). Per MIGRATING.md, minor versions may introduce breaking changes documented in CHANGELOG.md; patch versions will not.

Installing from a git tag is also supported for testing forks or unreleased branches:

bun add git+https://github.com/tjo099/onerecord-mapper#v0.2.0

Usage

Round-trip with WaybillCodec

import { WaybillCodec } from '@flaks/onerecord'

// Deserialize raw JSON-LD from the wire
const result = WaybillCodec.deserialize(rawJsonLd)
if (result.ok) {
  const waybill = result.value          // typed as Waybill (application object)
  const jsonLd = WaybillCodec.serialize(waybill)  // back to JsonLd<Waybill>
} else {
  console.error(formatError(result.error))
}

createMapper with custom limits

import { createMapper } from '@flaks/onerecord'

const mapper = createMapper({
  limits: { maxDepth: 12, maxNodes: 500, maxPayloadBytes: 512_000 },
  iriStrategy: 'strict',
  allowedSchemes: ['https'],
})

const result = mapper.deserialize.Waybill(rawJsonLd)
const jsonLd  = mapper.serialize.Waybill(waybill)

onerecord namespaced facade

import { onerecord, formatError } from '@flaks/onerecord'

// One-off operations, no factory state
const result = onerecord.deserialize.Shipment(rawJsonLd)
if (!result.ok) {
  throw new Error(formatError(result.error))
}
const jsonLd = onerecord.serialize.Piece(piece)

API overview

Per-class exports

Each of the 32 classes exposes:

| Export | Description | |---|---| | <Class>Schema | Zod schema for the application object | | <Class>Codec | { serialize, serializeStrict, deserialize } bundle | | serialize<Class>(obj) | Returns JsonLd<T> | | deserialize<Class>(raw) | Returns Result<T, ParseError> |

Factory

createMapper(opts: {
  limits?: Partial<SafetyLimits>
  iriStrategy?: 'strict' | 'lenient'
  allowedSchemes?: string[]
}): BoundMapper

Returns a mapper with bound serialize.<Class> and deserialize.<Class> methods using deep-frozen options set at creation time.

Facade

onerecord.deserialize.<Class>(raw): Result<T, ParseError>
onerecord.serialize.<Class>(obj): JsonLd<T>

No bound state; suitable for one-off operations and tree-shake-friendly imports.

Errors

  • ParseError — 22-variant discriminated union (kind field); covers zod_validation, cardinality_violation, invalid_iri, depth_limit_exceeded, prototype_pollution_attempt, invalid_pointer, and 16 more
  • SerializationErrorcode: 'invalid_application_object' | 'iri_construction_failed'
  • formatError(e: ParseError): string — human-readable message
  • redactError(e: ParseError): ParseError — strips PII from error payloads before logging

Booking state machine

import { STATE_DIAGRAM, canTransition } from '@flaks/onerecord'

canTransition(from, to)            // boolean predicate
acceptBookingRequest(req)          // typed transition → BookingOption
acceptBookingOption(opt)           // typed transition → Booking
rejectBookingOption(opt)           // typed transition → BookingOption
revokeBookingOption(opt)           // typed transition → BookingOption

Operations (JSON-Patch per spec §6.5)

import { applyChange, validateOperation, asJsonPointer } from '@flaks/onerecord'

applyChange(codec, obj, change)         // returns Result<T, ParseError>
validateOperation(op, allowedFields)    // validates op.s against allowed field list
asJsonPointer(path)                     // typed JsonPointer helper

FSU codes

import { FSU_EVENT_CODES } from '@flaks/onerecord'
// Record<string, FsuEventCode> — 26-code map per IATA XFSU spec

Safety primitives

import { DEFAULT_SAFETY_LIMITS, mergeLimits } from '@flaks/onerecord'
// DEFAULT_SAFETY_LIMITS: SafetyLimits (depth, nodes, strings, arrays, payloadBytes)
// mergeLimits(base, overrides): SafetyLimits

IRI utilities

import { safeIri, validateIri, defaultIriStrategy } from '@flaks/onerecord'
// safeIri()             — Zod helper; lifts IRI failures into kind: 'invalid_iri'
// validateIri(s)        — Result<SafeIri, ParseError>
// defaultIriStrategy    — IriStrategy with https-only scheme enforcement

Architecture notes

  • Zero runtime dependencies other than Zod (peer).
  • Round-trip safety: serialize(deserialize(x)) == x per spec §7.1 tolerance. Deserialized application objects carry no @context or @type noise; serialize reconstructs the canonical JSON-LD envelope.
  • Pre-Zod safety pass: before any schema evaluation, preValidate enforces depth, node count, string length, array length, and payload-byte limits; detects prototype-pollution keys (__proto__, constructor, prototype); and unwinds JS-level circular references. Zod never sees a malformed graph.
  • Empty arrays rejected at any depth as cardinality_violation. The spec mandates omitting a field rather than sending []; this is enforced pre-Zod.
  • Null-prototype output: all deserialized graphs are built on Object.create(null) objects. Consumer code cannot accidentally read or pollute Object.prototype through a deserialized value.
  • Branded types: SafeIri (validated IRI string) and JsonLd<T> (serialized graph) are distinct branded types. TypeScript prevents passing a raw string where a SafeIri is required, and passing an application object where JsonLd<T> is expected.

Tree-shaking

For maximum bundle size optimization, import from the /codecs subpath:

import { WaybillCodec } from '@flaks/onerecord/codecs'
import { ShipmentCodec } from '@flaks/onerecord/codecs'

Type-only imports (zero runtime cost):

import type { Waybill, ParseError } from '@flaks/onerecord/types'

Version pins

| Spec | Version | |---|---| | Cargo data model | 3.2 (2025-07 endorsed standard) | | API spec | 2.2.0 |

Development

bun install
bun run test       # 518 passing + 10 skipped = 528 total
bun run lint       # Biome
bun run typecheck  # tsc --noEmit

License

Apache-2.0