Validate block states

This commit is contained in:
Misode
2020-12-20 04:25:50 +01:00
parent 394dd27d85
commit a52716a80a
8 changed files with 159 additions and 29 deletions

View File

@@ -0,0 +1,36 @@
import { Errors, Hook, relativePath } from '@mcschema/core'
import { BlockStateRegistry } from '../App'
import { walk } from './walk'
export const customValidation: Hook<[any, Errors], void> = walk<[Errors]>({
base() {},
boolean() {},
choice() {},
list() {},
map({ config }, path, value) {
if (config.validation?.validator === 'block_state_map') {
const block = relativePath(path, config.validation.params.id).get()
const errors = path.getModel().errors
const requiredProps = BlockStateRegistry[block].properties ?? {}
const existingKeys = Object.keys(value ?? {})
Object.keys(requiredProps).forEach(p => {
if (!existingKeys.includes(p)) {
errors.add(path, 'error.block_state.missing_property', p)
} else if (!requiredProps[p].includes(value[p])) {
errors.add(path.push(p), 'error.invalid_enum_option', value[p])
}
})
}
},
number() {},
object() {},
string() {}
})

39
src/app/hooks/walk.ts Normal file
View File

@@ -0,0 +1,39 @@
import { Hook } from '@mcschema/core'
type Args = any[]
export const walk = <U extends Args> (hook: Hook<[any, ...U], void>): Hook<[any, ...U], void> => ({
...hook,
choice(params, path, value, ...args) {
hook.choice(params, path, value, ...args)
params.switchNode.hook(this, path, value, ...args)
},
list(params, path, value, ...args) {
hook.list(params, path, value, ...args)
if (!Array.isArray(value)) return
value.forEach((e, i) =>
params.children.hook(this, path.push(i), value, ...args)
)
},
map(params, path, value, ...args) {
hook.map(params, path, value, ...args)
if (typeof value !== 'object') return
Object.keys(value).forEach(f =>
params.children.hook(this, path.push(f), value[f], ...args)
)
},
object(params, path, value, ...args) {
hook.object(params, path, value, ...args)
if (value === null || typeof value !== 'object') return
const activeFields = params.getActiveFields(path)
Object.keys(activeFields)
.filter(f => activeFields[f].enabled(path))
.forEach(f => {
activeFields[f].hook(this, path.push(f), value[f], ...args)
})
}
})