@ecrvs/opencrvs-toolkit 1.9.0-rc.2c621d0 → 1.9.0-rc.47deb60

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.
@@ -133,6 +133,7 @@ export declare function createFieldConditionals(fieldId: string): {
133
133
  isLessThan(value: number | FieldReference): JSONSchema;
134
134
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
135
135
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
136
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
136
137
  isAbbreviation(): JSONSchema;
137
138
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
138
139
  /**
@@ -191,6 +192,7 @@ export declare function createFieldConditionals(fieldId: string): {
191
192
  isLessThan(value: number | FieldReference): JSONSchema;
192
193
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
193
194
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
195
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
194
196
  isAbbreviation(): JSONSchema;
195
197
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
196
198
  /**
@@ -263,6 +265,7 @@ export declare function createFieldConditionals(fieldId: string): {
263
265
  isLessThan(value: number | FieldReference): JSONSchema;
264
266
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
265
267
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
268
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
266
269
  isAbbreviation(): JSONSchema;
267
270
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
268
271
  /**
@@ -330,6 +333,7 @@ export declare function createFieldConditionals(fieldId: string): {
330
333
  isLessThan(value: number | FieldReference): JSONSchema;
331
334
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
332
335
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
336
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
333
337
  isAbbreviation(): JSONSchema;
334
338
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
335
339
  /**
@@ -396,6 +400,7 @@ export declare function createFieldConditionals(fieldId: string): {
396
400
  isLessThan(value: number | FieldReference): JSONSchema;
397
401
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
398
402
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
403
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
399
404
  isAbbreviation(): JSONSchema;
400
405
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
401
406
  /**
@@ -452,6 +457,7 @@ export declare function createFieldConditionals(fieldId: string): {
452
457
  isLessThan(value: number | FieldReference): JSONSchema;
453
458
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
454
459
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
460
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
455
461
  isAbbreviation(): JSONSchema;
456
462
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
457
463
  /**
@@ -525,6 +531,7 @@ export declare function createFieldConditionals(fieldId: string): {
525
531
  isLessThan(value: number | FieldReference): JSONSchema;
526
532
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
527
533
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
534
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
528
535
  isAbbreviation(): JSONSchema;
529
536
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
530
537
  /**
@@ -583,6 +590,7 @@ export declare function createFieldConditionals(fieldId: string): {
583
590
  isLessThan(value: number | FieldReference): JSONSchema;
584
591
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
585
592
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
593
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
586
594
  isAbbreviation(): JSONSchema;
587
595
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
588
596
  /**
@@ -656,6 +664,7 @@ export declare function createFieldConditionals(fieldId: string): {
656
664
  isLessThan(value: number | FieldReference): JSONSchema;
657
665
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
658
666
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
667
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
659
668
  isAbbreviation(): JSONSchema;
660
669
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
661
670
  /**
@@ -714,6 +723,7 @@ export declare function createFieldConditionals(fieldId: string): {
714
723
  isLessThan(value: number | FieldReference): JSONSchema;
715
724
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
716
725
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
726
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
717
727
  isAbbreviation(): JSONSchema;
718
728
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
719
729
  /**
@@ -770,6 +780,7 @@ export declare function createFieldConditionals(fieldId: string): {
770
780
  isLessThan(value: number | FieldReference): JSONSchema;
771
781
  isEqualTo(value: string | boolean | number | FieldReference): JSONSchema;
772
782
  isEqualToSumOf(val1: FieldReference, val2: FieldReference): JSONSchema;
783
+ isValidDeceasedAge(dobField: FieldReference, dodField: FieldReference, todField: FieldReference, format: "years" | "months" | "days" | "hours" | "minutes"): JSONSchema;
773
784
  isAbbreviation(): JSONSchema;
774
785
  isIllDefined(causesOfDeathFields: FieldReference[], threshold: number): JSONSchema;
775
786
  /**
@@ -7,6 +7,7 @@ import { TranslationConfig } from '../events/TranslationConfig';
7
7
  import { ITokenPayload } from '../authentication';
8
8
  import { UUID } from '../uuid';
9
9
  import { ActionType } from '../client';
10
+ export declare const isValidDateFormat: (date: string) => boolean;
10
11
  export declare function validate(schema: JSONSchema, data: ConditionalParameters): boolean;
11
12
  export declare function validateValue(schema: JSONSchema, data: unknown): boolean;
12
13
  export declare function isOnline(): boolean;
@@ -120,8 +120,8 @@ declare const DateRangeMatcher: z.ZodObject<z.objectUtil.extendShape<{
120
120
  days: z.ZodNumber;
121
121
  boost: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
122
122
  }, "strip", z.ZodTypeAny, {
123
- boost: number;
124
123
  days: number;
124
+ boost: number;
125
125
  pivot?: number | undefined;
126
126
  }, {
127
127
  days: number;
@@ -131,8 +131,8 @@ declare const DateRangeMatcher: z.ZodObject<z.objectUtil.extendShape<{
131
131
  }>, "strip", z.ZodTypeAny, {
132
132
  type: "dateRange";
133
133
  options: {
134
- boost: number;
135
134
  days: number;
135
+ boost: number;
136
136
  pivot?: number | undefined;
137
137
  };
138
138
  fieldId: string;
@@ -114,6 +114,16 @@ export declare function field(fieldId: string, options?: {
114
114
  $$field: string;
115
115
  $$subfield: string[];
116
116
  }): import("../conditionals/conditionals").JSONSchema;
117
+ isValidDeceasedAge(dobField: {
118
+ $$field: string;
119
+ $$subfield: string[];
120
+ }, dodField: {
121
+ $$field: string;
122
+ $$subfield: string[];
123
+ }, todField: {
124
+ $$field: string;
125
+ $$subfield: string[];
126
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
117
127
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
118
128
  isIllDefined(causesOfDeathFields: {
119
129
  $$field: string;
@@ -174,6 +184,16 @@ export declare function field(fieldId: string, options?: {
174
184
  $$field: string;
175
185
  $$subfield: string[];
176
186
  }): import("../conditionals/conditionals").JSONSchema;
187
+ isValidDeceasedAge(dobField: {
188
+ $$field: string;
189
+ $$subfield: string[];
190
+ }, dodField: {
191
+ $$field: string;
192
+ $$subfield: string[];
193
+ }, todField: {
194
+ $$field: string;
195
+ $$subfield: string[];
196
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
177
197
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
178
198
  isIllDefined(causesOfDeathFields: {
179
199
  $$field: string;
@@ -242,6 +262,16 @@ export declare function field(fieldId: string, options?: {
242
262
  $$field: string;
243
263
  $$subfield: string[];
244
264
  }): import("../conditionals/conditionals").JSONSchema;
265
+ isValidDeceasedAge(dobField: {
266
+ $$field: string;
267
+ $$subfield: string[];
268
+ }, dodField: {
269
+ $$field: string;
270
+ $$subfield: string[];
271
+ }, todField: {
272
+ $$field: string;
273
+ $$subfield: string[];
274
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
245
275
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
246
276
  isIllDefined(causesOfDeathFields: {
247
277
  $$field: string;
@@ -308,6 +338,16 @@ export declare function field(fieldId: string, options?: {
308
338
  $$field: string;
309
339
  $$subfield: string[];
310
340
  }): import("../conditionals/conditionals").JSONSchema;
341
+ isValidDeceasedAge(dobField: {
342
+ $$field: string;
343
+ $$subfield: string[];
344
+ }, dodField: {
345
+ $$field: string;
346
+ $$subfield: string[];
347
+ }, todField: {
348
+ $$field: string;
349
+ $$subfield: string[];
350
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
311
351
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
312
352
  isIllDefined(causesOfDeathFields: {
313
353
  $$field: string;
@@ -373,6 +413,16 @@ export declare function field(fieldId: string, options?: {
373
413
  $$field: string;
374
414
  $$subfield: string[];
375
415
  }): import("../conditionals/conditionals").JSONSchema;
416
+ isValidDeceasedAge(dobField: {
417
+ $$field: string;
418
+ $$subfield: string[];
419
+ }, dodField: {
420
+ $$field: string;
421
+ $$subfield: string[];
422
+ }, todField: {
423
+ $$field: string;
424
+ $$subfield: string[];
425
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
376
426
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
377
427
  isIllDefined(causesOfDeathFields: {
378
428
  $$field: string;
@@ -431,6 +481,16 @@ export declare function field(fieldId: string, options?: {
431
481
  $$field: string;
432
482
  $$subfield: string[];
433
483
  }): import("../conditionals/conditionals").JSONSchema;
484
+ isValidDeceasedAge(dobField: {
485
+ $$field: string;
486
+ $$subfield: string[];
487
+ }, dodField: {
488
+ $$field: string;
489
+ $$subfield: string[];
490
+ }, todField: {
491
+ $$field: string;
492
+ $$subfield: string[];
493
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
434
494
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
435
495
  isIllDefined(causesOfDeathFields: {
436
496
  $$field: string;
@@ -500,6 +560,16 @@ export declare function field(fieldId: string, options?: {
500
560
  $$field: string;
501
561
  $$subfield: string[];
502
562
  }): import("../conditionals/conditionals").JSONSchema;
563
+ isValidDeceasedAge(dobField: {
564
+ $$field: string;
565
+ $$subfield: string[];
566
+ }, dodField: {
567
+ $$field: string;
568
+ $$subfield: string[];
569
+ }, todField: {
570
+ $$field: string;
571
+ $$subfield: string[];
572
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
503
573
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
504
574
  isIllDefined(causesOfDeathFields: {
505
575
  $$field: string;
@@ -560,6 +630,16 @@ export declare function field(fieldId: string, options?: {
560
630
  $$field: string;
561
631
  $$subfield: string[];
562
632
  }): import("../conditionals/conditionals").JSONSchema;
633
+ isValidDeceasedAge(dobField: {
634
+ $$field: string;
635
+ $$subfield: string[];
636
+ }, dodField: {
637
+ $$field: string;
638
+ $$subfield: string[];
639
+ }, todField: {
640
+ $$field: string;
641
+ $$subfield: string[];
642
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
563
643
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
564
644
  isIllDefined(causesOfDeathFields: {
565
645
  $$field: string;
@@ -629,6 +709,16 @@ export declare function field(fieldId: string, options?: {
629
709
  $$field: string;
630
710
  $$subfield: string[];
631
711
  }): import("../conditionals/conditionals").JSONSchema;
712
+ isValidDeceasedAge(dobField: {
713
+ $$field: string;
714
+ $$subfield: string[];
715
+ }, dodField: {
716
+ $$field: string;
717
+ $$subfield: string[];
718
+ }, todField: {
719
+ $$field: string;
720
+ $$subfield: string[];
721
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
632
722
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
633
723
  isIllDefined(causesOfDeathFields: {
634
724
  $$field: string;
@@ -689,6 +779,16 @@ export declare function field(fieldId: string, options?: {
689
779
  $$field: string;
690
780
  $$subfield: string[];
691
781
  }): import("../conditionals/conditionals").JSONSchema;
782
+ isValidDeceasedAge(dobField: {
783
+ $$field: string;
784
+ $$subfield: string[];
785
+ }, dodField: {
786
+ $$field: string;
787
+ $$subfield: string[];
788
+ }, todField: {
789
+ $$field: string;
790
+ $$subfield: string[];
791
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
692
792
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
693
793
  isIllDefined(causesOfDeathFields: {
694
794
  $$field: string;
@@ -747,6 +847,16 @@ export declare function field(fieldId: string, options?: {
747
847
  $$field: string;
748
848
  $$subfield: string[];
749
849
  }): import("../conditionals/conditionals").JSONSchema;
850
+ isValidDeceasedAge(dobField: {
851
+ $$field: string;
852
+ $$subfield: string[];
853
+ }, dodField: {
854
+ $$field: string;
855
+ $$subfield: string[];
856
+ }, todField: {
857
+ $$field: string;
858
+ $$subfield: string[];
859
+ }, format: "years" | "months" | "days" | "hours" | "minutes"): import("../conditionals/conditionals").JSONSchema;
750
860
  isAbbreviation(): import("../conditionals/conditionals").JSONSchema;
751
861
  isIllDefined(causesOfDeathFields: {
752
862
  $$field: string;
@@ -437,18 +437,39 @@ function createFieldConditionals(fieldId) {
437
437
  return defineFormConditional({
438
438
  type: "object",
439
439
  properties: {
440
- [fieldId]: { type: "number" },
440
+ [this.$$field]: { type: "number" },
441
441
  [field1Id]: { type: "number" },
442
442
  [field2Id]: { type: "number" }
443
443
  },
444
- required: [fieldId, field1Id, field2Id],
444
+ required: [this.$$field, field1Id, field2Id],
445
445
  sumOf: {
446
- sum: fieldId,
446
+ sum: this.$$field,
447
447
  field1: field1Id,
448
448
  field2: field2Id
449
449
  }
450
450
  });
451
451
  },
452
+ isValidDeceasedAge(dobField, dodField, todField, format) {
453
+ const dobFieldId = dobField.$$field;
454
+ const dodFieldId = dodField.$$field;
455
+ const todFieldId = todField.$$field;
456
+ return defineFormConditional({
457
+ type: "object",
458
+ properties: {
459
+ [this.$$field]: { type: "number" },
460
+ [dobFieldId]: { type: "string" },
461
+ [dodFieldId]: { type: "string" },
462
+ [todFieldId]: { type: "string" }
463
+ },
464
+ isValidAgeOfDeceased: {
465
+ ageField: this.$$field,
466
+ dateOfBirthField: dobFieldId,
467
+ deathDateField: dodFieldId,
468
+ deathTimeField: todFieldId,
469
+ format
470
+ }
471
+ });
472
+ },
452
473
  isAbbreviation() {
453
474
  return defineFormConditional({
454
475
  type: "object",
@@ -349,6 +349,7 @@ __export(events_exports, {
349
349
  isTextFieldType: () => isTextFieldType,
350
350
  isTimeFieldType: () => isTimeFieldType,
351
351
  isUndeclaredDraft: () => isUndeclaredDraft,
352
+ isValidDateFormat: () => isValidDateFormat,
352
353
  isVerificationPage: () => isVerificationPage,
353
354
  isVerificationStatusType: () => isVerificationStatusType,
354
355
  isWriteAction: () => isWriteAction,
@@ -4404,6 +4405,72 @@ ajv.addKeyword({
4404
4405
  return locations.some((location) => location.id === locationIdInput);
4405
4406
  }
4406
4407
  });
4408
+ var datePattern = /^\d{4}-\d{1,2}-\d{1,2}$/;
4409
+ var isValidDateFormat = (date) => {
4410
+ if (!datePattern.test(date)) return false;
4411
+ const d = new Date(date);
4412
+ return !isNaN(d.getTime());
4413
+ };
4414
+ var MS_PER_DAY = 1e3 * 60 * 60 * 24;
4415
+ var MS_PER_HOUR = 1e3 * 60 * 60;
4416
+ var MS_PER_MINUTE = 1e3 * 60;
4417
+ function getAgeOfDeceased(dateOfBirth, dateOfDeath, format3 = "years") {
4418
+ if (dateOfDeath < dateOfBirth) {
4419
+ return 0;
4420
+ }
4421
+ if (format3 === "years") {
4422
+ let age = dateOfDeath.getFullYear() - dateOfBirth.getFullYear();
4423
+ const monthDiff = dateOfDeath.getMonth() - dateOfBirth.getMonth();
4424
+ const dayDiff = dateOfDeath.getDate() - dateOfBirth.getDate();
4425
+ if (monthDiff < 0 || monthDiff === 0 && dayDiff < 0) age--;
4426
+ return age;
4427
+ }
4428
+ if (format3 === "months") {
4429
+ let months = (dateOfDeath.getFullYear() - dateOfBirth.getFullYear()) * 12;
4430
+ months += dateOfDeath.getMonth() - dateOfBirth.getMonth();
4431
+ if (dateOfDeath.getDate() < dateOfBirth.getDate()) months--;
4432
+ return months;
4433
+ }
4434
+ if (format3 === "days") {
4435
+ const diffTime2 = dateOfDeath.getTime() - dateOfBirth.getTime();
4436
+ return Math.floor(diffTime2 / MS_PER_DAY);
4437
+ }
4438
+ if (format3 === "hours") {
4439
+ const diffTime2 = dateOfDeath.getTime() - dateOfBirth.getTime();
4440
+ const remainingMs2 = diffTime2 - MS_PER_DAY;
4441
+ return remainingMs2 < 0 ? Math.floor(diffTime2 / MS_PER_HOUR) : Math.floor(remainingMs2 / MS_PER_HOUR);
4442
+ }
4443
+ const diffTime = dateOfDeath.getTime() - dateOfBirth.getTime();
4444
+ const remainingMs = diffTime - MS_PER_DAY;
4445
+ return remainingMs < 0 ? Math.floor(diffTime / MS_PER_MINUTE) : Math.floor(remainingMs / MS_PER_MINUTE);
4446
+ }
4447
+ ajv.addKeyword({
4448
+ keyword: "isValidAgeOfDeceased",
4449
+ type: "object",
4450
+ schemaType: "object",
4451
+ errors: true,
4452
+ validate(schema, data) {
4453
+ const {
4454
+ ageField,
4455
+ dateOfBirthField,
4456
+ deathDateField,
4457
+ deathTimeField,
4458
+ format: format3
4459
+ } = schema;
4460
+ const dob = data?.[dateOfBirthField];
4461
+ const dod = data?.[deathDateField];
4462
+ const tod = data?.[deathTimeField];
4463
+ const ageValue = data?.[ageField];
4464
+ if (!ageValue || !isValidDateFormat(dob) || !isValidDateFormat(dod)) {
4465
+ return true;
4466
+ }
4467
+ const dateOfBirth = /* @__PURE__ */ new Date(`${dob}T00:00:00+00:00`);
4468
+ const dateOfDeath = tod ? /* @__PURE__ */ new Date(`${dod}T${tod}:00+00:00`) : /* @__PURE__ */ new Date(`${dod}T00:00:00+00:00`);
4469
+ const deceasedAge = getAgeOfDeceased(dateOfBirth, dateOfDeath, format3);
4470
+ const sameDay = dateOfBirth.toISOString().slice(0, 10) === dateOfDeath.toISOString().slice(0, 10);
4471
+ return Number(ageValue) === deceasedAge && !(format3 === "hours" && !sameDay) && !(format3 === "minutes" && !sameDay) || format3 === "days" && deceasedAge - Number(ageValue) === 1 || format3 === "hours" && !sameDay && deceasedAge < Number(ageValue) || format3 === "hours" && sameDay && !tod || format3 === "minutes" && !sameDay && deceasedAge < Number(ageValue) || format3 === "minutes" && sameDay && !tod;
4472
+ }
4473
+ });
4407
4474
  ajv.addKeyword({
4408
4475
  keyword: "sumOf",
4409
4476
  type: "object",
@@ -4427,7 +4494,9 @@ ajv.addKeyword({
4427
4494
  schemaType: "boolean",
4428
4495
  errors: true,
4429
4496
  validate(schema, data) {
4430
- if (!schema) return true;
4497
+ if (!schema) {
4498
+ return true;
4499
+ }
4431
4500
  if (typeof data !== "string") {
4432
4501
  return true;
4433
4502
  }
@@ -4448,11 +4517,15 @@ ajv.addKeyword({
4448
4517
  errors: true,
4449
4518
  validate(schema, data) {
4450
4519
  const { fields, threshold } = schema;
4451
- if (!data || typeof data !== "object") return true;
4520
+ if (!data || typeof data !== "object") {
4521
+ return true;
4522
+ }
4452
4523
  const causesOfDeath = fields.flatMap(
4453
4524
  (field3) => (data?.[field3] || "").split(",").map((v) => v.trim()).filter(Boolean)
4454
4525
  ).filter((val, index, self) => self.indexOf(val) === index);
4455
- if (causesOfDeath.length === 0) return true;
4526
+ if (causesOfDeath.length === 0) {
4527
+ return true;
4528
+ }
4456
4529
  let hasNonIllDefined = false;
4457
4530
  for (const term of causesOfDeath) {
4458
4531
  const results = fuzzySearch(term, illDefinedConditions, threshold).filter(
@@ -4791,7 +4864,9 @@ function fuzzySearch(query, list, threshold, limit = 3) {
4791
4864
  const normalize = (str) => str.toLowerCase().replace(/[^\w\s]/g, "").trim();
4792
4865
  const tokenize = (str) => normalize(str).split(/\s+/).filter((w) => w.length >= 3);
4793
4866
  const queryWords = tokenize(query);
4794
- if (queryWords.length === 0) return [];
4867
+ if (queryWords.length === 0) {
4868
+ return [];
4869
+ }
4795
4870
  const results = [];
4796
4871
  for (const item of list) {
4797
4872
  const itemWords = tokenize(item);
@@ -4807,7 +4882,9 @@ function fuzzySearch(query, list, threshold, limit = 3) {
4807
4882
  for (const iWord of itemWords) {
4808
4883
  const dist = levenshtein(qWord, iWord);
4809
4884
  const normDist = dist / Math.max(qWord.length, iWord.length);
4810
- if (normDist < bestScore) bestScore = normDist;
4885
+ if (normDist < bestScore) {
4886
+ bestScore = normDist;
4887
+ }
4811
4888
  }
4812
4889
  if (bestScore !== Infinity) {
4813
4890
  const weight = COMMON_WORDS.has(qWord) ? 0.5 : 1;
@@ -5623,18 +5700,39 @@ function createFieldConditionals(fieldId) {
5623
5700
  return defineFormConditional({
5624
5701
  type: "object",
5625
5702
  properties: {
5626
- [fieldId]: { type: "number" },
5703
+ [this.$$field]: { type: "number" },
5627
5704
  [field1Id]: { type: "number" },
5628
5705
  [field2Id]: { type: "number" }
5629
5706
  },
5630
- required: [fieldId, field1Id, field2Id],
5707
+ required: [this.$$field, field1Id, field2Id],
5631
5708
  sumOf: {
5632
- sum: fieldId,
5709
+ sum: this.$$field,
5633
5710
  field1: field1Id,
5634
5711
  field2: field2Id
5635
5712
  }
5636
5713
  });
5637
5714
  },
5715
+ isValidDeceasedAge(dobField, dodField, todField, format3) {
5716
+ const dobFieldId = dobField.$$field;
5717
+ const dodFieldId = dodField.$$field;
5718
+ const todFieldId = todField.$$field;
5719
+ return defineFormConditional({
5720
+ type: "object",
5721
+ properties: {
5722
+ [this.$$field]: { type: "number" },
5723
+ [dobFieldId]: { type: "string" },
5724
+ [dodFieldId]: { type: "string" },
5725
+ [todFieldId]: { type: "string" }
5726
+ },
5727
+ isValidAgeOfDeceased: {
5728
+ ageField: this.$$field,
5729
+ dateOfBirthField: dobFieldId,
5730
+ deathDateField: dodFieldId,
5731
+ deathTimeField: todFieldId,
5732
+ format: format3
5733
+ }
5734
+ });
5735
+ },
5638
5736
  isAbbreviation() {
5639
5737
  return defineFormConditional({
5640
5738
  type: "object",
@@ -3644,6 +3644,72 @@ ajv.addKeyword({
3644
3644
  return locations.some((location) => location.id === locationIdInput);
3645
3645
  }
3646
3646
  });
3647
+ var datePattern = /^\d{4}-\d{1,2}-\d{1,2}$/;
3648
+ var isValidDateFormat = (date) => {
3649
+ if (!datePattern.test(date)) return false;
3650
+ const d = new Date(date);
3651
+ return !isNaN(d.getTime());
3652
+ };
3653
+ var MS_PER_DAY = 1e3 * 60 * 60 * 24;
3654
+ var MS_PER_HOUR = 1e3 * 60 * 60;
3655
+ var MS_PER_MINUTE = 1e3 * 60;
3656
+ function getAgeOfDeceased(dateOfBirth, dateOfDeath, format3 = "years") {
3657
+ if (dateOfDeath < dateOfBirth) {
3658
+ return 0;
3659
+ }
3660
+ if (format3 === "years") {
3661
+ let age = dateOfDeath.getFullYear() - dateOfBirth.getFullYear();
3662
+ const monthDiff = dateOfDeath.getMonth() - dateOfBirth.getMonth();
3663
+ const dayDiff = dateOfDeath.getDate() - dateOfBirth.getDate();
3664
+ if (monthDiff < 0 || monthDiff === 0 && dayDiff < 0) age--;
3665
+ return age;
3666
+ }
3667
+ if (format3 === "months") {
3668
+ let months = (dateOfDeath.getFullYear() - dateOfBirth.getFullYear()) * 12;
3669
+ months += dateOfDeath.getMonth() - dateOfBirth.getMonth();
3670
+ if (dateOfDeath.getDate() < dateOfBirth.getDate()) months--;
3671
+ return months;
3672
+ }
3673
+ if (format3 === "days") {
3674
+ const diffTime2 = dateOfDeath.getTime() - dateOfBirth.getTime();
3675
+ return Math.floor(diffTime2 / MS_PER_DAY);
3676
+ }
3677
+ if (format3 === "hours") {
3678
+ const diffTime2 = dateOfDeath.getTime() - dateOfBirth.getTime();
3679
+ const remainingMs2 = diffTime2 - MS_PER_DAY;
3680
+ return remainingMs2 < 0 ? Math.floor(diffTime2 / MS_PER_HOUR) : Math.floor(remainingMs2 / MS_PER_HOUR);
3681
+ }
3682
+ const diffTime = dateOfDeath.getTime() - dateOfBirth.getTime();
3683
+ const remainingMs = diffTime - MS_PER_DAY;
3684
+ return remainingMs < 0 ? Math.floor(diffTime / MS_PER_MINUTE) : Math.floor(remainingMs / MS_PER_MINUTE);
3685
+ }
3686
+ ajv.addKeyword({
3687
+ keyword: "isValidAgeOfDeceased",
3688
+ type: "object",
3689
+ schemaType: "object",
3690
+ errors: true,
3691
+ validate(schema, data) {
3692
+ const {
3693
+ ageField,
3694
+ dateOfBirthField,
3695
+ deathDateField,
3696
+ deathTimeField,
3697
+ format: format3
3698
+ } = schema;
3699
+ const dob = data?.[dateOfBirthField];
3700
+ const dod = data?.[deathDateField];
3701
+ const tod = data?.[deathTimeField];
3702
+ const ageValue = data?.[ageField];
3703
+ if (!ageValue || !isValidDateFormat(dob) || !isValidDateFormat(dod)) {
3704
+ return true;
3705
+ }
3706
+ const dateOfBirth = /* @__PURE__ */ new Date(`${dob}T00:00:00+00:00`);
3707
+ const dateOfDeath = tod ? /* @__PURE__ */ new Date(`${dod}T${tod}:00+00:00`) : /* @__PURE__ */ new Date(`${dod}T00:00:00+00:00`);
3708
+ const deceasedAge = getAgeOfDeceased(dateOfBirth, dateOfDeath, format3);
3709
+ const sameDay = dateOfBirth.toISOString().slice(0, 10) === dateOfDeath.toISOString().slice(0, 10);
3710
+ return Number(ageValue) === deceasedAge && !(format3 === "hours" && !sameDay) && !(format3 === "minutes" && !sameDay) || format3 === "days" && deceasedAge - Number(ageValue) === 1 || format3 === "hours" && !sameDay && deceasedAge < Number(ageValue) || format3 === "hours" && sameDay && !tod || format3 === "minutes" && !sameDay && deceasedAge < Number(ageValue) || format3 === "minutes" && sameDay && !tod;
3711
+ }
3712
+ });
3647
3713
  ajv.addKeyword({
3648
3714
  keyword: "sumOf",
3649
3715
  type: "object",
@@ -3667,7 +3733,9 @@ ajv.addKeyword({
3667
3733
  schemaType: "boolean",
3668
3734
  errors: true,
3669
3735
  validate(schema, data) {
3670
- if (!schema) return true;
3736
+ if (!schema) {
3737
+ return true;
3738
+ }
3671
3739
  if (typeof data !== "string") {
3672
3740
  return true;
3673
3741
  }
@@ -3688,11 +3756,15 @@ ajv.addKeyword({
3688
3756
  errors: true,
3689
3757
  validate(schema, data) {
3690
3758
  const { fields, threshold } = schema;
3691
- if (!data || typeof data !== "object") return true;
3759
+ if (!data || typeof data !== "object") {
3760
+ return true;
3761
+ }
3692
3762
  const causesOfDeath = fields.flatMap(
3693
3763
  (field3) => (data?.[field3] || "").split(",").map((v) => v.trim()).filter(Boolean)
3694
3764
  ).filter((val, index, self) => self.indexOf(val) === index);
3695
- if (causesOfDeath.length === 0) return true;
3765
+ if (causesOfDeath.length === 0) {
3766
+ return true;
3767
+ }
3696
3768
  let hasNonIllDefined = false;
3697
3769
  for (const term of causesOfDeath) {
3698
3770
  const results = fuzzySearch(term, illDefinedConditions, threshold).filter(
@@ -3742,7 +3814,9 @@ function fuzzySearch(query, list, threshold, limit = 3) {
3742
3814
  const normalize = (str) => str.toLowerCase().replace(/[^\w\s]/g, "").trim();
3743
3815
  const tokenize = (str) => normalize(str).split(/\s+/).filter((w) => w.length >= 3);
3744
3816
  const queryWords = tokenize(query);
3745
- if (queryWords.length === 0) return [];
3817
+ if (queryWords.length === 0) {
3818
+ return [];
3819
+ }
3746
3820
  const results = [];
3747
3821
  for (const item of list) {
3748
3822
  const itemWords = tokenize(item);
@@ -3758,7 +3832,9 @@ function fuzzySearch(query, list, threshold, limit = 3) {
3758
3832
  for (const iWord of itemWords) {
3759
3833
  const dist = levenshtein(qWord, iWord);
3760
3834
  const normDist = dist / Math.max(qWord.length, iWord.length);
3761
- if (normDist < bestScore) bestScore = normDist;
3835
+ if (normDist < bestScore) {
3836
+ bestScore = normDist;
3837
+ }
3762
3838
  }
3763
3839
  if (bestScore !== Infinity) {
3764
3840
  const weight = COMMON_WORDS.has(qWord) ? 0.5 : 1;
@@ -4267,18 +4343,39 @@ function createFieldConditionals(fieldId) {
4267
4343
  return defineFormConditional({
4268
4344
  type: "object",
4269
4345
  properties: {
4270
- [fieldId]: { type: "number" },
4346
+ [this.$$field]: { type: "number" },
4271
4347
  [field1Id]: { type: "number" },
4272
4348
  [field2Id]: { type: "number" }
4273
4349
  },
4274
- required: [fieldId, field1Id, field2Id],
4350
+ required: [this.$$field, field1Id, field2Id],
4275
4351
  sumOf: {
4276
- sum: fieldId,
4352
+ sum: this.$$field,
4277
4353
  field1: field1Id,
4278
4354
  field2: field2Id
4279
4355
  }
4280
4356
  });
4281
4357
  },
4358
+ isValidDeceasedAge(dobField, dodField, todField, format3) {
4359
+ const dobFieldId = dobField.$$field;
4360
+ const dodFieldId = dodField.$$field;
4361
+ const todFieldId = todField.$$field;
4362
+ return defineFormConditional({
4363
+ type: "object",
4364
+ properties: {
4365
+ [this.$$field]: { type: "number" },
4366
+ [dobFieldId]: { type: "string" },
4367
+ [dodFieldId]: { type: "string" },
4368
+ [todFieldId]: { type: "string" }
4369
+ },
4370
+ isValidAgeOfDeceased: {
4371
+ ageField: this.$$field,
4372
+ dateOfBirthField: dobFieldId,
4373
+ deathDateField: dodFieldId,
4374
+ deathTimeField: todFieldId,
4375
+ format: format3
4376
+ }
4377
+ });
4378
+ },
4282
4379
  isAbbreviation() {
4283
4380
  return defineFormConditional({
4284
4381
  type: "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecrvs/opencrvs-toolkit",
3
- "version": "1.9.0-rc.2c621d0",
3
+ "version": "1.9.0-rc.47deb60",
4
4
  "description": "OpenCRVS toolkit for building country configurations",
5
5
  "license": "MPL-2.0",
6
6
  "exports": {