# schema — JSON-Schema tooling pack

JSON-Schema tooling pack (Draft-07 subset, pure JS, zero deps). Infer a JSON Schema from sample data, validate any data value (object/array/scalar) against a schema returning {valid,errors}, generate...


A pure-JavaScript (zero npm deps, Node built-ins only) toolkit for authoring, analyzing, and
transforming **JSON Schema** (a Draft-07 subset). It infers schemas from data, validates data
against schemas, generates mock/example instances, emits TypeScript, and diffs/merges/coerces
schemas — everything you need to treat data shapes as first-class artifacts.

## Tools

| Tool | Args | Returns |
|---|---|---|
| `infer` | `{ data, options? }` | `{ schema }` — a JSON Schema inferred from sample `data`. |
| `validate` | `{ data, schema }` | `{ valid, errors, errorCount }` — validate one value against a schema. |
| `mock` | `{ schema, options?, seed? }` | `{ data }` — randomized data (deterministic per `seed`); `options.count` → array. |
| `example` | `{ schema, options? }` | `{ example }` — one canonical instance (prefers `default`/`examples`/`enum`). |
| `toTypeScript` | `{ schema \| data, options? }` | `{ typescript, rootType, interfaces }` — TS interface/type string. |
| `diff` | `{ from, to }` (or `schemaA`/`schemaB`) | `{ added, removed, changed, identical }`. |
| `merge` | `{ schemaA, schemaB }` | `{ schema }` — one schema accepting data valid under either. |
| `coerce` | `{ data, schema }` | `{ data, changes, changed, valid, errors }` — coerce scalar leaves to declared types. |

### Supported JSON-Schema keywords
`type` (incl. type arrays, integer vs number), `enum`, `const`; strings: `minLength`, `maxLength`,
`pattern`, `format` (`email`, `uri`, `url`, `uuid`, `date-time`, `date`, `time`, `ipv4`, `hostname`);
numbers: `minimum`, `maximum`, `exclusiveMinimum`, `exclusiveMaximum`, `multipleOf`; arrays:
`minItems`, `maxItems`, `uniqueItems`, `items` (schema **and** tuple); objects: `required`,
`properties`, `patternProperties`, `additionalProperties`, `minProperties`, `maxProperties`;
combinators: `allOf`, `anyOf`, `oneOf`, `not`. (`$ref` is not resolved — inline your schemas.)

## Usage

```js
import schema from './index.js';

// infer a schema from a sample record
const { schema: s } = schema.adapters.infer({ data: { id: 1, name: 'Ada', tags: ['x'] } });

// validate a value against it
schema.adapters.validate({ data: { id: 2, name: 'Grace', tags: [] }, schema: s });
// → { valid: true, errors: [], errorCount: 0 }

// deterministic mock + one example
schema.adapters.mock({ schema: s, seed: 7 });
schema.adapters.example({ schema: s });

// TypeScript interface from a schema (or straight from sample data)
schema.adapters.toTypeScript({ schema: s, options: { name: 'User' } }).typescript;

// diff / merge two schemas
schema.adapters.diff({ from: s, to: s2 });
schema.adapters.merge({ schemaA: s, schemaB: s2 });

// coerce loose strings to declared types
schema.adapters.coerce({ data: { id: '3', active: 'true' }, schema: s });
// → { data: { id: 3, active: true }, changes: [...], valid: true }
```

Every tool takes one args object (a POST body maps 1:1) and returns a plain JSON-serializable
object. Schemas and data may be passed as objects or JSON strings.

## DRY boundary (important)

This pack is **JSON-Schema tooling** — it operates on and with real JSON Schemas. It deliberately
does **not** overlap two neighbouring packs:

- **`domain/validation`** validates a **single scalar string** against a **format/checksum**
  (email, IBAN, UUID, credit card…). No schema involved. Use it for "is this one value a valid X".
- **`domain/filters` → `schemaValidate`** validates an **array of records** against a lightweight
  field-rule schema *inside a data pipeline* (bulk row filtering/annotation).

`schema.validate` here validates **one arbitrary value** (object/array/scalar) against a **full
JSON Schema**. Three different altitudes — keep them separate.


---
Source: shared/engines/adapters/domain/schema/README.md
Canonical: https://docs.leumas.tech/p/adapters/domain/schema
