@opencrvs/toolkit 1.9.2-rc.fd254a6 → 1.9.3-rc.1cf6bbd

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.
@@ -251,6 +251,34 @@ function getDateRangeToFieldReference(field, comparedField, clause) {
251
251
  required: [field.$$field]
252
252
  };
253
253
  }
254
+ function getDayRangeToFieldReference(field, comparedField, days, clause) {
255
+ return {
256
+ type: "object",
257
+ properties: {
258
+ [field.$$field]: wrapToPath(
259
+ {
260
+ type: "string",
261
+ format: "date",
262
+ daysFromDate: {
263
+ referenceDate: {
264
+ $data: `${field.$$subfield.length + 1}/${jsonFieldPath(
265
+ comparedField
266
+ )}`
267
+ },
268
+ clause,
269
+ days
270
+ }
271
+ },
272
+ field.$$subfield
273
+ ),
274
+ [comparedField.$$field]: wrapToPath(
275
+ { type: "string", format: "date" },
276
+ comparedField.$$subfield
277
+ )
278
+ },
279
+ required: [field.$$field]
280
+ };
281
+ }
254
282
  function defineComparison(field, value, keyword) {
255
283
  if (isFieldReference(value)) {
256
284
  const comparedField = value;
@@ -286,16 +314,17 @@ function defineComparison(field, value, keyword) {
286
314
  });
287
315
  }
288
316
  function createFieldConditionals(fieldId) {
289
- const getDayRange = (field, days, clause) => ({
317
+ const getDayRange = (field, days, clause, referenceDate) => ({
290
318
  type: "object",
291
319
  properties: {
292
320
  [field.$$field]: wrapToPath(
293
321
  {
294
322
  type: "string",
295
323
  format: "date",
296
- daysFromNow: {
324
+ daysFromDate: {
297
325
  days,
298
- clause
326
+ clause,
327
+ referenceDate
299
328
  }
300
329
  },
301
330
  field.$$subfield
@@ -348,7 +377,19 @@ function createFieldConditionals(fieldId) {
348
377
  return {
349
378
  days: (days) => ({
350
379
  inPast: () => defineFormConditional(getDayRange(this, -days, "after")),
351
- inFuture: () => defineFormConditional(getDayRange(this, days, "after"))
380
+ inFuture: () => defineFormConditional(getDayRange(this, days, "after")),
381
+ fromDate: (date) => {
382
+ if (isFieldReference(date)) {
383
+ const comparedField = date;
384
+ return defineFormConditional(
385
+ getDayRangeToFieldReference(this, comparedField, days, "after")
386
+ );
387
+ }
388
+ return defineFormConditional(getDayRange(this, days, "after", date));
389
+ },
390
+ fromNow: () => {
391
+ return defineFormConditional(getDayRange(this, days, "after"));
392
+ }
352
393
  }),
353
394
  date: (date) => {
354
395
  if (isFieldReference(date)) {
@@ -370,7 +411,26 @@ function createFieldConditionals(fieldId) {
370
411
  return {
371
412
  days: (days) => ({
372
413
  inPast: () => defineFormConditional(getDayRange(this, -days, "before")),
373
- inFuture: () => defineFormConditional(getDayRange(this, days, "before"))
414
+ inFuture: () => defineFormConditional(getDayRange(this, days, "before")),
415
+ fromDate: (date) => {
416
+ if (isFieldReference(date)) {
417
+ const comparedField = date;
418
+ return defineFormConditional(
419
+ getDayRangeToFieldReference(
420
+ this,
421
+ comparedField,
422
+ -days,
423
+ "before"
424
+ )
425
+ );
426
+ }
427
+ return defineFormConditional(
428
+ getDayRange(this, -days, "before", date)
429
+ );
430
+ },
431
+ fromNow: () => {
432
+ return defineFormConditional(getDayRange(this, -days, "before"));
433
+ }
374
434
  }),
375
435
  date: (date) => {
376
436
  if (isFieldReference(date)) {
@@ -2443,6 +2443,9 @@ var PageTypes = import_zod16.z.enum(["FORM", "VERIFICATION"]);
2443
2443
  var PageConfigBase = import_zod16.z.object({
2444
2444
  id: import_zod16.z.string().describe("Unique identifier for the page"),
2445
2445
  title: TranslationConfig.describe("Header title of the page"),
2446
+ requireCompletionToContinue: import_zod16.z.boolean().default(false).describe(
2447
+ "If true, all required fields must be filled before continuing to the next page"
2448
+ ),
2446
2449
  fields: import_zod16.z.array(FieldConfig).describe("Fields to be rendered on the page"),
2447
2450
  conditional: Conditional.optional().describe(
2448
2451
  "Page will be shown if condition is met. If conditional is not defined, the page will be always shown."
@@ -3182,9 +3185,30 @@ var DataContext = import_zod25.z.object({
3182
3185
  $leafAdminStructureLocationIds: import_zod25.z.array(import_zod25.z.object({ id: UUID }))
3183
3186
  })
3184
3187
  });
3188
+ function resolveDataPath(rootData, dataPath, instancePath) {
3189
+ const pathParts = dataPath.split("/");
3190
+ const levels = parseInt(pathParts[0], 10);
3191
+ const referencePath = pathParts.slice(1);
3192
+ const instanceParts = instancePath.split("/").filter(Boolean);
3193
+ const traversedParts = instanceParts.slice(0, -levels);
3194
+ let current = rootData;
3195
+ for (const part of traversedParts) {
3196
+ if (current === null || current === void 0) {
3197
+ return void 0;
3198
+ }
3199
+ current = current[part];
3200
+ }
3201
+ for (const part of referencePath) {
3202
+ if (current === null || current === void 0) {
3203
+ return void 0;
3204
+ }
3205
+ current = current[part];
3206
+ }
3207
+ return current;
3208
+ }
3185
3209
  (0, import_ajv_formats.default)(ajv);
3186
3210
  ajv.addKeyword({
3187
- keyword: "daysFromNow",
3211
+ keyword: "daysFromDate",
3188
3212
  type: "string",
3189
3213
  schemaType: "object",
3190
3214
  $data: true,
@@ -3201,8 +3225,22 @@ ajv.addKeyword({
3201
3225
  if (isNaN(date.getTime())) {
3202
3226
  return false;
3203
3227
  }
3204
- const now = new Date(dataContext.rootData.$now);
3205
- const offsetDate = new Date(now.getTime() + days * 24 * 60 * 60 * 1e3);
3228
+ let referenceDate = schema.referenceDate;
3229
+ if (referenceDate && typeof referenceDate === "object" && "$data" in referenceDate) {
3230
+ referenceDate = resolveDataPath(
3231
+ dataContext.rootData,
3232
+ referenceDate.$data,
3233
+ dataContext.instancePath
3234
+ );
3235
+ }
3236
+ if (!referenceDate) {
3237
+ referenceDate = dataContext.rootData.$now;
3238
+ }
3239
+ const baseDate = new Date(referenceDate);
3240
+ if (isNaN(baseDate.getTime())) {
3241
+ return false;
3242
+ }
3243
+ const offsetDate = new Date(baseDate.getTime() + days * 24 * 60 * 60 * 1e3);
3206
3244
  return clause === "after" ? (0, import_date_fns.isAfter)(date, offsetDate) : (0, import_date_fns.isBefore)(date, offsetDate);
3207
3245
  }
3208
3246
  });
@@ -3265,7 +3303,8 @@ function isConditionMet(conditional, values, context) {
3265
3303
  $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3266
3304
  $online: isOnline(),
3267
3305
  $user: context.user,
3268
- $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? []
3306
+ $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? [],
3307
+ $event: context.event
3269
3308
  });
3270
3309
  }
3271
3310
  function getConditionalActionsForField(field3, values) {
@@ -3291,7 +3330,8 @@ function isFieldConditionMet(field3, form, conditionalType, context) {
3291
3330
  $now: (0, import_date_fns.formatISO)(/* @__PURE__ */ new Date(), { representation: "date" }),
3292
3331
  $online: isOnline(),
3293
3332
  $user: context.user,
3294
- $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? []
3333
+ $leafAdminStructureLocationIds: context.leafAdminStructureLocationIds ?? [],
3334
+ $event: context.event
3295
3335
  });
3296
3336
  return validConditionals.includes(conditionalType);
3297
3337
  }
@@ -4113,6 +4153,34 @@ function getDateRangeToFieldReference(field3, comparedField, clause) {
4113
4153
  required: [field3.$$field]
4114
4154
  };
4115
4155
  }
4156
+ function getDayRangeToFieldReference(field3, comparedField, days, clause) {
4157
+ return {
4158
+ type: "object",
4159
+ properties: {
4160
+ [field3.$$field]: wrapToPath(
4161
+ {
4162
+ type: "string",
4163
+ format: "date",
4164
+ daysFromDate: {
4165
+ referenceDate: {
4166
+ $data: `${field3.$$subfield.length + 1}/${jsonFieldPath(
4167
+ comparedField
4168
+ )}`
4169
+ },
4170
+ clause,
4171
+ days
4172
+ }
4173
+ },
4174
+ field3.$$subfield
4175
+ ),
4176
+ [comparedField.$$field]: wrapToPath(
4177
+ { type: "string", format: "date" },
4178
+ comparedField.$$subfield
4179
+ )
4180
+ },
4181
+ required: [field3.$$field]
4182
+ };
4183
+ }
4116
4184
  function defineComparison(field3, value, keyword) {
4117
4185
  if (isFieldReference(value)) {
4118
4186
  const comparedField = value;
@@ -4148,16 +4216,17 @@ function defineComparison(field3, value, keyword) {
4148
4216
  });
4149
4217
  }
4150
4218
  function createFieldConditionals(fieldId) {
4151
- const getDayRange = (field3, days, clause) => ({
4219
+ const getDayRange = (field3, days, clause, referenceDate) => ({
4152
4220
  type: "object",
4153
4221
  properties: {
4154
4222
  [field3.$$field]: wrapToPath(
4155
4223
  {
4156
4224
  type: "string",
4157
4225
  format: "date",
4158
- daysFromNow: {
4226
+ daysFromDate: {
4159
4227
  days,
4160
- clause
4228
+ clause,
4229
+ referenceDate
4161
4230
  }
4162
4231
  },
4163
4232
  field3.$$subfield
@@ -4210,7 +4279,19 @@ function createFieldConditionals(fieldId) {
4210
4279
  return {
4211
4280
  days: (days) => ({
4212
4281
  inPast: () => defineFormConditional(getDayRange(this, -days, "after")),
4213
- inFuture: () => defineFormConditional(getDayRange(this, days, "after"))
4282
+ inFuture: () => defineFormConditional(getDayRange(this, days, "after")),
4283
+ fromDate: (date) => {
4284
+ if (isFieldReference(date)) {
4285
+ const comparedField = date;
4286
+ return defineFormConditional(
4287
+ getDayRangeToFieldReference(this, comparedField, days, "after")
4288
+ );
4289
+ }
4290
+ return defineFormConditional(getDayRange(this, days, "after", date));
4291
+ },
4292
+ fromNow: () => {
4293
+ return defineFormConditional(getDayRange(this, days, "after"));
4294
+ }
4214
4295
  }),
4215
4296
  date: (date) => {
4216
4297
  if (isFieldReference(date)) {
@@ -4232,7 +4313,26 @@ function createFieldConditionals(fieldId) {
4232
4313
  return {
4233
4314
  days: (days) => ({
4234
4315
  inPast: () => defineFormConditional(getDayRange(this, -days, "before")),
4235
- inFuture: () => defineFormConditional(getDayRange(this, days, "before"))
4316
+ inFuture: () => defineFormConditional(getDayRange(this, days, "before")),
4317
+ fromDate: (date) => {
4318
+ if (isFieldReference(date)) {
4319
+ const comparedField = date;
4320
+ return defineFormConditional(
4321
+ getDayRangeToFieldReference(
4322
+ this,
4323
+ comparedField,
4324
+ -days,
4325
+ "before"
4326
+ )
4327
+ );
4328
+ }
4329
+ return defineFormConditional(
4330
+ getDayRange(this, -days, "before", date)
4331
+ );
4332
+ },
4333
+ fromNow: () => {
4334
+ return defineFormConditional(getDayRange(this, -days, "before"));
4335
+ }
4236
4336
  }),
4237
4337
  date: (date) => {
4238
4338
  if (isFieldReference(date)) {
@@ -1969,6 +1969,9 @@ var PageTypes = import_zod16.z.enum(["FORM", "VERIFICATION"]);
1969
1969
  var PageConfigBase = import_zod16.z.object({
1970
1970
  id: import_zod16.z.string().describe("Unique identifier for the page"),
1971
1971
  title: TranslationConfig.describe("Header title of the page"),
1972
+ requireCompletionToContinue: import_zod16.z.boolean().default(false).describe(
1973
+ "If true, all required fields must be filled before continuing to the next page"
1974
+ ),
1972
1975
  fields: import_zod16.z.array(FieldConfig).describe("Fields to be rendered on the page"),
1973
1976
  conditional: Conditional.optional().describe(
1974
1977
  "Page will be shown if condition is met. If conditional is not defined, the page will be always shown."
@@ -2421,9 +2424,30 @@ var DataContext = import_zod25.z.object({
2421
2424
  $leafAdminStructureLocationIds: import_zod25.z.array(import_zod25.z.object({ id: UUID }))
2422
2425
  })
2423
2426
  });
2427
+ function resolveDataPath(rootData, dataPath, instancePath) {
2428
+ const pathParts = dataPath.split("/");
2429
+ const levels = parseInt(pathParts[0], 10);
2430
+ const referencePath = pathParts.slice(1);
2431
+ const instanceParts = instancePath.split("/").filter(Boolean);
2432
+ const traversedParts = instanceParts.slice(0, -levels);
2433
+ let current = rootData;
2434
+ for (const part of traversedParts) {
2435
+ if (current === null || current === void 0) {
2436
+ return void 0;
2437
+ }
2438
+ current = current[part];
2439
+ }
2440
+ for (const part of referencePath) {
2441
+ if (current === null || current === void 0) {
2442
+ return void 0;
2443
+ }
2444
+ current = current[part];
2445
+ }
2446
+ return current;
2447
+ }
2424
2448
  (0, import_ajv_formats.default)(ajv);
2425
2449
  ajv.addKeyword({
2426
- keyword: "daysFromNow",
2450
+ keyword: "daysFromDate",
2427
2451
  type: "string",
2428
2452
  schemaType: "object",
2429
2453
  $data: true,
@@ -2440,8 +2464,22 @@ ajv.addKeyword({
2440
2464
  if (isNaN(date.getTime())) {
2441
2465
  return false;
2442
2466
  }
2443
- const now = new Date(dataContext.rootData.$now);
2444
- const offsetDate = new Date(now.getTime() + days * 24 * 60 * 60 * 1e3);
2467
+ let referenceDate = schema.referenceDate;
2468
+ if (referenceDate && typeof referenceDate === "object" && "$data" in referenceDate) {
2469
+ referenceDate = resolveDataPath(
2470
+ dataContext.rootData,
2471
+ referenceDate.$data,
2472
+ dataContext.instancePath
2473
+ );
2474
+ }
2475
+ if (!referenceDate) {
2476
+ referenceDate = dataContext.rootData.$now;
2477
+ }
2478
+ const baseDate = new Date(referenceDate);
2479
+ if (isNaN(baseDate.getTime())) {
2480
+ return false;
2481
+ }
2482
+ const offsetDate = new Date(baseDate.getTime() + days * 24 * 60 * 60 * 1e3);
2445
2483
  return clause === "after" ? (0, import_date_fns.isAfter)(date, offsetDate) : (0, import_date_fns.isBefore)(date, offsetDate);
2446
2484
  }
2447
2485
  });
@@ -2756,6 +2794,34 @@ function getDateRangeToFieldReference(field3, comparedField, clause) {
2756
2794
  required: [field3.$$field]
2757
2795
  };
2758
2796
  }
2797
+ function getDayRangeToFieldReference(field3, comparedField, days, clause) {
2798
+ return {
2799
+ type: "object",
2800
+ properties: {
2801
+ [field3.$$field]: wrapToPath(
2802
+ {
2803
+ type: "string",
2804
+ format: "date",
2805
+ daysFromDate: {
2806
+ referenceDate: {
2807
+ $data: `${field3.$$subfield.length + 1}/${jsonFieldPath(
2808
+ comparedField
2809
+ )}`
2810
+ },
2811
+ clause,
2812
+ days
2813
+ }
2814
+ },
2815
+ field3.$$subfield
2816
+ ),
2817
+ [comparedField.$$field]: wrapToPath(
2818
+ { type: "string", format: "date" },
2819
+ comparedField.$$subfield
2820
+ )
2821
+ },
2822
+ required: [field3.$$field]
2823
+ };
2824
+ }
2759
2825
  function defineComparison(field3, value, keyword) {
2760
2826
  if (isFieldReference(value)) {
2761
2827
  const comparedField = value;
@@ -2791,16 +2857,17 @@ function defineComparison(field3, value, keyword) {
2791
2857
  });
2792
2858
  }
2793
2859
  function createFieldConditionals(fieldId) {
2794
- const getDayRange = (field3, days, clause) => ({
2860
+ const getDayRange = (field3, days, clause, referenceDate) => ({
2795
2861
  type: "object",
2796
2862
  properties: {
2797
2863
  [field3.$$field]: wrapToPath(
2798
2864
  {
2799
2865
  type: "string",
2800
2866
  format: "date",
2801
- daysFromNow: {
2867
+ daysFromDate: {
2802
2868
  days,
2803
- clause
2869
+ clause,
2870
+ referenceDate
2804
2871
  }
2805
2872
  },
2806
2873
  field3.$$subfield
@@ -2853,7 +2920,19 @@ function createFieldConditionals(fieldId) {
2853
2920
  return {
2854
2921
  days: (days) => ({
2855
2922
  inPast: () => defineFormConditional(getDayRange(this, -days, "after")),
2856
- inFuture: () => defineFormConditional(getDayRange(this, days, "after"))
2923
+ inFuture: () => defineFormConditional(getDayRange(this, days, "after")),
2924
+ fromDate: (date) => {
2925
+ if (isFieldReference(date)) {
2926
+ const comparedField = date;
2927
+ return defineFormConditional(
2928
+ getDayRangeToFieldReference(this, comparedField, days, "after")
2929
+ );
2930
+ }
2931
+ return defineFormConditional(getDayRange(this, days, "after", date));
2932
+ },
2933
+ fromNow: () => {
2934
+ return defineFormConditional(getDayRange(this, days, "after"));
2935
+ }
2857
2936
  }),
2858
2937
  date: (date) => {
2859
2938
  if (isFieldReference(date)) {
@@ -2875,7 +2954,26 @@ function createFieldConditionals(fieldId) {
2875
2954
  return {
2876
2955
  days: (days) => ({
2877
2956
  inPast: () => defineFormConditional(getDayRange(this, -days, "before")),
2878
- inFuture: () => defineFormConditional(getDayRange(this, days, "before"))
2957
+ inFuture: () => defineFormConditional(getDayRange(this, days, "before")),
2958
+ fromDate: (date) => {
2959
+ if (isFieldReference(date)) {
2960
+ const comparedField = date;
2961
+ return defineFormConditional(
2962
+ getDayRangeToFieldReference(
2963
+ this,
2964
+ comparedField,
2965
+ -days,
2966
+ "before"
2967
+ )
2968
+ );
2969
+ }
2970
+ return defineFormConditional(
2971
+ getDayRange(this, -days, "before", date)
2972
+ );
2973
+ },
2974
+ fromNow: () => {
2975
+ return defineFormConditional(getDayRange(this, -days, "before"));
2976
+ }
2879
2977
  }),
2880
2978
  date: (date) => {
2881
2979
  if (isFieldReference(date)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencrvs/toolkit",
3
- "version": "1.9.2-rc.fd254a6",
3
+ "version": "1.9.3-rc.1cf6bbd",
4
4
  "description": "OpenCRVS toolkit for building country configurations",
5
5
  "license": "MPL-2.0",
6
6
  "exports": {