@petrarca/sonnet-core 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,353 +1,8 @@
1
+ import { J as JsonSchemaProperty, a as JsonSchema, U as UIRule, A as AdditionalBinding, C as ConceptCoding, b as CodeableConcept, F as FormDiff } from '../types-HhzIKd1R.js';
2
+ export { c as ArrayItemChange, B as Binding, d as BindingStrength, e as CODEABLE_CONCEPT_TYPE, f as CODEABLE_CONCEPT_TYPE_ID, g as CODING_TYPE, h as CODING_TYPE_ID, i as CORE_TYPES_BASE, j as CORE_VALUE_TYPES, k as Coding, l as CodingMatch, m as FieldDiff, Q as QUANTITY_TYPE, n as QUANTITY_TYPE_ID, o as Quantity, p as QuantityComparator, R as RefResolver, q as UCUM_SYSTEM, r as UILayoutConfig, s as UILayoutGroupConfig, t as UILayoutRowConfig, u as UIRuleCondition, v as UIRuleEffect, w as UISchema, x as UISchemaOptions, y as UIValidate, z as UIValidateRef, V as ValueChange, D as ValueType, W as WIDTH_TOKEN_REMS, E as WidthToken, G as bindingLists, H as bindingOf, I as codeToken, K as codingKey, L as coreType, M as coreTypeOf, N as parseCodeToken, O as resolveRefs, P as valueTypeResolver } from '../types-HhzIKd1R.js';
1
3
  import Ajv from 'ajv';
2
4
  import { z } from 'zod';
3
5
 
4
- /**
5
- * Generic JSON Schema type definitions.
6
- *
7
- * These types follow Draft 2020-12 and include x-ui-* extension points
8
- * for form/widget integration. They are domain-agnostic -- no
9
- * application-specific entity concepts live here.
10
- */
11
- /**
12
- * A declarative presentation rule (JSONForms-style) attached to a field.
13
- *
14
- * The rule lives on the field it controls (the target). Its `condition` points
15
- * at another field's value via a JSON Pointer (RFC 6901) into the form DATA
16
- * (rooted at the whole form), and validates that value against `condition.schema`.
17
- * When the condition holds, `effect` is applied to the target:
18
- * - "show" -- render only when the condition holds
19
- * - "hide" -- render only when the condition does NOT hold
20
- * - "enable" -- interactive only when the condition holds
21
- * - "disable"-- non-interactive when the condition holds
22
- *
23
- * Example: show `pregnancy_status` when `gender` equals "female":
24
- * ```json
25
- * { "effect": "show",
26
- * "condition": { "scope": "/gender", "schema": { "const": "female" } } }
27
- * ```
28
- * Unlike if/then/else, the target field stays declared at its own position, so
29
- * layout placement is stable.
30
- */
31
- interface UIRuleCondition {
32
- /** JSON Pointer (RFC 6901) into the form data, e.g. "/gender" or "/patient/gender". */
33
- scope: string;
34
- /** Schema the value at `scope` is validated against (e.g. { const: "female" }). */
35
- schema: JsonSchemaProperty;
36
- }
37
- type UIRuleEffect = "show" | "hide" | "enable" | "disable";
38
- interface UIRule {
39
- effect: UIRuleEffect;
40
- condition: UIRuleCondition;
41
- }
42
- /**
43
- * JSON Schema property definition following Draft 2020-12 specification.
44
- * Supports basic types, validation constraints, conditionals, and custom extensions.
45
- */
46
- type JsonSchemaProperty = {
47
- type?: "string" | "number" | "integer" | "boolean" | "array" | "object" | "null";
48
- title?: string;
49
- description?: string;
50
- default?: any;
51
- const?: any;
52
- enum?: any[];
53
- pattern?: string;
54
- format?: string;
55
- minLength?: number;
56
- maxLength?: number;
57
- minimum?: number;
58
- maximum?: number;
59
- exclusiveMinimum?: number;
60
- exclusiveMaximum?: number;
61
- items?: JsonSchemaProperty;
62
- minItems?: number;
63
- maxItems?: number;
64
- properties?: Record<string, JsonSchemaProperty>;
65
- required?: string[];
66
- $ref?: string;
67
- $defs?: Record<string, JsonSchemaProperty>;
68
- definitions?: Record<string, JsonSchemaProperty>;
69
- allOf?: JsonSchemaProperty[];
70
- anyOf?: JsonSchemaProperty[];
71
- oneOf?: JsonSchemaProperty[];
72
- not?: JsonSchemaProperty;
73
- /**
74
- * Discriminator for a `oneOf` union (OpenAPI convention). `propertyName` is
75
- * the shared property whose `const` value tags the active branch. When
76
- * absent, the discriminator is auto-detected as the property that is const
77
- * in every branch.
78
- */
79
- discriminator?: {
80
- propertyName: string;
81
- };
82
- if?: JsonSchemaProperty;
83
- then?: JsonSchemaProperty;
84
- else?: JsonSchemaProperty;
85
- "x-ui-order"?: string[];
86
- "x-ui-rule"?: UIRule;
87
- "x-ui-widget"?: string;
88
- "x-ui-options"?: Record<string, any>;
89
- "x-ui-layout"?: UILayoutConfig;
90
- "x-ui-title"?: string;
91
- "x-ui-placeholder"?: string;
92
- "x-ui-description"?: string;
93
- "x-ui-column"?: {
94
- /**
95
- * Display order (ascending). Properties without an order are appended
96
- * after the ordered ones, keeping their schema declaration order.
97
- */
98
- order?: number;
99
- /** Exclude this column from the table entirely. */
100
- hidden?: boolean;
101
- /** Fixed column width in pixels. */
102
- width?: number;
103
- /** Minimum column width in pixels. */
104
- minWidth?: number;
105
- };
106
- /** Cell renderer name. Inferred from type+format when absent. */
107
- "x-ui-cell"?: string;
108
- /** Cell renderer configuration options (colors, href template, etc.). */
109
- "x-ui-cell-options"?: Record<string, unknown>;
110
- };
111
- /**
112
- * JSON Schema following Draft 2020-12 specification.
113
- *
114
- * This is the generic base type. Domain-specific consumers extend it
115
- * with their own x-* extension keys via intersection types in their
116
- * own type files.
117
- */
118
- type JsonSchema = {
119
- $schema?: string;
120
- title: string;
121
- type: "object";
122
- properties: Record<string, JsonSchemaProperty>;
123
- required?: string[];
124
- allOf?: JsonSchemaProperty[];
125
- anyOf?: JsonSchemaProperty[];
126
- oneOf?: JsonSchemaProperty[];
127
- not?: JsonSchemaProperty;
128
- if?: JsonSchemaProperty;
129
- then?: JsonSchemaProperty;
130
- else?: JsonSchemaProperty;
131
- $defs?: Record<string, JsonSchemaProperty>;
132
- definitions?: Record<string, JsonSchemaProperty>;
133
- "x-ui-order"?: string[];
134
- [key: `x-${string}`]: unknown;
135
- };
136
- /**
137
- * WidthToken -- the shared semantic sizing vocabulary used across the form
138
- * layout system: per-field slot width (x-ui-width) and per-column width
139
- * (UILayoutRowConfig.widths). "full" fills available space; sm/md/lg are
140
- * fixed inline sizes. Raw CSS remains available as an advanced escape hatch.
141
- */
142
- type WidthToken = "sm" | "md" | "lg" | "full";
143
- /**
144
- * The fixed rem values for each non-full WidthToken. This is the single source
145
- * of truth for token sizing used by:
146
- * - the CSS grid track map in JsonSchemaFormRenderer (sm -> "8rem" track)
147
- * - the Tailwind class map in FormFieldRenderer (sm -> w-32 = 8rem)
148
- * Consumers that need px can multiply by 16.
149
- */
150
- declare const WIDTH_TOKEN_REMS: Record<WidthToken, string>;
151
- /**
152
- * UISchema - User Interface Schema configuration.
153
- *
154
- * Defines how form fields should be rendered and behave in the UI.
155
- * Separate from JSON Schema (which defines data structure) and focuses
156
- * on presentation, widgets, and user interaction.
157
- */
158
- interface UISchema {
159
- /** Widget name (string) or direct component reference */
160
- "x-ui-widget"?: string | object;
161
- "x-ui-options"?: UISchemaOptions;
162
- "x-ui-globalOptions"?: UISchemaOptions;
163
- "x-ui-order"?: string[];
164
- /** Declarative show/hide or enable/disable rule (see UIRule). */
165
- "x-ui-rule"?: UIRule;
166
- "x-ui-title"?: string | false;
167
- "x-ui-description"?: string;
168
- "x-ui-placeholder"?: string;
169
- /** Semantic field-slot width (default "full"). */
170
- "x-ui-width"?: WidthToken;
171
- /** Column override -- merged over schema-level x-ui-column, UI schema wins. */
172
- "x-ui-column"?: JsonSchemaProperty["x-ui-column"] & {
173
- label?: string;
174
- };
175
- /** Cell renderer override. */
176
- "x-ui-cell"?: string;
177
- /** Cell renderer options override -- shallow-merged over schema-level x-ui-cell-options. */
178
- "x-ui-cell-options"?: Record<string, unknown>;
179
- /** Per-field UISchema for nested sub-forms (ObjectWidget / ArrayWidget) */
180
- "x-ui-fields"?: {
181
- [fieldName: string]: UISchema;
182
- };
183
- /** Layout config forwarded to the active template (ObjectWidget / ArrayWidget) */
184
- "x-ui-layout"?: UILayoutConfig;
185
- /** Extension keys not yet enumerated above */
186
- [key: `x-ui-${string}`]: unknown;
187
- }
188
- /**
189
- * UILayoutRowConfig -- one horizontal row in a multi-column object form layout.
190
- *
191
- * `fields` lists the field names to place in this row, left to right.
192
- * Column sizing (grid mode) is resolved in this precedence:
193
- * 1. `columns` -- raw CSS grid-template-columns (advanced escape hatch).
194
- * 2. `widths` -- per-cell semantic tokens (the designer-friendly path).
195
- * 3. default -- equal 1fr per field.
196
- * `gap` overrides the parent layout gap for this row only.
197
- *
198
- * `group` renders the row inside a titled fieldset (presentation-only grouping
199
- * over flat schema fields -- the data shape is unchanged).
200
- *
201
- * Examples:
202
- * { fields: ["first_name", "last_name"], widths: ["md", "full"] }
203
- * { fields: ["npi", "specialty", "email"], columns: "20% 1fr 1fr" }
204
- * { group: "Contact", fields: ["email", "phone"] }
205
- */
206
- interface UILayoutRowConfig {
207
- fields: string[];
208
- columns?: string;
209
- /**
210
- * Per-cell semantic widths, aligned to `fields` by index. Translated to grid
211
- * tracks: sm/md/lg -> fixed rem tracks, full -> 1fr. Ignored when `columns`
212
- * is set (raw CSS wins) or in "flow" mode. Missing/short entries default to
213
- * "full".
214
- */
215
- widths?: WidthToken[];
216
- gap?: number;
217
- /**
218
- * Optional title. When set, the row renders inside a <fieldset> with a
219
- * <legend>, grouping its fields visually without nesting them in the schema.
220
- */
221
- group?: string;
222
- /**
223
- * How this row arranges its fields:
224
- * - "grid" (default): CSS grid using `columns`/`widths` (equal 1fr per field
225
- * when neither is set).
226
- * - "flow": flex row, fields at their natural width, left-to-right, wrapping.
227
- * Use for compact toolbars / tight field groups. `columns`/`widths` are
228
- * ignored.
229
- */
230
- arrange?: "grid" | "flow";
231
- }
232
- /**
233
- * One named group of a grouped form layout. A group holds rows of fields under
234
- * a label; the data stays flat (grouping is presentation only, like `group` on
235
- * a single row). How groups are shown -- tabs, wizard steps, stacked sections
236
- * -- is chosen by {@link UILayoutConfig.variant}, not by this structure.
237
- *
238
- * A group may carry an `x-ui-rule`-style {@link UIRule} to appear conditionally
239
- * (e.g. show an "Address" group only when "provide address" is checked). The
240
- * rule is evaluated against the form data exactly as a field-level rule is.
241
- */
242
- interface UILayoutGroupConfig {
243
- /** Label shown on the group's trigger or heading. */
244
- label: string;
245
- /** Rows of fields in this group (same shape as UILayoutConfig.rows). */
246
- rows: UILayoutRowConfig[];
247
- /**
248
- * Optional show/hide rule for the whole group: a hidden group disappears
249
- * along with its fields. Narrowed to the visibility effects -- a disabled
250
- * group has no meaning, and permitting the effect would let it be authored
251
- * and then silently ignored.
252
- */
253
- rule?: UIRule & {
254
- effect: "show" | "hide";
255
- };
256
- }
257
- /**
258
- * UILayoutConfig -- layout configuration for ObjectWidget and ArrayWidget.
259
- *
260
- * Configures the built-in default templates. Has no effect when a custom
261
- * template is registered for the field.
262
- */
263
- interface UILayoutConfig {
264
- direction?: "vertical" | "horizontal";
265
- rows?: UILayoutRowConfig[];
266
- groups?: UILayoutGroupConfig[];
267
- variant?: "tabs" | "stepper" | "sections" | (string & {});
268
- columns?: string;
269
- gap?: number;
270
- labels?: boolean;
271
- compact?: boolean;
272
- labelPlacement?: "top" | "start";
273
- }
274
- /**
275
- * ValueChange -- a single scalar or nested-object field that changed value.
276
- *
277
- * `path` is a dot-separated field path: "name", "address.city".
278
- */
279
- type ValueChange = {
280
- type: "value";
281
- path: string;
282
- from: unknown;
283
- to: unknown;
284
- };
285
- /**
286
- * ArrayItemChange -- one item-level change within an array field.
287
- *
288
- * Items are identified by their form-internal `_fid` (never the server ID).
289
- * A single item can appear as both "moved" and "modified" if it was
290
- * repositioned and its values also changed -- these are emitted as two
291
- * separate entries with the same `fid`.
292
- */
293
- type ArrayItemChange = {
294
- type: "added";
295
- fid: string;
296
- index: number;
297
- item: unknown;
298
- } | {
299
- type: "removed";
300
- fid: string;
301
- index: number;
302
- item: unknown;
303
- } | {
304
- type: "moved";
305
- fid: string;
306
- from: number;
307
- to: number;
308
- } | {
309
- type: "modified";
310
- fid: string;
311
- index: number;
312
- changes: ValueChange[];
313
- };
314
- /**
315
- * FieldDiff -- the diff for one top-level form field.
316
- */
317
- type FieldDiff = ValueChange | {
318
- type: "array";
319
- field: string;
320
- changes: ArrayItemChange[];
321
- };
322
- /**
323
- * FormDiff -- structured diff produced by diffFormData().
324
- *
325
- * One entry per changed top-level field. Fields whose value is deeply
326
- * equal between original and updated are omitted.
327
- */
328
- type FormDiff = FieldDiff[];
329
- /**
330
- * UISchemaOptions - Widget configuration options.
331
- */
332
- interface UISchemaOptions {
333
- label?: string | false;
334
- disabled?: boolean;
335
- readonly?: boolean;
336
- compact?: boolean;
337
- enumNames?: Record<string | number, string>;
338
- inputType?: string;
339
- rows?: number;
340
- searchable?: boolean;
341
- clearable?: boolean;
342
- /** Allow the user to type and submit a value not in the enum list (combobox / open-choice). */
343
- creatable?: boolean;
344
- /** Label placement: "top" (default, above) or "start" (inline, RTL-safe). */
345
- labelPlacement?: "top" | "start";
346
- /** Semantic field-slot width (default "full"). */
347
- width?: WidthToken;
348
- [key: string]: any;
349
- }
350
-
351
6
  /**
352
7
  * Schema Service - Pure functions for JSON Schema manipulation.
353
8
  *
@@ -376,11 +31,28 @@ declare function getFieldType(property: JsonSchemaProperty): JsonSchemaType;
376
31
  * Used for tri-state checkbox rendering.
377
32
  */
378
33
  declare function isNullableBoolean(property: JsonSchemaProperty): boolean;
34
+ /**
35
+ * Lift the non-null member of a nullable `anyOf` onto the property.
36
+ *
37
+ * Pydantic and Zod emit `Optional[T]` as `{ anyOf: [{ type: T, ...keywords },
38
+ * { type: "null" }], title, default }`: the keywords a widget reads (`minimum`,
39
+ * `maximum`, `minLength`, `pattern`, `format`, `items`) sit on the member, out of
40
+ * reach of `propertySchema.minimum`. This returns the property with the
41
+ * member's keywords merged in -- the property's own keys (title, description,
42
+ * default, x-ui-*) win -- and `anyOf` kept, so nullability checks
43
+ * (`isNullableBoolean`, `isFieldOptional`) still see it.
44
+ *
45
+ * Any other shape -- no anyOf, several non-null members, an object member -- is
46
+ * returned unchanged.
47
+ */
48
+ declare function liftNullableMember(property: JsonSchemaProperty): JsonSchemaProperty;
379
49
  /**
380
50
  * Extract enum values from a property schema.
381
51
  *
382
- * Handles both the simple case (`{ enum: [...] }`) and the nullable
383
- * pattern produced by Zod (`{ anyOf: [{ type: "string", enum: [...] }, { type: "null" }] }`).
52
+ * Handles the simple case (`{ enum: [...] }`), the nullable pattern produced
53
+ * by Zod (`{ anyOf: [{ type: "string", enum: [...] }, { type: "null" }] }`),
54
+ * and an array of enum items (`{ type: "array", items: { enum: [...] } }`) --
55
+ * the choices of a multi-select.
384
56
  *
385
57
  * Returns the enum array if found, or an empty array.
386
58
  */
@@ -588,6 +260,8 @@ declare function evaluateUiRule(rule: UIRule | undefined, formData: unknown): Ru
588
260
  * For each property in the schema that has a `default` value, if the
589
261
  * corresponding key is absent (`undefined`) in `data`, the default is applied.
590
262
  * Existing values — including `null` and `false` — are never overwritten.
263
+ * A nested object's properties are filled the same way, at any depth -- a
264
+ * group absent from `data` is added when one of its properties has a default.
591
265
  *
592
266
  * @param data - Existing form data (may be partial)
593
267
  * @param schema - JSON Schema containing property defaults
@@ -597,8 +271,9 @@ declare function applySchemaDefaults(data: Record<string, unknown>, schema: Json
597
271
  /**
598
272
  * Extract all default values declared in a JSON Schema.
599
273
  *
600
- * Walks the schema's top-level properties and collects any `default` values.
601
- * Properties without a `default` are omitted from the result.
274
+ * Walks the schema's properties and collects any `default` values -- a
275
+ * nested object's at any depth, under its key. Properties without a
276
+ * `default` are omitted from the result.
602
277
  *
603
278
  * @param schema - JSON Schema to extract defaults from
604
279
  * @returns Record of field names to their default values
@@ -675,36 +350,80 @@ declare function generateJsonSchemaFromVariables(variables: string[], existingSc
675
350
  declare function toJsonSchema(schema: z.ZodType): JsonSchema;
676
351
 
677
352
  /**
678
- * $ref Resolution -- resolves JSON Schema references.
679
- *
680
- * Walks the schema tree and replaces `{ "$ref": ... }` nodes with the
681
- * corresponding sub-schema. By default it resolves local, in-document refs:
682
- * `#/$defs/name` (Draft 2020-12) or `#/definitions/name` (Draft 7).
683
- *
684
- * A caller may inject a `RefResolver` to resolve ANY ref string (e.g. a schema
685
- * registry id like `sdf_...`, or a canonical URI). The injected resolver is
686
- * tried first; the in-document `$defs`/`definitions` lookup is the fallback, so
687
- * both ref styles work together. The resolver is synchronous: consumers that
688
- * fetch schemas asynchronously (e.g. from a registry over HTTP) pre-load them
689
- * into a map and pass a `(ref) => map[ref]` lookup. This keeps the toolkit pure
690
- * (no HTTP, no async).
691
- *
692
- * Properties on the referencing node are merged on top of the resolved target,
693
- * so context-specific overrides (e.g. a custom title) work without duplicating
694
- * the definition. Refs that no resolver can satisfy are left as-is.
353
+ * A codeable concept's codings by its lists -- shared by its widget and its
354
+ * validation. A list on a code system claims the coding of that system; a list
355
+ * on a value set -- whose codes carry the system of the code system they come
356
+ * from -- takes the codings left, in their order. A coding no list claims is
357
+ * one of a list the field does not name. See docs/design/codeable-concepts.md
358
+ * (workspace).
695
359
  */
696
360
 
697
- /** Resolve a `$ref` string to its target sub-schema, or undefined if unknown. */
698
- type RefResolver = (ref: string) => JsonSchemaProperty | undefined;
361
+ /** A value as a codeable concept: an object, else an empty one. */
362
+ declare function conceptOf(value: unknown): CodeableConcept;
363
+ /** A value's codings by list -- the lists in their order -- and those of no list. */
364
+ declare function codingsByList(value: unknown, lists: AdditionalBinding[]): {
365
+ byList: (ConceptCoding | undefined)[];
366
+ others: ConceptCoding[];
367
+ };
368
+ /** What a list is called beside the others: its title, its purpose's label, else its identifier's last part. */
369
+ declare function listTitle(list: AdditionalBinding): string;
699
370
  /**
700
- * Resolve `$ref` pointers in a JSON Schema document.
701
- *
702
- * By default resolves in-document `#/$defs` / `#/definitions` refs. Pass a
703
- * `resolve` to also resolve registry/URI refs; it is tried first and the
704
- * in-document lookup is the fallback. The original schema is never mutated;
705
- * a document with no refs to resolve is returned unchanged.
371
+ * The required lists a value has no coding of. Only a value with codings is
372
+ * held to them: a text alone is the answer when no code fits.
373
+ */
374
+ declare function missingLists(prop: JsonSchemaProperty, value: unknown): AdditionalBinding[];
375
+
376
+ /**
377
+ * A property of a value type: its `$ref` -- or, when it also takes a text of
378
+ * one's own, `anyOf: [{ $ref }, { type: "string" }]`. The second is the open
379
+ * question of FHIR (R4 `open-choice`, R5 `optionsOrString`) and openEHR's
380
+ * `DV_TEXT` where `DV_CODED_TEXT` is offered: the answer is a value of the
381
+ * type, or a text -- never a value of the type without its own content. See
382
+ * docs/design/coded-values.md (workspace).
383
+ */
384
+
385
+ /** The value type a property is of, whether it also takes a text, and whether it takes several. */
386
+ interface ValueRef {
387
+ ref: string;
388
+ orText: boolean;
389
+ /** Several answers: an array of the type (or of it or a text). */
390
+ multiple: boolean;
391
+ }
392
+ /**
393
+ * The value type of a property: its `$ref`, or that of a `$ref` or a text --
394
+ * or of an array of either, for several answers; undefined for none of them.
395
+ */
396
+ declare function valueRefOf(prop: JsonSchemaProperty): ValueRef | undefined;
397
+ /**
398
+ * The keywords of a property of a value type -- its `$ref`, or that or a text;
399
+ * several answers an array of it -- the others undefined, so writing them
400
+ * replaces the shape a property had.
401
+ */
402
+ declare function valueRefKeywords(ref: string, orText: boolean, multiple?: boolean): Pick<JsonSchemaProperty, "$ref" | "anyOf" | "type" | "items">;
403
+
404
+ /**
405
+ * A quantity's range per unit -- 0 to 300 kg, 0 to 660 lb -- in standard JSON
406
+ * Schema, beside the quantity's `$ref`: one `allOf` entry per unit, "if the
407
+ * unit is kg, then the value is in its range". A range is the unit's, as a
408
+ * number means nothing without one. See docs/design/core-types.md.
409
+ */
410
+
411
+ /** A unit's range: its least and greatest value, either optional. */
412
+ interface UnitRange {
413
+ min?: number;
414
+ max?: number;
415
+ }
416
+ /** The ranges of a quantity's units, by unit code. */
417
+ type UnitRanges = Record<string, UnitRange>;
418
+ /**
419
+ * The ranges a quantity's schema sets per unit; empty when it sets none, and
420
+ * undefined when its `allOf` says something else -- not ranges to edit.
706
421
  */
707
- declare function resolveRefs(schema: JsonSchema, resolve?: RefResolver): JsonSchema;
422
+ declare function unitRangesOf(prop: JsonSchemaProperty): UnitRanges | undefined;
423
+ /** The keywords that set a quantity's ranges, by unit; a unit without a bound sets none. */
424
+ declare function unitRangesKeywords(ranges: UnitRanges): {
425
+ allOf?: JsonSchemaProperty[];
426
+ };
708
427
 
709
428
  /**
710
429
  * Recursive form data validation against a JSON Schema.
@@ -741,9 +460,69 @@ interface ValidationResult {
741
460
  /**
742
461
  * Validate form data against a JSON Schema, recursing into nested objects
743
462
  * and array items.
463
+ *
464
+ * Two layers: this function owns required-ness and array cardinality with
465
+ * human-authored messages; `validateContentConstraints` adds the JSON Schema
466
+ * content constraints (format, pattern, type, length, range, enum, const) via
467
+ * AJV. Both contribute to the same `FieldError[]`, so downstream attribution
468
+ * (per-field `rawErrors`, per-tab error badges) is unchanged.
744
469
  */
745
470
  declare function validateFormData(schema: JsonSchema, data: Record<string, unknown>): ValidationResult;
746
471
 
472
+ /**
473
+ * Content-constraint validation, layered on top of validateFormData.
474
+ *
475
+ * validateFormData covers required-ness and array cardinality with
476
+ * human-authored messages. This module adds the JSON Schema *content*
477
+ * constraints it does not: `format`, `pattern`, `type`, `minLength` /
478
+ * `maxLength`, `minimum` / `maximum` (and their exclusive variants),
479
+ * `enum`, `const`, and `multipleOf`. It reuses the shared AJV instance
480
+ * (already configured with `ajv-formats`) and maps AJV's errors into the
481
+ * same `FieldError` shape the renderer consumes -- AJV's `instancePath` is
482
+ * already an RFC 6901 JSON Pointer, so per-field and per-tab attribution
483
+ * keep working unchanged.
484
+ *
485
+ * Required and array-cardinality keywords are intentionally excluded here so
486
+ * validateFormData stays the single source of those messages -- no field ever
487
+ * shows two errors for the same cause.
488
+ */
489
+
490
+ /**
491
+ * Validate content constraints via AJV and return them as FieldErrors.
492
+ *
493
+ * Only content keywords are returned; required and array-cardinality errors
494
+ * are filtered out (validateFormData owns those). Returns an empty array when
495
+ * the schema compiles cleanly and the data satisfies every content rule, or
496
+ * when AJV cannot compile the schema (in which case the caller's structural
497
+ * validation still stands).
498
+ */
499
+ declare function validateContentConstraints(schema: JsonSchema, data: Record<string, unknown>): FieldError[];
500
+
501
+ /**
502
+ * Merge FieldError lists from several validation sources into one, de-duplicated
503
+ * by field so a field never shows two errors for the same cause.
504
+ *
505
+ * Sources are passed in precedence order (strongest first): structural/content
506
+ * from validateFormData, then custom validators, then external/extra errors.
507
+ * The first source to flag a given field (by its pointer's root segment) wins;
508
+ * later sources add errors only for fields not already flagged. This extends the
509
+ * existing rule inside validateFormData (a content error is skipped on a field
510
+ * that already has a structural error) across every source.
511
+ *
512
+ * Form-level errors (pointer "") are never de-duplicated against fields -- they
513
+ * belong to the form, not a field -- but identical form-level messages collapse.
514
+ *
515
+ * Pure function -- no React, no side effects.
516
+ */
517
+
518
+ /**
519
+ * Merge ordered FieldError sources. Earlier sources take precedence per field.
520
+ *
521
+ * @param sources FieldError lists in precedence order (strongest first).
522
+ * @returns one de-duplicated list preserving each kept error's order.
523
+ */
524
+ declare function mergeFieldErrors(...sources: FieldError[][]): FieldError[];
525
+
747
526
  /**
748
527
  * diffFormData -- structural diff between two form data snapshots.
749
528
  *
@@ -785,5 +564,14 @@ declare function diffFormData(original: Record<string, unknown>, updated: Record
785
564
  * declares. Returns the input unchanged when nothing needed stamping.
786
565
  */
787
566
  declare function ensureFormItemIds(data: Record<string, unknown>, schema: JsonSchema): Record<string, unknown>;
567
+ /**
568
+ * Return `data` without any `_fid` -- the inverse of `ensureFormItemIds`.
569
+ *
570
+ * Item ids are the renderer's own bookkeeping: they must not reach a consumer
571
+ * nor be validated against the schema (an item schema with
572
+ * `additionalProperties: false` would reject them).
573
+ */
574
+ declare function stripFormItemIds(data: Record<string, unknown>): Record<string, unknown>;
788
575
 
789
- export { type ArrayItemChange, type FieldDiff, type FieldError, type FormDiff, type JsonSchema, type JsonSchemaProperty, type RefResolver, type RuleState, type UILayoutConfig, type UILayoutGroupConfig, type UILayoutRowConfig, type UIRule, type UIRuleCondition, type UIRuleEffect, type UISchema, type UISchemaOptions, type ValidationResult, type ValueChange, WIDTH_TOKEN_REMS, type WidthToken, ajv, applySchemaDefaults, diffFormData, ensureFormItemIds, evaluateUiRule, extractEnumValues, extractSchemaDefaults, findActiveBranch, generateJsonSchemaFromVariables, getAtPointer, getBranchLabel, getBranchValue, getDiscriminator, getFieldConstraints, getFieldDefault, getFieldHelpText, getFieldPlaceholder, getFieldTitle, getFieldType, getFieldWidget, getOptionalFields, getRequiredFields, getSchemaProperties, hasConditionals, hasProperties, isFieldOptional, isFieldRequired, isNullableBoolean, isOneOf, matchesConst, resolveRefs, resolveSchema, toJsonSchema, validateFormData, validateSchema };
576
+ export { AdditionalBinding, CodeableConcept, ConceptCoding, FormDiff, JsonSchema, JsonSchemaProperty, UIRule, ajv, applySchemaDefaults, codingsByList, conceptOf, diffFormData, ensureFormItemIds, evaluateUiRule, extractEnumValues, extractSchemaDefaults, findActiveBranch, generateJsonSchemaFromVariables, getAtPointer, getBranchLabel, getBranchValue, getDiscriminator, getFieldConstraints, getFieldDefault, getFieldHelpText, getFieldPlaceholder, getFieldTitle, getFieldType, getFieldWidget, getOptionalFields, getRequiredFields, getSchemaProperties, hasConditionals, hasProperties, isFieldOptional, isFieldRequired, isNullableBoolean, isOneOf, liftNullableMember, listTitle, matchesConst, mergeFieldErrors, missingLists, resolveSchema, stripFormItemIds, toJsonSchema, unitRangesKeywords, unitRangesOf, validateContentConstraints, validateFormData, validateSchema, valueRefKeywords, valueRefOf };
577
+ export type { FieldError, RuleState, UnitRange, UnitRanges, ValidationResult, ValueRef };