@maplibre/maplibre-gl-style-spec
Version:
a specification for maplibre styles
129 lines (115 loc) • 4.1 kB
text/typescript
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 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;
}
}