@fogpipe/forma-core 0.6.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.
- package/README.md +169 -0
- package/dist/chunk-IRLYWN3R.js +790 -0
- package/dist/chunk-IRLYWN3R.js.map +1 -0
- package/dist/chunk-QTLXVG6P.js +135 -0
- package/dist/chunk-QTLXVG6P.js.map +1 -0
- package/dist/engine/index.cjs +885 -0
- package/dist/engine/index.cjs.map +1 -0
- package/dist/engine/index.d.cts +258 -0
- package/dist/engine/index.d.ts +258 -0
- package/dist/engine/index.js +32 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/feel/index.cjs +165 -0
- package/dist/feel/index.cjs.map +1 -0
- package/dist/feel/index.d.cts +105 -0
- package/dist/feel/index.d.ts +105 -0
- package/dist/feel/index.js +19 -0
- package/dist/feel/index.js.map +1 -0
- package/dist/index.cjs +962 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/types-Bs3CG9JZ.d.cts +283 -0
- package/dist/types-Bs3CG9JZ.d.ts +283 -0
- package/package.json +82 -0
- package/src/engine/calculate.ts +363 -0
- package/src/engine/enabled.ts +147 -0
- package/src/engine/index.ts +54 -0
- package/src/engine/required.ts +151 -0
- package/src/engine/validate.ts +647 -0
- package/src/engine/visibility.ts +228 -0
- package/src/feel/index.ts +299 -0
- package/src/index.ts +15 -0
- package/src/types.ts +364 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Forma Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* This module defines the complete type system for Forma specifications.
|
|
5
|
+
* All conditional logic uses FEEL (Friendly Enough Expression Language).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// FEEL Expression Type
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* FEEL expression - a string that will be evaluated at runtime.
|
|
14
|
+
*
|
|
15
|
+
* Available context variables:
|
|
16
|
+
* - `fieldName` - Any field value by name
|
|
17
|
+
* - `computed.name` - Computed value by name
|
|
18
|
+
* - `ref.path` - Reference data lookup (external lookup tables)
|
|
19
|
+
* - `item.fieldName` - Field within current array item
|
|
20
|
+
* - `itemIndex` - Current item index (0-based)
|
|
21
|
+
* - `value` - Current field value (in validation expressions)
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* "age >= 18"
|
|
25
|
+
* "claimType = \"Auto\" and wasDriver = true"
|
|
26
|
+
* "computed.bmi > 30"
|
|
27
|
+
* "item.frequency = \"daily\""
|
|
28
|
+
*/
|
|
29
|
+
export type FEELExpression = string;
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// JSON Schema Types
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Standard JSON Schema (subset we support)
|
|
37
|
+
*/
|
|
38
|
+
export interface JSONSchema {
|
|
39
|
+
type: "object";
|
|
40
|
+
properties: Record<string, JSONSchemaProperty>;
|
|
41
|
+
required?: string[];
|
|
42
|
+
$defs?: Record<string, JSONSchemaProperty>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type JSONSchemaProperty =
|
|
46
|
+
| JSONSchemaString
|
|
47
|
+
| JSONSchemaNumber
|
|
48
|
+
| JSONSchemaInteger
|
|
49
|
+
| JSONSchemaBoolean
|
|
50
|
+
| JSONSchemaArray
|
|
51
|
+
| JSONSchemaObject
|
|
52
|
+
| JSONSchemaEnum;
|
|
53
|
+
|
|
54
|
+
export interface JSONSchemaBase {
|
|
55
|
+
description?: string;
|
|
56
|
+
title?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface JSONSchemaString extends JSONSchemaBase {
|
|
60
|
+
type: "string";
|
|
61
|
+
minLength?: number;
|
|
62
|
+
maxLength?: number;
|
|
63
|
+
pattern?: string;
|
|
64
|
+
format?: "date" | "date-time" | "email" | "uri" | "uuid";
|
|
65
|
+
enum?: string[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface JSONSchemaNumber extends JSONSchemaBase {
|
|
69
|
+
type: "number";
|
|
70
|
+
minimum?: number;
|
|
71
|
+
maximum?: number;
|
|
72
|
+
exclusiveMinimum?: number;
|
|
73
|
+
exclusiveMaximum?: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface JSONSchemaInteger extends JSONSchemaBase {
|
|
77
|
+
type: "integer";
|
|
78
|
+
minimum?: number;
|
|
79
|
+
maximum?: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface JSONSchemaBoolean extends JSONSchemaBase {
|
|
83
|
+
type: "boolean";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface JSONSchemaArray extends JSONSchemaBase {
|
|
87
|
+
type: "array";
|
|
88
|
+
items: JSONSchemaProperty;
|
|
89
|
+
minItems?: number;
|
|
90
|
+
maxItems?: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface JSONSchemaObject extends JSONSchemaBase {
|
|
94
|
+
type: "object";
|
|
95
|
+
properties: Record<string, JSONSchemaProperty>;
|
|
96
|
+
required?: string[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface JSONSchemaEnum extends JSONSchemaBase {
|
|
100
|
+
type: "string";
|
|
101
|
+
enum: string[];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// Field Types
|
|
106
|
+
// ============================================================================
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Field type enumeration - maps to UI component types
|
|
110
|
+
*/
|
|
111
|
+
export type FieldType =
|
|
112
|
+
| "text"
|
|
113
|
+
| "password"
|
|
114
|
+
| "number"
|
|
115
|
+
| "integer"
|
|
116
|
+
| "boolean"
|
|
117
|
+
| "select"
|
|
118
|
+
| "multiselect"
|
|
119
|
+
| "date"
|
|
120
|
+
| "datetime"
|
|
121
|
+
| "email"
|
|
122
|
+
| "url"
|
|
123
|
+
| "textarea"
|
|
124
|
+
| "array"
|
|
125
|
+
| "object"
|
|
126
|
+
| "computed";
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Validation rule with FEEL expression
|
|
130
|
+
*/
|
|
131
|
+
export interface ValidationRule {
|
|
132
|
+
/** FEEL expression that should evaluate to true for valid data */
|
|
133
|
+
rule: FEELExpression;
|
|
134
|
+
/** Error message shown when validation fails */
|
|
135
|
+
message: string;
|
|
136
|
+
/** Severity level - errors block submission, warnings are informational */
|
|
137
|
+
severity?: "error" | "warning";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Option for select/multiselect fields
|
|
142
|
+
*/
|
|
143
|
+
export interface SelectOption {
|
|
144
|
+
/** Option value - can be string or number to match schema types */
|
|
145
|
+
value: string | number;
|
|
146
|
+
label: string;
|
|
147
|
+
/** When to show this option */
|
|
148
|
+
visibleWhen?: FEELExpression;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Field definition with all conditional logic
|
|
153
|
+
*/
|
|
154
|
+
export interface FieldDefinition {
|
|
155
|
+
/** Display label for the field */
|
|
156
|
+
label?: string;
|
|
157
|
+
/** Help text or description */
|
|
158
|
+
description?: string;
|
|
159
|
+
/** Placeholder text for input fields */
|
|
160
|
+
placeholder?: string;
|
|
161
|
+
/** Field type override (inferred from schema if not provided) */
|
|
162
|
+
type?: FieldType;
|
|
163
|
+
|
|
164
|
+
// Conditional logic (all FEEL expressions)
|
|
165
|
+
|
|
166
|
+
/** When to show this field. If omitted, always visible. */
|
|
167
|
+
visibleWhen?: FEELExpression;
|
|
168
|
+
/** When this field is required. If omitted, uses schema required. */
|
|
169
|
+
requiredWhen?: FEELExpression;
|
|
170
|
+
/** When this field is editable. If omitted, always enabled. */
|
|
171
|
+
enabledWhen?: FEELExpression;
|
|
172
|
+
|
|
173
|
+
// Validation rules (in addition to JSON Schema validation)
|
|
174
|
+
|
|
175
|
+
/** Custom validation rules using FEEL expressions */
|
|
176
|
+
validations?: ValidationRule[];
|
|
177
|
+
|
|
178
|
+
// Array-specific properties
|
|
179
|
+
|
|
180
|
+
/** For array fields: field definitions for each item. Requires type: "array" */
|
|
181
|
+
itemFields?: Record<string, FieldDefinition>;
|
|
182
|
+
/** Minimum number of items (overrides schema) */
|
|
183
|
+
minItems?: number;
|
|
184
|
+
/** Maximum number of items (overrides schema) */
|
|
185
|
+
maxItems?: number;
|
|
186
|
+
|
|
187
|
+
// Select field options
|
|
188
|
+
|
|
189
|
+
/** For select fields: available options */
|
|
190
|
+
options?: SelectOption[];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Computed field definition - derived values from form data
|
|
195
|
+
*/
|
|
196
|
+
export interface ComputedField {
|
|
197
|
+
/** FEEL expression to calculate the value */
|
|
198
|
+
expression: FEELExpression;
|
|
199
|
+
/** Display label */
|
|
200
|
+
label?: string;
|
|
201
|
+
/** Display format (e.g., "decimal(1)", "currency", "percent") */
|
|
202
|
+
format?: string;
|
|
203
|
+
/** Whether to display this value in the form */
|
|
204
|
+
display?: boolean;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Page definition for multi-step wizard forms
|
|
209
|
+
*/
|
|
210
|
+
export interface PageDefinition {
|
|
211
|
+
/** Unique page identifier */
|
|
212
|
+
id: string;
|
|
213
|
+
/** Page title */
|
|
214
|
+
title: string;
|
|
215
|
+
/** Page description/instructions */
|
|
216
|
+
description?: string;
|
|
217
|
+
/** When to show this page */
|
|
218
|
+
visibleWhen?: FEELExpression;
|
|
219
|
+
/** Field paths to include on this page */
|
|
220
|
+
fields: string[];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Form metadata
|
|
225
|
+
*/
|
|
226
|
+
export interface FormMeta {
|
|
227
|
+
/** Unique form identifier */
|
|
228
|
+
id: string;
|
|
229
|
+
/** Form title */
|
|
230
|
+
title: string;
|
|
231
|
+
/** Form description */
|
|
232
|
+
description?: string;
|
|
233
|
+
/** Form version */
|
|
234
|
+
version?: string;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Complete Form Specification
|
|
239
|
+
*
|
|
240
|
+
* This is the root type that defines an entire form including:
|
|
241
|
+
* - Data schema (JSON Schema)
|
|
242
|
+
* - Computed values
|
|
243
|
+
* - Reference data (lookup tables for calculations)
|
|
244
|
+
* - Field-level configuration and conditional logic
|
|
245
|
+
* - Field ordering
|
|
246
|
+
* - Optional wizard/page structure
|
|
247
|
+
*/
|
|
248
|
+
export interface Forma {
|
|
249
|
+
/** Schema version identifier */
|
|
250
|
+
$schema?: string;
|
|
251
|
+
/** Spec version */
|
|
252
|
+
version: "1.0";
|
|
253
|
+
/** Form metadata */
|
|
254
|
+
meta: FormMeta;
|
|
255
|
+
/** JSON Schema defining the data structure */
|
|
256
|
+
schema: JSONSchema;
|
|
257
|
+
/** Computed/calculated values */
|
|
258
|
+
computed?: Record<string, ComputedField>;
|
|
259
|
+
/** Reference data for lookups (external data sources, lookup tables) */
|
|
260
|
+
referenceData?: Record<string, unknown>;
|
|
261
|
+
/** Field-level definitions and rules */
|
|
262
|
+
fields: Record<string, FieldDefinition>;
|
|
263
|
+
/** Order in which fields should be displayed */
|
|
264
|
+
fieldOrder: string[];
|
|
265
|
+
/** Optional multi-page wizard structure */
|
|
266
|
+
pages?: PageDefinition[];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ============================================================================
|
|
270
|
+
// Evaluation Context
|
|
271
|
+
// ============================================================================
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Context provided when evaluating FEEL expressions
|
|
275
|
+
*/
|
|
276
|
+
export interface EvaluationContext {
|
|
277
|
+
/** Current form data */
|
|
278
|
+
data: Record<string, unknown>;
|
|
279
|
+
/** Computed values (calculated before field evaluation) */
|
|
280
|
+
computed?: Record<string, unknown>;
|
|
281
|
+
/** Reference data for lookups (external data sources, lookup tables) */
|
|
282
|
+
referenceData?: Record<string, unknown>;
|
|
283
|
+
/** Current array item (when evaluating within array context) */
|
|
284
|
+
item?: Record<string, unknown>;
|
|
285
|
+
/** Current array item index (0-based) */
|
|
286
|
+
itemIndex?: number;
|
|
287
|
+
/** Current field value (for validation expressions) */
|
|
288
|
+
value?: unknown;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ============================================================================
|
|
292
|
+
// Result Types
|
|
293
|
+
// ============================================================================
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Field visibility result - map of field path to visibility state
|
|
297
|
+
*/
|
|
298
|
+
export interface VisibilityResult {
|
|
299
|
+
[fieldPath: string]: boolean;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Required fields result - map of field path to required state
|
|
304
|
+
*/
|
|
305
|
+
export interface RequiredResult {
|
|
306
|
+
[fieldPath: string]: boolean;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Alias for RequiredResult (backwards compatibility)
|
|
311
|
+
*/
|
|
312
|
+
export type RequiredFieldsResult = RequiredResult;
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Enabled fields result - map of field path to enabled state
|
|
316
|
+
*/
|
|
317
|
+
export interface EnabledResult {
|
|
318
|
+
[fieldPath: string]: boolean;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Field validation error
|
|
323
|
+
*/
|
|
324
|
+
export interface FieldError {
|
|
325
|
+
/** Field path that has the error */
|
|
326
|
+
field: string;
|
|
327
|
+
/** Error message */
|
|
328
|
+
message: string;
|
|
329
|
+
/** Error severity */
|
|
330
|
+
severity: "error" | "warning";
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Validation result
|
|
335
|
+
*/
|
|
336
|
+
export interface ValidationResult {
|
|
337
|
+
/** Whether the form data is valid */
|
|
338
|
+
valid: boolean;
|
|
339
|
+
/** List of validation errors */
|
|
340
|
+
errors: FieldError[];
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Calculation error
|
|
345
|
+
*/
|
|
346
|
+
export interface CalculationError {
|
|
347
|
+
/** Computed field name */
|
|
348
|
+
field: string;
|
|
349
|
+
/** Error message */
|
|
350
|
+
message: string;
|
|
351
|
+
/** The expression that failed */
|
|
352
|
+
expression: string;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Calculation result with potential errors
|
|
357
|
+
*/
|
|
358
|
+
export interface CalculationResult {
|
|
359
|
+
/** Computed values */
|
|
360
|
+
values: Record<string, unknown>;
|
|
361
|
+
/** Errors encountered during calculation */
|
|
362
|
+
errors: CalculationError[];
|
|
363
|
+
}
|
|
364
|
+
|