@remoteoss/json-schema-form 0.5.0-dev.20230719162322 → 0.5.0-dev.20230901130231

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.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2023 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.5.0-dev.20230719162322
5
- Generated: Wed, 19 Jul 2023 16:23:38 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.5.0-dev.20230901130231
5
+ Generated: Fri, 01 Sep 2023 13:03:04 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -48,6 +48,69 @@ import omitBy from "lodash/omitBy";
48
48
  import set from "lodash/set";
49
49
  import { lazy } from "yup";
50
50
 
51
+ // src/utils.js
52
+ function convertDiskSizeFromTo(from, to) {
53
+ const units = ["bytes", "kb", "mb"];
54
+ return function convert(value) {
55
+ return value * Math.pow(1024, units.indexOf(from.toLowerCase())) / Math.pow(1024, units.indexOf(to.toLowerCase()));
56
+ };
57
+ }
58
+ function containsHTML(str = "") {
59
+ return /<[a-z][\s\S]*>/i.test(str);
60
+ }
61
+ function wrapWithSpan(html, properties = {}) {
62
+ const attributes = Object.entries(properties).reduce((acc, [key, value]) => `${acc}${key}="${value}" `, "").trim();
63
+ return `<span ${attributes}>${html}</span>`;
64
+ }
65
+ function hasProperty(object2, propertyName) {
66
+ return Object.prototype.hasOwnProperty.call(object2, propertyName);
67
+ }
68
+
69
+ // src/checkIfConditionMatches.js
70
+ function checkIfConditionMatches(node, formValues, formFields) {
71
+ return Object.keys(node.if.properties).every((name) => {
72
+ const currentProperty = node.if.properties[name];
73
+ const value = formValues[name];
74
+ const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
75
+ value === null;
76
+ const hasIfExplicit = node.if.required?.includes(name);
77
+ if (hasEmptyValue && !hasIfExplicit) {
78
+ return true;
79
+ }
80
+ if (hasProperty(currentProperty, "const")) {
81
+ return compareFormValueWithSchemaValue(value, currentProperty.const);
82
+ }
83
+ if (currentProperty.contains?.pattern) {
84
+ const formValue = value || [];
85
+ if (Array.isArray(formValue)) {
86
+ const pattern = new RegExp(currentProperty.contains.pattern);
87
+ return (value || []).some((item) => pattern.test(item));
88
+ }
89
+ }
90
+ if (currentProperty.enum) {
91
+ return currentProperty.enum.includes(value);
92
+ }
93
+ if (currentProperty.properties) {
94
+ return checkIfConditionMatches(
95
+ { if: currentProperty },
96
+ formValues[name],
97
+ getField(name, formFields).fields
98
+ );
99
+ }
100
+ const field = getField(name, formFields);
101
+ return validateFieldSchema(
102
+ {
103
+ options: field.options,
104
+ // @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
105
+ ...currentProperty,
106
+ inputType: field.inputType,
107
+ required: true
108
+ },
109
+ value
110
+ );
111
+ });
112
+ }
113
+
51
114
  // src/internals/helpers.js
52
115
  import merge from "lodash/fp/merge";
53
116
  import get from "lodash/get";
@@ -307,29 +370,108 @@ function _composeFieldCustomClosure(defaultComposeFn) {
307
370
  };
308
371
  }
309
372
 
310
- // src/utils.js
311
- function convertDiskSizeFromTo(from, to) {
312
- const units = ["bytes", "kb", "mb"];
313
- return function convert(value) {
314
- return value * Math.pow(1024, units.indexOf(from.toLowerCase())) / Math.pow(1024, units.indexOf(to.toLowerCase()));
373
+ // src/yupSchema.js
374
+ import flow from "lodash/flow";
375
+ import noop from "lodash/noop";
376
+ import { randexp } from "randexp";
377
+ import { string, number, boolean, object, array } from "yup";
378
+
379
+ // src/jsonLogic.js
380
+ import jsonLogic from "json-logic-js";
381
+ function createValidationChecker(schema) {
382
+ const scopes = /* @__PURE__ */ new Map();
383
+ function createScopes(jsonSchema, key = "root") {
384
+ scopes.set(key, createValidationsScope(jsonSchema));
385
+ Object.entries(jsonSchema?.properties ?? {}).filter(([, property]) => property.type === "object" || property.type === "array").forEach(([key2, property]) => {
386
+ if (property.type === "array") {
387
+ createScopes(property.items, `${key2}[]`);
388
+ } else {
389
+ createScopes(property, key2);
390
+ }
391
+ });
392
+ }
393
+ createScopes(schema);
394
+ return {
395
+ scopes,
396
+ getScope(name = "root") {
397
+ return scopes.get(name);
398
+ }
315
399
  };
316
400
  }
317
- function containsHTML(str = "") {
318
- return /<[a-z][\s\S]*>/i.test(str);
401
+ function createValidationsScope(schema) {
402
+ const validationMap = /* @__PURE__ */ new Map();
403
+ const computedValuesMap = /* @__PURE__ */ new Map();
404
+ const logic = schema?.["x-jsf-logic"] ?? {
405
+ validations: {},
406
+ computedValues: {}
407
+ };
408
+ const validations = Object.entries(logic.validations ?? {});
409
+ const computedValues = Object.entries(logic.computedValues ?? {});
410
+ validations.forEach(([id, validation]) => {
411
+ validationMap.set(id, validation);
412
+ });
413
+ computedValues.forEach(([id, computedValue]) => {
414
+ computedValuesMap.set(id, computedValue);
415
+ });
416
+ function validate(rule, values) {
417
+ return jsonLogic.apply(rule, replaceUndefinedValuesWithNulls(values));
418
+ }
419
+ return {
420
+ validationMap,
421
+ computedValuesMap,
422
+ validate,
423
+ applyValidationRuleInCondition(id, values) {
424
+ const validation = validationMap.get(id);
425
+ return validate(validation.rule, values);
426
+ },
427
+ applyComputedValueInField(id, values) {
428
+ const validation = computedValuesMap.get(id);
429
+ return validate(validation.rule, values);
430
+ },
431
+ applyComputedValueRuleInCondition(id, values) {
432
+ const validation = computedValuesMap.get(id);
433
+ return validate(validation.rule, values);
434
+ }
435
+ };
319
436
  }
320
- function wrapWithSpan(html, properties = {}) {
321
- const attributes = Object.entries(properties).reduce((acc, [key, value]) => `${acc}${key}="${value}" `, "").trim();
322
- return `<span ${attributes}>${html}</span>`;
437
+ function replaceUndefinedValuesWithNulls(values = {}) {
438
+ return Object.entries(values).reduce((prev, [key, value]) => {
439
+ return { ...prev, [key]: value === void 0 ? null : value };
440
+ }, {});
323
441
  }
324
- function hasProperty(object2, propertyName) {
325
- return Object.prototype.hasOwnProperty.call(object2, propertyName);
442
+ function yupSchemaWithCustomJSONLogic({ field, logic, config, id }) {
443
+ const { parentID = "root" } = config;
444
+ const validation = logic.getScope(parentID).validationMap.get(id);
445
+ return (yupSchema) => yupSchema.test(
446
+ `${field.name}-validation-${id}`,
447
+ validation?.errorMessage ?? "This field is invalid.",
448
+ (value, { parent }) => {
449
+ if (value === void 0 && !field.required)
450
+ return true;
451
+ return jsonLogic.apply(validation.rule, parent);
452
+ }
453
+ );
454
+ }
455
+ function calculateComputedAttributes(fieldParams, { parentID = "root" } = {}) {
456
+ return ({ logic, formValues }) => {
457
+ const { computedAttributes } = fieldParams;
458
+ const attributes = Object.fromEntries(
459
+ Object.entries(computedAttributes).map(handleComputedAttribute(logic, formValues, parentID)).filter(([, value]) => value !== null)
460
+ );
461
+ return attributes;
462
+ };
463
+ }
464
+ function handleComputedAttribute(logic, formValues, parentID) {
465
+ return ([key, value]) => {
466
+ if (key === "const")
467
+ return [key, logic.getScope(parentID).applyComputedValueInField(value, formValues)];
468
+ if (typeof value === "string") {
469
+ return [key, logic.getScope(parentID).applyComputedValueInField(value, formValues)];
470
+ }
471
+ };
326
472
  }
327
473
 
328
474
  // src/yupSchema.js
329
- import flow from "lodash/flow";
330
- import noop from "lodash/noop";
331
- import { randexp } from "randexp";
332
- import { string, number, boolean, object, array } from "yup";
333
475
  var DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
334
476
  var baseString = string().trim();
335
477
  var todayDateHint = (/* @__PURE__ */ new Date()).toISOString().substring(0, 10);
@@ -452,7 +594,7 @@ var getYupSchema = ({ inputType, ...field }) => {
452
594
  }
453
595
  return yupSchemas[inputType] || yupSchemasToJsonTypes[jsonType];
454
596
  };
455
- function buildYupSchema(field, config) {
597
+ function buildYupSchema(field, config, logic) {
456
598
  const { inputType, jsonType: jsonTypeValue, errorMessage = {}, ...propertyFields } = field;
457
599
  const isCheckboxBoolean = typeof propertyFields.checkboxValue === "boolean";
458
600
  let baseSchema;
@@ -525,6 +667,13 @@ function buildYupSchema(field, config) {
525
667
  }) : true
526
668
  );
527
669
  }
670
+ function withConst(yupSchema) {
671
+ return yupSchema.test(
672
+ "isConst",
673
+ errorMessage.const ?? errorMessageFromConfig.const ?? `The only accepted value is ${propertyFields.const}.`,
674
+ (value) => propertyFields.required === false && value === void 0 || value === null || value === propertyFields.const
675
+ );
676
+ }
528
677
  function withBaseSchema() {
529
678
  const customErrorMsg = errorMessage.type || errorMessageFromConfig.type;
530
679
  if (customErrorMsg) {
@@ -592,6 +741,14 @@ function buildYupSchema(field, config) {
592
741
  if (propertyFields.accept) {
593
742
  validators.push(withFileFormat);
594
743
  }
744
+ if (propertyFields.const) {
745
+ validators.push(withConst);
746
+ }
747
+ if (propertyFields.requiredValidations) {
748
+ propertyFields.requiredValidations.forEach(
749
+ (id) => validators.push(yupSchemaWithCustomJSONLogic({ field, id, logic, config }))
750
+ );
751
+ }
595
752
  return flow(validators);
596
753
  }
597
754
  function getNoSortEdges(fields = []) {
@@ -631,50 +788,14 @@ function hasType(type, typeName) {
631
788
  function getField(fieldName, fields) {
632
789
  return fields.find(({ name }) => name === fieldName);
633
790
  }
634
- function validateFieldSchema(field, value) {
635
- const validator = buildYupSchema(field);
791
+ function validateFieldSchema(field, value, logic) {
792
+ const validator = buildYupSchema(field, {}, logic);
636
793
  return validator().isValidSync(value);
637
794
  }
638
795
  function compareFormValueWithSchemaValue(formValue, schemaValue) {
639
796
  const currentPropertyValue = typeof schemaValue === "number" ? schemaValue : schemaValue || void 0;
640
797
  return String(formValue) === String(currentPropertyValue);
641
798
  }
642
- function checkIfConditionMatches(node, formValues, formFields) {
643
- return Object.keys(node.if.properties).every((name) => {
644
- const currentProperty = node.if.properties[name];
645
- const value = formValues[name];
646
- const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
647
- value === null;
648
- const hasIfExplicit = node.if.required?.includes(name);
649
- if (hasEmptyValue && !hasIfExplicit) {
650
- return true;
651
- }
652
- if (hasProperty(currentProperty, "const")) {
653
- return compareFormValueWithSchemaValue(value, currentProperty.const);
654
- }
655
- if (currentProperty.contains?.pattern) {
656
- const formValue = value || [];
657
- if (Array.isArray(formValue)) {
658
- const pattern = new RegExp(currentProperty.contains.pattern);
659
- return (value || []).some((item) => pattern.test(item));
660
- }
661
- }
662
- if (currentProperty.enum) {
663
- return currentProperty.enum.includes(value);
664
- }
665
- const field = getField(name, formFields);
666
- return validateFieldSchema(
667
- {
668
- options: field.options,
669
- // @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
670
- ...currentProperty,
671
- inputType: field.inputType,
672
- required: true
673
- },
674
- value
675
- );
676
- });
677
- }
678
799
  function isFieldFilled(fieldValue) {
679
800
  return Array.isArray(fieldValue) ? fieldValue.length > 0 : !!fieldValue;
680
801
  }
@@ -704,7 +825,16 @@ function getPrefillSubFieldValues(field, defaultValues, parentFieldKeyPath) {
704
825
  initialValue[field.name] = subFieldValues;
705
826
  }
706
827
  } else {
707
- initialValue = getPrefillValues([field], initialValue);
828
+ if (typeof initialValue !== "object") {
829
+ console.warn(
830
+ `Field "${parentFieldKeyPath}"'s value is "${initialValue}", but should be type object.`
831
+ );
832
+ initialValue = getPrefillValues([field], {
833
+ // TODO nested fieldsets are not handled
834
+ });
835
+ } else {
836
+ initialValue = getPrefillValues([field], initialValue);
837
+ }
708
838
  }
709
839
  return initialValue;
710
840
  }
@@ -733,7 +863,7 @@ function getPrefillValues(fields, initialValues = {}) {
733
863
  });
734
864
  return initialValues;
735
865
  }
736
- function updateField(field, requiredFields, node, formValues) {
866
+ function updateField(field, requiredFields, node, formValues, logic, config) {
737
867
  if (!field) {
738
868
  return;
739
869
  }
@@ -755,6 +885,17 @@ function updateField(field, requiredFields, node, formValues) {
755
885
  }
756
886
  }
757
887
  });
888
+ if (field.getComputedAttributes) {
889
+ const computedFieldValues = field.getComputedAttributes({
890
+ field,
891
+ isRequired: fieldIsRequired,
892
+ node,
893
+ formValues,
894
+ config,
895
+ logic
896
+ });
897
+ updateValues(computedFieldValues);
898
+ }
758
899
  if (field.calculateConditionalProperties) {
759
900
  const newFieldValues = field.calculateConditionalProperties(fieldIsRequired, node);
760
901
  updateValues(newFieldValues);
@@ -768,33 +909,46 @@ function updateField(field, requiredFields, node, formValues) {
768
909
  updateValues(newFieldValues);
769
910
  }
770
911
  }
771
- function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */ new Set()) {
912
+ function processNode({
913
+ node,
914
+ formValues,
915
+ formFields,
916
+ accRequired = /* @__PURE__ */ new Set(),
917
+ parentID = "root",
918
+ logic
919
+ }) {
772
920
  const requiredFields = new Set(accRequired);
773
921
  Object.keys(node.properties ?? []).forEach((fieldName) => {
774
922
  const field = getField(fieldName, formFields);
775
- updateField(field, requiredFields, node, formValues);
923
+ updateField(field, requiredFields, node, formValues, logic, { parentID });
776
924
  });
777
925
  node.required?.forEach((fieldName) => {
778
926
  requiredFields.add(fieldName);
779
- updateField(getField(fieldName, formFields), requiredFields, node, formValues);
927
+ updateField(getField(fieldName, formFields), requiredFields, node, formValues, logic, {
928
+ parentID
929
+ });
780
930
  });
781
931
  if (node.if) {
782
- const matchesCondition = checkIfConditionMatches(node, formValues, formFields);
932
+ const matchesCondition = checkIfConditionMatches(node, formValues, formFields, logic);
783
933
  if (matchesCondition && node.then) {
784
- const { required: branchRequired } = processNode(
785
- node.then,
934
+ const { required: branchRequired } = processNode({
935
+ node: node.then,
786
936
  formValues,
787
937
  formFields,
788
- requiredFields
789
- );
938
+ accRequired: requiredFields,
939
+ parentID,
940
+ logic
941
+ });
790
942
  branchRequired.forEach((field) => requiredFields.add(field));
791
943
  } else if (node.else) {
792
- const { required: branchRequired } = processNode(
793
- node.else,
944
+ const { required: branchRequired } = processNode({
945
+ node: node.else,
794
946
  formValues,
795
947
  formFields,
796
- requiredFields
797
- );
948
+ accRequired: requiredFields,
949
+ parentID,
950
+ logic
951
+ });
798
952
  branchRequired.forEach((field) => requiredFields.add(field));
799
953
  }
800
954
  }
@@ -806,12 +960,21 @@ function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */
806
960
  node.anyOf.forEach(({ required = [] }) => {
807
961
  required.forEach((fieldName) => {
808
962
  const field = getField(fieldName, formFields);
809
- updateField(field, requiredFields, node, formValues);
963
+ updateField(field, requiredFields, node, formValues, logic, { parentID });
810
964
  });
811
965
  });
812
966
  }
813
967
  if (node.allOf) {
814
- node.allOf.map((allOfNode) => processNode(allOfNode, formValues, formFields, requiredFields)).forEach(({ required: allOfItemRequired }) => {
968
+ node.allOf.map(
969
+ (allOfNode) => processNode({
970
+ node: allOfNode,
971
+ formValues,
972
+ formFields,
973
+ accRequired: requiredFields,
974
+ parentID,
975
+ logic
976
+ })
977
+ ).forEach(({ required: allOfItemRequired }) => {
815
978
  allOfItemRequired.forEach(requiredFields.add, requiredFields);
816
979
  });
817
980
  }
@@ -819,7 +982,13 @@ function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */
819
982
  Object.entries(node.properties).forEach(([name, nestedNode]) => {
820
983
  const inputType = getInputType(nestedNode);
821
984
  if (inputType === supportedTypes.FIELDSET) {
822
- processNode(nestedNode, formValues[name] || {}, getField(name, formFields).fields);
985
+ processNode({
986
+ node: nestedNode,
987
+ formValues: formValues[name] || {},
988
+ formFields: getField(name, formFields).fields,
989
+ parentID: name,
990
+ logic
991
+ });
823
992
  }
824
993
  });
825
994
  }
@@ -837,11 +1006,11 @@ function clearValuesIfNotVisible(fields, formValues) {
837
1006
  }
838
1007
  });
839
1008
  }
840
- function updateFieldsProperties(fields, formValues, jsonSchema) {
1009
+ function updateFieldsProperties(fields, formValues, jsonSchema, logic) {
841
1010
  if (!jsonSchema?.properties) {
842
1011
  return;
843
1012
  }
844
- processNode(jsonSchema, formValues, fields);
1013
+ processNode({ node: jsonSchema, formValues, formFields: fields, logic });
845
1014
  clearValuesIfNotVisible(fields, formValues);
846
1015
  }
847
1016
  var notNullOption = (opt) => opt.const !== null;
@@ -884,11 +1053,15 @@ function extractParametersFromNode(schemaNode) {
884
1053
  }
885
1054
  const presentation = pickXKey(schemaNode, "presentation") ?? {};
886
1055
  const errorMessage = pickXKey(schemaNode, "errorMessage") ?? {};
1056
+ const requiredValidations = schemaNode["x-jsf-logic-validations"];
1057
+ const computedAttributes = schemaNode["x-jsf-logic-computedAttrs"];
1058
+ const decoratedComputedAttributes = getDecoratedComputedAttributes(computedAttributes);
887
1059
  const node = omit(schemaNode, ["x-jsf-presentation", "presentation"]);
888
1060
  const description = presentation?.description || node.description;
889
1061
  const statementDescription = containsHTML(presentation.statement?.description) ? wrapWithSpan(presentation.statement.description, { class: "jsf-statement" }) : presentation.statement?.description;
890
1062
  return omitBy(
891
1063
  {
1064
+ const: node.const,
892
1065
  label: node.title,
893
1066
  readOnly: node.readOnly,
894
1067
  ...node.deprecated && {
@@ -923,6 +1096,8 @@ function extractParametersFromNode(schemaNode) {
923
1096
  },
924
1097
  // Handle [name].presentation
925
1098
  ...presentation,
1099
+ requiredValidations,
1100
+ computedAttributes: decoratedComputedAttributes,
926
1101
  description: containsHTML(description) ? wrapWithSpan(description, {
927
1102
  class: "jsf-description"
928
1103
  }) : description,
@@ -959,8 +1134,8 @@ function yupToFormErrors(yupError) {
959
1134
  }
960
1135
  return errors;
961
1136
  }
962
- var handleValuesChange = (fields, jsonSchema, config) => (values) => {
963
- updateFieldsProperties(fields, values, jsonSchema);
1137
+ var handleValuesChange = (fields, jsonSchema, config, logic) => (values) => {
1138
+ updateFieldsProperties(fields, values, jsonSchema, logic);
964
1139
  const lazySchema = lazy(() => buildCompleteYupSchema(fields, config));
965
1140
  let errors;
966
1141
  try {
@@ -979,6 +1154,12 @@ var handleValuesChange = (fields, jsonSchema, config) => (values) => {
979
1154
  formErrors: yupToFormErrors(errors)
980
1155
  };
981
1156
  };
1157
+ function getDecoratedComputedAttributes(computedAttributes) {
1158
+ return {
1159
+ ...computedAttributes ?? {},
1160
+ ...computedAttributes?.const && computedAttributes?.default ? { value: computedAttributes.const } : {}
1161
+ };
1162
+ }
982
1163
 
983
1164
  // src/calculateConditionalProperties.js
984
1165
  function isFieldRequired(node, field) {
@@ -1180,6 +1361,9 @@ function applyFieldsDependencies(fieldsParameters, node) {
1180
1361
  applyFieldsDependencies(fieldsParameters, condition);
1181
1362
  });
1182
1363
  }
1364
+ if (node?.["x-jsf-logic"]) {
1365
+ applyFieldsDependencies(fieldsParameters, node["x-jsf-logic"]);
1366
+ }
1183
1367
  }
1184
1368
  function getCustomPropertiesForField(fieldParams, config) {
1185
1369
  return config?.customProperties?.[fieldParams.name];
@@ -1191,15 +1375,16 @@ function getComposeFunctionForField(fieldParams, hasCustomizations) {
1191
1375
  }
1192
1376
  return composeFn;
1193
1377
  }
1194
- function buildField(fieldParams, config, scopedJsonSchema) {
1378
+ function buildField(fieldParams, config, scopedJsonSchema, logic) {
1195
1379
  const customProperties = getCustomPropertiesForField(fieldParams, config);
1196
1380
  const composeFn = getComposeFunctionForField(fieldParams, !!customProperties);
1197
- const yupSchema = buildYupSchema(fieldParams, config);
1381
+ const yupSchema = buildYupSchema(fieldParams, config, logic);
1198
1382
  const calculateConditionalFieldsClosure = fieldParams.isDynamic && calculateConditionalProperties(fieldParams, customProperties);
1199
1383
  const calculateCustomValidationPropertiesClosure = calculateCustomValidationProperties(
1200
1384
  fieldParams,
1201
1385
  customProperties
1202
1386
  );
1387
+ const getComputedAttributes = Object.keys(fieldParams.computedAttributes).length > 0 && calculateComputedAttributes(fieldParams, config);
1203
1388
  const hasCustomValidations = !!customProperties && size(pick2(customProperties, SUPPORTED_CUSTOM_VALIDATION_FIELD_PARAMS)) > 0;
1204
1389
  const finalFieldParams = {
1205
1390
  // invalid attribute cleanup
@@ -1212,6 +1397,7 @@ function buildField(fieldParams, config, scopedJsonSchema) {
1212
1397
  ...hasCustomValidations && {
1213
1398
  calculateCustomValidationProperties: calculateCustomValidationPropertiesClosure
1214
1399
  },
1400
+ ...getComputedAttributes && { getComputedAttributes },
1215
1401
  // field customization properties
1216
1402
  ...customProperties && { fieldCustomization: customProperties },
1217
1403
  // base schema
@@ -1220,7 +1406,7 @@ function buildField(fieldParams, config, scopedJsonSchema) {
1220
1406
  };
1221
1407
  return composeFn(finalFieldParams);
1222
1408
  }
1223
- function getFieldsFromJSONSchema(scopedJsonSchema, config) {
1409
+ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
1224
1410
  if (!scopedJsonSchema) {
1225
1411
  return [];
1226
1412
  }
@@ -1244,11 +1430,11 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config) {
1244
1430
  fields: () => groupArrayFields,
1245
1431
  addFieldText: fieldParams.addFieldText
1246
1432
  };
1247
- buildField(fieldParams, config, scopedJsonSchema).forEach((groupField) => {
1433
+ buildField(fieldParams, config, scopedJsonSchema, logic).forEach((groupField) => {
1248
1434
  fields.push(groupField);
1249
1435
  });
1250
1436
  } else {
1251
- fields.push(buildField(fieldParams, config, scopedJsonSchema));
1437
+ fields.push(buildField(fieldParams, config, scopedJsonSchema, logic));
1252
1438
  }
1253
1439
  });
1254
1440
  return fields;
@@ -1259,9 +1445,15 @@ function createHeadlessForm(jsonSchema, customConfig = {}) {
1259
1445
  ...customConfig
1260
1446
  };
1261
1447
  try {
1262
- const fields = getFieldsFromJSONSchema(jsonSchema, config);
1263
- const handleValidation = handleValuesChange(fields, jsonSchema, config);
1264
- updateFieldsProperties(fields, getPrefillValues(fields, config.initialValues), jsonSchema);
1448
+ const logic = createValidationChecker(jsonSchema);
1449
+ const fields = getFieldsFromJSONSchema(jsonSchema, config, logic);
1450
+ const handleValidation = handleValuesChange(fields, jsonSchema, config, logic);
1451
+ updateFieldsProperties(
1452
+ fields,
1453
+ getPrefillValues(fields, config.initialValues),
1454
+ jsonSchema,
1455
+ logic
1456
+ );
1265
1457
  return {
1266
1458
  fields,
1267
1459
  handleValidation,