import * as NumberCheck from "./number"; export enum PotentiallyUnsafeDateErrorCode { NOT_DATE = "NOT_DATE" } export function checkPotentiallyUnsafeDate (mixed : any) : undefined|PotentiallyUnsafeDateErrorCode { if (mixed instanceof Date) { return undefined; } else { return PotentiallyUnsafeDateErrorCode.NOT_DATE; } } export function checkPotentiallyUnsafeDatePredicate (mixed : any, predicate : (date : Date) => undefined|ErrorT) : undefined|PotentiallyUnsafeDateErrorCode|ErrorT { const error = checkPotentiallyUnsafeDate(mixed); if (error !== undefined) { return error; } return predicate(mixed); } export type ValidDateErrorCodeType = ( PotentiallyUnsafeDateErrorCode | { index : string, error : NumberCheck.PotentiallyUnsafeNumberErrorCode|NumberCheck.FiniteNumberErrorCode } ); export function checkValidDate (mixed : any) : undefined|ValidDateErrorCodeType { return checkPotentiallyUnsafeDatePredicate(mixed, (date) => { const timestamp = date.getTime(); const error = NumberCheck.checkFiniteNumber(timestamp); if (error !== undefined) { return { index : "UNIX timestamp", error : error }; } return undefined; }) } export function checkValidDatePredicate (mixed : any, predicate : (date : Date) => undefined|ErrorT) { const error = checkValidDate(mixed); if (error !== undefined) { return error; } return predicate(mixed); } export enum BeforeErrorCode { EQUAL = "EQUAL", AFTER = "AFTER" } export function checkBefore (mixed : any, x : Date) : undefined|ValidDateErrorCodeType|BeforeErrorCode { return checkValidDatePredicate(x, (validX) => { return checkValidDatePredicate(mixed, (date) => { if (date.getTime() == validX.getTime()) { return BeforeErrorCode.EQUAL; } if (date.getTime() > validX.getTime()) { return BeforeErrorCode.AFTER; } return undefined; }); }); } export enum AfterErrorCode { EQUAL = "EQUAL", BEFORE = "BEFORE" } export function checkAfter (mixed : any, x : Date) : undefined|ValidDateErrorCodeType|AfterErrorCode { return checkValidDatePredicate(x, (validX) => { return checkValidDatePredicate(mixed, (date) => { if (date.getTime() == validX.getTime()) { return AfterErrorCode.EQUAL; } if (date.getTime() < validX.getTime()) { return AfterErrorCode.BEFORE; } return undefined; }); }); } export enum BeforeOrAtErrorCode { AFTER = "AFTER" } export function checkBeforeOrAt (mixed : any, x : Date) : undefined|ValidDateErrorCodeType|BeforeOrAtErrorCode { return checkValidDatePredicate(x, (validX) => { return checkValidDatePredicate(mixed, (date) => { if (date.getTime() > validX.getTime()) { return BeforeOrAtErrorCode.AFTER; } return undefined; }); }); } export enum AfterOrAtErrorCode { BEFORE = "BEFORE" } export function checkAfterOrAt (mixed : any, x : Date) : undefined|ValidDateErrorCodeType|AfterOrAtErrorCode { return checkValidDatePredicate(x, (validX) => { return checkValidDatePredicate(mixed, (date) => { if (date.getTime() > validX.getTime()) { return AfterOrAtErrorCode.BEFORE; } return undefined; }); }); } export type RangeErrorCode = ValidDateErrorCodeType|AfterOrAtErrorCode|BeforeOrAtErrorCode; export function checkRange (mixed : any, args : { min? : Date, max? : Date }) : undefined|RangeErrorCode { if (args.min != null) { const error = checkAfterOrAt(mixed, args.min); if (error !== undefined) { return error; } } if (args.max != null) { const error = checkBeforeOrAt(mixed, args.max); if (error !== undefined) { return error; } } return undefined; }