@remoteoss/json-schema-form 0.4.3-beta.0 → 0.4.4-dev.20230829101351
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.cjs +500 -62
- package/dist/index.js +500 -62
- package/dist/standalone.js +878 -62
- package/package.json +2 -1
- package/src/tests/jsonLogic.test.js +814 -0
- package/src/tests/jsonLogicFixtures.js +1489 -0
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.4.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.4.4-dev.20230829101351
|
|
5
|
+
Generated: Tue, 29 Aug 2023 10:14:13 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -67,8 +67,8 @@ function hasProperty(object2, propertyName) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// src/checkIfConditionMatches.js
|
|
70
|
-
function checkIfConditionMatches(node, formValues, formFields) {
|
|
71
|
-
return Object.keys(node.if.properties).every((name) => {
|
|
70
|
+
function checkIfConditionMatches(node, formValues, formFields, validations) {
|
|
71
|
+
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
72
72
|
const currentProperty = node.if.properties[name];
|
|
73
73
|
const value = formValues[name];
|
|
74
74
|
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
@@ -94,7 +94,8 @@ function checkIfConditionMatches(node, formValues, formFields) {
|
|
|
94
94
|
return checkIfConditionMatches(
|
|
95
95
|
{ if: currentProperty },
|
|
96
96
|
formValues[name],
|
|
97
|
-
getField(name, formFields).fields
|
|
97
|
+
getField(name, formFields).fields,
|
|
98
|
+
validations
|
|
98
99
|
);
|
|
99
100
|
}
|
|
100
101
|
const field = getField(name, formFields);
|
|
@@ -110,6 +111,23 @@ function checkIfConditionMatches(node, formValues, formFields) {
|
|
|
110
111
|
);
|
|
111
112
|
});
|
|
112
113
|
}
|
|
114
|
+
function checkIfMatchesValidationsAndComputedValues(node, formValues, validations, parentID) {
|
|
115
|
+
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
116
|
+
const currentValue = validations.getScope(parentID).evaluateValidationRuleInCondition(name, formValues);
|
|
117
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
118
|
+
return true;
|
|
119
|
+
return false;
|
|
120
|
+
});
|
|
121
|
+
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
122
|
+
([name, property]) => {
|
|
123
|
+
const currentValue = validations.getScope(parentID).evaluateComputedValueRuleInCondition(name, formValues);
|
|
124
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
125
|
+
return true;
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
return computedValuesMatch && validationsMatch;
|
|
130
|
+
}
|
|
113
131
|
|
|
114
132
|
// src/internals/helpers.js
|
|
115
133
|
import merge from "lodash/fp/merge";
|
|
@@ -370,6 +388,9 @@ function _composeFieldCustomClosure(defaultComposeFn) {
|
|
|
370
388
|
};
|
|
371
389
|
}
|
|
372
390
|
|
|
391
|
+
// src/jsonLogic.js
|
|
392
|
+
import jsonLogic from "json-logic-js";
|
|
393
|
+
|
|
373
394
|
// src/yupSchema.js
|
|
374
395
|
import flow from "lodash/flow";
|
|
375
396
|
import noop from "lodash/noop";
|
|
@@ -497,7 +518,7 @@ var getYupSchema = ({ inputType, ...field }) => {
|
|
|
497
518
|
}
|
|
498
519
|
return yupSchemas[inputType] || yupSchemasToJsonTypes[jsonType];
|
|
499
520
|
};
|
|
500
|
-
function buildYupSchema(field, config) {
|
|
521
|
+
function buildYupSchema(field, config, validations) {
|
|
501
522
|
const { inputType, jsonType: jsonTypeValue, errorMessage = {}, ...propertyFields } = field;
|
|
502
523
|
const isCheckboxBoolean = typeof propertyFields.checkboxValue === "boolean";
|
|
503
524
|
let baseSchema;
|
|
@@ -570,6 +591,13 @@ function buildYupSchema(field, config) {
|
|
|
570
591
|
}) : true
|
|
571
592
|
);
|
|
572
593
|
}
|
|
594
|
+
function withConst(yupSchema) {
|
|
595
|
+
return yupSchema.test(
|
|
596
|
+
"isConst",
|
|
597
|
+
errorMessage.const ?? errorMessageFromConfig.const ?? `The only accepted value is ${propertyFields.const}.`,
|
|
598
|
+
(value) => propertyFields.required === false && value === void 0 || value === null || value === propertyFields.const
|
|
599
|
+
);
|
|
600
|
+
}
|
|
573
601
|
function withBaseSchema() {
|
|
574
602
|
const customErrorMsg = errorMessage.type || errorMessageFromConfig.type;
|
|
575
603
|
if (customErrorMsg) {
|
|
@@ -590,7 +618,8 @@ function buildYupSchema(field, config) {
|
|
|
590
618
|
...fieldSetfield,
|
|
591
619
|
inputType: fieldSetfield.type
|
|
592
620
|
},
|
|
593
|
-
config
|
|
621
|
+
{ ...config, parentID: field.name },
|
|
622
|
+
validations
|
|
594
623
|
)();
|
|
595
624
|
}
|
|
596
625
|
});
|
|
@@ -601,7 +630,11 @@ function buildYupSchema(field, config) {
|
|
|
601
630
|
propertyFields.nthFieldGroup.fields().reduce(
|
|
602
631
|
(schema, groupArrayField) => ({
|
|
603
632
|
...schema,
|
|
604
|
-
[groupArrayField.name]: buildYupSchema(
|
|
633
|
+
[groupArrayField.name]: buildYupSchema(
|
|
634
|
+
groupArrayField,
|
|
635
|
+
{ ...config, parentID: `${propertyFields.nthFieldGroup.name}[]` },
|
|
636
|
+
validations
|
|
637
|
+
)()
|
|
605
638
|
}),
|
|
606
639
|
{}
|
|
607
640
|
)
|
|
@@ -637,6 +670,14 @@ function buildYupSchema(field, config) {
|
|
|
637
670
|
if (propertyFields.accept) {
|
|
638
671
|
validators.push(withFileFormat);
|
|
639
672
|
}
|
|
673
|
+
if (propertyFields.const) {
|
|
674
|
+
validators.push(withConst);
|
|
675
|
+
}
|
|
676
|
+
if (propertyFields.requiredValidations) {
|
|
677
|
+
propertyFields.requiredValidations.forEach(
|
|
678
|
+
(id) => validators.push(yupSchemaWithCustomJSONLogic({ field, id, validations, config }))
|
|
679
|
+
);
|
|
680
|
+
}
|
|
640
681
|
return flow(validators);
|
|
641
682
|
}
|
|
642
683
|
function getNoSortEdges(fields = []) {
|
|
@@ -647,26 +688,322 @@ function getNoSortEdges(fields = []) {
|
|
|
647
688
|
return list;
|
|
648
689
|
}, []);
|
|
649
690
|
}
|
|
650
|
-
function getSchema(fields = [], config) {
|
|
691
|
+
function getSchema(fields = [], config, validations) {
|
|
651
692
|
const newSchema = {};
|
|
652
693
|
fields.forEach((field) => {
|
|
653
694
|
if (field.schema) {
|
|
654
695
|
if (field.name) {
|
|
655
696
|
if (field.inputType === supportedTypes.FIELDSET) {
|
|
656
|
-
const fieldsetSchema = buildYupSchema(
|
|
697
|
+
const fieldsetSchema = buildYupSchema(
|
|
698
|
+
field,
|
|
699
|
+
{ ...config, parentID: field.name },
|
|
700
|
+
validations
|
|
701
|
+
)();
|
|
657
702
|
newSchema[field.name] = fieldsetSchema;
|
|
658
703
|
} else {
|
|
659
704
|
newSchema[field.name] = field.schema;
|
|
660
705
|
}
|
|
661
706
|
} else {
|
|
662
|
-
Object.assign(newSchema, getSchema(field.fields, config));
|
|
707
|
+
Object.assign(newSchema, getSchema(field.fields, config, validations));
|
|
663
708
|
}
|
|
664
709
|
}
|
|
665
710
|
});
|
|
666
711
|
return newSchema;
|
|
667
712
|
}
|
|
668
|
-
function buildCompleteYupSchema(fields, config) {
|
|
669
|
-
return object().shape(getSchema(fields, config), getNoSortEdges(fields));
|
|
713
|
+
function buildCompleteYupSchema(fields, config, validations) {
|
|
714
|
+
return object().shape(getSchema(fields, config, validations), getNoSortEdges(fields));
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// src/jsonLogic.js
|
|
718
|
+
function createValidationChecker(schema) {
|
|
719
|
+
const scopes = /* @__PURE__ */ new Map();
|
|
720
|
+
function createScopes(jsonSchema, key = "root") {
|
|
721
|
+
const sampleEmptyObject = buildSampleEmptyObject(schema);
|
|
722
|
+
scopes.set(key, createValidationsScope(jsonSchema));
|
|
723
|
+
Object.entries(jsonSchema?.properties ?? {}).filter(([, property]) => property.type === "object" || property.type === "array").forEach(([key2, property]) => {
|
|
724
|
+
if (property.type === "array") {
|
|
725
|
+
createScopes(property.items, `${key2}[]`);
|
|
726
|
+
}
|
|
727
|
+
createScopes(property, key2);
|
|
728
|
+
});
|
|
729
|
+
validateInlineRules(jsonSchema, sampleEmptyObject);
|
|
730
|
+
}
|
|
731
|
+
createScopes(schema);
|
|
732
|
+
return {
|
|
733
|
+
scopes,
|
|
734
|
+
getScope(name = "root") {
|
|
735
|
+
return scopes.get(name);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
function createValidationsScope(schema) {
|
|
740
|
+
const validationMap = /* @__PURE__ */ new Map();
|
|
741
|
+
const computedValuesMap = /* @__PURE__ */ new Map();
|
|
742
|
+
const logic = schema?.["x-jsf-logic"] ?? {
|
|
743
|
+
validations: {},
|
|
744
|
+
computedValues: {}
|
|
745
|
+
};
|
|
746
|
+
const validations = Object.entries(logic.validations ?? {});
|
|
747
|
+
const computedValues = Object.entries(logic.computedValues ?? {});
|
|
748
|
+
const sampleEmptyObject = buildSampleEmptyObject(schema);
|
|
749
|
+
validations.forEach(([id, validation]) => {
|
|
750
|
+
if (!validation.rule) {
|
|
751
|
+
throw Error(`Missing rule for validation with id of: "${id}".`);
|
|
752
|
+
}
|
|
753
|
+
checkRuleIntegrity(validation.rule, id, sampleEmptyObject);
|
|
754
|
+
validationMap.set(id, validation);
|
|
755
|
+
});
|
|
756
|
+
computedValues.forEach(([id, computedValue]) => {
|
|
757
|
+
if (!computedValue.rule) {
|
|
758
|
+
throw Error(`Missing rule for computedValue with id of: "${id}".`);
|
|
759
|
+
}
|
|
760
|
+
checkRuleIntegrity(computedValue.rule, id, sampleEmptyObject);
|
|
761
|
+
computedValuesMap.set(id, computedValue);
|
|
762
|
+
});
|
|
763
|
+
function evaluateValidation(rule, values) {
|
|
764
|
+
return jsonLogic.apply(rule, clean(values));
|
|
765
|
+
}
|
|
766
|
+
return {
|
|
767
|
+
validationMap,
|
|
768
|
+
computedValuesMap,
|
|
769
|
+
evaluateValidation,
|
|
770
|
+
evaluateValidationRuleInCondition(id, values) {
|
|
771
|
+
const validation = validationMap.get(id);
|
|
772
|
+
if (validation === void 0)
|
|
773
|
+
throw Error(`"${id}" validation in if condition doesn't exist.`);
|
|
774
|
+
return evaluateValidation(validation.rule, values);
|
|
775
|
+
},
|
|
776
|
+
evaluateComputedValueRuleForField(id, values, fieldName) {
|
|
777
|
+
const validation = computedValuesMap.get(id);
|
|
778
|
+
if (validation === void 0)
|
|
779
|
+
throw Error(`"${id}" computedValue in field "${fieldName}" doesn't exist.`);
|
|
780
|
+
return evaluateValidation(validation.rule, values);
|
|
781
|
+
},
|
|
782
|
+
evaluateComputedValueRuleInCondition(id, values) {
|
|
783
|
+
const validation = computedValuesMap.get(id);
|
|
784
|
+
if (validation === void 0)
|
|
785
|
+
throw Error(`"${id}" computedValue in if condition doesn't exist.`);
|
|
786
|
+
return evaluateValidation(validation.rule, values);
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
function clean(values = {}) {
|
|
791
|
+
return Object.entries(values).reduce((prev, [key, value]) => {
|
|
792
|
+
return { ...prev, [key]: value === void 0 ? null : value };
|
|
793
|
+
}, {});
|
|
794
|
+
}
|
|
795
|
+
function yupSchemaWithCustomJSONLogic({ field, validations, config, id }) {
|
|
796
|
+
const { parentID = "root" } = config;
|
|
797
|
+
const validation = validations.getScope(parentID).validationMap.get(id);
|
|
798
|
+
if (validation === void 0) {
|
|
799
|
+
throw Error(`Validation "${id}" required for "${field.name}" doesn't exist.`);
|
|
800
|
+
}
|
|
801
|
+
return (yupSchema) => yupSchema.test(
|
|
802
|
+
`${field.name}-validation-${id}`,
|
|
803
|
+
validation?.errorMessage ?? "This field is invalid.",
|
|
804
|
+
(value, { parent }) => {
|
|
805
|
+
if (value === void 0 && !field.required)
|
|
806
|
+
return true;
|
|
807
|
+
return jsonLogic.apply(validation.rule, parent);
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
function replaceHandlebarsTemplates({
|
|
812
|
+
value: toReplace,
|
|
813
|
+
validations,
|
|
814
|
+
formValues,
|
|
815
|
+
parentID,
|
|
816
|
+
name: fieldName
|
|
817
|
+
}) {
|
|
818
|
+
if (typeof toReplace === "string") {
|
|
819
|
+
return toReplace.replace(/\{\{([^{}]+)\}\}/g, (match, key) => {
|
|
820
|
+
return validations.getScope(parentID).evaluateComputedValueRuleForField(key.trim(), formValues, fieldName);
|
|
821
|
+
});
|
|
822
|
+
} else if (typeof toReplace === "object") {
|
|
823
|
+
const { value, ...rules } = toReplace;
|
|
824
|
+
if (Object.keys(rules).length > 1 && !value)
|
|
825
|
+
throw Error("Cannot define multiple rules without a template string with key `value`.");
|
|
826
|
+
const computedTemplateValue = Object.entries(rules).reduce((prev, [key, rule]) => {
|
|
827
|
+
const computedValue = validations.getScope(parentID).evaluateValidation(rule, formValues);
|
|
828
|
+
return prev.replaceAll(`{{${key}}}`, computedValue);
|
|
829
|
+
}, value);
|
|
830
|
+
return computedTemplateValue.replace(/\{\{([^{}]+)\}\}/g, (match, key) => {
|
|
831
|
+
return validations.getScope(parentID).evaluateComputedValueRuleForField(key.trim(), formValues, fieldName);
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
function calculateComputedAttributes(fieldParams, { parentID = "root" } = {}) {
|
|
836
|
+
return ({ validations, isRequired, config, formValues }) => {
|
|
837
|
+
const { name, computedAttributes } = fieldParams;
|
|
838
|
+
const attributes = Object.fromEntries(
|
|
839
|
+
Object.entries(computedAttributes).map(handleComputedAttribute(validations, formValues, parentID, name)).filter(([, value]) => value !== null)
|
|
840
|
+
);
|
|
841
|
+
return {
|
|
842
|
+
...attributes,
|
|
843
|
+
schema: buildYupSchema(
|
|
844
|
+
{ ...fieldParams, ...attributes, required: isRequired },
|
|
845
|
+
config,
|
|
846
|
+
validations
|
|
847
|
+
)
|
|
848
|
+
};
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
function handleComputedAttribute(validations, formValues, parentID, name) {
|
|
852
|
+
return ([key, value]) => {
|
|
853
|
+
if (key === "description")
|
|
854
|
+
return [key, replaceHandlebarsTemplates({ value, validations, formValues, parentID, name })];
|
|
855
|
+
if (key === "title") {
|
|
856
|
+
return [
|
|
857
|
+
"label",
|
|
858
|
+
replaceHandlebarsTemplates({ value, validations, formValues, parentID, name })
|
|
859
|
+
];
|
|
860
|
+
}
|
|
861
|
+
if (key === "const")
|
|
862
|
+
return [
|
|
863
|
+
key,
|
|
864
|
+
validations.getScope(parentID).evaluateComputedValueRuleForField(value, formValues, name)
|
|
865
|
+
];
|
|
866
|
+
if (key === "x-jsf-errorMessage") {
|
|
867
|
+
return [
|
|
868
|
+
"errorMessage",
|
|
869
|
+
handleNestedObjectForComputedValues(value, formValues, parentID, validations, name)
|
|
870
|
+
];
|
|
871
|
+
}
|
|
872
|
+
if (typeof value === "string") {
|
|
873
|
+
return [
|
|
874
|
+
key,
|
|
875
|
+
validations.getScope(parentID).evaluateComputedValueRuleForField(value, formValues, name)
|
|
876
|
+
];
|
|
877
|
+
}
|
|
878
|
+
if (key === "x-jsf-presentation" && value.statement) {
|
|
879
|
+
return [
|
|
880
|
+
"statement",
|
|
881
|
+
handleNestedObjectForComputedValues(
|
|
882
|
+
value.statement,
|
|
883
|
+
formValues,
|
|
884
|
+
parentID,
|
|
885
|
+
validations,
|
|
886
|
+
name
|
|
887
|
+
)
|
|
888
|
+
];
|
|
889
|
+
}
|
|
890
|
+
if (typeof value === "object" && value.rule) {
|
|
891
|
+
return [key, validations.getScope(parentID).evaluateValidation(value.rule, formValues)];
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
function handleNestedObjectForComputedValues(values, formValues, parentID, validations, name) {
|
|
896
|
+
return Object.fromEntries(
|
|
897
|
+
Object.entries(values).map(([key, value]) => {
|
|
898
|
+
return [key, replaceHandlebarsTemplates({ value, validations, formValues, parentID, name })];
|
|
899
|
+
})
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
function processJSONLogicNode({
|
|
903
|
+
node,
|
|
904
|
+
formFields,
|
|
905
|
+
formValues,
|
|
906
|
+
accRequired,
|
|
907
|
+
parentID,
|
|
908
|
+
validations
|
|
909
|
+
}) {
|
|
910
|
+
const requiredFields = new Set(accRequired);
|
|
911
|
+
if (node.allOf) {
|
|
912
|
+
node.allOf.map(
|
|
913
|
+
(allOfNode) => processJSONLogicNode({ node: allOfNode, formValues, formFields, validations, parentID })
|
|
914
|
+
).forEach(({ required: allOfItemRequired }) => {
|
|
915
|
+
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
if (node.if) {
|
|
919
|
+
const matchesPropertyCondition = checkIfConditionMatches(
|
|
920
|
+
node,
|
|
921
|
+
formValues,
|
|
922
|
+
formFields,
|
|
923
|
+
validations
|
|
924
|
+
);
|
|
925
|
+
const matchesValidationsAndComputedValues = checkIfMatchesValidationsAndComputedValues(
|
|
926
|
+
node,
|
|
927
|
+
formValues,
|
|
928
|
+
validations,
|
|
929
|
+
parentID
|
|
930
|
+
);
|
|
931
|
+
const isConditionMatch = matchesPropertyCondition && matchesValidationsAndComputedValues;
|
|
932
|
+
if (isConditionMatch && node.then) {
|
|
933
|
+
const { required: branchRequired } = processNode({
|
|
934
|
+
node: node.then,
|
|
935
|
+
formValues,
|
|
936
|
+
formFields,
|
|
937
|
+
accRequired,
|
|
938
|
+
validations
|
|
939
|
+
});
|
|
940
|
+
branchRequired.forEach((field) => requiredFields.add(field));
|
|
941
|
+
}
|
|
942
|
+
if (!isConditionMatch && node.else) {
|
|
943
|
+
const { required: branchRequired } = processNode({
|
|
944
|
+
node: node.else,
|
|
945
|
+
formValues,
|
|
946
|
+
formFields,
|
|
947
|
+
accRequired: requiredFields,
|
|
948
|
+
validations
|
|
949
|
+
});
|
|
950
|
+
branchRequired.forEach((field) => requiredFields.add(field));
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return { required: requiredFields };
|
|
954
|
+
}
|
|
955
|
+
function buildSampleEmptyObject(schema = {}) {
|
|
956
|
+
const sample = {};
|
|
957
|
+
if (typeof schema !== "object" || !schema.properties) {
|
|
958
|
+
return schema;
|
|
959
|
+
}
|
|
960
|
+
for (const key in schema.properties) {
|
|
961
|
+
if (schema.properties[key].type === "object") {
|
|
962
|
+
sample[key] = buildSampleEmptyObject(schema.properties[key]);
|
|
963
|
+
} else if (schema.properties[key].type === "array") {
|
|
964
|
+
const itemSchema = schema.properties[key].items;
|
|
965
|
+
sample[key] = buildSampleEmptyObject(itemSchema);
|
|
966
|
+
} else {
|
|
967
|
+
sample[key] = true;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return sample;
|
|
971
|
+
}
|
|
972
|
+
function validateInlineRules(jsonSchema, sampleEmptyObject) {
|
|
973
|
+
const properties = (jsonSchema?.properties || jsonSchema?.items?.properties) ?? {};
|
|
974
|
+
Object.entries(properties).filter(([, property]) => property["x-jsf-logic-computedAttrs"] !== void 0).forEach(([fieldName, property]) => {
|
|
975
|
+
Object.entries(property["x-jsf-logic-computedAttrs"]).filter(([, value]) => typeof value === "object").forEach(([key, item]) => {
|
|
976
|
+
Object.values(item).forEach((rule) => {
|
|
977
|
+
checkRuleIntegrity(
|
|
978
|
+
rule,
|
|
979
|
+
fieldName,
|
|
980
|
+
sampleEmptyObject,
|
|
981
|
+
(item2) => `"${item2.var}" in inline rule in property "${fieldName}.x-jsf-logic-computedAttrs.${key}" does not exist as a JSON schema property.`
|
|
982
|
+
);
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
function checkRuleIntegrity(rule, id, data, errorMessage = (item) => `"${item.var}" in rule "${id}" does not exist as a JSON schema property.`) {
|
|
988
|
+
Object.values(rule ?? {}).map((subRule) => {
|
|
989
|
+
if (!Array.isArray(subRule) && subRule !== null && subRule !== void 0)
|
|
990
|
+
return;
|
|
991
|
+
subRule.map((item) => {
|
|
992
|
+
const isVar = item !== null && typeof item === "object" && Object.hasOwn(item, "var");
|
|
993
|
+
if (isVar) {
|
|
994
|
+
const exists = jsonLogic.apply({ var: removeIndicesFromPath(item.var) }, data);
|
|
995
|
+
if (exists === null) {
|
|
996
|
+
throw Error(errorMessage(item));
|
|
997
|
+
}
|
|
998
|
+
} else {
|
|
999
|
+
checkRuleIntegrity(item, id, data);
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
function removeIndicesFromPath(path) {
|
|
1005
|
+
const intermediatePath = path.replace(/\.\d+\./g, ".");
|
|
1006
|
+
return intermediatePath.replace(/\.\d+$/, "");
|
|
670
1007
|
}
|
|
671
1008
|
|
|
672
1009
|
// src/helpers.js
|
|
@@ -676,8 +1013,8 @@ function hasType(type, typeName) {
|
|
|
676
1013
|
function getField(fieldName, fields) {
|
|
677
1014
|
return fields.find(({ name }) => name === fieldName);
|
|
678
1015
|
}
|
|
679
|
-
function validateFieldSchema(field, value) {
|
|
680
|
-
const validator = buildYupSchema(field);
|
|
1016
|
+
function validateFieldSchema(field, value, validations) {
|
|
1017
|
+
const validator = buildYupSchema(field, {}, validations);
|
|
681
1018
|
return validator().isValidSync(value);
|
|
682
1019
|
}
|
|
683
1020
|
function compareFormValueWithSchemaValue(formValue, schemaValue) {
|
|
@@ -742,7 +1079,7 @@ function getPrefillValues(fields, initialValues = {}) {
|
|
|
742
1079
|
});
|
|
743
1080
|
return initialValues;
|
|
744
1081
|
}
|
|
745
|
-
function updateField(field, requiredFields, node, formValues) {
|
|
1082
|
+
function updateField(field, requiredFields, node, formValues, validations, config) {
|
|
746
1083
|
if (!field) {
|
|
747
1084
|
return;
|
|
748
1085
|
}
|
|
@@ -764,8 +1101,25 @@ function updateField(field, requiredFields, node, formValues) {
|
|
|
764
1101
|
}
|
|
765
1102
|
}
|
|
766
1103
|
});
|
|
1104
|
+
if (field.getComputedAttributes) {
|
|
1105
|
+
const computedFieldValues = field.getComputedAttributes({
|
|
1106
|
+
field,
|
|
1107
|
+
isRequired: fieldIsRequired,
|
|
1108
|
+
node,
|
|
1109
|
+
formValues,
|
|
1110
|
+
config,
|
|
1111
|
+
validations
|
|
1112
|
+
});
|
|
1113
|
+
updateValues(computedFieldValues);
|
|
1114
|
+
}
|
|
767
1115
|
if (field.calculateConditionalProperties) {
|
|
768
|
-
const newFieldValues = field.calculateConditionalProperties(
|
|
1116
|
+
const newFieldValues = field.calculateConditionalProperties(
|
|
1117
|
+
fieldIsRequired,
|
|
1118
|
+
node,
|
|
1119
|
+
validations,
|
|
1120
|
+
config,
|
|
1121
|
+
formValues
|
|
1122
|
+
);
|
|
769
1123
|
updateValues(newFieldValues);
|
|
770
1124
|
}
|
|
771
1125
|
if (field.calculateCustomValidationProperties) {
|
|
@@ -777,33 +1131,46 @@ function updateField(field, requiredFields, node, formValues) {
|
|
|
777
1131
|
updateValues(newFieldValues);
|
|
778
1132
|
}
|
|
779
1133
|
}
|
|
780
|
-
function processNode(
|
|
1134
|
+
function processNode({
|
|
1135
|
+
node,
|
|
1136
|
+
formValues,
|
|
1137
|
+
formFields,
|
|
1138
|
+
accRequired = /* @__PURE__ */ new Set(),
|
|
1139
|
+
parentID = "root",
|
|
1140
|
+
validations
|
|
1141
|
+
}) {
|
|
781
1142
|
const requiredFields = new Set(accRequired);
|
|
782
1143
|
Object.keys(node.properties ?? []).forEach((fieldName) => {
|
|
783
1144
|
const field = getField(fieldName, formFields);
|
|
784
|
-
updateField(field, requiredFields, node, formValues);
|
|
1145
|
+
updateField(field, requiredFields, node, formValues, validations, { parentID });
|
|
785
1146
|
});
|
|
786
1147
|
node.required?.forEach((fieldName) => {
|
|
787
1148
|
requiredFields.add(fieldName);
|
|
788
|
-
updateField(getField(fieldName, formFields), requiredFields, node, formValues
|
|
1149
|
+
updateField(getField(fieldName, formFields), requiredFields, node, formValues, validations, {
|
|
1150
|
+
parentID
|
|
1151
|
+
});
|
|
789
1152
|
});
|
|
790
1153
|
if (node.if) {
|
|
791
|
-
const matchesCondition = checkIfConditionMatches(node, formValues, formFields);
|
|
1154
|
+
const matchesCondition = checkIfConditionMatches(node, formValues, formFields, validations);
|
|
792
1155
|
if (matchesCondition && node.then) {
|
|
793
|
-
const { required: branchRequired } = processNode(
|
|
794
|
-
node.then,
|
|
1156
|
+
const { required: branchRequired } = processNode({
|
|
1157
|
+
node: node.then,
|
|
795
1158
|
formValues,
|
|
796
1159
|
formFields,
|
|
797
|
-
requiredFields
|
|
798
|
-
|
|
1160
|
+
accRequired: requiredFields,
|
|
1161
|
+
parentID,
|
|
1162
|
+
validations
|
|
1163
|
+
});
|
|
799
1164
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
800
1165
|
} else if (node.else) {
|
|
801
|
-
const { required: branchRequired } = processNode(
|
|
802
|
-
node.else,
|
|
1166
|
+
const { required: branchRequired } = processNode({
|
|
1167
|
+
node: node.else,
|
|
803
1168
|
formValues,
|
|
804
1169
|
formFields,
|
|
805
|
-
requiredFields
|
|
806
|
-
|
|
1170
|
+
accRequired: requiredFields,
|
|
1171
|
+
parentID,
|
|
1172
|
+
validations
|
|
1173
|
+
});
|
|
807
1174
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
808
1175
|
}
|
|
809
1176
|
}
|
|
@@ -815,12 +1182,21 @@ function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */
|
|
|
815
1182
|
node.anyOf.forEach(({ required = [] }) => {
|
|
816
1183
|
required.forEach((fieldName) => {
|
|
817
1184
|
const field = getField(fieldName, formFields);
|
|
818
|
-
updateField(field, requiredFields, node, formValues);
|
|
1185
|
+
updateField(field, requiredFields, node, formValues, validations, { parentID });
|
|
819
1186
|
});
|
|
820
1187
|
});
|
|
821
1188
|
}
|
|
822
1189
|
if (node.allOf) {
|
|
823
|
-
node.allOf.map(
|
|
1190
|
+
node.allOf.map(
|
|
1191
|
+
(allOfNode) => processNode({
|
|
1192
|
+
node: allOfNode,
|
|
1193
|
+
formValues,
|
|
1194
|
+
formFields,
|
|
1195
|
+
accRequired: requiredFields,
|
|
1196
|
+
parentID,
|
|
1197
|
+
validations
|
|
1198
|
+
})
|
|
1199
|
+
).forEach(({ required: allOfItemRequired }) => {
|
|
824
1200
|
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
825
1201
|
});
|
|
826
1202
|
}
|
|
@@ -828,10 +1204,27 @@ function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */
|
|
|
828
1204
|
Object.entries(node.properties).forEach(([name, nestedNode]) => {
|
|
829
1205
|
const inputType = getInputType(nestedNode);
|
|
830
1206
|
if (inputType === supportedTypes.FIELDSET) {
|
|
831
|
-
processNode(
|
|
1207
|
+
processNode({
|
|
1208
|
+
node: nestedNode,
|
|
1209
|
+
formValues: formValues[name] || {},
|
|
1210
|
+
formFields: getField(name, formFields).fields,
|
|
1211
|
+
validations,
|
|
1212
|
+
parentID: name
|
|
1213
|
+
});
|
|
832
1214
|
}
|
|
833
1215
|
});
|
|
834
1216
|
}
|
|
1217
|
+
if (node["x-jsf-logic"]) {
|
|
1218
|
+
const { required: requiredFromLogic } = processJSONLogicNode({
|
|
1219
|
+
node: node["x-jsf-logic"],
|
|
1220
|
+
formValues,
|
|
1221
|
+
formFields,
|
|
1222
|
+
accRequired: requiredFields,
|
|
1223
|
+
parentID,
|
|
1224
|
+
validations
|
|
1225
|
+
});
|
|
1226
|
+
requiredFromLogic.forEach((field) => requiredFields.add(field));
|
|
1227
|
+
}
|
|
835
1228
|
return {
|
|
836
1229
|
required: requiredFields
|
|
837
1230
|
};
|
|
@@ -846,11 +1239,11 @@ function clearValuesIfNotVisible(fields, formValues) {
|
|
|
846
1239
|
}
|
|
847
1240
|
});
|
|
848
1241
|
}
|
|
849
|
-
function updateFieldsProperties(fields, formValues, jsonSchema) {
|
|
1242
|
+
function updateFieldsProperties(fields, formValues, jsonSchema, validations) {
|
|
850
1243
|
if (!jsonSchema?.properties) {
|
|
851
1244
|
return;
|
|
852
1245
|
}
|
|
853
|
-
processNode(jsonSchema, formValues, fields);
|
|
1246
|
+
processNode({ node: jsonSchema, formValues, formFields: fields, validations });
|
|
854
1247
|
clearValuesIfNotVisible(fields, formValues);
|
|
855
1248
|
}
|
|
856
1249
|
var notNullOption = (opt) => opt.const !== null;
|
|
@@ -893,11 +1286,20 @@ function extractParametersFromNode(schemaNode) {
|
|
|
893
1286
|
}
|
|
894
1287
|
const presentation = pickXKey(schemaNode, "presentation") ?? {};
|
|
895
1288
|
const errorMessage = pickXKey(schemaNode, "errorMessage") ?? {};
|
|
1289
|
+
const requiredValidations = schemaNode["x-jsf-logic-validations"];
|
|
1290
|
+
const computedAttributes = schemaNode["x-jsf-logic-computedAttrs"];
|
|
1291
|
+
const decoratedComputedAttributes = {
|
|
1292
|
+
...computedAttributes ?? {},
|
|
1293
|
+
...computedAttributes?.const && computedAttributes?.default ? { value: computedAttributes.const } : {}
|
|
1294
|
+
};
|
|
896
1295
|
const node = omit(schemaNode, ["x-jsf-presentation", "presentation"]);
|
|
897
1296
|
const description = presentation?.description || node.description;
|
|
898
1297
|
const statementDescription = containsHTML(presentation.statement?.description) ? wrapWithSpan(presentation.statement.description, { class: "jsf-statement" }) : presentation.statement?.description;
|
|
899
1298
|
return omitBy(
|
|
900
1299
|
{
|
|
1300
|
+
const: node.const,
|
|
1301
|
+
// This is a "forced value" when both const and default are present.
|
|
1302
|
+
...node.const && node.default ? { value: node.const } : {},
|
|
901
1303
|
label: node.title,
|
|
902
1304
|
readOnly: node.readOnly,
|
|
903
1305
|
...node.deprecated && {
|
|
@@ -932,6 +1334,8 @@ function extractParametersFromNode(schemaNode) {
|
|
|
932
1334
|
},
|
|
933
1335
|
// Handle [name].presentation
|
|
934
1336
|
...presentation,
|
|
1337
|
+
requiredValidations,
|
|
1338
|
+
computedAttributes: decoratedComputedAttributes,
|
|
935
1339
|
description: containsHTML(description) ? wrapWithSpan(description, {
|
|
936
1340
|
class: "jsf-description"
|
|
937
1341
|
}) : description,
|
|
@@ -968,9 +1372,9 @@ function yupToFormErrors(yupError) {
|
|
|
968
1372
|
}
|
|
969
1373
|
return errors;
|
|
970
1374
|
}
|
|
971
|
-
var handleValuesChange = (fields, jsonSchema, config) => (values) => {
|
|
972
|
-
updateFieldsProperties(fields, values, jsonSchema);
|
|
973
|
-
const lazySchema = lazy(() => buildCompleteYupSchema(fields, config));
|
|
1375
|
+
var handleValuesChange = (fields, jsonSchema, config, validations) => (values) => {
|
|
1376
|
+
updateFieldsProperties(fields, values, jsonSchema, validations);
|
|
1377
|
+
const lazySchema = lazy(() => buildCompleteYupSchema(fields, config, validations));
|
|
974
1378
|
let errors;
|
|
975
1379
|
try {
|
|
976
1380
|
lazySchema.validateSync(values, {
|
|
@@ -1024,8 +1428,8 @@ function rebuildFieldset(fields, property) {
|
|
|
1024
1428
|
required: isFieldRequired(property, field)
|
|
1025
1429
|
}));
|
|
1026
1430
|
}
|
|
1027
|
-
function calculateConditionalProperties(fieldParams, customProperties) {
|
|
1028
|
-
return (isRequired, conditionBranch) => {
|
|
1431
|
+
function calculateConditionalProperties(fieldParams, customProperties, validations, config) {
|
|
1432
|
+
return (isRequired, conditionBranch, __, _, formValues) => {
|
|
1029
1433
|
const conditionalProperty = conditionBranch?.properties?.[fieldParams.name];
|
|
1030
1434
|
if (conditionalProperty) {
|
|
1031
1435
|
const presentation = pickXKey(conditionalProperty, "presentation") ?? {};
|
|
@@ -1039,17 +1443,31 @@ function calculateConditionalProperties(fieldParams, customProperties) {
|
|
|
1039
1443
|
fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
|
|
1040
1444
|
newFieldParams.fields = fieldSetFields;
|
|
1041
1445
|
}
|
|
1446
|
+
const { computedAttributes, ...restNewFieldParams } = newFieldParams;
|
|
1447
|
+
const calculatedComputedAttributes = computedAttributes ? calculateComputedAttributes(newFieldParams, config)({ validations, formValues }) : {};
|
|
1448
|
+
const requiredValidations = [
|
|
1449
|
+
...fieldParams.requiredValidations ?? [],
|
|
1450
|
+
...restNewFieldParams.requiredValidations ?? []
|
|
1451
|
+
];
|
|
1042
1452
|
const base = {
|
|
1043
1453
|
isVisible: true,
|
|
1044
1454
|
required: isRequired,
|
|
1045
1455
|
...presentation?.inputType && { type: presentation.inputType },
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1456
|
+
...calculatedComputedAttributes,
|
|
1457
|
+
...calculatedComputedAttributes.value ? { value: calculatedComputedAttributes.value } : { value: void 0 },
|
|
1458
|
+
schema: buildYupSchema(
|
|
1459
|
+
{
|
|
1460
|
+
...fieldParams,
|
|
1461
|
+
...restNewFieldParams,
|
|
1462
|
+
...calculatedComputedAttributes,
|
|
1463
|
+
requiredValidations,
|
|
1464
|
+
// If there are inner fields (case of fieldset) they need to be updated based on the condition
|
|
1465
|
+
fields: fieldSetFields,
|
|
1466
|
+
required: isRequired
|
|
1467
|
+
},
|
|
1468
|
+
config,
|
|
1469
|
+
validations
|
|
1470
|
+
)
|
|
1053
1471
|
};
|
|
1054
1472
|
return omit2(merge2(base, presentation, newFieldParams), ["inputType"]);
|
|
1055
1473
|
}
|
|
@@ -1143,14 +1561,19 @@ function sortByOrderOrPosition(a, b, order) {
|
|
|
1143
1561
|
function removeInvalidAttributes(fields) {
|
|
1144
1562
|
return omit3(fields, ["items", "maxFileSize", "isDynamic"]);
|
|
1145
1563
|
}
|
|
1146
|
-
function buildFieldParameters(name, fieldProperties, required = [], config = {}) {
|
|
1564
|
+
function buildFieldParameters(name, fieldProperties, required = [], config = {}, validations) {
|
|
1147
1565
|
const { position } = pickXKey(fieldProperties, "presentation") ?? {};
|
|
1148
1566
|
let fields;
|
|
1149
1567
|
const inputType = getInputType(fieldProperties, config.strictInputType, name);
|
|
1150
1568
|
if (inputType === supportedTypes.FIELDSET) {
|
|
1151
|
-
fields = getFieldsFromJSONSchema(
|
|
1152
|
-
|
|
1153
|
-
|
|
1569
|
+
fields = getFieldsFromJSONSchema(
|
|
1570
|
+
fieldProperties,
|
|
1571
|
+
{
|
|
1572
|
+
customProperties: get3(config, `customProperties.${name}`, {}),
|
|
1573
|
+
parentID: name
|
|
1574
|
+
},
|
|
1575
|
+
validations
|
|
1576
|
+
);
|
|
1154
1577
|
}
|
|
1155
1578
|
const result = {
|
|
1156
1579
|
name,
|
|
@@ -1165,9 +1588,9 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {})
|
|
|
1165
1588
|
};
|
|
1166
1589
|
return omitBy2(result, isNil3);
|
|
1167
1590
|
}
|
|
1168
|
-
function convertJSONSchemaPropertiesToFieldParameters({ properties, required, "x-jsf-order": order }, config = {}) {
|
|
1591
|
+
function convertJSONSchemaPropertiesToFieldParameters({ properties, required, "x-jsf-order": order }, config = {}, validations) {
|
|
1169
1592
|
const sortFields = (a, b) => sortByOrderOrPosition(a, b, order);
|
|
1170
|
-
return Object.entries(properties).filter(([, value]) => typeof value === "object").map(([key, value]) => buildFieldParameters(key, value, required, config)).sort(sortFields).map(({ position, ...fieldParams }) => fieldParams);
|
|
1593
|
+
return Object.entries(properties).filter(([, value]) => typeof value === "object").map(([key, value]) => buildFieldParameters(key, value, required, config, validations)).sort(sortFields).map(({ position, ...fieldParams }) => fieldParams);
|
|
1171
1594
|
}
|
|
1172
1595
|
function applyFieldsDependencies(fieldsParameters, node) {
|
|
1173
1596
|
if (node?.then) {
|
|
@@ -1189,6 +1612,9 @@ function applyFieldsDependencies(fieldsParameters, node) {
|
|
|
1189
1612
|
applyFieldsDependencies(fieldsParameters, condition);
|
|
1190
1613
|
});
|
|
1191
1614
|
}
|
|
1615
|
+
if (node?.["x-jsf-logic"]) {
|
|
1616
|
+
applyFieldsDependencies(fieldsParameters, node["x-jsf-logic"]);
|
|
1617
|
+
}
|
|
1192
1618
|
}
|
|
1193
1619
|
function getCustomPropertiesForField(fieldParams, config) {
|
|
1194
1620
|
return config?.customProperties?.[fieldParams.name];
|
|
@@ -1200,15 +1626,16 @@ function getComposeFunctionForField(fieldParams, hasCustomizations) {
|
|
|
1200
1626
|
}
|
|
1201
1627
|
return composeFn;
|
|
1202
1628
|
}
|
|
1203
|
-
function buildField(fieldParams, config, scopedJsonSchema) {
|
|
1629
|
+
function buildField(fieldParams, config, scopedJsonSchema, validations) {
|
|
1204
1630
|
const customProperties = getCustomPropertiesForField(fieldParams, config);
|
|
1205
1631
|
const composeFn = getComposeFunctionForField(fieldParams, !!customProperties);
|
|
1206
|
-
const yupSchema = buildYupSchema(fieldParams, config);
|
|
1207
|
-
const calculateConditionalFieldsClosure = fieldParams.isDynamic && calculateConditionalProperties(fieldParams, customProperties);
|
|
1632
|
+
const yupSchema = buildYupSchema(fieldParams, config, validations);
|
|
1633
|
+
const calculateConditionalFieldsClosure = fieldParams.isDynamic && calculateConditionalProperties(fieldParams, customProperties, validations, config);
|
|
1208
1634
|
const calculateCustomValidationPropertiesClosure = calculateCustomValidationProperties(
|
|
1209
1635
|
fieldParams,
|
|
1210
1636
|
customProperties
|
|
1211
1637
|
);
|
|
1638
|
+
const getComputedAttributes = Object.keys(fieldParams.computedAttributes).length > 0 && calculateComputedAttributes(fieldParams, config);
|
|
1212
1639
|
const hasCustomValidations = !!customProperties && size(pick2(customProperties, SUPPORTED_CUSTOM_VALIDATION_FIELD_PARAMS)) > 0;
|
|
1213
1640
|
const finalFieldParams = {
|
|
1214
1641
|
// invalid attribute cleanup
|
|
@@ -1221,6 +1648,7 @@ function buildField(fieldParams, config, scopedJsonSchema) {
|
|
|
1221
1648
|
...hasCustomValidations && {
|
|
1222
1649
|
calculateCustomValidationProperties: calculateCustomValidationPropertiesClosure
|
|
1223
1650
|
},
|
|
1651
|
+
...getComputedAttributes && { getComputedAttributes },
|
|
1224
1652
|
// field customization properties
|
|
1225
1653
|
...customProperties && { fieldCustomization: customProperties },
|
|
1226
1654
|
// base schema
|
|
@@ -1229,11 +1657,15 @@ function buildField(fieldParams, config, scopedJsonSchema) {
|
|
|
1229
1657
|
};
|
|
1230
1658
|
return composeFn(finalFieldParams);
|
|
1231
1659
|
}
|
|
1232
|
-
function getFieldsFromJSONSchema(scopedJsonSchema, config) {
|
|
1660
|
+
function getFieldsFromJSONSchema(scopedJsonSchema, config, validations) {
|
|
1233
1661
|
if (!scopedJsonSchema) {
|
|
1234
1662
|
return [];
|
|
1235
1663
|
}
|
|
1236
|
-
const fieldParamsList = convertJSONSchemaPropertiesToFieldParameters(
|
|
1664
|
+
const fieldParamsList = convertJSONSchemaPropertiesToFieldParameters(
|
|
1665
|
+
scopedJsonSchema,
|
|
1666
|
+
config,
|
|
1667
|
+
validations
|
|
1668
|
+
);
|
|
1237
1669
|
applyFieldsDependencies(fieldParamsList, scopedJsonSchema);
|
|
1238
1670
|
const fields = [];
|
|
1239
1671
|
fieldParamsList.forEach((fieldParams) => {
|
|
@@ -1253,11 +1685,11 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config) {
|
|
|
1253
1685
|
fields: () => groupArrayFields,
|
|
1254
1686
|
addFieldText: fieldParams.addFieldText
|
|
1255
1687
|
};
|
|
1256
|
-
buildField(fieldParams, config, scopedJsonSchema).forEach((groupField) => {
|
|
1688
|
+
buildField(fieldParams, config, scopedJsonSchema, validations).forEach((groupField) => {
|
|
1257
1689
|
fields.push(groupField);
|
|
1258
1690
|
});
|
|
1259
1691
|
} else {
|
|
1260
|
-
fields.push(buildField(fieldParams, config, scopedJsonSchema));
|
|
1692
|
+
fields.push(buildField(fieldParams, config, scopedJsonSchema, validations));
|
|
1261
1693
|
}
|
|
1262
1694
|
});
|
|
1263
1695
|
return fields;
|
|
@@ -1268,9 +1700,15 @@ function createHeadlessForm(jsonSchema, customConfig = {}) {
|
|
|
1268
1700
|
...customConfig
|
|
1269
1701
|
};
|
|
1270
1702
|
try {
|
|
1271
|
-
const
|
|
1272
|
-
const
|
|
1273
|
-
|
|
1703
|
+
const validations = createValidationChecker(jsonSchema);
|
|
1704
|
+
const fields = getFieldsFromJSONSchema(jsonSchema, config, validations);
|
|
1705
|
+
const handleValidation = handleValuesChange(fields, jsonSchema, config, validations);
|
|
1706
|
+
updateFieldsProperties(
|
|
1707
|
+
fields,
|
|
1708
|
+
getPrefillValues(fields, config.initialValues),
|
|
1709
|
+
jsonSchema,
|
|
1710
|
+
validations
|
|
1711
|
+
);
|
|
1274
1712
|
return {
|
|
1275
1713
|
fields,
|
|
1276
1714
|
handleValidation,
|