@reforgium/internal 1.1.0 → 1.1.1
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.
|
@@ -76,12 +76,12 @@ const VALIDATION_MESSAGES = new InjectionToken('RE_VALIDATION_MESSAGES', {
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
*
|
|
79
|
+
* Downloads a file from a Blob object and prompts the user to save it.
|
|
80
80
|
*
|
|
81
|
-
* @param {Blob} blob -
|
|
82
|
-
* @param {string} [fileName] -
|
|
83
|
-
*
|
|
84
|
-
* @return {void}
|
|
81
|
+
* @param {Blob} blob - Blob object representing the file to download.
|
|
82
|
+
* @param {string} [fileName] - Optional. Name for the downloaded file.
|
|
83
|
+
* If not specified, the current timestamp will be used as the filename.
|
|
84
|
+
* @return {void} Does not return a value.
|
|
85
85
|
*/
|
|
86
86
|
function downloadByBlob(blob, fileName) {
|
|
87
87
|
const win = window;
|
|
@@ -95,12 +95,12 @@ function downloadByBlob(blob, fileName) {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
98
|
+
* Initiates a file download for the given URL. Optionally, a custom filename can be specified.
|
|
99
99
|
*
|
|
100
|
-
* @param {string} url - URL
|
|
101
|
-
* @param {string} [filename] -
|
|
102
|
-
*
|
|
103
|
-
* @return {void}
|
|
100
|
+
* @param {string} url - URL of the file to download.
|
|
101
|
+
* @param {string} [filename] - Desired name for the downloaded file.
|
|
102
|
+
* If not specified, a timestamp-based name will be used.
|
|
103
|
+
* @return {void} The function does not return a value.
|
|
104
104
|
*/
|
|
105
105
|
function downloadByUrl(url, filename) {
|
|
106
106
|
const win = window;
|
|
@@ -114,12 +114,12 @@ function downloadByUrl(url, filename) {
|
|
|
114
114
|
win.document.body.removeChild(a);
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
117
|
+
* Copies the specified text to the clipboard. Uses the Clipboard API if available,
|
|
118
|
+
* otherwise falls back to `document.execCommand`.
|
|
119
119
|
*
|
|
120
|
-
* @param {string} text -
|
|
121
|
-
* @return {Promise<boolean>}
|
|
122
|
-
*
|
|
120
|
+
* @param {string} text - The text to copy to the clipboard.
|
|
121
|
+
* @return {Promise<boolean>} A promise that resolves to a boolean indicating whether
|
|
122
|
+
* the text copying was successful.
|
|
123
123
|
*/
|
|
124
124
|
async function copyText(text) {
|
|
125
125
|
const win = window;
|
|
@@ -145,13 +145,13 @@ async function copyText(text) {
|
|
|
145
145
|
return ok;
|
|
146
146
|
}
|
|
147
147
|
/**
|
|
148
|
-
*
|
|
148
|
+
* Converts a Base64 encoded string to a Blob object.
|
|
149
149
|
*
|
|
150
|
-
* @param {string} base64 -
|
|
151
|
-
*
|
|
152
|
-
* @param {string} [mimeType=''] - MIME
|
|
153
|
-
*
|
|
154
|
-
* @return {Blob}
|
|
150
|
+
* @param {string} base64 - Base64 encoded string. Can optionally include a MIME type
|
|
151
|
+
* in the format `data:<mimeType>;base64,<data>`.
|
|
152
|
+
* @param {string} [mimeType=''] - MIME type of the data. Optional parameter, will be overridden
|
|
153
|
+
* if the `base64` string includes a MIME type.
|
|
154
|
+
* @return {Blob} A Blob object created from the Base64 string.
|
|
155
155
|
*/
|
|
156
156
|
function base64ToBlob(base64, mimeType = '') {
|
|
157
157
|
const matches = base64.match(/^data:(.+);base64,(.*)$/);
|
|
@@ -166,6 +166,27 @@ function base64ToBlob(base64, mimeType = '') {
|
|
|
166
166
|
return new Blob([byteArray], { type: mime });
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Creates a debounced signal that delays updates from the source signal.
|
|
171
|
+
* The output signal will only update after the specified delay has passed without new values.
|
|
172
|
+
*
|
|
173
|
+
* @template T - The type of the signal value
|
|
174
|
+
* @param {Signal<T>} src - The source signal to debounce
|
|
175
|
+
* @param {number} [ms=150] - The debounce delay in milliseconds (default: 150ms)
|
|
176
|
+
* @param {Object} [opts] - Optional configuration
|
|
177
|
+
* @param {Injector} [opts.injector] - Optional injector for the effect context
|
|
178
|
+
* @returns {Signal<T>} A readonly signal that emits debounced values from the source
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* const searchQuery = signal('');
|
|
183
|
+
* const debouncedQuery = debounceSignal(searchQuery, 300);
|
|
184
|
+
*
|
|
185
|
+
* effect(() => {
|
|
186
|
+
* console.log('Debounced value:', debouncedQuery());
|
|
187
|
+
* });
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
169
190
|
const debounceSignal = (src, ms = 150, opts) => {
|
|
170
191
|
const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : []));
|
|
171
192
|
let timeoutRef;
|
|
@@ -182,6 +203,29 @@ const debounceSignal = (src, ms = 150, opts) => {
|
|
|
182
203
|
}, { injector: opts?.injector });
|
|
183
204
|
return out.asReadonly();
|
|
184
205
|
};
|
|
206
|
+
/**
|
|
207
|
+
* Creates a throttled signal that limits the rate of updates from the source signal.
|
|
208
|
+
* The output signal will emit the first value immediately, then wait for the specified delay
|
|
209
|
+
* before allowing subsequent updates. If values are emitted during the waiting period,
|
|
210
|
+
* the last value will be queued and emitted after the delay.
|
|
211
|
+
*
|
|
212
|
+
* @template T - The type of the signal value
|
|
213
|
+
* @param {Signal<T>} src - The source signal to throttle
|
|
214
|
+
* @param {number} [ms=100] - The throttle delay in milliseconds (default: 100ms)
|
|
215
|
+
* @param {Object} [opts] - Optional configuration
|
|
216
|
+
* @param {Injector} [opts.injector] - Optional injector for the effect context
|
|
217
|
+
* @returns {Signal<T>} A readonly signal that emits throttled values from the source
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* const scrollPosition = signal(0);
|
|
222
|
+
* const throttledPosition = throttleSignal(scrollPosition, 200);
|
|
223
|
+
*
|
|
224
|
+
* effect(() => {
|
|
225
|
+
* console.log('Throttled position:', throttledPosition());
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
185
229
|
const throttleSignal = (src, ms = 100, opts) => {
|
|
186
230
|
const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : []));
|
|
187
231
|
let last = 0;
|
|
@@ -227,19 +271,19 @@ const throttleSignal = (src, ms = 100, opts) => {
|
|
|
227
271
|
|
|
228
272
|
const pad = (n) => n.toString().padStart(2, '0');
|
|
229
273
|
/**
|
|
230
|
-
*
|
|
274
|
+
* Formats a Date object into a string of the given format.
|
|
231
275
|
*
|
|
232
|
-
* @param {Date} date -
|
|
233
|
-
* @param {string} [format='yyyy-MM-dd'] -
|
|
234
|
-
*
|
|
235
|
-
* - yyyy:
|
|
236
|
-
* - MM:
|
|
237
|
-
* - dd:
|
|
238
|
-
* - HH:
|
|
239
|
-
* - mm:
|
|
240
|
-
* - ss:
|
|
276
|
+
* @param {Date} date - Date object to format.
|
|
277
|
+
* @param {string} [format='yyyy-MM-dd'] - String format to apply. Defaults to 'yyyy-MM-dd'.
|
|
278
|
+
* Supported tokens in the format string:
|
|
279
|
+
* - yyyy: Full year (e.g., 2023)
|
|
280
|
+
* - MM: Month with leading zero (01-12)
|
|
281
|
+
* - dd: Day of the month with leading zero (01-31)
|
|
282
|
+
* - HH: Hour in 24-hour format with leading zero (00-23)
|
|
283
|
+
* - mm: Minutes with leading zero (00-59)
|
|
284
|
+
* - ss: Seconds with leading zero (00-59)
|
|
241
285
|
*
|
|
242
|
-
* @returns {string}
|
|
286
|
+
* @returns {string} Formatted date string. Returns an empty string if the input date is invalid.
|
|
243
287
|
*/
|
|
244
288
|
const formatDate = (date, format = 'yyyy-MM-dd') => {
|
|
245
289
|
if (isNaN(date['getTime']?.())) {
|
|
@@ -260,11 +304,11 @@ const formatDate = (date, format = 'yyyy-MM-dd') => {
|
|
|
260
304
|
return formatted;
|
|
261
305
|
};
|
|
262
306
|
/**
|
|
263
|
-
*
|
|
264
|
-
*
|
|
307
|
+
* Formats the given date into a localized string representation in the format 'day month year'.
|
|
308
|
+
* The month is localized for 'ru-RU' locale and abbreviated.
|
|
265
309
|
*
|
|
266
|
-
* @param {Date} date -
|
|
267
|
-
* @return {string}
|
|
310
|
+
* @param {Date} date - Date object to format.
|
|
311
|
+
* @return {string} A string representing the formatted date in the format 'day month year'.
|
|
268
312
|
*/
|
|
269
313
|
function formatToLocaledDate(date) {
|
|
270
314
|
const day = date.getDate();
|
|
@@ -273,12 +317,12 @@ function formatToLocaledDate(date) {
|
|
|
273
317
|
return `${day} ${month} ${year}`;
|
|
274
318
|
}
|
|
275
319
|
/**
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
320
|
+
* Parses a date from a string based on the given mask.
|
|
321
|
+
* Supports dd, MM, yyyy, HH, mm, ss.
|
|
322
|
+
* Any delimiters: '.', '/', '-', ' '.
|
|
279
323
|
*
|
|
280
|
-
* @param {string} value -
|
|
281
|
-
* @param {string} format -
|
|
324
|
+
* @param {string} value - source date string
|
|
325
|
+
* @param {string} format - mask, e.g., "dd.MM.yyyy"
|
|
282
326
|
* @returns {Date|null}
|
|
283
327
|
*/
|
|
284
328
|
const parseToDate = (value, format = 'dd.MM.yyyy') => {
|
|
@@ -307,19 +351,19 @@ const parseToDate = (value, format = 'dd.MM.yyyy') => {
|
|
|
307
351
|
return date;
|
|
308
352
|
};
|
|
309
353
|
/**
|
|
310
|
-
*
|
|
354
|
+
* Parses a string representation of two dates into a tuple of `Date` objects or `null` values.
|
|
311
355
|
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
356
|
+
* This function attempts to extract and parse two date values from the input string
|
|
357
|
+
* based on the provided date format. If parsing is unsuccessful, the returned tuple will
|
|
358
|
+
* consist of `null` values. The default expected date format is `dd.MM.yyyy`, but it
|
|
359
|
+
* can be changed.
|
|
316
360
|
*
|
|
317
|
-
* @param {string | null} value -
|
|
318
|
-
*
|
|
319
|
-
* @param {string} [format='dd.MM.yyyy'] -
|
|
320
|
-
*
|
|
321
|
-
* @returns {[Date | null, Date | null]}
|
|
322
|
-
*
|
|
361
|
+
* @param {string | null} value - String containing date representations to parse.
|
|
362
|
+
* If `null`, the function will return `[null, null]`.
|
|
363
|
+
* @param {string} [format='dd.MM.yyyy'] - Date format used for parsing.
|
|
364
|
+
* Supports `yyyy`, `MM`, `dd`, `HH`, `mm`, and `ss`.
|
|
365
|
+
* @returns {[Date | null, Date | null]} A tuple where the first element is the parsed start date
|
|
366
|
+
* and the second element is the parsed end date. If parsing fails, both elements will be `null`.
|
|
323
367
|
*/
|
|
324
368
|
const parseToDatePeriod = (value, format = 'dd.MM.yyyy') => {
|
|
325
369
|
if (typeof value !== 'string' || !format) {
|
|
@@ -344,21 +388,21 @@ const parseToDatePeriod = (value, format = 'dd.MM.yyyy') => {
|
|
|
344
388
|
}
|
|
345
389
|
};
|
|
346
390
|
/**
|
|
347
|
-
*
|
|
391
|
+
* Determines if the given value is a date period.
|
|
348
392
|
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
393
|
+
* A date period is represented as an array containing exactly two Date instances.
|
|
394
|
+
* Both elements of the array must be valid Date objects (i.e., not `Invalid Date`).
|
|
351
395
|
*
|
|
352
|
-
* @param {unknown} value -
|
|
353
|
-
* @returns {value is [Date, Date]} -
|
|
396
|
+
* @param {unknown} value - Value to check.
|
|
397
|
+
* @returns {value is [Date, Date]} - Returns `true` if the value is a valid date period, otherwise `false`.
|
|
354
398
|
*/
|
|
355
399
|
const isDatePeriod = (value) => Array.isArray(value) && value.length === 2 && value.every((it) => it instanceof Date && !isNaN(it.getTime()));
|
|
356
400
|
/**
|
|
357
|
-
*
|
|
401
|
+
* Converts various data types to a Date object.
|
|
358
402
|
*
|
|
359
|
-
* @param {unknown} v -
|
|
360
|
-
*
|
|
361
|
-
* @returns {Date}
|
|
403
|
+
* @param {unknown} v - Value to convert. Can be a Date object,
|
|
404
|
+
* a number (timestamp), or a string containing a valid date.
|
|
405
|
+
* @returns {Date} Date object. If conversion is impossible, returns Invalid Date.
|
|
362
406
|
*/
|
|
363
407
|
const toDate = (v) => {
|
|
364
408
|
if (v instanceof Date)
|
|
@@ -370,8 +414,8 @@ const toDate = (v) => {
|
|
|
370
414
|
return new Date(NaN);
|
|
371
415
|
};
|
|
372
416
|
/**
|
|
373
|
-
*
|
|
374
|
-
*
|
|
417
|
+
* Converts a date string from a given format to ISO (UTC).
|
|
418
|
+
* Example:
|
|
375
419
|
* reformatDateToISO("24.11.2025", "dd.MM.yyyy")
|
|
376
420
|
* → "2025-11-24T00:00:00.000Z"
|
|
377
421
|
*/
|
|
@@ -421,27 +465,27 @@ function reformatDateToISO(dateStr, mask) {
|
|
|
421
465
|
}
|
|
422
466
|
|
|
423
467
|
/**
|
|
424
|
-
*
|
|
425
|
-
*
|
|
468
|
+
* Determines if the given value is null or undefined, optionally considering
|
|
469
|
+
* empty strings as null-like values.
|
|
426
470
|
*
|
|
427
|
-
* @param {unknown} value -
|
|
428
|
-
* @param {boolean} [withEmptyString=false] -
|
|
429
|
-
* null
|
|
430
|
-
* @returns {value is null | undefined}
|
|
431
|
-
*
|
|
471
|
+
* @param {unknown} value - Value to check for null or undefined.
|
|
472
|
+
* @param {boolean} [withEmptyString=false] - If true, empty strings are also considered
|
|
473
|
+
* null-like values in addition to null and undefined.
|
|
474
|
+
* @returns {value is null | undefined} Returns `true` if the value is null, undefined,
|
|
475
|
+
* or (if `withEmptyString` is true) an empty string. Otherwise returns `false`.
|
|
432
476
|
*/
|
|
433
477
|
const isNullable = (value, withEmptyString = false) => value === null || value === undefined || (withEmptyString ? value === '' : false);
|
|
434
478
|
/**
|
|
435
|
-
*
|
|
479
|
+
* Checks if the given value is a number or can be converted to a valid number.
|
|
436
480
|
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
481
|
+
* This function checks if the input value is numeric. If the input value
|
|
482
|
+
* is of type number, it is verified to be a finite number and not NaN. If the input
|
|
483
|
+
* value is a string, it checks if this string can be converted to a valid number.
|
|
440
484
|
*
|
|
441
|
-
* @param {unknown} value -
|
|
442
|
-
* @param {boolean} [fromString=false] -
|
|
443
|
-
* @returns {value is number} `true`
|
|
444
|
-
*
|
|
485
|
+
* @param {unknown} value - Value to check.
|
|
486
|
+
* @param {boolean} [fromString=false] - If true, string values will attempt to be converted to a number.
|
|
487
|
+
* @returns {value is number} `true` if the value is a number or a string
|
|
488
|
+
* that can be converted to a number; otherwise `false`.
|
|
445
489
|
*/
|
|
446
490
|
const isNumber = (value, fromString = false) => {
|
|
447
491
|
if (typeof value === 'number') {
|
|
@@ -531,12 +575,12 @@ const concatArray = (value, mode, key) => {
|
|
|
531
575
|
};
|
|
532
576
|
|
|
533
577
|
/**
|
|
534
|
-
*
|
|
578
|
+
* Formats a number or a string containing a number by adding spaces as thousands separators.
|
|
535
579
|
*
|
|
536
|
-
* @param {number|string} num -
|
|
537
|
-
*
|
|
538
|
-
* @return {string}
|
|
539
|
-
*
|
|
580
|
+
* @param {number|string} num - The number or string to format.
|
|
581
|
+
* If the input value is null, undefined, or an invalid number, an empty string is returned.
|
|
582
|
+
* @return {string} Formatted string with spaces as thousands separators, or an empty string
|
|
583
|
+
* if the input is invalid.
|
|
540
584
|
*/
|
|
541
585
|
function formatToSpacedNumber(num) {
|
|
542
586
|
const stringed = String(num).replaceAll(' ', '');
|
|
@@ -547,13 +591,13 @@ function formatToSpacedNumber(num) {
|
|
|
547
591
|
return str.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
|
|
548
592
|
}
|
|
549
593
|
/**
|
|
550
|
-
*
|
|
551
|
-
*
|
|
594
|
+
* Truncates a string to the specified number of characters and adds an ellipsis ('…')
|
|
595
|
+
* if the string exceeds the limit.
|
|
552
596
|
*
|
|
553
|
-
* @param {string} text -
|
|
554
|
-
* @param {number} limit -
|
|
555
|
-
* @returns {string}
|
|
556
|
-
*
|
|
597
|
+
* @param {string} text - The text to truncate.
|
|
598
|
+
* @param {number} limit - Maximum allowed string length.
|
|
599
|
+
* @returns {string} Truncated string with an ellipsis if length exceeds the limit,
|
|
600
|
+
* or the original string otherwise.
|
|
557
601
|
*/
|
|
558
602
|
const truncate = (text, limit) => {
|
|
559
603
|
return text.length > limit ? text.slice(0, limit) + '…' : text;
|
|
@@ -614,12 +658,12 @@ const getDirMap = (directions) => {
|
|
|
614
658
|
};
|
|
615
659
|
|
|
616
660
|
/**
|
|
617
|
-
*
|
|
661
|
+
* Calculates the available vertical space below the given element in the viewport.
|
|
618
662
|
*
|
|
619
|
-
* @param {Element} el - DOM
|
|
620
|
-
* @param {number} [margin=20] -
|
|
621
|
-
* @return {number}
|
|
622
|
-
*
|
|
663
|
+
* @param {Element} el - DOM element for which to calculate the available height below.
|
|
664
|
+
* @param {number} [margin=20] - Optional margin subtracted from the calculated available height.
|
|
665
|
+
* @return {number} Available height in pixels below the element, taking margin into account.
|
|
666
|
+
* Returns 0 if there is no available space.
|
|
623
667
|
*/
|
|
624
668
|
function getAvailableHeight(el, margin = 20) {
|
|
625
669
|
const rect = el.getBoundingClientRect();
|
|
@@ -630,12 +674,12 @@ function getAvailableHeight(el, margin = 20) {
|
|
|
630
674
|
}
|
|
631
675
|
|
|
632
676
|
/**
|
|
633
|
-
*
|
|
634
|
-
*
|
|
677
|
+
* Retrieves a value by a nested path within an object or array.
|
|
678
|
+
* The path is specified as a dot-delimited string.
|
|
635
679
|
*
|
|
636
|
-
* @param obj
|
|
637
|
-
* @param path
|
|
638
|
-
* @return
|
|
680
|
+
* @param obj The object or array to traverse.
|
|
681
|
+
* @param path A dot-delimited string specifying the path to retrieve the value.
|
|
682
|
+
* @return The value found at the specified path, or undefined if the path does not exist or is invalid.
|
|
639
683
|
*/
|
|
640
684
|
function getChainedValue(obj, path) {
|
|
641
685
|
if (!obj) {
|
|
@@ -657,11 +701,11 @@ function getChainedValue(obj, path) {
|
|
|
657
701
|
}
|
|
658
702
|
|
|
659
703
|
/**
|
|
660
|
-
*
|
|
661
|
-
*
|
|
704
|
+
* Normalizes a given URL by removing redundant slashes, resolving dot segments,
|
|
705
|
+
* and ensuring there are no trailing slashes at the end of the URL.
|
|
662
706
|
*
|
|
663
|
-
* @param {string} url -
|
|
664
|
-
* @return {string} -
|
|
707
|
+
* @param {string} url - The URL string to normalize.
|
|
708
|
+
* @return {string} - The normalized URL string.
|
|
665
709
|
*/
|
|
666
710
|
function normalizeUrl(url) {
|
|
667
711
|
const [protocol, rest] = url.split('://');
|
|
@@ -672,14 +716,14 @@ function normalizeUrl(url) {
|
|
|
672
716
|
return rest ? `${protocol}://${cleaned}` : cleaned;
|
|
673
717
|
}
|
|
674
718
|
/**
|
|
675
|
-
*
|
|
676
|
-
*
|
|
719
|
+
* Replaces placeholders in the provided URL template with corresponding values from the params object.
|
|
720
|
+
* Placeholders are defined as `:key` in the template string.
|
|
677
721
|
*
|
|
678
|
-
* @param {string} template URL
|
|
679
|
-
* @param {AnyDict} [params]
|
|
680
|
-
*
|
|
681
|
-
* @return {string} URL
|
|
682
|
-
*
|
|
722
|
+
* @param {string} template URL template containing placeholders to replace.
|
|
723
|
+
* @param {AnyDict} [params] Optional dictionary containing key-value pairs.
|
|
724
|
+
* Keys correspond to placeholders in the template, and values will replace them.
|
|
725
|
+
* @return {string} URL with placeholders replaced by corresponding values from the params object.
|
|
726
|
+
* Defaults to the original template if params is not provided.
|
|
683
727
|
*/
|
|
684
728
|
function fillUrlWithParams(template, params) {
|
|
685
729
|
if (!params) {
|
|
@@ -688,12 +732,12 @@ function fillUrlWithParams(template, params) {
|
|
|
688
732
|
return template.replace(/:([a-zA-Z0-9_]+)/g, (_, k) => encodeURIComponent(params[k] ?? ''));
|
|
689
733
|
}
|
|
690
734
|
/**
|
|
691
|
-
*
|
|
735
|
+
* Appends query parameters to the specified URL.
|
|
692
736
|
*
|
|
693
|
-
* @param {string} url
|
|
694
|
-
* @param {Record<string, unknown>} [params]
|
|
695
|
-
*
|
|
696
|
-
* @return {string} URL
|
|
737
|
+
* @param {string} url Base URL to which query parameters will be added.
|
|
738
|
+
* @param {Record<string, unknown>} [params] Optional object containing query parameter key-value pairs.
|
|
739
|
+
* Keys with null or undefined values will be ignored.
|
|
740
|
+
* @return {string} URL with appended query parameters.
|
|
697
741
|
*/
|
|
698
742
|
function appendQueryParams(url, params) {
|
|
699
743
|
if (!params || !Object.keys(params).length)
|
|
@@ -708,11 +752,11 @@ function appendQueryParams(url, params) {
|
|
|
708
752
|
return `${base}?${searchParams.toString()}`;
|
|
709
753
|
}
|
|
710
754
|
/**
|
|
711
|
-
*
|
|
755
|
+
* Parses a query string into an object containing key-value pairs.
|
|
712
756
|
*
|
|
713
|
-
* @param {string} query -
|
|
714
|
-
* @return {Record<string, string>}
|
|
715
|
-
*
|
|
757
|
+
* @param {string} query - The query string to parse. May start with '?'.
|
|
758
|
+
* @return {Record<string, string>} An object where each key is a query parameter name,
|
|
759
|
+
* and the value is the corresponding value.
|
|
716
760
|
*/
|
|
717
761
|
function parseQueryParams(query) {
|
|
718
762
|
const search = query.startsWith('?') ? query.slice(1) : query;
|
|
@@ -727,13 +771,13 @@ function parseQueryParams(query) {
|
|
|
727
771
|
/**
|
|
728
772
|
* Constructs a query string from a given object and concatenation type.
|
|
729
773
|
*
|
|
730
|
-
* @param {Record<string, any>} object -
|
|
731
|
-
*
|
|
732
|
-
* @param {'comma' | 'json' | 'multi'} concatType -
|
|
733
|
-
* - 'comma':
|
|
734
|
-
* - 'json':
|
|
735
|
-
* - 'multi':
|
|
736
|
-
* @returns {string} -
|
|
774
|
+
* @param {Record<string, any>} object - Object with key-value pairs to convert into a query string.
|
|
775
|
+
* Keys represent parameter names, and values represent parameter values.
|
|
776
|
+
* @param {'comma' | 'json' | 'multi'} concatType - Method for handling array values:
|
|
777
|
+
* - 'comma': Joins array elements with a comma.
|
|
778
|
+
* - 'json': Serializes the array as a JSON string.
|
|
779
|
+
* - 'multi': Creates multiple entries for array elements, each associated with the same key.
|
|
780
|
+
* @returns {string} - Formed query string with keys and values encoded as URI components.
|
|
737
781
|
*/
|
|
738
782
|
const makeQuery = (object, concatType) => {
|
|
739
783
|
return Object.entries(object)
|
|
@@ -748,16 +792,16 @@ const makeQuery = (object, concatType) => {
|
|
|
748
792
|
.join('&');
|
|
749
793
|
};
|
|
750
794
|
/**
|
|
751
|
-
*
|
|
752
|
-
*
|
|
795
|
+
* Compares two routes to determine if the actual route matches the route template.
|
|
796
|
+
* Supports static and dynamic route matching with optional subroute consideration.
|
|
753
797
|
*
|
|
754
|
-
* @param {string} actualRoute -
|
|
755
|
-
* @param {string} pureRoute -
|
|
756
|
-
* (
|
|
757
|
-
* @param {boolean} [withSubroute=false] -
|
|
758
|
-
* actualRoute
|
|
759
|
-
* @return {boolean}
|
|
760
|
-
*
|
|
798
|
+
* @param {string} actualRoute - Actual route path to compare.
|
|
799
|
+
* @param {string} pureRoute - Template route path to match, which may include placeholders
|
|
800
|
+
* (e.g., `:id`).
|
|
801
|
+
* @param {boolean} [withSubroute=false] - Determines whether to allow subroute matching. If true,
|
|
802
|
+
* actualRoute must start with the filled pureRoute.
|
|
803
|
+
* @return {boolean} Returns true if the actual route matches the template
|
|
804
|
+
* route (and optional subroute condition if enabled), otherwise false.
|
|
761
805
|
*/
|
|
762
806
|
const compareRoutes = (actualRoute, pureRoute, withSubroute = false) => {
|
|
763
807
|
if (!pureRoute.includes(':')) {
|
|
@@ -769,12 +813,12 @@ const compareRoutes = (actualRoute, pureRoute, withSubroute = false) => {
|
|
|
769
813
|
}
|
|
770
814
|
};
|
|
771
815
|
/**
|
|
772
|
-
*
|
|
816
|
+
* Processes and materializes a route path by decoding and, if necessary, replacing route parameters.
|
|
773
817
|
*
|
|
774
|
-
* @param {string} actualRoute -
|
|
775
|
-
*
|
|
776
|
-
* @param {string} pureRoute -
|
|
777
|
-
* @returns {string}
|
|
818
|
+
* @param {string} actualRoute - Actual route path, usually provided
|
|
819
|
+
* as a source for dynamic parameter values.
|
|
820
|
+
* @param {string} pureRoute - Route path template, may include dynamic segments denoted by `:`.
|
|
821
|
+
* @returns {string} Fully materialized and decoded route path.
|
|
778
822
|
*/
|
|
779
823
|
const materializeRoutePath = (actualRoute, pureRoute) => {
|
|
780
824
|
if (!pureRoute.includes(':')) {
|
|
@@ -798,14 +842,14 @@ const fillRouteTemplate = (actualRoute, pureRoute) => {
|
|
|
798
842
|
};
|
|
799
843
|
|
|
800
844
|
/**
|
|
801
|
-
*
|
|
802
|
-
*
|
|
845
|
+
* Recursively checks the equality of two objects, including nested structures and special cases
|
|
846
|
+
* such as arrays, sets, maps, dates, and NaN.
|
|
803
847
|
*
|
|
804
|
-
* @param {AnyType} a -
|
|
805
|
-
* @param {AnyType} b -
|
|
806
|
-
* @param {Map} [seen=new Map()] -
|
|
807
|
-
*
|
|
808
|
-
* @return {boolean} -
|
|
848
|
+
* @param {AnyType} a - The first object to compare.
|
|
849
|
+
* @param {AnyType} b - The second object to compare.
|
|
850
|
+
* @param {Map} [seen=new Map()] - A map used to detect cyclic references
|
|
851
|
+
* during deep equality check.
|
|
852
|
+
* @return {boolean} - Returns true if the objects are deeply equal, otherwise returns false.
|
|
809
853
|
*/
|
|
810
854
|
function deepEqual(a, b, seen = new Map()) {
|
|
811
855
|
if (a === b) {
|