From b90c2072f1ef8f55ef495bfa3920af4bb482f0cd Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 21 Aug 2023 22:13:08 -0300 Subject: data: valdiateArrayItems: use same index formatting as other errors Specifically, the same as decorateErrorWithIndex. --- src/data/things/validators.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index fc953c2a..5748eacf 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -174,7 +174,7 @@ function validateArrayItemsHelper(itemValidator) { throw new Error(`Expected validator to return true`); } } catch (error) { - error.message = `(index: ${color.green(index)}, item: ${inspect(item)}) ${error.message}`; + error.message = `(index: ${color.yellow(`#${index}`)}, item: ${inspect(item)}) ${error.message}`; throw error; } }; -- cgit 1.3.0-6-gf8a5 From eb00f2993a1aaaba171ad6c918656552f80bb748 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 7 Sep 2023 12:38:34 -0300 Subject: data: import Thing.common utilities directly Also rename 'color' (from #cli) to 'colors'. --- src/data/things/validators.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index 5748eacf..4c8f683b 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -1,6 +1,6 @@ import {inspect as nodeInspect} from 'node:util'; -import {color, ENABLE_COLOR} from '#cli'; +import {colors, ENABLE_COLOR} from '#cli'; import {withAggregate} from '#sugar'; function inspect(value) { @@ -174,7 +174,7 @@ function validateArrayItemsHelper(itemValidator) { throw new Error(`Expected validator to return true`); } } catch (error) { - error.message = `(index: ${color.yellow(`#${index}`)}, item: ${inspect(item)}) ${error.message}`; + error.message = `(index: ${colors.yellow(`#${index}`)}, item: ${inspect(item)}) ${error.message}`; throw error; } }; @@ -264,7 +264,7 @@ export function validateProperties(spec) { try { specValidator(value); } catch (error) { - error.message = `(key: ${color.green(specKey)}, value: ${inspect(value)}) ${error.message}`; + error.message = `(key: ${colors.green(specKey)}, value: ${inspect(value)}) ${error.message}`; throw error; } }); -- cgit 1.3.0-6-gf8a5 From bbccaf51222cb4bed73466164496f5bc1030292c Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 7 Sep 2023 17:30:54 -0300 Subject: data: roll paired "byRef" and "dynamic" properties into one --- src/data/things/validators.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index 4c8f683b..f0d1d9fd 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -308,7 +308,7 @@ export const isTrackSection = validateProperties({ color: optional(isColor), dateOriginallyReleased: optional(isDate), isDefaultTrackSection: optional(isBoolean), - tracksByRef: optional(validateReferenceList('track')), + tracks: optional(validateReferenceList('track')), }); export const isTrackSectionList = validateArrayItems(isTrackSection); -- cgit 1.3.0-6-gf8a5 From 8db50e29b5a1cfddfddf499129b697ecabfadcb0 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 20 Sep 2023 13:01:25 -0300 Subject: data: moar WIP composite syntax! --- src/data/things/validators.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index f0d1d9fd..cd4c2b46 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -9,11 +9,11 @@ function inspect(value) { // Basic types (primitives) -function a(noun) { +export function a(noun) { return /[aeiou]/.test(noun[0]) ? `an ${noun}` : `a ${noun}`; } -function isType(value, type) { +export function isType(value, type) { if (typeof value !== type) throw new TypeError(`Expected ${a(type)}, got ${typeof value}`); -- cgit 1.3.0-6-gf8a5 From b5cfc2a793f22da60606a4dd7387fcf3d3163843 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 25 Sep 2023 14:23:23 -0300 Subject: data: misc. improvements for input validation & infrastructure --- src/data/things/validators.js | 58 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index cd4c2b46..048f7ebb 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -1,7 +1,7 @@ import {inspect as nodeInspect} from 'node:util'; import {colors, ENABLE_COLOR} from '#cli'; -import {withAggregate} from '#sugar'; +import {empty, withAggregate} from '#sugar'; function inspect(value) { return nodeInspect(value, {colors: ENABLE_COLOR}); @@ -404,6 +404,62 @@ export function validateReferenceList(type = '') { return validateArrayItems(validateReference(type)); } +export function validateWikiData({ + referenceType = '', + allowMixedTypes = false, +}) { + if (referenceType && allowMixedTypes) { + throw new TypeError(`Don't specify both referenceType and allowMixedTypes`); + } + + const isArrayOfObjects = validateArrayItems(isObject); + + return (array) => { + isArrayOfObjects(array); + + if (empty(array)) { + return true; + } + + const allRefTypes = + new Set(array.map(object => + object.constructor[Symbol.for('Thing.referenceType')])); + + if (allRefTypes.has(undefined)) { + if (allRefTypes.size === 1) { + throw new TypeError(`Expected array of wiki data objects, got array of other objects`); + } else { + throw new TypeError(`Expected array of wiki data objects, got mixed items`); + } + } + + if (allRefTypes.size > 1) { + if (allowMixedTypes) { + return true; + } + + const types = () => Array.from(allRefTypes).join(', '); + + if (referenceType) { + if (allRefTypes.has(referenceType)) { + allRefTypes.remove(referenceType); + throw new TypeError(`Expected array of only ${referenceType}, also got other types: ${types()}`) + } else { + throw new TypeError(`Expected array of only ${referenceType}, got other types: ${types()}`); + } + } + + throw new TypeError(`Expected array of unmixed reference types, got multiple: ${types()}`); + } + + if (referenceType && !allRefTypes.has(referenceType)) { + throw new TypeError(`Expected array of ${referenceType}, got array of ${allRefTypes[0]}`) + } + + return true; + }; +} + // Compositional utilities export function oneOf(...checks) { -- cgit 1.3.0-6-gf8a5 From 411c053dc4b314b2bc0d58d3899fd796ad0054c2 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 28 Sep 2023 14:11:02 -0300 Subject: data, util: use typeAppearance in more places --- src/data/things/validators.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index 048f7ebb..ba62fb84 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -1,7 +1,7 @@ import {inspect as nodeInspect} from 'node:util'; import {colors, ENABLE_COLOR} from '#cli'; -import {empty, withAggregate} from '#sugar'; +import {empty, typeAppearance, withAggregate} from '#sugar'; function inspect(value) { return nodeInspect(value, {colors: ENABLE_COLOR}); @@ -15,7 +15,7 @@ export function a(noun) { export function isType(value, type) { if (typeof value !== type) - throw new TypeError(`Expected ${a(type)}, got ${typeof value}`); + throw new TypeError(`Expected ${a(type)}, got ${typeAppearance(value)}`); return true; } @@ -132,7 +132,7 @@ export function isObject(value) { export function isArray(value) { if (typeof value !== 'object' || value === null || !Array.isArray(value)) - throw new TypeError(`Expected an array, got ${value}`); + throw new TypeError(`Expected an array, got ${typeAppearance(value)}`); return true; } -- cgit 1.3.0-6-gf8a5 From 6eaa070e5c036ba8cd45f79c16dc2732b40ea480 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 30 Sep 2023 09:14:29 -0300 Subject: data, util: hsmusic.sugar.index -> hsmusic.decorate.indexInSourceArray --- src/data/things/validators.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index ba62fb84..bdb22058 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -174,7 +174,8 @@ function validateArrayItemsHelper(itemValidator) { throw new Error(`Expected validator to return true`); } } catch (error) { - error.message = `(index: ${colors.yellow(`#${index}`)}, item: ${inspect(item)}) ${error.message}`; + error.message = `(index: ${colors.yellow(`${index}`)}, item: ${inspect(item)}) ${error.message}`; + error[Symbol.for('hsmusic.decorate.indexInSourceArray')] = index; throw error; } }; -- cgit 1.3.0-6-gf8a5 From 44e47fb3316c5452d277166215bc7522b404047f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 2 Oct 2023 10:41:42 -0300 Subject: data: custom cache for validateWikiData --- src/data/things/validators.js | 72 ++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 29 deletions(-) (limited to 'src/data/things/validators.js') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index bdb22058..ee301f15 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -405,6 +405,8 @@ export function validateReferenceList(type = '') { return validateArrayItems(validateReference(type)); } +const validateWikiData_cache = {}; + export function validateWikiData({ referenceType = '', allowMixedTypes = false, @@ -413,51 +415,63 @@ export function validateWikiData({ throw new TypeError(`Don't specify both referenceType and allowMixedTypes`); } + validateWikiData_cache[referenceType] ??= {}; + validateWikiData_cache[referenceType][allowMixedTypes] ??= new WeakMap(); + const isArrayOfObjects = validateArrayItems(isObject); return (array) => { - isArrayOfObjects(array); + const subcache = validateWikiData_cache[referenceType][allowMixedTypes]; + if (subcache.has(array)) return subcache.get(array); - if (empty(array)) { - return true; - } + let OK = false; - const allRefTypes = - new Set(array.map(object => - object.constructor[Symbol.for('Thing.referenceType')])); + try { + isArrayOfObjects(array); - if (allRefTypes.has(undefined)) { - if (allRefTypes.size === 1) { - throw new TypeError(`Expected array of wiki data objects, got array of other objects`); - } else { - throw new TypeError(`Expected array of wiki data objects, got mixed items`); + if (empty(array)) { + OK = true; return true; } - } - if (allRefTypes.size > 1) { - if (allowMixedTypes) { - return true; + const allRefTypes = + new Set(array.map(object => + object.constructor[Symbol.for('Thing.referenceType')])); + + if (allRefTypes.has(undefined)) { + if (allRefTypes.size === 1) { + throw new TypeError(`Expected array of wiki data objects, got array of other objects`); + } else { + throw new TypeError(`Expected array of wiki data objects, got mixed items`); + } } - const types = () => Array.from(allRefTypes).join(', '); + if (allRefTypes.size > 1) { + if (allowMixedTypes) { + OK = true; return true; + } - if (referenceType) { - if (allRefTypes.has(referenceType)) { - allRefTypes.remove(referenceType); - throw new TypeError(`Expected array of only ${referenceType}, also got other types: ${types()}`) - } else { - throw new TypeError(`Expected array of only ${referenceType}, got other types: ${types()}`); + const types = () => Array.from(allRefTypes).join(', '); + + if (referenceType) { + if (allRefTypes.has(referenceType)) { + allRefTypes.remove(referenceType); + throw new TypeError(`Expected array of only ${referenceType}, also got other types: ${types()}`) + } else { + throw new TypeError(`Expected array of only ${referenceType}, got other types: ${types()}`); + } } + + throw new TypeError(`Expected array of unmixed reference types, got multiple: ${types()}`); } - throw new TypeError(`Expected array of unmixed reference types, got multiple: ${types()}`); - } + if (referenceType && !allRefTypes.has(referenceType)) { + throw new TypeError(`Expected array of ${referenceType}, got array of ${allRefTypes[0]}`) + } - if (referenceType && !allRefTypes.has(referenceType)) { - throw new TypeError(`Expected array of ${referenceType}, got array of ${allRefTypes[0]}`) + OK = true; return true; + } finally { + subcache.set(array, OK); } - - return true; }; } -- cgit 1.3.0-6-gf8a5