@remoteoss/json-schema-form 0.11.9-dev.20241210213029 → 0.11.9-dev.20241213082826

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) 2024 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.11.9-dev.20241210213029
5
- Generated: Tue, 10 Dec 2024 21:31:03 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.9-dev.20241213082826
5
+ Generated: Fri, 13 Dec 2024 08:29:06 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -98,6 +98,9 @@ function hasProperty(object2, propertyName) {
98
98
 
99
99
  // src/checkIfConditionMatches.js
100
100
  function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
101
+ if (typeof node.if === "boolean") {
102
+ return node.if;
103
+ }
101
104
  return Object.keys(node.if.properties ?? {}).every((name) => {
102
105
  const currentProperty = node.if.properties[name];
103
106
  const value = formValues[name];
@@ -1278,9 +1281,6 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
1278
1281
  }
1279
1282
  if (field.calculateConditionalProperties) {
1280
1283
  const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
1281
- dynamicAttributes: Object.fromEntries(
1282
- (field.dynamicAttributes ?? []).map((attr) => [attr, field[attr]])
1283
- ),
1284
1284
  isRequired: fieldIsRequired,
1285
1285
  conditionBranch: node,
1286
1286
  formValues
@@ -1316,7 +1316,7 @@ function processNode({
1316
1316
  parentID
1317
1317
  });
1318
1318
  });
1319
- if (node.if) {
1319
+ if (node.if !== void 0) {
1320
1320
  const matchesCondition = checkIfConditionMatchesProperties(node, formValues, formFields, logic);
1321
1321
  if (matchesCondition && node.then) {
1322
1322
  const { required: branchRequired } = processNode({
@@ -1597,18 +1597,15 @@ function rebuildFieldset(fields, property) {
1597
1597
  }));
1598
1598
  }
1599
1599
  function calculateConditionalProperties({ fieldParams, customProperties, logic, config }) {
1600
- return ({ dynamicAttributes, isRequired, conditionBranch, formValues }) => {
1600
+ return ({ isRequired, conditionBranch, formValues }) => {
1601
1601
  const conditionalProperty = conditionBranch?.properties?.[fieldParams.name];
1602
1602
  if (conditionalProperty) {
1603
1603
  const presentation = pickXKey(conditionalProperty, "presentation") ?? {};
1604
1604
  const fieldDescription = getFieldDescription(conditionalProperty, customProperties);
1605
- const newFieldParams = extractParametersFromNode(
1606
- {
1607
- ...conditionalProperty,
1608
- ...fieldDescription
1609
- },
1610
- Object.keys(dynamicAttributes)
1611
- );
1605
+ const newFieldParams = extractParametersFromNode({
1606
+ ...conditionalProperty,
1607
+ ...fieldDescription
1608
+ });
1612
1609
  let fieldSetFields;
1613
1610
  if (fieldParams.inputType === supportedTypes.FIELDSET) {
1614
1611
  fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
@@ -1628,7 +1625,6 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
1628
1625
  ...calculatedComputedAttributes.value ? { value: calculatedComputedAttributes.value } : { value: void 0 },
1629
1626
  schema: buildYupSchema(
1630
1627
  {
1631
- ...dynamicAttributes,
1632
1628
  ...fieldParams,
1633
1629
  ...restNewFieldParams,
1634
1630
  ...calculatedComputedAttributes,
@@ -1771,32 +1767,11 @@ function convertJSONSchemaPropertiesToFieldParameters({ properties, required, "x
1771
1767
  return Object.entries(properties).filter(([, value]) => typeof value === "object").map(([key, value]) => buildFieldParameters(key, value, required, config)).sort(sortFields).map(({ position, ...fieldParams }) => fieldParams);
1772
1768
  }
1773
1769
  function applyFieldsDependencies(fieldsParameters, node) {
1774
- if (node?.properties) {
1775
- Object.entries(node.properties ?? {}).forEach(([key, value]) => {
1776
- if (value["x-jsf-logic-computedAttrs"]) {
1777
- const property = fieldsParameters.find(({ name }) => name === key);
1778
- property.isDynamic = true;
1779
- property.dynamicAttributes = [
1780
- ...property.dynamicAttributes ?? [],
1781
- ...Object.keys(value["x-jsf-logic-computedAttrs"])
1782
- ];
1783
- }
1784
- });
1785
- }
1786
1770
  if (node?.then) {
1787
1771
  fieldsParameters.filter(
1788
1772
  ({ name }) => node.then?.properties?.[name] || node.then?.required?.includes(name) || node.else?.properties?.[name] || node.else?.required?.includes(name)
1789
1773
  ).forEach((property) => {
1790
- const dynamicAttributes = [
1791
- ...Object.keys(node.then?.properties?.[property.name] ?? {}),
1792
- ...Object.keys(node.else?.properties?.[property.name] ?? {})
1793
- ];
1794
1774
  property.isDynamic = true;
1795
- if (property.dynamicAttributes) {
1796
- property.dynamicAttributes.push(...dynamicAttributes);
1797
- } else {
1798
- property.dynamicAttributes = dynamicAttributes;
1799
- }
1800
1775
  });
1801
1776
  applyFieldsDependencies(fieldsParameters, node.then);
1802
1777
  }
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2024 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.11.9-dev.20241210213029
5
- Generated: Tue, 10 Dec 2024 21:31:03 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.9-dev.20241213082826
5
+ Generated: Fri, 13 Dec 2024 08:29:06 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -61,6 +61,9 @@ function hasProperty(object2, propertyName) {
61
61
 
62
62
  // src/checkIfConditionMatches.js
63
63
  function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
64
+ if (typeof node.if === "boolean") {
65
+ return node.if;
66
+ }
64
67
  return Object.keys(node.if.properties ?? {}).every((name) => {
65
68
  const currentProperty = node.if.properties[name];
66
69
  const value = formValues[name];
@@ -1241,9 +1244,6 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
1241
1244
  }
1242
1245
  if (field.calculateConditionalProperties) {
1243
1246
  const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
1244
- dynamicAttributes: Object.fromEntries(
1245
- (field.dynamicAttributes ?? []).map((attr) => [attr, field[attr]])
1246
- ),
1247
1247
  isRequired: fieldIsRequired,
1248
1248
  conditionBranch: node,
1249
1249
  formValues
@@ -1279,7 +1279,7 @@ function processNode({
1279
1279
  parentID
1280
1280
  });
1281
1281
  });
1282
- if (node.if) {
1282
+ if (node.if !== void 0) {
1283
1283
  const matchesCondition = checkIfConditionMatchesProperties(node, formValues, formFields, logic);
1284
1284
  if (matchesCondition && node.then) {
1285
1285
  const { required: branchRequired } = processNode({
@@ -1560,18 +1560,15 @@ function rebuildFieldset(fields, property) {
1560
1560
  }));
1561
1561
  }
1562
1562
  function calculateConditionalProperties({ fieldParams, customProperties, logic, config }) {
1563
- return ({ dynamicAttributes, isRequired, conditionBranch, formValues }) => {
1563
+ return ({ isRequired, conditionBranch, formValues }) => {
1564
1564
  const conditionalProperty = conditionBranch?.properties?.[fieldParams.name];
1565
1565
  if (conditionalProperty) {
1566
1566
  const presentation = pickXKey(conditionalProperty, "presentation") ?? {};
1567
1567
  const fieldDescription = getFieldDescription(conditionalProperty, customProperties);
1568
- const newFieldParams = extractParametersFromNode(
1569
- {
1570
- ...conditionalProperty,
1571
- ...fieldDescription
1572
- },
1573
- Object.keys(dynamicAttributes)
1574
- );
1568
+ const newFieldParams = extractParametersFromNode({
1569
+ ...conditionalProperty,
1570
+ ...fieldDescription
1571
+ });
1575
1572
  let fieldSetFields;
1576
1573
  if (fieldParams.inputType === supportedTypes.FIELDSET) {
1577
1574
  fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
@@ -1591,7 +1588,6 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
1591
1588
  ...calculatedComputedAttributes.value ? { value: calculatedComputedAttributes.value } : { value: void 0 },
1592
1589
  schema: buildYupSchema(
1593
1590
  {
1594
- ...dynamicAttributes,
1595
1591
  ...fieldParams,
1596
1592
  ...restNewFieldParams,
1597
1593
  ...calculatedComputedAttributes,
@@ -1734,32 +1730,11 @@ function convertJSONSchemaPropertiesToFieldParameters({ properties, required, "x
1734
1730
  return Object.entries(properties).filter(([, value]) => typeof value === "object").map(([key, value]) => buildFieldParameters(key, value, required, config)).sort(sortFields).map(({ position, ...fieldParams }) => fieldParams);
1735
1731
  }
1736
1732
  function applyFieldsDependencies(fieldsParameters, node) {
1737
- if (node?.properties) {
1738
- Object.entries(node.properties ?? {}).forEach(([key, value]) => {
1739
- if (value["x-jsf-logic-computedAttrs"]) {
1740
- const property = fieldsParameters.find(({ name }) => name === key);
1741
- property.isDynamic = true;
1742
- property.dynamicAttributes = [
1743
- ...property.dynamicAttributes ?? [],
1744
- ...Object.keys(value["x-jsf-logic-computedAttrs"])
1745
- ];
1746
- }
1747
- });
1748
- }
1749
1733
  if (node?.then) {
1750
1734
  fieldsParameters.filter(
1751
1735
  ({ name }) => node.then?.properties?.[name] || node.then?.required?.includes(name) || node.else?.properties?.[name] || node.else?.required?.includes(name)
1752
1736
  ).forEach((property) => {
1753
- const dynamicAttributes = [
1754
- ...Object.keys(node.then?.properties?.[property.name] ?? {}),
1755
- ...Object.keys(node.else?.properties?.[property.name] ?? {})
1756
- ];
1757
1737
  property.isDynamic = true;
1758
- if (property.dynamicAttributes) {
1759
- property.dynamicAttributes.push(...dynamicAttributes);
1760
- } else {
1761
- property.dynamicAttributes = dynamicAttributes;
1762
- }
1763
1738
  });
1764
1739
  applyFieldsDependencies(fieldsParameters, node.then);
1765
1740
  }
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2024 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.11.9-dev.20241210213029
5
- Generated: Tue, 10 Dec 2024 21:31:03 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.9-dev.20241213082826
5
+ Generated: Fri, 13 Dec 2024 08:29:06 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -11578,6 +11578,9 @@ function hasProperty(object2, propertyName) {
11578
11578
 
11579
11579
  // src/checkIfConditionMatches.js
11580
11580
  function checkIfConditionMatchesProperties(node, formValues, formFields, logic) {
11581
+ if (typeof node.if === "boolean") {
11582
+ return node.if;
11583
+ }
11581
11584
  return Object.keys(node.if.properties ?? {}).every((name) => {
11582
11585
  const currentProperty = node.if.properties[name];
11583
11586
  const value = formValues[name];
@@ -12757,9 +12760,6 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
12757
12760
  }
12758
12761
  if (field.calculateConditionalProperties) {
12759
12762
  const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
12760
- dynamicAttributes: Object.fromEntries(
12761
- (field.dynamicAttributes ?? []).map((attr) => [attr, field[attr]])
12762
- ),
12763
12763
  isRequired: fieldIsRequired,
12764
12764
  conditionBranch: node,
12765
12765
  formValues
@@ -12795,7 +12795,7 @@ function processNode({
12795
12795
  parentID
12796
12796
  });
12797
12797
  });
12798
- if (node.if) {
12798
+ if (node.if !== void 0) {
12799
12799
  const matchesCondition = checkIfConditionMatchesProperties(node, formValues, formFields, logic);
12800
12800
  if (matchesCondition && node.then) {
12801
12801
  const { required: branchRequired } = processNode({
@@ -13076,18 +13076,15 @@ function rebuildFieldset(fields, property2) {
13076
13076
  }));
13077
13077
  }
13078
13078
  function calculateConditionalProperties({ fieldParams, customProperties, logic, config }) {
13079
- return ({ dynamicAttributes, isRequired, conditionBranch, formValues }) => {
13079
+ return ({ isRequired, conditionBranch, formValues }) => {
13080
13080
  const conditionalProperty = conditionBranch?.properties?.[fieldParams.name];
13081
13081
  if (conditionalProperty) {
13082
13082
  const presentation = pickXKey(conditionalProperty, "presentation") ?? {};
13083
13083
  const fieldDescription = getFieldDescription(conditionalProperty, customProperties);
13084
- const newFieldParams = extractParametersFromNode(
13085
- {
13086
- ...conditionalProperty,
13087
- ...fieldDescription
13088
- },
13089
- Object.keys(dynamicAttributes)
13090
- );
13084
+ const newFieldParams = extractParametersFromNode({
13085
+ ...conditionalProperty,
13086
+ ...fieldDescription
13087
+ });
13091
13088
  let fieldSetFields;
13092
13089
  if (fieldParams.inputType === supportedTypes.FIELDSET) {
13093
13090
  fieldSetFields = rebuildFieldset(fieldParams.fields, conditionalProperty);
@@ -13107,7 +13104,6 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
13107
13104
  ...calculatedComputedAttributes.value ? { value: calculatedComputedAttributes.value } : { value: void 0 },
13108
13105
  schema: buildYupSchema(
13109
13106
  {
13110
- ...dynamicAttributes,
13111
13107
  ...fieldParams,
13112
13108
  ...restNewFieldParams,
13113
13109
  ...calculatedComputedAttributes,
@@ -13250,32 +13246,11 @@ function convertJSONSchemaPropertiesToFieldParameters({ properties, required: re
13250
13246
  return Object.entries(properties).filter(([, value]) => typeof value === "object").map(([key, value]) => buildFieldParameters(key, value, required2, config)).sort(sortFields2).map(({ position, ...fieldParams }) => fieldParams);
13251
13247
  }
13252
13248
  function applyFieldsDependencies(fieldsParameters, node) {
13253
- if (node?.properties) {
13254
- Object.entries(node.properties ?? {}).forEach(([key, value]) => {
13255
- if (value["x-jsf-logic-computedAttrs"]) {
13256
- const property2 = fieldsParameters.find(({ name }) => name === key);
13257
- property2.isDynamic = true;
13258
- property2.dynamicAttributes = [
13259
- ...property2.dynamicAttributes ?? [],
13260
- ...Object.keys(value["x-jsf-logic-computedAttrs"])
13261
- ];
13262
- }
13263
- });
13264
- }
13265
13249
  if (node?.then) {
13266
13250
  fieldsParameters.filter(
13267
13251
  ({ name }) => node.then?.properties?.[name] || node.then?.required?.includes(name) || node.else?.properties?.[name] || node.else?.required?.includes(name)
13268
13252
  ).forEach((property2) => {
13269
- const dynamicAttributes = [
13270
- ...Object.keys(node.then?.properties?.[property2.name] ?? {}),
13271
- ...Object.keys(node.else?.properties?.[property2.name] ?? {})
13272
- ];
13273
13253
  property2.isDynamic = true;
13274
- if (property2.dynamicAttributes) {
13275
- property2.dynamicAttributes.push(...dynamicAttributes);
13276
- } else {
13277
- property2.dynamicAttributes = dynamicAttributes;
13278
- }
13279
13254
  });
13280
13255
  applyFieldsDependencies(fieldsParameters, node.then);
13281
13256
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remoteoss/json-schema-form",
3
- "version": "0.11.9-dev.20241210213029",
3
+ "version": "0.11.9-dev.20241213082826",
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",
@@ -1,5 +1,13 @@
1
1
  import { checkIfConditionMatchesProperties } from '../checkIfConditionMatches';
2
2
 
3
+ it('True if is always going to be true', () => {
4
+ expect(checkIfConditionMatchesProperties({ if: true })).toBe(true);
5
+ });
6
+
7
+ it('False if is always going to be false', () => {
8
+ expect(checkIfConditionMatchesProperties({ if: false })).toBe(false);
9
+ });
10
+
3
11
  it('Empty if is always going to be true', () => {
4
12
  expect(checkIfConditionMatchesProperties({ if: { properties: {} } })).toBe(true);
5
13
  });
@@ -480,116 +480,70 @@ describe('Conditional with a minimum value check', () => {
480
480
  });
481
481
  });
482
482
 
483
- describe('Multiple conditions affecting the same field', () => {
484
- it('Should apply all conditions', () => {
483
+ describe('Conditional with literal booleans', () => {
484
+ it('handles true case', () => {
485
485
  const schema = {
486
486
  properties: {
487
- answer: { type: 'string' },
488
- number: { type: 'number' },
489
- },
490
- allOf: [
491
- {
492
- if: { properties: { answer: { const: 'yes' } } },
493
- then: { properties: { number: { minimum: 10 } } },
487
+ is_full_time: {
488
+ type: 'boolean',
494
489
  },
495
- {
496
- if: { properties: { answer: { const: 'yes' } } },
497
- then: { properties: { number: { maximum: 20 } } },
498
- },
499
- ],
500
- };
501
-
502
- const { handleValidation } = createHeadlessForm(schema, { strictInputType: false });
503
- expect(handleValidation({ answer: 'yes', number: 15 }).formErrors).toEqual(undefined);
504
- expect(handleValidation({ answer: 'yes', number: 9 }).formErrors).toEqual({
505
- number: 'Must be greater or equal to 10',
506
- });
507
- expect(handleValidation({ answer: 'yes', number: 21 }).formErrors).toEqual({
508
- number: 'Must be smaller or equal to 20',
509
- });
510
- expect(handleValidation({ answer: 'no', number: 9 }).formErrors).toBeUndefined();
511
- expect(handleValidation({ answer: 'no', number: 15 }).formErrors).toBeUndefined();
512
- expect(handleValidation({ answer: 'no', number: 21 }).formErrors).toBeUndefined();
513
- });
514
-
515
- it('Accepts unsatisfiable conflicting conditions', () => {
516
- const unsatisfiableSchema = {
517
- properties: {
518
- has_books: { type: 'string' },
519
- books: {
490
+ salary: {
520
491
  type: 'number',
521
- const: 4,
522
492
  },
523
493
  },
524
- required: ['books'],
525
- allOf: [
526
- {
527
- if: { properties: { has_books: { const: 'yes' } } },
528
- then: {
529
- properties: {
530
- books: {
531
- minimum: 5,
532
- },
533
- },
534
- },
535
- },
536
- ],
494
+ required: [],
495
+ if: true,
496
+ then: {
497
+ required: ['is_full_time'],
498
+ },
499
+ else: {
500
+ required: ['salary'],
501
+ },
537
502
  };
503
+ const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
538
504
 
539
- // This is intentionally not able to be satisfied.
540
- const { handleValidation } = createHeadlessForm(unsatisfiableSchema, {
541
- strictInputType: false,
542
- });
543
- expect(handleValidation({ has_books: 'yes', books: 4 }).formErrors).toEqual({
544
- books: 'Must be greater or equal to 5',
505
+ handleValidation({});
506
+
507
+ expect(fields[0]).toMatchObject({
508
+ name: 'is_full_time',
509
+ required: true,
545
510
  });
546
- expect(handleValidation({ has_books: 'yes', books: 5 }).formErrors).toEqual({
547
- books: 'The only accepted value is 4.',
511
+ expect(fields[1]).toMatchObject({
512
+ name: 'salary',
513
+ required: false,
548
514
  });
549
515
  });
550
516
 
551
- it('Computed attributes also get the same treatment for unsatisfiable conflicting conditions', () => {
552
- const unsatisfiableSchema = {
517
+ it('handles false case', () => {
518
+ const schema = {
553
519
  properties: {
554
- has_books: { type: 'string' },
555
- books: {
520
+ is_full_time: {
521
+ type: 'boolean',
522
+ },
523
+ salary: {
556
524
  type: 'number',
557
- 'x-jsf-logic-computedAttrs': {
558
- const: 'book_space',
559
- },
560
525
  },
561
526
  },
562
- required: ['books'],
563
- allOf: [
564
- {
565
- if: { properties: { has_books: { const: 'yes' } } },
566
- then: {
567
- properties: {
568
- books: {
569
- minimum: 5,
570
- },
571
- },
572
- },
573
- },
574
- ],
575
- 'x-jsf-logic': {
576
- computedValues: {
577
- book_space: {
578
- rule: {
579
- '*': [2, 2],
580
- },
581
- },
582
- },
527
+ required: [],
528
+ if: false,
529
+ then: {
530
+ required: ['is_full_time'],
531
+ },
532
+ else: {
533
+ required: ['salary'],
583
534
  },
584
535
  };
585
- const { handleValidation } = createHeadlessForm(unsatisfiableSchema, {
586
- strictInputType: false,
587
- });
588
- expect(handleValidation({ has_books: 'yes', books: 4 }).formErrors).toEqual({
589
- books: 'Must be greater or equal to 5',
536
+ const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
537
+
538
+ handleValidation({});
539
+
540
+ expect(fields[0]).toMatchObject({
541
+ name: 'is_full_time',
542
+ required: false,
590
543
  });
591
- expect(handleValidation({ has_books: 'yes', books: 5 }).formErrors).toEqual({
592
- books: 'The only accepted value is 4.',
544
+ expect(fields[1]).toMatchObject({
545
+ name: 'salary',
546
+ required: true,
593
547
  });
594
548
  });
595
549
  });
@@ -2009,8 +2009,6 @@ describe('createHeadlessForm', () => {
2009
2009
  });
2010
2010
 
2011
2011
  it('When changing back to low work hours, the perks.food goes back to the original state', () => {
2012
- // HACK FOR NOW THAT IS CAUSING THIS EXTRA VALIDATION. Fix me!!
2013
- validateForm({});
2014
2012
  expect(
2015
2013
  validateForm({
2016
2014
  work_hours_per_week: 10,
@@ -2021,7 +2019,6 @@ describe('createHeadlessForm', () => {
2021
2019
  food: 'Required field',
2022
2020
  retirement: 'Required field',
2023
2021
  },
2024
- // pto_minimum: 20 would appear if not for the extra validation above.
2025
2022
  // ...pto is minimum error is gone! (sanity-check)
2026
2023
  });
2027
2024