UNPKG

@mapbox/mapbox-gl-style-spec

Version:

a specification for mapbox gl styles

91 lines (78 loc) 3.36 kB
import {default as ValidationError, ValidationWarning} from '../error/validation_error'; import {getType, isObject} from '../util/get_type'; import validateSpec from './validate'; import type {StyleReference} from '../reference/latest'; import type {StyleSpecification, LayerSpecification} from '../types'; type ObjectElementValidatorOptions = { key: string; value: unknown; valueSpec?: unknown; style: Partial<StyleSpecification>; styleSpec: StyleReference; object?: object; objectKey?: string; }; type ObjectValidatorOptions = { key: string; value: unknown; valueSpec?: object; style: Partial<StyleSpecification>; styleSpec: StyleReference; object?: object; objectKey?: string; layer?: LayerSpecification; objectElementValidators?: Record<string, (options: ObjectElementValidatorOptions) => ValidationError[]>; }; export default function validateObject(options: ObjectValidatorOptions): ValidationError[] { const key = options.key; const object = options.value; const elementSpecs = options.valueSpec || {}; const elementValidators = options.objectElementValidators || {}; const style = options.style; const styleSpec = options.styleSpec; if (!isObject(object)) { return [new ValidationError(key, object, `object expected, ${getType(object)} found`)]; } let errors: ValidationError[] = []; for (const objectKey in object) { const elementSpecKey = objectKey.split('.')[0]; // treat 'paint.*' as 'paint' // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const elementSpec = elementSpecs[elementSpecKey] || elementSpecs['*']; let validateElement; if (elementValidators[elementSpecKey]) { validateElement = elementValidators[elementSpecKey]; } else if (elementSpecs[elementSpecKey]) { validateElement = validateSpec; } else if (elementValidators['*']) { validateElement = elementValidators['*']; } else if (elementSpecs['*']) { validateElement = validateSpec; } if (!validateElement) { errors.push(new ValidationWarning(key, object[objectKey], `unknown property "${objectKey}"`)); continue; } // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call errors = errors.concat(validateElement({ key: (key ? `${key}.` : key) + objectKey, value: object[objectKey], // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment valueSpec: elementSpec, style, styleSpec, object, objectKey }, object)); } for (const elementSpecKey in elementSpecs) { // Don't check `required` when there's a custom validator for that property. if (elementValidators[elementSpecKey]) { continue; } // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access if (elementSpecs[elementSpecKey].required && elementSpecs[elementSpecKey]['default'] === undefined && object[elementSpecKey] === undefined) { errors.push(new ValidationError(key, object, `missing required property "${elementSpecKey}"`)); } } return errors; }