@qoretechnologies/reqraft 0.10.39 → 0.10.40-pr.100.g279b5f8

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.
@@ -1809,6 +1809,68 @@ export const getUnresolvedRequiredOptions = (
1809
1809
  return unresolved;
1810
1810
  };
1811
1811
 
1812
+ /**
1813
+ * Split a dependency entry into the sibling it names and how its value is compared.
1814
+ *
1815
+ * Three forms: `name` (the sibling must simply have a value), `name=value` (it must
1816
+ * have exactly that value) and `name!=value` (it must have a value, and not that
1817
+ * one). The negative form is what lets a field say it applies to every variant of a
1818
+ * record but one — spelling that as an `any-of` list of every other variant is both
1819
+ * unreadable in the "Depends on" lock and silently wrong the moment a variant is
1820
+ * added.
1821
+ *
1822
+ * `!=` deliberately requires the sibling to be answered: "not X" is a statement about
1823
+ * an answer, so an unanswered sibling does not satisfy it and the field stays locked.
1824
+ */
1825
+ export const parseDependency = (
1826
+ dependency: string
1827
+ ): { name: string; op?: '=' | '!='; value?: string } => {
1828
+ const neqIdx = dependency.indexOf('!=');
1829
+ if (neqIdx !== -1) {
1830
+ return {
1831
+ name: dependency.substring(0, neqIdx),
1832
+ op: '!=',
1833
+ value: dependency.substring(neqIdx + 2),
1834
+ };
1835
+ }
1836
+
1837
+ const eqIdx = dependency.indexOf('=');
1838
+ if (eqIdx !== -1) {
1839
+ return {
1840
+ name: dependency.substring(0, eqIdx),
1841
+ op: '=',
1842
+ value: dependency.substring(eqIdx + 1),
1843
+ };
1844
+ }
1845
+
1846
+ return { name: dependency };
1847
+ };
1848
+
1849
+ /** Whether one dependency entry holds against the current form values. */
1850
+ const isDependencyFulfilled = (
1851
+ dependency: string,
1852
+ options: TQorusForm,
1853
+ optionsSchema?: IQorusFormSchema
1854
+ ): boolean => {
1855
+ const { name, op, value } = parseDependency(dependency);
1856
+
1857
+ if (op) {
1858
+ const optValue = options?.[name]?.value;
1859
+ if (optValue == null) {
1860
+ return false;
1861
+ }
1862
+ return op === '=' ? String(optValue) === value : String(optValue) !== value;
1863
+ }
1864
+
1865
+ return options?.[name]
1866
+ ? validateField(options[name].type, options[name].value, {
1867
+ ...(optionsSchema?.[name] as unknown as IFieldValidationProps),
1868
+ options,
1869
+ optionSchema: optionsSchema,
1870
+ })
1871
+ : true;
1872
+ };
1873
+
1812
1874
  export const hasAllDependenciesFullfilled = (
1813
1875
  dependencies: string[] | string[][],
1814
1876
  options: TQorusForm,
@@ -1819,38 +1881,19 @@ export const hasAllDependenciesFullfilled = (
1819
1881
  }
1820
1882
 
1821
1883
  return dependencies.every((dependency: string | string[]) => {
1884
+ // A nested list is an ANY. It used to look each entry up as a whole form-field
1885
+ // name, so a `name=value` entry inside one found no field and returned `true`
1886
+ // unconditionally — the any-of group was satisfied by anything at all, while
1887
+ // CompactRow's lock rendered those same entries as real comparisons. Both halves
1888
+ // now go through one parser, so the grammar cannot mean two things.
1822
1889
  if (isArray(dependency)) {
1823
- return (dependency as string[]).some((dep) => {
1824
- return options?.[dep]
1825
- ? validateField(options[dep].type, options[dep].value, {
1826
- ...(optionsSchema?.[dep] as unknown as IFieldValidationProps),
1827
- options,
1828
- optionSchema: optionsSchema,
1829
- })
1830
- : true;
1831
- });
1832
- }
1833
-
1834
- if (isString(dependency)) {
1835
- const eqIdx = (dependency as string).indexOf('=');
1836
- if (eqIdx !== -1) {
1837
- const depName = (dependency as string).substring(0, eqIdx);
1838
- const depValue = (dependency as string).substring(eqIdx + 1);
1839
- const optValue = options?.[depName]?.value;
1840
- return optValue != null && String(optValue) === depValue;
1841
- }
1890
+ return (dependency as string[]).some((dep) =>
1891
+ isDependencyFulfilled(dep, options, optionsSchema)
1892
+ );
1842
1893
  }
1843
1894
 
1844
- return options?.[dependency as string]
1845
- ? validateField(
1846
- options[dependency as string].type,
1847
- options[dependency as string].value,
1848
- {
1849
- ...(optionsSchema?.[dependency as string] as unknown as IFieldValidationProps),
1850
- options,
1851
- optionSchema: optionsSchema,
1852
- }
1853
- )
1895
+ return isString(dependency)
1896
+ ? isDependencyFulfilled(dependency as string, options, optionsSchema)
1854
1897
  : true;
1855
1898
  });
1856
1899
  };
package/src/index.tsx CHANGED
@@ -7,6 +7,7 @@ export {
7
7
  getTypeFromValue,
8
8
  maybeParseYaml,
9
9
  hasAllDependenciesFullfilled,
10
+ parseDependency,
10
11
  validateOptionWithRequiredGroups,
11
12
  } from './helpers/validations';
12
13
  export type { IValidationResult } from './helpers/validations';