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

nav-osa-core

v0.2.0

Published

Shared TypeScript types, XML parser, XSD validator, and XML builder for the Hungarian NAV Online Invoice System (OSA)

Readme

nav-osa-core

Shared TypeScript types, XML parser, XSD validator, and XML builder for the Hungarian NAV Online Invoice System (OSA) version 3.0.

Hybrid architecture: parsing is done with libxml2-wasm (libxml2 compiled to WebAssembly), building with fast-xml-builder.

Contents

  • Generic XML parser built on libxml2-wasm configured for NAV XML documents
  • XML builders: buildInvoiceXml for invoice data, buildApiRequestXml for API request XML (built on fast-xml-builder)
  • XSD validation with built-in lazy validator cache (libxml2-wasm)

Installation

npm install nav-osa-core nav-osa-types

Usage

Types

Types are provided by the separate nav-osa-types package:

import { InvoiceData, TaxNumberType, MonetaryType } from 'nav-osa-types';

Parse XML

schemaName is required as the second argument — the XML is validated against that schema before parsing. Validation can be disabled with validate: false:

import { parseXml, XsdSchemaName } from 'nav-osa-core';
import { InvoiceData } from 'nav-osa-types';

const result = await parseXml<{ InvoiceData: InvoiceData }>(xmlString, XsdSchemaName.Data);
const resultNoValidation = await parseXml(xmlString, XsdSchemaName.Data, { validate: false });

If validation fails, a detailed XmlValidationError is thrown:

import { XmlValidationError } from 'nav-osa-core';

try {
  const result = await parseXml(xmlString, XsdSchemaName.Data);
} catch (err) {
  if (err instanceof XmlValidationError) {
    console.log('Validation failed:', err.errors);
  }
}

Validate XML

import { validateXml, ValidationResult, XsdSchemaName } from 'nav-osa-core';

const result: ValidationResult = await validateXml(xmlString, XsdSchemaName.Data);
if (!result.valid) {
  console.log('Errors:', result.errors);
}

Validators are cached by schema name after the first call.

Build invoice XML from JSON

Converts an InvoiceData object to XML and validates it against the built-in data.xsd schema:

import { buildInvoiceXml } from 'nav-osa-core';
import { InvoiceData } from 'nav-osa-types';

const invoice: InvoiceData = {
  invoiceNumber: 'ABC-2025-001',
  invoiceIssueDate: '2025-01-15',
  completenessIndicator: false,
  invoiceMain: {
    invoice: {
      invoiceHead: {
        supplierInfo: { /* ... */ },
        invoiceDetail: { /* ... */ },
      },
      invoiceSummary: { /* ... */ },
    },
  },
};

const xml = await buildInvoiceXml(invoice);

If validation fails, a detailed XmlValidationError is thrown:

import { XmlValidationError } from 'nav-osa-core';

try {
  const xml = await buildInvoiceXml(invoice);
} catch (err) {
  if (err instanceof XmlValidationError) {
    console.log('XSD validation errors:', err.errors);
  }
}

Build API request XML

Build and validate API request XML (TokenExchangeRequest, QueryInvoiceDigestRequest, etc.) with optional namespace prefixing:

import { buildApiRequestXml, XsdSchemaName } from 'nav-osa-core';

const xml = await buildApiRequestXml('TokenExchangeRequest', {
  '@_xmlns': 'http://schemas.nav.gov.hu/OSA/3.0/api',
  '@_xmlns:common': 'http://schemas.nav.gov.hu/NTCA/1.0/common',
  header: {
    requestId: 'RID...',
    timestamp: '2025-01-01T00:00:00.000Z',
    requestVersion: '3.0',
    headerVersion: '1.0',
  },
  user: {
    login: 'user',
    passwordHash: {
      '@_cryptoType': 'SHA-512',
      '#text': 'hash...',
    },
    taxNumber: '12345678',
    requestSignature: {
      '@_cryptoType': 'SHA3-512',
      '#text': 'sig...',
    },
  },
  software: {
    softwareId: '123456789012345678',
    softwareName: 'TestApp',
    softwareOperation: 'LOCAL_SOFTWARE',
    softwareMainVersion: '1.0',
    softwareDevName: 'Dev',
    softwareDevContact: '[email protected]',
  },
}, XsdSchemaName.InvoiceApi, {
  namespacePrefix: 'common',
  prefixRootKeys: ['header', 'user'],
});

The namespacePrefix option controls which top-level keys receive a namespace prefix. With prefixRootKeys: ['header', 'user'], the output becomes:

<TokenExchangeRequest xmlns="..." xmlns:common="...">
  <common:header>
    <common:requestId>RID...</common:requestId>
    ...
  </common:header>
  <common:user>...</common:user>
  <software>...</software>
</TokenExchangeRequest>

XSD schemas

The module ships the official NAV XSD files and an enum to reference them:

  • XsdSchemaName.Commoncommon.xsd — NTCA Common types
  • XsdSchemaName.InvoiceBaseinvoiceBase.xsd — Base invoice types
  • XsdSchemaName.Datadata.xsd — Invoice data types
  • XsdSchemaName.InvoiceApiinvoiceApi.xsd — API request/response types
import { validateXml, buildApiRequestXml, XsdSchemaName } from 'nav-osa-core';

// Validate against a named schema
await validateXml(xmlString, XsdSchemaName.Data);

// Build and validate API request
await buildApiRequestXml('TokenExchangeRequest', data, XsdSchemaName.InvoiceApi);

Security options

The parser processes XML entities by default (processEntities: true) to protect against entity expansion attacks. For trusted XML (self-generated documents with no external input), you can disable this to reduce overhead:

import { parseXml, XsdSchemaName } from 'nav-osa-core';

const result = await parseXml(xmlString, XsdSchemaName.Data, { processEntities: false });

Warning: Only disable entity processing when parsing XML you fully control. Never use this for external or untrusted input.

Payload size limit

The parser rejects XML payloads larger than 10 MB by default. You can override this:

import { parseXml, XsdSchemaName } from 'nav-osa-core';

const result = await parseXml(xmlString, XsdSchemaName.Data, { maxXmlSize: 50 * 1024 * 1024 });

Security

  • Network access disabled (NONET) — XML parsing never fetches external resources, preventing XXE (XML External Entity) attacks.
  • Entity expansion protection (processEntities: true by default) — guards against billion laughs / exponential entity expansion attacks. Can be disabled for trusted self-generated XML to reduce overhead.
  • Payload size limit (maxXmlSize: 10 MB by default) — prevents memory exhaustion from oversized XML inputs.
  • HUGE flag — used only when loading the built-in XSD schemas (trusted, shipped with the package). Never applied to user-provided XML.

Support

If you find this package useful, consider supporting the development:

License

Apache-2.0