evlog 2.17.0 → 2.19.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/README.md +95 -2
- package/dist/adapters/axiom.d.mts +1 -1
- package/dist/adapters/axiom.mjs +2 -2
- package/dist/adapters/axiom.mjs.map +1 -1
- package/dist/adapters/better-stack.d.mts +1 -1
- package/dist/adapters/better-stack.mjs +2 -2
- package/dist/adapters/datadog.d.mts +1 -1
- package/dist/adapters/datadog.mjs +2 -2
- package/dist/adapters/fs.d.mts +1 -1
- package/dist/adapters/fs.mjs +2 -2
- package/dist/adapters/hyperdx.d.mts +1 -1
- package/dist/adapters/hyperdx.mjs +1 -1
- package/dist/adapters/memory.d.mts +116 -0
- package/dist/adapters/memory.d.mts.map +1 -0
- package/dist/adapters/memory.mjs +191 -0
- package/dist/adapters/memory.mjs.map +1 -0
- package/dist/adapters/otlp.d.mts +1 -1
- package/dist/adapters/otlp.mjs +4 -4
- package/dist/adapters/posthog.d.mts +1 -1
- package/dist/adapters/posthog.mjs +2 -2
- package/dist/adapters/sentry.d.mts +1 -1
- package/dist/adapters/sentry.mjs +3 -3
- package/dist/ai/index.d.mts +1 -1
- package/dist/{audit-pV5aLGP0.mjs → audit-BFwTUxBJ.mjs} +475 -151
- package/dist/audit-BFwTUxBJ.mjs.map +1 -0
- package/dist/{audit-CC8nfazi.d.mts → audit-BUAajsPU.d.mts} +126 -35
- package/dist/audit-BUAajsPU.d.mts.map +1 -0
- package/dist/better-auth/index.d.mts +1 -1
- package/dist/browser.d.mts +1 -1
- package/dist/{define-D6OJdSUH.mjs → define-Bpaymi-h.mjs} +2 -1
- package/dist/define-Bpaymi-h.mjs.map +1 -0
- package/dist/{define-MSdhzmXn.d.mts → define-DGwZkZ7x.d.mts} +8 -3
- package/dist/define-DGwZkZ7x.d.mts.map +1 -0
- package/dist/dev-terminal-D4UaEm17.mjs +54 -0
- package/dist/dev-terminal-D4UaEm17.mjs.map +1 -0
- package/dist/{dist-H3GIh-KK.mjs → dist-DdQWiZn8.mjs} +1 -1
- package/dist/{dist-H3GIh-KK.mjs.map → dist-DdQWiZn8.mjs.map} +1 -1
- package/dist/{drain-X7_5szSI.mjs → drain-D_fy7m0n.mjs} +3 -3
- package/dist/drain-D_fy7m0n.mjs.map +1 -0
- package/dist/elysia/index.d.mts +3 -3
- package/dist/elysia/index.d.mts.map +1 -1
- package/dist/elysia/index.mjs +8 -5
- package/dist/elysia/index.mjs.map +1 -1
- package/dist/enrich-drain-CG_2Nix-.mjs +122 -0
- package/dist/enrich-drain-CG_2Nix-.mjs.map +1 -0
- package/dist/{enricher-DxgML6IC.d.mts → enricher-CuMbbdqp.d.mts} +2 -2
- package/dist/{enricher-DxgML6IC.d.mts.map → enricher-CuMbbdqp.d.mts.map} +1 -1
- package/dist/{enricher-N0erZS87.mjs → enricher-DAWf2-Fx.mjs} +2 -2
- package/dist/{enricher-N0erZS87.mjs.map → enricher-DAWf2-Fx.mjs.map} +1 -1
- package/dist/enrichers.d.mts +2 -2
- package/dist/enrichers.mjs +2 -2
- package/dist/{error-CpbbtyXL.d.mts → error-DwajXSKM.d.mts} +2 -2
- package/dist/{error-CpbbtyXL.d.mts.map → error-DwajXSKM.d.mts.map} +1 -1
- package/dist/error.d.mts +1 -1
- package/dist/{errors-DySW1F9_.d.mts → errors-CAq8pYpW.d.mts} +2 -2
- package/dist/{errors-DySW1F9_.d.mts.map → errors-CAq8pYpW.d.mts.map} +1 -1
- package/dist/{errors-BQgyQ9xe.mjs → errors-DA0cyr8q.mjs} +1 -1
- package/dist/{errors-BQgyQ9xe.mjs.map → errors-DA0cyr8q.mjs.map} +1 -1
- package/dist/{event-1BMl7o0k.mjs → event-qwAv-7AZ.mjs} +1 -1
- package/dist/{event-1BMl7o0k.mjs.map → event-qwAv-7AZ.mjs.map} +1 -1
- package/dist/express/index.d.mts +3 -3
- package/dist/express/index.d.mts.map +1 -1
- package/dist/express/index.mjs +3 -3
- package/dist/express/index.mjs.map +1 -1
- package/dist/fastify/index.d.mts +9 -4
- package/dist/fastify/index.d.mts.map +1 -1
- package/dist/fastify/index.mjs +10 -8
- package/dist/fastify/index.mjs.map +1 -1
- package/dist/{fork-8u_zFOJq.mjs → fork-CYm453dq.mjs} +40 -14
- package/dist/fork-CYm453dq.mjs.map +1 -0
- package/dist/{headers-CU-QqnYg.mjs → headers-VtmnWcfn.mjs} +1 -1
- package/dist/{headers-CU-QqnYg.mjs.map → headers-VtmnWcfn.mjs.map} +1 -1
- package/dist/hono/index.d.mts +2 -2
- package/dist/hono/index.d.mts.map +1 -1
- package/dist/hono/index.mjs +10 -2
- package/dist/hono/index.mjs.map +1 -1
- package/dist/{http-6umVAKDW.mjs → http-Bept5EIC.mjs} +2 -2
- package/dist/{http-6umVAKDW.mjs.map → http-Bept5EIC.mjs.map} +1 -1
- package/dist/http.d.mts +1 -1
- package/dist/{index-o1_z4phv.d.mts → index-CE7kH0II.d.mts} +15 -8
- package/dist/index-CE7kH0II.d.mts.map +1 -0
- package/dist/index.d.mts +9 -9
- package/dist/index.mjs +9 -15
- package/dist/index.mjs.map +1 -1
- package/dist/{integration-DTZtjSqh.mjs → integration-CR601uyW.mjs} +3 -3
- package/dist/{integration-DTZtjSqh.mjs.map → integration-CR601uyW.mjs.map} +1 -1
- package/dist/{logger-DntcxxHg.d.mts → logger-BccCJUyD.d.mts} +11 -3
- package/dist/logger-BccCJUyD.d.mts.map +1 -0
- package/dist/logger.d.mts +2 -2
- package/dist/logger.mjs +2 -2
- package/dist/{middleware-U-lIAzHg.d.mts → middleware-DQ6-h8h0.d.mts} +9 -2
- package/dist/middleware-DQ6-h8h0.d.mts.map +1 -0
- package/dist/nestjs/index.d.mts +2 -2
- package/dist/nestjs/index.mjs +4 -4
- package/dist/next/client.d.mts +1 -1
- package/dist/next/index.d.mts +6 -5
- package/dist/next/index.d.mts.map +1 -1
- package/dist/next/index.mjs +36 -38
- package/dist/next/index.mjs.map +1 -1
- package/dist/next/instrumentation.d.mts +1 -1
- package/dist/next/instrumentation.mjs +1 -1
- package/dist/next/instrumentation.mjs.map +1 -1
- package/dist/nitro/errorHandler.mjs +10 -16
- package/dist/nitro/errorHandler.mjs.map +1 -1
- package/dist/nitro/module.d.mts +2 -2
- package/dist/nitro/module.d.mts.map +1 -1
- package/dist/nitro/module.mjs +8 -2
- package/dist/nitro/module.mjs.map +1 -1
- package/dist/nitro/plugin.mjs +37 -65
- package/dist/nitro/plugin.mjs.map +1 -1
- package/dist/nitro/v3/errorHandler.d.mts +0 -7
- package/dist/nitro/v3/errorHandler.mjs +13 -15
- package/dist/nitro/v3/errorHandler.mjs.map +1 -1
- package/dist/nitro/v3/index.d.mts +2 -2
- package/dist/nitro/v3/module.d.mts +1 -1
- package/dist/nitro/v3/module.d.mts.map +1 -1
- package/dist/nitro/v3/module.mjs +9 -4
- package/dist/nitro/v3/module.mjs.map +1 -1
- package/dist/nitro/v3/plugin.mjs +77 -44
- package/dist/nitro/v3/plugin.mjs.map +1 -1
- package/dist/nitro/v3/useLogger.d.mts +1 -1
- package/dist/nitro-ClRZLD1g.mjs +96 -0
- package/dist/nitro-ClRZLD1g.mjs.map +1 -0
- package/dist/{nitro-oZre8ab3.d.mts → nitro-zCXTylj4.d.mts} +7 -2
- package/dist/nitro-zCXTylj4.d.mts.map +1 -0
- package/dist/nitroConfigBridge-BkVWnSV3.mjs +164 -0
- package/dist/nitroConfigBridge-BkVWnSV3.mjs.map +1 -0
- package/dist/{nodeResponse-BkkionWl.mjs → nodeResponse-CIEEbrNE.mjs} +1 -1
- package/dist/{nodeResponse-BkkionWl.mjs.map → nodeResponse-CIEEbrNE.mjs.map} +1 -1
- package/dist/nuxt/module.d.mts +13 -4
- package/dist/nuxt/module.d.mts.map +1 -1
- package/dist/nuxt/module.mjs +11 -4
- package/dist/nuxt/module.mjs.map +1 -1
- package/dist/orpc/index.d.mts +115 -0
- package/dist/orpc/index.d.mts.map +1 -0
- package/dist/orpc/index.mjs +145 -0
- package/dist/orpc/index.mjs.map +1 -0
- package/dist/{package-v_MmOZeA.mjs → package-CUhII9DA.mjs} +2 -2
- package/dist/package-CUhII9DA.mjs.map +1 -0
- package/dist/{parseError-yVZ58wIK.d.mts → parseError-Cagr-Ctc.d.mts} +2 -2
- package/dist/parseError-Cagr-Ctc.d.mts.map +1 -0
- package/dist/pretty-error-CVVgwlTn.mjs +278 -0
- package/dist/pretty-error-CVVgwlTn.mjs.map +1 -0
- package/dist/pretty-error-snippet.node-c_bzjg7g.mjs +47 -0
- package/dist/pretty-error-snippet.node-c_bzjg7g.mjs.map +1 -0
- package/dist/react-router/index.d.mts +2 -2
- package/dist/react-router/index.mjs +5 -6
- package/dist/react-router/index.mjs.map +1 -1
- package/dist/{routes-CnIgYWf8.mjs → routes-4rMzRyTk.mjs} +1 -1
- package/dist/{routes-CnIgYWf8.mjs.map → routes-4rMzRyTk.mjs.map} +1 -1
- package/dist/runtime/client/log.d.mts +1 -1
- package/dist/runtime/server/routes/_evlog/ingest.post.mjs +28 -12
- package/dist/runtime/server/routes/_evlog/ingest.post.mjs.map +1 -1
- package/dist/runtime/server/useLogger.d.mts +1 -1
- package/dist/runtime/utils/parseError.d.mts +2 -2
- package/dist/runtime/utils/parseError.mjs +1 -1
- package/dist/{severity-R5Egq3qz.mjs → severity-CwXUSHt3.mjs} +1 -1
- package/dist/{severity-R5Egq3qz.mjs.map → severity-CwXUSHt3.mjs.map} +1 -1
- package/dist/{source-location-Dco0cRTz.mjs → source-location-xkDGiERl.mjs} +1 -1
- package/dist/{source-location-Dco0cRTz.mjs.map → source-location-xkDGiERl.mjs.map} +1 -1
- package/dist/{storage-Dwinmg8P.mjs → storage-7X37OToT.mjs} +2 -1
- package/dist/{storage-Dwinmg8P.mjs.map → storage-7X37OToT.mjs.map} +1 -1
- package/dist/stream.d.mts +1 -1
- package/dist/stream.mjs +1 -1
- package/dist/streamResponse-CmQ3qUbF.mjs +94 -0
- package/dist/streamResponse-CmQ3qUbF.mjs.map +1 -0
- package/dist/sveltekit/index.d.mts +3 -3
- package/dist/sveltekit/index.d.mts.map +1 -1
- package/dist/sveltekit/index.mjs +48 -16
- package/dist/sveltekit/index.mjs.map +1 -1
- package/dist/toolkit.d.mts +38 -7
- package/dist/toolkit.d.mts.map +1 -1
- package/dist/toolkit.mjs +15 -14
- package/dist/types.d.mts +2 -2
- package/dist/{useLogger-BsPL4AQm.d.mts → useLogger-Dv52PDpH.d.mts} +2 -2
- package/dist/{useLogger-BsPL4AQm.d.mts.map → useLogger-Dv52PDpH.d.mts.map} +1 -1
- package/dist/{utils-DLCeShxL.d.mts → utils-DmNbZwBZ.d.mts} +21 -4
- package/dist/{utils-DLCeShxL.d.mts.map → utils-DmNbZwBZ.d.mts.map} +1 -1
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +31 -9
- package/dist/utils.mjs.map +1 -1
- package/dist/vite/index.d.mts +1 -1
- package/dist/vite/index.mjs +1 -1
- package/dist/workers.d.mts +1 -1
- package/dist/workers.mjs +1 -1
- package/package.json +48 -15
- package/dist/audit-CC8nfazi.d.mts.map +0 -1
- package/dist/audit-pV5aLGP0.mjs.map +0 -1
- package/dist/define-D6OJdSUH.mjs.map +0 -1
- package/dist/define-MSdhzmXn.d.mts.map +0 -1
- package/dist/drain-X7_5szSI.mjs.map +0 -1
- package/dist/fork-8u_zFOJq.mjs.map +0 -1
- package/dist/index-o1_z4phv.d.mts.map +0 -1
- package/dist/logger-DntcxxHg.d.mts.map +0 -1
- package/dist/middleware-U-lIAzHg.d.mts.map +0 -1
- package/dist/nitro-DErMq_Zj.mjs +0 -34
- package/dist/nitro-DErMq_Zj.mjs.map +0 -1
- package/dist/nitro-oZre8ab3.d.mts.map +0 -1
- package/dist/nitroConfigBridge-DKk7eOn-.mjs +0 -92
- package/dist/nitroConfigBridge-DKk7eOn-.mjs.map +0 -1
- package/dist/package-v_MmOZeA.mjs.map +0 -1
- package/dist/parseError-yVZ58wIK.d.mts.map +0 -1
|
@@ -1,8 +1,118 @@
|
|
|
1
|
-
import { colors, cssColors, detectEnvironment, escapeFormatString, formatDuration, getConsoleMethod, getCssLevelColor, getLevelColor, isBrowser, isDev, isLevelEnabled, matchesPattern } from "./utils.mjs";
|
|
2
|
-
import {
|
|
1
|
+
import { colors, cssColors, detectEnvironment, escapeFormatString, formatDuration, getConsoleMethod, getCssLevelColor, getLevelColor, globToRegExp, isBrowser, isDev, isLevelEnabled, matchesPattern } from "./utils.mjs";
|
|
2
|
+
import { i as registerPrettyErrorSnippetReader, n as buildErrorEntries } from "./pretty-error-CVVgwlTn.mjs";
|
|
3
|
+
import { t as resolveDevTerminal } from "./dev-terminal-D4UaEm17.mjs";
|
|
4
|
+
import { EvlogError } from "./error.mjs";
|
|
5
|
+
import { r as getHeader$1 } from "./headers-VtmnWcfn.mjs";
|
|
3
6
|
//#region src/redact.ts
|
|
4
7
|
const DEFAULT_REPLACEMENT = "[REDACTED]";
|
|
5
8
|
/**
|
|
9
|
+
* Normalize a redact path pattern.
|
|
10
|
+
* Single segments without wildcards are shorthand for `**.<segment>`.
|
|
11
|
+
*/
|
|
12
|
+
function normalizeRedactPathPattern(pattern) {
|
|
13
|
+
if (!pattern.includes("*") && !pattern.includes(".")) return `**.${pattern}`;
|
|
14
|
+
return pattern;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Compile `RedactConfig.paths` into exact paths, path globs, and key globs.
|
|
18
|
+
* Returns `undefined` when `patterns` is empty.
|
|
19
|
+
*/
|
|
20
|
+
function compileRedactPathMatchers(patterns) {
|
|
21
|
+
if (!patterns?.length) return void 0;
|
|
22
|
+
const exactPaths = /* @__PURE__ */ new Set();
|
|
23
|
+
const pathGlobs = [];
|
|
24
|
+
const keyGlobs = [];
|
|
25
|
+
const caseInsensitiveLeaves = /* @__PURE__ */ new Set();
|
|
26
|
+
for (const raw of patterns) {
|
|
27
|
+
if (!raw.includes("*")) {
|
|
28
|
+
if (raw.includes(".")) exactPaths.add(raw);
|
|
29
|
+
else addPathGlobPattern(normalizeRedactPathPattern(raw), exactPaths, pathGlobs, caseInsensitiveLeaves);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (!raw.includes(".")) keyGlobs.push(globToRegExp(raw, "."));
|
|
33
|
+
else addPathGlobPattern(raw, exactPaths, pathGlobs, caseInsensitiveLeaves);
|
|
34
|
+
}
|
|
35
|
+
if (exactPaths.size === 0 && pathGlobs.length === 0 && keyGlobs.length === 0 && caseInsensitiveLeaves.size === 0) return;
|
|
36
|
+
return {
|
|
37
|
+
exactPaths,
|
|
38
|
+
pathGlobs,
|
|
39
|
+
keyGlobs,
|
|
40
|
+
caseInsensitiveLeaves
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** `**.segment` also matches a top-level `segment` field. */
|
|
44
|
+
function addPathGlobPattern(pattern, exactPaths, pathGlobs, caseInsensitiveLeaves) {
|
|
45
|
+
pathGlobs.push(globToRegExp(pattern, "."));
|
|
46
|
+
const leaf = pattern.match(/^\*\*\.([^.?*]+)$/);
|
|
47
|
+
if (leaf) {
|
|
48
|
+
exactPaths.add(leaf[1]);
|
|
49
|
+
caseInsensitiveLeaves.add(leaf[1]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Whether a field at `fullPath` (dot-notation from root) with leaf key `leafKey`
|
|
54
|
+
* should be fully redacted.
|
|
55
|
+
*/
|
|
56
|
+
function matchesRedactPath(fullPath, leafKey, matchers) {
|
|
57
|
+
if (matchers.exactPaths.has(fullPath)) return true;
|
|
58
|
+
const leafLower = leafKey.toLowerCase();
|
|
59
|
+
for (const name of matchers.caseInsensitiveLeaves) if (leafLower === name.toLowerCase()) return true;
|
|
60
|
+
for (const glob of matchers.pathGlobs) {
|
|
61
|
+
glob.lastIndex = 0;
|
|
62
|
+
if (glob.test(fullPath)) return true;
|
|
63
|
+
}
|
|
64
|
+
for (const glob of matchers.keyGlobs) {
|
|
65
|
+
glob.lastIndex = 0;
|
|
66
|
+
if (glob.test(leafKey)) return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Redact fields matching path globs recursively. Mutates `obj` in place (use on a clone).
|
|
72
|
+
*/
|
|
73
|
+
function redactPathsInTree(obj, matchers, replacement, prefix = "") {
|
|
74
|
+
if (obj === null || obj === void 0) return;
|
|
75
|
+
if (Array.isArray(obj)) {
|
|
76
|
+
for (let i = 0; i < obj.length; i++) {
|
|
77
|
+
const segment = String(i);
|
|
78
|
+
const fullPath = prefix ? `${prefix}.${segment}` : segment;
|
|
79
|
+
redactPathsInTree(obj[i], matchers, replacement, fullPath);
|
|
80
|
+
}
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (typeof obj === "object") {
|
|
84
|
+
const record = obj;
|
|
85
|
+
for (const key in record) {
|
|
86
|
+
const fullPath = prefix ? `${prefix}.${key}` : key;
|
|
87
|
+
if (matchesRedactPath(fullPath, key, matchers)) record[key] = replacement;
|
|
88
|
+
else redactPathsInTree(record[key], matchers, replacement, fullPath);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Return a copy of `value` with path-pattern matches replaced by `replacement`.
|
|
94
|
+
* Used by audit diffs; does not mutate the input.
|
|
95
|
+
*
|
|
96
|
+
* `pointerPath` is a JSON Pointer (e.g. `/user/password`).
|
|
97
|
+
*/
|
|
98
|
+
function redactValueByPaths(value, matchers, replacement, pointerPath = "") {
|
|
99
|
+
const segments = pointerPath.split("/").filter(Boolean);
|
|
100
|
+
const dotPath = segments.join(".");
|
|
101
|
+
const leafKey = segments.at(-1) ?? "";
|
|
102
|
+
if (value === null || typeof value !== "object") {
|
|
103
|
+
if (dotPath && matchesRedactPath(dotPath, leafKey, matchers)) return replacement;
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
if (Array.isArray(value)) return value.map((v, i) => redactValueByPaths(v, matchers, replacement, `${pointerPath}/${i}`));
|
|
107
|
+
if (!isPlainRecord(value)) return value;
|
|
108
|
+
const out = {};
|
|
109
|
+
for (const [k, v] of Object.entries(value)) {
|
|
110
|
+
const childPointer = pointerPath ? `${pointerPath}/${k}` : `/${k}`;
|
|
111
|
+
out[k] = matchesRedactPath(dotPath ? `${dotPath}.${k}` : k, k, matchers) ? replacement : redactValueByPaths(v, matchers, replacement, childPointer);
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
6
116
|
* Built-in PII detection patterns with smart masking.
|
|
7
117
|
* Each builtin preserves just enough signal for debugging while scrubbing PII.
|
|
8
118
|
*/
|
|
@@ -89,32 +199,56 @@ function allBuiltinMaskers() {
|
|
|
89
199
|
function cloneRegex(re) {
|
|
90
200
|
return new RegExp(re.source, re.flags);
|
|
91
201
|
}
|
|
202
|
+
/** @internal Set on wide events after initLogger redaction so middleware skips a second pass. */
|
|
203
|
+
const globallyRedacted = Symbol.for("evlog.globallyRedacted");
|
|
204
|
+
/** @internal Mark a wide event as already redacted by {@link initLogger}. */
|
|
205
|
+
function markGloballyRedacted(event) {
|
|
206
|
+
Object.defineProperty(event, globallyRedacted, {
|
|
207
|
+
value: true,
|
|
208
|
+
enumerable: false,
|
|
209
|
+
configurable: true
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/** @internal Whether global redaction already ran on this wide event. */
|
|
213
|
+
function isGloballyRedacted(event) {
|
|
214
|
+
return Reflect.has(event, globallyRedacted);
|
|
215
|
+
}
|
|
92
216
|
/**
|
|
93
|
-
*
|
|
217
|
+
* Clone before redaction. Wide events are JSON-shaped; fall back when
|
|
218
|
+
* `structuredClone` rejects non-cloneable values (functions, symbols, etc.).
|
|
219
|
+
*/
|
|
220
|
+
function cloneForRedaction(event) {
|
|
221
|
+
try {
|
|
222
|
+
return structuredClone(event);
|
|
223
|
+
} catch {
|
|
224
|
+
try {
|
|
225
|
+
return JSON.parse(JSON.stringify(event));
|
|
226
|
+
} catch {
|
|
227
|
+
console.warn("[cloneForRedaction] Shallow clone used — nested objects may be mutated by redactPath, redactPatterns, and applyMaskersToTree");
|
|
228
|
+
return { ...event };
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Redact sensitive data from a wide event without mutating the input.
|
|
94
234
|
*
|
|
95
|
-
* Three strategies
|
|
96
|
-
* 1. **Path-based**: dot-notation paths
|
|
235
|
+
* Returns a deep clone with redaction applied. Three strategies run in order:
|
|
236
|
+
* 1. **Path-based**: dot-notation paths with optional globs (`password`, `**.password`, `*_token`, `user.*`) — full value replacement.
|
|
97
237
|
* 2. **Masker-based**: built-in patterns with smart partial masking (e.g. `****1111`).
|
|
98
|
-
* 3. **Pattern-based**: custom RegExp patterns replaced with `replacement`.
|
|
238
|
+
* 3. **Pattern-based**: custom RegExp patterns on string values replaced with `replacement`.
|
|
99
239
|
*
|
|
100
|
-
* @param event - The wide event object (mutated
|
|
240
|
+
* @param event - The wide event object (not mutated).
|
|
101
241
|
* @param config - Redaction configuration.
|
|
242
|
+
* @returns A redacted deep clone of `event`.
|
|
102
243
|
*/
|
|
103
244
|
function redactEvent(event, config) {
|
|
245
|
+
const clone = cloneForRedaction(event);
|
|
104
246
|
const replacement = config.replacement ?? DEFAULT_REPLACEMENT;
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
if (config.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
let current = obj;
|
|
111
|
-
for (let i = 0; i < segments.length - 1; i++) {
|
|
112
|
-
if (current === null || current === void 0 || typeof current !== "object") return;
|
|
113
|
-
current = current[segments[i]];
|
|
114
|
-
}
|
|
115
|
-
if (current === null || current === void 0 || typeof current !== "object") return;
|
|
116
|
-
const leaf = segments[segments.length - 1];
|
|
117
|
-
if (leaf in current) current[leaf] = replacement;
|
|
247
|
+
const pathMatchers = compileRedactPathMatchers(config.paths);
|
|
248
|
+
if (pathMatchers) redactPathsInTree(clone, pathMatchers, replacement);
|
|
249
|
+
if (config._maskers?.length) applyMaskersToTree(clone, config._maskers);
|
|
250
|
+
if (config.patterns?.length) redactPatterns(clone, config.patterns, replacement);
|
|
251
|
+
return clone;
|
|
118
252
|
}
|
|
119
253
|
function redactPatterns(obj, patterns, replacement) {
|
|
120
254
|
if (obj === null || obj === void 0) return;
|
|
@@ -177,17 +311,34 @@ function normalizeRedactConfig(raw) {
|
|
|
177
311
|
if (typeof raw.replacement === "string") config.replacement = raw.replacement;
|
|
178
312
|
if (raw.builtins === false) config.builtins = false;
|
|
179
313
|
else if (Array.isArray(raw.builtins)) config.builtins = raw.builtins;
|
|
180
|
-
if (Array.isArray(raw.patterns)) config.patterns = raw.patterns
|
|
181
|
-
if (p instanceof RegExp) return p;
|
|
182
|
-
if (typeof p === "string") return new RegExp(p, "g");
|
|
183
|
-
if (typeof p === "object" && p !== null) {
|
|
184
|
-
const obj = p;
|
|
185
|
-
return new RegExp(obj.source, obj.flags ?? "g");
|
|
186
|
-
}
|
|
187
|
-
return null;
|
|
188
|
-
}).filter((p) => p !== null);
|
|
314
|
+
if (Array.isArray(raw.patterns)) config.patterns = deserializeRegexList(raw.patterns);
|
|
189
315
|
return resolveRedactConfig(config);
|
|
190
316
|
}
|
|
317
|
+
function isPlainRecord(value) {
|
|
318
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
319
|
+
const proto = Object.getPrototypeOf(value);
|
|
320
|
+
return proto === Object.prototype || proto === null;
|
|
321
|
+
}
|
|
322
|
+
function deserializeRegexList(raw) {
|
|
323
|
+
const patterns = [];
|
|
324
|
+
for (const p of raw) try {
|
|
325
|
+
if (p instanceof RegExp) {
|
|
326
|
+
patterns.push(cloneRegex(p));
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (typeof p === "string") {
|
|
330
|
+
patterns.push(new RegExp(p, "g"));
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
if (typeof p === "object" && p !== null && typeof p.source === "string") {
|
|
334
|
+
const flags = typeof p.flags === "string" ? p.flags : "g";
|
|
335
|
+
patterns.push(new RegExp(p.source, flags));
|
|
336
|
+
}
|
|
337
|
+
} catch {
|
|
338
|
+
console.warn("[normalizeRedactConfig] Ignoring invalid redact regex entry");
|
|
339
|
+
}
|
|
340
|
+
return patterns;
|
|
341
|
+
}
|
|
191
342
|
//#endregion
|
|
192
343
|
//#region src/shared/plugin.ts
|
|
193
344
|
/** Identity helper preserving plugin type inference. */
|
|
@@ -314,7 +465,7 @@ function getEmptyPluginRunner() {
|
|
|
314
465
|
}
|
|
315
466
|
//#endregion
|
|
316
467
|
//#region src/logger.ts
|
|
317
|
-
function isPlainObject(val) {
|
|
468
|
+
function isPlainObject$1(val) {
|
|
318
469
|
return val !== null && typeof val === "object" && !Array.isArray(val);
|
|
319
470
|
}
|
|
320
471
|
const _tsDate = /* @__PURE__ */ new Date();
|
|
@@ -332,16 +483,38 @@ function mergeInto(target, source) {
|
|
|
332
483
|
const sourceVal = source[key];
|
|
333
484
|
if (sourceVal === void 0 || sourceVal === null) continue;
|
|
334
485
|
const targetVal = target[key];
|
|
335
|
-
if (isPlainObject(sourceVal) && isPlainObject(targetVal)) mergeInto(targetVal, sourceVal);
|
|
486
|
+
if (isPlainObject$1(sourceVal) && isPlainObject$1(targetVal)) mergeInto(targetVal, sourceVal);
|
|
336
487
|
else if (Array.isArray(targetVal) && Array.isArray(sourceVal)) target[key] = [...targetVal, ...sourceVal];
|
|
337
488
|
else target[key] = sourceVal;
|
|
338
489
|
}
|
|
339
490
|
}
|
|
491
|
+
const pendingDrainState = /* @__PURE__ */ new WeakMap();
|
|
492
|
+
function isAiOnlyFieldUpdate(data) {
|
|
493
|
+
const keys = Object.keys(data);
|
|
494
|
+
return keys.length === 1 && keys[0] === "ai";
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Mark a wide event as past the post-emit AI merge window so late `log.set({ ai })`
|
|
498
|
+
* calls warn again. Called by framework enrich/drain pipelines before drain runs.
|
|
499
|
+
*
|
|
500
|
+
* @internal Used by middleware and framework integrations.
|
|
501
|
+
*/
|
|
502
|
+
function markWideEventDrainStarted(event) {
|
|
503
|
+
if (!event) return;
|
|
504
|
+
const state = pendingDrainState.get(event);
|
|
505
|
+
if (state) state.drainStarted = true;
|
|
506
|
+
}
|
|
340
507
|
let globalEnv = {
|
|
341
508
|
service: "app",
|
|
342
509
|
environment: "development"
|
|
343
510
|
};
|
|
344
511
|
let globalPretty = isDev();
|
|
512
|
+
let globalPrettyError = {
|
|
513
|
+
snippet: isDev(),
|
|
514
|
+
stackDepth: 2,
|
|
515
|
+
compact: isDev(),
|
|
516
|
+
detail: "full"
|
|
517
|
+
};
|
|
345
518
|
let globalSampling = {};
|
|
346
519
|
let globalStringify = true;
|
|
347
520
|
let globalDrain;
|
|
@@ -367,6 +540,7 @@ function initLogger(config = {}) {
|
|
|
367
540
|
region: config.env?.region ?? detected.region
|
|
368
541
|
};
|
|
369
542
|
globalPretty = config.pretty ?? isDev();
|
|
543
|
+
globalPrettyError = resolveDevTerminal(config).prettyError;
|
|
370
544
|
globalSampling = config.sampling ?? {};
|
|
371
545
|
globalStringify = config.stringify ?? true;
|
|
372
546
|
globalDrain = config.drain;
|
|
@@ -375,6 +549,11 @@ function initLogger(config = {}) {
|
|
|
375
549
|
globalMinLevel = config.minLevel ?? "debug";
|
|
376
550
|
globalPluginRunner = config.plugins?.length ? createPluginRunner(config.plugins) : getEmptyPluginRunner();
|
|
377
551
|
if (globalPluginRunner.plugins.length > 0) globalPluginRunner.runSetup({ env: { ...globalEnv } });
|
|
552
|
+
if (!isBrowser() && typeof process !== "undefined" && process.versions?.node) import("./pretty-error-snippet.node-c_bzjg7g.mjs").then((n) => n.t).then((mod) => {
|
|
553
|
+
registerPrettyErrorSnippetReader(mod.readCodeSnippetFromDisk);
|
|
554
|
+
}).catch(() => {
|
|
555
|
+
registerPrettyErrorSnippetReader(null);
|
|
556
|
+
});
|
|
378
557
|
const hasAnyDrain = !!globalDrain || globalPluginRunner.hasDrain;
|
|
379
558
|
if (globalSilent && !hasAnyDrain && !config._suppressDrainWarning) console.warn("[evlog] silent mode is enabled but no drain is configured. Events will be built and sampled but not output anywhere. Set a drain via initLogger({ drain }) or a framework hook (evlog:drain).");
|
|
380
559
|
}
|
|
@@ -464,7 +643,10 @@ function emitWideEvent(level, event, options = {}) {
|
|
|
464
643
|
...event
|
|
465
644
|
};
|
|
466
645
|
finalizeAudit(formatted);
|
|
467
|
-
if (globalRedact)
|
|
646
|
+
if (globalRedact) {
|
|
647
|
+
formatted = redactEvent(formatted, globalRedact);
|
|
648
|
+
markGloballyRedacted(formatted);
|
|
649
|
+
}
|
|
468
650
|
if (!globalSilent) if (globalPretty) prettyPrintWideEvent(formatted);
|
|
469
651
|
else if (globalStringify) console[getConsoleMethod(level)](JSON.stringify(formatted));
|
|
470
652
|
else console[getConsoleMethod(level)](formatted);
|
|
@@ -505,7 +687,7 @@ function emitTaggedLog(level, tag, message) {
|
|
|
505
687
|
}
|
|
506
688
|
function formatValue(value) {
|
|
507
689
|
if (value === null || value === void 0) return String(value);
|
|
508
|
-
if (
|
|
690
|
+
if (isPlainObject$1(value)) {
|
|
509
691
|
const pairs = [];
|
|
510
692
|
for (const [k, v] of Object.entries(value)) if (v !== void 0 && v !== null) if (typeof v === "object") pairs.push(`${k}=${JSON.stringify(v)}`);
|
|
511
693
|
else pairs.push(`${k}=${v}`);
|
|
@@ -518,6 +700,43 @@ function formatCost(cost) {
|
|
|
518
700
|
if (cost < 1) return `$${cost.toFixed(4)}`;
|
|
519
701
|
return `$${cost.toFixed(2)}`;
|
|
520
702
|
}
|
|
703
|
+
function asNumber(value) {
|
|
704
|
+
return typeof value === "number" ? value : void 0;
|
|
705
|
+
}
|
|
706
|
+
function asStringArray(value) {
|
|
707
|
+
if (!Array.isArray(value)) return void 0;
|
|
708
|
+
return value.every((item) => typeof item === "string") ? value : void 0;
|
|
709
|
+
}
|
|
710
|
+
function isToolUsageEntry(value) {
|
|
711
|
+
return isPlainObject$1(value) && typeof value.name === "string" && typeof value.durationMs === "number" && typeof value.success === "boolean";
|
|
712
|
+
}
|
|
713
|
+
function asToolUsageArray(value) {
|
|
714
|
+
if (!Array.isArray(value)) return void 0;
|
|
715
|
+
return value.every(isToolUsageEntry) ? value : void 0;
|
|
716
|
+
}
|
|
717
|
+
function serializeToolInput(input) {
|
|
718
|
+
if (typeof input === "string") return input;
|
|
719
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
720
|
+
try {
|
|
721
|
+
return JSON.stringify(input, (_key, value) => {
|
|
722
|
+
if (typeof value === "bigint") return value.toString();
|
|
723
|
+
if (typeof value === "object" && value !== null) {
|
|
724
|
+
if (seen.has(value)) return "[Circular]";
|
|
725
|
+
seen.add(value);
|
|
726
|
+
}
|
|
727
|
+
return value;
|
|
728
|
+
}) ?? "";
|
|
729
|
+
} catch {
|
|
730
|
+
return "[unserializable tool input]";
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
function isToolCallEntry(value) {
|
|
734
|
+
return isPlainObject$1(value) && typeof value.name === "string" && "input" in value;
|
|
735
|
+
}
|
|
736
|
+
function asToolCallArray(value) {
|
|
737
|
+
if (!Array.isArray(value)) return void 0;
|
|
738
|
+
return value.every(isToolCallEntry) ? value : void 0;
|
|
739
|
+
}
|
|
521
740
|
function buildAIEntries(ai) {
|
|
522
741
|
const entries = [];
|
|
523
742
|
const headerParts = [];
|
|
@@ -526,15 +745,19 @@ function buildAIEntries(ai) {
|
|
|
526
745
|
if (ai.provider) m += ` (${ai.provider})`;
|
|
527
746
|
headerParts.push(m);
|
|
528
747
|
}
|
|
529
|
-
if (ai.calls)
|
|
530
|
-
|
|
748
|
+
if (ai.calls) {
|
|
749
|
+
const calls = asNumber(ai.calls);
|
|
750
|
+
if (calls !== void 0) headerParts.push(`${calls} call${calls > 1 ? "s" : ""}`);
|
|
751
|
+
}
|
|
752
|
+
const steps = asNumber(ai.steps);
|
|
753
|
+
if (steps !== void 0 && steps > 1) headerParts.push(`${steps} steps`);
|
|
531
754
|
entries.push({
|
|
532
755
|
key: "ai",
|
|
533
756
|
value: headerParts.join(" · ")
|
|
534
757
|
});
|
|
535
|
-
const inputTokens = ai.inputTokens;
|
|
536
|
-
const outputTokens = ai.outputTokens;
|
|
537
|
-
const totalTokens = ai.totalTokens;
|
|
758
|
+
const inputTokens = asNumber(ai.inputTokens);
|
|
759
|
+
const outputTokens = asNumber(ai.outputTokens);
|
|
760
|
+
const totalTokens = asNumber(ai.totalTokens);
|
|
538
761
|
if (inputTokens !== void 0 && outputTokens !== void 0) {
|
|
539
762
|
let tokLine = `${inputTokens} in → ${outputTokens} out`;
|
|
540
763
|
if (totalTokens) tokLine += ` (${totalTokens} total)`;
|
|
@@ -548,9 +771,9 @@ function buildAIEntries(ai) {
|
|
|
548
771
|
value: tokLine
|
|
549
772
|
});
|
|
550
773
|
}
|
|
551
|
-
const msFirst = ai.msToFirstChunk;
|
|
552
|
-
const msFinish = ai.msToFinish;
|
|
553
|
-
const tps = ai.tokensPerSecond;
|
|
774
|
+
const msFirst = asNumber(ai.msToFirstChunk);
|
|
775
|
+
const msFinish = asNumber(ai.msToFinish);
|
|
776
|
+
const tps = asNumber(ai.tokensPerSecond);
|
|
554
777
|
if (msFirst !== void 0 || msFinish !== void 0) {
|
|
555
778
|
const parts = [];
|
|
556
779
|
if (msFirst !== void 0) parts.push(`${formatDuration(msFirst)} to first chunk`);
|
|
@@ -562,25 +785,28 @@ function buildAIEntries(ai) {
|
|
|
562
785
|
value: streamLine
|
|
563
786
|
});
|
|
564
787
|
}
|
|
565
|
-
|
|
788
|
+
const estimatedCost = asNumber(ai.estimatedCost);
|
|
789
|
+
if (estimatedCost !== void 0) entries.push({
|
|
566
790
|
key: "ai.cost",
|
|
567
|
-
value: formatCost(
|
|
791
|
+
value: formatCost(estimatedCost)
|
|
568
792
|
});
|
|
569
|
-
|
|
793
|
+
const totalDurationMs = asNumber(ai.totalDurationMs);
|
|
794
|
+
if (totalDurationMs !== void 0) entries.push({
|
|
570
795
|
key: "ai.totalDuration",
|
|
571
|
-
value: formatDuration(
|
|
796
|
+
value: formatDuration(totalDurationMs)
|
|
572
797
|
});
|
|
573
|
-
const toolCalls = ai.toolCalls;
|
|
574
|
-
const tools = ai.tools;
|
|
575
|
-
const
|
|
798
|
+
const toolCalls = Array.isArray(ai.toolCalls) ? ai.toolCalls : void 0;
|
|
799
|
+
const tools = asToolUsageArray(ai.tools);
|
|
800
|
+
const toolCallEntries = toolCalls ? asToolCallArray(toolCalls) : void 0;
|
|
801
|
+
const hasInputs = toolCallEntries !== void 0 && toolCallEntries.length > 0;
|
|
576
802
|
if (tools?.length) {
|
|
577
803
|
const children = tools.map((t, idx) => {
|
|
578
804
|
const mark = t.success ? "✓" : "✗";
|
|
579
805
|
let line = `${t.name} ${formatDuration(t.durationMs)} ${mark}`;
|
|
580
806
|
if (t.error) line += ` ${t.error}`;
|
|
581
|
-
if (hasInputs &&
|
|
582
|
-
const tc =
|
|
583
|
-
const inputStr =
|
|
807
|
+
if (hasInputs && toolCallEntries && idx < toolCallEntries.length) {
|
|
808
|
+
const tc = toolCallEntries[idx];
|
|
809
|
+
const inputStr = serializeToolInput(tc.input);
|
|
584
810
|
const truncated = inputStr.length > 100 ? `${inputStr.slice(0, 100)}…` : inputStr;
|
|
585
811
|
line += ` ${truncated}`;
|
|
586
812
|
}
|
|
@@ -591,9 +817,9 @@ function buildAIEntries(ai) {
|
|
|
591
817
|
value: "",
|
|
592
818
|
children
|
|
593
819
|
});
|
|
594
|
-
} else if (toolCalls?.length) if (
|
|
595
|
-
const children =
|
|
596
|
-
const inputStr =
|
|
820
|
+
} else if (toolCalls?.length) if (toolCallEntries?.length) {
|
|
821
|
+
const children = toolCallEntries.map((tc) => {
|
|
822
|
+
const inputStr = serializeToolInput(tc.input);
|
|
597
823
|
const truncated = inputStr.length > 100 ? `${inputStr.slice(0, 100)}…` : inputStr;
|
|
598
824
|
return `${tc.name}(${truncated})`;
|
|
599
825
|
});
|
|
@@ -602,16 +828,20 @@ function buildAIEntries(ai) {
|
|
|
602
828
|
value: "",
|
|
603
829
|
children
|
|
604
830
|
});
|
|
605
|
-
} else
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
831
|
+
} else {
|
|
832
|
+
const names = asStringArray(toolCalls);
|
|
833
|
+
if (names?.length) entries.push({
|
|
834
|
+
key: "ai.tools",
|
|
835
|
+
value: names.join(", ")
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
const stepsUsage = Array.isArray(ai.stepsUsage) ? ai.stepsUsage.filter(isPlainObject$1) : void 0;
|
|
610
839
|
if (stepsUsage?.length) {
|
|
611
|
-
const
|
|
840
|
+
const firstModel = stepsUsage[0]?.model;
|
|
841
|
+
const allSameModel = firstModel !== void 0 && stepsUsage.every((s) => s.model === firstModel);
|
|
612
842
|
const children = stepsUsage.map((s) => {
|
|
613
|
-
let line = `${allSameModel ? "" : `${s.model} `}${s.inputTokens} in → ${s.outputTokens} out`;
|
|
614
|
-
const stepTools = s.toolCalls;
|
|
843
|
+
let line = `${allSameModel ? "" : `${String(s.model)} `}${s.inputTokens} in → ${s.outputTokens} out`;
|
|
844
|
+
const stepTools = asStringArray(s.toolCalls);
|
|
615
845
|
if (stepTools?.length) line += ` [${stepTools.join(", ")}]`;
|
|
616
846
|
return line;
|
|
617
847
|
});
|
|
@@ -620,11 +850,11 @@ function buildAIEntries(ai) {
|
|
|
620
850
|
value: "",
|
|
621
851
|
children
|
|
622
852
|
});
|
|
623
|
-
} else if (
|
|
853
|
+
} else if (steps !== void 0 && steps > 1) entries.push({
|
|
624
854
|
key: "ai.steps",
|
|
625
|
-
value: String(
|
|
855
|
+
value: String(steps)
|
|
626
856
|
});
|
|
627
|
-
const embedding = ai.embedding;
|
|
857
|
+
const embedding = isPlainObject$1(ai.embedding) ? ai.embedding : void 0;
|
|
628
858
|
if (embedding) {
|
|
629
859
|
const parts = [];
|
|
630
860
|
if (embedding.model) parts.push(String(embedding.model));
|
|
@@ -650,19 +880,39 @@ function buildAIEntries(ai) {
|
|
|
650
880
|
});
|
|
651
881
|
return entries;
|
|
652
882
|
}
|
|
883
|
+
function flushPrettyLines(lines) {
|
|
884
|
+
if (lines.length === 0) return;
|
|
885
|
+
const text = `${lines.join("\n")}\n`;
|
|
886
|
+
if (typeof process !== "undefined" && typeof process.stdout?.write === "function" && !isBrowser() && process.env.VITEST !== "true") {
|
|
887
|
+
process.stdout.write(text);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
console.log(lines.join("\n"));
|
|
891
|
+
}
|
|
653
892
|
function prettyPrintWideEvent(event) {
|
|
654
893
|
const { timestamp, level, service, environment, version, ...rest } = event;
|
|
655
|
-
const ts = timestamp.slice(11, 23);
|
|
894
|
+
const ts = typeof timestamp === "string" ? timestamp.slice(11, 23) : "";
|
|
895
|
+
const levelLabel = typeof level === "string" ? level : "info";
|
|
656
896
|
const browser = isBrowser();
|
|
897
|
+
const lines = [];
|
|
898
|
+
const writeLine = (...args) => {
|
|
899
|
+
if (browser) {
|
|
900
|
+
console.log(...args);
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
const [line] = args;
|
|
904
|
+
if (typeof line === "string") lines.push(line);
|
|
905
|
+
};
|
|
657
906
|
const parts = [];
|
|
658
907
|
const styles = [];
|
|
659
908
|
if (browser) {
|
|
660
|
-
const lc = getCssLevelColor(
|
|
661
|
-
parts.push(`%c${ts}%c %c${
|
|
909
|
+
const lc = getCssLevelColor(levelLabel);
|
|
910
|
+
parts.push(`%c${ts}%c %c${levelLabel.toUpperCase()}%c %c[${escapeFormatString(String(service))}]%c`);
|
|
662
911
|
styles.push(cssColors.dim, cssColors.reset, lc, cssColors.reset, cssColors.cyan, cssColors.reset);
|
|
663
912
|
} else {
|
|
664
|
-
const lc = getLevelColor(
|
|
665
|
-
parts.push(`${
|
|
913
|
+
const lc = getLevelColor(levelLabel);
|
|
914
|
+
if (isDev()) parts.push(`${lc}${levelLabel.toUpperCase()}${colors.reset} ${colors.cyan}[${service}]${colors.reset}`);
|
|
915
|
+
else parts.push(`${colors.dim}${ts}${colors.reset} ${lc}${levelLabel.toUpperCase()}${colors.reset} ${colors.cyan}[${service}]${colors.reset}`);
|
|
666
916
|
}
|
|
667
917
|
if (rest.method && rest.path) {
|
|
668
918
|
parts.push(browser ? ` ${escapeFormatString(String(rest.method))} ${escapeFormatString(String(rest.path))}` : ` ${rest.method} ${rest.path}`);
|
|
@@ -670,7 +920,8 @@ function prettyPrintWideEvent(event) {
|
|
|
670
920
|
delete rest.path;
|
|
671
921
|
}
|
|
672
922
|
if (rest.status) {
|
|
673
|
-
const
|
|
923
|
+
const statusCode = asNumber(rest.status) ?? Number(rest.status);
|
|
924
|
+
const sc = browser ? statusCode >= 400 ? cssColors.red : cssColors.green : statusCode >= 400 ? colors.red : colors.green;
|
|
674
925
|
if (browser) {
|
|
675
926
|
parts.push(` %c${rest.status}%c`);
|
|
676
927
|
styles.push(sc, cssColors.reset);
|
|
@@ -684,36 +935,53 @@ function prettyPrintWideEvent(event) {
|
|
|
684
935
|
} else parts.push(` ${colors.dim}in ${rest.duration}${colors.reset}`);
|
|
685
936
|
delete rest.duration;
|
|
686
937
|
}
|
|
687
|
-
|
|
688
|
-
const aiData = rest.ai;
|
|
689
|
-
if (aiData
|
|
938
|
+
writeLine(parts.join(""), ...styles);
|
|
939
|
+
const aiData = isPlainObject$1(rest.ai) ? rest.ai : void 0;
|
|
940
|
+
if (aiData) delete rest.ai;
|
|
941
|
+
const errorData = rest.error;
|
|
942
|
+
if (errorData !== void 0) delete rest.error;
|
|
690
943
|
const restEntries = Object.entries(rest).filter(([_, v]) => v !== void 0);
|
|
691
944
|
const aiEntries = aiData ? buildAIEntries(aiData) : [];
|
|
692
|
-
const
|
|
945
|
+
const errorEntries = errorData !== void 0 ? buildErrorEntries(errorData, globalPrettyError) : [];
|
|
946
|
+
const contextEntries = [...restEntries.map(([key, value]) => ({
|
|
693
947
|
key,
|
|
694
948
|
value: formatValue(value)
|
|
695
949
|
})), ...aiEntries];
|
|
950
|
+
const allEntries = errorEntries.length > 0 ? [...errorEntries, ...contextEntries] : contextEntries;
|
|
696
951
|
for (let i = 0; i < allEntries.length; i++) {
|
|
697
952
|
const entry = allEntries[i];
|
|
698
|
-
|
|
953
|
+
if (!entry) continue;
|
|
954
|
+
const { children } = entry;
|
|
955
|
+
const hasChildren = children !== void 0 && children.length > 0;
|
|
699
956
|
const prefix = i === allEntries.length - 1 && !hasChildren ? "└─" : "├─";
|
|
700
957
|
if (browser) {
|
|
701
958
|
const val = entry.value ? ` ${escapeFormatString(entry.value)}` : "";
|
|
702
|
-
|
|
959
|
+
writeLine(` %c${prefix}%c %c${escapeFormatString(entry.key)}:%c${val}`, cssColors.dim, cssColors.reset, cssColors.cyan, cssColors.reset);
|
|
703
960
|
} else {
|
|
704
961
|
const val = entry.value ? ` ${entry.value}` : "";
|
|
705
|
-
|
|
962
|
+
writeLine(` ${colors.dim}${prefix}${colors.reset} ${colors.cyan}${entry.key}:${colors.reset}${val}`);
|
|
706
963
|
}
|
|
707
|
-
if (hasChildren) {
|
|
964
|
+
if (hasChildren && children) {
|
|
708
965
|
const connector = i === allEntries.length - 1 ? " " : "│";
|
|
709
|
-
for (let j = 0; j <
|
|
710
|
-
const child =
|
|
711
|
-
|
|
712
|
-
if (
|
|
713
|
-
|
|
966
|
+
for (let j = 0; j < children.length; j++) {
|
|
967
|
+
const child = children[j];
|
|
968
|
+
if (child === void 0) continue;
|
|
969
|
+
if (child === "__EVLOG_TREE_SPACER__") {
|
|
970
|
+
writeLine(` ${colors.dim}${connector}${colors.reset}`);
|
|
971
|
+
continue;
|
|
972
|
+
}
|
|
973
|
+
const childPrefix = j === children.length - 1 ? "└─" : "├─";
|
|
974
|
+
if (child === "") {
|
|
975
|
+
writeLine("");
|
|
976
|
+
continue;
|
|
977
|
+
}
|
|
978
|
+
if (browser) writeLine(` %c${connector} ${childPrefix}%c ${escapeFormatString(child)}`, cssColors.dim, cssColors.reset);
|
|
979
|
+
else if (child.startsWith(" ") || child.startsWith("\x1B")) writeLine(` ${colors.dim}${connector}${colors.reset}${child}`);
|
|
980
|
+
else writeLine(` ${colors.dim}${connector} ${childPrefix}${colors.reset} ${child}`);
|
|
714
981
|
}
|
|
715
982
|
}
|
|
716
983
|
}
|
|
984
|
+
if (!browser && lines.length > 0) flushPrettyLines(lines);
|
|
717
985
|
}
|
|
718
986
|
function createLogMethod(level) {
|
|
719
987
|
return function logMethod(tagOrEvent, message) {
|
|
@@ -739,6 +1007,7 @@ const _log = {
|
|
|
739
1007
|
};
|
|
740
1008
|
const noopLogger = {
|
|
741
1009
|
set() {},
|
|
1010
|
+
setLevel() {},
|
|
742
1011
|
error() {},
|
|
743
1012
|
info() {},
|
|
744
1013
|
warn() {},
|
|
@@ -773,7 +1042,9 @@ function createLogger(initialContext = {}, internalOptions) {
|
|
|
773
1042
|
const context = { ...initialContext };
|
|
774
1043
|
let hasError = false;
|
|
775
1044
|
let hasWarn = false;
|
|
1045
|
+
let manualLevel;
|
|
776
1046
|
let emitted = false;
|
|
1047
|
+
let pendingWideEvent = null;
|
|
777
1048
|
function addLog(level, message) {
|
|
778
1049
|
if (!Array.isArray(context.requestLogs)) context.requestLogs = [];
|
|
779
1050
|
context.requestLogs.push({
|
|
@@ -788,7 +1059,7 @@ function createLogger(initialContext = {}, internalOptions) {
|
|
|
788
1059
|
return;
|
|
789
1060
|
}
|
|
790
1061
|
const fields = buildAuditFields(input);
|
|
791
|
-
if (!isPlainObject(context.audit)) context.audit = fields;
|
|
1062
|
+
if (!isPlainObject$1(context.audit)) context.audit = fields;
|
|
792
1063
|
else mergeInto(context.audit, fields);
|
|
793
1064
|
context._auditForceKeep = true;
|
|
794
1065
|
};
|
|
@@ -803,12 +1074,25 @@ function createLogger(initialContext = {}, internalOptions) {
|
|
|
803
1074
|
audit: auditMethod,
|
|
804
1075
|
set(data) {
|
|
805
1076
|
if (emitted) {
|
|
806
|
-
const
|
|
1077
|
+
const record = data;
|
|
1078
|
+
const pendingState = pendingWideEvent ? pendingDrainState.get(pendingWideEvent) : void 0;
|
|
1079
|
+
if (pendingWideEvent && pendingState && !pendingState.drainStarted && isAiOnlyFieldUpdate(record)) {
|
|
1080
|
+
mergeInto(pendingWideEvent, record);
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
const keys = Object.keys(record);
|
|
807
1084
|
warnPostEmit("log.set()", `Keys dropped: ${keys.length ? keys.join(", ") : "(empty)"}.`);
|
|
808
1085
|
return;
|
|
809
1086
|
}
|
|
810
1087
|
mergeInto(context, data);
|
|
811
1088
|
},
|
|
1089
|
+
setLevel(level) {
|
|
1090
|
+
if (emitted) {
|
|
1091
|
+
warnPostEmit("log.setLevel()", `Level dropped: ${level}.`);
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
manualLevel = level;
|
|
1095
|
+
},
|
|
812
1096
|
error(error, errorContext) {
|
|
813
1097
|
if (emitted) {
|
|
814
1098
|
warnPostEmit("log.error()", `Keys dropped: ${(errorContext ? [...Object.keys(errorContext), "error"] : ["error"]).join(", ")}.`);
|
|
@@ -833,7 +1117,14 @@ function createLogger(initialContext = {}, internalOptions) {
|
|
|
833
1117
|
"cause",
|
|
834
1118
|
"internal"
|
|
835
1119
|
]) if (k in err) errorObj[k] = errRecord[k];
|
|
836
|
-
if (
|
|
1120
|
+
if (err instanceof EvlogError) {
|
|
1121
|
+
if (err.code) errorObj.code = err.code;
|
|
1122
|
+
if (err.why) errorObj.why = err.why;
|
|
1123
|
+
if (err.fix) errorObj.fix = err.fix;
|
|
1124
|
+
if (err.link) errorObj.link = err.link;
|
|
1125
|
+
if (err.status) errorObj.status = err.status;
|
|
1126
|
+
}
|
|
1127
|
+
if (isPlainObject$1(context.error)) mergeInto(context.error, errorObj);
|
|
837
1128
|
else context.error = errorObj;
|
|
838
1129
|
},
|
|
839
1130
|
info(message, infoContext) {
|
|
@@ -865,7 +1156,7 @@ function createLogger(initialContext = {}, internalOptions) {
|
|
|
865
1156
|
return null;
|
|
866
1157
|
}
|
|
867
1158
|
const durationMs = Date.now() - startTime;
|
|
868
|
-
const level = hasError ? "error" : hasWarn ? "warn" : "info";
|
|
1159
|
+
const level = manualLevel ?? (hasError ? "error" : hasWarn ? "warn" : "info");
|
|
869
1160
|
let forceKeep = false;
|
|
870
1161
|
if (overrides?._forceKeep) forceKeep = true;
|
|
871
1162
|
else if (consumeAuditForceKeep(context)) forceKeep = true;
|
|
@@ -878,6 +1169,7 @@ function createLogger(initialContext = {}, internalOptions) {
|
|
|
878
1169
|
});
|
|
879
1170
|
if (!forceKeep && !shouldSample(level)) {
|
|
880
1171
|
emitted = true;
|
|
1172
|
+
pendingWideEvent = null;
|
|
881
1173
|
return null;
|
|
882
1174
|
}
|
|
883
1175
|
if (overrides) {
|
|
@@ -891,6 +1183,8 @@ function createLogger(initialContext = {}, internalOptions) {
|
|
|
891
1183
|
waitUntil
|
|
892
1184
|
});
|
|
893
1185
|
emitted = true;
|
|
1186
|
+
pendingWideEvent = wide;
|
|
1187
|
+
if (wide) pendingDrainState.set(wide, { drainStarted: !deferDrain });
|
|
894
1188
|
return wide;
|
|
895
1189
|
},
|
|
896
1190
|
getContext() {
|
|
@@ -955,9 +1249,15 @@ const AUDIT_SCHEMA_VERSION = 1;
|
|
|
955
1249
|
* Used by `idempotencyKey` and `hash-chain` so the same logical event always
|
|
956
1250
|
* produces the same digest, regardless of how object keys were added.
|
|
957
1251
|
*/
|
|
1252
|
+
function isPlainObject(value) {
|
|
1253
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
1254
|
+
if (Object.prototype.toString.call(value) !== "[object Object]") return false;
|
|
1255
|
+
return Object.getPrototypeOf(value) === Object.prototype || value.constructor === Object;
|
|
1256
|
+
}
|
|
958
1257
|
function stableStringify(value) {
|
|
959
1258
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
960
1259
|
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
1260
|
+
if (!isPlainObject(value)) return JSON.stringify(value);
|
|
961
1261
|
return `{${Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${stableStringify(value[k])}`).join(",")}}`;
|
|
962
1262
|
}
|
|
963
1263
|
/**
|
|
@@ -1104,10 +1404,7 @@ function markForceKeep(logger) {
|
|
|
1104
1404
|
* ```
|
|
1105
1405
|
*/
|
|
1106
1406
|
function audit(input) {
|
|
1107
|
-
|
|
1108
|
-
const wide = createLogger({ audit: fields }).emit({ _forceKeep: true });
|
|
1109
|
-
_testCollector?.(fields, wide);
|
|
1110
|
-
return wide;
|
|
1407
|
+
return createLogger({ audit: buildAuditFields(input) }).emit({ _forceKeep: true });
|
|
1111
1408
|
}
|
|
1112
1409
|
/**
|
|
1113
1410
|
* Wrap a function so its outcome (success / failure / denied) is automatically
|
|
@@ -1180,8 +1477,8 @@ var AuditDeniedError = class extends Error {
|
|
|
1180
1477
|
* `changes` field. Output is a JSON Patch-style array (RFC 6902 subset:
|
|
1181
1478
|
* `add`, `remove`, `replace`) — small enough to ship over the wire.
|
|
1182
1479
|
*
|
|
1183
|
-
*
|
|
1184
|
-
* `'
|
|
1480
|
+
* Fields matching `redactPaths` glob patterns (e.g. `'password'`, `'**.password'`,
|
|
1481
|
+
* `'*_token'`, `'user.email'`) are replaced with `'[REDACTED]'` so PII
|
|
1185
1482
|
* never leaks through the diff.
|
|
1186
1483
|
*
|
|
1187
1484
|
* @example
|
|
@@ -1196,14 +1493,13 @@ var AuditDeniedError = class extends Error {
|
|
|
1196
1493
|
*/
|
|
1197
1494
|
function auditDiff(before, after, options = {}) {
|
|
1198
1495
|
const replacement = options.replacement ?? "[REDACTED]";
|
|
1199
|
-
const
|
|
1496
|
+
const pathMatchers = compileRedactPathMatchers(options.redactPaths) ?? {
|
|
1497
|
+
exactPaths: /* @__PURE__ */ new Set(),
|
|
1498
|
+
pathGlobs: [],
|
|
1499
|
+
keyGlobs: [],
|
|
1500
|
+
caseInsensitiveLeaves: /* @__PURE__ */ new Set()
|
|
1501
|
+
};
|
|
1200
1502
|
const patch = [];
|
|
1201
|
-
function isRedacted(path) {
|
|
1202
|
-
if (redactSet.size === 0) return false;
|
|
1203
|
-
if (redactSet.has(path)) return true;
|
|
1204
|
-
for (const p of redactSet) if (path.endsWith(`.${p}`)) return true;
|
|
1205
|
-
return false;
|
|
1206
|
-
}
|
|
1207
1503
|
function diff(a, b, path) {
|
|
1208
1504
|
if (a === b) return;
|
|
1209
1505
|
if (a === void 0 && b !== void 0) {
|
|
@@ -1233,16 +1529,7 @@ function auditDiff(before, after, options = {}) {
|
|
|
1233
1529
|
});
|
|
1234
1530
|
}
|
|
1235
1531
|
function redactValue(value, path) {
|
|
1236
|
-
|
|
1237
|
-
const segs = path.split("/").filter(Boolean);
|
|
1238
|
-
const last = segs[segs.length - 1];
|
|
1239
|
-
if (last && isRedacted(last)) return replacement;
|
|
1240
|
-
return value;
|
|
1241
|
-
}
|
|
1242
|
-
if (Array.isArray(value)) return value.map((v, i) => redactValue(v, `${path}/${i}`));
|
|
1243
|
-
const out = {};
|
|
1244
|
-
for (const [k, v] of Object.entries(value)) out[k] = isRedacted(k) ? replacement : redactValue(v, `${path}/${k}`);
|
|
1245
|
-
return out;
|
|
1532
|
+
return redactValueByPaths(value, pathMatchers, replacement, path);
|
|
1246
1533
|
}
|
|
1247
1534
|
diff(before, after, "");
|
|
1248
1535
|
const result = { patch };
|
|
@@ -1251,15 +1538,21 @@ function auditDiff(before, after, options = {}) {
|
|
|
1251
1538
|
return result;
|
|
1252
1539
|
}
|
|
1253
1540
|
/**
|
|
1254
|
-
* Define a typed audit action with
|
|
1541
|
+
* Define a typed audit action with optional fixed target type and catalog metadata.
|
|
1255
1542
|
*
|
|
1256
1543
|
* Returns a curried helper that fills in the action name (and target shape
|
|
1257
1544
|
* if provided) so call sites stay terse and the action set is discoverable
|
|
1258
|
-
* in one place.
|
|
1545
|
+
* in one place. Metadata (`description`, `severity`, `requiresChanges`, …)
|
|
1546
|
+
* is exposed on the factory for introspection, docs, and review tooling.
|
|
1259
1547
|
*
|
|
1260
1548
|
* @example
|
|
1261
1549
|
* ```ts
|
|
1262
|
-
* const refund = defineAuditAction('invoice.refund', {
|
|
1550
|
+
* const refund = defineAuditAction('invoice.refund', {
|
|
1551
|
+
* target: 'invoice',
|
|
1552
|
+
* severity: 'high',
|
|
1553
|
+
* requiresChanges: true,
|
|
1554
|
+
* redactPaths: ['cardNumber'],
|
|
1555
|
+
* })
|
|
1263
1556
|
*
|
|
1264
1557
|
* log.audit(refund({
|
|
1265
1558
|
* actor: { type: 'user', id: user.id },
|
|
@@ -1270,7 +1563,7 @@ function auditDiff(before, after, options = {}) {
|
|
|
1270
1563
|
*/
|
|
1271
1564
|
function defineAuditAction(action, options) {
|
|
1272
1565
|
const targetType = options?.target;
|
|
1273
|
-
|
|
1566
|
+
const factory = ((input) => {
|
|
1274
1567
|
const merged = {
|
|
1275
1568
|
...input,
|
|
1276
1569
|
action
|
|
@@ -1280,21 +1573,50 @@ function defineAuditAction(action, options) {
|
|
|
1280
1573
|
type: targetType
|
|
1281
1574
|
};
|
|
1282
1575
|
return merged;
|
|
1283
|
-
};
|
|
1576
|
+
});
|
|
1577
|
+
Object.defineProperties(factory, {
|
|
1578
|
+
action: {
|
|
1579
|
+
value: action,
|
|
1580
|
+
enumerable: true
|
|
1581
|
+
},
|
|
1582
|
+
target: {
|
|
1583
|
+
value: options?.target,
|
|
1584
|
+
enumerable: true
|
|
1585
|
+
},
|
|
1586
|
+
description: {
|
|
1587
|
+
value: options?.description,
|
|
1588
|
+
enumerable: true
|
|
1589
|
+
},
|
|
1590
|
+
severity: {
|
|
1591
|
+
value: options?.severity,
|
|
1592
|
+
enumerable: true
|
|
1593
|
+
},
|
|
1594
|
+
requiresChanges: {
|
|
1595
|
+
value: options?.requiresChanges,
|
|
1596
|
+
enumerable: true
|
|
1597
|
+
},
|
|
1598
|
+
requiresReason: {
|
|
1599
|
+
value: options?.requiresReason,
|
|
1600
|
+
enumerable: true
|
|
1601
|
+
},
|
|
1602
|
+
redactPaths: {
|
|
1603
|
+
value: options?.redactPaths,
|
|
1604
|
+
enumerable: true
|
|
1605
|
+
}
|
|
1606
|
+
});
|
|
1607
|
+
return factory;
|
|
1284
1608
|
}
|
|
1285
1609
|
/**
|
|
1286
1610
|
* Test helper that captures every audit event emitted while it is active.
|
|
1287
1611
|
*
|
|
1288
|
-
* Returns `{ events, restore,
|
|
1612
|
+
* Returns `{ events, restore, toIncludeAuditOf, assertAudit }`:
|
|
1289
1613
|
* - `events` — live array of captured `AuditFields`, populated as audits fire.
|
|
1290
1614
|
* - `restore()` — uninstall the collector. Call from `afterEach()`.
|
|
1291
|
-
* - `
|
|
1292
|
-
*
|
|
1615
|
+
* - `toIncludeAuditOf(matcher)` — returns `true` if at least one captured event matches.
|
|
1616
|
+
* - `assertAudit(matcher)` — returns the matched event or throws with a readable summary.
|
|
1293
1617
|
*
|
|
1294
|
-
*
|
|
1295
|
-
* `
|
|
1296
|
-
* collector by design — wrap them with `log.audit()` to make them visible to
|
|
1297
|
-
* tests.
|
|
1618
|
+
* Captures audits on emit from `log.audit()`, standalone `audit()`, and
|
|
1619
|
+
* `log.set({ audit })` — including auto-filled `idempotencyKey`.
|
|
1298
1620
|
*
|
|
1299
1621
|
* @example
|
|
1300
1622
|
* ```ts
|
|
@@ -1318,6 +1640,18 @@ function mockAudit() {
|
|
|
1318
1640
|
},
|
|
1319
1641
|
toIncludeAuditOf(matcher) {
|
|
1320
1642
|
return events.some((event) => matchesAudit(event, matcher));
|
|
1643
|
+
},
|
|
1644
|
+
assertAudit(matcher) {
|
|
1645
|
+
const match = events.find((event) => matchesAudit(event, matcher));
|
|
1646
|
+
if (!match) {
|
|
1647
|
+
const summary = events.map((e) => ({
|
|
1648
|
+
action: e.action,
|
|
1649
|
+
outcome: e.outcome
|
|
1650
|
+
}));
|
|
1651
|
+
const matcherStr = JSON.stringify(matcher, (_k, v) => v instanceof RegExp ? v.toString() : v);
|
|
1652
|
+
throw new Error(`No audit event matched ${matcherStr}. Captured ${events.length} event(s): ${JSON.stringify(summary)}`);
|
|
1653
|
+
}
|
|
1654
|
+
return match;
|
|
1321
1655
|
}
|
|
1322
1656
|
};
|
|
1323
1657
|
}
|
|
@@ -1358,7 +1692,9 @@ function consumeAuditForceKeep(context) {
|
|
|
1358
1692
|
function finalizeAudit(event) {
|
|
1359
1693
|
const a = event.audit;
|
|
1360
1694
|
if (!a) return;
|
|
1361
|
-
|
|
1695
|
+
const decorated = decorateAudit(a, String(event.timestamp));
|
|
1696
|
+
event.audit = decorated;
|
|
1697
|
+
_testCollector?.(decorated, event);
|
|
1362
1698
|
}
|
|
1363
1699
|
/**
|
|
1364
1700
|
* Enrich audit-bearing wide events with request, runtime, and tenant context.
|
|
@@ -1591,33 +1927,21 @@ function stripIntegrity(event) {
|
|
|
1591
1927
|
* enough signal to be useful.
|
|
1592
1928
|
*/
|
|
1593
1929
|
const auditRedactPreset = { paths: [
|
|
1594
|
-
"
|
|
1595
|
-
"
|
|
1596
|
-
"
|
|
1597
|
-
"
|
|
1598
|
-
"
|
|
1599
|
-
"
|
|
1600
|
-
"
|
|
1601
|
-
"
|
|
1602
|
-
"
|
|
1603
|
-
"
|
|
1604
|
-
"
|
|
1605
|
-
"
|
|
1606
|
-
"
|
|
1607
|
-
"audit.changes.after.apiKey",
|
|
1608
|
-
"audit.changes.after.secret",
|
|
1609
|
-
"audit.changes.after.accessToken",
|
|
1610
|
-
"audit.changes.after.refreshToken",
|
|
1611
|
-
"audit.changes.after.cardNumber",
|
|
1612
|
-
"audit.changes.after.cvv",
|
|
1613
|
-
"audit.changes.after.ssn",
|
|
1614
|
-
"headers.authorization",
|
|
1615
|
-
"headers.cookie",
|
|
1616
|
-
"headers.set-cookie",
|
|
1617
|
-
"audit.context.headers.authorization",
|
|
1618
|
-
"audit.context.headers.cookie"
|
|
1930
|
+
"password",
|
|
1931
|
+
"passwordHash",
|
|
1932
|
+
"token",
|
|
1933
|
+
"apiKey",
|
|
1934
|
+
"secret",
|
|
1935
|
+
"accessToken",
|
|
1936
|
+
"refreshToken",
|
|
1937
|
+
"cardNumber",
|
|
1938
|
+
"cvv",
|
|
1939
|
+
"ssn",
|
|
1940
|
+
"authorization",
|
|
1941
|
+
"cookie",
|
|
1942
|
+
"set-cookie"
|
|
1619
1943
|
] };
|
|
1620
1944
|
//#endregion
|
|
1621
|
-
export {
|
|
1945
|
+
export { enricherPlugin as A, lockLogger as C, createPluginRunner as D, shouldKeep as E, resolveRedactConfig as F, isGloballyRedacted as M, normalizeRedactConfig as N, definePlugin as O, redactEvent as P, isLoggerLocked as S, mergeInto as T, getEnvironment as _, auditEnricher as a, initLogger as b, buildAuditFields as c, signed as d, withAudit as f, createRequestLogger as g, createLogger as h, auditDiff as i, getEmptyPluginRunner as j, drainPlugin as k, defineAuditAction as l, _log as m, AuditDeniedError as n, auditOnly as o, withAuditMethods as p, audit as r, auditRedactPreset as s, AUDIT_SCHEMA_VERSION as t, mockAudit as u, getGlobalDrain as v, markWideEventDrainStarted as w, isEnabled as x, getGlobalPluginRunner as y };
|
|
1622
1946
|
|
|
1623
|
-
//# sourceMappingURL=audit-
|
|
1947
|
+
//# sourceMappingURL=audit-BFwTUxBJ.mjs.map
|