repzo-thermal-print
v0.1.0
Published
Shared contract, catalogue, labels and render rules for Repzo thermal (3-inch / 4-inch) print templates — one implementation for the dashboard, the backend and the React Native app.
Readme
repzo-thermal-print
The single implementation of Repzo's thermal (3-inch / 4-inch) print templates, shared by the dashboard, the backend and the React Native app.
A thermal template is stored in pdf-template.settings. Before this package, its
shape, its catalogue of sections and fields, its default labels and its rendering
rules lived in the dashboard alone, and every other reader had to re-implement
them from prose. This package is now the source of truth for all of them:
| Concern | Exports |
| --- | --- |
| Contract — what may be stored, what must be accepted | WRITE, READ, validateWrite, normalizeForWrite, parseForPrint, checkInvariants |
| Selection — which template prints a document | resolvePrintTemplate, systemDefaultConfig, pickStandardTemplate, customTemplatesFor |
| Rendering — the receipt as data | buildRenderModel, createLabelResolver, tokens (FONT_ROLE_SIZE, DENSITY_SPACING, …) |
| Authoring — the editor's building blocks | getSectionBlueprint, createThermalConfig, normalizeSections, the set* / move* mutators, validateThermalTemplate, toEditorIssues |
| Legacy — what tenants print today | buildSeededConfig, buildSystemDefault |
| Rows — pdf-template documents | templateKindOf, toThermalTemplate, rowFieldsFor, receipt helpers |
Generated, versioned artifacts ship in generated/ (import them as
repzo-thermal-print/schemas/<file>):
settings.write.v1.schema.json/settings.read.v1.schema.json— JSON Schema 2020-12settings.write.v1.openapi30.json/settings.read.v1.openapi30.json— the same, as OpenAPI 3.0 schema objectscatalogue.v1.json— sections and fields per document type with their defaultslabels.v1.json— default labels in English and Arabic
Install
npm install repzo-thermal-printZod 4 is its only dependency. The build targets ES2020 (Node 18+, Hermes).
Use it
Backend — validate a write (see docs/backend-integration.md):
import { normalizeForWrite, validateWrite } from 'repzo-thermal-print';
const settings = normalizeForWrite(body.settings);
const { ok, issues } = validateWrite(settings, { requirePrintable: settings.isDefault && !body.disabled });
if (!ok) throw new BadRequest('Invalid print template settings', { errors: issues });Mobile — print a document (see docs/mobile-integration.md):
import { buildRenderModel, createLabelResolver, resolvePrintTemplate, systemDefaultConfig } from 'repzo-thermal-print';
const job = { documentType: 'invoice', language: 'ar' } as const;
const picked = resolvePrintTemplate(rows, job);
if (picked.source === 'receipt_html') return printHtml(picked.row);
const config = picked.source === 'thermal' ? picked.config : systemDefaultConfig(job, legacy);
const model = buildRenderModel({
config,
paperSize: printer.paperSize,
doc,
org,
label: createLabelResolver(config.language, config.documentType),
formatMoney,
formatDate
});
draw(model); // the only platform-specific stepDashboard — preview and save: the editor builds configurations with
createThermalConfig and the mutators, previews with buildRenderModel, and
runs validateThermalTemplate — which includes validateWrite — before saving
(see docs/dashboard-migration.md).
The contract in one paragraph
Producers write the strict contract (WRITE): closed objects and enums, only the
fields a section of a document type has, bounded strings, unique keys and orders
1..n. Consumers read the tolerant contract (READ, implemented by
parseForPrint): they ignore unknown properties, sections and fields, fall back
to the default for an unknown enum value, and skip a row whose schema_version
major they do not know. That is what lets the dashboard ship a new option before
every phone has updated. The full rules are in docs/contract.md.
Develop
npm test # vitest: ported dashboard tests, contract, resolution, property and golden tests
npm run typecheck
npm run generate # rewrite generated/ after changing the contract, catalogue or labels
npm run generate:check # fail if generated/ is stale (CI)
npm run fixtures:update # accept a reviewed change to the golden render models
npm run build # dist/ (ESM + CJS + types)
npm run verify # all of the above; runs before publishfixtures/render/*.json are golden render models: { input, model } pairs that
any renderer can replay. A diff there is a change to customers' receipts — review
it before running fixtures:update.
Versioning
- The npm version follows semver for the API.
schema_versionin stored settings is the contract's major. Adding an optional property, an enum value, a section or a field is additive and stays at1: older readers ignore or default it. Renaming, removing or changing the meaning of anything is a new major, and producers keep writing1until no supported app build is left that cannot read the new one.
Origin
The authoring, rendering, legacy-seeding and library modules were moved here from the Repzo dashboard's thermal template module, with their tests. The contract, the tolerant reader, print-time resolution, the label data and the generated artifacts are new.
License
Proprietary — Copyright (c) 2026 Repzo, Inc. All rights reserved. See
LICENSE. The package is on a public registry only so Repzo's
applications can install it; downloading or installing it grants no rights to it.
