forked from couchbaselabs/node-ottoman
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdate-type.ts
More file actions
127 lines (114 loc) · 3.95 KB
/
date-type.ts
File metadata and controls
127 lines (114 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { CoreType } from './core-type';
import { DateFunction, DateOption, validateMaxDate, validateMinDate } from '../helpers';
import { ValidationError } from '../errors';
import { CoreTypeOptions } from '../interfaces/schema.types';
import { is } from '../../utils';
import { CAST_STRATEGY, checkCastStrategy } from '../../utils/cast-strategy';
import { isDateValid } from '../../utils/type-helpers';
/**
* @field `min` date value that will be accepted
* @field `max` date value that will be accepted
* */
interface DateTypeOptions {
min?: Date | DateOption | DateFunction | string;
max?: Date | DateOption | DateFunction | string;
}
/**
* `Date` are plain JavaScript Date.
*
* ## Options
*
* - **required** flag to define if the field is mandatory
* - **validator** that will be applied to the field a validation function, validation object or string with the name of the custom validator
* - **default** that will define the initial value of the field, this option allows a value or a function
* - **immutable** that will define this field as immutable. Ottoman prevents you from changing immutable fields if the schema as configure like strict
* - **min** minimum date value that will be accepted
* - **max** maximum date value that will be accepted
*
* @example
* ```typescript
* const userSchema = new Schema({
* birthday: { type: Date, min: '1990-12-31', max: new Date() },
* hired: Schema.Types.Date
* })
* ```
*/
export class DateType extends CoreType {
constructor(name: string, options?: DateTypeOptions & CoreTypeOptions) {
super(name, DateType.sName, options);
}
static sName = Date.name;
get min(): Date | DateOption | DateFunction | undefined {
const _min = (this.options as DateTypeOptions).min;
if (typeof _min === 'string') {
return new Date(String(_min));
}
return _min;
}
get max(): Date | DateOption | DateFunction | undefined {
const _max = (this.options as DateTypeOptions).max;
if (typeof _max === 'string') {
return new Date(String(_max));
}
return _max;
}
buildDefault(): Date | undefined {
const result: any = super.buildDefault();
if (result) {
return !(result instanceof Date) ? new Date(String(result)) : (result as Date);
}
return result;
}
cast(value: any, strategy = CAST_STRATEGY.DEFAULT_OR_DROP) {
if(value === null || value === undefined) {
return value;
}
if (isDateValid(value)) {
return new Date(value);
}
return checkCastStrategy(value, strategy, this);
}
validate(value: unknown, strategy) {
value = super.validate(value, strategy);
if (this.isEmpty(value)) return value;
const _value = this.isStrictStrategy(strategy)
? is(value, Date)
? (value as Date)
: undefined
: is(value, Date)
? (value as Date)
: is(value, String)
? new Date(String(value))
: is(value, Number)
? new Date(Number(value))
: undefined;
if (_value === undefined) {
throw new ValidationError(`Property '${this.name}' must be of type '${this.typeName}'`);
}
this.checkValidator(_value);
let errors: string[] = [];
errors.push(this._checkMinDate(_value));
errors.push(this._checkMaxDate(_value));
errors = errors.filter((e) => e !== '');
if (errors.length > 0) {
throw new ValidationError(errors.join('\n'));
}
return _value;
}
private _checkMinDate(val: Date): string {
const _min = typeof this.min === 'function' ? this.min() : this.min;
if (_min === undefined) {
return '';
}
return validateMinDate(val, _min, this.name) || '';
}
private _checkMaxDate(val: Date): string {
const _max = typeof this.max === 'function' ? this.max() : this.max;
if (_max === undefined) {
return '';
}
return validateMaxDate(val, _max, this.name) || '';
}
}
export const dateTypeFactory = (name: string, opts: DateTypeOptions & CoreTypeOptions): DateType =>
new DateType(name, opts);