@defra/forms-model 3.0.685 → 3.0.687

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/module/components/types.js.map +1 -1
  2. package/dist/module/conditions/migration.js +74 -19
  3. package/dist/module/conditions/migration.js.map +1 -1
  4. package/dist/module/conditions/types.js.map +1 -1
  5. package/dist/module/form/form-definition/helpers.js +14 -0
  6. package/dist/module/form/form-definition/helpers.js.map +1 -1
  7. package/dist/module/form/form-definition/index.js +14 -3
  8. package/dist/module/form/form-definition/index.js.map +1 -1
  9. package/dist/module/form/form-editor/index.js +2 -0
  10. package/dist/module/form/form-editor/index.js.map +1 -1
  11. package/dist/module/form/form-editor/types.js.map +1 -1
  12. package/dist/types/components/types.d.ts +7 -0
  13. package/dist/types/components/types.d.ts.map +1 -1
  14. package/dist/types/conditions/migration.d.ts.map +1 -1
  15. package/dist/types/conditions/types.d.ts +13 -1
  16. package/dist/types/conditions/types.d.ts.map +1 -1
  17. package/dist/types/form/form-definition/helpers.d.ts +8 -0
  18. package/dist/types/form/form-definition/helpers.d.ts.map +1 -1
  19. package/dist/types/form/form-definition/index.d.ts.map +1 -1
  20. package/dist/types/form/form-editor/index.d.ts +2 -0
  21. package/dist/types/form/form-editor/index.d.ts.map +1 -1
  22. package/dist/types/form/form-editor/types.d.ts +5 -1
  23. package/dist/types/form/form-editor/types.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/schemas/component-schema-v2.json +13 -0
  26. package/schemas/component-schema.json +13 -0
  27. package/schemas/form-definition-schema.json +39 -0
  28. package/schemas/form-definition-v2-schema.json +65 -0
  29. package/schemas/list-schema-v2.json +26 -0
  30. package/schemas/list-schema.json +26 -0
  31. package/schemas/page-schema-v2.json +39 -0
  32. package/schemas/page-schema.json +13 -0
  33. package/src/components/types.ts +8 -0
  34. package/src/conditions/migration.ts +111 -25
  35. package/src/conditions/types.ts +13 -1
  36. package/src/form/form-definition/helpers.ts +17 -0
  37. package/src/form/form-definition/index.ts +40 -6
  38. package/src/form/form-editor/index.ts +6 -0
  39. package/src/form/form-editor/types.ts +6 -0
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../src/components/types.ts"],"sourcesContent":["import { type LanguageMessages } from 'joi'\n\nimport {\n type ComponentType,\n type GeospatialFieldGeometryTypesEnum,\n type PreviewTypeEnum\n} from '~/src/components/enums.js'\nimport {\n type ListTypeContent,\n type ListTypeOption\n} from '~/src/form/form-definition/types.js'\n\nexport type ConditionalComponentType = Exclude<\n ConditionalComponentsDef['type'],\n ContentComponentsDef\n>\n\n/**\n * Types for Components JSON structure which are expected by engine and turned into actual form input/content/lists\n */\n\ninterface FormFieldBase {\n id?: string\n type: FormComponentsDef['type']\n shortDescription?: string\n errorDescription?: string\n name: string\n title: string\n hint?: string\n options: {\n required?: boolean\n optionalText?: boolean\n classes?: string\n customValidationMessages?: LanguageMessages\n instructionText?: string\n }\n}\n\ninterface ListFieldBase extends FormFieldBase {\n type:\n | ComponentType.AutocompleteField\n | ComponentType.CheckboxesField\n | ComponentType.RadiosField\n | ComponentType.SelectField\n list: string\n options: FormFieldBase['options'] & {\n type?: ListTypeContent\n }\n}\n\ninterface ContentFieldBase {\n id?: string\n type:\n | ComponentType.Details\n | ComponentType.Html\n | ComponentType.Markdown\n | ComponentType.InsetText\n | ComponentType.List\n | ComponentType.NotificationBanner\n name: string\n title: string\n options?: {\n required?: undefined\n optionalText?: undefined\n }\n}\n\ninterface DateFieldBase extends FormFieldBase {\n type: ComponentType.DatePartsField\n name: string\n title: string\n hint?: string\n options: FormFieldBase['options'] & {\n maxDaysInPast?: number\n maxDaysInFuture?: number\n earliestDate?: string\n latestDate?: string\n }\n}\n\n// Text Fields\nexport interface TextFieldComponent extends FormFieldBase {\n type: ComponentType.TextField\n options: FormFieldBase['options'] & {\n autocomplete?: string\n condition?: string\n customValidationMessage?: string\n }\n schema: {\n max?: number\n min?: number\n length?: number\n regex?: string\n }\n}\n\nexport interface EmailAddressFieldComponent extends FormFieldBase {\n type: ComponentType.EmailAddressField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n }\n}\n\nexport interface NumberFieldComponent extends FormFieldBase {\n type: ComponentType.NumberField\n options: FormFieldBase['options'] & {\n prefix?: string\n suffix?: string\n autocomplete?: string\n condition?: string\n customValidationMessage?: string\n }\n schema: {\n max?: number\n min?: number\n precision?: number\n minPrecision?: number\n minLength?: number\n maxLength?: number\n }\n}\n\nexport type TelephoneNumberFieldOptionsFormat = 'international' | 'uk'\n\nexport interface TelephoneNumberFieldComponent extends FormFieldBase {\n type: ComponentType.TelephoneNumberField\n options: FormFieldBase['options'] & {\n condition?: string\n format?: TelephoneNumberFieldOptionsFormat\n customValidationMessage?: string\n }\n}\n\nexport interface FileUploadFieldComponent extends FormFieldBase {\n type: ComponentType.FileUploadField\n name: string\n title: string\n hint?: string\n options: FormFieldBase['options'] & {\n accept?: string\n }\n schema: {\n max?: number\n min?: number\n length?: number\n }\n}\n\nexport interface YesNoFieldComponent extends FormFieldBase {\n type: ComponentType.YesNoField\n options: FormFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface DeclarationFieldComponent extends FormFieldBase {\n type: ComponentType.DeclarationField\n content: string\n options: FormFieldBase['options'] & {\n condition?: string\n declarationConfirmationLabel?: string\n }\n}\n\nexport interface MultilineTextFieldComponent extends FormFieldBase {\n type: ComponentType.MultilineTextField\n options: FormFieldBase['options'] & {\n autocomplete?: string\n condition?: string\n customValidationMessage?: string\n rows?: number\n maxWords?: number\n }\n schema: {\n max?: number\n min?: number\n length?: number\n regex?: string\n }\n}\n\nexport interface UkAddressFieldComponent extends FormFieldBase {\n type: ComponentType.UkAddressField\n options: FormFieldBase['options'] & {\n hideTitle?: boolean\n usePostcodeLookup?: boolean\n }\n}\n\n// Precise Location Fields\nexport interface EastingNorthingFieldComponent extends FormFieldBase {\n type: ComponentType.EastingNorthingField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n }\n schema?: {\n easting?: {\n min?: number\n max?: number\n }\n northing?: {\n min?: number\n max?: number\n }\n }\n}\n\nexport interface OsGridRefFieldComponent extends FormFieldBase {\n type: ComponentType.OsGridRefField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n }\n}\n\nexport interface NationalGridFieldNumberFieldComponent extends FormFieldBase {\n type: ComponentType.NationalGridFieldNumberField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n }\n}\n\nexport interface LatLongFieldComponent extends FormFieldBase {\n type: ComponentType.LatLongField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n }\n schema?: {\n latitude?: {\n min?: number\n max?: number\n }\n longitude?: {\n min?: number\n max?: number\n }\n }\n}\n\nexport interface HiddenFieldComponent extends FormFieldBase {\n type: ComponentType.HiddenField\n options: FormFieldBase['options'] & {\n condition?: string\n }\n}\n\n// Date Fields\nexport interface DatePartsFieldComponent extends DateFieldBase {\n type: ComponentType.DatePartsField\n options: DateFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface MonthYearFieldComponent extends FormFieldBase {\n type: ComponentType.MonthYearField\n options: FormFieldBase['options'] & {\n customValidationMessage?: string\n earliestMonthYear?: string\n latestMonthYear?: string\n }\n}\n\nexport interface PaymentFieldComponent extends FormFieldBase {\n type: ComponentType.PaymentField\n options: FormFieldBase['options'] & {\n amount: number\n description: string\n conditionalAmounts?: {\n condition: string\n amount: number\n }[]\n emailField?: string\n }\n}\n\nexport type GeospatialFieldOptionsCountry =\n | 'england'\n | 'wales'\n | 'northern-ireland'\n | 'scotland'\n\nexport interface GeospatialFieldComponent extends FormFieldBase {\n type: ComponentType.GeospatialField\n options: FormFieldBase['options'] & {\n condition?: string\n countries?: GeospatialFieldOptionsCountry[]\n geometryTypes?: GeospatialFieldGeometryTypesEnum[]\n }\n schema?: {\n max?: number\n min?: number\n length?: number\n }\n}\n\n// Content Fields\nexport interface DetailsComponent extends ContentFieldBase {\n type: ComponentType.Details\n content: string\n options: ContentFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface HtmlComponent extends ContentFieldBase {\n type: ComponentType.Html\n content: string\n options: ContentFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface MarkdownComponent extends ContentFieldBase {\n type: ComponentType.Markdown\n content: string\n options: ContentFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface InsetTextComponent extends ContentFieldBase {\n type: ComponentType.InsetText\n content: string\n}\n\nexport interface ListComponent extends ContentFieldBase {\n type: ComponentType.List\n hint?: string\n list: string\n options: ContentFieldBase['options'] & {\n type?: ListTypeOption\n classes?: string\n hideTitle?: boolean\n bold?: boolean\n }\n}\n\nexport interface NotificationBannerComponent extends ContentFieldBase {\n type: ComponentType.NotificationBanner\n content: string\n options: ContentFieldBase['options'] & {\n type?: 'success'\n heading?: string\n condition?: string\n }\n}\n\nexport interface AutocompleteFieldComponent extends ListFieldBase {\n type: ComponentType.AutocompleteField\n options: ListFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface CheckboxesFieldComponent extends ListFieldBase {\n type: ComponentType.CheckboxesField\n options: ListFieldBase['options'] & {\n bold?: boolean\n condition?: string\n }\n schema?: {\n max?: number\n min?: number\n length?: number\n }\n}\n\nexport interface RadiosFieldComponent extends ListFieldBase {\n type: ComponentType.RadiosField\n options: ListFieldBase['options'] & {\n bold?: boolean\n condition?: string\n }\n}\n\nexport interface SelectFieldComponent extends ListFieldBase {\n type: ComponentType.SelectField\n options: ListFieldBase['options'] & {\n autocomplete?: string\n condition?: string\n }\n}\n\nexport type ComponentDef = FormComponentsDef | ContentComponentsDef\n\n// Components that render form fields\nexport type FormComponentsDef =\n | InputFieldsComponentsDef\n | SelectionComponentsDef\n\n// Components that render inputs\nexport type InputFieldsComponentsDef =\n | TextFieldComponent\n | EmailAddressFieldComponent\n | NumberFieldComponent\n | MultilineTextFieldComponent\n | TelephoneNumberFieldComponent\n | MonthYearFieldComponent\n | DatePartsFieldComponent\n | UkAddressFieldComponent\n | FileUploadFieldComponent\n | DeclarationFieldComponent\n | EastingNorthingFieldComponent\n | OsGridRefFieldComponent\n | NationalGridFieldNumberFieldComponent\n | LatLongFieldComponent\n | HiddenFieldComponent\n | PaymentFieldComponent\n | GeospatialFieldComponent\n\n// Components that render content\nexport type ContentComponentsDef =\n | DetailsComponent\n | HtmlComponent\n | MarkdownComponent\n | InsetTextComponent\n | ListComponent\n | NotificationBannerComponent\n\n// Components that render lists\nexport type ListComponentsDef =\n | Exclude<SelectionComponentsDef, YesNoFieldComponent>\n | ListComponent\n\n// Components that have selection fields\nexport type SelectionComponentsDef =\n | AutocompleteFieldComponent\n | CheckboxesFieldComponent\n | RadiosFieldComponent\n | SelectFieldComponent\n | YesNoFieldComponent\n\n// Components that have condition support\nexport type ConditionalComponentsDef = Exclude<\n ComponentDef,\n | InsetTextComponent\n | ListComponent\n | MonthYearFieldComponent\n | UkAddressFieldComponent\n | FileUploadFieldComponent\n | PaymentFieldComponent\n>\n\nexport type PreviewType = keyof typeof PreviewTypeEnum\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/components/types.ts"],"sourcesContent":["import { type LanguageMessages } from 'joi'\n\nimport {\n type ComponentType,\n type GeospatialFieldGeometryTypesEnum,\n type PreviewTypeEnum\n} from '~/src/components/enums.js'\nimport {\n type ListTypeContent,\n type ListTypeOption\n} from '~/src/form/form-definition/types.js'\n\nexport type ConditionalComponentType = Exclude<\n ConditionalComponentsDef['type'],\n ContentComponentsDef\n>\n\n/**\n * Types for Components JSON structure which are expected by engine and turned into actual form input/content/lists\n */\n\ninterface FormFieldBase {\n id?: string\n type: FormComponentsDef['type']\n shortDescription?: string\n errorDescription?: string\n name: string\n title: string\n hint?: string\n options: {\n required?: boolean\n optionalText?: boolean\n classes?: string\n customValidationMessages?: LanguageMessages\n instructionText?: string\n }\n}\n\ninterface ListFieldBase extends FormFieldBase {\n type:\n | ComponentType.AutocompleteField\n | ComponentType.CheckboxesField\n | ComponentType.RadiosField\n | ComponentType.SelectField\n list: string\n options: FormFieldBase['options'] & {\n type?: ListTypeContent\n }\n}\n\ninterface ContentFieldBase {\n id?: string\n type:\n | ComponentType.Details\n | ComponentType.Html\n | ComponentType.Markdown\n | ComponentType.InsetText\n | ComponentType.List\n | ComponentType.NotificationBanner\n name: string\n title: string\n options?: {\n required?: undefined\n optionalText?: undefined\n }\n}\n\ninterface DateFieldBase extends FormFieldBase {\n type: ComponentType.DatePartsField\n name: string\n title: string\n hint?: string\n options: FormFieldBase['options'] & {\n maxDaysInPast?: number\n maxDaysInFuture?: number\n earliestDate?: string\n latestDate?: string\n }\n}\n\n// Text Fields\nexport interface TextFieldComponent extends FormFieldBase {\n type: ComponentType.TextField\n options: FormFieldBase['options'] & {\n autocomplete?: string\n condition?: string\n customValidationMessage?: string\n }\n schema: {\n max?: number\n min?: number\n length?: number\n regex?: string\n }\n}\n\nexport interface EmailAddressFieldComponent extends FormFieldBase {\n type: ComponentType.EmailAddressField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n }\n}\n\nexport interface NumberFieldComponent extends FormFieldBase {\n type: ComponentType.NumberField\n options: FormFieldBase['options'] & {\n prefix?: string\n suffix?: string\n autocomplete?: string\n condition?: string\n customValidationMessage?: string\n }\n schema: {\n max?: number\n min?: number\n precision?: number\n minPrecision?: number\n minLength?: number\n maxLength?: number\n }\n}\n\nexport type TelephoneNumberFieldOptionsFormat = 'international' | 'uk'\n\nexport interface TelephoneNumberFieldComponent extends FormFieldBase {\n type: ComponentType.TelephoneNumberField\n options: FormFieldBase['options'] & {\n condition?: string\n format?: TelephoneNumberFieldOptionsFormat\n customValidationMessage?: string\n }\n}\n\nexport interface FileUploadFieldComponent extends FormFieldBase {\n type: ComponentType.FileUploadField\n name: string\n title: string\n hint?: string\n options: FormFieldBase['options'] & {\n accept?: string\n }\n schema: {\n max?: number\n min?: number\n length?: number\n }\n}\n\nexport interface YesNoFieldComponent extends FormFieldBase {\n type: ComponentType.YesNoField\n options: FormFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface DeclarationFieldComponent extends FormFieldBase {\n type: ComponentType.DeclarationField\n content: string\n options: FormFieldBase['options'] & {\n condition?: string\n declarationConfirmationLabel?: string\n }\n}\n\nexport interface MultilineTextFieldComponent extends FormFieldBase {\n type: ComponentType.MultilineTextField\n options: FormFieldBase['options'] & {\n autocomplete?: string\n condition?: string\n customValidationMessage?: string\n rows?: number\n maxWords?: number\n }\n schema: {\n max?: number\n min?: number\n length?: number\n regex?: string\n }\n}\n\nexport interface UkAddressFieldComponent extends FormFieldBase {\n type: ComponentType.UkAddressField\n options: FormFieldBase['options'] & {\n hideTitle?: boolean\n usePostcodeLookup?: boolean\n }\n}\n\nexport interface MapLayerOptions {\n sssi?: boolean\n}\n\n// Precise Location Fields\nexport interface EastingNorthingFieldComponent extends FormFieldBase {\n type: ComponentType.EastingNorthingField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n mapLayers?: MapLayerOptions\n }\n schema?: {\n easting?: {\n min?: number\n max?: number\n }\n northing?: {\n min?: number\n max?: number\n }\n }\n}\n\nexport interface OsGridRefFieldComponent extends FormFieldBase {\n type: ComponentType.OsGridRefField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n mapLayers?: MapLayerOptions\n }\n}\n\nexport interface NationalGridFieldNumberFieldComponent extends FormFieldBase {\n type: ComponentType.NationalGridFieldNumberField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n }\n}\n\nexport interface LatLongFieldComponent extends FormFieldBase {\n type: ComponentType.LatLongField\n options: FormFieldBase['options'] & {\n condition?: string\n customValidationMessage?: string\n mapLayers?: MapLayerOptions\n }\n schema?: {\n latitude?: {\n min?: number\n max?: number\n }\n longitude?: {\n min?: number\n max?: number\n }\n }\n}\n\nexport interface HiddenFieldComponent extends FormFieldBase {\n type: ComponentType.HiddenField\n options: FormFieldBase['options'] & {\n condition?: string\n }\n}\n\n// Date Fields\nexport interface DatePartsFieldComponent extends DateFieldBase {\n type: ComponentType.DatePartsField\n options: DateFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface MonthYearFieldComponent extends FormFieldBase {\n type: ComponentType.MonthYearField\n options: FormFieldBase['options'] & {\n customValidationMessage?: string\n earliestMonthYear?: string\n latestMonthYear?: string\n }\n}\n\nexport interface PaymentFieldComponent extends FormFieldBase {\n type: ComponentType.PaymentField\n options: FormFieldBase['options'] & {\n amount: number\n description: string\n conditionalAmounts?: {\n condition: string\n amount: number\n }[]\n emailField?: string\n }\n}\n\nexport type GeospatialFieldOptionsCountry =\n | 'england'\n | 'wales'\n | 'northern-ireland'\n | 'scotland'\n\nexport interface GeospatialFieldComponent extends FormFieldBase {\n type: ComponentType.GeospatialField\n options: FormFieldBase['options'] & {\n condition?: string\n countries?: GeospatialFieldOptionsCountry[]\n geometryTypes?: GeospatialFieldGeometryTypesEnum[]\n mapLayers?: MapLayerOptions\n }\n schema?: {\n max?: number\n min?: number\n length?: number\n }\n}\n\n// Content Fields\nexport interface DetailsComponent extends ContentFieldBase {\n type: ComponentType.Details\n content: string\n options: ContentFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface HtmlComponent extends ContentFieldBase {\n type: ComponentType.Html\n content: string\n options: ContentFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface MarkdownComponent extends ContentFieldBase {\n type: ComponentType.Markdown\n content: string\n options: ContentFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface InsetTextComponent extends ContentFieldBase {\n type: ComponentType.InsetText\n content: string\n}\n\nexport interface ListComponent extends ContentFieldBase {\n type: ComponentType.List\n hint?: string\n list: string\n options: ContentFieldBase['options'] & {\n type?: ListTypeOption\n classes?: string\n hideTitle?: boolean\n bold?: boolean\n }\n}\n\nexport interface NotificationBannerComponent extends ContentFieldBase {\n type: ComponentType.NotificationBanner\n content: string\n options: ContentFieldBase['options'] & {\n type?: 'success'\n heading?: string\n condition?: string\n }\n}\n\nexport interface AutocompleteFieldComponent extends ListFieldBase {\n type: ComponentType.AutocompleteField\n options: ListFieldBase['options'] & {\n condition?: string\n }\n}\n\nexport interface CheckboxesFieldComponent extends ListFieldBase {\n type: ComponentType.CheckboxesField\n options: ListFieldBase['options'] & {\n bold?: boolean\n condition?: string\n }\n schema?: {\n max?: number\n min?: number\n length?: number\n }\n}\n\nexport interface RadiosFieldComponent extends ListFieldBase {\n type: ComponentType.RadiosField\n options: ListFieldBase['options'] & {\n bold?: boolean\n condition?: string\n }\n}\n\nexport interface SelectFieldComponent extends ListFieldBase {\n type: ComponentType.SelectField\n options: ListFieldBase['options'] & {\n autocomplete?: string\n condition?: string\n }\n}\n\nexport type ComponentDef = FormComponentsDef | ContentComponentsDef\n\n// Components that render form fields\nexport type FormComponentsDef =\n | InputFieldsComponentsDef\n | SelectionComponentsDef\n\n// Components that render inputs\nexport type InputFieldsComponentsDef =\n | TextFieldComponent\n | EmailAddressFieldComponent\n | NumberFieldComponent\n | MultilineTextFieldComponent\n | TelephoneNumberFieldComponent\n | MonthYearFieldComponent\n | DatePartsFieldComponent\n | UkAddressFieldComponent\n | FileUploadFieldComponent\n | DeclarationFieldComponent\n | EastingNorthingFieldComponent\n | OsGridRefFieldComponent\n | NationalGridFieldNumberFieldComponent\n | LatLongFieldComponent\n | HiddenFieldComponent\n | PaymentFieldComponent\n | GeospatialFieldComponent\n\n// Components that render content\nexport type ContentComponentsDef =\n | DetailsComponent\n | HtmlComponent\n | MarkdownComponent\n | InsetTextComponent\n | ListComponent\n | NotificationBannerComponent\n\n// Components that render lists\nexport type ListComponentsDef =\n | Exclude<SelectionComponentsDef, YesNoFieldComponent>\n | ListComponent\n\n// Components that have selection fields\nexport type SelectionComponentsDef =\n | AutocompleteFieldComponent\n | CheckboxesFieldComponent\n | RadiosFieldComponent\n | SelectFieldComponent\n | YesNoFieldComponent\n\n// Components that have condition support\nexport type ConditionalComponentsDef = Exclude<\n ComponentDef,\n | InsetTextComponent\n | ListComponent\n | MonthYearFieldComponent\n | UkAddressFieldComponent\n | FileUploadFieldComponent\n | PaymentFieldComponent\n>\n\nexport type PreviewType = keyof typeof PreviewTypeEnum\n"],"mappings":"","ignoreList":[]}
@@ -1,5 +1,7 @@
1
1
  import { ComponentType } from "../components/enums.js";
2
- import { ConditionType } from "./enums.js";
2
+ import { isConditionalType } from "../components/helpers.js";
3
+ import { ConditionType, Coordinator, OperatorName } from "./enums.js";
4
+ import { getConditionListItemIds } from "../form/form-definition/helpers.js";
3
5
  /**
4
6
  * Generate a valid JavaScript identifier from a condition ID
5
7
  * @param conditionId - The condition ID (UUID)
@@ -29,21 +31,69 @@ export function isConditionRelativeDateValueDataV2(condition) {
29
31
  function getListItem(model, listId, itemId) {
30
32
  const foundList = model.getListById(listId);
31
33
  if (!foundList) {
32
- throw Error(`List ${listId} not found`);
34
+ throw new Error(`List ${listId} not found`);
33
35
  }
34
36
  const item = foundList.items.find(item => item.id === itemId);
35
37
  if (!item) {
36
- throw Error(`List item ${itemId} not found`);
38
+ throw new Error(`List item ${itemId} not found`);
37
39
  }
38
40
  return item;
39
41
  }
40
- function createConditionValueDataFromListItemRefV2(condition, model) {
42
+ function createConditionValueDataListFromListItemRefV2(condition, model) {
41
43
  const value = condition.value;
42
- const refValue = getListItem(model, value.listId, value.itemId);
44
+ const itemIds = getConditionListItemIds(value);
45
+ return itemIds.map(itemId => {
46
+ const refValue = getListItem(model, value.listId, itemId);
47
+ return {
48
+ display: refValue.text,
49
+ type: ConditionType.Value,
50
+ value: refValue.value.toString()
51
+ };
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Determine how multiple selected list items are combined within a single
57
+ * V2 condition once expanded into individual V1 conditions.
58
+ * - Checkbox questions use the author-chosen coordinator (default OR).
59
+ * - Single-answer questions (radio/autocomplete/select) combine with OR for a
60
+ * positive match and AND for a negative ("is not any of these") match.
61
+ */
62
+ function getListItemsInnerCoordinator(componentType, operator, itemsCoordinator) {
63
+ if (componentType === ComponentType.CheckboxesField) {
64
+ return itemsCoordinator ?? Coordinator.OR;
65
+ }
66
+ return operator === OperatorName.IsNot ? Coordinator.AND : Coordinator.OR;
67
+ }
68
+
69
+ /**
70
+ * Convert a V2 list item ref condition to V1. A single selected item produces
71
+ * a single condition (unchanged from legacy behaviour); multiple selected
72
+ * items produce a nested condition group so they are correctly parenthesised
73
+ * relative to sibling conditions.
74
+ */
75
+ function convertListItemRefConditionV2(model, condition, component, field, coordinator) {
76
+ const value = condition.value;
77
+ const values = createConditionValueDataListFromListItemRefV2(condition, model);
78
+ if (!values.length) {
79
+ throw new Error('List item ref condition has no selected items');
80
+ }
81
+ if (values.length === 1) {
82
+ return {
83
+ field,
84
+ operator: condition.operator,
85
+ value: values[0],
86
+ coordinator
87
+ };
88
+ }
89
+ const innerCoordinator = getListItemsInnerCoordinator(component.type, condition.operator, value.itemsCoordinator);
43
90
  return {
44
- display: refValue.text,
45
- type: ConditionType.Value,
46
- value: refValue.value.toString()
91
+ conditions: values.map((itemValue, index) => ({
92
+ field,
93
+ operator: condition.operator,
94
+ value: itemValue,
95
+ coordinator: index === 0 ? coordinator : innerCoordinator
96
+ }))
47
97
  };
48
98
  }
49
99
  function createConditionValueDataFromStringOrDateValueDataV2(condition) {
@@ -95,12 +145,21 @@ function isConditionDataV2(condition) {
95
145
  function convertConditionDataV2(model, condition, coordinator) {
96
146
  const component = model.getComponentById(condition.componentId);
97
147
  if (!component) {
98
- throw Error('Component not found');
148
+ throw new Error('Component not found');
99
149
  }
100
- let newValue;
150
+ if (!isConditionalType(component.type)) {
151
+ throw new Error(`Component ${component.name} does not support conditions`);
152
+ }
153
+ const field = {
154
+ name: component.name,
155
+ type: component.type,
156
+ display: component.title
157
+ };
101
158
  if (isConditionListItemRefValueDataV2(condition)) {
102
- newValue = createConditionValueDataFromListItemRefV2(condition, model);
103
- } else if (isConditionStringValueDataV2(condition)) {
159
+ return convertListItemRefConditionV2(model, condition, component, field, coordinator);
160
+ }
161
+ let newValue;
162
+ if (isConditionStringValueDataV2(condition)) {
104
163
  newValue = createConditionValueDataFromStringValueDataV2(condition);
105
164
  } else if (isConditionBooleanValueDataV2(condition)) {
106
165
  newValue = component.type === ComponentType.DeclarationField ? createConditionValueDataFromDeclarationValueDataV2(condition) : createConditionValueDataFromBooleanValueDataV2(condition);
@@ -111,14 +170,10 @@ function convertConditionDataV2(model, condition, coordinator) {
111
170
  } else if (isConditionRelativeDateValueDataV2(condition)) {
112
171
  newValue = createConditionValueDataFromRelativeDateValueDataV2(condition);
113
172
  } else {
114
- throw Error('Unsupported condition type');
173
+ throw new Error('Unsupported condition type');
115
174
  }
116
175
  return {
117
- field: {
118
- name: component.name,
119
- type: component.type /** @todo fix this */,
120
- display: component.title
121
- },
176
+ field,
122
177
  operator: condition.operator,
123
178
  value: newValue,
124
179
  coordinator
@@ -127,7 +182,7 @@ function convertConditionDataV2(model, condition, coordinator) {
127
182
  function convertConditionRefDataFromV2(model, condition, coordinator) {
128
183
  const refCondition = model.getConditionById(condition.conditionId);
129
184
  if (!refCondition) {
130
- throw Error('Component not found');
185
+ throw new Error('Component not found');
131
186
  }
132
187
  return {
133
188
  conditionName: generateConditionAlias(refCondition.id),
@@ -1 +1 @@
1
- {"version":3,"file":"migration.js","names":["ComponentType","ConditionType","generateConditionAlias","conditionId","replaceAll","isConditionListItemRefValueDataV2","condition","type","ListItemRef","isConditionStringValueDataV2","StringValue","isConditionBooleanValueDataV2","BooleanValue","isConditionNumberValueDataV2","NumberValue","isConditionDateValueDataV2","DateValue","isConditionRelativeDateValueDataV2","RelativeDate","getListItem","model","listId","itemId","foundList","getListById","Error","item","items","find","id","createConditionValueDataFromListItemRefV2","value","refValue","display","text","Value","toString","createConditionValueDataFromStringOrDateValueDataV2","createConditionValueDataFromStringValueDataV2","createConditionValueDataFromDateValueDataV2","createConditionValueDataFromRelativeDateValueDataV2","period","unit","direction","createConditionValueDataFromNumberValueDataV2","createConditionValueDataFromBooleanValueDataV2","createConditionValueDataFromDeclarationValueDataV2","isConditionDataV2","convertConditionDataV2","coordinator","component","getComponentById","componentId","newValue","DeclarationField","field","name","title","operator","convertConditionRefDataFromV2","refCondition","getConditionById","conditionName","conditionDisplayName","displayName","isConditionWrapperV2","wrapper","Array","isArray","isConditionWrapper","convertConditionWrapperFromV2","conditionWrapper","length","newConditionWrapper","conditions","map","index","newCondition","undefined"],"sources":["../../../src/conditions/migration.ts"],"sourcesContent":["import { ComponentType } from '~/src/components/enums.js'\nimport {\n type ComponentDef,\n type ConditionalComponentType\n} from '~/src/components/types.js'\nimport { ConditionType, type Coordinator } from '~/src/conditions/enums.js'\nimport {\n type ConditionData,\n type ConditionDataV2,\n type ConditionListItemRefValueDataV2,\n type ConditionRefData,\n type ConditionRefDataV2,\n type ConditionValueData,\n type RelativeDateValueData,\n type RelativeDateValueDataV2\n} from '~/src/conditions/types.js'\nimport {\n type ConditionWrapper,\n type ConditionWrapperV2,\n type List\n} from '~/src/form/form-definition/types.js'\n\n/**\n * Generate a valid JavaScript identifier from a condition ID\n * @param conditionId - The condition ID (UUID)\n * @returns A valid JavaScript identifier\n */\nexport const generateConditionAlias = (conditionId: string): string => {\n return `cond_${conditionId.replaceAll('-', '')}`\n}\n\nexport function isConditionListItemRefValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.ListItemRef\n}\n\nexport function isConditionStringValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.StringValue\n}\n\nexport function isConditionBooleanValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.BooleanValue\n}\n\nexport function isConditionNumberValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.NumberValue\n}\n\nexport function isConditionDateValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.DateValue\n}\n\nexport function isConditionRelativeDateValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.RelativeDate\n}\n\nfunction getListItem(model: RuntimeFormModel, listId: string, itemId: string) {\n const foundList = model.getListById(listId)\n\n if (!foundList) {\n throw Error(`List ${listId} not found`)\n }\n\n const item = foundList.items.find((item) => item.id === itemId)\n\n if (!item) {\n throw Error(`List item ${itemId} not found`)\n }\n\n return item\n}\n\nfunction createConditionValueDataFromListItemRefV2(\n condition: ConditionDataV2,\n model: RuntimeFormModel\n): ConditionValueData {\n const value = condition.value as ConditionListItemRefValueDataV2\n const refValue = getListItem(model, value.listId, value.itemId)\n\n return {\n display: refValue.text,\n type: ConditionType.Value,\n value: refValue.value.toString()\n }\n}\n\nfunction createConditionValueDataFromStringOrDateValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: condition.value as string,\n display: condition.value as string\n }\n}\n\nfunction createConditionValueDataFromStringValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return createConditionValueDataFromStringOrDateValueDataV2(condition)\n}\n\nfunction createConditionValueDataFromDateValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return createConditionValueDataFromStringOrDateValueDataV2(condition)\n}\n\nfunction createConditionValueDataFromRelativeDateValueDataV2(\n condition: ConditionDataV2\n): RelativeDateValueData {\n const value = condition.value as RelativeDateValueDataV2\n return {\n type: ConditionType.RelativeDate,\n period: value.period.toString(),\n unit: value.unit,\n direction: value.direction\n }\n}\n\nfunction createConditionValueDataFromNumberValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: (condition.value as number).toString(),\n display: (condition.value as number).toString()\n }\n}\n\nfunction createConditionValueDataFromBooleanValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: (condition.value as boolean).toString(),\n display: (condition.value as boolean) ? 'Yes' : 'No'\n }\n}\n\nfunction createConditionValueDataFromDeclarationValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: (condition.value as boolean).toString(),\n display: (condition.value as boolean) ? 'Agreed' : 'Not agreed'\n }\n}\n\nfunction isConditionDataV2(\n condition: ConditionDataV2 | ConditionRefDataV2\n): condition is ConditionDataV2 {\n return 'componentId' in condition\n}\n\nfunction convertConditionDataV2(\n model: RuntimeFormModel,\n condition: ConditionDataV2,\n coordinator: Coordinator | undefined\n): ConditionData {\n const component = model.getComponentById(condition.componentId)\n\n if (!component) {\n throw Error('Component not found')\n }\n\n let newValue\n if (isConditionListItemRefValueDataV2(condition)) {\n newValue = createConditionValueDataFromListItemRefV2(condition, model)\n } else if (isConditionStringValueDataV2(condition)) {\n newValue = createConditionValueDataFromStringValueDataV2(condition)\n } else if (isConditionBooleanValueDataV2(condition)) {\n newValue =\n component.type === ComponentType.DeclarationField\n ? createConditionValueDataFromDeclarationValueDataV2(condition)\n : createConditionValueDataFromBooleanValueDataV2(condition)\n } else if (isConditionNumberValueDataV2(condition)) {\n newValue = createConditionValueDataFromNumberValueDataV2(condition)\n } else if (isConditionDateValueDataV2(condition)) {\n newValue = createConditionValueDataFromDateValueDataV2(condition)\n } else if (isConditionRelativeDateValueDataV2(condition)) {\n newValue = createConditionValueDataFromRelativeDateValueDataV2(condition)\n } else {\n throw Error('Unsupported condition type')\n }\n\n return {\n field: {\n name: component.name,\n type: component.type as ConditionalComponentType /** @todo fix this */,\n display: component.title\n },\n operator: condition.operator,\n value: newValue,\n coordinator\n }\n}\n\nfunction convertConditionRefDataFromV2(\n model: RuntimeFormModel,\n condition: ConditionRefDataV2,\n coordinator: Coordinator | undefined\n): ConditionRefData {\n const refCondition = model.getConditionById(condition.conditionId)\n\n if (!refCondition) {\n throw Error('Component not found')\n }\n\n return {\n conditionName: generateConditionAlias(refCondition.id),\n conditionDisplayName: refCondition.displayName,\n coordinator\n }\n}\n\nexport function isConditionWrapperV2(\n wrapper: ConditionWrapper | ConditionWrapperV2\n): wrapper is ConditionWrapperV2 {\n return Array.isArray((wrapper as ConditionWrapperV2).items)\n}\n\nexport function isConditionWrapper(\n wrapper: ConditionWrapper | ConditionWrapperV2\n): wrapper is ConditionWrapper {\n return !isConditionWrapperV2(wrapper)\n}\n\nexport function convertConditionWrapperFromV2(\n conditionWrapper: ConditionWrapperV2,\n model: RuntimeFormModel\n): ConditionWrapper {\n let coordinator\n\n if (conditionWrapper.items.length > 1 && !conditionWrapper.coordinator) {\n throw new Error('Coordinator is required for multiple conditions')\n } else {\n coordinator = conditionWrapper.coordinator\n }\n\n const newConditionWrapper: ConditionWrapper = {\n name: conditionWrapper.id,\n displayName: conditionWrapper.displayName,\n value: {\n name: conditionWrapper.id,\n conditions: conditionWrapper.items.map((condition, index) => {\n let newCondition: ConditionData | ConditionRefData\n\n if (isConditionDataV2(condition)) {\n newCondition = convertConditionDataV2(\n model,\n condition,\n index > 0 ? coordinator : undefined\n )\n } else {\n newCondition = convertConditionRefDataFromV2(\n model,\n condition,\n index > 0 ? coordinator : undefined\n )\n }\n\n return newCondition\n })\n }\n }\n\n return newConditionWrapper\n}\n\nexport interface RuntimeFormModel {\n getListById: (listId: string) => List | undefined\n getComponentById: (componentId: string) => ComponentDef | undefined\n getConditionById: (conditionId: string) => ConditionWrapperV2 | undefined\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"migration.js","names":["ComponentType","isConditionalType","ConditionType","Coordinator","OperatorName","getConditionListItemIds","generateConditionAlias","conditionId","replaceAll","isConditionListItemRefValueDataV2","condition","type","ListItemRef","isConditionStringValueDataV2","StringValue","isConditionBooleanValueDataV2","BooleanValue","isConditionNumberValueDataV2","NumberValue","isConditionDateValueDataV2","DateValue","isConditionRelativeDateValueDataV2","RelativeDate","getListItem","model","listId","itemId","foundList","getListById","Error","item","items","find","id","createConditionValueDataListFromListItemRefV2","value","itemIds","map","refValue","display","text","Value","toString","getListItemsInnerCoordinator","componentType","operator","itemsCoordinator","CheckboxesField","OR","IsNot","AND","convertListItemRefConditionV2","component","field","coordinator","values","length","innerCoordinator","conditions","itemValue","index","createConditionValueDataFromStringOrDateValueDataV2","createConditionValueDataFromStringValueDataV2","createConditionValueDataFromDateValueDataV2","createConditionValueDataFromRelativeDateValueDataV2","period","unit","direction","createConditionValueDataFromNumberValueDataV2","createConditionValueDataFromBooleanValueDataV2","createConditionValueDataFromDeclarationValueDataV2","isConditionDataV2","convertConditionDataV2","getComponentById","componentId","name","title","newValue","DeclarationField","convertConditionRefDataFromV2","refCondition","getConditionById","conditionName","conditionDisplayName","displayName","isConditionWrapperV2","wrapper","Array","isArray","isConditionWrapper","convertConditionWrapperFromV2","conditionWrapper","newConditionWrapper","newCondition","undefined"],"sources":["../../../src/conditions/migration.ts"],"sourcesContent":["import { ComponentType } from '~/src/components/enums.js'\nimport { isConditionalType } from '~/src/components/helpers.js'\nimport { type ComponentDef } from '~/src/components/types.js'\nimport {\n ConditionType,\n Coordinator,\n OperatorName\n} from '~/src/conditions/enums.js'\nimport {\n type ConditionData,\n type ConditionDataV2,\n type ConditionGroupData,\n type ConditionListItemRefValueDataV2,\n type ConditionRefData,\n type ConditionRefDataV2,\n type ConditionValueData,\n type RelativeDateValueData,\n type RelativeDateValueDataV2\n} from '~/src/conditions/types.js'\nimport { getConditionListItemIds } from '~/src/form/form-definition/helpers.js'\nimport {\n type ConditionWrapper,\n type ConditionWrapperV2,\n type List\n} from '~/src/form/form-definition/types.js'\n\n/**\n * Generate a valid JavaScript identifier from a condition ID\n * @param conditionId - The condition ID (UUID)\n * @returns A valid JavaScript identifier\n */\nexport const generateConditionAlias = (conditionId: string): string => {\n return `cond_${conditionId.replaceAll('-', '')}`\n}\n\nexport function isConditionListItemRefValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.ListItemRef\n}\n\nexport function isConditionStringValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.StringValue\n}\n\nexport function isConditionBooleanValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.BooleanValue\n}\n\nexport function isConditionNumberValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.NumberValue\n}\n\nexport function isConditionDateValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.DateValue\n}\n\nexport function isConditionRelativeDateValueDataV2(condition: ConditionDataV2) {\n return condition.type === ConditionType.RelativeDate\n}\n\nfunction getListItem(model: RuntimeFormModel, listId: string, itemId: string) {\n const foundList = model.getListById(listId)\n\n if (!foundList) {\n throw new Error(`List ${listId} not found`)\n }\n\n const item = foundList.items.find((item) => item.id === itemId)\n\n if (!item) {\n throw new Error(`List item ${itemId} not found`)\n }\n\n return item\n}\n\nfunction createConditionValueDataListFromListItemRefV2(\n condition: ConditionDataV2,\n model: RuntimeFormModel\n): ConditionValueData[] {\n const value = condition.value as ConditionListItemRefValueDataV2\n const itemIds = getConditionListItemIds(value)\n\n return itemIds.map((itemId) => {\n const refValue = getListItem(model, value.listId, itemId)\n\n return {\n display: refValue.text,\n type: ConditionType.Value,\n value: refValue.value.toString()\n }\n })\n}\n\n/**\n * Determine how multiple selected list items are combined within a single\n * V2 condition once expanded into individual V1 conditions.\n * - Checkbox questions use the author-chosen coordinator (default OR).\n * - Single-answer questions (radio/autocomplete/select) combine with OR for a\n * positive match and AND for a negative (\"is not any of these\") match.\n */\nfunction getListItemsInnerCoordinator(\n componentType: ComponentDef['type'],\n operator: OperatorName,\n itemsCoordinator: Coordinator | undefined\n): Coordinator {\n if (componentType === ComponentType.CheckboxesField) {\n return itemsCoordinator ?? Coordinator.OR\n }\n\n return operator === OperatorName.IsNot ? Coordinator.AND : Coordinator.OR\n}\n\n/**\n * Convert a V2 list item ref condition to V1. A single selected item produces\n * a single condition (unchanged from legacy behaviour); multiple selected\n * items produce a nested condition group so they are correctly parenthesised\n * relative to sibling conditions.\n */\nfunction convertListItemRefConditionV2(\n model: RuntimeFormModel,\n condition: ConditionDataV2,\n component: ComponentDef,\n field: ConditionData['field'],\n coordinator: Coordinator | undefined\n): ConditionData | ConditionGroupData {\n const value = condition.value as ConditionListItemRefValueDataV2\n const values = createConditionValueDataListFromListItemRefV2(condition, model)\n\n if (!values.length) {\n throw new Error('List item ref condition has no selected items')\n }\n\n if (values.length === 1) {\n return {\n field,\n operator: condition.operator,\n value: values[0],\n coordinator\n }\n }\n\n const innerCoordinator = getListItemsInnerCoordinator(\n component.type,\n condition.operator,\n value.itemsCoordinator\n )\n\n return {\n conditions: values.map((itemValue, index) => ({\n field,\n operator: condition.operator,\n value: itemValue,\n coordinator: index === 0 ? coordinator : innerCoordinator\n }))\n }\n}\n\nfunction createConditionValueDataFromStringOrDateValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: condition.value as string,\n display: condition.value as string\n }\n}\n\nfunction createConditionValueDataFromStringValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return createConditionValueDataFromStringOrDateValueDataV2(condition)\n}\n\nfunction createConditionValueDataFromDateValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return createConditionValueDataFromStringOrDateValueDataV2(condition)\n}\n\nfunction createConditionValueDataFromRelativeDateValueDataV2(\n condition: ConditionDataV2\n): RelativeDateValueData {\n const value = condition.value as RelativeDateValueDataV2\n return {\n type: ConditionType.RelativeDate,\n period: value.period.toString(),\n unit: value.unit,\n direction: value.direction\n }\n}\n\nfunction createConditionValueDataFromNumberValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: (condition.value as number).toString(),\n display: (condition.value as number).toString()\n }\n}\n\nfunction createConditionValueDataFromBooleanValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: (condition.value as boolean).toString(),\n display: (condition.value as boolean) ? 'Yes' : 'No'\n }\n}\n\nfunction createConditionValueDataFromDeclarationValueDataV2(\n condition: ConditionDataV2\n): ConditionValueData {\n return {\n type: ConditionType.Value,\n value: (condition.value as boolean).toString(),\n display: (condition.value as boolean) ? 'Agreed' : 'Not agreed'\n }\n}\n\nfunction isConditionDataV2(\n condition: ConditionDataV2 | ConditionRefDataV2\n): condition is ConditionDataV2 {\n return 'componentId' in condition\n}\n\nfunction convertConditionDataV2(\n model: RuntimeFormModel,\n condition: ConditionDataV2,\n coordinator: Coordinator | undefined\n): ConditionData | ConditionGroupData {\n const component = model.getComponentById(condition.componentId)\n\n if (!component) {\n throw new Error('Component not found')\n }\n\n if (!isConditionalType(component.type)) {\n throw new Error(`Component ${component.name} does not support conditions`)\n }\n\n const field = {\n name: component.name,\n type: component.type,\n display: component.title\n }\n\n if (isConditionListItemRefValueDataV2(condition)) {\n return convertListItemRefConditionV2(\n model,\n condition,\n component,\n field,\n coordinator\n )\n }\n\n let newValue\n if (isConditionStringValueDataV2(condition)) {\n newValue = createConditionValueDataFromStringValueDataV2(condition)\n } else if (isConditionBooleanValueDataV2(condition)) {\n newValue =\n component.type === ComponentType.DeclarationField\n ? createConditionValueDataFromDeclarationValueDataV2(condition)\n : createConditionValueDataFromBooleanValueDataV2(condition)\n } else if (isConditionNumberValueDataV2(condition)) {\n newValue = createConditionValueDataFromNumberValueDataV2(condition)\n } else if (isConditionDateValueDataV2(condition)) {\n newValue = createConditionValueDataFromDateValueDataV2(condition)\n } else if (isConditionRelativeDateValueDataV2(condition)) {\n newValue = createConditionValueDataFromRelativeDateValueDataV2(condition)\n } else {\n throw new Error('Unsupported condition type')\n }\n\n return {\n field,\n operator: condition.operator,\n value: newValue,\n coordinator\n }\n}\n\nfunction convertConditionRefDataFromV2(\n model: RuntimeFormModel,\n condition: ConditionRefDataV2,\n coordinator: Coordinator | undefined\n): ConditionRefData {\n const refCondition = model.getConditionById(condition.conditionId)\n\n if (!refCondition) {\n throw new Error('Component not found')\n }\n\n return {\n conditionName: generateConditionAlias(refCondition.id),\n conditionDisplayName: refCondition.displayName,\n coordinator\n }\n}\n\nexport function isConditionWrapperV2(\n wrapper: ConditionWrapper | ConditionWrapperV2\n): wrapper is ConditionWrapperV2 {\n return Array.isArray((wrapper as ConditionWrapperV2).items)\n}\n\nexport function isConditionWrapper(\n wrapper: ConditionWrapper | ConditionWrapperV2\n): wrapper is ConditionWrapper {\n return !isConditionWrapperV2(wrapper)\n}\n\nexport function convertConditionWrapperFromV2(\n conditionWrapper: ConditionWrapperV2,\n model: RuntimeFormModel\n): ConditionWrapper {\n let coordinator\n\n if (conditionWrapper.items.length > 1 && !conditionWrapper.coordinator) {\n throw new Error('Coordinator is required for multiple conditions')\n } else {\n coordinator = conditionWrapper.coordinator\n }\n\n const newConditionWrapper: ConditionWrapper = {\n name: conditionWrapper.id,\n displayName: conditionWrapper.displayName,\n value: {\n name: conditionWrapper.id,\n conditions: conditionWrapper.items.map((condition, index) => {\n let newCondition: ConditionData | ConditionRefData | ConditionGroupData\n\n if (isConditionDataV2(condition)) {\n newCondition = convertConditionDataV2(\n model,\n condition,\n index > 0 ? coordinator : undefined\n )\n } else {\n newCondition = convertConditionRefDataFromV2(\n model,\n condition,\n index > 0 ? coordinator : undefined\n )\n }\n\n return newCondition\n })\n }\n }\n\n return newConditionWrapper\n}\n\nexport interface RuntimeFormModel {\n getListById: (listId: string) => List | undefined\n getComponentById: (componentId: string) => ComponentDef | undefined\n getConditionById: (conditionId: string) => ConditionWrapperV2 | undefined\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../src/conditions/types.ts"],"sourcesContent":["import {\n type ComponentDef,\n type ConditionalComponentType\n} from '~/src/components/types.js'\nimport { type Condition } from '~/src/conditions/condition.js'\nimport {\n type ConditionType,\n type Coordinator,\n type DateDirections,\n type DateUnits,\n type OperatorName\n} from '~/src/conditions/enums.js'\n\nexport interface ConditionValueData {\n type: ConditionType.Value\n value: string\n display: string\n}\n\nexport interface RelativeDateValueData {\n type: ConditionType.RelativeDate\n period: string\n unit: DateUnits\n direction: DateDirections\n}\n\nexport interface ConditionListItemRefValueDataV2 {\n listId: string\n itemId: string\n}\n\nexport interface RelativeDateValueDataV2 {\n period: number\n unit: DateUnits\n direction: DateDirections\n}\n\nexport interface ConditionFieldData {\n name: string\n type: ConditionalComponentType\n display: string\n}\n\nexport interface ConditionData {\n field: ConditionFieldData\n operator: OperatorName\n value: ConditionValueData | RelativeDateValueData\n coordinator?: Coordinator\n}\n\nexport type ConditionValueDataV2 =\n | ConditionListItemRefValueDataV2\n | RelativeDateValueDataV2\n | string\n | boolean\n | number\n\nexport interface ConditionDataV2 {\n id: string\n componentId: string\n operator: OperatorName\n type: ConditionType\n value: ConditionValueDataV2\n}\n\nexport interface ConditionRefData {\n conditionName: string\n conditionDisplayName: string\n coordinator?: Coordinator\n}\n\nexport interface ConditionRefDataV2 {\n id: string\n conditionId: string\n}\n\nexport interface ConditionGroupData {\n conditions: (ConditionData | ConditionRefData | ConditionGroupData)[]\n}\n\nexport type ConditionGroupDataV2 = (ConditionDataV2 | ConditionRefDataV2)[]\n\nexport interface ConditionsModelData extends ConditionGroupData {\n name: string\n}\n\nexport interface OperatorDefinition {\n expression: (\n component: Pick<ComponentDef, 'type' | 'name'>,\n conditionValue: Condition['value']\n ) => string\n}\n\nexport type Conditionals = Record<OperatorName, OperatorDefinition>\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/conditions/types.ts"],"sourcesContent":["import {\n type ComponentDef,\n type ConditionalComponentType\n} from '~/src/components/types.js'\nimport { type Condition } from '~/src/conditions/condition.js'\nimport {\n type ConditionType,\n type Coordinator,\n type DateDirections,\n type DateUnits,\n type OperatorName\n} from '~/src/conditions/enums.js'\n\nexport interface ConditionValueData {\n type: ConditionType.Value\n value: string\n display: string\n}\n\nexport interface RelativeDateValueData {\n type: ConditionType.RelativeDate\n period: string\n unit: DateUnits\n direction: DateDirections\n}\n\nexport interface ConditionListItemRefValueDataV2 {\n listId: string\n /**\n * One or more referenced list item ids (radio, checkbox, autocomplete,\n * select). New conditions are always written as an array, even for a single\n * selection. A bare `string` is only retained for backwards compatibility so\n * conditions saved before multi-select support continue to load, display and\n * evaluate.\n */\n itemId: string[] | string\n /**\n * How multiple checkbox selections are combined (AND/OR). Only set for\n * checkbox questions; radio/autocomplete/select combine implicitly.\n */\n itemsCoordinator?: Coordinator\n}\n\nexport interface RelativeDateValueDataV2 {\n period: number\n unit: DateUnits\n direction: DateDirections\n}\n\nexport interface ConditionFieldData {\n name: string\n type: ConditionalComponentType\n display: string\n}\n\nexport interface ConditionData {\n field: ConditionFieldData\n operator: OperatorName\n value: ConditionValueData | RelativeDateValueData\n coordinator?: Coordinator\n}\n\nexport type ConditionValueDataV2 =\n | ConditionListItemRefValueDataV2\n | RelativeDateValueDataV2\n | string\n | boolean\n | number\n\nexport interface ConditionDataV2 {\n id: string\n componentId: string\n operator: OperatorName\n type: ConditionType\n value: ConditionValueDataV2\n}\n\nexport interface ConditionRefData {\n conditionName: string\n conditionDisplayName: string\n coordinator?: Coordinator\n}\n\nexport interface ConditionRefDataV2 {\n id: string\n conditionId: string\n}\n\nexport interface ConditionGroupData {\n conditions: (ConditionData | ConditionRefData | ConditionGroupData)[]\n}\n\nexport type ConditionGroupDataV2 = (ConditionDataV2 | ConditionRefDataV2)[]\n\nexport interface ConditionsModelData extends ConditionGroupData {\n name: string\n}\n\nexport interface OperatorDefinition {\n expression: (\n component: Pick<ComponentDef, 'type' | 'name'>,\n conditionValue: Condition['value']\n ) => string\n}\n\nexport type Conditionals = Record<OperatorName, OperatorDefinition>\n"],"mappings":"","ignoreList":[]}
@@ -25,6 +25,20 @@ export function isConditionListItemRefValueData(conditionValueData) {
25
25
  return typeof conditionValueData === 'object' && 'listId' in conditionValueData && 'itemId' in conditionValueData;
26
26
  }
27
27
 
28
+ /**
29
+ * Normalises a list item ref condition value to an array of item ids. `itemId`
30
+ * is normally an array, but may be a bare string for legacy conditions saved
31
+ * before multi-select support.
32
+ * @param { ConditionListItemRefValueDataV2 | undefined } value
33
+ * @returns { string[] }
34
+ */
35
+ export function getConditionListItemIds(value) {
36
+ if (!value?.itemId) {
37
+ return [];
38
+ }
39
+ return Array.isArray(value.itemId) ? value.itemId : [value.itemId];
40
+ }
41
+
28
42
  /**
29
43
  * Returns an array of all hidden fields in a form
30
44
  * @param definition - form definition
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","names":["ComponentType","hasComponents","isFormDefinition","definition","isConditionListItemRefValueData","conditionValueData","getHiddenFields","pages","length","totalHiddenFields","page","hiddenFields","components","filter","comp","type","HiddenField","push","isFeedbackForm","feedback","some","p","controller"],"sources":["../../../../src/form/form-definition/helpers.ts"],"sourcesContent":["import { ComponentType } from '~/src/components/enums.js'\nimport { type ComponentDef } from '~/src/components/types.js'\nimport { type ConditionListItemRefValueDataV2 } from '~/src/conditions/types.js'\nimport { type FormDefinition } from '~/src/form/form-definition/types.js'\nimport { type ControllerType } from '~/src/pages/enums.js'\nimport { hasComponents } from '~/src/pages/helpers.js'\n\n/**\n * TypeGuard to check if something is a FormDefinition\n * @param { unknown } definition\n * @returns { definition is FormDefinition }\n */\nexport function isFormDefinition(\n definition: unknown\n): definition is FormDefinition {\n if (!definition) {\n return false\n }\n\n return (\n typeof definition === 'object' &&\n 'name' in definition &&\n 'pages' in definition &&\n 'conditions' in definition\n )\n}\n\n/**\n * TypeGuard to check if something is a ConditionListItemRefValueDataV2\n * @param { unknown } conditionValueData\n * @returns { conditionValueData is ConditionListItemRefValueDataV2 }\n */\nexport function isConditionListItemRefValueData(\n conditionValueData: unknown\n): conditionValueData is ConditionListItemRefValueDataV2 {\n if (!conditionValueData) {\n return false\n }\n\n return (\n typeof conditionValueData === 'object' &&\n 'listId' in conditionValueData &&\n 'itemId' in conditionValueData\n )\n}\n\n/**\n * Returns an array of all hidden fields in a form\n * @param definition - form definition\n */\nexport function getHiddenFields(definition: FormDefinition) {\n if (definition.pages.length === 0) {\n return []\n }\n const totalHiddenFields = [] as ComponentDef[]\n for (const page of definition.pages) {\n const hiddenFields = hasComponents(page)\n ? page.components.filter(\n (comp) => comp.type === ComponentType.HiddenField\n )\n : []\n totalHiddenFields.push(...hiddenFields)\n }\n return totalHiddenFields\n}\n\n/**\n * @param definition - form definition\n * @returns {boolean}\n */\nexport function isFeedbackForm(definition: FormDefinition | undefined) {\n const feedback = 'FeedbackPageController' as ControllerType\n return definition?.pages\n ? definition.pages.some((p) => p.controller === feedback)\n : false\n}\n"],"mappings":"AAAA,SAASA,aAAa;AAKtB,SAASC,aAAa;;AAEtB;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAC9BC,UAAmB,EACW;EAC9B,IAAI,CAACA,UAAU,EAAE;IACf,OAAO,KAAK;EACd;EAEA,OACE,OAAOA,UAAU,KAAK,QAAQ,IAC9B,MAAM,IAAIA,UAAU,IACpB,OAAO,IAAIA,UAAU,IACrB,YAAY,IAAIA,UAAU;AAE9B;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,+BAA+BA,CAC7CC,kBAA2B,EAC4B;EACvD,IAAI,CAACA,kBAAkB,EAAE;IACvB,OAAO,KAAK;EACd;EAEA,OACE,OAAOA,kBAAkB,KAAK,QAAQ,IACtC,QAAQ,IAAIA,kBAAkB,IAC9B,QAAQ,IAAIA,kBAAkB;AAElC;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAACH,UAA0B,EAAE;EAC1D,IAAIA,UAAU,CAACI,KAAK,CAACC,MAAM,KAAK,CAAC,EAAE;IACjC,OAAO,EAAE;EACX;EACA,MAAMC,iBAAiB,GAAG,EAAoB;EAC9C,KAAK,MAAMC,IAAI,IAAIP,UAAU,CAACI,KAAK,EAAE;IACnC,MAAMI,YAAY,GAAGV,aAAa,CAACS,IAAI,CAAC,GACpCA,IAAI,CAACE,UAAU,CAACC,MAAM,CACnBC,IAAI,IAAKA,IAAI,CAACC,IAAI,KAAKf,aAAa,CAACgB,WACxC,CAAC,GACD,EAAE;IACNP,iBAAiB,CAACQ,IAAI,CAAC,GAAGN,YAAY,CAAC;EACzC;EACA,OAAOF,iBAAiB;AAC1B;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASS,cAAcA,CAACf,UAAsC,EAAE;EACrE,MAAMgB,QAAQ,GAAG,wBAA0C;EAC3D,OAAOhB,UAAU,EAAEI,KAAK,GACpBJ,UAAU,CAACI,KAAK,CAACa,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,UAAU,KAAKH,QAAQ,CAAC,GACvD,KAAK;AACX","ignoreList":[]}
1
+ {"version":3,"file":"helpers.js","names":["ComponentType","hasComponents","isFormDefinition","definition","isConditionListItemRefValueData","conditionValueData","getConditionListItemIds","value","itemId","Array","isArray","getHiddenFields","pages","length","totalHiddenFields","page","hiddenFields","components","filter","comp","type","HiddenField","push","isFeedbackForm","feedback","some","p","controller"],"sources":["../../../../src/form/form-definition/helpers.ts"],"sourcesContent":["import { ComponentType } from '~/src/components/enums.js'\nimport { type ComponentDef } from '~/src/components/types.js'\nimport { type ConditionListItemRefValueDataV2 } from '~/src/conditions/types.js'\nimport { type FormDefinition } from '~/src/form/form-definition/types.js'\nimport { type ControllerType } from '~/src/pages/enums.js'\nimport { hasComponents } from '~/src/pages/helpers.js'\n\n/**\n * TypeGuard to check if something is a FormDefinition\n * @param { unknown } definition\n * @returns { definition is FormDefinition }\n */\nexport function isFormDefinition(\n definition: unknown\n): definition is FormDefinition {\n if (!definition) {\n return false\n }\n\n return (\n typeof definition === 'object' &&\n 'name' in definition &&\n 'pages' in definition &&\n 'conditions' in definition\n )\n}\n\n/**\n * TypeGuard to check if something is a ConditionListItemRefValueDataV2\n * @param { unknown } conditionValueData\n * @returns { conditionValueData is ConditionListItemRefValueDataV2 }\n */\nexport function isConditionListItemRefValueData(\n conditionValueData: unknown\n): conditionValueData is ConditionListItemRefValueDataV2 {\n if (!conditionValueData) {\n return false\n }\n\n return (\n typeof conditionValueData === 'object' &&\n 'listId' in conditionValueData &&\n 'itemId' in conditionValueData\n )\n}\n\n/**\n * Normalises a list item ref condition value to an array of item ids. `itemId`\n * is normally an array, but may be a bare string for legacy conditions saved\n * before multi-select support.\n * @param { ConditionListItemRefValueDataV2 | undefined } value\n * @returns { string[] }\n */\nexport function getConditionListItemIds(\n value: ConditionListItemRefValueDataV2 | undefined\n): string[] {\n if (!value?.itemId) {\n return []\n }\n\n return Array.isArray(value.itemId) ? value.itemId : [value.itemId]\n}\n\n/**\n * Returns an array of all hidden fields in a form\n * @param definition - form definition\n */\nexport function getHiddenFields(definition: FormDefinition) {\n if (definition.pages.length === 0) {\n return []\n }\n const totalHiddenFields = [] as ComponentDef[]\n for (const page of definition.pages) {\n const hiddenFields = hasComponents(page)\n ? page.components.filter(\n (comp) => comp.type === ComponentType.HiddenField\n )\n : []\n totalHiddenFields.push(...hiddenFields)\n }\n return totalHiddenFields\n}\n\n/**\n * @param definition - form definition\n * @returns {boolean}\n */\nexport function isFeedbackForm(definition: FormDefinition | undefined) {\n const feedback = 'FeedbackPageController' as ControllerType\n return definition?.pages\n ? definition.pages.some((p) => p.controller === feedback)\n : false\n}\n"],"mappings":"AAAA,SAASA,aAAa;AAKtB,SAASC,aAAa;;AAEtB;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAC9BC,UAAmB,EACW;EAC9B,IAAI,CAACA,UAAU,EAAE;IACf,OAAO,KAAK;EACd;EAEA,OACE,OAAOA,UAAU,KAAK,QAAQ,IAC9B,MAAM,IAAIA,UAAU,IACpB,OAAO,IAAIA,UAAU,IACrB,YAAY,IAAIA,UAAU;AAE9B;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,+BAA+BA,CAC7CC,kBAA2B,EAC4B;EACvD,IAAI,CAACA,kBAAkB,EAAE;IACvB,OAAO,KAAK;EACd;EAEA,OACE,OAAOA,kBAAkB,KAAK,QAAQ,IACtC,QAAQ,IAAIA,kBAAkB,IAC9B,QAAQ,IAAIA,kBAAkB;AAElC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CACrCC,KAAkD,EACxC;EACV,IAAI,CAACA,KAAK,EAAEC,MAAM,EAAE;IAClB,OAAO,EAAE;EACX;EAEA,OAAOC,KAAK,CAACC,OAAO,CAACH,KAAK,CAACC,MAAM,CAAC,GAAGD,KAAK,CAACC,MAAM,GAAG,CAACD,KAAK,CAACC,MAAM,CAAC;AACpE;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASG,eAAeA,CAACR,UAA0B,EAAE;EAC1D,IAAIA,UAAU,CAACS,KAAK,CAACC,MAAM,KAAK,CAAC,EAAE;IACjC,OAAO,EAAE;EACX;EACA,MAAMC,iBAAiB,GAAG,EAAoB;EAC9C,KAAK,MAAMC,IAAI,IAAIZ,UAAU,CAACS,KAAK,EAAE;IACnC,MAAMI,YAAY,GAAGf,aAAa,CAACc,IAAI,CAAC,GACpCA,IAAI,CAACE,UAAU,CAACC,MAAM,CACnBC,IAAI,IAAKA,IAAI,CAACC,IAAI,KAAKpB,aAAa,CAACqB,WACxC,CAAC,GACD,EAAE;IACNP,iBAAiB,CAACQ,IAAI,CAAC,GAAGN,YAAY,CAAC;EACzC;EACA,OAAOF,iBAAiB;AAC1B;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASS,cAAcA,CAACpB,UAAsC,EAAE;EACrE,MAAMqB,QAAQ,GAAG,wBAA0C;EAC3D,OAAOrB,UAAU,EAAES,KAAK,GACpBT,UAAU,CAACS,KAAK,CAACa,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,UAAU,KAAKH,QAAQ,CAAC,GACvD,KAAK;AACX","ignoreList":[]}
@@ -4,7 +4,7 @@ import { v4 as uuidV4 } from 'uuid';
4
4
  import { rtrimOnly } from "../../common/rtrim-only.js";
5
5
  import { ComponentType, GeospatialFieldGeometryTypesEnum, GeospatialFieldOptionsCountryEnum, TelephoneNumberFieldOptionsFormatEnum } from "../../components/enums.js";
6
6
  import { isConditionalType } from "../../components/helpers.js";
7
- import { ConditionType, OperatorName } from "../../conditions/enums.js";
7
+ import { ConditionType, Coordinator, OperatorName } from "../../conditions/enums.js";
8
8
  import { MAX_NUMBER_OF_REPEAT_ITEMS, MIN_NUMBER_OF_REPEAT_ITEMS } from "./constants.js";
9
9
  import { isConditionListItemRefValueData, isFormDefinition } from "./helpers.js";
10
10
  import { SchemaVersion } from "./types.js";
@@ -36,7 +36,11 @@ export const listItemIdValidator = (value, helpers) => {
36
36
  if (!definition) {
37
37
  return value;
38
38
  }
39
- const conditionValue = helpers.state.ancestors[0];
39
+
40
+ // `itemId` is normally an array, so the condition value is one level up from
41
+ // each entry being validated. For a legacy bare-string `itemId` it is the
42
+ // nearest ancestor instead, so locate it by shape rather than fixed position.
43
+ const conditionValue = helpers.state.ancestors.find(isConditionListItemRefValueData);
40
44
  if (!isConditionListItemRefValueData(conditionValue)) {
41
45
  return value;
42
46
  }
@@ -103,7 +107,8 @@ const conditionListItemRefDataSchemaV2 = Joi.object().description('List item ref
103
107
  is: Joi.exist(),
104
108
  then: Joi.valid(listIdRef)
105
109
  }).description('The id of the list').error(checkErrors(FormDefinitionError.RefConditionListId)),
106
- itemId: Joi.string().trim().required().description('The id of the list item').custom(listItemIdValidator)
110
+ itemId: Joi.array().single().items(Joi.string().trim().custom(listItemIdValidator)).min(1).required().description('The ids of the selected list items.'),
111
+ itemsCoordinator: Joi.string().trim().valid(...Object.values(Coordinator)).optional().description('How multiple checkbox selections are combined (and/or)')
107
112
  });
108
113
  const relativeDateValueDataSchemaV2 = Joi.object().description('Relative date specification for date-based conditions').keys({
109
114
  period: Joi.number().integer().positive().required().description('Numeric amount of the time period, as a string'),
@@ -255,6 +260,12 @@ export const componentSchema = Joi.object().description('Form component definiti
255
260
  is: Joi.string().trim().valid(ComponentType.GeospatialField).required(),
256
261
  then: Joi.array().items(Joi.string().valid(...Object.values(GeospatialFieldGeometryTypesEnum))).description('Geometry types for geospatial data - for GeospatialField only')
257
262
  }).description('Geometry types - for GeospatialField only'),
263
+ mapLayers: Joi.when('type', {
264
+ is: Joi.string().trim().valid(ComponentType.GeospatialField, ComponentType.EastingNorthingField, ComponentType.LatLongField, ComponentType.OsGridRefField).required(),
265
+ then: Joi.object().keys({
266
+ sssi: Joi.boolean().optional().description('Sites of Special Scientific Interest layer')
267
+ }).optional().description('Supported map layers')
268
+ }).description('Map layers'),
258
269
  format: Joi.when('type', {
259
270
  is: Joi.string().trim().valid(ComponentType.TelephoneNumberField).required(),
260
271
  then: Joi.string().valid(...Object.values(TelephoneNumberFieldOptionsFormatEnum)).description('Format for telephone number - for TelephoneNumberField only')