@remoteoss/json-schema-form 0.8.1-dev.20240209164254 → 0.8.2-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 +12 -0
- package/dist/index.cjs +7 -10
- package/dist/index.js +7 -10
- package/dist/standalone.js +7 -10
- package/package.json +1 -1
- package/src/tests/conditions.test.js +56 -0
- package/src/tests/const.test.js +3 -15
- package/src/tests/createHeadlessForm.test.js +10 -0
- package/src/tests/helpers.js +12 -0
- package/src/tests/jsonLogic.fixtures.js +0 -29
- package/src/tests/jsonLogic.test.js +1 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
#### 0.8.2-beta.0 (2024-02-13)
|
|
2
|
+
|
|
3
|
+
##### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* **helpers:** getFieldOptions - return empty array if oneOf missing in radio ([#67](https://github.com/remoteoss/json-schema-form/pull/67)) ([6511330f](https://github.com/remoteoss/json-schema-form/commit/6511330f55a2accedb1c58a61ff915a3a0186dbb))
|
|
6
|
+
|
|
7
|
+
#### 0.8.1-beta.0 (2024-02-12)
|
|
8
|
+
|
|
9
|
+
##### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **conditionals:** Certain conditions in a JSON schema were failing. This bugfix adds missing field context to the evaluation to prevent the error. ([#65](https://github.com/remoteoss/json-schema-form/pull/65)) ([6755a2fd](https://github.com/remoteoss/json-schema-form/commit/6755a2fd29f3f806a57ba19e29ad7e21daf9e51b))
|
|
12
|
+
|
|
1
13
|
#### 0.8.0-beta.0 (2024-02-01)
|
|
2
14
|
|
|
3
15
|
##### Bug Fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2024 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.8.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.8.2-beta.0
|
|
5
|
+
Generated: Tue, 13 Feb 2024 11:25:15 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -130,10 +130,8 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
|
|
|
130
130
|
const field = getField(name, formFields);
|
|
131
131
|
return validateFieldSchema(
|
|
132
132
|
{
|
|
133
|
-
|
|
134
|
-
// @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
|
|
133
|
+
...field,
|
|
135
134
|
...currentProperty,
|
|
136
|
-
inputType: field.inputType,
|
|
137
135
|
required: true
|
|
138
136
|
},
|
|
139
137
|
value
|
|
@@ -1363,8 +1361,8 @@ function getFieldOptions(node, presentation) {
|
|
|
1363
1361
|
if (presentation.options) {
|
|
1364
1362
|
return presentation.options;
|
|
1365
1363
|
}
|
|
1366
|
-
if (node.oneOf) {
|
|
1367
|
-
return convertToOptions(node.oneOf);
|
|
1364
|
+
if (node.oneOf || presentation.inputType === "radio") {
|
|
1365
|
+
return convertToOptions(node.oneOf || []);
|
|
1368
1366
|
}
|
|
1369
1367
|
if (node.items?.anyOf) {
|
|
1370
1368
|
return convertToOptions(node.items.anyOf);
|
|
@@ -1383,7 +1381,7 @@ function extractParametersFromNode(schemaNode) {
|
|
|
1383
1381
|
const node = (0, import_omit.default)(schemaNode, ["x-jsf-presentation", "presentation"]);
|
|
1384
1382
|
const description = presentation?.description || node.description;
|
|
1385
1383
|
const statementDescription = presentation.statement?.description;
|
|
1386
|
-
const value = typeof node.const !== "undefined" && typeof node.default !== "undefined"
|
|
1384
|
+
const value = typeof node.const !== "undefined" && typeof node.default !== "undefined" ? { value: node.const } : {};
|
|
1387
1385
|
return (0, import_omitBy.default)(
|
|
1388
1386
|
{
|
|
1389
1387
|
const: node.const,
|
|
@@ -1479,10 +1477,9 @@ var handleValuesChange = (fields, jsonSchema, config, logic) => (values) => {
|
|
|
1479
1477
|
};
|
|
1480
1478
|
};
|
|
1481
1479
|
function getDecoratedComputedAttributes(computedAttributes) {
|
|
1482
|
-
const isEqualConstAndDefault = computedAttributes?.const === computedAttributes?.default;
|
|
1483
1480
|
return {
|
|
1484
1481
|
...computedAttributes ?? {},
|
|
1485
|
-
...computedAttributes?.const && computedAttributes?.default
|
|
1482
|
+
...computedAttributes?.const && computedAttributes?.default ? { value: computedAttributes.const } : {}
|
|
1486
1483
|
};
|
|
1487
1484
|
}
|
|
1488
1485
|
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2024 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.8.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.8.2-beta.0
|
|
5
|
+
Generated: Tue, 13 Feb 2024 11:25:15 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -94,10 +94,8 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
|
|
|
94
94
|
const field = getField(name, formFields);
|
|
95
95
|
return validateFieldSchema(
|
|
96
96
|
{
|
|
97
|
-
|
|
98
|
-
// @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
|
|
97
|
+
...field,
|
|
99
98
|
...currentProperty,
|
|
100
|
-
inputType: field.inputType,
|
|
101
99
|
required: true
|
|
102
100
|
},
|
|
103
101
|
value
|
|
@@ -1327,8 +1325,8 @@ function getFieldOptions(node, presentation) {
|
|
|
1327
1325
|
if (presentation.options) {
|
|
1328
1326
|
return presentation.options;
|
|
1329
1327
|
}
|
|
1330
|
-
if (node.oneOf) {
|
|
1331
|
-
return convertToOptions(node.oneOf);
|
|
1328
|
+
if (node.oneOf || presentation.inputType === "radio") {
|
|
1329
|
+
return convertToOptions(node.oneOf || []);
|
|
1332
1330
|
}
|
|
1333
1331
|
if (node.items?.anyOf) {
|
|
1334
1332
|
return convertToOptions(node.items.anyOf);
|
|
@@ -1347,7 +1345,7 @@ function extractParametersFromNode(schemaNode) {
|
|
|
1347
1345
|
const node = omit(schemaNode, ["x-jsf-presentation", "presentation"]);
|
|
1348
1346
|
const description = presentation?.description || node.description;
|
|
1349
1347
|
const statementDescription = presentation.statement?.description;
|
|
1350
|
-
const value = typeof node.const !== "undefined" && typeof node.default !== "undefined"
|
|
1348
|
+
const value = typeof node.const !== "undefined" && typeof node.default !== "undefined" ? { value: node.const } : {};
|
|
1351
1349
|
return omitBy(
|
|
1352
1350
|
{
|
|
1353
1351
|
const: node.const,
|
|
@@ -1443,10 +1441,9 @@ var handleValuesChange = (fields, jsonSchema, config, logic) => (values) => {
|
|
|
1443
1441
|
};
|
|
1444
1442
|
};
|
|
1445
1443
|
function getDecoratedComputedAttributes(computedAttributes) {
|
|
1446
|
-
const isEqualConstAndDefault = computedAttributes?.const === computedAttributes?.default;
|
|
1447
1444
|
return {
|
|
1448
1445
|
...computedAttributes ?? {},
|
|
1449
|
-
...computedAttributes?.const && computedAttributes?.default
|
|
1446
|
+
...computedAttributes?.const && computedAttributes?.default ? { value: computedAttributes.const } : {}
|
|
1450
1447
|
};
|
|
1451
1448
|
}
|
|
1452
1449
|
|
package/dist/standalone.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2024 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.8.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.8.2-beta.0
|
|
5
|
+
Generated: Tue, 13 Feb 2024 11:25:15 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -11449,10 +11449,8 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
|
|
|
11449
11449
|
const field = getField(name, formFields);
|
|
11450
11450
|
return validateFieldSchema(
|
|
11451
11451
|
{
|
|
11452
|
-
|
|
11453
|
-
// @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
|
|
11452
|
+
...field,
|
|
11454
11453
|
...currentProperty,
|
|
11455
|
-
inputType: field.inputType,
|
|
11456
11454
|
required: true
|
|
11457
11455
|
},
|
|
11458
11456
|
value
|
|
@@ -12681,8 +12679,8 @@ function getFieldOptions(node, presentation) {
|
|
|
12681
12679
|
if (presentation.options) {
|
|
12682
12680
|
return presentation.options;
|
|
12683
12681
|
}
|
|
12684
|
-
if (node.oneOf) {
|
|
12685
|
-
return convertToOptions(node.oneOf);
|
|
12682
|
+
if (node.oneOf || presentation.inputType === "radio") {
|
|
12683
|
+
return convertToOptions(node.oneOf || []);
|
|
12686
12684
|
}
|
|
12687
12685
|
if (node.items?.anyOf) {
|
|
12688
12686
|
return convertToOptions(node.items.anyOf);
|
|
@@ -12701,7 +12699,7 @@ function extractParametersFromNode(schemaNode) {
|
|
|
12701
12699
|
const node = (0, import_omit.default)(schemaNode, ["x-jsf-presentation", "presentation"]);
|
|
12702
12700
|
const description = presentation?.description || node.description;
|
|
12703
12701
|
const statementDescription = presentation.statement?.description;
|
|
12704
|
-
const value = typeof node.const !== "undefined" && typeof node.default !== "undefined"
|
|
12702
|
+
const value = typeof node.const !== "undefined" && typeof node.default !== "undefined" ? { value: node.const } : {};
|
|
12705
12703
|
return (0, import_omitBy.default)(
|
|
12706
12704
|
{
|
|
12707
12705
|
const: node.const,
|
|
@@ -12797,10 +12795,9 @@ var handleValuesChange = (fields, jsonSchema, config, logic) => (values2) => {
|
|
|
12797
12795
|
};
|
|
12798
12796
|
};
|
|
12799
12797
|
function getDecoratedComputedAttributes(computedAttributes) {
|
|
12800
|
-
const isEqualConstAndDefault = computedAttributes?.const === computedAttributes?.default;
|
|
12801
12798
|
return {
|
|
12802
12799
|
...computedAttributes ?? {},
|
|
12803
|
-
...computedAttributes?.const && computedAttributes?.default
|
|
12800
|
+
...computedAttributes?.const && computedAttributes?.default ? { value: computedAttributes.const } : {}
|
|
12804
12801
|
};
|
|
12805
12802
|
}
|
|
12806
12803
|
|
package/package.json
CHANGED
|
@@ -423,3 +423,59 @@ describe('Conditional attributes updated', () => {
|
|
|
423
423
|
expect(fields[1].visibilityCondition).toEqual(expect.any(Function));
|
|
424
424
|
});
|
|
425
425
|
});
|
|
426
|
+
|
|
427
|
+
describe('Conditional with a minimum value check', () => {
|
|
428
|
+
it('Should handle a maximum as a property field check', () => {
|
|
429
|
+
const schema = {
|
|
430
|
+
additionalProperties: false,
|
|
431
|
+
allOf: [
|
|
432
|
+
{
|
|
433
|
+
if: {
|
|
434
|
+
properties: {
|
|
435
|
+
salary: {
|
|
436
|
+
maximum: 119999,
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
required: ['salary'],
|
|
440
|
+
},
|
|
441
|
+
then: {
|
|
442
|
+
required: ['reason'],
|
|
443
|
+
},
|
|
444
|
+
else: {
|
|
445
|
+
properties: {
|
|
446
|
+
reason: false,
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
],
|
|
451
|
+
properties: {
|
|
452
|
+
salary: {
|
|
453
|
+
type: 'number',
|
|
454
|
+
'x-jsf-presentation': {
|
|
455
|
+
inputType: 'money',
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
reason: {
|
|
459
|
+
oneOf: [
|
|
460
|
+
{
|
|
461
|
+
const: 'reason_one',
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
const: 'reason_two',
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
type: 'string',
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
required: ['salary'],
|
|
471
|
+
type: 'object',
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
const { handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
475
|
+
expect(handleValidation({ salary: 120000 }).formErrors).toEqual(undefined);
|
|
476
|
+
expect(handleValidation({ salary: 1000 }).formErrors).toEqual({
|
|
477
|
+
reason: 'Required field',
|
|
478
|
+
});
|
|
479
|
+
expect(handleValidation({ salary: 1000, reason: 'reason_one' }).formErrors).toEqual(undefined);
|
|
480
|
+
});
|
|
481
|
+
});
|
package/src/tests/const.test.js
CHANGED
|
@@ -112,7 +112,7 @@ describe('validations: const', () => {
|
|
|
112
112
|
},
|
|
113
113
|
{ strictInputType: false }
|
|
114
114
|
);
|
|
115
|
-
expect(fields[0]).toMatchObject({
|
|
115
|
+
expect(fields[0]).toMatchObject({ value: 10, const: 10, default: 10 });
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
118
|
|
|
@@ -130,7 +130,7 @@ describe('const/default with forced values', () => {
|
|
|
130
130
|
expect(handleValidation({ zero_only: 1 }).formErrors).toEqual({
|
|
131
131
|
zero_only: 'The only accepted value is 0.',
|
|
132
132
|
});
|
|
133
|
-
expect(fields[0]).toMatchObject({
|
|
133
|
+
expect(fields[0]).toMatchObject({ value: 0, const: 0, default: 0 });
|
|
134
134
|
expect(handleValidation({ zero_only: 0 }).formErrors).toBeUndefined();
|
|
135
135
|
// null is also considered valid until we fix @BUG RMT-518
|
|
136
136
|
// Expectation: To fail with error "The only accepted value is 0."
|
|
@@ -151,21 +151,9 @@ describe('const/default with forced values', () => {
|
|
|
151
151
|
ten_only: 'The only accepted value is 10.',
|
|
152
152
|
});
|
|
153
153
|
expect(handleValidation({ ten_only: 10 }).formErrors).toBeUndefined();
|
|
154
|
-
expect(fields[0]).toMatchObject({
|
|
154
|
+
expect(fields[0]).toMatchObject({ value: 10, const: 10, default: 10 });
|
|
155
155
|
// null is also considered valid until we fix @BUG RMT-518
|
|
156
156
|
// Expectation: To fail with error "The only accepted value is 10."
|
|
157
157
|
expect(handleValidation({ ten_only: null }).formErrors).toBeUndefined();
|
|
158
158
|
});
|
|
159
|
-
|
|
160
|
-
it('do not set a forced value if const and default do not equal', () => {
|
|
161
|
-
const { fields } = createHeadlessForm(
|
|
162
|
-
{
|
|
163
|
-
properties: {
|
|
164
|
-
bad_field_for_number: { type: 'number', const: 10, default: 20 },
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
{ strictInputType: false }
|
|
168
|
-
);
|
|
169
|
-
expect(fields[0]).not.toMatchObject({ forcedValue: expect.any(Number) });
|
|
170
|
-
});
|
|
171
159
|
});
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
schemaInputRadioOptionalNull,
|
|
14
14
|
schemaInputRadioOptionalConventional,
|
|
15
15
|
schemaInputTypeRadioOptionsWithDetails,
|
|
16
|
+
schemaInputTypeRadioWithoutOptions,
|
|
16
17
|
schemaInputTypeSelectSoloDeprecated,
|
|
17
18
|
schemaInputTypeSelectSolo,
|
|
18
19
|
schemaInputTypeSelectMultipleDeprecated,
|
|
@@ -902,6 +903,15 @@ describe('createHeadlessForm', () => {
|
|
|
902
903
|
]);
|
|
903
904
|
});
|
|
904
905
|
|
|
906
|
+
it('support "radio" field type without oneOf options', () => {
|
|
907
|
+
const result = createHeadlessForm(schemaInputTypeRadioWithoutOptions);
|
|
908
|
+
|
|
909
|
+
expect(result.fields).toHaveLength(1);
|
|
910
|
+
|
|
911
|
+
const fieldOptions = result.fields[0].options;
|
|
912
|
+
expect(fieldOptions).toEqual([]);
|
|
913
|
+
});
|
|
914
|
+
|
|
905
915
|
it('support "number" field type', () => {
|
|
906
916
|
const result = createHeadlessForm(schemaInputTypeNumber);
|
|
907
917
|
expect(result).toMatchObject({
|
package/src/tests/helpers.js
CHANGED
|
@@ -923,6 +923,18 @@ export const schemaInputTypeRadioOptionsWithDetails = {
|
|
|
923
923
|
},
|
|
924
924
|
};
|
|
925
925
|
|
|
926
|
+
export const schemaInputTypeRadioWithoutOptions = {
|
|
927
|
+
properties: {
|
|
928
|
+
health_perks: {
|
|
929
|
+
title: 'Health perks',
|
|
930
|
+
description:
|
|
931
|
+
'This example contains options with more custom details, under the x-jsf-presentation key',
|
|
932
|
+
'x-jsf-presentation': { inputType: 'radio' },
|
|
933
|
+
type: 'string',
|
|
934
|
+
},
|
|
935
|
+
},
|
|
936
|
+
};
|
|
937
|
+
|
|
926
938
|
/** @deprecated */
|
|
927
939
|
export const schemaInputTypeSelectSoloDeprecated = JSONSchemaBuilder()
|
|
928
940
|
.addInput({
|
|
@@ -227,35 +227,6 @@ export const schemaWithComputedAttributes = {
|
|
|
227
227
|
},
|
|
228
228
|
};
|
|
229
229
|
|
|
230
|
-
export const badSchemaThatWillNotSetAForcedValue = {
|
|
231
|
-
properties: {
|
|
232
|
-
field_a: {
|
|
233
|
-
type: 'number',
|
|
234
|
-
},
|
|
235
|
-
field_b: {
|
|
236
|
-
type: 'number',
|
|
237
|
-
'x-jsf-logic-computedAttrs': {
|
|
238
|
-
const: 'a_times_three',
|
|
239
|
-
default: 'a_times_two',
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
'x-jsf-logic': {
|
|
244
|
-
computedValues: {
|
|
245
|
-
a_times_two: {
|
|
246
|
-
rule: {
|
|
247
|
-
'*': [{ var: 'field_a' }, 2],
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
a_times_three: {
|
|
251
|
-
rule: {
|
|
252
|
-
'*': [{ var: 'field_a' }, 3],
|
|
253
|
-
},
|
|
254
|
-
},
|
|
255
|
-
},
|
|
256
|
-
},
|
|
257
|
-
};
|
|
258
|
-
|
|
259
230
|
export const schemaWithInlineRuleForComputedAttributeWithoutCopy = {
|
|
260
231
|
properties: {
|
|
261
232
|
field_a: {
|
|
@@ -35,7 +35,6 @@ import {
|
|
|
35
35
|
schemaWithUnknownVariableInComputedValues,
|
|
36
36
|
schemaWithUnknownVariableInValidations,
|
|
37
37
|
schemaWithValidationThatDoesNotExistOnProperty,
|
|
38
|
-
badSchemaThatWillNotSetAForcedValue,
|
|
39
38
|
} from './jsonLogic.fixtures';
|
|
40
39
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
41
40
|
|
|
@@ -336,21 +335,12 @@ describe('jsonLogic: cross-values validations', () => {
|
|
|
336
335
|
'This field is 2 times bigger than field_a with value of 4.'
|
|
337
336
|
);
|
|
338
337
|
expect(fieldB.default).toEqual(4);
|
|
339
|
-
expect(fieldB.
|
|
338
|
+
expect(fieldB.value).toEqual(4);
|
|
340
339
|
handleValidation({ field_a: 4 });
|
|
341
340
|
expect(fieldB.default).toEqual(8);
|
|
342
341
|
expect(fieldB.label).toEqual('This is 8!');
|
|
343
342
|
});
|
|
344
343
|
|
|
345
|
-
it('A forced value will not be set when const and default are not equal', () => {
|
|
346
|
-
const { fields } = createHeadlessForm(badSchemaThatWillNotSetAForcedValue, {
|
|
347
|
-
strictInputType: false,
|
|
348
|
-
initialValues: { field_a: 2 },
|
|
349
|
-
});
|
|
350
|
-
expect(fields[1]).toMatchObject({ const: 6, default: 4 });
|
|
351
|
-
expect(fields[1]).not.toMatchObject({ forcedValue: expect.any(Number) });
|
|
352
|
-
});
|
|
353
|
-
|
|
354
344
|
it('Derived errorMessages and statements work', () => {
|
|
355
345
|
const { fields, handleValidation } = createHeadlessForm(
|
|
356
346
|
schemaWithComputedAttributesAndErrorMessages,
|