@logtape/logtape 1.1.4 → 1.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/logtape",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "Simple logging library with zero dependencies for Deno/Node.js/Bun/browsers",
5
5
  "keywords": [
6
6
  "logging",
@@ -65,6 +65,9 @@
65
65
  }
66
66
  },
67
67
  "sideEffects": false,
68
+ "files": [
69
+ "dist/"
70
+ ],
68
71
  "devDependencies": {
69
72
  "@alinea/suite": "^0.6.3",
70
73
  "@std/assert": "npm:@jsr/std__assert@^1.0.13",
package/deno.json DELETED
@@ -1,36 +0,0 @@
1
- {
2
- "name": "@logtape/logtape",
3
- "version": "1.1.4",
4
- "license": "MIT",
5
- "exports": "./src/mod.ts",
6
- "imports": {
7
- "#util": "./src/util.ts"
8
- },
9
- "exclude": [
10
- "dist/",
11
- "npm/"
12
- ],
13
- "tasks": {
14
- "build": "pnpm build",
15
- "test": "deno test",
16
- "test:node": {
17
- "dependencies": [
18
- "build"
19
- ],
20
- "command": "node --experimental-transform-types --test"
21
- },
22
- "test:bun": {
23
- "dependencies": [
24
- "build"
25
- ],
26
- "command": "bun test"
27
- },
28
- "test-all": {
29
- "dependencies": [
30
- "test",
31
- "test:node",
32
- "test:bun"
33
- ]
34
- }
35
- }
36
- }
@@ -1,589 +0,0 @@
1
- import { suite } from "@alinea/suite";
2
- import { assertEquals } from "@std/assert/equals";
3
- import { assertRejects } from "@std/assert/rejects";
4
- import { assertStrictEquals } from "@std/assert/strict-equals";
5
- import { assertThrows } from "@std/assert/throws";
6
- import {
7
- type Config,
8
- ConfigError,
9
- configure,
10
- configureSync,
11
- getConfig,
12
- reset,
13
- resetSync,
14
- } from "./config.ts";
15
- import type { Filter } from "./filter.ts";
16
- import { getLogger, LoggerImpl } from "./logger.ts";
17
- import type { LogRecord } from "./record.ts";
18
- import type { Sink } from "./sink.ts";
19
-
20
- const test = suite(import.meta);
21
-
22
- test("configure()", async () => {
23
- let disposed = 0;
24
-
25
- try {
26
- const aLogs: LogRecord[] = [];
27
- const a: Sink & AsyncDisposable = (record) => aLogs.push(record);
28
- a[Symbol.asyncDispose] = () => {
29
- ++disposed;
30
- return Promise.resolve();
31
- };
32
- const bLogs: LogRecord[] = [];
33
- const b: Sink & Disposable = (record) => bLogs.push(record);
34
- b[Symbol.dispose] = () => ++disposed;
35
- const cLogs: LogRecord[] = [];
36
- const c: Sink = cLogs.push.bind(cLogs);
37
- const x: Filter & AsyncDisposable = () => true;
38
- x[Symbol.asyncDispose] = () => {
39
- ++disposed;
40
- return Promise.resolve();
41
- };
42
- const y: Filter & Disposable = () => true;
43
- y[Symbol.dispose] = () => ++disposed;
44
- const config: Config<string, string> = {
45
- sinks: { a, b, c },
46
- filters: { x, y, debug: "debug" },
47
- loggers: [
48
- {
49
- category: "my-app",
50
- sinks: ["a"],
51
- filters: ["x"],
52
- },
53
- {
54
- category: ["my-app", "foo"],
55
- sinks: ["b"],
56
- parentSinks: "override",
57
- filters: ["y"],
58
- },
59
- {
60
- category: ["my-app", "bar"],
61
- sinks: ["c"],
62
- filters: ["debug"],
63
- lowestLevel: "info",
64
- },
65
- ],
66
- };
67
- await configure(config);
68
-
69
- const logger = LoggerImpl.getLogger("my-app");
70
- assertEquals(logger.sinks, [a]);
71
- assertEquals(logger.filters, [x]);
72
- assertEquals(logger.lowestLevel, "trace");
73
- const foo = LoggerImpl.getLogger(["my-app", "foo"]);
74
- assertEquals(foo.sinks, [b]);
75
- assertEquals(foo.filters, [y]);
76
- assertEquals(foo.lowestLevel, "trace");
77
- const bar = LoggerImpl.getLogger(["my-app", "bar"]);
78
- assertEquals(bar.sinks, [c]);
79
- assertEquals(bar.lowestLevel, "info");
80
- bar.debug("ignored");
81
- assertEquals(aLogs, []);
82
- assertEquals(bLogs, []);
83
- assertEquals(cLogs, []);
84
- foo.warn("logged");
85
- assertEquals(aLogs, []);
86
- assertEquals(bLogs, [
87
- {
88
- level: "warning",
89
- category: ["my-app", "foo"],
90
- message: ["logged"],
91
- rawMessage: "logged",
92
- properties: {},
93
- timestamp: bLogs[0].timestamp,
94
- },
95
- ]);
96
- assertEquals(cLogs, []);
97
- bar.info("logged");
98
- assertEquals(aLogs, [
99
- {
100
- level: "info",
101
- category: ["my-app", "bar"],
102
- message: ["logged"],
103
- rawMessage: "logged",
104
- properties: {},
105
- timestamp: cLogs[0].timestamp,
106
- },
107
- ]);
108
- assertEquals(bLogs, [
109
- {
110
- level: "warning",
111
- category: ["my-app", "foo"],
112
- message: ["logged"],
113
- rawMessage: "logged",
114
- properties: {},
115
- timestamp: bLogs[0].timestamp,
116
- },
117
- ]);
118
- assertEquals(cLogs, [
119
- {
120
- level: "info",
121
- category: ["my-app", "bar"],
122
- message: ["logged"],
123
- rawMessage: "logged",
124
- properties: {},
125
- timestamp: cLogs[0].timestamp,
126
- },
127
- ]);
128
- assertStrictEquals(getConfig(), config);
129
-
130
- // reconfigure
131
- await assertRejects(
132
- () =>
133
- configure({
134
- sinks: {},
135
- loggers: [{ category: "my-app" }],
136
- }),
137
- ConfigError,
138
- "Already configured",
139
- );
140
- assertEquals(disposed, 0);
141
-
142
- // No exception if reset is true:
143
- const config2 = {
144
- sinks: {},
145
- loggers: [{ category: "my-app" }],
146
- reset: true,
147
- };
148
- await configure(config2);
149
- assertEquals(disposed, 4);
150
- assertStrictEquals(getConfig(), config2);
151
- } finally {
152
- await reset();
153
- assertStrictEquals(getConfig(), null);
154
- }
155
-
156
- try { // lowestLevel
157
- const a: LogRecord[] = [];
158
- const b: LogRecord[] = [];
159
- const c: LogRecord[] = [];
160
- await configure({
161
- sinks: {
162
- a: a.push.bind(a),
163
- b: b.push.bind(b),
164
- c: c.push.bind(c),
165
- },
166
- loggers: [
167
- { category: "foo", sinks: ["a"], lowestLevel: "info" },
168
- { category: ["foo", "bar"], sinks: ["b"], lowestLevel: "warning" },
169
- { category: ["foo", "baz"], sinks: ["c"], lowestLevel: "debug" },
170
- { category: ["logtape", "meta"], sinks: [] },
171
- ],
172
- });
173
-
174
- getLogger(["foo", "bar"]).warn("test");
175
- assertEquals(a.length, 1);
176
- assertEquals(b.length, 1);
177
-
178
- while (a.length > 0) a.pop();
179
- while (b.length > 0) b.pop();
180
-
181
- getLogger(["foo", "baz"]).debug("test");
182
- assertEquals(a.length, 0);
183
- assertEquals(c.length, 1);
184
-
185
- while (a.length > 0) a.pop();
186
- while (c.length > 0) c.pop();
187
- } finally {
188
- await reset();
189
- assertStrictEquals(getConfig(), null);
190
- }
191
-
192
- { // misconfiguration
193
- await assertRejects(
194
- () =>
195
- configure({
196
- // deno-lint-ignore no-explicit-any
197
- sinks: {} as any,
198
- loggers: [
199
- {
200
- category: "my-app",
201
- sinks: ["invalid"],
202
- },
203
- ],
204
- reset: true,
205
- }),
206
- ConfigError,
207
- "Sink not found: invalid",
208
- );
209
- assertStrictEquals(getConfig(), null);
210
-
211
- await assertRejects(
212
- () =>
213
- configure({
214
- sinks: {},
215
- // deno-lint-ignore no-explicit-any
216
- filters: {} as any,
217
- loggers: [
218
- {
219
- category: "my-app",
220
- filters: ["invalid"],
221
- },
222
- ],
223
- reset: true,
224
- }),
225
- ConfigError,
226
- "Filter not found: invalid",
227
- );
228
- assertStrictEquals(getConfig(), null);
229
- }
230
-
231
- { // duplicate logger categories
232
- await assertRejects(
233
- () =>
234
- configure({
235
- sinks: {},
236
- loggers: [
237
- {
238
- category: "my-app",
239
- lowestLevel: "info",
240
- },
241
- {
242
- category: ["my-app"],
243
- lowestLevel: "warning",
244
- },
245
- ],
246
- reset: true,
247
- }),
248
- ConfigError,
249
- 'Duplicate logger configuration for category: ["my-app"]',
250
- );
251
- assertStrictEquals(getConfig(), null);
252
-
253
- await assertRejects(
254
- () =>
255
- configure({
256
- sinks: {},
257
- loggers: [
258
- {
259
- category: ["my-app", "service"],
260
- lowestLevel: "info",
261
- },
262
- {
263
- category: ["my-app", "service"],
264
- lowestLevel: "warning",
265
- },
266
- ],
267
- reset: true,
268
- }),
269
- ConfigError,
270
- 'Duplicate logger configuration for category: ["my-app","service"]',
271
- );
272
- assertStrictEquals(getConfig(), null);
273
- }
274
-
275
- const metaCategories = [[], ["logtape"], ["logtape", "meta"]];
276
- for (const metaCategory of metaCategories) {
277
- try { // meta configuration
278
- const config = {
279
- sinks: {},
280
- loggers: [
281
- {
282
- category: metaCategory,
283
- sinks: [],
284
- filters: [],
285
- },
286
- ],
287
- };
288
- await configure(config);
289
-
290
- assertEquals(LoggerImpl.getLogger(["logger", "meta"]).sinks, []);
291
- assertStrictEquals(getConfig(), config);
292
- } finally {
293
- await reset();
294
- assertStrictEquals(getConfig(), null);
295
- }
296
- }
297
- });
298
-
299
- test("configureSync()", async () => {
300
- let disposed = 0;
301
-
302
- try {
303
- const bLogs: LogRecord[] = [];
304
- const b: Sink & Disposable = (record) => bLogs.push(record);
305
- b[Symbol.dispose] = () => ++disposed;
306
- const cLogs: LogRecord[] = [];
307
- const c: Sink = cLogs.push.bind(cLogs);
308
- const y: Filter & Disposable = () => true;
309
- y[Symbol.dispose] = () => ++disposed;
310
- const config: Config<string, string> = {
311
- sinks: { b, c },
312
- filters: { y, debug: "debug" },
313
- loggers: [
314
- {
315
- category: ["my-app", "foo"],
316
- sinks: ["b"],
317
- parentSinks: "override",
318
- filters: ["y"],
319
- },
320
- {
321
- category: ["my-app", "bar"],
322
- sinks: ["c"],
323
- filters: ["debug"],
324
- lowestLevel: "info",
325
- },
326
- ],
327
- };
328
- configureSync(config);
329
-
330
- const foo = LoggerImpl.getLogger(["my-app", "foo"]);
331
- assertEquals(foo.sinks, [b]);
332
- assertEquals(foo.filters, [y]);
333
- assertEquals(foo.lowestLevel, "trace");
334
- const bar = LoggerImpl.getLogger(["my-app", "bar"]);
335
- assertEquals(bar.sinks, [c]);
336
- assertEquals(bar.lowestLevel, "info");
337
- bar.debug("ignored");
338
- assertEquals(bLogs, []);
339
- assertEquals(cLogs, []);
340
- foo.warn("logged");
341
- assertEquals(bLogs, [
342
- {
343
- level: "warning",
344
- category: ["my-app", "foo"],
345
- message: ["logged"],
346
- rawMessage: "logged",
347
- properties: {},
348
- timestamp: bLogs[0].timestamp,
349
- },
350
- ]);
351
- assertEquals(cLogs, []);
352
- bar.info("logged");
353
- assertEquals(bLogs, [
354
- {
355
- level: "warning",
356
- category: ["my-app", "foo"],
357
- message: ["logged"],
358
- rawMessage: "logged",
359
- properties: {},
360
- timestamp: bLogs[0].timestamp,
361
- },
362
- ]);
363
- assertEquals(cLogs, [
364
- {
365
- level: "info",
366
- category: ["my-app", "bar"],
367
- message: ["logged"],
368
- rawMessage: "logged",
369
- properties: {},
370
- timestamp: cLogs[0].timestamp,
371
- },
372
- ]);
373
- assertStrictEquals(getConfig(), config);
374
-
375
- // reconfigure
376
- assertThrows(
377
- () =>
378
- configureSync({
379
- sinks: {},
380
- loggers: [{ category: "my-app" }],
381
- }),
382
- ConfigError,
383
- "Already configured",
384
- );
385
- assertEquals(disposed, 0);
386
-
387
- // No exception if reset is true:
388
- const config2 = {
389
- sinks: {},
390
- loggers: [{ category: "my-app" }],
391
- reset: true,
392
- };
393
- configureSync(config2);
394
- assertEquals(disposed, 2);
395
- assertStrictEquals(getConfig(), config2);
396
- } finally {
397
- resetSync();
398
- assertStrictEquals(getConfig(), null);
399
- }
400
-
401
- { // misconfiguration
402
- assertThrows(
403
- () =>
404
- configureSync({
405
- // deno-lint-ignore no-explicit-any
406
- sinks: {} as any,
407
- loggers: [
408
- {
409
- category: "my-app",
410
- sinks: ["invalid"],
411
- },
412
- ],
413
- reset: true,
414
- }),
415
- ConfigError,
416
- "Sink not found: invalid",
417
- );
418
- assertStrictEquals(getConfig(), null);
419
-
420
- assertThrows(
421
- () =>
422
- configureSync({
423
- sinks: {},
424
- // deno-lint-ignore no-explicit-any
425
- filters: {} as any,
426
- loggers: [
427
- {
428
- category: "my-app",
429
- filters: ["invalid"],
430
- },
431
- ],
432
- reset: true,
433
- }),
434
- ConfigError,
435
- "Filter not found: invalid",
436
- );
437
- assertStrictEquals(getConfig(), null);
438
- }
439
-
440
- { // duplicate logger categories
441
- assertThrows(
442
- () =>
443
- configureSync({
444
- sinks: {},
445
- loggers: [
446
- {
447
- category: ["my-app"],
448
- lowestLevel: "info",
449
- },
450
- {
451
- category: "my-app",
452
- lowestLevel: "warning",
453
- },
454
- ],
455
- reset: true,
456
- }),
457
- ConfigError,
458
- 'Duplicate logger configuration for category: ["my-app"]',
459
- );
460
- assertStrictEquals(getConfig(), null);
461
-
462
- assertThrows(
463
- () =>
464
- configureSync({
465
- sinks: {},
466
- loggers: [
467
- {
468
- category: ["my-app", "service"],
469
- lowestLevel: "info",
470
- },
471
- {
472
- category: ["my-app", "service"],
473
- lowestLevel: "warning",
474
- },
475
- ],
476
- reset: true,
477
- }),
478
- ConfigError,
479
- 'Duplicate logger configuration for category: ["my-app","service"]',
480
- );
481
- assertStrictEquals(getConfig(), null);
482
- }
483
-
484
- const metaCategories = [[], ["logtape"], ["logtape", "meta"]];
485
- for (const metaCategory of metaCategories) {
486
- try { // meta configuration
487
- const config = {
488
- sinks: {},
489
- loggers: [
490
- {
491
- category: metaCategory,
492
- sinks: [],
493
- filters: [],
494
- },
495
- ],
496
- };
497
- configureSync(config);
498
-
499
- assertEquals(LoggerImpl.getLogger(["logger", "meta"]).sinks, []);
500
- assertStrictEquals(getConfig(), config);
501
- } finally {
502
- resetSync();
503
- assertStrictEquals(getConfig(), null);
504
- }
505
- }
506
-
507
- { // no async sinks
508
- const aLogs: LogRecord[] = [];
509
- const a: Sink & AsyncDisposable = (record) => aLogs.push(record);
510
- a[Symbol.asyncDispose] = () => {
511
- return Promise.resolve();
512
- };
513
- const config: Config<string, string> = {
514
- sinks: { a },
515
- loggers: [
516
- {
517
- category: "my-app",
518
- sinks: ["a"],
519
- },
520
- ],
521
- };
522
-
523
- assertThrows(
524
- () => configureSync(config),
525
- ConfigError,
526
- "Async disposables cannot be used with configureSync()",
527
- );
528
- assertStrictEquals(getConfig(), null);
529
- }
530
-
531
- { // no async filters
532
- const aLogs: LogRecord[] = [];
533
- const a: Sink & Disposable = (record) => aLogs.push(record);
534
- a[Symbol.dispose] = () => ++disposed;
535
- const x: Filter & AsyncDisposable = () => true;
536
- x[Symbol.asyncDispose] = () => {
537
- ++disposed;
538
- return Promise.resolve();
539
- };
540
- const config: Config<string, string> = {
541
- sinks: { a },
542
- filters: { x },
543
- loggers: [
544
- {
545
- category: "my-app",
546
- sinks: ["a"],
547
- filters: ["x"],
548
- },
549
- ],
550
- };
551
-
552
- assertThrows(
553
- () => configureSync(config),
554
- ConfigError,
555
- "Async disposables cannot be used with configureSync()",
556
- );
557
- assertStrictEquals(getConfig(), null);
558
- }
559
-
560
- try { // cannot reset async disposables
561
- const aLogs: LogRecord[] = [];
562
- const a: Sink & AsyncDisposable = (record) => aLogs.push(record);
563
- a[Symbol.asyncDispose] = () => {
564
- ++disposed;
565
- return Promise.resolve();
566
- };
567
- await configure({
568
- sinks: { a },
569
- loggers: [{ category: "my-app", sinks: ["a"] }],
570
- });
571
- assertThrows(
572
- () =>
573
- configureSync({
574
- sinks: {
575
- a(record) {
576
- aLogs.push(record);
577
- },
578
- },
579
- loggers: [{ category: "my-app", sinks: ["a"] }],
580
- reset: true,
581
- }),
582
- ConfigError,
583
- "Previously configured async disposables are still active",
584
- );
585
- } finally {
586
- await reset();
587
- assertStrictEquals(getConfig(), null);
588
- }
589
- });