logixia 1.13.0 → 1.13.3

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 (154) hide show
  1. package/README.md +9 -0
  2. package/dist/{async-context-CwBNMm2E.mjs → async-context-BzJrbfQs.mjs} +8 -4
  3. package/dist/async-context-BzJrbfQs.mjs.map +1 -0
  4. package/dist/{async-context-CSHWoHMB.js → async-context-DyQQYq3I.js} +8 -4
  5. package/dist/async-context-DyQQYq3I.js.map +1 -0
  6. package/dist/{azure-monitor.transport-CG7ClkYj.d.ts → azure-monitor.transport-BDFO4F-i.d.ts} +2 -2
  7. package/dist/{azure-monitor.transport-CG7ClkYj.d.ts.map → azure-monitor.transport-BDFO4F-i.d.ts.map} +1 -1
  8. package/dist/{azure-monitor.transport-Cm74kXZS.d.mts → azure-monitor.transport-D5wQEH04.d.mts} +2 -2
  9. package/dist/{azure-monitor.transport-Cm74kXZS.d.mts.map → azure-monitor.transport-D5wQEH04.d.mts.map} +1 -1
  10. package/dist/azure.d.mts +2 -2
  11. package/dist/azure.d.ts +2 -2
  12. package/dist/cli/index.js +98 -52
  13. package/dist/cloudwatch.d.mts +2 -2
  14. package/dist/cloudwatch.d.ts +2 -2
  15. package/dist/cloudwatch.js +2 -1
  16. package/dist/cloudwatch.mjs +2 -1
  17. package/dist/{cloudwatch.transport-CGHY4buE.d.mts → cloudwatch.transport-B00st6Xv.d.ts} +9 -2
  18. package/dist/cloudwatch.transport-B00st6Xv.d.ts.map +1 -0
  19. package/dist/{cloudwatch.transport-pNBNWJLt.js → cloudwatch.transport-BO1ahxw-.js} +26 -19
  20. package/dist/cloudwatch.transport-BO1ahxw-.js.map +1 -0
  21. package/dist/{cloudwatch.transport-DK_8cKd3.d.ts → cloudwatch.transport-Blc7Gtxt.d.mts} +9 -2
  22. package/dist/cloudwatch.transport-Blc7Gtxt.d.mts.map +1 -0
  23. package/dist/{cloudwatch.transport-yBwm4OeO.mjs → cloudwatch.transport-DZ6ies7g.mjs} +26 -19
  24. package/dist/cloudwatch.transport-DZ6ies7g.mjs.map +1 -0
  25. package/dist/{coerce.utils-BN980Y9V.js → coerce.utils-B-LilukN.js} +1 -1
  26. package/dist/{coerce.utils-BN980Y9V.js.map → coerce.utils-B-LilukN.js.map} +1 -1
  27. package/dist/{coerce.utils-Dxv4_ikC.mjs → coerce.utils-Cu6IUTgX.mjs} +1 -1
  28. package/dist/{coerce.utils-Dxv4_ikC.mjs.map → coerce.utils-Cu6IUTgX.mjs.map} +1 -1
  29. package/dist/correlation.d.mts +24 -6
  30. package/dist/correlation.d.mts.map +1 -1
  31. package/dist/correlation.d.ts +24 -6
  32. package/dist/correlation.d.ts.map +1 -1
  33. package/dist/correlation.js +41 -16
  34. package/dist/correlation.js.map +1 -1
  35. package/dist/correlation.mjs +41 -16
  36. package/dist/correlation.mjs.map +1 -1
  37. package/dist/entry-fields-BJkuPnIg.mjs +30 -0
  38. package/dist/entry-fields-BJkuPnIg.mjs.map +1 -0
  39. package/dist/entry-fields-BvOLFlJ4.js +36 -0
  40. package/dist/entry-fields-BvOLFlJ4.js.map +1 -0
  41. package/dist/gcp.d.mts +2 -2
  42. package/dist/gcp.d.ts +2 -2
  43. package/dist/gcp.js +2 -1
  44. package/dist/gcp.mjs +2 -1
  45. package/dist/{gcp.transport-SHdtc1n0.js → gcp.transport-CHV8MGgz.js} +5 -5
  46. package/dist/gcp.transport-CHV8MGgz.js.map +1 -0
  47. package/dist/{gcp.transport-BJuNRFe_.mjs → gcp.transport-DBX5TPIy.mjs} +5 -5
  48. package/dist/gcp.transport-DBX5TPIy.mjs.map +1 -0
  49. package/dist/{gcp.transport-BOhkVKlI.d.ts → gcp.transport-m4fVw0b1.d.ts} +2 -2
  50. package/dist/gcp.transport-m4fVw0b1.d.ts.map +1 -0
  51. package/dist/{gcp.transport-Bi6CUqZR.d.mts → gcp.transport-zzNyIoih.d.mts} +2 -2
  52. package/dist/gcp.transport-zzNyIoih.d.mts.map +1 -0
  53. package/dist/{index-BPKwwERo.d.mts → index-BPwEisy4.d.mts} +2 -2
  54. package/dist/{index-BPKwwERo.d.mts.map → index-BPwEisy4.d.mts.map} +1 -1
  55. package/dist/{index-C1X-TE5I.d.ts → index-nZEeCr3X.d.ts} +2 -2
  56. package/dist/{index-C1X-TE5I.d.ts.map → index-nZEeCr3X.d.ts.map} +1 -1
  57. package/dist/index.d.mts +63 -98
  58. package/dist/index.d.mts.map +1 -1
  59. package/dist/index.d.ts +63 -98
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +167 -443
  62. package/dist/index.js.map +1 -1
  63. package/dist/index.mjs +98 -377
  64. package/dist/index.mjs.map +1 -1
  65. package/dist/middleware.d.mts +11 -4
  66. package/dist/middleware.d.mts.map +1 -1
  67. package/dist/middleware.d.ts +11 -4
  68. package/dist/middleware.d.ts.map +1 -1
  69. package/dist/middleware.js +148 -24
  70. package/dist/middleware.js.map +1 -1
  71. package/dist/middleware.mjs +148 -24
  72. package/dist/middleware.mjs.map +1 -1
  73. package/dist/nest.d.mts +4 -4
  74. package/dist/nest.d.ts +4 -4
  75. package/dist/nest.js +20 -11
  76. package/dist/nest.mjs +7 -5
  77. package/dist/{logitron-logger.module-BsDZR5BH.js → nestjs-extras-DnJ6vrIC.js} +562 -444
  78. package/dist/nestjs-extras-DnJ6vrIC.js.map +1 -0
  79. package/dist/{logitron-logger.module-Bs3XYZgF.mjs → nestjs-extras-ImbuDhs1.mjs} +505 -349
  80. package/dist/nestjs-extras-ImbuDhs1.mjs.map +1 -0
  81. package/dist/{logitron-logger.module-CbXy2gfW.d.ts → nestjs-extras-OkC796py.d.mts} +111 -4
  82. package/dist/nestjs-extras-OkC796py.d.mts.map +1 -0
  83. package/dist/{logitron-logger.module-BdG1Jnpk.d.mts → nestjs-extras-mKrHE9S6.d.ts} +111 -4
  84. package/dist/nestjs-extras-mKrHE9S6.d.ts.map +1 -0
  85. package/dist/{search-njTI2hdo.js → search-B0MH1SJJ.js} +23 -10
  86. package/dist/search-B0MH1SJJ.js.map +1 -0
  87. package/dist/{search-DujhR94O.d.ts → search-BfBzDIT9.d.mts} +2 -3
  88. package/dist/search-BfBzDIT9.d.mts.map +1 -0
  89. package/dist/{search-CQOo-Iq6.d.mts → search-CHUZPl0h.d.ts} +2 -3
  90. package/dist/search-CHUZPl0h.d.ts.map +1 -0
  91. package/dist/{search-CFQRISUv.mjs → search-DjXSn6v5.mjs} +23 -10
  92. package/dist/search-DjXSn6v5.mjs.map +1 -0
  93. package/dist/search.d.mts +3 -3
  94. package/dist/search.d.ts +3 -3
  95. package/dist/search.js +2 -2
  96. package/dist/search.mjs +2 -2
  97. package/dist/testing.d.mts +2 -2
  98. package/dist/testing.d.ts +2 -2
  99. package/dist/trace.utils-CvXgaiQT.mjs +278 -0
  100. package/dist/trace.utils-CvXgaiQT.mjs.map +1 -0
  101. package/dist/trace.utils-DpBOLDtq.js +358 -0
  102. package/dist/trace.utils-DpBOLDtq.js.map +1 -0
  103. package/dist/{transport.manager-D6KL3t9V.mjs → transport.manager-CpdVHEGP.mjs} +365 -86
  104. package/dist/transport.manager-CpdVHEGP.mjs.map +1 -0
  105. package/dist/{transport.manager-BivyUTtU.js → transport.manager-Crau3Rle.js} +370 -85
  106. package/dist/transport.manager-Crau3Rle.js.map +1 -0
  107. package/dist/{transport.types-B5vcyv2k.d.mts → transport.types-CtNr3D7S.d.mts} +19 -2
  108. package/dist/transport.types-CtNr3D7S.d.mts.map +1 -0
  109. package/dist/{transport.types-BuY84TwO.d.ts → transport.types-DqVLZTyf.d.ts} +19 -2
  110. package/dist/transport.types-DqVLZTyf.d.ts.map +1 -0
  111. package/dist/transports.d.mts +38 -13
  112. package/dist/transports.d.mts.map +1 -1
  113. package/dist/transports.d.ts +38 -13
  114. package/dist/transports.d.ts.map +1 -1
  115. package/dist/transports.js +6 -5
  116. package/dist/transports.mjs +6 -5
  117. package/dist/worker-entry.js +307 -55
  118. package/dist/worker.d.mts +2 -2
  119. package/dist/worker.d.ts +2 -2
  120. package/dist/worker.js +1 -1
  121. package/dist/worker.mjs +1 -1
  122. package/dist/{worker.transport-BP8Q28Z2.d.mts → worker.transport-Bgv9heDI.d.mts} +2 -2
  123. package/dist/{worker.transport-BP8Q28Z2.d.mts.map → worker.transport-Bgv9heDI.d.mts.map} +1 -1
  124. package/dist/{worker.transport-mKXgNK0L.d.ts → worker.transport-Bj-i0P9V.d.ts} +2 -2
  125. package/dist/{worker.transport-mKXgNK0L.d.ts.map → worker.transport-Bj-i0P9V.d.ts.map} +1 -1
  126. package/dist/{worker.transport-CfH6z37Z.js → worker.transport-JP8YHBuU.js} +1 -1
  127. package/dist/{worker.transport-CfH6z37Z.js.map → worker.transport-JP8YHBuU.js.map} +1 -1
  128. package/dist/{worker.transport-BhMyvqQ2.mjs → worker.transport-otwhJ_Et.mjs} +1 -1
  129. package/dist/{worker.transport-BhMyvqQ2.mjs.map → worker.transport-otwhJ_Et.mjs.map} +1 -1
  130. package/package.json +10 -6
  131. package/dist/.tsbuildinfo +0 -1
  132. package/dist/async-context-CSHWoHMB.js.map +0 -1
  133. package/dist/async-context-CwBNMm2E.mjs.map +0 -1
  134. package/dist/cloudwatch.transport-CGHY4buE.d.mts.map +0 -1
  135. package/dist/cloudwatch.transport-DK_8cKd3.d.ts.map +0 -1
  136. package/dist/cloudwatch.transport-pNBNWJLt.js.map +0 -1
  137. package/dist/cloudwatch.transport-yBwm4OeO.mjs.map +0 -1
  138. package/dist/gcp.transport-BJuNRFe_.mjs.map +0 -1
  139. package/dist/gcp.transport-BOhkVKlI.d.ts.map +0 -1
  140. package/dist/gcp.transport-Bi6CUqZR.d.mts.map +0 -1
  141. package/dist/gcp.transport-SHdtc1n0.js.map +0 -1
  142. package/dist/logitron-logger.module-BdG1Jnpk.d.mts.map +0 -1
  143. package/dist/logitron-logger.module-Bs3XYZgF.mjs.map +0 -1
  144. package/dist/logitron-logger.module-BsDZR5BH.js.map +0 -1
  145. package/dist/logitron-logger.module-CbXy2gfW.d.ts.map +0 -1
  146. package/dist/search-CFQRISUv.mjs.map +0 -1
  147. package/dist/search-CQOo-Iq6.d.mts.map +0 -1
  148. package/dist/search-DujhR94O.d.ts.map +0 -1
  149. package/dist/search-njTI2hdo.js.map +0 -1
  150. package/dist/transport.manager-BivyUTtU.js.map +0 -1
  151. package/dist/transport.manager-D6KL3t9V.mjs.map +0 -1
  152. package/dist/transport.types-B5vcyv2k.d.mts.map +0 -1
  153. package/dist/transport.types-BuY84TwO.d.ts.map +0 -1
  154. package/scripts/postinstall.js +0 -61
@@ -1,7 +1,8 @@
1
1
  const require_chunk = require('./chunk-nOFOJqeH.js');
2
2
  const require_internal_log = require('./internal-log-BUJYMZbE.js');
3
3
  const require_safe_stringify = require('./safe-stringify-DWo3aZp_.js');
4
- const require_coerce_utils = require('./coerce.utils-BN980Y9V.js');
4
+ const require_entry_fields = require('./entry-fields-BvOLFlJ4.js');
5
+ const require_coerce_utils = require('./coerce.utils-B-LilukN.js');
5
6
  let node_fs = require("node:fs");
6
7
  node_fs = require_chunk.__toESM(node_fs);
7
8
  let node_path = require("node:path");
@@ -15,6 +16,24 @@ node_util = require_chunk.__toESM(node_util);
15
16
  let node_zlib = require("node:zlib");
16
17
  node_zlib = require_chunk.__toESM(node_zlib);
17
18
 
19
+ //#region src/utils/sanitize.utils.ts
20
+ /**
21
+ * Control-character stripping for text-mode log output.
22
+ *
23
+ * Line breaks become the visible escapes `\\n` / `\\r`; other C0 characters
24
+ * (except tab), DEL and C1 characters are removed, so user-supplied text cannot
25
+ * inject ANSI escapes, overwrite lines, or forge extra log entries.
26
+ */
27
+ const CONTROL_CHARS_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]/g;
28
+ const VISIBLE_ESCAPES = {
29
+ "\n": "\\n",
30
+ "\r": "\\r"
31
+ };
32
+ function stripControlChars(value) {
33
+ return value.replace(CONTROL_CHARS_RE, (ch) => VISIBLE_ESCAPES[ch] ?? "");
34
+ }
35
+
36
+ //#endregion
18
37
  //#region src/transports/console.transport.ts
19
38
  /**
20
39
  * Writes log entries to stdout (info/debug/verbose) and stderr (error/warn).
@@ -45,9 +64,8 @@ var ConsoleTransport = class ConsoleTransport {
45
64
  ["brightwhite", "\x1B[97m"],
46
65
  ["reset", "\x1B[0m"]
47
66
  ]);
48
- static #_2 = this.CONTROL_CHARS_RE = /[\x00-\x08\x0B-\x1F\x7F-\x9F]/g;
49
67
  static sanitize(value) {
50
- return require_coerce_utils.safeToString(value).replace(ConsoleTransport.CONTROL_CHARS_RE, "");
68
+ return stripControlChars(require_coerce_utils.safeToString(value));
51
69
  }
52
70
  constructor(config = {}) {
53
71
  this.config = config;
@@ -60,16 +78,15 @@ var ConsoleTransport = class ConsoleTransport {
60
78
  (lvl === "error" || lvl === "warn" ? process.stderr : process.stdout).write(formatted);
61
79
  }
62
80
  formatEntry(entry) {
63
- if (this.config.format === "json") return require_safe_stringify.stringifyForLog({
81
+ if (this.config.format === "json") return require_safe_stringify.stringifyForLog(require_entry_fields.mergeCoreFields({
64
82
  timestamp: this.config.timestamp !== false ? entry.timestamp.toISOString() : void 0,
65
83
  level: entry.level,
66
84
  message: entry.message,
67
- ...entry.data || {},
68
85
  context: entry.context,
69
86
  traceId: entry.traceId,
70
87
  appName: entry.appName,
71
88
  environment: entry.environment
72
- });
89
+ }, entry.data));
73
90
  const parts = [];
74
91
  if (this.config.timestamp !== false) {
75
92
  const timestamp = entry.timestamp.toISOString();
@@ -117,6 +134,47 @@ var ConsoleTransport = class ConsoleTransport {
117
134
  }
118
135
  };
119
136
 
137
+ //#endregion
138
+ //#region src/transports/buffer-cap.ts
139
+ const DEFAULT_BUFFER_CAP = 1e4;
140
+ const DROP_WARN_INTERVAL_MS$1 = 5e3;
141
+ /**
142
+ * Keeps an in-memory retry buffer bounded. Past `max` the oldest items are
143
+ * dropped, counted, and reported through internalWarn at most every few seconds.
144
+ *
145
+ * `requested` must be an integer of at least 1, otherwise the default is used.
146
+ * A cap below `batchSize` is raised to `batchSize` so one batch always fits.
147
+ */
148
+ var BufferCap = class {
149
+ constructor(name, requested, batchSize, fallback = DEFAULT_BUFFER_CAP) {
150
+ this.name = name;
151
+ this.dropped = 0;
152
+ this.lastWarning = 0;
153
+ let max = fallback;
154
+ if (requested !== void 0) if (Number.isInteger(requested) && requested >= 1) max = requested;
155
+ else require_internal_log.internalWarn(`${name}: maxBufferSize ${String(requested)} is not a positive integer; using ${fallback}`);
156
+ this.max = Math.max(max, batchSize);
157
+ }
158
+ /** Drops the oldest items beyond the cap, in place. */
159
+ enforce(items) {
160
+ const excess = items.length - this.max;
161
+ if (excess <= 0) return;
162
+ items.splice(0, excess);
163
+ this.note(excess);
164
+ }
165
+ note(count) {
166
+ this.dropped += count;
167
+ this.report(DROP_WARN_INTERVAL_MS$1);
168
+ }
169
+ report(minGapMs) {
170
+ const now = Date.now();
171
+ if (this.dropped === 0 || now - this.lastWarning < minGapMs) return;
172
+ require_internal_log.internalWarn(`${this.name}: buffer full (${this.max}), dropped ${this.dropped} oldest entr${this.dropped === 1 ? "y" : "ies"}`);
173
+ this.dropped = 0;
174
+ this.lastWarning = now;
175
+ }
176
+ };
177
+
120
178
  //#endregion
121
179
  //#region src/transports/database.transport.ts
122
180
  /**
@@ -127,6 +185,80 @@ const POSTGRES_MAX_PARAMS = 65535;
127
185
  const POSTGRES_COLUMNS = 8;
128
186
  const POSTGRES_ROWS_PER_INSERT = Math.floor(POSTGRES_MAX_PARAMS / POSTGRES_COLUMNS);
129
187
  const MYSQL_ROWS_PER_INSERT = 5e3;
188
+ /** Postgres rejects NUL in TEXT and JSONB. */
189
+ function stripNul(value) {
190
+ return typeof value === "string" ? value.split("\0").join("") : value;
191
+ }
192
+ /** JSONB also rejects the \u0000 escape, which JSON.stringify writes for a NUL. */
193
+ function stripJsonNulEscape(value) {
194
+ if (typeof value !== "string") return value;
195
+ return value.replace(/(?<!\\)((?:\\\\)*)\\u0000/g, "$1");
196
+ }
197
+ const PG_DATA_CLASSES = [
198
+ "22",
199
+ "23",
200
+ "54"
201
+ ];
202
+ const MYSQL_DATA_CODES = new Set([
203
+ "ER_DATA_TOO_LONG",
204
+ "ER_TRUNCATED_WRONG_VALUE",
205
+ "ER_TRUNCATED_WRONG_VALUE_FOR_FIELD",
206
+ "ER_BAD_NULL_ERROR",
207
+ "ER_WARN_DATA_OUT_OF_RANGE",
208
+ "ER_DUP_ENTRY",
209
+ "ER_INVALID_JSON_TEXT",
210
+ "ER_INVALID_CHARACTER_STRING"
211
+ ]);
212
+ const MYSQL_DATA_ERRNOS = new Set([
213
+ 1048,
214
+ 1062,
215
+ 1264,
216
+ 1292,
217
+ 1366,
218
+ 1406,
219
+ 3140
220
+ ]);
221
+ const SQLITE_DATA_CODES = new Set([
222
+ "SQLITE_CONSTRAINT",
223
+ "SQLITE_TOOBIG",
224
+ "SQLITE_MISMATCH"
225
+ ]);
226
+ const MONGO_DATA_CODES = new Set([
227
+ 2,
228
+ 121,
229
+ 10334,
230
+ 11e3
231
+ ]);
232
+ function isDataErrorLayer(type, e) {
233
+ const code = e.code;
234
+ switch (type) {
235
+ case "postgresql": return typeof code === "string" && PG_DATA_CLASSES.includes(code.slice(0, 2));
236
+ case "mysql": return typeof code === "string" && MYSQL_DATA_CODES.has(code) || typeof e.errno === "number" && MYSQL_DATA_ERRNOS.has(e.errno);
237
+ case "sqlite": return typeof code === "string" && (SQLITE_DATA_CODES.has(code) || code.startsWith("SQLITE_CONSTRAINT_"));
238
+ case "mongodb": return e.name === "BSONObjectTooLarge" || typeof code === "number" && MONGO_DATA_CODES.has(code);
239
+ default: return false;
240
+ }
241
+ }
242
+ /**
243
+ * True when the database refused the data itself (bad value, constraint, size),
244
+ * which retrying cannot fix. Connection, timeout, auth and unknown errors are
245
+ * not data errors and must be retried, never dropped.
246
+ */
247
+ function isDataError(type, error) {
248
+ let current = error;
249
+ for (let depth = 0; depth < 3 && current && typeof current === "object"; depth += 1) {
250
+ if (isDataErrorLayer(type, current)) return true;
251
+ current = current.cause;
252
+ }
253
+ return false;
254
+ }
255
+ /** A write that stored part of a batch: only `remaining` still needs to be written. */
256
+ var PartialWriteError = class extends Error {
257
+ constructor(message, remaining, cause) {
258
+ super(message, { cause });
259
+ this.remaining = remaining;
260
+ }
261
+ };
130
262
  function chunk(items, size) {
131
263
  const chunks = [];
132
264
  for (let i = 0; i < items.length; i += size) chunks.push(items.slice(i, i + size));
@@ -155,6 +287,7 @@ var DatabaseTransport = class {
155
287
  this.isConnected = false;
156
288
  this.batchSize = config.batchSize || 100;
157
289
  this.flushInterval = config.flushInterval || 5e3;
290
+ this.cap = new BufferCap("DatabaseTransport", config.maxBufferSize, this.batchSize);
158
291
  if (config.filter) this.filter = config.filter;
159
292
  if (config.table) validateSqlIdentifier(config.table, "table");
160
293
  this.setupFlushTimer();
@@ -166,6 +299,7 @@ var DatabaseTransport = class {
166
299
  }
167
300
  addToBatch(entry) {
168
301
  this.batch.push(entry);
302
+ this.cap.enforce(this.batch);
169
303
  }
170
304
  async flush() {
171
305
  if (!this.flushPromise) this.flushPromise = this.drain().finally(() => {
@@ -174,37 +308,97 @@ var DatabaseTransport = class {
174
308
  await this.flushPromise;
175
309
  }
176
310
  /**
177
- * Drains the batch to the database one snapshot at a time. The current batch
178
- * is detached SYNCHRONOUSLY before awaiting the write, so entries appended by
179
- * concurrent write() calls land in a fresh array and are never written twice.
180
- * On write failure the snapshot is restored to the front of the batch for the
181
- * next flush cycle and the loop stops, so a persistently failing DB does not
182
- * hot-spin retrying the same entries.
311
+ * Drains the buffer to the database one batch at a time. A batch is detached
312
+ * SYNCHRONOUSLY before awaiting the write, so entries appended by concurrent
313
+ * write() calls land in a fresh array and are never written twice.
314
+ *
315
+ * A failure that is not a data error (connection, timeout, auth, unknown) puts
316
+ * the batch back at the front of the buffer, bounded by `maxBufferSize`, and
317
+ * stops the loop so a down database is not hammered. A data error means the
318
+ * database refused some entry itself, so that batch alone is split to find and
319
+ * drop the refused entries; see isolate().
183
320
  */
184
321
  async drain() {
185
322
  while (this.batch.length > 0) {
186
- const entriesToFlush = this.batch;
187
- this.batch = [];
323
+ const entries = this.batch.splice(0, this.batchSize);
188
324
  try {
189
- switch (this.config.type) {
190
- case "mongodb":
191
- await this.flushToMongoDB(entriesToFlush);
192
- break;
193
- case "postgresql":
194
- await this.flushToPostgreSQL(entriesToFlush);
195
- break;
196
- case "mysql":
197
- await this.flushToMySQL(entriesToFlush);
198
- break;
199
- case "sqlite":
200
- await this.flushToSQLite(entriesToFlush);
201
- break;
202
- default: throw new Error(`Unsupported database type: ${this.config.type}`);
203
- }
325
+ await this.writeEntries(entries);
204
326
  } catch (error) {
205
327
  require_internal_log.internalError("Database flush error", error);
206
- this.batch.unshift(...entriesToFlush);
207
- throw error;
328
+ if (error instanceof PartialWriteError) {
329
+ this.requeue(error.remaining);
330
+ throw error.cause;
331
+ }
332
+ if (!isDataError(this.config.type, error)) {
333
+ this.requeue(entries);
334
+ throw error;
335
+ }
336
+ const state = {
337
+ budget: 2 * this.batchSize,
338
+ rejected: 0,
339
+ requeue: [],
340
+ stopped: false
341
+ };
342
+ await this.isolate(entries, state);
343
+ if (state.rejected > 0) require_internal_log.internalWarn(`DatabaseTransport: dropped ${state.rejected} log entr${state.rejected === 1 ? "y" : "ies"} the database rejected`);
344
+ this.requeue(state.requeue);
345
+ if (state.stopped) throw state.error;
346
+ }
347
+ }
348
+ }
349
+ requeue(entries) {
350
+ if (entries.length === 0) return;
351
+ this.batch = entries.concat(this.batch);
352
+ this.cap.enforce(this.batch);
353
+ }
354
+ async writeEntries(entries) {
355
+ switch (this.config.type) {
356
+ case "mongodb":
357
+ await this.flushToMongoDB(entries);
358
+ break;
359
+ case "postgresql":
360
+ await this.flushToPostgreSQL(entries);
361
+ break;
362
+ case "mysql":
363
+ await this.flushToMySQL(entries);
364
+ break;
365
+ case "sqlite":
366
+ await this.flushToSQLite(entries);
367
+ break;
368
+ default: throw new Error(`Unsupported database type: ${this.config.type}`);
369
+ }
370
+ }
371
+ /**
372
+ * `entries` failed with a data error. Splits them in half until the refused
373
+ * entries are alone and drops those. A write that fails with anything but a
374
+ * data error, or running out of the per-flush write budget, stops the search:
375
+ * the entries not yet written go back to the buffer.
376
+ */
377
+ async isolate(entries, state) {
378
+ if (entries.length === 1) {
379
+ state.rejected += 1;
380
+ return;
381
+ }
382
+ const mid = Math.ceil(entries.length / 2);
383
+ for (const half of [entries.slice(0, mid), entries.slice(mid)]) {
384
+ if (state.stopped || state.budget <= 0) {
385
+ state.requeue.push(...half);
386
+ continue;
387
+ }
388
+ state.budget -= 1;
389
+ try {
390
+ await this.writeEntries(half);
391
+ } catch (error) {
392
+ if (error instanceof PartialWriteError) {
393
+ state.requeue.push(...error.remaining);
394
+ state.stopped = true;
395
+ state.error = error.cause;
396
+ } else if (isDataError(this.config.type, error)) await this.isolate(half, state);
397
+ else {
398
+ state.requeue.push(...half);
399
+ state.stopped = true;
400
+ state.error = error;
401
+ }
208
402
  }
209
403
  }
210
404
  }
@@ -329,7 +523,26 @@ var DatabaseTransport = class {
329
523
  appName: entry.appName,
330
524
  environment: entry.environment
331
525
  }));
332
- await collection.insertMany(documents);
526
+ try {
527
+ await collection.insertMany(documents, { ordered: false });
528
+ } catch (error) {
529
+ const raw = error.writeErrors;
530
+ let list = [];
531
+ if (Array.isArray(raw)) list = raw;
532
+ else if (raw) list = [raw];
533
+ const writeErrors = list;
534
+ if (writeErrors.length === 0) throw error;
535
+ const remaining = [];
536
+ let rejected = 0;
537
+ for (const writeError of writeErrors) {
538
+ const entry = typeof writeError.index === "number" ? entries[writeError.index] : void 0;
539
+ if (!entry) throw error;
540
+ if (isDataError("mongodb", writeError)) rejected += 1;
541
+ else remaining.push(entry);
542
+ }
543
+ if (rejected > 0) require_internal_log.internalWarn(`DatabaseTransport: dropped ${rejected} log entr${rejected === 1 ? "y" : "ies"} the database rejected`);
544
+ if (remaining.length > 0) throw new PartialWriteError("MongoDB insert partially failed", remaining, error);
545
+ }
333
546
  }
334
547
  async flushToPostgreSQL(entries) {
335
548
  const tableName = this.config.table || "logs";
@@ -342,7 +555,7 @@ var DatabaseTransport = class {
342
555
  entry.traceId,
343
556
  entry.appName,
344
557
  entry.environment
345
- ]), POSTGRES_ROWS_PER_INSERT);
558
+ ].map((value, column) => stripNul(column === 3 ? stripJsonNulEscape(value) : value))), POSTGRES_ROWS_PER_INSERT);
346
559
  const insertChunk = async (rows) => {
347
560
  const query = `
348
561
  INSERT INTO ${tableName}
@@ -502,6 +715,7 @@ var DatabaseTransport = class {
502
715
  require_internal_log.internalError("Database flush during close failed; entries remain buffered", error);
503
716
  }
504
717
  if (this.batch.length > 0) require_internal_log.internalError(`Database transport closing with ${this.batch.length} unflushed log entr${this.batch.length === 1 ? "y" : "ies"} after ${MAX_CLOSE_FLUSH_ATTEMPTS} attempts`);
718
+ this.cap.report(0);
505
719
  if (this.connection) switch (this.config.type) {
506
720
  case "mongodb":
507
721
  await this.connection.close();
@@ -573,6 +787,7 @@ var AnalyticsTransport = class {
573
787
  this.level = config.level;
574
788
  this.batchSize = this.config.batchSize || 50;
575
789
  this.flushInterval = this.config.flushInterval || 1e4;
790
+ this.cap = new BufferCap(name, config.maxBufferSize, this.batchSize);
576
791
  }
577
792
  async write(entry) {
578
793
  if (!this.isReady) await this.ensureReady();
@@ -582,6 +797,7 @@ var AnalyticsTransport = class {
582
797
  }
583
798
  addToBatch(entry) {
584
799
  this.batch.push(entry);
800
+ this.cap.enforce(this.batch);
585
801
  if (this.batch.length >= (this.config.batchSize || 50)) this.flush().catch((err) => require_internal_log.internalError(`${this.name} batch flush failed`, err));
586
802
  else if (!this.batchTimer && this.config.flushInterval) {
587
803
  var _this$batchTimer$unre, _this$batchTimer;
@@ -617,6 +833,7 @@ var AnalyticsTransport = class {
617
833
  } catch (error) {
618
834
  require_internal_log.internalError(`Analytics transport ${this.name} flush failed`, error);
619
835
  this.batch.unshift(...entriesToSend);
836
+ this.cap.enforce(this.batch);
620
837
  return;
621
838
  }
622
839
  }
@@ -629,25 +846,36 @@ var AnalyticsTransport = class {
629
846
  const MAX_CLOSE_FLUSH_ATTEMPTS = 3;
630
847
  for (let attempt = 0; attempt < MAX_CLOSE_FLUSH_ATTEMPTS && this.batch.length > 0; attempt += 1) await this.flush();
631
848
  if (this.batch.length > 0) require_internal_log.internalError(`Analytics transport ${this.name} closing with ${this.batch.length} unflushed entr${this.batch.length === 1 ? "y" : "ies"} after ${MAX_CLOSE_FLUSH_ATTEMPTS} attempts`);
849
+ this.cap.report(0);
632
850
  await this.cleanup();
633
851
  }
634
852
  shouldSkipEntry(entry) {
635
853
  return ["debug", "trace"].includes(entry.level.toLowerCase());
636
854
  }
637
855
  transformEntry(entry) {
638
- const transformed = {
856
+ const core = {
639
857
  timestamp: entry.timestamp.toISOString(),
640
858
  level: entry.level,
641
859
  message: entry.message,
642
- ...entry.data
860
+ context: entry.context,
861
+ traceId: entry.traceId,
862
+ appName: entry.appName,
863
+ environment: entry.environment
643
864
  };
644
- if (entry.context) transformed.context = entry.context;
645
- if (entry.traceId) transformed.traceId = entry.traceId;
646
- if (entry.appName) transformed.appName = entry.appName;
647
- if (entry.environment) transformed.environment = entry.environment;
865
+ const transformed = require_entry_fields.mergeCoreFields(core, entry.data, this.reservedKeys());
866
+ for (const key of [
867
+ "context",
868
+ "traceId",
869
+ "appName",
870
+ "environment"
871
+ ]) if (!core[key]) delete transformed[key];
648
872
  if (this.config.customProperties) Object.assign(transformed, this.config.customProperties);
649
873
  return transformed;
650
874
  }
875
+ /** Provider-specific field names a payload key must not replace. */
876
+ reservedKeys() {
877
+ return [];
878
+ }
651
879
  /**
652
880
  * Runs initialize() once. A bad config (say, a missing API key) fails every
653
881
  * write with the same error instead of an unhandled rejection at startup.
@@ -732,8 +960,12 @@ var DataDogTransport = class extends AnalyticsTransport {
732
960
  await this.sendLogBatch(entries);
733
961
  }
734
962
  transformToDataDogLog(entry) {
735
- const transformed = this.transformEntry(entry);
736
963
  return {
964
+ ...this.transformEntry(entry),
965
+ "dd.trace_id": entry.traceId,
966
+ "dd.span_id": this.generateSpanId(),
967
+ host: this.getHostname(),
968
+ source: "nodejs",
737
969
  timestamp: entry.timestamp.toISOString(),
738
970
  level: this.mapLogLevel(entry.level),
739
971
  message: entry.message,
@@ -743,14 +975,25 @@ var DataDogTransport = class extends AnalyticsTransport {
743
975
  logger: {
744
976
  name: "logixia",
745
977
  thread_name: "main"
746
- },
747
- ...transformed,
748
- "dd.trace_id": entry.traceId,
749
- "dd.span_id": this.generateSpanId(),
750
- host: this.getHostname(),
751
- source: "nodejs"
978
+ }
752
979
  };
753
980
  }
981
+ reservedKeys() {
982
+ return [
983
+ "status",
984
+ "ddtags",
985
+ "ddsource",
986
+ "hostname",
987
+ "service",
988
+ "version",
989
+ "env",
990
+ "logger",
991
+ "host",
992
+ "source",
993
+ "dd.trace_id",
994
+ "dd.span_id"
995
+ ];
996
+ }
754
997
  transformToDataDogMetric(entry) {
755
998
  return {
756
999
  metric: `logitron.logs.${entry.level}`,
@@ -890,6 +1133,12 @@ const unlink = (0, node_util.promisify)(node_fs.unlink);
890
1133
  const readdir = (0, node_util.promisify)(node_fs.readdir);
891
1134
  const stat = (0, node_util.promisify)(node_fs.stat);
892
1135
  const DROP_WARN_INTERVAL_MS = 5e3;
1136
+ const DEFAULT_MAX_QUEUE = 1e4;
1137
+ const DEFAULT_FILE_MODE = 384;
1138
+ const DEFAULT_DIR_MODE = 448;
1139
+ function csvField(value) {
1140
+ return `"${stripControlChars(require_coerce_utils.safeToString(value)).replace(/"/g, "\"\"")}"`;
1141
+ }
893
1142
  const SIZE_UNITS = {
894
1143
  "": 1,
895
1144
  k: 1024,
@@ -925,6 +1174,10 @@ function formatDatePattern(date, pattern) {
925
1174
  * rotated files are renamed beside it (`app-2026-10-22T09-30-00-000.log`).
926
1175
  * With a `rotation` block every file, the live one included, is timestamped.
927
1176
  *
1177
+ * Files are created with mode 0o600 and directories with 0o700; override with
1178
+ * `fileMode` and `dirMode`. At most `maxQueue` (default 10000) entries wait in
1179
+ * memory; the rest are dropped per `queuePolicy` and counted in a warning.
1180
+ *
928
1181
  * @example
929
1182
  * transports: { file: { filename: 'app.log', dirname: './logs', maxSize: '50MB' } }
930
1183
  */
@@ -959,8 +1212,10 @@ var FileTransport = class {
959
1212
  this.maxBytes = parseSize(rawMaxSize);
960
1213
  if (rawMaxSize !== void 0 && this.maxBytes === void 0) require_internal_log.internalWarn(`FileTransport: maxSize ${JSON.stringify(rawMaxSize)} is not a valid size (try '50MB'); size rotation is off`);
961
1214
  const maxQueue = config.maxQueue;
962
- if (maxQueue !== void 0 && !(Number.isInteger(maxQueue) && maxQueue > 0)) require_internal_log.internalWarn(`FileTransport: maxQueue ${String(maxQueue)} is not a positive integer; ignored`);
963
- else this.maxQueue = maxQueue;
1215
+ if (maxQueue !== void 0 && !(Number.isInteger(maxQueue) && maxQueue > 0)) require_internal_log.internalWarn(`FileTransport: maxQueue ${String(maxQueue)} is not a positive integer; using ${DEFAULT_MAX_QUEUE}`);
1216
+ this.maxQueue = maxQueue !== void 0 && Number.isInteger(maxQueue) && maxQueue > 0 ? maxQueue : DEFAULT_MAX_QUEUE;
1217
+ this.fileMode = config.fileMode ?? DEFAULT_FILE_MODE;
1218
+ this.dirMode = config.dirMode ?? DEFAULT_DIR_MODE;
964
1219
  this.queuePolicy = config.queuePolicy ?? "drop-oldest";
965
1220
  this.maxFiles = (rotation === null || rotation === void 0 ? void 0 : rotation.maxFiles) ?? config.maxFiles;
966
1221
  this.compress = (rotation === null || rotation === void 0 ? void 0 : rotation.compress) ?? config.zippedArchive ?? false;
@@ -970,7 +1225,10 @@ var FileTransport = class {
970
1225
  this.ext = node_path.extname(config.filename);
971
1226
  this.base = node_path.basename(config.filename, this.ext);
972
1227
  try {
973
- node_fs.mkdirSync(this.dir, { recursive: true });
1228
+ node_fs.mkdirSync(this.dir, {
1229
+ recursive: true,
1230
+ mode: this.dirMode
1231
+ });
974
1232
  } catch (error) {
975
1233
  require_internal_log.internalError(`FileTransport could not create ${this.dir}`, error);
976
1234
  }
@@ -1038,7 +1296,7 @@ var FileTransport = class {
1038
1296
  this.enqueued += 1;
1039
1297
  }
1040
1298
  queueFull() {
1041
- return this.maxQueue !== void 0 && this.batch.length + this.inFlight >= this.maxQueue;
1299
+ return this.batch.length + this.inFlight >= this.maxQueue;
1042
1300
  }
1043
1301
  roomAvailable() {
1044
1302
  const room = new Promise((resolve) => this.spaceWaiters.push(resolve));
@@ -1118,30 +1376,26 @@ var FileTransport = class {
1118
1376
  }
1119
1377
  formatEntry(entry) {
1120
1378
  switch (this.config.format) {
1121
- case "json": return require_safe_stringify.stringifyForLog({
1379
+ case "json": return require_safe_stringify.stringifyForLog(require_entry_fields.mergeCoreFields({
1122
1380
  timestamp: entry.timestamp.toISOString(),
1123
1381
  level: entry.level,
1124
- message: entry.message,
1125
- ...entry.data || {}
1126
- });
1127
- case "csv": {
1128
- const safeMessage = require_coerce_utils.safeToString(entry.message);
1129
- return [
1130
- entry.timestamp.toISOString(),
1131
- entry.level,
1132
- `"${safeMessage.replace(/"/g, "\"\"")}"`,
1133
- require_coerce_utils.safeToString(entry.context),
1134
- require_coerce_utils.safeToString(entry.traceId),
1135
- require_safe_stringify.stringifyForLog(entry.data || {})
1136
- ].join(",");
1137
- }
1382
+ message: entry.message
1383
+ }, entry.data));
1384
+ case "csv": return [
1385
+ entry.timestamp.toISOString(),
1386
+ csvField(entry.level),
1387
+ csvField(entry.message),
1388
+ csvField(entry.context),
1389
+ csvField(entry.traceId),
1390
+ csvField(require_safe_stringify.stringifyForLog(entry.data || {}))
1391
+ ].join(",");
1138
1392
  case "text":
1139
- default: return `${entry.timestamp.toISOString()} [${entry.level.toUpperCase()}] ${require_coerce_utils.safeToString(entry.message)}${entry.data ? " " + require_safe_stringify.stringifyForLog(entry.data) : ""}`;
1393
+ default: return `${entry.timestamp.toISOString()} [${stripControlChars(require_coerce_utils.safeToString(entry.level)).toUpperCase()}] ${stripControlChars(require_coerce_utils.safeToString(entry.message))}${entry.data ? " " + require_safe_stringify.stringifyForLog(entry.data) : ""}`;
1140
1394
  }
1141
1395
  }
1142
1396
  addToBatch(entry) {
1143
1397
  this.enqueue(entry);
1144
- const threshold = Math.min(this.config.batchSize || 100, this.maxQueue ?? Infinity);
1398
+ const threshold = Math.min(this.config.batchSize || 100, this.maxQueue);
1145
1399
  if (this.batch.length >= threshold && !this.draining) {
1146
1400
  if (this.batchTimer) {
1147
1401
  clearTimeout(this.batchTimer);
@@ -1179,7 +1433,7 @@ var FileTransport = class {
1179
1433
  if (chunk$1) await this.append(chunk$1, chunkBytes);
1180
1434
  }
1181
1435
  async append(content, bytes = Buffer.byteLength(content)) {
1182
- await appendFile(this.currentFilePath, content);
1436
+ await appendFile(this.currentFilePath, content, { mode: this.fileMode });
1183
1437
  this.bytesWritten += bytes;
1184
1438
  }
1185
1439
  timeToRotate() {
@@ -1273,7 +1527,7 @@ var FileTransport = class {
1273
1527
  async compressFile(filePath) {
1274
1528
  const gzPath = `${filePath}.gz`;
1275
1529
  try {
1276
- await (0, node_stream_promises.pipeline)(node_fs.createReadStream(filePath), (0, node_zlib.createGzip)(), node_fs.createWriteStream(gzPath));
1530
+ await (0, node_stream_promises.pipeline)(node_fs.createReadStream(filePath), (0, node_zlib.createGzip)(), node_fs.createWriteStream(gzPath, { mode: this.fileMode }));
1277
1531
  await unlink(filePath);
1278
1532
  } catch (error) {
1279
1533
  require_internal_log.internalError("Failed to compress rotated log file", error);
@@ -1357,12 +1611,27 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
1357
1611
  await this.sendEvents(events);
1358
1612
  }
1359
1613
  async cleanup() {}
1614
+ reservedKeys() {
1615
+ return [
1616
+ "event_category",
1617
+ "event_label",
1618
+ "log_level",
1619
+ "log_message",
1620
+ "trace_id",
1621
+ "app_name",
1622
+ "custom_dimension_1",
1623
+ "custom_dimension_2",
1624
+ "custom_dimension_3"
1625
+ ];
1626
+ }
1360
1627
  transformToGAEvent(entry) {
1361
1628
  const transformed = this.transformEntry(entry);
1629
+ const eventCategory = this.mapLogLevelToCategory(entry.level);
1362
1630
  return {
1363
1631
  name: "log_event",
1364
1632
  params: {
1365
- event_category: this.mapLogLevelToCategory(entry.level),
1633
+ ...this.flattenData(transformed),
1634
+ event_category: eventCategory,
1366
1635
  event_label: entry.message,
1367
1636
  log_level: entry.level,
1368
1637
  log_message: entry.message,
@@ -1371,7 +1640,6 @@ var GoogleAnalyticsTransport = class extends AnalyticsTransport {
1371
1640
  ...entry.traceId && { trace_id: entry.traceId },
1372
1641
  ...entry.appName && { app_name: entry.appName },
1373
1642
  ...entry.environment && { environment: entry.environment },
1374
- ...this.flattenData(transformed),
1375
1643
  custom_dimension_1: entry.level,
1376
1644
  custom_dimension_2: entry.context || "default",
1377
1645
  custom_dimension_3: entry.environment || "production"
@@ -1567,12 +1835,21 @@ var MixpanelTransport = class extends AnalyticsTransport {
1567
1835
  await this.trackEvents(events);
1568
1836
  }
1569
1837
  async cleanup() {}
1838
+ reservedKeys() {
1839
+ return [
1840
+ "token",
1841
+ "distinct_id",
1842
+ "time",
1843
+ "$insert_id"
1844
+ ];
1845
+ }
1570
1846
  transformToMixpanelEvent(entry) {
1571
1847
  const transformed = this.transformEntry(entry);
1572
1848
  return {
1573
1849
  name: `log_${entry.level}`,
1574
1850
  properties: {
1575
1851
  ...transformed,
1852
+ token: this.mixpanelConfig.token,
1576
1853
  distinct_id: this.mixpanelConfig.distinct_id || "anonymous",
1577
1854
  time: entry.timestamp.getTime(),
1578
1855
  $insert_id: this.generateInsertId(entry),
@@ -1585,8 +1862,8 @@ var MixpanelTransport = class extends AnalyticsTransport {
1585
1862
  const payload = {
1586
1863
  event: event.name,
1587
1864
  properties: {
1588
- token: this.mixpanelConfig.token,
1589
- ...event.properties
1865
+ ...event.properties,
1866
+ token: this.mixpanelConfig.token
1590
1867
  }
1591
1868
  };
1592
1869
  await this.makeRequest("/track", [payload]);
@@ -1595,8 +1872,8 @@ var MixpanelTransport = class extends AnalyticsTransport {
1595
1872
  const payload = events.map((event) => ({
1596
1873
  event: event.name,
1597
1874
  properties: {
1598
- token: this.mixpanelConfig.token,
1599
- ...event.properties
1875
+ ...event.properties,
1876
+ token: this.mixpanelConfig.token
1600
1877
  }
1601
1878
  }));
1602
1879
  await this.makeRequest("/track", payload);
@@ -1654,11 +1931,11 @@ var MixpanelTransport = class extends AnalyticsTransport {
1654
1931
  const payload = {
1655
1932
  event: eventName,
1656
1933
  properties: {
1934
+ ...properties,
1935
+ ...this.mixpanelConfig.enableSuperProperties ? this.mixpanelConfig.superProperties : {},
1657
1936
  token: this.mixpanelConfig.token,
1658
1937
  distinct_id: this.mixpanelConfig.distinct_id || "anonymous",
1659
- time: Date.now(),
1660
- ...properties,
1661
- ...this.mixpanelConfig.enableSuperProperties ? this.mixpanelConfig.superProperties : {}
1938
+ time: Date.now()
1662
1939
  }
1663
1940
  };
1664
1941
  await this.makeRequest("/track", [payload]);
@@ -1718,6 +1995,9 @@ var SegmentTransport = class extends AnalyticsTransport {
1718
1995
  await this.batchTrack(segmentEvents);
1719
1996
  }
1720
1997
  async cleanup() {}
1998
+ reservedKeys() {
1999
+ return ["logger"];
2000
+ }
1721
2001
  transformToSegmentEvent(entry) {
1722
2002
  const transformed = this.transformEntry(entry);
1723
2003
  return {
@@ -1727,10 +2007,10 @@ var SegmentTransport = class extends AnalyticsTransport {
1727
2007
  anonymousId: this.generateAnonymousId(),
1728
2008
  timestamp: entry.timestamp.toISOString(),
1729
2009
  properties: {
2010
+ ...transformed,
1730
2011
  level: entry.level,
1731
2012
  message: entry.message,
1732
2013
  logger: "logixia",
1733
- ...transformed,
1734
2014
  ...entry.context && { context: entry.context },
1735
2015
  ...entry.traceId && { traceId: entry.traceId },
1736
2016
  ...entry.appName && { appName: entry.appName },
@@ -1786,11 +2066,10 @@ var SegmentTransport = class extends AnalyticsTransport {
1786
2066
  }
1787
2067
  }
1788
2068
  extractUserId(entry) {
1789
- if (entry.data) {
1790
- const d = entry.data;
1791
- const id = d["userId"] ?? d["user_id"] ?? d["id"];
1792
- return typeof id === "string" ? id : void 0;
1793
- }
2069
+ var _entry$data;
2070
+ const field = this.segmentConfig.userIdField ?? "userId";
2071
+ const id = (_entry$data = entry.data) === null || _entry$data === void 0 ? void 0 : _entry$data[field];
2072
+ return typeof id === "string" ? id : void 0;
1794
2073
  }
1795
2074
  generateAnonymousId() {
1796
2075
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
@@ -2345,4 +2624,10 @@ Object.defineProperty(exports, 'TransportManager', {
2345
2624
  return TransportManager;
2346
2625
  }
2347
2626
  });
2348
- //# sourceMappingURL=transport.manager-BivyUTtU.js.map
2627
+ Object.defineProperty(exports, 'stripControlChars', {
2628
+ enumerable: true,
2629
+ get: function () {
2630
+ return stripControlChars;
2631
+ }
2632
+ });
2633
+ //# sourceMappingURL=transport.manager-Crau3Rle.js.map