@decohere/scribe 0.0.1-dev.20 → 0.0.1-dev.20261105.46

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 (40) hide show
  1. package/LICENSE +15 -0
  2. package/commonjs/src/console.adapter.js +21 -14
  3. package/commonjs/src/env.js +2 -3
  4. package/commonjs/src/errors.js +0 -2
  5. package/commonjs/src/index.js +3 -2
  6. package/commonjs/src/log-entry.adapter.js +55 -0
  7. package/commonjs/src/log-entry.js +89 -0
  8. package/commonjs/src/logger.adapter.js +44 -3
  9. package/commonjs/src/logger.factory.js +112 -11
  10. package/commonjs/src/logger.type.js +0 -2
  11. package/commonjs/src/redact.js +67 -0
  12. package/commonjs/src/testing/capture.adapter.js +23 -0
  13. package/commonjs/src/testing/index.js +14 -2
  14. package/commonjs/src/types.js +19 -6
  15. package/es6/src/console.adapter.js +21 -14
  16. package/es6/src/env.js +3 -4
  17. package/es6/src/errors.js +0 -2
  18. package/es6/src/index.js +3 -2
  19. package/es6/src/log-entry.adapter.js +49 -0
  20. package/es6/src/log-entry.js +79 -0
  21. package/es6/src/logger.adapter.js +42 -3
  22. package/es6/src/logger.factory.js +112 -11
  23. package/es6/src/logger.type.js +0 -2
  24. package/es6/src/redact.js +57 -0
  25. package/es6/src/testing/capture.adapter.js +17 -0
  26. package/es6/src/testing/index.js +1 -3
  27. package/es6/src/types.js +16 -6
  28. package/package.json +15 -1
  29. package/types/src/console.adapter.d.ts +1 -0
  30. package/types/src/env.d.ts +1 -1
  31. package/types/src/index.d.ts +3 -0
  32. package/types/src/log-entry.adapter.d.ts +20 -0
  33. package/types/src/log-entry.d.ts +38 -0
  34. package/types/src/logger.adapter.d.ts +31 -1
  35. package/types/src/logger.factory.d.ts +31 -2
  36. package/types/src/logger.type.d.ts +5 -0
  37. package/types/src/redact.d.ts +10 -0
  38. package/types/src/testing/capture.adapter.d.ts +14 -0
  39. package/types/src/testing/index.d.ts +1 -1
  40. package/types/src/types.d.ts +7 -0
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "CaptureAdapter", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return CaptureAdapter;
9
+ }
10
+ });
11
+ const _logentryadapter = require("../log-entry.adapter.js");
12
+ class CaptureAdapter extends _logentryadapter.LogEntryAdapter {
13
+ entries = [];
14
+ /** Entries at `level`. */ at(level) {
15
+ return this.entries.filter((entry)=>entry.level === level);
16
+ }
17
+ clear() {
18
+ this.entries.length = 0;
19
+ }
20
+ write(entry) {
21
+ this.entries.push(entry);
22
+ }
23
+ }
@@ -2,5 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
-
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
5
+ _export_star(require("./capture.adapter.js"), exports);
6
+ function _export_star(from, to) {
7
+ Object.keys(from).forEach(function(k) {
8
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
9
+ Object.defineProperty(to, k, {
10
+ enumerable: true,
11
+ get: function() {
12
+ return from[k];
13
+ }
14
+ });
15
+ }
16
+ });
17
+ return from;
18
+ }
@@ -9,9 +9,15 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ get DefaultCensor () {
13
+ return DefaultCensor;
14
+ },
12
15
  get DefaultLogLevel () {
13
16
  return DefaultLogLevel;
14
17
  },
18
+ get DefaultRedactionKeys () {
19
+ return DefaultRedactionKeys;
20
+ },
15
21
  get DefaultRedactions () {
16
22
  return DefaultRedactions;
17
23
  },
@@ -36,11 +42,18 @@ const LogLevels = {
36
42
  trace: 10
37
43
  };
38
44
  const DefaultLogLevel = "info";
45
+ const DefaultCensor = "[Redacted]";
46
+ const DefaultRedactionKeys = [
47
+ "password",
48
+ "secret",
49
+ "token",
50
+ "otp",
51
+ "pw",
52
+ "userconfig"
53
+ ];
39
54
  const DefaultRedactions = {
40
- paths: [
41
- "*.password",
42
- "*.secret"
43
- ]
55
+ paths: DefaultRedactionKeys.flatMap((key)=>[
56
+ key,
57
+ `*.${key}`
58
+ ])
44
59
  };
45
-
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL3R5cGVzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IExPR19MRVZFTFMgPSBbXCJmYXRhbFwiLCBcImVycm9yXCIsIFwid2FyblwiLCBcImluZm9cIiwgXCJkZWJ1Z1wiLCBcInRyYWNlXCJdIGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBMb2dMZXZlbCA9IHR5cGVvZiBMT0dfTEVWRUxTO1xuXG5leHBvcnQgdHlwZSBEZWZhdWx0TGV2ZWxzID0gTG9nTGV2ZWxbbnVtYmVyXTtcblxuZXhwb3J0IGNvbnN0IExvZ0xldmVscyA9IHtcblx0ZmF0YWw6IDYwLFxuXHRlcnJvcjogNTAsXG5cdHdhcm46IDQwLFxuXHRpbmZvOiAzMCxcblx0ZGVidWc6IDIwLFxuXHR0cmFjZTogMTAsXG59IHNhdGlzZmllcyBSZWNvcmQ8RGVmYXVsdExldmVscywgbnVtYmVyPjtcblxuZXhwb3J0IGNvbnN0IERlZmF1bHRMb2dMZXZlbDogRGVmYXVsdExldmVscyA9IFwiaW5mb1wiO1xuXG5leHBvcnQgdHlwZSBSZWRhY3Rpb25PcHRpb25zID0ge1xuXHRwYXRoczogc3RyaW5nW107XG59O1xuXG5leHBvcnQgY29uc3QgRGVmYXVsdFJlZGFjdGlvbnM6IFJlZGFjdGlvbk9wdGlvbnMgPSB7IHBhdGhzOiBbXCIqLnBhc3N3b3JkXCIsIFwiKi5zZWNyZXRcIl0gfTtcblxuZXhwb3J0IGludGVyZmFjZSBTY3JpYmVPcHRpb25zPFxuXHRUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsXG5cdEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlIHwgZmFsc2UgPSB1bmRlZmluZWQsXG4+IHtcblx0bG9nTGV2ZWw/OiBEZWZhdWx0TGV2ZWxzIHwgc3RyaW5nO1xuXHRjdXN0b21MZXZlbHM/OiB7XG5cdFx0W2xldmVsIGluIFRdOiBudW1iZXI7XG5cdH07XG5cdGN1c3RvbU9ubHk/OiBDdXN0b21Pbmx5O1xuXHRyZWRhY3Rpb25zPzogUmVkYWN0aW9uT3B0aW9ucztcbn1cblxuZXhwb3J0IHR5cGUgTG9nQWRhcHRlck9wdGlvbnMgPSBSZWNvcmQ8c3RyaW5nLCBuZXZlcj47XG4iXSwibmFtZXMiOlsiRGVmYXVsdExvZ0xldmVsIiwiRGVmYXVsdFJlZGFjdGlvbnMiLCJMb2dMZXZlbHMiLCJMT0dfTEVWRUxTIiwiZmF0YWwiLCJlcnJvciIsIndhcm4iLCJpbmZvIiwiZGVidWciLCJ0cmFjZSIsInBhdGhzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztRQWVhQTtlQUFBQTs7UUFNQUM7ZUFBQUE7O1FBZkFDO2VBQUFBOzs7QUFOYixNQUFNQyxhQUFhO0lBQUM7SUFBUztJQUFTO0lBQVE7SUFBUTtJQUFTO0NBQVE7QUFNaEUsTUFBTUQsWUFBWTtJQUN4QkUsT0FBTztJQUNQQyxPQUFPO0lBQ1BDLE1BQU07SUFDTkMsTUFBTTtJQUNOQyxPQUFPO0lBQ1BDLE9BQU87QUFDUjtBQUVPLE1BQU1ULGtCQUFpQztBQU12QyxNQUFNQyxvQkFBc0M7SUFBRVMsT0FBTztRQUFDO1FBQWM7S0FBVztBQUFDIn0=
@@ -1,28 +1,33 @@
1
1
  import { formatError, LogAdapter } from "./logger.adapter.js";
2
+ import { redact } from "./redact.js";
2
3
  import { DefaultLogLevel, LogLevels } from "./types.js";
3
4
  export class ConsoleAdapter extends LogAdapter {
4
5
  configuredLevels;
5
6
  configuredLogLevel = DefaultLogLevel;
6
7
  configuredLogLevelValue = LogLevels.info;
8
+ redactionKeys = redact.fromOptions();
7
9
  constructor(_options = {}){
8
10
  super();
9
11
  }
10
12
  configure(scribeOptions) {
11
- // Get merged log levels (default + custom) using parent class method
12
13
  this.configuredLevels = this.getLogLevels(scribeOptions);
13
14
  const logLevelStr = scribeOptions.logLevel ?? DefaultLogLevel;
14
15
  this.configuredLogLevel = logLevelStr;
15
16
  this.configuredLogLevelValue = this.configuredLevels[logLevelStr] ?? LogLevels.info;
17
+ this.redactionKeys = redact.fromOptions(scribeOptions.redactions);
16
18
  }
17
19
  getLogger(name) {
18
20
  const loggerName = name || "default";
19
- return this.createConsoleLogger(loggerName);
21
+ return this.createConsoleLogger(loggerName, {});
20
22
  }
21
- createConsoleLogger(name) {
22
- // Use the levels configured during the configure() call
23
+ createConsoleLogger(name, bindings) {
23
24
  const allLevels = this.configuredLevels;
24
25
  const currentLevel = this.configuredLogLevel;
25
26
  const threshold = this.configuredLogLevelValue;
27
+ const redactionKeys = this.redactionKeys;
28
+ const bound = Object.keys(bindings).length > 0 ? [
29
+ redact.object(bindings, redactionKeys)
30
+ ] : [];
26
31
  const baseLogger = {
27
32
  get currentLevel () {
28
33
  return currentLevel;
@@ -35,30 +40,32 @@ export class ConsoleAdapter extends LogAdapter {
35
40
  const timestamp = new Date().toISOString();
36
41
  let message;
37
42
  if (typeof msg === "object") {
38
- message = msg instanceof Error ? formatError(msg) : JSON.stringify(msg);
43
+ message = msg instanceof Error ? formatError(msg) : JSON.stringify(redact.object(msg, redactionKeys));
39
44
  } else {
40
45
  message = String(msg);
41
46
  }
42
47
  const logLine = `[${timestamp}] ${level.toUpperCase()} [${name}]: ${message}`;
43
- if (args.length > 0) {
44
- console.log(logLine, ...args);
48
+ const payload = [
49
+ ...args.map((arg)=>redact.object(arg, redactionKeys)),
50
+ ...bound
51
+ ];
52
+ if (payload.length > 0) {
53
+ console.log(logLine, ...payload);
45
54
  } else {
46
55
  console.log(logLine);
47
56
  }
48
57
  };
49
58
  const noop = ()=>{};
50
- // Start with base logger and isLevelEnabled method
51
59
  const logger = Object.assign(baseLogger, {
52
- isLevelEnabled: (level)=>(allLevels[level] ?? 0) >= threshold
60
+ isLevelEnabled: (level)=>(allLevels[level] ?? 0) >= threshold,
61
+ child: (fields)=>this.createConsoleLogger(name, {
62
+ ...bindings,
63
+ ...fields
64
+ })
53
65
  });
54
- // Dynamically add all log level methods (default + custom)
55
- // Levels below the configured threshold are patched to noop
56
66
  for (const [levelName, levelValue] of Object.entries(allLevels)){
57
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic logger level creation requires any
58
67
  logger[levelName] = levelValue >= threshold ? logFunction(levelName) : noop;
59
68
  }
60
69
  return logger;
61
70
  }
62
71
  }
63
-
64
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL2NvbnNvbGUuYWRhcHRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmb3JtYXRFcnJvciwgTG9nQWRhcHRlciB9IGZyb20gXCIuL2xvZ2dlci5hZGFwdGVyLmpzXCI7XG5pbXBvcnQgdHlwZSB7IEJhc2VMb2dnZXIsIExvZ2dlciB9IGZyb20gXCIuL2xvZ2dlci50eXBlLmpzXCI7XG5pbXBvcnQge1xuXHREZWZhdWx0TG9nTGV2ZWwsXG5cdHR5cGUgTG9nQWRhcHRlck9wdGlvbnMsXG5cdExvZ0xldmVscyxcblx0dHlwZSBTY3JpYmVPcHRpb25zLFxufSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuXG5leHBvcnQgdHlwZSBDb25zb2xlQWRhcHRlck9wdGlvbnMgPSB7fSAmIExvZ0FkYXB0ZXJPcHRpb25zO1xuXG5leHBvcnQgY2xhc3MgQ29uc29sZUFkYXB0ZXIgZXh0ZW5kcyBMb2dBZGFwdGVyIHtcblx0cHJpdmF0ZSBjb25maWd1cmVkTGV2ZWxzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuXHRwcml2YXRlIGNvbmZpZ3VyZWRMb2dMZXZlbDogc3RyaW5nID0gRGVmYXVsdExvZ0xldmVsO1xuXHRwcml2YXRlIGNvbmZpZ3VyZWRMb2dMZXZlbFZhbHVlOiBudW1iZXIgPSBMb2dMZXZlbHMuaW5mbztcblxuXHRwdWJsaWMgY29uc3RydWN0b3IoX29wdGlvbnM6IENvbnNvbGVBZGFwdGVyT3B0aW9ucyA9IHt9KSB7XG5cdFx0c3VwZXIoKTtcblx0fVxuXG5cdHB1YmxpYyBjb25maWd1cmU8VCBleHRlbmRzIHN0cmluZyA9IG5ldmVyLCBDdXN0b21Pbmx5IGV4dGVuZHMgdHJ1ZSB8IGZhbHNlID0gZmFsc2U+KFxuXHRcdHNjcmliZU9wdGlvbnM6IFNjcmliZU9wdGlvbnM8VCwgQ3VzdG9tT25seT4sXG5cdCkge1xuXHRcdC8vIEdldCBtZXJnZWQgbG9nIGxldmVscyAoZGVmYXVsdCArIGN1c3RvbSkgdXNpbmcgcGFyZW50IGNsYXNzIG1ldGhvZFxuXHRcdHRoaXMuY29uZmlndXJlZExldmVscyA9IHRoaXMuZ2V0TG9nTGV2ZWxzKHNjcmliZU9wdGlvbnMpO1xuXHRcdGNvbnN0IGxvZ0xldmVsU3RyID0gc2NyaWJlT3B0aW9ucy5sb2dMZXZlbCA/PyBEZWZhdWx0TG9nTGV2ZWw7XG5cdFx0dGhpcy5jb25maWd1cmVkTG9nTGV2ZWwgPSBsb2dMZXZlbFN0cjtcblx0XHR0aGlzLmNvbmZpZ3VyZWRMb2dMZXZlbFZhbHVlID0gdGhpcy5jb25maWd1cmVkTGV2ZWxzW2xvZ0xldmVsU3RyXSA/PyBMb2dMZXZlbHMuaW5mbztcblx0fVxuXG5cdHB1YmxpYyBnZXRMb2dnZXI8VCBleHRlbmRzIHN0cmluZyA9IG5ldmVyLCBDdXN0b21Pbmx5IGV4dGVuZHMgdHJ1ZSB8IGZhbHNlID0gZmFsc2U+KFxuXHRcdG5hbWU/OiBzdHJpbmcsXG5cdCk6IExvZ2dlcjxULCBDdXN0b21Pbmx5PiB7XG5cdFx0Y29uc3QgbG9nZ2VyTmFtZSA9IG5hbWUgfHwgXCJkZWZhdWx0XCI7XG5cdFx0cmV0dXJuIHRoaXMuY3JlYXRlQ29uc29sZUxvZ2dlcjxULCBDdXN0b21Pbmx5Pihsb2dnZXJOYW1lKTtcblx0fVxuXG5cdHByaXZhdGUgY3JlYXRlQ29uc29sZUxvZ2dlcjxcblx0XHRUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsXG5cdFx0Q3VzdG9tT25seSBleHRlbmRzIHRydWUgfCBmYWxzZSA9IGZhbHNlLFxuXHQ+KG5hbWU6IHN0cmluZyk6IExvZ2dlcjxULCBDdXN0b21Pbmx5PiB7XG5cdFx0Ly8gVXNlIHRoZSBsZXZlbHMgY29uZmlndXJlZCBkdXJpbmcgdGhlIGNvbmZpZ3VyZSgpIGNhbGxcblx0XHRjb25zdCBhbGxMZXZlbHMgPSB0aGlzLmNvbmZpZ3VyZWRMZXZlbHM7XG5cdFx0Y29uc3QgY3VycmVudExldmVsID0gdGhpcy5jb25maWd1cmVkTG9nTGV2ZWw7XG5cdFx0Y29uc3QgdGhyZXNob2xkID0gdGhpcy5jb25maWd1cmVkTG9nTGV2ZWxWYWx1ZTtcblxuXHRcdGNvbnN0IGJhc2VMb2dnZXI6IEJhc2VMb2dnZXIgPSB7XG5cdFx0XHRnZXQgY3VycmVudExldmVsKCkge1xuXHRcdFx0XHRyZXR1cm4gY3VycmVudExldmVsO1xuXHRcdFx0fSxcblx0XHRcdGdldCBsb2dMZXZlbHMoKSB7XG5cdFx0XHRcdHJldHVybiBhbGxMZXZlbHM7XG5cdFx0XHR9LFxuXHRcdH07XG5cblx0XHRjb25zdCBsb2dGdW5jdGlvbiA9XG5cdFx0XHQobGV2ZWw6IHN0cmluZykgPT5cblx0XHRcdChtc2c6IHN0cmluZyB8IG51bWJlciB8IG9iamVjdCwgLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcblx0XHRcdFx0bGV0IG1lc3NhZ2U6IHN0cmluZztcblxuXHRcdFx0XHRpZiAodHlwZW9mIG1zZyA9PT0gXCJvYmplY3RcIikge1xuXHRcdFx0XHRcdG1lc3NhZ2UgPSBtc2cgaW5zdGFuY2VvZiBFcnJvciA/IGZvcm1hdEVycm9yKG1zZykgOiBKU09OLnN0cmluZ2lmeShtc2cpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG1lc3NhZ2UgPSBTdHJpbmcobXNnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IGxvZ0xpbmUgPSBgWyR7dGltZXN0YW1wfV0gJHtsZXZlbC50b1VwcGVyQ2FzZSgpfSBbJHtuYW1lfV06ICR7bWVzc2FnZX1gO1xuXG5cdFx0XHRcdGlmIChhcmdzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRjb25zb2xlLmxvZyhsb2dMaW5lLCAuLi5hcmdzKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjb25zb2xlLmxvZyhsb2dMaW5lKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdGNvbnN0IG5vb3AgPSAoKSA9PiB7fTtcblxuXHRcdC8vIFN0YXJ0IHdpdGggYmFzZSBsb2dnZXIgYW5kIGlzTGV2ZWxFbmFibGVkIG1ldGhvZFxuXHRcdGNvbnN0IGxvZ2dlciA9IE9iamVjdC5hc3NpZ24oYmFzZUxvZ2dlciwge1xuXHRcdFx0aXNMZXZlbEVuYWJsZWQ6IChsZXZlbDogc3RyaW5nKSA9PiAoYWxsTGV2ZWxzW2xldmVsXSA/PyAwKSA+PSB0aHJlc2hvbGQsXG5cdFx0fSk7XG5cblx0XHQvLyBEeW5hbWljYWxseSBhZGQgYWxsIGxvZyBsZXZlbCBtZXRob2RzIChkZWZhdWx0ICsgY3VzdG9tKVxuXHRcdC8vIExldmVscyBiZWxvdyB0aGUgY29uZmlndXJlZCB0aHJlc2hvbGQgYXJlIHBhdGNoZWQgdG8gbm9vcFxuXHRcdGZvciAoY29uc3QgW2xldmVsTmFtZSwgbGV2ZWxWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYWxsTGV2ZWxzKSkge1xuXHRcdFx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBEeW5hbWljIGxvZ2dlciBsZXZlbCBjcmVhdGlvbiByZXF1aXJlcyBhbnlcblx0XHRcdChsb2dnZXIgYXMgYW55KVtsZXZlbE5hbWVdID0gbGV2ZWxWYWx1ZSA+PSB0aHJlc2hvbGQgPyBsb2dGdW5jdGlvbihsZXZlbE5hbWUpIDogbm9vcDtcblx0XHR9XG5cblx0XHRyZXR1cm4gbG9nZ2VyIGFzIExvZ2dlcjxULCBDdXN0b21Pbmx5Pjtcblx0fVxufVxuIl0sIm5hbWVzIjpbImZvcm1hdEVycm9yIiwiTG9nQWRhcHRlciIsIkRlZmF1bHRMb2dMZXZlbCIsIkxvZ0xldmVscyIsIkNvbnNvbGVBZGFwdGVyIiwiY29uZmlndXJlZExldmVscyIsImNvbmZpZ3VyZWRMb2dMZXZlbCIsImNvbmZpZ3VyZWRMb2dMZXZlbFZhbHVlIiwiaW5mbyIsIl9vcHRpb25zIiwiY29uZmlndXJlIiwic2NyaWJlT3B0aW9ucyIsImdldExvZ0xldmVscyIsImxvZ0xldmVsU3RyIiwibG9nTGV2ZWwiLCJnZXRMb2dnZXIiLCJuYW1lIiwibG9nZ2VyTmFtZSIsImNyZWF0ZUNvbnNvbGVMb2dnZXIiLCJhbGxMZXZlbHMiLCJjdXJyZW50TGV2ZWwiLCJ0aHJlc2hvbGQiLCJiYXNlTG9nZ2VyIiwibG9nTGV2ZWxzIiwibG9nRnVuY3Rpb24iLCJsZXZlbCIsIm1zZyIsImFyZ3MiLCJ0aW1lc3RhbXAiLCJEYXRlIiwidG9JU09TdHJpbmciLCJtZXNzYWdlIiwiRXJyb3IiLCJKU09OIiwic3RyaW5naWZ5IiwiU3RyaW5nIiwibG9nTGluZSIsInRvVXBwZXJDYXNlIiwibGVuZ3RoIiwiY29uc29sZSIsImxvZyIsIm5vb3AiLCJsb2dnZXIiLCJPYmplY3QiLCJhc3NpZ24iLCJpc0xldmVsRW5hYmxlZCIsImxldmVsTmFtZSIsImxldmVsVmFsdWUiLCJlbnRyaWVzIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxXQUFXLEVBQUVDLFVBQVUsUUFBUSxzQkFBc0I7QUFFOUQsU0FDQ0MsZUFBZSxFQUVmQyxTQUFTLFFBRUgsYUFBYTtBQUlwQixPQUFPLE1BQU1DLHVCQUF1Qkg7SUFDM0JJLGlCQUF5QztJQUN6Q0MscUJBQTZCSixnQkFBZ0I7SUFDN0NLLDBCQUFrQ0osVUFBVUssSUFBSSxDQUFDO0lBRXpELFlBQW1CQyxXQUFrQyxDQUFDLENBQUMsQ0FBRTtRQUN4RCxLQUFLO0lBQ047SUFFT0MsVUFDTkMsYUFBMkMsRUFDMUM7UUFDRCxxRUFBcUU7UUFDckUsSUFBSSxDQUFDTixnQkFBZ0IsR0FBRyxJQUFJLENBQUNPLFlBQVksQ0FBQ0Q7UUFDMUMsTUFBTUUsY0FBY0YsY0FBY0csUUFBUSxJQUFJWjtRQUM5QyxJQUFJLENBQUNJLGtCQUFrQixHQUFHTztRQUMxQixJQUFJLENBQUNOLHVCQUF1QixHQUFHLElBQUksQ0FBQ0YsZ0JBQWdCLENBQUNRLFlBQVksSUFBSVYsVUFBVUssSUFBSTtJQUNwRjtJQUVPTyxVQUNOQyxJQUFhLEVBQ1c7UUFDeEIsTUFBTUMsYUFBYUQsUUFBUTtRQUMzQixPQUFPLElBQUksQ0FBQ0UsbUJBQW1CLENBQWdCRDtJQUNoRDtJQUVRQyxvQkFHTkYsSUFBWSxFQUF5QjtRQUN0Qyx3REFBd0Q7UUFDeEQsTUFBTUcsWUFBWSxJQUFJLENBQUNkLGdCQUFnQjtRQUN2QyxNQUFNZSxlQUFlLElBQUksQ0FBQ2Qsa0JBQWtCO1FBQzVDLE1BQU1lLFlBQVksSUFBSSxDQUFDZCx1QkFBdUI7UUFFOUMsTUFBTWUsYUFBeUI7WUFDOUIsSUFBSUYsZ0JBQWU7Z0JBQ2xCLE9BQU9BO1lBQ1I7WUFDQSxJQUFJRyxhQUFZO2dCQUNmLE9BQU9KO1lBQ1I7UUFDRDtRQUVBLE1BQU1LLGNBQ0wsQ0FBQ0MsUUFDRCxDQUFDQyxLQUErQixHQUFHQztnQkFDbEMsTUFBTUMsWUFBWSxJQUFJQyxPQUFPQyxXQUFXO2dCQUN4QyxJQUFJQztnQkFFSixJQUFJLE9BQU9MLFFBQVEsVUFBVTtvQkFDNUJLLFVBQVVMLGVBQWVNLFFBQVFoQyxZQUFZMEIsT0FBT08sS0FBS0MsU0FBUyxDQUFDUjtnQkFDcEUsT0FBTztvQkFDTkssVUFBVUksT0FBT1Q7Z0JBQ2xCO2dCQUVBLE1BQU1VLFVBQVUsQ0FBQyxDQUFDLEVBQUVSLFVBQVUsRUFBRSxFQUFFSCxNQUFNWSxXQUFXLEdBQUcsRUFBRSxFQUFFckIsS0FBSyxHQUFHLEVBQUVlLFNBQVM7Z0JBRTdFLElBQUlKLEtBQUtXLE1BQU0sR0FBRyxHQUFHO29CQUNwQkMsUUFBUUMsR0FBRyxDQUFDSixZQUFZVDtnQkFDekIsT0FBTztvQkFDTlksUUFBUUMsR0FBRyxDQUFDSjtnQkFDYjtZQUNEO1FBRUQsTUFBTUssT0FBTyxLQUFPO1FBRXBCLG1EQUFtRDtRQUNuRCxNQUFNQyxTQUFTQyxPQUFPQyxNQUFNLENBQUN0QixZQUFZO1lBQ3hDdUIsZ0JBQWdCLENBQUNwQixRQUFrQixBQUFDTixDQUFBQSxTQUFTLENBQUNNLE1BQU0sSUFBSSxDQUFBLEtBQU1KO1FBQy9EO1FBRUEsMkRBQTJEO1FBQzNELDREQUE0RDtRQUM1RCxLQUFLLE1BQU0sQ0FBQ3lCLFdBQVdDLFdBQVcsSUFBSUosT0FBT0ssT0FBTyxDQUFDN0IsV0FBWTtZQUNoRSx5RkFBeUY7WUFDeEZ1QixNQUFjLENBQUNJLFVBQVUsR0FBR0MsY0FBYzFCLFlBQVlHLFlBQVlzQixhQUFhTDtRQUNqRjtRQUVBLE9BQU9DO0lBQ1I7QUFDRCJ9
package/es6/src/env.js CHANGED
@@ -17,10 +17,11 @@ const VALID_LEVELS = [
17
17
  /**
18
18
  * Reads the log level from environment variables.
19
19
  * Checks LOG_LEVEL, SCRIBE_LOG_LEVEL, and LOGGING_LEVEL in order.
20
- * Returns null if none are set.
20
+ * Returns null if none are set, or if the runtime has no `process` (browsers).
21
21
  */ export function getLogLevelFromEnv() {
22
+ const env = globalThis.process?.env;
22
23
  for (const name of ENV_VAR_NAMES){
23
- const value = process.env[name]?.trim().toLowerCase();
24
+ const value = env?.[name]?.trim().toLowerCase();
24
25
  if (value) {
25
26
  return value;
26
27
  }
@@ -75,5 +76,3 @@ export function resolveLogLevel(arg) {
75
76
  }
76
77
  return defaultLogLevel;
77
78
  }
78
-
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL2Vudi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IERlZmF1bHRMZXZlbHMgfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuXG4vKipcbiAqIEVudmlyb25tZW50IHZhcmlhYmxlIG5hbWVzIGNoZWNrZWQgaW4gb3JkZXIgb2YgcHJlY2VkZW5jZS5cbiAqIFRoZSBmaXJzdCBub24tZW1wdHkgdmFsdWUgZm91bmQgaXMgdXNlZC5cbiAqL1xuY29uc3QgRU5WX1ZBUl9OQU1FUyA9IFtcIkxPR19MRVZFTFwiLCBcIlNDUklCRV9MT0dfTEVWRUxcIiwgXCJMT0dHSU5HX0xFVkVMXCJdIGFzIGNvbnN0O1xuXG5jb25zdCBWQUxJRF9MRVZFTFM6IERlZmF1bHRMZXZlbHNbXSA9IFtcImZhdGFsXCIsIFwiZXJyb3JcIiwgXCJ3YXJuXCIsIFwiaW5mb1wiLCBcImRlYnVnXCIsIFwidHJhY2VcIl07XG5cbi8qKlxuICogUmVhZHMgdGhlIGxvZyBsZXZlbCBmcm9tIGVudmlyb25tZW50IHZhcmlhYmxlcy5cbiAqIENoZWNrcyBMT0dfTEVWRUwsIFNDUklCRV9MT0dfTEVWRUwsIGFuZCBMT0dHSU5HX0xFVkVMIGluIG9yZGVyLlxuICogUmV0dXJucyBudWxsIGlmIG5vbmUgYXJlIHNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExvZ0xldmVsRnJvbUVudigpOiBzdHJpbmcgfCBudWxsIHtcblx0Zm9yIChjb25zdCBuYW1lIG9mIEVOVl9WQVJfTkFNRVMpIHtcblx0XHRjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52W25hbWVdPy50cmltKCkudG9Mb3dlckNhc2UoKTtcblx0XHRpZiAodmFsdWUpIHtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogUmVhZHMgYSBsb2ctbGV2ZWwgZmxhZyBmcm9tIGFyZ3YuXG4gKiBTdXBwb3J0czogLS1sb2ctbGV2ZWwgPHZhbHVlPiwgLWwgPHZhbHVlPiwgYW5kIC0tbG9nLWxldmVsPTx2YWx1ZT5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExvZ0xldmVsRnJvbUFyZ3YoYXJndjogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuXHRmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYXJndi5sZW5ndGg7IGluZGV4ICs9IDEpIHtcblx0XHRjb25zdCBhcmcgPSBhcmd2W2luZGV4XTtcblx0XHRpZiAoYXJnID09PSBcIi0tbG9nLWxldmVsXCIgfHwgYXJnID09PSBcIi1sXCIpIHtcblx0XHRcdHJldHVybiBhcmd2W2luZGV4ICsgMV07XG5cdFx0fVxuXHRcdGlmIChhcmcuc3RhcnRzV2l0aChcIi0tbG9nLWxldmVsPVwiKSkge1xuXHRcdFx0cmV0dXJuIGFyZy5zbGljZShcIi0tbG9nLWxldmVsPVwiLmxlbmd0aCk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHN0cmluZyBpcyBhIHJlY29nbmlzZWQgZGVmYXVsdCBsb2cgbGV2ZWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkTG9nTGV2ZWwobGV2ZWw6IHN0cmluZyk6IGxldmVsIGlzIERlZmF1bHRMZXZlbHMge1xuXHRyZXR1cm4gKFZBTElEX0xFVkVMUyBhcyBzdHJpbmdbXSkuaW5jbHVkZXMobGV2ZWwpO1xufVxuXG5leHBvcnQgdHlwZSBSZXNvbHZlTG9nTGV2ZWxPcHRpb25zID0ge1xuXHRleHBsaWNpdExvZ0xldmVsPzogc3RyaW5nIHwgbnVsbDtcblx0ZW52TG9nTGV2ZWw/OiBzdHJpbmcgfCBudWxsO1xuXHRkZWZhdWx0TG9nTGV2ZWw6IHN0cmluZztcbn07XG5cbi8qKlxuICogUmVzb2x2ZXMgbG9nIGxldmVsIHdpdGggcHJlY2VkZW5jZTogZXhwbGljaXQgPiBlbnYgPiBkZWZhdWx0LlxuICogSW52YWxpZCBleHBsaWNpdC9lbnYgbGV2ZWxzIGZhbGwgYmFjayB0byBkZWZhdWx0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUxvZ0xldmVsKGV4cGxpY2l0TG9nTGV2ZWw/OiBzdHJpbmcgfCBudWxsKTogc3RyaW5nIHwgbnVsbDtcbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTG9nTGV2ZWwob3B0aW9uczogUmVzb2x2ZUxvZ0xldmVsT3B0aW9ucyk6IHN0cmluZztcbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTG9nTGV2ZWwoYXJnPzogc3RyaW5nIHwgbnVsbCB8IFJlc29sdmVMb2dMZXZlbE9wdGlvbnMpOiBzdHJpbmcgfCBudWxsIHtcblx0aWYgKHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCIpIHtcblx0XHRpZiAoaXNWYWxpZExvZ0xldmVsKGFyZykpIHtcblx0XHRcdHJldHVybiBhcmc7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZW52TG9nTGV2ZWwgPSBnZXRMb2dMZXZlbEZyb21FbnYoKTtcblx0XHRpZiAoZW52TG9nTGV2ZWwgIT0gbnVsbCAmJiBpc1ZhbGlkTG9nTGV2ZWwoZW52TG9nTGV2ZWwpKSB7XG5cdFx0XHRyZXR1cm4gZW52TG9nTGV2ZWw7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHRpZiAoYXJnID09IG51bGwpIHtcblx0XHRjb25zdCBlbnZMb2dMZXZlbCA9IGdldExvZ0xldmVsRnJvbUVudigpO1xuXHRcdGlmIChlbnZMb2dMZXZlbCAhPSBudWxsICYmIGlzVmFsaWRMb2dMZXZlbChlbnZMb2dMZXZlbCkpIHtcblx0XHRcdHJldHVybiBlbnZMb2dMZXZlbDtcblx0XHR9XG5cblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdGNvbnN0IHsgZXhwbGljaXRMb2dMZXZlbCwgZW52TG9nTGV2ZWwsIGRlZmF1bHRMb2dMZXZlbCB9ID0gYXJnO1xuXHRpZiAoZXhwbGljaXRMb2dMZXZlbCAhPSBudWxsICYmIGlzVmFsaWRMb2dMZXZlbChleHBsaWNpdExvZ0xldmVsKSkge1xuXHRcdHJldHVybiBleHBsaWNpdExvZ0xldmVsO1xuXHR9XG5cblx0Y29uc3QgcmVzb2x2ZWRFbnZMb2dMZXZlbCA9IGVudkxvZ0xldmVsID8/IGdldExvZ0xldmVsRnJvbUVudigpO1xuXHRpZiAocmVzb2x2ZWRFbnZMb2dMZXZlbCAhPSBudWxsICYmIGlzVmFsaWRMb2dMZXZlbChyZXNvbHZlZEVudkxvZ0xldmVsKSkge1xuXHRcdHJldHVybiByZXNvbHZlZEVudkxvZ0xldmVsO1xuXHR9XG5cblx0cmV0dXJuIGRlZmF1bHRMb2dMZXZlbDtcbn1cbiJdLCJuYW1lcyI6WyJFTlZfVkFSX05BTUVTIiwiVkFMSURfTEVWRUxTIiwiZ2V0TG9nTGV2ZWxGcm9tRW52IiwibmFtZSIsInZhbHVlIiwicHJvY2VzcyIsImVudiIsInRyaW0iLCJ0b0xvd2VyQ2FzZSIsImdldExvZ0xldmVsRnJvbUFyZ3YiLCJhcmd2IiwiaW5kZXgiLCJsZW5ndGgiLCJhcmciLCJzdGFydHNXaXRoIiwic2xpY2UiLCJ1bmRlZmluZWQiLCJpc1ZhbGlkTG9nTGV2ZWwiLCJsZXZlbCIsImluY2x1ZGVzIiwicmVzb2x2ZUxvZ0xldmVsIiwiZW52TG9nTGV2ZWwiLCJleHBsaWNpdExvZ0xldmVsIiwiZGVmYXVsdExvZ0xldmVsIiwicmVzb2x2ZWRFbnZMb2dMZXZlbCJdLCJtYXBwaW5ncyI6IkFBRUE7OztDQUdDLEdBQ0QsTUFBTUEsZ0JBQWdCO0lBQUM7SUFBYTtJQUFvQjtDQUFnQjtBQUV4RSxNQUFNQyxlQUFnQztJQUFDO0lBQVM7SUFBUztJQUFRO0lBQVE7SUFBUztDQUFRO0FBRTFGOzs7O0NBSUMsR0FDRCxPQUFPLFNBQVNDO0lBQ2YsS0FBSyxNQUFNQyxRQUFRSCxjQUFlO1FBQ2pDLE1BQU1JLFFBQVFDLFFBQVFDLEdBQUcsQ0FBQ0gsS0FBSyxFQUFFSSxPQUFPQztRQUN4QyxJQUFJSixPQUFPO1lBQ1YsT0FBT0E7UUFDUjtJQUNEO0lBQ0EsT0FBTztBQUNSO0FBRUE7OztDQUdDLEdBQ0QsT0FBTyxTQUFTSyxvQkFBb0JDLElBQXVCO0lBQzFELElBQUssSUFBSUMsUUFBUSxHQUFHQSxRQUFRRCxLQUFLRSxNQUFNLEVBQUVELFNBQVMsRUFBRztRQUNwRCxNQUFNRSxNQUFNSCxJQUFJLENBQUNDLE1BQU07UUFDdkIsSUFBSUUsUUFBUSxpQkFBaUJBLFFBQVEsTUFBTTtZQUMxQyxPQUFPSCxJQUFJLENBQUNDLFFBQVEsRUFBRTtRQUN2QjtRQUNBLElBQUlFLElBQUlDLFVBQVUsQ0FBQyxpQkFBaUI7WUFDbkMsT0FBT0QsSUFBSUUsS0FBSyxDQUFDLGVBQWVILE1BQU07UUFDdkM7SUFDRDtJQUVBLE9BQU9JO0FBQ1I7QUFFQTs7Q0FFQyxHQUNELE9BQU8sU0FBU0MsZ0JBQWdCQyxLQUFhO0lBQzVDLE9BQU8sQUFBQ2pCLGFBQTBCa0IsUUFBUSxDQUFDRDtBQUM1QztBQWNBLE9BQU8sU0FBU0UsZ0JBQWdCUCxHQUE0QztJQUMzRSxJQUFJLE9BQU9BLFFBQVEsVUFBVTtRQUM1QixJQUFJSSxnQkFBZ0JKLE1BQU07WUFDekIsT0FBT0E7UUFDUjtRQUVBLE1BQU1RLGNBQWNuQjtRQUNwQixJQUFJbUIsZUFBZSxRQUFRSixnQkFBZ0JJLGNBQWM7WUFDeEQsT0FBT0E7UUFDUjtRQUVBLE9BQU87SUFDUjtJQUVBLElBQUlSLE9BQU8sTUFBTTtRQUNoQixNQUFNUSxjQUFjbkI7UUFDcEIsSUFBSW1CLGVBQWUsUUFBUUosZ0JBQWdCSSxjQUFjO1lBQ3hELE9BQU9BO1FBQ1I7UUFFQSxPQUFPO0lBQ1I7SUFFQSxNQUFNLEVBQUVDLGdCQUFnQixFQUFFRCxXQUFXLEVBQUVFLGVBQWUsRUFBRSxHQUFHVjtJQUMzRCxJQUFJUyxvQkFBb0IsUUFBUUwsZ0JBQWdCSyxtQkFBbUI7UUFDbEUsT0FBT0E7SUFDUjtJQUVBLE1BQU1FLHNCQUFzQkgsZUFBZW5CO0lBQzNDLElBQUlzQix1QkFBdUIsUUFBUVAsZ0JBQWdCTyxzQkFBc0I7UUFDeEUsT0FBT0E7SUFDUjtJQUVBLE9BQU9EO0FBQ1IifQ==
package/es6/src/errors.js CHANGED
@@ -1,4 +1,2 @@
1
1
  export class LoggingConfigurationError extends Error {
2
2
  }
3
-
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL2Vycm9ycy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgTG9nZ2luZ0NvbmZpZ3VyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHt9XG4iXSwibmFtZXMiOlsiTG9nZ2luZ0NvbmZpZ3VyYXRpb25FcnJvciIsIkVycm9yIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU1BLGtDQUFrQ0M7QUFBTyJ9
package/es6/src/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  export * from "./console.adapter.js";
2
2
  export * from "./env.js";
3
3
  export * from "./errors.js";
4
+ export * from "./log-entry.adapter.js";
5
+ export * from "./log-entry.js";
4
6
  export * from "./logger.adapter.js";
5
7
  export * from "./logger.factory.js";
6
8
  export * from "./logger.type.js";
9
+ export * from "./redact.js";
7
10
  export * from "./types.js";
8
-
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL2NvbnNvbGUuYWRhcHRlci5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52LmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lcnJvcnMuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2xvZ2dlci5hZGFwdGVyLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9sb2dnZXIuZmFjdG9yeS5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vbG9nZ2VyLnR5cGUuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzLmpzXCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx1QkFBdUI7QUFDckMsY0FBYyxXQUFXO0FBQ3pCLGNBQWMsY0FBYztBQUM1QixjQUFjLHNCQUFzQjtBQUNwQyxjQUFjLHNCQUFzQjtBQUNwQyxjQUFjLG1CQUFtQjtBQUNqQyxjQUFjLGFBQWEifQ==
@@ -0,0 +1,49 @@
1
+ import { logEntry } from "./log-entry.js";
2
+ import { LogAdapter } from "./logger.adapter.js";
3
+ import { redact } from "./redact.js";
4
+ import { DefaultLogLevel, LogLevels } from "./types.js";
5
+ /**
6
+ * Base for adapters that write structured entries. It owns levels, the level
7
+ * threshold, `child`, and censoring the `redactions` keys; a subclass only
8
+ * writes each `LogEntry`.
9
+ */ export class LogEntryAdapter extends LogAdapter {
10
+ levels = LogLevels;
11
+ level = DefaultLogLevel;
12
+ threshold = LogLevels.info;
13
+ redactionKeys = redact.fromOptions();
14
+ configure(scribeOptions) {
15
+ this.levels = this.getLogLevels(scribeOptions);
16
+ this.level = scribeOptions.logLevel ?? DefaultLogLevel;
17
+ this.threshold = this.levels[this.level] ?? LogLevels.info;
18
+ this.redactionKeys = redact.fromOptions(scribeOptions.redactions);
19
+ }
20
+ getLogger(name) {
21
+ return this.createLogger(name || "default", {});
22
+ }
23
+ createLogger(name, bindings) {
24
+ const { levels, level: currentLevel, threshold, redactionKeys } = this;
25
+ const baseLogger = {
26
+ get currentLevel () {
27
+ return currentLevel;
28
+ },
29
+ get logLevels () {
30
+ return levels;
31
+ }
32
+ };
33
+ const noop = ()=>{};
34
+ const methods = {};
35
+ for (const [level, value] of Object.entries(levels)){
36
+ methods[level] = value >= threshold ? (...args)=>this.write(logEntry.from(level, name, args, {
37
+ bindings,
38
+ redactionKeys
39
+ })) : noop;
40
+ }
41
+ return Object.assign(baseLogger, methods, {
42
+ isLevelEnabled: (level)=>(levels[level] ?? 0) >= threshold,
43
+ child: (fields)=>this.createLogger(name, {
44
+ ...bindings,
45
+ ...fields
46
+ })
47
+ });
48
+ }
49
+ }
@@ -0,0 +1,79 @@
1
+ import { serializeError } from "./logger.adapter.js";
2
+ import { redact } from "./redact.js";
3
+ function isFields(value) {
4
+ return value != null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ /** Serialize errors passed as fields (`{ error }`), so they keep their message and stack. */ function serializeErrors(fields) {
7
+ const out = {};
8
+ for (const [key, value] of Object.entries(fields)){
9
+ out[key] = value instanceof Error ? serializeError(value) : value;
10
+ }
11
+ return out;
12
+ }
13
+ /**
14
+ * Builds an entry from a log call's arguments:
15
+ *
16
+ * - `log.info("text")`, `log.info(42)` → `msg`
17
+ * - `log.error(err)` → `msg` is `err.message`, `err` the serialized error
18
+ * - `log.info({ fields })`, `log.info({ fields }, "text")` → `fields` (a string
19
+ * `msg` field becomes the message)
20
+ * - `log.info("text", { fields })` → `msg` + `fields`
21
+ * - `log.error("text", err)` → `msg` + `err`
22
+ * - `log.info("text", value)` → `msg` + `fields.data`; any further arguments go
23
+ * in `fields.args`
24
+ */ function from(level, name, [first, ...rest], { bindings, redactionKeys }) {
25
+ let msg;
26
+ let err;
27
+ let fields = {};
28
+ if (first instanceof Error) {
29
+ err = first;
30
+ msg = first.message;
31
+ } else if (isFields(first)) {
32
+ const { msg: fieldMsg, ...others } = first;
33
+ fields = others;
34
+ if (typeof fieldMsg === "string") {
35
+ msg = fieldMsg;
36
+ } else if (fieldMsg !== undefined) {
37
+ fields.msg = fieldMsg;
38
+ }
39
+ if (typeof rest[0] === "string") {
40
+ msg = rest.shift();
41
+ }
42
+ } else if (first !== undefined) {
43
+ msg = String(first);
44
+ }
45
+ const [second, ...extra] = rest;
46
+ if (second instanceof Error && err == null) {
47
+ err = second;
48
+ } else if (isFields(second)) {
49
+ fields = {
50
+ ...fields,
51
+ ...second
52
+ };
53
+ } else if (second !== undefined) {
54
+ fields.data = second;
55
+ }
56
+ if (extra.length > 0) {
57
+ fields.args = extra;
58
+ }
59
+ const allFields = serializeErrors({
60
+ ...bindings,
61
+ ...fields
62
+ });
63
+ const entry = {
64
+ level,
65
+ name,
66
+ fields: redactionKeys == null ? allFields : redact.object(allFields, redactionKeys)
67
+ };
68
+ if (msg !== undefined) {
69
+ entry.msg = msg;
70
+ }
71
+ if (err != null) {
72
+ const serialized = serializeError(err);
73
+ entry.err = redactionKeys == null ? serialized : redact.object(serialized, redactionKeys);
74
+ }
75
+ return entry;
76
+ }
77
+ export const logEntry = {
78
+ from
79
+ };
@@ -2,11 +2,52 @@ import { LogLevels } from "./types.js";
2
2
  export function formatError(err) {
3
3
  return err.stack ?? err.message;
4
4
  }
5
+ /** How many causes deep `serializeError` follows by default. */ export const DefaultErrorCauseDepth = 3;
6
+ /**
7
+ * Plain-object form of an error for structured logs. An `Error` cause, or an
8
+ * `Error` in another own property, is serialized the same way, up to
9
+ * `causeDepth` levels; any other value is kept as it is.
10
+ */ export function serializeError(err, causeDepth = DefaultErrorCauseDepth) {
11
+ const out = {
12
+ name: err.name,
13
+ message: err.message
14
+ };
15
+ if (err.stack != null) {
16
+ out.stack = err.stack;
17
+ }
18
+ for (const [key, value] of Object.entries(err)){
19
+ if (key === "cause" || key in out) {
20
+ continue;
21
+ }
22
+ if (!(value instanceof Error)) {
23
+ out[key] = value;
24
+ } else if (causeDepth > 0) {
25
+ out[key] = serializeError(value, causeDepth - 1);
26
+ }
27
+ }
28
+ const { cause } = err;
29
+ if (cause instanceof Error) {
30
+ if (causeDepth > 0) {
31
+ out.cause = serializeError(cause, causeDepth - 1);
32
+ }
33
+ } else if (cause !== undefined) {
34
+ out.cause = cause;
35
+ }
36
+ return out;
37
+ }
5
38
  export class LogAdapter {
6
39
  flush(cb) {
7
40
  cb?.();
8
41
  }
9
- // biome-ignore lint/suspicious/noExplicitAny: Generic utility method needs flexible typing
42
+ retire() {
43
+ // Console / no-op adapters have nothing to release.
44
+ }
45
+ async stop() {
46
+ await this[Symbol.asyncDispose]();
47
+ }
48
+ async [Symbol.asyncDispose]() {
49
+ // Console / no-op adapters have nothing to release.
50
+ }
10
51
  getLogLevels(options) {
11
52
  const { customOnly, customLevels } = options;
12
53
  if (customOnly) {
@@ -23,5 +64,3 @@ export class LogAdapter {
23
64
  return unique;
24
65
  }
25
66
  }
26
-
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL2xvZ2dlci5hZGFwdGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgTG9nZ2VyIH0gZnJvbSBcIi4vbG9nZ2VyLnR5cGUuanNcIjtcbmltcG9ydCB7IExvZ0xldmVscywgdHlwZSBTY3JpYmVPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXMuanNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEVycm9yKGVycjogRXJyb3IpOiBzdHJpbmcge1xuXHRyZXR1cm4gZXJyLnN0YWNrID8/IGVyci5tZXNzYWdlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExvZ2dlckFkYXB0ZXIge1xuXHRjb25maWd1cmU8VCBleHRlbmRzIHN0cmluZyA9IG5ldmVyLCBDdXN0b21Pbmx5IGV4dGVuZHMgdHJ1ZSB8IGZhbHNlID0gZmFsc2U+KFxuXHRcdG9wdGlvbnM6IFNjcmliZU9wdGlvbnM8VCwgQ3VzdG9tT25seT4sXG5cdCk7XG5cdGdldExvZ2dlcjxUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsIEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlIHwgZmFsc2UgPSBmYWxzZT4oXG5cdFx0bmFtZTogc3RyaW5nLFxuXHQpOiBMb2dnZXI8VCwgQ3VzdG9tT25seT47XG5cdGZsdXNoKGNiPzogKCkgPT4gdm9pZCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMb2dBZGFwdGVyIGltcGxlbWVudHMgTG9nZ2VyQWRhcHRlciB7XG5cdHB1YmxpYyBhYnN0cmFjdCBjb25maWd1cmU8VCBleHRlbmRzIHN0cmluZyA9IG5ldmVyLCBDdXN0b21Pbmx5IGV4dGVuZHMgdHJ1ZSB8IGZhbHNlID0gZmFsc2U+KFxuXHRcdG9wdGlvbnM6IFNjcmliZU9wdGlvbnM8VCwgQ3VzdG9tT25seT4sXG5cdCk7XG5cblx0cHVibGljIGFic3RyYWN0IGdldExvZ2dlcjxUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsIEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlIHwgZmFsc2UgPSBmYWxzZT4oXG5cdFx0bmFtZTogc3RyaW5nLFxuXHQpOiBMb2dnZXI8VCwgQ3VzdG9tT25seT47XG5cblx0cHVibGljIGZsdXNoKGNiPzogKCkgPT4gdm9pZCk6IHZvaWQge1xuXHRcdGNiPy4oKTtcblx0fVxuXG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogR2VuZXJpYyB1dGlsaXR5IG1ldGhvZCBuZWVkcyBmbGV4aWJsZSB0eXBpbmdcblx0cHJvdGVjdGVkIGdldExvZ0xldmVscyhvcHRpb25zOiBTY3JpYmVPcHRpb25zPGFueSwgYW55Pik6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4ge1xuXHRcdGNvbnN0IHsgY3VzdG9tT25seSwgY3VzdG9tTGV2ZWxzIH0gPSBvcHRpb25zO1xuXHRcdGlmIChjdXN0b21Pbmx5KSB7XG5cdFx0XHRyZXR1cm4gY3VzdG9tTGV2ZWxzO1xuXHRcdH1cblx0XHRjb25zdCBsZXZlbHMgPSB0aGlzLmdldFVuaXF1ZUxldmVscyhMb2dMZXZlbHMsIGN1c3RvbUxldmVscyk7XG5cdFx0cmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhsZXZlbHMpO1xuXHR9XG5cblx0cHJvdGVjdGVkIGdldFVuaXF1ZUxldmVscyhcblx0XHRkZWZhdWx0TGV2ZWxzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+LFxuXHRcdGN1c3RvbUxldmVsczogUmVjb3JkPHN0cmluZywgbnVtYmVyPixcblx0KSB7XG5cdFx0Y29uc3QgZGVmYXVsdEVudHJpZXMgPSBPYmplY3QuZW50cmllcyhkZWZhdWx0TGV2ZWxzID8/IHt9KTtcblx0XHRjb25zdCBjdXN0b21FbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoY3VzdG9tTGV2ZWxzID8/IHt9KTtcblx0XHRjb25zdCBkZWZhdWx0Tm90SW5DdXN0b20gPSBkZWZhdWx0RW50cmllcy5maWx0ZXIoXG5cdFx0XHQoW2RrXSkgPT4gY3VzdG9tRW50cmllcy5maW5kSW5kZXgoKFtja10pID0+IGNrID09PSBkaykgPT09IC0xLFxuXHRcdCk7XG5cblx0XHRjb25zdCB1bmlxdWUgPSBkZWZhdWx0Tm90SW5DdXN0b20uY29uY2F0KGN1c3RvbUVudHJpZXMpO1xuXHRcdHJldHVybiB1bmlxdWU7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJMb2dMZXZlbHMiLCJmb3JtYXRFcnJvciIsImVyciIsInN0YWNrIiwibWVzc2FnZSIsIkxvZ0FkYXB0ZXIiLCJmbHVzaCIsImNiIiwiZ2V0TG9nTGV2ZWxzIiwib3B0aW9ucyIsImN1c3RvbU9ubHkiLCJjdXN0b21MZXZlbHMiLCJsZXZlbHMiLCJnZXRVbmlxdWVMZXZlbHMiLCJPYmplY3QiLCJmcm9tRW50cmllcyIsImRlZmF1bHRMZXZlbHMiLCJkZWZhdWx0RW50cmllcyIsImVudHJpZXMiLCJjdXN0b21FbnRyaWVzIiwiZGVmYXVsdE5vdEluQ3VzdG9tIiwiZmlsdGVyIiwiZGsiLCJmaW5kSW5kZXgiLCJjayIsInVuaXF1ZSIsImNvbmNhdCJdLCJtYXBwaW5ncyI6IkFBQ0EsU0FBU0EsU0FBUyxRQUE0QixhQUFhO0FBRTNELE9BQU8sU0FBU0MsWUFBWUMsR0FBVTtJQUNyQyxPQUFPQSxJQUFJQyxLQUFLLElBQUlELElBQUlFLE9BQU87QUFDaEM7QUFZQSxPQUFPLE1BQWVDO0lBU2RDLE1BQU1DLEVBQWUsRUFBUTtRQUNuQ0E7SUFDRDtJQUVBLDJGQUEyRjtJQUNqRkMsYUFBYUMsT0FBZ0MsRUFBMEI7UUFDaEYsTUFBTSxFQUFFQyxVQUFVLEVBQUVDLFlBQVksRUFBRSxHQUFHRjtRQUNyQyxJQUFJQyxZQUFZO1lBQ2YsT0FBT0M7UUFDUjtRQUNBLE1BQU1DLFNBQVMsSUFBSSxDQUFDQyxlQUFlLENBQUNiLFdBQVdXO1FBQy9DLE9BQU9HLE9BQU9DLFdBQVcsQ0FBQ0g7SUFDM0I7SUFFVUMsZ0JBQ1RHLGFBQXFDLEVBQ3JDTCxZQUFvQyxFQUNuQztRQUNELE1BQU1NLGlCQUFpQkgsT0FBT0ksT0FBTyxDQUFDRixpQkFBaUIsQ0FBQztRQUN4RCxNQUFNRyxnQkFBZ0JMLE9BQU9JLE9BQU8sQ0FBQ1AsZ0JBQWdCLENBQUM7UUFDdEQsTUFBTVMscUJBQXFCSCxlQUFlSSxNQUFNLENBQy9DLENBQUMsQ0FBQ0MsR0FBRyxHQUFLSCxjQUFjSSxTQUFTLENBQUMsQ0FBQyxDQUFDQyxHQUFHLEdBQUtBLE9BQU9GLFFBQVEsQ0FBQztRQUc3RCxNQUFNRyxTQUFTTCxtQkFBbUJNLE1BQU0sQ0FBQ1A7UUFDekMsT0FBT007SUFDUjtBQUNEIn0=
@@ -1,23 +1,81 @@
1
1
  import { ConsoleAdapter } from "./console.adapter.js";
2
2
  import { resolveLogLevel } from "./env.js";
3
3
  import { LoggingConfigurationError } from "./errors.js";
4
+ import { logEntry } from "./log-entry.js";
4
5
  import { DefaultLogLevel, DefaultRedactions } from "./types.js";
5
6
  export class scribe {
6
7
  loggerProvider;
8
+ /** True after `configure({ adapter })` — the constructor’s ConsoleAdapter is only a fallback. */ adapterConfigured = false;
9
+ defaultAdapterWarned = false;
10
+ tap;
7
11
  static instance = new scribe();
8
12
  static logger(name, customLevels) {
9
- return scribe.instance.getLogger(name, customLevels);
13
+ // Apply custom levels once against the active adapter; the live handle
14
+ // re-resolves the underlying logger on each use.
15
+ if (customLevels) {
16
+ scribe.instance.getLogger(name, customLevels);
17
+ }
18
+ return scribe.createLiveLogger(name);
10
19
  }
11
20
  static configure(configOptions) {
21
+ const previous = scribe.instance;
22
+ // Sync: stop writes into the old ThreadStream before a new worker starts.
23
+ previous.retire();
12
24
  scribe.instance = new scribe();
13
- return scribe.instance.configure(configOptions);
14
- }
15
- static get extend() {
16
- return scribe.instance;
25
+ scribe.instance.configure(configOptions);
26
+ // Async drain of the retired adapter (flush / end). Flux/App.dispose may
27
+ // have already done this; reconfigure without stop still needs it.
28
+ void previous.stop();
29
+ return (name)=>scribe.logger(name);
17
30
  }
18
31
  static flush(cb) {
19
32
  scribe.instance.loggerProvider.flush(cb);
20
33
  }
34
+ /** Synchronously stop accepting writes on the active adapter. */ static retire() {
35
+ scribe.instance.retire();
36
+ }
37
+ /** Drain the active adapter and release workers / destinations. */ static async stop() {
38
+ await scribe.instance.stop();
39
+ }
40
+ /**
41
+ * Module-level `const log = scribe.logger(...)` must follow a later
42
+ * `scribe.configure()` (CLI / Flux / HotReloadServer). Forward every use to
43
+ * the active adapter logger for `name`, and `child(fields)` to a live handle
44
+ * that adds `bindings`, so children follow a reconfigure too.
45
+ */ static createLiveLogger(name, bindings = {}) {
46
+ const bound = Object.keys(bindings).length > 0;
47
+ const resolve = ()=>{
48
+ const root = scribe.instance.getLogger(name);
49
+ return bound ? root.child(bindings) : root;
50
+ };
51
+ return new Proxy({}, {
52
+ get (_target, prop) {
53
+ if (prop === "child") {
54
+ return (fields)=>scribe.createLiveLogger(name, {
55
+ ...bindings,
56
+ ...fields
57
+ });
58
+ }
59
+ const underlying = resolve();
60
+ const value = Reflect.get(underlying, prop, underlying);
61
+ if (typeof value !== "function") {
62
+ return value;
63
+ }
64
+ const method = value.bind(underlying);
65
+ const instance = scribe.instance;
66
+ if (instance.tap == null || typeof prop !== "string" || !Object.hasOwn(underlying.logLevels, prop) || !underlying.isLevelEnabled(prop)) {
67
+ return method;
68
+ }
69
+ return (...args)=>{
70
+ method(...args);
71
+ instance.notifyTap(prop, name ?? "default", args, bindings);
72
+ };
73
+ },
74
+ has (_target, prop) {
75
+ return Reflect.has(resolve(), prop);
76
+ }
77
+ });
78
+ }
21
79
  constructor(){
22
80
  // Initialize with default console adapter
23
81
  this.loggerProvider = new ConsoleAdapter();
@@ -25,13 +83,32 @@ export class scribe {
25
83
  this.loggerProvider.configure(defaultOptions);
26
84
  }
27
85
  configure(configOptions) {
28
- const { adapter, options } = configOptions;
86
+ const { adapter, options, tap } = configOptions;
87
+ const previous = this.loggerProvider;
88
+ if (previous !== adapter) {
89
+ previous.retire();
90
+ }
29
91
  this.loggerProvider = adapter;
92
+ this.adapterConfigured = true;
93
+ this.tap = tap;
30
94
  const defaultsAndOptions = this.mergeDefaults(options);
31
95
  adapter.configure(defaultsAndOptions);
32
- return (name)=>adapter.getLogger(name);
96
+ if (previous !== adapter) {
97
+ void previous.stop();
98
+ }
99
+ return (name)=>scribe.logger(name);
100
+ }
101
+ retire() {
102
+ this.loggerProvider.retire();
103
+ }
104
+ async stop() {
105
+ await this.loggerProvider.stop();
106
+ }
107
+ async [Symbol.asyncDispose]() {
108
+ await this.stop();
33
109
  }
34
110
  getLogger(name, customLevels) {
111
+ this.warnIfDefaultAdapter();
35
112
  // If custom levels are provided, we need to reconfigure the adapter
36
113
  if (customLevels) {
37
114
  const currentOptions = this.mergeDefaults({
@@ -43,6 +120,30 @@ export class scribe {
43
120
  this.supportsLevels(customLevels, logger);
44
121
  return logger;
45
122
  }
123
+ notifyTap(level, name, args, bindings) {
124
+ const tap = this.tap;
125
+ if (tap == null) {
126
+ return;
127
+ }
128
+ try {
129
+ tap(logEntry.from(level, name, args, {
130
+ bindings
131
+ }));
132
+ } catch (err) {
133
+ // Not swallowed: the logging call returns, the runtime reports the tap's error.
134
+ queueMicrotask(()=>{
135
+ throw err;
136
+ });
137
+ }
138
+ }
139
+ warnIfDefaultAdapter() {
140
+ if (this.adapterConfigured || this.defaultAdapterWarned) {
141
+ return;
142
+ }
143
+ this.defaultAdapterWarned = true;
144
+ // console.warn, not the stderr stream: the facade runs in browsers and Workers too.
145
+ console.warn("[scribe] No logger adapter configured; using the default ConsoleAdapter. " + "Configure an adapter at your composition root (for production, prefer " + "@decohere/scribe-pino → JSON on stdout). See " + "https://github.com/typesmiths/decohere/blob/main/projects/scribe/README.md");
146
+ }
46
147
  supportsLevels(customLevels, logger) {
47
148
  if (!customLevels) {
48
149
  return;
@@ -57,12 +158,12 @@ export class scribe {
57
158
  }
58
159
  mergeDefaults(options) {
59
160
  const logLevel = resolveLogLevel(options?.logLevel) ?? DefaultLogLevel;
161
+ // Resolved logLevel must win over options spread (invalid explicit values
162
+ // would otherwise stick).
60
163
  return {
61
- logLevel,
62
164
  redactions: DefaultRedactions,
63
- ...options
165
+ ...options,
166
+ logLevel
64
167
  };
65
168
  }
66
169
  }
67
-
68
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL2xvZ2dlci5mYWN0b3J5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnNvbGVBZGFwdGVyIH0gZnJvbSBcIi4vY29uc29sZS5hZGFwdGVyLmpzXCI7XG5pbXBvcnQgeyByZXNvbHZlTG9nTGV2ZWwgfSBmcm9tIFwiLi9lbnYuanNcIjtcbmltcG9ydCB7IExvZ2dpbmdDb25maWd1cmF0aW9uRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnMuanNcIjtcbmltcG9ydCB0eXBlIHsgTG9nZ2VyQWRhcHRlciB9IGZyb20gXCIuL2xvZ2dlci5hZGFwdGVyLmpzXCI7XG5pbXBvcnQgdHlwZSB7IExvZ2dlciB9IGZyb20gXCIuL2xvZ2dlci50eXBlLmpzXCI7XG5pbXBvcnQgeyBEZWZhdWx0TG9nTGV2ZWwsIERlZmF1bHRSZWRhY3Rpb25zLCB0eXBlIFNjcmliZU9wdGlvbnMgfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuXG50eXBlIExvZ2dlckZhY3RvcnlPcHRpb25zPFxuXHRUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsXG5cdEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlIHwgZmFsc2UgPSBmYWxzZSxcbj4gPSB7XG5cdG9wdGlvbnM/OiBTY3JpYmVPcHRpb25zPFQsIEN1c3RvbU9ubHk+O1xuXHRhZGFwdGVyOiBMb2dnZXJBZGFwdGVyO1xufTtcblxuZXhwb3J0IGNsYXNzIHNjcmliZSB7XG5cdHByaXZhdGUgbG9nZ2VyUHJvdmlkZXI6IExvZ2dlckFkYXB0ZXI7XG5cdHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBzY3JpYmUgPSBuZXcgc2NyaWJlKCk7XG5cblx0cHVibGljIHN0YXRpYyBsb2dnZXI8VCBleHRlbmRzIHN0cmluZyA9IG5ldmVyLCBDdXN0b21Pbmx5IGV4dGVuZHMgdHJ1ZSB8IGZhbHNlID0gZmFsc2U+KFxuXHRcdG5hbWU/OiBzdHJpbmcsXG5cdFx0Y3VzdG9tTGV2ZWxzPzoge1xuXHRcdFx0W2xldmVsIGluIFRdOiBudW1iZXI7XG5cdFx0fSxcblx0KTogTG9nZ2VyPFQsIEN1c3RvbU9ubHk+IHtcblx0XHRyZXR1cm4gc2NyaWJlLmluc3RhbmNlLmdldExvZ2dlcjxULCBDdXN0b21Pbmx5PihuYW1lLCBjdXN0b21MZXZlbHMpIGFzIExvZ2dlcjxcblx0XHRcdFQsXG5cdFx0XHRDdXN0b21Pbmx5XG5cdFx0Pjtcblx0fVxuXG5cdHB1YmxpYyBzdGF0aWMgY29uZmlndXJlPFQgZXh0ZW5kcyBzdHJpbmcgPSBuZXZlciwgQ3VzdG9tT25seSBleHRlbmRzIHRydWUgfCBmYWxzZSA9IGZhbHNlPihcblx0XHRjb25maWdPcHRpb25zOiBMb2dnZXJGYWN0b3J5T3B0aW9uczxULCBDdXN0b21Pbmx5Pixcblx0KSB7XG5cdFx0c2NyaWJlLmluc3RhbmNlID0gbmV3IHNjcmliZSgpO1xuXHRcdHJldHVybiBzY3JpYmUuaW5zdGFuY2UuY29uZmlndXJlPFQsIEN1c3RvbU9ubHk+KGNvbmZpZ09wdGlvbnMpO1xuXHR9XG5cblx0cHVibGljIHN0YXRpYyBnZXQgZXh0ZW5kKCkge1xuXHRcdHJldHVybiBzY3JpYmUuaW5zdGFuY2U7XG5cdH1cblxuXHRwdWJsaWMgc3RhdGljIGZsdXNoKGNiPzogKCkgPT4gdm9pZCk6IHZvaWQge1xuXHRcdHNjcmliZS5pbnN0YW5jZS5sb2dnZXJQcm92aWRlci5mbHVzaChjYik7XG5cdH1cblxuXHRwdWJsaWMgY29uc3RydWN0b3IoKSB7XG5cdFx0Ly8gSW5pdGlhbGl6ZSB3aXRoIGRlZmF1bHQgY29uc29sZSBhZGFwdGVyXG5cdFx0dGhpcy5sb2dnZXJQcm92aWRlciA9IG5ldyBDb25zb2xlQWRhcHRlcigpO1xuXHRcdGNvbnN0IGRlZmF1bHRPcHRpb25zID0gdGhpcy5tZXJnZURlZmF1bHRzKCk7XG5cdFx0dGhpcy5sb2dnZXJQcm92aWRlci5jb25maWd1cmUoZGVmYXVsdE9wdGlvbnMpO1xuXHR9XG5cblx0cHVibGljIGNvbmZpZ3VyZTxUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsIEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlIHwgZmFsc2UgPSBmYWxzZT4oXG5cdFx0Y29uZmlnT3B0aW9uczogTG9nZ2VyRmFjdG9yeU9wdGlvbnM8VCwgQ3VzdG9tT25seT4sXG5cdCk6IChuYW1lPzogc3RyaW5nKSA9PiBMb2dnZXI8VCwgQ3VzdG9tT25seT4ge1xuXHRcdGNvbnN0IHsgYWRhcHRlciwgb3B0aW9ucyB9ID0gY29uZmlnT3B0aW9ucztcblx0XHR0aGlzLmxvZ2dlclByb3ZpZGVyID0gYWRhcHRlcjtcblx0XHRjb25zdCBkZWZhdWx0c0FuZE9wdGlvbnMgPSB0aGlzLm1lcmdlRGVmYXVsdHM8VCwgQ3VzdG9tT25seT4ob3B0aW9ucyk7XG5cdFx0YWRhcHRlci5jb25maWd1cmUoZGVmYXVsdHNBbmRPcHRpb25zKTtcblx0XHRyZXR1cm4gKG5hbWU/OiBzdHJpbmcpID0+IGFkYXB0ZXIuZ2V0TG9nZ2VyKG5hbWUpIGFzIExvZ2dlcjxULCBDdXN0b21Pbmx5Pjtcblx0fVxuXG5cdHB1YmxpYyBnZXRMb2dnZXI8VCBleHRlbmRzIHN0cmluZyA9IG5ldmVyLCBDdXN0b21Pbmx5IGV4dGVuZHMgdHJ1ZSB8IGZhbHNlID0gZmFsc2U+KFxuXHRcdG5hbWU/OiBzdHJpbmcsXG5cdFx0Y3VzdG9tTGV2ZWxzPzoge1xuXHRcdFx0W2xldmVsIGluIFRdOiBudW1iZXI7XG5cdFx0fSxcblx0KTogTG9nZ2VyPFQsIEN1c3RvbU9ubHk+IHtcblx0XHQvLyBJZiBjdXN0b20gbGV2ZWxzIGFyZSBwcm92aWRlZCwgd2UgbmVlZCB0byByZWNvbmZpZ3VyZSB0aGUgYWRhcHRlclxuXHRcdGlmIChjdXN0b21MZXZlbHMpIHtcblx0XHRcdGNvbnN0IGN1cnJlbnRPcHRpb25zID0gdGhpcy5tZXJnZURlZmF1bHRzKHsgY3VzdG9tTGV2ZWxzIH0pO1xuXHRcdFx0dGhpcy5sb2dnZXJQcm92aWRlci5jb25maWd1cmUoY3VycmVudE9wdGlvbnMpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGxvZ2dlciA9IHRoaXMubG9nZ2VyUHJvdmlkZXIuZ2V0TG9nZ2VyKG5hbWUpIGFzIExvZ2dlcjxULCBDdXN0b21Pbmx5Pjtcblx0XHR0aGlzLnN1cHBvcnRzTGV2ZWxzKGN1c3RvbUxldmVscywgbG9nZ2VyKTtcblx0XHRyZXR1cm4gbG9nZ2VyO1xuXHR9XG5cblx0cHJpdmF0ZSBzdXBwb3J0c0xldmVsczxUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsIEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlID0gdW5kZWZpbmVkPihcblx0XHRjdXN0b21MZXZlbHM6IHtcblx0XHRcdFtsZXZlbCBpbiBUXTogbnVtYmVyO1xuXHRcdH0sXG5cdFx0bG9nZ2VyOiBMb2dnZXI8VCwgQ3VzdG9tT25seT4sXG5cdCkge1xuXHRcdGlmICghY3VzdG9tTGV2ZWxzKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgbWlzc2luZ0xldmVsID0gT2JqZWN0LmVudHJpZXMoY3VzdG9tTGV2ZWxzKS5maW5kKFxuXHRcdFx0KGtleSkgPT4gIWxvZ2dlci5sb2dMZXZlbHNba2V5LmF0KDApLnRvU3RyaW5nKCldLFxuXHRcdCk7XG5cblx0XHRpZiAobWlzc2luZ0xldmVsICE9IG51bGwpIHtcblx0XHRcdHRocm93IG5ldyBMb2dnaW5nQ29uZmlndXJhdGlvbkVycm9yKFxuXHRcdFx0XHRgQ3VycmVudCBsb2dnZXIgd2FzIG5vdCBjb25maWd1cmVkIGZvciBjdXN0b20gbGV2ZWwgJHttaXNzaW5nTGV2ZWx9LCB2YWxpZCBsZXZlbHMgYXJlOiAke0pTT04uc3RyaW5naWZ5KGxvZ2dlci5sb2dMZXZlbHMpfWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRyZXR1cm4geyBtaXNzaW5nTGV2ZWwgfTtcblx0fVxuXG5cdHByaXZhdGUgbWVyZ2VEZWZhdWx0czxUIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsIEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlIHwgZmFsc2UgPSBmYWxzZT4oXG5cdFx0b3B0aW9ucz86IFNjcmliZU9wdGlvbnM8VCwgQ3VzdG9tT25seT4sXG5cdCk6IFNjcmliZU9wdGlvbnM8VCwgQ3VzdG9tT25seT4ge1xuXHRcdGNvbnN0IGxvZ0xldmVsID0gcmVzb2x2ZUxvZ0xldmVsKG9wdGlvbnM/LmxvZ0xldmVsKSA/PyBEZWZhdWx0TG9nTGV2ZWw7XG5cdFx0cmV0dXJuIHsgbG9nTGV2ZWwsIHJlZGFjdGlvbnM6IERlZmF1bHRSZWRhY3Rpb25zLCAuLi5vcHRpb25zIH07XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJDb25zb2xlQWRhcHRlciIsInJlc29sdmVMb2dMZXZlbCIsIkxvZ2dpbmdDb25maWd1cmF0aW9uRXJyb3IiLCJEZWZhdWx0TG9nTGV2ZWwiLCJEZWZhdWx0UmVkYWN0aW9ucyIsInNjcmliZSIsImxvZ2dlclByb3ZpZGVyIiwiaW5zdGFuY2UiLCJsb2dnZXIiLCJuYW1lIiwiY3VzdG9tTGV2ZWxzIiwiZ2V0TG9nZ2VyIiwiY29uZmlndXJlIiwiY29uZmlnT3B0aW9ucyIsImV4dGVuZCIsImZsdXNoIiwiY2IiLCJkZWZhdWx0T3B0aW9ucyIsIm1lcmdlRGVmYXVsdHMiLCJhZGFwdGVyIiwib3B0aW9ucyIsImRlZmF1bHRzQW5kT3B0aW9ucyIsImN1cnJlbnRPcHRpb25zIiwic3VwcG9ydHNMZXZlbHMiLCJtaXNzaW5nTGV2ZWwiLCJPYmplY3QiLCJlbnRyaWVzIiwiZmluZCIsImtleSIsImxvZ0xldmVscyIsImF0IiwidG9TdHJpbmciLCJKU09OIiwic3RyaW5naWZ5IiwibG9nTGV2ZWwiLCJyZWRhY3Rpb25zIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxjQUFjLFFBQVEsdUJBQXVCO0FBQ3RELFNBQVNDLGVBQWUsUUFBUSxXQUFXO0FBQzNDLFNBQVNDLHlCQUF5QixRQUFRLGNBQWM7QUFHeEQsU0FBU0MsZUFBZSxFQUFFQyxpQkFBaUIsUUFBNEIsYUFBYTtBQVVwRixPQUFPLE1BQU1DO0lBQ0pDLGVBQThCO0lBQ3RDLE9BQWVDLFdBQW1CLElBQUlGLFNBQVM7SUFFL0MsT0FBY0csT0FDYkMsSUFBYSxFQUNiQyxZQUVDLEVBQ3VCO1FBQ3hCLE9BQU9MLE9BQU9FLFFBQVEsQ0FBQ0ksU0FBUyxDQUFnQkYsTUFBTUM7SUFJdkQ7SUFFQSxPQUFjRSxVQUNiQyxhQUFrRCxFQUNqRDtRQUNEUixPQUFPRSxRQUFRLEdBQUcsSUFBSUY7UUFDdEIsT0FBT0EsT0FBT0UsUUFBUSxDQUFDSyxTQUFTLENBQWdCQztJQUNqRDtJQUVBLFdBQWtCQyxTQUFTO1FBQzFCLE9BQU9ULE9BQU9FLFFBQVE7SUFDdkI7SUFFQSxPQUFjUSxNQUFNQyxFQUFlLEVBQVE7UUFDMUNYLE9BQU9FLFFBQVEsQ0FBQ0QsY0FBYyxDQUFDUyxLQUFLLENBQUNDO0lBQ3RDO0lBRUEsYUFBcUI7UUFDcEIsMENBQTBDO1FBQzFDLElBQUksQ0FBQ1YsY0FBYyxHQUFHLElBQUlOO1FBQzFCLE1BQU1pQixpQkFBaUIsSUFBSSxDQUFDQyxhQUFhO1FBQ3pDLElBQUksQ0FBQ1osY0FBYyxDQUFDTSxTQUFTLENBQUNLO0lBQy9CO0lBRU9MLFVBQ05DLGFBQWtELEVBQ1A7UUFDM0MsTUFBTSxFQUFFTSxPQUFPLEVBQUVDLE9BQU8sRUFBRSxHQUFHUDtRQUM3QixJQUFJLENBQUNQLGNBQWMsR0FBR2E7UUFDdEIsTUFBTUUscUJBQXFCLElBQUksQ0FBQ0gsYUFBYSxDQUFnQkU7UUFDN0RELFFBQVFQLFNBQVMsQ0FBQ1M7UUFDbEIsT0FBTyxDQUFDWixPQUFrQlUsUUFBUVIsU0FBUyxDQUFDRjtJQUM3QztJQUVPRSxVQUNORixJQUFhLEVBQ2JDLFlBRUMsRUFDdUI7UUFDeEIsb0VBQW9FO1FBQ3BFLElBQUlBLGNBQWM7WUFDakIsTUFBTVksaUJBQWlCLElBQUksQ0FBQ0osYUFBYSxDQUFDO2dCQUFFUjtZQUFhO1lBQ3pELElBQUksQ0FBQ0osY0FBYyxDQUFDTSxTQUFTLENBQUNVO1FBQy9CO1FBRUEsTUFBTWQsU0FBUyxJQUFJLENBQUNGLGNBQWMsQ0FBQ0ssU0FBUyxDQUFDRjtRQUM3QyxJQUFJLENBQUNjLGNBQWMsQ0FBQ2IsY0FBY0Y7UUFDbEMsT0FBT0E7SUFDUjtJQUVRZSxlQUNQYixZQUVDLEVBQ0RGLE1BQTZCLEVBQzVCO1FBQ0QsSUFBSSxDQUFDRSxjQUFjO1lBQ2xCO1FBQ0Q7UUFFQSxNQUFNYyxlQUFlQyxPQUFPQyxPQUFPLENBQUNoQixjQUFjaUIsSUFBSSxDQUNyRCxDQUFDQyxNQUFRLENBQUNwQixPQUFPcUIsU0FBUyxDQUFDRCxJQUFJRSxFQUFFLENBQUMsR0FBR0MsUUFBUSxHQUFHO1FBR2pELElBQUlQLGdCQUFnQixNQUFNO1lBQ3pCLE1BQU0sSUFBSXRCLDBCQUNULENBQUMsbURBQW1ELEVBQUVzQixhQUFhLG9CQUFvQixFQUFFUSxLQUFLQyxTQUFTLENBQUN6QixPQUFPcUIsU0FBUyxHQUFHO1FBRTdIO1FBQ0EsT0FBTztZQUFFTDtRQUFhO0lBQ3ZCO0lBRVFOLGNBQ1BFLE9BQXNDLEVBQ1A7UUFDL0IsTUFBTWMsV0FBV2pDLGdCQUFnQm1CLFNBQVNjLGFBQWEvQjtRQUN2RCxPQUFPO1lBQUUrQjtZQUFVQyxZQUFZL0I7WUFBbUIsR0FBR2dCLE9BQU87UUFBQztJQUM5RDtBQUNEIn0=
@@ -1,3 +1 @@
1
1
  export { };
2
-
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjcmliZS9zY3JpYmUvc3JjL2xvZ2dlci50eXBlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRGVmYXVsdExldmVscyB9IGZyb20gXCIuL3R5cGVzLmpzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUxvZ2dlciB7XG5cdGdldCBjdXJyZW50TGV2ZWwoKTogc3RyaW5nO1xuXHRnZXQgbG9nTGV2ZWxzKCk6IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG59XG5cbmV4cG9ydCB0eXBlIExvZ0ZuID0gKG1zZzogc3RyaW5nIHwgbnVtYmVyIHwgb2JqZWN0LCAuLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ7XG5cbmV4cG9ydCB0eXBlIExvZ2dlcjxcblx0Q3VzdG9tTGV2ZWxzIGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsXG5cdEN1c3RvbU9ubHkgZXh0ZW5kcyB0cnVlIHwgZmFsc2UgPSB1bmRlZmluZWQsXG4+ID0ge1xuXHRbSyBpbiBEZWZhdWx0TGV2ZWxzIGFzIEN1c3RvbU9ubHkgZXh0ZW5kcyBmYWxzZSA/IEsgOiBuZXZlcl06IExvZ0ZuO1xufSAmIHtcblx0W1Byb3BlcnR5IGluIEN1c3RvbUxldmVsc106IExvZ0ZuO1xufSAmIHtcblx0aXNMZXZlbEVuYWJsZWQobGV2ZWw6IHN0cmluZyk6IGJvb2xlYW47XG59ICYgQmFzZUxvZ2dlcjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFTQSxXQVNlIn0=