@rendara/report-schema
v1.0.0
Published
Framework-agnostic Template JSON types, JSON Schema, validator, and migrations for Rendara Reports.
Readme
report-schema
@rendara/report-schema — the framework-agnostic Template JSON contract for
Rendara Reports: TypeScript types, JSON Schema, ajv validator, and migrations.
Depends on nothing internal (brief §4). No Angular — usable in any Node
backend or template-tooling script.
Status
Built incrementally across Epic 1:
- E1-S1 ✅ Core document & element-base types —
RendaraTemplate,Page(structural), band containers (header/body/footer),ElementBase, and the stubbedTemplateElementdiscriminated union (text/shape/image/dataTable). PlusSCHEMA_VERSION(E0-S2). - E1-S2 ✅ Page & document settings — defaults, named-size → mm resolution,
resolvePage, and focusedvalidatePageSettings. - E1-S3 ✅ Per-type element models — concrete
TextElement,ShapeElement(line/rect/ellipse),ImageElement(src/binding,fit),DataTableElement(source.arrayExpr, columns with header/cell/footer, optional groups,repeatHeaderOnEachPage,keepTogether); anElementBindingslot (completed in E1-S5); type guards, anassertNeverexhaustiveness guard, and a focusedvalidateElement. - E1-S4 ✅ Style model — concrete
ElementStyle:font(family/sizePt/weight/style),color,fill, per-sideborder(widthMm/style/color),align(horizontal/vertical),padding,stroke, and a number/dateformattoken slot. Runtime literal mirrors (FONT_WEIGHTS/FONT_STYLES/LINE_STYLES/HORIZONTAL_ALIGNS/VERTICAL_ALIGNS) and a focusedvalidateStyle(folded intovalidateElement). - E1-S5 ✅ Binding model — structured
ElementBinding(expr+ optionalformattoken +fallback), reused at every binding location (elementbinding, columncell/footer); grouping with header/footerGroupBands carrying alabeland per-columnGroupAggregatesubtotals;visibleWhenboolean expression. A focusedvalidateBinding(folded intovalidateElement, with a column-key referential check on group aggregates). - E1-S6 ✅ JSON Schema + validator API — a generated
TEMPLATE_JSON_SCHEMA(the machine-readable mirror of the E1-S1…S5 types, also emitted toschema/rendara-template.schema.json), an ajv-backedvalidate(template): Result<RendaraTemplate, RendaraValidationError[]>with human-readable, path-pointed errors, andparse(stringOrObject). Validation is layered: ajv handles structure (shape/required/enums/ranges, the element discriminated union via thediscriminatorkeyword), and the focused semantic validators (validatePageSettings,validateElement) fold in the cross-field/referential rules JSON Schema can't express. - E1-S7 ✅ Versioning & migrations — a
migrate(template)runner that chains registered version→version migrations up toCURRENT_SCHEMA_VERSION(with an identity migration for the current version), handling missing/unknown versions gracefully. - E1-S8 ✅ Canonical golden fixtures — three reference templates, each paired
with sample data (
GOLDEN_FIXTURES):invoice(text + table + total),certificate(absolute layout + image + shapes), andtabular-report(large grouped table with subtotals + grand total). Reused as the basis for tests across the monorepo. See Golden fixtures below.
import { parse, validate, type RendaraTemplate } from '@rendara/report-schema';
const result = validate(templateJson); // or parse(jsonStringOrObject)
if (result.ok) {
const template: RendaraTemplate = result.value;
} else {
for (const { path, message } of result.errors) {
console.error(`${path}: ${message}`);
}
}Packaging (E9-S3)
The package is built framework-agnostic — no Angular (tools/bundle-schema.mjs,
not ng-packagr; see ADR 0015).
It ships dual ESM + CommonJS, so it works in either Node module system:
import { validate } from '@rendara/report-schema'; // ESM
const { validate } = require('@rendara/report-schema'); // CommonJSThe raw JSON Schema is shipped as a file and exposed as a subpath, for backends that consume it directly (e.g. with ajv):
import schema from '@rendara/report-schema/schema.json' with { type: 'json' };Build, then verify the package is Angular-free and consumable in Node (the QA
gate imports + validates a golden via both import and require):
npx nx build report-schema # -> dist/libs/report-schema (ESM + CJS + types + schema.json)
npx nx run report-schema:pack # verify-schema-pack + verify-schema-nodeSchema artifact
schema/rendara-template.schema.json is generated from TEMPLATE_JSON_SCHEMA.
Re-run after any schema change (a test fails if it drifts):
pnpm schema:generate # or: npx nx run report-schema:generate-schemaGolden fixtures
src/lib/fixtures.ts is the single source of truth for the canonical golden
templates + sample data (GOLDEN_FIXTURES, plus the individual
golden*Template / golden*Data exports). They are committed as JSON under
fixtures/<name>/{template.json,data.json} for use as raw test inputs. Re-run
after any fixture change (a test fails if the committed JSON drifts):
pnpm fixtures:generate # or: npx nx run report-schema:generate-fixturesTest
npx nx test report-schemaVersioning & migration policy (E10-S7)
The package follows semver (release notes: CHANGELOG.md);
the Template JSON contract is versioned separately by schemaVersion /
SCHEMA_VERSION. What counts as a contract change, how schemaVersion bumps
map to semver, and what every migration must guarantee is defined in the
schema versioning & migration policy.
Consumer upgrade guidance: integration & upgrade guide.
