syntropylog 0.9.20 โ†’ 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Patch Changes
6
+
7
+ - refactor: replace valibot with zero-dependency ROP config validator.
8
+ This change significantly reduces the bundle size by eliminating the valibot dependency (~30kB raw reduction) and introduces a robust, functional configuration validation system with 100% test coverage.
9
+
3
10
  ## 0.9.20
4
11
 
5
12
  ### Patch Changes
package/README.md CHANGED
@@ -16,8 +16,8 @@
16
16
  <a href="https://www.npmjs.com/package/syntropylog"><img src="https://img.shields.io/npm/v/syntropylog.svg" alt="NPM Version"></a>
17
17
  <a href="https://github.com/Syntropysoft/SyntropyLog/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/syntropylog.svg" alt="License"></a>
18
18
  <a href="https://github.com/Syntropysoft/SyntropyLog/actions/workflows/ci.yaml"><img src="https://github.com/Syntropysoft/SyntropyLog/actions/workflows/ci.yaml/badge.svg" alt="CI Status"></a>
19
- <a href="#"><img src="https://img.shields.io/badge/coverage-92.47%25-brightgreen" alt="Test Coverage"></a>
20
- <a href="#"><img src="https://img.shields.io/badge/status-v0.9.12-brightgreen.svg" alt="Version 0.9.12"></a>
19
+ <a href="#"><img src="https://img.shields.io/badge/coverage-95.13%25-brightgreen" alt="Test Coverage"></a>
20
+ <a href="#"><img src="https://img.shields.io/badge/status-v0.10.0-brightgreen.svg" alt="Version 0.10.0"></a>
21
21
  <a href="https://socket.dev/npm/package/syntropylog"><img src="https://socket.dev/api/badge/npm/package/syntropylog" alt="Socket Badge"></a>
22
22
  </p>
23
23
 
@@ -57,7 +57,7 @@ We ship with `sideEffects: false` and ESM so bundlers (Vite, Rollup, webpack, es
57
57
 
58
58
  Traditional loggers (and even modern ones) share a common weakness: **serialization is a blocking operation**. If you log a massive, deeply nested, or circular object, the Node.js Event Loop stops. Your API stops responding. Your service might even crash with a `TypeError`.
59
59
 
60
- SyntropyLog v0.9.1 introduces the **Log Resilience Engine**, making your application immune to "Death by Log":
60
+ SyntropyLog v0.10.0 introduces the **Log Resilience Engine**, making your application immune to "Death by Log":
61
61
 
62
62
  1. **Event Loop Protection**: Every serialization step is wrapped in a mandatory timeout (default: **50ms**). If serialization takes too long, it is aborted via `Promise.race`, and a safe subset of the data is logged instead. Your app keeps running.
63
63
  2. **Circular Reference Immunity**: Built-in hygiene automatically detects and neutralizes circular references. No more `TypeError: Converting circular structure to JSON`.
@@ -604,20 +604,7 @@ const dbTransport = new UniversalAdapter({
604
604
 
605
605
  ---
606
606
 
607
- ## ๐Ÿ“š Learn More
608
-
609
- SyntropyLog goes deep. Explore our specialized guides:
610
-
611
- | | Guide | Description |
612
- | :--- | :--- | :--- |
613
- | ๐Ÿ”ง | [Master Configuration](./docs/configuration.md) | Every option explained: `loggingMatrix`, `serializers`, masking, context. |
614
- | ๐Ÿ’พ | [Universal Persistence](./docs/persistence.md) | Map logs to any DB (SQL/NoSQL) with pure JSON, zero dependencies. |
615
- | ๐Ÿงฌ | [Serialization & Resiliency](./docs/serialization.md) | Circular reference protection, automated timeouts, and the Safe Pipeline. |
616
- | โš™๏ธ | [Middleware & Frameworks](./docs/middleware.md) | Integration patterns for Express, NestJS, and more via Universal Contracts. |
617
- | ๐Ÿข | [Enterprise Patterns](./docs/enterprise.md) | Scalable architectures, ELK, Kubernetes, and compliance. |
618
- | ๐Ÿงช | [Testing Strategy](./docs/testing.md) | Zero-boilerplate mocking with `SyntropyLogMock`. |
619
- | ๐ŸŽญ | [Core Philosophy](./docs/philosophy.md) | The "Silent Observer" principle and error handling strategy. |
620
- | ๐Ÿ“ฆ | [Examples](https://github.com/Syntropysoft/syntropylog-examples) | Real integrations with Express, Redis, Kafka, and more. |
607
+ ---
621
608
 
622
609
  ---
623
610
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("events"),t=require("valibot"),i=require("node:async_hooks"),r=require("crypto"),s=require("node:util");function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(i){if("default"!==i){var r=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,r.get?r:{enumerable:!0,get:function(){return e[i]}})}}),t.default=e,Object.freeze(t)}var a=n(t),o=n(s);const l={audit:70,fatal:60,error:50,warn:40,info:30,debug:20,trace:10,silent:0};class c{constructor(e={}){this.level=e.level??"info",this.name=e.name??this.constructor.name,this.formatter=e?.formatter,this.sanitizationEngine=e?.sanitizationEngine}isLevelEnabled(e){return l[e]>=l[this.level]}async flush(){return Promise.resolve()}}var u;!function(e){e.CREDIT_CARD="credit_card",e.SSN="ssn",e.EMAIL="email",e.PHONE="phone",e.PASSWORD="password",e.TOKEN="token",e.CUSTOM="custom"}(u||(u={}));class g{constructor(e){if(this.rules=[],this.initialized=!1,this.maskChar=e?.maskChar||"*",this.preserveLength=e?.preserveLength??!0,this.regexTimeoutMs=e?.regexTimeoutMs??100,!1!==e?.enableDefaultRules&&this.addDefaultRules(),e?.rules)for(const t of e.rules)this.addRule(t)}addDefaultRules(){const e=[{pattern:/credit_card|card_number|payment_number/i,strategy:u.CREDIT_CARD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/ssn|social_security|security_number/i,strategy:u.SSN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/email/i,strategy:u.EMAIL,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/phone|phone_number|mobile_number/i,strategy:u.PHONE,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/password|pass|pwd|secret/i,strategy:u.PASSWORD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/token|api_key|auth_token|jwt|bearer/i,strategy:u.TOKEN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0}];for(const t of e)this.addRule(t)}addRule(e){"string"==typeof e.pattern?e._compiledPattern=new RegExp(e.pattern,"i"):e._compiledPattern=e.pattern,e.preserveLength=e.preserveLength??this.preserveLength,e.maskChar=e.maskChar??this.maskChar,this.rules.push(e)}process(e){this.initialized||(this.initialized=!0);try{const t=new WeakSet;return this.applyMaskingRules(e,t)}catch{return{...g.buildSafeFallbackFromMeta(e),_maskingFailed:!0,_maskingFailedMessage:g.MASKING_FAILED_MESSAGE}}}static buildSafeFallbackFromMeta(e){const t={},i=["level","timestamp","message","service"];for(const r of i)r in e&&void 0!==e[r]&&(t[r]=e[r]);return t}applyMaskingRules(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return e;if(t.add(e),Array.isArray(e)){let i=!1;const r=new Array(e.length);for(let s=0;s<e.length;s++){const n=this.applyMaskingRules(e[s],t);r[s]=n,n!==e[s]&&(i=!0)}return i?r:e}const i=e;for(const e in i){if(!Object.prototype.hasOwnProperty.call(i,e))continue;const r=i[e];if("string"==typeof r)for(const t of this.rules){let s=!1;if(t._compiledPattern&&(s=t._isDefaultRule?t._compiledPattern.test(e):this.testRegexWithTimeout(t._compiledPattern,e)),s){i[e]=this.applyStrategy(r,t);break}}else if("object"==typeof r&&null!==r){const s=this.applyMaskingRules(r,t);s!==r&&(i[e]=s)}}return i}applyStrategy(e,t){if(t.strategy===u.CUSTOM&&t.customMask)return t.customMask(e);switch(t.strategy){case u.CREDIT_CARD:return this.maskCreditCard(e,t);case u.SSN:return this.maskSSN(e,t);case u.EMAIL:return this.maskEmail(e,t);case u.PHONE:return this.maskPhone(e,t);case u.PASSWORD:return this.maskPassword(e,t);case u.TOKEN:return this.maskToken(e,t);default:return this.maskDefault(e,t)}}maskCreditCard(e,t){const i=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(r,s)=>e.substring(0,s).replace(/\D/g,"").length<i.length-4?t.maskChar:r):`${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${i.slice(-4)}`}maskSSN(e,t){const i=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(r,s)=>e.substring(0,s).replace(/\D/g,"").length<i.length-4?t.maskChar:r):`***-**-${i.slice(-4)}`}maskEmail(e,t){const i=e.indexOf("@");if(i>0){const r=e.substring(0,i),s=e.substring(i);if(t.preserveLength){return(r.length>1?r.charAt(0)+t.maskChar.repeat(r.length-1):t.maskChar.repeat(r.length))+s}return`${r.charAt(0)}***${s}`}return this.maskDefault(e,t)}maskPhone(e,t){const i=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(r,s)=>e.substring(0,s).replace(/\D/g,"").length<i.length-4?t.maskChar:r):`${t.maskChar.repeat(3)}-${t.maskChar.repeat(3)}-${i.slice(-4)}`}maskPassword(e,t){return t.maskChar.repeat(e.length)}maskToken(e,t){return t.preserveLength?e.substring(0,4)+t.maskChar.repeat(e.length-9)+e.substring(e.length-5):e.length>8?e.substring(0,4)+"..."+e.substring(e.length-5):t.maskChar.repeat(e.length)}maskDefault(e,t){return t.preserveLength?t.maskChar.repeat(e.length):t.maskChar.repeat(Math.min(e.length,8))}getStats(){return{initialized:this.initialized,totalRules:this.rules.length,defaultRules:this.rules.filter(e=>[u.CREDIT_CARD,u.SSN,u.EMAIL,u.PHONE,u.PASSWORD,u.TOKEN].includes(e.strategy)).length,customRules:this.rules.filter(e=>e.strategy===u.CUSTOM).length,strategies:this.rules.map(e=>e.strategy)}}isInitialized(){return this.initialized}testRegexWithTimeout(e,t){if(t.length>256)return!1;try{return e.test(t)}catch{return!1}}shutdown(){this.rules=[],this.initialized=!1}}g.MASKING_FAILED_MESSAGE="[SyntropyLog] Masking could not be applied (e.g. timeout or error); payload redacted for safety.";const h=a.object({transport:a.custom(e=>e instanceof c,"Must be an instance of Transport"),env:a.optional(a.union([a.string(),a.array(a.string())]))}),d=a.union([a.custom(e=>e instanceof c,"Must be an instance of Transport"),h]),p=a.optional(a.object({name:a.optional(a.string()),level:a.optional(a.picklist(["audit","fatal","error","warn","info","debug","trace","silent"])),serviceName:a.optional(a.string()),environment:a.optional(a.string()),transportList:a.optional(a.record(a.string(),a.custom(e=>e instanceof c,"Must be an instance of Transport"))),env:a.optional(a.record(a.string(),a.array(a.string()))),transports:a.optional(a.union([a.array(d),a.record(a.string(),a.array(d))])),serializerTimeoutMs:a.optional(a.pipe(a.number(),a.integer(),a.minValue(1)),50),prettyPrint:a.optional(a.object({enabled:a.optional(a.boolean(),!1)}))})),m=a.optional(a.object({rules:a.optional(a.array(a.object({pattern:a.union([a.string(),a.instance(RegExp)]),strategy:a.enum(u),preserveLength:a.optional(a.boolean()),maskChar:a.optional(a.string()),customMask:a.optional(a.custom(e=>"function"==typeof e,"Must be a function"))}))),maskChar:a.optional(a.string()),preserveLength:a.optional(a.boolean()),enableDefaultRules:a.optional(a.boolean()),regexTimeoutMs:a.optional(a.pipe(a.number(),a.integer(),a.minValue(1)),100)})),f=a.optional(a.object({default:a.optional(a.array(a.string())),trace:a.optional(a.array(a.string())),debug:a.optional(a.array(a.string())),info:a.optional(a.array(a.string())),warn:a.optional(a.array(a.string())),error:a.optional(a.array(a.string())),fatal:a.optional(a.array(a.string()))})),y=a.object({logger:p,loggingMatrix:f,masking:m,context:a.optional(a.object({correlationIdHeader:a.optional(a.string()),transactionIdHeader:a.optional(a.string())})),shutdownTimeout:a.optional(a.pipe(a.number(),a.integer(),a.minValue(1),a.description("The maximum time in ms to wait for a graceful shutdown.")))}),S=Object.freeze({});class b{constructor(e){this.storage=new i.AsyncLocalStorage,this.correlationIdHeader="x-correlation-id",this.transactionIdHeader="x-trace-id",this.storage=new i.AsyncLocalStorage,this.loggingMatrix=e}configure(e){e.correlationIdHeader&&(this.correlationIdHeader=e.correlationIdHeader),e.transactionIdHeader&&(this.transactionIdHeader=e.transactionIdHeader)}reconfigureLoggingMatrix(e){this.loggingMatrix=e}run(e){return new Promise((t,i)=>{const r=this.storage.getStore(),s=new Map(r?.data);this.storage.run({data:s},async()=>{try{await Promise.resolve(e()),t()}catch(e){i(e)}})})}get(e){return this.storage.getStore()?.data.get(e)}getAll(){const e=this.storage.getStore();return e?Object.fromEntries(e.data.entries()):{}}set(e,t){const i=this.storage.getStore();i&&i.data.set(e,t)}getCorrelationId(){let e=this.get(this.correlationIdHeader)||this.get("correlationId");return e&&"string"==typeof e||(e=r.randomUUID(),this.set(this.correlationIdHeader,e)),e}setCorrelationId(e){this.set(this.correlationIdHeader,e)}getTransactionId(){return this.get("transactionId")}setTransactionId(e){this.set("transactionId",e)}getCorrelationIdHeaderName(){return this.correlationIdHeader}getTransactionIdHeaderName(){return this.transactionIdHeader}getTraceContextHeaders(){const e={};if(!this.storage.getStore())return e;const t=this.getCorrelationId(),i=this.getTransactionId();return t&&(e[this.getCorrelationIdHeaderName()]=t),i&&(e[this.getTransactionIdHeaderName()]=i),e}getFilteredContext(e){const t=this.getAll();if(!this.loggingMatrix){const e=Object.keys(t).length,i=this.get(this.correlationIdHeader),r=this.get("correlationId");if(0===e&&!i&&!r)return S;const s={};return Object.assign(s,t),!i&&r&&(s[this.correlationIdHeader]=r),s}const i=this.loggingMatrix[e]??this.loggingMatrix.default;if(!i)return S;const r={correlationId:[this.correlationIdHeader,"correlationId"],transactionId:[this.transactionIdHeader,"transactionId"],userId:["userId"],serviceName:["serviceName"],operation:["operation"],errorCode:["errorCode"],tenantId:["tenantId"],paymentId:["paymentId"],orderId:["orderId"],processorId:["processorId"],eventType:["eventType"]};if(i.includes("*")){const e={};for(const[i,s]of Object.entries(t)){let t=i;for(const[e,s]of Object.entries(r))if(s.includes(i)){t=e;break}e[t]=s}return e}const s={};for(const e of i){const i=r[e]||[e];for(const r of i)if(Object.prototype.hasOwnProperty.call(t,r)){s[e]=t[r];break}!Object.prototype.hasOwnProperty.call(s,e)&&Object.prototype.hasOwnProperty.call(t,e)&&(s[e]=t[e])}return s}}const w={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0};class v{constructor(e,t,i,r={}){this.pendingRouting=null,this.name=e,this.transports=t,this.dependencies=i,this.bindings=r.bindings??{},this.level=r.level??"info"}override(...e){return this.pendingRouting={override:e},this}add(...e){const t=this.pendingRouting,i=[...t&&"add"in t?t.add??[]:[],...e],r=t&&"remove"in t?t.remove??[]:void 0;return this.pendingRouting=r?.length?{add:i,remove:r}:{add:i},this}remove(...e){const t=this.pendingRouting,i=[...t&&"remove"in t?t.remove??[]:[],...e],r=t&&"add"in t?t.add??[]:void 0;return this.pendingRouting=r?.length?{add:r,remove:i}:{remove:i},this}captureEffectiveTransports(){const e=this.pendingRouting;return this.pendingRouting=null,function(e,t,i){if(!t||!i)return e;if("override"in i)return i.override.map(e=>t.get(e)).filter(e=>null!=e);let r=[...e];if(i.add?.length)for(const e of i.add){const i=t.get(e);i&&r.push(i)}if(i.remove?.length){const e=new Set(i.remove);r=r.filter(t=>!e.has(t.name))}return r}(this.transports,this.dependencies.transportPool,e)}async _log(e,...t){if("silent"===e)return;if(!function(e,t){return"silent"!==e&&("audit"===e||l[e]>=l[t])}(e,this.level))return;const i=this.captureEffectiveTransports();try{const{message:r,metadata:s}=function(e){let t,i={};if(0===e.length)t="";else if("object"!=typeof e[0]||null===e[0]||Array.isArray(e[0])){t=e[0]||"";const i=e.slice(1);t&&i.length>0&&(t=o.format(t,...i))}else{i=e[0],t=e[1]||"";const r=e.slice(2);t&&r.length>0&&(t=o.format(t,...r))}return{message:t||"",metadata:i}}(t),n=this.dependencies.contextManager.getFilteredContext(e),a={level:e,timestamp:(new Date).toISOString(),service:this.name,message:r};Object.assign(a,n,this.bindings,s);const l=this.dependencies.serializationManager.serialize(a,w).data,c=this.dependencies.maskingEngine.process(l);for(const t of i)t.isLevelEnabled(e)&&t.log(c)}catch{}}info(...e){return this._log("info",...e)}warn(...e){return this._log("warn",...e)}error(...e){return this._log("error",...e)}debug(...e){return this._log("debug",...e)}trace(...e){return this._log("trace",...e)}audit(...e){return this._log("audit",...e)}fatal(...e){return this._log("fatal",...e)}setLevel(e){this.level=e}child(e){return new v(this.name,this.transports,this.dependencies,{level:this.level,bindings:{...this.bindings,...e}})}withSource(e){return this.child({source:e})}withRetention(e){return this.child({retention:e})}withTransactionId(e){return this.child({transactionId:e})}}var k;exports.SerializationComplexity=void 0,(k=exports.SerializationComplexity||(exports.SerializationComplexity={})).SIMPLE="simple",k.COMPLEX="complex",k.CRITICAL="critical";class z{constructor(){this.defaultSensitiveFields=["password","token","secret","key","auth","authorization","api_key","apikey","private_key","privatekey","credential","credential_id","credentialid","access_token","accesstoken","refresh_token","refreshtoken","session_id","sessionid"],this.defaultMaxDepth=10}sanitize(e,t={}){const i=t.sensitiveFields||this.defaultSensitiveFields,r=t.maxDepth||this.defaultMaxDepth,s=t.currentDepth||0;if(s>=r)return"[MAX_DEPTH_REACHED]";if(null==e)return e;if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e)){const t={sensitiveFields:i,maxDepth:r,currentDepth:s+1};for(let i=0;i<e.length;i++){const r=this.sanitize(e[i],t);r!==e[i]&&(e[i]=r)}return e}if("object"==typeof e){const t=e;for(const e of Object.keys(t)){const n=e.toLowerCase();if(i.some(e=>n.includes(e.toLowerCase())))t[e]="[REDACTED]";else{const n=this.sanitize(t[e],{sensitiveFields:i,maxDepth:r,currentDepth:s+1});n!==t[e]&&(t[e]=n)}}return e}return e}}const x="pipeline",D="unknown";class M{constructor(){this.steps=[],this.timeoutStrategies=new Map,this.metrics=null,this.sanitizer=new z,this.initializeDefaultStrategies()}addStep(e){this.steps.push(e)}addTimeoutStrategy(e){this.timeoutStrategies.set(e.getStrategyName(),e)}process(e,t){const i=Date.now();this.metrics={stepDurations:{},totalDuration:0,operationTimeout:0,timeoutStrategy:D};let r=e;try{for(const e of this.steps){const i=Date.now();r=e.execute(r,t),this.metrics.stepDurations[e.name]=Date.now()-i}const e=this.selectTimeoutStrategy(r),s=e.calculateTimeout(r);return this.metrics.operationTimeout=s,this.metrics.timeoutStrategy=e.getStrategyName(),this.metrics.totalDuration=Date.now()-i,M.buildSuccessResult(r,t.sanitizeSensitiveData,this.metrics,s,e.getStrategyName())}catch(e){return this.metrics.totalDuration=Date.now()-i,M.buildErrorResult(r,e,this.metrics)}}getMetrics(){return this.metrics}static buildSuccessResult(e,t,i,r,s){const n=e,a=n.serializer??x,o=n.serializationComplexity??exports.SerializationComplexity.SIMPLE;return{success:!0,data:e,serializer:a,duration:i.totalDuration,complexity:o,sanitized:t,metadata:{stepDurations:i.stepDurations,operationTimeout:r,timeoutStrategy:s,serializer:a,complexity:o}}}static buildErrorResult(e,t,i){const r=t?.serializer??x;return{success:!1,data:e,serializer:r,duration:i.totalDuration,complexity:exports.SerializationComplexity.SIMPLE,sanitized:!1,error:t instanceof Error?t.message:String(t),metadata:{stepDurations:i.stepDurations,operationTimeout:0,timeoutStrategy:D,serializer:r,complexity:exports.SerializationComplexity.SIMPLE}}}selectTimeoutStrategy(e){const t=this.timeoutStrategies.get("default");if(null==t)throw new Error("SerializationPipeline: default timeout strategy is required");return t}initializeDefaultStrategies(){this.addTimeoutStrategy(new C)}}class C{calculateTimeout(e){return 5e3}getStrategyName(){return"default"}}class E{constructor(e=[]){this.name="serialization",this.serializers=[],this.serializers=e}addSerializer(e){const t=this.serializers.findIndex(t=>t.priority<e.priority);-1===t?this.serializers.push(e):this.serializers.splice(t,0,e)}execute(e,t){const i=Date.now(),r=this.findSerializer(e);if(!r)return e;try{const s=r.serialize(e,t.serializationContext),n=Date.now()-i,a="object"==typeof s.data&&null!==s.data?s.data:{};return a.serializationDuration=n,a.serializer=r.name,a.serializationComplexity=s.complexity||s.metadata?.complexity||null,a}catch(e){throw e instanceof Error&&!e.serializer&&(e.serializer=r.name),e}}findSerializer(e){for(const t of this.serializers)if(t.canSerialize(e))return t;return null}getRegisteredSerializers(){return this.serializers.map(e=>e.name)}}function O(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return"[Circular]";if(t.add(e),Array.isArray(e)){let i=!1;const r=new Array(e.length);for(let s=0;s<e.length;s++){const n=O(e[s],t);r[s]=n,n!==e[s]&&(i=!0)}return t.delete(e),i?r:e}for(const i in e)if(Object.prototype.hasOwnProperty.call(e,i)){const r=e[i],s=O(r,t);s!==r&&(e[i]=s)}return t.delete(e),e}class I{constructor(){this.name="hygiene"}execute(e,t){if(null===e||"object"!=typeof e)return e;try{if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack,...e};try{return JSON.stringify(e),e}catch{let t;try{t=O(e,new WeakSet)}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}return t}}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}}}function L(e,t,i,r){if("object"==typeof e&&null!==e){const s=e;return s.sanitizationDuration=t,s.sanitized=i,void 0!==r&&(s.sanitizationError=r),e}return{sanitizationDuration:t,sanitized:i,...void 0!==r&&{sanitizationError:r}}}class T{constructor(e){this.name="sanitization",this.sanitizer=e??new z}execute(e,t){const i=Date.now(),r=()=>Date.now()-i;if(!t.sanitizeSensitiveData)return L(e,r(),!1);try{return L(this.sanitizer.sanitize(e,t.sanitizationContext),r(),!0)}catch(t){return L(e,r(),!1,function(e){return e instanceof Error?e.message:String(e)}(t))}}}const R=3e3;class P{constructor(e){this.name="timeout",this.timeoutStrategies=new Map,this.timeoutStrategies=e}execute(e,t){const i=Date.now();try{const t=this.selectTimeoutStrategy(e),r=t?.calculateTimeout(e)??R;return function(e,t,i,r){if("object"==typeof e&&null!==e){const s=e;return s.timeoutDuration=t,s.operationTimeout=i,s.timeoutStrategy=r?.getStrategyName()??"default",s.timeoutApplied=null!=r,e}return{timeoutDuration:t,operationTimeout:i,timeoutStrategy:r?.getStrategyName()??"default",timeoutApplied:null!=r}}(e,Date.now()-i,r,t)}catch(t){return function(e,t,i){if("object"==typeof e&&null!==e){const r=e;return r.timeoutDuration=t,r.operationTimeout=R,r.timeoutStrategy="default",r.timeoutApplied=!1,r.timeoutError=i instanceof Error?i.message:"Timeout error",e}return{timeoutDuration:t,operationTimeout:R,timeoutStrategy:"default",timeoutApplied:!1,timeoutError:i instanceof Error?i.message:"Timeout error"}}(e,Date.now()-i,t)}}selectTimeoutStrategy(e){return this.timeoutStrategies.get("default")??null}}class j{constructor(e={}){this.config={timeoutMs:e.timeoutMs||5e3,enableMetrics:e.enableMetrics??!0,sanitizeSensitiveData:e.sanitizeSensitiveData??!0,sanitizationContext:{sensitiveFields:e.sanitizationContext?.sensitiveFields||["password","token","secret","key","auth","credential","api_key","private_key","connection_string","wallet_location"],redactPatterns:e.sanitizationContext?.redactPatterns||[/password\s*=\s*['"][^'"]*['"]/gi,/user\s*=\s*['"][^'"]*['"]/gi,/token\s*=\s*['"][^'"]*['"]/gi,/secret\s*=\s*['"][^'"]*['"]/gi],maxStringLength:e.sanitizationContext?.maxStringLength||300,enableDeepSanitization:e.sanitizationContext?.enableDeepSanitization??!0}},this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}},this.pipeline=new M,this.serializationStep=new E,this.hygieneStep=new I,this.sanitizationStep=new T,this.timeoutStep=new P(this.pipeline.timeoutStrategies),this.pipeline.addStep(this.serializationStep),this.pipeline.addStep(this.hygieneStep),this.pipeline.addStep(this.sanitizationStep),this.pipeline.addStep(this.timeoutStep)}register(e){this.serializationStep.addSerializer(e)}serialize(e,t={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0}){const i=Date.now(),r={serializationContext:t,sanitizeSensitiveData:this.config.sanitizeSensitiveData,sanitizationContext:this.config.sanitizationContext,enableMetrics:this.config.enableMetrics},s=this.pipeline.process(e,r);return this.config.enableMetrics&&this.updateMetrics(s,Date.now()-i),s}updateMetrics(e,t){if(this.metrics.totalSerializations++,e.success){this.metrics.successfulSerializations++;const t=(e.metadata.stepDurations?.serialization||0)+(e.metadata.stepDurations?.hygiene||0);this.metrics.totalSerializationDuration+=t,this.metrics.maxSerializationDuration=Math.max(this.metrics.maxSerializationDuration,t),this.metrics.minSerializationDuration=0===this.metrics.minSerializationDuration?t:Math.min(this.metrics.minSerializationDuration,t);const i=e.metadata.operationTimeout||0;this.metrics.totalOperationTimeout+=i;const r=e.complexity||exports.SerializationComplexity.SIMPLE;r===exports.SerializationComplexity.SIMPLE?this.metrics.complexityDistribution.low++:r===exports.SerializationComplexity.COMPLEX?this.metrics.complexityDistribution.medium++:r===exports.SerializationComplexity.CRITICAL&&this.metrics.complexityDistribution.high++;const s=e.serializer||"unknown";this.metrics.serializerDistribution[s]=(this.metrics.serializerDistribution[s]||0)+1;const n=e.metadata.timeoutStrategy||"unknown";this.metrics.timeoutStrategyDistribution[n]=(this.metrics.timeoutStrategyDistribution[n]||0)+1}else this.metrics.failedSerializations++}getMetrics(){return{totalSerializations:this.metrics.totalSerializations,successfulSerializations:this.metrics.successfulSerializations,failedSerializations:this.metrics.failedSerializations,averageSerializationDuration:this.metrics.totalSerializations>0?this.metrics.totalSerializationDuration/this.metrics.totalSerializations:0,averageOperationTimeout:this.metrics.successfulSerializations>0?this.metrics.totalOperationTimeout/this.metrics.successfulSerializations:0,maxSerializationDuration:this.metrics.maxSerializationDuration,minSerializationDuration:this.metrics.minSerializationDuration,complexityDistribution:{...this.metrics.complexityDistribution},serializerDistribution:{...this.metrics.serializerDistribution},timeoutStrategyDistribution:{...this.metrics.timeoutStrategyDistribution}}}resetMetrics(){this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}}}getRegisteredSerializers(){return this.serializationStep.getRegisteredSerializers()}getPipelineMetrics(){return this.pipeline.getMetrics()}}class A extends c{constructor(e){super(e)}log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,i=JSON.stringify(t);switch(e.level){case"fatal":case"error":console.error(i);break;case"warn":console.warn(i);break;default:console.log(i)}}}class _{constructor(e){this.ansiRegex=/[\x1b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,this.maskingEngine=e}async process(e){let t=this.sanitizeRecursively(e);return this.maskingEngine&&(t=this.maskingEngine.process(t)),t}sanitizeRecursively(e){if("string"==typeof e)return e.replace(this.ansiRegex,"");if(Array.isArray(e))return e.map(e=>this.sanitizeRecursively(e));if("object"==typeof e&&null!==e&&e.constructor===Object){const t={},i=e;for(const e in i)Object.prototype.hasOwnProperty.call(i,e)&&(t[e]=this.sanitizeRecursively(i[e]));return t}return e}}function $(e,t){const i=[];for(const r of e)if(r instanceof c)i.push(r);else if(r&&"object"==typeof r&&"transport"in r){const e=null==r.env?null:Array.isArray(r.env)?r.env:[r.env];(null===e||e.includes(t))&&i.push(r.transport)}else r&&"object"==typeof r&&i.push(r);return i}class N{constructor(e,t,i){this.loggerPool=new Map,this.MAX_POOL_SIZE=1e3,this.contextManager=t,this.syntropyLogInstance=i,e.context&&this.contextManager.configure(e.context);const r=(e=>{const t=e.logger?.environment??"development",i=e.logger?.transportList&&Object.keys(e.logger.transportList).length>0,r=e.logger?.env&&Object.keys(e.logger.env).length>0;if(i&&r&&e.logger?.transportList&&e.logger?.env){const i=new Map(Object.entries(e.logger.transportList));return{transports:{default:(e.logger.env[t]??[]).map(e=>i.get(e)).filter(e=>null!=e)},transportPool:i}}if(e.logger?.transports){const i=e.logger.transports,r=new Map,s=e=>{const t=e instanceof c?e:e&&"object"==typeof e&&"transport"in e?e.transport:e,i=t.name??t.constructor?.name??`transport-${r.size}`;return r.set(i,t),t};let n;if(Array.isArray(i))i.forEach(s),n={default:$(i,t)};else{const e=i;n={};for(const[i,r]of Object.entries(e))r.forEach(s),n[i]=$(r,t)}return{transports:n,transportPool:r}}{const e=new _,t=new A({sanitizationEngine:e,name:"console"});return{transports:{default:[t]},transportPool:new Map([["console",t]])}}})(e);this.transports=r.transports,this.transportPool=r.transportPool,this.globalLogLevel=e.logger?.level??"info",this.serviceName=e.logger?.serviceName??"unknown-service",this.serializationManager=new j({timeoutMs:e.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==e.masking?.enableDefaultRules}),this.maskingEngine=new g({rules:e.masking?.rules,maskChar:e.masking?.maskChar,preserveLength:e.masking?.preserveLength,enableDefaultRules:!1!==e.masking?.enableDefaultRules,regexTimeoutMs:e.masking?.regexTimeoutMs})}getLogger(e="default",t){const i=((e,t)=>{if(!t||0===Object.keys(t).length)return e;const i=Object.keys(t).sort().reduce((e,i)=>(e[i]=t[i],e),{});try{return`${e}:${JSON.stringify(i)}`}catch{return`${e}:${Object.keys(i).sort().join(",")}`}})(e,t);if(this.loggerPool.has(i)){const e=this.loggerPool.get(i);return this.loggerPool.delete(i),this.loggerPool.set(i,e),e}const r="default"===e?this.serviceName:e,s={contextManager:this.contextManager,serializationManager:this.serializationManager,maskingEngine:this.maskingEngine,syntropyLogInstance:this.syntropyLogInstance,transportPool:this.transportPool},n=this.transports[e]??this.transports.default,a=new v(r,n,s,{bindings:t});if(a.level=this.globalLogLevel,this.loggerPool.size>=this.MAX_POOL_SIZE){const e=this.loggerPool.keys().next().value;void 0!==e&&this.loggerPool.delete(e)}return this.loggerPool.set(i,a),a}async flushAllTransports(){const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>e.flush().catch(t=>{console.error(`Error flushing transport ${e.constructor.name}:`,t)}));await Promise.allSettled(t)}async shutdown(){try{await this.flushAllTransports(),this.loggerPool.clear();const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>"function"==typeof e.shutdown?e.shutdown().catch(t=>{console.error(`Error shutting down transport ${e.constructor.name}:`,t)}):Promise.resolve());await Promise.allSettled(t)}catch(e){console.error("Error during LoggerFactory shutdown:",e)}}}const H="[CONFIG_MASKED]",F=["password","token","secret","apikey","credential","pass","key","accesstoken","refreshtoken","clientsecret","sentinelpassword","sasl"];function K(e){if(e instanceof c)return e;if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(e=>K(e));const t={},i=F.map(e=>e.toLowerCase());for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r)){const s=r.toLowerCase(),n=e[r];i.includes(s)?t[r]=H:(s.includes("url")||s.includes("uri"))&&"string"==typeof n?t[r]=n.replace(/(?<=:\/\/)[^:]+:[^@]+@/,`${H}@`):"object"!=typeof n||null===n||n instanceof RegExp?t[r]=n:t[r]=K(n)}return t}function U(e){return e instanceof Error?{name:e.name,message:e.message,stack:e.stack||null}:String(e)}class V extends e.EventEmitter{constructor(e){super(),this.state="NOT_INITIALIZED",this.logger=null,this.trackedProcesses=new Set,this.syntropyFacade=e,this.config={},this.serializationManager=new j({}),this.maskingEngine=new g({})}getState(){return this.state}async init(e){if("NOT_INITIALIZED"===this.state){this.state="INITIALIZING";try{const i=K(t.parse(y,e));this.config=i,this.contextManager=new b(this.config.loggingMatrix),this.config.context&&this.contextManager.configure(this.config.context),this.serializationManager=new j({timeoutMs:this.config.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==this.config.masking?.enableDefaultRules}),this.maskingEngine=new g({rules:this.config.masking?.rules,maskChar:this.config.masking?.maskChar,preserveLength:this.config.masking?.preserveLength,enableDefaultRules:!1!==this.config.masking?.enableDefaultRules,regexTimeoutMs:this.config.masking?.regexTimeoutMs}),this.loggerFactory=new N(this.config,this.contextManager,this.syntropyFacade);const r=this.loggerFactory.getLogger("syntropylog-main");this.logger=r,r.info("SyntropyLog framework initialized successfully."),this.state="READY",this.emit("ready")}catch(e){throw this.state="ERROR",this.emit("error",e),e instanceof t.ValiError?console.error("[SyntropyLog] Configuration validation failed:",e.issues):console.error("[SyntropyLog] Failed to initialize framework:",e),e}}else this.logger?.warn(`LifecycleManager.init() called while in state '${this.state}'. Ignoring subsequent call.`)}async shutdown(){if(this.logger?.info(`๐Ÿ”„ LifecycleManager.shutdown() called. Current state: ${this.state}`),"READY"===this.state){this.state="SHUTTING_DOWN",this.emit("shutting_down"),this.logger?.info("๐Ÿ”„ State changed to SHUTTING_DOWN");try{this.logger?.info("Shutting down SyntropyLog framework..."),this.maskingEngine?.shutdown?.();const e=[];e.push(this.terminateExternalProcesses()),this.logger?.info(`๐Ÿ“‹ Executing ${e.length} shutdown steps...`),await Promise.allSettled(e),await(this.logger?.info("โœ… Shutdown steps completed")),await(this.logger?.info("All managers have been shut down.")),await(this.logger?.info("โœ… State changed to SHUTDOWN")),await(this.loggerFactory?.shutdown?.()),"SHUTTING_DOWN"===this.state&&this.emit("transports_drained"),this.state="SHUTDOWN",this.emit("shutdown")}catch(e){this.state="ERROR",this.emit("error",e),this.logger?.error("โŒ Error during shutdown:",{error:U(e)}),await(this.loggerFactory?.shutdown?.()),"ERROR"===this.state&&this.emit("transports_drained")}}else this.logger?.warn(`โŒ Cannot perform shutdown. Current state: ${this.state}`)}registerChildProcess(e){this.trackedProcesses.add(e),e.on("exit",()=>{this.trackedProcesses.delete(e)})}async terminateExternalProcesses(){try{if(0===this.trackedProcesses.size)return void this.logger?.info("No tracked external processes to terminate");this.logger?.info(`Terminating ${this.trackedProcesses.size} external processes...`);const e=Array.from(this.trackedProcesses).map(e=>(async(e,t)=>{if(!e.connected&&null!==e.exitCode)return;const i=e.pid;t?.debug(`Sending SIGTERM to process ${i}...`),e.kill("SIGTERM");const r=new Promise(t=>{const i=()=>{t(),e.removeListener("exit",i)};e.on("exit",i)}),s=new Promise(e=>setTimeout(e,5e3));await Promise.race([r,s]),null===e.exitCode?(t?.warn(`Process ${i} did not exit after SIGTERM, sending SIGKILL...`),e.kill("SIGKILL")):t?.debug(`Process ${i} exited gracefully`)})(e,this.logger));await Promise.allSettled(e),this.trackedProcesses.clear(),this.logger?.info("โœ… All external processes terminated")}catch(e){this.logger?.warn("Error terminating external processes:",{error:U(e)})}}ensureReady(){if("READY"!==this.state)throw new Error(`SyntropyLog is not ready. Current state: '${this.state}'. Ensure init() has completed successfully by listening for the 'ready' event.`)}}function G(e,t){if(null==e)throw new Error(t)}class W extends e.EventEmitter{constructor(){super(),this.lifecycleManager=new V(this),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("transports_drained",()=>this.emit("transports_drained")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}static getInstance(){return W.instance||(W.instance=new W),W.instance}static resetInstance(){W.instance=void 0}getState(){return this.lifecycleManager.getState()}async init(e){return this.lifecycleManager.init(e)}async shutdown(){return this.lifecycleManager.shutdown()}getLogger(e="default",t){return G(this.lifecycleManager.loggerFactory,"Logger Factory not available."),this.lifecycleManager.loggerFactory.getLogger(e,t)}getContextManager(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager}getConfig(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.config}getFilteredContext(e){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.getFilteredContext(e)}reconfigureLoggingMatrix(e){this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.reconfigureLoggingMatrix(e)}getMasker(){return G(this.lifecycleManager.maskingEngine,"MaskingEngine not available."),this.lifecycleManager.maskingEngine}getSerializer(){return G(this.lifecycleManager.serializationManager,"SerializationManager not available."),this.lifecycleManager.serializationManager}_resetForTesting(){this.lifecycleManager.removeAllListeners(),Object.assign(this,{lifecycleManager:new V(this)}),this.removeAllListeners(),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}}const q=W.getInstance();function Y(e){const t=t=>function(e,t){return 0===t.length?e:`[${t.join(";")}m${e}`}(t,e),i=t=>Y([...e,t]);return Object.defineProperty(t,"white",{get:()=>i(37),enumerable:!0}),Object.defineProperty(t,"bold",{get:()=>i(1),enumerable:!0}),Object.defineProperty(t,"red",{get:()=>i(31),enumerable:!0}),Object.defineProperty(t,"bgRed",{get:()=>i(41),enumerable:!0}),Object.defineProperty(t,"yellow",{get:()=>i(33),enumerable:!0}),Object.defineProperty(t,"cyan",{get:()=>i(36),enumerable:!0}),Object.defineProperty(t,"green",{get:()=>i(32),enumerable:!0}),Object.defineProperty(t,"gray",{get:()=>i(90),enumerable:!0}),Object.defineProperty(t,"magenta",{get:()=>i(35),enumerable:!0}),Object.defineProperty(t,"blue",{get:()=>i(34),enumerable:!0}),Object.defineProperty(t,"bgWhite",{get:()=>i(47),enumerable:!0}),Object.defineProperty(t,"dim",{get:()=>i(2),enumerable:!0}),t}let J=null;function Z(){if(null!==J)return J;const e=void 0!==process.env.NO_COLOR&&""!==process.env.NO_COLOR&&"0"!==process.env.NO_COLOR,t="boolean"==typeof process.stdout?.isTTY&&process.stdout.isTTY;if(e||!t){const e=e=>e;e.white=e,e.bold=e,e.red=e,e.bgRed=e,e.yellow=e,e.cyan=e,e.green=e,e.gray=e,e.magenta=e,e.blue=e,e.bgWhite=e,e.dim=e,J=e}else J=Y([]);return J}class X extends c{constructor(e){super(e),this.chalk=Z()}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,i=this.formatLogString(t);this.getConsoleMethod(t.level)(i)}getConsoleMethod(e){switch(e){case"fatal":case"error":return console.error;case"warn":return console.warn;default:return console.log}}}exports.AdapterTransport=class extends c{constructor(e){if(!e.adapter)throw new Error("AdapterTransport requires a valid adapter implementation.");super(e),this.adapter=e.adapter}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e;await this.adapter.log(t)}async flush(){"function"==typeof this.adapter.flush&&await this.adapter.flush()}async shutdown(){"function"==typeof this.adapter.shutdown&&await this.adapter.shutdown()}},exports.ClassicConsoleTransport=class extends X{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatTimestamp(e){const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}:${String(t.getSeconds()).padStart(2,"0")}`}formatLogString(e){const{timestamp:t,level:i,service:r,message:s,context:n,...a}=e,o=this.levelColorMap[i]||this.chalk.white,l=this.formatTimestamp(t),c=o(i.toUpperCase().padEnd(5)),u=this.chalk.magenta(`[${r}]`),g={...n||{},...a,message:s},h=Object.keys(g);let d="";h.length>0&&(d=this.chalk.dim(" ["+h.map(e=>`${e}=${JSON.stringify(g[e])}`).join(" ")+"]"));return`${l} ${c} ${u}${d}`}},exports.ColorfulConsoleTransport=class extends X{constructor(e){var t;super(e),this.levelStyleMap={trace:{level:(t=this.chalk).gray.bold,message:t.gray,metaKey:t.gray.dim,metaValue:t.gray},debug:{level:t.cyan.bold,message:t.cyan,metaKey:t.cyan.dim,metaValue:t.cyan},info:{level:t.green.bold,message:t.green,metaKey:t.green.dim,metaValue:t.green},warn:{level:t.yellow.bold,message:t.yellow,metaKey:t.yellow.dim,metaValue:t.yellow},error:{level:t.red.bold,message:t.red,metaKey:t.red.dim,metaValue:t.red},fatal:{level:t.red.bgWhite.bold,message:t.red.bold,metaKey:t.red.dim,metaValue:t.red},audit:{level:t.magenta.bold,message:t.magenta,metaKey:t.magenta.dim,metaValue:t.magenta}}}formatLogString(e){return((e,t,i)=>{const{timestamp:r,level:s,service:n,message:a,...o}=e,l=i[s]??{level:t.white.bold,message:t.white,metaKey:t.gray,metaValue:t.white},c=l.metaKey(new Date(r).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})),u=s.toUpperCase().padEnd(8),g=l.level(u),h=n?l.metaValue(`(${n})`):"";let d=`${c} ${g}`;h&&(d+=` ${h}`),d+=` ${l.message(a??"")}`;const p=Object.keys(o);if(p.length>0){const e=p.map(e=>{const t=o[e],i="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${l.metaKey(e)}=${l.metaValue(i)}`});d+=`\n ${t.dim("โ””โ”€")} ${e.join(" ")}`}return d})(e,this.chalk,this.levelStyleMap)}},exports.CompactConsoleTransport=class extends X{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatLogString(e){const{timestamp:t,level:i,service:r,message:s,...n}=e,a=this.levelColorMap[i]||this.chalk.white;let o=`${this.chalk.gray(new Date(t).toLocaleTimeString())} ${a(`[${i.toUpperCase()}]`)} ${this.chalk.blue(`(${r})`)}: ${s||""}`;const l=Object.keys(n);if(l.length>0){const e=l.map(e=>{const t=n[e],i="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${this.chalk.dim(e)}=${this.chalk.gray(i)}`}).join(" ");o+=`\n ${this.chalk.dim("โ””โ”€")} ${e}`}return o}},exports.ConsoleTransport=A,exports.PrettyConsoleTransport=class extends X{constructor(e){var t;super(e),this.levelColorMap={fatal:(t=this.chalk).bgRed.white.bold,error:t.red.bold,warn:t.yellow.bold,info:t.blue.bold,audit:t.white.bold,debug:t.green,trace:t.gray}}formatLogString(e){return((e,t,i)=>{const{timestamp:r,level:s,service:n,message:a,...o}=e,l=i[s]||t.white;let c=`${t.gray(new Date(r).toLocaleTimeString())} ${l(`[${s.toUpperCase()}]`)} ${t.cyan(`(${n})`)}: ${a||""}`;Object.keys(o).length>0&&(c+=`\n${t.gray(JSON.stringify(o,null,2))}`);return c})(e,this.chalk,this.levelColorMap)}},exports.SanitizationEngine=_,exports.SerializationManager=j,exports.SpyTransport=class extends c{constructor(e){super(e),this.entries=[]}async log(e){this.entries.push(e)}getEntries(){return[...this.entries]}findEntries(e){return"function"==typeof e?this.entries.filter(e):this.entries.filter(t=>Object.keys(e).every(i=>{const r=i;return e[r]===t[r]}))}clear(){this.entries=[]}getFirstEntry(){return this.entries[0]}getLastEntry(){return this.entries[this.entries.length-1]}},exports.SyntropyLog=W,exports.Transport=c,exports.UniversalAdapter=class{constructor(e){if("function"!=typeof e.executor)throw new Error("UniversalAdapter requires an executor function.");this.executor=e.executor}async log(e){try{await this.executor(e)}catch(e){console.error(`UniversalAdapter execution failed: ${e instanceof Error?e.message:String(e)}`)}}},exports.UniversalLogFormatter=class{constructor(e){this.mapping=e.mapping,this.includeAllIn=e.includeAllIn}format(e){const t={};for(const[i,r]of Object.entries(this.mapping))t[i]=this.resolveValue(r,e);if(this.includeAllIn){const i=e.bindings??{},r=e.metadata??{};t[this.includeAllIn]={..."object"==typeof i&&null!==i?i:{},..."object"==typeof r&&null!==r?r:{}}}return t}resolveValue(e,t){if("object"==typeof e&&!Array.isArray(e)&&"value"in e){const t=e;return t.value??t.fallback}const i=Array.isArray(e)?e:[e];for(const e of i){if("object"==typeof e&&null!==e&&"value"in e){const t=e;return t.value??t.fallback}if("string"==typeof e){const i=this.getValueByPath(e,t);if(null!=i)return i}}}getValueByPath(e,t){if("message"===e)return t.message;if("level"===e)return t.level;if("timestamp"===e)return t.timestamp;const i=e.split(".");let r=t;for(const e of i){if(null===r||"object"!=typeof r)return;if(r===t&&!Object.prototype.hasOwnProperty.call(t,e)){const i=t,s=i.bindings?.[e];if(void 0!==s){r=s;continue}const n=i.metadata?.[e];if(void 0!==n){r=n;continue}}r=r[e]}return r}},exports.syntropyLog=q;
1
+ "use strict";var e=require("events"),t=require("node:async_hooks"),r=require("crypto");function i(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,Object.freeze(t)}var s=i(require("node:util"));const n=e=>({ok:!0,value:e}),a=(...e)=>({ok:!1,errors:e}),o=e=>t=>null==t?n(void 0):e(t),l=e=>t=>{if(!Array.isArray(t))return a("must be an array");const r=[],i=[];for(let s=0;s<t.length;s++){const n=e(t[s]);n.ok?r.push(n.value):i.push(...n.errors.map(e=>`[${s}]: ${String(e)}`))}return i.length>0?{ok:!1,errors:i}:n(r)},c=e=>t=>{if(null===t||"object"!=typeof t||Array.isArray(t))return a("must be an object");const r=t,i={...r},s=[];for(const t of Object.keys(e)){const n=(0,e[t])(r[t]);n.ok?i[t]=n.value:s.push(...n.errors.map(e=>`${t}: ${String(e)}`))}return s.length>0?{ok:!1,errors:s}:n(i)},u=e=>"string"==typeof e?n(e):a("expected string, got "+typeof e),g=e=>"boolean"==typeof e?n(e):a("expected boolean, got "+typeof e),h=e=>{const t=(e=>"number"!=typeof e||Number.isNaN(e)?a("expected number, got "+typeof e):n(e))(e);return t.ok?!Number.isInteger(t.value)||t.value<1?a(`must be a positive integer (>= 1), got ${t.value}`):n(t.value):t},d=e=>t=>e.includes(t)?n(t):a(`must be one of [${e.join(", ")}], got ${String(t)}`),m=e=>t=>{const r=(e=>null===e||"object"!=typeof e||Array.isArray(e)?a("expected object, got "+(null===e?"null":typeof e)):n(e))(t);if(!r.ok)return r;const i={},s=[];for(const[t,n]of Object.entries(r.value)){const r=e(n);r.ok?i[t]=r.value:s.push(...r.errors.map(e=>`${t}: ${e}`))}return s.length?{ok:!1,errors:s}:n(i)},p={audit:70,fatal:60,error:50,warn:40,info:30,debug:20,trace:10,silent:0};class f{constructor(e={}){this.level=e.level??"info",this.name=e.name??this.constructor.name,this.formatter=e?.formatter,this.sanitizationEngine=e?.sanitizationEngine}isLevelEnabled(e){return p[e]>=p[this.level]}async flush(){return Promise.resolve()}}var y;!function(e){e.CREDIT_CARD="credit_card",e.SSN="ssn",e.EMAIL="email",e.PHONE="phone",e.PASSWORD="password",e.TOKEN="token",e.CUSTOM="custom"}(y||(y={}));class S{constructor(e){if(this.rules=[],this.initialized=!1,this.maskChar=e?.maskChar||"*",this.preserveLength=e?.preserveLength??!0,this.regexTimeoutMs=e?.regexTimeoutMs??100,!1!==e?.enableDefaultRules&&this.addDefaultRules(),e?.rules)for(const t of e.rules)this.addRule(t)}addDefaultRules(){const e=[{pattern:/credit_card|card_number|payment_number/i,strategy:y.CREDIT_CARD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/ssn|social_security|security_number/i,strategy:y.SSN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/email/i,strategy:y.EMAIL,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/phone|phone_number|mobile_number/i,strategy:y.PHONE,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/password|pass|pwd|secret/i,strategy:y.PASSWORD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/token|api_key|auth_token|jwt|bearer/i,strategy:y.TOKEN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0}];for(const t of e)this.addRule(t)}addRule(e){"string"==typeof e.pattern?e._compiledPattern=new RegExp(e.pattern,"i"):e._compiledPattern=e.pattern,e.preserveLength=e.preserveLength??this.preserveLength,e.maskChar=e.maskChar??this.maskChar,this.rules.push(e)}process(e){this.initialized||(this.initialized=!0);try{const t=new WeakSet;return this.applyMaskingRules(e,t)}catch{return{...S.buildSafeFallbackFromMeta(e),_maskingFailed:!0,_maskingFailedMessage:S.MASKING_FAILED_MESSAGE}}}static buildSafeFallbackFromMeta(e){const t={},r=["level","timestamp","message","service"];for(const i of r)i in e&&void 0!==e[i]&&(t[i]=e[i]);return t}applyMaskingRules(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return e;if(t.add(e),Array.isArray(e)){let r=!1;const i=new Array(e.length);for(let s=0;s<e.length;s++){const n=this.applyMaskingRules(e[s],t);i[s]=n,n!==e[s]&&(r=!0)}return r?i:e}const r=e;for(const e in r){if(!Object.prototype.hasOwnProperty.call(r,e))continue;const i=r[e];if("string"==typeof i)for(const t of this.rules){let s=!1;if(t._compiledPattern&&(s=t._isDefaultRule?t._compiledPattern.test(e):this.testRegexWithTimeout(t._compiledPattern,e)),s){r[e]=this.applyStrategy(i,t);break}}else if("object"==typeof i&&null!==i){const s=this.applyMaskingRules(i,t);s!==i&&(r[e]=s)}}return r}applyStrategy(e,t){if(t.strategy===y.CUSTOM&&t.customMask)return t.customMask(e);switch(t.strategy){case y.CREDIT_CARD:return this.maskCreditCard(e,t);case y.SSN:return this.maskSSN(e,t);case y.EMAIL:return this.maskEmail(e,t);case y.PHONE:return this.maskPhone(e,t);case y.PASSWORD:return this.maskPassword(e,t);case y.TOKEN:return this.maskToken(e,t);default:return this.maskDefault(e,t)}}maskCreditCard(e,t){const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(i,s)=>e.substring(0,s).replace(/\D/g,"").length<r.length-4?t.maskChar:i):`${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${r.slice(-4)}`}maskSSN(e,t){const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(i,s)=>e.substring(0,s).replace(/\D/g,"").length<r.length-4?t.maskChar:i):`***-**-${r.slice(-4)}`}maskEmail(e,t){const r=e.indexOf("@");if(r>0){const i=e.substring(0,r),s=e.substring(r);if(t.preserveLength){return(i.length>1?i.charAt(0)+t.maskChar.repeat(i.length-1):t.maskChar.repeat(i.length))+s}return`${i.charAt(0)}***${s}`}return this.maskDefault(e,t)}maskPhone(e,t){const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(i,s)=>e.substring(0,s).replace(/\D/g,"").length<r.length-4?t.maskChar:i):`${t.maskChar.repeat(3)}-${t.maskChar.repeat(3)}-${r.slice(-4)}`}maskPassword(e,t){return t.maskChar.repeat(e.length)}maskToken(e,t){return t.preserveLength?e.substring(0,4)+t.maskChar.repeat(e.length-9)+e.substring(e.length-5):e.length>8?e.substring(0,4)+"..."+e.substring(e.length-5):t.maskChar.repeat(e.length)}maskDefault(e,t){return t.preserveLength?t.maskChar.repeat(e.length):t.maskChar.repeat(Math.min(e.length,8))}getStats(){return{initialized:this.initialized,totalRules:this.rules.length,defaultRules:this.rules.filter(e=>[y.CREDIT_CARD,y.SSN,y.EMAIL,y.PHONE,y.PASSWORD,y.TOKEN].includes(e.strategy)).length,customRules:this.rules.filter(e=>e.strategy===y.CUSTOM).length,strategies:this.rules.map(e=>e.strategy)}}isInitialized(){return this.initialized}testRegexWithTimeout(e,t){if(t.length>256)return!1;try{return e.test(t)}catch{return!1}}shutdown(){this.rules=[],this.initialized=!1}}S.MASKING_FAILED_MESSAGE="[SyntropyLog] Masking could not be applied (e.g. timeout or error); payload redacted for safety.";class b extends Error{constructor(e){super(`[SyntropyLog] Configuration validation failed:\n${e.map(e=>` โ€ข ${e}`).join("\n")}`),this.name="ConfigValidationError",this.issues=e}}const v=d(["audit","fatal","error","warn","info","debug","trace","silent"]),w=e=>e instanceof f?n(e):a("must be an instance of Transport"),k=e=>{const t=w(e);return t.ok?t:c({transport:w,env:o(e=>"string"==typeof e||Array.isArray(e)?n(e):a("env must be a string or string[]"))})(e)},x=c({pattern:e=>"string"==typeof e||e instanceof RegExp?n(e):a("expected string or RegExp, got "+typeof e),strategy:d(Object.values(y)),preserveLength:o(g),maskChar:o(u),customMask:o(e=>"function"==typeof e?n(e):a("expected function, got "+typeof e))}),z=c({name:o(u),level:o(v),serviceName:o(u),environment:o(u),transportList:o(m(w)),env:o(m(l(u))),transports:o(e=>{if(Array.isArray(e)){const t=l(k)(e);return t.ok?n(t.value):t}return null!==e&&"object"==typeof e?n(e):a("transports must be an array or a record of arrays")}),serializerTimeoutMs:o(h),prettyPrint:o(c({enabled:o(g)}))}),D=c({rules:o(l(x)),maskChar:o(u),preserveLength:o(g),enableDefaultRules:o(g),regexTimeoutMs:o(h)}),M=c({default:o(l(u)),trace:o(l(u)),debug:o(l(u)),info:o(l(u)),warn:o(l(u)),error:o(l(u)),fatal:o(l(u))}),C=c({correlationIdHeader:o(u),transactionIdHeader:o(u)}),E=c({logger:o(z),loggingMatrix:o(M),masking:o(D),context:o(C),shutdownTimeout:o(h)});const O=Object.freeze({});class I{constructor(e){this.storage=new t.AsyncLocalStorage,this.correlationIdHeader="x-correlation-id",this.transactionIdHeader="x-trace-id",this.storage=new t.AsyncLocalStorage,this.loggingMatrix=e}configure(e){e.correlationIdHeader&&(this.correlationIdHeader=e.correlationIdHeader),e.transactionIdHeader&&(this.transactionIdHeader=e.transactionIdHeader)}reconfigureLoggingMatrix(e){this.loggingMatrix=e}run(e){return new Promise((t,r)=>{const i=this.storage.getStore(),s=new Map(i?.data);this.storage.run({data:s},async()=>{try{await Promise.resolve(e()),t()}catch(e){r(e)}})})}get(e){return this.storage.getStore()?.data.get(e)}getAll(){const e=this.storage.getStore();return e?Object.fromEntries(e.data.entries()):{}}set(e,t){const r=this.storage.getStore();r&&r.data.set(e,t)}getCorrelationId(){let e=this.get(this.correlationIdHeader)||this.get("correlationId");return e&&"string"==typeof e||(e=r.randomUUID(),this.set(this.correlationIdHeader,e)),e}setCorrelationId(e){this.set(this.correlationIdHeader,e)}getTransactionId(){return this.get("transactionId")}setTransactionId(e){this.set("transactionId",e)}getCorrelationIdHeaderName(){return this.correlationIdHeader}getTransactionIdHeaderName(){return this.transactionIdHeader}getTraceContextHeaders(){const e={};if(!this.storage.getStore())return e;const t=this.getCorrelationId(),r=this.getTransactionId();return t&&(e[this.getCorrelationIdHeaderName()]=t),r&&(e[this.getTransactionIdHeaderName()]=r),e}getFilteredContext(e){const t=this.getAll();if(!this.loggingMatrix){const e=Object.keys(t).length,r=this.get(this.correlationIdHeader),i=this.get("correlationId");if(0===e&&!r&&!i)return O;const s={};return Object.assign(s,t),!r&&i&&(s[this.correlationIdHeader]=i),s}const r=this.loggingMatrix[e]??this.loggingMatrix.default;if(!r)return O;const i={correlationId:[this.correlationIdHeader,"correlationId"],transactionId:[this.transactionIdHeader,"transactionId"],userId:["userId"],serviceName:["serviceName"],operation:["operation"],errorCode:["errorCode"],tenantId:["tenantId"],paymentId:["paymentId"],orderId:["orderId"],processorId:["processorId"],eventType:["eventType"]};if(r.includes("*")){const e={};for(const[r,s]of Object.entries(t)){let t=r;for(const[e,s]of Object.entries(i))if(s.includes(r)){t=e;break}e[t]=s}return e}const s={};for(const e of r){const r=i[e]||[e];for(const i of r)if(Object.prototype.hasOwnProperty.call(t,i)){s[e]=t[i];break}!Object.prototype.hasOwnProperty.call(s,e)&&Object.prototype.hasOwnProperty.call(t,e)&&(s[e]=t[e])}return s}}const L={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0};class R{constructor(e,t,r,i={}){this.pendingRouting=null,this.name=e,this.transports=t,this.dependencies=r,this.bindings=i.bindings??{},this.level=i.level??"info"}override(...e){return this.pendingRouting={override:e},this}add(...e){const t=this.pendingRouting,r=[...t&&"add"in t?t.add??[]:[],...e],i=t&&"remove"in t?t.remove??[]:void 0;return this.pendingRouting=i?.length?{add:r,remove:i}:{add:r},this}remove(...e){const t=this.pendingRouting,r=[...t&&"remove"in t?t.remove??[]:[],...e],i=t&&"add"in t?t.add??[]:void 0;return this.pendingRouting=i?.length?{add:i,remove:r}:{remove:r},this}captureEffectiveTransports(){const e=this.pendingRouting;return this.pendingRouting=null,function(e,t,r){if(!t||!r)return e;if("override"in r)return r.override.map(e=>t.get(e)).filter(e=>null!=e);let i=[...e];if(r.add?.length)for(const e of r.add){const r=t.get(e);r&&i.push(r)}if(r.remove?.length){const e=new Set(r.remove);i=i.filter(t=>!e.has(t.name))}return i}(this.transports,this.dependencies.transportPool,e)}async _log(e,...t){if("silent"===e)return;if(!function(e,t){return"silent"!==e&&("audit"===e||p[e]>=p[t])}(e,this.level))return;const r=this.captureEffectiveTransports();try{const{message:i,metadata:n}=function(e){let t,r={};if(0===e.length)t="";else if("object"!=typeof e[0]||null===e[0]||Array.isArray(e[0])){t=e[0]||"";const r=e.slice(1);t&&r.length>0&&(t=s.format(t,...r))}else{r=e[0],t=e[1]||"";const i=e.slice(2);t&&i.length>0&&(t=s.format(t,...i))}return{message:t||"",metadata:r}}(t),a=this.dependencies.contextManager.getFilteredContext(e),o={level:e,timestamp:(new Date).toISOString(),service:this.name,message:i};Object.assign(o,a,this.bindings,n);const l=this.dependencies.serializationManager.serialize(o,L).data,c=this.dependencies.maskingEngine.process(l);for(const t of r)t.isLevelEnabled(e)&&t.log(c)}catch{}}info(...e){return this._log("info",...e)}warn(...e){return this._log("warn",...e)}error(...e){return this._log("error",...e)}debug(...e){return this._log("debug",...e)}trace(...e){return this._log("trace",...e)}audit(...e){return this._log("audit",...e)}fatal(...e){return this._log("fatal",...e)}setLevel(e){this.level=e}child(e){return new R(this.name,this.transports,this.dependencies,{level:this.level,bindings:{...this.bindings,...e}})}withSource(e){return this.child({source:e})}withRetention(e){return this.child({retention:e})}withTransactionId(e){return this.child({transactionId:e})}}var T;exports.SerializationComplexity=void 0,(T=exports.SerializationComplexity||(exports.SerializationComplexity={})).SIMPLE="simple",T.COMPLEX="complex",T.CRITICAL="critical";class P{constructor(){this.defaultSensitiveFields=["password","token","secret","key","auth","authorization","api_key","apikey","private_key","privatekey","credential","credential_id","credentialid","access_token","accesstoken","refresh_token","refreshtoken","session_id","sessionid"],this.defaultMaxDepth=10}sanitize(e,t={}){const r=t.sensitiveFields||this.defaultSensitiveFields,i=t.maxDepth||this.defaultMaxDepth,s=t.currentDepth||0;if(s>=i)return"[MAX_DEPTH_REACHED]";if(null==e)return e;if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e)){const t={sensitiveFields:r,maxDepth:i,currentDepth:s+1};for(let r=0;r<e.length;r++){const i=this.sanitize(e[r],t);i!==e[r]&&(e[r]=i)}return e}if("object"==typeof e){const t=e;for(const e of Object.keys(t)){const n=e.toLowerCase();if(r.some(e=>n.includes(e.toLowerCase())))t[e]="[REDACTED]";else{const n=this.sanitize(t[e],{sensitiveFields:r,maxDepth:i,currentDepth:s+1});n!==t[e]&&(t[e]=n)}}return e}return e}}const A="pipeline",j="unknown";class ${constructor(){this.steps=[],this.timeoutStrategies=new Map,this.metrics=null,this.sanitizer=new P,this.initializeDefaultStrategies()}addStep(e){this.steps.push(e)}addTimeoutStrategy(e){this.timeoutStrategies.set(e.getStrategyName(),e)}process(e,t){const r=Date.now();this.metrics={stepDurations:{},totalDuration:0,operationTimeout:0,timeoutStrategy:j};let i=e;try{for(const e of this.steps){const r=Date.now();i=e.execute(i,t),this.metrics.stepDurations[e.name]=Date.now()-r}const e=this.selectTimeoutStrategy(i),s=e.calculateTimeout(i);return this.metrics.operationTimeout=s,this.metrics.timeoutStrategy=e.getStrategyName(),this.metrics.totalDuration=Date.now()-r,$.buildSuccessResult(i,t.sanitizeSensitiveData,this.metrics,s,e.getStrategyName())}catch(e){return this.metrics.totalDuration=Date.now()-r,$.buildErrorResult(i,e,this.metrics)}}getMetrics(){return this.metrics}static buildSuccessResult(e,t,r,i,s){const n=e,a=n.serializer??A,o=n.serializationComplexity??exports.SerializationComplexity.SIMPLE;return{success:!0,data:e,serializer:a,duration:r.totalDuration,complexity:o,sanitized:t,metadata:{stepDurations:r.stepDurations,operationTimeout:i,timeoutStrategy:s,serializer:a,complexity:o}}}static buildErrorResult(e,t,r){const i=t?.serializer??A;return{success:!1,data:e,serializer:i,duration:r.totalDuration,complexity:exports.SerializationComplexity.SIMPLE,sanitized:!1,error:t instanceof Error?t.message:String(t),metadata:{stepDurations:r.stepDurations,operationTimeout:0,timeoutStrategy:j,serializer:i,complexity:exports.SerializationComplexity.SIMPLE}}}selectTimeoutStrategy(e){const t=this.timeoutStrategies.get("default");if(null==t)throw new Error("SerializationPipeline: default timeout strategy is required");return t}initializeDefaultStrategies(){this.addTimeoutStrategy(new _)}}class _{calculateTimeout(e){return 5e3}getStrategyName(){return"default"}}class N{constructor(e=[]){this.name="serialization",this.serializers=[],this.serializers=e}addSerializer(e){const t=this.serializers.findIndex(t=>t.priority<e.priority);-1===t?this.serializers.push(e):this.serializers.splice(t,0,e)}execute(e,t){const r=Date.now(),i=this.findSerializer(e);if(!i)return e;try{const s=i.serialize(e,t.serializationContext),n=Date.now()-r,a="object"==typeof s.data&&null!==s.data?s.data:{};return a.serializationDuration=n,a.serializer=i.name,a.serializationComplexity=s.complexity||s.metadata?.complexity||null,a}catch(e){throw e instanceof Error&&!e.serializer&&(e.serializer=i.name),e}}findSerializer(e){for(const t of this.serializers)if(t.canSerialize(e))return t;return null}getRegisteredSerializers(){return this.serializers.map(e=>e.name)}}function H(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return"[Circular]";if(t.add(e),Array.isArray(e)){let r=!1;const i=new Array(e.length);for(let s=0;s<e.length;s++){const n=H(e[s],t);i[s]=n,n!==e[s]&&(r=!0)}return t.delete(e),r?i:e}for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r)){const i=e[r],s=H(i,t);s!==i&&(e[r]=s)}return t.delete(e),e}class F{constructor(){this.name="hygiene"}execute(e,t){if(null===e||"object"!=typeof e)return e;try{if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack,...e};try{return JSON.stringify(e),e}catch{let t;try{t=H(e,new WeakSet)}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}return t}}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}}}function K(e,t,r,i){if("object"==typeof e&&null!==e){const s=e;return s.sanitizationDuration=t,s.sanitized=r,void 0!==i&&(s.sanitizationError=i),e}return{sanitizationDuration:t,sanitized:r,...void 0!==i&&{sanitizationError:i}}}class U{constructor(e){this.name="sanitization",this.sanitizer=e??new P}execute(e,t){const r=Date.now(),i=()=>Date.now()-r;if(!t.sanitizeSensitiveData)return K(e,i(),!1);try{return K(this.sanitizer.sanitize(e,t.sanitizationContext),i(),!0)}catch(t){return K(e,i(),!1,function(e){return e instanceof Error?e.message:String(e)}(t))}}}const G=3e3;class W{constructor(e){this.name="timeout",this.timeoutStrategies=new Map,this.timeoutStrategies=e}execute(e,t){const r=Date.now();try{const t=this.selectTimeoutStrategy(e),i=t?.calculateTimeout(e)??G;return function(e,t,r,i){if("object"==typeof e&&null!==e){const s=e;return s.timeoutDuration=t,s.operationTimeout=r,s.timeoutStrategy=i?.getStrategyName()??"default",s.timeoutApplied=null!=i,e}return{timeoutDuration:t,operationTimeout:r,timeoutStrategy:i?.getStrategyName()??"default",timeoutApplied:null!=i}}(e,Date.now()-r,i,t)}catch(t){return function(e,t,r){if("object"==typeof e&&null!==e){const i=e;return i.timeoutDuration=t,i.operationTimeout=G,i.timeoutStrategy="default",i.timeoutApplied=!1,i.timeoutError=r instanceof Error?r.message:"Timeout error",e}return{timeoutDuration:t,operationTimeout:G,timeoutStrategy:"default",timeoutApplied:!1,timeoutError:r instanceof Error?r.message:"Timeout error"}}(e,Date.now()-r,t)}}selectTimeoutStrategy(e){return this.timeoutStrategies.get("default")??null}}class V{constructor(e={}){this.config={timeoutMs:e.timeoutMs||5e3,enableMetrics:e.enableMetrics??!0,sanitizeSensitiveData:e.sanitizeSensitiveData??!0,sanitizationContext:{sensitiveFields:e.sanitizationContext?.sensitiveFields||["password","token","secret","key","auth","credential","api_key","private_key","connection_string","wallet_location"],redactPatterns:e.sanitizationContext?.redactPatterns||[/password\s*=\s*['"][^'"]*['"]/gi,/user\s*=\s*['"][^'"]*['"]/gi,/token\s*=\s*['"][^'"]*['"]/gi,/secret\s*=\s*['"][^'"]*['"]/gi],maxStringLength:e.sanitizationContext?.maxStringLength||300,enableDeepSanitization:e.sanitizationContext?.enableDeepSanitization??!0}},this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}},this.pipeline=new $,this.serializationStep=new N,this.hygieneStep=new F,this.sanitizationStep=new U,this.timeoutStep=new W(this.pipeline.timeoutStrategies),this.pipeline.addStep(this.serializationStep),this.pipeline.addStep(this.hygieneStep),this.pipeline.addStep(this.sanitizationStep),this.pipeline.addStep(this.timeoutStep)}register(e){this.serializationStep.addSerializer(e)}serialize(e,t={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0}){const r=Date.now(),i={serializationContext:t,sanitizeSensitiveData:this.config.sanitizeSensitiveData,sanitizationContext:this.config.sanitizationContext,enableMetrics:this.config.enableMetrics},s=this.pipeline.process(e,i);return this.config.enableMetrics&&this.updateMetrics(s,Date.now()-r),s}updateMetrics(e,t){if(this.metrics.totalSerializations++,e.success){this.metrics.successfulSerializations++;const t=(e.metadata.stepDurations?.serialization||0)+(e.metadata.stepDurations?.hygiene||0);this.metrics.totalSerializationDuration+=t,this.metrics.maxSerializationDuration=Math.max(this.metrics.maxSerializationDuration,t),this.metrics.minSerializationDuration=0===this.metrics.minSerializationDuration?t:Math.min(this.metrics.minSerializationDuration,t);const r=e.metadata.operationTimeout||0;this.metrics.totalOperationTimeout+=r;const i=e.complexity||exports.SerializationComplexity.SIMPLE;i===exports.SerializationComplexity.SIMPLE?this.metrics.complexityDistribution.low++:i===exports.SerializationComplexity.COMPLEX?this.metrics.complexityDistribution.medium++:i===exports.SerializationComplexity.CRITICAL&&this.metrics.complexityDistribution.high++;const s=e.serializer||"unknown";this.metrics.serializerDistribution[s]=(this.metrics.serializerDistribution[s]||0)+1;const n=e.metadata.timeoutStrategy||"unknown";this.metrics.timeoutStrategyDistribution[n]=(this.metrics.timeoutStrategyDistribution[n]||0)+1}else this.metrics.failedSerializations++}getMetrics(){return{totalSerializations:this.metrics.totalSerializations,successfulSerializations:this.metrics.successfulSerializations,failedSerializations:this.metrics.failedSerializations,averageSerializationDuration:this.metrics.totalSerializations>0?this.metrics.totalSerializationDuration/this.metrics.totalSerializations:0,averageOperationTimeout:this.metrics.successfulSerializations>0?this.metrics.totalOperationTimeout/this.metrics.successfulSerializations:0,maxSerializationDuration:this.metrics.maxSerializationDuration,minSerializationDuration:this.metrics.minSerializationDuration,complexityDistribution:{...this.metrics.complexityDistribution},serializerDistribution:{...this.metrics.serializerDistribution},timeoutStrategyDistribution:{...this.metrics.timeoutStrategyDistribution}}}resetMetrics(){this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}}}getRegisteredSerializers(){return this.serializationStep.getRegisteredSerializers()}getPipelineMetrics(){return this.pipeline.getMetrics()}}class q extends f{constructor(e){super(e)}log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,r=JSON.stringify(t);switch(e.level){case"fatal":case"error":console.error(r);break;case"warn":console.warn(r);break;default:console.log(r)}}}class Y{constructor(e){this.ansiRegex=/[\x1b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,this.maskingEngine=e}async process(e){let t=this.sanitizeRecursively(e);return this.maskingEngine&&(t=this.maskingEngine.process(t)),t}sanitizeRecursively(e){if("string"==typeof e)return e.replace(this.ansiRegex,"");if(Array.isArray(e))return e.map(e=>this.sanitizeRecursively(e));if("object"==typeof e&&null!==e&&e.constructor===Object){const t={},r=e;for(const e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=this.sanitizeRecursively(r[e]));return t}return e}}function J(e,t){const r=[];for(const i of e)if(i instanceof f)r.push(i);else if(i&&"object"==typeof i&&"transport"in i){const e=null==i.env?null:Array.isArray(i.env)?i.env:[i.env];(null===e||e.includes(t))&&r.push(i.transport)}else i&&"object"==typeof i&&r.push(i);return r}class Z{constructor(e,t,r){this.loggerPool=new Map,this.MAX_POOL_SIZE=1e3,this.contextManager=t,this.syntropyLogInstance=r,e.context&&this.contextManager.configure(e.context);const i=(e=>{const t=e.logger?.environment??"development",r=e.logger?.transportList&&Object.keys(e.logger.transportList).length>0,i=e.logger?.env&&Object.keys(e.logger.env).length>0;if(r&&i&&e.logger?.transportList&&e.logger?.env){const r=new Map(Object.entries(e.logger.transportList));return{transports:{default:(e.logger.env[t]??[]).map(e=>r.get(e)).filter(e=>null!=e)},transportPool:r}}if(e.logger?.transports){const r=e.logger.transports,i=new Map,s=e=>{const t=e instanceof f?e:e&&"object"==typeof e&&"transport"in e?e.transport:e,r=t.name??t.constructor?.name??`transport-${i.size}`;return i.set(r,t),t};let n;if(Array.isArray(r))r.forEach(s),n={default:J(r,t)};else{const e=r;n={};for(const[r,i]of Object.entries(e))i.forEach(s),n[r]=J(i,t)}return{transports:n,transportPool:i}}{const e=new Y,t=new q({sanitizationEngine:e,name:"console"});return{transports:{default:[t]},transportPool:new Map([["console",t]])}}})(e);this.transports=i.transports,this.transportPool=i.transportPool,this.globalLogLevel=e.logger?.level??"info",this.serviceName=e.logger?.serviceName??"unknown-service",this.serializationManager=new V({timeoutMs:e.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==e.masking?.enableDefaultRules}),this.maskingEngine=new S({rules:e.masking?.rules,maskChar:e.masking?.maskChar,preserveLength:e.masking?.preserveLength,enableDefaultRules:!1!==e.masking?.enableDefaultRules,regexTimeoutMs:e.masking?.regexTimeoutMs})}getLogger(e="default",t){const r=((e,t)=>{if(!t||0===Object.keys(t).length)return e;const r=Object.keys(t).sort().reduce((e,r)=>(e[r]=t[r],e),{});try{return`${e}:${JSON.stringify(r)}`}catch{return`${e}:${Object.keys(r).sort().join(",")}`}})(e,t);if(this.loggerPool.has(r)){const e=this.loggerPool.get(r);return this.loggerPool.delete(r),this.loggerPool.set(r,e),e}const i="default"===e?this.serviceName:e,s={contextManager:this.contextManager,serializationManager:this.serializationManager,maskingEngine:this.maskingEngine,syntropyLogInstance:this.syntropyLogInstance,transportPool:this.transportPool},n=this.transports[e]??this.transports.default,a=new R(i,n,s,{bindings:t});if(a.level=this.globalLogLevel,this.loggerPool.size>=this.MAX_POOL_SIZE){const e=this.loggerPool.keys().next().value;void 0!==e&&this.loggerPool.delete(e)}return this.loggerPool.set(r,a),a}async flushAllTransports(){const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>e.flush().catch(t=>{console.error(`Error flushing transport ${e.constructor.name}:`,t)}));await Promise.allSettled(t)}async shutdown(){try{await this.flushAllTransports(),this.loggerPool.clear();const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>"function"==typeof e.shutdown?e.shutdown().catch(t=>{console.error(`Error shutting down transport ${e.constructor.name}:`,t)}):Promise.resolve());await Promise.allSettled(t)}catch(e){console.error("Error during LoggerFactory shutdown:",e)}}}const X="[CONFIG_MASKED]",B=["password","token","secret","apikey","credential","pass","key","accesstoken","refreshtoken","clientsecret","sentinelpassword","sasl"];function Q(e){if(e instanceof f)return e;if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(e=>Q(e));const t={},r=B.map(e=>e.toLowerCase());for(const i in e)if(Object.prototype.hasOwnProperty.call(e,i)){const s=i.toLowerCase(),n=e[i];r.includes(s)?t[i]=X:(s.includes("url")||s.includes("uri"))&&"string"==typeof n?t[i]=n.replace(/(?<=:\/\/)[^:]+:[^@]+@/,`${X}@`):"object"!=typeof n||null===n||n instanceof RegExp?t[i]=n:t[i]=Q(n)}return t}function ee(e){return e instanceof Error?{name:e.name,message:e.message,stack:e.stack||null}:String(e)}class te extends e.EventEmitter{constructor(e){super(),this.state="NOT_INITIALIZED",this.logger=null,this.trackedProcesses=new Set,this.syntropyFacade=e,this.config={},this.serializationManager=new V({}),this.maskingEngine=new S({})}getState(){return this.state}async init(e){if("NOT_INITIALIZED"===this.state){this.state="INITIALIZING";try{const t=Q(function(e){const t=E(e);if(!t.ok)throw new b(t.errors);return t.value}(e));this.config=t,this.contextManager=new I(this.config.loggingMatrix),this.config.context&&this.contextManager.configure(this.config.context),this.serializationManager=new V({timeoutMs:this.config.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==this.config.masking?.enableDefaultRules}),this.maskingEngine=new S({rules:this.config.masking?.rules,maskChar:this.config.masking?.maskChar,preserveLength:this.config.masking?.preserveLength,enableDefaultRules:!1!==this.config.masking?.enableDefaultRules,regexTimeoutMs:this.config.masking?.regexTimeoutMs}),this.loggerFactory=new Z(this.config,this.contextManager,this.syntropyFacade);const r=this.loggerFactory.getLogger("syntropylog-main");this.logger=r,r.info("SyntropyLog framework initialized successfully."),this.state="READY",this.emit("ready")}catch(e){throw this.state="ERROR",this.emit("error",e),e instanceof b?console.error("[SyntropyLog] Configuration validation failed:",e.issues):console.error("[SyntropyLog] Failed to initialize framework:",e),e}}else this.logger?.warn(`LifecycleManager.init() called while in state '${this.state}'. Ignoring subsequent call.`)}async shutdown(){if(this.logger?.info(`๐Ÿ”„ LifecycleManager.shutdown() called. Current state: ${this.state}`),"READY"===this.state){this.state="SHUTTING_DOWN",this.emit("shutting_down"),this.logger?.info("๐Ÿ”„ State changed to SHUTTING_DOWN");try{this.logger?.info("Shutting down SyntropyLog framework..."),this.maskingEngine?.shutdown?.();const e=[];e.push(this.terminateExternalProcesses()),this.logger?.info(`๐Ÿ“‹ Executing ${e.length} shutdown steps...`),await Promise.allSettled(e),await(this.logger?.info("โœ… Shutdown steps completed")),await(this.logger?.info("All managers have been shut down.")),await(this.logger?.info("โœ… State changed to SHUTDOWN")),await(this.loggerFactory?.shutdown?.()),"SHUTTING_DOWN"===this.state&&this.emit("transports_drained"),this.state="SHUTDOWN",this.emit("shutdown")}catch(e){this.state="ERROR",this.emit("error",e),this.logger?.error("โŒ Error during shutdown:",{error:ee(e)}),await(this.loggerFactory?.shutdown?.()),"ERROR"===this.state&&this.emit("transports_drained")}}else this.logger?.warn(`โŒ Cannot perform shutdown. Current state: ${this.state}`)}registerChildProcess(e){this.trackedProcesses.add(e),e.on("exit",()=>{this.trackedProcesses.delete(e)})}async terminateExternalProcesses(){try{if(0===this.trackedProcesses.size)return void this.logger?.info("No tracked external processes to terminate");this.logger?.info(`Terminating ${this.trackedProcesses.size} external processes...`);const e=Array.from(this.trackedProcesses).map(e=>(async(e,t)=>{if(!e.connected&&null!==e.exitCode)return;const r=e.pid;t?.debug(`Sending SIGTERM to process ${r}...`),e.kill("SIGTERM");const i=new Promise(t=>{const r=()=>{t(),e.removeListener("exit",r)};e.on("exit",r)}),s=new Promise(e=>setTimeout(e,5e3));await Promise.race([i,s]),null===e.exitCode?(t?.warn(`Process ${r} did not exit after SIGTERM, sending SIGKILL...`),e.kill("SIGKILL")):t?.debug(`Process ${r} exited gracefully`)})(e,this.logger));await Promise.allSettled(e),this.trackedProcesses.clear(),this.logger?.info("โœ… All external processes terminated")}catch(e){this.logger?.warn("Error terminating external processes:",{error:ee(e)})}}ensureReady(){if("READY"!==this.state)throw new Error(`SyntropyLog is not ready. Current state: '${this.state}'. Ensure init() has completed successfully by listening for the 'ready' event.`)}}function re(e,t){if(null==e)throw new Error(t)}class ie extends e.EventEmitter{constructor(){super(),this.lifecycleManager=new te(this),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("transports_drained",()=>this.emit("transports_drained")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}static getInstance(){return ie.instance||(ie.instance=new ie),ie.instance}static resetInstance(){ie.instance=void 0}getState(){return this.lifecycleManager.getState()}async init(e){return this.lifecycleManager.init(e)}async shutdown(){return this.lifecycleManager.shutdown()}getLogger(e="default",t){return re(this.lifecycleManager.loggerFactory,"Logger Factory not available."),this.lifecycleManager.loggerFactory.getLogger(e,t)}getContextManager(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager}getConfig(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.config}getFilteredContext(e){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.getFilteredContext(e)}reconfigureLoggingMatrix(e){this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.reconfigureLoggingMatrix(e)}getMasker(){return re(this.lifecycleManager.maskingEngine,"MaskingEngine not available."),this.lifecycleManager.maskingEngine}getSerializer(){return re(this.lifecycleManager.serializationManager,"SerializationManager not available."),this.lifecycleManager.serializationManager}_resetForTesting(){this.lifecycleManager.removeAllListeners(),Object.assign(this,{lifecycleManager:new te(this)}),this.removeAllListeners(),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}}const se=ie.getInstance();function ne(e){const t=t=>function(e,t){return 0===t.length?e:`[${t.join(";")}m${e}`}(t,e),r=t=>ne([...e,t]);return Object.defineProperty(t,"white",{get:()=>r(37),enumerable:!0}),Object.defineProperty(t,"bold",{get:()=>r(1),enumerable:!0}),Object.defineProperty(t,"red",{get:()=>r(31),enumerable:!0}),Object.defineProperty(t,"bgRed",{get:()=>r(41),enumerable:!0}),Object.defineProperty(t,"yellow",{get:()=>r(33),enumerable:!0}),Object.defineProperty(t,"cyan",{get:()=>r(36),enumerable:!0}),Object.defineProperty(t,"green",{get:()=>r(32),enumerable:!0}),Object.defineProperty(t,"gray",{get:()=>r(90),enumerable:!0}),Object.defineProperty(t,"magenta",{get:()=>r(35),enumerable:!0}),Object.defineProperty(t,"blue",{get:()=>r(34),enumerable:!0}),Object.defineProperty(t,"bgWhite",{get:()=>r(47),enumerable:!0}),Object.defineProperty(t,"dim",{get:()=>r(2),enumerable:!0}),t}let ae=null;function oe(){if(null!==ae)return ae;const e=void 0!==process.env.NO_COLOR&&""!==process.env.NO_COLOR&&"0"!==process.env.NO_COLOR,t="boolean"==typeof process.stdout?.isTTY&&process.stdout.isTTY;if(e||!t){const e=e=>e;e.white=e,e.bold=e,e.red=e,e.bgRed=e,e.yellow=e,e.cyan=e,e.green=e,e.gray=e,e.magenta=e,e.blue=e,e.bgWhite=e,e.dim=e,ae=e}else ae=ne([]);return ae}class le extends f{constructor(e){super(e),this.chalk=oe()}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,r=this.formatLogString(t);this.getConsoleMethod(t.level)(r)}getConsoleMethod(e){switch(e){case"fatal":case"error":return console.error;case"warn":return console.warn;default:return console.log}}}exports.AdapterTransport=class extends f{constructor(e){if(!e.adapter)throw new Error("AdapterTransport requires a valid adapter implementation.");super(e),this.adapter=e.adapter}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e;await this.adapter.log(t)}async flush(){"function"==typeof this.adapter.flush&&await this.adapter.flush()}async shutdown(){"function"==typeof this.adapter.shutdown&&await this.adapter.shutdown()}},exports.ClassicConsoleTransport=class extends le{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatTimestamp(e){const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}:${String(t.getSeconds()).padStart(2,"0")}`}formatLogString(e){const{timestamp:t,level:r,service:i,message:s,context:n,...a}=e,o=this.levelColorMap[r]||this.chalk.white,l=this.formatTimestamp(t),c=o(r.toUpperCase().padEnd(5)),u=this.chalk.magenta(`[${i}]`),g={...n||{},...a,message:s},h=Object.keys(g);let d="";h.length>0&&(d=this.chalk.dim(" ["+h.map(e=>`${e}=${JSON.stringify(g[e])}`).join(" ")+"]"));return`${l} ${c} ${u}${d}`}},exports.ColorfulConsoleTransport=class extends le{constructor(e){var t;super(e),this.levelStyleMap={trace:{level:(t=this.chalk).gray.bold,message:t.gray,metaKey:t.gray.dim,metaValue:t.gray},debug:{level:t.cyan.bold,message:t.cyan,metaKey:t.cyan.dim,metaValue:t.cyan},info:{level:t.green.bold,message:t.green,metaKey:t.green.dim,metaValue:t.green},warn:{level:t.yellow.bold,message:t.yellow,metaKey:t.yellow.dim,metaValue:t.yellow},error:{level:t.red.bold,message:t.red,metaKey:t.red.dim,metaValue:t.red},fatal:{level:t.red.bgWhite.bold,message:t.red.bold,metaKey:t.red.dim,metaValue:t.red},audit:{level:t.magenta.bold,message:t.magenta,metaKey:t.magenta.dim,metaValue:t.magenta}}}formatLogString(e){return((e,t,r)=>{const{timestamp:i,level:s,service:n,message:a,...o}=e,l=r[s]??{level:t.white.bold,message:t.white,metaKey:t.gray,metaValue:t.white},c=l.metaKey(new Date(i).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})),u=s.toUpperCase().padEnd(8),g=l.level(u),h=n?l.metaValue(`(${n})`):"";let d=`${c} ${g}`;h&&(d+=` ${h}`),d+=` ${l.message(a??"")}`;const m=Object.keys(o);if(m.length>0){const e=m.map(e=>{const t=o[e],r="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${l.metaKey(e)}=${l.metaValue(r)}`});d+=`\n ${t.dim("โ””โ”€")} ${e.join(" ")}`}return d})(e,this.chalk,this.levelStyleMap)}},exports.CompactConsoleTransport=class extends le{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatLogString(e){const{timestamp:t,level:r,service:i,message:s,...n}=e,a=this.levelColorMap[r]||this.chalk.white;let o=`${this.chalk.gray(new Date(t).toLocaleTimeString())} ${a(`[${r.toUpperCase()}]`)} ${this.chalk.blue(`(${i})`)}: ${s||""}`;const l=Object.keys(n);if(l.length>0){const e=l.map(e=>{const t=n[e],r="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${this.chalk.dim(e)}=${this.chalk.gray(r)}`}).join(" ");o+=`\n ${this.chalk.dim("โ””โ”€")} ${e}`}return o}},exports.ConsoleTransport=q,exports.PrettyConsoleTransport=class extends le{constructor(e){var t;super(e),this.levelColorMap={fatal:(t=this.chalk).bgRed.white.bold,error:t.red.bold,warn:t.yellow.bold,info:t.blue.bold,audit:t.white.bold,debug:t.green,trace:t.gray}}formatLogString(e){return((e,t,r)=>{const{timestamp:i,level:s,service:n,message:a,...o}=e,l=r[s]||t.white;let c=`${t.gray(new Date(i).toLocaleTimeString())} ${l(`[${s.toUpperCase()}]`)} ${t.cyan(`(${n})`)}: ${a||""}`;Object.keys(o).length>0&&(c+=`\n${t.gray(JSON.stringify(o,null,2))}`);return c})(e,this.chalk,this.levelColorMap)}},exports.SanitizationEngine=Y,exports.SerializationManager=V,exports.SpyTransport=class extends f{constructor(e){super(e),this.entries=[]}async log(e){this.entries.push(e)}getEntries(){return[...this.entries]}findEntries(e){return"function"==typeof e?this.entries.filter(e):this.entries.filter(t=>Object.keys(e).every(r=>{const i=r;return e[i]===t[i]}))}clear(){this.entries=[]}getFirstEntry(){return this.entries[0]}getLastEntry(){return this.entries[this.entries.length-1]}},exports.SyntropyLog=ie,exports.Transport=f,exports.UniversalAdapter=class{constructor(e){if("function"!=typeof e.executor)throw new Error("UniversalAdapter requires an executor function.");this.executor=e.executor}async log(e){try{await this.executor(e)}catch(e){console.error(`UniversalAdapter execution failed: ${e instanceof Error?e.message:String(e)}`)}}},exports.UniversalLogFormatter=class{constructor(e){this.mapping=e.mapping,this.includeAllIn=e.includeAllIn}format(e){const t={};for(const[r,i]of Object.entries(this.mapping))t[r]=this.resolveValue(i,e);if(this.includeAllIn){const r=e.bindings??{},i=e.metadata??{};t[this.includeAllIn]={..."object"==typeof r&&null!==r?r:{},..."object"==typeof i&&null!==i?i:{}}}return t}resolveValue(e,t){if("object"==typeof e&&!Array.isArray(e)&&"value"in e){const t=e;return t.value??t.fallback}const r=Array.isArray(e)?e:[e];for(const e of r){if("object"==typeof e&&null!==e&&"value"in e){const t=e;return t.value??t.fallback}if("string"==typeof e){const r=this.getValueByPath(e,t);if(null!=r)return r}}}getValueByPath(e,t){if("message"===e)return t.message;if("level"===e)return t.level;if("timestamp"===e)return t.timestamp;const r=e.split(".");let i=t;for(const e of r){if(null===i||"object"!=typeof i)return;if(i===t&&!Object.prototype.hasOwnProperty.call(t,e)){const r=t,s=r.bindings?.[e];if(void 0!==s){i=s;continue}const n=r.metadata?.[e];if(void 0!==n){i=n;continue}}i=i[e]}return i}},exports.syntropyLog=se;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as v from 'valibot';
2
1
  import { EventEmitter } from 'events';
3
2
 
4
3
  /**
@@ -58,7 +57,7 @@ type ContextData = Record<string, ContextValue>;
58
57
  /**
59
58
  * Type for context configuration options
60
59
  */
61
- type ContextConfig = {
60
+ type ContextConfig$1 = {
62
61
  correlationIdHeader?: string;
63
62
  transactionIdHeader?: string;
64
63
  [key: string]: ContextValue;
@@ -247,7 +246,7 @@ type LogLevel = keyof typeof LOG_LEVEL_WEIGHTS;
247
246
 
248
247
  type SerializableData = unknown;
249
248
 
250
- type LoggerOptions = {
249
+ type LoggerOptions$1 = {
251
250
  level?: LogLevel;
252
251
  serviceName?: string;
253
252
  transports?: unknown[];
@@ -583,131 +582,59 @@ declare abstract class Transport {
583
582
  }
584
583
 
585
584
  /**
586
- * FILE: src/config.schema.ts
587
- * DESCRIPTION: Defines the Zod validation schemas for the entire library's configuration.
588
- * These schemas are the single source of truth for the configuration's structure and types.
585
+ * @file src/config.schema.ts
586
+ * @description Defines and exports the configuration types for the entire library.
587
+ * These are pure TypeScript interfaces โ€” no runtime dependencies.
588
+ * Runtime validation is done by `src/config/config.validator.ts`.
589
589
  */
590
590
 
591
- /**
592
- * @description The main schema for the entire SyntropyLog configuration.
593
- * This is the single source of truth for validating the user's configuration object.
594
- */
595
- declare const syntropyLogConfigSchema: v.ObjectSchema<{
596
- /** Logger-specific configuration. */
597
- readonly logger: v.OptionalSchema<v.ObjectSchema<{
598
- readonly name: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
599
- readonly level: v.OptionalSchema<v.PicklistSchema<["audit", "fatal", "error", "warn", "info", "debug", "trace", "silent"], undefined>, undefined>;
600
- readonly serviceName: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
601
- /**
602
- * The explicit environment name used to resolve conditional transports (e.g. 'development', 'production').
603
- * @default 'development'
604
- */
605
- readonly environment: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
606
- /**
607
- * Pool of transports by name. Use together with `env` to pick per-environment defaults.
608
- * When both transportList and env are set, this form is used instead of `transports`.
609
- */
610
- readonly transportList: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>, undefined>, undefined>;
611
- /**
612
- * Per-environment list of transport names (keys from transportList) to use as default.
613
- * E.g. { development: ['consola'], production: ['consola', 'db'] }.
614
- * Used only when transportList is also set.
615
- */
616
- readonly env: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>, undefined>;
617
- /**
618
- * Legacy: array of transport instances or descriptors { transport, env? },
619
- * or a mapping of logger names (categories) to such arrays.
620
- * Ignored when both transportList and env are set.
621
- */
622
- readonly transports: v.OptionalSchema<v.UnionSchema<[v.ArraySchema<v.UnionSchema<[v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>, v.ObjectSchema<{
623
- readonly transport: v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>;
624
- /** When set, the transport is only enabled when the environment (e.g. NODE_ENV) is in this list. */
625
- readonly env: v.OptionalSchema<v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>], undefined>, undefined>;
626
- }, undefined>], undefined>, undefined>, v.RecordSchema<v.StringSchema<undefined>, v.ArraySchema<v.UnionSchema<[v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>, v.ObjectSchema<{
627
- readonly transport: v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>;
628
- /** When set, the transport is only enabled when the environment (e.g. NODE_ENV) is in this list. */
629
- readonly env: v.OptionalSchema<v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>], undefined>, undefined>;
630
- }, undefined>], undefined>, undefined>, undefined>], undefined>, undefined>;
631
- /**
632
- * The maximum time in milliseconds a custom serializer can run before being timed out.
633
- * @default 50
634
- */
635
- readonly serializerTimeoutMs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, 50>;
636
- /** Configuration for pretty printing logs in development. */
637
- readonly prettyPrint: v.OptionalSchema<v.ObjectSchema<{
638
- readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
639
- }, undefined>, undefined>;
640
- }, undefined>, undefined>;
641
- /** Declarative matrix to control context data in logs. */
642
- readonly loggingMatrix: v.OptionalSchema<v.ObjectSchema<{
643
- /** An array of context keys to include in logs by default. Can be overridden by level-specific rules. */
644
- readonly default: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
645
- /** An array of context keys to include for 'trace' level logs. Use `['*']` to include all context properties. */
646
- readonly trace: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
647
- /** An array of context keys to include for 'debug' level logs. Use `['*']` to include all context properties. */
648
- readonly debug: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
649
- /** An array of context keys to include for 'info' level logs. Use `['*']` to include all context properties. */
650
- readonly info: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
651
- /** An array of context keys to include for 'warn' level logs. Use `['*']` to include all context properties. */
652
- readonly warn: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
653
- /** An array of context keys to include for 'error' level logs. Use `['*']` to include all context properties. */
654
- readonly error: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
655
- /** An array of context keys to include for 'fatal' level logs. Use `['*']` to include all context properties. */
656
- readonly fatal: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
657
- }, undefined>, undefined>;
658
- /** Centralized data masking configuration. */
659
- readonly masking: v.OptionalSchema<v.ObjectSchema<{
660
- /** Array of masking rules with patterns and strategies. */
661
- readonly rules: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
662
- /** Regex pattern to match field names */
663
- readonly pattern: v.UnionSchema<[v.StringSchema<undefined>, v.InstanceSchema<RegExpConstructor, undefined>], undefined>;
664
- /** Masking strategy to apply */
665
- readonly strategy: v.EnumSchema<typeof MaskingStrategy, undefined>;
666
- /** Whether to preserve original length */
667
- readonly preserveLength: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
668
- /** Character to use for masking */
669
- readonly maskChar: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
670
- /** Custom masking function (for CUSTOM strategy) */
671
- readonly customMask: v.OptionalSchema<v.CustomSchema<(val: string) => string, v.ErrorMessage<v.CustomIssue> | undefined>, undefined>;
672
- }, undefined>, undefined>, undefined>;
673
- /** Default mask character */
674
- readonly maskChar: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
675
- /** Whether to preserve original length by default */
676
- readonly preserveLength: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
677
- /** Enable default rules for common data types */
678
- readonly enableDefaultRules: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
679
- /**
680
- * Max ms for evaluating each custom rule regex; if exceeded, no match and a warning is logged.
681
- * @default 100
682
- */
683
- readonly regexTimeoutMs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, 100>;
684
- }, undefined>, undefined>;
685
- /** Context propagation configuration. */
686
- readonly context: v.OptionalSchema<v.ObjectSchema<{
687
- /** The HTTP header name to use for the correlation ID. @default 'x-correlation-id' */
688
- readonly correlationIdHeader: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
689
- /** The HTTP header name to use for the external transaction/trace ID. @default 'x-trace-id' */
690
- readonly transactionIdHeader: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
691
- }, undefined>, undefined>;
692
- /**
693
- * The maximum time in milliseconds to wait for a graceful shutdown before timing out.
694
- * @default 5000
695
- */
696
- readonly shutdownTimeout: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "The maximum time in ms to wait for a graceful shutdown.">]>, undefined>;
697
- }, undefined>;
698
-
699
- /**
700
- * @file src/config.ts
701
- * @description Defines and exports the configuration types for the library.
702
- * These types are now explicitly defined for better TypeScript intellisense and autocompletion,
703
- * while still using Zod schemas for runtime validation.
704
- */
705
-
706
- /**
707
- * @description The complete, top-level configuration type for the SyntropyLog framework.
708
- * This type is inferred from the main Zod schema and represents the entire valid configuration object.
709
- */
710
- type SyntropyLogConfig = v.InferInput<typeof syntropyLogConfigSchema>;
591
+ interface TransportDescriptor {
592
+ transport: Transport;
593
+ env?: string | string[];
594
+ }
595
+ type TransportEntry = Transport | TransportDescriptor;
596
+ interface LoggerOptions {
597
+ name?: string;
598
+ level?: 'audit' | 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent';
599
+ serviceName?: string;
600
+ environment?: string;
601
+ transportList?: Record<string, Transport>;
602
+ env?: Record<string, string[]>;
603
+ transports?: TransportEntry[] | Record<string, TransportEntry[]>;
604
+ serializerTimeoutMs?: number;
605
+ prettyPrint?: {
606
+ enabled?: boolean;
607
+ };
608
+ }
609
+ interface MaskingConfig {
610
+ rules?: MaskingRule[];
611
+ maskChar?: string;
612
+ preserveLength?: boolean;
613
+ enableDefaultRules?: boolean;
614
+ regexTimeoutMs?: number;
615
+ }
616
+ interface LoggingMatrixConfig {
617
+ default?: string[];
618
+ trace?: string[];
619
+ debug?: string[];
620
+ info?: string[];
621
+ warn?: string[];
622
+ error?: string[];
623
+ fatal?: string[];
624
+ [key: string]: string[] | undefined;
625
+ }
626
+ interface ContextConfig {
627
+ correlationIdHeader?: string;
628
+ transactionIdHeader?: string;
629
+ [key: string]: string | undefined;
630
+ }
631
+ interface SyntropyLogConfig {
632
+ logger?: LoggerOptions;
633
+ loggingMatrix?: LoggingMatrixConfig;
634
+ masking?: MaskingConfig;
635
+ context?: ContextConfig;
636
+ shutdownTimeout?: number;
637
+ }
711
638
 
712
639
  /**
713
640
  * Defines the public interface for a logger instance.
@@ -819,7 +746,7 @@ interface IContextManager {
819
746
  * @param options.correlationIdHeader The custom header name to use for the correlation ID.
820
747
  * @param options.transactionIdHeader The custom header name for the transaction ID.
821
748
  */
822
- configure(options: ContextConfig): void;
749
+ configure(options: ContextConfig$1): void;
823
750
  /**
824
751
  * Executes a function within a new, isolated asynchronous context.
825
752
  * The new context can inherit data from the parent context.
@@ -1227,4 +1154,4 @@ declare class SyntropyLog extends EventEmitter {
1227
1154
  declare const syntropyLog: SyntropyLog;
1228
1155
 
1229
1156
  export { ClassicConsoleTransport, CompactConsoleTransport, ConsoleTransport, MaskingEngine, PrettyConsoleTransport, SanitizationEngine, SpyTransport, SyntropyLog, Transport, errorToJsonValue, syntropyLog };
1230
- export type { ComplexityDistribution, ContextCallback, ContextConfig, ContextData, ContextHeaders, ContextValue, FilteredContext, IContextManager, ILogger, JsonValue, LogArguments, LogBindings, LogContext, LogEntry, LogFormatArg, LogFormatter, LogLevel, LogMetadata, LogRetentionRules, LoggerDependencies, LoggerOptions, LoggingMatrix, MetadataObject, PipelineContext, SanitizationConfig, SanitizationContext, SerializationContextConfig, SerializationMetadata, SerializationMetrics, SerializationPipelineContext, SerializationResult, SerializedData, SerializerDistribution, StepDurations, SyntropyLogConfig, TimeoutStrategyDistribution };
1157
+ export type { ComplexityDistribution, ContextCallback, ContextConfig$1 as ContextConfig, ContextData, ContextHeaders, ContextValue, FilteredContext, IContextManager, ILogger, JsonValue, LogArguments, LogBindings, LogContext, LogEntry, LogFormatArg, LogFormatter, LogLevel, LogMetadata, LogRetentionRules, LoggerDependencies, LoggerOptions$1 as LoggerOptions, LoggingMatrix, MetadataObject, PipelineContext, SanitizationConfig, SanitizationContext, SerializationContextConfig, SerializationMetadata, SerializationMetrics, SerializationPipelineContext, SerializationResult, SerializedData, SerializerDistribution, StepDurations, SyntropyLogConfig, TimeoutStrategyDistribution };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{EventEmitter as e}from"events";import*as t from"valibot";import{parse as i,ValiError as r}from"valibot";import{AsyncLocalStorage as s}from"node:async_hooks";import{randomUUID as n}from"crypto";import*as a from"node:util";const o={audit:70,fatal:60,error:50,warn:40,info:30,debug:20,trace:10,silent:0};class l{constructor(e={}){this.level=e.level??"info",this.name=e.name??this.constructor.name,this.formatter=e?.formatter,this.sanitizationEngine=e?.sanitizationEngine}isLevelEnabled(e){return o[e]>=o[this.level]}async flush(){return Promise.resolve()}}var c;!function(e){e.CREDIT_CARD="credit_card",e.SSN="ssn",e.EMAIL="email",e.PHONE="phone",e.PASSWORD="password",e.TOKEN="token",e.CUSTOM="custom"}(c||(c={}));class u{constructor(e){if(this.rules=[],this.initialized=!1,this.maskChar=e?.maskChar||"*",this.preserveLength=e?.preserveLength??!0,this.regexTimeoutMs=e?.regexTimeoutMs??100,!1!==e?.enableDefaultRules&&this.addDefaultRules(),e?.rules)for(const t of e.rules)this.addRule(t)}addDefaultRules(){const e=[{pattern:/credit_card|card_number|payment_number/i,strategy:c.CREDIT_CARD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/ssn|social_security|security_number/i,strategy:c.SSN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/email/i,strategy:c.EMAIL,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/phone|phone_number|mobile_number/i,strategy:c.PHONE,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/password|pass|pwd|secret/i,strategy:c.PASSWORD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/token|api_key|auth_token|jwt|bearer/i,strategy:c.TOKEN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0}];for(const t of e)this.addRule(t)}addRule(e){"string"==typeof e.pattern?e._compiledPattern=new RegExp(e.pattern,"i"):e._compiledPattern=e.pattern,e.preserveLength=e.preserveLength??this.preserveLength,e.maskChar=e.maskChar??this.maskChar,this.rules.push(e)}process(e){this.initialized||(this.initialized=!0);try{const t=new WeakSet;return this.applyMaskingRules(e,t)}catch{return{...u.buildSafeFallbackFromMeta(e),_maskingFailed:!0,_maskingFailedMessage:u.MASKING_FAILED_MESSAGE}}}static buildSafeFallbackFromMeta(e){const t={},i=["level","timestamp","message","service"];for(const r of i)r in e&&void 0!==e[r]&&(t[r]=e[r]);return t}applyMaskingRules(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return e;if(t.add(e),Array.isArray(e)){let i=!1;const r=new Array(e.length);for(let s=0;s<e.length;s++){const n=this.applyMaskingRules(e[s],t);r[s]=n,n!==e[s]&&(i=!0)}return i?r:e}const i=e;for(const e in i){if(!Object.prototype.hasOwnProperty.call(i,e))continue;const r=i[e];if("string"==typeof r)for(const t of this.rules){let s=!1;if(t._compiledPattern&&(s=t._isDefaultRule?t._compiledPattern.test(e):this.testRegexWithTimeout(t._compiledPattern,e)),s){i[e]=this.applyStrategy(r,t);break}}else if("object"==typeof r&&null!==r){const s=this.applyMaskingRules(r,t);s!==r&&(i[e]=s)}}return i}applyStrategy(e,t){if(t.strategy===c.CUSTOM&&t.customMask)return t.customMask(e);switch(t.strategy){case c.CREDIT_CARD:return this.maskCreditCard(e,t);case c.SSN:return this.maskSSN(e,t);case c.EMAIL:return this.maskEmail(e,t);case c.PHONE:return this.maskPhone(e,t);case c.PASSWORD:return this.maskPassword(e,t);case c.TOKEN:return this.maskToken(e,t);default:return this.maskDefault(e,t)}}maskCreditCard(e,t){const i=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(r,s)=>e.substring(0,s).replace(/\D/g,"").length<i.length-4?t.maskChar:r):`${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${i.slice(-4)}`}maskSSN(e,t){const i=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(r,s)=>e.substring(0,s).replace(/\D/g,"").length<i.length-4?t.maskChar:r):`***-**-${i.slice(-4)}`}maskEmail(e,t){const i=e.indexOf("@");if(i>0){const r=e.substring(0,i),s=e.substring(i);if(t.preserveLength){return(r.length>1?r.charAt(0)+t.maskChar.repeat(r.length-1):t.maskChar.repeat(r.length))+s}return`${r.charAt(0)}***${s}`}return this.maskDefault(e,t)}maskPhone(e,t){const i=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(r,s)=>e.substring(0,s).replace(/\D/g,"").length<i.length-4?t.maskChar:r):`${t.maskChar.repeat(3)}-${t.maskChar.repeat(3)}-${i.slice(-4)}`}maskPassword(e,t){return t.maskChar.repeat(e.length)}maskToken(e,t){return t.preserveLength?e.substring(0,4)+t.maskChar.repeat(e.length-9)+e.substring(e.length-5):e.length>8?e.substring(0,4)+"..."+e.substring(e.length-5):t.maskChar.repeat(e.length)}maskDefault(e,t){return t.preserveLength?t.maskChar.repeat(e.length):t.maskChar.repeat(Math.min(e.length,8))}getStats(){return{initialized:this.initialized,totalRules:this.rules.length,defaultRules:this.rules.filter(e=>[c.CREDIT_CARD,c.SSN,c.EMAIL,c.PHONE,c.PASSWORD,c.TOKEN].includes(e.strategy)).length,customRules:this.rules.filter(e=>e.strategy===c.CUSTOM).length,strategies:this.rules.map(e=>e.strategy)}}isInitialized(){return this.initialized}testRegexWithTimeout(e,t){if(t.length>256)return!1;try{return e.test(t)}catch{return!1}}shutdown(){this.rules=[],this.initialized=!1}}u.MASKING_FAILED_MESSAGE="[SyntropyLog] Masking could not be applied (e.g. timeout or error); payload redacted for safety.";const g=t.object({transport:t.custom(e=>e instanceof l,"Must be an instance of Transport"),env:t.optional(t.union([t.string(),t.array(t.string())]))}),h=t.union([t.custom(e=>e instanceof l,"Must be an instance of Transport"),g]),d=t.optional(t.object({name:t.optional(t.string()),level:t.optional(t.picklist(["audit","fatal","error","warn","info","debug","trace","silent"])),serviceName:t.optional(t.string()),environment:t.optional(t.string()),transportList:t.optional(t.record(t.string(),t.custom(e=>e instanceof l,"Must be an instance of Transport"))),env:t.optional(t.record(t.string(),t.array(t.string()))),transports:t.optional(t.union([t.array(h),t.record(t.string(),t.array(h))])),serializerTimeoutMs:t.optional(t.pipe(t.number(),t.integer(),t.minValue(1)),50),prettyPrint:t.optional(t.object({enabled:t.optional(t.boolean(),!1)}))})),m=t.optional(t.object({rules:t.optional(t.array(t.object({pattern:t.union([t.string(),t.instance(RegExp)]),strategy:t.enum(c),preserveLength:t.optional(t.boolean()),maskChar:t.optional(t.string()),customMask:t.optional(t.custom(e=>"function"==typeof e,"Must be a function"))}))),maskChar:t.optional(t.string()),preserveLength:t.optional(t.boolean()),enableDefaultRules:t.optional(t.boolean()),regexTimeoutMs:t.optional(t.pipe(t.number(),t.integer(),t.minValue(1)),100)})),p=t.optional(t.object({default:t.optional(t.array(t.string())),trace:t.optional(t.array(t.string())),debug:t.optional(t.array(t.string())),info:t.optional(t.array(t.string())),warn:t.optional(t.array(t.string())),error:t.optional(t.array(t.string())),fatal:t.optional(t.array(t.string()))})),f=t.object({logger:d,loggingMatrix:p,masking:m,context:t.optional(t.object({correlationIdHeader:t.optional(t.string()),transactionIdHeader:t.optional(t.string())})),shutdownTimeout:t.optional(t.pipe(t.number(),t.integer(),t.minValue(1),t.description("The maximum time in ms to wait for a graceful shutdown.")))}),y=Object.freeze({});class b{constructor(e){this.storage=new s,this.correlationIdHeader="x-correlation-id",this.transactionIdHeader="x-trace-id",this.storage=new s,this.loggingMatrix=e}configure(e){e.correlationIdHeader&&(this.correlationIdHeader=e.correlationIdHeader),e.transactionIdHeader&&(this.transactionIdHeader=e.transactionIdHeader)}reconfigureLoggingMatrix(e){this.loggingMatrix=e}run(e){return new Promise((t,i)=>{const r=this.storage.getStore(),s=new Map(r?.data);this.storage.run({data:s},async()=>{try{await Promise.resolve(e()),t()}catch(e){i(e)}})})}get(e){return this.storage.getStore()?.data.get(e)}getAll(){const e=this.storage.getStore();return e?Object.fromEntries(e.data.entries()):{}}set(e,t){const i=this.storage.getStore();i&&i.data.set(e,t)}getCorrelationId(){let e=this.get(this.correlationIdHeader)||this.get("correlationId");return e&&"string"==typeof e||(e=n(),this.set(this.correlationIdHeader,e)),e}setCorrelationId(e){this.set(this.correlationIdHeader,e)}getTransactionId(){return this.get("transactionId")}setTransactionId(e){this.set("transactionId",e)}getCorrelationIdHeaderName(){return this.correlationIdHeader}getTransactionIdHeaderName(){return this.transactionIdHeader}getTraceContextHeaders(){const e={};if(!this.storage.getStore())return e;const t=this.getCorrelationId(),i=this.getTransactionId();return t&&(e[this.getCorrelationIdHeaderName()]=t),i&&(e[this.getTransactionIdHeaderName()]=i),e}getFilteredContext(e){const t=this.getAll();if(!this.loggingMatrix){const e=Object.keys(t).length,i=this.get(this.correlationIdHeader),r=this.get("correlationId");if(0===e&&!i&&!r)return y;const s={};return Object.assign(s,t),!i&&r&&(s[this.correlationIdHeader]=r),s}const i=this.loggingMatrix[e]??this.loggingMatrix.default;if(!i)return y;const r={correlationId:[this.correlationIdHeader,"correlationId"],transactionId:[this.transactionIdHeader,"transactionId"],userId:["userId"],serviceName:["serviceName"],operation:["operation"],errorCode:["errorCode"],tenantId:["tenantId"],paymentId:["paymentId"],orderId:["orderId"],processorId:["processorId"],eventType:["eventType"]};if(i.includes("*")){const e={};for(const[i,s]of Object.entries(t)){let t=i;for(const[e,s]of Object.entries(r))if(s.includes(i)){t=e;break}e[t]=s}return e}const s={};for(const e of i){const i=r[e]||[e];for(const r of i)if(Object.prototype.hasOwnProperty.call(t,r)){s[e]=t[r];break}!Object.prototype.hasOwnProperty.call(s,e)&&Object.prototype.hasOwnProperty.call(t,e)&&(s[e]=t[e])}return s}}const S={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0};class w{constructor(e,t,i,r={}){this.pendingRouting=null,this.name=e,this.transports=t,this.dependencies=i,this.bindings=r.bindings??{},this.level=r.level??"info"}override(...e){return this.pendingRouting={override:e},this}add(...e){const t=this.pendingRouting,i=[...t&&"add"in t?t.add??[]:[],...e],r=t&&"remove"in t?t.remove??[]:void 0;return this.pendingRouting=r?.length?{add:i,remove:r}:{add:i},this}remove(...e){const t=this.pendingRouting,i=[...t&&"remove"in t?t.remove??[]:[],...e],r=t&&"add"in t?t.add??[]:void 0;return this.pendingRouting=r?.length?{add:r,remove:i}:{remove:i},this}captureEffectiveTransports(){const e=this.pendingRouting;return this.pendingRouting=null,function(e,t,i){if(!t||!i)return e;if("override"in i)return i.override.map(e=>t.get(e)).filter(e=>null!=e);let r=[...e];if(i.add?.length)for(const e of i.add){const i=t.get(e);i&&r.push(i)}if(i.remove?.length){const e=new Set(i.remove);r=r.filter(t=>!e.has(t.name))}return r}(this.transports,this.dependencies.transportPool,e)}async _log(e,...t){if("silent"===e)return;if(!function(e,t){return"silent"!==e&&("audit"===e||o[e]>=o[t])}(e,this.level))return;const i=this.captureEffectiveTransports();try{const{message:r,metadata:s}=function(e){let t,i={};if(0===e.length)t="";else if("object"!=typeof e[0]||null===e[0]||Array.isArray(e[0])){t=e[0]||"";const i=e.slice(1);t&&i.length>0&&(t=a.format(t,...i))}else{i=e[0],t=e[1]||"";const r=e.slice(2);t&&r.length>0&&(t=a.format(t,...r))}return{message:t||"",metadata:i}}(t),n=this.dependencies.contextManager.getFilteredContext(e),o={level:e,timestamp:(new Date).toISOString(),service:this.name,message:r};Object.assign(o,n,this.bindings,s);const l=this.dependencies.serializationManager.serialize(o,S).data,c=this.dependencies.maskingEngine.process(l);for(const t of i)t.isLevelEnabled(e)&&t.log(c)}catch{}}info(...e){return this._log("info",...e)}warn(...e){return this._log("warn",...e)}error(...e){return this._log("error",...e)}debug(...e){return this._log("debug",...e)}trace(...e){return this._log("trace",...e)}audit(...e){return this._log("audit",...e)}fatal(...e){return this._log("fatal",...e)}setLevel(e){this.level=e}child(e){return new w(this.name,this.transports,this.dependencies,{level:this.level,bindings:{...this.bindings,...e}})}withSource(e){return this.child({source:e})}withRetention(e){return this.child({retention:e})}withTransactionId(e){return this.child({transactionId:e})}}var k;!function(e){e.SIMPLE="simple",e.COMPLEX="complex",e.CRITICAL="critical"}(k||(k={}));class v{constructor(){this.defaultSensitiveFields=["password","token","secret","key","auth","authorization","api_key","apikey","private_key","privatekey","credential","credential_id","credentialid","access_token","accesstoken","refresh_token","refreshtoken","session_id","sessionid"],this.defaultMaxDepth=10}sanitize(e,t={}){const i=t.sensitiveFields||this.defaultSensitiveFields,r=t.maxDepth||this.defaultMaxDepth,s=t.currentDepth||0;if(s>=r)return"[MAX_DEPTH_REACHED]";if(null==e)return e;if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e)){const t={sensitiveFields:i,maxDepth:r,currentDepth:s+1};for(let i=0;i<e.length;i++){const r=this.sanitize(e[i],t);r!==e[i]&&(e[i]=r)}return e}if("object"==typeof e){const t=e;for(const e of Object.keys(t)){const n=e.toLowerCase();if(i.some(e=>n.includes(e.toLowerCase())))t[e]="[REDACTED]";else{const n=this.sanitize(t[e],{sensitiveFields:i,maxDepth:r,currentDepth:s+1});n!==t[e]&&(t[e]=n)}}return e}return e}}const z="pipeline",M="unknown";class D{constructor(){this.steps=[],this.timeoutStrategies=new Map,this.metrics=null,this.sanitizer=new v,this.initializeDefaultStrategies()}addStep(e){this.steps.push(e)}addTimeoutStrategy(e){this.timeoutStrategies.set(e.getStrategyName(),e)}process(e,t){const i=Date.now();this.metrics={stepDurations:{},totalDuration:0,operationTimeout:0,timeoutStrategy:M};let r=e;try{for(const e of this.steps){const i=Date.now();r=e.execute(r,t),this.metrics.stepDurations[e.name]=Date.now()-i}const e=this.selectTimeoutStrategy(r),s=e.calculateTimeout(r);return this.metrics.operationTimeout=s,this.metrics.timeoutStrategy=e.getStrategyName(),this.metrics.totalDuration=Date.now()-i,D.buildSuccessResult(r,t.sanitizeSensitiveData,this.metrics,s,e.getStrategyName())}catch(e){return this.metrics.totalDuration=Date.now()-i,D.buildErrorResult(r,e,this.metrics)}}getMetrics(){return this.metrics}static buildSuccessResult(e,t,i,r,s){const n=e,a=n.serializer??z,o=n.serializationComplexity??k.SIMPLE;return{success:!0,data:e,serializer:a,duration:i.totalDuration,complexity:o,sanitized:t,metadata:{stepDurations:i.stepDurations,operationTimeout:r,timeoutStrategy:s,serializer:a,complexity:o}}}static buildErrorResult(e,t,i){const r=t?.serializer??z;return{success:!1,data:e,serializer:r,duration:i.totalDuration,complexity:k.SIMPLE,sanitized:!1,error:t instanceof Error?t.message:String(t),metadata:{stepDurations:i.stepDurations,operationTimeout:0,timeoutStrategy:M,serializer:r,complexity:k.SIMPLE}}}selectTimeoutStrategy(e){const t=this.timeoutStrategies.get("default");if(null==t)throw new Error("SerializationPipeline: default timeout strategy is required");return t}initializeDefaultStrategies(){this.addTimeoutStrategy(new x)}}class x{calculateTimeout(e){return 5e3}getStrategyName(){return"default"}}class E{constructor(e=[]){this.name="serialization",this.serializers=[],this.serializers=e}addSerializer(e){const t=this.serializers.findIndex(t=>t.priority<e.priority);-1===t?this.serializers.push(e):this.serializers.splice(t,0,e)}execute(e,t){const i=Date.now(),r=this.findSerializer(e);if(!r)return e;try{const s=r.serialize(e,t.serializationContext),n=Date.now()-i,a="object"==typeof s.data&&null!==s.data?s.data:{};return a.serializationDuration=n,a.serializer=r.name,a.serializationComplexity=s.complexity||s.metadata?.complexity||null,a}catch(e){throw e instanceof Error&&!e.serializer&&(e.serializer=r.name),e}}findSerializer(e){for(const t of this.serializers)if(t.canSerialize(e))return t;return null}getRegisteredSerializers(){return this.serializers.map(e=>e.name)}}function C(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return"[Circular]";if(t.add(e),Array.isArray(e)){let i=!1;const r=new Array(e.length);for(let s=0;s<e.length;s++){const n=C(e[s],t);r[s]=n,n!==e[s]&&(i=!0)}return t.delete(e),i?r:e}for(const i in e)if(Object.prototype.hasOwnProperty.call(e,i)){const r=e[i],s=C(r,t);s!==r&&(e[i]=s)}return t.delete(e),e}class I{constructor(){this.name="hygiene"}execute(e,t){if(null===e||"object"!=typeof e)return e;try{if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack,...e};try{return JSON.stringify(e),e}catch{let t;try{t=C(e,new WeakSet)}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}return t}}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}}}function O(e,t,i,r){if("object"==typeof e&&null!==e){const s=e;return s.sanitizationDuration=t,s.sanitized=i,void 0!==r&&(s.sanitizationError=r),e}return{sanitizationDuration:t,sanitized:i,...void 0!==r&&{sanitizationError:r}}}class R{constructor(e){this.name="sanitization",this.sanitizer=e??new v}execute(e,t){const i=Date.now(),r=()=>Date.now()-i;if(!t.sanitizeSensitiveData)return O(e,r(),!1);try{return O(this.sanitizer.sanitize(e,t.sanitizationContext),r(),!0)}catch(t){return O(e,r(),!1,function(e){return e instanceof Error?e.message:String(e)}(t))}}}const L=3e3;class T{constructor(e){this.name="timeout",this.timeoutStrategies=new Map,this.timeoutStrategies=e}execute(e,t){const i=Date.now();try{const t=this.selectTimeoutStrategy(e),r=t?.calculateTimeout(e)??L;return function(e,t,i,r){if("object"==typeof e&&null!==e){const s=e;return s.timeoutDuration=t,s.operationTimeout=i,s.timeoutStrategy=r?.getStrategyName()??"default",s.timeoutApplied=null!=r,e}return{timeoutDuration:t,operationTimeout:i,timeoutStrategy:r?.getStrategyName()??"default",timeoutApplied:null!=r}}(e,Date.now()-i,r,t)}catch(t){return function(e,t,i){if("object"==typeof e&&null!==e){const r=e;return r.timeoutDuration=t,r.operationTimeout=L,r.timeoutStrategy="default",r.timeoutApplied=!1,r.timeoutError=i instanceof Error?i.message:"Timeout error",e}return{timeoutDuration:t,operationTimeout:L,timeoutStrategy:"default",timeoutApplied:!1,timeoutError:i instanceof Error?i.message:"Timeout error"}}(e,Date.now()-i,t)}}selectTimeoutStrategy(e){return this.timeoutStrategies.get("default")??null}}class P{constructor(e={}){this.config={timeoutMs:e.timeoutMs||5e3,enableMetrics:e.enableMetrics??!0,sanitizeSensitiveData:e.sanitizeSensitiveData??!0,sanitizationContext:{sensitiveFields:e.sanitizationContext?.sensitiveFields||["password","token","secret","key","auth","credential","api_key","private_key","connection_string","wallet_location"],redactPatterns:e.sanitizationContext?.redactPatterns||[/password\s*=\s*['"][^'"]*['"]/gi,/user\s*=\s*['"][^'"]*['"]/gi,/token\s*=\s*['"][^'"]*['"]/gi,/secret\s*=\s*['"][^'"]*['"]/gi],maxStringLength:e.sanitizationContext?.maxStringLength||300,enableDeepSanitization:e.sanitizationContext?.enableDeepSanitization??!0}},this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}},this.pipeline=new D,this.serializationStep=new E,this.hygieneStep=new I,this.sanitizationStep=new R,this.timeoutStep=new T(this.pipeline.timeoutStrategies),this.pipeline.addStep(this.serializationStep),this.pipeline.addStep(this.hygieneStep),this.pipeline.addStep(this.sanitizationStep),this.pipeline.addStep(this.timeoutStep)}register(e){this.serializationStep.addSerializer(e)}serialize(e,t={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0}){const i=Date.now(),r={serializationContext:t,sanitizeSensitiveData:this.config.sanitizeSensitiveData,sanitizationContext:this.config.sanitizationContext,enableMetrics:this.config.enableMetrics},s=this.pipeline.process(e,r);return this.config.enableMetrics&&this.updateMetrics(s,Date.now()-i),s}updateMetrics(e,t){if(this.metrics.totalSerializations++,e.success){this.metrics.successfulSerializations++;const t=(e.metadata.stepDurations?.serialization||0)+(e.metadata.stepDurations?.hygiene||0);this.metrics.totalSerializationDuration+=t,this.metrics.maxSerializationDuration=Math.max(this.metrics.maxSerializationDuration,t),this.metrics.minSerializationDuration=0===this.metrics.minSerializationDuration?t:Math.min(this.metrics.minSerializationDuration,t);const i=e.metadata.operationTimeout||0;this.metrics.totalOperationTimeout+=i;const r=e.complexity||k.SIMPLE;r===k.SIMPLE?this.metrics.complexityDistribution.low++:r===k.COMPLEX?this.metrics.complexityDistribution.medium++:r===k.CRITICAL&&this.metrics.complexityDistribution.high++;const s=e.serializer||"unknown";this.metrics.serializerDistribution[s]=(this.metrics.serializerDistribution[s]||0)+1;const n=e.metadata.timeoutStrategy||"unknown";this.metrics.timeoutStrategyDistribution[n]=(this.metrics.timeoutStrategyDistribution[n]||0)+1}else this.metrics.failedSerializations++}getMetrics(){return{totalSerializations:this.metrics.totalSerializations,successfulSerializations:this.metrics.successfulSerializations,failedSerializations:this.metrics.failedSerializations,averageSerializationDuration:this.metrics.totalSerializations>0?this.metrics.totalSerializationDuration/this.metrics.totalSerializations:0,averageOperationTimeout:this.metrics.successfulSerializations>0?this.metrics.totalOperationTimeout/this.metrics.successfulSerializations:0,maxSerializationDuration:this.metrics.maxSerializationDuration,minSerializationDuration:this.metrics.minSerializationDuration,complexityDistribution:{...this.metrics.complexityDistribution},serializerDistribution:{...this.metrics.serializerDistribution},timeoutStrategyDistribution:{...this.metrics.timeoutStrategyDistribution}}}resetMetrics(){this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}}}getRegisteredSerializers(){return this.serializationStep.getRegisteredSerializers()}getPipelineMetrics(){return this.pipeline.getMetrics()}}class j extends l{constructor(e){super(e)}log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,i=JSON.stringify(t);switch(e.level){case"fatal":case"error":console.error(i);break;case"warn":console.warn(i);break;default:console.log(i)}}}class A{constructor(e){this.ansiRegex=/[\x1b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,this.maskingEngine=e}async process(e){let t=this.sanitizeRecursively(e);return this.maskingEngine&&(t=this.maskingEngine.process(t)),t}sanitizeRecursively(e){if("string"==typeof e)return e.replace(this.ansiRegex,"");if(Array.isArray(e))return e.map(e=>this.sanitizeRecursively(e));if("object"==typeof e&&null!==e&&e.constructor===Object){const t={},i=e;for(const e in i)Object.prototype.hasOwnProperty.call(i,e)&&(t[e]=this.sanitizeRecursively(i[e]));return t}return e}}function _(e,t){const i=[];for(const r of e)if(r instanceof l)i.push(r);else if(r&&"object"==typeof r&&"transport"in r){const e=null==r.env?null:Array.isArray(r.env)?r.env:[r.env];(null===e||e.includes(t))&&i.push(r.transport)}else r&&"object"==typeof r&&i.push(r);return i}class ${constructor(e,t,i){this.loggerPool=new Map,this.MAX_POOL_SIZE=1e3,this.contextManager=t,this.syntropyLogInstance=i,e.context&&this.contextManager.configure(e.context);const r=(e=>{const t=e.logger?.environment??"development",i=e.logger?.transportList&&Object.keys(e.logger.transportList).length>0,r=e.logger?.env&&Object.keys(e.logger.env).length>0;if(i&&r&&e.logger?.transportList&&e.logger?.env){const i=new Map(Object.entries(e.logger.transportList));return{transports:{default:(e.logger.env[t]??[]).map(e=>i.get(e)).filter(e=>null!=e)},transportPool:i}}if(e.logger?.transports){const i=e.logger.transports,r=new Map,s=e=>{const t=e instanceof l?e:e&&"object"==typeof e&&"transport"in e?e.transport:e,i=t.name??t.constructor?.name??`transport-${r.size}`;return r.set(i,t),t};let n;if(Array.isArray(i))i.forEach(s),n={default:_(i,t)};else{const e=i;n={};for(const[i,r]of Object.entries(e))r.forEach(s),n[i]=_(r,t)}return{transports:n,transportPool:r}}{const e=new A,t=new j({sanitizationEngine:e,name:"console"});return{transports:{default:[t]},transportPool:new Map([["console",t]])}}})(e);this.transports=r.transports,this.transportPool=r.transportPool,this.globalLogLevel=e.logger?.level??"info",this.serviceName=e.logger?.serviceName??"unknown-service",this.serializationManager=new P({timeoutMs:e.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==e.masking?.enableDefaultRules}),this.maskingEngine=new u({rules:e.masking?.rules,maskChar:e.masking?.maskChar,preserveLength:e.masking?.preserveLength,enableDefaultRules:!1!==e.masking?.enableDefaultRules,regexTimeoutMs:e.masking?.regexTimeoutMs})}getLogger(e="default",t){const i=((e,t)=>{if(!t||0===Object.keys(t).length)return e;const i=Object.keys(t).sort().reduce((e,i)=>(e[i]=t[i],e),{});try{return`${e}:${JSON.stringify(i)}`}catch{return`${e}:${Object.keys(i).sort().join(",")}`}})(e,t);if(this.loggerPool.has(i)){const e=this.loggerPool.get(i);return this.loggerPool.delete(i),this.loggerPool.set(i,e),e}const r="default"===e?this.serviceName:e,s={contextManager:this.contextManager,serializationManager:this.serializationManager,maskingEngine:this.maskingEngine,syntropyLogInstance:this.syntropyLogInstance,transportPool:this.transportPool},n=this.transports[e]??this.transports.default,a=new w(r,n,s,{bindings:t});if(a.level=this.globalLogLevel,this.loggerPool.size>=this.MAX_POOL_SIZE){const e=this.loggerPool.keys().next().value;void 0!==e&&this.loggerPool.delete(e)}return this.loggerPool.set(i,a),a}async flushAllTransports(){const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>e.flush().catch(t=>{console.error(`Error flushing transport ${e.constructor.name}:`,t)}));await Promise.allSettled(t)}async shutdown(){try{await this.flushAllTransports(),this.loggerPool.clear();const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>"function"==typeof e.shutdown?e.shutdown().catch(t=>{console.error(`Error shutting down transport ${e.constructor.name}:`,t)}):Promise.resolve());await Promise.allSettled(t)}catch(e){console.error("Error during LoggerFactory shutdown:",e)}}}const N="[CONFIG_MASKED]",H=["password","token","secret","apikey","credential","pass","key","accesstoken","refreshtoken","clientsecret","sentinelpassword","sasl"];function F(e){if(e instanceof l)return e;if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(e=>F(e));const t={},i=H.map(e=>e.toLowerCase());for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r)){const s=r.toLowerCase(),n=e[r];i.includes(s)?t[r]=N:(s.includes("url")||s.includes("uri"))&&"string"==typeof n?t[r]=n.replace(/(?<=:\/\/)[^:]+:[^@]+@/,`${N}@`):"object"!=typeof n||null===n||n instanceof RegExp?t[r]=n:t[r]=F(n)}return t}function K(e){return e instanceof Error?{name:e.name,message:e.message,stack:e.stack||null}:String(e)}class G extends e{constructor(e){super(),this.state="NOT_INITIALIZED",this.logger=null,this.trackedProcesses=new Set,this.syntropyFacade=e,this.config={},this.serializationManager=new P({}),this.maskingEngine=new u({})}getState(){return this.state}async init(e){if("NOT_INITIALIZED"===this.state){this.state="INITIALIZING";try{const t=F(i(f,e));this.config=t,this.contextManager=new b(this.config.loggingMatrix),this.config.context&&this.contextManager.configure(this.config.context),this.serializationManager=new P({timeoutMs:this.config.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==this.config.masking?.enableDefaultRules}),this.maskingEngine=new u({rules:this.config.masking?.rules,maskChar:this.config.masking?.maskChar,preserveLength:this.config.masking?.preserveLength,enableDefaultRules:!1!==this.config.masking?.enableDefaultRules,regexTimeoutMs:this.config.masking?.regexTimeoutMs}),this.loggerFactory=new $(this.config,this.contextManager,this.syntropyFacade);const r=this.loggerFactory.getLogger("syntropylog-main");this.logger=r,r.info("SyntropyLog framework initialized successfully."),this.state="READY",this.emit("ready")}catch(e){throw this.state="ERROR",this.emit("error",e),e instanceof r?console.error("[SyntropyLog] Configuration validation failed:",e.issues):console.error("[SyntropyLog] Failed to initialize framework:",e),e}}else this.logger?.warn(`LifecycleManager.init() called while in state '${this.state}'. Ignoring subsequent call.`)}async shutdown(){if(this.logger?.info(`๐Ÿ”„ LifecycleManager.shutdown() called. Current state: ${this.state}`),"READY"===this.state){this.state="SHUTTING_DOWN",this.emit("shutting_down"),this.logger?.info("๐Ÿ”„ State changed to SHUTTING_DOWN");try{this.logger?.info("Shutting down SyntropyLog framework..."),this.maskingEngine?.shutdown?.();const e=[];e.push(this.terminateExternalProcesses()),this.logger?.info(`๐Ÿ“‹ Executing ${e.length} shutdown steps...`),await Promise.allSettled(e),await(this.logger?.info("โœ… Shutdown steps completed")),await(this.logger?.info("All managers have been shut down.")),await(this.logger?.info("โœ… State changed to SHUTDOWN")),await(this.loggerFactory?.shutdown?.()),"SHUTTING_DOWN"===this.state&&this.emit("transports_drained"),this.state="SHUTDOWN",this.emit("shutdown")}catch(e){this.state="ERROR",this.emit("error",e),this.logger?.error("โŒ Error during shutdown:",{error:K(e)}),await(this.loggerFactory?.shutdown?.()),"ERROR"===this.state&&this.emit("transports_drained")}}else this.logger?.warn(`โŒ Cannot perform shutdown. Current state: ${this.state}`)}registerChildProcess(e){this.trackedProcesses.add(e),e.on("exit",()=>{this.trackedProcesses.delete(e)})}async terminateExternalProcesses(){try{if(0===this.trackedProcesses.size)return void this.logger?.info("No tracked external processes to terminate");this.logger?.info(`Terminating ${this.trackedProcesses.size} external processes...`);const e=Array.from(this.trackedProcesses).map(e=>(async(e,t)=>{if(!e.connected&&null!==e.exitCode)return;const i=e.pid;t?.debug(`Sending SIGTERM to process ${i}...`),e.kill("SIGTERM");const r=new Promise(t=>{const i=()=>{t(),e.removeListener("exit",i)};e.on("exit",i)}),s=new Promise(e=>setTimeout(e,5e3));await Promise.race([r,s]),null===e.exitCode?(t?.warn(`Process ${i} did not exit after SIGTERM, sending SIGKILL...`),e.kill("SIGKILL")):t?.debug(`Process ${i} exited gracefully`)})(e,this.logger));await Promise.allSettled(e),this.trackedProcesses.clear(),this.logger?.info("โœ… All external processes terminated")}catch(e){this.logger?.warn("Error terminating external processes:",{error:K(e)})}}ensureReady(){if("READY"!==this.state)throw new Error(`SyntropyLog is not ready. Current state: '${this.state}'. Ensure init() has completed successfully by listening for the 'ready' event.`)}}function V(e,t){if(null==e)throw new Error(t)}class W extends e{constructor(){super(),this.lifecycleManager=new G(this),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("transports_drained",()=>this.emit("transports_drained")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}static getInstance(){return W.instance||(W.instance=new W),W.instance}static resetInstance(){W.instance=void 0}getState(){return this.lifecycleManager.getState()}async init(e){return this.lifecycleManager.init(e)}async shutdown(){return this.lifecycleManager.shutdown()}getLogger(e="default",t){return V(this.lifecycleManager.loggerFactory,"Logger Factory not available."),this.lifecycleManager.loggerFactory.getLogger(e,t)}getContextManager(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager}getConfig(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.config}getFilteredContext(e){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.getFilteredContext(e)}reconfigureLoggingMatrix(e){this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.reconfigureLoggingMatrix(e)}getMasker(){return V(this.lifecycleManager.maskingEngine,"MaskingEngine not available."),this.lifecycleManager.maskingEngine}getSerializer(){return V(this.lifecycleManager.serializationManager,"SerializationManager not available."),this.lifecycleManager.serializationManager}_resetForTesting(){this.lifecycleManager.removeAllListeners(),Object.assign(this,{lifecycleManager:new G(this)}),this.removeAllListeners(),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}}const U=W.getInstance();function Y(e){const t=t=>function(e,t){return 0===t.length?e:`[${t.join(";")}m${e}`}(t,e),i=t=>Y([...e,t]);return Object.defineProperty(t,"white",{get:()=>i(37),enumerable:!0}),Object.defineProperty(t,"bold",{get:()=>i(1),enumerable:!0}),Object.defineProperty(t,"red",{get:()=>i(31),enumerable:!0}),Object.defineProperty(t,"bgRed",{get:()=>i(41),enumerable:!0}),Object.defineProperty(t,"yellow",{get:()=>i(33),enumerable:!0}),Object.defineProperty(t,"cyan",{get:()=>i(36),enumerable:!0}),Object.defineProperty(t,"green",{get:()=>i(32),enumerable:!0}),Object.defineProperty(t,"gray",{get:()=>i(90),enumerable:!0}),Object.defineProperty(t,"magenta",{get:()=>i(35),enumerable:!0}),Object.defineProperty(t,"blue",{get:()=>i(34),enumerable:!0}),Object.defineProperty(t,"bgWhite",{get:()=>i(47),enumerable:!0}),Object.defineProperty(t,"dim",{get:()=>i(2),enumerable:!0}),t}let J=null;function Z(){if(null!==J)return J;const e=void 0!==process.env.NO_COLOR&&""!==process.env.NO_COLOR&&"0"!==process.env.NO_COLOR,t="boolean"==typeof process.stdout?.isTTY&&process.stdout.isTTY;if(e||!t){const e=e=>e;e.white=e,e.bold=e,e.red=e,e.bgRed=e,e.yellow=e,e.cyan=e,e.green=e,e.gray=e,e.magenta=e,e.blue=e,e.bgWhite=e,e.dim=e,J=e}else J=Y([]);return J}class q extends l{constructor(e){super(e),this.chalk=Z()}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,i=this.formatLogString(t);this.getConsoleMethod(t.level)(i)}getConsoleMethod(e){switch(e){case"fatal":case"error":return console.error;case"warn":return console.warn;default:return console.log}}}class X extends q{constructor(e){var t;super(e),this.levelColorMap={fatal:(t=this.chalk).bgRed.white.bold,error:t.red.bold,warn:t.yellow.bold,info:t.blue.bold,audit:t.white.bold,debug:t.green,trace:t.gray}}formatLogString(e){return((e,t,i)=>{const{timestamp:r,level:s,service:n,message:a,...o}=e,l=i[s]||t.white;let c=`${t.gray(new Date(r).toLocaleTimeString())} ${l(`[${s.toUpperCase()}]`)} ${t.cyan(`(${n})`)}: ${a||""}`;Object.keys(o).length>0&&(c+=`\n${t.gray(JSON.stringify(o,null,2))}`);return c})(e,this.chalk,this.levelColorMap)}}class B extends q{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatLogString(e){const{timestamp:t,level:i,service:r,message:s,...n}=e,a=this.levelColorMap[i]||this.chalk.white;let o=`${this.chalk.gray(new Date(t).toLocaleTimeString())} ${a(`[${i.toUpperCase()}]`)} ${this.chalk.blue(`(${r})`)}: ${s||""}`;const l=Object.keys(n);if(l.length>0){const e=l.map(e=>{const t=n[e],i="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${this.chalk.dim(e)}=${this.chalk.gray(i)}`}).join(" ");o+=`\n ${this.chalk.dim("โ””โ”€")} ${e}`}return o}}class Q extends q{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatTimestamp(e){const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}:${String(t.getSeconds()).padStart(2,"0")}`}formatLogString(e){const{timestamp:t,level:i,service:r,message:s,context:n,...a}=e,o=this.levelColorMap[i]||this.chalk.white,l=this.formatTimestamp(t),c=o(i.toUpperCase().padEnd(5)),u=this.chalk.magenta(`[${r}]`),g={...n||{},...a,message:s},h=Object.keys(g);let d="";h.length>0&&(d=this.chalk.dim(" ["+h.map(e=>`${e}=${JSON.stringify(g[e])}`).join(" ")+"]"));return`${l} ${c} ${u}${d}`}}class ee extends q{constructor(e){var t;super(e),this.levelStyleMap={trace:{level:(t=this.chalk).gray.bold,message:t.gray,metaKey:t.gray.dim,metaValue:t.gray},debug:{level:t.cyan.bold,message:t.cyan,metaKey:t.cyan.dim,metaValue:t.cyan},info:{level:t.green.bold,message:t.green,metaKey:t.green.dim,metaValue:t.green},warn:{level:t.yellow.bold,message:t.yellow,metaKey:t.yellow.dim,metaValue:t.yellow},error:{level:t.red.bold,message:t.red,metaKey:t.red.dim,metaValue:t.red},fatal:{level:t.red.bgWhite.bold,message:t.red.bold,metaKey:t.red.dim,metaValue:t.red},audit:{level:t.magenta.bold,message:t.magenta,metaKey:t.magenta.dim,metaValue:t.magenta}}}formatLogString(e){return((e,t,i)=>{const{timestamp:r,level:s,service:n,message:a,...o}=e,l=i[s]??{level:t.white.bold,message:t.white,metaKey:t.gray,metaValue:t.white},c=l.metaKey(new Date(r).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})),u=s.toUpperCase().padEnd(8),g=l.level(u),h=n?l.metaValue(`(${n})`):"";let d=`${c} ${g}`;h&&(d+=` ${h}`),d+=` ${l.message(a??"")}`;const m=Object.keys(o);if(m.length>0){const e=m.map(e=>{const t=o[e],i="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${l.metaKey(e)}=${l.metaValue(i)}`});d+=`\n ${t.dim("โ””โ”€")} ${e.join(" ")}`}return d})(e,this.chalk,this.levelStyleMap)}}class te extends l{constructor(e){super(e),this.entries=[]}async log(e){this.entries.push(e)}getEntries(){return[...this.entries]}findEntries(e){return"function"==typeof e?this.entries.filter(e):this.entries.filter(t=>Object.keys(e).every(i=>{const r=i;return e[r]===t[r]}))}clear(){this.entries=[]}getFirstEntry(){return this.entries[0]}getLastEntry(){return this.entries[this.entries.length-1]}}class ie extends l{constructor(e){if(!e.adapter)throw new Error("AdapterTransport requires a valid adapter implementation.");super(e),this.adapter=e.adapter}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e;await this.adapter.log(t)}async flush(){"function"==typeof this.adapter.flush&&await this.adapter.flush()}async shutdown(){"function"==typeof this.adapter.shutdown&&await this.adapter.shutdown()}}class re{constructor(e){if("function"!=typeof e.executor)throw new Error("UniversalAdapter requires an executor function.");this.executor=e.executor}async log(e){try{await this.executor(e)}catch(e){console.error(`UniversalAdapter execution failed: ${e instanceof Error?e.message:String(e)}`)}}}class se{constructor(e){this.mapping=e.mapping,this.includeAllIn=e.includeAllIn}format(e){const t={};for(const[i,r]of Object.entries(this.mapping))t[i]=this.resolveValue(r,e);if(this.includeAllIn){const i=e.bindings??{},r=e.metadata??{};t[this.includeAllIn]={..."object"==typeof i&&null!==i?i:{},..."object"==typeof r&&null!==r?r:{}}}return t}resolveValue(e,t){if("object"==typeof e&&!Array.isArray(e)&&"value"in e){const t=e;return t.value??t.fallback}const i=Array.isArray(e)?e:[e];for(const e of i){if("object"==typeof e&&null!==e&&"value"in e){const t=e;return t.value??t.fallback}if("string"==typeof e){const i=this.getValueByPath(e,t);if(null!=i)return i}}}getValueByPath(e,t){if("message"===e)return t.message;if("level"===e)return t.level;if("timestamp"===e)return t.timestamp;const i=e.split(".");let r=t;for(const e of i){if(null===r||"object"!=typeof r)return;if(r===t&&!Object.prototype.hasOwnProperty.call(t,e)){const i=t,s=i.bindings?.[e];if(void 0!==s){r=s;continue}const n=i.metadata?.[e];if(void 0!==n){r=n;continue}}r=r[e]}return r}}export{ie as AdapterTransport,Q as ClassicConsoleTransport,ee as ColorfulConsoleTransport,B as CompactConsoleTransport,j as ConsoleTransport,X as PrettyConsoleTransport,A as SanitizationEngine,k as SerializationComplexity,P as SerializationManager,te as SpyTransport,W as SyntropyLog,l as Transport,re as UniversalAdapter,se as UniversalLogFormatter,U as syntropyLog};
1
+ import{EventEmitter as e}from"events";import{AsyncLocalStorage as t}from"node:async_hooks";import{randomUUID as r}from"crypto";import*as i from"node:util";const s=e=>({ok:!0,value:e}),n=(...e)=>({ok:!1,errors:e}),a=e=>t=>null==t?s(void 0):e(t),o=e=>t=>{if(!Array.isArray(t))return n("must be an array");const r=[],i=[];for(let s=0;s<t.length;s++){const n=e(t[s]);n.ok?r.push(n.value):i.push(...n.errors.map(e=>`[${s}]: ${String(e)}`))}return i.length>0?{ok:!1,errors:i}:s(r)},l=e=>t=>{if(null===t||"object"!=typeof t||Array.isArray(t))return n("must be an object");const r=t,i={...r},a=[];for(const t of Object.keys(e)){const s=(0,e[t])(r[t]);s.ok?i[t]=s.value:a.push(...s.errors.map(e=>`${t}: ${String(e)}`))}return a.length>0?{ok:!1,errors:a}:s(i)},c=e=>"string"==typeof e?s(e):n("expected string, got "+typeof e),u=e=>"boolean"==typeof e?s(e):n("expected boolean, got "+typeof e),h=e=>{const t=(e=>"number"!=typeof e||Number.isNaN(e)?n("expected number, got "+typeof e):s(e))(e);return t.ok?!Number.isInteger(t.value)||t.value<1?n(`must be a positive integer (>= 1), got ${t.value}`):s(t.value):t},g=e=>t=>e.includes(t)?s(t):n(`must be one of [${e.join(", ")}], got ${String(t)}`),d=e=>t=>{const r=(e=>null===e||"object"!=typeof e||Array.isArray(e)?n("expected object, got "+(null===e?"null":typeof e)):s(e))(t);if(!r.ok)return r;const i={},a=[];for(const[t,s]of Object.entries(r.value)){const r=e(s);r.ok?i[t]=r.value:a.push(...r.errors.map(e=>`${t}: ${e}`))}return a.length?{ok:!1,errors:a}:s(i)},m={audit:70,fatal:60,error:50,warn:40,info:30,debug:20,trace:10,silent:0};class p{constructor(e={}){this.level=e.level??"info",this.name=e.name??this.constructor.name,this.formatter=e?.formatter,this.sanitizationEngine=e?.sanitizationEngine}isLevelEnabled(e){return m[e]>=m[this.level]}async flush(){return Promise.resolve()}}var f;!function(e){e.CREDIT_CARD="credit_card",e.SSN="ssn",e.EMAIL="email",e.PHONE="phone",e.PASSWORD="password",e.TOKEN="token",e.CUSTOM="custom"}(f||(f={}));class y{constructor(e){if(this.rules=[],this.initialized=!1,this.maskChar=e?.maskChar||"*",this.preserveLength=e?.preserveLength??!0,this.regexTimeoutMs=e?.regexTimeoutMs??100,!1!==e?.enableDefaultRules&&this.addDefaultRules(),e?.rules)for(const t of e.rules)this.addRule(t)}addDefaultRules(){const e=[{pattern:/credit_card|card_number|payment_number/i,strategy:f.CREDIT_CARD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/ssn|social_security|security_number/i,strategy:f.SSN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/email/i,strategy:f.EMAIL,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/phone|phone_number|mobile_number/i,strategy:f.PHONE,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/password|pass|pwd|secret/i,strategy:f.PASSWORD,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0},{pattern:/token|api_key|auth_token|jwt|bearer/i,strategy:f.TOKEN,preserveLength:!0,maskChar:this.maskChar,_isDefaultRule:!0}];for(const t of e)this.addRule(t)}addRule(e){"string"==typeof e.pattern?e._compiledPattern=new RegExp(e.pattern,"i"):e._compiledPattern=e.pattern,e.preserveLength=e.preserveLength??this.preserveLength,e.maskChar=e.maskChar??this.maskChar,this.rules.push(e)}process(e){this.initialized||(this.initialized=!0);try{const t=new WeakSet;return this.applyMaskingRules(e,t)}catch{return{...y.buildSafeFallbackFromMeta(e),_maskingFailed:!0,_maskingFailedMessage:y.MASKING_FAILED_MESSAGE}}}static buildSafeFallbackFromMeta(e){const t={},r=["level","timestamp","message","service"];for(const i of r)i in e&&void 0!==e[i]&&(t[i]=e[i]);return t}applyMaskingRules(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return e;if(t.add(e),Array.isArray(e)){let r=!1;const i=new Array(e.length);for(let s=0;s<e.length;s++){const n=this.applyMaskingRules(e[s],t);i[s]=n,n!==e[s]&&(r=!0)}return r?i:e}const r=e;for(const e in r){if(!Object.prototype.hasOwnProperty.call(r,e))continue;const i=r[e];if("string"==typeof i)for(const t of this.rules){let s=!1;if(t._compiledPattern&&(s=t._isDefaultRule?t._compiledPattern.test(e):this.testRegexWithTimeout(t._compiledPattern,e)),s){r[e]=this.applyStrategy(i,t);break}}else if("object"==typeof i&&null!==i){const s=this.applyMaskingRules(i,t);s!==i&&(r[e]=s)}}return r}applyStrategy(e,t){if(t.strategy===f.CUSTOM&&t.customMask)return t.customMask(e);switch(t.strategy){case f.CREDIT_CARD:return this.maskCreditCard(e,t);case f.SSN:return this.maskSSN(e,t);case f.EMAIL:return this.maskEmail(e,t);case f.PHONE:return this.maskPhone(e,t);case f.PASSWORD:return this.maskPassword(e,t);case f.TOKEN:return this.maskToken(e,t);default:return this.maskDefault(e,t)}}maskCreditCard(e,t){const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(i,s)=>e.substring(0,s).replace(/\D/g,"").length<r.length-4?t.maskChar:i):`${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${t.maskChar.repeat(4)}-${r.slice(-4)}`}maskSSN(e,t){const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(i,s)=>e.substring(0,s).replace(/\D/g,"").length<r.length-4?t.maskChar:i):`***-**-${r.slice(-4)}`}maskEmail(e,t){const r=e.indexOf("@");if(r>0){const i=e.substring(0,r),s=e.substring(r);if(t.preserveLength){return(i.length>1?i.charAt(0)+t.maskChar.repeat(i.length-1):t.maskChar.repeat(i.length))+s}return`${i.charAt(0)}***${s}`}return this.maskDefault(e,t)}maskPhone(e,t){const r=e.replace(/\D/g,"");return t.preserveLength?e.replace(/\d/g,(i,s)=>e.substring(0,s).replace(/\D/g,"").length<r.length-4?t.maskChar:i):`${t.maskChar.repeat(3)}-${t.maskChar.repeat(3)}-${r.slice(-4)}`}maskPassword(e,t){return t.maskChar.repeat(e.length)}maskToken(e,t){return t.preserveLength?e.substring(0,4)+t.maskChar.repeat(e.length-9)+e.substring(e.length-5):e.length>8?e.substring(0,4)+"..."+e.substring(e.length-5):t.maskChar.repeat(e.length)}maskDefault(e,t){return t.preserveLength?t.maskChar.repeat(e.length):t.maskChar.repeat(Math.min(e.length,8))}getStats(){return{initialized:this.initialized,totalRules:this.rules.length,defaultRules:this.rules.filter(e=>[f.CREDIT_CARD,f.SSN,f.EMAIL,f.PHONE,f.PASSWORD,f.TOKEN].includes(e.strategy)).length,customRules:this.rules.filter(e=>e.strategy===f.CUSTOM).length,strategies:this.rules.map(e=>e.strategy)}}isInitialized(){return this.initialized}testRegexWithTimeout(e,t){if(t.length>256)return!1;try{return e.test(t)}catch{return!1}}shutdown(){this.rules=[],this.initialized=!1}}y.MASKING_FAILED_MESSAGE="[SyntropyLog] Masking could not be applied (e.g. timeout or error); payload redacted for safety.";class b extends Error{constructor(e){super(`[SyntropyLog] Configuration validation failed:\n${e.map(e=>` โ€ข ${e}`).join("\n")}`),this.name="ConfigValidationError",this.issues=e}}const S=g(["audit","fatal","error","warn","info","debug","trace","silent"]),w=e=>e instanceof p?s(e):n("must be an instance of Transport"),k=e=>{const t=w(e);return t.ok?t:l({transport:w,env:a(e=>"string"==typeof e||Array.isArray(e)?s(e):n("env must be a string or string[]"))})(e)},v=l({pattern:e=>"string"==typeof e||e instanceof RegExp?s(e):n("expected string or RegExp, got "+typeof e),strategy:g(Object.values(f)),preserveLength:a(u),maskChar:a(c),customMask:a(e=>"function"==typeof e?s(e):n("expected function, got "+typeof e))}),z=l({name:a(c),level:a(S),serviceName:a(c),environment:a(c),transportList:a(d(w)),env:a(d(o(c))),transports:a(e=>{if(Array.isArray(e)){const t=o(k)(e);return t.ok?s(t.value):t}return null!==e&&"object"==typeof e?s(e):n("transports must be an array or a record of arrays")}),serializerTimeoutMs:a(h),prettyPrint:a(l({enabled:a(u)}))}),D=l({rules:a(o(v)),maskChar:a(c),preserveLength:a(u),enableDefaultRules:a(u),regexTimeoutMs:a(h)}),M=l({default:a(o(c)),trace:a(o(c)),debug:a(o(c)),info:a(o(c)),warn:a(o(c)),error:a(o(c)),fatal:a(o(c))}),x=l({correlationIdHeader:a(c),transactionIdHeader:a(c)}),E=l({logger:a(z),loggingMatrix:a(M),masking:a(D),context:a(x),shutdownTimeout:a(h)});const C=Object.freeze({});class I{constructor(e){this.storage=new t,this.correlationIdHeader="x-correlation-id",this.transactionIdHeader="x-trace-id",this.storage=new t,this.loggingMatrix=e}configure(e){e.correlationIdHeader&&(this.correlationIdHeader=e.correlationIdHeader),e.transactionIdHeader&&(this.transactionIdHeader=e.transactionIdHeader)}reconfigureLoggingMatrix(e){this.loggingMatrix=e}run(e){return new Promise((t,r)=>{const i=this.storage.getStore(),s=new Map(i?.data);this.storage.run({data:s},async()=>{try{await Promise.resolve(e()),t()}catch(e){r(e)}})})}get(e){return this.storage.getStore()?.data.get(e)}getAll(){const e=this.storage.getStore();return e?Object.fromEntries(e.data.entries()):{}}set(e,t){const r=this.storage.getStore();r&&r.data.set(e,t)}getCorrelationId(){let e=this.get(this.correlationIdHeader)||this.get("correlationId");return e&&"string"==typeof e||(e=r(),this.set(this.correlationIdHeader,e)),e}setCorrelationId(e){this.set(this.correlationIdHeader,e)}getTransactionId(){return this.get("transactionId")}setTransactionId(e){this.set("transactionId",e)}getCorrelationIdHeaderName(){return this.correlationIdHeader}getTransactionIdHeaderName(){return this.transactionIdHeader}getTraceContextHeaders(){const e={};if(!this.storage.getStore())return e;const t=this.getCorrelationId(),r=this.getTransactionId();return t&&(e[this.getCorrelationIdHeaderName()]=t),r&&(e[this.getTransactionIdHeaderName()]=r),e}getFilteredContext(e){const t=this.getAll();if(!this.loggingMatrix){const e=Object.keys(t).length,r=this.get(this.correlationIdHeader),i=this.get("correlationId");if(0===e&&!r&&!i)return C;const s={};return Object.assign(s,t),!r&&i&&(s[this.correlationIdHeader]=i),s}const r=this.loggingMatrix[e]??this.loggingMatrix.default;if(!r)return C;const i={correlationId:[this.correlationIdHeader,"correlationId"],transactionId:[this.transactionIdHeader,"transactionId"],userId:["userId"],serviceName:["serviceName"],operation:["operation"],errorCode:["errorCode"],tenantId:["tenantId"],paymentId:["paymentId"],orderId:["orderId"],processorId:["processorId"],eventType:["eventType"]};if(r.includes("*")){const e={};for(const[r,s]of Object.entries(t)){let t=r;for(const[e,s]of Object.entries(i))if(s.includes(r)){t=e;break}e[t]=s}return e}const s={};for(const e of r){const r=i[e]||[e];for(const i of r)if(Object.prototype.hasOwnProperty.call(t,i)){s[e]=t[i];break}!Object.prototype.hasOwnProperty.call(s,e)&&Object.prototype.hasOwnProperty.call(t,e)&&(s[e]=t[e])}return s}}const O={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0};class R{constructor(e,t,r,i={}){this.pendingRouting=null,this.name=e,this.transports=t,this.dependencies=r,this.bindings=i.bindings??{},this.level=i.level??"info"}override(...e){return this.pendingRouting={override:e},this}add(...e){const t=this.pendingRouting,r=[...t&&"add"in t?t.add??[]:[],...e],i=t&&"remove"in t?t.remove??[]:void 0;return this.pendingRouting=i?.length?{add:r,remove:i}:{add:r},this}remove(...e){const t=this.pendingRouting,r=[...t&&"remove"in t?t.remove??[]:[],...e],i=t&&"add"in t?t.add??[]:void 0;return this.pendingRouting=i?.length?{add:i,remove:r}:{remove:r},this}captureEffectiveTransports(){const e=this.pendingRouting;return this.pendingRouting=null,function(e,t,r){if(!t||!r)return e;if("override"in r)return r.override.map(e=>t.get(e)).filter(e=>null!=e);let i=[...e];if(r.add?.length)for(const e of r.add){const r=t.get(e);r&&i.push(r)}if(r.remove?.length){const e=new Set(r.remove);i=i.filter(t=>!e.has(t.name))}return i}(this.transports,this.dependencies.transportPool,e)}async _log(e,...t){if("silent"===e)return;if(!function(e,t){return"silent"!==e&&("audit"===e||m[e]>=m[t])}(e,this.level))return;const r=this.captureEffectiveTransports();try{const{message:s,metadata:n}=function(e){let t,r={};if(0===e.length)t="";else if("object"!=typeof e[0]||null===e[0]||Array.isArray(e[0])){t=e[0]||"";const r=e.slice(1);t&&r.length>0&&(t=i.format(t,...r))}else{r=e[0],t=e[1]||"";const s=e.slice(2);t&&s.length>0&&(t=i.format(t,...s))}return{message:t||"",metadata:r}}(t),a=this.dependencies.contextManager.getFilteredContext(e),o={level:e,timestamp:(new Date).toISOString(),service:this.name,message:s};Object.assign(o,a,this.bindings,n);const l=this.dependencies.serializationManager.serialize(o,O).data,c=this.dependencies.maskingEngine.process(l);for(const t of r)t.isLevelEnabled(e)&&t.log(c)}catch{}}info(...e){return this._log("info",...e)}warn(...e){return this._log("warn",...e)}error(...e){return this._log("error",...e)}debug(...e){return this._log("debug",...e)}trace(...e){return this._log("trace",...e)}audit(...e){return this._log("audit",...e)}fatal(...e){return this._log("fatal",...e)}setLevel(e){this.level=e}child(e){return new R(this.name,this.transports,this.dependencies,{level:this.level,bindings:{...this.bindings,...e}})}withSource(e){return this.child({source:e})}withRetention(e){return this.child({retention:e})}withTransactionId(e){return this.child({transactionId:e})}}var L;!function(e){e.SIMPLE="simple",e.COMPLEX="complex",e.CRITICAL="critical"}(L||(L={}));class T{constructor(){this.defaultSensitiveFields=["password","token","secret","key","auth","authorization","api_key","apikey","private_key","privatekey","credential","credential_id","credentialid","access_token","accesstoken","refresh_token","refreshtoken","session_id","sessionid"],this.defaultMaxDepth=10}sanitize(e,t={}){const r=t.sensitiveFields||this.defaultSensitiveFields,i=t.maxDepth||this.defaultMaxDepth,s=t.currentDepth||0;if(s>=i)return"[MAX_DEPTH_REACHED]";if(null==e)return e;if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e)return e;if(Array.isArray(e)){const t={sensitiveFields:r,maxDepth:i,currentDepth:s+1};for(let r=0;r<e.length;r++){const i=this.sanitize(e[r],t);i!==e[r]&&(e[r]=i)}return e}if("object"==typeof e){const t=e;for(const e of Object.keys(t)){const n=e.toLowerCase();if(r.some(e=>n.includes(e.toLowerCase())))t[e]="[REDACTED]";else{const n=this.sanitize(t[e],{sensitiveFields:r,maxDepth:i,currentDepth:s+1});n!==t[e]&&(t[e]=n)}}return e}return e}}const P="pipeline",A="unknown";class j{constructor(){this.steps=[],this.timeoutStrategies=new Map,this.metrics=null,this.sanitizer=new T,this.initializeDefaultStrategies()}addStep(e){this.steps.push(e)}addTimeoutStrategy(e){this.timeoutStrategies.set(e.getStrategyName(),e)}process(e,t){const r=Date.now();this.metrics={stepDurations:{},totalDuration:0,operationTimeout:0,timeoutStrategy:A};let i=e;try{for(const e of this.steps){const r=Date.now();i=e.execute(i,t),this.metrics.stepDurations[e.name]=Date.now()-r}const e=this.selectTimeoutStrategy(i),s=e.calculateTimeout(i);return this.metrics.operationTimeout=s,this.metrics.timeoutStrategy=e.getStrategyName(),this.metrics.totalDuration=Date.now()-r,j.buildSuccessResult(i,t.sanitizeSensitiveData,this.metrics,s,e.getStrategyName())}catch(e){return this.metrics.totalDuration=Date.now()-r,j.buildErrorResult(i,e,this.metrics)}}getMetrics(){return this.metrics}static buildSuccessResult(e,t,r,i,s){const n=e,a=n.serializer??P,o=n.serializationComplexity??L.SIMPLE;return{success:!0,data:e,serializer:a,duration:r.totalDuration,complexity:o,sanitized:t,metadata:{stepDurations:r.stepDurations,operationTimeout:i,timeoutStrategy:s,serializer:a,complexity:o}}}static buildErrorResult(e,t,r){const i=t?.serializer??P;return{success:!1,data:e,serializer:i,duration:r.totalDuration,complexity:L.SIMPLE,sanitized:!1,error:t instanceof Error?t.message:String(t),metadata:{stepDurations:r.stepDurations,operationTimeout:0,timeoutStrategy:A,serializer:i,complexity:L.SIMPLE}}}selectTimeoutStrategy(e){const t=this.timeoutStrategies.get("default");if(null==t)throw new Error("SerializationPipeline: default timeout strategy is required");return t}initializeDefaultStrategies(){this.addTimeoutStrategy(new $)}}class ${calculateTimeout(e){return 5e3}getStrategyName(){return"default"}}class _{constructor(e=[]){this.name="serialization",this.serializers=[],this.serializers=e}addSerializer(e){const t=this.serializers.findIndex(t=>t.priority<e.priority);-1===t?this.serializers.push(e):this.serializers.splice(t,0,e)}execute(e,t){const r=Date.now(),i=this.findSerializer(e);if(!i)return e;try{const s=i.serialize(e,t.serializationContext),n=Date.now()-r,a="object"==typeof s.data&&null!==s.data?s.data:{};return a.serializationDuration=n,a.serializer=i.name,a.serializationComplexity=s.complexity||s.metadata?.complexity||null,a}catch(e){throw e instanceof Error&&!e.serializer&&(e.serializer=i.name),e}}findSerializer(e){for(const t of this.serializers)if(t.canSerialize(e))return t;return null}getRegisteredSerializers(){return this.serializers.map(e=>e.name)}}function N(e,t){if(null===e||"object"!=typeof e)return e;if(t.has(e))return"[Circular]";if(t.add(e),Array.isArray(e)){let r=!1;const i=new Array(e.length);for(let s=0;s<e.length;s++){const n=N(e[s],t);i[s]=n,n!==e[s]&&(r=!0)}return t.delete(e),r?i:e}for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r)){const i=e[r],s=N(i,t);s!==i&&(e[r]=s)}return t.delete(e),e}class H{constructor(){this.name="hygiene"}execute(e,t){if(null===e||"object"!=typeof e)return e;try{if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack,...e};try{return JSON.stringify(e),e}catch{let t;try{t=N(e,new WeakSet)}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}return t}}catch(e){let t;try{t=e instanceof Error?e.message:String(e)}catch{t="unknown"}return`[HYGIENE_ERROR: ${t}]`}}}function F(e,t,r,i){if("object"==typeof e&&null!==e){const s=e;return s.sanitizationDuration=t,s.sanitized=r,void 0!==i&&(s.sanitizationError=i),e}return{sanitizationDuration:t,sanitized:r,...void 0!==i&&{sanitizationError:i}}}class K{constructor(e){this.name="sanitization",this.sanitizer=e??new T}execute(e,t){const r=Date.now(),i=()=>Date.now()-r;if(!t.sanitizeSensitiveData)return F(e,i(),!1);try{return F(this.sanitizer.sanitize(e,t.sanitizationContext),i(),!0)}catch(t){return F(e,i(),!1,function(e){return e instanceof Error?e.message:String(e)}(t))}}}const G=3e3;class W{constructor(e){this.name="timeout",this.timeoutStrategies=new Map,this.timeoutStrategies=e}execute(e,t){const r=Date.now();try{const t=this.selectTimeoutStrategy(e),i=t?.calculateTimeout(e)??G;return function(e,t,r,i){if("object"==typeof e&&null!==e){const s=e;return s.timeoutDuration=t,s.operationTimeout=r,s.timeoutStrategy=i?.getStrategyName()??"default",s.timeoutApplied=null!=i,e}return{timeoutDuration:t,operationTimeout:r,timeoutStrategy:i?.getStrategyName()??"default",timeoutApplied:null!=i}}(e,Date.now()-r,i,t)}catch(t){return function(e,t,r){if("object"==typeof e&&null!==e){const i=e;return i.timeoutDuration=t,i.operationTimeout=G,i.timeoutStrategy="default",i.timeoutApplied=!1,i.timeoutError=r instanceof Error?r.message:"Timeout error",e}return{timeoutDuration:t,operationTimeout:G,timeoutStrategy:"default",timeoutApplied:!1,timeoutError:r instanceof Error?r.message:"Timeout error"}}(e,Date.now()-r,t)}}selectTimeoutStrategy(e){return this.timeoutStrategies.get("default")??null}}class V{constructor(e={}){this.config={timeoutMs:e.timeoutMs||5e3,enableMetrics:e.enableMetrics??!0,sanitizeSensitiveData:e.sanitizeSensitiveData??!0,sanitizationContext:{sensitiveFields:e.sanitizationContext?.sensitiveFields||["password","token","secret","key","auth","credential","api_key","private_key","connection_string","wallet_location"],redactPatterns:e.sanitizationContext?.redactPatterns||[/password\s*=\s*['"][^'"]*['"]/gi,/user\s*=\s*['"][^'"]*['"]/gi,/token\s*=\s*['"][^'"]*['"]/gi,/secret\s*=\s*['"][^'"]*['"]/gi],maxStringLength:e.sanitizationContext?.maxStringLength||300,enableDeepSanitization:e.sanitizationContext?.enableDeepSanitization??!0}},this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}},this.pipeline=new j,this.serializationStep=new _,this.hygieneStep=new H,this.sanitizationStep=new K,this.timeoutStep=new W(this.pipeline.timeoutStrategies),this.pipeline.addStep(this.serializationStep),this.pipeline.addStep(this.hygieneStep),this.pipeline.addStep(this.sanitizationStep),this.pipeline.addStep(this.timeoutStep)}register(e){this.serializationStep.addSerializer(e)}serialize(e,t={depth:0,maxDepth:10,sensitiveFields:[],sanitize:!0}){const r=Date.now(),i={serializationContext:t,sanitizeSensitiveData:this.config.sanitizeSensitiveData,sanitizationContext:this.config.sanitizationContext,enableMetrics:this.config.enableMetrics},s=this.pipeline.process(e,i);return this.config.enableMetrics&&this.updateMetrics(s,Date.now()-r),s}updateMetrics(e,t){if(this.metrics.totalSerializations++,e.success){this.metrics.successfulSerializations++;const t=(e.metadata.stepDurations?.serialization||0)+(e.metadata.stepDurations?.hygiene||0);this.metrics.totalSerializationDuration+=t,this.metrics.maxSerializationDuration=Math.max(this.metrics.maxSerializationDuration,t),this.metrics.minSerializationDuration=0===this.metrics.minSerializationDuration?t:Math.min(this.metrics.minSerializationDuration,t);const r=e.metadata.operationTimeout||0;this.metrics.totalOperationTimeout+=r;const i=e.complexity||L.SIMPLE;i===L.SIMPLE?this.metrics.complexityDistribution.low++:i===L.COMPLEX?this.metrics.complexityDistribution.medium++:i===L.CRITICAL&&this.metrics.complexityDistribution.high++;const s=e.serializer||"unknown";this.metrics.serializerDistribution[s]=(this.metrics.serializerDistribution[s]||0)+1;const n=e.metadata.timeoutStrategy||"unknown";this.metrics.timeoutStrategyDistribution[n]=(this.metrics.timeoutStrategyDistribution[n]||0)+1}else this.metrics.failedSerializations++}getMetrics(){return{totalSerializations:this.metrics.totalSerializations,successfulSerializations:this.metrics.successfulSerializations,failedSerializations:this.metrics.failedSerializations,averageSerializationDuration:this.metrics.totalSerializations>0?this.metrics.totalSerializationDuration/this.metrics.totalSerializations:0,averageOperationTimeout:this.metrics.successfulSerializations>0?this.metrics.totalOperationTimeout/this.metrics.successfulSerializations:0,maxSerializationDuration:this.metrics.maxSerializationDuration,minSerializationDuration:this.metrics.minSerializationDuration,complexityDistribution:{...this.metrics.complexityDistribution},serializerDistribution:{...this.metrics.serializerDistribution},timeoutStrategyDistribution:{...this.metrics.timeoutStrategyDistribution}}}resetMetrics(){this.metrics={totalSerializations:0,successfulSerializations:0,failedSerializations:0,totalSerializationDuration:0,totalOperationTimeout:0,maxSerializationDuration:0,minSerializationDuration:0,complexityDistribution:{low:0,medium:0,high:0},serializerDistribution:{},timeoutStrategyDistribution:{}}}getRegisteredSerializers(){return this.serializationStep.getRegisteredSerializers()}getPipelineMetrics(){return this.pipeline.getMetrics()}}class U extends p{constructor(e){super(e)}log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,r=JSON.stringify(t);switch(e.level){case"fatal":case"error":console.error(r);break;case"warn":console.warn(r);break;default:console.log(r)}}}class Y{constructor(e){this.ansiRegex=/[\x1b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,this.maskingEngine=e}async process(e){let t=this.sanitizeRecursively(e);return this.maskingEngine&&(t=this.maskingEngine.process(t)),t}sanitizeRecursively(e){if("string"==typeof e)return e.replace(this.ansiRegex,"");if(Array.isArray(e))return e.map(e=>this.sanitizeRecursively(e));if("object"==typeof e&&null!==e&&e.constructor===Object){const t={},r=e;for(const e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=this.sanitizeRecursively(r[e]));return t}return e}}function J(e,t){const r=[];for(const i of e)if(i instanceof p)r.push(i);else if(i&&"object"==typeof i&&"transport"in i){const e=null==i.env?null:Array.isArray(i.env)?i.env:[i.env];(null===e||e.includes(t))&&r.push(i.transport)}else i&&"object"==typeof i&&r.push(i);return r}class Z{constructor(e,t,r){this.loggerPool=new Map,this.MAX_POOL_SIZE=1e3,this.contextManager=t,this.syntropyLogInstance=r,e.context&&this.contextManager.configure(e.context);const i=(e=>{const t=e.logger?.environment??"development",r=e.logger?.transportList&&Object.keys(e.logger.transportList).length>0,i=e.logger?.env&&Object.keys(e.logger.env).length>0;if(r&&i&&e.logger?.transportList&&e.logger?.env){const r=new Map(Object.entries(e.logger.transportList));return{transports:{default:(e.logger.env[t]??[]).map(e=>r.get(e)).filter(e=>null!=e)},transportPool:r}}if(e.logger?.transports){const r=e.logger.transports,i=new Map,s=e=>{const t=e instanceof p?e:e&&"object"==typeof e&&"transport"in e?e.transport:e,r=t.name??t.constructor?.name??`transport-${i.size}`;return i.set(r,t),t};let n;if(Array.isArray(r))r.forEach(s),n={default:J(r,t)};else{const e=r;n={};for(const[r,i]of Object.entries(e))i.forEach(s),n[r]=J(i,t)}return{transports:n,transportPool:i}}{const e=new Y,t=new U({sanitizationEngine:e,name:"console"});return{transports:{default:[t]},transportPool:new Map([["console",t]])}}})(e);this.transports=i.transports,this.transportPool=i.transportPool,this.globalLogLevel=e.logger?.level??"info",this.serviceName=e.logger?.serviceName??"unknown-service",this.serializationManager=new V({timeoutMs:e.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==e.masking?.enableDefaultRules}),this.maskingEngine=new y({rules:e.masking?.rules,maskChar:e.masking?.maskChar,preserveLength:e.masking?.preserveLength,enableDefaultRules:!1!==e.masking?.enableDefaultRules,regexTimeoutMs:e.masking?.regexTimeoutMs})}getLogger(e="default",t){const r=((e,t)=>{if(!t||0===Object.keys(t).length)return e;const r=Object.keys(t).sort().reduce((e,r)=>(e[r]=t[r],e),{});try{return`${e}:${JSON.stringify(r)}`}catch{return`${e}:${Object.keys(r).sort().join(",")}`}})(e,t);if(this.loggerPool.has(r)){const e=this.loggerPool.get(r);return this.loggerPool.delete(r),this.loggerPool.set(r,e),e}const i="default"===e?this.serviceName:e,s={contextManager:this.contextManager,serializationManager:this.serializationManager,maskingEngine:this.maskingEngine,syntropyLogInstance:this.syntropyLogInstance,transportPool:this.transportPool},n=this.transports[e]??this.transports.default,a=new R(i,n,s,{bindings:t});if(a.level=this.globalLogLevel,this.loggerPool.size>=this.MAX_POOL_SIZE){const e=this.loggerPool.keys().next().value;void 0!==e&&this.loggerPool.delete(e)}return this.loggerPool.set(r,a),a}async flushAllTransports(){const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>e.flush().catch(t=>{console.error(`Error flushing transport ${e.constructor.name}:`,t)}));await Promise.allSettled(t)}async shutdown(){try{await this.flushAllTransports(),this.loggerPool.clear();const e=Object.values(this.transports).flat(),t=Array.from(new Set(e)).map(e=>"function"==typeof e.shutdown?e.shutdown().catch(t=>{console.error(`Error shutting down transport ${e.constructor.name}:`,t)}):Promise.resolve());await Promise.allSettled(t)}catch(e){console.error("Error during LoggerFactory shutdown:",e)}}}const q="[CONFIG_MASKED]",X=["password","token","secret","apikey","credential","pass","key","accesstoken","refreshtoken","clientsecret","sentinelpassword","sasl"];function B(e){if(e instanceof p)return e;if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map(e=>B(e));const t={},r=X.map(e=>e.toLowerCase());for(const i in e)if(Object.prototype.hasOwnProperty.call(e,i)){const s=i.toLowerCase(),n=e[i];r.includes(s)?t[i]=q:(s.includes("url")||s.includes("uri"))&&"string"==typeof n?t[i]=n.replace(/(?<=:\/\/)[^:]+:[^@]+@/,`${q}@`):"object"!=typeof n||null===n||n instanceof RegExp?t[i]=n:t[i]=B(n)}return t}function Q(e){return e instanceof Error?{name:e.name,message:e.message,stack:e.stack||null}:String(e)}class ee extends e{constructor(e){super(),this.state="NOT_INITIALIZED",this.logger=null,this.trackedProcesses=new Set,this.syntropyFacade=e,this.config={},this.serializationManager=new V({}),this.maskingEngine=new y({})}getState(){return this.state}async init(e){if("NOT_INITIALIZED"===this.state){this.state="INITIALIZING";try{const t=B(function(e){const t=E(e);if(!t.ok)throw new b(t.errors);return t.value}(e));this.config=t,this.contextManager=new I(this.config.loggingMatrix),this.config.context&&this.contextManager.configure(this.config.context),this.serializationManager=new V({timeoutMs:this.config.logger?.serializerTimeoutMs,sanitizeSensitiveData:!1!==this.config.masking?.enableDefaultRules}),this.maskingEngine=new y({rules:this.config.masking?.rules,maskChar:this.config.masking?.maskChar,preserveLength:this.config.masking?.preserveLength,enableDefaultRules:!1!==this.config.masking?.enableDefaultRules,regexTimeoutMs:this.config.masking?.regexTimeoutMs}),this.loggerFactory=new Z(this.config,this.contextManager,this.syntropyFacade);const r=this.loggerFactory.getLogger("syntropylog-main");this.logger=r,r.info("SyntropyLog framework initialized successfully."),this.state="READY",this.emit("ready")}catch(e){throw this.state="ERROR",this.emit("error",e),e instanceof b?console.error("[SyntropyLog] Configuration validation failed:",e.issues):console.error("[SyntropyLog] Failed to initialize framework:",e),e}}else this.logger?.warn(`LifecycleManager.init() called while in state '${this.state}'. Ignoring subsequent call.`)}async shutdown(){if(this.logger?.info(`๐Ÿ”„ LifecycleManager.shutdown() called. Current state: ${this.state}`),"READY"===this.state){this.state="SHUTTING_DOWN",this.emit("shutting_down"),this.logger?.info("๐Ÿ”„ State changed to SHUTTING_DOWN");try{this.logger?.info("Shutting down SyntropyLog framework..."),this.maskingEngine?.shutdown?.();const e=[];e.push(this.terminateExternalProcesses()),this.logger?.info(`๐Ÿ“‹ Executing ${e.length} shutdown steps...`),await Promise.allSettled(e),await(this.logger?.info("โœ… Shutdown steps completed")),await(this.logger?.info("All managers have been shut down.")),await(this.logger?.info("โœ… State changed to SHUTDOWN")),await(this.loggerFactory?.shutdown?.()),"SHUTTING_DOWN"===this.state&&this.emit("transports_drained"),this.state="SHUTDOWN",this.emit("shutdown")}catch(e){this.state="ERROR",this.emit("error",e),this.logger?.error("โŒ Error during shutdown:",{error:Q(e)}),await(this.loggerFactory?.shutdown?.()),"ERROR"===this.state&&this.emit("transports_drained")}}else this.logger?.warn(`โŒ Cannot perform shutdown. Current state: ${this.state}`)}registerChildProcess(e){this.trackedProcesses.add(e),e.on("exit",()=>{this.trackedProcesses.delete(e)})}async terminateExternalProcesses(){try{if(0===this.trackedProcesses.size)return void this.logger?.info("No tracked external processes to terminate");this.logger?.info(`Terminating ${this.trackedProcesses.size} external processes...`);const e=Array.from(this.trackedProcesses).map(e=>(async(e,t)=>{if(!e.connected&&null!==e.exitCode)return;const r=e.pid;t?.debug(`Sending SIGTERM to process ${r}...`),e.kill("SIGTERM");const i=new Promise(t=>{const r=()=>{t(),e.removeListener("exit",r)};e.on("exit",r)}),s=new Promise(e=>setTimeout(e,5e3));await Promise.race([i,s]),null===e.exitCode?(t?.warn(`Process ${r} did not exit after SIGTERM, sending SIGKILL...`),e.kill("SIGKILL")):t?.debug(`Process ${r} exited gracefully`)})(e,this.logger));await Promise.allSettled(e),this.trackedProcesses.clear(),this.logger?.info("โœ… All external processes terminated")}catch(e){this.logger?.warn("Error terminating external processes:",{error:Q(e)})}}ensureReady(){if("READY"!==this.state)throw new Error(`SyntropyLog is not ready. Current state: '${this.state}'. Ensure init() has completed successfully by listening for the 'ready' event.`)}}function te(e,t){if(null==e)throw new Error(t)}class re extends e{constructor(){super(),this.lifecycleManager=new ee(this),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("transports_drained",()=>this.emit("transports_drained")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}static getInstance(){return re.instance||(re.instance=new re),re.instance}static resetInstance(){re.instance=void 0}getState(){return this.lifecycleManager.getState()}async init(e){return this.lifecycleManager.init(e)}async shutdown(){return this.lifecycleManager.shutdown()}getLogger(e="default",t){return te(this.lifecycleManager.loggerFactory,"Logger Factory not available."),this.lifecycleManager.loggerFactory.getLogger(e,t)}getContextManager(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager}getConfig(){return this.lifecycleManager.ensureReady(),this.lifecycleManager.config}getFilteredContext(e){return this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.getFilteredContext(e)}reconfigureLoggingMatrix(e){this.lifecycleManager.ensureReady(),this.lifecycleManager.contextManager.reconfigureLoggingMatrix(e)}getMasker(){return te(this.lifecycleManager.maskingEngine,"MaskingEngine not available."),this.lifecycleManager.maskingEngine}getSerializer(){return te(this.lifecycleManager.serializationManager,"SerializationManager not available."),this.lifecycleManager.serializationManager}_resetForTesting(){this.lifecycleManager.removeAllListeners(),Object.assign(this,{lifecycleManager:new ee(this)}),this.removeAllListeners(),this.lifecycleManager.on("ready",()=>this.emit("ready")),this.lifecycleManager.on("error",e=>this.emit("error",e)),this.lifecycleManager.on("shutting_down",()=>this.emit("shutting_down")),this.lifecycleManager.on("shutdown",()=>this.emit("shutdown"))}}const ie=re.getInstance();function se(e){const t=t=>function(e,t){return 0===t.length?e:`[${t.join(";")}m${e}`}(t,e),r=t=>se([...e,t]);return Object.defineProperty(t,"white",{get:()=>r(37),enumerable:!0}),Object.defineProperty(t,"bold",{get:()=>r(1),enumerable:!0}),Object.defineProperty(t,"red",{get:()=>r(31),enumerable:!0}),Object.defineProperty(t,"bgRed",{get:()=>r(41),enumerable:!0}),Object.defineProperty(t,"yellow",{get:()=>r(33),enumerable:!0}),Object.defineProperty(t,"cyan",{get:()=>r(36),enumerable:!0}),Object.defineProperty(t,"green",{get:()=>r(32),enumerable:!0}),Object.defineProperty(t,"gray",{get:()=>r(90),enumerable:!0}),Object.defineProperty(t,"magenta",{get:()=>r(35),enumerable:!0}),Object.defineProperty(t,"blue",{get:()=>r(34),enumerable:!0}),Object.defineProperty(t,"bgWhite",{get:()=>r(47),enumerable:!0}),Object.defineProperty(t,"dim",{get:()=>r(2),enumerable:!0}),t}let ne=null;function ae(){if(null!==ne)return ne;const e=void 0!==process.env.NO_COLOR&&""!==process.env.NO_COLOR&&"0"!==process.env.NO_COLOR,t="boolean"==typeof process.stdout?.isTTY&&process.stdout.isTTY;if(e||!t){const e=e=>e;e.white=e,e.bold=e,e.red=e,e.bgRed=e,e.yellow=e,e.cyan=e,e.green=e,e.gray=e,e.magenta=e,e.blue=e,e.bgWhite=e,e.dim=e,ne=e}else ne=se([]);return ne}class oe extends p{constructor(e){super(e),this.chalk=ae()}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e,r=this.formatLogString(t);this.getConsoleMethod(t.level)(r)}getConsoleMethod(e){switch(e){case"fatal":case"error":return console.error;case"warn":return console.warn;default:return console.log}}}class le extends oe{constructor(e){var t;super(e),this.levelColorMap={fatal:(t=this.chalk).bgRed.white.bold,error:t.red.bold,warn:t.yellow.bold,info:t.blue.bold,audit:t.white.bold,debug:t.green,trace:t.gray}}formatLogString(e){return((e,t,r)=>{const{timestamp:i,level:s,service:n,message:a,...o}=e,l=r[s]||t.white;let c=`${t.gray(new Date(i).toLocaleTimeString())} ${l(`[${s.toUpperCase()}]`)} ${t.cyan(`(${n})`)}: ${a||""}`;Object.keys(o).length>0&&(c+=`\n${t.gray(JSON.stringify(o,null,2))}`);return c})(e,this.chalk,this.levelColorMap)}}class ce extends oe{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatLogString(e){const{timestamp:t,level:r,service:i,message:s,...n}=e,a=this.levelColorMap[r]||this.chalk.white;let o=`${this.chalk.gray(new Date(t).toLocaleTimeString())} ${a(`[${r.toUpperCase()}]`)} ${this.chalk.blue(`(${i})`)}: ${s||""}`;const l=Object.keys(n);if(l.length>0){const e=l.map(e=>{const t=n[e],r="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${this.chalk.dim(e)}=${this.chalk.gray(r)}`}).join(" ");o+=`\n ${this.chalk.dim("โ””โ”€")} ${e}`}return o}}class ue extends oe{constructor(e){super(e),this.levelColorMap={fatal:this.chalk.bgRed.white.bold,error:this.chalk.red.bold,warn:this.chalk.yellow.bold,info:this.chalk.cyan.bold,audit:this.chalk.white.bold,debug:this.chalk.green,trace:this.chalk.gray}}formatTimestamp(e){const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}:${String(t.getSeconds()).padStart(2,"0")}`}formatLogString(e){const{timestamp:t,level:r,service:i,message:s,context:n,...a}=e,o=this.levelColorMap[r]||this.chalk.white,l=this.formatTimestamp(t),c=o(r.toUpperCase().padEnd(5)),u=this.chalk.magenta(`[${i}]`),h={...n||{},...a,message:s},g=Object.keys(h);let d="";g.length>0&&(d=this.chalk.dim(" ["+g.map(e=>`${e}=${JSON.stringify(h[e])}`).join(" ")+"]"));return`${l} ${c} ${u}${d}`}}class he extends oe{constructor(e){var t;super(e),this.levelStyleMap={trace:{level:(t=this.chalk).gray.bold,message:t.gray,metaKey:t.gray.dim,metaValue:t.gray},debug:{level:t.cyan.bold,message:t.cyan,metaKey:t.cyan.dim,metaValue:t.cyan},info:{level:t.green.bold,message:t.green,metaKey:t.green.dim,metaValue:t.green},warn:{level:t.yellow.bold,message:t.yellow,metaKey:t.yellow.dim,metaValue:t.yellow},error:{level:t.red.bold,message:t.red,metaKey:t.red.dim,metaValue:t.red},fatal:{level:t.red.bgWhite.bold,message:t.red.bold,metaKey:t.red.dim,metaValue:t.red},audit:{level:t.magenta.bold,message:t.magenta,metaKey:t.magenta.dim,metaValue:t.magenta}}}formatLogString(e){return((e,t,r)=>{const{timestamp:i,level:s,service:n,message:a,...o}=e,l=r[s]??{level:t.white.bold,message:t.white,metaKey:t.gray,metaValue:t.white},c=l.metaKey(new Date(i).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})),u=s.toUpperCase().padEnd(8),h=l.level(u),g=n?l.metaValue(`(${n})`):"";let d=`${c} ${h}`;g&&(d+=` ${g}`),d+=` ${l.message(a??"")}`;const m=Object.keys(o);if(m.length>0){const e=m.map(e=>{const t=o[e],r="object"==typeof t&&null!==t?JSON.stringify(t):String(t);return`${l.metaKey(e)}=${l.metaValue(r)}`});d+=`\n ${t.dim("โ””โ”€")} ${e.join(" ")}`}return d})(e,this.chalk,this.levelStyleMap)}}class ge extends p{constructor(e){super(e),this.entries=[]}async log(e){this.entries.push(e)}getEntries(){return[...this.entries]}findEntries(e){return"function"==typeof e?this.entries.filter(e):this.entries.filter(t=>Object.keys(e).every(r=>{const i=r;return e[i]===t[i]}))}clear(){this.entries=[]}getFirstEntry(){return this.entries[0]}getLastEntry(){return this.entries[this.entries.length-1]}}class de extends p{constructor(e){if(!e.adapter)throw new Error("AdapterTransport requires a valid adapter implementation.");super(e),this.adapter=e.adapter}async log(e){if(!this.isLevelEnabled(e.level))return;const t=this.formatter?this.formatter.format(e):e;await this.adapter.log(t)}async flush(){"function"==typeof this.adapter.flush&&await this.adapter.flush()}async shutdown(){"function"==typeof this.adapter.shutdown&&await this.adapter.shutdown()}}class me{constructor(e){if("function"!=typeof e.executor)throw new Error("UniversalAdapter requires an executor function.");this.executor=e.executor}async log(e){try{await this.executor(e)}catch(e){console.error(`UniversalAdapter execution failed: ${e instanceof Error?e.message:String(e)}`)}}}class pe{constructor(e){this.mapping=e.mapping,this.includeAllIn=e.includeAllIn}format(e){const t={};for(const[r,i]of Object.entries(this.mapping))t[r]=this.resolveValue(i,e);if(this.includeAllIn){const r=e.bindings??{},i=e.metadata??{};t[this.includeAllIn]={..."object"==typeof r&&null!==r?r:{},..."object"==typeof i&&null!==i?i:{}}}return t}resolveValue(e,t){if("object"==typeof e&&!Array.isArray(e)&&"value"in e){const t=e;return t.value??t.fallback}const r=Array.isArray(e)?e:[e];for(const e of r){if("object"==typeof e&&null!==e&&"value"in e){const t=e;return t.value??t.fallback}if("string"==typeof e){const r=this.getValueByPath(e,t);if(null!=r)return r}}}getValueByPath(e,t){if("message"===e)return t.message;if("level"===e)return t.level;if("timestamp"===e)return t.timestamp;const r=e.split(".");let i=t;for(const e of r){if(null===i||"object"!=typeof i)return;if(i===t&&!Object.prototype.hasOwnProperty.call(t,e)){const r=t,s=r.bindings?.[e];if(void 0!==s){i=s;continue}const n=r.metadata?.[e];if(void 0!==n){i=n;continue}}i=i[e]}return i}}export{de as AdapterTransport,ue as ClassicConsoleTransport,he as ColorfulConsoleTransport,ce as CompactConsoleTransport,U as ConsoleTransport,le as PrettyConsoleTransport,Y as SanitizationEngine,L as SerializationComplexity,V as SerializationManager,ge as SpyTransport,re as SyntropyLog,p as Transport,me as UniversalAdapter,pe as UniversalLogFormatter,ie as syntropyLog};
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @file src/config/Result.ts
3
+ * @description Railway-Oriented Programming (ROP) Result type and composable combinators.
4
+ * Zero dependencies. Every combinator is a pure function.
5
+ */
6
+ export type Ok<T> = {
7
+ readonly ok: true;
8
+ readonly value: T;
9
+ };
10
+ export type Err<E> = {
11
+ readonly ok: false;
12
+ readonly errors: E[];
13
+ };
14
+ export type Result<T, E = string> = Ok<T> | Err<E>;
15
+ /** Validator signature: any unknown input โ†’ typed Result */
16
+ export type Validator<T, E = string> = (input: unknown) => Result<T, E>;
17
+ export declare const ok: <T>(value: T) => Ok<T>;
18
+ export declare const err: <E>(...errors: E[]) => Err<E>;
19
+ /**
20
+ * If the input is undefined or null, succeeds with undefined.
21
+ * Otherwise delegates to the wrapped validator.
22
+ */
23
+ export declare const optional: <T, E = string>(validator: Validator<T, E>) => Validator<T | undefined, E>;
24
+ /**
25
+ * Runs v1, then if ok, runs v2 on the result value.
26
+ */
27
+ export declare const chain: <A, B, E = string>(v1: Validator<A, E>, v2: Validator<B, E>) => Validator<B, E>;
28
+ /**
29
+ * Validates each value in an array with the given element validator.
30
+ * Collects all errors across all elements.
31
+ */
32
+ export declare const arrayOf: <T, E = string>(elementValidator: Validator<T, E>) => Validator<T[], E>;
33
+ /**
34
+ * Validates an object against a schema of validators.
35
+ * Unknown keys are passed through.
36
+ * Collects all errors across all fields.
37
+ */
38
+ export declare const object: <T extends Record<string, unknown>, E = string>(schema: { [K in keyof T]: Validator<T[K], E>; }) => Validator<T, E>;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @file src/config/config.validator.ts
3
+ * @description Zero-dependency config validator using ROP combinators.
4
+ * Replaces valibot for runtime config validation while keeping identical error quality.
5
+ */
6
+ import { Transport } from '../logger/transports/Transport';
7
+ export { Transport };
8
+ import type { SyntropyLogConfig } from '../config.schema';
9
+ export declare class ConfigValidationError extends Error {
10
+ readonly issues: string[];
11
+ constructor(issues: string[]);
12
+ }
13
+ /**
14
+ * Validates and parses a raw config object into a typed `SyntropyLogConfig`.
15
+ * Throws `ConfigValidationError` with detailed messages if validation fails.
16
+ */
17
+ export declare function parseConfig(raw: unknown): SyntropyLogConfig;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @file src/config/validators.ts
3
+ * @description Primitive validators as pure functions.
4
+ * Each validator is `(unknown) => Result<T>`. Zero dependencies.
5
+ */
6
+ import { Validator } from './Result';
7
+ export declare const isString: Validator<string>;
8
+ export declare const isNumber: Validator<number>;
9
+ export declare const isBoolean: Validator<boolean>;
10
+ export type AnyCallable = (...args: unknown[]) => unknown;
11
+ export declare const isFunction: Validator<AnyCallable>;
12
+ export declare const isRegExp: Validator<RegExp>;
13
+ /** Integer โ‰ฅ 1 */
14
+ export declare const isPositiveInt: Validator<number>;
15
+ /** Succeeds only if the value is strictly equal to one of the provided options. */
16
+ export declare const oneOf: <T extends string | number>(values: readonly T[]) => Validator<T>;
17
+ /** Accepts either a string or a RegExp. */
18
+ export declare const isStringOrRegExp: Validator<string | RegExp>;
19
+ /** Passes if value is a non-null, non-array object. Does NOT validate fields. */
20
+ export declare const isRecord: Validator<Record<string, unknown>>;
21
+ /** Passes if value is an instance of the given class. */
22
+ export declare const isInstance: <T>(ctor: new (...args: unknown[]) => T, name?: string) => Validator<T>;
23
+ export declare const recordOf: <V>(valueValidator: Validator<V>) => Validator<Record<string, V>>;
@@ -1,13 +1,6 @@
1
1
  /**
2
2
  * @file src/config.ts
3
- * @description Defines and exports the configuration types for the library.
4
- * These types are now explicitly defined for better TypeScript intellisense and autocompletion,
5
- * while still using Zod schemas for runtime validation.
3
+ * @description Re-exports the SyntropyLogConfig type from config.schema.ts.
4
+ * No runtime validation here โ€” that is handled by config.validator.ts.
6
5
  */
7
- import * as v from 'valibot';
8
- import { syntropyLogConfigSchema } from './config.schema';
9
- /**
10
- * @description The complete, top-level configuration type for the SyntropyLog framework.
11
- * This type is inferred from the main Zod schema and represents the entire valid configuration object.
12
- */
13
- export type SyntropyLogConfig = v.InferInput<typeof syntropyLogConfigSchema>;
6
+ export type { SyntropyLogConfig } from './config.schema';
@@ -1,115 +1,56 @@
1
1
  /**
2
- * FILE: src/config.schema.ts
3
- * DESCRIPTION: Defines the Zod validation schemas for the entire library's configuration.
4
- * These schemas are the single source of truth for the configuration's structure and types.
2
+ * @file src/config.schema.ts
3
+ * @description Defines and exports the configuration types for the entire library.
4
+ * These are pure TypeScript interfaces โ€” no runtime dependencies.
5
+ * Runtime validation is done by `src/config/config.validator.ts`.
5
6
  */
6
- import * as v from 'valibot';
7
7
  import { Transport } from './logger/transports/Transport';
8
- import { MaskingStrategy } from './masking/MaskingEngine';
9
- /**
10
- * @description The main schema for the entire SyntropyLog configuration.
11
- * This is the single source of truth for validating the user's configuration object.
12
- */
13
- export declare const syntropyLogConfigSchema: v.ObjectSchema<{
14
- /** Logger-specific configuration. */
15
- readonly logger: v.OptionalSchema<v.ObjectSchema<{
16
- readonly name: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
17
- readonly level: v.OptionalSchema<v.PicklistSchema<["audit", "fatal", "error", "warn", "info", "debug", "trace", "silent"], undefined>, undefined>;
18
- readonly serviceName: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
19
- /**
20
- * The explicit environment name used to resolve conditional transports (e.g. 'development', 'production').
21
- * @default 'development'
22
- */
23
- readonly environment: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
24
- /**
25
- * Pool of transports by name. Use together with `env` to pick per-environment defaults.
26
- * When both transportList and env are set, this form is used instead of `transports`.
27
- */
28
- readonly transportList: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>, undefined>, undefined>;
29
- /**
30
- * Per-environment list of transport names (keys from transportList) to use as default.
31
- * E.g. { development: ['consola'], production: ['consola', 'db'] }.
32
- * Used only when transportList is also set.
33
- */
34
- readonly env: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>, undefined>;
35
- /**
36
- * Legacy: array of transport instances or descriptors { transport, env? },
37
- * or a mapping of logger names (categories) to such arrays.
38
- * Ignored when both transportList and env are set.
39
- */
40
- readonly transports: v.OptionalSchema<v.UnionSchema<[v.ArraySchema<v.UnionSchema<[v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>, v.ObjectSchema<{
41
- readonly transport: v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>;
42
- /** When set, the transport is only enabled when the environment (e.g. NODE_ENV) is in this list. */
43
- readonly env: v.OptionalSchema<v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>], undefined>, undefined>;
44
- }, undefined>], undefined>, undefined>, v.RecordSchema<v.StringSchema<undefined>, v.ArraySchema<v.UnionSchema<[v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>, v.ObjectSchema<{
45
- readonly transport: v.CustomSchema<Transport, v.ErrorMessage<v.CustomIssue> | undefined>;
46
- /** When set, the transport is only enabled when the environment (e.g. NODE_ENV) is in this list. */
47
- readonly env: v.OptionalSchema<v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>], undefined>, undefined>;
48
- }, undefined>], undefined>, undefined>, undefined>], undefined>, undefined>;
49
- /**
50
- * The maximum time in milliseconds a custom serializer can run before being timed out.
51
- * @default 50
52
- */
53
- readonly serializerTimeoutMs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, 50>;
54
- /** Configuration for pretty printing logs in development. */
55
- readonly prettyPrint: v.OptionalSchema<v.ObjectSchema<{
56
- readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
57
- }, undefined>, undefined>;
58
- }, undefined>, undefined>;
59
- /** Declarative matrix to control context data in logs. */
60
- readonly loggingMatrix: v.OptionalSchema<v.ObjectSchema<{
61
- /** An array of context keys to include in logs by default. Can be overridden by level-specific rules. */
62
- readonly default: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
63
- /** An array of context keys to include for 'trace' level logs. Use `['*']` to include all context properties. */
64
- readonly trace: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
65
- /** An array of context keys to include for 'debug' level logs. Use `['*']` to include all context properties. */
66
- readonly debug: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
67
- /** An array of context keys to include for 'info' level logs. Use `['*']` to include all context properties. */
68
- readonly info: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
69
- /** An array of context keys to include for 'warn' level logs. Use `['*']` to include all context properties. */
70
- readonly warn: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
71
- /** An array of context keys to include for 'error' level logs. Use `['*']` to include all context properties. */
72
- readonly error: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
73
- /** An array of context keys to include for 'fatal' level logs. Use `['*']` to include all context properties. */
74
- readonly fatal: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
75
- }, undefined>, undefined>;
76
- /** Centralized data masking configuration. */
77
- readonly masking: v.OptionalSchema<v.ObjectSchema<{
78
- /** Array of masking rules with patterns and strategies. */
79
- readonly rules: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
80
- /** Regex pattern to match field names */
81
- readonly pattern: v.UnionSchema<[v.StringSchema<undefined>, v.InstanceSchema<RegExpConstructor, undefined>], undefined>;
82
- /** Masking strategy to apply */
83
- readonly strategy: v.EnumSchema<typeof MaskingStrategy, undefined>;
84
- /** Whether to preserve original length */
85
- readonly preserveLength: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
86
- /** Character to use for masking */
87
- readonly maskChar: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
88
- /** Custom masking function (for CUSTOM strategy) */
89
- readonly customMask: v.OptionalSchema<v.CustomSchema<(val: string) => string, v.ErrorMessage<v.CustomIssue> | undefined>, undefined>;
90
- }, undefined>, undefined>, undefined>;
91
- /** Default mask character */
92
- readonly maskChar: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
93
- /** Whether to preserve original length by default */
94
- readonly preserveLength: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
95
- /** Enable default rules for common data types */
96
- readonly enableDefaultRules: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
97
- /**
98
- * Max ms for evaluating each custom rule regex; if exceeded, no match and a warning is logged.
99
- * @default 100
100
- */
101
- readonly regexTimeoutMs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, 100>;
102
- }, undefined>, undefined>;
103
- /** Context propagation configuration. */
104
- readonly context: v.OptionalSchema<v.ObjectSchema<{
105
- /** The HTTP header name to use for the correlation ID. @default 'x-correlation-id' */
106
- readonly correlationIdHeader: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
107
- /** The HTTP header name to use for the external transaction/trace ID. @default 'x-trace-id' */
108
- readonly transactionIdHeader: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
109
- }, undefined>, undefined>;
110
- /**
111
- * The maximum time in milliseconds to wait for a graceful shutdown before timing out.
112
- * @default 5000
113
- */
114
- readonly shutdownTimeout: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "The maximum time in ms to wait for a graceful shutdown.">]>, undefined>;
115
- }, undefined>;
8
+ import { MaskingStrategy, MaskingRule } from './masking/MaskingEngine';
9
+ export interface TransportDescriptor {
10
+ transport: Transport;
11
+ env?: string | string[];
12
+ }
13
+ export type TransportEntry = Transport | TransportDescriptor;
14
+ export interface LoggerOptions {
15
+ name?: string;
16
+ level?: 'audit' | 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent';
17
+ serviceName?: string;
18
+ environment?: string;
19
+ transportList?: Record<string, Transport>;
20
+ env?: Record<string, string[]>;
21
+ transports?: TransportEntry[] | Record<string, TransportEntry[]>;
22
+ serializerTimeoutMs?: number;
23
+ prettyPrint?: {
24
+ enabled?: boolean;
25
+ };
26
+ }
27
+ export interface MaskingConfig {
28
+ rules?: MaskingRule[];
29
+ maskChar?: string;
30
+ preserveLength?: boolean;
31
+ enableDefaultRules?: boolean;
32
+ regexTimeoutMs?: number;
33
+ }
34
+ export interface LoggingMatrixConfig {
35
+ default?: string[];
36
+ trace?: string[];
37
+ debug?: string[];
38
+ info?: string[];
39
+ warn?: string[];
40
+ error?: string[];
41
+ fatal?: string[];
42
+ [key: string]: string[] | undefined;
43
+ }
44
+ export interface ContextConfig {
45
+ correlationIdHeader?: string;
46
+ transactionIdHeader?: string;
47
+ [key: string]: string | undefined;
48
+ }
49
+ export interface SyntropyLogConfig {
50
+ logger?: LoggerOptions;
51
+ loggingMatrix?: LoggingMatrixConfig;
52
+ masking?: MaskingConfig;
53
+ context?: ContextConfig;
54
+ shutdownTimeout?: number;
55
+ }
56
+ export { MaskingStrategy, Transport };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "syntropylog",
3
- "version": "0.9.20",
3
+ "version": "0.10.0",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },
@@ -139,8 +139,7 @@
139
139
  "provenance": true
140
140
  },
141
141
  "dependencies": {
142
- "js-yaml": "^4.1.1",
143
- "valibot": "^1.2.0"
142
+ "js-yaml": "^4.1.1"
144
143
  },
145
144
  "devDependencies": {
146
145
  "@changesets/cli": "^2.27.1",
@@ -148,7 +147,7 @@
148
147
  "@rollup/plugin-commonjs": "^28.0.2",
149
148
  "@rollup/plugin-json": "^6.1.0",
150
149
  "@rollup/plugin-node-resolve": "^16.0.0",
151
- "@rollup/plugin-terser": "^0.4.4",
150
+ "@rollup/plugin-terser": "^1.0.0",
152
151
  "@rollup/plugin-typescript": "^12.1.2",
153
152
  "@types/js-yaml": "^4.0.9",
154
153
  "@types/node": "^22.13.5",