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

@n42/edelivery

v0.1.79

Published

Node42's pure Node.js eDelivery toolkit — SMP lookup, document validation and AS4 signing, encryption and sending. No Java, no third-party AP dependencies.

Downloads

767

Readme

CI codecov npm

Node42 eDelivery

Pure Node.js Peppol AS4 Sender & Toolkit
Intended for interoperability testing, validation, troubleshooting, and controlled AS4 message transmission (e.g., dispatching UBL documents).

Low-Level Cryptographic Implementation

A deliberate choice was made to keep this a super lightweight, pure Node.js implementation with zero platform dependencies.

All cryptographic operations:

  • RSA-OAEP key wrapping
  • AES-128-GCM encryption
  • RSA-SHA256 signing
  • X.509 certificate handling

are implemented directly using Node.js's built-in crypto module and the xml-crypto library, with no native addons, no external binaries, and no compilation required.

Features

  • SML lookup + Peppol SMP discovery
  • Send AS4 messages (validate, sign, encrypt, verify)
  • Built-in schematron validation
  • Transaction reporting
  • Replay last message byte-for-byte
  • Zero native dependencies, zero compilation
  • Works on Linux, macOS and Windows

Background

If you’d like a deeper understanding of the protocol before exploring the code, the accompanying Medium articles provide additional context. They walk through the AS4 transport protocol, explain how Peppol messaging works in practice, and describe the reasoning behind building this implementation.

Installation

Requirements

  • Node.js 18+ (Node 20 recommended)
  • npm

Install globally

npm install -g @n42/edelivery

Verify installation:

n42-edelivery --version

Commands

init

Initialize local Node42 workspace with certificates, schematrons, and JSON control structure (for dynamic UBL document creation)

.node42/
    ├── certs/
    │     ├── cert.pem
    │     ├── key.pem
    │     └── truststore.pem
    └── templates/
            └── ubl.json

Certificates can be placed in ~/.node42/certs/ using the naming convention above, or their paths specified explicitly via --cert, --key and --truststore flags.

pki

Display PKI configuration — certificate, private key and truststore used for AS4 signing, encryption and peer validation.

send peppol

Send a Peppol UBL document via AS4.

| Argument | Description | |--------------------|------------------------------------------------------| | --replay | Re-send transaction using stored artefacts | | --document | Path to the UBL XML document to send | | --data | Path to JSON document data | | --schematron | Path to schematron XSL files for validation | | --env | Target environment: test or prod | | --cert-id | Node42 Probe certificate ID | | --cert | Public certificate (PEM) | | --key | Private key (PEM) | | --key-pass | Private key passphrase | | --truststore | Truststore (PEM) | | --sender-id | Peppol participant ID of sender | | --receiver-id | Peppol participant ID of receiver | | --sender-country | Sender country code | | --endpoint-url | Override the SMP-discovered endpoint URL | | --hostname | Hostname used in message IDs | | --strip-sbdh | Strip SBDH and re-wrap using provided context | | --dryrun | Prepare and resolve but do not transmit | | --persist | Persist transaction data to disk | | --verbose | Enable detailed output |

validate peppol

Validate a Peppol UBL document against schematron rules.

| Argument | Description | |-----------------|--------------------------------------------| | --document | Path to UBL XML document (required) | | --schematron | Path to schematron XSL files | | --persist | Persist validation errors to disk | | --verbose | Enable detailed output |

report peppol

Generate Peppol reporting data

| Argument | Description | |-----------------|--------------------------------------| | --from | Start date of the reporting period | | --to | End date of the reporting period |

Usage

Send a prepared document directly:

n42-edelivery send peppol \
    --env "test" \
    --document "~/<path_to_document>/invoice.xml"

Send a test document dynamically built from CLI arguments and an UBL document descriptor:

n42-edelivery send peppol \
    --env "test" \
    --sender-id "iso6523-actorid-upis::0007:node42" \
    --receiver-id "iso6523-actorid-upis::0007:node42" \
    --sender-country SE \
    --ubl "./ubl.json"

The --ubl document descriptor:

{
    "document_type" : "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
    "process_id" : "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
    "seller": {
        "name": "Test Sender",
        "endpoint_scheme": "0007",
        "street": "Sender Street 1",
        "city": "Stockholm",
        "zip": "11122",
        "vat": "SE556677889901",
        "company_id": "5566778899"
    },
    "buyer": {
        "name": "Test Receiver",
        "endpoint_scheme": "0008",
        "street": "Receiver Street 1",
        "city": "Brussels",
        "zip": "1000",
        "country": "BE",
        "company_id": "6677889900"
    },
    "invoice": {
        "currency": "EUR",
        "payment_means": "30",
        "items": [
            {
                "name": "Consulting Services",
                "quantity": 2,
                "unit": "HUR",
                "unit_price": "100.00",
                "net_amount": "200.00",
                "vat_percent": 25
            },
            {
                "name": "Software License",
                "quantity": 1,
                "unit": "EA",
                "unit_price": "50.00",
                "net_amount": "50.00",
                "vat_percent": 25
            }
        ]
    }
}

Validate a document:

n42-edelivery validate peppol \
    --document "~/<path_to_document>/invoice.xml"

Replay

The replay command resends a previously sent AS4 message byte-for-byte using its stored artefacts.

n42-edelivery replay

The last sent transaction is automatically selected. To replay a specific transaction, pass its ID:

n42-edelivery replay <transactionId>

The original message headers, and body are loaded from disk and transmitted as-is to the original endpoint — identical bytes, identical message ID.

  • The receiving Access Point (C3) must have duplicate message detection disabled before replaying.
    By default, most AS4 implementations reject messages with a previously seen message ID.

Persistence

When --persist is enabled, the tool stores execution artefacts for later inspection.

.node42/
    └── artefacts/
            ├── discovery/
            ├── validations/
            └── transactions/
                     ├── <uuid>_context.json
                     ├── <uuid>_document.xml
                     ├── <uuid>_validation.xml
                     ├── <uuid>_soap_envelope.xml
                     ├── <uuid>_signing_input.txt
                     ├── <uuid>_message_headers.json
                     ├── <uuid>_message_body.txt
                     └── <uuid>_as4_signal.json

Workspace

Node42 stores runtime data, generated artefacts, certificates, and configuration in the user workspace located at ~/.node42.

.node42/
    ├── artefacts/
    ├── certs/
    ├── schematrons/
    │       ├── billing/
    │       ├── reporting/
    │       └── schxslt/
    ├── templates/
    ├── reports/ 
    ├── db.json
    ├── replay.txt
    └── .env.local

This directory contains all local data required by the CLI, including cached artefacts, validation rules, certificates, templates, and execution history.

Disclaimer

Production deployment requires proper certificate lifecycle management, secure key storage, monitoring, and full compliance with applicable Peppol policies and transport requirements.

License

Apache-2.0

Author

Alex Olsson
LinkedIn