« get me outta code hell

yaml: invalidFieldCombinations value matching - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2025-07-13 15:49:21 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-07-13 15:49:21 -0300
commit7c86db9d0a2df821151b54564f66288680908d66 (patch)
tree75cd5e62b7a46f7562c37d26637c4d222f81552a /src
parentd3c5ce976e1abf0ae6791fb45b8713b16f031918 (diff)
yaml: invalidFieldCombinations value matching
Diffstat (limited to 'src')
-rw-r--r--src/data/yaml.js51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 9a0295b8..9788f19f 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -87,7 +87,7 @@ function makeProcessDocument(thingConstructor, {
   //   ]
   //
   // ...means A can't coexist with B or C, B can't coexist with A or C, and
-  // C can't coexist iwth A, B, or D - but it's okay for D to coexist with
+  // C can't coexist with A, B, or D - but it's okay for D to coexist with
   // A or B.
   //
   invalidFieldCombinations = [],
@@ -182,9 +182,22 @@ function makeProcessDocument(thingConstructor, {
 
     const fieldCombinationErrors = [];
 
-    for (const {message, fields} of invalidFieldCombinations) {
+    for (const {message, fields: fieldsSpec} of invalidFieldCombinations) {
       const fieldsPresent =
-        presentFields.filter(field => fields.includes(field));
+        fieldsSpec.flatMap(fieldSpec => {
+          if (Array.isArray(fieldSpec)) {
+            const [field, match] = fieldSpec;
+            if (!presentFields.includes(field)) return [];
+            if (typeof match === 'function') {
+              return match(document[field]) ? [field] : [];
+            } else {
+              return document[field] === match ? [field] : [];
+            }
+          }
+
+          const field = fieldSpec;
+          return presentFields.includes(field) ? [field] : [];
+        });
 
       if (fieldsPresent.length >= 2) {
         const filteredDocument =
@@ -194,7 +207,10 @@ function makeProcessDocument(thingConstructor, {
             {preserveOriginalOrder: true});
 
         fieldCombinationErrors.push(
-          new FieldCombinationError(filteredDocument, message));
+          new FieldCombinationError(
+            filteredDocument,
+            fieldsSpec,
+            message));
 
         for (const field of Object.keys(filteredDocument)) {
           skippedFields.add(field);
@@ -416,19 +432,36 @@ export class FieldCombinationAggregateError extends AggregateError {
 }
 
 export class FieldCombinationError extends Error {
-  constructor(fields, message) {
-    const fieldNames = Object.keys(fields);
+  constructor(filteredDocument, fieldsSpec, message) {
+    const fieldNames = Object.keys(filteredDocument);
 
     const fieldNamesText =
       fieldNames
-        .map(field => colors.red(field))
+        .map(field => {
+          if (fieldsSpec.includes(field)) {
+            return colors.red(field);
+          }
+
+          const match =
+            fieldsSpec
+              .find(fieldSpec =>
+                Array.isArray(fieldSpec) &&
+                fieldSpec[0] === field)
+              .at(1);
+
+          if (typeof match === 'function') {
+            return colors.red(`${field}: ${filteredDocument[field]}`);
+          } else {
+            return colors.red(`${field}: ${match}`);
+          }
+        })
         .join(', ');
 
     const mainMessage = `Don't combine ${fieldNamesText}`;
 
     const causeMessage =
       (typeof message === 'function'
-        ? message(fields)
+        ? message(filteredFields)
      : typeof message === 'string'
         ? message
         : null);
@@ -440,7 +473,7 @@ export class FieldCombinationError extends Error {
           : null),
     });
 
-    this.fields = fields;
+    this.fields = fieldNames;
   }
 }