@opencrvs/toolkit 1.9.3-rc.866b278 → 1.9.3-rc.8e41e94

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.
@@ -153,6 +153,8 @@ __export(events_exports, {
153
153
  NonEmptyTextValue: () => NonEmptyTextValue,
154
154
  NotifyActionInput: () => NotifyActionInput,
155
155
  NumberFieldValue: () => NumberFieldValue,
156
+ NumberWithUnitFieldUpdateValue: () => NumberWithUnitFieldUpdateValue,
157
+ NumberWithUnitFieldValue: () => NumberWithUnitFieldValue,
156
158
  PageConfig: () => PageConfig,
157
159
  PageTypes: () => PageTypes,
158
160
  PotentialDuplicate: () => PotentialDuplicate,
@@ -330,6 +332,7 @@ __export(events_exports, {
330
332
  isNameFieldType: () => isNameFieldType,
331
333
  isNonInteractiveFieldType: () => isNonInteractiveFieldType,
332
334
  isNumberFieldType: () => isNumberFieldType,
335
+ isNumberWithUnitFieldType: () => isNumberWithUnitFieldType,
333
336
  isOfficeFieldType: () => isOfficeFieldType,
334
337
  isOnline: () => isOnline,
335
338
  isPageHeaderFieldType: () => isPageHeaderFieldType,
@@ -565,6 +568,7 @@ var FieldType = {
565
568
  ADDRESS: "ADDRESS",
566
569
  TEXT: "TEXT",
567
570
  NUMBER: "NUMBER",
571
+ NUMBER_WITH_UNIT: "NUMBER_WITH_UNIT",
568
572
  TEXTAREA: "TEXTAREA",
569
573
  EMAIL: "EMAIL",
570
574
  DATE: "DATE",
@@ -732,6 +736,14 @@ var ReadDataValue = import_zod6.z.object({
732
736
  });
733
737
  var QrReaderFieldValue = ReadDataValue;
734
738
  var IdReaderFieldValue = ReadDataValue;
739
+ var NumberWithUnitFieldValue = import_zod6.z.object({
740
+ numericValue: import_zod6.z.number(),
741
+ unit: import_zod6.z.string()
742
+ });
743
+ var NumberWithUnitFieldUpdateValue = import_zod6.z.object({
744
+ numericValue: import_zod6.z.number().optional(),
745
+ unit: import_zod6.z.string().optional()
746
+ });
735
747
 
736
748
  // ../commons/src/events/FieldValue.ts
737
749
  var TextValue = import_zod7.z.string();
@@ -786,7 +798,9 @@ var FieldValuesWithoutDataField = import_zod7.z.union([
786
798
  VerificationStatusValue,
787
799
  QueryParamReaderFieldValue,
788
800
  QrReaderFieldValue,
789
- IdReaderFieldValue
801
+ IdReaderFieldValue,
802
+ NumberWithUnitFieldValue,
803
+ NumberWithUnitFieldUpdateValue
790
804
  ]);
791
805
  var DataFieldValue = import_zod7.z.object({
792
806
  data: import_zod7.z.record(import_zod7.z.string(), FieldValuesWithoutDataField)
@@ -806,6 +820,7 @@ var PRIORITY_ORDER = [
806
820
  "SelectDateRangeValue",
807
821
  "CheckboxFieldValue",
808
822
  "NumberFieldValue",
823
+ "NumberWithUnitFieldUpdateValue",
809
824
  "FileFieldValue",
810
825
  "FileFieldWithOptionValue",
811
826
  "DataFieldValue"
@@ -839,6 +854,7 @@ var FieldUpdateValue = safeUnion([
839
854
  SelectDateRangeValue.describe("SelectDateRangeValue"),
840
855
  CheckboxFieldValue.describe("CheckboxFieldValue"),
841
856
  NumberFieldValue.describe("NumberFieldValue"),
857
+ NumberWithUnitFieldUpdateValue.describe("NumberWithUnitFieldUpdateValue"),
842
858
  FileFieldValue.describe("FileFieldValue"),
843
859
  FileFieldWithOptionValue.describe("FileFieldWithOptionValue"),
844
860
  DataFieldValue.describe("DataFieldValue"),
@@ -2098,6 +2114,18 @@ var SelectOption = import_zod15.z.object({
2098
2114
  value: import_zod15.z.string().describe("The value of the option"),
2099
2115
  label: import_zod15.z.union([import_zod15.z.string(), TranslationConfig]).describe("The label of the option")
2100
2116
  });
2117
+ var NumberWithUnitField = BaseField.extend({
2118
+ type: import_zod15.z.literal(FieldType.NUMBER_WITH_UNIT),
2119
+ defaultValue: NumberWithUnitFieldValue.optional(),
2120
+ options: import_zod15.z.array(SelectOption).describe("A list of options for the unit select"),
2121
+ configuration: import_zod15.z.object({
2122
+ min: import_zod15.z.number().optional().describe("Minimum value of the number field"),
2123
+ max: import_zod15.z.number().optional().describe("Maximum value of the number field"),
2124
+ numberFieldPlaceholder: TranslationConfig.optional().describe(
2125
+ "Placeholder for the number field"
2126
+ )
2127
+ }).optional()
2128
+ }).describe("Number with unit input");
2101
2129
  var RadioGroup = BaseField.extend({
2102
2130
  type: import_zod15.z.literal(FieldType.RADIO_GROUP),
2103
2131
  defaultValue: TextValue.optional(),
@@ -2386,6 +2414,7 @@ var FieldConfig = import_zod15.z.discriminatedUnion("type", [
2386
2414
  Address,
2387
2415
  TextField,
2388
2416
  NumberField,
2417
+ NumberWithUnitField,
2389
2418
  TextAreaField,
2390
2419
  AgeField,
2391
2420
  DateField,
@@ -2955,6 +2984,9 @@ function mapFieldTypeToZod(field3, actionType) {
2955
2984
  case FieldType.NUMBER:
2956
2985
  schema = NumberFieldValue;
2957
2986
  break;
2987
+ case FieldType.NUMBER_WITH_UNIT:
2988
+ schema = NumberWithUnitFieldUpdateValue;
2989
+ break;
2958
2990
  case FieldType.CHECKBOX:
2959
2991
  schema = CheckboxFieldValue;
2960
2992
  break;
@@ -3012,6 +3044,7 @@ function mapFieldTypeToEmptyValue(field3) {
3012
3044
  case FieldType.FACILITY:
3013
3045
  case FieldType.OFFICE:
3014
3046
  case FieldType.NUMBER:
3047
+ case FieldType.NUMBER_WITH_UNIT:
3015
3048
  case FieldType.EMAIL:
3016
3049
  case FieldType.DATE:
3017
3050
  case FieldType.AGE:
@@ -3079,6 +3112,9 @@ var isTextFieldType = (field3) => {
3079
3112
  var isNumberFieldType = (field3) => {
3080
3113
  return field3.config.type === FieldType.NUMBER;
3081
3114
  };
3115
+ var isNumberWithUnitFieldType = (field3) => {
3116
+ return field3.config.type === FieldType.NUMBER_WITH_UNIT;
3117
+ };
3082
3118
  var isNameFieldType = (field3) => {
3083
3119
  return field3.config.type === FieldType.NAME;
3084
3120
  };
@@ -3185,9 +3221,30 @@ var DataContext = import_zod25.z.object({
3185
3221
  $leafAdminStructureLocationIds: import_zod25.z.array(import_zod25.z.object({ id: UUID }))
3186
3222
  })
3187
3223
  });
3224
+ function resolveDataPath(rootData, dataPath, instancePath) {
3225
+ const pathParts = dataPath.split("/");
3226
+ const levels = parseInt(pathParts[0], 10);
3227
+ const referencePath = pathParts.slice(1);
3228
+ const instanceParts = instancePath.split("/").filter(Boolean);
3229
+ const traversedParts = instanceParts.slice(0, -levels);
3230
+ let current = rootData;
3231
+ for (const part of traversedParts) {
3232
+ if (current === null || current === void 0) {
3233
+ return void 0;
3234
+ }
3235
+ current = current[part];
3236
+ }
3237
+ for (const part of referencePath) {
3238
+ if (current === null || current === void 0) {
3239
+ return void 0;
3240
+ }
3241
+ current = current[part];
3242
+ }
3243
+ return current;
3244
+ }
3188
3245
  (0, import_ajv_formats.default)(ajv);
3189
3246
  ajv.addKeyword({
3190
- keyword: "daysFromNow",
3247
+ keyword: "daysFromDate",
3191
3248
  type: "string",
3192
3249
  schemaType: "object",
3193
3250
  $data: true,
@@ -3204,8 +3261,22 @@ ajv.addKeyword({
3204
3261
  if (isNaN(date.getTime())) {
3205
3262
  return false;
3206
3263
  }
3207
- const now = new Date(dataContext.rootData.$now);
3208
- const offsetDate = new Date(now.getTime() + days * 24 * 60 * 60 * 1e3);
3264
+ let referenceDate = schema.referenceDate;
3265
+ if (referenceDate && typeof referenceDate === "object" && "$data" in referenceDate) {
3266
+ referenceDate = resolveDataPath(
3267
+ dataContext.rootData,
3268
+ referenceDate.$data,
3269
+ dataContext.instancePath
3270
+ );
3271
+ }
3272
+ if (!referenceDate) {
3273
+ referenceDate = dataContext.rootData.$now;
3274
+ }
3275
+ const baseDate = new Date(referenceDate);
3276
+ if (isNaN(baseDate.getTime())) {
3277
+ return false;
3278
+ }
3279
+ const offsetDate = new Date(baseDate.getTime() + days * 24 * 60 * 60 * 1e3);
3209
3280
  return clause === "after" ? (0, import_date_fns.isAfter)(date, offsetDate) : (0, import_date_fns.isBefore)(date, offsetDate);
3210
3281
  }
3211
3282
  });
@@ -3268,7 +3339,8 @@ function isConditionMet(conditional, values, context) {
3268
3339
  $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3269
3340
  $online: isOnline(),
3270
3341
  $user: context.user,
3271
- $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? []
3342
+ $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? [],
3343
+ $event: context.event
3272
3344
  });
3273
3345
  }
3274
3346
  function getConditionalActionsForField(field3, values) {
@@ -3294,7 +3366,8 @@ function isFieldConditionMet(field3, form, conditionalType, context) {
3294
3366
  $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3295
3367
  $online: isOnline(),
3296
3368
  $user: context.user,
3297
- $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? []
3369
+ $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? [],
3370
+ $event: context.event
3298
3371
  });
3299
3372
  return validConditionals.includes(conditionalType);
3300
3373
  }
@@ -4116,6 +4189,34 @@ function getDateRangeToFieldReference(field3, comparedField, clause) {
4116
4189
  required: [field3.$$field]
4117
4190
  };
4118
4191
  }
4192
+ function getDayRangeToFieldReference(field3, comparedField, days, clause) {
4193
+ return {
4194
+ type: "object",
4195
+ properties: {
4196
+ [field3.$$field]: wrapToPath(
4197
+ {
4198
+ type: "string",
4199
+ format: "date",
4200
+ daysFromDate: {
4201
+ referenceDate: {
4202
+ $data: `${field3.$$subfield.length + 1}/${jsonFieldPath(
4203
+ comparedField
4204
+ )}`
4205
+ },
4206
+ clause,
4207
+ days
4208
+ }
4209
+ },
4210
+ field3.$$subfield
4211
+ ),
4212
+ [comparedField.$$field]: wrapToPath(
4213
+ { type: "string", format: "date" },
4214
+ comparedField.$$subfield
4215
+ )
4216
+ },
4217
+ required: [field3.$$field]
4218
+ };
4219
+ }
4119
4220
  function defineComparison(field3, value, keyword) {
4120
4221
  if (isFieldReference(value)) {
4121
4222
  const comparedField = value;
@@ -4151,16 +4252,17 @@ function defineComparison(field3, value, keyword) {
4151
4252
  });
4152
4253
  }
4153
4254
  function createFieldConditionals(fieldId) {
4154
- const getDayRange = (field3, days, clause) => ({
4255
+ const getDayRange = (field3, days, clause, referenceDate) => ({
4155
4256
  type: "object",
4156
4257
  properties: {
4157
4258
  [field3.$$field]: wrapToPath(
4158
4259
  {
4159
4260
  type: "string",
4160
4261
  format: "date",
4161
- daysFromNow: {
4262
+ daysFromDate: {
4162
4263
  days,
4163
- clause
4264
+ clause,
4265
+ referenceDate
4164
4266
  }
4165
4267
  },
4166
4268
  field3.$$subfield
@@ -4213,7 +4315,19 @@ function createFieldConditionals(fieldId) {
4213
4315
  return {
4214
4316
  days: (days) => ({
4215
4317
  inPast: () => defineFormConditional(getDayRange(this, -days, "after")),
4216
- inFuture: () => defineFormConditional(getDayRange(this, days, "after"))
4318
+ inFuture: () => defineFormConditional(getDayRange(this, days, "after")),
4319
+ fromDate: (date) => {
4320
+ if (isFieldReference(date)) {
4321
+ const comparedField = date;
4322
+ return defineFormConditional(
4323
+ getDayRangeToFieldReference(this, comparedField, days, "after")
4324
+ );
4325
+ }
4326
+ return defineFormConditional(getDayRange(this, days, "after", date));
4327
+ },
4328
+ fromNow: () => {
4329
+ return defineFormConditional(getDayRange(this, days, "after"));
4330
+ }
4217
4331
  }),
4218
4332
  date: (date) => {
4219
4333
  if (isFieldReference(date)) {
@@ -4235,7 +4349,26 @@ function createFieldConditionals(fieldId) {
4235
4349
  return {
4236
4350
  days: (days) => ({
4237
4351
  inPast: () => defineFormConditional(getDayRange(this, -days, "before")),
4238
- inFuture: () => defineFormConditional(getDayRange(this, days, "before"))
4352
+ inFuture: () => defineFormConditional(getDayRange(this, days, "before")),
4353
+ fromDate: (date) => {
4354
+ if (isFieldReference(date)) {
4355
+ const comparedField = date;
4356
+ return defineFormConditional(
4357
+ getDayRangeToFieldReference(
4358
+ this,
4359
+ comparedField,
4360
+ -days,
4361
+ "before"
4362
+ )
4363
+ );
4364
+ }
4365
+ return defineFormConditional(
4366
+ getDayRange(this, -days, "before", date)
4367
+ );
4368
+ },
4369
+ fromNow: () => {
4370
+ return defineFormConditional(getDayRange(this, -days, "before"));
4371
+ }
4239
4372
  }),
4240
4373
  date: (date) => {
4241
4374
  if (isFieldReference(date)) {
@@ -5558,6 +5691,7 @@ var PRINT_CERTIFICATE_FORM = defineActionForm({
5558
5691
  {
5559
5692
  id: "collector",
5560
5693
  type: PageTypes.enum.FORM,
5694
+ requireCompletionToContinue: true,
5561
5695
  title: {
5562
5696
  id: "event.tennis-club-membership.action.certificate.form.section.who.title",
5563
5697
  defaultMessage: "Print certified copy",
@@ -6165,6 +6299,7 @@ var PRINT_CERTIFICATE_FORM = defineActionForm({
6165
6299
  {
6166
6300
  id: "collector.identity.verify",
6167
6301
  type: PageTypes.enum.VERIFICATION,
6302
+ requireCompletionToContinue: true,
6168
6303
  conditional: field("collector.requesterId").isEqualTo("INFORMANT"),
6169
6304
  title: {
6170
6305
  id: "event.tennis-club-membership.action.print.verifyIdentity",
@@ -7763,6 +7898,220 @@ var v2BirthEvent = defineConfig({
7763
7898
  advancedSearch: []
7764
7899
  });
7765
7900
 
7901
+ // ../commons/src/fixtures/digital-identity-issuance-event.ts
7902
+ var PRINT_DIGITAL_ID_CERTIFICATE_FORM = defineActionForm({
7903
+ label: {
7904
+ id: "event.digital-identity.action.certificate.form.label",
7905
+ defaultMessage: "Digital identity certificate printer",
7906
+ description: "This is what this form is referred as in the system"
7907
+ },
7908
+ pages: [
7909
+ {
7910
+ id: "collector",
7911
+ type: PageTypes.enum.FORM,
7912
+ title: {
7913
+ id: "event.tennis-club-membership.action.certificate.form.section.who.title",
7914
+ defaultMessage: "Print certified copy",
7915
+ description: "This is the title of the section"
7916
+ },
7917
+ fields: [
7918
+ {
7919
+ id: "identity.http-fetch",
7920
+ type: FieldType.HTTP,
7921
+ label: {
7922
+ defaultMessage: "Digital identity certificate",
7923
+ description: "Fetch printable digital identity certificate",
7924
+ id: "event.digital-identity.certificate.fetch.label"
7925
+ },
7926
+ configuration: {
7927
+ trigger: field("identity.http-button"),
7928
+ url: "/api/digital-identity/certificate",
7929
+ timeout: 5e3,
7930
+ method: "POST",
7931
+ headers: {
7932
+ "Content-Type": "application/json"
7933
+ },
7934
+ body: {
7935
+ subjectId: "$event.subject.id"
7936
+ }
7937
+ }
7938
+ },
7939
+ {
7940
+ id: "identity.http-button",
7941
+ type: FieldType.BUTTON,
7942
+ label: {
7943
+ defaultMessage: "Certificate",
7944
+ description: "Certificate",
7945
+ id: "event.digital-identity.certificate.button.label"
7946
+ },
7947
+ conditionals: [
7948
+ {
7949
+ type: ConditionalType.ENABLE,
7950
+ conditional: and(
7951
+ field("identity.http-fetch").isUndefined(),
7952
+ user.isOnline()
7953
+ )
7954
+ },
7955
+ {
7956
+ type: ConditionalType.SHOW,
7957
+ conditional: and(
7958
+ field("identity.http-fetch").get("loading").isFalsy(),
7959
+ field("identity.http-fetch").get("data").isFalsy()
7960
+ )
7961
+ }
7962
+ ],
7963
+ configuration: {
7964
+ icon: "IdentificationCard",
7965
+ text: {
7966
+ defaultMessage: "Fetch certificate",
7967
+ description: "Fetch certificate",
7968
+ id: "event.digital-identity.certificate.fetch.text"
7969
+ }
7970
+ }
7971
+ },
7972
+ {
7973
+ id: "identity.http-button",
7974
+ type: FieldType.BUTTON,
7975
+ label: {
7976
+ defaultMessage: "Certificate",
7977
+ description: "Certificate",
7978
+ id: "event.digital-identity.certificate.button.label"
7979
+ },
7980
+ conditionals: [
7981
+ {
7982
+ type: ConditionalType.ENABLE,
7983
+ conditional: never()
7984
+ },
7985
+ {
7986
+ type: ConditionalType.SHOW,
7987
+ conditional: field("identity.http-fetch").get("loading").isEqualTo(true)
7988
+ }
7989
+ ],
7990
+ configuration: {
7991
+ loading: true,
7992
+ text: {
7993
+ defaultMessage: "Fetching certificate\u2026",
7994
+ description: "Fetching certificate\u2026",
7995
+ id: "event.digital-identity.certificate.fetching.text"
7996
+ }
7997
+ }
7998
+ },
7999
+ {
8000
+ id: "identity.http-button",
8001
+ type: FieldType.BUTTON,
8002
+ label: {
8003
+ defaultMessage: "Certificate",
8004
+ description: "Certificate",
8005
+ id: "event.digital-identity.certificate.button.label"
8006
+ },
8007
+ conditionals: [
8008
+ {
8009
+ type: ConditionalType.ENABLE,
8010
+ conditional: never()
8011
+ },
8012
+ {
8013
+ type: ConditionalType.SHOW,
8014
+ conditional: not(field("identity.certificateId").isFalsy())
8015
+ }
8016
+ ],
8017
+ configuration: {
8018
+ icon: "Check",
8019
+ text: {
8020
+ defaultMessage: "Certificate ready",
8021
+ description: "Certificate ready",
8022
+ id: "event.digital-identity.certificate.ready.text"
8023
+ }
8024
+ }
8025
+ },
8026
+ {
8027
+ id: "identity.certificateId",
8028
+ type: FieldType.TEXT,
8029
+ parent: field("identity.http-fetch"),
8030
+ label: {
8031
+ defaultMessage: "Certificate ID",
8032
+ description: "Issued digital identity certificate identifier",
8033
+ id: "event.digital-identity.certificate.id.label"
8034
+ },
8035
+ conditionals: [
8036
+ {
8037
+ type: ConditionalType.ENABLE,
8038
+ conditional: never()
8039
+ }
8040
+ ],
8041
+ value: field("identity.http-fetch").get("data.certificateId")
8042
+ }
8043
+ ]
8044
+ }
8045
+ ]
8046
+ });
8047
+ var digitalIdentityForm = defineDeclarationForm({
8048
+ label: {
8049
+ id: "event.digital-identity.action.declare.form.label",
8050
+ defaultMessage: "Digital identity issuance",
8051
+ description: "This is what this form is referred as in the system"
8052
+ },
8053
+ pages: [
8054
+ {
8055
+ id: "subject",
8056
+ title: {
8057
+ id: "event.digital-identity.action.declare.form.section.who.title",
8058
+ defaultMessage: "Who is the digital identity issued to?",
8059
+ description: "This is the title of the section"
8060
+ },
8061
+ fields: [
8062
+ {
8063
+ id: "subject.firstname",
8064
+ type: FieldType.TEXT,
8065
+ required: true,
8066
+ conditionals: [],
8067
+ label: {
8068
+ defaultMessage: "Subject's first name",
8069
+ description: "This is the label for the field",
8070
+ id: "event.digital-identity.action.declare.form.section.who.field.firstname.label"
8071
+ }
8072
+ },
8073
+ {
8074
+ id: "subject.surname",
8075
+ type: FieldType.TEXT,
8076
+ required: true,
8077
+ conditionals: [],
8078
+ label: {
8079
+ defaultMessage: "Subject's surname",
8080
+ description: "This is the label for the field",
8081
+ id: "event.digital-identity.action.declare.form.section.who.field.surname.label"
8082
+ }
8083
+ }
8084
+ ]
8085
+ }
8086
+ ]
8087
+ });
8088
+ var digitalIdentityEvent = defineConfig({
8089
+ id: "digital-identity",
8090
+ label: {
8091
+ defaultMessage: "Digital identity issuance",
8092
+ description: "This is what this event is referred as in the system",
8093
+ id: "event.digital-identity.label"
8094
+ },
8095
+ title: {
8096
+ defaultMessage: "{subject.firstname} {subject.surname}",
8097
+ description: "This is the title of the summary",
8098
+ id: "event.digital-identity.title"
8099
+ },
8100
+ summary: { fields: [] },
8101
+ actions: [
8102
+ {
8103
+ type: ActionType.PRINT_CERTIFICATE,
8104
+ label: {
8105
+ id: "event.football-club-membership.action.collect-certificate.label",
8106
+ defaultMessage: "Print certificate",
8107
+ description: "This is shown as the action name anywhere the user can trigger the action from"
8108
+ },
8109
+ printForm: PRINT_DIGITAL_ID_CERTIFICATE_FORM
8110
+ }
8111
+ ],
8112
+ declaration: digitalIdentityForm
8113
+ });
8114
+
7766
8115
  // ../commons/src/events/test.utils.ts
7767
8116
  var import_zod35 = require("zod");
7768
8117
  var TEST_SYSTEM_IANA_TIMEZONE = "Asia/Dhaka";
@@ -7862,6 +8211,11 @@ function mapFieldTypeToMockValue(field3, i, rng) {
7862
8211
  return generateRandomName(rng);
7863
8212
  case FieldType.NUMBER:
7864
8213
  return 19;
8214
+ case FieldType.NUMBER_WITH_UNIT:
8215
+ return {
8216
+ numericValue: 42,
8217
+ unit: "Hours"
8218
+ };
7865
8219
  case FieldType.BUTTON:
7866
8220
  return 1;
7867
8221
  case FieldType.EMAIL: