@catbee/utils 2.0.2 → 2.0.4
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/config/index.cjs +0 -5
- package/config/index.mjs +0 -5
- package/crypto/index.cjs +297 -1
- package/crypto/index.d.ts +229 -2
- package/crypto/index.mjs +292 -3
- package/date/index.cjs +276 -0
- package/date/index.d.ts +44 -1
- package/date/index.mjs +273 -1
- package/error/index.cjs +58 -0
- package/error/index.d.ts +62 -0
- package/error/index.mjs +54 -0
- package/index.cjs +7 -0
- package/index.d.ts +1 -0
- package/index.mjs +1 -0
- package/logger/index.cjs +13 -12
- package/logger/index.d.ts +5 -5
- package/logger/index.mjs +13 -12
- package/package.json +6 -2
- package/server/index.cjs +129 -272
- package/server/index.d.ts +22 -59
- package/server/index.mjs +129 -272
- package/types/index.d.ts +0 -22
package/crypto/index.mjs
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import { pbkdf2, scrypt, createHmac, createHash, randomBytes, timingSafeEqual, createCipheriv, createDecipheriv } from 'crypto';
|
|
25
|
+
import { pbkdf2, scrypt, webcrypto, createHmac, createHash, randomBytes, timingSafeEqual, createCipheriv, createDecipheriv } from 'crypto';
|
|
26
26
|
import { promisify } from 'util';
|
|
27
27
|
import { uuid } from '@catbee/utils/id';
|
|
28
28
|
|
|
@@ -54,6 +54,287 @@ function md5(input) {
|
|
|
54
54
|
return hash("md5", input);
|
|
55
55
|
}
|
|
56
56
|
__name(md5, "md5");
|
|
57
|
+
var DEFAULT_SIGNATURE_ENCODING = "base64url";
|
|
58
|
+
var subtle = globalThis.crypto?.subtle ?? webcrypto.subtle;
|
|
59
|
+
function getDigestLength(hash2) {
|
|
60
|
+
switch (hash2) {
|
|
61
|
+
case "SHA-256":
|
|
62
|
+
return 32;
|
|
63
|
+
case "SHA-384":
|
|
64
|
+
return 48;
|
|
65
|
+
case "SHA-512":
|
|
66
|
+
return 64;
|
|
67
|
+
default:
|
|
68
|
+
return 32;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
__name(getDigestLength, "getDigestLength");
|
|
72
|
+
function resolveKeyAlgorithm({ type = "RSA-PSS", modulusLength = 2048, hash: hash2 = "SHA-256", namedCurve = "P-256" }) {
|
|
73
|
+
switch (type) {
|
|
74
|
+
case "RSA":
|
|
75
|
+
if (!Number.isInteger(modulusLength) || modulusLength < 2048) {
|
|
76
|
+
throw new Error("RSA modulusLength must be an integer greater than or equal to 2048");
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
80
|
+
modulusLength,
|
|
81
|
+
publicExponent: new Uint8Array([
|
|
82
|
+
1,
|
|
83
|
+
0,
|
|
84
|
+
1
|
|
85
|
+
]),
|
|
86
|
+
hash: hash2
|
|
87
|
+
};
|
|
88
|
+
case "RSA-PSS":
|
|
89
|
+
if (!Number.isInteger(modulusLength) || modulusLength < 2048) {
|
|
90
|
+
throw new Error("RSA-PSS modulusLength must be an integer greater than or equal to 2048");
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
name: "RSA-PSS",
|
|
94
|
+
modulusLength,
|
|
95
|
+
publicExponent: new Uint8Array([
|
|
96
|
+
1,
|
|
97
|
+
0,
|
|
98
|
+
1
|
|
99
|
+
]),
|
|
100
|
+
hash: hash2
|
|
101
|
+
};
|
|
102
|
+
case "ECDSA":
|
|
103
|
+
return {
|
|
104
|
+
name: "ECDSA",
|
|
105
|
+
namedCurve
|
|
106
|
+
};
|
|
107
|
+
case "Ed25519":
|
|
108
|
+
return {
|
|
109
|
+
name: "Ed25519"
|
|
110
|
+
};
|
|
111
|
+
default:
|
|
112
|
+
throw new Error(`Unsupported key type: ${type}. Supported types: RSA, RSA-PSS, ECDSA, Ed25519`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
__name(resolveKeyAlgorithm, "resolveKeyAlgorithm");
|
|
116
|
+
function toBase64(buffer) {
|
|
117
|
+
if (typeof Buffer !== "undefined") {
|
|
118
|
+
return Buffer.from(buffer).toString("base64");
|
|
119
|
+
}
|
|
120
|
+
let binary = "";
|
|
121
|
+
const bytes = new Uint8Array(buffer);
|
|
122
|
+
const chunkSize = 32768;
|
|
123
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
124
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
|
|
125
|
+
}
|
|
126
|
+
return btoa(binary);
|
|
127
|
+
}
|
|
128
|
+
__name(toBase64, "toBase64");
|
|
129
|
+
function toPEM(base64, type, formatPemLines, addPrefixSuffix) {
|
|
130
|
+
const formattedBase64 = formatPemLines ? base64.match(/.{1,64}/g)?.join("\n") ?? base64 : base64;
|
|
131
|
+
if (!addPrefixSuffix) {
|
|
132
|
+
return formattedBase64;
|
|
133
|
+
}
|
|
134
|
+
const prefix = `-----BEGIN ${type}-----`;
|
|
135
|
+
const suffix = `-----END ${type}-----`;
|
|
136
|
+
return `${prefix}
|
|
137
|
+
${formattedBase64}
|
|
138
|
+
${suffix}`;
|
|
139
|
+
}
|
|
140
|
+
__name(toPEM, "toPEM");
|
|
141
|
+
function fromPEM(pem) {
|
|
142
|
+
const trimmedPem = pem.trim();
|
|
143
|
+
const format = trimmedPem.includes("BEGIN PRIVATE KEY") ? "pkcs8" : trimmedPem.includes("BEGIN PUBLIC KEY") ? "spki" : void 0;
|
|
144
|
+
if (!format) {
|
|
145
|
+
throw new Error("Unsupported PEM format. Expected PUBLIC KEY or PRIVATE KEY PEM block");
|
|
146
|
+
}
|
|
147
|
+
const base64 = trimmedPem.replace(/-----BEGIN [A-Z ]+-----/g, "").replace(/-----END [A-Z ]+-----/g, "").replace(/\s+/g, "");
|
|
148
|
+
return {
|
|
149
|
+
format,
|
|
150
|
+
binary: toArrayBuffer(Buffer.from(base64, "base64"))
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
__name(fromPEM, "fromPEM");
|
|
154
|
+
function toBinary(data, encoding = "utf8") {
|
|
155
|
+
if (typeof data === "string") {
|
|
156
|
+
return Uint8Array.from(Buffer.from(data, encoding));
|
|
157
|
+
}
|
|
158
|
+
if (Buffer.isBuffer(data)) {
|
|
159
|
+
return Uint8Array.from(data);
|
|
160
|
+
}
|
|
161
|
+
return data;
|
|
162
|
+
}
|
|
163
|
+
__name(toBinary, "toBinary");
|
|
164
|
+
function toArrayBuffer(data) {
|
|
165
|
+
const byteView = data instanceof Uint8Array ? data : Uint8Array.from(data);
|
|
166
|
+
const copy = new Uint8Array(byteView.byteLength);
|
|
167
|
+
copy.set(byteView);
|
|
168
|
+
return copy.buffer;
|
|
169
|
+
}
|
|
170
|
+
__name(toArrayBuffer, "toArrayBuffer");
|
|
171
|
+
function inferKeyTypeFromJwk(jwk, fallback) {
|
|
172
|
+
if (fallback) {
|
|
173
|
+
return fallback;
|
|
174
|
+
}
|
|
175
|
+
const keyType = typeof jwk.kty === "string" ? jwk.kty : void 0;
|
|
176
|
+
const curve = typeof jwk.crv === "string" ? jwk.crv : void 0;
|
|
177
|
+
const algorithm = typeof jwk.alg === "string" ? jwk.alg : void 0;
|
|
178
|
+
if (keyType === "OKP" && curve === "Ed25519") {
|
|
179
|
+
return "Ed25519";
|
|
180
|
+
}
|
|
181
|
+
if (keyType === "EC") {
|
|
182
|
+
return "ECDSA";
|
|
183
|
+
}
|
|
184
|
+
if (keyType === "RSA") {
|
|
185
|
+
return algorithm?.startsWith("PS") ? "RSA-PSS" : "RSA";
|
|
186
|
+
}
|
|
187
|
+
throw new Error("Unable to infer key type from JWK. Provide import options with an explicit type");
|
|
188
|
+
}
|
|
189
|
+
__name(inferKeyTypeFromJwk, "inferKeyTypeFromJwk");
|
|
190
|
+
function resolveDefaultUsages(format, usages) {
|
|
191
|
+
return usages ?? (format === "pkcs8" ? [
|
|
192
|
+
"sign"
|
|
193
|
+
] : [
|
|
194
|
+
"verify"
|
|
195
|
+
]);
|
|
196
|
+
}
|
|
197
|
+
__name(resolveDefaultUsages, "resolveDefaultUsages");
|
|
198
|
+
function inferJwkUsages(jwk, usages) {
|
|
199
|
+
if (usages) {
|
|
200
|
+
return usages;
|
|
201
|
+
}
|
|
202
|
+
if (Array.isArray(jwk.key_ops)) {
|
|
203
|
+
const inferredFromKeyOps = jwk.key_ops.filter((usage) => usage === "sign" || usage === "verify");
|
|
204
|
+
if (inferredFromKeyOps.length === 0) {
|
|
205
|
+
throw new Error("JWK key_ops must include at least one of sign or verify when provided");
|
|
206
|
+
}
|
|
207
|
+
return inferredFromKeyOps;
|
|
208
|
+
}
|
|
209
|
+
if (typeof jwk.d === "string" && jwk.d.length > 0) {
|
|
210
|
+
return [
|
|
211
|
+
"sign"
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
return [
|
|
215
|
+
"verify"
|
|
216
|
+
];
|
|
217
|
+
}
|
|
218
|
+
__name(inferJwkUsages, "inferJwkUsages");
|
|
219
|
+
function resolveSignAlgorithm(key, options = {}) {
|
|
220
|
+
const hash2 = options.hash ?? "SHA-256";
|
|
221
|
+
switch (key.algorithm.name) {
|
|
222
|
+
case "RSASSA-PKCS1-v1_5":
|
|
223
|
+
return "RSASSA-PKCS1-v1_5";
|
|
224
|
+
case "RSA-PSS": {
|
|
225
|
+
const keyAlgorithm = key.algorithm;
|
|
226
|
+
const pssHash = options.hash ?? keyAlgorithm.hash.name;
|
|
227
|
+
return {
|
|
228
|
+
name: "RSA-PSS",
|
|
229
|
+
saltLength: options.saltLength ?? getDigestLength(pssHash)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
case "ECDSA":
|
|
233
|
+
return {
|
|
234
|
+
name: "ECDSA",
|
|
235
|
+
hash: hash2
|
|
236
|
+
};
|
|
237
|
+
case "Ed25519":
|
|
238
|
+
return "Ed25519";
|
|
239
|
+
default:
|
|
240
|
+
throw new Error(`Unsupported signing key algorithm: ${key.algorithm.name}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
__name(resolveSignAlgorithm, "resolveSignAlgorithm");
|
|
244
|
+
function arrayBufferToBuffer(buffer) {
|
|
245
|
+
return Buffer.from(buffer);
|
|
246
|
+
}
|
|
247
|
+
__name(arrayBufferToBuffer, "arrayBufferToBuffer");
|
|
248
|
+
async function generateKeys(options = {}) {
|
|
249
|
+
const { type = "RSA-PSS", modulusLength = 2048, hash: hash2 = "SHA-256", namedCurve = "P-256", extractable = false, includeCryptoKeys = false, formatPemLines = true, addPrefixSuffix = true } = options;
|
|
250
|
+
const algorithm = resolveKeyAlgorithm({
|
|
251
|
+
type,
|
|
252
|
+
modulusLength,
|
|
253
|
+
hash: hash2,
|
|
254
|
+
namedCurve
|
|
255
|
+
});
|
|
256
|
+
const usages = [
|
|
257
|
+
"sign",
|
|
258
|
+
"verify"
|
|
259
|
+
];
|
|
260
|
+
const keyPair = await subtle.generateKey(algorithm, extractable, usages);
|
|
261
|
+
const [publicKeyBuf, privateKeyBuf] = await Promise.all([
|
|
262
|
+
subtle.exportKey("spki", keyPair.publicKey),
|
|
263
|
+
extractable ? subtle.exportKey("pkcs8", keyPair.privateKey) : Promise.resolve(void 0)
|
|
264
|
+
]);
|
|
265
|
+
const publicKeyBase64 = toBase64(publicKeyBuf);
|
|
266
|
+
const privateKeyBase64 = privateKeyBuf ? toBase64(privateKeyBuf) : void 0;
|
|
267
|
+
const result = {
|
|
268
|
+
type,
|
|
269
|
+
publicKey: toPEM(publicKeyBase64, "PUBLIC KEY", formatPemLines, addPrefixSuffix),
|
|
270
|
+
publicKeyBuffer: publicKeyBuf
|
|
271
|
+
};
|
|
272
|
+
if (privateKeyBase64 && privateKeyBuf) {
|
|
273
|
+
result.privateKey = toPEM(privateKeyBase64, "PRIVATE KEY", formatPemLines, addPrefixSuffix);
|
|
274
|
+
result.privateKeyBuffer = privateKeyBuf;
|
|
275
|
+
}
|
|
276
|
+
if (includeCryptoKeys) {
|
|
277
|
+
result.privateKeyCrypto = keyPair.privateKey;
|
|
278
|
+
result.publicKeyCrypto = keyPair.publicKey;
|
|
279
|
+
}
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
__name(generateKeys, "generateKeys");
|
|
283
|
+
async function sign(data, privateKeyCrypto, options = {}) {
|
|
284
|
+
const algorithm = resolveSignAlgorithm(privateKeyCrypto, options);
|
|
285
|
+
const signature = await subtle.sign(algorithm, privateKeyCrypto, toArrayBuffer(toBinary(data, options.inputEncoding)));
|
|
286
|
+
return arrayBufferToBuffer(signature).toString(options.outputEncoding ?? DEFAULT_SIGNATURE_ENCODING);
|
|
287
|
+
}
|
|
288
|
+
__name(sign, "sign");
|
|
289
|
+
async function verify(data, signature, publicKeyCrypto, options = {}) {
|
|
290
|
+
const algorithm = resolveSignAlgorithm(publicKeyCrypto, options);
|
|
291
|
+
const signatureBytes = typeof signature === "string" ? Uint8Array.from(Buffer.from(signature, options.signatureEncoding ?? DEFAULT_SIGNATURE_ENCODING)) : toBinary(signature);
|
|
292
|
+
return subtle.verify(algorithm, publicKeyCrypto, toArrayBuffer(signatureBytes), toArrayBuffer(toBinary(data, options.inputEncoding)));
|
|
293
|
+
}
|
|
294
|
+
__name(verify, "verify");
|
|
295
|
+
async function importKey(key, options = {}) {
|
|
296
|
+
const extractable = options.extractable ?? false;
|
|
297
|
+
if (typeof key === "string") {
|
|
298
|
+
if (!options.type) {
|
|
299
|
+
throw new Error("Key type is required when importing PEM keys");
|
|
300
|
+
}
|
|
301
|
+
const { format, binary } = fromPEM(key);
|
|
302
|
+
const algorithm2 = resolveKeyAlgorithm({
|
|
303
|
+
type: options.type,
|
|
304
|
+
hash: options.hash,
|
|
305
|
+
namedCurve: options.namedCurve
|
|
306
|
+
});
|
|
307
|
+
return subtle.importKey(format, binary, algorithm2, extractable, resolveDefaultUsages(format, options.usages));
|
|
308
|
+
}
|
|
309
|
+
const keyType = inferKeyTypeFromJwk(key, options.type);
|
|
310
|
+
const algorithm = resolveKeyAlgorithm({
|
|
311
|
+
type: keyType,
|
|
312
|
+
hash: options.hash,
|
|
313
|
+
namedCurve: options.namedCurve
|
|
314
|
+
});
|
|
315
|
+
return subtle.importKey("jwk", key, algorithm, extractable, inferJwkUsages(key, options.usages));
|
|
316
|
+
}
|
|
317
|
+
__name(importKey, "importKey");
|
|
318
|
+
async function exportKey(key, format = "jwk", options = {}) {
|
|
319
|
+
if (format === "jwk") {
|
|
320
|
+
return subtle.exportKey("jwk", key);
|
|
321
|
+
}
|
|
322
|
+
const binary = key.type === "private" ? await subtle.exportKey("pkcs8", key) : await subtle.exportKey("spki", key);
|
|
323
|
+
return toPEM(toBase64(binary), key.type === "private" ? "PRIVATE KEY" : "PUBLIC KEY", options.formatPemLines ?? true, options.addPrefixSuffix ?? true);
|
|
324
|
+
}
|
|
325
|
+
__name(exportKey, "exportKey");
|
|
326
|
+
async function fingerprint(publicKey, encoding = "base64url") {
|
|
327
|
+
if (publicKey.type !== "public") {
|
|
328
|
+
throw new Error("fingerprint requires a public key");
|
|
329
|
+
}
|
|
330
|
+
const spki = await subtle.exportKey("spki", publicKey);
|
|
331
|
+
return createHash("sha256").update(arrayBufferToBuffer(spki)).digest(encoding);
|
|
332
|
+
}
|
|
333
|
+
__name(fingerprint, "fingerprint");
|
|
334
|
+
async function getKeyId(publicKey) {
|
|
335
|
+
return fingerprint(publicKey, "base64url");
|
|
336
|
+
}
|
|
337
|
+
__name(getKeyId, "getKeyId");
|
|
57
338
|
function randomString() {
|
|
58
339
|
return sha256(uuid());
|
|
59
340
|
}
|
|
@@ -174,8 +455,16 @@ function generateNonce(byteLength = 16, encoding = "hex") {
|
|
|
174
455
|
}
|
|
175
456
|
__name(generateNonce, "generateNonce");
|
|
176
457
|
function secureRandomInt(min, max) {
|
|
177
|
-
if (min
|
|
458
|
+
if (!Number.isSafeInteger(min) || !Number.isSafeInteger(max)) {
|
|
459
|
+
throw new TypeError("min and max must be safe integers");
|
|
460
|
+
}
|
|
461
|
+
if (min > max) {
|
|
462
|
+
throw new RangeError("min must be less than or equal to max");
|
|
463
|
+
}
|
|
178
464
|
const range = max - min + 1;
|
|
465
|
+
if (!Number.isSafeInteger(range) || range <= 0) {
|
|
466
|
+
throw new RangeError("Range is too large");
|
|
467
|
+
}
|
|
179
468
|
const bytesNeeded = Math.ceil(Math.log2(range) / 8);
|
|
180
469
|
const maxValid = Math.floor(256 ** bytesNeeded / range) * range;
|
|
181
470
|
let randomValue;
|
|
@@ -208,4 +497,4 @@ async function verifyPassword(password, hash2) {
|
|
|
208
497
|
}
|
|
209
498
|
__name(verifyPassword, "verifyPassword");
|
|
210
499
|
|
|
211
|
-
export { createSignedToken, decrypt, encrypt, generateApiKey, generateNonce, generateRandomBytes, generateRandomBytesAsString, hash, hashPassword, hmac, md5, pbkdf2Hash, randomString, safeCompare, secureRandomInt, sha1, sha256, sha256Hmac, verifyPassword, verifySignedToken };
|
|
500
|
+
export { createSignedToken, decrypt, encrypt, exportKey, fingerprint, generateApiKey, generateKeys, generateNonce, generateRandomBytes, generateRandomBytesAsString, getKeyId, hash, hashPassword, hmac, importKey, md5, pbkdf2Hash, randomString, safeCompare, secureRandomInt, sha1, sha256, sha256Hmac, sign, verify, verifyPassword, verifySignedToken };
|
package/date/index.cjs
CHANGED
|
@@ -575,6 +575,278 @@ function getTimeZoneParts(date, timeZone) {
|
|
|
575
575
|
};
|
|
576
576
|
}
|
|
577
577
|
__name(getTimeZoneParts, "getTimeZoneParts");
|
|
578
|
+
var COUNTRY_CODES = [
|
|
579
|
+
"AD",
|
|
580
|
+
"AE",
|
|
581
|
+
"AF",
|
|
582
|
+
"AG",
|
|
583
|
+
"AI",
|
|
584
|
+
"AL",
|
|
585
|
+
"AM",
|
|
586
|
+
"AO",
|
|
587
|
+
"AQ",
|
|
588
|
+
"AR",
|
|
589
|
+
"AS",
|
|
590
|
+
"AT",
|
|
591
|
+
"AU",
|
|
592
|
+
"AW",
|
|
593
|
+
"AX",
|
|
594
|
+
"AZ",
|
|
595
|
+
"BA",
|
|
596
|
+
"BB",
|
|
597
|
+
"BD",
|
|
598
|
+
"BE",
|
|
599
|
+
"BF",
|
|
600
|
+
"BG",
|
|
601
|
+
"BH",
|
|
602
|
+
"BI",
|
|
603
|
+
"BJ",
|
|
604
|
+
"BL",
|
|
605
|
+
"BM",
|
|
606
|
+
"BN",
|
|
607
|
+
"BO",
|
|
608
|
+
"BQ",
|
|
609
|
+
"BR",
|
|
610
|
+
"BS",
|
|
611
|
+
"BT",
|
|
612
|
+
"BV",
|
|
613
|
+
"BW",
|
|
614
|
+
"BY",
|
|
615
|
+
"BZ",
|
|
616
|
+
"CA",
|
|
617
|
+
"CC",
|
|
618
|
+
"CD",
|
|
619
|
+
"CF",
|
|
620
|
+
"CG",
|
|
621
|
+
"CH",
|
|
622
|
+
"CI",
|
|
623
|
+
"CK",
|
|
624
|
+
"CL",
|
|
625
|
+
"CM",
|
|
626
|
+
"CN",
|
|
627
|
+
"CO",
|
|
628
|
+
"CR",
|
|
629
|
+
"CU",
|
|
630
|
+
"CV",
|
|
631
|
+
"CW",
|
|
632
|
+
"CX",
|
|
633
|
+
"CY",
|
|
634
|
+
"CZ",
|
|
635
|
+
"DE",
|
|
636
|
+
"DJ",
|
|
637
|
+
"DK",
|
|
638
|
+
"DM",
|
|
639
|
+
"DO",
|
|
640
|
+
"DZ",
|
|
641
|
+
"EC",
|
|
642
|
+
"EE",
|
|
643
|
+
"EG",
|
|
644
|
+
"EH",
|
|
645
|
+
"ER",
|
|
646
|
+
"ES",
|
|
647
|
+
"ET",
|
|
648
|
+
"FI",
|
|
649
|
+
"FJ",
|
|
650
|
+
"FK",
|
|
651
|
+
"FM",
|
|
652
|
+
"FO",
|
|
653
|
+
"FR",
|
|
654
|
+
"GA",
|
|
655
|
+
"GB",
|
|
656
|
+
"GD",
|
|
657
|
+
"GE",
|
|
658
|
+
"GF",
|
|
659
|
+
"GG",
|
|
660
|
+
"GH",
|
|
661
|
+
"GI",
|
|
662
|
+
"GL",
|
|
663
|
+
"GM",
|
|
664
|
+
"GN",
|
|
665
|
+
"GP",
|
|
666
|
+
"GQ",
|
|
667
|
+
"GR",
|
|
668
|
+
"GS",
|
|
669
|
+
"GT",
|
|
670
|
+
"GU",
|
|
671
|
+
"GW",
|
|
672
|
+
"GY",
|
|
673
|
+
"HK",
|
|
674
|
+
"HM",
|
|
675
|
+
"HN",
|
|
676
|
+
"HR",
|
|
677
|
+
"HT",
|
|
678
|
+
"HU",
|
|
679
|
+
"ID",
|
|
680
|
+
"IE",
|
|
681
|
+
"IL",
|
|
682
|
+
"IM",
|
|
683
|
+
"IN",
|
|
684
|
+
"IO",
|
|
685
|
+
"IQ",
|
|
686
|
+
"IR",
|
|
687
|
+
"IS",
|
|
688
|
+
"IT",
|
|
689
|
+
"JE",
|
|
690
|
+
"JM",
|
|
691
|
+
"JO",
|
|
692
|
+
"JP",
|
|
693
|
+
"KE",
|
|
694
|
+
"KG",
|
|
695
|
+
"KH",
|
|
696
|
+
"KI",
|
|
697
|
+
"KM",
|
|
698
|
+
"KN",
|
|
699
|
+
"KP",
|
|
700
|
+
"KR",
|
|
701
|
+
"KW",
|
|
702
|
+
"KY",
|
|
703
|
+
"KZ",
|
|
704
|
+
"LA",
|
|
705
|
+
"LB",
|
|
706
|
+
"LC",
|
|
707
|
+
"LI",
|
|
708
|
+
"LK",
|
|
709
|
+
"LR",
|
|
710
|
+
"LS",
|
|
711
|
+
"LT",
|
|
712
|
+
"LU",
|
|
713
|
+
"LV",
|
|
714
|
+
"LY",
|
|
715
|
+
"MA",
|
|
716
|
+
"MC",
|
|
717
|
+
"MD",
|
|
718
|
+
"ME",
|
|
719
|
+
"MF",
|
|
720
|
+
"MG",
|
|
721
|
+
"MH",
|
|
722
|
+
"MK",
|
|
723
|
+
"ML",
|
|
724
|
+
"MM",
|
|
725
|
+
"MN",
|
|
726
|
+
"MO",
|
|
727
|
+
"MP",
|
|
728
|
+
"MQ",
|
|
729
|
+
"MR",
|
|
730
|
+
"MS",
|
|
731
|
+
"MT",
|
|
732
|
+
"MU",
|
|
733
|
+
"MV",
|
|
734
|
+
"MW",
|
|
735
|
+
"MX",
|
|
736
|
+
"MY",
|
|
737
|
+
"MZ",
|
|
738
|
+
"NA",
|
|
739
|
+
"NC",
|
|
740
|
+
"NE",
|
|
741
|
+
"NF",
|
|
742
|
+
"NG",
|
|
743
|
+
"NI",
|
|
744
|
+
"NL",
|
|
745
|
+
"NO",
|
|
746
|
+
"NP",
|
|
747
|
+
"NR",
|
|
748
|
+
"NU",
|
|
749
|
+
"NZ",
|
|
750
|
+
"OM",
|
|
751
|
+
"PA",
|
|
752
|
+
"PE",
|
|
753
|
+
"PF",
|
|
754
|
+
"PG",
|
|
755
|
+
"PH",
|
|
756
|
+
"PK",
|
|
757
|
+
"PL",
|
|
758
|
+
"PM",
|
|
759
|
+
"PN",
|
|
760
|
+
"PR",
|
|
761
|
+
"PS",
|
|
762
|
+
"PT",
|
|
763
|
+
"PW",
|
|
764
|
+
"PY",
|
|
765
|
+
"QA",
|
|
766
|
+
"RE",
|
|
767
|
+
"RO",
|
|
768
|
+
"RS",
|
|
769
|
+
"RU",
|
|
770
|
+
"RW",
|
|
771
|
+
"SA",
|
|
772
|
+
"SB",
|
|
773
|
+
"SC",
|
|
774
|
+
"SD",
|
|
775
|
+
"SE",
|
|
776
|
+
"SG",
|
|
777
|
+
"SH",
|
|
778
|
+
"SI",
|
|
779
|
+
"SJ",
|
|
780
|
+
"SK",
|
|
781
|
+
"SL",
|
|
782
|
+
"SM",
|
|
783
|
+
"SN",
|
|
784
|
+
"SO",
|
|
785
|
+
"SR",
|
|
786
|
+
"SS",
|
|
787
|
+
"ST",
|
|
788
|
+
"SV",
|
|
789
|
+
"SX",
|
|
790
|
+
"SY",
|
|
791
|
+
"SZ",
|
|
792
|
+
"TC",
|
|
793
|
+
"TD",
|
|
794
|
+
"TF",
|
|
795
|
+
"TG",
|
|
796
|
+
"TH",
|
|
797
|
+
"TJ",
|
|
798
|
+
"TK",
|
|
799
|
+
"TL",
|
|
800
|
+
"TM",
|
|
801
|
+
"TN",
|
|
802
|
+
"TO",
|
|
803
|
+
"TR",
|
|
804
|
+
"TT",
|
|
805
|
+
"TV",
|
|
806
|
+
"TW",
|
|
807
|
+
"TZ",
|
|
808
|
+
"UA",
|
|
809
|
+
"UG",
|
|
810
|
+
"UM",
|
|
811
|
+
"US",
|
|
812
|
+
"UY",
|
|
813
|
+
"UZ",
|
|
814
|
+
"VA",
|
|
815
|
+
"VC",
|
|
816
|
+
"VE",
|
|
817
|
+
"VG",
|
|
818
|
+
"VI",
|
|
819
|
+
"VN",
|
|
820
|
+
"VU",
|
|
821
|
+
"WF",
|
|
822
|
+
"WS",
|
|
823
|
+
"YE",
|
|
824
|
+
"YT",
|
|
825
|
+
"ZA",
|
|
826
|
+
"ZM",
|
|
827
|
+
"ZW"
|
|
828
|
+
];
|
|
829
|
+
function getCountries(locale = "en") {
|
|
830
|
+
const regionNames = new Intl.DisplayNames([
|
|
831
|
+
locale
|
|
832
|
+
], {
|
|
833
|
+
type: "region"
|
|
834
|
+
});
|
|
835
|
+
return COUNTRY_CODES.map((code) => ({
|
|
836
|
+
code,
|
|
837
|
+
name: regionNames.of(code)
|
|
838
|
+
}));
|
|
839
|
+
}
|
|
840
|
+
__name(getCountries, "getCountries");
|
|
841
|
+
var SUPPORTED_TIMEZONE_NAMES = Intl.supportedValuesOf("timeZone");
|
|
842
|
+
var TIMEZONE_NAMES = SUPPORTED_TIMEZONE_NAMES.includes("UTC") ? SUPPORTED_TIMEZONE_NAMES : [
|
|
843
|
+
...SUPPORTED_TIMEZONE_NAMES,
|
|
844
|
+
"UTC"
|
|
845
|
+
].sort((a, b) => a.localeCompare(b));
|
|
846
|
+
function getTimezones() {
|
|
847
|
+
return TIMEZONE_NAMES;
|
|
848
|
+
}
|
|
849
|
+
__name(getTimezones, "getTimezones");
|
|
578
850
|
|
|
579
851
|
// src/date/date.builder.ts
|
|
580
852
|
var DateBuilder = class _DateBuilder {
|
|
@@ -1179,7 +1451,9 @@ var DateBuilder = class _DateBuilder {
|
|
|
1179
1451
|
}
|
|
1180
1452
|
};
|
|
1181
1453
|
|
|
1454
|
+
exports.COUNTRY_CODES = COUNTRY_CODES;
|
|
1182
1455
|
exports.DateBuilder = DateBuilder;
|
|
1456
|
+
exports.TIMEZONE_NAMES = TIMEZONE_NAMES;
|
|
1183
1457
|
exports.addDays = addDays;
|
|
1184
1458
|
exports.addMonths = addMonths;
|
|
1185
1459
|
exports.addToDate = addToDate;
|
|
@@ -1192,9 +1466,11 @@ exports.formatDate = formatDate;
|
|
|
1192
1466
|
exports.formatDateInTimeZone = formatDateInTimeZone;
|
|
1193
1467
|
exports.formatDuration = formatDuration;
|
|
1194
1468
|
exports.formatRelativeTime = formatRelativeTime;
|
|
1469
|
+
exports.getCountries = getCountries;
|
|
1195
1470
|
exports.getDateFromDuration = getDateFromDuration;
|
|
1196
1471
|
exports.getTimezoneAbbreviation = getTimezoneAbbreviation;
|
|
1197
1472
|
exports.getTimezoneOffset = getTimezoneOffset;
|
|
1473
|
+
exports.getTimezones = getTimezones;
|
|
1198
1474
|
exports.isBetween = isBetween;
|
|
1199
1475
|
exports.isDST = isDST;
|
|
1200
1476
|
exports.isFuture = isFuture;
|
package/date/index.d.ts
CHANGED
|
@@ -441,6 +441,49 @@ declare function isDST(timeZone: string, date?: Date | number): boolean;
|
|
|
441
441
|
* ```
|
|
442
442
|
*/
|
|
443
443
|
declare function getTimezoneAbbreviation(timeZone: string, date?: Date | number, locale?: string): string;
|
|
444
|
+
/**
|
|
445
|
+
* List of ISO 3166-1 alpha-2 country codes for use in timezone utilities.
|
|
446
|
+
* This list is used to generate country names and filter timezones by country.
|
|
447
|
+
*/
|
|
448
|
+
declare const COUNTRY_CODES: string[];
|
|
449
|
+
type Country = {
|
|
450
|
+
code: string;
|
|
451
|
+
name: string;
|
|
452
|
+
};
|
|
453
|
+
/**
|
|
454
|
+
* Get a list of countries with their ISO codes and localized names.
|
|
455
|
+
* Uses Intl.DisplayNames to get the country names based on the provided locale.
|
|
456
|
+
*
|
|
457
|
+
* @param locale - Locale code for country names (default: 'en')
|
|
458
|
+
* @returns Array of country objects with code and name
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* getCountries('en');
|
|
463
|
+
* // [ { code: 'US', name: 'United States' }, { code: 'DE', name: 'Germany' }, ... ]
|
|
464
|
+
*
|
|
465
|
+
* getCountries('fr');
|
|
466
|
+
* // [ { code: 'US', name: 'États-Unis' }, { code: 'DE', name: 'Allemagne' }, ... ]
|
|
467
|
+
* ```
|
|
468
|
+
*/
|
|
469
|
+
declare function getCountries(locale?: string): Country[];
|
|
470
|
+
/**
|
|
471
|
+
* List of all IANA timezone identifiers supported by the environment.
|
|
472
|
+
* This can be used to populate dropdowns or validate timezone inputs.
|
|
473
|
+
*/
|
|
474
|
+
declare const TIMEZONE_NAMES: string[];
|
|
475
|
+
/**
|
|
476
|
+
* Get a list of all IANA timezone identifiers supported by the environment.
|
|
477
|
+
* This can be used to populate dropdowns or validate timezone inputs.
|
|
478
|
+
*
|
|
479
|
+
* @returns Array of timezone identifiers (e.g., 'America/New_York', 'Europe/Berlin')
|
|
480
|
+
* @example
|
|
481
|
+
* ```typescript
|
|
482
|
+
* getTimezones();
|
|
483
|
+
* // [ 'Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', ... ]
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function getTimezones(): string[];
|
|
444
487
|
|
|
445
488
|
/**
|
|
446
489
|
* DateBuilder class for fluent date manipulation and building.
|
|
@@ -867,5 +910,5 @@ declare class DateBuilder {
|
|
|
867
910
|
getTimezoneAbbreviation(timeZone: string): string;
|
|
868
911
|
}
|
|
869
912
|
|
|
870
|
-
export { DateBuilder, addDays, addMonths, addToDate, addYears, dateDiff, dateDiffDaysTZ, daysInMonth, endOf, formatDate, formatDateInTimeZone, formatDuration, formatRelativeTime, getDateFromDuration, getTimezoneAbbreviation, getTimezoneOffset, isBetween, isDST, isFuture, isLeapYear, isPast, isToday, isWeekend, parseDate, parseDuration, quarterOf, startOf, toTimeZone, weekOfYear };
|
|
913
|
+
export { COUNTRY_CODES, DateBuilder, TIMEZONE_NAMES, addDays, addMonths, addToDate, addYears, dateDiff, dateDiffDaysTZ, daysInMonth, endOf, formatDate, formatDateInTimeZone, formatDuration, formatRelativeTime, getCountries, getDateFromDuration, getTimezoneAbbreviation, getTimezoneOffset, getTimezones, isBetween, isDST, isFuture, isLeapYear, isPast, isToday, isWeekend, parseDate, parseDuration, quarterOf, startOf, toTimeZone, weekOfYear };
|
|
871
914
|
export type { DateFormatOptions, DateFormatPreset };
|