@adviser/cement 0.2.40 → 0.2.42
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/{chunk-USQXEZHL.js → chunk-3RHIVQAA.js} +2 -2
- package/{chunk-W2GV5KXV.js → chunk-N3NUTN4B.js} +3 -3
- package/{chunk-F5W6VELE.js → chunk-N5LQQXOU.js} +2 -2
- package/chunk-PPS4L4VW.js +38 -0
- package/{chunk-GES3MUGV.js.map → chunk-PPS4L4VW.js.map} +1 -1
- package/index.cjs +500 -179
- package/index.cjs.map +1 -1
- package/index.d.cts +73 -30
- package/index.d.ts +73 -30
- package/index.js +506 -141
- package/index.js.map +1 -1
- package/node/index.js +2 -2
- package/package.json +2 -2
- package/src/http_header.ts +161 -0
- package/src/index.ts +1 -0
- package/src/jsr.json +1 -1
- package/src/log-level-impl.ts +7 -0
- package/src/logger-impl.ts +70 -43
- package/src/logger.ts +37 -9
- package/src/option.ts +7 -0
- package/src/result.ts +7 -1
- package/src/uri.ts +35 -11
- package/src/utils/relative-path.ts +161 -0
- package/ts/http_header.d.ts +29 -0
- package/ts/http_header.d.ts.map +1 -0
- package/ts/http_header.js +155 -0
- package/ts/http_header.js.map +1 -0
- package/ts/http_header.test.d.ts +2 -0
- package/ts/http_header.test.d.ts.map +1 -0
- package/ts/http_header.test.js +90 -0
- package/ts/http_header.test.js.map +1 -0
- package/ts/index.d.ts +1 -0
- package/ts/index.d.ts.map +1 -1
- package/ts/index.js +1 -0
- package/ts/index.js.map +1 -1
- package/ts/log-level-impl.d.ts +3 -0
- package/ts/log-level-impl.d.ts.map +1 -1
- package/ts/log-level-impl.js +5 -0
- package/ts/log-level-impl.js.map +1 -1
- package/ts/logger-impl.d.ts +2 -1
- package/ts/logger-impl.d.ts.map +1 -1
- package/ts/logger-impl.js +66 -47
- package/ts/logger-impl.js.map +1 -1
- package/ts/logger.d.ts +10 -1
- package/ts/logger.d.ts.map +1 -1
- package/ts/logger.js +22 -8
- package/ts/logger.js.map +1 -1
- package/ts/logger.test.js +111 -58
- package/ts/logger.test.js.map +1 -1
- package/ts/option.d.ts +1 -0
- package/ts/option.d.ts.map +1 -1
- package/ts/option.js +6 -0
- package/ts/option.js.map +1 -1
- package/ts/result.d.ts +1 -1
- package/ts/result.d.ts.map +1 -1
- package/ts/result.js +6 -0
- package/ts/result.js.map +1 -1
- package/ts/result.test.js +6 -0
- package/ts/result.test.js.map +1 -1
- package/ts/tracer.js +24 -6
- package/ts/tracer.js.map +1 -1
- package/ts/uri.d.ts +3 -1
- package/ts/uri.d.ts.map +1 -1
- package/ts/uri.js +27 -10
- package/ts/uri.js.map +1 -1
- package/ts/uri.test.js +39 -10
- package/ts/uri.test.js.map +1 -1
- package/ts/utils/relative-path.d.ts +17 -0
- package/ts/utils/relative-path.d.ts.map +1 -0
- package/ts/utils/relative-path.js +148 -0
- package/ts/utils/relative-path.js.map +1 -0
- package/ts/utils/relative-path.test.d.ts +2 -0
- package/ts/utils/relative-path.test.d.ts.map +1 -0
- package/ts/utils/relative-path.test.js +187 -0
- package/ts/utils/relative-path.test.js.map +1 -0
- package/ts/utils/stripper.js +1 -1
- package/ts/utils/stripper.js.map +1 -1
- package/utils/index.js +2 -2
- package/web/index.js +3 -3
- package/chunk-GES3MUGV.js +0 -92
- /package/{chunk-USQXEZHL.js.map → chunk-3RHIVQAA.js.map} +0 -0
- /package/{chunk-W2GV5KXV.js.map → chunk-N3NUTN4B.js.map} +0 -0
- /package/{chunk-F5W6VELE.js.map → chunk-N5LQQXOU.js.map} +0 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@adviser/cement",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.42",
|
4
4
|
"description": "better try/catch/finally handling",
|
5
5
|
"main": "index.js",
|
6
6
|
"type": "module",
|
@@ -49,7 +49,7 @@
|
|
49
49
|
"@vitest/browser": "^2.1.1",
|
50
50
|
"esbuild-plugin-replace": "^1.4.0",
|
51
51
|
"esbuild-plugin-resolve": "^2.0.0",
|
52
|
-
"eslint": "9.
|
52
|
+
"eslint": "9.17.0",
|
53
53
|
"prettier": "^3.3.3",
|
54
54
|
"tsup": "^8.3.0",
|
55
55
|
"tsx": "^4.19.1",
|
@@ -0,0 +1,161 @@
|
|
1
|
+
export class HeadersImpl extends Headers {
|
2
|
+
readonly _headers: Map<string, string>;
|
3
|
+
|
4
|
+
constructor(init: Map<string, string>) {
|
5
|
+
super();
|
6
|
+
this._headers = init;
|
7
|
+
}
|
8
|
+
|
9
|
+
[Symbol.iterator](): HeadersIterator<[string, string]> {
|
10
|
+
return this.entries();
|
11
|
+
}
|
12
|
+
|
13
|
+
entries(): HeadersIterator<[string, string]> {
|
14
|
+
return this._headers.entries();
|
15
|
+
}
|
16
|
+
keys(): HeadersIterator<string> {
|
17
|
+
return this._headers.keys();
|
18
|
+
}
|
19
|
+
values(): HeadersIterator<string> {
|
20
|
+
return this._headers.values();
|
21
|
+
}
|
22
|
+
|
23
|
+
append(key: string, value: string | string[] | undefined): HeadersImpl {
|
24
|
+
const values = this._headers.get(key);
|
25
|
+
if (typeof value === "undefined") {
|
26
|
+
value = "";
|
27
|
+
}
|
28
|
+
if (Array.isArray(value)) {
|
29
|
+
this._headers.set(key, [values, ...value].filter((i) => i).join(", "));
|
30
|
+
} else {
|
31
|
+
this._headers.set(key, [values, value].filter((i) => i).join(", "));
|
32
|
+
}
|
33
|
+
return this;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
export class HttpHeader {
|
38
|
+
readonly _headers: Map<string, string[]> = new Map<string, string[]>();
|
39
|
+
|
40
|
+
static from(headers?: HeadersInit | NodeJS.Dict<string | string[]> | Headers): HttpHeader {
|
41
|
+
const h = new HttpHeader();
|
42
|
+
if (headers) {
|
43
|
+
if (Array.isArray(headers)) {
|
44
|
+
for (const [k, v] of headers) {
|
45
|
+
if (v) {
|
46
|
+
h.Add(k, v);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
} else if (headers instanceof Headers) {
|
50
|
+
for (const [k, v] of headers.entries()) {
|
51
|
+
if (v) {
|
52
|
+
h.Add(
|
53
|
+
k,
|
54
|
+
v.split(",").map((v) => v.trim()),
|
55
|
+
);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
for (const k in headers) {
|
60
|
+
const v = headers[k];
|
61
|
+
if (v) {
|
62
|
+
h.Add(k, v);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
return h;
|
68
|
+
}
|
69
|
+
|
70
|
+
_asStringString(): Map<string, string> {
|
71
|
+
const ret = new Map<string, string>();
|
72
|
+
for (const [key, values] of this._headers) {
|
73
|
+
ret.set(key, values.join(", "));
|
74
|
+
}
|
75
|
+
return ret;
|
76
|
+
}
|
77
|
+
|
78
|
+
_key(key: string): string {
|
79
|
+
return key.toLowerCase();
|
80
|
+
}
|
81
|
+
Values(key: string): string[] {
|
82
|
+
const values = this._headers.get(this._key(key));
|
83
|
+
return values || [];
|
84
|
+
}
|
85
|
+
Get(key: string): string | undefined {
|
86
|
+
const values = this._headers.get(this._key(key));
|
87
|
+
if (values === undefined || values.length === 0) {
|
88
|
+
return undefined;
|
89
|
+
}
|
90
|
+
return values[0];
|
91
|
+
}
|
92
|
+
Set(key: string, valueOr: string | string[]): HttpHeader {
|
93
|
+
const value = Array.isArray(valueOr) ? valueOr : [valueOr];
|
94
|
+
this._headers.set(this._key(key), value);
|
95
|
+
return this;
|
96
|
+
}
|
97
|
+
Add(key: string, value: string | string[] | undefined): HttpHeader {
|
98
|
+
if (typeof value === "undefined") {
|
99
|
+
return this;
|
100
|
+
}
|
101
|
+
const vs = Array.isArray(value) ? value : [value];
|
102
|
+
const values = this._headers.get(this._key(key));
|
103
|
+
if (values === undefined) {
|
104
|
+
this._headers.set(this._key(key), vs);
|
105
|
+
} else {
|
106
|
+
values.push(...vs);
|
107
|
+
}
|
108
|
+
return this;
|
109
|
+
}
|
110
|
+
Del(ey: string): HttpHeader {
|
111
|
+
this._headers.delete(this._key(ey));
|
112
|
+
return this;
|
113
|
+
}
|
114
|
+
Items(): [string, string[]][] {
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
116
|
+
return Array.from(this._headers).filter(([_, vs]) => vs.length > 0);
|
117
|
+
}
|
118
|
+
SortItems(): [string, string[]][] {
|
119
|
+
return this.Items().sort(([[a]], [[b]]) => a.localeCompare(b));
|
120
|
+
}
|
121
|
+
Clone(): HttpHeader {
|
122
|
+
const clone = new HttpHeader();
|
123
|
+
for (const [key, values] of this._headers.entries()) {
|
124
|
+
clone._headers.set(key, values.slice());
|
125
|
+
}
|
126
|
+
return clone;
|
127
|
+
}
|
128
|
+
AsRecordStringStringArray(): Record<string, string[]> {
|
129
|
+
const obj: Record<string, string[]> = {};
|
130
|
+
for (const [key, values] of this._headers.entries()) {
|
131
|
+
obj[key] = [...values];
|
132
|
+
}
|
133
|
+
return obj;
|
134
|
+
}
|
135
|
+
AsRecordStringString(): Record<string, string> {
|
136
|
+
const obj: Record<string, string> = {};
|
137
|
+
for (const [key, values] of this._headers.entries()) {
|
138
|
+
obj[key] = values.join(", ");
|
139
|
+
}
|
140
|
+
return obj;
|
141
|
+
}
|
142
|
+
AsHeaderInit(): HeadersInit {
|
143
|
+
const obj: HeadersInit = {};
|
144
|
+
for (const [key, values] of this._headers.entries()) {
|
145
|
+
obj[key] = values[0];
|
146
|
+
}
|
147
|
+
return obj;
|
148
|
+
}
|
149
|
+
AsHeaders(): Headers {
|
150
|
+
return new HeadersImpl(this._asStringString());
|
151
|
+
}
|
152
|
+
Merge(other?: HttpHeader): HttpHeader {
|
153
|
+
const ret = this.Clone();
|
154
|
+
if (other) {
|
155
|
+
for (const [key, values] of other.Items()) {
|
156
|
+
ret.Add(key, values);
|
157
|
+
}
|
158
|
+
}
|
159
|
+
return ret;
|
160
|
+
}
|
161
|
+
}
|
package/src/index.ts
CHANGED
package/src/jsr.json
CHANGED
package/src/log-level-impl.ts
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
import { LevelHandler, Level } from "./logger.js";
|
2
|
+
import { Option } from "./option.js";
|
2
3
|
|
3
4
|
export class LevelHandlerImpl implements LevelHandler {
|
4
5
|
readonly _globalLevels: Set<Level> = new Set<Level>([Level.INFO, Level.ERROR, Level.WARN]);
|
5
6
|
readonly _modules: Map<string, Set<Level>> = new Map<string, Set<Level>>();
|
7
|
+
|
8
|
+
ignoreAttr: Option<RegExp> = Option.Some(/^_/);
|
6
9
|
isStackExposed = false;
|
7
10
|
enableLevel(level: Level, ...modules: string[]): void {
|
8
11
|
if (modules.length == 0) {
|
@@ -35,6 +38,10 @@ export class LevelHandlerImpl implements LevelHandler {
|
|
35
38
|
this.isStackExposed = !!enable;
|
36
39
|
}
|
37
40
|
|
41
|
+
setIgnoreAttr(re?: RegExp): void {
|
42
|
+
this.ignoreAttr = Option.From(re);
|
43
|
+
}
|
44
|
+
|
38
45
|
forModules(level: Level, fnAction: (p: string) => void, ...modules: (string | string[])[]): void {
|
39
46
|
for (const m of modules.flat()) {
|
40
47
|
if (typeof m !== "string") {
|
package/src/logger-impl.ts
CHANGED
@@ -18,6 +18,7 @@ import {
|
|
18
18
|
LogFormatter,
|
19
19
|
LogValueArg,
|
20
20
|
HttpType,
|
21
|
+
LogValueState,
|
21
22
|
} from "./logger.js";
|
22
23
|
import { WebSysAbstraction } from "./web/web-sys-abstraction.js";
|
23
24
|
import { SysAbstraction } from "./sys-abstraction.js";
|
@@ -29,20 +30,20 @@ import { LogWriterStream } from "./log-writer-impl.js";
|
|
29
30
|
import { TxtEnDecoder, Utf8EnDecoderSingleton } from "./txt-en-decoder.js";
|
30
31
|
import { LevelHandlerSingleton } from "./log-level-impl.js";
|
31
32
|
|
32
|
-
function getLen(value: unknown): LogValue {
|
33
|
+
function getLen(value: unknown, lvs: LogValueState): LogValue {
|
33
34
|
if (Array.isArray(value)) {
|
34
|
-
return logValue(() => value.length);
|
35
|
+
return logValue(() => value.length, lvs);
|
35
36
|
} else if (typeof value === "string") {
|
36
|
-
return logValue(() => value.length);
|
37
|
+
return logValue(() => value.length, lvs);
|
37
38
|
} else if (typeof value === "object" && value !== null) {
|
38
39
|
if (typeof (value as Sized).size === "number") {
|
39
|
-
return logValue(() => (value as Sized).size);
|
40
|
+
return logValue(() => (value as Sized).size, lvs);
|
40
41
|
} else if (typeof (value as Lengthed).length === "number") {
|
41
|
-
return logValue(() => (value as Lengthed).length);
|
42
|
+
return logValue(() => (value as Lengthed).length, lvs);
|
42
43
|
}
|
43
|
-
return logValue(() => Object.keys(value).length);
|
44
|
+
return logValue(() => Object.keys(value).length, lvs);
|
44
45
|
}
|
45
|
-
return logValue(() => -1);
|
46
|
+
return logValue(() => -1, lvs);
|
46
47
|
}
|
47
48
|
|
48
49
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
@@ -100,12 +101,18 @@ export interface LoggerImplParams {
|
|
100
101
|
readonly formatter?: LogFormatter;
|
101
102
|
}
|
102
103
|
|
104
|
+
function toLogValueCtx(lvh: LevelHandler): LogValueState {
|
105
|
+
return {
|
106
|
+
ignoreAttr: lvh.ignoreAttr,
|
107
|
+
};
|
108
|
+
}
|
109
|
+
|
103
110
|
export class LoggerImpl implements Logger {
|
104
111
|
readonly _sys: SysAbstraction;
|
105
112
|
readonly _attributes: LogSerializable = {};
|
106
113
|
readonly _withAttributes: LogSerializable;
|
107
114
|
readonly _logWriter: LogWriterStream;
|
108
|
-
readonly
|
115
|
+
readonly levelHandler: LevelHandler;
|
109
116
|
readonly _txtEnDe: TxtEnDecoder;
|
110
117
|
_formatter: LogFormatter;
|
111
118
|
// readonly _id: string = "logger-" + Math.random().toString(36)
|
@@ -157,9 +164,9 @@ export class LoggerImpl implements Logger {
|
|
157
164
|
}
|
158
165
|
this._attributes = { ...this._withAttributes };
|
159
166
|
if (params.levelHandler) {
|
160
|
-
this.
|
167
|
+
this.levelHandler = params.levelHandler;
|
161
168
|
} else {
|
162
|
-
this.
|
169
|
+
this.levelHandler = LevelHandlerSingleton();
|
163
170
|
}
|
164
171
|
// console.log("LoggerImpl", this._id, this._attributes, this._withAttributes)
|
165
172
|
}
|
@@ -182,27 +189,32 @@ export class LoggerImpl implements Logger {
|
|
182
189
|
}
|
183
190
|
|
184
191
|
SetExposeStack(enable?: boolean): Logger {
|
185
|
-
this.
|
192
|
+
this.levelHandler.setExposeStack(enable);
|
186
193
|
return this;
|
187
194
|
}
|
188
195
|
|
189
196
|
EnableLevel(level: Level, ...modules: string[]): Logger {
|
190
|
-
this.
|
197
|
+
this.levelHandler.enableLevel(level, ...modules);
|
191
198
|
return this;
|
192
199
|
}
|
193
200
|
DisableLevel(level: Level, ...modules: string[]): Logger {
|
194
|
-
this.
|
201
|
+
this.levelHandler.disableLevel(level, ...modules);
|
195
202
|
return this;
|
196
203
|
}
|
197
204
|
|
198
205
|
Module(key: string): Logger {
|
199
|
-
this._attributes["module"] = logValue(key);
|
200
|
-
this._withAttributes["module"] = logValue(key);
|
206
|
+
this._attributes["module"] = logValue(key, toLogValueCtx(this.levelHandler));
|
207
|
+
this._withAttributes["module"] = logValue(key, toLogValueCtx(this.levelHandler));
|
201
208
|
return this;
|
202
209
|
}
|
203
210
|
// if the string is "*" it will enable for all modules
|
204
211
|
SetDebug(...modules: (string | string[])[]): Logger {
|
205
|
-
this.
|
212
|
+
this.levelHandler.setDebug(...modules);
|
213
|
+
return this;
|
214
|
+
}
|
215
|
+
|
216
|
+
SetIgnoreAttribute(re?: RegExp): Logger {
|
217
|
+
this.levelHandler.setIgnoreAttr(re);
|
206
218
|
return this;
|
207
219
|
}
|
208
220
|
|
@@ -212,57 +224,63 @@ export class LoggerImpl implements Logger {
|
|
212
224
|
}
|
213
225
|
|
214
226
|
Timestamp(): Logger {
|
215
|
-
this._attributes["ts"] = logValue(() => this._sys.Time().Now().toISOString());
|
227
|
+
this._attributes["ts"] = logValue(() => this._sys.Time().Now().toISOString(), toLogValueCtx(this.levelHandler));
|
216
228
|
return this;
|
217
229
|
}
|
218
230
|
Warn(): Logger {
|
219
|
-
this._attributes["level"] = logValue(Level.WARN);
|
231
|
+
this._attributes["level"] = logValue(Level.WARN, toLogValueCtx(this.levelHandler));
|
220
232
|
return this;
|
221
233
|
}
|
222
234
|
Log(): Logger {
|
223
235
|
return this;
|
224
236
|
}
|
225
237
|
Debug(): Logger {
|
226
|
-
this._attributes["level"] = logValue(Level.DEBUG);
|
238
|
+
this._attributes["level"] = logValue(Level.DEBUG, toLogValueCtx(this.levelHandler));
|
227
239
|
return this;
|
228
240
|
}
|
229
241
|
Error(): Logger {
|
230
|
-
this._attributes["level"] = logValue(Level.ERROR);
|
242
|
+
this._attributes["level"] = logValue(Level.ERROR, toLogValueCtx(this.levelHandler));
|
231
243
|
return this;
|
232
244
|
}
|
233
245
|
Info(): Logger {
|
234
|
-
this._attributes["level"] = logValue(Level.INFO);
|
246
|
+
this._attributes["level"] = logValue(Level.INFO, toLogValueCtx(this.levelHandler));
|
235
247
|
return this;
|
236
248
|
}
|
237
249
|
Err(err: unknown | Result<unknown> | Error): Logger {
|
250
|
+
let key = "error";
|
238
251
|
if (Result.Is(err)) {
|
239
252
|
if (err.isOk()) {
|
240
|
-
|
253
|
+
key = "noerror";
|
254
|
+
err = err.Ok();
|
241
255
|
} else {
|
242
|
-
|
256
|
+
err = err.Err();
|
243
257
|
}
|
244
|
-
}
|
245
|
-
|
246
|
-
|
247
|
-
|
258
|
+
}
|
259
|
+
if (err instanceof Error) {
|
260
|
+
this._attributes[key] = logValue(err.message, toLogValueCtx(this.levelHandler));
|
261
|
+
if (this.levelHandler.isStackExposed) {
|
262
|
+
this._attributes["stack"] = logValue(
|
263
|
+
err.stack?.split("\n").map((s) => s.trim()),
|
264
|
+
toLogValueCtx(this.levelHandler),
|
265
|
+
);
|
248
266
|
}
|
249
267
|
} else {
|
250
|
-
this.
|
268
|
+
this.Any(key, err as LogSerializable);
|
251
269
|
}
|
252
270
|
return this;
|
253
271
|
}
|
254
272
|
WithLevel(l: Level): Logger {
|
255
|
-
this._attributes["level"] = logValue(l);
|
273
|
+
this._attributes["level"] = logValue(l, toLogValueCtx(this.levelHandler));
|
256
274
|
return this;
|
257
275
|
}
|
258
276
|
|
259
277
|
Ref(key: string, action: { toString: () => string } | FnSerialized): Logger {
|
260
278
|
if (typeof action === "function") {
|
261
|
-
this._attributes[key] = logValue(action as FnSerialized);
|
279
|
+
this._attributes[key] = logValue(action as FnSerialized, toLogValueCtx(this.levelHandler));
|
262
280
|
} else if (typeof action.toString === "function") {
|
263
|
-
this._attributes[key] = logValue(() => action.toString());
|
281
|
+
this._attributes[key] = logValue(() => action.toString(), toLogValueCtx(this.levelHandler));
|
264
282
|
} else {
|
265
|
-
this._attributes[key] = logValue("INVALID REF");
|
283
|
+
this._attributes[key] = logValue("INVALID REF", toLogValueCtx(this.levelHandler));
|
266
284
|
}
|
267
285
|
return this;
|
268
286
|
}
|
@@ -319,7 +337,7 @@ export class LoggerImpl implements Logger {
|
|
319
337
|
|
320
338
|
Result<T>(key: string, res: Result<T, Error>): Logger {
|
321
339
|
if (res.isOk()) {
|
322
|
-
this._attributes[key] = logValue(res.Ok() as Serialized);
|
340
|
+
this._attributes[key] = logValue(res.Ok() as Serialized, toLogValueCtx(this.levelHandler));
|
323
341
|
} else {
|
324
342
|
this.Err(res.Err());
|
325
343
|
}
|
@@ -327,12 +345,14 @@ export class LoggerImpl implements Logger {
|
|
327
345
|
}
|
328
346
|
|
329
347
|
Len(value: unknown, key = "len"): Logger {
|
330
|
-
this._attributes[key] = getLen(value);
|
348
|
+
this._attributes[key] = getLen(value, toLogValueCtx(this.levelHandler));
|
331
349
|
return this;
|
332
350
|
}
|
333
351
|
|
334
352
|
Hash(value: unknown, key = "hash"): Logger {
|
335
|
-
this._attributes[key] = asyncLogValue(
|
353
|
+
this._attributes[key] = asyncLogValue(
|
354
|
+
async () => `${getLen(value, toLogValueCtx(this.levelHandler)).value()}:${await hash(value)}`,
|
355
|
+
);
|
336
356
|
return this;
|
337
357
|
}
|
338
358
|
|
@@ -343,7 +363,7 @@ export class LoggerImpl implements Logger {
|
|
343
363
|
|
344
364
|
private coerceKey(key: string | Record<string, unknown>, value?: unknown): void {
|
345
365
|
if (typeof key === "string") {
|
346
|
-
this._attributes[key] = logValue(value as LogValueArg);
|
366
|
+
this._attributes[key] = logValue(value as LogValueArg, toLogValueCtx(this.levelHandler));
|
347
367
|
} else {
|
348
368
|
this.Pair(key);
|
349
369
|
}
|
@@ -360,7 +380,7 @@ export class LoggerImpl implements Logger {
|
|
360
380
|
return this;
|
361
381
|
}
|
362
382
|
Dur(key: string, nsec: number): Logger {
|
363
|
-
this._attributes[key] = logValue(`${nsec}ms
|
383
|
+
this._attributes[key] = logValue(`${nsec}ms`, toLogValueCtx(this.levelHandler));
|
364
384
|
// new Intl.DurationFormat("en", { style: "narrow" }).format(nsec);
|
365
385
|
return this;
|
366
386
|
}
|
@@ -385,7 +405,7 @@ export class LoggerImpl implements Logger {
|
|
385
405
|
new LoggerImpl({
|
386
406
|
logWriter: this._logWriter,
|
387
407
|
sys: this._sys,
|
388
|
-
levelHandler: this.
|
408
|
+
levelHandler: this.levelHandler,
|
389
409
|
formatter: this._formatter,
|
390
410
|
withAttributes: {
|
391
411
|
module: this._attributes["module"],
|
@@ -407,11 +427,11 @@ export class LoggerImpl implements Logger {
|
|
407
427
|
|
408
428
|
Msg(...args: string[]): AsError {
|
409
429
|
const fnError = this._resetAttributes(() => {
|
410
|
-
const doWrite = this.
|
430
|
+
const doWrite = this.levelHandler.isEnabled(
|
411
431
|
toLogValue(this._attributes["level"])?.value(),
|
412
432
|
toLogValue(this._attributes["module"])?.value(),
|
413
433
|
);
|
414
|
-
this._attributes["msg"] = logValue(args.join(" "));
|
434
|
+
this._attributes["msg"] = logValue(args.join(" "), toLogValueCtx(this.levelHandler));
|
415
435
|
const msg = this._attributes["msg"].value();
|
416
436
|
if (typeof msg === "string" && !msg.trim().length) {
|
417
437
|
delete this._attributes["msg"];
|
@@ -434,8 +454,10 @@ export class LoggerImpl implements Logger {
|
|
434
454
|
|
435
455
|
class WithLoggerBuilder implements WithLogger {
|
436
456
|
readonly _li: LoggerImpl;
|
457
|
+
readonly levelHandler: LevelHandler;
|
437
458
|
constructor(li: LoggerImpl) {
|
438
459
|
this._li = li;
|
460
|
+
this.levelHandler = li.levelHandler;
|
439
461
|
}
|
440
462
|
|
441
463
|
TxtEnDe(): TxtEnDecoder {
|
@@ -452,7 +474,12 @@ class WithLoggerBuilder implements WithLogger {
|
|
452
474
|
}
|
453
475
|
|
454
476
|
SetExposeStack(enable?: boolean): WithLogger {
|
455
|
-
this._li.
|
477
|
+
this._li.levelHandler.setExposeStack(enable);
|
478
|
+
return this;
|
479
|
+
}
|
480
|
+
|
481
|
+
SetIgnoreAttribute(re?: RegExp): WithLogger {
|
482
|
+
this._li.levelHandler.setIgnoreAttr(re);
|
456
483
|
return this;
|
457
484
|
}
|
458
485
|
|
@@ -462,11 +489,11 @@ class WithLoggerBuilder implements WithLogger {
|
|
462
489
|
}
|
463
490
|
|
464
491
|
EnableLevel(level: Level, ...modules: string[]): WithLogger {
|
465
|
-
this._li.
|
492
|
+
this._li.levelHandler.enableLevel(level, ...modules);
|
466
493
|
return this;
|
467
494
|
}
|
468
495
|
DisableLevel(level: Level, ...modules: string[]): WithLogger {
|
469
|
-
this._li.
|
496
|
+
this._li.levelHandler.enableLevel(level, ...modules);
|
470
497
|
return this;
|
471
498
|
}
|
472
499
|
|
package/src/logger.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { bin2string } from "./bin2text.js";
|
2
|
+
import { Option } from "./option.js";
|
2
3
|
import { Result } from "./result.js";
|
3
4
|
import { TxtEnDecoder } from "./txt-en-decoder.js";
|
4
5
|
import { CoerceURI } from "./uri.js";
|
@@ -50,7 +51,25 @@ export function asyncLogValue(val: () => Promise<Serialized>): Promise<LogValue>
|
|
50
51
|
|
51
52
|
export type LogValueArg = LogValue | Serialized | Serialized[] | FnSerialized | undefined | null;
|
52
53
|
|
53
|
-
export
|
54
|
+
export interface LogValueState {
|
55
|
+
readonly state?: Set<unknown>;
|
56
|
+
readonly ignoreAttr: Option<RegExp>;
|
57
|
+
}
|
58
|
+
|
59
|
+
export function logValue(val: LogValueArg, ctx: LogValueState): LogValue {
|
60
|
+
return logValueInternal(val, {
|
61
|
+
...ctx,
|
62
|
+
state: ctx.state || new Set<unknown>([Math.random()]),
|
63
|
+
});
|
64
|
+
}
|
65
|
+
|
66
|
+
type LogValueStateInternal = LogValueState & { readonly state: Set<unknown> };
|
67
|
+
|
68
|
+
function logValueInternal(val: LogValueArg, ctx: LogValueStateInternal): LogValue {
|
69
|
+
ctx = {
|
70
|
+
...ctx,
|
71
|
+
state: ctx.state || new Set<unknown>([Math.random()]),
|
72
|
+
} satisfies LogValueStateInternal;
|
54
73
|
switch (typeof val) {
|
55
74
|
case "function":
|
56
75
|
return new LogValue(val);
|
@@ -58,7 +77,7 @@ export function logValue(val: LogValueArg, state: Set<unknown> = new Set<unknown
|
|
58
77
|
try {
|
59
78
|
const ret = JSON.parse(val);
|
60
79
|
if (typeof ret === "object" && ret !== null) {
|
61
|
-
return
|
80
|
+
return logValueInternal(ret, ctx);
|
62
81
|
}
|
63
82
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
64
83
|
} catch (e) {
|
@@ -83,14 +102,16 @@ export function logValue(val: LogValueArg, state: Set<unknown> = new Set<unknown
|
|
83
102
|
const decoder = new TextDecoder();
|
84
103
|
const asStr = decoder.decode(val);
|
85
104
|
const obj = JSON.parse(asStr);
|
86
|
-
return
|
105
|
+
return logValueInternal(obj, ctx);
|
87
106
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
88
107
|
} catch (e) {
|
89
|
-
return
|
108
|
+
return logValueInternal(bin2string(val, 512), ctx);
|
90
109
|
}
|
91
110
|
}
|
92
111
|
if (Array.isArray(val)) {
|
93
|
-
return new LogValue(() =>
|
112
|
+
return new LogValue(() =>
|
113
|
+
(val as Serialized[]).map((v) => logValue(v, { ...ctx, state: undefined }).value() as Serialized),
|
114
|
+
);
|
94
115
|
}
|
95
116
|
// if (val instanceof Response) {
|
96
117
|
// // my = my.clone() as unknown as LogValue | Serialized[] | null
|
@@ -109,10 +130,10 @@ export function logValue(val: LogValueArg, state: Set<unknown> = new Set<unknown
|
|
109
130
|
}
|
110
131
|
|
111
132
|
// Duplicate reference found, discard key
|
112
|
-
if (state
|
133
|
+
if (ctx.state?.has(val)) {
|
113
134
|
return new LogValue(() => "...");
|
114
135
|
}
|
115
|
-
state
|
136
|
+
ctx.state?.add(val);
|
116
137
|
if (typeof val.toJSON === "function") {
|
117
138
|
return new LogValue(() => val.toJSON());
|
118
139
|
}
|
@@ -120,14 +141,16 @@ export function logValue(val: LogValueArg, state: Set<unknown> = new Set<unknown
|
|
120
141
|
const res: Record<string, LogValue> = {};
|
121
142
|
const typedVal = val as unknown as Record<string, LogValueArg>;
|
122
143
|
for (const key in typedVal) {
|
144
|
+
if (ctx.ignoreAttr.IsSome() && ctx.ignoreAttr.unwrap().test(key)) {
|
145
|
+
continue;
|
146
|
+
}
|
123
147
|
const element = typedVal[key];
|
124
148
|
if (element instanceof LogValue) {
|
125
149
|
res[key] = element;
|
126
150
|
} else {
|
127
151
|
if (typeof element !== "function") {
|
128
|
-
res[key] =
|
152
|
+
res[key] = logValueInternal(element, ctx);
|
129
153
|
}
|
130
|
-
// res[key] = logValue(element, state);
|
131
154
|
}
|
132
155
|
}
|
133
156
|
// ugly as hell cast but how declare a self-referencing type?
|
@@ -157,6 +180,8 @@ export interface LevelHandler {
|
|
157
180
|
enableLevel(level: Level, ...modules: string[]): void;
|
158
181
|
disableLevel(level: Level, ...modules: string[]): void;
|
159
182
|
setExposeStack(enable?: boolean): void;
|
183
|
+
setIgnoreAttr(re?: RegExp): void;
|
184
|
+
ignoreAttr: Option<RegExp>;
|
160
185
|
isStackExposed: boolean;
|
161
186
|
setDebug(...modules: (string | string[])[]): void;
|
162
187
|
isEnabled(ilevel: unknown, module: unknown): boolean;
|
@@ -165,6 +190,7 @@ export interface LevelHandler {
|
|
165
190
|
export type HttpType = Response | Result<Response> | Request | Result<Request>;
|
166
191
|
|
167
192
|
export interface LoggerInterface<R> {
|
193
|
+
readonly levelHandler: LevelHandler;
|
168
194
|
TxtEnDe(): TxtEnDecoder;
|
169
195
|
Module(key: string): R;
|
170
196
|
// if modules is empty, set for all Levels
|
@@ -174,6 +200,8 @@ export interface LoggerInterface<R> {
|
|
174
200
|
Attributes(): Record<string, unknown>;
|
175
201
|
|
176
202
|
SetDebug(...modules: (string | string[])[]): R;
|
203
|
+
// default is /^_/
|
204
|
+
SetIgnoreAttribute(re?: RegExp): R;
|
177
205
|
SetExposeStack(enable?: boolean): R;
|
178
206
|
SetFormatter(fmt: LogFormatter): R;
|
179
207
|
|
package/src/option.ts
CHANGED
package/src/result.ts
CHANGED
@@ -2,10 +2,16 @@ export abstract class Result<T, E = Error> {
|
|
2
2
|
static Ok<T = void>(t: T): Result<T, Error> {
|
3
3
|
return new ResultOK(t);
|
4
4
|
}
|
5
|
-
static Err<T, E extends Error = Error>(t: E | string): Result<T, E> {
|
5
|
+
static Err<T, E extends Error = Error>(t: E | string | Result<unknown, E>): Result<T, E> {
|
6
6
|
if (typeof t === "string") {
|
7
7
|
return new ResultError(new Error(t) as E);
|
8
8
|
}
|
9
|
+
if (Result.Is(t)) {
|
10
|
+
if (t.is_ok()) {
|
11
|
+
return new ResultError(new Error("Result Error is Ok") as E);
|
12
|
+
}
|
13
|
+
return t as Result<T, E>;
|
14
|
+
}
|
9
15
|
return new ResultError(t);
|
10
16
|
}
|
11
17
|
static Is<T>(t: unknown): t is Result<T> {
|