From db054be170faa6146759cce20b18f242d89dfdcf Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 4 Mar 2024 13:34:56 -0400 Subject: data: transparent basic Contribution objects --- src/data/things/contribution.js | 97 +++++++++++++++++++++++++++++++++++++++++ src/data/things/index.js | 2 + 2 files changed, 99 insertions(+) create mode 100644 src/data/things/contribution.js (limited to 'src/data/things') diff --git a/src/data/things/contribution.js b/src/data/things/contribution.js new file mode 100644 index 00000000..dc7f2157 --- /dev/null +++ b/src/data/things/contribution.js @@ -0,0 +1,97 @@ +import {inspect} from 'node:util'; + +import CacheableObject from '#cacheable-object'; +import {colors} from '#cli'; +import {input} from '#composite'; +import {empty} from '#sugar'; +import Thing from '#thing'; +import {isStringNonEmpty, isThing, validateReference} from '#validators'; + +import {exposeDependency} from '#composite/control-flow'; +import {withResolvedReference} from '#composite/wiki-data'; + +import {withContributionArtist} from '#composite/things/contribution'; + +export class Contribution extends Thing { + static [Thing.getPropertyDescriptors] = () => ({ + // Update & expose + + thing: { + flags: {update: true, expose: true}, + update: {validate: isThing}, + }, + + artist: [ + withContributionArtist({ + ref: input.updateValue({ + validate: validateReference('artist'), + }), + }), + + exposeDependency({ + dependency: '#artist', + }), + ], + + annotation: { + flags: {update: true, expose: true}, + update: {validate: isStringNonEmpty}, + }, + }); + + [inspect.custom](depth, options, inspect) { + const parts = []; + const accentParts = []; + + parts.push(Thing.prototype[inspect.custom].apply(this)); + + if (this.annotation) { + accentParts.push(colors.green(`"${this.annotation}"`)); + } + + let artistRef; + if (depth >= 0) { + let artist; + try { + artist = this.artist; + } catch (_error) { + // Computing artist might crash for any reason - don't distract from + // other errors as a result of inspecting this contribution. + } + + if (artist) { + artistRef = + colors.blue(Thing.getReference(artist)); + } + } else { + artistRef = + colors.green(CacheableObject.getUpdateValue(this, 'artist')); + } + + if (artistRef) { + accentParts.push(`by ${artistRef}`); + } + + if (this.thing) { + if (depth >= 0) { + const newOptions = { + ...options, + depth: + (options.depth === null + ? null + : options.depth - 1), + }; + + accentParts.push(`to ${inspect(this.thing, newOptions)}`); + } else { + accentParts.push(`to ${colors.blue(Thing.getReference(this.thing))}`); + } + } + + if (!empty(accentParts)) { + parts.push(` (${accentParts.join(', ')})`); + } + + return parts.join(''); + } +} diff --git a/src/data/things/index.js b/src/data/things/index.js index 4f87f492..f18e283a 100644 --- a/src/data/things/index.js +++ b/src/data/things/index.js @@ -11,6 +11,7 @@ import Thing from '#thing'; import * as albumClasses from './album.js'; import * as artTagClasses from './art-tag.js'; import * as artistClasses from './artist.js'; +import * as contributionClasses from './contribution.js'; import * as flashClasses from './flash.js'; import * as groupClasses from './group.js'; import * as homepageLayoutClasses from './homepage-layout.js'; @@ -24,6 +25,7 @@ const allClassLists = { 'album.js': albumClasses, 'art-tag.js': artTagClasses, 'artist.js': artistClasses, + 'contribution.js': contributionClasses, 'flash.js': flashClasses, 'group.js': groupClasses, 'homepage-layout.js': homepageLayoutClasses, -- cgit 1.3.0-6-gf8a5