typestack / class-validator

Decorator-based property validation for classes.
MIT License
11.08k stars 804 forks source link

GeoJson validation #597

Open anthowm opened 4 years ago

anthowm commented 4 years ago

Hi today I was working with mongodb GeoJson and my backend is nestjs that use this library for validation(cool one :)). I'm requesting validation for GeoJson [longitude, latitude] array that can be cool for the moment I did a custom decorator that can help to integrate it to this library. Also my decorator and the feature can help to solve this issues as well https://github.com/typestack/class-validator/issues/117 https://github.com/typestack/class-validator/issues/332

import { ValidationOptions, registerDecorator } from 'class-validator';
import validator = require('validator');
export const ARRAY_IS_COORDINATE = 'arrayIsCoordinate';
/**
 * Checks if a value is string in format a "latitude,longitude".
 */
export function isLatLong(value: string): boolean {
    return typeof value === 'string' && validator.isLatLong(value);
}
/**
 * Checks if a given value is a longitude.
 */
export function isLongitude(value: number): boolean {
    return (typeof value === 'number') && isLatLong(`0,${value}`);
}

/**
 * Checks if a given value is a latitude.
 */
export function isLatitude(value: number): boolean {
    return (typeof value === 'number') && isLatLong(`${value},0`);
}
/**
 * Checks if array contains a GeoJson valid values.
 * If null or undefined is given then this function returns false.
 */
export function arrayIsCoordinate(values: any[]) {
    if (!Array.isArray(values)) {
        return false;
    }
    if (values.length !== 2) {
        return false;
    }
    const isValidLongitude = isLongitude(values[0]);
    const isValidLatitude = isLatitude(values[1]);
    return isValidLatitude && isValidLongitude;
}

/**
 * Checks if array contains all values from the given array of values.
 * If null or undefined is given then this function returns false.
 */
export function ArrayIsCoordinate(validationOptions?: ValidationOptions) {
    return function (object: Object, propertyName: string) {
        registerDecorator({
            name: 'arrayIsCoordinate',
            target: object.constructor,
            propertyName,
            constraints: [],
            options: validationOptions,
            validator: {
                validate(value: any, args) {
                    return arrayIsCoordinate(value);
                },
            },
        });
    };
}
vlapo commented 4 years ago

Feel free to open PR. Could you also cover case with altitude (mentioned in https://github.com/typestack/class-validator/issues/117 - array with 3 items)?