« get me outta code hell

yaml, data: store document specs statically on Thing subclasses - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/thing.js
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-01-20 16:13:36 -0400
committer(quasar) nebula <qznebula@protonmail.com>2024-01-30 07:59:34 -0400
commit296a4961a951e44ea53509391ad225d1491197f9 (patch)
tree4bdedf0f85b7af8d3039bb46ccfd2f1f600db5ce /src/data/things/thing.js
parentac277f23abe0d8432a94f72913f4421b0eebaa62 (diff)
yaml, data: store document specs statically on Thing subclasses
Diffstat (limited to 'src/data/things/thing.js')
-rw-r--r--src/data/things/thing.js42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/data/things/thing.js b/src/data/things/thing.js
index def7e91..42971c0 100644
--- a/src/data/things/thing.js
+++ b/src/data/things/thing.js
@@ -14,6 +14,8 @@ export default class Thing extends CacheableObject {
   static getPropertyDescriptors = Symbol('Thing.getPropertyDescriptors');
   static getSerializeDescriptors = Symbol('Thing.getSerializeDescriptors');
 
+  static yamlDocumentSpec = Symbol.for('Thing.yamlDocumentSpec');
+
   // Default custom inspect function, which may be overridden by Thing
   // subclasses. This will be used when displaying aggregate errors and other
   // command-line logging - it's the place to provide information useful in
@@ -38,4 +40,44 @@ export default class Thing extends CacheableObject {
 
     return `${thing.constructor[Thing.referenceType]}:${thing.directory}`;
   }
+
+  static extendDocumentSpec(thingClass, subspec) {
+    const superspec = thingClass[Thing.yamlDocumentSpec];
+
+    const {
+      fieldTransformations,
+      propertyFieldMapping,
+      ignoredFields,
+      invalidFieldCombinations,
+      ...restOfSubspec
+    } = subspec;
+
+    const newFields =
+      Object.values(subspec.propertyFieldMapping ?? {});
+
+    return {
+      ...superspec,
+      ...restOfSubspec,
+
+      fieldTransformations: {
+        ...superspec.fieldTransformations,
+        ...fieldTransformations,
+      },
+
+      propertyFieldMapping: {
+        ...superspec.propertyFieldMapping,
+        ...propertyFieldMapping,
+      },
+
+      ignoredFields:
+        (superspec.ignoredFields ?? [])
+          .filter(field => newFields.includes(field))
+          .concat(ignoredFields ?? []),
+
+      invalidFieldCombinations: [
+        ...superspec.invalidFieldCombinations ?? [],
+        ...invalidFieldCombinations ?? [],
+      ],
+    };
+  }
 }