« get me outta code hell

validators: validateProperties: allow or validate other properties - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-01-03 17:37:22 -0400
committer(quasar) nebula <qznebula@protonmail.com>2024-01-03 19:25:58 -0400
commitf2accf775dd711cef9e212c05a0c58a5bcdd320d (patch)
treed57efb8a09a50a8fea2cbfae7ee3f8327e415b76
parentf043a0ca4c20237026abdc30d14c298c124dfec3 (diff)
validators: validateProperties: allow or validate other properties
-rw-r--r--src/data/things/validators.js41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/data/things/validators.js b/src/data/things/validators.js
index 8c2a96e4..939d78d5 100644
--- a/src/data/things/validators.js
+++ b/src/data/things/validators.js
@@ -363,24 +363,34 @@ export function validateProperties(spec) {
     if (Array.isArray(object))
       throw new TypeError(`Expected an object, got array`);
 
-    withAggregate({message: `Errors validating object properties`}, ({call}) => {
+    withAggregate({message: `Errors validating object properties`}, ({push}) => {
       for (const [specKey, specValidator] of specEntries) {
-        call(() => {
-          const value = object[specKey];
-          try {
-            specValidator(value);
-          } catch (error) {
-            error.message = `(key: ${colors.green(specKey)}, value: ${inspect(value)}) ${error.message}`;
-            throw error;
-          }
-        });
+        const value = object[specKey];
+        try {
+          specValidator(value);
+        } catch (error) {
+          error.message = `(key: ${colors.green(specKey)}, value: ${inspect(value)}) ${error.message}`;
+          push(error);
+        }
       }
 
       const unknownKeys = Object.keys(object).filter((key) => !specKeys.includes(key));
-      if (unknownKeys.length > 0) {
-        call(() => {
-          throw new Error(`Unknown keys present (${unknownKeys.length}): [${unknownKeys.join(', ')}]`);
-        });
+      if (!empty(unknownKeys)) {
+        if (spec[validateProperties.validateOtherKeys]) {
+          const specValidator = spec[validateProperties.validateOtherKeys];
+          for (const key of unknownKeys) {
+            const value = object[key];
+            try {
+              specValidator(value);
+            } catch (error) {
+              error.message = `(key: ${colors.green(key)}, value: ${inspect(value)}) ${error.message}`;
+              push(error);
+            }
+          }
+        } else if (!spec[validateProperties.allowOtherKeys]) {
+          push(new Error(
+            `Unknown keys present (${unknownKeys.length}): [${unknownKeys.join(', ')}]`));
+        }
       }
     });
 
@@ -388,6 +398,9 @@ export function validateProperties(spec) {
   };
 }
 
+validateProperties.validateOtherKeys = Symbol();
+validateProperties.allowOtherKeys = Symbol();
+
 export function validateAllPropertyValues(validator) {
   return (object) => {
     isObject(object);