@kikiutils/shared 20.0.0 → 20.1.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.js.map +1 -1
- package/dist/classes/enhanced-date.d.ts +2 -2
- package/dist/classes/enhanced-date.d.ts.map +1 -1
- package/dist/classes/enhanced-date.js.map +1 -1
- package/dist/classes/path.d.ts +1 -1
- package/dist/classes/path.d.ts.map +1 -1
- package/dist/classes/path.js.map +1 -1
- package/dist/enum.d.ts +3 -3
- package/dist/enum.d.ts.map +1 -1
- package/dist/enum.js.map +1 -1
- package/dist/event-awaiter.d.ts.map +1 -1
- package/dist/event-awaiter.js +1 -0
- package/dist/event-awaiter.js.map +1 -1
- package/dist/logger/_internals/formatter.d.ts +12 -4
- package/dist/logger/_internals/formatter.d.ts.map +1 -1
- package/dist/logger/_internals/formatter.js +12 -4
- package/dist/logger/_internals/formatter.js.map +1 -1
- package/dist/logger/_internals/logger.d.ts +6 -2
- package/dist/logger/_internals/logger.d.ts.map +1 -1
- package/dist/logger/_internals/logger.js +3 -1
- package/dist/logger/_internals/logger.js.map +1 -1
- package/dist/logger/index.js +1 -1
- package/dist/logger/node/_internals/file-writer.d.ts +3 -1
- package/dist/logger/node/_internals/file-writer.d.ts.map +1 -1
- package/dist/logger/node/_internals/file-writer.js +6 -2
- package/dist/logger/node/_internals/file-writer.js.map +1 -1
- package/dist/logger/node/_internals/formatter.d.ts +3 -1
- package/dist/logger/node/_internals/formatter.d.ts.map +1 -1
- package/dist/logger/node/_internals/formatter.js +3 -1
- package/dist/logger/node/_internals/formatter.js.map +1 -1
- package/dist/logger/node/index.js +4 -2
- package/dist/logger/node/index.js.map +1 -1
- package/dist/logger/node/types.d.ts +36 -12
- package/dist/logger/node/types.d.ts.map +1 -1
- package/dist/logger/types.d.ts +44 -19
- package/dist/logger/types.d.ts.map +1 -1
- package/dist/redis/script-runner.d.ts +1 -1
- package/dist/redis/script-runner.d.ts.map +1 -1
- package/dist/redis/script-runner.js.map +1 -1
- package/dist/types/filtered-key-path.d.ts +2 -2
- package/dist/types/filtered-key-path.d.ts.map +1 -1
- package/dist/types/filtered-key-path.js +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/vue.js +1 -0
- package/dist/url.d.ts.map +1 -1
- package/dist/url.js.map +1 -1
- package/package.json +44 -70
- package/src/buffer.ts +0 -1
- package/src/classes/enhanced-date.ts +2 -2
- package/src/classes/path.ts +1 -1
- package/src/enum.ts +3 -3
- package/src/event-awaiter.ts +3 -1
- package/src/logger/_internals/formatter.ts +12 -4
- package/src/logger/_internals/logger.ts +6 -2
- package/src/logger/node/_internals/file-writer.ts +6 -2
- package/src/logger/node/_internals/formatter.ts +3 -1
- package/src/logger/node/index.ts +4 -1
- package/src/logger/node/types.ts +36 -12
- package/src/logger/types.ts +45 -19
- package/src/redis/script-runner.ts +1 -1
- package/src/types/filtered-key-path.ts +2 -2
- package/src/types/index.ts +6 -0
- package/src/url.ts +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kikiutils/shared",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "20.
|
|
4
|
+
"version": "20.1.0",
|
|
5
5
|
"description": "A lightweight and modular utility library for modern JavaScript and TypeScript — includes secure hashing, flexible logging, datetime tools, Vue/web helpers, storage abstraction, and more.",
|
|
6
6
|
"author": "kiki-kanri",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,68 +31,41 @@
|
|
|
31
31
|
],
|
|
32
32
|
"sideEffects": false,
|
|
33
33
|
"exports": {
|
|
34
|
-
"./
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"./
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"./
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"./logger/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"./
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"./
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"./
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"./logger/node/_internals/file-writer": {
|
|
70
|
-
"types": null,
|
|
71
|
-
"import": null,
|
|
72
|
-
"require": null
|
|
73
|
-
},
|
|
74
|
-
"./logger/node/_internals/formatter": {
|
|
75
|
-
"types": null,
|
|
76
|
-
"import": null,
|
|
77
|
-
"require": null
|
|
78
|
-
},
|
|
79
|
-
"./logger/node/index": {
|
|
80
|
-
"types": null,
|
|
81
|
-
"import": null,
|
|
82
|
-
"require": null
|
|
83
|
-
},
|
|
84
|
-
"./package.json": "./package.json",
|
|
85
|
-
"./types": {
|
|
86
|
-
"types": "./dist/types/index.d.ts",
|
|
87
|
-
"import": null,
|
|
88
|
-
"require": null
|
|
89
|
-
},
|
|
90
|
-
"./types/index": {
|
|
91
|
-
"types": null,
|
|
92
|
-
"import": null,
|
|
93
|
-
"require": null
|
|
94
|
-
},
|
|
95
|
-
"./*": "./dist/*.js"
|
|
34
|
+
"./buffer": "./dist/buffer.js",
|
|
35
|
+
"./classes/enhanced-date": "./dist/classes/enhanced-date.js",
|
|
36
|
+
"./classes/path": "./dist/classes/path.js",
|
|
37
|
+
"./classes/precision-number": "./dist/classes/precision-number.js",
|
|
38
|
+
"./clipboard": "./dist/clipboard.js",
|
|
39
|
+
"./crypto-hash": "./dist/crypto-hash.js",
|
|
40
|
+
"./datetime": "./dist/datetime.js",
|
|
41
|
+
"./element-plus": "./dist/element-plus.js",
|
|
42
|
+
"./enum": "./dist/enum.js",
|
|
43
|
+
"./env": "./dist/env.js",
|
|
44
|
+
"./event-awaiter": "./dist/event-awaiter.js",
|
|
45
|
+
"./file": "./dist/file.js",
|
|
46
|
+
"./general": "./dist/general.js",
|
|
47
|
+
"./hash": "./dist/hash.js",
|
|
48
|
+
"./logger": "./dist/logger/index.js",
|
|
49
|
+
"./logger/node": "./dist/logger/node/index.js",
|
|
50
|
+
"./logger/node/types": "./dist/logger/node/types.js",
|
|
51
|
+
"./logger/types": "./dist/logger/types.js",
|
|
52
|
+
"./math": "./dist/math.js",
|
|
53
|
+
"./number": "./dist/number.js",
|
|
54
|
+
"./random": "./dist/random.js",
|
|
55
|
+
"./redis/script-runner": "./dist/redis/script-runner.js",
|
|
56
|
+
"./storages/lru/keyed-store": "./dist/storages/lru/keyed-store.js",
|
|
57
|
+
"./storages/redis/keyed-store": "./dist/storages/redis/keyed-store.js",
|
|
58
|
+
"./storages/redis/msgpack": "./dist/storages/redis/msgpack.js",
|
|
59
|
+
"./storages/redis/types": "./dist/storages/redis/types.js",
|
|
60
|
+
"./string": "./dist/string.js",
|
|
61
|
+
"./time": "./dist/time.js",
|
|
62
|
+
"./types": "./dist/types/index.js",
|
|
63
|
+
"./types/filtered-key-path": "./dist/types/filtered-key-path.js",
|
|
64
|
+
"./types/vue": "./dist/types/vue.js",
|
|
65
|
+
"./url": "./dist/url.js",
|
|
66
|
+
"./vue": "./dist/vue.js",
|
|
67
|
+
"./web": "./dist/web.js",
|
|
68
|
+
"./package.json": "./package.json"
|
|
96
69
|
},
|
|
97
70
|
"files": [
|
|
98
71
|
"./dist",
|
|
@@ -172,10 +145,11 @@
|
|
|
172
145
|
},
|
|
173
146
|
"devDependencies": {
|
|
174
147
|
"@antfu/eslint-config": "^10.0.0",
|
|
175
|
-
"@
|
|
148
|
+
"@arethetypeswrong/core": "^0.18.5",
|
|
149
|
+
"@kikiutils/eslint-config": "^10.1.0",
|
|
176
150
|
"@kikiutils/tsconfigs": "^7.0.0",
|
|
177
151
|
"@noble/hashes": "^2.4.0",
|
|
178
|
-
"@types/node": "^26.6.
|
|
152
|
+
"@types/node": "^26.6.6",
|
|
179
153
|
"@vitest/coverage-v8": "^5.0.5",
|
|
180
154
|
"async-validator": "^4.2.5",
|
|
181
155
|
"bson": "^7.3.3",
|
|
@@ -184,16 +158,16 @@
|
|
|
184
158
|
"date-fns": "^4.4.0",
|
|
185
159
|
"decimal.js": "^10.6.0",
|
|
186
160
|
"element-plus": "^2.14.7",
|
|
187
|
-
"eslint": "^10.
|
|
188
|
-
"file-type": "^22.
|
|
161
|
+
"eslint": "^10.14.0",
|
|
162
|
+
"file-type": "^22.3.0",
|
|
189
163
|
"jsdom": "^30.1.3",
|
|
190
|
-
"knip": "^6.
|
|
164
|
+
"knip": "^6.44.1",
|
|
191
165
|
"lru-cache": "^11.5.3",
|
|
192
166
|
"millify": "^6.1.0",
|
|
193
|
-
"msgpackr": "^2.1.
|
|
167
|
+
"msgpackr": "^2.1.3",
|
|
194
168
|
"publint": "^0.3.25",
|
|
195
169
|
"rotating-file-stream": "^3.2.10",
|
|
196
|
-
"tsdown": "^0.23.
|
|
170
|
+
"tsdown": "^0.23.4",
|
|
197
171
|
"typescript": "^6.0.3",
|
|
198
172
|
"unplugin-unused": "^0.6.0",
|
|
199
173
|
"vitest": "^5.0.5",
|
package/src/buffer.ts
CHANGED
|
@@ -36,6 +36,5 @@ export async function toBuffer(input: BinaryInput) {
|
|
|
36
36
|
if (input instanceof ArrayBuffer) return Buffer.from(input);
|
|
37
37
|
if (input instanceof Uint8Array) return Buffer.from(input.buffer, input.byteOffset, input.byteLength);
|
|
38
38
|
if (typeof input.arrayBuffer === 'function') return Buffer.from(await input.arrayBuffer());
|
|
39
|
-
// eslint-disable-next-line style/max-len
|
|
40
39
|
throw new TypeError('The provided input is not a supported binary type (Blob, Buffer, File, ArrayBuffer, or Uint8Array).');
|
|
41
40
|
}
|
|
@@ -100,7 +100,7 @@ export class EnhancedDate extends Date {
|
|
|
100
100
|
*
|
|
101
101
|
* @returns A new `EnhancedDate`, or `Invalid Date` if the array is empty or contains an invalid date.
|
|
102
102
|
*/
|
|
103
|
-
static max(dates:
|
|
103
|
+
static max(dates: Array<Date | number>) {
|
|
104
104
|
return new EnhancedDate(dateFns.max(dates));
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -111,7 +111,7 @@ export class EnhancedDate extends Date {
|
|
|
111
111
|
*
|
|
112
112
|
* @returns A new `EnhancedDate`, or `Invalid Date` if the array is empty or contains an invalid date.
|
|
113
113
|
*/
|
|
114
|
-
static min(dates:
|
|
114
|
+
static min(dates: Array<Date | number>) {
|
|
115
115
|
return new EnhancedDate(dateFns.min(dates));
|
|
116
116
|
}
|
|
117
117
|
|
package/src/classes/path.ts
CHANGED
package/src/enum.ts
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* console.log(getEnumNumberValues(RecordType)); // => [0, 1]
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
export function getEnumNumberValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], number
|
|
25
|
+
export function getEnumNumberValues<T extends Record<string, any>>(enumObject: T): Array<Extract<T[keyof T], number>> {
|
|
26
26
|
return getEnumValues(enumObject).filter((value) => typeof value === 'number');
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -50,7 +50,7 @@ export function getEnumNumberValues<T extends Record<string, any>>(enumObject: T
|
|
|
50
50
|
* console.log(getEnumStringValues(RecordType)); // => ['unknown']
|
|
51
51
|
* ```
|
|
52
52
|
*/
|
|
53
|
-
export function getEnumStringValues<T extends Record<string, any>>(enumObject: T): Extract<T[keyof T], string
|
|
53
|
+
export function getEnumStringValues<T extends Record<string, any>>(enumObject: T): Array<Extract<T[keyof T], string>> {
|
|
54
54
|
return getEnumValues(enumObject).filter((value) => typeof value === 'string');
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -102,7 +102,7 @@ export function getEnumStringValues<T extends Record<string, any>>(enumObject: T
|
|
|
102
102
|
* console.log(getEnumValues(RecordType)); // => [0, 1, 'unknown']
|
|
103
103
|
* ```
|
|
104
104
|
*/
|
|
105
|
-
export function getEnumValues<T extends Record<string, any>>(enumObject: T):
|
|
105
|
+
export function getEnumValues<T extends Record<string, any>>(enumObject: T): Array<T[keyof T]> {
|
|
106
106
|
const values = Object.values(enumObject);
|
|
107
107
|
const hasNumberValues = values.some((value) => typeof value === 'number');
|
|
108
108
|
if (!hasNumberValues) return values;
|
package/src/event-awaiter.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export class EventAwaiter<T> {
|
|
13
13
|
// Private instance properties
|
|
14
|
-
#promiseResolvers = new Map<string, (
|
|
14
|
+
#promiseResolvers = new Map<string, Array<(value: PromiseLike<T | undefined> | T | undefined) => void>>();
|
|
15
15
|
|
|
16
16
|
// Public instance methods
|
|
17
17
|
|
|
@@ -69,6 +69,8 @@ export class EventAwaiter<T> {
|
|
|
69
69
|
break;
|
|
70
70
|
case 'strict':
|
|
71
71
|
throw new Error(`Duplicate wait detected for key: ${key}`);
|
|
72
|
+
case undefined:
|
|
73
|
+
break;
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -6,7 +6,9 @@ import type { LoggerRecord } from './types';
|
|
|
6
6
|
|
|
7
7
|
// Functions
|
|
8
8
|
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Native console formatting keeps user strings literal and objects expandable.
|
|
11
|
+
*/
|
|
10
12
|
export function formatLoggerConsoleArgs(record: LoggerRecord): unknown[] {
|
|
11
13
|
if (typeof process !== 'undefined' && process.versions?.node) {
|
|
12
14
|
const target = process[getLoggerStreamName(record.type)];
|
|
@@ -39,7 +41,9 @@ export function formatLoggerConsoleArgs(record: LoggerRecord): unknown[] {
|
|
|
39
41
|
];
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Keeps data arguments intact so browser developer tools can expand objects.
|
|
46
|
+
*/
|
|
43
47
|
export function formatLoggerParts(record: LoggerRecord, colors = false): unknown[] {
|
|
44
48
|
const parts: unknown[] = [];
|
|
45
49
|
const paint = (text: string, color: string) => colors ? `\u001B[${color}m${text}\u001B[0m` : text;
|
|
@@ -51,7 +55,9 @@ export function formatLoggerParts(record: LoggerRecord, colors = false): unknown
|
|
|
51
55
|
return parts;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Fixed local-time representation, deliberately without a per-second cache.
|
|
60
|
+
*/
|
|
55
61
|
export function formatLoggerTime(date: Date): string {
|
|
56
62
|
const pad = (value: number, width = 2) => String(value).padStart(width, '0');
|
|
57
63
|
const day = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
@@ -59,7 +65,9 @@ export function formatLoggerTime(date: Date): string {
|
|
|
59
65
|
return `[${day} ${time}.${pad(date.getMilliseconds(), 3)}]`;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Use native terminal detection; redirected streams still honor FORCE_COLOR.
|
|
70
|
+
*/
|
|
63
71
|
export function supportsLoggerColor(target: { hasColors?: () => boolean; isTTY?: boolean }): boolean {
|
|
64
72
|
if (target.hasColors) return target.hasColors();
|
|
65
73
|
const forced = process.env.FORCE_COLOR;
|
|
@@ -10,7 +10,9 @@ import { loggerMethods } from './levels';
|
|
|
10
10
|
import type { LoggerRecord } from './types';
|
|
11
11
|
|
|
12
12
|
interface LoggerHooks {
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* A non-throwing reporter created by createDiagnosticReporter.
|
|
15
|
+
*/
|
|
14
16
|
report: (event: LoggerDiagnostic) => void;
|
|
15
17
|
write: (record: LoggerRecord) => Promise<void> | void;
|
|
16
18
|
}
|
|
@@ -29,7 +31,9 @@ const stringPresentationKeys = [
|
|
|
29
31
|
|
|
30
32
|
// Functions
|
|
31
33
|
|
|
32
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* A non-recursive, rate-limited diagnostic boundary shared by server and browser adapters.
|
|
36
|
+
*/
|
|
33
37
|
export function createDiagnosticReporter(
|
|
34
38
|
onError?: (event: Readonly<LoggerDiagnostic>) => void,
|
|
35
39
|
fallback?: (message: string) => void,
|
|
@@ -26,7 +26,9 @@ const defaultMaxPendingBytes = 8 * 1024 * 1024;
|
|
|
26
26
|
|
|
27
27
|
// Functions
|
|
28
28
|
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* A bounded admission layer over the stream's own ordered write buffer; not a second FIFO.
|
|
31
|
+
*/
|
|
30
32
|
export async function createFileWriter(
|
|
31
33
|
options: LoggerFileOptions,
|
|
32
34
|
report: (event: LoggerDiagnostic) => void,
|
|
@@ -213,7 +215,9 @@ export async function createFileWriter(
|
|
|
213
215
|
});
|
|
214
216
|
}
|
|
215
217
|
|
|
216
|
-
/**
|
|
218
|
+
/**
|
|
219
|
+
* Validate before mkdir, stream creation, or other filesystem side effects.
|
|
220
|
+
*/
|
|
217
221
|
function validateFileOptions(options: LoggerFileOptions) {
|
|
218
222
|
if (
|
|
219
223
|
!options
|
|
@@ -5,7 +5,9 @@ import type { LoggerRecord } from '../../_internals/types';
|
|
|
5
5
|
|
|
6
6
|
// Functions
|
|
7
7
|
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Preserve user ANSI for console output without invoking custom inspect callbacks/getters.
|
|
10
|
+
*/
|
|
9
11
|
export function formatNodeLoggerRecord(record: LoggerRecord, colors = false) {
|
|
10
12
|
const message = record.args.map(
|
|
11
13
|
(arg) => typeof arg === 'string'
|
package/src/logger/node/index.ts
CHANGED
|
@@ -107,6 +107,7 @@ export async function createNodeLogger(options: NodeLoggerOptions = {}): Promise
|
|
|
107
107
|
|
|
108
108
|
consoleTargets.clear();
|
|
109
109
|
})();
|
|
110
|
+
|
|
110
111
|
return closePromise;
|
|
111
112
|
},
|
|
112
113
|
getStats: () => writer?.getStats() ?? Object.freeze({
|
|
@@ -117,7 +118,9 @@ export async function createNodeLogger(options: NodeLoggerOptions = {}): Promise
|
|
|
117
118
|
});
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* One error listener per shared output stream; retained until its last owning logger calls close().
|
|
123
|
+
*/
|
|
121
124
|
function writeConsole(
|
|
122
125
|
target: NodeJS.WriteStream,
|
|
123
126
|
text: string,
|
package/src/logger/node/types.ts
CHANGED
|
@@ -4,50 +4,74 @@ import type {
|
|
|
4
4
|
LoggerOptions,
|
|
5
5
|
} from '../types';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Specify interval and/or maxSize. Size limits use positive integers with B, K, M, or G (binary units).
|
|
9
|
+
*/
|
|
8
10
|
export type LoggerRotationOptions = {
|
|
9
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Gzip historical files. Defaults to true.
|
|
13
|
+
*/
|
|
10
14
|
compress?: boolean;
|
|
11
15
|
|
|
12
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Number of historical files, excluding the active file. Defaults to 30.
|
|
18
|
+
*/
|
|
13
19
|
keepFiles?: number;
|
|
14
20
|
|
|
15
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Maximum combined size of historical files.
|
|
23
|
+
*/
|
|
16
24
|
maxTotalSize?: string;
|
|
17
25
|
} & (
|
|
18
26
|
| {
|
|
19
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Opt-in time rotation aligned to the system's local calendar boundary.
|
|
29
|
+
*/
|
|
20
30
|
interval: 'daily' | 'hourly';
|
|
21
31
|
maxSize?: string;
|
|
22
32
|
}
|
|
23
33
|
| {
|
|
24
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Opt-in time rotation aligned to the system's local calendar boundary.
|
|
36
|
+
*/
|
|
25
37
|
interval?: 'daily' | 'hourly';
|
|
26
38
|
maxSize: string;
|
|
27
39
|
}
|
|
28
40
|
);
|
|
29
41
|
|
|
30
42
|
export interface LoggerFileOptions {
|
|
31
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Maximum unfinished payload bytes, including data already submitted to the stream.
|
|
45
|
+
*/
|
|
32
46
|
maxPendingBytes?: number;
|
|
33
47
|
|
|
34
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Resolved once at creation. The file is opened in append mode.
|
|
50
|
+
*/
|
|
35
51
|
path: PathLike;
|
|
36
52
|
|
|
37
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Omitted or false disables rotation. An object must specify interval or maxSize.
|
|
55
|
+
*/
|
|
38
56
|
rotate?: false | LoggerRotationOptions;
|
|
39
57
|
}
|
|
40
58
|
|
|
41
59
|
export interface NodeLogger extends Logger {
|
|
42
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Stop accepting records, finish accepted file writes, then release the stream. Not fsync.
|
|
62
|
+
*/
|
|
43
63
|
close: () => Promise<void>;
|
|
44
64
|
|
|
45
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* A fresh, frozen file-output snapshot. Dropped/failed records still resolve their logging promises.
|
|
67
|
+
*/
|
|
46
68
|
getStats: () => Readonly<NodeLoggerStats>;
|
|
47
69
|
}
|
|
48
70
|
|
|
49
71
|
export interface NodeLoggerOptions extends LoggerOptions {
|
|
50
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Disabled by default. Each logger owns at most one fixed file destination.
|
|
74
|
+
*/
|
|
51
75
|
file?: false | LoggerFileOptions;
|
|
52
76
|
}
|
|
53
77
|
|
package/src/logger/types.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import type { SafePromise } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Minimum severity to emit; `success` uses the same threshold as `info`.
|
|
5
|
+
*/
|
|
2
6
|
export type LoggerLevel = 'debug' | 'error' | 'fatal' | 'info' | 'silent' | 'trace' | 'warn';
|
|
3
7
|
|
|
4
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* A logging method, including the informational success presentation.
|
|
10
|
+
*/
|
|
5
11
|
export type LoggerMethod = 'success' | Exclude<LoggerLevel, 'silent'>;
|
|
6
12
|
|
|
7
13
|
/**
|
|
@@ -13,48 +19,68 @@ export type LoggerMethod = 'success' | Exclude<LoggerLevel, 'silent'>;
|
|
|
13
19
|
*/
|
|
14
20
|
export interface Logger {
|
|
15
21
|
configure: (options: Pick<LoggerOptions, 'console' | 'icons' | 'prefix' | 'suffix' | 'timestamp'>) => void;
|
|
16
|
-
debug: (...args: unknown[]) =>
|
|
17
|
-
error: (...args: unknown[]) =>
|
|
18
|
-
fatal: (...args: unknown[]) =>
|
|
19
|
-
info: (...args: unknown[]) =>
|
|
22
|
+
debug: (...args: unknown[]) => SafePromise<void>;
|
|
23
|
+
error: (...args: unknown[]) => SafePromise<void>;
|
|
24
|
+
fatal: (...args: unknown[]) => SafePromise<void>;
|
|
25
|
+
info: (...args: unknown[]) => SafePromise<void>;
|
|
20
26
|
|
|
21
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Accepts success as an informational method; it is not a configurable threshold.
|
|
29
|
+
*/
|
|
22
30
|
isLevelEnabled: (level: LoggerLevel | LoggerMethod) => boolean;
|
|
23
31
|
|
|
24
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Sets a severity threshold (not success); env restores environment-driven filtering.
|
|
34
|
+
*/
|
|
25
35
|
setLevel: (level: 'env' | LoggerLevel) => void;
|
|
26
|
-
success: (...args: unknown[]) =>
|
|
27
|
-
trace: (...args: unknown[]) =>
|
|
28
|
-
warn: (...args: unknown[]) =>
|
|
36
|
+
success: (...args: unknown[]) => SafePromise<void>;
|
|
37
|
+
trace: (...args: unknown[]) => SafePromise<void>;
|
|
38
|
+
warn: (...args: unknown[]) => SafePromise<void>;
|
|
29
39
|
}
|
|
30
40
|
|
|
31
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* A shallow-frozen failure notification; nested error values retain their original ownership.
|
|
43
|
+
*/
|
|
32
44
|
export interface LoggerDiagnostic {
|
|
33
45
|
droppedCount?: number;
|
|
34
46
|
error?: unknown;
|
|
35
47
|
message: string;
|
|
36
48
|
|
|
37
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Same-type notifications suppressed since the previous emitted diagnostic.
|
|
51
|
+
*/
|
|
38
52
|
suppressedCount?: number;
|
|
39
53
|
type: 'closed' | 'console' | 'file' | 'format' | 'invalid-level' | 'overflow';
|
|
40
54
|
}
|
|
41
55
|
|
|
42
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Configuration shared by browser and server loggers.
|
|
58
|
+
*/
|
|
43
59
|
export interface LoggerOptions {
|
|
44
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Enables console output. Defaults to `true`.
|
|
62
|
+
*/
|
|
45
63
|
console?: boolean;
|
|
46
64
|
|
|
47
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Enables Unicode level icons. Defaults to `true`.
|
|
67
|
+
*/
|
|
48
68
|
icons?: boolean;
|
|
49
69
|
|
|
50
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Overrides LOG_LEVEL; `env` restores the environment-driven threshold.
|
|
72
|
+
*/
|
|
51
73
|
level?: 'env' | LoggerLevel;
|
|
52
74
|
|
|
53
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* Best-effort, rate-limited notification; failures in this callback are contained.
|
|
77
|
+
*/
|
|
54
78
|
onError?: (event: Readonly<LoggerDiagnostic>) => void;
|
|
55
79
|
prefix?: string;
|
|
56
80
|
suffix?: string;
|
|
57
81
|
|
|
58
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* Enables the fixed local-time millisecond prefix. Defaults to `true`.
|
|
84
|
+
*/
|
|
59
85
|
timestamp?: boolean;
|
|
60
86
|
}
|
|
@@ -14,7 +14,7 @@ import { createHash } from 'node:crypto';
|
|
|
14
14
|
*
|
|
15
15
|
* @returns A promise resolving to the Redis script result after execution completes.
|
|
16
16
|
*/
|
|
17
|
-
export type RedisScriptRunner<T = unknown> = (keys: readonly string[], args:
|
|
17
|
+
export type RedisScriptRunner<T = unknown> = (keys: readonly string[], args: ReadonlyArray<number | string>) => Promise<
|
|
18
18
|
T
|
|
19
19
|
>;
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ type DefaultPath<
|
|
|
22
22
|
export type FilteredKeyPath<T, U = never> = T extends ReadonlyArray<infer V> ? (IsTuple<T> extends true ? { [K in TupleKey<T>]-?: PathImpl<Exclude<K, symbol>, T[K], U> }[TupleKey<T>] : PathImpl<number, V, U>) : { [K in keyof T]-?: PathImpl<Exclude<K, symbol>, T[K], U> }[keyof T];
|
|
23
23
|
/* eslint-enable style/max-len */
|
|
24
24
|
|
|
25
|
-
type IsTuple<T extends
|
|
25
|
+
type IsTuple<T extends readonly any[]> = number extends T['length'] ? false : true;
|
|
26
26
|
type PathImpl<K extends number | string, V, U> = [U] extends [never] ? DefaultPath<K, V> : ConditionalPath<K, V, U>;
|
|
27
27
|
type TerminalType =
|
|
28
28
|
| bigint
|
|
@@ -38,4 +38,4 @@ type TerminalType =
|
|
|
38
38
|
| symbol
|
|
39
39
|
| undefined;
|
|
40
40
|
|
|
41
|
-
type TupleKey<T extends
|
|
41
|
+
type TupleKey<T extends readonly any[]> = Exclude<keyof T, keyof any[]>;
|
package/src/types/index.ts
CHANGED
|
@@ -40,3 +40,9 @@ export type ReadonlyPartialRecord<K extends keyof any, T> = Readonly<PartialReco
|
|
|
40
40
|
* A readonly `Record`.
|
|
41
41
|
*/
|
|
42
42
|
export type ReadonlyRecord<K extends keyof any, T> = Readonly<Record<K, T>>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A promise whose rejection is handled internally and can safely be left unawaited.
|
|
46
|
+
* This type only marks that contract; it does not add runtime rejection handling.
|
|
47
|
+
*/
|
|
48
|
+
export type SafePromise<T> = Promise<T> & { readonly __safePromise?: true };
|
package/src/url.ts
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
* @throws Error if `redirectPath` is not a safe same-origin application path.
|
|
13
13
|
*/
|
|
14
14
|
export function appendRedirectParamToUrl(url: string, redirectPath: string) {
|
|
15
|
-
// eslint-disable-next-line style/max-len
|
|
16
15
|
if (!isSafeRedirectPath(redirectPath)) throw new Error(`Invalid redirect path: "${redirectPath}". Redirect paths must be safe same-origin paths starting with '/'.`);
|
|
17
16
|
|
|
18
17
|
const [baseAndHash, rawQuery = ''] = url.split('?');
|