@naturalcycles/nodejs-lib 13.23.1 → 13.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -41,14 +41,14 @@ function stringExtensions(joi) {
|
|
|
41
41
|
let { min, max } = args;
|
|
42
42
|
// Today allows +-14 hours gap to account for different timezones
|
|
43
43
|
if (max === 'today') {
|
|
44
|
-
max = (
|
|
44
|
+
max = getTodayStrPlus15();
|
|
45
45
|
}
|
|
46
46
|
if (min === 'today') {
|
|
47
|
-
min = (
|
|
47
|
+
min = getTodayStrMinus15();
|
|
48
48
|
}
|
|
49
49
|
// console.log('min/max', min, max)
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
50
|
+
const parts = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v);
|
|
51
|
+
if (!parts || parts.length < 4) {
|
|
52
52
|
err = 'string.dateString';
|
|
53
53
|
}
|
|
54
54
|
else if (min && v < min) {
|
|
@@ -57,8 +57,7 @@ function stringExtensions(joi) {
|
|
|
57
57
|
else if (max && v > max) {
|
|
58
58
|
err = 'string.dateStringMax';
|
|
59
59
|
}
|
|
60
|
-
else if (!
|
|
61
|
-
// todo: replace with another regex (from ajv-validators) for speed
|
|
60
|
+
else if (!isValidDate(parts)) {
|
|
62
61
|
err = 'string.dateStringCalendarAccuracy';
|
|
63
62
|
}
|
|
64
63
|
if (err) {
|
|
@@ -71,3 +70,39 @@ function stringExtensions(joi) {
|
|
|
71
70
|
};
|
|
72
71
|
}
|
|
73
72
|
exports.stringExtensions = stringExtensions;
|
|
73
|
+
const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
74
|
+
// Based on: https://github.com/ajv-validator
|
|
75
|
+
function isValidDate(parts) {
|
|
76
|
+
const year = Number(parts[1]);
|
|
77
|
+
const month = Number(parts[2]);
|
|
78
|
+
const day = Number(parts[3]);
|
|
79
|
+
return (month >= 1 &&
|
|
80
|
+
month <= 12 &&
|
|
81
|
+
day >= 1 &&
|
|
82
|
+
day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]));
|
|
83
|
+
}
|
|
84
|
+
function isLeapYear(year) {
|
|
85
|
+
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
86
|
+
}
|
|
87
|
+
let lastCheckedPlus = 0;
|
|
88
|
+
let todayStrPlusCached;
|
|
89
|
+
let lastCheckedMinus = 0;
|
|
90
|
+
let todayStrMinusCached;
|
|
91
|
+
function getTodayStrPlus15() {
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
if (now - lastCheckedPlus < 3_600_000) {
|
|
94
|
+
// cached for 1 hour
|
|
95
|
+
return todayStrPlusCached;
|
|
96
|
+
}
|
|
97
|
+
lastCheckedPlus = now;
|
|
98
|
+
return (todayStrPlusCached = (0, js_lib_1.localTimeNow)().plus(15, 'hour').toISODate());
|
|
99
|
+
}
|
|
100
|
+
function getTodayStrMinus15() {
|
|
101
|
+
const now = Date.now();
|
|
102
|
+
if (now - lastCheckedMinus < 3_600_000) {
|
|
103
|
+
// cached for 1 hour
|
|
104
|
+
return todayStrMinusCached;
|
|
105
|
+
}
|
|
106
|
+
lastCheckedMinus = now;
|
|
107
|
+
return (todayStrMinusCached = (0, js_lib_1.localTimeNow)().plus(-15, 'hour').toISODate());
|
|
108
|
+
}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { localTimeNow } from '@naturalcycles/js-lib'
|
|
2
2
|
import Joi, { Extension, StringSchema as JoiStringSchema } from 'joi'
|
|
3
3
|
|
|
4
4
|
export interface StringSchema<TSchema = string> extends JoiStringSchema<TSchema> {
|
|
@@ -51,22 +51,21 @@ export function stringExtensions(joi: typeof Joi): Extension {
|
|
|
51
51
|
|
|
52
52
|
// Today allows +-14 hours gap to account for different timezones
|
|
53
53
|
if (max === 'today') {
|
|
54
|
-
max =
|
|
54
|
+
max = getTodayStrPlus15()
|
|
55
55
|
}
|
|
56
56
|
if (min === 'today') {
|
|
57
|
-
min =
|
|
57
|
+
min = getTodayStrMinus15()
|
|
58
58
|
}
|
|
59
59
|
// console.log('min/max', min, max)
|
|
60
60
|
|
|
61
|
-
const
|
|
62
|
-
if (!
|
|
61
|
+
const parts = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v)
|
|
62
|
+
if (!parts || parts.length < 4) {
|
|
63
63
|
err = 'string.dateString'
|
|
64
64
|
} else if (min && v < min) {
|
|
65
65
|
err = 'string.dateStringMin'
|
|
66
66
|
} else if (max && v > max) {
|
|
67
67
|
err = 'string.dateStringMax'
|
|
68
|
-
} else if (!
|
|
69
|
-
// todo: replace with another regex (from ajv-validators) for speed
|
|
68
|
+
} else if (!isValidDate(parts)) {
|
|
70
69
|
err = 'string.dateStringCalendarAccuracy'
|
|
71
70
|
}
|
|
72
71
|
|
|
@@ -80,3 +79,48 @@ export function stringExtensions(joi: typeof Joi): Extension {
|
|
|
80
79
|
},
|
|
81
80
|
}
|
|
82
81
|
}
|
|
82
|
+
|
|
83
|
+
const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
84
|
+
// Based on: https://github.com/ajv-validator
|
|
85
|
+
function isValidDate(parts: string[]): boolean {
|
|
86
|
+
const year = Number(parts[1])
|
|
87
|
+
const month = Number(parts[2])
|
|
88
|
+
const day = Number(parts[3])
|
|
89
|
+
return (
|
|
90
|
+
month >= 1 &&
|
|
91
|
+
month <= 12 &&
|
|
92
|
+
day >= 1 &&
|
|
93
|
+
day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]!)
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function isLeapYear(year: number): boolean {
|
|
98
|
+
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let lastCheckedPlus = 0
|
|
102
|
+
let todayStrPlusCached: string
|
|
103
|
+
let lastCheckedMinus = 0
|
|
104
|
+
let todayStrMinusCached: string
|
|
105
|
+
|
|
106
|
+
function getTodayStrPlus15(): string {
|
|
107
|
+
const now = Date.now()
|
|
108
|
+
if (now - lastCheckedPlus < 3_600_000) {
|
|
109
|
+
// cached for 1 hour
|
|
110
|
+
return todayStrPlusCached
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
lastCheckedPlus = now
|
|
114
|
+
return (todayStrPlusCached = localTimeNow().plus(15, 'hour').toISODate())
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getTodayStrMinus15(): string {
|
|
118
|
+
const now = Date.now()
|
|
119
|
+
if (now - lastCheckedMinus < 3_600_000) {
|
|
120
|
+
// cached for 1 hour
|
|
121
|
+
return todayStrMinusCached
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
lastCheckedMinus = now
|
|
125
|
+
return (todayStrMinusCached = localTimeNow().plus(-15, 'hour').toISODate())
|
|
126
|
+
}
|