1 | import { dayjs } from '@naturalcycles/time-lib'
|
2 | import { Extension, StringSchema } from 'joi'
|
3 | import * as Joi from 'joi'
|
4 | import { AnySchemaTyped } from './joi.model'
|
5 |
|
6 | export interface ExtendedStringSchema extends StringSchema, AnySchemaTyped<string> {
|
7 | dateString(min?: string, max?: string): this
|
8 | }
|
9 |
|
10 | export interface JoiDateStringOptions {
|
11 | min?: string
|
12 | max?: string
|
13 | }
|
14 |
|
15 | export function stringExtensions(joi: typeof Joi): Extension {
|
16 | return {
|
17 | type: 'string',
|
18 | base: joi.string(),
|
19 | messages: {
|
20 | 'string.dateString': '"{{#label}}" must be an ISO8601 date (yyyy-mm-dd)',
|
21 | 'string.dateStringMin': '"{{#label}}" must be not earlier than {{#min}}',
|
22 | 'string.dateStringMax': '"{{#label}}" must be not later than {{#max}}',
|
23 | 'string.dateStringCalendarAccuracy': '"{{#label}}" must be a VALID calendar date',
|
24 | 'string.stripHTML': '"{{#label}}" must NOT contain any HTML tags',
|
25 | },
|
26 | rules: {
|
27 | dateString: {
|
28 | method(min?: string, max?: string) {
|
29 | return this.$_addRule({
|
30 | name: 'dateString',
|
31 | args: { min, max } as JoiDateStringOptions,
|
32 | })
|
33 | },
|
34 | args: [
|
35 | {
|
36 | name: 'min',
|
37 | ref: true,
|
38 | assert: v => typeof v === 'string',
|
39 | message: 'must be a string',
|
40 | },
|
41 | {
|
42 | name: 'max',
|
43 | ref: true,
|
44 | assert: v => typeof v === 'string',
|
45 | message: 'must be a string',
|
46 | },
|
47 | ],
|
48 | validate(v: string, helpers, args: JoiDateStringOptions) {
|
49 |
|
50 |
|
51 | let err: string | undefined
|
52 | let { min, max } = args
|
53 |
|
54 |
|
55 | if (max === 'today') {
|
56 | max = dayjs().add(14, 'hour').toISODate()
|
57 | }
|
58 | if (min === 'today') {
|
59 | min = dayjs().subtract(14, 'hour').toISODate()
|
60 | }
|
61 |
|
62 |
|
63 | const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v)
|
64 | if (!m || m.length <= 1) {
|
65 | err = 'string.dateString'
|
66 | } else if (min && v < min) {
|
67 | err = 'string.dateStringMin'
|
68 | } else if (max && v > max) {
|
69 | err = 'string.dateStringMax'
|
70 | } else if (!dayjs(v).isValid()) {
|
71 |
|
72 | err = 'string.dateStringCalendarAccuracy'
|
73 | }
|
74 |
|
75 | if (err) {
|
76 | return helpers.error(err, args)
|
77 | }
|
78 |
|
79 | return v
|
80 | },
|
81 | },
|
82 | },
|
83 | }
|
84 | }
|