@kikiutils/shared 18.0.1 → 18.2.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/dist/buffer.d.ts +19 -21
- package/dist/buffer.d.ts.map +1 -1
- package/dist/buffer.js +18 -19
- package/dist/buffer.js.map +1 -1
- package/dist/classes/enhanced-date.d.ts +457 -0
- package/dist/classes/enhanced-date.d.ts.map +1 -0
- package/dist/classes/enhanced-date.js +635 -0
- package/dist/classes/enhanced-date.js.map +1 -0
- package/dist/classes/path.d.ts +211 -48
- package/dist/classes/path.d.ts.map +1 -1
- package/dist/classes/path.js +188 -54
- package/dist/classes/path.js.map +1 -1
- package/dist/classes/precision-number.d.ts +44 -39
- package/dist/classes/precision-number.d.ts.map +1 -1
- package/dist/classes/precision-number.js +51 -45
- package/dist/classes/precision-number.js.map +1 -1
- package/dist/classes/ssh-client.d.ts +3 -4
- package/dist/classes/ssh-client.d.ts.map +1 -1
- package/dist/classes/ssh-client.js +2 -2
- package/dist/classes/ssh-client.js.map +1 -1
- package/dist/clipboard.d.ts +25 -26
- package/dist/clipboard.d.ts.map +1 -1
- package/dist/clipboard.js +23 -23
- package/dist/clipboard.js.map +1 -1
- package/dist/consola.d.ts +12 -15
- package/dist/consola.d.ts.map +1 -1
- package/dist/consola.js +10 -12
- package/dist/consola.js.map +1 -1
- package/dist/crypto-hash.d.ts +65 -56
- package/dist/crypto-hash.d.ts.map +1 -1
- package/dist/crypto-hash.js +55 -45
- package/dist/crypto-hash.js.map +1 -1
- package/dist/datetime.d.ts +41 -53
- package/dist/datetime.d.ts.map +1 -1
- package/dist/datetime.js +53 -66
- package/dist/datetime.js.map +1 -1
- package/dist/element-plus.d.ts +13 -14
- package/dist/element-plus.d.ts.map +1 -1
- package/dist/element-plus.js +11 -11
- package/dist/element-plus.js.map +1 -1
- package/dist/enum.d.ts +39 -36
- package/dist/enum.d.ts.map +1 -1
- package/dist/enum.js +36 -32
- package/dist/enum.js.map +1 -1
- package/dist/env.d.ts +22 -15
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +20 -12
- package/dist/env.js.map +1 -1
- package/dist/event-awaiter.d.ts +47 -52
- package/dist/event-awaiter.d.ts.map +1 -1
- package/dist/event-awaiter.js +46 -50
- package/dist/event-awaiter.js.map +1 -1
- package/dist/general.d.ts +22 -17
- package/dist/general.d.ts.map +1 -1
- package/dist/general.js.map +1 -1
- package/dist/hash.d.ts +24 -21
- package/dist/hash.d.ts.map +1 -1
- package/dist/hash.js +20 -16
- package/dist/hash.js.map +1 -1
- package/dist/math.d.ts +20 -19
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +14 -12
- package/dist/math.js.map +1 -1
- package/dist/number.d.ts +10 -9
- package/dist/number.d.ts.map +1 -1
- package/dist/number.js +9 -7
- package/dist/number.js.map +1 -1
- package/dist/object.d.ts +22 -10
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +21 -8
- package/dist/object.js.map +1 -1
- package/dist/pino.d.ts +13 -15
- package/dist/pino.d.ts.map +1 -1
- package/dist/pino.js +10 -15
- package/dist/pino.js.map +1 -1
- package/dist/random.d.ts +17 -15
- package/dist/random.d.ts.map +1 -1
- package/dist/random.js +16 -13
- package/dist/random.js.map +1 -1
- package/dist/redis/script-runner.d.ts +57 -0
- package/dist/redis/script-runner.d.ts.map +1 -0
- package/dist/redis/script-runner.js +46 -0
- package/dist/redis/script-runner.js.map +1 -0
- package/dist/storages/lru/keyed-store.d.ts +18 -14
- package/dist/storages/lru/keyed-store.d.ts.map +1 -1
- package/dist/storages/lru/keyed-store.js +17 -12
- package/dist/storages/lru/keyed-store.js.map +1 -1
- package/dist/storages/redis/keyed-store.d.ts +11 -21
- package/dist/storages/redis/keyed-store.d.ts.map +1 -1
- package/dist/storages/redis/keyed-store.js +10 -19
- package/dist/storages/redis/keyed-store.js.map +1 -1
- package/dist/storages/redis/msgpack.d.ts +33 -13
- package/dist/storages/redis/msgpack.d.ts.map +1 -1
- package/dist/storages/redis/msgpack.js +32 -11
- package/dist/storages/redis/msgpack.js.map +1 -1
- package/dist/storages/redis/types.d.ts +34 -17
- package/dist/storages/redis/types.d.ts.map +1 -1
- package/dist/string.d.ts +12 -11
- package/dist/string.d.ts.map +1 -1
- package/dist/string.js +20 -15
- package/dist/string.js.map +1 -1
- package/dist/time.d.ts +26 -21
- package/dist/time.d.ts.map +1 -1
- package/dist/time.js +24 -18
- package/dist/time.js.map +1 -1
- package/dist/types/filtered-key-path.d.ts +4 -15
- package/dist/types/filtered-key-path.d.ts.map +1 -1
- package/dist/types/index.d.ts +10 -10
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/vue.d.ts +7 -7
- package/dist/types/vue.d.ts.map +1 -1
- package/dist/url.d.ts +15 -14
- package/dist/url.d.ts.map +1 -1
- package/dist/url.js +12 -10
- package/dist/url.js.map +1 -1
- package/dist/vue.d.ts +19 -21
- package/dist/vue.d.ts.map +1 -1
- package/dist/vue.js +15 -16
- package/dist/vue.js.map +1 -1
- package/dist/web.d.ts +14 -11
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +12 -8
- package/dist/web.js.map +1 -1
- package/package.json +21 -21
- package/src/buffer.ts +18 -19
- package/src/classes/enhanced-date.ts +715 -0
- package/src/classes/path.ts +248 -96
- package/src/classes/precision-number.ts +61 -53
- package/src/classes/ssh-client.ts +8 -5
- package/src/clipboard.ts +23 -23
- package/src/consola.ts +10 -12
- package/src/crypto-hash.ts +55 -45
- package/src/datetime.ts +65 -85
- package/src/element-plus.ts +11 -11
- package/src/enum.ts +36 -32
- package/src/env.ts +20 -12
- package/src/event-awaiter.ts +49 -50
- package/src/general.ts +20 -14
- package/src/hash.ts +20 -16
- package/src/math.ts +18 -16
- package/src/number.ts +9 -7
- package/src/object.ts +21 -8
- package/src/pino.ts +11 -15
- package/src/random.ts +16 -13
- package/src/redis/script-runner.ts +107 -0
- package/src/storages/lru/keyed-store.ts +17 -12
- package/src/storages/redis/keyed-store.ts +10 -19
- package/src/storages/redis/msgpack.ts +32 -11
- package/src/storages/redis/types.ts +32 -14
- package/src/string.ts +10 -8
- package/src/time.ts +24 -18
- package/src/types/filtered-key-path.ts +9 -14
- package/src/types/vue.ts +6 -5
- package/src/url.ts +12 -10
- package/src/vue.ts +15 -16
- package/src/web.ts +12 -8
package/src/datetime.ts
CHANGED
|
@@ -1,77 +1,66 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
endOfMonth,
|
|
5
|
-
endOfWeek,
|
|
6
|
-
startOfDay,
|
|
7
|
-
startOfMonth,
|
|
8
|
-
startOfWeek,
|
|
9
|
-
subDays,
|
|
10
|
-
subMonths,
|
|
11
|
-
subWeeks,
|
|
12
|
-
} from 'date-fns';
|
|
13
|
-
import type {
|
|
14
|
-
DateArg,
|
|
15
|
-
Day,
|
|
16
|
-
FormatOptions,
|
|
17
|
-
} from 'date-fns';
|
|
1
|
+
import * as dateFns from 'date-fns';
|
|
2
|
+
|
|
3
|
+
import { EnhancedDate } from './classes/enhanced-date';
|
|
18
4
|
|
|
19
5
|
export type DateRangeType = 'lastMonth' | 'lastWeek' | 'thisMonth' | 'thisWeek' | 'today' | 'yesterday';
|
|
20
6
|
|
|
21
7
|
/**
|
|
22
|
-
* Formats a
|
|
8
|
+
* Formats a date using a date-fns pattern without changing the input.
|
|
23
9
|
*
|
|
24
|
-
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Formatting uses the system time zone unless configured through date-fns options.
|
|
12
|
+
* Invalid dates and unsupported patterns propagate date-fns exceptions.
|
|
25
13
|
*
|
|
26
|
-
* @param
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
14
|
+
* @param date - The date, timestamp in milliseconds, or date string to format.
|
|
15
|
+
* @param format - The date-fns pattern. Defaults to `yyyy-MM-dd HH:mm:ss`.
|
|
16
|
+
* @param options - Formatting options passed to date-fns.
|
|
29
17
|
*
|
|
30
|
-
* @returns
|
|
18
|
+
* @returns The formatted date string.
|
|
31
19
|
*
|
|
32
20
|
* @example
|
|
33
|
-
* ```typescript
|
|
34
|
-
* import { formatDate } from '@kikiutils/shared/datetime';
|
|
35
21
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* // Format a timestamp
|
|
40
|
-
* console.log(formatDate(1657814400000, 'yyyy-MM-dd')); // 2022-07-15
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { formatDate } from '@kikiutils/shared/datetime';
|
|
41
24
|
*
|
|
42
|
-
*
|
|
43
|
-
* console.log(formatDate(
|
|
25
|
+
* const date = new Date(2026, 0, 15, 12);
|
|
26
|
+
* console.log(formatDate(date, 'yyyy-MM-dd')); // => '2026-01-15'
|
|
44
27
|
* ```
|
|
45
28
|
*/
|
|
46
|
-
export function formatDate(
|
|
47
|
-
|
|
29
|
+
export function formatDate(
|
|
30
|
+
date: dateFns.DateArg<Date>,
|
|
31
|
+
format: string = 'yyyy-MM-dd HH:mm:ss',
|
|
32
|
+
options?: dateFns.FormatOptions,
|
|
33
|
+
) {
|
|
34
|
+
return dateFns.format(date, format, options);
|
|
48
35
|
}
|
|
49
36
|
|
|
37
|
+
/* eslint-disable jsdoc/check-param-names -- Inline TypeScript options are documented in remarks. */
|
|
38
|
+
|
|
50
39
|
/**
|
|
51
|
-
*
|
|
40
|
+
* Returns new start and end dates for a calendar range in the system time zone.
|
|
41
|
+
*
|
|
42
|
+
* @remarks
|
|
43
|
+
* The reference date is unchanged. Boundaries are inclusive by default, ending at `23:59:59.999`.
|
|
44
|
+
* When `options.setEndDateToNextDayStart` is `true`, the end is the exclusive start of the next calendar day.
|
|
45
|
+
* `options.weekStartsOn` defaults to `1` (Monday); `0` means Sunday and `6` means Saturday.
|
|
46
|
+
* Calendar ranges follow local daylight saving transitions rather than fixed 24-hour durations.
|
|
52
47
|
*
|
|
53
|
-
*
|
|
48
|
+
* @param date - The reference date for the range.
|
|
49
|
+
* @param type - The current or previous day, week, or month to select.
|
|
50
|
+
* @param options - Settings for the end boundary and first day of the week.
|
|
54
51
|
*
|
|
55
|
-
* @
|
|
56
|
-
* @param {DateRangeType} type - The range type to compute
|
|
57
|
-
* @param {object} [options] - Optional settings
|
|
58
|
-
* @param {boolean} [options.setEndDateToNextDayStart] - If true, set `endDate` to 00:00:00.000 of the next day
|
|
59
|
-
* @param {Day} [options.weekStartsOn] - The start day of the week (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
|
|
52
|
+
* @returns An object containing new `EnhancedDate` boundaries; the reference date is unchanged.
|
|
60
53
|
*
|
|
61
|
-
* @
|
|
54
|
+
* @throws Error if the range type is unsupported at runtime.
|
|
62
55
|
*
|
|
63
56
|
* @example
|
|
64
|
-
* ```typescript
|
|
65
|
-
* import { getDateRangeFromDate } from '@kikiutils/shared/datetime';
|
|
66
57
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* console.log(getDateRangeFromDate(date, 'lastMonth'));
|
|
70
|
-
* // { startDate: 2023-06-01T00:00:00.000Z, endDate: 2023-06-30T23:59:59.999Z }
|
|
58
|
+
* ```ts
|
|
59
|
+
* import { getDateRangeFromDate } from '@kikiutils/shared/datetime';
|
|
71
60
|
*
|
|
72
|
-
*
|
|
73
|
-
* console.log(
|
|
74
|
-
* //
|
|
61
|
+
* const range = getDateRangeFromDate(new Date(2026, 6, 15, 12), 'lastMonth');
|
|
62
|
+
* console.log(range.startDate.format('yyyy-MM-dd')); // => '2026-06-01'
|
|
63
|
+
* console.log(range.endDate.format('yyyy-MM-dd')); // => '2026-06-30'
|
|
75
64
|
* ```
|
|
76
65
|
*/
|
|
77
66
|
export function getDateRangeFromDate(
|
|
@@ -79,45 +68,46 @@ export function getDateRangeFromDate(
|
|
|
79
68
|
type: DateRangeType,
|
|
80
69
|
options?: {
|
|
81
70
|
setEndDateToNextDayStart?: boolean;
|
|
82
|
-
weekStartsOn?: Day;
|
|
71
|
+
weekStartsOn?: dateFns.Day;
|
|
83
72
|
},
|
|
84
73
|
) {
|
|
85
|
-
|
|
86
|
-
let
|
|
74
|
+
const referenceDate = new EnhancedDate(date);
|
|
75
|
+
let endDate: EnhancedDate;
|
|
76
|
+
let startDate: EnhancedDate;
|
|
87
77
|
switch (type) {
|
|
88
78
|
case 'lastMonth':
|
|
89
79
|
{
|
|
90
|
-
const lastMonth =
|
|
91
|
-
endDate =
|
|
92
|
-
startDate =
|
|
80
|
+
const lastMonth = referenceDate.toSubMonths(1);
|
|
81
|
+
endDate = lastMonth.toEndOfMonth();
|
|
82
|
+
startDate = lastMonth.toStartOfMonth();
|
|
93
83
|
}
|
|
94
84
|
|
|
95
85
|
break;
|
|
96
86
|
case 'lastWeek':
|
|
97
87
|
{
|
|
98
|
-
const lastWeek =
|
|
99
|
-
endDate =
|
|
100
|
-
startDate =
|
|
88
|
+
const lastWeek = referenceDate.toSubWeeks(1);
|
|
89
|
+
endDate = lastWeek.toEndOfWeek({ weekStartsOn: options?.weekStartsOn ?? 1 });
|
|
90
|
+
startDate = lastWeek.toStartOfWeek({ weekStartsOn: options?.weekStartsOn ?? 1 });
|
|
101
91
|
}
|
|
102
92
|
|
|
103
93
|
break;
|
|
104
94
|
case 'thisMonth':
|
|
105
|
-
endDate =
|
|
106
|
-
startDate =
|
|
95
|
+
endDate = referenceDate.toEndOfMonth();
|
|
96
|
+
startDate = referenceDate.toStartOfMonth();
|
|
107
97
|
break;
|
|
108
98
|
case 'thisWeek':
|
|
109
|
-
endDate =
|
|
110
|
-
startDate =
|
|
99
|
+
endDate = referenceDate.toEndOfWeek({ weekStartsOn: options?.weekStartsOn ?? 1 });
|
|
100
|
+
startDate = referenceDate.toStartOfWeek({ weekStartsOn: options?.weekStartsOn ?? 1 });
|
|
111
101
|
break;
|
|
112
102
|
case 'today':
|
|
113
|
-
endDate =
|
|
114
|
-
startDate =
|
|
103
|
+
endDate = referenceDate.toEndOfDay();
|
|
104
|
+
startDate = referenceDate.toStartOfDay();
|
|
115
105
|
break;
|
|
116
106
|
case 'yesterday':
|
|
117
107
|
{
|
|
118
|
-
const yesterday =
|
|
119
|
-
endDate =
|
|
120
|
-
startDate =
|
|
108
|
+
const yesterday = referenceDate.toSubDays(1);
|
|
109
|
+
endDate = yesterday.toEndOfDay();
|
|
110
|
+
startDate = yesterday.toStartOfDay();
|
|
121
111
|
}
|
|
122
112
|
|
|
123
113
|
break;
|
|
@@ -131,25 +121,15 @@ export function getDateRangeFromDate(
|
|
|
131
121
|
};
|
|
132
122
|
}
|
|
133
123
|
|
|
124
|
+
/* eslint-enable jsdoc/check-param-names */
|
|
125
|
+
|
|
134
126
|
/**
|
|
135
|
-
* Returns a
|
|
136
|
-
*
|
|
137
|
-
* @param {number} [offsetDays] - Number of days to offset from today. Can be negative
|
|
127
|
+
* Returns a new date at local midnight with an optional calendar-day offset from today.
|
|
138
128
|
*
|
|
139
|
-
* @
|
|
129
|
+
* @param offsetDays - The calendar days to add; negative values select earlier days.
|
|
140
130
|
*
|
|
141
|
-
* @
|
|
142
|
-
* ```typescript
|
|
143
|
-
* import { getMidnightDateFromToday } from '@kikiutils/shared/datetime';
|
|
144
|
-
*
|
|
145
|
-
* console.log(getMidnightDateFromToday()); // today at 00:00:00
|
|
146
|
-
* console.log(getMidnightDateFromToday(3)); // 3 days from today at 00:00:00
|
|
147
|
-
* console.log(getMidnightDateFromToday(-1)); // yesterday at 00:00:00
|
|
148
|
-
* ```
|
|
131
|
+
* @returns A new `EnhancedDate` at local midnight on the selected day.
|
|
149
132
|
*/
|
|
150
133
|
export function getMidnightDateFromToday(offsetDays: number = 0) {
|
|
151
|
-
|
|
152
|
-
date.setDate(date.getDate() + offsetDays);
|
|
153
|
-
date.setHours(0, 0, 0, 0);
|
|
154
|
-
return date;
|
|
134
|
+
return new EnhancedDate().addDays(offsetDays).startOfDay();
|
|
155
135
|
}
|
package/src/element-plus.ts
CHANGED
|
@@ -4,22 +4,22 @@ import type { FormItemRule } from 'element-plus';
|
|
|
4
4
|
export type DoNotRemoveOrUseThisType = RuleType;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Creates a
|
|
7
|
+
* Creates a new Element Plus form validation rule with overridable defaults.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Defaults to `required: true`, `trigger: 'blur'`, and `type: 'string'`.
|
|
11
|
+
* Non-nullish options override those defaults; `null` and `undefined` use the defaults.
|
|
12
|
+
* The `message` argument takes precedence over `options.message`.
|
|
13
|
+
* The options object is unchanged.
|
|
12
14
|
*
|
|
13
|
-
* @param
|
|
14
|
-
* @param
|
|
15
|
-
* @param {boolean} [options.required] - Whether the field is required (default: `true`)
|
|
16
|
-
* @param {string | string[]} [options.trigger] - The event(s) that trigger validation (default: `'blur'`)
|
|
17
|
-
* @param {RuleType} [options.type] - The expected type of the field (default: `'string'`)
|
|
15
|
+
* @param message - The validation message displayed on failure.
|
|
16
|
+
* @param options - Additional rule fields and non-nullish overrides for the defaults; `message` takes precedence.
|
|
18
17
|
*
|
|
19
|
-
* @returns A `FormItemRule` object
|
|
18
|
+
* @returns A new `FormItemRule` object.
|
|
20
19
|
*
|
|
21
20
|
* @example
|
|
22
|
-
*
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
23
|
* import { createElFormItemRuleWithDefaults } from '@kikiutils/shared/element-plus';
|
|
24
24
|
*
|
|
25
25
|
* const rule = createElFormItemRuleWithDefaults('This field is required');
|
package/src/enum.ts
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Extracts only the numeric values from an enumeration-like object.
|
|
3
3
|
*
|
|
4
|
-
* @
|
|
4
|
+
* @typeParam T - The type of the enum object.
|
|
5
5
|
*
|
|
6
|
-
* @param
|
|
6
|
+
* @param enumObject - The enumeration-like object to extract numeric values from,
|
|
7
7
|
* the object can contain numeric values, string values, or both.
|
|
8
8
|
*
|
|
9
|
-
* @returns
|
|
9
|
+
* @returns An array of numeric values extracted from the enum object.
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
13
14
|
* import { getEnumNumberValues } from '@kikiutils/shared/enum';
|
|
14
15
|
*
|
|
15
16
|
* enum RecordType {
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Receive = 0,
|
|
18
|
+
* Send = 1,
|
|
19
|
+
* Unknown = 'unknown',
|
|
19
20
|
* }
|
|
20
21
|
*
|
|
21
|
-
* console.log(getEnumNumberValues(RecordType)); // [0, 1]
|
|
22
|
+
* console.log(getEnumNumberValues(RecordType)); // => [0, 1]
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
24
25
|
export function getEnumNumberValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], number>[] {
|
|
@@ -28,24 +29,25 @@ export function getEnumNumberValues<T extends Record<string, any>>(enumObject: T
|
|
|
28
29
|
/**
|
|
29
30
|
* Extracts only the string values from an enumeration-like object.
|
|
30
31
|
*
|
|
31
|
-
* @
|
|
32
|
+
* @typeParam T - The type of the enum object.
|
|
32
33
|
*
|
|
33
|
-
* @param
|
|
34
|
+
* @param enumObject - The enumeration-like object to extract string values from,
|
|
34
35
|
* the object can contain numeric values, string values, or both.
|
|
35
36
|
*
|
|
36
|
-
* @returns
|
|
37
|
+
* @returns An array of string values extracted from the enum object.
|
|
37
38
|
*
|
|
38
39
|
* @example
|
|
39
|
-
*
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
40
42
|
* import { getEnumStringValues } from '@kikiutils/shared/enum';
|
|
41
43
|
*
|
|
42
44
|
* enum RecordType {
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
45
|
+
* Receive = 0,
|
|
46
|
+
* Send = 1,
|
|
47
|
+
* Unknown = 'unknown',
|
|
46
48
|
* }
|
|
47
49
|
*
|
|
48
|
-
* console.log(getEnumStringValues(RecordType)); // ['unknown']
|
|
50
|
+
* console.log(getEnumStringValues(RecordType)); // => ['unknown']
|
|
49
51
|
* ```
|
|
50
52
|
*/
|
|
51
53
|
export function getEnumStringValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], string>[] {
|
|
@@ -55,47 +57,49 @@ export function getEnumStringValues<T extends Record<string, any>>(enumObject: T
|
|
|
55
57
|
/**
|
|
56
58
|
* Extracts all values from an enumeration-like object.
|
|
57
59
|
*
|
|
60
|
+
* @remarks
|
|
58
61
|
* This function handles TypeScript enums correctly by accounting for the reverse mapping
|
|
59
62
|
* that occurs with numeric enums. It works with pure numeric enums, pure string enums,
|
|
60
63
|
* and mixed enums.
|
|
61
64
|
*
|
|
62
|
-
* @
|
|
65
|
+
* @typeParam T - The type of the enum object.
|
|
63
66
|
*
|
|
64
|
-
* @param
|
|
67
|
+
* @param enumObject - The enumeration-like object to extract values from,
|
|
65
68
|
* the object can contain numeric values, string values, or both.
|
|
66
69
|
*
|
|
67
|
-
* @returns
|
|
70
|
+
* @returns An array containing all the values from the enum object.
|
|
68
71
|
*
|
|
69
72
|
* @example
|
|
70
|
-
*
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
71
75
|
* import { getEnumValues } from '@kikiutils/shared/enum';
|
|
72
76
|
*
|
|
73
77
|
* // Numeric enum
|
|
74
78
|
* enum Status {
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
79
|
+
* Active = 0,
|
|
80
|
+
* Inactive = 1,
|
|
81
|
+
* Pending = 2,
|
|
78
82
|
* }
|
|
79
83
|
*
|
|
80
|
-
* console.log(getEnumValues(Status)); // [0, 1, 2]
|
|
84
|
+
* console.log(getEnumValues(Status)); // => [0, 1, 2]
|
|
81
85
|
*
|
|
82
86
|
* // String enum
|
|
83
87
|
* enum Color {
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
88
|
+
* Red = 'RED',
|
|
89
|
+
* Green = 'GREEN',
|
|
90
|
+
* Blue = 'BLUE',
|
|
87
91
|
* }
|
|
88
92
|
*
|
|
89
|
-
* console.log(getEnumValues(Color)); // ['RED', 'GREEN', 'BLUE']
|
|
93
|
+
* console.log(getEnumValues(Color)); // => ['RED', 'GREEN', 'BLUE']
|
|
90
94
|
*
|
|
91
95
|
* // Mixed enum
|
|
92
96
|
* enum RecordType {
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
97
|
+
* Receive = 0,
|
|
98
|
+
* Send = 1,
|
|
99
|
+
* Unknown = 'unknown',
|
|
96
100
|
* }
|
|
97
101
|
*
|
|
98
|
-
* console.log(getEnumValues(RecordType)); // [0, 1, 'unknown']
|
|
102
|
+
* console.log(getEnumValues(RecordType)); // => [0, 1, 'unknown']
|
|
99
103
|
* ```
|
|
100
104
|
*/
|
|
101
105
|
export function getEnumValues<T extends Record<string, any>>(enumObject: T): (T[keyof T])[] {
|
package/src/env.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Custom error class for handling missing environment variables.
|
|
3
3
|
*
|
|
4
|
+
* @remarks
|
|
4
5
|
* Extends the built-in `Error` class and includes the missing key.
|
|
5
|
-
*
|
|
6
|
-
* @extends {Error}
|
|
7
6
|
*/
|
|
8
7
|
export class EnvironmentNotFoundError extends Error {
|
|
9
8
|
readonly key: string;
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
|
-
* Creates a
|
|
11
|
+
* Creates an error identifying a missing environment variable.
|
|
13
12
|
*
|
|
14
|
-
* @param
|
|
13
|
+
* @param key - The missing environment variable key.
|
|
15
14
|
*/
|
|
16
15
|
constructor(key: string) {
|
|
17
16
|
super(`Missing environment variable: ${key}`);
|
|
@@ -24,24 +23,33 @@ export class EnvironmentNotFoundError extends Error {
|
|
|
24
23
|
/**
|
|
25
24
|
* Retrieves the value of an environment variable, or throws an error if it is not defined.
|
|
26
25
|
*
|
|
27
|
-
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* Only checks for `process.env[key] === undefined`. An empty string (for example `''`) or any falsy string
|
|
28
28
|
* value like `'0'` or `'false'` is considered a valid (defined) value.
|
|
29
29
|
*
|
|
30
|
-
* @param
|
|
30
|
+
* @param key - The environment variable key to retrieve.
|
|
31
31
|
*
|
|
32
|
-
* @returns
|
|
32
|
+
* @returns The value of the environment variable.
|
|
33
33
|
*
|
|
34
|
-
* @throws
|
|
34
|
+
* @throws EnvironmentNotFoundError if the environment variable is not defined.
|
|
35
35
|
*
|
|
36
36
|
* @example
|
|
37
|
-
*
|
|
38
|
-
*
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import {
|
|
40
|
+
* checkAndGetEnvValue,
|
|
41
|
+
* EnvironmentNotFoundError,
|
|
42
|
+
* } from '@kikiutils/shared/env';
|
|
39
43
|
*
|
|
40
44
|
* process.env.API_KEY = '';
|
|
41
|
-
* checkAndGetEnvValue('API_KEY'); //
|
|
45
|
+
* checkAndGetEnvValue('API_KEY'); // => ''
|
|
42
46
|
*
|
|
43
47
|
* delete process.env.API_KEY;
|
|
44
|
-
*
|
|
48
|
+
* try {
|
|
49
|
+
* checkAndGetEnvValue('API_KEY');
|
|
50
|
+
* } catch (error) {
|
|
51
|
+
* console.log(error instanceof EnvironmentNotFoundError); // => true
|
|
52
|
+
* }
|
|
45
53
|
* ```
|
|
46
54
|
*/
|
|
47
55
|
export function checkAndGetEnvValue(key: string) {
|
package/src/event-awaiter.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* An asynchronous keyed event rendezvous for one or more waiting consumers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Triggers resolve the currently registered waiters; values are not retained for future waits.
|
|
6
|
+
* Timeouts and subsequent abort events resolve affected waiters with `undefined`.
|
|
7
|
+
* Use `triggerAll` to resolve pending waits during cleanup. Timers and abort listeners are not proactively
|
|
8
|
+
* removed by triggers, so they may remain until their timeout or abort event occurs.
|
|
7
9
|
*
|
|
8
|
-
*
|
|
9
|
-
* or implementing event-driven primitives in applications or services.
|
|
10
|
-
*
|
|
11
|
-
* @template T - The type of value that will be resolved when the event is triggered
|
|
10
|
+
* @typeParam T - The value delivered to waiting consumers.
|
|
12
11
|
*/
|
|
13
12
|
export class EventAwaiter<T> {
|
|
13
|
+
// Private instance properties
|
|
14
14
|
#promiseResolvers = new Map<string, ((value: PromiseLike<T | undefined> | T | undefined) => void)[]>();
|
|
15
15
|
|
|
16
|
+
// Public instance methods
|
|
17
|
+
|
|
16
18
|
/**
|
|
17
|
-
*
|
|
18
|
-
* Each promise will be resolved with the provided value.
|
|
19
|
+
* Resolves all currently pending waits for a key with the supplied value.
|
|
19
20
|
*
|
|
20
|
-
* @param
|
|
21
|
-
* @param
|
|
22
|
-
* May be `undefined` to indicate no result or a timeout-like behavior.
|
|
21
|
+
* @param key - The event identifier; a key without pending waits has no effect.
|
|
22
|
+
* @param value - The delivered value; `undefined` indicates no result.
|
|
23
23
|
*/
|
|
24
24
|
trigger(key: string, value: T | undefined) {
|
|
25
25
|
const resolvers = this.#promiseResolvers.get(key);
|
|
@@ -30,13 +30,9 @@ export class EventAwaiter<T> {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* This is typically used during shutdown or cleanup to ensure that
|
|
36
|
-
* no consumer is left waiting indefinitely.
|
|
33
|
+
* Resolves all currently pending waits and clears their registrations.
|
|
37
34
|
*
|
|
38
|
-
* @param
|
|
39
|
-
* Defaults to `undefined`, which usually indicates cancellation or shutdown.
|
|
35
|
+
* @param value - The delivered value; omission resolves all pending waits with `undefined`.
|
|
40
36
|
*/
|
|
41
37
|
triggerAll(value: T | undefined = undefined) {
|
|
42
38
|
for (const [_, resolvers] of this.#promiseResolvers.entries()) resolvers.forEach((resolve) => resolve(value));
|
|
@@ -44,27 +40,23 @@ export class EventAwaiter<T> {
|
|
|
44
40
|
}
|
|
45
41
|
|
|
46
42
|
/**
|
|
47
|
-
* Waits for
|
|
43
|
+
* Waits for a trigger associated with a key.
|
|
48
44
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* By default, multiple waiters share a key and all receive the next trigger value.
|
|
47
|
+
* `strict` mode rejects duplicate waits; `override` mode resolves existing waits with `undefined` before
|
|
48
|
+
* registering the new wait. Timeout and abort remove only the affected waiter's registration.
|
|
49
|
+
* An already aborted signal is not checked; only an abort event emitted after registration ends the wait.
|
|
50
|
+
* Without a timeout or subsequent abort, the wait remains pending until a trigger arrives.
|
|
53
51
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* and only keeps the latest one.
|
|
52
|
+
* @param key - The event identifier to wait for.
|
|
53
|
+
* @param timeoutMs - The optional timeout in milliseconds, using native `setTimeout` timing rules.
|
|
54
|
+
* @param mode - The policy for existing waiters; omission allows multiple waiters.
|
|
55
|
+
* @param signal - A signal whose subsequent abort event ends this wait.
|
|
59
56
|
*
|
|
60
|
-
* @
|
|
61
|
-
* @param {number} [timeoutMs] - Optional timeout (in milliseconds).
|
|
62
|
-
* If reached, the promise resolves with `undefined`.
|
|
63
|
-
* @param {'override' | 'strict'} [mode] - Optional behavior mode for handling multiple waiters
|
|
64
|
-
* @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`
|
|
57
|
+
* @returns A promise resolving to the triggered value, or `undefined` after timeout, abort, or replacement.
|
|
65
58
|
*
|
|
66
|
-
* @
|
|
67
|
-
* or `undefined` if timeout or abort occurs
|
|
59
|
+
* @throws Error through promise rejection if `strict` mode encounters an existing waiter.
|
|
68
60
|
*/
|
|
69
61
|
wait(key: string, timeoutMs?: number, mode?: 'override' | 'strict', signal?: AbortSignal) {
|
|
70
62
|
return new Promise<T | undefined>((resolve) => {
|
|
@@ -116,28 +108,35 @@ export class EventAwaiter<T> {
|
|
|
116
108
|
}
|
|
117
109
|
|
|
118
110
|
/**
|
|
119
|
-
* Waits for
|
|
120
|
-
*
|
|
121
|
-
*
|
|
111
|
+
* Waits for a key while rejecting duplicate registrations.
|
|
112
|
+
*
|
|
113
|
+
* @param key - The event identifier to wait for.
|
|
114
|
+
* @param timeoutMs - The optional timeout in milliseconds.
|
|
115
|
+
* @param signal - A signal whose subsequent abort event ends this wait; an already aborted signal is not checked.
|
|
116
|
+
*
|
|
117
|
+
* @returns A promise resolving to the triggered value, or `undefined` on timeout or subsequent abort.
|
|
122
118
|
*
|
|
123
|
-
* @
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`
|
|
119
|
+
* @throws Error through promise rejection if the key already has a pending waiter.
|
|
120
|
+
*
|
|
121
|
+
* @see {@link EventAwaiter.wait}
|
|
127
122
|
*/
|
|
128
123
|
waitExclusive(key: string, timeoutMs?: number, signal?: AbortSignal) {
|
|
129
124
|
return this.wait(key, timeoutMs, 'strict', signal);
|
|
130
125
|
}
|
|
131
126
|
|
|
132
127
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
128
|
+
* Replaces existing waiters for a key and waits for its next trigger.
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* Existing waiters resolve with `undefined` before the new waiter is registered.
|
|
132
|
+
*
|
|
133
|
+
* @param key - The event identifier to wait for.
|
|
134
|
+
* @param timeoutMs - The optional timeout in milliseconds.
|
|
135
|
+
* @param signal - A signal whose subsequent abort event ends this wait; an already aborted signal is not checked.
|
|
136
|
+
*
|
|
137
|
+
* @returns A promise resolving to the triggered value, or `undefined` on timeout, subsequent abort, or replacement.
|
|
136
138
|
*
|
|
137
|
-
* @
|
|
138
|
-
* @param {number} [timeoutMs] - Optional timeout (in milliseconds).
|
|
139
|
-
* If reached, the promise resolves with `undefined`.
|
|
140
|
-
* @param {AbortSignal} [signal] - Optional AbortSignal. If aborted, the promise resolves with `undefined`
|
|
139
|
+
* @see {@link EventAwaiter.wait}
|
|
141
140
|
*/
|
|
142
141
|
waitLatest(key: string, timeoutMs?: number, signal?: AbortSignal) {
|
|
143
142
|
return this.wait(key, timeoutMs, 'override', signal);
|
package/src/general.ts
CHANGED
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
/* eslint-disable jsdoc/check-param-names */
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Returns the first array element or the input value, with a nullish fallback.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* An empty array, `null`, or `undefined` selects the fallback; omission of a fallback yields `undefined`.
|
|
8
|
+
* The input and selected values are not copied or changed.
|
|
9
9
|
*
|
|
10
|
-
* @
|
|
11
|
-
* @
|
|
10
|
+
* @typeParam T - The input value or array element type.
|
|
11
|
+
* @typeParam D - The fallback type when the fallback overload is used.
|
|
12
12
|
*
|
|
13
|
-
* @param
|
|
14
|
-
* @param
|
|
13
|
+
* @param value - A single value or an array of values.
|
|
14
|
+
* @param defaultValue - The fallback returned when the selected value is nullish.
|
|
15
15
|
*
|
|
16
|
-
* @returns
|
|
16
|
+
* @returns The selected non-nullish value, or the fallback without copying either value.
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
|
-
*
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
20
21
|
* import { extractFirstValue } from '@kikiutils/shared/general';
|
|
21
22
|
*
|
|
22
|
-
* console.log(extractFirstValue([
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* console.log(extractFirstValue([
|
|
24
|
+
* 1,
|
|
25
|
+
* 2,
|
|
26
|
+
* 3,
|
|
27
|
+
* ])); // => 1
|
|
28
|
+
*
|
|
29
|
+
* console.log(extractFirstValue('hello')); // => 'hello'
|
|
30
|
+
* console.log(extractFirstValue([], 'default')); // => 'default'
|
|
31
|
+
* console.log(extractFirstValue(undefined, 'fallback')); // => 'fallback'
|
|
26
32
|
* ```
|
|
27
33
|
*/
|
|
28
34
|
export function extractFirstValue<T>(value: T | T[]): T | undefined;
|