plslog 1.1.1 → 1.2.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/dist/index.mjs CHANGED
@@ -20,7 +20,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
20
20
  // file that has been converted to a CommonJS file using a Babel-
21
21
  // compatible transform (i.e. "__esModule" has not been set), then set
22
22
  // "default" to the CommonJS "module.exports" for node compatibility.
23
- __defProp(target, "default", { value: mod, enumerable: true }) ,
23
+ !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
24
  mod
25
25
  ));
26
26
 
@@ -1042,7 +1042,7 @@ var require_build = __commonJS({
1042
1042
  value: true
1043
1043
  });
1044
1044
  exports2["default"] = exports2.DEFAULT_OPTIONS = void 0;
1045
- exports2.format = format2;
1045
+ exports2.format = format;
1046
1046
  exports2.plugins = void 0;
1047
1047
  var _ansiStyles = _interopRequireDefault(require_ansi_styles());
1048
1048
  var _collections = __webpack_require__("./src/collections.ts");
@@ -1205,8 +1205,8 @@ ${indentationNext}`);
1205
1205
  }
1206
1206
  return printed;
1207
1207
  }
1208
- function findPlugin(plugins3, val) {
1209
- for (const plugin of plugins3) {
1208
+ function findPlugin(plugins2, val) {
1209
+ for (const plugin of plugins2) {
1210
1210
  try {
1211
1211
  if (plugin.test(val)) {
1212
1212
  return plugin;
@@ -1237,7 +1237,7 @@ ${indentationNext}`);
1237
1237
  };
1238
1238
  const DEFAULT_THEME_KEYS = Object.keys(DEFAULT_THEME);
1239
1239
  const toOptionsSubtype = (options) => options;
1240
- const DEFAULT_OPTIONS2 = exports2.DEFAULT_OPTIONS = toOptionsSubtype({
1240
+ const DEFAULT_OPTIONS = exports2.DEFAULT_OPTIONS = toOptionsSubtype({
1241
1241
  callToJSON: true,
1242
1242
  compareKeys: void 0,
1243
1243
  escapeRegex: false,
@@ -1254,7 +1254,7 @@ ${indentationNext}`);
1254
1254
  });
1255
1255
  function validateOptions(options) {
1256
1256
  for (const key of Object.keys(options)) {
1257
- if (!Object.prototype.hasOwnProperty.call(DEFAULT_OPTIONS2, key)) {
1257
+ if (!Object.prototype.hasOwnProperty.call(DEFAULT_OPTIONS, key)) {
1258
1258
  throw new Error(`pretty-format: Unknown option "${key}".`);
1259
1259
  }
1260
1260
  }
@@ -1287,20 +1287,20 @@ ${indentationNext}`);
1287
1287
  };
1288
1288
  return colors;
1289
1289
  }, /* @__PURE__ */ Object.create(null));
1290
- const getPrintFunctionName = (options) => options?.printFunctionName ?? DEFAULT_OPTIONS2.printFunctionName;
1291
- const getEscapeRegex = (options) => options?.escapeRegex ?? DEFAULT_OPTIONS2.escapeRegex;
1292
- const getEscapeString = (options) => options?.escapeString ?? DEFAULT_OPTIONS2.escapeString;
1290
+ const getPrintFunctionName = (options) => options?.printFunctionName ?? DEFAULT_OPTIONS.printFunctionName;
1291
+ const getEscapeRegex = (options) => options?.escapeRegex ?? DEFAULT_OPTIONS.escapeRegex;
1292
+ const getEscapeString = (options) => options?.escapeString ?? DEFAULT_OPTIONS.escapeString;
1293
1293
  const getConfig = (options) => ({
1294
- callToJSON: options?.callToJSON ?? DEFAULT_OPTIONS2.callToJSON,
1294
+ callToJSON: options?.callToJSON ?? DEFAULT_OPTIONS.callToJSON,
1295
1295
  colors: options?.highlight ? getColorsHighlight(options) : getColorsEmpty(),
1296
- compareKeys: typeof options?.compareKeys === "function" || options?.compareKeys === null ? options.compareKeys : DEFAULT_OPTIONS2.compareKeys,
1296
+ compareKeys: typeof options?.compareKeys === "function" || options?.compareKeys === null ? options.compareKeys : DEFAULT_OPTIONS.compareKeys,
1297
1297
  escapeRegex: getEscapeRegex(options),
1298
1298
  escapeString: getEscapeString(options),
1299
- indent: options?.min ? "" : createIndent(options?.indent ?? DEFAULT_OPTIONS2.indent),
1300
- maxDepth: options?.maxDepth ?? DEFAULT_OPTIONS2.maxDepth,
1301
- maxWidth: options?.maxWidth ?? DEFAULT_OPTIONS2.maxWidth,
1302
- min: options?.min ?? DEFAULT_OPTIONS2.min,
1303
- plugins: options?.plugins ?? DEFAULT_OPTIONS2.plugins,
1299
+ indent: options?.min ? "" : createIndent(options?.indent ?? DEFAULT_OPTIONS.indent),
1300
+ maxDepth: options?.maxDepth ?? DEFAULT_OPTIONS.maxDepth,
1301
+ maxWidth: options?.maxWidth ?? DEFAULT_OPTIONS.maxWidth,
1302
+ min: options?.min ?? DEFAULT_OPTIONS.min,
1303
+ plugins: options?.plugins ?? DEFAULT_OPTIONS.plugins,
1304
1304
  printBasicPrototype: options?.printBasicPrototype ?? true,
1305
1305
  printFunctionName: getPrintFunctionName(options),
1306
1306
  spacingInner: options?.min ? " " : "\n",
@@ -1311,7 +1311,7 @@ ${indentationNext}`);
1311
1311
  length: indent + 1
1312
1312
  }).join(" ");
1313
1313
  }
1314
- function format2(val, options) {
1314
+ function format(val, options) {
1315
1315
  if (options) {
1316
1316
  validateOptions(options);
1317
1317
  if (options.plugins) {
@@ -1335,7 +1335,7 @@ ${indentationNext}`);
1335
1335
  ReactElement: _ReactElement.default,
1336
1336
  ReactTestComponent: _ReactTestComponent.default
1337
1337
  };
1338
- exports2["default"] = format2;
1338
+ exports2["default"] = format;
1339
1339
  })();
1340
1340
  module.exports = __webpack_exports__;
1341
1341
  })();
@@ -1349,14 +1349,9 @@ function isBase64(link) {
1349
1349
  return link.startsWith("data:image/") && link.includes(";base64");
1350
1350
  }
1351
1351
 
1352
- // ../../node_modules/.pnpm/pretty-format@30.2.0/node_modules/pretty-format/build/index.mjs
1353
- var import_index = __toESM(require_build());
1354
- import_index.default.DEFAULT_OPTIONS;
1355
- var format = import_index.default.format;
1356
- import_index.default.plugins;
1357
- import_index.default.default;
1358
-
1359
1352
  // src/formatter.ts
1353
+ var import_pretty_format = __toESM(require_build());
1354
+ var prettyFormat = typeof import_pretty_format.default === "function" ? import_pretty_format.default : import_pretty_format.default.format;
1360
1355
  var EXCLUDED_ERROR_PROPS = /* @__PURE__ */ new Set(["name", "message", "stack", "cause"]);
1361
1356
  var Formatter = class {
1362
1357
  /**
@@ -1567,8 +1562,15 @@ var Formatter = class {
1567
1562
  if (obj instanceof Error) {
1568
1563
  return this.serializeError(obj, filterOptions?.errorConfig, 0);
1569
1564
  }
1570
- if (typeof obj === "string" && isBase64(obj)) {
1571
- return this.formatBase64String(obj);
1565
+ if (typeof obj === "string") {
1566
+ if (isBase64(obj)) {
1567
+ return this.formatBase64String(obj);
1568
+ }
1569
+ const stringLimit = filterOptions?.truncate?.string;
1570
+ if (stringLimit !== void 0 && obj.length > stringLimit) {
1571
+ return `${obj.slice(0, stringLimit)}... [${obj.length} chars]`;
1572
+ }
1573
+ return obj;
1572
1574
  }
1573
1575
  if (obj instanceof File) {
1574
1576
  return {
@@ -1585,7 +1587,10 @@ var Formatter = class {
1585
1587
  };
1586
1588
  }
1587
1589
  if (Array.isArray(obj)) {
1588
- return obj.map(
1590
+ const arrayLimit = filterOptions?.truncate?.array;
1591
+ const sourceItems = arrayLimit !== void 0 && obj.length > arrayLimit ? obj.slice(0, arrayLimit) : obj;
1592
+ const remainder = obj.length - sourceItems.length;
1593
+ const result = sourceItems.map(
1589
1594
  (item, index) => this.serializeSpecialObjects(
1590
1595
  item,
1591
1596
  maxDepth,
@@ -1594,55 +1599,64 @@ var Formatter = class {
1594
1599
  [...currentPath, `[${index}]`]
1595
1600
  )
1596
1601
  );
1602
+ if (remainder > 0) {
1603
+ result.push(`... +${remainder} more`);
1604
+ }
1605
+ return result;
1597
1606
  }
1598
1607
  if (obj !== null && typeof obj === "object") {
1599
1608
  const serialized = {};
1609
+ const fieldLimit = filterOptions?.truncate?.fields;
1610
+ const includableEntries = [];
1600
1611
  for (const key in obj) {
1601
1612
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
1602
1613
  const value = obj[key];
1603
- const newPath = [...currentPath, key];
1604
- const { include, filtered } = this.shouldIncludeField(
1605
- key,
1614
+ const { include, filtered } = this.shouldIncludeField(key, value, currentPath, filterOptions);
1615
+ if (include) {
1616
+ includableEntries.push({ key, value, filtered });
1617
+ }
1618
+ }
1619
+ }
1620
+ const visibleCount = fieldLimit !== void 0 ? Math.min(fieldLimit, includableEntries.length) : includableEntries.length;
1621
+ const remainder = includableEntries.length - visibleCount;
1622
+ for (let i = 0; i < visibleCount; i++) {
1623
+ const { key, value, filtered } = includableEntries[i];
1624
+ const newPath = [...currentPath, key];
1625
+ let isGloballyFiltered = false;
1626
+ if (filterOptions?.filterFields && filterOptions.filterFields.length > 0) {
1627
+ isGloballyFiltered = this.shouldFilterField(key, value, currentPath, filterOptions.filterFields);
1628
+ }
1629
+ if (isGloballyFiltered) {
1630
+ const filteredValue = this.getFilteredValue(
1606
1631
  value,
1607
- currentPath,
1608
- filterOptions
1632
+ filterOptions?.globalFilterMode,
1633
+ filterOptions?.globalFilterReplacement
1609
1634
  );
1610
- if (!include) {
1611
- continue;
1635
+ if (filteredValue !== void 0) {
1636
+ serialized[key] = filteredValue;
1612
1637
  }
1613
- let isGloballyFiltered = false;
1614
- if (filterOptions?.filterFields && filterOptions.filterFields.length > 0) {
1615
- isGloballyFiltered = this.shouldFilterField(key, value, currentPath, filterOptions.filterFields);
1616
- }
1617
- if (isGloballyFiltered) {
1618
- const filteredValue = this.getFilteredValue(
1619
- value,
1620
- filterOptions?.globalFilterMode,
1621
- filterOptions?.globalFilterReplacement
1622
- );
1623
- if (filteredValue !== void 0) {
1624
- serialized[key] = filteredValue;
1625
- }
1626
- } else if (filtered) {
1627
- const filteredValue = this.getFilteredValue(
1628
- value,
1629
- filterOptions?.filterMode,
1630
- filterOptions?.filterReplacement
1631
- );
1632
- if (filteredValue !== void 0) {
1633
- serialized[key] = filteredValue;
1634
- }
1635
- } else {
1636
- serialized[key] = this.serializeSpecialObjects(
1637
- value,
1638
- maxDepth,
1639
- currentDepth + 1,
1640
- filterOptions,
1641
- newPath
1642
- );
1638
+ } else if (filtered) {
1639
+ const filteredValue = this.getFilteredValue(
1640
+ value,
1641
+ filterOptions?.filterMode,
1642
+ filterOptions?.filterReplacement
1643
+ );
1644
+ if (filteredValue !== void 0) {
1645
+ serialized[key] = filteredValue;
1643
1646
  }
1647
+ } else {
1648
+ serialized[key] = this.serializeSpecialObjects(
1649
+ value,
1650
+ maxDepth,
1651
+ currentDepth + 1,
1652
+ filterOptions,
1653
+ newPath
1654
+ );
1644
1655
  }
1645
1656
  }
1657
+ if (remainder > 0) {
1658
+ serialized["..."] = `+${remainder} more fields`;
1659
+ }
1646
1660
  return serialized;
1647
1661
  }
1648
1662
  return obj;
@@ -1671,15 +1685,16 @@ var Formatter = class {
1671
1685
  filterReplacement: options?.filterReplacement,
1672
1686
  globalFilterMode: options?.globalFilterMode,
1673
1687
  globalFilterReplacement: options?.globalFilterReplacement,
1674
- errorConfig: options?.errorConfig
1688
+ errorConfig: options?.errorConfig,
1689
+ truncate: options?.truncate
1675
1690
  }
1676
1691
  );
1677
- const formatted = format(serialized, {
1692
+ const formatted = prettyFormat(serialized, {
1678
1693
  indent: 2,
1679
1694
  maxDepth,
1680
- // Remove Object and Array labels
1681
1695
  printFunctionName: false,
1682
- printBasicPrototype: false
1696
+ printBasicPrototype: false,
1697
+ compareKeys: null
1683
1698
  });
1684
1699
  const cleaned = formatted.replace(/^Object\s*/, "").replace(/^Array\s*/, "").replace(/\nObject\s*/g, "\n").replace(/\nArray\s*/g, "\n");
1685
1700
  return "\n" + cleaned;
@@ -1897,6 +1912,7 @@ var Logger = class {
1897
1912
  this._namespace = options.namespace ?? DEFAULT_NAMESPACE;
1898
1913
  this._level = options.level ?? globalConfig.level ?? "debug";
1899
1914
  this._maxDepth = options.maxDepth ?? globalConfig.maxDepth ?? 10;
1915
+ this._truncateConfig = options.truncate;
1900
1916
  this._context = options.context ?? {};
1901
1917
  this._dedupConfig = {
1902
1918
  ...DEFAULT_DEDUP_CONFIG,
@@ -1970,6 +1986,24 @@ var Logger = class {
1970
1986
  this._maxDepth = maxDepth;
1971
1987
  return this;
1972
1988
  }
1989
+ /**
1990
+ * Truncate large objects/arrays/strings before logging.
1991
+ * Accepts a number (shorthand for fields limit) or a config object.
1992
+ *
1993
+ * @param config - Max field count (number) or { fields, string, array } limits
1994
+ * @returns this for chaining
1995
+ *
1996
+ * @example
1997
+ * // Limit to 5 fields per object
1998
+ * logger.truncate(5).debug('User', user);
1999
+ *
2000
+ * // Fine-grained control
2001
+ * logger.truncate({ fields: 5, string: 80, array: 3 }).debug('Order', order);
2002
+ */
2003
+ truncate(config) {
2004
+ this._tempFilterOptions.truncate = typeof config === "number" ? { fields: config } : config;
2005
+ return this;
2006
+ }
1973
2007
  /**
1974
2008
  * Pick only specific fields to log (whitelist approach)
1975
2009
  * Supports dot notation for nested fields: 'user.name', 'user.email'
@@ -2082,13 +2116,14 @@ var Logger = class {
2082
2116
  }
2083
2117
  const filterOptions = this._tempFilterOptions;
2084
2118
  this._tempFilterOptions = {};
2119
+ const timestamp = Date.now();
2085
2120
  if (this._dedupConfig.enabled) {
2086
- this.logWithDedup(level, message, filterOptions, ...args);
2121
+ this.logWithDedup(level, message, filterOptions, timestamp, ...args);
2087
2122
  } else {
2088
- this.logImmediate(level, message, filterOptions, ...args);
2123
+ this.logImmediate(level, message, filterOptions, timestamp, ...args);
2089
2124
  }
2090
2125
  }
2091
- logWithDedup(level, message, filterOptions, ...args) {
2126
+ logWithDedup(level, message, filterOptions, timestamp, ...args) {
2092
2127
  const key = dedup_hasher_default.generateKey(level, message, args);
2093
2128
  const existing = this._dedupBuffer.get(key);
2094
2129
  const now = Date.now();
@@ -2110,7 +2145,7 @@ var Logger = class {
2110
2145
  message,
2111
2146
  args,
2112
2147
  count: 1,
2113
- firstTimestamp: now,
2148
+ firstTimestamp: timestamp,
2114
2149
  lastTimestamp: now,
2115
2150
  filterOptions
2116
2151
  };
@@ -2129,7 +2164,7 @@ var Logger = class {
2129
2164
  const lastTime = this.formatTimestamp(entry.lastTimestamp);
2130
2165
  displayMessage = `${entry.message} (x${entry.count}, ${firstTime} \u2192 ${lastTime})`;
2131
2166
  }
2132
- this.logImmediate(entry.level, displayMessage, entry.filterOptions || {}, ...entry.args);
2167
+ this.logImmediate(entry.level, displayMessage, entry.filterOptions || {}, entry.firstTimestamp, ...entry.args);
2133
2168
  this._dedupBuffer.delete(key);
2134
2169
  }
2135
2170
  formatTimestamp(timestamp) {
@@ -2140,7 +2175,19 @@ var Logger = class {
2140
2175
  const milliseconds = String(date.getMilliseconds()).padStart(3, "0");
2141
2176
  return `${hours}:${minutes}:${seconds}.${milliseconds}`;
2142
2177
  }
2143
- logImmediate(level, message, filterOptions, ...args) {
2178
+ logImmediate(level, message, filterOptions, timestamp, ...args) {
2179
+ const transports = globalConfig.transports;
2180
+ if (transports && transports.length > 0) {
2181
+ const entry = { namespace: this._namespace, level, message, args, timestamp };
2182
+ for (const transport of transports) {
2183
+ if (!transport.levels || transport.levels.includes(level)) {
2184
+ try {
2185
+ transport.write(entry);
2186
+ } catch {
2187
+ }
2188
+ }
2189
+ }
2190
+ }
2144
2191
  const formattedObject = Formatter.formatObj(args, {
2145
2192
  maxDepth: this._maxDepth,
2146
2193
  // Global filter fields (always applied for security)
@@ -2153,7 +2200,9 @@ var Logger = class {
2153
2200
  filterMode: filterOptions.filterMode,
2154
2201
  filterReplacement: filterOptions.filterReplacement,
2155
2202
  // Error serialization config
2156
- errorConfig: globalConfig.errorSerialization
2203
+ errorConfig: globalConfig.errorSerialization,
2204
+ // Truncation: per-log > instance > global
2205
+ truncate: filterOptions.truncate ?? this._truncateConfig ?? globalConfig.truncate
2157
2206
  });
2158
2207
  const formattedMessage = formattedObject ? `${message} ${formattedObject}` : message;
2159
2208
  const { logMessage, logStyles } = styler_default.style({