@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/bin/ng-forge-mcp.js
CHANGED
|
@@ -650,9 +650,9 @@ var FIELD_TYPES = [
|
|
|
650
650
|
minimalExample: `{ key: 'submit', type: 'submit', label: 'Submit' }`
|
|
651
651
|
},
|
|
652
652
|
{
|
|
653
|
-
type: "
|
|
653
|
+
type: "add-array-item",
|
|
654
654
|
category: "button",
|
|
655
|
-
description: "Button to
|
|
655
|
+
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.)",
|
|
656
656
|
valueType: void 0,
|
|
657
657
|
baseInterface: "FieldDef",
|
|
658
658
|
props: {},
|
|
@@ -661,15 +661,50 @@ var FIELD_TYPES = [
|
|
|
661
661
|
allowedIn: ["array", "row", "group"],
|
|
662
662
|
example: `{
|
|
663
663
|
key: 'addContact',
|
|
664
|
-
type: '
|
|
664
|
+
type: 'add-array-item',
|
|
665
665
|
label: 'Add Contact'
|
|
666
666
|
}`,
|
|
667
|
-
minimalExample: `{ key: 'add', type: '
|
|
667
|
+
minimalExample: `{ key: 'add', type: 'add-array-item', label: 'Add Item' }`
|
|
668
668
|
},
|
|
669
669
|
{
|
|
670
|
-
type: "
|
|
670
|
+
type: "prepend-array-item",
|
|
671
671
|
category: "button",
|
|
672
|
-
description: "Button to
|
|
672
|
+
description: "Button to add a new item to the beginning of an array field. (Legacy alias: prependArrayItem.)",
|
|
673
|
+
valueType: void 0,
|
|
674
|
+
baseInterface: "FieldDef",
|
|
675
|
+
props: {},
|
|
676
|
+
validationSupported: false,
|
|
677
|
+
source: "adapter",
|
|
678
|
+
allowedIn: ["array", "row", "group"],
|
|
679
|
+
example: `{
|
|
680
|
+
key: 'prependContact',
|
|
681
|
+
type: 'prepend-array-item',
|
|
682
|
+
label: 'Add to Top'
|
|
683
|
+
}`,
|
|
684
|
+
minimalExample: `{ key: 'prepend', type: 'prepend-array-item', label: 'Add First' }`
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
type: "insert-array-item",
|
|
688
|
+
category: "button",
|
|
689
|
+
description: "Button to insert a new item at a specific index in an array field (set via the index property). (Legacy alias: insertArrayItem.)",
|
|
690
|
+
valueType: void 0,
|
|
691
|
+
baseInterface: "FieldDef",
|
|
692
|
+
props: {},
|
|
693
|
+
validationSupported: false,
|
|
694
|
+
source: "adapter",
|
|
695
|
+
allowedIn: ["array", "row", "group"],
|
|
696
|
+
example: `{
|
|
697
|
+
key: 'insertContact',
|
|
698
|
+
type: 'insert-array-item',
|
|
699
|
+
label: 'Insert',
|
|
700
|
+
index: 1
|
|
701
|
+
}`,
|
|
702
|
+
minimalExample: `{ key: 'insert', type: 'insert-array-item', label: 'Insert', index: 0 }`
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
type: "remove-array-item",
|
|
706
|
+
category: "button",
|
|
707
|
+
description: "Button to remove the current item from an array field. Typically placed within each array item template. (Legacy alias: removeArrayItem.)",
|
|
673
708
|
valueType: void 0,
|
|
674
709
|
baseInterface: "FieldDef",
|
|
675
710
|
props: {},
|
|
@@ -678,10 +713,46 @@ var FIELD_TYPES = [
|
|
|
678
713
|
allowedIn: ["array", "row", "group"],
|
|
679
714
|
example: `{
|
|
680
715
|
key: 'removeContact',
|
|
681
|
-
type: '
|
|
716
|
+
type: 'remove-array-item',
|
|
682
717
|
label: 'Remove'
|
|
683
718
|
}`,
|
|
684
|
-
minimalExample: `{ key: 'remove', type: '
|
|
719
|
+
minimalExample: `{ key: 'remove', type: 'remove-array-item', label: 'Remove' }`
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
type: "pop-array-item",
|
|
723
|
+
category: "button",
|
|
724
|
+
description: "Button to remove the last item from an array field. (Legacy alias: popArrayItem.)",
|
|
725
|
+
valueType: void 0,
|
|
726
|
+
baseInterface: "FieldDef",
|
|
727
|
+
props: {},
|
|
728
|
+
validationSupported: false,
|
|
729
|
+
source: "adapter",
|
|
730
|
+
allowedIn: ["array", "row", "group"],
|
|
731
|
+
example: `{
|
|
732
|
+
key: 'popContact',
|
|
733
|
+
type: 'pop-array-item',
|
|
734
|
+
label: 'Remove Last',
|
|
735
|
+
arrayKey: 'contacts'
|
|
736
|
+
}`,
|
|
737
|
+
minimalExample: `{ key: 'pop', type: 'pop-array-item', label: 'Remove Last', arrayKey: 'items' }`
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
type: "shift-array-item",
|
|
741
|
+
category: "button",
|
|
742
|
+
description: "Button to remove the first item from an array field. (Legacy alias: shiftArrayItem.)",
|
|
743
|
+
valueType: void 0,
|
|
744
|
+
baseInterface: "FieldDef",
|
|
745
|
+
props: {},
|
|
746
|
+
validationSupported: false,
|
|
747
|
+
source: "adapter",
|
|
748
|
+
allowedIn: ["array", "row", "group"],
|
|
749
|
+
example: `{
|
|
750
|
+
key: 'shiftContact',
|
|
751
|
+
type: 'shift-array-item',
|
|
752
|
+
label: 'Remove First',
|
|
753
|
+
arrayKey: 'contacts'
|
|
754
|
+
}`,
|
|
755
|
+
minimalExample: `{ key: 'shift', type: 'shift-array-item', label: 'Remove First', arrayKey: 'items' }`
|
|
685
756
|
}
|
|
686
757
|
];
|
|
687
758
|
|
|
@@ -1472,7 +1543,7 @@ var WRAPPERS = [
|
|
|
1472
1543
|
category: "demo",
|
|
1473
1544
|
availability: "demo-only",
|
|
1474
1545
|
package: "@internal/examples-shared-ui",
|
|
1475
|
-
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 `
|
|
1546
|
+
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.',
|
|
1476
1547
|
props: {
|
|
1477
1548
|
title: {
|
|
1478
1549
|
name: "title",
|
|
@@ -2828,6 +2899,8 @@ Evaluates a JavaScript expression with access to \`formValue\`, \`fieldValue\`,
|
|
|
2828
2899
|
}
|
|
2829
2900
|
\`\`\`
|
|
2830
2901
|
|
|
2902
|
+
**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.
|
|
2903
|
+
|
|
2831
2904
|
#### Custom Condition
|
|
2832
2905
|
|
|
2833
2906
|
Invokes a registered custom function by name:
|
|
@@ -3005,7 +3078,7 @@ All features are exported from \`@ng-forge/dynamic-forms\`.
|
|
|
3005
3078
|
|
|
3006
3079
|
## CRITICAL: UI Library Differences
|
|
3007
3080
|
|
|
3008
|
-
Different UI libraries support different properties. Always validate against the correct library using \`
|
|
3081
|
+
Different UI libraries support different properties. Always validate against the correct library using \`ngforge_validate\` with the appropriate \`uiIntegration\` parameter.
|
|
3009
3082
|
|
|
3010
3083
|
### Property Differences by Library
|
|
3011
3084
|
|
|
@@ -3048,24 +3121,24 @@ Container fields (\`page\`, \`group\`, \`row\`) do NOT support these properties:
|
|
|
3048
3121
|
{ key: 'volume', type: 'slider', label: 'Volume', min: 0, max: 100 }
|
|
3049
3122
|
\`\`\`
|
|
3050
3123
|
|
|
3051
|
-
5. **Using unsupported field types** - Each UI library supports specific field types. Use \`
|
|
3124
|
+
5. **Using unsupported field types** - Each UI library supports specific field types. Use \`ngforge_lookup\` with \`depth: "schema"\` to see available types.
|
|
3052
3125
|
|
|
3053
3126
|
## Validation Before Use
|
|
3054
3127
|
|
|
3055
|
-
Always validate your FormConfig using the \`
|
|
3128
|
+
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.
|
|
3056
3129
|
|
|
3057
3130
|
\`\`\`typescript
|
|
3058
3131
|
// Always specify the UI integration you're using
|
|
3059
|
-
|
|
3132
|
+
ngforge_validate({
|
|
3060
3133
|
uiIntegration: 'material', // or 'bootstrap', 'primeng', 'ionic'
|
|
3061
3134
|
config: { fields: [...] }
|
|
3062
3135
|
})
|
|
3063
3136
|
\`\`\`
|
|
3064
3137
|
|
|
3065
|
-
To understand what properties are supported for each field type, use \`
|
|
3138
|
+
To understand what properties are supported for each field type, use \`ngforge_lookup\` with \`depth: "schema"\`:
|
|
3066
3139
|
|
|
3067
3140
|
\`\`\`typescript
|
|
3068
|
-
|
|
3141
|
+
ngforge_lookup({ topic: 'input', depth: 'schema', uiIntegration: 'material' })
|
|
3069
3142
|
\`\`\`
|
|
3070
3143
|
`;
|
|
3071
3144
|
|
|
@@ -5178,7 +5251,7 @@ var MatPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5178
5251
|
props: MatButtonPropsSchema.optional()
|
|
5179
5252
|
});
|
|
5180
5253
|
var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5181
|
-
type: z33.literal("
|
|
5254
|
+
type: z33.literal("add-array-item"),
|
|
5182
5255
|
/**
|
|
5183
5256
|
* Key of the array field to add items to.
|
|
5184
5257
|
* If omitted, uses the parent array context.
|
|
@@ -5187,7 +5260,7 @@ var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5187
5260
|
props: MatButtonPropsSchema.optional()
|
|
5188
5261
|
});
|
|
5189
5262
|
var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5190
|
-
type: z33.literal("
|
|
5263
|
+
type: z33.literal("remove-array-item"),
|
|
5191
5264
|
/**
|
|
5192
5265
|
* Key of the array field to remove items from.
|
|
5193
5266
|
* If omitted, uses the parent array context.
|
|
@@ -5195,6 +5268,44 @@ var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5195
5268
|
arrayKey: z33.string().optional(),
|
|
5196
5269
|
props: MatButtonPropsSchema.optional()
|
|
5197
5270
|
});
|
|
5271
|
+
var MatPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5272
|
+
type: z33.literal("prepend-array-item"),
|
|
5273
|
+
/**
|
|
5274
|
+
* Key of the array field to prepend items to.
|
|
5275
|
+
* If omitted, uses the parent array context.
|
|
5276
|
+
*/
|
|
5277
|
+
arrayKey: z33.string().optional(),
|
|
5278
|
+
props: MatButtonPropsSchema.optional()
|
|
5279
|
+
});
|
|
5280
|
+
var MatInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5281
|
+
type: z33.literal("insert-array-item"),
|
|
5282
|
+
/**
|
|
5283
|
+
* Key of the array field to insert items into.
|
|
5284
|
+
* If omitted, uses the parent array context.
|
|
5285
|
+
*/
|
|
5286
|
+
arrayKey: z33.string().optional(),
|
|
5287
|
+
/**
|
|
5288
|
+
* Index at which to insert the new item.
|
|
5289
|
+
*/
|
|
5290
|
+
index: z33.number(),
|
|
5291
|
+
props: MatButtonPropsSchema.optional()
|
|
5292
|
+
});
|
|
5293
|
+
var MatPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5294
|
+
type: z33.literal("pop-array-item"),
|
|
5295
|
+
/**
|
|
5296
|
+
* Key of the array field to pop items from.
|
|
5297
|
+
*/
|
|
5298
|
+
arrayKey: z33.string(),
|
|
5299
|
+
props: MatButtonPropsSchema.optional()
|
|
5300
|
+
});
|
|
5301
|
+
var MatShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5302
|
+
type: z33.literal("shift-array-item"),
|
|
5303
|
+
/**
|
|
5304
|
+
* Key of the array field to shift items from.
|
|
5305
|
+
*/
|
|
5306
|
+
arrayKey: z33.string(),
|
|
5307
|
+
props: MatButtonPropsSchema.optional()
|
|
5308
|
+
});
|
|
5198
5309
|
|
|
5199
5310
|
// internal/dynamic-forms-zod/material/src/mat-leaf-field.schema.ts
|
|
5200
5311
|
import { z as z36 } from "zod";
|
|
@@ -5270,7 +5381,11 @@ var MatLeafFieldSchema = z36.discriminatedUnion("type", [
|
|
|
5270
5381
|
MatNextButtonFieldSchema,
|
|
5271
5382
|
MatPreviousButtonFieldSchema,
|
|
5272
5383
|
MatAddArrayItemButtonFieldSchema,
|
|
5273
|
-
MatRemoveArrayItemButtonFieldSchema
|
|
5384
|
+
MatRemoveArrayItemButtonFieldSchema,
|
|
5385
|
+
MatPrependArrayItemButtonFieldSchema,
|
|
5386
|
+
MatInsertArrayItemButtonFieldSchema,
|
|
5387
|
+
MatPopArrayItemButtonFieldSchema,
|
|
5388
|
+
MatShiftArrayItemButtonFieldSchema
|
|
5274
5389
|
]).superRefine(nullableValueRefine);
|
|
5275
5390
|
|
|
5276
5391
|
// internal/dynamic-forms-zod/src/lib/schemas/containers/factories.ts
|
|
@@ -5738,15 +5853,36 @@ var BsPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5738
5853
|
props: BsButtonPropsSchema.optional()
|
|
5739
5854
|
});
|
|
5740
5855
|
var BsAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5741
|
-
type: z44.literal("
|
|
5856
|
+
type: z44.literal("add-array-item"),
|
|
5742
5857
|
arrayKey: z44.string().optional(),
|
|
5743
5858
|
props: BsButtonPropsSchema.optional()
|
|
5744
5859
|
});
|
|
5745
5860
|
var BsRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5746
|
-
type: z44.literal("
|
|
5861
|
+
type: z44.literal("remove-array-item"),
|
|
5747
5862
|
arrayKey: z44.string().optional(),
|
|
5748
5863
|
props: BsButtonPropsSchema.optional()
|
|
5749
5864
|
});
|
|
5865
|
+
var BsPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5866
|
+
type: z44.literal("prepend-array-item"),
|
|
5867
|
+
arrayKey: z44.string().optional(),
|
|
5868
|
+
props: BsButtonPropsSchema.optional()
|
|
5869
|
+
});
|
|
5870
|
+
var BsInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5871
|
+
type: z44.literal("insert-array-item"),
|
|
5872
|
+
arrayKey: z44.string().optional(),
|
|
5873
|
+
index: z44.number(),
|
|
5874
|
+
props: BsButtonPropsSchema.optional()
|
|
5875
|
+
});
|
|
5876
|
+
var BsPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5877
|
+
type: z44.literal("pop-array-item"),
|
|
5878
|
+
arrayKey: z44.string(),
|
|
5879
|
+
props: BsButtonPropsSchema.optional()
|
|
5880
|
+
});
|
|
5881
|
+
var BsShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5882
|
+
type: z44.literal("shift-array-item"),
|
|
5883
|
+
arrayKey: z44.string(),
|
|
5884
|
+
props: BsButtonPropsSchema.optional()
|
|
5885
|
+
});
|
|
5750
5886
|
|
|
5751
5887
|
// internal/dynamic-forms-zod/bootstrap/src/bs-leaf-field.schema.ts
|
|
5752
5888
|
import { z as z45 } from "zod";
|
|
@@ -5767,7 +5903,11 @@ var BsLeafFieldSchema = z45.discriminatedUnion("type", [
|
|
|
5767
5903
|
BsNextButtonFieldSchema,
|
|
5768
5904
|
BsPreviousButtonFieldSchema,
|
|
5769
5905
|
BsAddArrayItemButtonFieldSchema,
|
|
5770
|
-
BsRemoveArrayItemButtonFieldSchema
|
|
5906
|
+
BsRemoveArrayItemButtonFieldSchema,
|
|
5907
|
+
BsPrependArrayItemButtonFieldSchema,
|
|
5908
|
+
BsInsertArrayItemButtonFieldSchema,
|
|
5909
|
+
BsPopArrayItemButtonFieldSchema,
|
|
5910
|
+
BsShiftArrayItemButtonFieldSchema
|
|
5771
5911
|
]).superRefine(nullableValueRefine);
|
|
5772
5912
|
|
|
5773
5913
|
// internal/dynamic-forms-zod/bootstrap/src/bs-form-config.schema.ts
|
|
@@ -5950,15 +6090,36 @@ var PrimePreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
5950
6090
|
props: PrimeButtonPropsSchema.optional()
|
|
5951
6091
|
});
|
|
5952
6092
|
var PrimeAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5953
|
-
type: z48.literal("
|
|
6093
|
+
type: z48.literal("add-array-item"),
|
|
5954
6094
|
arrayKey: z48.string().optional(),
|
|
5955
6095
|
props: PrimeButtonPropsSchema.optional()
|
|
5956
6096
|
});
|
|
5957
6097
|
var PrimeRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
5958
|
-
type: z48.literal("
|
|
6098
|
+
type: z48.literal("remove-array-item"),
|
|
6099
|
+
arrayKey: z48.string().optional(),
|
|
6100
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6101
|
+
});
|
|
6102
|
+
var PrimePrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6103
|
+
type: z48.literal("prepend-array-item"),
|
|
5959
6104
|
arrayKey: z48.string().optional(),
|
|
5960
6105
|
props: PrimeButtonPropsSchema.optional()
|
|
5961
6106
|
});
|
|
6107
|
+
var PrimeInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6108
|
+
type: z48.literal("insert-array-item"),
|
|
6109
|
+
arrayKey: z48.string().optional(),
|
|
6110
|
+
index: z48.number(),
|
|
6111
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6112
|
+
});
|
|
6113
|
+
var PrimePopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6114
|
+
type: z48.literal("pop-array-item"),
|
|
6115
|
+
arrayKey: z48.string(),
|
|
6116
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6117
|
+
});
|
|
6118
|
+
var PrimeShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6119
|
+
type: z48.literal("shift-array-item"),
|
|
6120
|
+
arrayKey: z48.string(),
|
|
6121
|
+
props: PrimeButtonPropsSchema.optional()
|
|
6122
|
+
});
|
|
5962
6123
|
|
|
5963
6124
|
// internal/dynamic-forms-zod/primeng/src/prime-leaf-field.schema.ts
|
|
5964
6125
|
import { z as z49 } from "zod";
|
|
@@ -5979,7 +6140,11 @@ var PrimeLeafFieldSchema = z49.discriminatedUnion("type", [
|
|
|
5979
6140
|
PrimeNextButtonFieldSchema,
|
|
5980
6141
|
PrimePreviousButtonFieldSchema,
|
|
5981
6142
|
PrimeAddArrayItemButtonFieldSchema,
|
|
5982
|
-
PrimeRemoveArrayItemButtonFieldSchema
|
|
6143
|
+
PrimeRemoveArrayItemButtonFieldSchema,
|
|
6144
|
+
PrimePrependArrayItemButtonFieldSchema,
|
|
6145
|
+
PrimeInsertArrayItemButtonFieldSchema,
|
|
6146
|
+
PrimePopArrayItemButtonFieldSchema,
|
|
6147
|
+
PrimeShiftArrayItemButtonFieldSchema
|
|
5983
6148
|
]).superRefine(nullableValueRefine);
|
|
5984
6149
|
|
|
5985
6150
|
// internal/dynamic-forms-zod/primeng/src/prime-form-config.schema.ts
|
|
@@ -6204,13 +6369,34 @@ var IonicPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
|
6204
6369
|
props: IonicButtonPropsSchema.optional()
|
|
6205
6370
|
});
|
|
6206
6371
|
var IonicAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6207
|
-
type: z52.literal("
|
|
6372
|
+
type: z52.literal("add-array-item"),
|
|
6208
6373
|
arrayKey: z52.string().optional(),
|
|
6209
6374
|
props: IonicButtonPropsSchema.optional()
|
|
6210
6375
|
});
|
|
6211
6376
|
var IonicRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6212
|
-
type: z52.literal("
|
|
6377
|
+
type: z52.literal("remove-array-item"),
|
|
6378
|
+
arrayKey: z52.string().optional(),
|
|
6379
|
+
props: IonicButtonPropsSchema.optional()
|
|
6380
|
+
});
|
|
6381
|
+
var IonicPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6382
|
+
type: z52.literal("prepend-array-item"),
|
|
6383
|
+
arrayKey: z52.string().optional(),
|
|
6384
|
+
props: IonicButtonPropsSchema.optional()
|
|
6385
|
+
});
|
|
6386
|
+
var IonicInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6387
|
+
type: z52.literal("insert-array-item"),
|
|
6213
6388
|
arrayKey: z52.string().optional(),
|
|
6389
|
+
index: z52.number(),
|
|
6390
|
+
props: IonicButtonPropsSchema.optional()
|
|
6391
|
+
});
|
|
6392
|
+
var IonicPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6393
|
+
type: z52.literal("pop-array-item"),
|
|
6394
|
+
arrayKey: z52.string(),
|
|
6395
|
+
props: IonicButtonPropsSchema.optional()
|
|
6396
|
+
});
|
|
6397
|
+
var IonicShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
|
|
6398
|
+
type: z52.literal("shift-array-item"),
|
|
6399
|
+
arrayKey: z52.string(),
|
|
6214
6400
|
props: IonicButtonPropsSchema.optional()
|
|
6215
6401
|
});
|
|
6216
6402
|
|
|
@@ -6233,7 +6419,11 @@ var IonicLeafFieldSchema = z53.discriminatedUnion("type", [
|
|
|
6233
6419
|
IonicNextButtonFieldSchema,
|
|
6234
6420
|
IonicPreviousButtonFieldSchema,
|
|
6235
6421
|
IonicAddArrayItemButtonFieldSchema,
|
|
6236
|
-
IonicRemoveArrayItemButtonFieldSchema
|
|
6422
|
+
IonicRemoveArrayItemButtonFieldSchema,
|
|
6423
|
+
IonicPrependArrayItemButtonFieldSchema,
|
|
6424
|
+
IonicInsertArrayItemButtonFieldSchema,
|
|
6425
|
+
IonicPopArrayItemButtonFieldSchema,
|
|
6426
|
+
IonicShiftArrayItemButtonFieldSchema
|
|
6237
6427
|
]).superRefine(nullableValueRefine);
|
|
6238
6428
|
|
|
6239
6429
|
// internal/dynamic-forms-zod/ionic/src/ionic-form-config.schema.ts
|
|
@@ -6578,8 +6768,12 @@ var NESTING_RULES = {
|
|
|
6578
6768
|
"submit",
|
|
6579
6769
|
"next",
|
|
6580
6770
|
"previous",
|
|
6581
|
-
"
|
|
6582
|
-
"
|
|
6771
|
+
"add-array-item",
|
|
6772
|
+
"prepend-array-item",
|
|
6773
|
+
"insert-array-item",
|
|
6774
|
+
"remove-array-item",
|
|
6775
|
+
"pop-array-item",
|
|
6776
|
+
"shift-array-item"
|
|
6583
6777
|
],
|
|
6584
6778
|
forbidden: ["page"],
|
|
6585
6779
|
message: "Pages cannot be nested inside other containers. ALL top-level fields must be pages if using multi-page mode."
|
|
@@ -6602,8 +6796,12 @@ var NESTING_RULES = {
|
|
|
6602
6796
|
"submit",
|
|
6603
6797
|
"next",
|
|
6604
6798
|
"previous",
|
|
6605
|
-
"
|
|
6606
|
-
"
|
|
6799
|
+
"add-array-item",
|
|
6800
|
+
"prepend-array-item",
|
|
6801
|
+
"insert-array-item",
|
|
6802
|
+
"remove-array-item",
|
|
6803
|
+
"pop-array-item",
|
|
6804
|
+
"shift-array-item"
|
|
6607
6805
|
],
|
|
6608
6806
|
forbidden: ["page", "row", "hidden"],
|
|
6609
6807
|
message: "Rows cannot contain pages, other rows, or hidden fields. Hidden fields should be at page or form level."
|
|
@@ -6626,8 +6824,12 @@ var NESTING_RULES = {
|
|
|
6626
6824
|
"submit",
|
|
6627
6825
|
"next",
|
|
6628
6826
|
"previous",
|
|
6629
|
-
"
|
|
6630
|
-
"
|
|
6827
|
+
"add-array-item",
|
|
6828
|
+
"prepend-array-item",
|
|
6829
|
+
"insert-array-item",
|
|
6830
|
+
"remove-array-item",
|
|
6831
|
+
"pop-array-item",
|
|
6832
|
+
"shift-array-item"
|
|
6631
6833
|
],
|
|
6632
6834
|
forbidden: ["page", "group"],
|
|
6633
6835
|
message: "Groups cannot contain pages or other groups (no nested groups)."
|
|
@@ -6651,8 +6853,12 @@ var NESTING_RULES = {
|
|
|
6651
6853
|
"submit",
|
|
6652
6854
|
"next",
|
|
6653
6855
|
"previous",
|
|
6654
|
-
"
|
|
6655
|
-
"
|
|
6856
|
+
"add-array-item",
|
|
6857
|
+
"prepend-array-item",
|
|
6858
|
+
"insert-array-item",
|
|
6859
|
+
"remove-array-item",
|
|
6860
|
+
"pop-array-item",
|
|
6861
|
+
"shift-array-item"
|
|
6656
6862
|
],
|
|
6657
6863
|
forbidden: ["page", "array"],
|
|
6658
6864
|
message: "Arrays cannot contain pages or other arrays (no nested arrays)."
|
|
@@ -6898,6 +7104,27 @@ function preValidateConfig(config) {
|
|
|
6898
7104
|
});
|
|
6899
7105
|
return errors;
|
|
6900
7106
|
}
|
|
7107
|
+
var LEGACY_ARRAY_ACTION_TYPES = {
|
|
7108
|
+
addArrayItem: "add-array-item",
|
|
7109
|
+
prependArrayItem: "prepend-array-item",
|
|
7110
|
+
insertArrayItem: "insert-array-item",
|
|
7111
|
+
removeArrayItem: "remove-array-item",
|
|
7112
|
+
popArrayItem: "pop-array-item",
|
|
7113
|
+
shiftArrayItem: "shift-array-item"
|
|
7114
|
+
};
|
|
7115
|
+
function normalizeLegacyArrayActionTypes(value) {
|
|
7116
|
+
if (Array.isArray(value)) {
|
|
7117
|
+
return value.map(normalizeLegacyArrayActionTypes);
|
|
7118
|
+
}
|
|
7119
|
+
if (value && typeof value === "object") {
|
|
7120
|
+
const out = {};
|
|
7121
|
+
for (const [key, val] of Object.entries(value)) {
|
|
7122
|
+
out[key] = key === "type" && typeof val === "string" && LEGACY_ARRAY_ACTION_TYPES[val] ? LEGACY_ARRAY_ACTION_TYPES[val] : normalizeLegacyArrayActionTypes(val);
|
|
7123
|
+
}
|
|
7124
|
+
return out;
|
|
7125
|
+
}
|
|
7126
|
+
return value;
|
|
7127
|
+
}
|
|
6901
7128
|
function validateFormConfig(uiIntegration, config) {
|
|
6902
7129
|
const schema = formConfigSchemas[uiIntegration];
|
|
6903
7130
|
if (!schema) {
|
|
@@ -6912,15 +7139,16 @@ function validateFormConfig(uiIntegration, config) {
|
|
|
6912
7139
|
errorSummary: `Unknown UI integration: ${uiIntegration}`
|
|
6913
7140
|
};
|
|
6914
7141
|
}
|
|
6915
|
-
const
|
|
6916
|
-
const
|
|
7142
|
+
const normalizedConfig = normalizeLegacyArrayActionTypes(config);
|
|
7143
|
+
const preErrors = preValidateConfig(normalizedConfig);
|
|
7144
|
+
const result = schema.safeParse(normalizedConfig);
|
|
6917
7145
|
if (result.success && preErrors.length === 0) {
|
|
6918
7146
|
return {
|
|
6919
7147
|
valid: true,
|
|
6920
7148
|
data: result.data
|
|
6921
7149
|
};
|
|
6922
7150
|
}
|
|
6923
|
-
const zodErrors = result.success ? [] : formatZodError(result.error,
|
|
7151
|
+
const zodErrors = result.success ? [] : formatZodError(result.error, normalizedConfig);
|
|
6924
7152
|
const allErrors = [...preErrors, ...zodErrors];
|
|
6925
7153
|
return {
|
|
6926
7154
|
valid: false,
|
|
@@ -6947,29 +7175,32 @@ ${UI_INTEGRATIONS.map((ui) => `- ${ui}`).join("\n")}
|
|
|
6947
7175
|
## Field Types
|
|
6948
7176
|
${fieldTypes.map((ft) => `- ${ft}`).join("\n")}
|
|
6949
7177
|
|
|
6950
|
-
## Tools (
|
|
7178
|
+
## Tools (5 total - consolidated)
|
|
6951
7179
|
|
|
6952
|
-
**1. START HERE -
|
|
6953
|
-
\`
|
|
7180
|
+
**1. START HERE - Documentation lookup:**
|
|
7181
|
+
\`ngforge_lookup(topic, depth?, uiIntegration?)\`
|
|
7182
|
+
- topic="workflow" for the recommended tool-usage guide
|
|
6954
7183
|
- Property placement rules, condition syntax, copy-paste patterns, common errors
|
|
6955
|
-
-
|
|
6956
|
-
- **Use this first** - it has 90% of what you need in one call
|
|
7184
|
+
- depth="brief|full|schema" (default full); uiIntegration filters schema output
|
|
6957
7185
|
|
|
6958
|
-
**2.
|
|
6959
|
-
\`
|
|
7186
|
+
**2. Search:**
|
|
7187
|
+
\`ngforge_search(query)\`
|
|
7188
|
+
- Free-text keyword search across all topics and examples
|
|
7189
|
+
- Use when you don't know the exact topic name
|
|
7190
|
+
|
|
7191
|
+
**3. Validation:**
|
|
7192
|
+
\`ngforge_validate(config, uiIntegration?)\`
|
|
6960
7193
|
- Validates config against actual TypeScript types
|
|
6961
7194
|
- Catches errors before runtime
|
|
6962
7195
|
|
|
6963
|
-
**
|
|
6964
|
-
\`
|
|
6965
|
-
- Properties, validators, and examples for a specific field type
|
|
6966
|
-
- Set includeSchema=true for JSON Schema (machine-readable)
|
|
6967
|
-
|
|
6968
|
-
**4. Examples + deep explanations:**
|
|
6969
|
-
\`ngforge_get_example(pattern?, depth?)\`
|
|
7196
|
+
**4. Examples:**
|
|
7197
|
+
\`ngforge_examples(pattern, depth?)\`
|
|
6970
7198
|
- Patterns: complete, derivation, conditional, multi-page, validation
|
|
6971
|
-
- depth
|
|
6972
|
-
|
|
7199
|
+
- depth controls how much detail (working code vs. deep explanation)
|
|
7200
|
+
|
|
7201
|
+
**5. Scaffold:**
|
|
7202
|
+
\`ngforge_scaffold(fields?, pages?, arrays?, groups?, hidden?, uiIntegration?)\`
|
|
7203
|
+
- Generates a compilable FormConfig skeleton
|
|
6973
7204
|
`
|
|
6974
7205
|
}
|
|
6975
7206
|
]
|
|
@@ -7629,8 +7860,8 @@ interface SimplifiedArrayField {
|
|
|
7629
7860
|
|
|
7630
7861
|
The simplified API is normalized into the full API at runtime:
|
|
7631
7862
|
1. Each \`value\` element creates an item using the \`template\` structure
|
|
7632
|
-
2. An \`
|
|
7633
|
-
3. A \`
|
|
7863
|
+
2. An \`add-array-item\` button is auto-generated after the array (unless \`addButton: false\`)
|
|
7864
|
+
3. A \`remove-array-item\` button is added to each item (unless \`removeButton: false\`)
|
|
7634
7865
|
|
|
7635
7866
|
## Conditional Visibility
|
|
7636
7867
|
|
|
@@ -7844,6 +8075,7 @@ logic: [{ type: 'derivation', functionName: 'computeFromGroup', dependsOn: ['$gr
|
|
|
7844
8075
|
\`\`\`
|
|
7845
8076
|
Derivation is always defined ON the field that receives the computed value (self-targeting).
|
|
7846
8077
|
\`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.
|
|
8078
|
+
**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.
|
|
7847
8079
|
**Variables:** \`formValue\`, \`fieldValue\`, \`fieldState\`, \`formFieldState\`, \`externalData\` (see topic: expression-variables)
|
|
7848
8080
|
**For deriving component properties** (minDate, options, label): use \`targetProperty\` (see topic \`property-derivation\`)`,
|
|
7849
8081
|
full: `# Value Derivation (Computed Fields)
|
|
@@ -8205,7 +8437,8 @@ Wrong: Wrong property names
|
|
|
8205
8437
|
|
|
8206
8438
|
| Variable | Type | Available In | Description |
|
|
8207
8439
|
|----------|------|--------------|-------------|
|
|
8208
|
-
| \`formValue\` | object | Derivations, conditions, custom validators |
|
|
8440
|
+
| \`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 |
|
|
8441
|
+
| \`rootFormValue\` | object | Scoped contexts (array items, group-nested derivations) | The whole form value when \`formValue\` is scoped |
|
|
8209
8442
|
| \`fieldValue\` | any | Custom validator expressions only | Current field's value |
|
|
8210
8443
|
| \`fieldState\` | object | Derivations, conditions | Current field's state (touched, dirty, valid, etc.) |
|
|
8211
8444
|
| \`formFieldState\` | object | Derivations, conditions | All fields' states keyed by field key |
|
|
@@ -9383,19 +9616,19 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9383
9616
|
- Together they give you: type safety + exact type inference`
|
|
9384
9617
|
},
|
|
9385
9618
|
"array-buttons": {
|
|
9386
|
-
brief: `**Add:** \`{ type: '
|
|
9387
|
-
**Remove:** \`{ type: '
|
|
9619
|
+
brief: `**Add:** \`{ type: 'add-array-item', key: 'add', label: 'Add', arrayKey: 'contacts' }\`
|
|
9620
|
+
**Remove:** \`{ type: 'remove-array-item', key: 'remove', label: 'Remove' }\` (inside array template)
|
|
9388
9621
|
\u26A0\uFE0F arrayKey at FIELD level, NOT in props!`,
|
|
9389
9622
|
full: `# Array Buttons (Add/Remove Items)
|
|
9390
9623
|
|
|
9391
|
-
**UI libraries provide \`
|
|
9624
|
+
**UI libraries provide \`add-array-item\` and \`remove-array-item\` button types.**
|
|
9392
9625
|
|
|
9393
9626
|
## Add Item Button
|
|
9394
9627
|
|
|
9395
9628
|
\`\`\`typescript
|
|
9396
9629
|
{
|
|
9397
9630
|
key: 'addPhone',
|
|
9398
|
-
type: '
|
|
9631
|
+
type: 'add-array-item',
|
|
9399
9632
|
label: 'Add Phone',
|
|
9400
9633
|
arrayKey: 'phones', // \u26A0\uFE0F AT FIELD LEVEL, NOT IN PROPS!
|
|
9401
9634
|
props: {
|
|
@@ -9417,7 +9650,7 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9417
9650
|
{ key: 'number', type: 'input', label: 'Phone Number' },
|
|
9418
9651
|
{
|
|
9419
9652
|
key: 'removePhone',
|
|
9420
|
-
type: '
|
|
9653
|
+
type: 'remove-array-item',
|
|
9421
9654
|
label: 'Remove',
|
|
9422
9655
|
// arrayKey not needed - inferred from parent array
|
|
9423
9656
|
props: { color: 'warn' }
|
|
@@ -9432,13 +9665,13 @@ const config = { fields: [...] } as const satisfies FormConfig;
|
|
|
9432
9665
|
\`\`\`typescript
|
|
9433
9666
|
// WRONG - arrayKey in props
|
|
9434
9667
|
{
|
|
9435
|
-
type: '
|
|
9668
|
+
type: 'add-array-item',
|
|
9436
9669
|
props: { arrayKey: 'phones' } // \u274C WRONG LOCATION
|
|
9437
9670
|
}
|
|
9438
9671
|
|
|
9439
9672
|
// CORRECT - arrayKey at field level
|
|
9440
9673
|
{
|
|
9441
|
-
type: '
|
|
9674
|
+
type: 'add-array-item',
|
|
9442
9675
|
arrayKey: 'phones', // \u2705 CORRECT
|
|
9443
9676
|
props: { color: 'primary' }
|
|
9444
9677
|
}
|
|
@@ -9707,8 +9940,19 @@ var TOPIC_ALIASES = {
|
|
|
9707
9940
|
valueof: "context-api",
|
|
9708
9941
|
"add-array": "array-buttons",
|
|
9709
9942
|
"remove-array": "array-buttons",
|
|
9943
|
+
// Array-action field types: kebab-case canonical + camelCase legacy aliases
|
|
9944
|
+
"add-array-item": "array-buttons",
|
|
9945
|
+
"prepend-array-item": "array-buttons",
|
|
9946
|
+
"insert-array-item": "array-buttons",
|
|
9947
|
+
"remove-array-item": "array-buttons",
|
|
9948
|
+
"pop-array-item": "array-buttons",
|
|
9949
|
+
"shift-array-item": "array-buttons",
|
|
9710
9950
|
addarrayitem: "array-buttons",
|
|
9951
|
+
prependarrayitem: "array-buttons",
|
|
9952
|
+
insertarrayitem: "array-buttons",
|
|
9711
9953
|
removearrayitem: "array-buttons",
|
|
9954
|
+
poparrayitem: "array-buttons",
|
|
9955
|
+
shiftarrayitem: "array-buttons",
|
|
9712
9956
|
"custom-validator": "custom-validators",
|
|
9713
9957
|
customvalidator: "custom-validators",
|
|
9714
9958
|
mistakes: "pitfalls",
|
|
@@ -10753,7 +10997,7 @@ For full control, use the \`fields\`-based API with explicit add/remove buttons:
|
|
|
10753
10997
|
]
|
|
10754
10998
|
]
|
|
10755
10999
|
}
|
|
10756
|
-
// + separate
|
|
11000
|
+
// + separate add-array-item button with arrayKey
|
|
10757
11001
|
\`\`\``,
|
|
10758
11002
|
explained: `# Array Fields - Complete Explanation
|
|
10759
11003
|
|
|
@@ -10825,7 +11069,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
|
|
|
10825
11069
|
// ADD button - place OUTSIDE the array
|
|
10826
11070
|
{
|
|
10827
11071
|
key: 'addContact',
|
|
10828
|
-
type: '
|
|
11072
|
+
type: 'add-array-item',
|
|
10829
11073
|
label: 'Add Contact',
|
|
10830
11074
|
arrayKey: 'contacts', // \u26A0\uFE0F AT FIELD LEVEL!
|
|
10831
11075
|
}
|
|
@@ -10837,7 +11081,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
|
|
|
10837
11081
|
fields: [
|
|
10838
11082
|
[
|
|
10839
11083
|
{ key: 'name', type: 'input', label: 'Name' },
|
|
10840
|
-
{ key: 'remove', type: '
|
|
11084
|
+
{ key: 'remove', type: 'remove-array-item', label: 'Remove' }
|
|
10841
11085
|
]
|
|
10842
11086
|
]
|
|
10843
11087
|
}
|
|
@@ -10871,8 +11115,8 @@ expression: '(formValue.items || []).reduce((sum, item) => sum + (item.price ||
|
|
|
10871
11115
|
|
|
10872
11116
|
\u274C Putting \`arrayKey\` in props (full API):
|
|
10873
11117
|
\`\`\`typescript
|
|
10874
|
-
{ type: '
|
|
10875
|
-
{ type: '
|
|
11118
|
+
{ type: 'add-array-item', props: { arrayKey: 'x' } } // WRONG
|
|
11119
|
+
{ type: 'add-array-item', arrayKey: 'x' } // CORRECT
|
|
10876
11120
|
\`\`\``
|
|
10877
11121
|
},
|
|
10878
11122
|
"minimal-simplified-array": {
|