« get me outta code hell

AdditionalFile.js « additional-file « things « data « src - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/additional-file/AdditionalFile.js
blob: d137c7413a3413f25b81cefc2c9c8ad08b3d417a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import {inspect} from 'node:util';

import {colors} from '#cli';
import {input, V} from '#composite';
import Thing from '#thing';
import {isString, validateArrayItems} from '#validators';
import {parseContributors} from '#yaml';

import {exposeConstant, exposeUpdateValueOrContinue}
  from '#composite/control-flow';
import {contributionList, contentString, simpleString, soupyFind, thing}
  from '#composite/wiki-properties';

export class AdditionalFile extends Thing {
  static [Thing.friendlyName] = `Additional File`;

  static [Thing.getPropertyDescriptors] = () => ({
    // Update & expose

    thing: thing(),

    title: simpleString(),

    description: contentString(),

    folder: simpleString(),

    filenames: [
      exposeUpdateValueOrContinue({
        validate: input.value(validateArrayItems(isString)),
      }),

      exposeConstant(V([])),
    ],

    artistContribs: contributionList({
      // Subclasses override with the relevant artistProperty.
      artistProperty: input.value(null),
    }),

    // Update only

    find: soupyFind(),

    // Expose only

    isAdditionalFile: exposeConstant(V(true)),

    // The date property is generally expected by contributions.
    // Additional files don't actually support dates, but provide a null
    // value for convenience.
    date: {
      flags: {expose: true},
      expose: {compute: () => null},
    },
  });

  static [Thing.yamlDocumentSpec] = {
    fields: {
      'Title': {property: 'title'},
      'Description': {property: 'description'},

      'Artists': {
        property: 'artistContribs',
        transform: parseContributors,
      },

      'Folder': {property: 'folder'},
      'Files': {property: 'filenames'},
    },
  };

  get paths() {
    if (!this.thing) return null;
    if (!this.thing.getOwnAdditionalFilePath) return null;

    return (
      this.filenames.map(filename =>
        this.thing.getOwnAdditionalFilePath(this, filename)));
  }

  [inspect.custom](depth, options, inspect) {
    const parts = [];

    parts.push(this.constructor.name);

    if (this.title) {
      parts.push(` ${colors.green(`"${this.title}"`)}`);
    }

    if (this.thing) {
      if (depth >= 0) {
        const newOptions = {
          ...options,
          depth:
            (options.depth === null
              ? null
              : options.depth - 1),
        };

        parts.push(` for ${inspect(this.thing, newOptions)}`);
      } else {
        parts.push(` for ${colors.blue(Thing.inspectReference(this.thing))}`);
      }
    }

    return parts.join('');
  }
}