@opencrvs/toolkit 2.0.0-rc.fef9d21 → 2.0.0-rc.ff99998

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 (59) hide show
  1. package/create-countryconfig/index.js +103 -0
  2. package/create-countryconfig/package.json +21 -0
  3. package/dist/application-config/index.js +305 -129
  4. package/dist/cli.js +548 -178
  5. package/dist/commons/api/router.d.ts +3379 -239
  6. package/dist/commons/application-config/index.d.ts +17 -4
  7. package/dist/commons/conditionals/conditionals.d.ts +360 -10
  8. package/dist/commons/conditionals/validate.d.ts +52 -2
  9. package/dist/commons/events/ActionDocument.d.ts +6 -0
  10. package/dist/commons/events/ActionInput.d.ts +114 -0
  11. package/dist/commons/events/AdvancedSearchConfig.d.ts +342 -0
  12. package/dist/commons/events/Draft.d.ts +4 -2
  13. package/dist/commons/events/EventDocument.d.ts +3 -0
  14. package/dist/commons/events/EventIndex.d.ts +0 -3
  15. package/dist/commons/events/EventMetadata.d.ts +0 -7
  16. package/dist/commons/events/FieldConfig.d.ts +387 -50
  17. package/dist/commons/events/FieldValue.d.ts +6 -0
  18. package/dist/commons/events/WorkqueueConfig.d.ts +150 -150
  19. package/dist/commons/events/field.d.ts +53 -1
  20. package/dist/commons/events/index.d.ts +2 -0
  21. package/dist/commons/events/locations.d.ts +38 -1
  22. package/dist/commons/events/mocks.test.utils.d.ts +19 -0
  23. package/dist/commons/events/scopes.d.ts +24 -1
  24. package/dist/commons/events/state/flags.d.ts +16 -0
  25. package/dist/commons/events/state/index.d.ts +0 -4
  26. package/dist/commons/events/state/utils.d.ts +12 -289
  27. package/dist/commons/events/utils.d.ts +13 -2
  28. package/dist/conditionals/index.js +92 -9
  29. package/dist/events/index.js +1084 -261
  30. package/dist/migrations/v2.0/add-birth-certificate-issuance-flag.d.ts.map +1 -1
  31. package/dist/migrations/v2.0/add-birth-certificate-issuance-flag.js +60 -35
  32. package/dist/migrations/v2.0/checkout-upstream-files.d.ts +1 -1
  33. package/dist/migrations/v2.0/checkout-upstream-files.d.ts.map +1 -1
  34. package/dist/migrations/v2.0/checkout-upstream-files.js +1 -2
  35. package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts +9 -1
  36. package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts.map +1 -1
  37. package/dist/migrations/v2.0/delete-infrastructure-directory.js +66 -20
  38. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.d.ts +3 -0
  39. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.d.ts.map +1 -0
  40. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.js +110 -0
  41. package/dist/migrations/v2.0/index.d.ts +5 -3
  42. package/dist/migrations/v2.0/index.d.ts.map +1 -1
  43. package/dist/migrations/v2.0/index.js +546 -176
  44. package/dist/migrations/v2.0/make-built-in-validate-actions-custom.d.ts.map +1 -1
  45. package/dist/migrations/v2.0/make-built-in-validate-actions-custom.js +90 -1
  46. package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts +11 -1
  47. package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts.map +1 -1
  48. package/dist/migrations/v2.0/merge-infrastructure-directory.js +17 -16
  49. package/dist/migrations/v2.0/migrate-scopes.d.ts.map +1 -1
  50. package/dist/migrations/v2.0/migrate-scopes.js +54 -30
  51. package/dist/migrations/v2.0/migrate-workqueue-configs.d.ts.map +1 -1
  52. package/dist/migrations/v2.0/migrate-workqueue-configs.js +140 -59
  53. package/dist/notification/index.js +841 -160
  54. package/dist/scopes/index.d.ts +91 -16
  55. package/dist/scopes/index.js +55 -12
  56. package/opencrvs-toolkit-2.0.0-rc.ff99998.tgz +0 -0
  57. package/package.json +6 -2
  58. package/tsconfig.tsbuildinfo +1 -1
  59. package/opencrvs-toolkit-2.0.0-rc.fef9d21.tgz +0 -0
@@ -75,6 +75,7 @@ __export(events_exports, {
75
75
  CheckboxFieldValue: () => CheckboxFieldValue,
76
76
  Clause: () => Clause,
77
77
  ClientSpecificAction: () => ClientSpecificAction,
78
+ ComputedDefaultValue: () => ComputedDefaultValue,
78
79
  Conditional: () => Conditional,
79
80
  ConditionalType: () => ConditionalType,
80
81
  ConfirmableActions: () => ConfirmableActions,
@@ -200,6 +201,7 @@ __export(events_exports, {
200
201
  SelectDateRangeValue: () => SelectDateRangeValue,
201
202
  SelectOption: () => SelectOption,
202
203
  ShowConditional: () => ShowConditional,
204
+ SignatureFieldValue: () => SignatureFieldValue,
203
205
  StaticDataEntry: () => StaticDataEntry,
204
206
  StreetLevelDetailsUpdateValue: () => StreetLevelDetailsUpdateValue,
205
207
  SummaryConfig: () => SummaryConfig,
@@ -213,6 +215,10 @@ __export(events_exports, {
213
215
  UUID: () => UUID,
214
216
  UnassignActionInput: () => UnassignActionInput,
215
217
  UserAuditRecordInput: () => UserAuditRecordInput,
218
+ V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS: () => V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS,
219
+ V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS_MAP: () => V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS_MAP,
220
+ V2_DEFAULT_MOCK_LOCATIONS: () => V2_DEFAULT_MOCK_LOCATIONS,
221
+ V2_DEFAULT_MOCK_LOCATIONS_MAP: () => V2_DEFAULT_MOCK_LOCATIONS_MAP,
216
222
  ValidationConfig: () => ValidationConfig,
217
223
  VerificationActionConfig: () => VerificationActionConfig,
218
224
  VerificationPageConfig: () => VerificationPageConfig,
@@ -234,6 +240,7 @@ __export(events_exports, {
234
240
  ageToDate: () => ageToDate,
235
241
  aggregateActionAnnotations: () => aggregateActionAnnotations,
236
242
  aggregateActionDeclarations: () => aggregateActionDeclarations,
243
+ always: () => always,
237
244
  alwaysTrue: () => alwaysTrue,
238
245
  and: () => and,
239
246
  annotationActions: () => annotationActions,
@@ -241,8 +248,12 @@ __export(events_exports, {
241
248
  applyDraftToEventIndex: () => applyDraftToEventIndex,
242
249
  areCertificateConditionsMet: () => areCertificateConditionsMet,
243
250
  areConditionsMet: () => areConditionsMet,
251
+ buildClientFunctionContext: () => buildClientFunctionContext,
244
252
  buildFormState: () => buildFormState,
245
253
  canAccessEventWithScope: () => canAccessEventWithScope,
254
+ canAccessOtherUserWithScopes: () => canAccessOtherUserWithScopes,
255
+ canAccessUserWithScope: () => canAccessUserWithScope,
256
+ compileClientFunction: () => compileClientFunction,
246
257
  compositeFieldTypes: () => compositeFieldTypes,
247
258
  createEmptyDraft: () => createEmptyDraft,
248
259
  createFieldConditionals: () => createFieldConditionals,
@@ -263,6 +274,7 @@ __export(events_exports, {
263
274
  defineWorkqueuesColumns: () => defineWorkqueuesColumns,
264
275
  deserializeQuery: () => deserializeQuery,
265
276
  errorMessages: () => errorMessages,
277
+ evaluate: () => evaluate,
266
278
  event: () => event,
267
279
  eventMetadataLabelMap: () => eventMetadataLabelMap,
268
280
  eventPayloadGenerator: () => eventPayloadGenerator,
@@ -275,6 +287,7 @@ __export(events_exports, {
275
287
  findActiveDraftForEvent: () => findActiveDraftForEvent,
276
288
  findAllFields: () => findAllFields,
277
289
  findLastAssignmentAction: () => findLastAssignmentAction,
290
+ findPendingCorrectionAction: () => findPendingCorrectionAction,
278
291
  findRecordActionPages: () => findRecordActionPages,
279
292
  flag: () => flag,
280
293
  flattenFieldReference: () => flattenFieldReference,
@@ -300,13 +313,15 @@ __export(events_exports, {
300
313
  getActionConfig: () => getActionConfig,
301
314
  getActionReview: () => getActionReview,
302
315
  getActionReviewFields: () => getActionReviewFields,
316
+ getAdministrativeAreaHierarchy: () => getAdministrativeAreaHierarchy,
303
317
  getAllUniqueFields: () => getAllUniqueFields,
304
318
  getAnnotationFromDrafts: () => getAnnotationFromDrafts,
305
319
  getAssignedUserFromActions: () => getAssignedUserFromActions,
306
- getAssignedUserSignatureFromActions: () => getAssignedUserSignatureFromActions,
307
320
  getAssignmentStatus: () => getAssignmentStatus,
308
321
  getAvailableActionsForEvent: () => getAvailableActionsForEvent,
322
+ getAvailableRolesForUserUpdatePayload: () => getAvailableRolesForUserUpdatePayload,
309
323
  getCompleteActionAnnotation: () => getCompleteActionAnnotation,
324
+ getCompleteActionContent: () => getCompleteActionContent,
310
325
  getCompleteActionDeclaration: () => getCompleteActionDeclaration,
311
326
  getCurrentEventState: () => getCurrentEventState,
312
327
  getCustomActionFields: () => getCustomActionFields,
@@ -315,7 +330,9 @@ __export(events_exports, {
315
330
  getDeclarationFields: () => getDeclarationFields,
316
331
  getDeclarationPages: () => getDeclarationPages,
317
332
  getEventConfigById: () => getEventConfigById,
333
+ getEventFlags: () => getEventFlags,
318
334
  getFilePathsFromEvent: () => getFilePathsFromEvent,
335
+ getLocationHierarchy: () => getLocationHierarchy,
319
336
  getMixedPath: () => getMixedPath,
320
337
  getPendingAction: () => getPendingAction,
321
338
  getPrintCertificatePages: () => getPrintCertificatePages,
@@ -336,6 +353,7 @@ __export(events_exports, {
336
353
  isBulletListFieldType: () => isBulletListFieldType,
337
354
  isButtonFieldType: () => isButtonFieldType,
338
355
  isCheckboxFieldType: () => isCheckboxFieldType,
356
+ isCodeToEvaluate: () => isCodeToEvaluate,
339
357
  isConditionMet: () => isConditionMet,
340
358
  isCountryFieldType: () => isCountryFieldType,
341
359
  isCustomFieldType: () => isCustomFieldType,
@@ -376,6 +394,7 @@ __export(events_exports, {
376
394
  isPageVisible: () => isPageVisible,
377
395
  isParagraphFieldType: () => isParagraphFieldType,
378
396
  isPhoneFieldType: () => isPhoneFieldType,
397
+ isPotentialDuplicate: () => isPotentialDuplicate,
379
398
  isPrintButtonFieldType: () => isPrintButtonFieldType,
380
399
  isQrReaderFieldType: () => isQrReaderFieldType,
381
400
  isQueryParamReaderFieldType: () => isQueryParamReaderFieldType,
@@ -409,12 +428,15 @@ __export(events_exports, {
409
428
  plainDateToLocalDate: () => plainDateToLocalDate,
410
429
  precompileActionSchemas: () => precompileActionSchemas,
411
430
  resolveDateOfEvent: () => resolveDateOfEvent,
431
+ resolveEventCustomFlags: () => resolveEventCustomFlags,
412
432
  resolvePlaceOfEvent: () => resolvePlaceOfEvent,
433
+ runClientFunction: () => runClientFunction,
413
434
  runFieldValidations: () => runFieldValidations,
414
435
  runStructuralValidations: () => runStructuralValidations,
415
436
  safeUnion: () => safeUnion,
416
437
  status: () => status,
417
438
  timePeriodToDateRange: () => timePeriodToDateRange,
439
+ todayISO: () => todayISO,
418
440
  user: () => user,
419
441
  userCanAccessEventWithScopes: () => userCanAccessEventWithScopes,
420
442
  validate: () => validate,
@@ -489,6 +511,10 @@ var scopeByEvent = z2.preprocess(
489
511
  (val) => val === void 0 ? void 0 : [val].flat(),
490
512
  z2.array(z2.string()).optional()
491
513
  ).describe("Event type, e.g. birth, death");
514
+ var userRole = z2.preprocess(
515
+ (val) => val === void 0 ? void 0 : [val].flat(),
516
+ z2.array(z2.string()).optional()
517
+ ).describe("User role, e.g. admin, field agent");
492
518
  var scopeOptionsPlaceEvent = z2.object({
493
519
  event: scopeByEvent,
494
520
  placeOfEvent: JurisdictionFilter.optional()
@@ -512,6 +538,9 @@ var CustomActionScopeOptions = AllRecordScopeOptions.extend({
512
538
  var AccessLevelOptions = z2.object({
513
539
  accessLevel: JurisdictionFilter.optional()
514
540
  });
541
+ var AllUserScopeOptions = AccessLevelOptions.extend({
542
+ role: userRole.optional()
543
+ });
515
544
  var WorkqueueOrDashboardOptions = z2.object({
516
545
  ids: z2.preprocess(
517
546
  (val) => val === void 0 ? void 0 : [val].flat(),
@@ -521,6 +550,7 @@ var WorkqueueOrDashboardOptions = z2.object({
521
550
  var AllScopeOptions = z2.object({
522
551
  ...AllRecordScopeOptions.shape,
523
552
  ...AccessLevelOptions.shape,
553
+ ...AllUserScopeOptions.shape,
524
554
  ...WorkqueueOrDashboardOptions.shape
525
555
  });
526
556
  var ScopeOptionKey = AllScopeOptions.keyof();
@@ -593,6 +623,33 @@ var RecordScopeV2 = z2.discriminatedUnion("type", [
593
623
  ]).describe(
594
624
  "Scopes used to check user's permission to perform actions on a record."
595
625
  );
626
+ var SystemScopeType = z2.enum([
627
+ "organisation.read-locations",
628
+ "user.read",
629
+ "user.create",
630
+ "user.edit",
631
+ "user.search"
632
+ ]);
633
+ var UserScopeType = SystemScopeType.extract([
634
+ "user.read",
635
+ "user.create",
636
+ "user.edit",
637
+ "user.search"
638
+ ]);
639
+ var ScopesWithRoleOption = UserScopeType.extract(["user.edit", "user.create"]);
640
+ var UserScopeV2 = z2.discriminatedUnion("type", [
641
+ z2.object({
642
+ type: ScopesWithRoleOption,
643
+ options: AllUserScopeOptions.optional()
644
+ }),
645
+ z2.object({
646
+ type: UserScopeType.extract(["user.read", "user.search"]),
647
+ options: AccessLevelOptions.optional()
648
+ })
649
+ ]);
650
+ function scopeUsesRoleOptions(scope) {
651
+ return ScopesWithRoleOption?.options.some((opt) => opt === scope.type);
652
+ }
596
653
  function scopeUsesDeclaredOptions(scope) {
597
654
  return !ScopesWithPlaceEventOptions.options.some((opt) => opt === scope.type);
598
655
  }
@@ -625,16 +682,14 @@ var ResolvedRecordScopeV2 = z2.discriminatedUnion("type", [
625
682
  }).optional()
626
683
  })
627
684
  ]).describe("Resolved scope with location/user IDs instead of filters.");
628
- var SystemScopeType = z2.enum([
629
- "organisation.read-locations",
630
- "user.read",
631
- "user.create",
632
- "user.edit"
633
- ]);
634
685
  var Scope = z2.discriminatedUnion("type", [
635
686
  z2.object({ type: PlainScopeType }),
636
687
  ...RecordScopeV2.options,
637
- z2.object({ type: SystemScopeType, options: AccessLevelOptions.optional() }),
688
+ ...UserScopeV2.options,
689
+ z2.object({
690
+ type: z2.literal("organisation.read-locations"),
691
+ options: AccessLevelOptions.optional()
692
+ }),
638
693
  z2.object({
639
694
  type: z2.literal("workqueue"),
640
695
  options: WorkqueueOrDashboardOptions
@@ -656,18 +711,26 @@ var unflattenScope = (input) => {
656
711
  return { type, options };
657
712
  };
658
713
  var EncodedScope = z2.string().brand("EncodedScope");
659
- var decodeScope = (query) => {
660
- const scope = qs.parse(query, {
714
+ var decodedScopeCache = /* @__PURE__ */ new Map();
715
+ var decodeScope = (encodedScope) => {
716
+ if (decodedScopeCache.has(encodedScope)) {
717
+ return decodedScopeCache.get(encodedScope);
718
+ }
719
+ const scope = qs.parse(encodedScope, {
661
720
  ignoreQueryPrefix: true,
662
721
  comma: true,
663
722
  allowDots: true
664
723
  });
665
724
  const unflattenedScope = unflattenScope(scope);
666
- return Scope.safeParse(unflattenedScope)?.data;
725
+ const result = Scope.safeParse(unflattenedScope)?.data;
726
+ decodedScopeCache.set(encodedScope, result);
727
+ return result;
667
728
  };
668
729
  var DEFAULT_SCOPE_OPTIONS = {
669
730
  placeOfEvent: JurisdictionFilter.enum.all,
670
- accessLevel: JurisdictionFilter.enum.all
731
+ accessLevel: JurisdictionFilter.enum.all,
732
+ registeredIn: JurisdictionFilter.enum.all,
733
+ declaredIn: JurisdictionFilter.enum.all
671
734
  };
672
735
  function getAcceptedScopesByType({
673
736
  acceptedScopes,
@@ -1040,7 +1103,10 @@ var ActionConditional = z7.discriminatedUnion("type", [
1040
1103
  ShowConditional,
1041
1104
  // Action can be shown to the user in the list but as disabled
1042
1105
  EnableConditional
1043
- ]);
1106
+ ]).meta({
1107
+ id: "ActionConditional",
1108
+ 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."
1109
+ });
1044
1110
  var DisplayOnReviewConditional = z7.object({
1045
1111
  type: z7.literal(ConditionalType.DISPLAY_ON_REVIEW),
1046
1112
  conditional: Conditional
@@ -1055,8 +1121,8 @@ var FieldConditional = z7.discriminatedUnion("type", [
1055
1121
  // Field output can be shown / hidden on the review page
1056
1122
  DisplayOnReviewConditional
1057
1123
  ]).meta({
1058
- description: "Field conditional configuration",
1059
- id: "FieldConditional"
1124
+ id: "FieldConditional",
1125
+ 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."
1060
1126
  });
1061
1127
 
1062
1128
  // ../commons/src/events/FieldType.ts
@@ -1308,6 +1374,7 @@ var DateRangeFieldValue = z12.object({
1308
1374
  var EmailValue = z12.email();
1309
1375
  var CheckboxFieldValue = z12.boolean();
1310
1376
  var NumberFieldValue = z12.number();
1377
+ var SignatureFieldValue = FileFieldValue;
1311
1378
  var ButtonFieldValue = z12.number();
1312
1379
  var VerificationStatusValue = z12.enum([
1313
1380
  "verified",
@@ -1376,28 +1443,20 @@ function schemaPriority(schema) {
1376
1443
  return idx === -1 ? 9999 : idx;
1377
1444
  }
1378
1445
  function safeUnion(schemas) {
1446
+ const sortedSchemas = [...schemas].sort(
1447
+ (a, b) => schemaPriority(a) - schemaPriority(b)
1448
+ );
1379
1449
  return z12.any().superRefine((val, ctx) => {
1380
- const successful = schemas.filter((s) => s.safeParse(val).success);
1381
- if (successful.length === 1) {
1382
- return;
1383
- }
1384
- if (successful.length === 0) {
1385
- ctx.addIssue({
1386
- code: "invalid_type",
1387
- expected: "custom",
1388
- message: "Value does not match any schema"
1389
- });
1390
- return;
1391
- }
1392
- successful.sort((a, b) => schemaPriority(a) - schemaPriority(b));
1393
- const best = successful[0];
1394
- if (!best.safeParse(val).success) {
1395
- ctx.addIssue({
1396
- expected: "custom",
1397
- code: "invalid_type",
1398
- message: "Value did not match the best schema"
1399
- });
1450
+ for (const schema of sortedSchemas) {
1451
+ if (schema.safeParse(val).success) {
1452
+ return;
1453
+ }
1400
1454
  }
1455
+ ctx.addIssue({
1456
+ code: "invalid_type",
1457
+ expected: "custom",
1458
+ message: "Value does not match any schema"
1459
+ });
1401
1460
  }).meta({
1402
1461
  description: "Value that matches exactly one of the possible schema types (TextValue, DateValue, DateRangeFieldValue). The best matching schema is chosen by priority."
1403
1462
  });
@@ -1614,8 +1673,9 @@ var RequestedCorrectionAction = ActionBase.extend(
1614
1673
  var ApprovedCorrectionAction = ActionBase.extend(
1615
1674
  z14.object({
1616
1675
  type: z14.literal(ActionType.APPROVE_CORRECTION),
1617
- requestId: z14.string()
1676
+ requestId: z14.string(),
1618
1677
  // TODO move into 'content' property
1678
+ content: z14.object({ immediateCorrection: z14.boolean().optional() }).optional()
1619
1679
  }).shape
1620
1680
  );
1621
1681
  var RejectedCorrectionAction = ActionBase.extend(
@@ -1707,6 +1767,9 @@ var FlagConfig = z15.object({
1707
1767
  "Indicates if this flag expects an action to be performed to be cleared."
1708
1768
  ),
1709
1769
  label: TranslationConfig.describe("Human readable label of the flag.")
1770
+ }).meta({
1771
+ id: "FlagConfig",
1772
+ description: "Configuration for a custom flag that can be added to or removed from records by event actions."
1710
1773
  });
1711
1774
  var ActionFlagConfig = z15.object({
1712
1775
  id: Flag,
@@ -1714,6 +1777,9 @@ var ActionFlagConfig = z15.object({
1714
1777
  conditional: Conditional.optional().describe(
1715
1778
  "When conditional is met, the operation is performed on the flag. If not provided, the operation is performed unconditionally."
1716
1779
  )
1780
+ }).meta({
1781
+ id: "ActionFlagConfig",
1782
+ description: "Add or remove operation applied to a flag when the parent action is accepted. Optionally gated by a conditional."
1717
1783
  });
1718
1784
 
1719
1785
  // ../commons/src/events/EventMetadata.ts
@@ -1735,8 +1801,7 @@ var ActionCreationMetadata = z16.object({
1735
1801
  ),
1736
1802
  createdByUserType: z16.enum(["user", "system"]).nullish().describe("Whether the user is a normal user or a system."),
1737
1803
  acceptedAt: z16.iso.datetime().describe("Timestamp when the action request was accepted."),
1738
- createdByRole: z16.string().optional().describe("Role of the user at the time of action request creation."),
1739
- createdBySignature: z16.string().nullish().describe("Signature of the user who created the action request.")
1804
+ createdByRole: z16.string().optional().describe("Role of the user at the time of action request creation.")
1740
1805
  });
1741
1806
  var RegistrationCreationMetadata = ActionCreationMetadata.extend({
1742
1807
  registrationNumber: z16.string().describe(
@@ -1764,9 +1829,6 @@ var EventMetadata = z16.object({
1764
1829
  createdAtLocation: UUID.nullish().describe(
1765
1830
  "Location of the user who created the event."
1766
1831
  ),
1767
- createdBySignature: DocumentPath.nullish().describe(
1768
- "Signature of the user who created the event."
1769
- ),
1770
1832
  updatedAtLocation: UUID.nullish().describe(
1771
1833
  "Location of the user who last changed the status."
1772
1834
  ),
@@ -2141,14 +2203,34 @@ var FieldId = import_v43.default.string().superRefine((val, ctx) => {
2141
2203
  }
2142
2204
  }).describe("Unique identifier for the field");
2143
2205
  var FieldReference = import_v43.default.object({
2144
- $$field: FieldId,
2206
+ $$field: FieldId.describe("Id of the field to reference"),
2145
2207
  $$subfield: import_v43.default.array(import_v43.default.string()).optional().default([]).describe(
2146
2208
  'If the FieldValue is an object, subfield can be used to refer to e.g. `["foo", "bar"]` in `{ foo: { bar: 3 } }`'
2209
+ ),
2210
+ $$code: import_v43.default.string().optional().describe(
2211
+ "Serialised client-side function body. When present the expression is evaluated rather than dereferenced."
2147
2212
  )
2148
- }).describe("Reference to a field by its ID");
2213
+ }).describe(
2214
+ "Reference to a field value, with an optional client-side computation applied."
2215
+ );
2216
+ function isCodeToEvaluate(v) {
2217
+ return !!v && typeof v === "object" && "$$code" in v;
2218
+ }
2219
+ var ComputedDefaultValue = import_v43.default.object({
2220
+ $$code: import_v43.default.string().describe(
2221
+ "Serialised client-side function body. Receives (undefined, context) where context includes $now, $online, and system variables."
2222
+ )
2223
+ }).describe("A context-only computation used as a field default value.");
2149
2224
  var ValidationConfig = import_v43.default.object({
2150
- validator: Conditional,
2151
- message: TranslationConfig
2225
+ validator: Conditional.describe(
2226
+ "Conditional expression that must hold for the field value to be considered valid."
2227
+ ),
2228
+ message: TranslationConfig.describe(
2229
+ "Error message displayed when the validator does not hold."
2230
+ )
2231
+ }).meta({
2232
+ id: "ValidationConfig",
2233
+ 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."
2152
2234
  });
2153
2235
  var requiredSchema = import_v43.default.union([
2154
2236
  import_v43.default.boolean(),
@@ -2179,7 +2261,7 @@ var BaseField = import_v43.default.object({
2179
2261
  "Indicates whether the field can be modified during record correction."
2180
2262
  ),
2181
2263
  value: FieldReference.or(import_v43.default.array(FieldReference)).optional().describe(
2182
- "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."
2264
+ "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."
2183
2265
  ),
2184
2266
  analytics: import_v43.default.boolean().default(false).optional().describe(
2185
2267
  "Indicates whether the field is included in analytics. When enabled, its value becomes available in the analytics dashboard."
@@ -2187,30 +2269,39 @@ var BaseField = import_v43.default.object({
2187
2269
  }).describe("Common properties shared across all field types.");
2188
2270
  var Divider = BaseField.extend({
2189
2271
  type: import_v43.default.literal(FieldType.DIVIDER)
2272
+ }).meta({
2273
+ description: "A horizontal line divider",
2274
+ id: "Divider"
2190
2275
  });
2191
2276
  var TextField = BaseField.extend({
2192
2277
  type: import_v43.default.literal(FieldType.TEXT),
2193
- defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
2278
+ defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField, ComputedDefaultValue]).optional(),
2194
2279
  configuration: import_v43.default.object({
2195
2280
  maxLength: import_v43.default.number().optional().describe("Maximum length of the text"),
2196
2281
  type: import_v43.default.enum(["text", "password"]).optional(),
2197
2282
  prefix: TranslationConfig.optional(),
2198
2283
  postfix: TranslationConfig.optional()
2199
2284
  }).default({ type: "text" }).optional()
2200
- }).describe("Text input");
2285
+ }).meta({
2286
+ description: "A text input field",
2287
+ id: "TextField"
2288
+ });
2201
2289
  var NumberField = BaseField.extend({
2202
2290
  type: import_v43.default.literal(FieldType.NUMBER),
2203
- defaultValue: NumberFieldValue.optional(),
2291
+ defaultValue: NumberFieldValue.or(ComputedDefaultValue).optional(),
2204
2292
  configuration: import_v43.default.object({
2205
2293
  min: import_v43.default.number().optional().describe("Minimum value"),
2206
2294
  max: import_v43.default.number().optional().describe("Maximum value"),
2207
2295
  prefix: TranslationConfig.optional(),
2208
2296
  postfix: TranslationConfig.optional()
2209
2297
  }).optional()
2210
- }).describe("Number input");
2298
+ }).meta({
2299
+ description: "A number input field",
2300
+ id: "NumberField"
2301
+ });
2211
2302
  var TextAreaField = BaseField.extend({
2212
2303
  type: import_v43.default.literal(FieldType.TEXTAREA),
2213
- defaultValue: NonEmptyTextValue.optional(),
2304
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2214
2305
  configuration: import_v43.default.object({
2215
2306
  maxLength: import_v43.default.number().optional().describe("Maximum length of the text"),
2216
2307
  rows: import_v43.default.number().optional().describe("Number of visible text lines"),
@@ -2218,7 +2309,10 @@ var TextAreaField = BaseField.extend({
2218
2309
  prefix: TranslationConfig.optional(),
2219
2310
  postfix: TranslationConfig.optional()
2220
2311
  }).default({ rows: 4 }).optional()
2221
- }).describe("Multiline text input");
2312
+ }).meta({
2313
+ description: "A multiline text input",
2314
+ id: "TextAreaField"
2315
+ });
2222
2316
  var ImageMimeType = import_v43.default.enum([
2223
2317
  "image/png",
2224
2318
  "image/jpg",
@@ -2241,58 +2335,76 @@ var SignatureField = BaseField.extend({
2241
2335
  signaturePromptLabel: TranslationConfig.describe(
2242
2336
  "Title of the signature modal"
2243
2337
  ),
2244
- defaultValue: FieldValue.optional(),
2338
+ defaultValue: SignatureFieldValue.or(ComputedDefaultValue).optional(),
2245
2339
  configuration: import_v43.default.object({
2246
2340
  maxFileSize: import_v43.default.number().describe("Maximum file size in bytes").default(DEFAULT_MAX_FILE_SIZE_BYTES),
2247
2341
  acceptedFileTypes: MimeType.array().optional().describe("List of allowed file formats for the signature")
2248
2342
  }).default({
2249
2343
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
2250
2344
  })
2251
- }).describe("Signature input field");
2345
+ }).meta({
2346
+ description: "A signature input field",
2347
+ id: "SignatureField"
2348
+ });
2252
2349
  var EmailField = BaseField.extend({
2253
2350
  type: import_v43.default.literal(FieldType.EMAIL),
2254
2351
  configuration: import_v43.default.object({
2255
2352
  maxLength: import_v43.default.number().optional().describe("Maximum length of the text")
2256
2353
  }).default({ maxLength: 255 }).optional(),
2257
- defaultValue: NonEmptyTextValue.optional()
2354
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional()
2355
+ }).meta({
2356
+ description: "An email input field",
2357
+ id: "EmailField"
2258
2358
  });
2259
2359
  var DateField = BaseField.extend({
2260
2360
  type: import_v43.default.literal(FieldType.DATE),
2261
- defaultValue: SerializedNowDateTime.or(PlainDate).optional().describe("Default date value(yyyy-MM-dd)"),
2361
+ defaultValue: SerializedNowDateTime.or(PlainDate).or(ComputedDefaultValue).optional().describe("Default date value(yyyy-MM-dd)"),
2262
2362
  configuration: import_v43.default.object({
2263
2363
  notice: TranslationConfig.describe(
2264
2364
  "Text to display above the date input"
2265
2365
  ).optional()
2266
2366
  }).optional()
2267
- }).describe("A single date input (yyyy-MM-dd)");
2367
+ }).meta({
2368
+ description: "A date input (yyyy-MM-dd)",
2369
+ id: "DateField"
2370
+ });
2268
2371
  var AgeField = BaseField.extend({
2269
2372
  type: import_v43.default.literal(FieldType.AGE),
2270
- defaultValue: NumberFieldValue.optional(),
2373
+ defaultValue: NumberFieldValue.or(ComputedDefaultValue).optional(),
2271
2374
  configuration: import_v43.default.object({
2272
2375
  asOfDate: FieldReference,
2273
2376
  prefix: TranslationConfig.optional(),
2274
2377
  postfix: TranslationConfig.optional()
2275
2378
  })
2276
- }).describe("An age input field which uses the current date as the asOfDate");
2379
+ }).meta({
2380
+ description: "An age input field which uses the current date as the asOfDate",
2381
+ id: "AgeField"
2382
+ });
2277
2383
  var TimeField = BaseField.extend({
2278
2384
  type: import_v43.default.literal(FieldType.TIME),
2279
- defaultValue: SerializedNowDateTime.or(TimeValue).optional().describe("Default time value (HH-mm)"),
2385
+ defaultValue: SerializedNowDateTime.or(TimeValue).or(ComputedDefaultValue).optional().describe("Default time value (HH-mm)"),
2280
2386
  configuration: import_v43.default.object({
2281
2387
  use12HourFormat: import_v43.default.boolean().optional().describe("Whether to use 12-hour format"),
2282
2388
  notice: TranslationConfig.describe(
2283
2389
  "Text to display above the time input"
2284
2390
  ).optional()
2285
2391
  }).optional()
2286
- }).describe("A single date input (HH-mm)");
2392
+ }).meta({
2393
+ description: "A single time input (HH-mm)",
2394
+ id: "TimeField"
2395
+ });
2287
2396
  var DateRangeField = BaseField.extend({
2288
2397
  type: import_v43.default.literal(FieldType.DATE_RANGE),
2289
- defaultValue: DateRangeFieldValue.optional(),
2398
+ defaultValue: DateRangeFieldValue.or(ComputedDefaultValue).optional(),
2290
2399
  configuration: import_v43.default.object({
2291
2400
  notice: TranslationConfig.describe(
2292
2401
  "Text to display above the date input"
2293
2402
  ).optional()
2294
2403
  }).optional()
2295
- }).describe("A date range input ({ start: yyyy-MM-dd, end: yyyy-MM-dd })");
2404
+ }).meta({
2405
+ description: "A date range input ({ start: yyyy-MM-dd, end: yyyy-MM-dd })",
2406
+ id: "DateRangeField"
2407
+ });
2296
2408
  var HtmlFontVariant = import_v43.default.enum([
2297
2409
  "reg12",
2298
2410
  "reg14",
@@ -2336,21 +2448,33 @@ var ImageViewField = BaseField.extend({
2336
2448
  type: import_v43.default.literal(FieldType.IMAGE_VIEW),
2337
2449
  defaultValue: NonEmptyTextValue.optional(),
2338
2450
  configuration: ImageConfiguration
2339
- }).describe("A read-only image component for form pages");
2451
+ }).meta({
2452
+ description: "A read-only image component for form pages",
2453
+ id: "ImageViewField"
2454
+ });
2340
2455
  var Paragraph = BaseField.extend({
2341
2456
  type: import_v43.default.literal(FieldType.PARAGRAPH),
2342
2457
  configuration: ParagraphConfiguration
2343
- }).describe("A read-only HTML <p> paragraph");
2458
+ }).meta({
2459
+ description: "A read-only HTML <p> paragraph",
2460
+ id: "Paragraph"
2461
+ });
2344
2462
  var Heading = BaseField.extend({
2345
2463
  type: import_v43.default.literal(FieldType.HEADING),
2346
2464
  configuration: HeadingConfiguration
2347
- }).describe("A read-only heading component for form pages");
2465
+ }).meta({
2466
+ description: "A read-only heading component for form pages",
2467
+ id: "Heading"
2468
+ });
2348
2469
  var PageHeader = BaseField.extend({
2349
2470
  type: import_v43.default.literal(FieldType.PAGE_HEADER)
2350
- }).describe("A read-only header component for form pages");
2471
+ }).meta({
2472
+ description: "A read-only header component for form pages",
2473
+ id: "PageHeader"
2474
+ });
2351
2475
  var File = BaseField.extend({
2352
2476
  type: import_v43.default.literal(FieldType.FILE),
2353
- defaultValue: FileFieldValue.optional(),
2477
+ defaultValue: FileFieldValue.or(ComputedDefaultValue).optional(),
2354
2478
  configuration: import_v43.default.object({
2355
2479
  maxFileSize: import_v43.default.number().describe("Maximum file size in bytes").default(DEFAULT_MAX_FILE_SIZE_BYTES),
2356
2480
  acceptedFileTypes: MimeType.array().optional().describe("List of allowed file formats for the signature"),
@@ -2366,7 +2490,10 @@ var File = BaseField.extend({
2366
2490
  }).default({
2367
2491
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
2368
2492
  })
2369
- }).describe("File upload");
2493
+ }).meta({
2494
+ description: "A file upload field",
2495
+ id: "File"
2496
+ });
2370
2497
  var SelectOption = import_v43.default.object({
2371
2498
  value: import_v43.default.string().describe("The value of the option"),
2372
2499
  label: import_v43.default.union([import_v43.default.string(), TranslationConfig]).describe("The label of the option"),
@@ -2374,7 +2501,7 @@ var SelectOption = import_v43.default.object({
2374
2501
  });
2375
2502
  var NumberWithUnitField = BaseField.extend({
2376
2503
  type: import_v43.default.literal(FieldType.NUMBER_WITH_UNIT),
2377
- defaultValue: NumberWithUnitFieldValue.optional(),
2504
+ defaultValue: NumberWithUnitFieldValue.or(ComputedDefaultValue).optional(),
2378
2505
  options: import_v43.default.array(SelectOption).describe("A list of options for the unit select"),
2379
2506
  configuration: import_v43.default.object({
2380
2507
  min: import_v43.default.number().optional().describe("Minimum value of the number field"),
@@ -2383,17 +2510,23 @@ var NumberWithUnitField = BaseField.extend({
2383
2510
  "Placeholder for the number field"
2384
2511
  )
2385
2512
  }).optional()
2386
- }).describe("Number with unit input");
2513
+ }).meta({
2514
+ description: "A number with unit input field",
2515
+ id: "NumberWithUnitField"
2516
+ });
2387
2517
  var RadioGroup = BaseField.extend({
2388
2518
  type: import_v43.default.literal(FieldType.RADIO_GROUP),
2389
- defaultValue: TextValue.optional(),
2519
+ defaultValue: TextValue.or(ComputedDefaultValue).optional(),
2390
2520
  options: import_v43.default.array(SelectOption).describe("A list of options"),
2391
2521
  configuration: import_v43.default.object({
2392
2522
  styles: import_v43.default.object({
2393
2523
  size: import_v43.default.enum(["NORMAL", "LARGE"]).optional()
2394
2524
  }).optional()
2395
2525
  }).optional()
2396
- }).describe("Grouped radio options");
2526
+ }).meta({
2527
+ description: "A grouped radio button field",
2528
+ id: "RadioGroup"
2529
+ });
2397
2530
  var BulletList = BaseField.extend({
2398
2531
  type: import_v43.default.literal(FieldType.BULLET_LIST),
2399
2532
  items: import_v43.default.array(TranslationConfig).describe("A list of items"),
@@ -2402,10 +2535,13 @@ var BulletList = BaseField.extend({
2402
2535
  fontVariant: HtmlFontVariant.optional()
2403
2536
  }).optional()
2404
2537
  }).default({})
2405
- }).describe("A list of bullet points");
2538
+ }).meta({
2539
+ description: "A list of bullet points",
2540
+ id: "BulletList"
2541
+ });
2406
2542
  var Select = BaseField.extend({
2407
2543
  type: import_v43.default.literal(FieldType.SELECT),
2408
- defaultValue: TextValue.optional(),
2544
+ defaultValue: TextValue.or(ComputedDefaultValue).optional(),
2409
2545
  options: import_v43.default.array(SelectOption).describe("A list of options"),
2410
2546
  noOptionsMessage: TranslationConfig.optional().describe(
2411
2547
  `
@@ -2417,16 +2553,22 @@ var Select = BaseField.extend({
2417
2553
  { ..., defaultMessage: "'{input}' is not listed among the health facilities." }
2418
2554
  `
2419
2555
  )
2420
- }).describe("Select input");
2556
+ }).meta({
2557
+ description: "A select input field",
2558
+ id: "Select"
2559
+ });
2421
2560
  var SelectDateRangeOption = import_v43.default.object({
2422
2561
  value: SelectDateRangeValue.describe("The value of the option"),
2423
2562
  label: TranslationConfig.describe("The label of the option")
2424
2563
  });
2425
2564
  var SelectDateRangeField = BaseField.extend({
2426
2565
  type: import_v43.default.literal(FieldType.SELECT_DATE_RANGE),
2427
- defaultValue: SelectDateRangeValue.optional(),
2566
+ defaultValue: SelectDateRangeValue.or(ComputedDefaultValue).optional(),
2428
2567
  options: import_v43.default.array(SelectDateRangeOption).describe("A list of options")
2429
- }).describe("Select input with date range options");
2568
+ }).meta({
2569
+ description: "A date range selection field",
2570
+ id: "SelectDateRangeField"
2571
+ });
2430
2572
  var NameConfig = import_v43.default.object({
2431
2573
  firstname: import_v43.default.object({ required: requiredSchema, label: TranslationConfig.optional() }).optional(),
2432
2574
  middlename: import_v43.default.object({ required: requiredSchema, label: TranslationConfig.optional() }).optional(),
@@ -2438,7 +2580,7 @@ var NameField = BaseField.extend({
2438
2580
  firstname: SerializedUserField.or(NonEmptyTextValue).optional(),
2439
2581
  middlename: SerializedUserField.or(NonEmptyTextValue).optional(),
2440
2582
  surname: SerializedUserField.or(NonEmptyTextValue).optional()
2441
- }).optional(),
2583
+ }).or(ComputedDefaultValue).optional(),
2442
2584
  configuration: import_v43.default.object({
2443
2585
  name: NameConfig.default({
2444
2586
  firstname: { required: true },
@@ -2457,26 +2599,41 @@ var NameField = BaseField.extend({
2457
2599
  surname: { required: true }
2458
2600
  }
2459
2601
  }).optional()
2460
- }).describe("Name input field");
2602
+ }).meta({
2603
+ description: "A field for entering a persons name",
2604
+ id: "NameField"
2605
+ });
2461
2606
  var PhoneField = BaseField.extend({
2462
- defaultValue: NonEmptyTextValue.optional(),
2607
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2463
2608
  type: import_v43.default.literal(FieldType.PHONE)
2464
- }).describe("Phone input field");
2609
+ }).meta({
2610
+ description: "A field for entering a phone number",
2611
+ id: "PhoneField"
2612
+ });
2465
2613
  var IdField = BaseField.extend({
2466
- defaultValue: NonEmptyTextValue.optional(),
2614
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2467
2615
  type: import_v43.default.literal(FieldType.ID)
2468
- }).describe("ID input field");
2616
+ }).meta({
2617
+ description: "A field for entering an ID",
2618
+ id: "IdField"
2619
+ });
2469
2620
  var Checkbox = BaseField.extend({
2470
2621
  type: import_v43.default.literal(FieldType.CHECKBOX),
2471
- defaultValue: CheckboxFieldValue.default(false)
2472
- }).describe("Boolean checkbox field");
2622
+ defaultValue: CheckboxFieldValue.or(ComputedDefaultValue).default(false)
2623
+ }).meta({
2624
+ description: "A boolean checkbox field",
2625
+ id: "Checkbox"
2626
+ });
2473
2627
  var Country = BaseField.extend({
2474
2628
  type: import_v43.default.literal(FieldType.COUNTRY),
2475
- defaultValue: NonEmptyTextValue.optional(),
2629
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2476
2630
  optionOverrides: import_v43.default.array(SelectOption.omit({ label: true })).optional().describe(
2477
2631
  "Conditionals for specific countries. Countries not listed are always shown and enabled."
2478
2632
  )
2479
- }).describe("Country select field");
2633
+ }).meta({
2634
+ description: "A field for selecting a country",
2635
+ id: "Country"
2636
+ });
2480
2637
  var AllowedLocations = JurisdictionReference.optional().describe(
2481
2638
  "Limits which location options are selectable depending on user jurisdiction and location."
2482
2639
  );
@@ -2485,28 +2642,33 @@ var AdministrativeAreas = import_v43.default.enum([
2485
2642
  "HEALTH_FACILITY",
2486
2643
  "CRVS_OFFICE"
2487
2644
  ]);
2488
- var AdministrativeAreaConfiguration = import_v43.default.object({
2489
- partOf: FieldReference.optional().describe("Parent location"),
2490
- type: AdministrativeAreas,
2491
- allowedLocations: AllowedLocations
2492
- }).describe("Administrative area options");
2493
2645
  var AdministrativeAreaField = BaseField.extend({
2494
2646
  type: import_v43.default.literal(FieldType.ADMINISTRATIVE_AREA),
2495
- defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
2496
- configuration: AdministrativeAreaConfiguration
2497
- }).describe("Administrative area input field e.g. facility, office");
2647
+ defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField, ComputedDefaultValue]).optional(),
2648
+ configuration: import_v43.default.object({
2649
+ partOf: FieldReference.optional().describe("Parent location"),
2650
+ type: AdministrativeAreas,
2651
+ allowedLocations: AllowedLocations
2652
+ }).describe("Administrative area options")
2653
+ }).meta({
2654
+ description: "Administrative area input field",
2655
+ id: "AdministrativeAreaField"
2656
+ });
2498
2657
  var LocationInput = BaseField.extend({
2499
2658
  type: import_v43.default.literal(FieldType.LOCATION),
2500
- defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField]).optional(),
2659
+ defaultValue: import_v43.default.union([NonEmptyTextValue, SerializedUserField, ComputedDefaultValue]).optional(),
2501
2660
  configuration: import_v43.default.object({
2502
2661
  locationTypes: import_v43.default.array(import_v43.default.string()).optional().describe("Types of the locations that are available for selection."),
2503
2662
  allowedLocations: AllowedLocations
2504
2663
  }).optional()
2505
- }).describe("Input field for a location");
2664
+ }).meta({
2665
+ description: "A field for selecting a location",
2666
+ id: "LocationInput"
2667
+ });
2506
2668
  var FileUploadWithOptions = BaseField.extend({
2507
2669
  type: import_v43.default.literal(FieldType.FILE_WITH_OPTIONS),
2508
2670
  options: import_v43.default.array(SelectOption).describe("A list of options"),
2509
- defaultValue: FileFieldWithOptionValue.optional(),
2671
+ defaultValue: FileFieldWithOptionValue.or(ComputedDefaultValue).optional(),
2510
2672
  configuration: import_v43.default.object({
2511
2673
  maxFileSize: import_v43.default.number().describe("Maximum file size in bytes").default(DEFAULT_MAX_FILE_SIZE_BYTES),
2512
2674
  maxImageSize: import_v43.default.object({
@@ -2516,15 +2678,18 @@ var FileUploadWithOptions = BaseField.extend({
2516
2678
  }).default({
2517
2679
  maxFileSize: DEFAULT_MAX_FILE_SIZE_BYTES
2518
2680
  })
2681
+ }).meta({
2682
+ description: "A field for uploading files with file type options",
2683
+ id: "FileUploadWithOptions"
2519
2684
  });
2520
2685
  var Facility = BaseField.extend({
2521
2686
  type: import_v43.default.literal(FieldType.FACILITY),
2522
- defaultValue: NonEmptyTextValue.optional(),
2687
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2523
2688
  configuration: import_v43.default.object({ allowedLocations: AllowedLocations }).optional()
2524
2689
  }).describe("Input field for a facility");
2525
2690
  var Office = BaseField.extend({
2526
2691
  type: import_v43.default.literal(FieldType.OFFICE),
2527
- defaultValue: NonEmptyTextValue.optional(),
2692
+ defaultValue: NonEmptyTextValue.or(ComputedDefaultValue).optional(),
2528
2693
  configuration: import_v43.default.object({ allowedLocations: AllowedLocations }).optional()
2529
2694
  }).describe("Input field for an office");
2530
2695
  var DefaultAddressFieldValue = DomesticAddressFieldValue.extend({
@@ -2560,8 +2725,11 @@ var Address = BaseField.extend({
2560
2725
  ).optional(),
2561
2726
  allowedLocations: AllowedLocations
2562
2727
  }).optional(),
2563
- defaultValue: DefaultAddressFieldValue.optional()
2564
- }).describe("Address input field \u2013 a combination of location and text fields");
2728
+ defaultValue: DefaultAddressFieldValue.or(ComputedDefaultValue).optional()
2729
+ }).meta({
2730
+ description: "Address input field \u2013 a combination of location and text fields",
2731
+ id: "Address"
2732
+ });
2565
2733
  var StaticDataEntry = import_v43.default.object({
2566
2734
  id: import_v43.default.string().describe("ID for the data entry."),
2567
2735
  label: TranslationConfig,
@@ -2576,7 +2744,10 @@ var DataField = BaseField.extend({
2576
2744
  subtitle: TranslationConfig.optional(),
2577
2745
  data: import_v43.default.array(DataEntry)
2578
2746
  })
2579
- }).describe("Data field for displaying read-only data");
2747
+ }).meta({
2748
+ description: "A field for displaying a table of read-only data",
2749
+ id: "DataField"
2750
+ });
2580
2751
  var ButtonSize = import_v43.default.enum(["small", "medium", "large"]);
2581
2752
  var ButtonType = import_v43.default.enum([
2582
2753
  "primary",
@@ -2601,13 +2772,19 @@ var ButtonConfiguration = import_v43.default.object({
2601
2772
  });
2602
2773
  var ButtonField = BaseField.extend({
2603
2774
  type: import_v43.default.literal(FieldType.BUTTON),
2604
- defaultValue: ButtonFieldValue.optional(),
2775
+ defaultValue: ButtonFieldValue.or(ComputedDefaultValue).optional(),
2605
2776
  configuration: ButtonConfiguration
2606
- }).describe("Generic button without any built-in functionality");
2777
+ }).meta({
2778
+ description: "A generic button that can be used to trigger an action",
2779
+ id: "ButtonField"
2780
+ });
2607
2781
  var FieldGroup = BaseField.extend({
2608
2782
  type: import_v43.default.literal(FieldType.FIELD_GROUP),
2609
2783
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
2610
2784
  fields: import_v43.default.lazy(() => import_v43.default.array(FieldConfig))
2785
+ }).meta({
2786
+ description: "A group of fields that are displayed together",
2787
+ id: "FieldGroup"
2611
2788
  });
2612
2789
  var AlphaPrintButton = BaseField.extend({
2613
2790
  type: import_v43.default.literal(FieldType.ALPHA_PRINT_BUTTON),
@@ -2617,10 +2794,13 @@ var AlphaPrintButton = BaseField.extend({
2617
2794
  "Label for the print button"
2618
2795
  )
2619
2796
  })
2620
- }).describe("Print button field for printing certificates");
2797
+ }).meta({
2798
+ description: "An experimental print button field for printing certificates during the declaration process",
2799
+ id: "AlphaPrintButton"
2800
+ });
2621
2801
  var HttpField = BaseField.extend({
2622
2802
  type: import_v43.default.literal(FieldType.HTTP),
2623
- defaultValue: HttpFieldValue.optional(),
2803
+ defaultValue: HttpFieldValue.or(ComputedDefaultValue).optional(),
2624
2804
  configuration: import_v43.default.object({
2625
2805
  trigger: FieldReference.optional().describe(
2626
2806
  "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."
@@ -2633,20 +2813,30 @@ var HttpField = BaseField.extend({
2633
2813
  params: import_v43.default.record(import_v43.default.string(), import_v43.default.union([import_v43.default.string(), FieldReference])).optional(),
2634
2814
  timeout: import_v43.default.number().default(15e3).describe("Request timeout in milliseconds")
2635
2815
  })
2636
- }).describe("HTTP request function triggered by a button click or other event");
2816
+ }).meta({
2817
+ 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.",
2818
+ id: "HttpField"
2819
+ });
2637
2820
  var AutocompleteField = BaseField.extend({
2638
2821
  type: import_v43.default.literal(FieldType.AUTOCOMPLETE),
2639
2822
  configuration: import_v43.default.object({
2640
- url: import_v43.default.string().describe("URL to fetch autocomplete suggestions from").optional(),
2823
+ url: import_v43.default.string().describe(
2824
+ "URL to fetch autocomplete suggestions from. This should be a country config server endpoint."
2825
+ ).optional(),
2641
2826
  method: import_v43.default.enum(["GET", "POST"]).default("GET").optional(),
2642
2827
  defaultOptions: import_v43.default.array(
2643
2828
  import_v43.default.object({
2644
2829
  label: import_v43.default.string(),
2645
2830
  value: import_v43.default.string()
2646
2831
  })
2647
- ).optional()
2832
+ ).optional().describe(
2833
+ "Manual entry is supported through configuration, allowing users to provide values not currently represented in the dataset."
2834
+ )
2648
2835
  })
2649
- }).describe("Autocomplete input field");
2836
+ }).meta({
2837
+ 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.",
2838
+ id: "AutocompleteField"
2839
+ });
2650
2840
  var SearchField = HttpField.extend({
2651
2841
  type: import_v43.default.literal(FieldType.SEARCH),
2652
2842
  configuration: SearchQuery.pick({
@@ -2679,6 +2869,9 @@ var SearchField = HttpField.extend({
2679
2869
  ok: TranslationConfig.optional()
2680
2870
  }).optional()
2681
2871
  })
2872
+ }).meta({
2873
+ description: "A search input field",
2874
+ id: "SearchField"
2682
2875
  });
2683
2876
  var LinkButtonField = BaseField.extend({
2684
2877
  type: import_v43.default.literal(FieldType.LINK_BUTTON),
@@ -2687,28 +2880,35 @@ var LinkButtonField = BaseField.extend({
2687
2880
  text: TranslationConfig.describe("Text to display on the button"),
2688
2881
  icon: import_v43.default.string().optional().describe("Icon for the button. You can find icons from OpenCRVS UI-Kit.")
2689
2882
  })
2690
- }).describe("Button that opens a link");
2883
+ }).meta({
2884
+ description: "A button that opens a URL link",
2885
+ id: "LinkButtonField"
2886
+ });
2691
2887
  var VerificationStatus = BaseField.extend({
2692
2888
  type: import_v43.default.literal(FieldType.VERIFICATION_STATUS),
2693
- defaultValue: VerificationStatusValue.optional(),
2889
+ defaultValue: VerificationStatusValue.or(ComputedDefaultValue).optional(),
2694
2890
  configuration: import_v43.default.object({
2695
2891
  status: TranslationConfig.describe("Text to display on the status pill."),
2696
2892
  description: TranslationConfig.describe(
2697
2893
  "Explaining text on the banner in form."
2698
2894
  )
2699
2895
  })
2896
+ }).meta({
2897
+ 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.",
2898
+ id: "VerificationStatus"
2700
2899
  });
2701
2900
  var QueryParamReaderField = BaseField.extend({
2702
2901
  type: import_v43.default.literal(FieldType.QUERY_PARAM_READER),
2703
2902
  configuration: import_v43.default.object({
2704
2903
  pickParams: import_v43.default.array(import_v43.default.string()).describe("List of query parameters to read from the URL")
2705
2904
  })
2706
- }).describe(
2707
- "A field that maps URL query params into form values and clears them afterward"
2708
- );
2905
+ }).meta({
2906
+ description: "A field that maps URL query params into form values and clears them afterward",
2907
+ id: "QueryParamReaderField"
2908
+ });
2709
2909
  var QrReaderField = BaseField.extend({
2710
2910
  type: import_v43.default.literal(FieldType.QR_READER),
2711
- defaultValue: QrReaderFieldValue.optional(),
2911
+ defaultValue: QrReaderFieldValue.or(ComputedDefaultValue).optional(),
2712
2912
  configuration: import_v43.default.object({
2713
2913
  validator: import_v43.default.any().meta({
2714
2914
  description: "JSON Schema to validate the scanned QR code data against before populating the form fields.",
@@ -2716,21 +2916,27 @@ var QrReaderField = BaseField.extend({
2716
2916
  })
2717
2917
  }).optional()
2718
2918
  }).meta({
2719
- description: "Configuration for QR code reader field, including optional JSON Schema validator.",
2919
+ description: "QR code reader field, including optional JSON Schema validator.",
2720
2920
  id: "QrReaderField"
2721
2921
  });
2722
2922
  var IdReaderField = BaseField.extend({
2723
2923
  type: import_v43.default.literal(FieldType.ID_READER),
2724
- defaultValue: IdReaderFieldValue.optional(),
2924
+ defaultValue: IdReaderFieldValue.or(ComputedDefaultValue).optional(),
2725
2925
  methods: import_v43.default.array(
2726
2926
  import_v43.default.union([QrReaderField, LinkButtonField]).describe("Methods for reading an ID")
2727
2927
  )
2928
+ }).meta({
2929
+ description: "A wrapper around nested form fields, specifically QR_READER and LINK_BUTTON. It can hold the QR_READERs value.",
2930
+ id: "IdReaderField"
2728
2931
  });
2729
2932
  var CustomField = BaseField.extend({
2730
2933
  type: import_v43.default.literal(FieldType._EXPERIMENTAL_CUSTOM),
2731
2934
  defaultValue: CustomFieldValue.optional(),
2732
2935
  src: import_v43.default.string().describe("Module source path for the custom field component"),
2733
2936
  configuration: import_v43.default.unknown().optional()
2937
+ }).meta({
2938
+ description: "An expiremental custom field that is defined by a module source path",
2939
+ id: "CustomField"
2734
2940
  });
2735
2941
  var FieldStyleVariant = import_v43.default.enum(["default", "highlighted"]);
2736
2942
  var LoaderField = BaseField.extend({
@@ -2740,22 +2946,25 @@ var LoaderField = BaseField.extend({
2740
2946
  configuration: import_v43.default.object({
2741
2947
  text: TranslationConfig.describe("Display text above the loading spinner")
2742
2948
  })
2743
- }).describe(
2744
- "A non-interactive field that indicates an in progress operation in form"
2745
- );
2949
+ }).meta({
2950
+ description: "A non-interactive field that indicates an in progress operation in form",
2951
+ id: "LoaderField"
2952
+ });
2746
2953
  var HiddenField = BaseField.extend({
2747
2954
  type: import_v43.default.literal(FieldType.ALPHA_HIDDEN),
2748
2955
  required: import_v43.default.boolean().default(false).optional(),
2749
2956
  defaultValue: TextValue.optional()
2750
- }).describe(
2751
- "A non-interactive, hidden field that only hold a value in the form"
2752
- );
2957
+ }).meta({
2958
+ description: "A non-interactive, hidden field that only hold a value in the form",
2959
+ id: "HiddenField"
2960
+ });
2753
2961
  var UserRoleField = BaseField.extend({
2754
2962
  type: import_v43.default.literal(FieldType.USER_ROLE),
2755
2963
  defaultValue: TextValue.optional()
2756
- }).describe(
2757
- "A select dropdown that is automatically populated with available user roles"
2758
- );
2964
+ }).meta({
2965
+ description: "A select dropdown that is automatically populated with available user roles",
2966
+ id: "UserRoleField"
2967
+ });
2759
2968
  var FieldConfig = import_v43.default.discriminatedUnion("type", [
2760
2969
  FieldGroup,
2761
2970
  Address,
@@ -2854,16 +3063,19 @@ var VerificationPageConfig = FormPageConfig.extend({
2854
3063
  type: z21.literal(PageTypes.enum.VERIFICATION),
2855
3064
  actions: VerificationActionConfig
2856
3065
  });
2857
- var PageConfig = z21.discriminatedUnion("type", [
2858
- FormPageConfig,
2859
- VerificationPageConfig
2860
- ]);
3066
+ var PageConfig = z21.discriminatedUnion("type", [FormPageConfig, VerificationPageConfig]).meta({
3067
+ id: "PageConfig",
3068
+ 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."
3069
+ });
2861
3070
 
2862
3071
  // ../commons/src/events/FormConfig.ts
2863
3072
  var DeclarationFormConfig = z22.object({
2864
3073
  label: TranslationConfig.describe("Human readable description of the form"),
2865
3074
  pages: z22.array(FormPageConfig)
2866
- }).describe("Configuration of the declaration form.");
3075
+ }).meta({
3076
+ id: "DeclarationFormConfig",
3077
+ description: "Configuration of the declaration form."
3078
+ });
2867
3079
  var ActionFormConfig = z22.object({
2868
3080
  label: TranslationConfig.describe("Human readable description of the form"),
2869
3081
  pages: z22.array(PageConfig)
@@ -2963,6 +3175,9 @@ var DeduplicationConfig = z23.object({
2963
3175
  id: z23.string(),
2964
3176
  label: TranslationConfig,
2965
3177
  query: Clause
3178
+ }).meta({
3179
+ id: "DeduplicationConfig",
3180
+ 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."
2966
3181
  });
2967
3182
 
2968
3183
  // ../commons/src/events/ActionConfig.ts
@@ -3080,17 +3295,42 @@ var ActionConfig = z24.discriminatedUnion("type", [
3080
3295
  * OpenAPI references are defined here so our generated OpenAPI spec knows to reuse the models
3081
3296
  * and treat them as "models" instead of duplicating the data structure in each endpoint.
3082
3297
  */
3083
- ReadActionConfig.meta({ id: "ReadActionConfig" }),
3084
- DeclareConfig.meta({ id: "DeclareActionConfig" }),
3085
- RejectConfig.meta({ id: "RejectActionConfig" }),
3086
- RegisterConfig.meta({ id: "RegisterActionConfig" }),
3298
+ ReadActionConfig.meta({
3299
+ id: "ReadActionConfig",
3300
+ description: "Configuration for the read action \u2014 defines the record-tab content displayed on the event overview page."
3301
+ }),
3302
+ DeclareConfig.meta({
3303
+ id: "DeclareActionConfig",
3304
+ description: "Configuration for the declare action. Includes review-page fields. Shared with the notify action (ActionType.NOTIFY)."
3305
+ }),
3306
+ RejectConfig.meta({
3307
+ id: "RejectActionConfig",
3308
+ description: "Configuration for rejecting a record before registration."
3309
+ }),
3310
+ RegisterConfig.meta({
3311
+ id: "RegisterActionConfig",
3312
+ description: "Configuration for registering a record."
3313
+ }),
3087
3314
  PrintCertificateActionConfig.meta({
3088
- id: "PrintCertificateActionConfig"
3315
+ id: "PrintCertificateActionConfig",
3316
+ description: "Configuration for printing a certificate of a registered record."
3317
+ }),
3318
+ RequestCorrectionConfig.meta({
3319
+ id: "RequestCorrectionActionConfig",
3320
+ description: "Configuration for requesting a correction on a registered record."
3321
+ }),
3322
+ EditActionConfig.meta({
3323
+ id: "EditActionConfig",
3324
+ description: "Configuration for editing a record before registration."
3089
3325
  }),
3090
- RequestCorrectionConfig.meta({ id: "RequestCorrectionActionConfig" }),
3091
- EditActionConfig.meta({ id: "EditActionConfig" }),
3092
- ArchiveConfig.meta({ id: "ArchiveActionConfig" }),
3093
- CustomActionConfig.meta({ id: "CustomActionConfig" })
3326
+ ArchiveConfig.meta({
3327
+ id: "ArchiveActionConfig",
3328
+ description: "Configuration for archiving a record."
3329
+ }),
3330
+ CustomActionConfig.meta({
3331
+ id: "CustomActionConfig",
3332
+ description: "Configuration for a country-defined custom action. An event may include any number of these."
3333
+ })
3094
3334
  ]).describe(
3095
3335
  "Configuration of an action available for an event. Data collected depends on the action type and is accessible through the annotation property in ActionDocument."
3096
3336
  ).meta({ id: "ActionConfig" });
@@ -3166,7 +3406,10 @@ var Field = BaseField2.extend({
3166
3406
  }).describe("Custom field defined for the summary view.");
3167
3407
  var SummaryConfig = z27.object({
3168
3408
  fields: z27.array(z27.union([Field, ReferenceField])).describe("Fields displayed in the event summary view.")
3169
- }).describe("Configuration of the event summary section.");
3409
+ }).meta({
3410
+ id: "SummaryConfig",
3411
+ 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."
3412
+ });
3170
3413
 
3171
3414
  // ../commons/src/events/AdvancedSearchConfig.ts
3172
3415
  var z28 = __toESM(require("zod/v4"));
@@ -3237,6 +3480,9 @@ var BaseField3 = z28.object({
3237
3480
  ),
3238
3481
  validations: z28.array(ValidationConfig).optional().describe(
3239
3482
  `Option for overriding the field validations specifically for advanced search form.`
3483
+ ),
3484
+ allowedLocations: JurisdictionReference.optional().describe(
3485
+ `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.`
3240
3486
  )
3241
3487
  });
3242
3488
  var SearchQueryParams = z28.object({
@@ -3290,6 +3536,9 @@ var AdvancedSearchField = z28.discriminatedUnion("fieldType", [FieldConfigSchema
3290
3536
  var AdvancedSearchConfig = z28.object({
3291
3537
  title: TranslationConfig.describe("Advanced search tab title"),
3292
3538
  fields: z28.array(AdvancedSearchField).describe("Advanced search fields within the tab.")
3539
+ }).meta({
3540
+ id: "AdvancedSearchConfig",
3541
+ 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()`)."
3293
3542
  });
3294
3543
 
3295
3544
  // ../commons/src/events/utils.ts
@@ -3308,9 +3557,11 @@ var z30 = __toESM(require("zod/v4"));
3308
3557
  var z29 = __toESM(require("zod/v4"));
3309
3558
  function getDynamicNameValue(field3) {
3310
3559
  const nameConfiguration = field3.configuration?.name;
3560
+ const firstnameRequired = nameConfiguration?.firstname?.required ?? field3.required;
3561
+ const surnameRequired = nameConfiguration?.surname?.required ?? field3.required;
3311
3562
  return z29.object({
3312
- firstname: nameConfiguration?.firstname?.required ? NonEmptyTextValue : TextValue,
3313
- surname: nameConfiguration?.surname?.required ? NonEmptyTextValue : TextValue,
3563
+ firstname: firstnameRequired ? NonEmptyTextValue : TextValue,
3564
+ surname: surnameRequired ? NonEmptyTextValue : TextValue,
3314
3565
  middlename: nameConfiguration?.middlename?.required ? NonEmptyTextValue : TextValue.optional()
3315
3566
  });
3316
3567
  }
@@ -3693,7 +3944,37 @@ function resolveDataPath(rootData, dataPath, instancePath) {
3693
3944
  }
3694
3945
  return current;
3695
3946
  }
3947
+ function todayISO() {
3948
+ return (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" });
3949
+ }
3950
+ var compiledFunctionCache = /* @__PURE__ */ new Map();
3951
+ function compileClientFunction(code) {
3952
+ let fn = compiledFunctionCache.get(code);
3953
+ if (!fn) {
3954
+ fn = new Function(`return (${code})`)();
3955
+ compiledFunctionCache.set(code, fn);
3956
+ }
3957
+ return fn;
3958
+ }
3696
3959
  (0, import_ajv_formats.default)(ajv);
3960
+ function buildClientFunctionContext(input) {
3961
+ return {
3962
+ $form: input.form,
3963
+ $now: todayISO(),
3964
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
3965
+ $online: isOnline(),
3966
+ $user: input.validatorContext?.user,
3967
+ $event: input.validatorContext?.event,
3968
+ $leafAdminStructureLocationIds: input.validatorContext?.leafAdminStructureLocationIds ?? [],
3969
+ user: input.systemVariables?.user,
3970
+ $window: input.systemVariables?.$window,
3971
+ locations: input.locations,
3972
+ adminLevelIds: input.adminLevelIds
3973
+ };
3974
+ }
3975
+ function runClientFunction(code, data, context) {
3976
+ return compileClientFunction(code)(data, context);
3977
+ }
3697
3978
  ajv.addKeyword({
3698
3979
  keyword: "daysFromDate",
3699
3980
  type: "string",
@@ -3738,7 +4019,7 @@ ajv.addKeyword({
3738
4019
  $data: true,
3739
4020
  errors: true,
3740
4021
  // @ts-ignore -- Force type. We will move this away from AJV next. Parsing the array will take seconds and is only called by core.
3741
- validate(schema, data, _2, dataContext) {
4022
+ validate(_schema, data, _2, dataContext) {
3742
4023
  const locationIdInput = data;
3743
4024
  const locations = dataContext?.rootData.$leafAdminStructureLocationIds ?? [];
3744
4025
  return locations.some((location) => location.id === locationIdInput);
@@ -3766,6 +4047,26 @@ function precompileActionSchemas(eventConfigurations) {
3766
4047
  function isAgeValue(value) {
3767
4048
  return typeof value === "object" && value !== null && "age" in value && typeof value.age === "number";
3768
4049
  }
4050
+ function mergeWithBaseFormState(values, context) {
4051
+ return { ...context.baseFormState, ...values };
4052
+ }
4053
+ ajv.addKeyword({
4054
+ keyword: "customClientValidator",
4055
+ schemaType: "object",
4056
+ errors: true,
4057
+ // @ts-expect-error -- AJV's public types don't expose `rootData`. All
4058
+ // `validate()` callers build root data via `buildClientFunctionContext`,
4059
+ // so the cast holds.
4060
+ validate(schema, data, _2, dataContext) {
4061
+ return Boolean(
4062
+ runClientFunction(
4063
+ schema.code,
4064
+ data,
4065
+ dataContext?.rootData ?? buildClientFunctionContext({ form: {} })
4066
+ )
4067
+ );
4068
+ }
4069
+ });
3769
4070
  function validate(schema, data) {
3770
4071
  const validator = ajv.getSchema(schema.$id) || ajv.compile(schema);
3771
4072
  if ("$form" in data) {
@@ -3802,17 +4103,14 @@ function isOnline() {
3802
4103
  }
3803
4104
  return true;
3804
4105
  }
3805
- function isConditionMet(conditional, values, context, eventIndex) {
3806
- return validate(conditional, {
3807
- $form: values,
3808
- $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3809
- $online: isOnline(),
3810
- $user: context.user,
3811
- $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? [],
3812
- $flags: eventIndex?.flags ?? [],
3813
- $status: eventIndex?.status,
3814
- $event: context.event
3815
- });
4106
+ function isConditionMet(conditional, values, context) {
4107
+ return validate(
4108
+ conditional,
4109
+ buildClientFunctionContext({
4110
+ form: mergeWithBaseFormState(values, context),
4111
+ validatorContext: context
4112
+ })
4113
+ );
3816
4114
  }
3817
4115
  function getConditionalActionsForField(field3, values) {
3818
4116
  if (!field3.conditionals) {
@@ -3820,9 +4118,9 @@ function getConditionalActionsForField(field3, values) {
3820
4118
  }
3821
4119
  return field3.conditionals.filter((conditional) => validate(conditional.conditional, values)).map((conditional) => conditional.type);
3822
4120
  }
3823
- function areConditionsMet(conditions, values, context, event2) {
4121
+ function areConditionsMet(conditions, values, context, _event) {
3824
4122
  return conditions.every(
3825
- (condition) => isConditionMet(condition.conditional, values, context, event2)
4123
+ (condition) => isConditionMet(condition.conditional, values, context)
3826
4124
  );
3827
4125
  }
3828
4126
  function isFieldConditionMet(field3, form, conditionalType, context) {
@@ -3832,14 +4130,13 @@ function isFieldConditionMet(field3, form, conditionalType, context) {
3832
4130
  if (!hasRule) {
3833
4131
  return true;
3834
4132
  }
3835
- const validConditionals = getConditionalActionsForField(field3, {
3836
- $form: form,
3837
- $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3838
- $online: isOnline(),
3839
- $user: context.user,
3840
- $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? [],
3841
- $event: context.event
3842
- });
4133
+ const validConditionals = getConditionalActionsForField(
4134
+ field3,
4135
+ buildClientFunctionContext({
4136
+ form: mergeWithBaseFormState(form, context),
4137
+ validatorContext: context
4138
+ })
4139
+ );
3843
4140
  return validConditionals.includes(conditionalType);
3844
4141
  }
3845
4142
  function isFieldVisible(field3, form, context) {
@@ -3865,7 +4162,14 @@ function isActionConditionMet(actionConfig, event2, context, conditionalType) {
3865
4162
  if (!rule) {
3866
4163
  return true;
3867
4164
  }
3868
- return isConditionMet(rule.conditional, event2.declaration, context, event2);
4165
+ return validate(rule.conditional, {
4166
+ ...buildClientFunctionContext({
4167
+ form: mergeWithBaseFormState(event2.declaration, context),
4168
+ validatorContext: context
4169
+ }),
4170
+ $flags: event2.flags,
4171
+ $status: event2.status
4172
+ });
3869
4173
  }
3870
4174
  function isActionEnabled(actionConfig, event2, context) {
3871
4175
  return isActionConditionMet(
@@ -4024,19 +4328,10 @@ function runFieldValidations({
4024
4328
  if (!isFieldVisible(field3.config, form, context)) {
4025
4329
  return [];
4026
4330
  }
4027
- const conditionalParameters = {
4028
- $form: form,
4029
- $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
4030
- /**
4031
- * In real use cases, there can be hundreds of thousands of locations.
4032
- * Make sure that the context contains only the locations that are needed for validation.
4033
- * E.g. if the user is a leaf admin, only the leaf locations under their admin structure are needed.
4034
- * Loading few megabytes of locations to memory just for validation is not efficient and will choke the application.
4035
- */
4036
- $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? [],
4037
- $online: isOnline(),
4038
- $user: context.user
4039
- };
4331
+ const conditionalParameters = buildClientFunctionContext({
4332
+ form: mergeWithBaseFormState(form, context),
4333
+ validatorContext: context
4334
+ });
4040
4335
  if (isFieldGroupFieldType(field3)) {
4041
4336
  const subfieldErrors = buildFormState(
4042
4337
  field3.config.fields,
@@ -4269,17 +4564,16 @@ function isPageVisible(page, formValues, context) {
4269
4564
  }
4270
4565
  return isConditionMet(page.conditional, formValues, context);
4271
4566
  }
4272
- function omitHiddenFields(fields, formValues, validatorContext, includeHiddenFieldsWithNullValues = false, declarationContext) {
4567
+ function omitHiddenFields(fields, formValues, validatorContext, includeHiddenFieldsWithNullValues = false) {
4273
4568
  const base = (0, import_lodash.cloneDeep)(formValues);
4274
4569
  function fn(prevVisibilityContext) {
4275
- const visibilityForm = declarationContext ? { ...declarationContext, ...prevVisibilityContext } : prevVisibilityContext;
4276
4570
  const cleaned = (0, import_lodash.omitBy)(base, (value, fieldId) => {
4277
4571
  const fieldConfig = fields.filter((f) => f.id === fieldId);
4278
4572
  if (!fieldConfig.length) {
4279
4573
  return false;
4280
4574
  }
4281
4575
  const isHidden = fieldConfig.every(
4282
- (f) => !isFieldVisible(f, visibilityForm, validatorContext)
4576
+ (f) => !isFieldVisible(f, prevVisibilityContext, validatorContext)
4283
4577
  );
4284
4578
  if (!isHidden) {
4285
4579
  return false;
@@ -4297,7 +4591,7 @@ function omitHiddenPaginatedFields(formConfig, values, validatorContext, include
4297
4591
  const visibleFields = formConfig.pages.filter((p) => isPageVisible(p, values, validatorContext)).flatMap((p) => p.fields);
4298
4592
  const hiddenFields = formConfig.pages.filter((p) => !isPageVisible(p, values, validatorContext)).flatMap((p) => p.fields);
4299
4593
  const valuesExceptHiddenPage = (0, import_lodash.omitBy)(values, (_2, fieldId) => {
4300
- return hiddenFields.some((f) => f.id === fieldId);
4594
+ return hiddenFields.some((f) => f.id === fieldId) && !visibleFields.some((f) => f.id === fieldId);
4301
4595
  });
4302
4596
  return omitHiddenFields(
4303
4597
  visibleFields,
@@ -4344,13 +4638,10 @@ function getVisibleVerificationPageIds(pages, annotation, context) {
4344
4638
  }
4345
4639
  function omitHiddenAnnotationFields(actionConfig, declaration, annotation, context) {
4346
4640
  const annotationFields = getActionAnnotationFields(actionConfig);
4347
- return omitHiddenFields(
4348
- annotationFields,
4349
- annotation,
4350
- context,
4351
- false,
4352
- declaration
4353
- );
4641
+ return omitHiddenFields(annotationFields, annotation, {
4642
+ ...context,
4643
+ baseFormState: declaration
4644
+ });
4354
4645
  }
4355
4646
  function deepMerge(currentDocument, actionDocument) {
4356
4647
  const currentDocumentClone = (0, import_lodash.cloneDeep)(currentDocument);
@@ -4524,19 +4815,32 @@ function getPendingAction(actions) {
4524
4815
  }
4525
4816
  return pendingActions[0];
4526
4817
  }
4527
- function getCompleteActionAnnotation(annotation, event2, action) {
4818
+ function getCompleteActionAnnotation(event2, action) {
4528
4819
  if (action.originalActionId) {
4529
4820
  const originalAction = event2.actions.find(
4530
4821
  ({ id }) => id === action.originalActionId
4531
4822
  );
4532
4823
  if (originalAction?.status === ActionStatus.Requested) {
4533
- return deepMerge(
4534
- deepMerge(annotation, originalAction.annotation ?? {}),
4535
- action.annotation ?? {}
4536
- );
4824
+ return deepMerge(originalAction.annotation ?? {}, action.annotation ?? {});
4537
4825
  }
4538
4826
  }
4539
- return deepMerge(annotation, action.annotation ?? {});
4827
+ return action.annotation ?? {};
4828
+ }
4829
+ function getCompleteActionContent(event2, action) {
4830
+ const currentContent = "content" in action ? action.content : void 0;
4831
+ if (!action.originalActionId) {
4832
+ return currentContent;
4833
+ }
4834
+ const originalAction = event2.actions.find(
4835
+ ({ id }) => id === action.originalActionId
4836
+ );
4837
+ if (originalAction && "content" in originalAction && originalAction.content) {
4838
+ return {
4839
+ ...originalAction.content,
4840
+ ...currentContent ?? {}
4841
+ };
4842
+ }
4843
+ return currentContent;
4540
4844
  }
4541
4845
  function getCompleteActionDeclaration(declaration, event2, action) {
4542
4846
  if (action.originalActionId) {
@@ -4556,7 +4860,7 @@ function getAcceptedActions(event2) {
4556
4860
  return event2.actions.filter(isAcceptedAction).map((action) => ({
4557
4861
  ...action,
4558
4862
  declaration: getCompleteActionDeclaration({}, event2, action),
4559
- annotation: getCompleteActionAnnotation({}, event2, action)
4863
+ annotation: getCompleteActionAnnotation(event2, action)
4560
4864
  }));
4561
4865
  }
4562
4866
  var EXCLUDED_ACTIONS = [
@@ -4644,6 +4948,9 @@ function not(condition) {
4644
4948
  function never2() {
4645
4949
  return not(alwaysTrue());
4646
4950
  }
4951
+ function always() {
4952
+ return defineConditional(alwaysTrue());
4953
+ }
4647
4954
  function jsonFieldPath(field3) {
4648
4955
  return [field3.$$field, ...field3.$$subfield].join("/");
4649
4956
  }
@@ -5191,7 +5498,54 @@ function createFieldConditionals(fieldId) {
5191
5498
  }
5192
5499
  },
5193
5500
  required: [fieldId]
5194
- })
5501
+ }),
5502
+ /**
5503
+ * Custom client-side validator. The provided function is serialised and executed
5504
+ * just-in-time on the client only. External references (e.g. lodash) are not
5505
+ * available inside the function body — all logic must be self-contained.
5506
+ *
5507
+ * @example
5508
+ * field('nid').customClientValidator((value) => {
5509
+ * // LUHN check — all logic must be inline
5510
+ * const digits = String(value).split('').map(Number)
5511
+ * // ...
5512
+ * return isValid
5513
+ * })
5514
+ */
5515
+ customClientValidator(validationFn) {
5516
+ const code = validationFn.toString();
5517
+ return defineFormConditional({
5518
+ type: "object",
5519
+ properties: wrapToPath(
5520
+ { [fieldId]: { customClientValidator: { code } } },
5521
+ this.$$subfield
5522
+ ),
5523
+ required: [fieldId]
5524
+ });
5525
+ },
5526
+ /**
5527
+ * Custom client-side evaluation. Returns a {@link FieldReference} descriptor
5528
+ * that can be used as the `value` property or a DATA component entry.
5529
+ * The function receives the referenced field's value as the first argument and
5530
+ * the full form context as the second; its return value replaces the field reference.
5531
+ * The function is serialised and executed just-in-time on the client only.
5532
+ * External references (e.g. lodash) are not available inside the function body.
5533
+ *
5534
+ * For computing a default value without referencing a specific field, use
5535
+ * `evaluate(fn)` in the `defaultValue` property instead.
5536
+ *
5537
+ * @example
5538
+ * field('a').customClientEvaluation((aValue, ctx) =>
5539
+ * Number(aValue) + Number(ctx.$form.b)
5540
+ * )
5541
+ */
5542
+ customClientEvaluation(computationFn) {
5543
+ return {
5544
+ $$code: computationFn.toString(),
5545
+ $$field: fieldId,
5546
+ $$subfield: this.$$subfield
5547
+ };
5548
+ }
5195
5549
  };
5196
5550
  }
5197
5551
 
@@ -5339,7 +5693,7 @@ var _EventConfigBase = z33.object({
5339
5693
  ),
5340
5694
  label: TranslationConfig.describe("Human-readable label for the event type."),
5341
5695
  actions: z33.array(ActionConfig).describe(
5342
- "Configuration of system-defined actions associated with the event."
5696
+ "Configuration of core and custom actions associated with the event."
5343
5697
  ),
5344
5698
  actionOrder: z33.array(z33.string()).optional().describe(
5345
5699
  "Order of actions in the action menu. Use either the action type for core actions or the customActionType for custom actions."
@@ -5351,7 +5705,7 @@ var _EventConfigBase = z33.object({
5351
5705
  "Configuration of fields available in the advanced search feature."
5352
5706
  ),
5353
5707
  flags: z33.array(FlagConfig).optional().default([]).describe(
5354
- "Configuration of flags associated with the actions of this event type."
5708
+ "Configuration of custom flags associated with the actions of this event type."
5355
5709
  ),
5356
5710
  analytics: z33.boolean().optional().default(true).describe(
5357
5711
  "Indicates whether the records of this event type are included in analytics"
@@ -5364,8 +5718,9 @@ var EventConfig = _EventConfigBase.superRefine((event2, ctx) => {
5364
5718
  validateActionFlags(event2, ctx);
5365
5719
  validateActionOrder(event2, ctx);
5366
5720
  }).meta({
5367
- id: "EventConfig"
5368
- }).describe("Configuration defining an event type.");
5721
+ id: "EventConfig",
5722
+ description: "Configuration defining an event type registered in OpenCRVS (for example birth or death)."
5723
+ });
5369
5724
 
5370
5725
  // ../commons/src/events/EventConfigInput.ts
5371
5726
  var defineDeclarationForm = (form) => DeclarationFormConfig.parse(form);
@@ -5588,6 +5943,9 @@ var WorkqueueColumnValue = z34.object({
5588
5943
  var WorkqueueColumn = z34.object({
5589
5944
  label: TranslationConfig,
5590
5945
  value: WorkqueueColumnValue
5946
+ }).meta({
5947
+ id: "WorkqueueColumn",
5948
+ description: "Configuration for a single workqueue column. The value references an event metadata key (e.g. `dateOfEvent`, `status`, `trackingId`)."
5591
5949
  });
5592
5950
  function defineWorkqueuesColumns(workqueueColumns) {
5593
5951
  return workqueueColumns.map(
@@ -5790,18 +6148,11 @@ var WorkqueueConfigWithoutQuery = WorkqueueConfig.omit({
5790
6148
  query: true,
5791
6149
  columns: true
5792
6150
  });
5793
- var WorkqueueConfigInput = z37.object({
5794
- slug: z37.string().describe("Determines the url of the workqueue."),
5795
- name: TranslationConfig.describe(
5796
- "Title of the workflow (both in navigation and on the page)"
5797
- ),
5798
- query: CountryConfigQueryInputType,
5799
- action: z37.object({ type: WorkqueueActionType }).optional().describe(
5800
- "Workqueue call-to-action button configuration. This determines the quick action button shown on each event card and the action taken when the button is clicked."
5801
- ),
5802
- columns: z37.array(WorkqueueColumn).default(mandatoryColumns),
5803
- icon: AvailableIcons,
5804
- emptyMessage: TranslationConfig.optional()
6151
+ var WorkqueueConfigInput = WorkqueueConfig.extend({
6152
+ query: CountryConfigQueryInputType
6153
+ }).meta({
6154
+ id: "WorkqueueConfig",
6155
+ 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."
5805
6156
  });
5806
6157
  function defineWorkqueue(workqueueInput) {
5807
6158
  const queryInput = workqueueInput.query;
@@ -5862,6 +6213,11 @@ var BaseActionInput = z38.object({
5862
6213
  originalActionId: UUID.optional(),
5863
6214
  // should not be part of base action.
5864
6215
  keepAssignment: z38.boolean().optional(),
6216
+ keepAssignmentIfAccepted: z38.boolean().optional(),
6217
+ keepAssignmentIfRejected: z38.boolean().optional(),
6218
+ waitFor: z38.boolean().default(true).describe(
6219
+ "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."
6220
+ ),
5865
6221
  // For normal users, the createdAtLocation is resolved on the backend from the user's primaryOfficeId.
5866
6222
  // @TODO: createdAtLocation should be limited to actions that system users can perform. For normal users, it should not be part of the base action.
5867
6223
  createdAtLocation: UUID.nullish().describe(
@@ -5979,7 +6335,8 @@ var RejectCorrectionActionInput = BaseActionInput.extend(
5979
6335
  var ApproveCorrectionActionInput = BaseActionInput.extend(
5980
6336
  z38.object({
5981
6337
  requestId: z38.string(),
5982
- type: z38.literal(ActionType.APPROVE_CORRECTION).default(ActionType.APPROVE_CORRECTION)
6338
+ type: z38.literal(ActionType.APPROVE_CORRECTION).default(ActionType.APPROVE_CORRECTION),
6339
+ content: z38.object({ immediateCorrection: z38.boolean().optional() }).optional()
5983
6340
  }).shape
5984
6341
  );
5985
6342
  var ReadActionInput = BaseActionInput.extend(
@@ -6041,7 +6398,7 @@ var Draft = z39.object({
6041
6398
  }).describe(
6042
6399
  "A temporary storage for an action. Stored with details of the event, creator and creation time."
6043
6400
  );
6044
- var DraftInput = BaseActionInput.extend({
6401
+ var DraftInput = BaseActionInput.omit({ waitFor: true }).extend({
6045
6402
  type: ActionTypes.exclude([ActionTypes.enum.DELETE]),
6046
6403
  status: z39.enum([
6047
6404
  ActionStatus.Requested,
@@ -6115,7 +6472,6 @@ function getDeclarationActionCreationMetadata(actionType, actions) {
6115
6472
  createdAtLocation: requestAction?.createdAtLocation ?? acceptAction.createdAtLocation,
6116
6473
  acceptedAt: acceptAction.createdAt,
6117
6474
  createdByRole: requestAction?.createdByRole ?? acceptAction.createdByRole,
6118
- createdBySignature: requestAction?.createdBySignature ?? acceptAction.createdBySignature,
6119
6475
  registrationNumber
6120
6476
  };
6121
6477
  }
@@ -6143,7 +6499,7 @@ function getActionUpdateMetadata(actions) {
6143
6499
  "createdAtLocation",
6144
6500
  "createdByRole"
6145
6501
  ];
6146
- return actions.filter(({ type }) => updateActions.safeParse(type).success).filter(({ status: status2 }) => status2 === ActionStatus.Accepted).reduce(
6502
+ return actions.filter(({ type }) => updateActions.safeParse(type).success).reduce(
6147
6503
  (_2, action) => {
6148
6504
  if (action.originalActionId) {
6149
6505
  const originalAction = actions.find(({ id }) => id === action.originalActionId) ?? action;
@@ -6173,26 +6529,43 @@ var import_date_fns3 = require("date-fns");
6173
6529
  function isEditInProgress(actions) {
6174
6530
  return actions.at(-1)?.type === ActionType.EDIT;
6175
6531
  }
6532
+ function findPendingCorrectionAction(writeActions2) {
6533
+ let correctionRequestAction;
6534
+ for (let i = writeActions2.length - 1; i >= 0; i--) {
6535
+ const action = writeActions2[i];
6536
+ if (action.type === ActionType.APPROVE_CORRECTION || action.type === ActionType.REJECT_CORRECTION) {
6537
+ break;
6538
+ }
6539
+ if (action.type === ActionType.REQUEST_CORRECTION) {
6540
+ correctionRequestAction = action;
6541
+ break;
6542
+ }
6543
+ }
6544
+ return correctionRequestAction;
6545
+ }
6176
6546
  function isCorrectionRequested(actions) {
6547
+ return findPendingCorrectionAction(actions) !== void 0;
6548
+ }
6549
+ function isDeclarationIncomplete(actions) {
6550
+ return getStatusFromActions(actions) === EventStatus.enum.NOTIFIED;
6551
+ }
6552
+ function isRejected(actions) {
6553
+ const resettingActionTypes = [
6554
+ ActionType.NOTIFY,
6555
+ ActionType.DECLARE,
6556
+ ActionType.EDIT,
6557
+ ActionType.REGISTER
6558
+ ];
6177
6559
  return actions.reduce((prev, { type }) => {
6178
- if (type === ActionType.REQUEST_CORRECTION) {
6560
+ if (type === ActionType.REJECT) {
6179
6561
  return true;
6180
6562
  }
6181
- if (type === ActionType.APPROVE_CORRECTION) {
6182
- return false;
6183
- }
6184
- if (type === ActionType.REJECT_CORRECTION) {
6563
+ if (resettingActionTypes.includes(type)) {
6185
6564
  return false;
6186
6565
  }
6187
6566
  return prev;
6188
6567
  }, false);
6189
6568
  }
6190
- function isDeclarationIncomplete(actions) {
6191
- return getStatusFromActions(actions) === EventStatus.enum.NOTIFIED;
6192
- }
6193
- function isRejected(actions) {
6194
- return actions.at(-1)?.type === ActionType.REJECT;
6195
- }
6196
6569
  function isPotentialDuplicate(actions) {
6197
6570
  return actions.reduce((prev, { type }) => {
6198
6571
  if (type === ActionType.DUPLICATE_DETECTED) {
@@ -6255,8 +6628,7 @@ function resolveEventCustomFlags(event2, eventConfiguration) {
6255
6628
  return (0, import_lodash3.uniq)(flags);
6256
6629
  }, []);
6257
6630
  }
6258
- function getEventFlags(event2, config) {
6259
- const sortedActions = event2.actions.filter(({ type }) => !isMetaAction(type)).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
6631
+ function getActionStatusFlags(sortedActions) {
6260
6632
  const actionStatus = sortedActions.reduce(
6261
6633
  (actionStatuses, { type, status: status2 }) => ({
6262
6634
  ...actionStatuses,
@@ -6264,26 +6636,40 @@ function getEventFlags(event2, config) {
6264
6636
  }),
6265
6637
  {}
6266
6638
  );
6267
- const flags = Object.entries(actionStatus).filter(([, status2]) => status2 !== ActionStatus.Accepted).map(([type, status2]) => {
6639
+ return Object.entries(actionStatus).filter(([, status2]) => status2 !== ActionStatus.Accepted).map(([type, status2]) => {
6268
6640
  const flag2 = joinValues([type, status2], ":").toLowerCase();
6269
6641
  return flag2;
6270
6642
  });
6271
- if (isCorrectionRequested(sortedActions)) {
6272
- flags.push(InherentFlags.CORRECTION_REQUESTED);
6643
+ }
6644
+ function getInherentFlags(sortedActions) {
6645
+ const acceptedActions = sortedActions.filter(
6646
+ ({ status: status2 }) => status2 === ActionStatus.Accepted
6647
+ );
6648
+ const inherentFlags = [];
6649
+ if (isCorrectionRequested(acceptedActions)) {
6650
+ inherentFlags.push(InherentFlags.CORRECTION_REQUESTED);
6273
6651
  }
6274
- if (isDeclarationIncomplete(sortedActions)) {
6275
- flags.push(InherentFlags.INCOMPLETE);
6652
+ if (isDeclarationIncomplete(acceptedActions)) {
6653
+ inherentFlags.push(InherentFlags.INCOMPLETE);
6276
6654
  }
6277
- if (isRejected(sortedActions)) {
6278
- flags.push(InherentFlags.REJECTED);
6655
+ if (isRejected(acceptedActions)) {
6656
+ inherentFlags.push(InherentFlags.REJECTED);
6279
6657
  }
6280
- if (isPotentialDuplicate(sortedActions)) {
6281
- flags.push(InherentFlags.POTENTIAL_DUPLICATE);
6658
+ if (isPotentialDuplicate(acceptedActions)) {
6659
+ inherentFlags.push(InherentFlags.POTENTIAL_DUPLICATE);
6282
6660
  }
6283
- if (isEditInProgress(sortedActions)) {
6284
- flags.push(InherentFlags.EDIT_IN_PROGRESS);
6661
+ if (isEditInProgress(acceptedActions)) {
6662
+ inherentFlags.push(InherentFlags.EDIT_IN_PROGRESS);
6285
6663
  }
6286
- return [...flags, ...resolveEventCustomFlags(event2, config)];
6664
+ return inherentFlags;
6665
+ }
6666
+ function getEventFlags(event2, config) {
6667
+ const sortedActions = event2.actions.filter(({ type }) => !isMetaAction(type)).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
6668
+ return [
6669
+ ...getActionStatusFlags(sortedActions),
6670
+ ...getInherentFlags(sortedActions),
6671
+ ...resolveEventCustomFlags(event2, config)
6672
+ ];
6287
6673
  }
6288
6674
 
6289
6675
  // ../commons/src/events/state/index.ts
@@ -6329,17 +6715,6 @@ function getAssignedUserFromActions(actions) {
6329
6715
  return user2;
6330
6716
  }, null);
6331
6717
  }
6332
- function getAssignedUserSignatureFromActions(actions) {
6333
- return actions.reduce((signature, action) => {
6334
- if (action.type === ActionType.ASSIGN) {
6335
- return action.createdBySignature || null;
6336
- }
6337
- if (action.type === ActionType.UNASSIGN) {
6338
- return null;
6339
- }
6340
- return signature;
6341
- }, null);
6342
- }
6343
6718
  function deepDropNulls(obj) {
6344
6719
  if (Array.isArray(obj)) {
6345
6720
  return obj.map(deepDropNulls);
@@ -6435,10 +6810,8 @@ function getCurrentEventState(event2, config) {
6435
6810
  createdBy: creationAction.createdBy,
6436
6811
  createdByUserType: creationAction.createdByUserType,
6437
6812
  createdAtLocation: creationAction.createdAtLocation,
6438
- createdBySignature: creationAction.createdBySignature,
6439
6813
  updatedAt: acceptedActionMetadata.createdAt,
6440
6814
  assignedTo: getAssignedUserFromActions(acceptedActions),
6441
- assignedToSignature: getAssignedUserSignatureFromActions(acceptedActions),
6442
6815
  updatedBy: requestActionMetadata.createdBy,
6443
6816
  updatedAtLocation: requestActionMetadata.createdAtLocation,
6444
6817
  declaration,
@@ -6531,7 +6904,7 @@ function getActionAnnotation({
6531
6904
  const action = (0, import_lodash4.findLast)(activeActions, (a) => a.type === actionType);
6532
6905
  const actionWithCompleteAnnotation = action && {
6533
6906
  ...action,
6534
- annotation: getCompleteActionAnnotation({}, event2, action)
6907
+ annotation: getCompleteActionAnnotation(event2, action)
6535
6908
  };
6536
6909
  const matchingDraft = draft?.action.type === actionType ? draft : void 0;
6537
6910
  const sortedActions = (0, import_lodash4.orderBy)(
@@ -6603,6 +6976,9 @@ function createFieldConfig(fieldId, options) {
6603
6976
  }
6604
6977
 
6605
6978
  // ../commons/src/events/field.ts
6979
+ function evaluate(computationFn) {
6980
+ return { $$code: computationFn.toString() };
6981
+ }
6606
6982
  function field(fieldId, options = {}) {
6607
6983
  return {
6608
6984
  ...createFieldConditionals(fieldId),
@@ -9697,7 +10073,6 @@ var eventQueryDataGenerator = (overrides = {}, seed = 1) => {
9697
10073
  createdBy: overrides.createdBy ?? generateUuid(rng),
9698
10074
  createdAtLocation: overrides.createdAtLocation ?? generateUuid(rng),
9699
10075
  updatedAtLocation: overrides.updatedAtLocation ?? generateUuid(rng),
9700
- createdBySignature: overrides.createdBySignature ?? generateRandomSignature(rng),
9701
10076
  updatedAt: overrides.updatedAt ?? (0, import_date_fns4.addDays)(new Date(createdAt), 1).toISOString(),
9702
10077
  assignedTo: overrides.assignedTo ?? null,
9703
10078
  updatedBy: overrides.updatedBy ?? generateUuid(rng),
@@ -9930,11 +10305,77 @@ function canAccessEventWithScope(event2, scope, user2, customActionType) {
9930
10305
  }
9931
10306
  return true;
9932
10307
  }
10308
+ function canAccessUserWithScope({
10309
+ userToAccess,
10310
+ scope,
10311
+ user: user2
10312
+ }) {
10313
+ const opts = scope.options;
10314
+ const hasSameOffice = user2.primaryOfficeId === userToAccess.primaryOfficeId;
10315
+ if (opts?.accessLevel === JurisdictionFilter.enum.location && !hasSameOffice) {
10316
+ return false;
10317
+ }
10318
+ const hasAdministrativeAreaInHierarchy = userToAccess.administrativeHierarchy.some(
10319
+ (id) => user2.administrativeAreaId === id
10320
+ ) || user2.administrativeAreaId === null;
10321
+ if (opts?.accessLevel === JurisdictionFilter.enum.administrativeArea && !hasAdministrativeAreaInHierarchy) {
10322
+ return false;
10323
+ }
10324
+ if (scopeUsesRoleOptions(scope)) {
10325
+ const { options } = scope;
10326
+ if (options?.role && !options.role.includes(userToAccess.role)) {
10327
+ return false;
10328
+ }
10329
+ }
10330
+ return true;
10331
+ }
10332
+ function canAccessOtherUserWithScopes({
10333
+ scopes,
10334
+ userToAccess,
10335
+ user: user2
10336
+ }) {
10337
+ return scopes.some(
10338
+ (scope) => canAccessUserWithScope({ userToAccess, scope, user: user2 })
10339
+ );
10340
+ }
9933
10341
  function userCanAccessEventWithScopes(event2, scopes, user2, customActionType) {
9934
10342
  return scopes.some(
9935
10343
  (scope) => canAccessEventWithScope(event2, scope, user2, customActionType)
9936
10344
  );
9937
10345
  }
10346
+ function getAdministrativeAreaHierarchy(administrativeAreaId, administrativeAreas) {
10347
+ const collectedLocations = [];
10348
+ const parsedAdministrativeAreaId = administrativeAreaId && UUID.safeParse(administrativeAreaId).data;
10349
+ let current = parsedAdministrativeAreaId ? administrativeAreas.get(parsedAdministrativeAreaId) : null;
10350
+ while (current) {
10351
+ collectedLocations.push(current);
10352
+ if (!current.parentId) {
10353
+ break;
10354
+ }
10355
+ const parentId = current.parentId;
10356
+ current = administrativeAreas.get(parentId);
10357
+ }
10358
+ return collectedLocations;
10359
+ }
10360
+ function getLocationHierarchy(selectedId, context) {
10361
+ const { administrativeAreas, locations } = context;
10362
+ const loc = locations.get(selectedId);
10363
+ if (loc) {
10364
+ if (loc.administrativeAreaId) {
10365
+ const hierarchy2 = getAdministrativeAreaHierarchy(
10366
+ loc.administrativeAreaId,
10367
+ administrativeAreas
10368
+ );
10369
+ return [...hierarchy2.reverse().map((area) => area.id), loc.id];
10370
+ }
10371
+ return [loc.id];
10372
+ }
10373
+ const hierarchy = getAdministrativeAreaHierarchy(
10374
+ selectedId,
10375
+ administrativeAreas
10376
+ );
10377
+ return hierarchy.reverse().map((area) => area.id);
10378
+ }
9938
10379
 
9939
10380
  // ../commons/src/events/scopes.ts
9940
10381
  var ACTION_SCOPE_MAP = {
@@ -10009,6 +10450,25 @@ function isActionInScope({
10009
10450
  );
10010
10451
  return canAccess;
10011
10452
  }
10453
+ function getAvailableRolesForUserUpdatePayload({
10454
+ allRoles,
10455
+ userLocation,
10456
+ acceptedScopes,
10457
+ userRequesting
10458
+ }) {
10459
+ const availableRoles = allRoles.filter((role) => {
10460
+ const canAccess = canAccessOtherUserWithScopes({
10461
+ userToAccess: {
10462
+ ...userLocation,
10463
+ role
10464
+ },
10465
+ user: userRequesting,
10466
+ scopes: acceptedScopes
10467
+ });
10468
+ return canAccess;
10469
+ });
10470
+ return availableRoles;
10471
+ }
10012
10472
 
10013
10473
  // ../commons/src/events/serializers/user/deserializer.ts
10014
10474
  function userDeserializer(serializedUserField, user2) {
@@ -10211,3 +10671,366 @@ function getFilePathsFromEvent(event2) {
10211
10671
  });
10212
10672
  return (0, import_lodash7.uniq)(filepaths);
10213
10673
  }
10674
+
10675
+ // ../commons/src/events/mocks.test.utils.ts
10676
+ var V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS = [
10677
+ {
10678
+ id: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10679
+ name: "Central",
10680
+ parentId: null,
10681
+ validUntil: null,
10682
+ externalId: "ydyJb1RAy4U1"
10683
+ },
10684
+ {
10685
+ id: "c599b691-fd2d-45e1-abf4-d185de727fb5",
10686
+ name: "Sulaka",
10687
+ parentId: null,
10688
+ validUntil: null,
10689
+ externalId: "pQ8nGxWmZ2Q3"
10690
+ },
10691
+ {
10692
+ id: "7ef2b9c7-5e6d-49f6-ae05-656207d0fc64",
10693
+ name: "Pualula",
10694
+ parentId: null,
10695
+ validUntil: null,
10696
+ externalId: "Aq91DweLmT8k"
10697
+ },
10698
+ {
10699
+ id: "6d1a59df-988c-4021-a846-ccbc021931a7",
10700
+ name: "Chuminga",
10701
+ parentId: null,
10702
+ validUntil: null,
10703
+ externalId: "Rw0fYNh2Xk9a"
10704
+ },
10705
+ {
10706
+ id: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10707
+ name: "Ibombo",
10708
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10709
+ validUntil: null,
10710
+ externalId: "k7DsP4vbN1Qe"
10711
+ },
10712
+ {
10713
+ id: "27160bbd-32d1-4625-812f-860226bfb92a",
10714
+ name: "Isango",
10715
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10716
+ validUntil: null,
10717
+ externalId: "Gm3Z9eQpHw4L"
10718
+ },
10719
+ {
10720
+ id: "967032fd-3f81-478a-826c-30cb8fe121bd",
10721
+ name: "Isamba",
10722
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10723
+ validUntil: null,
10724
+ externalId: "sT0xVu1KqJ7r"
10725
+ },
10726
+ {
10727
+ id: "89a33893-b17d-481d-a26d-6461e7ac1651",
10728
+ name: "Itambo",
10729
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10730
+ validUntil: null,
10731
+ externalId: "Nq6Bv2HpL9Te"
10732
+ },
10733
+ {
10734
+ id: "d42ab2fe-e7ed-470e-8b31-4fb27f9b8250",
10735
+ name: "Ezhi",
10736
+ parentId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10737
+ validUntil: null,
10738
+ externalId: "xK8cQ0ZRy5Wd"
10739
+ },
10740
+ {
10741
+ id: "8fbd09d2-212b-47f4-beb3-5e1694931d9f",
10742
+ name: "Ilanga",
10743
+ parentId: "c599b691-fd2d-45e1-abf4-d185de727fb5",
10744
+ validUntil: null,
10745
+ externalId: "Cq4Jm1XvN8Ls"
10746
+ },
10747
+ // Villages under Ibombo (62a0ccb4-880d-4f30-8882-f256007dfff9)
10748
+ {
10749
+ id: "1d4e5f6a-7b8c-4912-8efa-345678901234",
10750
+ name: "Klow",
10751
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10752
+ validUntil: null,
10753
+ externalId: "IkYcYBUcyY2"
10754
+ },
10755
+ {
10756
+ id: "2e5f6a7b-8c9d-4a23-8fab-456789012345",
10757
+ name: "Mbondo",
10758
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10759
+ validUntil: null,
10760
+ externalId: "Qhvv5hvo3mY"
10761
+ },
10762
+ {
10763
+ id: "3f6a7b8c-9d0e-4b34-8abc-567890123456",
10764
+ name: "Ndara",
10765
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10766
+ validUntil: null,
10767
+ externalId: "crXh068O9TR"
10768
+ },
10769
+ {
10770
+ id: "4a7b8c9d-0e1f-4c45-abcd-678901234567",
10771
+ name: "Olani",
10772
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10773
+ validUntil: null,
10774
+ externalId: "r00It8Tvvp7"
10775
+ },
10776
+ {
10777
+ id: "5b8c9d0e-1f2a-4d56-bcde-789012345678",
10778
+ name: "Pemba",
10779
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10780
+ validUntil: null,
10781
+ externalId: "ZnUWsbONIaH"
10782
+ },
10783
+ {
10784
+ id: "6c9d0e1f-2a3b-4e67-8def-890123456789",
10785
+ name: "Quanza",
10786
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10787
+ validUntil: null,
10788
+ externalId: "fDZycvQTa7l"
10789
+ },
10790
+ {
10791
+ id: "7d0e1f2a-3b4c-4f78-8efa-901234567890",
10792
+ name: "Rivka",
10793
+ parentId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10794
+ validUntil: null,
10795
+ externalId: "KqswxCGTELa"
10796
+ },
10797
+ // Villages under Isamba (967032fd-3f81-478a-826c-30cb8fe121bd)
10798
+ {
10799
+ id: "8e1f2a3b-4c5d-4089-8fab-012345678901",
10800
+ name: "Mbula",
10801
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10802
+ validUntil: null,
10803
+ externalId: "osEbKjRc9Kg"
10804
+ },
10805
+ {
10806
+ id: "9f2a3b4c-5d6e-4190-8abf-123456789012",
10807
+ name: "Ndoki",
10808
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10809
+ validUntil: null,
10810
+ externalId: "aq4daBUAGr3"
10811
+ },
10812
+ {
10813
+ id: "0a3b4c5d-6e7f-4201-abcd-234567890123",
10814
+ name: "Tsanga",
10815
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10816
+ validUntil: null,
10817
+ externalId: "cqis6Y8trbJ"
10818
+ },
10819
+ {
10820
+ id: "1b4c5d6e-7f8a-4312-bcde-345678901234",
10821
+ name: "Waziri",
10822
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10823
+ validUntil: null,
10824
+ externalId: "LMijHPyyx6d"
10825
+ },
10826
+ {
10827
+ id: "2c5d6e7f-8a9b-4423-8def-456789012345",
10828
+ name: "Zimbi",
10829
+ parentId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10830
+ validUntil: null,
10831
+ externalId: "pcQYbPuKGZ7"
10832
+ },
10833
+ // Villages under Itambo (89a33893-b17d-481d-a26d-6461e7ac1651)
10834
+ {
10835
+ id: "3d6e7f8a-9b0c-4534-8efa-567890123456",
10836
+ name: "Felani",
10837
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10838
+ validUntil: null,
10839
+ externalId: "gSqpoCGdMXp"
10840
+ },
10841
+ {
10842
+ id: "4e7f8a9b-0c1d-4645-8fab-678901234567",
10843
+ name: "Goroma",
10844
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10845
+ validUntil: null,
10846
+ externalId: "KvAAIaNqVrp"
10847
+ },
10848
+ {
10849
+ id: "5f8a9b0c-1d2e-4756-8abc-789012345678",
10850
+ name: "Halifu",
10851
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10852
+ validUntil: null,
10853
+ externalId: "qe4UnEVt1hv"
10854
+ },
10855
+ {
10856
+ id: "6a9b0c1d-2e3f-4867-abcd-890123456789",
10857
+ name: "Jabari",
10858
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10859
+ validUntil: null,
10860
+ externalId: "yHH9Nz4rLOt"
10861
+ },
10862
+ {
10863
+ id: "7b0c1d2e-3f4a-4978-bcde-901234567890",
10864
+ name: "Kifani",
10865
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10866
+ validUntil: null,
10867
+ externalId: "eSWmXIGeu1I"
10868
+ },
10869
+ {
10870
+ id: "8c1d2e3f-4a5b-4089-8def-012345678901",
10871
+ name: "Lumela",
10872
+ parentId: "89a33893-b17d-481d-a26d-6461e7ac1651",
10873
+ validUntil: null,
10874
+ externalId: "bh0b3aI1uP3"
10875
+ }
10876
+ ];
10877
+ var V2_DEFAULT_MOCK_LOCATIONS = [
10878
+ {
10879
+ id: "6f6186ce-cd5f-4a5f-810a-2d99e7c4ba12",
10880
+ name: "Central Provincial Office",
10881
+ locationType: "CRVS_OFFICE",
10882
+ administrativeAreaId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10883
+ validUntil: null,
10884
+ externalId: "Xr3Df8WpK6Ys"
10885
+ },
10886
+ {
10887
+ id: "b1c2d3e4-f5a6-7890-bcde-f12345678901",
10888
+ name: "Central Health Post",
10889
+ locationType: "HEALTH_FACILITY",
10890
+ administrativeAreaId: "a45b982a-5c7b-4bd9-8fd8-a42d0994054c",
10891
+ validUntil: null
10892
+ },
10893
+ {
10894
+ id: "028d2c85-ca31-426d-b5d1-2cef545a4902",
10895
+ name: "Ibombo District Office",
10896
+ locationType: "CRVS_OFFICE",
10897
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10898
+ validUntil: null,
10899
+ externalId: "Sm4Nw7GrD2Vy"
10900
+ },
10901
+ {
10902
+ id: "62a0ccb4-4f30-4f30-8882-f256007dff9f",
10903
+ name: "Isamba District Office",
10904
+ locationType: "CRVS_OFFICE",
10905
+ administrativeAreaId: "967032fd-3f81-478a-826c-30cb8fe121bd",
10906
+ validUntil: null,
10907
+ externalId: "Vg1Bq5XeH9Lt"
10908
+ },
10909
+ {
10910
+ id: "954c93e1-13f7-4435-bb82-35e0e215e07d",
10911
+ name: "Isango District Office",
10912
+ locationType: "CRVS_OFFICE",
10913
+ administrativeAreaId: "27160bbd-32d1-4625-812f-860226bfb92a",
10914
+ validUntil: null,
10915
+ externalId: "Je7Lm2XqN9Vz"
10916
+ },
10917
+ {
10918
+ id: "2884f5b9-17b4-49ce-bf4d-f538228935df",
10919
+ name: "Sulaka Provincial Office",
10920
+ locationType: "CRVS_OFFICE",
10921
+ administrativeAreaId: "c599b691-fd2d-45e1-abf4-d185de727fb5",
10922
+ validUntil: null,
10923
+ externalId: "Ht2Wp9KcX5Qv"
10924
+ },
10925
+ {
10926
+ id: "030358c6-54af-44be-821b-8e4af963a49c",
10927
+ name: "Ilanga District Office",
10928
+ locationType: "CRVS_OFFICE",
10929
+ administrativeAreaId: "8fbd09d2-212b-47f4-beb3-5e1694931d9f",
10930
+ validUntil: null,
10931
+ externalId: "Yp6Ds1WqN3Xz"
10932
+ },
10933
+ {
10934
+ id: "423d000f-101b-47c0-8b86-21a908067cee",
10935
+ name: "Chamakubi Health Post",
10936
+ locationType: "HEALTH_FACILITY",
10937
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10938
+ validUntil: null,
10939
+ externalId: "M1nFr8LbC2Qy"
10940
+ },
10941
+ {
10942
+ id: "4d3279be-d026-420c-88f7-f0a4ae986973",
10943
+ name: "Ibombo Rural Health Centre",
10944
+ locationType: "HEALTH_FACILITY",
10945
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10946
+ validUntil: null,
10947
+ externalId: "bT7pV6YrW0Xc"
10948
+ },
10949
+ {
10950
+ id: "190902f4-1d77-476a-8947-41145af1db7d",
10951
+ name: "Chikobo Rural Health Centre",
10952
+ locationType: "HEALTH_FACILITY",
10953
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10954
+ validUntil: null,
10955
+ externalId: "zE4qPn2SgJ5d"
10956
+ },
10957
+ {
10958
+ id: "f5ecbd9b-a01e-4a65-910e-70e86ab41b71",
10959
+ name: "Chilochabalenje Health Post",
10960
+ locationType: "HEALTH_FACILITY",
10961
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10962
+ validUntil: null,
10963
+ externalId: "H8vDs1MqR4Uf"
10964
+ },
10965
+ {
10966
+ id: "dbfc178f-7295-4b90-b28d-111c95b03127",
10967
+ name: "Chipeso Rural Health Centre",
10968
+ locationType: "HEALTH_FACILITY",
10969
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10970
+ validUntil: null,
10971
+ externalId: "Qw3uZ9KfX6Lm"
10972
+ },
10973
+ {
10974
+ id: "09862bfe-c7ac-46cd-987b-668681533c80",
10975
+ name: "Chisamba Rural Health Centre",
10976
+ locationType: "HEALTH_FACILITY",
10977
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10978
+ validUntil: null,
10979
+ externalId: "Yr0pCg8LdM2s"
10980
+ },
10981
+ {
10982
+ id: "834ce389-e95b-4fb0-96a0-33e9ab323059",
10983
+ name: "Chitanda Rural Health Centre",
10984
+ locationType: "HEALTH_FACILITY",
10985
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10986
+ validUntil: null,
10987
+ externalId: "tS9gJ4PwB1Qx"
10988
+ },
10989
+ {
10990
+ id: "0431c433-6062-4a4c-aee9-25271aec61ee",
10991
+ name: "Golden Valley Rural Health Centre",
10992
+ locationType: "HEALTH_FACILITY",
10993
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
10994
+ validUntil: null,
10995
+ externalId: "Ld7Qm3XsA8Vr"
10996
+ },
10997
+ {
10998
+ id: "bc84d0b6-7ba7-480d-a339-5d9920d90eb2",
10999
+ name: "Ipongo Rural Health Centre",
11000
+ locationType: "HEALTH_FACILITY",
11001
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
11002
+ validUntil: null,
11003
+ externalId: "kF2sW9DmH0Bt"
11004
+ },
11005
+ {
11006
+ id: "4cf1f53b-b730-41d2-8649-dff7eeed970d",
11007
+ name: "Itumbwe Health Post",
11008
+ locationType: "HEALTH_FACILITY",
11009
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
11010
+ validUntil: null,
11011
+ externalId: "Ue5Xb3VaC7Pq"
11012
+ },
11013
+ {
11014
+ id: "4b3676cb-9355-4942-9eb9-2ce46acaf0e0",
11015
+ name: "Kabangalala Rural Health Centre",
11016
+ locationType: "HEALTH_FACILITY",
11017
+ administrativeAreaId: "62a0ccb4-880d-4f30-8882-f256007dfff9",
11018
+ validUntil: null,
11019
+ externalId: "Pz8Kc1TqH6Jn"
11020
+ },
11021
+ // Village offices
11022
+ {
11023
+ id: "1f4a5b6c-7d8e-4312-8abc-345678901234",
11024
+ name: "Klow Village Office",
11025
+ locationType: "CRVS_OFFICE",
11026
+ administrativeAreaId: "1d4e5f6a-7b8c-4912-8efa-345678901234",
11027
+ validUntil: null,
11028
+ externalId: "PmAyxAJkxiJ"
11029
+ }
11030
+ ];
11031
+ var V2_DEFAULT_MOCK_LOCATIONS_MAP = new Map(
11032
+ V2_DEFAULT_MOCK_LOCATIONS.map((l) => [l.id, l])
11033
+ );
11034
+ var V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS_MAP = new Map(
11035
+ V2_DEFAULT_MOCK_ADMINISTRATIVE_AREAS.map((a) => [a.id, a])
11036
+ );