@ng-forge/dynamic-form-mcp 1.0.0-rc.3 → 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 +313 -69
- package/index.d.ts +252 -0
- package/package.json +16 -13
- package/src/index.js +313 -69
- 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",
|
|
@@ -2858,6 +2929,8 @@ Evaluates a JavaScript expression with access to \`formValue\`, \`fieldValue\`,
|
|
|
2858
2929
|
}
|
|
2859
2930
|
\`\`\`
|
|
2860
2931
|
|
|
2932
|
+
**Condition scoping:** in logic conditions, \`formValue\` is the whole form value regardless of where the field sits, except inside array items where it is scoped to the current item (use \`rootFormValue\` for the rest of the form). Reference group-nested fields by their full path, e.g. \`formValue.person.firstName\`. Note that \`derivation\` expressions scope differently: there \`formValue\` is also scoped to the parent group for group-nested fields.
|
|
2933
|
+
|
|
2861
2934
|
#### Custom Condition
|
|
2862
2935
|
|
|
2863
2936
|
Invokes a registered custom function by name:
|
|
@@ -3035,7 +3108,7 @@ All features are exported from \`@ng-forge/dynamic-forms\`.
|
|
|
3035
3108
|
|
|
3036
3109
|
## CRITICAL: UI Library Differences
|
|
3037
3110
|
|
|
3038
|
-
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.
|
|
3039
3112
|
|
|
3040
3113
|
### Property Differences by Library
|
|
3041
3114
|
|
|
@@ -3078,24 +3151,24 @@ Container fields (\`page\`, \`group\`, \`row\`) do NOT support these properties:
|
|
|
3078
3151
|
{ key: 'volume', type: 'slider', label: 'Volume', min: 0, max: 100 }
|
|
3079
3152
|
\`\`\`
|
|
3080
3153
|
|
|
3081
|
-
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.
|
|
3082
3155
|
|
|
3083
3156
|
## Validation Before Use
|
|
3084
3157
|
|
|
3085
|
-
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.
|
|
3086
3159
|
|
|
3087
3160
|
\`\`\`typescript
|
|
3088
3161
|
// Always specify the UI integration you're using
|
|
3089
|
-
|
|
3162
|
+
ngforge_validate({
|
|
3090
3163
|
uiIntegration: 'material', // or 'bootstrap', 'primeng', 'ionic'
|
|
3091
3164
|
config: { fields: [...] }
|
|
3092
3165
|
})
|
|
3093
3166
|
\`\`\`
|
|
3094
3167
|
|
|
3095
|
-
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"\`:
|
|
3096
3169
|
|
|
3097
3170
|
\`\`\`typescript
|
|
3098
|
-
|
|
3171
|
+
ngforge_lookup({ topic: 'input', depth: 'schema', uiIntegration: 'material' })
|
|
3099
3172
|
\`\`\`
|
|
3100
3173
|
`;
|
|
3101
3174
|
|
|
@@ -5211,7 +5284,7 @@ var MatPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5211
5284
|
props: MatButtonPropsSchema.optional()
|
|
5212
5285
|
});
|
|
5213
5286
|
var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5214
|
-
type: z33.literal("
|
|
5287
|
+
type: z33.literal("add-array-item"),
|
|
5215
5288
|
/**
|
|
5216
5289
|
* Key of the array field to add items to.
|
|
5217
5290
|
* If omitted, uses the parent array context.
|
|
@@ -5220,7 +5293,7 @@ var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5220
5293
|
props: MatButtonPropsSchema.optional()
|
|
5221
5294
|
});
|
|
5222
5295
|
var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5223
|
-
type: z33.literal("
|
|
5296
|
+
type: z33.literal("remove-array-item"),
|
|
5224
5297
|
/**
|
|
5225
5298
|
* Key of the array field to remove items from.
|
|
5226
5299
|
* If omitted, uses the parent array context.
|
|
@@ -5228,6 +5301,44 @@ var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5228
5301
|
arrayKey: z33.string().optional(),
|
|
5229
5302
|
props: MatButtonPropsSchema.optional()
|
|
5230
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
|
+
});
|
|
5231
5342
|
|
|
5232
5343
|
// internal/dynamic-forms-zod/material/src/mat-leaf-field.schema.ts
|
|
5233
5344
|
import { z as z36 } from "zod";
|
|
@@ -5303,7 +5414,11 @@ var MatLeafFieldSchema = z36.discriminatedUnion("type", [
|
|
|
5303
5414
|
MatNextButtonFieldSchema,
|
|
5304
5415
|
MatPreviousButtonFieldSchema,
|
|
5305
5416
|
MatAddArrayItemButtonFieldSchema,
|
|
5306
|
-
MatRemoveArrayItemButtonFieldSchema
|
|
5417
|
+
MatRemoveArrayItemButtonFieldSchema,
|
|
5418
|
+
MatPrependArrayItemButtonFieldSchema,
|
|
5419
|
+
MatInsertArrayItemButtonFieldSchema,
|
|
5420
|
+
MatPopArrayItemButtonFieldSchema,
|
|
5421
|
+
MatShiftArrayItemButtonFieldSchema
|
|
5307
5422
|
]).superRefine(nullableValueRefine);
|
|
5308
5423
|
|
|
5309
5424
|
// internal/dynamic-forms-zod/src/lib/schemas/containers/factories.ts
|
|
@@ -5771,15 +5886,36 @@ var BsPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5771
5886
|
props: BsButtonPropsSchema.optional()
|
|
5772
5887
|
});
|
|
5773
5888
|
var BsAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5774
|
-
type: z44.literal("
|
|
5889
|
+
type: z44.literal("add-array-item"),
|
|
5775
5890
|
arrayKey: z44.string().optional(),
|
|
5776
5891
|
props: BsButtonPropsSchema.optional()
|
|
5777
5892
|
});
|
|
5778
5893
|
var BsRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5779
|
-
type: z44.literal("
|
|
5894
|
+
type: z44.literal("remove-array-item"),
|
|
5780
5895
|
arrayKey: z44.string().optional(),
|
|
5781
5896
|
props: BsButtonPropsSchema.optional()
|
|
5782
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"),
|
|
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(),
|
|
5917
|
+
props: BsButtonPropsSchema.optional()
|
|
5918
|
+
});
|
|
5783
5919
|
|
|
5784
5920
|
// internal/dynamic-forms-zod/bootstrap/src/bs-leaf-field.schema.ts
|
|
5785
5921
|
import { z as z45 } from "zod";
|
|
@@ -5800,7 +5936,11 @@ var BsLeafFieldSchema = z45.discriminatedUnion("type", [
|
|
|
5800
5936
|
BsNextButtonFieldSchema,
|
|
5801
5937
|
BsPreviousButtonFieldSchema,
|
|
5802
5938
|
BsAddArrayItemButtonFieldSchema,
|
|
5803
|
-
BsRemoveArrayItemButtonFieldSchema
|
|
5939
|
+
BsRemoveArrayItemButtonFieldSchema,
|
|
5940
|
+
BsPrependArrayItemButtonFieldSchema,
|
|
5941
|
+
BsInsertArrayItemButtonFieldSchema,
|
|
5942
|
+
BsPopArrayItemButtonFieldSchema,
|
|
5943
|
+
BsShiftArrayItemButtonFieldSchema
|
|
5804
5944
|
]).superRefine(nullableValueRefine);
|
|
5805
5945
|
|
|
5806
5946
|
// internal/dynamic-forms-zod/bootstrap/src/bs-form-config.schema.ts
|
|
@@ -5983,15 +6123,36 @@ var PrimePreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5983
6123
|
props: PrimeButtonPropsSchema.optional()
|
|
5984
6124
|
});
|
|
5985
6125
|
var PrimeAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5986
|
-
type: z48.literal("
|
|
6126
|
+
type: z48.literal("add-array-item"),
|
|
5987
6127
|
arrayKey: z48.string().optional(),
|
|
5988
6128
|
props: PrimeButtonPropsSchema.optional()
|
|
5989
6129
|
});
|
|
5990
6130
|
var PrimeRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5991
|
-
type: z48.literal("
|
|
6131
|
+
type: z48.literal("remove-array-item"),
|
|
6132
|
+
arrayKey: z48.string().optional(),
|
|
6133
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6134
|
+
});
|
|
6135
|
+
var PrimePrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6136
|
+
type: z48.literal("prepend-array-item"),
|
|
5992
6137
|
arrayKey: z48.string().optional(),
|
|
5993
6138
|
props: PrimeButtonPropsSchema.optional()
|
|
5994
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
|
+
});
|
|
5995
6156
|
|
|
5996
6157
|
// internal/dynamic-forms-zod/primeng/src/prime-leaf-field.schema.ts
|
|
5997
6158
|
import { z as z49 } from "zod";
|
|
@@ -6012,7 +6173,11 @@ var PrimeLeafFieldSchema = z49.discriminatedUnion("type", [
|
|
|
6012
6173
|
PrimeNextButtonFieldSchema,
|
|
6013
6174
|
PrimePreviousButtonFieldSchema,
|
|
6014
6175
|
PrimeAddArrayItemButtonFieldSchema,
|
|
6015
|
-
PrimeRemoveArrayItemButtonFieldSchema
|
|
6176
|
+
PrimeRemoveArrayItemButtonFieldSchema,
|
|
6177
|
+
PrimePrependArrayItemButtonFieldSchema,
|
|
6178
|
+
PrimeInsertArrayItemButtonFieldSchema,
|
|
6179
|
+
PrimePopArrayItemButtonFieldSchema,
|
|
6180
|
+
PrimeShiftArrayItemButtonFieldSchema
|
|
6016
6181
|
]).superRefine(nullableValueRefine);
|
|
6017
6182
|
|
|
6018
6183
|
// internal/dynamic-forms-zod/primeng/src/prime-form-config.schema.ts
|
|
@@ -6237,13 +6402,34 @@ var IonicPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
6237
6402
|
props: IonicButtonPropsSchema.optional()
|
|
6238
6403
|
});
|
|
6239
6404
|
var IonicAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6240
|
-
type: z52.literal("
|
|
6405
|
+
type: z52.literal("add-array-item"),
|
|
6241
6406
|
arrayKey: z52.string().optional(),
|
|
6242
6407
|
props: IonicButtonPropsSchema.optional()
|
|
6243
6408
|
});
|
|
6244
6409
|
var IonicRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6245
|
-
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"),
|
|
6416
|
+
arrayKey: z52.string().optional(),
|
|
6417
|
+
props: IonicButtonPropsSchema.optional()
|
|
6418
|
+
});
|
|
6419
|
+
var IonicInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6420
|
+
type: z52.literal("insert-array-item"),
|
|
6246
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(),
|
|
6247
6433
|
props: IonicButtonPropsSchema.optional()
|
|
6248
6434
|
});
|
|
6249
6435
|
|
|
@@ -6266,7 +6452,11 @@ var IonicLeafFieldSchema = z53.discriminatedUnion("type", [
|
|
|
6266
6452
|
IonicNextButtonFieldSchema,
|
|
6267
6453
|
IonicPreviousButtonFieldSchema,
|
|
6268
6454
|
IonicAddArrayItemButtonFieldSchema,
|
|
6269
|
-
IonicRemoveArrayItemButtonFieldSchema
|
|
6455
|
+
IonicRemoveArrayItemButtonFieldSchema,
|
|
6456
|
+
IonicPrependArrayItemButtonFieldSchema,
|
|
6457
|
+
IonicInsertArrayItemButtonFieldSchema,
|
|
6458
|
+
IonicPopArrayItemButtonFieldSchema,
|
|
6459
|
+
IonicShiftArrayItemButtonFieldSchema
|
|
6270
6460
|
]).superRefine(nullableValueRefine);
|
|
6271
6461
|
|
|
6272
6462
|
// internal/dynamic-forms-zod/ionic/src/ionic-form-config.schema.ts
|
|
@@ -6652,8 +6842,12 @@ var NESTING_RULES = {
|
|
|
6652
6842
|
"submit",
|
|
6653
6843
|
"next",
|
|
6654
6844
|
"previous",
|
|
6655
|
-
"
|
|
6656
|
-
"
|
|
6845
|
+
"add-array-item",
|
|
6846
|
+
"prepend-array-item",
|
|
6847
|
+
"insert-array-item",
|
|
6848
|
+
"remove-array-item",
|
|
6849
|
+
"pop-array-item",
|
|
6850
|
+
"shift-array-item"
|
|
6657
6851
|
],
|
|
6658
6852
|
forbidden: ["page"],
|
|
6659
6853
|
message: "Pages cannot be nested inside other containers. ALL top-level fields must be pages if using multi-page mode."
|
|
@@ -6676,8 +6870,12 @@ var NESTING_RULES = {
|
|
|
6676
6870
|
"submit",
|
|
6677
6871
|
"next",
|
|
6678
6872
|
"previous",
|
|
6679
|
-
"
|
|
6680
|
-
"
|
|
6873
|
+
"add-array-item",
|
|
6874
|
+
"prepend-array-item",
|
|
6875
|
+
"insert-array-item",
|
|
6876
|
+
"remove-array-item",
|
|
6877
|
+
"pop-array-item",
|
|
6878
|
+
"shift-array-item"
|
|
6681
6879
|
],
|
|
6682
6880
|
forbidden: ["page", "row", "hidden"],
|
|
6683
6881
|
message: "Rows cannot contain pages, other rows, or hidden fields. Hidden fields should be at page or form level."
|
|
@@ -6700,8 +6898,12 @@ var NESTING_RULES = {
|
|
|
6700
6898
|
"submit",
|
|
6701
6899
|
"next",
|
|
6702
6900
|
"previous",
|
|
6703
|
-
"
|
|
6704
|
-
"
|
|
6901
|
+
"add-array-item",
|
|
6902
|
+
"prepend-array-item",
|
|
6903
|
+
"insert-array-item",
|
|
6904
|
+
"remove-array-item",
|
|
6905
|
+
"pop-array-item",
|
|
6906
|
+
"shift-array-item"
|
|
6705
6907
|
],
|
|
6706
6908
|
forbidden: ["page", "group"],
|
|
6707
6909
|
message: "Groups cannot contain pages or other groups (no nested groups)."
|
|
@@ -6725,8 +6927,12 @@ var NESTING_RULES = {
|
|
|
6725
6927
|
"submit",
|
|
6726
6928
|
"next",
|
|
6727
6929
|
"previous",
|
|
6728
|
-
"
|
|
6729
|
-
"
|
|
6930
|
+
"add-array-item",
|
|
6931
|
+
"prepend-array-item",
|
|
6932
|
+
"insert-array-item",
|
|
6933
|
+
"remove-array-item",
|
|
6934
|
+
"pop-array-item",
|
|
6935
|
+
"shift-array-item"
|
|
6730
6936
|
],
|
|
6731
6937
|
forbidden: ["page", "array"],
|
|
6732
6938
|
message: "Arrays cannot contain pages or other arrays (no nested arrays)."
|
|
@@ -6972,6 +7178,27 @@ function preValidateConfig(config) {
|
|
|
6972
7178
|
});
|
|
6973
7179
|
return errors;
|
|
6974
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
|
+
}
|
|
6975
7202
|
function validateFormConfig(uiIntegration, config) {
|
|
6976
7203
|
const schema = formConfigSchemas2[uiIntegration];
|
|
6977
7204
|
if (!schema) {
|
|
@@ -6986,15 +7213,16 @@ function validateFormConfig(uiIntegration, config) {
|
|
|
6986
7213
|
errorSummary: `Unknown UI integration: ${uiIntegration}`
|
|
6987
7214
|
};
|
|
6988
7215
|
}
|
|
6989
|
-
const
|
|
6990
|
-
const
|
|
7216
|
+
const normalizedConfig = normalizeLegacyArrayActionTypes(config);
|
|
7217
|
+
const preErrors = preValidateConfig(normalizedConfig);
|
|
7218
|
+
const result = schema.safeParse(normalizedConfig);
|
|
6991
7219
|
if (result.success && preErrors.length === 0) {
|
|
6992
7220
|
return {
|
|
6993
7221
|
valid: true,
|
|
6994
7222
|
data: result.data
|
|
6995
7223
|
};
|
|
6996
7224
|
}
|
|
6997
|
-
const zodErrors = result.success ? [] : formatZodError(result.error,
|
|
7225
|
+
const zodErrors = result.success ? [] : formatZodError(result.error, normalizedConfig);
|
|
6998
7226
|
const allErrors = [...preErrors, ...zodErrors];
|
|
6999
7227
|
return {
|
|
7000
7228
|
valid: false,
|
|
@@ -7024,29 +7252,32 @@ ${UI_INTEGRATIONS.map((ui) => `- ${ui}`).join("\n")}
|
|
|
7024
7252
|
## Field Types
|
|
7025
7253
|
${fieldTypes.map((ft) => `- ${ft}`).join("\n")}
|
|
7026
7254
|
|
|
7027
|
-
## Tools (
|
|
7255
|
+
## Tools (5 total - consolidated)
|
|
7028
7256
|
|
|
7029
|
-
**1. START HERE -
|
|
7030
|
-
\`
|
|
7257
|
+
**1. START HERE - Documentation lookup:**
|
|
7258
|
+
\`ngforge_lookup(topic, depth?, uiIntegration?)\`
|
|
7259
|
+
- topic="workflow" for the recommended tool-usage guide
|
|
7031
7260
|
- Property placement rules, condition syntax, copy-paste patterns, common errors
|
|
7032
|
-
-
|
|
7033
|
-
- **Use this first** - it has 90% of what you need in one call
|
|
7261
|
+
- depth="brief|full|schema" (default full); uiIntegration filters schema output
|
|
7034
7262
|
|
|
7035
|
-
**2.
|
|
7036
|
-
\`
|
|
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?)\`
|
|
7037
7270
|
- Validates config against actual TypeScript types
|
|
7038
7271
|
- Catches errors before runtime
|
|
7039
7272
|
|
|
7040
|
-
**
|
|
7041
|
-
\`
|
|
7042
|
-
- Properties, validators, and examples for a specific field type
|
|
7043
|
-
- Set includeSchema=true for JSON Schema (machine-readable)
|
|
7044
|
-
|
|
7045
|
-
**4. Examples + deep explanations:**
|
|
7046
|
-
\`ngforge_get_example(pattern?, depth?)\`
|
|
7273
|
+
**4. Examples:**
|
|
7274
|
+
\`ngforge_examples(pattern, depth?)\`
|
|
7047
7275
|
- Patterns: complete, derivation, conditional, multi-page, validation
|
|
7048
|
-
- depth
|
|
7049
|
-
|
|
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
|
|
7050
7281
|
`
|
|
7051
7282
|
}
|
|
7052
7283
|
]
|
|
@@ -7706,8 +7937,8 @@ interface SimplifiedArrayField {
|
|
|
7706
7937
|
|
|
7707
7938
|
The simplified API is normalized into the full API at runtime:
|
|
7708
7939
|
1. Each \`value\` element creates an item using the \`template\` structure
|
|
7709
|
-
2. An \`
|
|
7710
|
-
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\`)
|
|
7711
7942
|
|
|
7712
7943
|
## Conditional Visibility
|
|
7713
7944
|
|
|
@@ -7921,6 +8152,7 @@ logic: [{ type: 'derivation', functionName: 'computeFromGroup', dependsOn: ['$gr
|
|
|
7921
8152
|
\`\`\`
|
|
7922
8153
|
Derivation is always defined ON the field that receives the computed value (self-targeting).
|
|
7923
8154
|
\`dependsOn\` paths are absolute from the form root (e.g. \`'address.state'\`). Use \`'$self'\` for the field's own absolute path and \`'$group'\` for its nearest parent group/array \u2014 both useful in factory-built fields where ancestor keys aren't known at config time.
|
|
8155
|
+
**Scoping:** in derivation expressions, \`formValue\` is scoped to the parent group for group-nested fields and to the current item inside arrays, so siblings are referenced directly (e.g. \`formValue.firstName\` inside a \`person\` group). Use \`rootFormValue\` to reach fields outside the current scope.
|
|
7924
8156
|
**Variables:** \`formValue\`, \`fieldValue\`, \`fieldState\`, \`formFieldState\`, \`externalData\` (see topic: expression-variables)
|
|
7925
8157
|
**For deriving component properties** (minDate, options, label): use \`targetProperty\` (see topic \`property-derivation\`)`,
|
|
7926
8158
|
full: `# Value Derivation (Computed Fields)
|
|
@@ -8282,7 +8514,8 @@ Wrong: Wrong property names
|
|
|
8282
8514
|
|
|
8283
8515
|
| Variable | Type | Available In | Description |
|
|
8284
8516
|
|----------|------|--------------|-------------|
|
|
8285
|
-
| \`formValue\` | object | Derivations, conditions, custom validators |
|
|
8517
|
+
| \`formValue\` | object | Derivations, conditions, custom validators | Form values as nested object. Scoped to the current array item in array contexts; in derivations additionally scoped to the parent group for group-nested fields. Conditions on group-nested fields see the root form value |
|
|
8518
|
+
| \`rootFormValue\` | object | Scoped contexts (array items, group-nested derivations) | The whole form value when \`formValue\` is scoped |
|
|
8286
8519
|
| \`fieldValue\` | any | Custom validator expressions only | Current field's value |
|
|
8287
8520
|
| \`fieldState\` | object | Derivations, conditions | Current field's state (touched, dirty, valid, etc.) |
|
|
8288
8521
|
| \`formFieldState\` | object | Derivations, conditions | All fields' states keyed by field key |
|
|
@@ -9460,19 +9693,19 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9460
9693
|
- Together they give you: type safety + exact type inference`
|
|
9461
9694
|
},
|
|
9462
9695
|
"array-buttons": {
|
|
9463
|
-
brief: `**Add:** \`{ type: '
|
|
9464
|
-
**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)
|
|
9465
9698
|
\u26A0\uFE0F arrayKey at FIELD level, NOT in props!`,
|
|
9466
9699
|
full: `# Array Buttons (Add/Remove Items)
|
|
9467
9700
|
|
|
9468
|
-
**UI libraries provide \`
|
|
9701
|
+
**UI libraries provide \`add-array-item\` and \`remove-array-item\` button types.**
|
|
9469
9702
|
|
|
9470
9703
|
## Add Item Button
|
|
9471
9704
|
|
|
9472
9705
|
\`\`\`typescript
|
|
9473
9706
|
{
|
|
9474
9707
|
key: 'addPhone',
|
|
9475
|
-
type: '
|
|
9708
|
+
type: 'add-array-item',
|
|
9476
9709
|
label: 'Add Phone',
|
|
9477
9710
|
arrayKey: 'phones', // \u26A0\uFE0F AT FIELD LEVEL, NOT IN PROPS!
|
|
9478
9711
|
props: {
|
|
@@ -9494,7 +9727,7 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9494
9727
|
{ key: 'number', type: 'input', label: 'Phone Number' },
|
|
9495
9728
|
{
|
|
9496
9729
|
key: 'removePhone',
|
|
9497
|
-
type: '
|
|
9730
|
+
type: 'remove-array-item',
|
|
9498
9731
|
label: 'Remove',
|
|
9499
9732
|
// arrayKey not needed - inferred from parent array
|
|
9500
9733
|
props: { color: 'warn' }
|
|
@@ -9509,13 +9742,13 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9509
9742
|
\`\`\`typescript
|
|
9510
9743
|
// WRONG - arrayKey in props
|
|
9511
9744
|
{
|
|
9512
|
-
type: '
|
|
9745
|
+
type: 'add-array-item',
|
|
9513
9746
|
props: { arrayKey: 'phones' } // \u274C WRONG LOCATION
|
|
9514
9747
|
}
|
|
9515
9748
|
|
|
9516
9749
|
// CORRECT - arrayKey at field level
|
|
9517
9750
|
{
|
|
9518
|
-
type: '
|
|
9751
|
+
type: 'add-array-item',
|
|
9519
9752
|
arrayKey: 'phones', // \u2705 CORRECT
|
|
9520
9753
|
props: { color: 'primary' }
|
|
9521
9754
|
}
|
|
@@ -9784,8 +10017,19 @@ var TOPIC_ALIASES = {
|
|
|
9784
10017
|
valueof: "context-api",
|
|
9785
10018
|
"add-array": "array-buttons",
|
|
9786
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",
|
|
9787
10027
|
addarrayitem: "array-buttons",
|
|
10028
|
+
prependarrayitem: "array-buttons",
|
|
10029
|
+
insertarrayitem: "array-buttons",
|
|
9788
10030
|
removearrayitem: "array-buttons",
|
|
10031
|
+
poparrayitem: "array-buttons",
|
|
10032
|
+
shiftarrayitem: "array-buttons",
|
|
9789
10033
|
"custom-validator": "custom-validators",
|
|
9790
10034
|
customvalidator: "custom-validators",
|
|
9791
10035
|
mistakes: "pitfalls",
|
|
@@ -10830,7 +11074,7 @@ For full control, use the \`fields\`-based API with explicit add/remove buttons:
|
|
|
10830
11074
|
]
|
|
10831
11075
|
]
|
|
10832
11076
|
}
|
|
10833
|
-
// + separate
|
|
11077
|
+
// + separate add-array-item button with arrayKey
|
|
10834
11078
|
\`\`\``,
|
|
10835
11079
|
explained: `# Array Fields - Complete Explanation
|
|
10836
11080
|
|
|
@@ -10902,7 +11146,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
|
|
|
10902
11146
|
// ADD button - place OUTSIDE the array
|
|
10903
11147
|
{
|
|
10904
11148
|
key: 'addContact',
|
|
10905
|
-
type: '
|
|
11149
|
+
type: 'add-array-item',
|
|
10906
11150
|
label: 'Add Contact',
|
|
10907
11151
|
arrayKey: 'contacts', // \u26A0\uFE0F AT FIELD LEVEL!
|
|
10908
11152
|
}
|
|
@@ -10914,7 +11158,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
|
|
|
10914
11158
|
fields: [
|
|
10915
11159
|
[
|
|
10916
11160
|
{ key: 'name', type: 'input', label: 'Name' },
|
|
10917
|
-
{ key: 'remove', type: '
|
|
11161
|
+
{ key: 'remove', type: 'remove-array-item', label: 'Remove' }
|
|
10918
11162
|
]
|
|
10919
11163
|
]
|
|
10920
11164
|
}
|
|
@@ -10948,8 +11192,8 @@ expression: '(formValue.items || []).reduce((sum, item) => sum + (item.price ||
|
|
|
10948
11192
|
|
|
10949
11193
|
\u274C Putting \`arrayKey\` in props (full API):
|
|
10950
11194
|
\`\`\`typescript
|
|
10951
|
-
{ type: '
|
|
10952
|
-
{ type: '
|
|
11195
|
+
{ type: 'add-array-item', props: { arrayKey: 'x' } } // WRONG
|
|
11196
|
+
{ type: 'add-array-item', arrayKey: 'x' } // CORRECT
|
|
10953
11197
|
\`\`\``
|
|
10954
11198
|
},
|
|
10955
11199
|
"minimal-simplified-array": {
|