# @polotno/schema

TypeScript types, default values, validation, and a JSON Schema for the **Polotno
design JSON** format — the document shape used across
[Polotno](https://polotno.com) and its import/export packages.

Use it to **validate** and **normalize** design JSON anywhere, without running the
editor.

```bash
npm install @polotno/schema
```

## What it's for

- **Validate** a design — before saving it, or when accepting it over the wire.
- **Fill in defaults** so partial JSON becomes a complete, canonical document.
- **Check converter output.** The import packages emit design JSON with defaults
  omitted; this validates and completes it. See
  [`@polotno/pdf-import`](https://www.npmjs.com/package/@polotno/pdf-import),
  [`@polotno/svg-import`](https://www.npmjs.com/package/@polotno/svg-import),
  [`@polotno/psd-import`](https://www.npmjs.com/package/@polotno/psd-import).

## Validate

```ts
import { validateDesign, assertValidDesign } from '@polotno/schema';

validateDesign(json, { mode: 'partial' }); // lenient — defaults may be missing
validateDesign(json, { mode: 'canonical' }); // strict — rejects unknown keys
// → { valid: boolean, errors: { path: string, message: string }[] }

assertValidDesign(json); // throws on invalid
```

The exported `designSchemaLenient` / `designSchemaCanonical` implement the
[Standard Schema](https://standardschema.dev) interface, so they interoperate with
zod, Effect Schema, Valibot, and other Standard-Schema tools.

## Normalize (fill defaults)

```ts
import { normalizeDesign } from '@polotno/schema';

const complete = normalizeDesign(partial);
// every default filled in, unknown keys stripped
```

Idempotent and exact for current-format input. It migrates older
`schemaVersion` documents up first (see below), and it leaves render-derived
values (e.g. text auto-height) for the editor to compute.

## Schema versions

Every design carries a `schemaVersion`. `normalizeDesign` / `parseDesign` migrate
an older document up to the current version before validating, so a consumer
never has to handle an old shape. A **missing** `schemaVersion` means 0 — the
oldest format, not the newest.

| Version | What changed                                                                                                            |
| ------- | ----------------------------------------------------------------------------------------------------------------------- |
| 1       | `letterSpacing` is a ratio of the element's own `fontSize`, no longer of a 16px root.                                   |
| 2       | Filter `intensity` moved from `-100..100` to `-1..1`.                                                                   |
| 3       | Text backgrounds render as per-line polygons; pre-v3 rich text is stamped `legacyBackground` to keep the old full rect. |
| 4       | Video time anchoring changed. Marker only — no document transform.                                                      |

Steps 1 and 3 apply only to the modern text renderers, which every converter
uses.

## JSON Schema

A language-neutral JSON Schema (draft 2020-12) ships at
`@polotno/schema/design.schema.json` — validate from any language or tooling.

```ts
import schema from '@polotno/schema/design.schema.json' with { type: 'json' };
```

## Types

```ts
import type { Design, Page, Element, TextElement } from '@polotno/schema';
```

## Related

- [Polotno](https://polotno.com) — the design editor SDK these documents come from.
- Import/export packages that produce or consume this JSON:
  [pdf-import](https://www.npmjs.com/package/@polotno/pdf-import),
  [svg-import](https://www.npmjs.com/package/@polotno/svg-import),
  [psd-import](https://www.npmjs.com/package/@polotno/psd-import),
  [pdf-export](https://www.npmjs.com/package/@polotno/pdf-export).

## License

See [LICENSE.md](./LICENSE.md).
