From fca61e36a67ef3d6578c9bb5c5f121e9b8ed8987 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 12 May 2022 19:02:53 -0300 Subject: new validateProperties util, port contribs to it --- src/data/validators.js | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/data/validators.js b/src/data/validators.js index 1ac8c33..c0e41c9 100644 --- a/src/data/validators.js +++ b/src/data/validators.js @@ -192,19 +192,46 @@ export function isCommentary(commentary) { const isArtistRef = validateReference('artist'); -export function isContribution(contrib) { - // TODO: Use better object validation for this (supporting aggregates etc) +export function validateProperties(spec) { + const specEntries = Object.entries(spec); + const specKeys = Object.keys(spec); + + return object => { + isObject(object); + + if (Array.isArray(object)) + throw new TypeError(`Expected an object, got array`); + + withAggregate({message: `Errors validating object properties`}, ({ call }) => { + for (const [ specKey, specValidator ] of specEntries) { + call(() => { + const value = object[specKey]; + try { + specValidator(value); + } catch (error) { + error.message = `(key: ${color.green(specKey)}, value: ${inspect(value)}) ${error.message}`; + throw error; + } + }); + } - isObject(contrib); + const unknownKeys = Object.keys(object).filter(key => !specKeys.includes(key)); + if (unknownKeys.length > 0) { + call(() => { + throw new Error(`Unknown keys present (${unknownKeys.length}): [${unknownKeys.join(', ')}]`); + }); + } + }); - isArtistRef(contrib.who); + return true; + }; +} - if (contrib.what !== null) { - isStringNonEmpty(contrib.what); - } - return true; -} +export const isContribution = validateProperties({ + who: isArtistRef, + what: value => value === undefined || value === null || isStringNonEmpty(value), +}); export const isContributionList = validateArrayItems(isContribution); -- cgit 1.3.0-6-gf8a5