@bjoernboss/mws 1.0.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/LICENSE.txt +29 -0
- package/README.md +301 -0
- package/dist/base.d.ts +198 -0
- package/dist/base.js +73 -0
- package/dist/builder.d.ts +58 -0
- package/dist/builder.js +146 -0
- package/dist/cache.d.ts +66 -0
- package/dist/cache.js +708 -0
- package/dist/client.d.ts +228 -0
- package/dist/client.js +1646 -0
- package/dist/handler.d.ts +119 -0
- package/dist/handler.js +542 -0
- package/dist/helper.d.ts +33 -0
- package/dist/helper.js +363 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +12 -0
- package/dist/log.d.ts +52 -0
- package/dist/log.js +288 -0
- package/dist/server.d.ts +66 -0
- package/dist/server.js +257 -0
- package/package.json +46 -0
package/dist/helper.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: BSD-3-Clause */
|
|
2
|
+
/* Copyright (c) 2026 Bjoern Boss Henrichsen */
|
|
3
|
+
import * as libBase from "./base.js";
|
|
4
|
+
import * as libLog from "./log.js";
|
|
5
|
+
import * as libUrl from "url";
|
|
6
|
+
import * as libPath from "path";
|
|
7
|
+
const helperLogger = libLog.createLogger('helper');
|
|
8
|
+
/* setup the reverse list of file-endings to media types and encoding-names to encoding types */
|
|
9
|
+
const FileEndingToMediaTypeMapping = {};
|
|
10
|
+
const EncodingNameToEncodingTypeMapping = {};
|
|
11
|
+
for (const media of Object.values(libBase.Media)) {
|
|
12
|
+
for (const fileEnding of media.fileEnding)
|
|
13
|
+
FileEndingToMediaTypeMapping[fileEnding] = media;
|
|
14
|
+
}
|
|
15
|
+
for (const encoding of Object.values(libBase.Encoding))
|
|
16
|
+
EncodingNameToEncodingTypeMapping[encoding.name] = encoding;
|
|
17
|
+
/* lookup the encoding for a given name */
|
|
18
|
+
export function lookupEncoding(name) {
|
|
19
|
+
return EncodingNameToEncodingTypeMapping[name.toLowerCase()] ?? null;
|
|
20
|
+
}
|
|
21
|
+
/* list of all supported encodings */
|
|
22
|
+
export function supportedEncodingNames() {
|
|
23
|
+
return Object.keys(EncodingNameToEncodingTypeMapping);
|
|
24
|
+
}
|
|
25
|
+
/* map extension of file-path/file-name to media type (null if no match was found) */
|
|
26
|
+
export function lookupMediaTypeFromFile(filePath) {
|
|
27
|
+
const fileExtension = splitFilePath(filePath)[2];
|
|
28
|
+
if (fileExtension != '') {
|
|
29
|
+
const type = FileEndingToMediaTypeMapping[fileExtension.substring(1).toLowerCase()] ?? null;
|
|
30
|
+
if (type != null)
|
|
31
|
+
return type;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/* format the media type to the proper http header identifier */
|
|
36
|
+
export function buildMediaTypeIdentifier(media) {
|
|
37
|
+
if (media.encoding == '')
|
|
38
|
+
return media.mediaType;
|
|
39
|
+
return `${media.mediaType}; ${media.encoding}`;
|
|
40
|
+
}
|
|
41
|
+
/* does not respect 'no-identity' encoding requests; unknown at-least-size is considered valid (defaults 'identity' to null) */
|
|
42
|
+
export function negotiateEncoding(accept, atLeastSize, media) {
|
|
43
|
+
if (!media.compressible || accept == null)
|
|
44
|
+
return null;
|
|
45
|
+
if (atLeastSize != null && atLeastSize < libBase.MIN_ENCODING_SIZE)
|
|
46
|
+
return null;
|
|
47
|
+
/* parse the encoding types and their score */
|
|
48
|
+
const scores = {};
|
|
49
|
+
let bestScore = null;
|
|
50
|
+
for (const part of splitAndTrimList(accept, ',', false)) {
|
|
51
|
+
const segments = splitAndTrimList(part, ';', false);
|
|
52
|
+
const name = segments[0].toLowerCase();
|
|
53
|
+
/* check if the name is even supported and otherwise drop it */
|
|
54
|
+
if (!(name in EncodingNameToEncodingTypeMapping) && name != '*')
|
|
55
|
+
continue;
|
|
56
|
+
/* parse the weight score of the value but default to 1.0 if none was given (ignore any with invalid quality) */
|
|
57
|
+
let score = 1.0;
|
|
58
|
+
for (let i = 1; i < segments.length; ++i) {
|
|
59
|
+
const match = segments[i].match(/^\s*q\s*=\s*(\d+\.?\d*)\s*$/i);
|
|
60
|
+
if (match != null) {
|
|
61
|
+
score = parseFloat(match[1]);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (score < 0 || score > 1)
|
|
66
|
+
continue;
|
|
67
|
+
/* update the scores and best match */
|
|
68
|
+
scores[name] = (name in scores ? Math.max(scores[name], score) : score);
|
|
69
|
+
if (bestScore == null || scores[bestScore] < score)
|
|
70
|
+
bestScore = name;
|
|
71
|
+
else if (scores[bestScore] == score && (bestScore == name || bestScore == 'identity' || (bestScore == '*' && name != 'identity')))
|
|
72
|
+
bestScore = name;
|
|
73
|
+
}
|
|
74
|
+
/* check if a best-match has been found */
|
|
75
|
+
if (bestScore == null || scores[bestScore] <= 0)
|
|
76
|
+
return null;
|
|
77
|
+
if (bestScore != null && bestScore != '*')
|
|
78
|
+
return (bestScore == 'identity' ? null : EncodingNameToEncodingTypeMapping[bestScore]);
|
|
79
|
+
/* lookup the best entry not mentioned (because '*' was the best match) */
|
|
80
|
+
for (const encoding in EncodingNameToEncodingTypeMapping) {
|
|
81
|
+
if (!(encoding in scores))
|
|
82
|
+
return EncodingNameToEncodingTypeMapping[encoding];
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
export var RangeState;
|
|
87
|
+
(function (RangeState) {
|
|
88
|
+
RangeState[RangeState["noRange"] = 0] = "noRange";
|
|
89
|
+
RangeState[RangeState["valid"] = 1] = "valid";
|
|
90
|
+
RangeState[RangeState["issue"] = 2] = "issue";
|
|
91
|
+
RangeState[RangeState["malformed"] = 3] = "malformed";
|
|
92
|
+
})(RangeState || (RangeState = {}));
|
|
93
|
+
/* parse an http header range request (first and last are correct for all valid range states; will be [0,-1] for an emtpy file) */
|
|
94
|
+
export function parseRangeHeader(range, fileSize) {
|
|
95
|
+
if (range == null)
|
|
96
|
+
return { first: 0, last: fileSize - 1, state: RangeState.noRange };
|
|
97
|
+
/* ignore unknown range units (range units are case-insensitive) */
|
|
98
|
+
if (range.length < 6 || range.substring(0, 6).toLowerCase() != 'bytes=')
|
|
99
|
+
return { first: 0, last: fileSize - 1, state: RangeState.noRange };
|
|
100
|
+
range = range.substring(6);
|
|
101
|
+
/* extract the first number */
|
|
102
|
+
let numberLength = 0, firstNumber = '', lastNumber = '';
|
|
103
|
+
while (numberLength < range.length && (range[numberLength] >= '0' && range[numberLength] <= '9'))
|
|
104
|
+
++numberLength;
|
|
105
|
+
firstNumber = range.substring(0, numberLength);
|
|
106
|
+
range = range.substring(numberLength);
|
|
107
|
+
/* check if the separator exists */
|
|
108
|
+
if (!range.startsWith('-'))
|
|
109
|
+
return { first: 0, last: 0, state: RangeState.malformed };
|
|
110
|
+
range = range.substring(1);
|
|
111
|
+
/* extract the second number */
|
|
112
|
+
numberLength = 0;
|
|
113
|
+
while (numberLength < range.length && (range[numberLength] >= '0' && range[numberLength] <= '9'))
|
|
114
|
+
++numberLength;
|
|
115
|
+
lastNumber = range.substring(0, numberLength);
|
|
116
|
+
range = range.substring(numberLength).trimStart();
|
|
117
|
+
/* check if a valid end has been found or another range (only the first
|
|
118
|
+
* range will be respected) and that at least one number has been given */
|
|
119
|
+
if (range != '' && !range.startsWith(','))
|
|
120
|
+
return { first: 0, last: 0, state: RangeState.malformed };
|
|
121
|
+
if (firstNumber == '' && lastNumber == '')
|
|
122
|
+
return { first: 0, last: 0, state: RangeState.malformed };
|
|
123
|
+
/* parse the two numbers */
|
|
124
|
+
let first = (firstNumber.length == 0 ? null : parseInt(firstNumber));
|
|
125
|
+
let last = (lastNumber.length == 0 ? null : parseInt(lastNumber));
|
|
126
|
+
/* check if the range has an offset and potentially also an end */
|
|
127
|
+
if (first != null) {
|
|
128
|
+
if (last == null)
|
|
129
|
+
last = fileSize - 1;
|
|
130
|
+
if (first > last || last >= fileSize)
|
|
131
|
+
return { first: 0, last: 0, state: RangeState.issue };
|
|
132
|
+
return { first, last, state: RangeState.valid };
|
|
133
|
+
}
|
|
134
|
+
/* validate the offset at the end */
|
|
135
|
+
if (last > fileSize || last == 0)
|
|
136
|
+
return { first: 0, last: 0, state: RangeState.issue };
|
|
137
|
+
return { first: fileSize - last, last: fileSize - 1, state: RangeState.valid };
|
|
138
|
+
}
|
|
139
|
+
/* check if the [etag] matches the list (i.e. in list or list is '*'), will not match for undefined list; if [strong]
|
|
140
|
+
* comparison, both must be non-weak, opaque-tags equal (strip W/ prefix and compare opaque-tags regardless of weakness) */
|
|
141
|
+
export function etagMatchesList(etag, header, strong) {
|
|
142
|
+
if (header == null)
|
|
143
|
+
return false;
|
|
144
|
+
const list = splitAndTrimList(header, ',', true);
|
|
145
|
+
if (list.length == 1 && list[0] == '*')
|
|
146
|
+
return true;
|
|
147
|
+
if (strong && etag.startsWith('W/'))
|
|
148
|
+
return false;
|
|
149
|
+
const target = etag.startsWith('W/') ? etag.substring(2) : etag;
|
|
150
|
+
for (const entry of list) {
|
|
151
|
+
const current = ((strong || !entry.startsWith('W/')) ? entry : entry.substring(2));
|
|
152
|
+
if (target == current)
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
/* returns null on invalid times, [>0] for a being greater, [<0] for a being smaller, [=0] for same time */
|
|
158
|
+
export function timestampCompare(a, b) {
|
|
159
|
+
const _a = new Date(a).getTime();
|
|
160
|
+
if (isNaN(_a))
|
|
161
|
+
return null;
|
|
162
|
+
const _b = new Date(b).getTime();
|
|
163
|
+
if (isNaN(_b))
|
|
164
|
+
return null;
|
|
165
|
+
return (_a - _b);
|
|
166
|
+
}
|
|
167
|
+
/* split a list value while removing whitespace and optionally respecting quotes (returns empty list on validly quoted strings) */
|
|
168
|
+
export function splitAndTrimList(content, separator, quotesAware) {
|
|
169
|
+
if (content == null)
|
|
170
|
+
return [];
|
|
171
|
+
let output = [], current = '', inQuote = false;
|
|
172
|
+
for (const c of content) {
|
|
173
|
+
if (c == '"' && quotesAware)
|
|
174
|
+
inQuote = !inQuote, current += c;
|
|
175
|
+
else if (c != separator || inQuote)
|
|
176
|
+
current += c;
|
|
177
|
+
else
|
|
178
|
+
output.push(current.trim()), current = '';
|
|
179
|
+
}
|
|
180
|
+
if (inQuote)
|
|
181
|
+
return [];
|
|
182
|
+
output.push(current.trim());
|
|
183
|
+
return output;
|
|
184
|
+
}
|
|
185
|
+
/* escape all html-special characters to prevent injection when embedding untrusted values */
|
|
186
|
+
export function escapeHtml(content) {
|
|
187
|
+
let out = '';
|
|
188
|
+
for (let i = 0; i < content.length; ++i) {
|
|
189
|
+
switch (content[i]) {
|
|
190
|
+
case '&':
|
|
191
|
+
out += '&';
|
|
192
|
+
break;
|
|
193
|
+
case '<':
|
|
194
|
+
out += '<';
|
|
195
|
+
break;
|
|
196
|
+
case '>':
|
|
197
|
+
out += '>';
|
|
198
|
+
break;
|
|
199
|
+
case '"':
|
|
200
|
+
out += '"';
|
|
201
|
+
break;
|
|
202
|
+
case '\'':
|
|
203
|
+
out += ''';
|
|
204
|
+
break;
|
|
205
|
+
default:
|
|
206
|
+
out += content[i];
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
/* expand the placeholders in the content (format: {#name}, with '{#' being escaped as '{##'; optionally html-escape values) */
|
|
213
|
+
export function expandPlaceholders(content, args, htmlEscape) {
|
|
214
|
+
let out = '', name = '', placeholder = false;
|
|
215
|
+
for (let i = 0; i < content.length; ++i) {
|
|
216
|
+
/* check if this is not the start/end of a placeholder, in which case it can just be added to the current set */
|
|
217
|
+
if (!content.startsWith(placeholder ? '}' : '{#', i)) {
|
|
218
|
+
if (placeholder)
|
|
219
|
+
name += content[i];
|
|
220
|
+
else
|
|
221
|
+
out += content[i];
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
/* check if a name is being started and if its potentially just an escape sequence */
|
|
225
|
+
if (!placeholder) {
|
|
226
|
+
if (content.startsWith('{##', i))
|
|
227
|
+
out += '{#', i += 2;
|
|
228
|
+
else
|
|
229
|
+
name = '', placeholder = true, ++i;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
placeholder = false;
|
|
233
|
+
if (name in args)
|
|
234
|
+
out += (htmlEscape ? escapeHtml(args[name]) : args[name]);
|
|
235
|
+
else
|
|
236
|
+
helperLogger.warning(`Undefined placeholder [${name}] encountered`);
|
|
237
|
+
}
|
|
238
|
+
if (placeholder)
|
|
239
|
+
helperLogger.warning('Content ends with an incomplete placeholder');
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
/* escape all placeholders in the content */
|
|
243
|
+
export function escapePlaceholders(content) {
|
|
244
|
+
let out = '';
|
|
245
|
+
/* construct the new escaped output content */
|
|
246
|
+
for (let i = 0; i < content.length; ++i) {
|
|
247
|
+
if (!content.startsWith('{#', i))
|
|
248
|
+
out += content[i];
|
|
249
|
+
else
|
|
250
|
+
out += '{##', ++i;
|
|
251
|
+
}
|
|
252
|
+
return out;
|
|
253
|
+
}
|
|
254
|
+
/* sanitize path and remove relative path components and convert it to an absolute path */
|
|
255
|
+
export function sanitize(path, relative) {
|
|
256
|
+
/* treat the path as absolute, but preserve backward traversals into the root */
|
|
257
|
+
let out = '/';
|
|
258
|
+
if (path.startsWith('/'))
|
|
259
|
+
relative = false;
|
|
260
|
+
/* iterate over the characters and write them to the output
|
|
261
|
+
* (i == path.length is a final implicit slash to catch trailing '/..') */
|
|
262
|
+
for (let i = 0; i <= path.length; ++i) {
|
|
263
|
+
/* check if the character can just be written out */
|
|
264
|
+
if (i < path.length && path[i] != '/' && path[i] != '\\') {
|
|
265
|
+
out += path[i];
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
/* check if the slash can be ignored as the string ends in a slash */
|
|
269
|
+
if (out.endsWith('/'))
|
|
270
|
+
continue;
|
|
271
|
+
/* check if its a relative path step and remove it */
|
|
272
|
+
if (out.endsWith('/.'))
|
|
273
|
+
out = out.substring(0, out.length - 1);
|
|
274
|
+
/* check if its just an arbitrary sequence */
|
|
275
|
+
else if (!out.endsWith('/..')) {
|
|
276
|
+
if (i + 1 >= path.length)
|
|
277
|
+
break;
|
|
278
|
+
out += '/';
|
|
279
|
+
}
|
|
280
|
+
/* process the backwards walking */
|
|
281
|
+
else if (relative && (out.endsWith('/../..') || out == '/..')) {
|
|
282
|
+
if (i < path.length)
|
|
283
|
+
out += '/';
|
|
284
|
+
}
|
|
285
|
+
else if (!relative && out == '/..')
|
|
286
|
+
out = '/';
|
|
287
|
+
else
|
|
288
|
+
out = out.substring(0, out.lastIndexOf('/', out.length - 4) + 1);
|
|
289
|
+
}
|
|
290
|
+
/* check if its not the root and remove trailing slashes and patch the relative path */
|
|
291
|
+
if (out != '/') {
|
|
292
|
+
if (out.endsWith('/'))
|
|
293
|
+
out = out.substring(0, out.length - 1);
|
|
294
|
+
if (relative)
|
|
295
|
+
out = out.substring(1);
|
|
296
|
+
}
|
|
297
|
+
else if (relative)
|
|
298
|
+
out = '.';
|
|
299
|
+
return out;
|
|
300
|
+
}
|
|
301
|
+
/* join two paths into the sanitized absolute server path-environment */
|
|
302
|
+
export function joinSanitized(a, b) {
|
|
303
|
+
if (a.length == 0 || b.length == 0)
|
|
304
|
+
return sanitize(a.length == 0 ? b : a, false);
|
|
305
|
+
const aSlash = a.endsWith('/'), bSlash = b.startsWith('/');
|
|
306
|
+
if (aSlash)
|
|
307
|
+
return sanitize(bSlash ? a + b.substring(1) : a + b, false);
|
|
308
|
+
return sanitize(bSlash ? a + b : `${a}/${b}`, false);
|
|
309
|
+
}
|
|
310
|
+
/* check if the sanitized path is a sub-path of or equal to the sanitized base path */
|
|
311
|
+
export function isSubPath(base, path) {
|
|
312
|
+
if (base.length > path.length)
|
|
313
|
+
return false;
|
|
314
|
+
if (base.length == path.length)
|
|
315
|
+
return (base == path);
|
|
316
|
+
if (!path.startsWith(base))
|
|
317
|
+
return false;
|
|
318
|
+
return (path[base.length] == '/' || base.endsWith('/'));
|
|
319
|
+
}
|
|
320
|
+
/* check if the sanitized path is a true sub-path of the sanitized base path */
|
|
321
|
+
export function isInside(base, path) {
|
|
322
|
+
if (base.length >= path.length)
|
|
323
|
+
return false;
|
|
324
|
+
if (!path.startsWith(base))
|
|
325
|
+
return false;
|
|
326
|
+
return (path[base.length] == '/' || base.endsWith('/'));
|
|
327
|
+
}
|
|
328
|
+
/* return the remaining path for the sub directory path in base (must be a true sub-directory) */
|
|
329
|
+
export function childPath(base, path) {
|
|
330
|
+
const out = path.substring(base.endsWith('/') ? base.length - 1 : base.length);
|
|
331
|
+
return (out == '' ? '/' : out);
|
|
332
|
+
}
|
|
333
|
+
/* rebase the path from the old base directory onto the new base (must be a true sub-directory) */
|
|
334
|
+
export function rebasePath(oldBase, newBase, path) {
|
|
335
|
+
return joinSanitized(newBase, childPath(oldBase, path));
|
|
336
|
+
}
|
|
337
|
+
/* create path-creator, which returns sanitized paths relative to [path] */
|
|
338
|
+
export function createPathLocation(path) {
|
|
339
|
+
return function (p) {
|
|
340
|
+
return libPath.join(path, sanitize(p, false));
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/* create path-creator, which returns paths relative to the file url path (like the script itself using 'import.meta.url') and optionally the nested path [path] */
|
|
344
|
+
export function createPathSelf(urlFilePath, path = null) {
|
|
345
|
+
let dirName = libPath.dirname(libUrl.fileURLToPath(urlFilePath));
|
|
346
|
+
if (path != null)
|
|
347
|
+
dirName = libPath.join(dirName, sanitize(path, true));
|
|
348
|
+
return createPathLocation(dirName);
|
|
349
|
+
}
|
|
350
|
+
/* split the path in three components ['/base/', 'name', '.extension'] (extension will be empty if the path
|
|
351
|
+
* does not contain a distinct extension; path will be empty if the path does not contain a distinct path) */
|
|
352
|
+
export function splitFilePath(path) {
|
|
353
|
+
let dot = null;
|
|
354
|
+
let name = path.length - 1;
|
|
355
|
+
for (; name >= 0 && (path[name] != '/' && path[name] != '\\'); --name) {
|
|
356
|
+
if (path[name] == '.' && dot == null)
|
|
357
|
+
dot = name;
|
|
358
|
+
}
|
|
359
|
+
if (dot == null || dot == name + 1)
|
|
360
|
+
dot = path.length;
|
|
361
|
+
return [path.substring(0, name + 1), path.substring(name + 1, dot), path.substring(dot)];
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=helper.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./base.js";
|
|
2
|
+
export * from "./cache.js";
|
|
3
|
+
export * from "./client.js";
|
|
4
|
+
export * from "./handler.js";
|
|
5
|
+
export * from "./helper.js";
|
|
6
|
+
export * from "./log.js";
|
|
7
|
+
export * from "./server.js";
|
|
8
|
+
export * as build from "./builder.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: BSD-3-Clause */
|
|
2
|
+
/* Copyright (c) 2026 Bjoern Boss Henrichsen */
|
|
3
|
+
export * from "./base.js";
|
|
4
|
+
;
|
|
5
|
+
export * from "./cache.js";
|
|
6
|
+
export * from "./client.js";
|
|
7
|
+
export * from "./handler.js";
|
|
8
|
+
export * from "./helper.js";
|
|
9
|
+
export * from "./log.js";
|
|
10
|
+
export * from "./server.js";
|
|
11
|
+
export * as build from "./builder.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type LogLevel = 'error' | 'info' | 'warning' | 'log' | 'trace';
|
|
2
|
+
export type LogConsumer = (level: LogLevel | null, date: string, identity: string, msg: string) => void;
|
|
3
|
+
export type Detacher = () => void;
|
|
4
|
+
export type TagUpdate = (value?: string) => void;
|
|
5
|
+
export declare function createConsoleLogger(): LogConsumer;
|
|
6
|
+
export declare function createLineLogger(cb: (line: string) => void): LogConsumer;
|
|
7
|
+
export declare enum PreserveMode {
|
|
8
|
+
none = 0,
|
|
9
|
+
last = 1,
|
|
10
|
+
all = 2
|
|
11
|
+
}
|
|
12
|
+
export declare function createFileLogger(filePath: string, options?: {
|
|
13
|
+
flushingDelayMs?: number;
|
|
14
|
+
bufMaxLineCount?: number;
|
|
15
|
+
sizeSwapFile?: number;
|
|
16
|
+
preserve?: PreserveMode;
|
|
17
|
+
}): LogConsumer;
|
|
18
|
+
export declare function createLogFilter(target: LogConsumer, options?: {
|
|
19
|
+
level?: LogLevel | LogLevel[];
|
|
20
|
+
identity?: string | string[];
|
|
21
|
+
}): LogConsumer;
|
|
22
|
+
export declare class Logger {
|
|
23
|
+
private _rootIdentity;
|
|
24
|
+
private _logIdentity;
|
|
25
|
+
private _logTagList;
|
|
26
|
+
constructor(identity: string);
|
|
27
|
+
private _updateLogIdentity;
|
|
28
|
+
private _performActualLog;
|
|
29
|
+
get logRoot(): string;
|
|
30
|
+
get logExtension(): string;
|
|
31
|
+
get logIdentity(): string;
|
|
32
|
+
tagLog(identifier: string): TagUpdate;
|
|
33
|
+
error(msg: string, options?: {
|
|
34
|
+
extension?: string;
|
|
35
|
+
}): void;
|
|
36
|
+
info(msg: string, options?: {
|
|
37
|
+
extension?: string;
|
|
38
|
+
}): void;
|
|
39
|
+
warning(msg: string, options?: {
|
|
40
|
+
extension?: string;
|
|
41
|
+
}): void;
|
|
42
|
+
log(msg: string, options?: {
|
|
43
|
+
extension?: string;
|
|
44
|
+
}): void;
|
|
45
|
+
trace(msg: string, options?: {
|
|
46
|
+
extension?: string;
|
|
47
|
+
}): void;
|
|
48
|
+
}
|
|
49
|
+
export declare function createLogger(identity: string): Logger;
|
|
50
|
+
export declare function addLogger(cb: LogConsumer): Detacher;
|
|
51
|
+
export declare function logGlobal(level: LogLevel, identity: string, msg: string): void;
|
|
52
|
+
//# sourceMappingURL=log.d.ts.map
|