@opencrvs/toolkit 1.8.1-rc.008155b → 1.8.1-rc.020858b

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.
@@ -134,6 +134,7 @@ __export(events_exports, {
134
134
  METADATA_FIELD_PREFIX: () => METADATA_FIELD_PREFIX,
135
135
  MarkedAsDuplicateActionInput: () => MarkedAsDuplicateActionInput,
136
136
  MimeType: () => MimeType,
137
+ NameConfig: () => NameConfig,
137
138
  NameFieldUpdateValue: () => NameFieldUpdateValue,
138
139
  NameFieldValue: () => NameFieldValue,
139
140
  NonEmptyTextValue: () => NonEmptyTextValue,
@@ -171,6 +172,7 @@ __export(events_exports, {
171
172
  TENNIS_CLUB_MEMBERSHIP: () => TENNIS_CLUB_MEMBERSHIP,
172
173
  TEST_SYSTEM_IANA_TIMEZONE: () => TEST_SYSTEM_IANA_TIMEZONE,
173
174
  TestUserRole: () => TestUserRole,
175
+ TextField: () => TextField,
174
176
  TextValue: () => TextValue,
175
177
  TimeValue: () => TimeValue,
176
178
  TranslationConfig: () => TranslationConfig,
@@ -200,6 +202,7 @@ __export(events_exports, {
200
202
  annotationActions: () => annotationActions,
201
203
  applyDeclarationToEventIndex: () => applyDeclarationToEventIndex,
202
204
  applyDraftsToEventIndex: () => applyDraftsToEventIndex,
205
+ areCertificateConditionsMet: () => areCertificateConditionsMet,
203
206
  areConditionsMet: () => areConditionsMet,
204
207
  compositeFieldTypes: () => compositeFieldTypes,
205
208
  createEmptyDraft: () => createEmptyDraft,
@@ -262,6 +265,7 @@ __export(events_exports, {
262
265
  getDeclarationPages: () => getDeclarationPages,
263
266
  getEventConfigById: () => getEventConfigById,
264
267
  getMixedPath: () => getMixedPath,
268
+ getOnlyVisibleFormValues: () => getOnlyVisibleFormValues,
265
269
  getPrintCertificatePages: () => getPrintCertificatePages,
266
270
  getRandomDate: () => getRandomDate,
267
271
  getRandomDatetime: () => getRandomDatetime,
@@ -323,6 +327,7 @@ __export(events_exports, {
323
327
  or: () => or,
324
328
  resolveDateOfEvent: () => resolveDateOfEvent,
325
329
  runFieldValidations: () => runFieldValidations,
330
+ runStructuralValidations: () => runStructuralValidations,
326
331
  timePeriodToDateRange: () => timePeriodToDateRange,
327
332
  user: () => user,
328
333
  validate: () => validate,
@@ -609,13 +614,13 @@ var UrbanAddressUpdateValue = AdminStructure.extend({
609
614
  zipCode: import_zod5.z.string().nullish()
610
615
  });
611
616
  var NameFieldValue = import_zod5.z.object({
612
- firstname: import_zod5.z.string().min(1),
613
- surname: import_zod5.z.string().min(1),
617
+ firstname: import_zod5.z.string(),
618
+ surname: import_zod5.z.string(),
614
619
  middlename: import_zod5.z.string().optional()
615
620
  });
616
621
  var NameFieldUpdateValue = import_zod5.z.object({
617
- firstname: import_zod5.z.string().nullish(),
618
- surname: import_zod5.z.string().nullish(),
622
+ firstname: import_zod5.z.string(),
623
+ surname: import_zod5.z.string(),
619
624
  middlename: import_zod5.z.string().nullish()
620
625
  }).or(import_zod5.z.null()).or(import_zod5.z.undefined());
621
626
  var RuralAddressUpdateValue = AdminStructure.extend({
@@ -912,18 +917,32 @@ var SelectDateRangeField = BaseField.extend({
912
917
  defaultValue: SelectDateRangeValue.optional(),
913
918
  options: import_zod7.z.array(SelectDateRangeOption).describe("A list of options")
914
919
  }).describe("Select input with date range options");
920
+ var NameConfig = import_zod7.z.object({
921
+ firstname: import_zod7.z.object({ required: import_zod7.z.boolean() }).optional(),
922
+ middlename: import_zod7.z.object({ required: import_zod7.z.boolean() }).optional(),
923
+ surname: import_zod7.z.object({ required: import_zod7.z.boolean() }).optional()
924
+ });
915
925
  var NameField = BaseField.extend({
916
926
  type: import_zod7.z.literal(FieldType.NAME),
917
927
  defaultValue: import_zod7.z.object({
918
- firstname: NonEmptyTextValue,
919
- surname: NonEmptyTextValue
928
+ firstname: NonEmptyTextValue.optional(),
929
+ middlename: NonEmptyTextValue.optional(),
930
+ surname: NonEmptyTextValue.optional()
920
931
  }).optional(),
921
932
  configuration: import_zod7.z.object({
933
+ name: NameConfig.default({
934
+ firstname: { required: true },
935
+ surname: { required: true }
936
+ }).optional(),
922
937
  maxLength: import_zod7.z.number().optional().describe("Maximum length of the text"),
923
938
  prefix: TranslationConfig.optional(),
924
939
  postfix: TranslationConfig.optional(),
925
- includeMiddlename: import_zod7.z.boolean().default(false).optional().describe("To make middle name visible in Name form field"),
926
940
  searchMode: import_zod7.z.boolean().optional()
941
+ }).default({
942
+ name: {
943
+ firstname: { required: true },
944
+ surname: { required: true }
945
+ }
927
946
  }).optional()
928
947
  }).describe("Name input field");
929
948
  var PhoneField = BaseField.extend({
@@ -1225,7 +1244,8 @@ var CertificateConfig = import_zod11.z.object({
1225
1244
  delayed: import_zod11.z.number()
1226
1245
  }),
1227
1246
  svgUrl: import_zod11.z.string(),
1228
- fonts: import_zod11.z.record(FontFamily).optional()
1247
+ fonts: import_zod11.z.record(FontFamily).optional(),
1248
+ conditionals: import_zod11.z.array(ShowConditional).optional()
1229
1249
  });
1230
1250
  var CertificateTemplateConfig = CertificateConfig.extend({
1231
1251
  hash: import_zod11.z.string().optional(),
@@ -2055,7 +2075,7 @@ var ResolvedUser = import_zod19.z.object({
2055
2075
  });
2056
2076
 
2057
2077
  // ../commons/src/conditionals/validate.ts
2058
- var import_ajv = __toESM(require("ajv"));
2078
+ var import__ = __toESM(require("ajv/dist/2019"));
2059
2079
  var import_ajv_formats = __toESM(require("ajv-formats"));
2060
2080
  var import_date_fns = require("date-fns");
2061
2081
 
@@ -2269,9 +2289,11 @@ var isNonInteractiveFieldType = (field2) => {
2269
2289
  };
2270
2290
 
2271
2291
  // ../commons/src/conditionals/validate.ts
2272
- var ajv = new import_ajv.default({
2292
+ var ajv = new import__.default({
2273
2293
  $data: true,
2274
- allowUnionTypes: true
2294
+ allowUnionTypes: true,
2295
+ strict: false
2296
+ // Allow minContains and other newer features
2275
2297
  });
2276
2298
  (0, import_ajv_formats.default)(ajv);
2277
2299
  ajv.addKeyword({
@@ -2335,6 +2357,14 @@ function isFieldConditionMet(field2, form, conditionalType) {
2335
2357
  function isFieldVisible(field2, form) {
2336
2358
  return isFieldConditionMet(field2, form, ConditionalType.SHOW);
2337
2359
  }
2360
+ function getOnlyVisibleFormValues(field2, form) {
2361
+ return field2.reduce((acc, f) => {
2362
+ if (isFieldVisible(f, form) && form[f.id] !== void 0) {
2363
+ acc[f.id] = form[f.id];
2364
+ }
2365
+ return acc;
2366
+ }, {});
2367
+ }
2338
2368
  function isFieldEmptyAndNotRequired(field2, form) {
2339
2369
  const fieldValue = form[field2.id];
2340
2370
  return !field2.required && (fieldValue === void 0 || fieldValue === "");
@@ -2444,6 +2474,23 @@ function validateFieldInput({
2444
2474
  const rawError = zodType.safeParse(value, { errorMap: zodToIntlErrorMap });
2445
2475
  return rawError.error?.issues.map((issue) => issue.message) ?? [];
2446
2476
  }
2477
+ function runStructuralValidations({
2478
+ field: field2,
2479
+ values
2480
+ }) {
2481
+ if (!isFieldVisible(field2, values) || isFieldEmptyAndNotRequired(field2, values)) {
2482
+ return {
2483
+ errors: []
2484
+ };
2485
+ }
2486
+ const fieldValidationResult = validateFieldInput({
2487
+ field: field2,
2488
+ value: values[field2.id]
2489
+ });
2490
+ return {
2491
+ errors: fieldValidationResult
2492
+ };
2493
+ }
2447
2494
  function runFieldValidations({
2448
2495
  field: field2,
2449
2496
  values
@@ -2509,6 +2556,11 @@ function getValidatorsForField(fieldId, validations) {
2509
2556
  };
2510
2557
  }).filter((x) => x !== null);
2511
2558
  }
2559
+ function areCertificateConditionsMet(conditions, values) {
2560
+ return conditions.every((condition) => {
2561
+ return ajv.validate(condition.conditional, values);
2562
+ });
2563
+ }
2512
2564
 
2513
2565
  // ../commons/src/utils.ts
2514
2566
  function getOrThrow(x, message) {
@@ -3105,6 +3157,7 @@ function createFieldConditionals(fieldId) {
3105
3157
  properties: {
3106
3158
  [fieldId]: {
3107
3159
  type: "string",
3160
+ minLength: 1,
3108
3161
  pattern: "^[\\p{Script=Latin}0-9'.-]*(\\([\\p{Script=Latin}0-9'.-]+\\))?[\\p{Script=Latin}0-9'.-]*( [\\p{Script=Latin}0-9'.-]*(\\([\\p{Script=Latin}0-9'.-]+\\))?[\\p{Script=Latin}0-9'.-]*)*$",
3109
3162
  description: "Name must contain only letters, numbers, and allowed special characters ('.-). No double spaces."
3110
3163
  }
@@ -3232,32 +3285,107 @@ function eventFn(fieldId) {
3232
3285
  var event = Object.assign(eventFn, {
3233
3286
  /**
3234
3287
  * Checks if the event contains a specific action type.
3288
+ * Can be used directly as a conditional or chained with additional methods.
3235
3289
  * @param action - The action type to check for.
3236
3290
  */
3237
- hasAction: (action) => defineConditional({
3238
- type: "object",
3239
- properties: {
3240
- $event: {
3291
+ hasAction: (action) => {
3292
+ const basicConditional = defineConditional({
3293
+ type: "object",
3294
+ properties: {
3295
+ $event: {
3296
+ type: "object",
3297
+ properties: {
3298
+ actions: {
3299
+ type: "array",
3300
+ contains: {
3301
+ type: "object",
3302
+ properties: {
3303
+ type: {
3304
+ const: action
3305
+ }
3306
+ },
3307
+ required: ["type"]
3308
+ }
3309
+ }
3310
+ },
3311
+ required: ["actions"]
3312
+ }
3313
+ },
3314
+ required: ["$event"]
3315
+ });
3316
+ const buildActionConstraints = (additionalFields) => {
3317
+ const actionProperties = {
3318
+ type: { const: action }
3319
+ };
3320
+ const requiredFields = ["type"];
3321
+ if (additionalFields) {
3322
+ Object.entries(additionalFields).forEach(([key, value]) => {
3323
+ actionProperties[key] = { const: value };
3324
+ requiredFields.push(key);
3325
+ });
3326
+ }
3327
+ return { actionProperties, requiredFields };
3328
+ };
3329
+ const createCountConditional = (countType, count, additionalFields) => {
3330
+ const { actionProperties, requiredFields } = buildActionConstraints(additionalFields);
3331
+ return defineConditional({
3241
3332
  type: "object",
3242
3333
  properties: {
3243
- actions: {
3244
- type: "array",
3245
- contains: {
3246
- type: "object",
3247
- properties: {
3248
- type: {
3249
- const: action
3250
- }
3251
- },
3252
- required: ["type"]
3253
- }
3334
+ $event: {
3335
+ type: "object",
3336
+ properties: {
3337
+ actions: {
3338
+ type: "array",
3339
+ contains: {
3340
+ type: "object",
3341
+ properties: actionProperties,
3342
+ required: requiredFields
3343
+ },
3344
+ [countType]: count
3345
+ }
3346
+ },
3347
+ required: ["actions"]
3254
3348
  }
3255
3349
  },
3256
- required: ["actions"]
3257
- }
3258
- },
3259
- required: ["$event"]
3260
- }),
3350
+ required: ["$event"]
3351
+ });
3352
+ };
3353
+ const withMinMax = (additionalFields) => {
3354
+ return {
3355
+ /**
3356
+ * Creates a conditional that checks if the event contains a specific action type
3357
+ * with a minimum count of occurrences.
3358
+ *
3359
+ * @param minCount - The minimum number of actions required.
3360
+ */
3361
+ minCount: (minCount) => createCountConditional("minContains", minCount, additionalFields),
3362
+ /**
3363
+ * Builds a conditional that sets a maximum count for the number of actions.
3364
+ * This is useful for limiting the number of actions of a specific type in a single event.
3365
+ */
3366
+ maxCount: (maxCount) => createCountConditional("maxContains", maxCount, additionalFields)
3367
+ };
3368
+ };
3369
+ const chainableMethods = {
3370
+ /**
3371
+ * Adds additional field constraints to the action matching.
3372
+ *
3373
+ * @param fields - Object containing additional fields to match on the action.
3374
+ */
3375
+ withFields: (fields) => withMinMax(fields),
3376
+ /**
3377
+ * Adds template ID constraint to the action matching.
3378
+ * This is a convenience method that adds content.templateId to the fields.
3379
+ *
3380
+ * @param id - The template ID to match against.
3381
+ */
3382
+ withTemplate: (id) => withMinMax({
3383
+ content: { templateId: id }
3384
+ }),
3385
+ ...withMinMax()
3386
+ };
3387
+ return { ...basicConditional, ...chainableMethods };
3388
+ },
3261
3389
  field(field2) {
3262
3390
  return {
3263
3391
  $event: field2
@@ -4245,13 +4373,13 @@ function getAssignedUserSignatureFromActions(actions) {
4245
4373
  return signature;
4246
4374
  }, null);
4247
4375
  }
4248
- function aggregateActionDeclarations(actions) {
4376
+ function aggregateActionDeclarations(actions, config) {
4249
4377
  const excludedActions = [
4250
4378
  ActionType.REQUEST_CORRECTION,
4251
4379
  ActionType.PRINT_CERTIFICATE,
4252
4380
  ActionType.REJECT_CORRECTION
4253
4381
  ];
4254
- return actions.reduce((declaration, action) => {
4382
+ const aggregatedDeclaration = actions.reduce((declaration, action) => {
4255
4383
  if (excludedActions.some((excludedAction) => excludedAction === action.type)) {
4256
4384
  return declaration;
4257
4385
  }
@@ -4264,6 +4392,10 @@ function aggregateActionDeclarations(actions) {
4264
4392
  }
4265
4393
  return deepMerge(declaration, action.declaration);
4266
4394
  }, {});
4395
+ return getOnlyVisibleFormValues(
4396
+ config.declaration.pages.flatMap((x) => x.fields),
4397
+ aggregatedDeclaration
4398
+ );
4267
4399
  }
4268
4400
  function deepDropNulls(obj) {
4269
4401
  if (Array.isArray(obj)) {
@@ -4309,7 +4441,7 @@ function getCurrentEventState(event2, config) {
4309
4441
  );
4310
4442
  const requestActionMetadata = getActionUpdateMetadata(event2.actions);
4311
4443
  const acceptedActionMetadata = getActionUpdateMetadata(acceptedActions);
4312
- const declaration = aggregateActionDeclarations(acceptedActions);
4444
+ const declaration = aggregateActionDeclarations(acceptedActions, config);
4313
4445
  return deepDropNulls({
4314
4446
  id: event2.id,
4315
4447
  type: event2.type,
@@ -5174,7 +5306,27 @@ var TENNIS_CLUB_DECLARATION_FORM = defineDeclarationForm({
5174
5306
  defaultMessage: "Applicant's name",
5175
5307
  description: "This is the label for the field",
5176
5308
  id: "v2.event.tennis-club-membership.action.declare.form.section.who.field.firstname.label"
5177
- }
5309
+ },
5310
+ configuration: {
5311
+ name: {
5312
+ firstname: { required: true },
5313
+ middlename: { required: false },
5314
+ surname: { required: true }
5315
+ }
5316
+ },
5317
+ validation: [
5318
+ {
5319
+ validator: field("applicant.name").object({
5320
+ firstname: field("firstname").isValidEnglishName(),
5321
+ surname: field("surname").isValidEnglishName()
5322
+ }),
5323
+ message: {
5324
+ defaultMessage: "Input contains invalid characters. Please use only letters (a-z, A-Z), numbers (0-9), hyphens (-), apostrophes(') and underscores (_)",
5325
+ description: "This is the error message for invalid name",
5326
+ id: "v2.error.invalidName"
5327
+ }
5328
+ }
5329
+ ]
5178
5330
  },
5179
5331
  {
5180
5332
  id: "applicant.email",
@@ -6847,7 +6999,11 @@ function generateActionDocument({
6847
6999
  case ActionType.NOTIFY:
6848
7000
  return { ...actionBase, type: action };
6849
7001
  case ActionType.PRINT_CERTIFICATE:
6850
- return { ...actionBase, type: action };
7002
+ return {
7003
+ ...actionBase,
7004
+ type: action,
7005
+ content: defaults.content
7006
+ };
6851
7007
  case ActionType.REQUEST_CORRECTION:
6852
7008
  return { ...actionBase, type: action };
6853
7009
  case ActionType.APPROVE_CORRECTION:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencrvs/toolkit",
3
- "version": "1.8.1-rc.008155b",
3
+ "version": "1.8.1-rc.020858b",
4
4
  "description": "OpenCRVS toolkit for building country configurations",
5
5
  "license": "MPL-2.0",
6
6
  "exports": {
package/tsconfig.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "@opencrvs/commons/events": ["../commons/src/events/index.ts"]
20
20
  }
21
21
  },
22
- "references": [{ "path": "../commons" }],
22
+ "references": [{ "path": "../commons/tsconfig-commonjs.json" }],
23
23
  "include": ["src/**/*.ts"],
24
24
  "exclude": ["**/node_modules/**", "dist"]
25
25
  }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=conditionals.test.d.ts.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=validate-address.test.d.ts.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=validate.test.d.ts.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=utils.test.d.ts.map