@mapbox/mapbox-gl-style-spec
Version:
a specification for mapbox gl styles
87 lines (73 loc) • 2.75 kB
text/typescript
import {getType, isObject} from '../util/get_type';
import validate from './validate';
import ValidationError from '../error/validation_error';
import type {StyleReference} from '../reference/latest';
import type {StyleSpecification} from '../types';
import type {ArrayPropertySpecification} from '../style-spec';
type ArraySpec = {
value?: unknown;
values?: unknown[] | {[_: string]: unknown};
length?: number;
minimum?: number;
maximum?: number;
function?: unknown;
};
type ArrayElementSpec<T = unknown> = {
type: string;
values: T[] | {[_: string]: unknown};
minimum: number;
maximum: number;
function: unknown;
};
type ArrayValidatorOptions<T = unknown> = {
key: string;
value: T;
valueSpec: ArrayPropertySpecification | ArraySpec;
style: Partial<StyleSpecification>;
styleSpec: StyleReference;
arrayElementValidator: (...args: unknown[]) => ValidationError[];
};
export default function validateArray(options: ArrayValidatorOptions): ValidationError[] {
const array = options.value;
const arraySpec = options.valueSpec;
const style = options.style;
const styleSpec = options.styleSpec;
const key = options.key;
const validateArrayElement = options.arrayElementValidator || validate;
if (!Array.isArray(array)) {
return [new ValidationError(key, array, `array expected, ${getType(array)} found`)];
}
if (arraySpec.length && array.length !== arraySpec.length) {
return [new ValidationError(key, array, `array length ${arraySpec.length} expected, length ${array.length} found`)];
}
if (arraySpec['min-length'] && array.length < arraySpec['min-length']) {
return [new ValidationError(key, array, `array length at least ${arraySpec['min-length']} expected, length ${array.length} found`)];
}
let arrayElementSpec: ArrayElementSpec = {
type: arraySpec.value as string,
values: arraySpec.values,
minimum: arraySpec.minimum,
maximum: arraySpec.maximum,
function: undefined
};
if (styleSpec.$version < 7) {
arrayElementSpec.function = (arraySpec as ArraySpec).function;
}
if (isObject(arraySpec.value)) {
arrayElementSpec = arraySpec.value as ArrayElementSpec;
}
let errors: ValidationError[] = [];
for (let i = 0; i < array.length; i++) {
errors = errors.concat(validateArrayElement({
array,
arrayIndex: i,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
value: array[i],
valueSpec: arrayElementSpec,
style,
styleSpec,
key: `${key}[${i}]`
}, true));
}
return errors;
}