@remoteoss/json-schema-form 0.11.11-dev.20250220164730 → 0.11.12-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 +2 -2
- package/dist/index.js +2 -2
- package/dist/standalone.js +2 -2
- package/package.json +1 -1
- package/src/tests/conditions.test.js +31 -59
- package/src/tests/createHeadlessForm.test.js +1 -1
- package/src/tests/helpers.custom.js +7 -7
- package/src/tests/helpers.js +5 -5
- package/src/tests/jsonLogic.fixtures.js +48 -0
- package/src/tests/jsonLogic.test.js +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
#### 0.11.12-beta.0 (2025-04-15)
|
|
2
|
+
|
|
3
|
+
##### Chores
|
|
4
|
+
|
|
5
|
+
* change deprecated 'presentation' to 'x-jsf-presentation' in test helpers ([#159](https://github.com/remoteoss/json-schema-form/pull/159)) ([3f03b16d](https://github.com/remoteoss/json-schema-form/commit/3f03b16dce6acd801ff497a9c547cceb1b6347c5))
|
|
6
|
+
|
|
7
|
+
#### 0.11.11-beta.0 (2025-02-20)
|
|
8
|
+
|
|
9
|
+
##### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **conditionals:** Add support to `oneOf` ([#136](https://github.com/remoteoss/json-schema-form/pull/136)) ([966cec59](https://github.com/remoteoss/json-schema-form/commit/966cec595ed2a1ff35f9d15e22acaea16cdd5113))
|
|
12
|
+
|
|
1
13
|
#### 0.11.10-beta.0 (2025-01-22)
|
|
2
14
|
|
|
3
15
|
##### Bug Fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2025 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.11.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-beta.0
|
|
5
|
+
Generated: Tue, 15 Apr 2025 08:28:29 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2025 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.11.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-beta.0
|
|
5
|
+
Generated: Tue, 15 Apr 2025 08:28:29 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
package/dist/standalone.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2025 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.11.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-beta.0
|
|
5
|
+
Generated: Tue, 15 Apr 2025 08:28:29 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.12-beta.0",
|
|
4
4
|
"description": "Headless UI form powered by JSON Schemas",
|
|
5
5
|
"author": "Remote.com <engineering@remote.com> (https://remote.com/)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -549,77 +549,49 @@ describe('Conditional with literal booleans', () => {
|
|
|
549
549
|
});
|
|
550
550
|
|
|
551
551
|
describe('Conditional with anyOf', () => {
|
|
552
|
-
|
|
553
|
-
|
|
552
|
+
const schema = {
|
|
553
|
+
additionalProperties: false,
|
|
554
|
+
type: 'object',
|
|
555
|
+
properties: {
|
|
556
|
+
field_a: { type: 'string' },
|
|
557
|
+
field_b: { type: 'string' },
|
|
558
|
+
field_c: { type: 'string' },
|
|
559
|
+
},
|
|
560
|
+
allOf: [
|
|
554
561
|
{
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
field_c: { type: 'string' },
|
|
562
|
+
if: {
|
|
563
|
+
anyOf: [
|
|
564
|
+
{ properties: { field_a: { const: '1' } }, required: ['field_a'] },
|
|
565
|
+
{ properties: { field_b: { const: '2' } }, required: ['field_b'] },
|
|
566
|
+
],
|
|
561
567
|
},
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
],
|
|
569
|
-
},
|
|
570
|
-
then: {
|
|
571
|
-
required: ['field_c'],
|
|
572
|
-
},
|
|
573
|
-
else: {
|
|
574
|
-
properties: {
|
|
575
|
-
field_c: false,
|
|
576
|
-
},
|
|
577
|
-
},
|
|
568
|
+
then: {
|
|
569
|
+
required: ['field_c'],
|
|
570
|
+
},
|
|
571
|
+
else: {
|
|
572
|
+
properties: {
|
|
573
|
+
field_c: false,
|
|
578
574
|
},
|
|
579
|
-
|
|
575
|
+
},
|
|
580
576
|
},
|
|
581
|
-
|
|
582
|
-
|
|
577
|
+
],
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
it('handles true case', () => {
|
|
581
|
+
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
583
582
|
|
|
584
|
-
expect(
|
|
583
|
+
expect(fields[2].isVisible).toBe(false);
|
|
584
|
+
expect(handleValidation({ field_a: 'x', field_b: '2' }).formErrors).toEqual({
|
|
585
585
|
field_c: 'Required field',
|
|
586
586
|
});
|
|
587
587
|
expect(fields[2].isVisible).toBe(true);
|
|
588
588
|
});
|
|
589
589
|
|
|
590
590
|
it('handles false case', () => {
|
|
591
|
-
const { fields, handleValidation } = createHeadlessForm(
|
|
592
|
-
{
|
|
593
|
-
additionalProperties: false,
|
|
594
|
-
type: 'object',
|
|
595
|
-
properties: {
|
|
596
|
-
field_a: { type: 'string' },
|
|
597
|
-
field_b: { type: 'string' },
|
|
598
|
-
field_c: { type: 'string' },
|
|
599
|
-
},
|
|
600
|
-
allOf: [
|
|
601
|
-
{
|
|
602
|
-
if: {
|
|
603
|
-
anyOf: [
|
|
604
|
-
{ properties: { field_a: { const: '1' } }, required: ['a'] },
|
|
605
|
-
{ properties: { field_b: { const: '2' } }, required: ['b'] },
|
|
606
|
-
],
|
|
607
|
-
},
|
|
608
|
-
then: {
|
|
609
|
-
required: ['field_c'],
|
|
610
|
-
},
|
|
611
|
-
else: {
|
|
612
|
-
properties: {
|
|
613
|
-
field_c: false,
|
|
614
|
-
},
|
|
615
|
-
},
|
|
616
|
-
},
|
|
617
|
-
],
|
|
618
|
-
},
|
|
619
|
-
{ strictInputType: false }
|
|
620
|
-
);
|
|
591
|
+
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
621
592
|
|
|
622
|
-
expect(
|
|
593
|
+
expect(fields[2].isVisible).toBe(false);
|
|
594
|
+
expect(handleValidation({ field_a: 'x', field_b: 'x' }).formErrors).toBeUndefined();
|
|
623
595
|
expect(fields[2].isVisible).toBe(false);
|
|
624
596
|
});
|
|
625
597
|
});
|
|
@@ -2521,7 +2521,7 @@ describe('createHeadlessForm', () => {
|
|
|
2521
2521
|
.addInput({
|
|
2522
2522
|
username: {
|
|
2523
2523
|
...mockTextInputDeprecated,
|
|
2524
|
-
presentation: {
|
|
2524
|
+
'x-jsf-presentation': {
|
|
2525
2525
|
inputType: 'text',
|
|
2526
2526
|
maskSecret: 2,
|
|
2527
2527
|
// should override the root level description
|
|
@@ -11,7 +11,7 @@ export const schemaInputTypeTextarea = {
|
|
|
11
11
|
properties: {
|
|
12
12
|
comment: {
|
|
13
13
|
title: 'Your comment',
|
|
14
|
-
presentation: {
|
|
14
|
+
'x-jsf-presentation': {
|
|
15
15
|
inputType: 'textarea',
|
|
16
16
|
},
|
|
17
17
|
maxLength: 250,
|
|
@@ -29,7 +29,7 @@ export const inputTypeCountriesSolo = {
|
|
|
29
29
|
{ title: 'Algeria', const: 'Algeria' },
|
|
30
30
|
],
|
|
31
31
|
type: 'string',
|
|
32
|
-
presentation: {
|
|
32
|
+
'x-jsf-presentation': {
|
|
33
33
|
inputType: 'countries',
|
|
34
34
|
},
|
|
35
35
|
};
|
|
@@ -58,7 +58,7 @@ export const schemaInputTypeCountriesMultiple = {
|
|
|
58
58
|
],
|
|
59
59
|
},
|
|
60
60
|
type: 'array',
|
|
61
|
-
presentation: {
|
|
61
|
+
'x-jsf-presentation': {
|
|
62
62
|
inputType: 'countries',
|
|
63
63
|
},
|
|
64
64
|
},
|
|
@@ -90,7 +90,7 @@ export const schemaInputTypeTel = {
|
|
|
90
90
|
type: 'string',
|
|
91
91
|
pattern: '^(\\+|00)[0-9]{6,}$',
|
|
92
92
|
maxLength: 30,
|
|
93
|
-
presentation: {
|
|
93
|
+
'x-jsf-presentation': {
|
|
94
94
|
inputType: 'tel',
|
|
95
95
|
},
|
|
96
96
|
errorMessage: {
|
|
@@ -106,7 +106,7 @@ const mockTelInput = {
|
|
|
106
106
|
title: 'Phone number',
|
|
107
107
|
description: 'Enter your telephone number',
|
|
108
108
|
maxLength: 30,
|
|
109
|
-
presentation: {
|
|
109
|
+
'x-jsf-presentation': {
|
|
110
110
|
inputType: 'tel',
|
|
111
111
|
},
|
|
112
112
|
pattern: '^(\\+|00)\\d*$',
|
|
@@ -116,7 +116,7 @@ const mockTelInput = {
|
|
|
116
116
|
export const mockMoneyInput = {
|
|
117
117
|
title: 'Weekly salary',
|
|
118
118
|
description: 'This field has a min and max values. Max has a custom error message.',
|
|
119
|
-
presentation: {
|
|
119
|
+
'x-jsf-presentation': {
|
|
120
120
|
inputType: 'money',
|
|
121
121
|
currency: 'EUR',
|
|
122
122
|
},
|
|
@@ -150,7 +150,7 @@ export const schemaCustomComponent = {
|
|
|
150
150
|
salary: {
|
|
151
151
|
title: 'Monthly gross salary',
|
|
152
152
|
description: 'This field gets represented by a custom UI Component.',
|
|
153
|
-
presentation: {
|
|
153
|
+
'x-jsf-presentation': {
|
|
154
154
|
inputType: 'money',
|
|
155
155
|
currency: 'EUR',
|
|
156
156
|
},
|
package/src/tests/helpers.js
CHANGED
|
@@ -17,7 +17,7 @@ export const mockTextInputDeprecated = {
|
|
|
17
17
|
title: 'Username',
|
|
18
18
|
description: 'Your username (max 10 characters)',
|
|
19
19
|
maxLength: 10,
|
|
20
|
-
presentation: {
|
|
20
|
+
'x-jsf-presentation': {
|
|
21
21
|
inputType: 'text',
|
|
22
22
|
maskSecret: 2,
|
|
23
23
|
},
|
|
@@ -1284,7 +1284,7 @@ export const schemaForErrorMessageSpecificity = {
|
|
|
1284
1284
|
title: 'Weekday',
|
|
1285
1285
|
description: "This text field has the traditional error message. 'Required field'",
|
|
1286
1286
|
type: 'string',
|
|
1287
|
-
presentation: { inputType: 'text' },
|
|
1287
|
+
'x-jsf-presentation': { inputType: 'text' },
|
|
1288
1288
|
},
|
|
1289
1289
|
day: {
|
|
1290
1290
|
title: 'Day',
|
|
@@ -1293,21 +1293,21 @@ export const schemaForErrorMessageSpecificity = {
|
|
|
1293
1293
|
'The remaining fields are numbers and were customized to say "This cannot be empty." instead of "Required field".',
|
|
1294
1294
|
|
|
1295
1295
|
maximum: 31,
|
|
1296
|
-
presentation: { inputType: 'number' },
|
|
1296
|
+
'x-jsf-presentation': { inputType: 'number' },
|
|
1297
1297
|
},
|
|
1298
1298
|
month: {
|
|
1299
1299
|
title: 'Month',
|
|
1300
1300
|
type: 'number',
|
|
1301
1301
|
minimum: 1,
|
|
1302
1302
|
maximum: 12,
|
|
1303
|
-
presentation: { inputType: 'number' },
|
|
1303
|
+
'x-jsf-presentation': { inputType: 'number' },
|
|
1304
1304
|
},
|
|
1305
1305
|
year: {
|
|
1306
1306
|
title: 'Year',
|
|
1307
1307
|
description:
|
|
1308
1308
|
"This number field has a custom error message declared in the json schema, which has a higher specificity than the one declared in createHeadlessForm's configuration.",
|
|
1309
1309
|
type: 'number',
|
|
1310
|
-
presentation: { inputType: 'number' },
|
|
1310
|
+
'x-jsf-presentation': { inputType: 'number' },
|
|
1311
1311
|
'x-jsf-errorMessage': {
|
|
1312
1312
|
required: 'The year is mandatory.',
|
|
1313
1313
|
},
|
|
@@ -984,3 +984,51 @@ export const schemaWithTwoValidationsWhereOneOfThemIsAppliedConditionally = {
|
|
|
984
984
|
},
|
|
985
985
|
],
|
|
986
986
|
};
|
|
987
|
+
|
|
988
|
+
export const schemaWithReduceAccumulator = {
|
|
989
|
+
properties: {
|
|
990
|
+
work_days: {
|
|
991
|
+
items: {
|
|
992
|
+
anyOf: [
|
|
993
|
+
{ const: 'monday', title: 'Monday' },
|
|
994
|
+
{ const: 'tuesday', title: 'Tuesday' },
|
|
995
|
+
{ const: 'wednesday', title: 'Wednesday' },
|
|
996
|
+
{ const: 'thursday', title: 'Thursday' },
|
|
997
|
+
{ const: 'friday', title: 'Friday' },
|
|
998
|
+
{ const: 'saturday', title: 'Saturday' },
|
|
999
|
+
{ const: 'sunday', title: 'Sunday' },
|
|
1000
|
+
],
|
|
1001
|
+
},
|
|
1002
|
+
type: 'array',
|
|
1003
|
+
uniqueItems: true,
|
|
1004
|
+
'x-jsf-presentation': {
|
|
1005
|
+
inputType: 'select',
|
|
1006
|
+
},
|
|
1007
|
+
},
|
|
1008
|
+
working_hours_per_day: {
|
|
1009
|
+
type: 'number',
|
|
1010
|
+
},
|
|
1011
|
+
working_hours_per_week: {
|
|
1012
|
+
type: 'number',
|
|
1013
|
+
'x-jsf-logic-computedAttrs': {
|
|
1014
|
+
const: 'computed_work_hours_per_week',
|
|
1015
|
+
defaultValue: 'computed_work_hours_per_week',
|
|
1016
|
+
title: '{{computed_work_hours_per_week}} hours per week',
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
},
|
|
1020
|
+
'x-jsf-logic': {
|
|
1021
|
+
computedValues: {
|
|
1022
|
+
computed_work_hours_per_week: {
|
|
1023
|
+
rule: {
|
|
1024
|
+
'*': [
|
|
1025
|
+
{ var: 'working_hours_per_day' },
|
|
1026
|
+
{
|
|
1027
|
+
reduce: [{ var: 'work_days' }, { '+': [{ var: ['accumulator', 0] }, 1] }, 0],
|
|
1028
|
+
},
|
|
1029
|
+
],
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
},
|
|
1033
|
+
},
|
|
1034
|
+
};
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
schemaWithUnknownVariableInValidations,
|
|
35
35
|
schemaWithValidationThatDoesNotExistOnProperty,
|
|
36
36
|
badSchemaThatWillNotSetAForcedValue,
|
|
37
|
+
schemaWithReduceAccumulator,
|
|
37
38
|
} from './jsonLogic.fixtures';
|
|
38
39
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
39
40
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -243,6 +244,23 @@ describe('jsonLogic: cross-values validations', () => {
|
|
|
243
244
|
});
|
|
244
245
|
});
|
|
245
246
|
|
|
247
|
+
// TODO: Implement this test.
|
|
248
|
+
describe.skip('Reduce', () => {
|
|
249
|
+
it('reduce: working_hours_per_day * work_days', () => {
|
|
250
|
+
const { fields, handleValidation } = createHeadlessForm(schemaWithReduceAccumulator, {
|
|
251
|
+
strictInputType: false,
|
|
252
|
+
});
|
|
253
|
+
handleValidation({
|
|
254
|
+
work_days: ['monday', 'tuesday'],
|
|
255
|
+
working_hours_per_day: 8,
|
|
256
|
+
});
|
|
257
|
+
const field = fields.find((i) => i.name === 'working_hours_per_week');
|
|
258
|
+
expect(field.const).toEqual(16);
|
|
259
|
+
expect(field.default).toEqual(16);
|
|
260
|
+
expect(field.label).toEqual('16 hours per week');
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
246
264
|
describe('Logical: ||, &&', () => {
|
|
247
265
|
it('AND: field_a > field_b && field_a > field_c (implicit with multiple rules in a single field)', () => {
|
|
248
266
|
const schema = createSchemaWithThreePropertiesWithRuleOnFieldA({
|