@bluprynt/forms-core 1.0.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.
@@ -0,0 +1,1200 @@
1
+ //#region src/types/conditions.d.ts
2
+ /**
3
+ * A leaf condition that compares a single field's value against an expected value.
4
+ *
5
+ * @property field - Numeric id of the field whose value is tested.
6
+ * @property op - Comparison operator. `set`/`notset` ignore {@link value};
7
+ * `in`/`notin` expect {@link value} to be an array.
8
+ * @property value - The reference value for the comparison. Optional for
9
+ * `set`/`notset` operators.
10
+ */
11
+ type SimpleCondition = {
12
+ field: number;
13
+ op: 'set' | 'notset' | 'eq' | 'ne' | 'lt' | 'gt' | 'lte' | 'gte' | 'in' | 'notin';
14
+ value?: unknown;
15
+ };
16
+ /**
17
+ * A compound condition that combines child conditions with logical AND or OR.
18
+ *
19
+ * - `{ and: [...] }` -- all child conditions must be true.
20
+ * - `{ or: [...] }` -- at least one child condition must be true.
21
+ */
22
+ type CompoundCondition = {
23
+ and: Condition[];
24
+ } | {
25
+ or: Condition[];
26
+ };
27
+ /**
28
+ * A condition controlling visibility of a field or section.
29
+ * Can be a {@link SimpleCondition} or a {@link CompoundCondition} that
30
+ * recursively nests other conditions.
31
+ */
32
+ type Condition = SimpleCondition | CompoundCondition;
33
+ //#endregion
34
+ //#region src/condition-evaluator.d.ts
35
+ /**
36
+ * Context passed to condition evaluation methods.
37
+ *
38
+ * @property values - Current form values keyed by stringified field id.
39
+ * @property visibilityMap - Pre-computed visibility map. When provided, a
40
+ * reference to a hidden field is treated as "not set" regardless of its
41
+ * actual value.
42
+ * @property now - Reference date for resolving relative date expressions in
43
+ * condition values.
44
+ */
45
+ type EvaluationContext = {
46
+ values: Record<string, unknown>;
47
+ visibilityMap?: Map<number, boolean>;
48
+ now: Date;
49
+ };
50
+ /**
51
+ * Evaluates condition trees against form state.
52
+ *
53
+ * Supports three kinds of conditions:
54
+ * - **Simple** ({@link SimpleCondition}): compares a single field's value
55
+ * using one of the supported operators (`set`, `notset`, `eq`, `ne`, `lt`,
56
+ * `gt`, `lte`, `gte`, `in`, `notin`).
57
+ * - **Compound AND**: `{ and: [...] }` -- all child conditions must be true.
58
+ * - **Compound OR**: `{ or: [...] }` -- at least one child condition must be true.
59
+ *
60
+ * **Hidden-field rule**: when a `visibilityMap` is provided and the
61
+ * referenced field is hidden (`false`), the condition evaluates as if the
62
+ * field has no value. This means `notset` returns `true` and all other
63
+ * operators return `false`.
64
+ *
65
+ * **Date handling**: condition values that are relative date expressions
66
+ * (e.g. `"+7d"`) are resolved against `ctx.now` before comparison.
67
+ */
68
+ declare class ConditionEvaluator {
69
+ /**
70
+ * Evaluates a condition tree against the current form state.
71
+ *
72
+ * @param condition - The condition to evaluate (simple or compound).
73
+ * @param ctx - Evaluation context containing form values and optional
74
+ * visibility/date overrides.
75
+ * @returns `true` if the condition is satisfied, `false` otherwise.
76
+ */
77
+ evalCondition(condition: Condition, ctx: EvaluationContext): boolean;
78
+ private evalSimple;
79
+ private resolveIfDate;
80
+ private compareTo;
81
+ }
82
+ //#endregion
83
+ //#region src/types/field-types.d.ts
84
+ /**
85
+ * Union of all supported form field types.
86
+ *
87
+ * - `string` -- free-text input
88
+ * - `number` -- numeric input
89
+ * - `boolean` -- true/false toggle
90
+ * - `date` -- date picker (ISO-8601 string value)
91
+ * - `select` -- single selection from a predefined list
92
+ * - `array` -- ordered list of values whose item type is any non-array field type
93
+ * - `file` -- file upload (stores name, MIME type, size, URL)
94
+ */
95
+ type FieldType = 'string' | 'number' | 'boolean' | 'date' | 'select' | 'array' | 'file';
96
+ /**
97
+ * Discriminator for every content node in a form definition.
98
+ * Includes all {@link FieldType} values plus `'section'` for grouping containers.
99
+ */
100
+ type ContentItemType = FieldType | 'section';
101
+ //#endregion
102
+ //#region src/types/select-option.d.ts
103
+ /**
104
+ * A single option within a `select` field's predefined list.
105
+ *
106
+ * @property value - The stored value when this option is chosen.
107
+ * @property label - Human-readable display text for this option.
108
+ */
109
+ type SelectOption = {
110
+ value: string | number;
111
+ label: string;
112
+ };
113
+ //#endregion
114
+ //#region src/types/array-item-def.d.ts
115
+ /**
116
+ * Schema for individual items inside an `array` field.
117
+ *
118
+ * Nested arrays are not allowed, so `type` excludes `'array'`.
119
+ * Items do not have their own id or condition -- they inherit the parent
120
+ * array field's identity and visibility.
121
+ *
122
+ * @property type - The scalar field type for each item in the array.
123
+ * @property label - Display label for the item.
124
+ * @property description - Optional description shown to the user.
125
+ * @property validation - Validation rules applied to each individual item.
126
+ * @property options - Required when {@link type} is `'select'`; the list of
127
+ * allowed values.
128
+ */
129
+ type ArrayItemDef = {
130
+ type: Exclude<FieldType, 'array'>;
131
+ label: string;
132
+ description?: string;
133
+ validation?: Record<string, unknown>;
134
+ options?: SelectOption[];
135
+ };
136
+ //#endregion
137
+ //#region src/types/validation/array.d.ts
138
+ /**
139
+ * Validation rules for `array` fields.
140
+ *
141
+ * @property minItems - Minimum number of items the array must contain (inclusive).
142
+ * @property maxItems - Maximum number of items the array may contain (inclusive).
143
+ */
144
+ type ArrayValidation = {
145
+ minItems?: number;
146
+ maxItems?: number;
147
+ };
148
+ //#endregion
149
+ //#region src/types/validation/boolean.d.ts
150
+ /**
151
+ * Validation rules for `boolean` fields.
152
+ *
153
+ * @property required - Whether an explicit `true` or `false` must be provided.
154
+ */
155
+ type BooleanValidation = {
156
+ required?: boolean;
157
+ };
158
+ //#endregion
159
+ //#region src/types/validation/date.d.ts
160
+ /**
161
+ * Validation rules for `date` fields.
162
+ *
163
+ * Date boundaries can be absolute ISO-8601 strings or relative date
164
+ * expressions (e.g. `"+7d"`, `"-1m"`). Relative dates are resolved at
165
+ * validation time.
166
+ *
167
+ * @property required - Whether a value must be provided.
168
+ * @property minDate - Earliest allowed date (inclusive). Absolute or relative.
169
+ * @property maxDate - Latest allowed date (inclusive). Absolute or relative.
170
+ */
171
+ type DateValidation = {
172
+ required?: boolean;
173
+ minDate?: string;
174
+ maxDate?: string;
175
+ };
176
+ //#endregion
177
+ //#region src/types/validation/file.d.ts
178
+ /**
179
+ * Validation rules for `file` fields.
180
+ *
181
+ * @property required - Whether a file must be uploaded.
182
+ */
183
+ type FileValidation = {
184
+ required?: boolean;
185
+ };
186
+ //#endregion
187
+ //#region src/types/validation/number.d.ts
188
+ /**
189
+ * Validation rules for `number` fields.
190
+ *
191
+ * @property required - Whether a value must be provided.
192
+ * @property min - Minimum allowed value (inclusive).
193
+ * @property max - Maximum allowed value (inclusive).
194
+ */
195
+ type NumberValidation = {
196
+ required?: boolean;
197
+ min?: number;
198
+ max?: number;
199
+ };
200
+ //#endregion
201
+ //#region src/types/validation/select.d.ts
202
+ /**
203
+ * Validation rules for `select` fields.
204
+ *
205
+ * @property required - Whether an option must be chosen.
206
+ */
207
+ type SelectValidation = {
208
+ required?: boolean;
209
+ };
210
+ //#endregion
211
+ //#region src/types/validation/string.d.ts
212
+ /**
213
+ * Validation rules for `string` fields.
214
+ *
215
+ * @property required - Whether a non-empty value must be provided.
216
+ * @property minLength - Minimum character count (inclusive).
217
+ * @property maxLength - Maximum character count (inclusive).
218
+ * @property pattern - Regular expression the value must match.
219
+ * @property patternMessage - Custom error message shown when `pattern` fails.
220
+ */
221
+ type StringValidation = {
222
+ required?: boolean;
223
+ minLength?: number;
224
+ maxLength?: number;
225
+ pattern?: string;
226
+ patternMessage?: string;
227
+ };
228
+ //#endregion
229
+ //#region src/types/validation/type-specific.d.ts
230
+ /**
231
+ * Union of all type-specific validation rule shapes.
232
+ * The applicable shape depends on the field's {@link FieldType}.
233
+ */
234
+ type TypeSpecificValidation = StringValidation | NumberValidation | BooleanValidation | DateValidation | SelectValidation | ArrayValidation | FileValidation;
235
+ //#endregion
236
+ //#region src/types/field-entry.d.ts
237
+ /**
238
+ * Flattened representation of a field or section stored in the engine's
239
+ * internal registry.
240
+ *
241
+ * Created during {@link prepare} by walking the form definition tree.
242
+ * Every content item (field or section) gets exactly one `FieldEntry`.
243
+ *
244
+ * @property id - Unique numeric identifier within the form.
245
+ * @property type - Discriminator: one of the {@link FieldType} values or `'section'`.
246
+ * @property condition - Visibility condition, if any.
247
+ * @property validation - Validation rules, if any (always `undefined` for sections).
248
+ * @property parentId - Id of the containing section, or `undefined` for top-level items.
249
+ * @property options - Select options (only for `select` fields).
250
+ * @property item - Array item definition (only for `array` fields).
251
+ * @property label - Display label (only for fields, `undefined` for sections).
252
+ * @property title - Display title (only for sections, `undefined` for fields).
253
+ */
254
+ type FieldEntry = {
255
+ id: number;
256
+ type: ContentItemType;
257
+ condition: Condition | undefined;
258
+ validation: TypeSpecificValidation | undefined;
259
+ parentId: number | undefined;
260
+ options: SelectOption[] | undefined;
261
+ item: ArrayItemDef | undefined;
262
+ label: string | undefined;
263
+ title: string | undefined;
264
+ };
265
+ //#endregion
266
+ //#region src/dependency-graph.d.ts
267
+ /**
268
+ * Manages the condition dependency graph for form fields.
269
+ *
270
+ * Built from the field registry during engine preparation. Provides:
271
+ * - Forward dependency graph (`graph`): answers "if field X changes, which
272
+ * items need to re-evaluate their visibility?"
273
+ * - Topological ordering (`topologicalOrder`): guarantees that when computing
274
+ * visibility, every item is evaluated after the fields it depends on.
275
+ * - Affected-ids lookup (`getAffectedIds`): returns all transitively
276
+ * affected item ids when a field value changes (lazily cached).
277
+ *
278
+ * Static methods (`extractFieldRefs`, `detectCycle`) can be used before
279
+ * constructing an instance, e.g. during semantic validation.
280
+ */
281
+ declare class DependencyGraph {
282
+ /**
283
+ * Forward adjacencyMap map: key is a field id, value is the set of item ids
284
+ * whose conditions reference that field.
285
+ */
286
+ readonly graph: Map<number, Set<number>>;
287
+ /**
288
+ * Item ids in topological order. Dependencies come before dependents.
289
+ */
290
+ readonly topologicalOrder: number[];
291
+ private readonly registry;
292
+ private readonly affectedCache;
293
+ /**
294
+ * @param registry - The engine's field registry (built during preparation).
295
+ */
296
+ constructor(registry: Map<number, FieldEntry>);
297
+ /**
298
+ * Extracts the set of field ids referenced by a condition tree.
299
+ *
300
+ * Recursively walks compound conditions (`and`/`or`) and collects the
301
+ * `field` property from every leaf {@link SimpleCondition}.
302
+ *
303
+ * @param condition - A simple or compound condition.
304
+ * @returns Set of all unique field ids that appear in the condition.
305
+ */
306
+ static extractFieldRefs(condition: Condition): Set<number>;
307
+ /**
308
+ * Detects circular dependencies in the condition graph.
309
+ *
310
+ * Uses DFS-based cycle detection (white/gray/black coloring). If a cycle
311
+ * is found, the function reconstructs and returns a human-readable path
312
+ * string (e.g. `"1 -> 2 -> 3 -> 1"`).
313
+ *
314
+ * @param registry - The engine's field registry.
315
+ * @returns An array of field ids forming the cycle, or `undefined` if no cycle exists.
316
+ */
317
+ static detectCycle(registry: Map<number, FieldEntry>): number[] | undefined;
318
+ /**
319
+ * Returns the set of item ids whose visibility could change when the given
320
+ * field's value changes.
321
+ *
322
+ * Performs a transitive expansion of the forward dependency graph starting
323
+ * from the field's direct dependents. Results are memoized for subsequent
324
+ * calls with the same `fieldId`.
325
+ *
326
+ * @param fieldId - Id of the field whose value changed.
327
+ * @returns Set of all transitively affected item ids. Empty set if no items
328
+ * depend on `fieldId`.
329
+ */
330
+ getAffectedIds(fieldId: number): Set<number>;
331
+ private static collectRefs;
332
+ private static dfs;
333
+ private static reconstructCycle;
334
+ /**
335
+ * Builds the forward dependency graph from the registry.
336
+ */
337
+ private buildGraph;
338
+ /**
339
+ * Produces a topological ordering using Kahn's algorithm.
340
+ */
341
+ private buildTopologicalOrder;
342
+ /**
343
+ * Expands a set of item ids to include all transitive dependents via BFS.
344
+ */
345
+ private expandTransitiveDependencies;
346
+ }
347
+ //#endregion
348
+ //#region src/types/form-values.d.ts
349
+ /**
350
+ * A flat key-value map of user-submitted form data.
351
+ *
352
+ * Keys are stringified field ids (e.g. `"1"`, `"42"`). Values are the raw
353
+ * data entered by the user, typed according to the field's {@link FieldType}.
354
+ */
355
+ type FormValues = Record<string, unknown>;
356
+ /**
357
+ * A complete form document containing form metadata and user-submitted values.
358
+ *
359
+ * This is the serialization/storage format for filled forms. The `form`
360
+ * property links the document back to the schema that produced it, and
361
+ * `values` holds the flat field data.
362
+ *
363
+ * @property form - Metadata identifying the form schema.
364
+ * @property form.id - The form schema's unique identifier (from {@link FormDefinition.id}).
365
+ * @property form.version - The form schema's version (from {@link FormDefinition.version}).
366
+ * @property values - Flat key-value map of user-submitted data.
367
+ */
368
+ type FormDocument = {
369
+ form: {
370
+ id: string;
371
+ version: string;
372
+ submittedAt: string;
373
+ };
374
+ values: FormValues;
375
+ };
376
+ //#endregion
377
+ //#region src/types/validation-results.d.ts
378
+ /**
379
+ * Machine-readable codes for all field-level validation rules.
380
+ *
381
+ * | Code | Applies to |
382
+ * |------|------------|
383
+ * | `REQUIRED` | All field types |
384
+ * | `TYPE` | All field types (value has wrong runtime type) |
385
+ * | `MIN_LENGTH` | `string` |
386
+ * | `MAX_LENGTH` | `string` |
387
+ * | `PATTERN` | `string` |
388
+ * | `MIN` | `number` |
389
+ * | `MAX` | `number` |
390
+ * | `MIN_DATE` | `date` |
391
+ * | `MAX_DATE` | `date` |
392
+ * | `INVALID_DATE` | `date` (unparseable value) |
393
+ * | `INVALID_OPTION` | `select` (value not in options list) |
394
+ * | `MIN_ITEMS` | `array` |
395
+ * | `MAX_ITEMS` | `array` |
396
+ */
397
+ type FieldValidationRule = 'REQUIRED' | 'TYPE' | 'MIN_LENGTH' | 'MAX_LENGTH' | 'PATTERN' | 'MIN' | 'MAX' | 'MIN_DATE' | 'MAX_DATE' | 'INVALID_DATE' | 'INVALID_OPTION' | 'MIN_ITEMS' | 'MAX_ITEMS';
398
+ /**
399
+ * A single validation error for a specific field.
400
+ *
401
+ * @property fieldId - Numeric id of the field that failed validation.
402
+ * @property rule - Machine-readable rule code from {@link FieldValidationRule}.
403
+ * @property message - Human-readable error description.
404
+ * @property params - Optional parameters providing context (e.g. `{ minLength: 5, actual: 3 }`).
405
+ * @property itemIndex - For array fields, the zero-based index of the item
406
+ * that failed validation. `undefined` for non-array fields.
407
+ */
408
+ type FieldValidationError = {
409
+ fieldId: number;
410
+ rule: FieldValidationRule;
411
+ message: string;
412
+ params?: Record<string, unknown>;
413
+ itemIndex?: number;
414
+ };
415
+ /**
416
+ * Machine-readable codes for all document-level validation errors.
417
+ *
418
+ * | Code | Description |
419
+ * |------|-------------|
420
+ * | `SCHEMA_INVALID` | The form definition does not conform to the JSON schema. |
421
+ * | `DUPLICATE_ID` | Two or more content items share the same numeric id. |
422
+ * | `NESTING_DEPTH` | A section is nested deeper than the allowed 3 levels. |
423
+ * | `UNKNOWN_FIELD_REF` | A condition references a field id that does not exist in the form. |
424
+ * | `CONDITION_REFS_SECTION` | A condition references a section id; sections have no value to compare. |
425
+ * | `INVALID_MIN_MAX` | A field's minimum constraint exceeds its maximum constraint. |
426
+ * | `INVALID_REGEX` | String field `pattern` is not a valid regular expression. |
427
+ * | `CIRCULAR_DEPENDENCY` | Condition dependencies form a cycle (A depends on B depends on A). |
428
+ * | `FORM_ID_MISMATCH` | The document's form id does not match the engine's form definition id. |
429
+ * | `FORM_VERSION_MISMATCH` | The document's form version does not match the engine's form definition version. |
430
+ * | `FORM_SUBMITTED_AT_MISSING` | The document's submittedAt field is missing. |
431
+ * | `FORM_SUBMITTED_AT_INVALID` | The document's submittedAt field is not a valid date. |
432
+ */
433
+ type DocumentValidationErrorCode = 'SCHEMA_INVALID' | 'DUPLICATE_ID' | 'NESTING_DEPTH' | 'UNKNOWN_FIELD_REF' | 'CONDITION_REFS_SECTION' | 'INVALID_MIN_MAX' | 'INVALID_REGEX' | 'CIRCULAR_DEPENDENCY' | 'FORM_ID_MISMATCH' | 'FORM_VERSION_MISMATCH' | 'FORM_SUBMITTED_AT_MISSING' | 'FORM_SUBMITTED_AT_INVALID';
434
+ /**
435
+ * A single validation error found during form definition or document validation.
436
+ *
437
+ * @property code - Machine-readable error code from {@link DocumentValidationErrorCode}.
438
+ * @property message - Human-readable error description.
439
+ * @property params - Optional parameters providing context (e.g. `{ expected, actual }`).
440
+ * @property itemId - Id of the content item involved, when applicable.
441
+ */
442
+ type DocumentValidationError = {
443
+ code: DocumentValidationErrorCode;
444
+ message: string;
445
+ params?: Record<string, unknown>;
446
+ itemId?: number;
447
+ };
448
+ /**
449
+ * Aggregated result of validating all visible form fields.
450
+ *
451
+ * @property valid - `true` when `fieldErrors` is empty and no `documentErrors` exist.
452
+ * @property fieldErrors - Map from field id to its validation errors.
453
+ * Empty map when `valid` is `true`. Fields with no errors have no entry.
454
+ * @property documentErrors - Document-level compatibility errors, if any.
455
+ */
456
+ type FormValidationResult = {
457
+ valid: boolean;
458
+ fieldErrors: Map<number, FieldValidationError[]>;
459
+ documentErrors?: DocumentValidationError[];
460
+ };
461
+ //#endregion
462
+ //#region src/field-validator.d.ts
463
+ /**
464
+ * Validates form values against the schema's validation rules.
465
+ *
466
+ * **Which fields are validated:**
467
+ * - Only fields (not sections) are validated.
468
+ * - Hidden fields (those with `visibilityMap.get(id) === false`) are skipped
469
+ * entirely -- they produce no errors regardless of their value.
470
+ *
471
+ * **How each field type is validated:**
472
+ * - `string` -- `required`, `minLength`, `maxLength`, `pattern`.
473
+ * - `number` -- `required`, `min`, `max`.
474
+ * - `boolean` -- `required` (must be explicitly `true` or `false`).
475
+ * - `date` -- `required`, `minDate`, `maxDate`. Relative date boundaries
476
+ * are resolved against `now`.
477
+ * - `select` -- `required`, plus the value must be one of the defined options.
478
+ * - `array` -- `minItems`, `maxItems`, plus each item is validated
479
+ * individually according to the array's {@link ArrayItemDef}. Item-level
480
+ * errors carry an `itemIndex`.
481
+ *
482
+ * For all types, if `required` fails, no further rules are checked for that
483
+ * field (early return). If the value is empty/absent and `required` is not
484
+ * set, no errors are produced.
485
+ */
486
+ declare class FieldValidator {
487
+ private readonly registry;
488
+ private readonly validators;
489
+ /**
490
+ * @param registry - The engine's field registry.
491
+ */
492
+ constructor(registry: Map<number, FieldEntry>);
493
+ /**
494
+ * Validates form values against the schema's validation rules.
495
+ *
496
+ * @param values - The form values to validate, keyed by stringified field id.
497
+ * @param visibilityMap - Pre-computed visibility map for all items.
498
+ * @param now - Reference date for resolving relative date expressions.
499
+ * Defaults to `new Date()`.
500
+ * @returns A {@link FormValidationResult} with `valid: true` when no errors
501
+ * exist, or `valid: false` with a populated `fieldErrors` map.
502
+ */
503
+ validate(values: FormValues, visibilityMap: Map<number, boolean>, now?: Date): FormValidationResult;
504
+ private validateField;
505
+ }
506
+ //#endregion
507
+ //#region src/types/form-definition.d.ts
508
+ /**
509
+ * Top-level form definition object representing a complete form schema.
510
+ *
511
+ * This is the JSON document that authors create and publish. It is passed to
512
+ * {@link prepare} to produce a {@link FormEngine}.
513
+ *
514
+ * @property id - Globally unique identifier for the form schema.
515
+ * @property version - Schema version string (e.g. `"1.0.0"`).
516
+ * @property title - Human-readable title of the form.
517
+ * @property description - Optional description of the form's purpose.
518
+ * @property content - Ordered list of top-level fields and sections.
519
+ */
520
+ type FormDefinition = {
521
+ id: string;
522
+ version: string;
523
+ title: string;
524
+ description?: string;
525
+ content: ContentItem[];
526
+ };
527
+ /**
528
+ * A single node in the form definition tree -- either a field or a section.
529
+ */
530
+ type ContentItem = FieldContentItem | SectionContentItem;
531
+ /**
532
+ * A field node within the form definition tree.
533
+ *
534
+ * @property id - Unique numeric identifier.
535
+ * @property type - The field's data type.
536
+ * @property label - Display label shown to the user.
537
+ * @property description - Optional help text.
538
+ * @property condition - Visibility condition that controls whether this field is shown.
539
+ * @property validation - Type-specific validation rules.
540
+ * @property options - Allowed values (required for `select` fields).
541
+ * @property item - Item schema (required for `array` fields).
542
+ */
543
+ type FieldContentItem = {
544
+ id: number;
545
+ type: FieldType;
546
+ label: string;
547
+ description?: string;
548
+ condition?: Condition;
549
+ validation?: TypeSpecificValidation;
550
+ options?: SelectOption[];
551
+ item?: ArrayItemDef;
552
+ };
553
+ /**
554
+ * A section node that groups fields and/or child sections.
555
+ *
556
+ * Sections can be nested up to 3 levels deep.
557
+ *
558
+ * @property id - Unique numeric identifier.
559
+ * @property type - Always `'section'`.
560
+ * @property title - Display title for the section.
561
+ * @property description - Optional description.
562
+ * @property condition - Visibility condition. When hidden, all descendant
563
+ * fields and sections are also hidden.
564
+ * @property content - Ordered list of child content items.
565
+ */
566
+ type SectionContentItem = {
567
+ id: number;
568
+ type: 'section';
569
+ title: string;
570
+ description?: string;
571
+ condition?: Condition;
572
+ content: ContentItem[];
573
+ };
574
+ //#endregion
575
+ //#region src/form-definition-editor.d.ts
576
+ /**
577
+ * Descriptor for a field to be added via the editor.
578
+ * `id` is optional -- when omitted the editor auto-assigns the next available id.
579
+ */
580
+ type FieldDescriptor = Omit<FieldContentItem, 'id'> & {
581
+ id?: number;
582
+ };
583
+ /**
584
+ * Descriptor for a section to be added via the editor.
585
+ * `id` is optional -- when omitted the editor auto-assigns the next available id.
586
+ * `content` defaults to an empty array (items are added separately).
587
+ */
588
+ type SectionDescriptor = Omit<SectionContentItem, 'id' | 'content'> & {
589
+ id?: number;
590
+ content?: ContentItem[];
591
+ };
592
+ /**
593
+ * Flat info about a content item returned by listing methods.
594
+ */
595
+ type ContentItemInfo = {
596
+ id: number;
597
+ type: ContentItem['type'];
598
+ label?: string;
599
+ title?: string;
600
+ parentId: number | undefined;
601
+ };
602
+ /**
603
+ * Mutable editor for building and modifying a {@link FormDefinition}.
604
+ *
605
+ * Operates directly on the definition tree. All mutating methods return
606
+ * `this` for fluent chaining.
607
+ *
608
+ * @example
609
+ * ```ts
610
+ * const editor = new FormDefinitionEditor({
611
+ * id: 'my-form', version: '1.0.0', title: 'My Form', content: [],
612
+ * })
613
+ * editor
614
+ * .addField({ type: 'string', label: 'Name', validation: { required: true } })
615
+ * .addSection({ type: 'section', title: 'Details' })
616
+ * .addField({ type: 'number', label: 'Age' }, 2) // into section id=2
617
+ *
618
+ * const definition = editor.toJSON()
619
+ * ```
620
+ */
621
+ declare class FormDefinitionEditor {
622
+ private definition;
623
+ constructor(definition: FormDefinition);
624
+ setTitle(title: string): this;
625
+ setDescription(description: string | undefined): this;
626
+ setVersion(version: string): this;
627
+ setId(id: string): this;
628
+ /**
629
+ * Returns the next available numeric id (max existing + 1).
630
+ */
631
+ nextId(): number;
632
+ /**
633
+ * Adds a field to the form.
634
+ *
635
+ * @param descriptor - Field properties. `id` is auto-assigned if omitted.
636
+ * @param parentId - Section id to add into. `undefined` for top-level.
637
+ * @param index - Position within the parent's content array. Appends if omitted.
638
+ * @returns `this` for chaining.
639
+ * @throws If `parentId` references a non-existent or non-section item, or if the id already exists.
640
+ */
641
+ addField(descriptor: FieldDescriptor, parentId?: number, index?: number): this;
642
+ /**
643
+ * Adds a section to the form.
644
+ *
645
+ * @param descriptor - Section properties. `id` is auto-assigned if omitted.
646
+ * @param parentId - Parent section id. `undefined` for top-level.
647
+ * @param index - Position within the parent's content array. Appends if omitted.
648
+ * @returns `this` for chaining.
649
+ * @throws If `parentId` references a non-existent or non-section item, or if the id already exists.
650
+ */
651
+ addSection(descriptor: SectionDescriptor, parentId?: number, index?: number): this;
652
+ /**
653
+ * Updates properties of an existing field.
654
+ *
655
+ * Cannot change `id` or `type`. Use {@link removeItem} + {@link addField}
656
+ * to change the type.
657
+ */
658
+ updateField(id: number, updates: Partial<Omit<FieldContentItem, 'id' | 'type'>>): this;
659
+ /**
660
+ * Updates properties of an existing section.
661
+ *
662
+ * Cannot change `id`, `type`, or `content` directly. Use add/remove methods
663
+ * for content manipulation.
664
+ */
665
+ updateSection(id: number, updates: Partial<Omit<SectionContentItem, 'id' | 'type' | 'content'>>): this;
666
+ /**
667
+ * Removes a field or section (and all its descendants) by id.
668
+ *
669
+ * @returns `this` for chaining.
670
+ * @throws If the id is not found.
671
+ */
672
+ removeItem(id: number): this;
673
+ /**
674
+ * Moves an item to a new parent and/or position.
675
+ *
676
+ * @param id - Id of the item to move.
677
+ * @param targetParentId - Destination section id, or `undefined` for top-level.
678
+ * @param index - Position in the target content array. Appends if omitted.
679
+ */
680
+ moveItem(id: number, targetParentId: number | undefined, index?: number): this;
681
+ /**
682
+ * Returns a flat list of all content items (fields + sections) with parent info.
683
+ */
684
+ listAll(): ContentItemInfo[];
685
+ /**
686
+ * Returns a flat list of all fields (excludes sections).
687
+ */
688
+ listFields(): ContentItemInfo[];
689
+ /**
690
+ * Returns a flat list of all sections.
691
+ */
692
+ listSections(): ContentItemInfo[];
693
+ /**
694
+ * Returns the content item with the given id, or `undefined` if not found.
695
+ */
696
+ getItem(id: number): ContentItem | undefined;
697
+ /**
698
+ * Sets or clears the validation rules for a field.
699
+ */
700
+ setValidation(id: number, validation: TypeSpecificValidation | undefined): this;
701
+ /**
702
+ * Sets or clears the visibility condition for a field or section.
703
+ */
704
+ setCondition(id: number, condition: Condition | undefined): this;
705
+ /**
706
+ * Sets the select options for a `select` field.
707
+ */
708
+ setOptions(id: number, options: SelectOption[]): this;
709
+ /**
710
+ * Sets the item definition for an `array` field.
711
+ */
712
+ setArrayItem(id: number, itemDef: ArrayItemDef): this;
713
+ /**
714
+ * Sets the label for a field.
715
+ */
716
+ setLabel(id: number, label: string): this;
717
+ /**
718
+ * Sets the description for a field or section.
719
+ */
720
+ setFieldDescription(id: number, description: string | undefined): this;
721
+ /**
722
+ * Returns a deep clone of the current form definition.
723
+ */
724
+ toJSON(): FormDefinition;
725
+ private findItem;
726
+ private assertIdAvailable;
727
+ private insertItem;
728
+ private getTargetContent;
729
+ private removeFromContent;
730
+ private walkAll;
731
+ private walkAllWithParent;
732
+ private collectDescendantIds;
733
+ }
734
+ //#endregion
735
+ //#region src/form-definition-validator.d.ts
736
+ /**
737
+ * Validates form definitions at both the structural (JSON Schema) and
738
+ * semantic levels.
739
+ *
740
+ * Used by {@link FormEngine} during construction before building the engine.
741
+ *
742
+ * ### Schema validation (`validateSchema`)
743
+ * Validates raw input against the form definition JSON Schema. Returns
744
+ * `SCHEMA_INVALID` issues for every violation found.
745
+ *
746
+ * ### Semantic validation (`validate`)
747
+ * Checks for logical issues that go beyond JSON schema validity:
748
+ * 1. **Duplicate IDs** (`DUPLICATE_ID`) -- every content item id must be unique.
749
+ * 2. **Nesting depth** (`NESTING_DEPTH`) -- sections may not be nested more
750
+ * than 3 levels deep.
751
+ * 3. **Unknown field references** (`UNKNOWN_FIELD_REF`) -- conditions must
752
+ * only reference field ids that exist in the registry.
753
+ * 4. **Condition references section** (`CONDITION_REFS_SECTION`) -- conditions
754
+ * must not reference section ids, because sections have no values.
755
+ * 5. **Constraint contradictions** (`INVALID_MIN_MAX`) -- e.g. `minLength > maxLength`,
756
+ * `min > max`, `minDate > maxDate` (absolute dates only), `minItems > maxItems`.
757
+ * 6. **Invalid regex** (`INVALID_REGEX`) -- string field `pattern` values must
758
+ * be valid regular expressions.
759
+ */
760
+ declare class FormDefinitionValidator {
761
+ /**
762
+ * Validates raw input against the form definition JSON schema.
763
+ *
764
+ * @param input - The raw input to validate.
765
+ * @returns Array of `SCHEMA_INVALID` issues. Empty when the input conforms to the schema.
766
+ */
767
+ validateSchema(input: unknown): DocumentValidationError[];
768
+ /**
769
+ * Validates a form definition semantically.
770
+ *
771
+ * @param definition - The form definition to validate.
772
+ * @param registry - The flattened field registry built from the definition.
773
+ * @returns Array of issues found. Empty if the definition is semantically valid.
774
+ */
775
+ validate(definition: FormDefinition, registry: Map<number, FieldEntry>): DocumentValidationError[];
776
+ private checkDuplicateIds;
777
+ private checkNestingDepth;
778
+ private checkConditionRefs;
779
+ private checkConditionRefsSection;
780
+ private checkConstraintContradictions;
781
+ private checkInvalidRegex;
782
+ private walkItems;
783
+ }
784
+ //#endregion
785
+ //#region src/types/form-snapshot.d.ts
786
+ /**
787
+ * A point-in-time snapshot pairing a {@link FormDefinition} with a
788
+ * {@link FormDocument}.
789
+ *
790
+ * @property definition - The form schema that describes the structure.
791
+ * @property document - The filled form data.
792
+ */
793
+ type FormSnapshot = {
794
+ definition: FormDefinition;
795
+ document: FormDocument;
796
+ };
797
+ //#endregion
798
+ //#region src/form-engine.d.ts
799
+ /**
800
+ * The runtime form engine.
801
+ *
802
+ * Created by passing a {@link FormDefinition} to the constructor. The
803
+ * construction lifecycle is:
804
+ *
805
+ * 1. **Build field registry** -- walks the definition tree depth-first,
806
+ * creating a flat {@link FieldEntry} for every field and section while
807
+ * recording document-order ids in `contentOrder`.
808
+ * 2. **Semantic validation** -- checks for duplicate ids, excessive nesting,
809
+ * unknown/invalid condition references, constraint contradictions, and
810
+ * invalid regex patterns.
811
+ * 3. **Cycle detection** -- verifies that condition dependencies form a DAG
812
+ * (no circular references).
813
+ * 4. **Error reporting** -- if any issues were found in steps 2-3, throws a
814
+ * {@link DocumentError} containing all issues.
815
+ * 5. **Build dependency graph** -- creates a forward adjacency map so the
816
+ * engine can quickly determine which items are affected when a field
817
+ * value changes.
818
+ * 6. **Topological sort** -- orders all items so that dependencies are
819
+ * evaluated before dependents (used by `getVisibilityMap`).
820
+ * 7. **Assemble components** -- creates internal {@link ConditionEvaluator},
821
+ * {@link VisibilityResolver}, and {@link FieldValidator} instances.
822
+ *
823
+ * @example
824
+ * ```ts
825
+ * const engine = new FormEngine(myFormDefinition);
826
+ * const visibility = engine.getVisibilityMap(formValues);
827
+ * const result = engine.validate(formValues);
828
+ * ```
829
+ */
830
+ declare class FormEngine {
831
+ private readonly registry;
832
+ private readonly depGraph;
833
+ private readonly visibilityResolver;
834
+ private readonly fieldValidator;
835
+ private readonly definition;
836
+ private readonly formId;
837
+ private readonly formVersion;
838
+ /**
839
+ * Ordered list of all content item ids in depth-first document order.
840
+ * Matches the order in which items appear in the form definition.
841
+ */
842
+ readonly contentOrder: readonly number[];
843
+ /**
844
+ * Compiles a {@link FormDefinition} into a ready-to-use engine.
845
+ *
846
+ * @param definition - A complete form definition to compile.
847
+ * @throws {DocumentError} If the definition contains semantic issues
848
+ * or circular condition dependencies.
849
+ */
850
+ constructor(definition: FormDefinition);
851
+ /**
852
+ * Creates a {@link FormDocument} pre-populated with the form schema's
853
+ * id and version.
854
+ *
855
+ * @param values - Optional initial field values. Defaults to an empty object.
856
+ * @returns A new form document ready for use with engine methods.
857
+ */
858
+ createFormDocument(values?: FormValues): FormDocument;
859
+ /**
860
+ * Serializes the form definition and document into a single {@link FormSnapshot}.
861
+ *
862
+ * The snapshot contains the original {@link FormDefinition} used to construct
863
+ * the engine and the provided {@link FormDocument}. No validation is performed;
864
+ * call {@link validate} separately if needed.
865
+ *
866
+ * @param doc - The form document to include in the snapshot.
867
+ * @returns A snapshot containing both the definition and the document.
868
+ */
869
+ dumpDocument(doc: FormDocument): FormSnapshot;
870
+ /**
871
+ * Loads a {@link FormDocument} from a previously created {@link FormSnapshot}.
872
+ *
873
+ * Verifies that the snapshot's form definition matches the engine's
874
+ * compiled definition by comparing id and version. Throws a
875
+ * {@link DocumentError} if there is a mismatch.
876
+ *
877
+ * @param snapshot - A snapshot previously produced by {@link dumpDocument}.
878
+ * @returns The form document from the snapshot.
879
+ * @throws {DocumentError} If the snapshot's definition id or version
880
+ * does not match the engine's.
881
+ */
882
+ loadDocument(snapshot: FormSnapshot): FormDocument;
883
+ /**
884
+ * Determines whether a field or section is visible given the current form document.
885
+ *
886
+ * Evaluates the item's own condition and walks up the parent chain --
887
+ * an item is hidden if any ancestor is hidden.
888
+ *
889
+ * @param id - Numeric id of the field or section.
890
+ * @param doc - Current form document.
891
+ * @returns `true` if the item should be displayed, `false` otherwise.
892
+ */
893
+ isVisible(id: number, doc: FormDocument): boolean;
894
+ /**
895
+ * Computes visibility for every field and section in topological order.
896
+ *
897
+ * The resulting map is keyed by item id. Items whose conditions depend on
898
+ * other items are evaluated after their dependencies, ensuring correct
899
+ * cascading visibility (e.g. a hidden parent hides all children).
900
+ *
901
+ * @param doc - Current form document.
902
+ * @returns Map from item id to visibility boolean.
903
+ */
904
+ getVisibilityMap(doc: FormDocument): Map<number, boolean>;
905
+ /**
906
+ * Returns the set of item ids whose visibility may change when the
907
+ * specified field's value changes.
908
+ *
909
+ * Includes transitive dependents -- if field A controls field B, and
910
+ * field B controls field C, changing A returns `{B, C}`.
911
+ * Results are cached for the lifetime of the engine.
912
+ *
913
+ * @param fieldId - Id of the field that changed.
914
+ * @returns Set of affected item ids (does not include `fieldId` itself unless
915
+ * it is part of a dependency chain).
916
+ */
917
+ getAffectedIds(fieldId: number): Set<number>;
918
+ /**
919
+ * Validates form values against the schema's validation rules.
920
+ *
921
+ * Only visible fields are validated -- hidden fields are skipped entirely.
922
+ * Sections are never validated directly. For array fields, each item is
923
+ * validated individually according to the array's item definition.
924
+ *
925
+ * The reference time for relative date validation is derived from
926
+ * `doc.form.submittedAt`. If that value is missing or unparseable, a
927
+ * document-level error is reported and `new Date()` is used as fallback.
928
+ *
929
+ * @param doc - Current form document to validate.
930
+ * @returns Validation result with a `valid` flag and a `fieldErrors` map.
931
+ */
932
+ validate(doc: FormDocument): FormValidationResult;
933
+ /**
934
+ * Retrieves the internal {@link FieldEntry} for a given id.
935
+ *
936
+ * @param id - Numeric id of the field or section.
937
+ * @returns The field entry, or `undefined` if the id is not in the registry.
938
+ */
939
+ getFieldDef(id: number): FieldEntry | undefined;
940
+ private static parseNow;
941
+ private static walkContent;
942
+ }
943
+ //#endregion
944
+ //#region src/form-values-editor.d.ts
945
+ /**
946
+ * Mutable editor for building and modifying form values against a {@link FormDefinition}.
947
+ *
948
+ * Wraps a {@link FormEngine} and a mutable {@link FormDocument}. All mutating
949
+ * methods return `this` for fluent chaining.
950
+ *
951
+ * @example
952
+ * ```ts
953
+ * const editor = new FormValuesEditor(definition)
954
+ * editor
955
+ * .setFieldValue(1, 'Alice')
956
+ * .setFieldValue(2, 30)
957
+ * .setSubmittedAt('2025-01-01T00:00:00Z')
958
+ *
959
+ * const result = editor.validate()
960
+ * const doc = editor.toJSON()
961
+ * ```
962
+ */
963
+ declare class FormValuesEditor {
964
+ private readonly engine;
965
+ private doc;
966
+ /**
967
+ * Creates a new editor for the given form definition.
968
+ *
969
+ * @param definition - The form definition to edit values against.
970
+ * @param doc - An existing document to pre-populate. Deep-cloned internally.
971
+ * When omitted a blank document is created via {@link FormEngine.createFormDocument}.
972
+ */
973
+ constructor(definition: FormDefinition, doc?: FormDocument);
974
+ /**
975
+ * Returns the current value of a field.
976
+ *
977
+ * @param fieldId - Numeric id of the field.
978
+ * @returns The field value, or `undefined` if not set.
979
+ */
980
+ getFieldValue(fieldId: number): unknown;
981
+ /**
982
+ * Sets the value of a field.
983
+ *
984
+ * @param fieldId - Numeric id of the field.
985
+ * @param value - The value to set.
986
+ * @returns `this` for chaining.
987
+ * @throws If `fieldId` is unknown or references a section.
988
+ */
989
+ setFieldValue(fieldId: number, value: unknown): this;
990
+ /**
991
+ * Removes the value of a field.
992
+ *
993
+ * @param fieldId - Numeric id of the field.
994
+ * @returns `this` for chaining.
995
+ */
996
+ clearFieldValue(fieldId: number): this;
997
+ /**
998
+ * Appends an item to an array field.
999
+ *
1000
+ * If the field currently has no value, it is initialized to an empty array
1001
+ * before appending.
1002
+ *
1003
+ * @param fieldId - Numeric id of the array field.
1004
+ * @param value - The value to append. Defaults to `undefined`.
1005
+ * @returns `this` for chaining.
1006
+ * @throws If `fieldId` is not an array field.
1007
+ */
1008
+ addArrayItem(fieldId: number, value?: unknown): this;
1009
+ /**
1010
+ * Removes an item from an array field by index.
1011
+ *
1012
+ * @param fieldId - Numeric id of the array field.
1013
+ * @param index - Zero-based index of the item to remove.
1014
+ * @returns `this` for chaining.
1015
+ * @throws If `fieldId` is not an array field or the index is out of bounds.
1016
+ */
1017
+ removeArrayItem(fieldId: number, index: number): this;
1018
+ /**
1019
+ * Moves an item within an array field from one index to another.
1020
+ *
1021
+ * @param fieldId - Numeric id of the array field.
1022
+ * @param fromIndex - Current zero-based index of the item.
1023
+ * @param toIndex - Target zero-based index.
1024
+ * @returns `this` for chaining.
1025
+ * @throws If `fieldId` is not an array field or either index is out of bounds.
1026
+ */
1027
+ moveArrayItem(fieldId: number, fromIndex: number, toIndex: number): this;
1028
+ /**
1029
+ * Sets the value of an item at a specific index in an array field.
1030
+ *
1031
+ * @param fieldId - Numeric id of the array field.
1032
+ * @param index - Zero-based index of the item to set.
1033
+ * @param value - The new value for the item.
1034
+ * @returns `this` for chaining.
1035
+ * @throws If `fieldId` is not an array field or the index is out of bounds.
1036
+ */
1037
+ setArrayItem(fieldId: number, index: number, value: unknown): this;
1038
+ /**
1039
+ * Sets the `submittedAt` timestamp on the document.
1040
+ *
1041
+ * @param submittedAt - ISO 8601 timestamp string.
1042
+ * @returns `this` for chaining.
1043
+ */
1044
+ setSubmittedAt(submittedAt: string): this;
1045
+ /**
1046
+ * Validates the current document against the form definition.
1047
+ *
1048
+ * Delegates to {@link FormEngine.validate}.
1049
+ *
1050
+ * @returns The validation result.
1051
+ */
1052
+ validate(): FormValidationResult;
1053
+ /**
1054
+ * Computes visibility for every field and section.
1055
+ *
1056
+ * Delegates to {@link FormEngine.getVisibilityMap}.
1057
+ *
1058
+ * @returns Map from item id to visibility boolean.
1059
+ */
1060
+ getVisibilityMap(): Map<number, boolean>;
1061
+ /**
1062
+ * Determines whether a field or section is visible given current values.
1063
+ *
1064
+ * Delegates to {@link FormEngine.isVisible}.
1065
+ *
1066
+ * @param id - Numeric id of the field or section.
1067
+ * @returns `true` if the item should be displayed.
1068
+ */
1069
+ isVisible(id: number): boolean;
1070
+ /**
1071
+ * Returns a deep clone of the current form document.
1072
+ *
1073
+ * @returns A new serializable {@link FormDocument} instance.
1074
+ */
1075
+ toJSON(): FormDocument;
1076
+ /**
1077
+ * Asserts that `fieldId` exists in the registry and is not a section.
1078
+ */
1079
+ private assertField;
1080
+ /**
1081
+ * Asserts that `fieldId` is an array field and returns the current array value.
1082
+ * Throws if the field is not an array type or the current value is not an array.
1083
+ */
1084
+ private assertArray;
1085
+ /**
1086
+ * Returns the array value for `fieldId`, initializing to `[]` if not yet set.
1087
+ */
1088
+ private getOrInitArray;
1089
+ }
1090
+ //#endregion
1091
+ //#region src/types/errors.d.ts
1092
+ /**
1093
+ * Error thrown when form definition or document validation fails.
1094
+ *
1095
+ * Inspect {@link errors} for structured programmatic access to all
1096
+ * validation issues.
1097
+ *
1098
+ * @example
1099
+ * ```ts
1100
+ * try {
1101
+ * const engine = new FormEngine(definition);
1102
+ * } catch (err) {
1103
+ * if (err instanceof DocumentError) {
1104
+ * for (const e of err.errors) {
1105
+ * console.log(e.code, e.message);
1106
+ * }
1107
+ * }
1108
+ * }
1109
+ * ```
1110
+ */
1111
+ declare class DocumentError extends Error {
1112
+ /** Structured list of all validation errors. */
1113
+ readonly errors: DocumentValidationError[];
1114
+ /**
1115
+ * @param errors - One or more validation errors that caused the error.
1116
+ */
1117
+ constructor(errors: DocumentValidationError[]);
1118
+ }
1119
+ //#endregion
1120
+ //#region src/types/file-value.d.ts
1121
+ /**
1122
+ * Metadata for an uploaded file.
1123
+ *
1124
+ * The engine does not handle actual file upload -- the consumer handles upload
1125
+ * and produces the `FileValue` object.
1126
+ *
1127
+ * @property name - Original file name.
1128
+ * @property mimeType - MIME type of the file.
1129
+ * @property size - File size in bytes.
1130
+ * @property url - URL where the file can be accessed.
1131
+ */
1132
+ type FileValue = {
1133
+ name: string;
1134
+ mimeType: string;
1135
+ size: number;
1136
+ url: string;
1137
+ };
1138
+ //#endregion
1139
+ //#region src/visibility-resolver.d.ts
1140
+ /**
1141
+ * Computes field and section visibility for a form.
1142
+ *
1143
+ * Provides two modes of visibility computation:
1144
+ * - **Single-item** (`isVisible`): evaluates one item's condition plus its
1145
+ * parent chain. Does not use the hidden-field rule.
1146
+ * - **Bulk** (`getVisibilityMap`): evaluates all items in topological order
1147
+ * with the hidden-field rule applied (references to hidden fields are
1148
+ * treated as "not set").
1149
+ */
1150
+ declare class VisibilityResolver {
1151
+ private readonly registry;
1152
+ private readonly conditionEvaluator;
1153
+ private readonly topologicalOrder;
1154
+ /**
1155
+ * @param registry - The engine's field registry.
1156
+ * @param conditionEvaluator - Evaluator for condition trees.
1157
+ * @param topologicalOrder - Item ids in topological order (from {@link DependencyGraph}).
1158
+ */
1159
+ constructor(registry: Map<number, FieldEntry>, conditionEvaluator: ConditionEvaluator, topologicalOrder: number[]);
1160
+ /**
1161
+ * Determines whether a single field or section is visible.
1162
+ *
1163
+ * Evaluation logic:
1164
+ * 1. If the item has its own condition, evaluate it. If `false`, the item is hidden.
1165
+ * 2. If the item has a parent section, recursively check parent visibility.
1166
+ * An item is hidden whenever any ancestor is hidden.
1167
+ * 3. Items without conditions and without hidden parents are visible.
1168
+ *
1169
+ * Unlike {@link getVisibilityMap}, this method does not use the
1170
+ * pre-computed visibility map and does not apply the hidden-field rule.
1171
+ * Use it for one-off visibility checks; prefer `getVisibilityMap` when
1172
+ * evaluating many items at once.
1173
+ *
1174
+ * @param id - Numeric id of the field or section to check.
1175
+ * @param values - Current form values.
1176
+ * @param now - Reference date for relative date expressions.
1177
+ * @returns `true` if the item should be displayed.
1178
+ */
1179
+ isVisible(id: number, values: FormValues, now: Date): boolean;
1180
+ /**
1181
+ * Computes visibility for all fields and sections in a single pass.
1182
+ *
1183
+ * Iterates in topological order so that every item is evaluated after the
1184
+ * fields its condition depends on. This enables the **hidden-field rule**:
1185
+ * if a condition references a field that has already been determined hidden,
1186
+ * that field is treated as "not set".
1187
+ *
1188
+ * Cascading parent visibility is also enforced -- if a parent section is
1189
+ * hidden, all its children are immediately marked hidden without evaluating
1190
+ * their own conditions.
1191
+ *
1192
+ * @param values - Current form values.
1193
+ * @param now - Reference date for relative date expressions.
1194
+ * @returns Map from item id to visibility boolean (`true` = visible).
1195
+ */
1196
+ getVisibilityMap(values: FormValues, now: Date): Map<number, boolean>;
1197
+ }
1198
+ //#endregion
1199
+ export { type ArrayItemDef, type ArrayValidation, type BooleanValidation, type CompoundCondition, type Condition, ConditionEvaluator, type ContentItem, type ContentItemInfo, type ContentItemType, type DateValidation, DependencyGraph, DocumentError, type DocumentValidationError, type DocumentValidationErrorCode, type EvaluationContext, type FieldContentItem, type FieldDescriptor, type FieldEntry, type FieldType, type FieldValidationError, type FieldValidationRule, FieldValidator, type FileValidation, type FileValue, type FormDefinition, FormDefinitionEditor, FormDefinitionValidator, type FormDocument, FormEngine, type FormSnapshot, type FormValidationResult, type FormValues, FormValuesEditor, type NumberValidation, type SectionContentItem, type SectionDescriptor, type SelectOption, type SelectValidation, type SimpleCondition, type StringValidation, type TypeSpecificValidation, VisibilityResolver };
1200
+ //# sourceMappingURL=index.d.cts.map