diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/data/validators.js | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/src/data/validators.js b/src/data/validators.js index 1ac8c336..c0e41c98 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); |