# @suaveplan/form-builder - Universal dynamic form schema engine with conditional logic, async validation, dependency graph, undo/redo, Zod-schema generation, OTel instrumentation, and pluggable field-type registry. Universal dynamic form schema engine. Renderer-agnostic — no DOM, no React, no Node-specific globals. Drives every dynamic form surface in the Suaveplan. ## Documentation tree - [form-builder](./src/builder/form-builder/form-builder.md) — `form-builder.ts` exposes the top-level `FormBuilder` class — the public entry point for `@suaveplan/form-builder`. The… - [form-builder](./src/builder/form-builder/form-builder.md) — `form-builder.ts` exposes the top-level `FormBuilder` class — the public entry point for `@suaveplan/form-builder`. The… - [conditional](./src/conditional/conditional/conditional.md) — `conditional.ts` is the rule-evaluation engine for `FieldDefinition.conditional`. It supports nine leaf operators (`eq`… - [conditional](./src/conditional/conditional/conditional.md) — `conditional.ts` is the rule-evaluation engine for `FieldDefinition.conditional`. It supports nine leaf operators (`eq`… - [dependency-graph](./src/conditional/dependency-graph/dependency-graph.md) — `dependency-graph.ts` builds a directed acyclic graph of field-id dependencies derived from `FieldDefinition.conditiona… - [dependency-graph](./src/conditional/dependency-graph/dependency-graph.md) — `dependency-graph.ts` builds a directed acyclic graph of field-id dependencies derived from `FieldDefinition.conditiona… - [form-error](./src/errors/form-error/form-error.md) — `form-error.ts` owns the stable error-code registry and the typed `FormError` class for the entire `@suaveplan/form-bui… - [form-error](./src/errors/form-error/form-error.md) — `form-error.ts` owns the stable error-code registry and the typed `FormError` class for the entire `@suaveplan/form-bui… - [field-registry](./src/fields/field-registry/field-registry.md) — `field-registry.ts` is the extensible registry of field-type descriptors used by `FormBuilder`. It ships seventeen buil… - [field-registry](./src/fields/field-registry/field-registry.md) — `field-registry.ts` is the extensible registry of field-type descriptors used by `FormBuilder`. It ships seventeen buil… - [instruments](./src/otel/instruments/instruments.md) — `instruments.ts` lazily resolves the OpenTelemetry meter and the five instruments emitted across the package: three cou… - [instruments](./src/otel/instruments/instruments.md) — `instruments.ts` lazily resolves the OpenTelemetry meter and the five instruments emitted across the package: three cou… - [schema](./src/schema/schema/schema.md) — `schema.ts` is the Zod boundary for the public `FormSchema`, `FieldDefinition`, and `FormSection` types. It exposes par… - [schema](./src/schema/schema/schema.md) — `schema.ts` is the Zod boundary for the public `FormSchema`, `FieldDefinition`, and `FormSection` types. It exposes par… - [serialise](./src/serialise/serialise/serialise.md) — `serialise.ts` provides versioned JSON round-trip for `FormSchema`. It is the bridge between the in-memory schema engin… - [serialise](./src/serialise/serialise/serialise.md) — `serialise.ts` provides versioned JSON round-trip for `FormSchema`. It is the bridge between the in-memory schema engin… - [form-state](./src/state/form-state/form-state.md) — `form-state.ts` is the mutable holder for the runtime state of a form instance: the current value map, the most recent… - [form-state](./src/state/form-state/form-state.md) — `form-state.ts` is the mutable holder for the runtime state of a form instance: the current value map, the most recent… - [undo-redo](./src/state/undo-redo/undo-redo.md) — `undo-redo.ts` is a bounded LIFO of reverse-ops with redo support. It is the substrate for `FormBuilder.enableHistory`… - [undo-redo](./src/state/undo-redo/undo-redo.md) — `undo-redo.ts` is a bounded LIFO of reverse-ops with redo support. It is the substrate for `FormBuilder.enableHistory`… - [submission](./src/submission/submission/submission.md) — `submission.ts` is the orchestration layer that runs the canonical `prepare → validate → transform → submit` pipeline f… - [submission](./src/submission/submission/submission.md) — `submission.ts` is the orchestration layer that runs the canonical `prepare → validate → transform → submit` pipeline f… - [validation](./src/validation/validation/validation.md) — `validation.ts` is the iteration layer that runs every rule attached to a field or form and aggregates the resulting `V… - [validation](./src/validation/validation/validation.md) — `validation.ts` is the iteration layer that runs every rule attached to a field or form and aggregates the resulting `V… - [validators](./src/validation/validators/validators.md) — `validators.ts` provides the eleven built-in rule runners used by the validation engine. Each runner takes the candidat… - [validators](./src/validation/validators/validators.md) — `validators.ts` provides the eleven built-in rule runners used by the validation engine. Each runner takes the candidat… - [zod-schema](./src/zod-schema/zod-schema/zod-schema.md) — `zod-schema.ts` exposes `toZodSchema(form)` — a function that compiles a `FormSchema` into a `z.ZodObject` whose `safeP… - [zod-schema](./src/zod-schema/zod-schema/zod-schema.md) — `zod-schema.ts` exposes `toZodSchema(form)` — a function that compiles a `FormSchema` into a `z.ZodObject` whose `safeP… ## Features - 17 built-in field types (`text`, `number`, `email`, `url`, `tel`, `password`, `select`, `multiselect`, `checkbox`, `radio`, `textarea`, `date`, `file`, `range`, `hidden`, `group`, `array`) via an extensible `FieldRegistry`. - 11 built-in validation rules (`required`, `minLength`, `maxLength`, `min`, `max`, `pattern`, `email`, `url`, `oneOf`, `equalsField`, `custom`). Async-friendly via `Promise` predicates. - Conditional logic with 9 leaf operators (`eq`, `neq`, `in`, `notIn`, `gt`, `lt`, `gte`, `lte`, `contains`) and boolean composition (`and` / `or` / `not`). - Field-level dependency graph with topological evaluation and cycle detection (`FORM_BUILDER.CYCLIC_DEPENDENCY`). - Bounded undo / redo on schema mutations. - Typed event bus via `EventBus` from `@suaveplan/events`. - Versioned JSON serialise / deserialise round-trip. - `toZodSchema(form)` generator for `react-hook-form` consumers. - Submission pipeline: `prepare → validate → transform → submit`. - Six stable `FORM_BUILDER.*` error codes via `defineCodes`. - Three OTel counters and two histograms emitted on every code path. - Injectable `Clock` + `IdGenerator` for deterministic tests. ## Install ```bash bun add @suaveplan/form-builder ``` ## Usage ```ts import { FormBuilder } from "@suaveplan/form-builder"; const builder = new FormBuilder().enableHistory(); builder.addField({ id: "name", name: "name", label: "Name", type: "text", validations: [{ type: "required" }], }); builder.addField({ id: "subscribe", name: "subscribe", label: "Subscribe to newsletter", type: "checkbox", }); builder.addField({ id: "frequency", name: "frequency", label: "Frequency", type: "select", options: [ { label: "Weekly", value: "weekly" }, { label: "Monthly", value: "monthly" }, ], conditional: { field: "subscribe", operator: "eq", value: true }, }); builder.bus.on("values.changed", (values) => console.log("changed", values) ); const schema = builder.createSchema("signup", "Sign-up form"); ``` ## Submission ```ts import { submit } from "@suaveplan/form-builder"; await submit({ fields: schema.fields, values: { name: "alice", subscribe: true, frequency: "weekly" }, submitter: async (values, signal) => fetch("/api/forms", { method: "POST", signal, body: JSON.stringify(values), }), }); ``` ## License MIT.