2023-02-11 16:45:00 -06:00
|
|
|
import { defaultGist } from 'shared/components/workbench/gist.mjs'
|
2022-12-14 16:37:17 -06:00
|
|
|
|
2022-12-16 11:58:39 -06:00
|
|
|
/** A utility for validating a gist against a design */
|
2022-12-14 16:37:17 -06:00
|
|
|
class GistValidator {
|
|
|
|
givenGist
|
|
|
|
design
|
|
|
|
errors
|
|
|
|
valid = true
|
|
|
|
|
2022-12-22 11:46:26 -06:00
|
|
|
setGist(givenGist, design) {
|
2022-12-14 16:37:17 -06:00
|
|
|
this.givenGist = givenGist
|
|
|
|
this.design = design
|
|
|
|
this.errors = {}
|
2022-12-22 11:46:26 -06:00
|
|
|
this.valid = true
|
2022-12-14 16:37:17 -06:00
|
|
|
}
|
|
|
|
|
2022-12-16 11:58:39 -06:00
|
|
|
/** check that the settings all exist and are all of the right type */
|
2022-12-14 16:37:17 -06:00
|
|
|
validateSettings() {
|
2023-02-11 16:45:00 -06:00
|
|
|
for (const key in defaultGist) {
|
2022-12-16 11:58:39 -06:00
|
|
|
if (this.givenGist[key] === undefined) {
|
|
|
|
this.errors[key] = 'MissingSetting'
|
|
|
|
this.valid = false
|
2023-02-11 16:45:00 -06:00
|
|
|
} else if (typeof this.givenGist[key] !== typeof defaultGist[key]) {
|
2022-12-14 16:37:17 -06:00
|
|
|
this.errors[key] = 'TypeError'
|
|
|
|
this.valid = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-16 11:58:39 -06:00
|
|
|
/** check that the required measurements are all there and the correct type */
|
2022-12-14 16:37:17 -06:00
|
|
|
validateMeasurements() {
|
2022-12-16 11:58:39 -06:00
|
|
|
if (!this.givenGist.measurements) {
|
|
|
|
this.errors.measurements = 'MissingMeasurements'
|
|
|
|
this.valid = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-12-14 16:37:17 -06:00
|
|
|
this.errors.measurements = {}
|
|
|
|
for (const m of this.design.patternConfig.measurements || []) {
|
|
|
|
if (this.givenGist.measurements[m] === undefined) {
|
|
|
|
this.errors.measurements[m] = 'MissingMeasurement'
|
|
|
|
this.valid = false
|
|
|
|
} else if (isNaN(this.givenGist.measurements[m])) {
|
|
|
|
this.errors.measurements[m] = 'TypeError'
|
|
|
|
this.valid = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-16 11:58:39 -06:00
|
|
|
/** check validit of any options that are included */
|
2022-12-14 16:37:17 -06:00
|
|
|
validateOptions() {
|
2022-12-15 19:27:05 -06:00
|
|
|
this.errors.options = {}
|
|
|
|
const configOpts = this.design.patternConfig.options
|
|
|
|
const gistOpts = this.givenGist.options
|
|
|
|
for (const o in gistOpts) {
|
|
|
|
const configOpt = configOpts[o]
|
|
|
|
const gistOpt = gistOpts[o]
|
2022-12-16 11:58:39 -06:00
|
|
|
// if the option doesn't exist on the pattern
|
2022-12-15 19:27:05 -06:00
|
|
|
if (!configOpt) {
|
|
|
|
this.errors.options[o] = 'UnknownOption'
|
|
|
|
}
|
|
|
|
// if it's a constant option, mark that it can't be overwritten
|
|
|
|
else if (typeof configOpt !== 'object') {
|
|
|
|
this.errors.options[o] = 'ConstantOption'
|
|
|
|
}
|
|
|
|
// if it's a list option but the selection isn't in the list, mark it an unknown selection
|
|
|
|
else if (configOpt.list !== undefined) {
|
|
|
|
if (!configOpt.list.includes(gistOpt) && gistOpt != configOpt.dflt)
|
|
|
|
this.error.options[o] = 'UnknownOptionSelection'
|
|
|
|
}
|
|
|
|
// if it's a boolean option but the gist value isn't a boolean. mark a type error
|
|
|
|
else if (configOpts[o].bool !== undefined) {
|
|
|
|
if (typeof gistOpt !== 'boolean') this.errors.options[o] = 'TypeError'
|
|
|
|
}
|
|
|
|
// all other options are numbers, so check it's a number
|
|
|
|
else if (isNaN(gistOpt)) {
|
|
|
|
this.errors.options[o] = 'TypeError'
|
|
|
|
}
|
|
|
|
// if still no error, check the bounds
|
|
|
|
else {
|
|
|
|
const checkNum = configOpt.pct ? gistOpt * 100 : gistOpt
|
|
|
|
if (checkNum < configOpt.min || checkNum > configOpt.max) {
|
|
|
|
this.errors.options[o] = 'RangeError'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.errors.options[o]) this.valid = false
|
|
|
|
}
|
2022-12-14 16:37:17 -06:00
|
|
|
}
|
|
|
|
|
2022-12-16 11:58:39 -06:00
|
|
|
/** run all validations */
|
2022-12-14 16:37:17 -06:00
|
|
|
validate() {
|
|
|
|
this.validateSettings()
|
|
|
|
this.validateMeasurements()
|
|
|
|
this.validateOptions()
|
|
|
|
|
|
|
|
return { valid: this.valid, errors: this.errors }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-22 11:46:26 -06:00
|
|
|
const validator = new GistValidator()
|
|
|
|
|
2022-12-16 11:58:39 -06:00
|
|
|
/** make and run a gist validator */
|
2023-02-11 16:45:00 -06:00
|
|
|
export function validateGist(givenGist, design) {
|
2022-12-22 11:46:26 -06:00
|
|
|
validator.setGist(givenGist, design)
|
2022-12-14 16:37:17 -06:00
|
|
|
return validator.validate()
|
|
|
|
}
|