@remoteoss/json-schema-form 0.3.0-beta.0 → 0.4.1-beta.0
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/CHANGELOG.md +19 -4
- package/dist/index.cjs +74 -22
- package/dist/index.js +74 -22
- package/dist/standalone.js +429 -805
- package/package.json +1 -1
- package/src/tests/createHeadlessForm.test.js +537 -266
- package/src/tests/helpers.custom.js +1 -1
- package/src/tests/helpers.js +233 -65
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,37 @@
|
|
|
1
|
+
#### 0.4.1-beta.0 (2023-07-03)
|
|
2
|
+
|
|
3
|
+
##### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* **fieldset:** support root conditionals for fieldsets ([#23](https://github.com/remoteoss/json-schema-form/pull/23)) ([65d87b3a](https://github.com/remoteoss/json-schema-form/commit/65d87b3a93018f0729aed565000eb2a2ce1f2ce7))
|
|
6
|
+
* **select/radio:** Accept just the values in options (plus `''` and `null` for backward-compatibility) ([#18](https://github.com/remoteoss/json-schema-form/pull/18)) ([37501d2d](https://github.com/remoteoss/json-schema-form/commit/37501d2ddafdd5e207b34d2ca3f6b7b7a1006e9d))
|
|
7
|
+
|
|
8
|
+
#### 0.4.0-beta.0 (2023-06-22)
|
|
9
|
+
|
|
10
|
+
##### New Features
|
|
11
|
+
|
|
12
|
+
BREAKING CHANGES:
|
|
13
|
+
|
|
14
|
+
- **Radio/Select:** In each option, spread `x-jsf-presentation` value to option root ([#17](https://github.com/remoteoss/json-schema-form/pull/17)) ([367688c2](https://github.com/remoteoss/json-schema-form/commit/367688c24e212c1a0a1d2e7b19cbd7efa7021a15))
|
|
15
|
+
|
|
1
16
|
#### 0.3.0-beta.0 (2023-06-21)
|
|
2
17
|
|
|
3
18
|
##### Fixes
|
|
4
19
|
|
|
5
|
-
- Fix validation
|
|
20
|
+
- **Text:** Fix validation to only accept strings ([#12](https://github.com/remoteoss/json-schema-form/pull/12)) ([00017c0](https://github.com/remoteoss/json-schema-form/commit/00017c056d8a3583d56d9fefc4d3c7e0f4c1dd99))
|
|
6
21
|
|
|
7
22
|
##### Chores
|
|
8
23
|
|
|
9
|
-
- Update
|
|
24
|
+
- Update Yup to v.0.30.0 ([#12](https://github.com/remoteoss/json-schema-form/pull/12)) ([00017c0](https://github.com/remoteoss/json-schema-form/commit/00017c056d8a3583d56d9fefc4d3c7e0f4c1dd99))
|
|
10
25
|
|
|
11
26
|
#### 0.2.0-beta.0 (2023-06-20)
|
|
12
27
|
|
|
13
28
|
##### New Features
|
|
14
29
|
|
|
15
|
-
- Add
|
|
30
|
+
- Add Typescript declarations to the library ([2404188c](https://github.com/remoteoss/json-schema-form/commit/2404188cba52a5a665f257430a65a0ebb938dd44))
|
|
16
31
|
|
|
17
32
|
##### Fixes
|
|
18
33
|
|
|
19
|
-
- Support maximum 0 ([#10](https://github.com/remoteoss/json-schema-form/pull/10)) ([1e9d6cf9](https://github.com/remoteoss/json-schema-form/commit/1e9d6cf96436cf16018e045b351567c643e10dac))
|
|
34
|
+
- **Number:** Support maximum 0 ([#10](https://github.com/remoteoss/json-schema-form/pull/10)) ([1e9d6cf9](https://github.com/remoteoss/json-schema-form/commit/1e9d6cf96436cf16018e045b351567c643e10dac))
|
|
20
35
|
|
|
21
36
|
##### Chores
|
|
22
37
|
|
package/dist/index.cjs
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
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.4.1-beta.0
|
|
5
|
+
Generated: Mon, 03 Jul 2023 22:21:10 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -383,8 +383,17 @@ var validateOnlyStrings = (0, import_yup.string)().trim().nullable().test(
|
|
|
383
383
|
);
|
|
384
384
|
var yupSchemas = {
|
|
385
385
|
text: validateOnlyStrings,
|
|
386
|
-
|
|
387
|
-
|
|
386
|
+
radioOrSelect: (options) => (0, import_yup.string)().nullable().transform((value) => {
|
|
387
|
+
if (value === "") {
|
|
388
|
+
return void 0;
|
|
389
|
+
}
|
|
390
|
+
if (options?.includes(null)) {
|
|
391
|
+
return value;
|
|
392
|
+
}
|
|
393
|
+
return value === null ? void 0 : value;
|
|
394
|
+
}).oneOf(options, ({ value }) => {
|
|
395
|
+
return `The option ${JSON.stringify(value)} is not valid.`;
|
|
396
|
+
}),
|
|
388
397
|
date: (0, import_yup.string)().nullable().trim().matches(
|
|
389
398
|
/(?:\d){4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9]|3[0-1])/,
|
|
390
399
|
`Must be a valid date in ${DEFAULT_DATE_FORMAT.toLocaleLowerCase()} format. e.g. ${todayDateHint}`
|
|
@@ -419,18 +428,33 @@ function getRequiredErrorMessage(inputType, { inlineError, configError }) {
|
|
|
419
428
|
return "Required field";
|
|
420
429
|
}
|
|
421
430
|
var getJsonTypeInArray = (jsonType) => Array.isArray(jsonType) ? jsonType.find((val) => val !== "null") : jsonType;
|
|
431
|
+
var getOptions = (field) => {
|
|
432
|
+
const allValues = field.options?.map((option) => option.value);
|
|
433
|
+
const isOptionalWithNull = Array.isArray(field.jsonType) && // @TODO should also check the "oneOf" directly looking for "null"
|
|
434
|
+
// option but we don't have direct access at this point.
|
|
435
|
+
// Otherwise the JSON Schema validator will fail as explained in PR#18
|
|
436
|
+
field.jsonType.includes("null");
|
|
437
|
+
return isOptionalWithNull ? [...allValues, null] : allValues;
|
|
438
|
+
};
|
|
439
|
+
var getYupSchema = ({ inputType, ...field }) => {
|
|
440
|
+
const jsonType = getJsonTypeInArray(field.jsonType);
|
|
441
|
+
if (field.options?.length > 0) {
|
|
442
|
+
const optionValues = getOptions(field);
|
|
443
|
+
return yupSchemas.radioOrSelect(optionValues);
|
|
444
|
+
}
|
|
445
|
+
return yupSchemas[inputType] || yupSchemasToJsonTypes[jsonType];
|
|
446
|
+
};
|
|
422
447
|
function buildYupSchema(field, config) {
|
|
423
448
|
const { inputType, jsonType: jsonTypeValue, errorMessage = {}, ...propertyFields } = field;
|
|
424
449
|
const isCheckboxBoolean = typeof propertyFields.checkboxValue === "boolean";
|
|
425
450
|
let baseSchema;
|
|
426
|
-
const jsonType = getJsonTypeInArray(jsonTypeValue);
|
|
427
451
|
const errorMessageFromConfig = config?.inputTypes?.[inputType]?.errorMessage || {};
|
|
428
452
|
if (propertyFields.multiple) {
|
|
429
453
|
baseSchema = yupSchemas.multiple[inputType] || yupSchemasToJsonTypes.array;
|
|
430
454
|
} else if (isCheckboxBoolean) {
|
|
431
455
|
baseSchema = yupSchemas.checkboxBool;
|
|
432
456
|
} else {
|
|
433
|
-
baseSchema =
|
|
457
|
+
baseSchema = getYupSchema(field);
|
|
434
458
|
}
|
|
435
459
|
if (!baseSchema) {
|
|
436
460
|
return import_noop.default;
|
|
@@ -630,8 +654,17 @@ function checkIfConditionMatches(node, formValues, formFields) {
|
|
|
630
654
|
if (currentProperty.enum) {
|
|
631
655
|
return currentProperty.enum.includes(value);
|
|
632
656
|
}
|
|
633
|
-
const
|
|
634
|
-
return validateFieldSchema(
|
|
657
|
+
const field = getField(name, formFields);
|
|
658
|
+
return validateFieldSchema(
|
|
659
|
+
{
|
|
660
|
+
options: field.options,
|
|
661
|
+
// @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
|
|
662
|
+
...currentProperty,
|
|
663
|
+
inputType: field.inputType,
|
|
664
|
+
required: true
|
|
665
|
+
},
|
|
666
|
+
value
|
|
667
|
+
);
|
|
635
668
|
});
|
|
636
669
|
}
|
|
637
670
|
function isFieldFilled(fieldValue) {
|
|
@@ -804,12 +837,26 @@ function updateFieldsProperties(fields, formValues, jsonSchema) {
|
|
|
804
837
|
clearValuesIfNotVisible(fields, formValues);
|
|
805
838
|
}
|
|
806
839
|
var notNullOption = (opt) => opt.const !== null;
|
|
840
|
+
function flatPresentation(item) {
|
|
841
|
+
return Object.entries(item).reduce((newItem, [key, value]) => {
|
|
842
|
+
if (key === "x-jsf-presentation") {
|
|
843
|
+
return {
|
|
844
|
+
...newItem,
|
|
845
|
+
...value
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
return {
|
|
849
|
+
...newItem,
|
|
850
|
+
[key]: value
|
|
851
|
+
};
|
|
852
|
+
}, {});
|
|
853
|
+
}
|
|
807
854
|
function getFieldOptions(node, presentation) {
|
|
808
855
|
function convertToOptions(nodeOptions) {
|
|
809
856
|
return nodeOptions.filter(notNullOption).map(({ title, const: cons, ...item }) => ({
|
|
810
857
|
label: title,
|
|
811
858
|
value: cons,
|
|
812
|
-
...item
|
|
859
|
+
...flatPresentation(item)
|
|
813
860
|
}));
|
|
814
861
|
}
|
|
815
862
|
if (presentation.options) {
|
|
@@ -925,30 +972,38 @@ var handleValuesChange = (fields, jsonSchema, config) => (values) => {
|
|
|
925
972
|
};
|
|
926
973
|
|
|
927
974
|
// src/calculateConditionalProperties.js
|
|
928
|
-
function isFieldRequired(node,
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
975
|
+
function isFieldRequired(node, field) {
|
|
976
|
+
return (
|
|
977
|
+
// Check base root required
|
|
978
|
+
field.scopedJsonSchema?.required?.includes(field.name) || // Check conditional required
|
|
979
|
+
node?.required?.includes(field.name)
|
|
980
|
+
);
|
|
933
981
|
}
|
|
934
|
-
function
|
|
982
|
+
function rebuildFieldset(fields, property) {
|
|
935
983
|
if (property?.properties) {
|
|
936
984
|
return fields.map((field) => {
|
|
985
|
+
const propertyConditionals = property.properties[field.name];
|
|
986
|
+
if (!propertyConditionals) {
|
|
987
|
+
return field;
|
|
988
|
+
}
|
|
989
|
+
const newFieldParams = extractParametersFromNode(propertyConditionals);
|
|
937
990
|
if (field.fields) {
|
|
938
991
|
return {
|
|
939
992
|
...field,
|
|
940
|
-
|
|
993
|
+
...newFieldParams,
|
|
994
|
+
fields: rebuildFieldset(field.fields, propertyConditionals)
|
|
941
995
|
};
|
|
942
996
|
}
|
|
943
997
|
return {
|
|
944
998
|
...field,
|
|
945
|
-
|
|
999
|
+
...newFieldParams,
|
|
1000
|
+
required: isFieldRequired(property, field)
|
|
946
1001
|
};
|
|
947
1002
|
});
|
|
948
1003
|
}
|
|
949
1004
|
return fields.map((field) => ({
|
|
950
1005
|
...field,
|
|
951
|
-
required: isFieldRequired(property, field
|
|
1006
|
+
required: isFieldRequired(property, field)
|
|
952
1007
|
}));
|
|
953
1008
|
}
|
|
954
1009
|
function calculateConditionalProperties(fieldParams, customProperties) {
|
|
@@ -963,10 +1018,7 @@ function calculateConditionalProperties(fieldParams, customProperties) {
|
|
|
963
1018
|
});
|
|
964
1019
|
let fieldSetFields;
|
|
965
1020
|
if (fieldParams.inputType === supportedTypes.FIELDSET) {
|
|
966
|
-
fieldSetFields =
|
|
967
|
-
fieldParams.fields,
|
|
968
|
-
conditionalProperty
|
|
969
|
-
);
|
|
1021
|
+
fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
|
|
970
1022
|
newFieldParams.fields = fieldSetFields;
|
|
971
1023
|
}
|
|
972
1024
|
const base = {
|
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
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.4.1-beta.0
|
|
5
|
+
Generated: Mon, 03 Jul 2023 22:21:10 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -347,8 +347,17 @@ var validateOnlyStrings = string().trim().nullable().test(
|
|
|
347
347
|
);
|
|
348
348
|
var yupSchemas = {
|
|
349
349
|
text: validateOnlyStrings,
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
radioOrSelect: (options) => string().nullable().transform((value) => {
|
|
351
|
+
if (value === "") {
|
|
352
|
+
return void 0;
|
|
353
|
+
}
|
|
354
|
+
if (options?.includes(null)) {
|
|
355
|
+
return value;
|
|
356
|
+
}
|
|
357
|
+
return value === null ? void 0 : value;
|
|
358
|
+
}).oneOf(options, ({ value }) => {
|
|
359
|
+
return `The option ${JSON.stringify(value)} is not valid.`;
|
|
360
|
+
}),
|
|
352
361
|
date: string().nullable().trim().matches(
|
|
353
362
|
/(?:\d){4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9]|3[0-1])/,
|
|
354
363
|
`Must be a valid date in ${DEFAULT_DATE_FORMAT.toLocaleLowerCase()} format. e.g. ${todayDateHint}`
|
|
@@ -383,18 +392,33 @@ function getRequiredErrorMessage(inputType, { inlineError, configError }) {
|
|
|
383
392
|
return "Required field";
|
|
384
393
|
}
|
|
385
394
|
var getJsonTypeInArray = (jsonType) => Array.isArray(jsonType) ? jsonType.find((val) => val !== "null") : jsonType;
|
|
395
|
+
var getOptions = (field) => {
|
|
396
|
+
const allValues = field.options?.map((option) => option.value);
|
|
397
|
+
const isOptionalWithNull = Array.isArray(field.jsonType) && // @TODO should also check the "oneOf" directly looking for "null"
|
|
398
|
+
// option but we don't have direct access at this point.
|
|
399
|
+
// Otherwise the JSON Schema validator will fail as explained in PR#18
|
|
400
|
+
field.jsonType.includes("null");
|
|
401
|
+
return isOptionalWithNull ? [...allValues, null] : allValues;
|
|
402
|
+
};
|
|
403
|
+
var getYupSchema = ({ inputType, ...field }) => {
|
|
404
|
+
const jsonType = getJsonTypeInArray(field.jsonType);
|
|
405
|
+
if (field.options?.length > 0) {
|
|
406
|
+
const optionValues = getOptions(field);
|
|
407
|
+
return yupSchemas.radioOrSelect(optionValues);
|
|
408
|
+
}
|
|
409
|
+
return yupSchemas[inputType] || yupSchemasToJsonTypes[jsonType];
|
|
410
|
+
};
|
|
386
411
|
function buildYupSchema(field, config) {
|
|
387
412
|
const { inputType, jsonType: jsonTypeValue, errorMessage = {}, ...propertyFields } = field;
|
|
388
413
|
const isCheckboxBoolean = typeof propertyFields.checkboxValue === "boolean";
|
|
389
414
|
let baseSchema;
|
|
390
|
-
const jsonType = getJsonTypeInArray(jsonTypeValue);
|
|
391
415
|
const errorMessageFromConfig = config?.inputTypes?.[inputType]?.errorMessage || {};
|
|
392
416
|
if (propertyFields.multiple) {
|
|
393
417
|
baseSchema = yupSchemas.multiple[inputType] || yupSchemasToJsonTypes.array;
|
|
394
418
|
} else if (isCheckboxBoolean) {
|
|
395
419
|
baseSchema = yupSchemas.checkboxBool;
|
|
396
420
|
} else {
|
|
397
|
-
baseSchema =
|
|
421
|
+
baseSchema = getYupSchema(field);
|
|
398
422
|
}
|
|
399
423
|
if (!baseSchema) {
|
|
400
424
|
return noop;
|
|
@@ -594,8 +618,17 @@ function checkIfConditionMatches(node, formValues, formFields) {
|
|
|
594
618
|
if (currentProperty.enum) {
|
|
595
619
|
return currentProperty.enum.includes(value);
|
|
596
620
|
}
|
|
597
|
-
const
|
|
598
|
-
return validateFieldSchema(
|
|
621
|
+
const field = getField(name, formFields);
|
|
622
|
+
return validateFieldSchema(
|
|
623
|
+
{
|
|
624
|
+
options: field.options,
|
|
625
|
+
// @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
|
|
626
|
+
...currentProperty,
|
|
627
|
+
inputType: field.inputType,
|
|
628
|
+
required: true
|
|
629
|
+
},
|
|
630
|
+
value
|
|
631
|
+
);
|
|
599
632
|
});
|
|
600
633
|
}
|
|
601
634
|
function isFieldFilled(fieldValue) {
|
|
@@ -768,12 +801,26 @@ function updateFieldsProperties(fields, formValues, jsonSchema) {
|
|
|
768
801
|
clearValuesIfNotVisible(fields, formValues);
|
|
769
802
|
}
|
|
770
803
|
var notNullOption = (opt) => opt.const !== null;
|
|
804
|
+
function flatPresentation(item) {
|
|
805
|
+
return Object.entries(item).reduce((newItem, [key, value]) => {
|
|
806
|
+
if (key === "x-jsf-presentation") {
|
|
807
|
+
return {
|
|
808
|
+
...newItem,
|
|
809
|
+
...value
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
return {
|
|
813
|
+
...newItem,
|
|
814
|
+
[key]: value
|
|
815
|
+
};
|
|
816
|
+
}, {});
|
|
817
|
+
}
|
|
771
818
|
function getFieldOptions(node, presentation) {
|
|
772
819
|
function convertToOptions(nodeOptions) {
|
|
773
820
|
return nodeOptions.filter(notNullOption).map(({ title, const: cons, ...item }) => ({
|
|
774
821
|
label: title,
|
|
775
822
|
value: cons,
|
|
776
|
-
...item
|
|
823
|
+
...flatPresentation(item)
|
|
777
824
|
}));
|
|
778
825
|
}
|
|
779
826
|
if (presentation.options) {
|
|
@@ -889,30 +936,38 @@ var handleValuesChange = (fields, jsonSchema, config) => (values) => {
|
|
|
889
936
|
};
|
|
890
937
|
|
|
891
938
|
// src/calculateConditionalProperties.js
|
|
892
|
-
function isFieldRequired(node,
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
939
|
+
function isFieldRequired(node, field) {
|
|
940
|
+
return (
|
|
941
|
+
// Check base root required
|
|
942
|
+
field.scopedJsonSchema?.required?.includes(field.name) || // Check conditional required
|
|
943
|
+
node?.required?.includes(field.name)
|
|
944
|
+
);
|
|
897
945
|
}
|
|
898
|
-
function
|
|
946
|
+
function rebuildFieldset(fields, property) {
|
|
899
947
|
if (property?.properties) {
|
|
900
948
|
return fields.map((field) => {
|
|
949
|
+
const propertyConditionals = property.properties[field.name];
|
|
950
|
+
if (!propertyConditionals) {
|
|
951
|
+
return field;
|
|
952
|
+
}
|
|
953
|
+
const newFieldParams = extractParametersFromNode(propertyConditionals);
|
|
901
954
|
if (field.fields) {
|
|
902
955
|
return {
|
|
903
956
|
...field,
|
|
904
|
-
|
|
957
|
+
...newFieldParams,
|
|
958
|
+
fields: rebuildFieldset(field.fields, propertyConditionals)
|
|
905
959
|
};
|
|
906
960
|
}
|
|
907
961
|
return {
|
|
908
962
|
...field,
|
|
909
|
-
|
|
963
|
+
...newFieldParams,
|
|
964
|
+
required: isFieldRequired(property, field)
|
|
910
965
|
};
|
|
911
966
|
});
|
|
912
967
|
}
|
|
913
968
|
return fields.map((field) => ({
|
|
914
969
|
...field,
|
|
915
|
-
required: isFieldRequired(property, field
|
|
970
|
+
required: isFieldRequired(property, field)
|
|
916
971
|
}));
|
|
917
972
|
}
|
|
918
973
|
function calculateConditionalProperties(fieldParams, customProperties) {
|
|
@@ -927,10 +982,7 @@ function calculateConditionalProperties(fieldParams, customProperties) {
|
|
|
927
982
|
});
|
|
928
983
|
let fieldSetFields;
|
|
929
984
|
if (fieldParams.inputType === supportedTypes.FIELDSET) {
|
|
930
|
-
fieldSetFields =
|
|
931
|
-
fieldParams.fields,
|
|
932
|
-
conditionalProperty
|
|
933
|
-
);
|
|
985
|
+
fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
|
|
934
986
|
newFieldParams.fields = fieldSetFields;
|
|
935
987
|
}
|
|
936
988
|
const base = {
|