@zelgadis87/utils-core 5.3.5 → 5.3.7
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/.rollup/index.cjs +94 -24
- package/.rollup/index.cjs.map +1 -1
- package/.rollup/index.d.ts +3 -1
- package/.rollup/index.mjs +93 -25
- package/.rollup/index.mjs.map +1 -1
- package/.rollup/tsconfig.tsbuildinfo +1 -1
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/src/time/TimeInstant.ts +84 -24
- package/src/utils/random.ts +17 -1
package/.rollup/index.cjs
CHANGED
|
@@ -1080,6 +1080,20 @@ function randomNumberInInterval(min, max) {
|
|
|
1080
1080
|
const randomId = (length) => {
|
|
1081
1081
|
return Math.random().toString(36).substring(2, length + 2);
|
|
1082
1082
|
};
|
|
1083
|
+
function randomPick(arr) {
|
|
1084
|
+
return first$1(randomPicks(arr, 1));
|
|
1085
|
+
}
|
|
1086
|
+
function randomPicks(arr, count) {
|
|
1087
|
+
const available = [...arr];
|
|
1088
|
+
const result = [];
|
|
1089
|
+
while (available.length > 0 && count > 0) {
|
|
1090
|
+
const randomIndex = randomNumberInInterval(0, available.length - 1);
|
|
1091
|
+
result.push(available[randomIndex]);
|
|
1092
|
+
available.splice(randomIndex, 1);
|
|
1093
|
+
count--;
|
|
1094
|
+
}
|
|
1095
|
+
return result;
|
|
1096
|
+
}
|
|
1083
1097
|
|
|
1084
1098
|
function dictToEntries(obj) {
|
|
1085
1099
|
return Object.entries(obj);
|
|
@@ -2345,8 +2359,48 @@ function normalizeMonthName(name) {
|
|
|
2345
2359
|
// Trim whitespace
|
|
2346
2360
|
.trim();
|
|
2347
2361
|
}
|
|
2348
|
-
const PATTERN_REGEX = /(M|y|d|D|h|H|m|s|S|G|Z|P|a)+/g;
|
|
2349
2362
|
const ESCAPE_REGEX = /\\"|"((?:\\"|[^"])*)"/g;
|
|
2363
|
+
/**
|
|
2364
|
+
* Tokenize a date/time pattern by detecting character changes.
|
|
2365
|
+
*
|
|
2366
|
+
* This function uses a character-change detection algorithm to split a pattern into tokens:
|
|
2367
|
+
* 1. Iterates through the pattern character by character
|
|
2368
|
+
* 2. Detects when the character changes (e.g., 'y' → 'M' → 'd')
|
|
2369
|
+
* 3. Creates tokens based on consecutive identical characters
|
|
2370
|
+
* 4. Marks tokens as pattern tokens only if they consist of repeated pattern characters
|
|
2371
|
+
*
|
|
2372
|
+
* This approach works correctly for patterns with or without separators:
|
|
2373
|
+
* - "yyyy-MM-dd" → [{token:"yyyy", type:"y"}, {token:"-", type:null}, {token:"MM", type:"M"}, {token:"-", type:null}, {token:"dd", type:"d"}]
|
|
2374
|
+
* - "yyyyMMdd" → [{token:"yyyy", type:"y"}, {token:"MM", type:"M"}, {token:"dd", type:"d"}]
|
|
2375
|
+
*
|
|
2376
|
+
* @param pattern - The date/time pattern to tokenize
|
|
2377
|
+
* @returns Array of tokens with their types (null for separators/literals, pattern char for pattern tokens)
|
|
2378
|
+
*/
|
|
2379
|
+
function tokenizePattern(pattern) {
|
|
2380
|
+
const result = [];
|
|
2381
|
+
let currentToken = '';
|
|
2382
|
+
let currentChar = '';
|
|
2383
|
+
for (const char of pattern) {
|
|
2384
|
+
if (char === currentChar) {
|
|
2385
|
+
// Same character, extend current token
|
|
2386
|
+
currentToken += char;
|
|
2387
|
+
}
|
|
2388
|
+
else {
|
|
2389
|
+
// Character changed, end current token and start new one
|
|
2390
|
+
if (currentToken) {
|
|
2391
|
+
// Mark the token with its character (caller will decide if it's a valid pattern)
|
|
2392
|
+
result.push({ token: currentToken, type: currentChar });
|
|
2393
|
+
}
|
|
2394
|
+
currentToken = char;
|
|
2395
|
+
currentChar = char;
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
// Don't forget the last token
|
|
2399
|
+
if (currentToken) {
|
|
2400
|
+
result.push({ token: currentToken, type: currentChar });
|
|
2401
|
+
}
|
|
2402
|
+
return result;
|
|
2403
|
+
}
|
|
2350
2404
|
// Formatter configuration mapping: token pattern -> configuration with optional extraction rules
|
|
2351
2405
|
const formatterConfigs = {
|
|
2352
2406
|
// Year
|
|
@@ -2428,11 +2482,16 @@ function formatTimeInstant(instant, pattern, config = {}) {
|
|
|
2428
2482
|
if (index % 2 !== 0) {
|
|
2429
2483
|
return sub;
|
|
2430
2484
|
}
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2485
|
+
// Tokenize the pattern by detecting character changes
|
|
2486
|
+
const tokens = tokenizePattern(sub);
|
|
2487
|
+
// Format each token and join the results
|
|
2488
|
+
return tokens.map(({ token, type }) => {
|
|
2489
|
+
// If type is null or formatting fails, keep token as-is
|
|
2490
|
+
if (!type)
|
|
2491
|
+
return token;
|
|
2492
|
+
const formatted = formatType(type, token.length, date, locale, timeZone);
|
|
2493
|
+
return formatted !== undefined ? formatted : token;
|
|
2494
|
+
}).join('');
|
|
2436
2495
|
})
|
|
2437
2496
|
.join('');
|
|
2438
2497
|
}
|
|
@@ -2460,53 +2519,62 @@ function parseTimeInstantComponents(dateString, pattern, config = {}) {
|
|
|
2460
2519
|
if (index % 2 !== 0) {
|
|
2461
2520
|
return sub.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // Escape special regex chars
|
|
2462
2521
|
}
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2522
|
+
// Tokenize the pattern by detecting character changes
|
|
2523
|
+
const patternTokens = tokenizePattern(sub);
|
|
2524
|
+
// Build regex pattern from tokens
|
|
2525
|
+
return patternTokens.map(({ token, type }) => {
|
|
2526
|
+
// Check if this is a valid pattern by looking it up in formatterConfigs
|
|
2527
|
+
const isValidPattern = type && formatterConfigs[token];
|
|
2528
|
+
if (!isValidPattern) {
|
|
2529
|
+
// This is a literal/separator, escape it for regex
|
|
2530
|
+
return token.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
2531
|
+
}
|
|
2532
|
+
// This is a pattern token, track it and create regex
|
|
2533
|
+
tokens.push({ type, length: token.length, position: position++ });
|
|
2466
2534
|
// Create appropriate regex for each token type
|
|
2467
2535
|
switch (type) {
|
|
2468
2536
|
case 'y':
|
|
2469
|
-
return
|
|
2537
|
+
return token.length === 2 ? '(\\d{2})' : '(\\d{4})';
|
|
2470
2538
|
case 'M':
|
|
2471
|
-
if (
|
|
2539
|
+
if (token.length === 1)
|
|
2472
2540
|
return '(\\d{1,2})';
|
|
2473
|
-
if (
|
|
2541
|
+
if (token.length === 2)
|
|
2474
2542
|
return '(\\d{2})';
|
|
2475
|
-
if (
|
|
2543
|
+
if (token.length === 3)
|
|
2476
2544
|
return '([A-Za-z.]{1,7})';
|
|
2477
2545
|
return '([A-Za-z]+)';
|
|
2478
2546
|
case 'd':
|
|
2479
|
-
return
|
|
2547
|
+
return token.length === 1 ? '(\\d{1,2})' : '(\\d{2})';
|
|
2480
2548
|
case 'H':
|
|
2481
2549
|
case 'h':
|
|
2482
|
-
return
|
|
2550
|
+
return token.length === 1 ? '(\\d{1,2})' : '(\\d{2})';
|
|
2483
2551
|
case 'm':
|
|
2484
2552
|
case 's':
|
|
2485
|
-
return
|
|
2553
|
+
return token.length === 1 ? '(\\d{1,2})' : '(\\d{2})';
|
|
2486
2554
|
case 'S':
|
|
2487
|
-
return `(\\d{${
|
|
2555
|
+
return `(\\d{${token.length}})`;
|
|
2488
2556
|
case 'a':
|
|
2489
2557
|
return '([aApP][mM])';
|
|
2490
2558
|
case 'D':
|
|
2491
|
-
if (
|
|
2559
|
+
if (token.length === 1)
|
|
2492
2560
|
return '([A-Za-z])';
|
|
2493
|
-
if (
|
|
2561
|
+
if (token.length === 2)
|
|
2494
2562
|
return '([A-Za-z]{3})';
|
|
2495
2563
|
return '([A-Za-z]+)';
|
|
2496
2564
|
case 'G':
|
|
2497
|
-
if (
|
|
2565
|
+
if (token.length === 1)
|
|
2498
2566
|
return '([A-Za-z])';
|
|
2499
|
-
if (
|
|
2567
|
+
if (token.length === 2)
|
|
2500
2568
|
return '([A-Za-z]{2})';
|
|
2501
2569
|
return '([A-Za-z\\s]+)';
|
|
2502
2570
|
case 'Z':
|
|
2503
|
-
return
|
|
2571
|
+
return token.length === 1 ? '([A-Za-z0-9+\\-:]+)' : '([A-Za-z\\s]+)';
|
|
2504
2572
|
case 'P':
|
|
2505
2573
|
return '([A-Za-z\\s]+)';
|
|
2506
2574
|
default:
|
|
2507
|
-
return
|
|
2575
|
+
return token;
|
|
2508
2576
|
}
|
|
2509
|
-
});
|
|
2577
|
+
}).join('');
|
|
2510
2578
|
}).join('');
|
|
2511
2579
|
const regex = new RegExp('^' + regexPattern + '$');
|
|
2512
2580
|
const matches = dateString.match(regex);
|
|
@@ -3658,6 +3726,8 @@ exports.pluralize = pluralize;
|
|
|
3658
3726
|
exports.promiseSequence = promiseSequence;
|
|
3659
3727
|
exports.randomId = randomId;
|
|
3660
3728
|
exports.randomNumberInInterval = randomNumberInInterval;
|
|
3729
|
+
exports.randomPick = randomPick;
|
|
3730
|
+
exports.randomPicks = randomPicks;
|
|
3661
3731
|
exports.range = range;
|
|
3662
3732
|
exports.repeat = repeat;
|
|
3663
3733
|
exports.reverse = reverse$1;
|