@ng-forge/dynamic-form-mcp 0.6.0 → 0.6.1
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/bin/ng-forge-mcp.js +1126 -478
- package/package.json +1 -1
- package/src/index.js +1126 -479
- package/src/registry/documentation.d.ts +14 -0
- package/src/registry/documentation.d.ts.map +1 -0
- package/src/registry/field-types.d.ts +9 -0
- package/src/registry/field-types.d.ts.map +1 -0
- package/src/registry/index.d.ts +10 -16
- package/src/registry/index.d.ts.map +1 -1
- package/src/registry/instructions.d.ts +1 -1
- package/src/registry/instructions.d.ts.map +1 -1
- package/src/registry/ui-adapters.d.ts +9 -0
- package/src/registry/ui-adapters.d.ts.map +1 -0
- package/src/registry/validators.d.ts +9 -0
- package/src/registry/validators.d.ts.map +1 -0
- package/src/resources/documentation.resource.d.ts +2 -1
- package/src/resources/documentation.resource.d.ts.map +1 -1
- package/src/services/doc-fetcher.d.ts +34 -0
- package/src/services/doc-fetcher.d.ts.map +1 -0
- package/src/services/topic-mapper.d.ts +18 -0
- package/src/services/topic-mapper.d.ts.map +1 -0
- package/src/tools/data/lookup-topics.d.ts +5 -0
- package/src/tools/data/lookup-topics.d.ts.map +1 -1
- package/src/tools/examples.tool.d.ts +18 -0
- package/src/tools/examples.tool.d.ts.map +1 -1
- package/src/tools/index.d.ts +8 -6
- package/src/tools/index.d.ts.map +1 -1
- package/src/tools/lookup.tool.d.ts.map +1 -1
- package/src/tools/search.tool.d.ts +9 -0
- package/src/tools/search.tool.d.ts.map +1 -0
- package/src/tools/validate.tool.d.ts.map +1 -1
- package/src/registry/api-reference.json +0 -561
- package/src/registry/docs.json +0 -266
- package/src/registry/field-types.json +0 -502
- package/src/registry/ui-adapters.json +0 -225
- package/src/registry/validators.json +0 -210
|
@@ -1,561 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "1.0.0",
|
|
3
|
-
"description": "ng-forge Dynamic Forms API Reference - Compact format optimized for LLM consumption",
|
|
4
|
-
"logicMatrix": {
|
|
5
|
-
"description": "Logic support per field type. Y=supported, N=not supported",
|
|
6
|
-
"columns": ["hidden", "disabled", "required", "readonly", "derivation"],
|
|
7
|
-
"fields": {
|
|
8
|
-
"page": ["Y", "N", "N", "N", "N"],
|
|
9
|
-
"group": ["Y", "N", "N", "N", "N"],
|
|
10
|
-
"row": ["Y", "N", "N", "N", "N"],
|
|
11
|
-
"array": ["Y", "N", "N", "N", "N"],
|
|
12
|
-
"input": ["Y", "Y", "Y", "Y", "Y"],
|
|
13
|
-
"select": ["Y", "Y", "Y", "Y", "Y"],
|
|
14
|
-
"checkbox": ["Y", "Y", "Y", "Y", "Y"],
|
|
15
|
-
"radio": ["Y", "Y", "Y", "Y", "Y"],
|
|
16
|
-
"multi-checkbox": ["Y", "Y", "Y", "Y", "Y"],
|
|
17
|
-
"textarea": ["Y", "Y", "Y", "Y", "Y"],
|
|
18
|
-
"datepicker": ["Y", "Y", "Y", "Y", "Y"],
|
|
19
|
-
"toggle": ["Y", "Y", "Y", "Y", "Y"],
|
|
20
|
-
"slider": ["Y", "Y", "Y", "Y", "Y"],
|
|
21
|
-
"hidden": ["N", "N", "N", "N", "N"],
|
|
22
|
-
"text": ["Y", "N", "N", "N", "N"],
|
|
23
|
-
"button": ["Y", "Y", "N", "N", "N"],
|
|
24
|
-
"submit": ["Y", "Y", "N", "N", "N"],
|
|
25
|
-
"next": ["Y", "Y", "N", "N", "N"],
|
|
26
|
-
"previous": ["Y", "Y", "N", "N", "N"]
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"containerRules": {
|
|
30
|
-
"page": {
|
|
31
|
-
"hasLabel": false,
|
|
32
|
-
"supportsLogic": true,
|
|
33
|
-
"logicTypes": ["hidden"],
|
|
34
|
-
"allowedChildren": [
|
|
35
|
-
"row",
|
|
36
|
-
"group",
|
|
37
|
-
"array",
|
|
38
|
-
"input",
|
|
39
|
-
"select",
|
|
40
|
-
"checkbox",
|
|
41
|
-
"radio",
|
|
42
|
-
"multi-checkbox",
|
|
43
|
-
"textarea",
|
|
44
|
-
"datepicker",
|
|
45
|
-
"toggle",
|
|
46
|
-
"slider",
|
|
47
|
-
"hidden",
|
|
48
|
-
"text",
|
|
49
|
-
"button",
|
|
50
|
-
"submit",
|
|
51
|
-
"next",
|
|
52
|
-
"previous"
|
|
53
|
-
],
|
|
54
|
-
"notAllowedChildren": ["page"],
|
|
55
|
-
"notes": "Nav buttons (next/previous) go INSIDE page. ALL top-level fields must be pages if using multi-page mode."
|
|
56
|
-
},
|
|
57
|
-
"group": {
|
|
58
|
-
"hasLabel": false,
|
|
59
|
-
"supportsLogic": true,
|
|
60
|
-
"logicTypes": ["hidden"],
|
|
61
|
-
"allowedChildren": [
|
|
62
|
-
"row",
|
|
63
|
-
"input",
|
|
64
|
-
"select",
|
|
65
|
-
"checkbox",
|
|
66
|
-
"radio",
|
|
67
|
-
"multi-checkbox",
|
|
68
|
-
"textarea",
|
|
69
|
-
"datepicker",
|
|
70
|
-
"toggle",
|
|
71
|
-
"slider",
|
|
72
|
-
"hidden",
|
|
73
|
-
"text",
|
|
74
|
-
"button",
|
|
75
|
-
"submit"
|
|
76
|
-
],
|
|
77
|
-
"notAllowedChildren": ["page", "group"],
|
|
78
|
-
"notes": "Creates nested object in form value. Use 'fields', NOT 'children' or 'template'."
|
|
79
|
-
},
|
|
80
|
-
"row": {
|
|
81
|
-
"hasLabel": false,
|
|
82
|
-
"supportsLogic": true,
|
|
83
|
-
"logicTypes": ["hidden"],
|
|
84
|
-
"allowedChildren": [
|
|
85
|
-
"group",
|
|
86
|
-
"array",
|
|
87
|
-
"input",
|
|
88
|
-
"select",
|
|
89
|
-
"checkbox",
|
|
90
|
-
"radio",
|
|
91
|
-
"multi-checkbox",
|
|
92
|
-
"textarea",
|
|
93
|
-
"datepicker",
|
|
94
|
-
"toggle",
|
|
95
|
-
"slider",
|
|
96
|
-
"text",
|
|
97
|
-
"button",
|
|
98
|
-
"submit"
|
|
99
|
-
],
|
|
100
|
-
"notAllowedChildren": ["page", "row", "hidden"],
|
|
101
|
-
"notes": "Layout only. Use 'col' (1-12) on children. Hidden fields NOT allowed inside rows."
|
|
102
|
-
},
|
|
103
|
-
"array": {
|
|
104
|
-
"hasLabel": false,
|
|
105
|
-
"supportsLogic": true,
|
|
106
|
-
"logicTypes": ["hidden"],
|
|
107
|
-
"allowedChildren": [
|
|
108
|
-
"row",
|
|
109
|
-
"group",
|
|
110
|
-
"input",
|
|
111
|
-
"select",
|
|
112
|
-
"checkbox",
|
|
113
|
-
"radio",
|
|
114
|
-
"multi-checkbox",
|
|
115
|
-
"textarea",
|
|
116
|
-
"datepicker",
|
|
117
|
-
"toggle",
|
|
118
|
-
"slider",
|
|
119
|
-
"text"
|
|
120
|
-
],
|
|
121
|
-
"notAllowedChildren": ["page", "array", "hidden"],
|
|
122
|
-
"notes": "Use 'fields' (NOT 'template'). Supports minLength/maxLength for array size validation."
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
"fieldReference": {
|
|
126
|
-
"input": {
|
|
127
|
-
"category": "value",
|
|
128
|
-
"valueType": "string | number",
|
|
129
|
-
"fieldLevelProps": [
|
|
130
|
-
"key",
|
|
131
|
-
"type",
|
|
132
|
-
"label",
|
|
133
|
-
"value",
|
|
134
|
-
"required",
|
|
135
|
-
"email",
|
|
136
|
-
"min",
|
|
137
|
-
"max",
|
|
138
|
-
"minLength",
|
|
139
|
-
"maxLength",
|
|
140
|
-
"pattern",
|
|
141
|
-
"disabled",
|
|
142
|
-
"readonly",
|
|
143
|
-
"hidden",
|
|
144
|
-
"col",
|
|
145
|
-
"logic",
|
|
146
|
-
"validators",
|
|
147
|
-
"validationMessages",
|
|
148
|
-
"excludeValueIfHidden",
|
|
149
|
-
"excludeValueIfDisabled",
|
|
150
|
-
"excludeValueIfReadonly"
|
|
151
|
-
],
|
|
152
|
-
"propsObject": ["type", "placeholder", "appearance", "hint"],
|
|
153
|
-
"copyPaste": "{ type: 'input', key: 'name', label: 'Name', value: '' }",
|
|
154
|
-
"copyPasteEmail": "{ type: 'input', key: 'email', label: 'Email', required: true, email: true, props: { type: 'email' } }",
|
|
155
|
-
"copyPasteNumber": "{ type: 'input', key: 'age', label: 'Age', value: '', meta: { inputmode: 'numeric' } }"
|
|
156
|
-
},
|
|
157
|
-
"select": {
|
|
158
|
-
"category": "value",
|
|
159
|
-
"valueType": "T | T[]",
|
|
160
|
-
"fieldLevelProps": [
|
|
161
|
-
"key",
|
|
162
|
-
"type",
|
|
163
|
-
"label",
|
|
164
|
-
"value",
|
|
165
|
-
"options",
|
|
166
|
-
"required",
|
|
167
|
-
"disabled",
|
|
168
|
-
"readonly",
|
|
169
|
-
"hidden",
|
|
170
|
-
"col",
|
|
171
|
-
"logic",
|
|
172
|
-
"validators",
|
|
173
|
-
"validationMessages",
|
|
174
|
-
"excludeValueIfHidden",
|
|
175
|
-
"excludeValueIfDisabled",
|
|
176
|
-
"excludeValueIfReadonly"
|
|
177
|
-
],
|
|
178
|
-
"propsObject": ["multiple", "placeholder", "appearance"],
|
|
179
|
-
"copyPaste": "{ type: 'select', key: 'country', label: 'Country', options: [{ value: 'us', label: 'USA' }], value: 'us' }",
|
|
180
|
-
"pitfall": "options goes at FIELD level, NOT inside props"
|
|
181
|
-
},
|
|
182
|
-
"radio": {
|
|
183
|
-
"category": "value",
|
|
184
|
-
"valueType": "T",
|
|
185
|
-
"fieldLevelProps": [
|
|
186
|
-
"key",
|
|
187
|
-
"type",
|
|
188
|
-
"label",
|
|
189
|
-
"value",
|
|
190
|
-
"options",
|
|
191
|
-
"required",
|
|
192
|
-
"disabled",
|
|
193
|
-
"readonly",
|
|
194
|
-
"hidden",
|
|
195
|
-
"col",
|
|
196
|
-
"logic",
|
|
197
|
-
"validators",
|
|
198
|
-
"validationMessages",
|
|
199
|
-
"excludeValueIfHidden",
|
|
200
|
-
"excludeValueIfDisabled",
|
|
201
|
-
"excludeValueIfReadonly"
|
|
202
|
-
],
|
|
203
|
-
"propsObject": [],
|
|
204
|
-
"copyPaste": "{ type: 'radio', key: 'gender', label: 'Gender', options: [{ value: 'm', label: 'Male' }, { value: 'f', label: 'Female' }] }",
|
|
205
|
-
"pitfall": "options goes at FIELD level, NOT inside props"
|
|
206
|
-
},
|
|
207
|
-
"checkbox": {
|
|
208
|
-
"category": "value",
|
|
209
|
-
"valueType": "boolean",
|
|
210
|
-
"fieldLevelProps": [
|
|
211
|
-
"key",
|
|
212
|
-
"type",
|
|
213
|
-
"label",
|
|
214
|
-
"value",
|
|
215
|
-
"required",
|
|
216
|
-
"disabled",
|
|
217
|
-
"readonly",
|
|
218
|
-
"hidden",
|
|
219
|
-
"col",
|
|
220
|
-
"logic",
|
|
221
|
-
"validators",
|
|
222
|
-
"validationMessages",
|
|
223
|
-
"excludeValueIfHidden",
|
|
224
|
-
"excludeValueIfDisabled",
|
|
225
|
-
"excludeValueIfReadonly"
|
|
226
|
-
],
|
|
227
|
-
"propsObject": ["color"],
|
|
228
|
-
"copyPaste": "{ type: 'checkbox', key: 'accept', label: 'Accept terms', value: false }"
|
|
229
|
-
},
|
|
230
|
-
"multi-checkbox": {
|
|
231
|
-
"category": "value",
|
|
232
|
-
"valueType": "T[]",
|
|
233
|
-
"fieldLevelProps": [
|
|
234
|
-
"key",
|
|
235
|
-
"type",
|
|
236
|
-
"label",
|
|
237
|
-
"value",
|
|
238
|
-
"options",
|
|
239
|
-
"required",
|
|
240
|
-
"disabled",
|
|
241
|
-
"readonly",
|
|
242
|
-
"hidden",
|
|
243
|
-
"col",
|
|
244
|
-
"logic",
|
|
245
|
-
"validators",
|
|
246
|
-
"validationMessages",
|
|
247
|
-
"excludeValueIfHidden",
|
|
248
|
-
"excludeValueIfDisabled",
|
|
249
|
-
"excludeValueIfReadonly"
|
|
250
|
-
],
|
|
251
|
-
"propsObject": [],
|
|
252
|
-
"copyPaste": "{ type: 'multi-checkbox', key: 'tags', label: 'Tags', options: [{ value: 'a', label: 'A' }], value: [] }",
|
|
253
|
-
"pitfall": "value is an array, options at FIELD level"
|
|
254
|
-
},
|
|
255
|
-
"textarea": {
|
|
256
|
-
"category": "value",
|
|
257
|
-
"valueType": "string",
|
|
258
|
-
"fieldLevelProps": [
|
|
259
|
-
"key",
|
|
260
|
-
"type",
|
|
261
|
-
"label",
|
|
262
|
-
"value",
|
|
263
|
-
"required",
|
|
264
|
-
"minLength",
|
|
265
|
-
"maxLength",
|
|
266
|
-
"disabled",
|
|
267
|
-
"readonly",
|
|
268
|
-
"hidden",
|
|
269
|
-
"col",
|
|
270
|
-
"logic",
|
|
271
|
-
"validators",
|
|
272
|
-
"validationMessages",
|
|
273
|
-
"excludeValueIfHidden",
|
|
274
|
-
"excludeValueIfDisabled",
|
|
275
|
-
"excludeValueIfReadonly"
|
|
276
|
-
],
|
|
277
|
-
"propsObject": ["rows", "placeholder", "appearance"],
|
|
278
|
-
"copyPaste": "{ type: 'textarea', key: 'bio', label: 'Bio', props: { rows: 4 } }"
|
|
279
|
-
},
|
|
280
|
-
"datepicker": {
|
|
281
|
-
"category": "value",
|
|
282
|
-
"valueType": "Date | string",
|
|
283
|
-
"fieldLevelProps": [
|
|
284
|
-
"key",
|
|
285
|
-
"type",
|
|
286
|
-
"label",
|
|
287
|
-
"value",
|
|
288
|
-
"required",
|
|
289
|
-
"disabled",
|
|
290
|
-
"readonly",
|
|
291
|
-
"hidden",
|
|
292
|
-
"col",
|
|
293
|
-
"logic",
|
|
294
|
-
"validators",
|
|
295
|
-
"validationMessages",
|
|
296
|
-
"excludeValueIfHidden",
|
|
297
|
-
"excludeValueIfDisabled",
|
|
298
|
-
"excludeValueIfReadonly"
|
|
299
|
-
],
|
|
300
|
-
"propsObject": ["minDate", "maxDate", "startView", "appearance"],
|
|
301
|
-
"copyPaste": "{ type: 'datepicker', key: 'dob', label: 'Date of Birth', value: undefined }"
|
|
302
|
-
},
|
|
303
|
-
"toggle": {
|
|
304
|
-
"category": "value",
|
|
305
|
-
"valueType": "boolean",
|
|
306
|
-
"fieldLevelProps": [
|
|
307
|
-
"key",
|
|
308
|
-
"type",
|
|
309
|
-
"label",
|
|
310
|
-
"value",
|
|
311
|
-
"required",
|
|
312
|
-
"disabled",
|
|
313
|
-
"readonly",
|
|
314
|
-
"hidden",
|
|
315
|
-
"col",
|
|
316
|
-
"logic",
|
|
317
|
-
"validators",
|
|
318
|
-
"validationMessages",
|
|
319
|
-
"excludeValueIfHidden",
|
|
320
|
-
"excludeValueIfDisabled",
|
|
321
|
-
"excludeValueIfReadonly"
|
|
322
|
-
],
|
|
323
|
-
"propsObject": ["color"],
|
|
324
|
-
"copyPaste": "{ type: 'toggle', key: 'notify', label: 'Enable notifications', value: false }"
|
|
325
|
-
},
|
|
326
|
-
"slider": {
|
|
327
|
-
"category": "value",
|
|
328
|
-
"valueType": "number",
|
|
329
|
-
"fieldLevelProps": [
|
|
330
|
-
"key",
|
|
331
|
-
"type",
|
|
332
|
-
"label",
|
|
333
|
-
"value",
|
|
334
|
-
"minValue",
|
|
335
|
-
"maxValue",
|
|
336
|
-
"step",
|
|
337
|
-
"required",
|
|
338
|
-
"disabled",
|
|
339
|
-
"readonly",
|
|
340
|
-
"hidden",
|
|
341
|
-
"col",
|
|
342
|
-
"logic",
|
|
343
|
-
"validators",
|
|
344
|
-
"validationMessages",
|
|
345
|
-
"excludeValueIfHidden",
|
|
346
|
-
"excludeValueIfDisabled",
|
|
347
|
-
"excludeValueIfReadonly"
|
|
348
|
-
],
|
|
349
|
-
"propsObject": ["thumbLabel", "tickInterval", "color"],
|
|
350
|
-
"copyPaste": "{ type: 'slider', key: 'rating', label: 'Rating', minValue: 1, maxValue: 10, step: 1, value: 5 }",
|
|
351
|
-
"pitfall": "Use minValue/maxValue/step at FIELD level, NOT min/max in props"
|
|
352
|
-
},
|
|
353
|
-
"hidden": {
|
|
354
|
-
"category": "value",
|
|
355
|
-
"valueType": "T",
|
|
356
|
-
"fieldLevelProps": ["key", "type", "value"],
|
|
357
|
-
"propsObject": [],
|
|
358
|
-
"copyPaste": "{ type: 'hidden', key: 'userId', value: '123' }",
|
|
359
|
-
"doesNotSupport": ["logic", "validators", "required", "label"]
|
|
360
|
-
},
|
|
361
|
-
"text": {
|
|
362
|
-
"category": "display",
|
|
363
|
-
"valueType": null,
|
|
364
|
-
"fieldLevelProps": ["key", "type", "label", "hidden", "col", "logic"],
|
|
365
|
-
"propsObject": ["elementType"],
|
|
366
|
-
"copyPaste": "{ type: 'text', key: 'title', label: 'Section Title', props: { elementType: 'h2' } }",
|
|
367
|
-
"notes": "Content goes in 'label', NOT in props.content"
|
|
368
|
-
},
|
|
369
|
-
"group": {
|
|
370
|
-
"category": "container",
|
|
371
|
-
"valueType": "object",
|
|
372
|
-
"fieldLevelProps": ["key", "type", "fields", "logic"],
|
|
373
|
-
"propsObject": [],
|
|
374
|
-
"copyPaste": "{ type: 'group', key: 'address', fields: [{ type: 'input', key: 'city', label: 'City' }] }",
|
|
375
|
-
"doesNotSupport": ["label"],
|
|
376
|
-
"notes": "Only supports 'hidden' logic type for conditional visibility."
|
|
377
|
-
},
|
|
378
|
-
"row": {
|
|
379
|
-
"category": "container",
|
|
380
|
-
"valueType": null,
|
|
381
|
-
"fieldLevelProps": ["key", "type", "fields", "logic"],
|
|
382
|
-
"propsObject": [],
|
|
383
|
-
"copyPaste": "{ type: 'row', key: 'nameRow', fields: [{ type: 'input', key: 'first', label: 'First', col: 6 }, { type: 'input', key: 'last', label: 'Last', col: 6 }] }",
|
|
384
|
-
"doesNotSupport": ["label"],
|
|
385
|
-
"notes": "Only supports 'hidden' logic type for conditional visibility."
|
|
386
|
-
},
|
|
387
|
-
"array": {
|
|
388
|
-
"category": "container",
|
|
389
|
-
"valueType": "T[]",
|
|
390
|
-
"fieldLevelProps": ["key", "type", "fields", "logic", "minLength", "maxLength"],
|
|
391
|
-
"propsObject": [],
|
|
392
|
-
"copyPaste": "{ type: 'array', key: 'contacts', fields: [{ type: 'group', key: 'item', fields: [{ type: 'input', key: 'name', label: 'Name' }] }] }",
|
|
393
|
-
"doesNotSupport": ["label", "minItems", "maxItems", "template"],
|
|
394
|
-
"notes": "Only supports 'hidden' logic type for conditional visibility. Supports minLength/maxLength for array size validation."
|
|
395
|
-
},
|
|
396
|
-
"page": {
|
|
397
|
-
"category": "container",
|
|
398
|
-
"valueType": null,
|
|
399
|
-
"fieldLevelProps": ["key", "type", "fields", "logic"],
|
|
400
|
-
"propsObject": [],
|
|
401
|
-
"copyPaste": "{ type: 'page', key: 'step1', fields: [{ type: 'input', key: 'name', label: 'Name' }, { type: 'next', key: 'next', label: 'Next' }] }",
|
|
402
|
-
"doesNotSupport": ["label", "title"],
|
|
403
|
-
"notes": "Only supports hidden logic. Nav buttons go INSIDE each page."
|
|
404
|
-
},
|
|
405
|
-
"button": {
|
|
406
|
-
"category": "button",
|
|
407
|
-
"valueType": null,
|
|
408
|
-
"fieldLevelProps": ["key", "type", "label", "event", "hidden", "disabled", "col", "logic"],
|
|
409
|
-
"propsObject": [],
|
|
410
|
-
"copyPaste": "{ type: 'button', key: 'custom', label: 'Custom', event: MyCustomEvent }",
|
|
411
|
-
"pitfall": "Generic button REQUIRES 'event' property. Use submit/next/previous instead for common actions."
|
|
412
|
-
},
|
|
413
|
-
"submit": {
|
|
414
|
-
"category": "button",
|
|
415
|
-
"valueType": null,
|
|
416
|
-
"fieldLevelProps": ["key", "type", "label", "hidden", "disabled", "col", "logic"],
|
|
417
|
-
"propsObject": [],
|
|
418
|
-
"copyPaste": "{ type: 'submit', key: 'submit', label: 'Submit' }"
|
|
419
|
-
},
|
|
420
|
-
"next": {
|
|
421
|
-
"category": "button",
|
|
422
|
-
"valueType": null,
|
|
423
|
-
"fieldLevelProps": ["key", "type", "label", "hidden", "disabled", "col", "logic"],
|
|
424
|
-
"propsObject": [],
|
|
425
|
-
"copyPaste": "{ type: 'next', key: 'next', label: 'Next' }",
|
|
426
|
-
"notes": "Must be placed INSIDE a page's fields array"
|
|
427
|
-
},
|
|
428
|
-
"previous": {
|
|
429
|
-
"category": "button",
|
|
430
|
-
"valueType": null,
|
|
431
|
-
"fieldLevelProps": ["key", "type", "label", "hidden", "disabled", "col", "logic"],
|
|
432
|
-
"propsObject": [],
|
|
433
|
-
"copyPaste": "{ type: 'previous', key: 'back', label: 'Back' }",
|
|
434
|
-
"notes": "Must be placed INSIDE a page's fields array"
|
|
435
|
-
}
|
|
436
|
-
},
|
|
437
|
-
"validators": {
|
|
438
|
-
"shorthand": {
|
|
439
|
-
"description": "Use directly on field (no validators array needed)",
|
|
440
|
-
"list": ["required", "email", "min", "max", "minLength", "maxLength", "pattern"]
|
|
441
|
-
},
|
|
442
|
-
"fullSyntax": {
|
|
443
|
-
"description": "Use in validators array for custom logic",
|
|
444
|
-
"types": {
|
|
445
|
-
"required": "{ type: 'required' }",
|
|
446
|
-
"email": "{ type: 'email' }",
|
|
447
|
-
"min": "{ type: 'min', value: 0 }",
|
|
448
|
-
"max": "{ type: 'max', value: 100 }",
|
|
449
|
-
"minLength": "{ type: 'minLength', value: 3 }",
|
|
450
|
-
"maxLength": "{ type: 'maxLength', value: 50 }",
|
|
451
|
-
"pattern": "{ type: 'pattern', value: '^[A-Z]+$' }",
|
|
452
|
-
"custom": "{ type: 'custom', expression: 'fieldValue !== formValue.other', kind: 'errorKind' }",
|
|
453
|
-
"async": "{ type: 'async', functionName: 'checkAvailability' }",
|
|
454
|
-
"customAsync": "DEPRECATED — use type: 'async'. { type: 'customAsync', functionName: 'checkAvailability' }",
|
|
455
|
-
"http (function-based)": "{ type: 'http', functionName: 'validateOnServer' }",
|
|
456
|
-
"customHttp": "DEPRECATED — use type: 'http' with functionName. { type: 'customHttp', functionName: 'validateOnServer' }"
|
|
457
|
-
}
|
|
458
|
-
},
|
|
459
|
-
"errorMessages": {
|
|
460
|
-
"description": "Custom messages go in validationMessages at FIELD level, NOT in validator config",
|
|
461
|
-
"example": "validationMessages: { required: 'This is required', customKind: 'Custom error' }"
|
|
462
|
-
}
|
|
463
|
-
},
|
|
464
|
-
"logic": {
|
|
465
|
-
"types": ["hidden", "disabled", "required", "readonly", "derivation"],
|
|
466
|
-
"conditions": {
|
|
467
|
-
"fieldValue": "{ type: 'fieldValue', fieldPath: 'field.path', operator: 'equals', value: 'x' }",
|
|
468
|
-
"javascript": "{ type: 'javascript', expression: 'formValue.age >= 18' }",
|
|
469
|
-
"and": "{ type: 'and', conditions: [...] }",
|
|
470
|
-
"or": "{ type: 'or', conditions: [...] }",
|
|
471
|
-
"http": "{ type: 'http', http: { url: '/api/check', queryParams: { field: 'formValue.x' } }, responseExpression: 'response.allowed', pendingValue: false, cacheDurationMs: 30000, debounceMs: 300 }",
|
|
472
|
-
"async": "{ type: 'async', asyncFunctionName: 'myAsyncCheck', pendingValue: false, debounceMs: 300 }",
|
|
473
|
-
"custom": "{ type: 'custom', functionName: 'myConditionFn' }",
|
|
474
|
-
"true": "{ type: 'true' }",
|
|
475
|
-
"false": "{ type: 'false' }"
|
|
476
|
-
},
|
|
477
|
-
"operators": [
|
|
478
|
-
"equals",
|
|
479
|
-
"notEquals",
|
|
480
|
-
"greater",
|
|
481
|
-
"greaterOrEquals",
|
|
482
|
-
"less",
|
|
483
|
-
"lessOrEquals",
|
|
484
|
-
"contains",
|
|
485
|
-
"notContains",
|
|
486
|
-
"startsWith",
|
|
487
|
-
"endsWith",
|
|
488
|
-
"empty",
|
|
489
|
-
"notEmpty"
|
|
490
|
-
],
|
|
491
|
-
"buttonConditions": ["formInvalid", "formSubmitting", "pageInvalid"],
|
|
492
|
-
"derivationExample": "{ key: 'fullName', derivation: 'formValue.first + \" \" + formValue.last' }",
|
|
493
|
-
"httpDerivationExample": "{ key: 'rate', logic: [{ type: 'derivation', source: 'http', http: { url: '/api/rate', queryParams: { from: 'formValue.currency' } }, responseExpression: 'response.rate', dependsOn: ['currency'] }] }",
|
|
494
|
-
"httpDerivationRules": {
|
|
495
|
-
"source": "REQUIRED - use source: 'http' to select HTTP derivation mode",
|
|
496
|
-
"dependsOn": "REQUIRED - prevents wildcard triggering on every keystroke",
|
|
497
|
-
"responseExpression": "REQUIRED - extracts value from HTTP response body",
|
|
498
|
-
"noArrays": "Array fields (items.$.rate) are NOT supported for HTTP derivations"
|
|
499
|
-
},
|
|
500
|
-
"asyncFunctionDerivationExample": "{ key: 'price', logic: [{ type: 'derivation', source: 'asyncFunction', asyncFunctionName: 'fetchSuggestedPrice', dependsOn: ['productId', 'quantity'] }] }",
|
|
501
|
-
"asyncFunctionDerivationRules": {
|
|
502
|
-
"source": "REQUIRED - use source: 'asyncFunction' to select async derivation mode",
|
|
503
|
-
"dependsOn": "REQUIRED - prevents wildcard triggering on every form change",
|
|
504
|
-
"noWildcard": "Wildcards ('*') are NOT allowed in dependsOn for async derivations"
|
|
505
|
-
},
|
|
506
|
-
"expressionVariables": {
|
|
507
|
-
"formValue": "Complete form value object",
|
|
508
|
-
"fieldValue": "Current field's value"
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
"typeInference": {
|
|
512
|
-
"recommended": "const config = { fields: [...] } as const satisfies FormConfig;",
|
|
513
|
-
"pitfall1": "const config: FormConfig = {...} // Loses type inference - InferFormValue returns Record<string, unknown>",
|
|
514
|
-
"pitfall2": "const config = {...} satisfies FormConfig // Without 'as const', arrays are mutable, inference breaks",
|
|
515
|
-
"correct": "const config = { fields: [...] } as const satisfies FormConfig;\ntype Value = InferFormValue<typeof config>; // Exact shape!"
|
|
516
|
-
},
|
|
517
|
-
"arrayButtons": {
|
|
518
|
-
"description": "Button types for adding/removing array items (provided by UI adapter packages)",
|
|
519
|
-
"addArrayItem": {
|
|
520
|
-
"copyPaste": "{ type: 'addArrayItem', key: 'addItem', label: 'Add', arrayKey: 'myArray' }",
|
|
521
|
-
"fieldLevelProps": ["key", "type", "label", "arrayKey", "hidden", "disabled", "col", "logic"],
|
|
522
|
-
"pitfall": "arrayKey goes at FIELD level, NOT in props"
|
|
523
|
-
},
|
|
524
|
-
"removeArrayItem": {
|
|
525
|
-
"copyPaste": "{ type: 'removeArrayItem', key: 'removeItem', label: 'Remove' }",
|
|
526
|
-
"fieldLevelProps": ["key", "type", "label", "hidden", "disabled", "col", "logic"],
|
|
527
|
-
"notes": "Place inside array template. arrayKey is inferred from parent array."
|
|
528
|
-
}
|
|
529
|
-
},
|
|
530
|
-
"contextApi": {
|
|
531
|
-
"description": "CRITICAL: Different APIs for validators vs expressions!",
|
|
532
|
-
"expressions": {
|
|
533
|
-
"usedIn": ["logic[].expression", "derivation.expression", "javascript conditions"],
|
|
534
|
-
"variables": {
|
|
535
|
-
"formValue": "formValue.fieldName or formValue.path.to.field",
|
|
536
|
-
"fieldValue": "Current field's value"
|
|
537
|
-
},
|
|
538
|
-
"example": "expression: 'formValue.password === fieldValue'"
|
|
539
|
-
},
|
|
540
|
-
"validators": {
|
|
541
|
-
"usedIn": ["customFnConfig.validators (registered functions)"],
|
|
542
|
-
"api": "Angular FieldContext",
|
|
543
|
-
"methods": {
|
|
544
|
-
"ctx.value()": "Current field value",
|
|
545
|
-
"ctx.valueOf('path' as never)": "Value at path (requires cast)",
|
|
546
|
-
"ctx.state": "Field state (errors, touched, dirty)",
|
|
547
|
-
"ctx.stateOf('path' as never)": "State at path"
|
|
548
|
-
},
|
|
549
|
-
"example": "const password = ctx.valueOf('password' as never);",
|
|
550
|
-
"pitfall": "Do NOT use formValue in validators - use ctx.valueOf()"
|
|
551
|
-
}
|
|
552
|
-
},
|
|
553
|
-
"commonPitfalls": [
|
|
554
|
-
"Container fields (group, row, array) only support 'hidden' logic type - for other logic types (disabled, required, readonly, derivation), apply to children instead",
|
|
555
|
-
"options/minValue/maxValue/arrayKey go at FIELD level, NOT in props",
|
|
556
|
-
"Validators use ctx.value() and ctx.valueOf(), NOT formValue",
|
|
557
|
-
"Type annotation (: FormConfig) loses inference - use 'as const satisfies'",
|
|
558
|
-
"Generic button type requires 'event' property - use submit/next/previous instead",
|
|
559
|
-
"Array fields use 'fields' property, NOT 'template'"
|
|
560
|
-
]
|
|
561
|
-
}
|