@naturalcycles/nodejs-lib
Version:
Standard library for Node.js
80 lines (72 loc) • 2.22 kB
text/typescript
import { Extension, State, ValidationOptions } from '@hapi/joi'
import * as JoiLib from '@hapi/joi'
import { dayjs } from '@naturalcycles/time-lib'
export interface DateStringExtension {
dateString(min?: string, max?: string): this
}
export interface DateStringParams {
min?: string
max?: string
}
export function dateStringExtension(joi: typeof JoiLib): Extension {
return {
base: joi.string(),
name: 'string',
language: {
dateString: 'needs to be a date string (yyyy-mm-dd)',
dateStringMin: 'needs to be not earlier than {{min}}',
dateStringMax: 'needs to be not later than {{max}}',
dateStringCalendarAccuracy: 'needs to be a calendar accurate date',
},
rules: [
{
name: 'dateString',
params: {
min: joi.string().optional(),
max: joi.string().optional(),
},
validate(params: DateStringParams, v: any, state: State, options: ValidationOptions) {
let err: string | undefined
let min = params.min
let max = params.max
// Today allows +-14 hours gap to account for different timezones
if (max === 'today') {
max = dayjs()
.add(14, 'hour')
.toISODate()
}
if (min === 'today') {
min = dayjs()
.subtract(14, 'hour')
.toISODate()
}
// console.log('min/max', min, max)
const m = v.match(/^(\d{4})-(\d{2})-(\d{2})$/)
if (!m || m.length <= 1) {
err = 'string.dateString'
} else if (min && v < min) {
err = 'string.dateStringMin'
} else if (max && v > max) {
err = 'string.dateStringMax'
} else if (!dayjs(v).isValid()) {
err = 'string.dateStringCalendarAccuracy'
}
if (err) {
// tslint:disable-next-line:no-invalid-this
return this.createError(
err,
{
v,
min,
max,
},
state,
options,
)
}
return v // validation passed
},
},
],
}
}