@remoteoss/json-schema-form 0.3.0-beta.0 → 0.4.1-dev.20230702181843
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 +12 -4
- package/dist/index.cjs +62 -20
- package/dist/index.js +62 -20
- package/dist/standalone.js +417 -803
- package/package.json +1 -1
- package/src/tests/createHeadlessForm.test.js +534 -266
- package/src/tests/helpers.js +233 -65
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
|
+
#### 0.4.0-beta.0 (2023-06-22)
|
|
2
|
+
|
|
3
|
+
##### New Features
|
|
4
|
+
|
|
5
|
+
BREAKING CHANGES:
|
|
6
|
+
|
|
7
|
+
- **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))
|
|
8
|
+
|
|
1
9
|
#### 0.3.0-beta.0 (2023-06-21)
|
|
2
10
|
|
|
3
11
|
##### Fixes
|
|
4
12
|
|
|
5
|
-
- Fix validation
|
|
13
|
+
- **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
14
|
|
|
7
15
|
##### Chores
|
|
8
16
|
|
|
9
|
-
- Update
|
|
17
|
+
- 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
18
|
|
|
11
19
|
#### 0.2.0-beta.0 (2023-06-20)
|
|
12
20
|
|
|
13
21
|
##### New Features
|
|
14
22
|
|
|
15
|
-
- Add
|
|
23
|
+
- Add Typescript declarations to the library ([2404188c](https://github.com/remoteoss/json-schema-form/commit/2404188cba52a5a665f257430a65a0ebb938dd44))
|
|
16
24
|
|
|
17
25
|
##### Fixes
|
|
18
26
|
|
|
19
|
-
- Support maximum 0 ([#10](https://github.com/remoteoss/json-schema-form/pull/10)) ([1e9d6cf9](https://github.com/remoteoss/json-schema-form/commit/1e9d6cf96436cf16018e045b351567c643e10dac))
|
|
27
|
+
- **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
28
|
|
|
21
29
|
##### Chores
|
|
22
30
|
|
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-dev.20230702181843
|
|
5
|
+
Generated: Sun, 02 Jul 2023 18:19:05 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -383,8 +383,9 @@ 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().oneOf(options, ({ value }) => {
|
|
387
|
+
return `The option ${JSON.stringify(value)} is not valid.`;
|
|
388
|
+
}),
|
|
388
389
|
date: (0, import_yup.string)().nullable().trim().matches(
|
|
389
390
|
/(?:\d){4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9]|3[0-1])/,
|
|
390
391
|
`Must be a valid date in ${DEFAULT_DATE_FORMAT.toLocaleLowerCase()} format. e.g. ${todayDateHint}`
|
|
@@ -419,18 +420,40 @@ function getRequiredErrorMessage(inputType, { inlineError, configError }) {
|
|
|
419
420
|
return "Required field";
|
|
420
421
|
}
|
|
421
422
|
var getJsonTypeInArray = (jsonType) => Array.isArray(jsonType) ? jsonType.find((val) => val !== "null") : jsonType;
|
|
423
|
+
var getOptionsAllowed = (field) => {
|
|
424
|
+
const onlyValues = field.options?.map((option) => option.value);
|
|
425
|
+
const optionsBroken = [...onlyValues, ""];
|
|
426
|
+
if (field.required) {
|
|
427
|
+
return optionsBroken;
|
|
428
|
+
}
|
|
429
|
+
const isOptionalWithNull = Array.isArray(field.jsonType) && // @TODO should also check the "oneOf" directly looking for "null" option
|
|
430
|
+
// but we don't have direct access at this point. Otherwise
|
|
431
|
+
// the JSON Schema validator will fail because setting jsonType is not enough.
|
|
432
|
+
field.jsonType.includes("null");
|
|
433
|
+
if (isOptionalWithNull) {
|
|
434
|
+
return [...optionsBroken, null];
|
|
435
|
+
}
|
|
436
|
+
return optionsBroken;
|
|
437
|
+
};
|
|
438
|
+
var getYupSchema = ({ inputType, ...field }) => {
|
|
439
|
+
const jsonType = getJsonTypeInArray(field.jsonType);
|
|
440
|
+
if (field.options?.length > 0) {
|
|
441
|
+
const optionsAllowed = getOptionsAllowed(field);
|
|
442
|
+
return yupSchemas.radioOrSelect(optionsAllowed);
|
|
443
|
+
}
|
|
444
|
+
return yupSchemas[inputType] || yupSchemasToJsonTypes[jsonType];
|
|
445
|
+
};
|
|
422
446
|
function buildYupSchema(field, config) {
|
|
423
447
|
const { inputType, jsonType: jsonTypeValue, errorMessage = {}, ...propertyFields } = field;
|
|
424
448
|
const isCheckboxBoolean = typeof propertyFields.checkboxValue === "boolean";
|
|
425
449
|
let baseSchema;
|
|
426
|
-
const jsonType = getJsonTypeInArray(jsonTypeValue);
|
|
427
450
|
const errorMessageFromConfig = config?.inputTypes?.[inputType]?.errorMessage || {};
|
|
428
451
|
if (propertyFields.multiple) {
|
|
429
452
|
baseSchema = yupSchemas.multiple[inputType] || yupSchemasToJsonTypes.array;
|
|
430
453
|
} else if (isCheckboxBoolean) {
|
|
431
454
|
baseSchema = yupSchemas.checkboxBool;
|
|
432
455
|
} else {
|
|
433
|
-
baseSchema =
|
|
456
|
+
baseSchema = getYupSchema(field);
|
|
434
457
|
}
|
|
435
458
|
if (!baseSchema) {
|
|
436
459
|
return import_noop.default;
|
|
@@ -804,12 +827,26 @@ function updateFieldsProperties(fields, formValues, jsonSchema) {
|
|
|
804
827
|
clearValuesIfNotVisible(fields, formValues);
|
|
805
828
|
}
|
|
806
829
|
var notNullOption = (opt) => opt.const !== null;
|
|
830
|
+
function flatPresentation(item) {
|
|
831
|
+
return Object.entries(item).reduce((newItem, [key, value]) => {
|
|
832
|
+
if (key === "x-jsf-presentation") {
|
|
833
|
+
return {
|
|
834
|
+
...newItem,
|
|
835
|
+
...value
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
return {
|
|
839
|
+
...newItem,
|
|
840
|
+
[key]: value
|
|
841
|
+
};
|
|
842
|
+
}, {});
|
|
843
|
+
}
|
|
807
844
|
function getFieldOptions(node, presentation) {
|
|
808
845
|
function convertToOptions(nodeOptions) {
|
|
809
846
|
return nodeOptions.filter(notNullOption).map(({ title, const: cons, ...item }) => ({
|
|
810
847
|
label: title,
|
|
811
848
|
value: cons,
|
|
812
|
-
...item
|
|
849
|
+
...flatPresentation(item)
|
|
813
850
|
}));
|
|
814
851
|
}
|
|
815
852
|
if (presentation.options) {
|
|
@@ -925,30 +962,38 @@ var handleValuesChange = (fields, jsonSchema, config) => (values) => {
|
|
|
925
962
|
};
|
|
926
963
|
|
|
927
964
|
// src/calculateConditionalProperties.js
|
|
928
|
-
function isFieldRequired(node,
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
965
|
+
function isFieldRequired(node, field) {
|
|
966
|
+
return (
|
|
967
|
+
// Check base root required
|
|
968
|
+
field.scopedJsonSchema?.required?.includes(field.name) || // Check conditional required
|
|
969
|
+
node?.required?.includes(field.name)
|
|
970
|
+
);
|
|
933
971
|
}
|
|
934
|
-
function
|
|
972
|
+
function rebuildFieldset(fields, property) {
|
|
935
973
|
if (property?.properties) {
|
|
936
974
|
return fields.map((field) => {
|
|
975
|
+
const propertyConditionals = property.properties[field.name];
|
|
976
|
+
if (!propertyConditionals) {
|
|
977
|
+
return field;
|
|
978
|
+
}
|
|
979
|
+
const newFieldParams = extractParametersFromNode(propertyConditionals);
|
|
937
980
|
if (field.fields) {
|
|
938
981
|
return {
|
|
939
982
|
...field,
|
|
940
|
-
|
|
983
|
+
...newFieldParams,
|
|
984
|
+
fields: rebuildFieldset(field.fields, propertyConditionals)
|
|
941
985
|
};
|
|
942
986
|
}
|
|
943
987
|
return {
|
|
944
988
|
...field,
|
|
945
|
-
|
|
989
|
+
...newFieldParams,
|
|
990
|
+
required: isFieldRequired(property, field)
|
|
946
991
|
};
|
|
947
992
|
});
|
|
948
993
|
}
|
|
949
994
|
return fields.map((field) => ({
|
|
950
995
|
...field,
|
|
951
|
-
required: isFieldRequired(property, field
|
|
996
|
+
required: isFieldRequired(property, field)
|
|
952
997
|
}));
|
|
953
998
|
}
|
|
954
999
|
function calculateConditionalProperties(fieldParams, customProperties) {
|
|
@@ -963,10 +1008,7 @@ function calculateConditionalProperties(fieldParams, customProperties) {
|
|
|
963
1008
|
});
|
|
964
1009
|
let fieldSetFields;
|
|
965
1010
|
if (fieldParams.inputType === supportedTypes.FIELDSET) {
|
|
966
|
-
fieldSetFields =
|
|
967
|
-
fieldParams.fields,
|
|
968
|
-
conditionalProperty
|
|
969
|
-
);
|
|
1011
|
+
fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
|
|
970
1012
|
newFieldParams.fields = fieldSetFields;
|
|
971
1013
|
}
|
|
972
1014
|
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-dev.20230702181843
|
|
5
|
+
Generated: Sun, 02 Jul 2023 18:19:05 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -347,8 +347,9 @@ var validateOnlyStrings = string().trim().nullable().test(
|
|
|
347
347
|
);
|
|
348
348
|
var yupSchemas = {
|
|
349
349
|
text: validateOnlyStrings,
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
radioOrSelect: (options) => string().nullable().oneOf(options, ({ value }) => {
|
|
351
|
+
return `The option ${JSON.stringify(value)} is not valid.`;
|
|
352
|
+
}),
|
|
352
353
|
date: string().nullable().trim().matches(
|
|
353
354
|
/(?:\d){4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9]|3[0-1])/,
|
|
354
355
|
`Must be a valid date in ${DEFAULT_DATE_FORMAT.toLocaleLowerCase()} format. e.g. ${todayDateHint}`
|
|
@@ -383,18 +384,40 @@ function getRequiredErrorMessage(inputType, { inlineError, configError }) {
|
|
|
383
384
|
return "Required field";
|
|
384
385
|
}
|
|
385
386
|
var getJsonTypeInArray = (jsonType) => Array.isArray(jsonType) ? jsonType.find((val) => val !== "null") : jsonType;
|
|
387
|
+
var getOptionsAllowed = (field) => {
|
|
388
|
+
const onlyValues = field.options?.map((option) => option.value);
|
|
389
|
+
const optionsBroken = [...onlyValues, ""];
|
|
390
|
+
if (field.required) {
|
|
391
|
+
return optionsBroken;
|
|
392
|
+
}
|
|
393
|
+
const isOptionalWithNull = Array.isArray(field.jsonType) && // @TODO should also check the "oneOf" directly looking for "null" option
|
|
394
|
+
// but we don't have direct access at this point. Otherwise
|
|
395
|
+
// the JSON Schema validator will fail because setting jsonType is not enough.
|
|
396
|
+
field.jsonType.includes("null");
|
|
397
|
+
if (isOptionalWithNull) {
|
|
398
|
+
return [...optionsBroken, null];
|
|
399
|
+
}
|
|
400
|
+
return optionsBroken;
|
|
401
|
+
};
|
|
402
|
+
var getYupSchema = ({ inputType, ...field }) => {
|
|
403
|
+
const jsonType = getJsonTypeInArray(field.jsonType);
|
|
404
|
+
if (field.options?.length > 0) {
|
|
405
|
+
const optionsAllowed = getOptionsAllowed(field);
|
|
406
|
+
return yupSchemas.radioOrSelect(optionsAllowed);
|
|
407
|
+
}
|
|
408
|
+
return yupSchemas[inputType] || yupSchemasToJsonTypes[jsonType];
|
|
409
|
+
};
|
|
386
410
|
function buildYupSchema(field, config) {
|
|
387
411
|
const { inputType, jsonType: jsonTypeValue, errorMessage = {}, ...propertyFields } = field;
|
|
388
412
|
const isCheckboxBoolean = typeof propertyFields.checkboxValue === "boolean";
|
|
389
413
|
let baseSchema;
|
|
390
|
-
const jsonType = getJsonTypeInArray(jsonTypeValue);
|
|
391
414
|
const errorMessageFromConfig = config?.inputTypes?.[inputType]?.errorMessage || {};
|
|
392
415
|
if (propertyFields.multiple) {
|
|
393
416
|
baseSchema = yupSchemas.multiple[inputType] || yupSchemasToJsonTypes.array;
|
|
394
417
|
} else if (isCheckboxBoolean) {
|
|
395
418
|
baseSchema = yupSchemas.checkboxBool;
|
|
396
419
|
} else {
|
|
397
|
-
baseSchema =
|
|
420
|
+
baseSchema = getYupSchema(field);
|
|
398
421
|
}
|
|
399
422
|
if (!baseSchema) {
|
|
400
423
|
return noop;
|
|
@@ -768,12 +791,26 @@ function updateFieldsProperties(fields, formValues, jsonSchema) {
|
|
|
768
791
|
clearValuesIfNotVisible(fields, formValues);
|
|
769
792
|
}
|
|
770
793
|
var notNullOption = (opt) => opt.const !== null;
|
|
794
|
+
function flatPresentation(item) {
|
|
795
|
+
return Object.entries(item).reduce((newItem, [key, value]) => {
|
|
796
|
+
if (key === "x-jsf-presentation") {
|
|
797
|
+
return {
|
|
798
|
+
...newItem,
|
|
799
|
+
...value
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
return {
|
|
803
|
+
...newItem,
|
|
804
|
+
[key]: value
|
|
805
|
+
};
|
|
806
|
+
}, {});
|
|
807
|
+
}
|
|
771
808
|
function getFieldOptions(node, presentation) {
|
|
772
809
|
function convertToOptions(nodeOptions) {
|
|
773
810
|
return nodeOptions.filter(notNullOption).map(({ title, const: cons, ...item }) => ({
|
|
774
811
|
label: title,
|
|
775
812
|
value: cons,
|
|
776
|
-
...item
|
|
813
|
+
...flatPresentation(item)
|
|
777
814
|
}));
|
|
778
815
|
}
|
|
779
816
|
if (presentation.options) {
|
|
@@ -889,30 +926,38 @@ var handleValuesChange = (fields, jsonSchema, config) => (values) => {
|
|
|
889
926
|
};
|
|
890
927
|
|
|
891
928
|
// src/calculateConditionalProperties.js
|
|
892
|
-
function isFieldRequired(node,
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
929
|
+
function isFieldRequired(node, field) {
|
|
930
|
+
return (
|
|
931
|
+
// Check base root required
|
|
932
|
+
field.scopedJsonSchema?.required?.includes(field.name) || // Check conditional required
|
|
933
|
+
node?.required?.includes(field.name)
|
|
934
|
+
);
|
|
897
935
|
}
|
|
898
|
-
function
|
|
936
|
+
function rebuildFieldset(fields, property) {
|
|
899
937
|
if (property?.properties) {
|
|
900
938
|
return fields.map((field) => {
|
|
939
|
+
const propertyConditionals = property.properties[field.name];
|
|
940
|
+
if (!propertyConditionals) {
|
|
941
|
+
return field;
|
|
942
|
+
}
|
|
943
|
+
const newFieldParams = extractParametersFromNode(propertyConditionals);
|
|
901
944
|
if (field.fields) {
|
|
902
945
|
return {
|
|
903
946
|
...field,
|
|
904
|
-
|
|
947
|
+
...newFieldParams,
|
|
948
|
+
fields: rebuildFieldset(field.fields, propertyConditionals)
|
|
905
949
|
};
|
|
906
950
|
}
|
|
907
951
|
return {
|
|
908
952
|
...field,
|
|
909
|
-
|
|
953
|
+
...newFieldParams,
|
|
954
|
+
required: isFieldRequired(property, field)
|
|
910
955
|
};
|
|
911
956
|
});
|
|
912
957
|
}
|
|
913
958
|
return fields.map((field) => ({
|
|
914
959
|
...field,
|
|
915
|
-
required: isFieldRequired(property, field
|
|
960
|
+
required: isFieldRequired(property, field)
|
|
916
961
|
}));
|
|
917
962
|
}
|
|
918
963
|
function calculateConditionalProperties(fieldParams, customProperties) {
|
|
@@ -927,10 +972,7 @@ function calculateConditionalProperties(fieldParams, customProperties) {
|
|
|
927
972
|
});
|
|
928
973
|
let fieldSetFields;
|
|
929
974
|
if (fieldParams.inputType === supportedTypes.FIELDSET) {
|
|
930
|
-
fieldSetFields =
|
|
931
|
-
fieldParams.fields,
|
|
932
|
-
conditionalProperty
|
|
933
|
-
);
|
|
975
|
+
fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
|
|
934
976
|
newFieldParams.fields = fieldSetFields;
|
|
935
977
|
}
|
|
936
978
|
const base = {
|