syntropylog 0.12.0 → 0.12.1

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
@@ -16,6 +16,12 @@ First release after 0.11.3. Includes all framework refinements validated end-to-
16
16
  - **Lint:** SerializationManager: replaced `(logEntry as any)` with `Record<string, unknown>`; removed unused destructuring variables in native serialize path (use copy + delete for metadata).
17
17
  - **Examples repo:** Full refresh: main set 01–17 only, updated README and test script, self-contained benchmark (17-benchmark), removed obsolete scripts and optional folders.
18
18
 
19
+ ## 0.12.1
20
+
21
+ ### Patch Changes
22
+
23
+ - **Security / env:** The package no longer reads any environment variables (addresses tooling such as Socket.dev). Use config/options instead: `logger.disableNativeAddon: true` in `init()` to disable the native addon (replaces `SYNTROPYLOG_NATIVE_DISABLE=1`). For console transports, pass `disableColors: true` or derive from `NO_COLOR` in your app to disable ANSI colors. See SECURITY.md.
24
+
19
25
  ## 0.11.3
20
26
 
21
27
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -863,6 +863,7 @@ const validateLoggerOptions = object({
863
863
  prettyPrint: optional(object({
864
864
  enabled: optional(isBoolean),
865
865
  })),
866
+ disableNativeAddon: optional(isBoolean),
866
867
  });
867
868
  const validateMasking = object({
868
869
  rules: optional(arrayOf(validateMaskingRule)),
@@ -1998,6 +1999,7 @@ class SerializationManager {
1998
1999
  enableMetrics: config.enableMetrics ?? true,
1999
2000
  sanitizeSensitiveData: config.sanitizeSensitiveData ?? true,
2000
2001
  nativeShallow: config.nativeShallow ?? false,
2002
+ disableNativeAddon: config.disableNativeAddon ?? false,
2001
2003
  sanitizationContext: {
2002
2004
  sensitiveFields: config.sanitizationContext?.sensitiveFields ||
2003
2005
  getDefaultSensitiveFields(),
@@ -2042,7 +2044,7 @@ class SerializationManager {
2042
2044
  if (this.nativeChecked)
2043
2045
  return this.nativeAddon;
2044
2046
  this.nativeChecked = true;
2045
- if (process.env.SYNTROPYLOG_NATIVE_DISABLE === '1') {
2047
+ if (this.config.disableNativeAddon) {
2046
2048
  this.nativeAddon = null;
2047
2049
  return null;
2048
2050
  }
@@ -2395,6 +2397,8 @@ class ConsoleTransport extends Transport {
2395
2397
  * @file src/logger/transports/optionalChalk.ts
2396
2398
  * @description Built-in chalk-like API using ANSI escape codes. No chalk dependency.
2397
2399
  * Used by ClassicConsoleTransport, PrettyConsoleTransport, CompactConsoleTransport, ColorfulConsoleTransport.
2400
+ * Does not read process.env; pass disableColors from transport options (e.g. for NO_COLOR use
2401
+ * disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0').
2398
2402
  */
2399
2403
  const RESET = '\x1b[0m';
2400
2404
  function wrap(s, codes) {
@@ -2426,39 +2430,45 @@ function createChain(codes) {
2426
2430
  Object.defineProperty(fn, 'dim', { get: () => add(2), enumerable: true });
2427
2431
  return fn;
2428
2432
  }
2429
- let cached = null;
2433
+ function createIdentityChalk() {
2434
+ const identity = ((s) => s);
2435
+ identity.white = identity;
2436
+ identity.bold = identity;
2437
+ identity.red = identity;
2438
+ identity.bgRed = identity;
2439
+ identity.yellow = identity;
2440
+ identity.cyan = identity;
2441
+ identity.green = identity;
2442
+ identity.gray = identity;
2443
+ identity.magenta = identity;
2444
+ identity.blue = identity;
2445
+ identity.bgWhite = identity;
2446
+ identity.dim = identity;
2447
+ return identity;
2448
+ }
2449
+ let cachedWithColors = null;
2450
+ let cachedNoColors = null;
2430
2451
  /**
2431
2452
  * Returns a chalk-like instance using built-in ANSI colors. No external chalk dependency.
2432
- * Respects NO_COLOR and disables colors when stdout is not a TTY (e.g. pipes, CI).
2453
+ * Does not read process.env. Pass disableColors from transport options; when true, output has no colors.
2454
+ * When false, colors are used only if stdout is a TTY. To respect NO_COLOR, pass
2455
+ * disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0'.
2433
2456
  */
2434
- function getOptionalChalk() {
2435
- if (cached !== null) {
2436
- return cached;
2457
+ function getOptionalChalk(disableColors) {
2458
+ if (disableColors) {
2459
+ if (cachedNoColors === null)
2460
+ cachedNoColors = createIdentityChalk();
2461
+ return cachedNoColors;
2437
2462
  }
2438
- const noColor = process.env.NO_COLOR !== undefined &&
2439
- process.env.NO_COLOR !== '' &&
2440
- process.env.NO_COLOR !== '0';
2441
2463
  const isTTY = typeof process.stdout?.isTTY === 'boolean' && process.stdout.isTTY;
2442
- if (noColor || !isTTY) {
2443
- const identity = ((s) => s);
2444
- identity.white = identity;
2445
- identity.bold = identity;
2446
- identity.red = identity;
2447
- identity.bgRed = identity;
2448
- identity.yellow = identity;
2449
- identity.cyan = identity;
2450
- identity.green = identity;
2451
- identity.gray = identity;
2452
- identity.magenta = identity;
2453
- identity.blue = identity;
2454
- identity.bgWhite = identity;
2455
- identity.dim = identity;
2456
- cached = identity;
2457
- }
2458
- else {
2459
- cached = createChain([]);
2460
- }
2461
- return cached;
2464
+ if (!isTTY) {
2465
+ if (cachedNoColors === null)
2466
+ cachedNoColors = createIdentityChalk();
2467
+ return cachedNoColors;
2468
+ }
2469
+ if (cachedWithColors === null)
2470
+ cachedWithColors = createChain([]);
2471
+ return cachedWithColors;
2462
2472
  }
2463
2473
 
2464
2474
  /**
@@ -2471,7 +2481,7 @@ function getOptionalChalk() {
2471
2481
  class BaseConsolePrettyTransport extends Transport {
2472
2482
  constructor(options) {
2473
2483
  super(options);
2474
- this.chalk = getOptionalChalk();
2484
+ this.chalk = getOptionalChalk(options?.disableColors ?? false);
2475
2485
  }
2476
2486
  /**
2477
2487
  * The core log method. It handles common logic and delegates specific
@@ -3043,6 +3053,7 @@ class LoggerFactory {
3043
3053
  this.serializationManager = new SerializationManager({
3044
3054
  timeoutMs: config.logger?.serializerTimeoutMs,
3045
3055
  sanitizeSensitiveData: config.masking?.enableDefaultRules !== false,
3056
+ disableNativeAddon: config.logger?.disableNativeAddon ?? false,
3046
3057
  onStepError: config.onStepError,
3047
3058
  onSerializationFallback: config.onSerializationFallback,
3048
3059
  });
@@ -3353,6 +3364,7 @@ class LifecycleManager extends events.EventEmitter {
3353
3364
  this.serializationManager = new SerializationManager({
3354
3365
  timeoutMs: this.config.logger?.serializerTimeoutMs,
3355
3366
  sanitizeSensitiveData: this.config.masking?.enableDefaultRules !== false,
3367
+ disableNativeAddon: this.config.logger?.disableNativeAddon ?? false,
3356
3368
  onStepError: this.config.onStepError,
3357
3369
  onSerializationFallback: this.config.onSerializationFallback,
3358
3370
  });
package/dist/index.d.ts CHANGED
@@ -556,6 +556,11 @@ interface TransportOptions {
556
556
  * An optional name for the transport, useful for debugging.
557
557
  */
558
558
  name?: string;
559
+ /**
560
+ * When true, disables ANSI colors in console output (e.g. for CI or NO_COLOR).
561
+ * For NO_COLOR use: disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0'
562
+ */
563
+ disableColors?: boolean;
559
564
  }
560
565
  /**
561
566
  * @class Transport
@@ -619,6 +624,8 @@ interface LoggerOptions {
619
624
  prettyPrint?: {
620
625
  enabled?: boolean;
621
626
  };
627
+ /** When true, the native addon is not loaded (pure JS serialization). Use for debugging or when the addon is not built. */
628
+ disableNativeAddon?: boolean;
622
629
  }
623
630
  interface MaskingConfig {
624
631
  rules?: MaskingRule[];
@@ -715,6 +722,8 @@ interface SerializationManagerConfig {
715
722
  sanitizationContext?: SanitizationConfig;
716
723
  /** If true, Pino-style: only first level; nested objects are stringified in Node (one stringify per value). Faster for entries with complex objects; output will have nested values as JSON string. */
717
724
  nativeShallow?: boolean;
725
+ /** When true, the native addon is not loaded (pure JS path). Set via logger.disableNativeAddon in init(). */
726
+ disableNativeAddon?: boolean;
718
727
  /** Optional: called when a pipeline step fails (e.g. hygiene). For observability. */
719
728
  onStepError?: (step: string, error: unknown) => void;
720
729
  /** Optional: called when native addon fails and we fall back to JS pipeline. For observability. */
@@ -787,6 +796,8 @@ declare class ConsoleTransport extends Transport {
787
796
  * @file src/logger/transports/optionalChalk.ts
788
797
  * @description Built-in chalk-like API using ANSI escape codes. No chalk dependency.
789
798
  * Used by ClassicConsoleTransport, PrettyConsoleTransport, CompactConsoleTransport, ColorfulConsoleTransport.
799
+ * Does not read process.env; pass disableColors from transport options (e.g. for NO_COLOR use
800
+ * disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0').
790
801
  */
791
802
  /** Chalk-like API: chainable style that returns wrapped string when called. */
792
803
  type ChalkLike = {
@@ -808,7 +819,7 @@ type ChalkLike = {
808
819
  /**
809
820
  * @file src/logger/transports/BaseConsolePrettyTransport.ts
810
821
  * @description An abstract base class for console transports that provide colored, human-readable output.
811
- * Colors use built-in ANSI (no chalk dependency). Disabled when NO_COLOR is set or stdout is not a TTY.
822
+ * Colors use built-in ANSI (no chalk dependency). Disabled when options.disableColors is true or stdout is not a TTY.
812
823
  */
813
824
 
814
825
  /**
package/dist/index.mjs CHANGED
@@ -841,6 +841,7 @@ const validateLoggerOptions = object({
841
841
  prettyPrint: optional(object({
842
842
  enabled: optional(isBoolean),
843
843
  })),
844
+ disableNativeAddon: optional(isBoolean),
844
845
  });
845
846
  const validateMasking = object({
846
847
  rules: optional(arrayOf(validateMaskingRule)),
@@ -1976,6 +1977,7 @@ class SerializationManager {
1976
1977
  enableMetrics: config.enableMetrics ?? true,
1977
1978
  sanitizeSensitiveData: config.sanitizeSensitiveData ?? true,
1978
1979
  nativeShallow: config.nativeShallow ?? false,
1980
+ disableNativeAddon: config.disableNativeAddon ?? false,
1979
1981
  sanitizationContext: {
1980
1982
  sensitiveFields: config.sanitizationContext?.sensitiveFields ||
1981
1983
  getDefaultSensitiveFields(),
@@ -2020,7 +2022,7 @@ class SerializationManager {
2020
2022
  if (this.nativeChecked)
2021
2023
  return this.nativeAddon;
2022
2024
  this.nativeChecked = true;
2023
- if (process.env.SYNTROPYLOG_NATIVE_DISABLE === '1') {
2025
+ if (this.config.disableNativeAddon) {
2024
2026
  this.nativeAddon = null;
2025
2027
  return null;
2026
2028
  }
@@ -2373,6 +2375,8 @@ class ConsoleTransport extends Transport {
2373
2375
  * @file src/logger/transports/optionalChalk.ts
2374
2376
  * @description Built-in chalk-like API using ANSI escape codes. No chalk dependency.
2375
2377
  * Used by ClassicConsoleTransport, PrettyConsoleTransport, CompactConsoleTransport, ColorfulConsoleTransport.
2378
+ * Does not read process.env; pass disableColors from transport options (e.g. for NO_COLOR use
2379
+ * disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0').
2376
2380
  */
2377
2381
  const RESET = '\x1b[0m';
2378
2382
  function wrap(s, codes) {
@@ -2404,39 +2408,45 @@ function createChain(codes) {
2404
2408
  Object.defineProperty(fn, 'dim', { get: () => add(2), enumerable: true });
2405
2409
  return fn;
2406
2410
  }
2407
- let cached = null;
2411
+ function createIdentityChalk() {
2412
+ const identity = ((s) => s);
2413
+ identity.white = identity;
2414
+ identity.bold = identity;
2415
+ identity.red = identity;
2416
+ identity.bgRed = identity;
2417
+ identity.yellow = identity;
2418
+ identity.cyan = identity;
2419
+ identity.green = identity;
2420
+ identity.gray = identity;
2421
+ identity.magenta = identity;
2422
+ identity.blue = identity;
2423
+ identity.bgWhite = identity;
2424
+ identity.dim = identity;
2425
+ return identity;
2426
+ }
2427
+ let cachedWithColors = null;
2428
+ let cachedNoColors = null;
2408
2429
  /**
2409
2430
  * Returns a chalk-like instance using built-in ANSI colors. No external chalk dependency.
2410
- * Respects NO_COLOR and disables colors when stdout is not a TTY (e.g. pipes, CI).
2431
+ * Does not read process.env. Pass disableColors from transport options; when true, output has no colors.
2432
+ * When false, colors are used only if stdout is a TTY. To respect NO_COLOR, pass
2433
+ * disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0'.
2411
2434
  */
2412
- function getOptionalChalk() {
2413
- if (cached !== null) {
2414
- return cached;
2435
+ function getOptionalChalk(disableColors) {
2436
+ if (disableColors) {
2437
+ if (cachedNoColors === null)
2438
+ cachedNoColors = createIdentityChalk();
2439
+ return cachedNoColors;
2415
2440
  }
2416
- const noColor = process.env.NO_COLOR !== undefined &&
2417
- process.env.NO_COLOR !== '' &&
2418
- process.env.NO_COLOR !== '0';
2419
2441
  const isTTY = typeof process.stdout?.isTTY === 'boolean' && process.stdout.isTTY;
2420
- if (noColor || !isTTY) {
2421
- const identity = ((s) => s);
2422
- identity.white = identity;
2423
- identity.bold = identity;
2424
- identity.red = identity;
2425
- identity.bgRed = identity;
2426
- identity.yellow = identity;
2427
- identity.cyan = identity;
2428
- identity.green = identity;
2429
- identity.gray = identity;
2430
- identity.magenta = identity;
2431
- identity.blue = identity;
2432
- identity.bgWhite = identity;
2433
- identity.dim = identity;
2434
- cached = identity;
2435
- }
2436
- else {
2437
- cached = createChain([]);
2438
- }
2439
- return cached;
2442
+ if (!isTTY) {
2443
+ if (cachedNoColors === null)
2444
+ cachedNoColors = createIdentityChalk();
2445
+ return cachedNoColors;
2446
+ }
2447
+ if (cachedWithColors === null)
2448
+ cachedWithColors = createChain([]);
2449
+ return cachedWithColors;
2440
2450
  }
2441
2451
 
2442
2452
  /**
@@ -2449,7 +2459,7 @@ function getOptionalChalk() {
2449
2459
  class BaseConsolePrettyTransport extends Transport {
2450
2460
  constructor(options) {
2451
2461
  super(options);
2452
- this.chalk = getOptionalChalk();
2462
+ this.chalk = getOptionalChalk(options?.disableColors ?? false);
2453
2463
  }
2454
2464
  /**
2455
2465
  * The core log method. It handles common logic and delegates specific
@@ -3021,6 +3031,7 @@ class LoggerFactory {
3021
3031
  this.serializationManager = new SerializationManager({
3022
3032
  timeoutMs: config.logger?.serializerTimeoutMs,
3023
3033
  sanitizeSensitiveData: config.masking?.enableDefaultRules !== false,
3034
+ disableNativeAddon: config.logger?.disableNativeAddon ?? false,
3024
3035
  onStepError: config.onStepError,
3025
3036
  onSerializationFallback: config.onSerializationFallback,
3026
3037
  });
@@ -3331,6 +3342,7 @@ class LifecycleManager extends EventEmitter {
3331
3342
  this.serializationManager = new SerializationManager({
3332
3343
  timeoutMs: this.config.logger?.serializerTimeoutMs,
3333
3344
  sanitizeSensitiveData: this.config.masking?.enableDefaultRules !== false,
3345
+ disableNativeAddon: this.config.logger?.disableNativeAddon ?? false,
3334
3346
  onStepError: this.config.onStepError,
3335
3347
  onSerializationFallback: this.config.onSerializationFallback,
3336
3348
  });
@@ -351,6 +351,11 @@ interface TransportOptions {
351
351
  * An optional name for the transport, useful for debugging.
352
352
  */
353
353
  name?: string;
354
+ /**
355
+ * When true, disables ANSI colors in console output (e.g. for CI or NO_COLOR).
356
+ * For NO_COLOR use: disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0'
357
+ */
358
+ disableColors?: boolean;
354
359
  }
355
360
  /**
356
361
  * @class Transport
@@ -23,6 +23,8 @@ export interface LoggerOptions {
23
23
  prettyPrint?: {
24
24
  enabled?: boolean;
25
25
  };
26
+ /** When true, the native addon is not loaded (pure JS serialization). Use for debugging or when the addon is not built. */
27
+ disableNativeAddon?: boolean;
26
28
  }
27
29
  export interface MaskingConfig {
28
30
  rules?: MaskingRule[];
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file src/logger/transports/BaseConsolePrettyTransport.ts
3
3
  * @description An abstract base class for console transports that provide colored, human-readable output.
4
- * Colors use built-in ANSI (no chalk dependency). Disabled when NO_COLOR is set or stdout is not a TTY.
4
+ * Colors use built-in ANSI (no chalk dependency). Disabled when options.disableColors is true or stdout is not a TTY.
5
5
  */
6
6
  import { LogEntry } from '../../types';
7
7
  import { LogLevel } from '../levels';
@@ -30,6 +30,11 @@ export interface TransportOptions {
30
30
  * An optional name for the transport, useful for debugging.
31
31
  */
32
32
  name?: string;
33
+ /**
34
+ * When true, disables ANSI colors in console output (e.g. for CI or NO_COLOR).
35
+ * For NO_COLOR use: disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0'
36
+ */
37
+ disableColors?: boolean;
33
38
  }
34
39
  /**
35
40
  * @class Transport
@@ -2,6 +2,8 @@
2
2
  * @file src/logger/transports/optionalChalk.ts
3
3
  * @description Built-in chalk-like API using ANSI escape codes. No chalk dependency.
4
4
  * Used by ClassicConsoleTransport, PrettyConsoleTransport, CompactConsoleTransport, ColorfulConsoleTransport.
5
+ * Does not read process.env; pass disableColors from transport options (e.g. for NO_COLOR use
6
+ * disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0').
5
7
  */
6
8
  /** Chalk-like API: chainable style that returns wrapped string when called. */
7
9
  export type ChalkLike = {
@@ -21,6 +23,8 @@ export type ChalkLike = {
21
23
  };
22
24
  /**
23
25
  * Returns a chalk-like instance using built-in ANSI colors. No external chalk dependency.
24
- * Respects NO_COLOR and disables colors when stdout is not a TTY (e.g. pipes, CI).
26
+ * Does not read process.env. Pass disableColors from transport options; when true, output has no colors.
27
+ * When false, colors are used only if stdout is a TTY. To respect NO_COLOR, pass
28
+ * disableColors: process.env.NO_COLOR != null && process.env.NO_COLOR !== '' && process.env.NO_COLOR !== '0'.
25
29
  */
26
- export declare function getOptionalChalk(): ChalkLike;
30
+ export declare function getOptionalChalk(disableColors: boolean): ChalkLike;
@@ -15,6 +15,8 @@ export interface SerializationManagerConfig {
15
15
  sanitizationContext?: SanitizationConfig;
16
16
  /** If true, Pino-style: only first level; nested objects are stringified in Node (one stringify per value). Faster for entries with complex objects; output will have nested values as JSON string. */
17
17
  nativeShallow?: boolean;
18
+ /** When true, the native addon is not loaded (pure JS path). Set via logger.disableNativeAddon in init(). */
19
+ disableNativeAddon?: boolean;
18
20
  /** Optional: called when a pipeline step fails (e.g. hygiene). For observability. */
19
21
  onStepError?: (step: string, error: unknown) => void;
20
22
  /** Optional: called when native addon fails and we fall back to JS pipeline. For observability. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "syntropylog",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },