« get me outta code hell

new validateProperties util, port contribs to it - 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>2022-05-12 19:02:53 -0300
committer(quasar) nebula <qznebula@protonmail.com>2022-05-12 19:02:53 -0300
commitfca61e36a67ef3d6578c9bb5c5f121e9b8ed8987 (patch)
tree402f59bd68450425d5fefbfa3ef8a7a429607569
parenta453db3ee0152ecf3c70dce5fae516b80a9eb014 (diff)
new validateProperties util, port contribs to it
-rw-r--r--src/data/validators.js45
1 files changed, 36 insertions, 9 deletions
diff --git a/src/data/validators.js b/src/data/validators.js
index 1ac8c33..c0e41c9 100644
--- a/src/data/validators.js
+++ b/src/data/validators.js
@@ -192,19 +192,46 @@ export function isCommentary(commentary) {
 
 const isArtistRef = validateReference('artist');
 
-export function isContribution(contrib) {
-    // TODO: Use better object validation for this (supporting aggregates etc)
+export function validateProperties(spec) {
+    const specEntries = Object.entries(spec);
+    const specKeys = Object.keys(spec);
+
+    return object => {
+        isObject(object);
+
+        if (Array.isArray(object))
+            throw new TypeError(`Expected an object, got array`);
+
+        withAggregate({message: `Errors validating object properties`}, ({ call }) => {
+            for (const [ specKey, specValidator ] of specEntries) {
+                call(() => {
+                    const value = object[specKey];
+                    try {
+                        specValidator(value);
+                    } catch (error) {
+                        error.message = `(key: ${color.green(specKey)}, value: ${inspect(value)}) ${error.message}`;
+                        throw error;
+                    }
+                });
+            }
 
-    isObject(contrib);
+            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(', ')}]`);
+                });
+            }
+        });
 
-    isArtistRef(contrib.who);
+        return true;
+    };
+}
 
-    if (contrib.what !== null) {
-        isStringNonEmpty(contrib.what);
-    }
 
-    return true;
-}
+export const isContribution = validateProperties({
+    who: isArtistRef,
+    what: value => value === undefined || value === null || isStringNonEmpty(value),
+});
 
 export const isContributionList = validateArrayItems(isContribution);