@logtape/file 0.9.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +43 -0
  3. package/esm/_dnt.shims.js +57 -0
  4. package/esm/file/filesink.base.js +78 -0
  5. package/esm/file/filesink.node.js +47 -0
  6. package/esm/file/mod.js +1 -0
  7. package/esm/logtape/config.js +287 -0
  8. package/esm/logtape/context.js +23 -0
  9. package/esm/logtape/filter.js +42 -0
  10. package/esm/logtape/formatter.js +261 -0
  11. package/esm/logtape/level.js +59 -0
  12. package/esm/logtape/logger.js +480 -0
  13. package/esm/logtape/mod.js +8 -0
  14. package/esm/logtape/nodeUtil.js +2 -0
  15. package/esm/logtape/record.js +1 -0
  16. package/esm/logtape/sink.js +96 -0
  17. package/esm/package.json +3 -0
  18. package/package.json +55 -0
  19. package/script/_dnt.shims.js +60 -0
  20. package/script/file/filesink.base.js +82 -0
  21. package/script/file/filesink.node.js +55 -0
  22. package/script/file/mod.js +6 -0
  23. package/script/logtape/config.js +321 -0
  24. package/script/logtape/context.js +26 -0
  25. package/script/logtape/filter.js +46 -0
  26. package/script/logtape/formatter.js +270 -0
  27. package/script/logtape/level.js +64 -0
  28. package/script/logtape/logger.js +511 -0
  29. package/script/logtape/mod.js +34 -0
  30. package/script/logtape/nodeUtil.js +7 -0
  31. package/script/logtape/record.js +2 -0
  32. package/script/logtape/sink.js +101 -0
  33. package/script/package.json +3 -0
  34. package/types/_dnt.shims.d.ts +2 -0
  35. package/types/_dnt.shims.d.ts.map +1 -0
  36. package/types/_dnt.test_shims.d.ts.map +1 -0
  37. package/types/deps/jsr.io/@david/which-runtime/0.2.1/mod.d.ts.map +1 -0
  38. package/types/deps/jsr.io/@std/assert/0.222.1/_constants.d.ts.map +1 -0
  39. package/types/deps/jsr.io/@std/assert/0.222.1/_diff.d.ts.map +1 -0
  40. package/types/deps/jsr.io/@std/assert/0.222.1/_format.d.ts.map +1 -0
  41. package/types/deps/jsr.io/@std/assert/0.222.1/assert_equals.d.ts.map +1 -0
  42. package/types/deps/jsr.io/@std/assert/0.222.1/assertion_error.d.ts.map +1 -0
  43. package/types/deps/jsr.io/@std/assert/0.222.1/equal.d.ts.map +1 -0
  44. package/types/deps/jsr.io/@std/fmt/0.222.1/colors.d.ts.map +1 -0
  45. package/types/deps/jsr.io/@std/path/1.0.8/_common/assert_path.d.ts.map +1 -0
  46. package/types/deps/jsr.io/@std/path/1.0.8/_common/constants.d.ts.map +1 -0
  47. package/types/deps/jsr.io/@std/path/1.0.8/_common/normalize.d.ts.map +1 -0
  48. package/types/deps/jsr.io/@std/path/1.0.8/_common/normalize_string.d.ts.map +1 -0
  49. package/types/deps/jsr.io/@std/path/1.0.8/_os.d.ts.map +1 -0
  50. package/types/deps/jsr.io/@std/path/1.0.8/join.d.ts.map +1 -0
  51. package/types/deps/jsr.io/@std/path/1.0.8/posix/_util.d.ts.map +1 -0
  52. package/types/deps/jsr.io/@std/path/1.0.8/posix/join.d.ts.map +1 -0
  53. package/types/deps/jsr.io/@std/path/1.0.8/posix/normalize.d.ts.map +1 -0
  54. package/types/deps/jsr.io/@std/path/1.0.8/windows/_util.d.ts.map +1 -0
  55. package/types/deps/jsr.io/@std/path/1.0.8/windows/join.d.ts.map +1 -0
  56. package/types/deps/jsr.io/@std/path/1.0.8/windows/normalize.d.ts.map +1 -0
  57. package/types/file/filesink.base.d.ts +89 -0
  58. package/types/file/filesink.base.d.ts.map +1 -0
  59. package/types/file/filesink.node.d.ts +34 -0
  60. package/types/file/filesink.node.d.ts.map +1 -0
  61. package/types/file/filesink.test.d.ts.map +1 -0
  62. package/types/file/mod.d.ts +3 -0
  63. package/types/file/mod.d.ts.map +1 -0
  64. package/types/logtape/config.d.ts +183 -0
  65. package/types/logtape/config.d.ts.map +1 -0
  66. package/types/logtape/context.d.ts +35 -0
  67. package/types/logtape/context.d.ts.map +1 -0
  68. package/types/logtape/filter.d.ts +31 -0
  69. package/types/logtape/filter.d.ts.map +1 -0
  70. package/types/logtape/fixtures.d.ts.map +1 -0
  71. package/types/logtape/formatter.d.ts +260 -0
  72. package/types/logtape/formatter.d.ts.map +1 -0
  73. package/types/logtape/level.d.ts +32 -0
  74. package/types/logtape/level.d.ts.map +1 -0
  75. package/types/logtape/logger.d.ts +423 -0
  76. package/types/logtape/logger.d.ts.map +1 -0
  77. package/types/logtape/mod.d.ts +9 -0
  78. package/types/logtape/mod.d.ts.map +1 -0
  79. package/types/logtape/nodeUtil.d.ts +3 -0
  80. package/types/logtape/nodeUtil.d.ts.map +1 -0
  81. package/types/logtape/record.d.ts +44 -0
  82. package/types/logtape/record.d.ts.map +1 -0
  83. package/types/logtape/sink.d.ts +108 -0
  84. package/types/logtape/sink.d.ts.map +1 -0
@@ -0,0 +1,260 @@
1
+ import type { LogLevel } from "./level.js";
2
+ import type { LogRecord } from "./record.js";
3
+ /**
4
+ * A text formatter is a function that accepts a log record and returns
5
+ * a string.
6
+ *
7
+ * @param record The log record to format.
8
+ * @returns The formatted log record.
9
+ */
10
+ export type TextFormatter = (record: LogRecord) => string;
11
+ /**
12
+ * The formatted values for a log record.
13
+ * @since 0.6.0
14
+ */
15
+ export interface FormattedValues {
16
+ /**
17
+ * The formatted timestamp.
18
+ */
19
+ timestamp: string;
20
+ /**
21
+ * The formatted log level.
22
+ */
23
+ level: string;
24
+ /**
25
+ * The formatted category.
26
+ */
27
+ category: string;
28
+ /**
29
+ * The formatted message.
30
+ */
31
+ message: string;
32
+ /**
33
+ * The unformatted log record.
34
+ */
35
+ record: LogRecord;
36
+ }
37
+ /**
38
+ * The various options for the built-in text formatters.
39
+ * @since 0.6.0
40
+ */
41
+ export interface TextFormatterOptions {
42
+ /**
43
+ * The timestamp format. This can be one of the following:
44
+ *
45
+ * - `"date-time-timezone"`: The date and time with the full timezone offset
46
+ * (e.g., `"2023-11-14 22:13:20.000 +00:00"`).
47
+ * - `"date-time-tz"`: The date and time with the short timezone offset
48
+ * (e.g., `"2023-11-14 22:13:20.000 +00"`).
49
+ * - `"date-time"`: The date and time without the timezone offset
50
+ * (e.g., `"2023-11-14 22:13:20.000"`).
51
+ * - `"time-timezone"`: The time with the full timezone offset but without
52
+ * the date (e.g., `"22:13:20.000 +00:00"`).
53
+ * - `"time-tz"`: The time with the short timezone offset but without the date
54
+ * (e.g., `"22:13:20.000 +00"`).
55
+ * - `"time"`: The time without the date or timezone offset
56
+ * (e.g., `"22:13:20.000"`).
57
+ * - `"date"`: The date without the time or timezone offset
58
+ * (e.g., `"2023-11-14"`).
59
+ * - `"rfc3339"`: The date and time in RFC 3339 format
60
+ * (e.g., `"2023-11-14T22:13:20.000Z"`).
61
+ *
62
+ * Alternatively, this can be a function that accepts a timestamp and returns
63
+ * a string.
64
+ *
65
+ * The default is `"date-time-timezone"`.
66
+ */
67
+ timestamp?: "date-time-timezone" | "date-time-tz" | "date-time" | "time-timezone" | "time-tz" | "time" | "date" | "rfc3339" | ((ts: number) => string);
68
+ /**
69
+ * The log level format. This can be one of the following:
70
+ *
71
+ * - `"ABBR"`: The log level abbreviation in uppercase (e.g., `"INF"`).
72
+ * - `"FULL"`: The full log level name in uppercase (e.g., `"INFO"`).
73
+ * - `"L"`: The first letter of the log level in uppercase (e.g., `"I"`).
74
+ * - `"abbr"`: The log level abbreviation in lowercase (e.g., `"inf"`).
75
+ * - `"full"`: The full log level name in lowercase (e.g., `"info"`).
76
+ * - `"l"`: The first letter of the log level in lowercase (e.g., `"i"`).
77
+ *
78
+ * Alternatively, this can be a function that accepts a log level and returns
79
+ * a string.
80
+ *
81
+ * The default is `"ABBR"`.
82
+ */
83
+ level?: "ABBR" | "FULL" | "L" | "abbr" | "full" | "l" | ((level: LogLevel) => string);
84
+ /**
85
+ * The separator between category names. For example, if the separator is
86
+ * `"·"`, the category `["a", "b", "c"]` will be formatted as `"a·b·c"`.
87
+ * The default separator is `"·"`.
88
+ *
89
+ * If this is a function, it will be called with the category array and
90
+ * should return a string, which will be used for rendering the category.
91
+ */
92
+ category?: string | ((category: readonly string[]) => string);
93
+ /**
94
+ * The format of the embedded values.
95
+ *
96
+ * A function that renders a value to a string. This function is used to
97
+ * render the values in the log record. The default is [`util.inspect()`] in
98
+ * Node.js/Bun and [`Deno.inspect()`] in Deno.
99
+ *
100
+ * [`util.inspect()`]: https://nodejs.org/api/util.html#utilinspectobject-options
101
+ * [`Deno.inspect()`]: https://docs.deno.com/api/deno/~/Deno.inspect
102
+ * @param value The value to render.
103
+ * @returns The string representation of the value.
104
+ */
105
+ value?: (value: unknown) => string;
106
+ /**
107
+ * How those formatted parts are concatenated.
108
+ *
109
+ * A function that formats the log record. This function is called with the
110
+ * formatted values and should return a string. Note that the formatted
111
+ * *should not* include a newline character at the end.
112
+ *
113
+ * By default, this is a function that formats the log record as follows:
114
+ *
115
+ * ```
116
+ * 2023-11-14 22:13:20.000 +00:00 [INF] category·subcategory: Hello, world!
117
+ * ```
118
+ * @param values The formatted values.
119
+ * @returns The formatted log record.
120
+ */
121
+ format?: (values: FormattedValues) => string;
122
+ }
123
+ /**
124
+ * Get a text formatter with the specified options. Although it's flexible
125
+ * enough to create a custom formatter, if you want more control, you can
126
+ * create a custom formatter that satisfies the {@link TextFormatter} type
127
+ * instead.
128
+ *
129
+ * For more information on the options, see {@link TextFormatterOptions}.
130
+ *
131
+ * By default, the formatter formats log records as follows:
132
+ *
133
+ * ```
134
+ * 2023-11-14 22:13:20.000 +00:00 [INF] category·subcategory: Hello, world!
135
+ * ```
136
+ * @param options The options for the text formatter.
137
+ * @returns The text formatter.
138
+ * @since 0.6.0
139
+ */
140
+ export declare function getTextFormatter(options?: TextFormatterOptions): TextFormatter;
141
+ /**
142
+ * The default text formatter. This formatter formats log records as follows:
143
+ *
144
+ * ```
145
+ * 2023-11-14 22:13:20.000 +00:00 [INF] category·subcategory: Hello, world!
146
+ * ```
147
+ *
148
+ * @param record The log record to format.
149
+ * @returns The formatted log record.
150
+ */
151
+ export declare const defaultTextFormatter: TextFormatter;
152
+ /**
153
+ * The ANSI colors. These can be used to colorize text in the console.
154
+ * @since 0.6.0
155
+ */
156
+ export type AnsiColor = "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white";
157
+ /**
158
+ * The ANSI text styles.
159
+ * @since 0.6.0
160
+ */
161
+ export type AnsiStyle = "bold" | "dim" | "italic" | "underline" | "strikethrough";
162
+ /**
163
+ * The various options for the ANSI color formatter.
164
+ * @since 0.6.0
165
+ */
166
+ export interface AnsiColorFormatterOptions extends TextFormatterOptions {
167
+ /**
168
+ * The timestamp format. This can be one of the following:
169
+ *
170
+ * - `"date-time-timezone"`: The date and time with the full timezone offset
171
+ * (e.g., `"2023-11-14 22:13:20.000 +00:00"`).
172
+ * - `"date-time-tz"`: The date and time with the short timezone offset
173
+ * (e.g., `"2023-11-14 22:13:20.000 +00"`).
174
+ * - `"date-time"`: The date and time without the timezone offset
175
+ * (e.g., `"2023-11-14 22:13:20.000"`).
176
+ * - `"time-timezone"`: The time with the full timezone offset but without
177
+ * the date (e.g., `"22:13:20.000 +00:00"`).
178
+ * - `"time-tz"`: The time with the short timezone offset but without the date
179
+ * (e.g., `"22:13:20.000 +00"`).
180
+ * - `"time"`: The time without the date or timezone offset
181
+ * (e.g., `"22:13:20.000"`).
182
+ * - `"date"`: The date without the time or timezone offset
183
+ * (e.g., `"2023-11-14"`).
184
+ * - `"rfc3339"`: The date and time in RFC 3339 format
185
+ * (e.g., `"2023-11-14T22:13:20.000Z"`).
186
+ *
187
+ * Alternatively, this can be a function that accepts a timestamp and returns
188
+ * a string.
189
+ *
190
+ * The default is `"date-time-tz"`.
191
+ */
192
+ timestamp?: "date-time-timezone" | "date-time-tz" | "date-time" | "time-timezone" | "time-tz" | "time" | "date" | "rfc3339" | ((ts: number) => string);
193
+ /**
194
+ * The ANSI style for the timestamp. `"dim"` is used by default.
195
+ */
196
+ timestampStyle?: AnsiStyle | null;
197
+ /**
198
+ * The ANSI color for the timestamp. No color is used by default.
199
+ */
200
+ timestampColor?: AnsiColor | null;
201
+ /**
202
+ * The ANSI style for the log level. `"bold"` is used by default.
203
+ */
204
+ levelStyle?: AnsiStyle | null;
205
+ /**
206
+ * The ANSI colors for the log levels. The default colors are as follows:
207
+ *
208
+ * - `"debug"`: `"blue"`
209
+ * - `"info"`: `"green"`
210
+ * - `"warning"`: `"yellow"`
211
+ * - `"error"`: `"red"`
212
+ * - `"fatal"`: `"magenta"`
213
+ */
214
+ levelColors?: Record<LogLevel, AnsiColor | null>;
215
+ /**
216
+ * The ANSI style for the category. `"dim"` is used by default.
217
+ */
218
+ categoryStyle?: AnsiStyle | null;
219
+ /**
220
+ * The ANSI color for the category. No color is used by default.
221
+ */
222
+ categoryColor?: AnsiColor | null;
223
+ }
224
+ /**
225
+ * Get an ANSI color formatter with the specified options.
226
+ *
227
+ * ![A preview of an ANSI color formatter.](https://i.imgur.com/I8LlBUf.png)
228
+ * @param option The options for the ANSI color formatter.
229
+ * @returns The ANSI color formatter.
230
+ * @since 0.6.0
231
+ */
232
+ export declare function getAnsiColorFormatter(options?: AnsiColorFormatterOptions): TextFormatter;
233
+ /**
234
+ * A text formatter that uses ANSI colors to format log records.
235
+ *
236
+ * ![A preview of ansiColorFormatter.](https://i.imgur.com/I8LlBUf.png)
237
+ *
238
+ * @param record The log record to format.
239
+ * @returns The formatted log record.
240
+ * @since 0.5.0
241
+ */
242
+ export declare const ansiColorFormatter: TextFormatter;
243
+ /**
244
+ * A console formatter is a function that accepts a log record and returns
245
+ * an array of arguments to pass to {@link console.log}.
246
+ *
247
+ * @param record The log record to format.
248
+ * @returns The formatted log record, as an array of arguments for
249
+ * {@link console.log}.
250
+ */
251
+ export type ConsoleFormatter = (record: LogRecord) => readonly unknown[];
252
+ /**
253
+ * The default console formatter.
254
+ *
255
+ * @param record The log record to format.
256
+ * @returns The formatted log record, as an array of arguments for
257
+ * {@link console.log}.
258
+ */
259
+ export declare function defaultConsoleFormatter(record: LogRecord): readonly unknown[];
260
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/logtape/formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ declare const logLevels: readonly ["debug", "info", "warning", "error", "fatal"];
2
+ /**
3
+ * The severity level of a {@link LogRecord}.
4
+ */
5
+ export type LogLevel = typeof logLevels[number];
6
+ /**
7
+ * Parses a log level from a string.
8
+ *
9
+ * @param level The log level as a string. This is case-insensitive.
10
+ * @returns The log level.
11
+ * @throws {TypeError} If the log level is invalid.
12
+ */
13
+ export declare function parseLogLevel(level: string): LogLevel;
14
+ /**
15
+ * Checks if a string is a valid log level. This function can be used as
16
+ * as a type guard to narrow the type of a string to a {@link LogLevel}.
17
+ *
18
+ * @param level The log level as a string. This is case-sensitive.
19
+ * @returns `true` if the string is a valid log level.
20
+ */
21
+ export declare function isLogLevel(level: string): level is LogLevel;
22
+ /**
23
+ * Compares two log levels.
24
+ * @param a The first log level.
25
+ * @param b The second log level.
26
+ * @returns A negative number if `a` is less than `b`, a positive number if `a`
27
+ * is greater than `b`, or zero if they are equal.
28
+ * @since 0.8.0
29
+ */
30
+ export declare function compareLogLevel(a: LogLevel, b: LogLevel): number;
31
+ export {};
32
+ //# sourceMappingURL=level.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"level.d.ts","sourceRoot":"","sources":["../../src/logtape/level.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,SAAS,yDAA0D,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAYrD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,QAAQ,CAW3D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAUhE"}