@remoteoss/json-schema-form 0.11.14-beta.0 → 0.11.14-dev.20250514100552
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 +0 -11
- package/dist/index.cjs +72 -71
- package/dist/index.js +72 -71
- package/dist/standalone.js +72 -71
- package/package.json +1 -1
- package/src/tests/conditions.test.js +68 -0
- package/src/tests/helpers.js +11 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
#### 0.11.14-beta.0 (2025-05-14)
|
|
2
|
-
|
|
3
|
-
##### Chores
|
|
4
|
-
|
|
5
|
-
* **next:** Type JSONSchema enum as unknown for better type safety ([#184](https://github.com/remoteoss/json-schema-form/pull/184)) ([e745444c](https://github.com/remoteoss/json-schema-form/commit/e745444c112337c22def693a924eae49f575c14d))
|
|
6
|
-
* **scripts:** Reminder to publish GitHub release ([#183](https://github.com/remoteoss/json-schema-form/pull/183)) ([adfa8c14](https://github.com/remoteoss/json-schema-form/commit/adfa8c14ca118b1012642f39c8388cf2ba1614c9))
|
|
7
|
-
|
|
8
|
-
##### New Features
|
|
9
|
-
|
|
10
|
-
* **next:** group-array field support ([#177](https://github.com/remoteoss/json-schema-form/pull/177)) ([e32f69b7](https://github.com/remoteoss/json-schema-form/commit/e32f69b771ab245583c3f4e167ab67b8f36b9a3f))
|
|
11
|
-
|
|
12
1
|
#### 0.11.13-beta.0 (2025-05-05)
|
|
13
2
|
|
|
14
3
|
##### 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.14-
|
|
5
|
-
Generated: Wed, 14 May 2025
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.14-dev.20250514100552
|
|
5
|
+
Generated: Wed, 14 May 2025 10:06:23 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -97,75 +97,6 @@ function hasProperty(object2, propertyName) {
|
|
|
97
97
|
return Object.prototype.hasOwnProperty.call(object2, propertyName);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
// src/internals/checkIfConditionMatches.js
|
|
101
|
-
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
102
|
-
if (typeof node.if === "boolean") {
|
|
103
|
-
return node.if;
|
|
104
|
-
}
|
|
105
|
-
if (node.if.anyOf) {
|
|
106
|
-
return node.if.anyOf.some(
|
|
107
|
-
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
111
|
-
const currentProperty = node.if.properties[name];
|
|
112
|
-
const value = formValues[name];
|
|
113
|
-
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
114
|
-
value === null;
|
|
115
|
-
const hasIfExplicit = node.if.required?.includes(name);
|
|
116
|
-
if (hasEmptyValue && !hasIfExplicit) {
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
if (hasProperty(currentProperty, "const")) {
|
|
120
|
-
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
121
|
-
}
|
|
122
|
-
if (currentProperty.contains?.pattern) {
|
|
123
|
-
const formValue = value || [];
|
|
124
|
-
if (Array.isArray(formValue)) {
|
|
125
|
-
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
126
|
-
return (value || []).some((item) => pattern.test(item));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (currentProperty.enum) {
|
|
130
|
-
return currentProperty.enum.includes(value);
|
|
131
|
-
}
|
|
132
|
-
if (currentProperty.properties) {
|
|
133
|
-
return checkIfConditionMatchesProperties(
|
|
134
|
-
{ if: currentProperty },
|
|
135
|
-
formValues[name],
|
|
136
|
-
getField(name, formFields).fields,
|
|
137
|
-
logic
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
const field = getField(name, formFields);
|
|
141
|
-
return validateFieldSchema(
|
|
142
|
-
{
|
|
143
|
-
...field,
|
|
144
|
-
...currentProperty,
|
|
145
|
-
required: true
|
|
146
|
-
},
|
|
147
|
-
value
|
|
148
|
-
);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
152
|
-
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
153
|
-
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
154
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
155
|
-
return true;
|
|
156
|
-
return false;
|
|
157
|
-
});
|
|
158
|
-
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
159
|
-
([name, property]) => {
|
|
160
|
-
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
161
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
162
|
-
return true;
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
);
|
|
166
|
-
return computedValuesMatch && validationsMatch;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
100
|
// src/internals/helpers.js
|
|
170
101
|
var import_merge = __toESM(require("lodash/fp/merge"));
|
|
171
102
|
var import_get = __toESM(require("lodash/get"));
|
|
@@ -425,6 +356,76 @@ function _composeFieldCustomClosure(defaultComposeFn) {
|
|
|
425
356
|
};
|
|
426
357
|
}
|
|
427
358
|
|
|
359
|
+
// src/internals/checkIfConditionMatches.js
|
|
360
|
+
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
361
|
+
if (typeof node.if === "boolean") {
|
|
362
|
+
return node.if;
|
|
363
|
+
}
|
|
364
|
+
if (node.if.anyOf) {
|
|
365
|
+
return node.if.anyOf.some(
|
|
366
|
+
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
370
|
+
const currentProperty = node.if.properties[name];
|
|
371
|
+
const field = getField(name, formFields ?? []);
|
|
372
|
+
const isFieldsetField = field?.inputType === supportedTypes.FIELDSET;
|
|
373
|
+
const value = formValues?.[name] ?? (isFieldsetField ? {} : void 0);
|
|
374
|
+
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
375
|
+
value === null;
|
|
376
|
+
const hasIfExplicit = node.if.required?.includes(name);
|
|
377
|
+
if (hasEmptyValue && !hasIfExplicit) {
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
if (hasProperty(currentProperty, "const")) {
|
|
381
|
+
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
382
|
+
}
|
|
383
|
+
if (currentProperty.contains?.pattern) {
|
|
384
|
+
const formValue = value || [];
|
|
385
|
+
if (Array.isArray(formValue)) {
|
|
386
|
+
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
387
|
+
return (value || []).some((item) => pattern.test(item));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (currentProperty.enum) {
|
|
391
|
+
return currentProperty.enum.includes(value);
|
|
392
|
+
}
|
|
393
|
+
if (currentProperty.properties) {
|
|
394
|
+
return checkIfConditionMatchesProperties(
|
|
395
|
+
{ if: currentProperty },
|
|
396
|
+
formValues[name],
|
|
397
|
+
getField(name, formFields).fields,
|
|
398
|
+
logic
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
return validateFieldSchema(
|
|
402
|
+
{
|
|
403
|
+
...field,
|
|
404
|
+
...currentProperty,
|
|
405
|
+
required: true
|
|
406
|
+
},
|
|
407
|
+
value
|
|
408
|
+
);
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
412
|
+
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
413
|
+
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
414
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
415
|
+
return true;
|
|
416
|
+
return false;
|
|
417
|
+
});
|
|
418
|
+
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
419
|
+
([name, property]) => {
|
|
420
|
+
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
421
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
422
|
+
return true;
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
);
|
|
426
|
+
return computedValuesMatch && validationsMatch;
|
|
427
|
+
}
|
|
428
|
+
|
|
428
429
|
// src/jsonLogic.js
|
|
429
430
|
var import_json_logic_js = __toESM(require("json-logic-js"));
|
|
430
431
|
|
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.14-
|
|
5
|
-
Generated: Wed, 14 May 2025
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.14-dev.20250514100552
|
|
5
|
+
Generated: Wed, 14 May 2025 10:06:23 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -60,75 +60,6 @@ function hasProperty(object2, propertyName) {
|
|
|
60
60
|
return Object.prototype.hasOwnProperty.call(object2, propertyName);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
// src/internals/checkIfConditionMatches.js
|
|
64
|
-
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
65
|
-
if (typeof node.if === "boolean") {
|
|
66
|
-
return node.if;
|
|
67
|
-
}
|
|
68
|
-
if (node.if.anyOf) {
|
|
69
|
-
return node.if.anyOf.some(
|
|
70
|
-
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
74
|
-
const currentProperty = node.if.properties[name];
|
|
75
|
-
const value = formValues[name];
|
|
76
|
-
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
77
|
-
value === null;
|
|
78
|
-
const hasIfExplicit = node.if.required?.includes(name);
|
|
79
|
-
if (hasEmptyValue && !hasIfExplicit) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
if (hasProperty(currentProperty, "const")) {
|
|
83
|
-
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
84
|
-
}
|
|
85
|
-
if (currentProperty.contains?.pattern) {
|
|
86
|
-
const formValue = value || [];
|
|
87
|
-
if (Array.isArray(formValue)) {
|
|
88
|
-
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
89
|
-
return (value || []).some((item) => pattern.test(item));
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (currentProperty.enum) {
|
|
93
|
-
return currentProperty.enum.includes(value);
|
|
94
|
-
}
|
|
95
|
-
if (currentProperty.properties) {
|
|
96
|
-
return checkIfConditionMatchesProperties(
|
|
97
|
-
{ if: currentProperty },
|
|
98
|
-
formValues[name],
|
|
99
|
-
getField(name, formFields).fields,
|
|
100
|
-
logic
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
const field = getField(name, formFields);
|
|
104
|
-
return validateFieldSchema(
|
|
105
|
-
{
|
|
106
|
-
...field,
|
|
107
|
-
...currentProperty,
|
|
108
|
-
required: true
|
|
109
|
-
},
|
|
110
|
-
value
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
115
|
-
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
116
|
-
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
117
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
118
|
-
return true;
|
|
119
|
-
return false;
|
|
120
|
-
});
|
|
121
|
-
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
122
|
-
([name, property]) => {
|
|
123
|
-
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
124
|
-
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
125
|
-
return true;
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
);
|
|
129
|
-
return computedValuesMatch && validationsMatch;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
63
|
// src/internals/helpers.js
|
|
133
64
|
import merge from "lodash/fp/merge";
|
|
134
65
|
import get from "lodash/get";
|
|
@@ -388,6 +319,76 @@ function _composeFieldCustomClosure(defaultComposeFn) {
|
|
|
388
319
|
};
|
|
389
320
|
}
|
|
390
321
|
|
|
322
|
+
// src/internals/checkIfConditionMatches.js
|
|
323
|
+
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
324
|
+
if (typeof node.if === "boolean") {
|
|
325
|
+
return node.if;
|
|
326
|
+
}
|
|
327
|
+
if (node.if.anyOf) {
|
|
328
|
+
return node.if.anyOf.some(
|
|
329
|
+
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
333
|
+
const currentProperty = node.if.properties[name];
|
|
334
|
+
const field = getField(name, formFields ?? []);
|
|
335
|
+
const isFieldsetField = field?.inputType === supportedTypes.FIELDSET;
|
|
336
|
+
const value = formValues?.[name] ?? (isFieldsetField ? {} : void 0);
|
|
337
|
+
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
338
|
+
value === null;
|
|
339
|
+
const hasIfExplicit = node.if.required?.includes(name);
|
|
340
|
+
if (hasEmptyValue && !hasIfExplicit) {
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
if (hasProperty(currentProperty, "const")) {
|
|
344
|
+
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
345
|
+
}
|
|
346
|
+
if (currentProperty.contains?.pattern) {
|
|
347
|
+
const formValue = value || [];
|
|
348
|
+
if (Array.isArray(formValue)) {
|
|
349
|
+
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
350
|
+
return (value || []).some((item) => pattern.test(item));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (currentProperty.enum) {
|
|
354
|
+
return currentProperty.enum.includes(value);
|
|
355
|
+
}
|
|
356
|
+
if (currentProperty.properties) {
|
|
357
|
+
return checkIfConditionMatchesProperties(
|
|
358
|
+
{ if: currentProperty },
|
|
359
|
+
formValues[name],
|
|
360
|
+
getField(name, formFields).fields,
|
|
361
|
+
logic
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
return validateFieldSchema(
|
|
365
|
+
{
|
|
366
|
+
...field,
|
|
367
|
+
...currentProperty,
|
|
368
|
+
required: true
|
|
369
|
+
},
|
|
370
|
+
value
|
|
371
|
+
);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
375
|
+
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property]) => {
|
|
376
|
+
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
377
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
378
|
+
return true;
|
|
379
|
+
return false;
|
|
380
|
+
});
|
|
381
|
+
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
382
|
+
([name, property]) => {
|
|
383
|
+
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
384
|
+
if (Object.hasOwn(property, "const") && currentValue === property.const)
|
|
385
|
+
return true;
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
return computedValuesMatch && validationsMatch;
|
|
390
|
+
}
|
|
391
|
+
|
|
391
392
|
// src/jsonLogic.js
|
|
392
393
|
import jsonLogic from "json-logic-js";
|
|
393
394
|
|
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.14-
|
|
5
|
-
Generated: Wed, 14 May 2025
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.14-dev.20250514100552
|
|
5
|
+
Generated: Wed, 14 May 2025 10:06:23 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -11577,75 +11577,6 @@ function hasProperty(object2, propertyName) {
|
|
|
11577
11577
|
return Object.prototype.hasOwnProperty.call(object2, propertyName);
|
|
11578
11578
|
}
|
|
11579
11579
|
|
|
11580
|
-
// src/internals/checkIfConditionMatches.js
|
|
11581
|
-
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
11582
|
-
if (typeof node.if === "boolean") {
|
|
11583
|
-
return node.if;
|
|
11584
|
-
}
|
|
11585
|
-
if (node.if.anyOf) {
|
|
11586
|
-
return node.if.anyOf.some(
|
|
11587
|
-
(property2) => checkIfConditionMatchesProperties({ if: property2 }, formValues, formFields, logic)
|
|
11588
|
-
);
|
|
11589
|
-
}
|
|
11590
|
-
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
11591
|
-
const currentProperty = node.if.properties[name];
|
|
11592
|
-
const value = formValues[name];
|
|
11593
|
-
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
11594
|
-
value === null;
|
|
11595
|
-
const hasIfExplicit = node.if.required?.includes(name);
|
|
11596
|
-
if (hasEmptyValue && !hasIfExplicit) {
|
|
11597
|
-
return true;
|
|
11598
|
-
}
|
|
11599
|
-
if (hasProperty(currentProperty, "const")) {
|
|
11600
|
-
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
11601
|
-
}
|
|
11602
|
-
if (currentProperty.contains?.pattern) {
|
|
11603
|
-
const formValue = value || [];
|
|
11604
|
-
if (Array.isArray(formValue)) {
|
|
11605
|
-
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
11606
|
-
return (value || []).some((item) => pattern.test(item));
|
|
11607
|
-
}
|
|
11608
|
-
}
|
|
11609
|
-
if (currentProperty.enum) {
|
|
11610
|
-
return currentProperty.enum.includes(value);
|
|
11611
|
-
}
|
|
11612
|
-
if (currentProperty.properties) {
|
|
11613
|
-
return checkIfConditionMatchesProperties(
|
|
11614
|
-
{ if: currentProperty },
|
|
11615
|
-
formValues[name],
|
|
11616
|
-
getField(name, formFields).fields,
|
|
11617
|
-
logic
|
|
11618
|
-
);
|
|
11619
|
-
}
|
|
11620
|
-
const field = getField(name, formFields);
|
|
11621
|
-
return validateFieldSchema(
|
|
11622
|
-
{
|
|
11623
|
-
...field,
|
|
11624
|
-
...currentProperty,
|
|
11625
|
-
required: true
|
|
11626
|
-
},
|
|
11627
|
-
value
|
|
11628
|
-
);
|
|
11629
|
-
});
|
|
11630
|
-
}
|
|
11631
|
-
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
11632
|
-
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property2]) => {
|
|
11633
|
-
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
11634
|
-
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11635
|
-
return true;
|
|
11636
|
-
return false;
|
|
11637
|
-
});
|
|
11638
|
-
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
11639
|
-
([name, property2]) => {
|
|
11640
|
-
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
11641
|
-
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11642
|
-
return true;
|
|
11643
|
-
return false;
|
|
11644
|
-
}
|
|
11645
|
-
);
|
|
11646
|
-
return computedValuesMatch && validationsMatch;
|
|
11647
|
-
}
|
|
11648
|
-
|
|
11649
11580
|
// src/internals/helpers.js
|
|
11650
11581
|
var import_merge = __toESM(require_merge2());
|
|
11651
11582
|
var import_get2 = __toESM(require_get());
|
|
@@ -11905,6 +11836,76 @@ function _composeFieldCustomClosure(defaultComposeFn) {
|
|
|
11905
11836
|
};
|
|
11906
11837
|
}
|
|
11907
11838
|
|
|
11839
|
+
// src/internals/checkIfConditionMatches.js
|
|
11840
|
+
function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
|
|
11841
|
+
if (typeof node.if === "boolean") {
|
|
11842
|
+
return node.if;
|
|
11843
|
+
}
|
|
11844
|
+
if (node.if.anyOf) {
|
|
11845
|
+
return node.if.anyOf.some(
|
|
11846
|
+
(property2) => checkIfConditionMatchesProperties({ if: property2 }, formValues, formFields, logic)
|
|
11847
|
+
);
|
|
11848
|
+
}
|
|
11849
|
+
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
11850
|
+
const currentProperty = node.if.properties[name];
|
|
11851
|
+
const field = getField(name, formFields ?? []);
|
|
11852
|
+
const isFieldsetField = field?.inputType === supportedTypes.FIELDSET;
|
|
11853
|
+
const value = formValues?.[name] ?? (isFieldsetField ? {} : void 0);
|
|
11854
|
+
const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
|
|
11855
|
+
value === null;
|
|
11856
|
+
const hasIfExplicit = node.if.required?.includes(name);
|
|
11857
|
+
if (hasEmptyValue && !hasIfExplicit) {
|
|
11858
|
+
return true;
|
|
11859
|
+
}
|
|
11860
|
+
if (hasProperty(currentProperty, "const")) {
|
|
11861
|
+
return compareFormValueWithSchemaValue(value, currentProperty.const);
|
|
11862
|
+
}
|
|
11863
|
+
if (currentProperty.contains?.pattern) {
|
|
11864
|
+
const formValue = value || [];
|
|
11865
|
+
if (Array.isArray(formValue)) {
|
|
11866
|
+
const pattern = new RegExp(currentProperty.contains.pattern);
|
|
11867
|
+
return (value || []).some((item) => pattern.test(item));
|
|
11868
|
+
}
|
|
11869
|
+
}
|
|
11870
|
+
if (currentProperty.enum) {
|
|
11871
|
+
return currentProperty.enum.includes(value);
|
|
11872
|
+
}
|
|
11873
|
+
if (currentProperty.properties) {
|
|
11874
|
+
return checkIfConditionMatchesProperties(
|
|
11875
|
+
{ if: currentProperty },
|
|
11876
|
+
formValues[name],
|
|
11877
|
+
getField(name, formFields).fields,
|
|
11878
|
+
logic
|
|
11879
|
+
);
|
|
11880
|
+
}
|
|
11881
|
+
return validateFieldSchema(
|
|
11882
|
+
{
|
|
11883
|
+
...field,
|
|
11884
|
+
...currentProperty,
|
|
11885
|
+
required: true
|
|
11886
|
+
},
|
|
11887
|
+
value
|
|
11888
|
+
);
|
|
11889
|
+
});
|
|
11890
|
+
}
|
|
11891
|
+
function checkIfMatchesValidationsAndComputedValues(node, formValues, logic, parentID) {
|
|
11892
|
+
const validationsMatch = Object.entries(node.if.validations ?? {}).every(([name, property2]) => {
|
|
11893
|
+
const currentValue = logic.getScope(parentID).applyValidationRuleInCondition(name, formValues);
|
|
11894
|
+
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11895
|
+
return true;
|
|
11896
|
+
return false;
|
|
11897
|
+
});
|
|
11898
|
+
const computedValuesMatch = Object.entries(node.if.computedValues ?? {}).every(
|
|
11899
|
+
([name, property2]) => {
|
|
11900
|
+
const currentValue = logic.getScope(parentID).applyComputedValueRuleInCondition(name, formValues);
|
|
11901
|
+
if (Object.hasOwn(property2, "const") && currentValue === property2.const)
|
|
11902
|
+
return true;
|
|
11903
|
+
return false;
|
|
11904
|
+
}
|
|
11905
|
+
);
|
|
11906
|
+
return computedValuesMatch && validationsMatch;
|
|
11907
|
+
}
|
|
11908
|
+
|
|
11908
11909
|
// src/jsonLogic.js
|
|
11909
11910
|
var import_json_logic_js = __toESM(require_logic());
|
|
11910
11911
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.11.14-
|
|
3
|
+
"version": "0.11.14-dev.20250514100552",
|
|
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",
|
|
@@ -596,6 +596,74 @@ describe('Conditional with anyOf', () => {
|
|
|
596
596
|
});
|
|
597
597
|
});
|
|
598
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
|
+
|
|
599
667
|
describe('Conditionals - bugs and code-smells', () => {
|
|
600
668
|
// Why do we have these bugs?
|
|
601
669
|
// To be honest we never realized it much later later.
|
package/src/tests/helpers.js
CHANGED
|
@@ -448,19 +448,20 @@ export const mockGroupArrayInput = {
|
|
|
448
448
|
sex: {
|
|
449
449
|
description:
|
|
450
450
|
'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
|
|
451
|
+
enum: ['female', 'male'],
|
|
451
452
|
'x-jsf-presentation': {
|
|
452
453
|
inputType: 'radio',
|
|
454
|
+
options: [
|
|
455
|
+
{
|
|
456
|
+
label: 'Male',
|
|
457
|
+
value: 'male',
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
label: 'Female',
|
|
461
|
+
value: 'female',
|
|
462
|
+
},
|
|
463
|
+
],
|
|
453
464
|
},
|
|
454
|
-
oneOf: [
|
|
455
|
-
{
|
|
456
|
-
const: 'male',
|
|
457
|
-
title: 'Male',
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
const: 'female',
|
|
461
|
-
title: 'Female',
|
|
462
|
-
},
|
|
463
|
-
],
|
|
464
465
|
title: 'Child Sex',
|
|
465
466
|
type: 'string',
|
|
466
467
|
},
|