@valkyriestudios/utils 12.48.0 → 12.49.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.
- package/cjs/date/convertToDate.js +15 -8
- package/cjs/date/format.js +33 -55
- package/cjs/date/is.js +1 -1
- package/cjs/date/isFormat.js +47 -38
- package/cjs/formdata/toObject.js +1 -1
- package/cjs/hash/hexId.js +1 -1
- package/cjs/number/round.js +1 -1
- package/esm/date/convertToDate.js +15 -8
- package/esm/date/format.js +33 -55
- package/esm/date/is.js +1 -1
- package/esm/date/isFormat.js +47 -38
- package/esm/formdata/toObject.js +1 -1
- package/esm/hash/hexId.js +1 -1
- package/esm/number/round.js +1 -1
- package/index.d.ts +10 -10
- package/package.json +4 -4
|
@@ -2,14 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.convertToDate = convertToDate;
|
|
4
4
|
exports.default = convertToDate;
|
|
5
|
-
const is_1 = require("./is");
|
|
6
5
|
function convertToDate(val) {
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
switch (typeof val) {
|
|
7
|
+
case 'number': {
|
|
8
|
+
if (val !== val)
|
|
9
|
+
return null;
|
|
10
|
+
const d = new Date(val);
|
|
11
|
+
return d.getTime() === d.getTime() ? d : null;
|
|
12
|
+
}
|
|
13
|
+
case 'object':
|
|
14
|
+
return val instanceof Date && val.getTime() === val.getTime() ? val : null;
|
|
15
|
+
case 'string': {
|
|
16
|
+
const d = new Date(val);
|
|
17
|
+
return d.getTime() === d.getTime() ? d : null;
|
|
18
|
+
}
|
|
19
|
+
default:
|
|
20
|
+
return null;
|
|
9
21
|
}
|
|
10
|
-
else if (typeof val === 'string') {
|
|
11
|
-
const date = new Date(val);
|
|
12
|
-
return Number.isNaN(date.getTime()) ? null : date;
|
|
13
|
-
}
|
|
14
|
-
return null;
|
|
15
22
|
}
|
package/cjs/date/format.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.format = format;
|
|
7
7
|
exports.default = format;
|
|
8
8
|
const convertToDate_1 = require("./convertToDate");
|
|
9
|
-
const isFormat_1 = require("./isFormat");
|
|
10
9
|
const LRU_1 = __importDefault(require("../caching/LRU"));
|
|
11
10
|
const WEEK_STARTS = {
|
|
12
11
|
mon: 'mon',
|
|
@@ -16,7 +15,6 @@ const WEEK_STARTS = {
|
|
|
16
15
|
let DEFAULT_LOCALE = 'en-US';
|
|
17
16
|
let DEFAULT_TZ = Intl?.DateTimeFormat?.().resolvedOptions?.().timeZone || 'UTC';
|
|
18
17
|
let DEFAULT_SOW = 'mon';
|
|
19
|
-
const ESCAPE_RGX = /\[([^\]]*)]/g;
|
|
20
18
|
const intl_formatters = new LRU_1.default({ max_size: 100 });
|
|
21
19
|
const spec_cache = new LRU_1.default({ max_size: 100 });
|
|
22
20
|
const zone_offset_cache = new LRU_1.default({ max_size: 100 });
|
|
@@ -42,15 +40,8 @@ function WeekNr(d, sow) {
|
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
function toZone(d, zone) {
|
|
45
|
-
const year = d.getUTCFullYear();
|
|
46
|
-
const month = d.getUTCMonth();
|
|
47
|
-
const day = d.getUTCDate();
|
|
48
43
|
const time = d.getTime();
|
|
49
|
-
const
|
|
50
|
-
let doy = day;
|
|
51
|
-
for (let i = 0; i <= month; i++)
|
|
52
|
-
doy += daysInMonths[i];
|
|
53
|
-
const ckey = zone + ':' + year + ':' + doy;
|
|
44
|
+
const ckey = zone + ':' + Math.floor(time / 900000);
|
|
54
45
|
const cached = zone_offset_cache.get(ckey);
|
|
55
46
|
if (cached !== undefined)
|
|
56
47
|
return new Date(time + cached);
|
|
@@ -80,54 +71,54 @@ function runIntl(loc, token, props, val) {
|
|
|
80
71
|
return formatter.format(val);
|
|
81
72
|
}
|
|
82
73
|
const Tokens = [
|
|
83
|
-
['YYYY', d => d.getFullYear()],
|
|
84
|
-
['Q', d => ((d.getMonth() + 3) / 3) | 0],
|
|
74
|
+
['YYYY', d => d.getFullYear().toString()],
|
|
75
|
+
['Q', d => (((d.getMonth() + 3) / 3) | 0).toString()],
|
|
85
76
|
['MMMM', (d, loc) => runIntl(loc, 'MMMM', { month: 'long' }, d)],
|
|
86
77
|
['MMM', (d, loc) => runIntl(loc, 'MMM', { month: 'short' }, d)],
|
|
87
78
|
['MM', d => {
|
|
88
79
|
const val = d.getMonth() + 1;
|
|
89
80
|
return (val < 10 ? '0' : '') + val;
|
|
90
81
|
}],
|
|
91
|
-
['M', d => d.getMonth() + 1],
|
|
82
|
+
['M', d => (d.getMonth() + 1).toString()],
|
|
92
83
|
['WW', (d, loc, sow) => {
|
|
93
84
|
const val = WeekNr(d, sow);
|
|
94
85
|
return (val < 10 ? '0' : '') + val;
|
|
95
86
|
}],
|
|
96
|
-
['W', (d, loc, sow) => WeekNr(d, sow)],
|
|
87
|
+
['W', (d, loc, sow) => WeekNr(d, sow).toString()],
|
|
97
88
|
['DD', d => {
|
|
98
89
|
const val = d.getDate();
|
|
99
90
|
return (val < 10 ? '0' : '') + val;
|
|
100
91
|
}],
|
|
101
|
-
['D', d => d.getDate()],
|
|
92
|
+
['D', d => d.getDate().toString()],
|
|
102
93
|
['dddd', (d, loc) => runIntl(loc, 'dddd', { weekday: 'long' }, d)],
|
|
103
94
|
['ddd', (d, loc) => runIntl(loc, 'ddd', { weekday: 'short' }, d)],
|
|
104
95
|
['HH', d => {
|
|
105
96
|
const val = d.getHours();
|
|
106
97
|
return (val < 10 ? '0' : '') + val;
|
|
107
98
|
}],
|
|
108
|
-
['H', d => d.getHours()],
|
|
99
|
+
['H', d => d.getHours().toString()],
|
|
109
100
|
['hh', d => {
|
|
110
101
|
const val = ((d.getHours() + 11) % 12) + 1;
|
|
111
102
|
return (val < 10 ? '0' : '') + val;
|
|
112
103
|
}],
|
|
113
|
-
['h', d => ((d.getHours() + 11) % 12) + 1],
|
|
104
|
+
['h', d => (((d.getHours() + 11) % 12) + 1).toString()],
|
|
114
105
|
['mm', d => {
|
|
115
106
|
const val = d.getMinutes();
|
|
116
107
|
return (val < 10 ? '0' : '') + val;
|
|
117
108
|
}],
|
|
118
|
-
['m', d => d.getMinutes()],
|
|
109
|
+
['m', d => d.getMinutes().toString()],
|
|
119
110
|
['ss', d => {
|
|
120
111
|
const val = d.getSeconds();
|
|
121
112
|
return (val < 10 ? '0' : '') + val;
|
|
122
113
|
}],
|
|
123
|
-
['s', d => d.getSeconds()],
|
|
114
|
+
['s', d => d.getSeconds().toString()],
|
|
124
115
|
['SSS', d => {
|
|
125
116
|
const val = d.getMilliseconds();
|
|
126
117
|
return val < 10
|
|
127
118
|
? '00' + val
|
|
128
119
|
: val < 100
|
|
129
120
|
? '0' + val
|
|
130
|
-
: val;
|
|
121
|
+
: val.toString();
|
|
131
122
|
}],
|
|
132
123
|
['A', d => d.getHours() < 12 ? 'AM' : 'PM'],
|
|
133
124
|
['a', d => d.getHours() < 12 ? 'am' : 'pm'],
|
|
@@ -141,38 +132,35 @@ const Tokens = [
|
|
|
141
132
|
const token_map = {};
|
|
142
133
|
for (const t of Tokens)
|
|
143
134
|
token_map[t[0]] = t;
|
|
144
|
-
const
|
|
135
|
+
const PARSE_RGX = new RegExp('\\[[^\\]]*\\]|' + Tokens.map(([tok]) => tok).join('|'), 'g');
|
|
145
136
|
function getSpecChain(spec) {
|
|
146
137
|
const cached = spec_cache.get(spec);
|
|
147
138
|
if (cached !== undefined)
|
|
148
139
|
return cached;
|
|
149
|
-
let base = spec;
|
|
150
|
-
const repl = [];
|
|
151
|
-
let repl_len = 0;
|
|
152
|
-
if (base.indexOf('[') >= 0) {
|
|
153
|
-
base = base.replace(ESCAPE_RGX, (_, inner) => {
|
|
154
|
-
const escape_token = '$' + repl_len++ + '$';
|
|
155
|
-
repl.push([escape_token, inner]);
|
|
156
|
-
return escape_token;
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
TOKENS_RGX.lastIndex = 0;
|
|
160
140
|
const parts = [];
|
|
141
|
+
PARSE_RGX.lastIndex = 0;
|
|
161
142
|
let last_idx = 0;
|
|
162
143
|
let has_token = false;
|
|
163
144
|
let m;
|
|
164
|
-
while (m =
|
|
165
|
-
|
|
166
|
-
|
|
145
|
+
while (m = PARSE_RGX.exec(spec)) {
|
|
146
|
+
const match = m[0];
|
|
147
|
+
const match_start = m.index;
|
|
148
|
+
if (match_start > last_idx) {
|
|
149
|
+
parts.push(spec.slice(last_idx, match_start));
|
|
150
|
+
}
|
|
151
|
+
if (match.charCodeAt(0) === 91) {
|
|
152
|
+
parts.push(match.slice(1, -1));
|
|
167
153
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
154
|
+
else {
|
|
155
|
+
parts.push(token_map[match][1]);
|
|
156
|
+
has_token = true;
|
|
157
|
+
}
|
|
158
|
+
last_idx = match_start + match.length;
|
|
171
159
|
}
|
|
172
|
-
if (last_idx <
|
|
173
|
-
parts.push(
|
|
160
|
+
if (last_idx < spec.length) {
|
|
161
|
+
parts.push(spec.slice(last_idx));
|
|
174
162
|
}
|
|
175
|
-
const result = has_token ?
|
|
163
|
+
const result = has_token ? parts : null;
|
|
176
164
|
spec_cache.set(spec, result);
|
|
177
165
|
return result;
|
|
178
166
|
}
|
|
@@ -189,26 +177,16 @@ function format(val, spec, locale = DEFAULT_LOCALE, zone = DEFAULT_TZ, sow = DEF
|
|
|
189
177
|
throw new TypeError('format: locale must be a string');
|
|
190
178
|
if (typeof zone !== 'string')
|
|
191
179
|
throw new TypeError('format: zone must be a string');
|
|
192
|
-
const
|
|
193
|
-
if (!
|
|
180
|
+
const parts = getSpecChain(SPEC_ALIASES[spec] || spec);
|
|
181
|
+
if (!parts)
|
|
194
182
|
return n_val.toISOString();
|
|
195
183
|
const d = toZone(n_val, zone);
|
|
196
|
-
const { parts, repl } = n_spec;
|
|
197
184
|
let out = '';
|
|
198
185
|
for (let i = 0; i < parts.length; i++) {
|
|
199
186
|
const part = parts[i];
|
|
200
|
-
|
|
201
|
-
out += part.literal;
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
out += part.token[1](d, locale, sow);
|
|
205
|
-
}
|
|
187
|
+
out += typeof part === 'string' ? part : part(d, locale, sow);
|
|
206
188
|
}
|
|
207
|
-
|
|
208
|
-
for (let i = 0; i < repl.length; i++) {
|
|
209
|
-
result = result.replace(repl[i][0], repl[i][1]);
|
|
210
|
-
}
|
|
211
|
-
return result;
|
|
189
|
+
return out;
|
|
212
190
|
}
|
|
213
191
|
format.getLocale = function () {
|
|
214
192
|
return DEFAULT_LOCALE;
|
package/cjs/date/is.js
CHANGED
package/cjs/date/isFormat.js
CHANGED
|
@@ -8,47 +8,49 @@ exports.isDateFormat = isDateFormat;
|
|
|
8
8
|
exports.default = isDateFormat;
|
|
9
9
|
const LRU_1 = __importDefault(require("../caching/LRU"));
|
|
10
10
|
const SPECIAL_CHARS = /[.*+?^${}()|[\]\\]/g;
|
|
11
|
+
const CTX = { year: 0, month: 0, day: 0, hour: -1, is12: 0 };
|
|
11
12
|
const TOKENS = [
|
|
12
|
-
['YYYY', /\d{4}/.source,
|
|
13
|
-
|
|
14
|
-
return
|
|
13
|
+
['YYYY', /\d{4}/.source, raw => {
|
|
14
|
+
CTX.year = +raw;
|
|
15
|
+
return CTX.year > 0;
|
|
15
16
|
}],
|
|
16
|
-
['MM', /(?:0[1-9]|1[0-2])/.source,
|
|
17
|
-
|
|
18
|
-
return
|
|
17
|
+
['MM', /(?:0[1-9]|1[0-2])/.source, raw => {
|
|
18
|
+
CTX.month = +raw;
|
|
19
|
+
return CTX.month >= 1 && CTX.month <= 12;
|
|
19
20
|
}],
|
|
20
|
-
['DD', /(?:0[1-9]|[12][0-9]|3[01])/.source,
|
|
21
|
-
|
|
22
|
-
return
|
|
21
|
+
['DD', /(?:0[1-9]|[12][0-9]|3[01])/.source, raw => {
|
|
22
|
+
CTX.day = +raw;
|
|
23
|
+
return CTX.day >= 1 && CTX.day <= 31;
|
|
23
24
|
}],
|
|
24
|
-
['HH', /(?:[01][0-9]|2[0-3])/.source,
|
|
25
|
-
|
|
26
|
-
return
|
|
25
|
+
['HH', /(?:[01][0-9]|2[0-3])/.source, raw => {
|
|
26
|
+
CTX.hour = +raw;
|
|
27
|
+
return CTX.hour >= 0 && CTX.hour <= 23;
|
|
27
28
|
}],
|
|
28
29
|
['mm', /[0-5][0-9]/.source, () => true],
|
|
29
30
|
['ss', /[0-5][0-9]/.source, () => true],
|
|
30
31
|
['SSS', /\d{3}/.source, () => true],
|
|
31
32
|
['Q', /[1-4]/.source, () => true],
|
|
32
|
-
['A', /(?:AM|PM)/.source,
|
|
33
|
-
|
|
33
|
+
['A', /(?:AM|PM)/.source, raw => {
|
|
34
|
+
CTX.is12 = 1;
|
|
34
35
|
return raw === 'AM' || raw === 'PM';
|
|
35
36
|
}],
|
|
36
|
-
['a', /(?:am|pm)/.source,
|
|
37
|
-
|
|
37
|
+
['a', /(?:am|pm)/.source, raw => {
|
|
38
|
+
CTX.is12 = 1;
|
|
38
39
|
return raw === 'am' || raw === 'pm';
|
|
39
40
|
}],
|
|
40
41
|
['Z', /Z|[+-](?:0[0-9]|1[0-4]):[0-5][0-9]/.source, raw => {
|
|
41
42
|
if (raw === 'Z')
|
|
42
43
|
return true;
|
|
43
|
-
let hour = (raw[1] + raw[2])
|
|
44
|
-
if (raw
|
|
44
|
+
let hour = +(raw[1] + raw[2]);
|
|
45
|
+
if (raw.charCodeAt(0) === 45)
|
|
45
46
|
hour = -hour;
|
|
46
|
-
const minutes = (raw[4] + raw[5])
|
|
47
|
+
const minutes = +(raw[4] + raw[5]);
|
|
47
48
|
if (hour === 14 || hour === -12)
|
|
48
49
|
return minutes === 0;
|
|
49
|
-
return hour >= -11 && hour < 14 &&
|
|
50
|
+
return hour >= -11 && hour < 14 && (minutes === 0 || minutes === 15 || minutes === 30 || minutes === 45);
|
|
50
51
|
}],
|
|
51
52
|
];
|
|
53
|
+
TOKENS.sort((a, b) => b[0].length - a[0].length);
|
|
52
54
|
const SPEC_ALIASES = {
|
|
53
55
|
ISO: 'YYYY-MM-DDTHH:mm:ss{.SSS}Z',
|
|
54
56
|
};
|
|
@@ -85,14 +87,18 @@ function compileSpec(spec, is_chunk = false) {
|
|
|
85
87
|
cursor = end_idx + 1;
|
|
86
88
|
}
|
|
87
89
|
else {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const [token_key, token_rgx] = TOKENS[
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
let matched = false;
|
|
91
|
+
for (let i = 0; i < TOKENS.length; i++) {
|
|
92
|
+
const [token_key, token_rgx] = TOKENS[i];
|
|
93
|
+
if (spec.startsWith(token_key, cursor)) {
|
|
94
|
+
pat += '(' + token_rgx + ')';
|
|
95
|
+
tokens.push(i);
|
|
96
|
+
cursor += token_key.length;
|
|
97
|
+
matched = true;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
|
-
|
|
101
|
+
if (!matched) {
|
|
96
102
|
pat += spec[cursor].replace(SPECIAL_CHARS, '\\$&');
|
|
97
103
|
cursor++;
|
|
98
104
|
}
|
|
@@ -107,23 +113,26 @@ function isDateFormat(input, spec) {
|
|
|
107
113
|
return false;
|
|
108
114
|
if (typeof spec !== 'string')
|
|
109
115
|
throw new TypeError('isDateFormat: spec must be a string');
|
|
110
|
-
const
|
|
111
|
-
if (!tokens.length)
|
|
116
|
+
const compiled = compileSpec(SPEC_ALIASES[spec] || spec);
|
|
117
|
+
if (!compiled.tokens.length)
|
|
112
118
|
return false;
|
|
113
|
-
const patMatch = rgx.exec(input);
|
|
119
|
+
const patMatch = compiled.rgx.exec(input);
|
|
114
120
|
if (!patMatch)
|
|
115
121
|
return false;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
CTX.year = 0;
|
|
123
|
+
CTX.month = 0;
|
|
124
|
+
CTX.day = 0;
|
|
125
|
+
CTX.hour = -1;
|
|
126
|
+
CTX.is12 = 0;
|
|
127
|
+
const { tokens } = compiled;
|
|
128
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
129
|
+
const match = patMatch[i + 1];
|
|
130
|
+
if (match !== undefined && !TOKENS[tokens[i]][2](match))
|
|
121
131
|
return false;
|
|
122
132
|
}
|
|
123
|
-
|
|
124
|
-
if (day && month && !isValidDay(year || 2024, month, day))
|
|
133
|
+
if (CTX.day > 0 && CTX.month > 0 && !isValidDay(CTX.year || 2024, CTX.month, CTX.day))
|
|
125
134
|
return false;
|
|
126
|
-
if (is12
|
|
135
|
+
if (CTX.is12 === 1 && CTX.hour > 11)
|
|
127
136
|
return false;
|
|
128
137
|
return true;
|
|
129
138
|
}
|
package/cjs/formdata/toObject.js
CHANGED
package/cjs/hash/hexId.js
CHANGED
|
@@ -11,7 +11,7 @@ const POOL_SIZE = 16 * 1024;
|
|
|
11
11
|
const pool = new Uint8Array(POOL_SIZE);
|
|
12
12
|
let poolIdx = POOL_SIZE;
|
|
13
13
|
function hexId(size) {
|
|
14
|
-
if (typeof size !== 'number' || size <= 0)
|
|
14
|
+
if (typeof size !== 'number' || size <= 0 || (size | 0) !== size)
|
|
15
15
|
return '';
|
|
16
16
|
if (size > POOL_SIZE) {
|
|
17
17
|
const buf = new Uint8Array(size);
|
package/cjs/number/round.js
CHANGED
|
@@ -6,7 +6,7 @@ const ROUND_EPSILON = 1 + Number.EPSILON;
|
|
|
6
6
|
function round(val, precision = 0) {
|
|
7
7
|
if (!Number.isFinite(val))
|
|
8
8
|
throw new TypeError('Value should be numeric');
|
|
9
|
-
if (
|
|
9
|
+
if (typeof precision !== 'number' || precision <= 0 || (precision | 0) !== precision)
|
|
10
10
|
return Math.round(val * ROUND_EPSILON);
|
|
11
11
|
const exp = Math.pow(10, precision);
|
|
12
12
|
return Math.round((val * exp) * ROUND_EPSILON) / exp;
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { isDate } from './is';
|
|
2
1
|
function convertToDate(val) {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
switch (typeof val) {
|
|
3
|
+
case 'number': {
|
|
4
|
+
if (val !== val)
|
|
5
|
+
return null;
|
|
6
|
+
const d = new Date(val);
|
|
7
|
+
return d.getTime() === d.getTime() ? d : null;
|
|
8
|
+
}
|
|
9
|
+
case 'object':
|
|
10
|
+
return val instanceof Date && val.getTime() === val.getTime() ? val : null;
|
|
11
|
+
case 'string': {
|
|
12
|
+
const d = new Date(val);
|
|
13
|
+
return d.getTime() === d.getTime() ? d : null;
|
|
14
|
+
}
|
|
15
|
+
default:
|
|
16
|
+
return null;
|
|
5
17
|
}
|
|
6
|
-
else if (typeof val === 'string') {
|
|
7
|
-
const date = new Date(val);
|
|
8
|
-
return Number.isNaN(date.getTime()) ? null : date;
|
|
9
|
-
}
|
|
10
|
-
return null;
|
|
11
18
|
}
|
|
12
19
|
export { convertToDate, convertToDate as default };
|
package/esm/date/format.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { convertToDate } from './convertToDate';
|
|
2
|
-
import { MONTHS, MONTHS_LEAP } from './isFormat';
|
|
3
2
|
import LRU from '../caching/LRU';
|
|
4
3
|
const WEEK_STARTS = {
|
|
5
4
|
mon: 'mon',
|
|
@@ -9,7 +8,6 @@ const WEEK_STARTS = {
|
|
|
9
8
|
let DEFAULT_LOCALE = 'en-US';
|
|
10
9
|
let DEFAULT_TZ = Intl?.DateTimeFormat?.().resolvedOptions?.().timeZone || 'UTC';
|
|
11
10
|
let DEFAULT_SOW = 'mon';
|
|
12
|
-
const ESCAPE_RGX = /\[([^\]]*)]/g;
|
|
13
11
|
const intl_formatters = new LRU({ max_size: 100 });
|
|
14
12
|
const spec_cache = new LRU({ max_size: 100 });
|
|
15
13
|
const zone_offset_cache = new LRU({ max_size: 100 });
|
|
@@ -35,15 +33,8 @@ function WeekNr(d, sow) {
|
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
function toZone(d, zone) {
|
|
38
|
-
const year = d.getUTCFullYear();
|
|
39
|
-
const month = d.getUTCMonth();
|
|
40
|
-
const day = d.getUTCDate();
|
|
41
36
|
const time = d.getTime();
|
|
42
|
-
const
|
|
43
|
-
let doy = day;
|
|
44
|
-
for (let i = 0; i <= month; i++)
|
|
45
|
-
doy += daysInMonths[i];
|
|
46
|
-
const ckey = zone + ':' + year + ':' + doy;
|
|
37
|
+
const ckey = zone + ':' + Math.floor(time / 900000);
|
|
47
38
|
const cached = zone_offset_cache.get(ckey);
|
|
48
39
|
if (cached !== undefined)
|
|
49
40
|
return new Date(time + cached);
|
|
@@ -73,54 +64,54 @@ function runIntl(loc, token, props, val) {
|
|
|
73
64
|
return formatter.format(val);
|
|
74
65
|
}
|
|
75
66
|
const Tokens = [
|
|
76
|
-
['YYYY', d => d.getFullYear()],
|
|
77
|
-
['Q', d => ((d.getMonth() + 3) / 3) | 0],
|
|
67
|
+
['YYYY', d => d.getFullYear().toString()],
|
|
68
|
+
['Q', d => (((d.getMonth() + 3) / 3) | 0).toString()],
|
|
78
69
|
['MMMM', (d, loc) => runIntl(loc, 'MMMM', { month: 'long' }, d)],
|
|
79
70
|
['MMM', (d, loc) => runIntl(loc, 'MMM', { month: 'short' }, d)],
|
|
80
71
|
['MM', d => {
|
|
81
72
|
const val = d.getMonth() + 1;
|
|
82
73
|
return (val < 10 ? '0' : '') + val;
|
|
83
74
|
}],
|
|
84
|
-
['M', d => d.getMonth() + 1],
|
|
75
|
+
['M', d => (d.getMonth() + 1).toString()],
|
|
85
76
|
['WW', (d, loc, sow) => {
|
|
86
77
|
const val = WeekNr(d, sow);
|
|
87
78
|
return (val < 10 ? '0' : '') + val;
|
|
88
79
|
}],
|
|
89
|
-
['W', (d, loc, sow) => WeekNr(d, sow)],
|
|
80
|
+
['W', (d, loc, sow) => WeekNr(d, sow).toString()],
|
|
90
81
|
['DD', d => {
|
|
91
82
|
const val = d.getDate();
|
|
92
83
|
return (val < 10 ? '0' : '') + val;
|
|
93
84
|
}],
|
|
94
|
-
['D', d => d.getDate()],
|
|
85
|
+
['D', d => d.getDate().toString()],
|
|
95
86
|
['dddd', (d, loc) => runIntl(loc, 'dddd', { weekday: 'long' }, d)],
|
|
96
87
|
['ddd', (d, loc) => runIntl(loc, 'ddd', { weekday: 'short' }, d)],
|
|
97
88
|
['HH', d => {
|
|
98
89
|
const val = d.getHours();
|
|
99
90
|
return (val < 10 ? '0' : '') + val;
|
|
100
91
|
}],
|
|
101
|
-
['H', d => d.getHours()],
|
|
92
|
+
['H', d => d.getHours().toString()],
|
|
102
93
|
['hh', d => {
|
|
103
94
|
const val = ((d.getHours() + 11) % 12) + 1;
|
|
104
95
|
return (val < 10 ? '0' : '') + val;
|
|
105
96
|
}],
|
|
106
|
-
['h', d => ((d.getHours() + 11) % 12) + 1],
|
|
97
|
+
['h', d => (((d.getHours() + 11) % 12) + 1).toString()],
|
|
107
98
|
['mm', d => {
|
|
108
99
|
const val = d.getMinutes();
|
|
109
100
|
return (val < 10 ? '0' : '') + val;
|
|
110
101
|
}],
|
|
111
|
-
['m', d => d.getMinutes()],
|
|
102
|
+
['m', d => d.getMinutes().toString()],
|
|
112
103
|
['ss', d => {
|
|
113
104
|
const val = d.getSeconds();
|
|
114
105
|
return (val < 10 ? '0' : '') + val;
|
|
115
106
|
}],
|
|
116
|
-
['s', d => d.getSeconds()],
|
|
107
|
+
['s', d => d.getSeconds().toString()],
|
|
117
108
|
['SSS', d => {
|
|
118
109
|
const val = d.getMilliseconds();
|
|
119
110
|
return val < 10
|
|
120
111
|
? '00' + val
|
|
121
112
|
: val < 100
|
|
122
113
|
? '0' + val
|
|
123
|
-
: val;
|
|
114
|
+
: val.toString();
|
|
124
115
|
}],
|
|
125
116
|
['A', d => d.getHours() < 12 ? 'AM' : 'PM'],
|
|
126
117
|
['a', d => d.getHours() < 12 ? 'am' : 'pm'],
|
|
@@ -134,38 +125,35 @@ const Tokens = [
|
|
|
134
125
|
const token_map = {};
|
|
135
126
|
for (const t of Tokens)
|
|
136
127
|
token_map[t[0]] = t;
|
|
137
|
-
const
|
|
128
|
+
const PARSE_RGX = new RegExp('\\[[^\\]]*\\]|' + Tokens.map(([tok]) => tok).join('|'), 'g');
|
|
138
129
|
function getSpecChain(spec) {
|
|
139
130
|
const cached = spec_cache.get(spec);
|
|
140
131
|
if (cached !== undefined)
|
|
141
132
|
return cached;
|
|
142
|
-
let base = spec;
|
|
143
|
-
const repl = [];
|
|
144
|
-
let repl_len = 0;
|
|
145
|
-
if (base.indexOf('[') >= 0) {
|
|
146
|
-
base = base.replace(ESCAPE_RGX, (_, inner) => {
|
|
147
|
-
const escape_token = '$' + repl_len++ + '$';
|
|
148
|
-
repl.push([escape_token, inner]);
|
|
149
|
-
return escape_token;
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
TOKENS_RGX.lastIndex = 0;
|
|
153
133
|
const parts = [];
|
|
134
|
+
PARSE_RGX.lastIndex = 0;
|
|
154
135
|
let last_idx = 0;
|
|
155
136
|
let has_token = false;
|
|
156
137
|
let m;
|
|
157
|
-
while (m =
|
|
158
|
-
|
|
159
|
-
|
|
138
|
+
while (m = PARSE_RGX.exec(spec)) {
|
|
139
|
+
const match = m[0];
|
|
140
|
+
const match_start = m.index;
|
|
141
|
+
if (match_start > last_idx) {
|
|
142
|
+
parts.push(spec.slice(last_idx, match_start));
|
|
143
|
+
}
|
|
144
|
+
if (match.charCodeAt(0) === 91) {
|
|
145
|
+
parts.push(match.slice(1, -1));
|
|
160
146
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
147
|
+
else {
|
|
148
|
+
parts.push(token_map[match][1]);
|
|
149
|
+
has_token = true;
|
|
150
|
+
}
|
|
151
|
+
last_idx = match_start + match.length;
|
|
164
152
|
}
|
|
165
|
-
if (last_idx <
|
|
166
|
-
parts.push(
|
|
153
|
+
if (last_idx < spec.length) {
|
|
154
|
+
parts.push(spec.slice(last_idx));
|
|
167
155
|
}
|
|
168
|
-
const result = has_token ?
|
|
156
|
+
const result = has_token ? parts : null;
|
|
169
157
|
spec_cache.set(spec, result);
|
|
170
158
|
return result;
|
|
171
159
|
}
|
|
@@ -182,26 +170,16 @@ function format(val, spec, locale = DEFAULT_LOCALE, zone = DEFAULT_TZ, sow = DEF
|
|
|
182
170
|
throw new TypeError('format: locale must be a string');
|
|
183
171
|
if (typeof zone !== 'string')
|
|
184
172
|
throw new TypeError('format: zone must be a string');
|
|
185
|
-
const
|
|
186
|
-
if (!
|
|
173
|
+
const parts = getSpecChain(SPEC_ALIASES[spec] || spec);
|
|
174
|
+
if (!parts)
|
|
187
175
|
return n_val.toISOString();
|
|
188
176
|
const d = toZone(n_val, zone);
|
|
189
|
-
const { parts, repl } = n_spec;
|
|
190
177
|
let out = '';
|
|
191
178
|
for (let i = 0; i < parts.length; i++) {
|
|
192
179
|
const part = parts[i];
|
|
193
|
-
|
|
194
|
-
out += part.literal;
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
out += part.token[1](d, locale, sow);
|
|
198
|
-
}
|
|
180
|
+
out += typeof part === 'string' ? part : part(d, locale, sow);
|
|
199
181
|
}
|
|
200
|
-
|
|
201
|
-
for (let i = 0; i < repl.length; i++) {
|
|
202
|
-
result = result.replace(repl[i][0], repl[i][1]);
|
|
203
|
-
}
|
|
204
|
-
return result;
|
|
182
|
+
return out;
|
|
205
183
|
}
|
|
206
184
|
format.getLocale = function () {
|
|
207
185
|
return DEFAULT_LOCALE;
|
package/esm/date/is.js
CHANGED
package/esm/date/isFormat.js
CHANGED
|
@@ -1,46 +1,48 @@
|
|
|
1
1
|
import LRU from '../caching/LRU';
|
|
2
2
|
const SPECIAL_CHARS = /[.*+?^${}()|[\]\\]/g;
|
|
3
|
+
const CTX = { year: 0, month: 0, day: 0, hour: -1, is12: 0 };
|
|
3
4
|
const TOKENS = [
|
|
4
|
-
['YYYY', /\d{4}/.source,
|
|
5
|
-
|
|
6
|
-
return
|
|
5
|
+
['YYYY', /\d{4}/.source, raw => {
|
|
6
|
+
CTX.year = +raw;
|
|
7
|
+
return CTX.year > 0;
|
|
7
8
|
}],
|
|
8
|
-
['MM', /(?:0[1-9]|1[0-2])/.source,
|
|
9
|
-
|
|
10
|
-
return
|
|
9
|
+
['MM', /(?:0[1-9]|1[0-2])/.source, raw => {
|
|
10
|
+
CTX.month = +raw;
|
|
11
|
+
return CTX.month >= 1 && CTX.month <= 12;
|
|
11
12
|
}],
|
|
12
|
-
['DD', /(?:0[1-9]|[12][0-9]|3[01])/.source,
|
|
13
|
-
|
|
14
|
-
return
|
|
13
|
+
['DD', /(?:0[1-9]|[12][0-9]|3[01])/.source, raw => {
|
|
14
|
+
CTX.day = +raw;
|
|
15
|
+
return CTX.day >= 1 && CTX.day <= 31;
|
|
15
16
|
}],
|
|
16
|
-
['HH', /(?:[01][0-9]|2[0-3])/.source,
|
|
17
|
-
|
|
18
|
-
return
|
|
17
|
+
['HH', /(?:[01][0-9]|2[0-3])/.source, raw => {
|
|
18
|
+
CTX.hour = +raw;
|
|
19
|
+
return CTX.hour >= 0 && CTX.hour <= 23;
|
|
19
20
|
}],
|
|
20
21
|
['mm', /[0-5][0-9]/.source, () => true],
|
|
21
22
|
['ss', /[0-5][0-9]/.source, () => true],
|
|
22
23
|
['SSS', /\d{3}/.source, () => true],
|
|
23
24
|
['Q', /[1-4]/.source, () => true],
|
|
24
|
-
['A', /(?:AM|PM)/.source,
|
|
25
|
-
|
|
25
|
+
['A', /(?:AM|PM)/.source, raw => {
|
|
26
|
+
CTX.is12 = 1;
|
|
26
27
|
return raw === 'AM' || raw === 'PM';
|
|
27
28
|
}],
|
|
28
|
-
['a', /(?:am|pm)/.source,
|
|
29
|
-
|
|
29
|
+
['a', /(?:am|pm)/.source, raw => {
|
|
30
|
+
CTX.is12 = 1;
|
|
30
31
|
return raw === 'am' || raw === 'pm';
|
|
31
32
|
}],
|
|
32
33
|
['Z', /Z|[+-](?:0[0-9]|1[0-4]):[0-5][0-9]/.source, raw => {
|
|
33
34
|
if (raw === 'Z')
|
|
34
35
|
return true;
|
|
35
|
-
let hour = (raw[1] + raw[2])
|
|
36
|
-
if (raw
|
|
36
|
+
let hour = +(raw[1] + raw[2]);
|
|
37
|
+
if (raw.charCodeAt(0) === 45)
|
|
37
38
|
hour = -hour;
|
|
38
|
-
const minutes = (raw[4] + raw[5])
|
|
39
|
+
const minutes = +(raw[4] + raw[5]);
|
|
39
40
|
if (hour === 14 || hour === -12)
|
|
40
41
|
return minutes === 0;
|
|
41
|
-
return hour >= -11 && hour < 14 &&
|
|
42
|
+
return hour >= -11 && hour < 14 && (minutes === 0 || minutes === 15 || minutes === 30 || minutes === 45);
|
|
42
43
|
}],
|
|
43
44
|
];
|
|
45
|
+
TOKENS.sort((a, b) => b[0].length - a[0].length);
|
|
44
46
|
const SPEC_ALIASES = {
|
|
45
47
|
ISO: 'YYYY-MM-DDTHH:mm:ss{.SSS}Z',
|
|
46
48
|
};
|
|
@@ -77,14 +79,18 @@ function compileSpec(spec, is_chunk = false) {
|
|
|
77
79
|
cursor = end_idx + 1;
|
|
78
80
|
}
|
|
79
81
|
else {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const [token_key, token_rgx] = TOKENS[
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
let matched = false;
|
|
83
|
+
for (let i = 0; i < TOKENS.length; i++) {
|
|
84
|
+
const [token_key, token_rgx] = TOKENS[i];
|
|
85
|
+
if (spec.startsWith(token_key, cursor)) {
|
|
86
|
+
pat += '(' + token_rgx + ')';
|
|
87
|
+
tokens.push(i);
|
|
88
|
+
cursor += token_key.length;
|
|
89
|
+
matched = true;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
86
92
|
}
|
|
87
|
-
|
|
93
|
+
if (!matched) {
|
|
88
94
|
pat += spec[cursor].replace(SPECIAL_CHARS, '\\$&');
|
|
89
95
|
cursor++;
|
|
90
96
|
}
|
|
@@ -99,23 +105,26 @@ function isDateFormat(input, spec) {
|
|
|
99
105
|
return false;
|
|
100
106
|
if (typeof spec !== 'string')
|
|
101
107
|
throw new TypeError('isDateFormat: spec must be a string');
|
|
102
|
-
const
|
|
103
|
-
if (!tokens.length)
|
|
108
|
+
const compiled = compileSpec(SPEC_ALIASES[spec] || spec);
|
|
109
|
+
if (!compiled.tokens.length)
|
|
104
110
|
return false;
|
|
105
|
-
const patMatch = rgx.exec(input);
|
|
111
|
+
const patMatch = compiled.rgx.exec(input);
|
|
106
112
|
if (!patMatch)
|
|
107
113
|
return false;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
114
|
+
CTX.year = 0;
|
|
115
|
+
CTX.month = 0;
|
|
116
|
+
CTX.day = 0;
|
|
117
|
+
CTX.hour = -1;
|
|
118
|
+
CTX.is12 = 0;
|
|
119
|
+
const { tokens } = compiled;
|
|
120
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
121
|
+
const match = patMatch[i + 1];
|
|
122
|
+
if (match !== undefined && !TOKENS[tokens[i]][2](match))
|
|
113
123
|
return false;
|
|
114
124
|
}
|
|
115
|
-
|
|
116
|
-
if (day && month && !isValidDay(year || 2024, month, day))
|
|
125
|
+
if (CTX.day > 0 && CTX.month > 0 && !isValidDay(CTX.year || 2024, CTX.month, CTX.day))
|
|
117
126
|
return false;
|
|
118
|
-
if (is12
|
|
127
|
+
if (CTX.is12 === 1 && CTX.hour > 11)
|
|
119
128
|
return false;
|
|
120
129
|
return true;
|
|
121
130
|
}
|
package/esm/formdata/toObject.js
CHANGED
package/esm/hash/hexId.js
CHANGED
|
@@ -7,7 +7,7 @@ const POOL_SIZE = 16 * 1024;
|
|
|
7
7
|
const pool = new Uint8Array(POOL_SIZE);
|
|
8
8
|
let poolIdx = POOL_SIZE;
|
|
9
9
|
function hexId(size) {
|
|
10
|
-
if (typeof size !== 'number' || size <= 0)
|
|
10
|
+
if (typeof size !== 'number' || size <= 0 || (size | 0) !== size)
|
|
11
11
|
return '';
|
|
12
12
|
if (size > POOL_SIZE) {
|
|
13
13
|
const buf = new Uint8Array(size);
|
package/esm/number/round.js
CHANGED
|
@@ -2,7 +2,7 @@ const ROUND_EPSILON = 1 + Number.EPSILON;
|
|
|
2
2
|
function round(val, precision = 0) {
|
|
3
3
|
if (!Number.isFinite(val))
|
|
4
4
|
throw new TypeError('Value should be numeric');
|
|
5
|
-
if (
|
|
5
|
+
if (typeof precision !== 'number' || precision <= 0 || (precision | 0) !== precision)
|
|
6
6
|
return Math.round(val * ROUND_EPSILON);
|
|
7
7
|
const exp = Math.pow(10, precision);
|
|
8
8
|
return Math.round((val * exp) * ROUND_EPSILON) / exp;
|
package/index.d.ts
CHANGED
|
@@ -163,10 +163,6 @@ declare module "boolean/is" {
|
|
|
163
163
|
declare module "boolean/index" {
|
|
164
164
|
export { isBoolean } from "boolean/is";
|
|
165
165
|
}
|
|
166
|
-
declare module "date/is" {
|
|
167
|
-
function isDate(val: unknown): val is Date;
|
|
168
|
-
export { isDate, isDate as default };
|
|
169
|
-
}
|
|
170
166
|
declare module "date/convertToDate" {
|
|
171
167
|
function convertToDate(val: Date | string | number): Date | null;
|
|
172
168
|
export { convertToDate, convertToDate as default };
|
|
@@ -211,12 +207,6 @@ declare module "caching/LRU" {
|
|
|
211
207
|
}
|
|
212
208
|
export { LRUCache, LRUCache as default };
|
|
213
209
|
}
|
|
214
|
-
declare module "date/isFormat" {
|
|
215
|
-
export const MONTHS_LEAP: number[];
|
|
216
|
-
export const MONTHS: number[];
|
|
217
|
-
function isDateFormat(input: unknown, spec: string): input is string;
|
|
218
|
-
export { isDateFormat, isDateFormat as default };
|
|
219
|
-
}
|
|
220
210
|
declare module "date/format" {
|
|
221
211
|
const WEEK_STARTS: {
|
|
222
212
|
readonly mon: "mon";
|
|
@@ -266,6 +256,10 @@ declare module "date/startOfUTC" {
|
|
|
266
256
|
function startOfUTC(val: Date | string, key?: StartOfUTCKey): Date;
|
|
267
257
|
export { startOfUTC, startOfUTC as default };
|
|
268
258
|
}
|
|
259
|
+
declare module "date/is" {
|
|
260
|
+
function isDate(val: unknown): val is Date;
|
|
261
|
+
export { isDate, isDate as default };
|
|
262
|
+
}
|
|
269
263
|
declare module "date/toUnix" {
|
|
270
264
|
function toUnix(val: Date): number;
|
|
271
265
|
export { toUnix, toUnix as default };
|
|
@@ -274,6 +268,12 @@ declare module "date/toUTC" {
|
|
|
274
268
|
function toUTC(val: Date): Date;
|
|
275
269
|
export { toUTC, toUTC as default };
|
|
276
270
|
}
|
|
271
|
+
declare module "date/isFormat" {
|
|
272
|
+
export const MONTHS_LEAP: number[];
|
|
273
|
+
export const MONTHS: number[];
|
|
274
|
+
function isDateFormat(input: unknown, spec: string): input is string;
|
|
275
|
+
export { isDateFormat, isDateFormat as default };
|
|
276
|
+
}
|
|
277
277
|
declare module "date/index" {
|
|
278
278
|
export { addUTC } from "date/addUTC";
|
|
279
279
|
export { convertToDate } from "date/convertToDate";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valkyriestudios/utils",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.49.0",
|
|
4
4
|
"description": "A collection of single-function utilities for common tasks",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Peter Vermeulen",
|
|
@@ -609,12 +609,12 @@
|
|
|
609
609
|
}
|
|
610
610
|
},
|
|
611
611
|
"devDependencies": {
|
|
612
|
-
"@types/node": "^22.19.
|
|
613
|
-
"@vitest/coverage-v8": "^4.0.
|
|
612
|
+
"@types/node": "^22.19.11",
|
|
613
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
614
614
|
"esbuild-register": "^3.6.0",
|
|
615
615
|
"eslint": "^9.39.2",
|
|
616
616
|
"typescript": "^5.9.3",
|
|
617
617
|
"typescript-eslint": "^8.51.0",
|
|
618
|
-
"vitest": "^4.0.
|
|
618
|
+
"vitest": "^4.0.18"
|
|
619
619
|
}
|
|
620
620
|
}
|