@ng-forge/dynamic-form-mcp 1.0.0-rc.4 → 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.
- package/LICENSE +21 -0
- package/README.md +24 -25
- package/bin/ng-forge-mcp.js +308 -68
- package/index.d.ts +252 -0
- package/package.json +15 -12
- package/src/index.js +308 -68
- package/src/registry/addons.d.ts +3 -2
- package/src/registry/addons.d.ts.map +1 -1
- package/src/registry/field-types.d.ts.map +1 -1
- package/src/registry/index.d.ts +3 -2
- 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/resources/schemas.resource.d.ts.map +1 -1
- package/src/resources/ui-adapters.resource.d.ts.map +1 -1
- package/src/tools/data/lookup-topics.d.ts.map +1 -1
package/src/index.js
CHANGED
|
@@ -648,9 +648,9 @@ var FIELD_TYPES = [
|
|
|
648
648
|
minimalExample: `{ key: 'submit', type: 'submit', label: 'Submit' }`
|
|
649
649
|
},
|
|
650
650
|
{
|
|
651
|
-
type: "
|
|
651
|
+
type: "add-array-item",
|
|
652
652
|
category: "button",
|
|
653
|
-
description: "Button to
|
|
653
|
+
description: "Button to append a new item to the end of an array field. Must be placed within or near the array container. (Legacy alias: addArrayItem.)",
|
|
654
654
|
valueType: void 0,
|
|
655
655
|
baseInterface: "FieldDef",
|
|
656
656
|
props: {},
|
|
@@ -659,15 +659,50 @@ var FIELD_TYPES = [
|
|
|
659
659
|
allowedIn: ["array", "row", "group"],
|
|
660
660
|
example: `{
|
|
661
661
|
key: 'addContact',
|
|
662
|
-
type: '
|
|
662
|
+
type: 'add-array-item',
|
|
663
663
|
label: 'Add Contact'
|
|
664
664
|
}`,
|
|
665
|
-
minimalExample: `{ key: 'add', type: '
|
|
665
|
+
minimalExample: `{ key: 'add', type: 'add-array-item', label: 'Add Item' }`
|
|
666
666
|
},
|
|
667
667
|
{
|
|
668
|
-
type: "
|
|
668
|
+
type: "prepend-array-item",
|
|
669
669
|
category: "button",
|
|
670
|
-
description: "Button to
|
|
670
|
+
description: "Button to add a new item to the beginning of an array field. (Legacy alias: prependArrayItem.)",
|
|
671
|
+
valueType: void 0,
|
|
672
|
+
baseInterface: "FieldDef",
|
|
673
|
+
props: {},
|
|
674
|
+
validationSupported: false,
|
|
675
|
+
source: "adapter",
|
|
676
|
+
allowedIn: ["array", "row", "group"],
|
|
677
|
+
example: `{
|
|
678
|
+
key: 'prependContact',
|
|
679
|
+
type: 'prepend-array-item',
|
|
680
|
+
label: 'Add to Top'
|
|
681
|
+
}`,
|
|
682
|
+
minimalExample: `{ key: 'prepend', type: 'prepend-array-item', label: 'Add First' }`
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
type: "insert-array-item",
|
|
686
|
+
category: "button",
|
|
687
|
+
description: "Button to insert a new item at a specific index in an array field (set via the index property). (Legacy alias: insertArrayItem.)",
|
|
688
|
+
valueType: void 0,
|
|
689
|
+
baseInterface: "FieldDef",
|
|
690
|
+
props: {},
|
|
691
|
+
validationSupported: false,
|
|
692
|
+
source: "adapter",
|
|
693
|
+
allowedIn: ["array", "row", "group"],
|
|
694
|
+
example: `{
|
|
695
|
+
key: 'insertContact',
|
|
696
|
+
type: 'insert-array-item',
|
|
697
|
+
label: 'Insert',
|
|
698
|
+
index: 1
|
|
699
|
+
}`,
|
|
700
|
+
minimalExample: `{ key: 'insert', type: 'insert-array-item', label: 'Insert', index: 0 }`
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
type: "remove-array-item",
|
|
704
|
+
category: "button",
|
|
705
|
+
description: "Button to remove the current item from an array field. Typically placed within each array item template. (Legacy alias: removeArrayItem.)",
|
|
671
706
|
valueType: void 0,
|
|
672
707
|
baseInterface: "FieldDef",
|
|
673
708
|
props: {},
|
|
@@ -676,10 +711,46 @@ var FIELD_TYPES = [
|
|
|
676
711
|
allowedIn: ["array", "row", "group"],
|
|
677
712
|
example: `{
|
|
678
713
|
key: 'removeContact',
|
|
679
|
-
type: '
|
|
714
|
+
type: 'remove-array-item',
|
|
680
715
|
label: 'Remove'
|
|
681
716
|
}`,
|
|
682
|
-
minimalExample: `{ key: 'remove', type: '
|
|
717
|
+
minimalExample: `{ key: 'remove', type: 'remove-array-item', label: 'Remove' }`
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
type: "pop-array-item",
|
|
721
|
+
category: "button",
|
|
722
|
+
description: "Button to remove the last item from an array field. (Legacy alias: popArrayItem.)",
|
|
723
|
+
valueType: void 0,
|
|
724
|
+
baseInterface: "FieldDef",
|
|
725
|
+
props: {},
|
|
726
|
+
validationSupported: false,
|
|
727
|
+
source: "adapter",
|
|
728
|
+
allowedIn: ["array", "row", "group"],
|
|
729
|
+
example: `{
|
|
730
|
+
key: 'popContact',
|
|
731
|
+
type: 'pop-array-item',
|
|
732
|
+
label: 'Remove Last',
|
|
733
|
+
arrayKey: 'contacts'
|
|
734
|
+
}`,
|
|
735
|
+
minimalExample: `{ key: 'pop', type: 'pop-array-item', label: 'Remove Last', arrayKey: 'items' }`
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
type: "shift-array-item",
|
|
739
|
+
category: "button",
|
|
740
|
+
description: "Button to remove the first item from an array field. (Legacy alias: shiftArrayItem.)",
|
|
741
|
+
valueType: void 0,
|
|
742
|
+
baseInterface: "FieldDef",
|
|
743
|
+
props: {},
|
|
744
|
+
validationSupported: false,
|
|
745
|
+
source: "adapter",
|
|
746
|
+
allowedIn: ["array", "row", "group"],
|
|
747
|
+
example: `{
|
|
748
|
+
key: 'shiftContact',
|
|
749
|
+
type: 'shift-array-item',
|
|
750
|
+
label: 'Remove First',
|
|
751
|
+
arrayKey: 'contacts'
|
|
752
|
+
}`,
|
|
753
|
+
minimalExample: `{ key: 'shift', type: 'shift-array-item', label: 'Remove First', arrayKey: 'items' }`
|
|
683
754
|
}
|
|
684
755
|
];
|
|
685
756
|
|
|
@@ -1470,7 +1541,7 @@ var WRAPPERS = [
|
|
|
1470
1541
|
category: "demo",
|
|
1471
1542
|
availability: "demo-only",
|
|
1472
1543
|
package: "@internal/examples-shared-ui",
|
|
1473
|
-
description: 'Demo wrapper used by the docs sandbox. Wraps an array field in a titled card whose header contains an "Add" button \u2014 the wrapper owns the append behaviour, dispatching `arrayEvent(key).append(itemTemplate)` on click via the `EventBus`. Lets the consumer config drop the separate `
|
|
1544
|
+
description: 'Demo wrapper used by the docs sandbox. Wraps an array field in a titled card whose header contains an "Add" button \u2014 the wrapper owns the append behaviour, dispatching `arrayEvent(key).append(itemTemplate)` on click via the `EventBus`. Lets the consumer config drop the separate `add-array-item` button field. NOT a shipping primitive; copy the component out of `internal/examples-shared-ui/src/lib/demo-wrappers/` or author your own if you want this pattern in production.',
|
|
1474
1545
|
props: {
|
|
1475
1546
|
title: {
|
|
1476
1547
|
name: "title",
|
|
@@ -3037,7 +3108,7 @@ All features are exported from \`@ng-forge/dynamic-forms\`.
|
|
|
3037
3108
|
|
|
3038
3109
|
## CRITICAL: UI Library Differences
|
|
3039
3110
|
|
|
3040
|
-
Different UI libraries support different properties. Always validate against the correct library using \`
|
|
3111
|
+
Different UI libraries support different properties. Always validate against the correct library using \`ngforge_validate\` with the appropriate \`uiIntegration\` parameter.
|
|
3041
3112
|
|
|
3042
3113
|
### Property Differences by Library
|
|
3043
3114
|
|
|
@@ -3080,24 +3151,24 @@ Container fields (\`page\`, \`group\`, \`row\`) do NOT support these properties:
|
|
|
3080
3151
|
{ key: 'volume', type: 'slider', label: 'Volume', min: 0, max: 100 }
|
|
3081
3152
|
\`\`\`
|
|
3082
3153
|
|
|
3083
|
-
5. **Using unsupported field types** - Each UI library supports specific field types. Use \`
|
|
3154
|
+
5. **Using unsupported field types** - Each UI library supports specific field types. Use \`ngforge_lookup\` with \`depth: "schema"\` to see available types.
|
|
3084
3155
|
|
|
3085
3156
|
## Validation Before Use
|
|
3086
3157
|
|
|
3087
|
-
Always validate your FormConfig using the \`
|
|
3158
|
+
Always validate your FormConfig using the \`ngforge_validate\` tool before using it. This tool uses the actual TypeScript/Zod schemas, so if validation passes, the config will work correctly at runtime.
|
|
3088
3159
|
|
|
3089
3160
|
\`\`\`typescript
|
|
3090
3161
|
// Always specify the UI integration you're using
|
|
3091
|
-
|
|
3162
|
+
ngforge_validate({
|
|
3092
3163
|
uiIntegration: 'material', // or 'bootstrap', 'primeng', 'ionic'
|
|
3093
3164
|
config: { fields: [...] }
|
|
3094
3165
|
})
|
|
3095
3166
|
\`\`\`
|
|
3096
3167
|
|
|
3097
|
-
To understand what properties are supported for each field type, use \`
|
|
3168
|
+
To understand what properties are supported for each field type, use \`ngforge_lookup\` with \`depth: "schema"\`:
|
|
3098
3169
|
|
|
3099
3170
|
\`\`\`typescript
|
|
3100
|
-
|
|
3171
|
+
ngforge_lookup({ topic: 'input', depth: 'schema', uiIntegration: 'material' })
|
|
3101
3172
|
\`\`\`
|
|
3102
3173
|
`;
|
|
3103
3174
|
|
|
@@ -5213,7 +5284,7 @@ var MatPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5213
5284
|
props: MatButtonPropsSchema.optional()
|
|
5214
5285
|
});
|
|
5215
5286
|
var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5216
|
-
type: z33.literal("
|
|
5287
|
+
type: z33.literal("add-array-item"),
|
|
5217
5288
|
/**
|
|
5218
5289
|
* Key of the array field to add items to.
|
|
5219
5290
|
* If omitted, uses the parent array context.
|
|
@@ -5222,7 +5293,7 @@ var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5222
5293
|
props: MatButtonPropsSchema.optional()
|
|
5223
5294
|
});
|
|
5224
5295
|
var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5225
|
-
type: z33.literal("
|
|
5296
|
+
type: z33.literal("remove-array-item"),
|
|
5226
5297
|
/**
|
|
5227
5298
|
* Key of the array field to remove items from.
|
|
5228
5299
|
* If omitted, uses the parent array context.
|
|
@@ -5230,6 +5301,44 @@ var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5230
5301
|
arrayKey: z33.string().optional(),
|
|
5231
5302
|
props: MatButtonPropsSchema.optional()
|
|
5232
5303
|
});
|
|
5304
|
+
var MatPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5305
|
+
type: z33.literal("prepend-array-item"),
|
|
5306
|
+
/**
|
|
5307
|
+
* Key of the array field to prepend items to.
|
|
5308
|
+
* If omitted, uses the parent array context.
|
|
5309
|
+
*/
|
|
5310
|
+
arrayKey: z33.string().optional(),
|
|
5311
|
+
props: MatButtonPropsSchema.optional()
|
|
5312
|
+
});
|
|
5313
|
+
var MatInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5314
|
+
type: z33.literal("insert-array-item"),
|
|
5315
|
+
/**
|
|
5316
|
+
* Key of the array field to insert items into.
|
|
5317
|
+
* If omitted, uses the parent array context.
|
|
5318
|
+
*/
|
|
5319
|
+
arrayKey: z33.string().optional(),
|
|
5320
|
+
/**
|
|
5321
|
+
* Index at which to insert the new item.
|
|
5322
|
+
*/
|
|
5323
|
+
index: z33.number(),
|
|
5324
|
+
props: MatButtonPropsSchema.optional()
|
|
5325
|
+
});
|
|
5326
|
+
var MatPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5327
|
+
type: z33.literal("pop-array-item"),
|
|
5328
|
+
/**
|
|
5329
|
+
* Key of the array field to pop items from.
|
|
5330
|
+
*/
|
|
5331
|
+
arrayKey: z33.string(),
|
|
5332
|
+
props: MatButtonPropsSchema.optional()
|
|
5333
|
+
});
|
|
5334
|
+
var MatShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5335
|
+
type: z33.literal("shift-array-item"),
|
|
5336
|
+
/**
|
|
5337
|
+
* Key of the array field to shift items from.
|
|
5338
|
+
*/
|
|
5339
|
+
arrayKey: z33.string(),
|
|
5340
|
+
props: MatButtonPropsSchema.optional()
|
|
5341
|
+
});
|
|
5233
5342
|
|
|
5234
5343
|
// internal/dynamic-forms-zod/material/src/mat-leaf-field.schema.ts
|
|
5235
5344
|
import { z as z36 } from "zod";
|
|
@@ -5305,7 +5414,11 @@ var MatLeafFieldSchema = z36.discriminatedUnion("type", [
|
|
|
5305
5414
|
MatNextButtonFieldSchema,
|
|
5306
5415
|
MatPreviousButtonFieldSchema,
|
|
5307
5416
|
MatAddArrayItemButtonFieldSchema,
|
|
5308
|
-
MatRemoveArrayItemButtonFieldSchema
|
|
5417
|
+
MatRemoveArrayItemButtonFieldSchema,
|
|
5418
|
+
MatPrependArrayItemButtonFieldSchema,
|
|
5419
|
+
MatInsertArrayItemButtonFieldSchema,
|
|
5420
|
+
MatPopArrayItemButtonFieldSchema,
|
|
5421
|
+
MatShiftArrayItemButtonFieldSchema
|
|
5309
5422
|
]).superRefine(nullableValueRefine);
|
|
5310
5423
|
|
|
5311
5424
|
// internal/dynamic-forms-zod/src/lib/schemas/containers/factories.ts
|
|
@@ -5773,13 +5886,34 @@ var BsPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5773
5886
|
props: BsButtonPropsSchema.optional()
|
|
5774
5887
|
});
|
|
5775
5888
|
var BsAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5776
|
-
type: z44.literal("
|
|
5889
|
+
type: z44.literal("add-array-item"),
|
|
5777
5890
|
arrayKey: z44.string().optional(),
|
|
5778
5891
|
props: BsButtonPropsSchema.optional()
|
|
5779
5892
|
});
|
|
5780
5893
|
var BsRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5781
|
-
type: z44.literal("
|
|
5894
|
+
type: z44.literal("remove-array-item"),
|
|
5895
|
+
arrayKey: z44.string().optional(),
|
|
5896
|
+
props: BsButtonPropsSchema.optional()
|
|
5897
|
+
});
|
|
5898
|
+
var BsPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5899
|
+
type: z44.literal("prepend-array-item"),
|
|
5900
|
+
arrayKey: z44.string().optional(),
|
|
5901
|
+
props: BsButtonPropsSchema.optional()
|
|
5902
|
+
});
|
|
5903
|
+
var BsInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5904
|
+
type: z44.literal("insert-array-item"),
|
|
5782
5905
|
arrayKey: z44.string().optional(),
|
|
5906
|
+
index: z44.number(),
|
|
5907
|
+
props: BsButtonPropsSchema.optional()
|
|
5908
|
+
});
|
|
5909
|
+
var BsPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5910
|
+
type: z44.literal("pop-array-item"),
|
|
5911
|
+
arrayKey: z44.string(),
|
|
5912
|
+
props: BsButtonPropsSchema.optional()
|
|
5913
|
+
});
|
|
5914
|
+
var BsShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5915
|
+
type: z44.literal("shift-array-item"),
|
|
5916
|
+
arrayKey: z44.string(),
|
|
5783
5917
|
props: BsButtonPropsSchema.optional()
|
|
5784
5918
|
});
|
|
5785
5919
|
|
|
@@ -5802,7 +5936,11 @@ var BsLeafFieldSchema = z45.discriminatedUnion("type", [
|
|
|
5802
5936
|
BsNextButtonFieldSchema,
|
|
5803
5937
|
BsPreviousButtonFieldSchema,
|
|
5804
5938
|
BsAddArrayItemButtonFieldSchema,
|
|
5805
|
-
BsRemoveArrayItemButtonFieldSchema
|
|
5939
|
+
BsRemoveArrayItemButtonFieldSchema,
|
|
5940
|
+
BsPrependArrayItemButtonFieldSchema,
|
|
5941
|
+
BsInsertArrayItemButtonFieldSchema,
|
|
5942
|
+
BsPopArrayItemButtonFieldSchema,
|
|
5943
|
+
BsShiftArrayItemButtonFieldSchema
|
|
5806
5944
|
]).superRefine(nullableValueRefine);
|
|
5807
5945
|
|
|
5808
5946
|
// internal/dynamic-forms-zod/bootstrap/src/bs-form-config.schema.ts
|
|
@@ -5985,15 +6123,36 @@ var PrimePreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5985
6123
|
props: PrimeButtonPropsSchema.optional()
|
|
5986
6124
|
});
|
|
5987
6125
|
var PrimeAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5988
|
-
type: z48.literal("
|
|
6126
|
+
type: z48.literal("add-array-item"),
|
|
5989
6127
|
arrayKey: z48.string().optional(),
|
|
5990
6128
|
props: PrimeButtonPropsSchema.optional()
|
|
5991
6129
|
});
|
|
5992
6130
|
var PrimeRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5993
|
-
type: z48.literal("
|
|
6131
|
+
type: z48.literal("remove-array-item"),
|
|
5994
6132
|
arrayKey: z48.string().optional(),
|
|
5995
6133
|
props: PrimeButtonPropsSchema.optional()
|
|
5996
6134
|
});
|
|
6135
|
+
var PrimePrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6136
|
+
type: z48.literal("prepend-array-item"),
|
|
6137
|
+
arrayKey: z48.string().optional(),
|
|
6138
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6139
|
+
});
|
|
6140
|
+
var PrimeInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6141
|
+
type: z48.literal("insert-array-item"),
|
|
6142
|
+
arrayKey: z48.string().optional(),
|
|
6143
|
+
index: z48.number(),
|
|
6144
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6145
|
+
});
|
|
6146
|
+
var PrimePopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6147
|
+
type: z48.literal("pop-array-item"),
|
|
6148
|
+
arrayKey: z48.string(),
|
|
6149
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6150
|
+
});
|
|
6151
|
+
var PrimeShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6152
|
+
type: z48.literal("shift-array-item"),
|
|
6153
|
+
arrayKey: z48.string(),
|
|
6154
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6155
|
+
});
|
|
5997
6156
|
|
|
5998
6157
|
// internal/dynamic-forms-zod/primeng/src/prime-leaf-field.schema.ts
|
|
5999
6158
|
import { z as z49 } from "zod";
|
|
@@ -6014,7 +6173,11 @@ var PrimeLeafFieldSchema = z49.discriminatedUnion("type", [
|
|
|
6014
6173
|
PrimeNextButtonFieldSchema,
|
|
6015
6174
|
PrimePreviousButtonFieldSchema,
|
|
6016
6175
|
PrimeAddArrayItemButtonFieldSchema,
|
|
6017
|
-
PrimeRemoveArrayItemButtonFieldSchema
|
|
6176
|
+
PrimeRemoveArrayItemButtonFieldSchema,
|
|
6177
|
+
PrimePrependArrayItemButtonFieldSchema,
|
|
6178
|
+
PrimeInsertArrayItemButtonFieldSchema,
|
|
6179
|
+
PrimePopArrayItemButtonFieldSchema,
|
|
6180
|
+
PrimeShiftArrayItemButtonFieldSchema
|
|
6018
6181
|
]).superRefine(nullableValueRefine);
|
|
6019
6182
|
|
|
6020
6183
|
// internal/dynamic-forms-zod/primeng/src/prime-form-config.schema.ts
|
|
@@ -6239,15 +6402,36 @@ var IonicPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
6239
6402
|
props: IonicButtonPropsSchema.optional()
|
|
6240
6403
|
});
|
|
6241
6404
|
var IonicAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6242
|
-
type: z52.literal("
|
|
6405
|
+
type: z52.literal("add-array-item"),
|
|
6243
6406
|
arrayKey: z52.string().optional(),
|
|
6244
6407
|
props: IonicButtonPropsSchema.optional()
|
|
6245
6408
|
});
|
|
6246
6409
|
var IonicRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6247
|
-
type: z52.literal("
|
|
6410
|
+
type: z52.literal("remove-array-item"),
|
|
6411
|
+
arrayKey: z52.string().optional(),
|
|
6412
|
+
props: IonicButtonPropsSchema.optional()
|
|
6413
|
+
});
|
|
6414
|
+
var IonicPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6415
|
+
type: z52.literal("prepend-array-item"),
|
|
6248
6416
|
arrayKey: z52.string().optional(),
|
|
6249
6417
|
props: IonicButtonPropsSchema.optional()
|
|
6250
6418
|
});
|
|
6419
|
+
var IonicInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6420
|
+
type: z52.literal("insert-array-item"),
|
|
6421
|
+
arrayKey: z52.string().optional(),
|
|
6422
|
+
index: z52.number(),
|
|
6423
|
+
props: IonicButtonPropsSchema.optional()
|
|
6424
|
+
});
|
|
6425
|
+
var IonicPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6426
|
+
type: z52.literal("pop-array-item"),
|
|
6427
|
+
arrayKey: z52.string(),
|
|
6428
|
+
props: IonicButtonPropsSchema.optional()
|
|
6429
|
+
});
|
|
6430
|
+
var IonicShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6431
|
+
type: z52.literal("shift-array-item"),
|
|
6432
|
+
arrayKey: z52.string(),
|
|
6433
|
+
props: IonicButtonPropsSchema.optional()
|
|
6434
|
+
});
|
|
6251
6435
|
|
|
6252
6436
|
// internal/dynamic-forms-zod/ionic/src/ionic-leaf-field.schema.ts
|
|
6253
6437
|
import { z as z53 } from "zod";
|
|
@@ -6268,7 +6452,11 @@ var IonicLeafFieldSchema = z53.discriminatedUnion("type", [
|
|
|
6268
6452
|
IonicNextButtonFieldSchema,
|
|
6269
6453
|
IonicPreviousButtonFieldSchema,
|
|
6270
6454
|
IonicAddArrayItemButtonFieldSchema,
|
|
6271
|
-
IonicRemoveArrayItemButtonFieldSchema
|
|
6455
|
+
IonicRemoveArrayItemButtonFieldSchema,
|
|
6456
|
+
IonicPrependArrayItemButtonFieldSchema,
|
|
6457
|
+
IonicInsertArrayItemButtonFieldSchema,
|
|
6458
|
+
IonicPopArrayItemButtonFieldSchema,
|
|
6459
|
+
IonicShiftArrayItemButtonFieldSchema
|
|
6272
6460
|
]).superRefine(nullableValueRefine);
|
|
6273
6461
|
|
|
6274
6462
|
// internal/dynamic-forms-zod/ionic/src/ionic-form-config.schema.ts
|
|
@@ -6654,8 +6842,12 @@ var NESTING_RULES = {
|
|
|
6654
6842
|
"submit",
|
|
6655
6843
|
"next",
|
|
6656
6844
|
"previous",
|
|
6657
|
-
"
|
|
6658
|
-
"
|
|
6845
|
+
"add-array-item",
|
|
6846
|
+
"prepend-array-item",
|
|
6847
|
+
"insert-array-item",
|
|
6848
|
+
"remove-array-item",
|
|
6849
|
+
"pop-array-item",
|
|
6850
|
+
"shift-array-item"
|
|
6659
6851
|
],
|
|
6660
6852
|
forbidden: ["page"],
|
|
6661
6853
|
message: "Pages cannot be nested inside other containers. ALL top-level fields must be pages if using multi-page mode."
|
|
@@ -6678,8 +6870,12 @@ var NESTING_RULES = {
|
|
|
6678
6870
|
"submit",
|
|
6679
6871
|
"next",
|
|
6680
6872
|
"previous",
|
|
6681
|
-
"
|
|
6682
|
-
"
|
|
6873
|
+
"add-array-item",
|
|
6874
|
+
"prepend-array-item",
|
|
6875
|
+
"insert-array-item",
|
|
6876
|
+
"remove-array-item",
|
|
6877
|
+
"pop-array-item",
|
|
6878
|
+
"shift-array-item"
|
|
6683
6879
|
],
|
|
6684
6880
|
forbidden: ["page", "row", "hidden"],
|
|
6685
6881
|
message: "Rows cannot contain pages, other rows, or hidden fields. Hidden fields should be at page or form level."
|
|
@@ -6702,8 +6898,12 @@ var NESTING_RULES = {
|
|
|
6702
6898
|
"submit",
|
|
6703
6899
|
"next",
|
|
6704
6900
|
"previous",
|
|
6705
|
-
"
|
|
6706
|
-
"
|
|
6901
|
+
"add-array-item",
|
|
6902
|
+
"prepend-array-item",
|
|
6903
|
+
"insert-array-item",
|
|
6904
|
+
"remove-array-item",
|
|
6905
|
+
"pop-array-item",
|
|
6906
|
+
"shift-array-item"
|
|
6707
6907
|
],
|
|
6708
6908
|
forbidden: ["page", "group"],
|
|
6709
6909
|
message: "Groups cannot contain pages or other groups (no nested groups)."
|
|
@@ -6727,8 +6927,12 @@ var NESTING_RULES = {
|
|
|
6727
6927
|
"submit",
|
|
6728
6928
|
"next",
|
|
6729
6929
|
"previous",
|
|
6730
|
-
"
|
|
6731
|
-
"
|
|
6930
|
+
"add-array-item",
|
|
6931
|
+
"prepend-array-item",
|
|
6932
|
+
"insert-array-item",
|
|
6933
|
+
"remove-array-item",
|
|
6934
|
+
"pop-array-item",
|
|
6935
|
+
"shift-array-item"
|
|
6732
6936
|
],
|
|
6733
6937
|
forbidden: ["page", "array"],
|
|
6734
6938
|
message: "Arrays cannot contain pages or other arrays (no nested arrays)."
|
|
@@ -6974,6 +7178,27 @@ function preValidateConfig(config) {
|
|
|
6974
7178
|
});
|
|
6975
7179
|
return errors;
|
|
6976
7180
|
}
|
|
7181
|
+
var LEGACY_ARRAY_ACTION_TYPES = {
|
|
7182
|
+
addArrayItem: "add-array-item",
|
|
7183
|
+
prependArrayItem: "prepend-array-item",
|
|
7184
|
+
insertArrayItem: "insert-array-item",
|
|
7185
|
+
removeArrayItem: "remove-array-item",
|
|
7186
|
+
popArrayItem: "pop-array-item",
|
|
7187
|
+
shiftArrayItem: "shift-array-item"
|
|
7188
|
+
};
|
|
7189
|
+
function normalizeLegacyArrayActionTypes(value) {
|
|
7190
|
+
if (Array.isArray(value)) {
|
|
7191
|
+
return value.map(normalizeLegacyArrayActionTypes);
|
|
7192
|
+
}
|
|
7193
|
+
if (value && typeof value === "object") {
|
|
7194
|
+
const out = {};
|
|
7195
|
+
for (const [key, val] of Object.entries(value)) {
|
|
7196
|
+
out[key] = key === "type" && typeof val === "string" && LEGACY_ARRAY_ACTION_TYPES[val] ? LEGACY_ARRAY_ACTION_TYPES[val] : normalizeLegacyArrayActionTypes(val);
|
|
7197
|
+
}
|
|
7198
|
+
return out;
|
|
7199
|
+
}
|
|
7200
|
+
return value;
|
|
7201
|
+
}
|
|
6977
7202
|
function validateFormConfig(uiIntegration, config) {
|
|
6978
7203
|
const schema = formConfigSchemas2[uiIntegration];
|
|
6979
7204
|
if (!schema) {
|
|
@@ -6988,15 +7213,16 @@ function validateFormConfig(uiIntegration, config) {
|
|
|
6988
7213
|
errorSummary: `Unknown UI integration: ${uiIntegration}`
|
|
6989
7214
|
};
|
|
6990
7215
|
}
|
|
6991
|
-
const
|
|
6992
|
-
const
|
|
7216
|
+
const normalizedConfig = normalizeLegacyArrayActionTypes(config);
|
|
7217
|
+
const preErrors = preValidateConfig(normalizedConfig);
|
|
7218
|
+
const result = schema.safeParse(normalizedConfig);
|
|
6993
7219
|
if (result.success && preErrors.length === 0) {
|
|
6994
7220
|
return {
|
|
6995
7221
|
valid: true,
|
|
6996
7222
|
data: result.data
|
|
6997
7223
|
};
|
|
6998
7224
|
}
|
|
6999
|
-
const zodErrors = result.success ? [] : formatZodError(result.error,
|
|
7225
|
+
const zodErrors = result.success ? [] : formatZodError(result.error, normalizedConfig);
|
|
7000
7226
|
const allErrors = [...preErrors, ...zodErrors];
|
|
7001
7227
|
return {
|
|
7002
7228
|
valid: false,
|
|
@@ -7026,29 +7252,32 @@ ${UI_INTEGRATIONS.map((ui) => `- ${ui}`).join("\n")}
|
|
|
7026
7252
|
## Field Types
|
|
7027
7253
|
${fieldTypes.map((ft) => `- ${ft}`).join("\n")}
|
|
7028
7254
|
|
|
7029
|
-
## Tools (
|
|
7255
|
+
## Tools (5 total - consolidated)
|
|
7030
7256
|
|
|
7031
|
-
**1. START HERE -
|
|
7032
|
-
\`
|
|
7257
|
+
**1. START HERE - Documentation lookup:**
|
|
7258
|
+
\`ngforge_lookup(topic, depth?, uiIntegration?)\`
|
|
7259
|
+
- topic="workflow" for the recommended tool-usage guide
|
|
7033
7260
|
- Property placement rules, condition syntax, copy-paste patterns, common errors
|
|
7034
|
-
-
|
|
7035
|
-
- **Use this first** - it has 90% of what you need in one call
|
|
7261
|
+
- depth="brief|full|schema" (default full); uiIntegration filters schema output
|
|
7036
7262
|
|
|
7037
|
-
**2.
|
|
7038
|
-
\`
|
|
7263
|
+
**2. Search:**
|
|
7264
|
+
\`ngforge_search(query)\`
|
|
7265
|
+
- Free-text keyword search across all topics and examples
|
|
7266
|
+
- Use when you don't know the exact topic name
|
|
7267
|
+
|
|
7268
|
+
**3. Validation:**
|
|
7269
|
+
\`ngforge_validate(config, uiIntegration?)\`
|
|
7039
7270
|
- Validates config against actual TypeScript types
|
|
7040
7271
|
- Catches errors before runtime
|
|
7041
7272
|
|
|
7042
|
-
**
|
|
7043
|
-
\`
|
|
7044
|
-
- Properties, validators, and examples for a specific field type
|
|
7045
|
-
- Set includeSchema=true for JSON Schema (machine-readable)
|
|
7046
|
-
|
|
7047
|
-
**4. Examples + deep explanations:**
|
|
7048
|
-
\`ngforge_get_example(pattern?, depth?)\`
|
|
7273
|
+
**4. Examples:**
|
|
7274
|
+
\`ngforge_examples(pattern, depth?)\`
|
|
7049
7275
|
- Patterns: complete, derivation, conditional, multi-page, validation
|
|
7050
|
-
- depth
|
|
7051
|
-
|
|
7276
|
+
- depth controls how much detail (working code vs. deep explanation)
|
|
7277
|
+
|
|
7278
|
+
**5. Scaffold:**
|
|
7279
|
+
\`ngforge_scaffold(fields?, pages?, arrays?, groups?, hidden?, uiIntegration?)\`
|
|
7280
|
+
- Generates a compilable FormConfig skeleton
|
|
7052
7281
|
`
|
|
7053
7282
|
}
|
|
7054
7283
|
]
|
|
@@ -7708,8 +7937,8 @@ interface SimplifiedArrayField {
|
|
|
7708
7937
|
|
|
7709
7938
|
The simplified API is normalized into the full API at runtime:
|
|
7710
7939
|
1. Each \`value\` element creates an item using the \`template\` structure
|
|
7711
|
-
2. An \`
|
|
7712
|
-
3. A \`
|
|
7940
|
+
2. An \`add-array-item\` button is auto-generated after the array (unless \`addButton: false\`)
|
|
7941
|
+
3. A \`remove-array-item\` button is added to each item (unless \`removeButton: false\`)
|
|
7713
7942
|
|
|
7714
7943
|
## Conditional Visibility
|
|
7715
7944
|
|
|
@@ -9464,19 +9693,19 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9464
9693
|
- Together they give you: type safety + exact type inference`
|
|
9465
9694
|
},
|
|
9466
9695
|
"array-buttons": {
|
|
9467
|
-
brief: `**Add:** \`{ type: '
|
|
9468
|
-
**Remove:** \`{ type: '
|
|
9696
|
+
brief: `**Add:** \`{ type: 'add-array-item', key: 'add', label: 'Add', arrayKey: 'contacts' }\`
|
|
9697
|
+
**Remove:** \`{ type: 'remove-array-item', key: 'remove', label: 'Remove' }\` (inside array template)
|
|
9469
9698
|
\u26A0\uFE0F arrayKey at FIELD level, NOT in props!`,
|
|
9470
9699
|
full: `# Array Buttons (Add/Remove Items)
|
|
9471
9700
|
|
|
9472
|
-
**UI libraries provide \`
|
|
9701
|
+
**UI libraries provide \`add-array-item\` and \`remove-array-item\` button types.**
|
|
9473
9702
|
|
|
9474
9703
|
## Add Item Button
|
|
9475
9704
|
|
|
9476
9705
|
\`\`\`typescript
|
|
9477
9706
|
{
|
|
9478
9707
|
key: 'addPhone',
|
|
9479
|
-
type: '
|
|
9708
|
+
type: 'add-array-item',
|
|
9480
9709
|
label: 'Add Phone',
|
|
9481
9710
|
arrayKey: 'phones', // \u26A0\uFE0F AT FIELD LEVEL, NOT IN PROPS!
|
|
9482
9711
|
props: {
|
|
@@ -9498,7 +9727,7 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9498
9727
|
{ key: 'number', type: 'input', label: 'Phone Number' },
|
|
9499
9728
|
{
|
|
9500
9729
|
key: 'removePhone',
|
|
9501
|
-
type: '
|
|
9730
|
+
type: 'remove-array-item',
|
|
9502
9731
|
label: 'Remove',
|
|
9503
9732
|
// arrayKey not needed - inferred from parent array
|
|
9504
9733
|
props: { color: 'warn' }
|
|
@@ -9513,13 +9742,13 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9513
9742
|
\`\`\`typescript
|
|
9514
9743
|
// WRONG - arrayKey in props
|
|
9515
9744
|
{
|
|
9516
|
-
type: '
|
|
9745
|
+
type: 'add-array-item',
|
|
9517
9746
|
props: { arrayKey: 'phones' } // \u274C WRONG LOCATION
|
|
9518
9747
|
}
|
|
9519
9748
|
|
|
9520
9749
|
// CORRECT - arrayKey at field level
|
|
9521
9750
|
{
|
|
9522
|
-
type: '
|
|
9751
|
+
type: 'add-array-item',
|
|
9523
9752
|
arrayKey: 'phones', // \u2705 CORRECT
|
|
9524
9753
|
props: { color: 'primary' }
|
|
9525
9754
|
}
|
|
@@ -9788,8 +10017,19 @@ var TOPIC_ALIASES = {
|
|
|
9788
10017
|
valueof: "context-api",
|
|
9789
10018
|
"add-array": "array-buttons",
|
|
9790
10019
|
"remove-array": "array-buttons",
|
|
10020
|
+
// Array-action field types: kebab-case canonical + camelCase legacy aliases
|
|
10021
|
+
"add-array-item": "array-buttons",
|
|
10022
|
+
"prepend-array-item": "array-buttons",
|
|
10023
|
+
"insert-array-item": "array-buttons",
|
|
10024
|
+
"remove-array-item": "array-buttons",
|
|
10025
|
+
"pop-array-item": "array-buttons",
|
|
10026
|
+
"shift-array-item": "array-buttons",
|
|
9791
10027
|
addarrayitem: "array-buttons",
|
|
10028
|
+
prependarrayitem: "array-buttons",
|
|
10029
|
+
insertarrayitem: "array-buttons",
|
|
9792
10030
|
removearrayitem: "array-buttons",
|
|
10031
|
+
poparrayitem: "array-buttons",
|
|
10032
|
+
shiftarrayitem: "array-buttons",
|
|
9793
10033
|
"custom-validator": "custom-validators",
|
|
9794
10034
|
customvalidator: "custom-validators",
|
|
9795
10035
|
mistakes: "pitfalls",
|
|
@@ -10834,7 +11074,7 @@ For full control, use the \`fields\`-based API with explicit add/remove buttons:
|
|
|
10834
11074
|
]
|
|
10835
11075
|
]
|
|
10836
11076
|
}
|
|
10837
|
-
// + separate
|
|
11077
|
+
// + separate add-array-item button with arrayKey
|
|
10838
11078
|
\`\`\``,
|
|
10839
11079
|
explained: `# Array Fields - Complete Explanation
|
|
10840
11080
|
|
|
@@ -10906,7 +11146,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
|
|
|
10906
11146
|
// ADD button - place OUTSIDE the array
|
|
10907
11147
|
{
|
|
10908
11148
|
key: 'addContact',
|
|
10909
|
-
type: '
|
|
11149
|
+
type: 'add-array-item',
|
|
10910
11150
|
label: 'Add Contact',
|
|
10911
11151
|
arrayKey: 'contacts', // \u26A0\uFE0F AT FIELD LEVEL!
|
|
10912
11152
|
}
|
|
@@ -10918,7 +11158,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
|
|
|
10918
11158
|
fields: [
|
|
10919
11159
|
[
|
|
10920
11160
|
{ key: 'name', type: 'input', label: 'Name' },
|
|
10921
|
-
{ key: 'remove', type: '
|
|
11161
|
+
{ key: 'remove', type: 'remove-array-item', label: 'Remove' }
|
|
10922
11162
|
]
|
|
10923
11163
|
]
|
|
10924
11164
|
}
|
|
@@ -10952,8 +11192,8 @@ expression: '(formValue.items || []).reduce((sum, item) => sum + (item.price ||
|
|
|
10952
11192
|
|
|
10953
11193
|
\u274C Putting \`arrayKey\` in props (full API):
|
|
10954
11194
|
\`\`\`typescript
|
|
10955
|
-
{ type: '
|
|
10956
|
-
{ type: '
|
|
11195
|
+
{ type: 'add-array-item', props: { arrayKey: 'x' } } // WRONG
|
|
11196
|
+
{ type: 'add-array-item', arrayKey: 'x' } // CORRECT
|
|
10957
11197
|
\`\`\``
|
|
10958
11198
|
},
|
|
10959
11199
|
"minimal-simplified-array": {
|
package/src/registry/addons.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Addon Registry Data */
|
|
2
|
+
import type { UiIntegration } from '@ng-forge/dynamic-forms-zod/mcp';
|
|
2
3
|
import type { PropertyInfo } from './index.js';
|
|
3
4
|
export interface AddonTypeInfo {
|
|
4
5
|
/** Discriminant matching `addon.type` in form configs. */
|
|
@@ -8,7 +9,7 @@ export interface AddonTypeInfo {
|
|
|
8
9
|
/** Provider package; `'core'` means @ng-forge/dynamic-forms. */
|
|
9
10
|
package: string;
|
|
10
11
|
/** Adapter that ships this type, or `null` for core types. */
|
|
11
|
-
adapter:
|
|
12
|
+
adapter: UiIntegration | null;
|
|
12
13
|
/** One-line description of what this type renders. */
|
|
13
14
|
description: string;
|
|
14
15
|
/**
|
|
@@ -33,7 +34,7 @@ export interface FieldAddonSupportInfo {
|
|
|
33
34
|
/** Field type discriminant (matches `FieldDef.type`). */
|
|
34
35
|
fieldType: string;
|
|
35
36
|
/** Adapter shipping the field — null for core fields. */
|
|
36
|
-
adapter:
|
|
37
|
+
adapter: UiIntegration | null;
|
|
37
38
|
/** Slots this field accepts. */
|
|
38
39
|
slots: ('prefix' | 'suffix' | string)[];
|
|
39
40
|
/** Whitelist of allowed types (omitted = any registered type). */
|