Skip to main content
TOML

Documentation

Using Vazen TOML

Use the @vazen/toml package to read and write Vazen TOML, JSON and PSA files. Any TOML parser can also read a Vazen TOML file.

Example shelf

This schema 0.3.0 spec describes two cereal products on one shelf. Each has three facings across and four packs deep, so the shelf holds 24 units.

Download example-shelf.vazen.toml

View the complete TOML file
# Wholly fictional example.
# All names, identifiers and measurements are invented.
schema = "vazen/spec"
schema_version = "0.3.0"
name = "Example shelf"

[[products]]
name = "Oat cereal"

[[products]]
name = "Cocoa cereal"

[[fixtures]]
[[fixtures.equipment]]
type = "shelf"

[[fixtures.equipment.sites]]
product = { name = "Oat cereal" }
facings = { wide = 3, deep = 4 }

[[fixtures.equipment.sites]]
product = { name = "Cocoa cereal" }
facings = { wide = 3, deep = 4 }

The products list defines the products. Each site selects one product by name and gives its facing counts. An omitted facing count is one, so facings = { wide = 3, deep = 4 } means three across, one high and four deep.

A vazen/spec file can omit dimensions and positions. A layout engine adds them to make a vazen/layout file, which records the resolved geometry.

Installation

Package@vazen/toml 0.4.0 (opens in a new tab)
ReadsVazen TOML 0.3.0, spec and layout, as TOML or JSON. PSA files of any version.
WritesVazen TOML 0.3.0, as TOML or JSON. PSA 2017.1.0 to 2024.4.0.
Default outputVazen TOML 0.3.0. PSA 2024.4.0.
DetailsVersions and compatibility

Requirements:

  • Node.js >=24.
  • ES modules. The package has no CommonJS build.
  • Effect ^4.0.0, as a peer dependency.

Install the package and Effect:

npm install @vazen/toml effect

The source is on GitHub (opens in a new tab). The examples on this page use @vazen/toml 0.4.0, Node.js 24 and schema 0.3.0 files.

Read a file

decodeVazenProjectFromTomlFile reads the text of a .vazen.toml file. It returns the project and its source.

Example (Count the units on the example shelf)

Save this as count-units.mjs beside the example shelf, then run node count-units.mjs.

import { readFileSync } from 'node:fs';
import {
  decodeVazenProjectFromTomlFile,
  VAZEN_SITE_DEFAULTS,
} from '@vazen/toml';

const { project } = decodeVazenProjectFromTomlFile(
  readFileSync('example-shelf.vazen.toml', 'utf8'),
);

let units = 0;
for (const fixture of project.fixtures ?? []) {
  for (const equipment of fixture.equipment ?? []) {
    for (const site of equipment.sites ?? []) {
      const { wide, high, deep } = {
        ...VAZEN_SITE_DEFAULTS.facings,
        ...site.facings,
      };
      units += wide * high * deep;
    }
  }
}
console.log(`${project.name}: ${units} units`);
// Output: Example shelf: 24 units

The project holds the tables of the file. A key that the file omits is absent, so site.facings can be undefined. VAZEN_SITE_DEFAULTS gives the value of an omitted facing count or orientation.

The source gives the file’s format and declared version, such as { declaredVersion: '0.3.0', format: 'vazen-toml' }. A reader also returns messages, a list of structured findings, beside project and source. A writer writes only the project.

Read a file with any TOML parser

Any TOML 1.0 parser reads the syntax of a Vazen TOML file. This example uses the parser in Python 3.11 or later. Save it as read_plan.py beside the file, then run python3 read_plan.py.

import tomllib

with open("example-shelf.vazen.toml", "rb") as source:
    plan = tomllib.load(source)

units = 0
for shelf in plan["fixtures"][0]["equipment"]:
    for site in shelf["sites"]:
        facings = site["facings"]
        units += (
            facings.get("wide", 1)
            * facings.get("high", 1)
            * facings.get("deep", 1)
        )
print(plan["name"])
print(f"{units} units")

The output is:

Example shelf
24 units

A general parser checks only the syntax. The package also checks the shape of each table. Validation says what it checks.

Write a file

encodeTomlFileFromVazenProject writes a project as the text of a .vazen.toml file.

Example (Write a spec with one site)

import { encodeTomlFileFromVazenProject } from '@vazen/toml';

const text = encodeTomlFileFromVazenProject({
  project: {
    schema: 'vazen/spec',
    schema_version: '0.3.0',
    name: 'Example shelf',
    products: [{ name: 'Oat cereal' }],
    fixtures: [
      {
        equipment: [
          {
            type: 'shelf',
            sites: [
              { product: { name: 'Oat cereal' }, facings: { wide: 3, deep: 4 } },
            ],
          },
        ],
      },
    ],
  },
});

The text is:

schema = "vazen/spec"
schema_version = "0.3.0"
name = "Example shelf"

[[products]]
name = "Oat cereal"

[[fixtures]]
[[fixtures.equipment]]
type = "shelf"

[[fixtures.equipment.sites]]
[fixtures.equipment.sites.product]
name = "Oat cereal"

[fixtures.equipment.sites.facings]
wide = 3
deep = 4

A project must have schema and schema_version. The writer writes schema 0.3.0, unless the version option names another version that VazenVersion lists. It refuses a project that a reader would refuse as a file.

JSON files

decodeVazenProjectFromJsonFile and encodeJsonFileFromVazenProject read and write the same tables as JSON, in a .vazen.json file. JSON suits a program or an API. TOML suits a file that people keep and edit. The specification gives the rules for dates, null, nan and inf.

Example (Write a date as JSON and read it back)

import {
  decodeVazenProjectFromJsonFile,
  decodeVazenProjectFromTomlFile,
  encodeJsonFileFromVazenProject,
} from '@vazen/toml';

const { project } = decodeVazenProjectFromTomlFile(`schema = "vazen/spec"
schema_version = "0.3.0"
reviewed = 2026-09-27
`);
const json = encodeJsonFileFromVazenProject({ project });
console.log(json);
/*
Output:
{
  "schema": "vazen/spec",
  "schema_version": "0.3.0",
  "reviewed": "2026-09-27"
}
*/

const read = decodeVazenProjectFromJsonFile(json);
console.log(read.project.reviewed instanceof Date);
// Output: true

The JSON reader also refuses an integer outside JavaScript’s safe range, as the TOML reader does.

PSA files

PSA files shows how to convert a ProSpace PSA file to JSON or Vazen TOML and write it back. It also says what a conversion keeps.

Effect schemas

The file functions throw a SchemaError. To get a Result or an Effect, use the Effect schemas behind them.

SchemaEncodedType
VazenProjectFromTomlTextstringVazenProject
VazenProjectFromJsonTextstringVazenProject
VazenProjectFromPsaTextstringVazenProject
VazenProjectFromPsaBytesUint8ArrayVazenProject
VazenProjectFromPsaDataPsaDataVazenProject
PsaDataFromPsaTextstringPsaData
PsaDataFromPsaBytesUint8ArrayPsaData

A VazenProject differs from the tables of a file:

  • An optional value is an Option.
  • Keys that the specification does not define are in the attributes of each object.
  • stage is 'spec' or 'layout'.
  • source is part of the project. So a PSA schema writes the version of the PSA file that the project came from, if that version can hold the project.

Example (Decode a file to a Result)

import { readFileSync } from 'node:fs';
import { Option, Result, Schema } from 'effect';
import { VazenProjectFromTomlText } from '@vazen/toml';

const result = Schema.decodeResult(VazenProjectFromTomlText)(
  readFileSync('example-shelf.vazen.toml', 'utf8'),
);
if (Result.isSuccess(result)) {
  const project = result.success;
  console.log(project.stage, Option.getOrElse(project.name, () => 'Untitled'));
} else {
  console.error(result.failure.message);
}
// Output: spec Example shelf

API overview

No function reads or writes the file system. Your code reads and writes the files.

FunctionInputOutput
decodeVazenProjectFromTomlFile.vazen.toml text{ project, source }
encodeTomlFileFromVazenProject{ project, version? }.vazen.toml text
decodeVazenProjectFromJsonFile.vazen.json text{ project, source }
encodeJsonFileFromVazenProject{ project, version? }.vazen.json text
decodeVazenProjectFromPsaFilePSA bytes{ project, source }
encodePsaFileFromVazenProject{ project, version? }PSA bytes
decodePsaDataFromPsaFilePSA bytesPsaData
encodePsaFileFromPsaData{ data, version? }PSA bytes

The package also exports:

  • VazenVersion and PsaVersion, the versions each writer accepts.
  • VAZEN_SITE_DEFAULTS and the PSA_*_DEFAULTS, the values of omitted keys and empty cells.
  • VazenTomlProjectV0_3_0, the tables of a 0.3.0 file, and the types of VazenProject, PsaData and their parts.

This release does not check whole-file or spatial rules, and does not upgrade a file to another schema version.

Errors

Each function throws a SchemaError when it cannot read or write. The message is a tree that ends at the problem. PSA reading makes a best effort and returns a project satisfying its schema, with recoverable issues in messages. Writers enforce the destination format’s requirements.

Example (Read a file of an unsupported version)

import { decodeVazenProjectFromTomlFile } from '@vazen/toml';

decodeVazenProjectFromTomlFile(`schema = "vazen/spec"
schema_version = "0.9.0"
`);
/*
throws:
SchemaError(Expected VazenVersion, got "0.9.0"
  at ["schema_version"])
*/

Validation

Reading checks the shape of each table: its keys, their types and their allowed values. For example, a product must have a name, and a gtin must have 8, 12, 13 or 14 digits.

Reading does not check rules that need the whole file, such as each product selector matching exactly one product. It does not check spatial rules, such as equipment containment or overlapping product placements. It does not repair a file.

We are developing optional spatial checks. They will be published with the schema they apply to, and use that schema’s version. Their result will be separate from base conformance.

Validation reports problems. A repair changes the plan, so it must be requested explicitly. The specification is the source for the requirements of each release.

Versions and compatibility

The schema version identifies the data contract. A package version identifies one implementation. They change independently, and npm and Python releases can support the same schema.

ArtifactStatusVersion
SpecificationPublished0.3.0
JavaScript / TypeScript (opens in a new tab)Published@vazen/toml 0.4.0
PythonPlannedIts own releases and schema support

@vazen/toml 0.4.0 supports:

CapabilitySupport
Read vazen/spec and vazen/layout0.3.0, as TOML or JSON
Write vazen/spec and vazen/layout0.3.0, as TOML or JSON. Default 0.3.0.
Read PSAAny version. Column counts are known for the versions the writer accepts. A row with another count is reported as UnlistedWidth.
Write PSA2017.1.0, 2017.2.0, 2019.1.0, 2019.1.1, 2020.1.0, 2020.1.1, 2021.1.2, 2023.1.0, 2024.1.0, 2024.4.0. Default 2024.4.0.
Check whole-file rulesNot supported
Check spatial rulesNot supported
Upgrade to another schema versionNot supported

Each package release states the schemas it reads and writes, and its default output. A reader for a version does not mean a writer or an upgrade path for it.

The schema_version in a file does not identify the npm package, the Python package or the TOML version. Older specifications keep their own versioned URLs.