@remoteoss/json-schema-form 0.11.11-dev.20250220174843 → 0.11.12-dev.20250310202108
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 +6 -0
- package/dist/index.cjs +75 -100
- package/dist/index.js +75 -100
- package/dist/standalone.js +75 -100
- package/package.json +1 -1
- package/src/tests/conditions.test.js +116 -227
- package/src/tests/createHeadlessForm.test.js +3 -58
- package/src/tests/helpers.js +0 -56
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
#### 0.11.11-beta.0 (2025-02-20)
|
|
2
|
+
|
|
3
|
+
##### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* **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))
|
|
6
|
+
|
|
1
7
|
#### 0.11.10-beta.0 (2025-01-22)
|
|
2
8
|
|
|
3
9
|
##### 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-dev.20250310202108
|
|
5
|
+
Generated: Mon, 10 Mar 2025 20:22:24 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -96,70 +96,6 @@ function hasProperty(object2, propertyName) {
|
|
|
96
96
|
return Object.prototype.hasOwnProperty.call(object2, propertyName);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
// src/internals/checkIfConditionMatches.js
|
|
100
|
-
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
101
|
-
if (typeof node.if === "boolean") {
|
|
102
|
-
return node.if;
|
|
103
|
-
}
|
|
104
|
-
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
105
|
-
const currentProperty = node.if.properties[name];
|
|
106
|
-
const value = formValues[name];
|
|
107
|
-
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
108
|
-
value === null;
|
|
109
|
-
const hasIfExplicit = node.if.required?.includes(name);
|
|
110
|
-
if (hasEmptyValue && !hasIfExplicit) {
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
if (hasProperty(currentProperty, "const")) {
|
|
114
|
-
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
115
|
-
}
|
|
116
|
-
if (currentProperty.contains?.pattern) {
|
|
117
|
-
const formValue = value || [];
|
|
118
|
-
if (Array.isArray(formValue)) {
|
|
119
|
-
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
120
|
-
return (value || []).some((item) => pattern.test(item));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
if (currentProperty.enum) {
|
|
124
|
-
return currentProperty.enum.includes(value);
|
|
125
|
-
}
|
|
126
|
-
if (currentProperty.properties) {
|
|
127
|
-
return checkIfConditionMatchesProperties(
|
|
128
|
-
{ if: currentProperty },
|
|
129
|
-
formValues[name],
|
|
130
|
-
getField(name, formFields).fields,
|
|
131
|
-
logic
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
const field = getField(name, formFields);
|
|
135
|
-
return validateFieldSchema(
|
|
136
|
-
{
|
|
137
|
-
...field,
|
|
138
|
-
...currentProperty,
|
|
139
|
-
required: true
|
|
140
|
-
},
|
|
141
|
-
value
|
|
142
|
-
);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
146
|
-
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
147
|
-
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
148
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
149
|
-
return true;
|
|
150
|
-
return false;
|
|
151
|
-
});
|
|
152
|
-
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
153
|
-
([name, property]) => {
|
|
154
|
-
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
155
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
156
|
-
return true;
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
);
|
|
160
|
-
return computedValuesMatch && validationsMatch;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
99
|
// src/internals/helpers.js
|
|
164
100
|
var import_merge = __toESM(require("lodash/fp/merge"));
|
|
165
101
|
var import_get = __toESM(require("lodash/get"));
|
|
@@ -419,6 +355,76 @@ function _composeFieldCustomClosure(defaultComposeFn) {
|
|
|
419
355
|
};
|
|
420
356
|
}
|
|
421
357
|
|
|
358
|
+
// src/internals/checkIfConditionMatches.js
|
|
359
|
+
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
360
|
+
if (typeof node.if === "boolean") {
|
|
361
|
+
return node.if;
|
|
362
|
+
}
|
|
363
|
+
if (node.if.anyOf) {
|
|
364
|
+
return node.if.anyOf.some(
|
|
365
|
+
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
369
|
+
const currentProperty = node.if.properties[name];
|
|
370
|
+
const field = getField(name, formFields ?? []);
|
|
371
|
+
const isFieldsetField = field?.inputType === supportedTypes.FIELDSET;
|
|
372
|
+
const value = formValues?.[name] ?? (isFieldsetField ? {} : void 0);
|
|
373
|
+
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
374
|
+
value === null;
|
|
375
|
+
const hasIfExplicit = node.if.required?.includes(name);
|
|
376
|
+
if (hasEmptyValue && !hasIfExplicit) {
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
if (hasProperty(currentProperty, "const")) {
|
|
380
|
+
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
381
|
+
}
|
|
382
|
+
if (currentProperty.contains?.pattern) {
|
|
383
|
+
const formValue = value || [];
|
|
384
|
+
if (Array.isArray(formValue)) {
|
|
385
|
+
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
386
|
+
return (value || []).some((item) => pattern.test(item));
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (currentProperty.enum) {
|
|
390
|
+
return currentProperty.enum.includes(value);
|
|
391
|
+
}
|
|
392
|
+
if (currentProperty.properties) {
|
|
393
|
+
return checkIfConditionMatchesProperties(
|
|
394
|
+
{ if: currentProperty },
|
|
395
|
+
formValues[name],
|
|
396
|
+
getField(name, formFields).fields,
|
|
397
|
+
logic
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
return validateFieldSchema(
|
|
401
|
+
{
|
|
402
|
+
...field,
|
|
403
|
+
...currentProperty,
|
|
404
|
+
required: true
|
|
405
|
+
},
|
|
406
|
+
value
|
|
407
|
+
);
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
411
|
+
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
412
|
+
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
413
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
414
|
+
return true;
|
|
415
|
+
return false;
|
|
416
|
+
});
|
|
417
|
+
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
418
|
+
([name, property]) => {
|
|
419
|
+
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
420
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
421
|
+
return true;
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
return computedValuesMatch && validationsMatch;
|
|
426
|
+
}
|
|
427
|
+
|
|
422
428
|
// src/jsonLogic.js
|
|
423
429
|
var import_json_logic_js = __toESM(require("json-logic-js"));
|
|
424
430
|
|
|
@@ -1164,11 +1170,7 @@ function hasType(type, typeName) {
|
|
|
1164
1170
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1165
1171
|
}
|
|
1166
1172
|
function getField(fieldName, fields) {
|
|
1167
|
-
|
|
1168
|
-
return fields.find(({ name }) => name === fieldName);
|
|
1169
|
-
} else {
|
|
1170
|
-
return fields[fieldName];
|
|
1171
|
-
}
|
|
1173
|
+
return fields.find(({ name }) => name === fieldName);
|
|
1172
1174
|
}
|
|
1173
1175
|
function validateFieldSchema(field, value, logic) {
|
|
1174
1176
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -1382,25 +1384,6 @@ function processNode({
|
|
|
1382
1384
|
logic
|
|
1383
1385
|
});
|
|
1384
1386
|
}
|
|
1385
|
-
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1386
|
-
const values = formValues[name];
|
|
1387
|
-
if (Array.isArray(values)) {
|
|
1388
|
-
const newFields = [];
|
|
1389
|
-
const field = getField(name, formFields);
|
|
1390
|
-
values.forEach((value) => {
|
|
1391
|
-
const fields = field.fields();
|
|
1392
|
-
processNode({
|
|
1393
|
-
node: nestedNode.items,
|
|
1394
|
-
formValues: value,
|
|
1395
|
-
formFields: fields,
|
|
1396
|
-
parentID: name,
|
|
1397
|
-
logic
|
|
1398
|
-
});
|
|
1399
|
-
newFields.push(fields);
|
|
1400
|
-
});
|
|
1401
|
-
field.dynamicFields = newFields;
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
1387
|
});
|
|
1405
1388
|
}
|
|
1406
1389
|
if (node["x-jsf-logic"]) {
|
|
@@ -1772,16 +1755,6 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
|
|
|
1772
1755
|
logic
|
|
1773
1756
|
);
|
|
1774
1757
|
}
|
|
1775
|
-
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1776
|
-
fields = () => getFieldsFromJSONSchema(
|
|
1777
|
-
fieldProperties.items,
|
|
1778
|
-
{
|
|
1779
|
-
customProperties: (0, import_get3.default)(config, `customProperties.${name}.customProperties`, {}),
|
|
1780
|
-
parentID: name
|
|
1781
|
-
},
|
|
1782
|
-
logic
|
|
1783
|
-
);
|
|
1784
|
-
}
|
|
1785
1758
|
const result = {
|
|
1786
1759
|
name,
|
|
1787
1760
|
inputType,
|
|
@@ -1875,10 +1848,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
1875
1848
|
if (fieldParams.inputType === "group-array") {
|
|
1876
1849
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
1877
1850
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
1851
|
+
groupArrayItem.nameKey = groupArrayItem.name;
|
|
1878
1852
|
const customProperties = null;
|
|
1879
1853
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
1880
1854
|
return composeFn(groupArrayItem);
|
|
1881
1855
|
});
|
|
1856
|
+
fieldParams.nameKey = fieldParams.name;
|
|
1882
1857
|
fieldParams.nthFieldGroup = {
|
|
1883
1858
|
name: fieldParams.name,
|
|
1884
1859
|
label: fieldParams.label,
|
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-dev.20250310202108
|
|
5
|
+
Generated: Mon, 10 Mar 2025 20:22:24 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -59,70 +59,6 @@ function hasProperty(object2, propertyName) {
|
|
|
59
59
|
return Object.prototype.hasOwnProperty.call(object2, propertyName);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
// src/internals/checkIfConditionMatches.js
|
|
63
|
-
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
64
|
-
if (typeof node.if === "boolean") {
|
|
65
|
-
return node.if;
|
|
66
|
-
}
|
|
67
|
-
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
68
|
-
const currentProperty = node.if.properties[name];
|
|
69
|
-
const value = formValues[name];
|
|
70
|
-
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
71
|
-
value === null;
|
|
72
|
-
const hasIfExplicit = node.if.required?.includes(name);
|
|
73
|
-
if (hasEmptyValue && !hasIfExplicit) {
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
if (hasProperty(currentProperty, "const")) {
|
|
77
|
-
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
78
|
-
}
|
|
79
|
-
if (currentProperty.contains?.pattern) {
|
|
80
|
-
const formValue = value || [];
|
|
81
|
-
if (Array.isArray(formValue)) {
|
|
82
|
-
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
83
|
-
return (value || []).some((item) => pattern.test(item));
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
if (currentProperty.enum) {
|
|
87
|
-
return currentProperty.enum.includes(value);
|
|
88
|
-
}
|
|
89
|
-
if (currentProperty.properties) {
|
|
90
|
-
return checkIfConditionMatchesProperties(
|
|
91
|
-
{ if: currentProperty },
|
|
92
|
-
formValues[name],
|
|
93
|
-
getField(name, formFields).fields,
|
|
94
|
-
logic
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
const field = getField(name, formFields);
|
|
98
|
-
return validateFieldSchema(
|
|
99
|
-
{
|
|
100
|
-
...field,
|
|
101
|
-
...currentProperty,
|
|
102
|
-
required: true
|
|
103
|
-
},
|
|
104
|
-
value
|
|
105
|
-
);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
109
|
-
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
110
|
-
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
111
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
112
|
-
return true;
|
|
113
|
-
return false;
|
|
114
|
-
});
|
|
115
|
-
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
116
|
-
([name, property]) => {
|
|
117
|
-
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
118
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
119
|
-
return true;
|
|
120
|
-
return false;
|
|
121
|
-
}
|
|
122
|
-
);
|
|
123
|
-
return computedValuesMatch && validationsMatch;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
62
|
// src/internals/helpers.js
|
|
127
63
|
import merge from "lodash/fp/merge";
|
|
128
64
|
import get from "lodash/get";
|
|
@@ -382,6 +318,76 @@ function _composeFieldCustomClosure(defaultComposeFn) {
|
|
|
382
318
|
};
|
|
383
319
|
}
|
|
384
320
|
|
|
321
|
+
// src/internals/checkIfConditionMatches.js
|
|
322
|
+
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
323
|
+
if (typeof node.if === "boolean") {
|
|
324
|
+
return node.if;
|
|
325
|
+
}
|
|
326
|
+
if (node.if.anyOf) {
|
|
327
|
+
return node.if.anyOf.some(
|
|
328
|
+
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
332
|
+
const currentProperty = node.if.properties[name];
|
|
333
|
+
const field = getField(name, formFields ?? []);
|
|
334
|
+
const isFieldsetField = field?.inputType === supportedTypes.FIELDSET;
|
|
335
|
+
const value = formValues?.[name] ?? (isFieldsetField ? {} : void 0);
|
|
336
|
+
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
337
|
+
value === null;
|
|
338
|
+
const hasIfExplicit = node.if.required?.includes(name);
|
|
339
|
+
if (hasEmptyValue && !hasIfExplicit) {
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
if (hasProperty(currentProperty, "const")) {
|
|
343
|
+
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
344
|
+
}
|
|
345
|
+
if (currentProperty.contains?.pattern) {
|
|
346
|
+
const formValue = value || [];
|
|
347
|
+
if (Array.isArray(formValue)) {
|
|
348
|
+
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
349
|
+
return (value || []).some((item) => pattern.test(item));
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (currentProperty.enum) {
|
|
353
|
+
return currentProperty.enum.includes(value);
|
|
354
|
+
}
|
|
355
|
+
if (currentProperty.properties) {
|
|
356
|
+
return checkIfConditionMatchesProperties(
|
|
357
|
+
{ if: currentProperty },
|
|
358
|
+
formValues[name],
|
|
359
|
+
getField(name, formFields).fields,
|
|
360
|
+
logic
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
return validateFieldSchema(
|
|
364
|
+
{
|
|
365
|
+
...field,
|
|
366
|
+
...currentProperty,
|
|
367
|
+
required: true
|
|
368
|
+
},
|
|
369
|
+
value
|
|
370
|
+
);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
374
|
+
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
375
|
+
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
376
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
377
|
+
return true;
|
|
378
|
+
return false;
|
|
379
|
+
});
|
|
380
|
+
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
381
|
+
([name, property]) => {
|
|
382
|
+
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
383
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
384
|
+
return true;
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
);
|
|
388
|
+
return computedValuesMatch && validationsMatch;
|
|
389
|
+
}
|
|
390
|
+
|
|
385
391
|
// src/jsonLogic.js
|
|
386
392
|
import jsonLogic from "json-logic-js";
|
|
387
393
|
|
|
@@ -1127,11 +1133,7 @@ function hasType(type, typeName) {
|
|
|
1127
1133
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1128
1134
|
}
|
|
1129
1135
|
function getField(fieldName, fields) {
|
|
1130
|
-
|
|
1131
|
-
return fields.find(({ name }) => name === fieldName);
|
|
1132
|
-
} else {
|
|
1133
|
-
return fields[fieldName];
|
|
1134
|
-
}
|
|
1136
|
+
return fields.find(({ name }) => name === fieldName);
|
|
1135
1137
|
}
|
|
1136
1138
|
function validateFieldSchema(field, value, logic) {
|
|
1137
1139
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -1345,25 +1347,6 @@ function processNode({
|
|
|
1345
1347
|
logic
|
|
1346
1348
|
});
|
|
1347
1349
|
}
|
|
1348
|
-
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1349
|
-
const values = formValues[name];
|
|
1350
|
-
if (Array.isArray(values)) {
|
|
1351
|
-
const newFields = [];
|
|
1352
|
-
const field = getField(name, formFields);
|
|
1353
|
-
values.forEach((value) => {
|
|
1354
|
-
const fields = field.fields();
|
|
1355
|
-
processNode({
|
|
1356
|
-
node: nestedNode.items,
|
|
1357
|
-
formValues: value,
|
|
1358
|
-
formFields: fields,
|
|
1359
|
-
parentID: name,
|
|
1360
|
-
logic
|
|
1361
|
-
});
|
|
1362
|
-
newFields.push(fields);
|
|
1363
|
-
});
|
|
1364
|
-
field.dynamicFields = newFields;
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
1350
|
});
|
|
1368
1351
|
}
|
|
1369
1352
|
if (node["x-jsf-logic"]) {
|
|
@@ -1735,16 +1718,6 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
|
|
|
1735
1718
|
logic
|
|
1736
1719
|
);
|
|
1737
1720
|
}
|
|
1738
|
-
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1739
|
-
fields = () => getFieldsFromJSONSchema(
|
|
1740
|
-
fieldProperties.items,
|
|
1741
|
-
{
|
|
1742
|
-
customProperties: get3(config, `customProperties.${name}.customProperties`, {}),
|
|
1743
|
-
parentID: name
|
|
1744
|
-
},
|
|
1745
|
-
logic
|
|
1746
|
-
);
|
|
1747
|
-
}
|
|
1748
1721
|
const result = {
|
|
1749
1722
|
name,
|
|
1750
1723
|
inputType,
|
|
@@ -1838,10 +1811,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
1838
1811
|
if (fieldParams.inputType === "group-array") {
|
|
1839
1812
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
1840
1813
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
1814
|
+
groupArrayItem.nameKey = groupArrayItem.name;
|
|
1841
1815
|
const customProperties = null;
|
|
1842
1816
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
1843
1817
|
return composeFn(groupArrayItem);
|
|
1844
1818
|
});
|
|
1819
|
+
fieldParams.nameKey = fieldParams.name;
|
|
1845
1820
|
fieldParams.nthFieldGroup = {
|
|
1846
1821
|
name: fieldParams.name,
|
|
1847
1822
|
label: fieldParams.label,
|
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-dev.20250310202108
|
|
5
|
+
Generated: Mon, 10 Mar 2025 20:22:24 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -11576,70 +11576,6 @@ function hasProperty(object2, propertyName) {
|
|
|
11576
11576
|
return Object.prototype.hasOwnProperty.call(object2, propertyName);
|
|
11577
11577
|
}
|
|
11578
11578
|
|
|
11579
|
-
// src/internals/checkIfConditionMatches.js
|
|
11580
|
-
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
11581
|
-
if (typeof node.if === "boolean") {
|
|
11582
|
-
return node.if;
|
|
11583
|
-
}
|
|
11584
|
-
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
11585
|
-
const currentProperty = node.if.properties[name];
|
|
11586
|
-
const value = formValues[name];
|
|
11587
|
-
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
11588
|
-
value === null;
|
|
11589
|
-
const hasIfExplicit = node.if.required?.includes(name);
|
|
11590
|
-
if (hasEmptyValue && !hasIfExplicit) {
|
|
11591
|
-
return true;
|
|
11592
|
-
}
|
|
11593
|
-
if (hasProperty(currentProperty, "const")) {
|
|
11594
|
-
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
11595
|
-
}
|
|
11596
|
-
if (currentProperty.contains?.pattern) {
|
|
11597
|
-
const formValue = value || [];
|
|
11598
|
-
if (Array.isArray(formValue)) {
|
|
11599
|
-
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
11600
|
-
return (value || []).some((item) => pattern.test(item));
|
|
11601
|
-
}
|
|
11602
|
-
}
|
|
11603
|
-
if (currentProperty.enum) {
|
|
11604
|
-
return currentProperty.enum.includes(value);
|
|
11605
|
-
}
|
|
11606
|
-
if (currentProperty.properties) {
|
|
11607
|
-
return checkIfConditionMatchesProperties(
|
|
11608
|
-
{ if: currentProperty },
|
|
11609
|
-
formValues[name],
|
|
11610
|
-
getField(name, formFields).fields,
|
|
11611
|
-
logic
|
|
11612
|
-
);
|
|
11613
|
-
}
|
|
11614
|
-
const field = getField(name, formFields);
|
|
11615
|
-
return validateFieldSchema(
|
|
11616
|
-
{
|
|
11617
|
-
...field,
|
|
11618
|
-
...currentProperty,
|
|
11619
|
-
required: true
|
|
11620
|
-
},
|
|
11621
|
-
value
|
|
11622
|
-
);
|
|
11623
|
-
});
|
|
11624
|
-
}
|
|
11625
|
-
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
11626
|
-
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property2]) => {
|
|
11627
|
-
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
11628
|
-
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11629
|
-
return true;
|
|
11630
|
-
return false;
|
|
11631
|
-
});
|
|
11632
|
-
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
11633
|
-
([name, property2]) => {
|
|
11634
|
-
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
11635
|
-
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11636
|
-
return true;
|
|
11637
|
-
return false;
|
|
11638
|
-
}
|
|
11639
|
-
);
|
|
11640
|
-
return computedValuesMatch && validationsMatch;
|
|
11641
|
-
}
|
|
11642
|
-
|
|
11643
11579
|
// src/internals/helpers.js
|
|
11644
11580
|
var import_merge = __toESM(require_merge2());
|
|
11645
11581
|
var import_get2 = __toESM(require_get());
|
|
@@ -11899,6 +11835,76 @@ function _composeFieldCustomClosure(defaultComposeFn) {
|
|
|
11899
11835
|
};
|
|
11900
11836
|
}
|
|
11901
11837
|
|
|
11838
|
+
// src/internals/checkIfConditionMatches.js
|
|
11839
|
+
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
11840
|
+
if (typeof node.if === "boolean") {
|
|
11841
|
+
return node.if;
|
|
11842
|
+
}
|
|
11843
|
+
if (node.if.anyOf) {
|
|
11844
|
+
return node.if.anyOf.some(
|
|
11845
|
+
(property2) => checkIfConditionMatchesProperties({ if: property2 }, formValues, formFields, logic)
|
|
11846
|
+
);
|
|
11847
|
+
}
|
|
11848
|
+
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
11849
|
+
const currentProperty = node.if.properties[name];
|
|
11850
|
+
const field = getField(name, formFields ?? []);
|
|
11851
|
+
const isFieldsetField = field?.inputType === supportedTypes.FIELDSET;
|
|
11852
|
+
const value = formValues?.[name] ?? (isFieldsetField ? {} : void 0);
|
|
11853
|
+
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
11854
|
+
value === null;
|
|
11855
|
+
const hasIfExplicit = node.if.required?.includes(name);
|
|
11856
|
+
if (hasEmptyValue && !hasIfExplicit) {
|
|
11857
|
+
return true;
|
|
11858
|
+
}
|
|
11859
|
+
if (hasProperty(currentProperty, "const")) {
|
|
11860
|
+
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
11861
|
+
}
|
|
11862
|
+
if (currentProperty.contains?.pattern) {
|
|
11863
|
+
const formValue = value || [];
|
|
11864
|
+
if (Array.isArray(formValue)) {
|
|
11865
|
+
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
11866
|
+
return (value || []).some((item) => pattern.test(item));
|
|
11867
|
+
}
|
|
11868
|
+
}
|
|
11869
|
+
if (currentProperty.enum) {
|
|
11870
|
+
return currentProperty.enum.includes(value);
|
|
11871
|
+
}
|
|
11872
|
+
if (currentProperty.properties) {
|
|
11873
|
+
return checkIfConditionMatchesProperties(
|
|
11874
|
+
{ if: currentProperty },
|
|
11875
|
+
formValues[name],
|
|
11876
|
+
getField(name, formFields).fields,
|
|
11877
|
+
logic
|
|
11878
|
+
);
|
|
11879
|
+
}
|
|
11880
|
+
return validateFieldSchema(
|
|
11881
|
+
{
|
|
11882
|
+
...field,
|
|
11883
|
+
...currentProperty,
|
|
11884
|
+
required: true
|
|
11885
|
+
},
|
|
11886
|
+
value
|
|
11887
|
+
);
|
|
11888
|
+
});
|
|
11889
|
+
}
|
|
11890
|
+
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
11891
|
+
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property2]) => {
|
|
11892
|
+
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
11893
|
+
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11894
|
+
return true;
|
|
11895
|
+
return false;
|
|
11896
|
+
});
|
|
11897
|
+
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
11898
|
+
([name, property2]) => {
|
|
11899
|
+
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
11900
|
+
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11901
|
+
return true;
|
|
11902
|
+
return false;
|
|
11903
|
+
}
|
|
11904
|
+
);
|
|
11905
|
+
return computedValuesMatch && validationsMatch;
|
|
11906
|
+
}
|
|
11907
|
+
|
|
11902
11908
|
// src/jsonLogic.js
|
|
11903
11909
|
var import_json_logic_js = __toESM(require_logic());
|
|
11904
11910
|
|
|
@@ -12643,11 +12649,7 @@ function hasType(type, typeName) {
|
|
|
12643
12649
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
12644
12650
|
}
|
|
12645
12651
|
function getField(fieldName, fields) {
|
|
12646
|
-
|
|
12647
|
-
return fields.find(({ name }) => name === fieldName);
|
|
12648
|
-
} else {
|
|
12649
|
-
return fields[fieldName];
|
|
12650
|
-
}
|
|
12652
|
+
return fields.find(({ name }) => name === fieldName);
|
|
12651
12653
|
}
|
|
12652
12654
|
function validateFieldSchema(field, value, logic) {
|
|
12653
12655
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -12861,25 +12863,6 @@ function processNode({
|
|
|
12861
12863
|
logic
|
|
12862
12864
|
});
|
|
12863
12865
|
}
|
|
12864
|
-
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
12865
|
-
const values2 = formValues[name];
|
|
12866
|
-
if (Array.isArray(values2)) {
|
|
12867
|
-
const newFields = [];
|
|
12868
|
-
const field = getField(name, formFields);
|
|
12869
|
-
values2.forEach((value) => {
|
|
12870
|
-
const fields = field.fields();
|
|
12871
|
-
processNode({
|
|
12872
|
-
node: nestedNode.items,
|
|
12873
|
-
formValues: value,
|
|
12874
|
-
formFields: fields,
|
|
12875
|
-
parentID: name,
|
|
12876
|
-
logic
|
|
12877
|
-
});
|
|
12878
|
-
newFields.push(fields);
|
|
12879
|
-
});
|
|
12880
|
-
field.dynamicFields = newFields;
|
|
12881
|
-
}
|
|
12882
|
-
}
|
|
12883
12866
|
});
|
|
12884
12867
|
}
|
|
12885
12868
|
if (node["x-jsf-logic"]) {
|
|
@@ -13251,16 +13234,6 @@ function buildFieldParameters(name, fieldProperties, required2 = [], config = {}
|
|
|
13251
13234
|
logic
|
|
13252
13235
|
);
|
|
13253
13236
|
}
|
|
13254
|
-
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
13255
|
-
fields = () => getFieldsFromJSONSchema(
|
|
13256
|
-
fieldProperties.items,
|
|
13257
|
-
{
|
|
13258
|
-
customProperties: (0, import_get4.default)(config, `customProperties.${name}.customProperties`, {}),
|
|
13259
|
-
parentID: name
|
|
13260
|
-
},
|
|
13261
|
-
logic
|
|
13262
|
-
);
|
|
13263
|
-
}
|
|
13264
13237
|
const result = {
|
|
13265
13238
|
name,
|
|
13266
13239
|
inputType,
|
|
@@ -13354,10 +13327,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
13354
13327
|
if (fieldParams.inputType === "group-array") {
|
|
13355
13328
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
13356
13329
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
13330
|
+
groupArrayItem.nameKey = groupArrayItem.name;
|
|
13357
13331
|
const customProperties = null;
|
|
13358
13332
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
13359
13333
|
return composeFn(groupArrayItem);
|
|
13360
13334
|
});
|
|
13335
|
+
fieldParams.nameKey = fieldParams.name;
|
|
13361
13336
|
fieldParams.nthFieldGroup = {
|
|
13362
13337
|
name: fieldParams.name,
|
|
13363
13338
|
label: fieldParams.label,
|
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-dev.20250310202108",
|
|
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",
|
|
@@ -422,233 +422,6 @@ describe('Conditional attributes updated', () => {
|
|
|
422
422
|
handleValidation({ is_full_time: 'no' });
|
|
423
423
|
expect(fields[1].visibilityCondition).toEqual(expect.any(Function));
|
|
424
424
|
});
|
|
425
|
-
|
|
426
|
-
it('Group array nested condition', () => {
|
|
427
|
-
const { fields, handleValidation } = createHeadlessForm({
|
|
428
|
-
type: 'object',
|
|
429
|
-
additionalProperties: false,
|
|
430
|
-
properties: {
|
|
431
|
-
companies: {
|
|
432
|
-
type: 'array',
|
|
433
|
-
'x-jsf-presentation': {
|
|
434
|
-
inputType: 'group-array',
|
|
435
|
-
},
|
|
436
|
-
items: {
|
|
437
|
-
type: 'object',
|
|
438
|
-
properties: {
|
|
439
|
-
company: {
|
|
440
|
-
type: 'string',
|
|
441
|
-
oneOf: [
|
|
442
|
-
{
|
|
443
|
-
title: 'A',
|
|
444
|
-
const: 'A',
|
|
445
|
-
},
|
|
446
|
-
{
|
|
447
|
-
title: 'B',
|
|
448
|
-
const: 'B',
|
|
449
|
-
},
|
|
450
|
-
],
|
|
451
|
-
'x-jsf-presentation': {
|
|
452
|
-
inputType: 'select',
|
|
453
|
-
},
|
|
454
|
-
},
|
|
455
|
-
role: {
|
|
456
|
-
title: 'Role',
|
|
457
|
-
oneOf: [],
|
|
458
|
-
'x-jsf-presentation': {
|
|
459
|
-
inputType: 'select',
|
|
460
|
-
},
|
|
461
|
-
},
|
|
462
|
-
},
|
|
463
|
-
allOf: [
|
|
464
|
-
{
|
|
465
|
-
if: {
|
|
466
|
-
properties: {
|
|
467
|
-
company: {
|
|
468
|
-
const: 'A',
|
|
469
|
-
},
|
|
470
|
-
},
|
|
471
|
-
required: ['company'],
|
|
472
|
-
},
|
|
473
|
-
then: {
|
|
474
|
-
properties: {
|
|
475
|
-
role: {
|
|
476
|
-
oneOf: [
|
|
477
|
-
{
|
|
478
|
-
title: 'adminA',
|
|
479
|
-
const: 'adminA',
|
|
480
|
-
},
|
|
481
|
-
{
|
|
482
|
-
title: 'userA',
|
|
483
|
-
const: 'userA',
|
|
484
|
-
},
|
|
485
|
-
],
|
|
486
|
-
'x-jsf-presentation': {
|
|
487
|
-
inputType: 'select',
|
|
488
|
-
},
|
|
489
|
-
},
|
|
490
|
-
},
|
|
491
|
-
required: ['role'],
|
|
492
|
-
},
|
|
493
|
-
},
|
|
494
|
-
{
|
|
495
|
-
if: {
|
|
496
|
-
properties: {
|
|
497
|
-
company: {
|
|
498
|
-
const: 'B',
|
|
499
|
-
},
|
|
500
|
-
},
|
|
501
|
-
required: ['company'],
|
|
502
|
-
},
|
|
503
|
-
then: {
|
|
504
|
-
properties: {
|
|
505
|
-
role: {
|
|
506
|
-
oneOf: [
|
|
507
|
-
{
|
|
508
|
-
title: 'adminB',
|
|
509
|
-
const: 'adminB',
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
title: 'userB',
|
|
513
|
-
const: 'userB',
|
|
514
|
-
},
|
|
515
|
-
],
|
|
516
|
-
'x-jsf-presentation': {
|
|
517
|
-
inputType: 'select',
|
|
518
|
-
},
|
|
519
|
-
},
|
|
520
|
-
},
|
|
521
|
-
required: ['role'],
|
|
522
|
-
},
|
|
523
|
-
},
|
|
524
|
-
],
|
|
525
|
-
required: ['company', 'role'],
|
|
526
|
-
},
|
|
527
|
-
},
|
|
528
|
-
},
|
|
529
|
-
required: ['companies'],
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
handleValidation({ companies: [{ company: 'A' }, { company: 'B' }] });
|
|
533
|
-
expect(fields[0].dynamicFields[0][1].options).toEqual([
|
|
534
|
-
{ label: 'adminA', value: 'adminA' },
|
|
535
|
-
{ label: 'userA', value: 'userA' },
|
|
536
|
-
]);
|
|
537
|
-
expect(fields[0].dynamicFields[1][1].options).toEqual([
|
|
538
|
-
{ label: 'adminB', value: 'adminB' },
|
|
539
|
-
{ label: 'userB', value: 'userB' },
|
|
540
|
-
]);
|
|
541
|
-
handleValidation({ companies: [] });
|
|
542
|
-
expect(fields[0].dynamicFields).toEqual([]);
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
it('select multiple conditions', () => {
|
|
546
|
-
const { fields, handleValidation } = createHeadlessForm({
|
|
547
|
-
type: 'object',
|
|
548
|
-
additionalProperties: false,
|
|
549
|
-
properties: {
|
|
550
|
-
company: {
|
|
551
|
-
title: 'Select Company',
|
|
552
|
-
type: 'string',
|
|
553
|
-
description: 'Choose a company',
|
|
554
|
-
oneOf: [
|
|
555
|
-
{
|
|
556
|
-
title: 'A',
|
|
557
|
-
const: 'A',
|
|
558
|
-
},
|
|
559
|
-
{
|
|
560
|
-
title: 'B',
|
|
561
|
-
const: 'B',
|
|
562
|
-
},
|
|
563
|
-
],
|
|
564
|
-
'x-jsf-presentation': {
|
|
565
|
-
inputType: 'select',
|
|
566
|
-
},
|
|
567
|
-
},
|
|
568
|
-
role: {
|
|
569
|
-
title: 'Role',
|
|
570
|
-
oneOf: [],
|
|
571
|
-
'x-jsf-presentation': {
|
|
572
|
-
inputType: 'select',
|
|
573
|
-
},
|
|
574
|
-
},
|
|
575
|
-
},
|
|
576
|
-
allOf: [
|
|
577
|
-
{
|
|
578
|
-
if: {
|
|
579
|
-
properties: {
|
|
580
|
-
company: {
|
|
581
|
-
const: 'A',
|
|
582
|
-
},
|
|
583
|
-
},
|
|
584
|
-
required: ['company'],
|
|
585
|
-
},
|
|
586
|
-
then: {
|
|
587
|
-
properties: {
|
|
588
|
-
role: {
|
|
589
|
-
oneOf: [
|
|
590
|
-
{
|
|
591
|
-
title: 'adminA',
|
|
592
|
-
const: 'adminA',
|
|
593
|
-
},
|
|
594
|
-
{
|
|
595
|
-
title: 'userA',
|
|
596
|
-
const: 'userA',
|
|
597
|
-
},
|
|
598
|
-
],
|
|
599
|
-
'x-jsf-presentation': {
|
|
600
|
-
inputType: 'select',
|
|
601
|
-
},
|
|
602
|
-
},
|
|
603
|
-
},
|
|
604
|
-
required: ['role'],
|
|
605
|
-
},
|
|
606
|
-
},
|
|
607
|
-
{
|
|
608
|
-
if: {
|
|
609
|
-
properties: {
|
|
610
|
-
company: {
|
|
611
|
-
const: 'B',
|
|
612
|
-
},
|
|
613
|
-
},
|
|
614
|
-
required: ['company'],
|
|
615
|
-
},
|
|
616
|
-
then: {
|
|
617
|
-
properties: {
|
|
618
|
-
role: {
|
|
619
|
-
oneOf: [
|
|
620
|
-
{
|
|
621
|
-
title: 'adminB',
|
|
622
|
-
const: 'adminB',
|
|
623
|
-
},
|
|
624
|
-
{
|
|
625
|
-
title: 'userB',
|
|
626
|
-
const: 'userB',
|
|
627
|
-
},
|
|
628
|
-
],
|
|
629
|
-
'x-jsf-presentation': {
|
|
630
|
-
inputType: 'select',
|
|
631
|
-
},
|
|
632
|
-
},
|
|
633
|
-
},
|
|
634
|
-
required: ['role'],
|
|
635
|
-
},
|
|
636
|
-
},
|
|
637
|
-
],
|
|
638
|
-
required: ['company', 'role'],
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
handleValidation({ company: 'A' });
|
|
642
|
-
expect(fields[1].options).toEqual([
|
|
643
|
-
{ label: 'adminA', value: 'adminA' },
|
|
644
|
-
{ label: 'userA', value: 'userA' },
|
|
645
|
-
]);
|
|
646
|
-
handleValidation({ company: 'B' });
|
|
647
|
-
expect(fields[1].options).toEqual([
|
|
648
|
-
{ label: 'adminB', value: 'adminB' },
|
|
649
|
-
{ label: 'userB', value: 'userB' },
|
|
650
|
-
]);
|
|
651
|
-
});
|
|
652
425
|
});
|
|
653
426
|
|
|
654
427
|
describe('Conditional with a minimum value check', () => {
|
|
@@ -775,6 +548,122 @@ describe('Conditional with literal booleans', () => {
|
|
|
775
548
|
});
|
|
776
549
|
});
|
|
777
550
|
|
|
551
|
+
describe('Conditional with anyOf', () => {
|
|
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: [
|
|
561
|
+
{
|
|
562
|
+
if: {
|
|
563
|
+
anyOf: [
|
|
564
|
+
{ properties: { field_a: { const: '1' } }, required: ['field_a'] },
|
|
565
|
+
{ properties: { field_b: { const: '2' } }, required: ['field_b'] },
|
|
566
|
+
],
|
|
567
|
+
},
|
|
568
|
+
then: {
|
|
569
|
+
required: ['field_c'],
|
|
570
|
+
},
|
|
571
|
+
else: {
|
|
572
|
+
properties: {
|
|
573
|
+
field_c: false,
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
],
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
it('handles true case', () => {
|
|
581
|
+
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
582
|
+
|
|
583
|
+
expect(fields[2].isVisible).toBe(false);
|
|
584
|
+
expect(handleValidation({ field_a: 'x', field_b: '2' }).formErrors).toEqual({
|
|
585
|
+
field_c: 'Required field',
|
|
586
|
+
});
|
|
587
|
+
expect(fields[2].isVisible).toBe(true);
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
it('handles false case', () => {
|
|
591
|
+
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
592
|
+
|
|
593
|
+
expect(fields[2].isVisible).toBe(false);
|
|
594
|
+
expect(handleValidation({ field_a: 'x', field_b: 'x' }).formErrors).toBeUndefined();
|
|
595
|
+
expect(fields[2].isVisible).toBe(false);
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
describe('Conditional with fieldset', () => {
|
|
600
|
+
const schema = {
|
|
601
|
+
additionalProperties: false,
|
|
602
|
+
type: 'object',
|
|
603
|
+
properties: {
|
|
604
|
+
field_a: {
|
|
605
|
+
type: 'object',
|
|
606
|
+
properties: {
|
|
607
|
+
min: { type: 'number' },
|
|
608
|
+
max: { type: 'number' },
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
field_b: { type: 'string' },
|
|
612
|
+
},
|
|
613
|
+
allOf: [
|
|
614
|
+
{
|
|
615
|
+
if: {
|
|
616
|
+
properties: {
|
|
617
|
+
field_a: {
|
|
618
|
+
properties: {
|
|
619
|
+
min: {
|
|
620
|
+
minimum: 10,
|
|
621
|
+
},
|
|
622
|
+
},
|
|
623
|
+
required: ['min'],
|
|
624
|
+
},
|
|
625
|
+
},
|
|
626
|
+
required: ['field_a'],
|
|
627
|
+
},
|
|
628
|
+
then: {
|
|
629
|
+
required: ['field_b'],
|
|
630
|
+
},
|
|
631
|
+
else: {
|
|
632
|
+
properties: {
|
|
633
|
+
field_b: false,
|
|
634
|
+
},
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
],
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
it('handles true case', () => {
|
|
641
|
+
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
642
|
+
|
|
643
|
+
expect(fields[1].isVisible).toBe(false);
|
|
644
|
+
expect(handleValidation({ field_a: { min: 100 } }).formErrors).toEqual({
|
|
645
|
+
field_b: 'Required field',
|
|
646
|
+
});
|
|
647
|
+
expect(fields[1].isVisible).toBe(true);
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
it('handles false case', () => {
|
|
651
|
+
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
652
|
+
|
|
653
|
+
expect(fields[1].isVisible).toBe(false);
|
|
654
|
+
expect(handleValidation({ field_a: { min: 1 } }).formErrors).toBeUndefined();
|
|
655
|
+
expect(fields[1].isVisible).toBe(false);
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
it('handles undefined fieldset case', () => {
|
|
659
|
+
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
660
|
+
|
|
661
|
+
expect(fields[1].isVisible).toBe(false);
|
|
662
|
+
expect(handleValidation({}).formErrors).toBeUndefined();
|
|
663
|
+
expect(fields[1].isVisible).toBe(false);
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
|
|
778
667
|
describe('Conditionals - bugs and code-smells', () => {
|
|
779
668
|
// Why do we have these bugs?
|
|
780
669
|
// To be honest we never realized it much later later.
|
|
@@ -63,7 +63,6 @@ import {
|
|
|
63
63
|
schemaForErrorMessageSpecificity,
|
|
64
64
|
jsfConfigForErrorMessageSpecificity,
|
|
65
65
|
schemaInputTypeFile,
|
|
66
|
-
nestedGroupArrayForm,
|
|
67
66
|
} from './helpers';
|
|
68
67
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
69
68
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -1605,6 +1604,7 @@ describe('createHeadlessForm', () => {
|
|
|
1605
1604
|
type: 'text',
|
|
1606
1605
|
description: 'Enter your child’s full name',
|
|
1607
1606
|
maxLength: 255,
|
|
1607
|
+
nameKey: 'full_name',
|
|
1608
1608
|
label: 'Child Full Name',
|
|
1609
1609
|
name: 'full_name',
|
|
1610
1610
|
required: true,
|
|
@@ -1616,6 +1616,7 @@ describe('createHeadlessForm', () => {
|
|
|
1616
1616
|
required: true,
|
|
1617
1617
|
description: 'Enter your child’s date of birth',
|
|
1618
1618
|
maxLength: 255,
|
|
1619
|
+
nameKey: 'birthdate',
|
|
1619
1620
|
},
|
|
1620
1621
|
{
|
|
1621
1622
|
type: 'radio',
|
|
@@ -1634,6 +1635,7 @@ describe('createHeadlessForm', () => {
|
|
|
1634
1635
|
required: true,
|
|
1635
1636
|
description:
|
|
1636
1637
|
'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
|
|
1638
|
+
nameKey: 'sex',
|
|
1637
1639
|
},
|
|
1638
1640
|
]);
|
|
1639
1641
|
});
|
|
@@ -1735,63 +1737,6 @@ describe('createHeadlessForm', () => {
|
|
|
1735
1737
|
});
|
|
1736
1738
|
});
|
|
1737
1739
|
|
|
1738
|
-
it('nested "group-array" fields', () => {
|
|
1739
|
-
const result = createHeadlessForm({
|
|
1740
|
-
properties: {
|
|
1741
|
-
nestedGroupArray: nestedGroupArrayForm,
|
|
1742
|
-
},
|
|
1743
|
-
});
|
|
1744
|
-
|
|
1745
|
-
expect(result.fields[0]).toMatchObject({
|
|
1746
|
-
label: 'Parent object',
|
|
1747
|
-
name: 'nestedGroupArray',
|
|
1748
|
-
required: false,
|
|
1749
|
-
type: 'group-array',
|
|
1750
|
-
inputType: 'group-array',
|
|
1751
|
-
jsonType: 'array',
|
|
1752
|
-
fields: expect.any(Function),
|
|
1753
|
-
});
|
|
1754
|
-
|
|
1755
|
-
expect(result.fields[0].fields()).toMatchObject([
|
|
1756
|
-
{
|
|
1757
|
-
type: 'text',
|
|
1758
|
-
description: 'Simple text field',
|
|
1759
|
-
maxLength: 255,
|
|
1760
|
-
label: 'Outer Field',
|
|
1761
|
-
name: 'notNested',
|
|
1762
|
-
required: true,
|
|
1763
|
-
},
|
|
1764
|
-
{
|
|
1765
|
-
label: 'Nested group-array',
|
|
1766
|
-
name: 'nested',
|
|
1767
|
-
required: true,
|
|
1768
|
-
type: 'group-array',
|
|
1769
|
-
inputType: 'group-array',
|
|
1770
|
-
jsonType: 'array',
|
|
1771
|
-
fields: expect.any(Function),
|
|
1772
|
-
},
|
|
1773
|
-
]);
|
|
1774
|
-
|
|
1775
|
-
expect(result.fields[0].fields()[1].fields()).toMatchObject([
|
|
1776
|
-
{
|
|
1777
|
-
type: 'text',
|
|
1778
|
-
description: 'First nested text field',
|
|
1779
|
-
maxLength: 255,
|
|
1780
|
-
label: 'Inner Field 1',
|
|
1781
|
-
name: 'nestedField1',
|
|
1782
|
-
required: true,
|
|
1783
|
-
},
|
|
1784
|
-
{
|
|
1785
|
-
type: 'text',
|
|
1786
|
-
description: 'Second nested text field',
|
|
1787
|
-
maxLength: 255,
|
|
1788
|
-
label: 'Inner Field 2',
|
|
1789
|
-
name: 'nestedField2',
|
|
1790
|
-
required: true,
|
|
1791
|
-
},
|
|
1792
|
-
]);
|
|
1793
|
-
});
|
|
1794
|
-
|
|
1795
1740
|
it('can pass custom field attributes', () => {
|
|
1796
1741
|
const result = createHeadlessForm(
|
|
1797
1742
|
{
|
package/src/tests/helpers.js
CHANGED
|
@@ -2327,59 +2327,3 @@ export const schemaWithCustomValidationsAndConditionals = {
|
|
|
2327
2327
|
},
|
|
2328
2328
|
],
|
|
2329
2329
|
};
|
|
2330
|
-
|
|
2331
|
-
export const nestedGroupArrayForm = {
|
|
2332
|
-
items: {
|
|
2333
|
-
properties: {
|
|
2334
|
-
notNested: {
|
|
2335
|
-
description: 'Simple text field',
|
|
2336
|
-
'x-jsf-presentation': {
|
|
2337
|
-
inputType: 'text',
|
|
2338
|
-
},
|
|
2339
|
-
title: 'Outer Field',
|
|
2340
|
-
type: 'string',
|
|
2341
|
-
maxLength: 255,
|
|
2342
|
-
},
|
|
2343
|
-
nested: {
|
|
2344
|
-
items: {
|
|
2345
|
-
properties: {
|
|
2346
|
-
nestedField1: {
|
|
2347
|
-
description: 'First nested text field',
|
|
2348
|
-
'x-jsf-presentation': {
|
|
2349
|
-
inputType: 'text',
|
|
2350
|
-
},
|
|
2351
|
-
title: 'Inner Field 1',
|
|
2352
|
-
type: 'string',
|
|
2353
|
-
maxLength: 255,
|
|
2354
|
-
},
|
|
2355
|
-
nestedField2: {
|
|
2356
|
-
description: 'Second nested text field',
|
|
2357
|
-
'x-jsf-presentation': {
|
|
2358
|
-
inputType: 'text',
|
|
2359
|
-
},
|
|
2360
|
-
title: 'Inner Field 2',
|
|
2361
|
-
type: 'string',
|
|
2362
|
-
maxLength: 255,
|
|
2363
|
-
},
|
|
2364
|
-
},
|
|
2365
|
-
'x-jsf-order': ['nestedField1', 'nestedField2'],
|
|
2366
|
-
required: ['nestedField1', 'nestedField2'],
|
|
2367
|
-
type: 'object',
|
|
2368
|
-
},
|
|
2369
|
-
'x-jsf-presentation': {
|
|
2370
|
-
inputType: 'group-array',
|
|
2371
|
-
},
|
|
2372
|
-
title: 'Nested group-array',
|
|
2373
|
-
type: 'array',
|
|
2374
|
-
},
|
|
2375
|
-
},
|
|
2376
|
-
'x-jsf-order': ['notNested', 'nested'],
|
|
2377
|
-
required: ['notNested', 'nested'],
|
|
2378
|
-
type: 'object',
|
|
2379
|
-
},
|
|
2380
|
-
'x-jsf-presentation': {
|
|
2381
|
-
inputType: 'group-array',
|
|
2382
|
-
},
|
|
2383
|
-
title: 'Parent object',
|
|
2384
|
-
type: 'array',
|
|
2385
|
-
};
|