@opencrvs/toolkit 2.0.0-rc.ff04b30 → 2.0.0-rc.ff777d6

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.
@@ -655,8 +655,8 @@ var ActionConditional = z7.discriminatedUnion("type", [
655
655
  // Action can be shown to the user in the list but as disabled
656
656
  EnableConditional
657
657
  ]).meta({
658
- description: "Action conditional configuration",
659
- id: "ActionConditional"
658
+ id: "ActionConditional",
659
+ description: "Conditional gating whether an action is shown (SHOW) or enabled (ENABLE). When omitted from an action, the action is shown and enabled for everyone."
660
660
  });
661
661
  var DisplayOnReviewConditional = z7.object({
662
662
  type: z7.literal(ConditionalType.DISPLAY_ON_REVIEW),
@@ -672,8 +672,8 @@ var FieldConditional = z7.discriminatedUnion("type", [
672
672
  // Field output can be shown / hidden on the review page
673
673
  DisplayOnReviewConditional
674
674
  ]).meta({
675
- description: "Field conditional configuration",
676
- id: "FieldConditional"
675
+ id: "FieldConditional",
676
+ description: "Conditional gating whether a form field is shown (SHOW), enabled (ENABLE), or displayed on the review page (DISPLAY_ON_REVIEW). When omitted, the field is shown and enabled for everyone, and is displayed on review whenever it has a value."
677
677
  });
678
678
 
679
679
  // ../commons/src/events/FieldType.ts
@@ -888,7 +888,7 @@ var PlainDate = import_zod.z.string().date().brand("PlainDate").describe("Date i
888
888
  // ../commons/src/events/FieldValue.ts
889
889
  var TextValue = z12.string();
890
890
  var HiddenFieldValue = z12.string();
891
- var NonEmptyTextValue = TextValue.min(1);
891
+ var NonEmptyTextValue = z12.string().trim().min(1);
892
892
  var DateValue = z12.iso.date().describe("Date in the format YYYY-MM-DD");
893
893
  var AgeValue = z12.object({
894
894
  age: z12.number(),
@@ -917,6 +917,7 @@ var DateRangeFieldValue = z12.object({
917
917
  var EmailValue = z12.email();
918
918
  var CheckboxFieldValue = z12.boolean();
919
919
  var NumberFieldValue = z12.number();
920
+ var SignatureFieldValue = FileFieldValue;
920
921
  var ButtonFieldValue = z12.number();
921
922
  var VerificationStatusValue = z12.enum([
922
923
  "verified",
@@ -1215,8 +1216,9 @@ var RequestedCorrectionAction = ActionBase.extend(
1215
1216
  var ApprovedCorrectionAction = ActionBase.extend(
1216
1217
  z14.object({
1217
1218
  type: z14.literal(ActionType.APPROVE_CORRECTION),
1218
- requestId: z14.string()
1219
+ requestId: z14.string(),
1219
1220
  // TODO move into 'content' property
1221
+ content: z14.object({ immediateCorrection: z14.boolean().optional() }).optional()
1220
1222
  }).shape
1221
1223
  );
1222
1224
  var RejectedCorrectionAction = ActionBase.extend(
@@ -1309,8 +1311,8 @@ var FlagConfig = z15.object({
1309
1311
  ),
1310
1312
  label: TranslationConfig.describe("Human readable label of the flag.")
1311
1313
  }).meta({
1312
- description: "Flag configuration",
1313
- id: "FlagConfig"
1314
+ id: "FlagConfig",
1315
+ description: "Configuration for a custom flag that can be added to or removed from records by event actions."
1314
1316
  });
1315
1317
  var ActionFlagConfig = z15.object({
1316
1318
  id: Flag,
@@ -1319,8 +1321,8 @@ var ActionFlagConfig = z15.object({
1319
1321
  "When conditional is met, the operation is performed on the flag. If not provided, the operation is performed unconditionally."
1320
1322
  )
1321
1323
  }).meta({
1322
- description: "Action flag configuration",
1323
- id: "ActionFlagConfig"
1324
+ id: "ActionFlagConfig",
1325
+ description: "Add or remove operation applied to a flag when the parent action is accepted. Optionally gated by a conditional."
1324
1326
  });
1325
1327
 
1326
1328
  // ../commons/src/events/EventMetadata.ts
@@ -1665,11 +1667,28 @@ var FieldReference = import_v43.default.object({
1665
1667
  $$field: FieldId.describe("Id of the field to reference"),
1666
1668
  $$subfield: import_v43.default.array(import_v43.default.string()).optional().default([]).describe(
1667
1669
  'If the FieldValue is an object, subfield can be used to refer to e.g. `["foo", "bar"]` in `{ foo: { bar: 3 } }`'
1670
+ ),
1671
+ $$code: import_v43.default.string().optional().describe(
1672
+ "Serialised client-side function body. When present the expression is evaluated rather than dereferenced."
1673
+ )
1674
+ }).describe(
1675
+ "Reference to a field value, with an optional client-side computation applied."
1676
+ );
1677
+ var ComputedDefaultValue = import_v43.default.object({
1678
+ $$code: import_v43.default.string().describe(
1679
+ "Serialised client-side function body. Receives (undefined, context) where context includes $now, $online, and system variables."
1668
1680
  )
1669
- }).describe("Reference to a field by its ID");
1681
+ }).describe("A context-only computation used as a field default value.");
1670
1682
  var ValidationConfig = import_v43.default.object({
1671
- validator: Conditional,
1672
- message: TranslationConfig
1683
+ validator: Conditional.describe(
1684
+ "Conditional expression that must hold for the field value to be considered valid."
1685
+ ),
1686
+ message: TranslationConfig.describe(
1687
+ "Error message displayed when the validator does not hold."
1688
+ )
1689
+ }).meta({
1690
+ id: "ValidationConfig",
1691
+ description: "Validation rule applied to a form field. The validator is a conditional expression that must hold for the field value to be considered valid."
1673
1692
  });
1674
1693
  var requiredSchema = import_v43.default.union([
1675
1694
  import_v43.default.boolean(),
@@ -1700,7 +1719,7 @@ var BaseField = import_v43.default.object({
1700
1719
  "Indicates whether the field can be modified during record correction."
1701
1720
  ),
1702
1721
  value: FieldReference.or(import_v43.default.array(FieldReference)).optional().describe(
1703
- "Reference to the source field or fields. When a value is defined, it is copied from the parent field when changed. If multiple references are provided, the first truthy value is used."
1722
+ "Reference to the source field or fields. When a value is defined, it is copied from the parent field when changed. If multiple references are provided, the first truthy value is used. A FieldReference with $$code computes the value via a custom client-side function."
1704
1723
  ),
1705
1724
  analytics: import_v43.default.boolean().default(false).optional().describe(
1706
1725
  "Indicates whether the field is included in analytics. When enabled, its value becomes available in the analytics dashboard."
@@ -1708,30 +1727,39 @@ var BaseField = import_v43.default.object({
1708
1727
  }).describe("Common properties shared across all field types.");
1709
1728
  var Divider = BaseField.extend({
1710
1729
  type: import_v43.default.literal(FieldType.DIVIDER)
1730
+ }).meta({
1731
+ description: "A horizontal line divider",
1732
+ id: "Divider"
1711
1733
  });
1712
1734
  var TextField = BaseField.extend({
1713
1735
  type: import_v43.default.literal(FieldType.TEXT),
1714
- defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
1736
+ defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField, ComputedDefaultValue]).optional(),
1715
1737
  configuration: import_v43.default.object({
1716
1738
  maxLength: import_v43.default.number().optional().describe("Maximum length of the text"),
1717
1739
  type: import_v43.default.enum(["text", "password"]).optional(),
1718
1740
  prefix: TranslationConfig.optional(),
1719
1741
  postfix: TranslationConfig.optional()
1720
1742
  }).default({ type: "text" }).optional()
1721
- }).describe("Text input");
1743
+ }).meta({
1744
+ description: "A text input field",
1745
+ id: "TextField"
1746
+ });
1722
1747
  var NumberField = BaseField.extend({
1723
1748
  type: import_v43.default.literal(FieldType.NUMBER),
1724
- defaultValue: NumberFieldValue.optional(),
1749
+ defaultValue: NumberFieldValue.or(ComputedDefaultValue).optional(),
1725
1750
  configuration: import_v43.default.object({
1726
1751
  min: import_v43.default.number().optional().describe("Minimum value"),
1727
1752
  max: import_v43.default.number().optional().describe("Maximum value"),
1728
1753
  prefix: TranslationConfig.optional(),
1729
1754
  postfix: TranslationConfig.optional()
1730
1755
  }).optional()
1731
- }).describe("Number input");
1756
+ }).meta({
1757
+ description: "A number input field",
1758
+ id: "NumberField"
1759
+ });
1732
1760
  var TextAreaField = BaseField.extend({
1733
1761
  type: import_v43.default.literal(FieldType.TEXTAREA),
1734
- defaultValue: NonEmptyTextValue.optional(),
1762
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
1735
1763
  configuration: import_v43.default.object({
1736
1764
  maxLength: import_v43.default.number().optional().describe("Maximum length of the text"),
1737
1765
  rows: import_v43.default.number().optional().describe("Number of visible text lines"),
@@ -1739,7 +1767,10 @@ var TextAreaField = BaseField.extend({
1739
1767
  prefix: TranslationConfig.optional(),
1740
1768
  postfix: TranslationConfig.optional()
1741
1769
  }).default({ rows: 4 }).optional()
1742
- }).describe("Multiline text input");
1770
+ }).meta({
1771
+ description: "A multiline text input",
1772
+ id: "TextAreaField"
1773
+ });
1743
1774
  var ImageMimeType = import_v43.default.enum([
1744
1775
  "image/png",
1745
1776
  "image/jpg",
@@ -1762,58 +1793,76 @@ var SignatureField = BaseField.extend({
1762
1793
  signaturePromptLabel: TranslationConfig.describe(
1763
1794
  "Title of the signature modal"
1764
1795
  ),
1765
- defaultValue: FieldValue.optional(),
1796
+ defaultValue: SignatureFieldValue.or(ComputedDefaultValue).optional(),
1766
1797
  configuration: import_v43.default.object({
1767
1798
  maxFileSize: import_v43.default.number().describe("Maximum file size in bytes").default(DEFAULT_MAX_FILE_SIZE_BYTES),
1768
1799
  acceptedFileTypes: MimeType.array().optional().describe("List of allowed file formats for the signature")
1769
1800
  }).default({
1770
1801
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
1771
1802
  })
1772
- }).describe("Signature input field");
1803
+ }).meta({
1804
+ description: "A signature input field",
1805
+ id: "SignatureField"
1806
+ });
1773
1807
  var EmailField = BaseField.extend({
1774
1808
  type: import_v43.default.literal(FieldType.EMAIL),
1775
1809
  configuration: import_v43.default.object({
1776
1810
  maxLength: import_v43.default.number().optional().describe("Maximum length of the text")
1777
1811
  }).default({ maxLength: 255 }).optional(),
1778
- defaultValue: NonEmptyTextValue.optional()
1812
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional()
1813
+ }).meta({
1814
+ description: "An email input field",
1815
+ id: "EmailField"
1779
1816
  });
1780
1817
  var DateField = BaseField.extend({
1781
1818
  type: import_v43.default.literal(FieldType.DATE),
1782
- defaultValue: SerializedNowDateTime.or(PlainDate).optional().describe("Default date value(yyyy-MM-dd)"),
1819
+ defaultValue: SerializedNowDateTime.or(PlainDate).or(ComputedDefaultValue).optional().describe("Default date value(yyyy-MM-dd)"),
1783
1820
  configuration: import_v43.default.object({
1784
1821
  notice: TranslationConfig.describe(
1785
1822
  "Text to display above the date input"
1786
1823
  ).optional()
1787
1824
  }).optional()
1788
- }).describe("A single date input (yyyy-MM-dd)");
1825
+ }).meta({
1826
+ description: "A date input (yyyy-MM-dd)",
1827
+ id: "DateField"
1828
+ });
1789
1829
  var AgeField = BaseField.extend({
1790
1830
  type: import_v43.default.literal(FieldType.AGE),
1791
- defaultValue: NumberFieldValue.optional(),
1831
+ defaultValue: NumberFieldValue.or(ComputedDefaultValue).optional(),
1792
1832
  configuration: import_v43.default.object({
1793
1833
  asOfDate: FieldReference,
1794
1834
  prefix: TranslationConfig.optional(),
1795
1835
  postfix: TranslationConfig.optional()
1796
1836
  })
1797
- }).describe("An age input field which uses the current date as the asOfDate");
1837
+ }).meta({
1838
+ description: "An age input field which uses the current date as the asOfDate",
1839
+ id: "AgeField"
1840
+ });
1798
1841
  var TimeField = BaseField.extend({
1799
1842
  type: import_v43.default.literal(FieldType.TIME),
1800
- defaultValue: SerializedNowDateTime.or(TimeValue).optional().describe("Default time value (HH-mm)"),
1843
+ defaultValue: SerializedNowDateTime.or(TimeValue).or(ComputedDefaultValue).optional().describe("Default time value (HH-mm)"),
1801
1844
  configuration: import_v43.default.object({
1802
1845
  use12HourFormat: import_v43.default.boolean().optional().describe("Whether to use 12-hour format"),
1803
1846
  notice: TranslationConfig.describe(
1804
1847
  "Text to display above the time input"
1805
1848
  ).optional()
1806
1849
  }).optional()
1807
- }).describe("A single date input (HH-mm)");
1850
+ }).meta({
1851
+ description: "A single time input (HH-mm)",
1852
+ id: "TimeField"
1853
+ });
1808
1854
  var DateRangeField = BaseField.extend({
1809
1855
  type: import_v43.default.literal(FieldType.DATE_RANGE),
1810
- defaultValue: DateRangeFieldValue.optional(),
1856
+ defaultValue: DateRangeFieldValue.or(ComputedDefaultValue).optional(),
1811
1857
  configuration: import_v43.default.object({
1812
1858
  notice: TranslationConfig.describe(
1813
1859
  "Text to display above the date input"
1814
1860
  ).optional()
1815
1861
  }).optional()
1816
- }).describe("A date range input ({ start: yyyy-MM-dd, end: yyyy-MM-dd })");
1862
+ }).meta({
1863
+ description: "A date range input ({ start: yyyy-MM-dd, end: yyyy-MM-dd })",
1864
+ id: "DateRangeField"
1865
+ });
1817
1866
  var HtmlFontVariant = import_v43.default.enum([
1818
1867
  "reg12",
1819
1868
  "reg14",
@@ -1857,21 +1906,33 @@ var ImageViewField = BaseField.extend({
1857
1906
  type: import_v43.default.literal(FieldType.IMAGE_VIEW),
1858
1907
  defaultValue: NonEmptyTextValue.optional(),
1859
1908
  configuration: ImageConfiguration
1860
- }).describe("A read-only image component for form pages");
1909
+ }).meta({
1910
+ description: "A read-only image component for form pages",
1911
+ id: "ImageViewField"
1912
+ });
1861
1913
  var Paragraph = BaseField.extend({
1862
1914
  type: import_v43.default.literal(FieldType.PARAGRAPH),
1863
1915
  configuration: ParagraphConfiguration
1864
- }).describe("A read-only HTML <p> paragraph");
1916
+ }).meta({
1917
+ description: "A read-only HTML <p> paragraph",
1918
+ id: "Paragraph"
1919
+ });
1865
1920
  var Heading = BaseField.extend({
1866
1921
  type: import_v43.default.literal(FieldType.HEADING),
1867
1922
  configuration: HeadingConfiguration
1868
- }).describe("A read-only heading component for form pages");
1923
+ }).meta({
1924
+ description: "A read-only heading component for form pages",
1925
+ id: "Heading"
1926
+ });
1869
1927
  var PageHeader = BaseField.extend({
1870
1928
  type: import_v43.default.literal(FieldType.PAGE_HEADER)
1871
- }).describe("A read-only header component for form pages");
1929
+ }).meta({
1930
+ description: "A read-only header component for form pages",
1931
+ id: "PageHeader"
1932
+ });
1872
1933
  var File = BaseField.extend({
1873
1934
  type: import_v43.default.literal(FieldType.FILE),
1874
- defaultValue: FileFieldValue.optional(),
1935
+ defaultValue: FileFieldValue.or(ComputedDefaultValue).optional(),
1875
1936
  configuration: import_v43.default.object({
1876
1937
  maxFileSize: import_v43.default.number().describe("Maximum file size in bytes").default(DEFAULT_MAX_FILE_SIZE_BYTES),
1877
1938
  acceptedFileTypes: MimeType.array().optional().describe("List of allowed file formats for the signature"),
@@ -1887,7 +1948,10 @@ var File = BaseField.extend({
1887
1948
  }).default({
1888
1949
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
1889
1950
  })
1890
- }).describe("File upload");
1951
+ }).meta({
1952
+ description: "A file upload field",
1953
+ id: "File"
1954
+ });
1891
1955
  var SelectOption = import_v43.default.object({
1892
1956
  value: import_v43.default.string().describe("The value of the option"),
1893
1957
  label: import_v43.default.union([import_v43.default.string(), TranslationConfig]).describe("The label of the option"),
@@ -1895,7 +1959,7 @@ var SelectOption = import_v43.default.object({
1895
1959
  });
1896
1960
  var NumberWithUnitField = BaseField.extend({
1897
1961
  type: import_v43.default.literal(FieldType.NUMBER_WITH_UNIT),
1898
- defaultValue: NumberWithUnitFieldValue.optional(),
1962
+ defaultValue: NumberWithUnitFieldValue.or(ComputedDefaultValue).optional(),
1899
1963
  options: import_v43.default.array(SelectOption).describe("A list of options for the unit select"),
1900
1964
  configuration: import_v43.default.object({
1901
1965
  min: import_v43.default.number().optional().describe("Minimum value of the number field"),
@@ -1904,17 +1968,23 @@ var NumberWithUnitField = BaseField.extend({
1904
1968
  "Placeholder for the number field"
1905
1969
  )
1906
1970
  }).optional()
1907
- }).describe("Number with unit input");
1971
+ }).meta({
1972
+ description: "A number with unit input field",
1973
+ id: "NumberWithUnitField"
1974
+ });
1908
1975
  var RadioGroup = BaseField.extend({
1909
1976
  type: import_v43.default.literal(FieldType.RADIO_GROUP),
1910
- defaultValue: TextValue.optional(),
1977
+ defaultValue: TextValue.or(ComputedDefaultValue).optional(),
1911
1978
  options: import_v43.default.array(SelectOption).describe("A list of options"),
1912
1979
  configuration: import_v43.default.object({
1913
1980
  styles: import_v43.default.object({
1914
1981
  size: import_v43.default.enum(["NORMAL", "LARGE"]).optional()
1915
1982
  }).optional()
1916
1983
  }).optional()
1917
- }).describe("Grouped radio options");
1984
+ }).meta({
1985
+ description: "A grouped radio button field",
1986
+ id: "RadioGroup"
1987
+ });
1918
1988
  var BulletList = BaseField.extend({
1919
1989
  type: import_v43.default.literal(FieldType.BULLET_LIST),
1920
1990
  items: import_v43.default.array(TranslationConfig).describe("A list of items"),
@@ -1923,10 +1993,13 @@ var BulletList = BaseField.extend({
1923
1993
  fontVariant: HtmlFontVariant.optional()
1924
1994
  }).optional()
1925
1995
  }).default({})
1926
- }).describe("A list of bullet points");
1996
+ }).meta({
1997
+ description: "A list of bullet points",
1998
+ id: "BulletList"
1999
+ });
1927
2000
  var Select = BaseField.extend({
1928
2001
  type: import_v43.default.literal(FieldType.SELECT),
1929
- defaultValue: TextValue.optional(),
2002
+ defaultValue: TextValue.or(ComputedDefaultValue).optional(),
1930
2003
  options: import_v43.default.array(SelectOption).describe("A list of options"),
1931
2004
  noOptionsMessage: TranslationConfig.optional().describe(
1932
2005
  `
@@ -1938,16 +2011,22 @@ var Select = BaseField.extend({
1938
2011
  { ..., defaultMessage: "'{input}' is not listed among the health facilities." }
1939
2012
  `
1940
2013
  )
1941
- }).describe("Select input");
2014
+ }).meta({
2015
+ description: "A select input field",
2016
+ id: "Select"
2017
+ });
1942
2018
  var SelectDateRangeOption = import_v43.default.object({
1943
2019
  value: SelectDateRangeValue.describe("The value of the option"),
1944
2020
  label: TranslationConfig.describe("The label of the option")
1945
2021
  });
1946
2022
  var SelectDateRangeField = BaseField.extend({
1947
2023
  type: import_v43.default.literal(FieldType.SELECT_DATE_RANGE),
1948
- defaultValue: SelectDateRangeValue.optional(),
2024
+ defaultValue: SelectDateRangeValue.or(ComputedDefaultValue).optional(),
1949
2025
  options: import_v43.default.array(SelectDateRangeOption).describe("A list of options")
1950
- }).describe("Select input with date range options");
2026
+ }).meta({
2027
+ description: "A date range selection field",
2028
+ id: "SelectDateRangeField"
2029
+ });
1951
2030
  var NameConfig = import_v43.default.object({
1952
2031
  firstname: import_v43.default.object({ required: requiredSchema, label: TranslationConfig.optional() }).optional(),
1953
2032
  middlename: import_v43.default.object({ required: requiredSchema, label: TranslationConfig.optional() }).optional(),
@@ -1959,7 +2038,7 @@ var NameField = BaseField.extend({
1959
2038
  firstname: SerializedUserField.or(NonEmptyTextValue).optional(),
1960
2039
  middlename: SerializedUserField.or(NonEmptyTextValue).optional(),
1961
2040
  surname: SerializedUserField.or(NonEmptyTextValue).optional()
1962
- }).optional(),
2041
+ }).or(ComputedDefaultValue).optional(),
1963
2042
  configuration: import_v43.default.object({
1964
2043
  name: NameConfig.default({
1965
2044
  firstname: { required: true },
@@ -1978,26 +2057,41 @@ var NameField = BaseField.extend({
1978
2057
  surname: { required: true }
1979
2058
  }
1980
2059
  }).optional()
1981
- }).describe("Name input field");
2060
+ }).meta({
2061
+ description: "A field for entering a persons name",
2062
+ id: "NameField"
2063
+ });
1982
2064
  var PhoneField = BaseField.extend({
1983
- defaultValue: NonEmptyTextValue.optional(),
2065
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
1984
2066
  type: import_v43.default.literal(FieldType.PHONE)
1985
- }).describe("Phone input field");
2067
+ }).meta({
2068
+ description: "A field for entering a phone number",
2069
+ id: "PhoneField"
2070
+ });
1986
2071
  var IdField = BaseField.extend({
1987
- defaultValue: NonEmptyTextValue.optional(),
2072
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
1988
2073
  type: import_v43.default.literal(FieldType.ID)
1989
- }).describe("ID input field");
2074
+ }).meta({
2075
+ description: "A field for entering an ID",
2076
+ id: "IdField"
2077
+ });
1990
2078
  var Checkbox = BaseField.extend({
1991
2079
  type: import_v43.default.literal(FieldType.CHECKBOX),
1992
- defaultValue: CheckboxFieldValue.default(false)
1993
- }).describe("Boolean checkbox field");
2080
+ defaultValue: CheckboxFieldValue.or(ComputedDefaultValue).default(false)
2081
+ }).meta({
2082
+ description: "A boolean checkbox field",
2083
+ id: "Checkbox"
2084
+ });
1994
2085
  var Country = BaseField.extend({
1995
2086
  type: import_v43.default.literal(FieldType.COUNTRY),
1996
- defaultValue: NonEmptyTextValue.optional(),
2087
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
1997
2088
  optionOverrides: import_v43.default.array(SelectOption.omit({ label: true })).optional().describe(
1998
2089
  "Conditionals for specific countries. Countries not listed are always shown and enabled."
1999
2090
  )
2000
- }).describe("Country select field");
2091
+ }).meta({
2092
+ description: "A field for selecting a country",
2093
+ id: "Country"
2094
+ });
2001
2095
  var AllowedLocations = JurisdictionReference.optional().describe(
2002
2096
  "Limits which location options are selectable depending on user jurisdiction and location."
2003
2097
  );
@@ -2006,28 +2100,33 @@ var AdministrativeAreas = import_v43.default.enum([
2006
2100
  "HEALTH_FACILITY",
2007
2101
  "CRVS_OFFICE"
2008
2102
  ]);
2009
- var AdministrativeAreaConfiguration = import_v43.default.object({
2010
- partOf: FieldReference.optional().describe("Parent location"),
2011
- type: AdministrativeAreas,
2012
- allowedLocations: AllowedLocations
2013
- }).describe("Administrative area options");
2014
2103
  var AdministrativeAreaField = BaseField.extend({
2015
2104
  type: import_v43.default.literal(FieldType.ADMINISTRATIVE_AREA),
2016
- defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
2017
- configuration: AdministrativeAreaConfiguration
2018
- }).describe("Administrative area input field e.g. facility, office");
2105
+ defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField, ComputedDefaultValue]).optional(),
2106
+ configuration: import_v43.default.object({
2107
+ partOf: FieldReference.optional().describe("Parent location"),
2108
+ type: AdministrativeAreas,
2109
+ allowedLocations: AllowedLocations
2110
+ }).describe("Administrative area options")
2111
+ }).meta({
2112
+ description: "Administrative area input field",
2113
+ id: "AdministrativeAreaField"
2114
+ });
2019
2115
  var LocationInput = BaseField.extend({
2020
2116
  type: import_v43.default.literal(FieldType.LOCATION),
2021
- defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
2117
+ defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField, ComputedDefaultValue]).optional(),
2022
2118
  configuration: import_v43.default.object({
2023
2119
  locationTypes: import_v43.default.array(import_v43.default.string()).optional().describe("Types of the locations that are available for selection."),
2024
2120
  allowedLocations: AllowedLocations
2025
2121
  }).optional()
2026
- }).describe("Input field for a location");
2122
+ }).meta({
2123
+ description: "A field for selecting a location",
2124
+ id: "LocationInput"
2125
+ });
2027
2126
  var FileUploadWithOptions = BaseField.extend({
2028
2127
  type: import_v43.default.literal(FieldType.FILE_WITH_OPTIONS),
2029
2128
  options: import_v43.default.array(SelectOption).describe("A list of options"),
2030
- defaultValue: FileFieldWithOptionValue.optional(),
2129
+ defaultValue: FileFieldWithOptionValue.or(ComputedDefaultValue).optional(),
2031
2130
  configuration: import_v43.default.object({
2032
2131
  maxFileSize: import_v43.default.number().describe("Maximum file size in bytes").default(DEFAULT_MAX_FILE_SIZE_BYTES),
2033
2132
  maxImageSize: import_v43.default.object({
@@ -2037,15 +2136,18 @@ var FileUploadWithOptions = BaseField.extend({
2037
2136
  }).default({
2038
2137
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
2039
2138
  })
2139
+ }).meta({
2140
+ description: "A field for uploading files with file type options",
2141
+ id: "FileUploadWithOptions"
2040
2142
  });
2041
2143
  var Facility = BaseField.extend({
2042
2144
  type: import_v43.default.literal(FieldType.FACILITY),
2043
- defaultValue: NonEmptyTextValue.optional(),
2145
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2044
2146
  configuration: import_v43.default.object({ allowedLocations: AllowedLocations }).optional()
2045
2147
  }).describe("Input field for a facility");
2046
2148
  var Office = BaseField.extend({
2047
2149
  type: import_v43.default.literal(FieldType.OFFICE),
2048
- defaultValue: NonEmptyTextValue.optional(),
2150
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2049
2151
  configuration: import_v43.default.object({ allowedLocations: AllowedLocations }).optional()
2050
2152
  }).describe("Input field for an office");
2051
2153
  var DefaultAddressFieldValue = DomesticAddressFieldValue.extend({
@@ -2081,8 +2183,11 @@ var Address = BaseField.extend({
2081
2183
  ).optional(),
2082
2184
  allowedLocations: AllowedLocations
2083
2185
  }).optional(),
2084
- defaultValue: DefaultAddressFieldValue.optional()
2085
- }).describe("Address input field \u2013 a combination of location and text fields");
2186
+ defaultValue: DefaultAddressFieldValue.or(ComputedDefaultValue).optional()
2187
+ }).meta({
2188
+ description: "Address input field \u2013 a combination of location and text fields",
2189
+ id: "Address"
2190
+ });
2086
2191
  var StaticDataEntry = import_v43.default.object({
2087
2192
  id: import_v43.default.string().describe("ID for the data entry."),
2088
2193
  label: TranslationConfig,
@@ -2097,7 +2202,10 @@ var DataField = BaseField.extend({
2097
2202
  subtitle: TranslationConfig.optional(),
2098
2203
  data: import_v43.default.array(DataEntry)
2099
2204
  })
2100
- }).describe("Data field for displaying read-only data");
2205
+ }).meta({
2206
+ description: "A field for displaying a table of read-only data",
2207
+ id: "DataField"
2208
+ });
2101
2209
  var ButtonSize = import_v43.default.enum(["small", "medium", "large"]);
2102
2210
  var ButtonType = import_v43.default.enum([
2103
2211
  "primary",
@@ -2122,13 +2230,19 @@ var ButtonConfiguration = import_v43.default.object({
2122
2230
  });
2123
2231
  var ButtonField = BaseField.extend({
2124
2232
  type: import_v43.default.literal(FieldType.BUTTON),
2125
- defaultValue: ButtonFieldValue.optional(),
2233
+ defaultValue: ButtonFieldValue.or(ComputedDefaultValue).optional(),
2126
2234
  configuration: ButtonConfiguration
2127
- }).describe("Generic button without any built-in functionality");
2235
+ }).meta({
2236
+ description: "A generic button that can be used to trigger an action",
2237
+ id: "ButtonField"
2238
+ });
2128
2239
  var FieldGroup = BaseField.extend({
2129
2240
  type: import_v43.default.literal(FieldType.FIELD_GROUP),
2130
2241
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
2131
2242
  fields: import_v43.default.lazy(() => import_v43.default.array(FieldConfig))
2243
+ }).meta({
2244
+ description: "A group of fields that are displayed together",
2245
+ id: "FieldGroup"
2132
2246
  });
2133
2247
  var AlphaPrintButton = BaseField.extend({
2134
2248
  type: import_v43.default.literal(FieldType.ALPHA_PRINT_BUTTON),
@@ -2138,10 +2252,13 @@ var AlphaPrintButton = BaseField.extend({
2138
2252
  "Label for the print button"
2139
2253
  )
2140
2254
  })
2141
- }).describe("Print button field for printing certificates");
2255
+ }).meta({
2256
+ description: "An experimental print button field for printing certificates during the declaration process",
2257
+ id: "AlphaPrintButton"
2258
+ });
2142
2259
  var HttpField = BaseField.extend({
2143
2260
  type: import_v43.default.literal(FieldType.HTTP),
2144
- defaultValue: HttpFieldValue.optional(),
2261
+ defaultValue: HttpFieldValue.or(ComputedDefaultValue).optional(),
2145
2262
  configuration: import_v43.default.object({
2146
2263
  trigger: FieldReference.optional().describe(
2147
2264
  "Reference to the field that triggers the HTTP request when its value changes. If not provided, the HTTP request is triggered once on component mount."
@@ -2154,20 +2271,30 @@ var HttpField = BaseField.extend({
2154
2271
  params: import_v43.default.record(import_v43.default.string(), import_v43.default.union([import_v43.default.string(), FieldReference])).optional(),
2155
2272
  timeout: import_v43.default.number().default(15e3).describe("Request timeout in milliseconds")
2156
2273
  })
2157
- }).describe("HTTP request function triggered by a button click or other event");
2274
+ }).meta({
2275
+ description: "Makes a background HTTP request to an external service and stores the response so other fields can use it. Has no visible UI \u2014 pair with LOADER to show request status.",
2276
+ id: "HttpField"
2277
+ });
2158
2278
  var AutocompleteField = BaseField.extend({
2159
2279
  type: import_v43.default.literal(FieldType.AUTOCOMPLETE),
2160
2280
  configuration: import_v43.default.object({
2161
- url: import_v43.default.string().describe("URL to fetch autocomplete suggestions from").optional(),
2281
+ url: import_v43.default.string().describe(
2282
+ "URL to fetch autocomplete suggestions from. This should be a country config server endpoint."
2283
+ ).optional(),
2162
2284
  method: import_v43.default.enum(["GET", "POST"]).default("GET").optional(),
2163
2285
  defaultOptions: import_v43.default.array(
2164
2286
  import_v43.default.object({
2165
2287
  label: import_v43.default.string(),
2166
2288
  value: import_v43.default.string()
2167
2289
  })
2168
- ).optional()
2290
+ ).optional().describe(
2291
+ "Manual entry is supported through configuration, allowing users to provide values not currently represented in the dataset."
2292
+ )
2169
2293
  })
2170
- }).describe("Autocomplete input field");
2294
+ }).meta({
2295
+ description: "Generic autocomplete component designed for use with large dictionary-based datasets. The component supports dynamic retrieval of options from configurable data sources and is intended for datasets that may contain tens or hundreds of thousands of records.",
2296
+ id: "AutocompleteField"
2297
+ });
2171
2298
  var SearchField = HttpField.extend({
2172
2299
  type: import_v43.default.literal(FieldType.SEARCH),
2173
2300
  configuration: SearchQuery.pick({
@@ -2200,6 +2327,9 @@ var SearchField = HttpField.extend({
2200
2327
  ok: TranslationConfig.optional()
2201
2328
  }).optional()
2202
2329
  })
2330
+ }).meta({
2331
+ description: "A search input field",
2332
+ id: "SearchField"
2203
2333
  });
2204
2334
  var LinkButtonField = BaseField.extend({
2205
2335
  type: import_v43.default.literal(FieldType.LINK_BUTTON),
@@ -2208,28 +2338,35 @@ var LinkButtonField = BaseField.extend({
2208
2338
  text: TranslationConfig.describe("Text to display on the button"),
2209
2339
  icon: import_v43.default.string().optional().describe("Icon for the button. You can find icons from OpenCRVS UI-Kit.")
2210
2340
  })
2211
- }).describe("Button that opens a link");
2341
+ }).meta({
2342
+ description: "A button that opens a URL link",
2343
+ id: "LinkButtonField"
2344
+ });
2212
2345
  var VerificationStatus = BaseField.extend({
2213
2346
  type: import_v43.default.literal(FieldType.VERIFICATION_STATUS),
2214
- defaultValue: VerificationStatusValue.optional(),
2347
+ defaultValue: VerificationStatusValue.or(ComputedDefaultValue).optional(),
2215
2348
  configuration: import_v43.default.object({
2216
2349
  status: TranslationConfig.describe("Text to display on the status pill."),
2217
2350
  description: TranslationConfig.describe(
2218
2351
  "Explaining text on the banner in form."
2219
2352
  )
2220
2353
  })
2354
+ }).meta({
2355
+ description: "Displays a verification state (e.g. ID verified / pending). Often paired with ID_READER \u2014 it can read its value off an ID_READER rather than holding its own.",
2356
+ id: "VerificationStatus"
2221
2357
  });
2222
2358
  var QueryParamReaderField = BaseField.extend({
2223
2359
  type: import_v43.default.literal(FieldType.QUERY_PARAM_READER),
2224
2360
  configuration: import_v43.default.object({
2225
2361
  pickParams: import_v43.default.array(import_v43.default.string()).describe("List of query parameters to read from the URL")
2226
2362
  })
2227
- }).describe(
2228
- "A field that maps URL query params into form values and clears them afterward"
2229
- );
2363
+ }).meta({
2364
+ description: "A field that maps URL query params into form values and clears them afterward",
2365
+ id: "QueryParamReaderField"
2366
+ });
2230
2367
  var QrReaderField = BaseField.extend({
2231
2368
  type: import_v43.default.literal(FieldType.QR_READER),
2232
- defaultValue: QrReaderFieldValue.optional(),
2369
+ defaultValue: QrReaderFieldValue.or(ComputedDefaultValue).optional(),
2233
2370
  configuration: import_v43.default.object({
2234
2371
  validator: import_v43.default.any().meta({
2235
2372
  description: "JSON Schema to validate the scanned QR code data against before populating the form fields.",
@@ -2237,21 +2374,27 @@ var QrReaderField = BaseField.extend({
2237
2374
  })
2238
2375
  }).optional()
2239
2376
  }).meta({
2240
- description: "Configuration for QR code reader field, including optional JSON Schema validator.",
2377
+ description: "QR code reader field, including optional JSON Schema validator.",
2241
2378
  id: "QrReaderField"
2242
2379
  });
2243
2380
  var IdReaderField = BaseField.extend({
2244
2381
  type: import_v43.default.literal(FieldType.ID_READER),
2245
- defaultValue: IdReaderFieldValue.optional(),
2382
+ defaultValue: IdReaderFieldValue.or(ComputedDefaultValue).optional(),
2246
2383
  methods: import_v43.default.array(
2247
2384
  import_v43.default.union([QrReaderField, LinkButtonField]).describe("Methods for reading an ID")
2248
2385
  )
2386
+ }).meta({
2387
+ description: "A wrapper around nested form fields, specifically QR_READER and LINK_BUTTON. It can hold the QR_READERs value.",
2388
+ id: "IdReaderField"
2249
2389
  });
2250
2390
  var CustomField = BaseField.extend({
2251
2391
  type: import_v43.default.literal(FieldType._EXPERIMENTAL_CUSTOM),
2252
2392
  defaultValue: CustomFieldValue.optional(),
2253
2393
  src: import_v43.default.string().describe("Module source path for the custom field component"),
2254
2394
  configuration: import_v43.default.unknown().optional()
2395
+ }).meta({
2396
+ description: "An expiremental custom field that is defined by a module source path",
2397
+ id: "CustomField"
2255
2398
  });
2256
2399
  var FieldStyleVariant = import_v43.default.enum(["default", "highlighted"]);
2257
2400
  var LoaderField = BaseField.extend({
@@ -2261,22 +2404,25 @@ var LoaderField = BaseField.extend({
2261
2404
  configuration: import_v43.default.object({
2262
2405
  text: TranslationConfig.describe("Display text above the loading spinner")
2263
2406
  })
2264
- }).describe(
2265
- "A non-interactive field that indicates an in progress operation in form"
2266
- );
2407
+ }).meta({
2408
+ description: "A non-interactive field that indicates an in progress operation in form",
2409
+ id: "LoaderField"
2410
+ });
2267
2411
  var HiddenField = BaseField.extend({
2268
2412
  type: import_v43.default.literal(FieldType.ALPHA_HIDDEN),
2269
2413
  required: import_v43.default.boolean().default(false).optional(),
2270
2414
  defaultValue: TextValue.optional()
2271
- }).describe(
2272
- "A non-interactive, hidden field that only hold a value in the form"
2273
- );
2415
+ }).meta({
2416
+ description: "A non-interactive, hidden field that only hold a value in the form",
2417
+ id: "HiddenField"
2418
+ });
2274
2419
  var UserRoleField = BaseField.extend({
2275
2420
  type: import_v43.default.literal(FieldType.USER_ROLE),
2276
2421
  defaultValue: TextValue.optional()
2277
- }).describe(
2278
- "A select dropdown that is automatically populated with available user roles"
2279
- );
2422
+ }).meta({
2423
+ description: "A select dropdown that is automatically populated with available user roles",
2424
+ id: "UserRoleField"
2425
+ });
2280
2426
  var FieldConfig = import_v43.default.discriminatedUnion("type", [
2281
2427
  FieldGroup,
2282
2428
  Address,
@@ -2376,15 +2522,18 @@ var VerificationPageConfig = FormPageConfig.extend({
2376
2522
  actions: VerificationActionConfig
2377
2523
  });
2378
2524
  var PageConfig = z21.discriminatedUnion("type", [FormPageConfig, VerificationPageConfig]).meta({
2379
- description: "Page configuration",
2380
- id: "PageConfig"
2525
+ id: "PageConfig",
2526
+ description: "Configuration for a single page in a form. Either a form page with fields and a continue button, or a verification page with verify/cancel options."
2381
2527
  });
2382
2528
 
2383
2529
  // ../commons/src/events/FormConfig.ts
2384
2530
  var DeclarationFormConfig = z22.object({
2385
2531
  label: TranslationConfig.describe("Human readable description of the form"),
2386
2532
  pages: z22.array(FormPageConfig)
2387
- }).describe("Configuration of the declaration form.");
2533
+ }).meta({
2534
+ id: "DeclarationFormConfig",
2535
+ description: "Configuration of the declaration form."
2536
+ });
2388
2537
  var ActionFormConfig = z22.object({
2389
2538
  label: TranslationConfig.describe("Human readable description of the form"),
2390
2539
  pages: z22.array(PageConfig)
@@ -2484,6 +2633,9 @@ var DeduplicationConfig = z23.object({
2484
2633
  id: z23.string(),
2485
2634
  label: TranslationConfig,
2486
2635
  query: Clause
2636
+ }).meta({
2637
+ id: "DeduplicationConfig",
2638
+ description: "Configuration for duplicate detection on a declare or register action. The query is built from fuzzy / strict / date-range matchers combined with and/or/not."
2487
2639
  });
2488
2640
 
2489
2641
  // ../commons/src/events/ActionConfig.ts
@@ -2601,17 +2753,42 @@ var ActionConfig = z24.discriminatedUnion("type", [
2601
2753
  * OpenAPI references are defined here so our generated OpenAPI spec knows to reuse the models
2602
2754
  * and treat them as "models" instead of duplicating the data structure in each endpoint.
2603
2755
  */
2604
- ReadActionConfig.meta({ id: "ReadActionConfig" }),
2605
- DeclareConfig.meta({ id: "DeclareActionConfig" }),
2606
- RejectConfig.meta({ id: "RejectActionConfig" }),
2607
- RegisterConfig.meta({ id: "RegisterActionConfig" }),
2756
+ ReadActionConfig.meta({
2757
+ id: "ReadActionConfig",
2758
+ description: "Configuration for the read action \u2014 defines the record-tab content displayed on the event overview page."
2759
+ }),
2760
+ DeclareConfig.meta({
2761
+ id: "DeclareActionConfig",
2762
+ description: "Configuration for the declare action. Includes review-page fields. Shared with the notify action (ActionType.NOTIFY)."
2763
+ }),
2764
+ RejectConfig.meta({
2765
+ id: "RejectActionConfig",
2766
+ description: "Configuration for rejecting a record before registration."
2767
+ }),
2768
+ RegisterConfig.meta({
2769
+ id: "RegisterActionConfig",
2770
+ description: "Configuration for registering a record."
2771
+ }),
2608
2772
  PrintCertificateActionConfig.meta({
2609
- id: "PrintCertificateActionConfig"
2773
+ id: "PrintCertificateActionConfig",
2774
+ description: "Configuration for printing a certificate of a registered record."
2775
+ }),
2776
+ RequestCorrectionConfig.meta({
2777
+ id: "RequestCorrectionActionConfig",
2778
+ description: "Configuration for requesting a correction on a registered record."
2610
2779
  }),
2611
- RequestCorrectionConfig.meta({ id: "RequestCorrectionActionConfig" }),
2612
- EditActionConfig.meta({ id: "EditActionConfig" }),
2613
- ArchiveConfig.meta({ id: "ArchiveActionConfig" }),
2614
- CustomActionConfig.meta({ id: "CustomActionConfig" })
2780
+ EditActionConfig.meta({
2781
+ id: "EditActionConfig",
2782
+ description: "Configuration for editing a record before registration."
2783
+ }),
2784
+ ArchiveConfig.meta({
2785
+ id: "ArchiveActionConfig",
2786
+ description: "Configuration for archiving a record."
2787
+ }),
2788
+ CustomActionConfig.meta({
2789
+ id: "CustomActionConfig",
2790
+ description: "Configuration for a country-defined custom action. An event may include any number of these."
2791
+ })
2615
2792
  ]).describe(
2616
2793
  "Configuration of an action available for an event. Data collected depends on the action type and is accessible through the annotation property in ActionDocument."
2617
2794
  ).meta({ id: "ActionConfig" });
@@ -2687,7 +2864,10 @@ var Field = BaseField2.extend({
2687
2864
  }).describe("Custom field defined for the summary view.");
2688
2865
  var SummaryConfig = z27.object({
2689
2866
  fields: z27.array(z27.union([Field, ReferenceField])).describe("Fields displayed in the event summary view.")
2690
- }).describe("Configuration of the event summary section.");
2867
+ }).meta({
2868
+ id: "SummaryConfig",
2869
+ description: "Configuration of the event overview page. Defines which declaration fields appear in the record summary, optionally with custom labels, empty-value messages, and templated values."
2870
+ });
2691
2871
 
2692
2872
  // ../commons/src/events/AdvancedSearchConfig.ts
2693
2873
  var z28 = __toESM(require("zod/v4"));
@@ -2758,6 +2938,9 @@ var BaseField3 = z28.object({
2758
2938
  ),
2759
2939
  validations: z28.array(ValidationConfig).optional().describe(
2760
2940
  `Option for overriding the field validations specifically for advanced search form.`
2941
+ ),
2942
+ allowedLocations: JurisdictionReference.optional().describe(
2943
+ `Override the allowedLocations for a location field in advanced search. Use this when the declaration form's allowedLocations references a scope (e.g. record.create) that search-only users don't have \u2014 specify record.search scope instead.`
2761
2944
  )
2762
2945
  });
2763
2946
  var SearchQueryParams = z28.object({
@@ -2811,6 +2994,9 @@ var AdvancedSearchField = z28.discriminatedUnion("fieldType", [FieldConfigSchema
2811
2994
  var AdvancedSearchConfig = z28.object({
2812
2995
  title: TranslationConfig.describe("Advanced search tab title"),
2813
2996
  fields: z28.array(AdvancedSearchField).describe("Advanced search fields within the tab.")
2997
+ }).meta({
2998
+ id: "AdvancedSearchConfig",
2999
+ description: "Configuration of one advanced search tab. Each tab has a title and a list of searchable fields \u2014 either declaration fields (via `field()`) or event metadata (via `event()`)."
2814
3000
  });
2815
3001
 
2816
3002
  // ../commons/src/events/utils.ts
@@ -2861,7 +3047,37 @@ function resolveDataPath(rootData, dataPath, instancePath) {
2861
3047
  }
2862
3048
  return current;
2863
3049
  }
3050
+ function todayISO() {
3051
+ return (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" });
3052
+ }
3053
+ var compiledFunctionCache = /* @__PURE__ */ new Map();
3054
+ function compileClientFunction(code) {
3055
+ let fn = compiledFunctionCache.get(code);
3056
+ if (!fn) {
3057
+ fn = new Function(`return (${code})`)();
3058
+ compiledFunctionCache.set(code, fn);
3059
+ }
3060
+ return fn;
3061
+ }
2864
3062
  (0, import_ajv_formats.default)(ajv);
3063
+ function buildClientFunctionContext(input) {
3064
+ return {
3065
+ $form: input.form,
3066
+ $now: todayISO(),
3067
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
3068
+ $online: isOnline(),
3069
+ $user: input.validatorContext?.user,
3070
+ $event: input.validatorContext?.event,
3071
+ $leafAdminStructureLocationIds: input.validatorContext?.leafAdminStructureLocationIds ?? [],
3072
+ user: input.systemVariables?.user,
3073
+ $window: input.systemVariables?.$window,
3074
+ locations: input.locations,
3075
+ adminLevelIds: input.adminLevelIds
3076
+ };
3077
+ }
3078
+ function runClientFunction(code, data, context) {
3079
+ return compileClientFunction(code)(data, context);
3080
+ }
2865
3081
  ajv.addKeyword({
2866
3082
  keyword: "daysFromDate",
2867
3083
  type: "string",
@@ -2906,12 +3122,35 @@ ajv.addKeyword({
2906
3122
  $data: true,
2907
3123
  errors: true,
2908
3124
  // @ts-ignore -- Force type. We will move this away from AJV next. Parsing the array will take seconds and is only called by core.
2909
- validate(schema, data, _2, dataContext) {
3125
+ validate(_schema, data, _2, dataContext) {
2910
3126
  const locationIdInput = data;
2911
3127
  const locations = dataContext?.rootData.$leafAdminStructureLocationIds ?? [];
2912
3128
  return locations.some((location) => location.id === locationIdInput);
2913
3129
  }
2914
3130
  });
3131
+ ajv.addKeyword({
3132
+ keyword: "customClientValidator",
3133
+ schemaType: "object",
3134
+ errors: true,
3135
+ // @ts-expect-error -- AJV's public types don't expose `rootData`. All
3136
+ // `validate()` callers build root data via `buildClientFunctionContext`,
3137
+ // so the cast holds.
3138
+ validate(schema, data, _2, dataContext) {
3139
+ return Boolean(
3140
+ runClientFunction(
3141
+ schema.code,
3142
+ data,
3143
+ dataContext?.rootData ?? buildClientFunctionContext({ form: {} })
3144
+ )
3145
+ );
3146
+ }
3147
+ });
3148
+ function isOnline() {
3149
+ if (typeof window !== "undefined" && typeof navigator !== "undefined") {
3150
+ return navigator.onLine;
3151
+ }
3152
+ return true;
3153
+ }
2915
3154
 
2916
3155
  // ../commons/src/utils.ts
2917
3156
  var z32 = __toESM(require("zod/v4"));
@@ -3530,7 +3769,54 @@ function createFieldConditionals(fieldId) {
3530
3769
  }
3531
3770
  },
3532
3771
  required: [fieldId]
3533
- })
3772
+ }),
3773
+ /**
3774
+ * Custom client-side validator. The provided function is serialised and executed
3775
+ * just-in-time on the client only. External references (e.g. lodash) are not
3776
+ * available inside the function body — all logic must be self-contained.
3777
+ *
3778
+ * @example
3779
+ * field('nid').customClientValidator((value) => {
3780
+ * // LUHN check — all logic must be inline
3781
+ * const digits = String(value).split('').map(Number)
3782
+ * // ...
3783
+ * return isValid
3784
+ * })
3785
+ */
3786
+ customClientValidator(validationFn) {
3787
+ const code = validationFn.toString();
3788
+ return defineFormConditional({
3789
+ type: "object",
3790
+ properties: wrapToPath(
3791
+ { [fieldId]: { customClientValidator: { code } } },
3792
+ this.$$subfield
3793
+ ),
3794
+ required: [fieldId]
3795
+ });
3796
+ },
3797
+ /**
3798
+ * Custom client-side evaluation. Returns a {@link FieldReference} descriptor
3799
+ * that can be used as the `value` property or a DATA component entry.
3800
+ * The function receives the referenced field's value as the first argument and
3801
+ * the full form context as the second; its return value replaces the field reference.
3802
+ * The function is serialised and executed just-in-time on the client only.
3803
+ * External references (e.g. lodash) are not available inside the function body.
3804
+ *
3805
+ * For computing a default value without referencing a specific field, use
3806
+ * `evaluate(fn)` in the `defaultValue` property instead.
3807
+ *
3808
+ * @example
3809
+ * field('a').customClientEvaluation((aValue, ctx) =>
3810
+ * Number(aValue) + Number(ctx.$form.b)
3811
+ * )
3812
+ */
3813
+ customClientEvaluation(computationFn) {
3814
+ return {
3815
+ $$code: computationFn.toString(),
3816
+ $$field: fieldId,
3817
+ $$subfield: this.$$subfield
3818
+ };
3819
+ }
3534
3820
  };
3535
3821
  }
3536
3822
 
@@ -3703,8 +3989,9 @@ var EventConfig = _EventConfigBase.superRefine((event2, ctx) => {
3703
3989
  validateActionFlags(event2, ctx);
3704
3990
  validateActionOrder(event2, ctx);
3705
3991
  }).meta({
3706
- id: "EventConfig"
3707
- }).describe("Configuration defining an event type.");
3992
+ id: "EventConfig",
3993
+ description: "Configuration defining an event type registered in OpenCRVS (for example birth or death)."
3994
+ });
3708
3995
 
3709
3996
  // ../commons/src/events/EventConfigInput.ts
3710
3997
  var defineDeclarationForm = (form) => DeclarationFormConfig.parse(form);
@@ -3926,6 +4213,9 @@ var WorkqueueColumnValue = z34.object({
3926
4213
  var WorkqueueColumn = z34.object({
3927
4214
  label: TranslationConfig,
3928
4215
  value: WorkqueueColumnValue
4216
+ }).meta({
4217
+ id: "WorkqueueColumn",
4218
+ description: "Configuration for a single workqueue column. The value references an event metadata key (e.g. `dateOfEvent`, `status`, `trackingId`)."
3929
4219
  });
3930
4220
  function defineWorkqueuesColumns(workqueueColumns) {
3931
4221
  return workqueueColumns.map(
@@ -4131,8 +4421,8 @@ var WorkqueueConfigWithoutQuery = WorkqueueConfig.omit({
4131
4421
  var WorkqueueConfigInput = WorkqueueConfig.extend({
4132
4422
  query: CountryConfigQueryInputType
4133
4423
  }).meta({
4134
- description: "Workqueue configuration",
4135
- id: "WorkqueueConfig"
4424
+ id: "WorkqueueConfig",
4425
+ description: "Configuration for a single workqueue. Defines the filter applied to the event index, the quick-action button, the columns shown on each row, and the message rendered when the queue is empty."
4136
4426
  });
4137
4427
  var WorkqueueCountInput = z37.array(
4138
4428
  z37.object({ slug: z37.string(), query: QueryType })
@@ -4174,7 +4464,9 @@ var BaseActionInput = z38.object({
4174
4464
  keepAssignment: z38.boolean().optional(),
4175
4465
  keepAssignmentIfAccepted: z38.boolean().optional(),
4176
4466
  keepAssignmentIfRejected: z38.boolean().optional(),
4177
- waitFor: z38.boolean().optional(),
4467
+ waitFor: z38.boolean().default(true).describe(
4468
+ "Whether action waits for the indexing before returning. Defaults to true. Setting this to to false completes faster but might lead to stale data in the client if the client tries to read the event immediately after performing the action. Use with care."
4469
+ ),
4178
4470
  // For normal users, the createdAtLocation is resolved on the backend from the user's primaryOfficeId.
4179
4471
  // @TODO: createdAtLocation should be limited to actions that system users can perform. For normal users, it should not be part of the base action.
4180
4472
  createdAtLocation: UUID.nullish().describe(
@@ -4292,7 +4584,8 @@ var RejectCorrectionActionInput = BaseActionInput.extend(
4292
4584
  var ApproveCorrectionActionInput = BaseActionInput.extend(
4293
4585
  z38.object({
4294
4586
  requestId: z38.string(),
4295
- type: z38.literal(ActionType.APPROVE_CORRECTION).default(ActionType.APPROVE_CORRECTION)
4587
+ type: z38.literal(ActionType.APPROVE_CORRECTION).default(ActionType.APPROVE_CORRECTION),
4588
+ content: z38.object({ immediateCorrection: z38.boolean().optional() }).optional()
4296
4589
  }).shape
4297
4590
  );
4298
4591
  var ReadActionInput = BaseActionInput.extend(
@@ -4354,7 +4647,7 @@ var Draft = z39.object({
4354
4647
  }).describe(
4355
4648
  "A temporary storage for an action. Stored with details of the event, creator and creation time."
4356
4649
  );
4357
- var DraftInput = BaseActionInput.extend({
4650
+ var DraftInput = BaseActionInput.omit({ waitFor: true }).extend({
4358
4651
  type: ActionTypes.exclude([ActionTypes.enum.DELETE]),
4359
4652
  status: z39.enum([
4360
4653
  ActionStatus.Requested,
@@ -6952,6 +7245,369 @@ var ACTION_FILTERS = {
6952
7245
  // ../commons/src/events/FileUtils.ts
6953
7246
  var import_lodash7 = require("lodash");
6954
7247
 
7248
+ // ../commons/src/events/mocks.test.utils.ts
7249
+ var V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS = [
7250
+ {
7251
+ id: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7252
+ name: "Central",
7253
+ parentId: null,
7254
+ validUntil: null,
7255
+ externalId: "ydyJb1RAy4U1"
7256
+ },
7257
+ {
7258
+ id: "c599b691-fd2d-45e1-abf4-d185de727fb5",
7259
+ name: "Sulaka",
7260
+ parentId: null,
7261
+ validUntil: null,
7262
+ externalId: "pQ8nGxWmZ2Q3"
7263
+ },
7264
+ {
7265
+ id: "7ef2b9c7-5e6d-49f6-ae05-656207d0fc64",
7266
+ name: "Pualula",
7267
+ parentId: null,
7268
+ validUntil: null,
7269
+ externalId: "Aq91DweLmT8k"
7270
+ },
7271
+ {
7272
+ id: "6d1a59df-988c-4021-a846-ccbc021931a7",
7273
+ name: "Chuminga",
7274
+ parentId: null,
7275
+ validUntil: null,
7276
+ externalId: "Rw0fYNh2Xk9a"
7277
+ },
7278
+ {
7279
+ id: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7280
+ name: "Ibombo",
7281
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7282
+ validUntil: null,
7283
+ externalId: "k7DsP4vbN1Qe"
7284
+ },
7285
+ {
7286
+ id: "27160bbd-32d1-4625-812f-860226bfb92a",
7287
+ name: "Isango",
7288
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7289
+ validUntil: null,
7290
+ externalId: "Gm3Z9eQpHw4L"
7291
+ },
7292
+ {
7293
+ id: "967032fd-3f81-478a-826c-30cb8fe121bd",
7294
+ name: "Isamba",
7295
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7296
+ validUntil: null,
7297
+ externalId: "sT0xVu1KqJ7r"
7298
+ },
7299
+ {
7300
+ id: "89a33893-b17d-481d-a26d-6461e7ac1651",
7301
+ name: "Itambo",
7302
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7303
+ validUntil: null,
7304
+ externalId: "Nq6Bv2HpL9Te"
7305
+ },
7306
+ {
7307
+ id: "d42ab2fe-e7ed-470e-8b31-4fb27f9b8250",
7308
+ name: "Ezhi",
7309
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7310
+ validUntil: null,
7311
+ externalId: "xK8cQ0ZRy5Wd"
7312
+ },
7313
+ {
7314
+ id: "8fbd09d2-212b-47f4-beb3-5e1694931d9f",
7315
+ name: "Ilanga",
7316
+ parentId: "c599b691-fd2d-45e1-abf4-d185de727fb5",
7317
+ validUntil: null,
7318
+ externalId: "Cq4Jm1XvN8Ls"
7319
+ },
7320
+ // Villages under Ibombo (62a0ccb4-880d-4f30-8882-f256007dfff9)
7321
+ {
7322
+ id: "1d4e5f6a-7b8c-4912-8efa-345678901234",
7323
+ name: "Klow",
7324
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7325
+ validUntil: null,
7326
+ externalId: "IkYcYBUcyY2"
7327
+ },
7328
+ {
7329
+ id: "2e5f6a7b-8c9d-4a23-8fab-456789012345",
7330
+ name: "Mbondo",
7331
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7332
+ validUntil: null,
7333
+ externalId: "Qhvv5hvo3mY"
7334
+ },
7335
+ {
7336
+ id: "3f6a7b8c-9d0e-4b34-8abc-567890123456",
7337
+ name: "Ndara",
7338
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7339
+ validUntil: null,
7340
+ externalId: "crXh068O9TR"
7341
+ },
7342
+ {
7343
+ id: "4a7b8c9d-0e1f-4c45-abcd-678901234567",
7344
+ name: "Olani",
7345
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7346
+ validUntil: null,
7347
+ externalId: "r00It8Tvvp7"
7348
+ },
7349
+ {
7350
+ id: "5b8c9d0e-1f2a-4d56-bcde-789012345678",
7351
+ name: "Pemba",
7352
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7353
+ validUntil: null,
7354
+ externalId: "ZnUWsbONIaH"
7355
+ },
7356
+ {
7357
+ id: "6c9d0e1f-2a3b-4e67-8def-890123456789",
7358
+ name: "Quanza",
7359
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7360
+ validUntil: null,
7361
+ externalId: "fDZycvQTa7l"
7362
+ },
7363
+ {
7364
+ id: "7d0e1f2a-3b4c-4f78-8efa-901234567890",
7365
+ name: "Rivka",
7366
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7367
+ validUntil: null,
7368
+ externalId: "KqswxCGTELa"
7369
+ },
7370
+ // Villages under Isamba (967032fd-3f81-478a-826c-30cb8fe121bd)
7371
+ {
7372
+ id: "8e1f2a3b-4c5d-4089-8fab-012345678901",
7373
+ name: "Mbula",
7374
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
7375
+ validUntil: null,
7376
+ externalId: "osEbKjRc9Kg"
7377
+ },
7378
+ {
7379
+ id: "9f2a3b4c-5d6e-4190-8abf-123456789012",
7380
+ name: "Ndoki",
7381
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
7382
+ validUntil: null,
7383
+ externalId: "aq4daBUAGr3"
7384
+ },
7385
+ {
7386
+ id: "0a3b4c5d-6e7f-4201-abcd-234567890123",
7387
+ name: "Tsanga",
7388
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
7389
+ validUntil: null,
7390
+ externalId: "cqis6Y8trbJ"
7391
+ },
7392
+ {
7393
+ id: "1b4c5d6e-7f8a-4312-bcde-345678901234",
7394
+ name: "Waziri",
7395
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
7396
+ validUntil: null,
7397
+ externalId: "LMijHPyyx6d"
7398
+ },
7399
+ {
7400
+ id: "2c5d6e7f-8a9b-4423-8def-456789012345",
7401
+ name: "Zimbi",
7402
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
7403
+ validUntil: null,
7404
+ externalId: "pcQYbPuKGZ7"
7405
+ },
7406
+ // Villages under Itambo (89a33893-b17d-481d-a26d-6461e7ac1651)
7407
+ {
7408
+ id: "3d6e7f8a-9b0c-4534-8efa-567890123456",
7409
+ name: "Felani",
7410
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
7411
+ validUntil: null,
7412
+ externalId: "gSqpoCGdMXp"
7413
+ },
7414
+ {
7415
+ id: "4e7f8a9b-0c1d-4645-8fab-678901234567",
7416
+ name: "Goroma",
7417
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
7418
+ validUntil: null,
7419
+ externalId: "KvAAIaNqVrp"
7420
+ },
7421
+ {
7422
+ id: "5f8a9b0c-1d2e-4756-8abc-789012345678",
7423
+ name: "Halifu",
7424
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
7425
+ validUntil: null,
7426
+ externalId: "qe4UnEVt1hv"
7427
+ },
7428
+ {
7429
+ id: "6a9b0c1d-2e3f-4867-abcd-890123456789",
7430
+ name: "Jabari",
7431
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
7432
+ validUntil: null,
7433
+ externalId: "yHH9Nz4rLOt"
7434
+ },
7435
+ {
7436
+ id: "7b0c1d2e-3f4a-4978-bcde-901234567890",
7437
+ name: "Kifani",
7438
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
7439
+ validUntil: null,
7440
+ externalId: "eSWmXIGeu1I"
7441
+ },
7442
+ {
7443
+ id: "8c1d2e3f-4a5b-4089-8def-012345678901",
7444
+ name: "Lumela",
7445
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
7446
+ validUntil: null,
7447
+ externalId: "bh0b3aI1uP3"
7448
+ }
7449
+ ];
7450
+ var V2_DEFAULT_MOCK_LOCATIONS = [
7451
+ {
7452
+ id: "6f6186ce-cd5f-4a5f-810a-2d99e7c4ba12",
7453
+ name: "Central Provincial Office",
7454
+ locationType: "CRVS_OFFICE",
7455
+ administrativeAreaId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7456
+ validUntil: null,
7457
+ externalId: "Xr3Df8WpK6Ys"
7458
+ },
7459
+ {
7460
+ id: "b1c2d3e4-f5a6-7890-bcde-f12345678901",
7461
+ name: "Central Health Post",
7462
+ locationType: "HEALTH_FACILITY",
7463
+ administrativeAreaId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
7464
+ validUntil: null
7465
+ },
7466
+ {
7467
+ id: "028d2c85-ca31-426d-b5d1-2cef545a4902",
7468
+ name: "Ibombo District Office",
7469
+ locationType: "CRVS_OFFICE",
7470
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7471
+ validUntil: null,
7472
+ externalId: "Sm4Nw7GrD2Vy"
7473
+ },
7474
+ {
7475
+ id: "62a0ccb4-4f30-4f30-8882-f256007dff9f",
7476
+ name: "Isamba District Office",
7477
+ locationType: "CRVS_OFFICE",
7478
+ administrativeAreaId: "967032fd-3f81-478a-826c-30cb8fe121bd",
7479
+ validUntil: null,
7480
+ externalId: "Vg1Bq5XeH9Lt"
7481
+ },
7482
+ {
7483
+ id: "954c93e1-13f7-4435-bb82-35e0e215e07d",
7484
+ name: "Isango District Office",
7485
+ locationType: "CRVS_OFFICE",
7486
+ administrativeAreaId: "27160bbd-32d1-4625-812f-860226bfb92a",
7487
+ validUntil: null,
7488
+ externalId: "Je7Lm2XqN9Vz"
7489
+ },
7490
+ {
7491
+ id: "2884f5b9-17b4-49ce-bf4d-f538228935df",
7492
+ name: "Sulaka Provincial Office",
7493
+ locationType: "CRVS_OFFICE",
7494
+ administrativeAreaId: "c599b691-fd2d-45e1-abf4-d185de727fb5",
7495
+ validUntil: null,
7496
+ externalId: "Ht2Wp9KcX5Qv"
7497
+ },
7498
+ {
7499
+ id: "030358c6-54af-44be-821b-8e4af963a49c",
7500
+ name: "Ilanga District Office",
7501
+ locationType: "CRVS_OFFICE",
7502
+ administrativeAreaId: "8fbd09d2-212b-47f4-beb3-5e1694931d9f",
7503
+ validUntil: null,
7504
+ externalId: "Yp6Ds1WqN3Xz"
7505
+ },
7506
+ {
7507
+ id: "423d000f-101b-47c0-8b86-21a908067cee",
7508
+ name: "Chamakubi Health Post",
7509
+ locationType: "HEALTH_FACILITY",
7510
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7511
+ validUntil: null,
7512
+ externalId: "M1nFr8LbC2Qy"
7513
+ },
7514
+ {
7515
+ id: "4d3279be-d026-420c-88f7-f0a4ae986973",
7516
+ name: "Ibombo Rural Health Centre",
7517
+ locationType: "HEALTH_FACILITY",
7518
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7519
+ validUntil: null,
7520
+ externalId: "bT7pV6YrW0Xc"
7521
+ },
7522
+ {
7523
+ id: "190902f4-1d77-476a-8947-41145af1db7d",
7524
+ name: "Chikobo Rural Health Centre",
7525
+ locationType: "HEALTH_FACILITY",
7526
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7527
+ validUntil: null,
7528
+ externalId: "zE4qPn2SgJ5d"
7529
+ },
7530
+ {
7531
+ id: "f5ecbd9b-a01e-4a65-910e-70e86ab41b71",
7532
+ name: "Chilochabalenje Health Post",
7533
+ locationType: "HEALTH_FACILITY",
7534
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7535
+ validUntil: null,
7536
+ externalId: "H8vDs1MqR4Uf"
7537
+ },
7538
+ {
7539
+ id: "dbfc178f-7295-4b90-b28d-111c95b03127",
7540
+ name: "Chipeso Rural Health Centre",
7541
+ locationType: "HEALTH_FACILITY",
7542
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7543
+ validUntil: null,
7544
+ externalId: "Qw3uZ9KfX6Lm"
7545
+ },
7546
+ {
7547
+ id: "09862bfe-c7ac-46cd-987b-668681533c80",
7548
+ name: "Chisamba Rural Health Centre",
7549
+ locationType: "HEALTH_FACILITY",
7550
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7551
+ validUntil: null,
7552
+ externalId: "Yr0pCg8LdM2s"
7553
+ },
7554
+ {
7555
+ id: "834ce389-e95b-4fb0-96a0-33e9ab323059",
7556
+ name: "Chitanda Rural Health Centre",
7557
+ locationType: "HEALTH_FACILITY",
7558
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7559
+ validUntil: null,
7560
+ externalId: "tS9gJ4PwB1Qx"
7561
+ },
7562
+ {
7563
+ id: "0431c433-6062-4a4c-aee9-25271aec61ee",
7564
+ name: "Golden Valley Rural Health Centre",
7565
+ locationType: "HEALTH_FACILITY",
7566
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7567
+ validUntil: null,
7568
+ externalId: "Ld7Qm3XsA8Vr"
7569
+ },
7570
+ {
7571
+ id: "bc84d0b6-7ba7-480d-a339-5d9920d90eb2",
7572
+ name: "Ipongo Rural Health Centre",
7573
+ locationType: "HEALTH_FACILITY",
7574
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7575
+ validUntil: null,
7576
+ externalId: "kF2sW9DmH0Bt"
7577
+ },
7578
+ {
7579
+ id: "4cf1f53b-b730-41d2-8649-dff7eeed970d",
7580
+ name: "Itumbwe Health Post",
7581
+ locationType: "HEALTH_FACILITY",
7582
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7583
+ validUntil: null,
7584
+ externalId: "Ue5Xb3VaC7Pq"
7585
+ },
7586
+ {
7587
+ id: "4b3676cb-9355-4942-9eb9-2ce46acaf0e0",
7588
+ name: "Kabangalala Rural Health Centre",
7589
+ locationType: "HEALTH_FACILITY",
7590
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
7591
+ validUntil: null,
7592
+ externalId: "Pz8Kc1TqH6Jn"
7593
+ },
7594
+ // Village offices
7595
+ {
7596
+ id: "1f4a5b6c-7d8e-4312-8abc-345678901234",
7597
+ name: "Klow Village Office",
7598
+ locationType: "CRVS_OFFICE",
7599
+ administrativeAreaId: "1d4e5f6a-7b8c-4912-8efa-345678901234",
7600
+ validUntil: null,
7601
+ externalId: "PmAyxAJkxiJ"
7602
+ }
7603
+ ];
7604
+ var V2_DEFAULT_MOCK_LOCATIONS_MAP = new Map(
7605
+ V2_DEFAULT_MOCK_LOCATIONS.map((l) => [l.id, l])
7606
+ );
7607
+ var V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS_MAP = new Map(
7608
+ V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS.map((a) => [a.id, a])
7609
+ );
7610
+
6955
7611
  // ../commons/src/notification/UserNotifications.ts
6956
7612
  var z44 = __toESM(require("zod/v4"));
6957
7613
  var TriggerEvent = {