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