diff options
Diffstat (limited to 'src/data/things')
-rw-r--r-- | src/data/things/album.js | 24 | ||||
-rw-r--r-- | src/data/things/artist.js | 5 | ||||
-rw-r--r-- | src/data/things/homepage-layout.js | 4 | ||||
-rw-r--r-- | src/data/things/language.js | 6 | ||||
-rw-r--r-- | src/data/things/thing.js | 16 | ||||
-rw-r--r-- | src/data/things/validators.js | 49 |
6 files changed, 72 insertions, 32 deletions
diff --git a/src/data/things/album.js b/src/data/things/album.js index 2a188f2d..d371f51f 100644 --- a/src/data/things/album.js +++ b/src/data/things/album.js @@ -1,5 +1,6 @@ import Thing from './thing.js'; +import {empty} from '../../util/sugar.js'; import find from '../../util/find.js'; export class Album extends Thing { @@ -34,12 +35,12 @@ export class Album extends Thing { update: {validate: isDate}, expose: { - dependencies: ['date', 'hasCoverArt'], + dependencies: ['date', 'coverArtistContribsByRef'], transform: (coverArtDate, { + coverArtistContribsByRef, date, - hasCoverArt, }) => - (hasCoverArt + (!empty(coverArtistContribsByRef) ? coverArtDate ?? date ?? null : null), }, @@ -103,7 +104,6 @@ export class Album extends Thing { update: {validate: isDimensions}, }, - hasCoverArt: Thing.common.flag(true), hasTrackArt: Thing.common.flag(true), hasTrackNumbers: Thing.common.flag(true), isListedOnHomepage: Thing.common.flag(true), @@ -123,18 +123,16 @@ export class Album extends Thing { artistContribs: Thing.common.dynamicContribs('artistContribsByRef'), coverArtistContribs: Thing.common.dynamicContribs('coverArtistContribsByRef'), - trackCoverArtistContribs: Thing.common.dynamicContribs( - 'trackCoverArtistContribsByRef' - ), - wallpaperArtistContribs: Thing.common.dynamicContribs( - 'wallpaperArtistContribsByRef' - ), - bannerArtistContribs: Thing.common.dynamicContribs( - 'bannerArtistContribsByRef' - ), + trackCoverArtistContribs: Thing.common.dynamicContribs('trackCoverArtistContribsByRef'), + wallpaperArtistContribs: Thing.common.dynamicContribs('wallpaperArtistContribsByRef'), + bannerArtistContribs: Thing.common.dynamicContribs('bannerArtistContribsByRef'), commentatorArtists: Thing.common.commentatorArtists(), + hasCoverArt: Thing.common.contribsPresent('coverArtistContribsByRef'), + hasWallpaperArt: Thing.common.contribsPresent('wallpaperArtistContribsByRef'), + hasBannerArt: Thing.common.contribsPresent('bannerArtistContribsByRef'), + tracks: { flags: {expose: true}, diff --git a/src/data/things/artist.js b/src/data/things/artist.js index 303f33f3..f144b21f 100644 --- a/src/data/things/artist.js +++ b/src/data/things/artist.js @@ -27,9 +27,8 @@ export class Artist extends Thing { aliasNames: { flags: {update: true, expose: true}, - update: { - validate: validateArrayItems(isName), - }, + update: {validate: validateArrayItems(isName)}, + expose: {transform: (names) => names ?? []}, }, isAlias: Thing.common.flag(), diff --git a/src/data/things/homepage-layout.js b/src/data/things/homepage-layout.js index c18e8110..a79dd77a 100644 --- a/src/data/things/homepage-layout.js +++ b/src/data/things/homepage-layout.js @@ -68,10 +68,10 @@ export class HomepageLayoutAlbumsRow extends HomepageLayoutRow { Group, validators: { + is, isCountingNumber, isString, validateArrayItems, - validateFromConstants, }, } = opts) => ({ ...HomepageLayoutRow[Thing.getPropertyDescriptors](opts), @@ -95,7 +95,7 @@ export class HomepageLayoutAlbumsRow extends HomepageLayoutRow { flags: {update: true, expose: true}, update: { - validate: validateFromConstants('grid', 'carousel'), + validate: is('grid', 'carousel'), }, expose: { diff --git a/src/data/things/language.js b/src/data/things/language.js index 3086ad2e..98ab9bc7 100644 --- a/src/data/things/language.js +++ b/src/data/things/language.js @@ -252,19 +252,19 @@ export class Language extends Thing { // Conjunction list: A, B, and C formatConjunctionList(array) { this.assertIntlAvailable('intl_listConjunction'); - return this.intl_listConjunction.format(array); + return this.intl_listConjunction.format(array.map(arr => arr.toString())); } // Disjunction lists: A, B, or C formatDisjunctionList(array) { this.assertIntlAvailable('intl_listDisjunction'); - return this.intl_listDisjunction.format(array); + return this.intl_listDisjunction.format(array.map(arr => arr.toString())); } // Unit lists: A, B, C formatUnitList(array) { this.assertIntlAvailable('intl_listUnit'); - return this.intl_listUnit.format(array); + return this.intl_listUnit.format(array.map(arr => arr.toString())); } // File sizes: 42.5 kB, 127.2 MB, 4.13 GB, 998.82 TB diff --git a/src/data/things/thing.js b/src/data/things/thing.js index 9c59436e..5004f4e6 100644 --- a/src/data/things/thing.js +++ b/src/data/things/thing.js @@ -23,6 +23,7 @@ import { import {inspect} from 'util'; import {color} from '../../util/cli.js'; +import {empty} from '../../util/sugar.js'; import {getKebabCase} from '../../util/wiki-data.js'; import find from '../../util/find.js'; @@ -63,6 +64,7 @@ export default class Thing extends CacheableObject { urls: () => ({ flags: {update: true, expose: true}, update: {validate: validateArrayItems(isURL)}, + expose: {transform: (value) => value ?? []}, }), // A file extension! Or the default, if provided when calling this. @@ -312,6 +314,20 @@ export default class Thing extends CacheableObject { }, }), + // Nice 'n simple shorthand for an exposed-only flag which is true when any + // contributions are present in the specified property. + contribsPresent: (contribsByRefProperty) => ({ + flags: {expose: true}, + expose: { + dependencies: [contribsByRefProperty], + compute({ + [contribsByRefProperty]: contribsByRef, + }) { + return !empty(contribsByRef); + }, + } + }), + // Neat little shortcut for "reversing" the reference lists stored on other // things - for example, tracks specify a "referenced tracks" property, and // you would use this to compute a corresponding "referenced *by* tracks" diff --git a/src/data/things/validators.js b/src/data/things/validators.js index b116120a..14092102 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -112,7 +112,12 @@ export function isInstance(value, constructor) { } export function isDate(value) { - return isInstance(value, Date); + isInstance(value, Date); + + if (isNaN(value)) + throw new TypeError(`Expected valid date`); + + return true; } export function isObject(value) { @@ -133,6 +138,34 @@ export function isArray(value) { return true; } +// This one's shaped a bit different from other "is" functions. +// More like validate functions, it returns a function. +export function is(...values) { + if (Array.isArray(values)) { + values = new Set(values); + } + + if (values.size === 1) { + const expected = Array.from(values)[0]; + + return (value) => { + if (value !== expected) { + throw new TypeError(`Expected ${expected}, got ${value}`); + } + + return true; + }; + } + + return (value) => { + if (!values.has(value)) { + throw new TypeError(`Expected one of ${Array.from(values).join(' ')}, got ${value}`); + } + + return true; + }; +} + function validateArrayItemsHelper(itemValidator) { return (item, index) => { try { @@ -162,18 +195,12 @@ export function validateArrayItems(itemValidator) { }; } -export function validateInstanceOf(constructor) { - return (object) => isInstance(object, constructor); +export function arrayOf(itemValidator) { + return validateArrayItems(itemValidator); } -export function validateFromConstants(...values) { - return (value) => { - if (!values.includes(value)) { - throw new TypeError(`Expected one of ${values.join(', ')}`); - } - - return true; - }; +export function validateInstanceOf(constructor) { + return (object) => isInstance(object, constructor); } // Wiki data (primitives & non-primitives) |