1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _momentTimezone = require('moment-timezone');
|
8 |
|
9 | var _momentTimezone2 = _interopRequireDefault(_momentTimezone);
|
10 |
|
11 | var _chronoNode = require('chrono-node');
|
12 |
|
13 | var _chronoNode2 = _interopRequireDefault(_chronoNode);
|
14 |
|
15 | var _Error = require('../Error');
|
16 |
|
17 | var _Error2 = _interopRequireDefault(_Error);
|
18 |
|
19 | var _Any = require('./Any');
|
20 |
|
21 | var _Any2 = _interopRequireDefault(_Any);
|
22 |
|
23 | var _Reference = require('../Reference');
|
24 |
|
25 | var _Reference2 = _interopRequireDefault(_Reference);
|
26 |
|
27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
28 |
|
29 | _momentTimezone2.default.createFromInputFallback = config => {
|
30 | if (config._i.toLowerCase() === 'now') config._d = new Date();else config._d = _chronoNode2.default.parseDate(config._i);
|
31 | };
|
32 |
|
33 | const types = ['date', 'time', 'datetime'];
|
34 |
|
35 | const zones = {
|
36 | 'Eastern Standard Time': 'EST',
|
37 | 'Eastern Daylight Time': 'EDT',
|
38 | 'Central Standard Time': 'CST',
|
39 | 'Central Daylight Time': 'CDT',
|
40 | 'Mountain Standard Time': 'MST',
|
41 | 'Mountain Daylight Time': 'MDT',
|
42 | 'Pacific Standard Time': 'PST',
|
43 | 'Pacific Daylight Time': 'PDT',
|
44 | 'Central European Time': 'CET',
|
45 | 'Central European Summer Time': 'CEST',
|
46 | MESZ: 'CEST',
|
47 | MEZ: 'CET'
|
48 | };
|
49 |
|
50 | const alias = {
|
51 | datetime: {
|
52 | ISO8601: 'YYYY-MM-DDTHH:mm:ssZ',
|
53 | RFC1123: 'ddd, DD MMM YYYY HH:mm:ss z',
|
54 | RFC2822: 'ddd, DD MMM YYYY HH:mm:ss ZZ',
|
55 | RFC822: 'ddd, DD MMM YY HH:mm:ss ZZ',
|
56 | RFC1036: 'ddd, D MMM YY HH:mm:ss ZZ'
|
57 | },
|
58 | date: {
|
59 | ISO8601: 'YYYY-MM-DD'
|
60 | }
|
61 | };
|
62 |
|
63 | class DateSchema extends _Any2.default {
|
64 | constructor(base) {
|
65 | super(base);
|
66 | this._setting.type = 'datetime';
|
67 |
|
68 | let raw = this._rules.descriptor.pop();
|
69 | let allow = this._rules.descriptor.pop();
|
70 | this._rules.descriptor.push(this._typeDescriptor, allow, this._rangeDescriptor, this._formatDescriptor, raw);
|
71 | raw = this._rules.validator.pop();
|
72 | allow = this._rules.validator.pop();
|
73 | this._rules.validator.push(this._typeValidator, allow, this._rangeValidator, this._formatValidator, raw);
|
74 | }
|
75 |
|
76 | type(value = 'datetime') {
|
77 | return this._setAny('type', value);
|
78 | }
|
79 |
|
80 | timezone(value) {
|
81 | const set = this._setting;
|
82 | if (value === undefined) delete set.timezone;else if (typeof value === 'string') set.timezone = zones[value] || value;else set.timezone = value;
|
83 | return this;
|
84 | }
|
85 |
|
86 | _typeDescriptor() {
|
87 | const set = this._setting;
|
88 | let msg;
|
89 | if (set.type instanceof _Reference2.default) {
|
90 | msg = `It has to be of type defined in ${set.type.description}. \
|
91 | It may also be given in string format. `;
|
92 | } else {
|
93 | msg = `It has to be a ${set.type}. It may also be given in string format. `;
|
94 | }
|
95 | if (set.timezone) {
|
96 | if (set.timezone instanceof _Reference2.default) {
|
97 | msg += `The time is assumed as timezone defined under ${set.timezone.description}. `;
|
98 | } else {
|
99 | msg += `The time is assumed as timezone ${set.timezone}. `;
|
100 | }
|
101 | }
|
102 | return msg.replace(/ $/, '\n');
|
103 | }
|
104 |
|
105 | _typeValidator(data) {
|
106 | const check = this._check;
|
107 | try {
|
108 | this._checkString('timezone');
|
109 | this._checkString('type');
|
110 | if (!types.includes(check.type)) {
|
111 | throw new Error(`Invalid type setting, use one of ${types.join(', ')}`);
|
112 | }
|
113 | } catch (err) {
|
114 | return Promise.reject(new _Error2.default(this, data, err.message));
|
115 | }
|
116 |
|
117 | if (check.timezone) data.value = _momentTimezone2.default.tz(data.value, check.timezone);else data.value = (0, _momentTimezone2.default)(data.value);
|
118 | if (!data.value.isValid()) {
|
119 | return Promise.reject(new _Error2.default(this, data, `The given text is not parse able as ${check.type}`));
|
120 | }
|
121 | return Promise.resolve();
|
122 | }
|
123 |
|
124 | min(value) {
|
125 | const set = this._setting;
|
126 | if (value === undefined) delete set.min;else if (!(value instanceof _Reference2.default)) {
|
127 | if (set.timezone) value = _momentTimezone2.default.tz(value, set.timezone);else value = (0, _momentTimezone2.default)(value);
|
128 | if (!value.isValid()) {
|
129 | throw new Error('The given text is not parse able as date');
|
130 | }
|
131 | if (set.max && !this._isReference('max') && value > set.max) {
|
132 | throw new Error('Min can´t be greater than max value');
|
133 | }
|
134 | if (set.less && !this._isReference('less') && value >= set.less) {
|
135 | throw new Error('Min can´t be greater or equal less value');
|
136 | }
|
137 | if (set.negative && !this._isReference('negative') && value > 0) {
|
138 | throw new Error('Min can´t be positive, because defined as negative');
|
139 | }
|
140 | set.min = value;
|
141 | } else set.min = value;
|
142 | return this;
|
143 | }
|
144 |
|
145 | max(value) {
|
146 | const set = this._setting;
|
147 | if (value === undefined) delete set.max;else if (!(value instanceof _Reference2.default)) {
|
148 | if (set.timezone) value = _momentTimezone2.default.tz(value, set.timezone);else value = (0, _momentTimezone2.default)(value);
|
149 | if (!value.isValid()) {
|
150 | throw new Error('The given text is not parse able as date');
|
151 | }
|
152 | if (set.min && !this._isReference('min') && value < set.min) {
|
153 | throw new Error('Max can´t be less than min value');
|
154 | }
|
155 | if (set.greater && !this._isReference('greater') && value >= set.greater) {
|
156 | throw new Error('Max can´t be less or equal greater value');
|
157 | }
|
158 | if (set.positive && !this._isReference('positive') && value < 0) {
|
159 | throw new Error('Max can´t be negative, because defined as positive');
|
160 | }
|
161 | set.max = value;
|
162 | } else set.max = value;
|
163 | return this;
|
164 | }
|
165 |
|
166 | less(value) {
|
167 | const set = this._setting;
|
168 | if (value === undefined) delete set.less;else if (!(value instanceof _Reference2.default)) {
|
169 | if (set.timezone) value = _momentTimezone2.default.tz(value, set.timezone);else value = (0, _momentTimezone2.default)(value);
|
170 | if (!value.isValid()) {
|
171 | throw new Error('The given text is not parse able as date');
|
172 | }
|
173 | if (set.min && !this._isReference('min') && value <= set.min) {
|
174 | throw new Error('Less can´t be less than min value');
|
175 | }
|
176 | if (set.greater && !this._isReference('greater') && value <= set.greater) {
|
177 | throw new Error('Less can´t be less or equal greater value');
|
178 | }
|
179 | if (set.positive && !this._isReference('positive') && value <= 0) {
|
180 | throw new Error('Less can´t be negative, because defined as positive');
|
181 | }
|
182 | set.less = value;
|
183 | } else set.less = value;
|
184 | return this;
|
185 | }
|
186 |
|
187 | greater(value) {
|
188 | const set = this._setting;
|
189 | if (value === undefined) delete set.greater;else if (!(value instanceof _Reference2.default)) {
|
190 | if (set.timezone) value = _momentTimezone2.default.tz(value, set.timezone);else value = (0, _momentTimezone2.default)(value);
|
191 | if (!value.isValid()) {
|
192 | throw new Error('The given text is not parse able as date');
|
193 | }
|
194 | if (set.max && !this._isReference('max') && value >= set.max) {
|
195 | throw new Error('Greater can´t be greater than max value');
|
196 | }
|
197 | if (set.less && !this._isReference('less') && value >= set.less) {
|
198 | throw new Error('Greater can´t be greater or equal less value');
|
199 | }
|
200 | if (set.negative && !this._isReference('negative') && value >= 0) {
|
201 | throw new Error('Greater can´t be positive, because defined as negative');
|
202 | }
|
203 | set.greater = value;
|
204 | } else set.greater = value;
|
205 | return this;
|
206 | }
|
207 |
|
208 | _rangeDescriptor() {
|
209 | const set = this._setting;
|
210 | let msg = '';
|
211 | if (this._isReference('min')) {
|
212 | msg += `The ${set.type} has to be at least the number given in ${set.min.description}. `;
|
213 | } else if (set.min !== undefined) msg += `The ${set.type} has to be at least \`${set.min}\`. `;
|
214 | if (this._isReference('greater')) {
|
215 | msg += `The ${set.type} has to be higher than given in ${set.greater.description}. `;
|
216 | } else if (set.greater !== undefined) {
|
217 | msg += `The ${set.type} has to be greater than \`${set.greater}\`. `;
|
218 | }
|
219 | if (this._isReference('less')) {
|
220 | msg += `The ${set.type} has to be at lower than given in ${set.less.description}. `;
|
221 | } else if (set.less !== undefined) msg += `The ${set.type} has to be less than \`${set.less}\`. `;
|
222 | if (this._isReference('max')) {
|
223 | msg += `The ${set.type} has to be at least the number given in ${set.max.description}. `;
|
224 | } else if (set.max !== undefined) msg += `The ${set.type} has to be at most \`${set.max}\`. `;
|
225 | if ((set.min !== undefined || set.greater !== undefined) && (set.max !== undefined || set.less !== undefined)) {
|
226 | msg = msg.replace(/(.*)\. The \w+ has to be/, '$1 and');
|
227 | }
|
228 | return msg.replace(/ $/, '\n');
|
229 | }
|
230 |
|
231 | _rangeValidator(data) {
|
232 | const check = this._check;
|
233 |
|
234 | if (check.min && this._isReference('min')) {
|
235 | if (check.timezone) check.min = _momentTimezone2.default.tz(check.min, check.timezone);else check.min = (0, _momentTimezone2.default)(check.min);
|
236 | if (!check.min.isValid()) {
|
237 | return Promise.reject(new _Error2.default(this, data, `The given text is not parse able as ${check.type}`));
|
238 | }
|
239 | }
|
240 | if (check.max && this._isReference('max')) {
|
241 | if (check.timezone) check.max = _momentTimezone2.default.tz(check.max, check.timezone);else check.max = (0, _momentTimezone2.default)(check.max);
|
242 | if (!check.max.isValid()) {
|
243 | return Promise.reject(new _Error2.default(this, data, `The given text is not parse able as ${check.type}`));
|
244 | }
|
245 | }
|
246 | if (check.greater && this._isReference('greater')) {
|
247 | if (check.timezone) check.greater = _momentTimezone2.default.tz(check.greater, check.timezone);else check.greater = (0, _momentTimezone2.default)(check.greater);
|
248 | if (!check.greater.isValid()) {
|
249 | return Promise.reject(new _Error2.default(this, data, `The given text is not parse able as ${check.type}`));
|
250 | }
|
251 | }
|
252 | if (check.less && this._isReference('less')) {
|
253 | if (check.timezone) check.less = _momentTimezone2.default.tz(check.less, check.timezone);else check.less = (0, _momentTimezone2.default)(check.less);
|
254 | if (!check.less.isValid()) {
|
255 | return Promise.reject(new _Error2.default(this, data, `The given text is not parse able as ${check.type}`));
|
256 | }
|
257 | }
|
258 |
|
259 | if (check.min && check.min.isSameOrAfter(data.value)) {
|
260 | return Promise.reject(new _Error2.default(this, data, `The ${check.type} is before the defined range. It has to be ${check.min} or later.`));
|
261 | }
|
262 | if (check.max && check.max.isSameOrBefore(data.value)) {
|
263 | return Promise.reject(new _Error2.default(this, data, `The ${check.type} is after the defined range. It has to be ${check.max} or earlier.`));
|
264 | }
|
265 | if (check.greater && check.greater.isAfter(data.value)) {
|
266 | return Promise.reject(new _Error2.default(this, data, `The ${check.type} is before the defined range. It has to be after ${check.greater}.`));
|
267 | }
|
268 | if (check.less && check.less.isBefore(data.value)) {
|
269 | return Promise.reject(new _Error2.default(this, data, `The ${check.type} is after the defined range. It has to be before ${check.less}.`));
|
270 | }
|
271 | return Promise.resolve();
|
272 | }
|
273 |
|
274 | format(value) {
|
275 | if (value === 'unix') value = 'seconds';
|
276 | return this._setAny('format', value);
|
277 | }
|
278 | toLocale(value) {
|
279 | return this._setAny('toLocale', value);
|
280 | }
|
281 | toTimezone(value) {
|
282 | const set = this._setting;
|
283 | if (value === undefined) delete set.toTimezone;else if (typeof value === 'string') set.toTimezone = zones[value] || value;else set.toTimezone = value;
|
284 | return this;
|
285 | }
|
286 |
|
287 | _formatDescriptor() {
|
288 | const set = this._setting;
|
289 | let msg = '';
|
290 | if (set.format) {
|
291 | if (this._isReference('format')) {
|
292 | msg += `The ${set.type} will be formatted like defined under ${set.format.description}. `;
|
293 | } else msg += `The ${set.type} will be formatted like: ${set.format}. `;
|
294 | }
|
295 | return msg.length ? `${msg.trim()}\n` : msg;
|
296 | }
|
297 |
|
298 | _formatValidator(data) {
|
299 | const check = this._check;
|
300 | try {
|
301 | this._checkString('format');
|
302 | if (alias[check.type] && alias[check.type][check.format]) {
|
303 | check.format = alias[check.type][check.format];
|
304 | }
|
305 | } catch (err) {
|
306 | return Promise.reject(new _Error2.default(this, data, err.message));
|
307 | }
|
308 |
|
309 | if (check.toLocale) data.value = data.value.locale(check.toLocale);
|
310 | if (check.toTimezone) data.value = data.value.tz(check.toTimezone);
|
311 | if (check.format) {
|
312 | if (check.format === 'milliseconds') data.value = data.value.valueOf();else if (check.format === 'seconds') data.value = data.value.unix();else data.value = data.value.format(check.format);
|
313 | } else data.value = data.value.toDate();
|
314 | return Promise.resolve();
|
315 | }
|
316 | }
|
317 |
|
318 | exports.default = DateSchema; |
\ | No newline at end of file |