@timeax/digital-service-engine 0.3.4 → 0.3.6

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.
@@ -59,7 +59,7 @@ type NodeRef$1 = {
59
59
  };
60
60
  type NodeMap = Map<string, NodeRef$1>;
61
61
 
62
- type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern" | "multiple_order_kinds_selected";
62
+ type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "bad_option_effect_key" | "bad_option_effect_target" | "bad_option_effect_option" | "option_include_exclude_conflict" | "visibility_dependency_cycle" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern" | "multiple_order_kinds_selected";
63
63
  type ValidationError = {
64
64
  code: ValidationCode;
65
65
  message: string;
@@ -186,6 +186,75 @@ interface BaseFieldUI {
186
186
  /** Host-defined prop names → runtime default values (untyped base) */
187
187
  defaults?: Record<string, unknown>;
188
188
  }
189
+ type Ui = (UiString | UiNumber | UiBoolean | UiAnyOf | UiArray | UiObject) & {
190
+ description: string;
191
+ label: string;
192
+ };
193
+ /** string */
194
+ interface UiString {
195
+ type: "string";
196
+ enum?: string[];
197
+ minLength?: number;
198
+ maxLength?: number;
199
+ pattern?: string;
200
+ format?: string;
201
+ }
202
+ /** number */
203
+ interface UiNumber {
204
+ type: "number";
205
+ minimum?: number;
206
+ maximum?: number;
207
+ multipleOf?: number;
208
+ }
209
+ /** boolean */
210
+ interface UiBoolean {
211
+ type: "boolean";
212
+ }
213
+ /** enumerated choices */
214
+ interface UiAnyOf {
215
+ type: "anyOf";
216
+ multiple?: boolean;
217
+ items: Array<{
218
+ type: "string" | "number" | "boolean";
219
+ title?: string;
220
+ description?: string;
221
+ value: string | number | boolean;
222
+ }>;
223
+ }
224
+ /** arrays: homogeneous (item) or tuple (items) */
225
+ interface UiArray {
226
+ type: "array";
227
+ label: string;
228
+ description: string;
229
+ item?: Ui;
230
+ items?: Ui[];
231
+ editable?: boolean;
232
+ /**
233
+ * Optional: allowed shapes for new items.
234
+ * Key = label shown in UI picker
235
+ * Value = schema for the new element
236
+ */
237
+ shape?: Record<string, Ui>;
238
+ minItems?: number;
239
+ maxItems?: number;
240
+ uniqueItems?: boolean;
241
+ }
242
+ /** objects: nested props */
243
+ interface UiObject {
244
+ type: "object";
245
+ label: string;
246
+ description: string;
247
+ editable?: boolean;
248
+ fields: Record<string, Ui>;
249
+ /**
250
+ * Optional: allowed shapes for dynamically added keys.
251
+ * Key = human-readable name shown in UI picker
252
+ * Value = schema applied to the value of the new key
253
+ */
254
+ shape?: Record<string, Ui>;
255
+ required?: string[];
256
+ order?: string[];
257
+ }
189
258
  type FieldValidationValueBy = "value" | "length" | "eval";
190
259
  type FieldValidationOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "between" | "in" | "nin" | "truthy" | "falsy" | "match";
191
260
  type FieldValidationRule = {
@@ -207,6 +276,22 @@ type FieldOption = {
207
276
  service_id?: ServiceIdRef;
208
277
  pricing_role?: PricingRole;
209
278
  meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
279
+ children?: FieldOption[];
280
+ };
281
+ type OptionEffectForButton = {
282
+ /**
283
+ * If true, selecting this button/option may force the target field visible.
284
+ * If false/missing, the option filter only applies when the target field is already visible.
285
+ */
286
+ forceVisible?: boolean;
287
+ /**
288
+ * If present, only these option ids remain visible.
289
+ */
290
+ include?: string[];
291
+ /**
292
+ * Removed after include is applied.
293
+ */
294
+ exclude?: string[];
210
295
  };
211
296
  type Field = BaseFieldUI & {
212
297
  id: string;
@@ -260,6 +345,7 @@ type ServiceProps = {
260
345
  fields: Field[];
261
346
  includes_for_buttons?: Record<string, string[]>;
262
347
  excludes_for_buttons?: Record<string, string[]>;
348
+ option_effects_for_buttons?: Record<string, Record<string, OptionEffectForButton>>;
263
349
  schema_version?: string;
264
350
  fallbacks?: ServiceFallback;
265
351
  name?: string;
@@ -355,6 +441,12 @@ type CommentThread = {
355
441
  _sync?: "pending" | "synced" | "error";
356
442
  };
357
443
 
444
+ type ResolvedVisibility = {
445
+ fieldIds: string[];
446
+ optionsByFieldId: Record<string, string[]>;
447
+ forcedFieldIds: string[];
448
+ };
449
+
358
450
  /** Options you can set on the builder (used for validation/visibility) */
359
451
  type BuilderOptions = Omit<ValidatorOptions, "serviceMap"> & {
360
452
  serviceMap?: DgpServiceMap;
@@ -380,6 +472,8 @@ interface Builder {
380
472
  * NOTE: keys are “button ids”: either option.id or field.id for option-less buttons.
381
473
  */
382
474
  visibleFields(tagId: string, selectedOptionKeys?: string[]): string[];
475
+ /** Compute field ids plus option visibility under a tag. */
476
+ resolveVisibility(tagId: string, selectedOptionKeys?: string[]): ResolvedVisibility;
383
477
  /** Update builder options (validator context etc.) */
384
478
  setOptions(patch: Partial<BuilderOptions>): void;
385
479
  /** Access the current props (already normalised) */
@@ -501,6 +595,8 @@ type VisibleGroup = {
501
595
  tag?: Tag;
502
596
  fields: Field[];
503
597
  fieldIds: string[];
598
+ optionsByFieldId?: Record<string, string[]>;
599
+ forcedFieldIds?: string[];
504
600
  parentTags?: Tag[];
505
601
  childrenTags?: Tag[];
506
602
  /** In order of selection: tag base (unless overridden) then selected options */
@@ -550,11 +646,10 @@ declare class Selection {
550
646
  * What counts as a "button selection" (trigger key):
551
647
  * - field key where the field has button === true (e.g. "f:dripfeed")
552
648
  * - option key (e.g. "o:fast")
553
- * - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
554
649
  *
555
650
  * Grouping:
556
651
  * - button-field trigger groups under its own fieldId
557
- * - option/composite groups under the option's owning fieldId (from nodeMap)
652
+ * - option trigger groups under the option's owning fieldId (from nodeMap)
558
653
  *
559
654
  * Deterministic:
560
655
  * - preserves selection insertion order
@@ -565,7 +660,6 @@ declare class Selection {
565
660
  * Returns only selection keys that are valid "trigger buttons":
566
661
  * - field keys where field.button === true
567
662
  * - option keys
568
- * - composite keys "fieldId::optionId" (validated by optionId)
569
663
  * Excludes tags and non-button fields.
570
664
  */
571
665
  selectedButtons(): string[];
@@ -575,6 +669,7 @@ declare class Selection {
575
669
  private computeGroupForTag;
576
670
  private addServiceByRole;
577
671
  private findOptionById;
672
+ private isSelectedOptionVisible;
578
673
  }
579
674
 
580
675
  type CatalogId = string;
@@ -1692,6 +1787,66 @@ type QuantityRule = {
1692
1787
  fallback?: number;
1693
1788
  };
1694
1789
 
1790
+ /** Matches your InputWrapper’s expectations */
1791
+ type InputKind = string;
1792
+ type InputVariant = "default" | (string & {});
1793
+ type AdapterCtx = {
1794
+ field: Field;
1795
+ props: ServiceProps;
1796
+ };
1797
+ type Adapter = {
1798
+ valueProp?: string;
1799
+ changeProp?: string;
1800
+ errorProp?: string;
1801
+ /** normalize what the host emitted into what we store in form-palette */
1802
+ getValue?: (next: unknown, current: unknown, ctx: AdapterCtx) => unknown;
1803
+ /** REQUIRED if field.options exists */
1804
+ getSelectedOptions?: (next: unknown, current: unknown, ctx: AdapterCtx) => string[];
1805
+ /** For option-less action buttons (button: true with no options) */
1806
+ isActive?: (stored: unknown, ctx: AdapterCtx) => boolean;
1807
+ getInputPropsFromField?: (props: AdapterCtx) => any;
1808
+ toValue?: (value: any) => any;
1809
+ };
1810
+ type InputChildOptionCapability = {
1811
+ supported?: boolean;
1812
+ autoCreate?: boolean;
1813
+ defaultLabel?: string;
1814
+ defaultValue?: string | number;
1815
+ };
1816
+ type InputOptionCapability = {
1817
+ supported?: boolean;
1818
+ autoCreate?: boolean;
1819
+ defaultLabel?: string;
1820
+ defaultValue?: string | number;
1821
+ children?: InputChildOptionCapability;
1822
+ };
1823
+ type InputMultiCapability = {
1824
+ supported?: boolean;
1825
+ autoEnable?: boolean;
1826
+ };
1827
+ type InputDescriptor = {
1828
+ Component: React__default.ComponentType<Record<string, unknown>>;
1829
+ adapter?: Adapter;
1830
+ defaultProps?: Record<string, unknown>;
1831
+ ui?: Record<string, Ui>;
1832
+ options?: InputOptionCapability;
1833
+ multi?: InputMultiCapability;
1834
+ };
1835
+ type VariantMap = Map<InputVariant, InputDescriptor>;
1836
+ type RegistryStore = Map<InputKind, VariantMap>;
1837
+ type Registry = {
1838
+ get(kind: InputKind, variant?: InputVariant): InputDescriptor | undefined;
1839
+ register(kind: InputKind, descriptor: InputDescriptor, variant?: InputVariant): void;
1840
+ unregister(kind: InputKind, variant?: InputVariant): void;
1841
+ registerMany(entries: Array<{
1842
+ kind: InputKind;
1843
+ descriptor: InputDescriptor;
1844
+ variant?: InputVariant;
1845
+ }>): void;
1846
+ /** low-level escape hatch */
1847
+ _store: RegistryStore;
1848
+ };
1849
+
1695
1850
  declare class Editor {
1696
1851
  private readonly builder;
1697
1852
  private readonly api;
@@ -1763,7 +1918,14 @@ declare class Editor {
1763
1918
  id?: string;
1764
1919
  label: string;
1765
1920
  type: Field["type"];
1766
- }): void;
1921
+ }): string;
1922
+ addFieldFromDescriptor(registry: Registry, partial: Omit<Field, "id" | "label" | "type"> & {
1923
+ id?: string;
1924
+ label: string;
1925
+ type: Field["type"];
1926
+ }, opts?: {
1927
+ variant?: InputVariant;
1928
+ }): string;
1767
1929
  updateField(id: string, patch: Partial<Field>): void;
1768
1930
  removeField(id: string): void;
1769
1931
  remove(id: string): void;
@@ -1782,6 +1944,7 @@ declare class Editor {
1782
1944
  setPricingRoleMany(ids: readonly string[], role: "base" | "utility"): void;
1783
1945
  clearFieldDefaultsMany(ids: readonly string[]): void;
1784
1946
  clearFieldValidationMany(ids: readonly string[]): void;
1947
+ setFieldMulti(fieldId: string, enabled: boolean): void;
1785
1948
  autoCreateOptionsMany(ids: readonly string[], makeOption?: (fieldId: string) => {
1786
1949
  id?: string;
1787
1950
  label: string;
@@ -1796,6 +1959,14 @@ declare class Editor {
1796
1959
  clearFieldQuantityRule(id: string): void;
1797
1960
  include(receiverId: string, idOrIds: string | string[]): void;
1798
1961
  exclude(receiverId: string, idOrIds: string | string[]): void;
1962
+ setOptionEffect(triggerId: string, targetFieldId: string, effect: OptionEffectForButton | undefined | null): void;
1963
+ patchOptionEffect(triggerId: string, targetFieldId: string, patch: OptionEffectForButton): void;
1964
+ clearOptionEffect(triggerId: string, targetFieldId: string): void;
1965
+ clearOptionEffectsForTrigger(triggerId: string): void;
1966
+ clearOptionEffectsForTarget(targetFieldId: string): void;
1967
+ addOptionEffectOptions(triggerId: string, targetFieldId: string, kind: "include" | "exclude", optionIds: readonly string[]): void;
1968
+ removeOptionEffectOptions(triggerId: string, targetFieldId: string, kind: "include" | "exclude", optionIds: readonly string[]): void;
1969
+ setOptionEffectForceVisible(triggerId: string, targetFieldId: string, forceVisible: boolean | undefined): void;
1799
1970
  connect(kind: WireKind, fromId: string, toId: string): void;
1800
1971
  disconnect(kind: WireKind, fromId: string, toId: string): void;
1801
1972
  setConstraint(tagId: string, flag: string, value: boolean | undefined): void;
@@ -59,7 +59,7 @@ type NodeRef$1 = {
59
59
  };
60
60
  type NodeMap = Map<string, NodeRef$1>;
61
61
 
62
- type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern" | "multiple_order_kinds_selected";
62
+ type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "bad_option_effect_key" | "bad_option_effect_target" | "bad_option_effect_option" | "option_include_exclude_conflict" | "visibility_dependency_cycle" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern" | "multiple_order_kinds_selected";
63
63
  type ValidationError = {
64
64
  code: ValidationCode;
65
65
  message: string;
@@ -186,6 +186,75 @@ interface BaseFieldUI {
186
186
  /** Host-defined prop names → runtime default values (untyped base) */
187
187
  defaults?: Record<string, unknown>;
188
188
  }
189
+ type Ui = (UiString | UiNumber | UiBoolean | UiAnyOf | UiArray | UiObject) & {
190
+ description: string;
191
+ label: string;
192
+ };
193
+ /** string */
194
+ interface UiString {
195
+ type: "string";
196
+ enum?: string[];
197
+ minLength?: number;
198
+ maxLength?: number;
199
+ pattern?: string;
200
+ format?: string;
201
+ }
202
+ /** number */
203
+ interface UiNumber {
204
+ type: "number";
205
+ minimum?: number;
206
+ maximum?: number;
207
+ multipleOf?: number;
208
+ }
209
+ /** boolean */
210
+ interface UiBoolean {
211
+ type: "boolean";
212
+ }
213
+ /** enumerated choices */
214
+ interface UiAnyOf {
215
+ type: "anyOf";
216
+ multiple?: boolean;
217
+ items: Array<{
218
+ type: "string" | "number" | "boolean";
219
+ title?: string;
220
+ description?: string;
221
+ value: string | number | boolean;
222
+ }>;
223
+ }
224
+ /** arrays: homogeneous (item) or tuple (items) */
225
+ interface UiArray {
226
+ type: "array";
227
+ label: string;
228
+ description: string;
229
+ item?: Ui;
230
+ items?: Ui[];
231
+ editable?: boolean;
232
+ /**
233
+ * Optional: allowed shapes for new items.
234
+ * Key = label shown in UI picker
235
+ * Value = schema for the new element
236
+ */
237
+ shape?: Record<string, Ui>;
238
+ minItems?: number;
239
+ maxItems?: number;
240
+ uniqueItems?: boolean;
241
+ }
242
+ /** objects: nested props */
243
+ interface UiObject {
244
+ type: "object";
245
+ label: string;
246
+ description: string;
247
+ editable?: boolean;
248
+ fields: Record<string, Ui>;
249
+ /**
250
+ * Optional: allowed shapes for dynamically added keys.
251
+ * Key = human-readable name shown in UI picker
252
+ * Value = schema applied to the value of the new key
253
+ */
254
+ shape?: Record<string, Ui>;
255
+ required?: string[];
256
+ order?: string[];
257
+ }
189
258
  type FieldValidationValueBy = "value" | "length" | "eval";
190
259
  type FieldValidationOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "between" | "in" | "nin" | "truthy" | "falsy" | "match";
191
260
  type FieldValidationRule = {
@@ -207,6 +276,22 @@ type FieldOption = {
207
276
  service_id?: ServiceIdRef;
208
277
  pricing_role?: PricingRole;
209
278
  meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
279
+ children?: FieldOption[];
280
+ };
281
+ type OptionEffectForButton = {
282
+ /**
283
+ * If true, selecting this button/option may force the target field visible.
284
+ * If false/missing, the option filter only applies when the target field is already visible.
285
+ */
286
+ forceVisible?: boolean;
287
+ /**
288
+ * If present, only these option ids remain visible.
289
+ */
290
+ include?: string[];
291
+ /**
292
+ * Removed after include is applied.
293
+ */
294
+ exclude?: string[];
210
295
  };
211
296
  type Field = BaseFieldUI & {
212
297
  id: string;
@@ -260,6 +345,7 @@ type ServiceProps = {
260
345
  fields: Field[];
261
346
  includes_for_buttons?: Record<string, string[]>;
262
347
  excludes_for_buttons?: Record<string, string[]>;
348
+ option_effects_for_buttons?: Record<string, Record<string, OptionEffectForButton>>;
263
349
  schema_version?: string;
264
350
  fallbacks?: ServiceFallback;
265
351
  name?: string;
@@ -355,6 +441,12 @@ type CommentThread = {
355
441
  _sync?: "pending" | "synced" | "error";
356
442
  };
357
443
 
444
+ type ResolvedVisibility = {
445
+ fieldIds: string[];
446
+ optionsByFieldId: Record<string, string[]>;
447
+ forcedFieldIds: string[];
448
+ };
449
+
358
450
  /** Options you can set on the builder (used for validation/visibility) */
359
451
  type BuilderOptions = Omit<ValidatorOptions, "serviceMap"> & {
360
452
  serviceMap?: DgpServiceMap;
@@ -380,6 +472,8 @@ interface Builder {
380
472
  * NOTE: keys are “button ids”: either option.id or field.id for option-less buttons.
381
473
  */
382
474
  visibleFields(tagId: string, selectedOptionKeys?: string[]): string[];
475
+ /** Compute field ids plus option visibility under a tag. */
476
+ resolveVisibility(tagId: string, selectedOptionKeys?: string[]): ResolvedVisibility;
383
477
  /** Update builder options (validator context etc.) */
384
478
  setOptions(patch: Partial<BuilderOptions>): void;
385
479
  /** Access the current props (already normalised) */
@@ -501,6 +595,8 @@ type VisibleGroup = {
501
595
  tag?: Tag;
502
596
  fields: Field[];
503
597
  fieldIds: string[];
598
+ optionsByFieldId?: Record<string, string[]>;
599
+ forcedFieldIds?: string[];
504
600
  parentTags?: Tag[];
505
601
  childrenTags?: Tag[];
506
602
  /** In order of selection: tag base (unless overridden) then selected options */
@@ -550,11 +646,10 @@ declare class Selection {
550
646
  * What counts as a "button selection" (trigger key):
551
647
  * - field key where the field has button === true (e.g. "f:dripfeed")
552
648
  * - option key (e.g. "o:fast")
553
- * - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
554
649
  *
555
650
  * Grouping:
556
651
  * - button-field trigger groups under its own fieldId
557
- * - option/composite groups under the option's owning fieldId (from nodeMap)
652
+ * - option trigger groups under the option's owning fieldId (from nodeMap)
558
653
  *
559
654
  * Deterministic:
560
655
  * - preserves selection insertion order
@@ -565,7 +660,6 @@ declare class Selection {
565
660
  * Returns only selection keys that are valid "trigger buttons":
566
661
  * - field keys where field.button === true
567
662
  * - option keys
568
- * - composite keys "fieldId::optionId" (validated by optionId)
569
663
  * Excludes tags and non-button fields.
570
664
  */
571
665
  selectedButtons(): string[];
@@ -575,6 +669,7 @@ declare class Selection {
575
669
  private computeGroupForTag;
576
670
  private addServiceByRole;
577
671
  private findOptionById;
672
+ private isSelectedOptionVisible;
578
673
  }
579
674
 
580
675
  type CatalogId = string;
@@ -1692,6 +1787,66 @@ type QuantityRule = {
1692
1787
  fallback?: number;
1693
1788
  };
1694
1789
 
1790
+ /** Matches your InputWrapper’s expectations */
1791
+ type InputKind = string;
1792
+ type InputVariant = "default" | (string & {});
1793
+ type AdapterCtx = {
1794
+ field: Field;
1795
+ props: ServiceProps;
1796
+ };
1797
+ type Adapter = {
1798
+ valueProp?: string;
1799
+ changeProp?: string;
1800
+ errorProp?: string;
1801
+ /** normalize what the host emitted into what we store in form-palette */
1802
+ getValue?: (next: unknown, current: unknown, ctx: AdapterCtx) => unknown;
1803
+ /** REQUIRED if field.options exists */
1804
+ getSelectedOptions?: (next: unknown, current: unknown, ctx: AdapterCtx) => string[];
1805
+ /** For option-less action buttons (button: true with no options) */
1806
+ isActive?: (stored: unknown, ctx: AdapterCtx) => boolean;
1807
+ getInputPropsFromField?: (props: AdapterCtx) => any;
1808
+ toValue?: (value: any) => any;
1809
+ };
1810
+ type InputChildOptionCapability = {
1811
+ supported?: boolean;
1812
+ autoCreate?: boolean;
1813
+ defaultLabel?: string;
1814
+ defaultValue?: string | number;
1815
+ };
1816
+ type InputOptionCapability = {
1817
+ supported?: boolean;
1818
+ autoCreate?: boolean;
1819
+ defaultLabel?: string;
1820
+ defaultValue?: string | number;
1821
+ children?: InputChildOptionCapability;
1822
+ };
1823
+ type InputMultiCapability = {
1824
+ supported?: boolean;
1825
+ autoEnable?: boolean;
1826
+ };
1827
+ type InputDescriptor = {
1828
+ Component: React__default.ComponentType<Record<string, unknown>>;
1829
+ adapter?: Adapter;
1830
+ defaultProps?: Record<string, unknown>;
1831
+ ui?: Record<string, Ui>;
1832
+ options?: InputOptionCapability;
1833
+ multi?: InputMultiCapability;
1834
+ };
1835
+ type VariantMap = Map<InputVariant, InputDescriptor>;
1836
+ type RegistryStore = Map<InputKind, VariantMap>;
1837
+ type Registry = {
1838
+ get(kind: InputKind, variant?: InputVariant): InputDescriptor | undefined;
1839
+ register(kind: InputKind, descriptor: InputDescriptor, variant?: InputVariant): void;
1840
+ unregister(kind: InputKind, variant?: InputVariant): void;
1841
+ registerMany(entries: Array<{
1842
+ kind: InputKind;
1843
+ descriptor: InputDescriptor;
1844
+ variant?: InputVariant;
1845
+ }>): void;
1846
+ /** low-level escape hatch */
1847
+ _store: RegistryStore;
1848
+ };
1849
+
1695
1850
  declare class Editor {
1696
1851
  private readonly builder;
1697
1852
  private readonly api;
@@ -1763,7 +1918,14 @@ declare class Editor {
1763
1918
  id?: string;
1764
1919
  label: string;
1765
1920
  type: Field["type"];
1766
- }): void;
1921
+ }): string;
1922
+ addFieldFromDescriptor(registry: Registry, partial: Omit<Field, "id" | "label" | "type"> & {
1923
+ id?: string;
1924
+ label: string;
1925
+ type: Field["type"];
1926
+ }, opts?: {
1927
+ variant?: InputVariant;
1928
+ }): string;
1767
1929
  updateField(id: string, patch: Partial<Field>): void;
1768
1930
  removeField(id: string): void;
1769
1931
  remove(id: string): void;
@@ -1782,6 +1944,7 @@ declare class Editor {
1782
1944
  setPricingRoleMany(ids: readonly string[], role: "base" | "utility"): void;
1783
1945
  clearFieldDefaultsMany(ids: readonly string[]): void;
1784
1946
  clearFieldValidationMany(ids: readonly string[]): void;
1947
+ setFieldMulti(fieldId: string, enabled: boolean): void;
1785
1948
  autoCreateOptionsMany(ids: readonly string[], makeOption?: (fieldId: string) => {
1786
1949
  id?: string;
1787
1950
  label: string;
@@ -1796,6 +1959,14 @@ declare class Editor {
1796
1959
  clearFieldQuantityRule(id: string): void;
1797
1960
  include(receiverId: string, idOrIds: string | string[]): void;
1798
1961
  exclude(receiverId: string, idOrIds: string | string[]): void;
1962
+ setOptionEffect(triggerId: string, targetFieldId: string, effect: OptionEffectForButton | undefined | null): void;
1963
+ patchOptionEffect(triggerId: string, targetFieldId: string, patch: OptionEffectForButton): void;
1964
+ clearOptionEffect(triggerId: string, targetFieldId: string): void;
1965
+ clearOptionEffectsForTrigger(triggerId: string): void;
1966
+ clearOptionEffectsForTarget(targetFieldId: string): void;
1967
+ addOptionEffectOptions(triggerId: string, targetFieldId: string, kind: "include" | "exclude", optionIds: readonly string[]): void;
1968
+ removeOptionEffectOptions(triggerId: string, targetFieldId: string, kind: "include" | "exclude", optionIds: readonly string[]): void;
1969
+ setOptionEffectForceVisible(triggerId: string, targetFieldId: string, forceVisible: boolean | undefined): void;
1799
1970
  connect(kind: WireKind, fromId: string, toId: string): void;
1800
1971
  disconnect(kind: WireKind, fromId: string, toId: string): void;
1801
1972
  setConstraint(tagId: string, flag: string, value: boolean | undefined): void;