Skip to content

Repository files navigation

Onyxa

A browser-only ONIX metadata composer. Write a book record, or open an existing ONIX file, and get valid XML back out — in ONIX 2.1, 3.0 or 3.1, in reference or short tags.

There is no backend. Every schema, code list, parse, validation, conversion and download happens in your browser; nothing is uploaded anywhere.

Live at onyxa.aodihis.com.

What it does

  • Open or start fresh — drop in an existing ONIX file, or begin a new record.
  • Reads what the trade actually sends — ONIX 2.1 and 3.0/3.1, reference tags (<ProductForm>) and short tags (<b012>), single- or multi-product files, namespaced or not. The version is detected from the file.
  • Converts between versions in both directions, and tells you which fields cannot survive the trip before you commit to it.
  • Covers every field. 1,454 elements across the three releases, all editable, all round-trippable — proven by a check that fails the build otherwise.
  • Validates as you type — required, conditional and code-list membership, against the full Issue 74 code lists.

Field coverage

Version Elements In folios In All fields Round-trip Gaps
ONIX 2.1 431 130 301 431 0
ONIX 3.0 512 210 302 512 0
ONIX 3.1 511 209 302 511 0

Rather than hand-writing ~500 form controls, the app generates a JSON element registry from EDItEUR's own schemas — reference name, short tag, parent path, cardinality, datatype, code list, sequence position — and renders forms from it. Eight curated folios cover the fields most records need; a ninth All fields view exposes everything else.

npm run check:coverage then asserts that every element in every registry is both editable in the UI and survives a parse → serialize → parse round trip in both tag styles, and fails otherwise. Because the registry is generated rather than written by hand, "all fields are covered" is a measurement, not a claim. Latest run: dev_docs/coverage.md.

Getting started

npm install
npm run dev

Scripts

Script Does
npm run dev Dev server
npm run build Static site into build/ — host it anywhere
npm test Everything, coverage check included
npm run test:unit Everything except the coverage check
npm run check:coverage Coverage check alone; writes coverage-report.json and dev_docs/coverage.md
npm run check svelte-check type checking
npm run build:registry Regenerate the registries and code lists from vendor/

Docker

make build            # docker build -t ghcr.io/aodihis/onyxa:latest .
make run              # serve it on http://localhost:8080
make release TAG=v1   # build and push to GHCR

The image is a multi-stage build: Node compiles the static site, then nginx:alpine serves it (~64 MB). nginx handles the SPA fallback — /editor and /preview are client-side routes with no file behind them — and gzips the generated JSON, which is worth about 6.6:1 (elements.3.0.json is 160 KB raw, 24 KB over the wire).

The test suite runs inside the build, so a broken record model cannot be published.

Deployment

Pushes to main run the suite, publish to GHCR, and deploy over SSH to a VPS running Traefik. See .github/workflows/docker-publish.yml and docker-compose.vps.yml.

Repository variables

Variable Value
DOMAIN onyxa.aodihis.com — written to the host .env as APP_HOST
APP_DIR /opt/apps/onyxa

Repository secrets — currently placeholders; deploys will fail until they are real:

Secret Should be
VPS_HOST Hostname or IP of the VPS
VPS_USER SSH user to deploy as
VPS_SSH_KEY Private half of a deploy keypair whose public half is in that user's ~/.ssh/authorized_keys
gh secret set VPS_HOST    --repo aodihis/onyxa --body "1.2.3.4"
gh secret set VPS_USER    --repo aodihis/onyxa --body "deploy"
gh secret set VPS_SSH_KEY --repo aodihis/onyxa < ~/.ssh/onyxa_deploy

The VPS needs Docker, the external traefik and shared-network networks, and a DNS A record for onyxa.aodihis.com. The domain lives in the DOMAIN repository variable, so changing it there moves the app on the next deploy.

docker-compose.vps.yml declares env_file: .env, so .env must exist next to it — without it docker compose up fails and the container never starts, which shows up as "not registered in Traefik". The deploy writes it every time; if you run compose by hand:

printf 'APP_HOST=onyxa.aodihis.com\nTAG=latest\n' > /opt/apps/onyxa/.env

If the site 404s or the router never appears, run scripts/diagnose-deploy.sh on the VPS.

Schemas and code lists

All schema sources are vendored so the build is offline and reproducible. Provenance, versions and licences are in vendor/editeur/SOURCE.md and vendor/transpect/2.1/SOURCE.md.

  • ONIX 3.0 / 3.1 — EDItEUR XSDs, code lists Issue 74.
  • ONIX 2.1 — EDItEUR withdrew the 2.1 XSDs, so the 2.1 registry is generated from the RelaxNG conversion published by transpect.io (BSD-2-Clause), which carries ONIX 2.1 revision 03 verbatim.

ONIX is a standard of EDItEUR. Its schemas and code lists are copyright EDItEUR and are redistributed here unmodified, as permitted for general use.

How it is built

dev_docs/ carries the plan, a per-phase write-up, and a decision log (decisions.md) recording the seventeen architectural decisions and why each was made — including the ones that turned out to be wrong.

Two worth knowing if you touch the conversion code:

  • ONIX 3.1 is not a superset of 3.0. It removes 20 elements and adds 18, so every version change is potentially lossy, including 3.0 → 3.1.
  • Never rename an element the target version already defines. The reverse rename table is derived by inverting the forward one, and that inversion is lossy — five 2.1 names collapse onto TitleText. Ignoring this silently lost the book's title on a 2.1 → 3.0 → 2.1 round trip.

Tech

SvelteKit (adapter-static, SPA) · Svelte 5 runes · TypeScript · Vitest · fast-xml-parser · nginx.

Licence

MIT.

About

An Onix form to help user generate their XML.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages