validata
Version:
Type safe data validation and sanitization
49 lines (40 loc) • 1.6 kB
text/typescript
import { basicValidation, Check, Coerce, CommonValidationOptions, Convert, createAsCheck, createIsCheck, createMaybeAsCheck, createMaybeCheck, Validate } from './common';
import { Issue } from './types';
interface CoerceOptions {
setProtocol?: string;
}
interface ValidationOptions extends CommonValidationOptions<URL> {
protocol?: string;
}
const check: Check<URL> = (value): value is URL => {
return value instanceof URL;
};
const convert: Convert<URL> = (value) => {
if (typeof value === 'string') {
try {
return new URL(value);
} catch (e) {
return undefined;
}
}
return undefined;
};
const coerce: Coerce<URL, CoerceOptions> = (options) => (next) => (value, path) => {
if (!options) return next(value, path);
const coerced = new URL(value.toString());
if (options.setProtocol) {
coerced.protocol = options.setProtocol;
}
return next(coerced, path);
};
const validate: Validate<URL, ValidationOptions> = (value, path, options) => {
const result = basicValidation(value, path, options);
if (options.protocol && value.protocol.replace(/:\s*$/, '') !== options.protocol.replace(/:\s*$/, '')) {
result.issues.push(Issue.forPath(path, value, 'invalid-protocol', { expectedProtocol: options.protocol }));
}
return result;
};
export const isUrl = createIsCheck('url', check, coerce, validate);
export const maybeUrl = createMaybeCheck('url', check, coerce, validate);
export const asUrl = createAsCheck('url', check, convert, coerce, validate);
export const maybeAsUrl = createMaybeAsCheck('url', check, convert, coerce, validate);