« get me outta code hell

data: WIP input validation - 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>2023-09-23 22:15:06 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-09-23 22:15:19 -0300
commite304bebf19340b825df10a17315b534f5dca0219 (patch)
treea2e5f640820702190714604316615d5298462820
parentb4137b02f09761b78c520e5514381cda714dcf6d (diff)
data: WIP input validation
Static only, as of this commit.
-rw-r--r--src/data/things/composite.js55
1 files changed, 54 insertions, 1 deletions
diff --git a/src/data/things/composite.js b/src/data/things/composite.js
index 791b836..27b345c 100644
--- a/src/data/things/composite.js
+++ b/src/data/things/composite.js
@@ -548,7 +548,12 @@ export function templateCompositeFrom(description) {
         });
 
     const wrongTypeInputNames = [];
-    const wrongInputCallInputNames = [];
+
+    const expectedStaticValueInputNames = [];
+    const expectedStaticDependencyInputNames = [];
+
+    const validateFailedInputNames = [];
+    const validateFailedErrors = [];
 
     for (const [name, value] of Object.entries(inputOptions)) {
       if (misplacedInputNames.includes(name)) {
@@ -559,6 +564,37 @@ export function templateCompositeFrom(description) {
         wrongTypeInputNames.push(name);
         continue;
       }
+
+      const descriptionShape = getInputTokenShape(description.inputs[name]);
+      const descriptionValue = getInputTokenValue(description.inputs[name]);
+
+      const tokenShape = (isInputToken(value) ? getInputTokenShape(value) : null);
+      const tokenValue = (isInputToken(value) ? getInputTokenValue(value) : null);
+
+      if (descriptionShape === 'input.staticValue') {
+        if (tokenShape !== 'input.value') {
+          expectedStaticValueInputNames.push(name);
+          continue;
+        }
+      }
+
+      if (descriptionShape === 'input.staticDependency') {
+        if (typeof value !== 'string' && tokenShape !== 'input.dependency') {
+          expectedStaticDependencyInputNames.push(name);
+          continue;
+        }
+      }
+
+      if (descriptionValue && 'validate' in descriptionValue) {
+        if (tokenShape === 'input.value') {
+          try {
+            descriptionValue.validate(tokenValue);
+          } catch (error) {
+            validateFailedInputNames.push(name);
+            validateFailedErrors.push(error);
+          }
+        }
+      }
     }
 
     if (!empty(misplacedInputNames)) {
@@ -569,6 +605,23 @@ export function templateCompositeFrom(description) {
       inputOptionsAggregate.push(new Error(`Required these inputs: ${missingInputNames.join(', ')}`));
     }
 
+    if (!empty(expectedStaticDependencyInputNames)) {
+      inputOptionsAggregate.push(new Error(`Expected static dependencies: ${expectedStaticDependencyInputNames.join(', ')}`));
+    }
+
+    if (!empty(expectedStaticValueInputNames)) {
+      inputOptionsAggregate.push(new Error(`Expected static values: ${expectedStaticValueInputNames.join(', ')}`));
+    }
+
+    for (const {name, validationError} of stitchArrays({
+      name: validateFailedInputNames,
+      validationError: validateFailedErrors,
+    })) {
+      const error = new Error(`${name}: Validation failed for static value`);
+      error.cause = validationError;
+      inputOptionsAggregate.push(error);
+    }
+
     for (const name of wrongTypeInputNames) {
       const type = typeof inputOptions[name];
       inputOptionsAggregate.push(new Error(`${name}: Expected string or input() call, got ${type}`));