@remoteoss/json-schema-form 0.11.12-dev.20250313084704 → 0.11.12-dev.20250411165200

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/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.12-dev.20250313084704
5
- Generated: Thu, 13 Mar 2025 08:47:14 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250411165200
5
+ Generated: Fri, 11 Apr 2025 16:52:23 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -613,8 +613,6 @@ var getYupSchema = ({ inputType, ...field }) => {
613
613
  switch (type) {
614
614
  case "number":
615
615
  return yupSchemas.radioOrSelectNumber(optionValues);
616
- case "integer":
617
- return yupSchemas.radioOrSelectNumber(optionValues);
618
616
  case "boolean":
619
617
  return yupSchemas.radioOrSelectBoolean(optionValues);
620
618
  default:
@@ -775,8 +773,7 @@ function buildYupSchema(field, config, logic) {
775
773
  if (inputType === supportedTypes.FILE) {
776
774
  validators.push(withFile);
777
775
  }
778
- const hasOptions = field.options?.length > 0;
779
- if (jsonType === "integer" && !hasOptions) {
776
+ if (jsonType === "integer") {
780
777
  validators.push(withInteger);
781
778
  }
782
779
  if (typeof propertyFields.minimum !== "undefined") {
@@ -1311,12 +1308,24 @@ function processNode({
1311
1308
  formFields,
1312
1309
  accRequired = /* @__PURE__ */ new Set(),
1313
1310
  parentID = "root",
1314
- logic
1311
+ logic,
1312
+ processingConditional = false
1315
1313
  }) {
1316
1314
  const requiredFields = new Set(accRequired);
1317
1315
  Object.keys(node.properties ?? []).forEach((fieldName) => {
1318
1316
  const field = getField(fieldName, formFields);
1319
1317
  updateField(field, requiredFields, node, formValues, logic, { parentID });
1318
+ const nestedNode = node.properties[fieldName];
1319
+ const isFieldset = field.inputType === supportedTypes.FIELDSET;
1320
+ if (isFieldset && processingConditional) {
1321
+ processNode({
1322
+ node: nestedNode,
1323
+ formValues: formValues[fieldName] || {},
1324
+ formFields: field.fields,
1325
+ parentID,
1326
+ logic
1327
+ });
1328
+ }
1320
1329
  });
1321
1330
  node.required?.forEach((fieldName) => {
1322
1331
  requiredFields.add(fieldName);
@@ -1333,7 +1342,8 @@ function processNode({
1333
1342
  formFields,
1334
1343
  accRequired: requiredFields,
1335
1344
  parentID,
1336
- logic
1345
+ logic,
1346
+ processingConditional: true
1337
1347
  });
1338
1348
  branchRequired.forEach((field) => requiredFields.add(field));
1339
1349
  } else if (node.else) {
@@ -1343,7 +1353,8 @@ function processNode({
1343
1353
  formFields,
1344
1354
  accRequired: requiredFields,
1345
1355
  parentID,
1346
- logic
1356
+ logic,
1357
+ processingConditional: true
1347
1358
  });
1348
1359
  branchRequired.forEach((field) => requiredFields.add(field));
1349
1360
  }
@@ -1360,20 +1371,6 @@ function processNode({
1360
1371
  });
1361
1372
  });
1362
1373
  }
1363
- if (node.allOf) {
1364
- node.allOf.map(
1365
- (allOfNode) => processNode({
1366
- node: allOfNode,
1367
- formValues,
1368
- formFields,
1369
- accRequired: requiredFields,
1370
- parentID,
1371
- logic
1372
- })
1373
- ).forEach(({ required: allOfItemRequired }) => {
1374
- allOfItemRequired.forEach(requiredFields.add, requiredFields);
1375
- });
1376
- }
1377
1374
  if (node.properties) {
1378
1375
  Object.entries(node.properties).forEach(([name, nestedNode]) => {
1379
1376
  const inputType = getInputType(nestedNode);
@@ -1388,6 +1385,20 @@ function processNode({
1388
1385
  }
1389
1386
  });
1390
1387
  }
1388
+ if (node.allOf) {
1389
+ node.allOf.map(
1390
+ (allOfNode) => processNode({
1391
+ node: allOfNode,
1392
+ formValues,
1393
+ formFields,
1394
+ accRequired: requiredFields,
1395
+ parentID,
1396
+ logic
1397
+ })
1398
+ ).forEach(({ required: allOfItemRequired }) => {
1399
+ allOfItemRequired.forEach(requiredFields.add, requiredFields);
1400
+ });
1401
+ }
1391
1402
  if (node["x-jsf-logic"]) {
1392
1403
  const { required: requiredFromLogic } = processJSONLogicNode({
1393
1404
  node: node["x-jsf-logic"],
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.12-dev.20250313084704
5
- Generated: Thu, 13 Mar 2025 08:47:14 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250411165200
5
+ Generated: Fri, 11 Apr 2025 16:52:23 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -576,8 +576,6 @@ var getYupSchema = ({ inputType, ...field }) => {
576
576
  switch (type) {
577
577
  case "number":
578
578
  return yupSchemas.radioOrSelectNumber(optionValues);
579
- case "integer":
580
- return yupSchemas.radioOrSelectNumber(optionValues);
581
579
  case "boolean":
582
580
  return yupSchemas.radioOrSelectBoolean(optionValues);
583
581
  default:
@@ -738,8 +736,7 @@ function buildYupSchema(field, config, logic) {
738
736
  if (inputType === supportedTypes.FILE) {
739
737
  validators.push(withFile);
740
738
  }
741
- const hasOptions = field.options?.length > 0;
742
- if (jsonType === "integer" && !hasOptions) {
739
+ if (jsonType === "integer") {
743
740
  validators.push(withInteger);
744
741
  }
745
742
  if (typeof propertyFields.minimum !== "undefined") {
@@ -1274,12 +1271,24 @@ function processNode({
1274
1271
  formFields,
1275
1272
  accRequired = /* @__PURE__ */ new Set(),
1276
1273
  parentID = "root",
1277
- logic
1274
+ logic,
1275
+ processingConditional = false
1278
1276
  }) {
1279
1277
  const requiredFields = new Set(accRequired);
1280
1278
  Object.keys(node.properties ?? []).forEach((fieldName) => {
1281
1279
  const field = getField(fieldName, formFields);
1282
1280
  updateField(field, requiredFields, node, formValues, logic, { parentID });
1281
+ const nestedNode = node.properties[fieldName];
1282
+ const isFieldset = field.inputType === supportedTypes.FIELDSET;
1283
+ if (isFieldset && processingConditional) {
1284
+ processNode({
1285
+ node: nestedNode,
1286
+ formValues: formValues[fieldName] || {},
1287
+ formFields: field.fields,
1288
+ parentID,
1289
+ logic
1290
+ });
1291
+ }
1283
1292
  });
1284
1293
  node.required?.forEach((fieldName) => {
1285
1294
  requiredFields.add(fieldName);
@@ -1296,7 +1305,8 @@ function processNode({
1296
1305
  formFields,
1297
1306
  accRequired: requiredFields,
1298
1307
  parentID,
1299
- logic
1308
+ logic,
1309
+ processingConditional: true
1300
1310
  });
1301
1311
  branchRequired.forEach((field) => requiredFields.add(field));
1302
1312
  } else if (node.else) {
@@ -1306,7 +1316,8 @@ function processNode({
1306
1316
  formFields,
1307
1317
  accRequired: requiredFields,
1308
1318
  parentID,
1309
- logic
1319
+ logic,
1320
+ processingConditional: true
1310
1321
  });
1311
1322
  branchRequired.forEach((field) => requiredFields.add(field));
1312
1323
  }
@@ -1323,20 +1334,6 @@ function processNode({
1323
1334
  });
1324
1335
  });
1325
1336
  }
1326
- if (node.allOf) {
1327
- node.allOf.map(
1328
- (allOfNode) => processNode({
1329
- node: allOfNode,
1330
- formValues,
1331
- formFields,
1332
- accRequired: requiredFields,
1333
- parentID,
1334
- logic
1335
- })
1336
- ).forEach(({ required: allOfItemRequired }) => {
1337
- allOfItemRequired.forEach(requiredFields.add, requiredFields);
1338
- });
1339
- }
1340
1337
  if (node.properties) {
1341
1338
  Object.entries(node.properties).forEach(([name, nestedNode]) => {
1342
1339
  const inputType = getInputType(nestedNode);
@@ -1351,6 +1348,20 @@ function processNode({
1351
1348
  }
1352
1349
  });
1353
1350
  }
1351
+ if (node.allOf) {
1352
+ node.allOf.map(
1353
+ (allOfNode) => processNode({
1354
+ node: allOfNode,
1355
+ formValues,
1356
+ formFields,
1357
+ accRequired: requiredFields,
1358
+ parentID,
1359
+ logic
1360
+ })
1361
+ ).forEach(({ required: allOfItemRequired }) => {
1362
+ allOfItemRequired.forEach(requiredFields.add, requiredFields);
1363
+ });
1364
+ }
1354
1365
  if (node["x-jsf-logic"]) {
1355
1366
  const { required: requiredFromLogic } = processJSONLogicNode({
1356
1367
  node: node["x-jsf-logic"],
@@ -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.12-dev.20250313084704
5
- Generated: Thu, 13 Mar 2025 08:47:14 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250411165200
5
+ Generated: Fri, 11 Apr 2025 16:52:23 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -12092,8 +12092,6 @@ var getYupSchema = ({ inputType, ...field }) => {
12092
12092
  switch (type) {
12093
12093
  case "number":
12094
12094
  return yupSchemas.radioOrSelectNumber(optionValues);
12095
- case "integer":
12096
- return yupSchemas.radioOrSelectNumber(optionValues);
12097
12095
  case "boolean":
12098
12096
  return yupSchemas.radioOrSelectBoolean(optionValues);
12099
12097
  default:
@@ -12254,8 +12252,7 @@ function buildYupSchema(field, config, logic) {
12254
12252
  if (inputType === supportedTypes.FILE) {
12255
12253
  validators.push(withFile);
12256
12254
  }
12257
- const hasOptions = field.options?.length > 0;
12258
- if (jsonType === "integer" && !hasOptions) {
12255
+ if (jsonType === "integer") {
12259
12256
  validators.push(withInteger);
12260
12257
  }
12261
12258
  if (typeof propertyFields.minimum !== "undefined") {
@@ -12790,12 +12787,24 @@ function processNode({
12790
12787
  formFields,
12791
12788
  accRequired = /* @__PURE__ */ new Set(),
12792
12789
  parentID = "root",
12793
- logic
12790
+ logic,
12791
+ processingConditional = false
12794
12792
  }) {
12795
12793
  const requiredFields = new Set(accRequired);
12796
12794
  Object.keys(node.properties ?? []).forEach((fieldName) => {
12797
12795
  const field = getField(fieldName, formFields);
12798
12796
  updateField(field, requiredFields, node, formValues, logic, { parentID });
12797
+ const nestedNode = node.properties[fieldName];
12798
+ const isFieldset = field.inputType === supportedTypes.FIELDSET;
12799
+ if (isFieldset && processingConditional) {
12800
+ processNode({
12801
+ node: nestedNode,
12802
+ formValues: formValues[fieldName] || {},
12803
+ formFields: field.fields,
12804
+ parentID,
12805
+ logic
12806
+ });
12807
+ }
12799
12808
  });
12800
12809
  node.required?.forEach((fieldName) => {
12801
12810
  requiredFields.add(fieldName);
@@ -12812,7 +12821,8 @@ function processNode({
12812
12821
  formFields,
12813
12822
  accRequired: requiredFields,
12814
12823
  parentID,
12815
- logic
12824
+ logic,
12825
+ processingConditional: true
12816
12826
  });
12817
12827
  branchRequired.forEach((field) => requiredFields.add(field));
12818
12828
  } else if (node.else) {
@@ -12822,7 +12832,8 @@ function processNode({
12822
12832
  formFields,
12823
12833
  accRequired: requiredFields,
12824
12834
  parentID,
12825
- logic
12835
+ logic,
12836
+ processingConditional: true
12826
12837
  });
12827
12838
  branchRequired.forEach((field) => requiredFields.add(field));
12828
12839
  }
@@ -12839,20 +12850,6 @@ function processNode({
12839
12850
  });
12840
12851
  });
12841
12852
  }
12842
- if (node.allOf) {
12843
- node.allOf.map(
12844
- (allOfNode) => processNode({
12845
- node: allOfNode,
12846
- formValues,
12847
- formFields,
12848
- accRequired: requiredFields,
12849
- parentID,
12850
- logic
12851
- })
12852
- ).forEach(({ required: allOfItemRequired }) => {
12853
- allOfItemRequired.forEach(requiredFields.add, requiredFields);
12854
- });
12855
- }
12856
12853
  if (node.properties) {
12857
12854
  Object.entries(node.properties).forEach(([name, nestedNode]) => {
12858
12855
  const inputType = getInputType(nestedNode);
@@ -12867,6 +12864,20 @@ function processNode({
12867
12864
  }
12868
12865
  });
12869
12866
  }
12867
+ if (node.allOf) {
12868
+ node.allOf.map(
12869
+ (allOfNode) => processNode({
12870
+ node: allOfNode,
12871
+ formValues,
12872
+ formFields,
12873
+ accRequired: requiredFields,
12874
+ parentID,
12875
+ logic
12876
+ })
12877
+ ).forEach(({ required: allOfItemRequired }) => {
12878
+ allOfItemRequired.forEach(requiredFields.add, requiredFields);
12879
+ });
12880
+ }
12870
12881
  if (node["x-jsf-logic"]) {
12871
12882
  const { required: requiredFromLogic } = processJSONLogicNode({
12872
12883
  node: node["x-jsf-logic"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remoteoss/json-schema-form",
3
- "version": "0.11.12-dev.20250313084704",
3
+ "version": "0.11.12-dev.20250411165200",
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",
@@ -63,7 +63,7 @@ import {
63
63
  schemaForErrorMessageSpecificity,
64
64
  jsfConfigForErrorMessageSpecificity,
65
65
  schemaInputTypeFile,
66
- schemaWithSelectInteger,
66
+ schemaWithRootFieldsetsConditionals,
67
67
  } from './helpers';
68
68
  import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
69
69
  import { createHeadlessForm } from '@/createHeadlessForm';
@@ -658,27 +658,6 @@ describe('createHeadlessForm', () => {
658
658
  ],
659
659
  });
660
660
  });
661
-
662
- it('supports "select" field with integer values', async () => {
663
- const { handleValidation } = createHeadlessForm(schemaWithSelectInteger);
664
- const validateForm = (vals) => friendlyError(handleValidation(vals));
665
-
666
- // Check for invalid option
667
- expect(
668
- validateForm({
669
- account_type: 4,
670
- })
671
- ).toEqual({
672
- account_type: 'The option 4 is not valid.',
673
- });
674
-
675
- // Check for valid option
676
- expect(
677
- validateForm({
678
- account_type: 1,
679
- })
680
- ).toBeUndefined();
681
- });
682
661
  });
683
662
  describe('support "radio" field type', () => {
684
663
  it('support "radio" field type @deprecated', () => {
@@ -2184,6 +2163,47 @@ describe('createHeadlessForm', () => {
2184
2163
  ).toBeUndefined();
2185
2164
  });
2186
2165
  });
2166
+
2167
+ describe('supports root fieldsets conditionals', () => {
2168
+ it('Given a basic retirement, the perks.has_pension is hidden', async () => {
2169
+ const { fields, handleValidation } = createHeadlessForm(
2170
+ schemaWithRootFieldsetsConditionals,
2171
+ {}
2172
+ );
2173
+ const validateForm = (vals) => friendlyError(handleValidation(vals));
2174
+
2175
+ expect(validateForm({})).toEqual({
2176
+ perks: {
2177
+ retirement: 'Required field',
2178
+ },
2179
+ });
2180
+
2181
+ // has_pension is not visible
2182
+ expect(getField(fields, 'perks', 'has_pension').isVisible).toBe(false);
2183
+
2184
+ expect(
2185
+ validateForm({
2186
+ perks: { retirement: 'plus' },
2187
+ })
2188
+ ).toEqual({
2189
+ perks: {
2190
+ has_pension: 'Required field',
2191
+ },
2192
+ });
2193
+
2194
+ // field becomes visible
2195
+ expect(getField(fields, 'perks', 'has_pension').isVisible).toBe(true);
2196
+
2197
+ expect(
2198
+ validateForm({
2199
+ perks: { retirement: 'basic' },
2200
+ })
2201
+ ).toBeUndefined();
2202
+
2203
+ // field becomes invisible
2204
+ expect(getField(fields, 'perks', 'has_pension').isVisible).toBe(false);
2205
+ });
2206
+ });
2187
2207
  });
2188
2208
 
2189
2209
  it('support "email" field type', () => {
@@ -1973,6 +1973,90 @@ export const schemaWithConditionalToFieldset = {
1973
1973
  required: ['perks', 'work_hours_per_week'],
1974
1974
  };
1975
1975
 
1976
+ export const schemaWithRootFieldsetsConditionals = {
1977
+ additionalProperties: false,
1978
+ type: 'object',
1979
+ properties: {
1980
+ perks: {
1981
+ additionalProperties: false,
1982
+ properties: {
1983
+ retirement: {
1984
+ oneOf: [
1985
+ {
1986
+ const: 'basic',
1987
+ title: 'Basic',
1988
+ },
1989
+ {
1990
+ const: 'plus',
1991
+ title: 'Plus',
1992
+ },
1993
+ ],
1994
+ title: 'Retirement',
1995
+ type: 'string',
1996
+ 'x-jsf-presentation': {
1997
+ inputType: 'radio',
1998
+ },
1999
+ },
2000
+ has_pension: {
2001
+ oneOf: [
2002
+ {
2003
+ const: 'yes',
2004
+ title: 'Yes',
2005
+ },
2006
+ {
2007
+ const: 'no',
2008
+ title: 'No',
2009
+ },
2010
+ ],
2011
+ title: 'Has pension',
2012
+ type: 'string',
2013
+ 'x-jsf-presentation': {
2014
+ inputType: 'radio',
2015
+ },
2016
+ },
2017
+ },
2018
+ required: ['retirement'],
2019
+ title: 'Perks',
2020
+ type: 'object',
2021
+ 'x-jsf-presentation': {
2022
+ inputType: 'fieldset',
2023
+ },
2024
+ },
2025
+ },
2026
+ required: ['perks'],
2027
+ allOf: [
2028
+ {
2029
+ if: {
2030
+ properties: {
2031
+ perks: {
2032
+ properties: {
2033
+ retirement: {
2034
+ const: 'basic',
2035
+ },
2036
+ },
2037
+ },
2038
+ },
2039
+ },
2040
+ then: {
2041
+ properties: {
2042
+ perks: {
2043
+ properties: {
2044
+ has_pension: false,
2045
+ },
2046
+ },
2047
+ },
2048
+ },
2049
+ else: {
2050
+ properties: {
2051
+ perks: {
2052
+ required: ['has_pension'],
2053
+ },
2054
+ },
2055
+ },
2056
+ },
2057
+ ],
2058
+ };
2059
+
1976
2060
  export const schemaWorkSchedule = {
1977
2061
  type: 'object',
1978
2062
  properties: {
@@ -2327,24 +2411,3 @@ export const schemaWithCustomValidationsAndConditionals = {
2327
2411
  },
2328
2412
  ],
2329
2413
  };
2330
-
2331
- export const schemaWithSelectInteger = {
2332
- additionalProperties: false,
2333
- type: 'object',
2334
- properties: {
2335
- account_type: {
2336
- title: 'Select an account type',
2337
- description: '',
2338
- 'x-jsf-presentation': {
2339
- inputType: 'select',
2340
- },
2341
- oneOf: [
2342
- { title: 'Normal User', const: 0 },
2343
- { title: 'Business', const: 1 },
2344
- { title: 'Services Provider', const: 2 },
2345
- ],
2346
- type: 'integer',
2347
- },
2348
- },
2349
- required: [],
2350
- };
@@ -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({