@ng-forge/dynamic-form-mcp 0.5.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.
Files changed (50) hide show
  1. package/README.md +221 -0
  2. package/bin/ng-forge-mcp.d.ts +8 -0
  3. package/bin/ng-forge-mcp.d.ts.map +1 -0
  4. package/bin/ng-forge-mcp.js +10202 -0
  5. package/package.json +61 -0
  6. package/src/index.d.ts +14 -0
  7. package/src/index.d.ts.map +1 -0
  8. package/src/index.js +10265 -0
  9. package/src/registry/api-reference.json +510 -0
  10. package/src/registry/docs.json +230 -0
  11. package/src/registry/examples.json +629 -0
  12. package/src/registry/field-types.json +490 -0
  13. package/src/registry/index.d.ts +110 -0
  14. package/src/registry/index.d.ts.map +1 -0
  15. package/src/registry/instructions.d.ts +8 -0
  16. package/src/registry/instructions.d.ts.map +1 -0
  17. package/src/registry/ui-adapters.json +225 -0
  18. package/src/registry/validators.json +158 -0
  19. package/src/resources/documentation.resource.d.ts +8 -0
  20. package/src/resources/documentation.resource.d.ts.map +1 -0
  21. package/src/resources/examples.resource.d.ts +8 -0
  22. package/src/resources/examples.resource.d.ts.map +1 -0
  23. package/src/resources/field-types.resource.d.ts +8 -0
  24. package/src/resources/field-types.resource.d.ts.map +1 -0
  25. package/src/resources/index.d.ts +11 -0
  26. package/src/resources/index.d.ts.map +1 -0
  27. package/src/resources/instructions.resource.d.ts +8 -0
  28. package/src/resources/instructions.resource.d.ts.map +1 -0
  29. package/src/resources/schemas.resource.d.ts +9 -0
  30. package/src/resources/schemas.resource.d.ts.map +1 -0
  31. package/src/resources/ui-adapters.resource.d.ts +8 -0
  32. package/src/resources/ui-adapters.resource.d.ts.map +1 -0
  33. package/src/resources/validators.resource.d.ts +8 -0
  34. package/src/resources/validators.resource.d.ts.map +1 -0
  35. package/src/server.d.ts +22 -0
  36. package/src/server.d.ts.map +1 -0
  37. package/src/tools/data/lookup-topics.d.ts +18 -0
  38. package/src/tools/data/lookup-topics.d.ts.map +1 -0
  39. package/src/tools/examples.tool.d.ts +12 -0
  40. package/src/tools/examples.tool.d.ts.map +1 -0
  41. package/src/tools/index.d.ts +33 -0
  42. package/src/tools/index.d.ts.map +1 -0
  43. package/src/tools/lookup.tool.d.ts +15 -0
  44. package/src/tools/lookup.tool.d.ts.map +1 -0
  45. package/src/tools/scaffold.tool.d.ts +11 -0
  46. package/src/tools/scaffold.tool.d.ts.map +1 -0
  47. package/src/tools/validate.tool.d.ts +14 -0
  48. package/src/tools/validate.tool.d.ts.map +1 -0
  49. package/src/utils/ast-extractor.d.ts +88 -0
  50. package/src/utils/ast-extractor.d.ts.map +1 -0
@@ -0,0 +1,490 @@
1
+ [
2
+ {
3
+ "type": "input",
4
+ "category": "value",
5
+ "description": "Text-based input field with HTML5 type support (text, email, password, number, tel, url)",
6
+ "valueType": "string | number",
7
+ "baseInterface": "BaseValueField",
8
+ "props": {
9
+ "type": {
10
+ "name": "type",
11
+ "type": "'text' | 'email' | 'password' | 'number' | 'tel' | 'url'",
12
+ "description": "HTML input type",
13
+ "required": false,
14
+ "default": "text"
15
+ },
16
+ "placeholder": {
17
+ "name": "placeholder",
18
+ "type": "DynamicText",
19
+ "description": "Placeholder text displayed when field is empty",
20
+ "required": false
21
+ }
22
+ },
23
+ "validationSupported": true,
24
+ "source": "adapter",
25
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
26
+ "example": "{\n key: 'email',\n type: 'input',\n label: 'Email Address',\n required: true,\n email: true,\n props: { type: 'email', placeholder: 'user@example.com' }\n}",
27
+ "minimalExample": "{ key: 'name', type: 'input', label: 'Name' }"
28
+ },
29
+ {
30
+ "type": "textarea",
31
+ "category": "value",
32
+ "description": "Multi-line text input field for longer content",
33
+ "valueType": "string",
34
+ "baseInterface": "BaseValueField",
35
+ "props": {
36
+ "rows": {
37
+ "name": "rows",
38
+ "type": "number",
39
+ "description": "Number of visible text lines",
40
+ "required": false,
41
+ "default": 3
42
+ },
43
+ "placeholder": {
44
+ "name": "placeholder",
45
+ "type": "DynamicText",
46
+ "description": "Placeholder text displayed when field is empty",
47
+ "required": false
48
+ }
49
+ },
50
+ "validationSupported": true,
51
+ "source": "adapter",
52
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
53
+ "example": "{\n key: 'description',\n type: 'textarea',\n label: 'Description',\n props: { rows: 5, placeholder: 'Enter description...' }\n}",
54
+ "minimalExample": "{ key: 'bio', type: 'textarea', label: 'Bio' }"
55
+ },
56
+ {
57
+ "type": "select",
58
+ "category": "value",
59
+ "description": "Dropdown selection field with single or multiple selection",
60
+ "valueType": "T | T[]",
61
+ "baseInterface": "BaseValueField",
62
+ "props": {
63
+ "options": {
64
+ "name": "options",
65
+ "type": "FieldOption[]",
66
+ "description": "Array of selectable options with label and value. IMPORTANT: options goes at FIELD level, NOT inside props",
67
+ "required": true
68
+ },
69
+ "multiple": {
70
+ "name": "multiple",
71
+ "type": "boolean",
72
+ "description": "Allow multiple selections",
73
+ "required": false,
74
+ "default": false
75
+ },
76
+ "placeholder": {
77
+ "name": "placeholder",
78
+ "type": "DynamicText",
79
+ "description": "Placeholder text for empty selection",
80
+ "required": false
81
+ }
82
+ },
83
+ "validationSupported": true,
84
+ "source": "adapter",
85
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
86
+ "example": "{\n key: 'country',\n type: 'select',\n label: 'Country',\n required: true,\n options: [\n { label: 'United States', value: 'us' },\n { label: 'Canada', value: 'ca' }\n ]\n}",
87
+ "minimalExample": "{ key: 'status', type: 'select', label: 'Status', options: [{ label: 'Active', value: 'active' }] }"
88
+ },
89
+ {
90
+ "type": "checkbox",
91
+ "category": "value",
92
+ "description": "Boolean toggle checkbox field",
93
+ "valueType": "boolean",
94
+ "baseInterface": "BaseCheckedField",
95
+ "props": {},
96
+ "validationSupported": true,
97
+ "source": "adapter",
98
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
99
+ "example": "{\n key: 'acceptTerms',\n type: 'checkbox',\n label: 'I accept the terms and conditions',\n required: true\n}",
100
+ "minimalExample": "{ key: 'agree', type: 'checkbox', label: 'I agree' }"
101
+ },
102
+ {
103
+ "type": "multi-checkbox",
104
+ "category": "value",
105
+ "description": "Multiple checkbox group for selecting multiple values from options",
106
+ "valueType": "T[]",
107
+ "baseInterface": "BaseValueField",
108
+ "props": {
109
+ "options": {
110
+ "name": "options",
111
+ "type": "FieldOption[]",
112
+ "description": "Array of selectable options. IMPORTANT: options goes at FIELD level, NOT inside props",
113
+ "required": true
114
+ }
115
+ },
116
+ "validationSupported": true,
117
+ "source": "adapter",
118
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
119
+ "example": "{\n key: 'interests',\n type: 'multi-checkbox',\n label: 'Select your interests',\n options: [\n { label: 'Sports', value: 'sports' },\n { label: 'Music', value: 'music' },\n { label: 'Art', value: 'art' },\n { label: 'Technology', value: 'tech' }\n ]\n}",
120
+ "minimalExample": "{ key: 'tags', type: 'multi-checkbox', label: 'Tags', options: [{ label: 'A', value: 'a' }] }"
121
+ },
122
+ {
123
+ "type": "radio",
124
+ "category": "value",
125
+ "description": "Radio button group for single selection from options",
126
+ "valueType": "T",
127
+ "baseInterface": "BaseValueField",
128
+ "props": {
129
+ "options": {
130
+ "name": "options",
131
+ "type": "FieldOption[]",
132
+ "description": "Array of selectable options. IMPORTANT: options goes at FIELD level, NOT inside props",
133
+ "required": true
134
+ }
135
+ },
136
+ "validationSupported": true,
137
+ "source": "adapter",
138
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
139
+ "example": "{\n key: 'gender',\n type: 'radio',\n label: 'Gender',\n options: [\n { label: 'Male', value: 'male' },\n { label: 'Female', value: 'female' },\n { label: 'Other', value: 'other' }\n ]\n}",
140
+ "minimalExample": "{ key: 'choice', type: 'radio', label: 'Choice', options: [{ label: 'Yes', value: 'yes' }, { label: 'No', value: 'no' }] }"
141
+ },
142
+ {
143
+ "type": "datepicker",
144
+ "category": "value",
145
+ "description": "Date selection field with calendar picker",
146
+ "valueType": "Date | string",
147
+ "baseInterface": "BaseValueField",
148
+ "props": {
149
+ "minDate": {
150
+ "name": "minDate",
151
+ "type": "Date | string",
152
+ "description": "Minimum selectable date",
153
+ "required": false
154
+ },
155
+ "maxDate": {
156
+ "name": "maxDate",
157
+ "type": "Date | string",
158
+ "description": "Maximum selectable date",
159
+ "required": false
160
+ }
161
+ },
162
+ "validationSupported": true,
163
+ "source": "adapter",
164
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
165
+ "example": "{\n key: 'birthDate',\n type: 'datepicker',\n label: 'Date of Birth',\n required: true,\n props: { maxDate: new Date() }\n}",
166
+ "minimalExample": "{ key: 'date', type: 'datepicker', label: 'Date' }"
167
+ },
168
+ {
169
+ "type": "toggle",
170
+ "category": "value",
171
+ "description": "Switch/toggle control for boolean values",
172
+ "valueType": "boolean",
173
+ "baseInterface": "BaseCheckedField",
174
+ "props": {},
175
+ "validationSupported": true,
176
+ "source": "adapter",
177
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
178
+ "example": "{\n key: 'notifications',\n type: 'toggle',\n label: 'Enable notifications'\n}",
179
+ "minimalExample": "{ key: 'enabled', type: 'toggle', label: 'Enable' }"
180
+ },
181
+ {
182
+ "type": "slider",
183
+ "category": "value",
184
+ "description": "Numeric range slider for value selection",
185
+ "valueType": "number",
186
+ "baseInterface": "BaseValueField",
187
+ "props": {
188
+ "minValue": {
189
+ "name": "minValue",
190
+ "type": "number",
191
+ "description": "Minimum value. IMPORTANT: This is at FIELD level, NOT inside props",
192
+ "required": false,
193
+ "default": 0
194
+ },
195
+ "maxValue": {
196
+ "name": "maxValue",
197
+ "type": "number",
198
+ "description": "Maximum value. IMPORTANT: This is at FIELD level, NOT inside props",
199
+ "required": false,
200
+ "default": 100
201
+ },
202
+ "step": {
203
+ "name": "step",
204
+ "type": "number",
205
+ "description": "Step increment. IMPORTANT: This is at FIELD level, NOT inside props",
206
+ "required": false,
207
+ "default": 1
208
+ }
209
+ },
210
+ "validationSupported": true,
211
+ "source": "adapter",
212
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
213
+ "example": "{\n key: 'volume',\n type: 'slider',\n label: 'Volume',\n value: 50,\n minValue: 0,\n maxValue: 100,\n step: 5\n}",
214
+ "minimalExample": "{ key: 'rating', type: 'slider', label: 'Rating' }"
215
+ },
216
+ {
217
+ "type": "hidden",
218
+ "category": "value",
219
+ "description": "Hidden field that participates in form values without rendering. REQUIRED: The \"value\" property MUST be provided (string, number, boolean, or array). FORBIDDEN: label, logic, validators, required, props, disabled, readonly, hidden, col, tabIndex, meta - hidden fields are purely for passing values through the form. IMPORTANT: In multi-page forms, hidden fields must go INSIDE a page, not at the root level.",
220
+ "valueType": "string | number | boolean | (string | number | boolean)[]",
221
+ "baseInterface": "FieldDef",
222
+ "props": {},
223
+ "validationSupported": false,
224
+ "source": "core",
225
+ "allowedIn": ["top-level (single-page forms only)", "page.fields", "group.fields", "array.fields"],
226
+ "notAllowedIn": ["row", "top-level when using pages"],
227
+ "example": "// Hidden field - value is REQUIRED!\n{\n key: 'userId',\n type: 'hidden',\n value: 'abc123' // REQUIRED: string, number, boolean, or array\n}\n\n// Valid value types:\n{ key: 'count', type: 'hidden', value: 42 } // number\n{ key: 'active', type: 'hidden', value: true } // boolean\n{ key: 'tags', type: 'hidden', value: [1, 2, 3] } // array\n\n// ❌ FORBIDDEN (will cause validation error):\n// - label, logic, validators, required, props\n// - disabled, readonly, hidden, col, tabIndex, meta\n// - Validation shorthand: email, min, max, minLength, maxLength, pattern",
228
+ "minimalExample": "{ key: 'id', type: 'hidden', value: 'abc123' }"
229
+ },
230
+ {
231
+ "type": "text",
232
+ "category": "display",
233
+ "description": "Static text display element (headings, paragraphs, spans). The text content comes from the label property.",
234
+ "baseInterface": "FieldDef",
235
+ "props": {
236
+ "elementType": {
237
+ "name": "elementType",
238
+ "type": "'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span'",
239
+ "description": "HTML element type for rendering",
240
+ "required": false,
241
+ "default": "p"
242
+ }
243
+ },
244
+ "validationSupported": false,
245
+ "source": "core",
246
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
247
+ "example": "{\n key: 'sectionTitle',\n type: 'text',\n label: 'Personal Information',\n props: { elementType: 'h2' }\n}",
248
+ "minimalExample": "{ key: 'header', type: 'text', label: 'Section Title' }"
249
+ },
250
+ {
251
+ "type": "row",
252
+ "category": "container",
253
+ "description": "Horizontal layout container for grouping fields in columns. Rows do NOT have a label property and do NOT support logic blocks.",
254
+ "baseInterface": "FieldDef",
255
+ "props": {
256
+ "fields": {
257
+ "name": "fields",
258
+ "type": "RowAllowedChildren[]",
259
+ "description": "Child fields to render horizontally. Allowed: groups, arrays, VALUE fields (input, select, etc). NOT ALLOWED: pages, rows, hidden fields",
260
+ "required": true
261
+ }
262
+ },
263
+ "validationSupported": false,
264
+ "source": "core",
265
+ "allowedIn": ["top-level", "page", "group", "array"],
266
+ "notAllowedIn": ["row"],
267
+ "canContain": [
268
+ "group",
269
+ "array",
270
+ "input",
271
+ "textarea",
272
+ "select",
273
+ "checkbox",
274
+ "multi-checkbox",
275
+ "radio",
276
+ "datepicker",
277
+ "toggle",
278
+ "slider",
279
+ "text",
280
+ "button",
281
+ "submit",
282
+ "next",
283
+ "previous"
284
+ ],
285
+ "cannotContain": ["page", "row", "hidden"],
286
+ "example": "{\n key: 'nameRow',\n type: 'row',\n // NOTE: Rows do NOT have label or logic properties\n fields: [\n { key: 'firstName', type: 'input', label: 'First Name', col: 6 },\n { key: 'lastName', type: 'input', label: 'Last Name', col: 6 }\n ]\n}\n// NOT ALLOWED in rows:\n// - type: 'hidden' (hidden fields cannot be inside rows)\n// - type: 'page' (pages are top-level only)\n// - type: 'row' (no nested rows)",
287
+ "minimalExample": "{ key: 'row1', type: 'row', fields: [...] }"
288
+ },
289
+ {
290
+ "type": "group",
291
+ "category": "container",
292
+ "description": "Nested form group container creating a sub-object in form values. Groups are logical containers only and do NOT have a label property.",
293
+ "valueType": "object",
294
+ "baseInterface": "FieldDef",
295
+ "props": {
296
+ "fields": {
297
+ "name": "fields",
298
+ "type": "GroupAllowedChildren[]",
299
+ "description": "Child fields in the group. Allowed: rows, leaf fields (NOT pages or other groups)",
300
+ "required": true
301
+ }
302
+ },
303
+ "validationSupported": true,
304
+ "source": "core",
305
+ "allowedIn": ["top-level", "page", "row", "array"],
306
+ "notAllowedIn": ["group"],
307
+ "canContain": [
308
+ "row",
309
+ "input",
310
+ "textarea",
311
+ "select",
312
+ "checkbox",
313
+ "multi-checkbox",
314
+ "radio",
315
+ "datepicker",
316
+ "toggle",
317
+ "slider",
318
+ "hidden",
319
+ "text",
320
+ "button",
321
+ "submit",
322
+ "next",
323
+ "previous"
324
+ ],
325
+ "cannotContain": ["page", "group"],
326
+ "example": "{\n key: 'address',\n type: 'group',\n // NOTE: Groups do NOT have a label property\n fields: [\n { key: 'street', type: 'input', label: 'Street' },\n { key: 'city', type: 'input', label: 'City' },\n { key: 'zip', type: 'input', label: 'ZIP Code' }\n ]\n}",
327
+ "minimalExample": "{ key: 'address', type: 'group', fields: [...] }"
328
+ },
329
+ {
330
+ "type": "array",
331
+ "category": "container",
332
+ "description": "Repeatable field group for dynamic lists/arrays. Arrays do NOT have label, minItems, or maxItems properties. Use \"fields\" (not \"template\") to define the item template.",
333
+ "valueType": "T[]",
334
+ "baseInterface": "FieldDef",
335
+ "props": {
336
+ "fields": {
337
+ "name": "fields",
338
+ "type": "ArrayAllowedChildren[]",
339
+ "description": "Template field(s) for each array item. Allowed: rows, groups, leaf fields (NOT pages or other arrays)",
340
+ "required": true
341
+ }
342
+ },
343
+ "validationSupported": false,
344
+ "source": "core",
345
+ "allowedIn": ["top-level", "page", "row", "group"],
346
+ "notAllowedIn": ["array"],
347
+ "canContain": [
348
+ "row",
349
+ "group",
350
+ "input",
351
+ "textarea",
352
+ "select",
353
+ "checkbox",
354
+ "multi-checkbox",
355
+ "radio",
356
+ "datepicker",
357
+ "toggle",
358
+ "slider",
359
+ "hidden",
360
+ "text",
361
+ "button",
362
+ "submit",
363
+ "next",
364
+ "previous"
365
+ ],
366
+ "cannotContain": ["page", "array"],
367
+ "example": "// Flat array (primitive values)\n{\n key: 'tags',\n type: 'array',\n // NOTE: Arrays do NOT have label, minItems, or maxItems\n fields: [\n { key: 'tag', type: 'input', label: 'Tag' }\n ]\n}\n// Result: { tags: ['value1', 'value2'] }\n\n// Object array (nested groups)\n{\n key: 'contacts',\n type: 'array',\n fields: [{\n type: 'group',\n fields: [\n { key: 'name', type: 'input', label: 'Name' },\n { key: 'email', type: 'input', label: 'Email' }\n ]\n }]\n}\n// Result: { contacts: [{name: '', email: ''}, ...] }",
368
+ "minimalExample": "{ key: 'items', type: 'array', fields: [...] }"
369
+ },
370
+ {
371
+ "type": "page",
372
+ "category": "container",
373
+ "description": "Multi-step form page container for wizard-style forms. Pages do NOT have label or title properties. ALL top-level fields must be pages if using multi-page mode. IMPORTANT: Navigation buttons (next, previous) must be added as fields WITHIN each page that needs them.",
374
+ "baseInterface": "FieldDef",
375
+ "props": {
376
+ "fields": {
377
+ "name": "fields",
378
+ "type": "PageAllowedChildren[]",
379
+ "description": "Fields in this page. Allowed: rows, groups, arrays, leaf fields (NOT other pages). Include next/previous buttons as needed.",
380
+ "required": true
381
+ }
382
+ },
383
+ "validationSupported": false,
384
+ "source": "core",
385
+ "allowedIn": ["top-level"],
386
+ "notAllowedIn": ["page", "row", "group", "array"],
387
+ "canContain": [
388
+ "row",
389
+ "group",
390
+ "array",
391
+ "input",
392
+ "textarea",
393
+ "select",
394
+ "checkbox",
395
+ "multi-checkbox",
396
+ "radio",
397
+ "datepicker",
398
+ "toggle",
399
+ "slider",
400
+ "hidden",
401
+ "text",
402
+ "button",
403
+ "submit",
404
+ "next",
405
+ "previous"
406
+ ],
407
+ "cannotContain": ["page"],
408
+ "example": "{\n key: 'step1',\n type: 'page',\n // NOTE: Pages do NOT have label or title properties\n // Navigation buttons are fields WITHIN the page\n fields: [\n { key: 'firstName', type: 'input', label: 'First Name' },\n { key: 'lastName', type: 'input', label: 'Last Name' },\n { key: 'next', type: 'next', label: 'Next' }\n ]\n}",
409
+ "minimalExample": "{ key: 'step1', type: 'page', fields: [...] }"
410
+ },
411
+ {
412
+ "type": "next",
413
+ "category": "button",
414
+ "description": "Navigation button to go to next page in multi-step forms. Must be placed INSIDE a page's fields array.",
415
+ "baseInterface": "FieldDef",
416
+ "props": {},
417
+ "validationSupported": false,
418
+ "source": "adapter",
419
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
420
+ "example": "{\n key: 'next',\n type: 'next',\n label: 'Next'\n}",
421
+ "minimalExample": "{ key: 'next', type: 'next', label: 'Next' }"
422
+ },
423
+ {
424
+ "type": "previous",
425
+ "category": "button",
426
+ "description": "Navigation button to go to previous page in multi-step forms. Must be placed INSIDE a page's fields array.",
427
+ "baseInterface": "FieldDef",
428
+ "props": {},
429
+ "validationSupported": false,
430
+ "source": "adapter",
431
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
432
+ "example": "{\n key: 'back',\n type: 'previous',\n label: 'Back'\n}",
433
+ "minimalExample": "{ key: 'back', type: 'previous', label: 'Back' }"
434
+ },
435
+ {
436
+ "type": "button",
437
+ "category": "button",
438
+ "description": "Generic button for custom actions. IMPORTANT: The generic 'button' type REQUIRES the 'event' property with a FormEventConstructor. For simple use cases, prefer 'submit', 'next', or 'previous' which don't require event configuration.",
439
+ "baseInterface": "FieldDef",
440
+ "props": {
441
+ "event": {
442
+ "name": "event",
443
+ "type": "FormEventConstructor<TEvent>",
444
+ "description": "REQUIRED. Event constructor that will be emitted when button is clicked. Must be registered with provideFormEvents().",
445
+ "required": true
446
+ }
447
+ },
448
+ "validationSupported": false,
449
+ "source": "adapter",
450
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
451
+ "example": "// RECOMMENDED: Use pre-defined button types for common actions\n{ key: 'submit', type: 'submit', label: 'Submit Form' }\n{ key: 'next', type: 'next', label: 'Next' }\n{ key: 'back', type: 'previous', label: 'Back' }\n\n// ADVANCED: Generic button with custom event (requires setup)\n// 1. Create event class: class MyCustomEvent extends FormEvent {}\n// 2. Register with: provideFormEvents([MyCustomEvent])\n// 3. Use in config:\n{\n key: 'customAction',\n type: 'button',\n label: 'Custom Action',\n event: MyCustomEvent // Must be the class reference\n}",
452
+ "minimalExample": "{ key: 'action', type: 'button', label: 'Action', event: MyEvent }"
453
+ },
454
+ {
455
+ "type": "submit",
456
+ "category": "button",
457
+ "description": "Form submit button",
458
+ "baseInterface": "FieldDef",
459
+ "props": {},
460
+ "validationSupported": false,
461
+ "source": "adapter",
462
+ "allowedIn": ["top-level", "page", "row", "group", "array"],
463
+ "example": "{\n key: 'submit',\n type: 'submit',\n label: 'Submit Form'\n}",
464
+ "minimalExample": "{ key: 'submit', type: 'submit', label: 'Submit' }"
465
+ },
466
+ {
467
+ "type": "addArrayItem",
468
+ "category": "button",
469
+ "description": "Button to add a new item to an array field. Must be placed within or near the array container.",
470
+ "baseInterface": "FieldDef",
471
+ "props": {},
472
+ "validationSupported": false,
473
+ "source": "adapter",
474
+ "allowedIn": ["array", "row", "group"],
475
+ "example": "{\n key: 'addContact',\n type: 'addArrayItem',\n label: 'Add Contact'\n}",
476
+ "minimalExample": "{ key: 'add', type: 'addArrayItem', label: 'Add Item' }"
477
+ },
478
+ {
479
+ "type": "removeArrayItem",
480
+ "category": "button",
481
+ "description": "Button to remove the current item from an array field. Typically placed within each array item template.",
482
+ "baseInterface": "FieldDef",
483
+ "props": {},
484
+ "validationSupported": false,
485
+ "source": "adapter",
486
+ "allowedIn": ["array", "row", "group"],
487
+ "example": "{\n key: 'removeContact',\n type: 'removeArrayItem',\n label: 'Remove'\n}",
488
+ "minimalExample": "{ key: 'remove', type: 'removeArrayItem', label: 'Remove' }"
489
+ }
490
+ ]
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Registry module for loading generated JSON metadata
3
+ *
4
+ * This module provides access to field types, validators, and UI adapters
5
+ * that are generated at build time from the ng-forge packages.
6
+ *
7
+ * JSON data is imported directly to work correctly with esbuild bundling.
8
+ */
9
+ export interface PropertyInfo {
10
+ name: string;
11
+ type: string;
12
+ description: string;
13
+ required: boolean;
14
+ default?: unknown;
15
+ }
16
+ export interface FieldTypeInfo {
17
+ type: string;
18
+ category: 'value' | 'container' | 'button' | 'display';
19
+ description: string;
20
+ valueType?: string;
21
+ baseInterface?: string;
22
+ props: Record<string, PropertyInfo>;
23
+ validationSupported: boolean;
24
+ example: string;
25
+ /** Field types that this container can contain (for containers only) */
26
+ canContain?: string[];
27
+ /** Field types that this container CANNOT contain (for containers only) */
28
+ cannotContain?: string[];
29
+ /** Where this field type is allowed to be placed */
30
+ allowedIn?: string[];
31
+ /** Where this field type is NOT allowed to be placed */
32
+ notAllowedIn?: string[];
33
+ /** Whether this field type is part of core library or requires an adapter */
34
+ source: 'core' | 'adapter';
35
+ /** Minimal valid example (just required properties) */
36
+ minimalExample?: string;
37
+ }
38
+ export interface ValidatorInfo {
39
+ type: string;
40
+ category: 'built-in' | 'custom' | 'async' | 'http';
41
+ description: string;
42
+ parameters: Record<string, PropertyInfo>;
43
+ example: string;
44
+ }
45
+ export interface UIAdapterFieldType {
46
+ type: string;
47
+ componentName: string;
48
+ additionalProps: Record<string, PropertyInfo>;
49
+ }
50
+ export interface UIAdapterInfo {
51
+ library: string;
52
+ package: string;
53
+ fieldTypes: UIAdapterFieldType[];
54
+ providerFunction: string;
55
+ }
56
+ export interface DocTopic {
57
+ id: string;
58
+ title: string;
59
+ category: string;
60
+ content: string;
61
+ }
62
+ /**
63
+ * Get all available field types
64
+ */
65
+ export declare function getFieldTypes(): FieldTypeInfo[];
66
+ /**
67
+ * Get a specific field type by name
68
+ */
69
+ export declare function getFieldType(type: string): FieldTypeInfo | undefined;
70
+ /**
71
+ * Get field types by category
72
+ */
73
+ export declare function getFieldTypesByCategory(category: 'value' | 'container' | 'button' | 'display'): FieldTypeInfo[];
74
+ /**
75
+ * Get all available validators
76
+ */
77
+ export declare function getValidators(): ValidatorInfo[];
78
+ /**
79
+ * Get a specific validator by type
80
+ */
81
+ export declare function getValidator(type: string): ValidatorInfo | undefined;
82
+ /**
83
+ * Get validators by category
84
+ */
85
+ export declare function getValidatorsByCategory(category: 'built-in' | 'custom' | 'async' | 'http'): ValidatorInfo[];
86
+ /**
87
+ * Get all UI adapters
88
+ */
89
+ export declare function getUIAdapters(): UIAdapterInfo[];
90
+ /**
91
+ * Get a specific UI adapter by library name
92
+ */
93
+ export declare function getUIAdapter(library: 'material' | 'bootstrap' | 'primeng' | 'ionic'): UIAdapterInfo | undefined;
94
+ /**
95
+ * Get UI adapter field type configuration
96
+ */
97
+ export declare function getUIAdapterFieldType(library: 'material' | 'bootstrap' | 'primeng' | 'ionic', fieldType: string): UIAdapterFieldType | undefined;
98
+ /**
99
+ * Get all documentation topics
100
+ */
101
+ export declare function getDocs(): DocTopic[];
102
+ /**
103
+ * Get a specific documentation topic by ID
104
+ */
105
+ export declare function getDoc(id: string): DocTopic | undefined;
106
+ /**
107
+ * Get documentation topics by category
108
+ */
109
+ export declare function getDocsByCategory(category: string): DocTopic[];
110
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/dynamic-form-mcp/src/registry/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ng-forge Best Practices
3
+ *
4
+ * This content is served via the ng-forge://instructions resource
5
+ * to guide AI assistants in generating FormConfig objects.
6
+ */
7
+ export declare const INSTRUCTIONS = "# ng-forge Dynamic Forms - Best Practices\n\nYou MUST follow these practices when generating FormConfig objects for ng-forge.\n\n## Core Principles\n\n1. **Configuration-driven**: ng-forge wraps Angular Reactive Forms. Define structure declaratively via `FormConfig`, not imperatively.\n2. **Type-safe**: Use TypeScript interfaces for form values. The library provides full type inference.\n3. **Validation-first**: Always include validation and user-friendly error messages.\n\n## FormConfig Structure\n\n```typescript\nconst config: FormConfig = {\n // Optional: Default validation messages for all fields\n defaultValidationMessages: {\n required: 'This field is required',\n email: 'Please enter a valid email',\n minLength: 'Must be at least {{requiredLength}} characters',\n },\n // Required: Array of field definitions\n fields: [\n // ... field definitions\n ],\n};\n```\n\n## Field Definition Rules\n\n### Required Properties\n\nEvery field MUST have:\n\n- `key`: Unique identifier (except for `row` type which is layout-only)\n- `type`: One of the registered field types\n- `label`: Human-readable label (for accessibility)\n\n### Value Fields\n\nFor fields that collect user input (`input`, `textarea`, `select`, `checkbox`, `radio`, `datepicker`, `toggle`, `slider`):\n\n```typescript\n{\n key: 'email',\n type: 'input',\n label: 'Email Address',\n required: true, // Shorthand validator\n email: true, // Shorthand validator\n validationMessages: { // Always provide clear messages\n required: 'Email is required',\n email: 'Please enter a valid email'\n },\n props: {\n type: 'email', // HTML input type\n placeholder: 'user@example.com',\n hint: 'We will never share your email' // UI library specific\n }\n}\n```\n\n### Select/Radio Fields\n\nMUST include `options` array:\n\n```typescript\n{\n key: 'country',\n type: 'select',\n label: 'Country',\n required: true,\n options: [\n { value: 'us', label: 'United States' },\n { value: 'uk', label: 'United Kingdom' }\n ],\n props: { placeholder: 'Select a country' }\n}\n```\n\n### Container Fields\n\n#### Row (Horizontal Layout)\n\nUse for side-by-side fields. Row fields do NOT create nested values - children are flat.\n\n```typescript\n{\n key: 'nameRow',\n type: 'row',\n fields: [\n { key: 'firstName', type: 'input', label: 'First', col: 6 },\n { key: 'lastName', type: 'input', label: 'Last', col: 6 }\n ]\n}\n// Result: { firstName: '...', lastName: '...' }\n```\n\nUse `col` property (1-12) to control column widths.\n\n#### Group (Nested Object)\n\nUse when you need nested object structure in form values:\n\n```typescript\n{\n key: 'address',\n type: 'group',\n fields: [\n { key: 'street', type: 'input', label: 'Street' },\n { key: 'city', type: 'input', label: 'City' }\n ]\n}\n// Result: { address: { street: '...', city: '...' } }\n```\n\n#### Array (Repeatable Items)\n\nUse for dynamic lists:\n\n```typescript\n{\n key: 'contacts',\n type: 'array',\n label: 'Emergency Contacts',\n fields: [\n {\n key: 'contact',\n type: 'group',\n fields: [\n { key: 'name', type: 'input', label: 'Name', required: true },\n { key: 'phone', type: 'input', label: 'Phone', required: true }\n ]\n }\n ]\n}\n// Result: { contacts: [{ name: '...', phone: '...' }, ...] }\n```\n\n#### Page (Multi-step Forms)\n\nUse for wizard-style forms:\n\n```typescript\n{\n fields: [\n {\n key: 'step1',\n type: 'page',\n fields: [\n { key: 'name', type: 'input', label: 'Name' },\n { key: 'next', type: 'next', label: 'Continue' },\n ],\n },\n {\n key: 'step2',\n type: 'page',\n fields: [\n { key: 'prev', type: 'previous', label: 'Back' },\n { key: 'submit', type: 'submit', label: 'Submit' },\n ],\n },\n ];\n}\n```\n\n## Validation\n\n### Shorthand Validators (Preferred)\n\nUse shorthand properties directly on field definitions:\n\n```typescript\n{\n key: 'age',\n type: 'input',\n label: 'Age',\n required: true,\n min: 18,\n max: 120,\n validationMessages: {\n required: 'Age is required',\n min: 'Must be at least {{min}}',\n max: 'Cannot exceed {{max}}'\n }\n}\n```\n\nAvailable shorthands: `required`, `email`, `min`, `max`, `minLength`, `maxLength`, `pattern`\n\n### Validation Messages\n\nALWAYS provide validation messages. Use template variables:\n\n- `{{requiredLength}}` - for minLength/maxLength\n- `{{min}}`, `{{max}}` - for min/max\n- `{{requiredPattern}}` - for pattern\n\n## Conditional Logic\n\nUse `logic` array for conditional behavior:\n\n```typescript\n{\n key: 'businessName',\n type: 'input',\n label: 'Business Name',\n logic: [\n {\n type: 'hidden',\n condition: {\n type: 'fieldValue',\n fieldPath: 'accountType',\n operator: 'notEquals',\n value: 'business'\n }\n },\n {\n type: 'required',\n condition: {\n type: 'fieldValue',\n fieldPath: 'accountType',\n operator: 'equals',\n value: 'business'\n }\n }\n ]\n}\n```\n\n### Logic Types\n\n- `hidden` - Show/hide field\n- `disabled` - Enable/disable field\n- `required` - Conditional requirement\n\n### Condition Operators\n\n- `equals`, `notEquals`\n- `greaterThan`, `lessThan`, `greaterThanOrEquals`, `lessThanOrEquals`\n- `contains`, `notContains`\n- `empty`, `notEmpty`\n\n## UI Library Integration\n\nng-forge supports multiple UI libraries. Configure in `app.config.ts`:\n\n```typescript\nimport { provideDynamicForm } from '@ng-forge/dynamic-forms';\nimport { withMaterialFields } from '@ng-forge/dynamic-forms-material';\n\nexport const appConfig = {\n providers: [provideDynamicForm(...withMaterialFields())],\n};\n```\n\nAvailable adapters:\n\n- `@ng-forge/dynamic-forms-material` - Angular Material\n- `@ng-forge/dynamic-forms-bootstrap` - Bootstrap 5\n- `@ng-forge/dynamic-forms-primeng` - PrimeNG\n- `@ng-forge/dynamic-forms-ionic` - Ionic\n\n## Common Patterns\n\n### Always End with Submit Button\n\n```typescript\n{ type: 'submit', key: 'submit', label: 'Submit', props: { color: 'primary' } }\n```\n\n### Use Text Fields for Headings\n\n```typescript\n{ key: 'sectionTitle', type: 'text', label: 'Personal Info', props: { elementType: 'h3' } }\n```\n\n### Input Types via Props\n\n```typescript\n// Email input\n{ key: 'email', type: 'input', props: { type: 'email' } }\n\n// Password input\n{ key: 'password', type: 'input', props: { type: 'password' } }\n\n// Number input\n{ key: 'age', type: 'input', props: { type: 'number' } }\n\n// Phone input\n{ key: 'phone', type: 'input', props: { type: 'tel' } }\n```\n\n## Anti-patterns to Avoid\n\n1. **Missing labels** - Always include labels for accessibility\n2. **Missing validation messages** - Users need clear feedback\n3. **Duplicate keys** - Each key must be unique within its scope\n4. **Select without options** - Select/radio fields must have options\n5. **Array without fields** - Array fields need a fields template\n6. **Group without fields** - Group fields need child fields\n7. **min > max** - Ensure min values are less than max values\n\n## CRITICAL: UI Library Differences\n\nDifferent UI libraries support different properties. Always validate against the correct library using `ngforge_validate_form_config` with the appropriate `uiIntegration` parameter.\n\n### Property Differences by Library\n\n| Property | Material | Bootstrap | PrimeNG | Ionic |\n|----------|----------|-----------|---------|-------|\n| `appearance` | \u2713 (fill, outline) | \u2717 | \u2717 | \u2713 (fill, outline) |\n| `subscriptSizing` | \u2713 | \u2717 | \u2717 | \u2717 |\n| `floatLabel` | \u2713 | \u2717 | \u2713 | \u2717 |\n| `hint` | \u2713 | \u2713 (as `helpText`) | \u2713 | \u2713 |\n\n### Container Fields\n\nContainer fields (`page`, `group`, `row`) do NOT support these properties:\n- `label` - Use `text` field type for headings instead\n- `required`, `email`, `min`, `max`, etc. - Validation is for leaf fields only\n\n### Common Mistakes to Avoid\n\n1. **Using `expressions` on fields** - This property is NOT supported on standard fields. Use `derivation` for computed values or `logic` for conditional behavior.\n\n2. **Adding `label` to container fields** - Pages, groups, and rows don't have labels:\n ```typescript\n // \u274C WRONG\n { key: 'address', type: 'group', label: 'Address', fields: [...] }\n\n // \u2705 CORRECT - Use a text field for the heading\n { key: 'addressTitle', type: 'text', label: 'Address', props: { elementType: 'h3' } }\n { key: 'address', type: 'group', fields: [...] }\n ```\n\n3. **Adding `id` to FormConfig** - The root FormConfig does not accept an `id` property.\n\n4. **Putting slider min/max in props** - For slider fields, `min`, `max`, and `step` are field-level properties:\n ```typescript\n // \u274C WRONG\n { key: 'volume', type: 'slider', label: 'Volume', props: { min: 0, max: 100 } }\n\n // \u2705 CORRECT\n { key: 'volume', type: 'slider', label: 'Volume', min: 0, max: 100 }\n ```\n\n5. **Using unsupported field types** - Each UI library supports specific field types. Use `ngforge_get_field_schema` to see available types.\n\n## Validation Before Use\n\nAlways validate your FormConfig using the `ngforge_validate_form_config` tool before using it. This tool uses the actual TypeScript/Zod schemas, so if validation passes, the config will work correctly at runtime.\n\n```typescript\n// Always specify the UI integration you're using\nngforge_validate_form_config({\n uiIntegration: 'material', // or 'bootstrap', 'primeng', 'ionic'\n config: { fields: [...] }\n})\n```\n\nTo understand what properties are supported for each field type, use `ngforge_get_field_schema`:\n\n```typescript\nngforge_get_field_schema({ uiIntegration: 'material' })\n```\n";
8
+ //# sourceMappingURL=instructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../../../../packages/dynamic-form-mcp/src/registry/instructions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,YAAY,4rTA4WxB,CAAC"}