@warlock.js/logger 5.32.0 → 5.34.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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to `@warlock.js/logger` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.33.0 - 2026-10-19
8
+
9
+ ### Added
10
+
11
+ - Add `registerLogSecret(value, keys?)` and `maskRegisteredLogSecrets(text)` for process-lifetime credential masking. Registered keys and literal values remain protected with defaults disabled or custom censors, including free text, Error causes and channel failure diagnostics. The safety pass masks opaque objects and does not invoke serializers/getters.
12
+
7
13
  ## 5.32.0 - 2026-10-18
8
14
 
9
15
  ### Changed
@@ -59,73 +65,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
59
65
 
60
66
  ### Changed
61
67
 
62
- - Lockstep release; package APIs are unchanged. Skills refer to other topics by name instead of file paths, so cross-references keep working after `agent-kit` copies them into an app.
68
+ - Skills refer to other topics by name instead of file paths, so cross-references keep working after `agent-kit` copies them into an app.
63
69
 
64
70
  ## 5.28.0 - 2026-10-01
65
71
 
66
72
  ### Changed
67
73
 
68
- - Lockstep release; package APIs are unchanged. `llms.txt` now lists every skill topic with its description (frontmatter in CRLF files was skipped).
69
-
70
- ## 5.27.0 - 2026-10-01
71
-
72
- ### Changed
73
-
74
- - Lockstep release; package APIs are unchanged.
75
-
76
- ## 5.26.0 - 2026-09-30
77
-
78
- ### Changed
79
-
80
- - Lockstep release; package APIs are unchanged.
81
-
82
- ## 5.25.0 - 2026-09-28
83
-
84
- ### Changed
85
-
86
- - Lockstep release; package APIs are unchanged.
87
-
88
- ## 5.24.0 - 2026-09-27
89
-
90
- ### Changed
91
-
92
- - Lockstep release; package APIs are unchanged.
93
-
94
- ## 5.23.2 - 2026-09-26
95
-
96
- ### Changed
97
-
98
- - Lockstep patch release; package APIs are unchanged.
99
-
100
- ## 5.23.1 - 2026-09-26
101
-
102
- ### Changed
103
-
104
- - Lockstep patch release; package APIs are unchanged.
105
-
106
- ## 5.23.0 - 2026-09-25
107
-
108
- ### Changed
109
-
110
- - Lockstep patch release; package APIs are unchanged.
111
-
112
- ## 5.22.1 - 2026-09-25
113
-
114
- ### Changed
115
-
116
- - Lockstep patch release; package APIs are unchanged.
117
-
118
- ## 5.22.0 - 2026-09-25
119
-
120
- ### Changed
121
-
122
- - Lockstep release maintenance and dependency refresh.
123
-
124
- ## 5.21.0 - 2026-09-25
125
-
126
- ### Changed
127
-
128
- - Lockstep release maintenance and dependency refresh.
74
+ - `llms.txt` now lists every skill topic with its description (frontmatter in CRLF files was skipped).
129
75
 
130
76
  ## 5.20.0 - 2026-09-24
131
77
 
@@ -145,18 +91,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
145
91
 
146
92
  - Use the package-resolved TypeScript binary for type checking.
147
93
 
148
- ## 5.11.0 - 2026-09-14
149
-
150
- _Released in lockstep with the `@warlock.js/*` family; no package-specific changes in 5.11.0._
151
-
152
- ## 5.10.0 - 2026-09-14
153
-
154
- _Released in lockstep with the `@warlock.js/*` family; no package-specific changes in 5.10.0._
155
-
156
- ## 5.9.0 - 2026-09-13
157
-
158
- _Released in lockstep with the `@warlock.js/*` family; no package-specific changes in 5.9.0._
159
-
160
94
  ## 5.7.0 - 2026-09-11
161
95
 
162
96
  ### Fixed
@@ -173,12 +107,6 @@ _Released in lockstep with the `@warlock.js/*` family; no package-specific chang
173
107
 
174
108
  - Documentation shipped in this package's `skills/` told users to run `pnpm`-specific commands. `pnpm <binary>` has no npm equivalent, so those instructions failed outright for anyone not using pnpm. Commands are now package-manager neutral.
175
109
 
176
- ## 5.2.3 - 2026-09-02
177
-
178
- ### Fixed
179
-
180
- - Released in exact lockstep with Core's Web generator repairs so every family dependency remains installable at 5.2.3.
181
-
182
110
  ## 5.2.2
183
111
 
184
112
  - Documented: the README, CHANGELOG, and `overview` skill now describe the
@@ -189,29 +117,6 @@ _Released in lockstep with the `@warlock.js/*` family; no package-specific chang
189
117
  code must not value-import this package, type-only imports are allowed, and
190
118
  server loaders/controllers/modules may import it freely. No source change.
191
119
 
192
- ## 5.1.0
193
-
194
- No changes to `@warlock.js/logger`. Released in lockstep with the `@warlock.js/web`
195
- React-execution fix and the `@warlock.js/core` CLI additions — see those packages'
196
- changelogs.
197
-
198
- ## 5.0.2 - 2026-08-25
199
-
200
- No changes to `@warlock.js/logger`. Released in lockstep with the `@warlock.js/web` SSR
201
- fix (`ssr.noExternal`) — see that package's changelog.
202
-
203
- ## 5.0.1 - 2026-08-25
204
-
205
- No changes to `@warlock.js/logger`. Released in lockstep with the `create-warlock` vite
206
- resolution pin and the `@warlock.js/web` peer narrowing — see those packages'
207
- changelogs.
208
-
209
- ## 5.0.0 - 2026-08-25
210
-
211
- ### Changed
212
-
213
- - This package is unchanged in 5.0.0; its version moved only because the Warlock family releases in lockstep.
214
-
215
120
  ## 4.16.0 - 2026-08-18
216
121
 
217
122
  ### Security
package/cjs/index.cjs CHANGED
@@ -39,6 +39,221 @@ path = __toESM(path, 1);
39
39
  let safe_stable_stringify = require("safe-stable-stringify");
40
40
  let _mongez_reinforcements = require("@mongez/reinforcements");
41
41
 
42
+ //#region ../../packages/logger/src/redact/default-keys.ts
43
+ /**
44
+ * Built-in secret-key denylist — the redaction floor that applies with no
45
+ * configuration at all.
46
+ *
47
+ * ## Why a default list exists
48
+ *
49
+ * Path-based `redact.paths` is a *tool*; it only protects an application whose
50
+ * every call site was configured correctly, and nothing warns you when one
51
+ * wasn't. The overwhelmingly common leak is mundane and needs no attacker
52
+ * input: `log.error("auth", "login", "failed", { headers: req.headers, body:
53
+ * req.body })` puts a live bearer token and a cleartext password into every
54
+ * sink. A key denylist that runs by default turns redaction from a tool into a
55
+ * default protection.
56
+ *
57
+ * ## Matching semantics — exact, on a normalized key
58
+ *
59
+ * Keys are compared after {@link normalizeRedactKey}: lower-cased with every
60
+ * non-alphanumeric character removed. So one entry covers every spelling
61
+ * convention a codebase might use —
62
+ * `apiKey` / `api_key` / `API-KEY` / `apikey` all normalize to `apikey`.
63
+ *
64
+ * The match is **exact on the normalized key, not a substring**. That is a
65
+ * deliberate trade: substring matching (`*token*`) would also swallow
66
+ * `tokenCount`, `passwordUpdatedAt`, `secretsLoaded` — silent, hard-to-debug
67
+ * data loss in the one place engineers look when something is broken. An exact
68
+ * list is auditable: you can read it and know precisely what disappears. The
69
+ * cost is that unusual spellings are missed, which is why the list carries the
70
+ * concrete wire-format variants that actually show up in HTTP headers
71
+ * (`x-api-key`, `proxy-authorization`, `set-cookie`) and why apps can extend it
72
+ * with `redact.keys`.
73
+ *
74
+ * ## What is deliberately NOT here
75
+ *
76
+ * `key`, `auth`, `hash`, `signature`, `salt`, `id` — all too generic. Each
77
+ * would redact far more non-secret fields than secret ones (`key` alone would
78
+ * blank out every `key` in a keyed collection). Applications that want them
79
+ * add them via `redact.keys`.
80
+ */
81
+ /**
82
+ * Normalize a key for denylist comparison: lower-case, strip every
83
+ * non-alphanumeric character. Collapses `apiKey`, `api_key`, `API-KEY`,
84
+ * `Api Key` and `apikey` onto a single entry.
85
+ */
86
+ function normalizeRedactKey(key) {
87
+ return key.toLowerCase().replace(/[^a-z0-9]/g, "");
88
+ }
89
+ /**
90
+ * The default denylist, in source spelling. Anything whose normalized key
91
+ * matches one of these is replaced by the configured censor (`"[REDACTED]"`
92
+ * by default) at any depth of `context`, `message`, or an `Error`'s own
93
+ * enumerable properties.
94
+ *
95
+ * Exported so applications can inspect, log, or build on the exact set they
96
+ * are getting rather than guessing at it.
97
+ */
98
+ const DEFAULT_REDACT_KEYS = [
99
+ "password",
100
+ "passwd",
101
+ "pwd",
102
+ "passphrase",
103
+ "passwordHash",
104
+ "currentPassword",
105
+ "newPassword",
106
+ "passwordConfirmation",
107
+ "secret",
108
+ "clientSecret",
109
+ "appSecret",
110
+ "apiSecret",
111
+ "secretKey",
112
+ "token",
113
+ "accessToken",
114
+ "refreshToken",
115
+ "idToken",
116
+ "authToken",
117
+ "apiToken",
118
+ "bearerToken",
119
+ "csrfToken",
120
+ "sessionToken",
121
+ "resetToken",
122
+ "verificationToken",
123
+ "jwt",
124
+ "otp",
125
+ "apiKey",
126
+ "privateKey",
127
+ "encryptionKey",
128
+ "signingKey",
129
+ "authorization",
130
+ "proxyAuthorization",
131
+ "x-api-key",
132
+ "x-auth-token",
133
+ "cookie",
134
+ "set-cookie",
135
+ "sessionId",
136
+ "credentials",
137
+ "credential",
138
+ "connectionString",
139
+ "creditCard",
140
+ "creditCardNumber",
141
+ "cardNumber",
142
+ "cvv",
143
+ "cvc",
144
+ "ssn",
145
+ "socialSecurityNumber",
146
+ "iban",
147
+ "taxId"
148
+ ];
149
+ /**
150
+ * The default denylist, pre-normalized. Frozen at module load so the hot path
151
+ * never rebuilds it.
152
+ */
153
+ const DEFAULT_REDACT_KEY_SET = new Set(DEFAULT_REDACT_KEYS.map(normalizeRedactKey));
154
+
155
+ //#endregion
156
+ //#region ../../packages/logger/src/redact/registered-secrets.ts
157
+ const keys = /* @__PURE__ */ new Set();
158
+ const values = /* @__PURE__ */ new Set();
159
+ const MASK = "[REDACTED]";
160
+ let orderedValues = [];
161
+ /**
162
+ * Register credentials for process-lifetime masking in every Logger instance.
163
+ * Empty values are ignored. Old values remain protected after rotation/removal.
164
+ * This safety floor is independent of redact config and custom censors.
165
+ */
166
+ function registerLogSecret(value, secretKeys = []) {
167
+ for (const key of secretKeys) {
168
+ const normalized = normalizeRedactKey(key);
169
+ if (normalized) keys.add(normalized);
170
+ }
171
+ if (!value || values.has(value)) return;
172
+ values.add(value);
173
+ orderedValues = [...values].sort((left, right) => right.length - left.length);
174
+ }
175
+ /** Exact substring masking; no encoding, hashing, or fuzzy matching. */
176
+ function maskRegisteredLogSecrets(text) {
177
+ if (orderedValues.length === 0) return text;
178
+ let cursor = 0;
179
+ let result = "";
180
+ while (cursor < text.length) {
181
+ let next = -1;
182
+ let length = 0;
183
+ for (const secret of orderedValues) {
184
+ const index = text.indexOf(secret, cursor);
185
+ if (index !== -1 && (next === -1 || index < next)) {
186
+ next = index;
187
+ length = secret.length;
188
+ }
189
+ }
190
+ if (next === -1) return result + text.slice(cursor);
191
+ result += text.slice(cursor, next) + MASK;
192
+ cursor = next + length;
193
+ }
194
+ return result;
195
+ }
196
+ /** @internal Final safety pass, after user censors have run. */
197
+ function redactRegisteredSecrets(value) {
198
+ if (keys.size === 0 && values.size === 0) return value;
199
+ const seen = /* @__PURE__ */ new WeakMap();
200
+ function visit(value) {
201
+ if (typeof value === "string") return maskRegisteredLogSecrets(value);
202
+ if (typeof value === "function" || typeof value === "symbol") return MASK;
203
+ if (value === null || typeof value !== "object") return value;
204
+ if (seen.has(value)) return seen.get(value);
205
+ if (value instanceof Date) return new Date(Date.prototype.getTime.call(value));
206
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof WeakMap || value instanceof WeakSet || value instanceof Promise || value instanceof RegExp) return MASK;
207
+ if (value instanceof Map) {
208
+ const copy = /* @__PURE__ */ new Map();
209
+ seen.set(value, copy);
210
+ for (const [key, child] of Map.prototype.entries.call(value)) copy.set(visit(key), typeof key === "string" && keys.has(normalizeRedactKey(key)) ? MASK : visit(child));
211
+ return copy;
212
+ }
213
+ if (value instanceof Set) {
214
+ const copy = /* @__PURE__ */ new Set();
215
+ seen.set(value, copy);
216
+ for (const child of Set.prototype.values.call(value)) copy.add(visit(child));
217
+ return copy;
218
+ }
219
+ const copy = value instanceof Error ? /* @__PURE__ */ new Error() : Array.isArray(value) ? [] : {};
220
+ seen.set(value, copy);
221
+ for (const key of Reflect.ownKeys(value)) {
222
+ if (Array.isArray(value) && key === "length") continue;
223
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
224
+ if (!descriptor) continue;
225
+ if (typeof key === "symbol") continue;
226
+ const name = maskRegisteredLogSecrets(key);
227
+ const hidden = keys.has(normalizeRedactKey(key));
228
+ const child = "value" in descriptor ? descriptor.value : MASK;
229
+ Object.defineProperty(copy, name, {
230
+ value: hidden ? MASK : visit(child),
231
+ enumerable: descriptor.enumerable,
232
+ writable: true,
233
+ configurable: true
234
+ });
235
+ }
236
+ if (value instanceof Error && !Object.hasOwn(copy, "name")) {
237
+ let prototype = Object.getPrototypeOf(value);
238
+ while (prototype) {
239
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, "name");
240
+ if (descriptor) {
241
+ const name = "value" in descriptor ? descriptor.value : MASK;
242
+ Object.defineProperty(copy, "name", {
243
+ value: typeof name === "string" ? maskRegisteredLogSecrets(name) : MASK,
244
+ configurable: true
245
+ });
246
+ break;
247
+ }
248
+ prototype = Object.getPrototypeOf(prototype);
249
+ }
250
+ }
251
+ return copy;
252
+ }
253
+ return visit(value);
254
+ }
255
+
256
+ //#endregion
42
257
  //#region ../../packages/logger/src/log-channel.ts
43
258
  var LogChannel = class {
44
259
  /**
@@ -74,7 +289,7 @@ var LogChannel = class {
74
289
  return;
75
290
  }
76
291
  const reason = error instanceof Error ? error.message : String(error);
77
- process.stderr.write(`[@warlock.js/logger] channel "${this.name}" failed: ${reason}\n`);
292
+ process.stderr.write(maskRegisteredLogSecrets(`[@warlock.js/logger] channel "${this.name}" failed: ${reason}\n`));
78
293
  } catch {}
79
294
  }
80
295
  /**
@@ -1082,120 +1297,6 @@ var SentryLog = class extends LogChannel {
1082
1297
  }
1083
1298
  };
1084
1299
 
1085
- //#endregion
1086
- //#region ../../packages/logger/src/redact/default-keys.ts
1087
- /**
1088
- * Built-in secret-key denylist — the redaction floor that applies with no
1089
- * configuration at all.
1090
- *
1091
- * ## Why a default list exists
1092
- *
1093
- * Path-based `redact.paths` is a *tool*; it only protects an application whose
1094
- * every call site was configured correctly, and nothing warns you when one
1095
- * wasn't. The overwhelmingly common leak is mundane and needs no attacker
1096
- * input: `log.error("auth", "login", "failed", { headers: req.headers, body:
1097
- * req.body })` puts a live bearer token and a cleartext password into every
1098
- * sink. A key denylist that runs by default turns redaction from a tool into a
1099
- * default protection.
1100
- *
1101
- * ## Matching semantics — exact, on a normalized key
1102
- *
1103
- * Keys are compared after {@link normalizeRedactKey}: lower-cased with every
1104
- * non-alphanumeric character removed. So one entry covers every spelling
1105
- * convention a codebase might use —
1106
- * `apiKey` / `api_key` / `API-KEY` / `apikey` all normalize to `apikey`.
1107
- *
1108
- * The match is **exact on the normalized key, not a substring**. That is a
1109
- * deliberate trade: substring matching (`*token*`) would also swallow
1110
- * `tokenCount`, `passwordUpdatedAt`, `secretsLoaded` — silent, hard-to-debug
1111
- * data loss in the one place engineers look when something is broken. An exact
1112
- * list is auditable: you can read it and know precisely what disappears. The
1113
- * cost is that unusual spellings are missed, which is why the list carries the
1114
- * concrete wire-format variants that actually show up in HTTP headers
1115
- * (`x-api-key`, `proxy-authorization`, `set-cookie`) and why apps can extend it
1116
- * with `redact.keys`.
1117
- *
1118
- * ## What is deliberately NOT here
1119
- *
1120
- * `key`, `auth`, `hash`, `signature`, `salt`, `id` — all too generic. Each
1121
- * would redact far more non-secret fields than secret ones (`key` alone would
1122
- * blank out every `key` in a keyed collection). Applications that want them
1123
- * add them via `redact.keys`.
1124
- */
1125
- /**
1126
- * Normalize a key for denylist comparison: lower-case, strip every
1127
- * non-alphanumeric character. Collapses `apiKey`, `api_key`, `API-KEY`,
1128
- * `Api Key` and `apikey` onto a single entry.
1129
- */
1130
- function normalizeRedactKey(key) {
1131
- return key.toLowerCase().replace(/[^a-z0-9]/g, "");
1132
- }
1133
- /**
1134
- * The default denylist, in source spelling. Anything whose normalized key
1135
- * matches one of these is replaced by the configured censor (`"[REDACTED]"`
1136
- * by default) at any depth of `context`, `message`, or an `Error`'s own
1137
- * enumerable properties.
1138
- *
1139
- * Exported so applications can inspect, log, or build on the exact set they
1140
- * are getting rather than guessing at it.
1141
- */
1142
- const DEFAULT_REDACT_KEYS = [
1143
- "password",
1144
- "passwd",
1145
- "pwd",
1146
- "passphrase",
1147
- "passwordHash",
1148
- "currentPassword",
1149
- "newPassword",
1150
- "passwordConfirmation",
1151
- "secret",
1152
- "clientSecret",
1153
- "appSecret",
1154
- "apiSecret",
1155
- "secretKey",
1156
- "token",
1157
- "accessToken",
1158
- "refreshToken",
1159
- "idToken",
1160
- "authToken",
1161
- "apiToken",
1162
- "bearerToken",
1163
- "csrfToken",
1164
- "sessionToken",
1165
- "resetToken",
1166
- "verificationToken",
1167
- "jwt",
1168
- "otp",
1169
- "apiKey",
1170
- "privateKey",
1171
- "encryptionKey",
1172
- "signingKey",
1173
- "authorization",
1174
- "proxyAuthorization",
1175
- "x-api-key",
1176
- "x-auth-token",
1177
- "cookie",
1178
- "set-cookie",
1179
- "sessionId",
1180
- "credentials",
1181
- "credential",
1182
- "connectionString",
1183
- "creditCard",
1184
- "creditCardNumber",
1185
- "cardNumber",
1186
- "cvv",
1187
- "cvc",
1188
- "ssn",
1189
- "socialSecurityNumber",
1190
- "iban",
1191
- "taxId"
1192
- ];
1193
- /**
1194
- * The default denylist, pre-normalized. Frozen at module load so the hot path
1195
- * never rebuilds it.
1196
- */
1197
- const DEFAULT_REDACT_KEY_SET = new Set(DEFAULT_REDACT_KEYS.map(normalizeRedactKey));
1198
-
1199
1300
  //#endregion
1200
1301
  //#region ../../packages/logger/src/redact/redact.ts
1201
1302
  const DEFAULT_CENSOR = "[REDACTED]";
@@ -1402,17 +1503,19 @@ function resolveRedactKeys(config) {
1402
1503
  *
1403
1504
  * ## Residual gaps (by design, documented rather than silently absent)
1404
1505
  *
1405
- * - **Secrets interpolated into a `message` string** (`` `token=${t}` ``)
1406
- * cannot be reached — neither a path nor a key names a substring.
1407
- * - **`Map`/`Set`/`Buffer` contents** are not traversed (see {@link isOpaque}).
1408
- * - **Non-enumerable / getter-backed properties** are not walked, so an HTTP
1409
- * client that exposes request config behind a getter still slips through.
1410
- * Enumerable ones (axios's `.config`, `.response`) *are* covered.
1506
+ * - **Unregistered secrets interpolated into strings** cannot be reached.
1507
+ * registerLogSecret protects known literal values, including Error text.
1508
+ * - Without registered credentials, **`Map`/`Set`/`Buffer` contents** are
1509
+ * not traversed (see {@link isOpaque}). Registered credentials add a
1510
+ * final safety pass that traverses Maps/Sets and masks opaque objects.
1511
+ * - Key/path redaction does not walk non-enumerable properties. With
1512
+ * registered credentials the final pass walks data descriptors and replaces
1513
+ * accessors without invoking them.
1411
1514
  */
1412
1515
  function applyRedact(data, config) {
1413
1516
  const paths = config?.paths ?? [];
1414
1517
  const keys = resolveRedactKeys(config);
1415
- if (paths.length === 0 && !keys) return data;
1518
+ if (paths.length === 0 && !keys) return redactRegisteredSecrets(data);
1416
1519
  const censor = config?.censor ?? DEFAULT_CENSOR;
1417
1520
  let result = data;
1418
1521
  const censored = /* @__PURE__ */ new Set();
@@ -1429,7 +1532,7 @@ function applyRedact(data, config) {
1429
1532
  censor,
1430
1533
  alreadyCensored: censored
1431
1534
  });
1432
- return result;
1535
+ return redactRegisteredSecrets(result);
1433
1536
  }
1434
1537
  /**
1435
1538
  * Combine two redact configs into one effective config. Used to merge a
@@ -1774,7 +1877,7 @@ var Logger = class {
1774
1877
  }
1775
1878
  reportChannelError(error, channel, entry) {
1776
1879
  try {
1777
- const outcome = this.channelErrorHandler(error, channel, entry);
1880
+ const outcome = this.channelErrorHandler(redactRegisteredSecrets(error), channel, redactRegisteredSecrets(entry));
1778
1881
  if (outcome && typeof outcome.then === "function") outcome.then(void 0, () => {});
1779
1882
  } catch {}
1780
1883
  }
@@ -2013,7 +2116,7 @@ function redactionFailedEntry(data) {
2013
2116
  function reportChannelError(error, channel) {
2014
2117
  const reason = error instanceof Error ? error.message : String(error);
2015
2118
  try {
2016
- process.stderr.write(`[@warlock.js/logger] channel "${channel.name}" failed to log: ${reason}\n`);
2119
+ process.stderr.write(maskRegisteredLogSecrets(`[@warlock.js/logger] channel "${channel.name}" failed to log: ${reason}\n`));
2017
2120
  } catch {}
2018
2121
  }
2019
2122
  /**
@@ -2102,8 +2205,10 @@ exports.escapeLogValue = escapeLogValue;
2102
2205
  exports.log = log;
2103
2206
  exports.maskEmail = maskEmail;
2104
2207
  exports.maskEmailsInText = maskEmailsInText;
2208
+ exports.maskRegisteredLogSecrets = maskRegisteredLogSecrets;
2105
2209
  exports.mergeRedact = mergeRedact;
2106
2210
  exports.normalizeRedactKey = normalizeRedactKey;
2211
+ exports.registerLogSecret = registerLogSecret;
2107
2212
  exports.resolveRedactKeys = resolveRedactKeys;
2108
2213
  exports.safeJsonStringify = safeJsonStringify;
2109
2214
  //# sourceMappingURL=index.cjs.map