import ValidationError from '../error/validation_error'; import {unbundle} from '../util/unbundle_jsonlint'; import validateObject from './validate_object'; import validateEnum from './validate_enum'; import validateExpression from './validate_expression'; import validateString from './validate_string'; import getType from '../util/get_type'; import validateRasterDEMSource from './validate_raster_dem_source'; const objectElementValidators = { promoteId: validatePromoteId }; export default function validateSource(options) { const value = options.value; const key = options.key; const styleSpec = options.styleSpec; const style = options.style; const validateSpec = options.validateSpec; if (!value.type) { return [new ValidationError(key, value, '"type" is required')]; } const type = unbundle(value.type); let errors; switch (type) { case 'vector': case 'raster': errors = validateObject({ key, value, valueSpec: styleSpec[`source_${type.replace('-', '_')}`], style: options.style, styleSpec, objectElementValidators, validateSpec, }); return errors; case 'raster-dem': errors = validateRasterDEMSource({ sourceName: key, value, style: options.style, styleSpec, validateSpec, }); return errors; case 'geojson': errors = validateObject({ key, value, valueSpec: styleSpec.source_geojson, style, styleSpec, validateSpec, objectElementValidators }); if (value.cluster) { for (const prop in value.clusterProperties) { const [operator, mapExpr] = value.clusterProperties[prop]; const reduceExpr = typeof operator === 'string' ? [operator, ['accumulated'], ['get', prop]] : operator; errors.push(...validateExpression({ key: `${key}.${prop}.map`, value: mapExpr, validateSpec, expressionContext: 'cluster-map' })); errors.push(...validateExpression({ key: `${key}.${prop}.reduce`, value: reduceExpr, validateSpec, expressionContext: 'cluster-reduce' })); } } return errors; case 'video': return validateObject({ key, value, valueSpec: styleSpec.source_video, style, validateSpec, styleSpec }); case 'image': return validateObject({ key, value, valueSpec: styleSpec.source_image, style, validateSpec, styleSpec }); case 'canvas': return [new ValidationError(key, null, 'Please use runtime APIs to add canvas sources, rather than including them in stylesheets.', 'source.canvas')]; default: return validateEnum({ key: `${key}.type`, value: value.type, valueSpec: {values: ['vector', 'raster', 'raster-dem', 'geojson', 'video', 'image']}, style, validateSpec, styleSpec }); } } function validatePromoteId({key, value}) { if (getType(value) === 'string') { return validateString({key, value}); } else { const errors = []; for (const prop in value) { errors.push(...validateString({key: `${key}.${prop}`, value: value[prop]})); } return errors; } }