evlog 2.0.0 → 2.1.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.
Files changed (52) hide show
  1. package/dist/{_severity-D_IU9-90.mjs → _severity-78FkT5MD.mjs} +1 -1
  2. package/dist/{_severity-D_IU9-90.mjs.map → _severity-78FkT5MD.mjs.map} +1 -1
  3. package/dist/adapters/axiom.d.mts +0 -2
  4. package/dist/adapters/axiom.d.mts.map +1 -1
  5. package/dist/adapters/better-stack.d.mts +0 -2
  6. package/dist/adapters/better-stack.d.mts.map +1 -1
  7. package/dist/adapters/otlp.d.mts +0 -2
  8. package/dist/adapters/otlp.d.mts.map +1 -1
  9. package/dist/adapters/otlp.mjs +1 -1
  10. package/dist/adapters/posthog.d.mts +0 -2
  11. package/dist/adapters/posthog.d.mts.map +1 -1
  12. package/dist/adapters/sentry.d.mts +0 -2
  13. package/dist/adapters/sentry.d.mts.map +1 -1
  14. package/dist/adapters/sentry.mjs +1 -1
  15. package/dist/dist-By0jiJRA.mjs +52 -0
  16. package/dist/dist-By0jiJRA.mjs.map +1 -0
  17. package/dist/index.d.mts +2 -2
  18. package/dist/index.mjs +2 -2
  19. package/dist/logger.d.mts +14 -1
  20. package/dist/logger.d.mts.map +1 -1
  21. package/dist/logger.mjs +29 -14
  22. package/dist/logger.mjs.map +1 -1
  23. package/dist/next/client.d.mts +8 -0
  24. package/dist/next/client.d.mts.map +1 -1
  25. package/dist/next/client.mjs +3 -1
  26. package/dist/next/client.mjs.map +1 -1
  27. package/dist/next/index.d.mts +0 -1
  28. package/dist/next/index.d.mts.map +1 -1
  29. package/dist/nitro/module.d.mts +3 -2
  30. package/dist/nitro/module.d.mts.map +1 -1
  31. package/dist/nitro/module.mjs +1 -0
  32. package/dist/nitro/module.mjs.map +1 -1
  33. package/dist/nitro/v3/errorHandler.mjs +1 -1
  34. package/dist/nitro/v3/index.d.mts +0 -1
  35. package/dist/nitro/v3/module.d.mts +3 -2
  36. package/dist/nitro/v3/module.d.mts.map +1 -1
  37. package/dist/nitro/v3/module.mjs +2 -0
  38. package/dist/nitro/v3/module.mjs.map +1 -1
  39. package/dist/nitro/v3/plugin.mjs +1 -1
  40. package/dist/{nitro-CrFBjY1Y.d.mts → nitro-mfub2f8G.d.mts} +1 -1
  41. package/dist/{nitro-CrFBjY1Y.d.mts.map → nitro-mfub2f8G.d.mts.map} +1 -1
  42. package/dist/nuxt/module.d.mts +7 -0
  43. package/dist/nuxt/module.d.mts.map +1 -1
  44. package/dist/nuxt/module.mjs +2 -1
  45. package/dist/nuxt/module.mjs.map +1 -1
  46. package/dist/runtime/client/log.d.mts +1 -0
  47. package/dist/runtime/client/log.d.mts.map +1 -1
  48. package/dist/runtime/client/log.mjs +10 -6
  49. package/dist/runtime/client/log.mjs.map +1 -1
  50. package/dist/runtime/client/plugin.mjs +1 -0
  51. package/dist/runtime/client/plugin.mjs.map +1 -1
  52. package/package.json +2 -2
@@ -14,4 +14,4 @@ const OTEL_SEVERITY_TEXT = {
14
14
 
15
15
  //#endregion
16
16
  export { OTEL_SEVERITY_TEXT as n, OTEL_SEVERITY_NUMBER as t };
17
- //# sourceMappingURL=_severity-D_IU9-90.mjs.map
17
+ //# sourceMappingURL=_severity-78FkT5MD.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_severity-D_IU9-90.mjs","names":[],"sources":["../src/adapters/_severity.ts"],"sourcesContent":["import type { LogLevel } from '../types'\n\nexport const OTEL_SEVERITY_NUMBER: Record<LogLevel, number> = {\n debug: 5,\n info: 9,\n warn: 13,\n error: 17,\n}\n\nexport const OTEL_SEVERITY_TEXT: Record<LogLevel, string> = {\n debug: 'DEBUG',\n info: 'INFO',\n warn: 'WARN',\n error: 'ERROR',\n}\n"],"mappings":";AAEA,MAAa,uBAAiD;CAC5D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR;AAED,MAAa,qBAA+C;CAC1D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR"}
1
+ {"version":3,"file":"_severity-78FkT5MD.mjs","names":[],"sources":["../src/adapters/_severity.ts"],"sourcesContent":["import type { LogLevel } from '../types'\n\nexport const OTEL_SEVERITY_NUMBER: Record<LogLevel, number> = {\n debug: 5,\n info: 9,\n warn: 13,\n error: 17,\n}\n\nexport const OTEL_SEVERITY_TEXT: Record<LogLevel, string> = {\n debug: 'DEBUG',\n info: 'INFO',\n warn: 'WARN',\n error: 'ERROR',\n}\n"],"mappings":";AAEA,MAAa,uBAAiD;CAC5D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR;AAED,MAAa,qBAA+C;CAC1D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR"}
@@ -1,6 +1,4 @@
1
1
  import { DrainContext, WideEvent } from "../types.mjs";
2
- import "../index.mjs";
3
-
4
2
  //#region src/adapters/axiom.d.ts
5
3
  interface BaseAxiomConfig {
6
4
  /** Axiom dataset name */
@@ -1 +1 @@
1
- {"version":3,"file":"axiom.d.mts","names":[],"sources":["../../src/adapters/axiom.ts"],"mappings":";;;;UAMU,eAAA;;EAER,OAAA;EAFQ;EAIR,KAAA;;EAEA,KAAA;EAJA;EAMA,OAAA;AAAA;AAAA,UAGQ,eAAA;EAHD;;AAAA;;;EASP,OAAA;EAEO;EAAP,OAAA;AAAA;AAAA,UAGQ,mBAAA;EAER;EAAA,OAAA;EAKU;EAHV,OAAA;AAAA;AAAA,KAGU,WAAA,GAAc,eAAA,IAAmB,eAAA,GAAkB,mBAAA;;;;;;;;;;AAoC/D;;;;;;;;;;;iBAAgB,gBAAA,CAAiB,SAAA,GAAY,OAAA,CAAQ,WAAA,KAAY,GAAA,EAAb,YAAA,GAAa,YAAA,OAAA,OAAA;;;;;;;;AAoCjE;;;;iBAAsB,WAAA,CAAY,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,WAAA,GAAc,OAAA;;;;;;;;;;;AAe1E;iBAAsB,gBAAA,CAAiB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,WAAA,GAAc,OAAA"}
1
+ {"version":3,"file":"axiom.d.mts","names":[],"sources":["../../src/adapters/axiom.ts"],"mappings":";;UAMU,eAAA;;EAER,OAAA;EAFQ;EAIR,KAAA;;EAEA,KAAA;EAJA;EAMA,OAAA;AAAA;AAAA,UAGQ,eAAA;EAHD;;AAAA;;;EASP,OAAA;EAEO;EAAP,OAAA;AAAA;AAAA,UAGQ,mBAAA;EAER;EAAA,OAAA;EAKU;EAHV,OAAA;AAAA;AAAA,KAGU,WAAA,GAAc,eAAA,IAAmB,eAAA,GAAkB,mBAAA;;;;;;;;;;AAoC/D;;;;;;;;;;;iBAAgB,gBAAA,CAAiB,SAAA,GAAY,OAAA,CAAQ,WAAA,KAAY,GAAA,EAAb,YAAA,GAAa,YAAA,OAAA,OAAA;;;;;;;;AAoCjE;;;;iBAAsB,WAAA,CAAY,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,WAAA,GAAc,OAAA;;;;;;;;;;;AAe1E;iBAAsB,gBAAA,CAAiB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,WAAA,GAAc,OAAA"}
@@ -1,6 +1,4 @@
1
1
  import { DrainContext, WideEvent } from "../types.mjs";
2
- import "../index.mjs";
3
-
4
2
  //#region src/adapters/better-stack.d.ts
5
3
  interface BetterStackConfig {
6
4
  /** Better Stack source token */
@@ -1 +1 @@
1
- {"version":3,"file":"better-stack.d.mts","names":[],"sources":["../../src/adapters/better-stack.ts"],"mappings":";;;;UAMiB,iBAAA;;EAEf,WAAA;EAFe;EAIf,QAAA;;EAEA,OAAA;AAAA;;;;;iBAac,kBAAA,CAAmB,KAAA,EAAO,SAAA,GAAY,MAAA;;;;;;;;;AAyBtD;;;;;;;;;;;;iBAAgB,sBAAA,CAAuB,SAAA,GAAY,OAAA,CAAQ,iBAAA,KAAkB,GAAA,EAAnB,YAAA,GAAmB,YAAA,OAAA,OAAA;;;;;;;AAyB7E;;;;iBAAsB,iBAAA,CAAkB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,iBAAA,GAAoB,OAAA;;;;;;;;;;;iBAchE,sBAAA,CAAuB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,iBAAA,GAAoB,OAAA"}
1
+ {"version":3,"file":"better-stack.d.mts","names":[],"sources":["../../src/adapters/better-stack.ts"],"mappings":";;UAMiB,iBAAA;;EAEf,WAAA;EAFe;EAIf,QAAA;;EAEA,OAAA;AAAA;;;;;iBAac,kBAAA,CAAmB,KAAA,EAAO,SAAA,GAAY,MAAA;;;;;;;;;AAyBtD;;;;;;;;;;;;iBAAgB,sBAAA,CAAuB,SAAA,GAAY,OAAA,CAAQ,iBAAA,KAAkB,GAAA,EAAnB,YAAA,GAAmB,YAAA,OAAA,OAAA;;;;;;;AAyB7E;;;;iBAAsB,iBAAA,CAAkB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,iBAAA,GAAoB,OAAA;;;;;;;;;;;iBAchE,sBAAA,CAAuB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,iBAAA,GAAoB,OAAA"}
@@ -1,6 +1,4 @@
1
1
  import { DrainContext, WideEvent } from "../types.mjs";
2
- import "../index.mjs";
3
-
4
2
  //#region src/adapters/otlp.d.ts
5
3
  interface OTLPConfig {
6
4
  /** OTLP HTTP endpoint (e.g., http://localhost:4318) */
@@ -1 +1 @@
1
- {"version":3,"file":"otlp.d.mts","names":[],"sources":["../../src/adapters/otlp.ts"],"mappings":";;;;UAOiB,UAAA;;EAEf,QAAA;EAFe;EAIf,WAAA;;EAEA,kBAAA,GAAqB,MAAA;EAJrB;EAMA,OAAA,GAAU,MAAA;EAFV;EAIA,OAAA;AAAA;;UAIe,aAAA;EACf,YAAA;EACA,cAAA;EACA,YAAA;EACA,IAAA;IAAQ,WAAA;EAAA;EACR,UAAA,EAAY,KAAA;IACV,GAAA;IACA,KAAA;MAAS,WAAA;MAAsB,QAAA;MAAmB,SAAA;IAAA;EAAA;EAEpD,OAAA;EACA,MAAA;AAAA;;;;iBAwDc,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAY,aAAA;;AAAnD;;;;;;;;;AA0JA;;;;;;;;;;iBAAgB,eAAA,CAAgB,SAAA,GAAY,OAAA,CAAQ,UAAA,KAAW,GAAA,EAAZ,YAAA,GAAY,YAAA,OAAA,OAAA;;;;;;;;;AA+B/D;;iBAAsB,UAAA,CAAW,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,UAAA,GAAa,OAAA;;;;;;;;;;;iBAclD,eAAA,CAAgB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,UAAA,GAAa,OAAA"}
1
+ {"version":3,"file":"otlp.d.mts","names":[],"sources":["../../src/adapters/otlp.ts"],"mappings":";;UAOiB,UAAA;;EAEf,QAAA;EAFe;EAIf,WAAA;;EAEA,kBAAA,GAAqB,MAAA;EAJrB;EAMA,OAAA,GAAU,MAAA;EAFV;EAIA,OAAA;AAAA;;UAIe,aAAA;EACf,YAAA;EACA,cAAA;EACA,YAAA;EACA,IAAA;IAAQ,WAAA;EAAA;EACR,UAAA,EAAY,KAAA;IACV,GAAA;IACA,KAAA;MAAS,WAAA;MAAsB,QAAA;MAAmB,SAAA;IAAA;EAAA;EAEpD,OAAA;EACA,MAAA;AAAA;;;;iBAwDc,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAY,aAAA;;AAAnD;;;;;;;;;AA0JA;;;;;;;;;;iBAAgB,eAAA,CAAgB,SAAA,GAAY,OAAA,CAAQ,UAAA,KAAW,GAAA,EAAZ,YAAA,GAAY,YAAA,OAAA,OAAA;;;;;;;;;AA+B/D;;iBAAsB,UAAA,CAAW,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,UAAA,GAAa,OAAA;;;;;;;;;;;iBAclD,eAAA,CAAgB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,UAAA,GAAa,OAAA"}
@@ -1,5 +1,5 @@
1
1
  import { n as defineDrain, r as resolveAdapterConfig, t as httpPost } from "../_http-DVDwNag0.mjs";
2
- import { n as OTEL_SEVERITY_TEXT, t as OTEL_SEVERITY_NUMBER } from "../_severity-D_IU9-90.mjs";
2
+ import { n as OTEL_SEVERITY_TEXT, t as OTEL_SEVERITY_NUMBER } from "../_severity-78FkT5MD.mjs";
3
3
 
4
4
  //#region src/adapters/otlp.ts
5
5
  const OTLP_FIELDS = [
@@ -1,6 +1,4 @@
1
1
  import { DrainContext, WideEvent } from "../types.mjs";
2
- import "../index.mjs";
3
-
4
2
  //#region src/adapters/posthog.d.ts
5
3
  interface PostHogConfig {
6
4
  /** PostHog project API key */
@@ -1 +1 @@
1
- {"version":3,"file":"posthog.d.mts","names":[],"sources":["../../src/adapters/posthog.ts"],"mappings":";;;;UAQiB,aAAA;;EAEf,MAAA;EAFe;EAIf,IAAA;;EAEA,OAAA;AAAA;AAAA,UAGe,mBAAA,SAA4B,aAAA;EAH3C;EAKA,SAAA;EALO;EAOP,UAAA;AAAA;;UAIe,YAAA;EACf,KAAA;EACA,WAAA;EACA,SAAA;EACA,UAAA,EAAY,MAAA;AAAA;AAJd;;;AAAA,iBAmCgB,cAAA,CAAe,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,mBAAA,GAAsB,YAAA;;;;;;;;AAA/E;;;;;;;;;;;;;;iBAwCgB,kBAAA,CAAmB,SAAA,GAAY,OAAA,CAAQ,aAAA,KAAc,GAAA,EAAf,YAAA,GAAe,YAAA,OAAA,OAAA;AAArE;;;;;;;;;;AAAA,iBAyBsB,aAAA,CAAc,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;;;;;;AAA9E;;iBAcsB,kBAAA,CAAmB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;;;;;;;;;;AAAtF;;;;;;;iBA4BgB,wBAAA,CAAyB,SAAA,GAAY,OAAA,CAAQ,mBAAA,KAAoB,GAAA,EAArB,YAAA,GAAqB,YAAA,OAAA,OAAA;;;;;;;;AAAjF;;;iBAyBsB,mBAAA,CAAoB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,mBAAA,GAAsB,OAAA;;;;;;;;;;;iBAcpE,wBAAA,CAAyB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,mBAAA,GAAsB,OAAA"}
1
+ {"version":3,"file":"posthog.d.mts","names":[],"sources":["../../src/adapters/posthog.ts"],"mappings":";;UAQiB,aAAA;;EAEf,MAAA;EAFe;EAIf,IAAA;;EAEA,OAAA;AAAA;AAAA,UAGe,mBAAA,SAA4B,aAAA;EAH3C;EAKA,SAAA;EALO;EAOP,UAAA;AAAA;;UAIe,YAAA;EACf,KAAA;EACA,WAAA;EACA,SAAA;EACA,UAAA,EAAY,MAAA;AAAA;AAJd;;;AAAA,iBAmCgB,cAAA,CAAe,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,mBAAA,GAAsB,YAAA;;;;;;;;AAA/E;;;;;;;;;;;;;;iBAwCgB,kBAAA,CAAmB,SAAA,GAAY,OAAA,CAAQ,aAAA,KAAc,GAAA,EAAf,YAAA,GAAe,YAAA,OAAA,OAAA;AAArE;;;;;;;;;;AAAA,iBAyBsB,aAAA,CAAc,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;;;;;;AAA9E;;iBAcsB,kBAAA,CAAmB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;;;;;;;;;;AAAtF;;;;;;;iBA4BgB,wBAAA,CAAyB,SAAA,GAAY,OAAA,CAAQ,mBAAA,KAAoB,GAAA,EAArB,YAAA,GAAqB,YAAA,OAAA,OAAA;;;;;;;;AAAjF;;;iBAyBsB,mBAAA,CAAoB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,mBAAA,GAAsB,OAAA;;;;;;;;;;;iBAcpE,wBAAA,CAAyB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,mBAAA,GAAsB,OAAA"}
@@ -1,6 +1,4 @@
1
1
  import { DrainContext, WideEvent } from "../types.mjs";
2
- import "../index.mjs";
3
-
4
2
  //#region src/adapters/sentry.d.ts
5
3
  interface SentryConfig {
6
4
  /** Sentry DSN */
@@ -1 +1 @@
1
- {"version":3,"file":"sentry.d.mts","names":[],"sources":["../../src/adapters/sentry.ts"],"mappings":";;;;UAOiB,YAAA;;EAEf,GAAA;EAFe;EAIf,WAAA;;EAEA,OAAA;EAJA;EAMA,IAAA,GAAO,MAAA;EAFP;EAIA,OAAA;AAAA;;UAIe,oBAAA;EACf,KAAA;EACA,IAAA;AAAA;;UAIe,SAAA;EACf,SAAA;EACA,QAAA;EACA,KAAA;EACA,IAAA;EACA,eAAA;EACA,UAAA,GAAa,MAAA,SAAe,oBAAA;AAAA;AAAA,iBA0Fd,WAAA,CAAY,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,YAAA,GAAe,SAAA;;;;;;;;AAArE;;;;;;;;;;;;;;;AAiGA;iBAAgB,iBAAA,CAAkB,SAAA,GAAY,OAAA,CAAQ,YAAA,KAAa,GAAA,EAAd,YAAA,GAAc,YAAA,OAAA,OAAA;;;;;;;;;;;iBAyB7C,YAAA,CAAa,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,YAAA,GAAe,OAAA;;;;;;;AAA5E;;;;iBAcsB,iBAAA,CAAkB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,YAAA,GAAe,OAAA"}
1
+ {"version":3,"file":"sentry.d.mts","names":[],"sources":["../../src/adapters/sentry.ts"],"mappings":";;UAOiB,YAAA;;EAEf,GAAA;EAFe;EAIf,WAAA;;EAEA,OAAA;EAJA;EAMA,IAAA,GAAO,MAAA;EAFP;EAIA,OAAA;AAAA;;UAIe,oBAAA;EACf,KAAA;EACA,IAAA;AAAA;;UAIe,SAAA;EACf,SAAA;EACA,QAAA;EACA,KAAA;EACA,IAAA;EACA,eAAA;EACA,UAAA,GAAa,MAAA,SAAe,oBAAA;AAAA;AAAA,iBA0Fd,WAAA,CAAY,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,YAAA,GAAe,SAAA;;;;;;;;AAArE;;;;;;;;;;;;;;;AAiGA;iBAAgB,iBAAA,CAAkB,SAAA,GAAY,OAAA,CAAQ,YAAA,KAAa,GAAA,EAAd,YAAA,GAAc,YAAA,OAAA,OAAA;;;;;;;;;;;iBAyB7C,YAAA,CAAa,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,YAAA,GAAe,OAAA;;;;;;;AAA5E;;;;iBAcsB,iBAAA,CAAkB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,YAAA,GAAe,OAAA"}
@@ -1,5 +1,5 @@
1
1
  import { n as defineDrain, r as resolveAdapterConfig, t as httpPost } from "../_http-DVDwNag0.mjs";
2
- import { t as OTEL_SEVERITY_NUMBER } from "../_severity-D_IU9-90.mjs";
2
+ import { t as OTEL_SEVERITY_NUMBER } from "../_severity-78FkT5MD.mjs";
3
3
 
4
4
  //#region src/adapters/sentry.ts
5
5
  const SENTRY_FIELDS = [
@@ -0,0 +1,52 @@
1
+ //#region ../../node_modules/ufo/dist/index.mjs
2
+ const r = String.fromCharCode;
3
+ const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/;
4
+ const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/;
5
+ const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
6
+ function hasProtocol(inputString, opts = {}) {
7
+ if (typeof opts === "boolean") opts = { acceptRelative: opts };
8
+ if (opts.strict) return PROTOCOL_STRICT_REGEX.test(inputString);
9
+ return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
10
+ }
11
+ const protocolRelative = Symbol.for("ufo:protocolRelative");
12
+ function parseURL(input = "", defaultProto) {
13
+ const _specialProtoMatch = input.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);
14
+ if (_specialProtoMatch) {
15
+ const [, _proto, _pathname = ""] = _specialProtoMatch;
16
+ return {
17
+ protocol: _proto.toLowerCase(),
18
+ pathname: _pathname,
19
+ href: _proto + _pathname,
20
+ auth: "",
21
+ host: "",
22
+ search: "",
23
+ hash: ""
24
+ };
25
+ }
26
+ if (!hasProtocol(input, { acceptRelative: true })) return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
27
+ const [, protocol = "", auth, hostAndPath = ""] = input.replace(/\\/g, "/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/) || [];
28
+ let [, host = "", path = ""] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];
29
+ if (protocol === "file:") path = path.replace(/\/(?=[A-Za-z]:)/, "");
30
+ const { pathname, search, hash } = parsePath(path);
31
+ return {
32
+ protocol: protocol.toLowerCase(),
33
+ auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
34
+ host,
35
+ pathname,
36
+ search,
37
+ hash,
38
+ [protocolRelative]: !protocol
39
+ };
40
+ }
41
+ function parsePath(input = "") {
42
+ const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
43
+ return {
44
+ pathname,
45
+ search,
46
+ hash
47
+ };
48
+ }
49
+
50
+ //#endregion
51
+ export { parseURL as t };
52
+ //# sourceMappingURL=dist-By0jiJRA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dist-By0jiJRA.mjs","names":[],"sources":["../../../node_modules/ufo/dist/index.mjs"],"sourcesContent":["const n = /[^\\0-\\x7E]/;\nconst t = /[\\x2E\\u3002\\uFF0E\\uFF61]/g;\nconst o = {\n overflow: \"Overflow Error\",\n \"not-basic\": \"Illegal Input\",\n \"invalid-input\": \"Invalid Input\"\n};\nconst e = Math.floor;\nconst r = String.fromCharCode;\nfunction s(n2) {\n throw new RangeError(o[n2]);\n}\nconst c = function(n2, t2) {\n return n2 + 22 + 75 * (n2 < 26) - ((t2 != 0) << 5);\n};\nconst u = function(n2, t2, o2) {\n let r2 = 0;\n for (n2 = o2 ? e(n2 / 700) : n2 >> 1, n2 += e(n2 / t2); n2 > 455; r2 += 36) {\n n2 = e(n2 / 35);\n }\n return e(r2 + 36 * n2 / (n2 + 38));\n};\nfunction toASCII(o2) {\n return (function(n2, o3) {\n const e2 = n2.split(\"@\");\n let r2 = \"\";\n e2.length > 1 && (r2 = e2[0] + \"@\", n2 = e2[1]);\n const s2 = (function(n3, t2) {\n const o4 = [];\n let e3 = n3.length;\n for (; e3--; ) {\n o4[e3] = t2(n3[e3]);\n }\n return o4;\n })((n2 = n2.replace(t, \".\")).split(\".\"), o3).join(\".\");\n return r2 + s2;\n })(o2, function(t2) {\n return n.test(t2) ? \"xn--\" + (function(n2) {\n const t3 = [];\n const o3 = (n2 = (function(n3) {\n const t4 = [];\n let o4 = 0;\n const e2 = n3.length;\n for (; o4 < e2; ) {\n const r2 = n3.charCodeAt(o4++);\n if (r2 >= 55296 && r2 <= 56319 && o4 < e2) {\n const e3 = n3.charCodeAt(o4++);\n (64512 & e3) == 56320 ? t4.push(((1023 & r2) << 10) + (1023 & e3) + 65536) : (t4.push(r2), o4--);\n } else {\n t4.push(r2);\n }\n }\n return t4;\n })(n2)).length;\n let f = 128;\n let i = 0;\n let l = 72;\n for (const o4 of n2) {\n o4 < 128 && t3.push(r(o4));\n }\n const h = t3.length;\n let p = h;\n for (h && t3.push(\"-\"); p < o3; ) {\n let o4 = 2147483647;\n for (const t4 of n2) {\n t4 >= f && t4 < o4 && (o4 = t4);\n }\n const a = p + 1;\n o4 - f > e((2147483647 - i) / a) && s(\"overflow\"), i += (o4 - f) * a, f = o4;\n for (const o5 of n2) {\n if (o5 < f && ++i > 2147483647 && s(\"overflow\"), o5 == f) {\n let n3 = i;\n for (let o6 = 36; ; o6 += 36) {\n const s2 = o6 <= l ? 1 : o6 >= l + 26 ? 26 : o6 - l;\n if (n3 < s2) {\n break;\n }\n const u2 = n3 - s2;\n const f2 = 36 - s2;\n t3.push(r(c(s2 + u2 % f2, 0))), n3 = e(u2 / f2);\n }\n t3.push(r(c(n3, 0))), l = u(i, a, p == h), i = 0, ++p;\n }\n }\n ++i, ++f;\n }\n return t3.join(\"\");\n })(t2) : t2;\n });\n}\n\nconst HASH_RE = /#/g;\nconst AMPERSAND_RE = /&/g;\nconst SLASH_RE = /\\//g;\nconst EQUAL_RE = /=/g;\nconst IM_RE = /\\?/g;\nconst PLUS_RE = /\\+/g;\nconst ENC_CARET_RE = /%5e/gi;\nconst ENC_BACKTICK_RE = /%60/gi;\nconst ENC_CURLY_OPEN_RE = /%7b/gi;\nconst ENC_PIPE_RE = /%7c/gi;\nconst ENC_CURLY_CLOSE_RE = /%7d/gi;\nconst ENC_SPACE_RE = /%20/gi;\nconst ENC_SLASH_RE = /%2f/gi;\nconst ENC_ENC_SLASH_RE = /%252f/gi;\nfunction encode(text) {\n return encodeURI(\"\" + text).replace(ENC_PIPE_RE, \"|\");\n}\nfunction encodeHash(text) {\n return encode(text).replace(ENC_CURLY_OPEN_RE, \"{\").replace(ENC_CURLY_CLOSE_RE, \"}\").replace(ENC_CARET_RE, \"^\");\n}\nfunction encodeQueryValue(input) {\n return encode(typeof input === \"string\" ? input : JSON.stringify(input)).replace(PLUS_RE, \"%2B\").replace(ENC_SPACE_RE, \"+\").replace(HASH_RE, \"%23\").replace(AMPERSAND_RE, \"%26\").replace(ENC_BACKTICK_RE, \"`\").replace(ENC_CARET_RE, \"^\").replace(SLASH_RE, \"%2F\");\n}\nfunction encodeQueryKey(text) {\n return encodeQueryValue(text).replace(EQUAL_RE, \"%3D\");\n}\nfunction encodePath(text) {\n return encode(text).replace(HASH_RE, \"%23\").replace(IM_RE, \"%3F\").replace(ENC_ENC_SLASH_RE, \"%2F\").replace(AMPERSAND_RE, \"%26\").replace(PLUS_RE, \"%2B\");\n}\nfunction encodeParam(text) {\n return encodePath(text).replace(SLASH_RE, \"%2F\");\n}\nfunction decode(text = \"\") {\n try {\n return decodeURIComponent(\"\" + text);\n } catch {\n return \"\" + text;\n }\n}\nfunction decodePath(text) {\n return decode(text.replace(ENC_SLASH_RE, \"%252F\"));\n}\nfunction decodeQueryKey(text) {\n return decode(text.replace(PLUS_RE, \" \"));\n}\nfunction decodeQueryValue(text) {\n return decode(text.replace(PLUS_RE, \" \"));\n}\nfunction encodeHost(name = \"\") {\n return toASCII(name);\n}\n\nfunction parseQuery(parametersString = \"\") {\n const object = /* @__PURE__ */ Object.create(null);\n if (parametersString[0] === \"?\") {\n parametersString = parametersString.slice(1);\n }\n for (const parameter of parametersString.split(\"&\")) {\n const s = parameter.match(/([^=]+)=?(.*)/) || [];\n if (s.length < 2) {\n continue;\n }\n const key = decodeQueryKey(s[1]);\n if (key === \"__proto__\" || key === \"constructor\") {\n continue;\n }\n const value = decodeQueryValue(s[2] || \"\");\n if (object[key] === void 0) {\n object[key] = value;\n } else if (Array.isArray(object[key])) {\n object[key].push(value);\n } else {\n object[key] = [object[key], value];\n }\n }\n return object;\n}\nfunction encodeQueryItem(key, value) {\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n value = String(value);\n }\n if (!value) {\n return encodeQueryKey(key);\n }\n if (Array.isArray(value)) {\n return value.map(\n (_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`\n ).join(\"&\");\n }\n return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;\n}\nfunction stringifyQuery(query) {\n return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join(\"&\");\n}\n\nconst PROTOCOL_STRICT_REGEX = /^[\\s\\w\\0+.-]{2,}:([/\\\\]{1,2})/;\nconst PROTOCOL_REGEX = /^[\\s\\w\\0+.-]{2,}:([/\\\\]{2})?/;\nconst PROTOCOL_RELATIVE_REGEX = /^([/\\\\]\\s*){2,}[^/\\\\]/;\nconst PROTOCOL_SCRIPT_RE = /^[\\s\\0]*(blob|data|javascript|vbscript):$/i;\nconst TRAILING_SLASH_RE = /\\/$|\\/\\?|\\/#/;\nconst JOIN_LEADING_SLASH_RE = /^\\.?\\//;\nfunction isRelative(inputString) {\n return [\"./\", \"../\"].some((string_) => inputString.startsWith(string_));\n}\nfunction hasProtocol(inputString, opts = {}) {\n if (typeof opts === \"boolean\") {\n opts = { acceptRelative: opts };\n }\n if (opts.strict) {\n return PROTOCOL_STRICT_REGEX.test(inputString);\n }\n return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);\n}\nfunction isScriptProtocol(protocol) {\n return !!protocol && PROTOCOL_SCRIPT_RE.test(protocol);\n}\nfunction hasTrailingSlash(input = \"\", respectQueryAndFragment) {\n if (!respectQueryAndFragment) {\n return input.endsWith(\"/\");\n }\n return TRAILING_SLASH_RE.test(input);\n}\nfunction withoutTrailingSlash(input = \"\", respectQueryAndFragment) {\n if (!respectQueryAndFragment) {\n return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || \"/\";\n }\n if (!hasTrailingSlash(input, true)) {\n return input || \"/\";\n }\n let path = input;\n let fragment = \"\";\n const fragmentIndex = input.indexOf(\"#\");\n if (fragmentIndex !== -1) {\n path = input.slice(0, fragmentIndex);\n fragment = input.slice(fragmentIndex);\n }\n const [s0, ...s] = path.split(\"?\");\n const cleanPath = s0.endsWith(\"/\") ? s0.slice(0, -1) : s0;\n return (cleanPath || \"/\") + (s.length > 0 ? `?${s.join(\"?\")}` : \"\") + fragment;\n}\nfunction withTrailingSlash(input = \"\", respectQueryAndFragment) {\n if (!respectQueryAndFragment) {\n return input.endsWith(\"/\") ? input : input + \"/\";\n }\n if (hasTrailingSlash(input, true)) {\n return input || \"/\";\n }\n let path = input;\n let fragment = \"\";\n const fragmentIndex = input.indexOf(\"#\");\n if (fragmentIndex !== -1) {\n path = input.slice(0, fragmentIndex);\n fragment = input.slice(fragmentIndex);\n if (!path) {\n return fragment;\n }\n }\n const [s0, ...s] = path.split(\"?\");\n return s0 + \"/\" + (s.length > 0 ? `?${s.join(\"?\")}` : \"\") + fragment;\n}\nfunction hasLeadingSlash(input = \"\") {\n return input.startsWith(\"/\");\n}\nfunction withoutLeadingSlash(input = \"\") {\n return (hasLeadingSlash(input) ? input.slice(1) : input) || \"/\";\n}\nfunction withLeadingSlash(input = \"\") {\n return hasLeadingSlash(input) ? input : \"/\" + input;\n}\nfunction cleanDoubleSlashes(input = \"\") {\n return input.split(\"://\").map((string_) => string_.replace(/\\/{2,}/g, \"/\")).join(\"://\");\n}\nfunction withBase(input, base) {\n if (isEmptyURL(base) || hasProtocol(input)) {\n return input;\n }\n const _base = withoutTrailingSlash(base);\n if (input.startsWith(_base)) {\n const nextChar = input[_base.length];\n if (!nextChar || nextChar === \"/\" || nextChar === \"?\") {\n return input;\n }\n }\n return joinURL(_base, input);\n}\nfunction withoutBase(input, base) {\n if (isEmptyURL(base)) {\n return input;\n }\n const _base = withoutTrailingSlash(base);\n if (!input.startsWith(_base)) {\n return input;\n }\n const nextChar = input[_base.length];\n if (nextChar && nextChar !== \"/\" && nextChar !== \"?\") {\n return input;\n }\n const trimmed = input.slice(_base.length);\n return trimmed[0] === \"/\" ? trimmed : \"/\" + trimmed;\n}\nfunction withQuery(input, query) {\n const parsed = parseURL(input);\n const mergedQuery = { ...parseQuery(parsed.search), ...query };\n parsed.search = stringifyQuery(mergedQuery);\n return stringifyParsedURL(parsed);\n}\nfunction filterQuery(input, predicate) {\n if (!input.includes(\"?\")) {\n return input;\n }\n const parsed = parseURL(input);\n const query = parseQuery(parsed.search);\n const filteredQuery = Object.fromEntries(\n Object.entries(query).filter(([key, value]) => predicate(key, value))\n );\n parsed.search = stringifyQuery(filteredQuery);\n return stringifyParsedURL(parsed);\n}\nfunction getQuery(input) {\n return parseQuery(parseURL(input).search);\n}\nfunction isEmptyURL(url) {\n return !url || url === \"/\";\n}\nfunction isNonEmptyURL(url) {\n return url && url !== \"/\";\n}\nfunction joinURL(base, ...input) {\n let url = base || \"\";\n for (const segment of input.filter((url2) => isNonEmptyURL(url2))) {\n if (url) {\n const _segment = segment.replace(JOIN_LEADING_SLASH_RE, \"\");\n url = withTrailingSlash(url) + _segment;\n } else {\n url = segment;\n }\n }\n return url;\n}\nfunction joinRelativeURL(..._input) {\n const JOIN_SEGMENT_SPLIT_RE = /\\/(?!\\/)/;\n const input = _input.filter(Boolean);\n const segments = [];\n let segmentsDepth = 0;\n for (const i of input) {\n if (!i || i === \"/\") {\n continue;\n }\n for (const [sindex, s] of i.split(JOIN_SEGMENT_SPLIT_RE).entries()) {\n if (!s || s === \".\") {\n continue;\n }\n if (s === \"..\") {\n if (segments.length === 1 && hasProtocol(segments[0])) {\n continue;\n }\n segments.pop();\n segmentsDepth--;\n continue;\n }\n if (sindex === 1 && segments[segments.length - 1]?.endsWith(\":/\")) {\n segments[segments.length - 1] += \"/\" + s;\n continue;\n }\n segments.push(s);\n segmentsDepth++;\n }\n }\n let url = segments.join(\"/\");\n if (segmentsDepth >= 0) {\n if (input[0]?.startsWith(\"/\") && !url.startsWith(\"/\")) {\n url = \"/\" + url;\n } else if (input[0]?.startsWith(\"./\") && !url.startsWith(\"./\")) {\n url = \"./\" + url;\n }\n } else {\n url = \"../\".repeat(-1 * segmentsDepth) + url;\n }\n if (input[input.length - 1]?.endsWith(\"/\") && !url.endsWith(\"/\")) {\n url += \"/\";\n }\n return url;\n}\nfunction withHttp(input) {\n return withProtocol(input, \"http://\");\n}\nfunction withHttps(input) {\n return withProtocol(input, \"https://\");\n}\nfunction withoutProtocol(input) {\n return withProtocol(input, \"\");\n}\nfunction withProtocol(input, protocol) {\n let match = input.match(PROTOCOL_REGEX);\n if (!match) {\n match = input.match(/^\\/{2,}/);\n }\n if (!match) {\n return protocol + input;\n }\n return protocol + input.slice(match[0].length);\n}\nfunction normalizeURL(input) {\n const parsed = parseURL(input);\n parsed.pathname = encodePath(decodePath(parsed.pathname));\n parsed.hash = encodeHash(decode(parsed.hash));\n parsed.host = encodeHost(decode(parsed.host));\n parsed.search = stringifyQuery(parseQuery(parsed.search));\n return stringifyParsedURL(parsed);\n}\nfunction resolveURL(base = \"\", ...inputs) {\n if (typeof base !== \"string\") {\n throw new TypeError(\n `URL input should be string received ${typeof base} (${base})`\n );\n }\n const filteredInputs = inputs.filter((input) => isNonEmptyURL(input));\n if (filteredInputs.length === 0) {\n return base;\n }\n const url = parseURL(base);\n for (const inputSegment of filteredInputs) {\n const urlSegment = parseURL(inputSegment);\n if (urlSegment.pathname) {\n url.pathname = withTrailingSlash(url.pathname) + withoutLeadingSlash(urlSegment.pathname);\n }\n if (urlSegment.hash && urlSegment.hash !== \"#\") {\n url.hash = urlSegment.hash;\n }\n if (urlSegment.search && urlSegment.search !== \"?\") {\n if (url.search && url.search !== \"?\") {\n const queryString = stringifyQuery({\n ...parseQuery(url.search),\n ...parseQuery(urlSegment.search)\n });\n url.search = queryString.length > 0 ? \"?\" + queryString : \"\";\n } else {\n url.search = urlSegment.search;\n }\n }\n }\n return stringifyParsedURL(url);\n}\nfunction isSamePath(p1, p2) {\n return decode(withoutTrailingSlash(p1)) === decode(withoutTrailingSlash(p2));\n}\nfunction isEqual(a, b, options = {}) {\n if (!options.trailingSlash) {\n a = withTrailingSlash(a);\n b = withTrailingSlash(b);\n }\n if (!options.leadingSlash) {\n a = withLeadingSlash(a);\n b = withLeadingSlash(b);\n }\n if (!options.encoding) {\n a = decode(a);\n b = decode(b);\n }\n return a === b;\n}\nfunction withFragment(input, hash) {\n if (!hash || hash === \"#\") {\n return input;\n }\n const parsed = parseURL(input);\n parsed.hash = hash === \"\" ? \"\" : \"#\" + encodeHash(hash);\n return stringifyParsedURL(parsed);\n}\nfunction withoutFragment(input) {\n return stringifyParsedURL({ ...parseURL(input), hash: \"\" });\n}\nfunction withoutHost(input) {\n const parsed = parseURL(input);\n return (parsed.pathname || \"/\") + parsed.search + parsed.hash;\n}\n\nconst protocolRelative = Symbol.for(\"ufo:protocolRelative\");\nfunction parseURL(input = \"\", defaultProto) {\n const _specialProtoMatch = input.match(\n /^[\\s\\0]*(blob:|data:|javascript:|vbscript:)(.*)/i\n );\n if (_specialProtoMatch) {\n const [, _proto, _pathname = \"\"] = _specialProtoMatch;\n return {\n protocol: _proto.toLowerCase(),\n pathname: _pathname,\n href: _proto + _pathname,\n auth: \"\",\n host: \"\",\n search: \"\",\n hash: \"\"\n };\n }\n if (!hasProtocol(input, { acceptRelative: true })) {\n return defaultProto ? parseURL(defaultProto + input) : parsePath(input);\n }\n const [, protocol = \"\", auth, hostAndPath = \"\"] = input.replace(/\\\\/g, \"/\").match(/^[\\s\\0]*([\\w+.-]{2,}:)?\\/\\/([^/@]+@)?(.*)/) || [];\n let [, host = \"\", path = \"\"] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];\n if (protocol === \"file:\") {\n path = path.replace(/\\/(?=[A-Za-z]:)/, \"\");\n }\n const { pathname, search, hash } = parsePath(path);\n return {\n protocol: protocol.toLowerCase(),\n auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : \"\",\n host,\n pathname,\n search,\n hash,\n [protocolRelative]: !protocol\n };\n}\nfunction parsePath(input = \"\") {\n const [pathname = \"\", search = \"\", hash = \"\"] = (input.match(/([^#?]*)(\\?[^#]*)?(#.*)?/) || []).splice(1);\n return {\n pathname,\n search,\n hash\n };\n}\nfunction parseAuth(input = \"\") {\n const [username, password] = input.split(\":\");\n return {\n username: decode(username),\n password: decode(password)\n };\n}\nfunction parseHost(input = \"\") {\n const [hostname, port] = (input.match(/([^/:]*):?(\\d+)?/) || []).splice(1);\n return {\n hostname: decode(hostname),\n port\n };\n}\nfunction stringifyParsedURL(parsed) {\n const pathname = parsed.pathname || \"\";\n const search = parsed.search ? (parsed.search.startsWith(\"?\") ? \"\" : \"?\") + parsed.search : \"\";\n const hash = parsed.hash || \"\";\n const auth = parsed.auth ? parsed.auth + \"@\" : \"\";\n const host = parsed.host || \"\";\n const proto = parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || \"\") + \"//\" : \"\";\n return proto + auth + host + pathname + search + hash;\n}\nconst FILENAME_STRICT_REGEX = /\\/([^/]+\\.[^/]+)$/;\nconst FILENAME_REGEX = /\\/([^/]+)$/;\nfunction parseFilename(input = \"\", opts) {\n const { pathname } = parseURL(input);\n const matches = opts?.strict ? pathname.match(FILENAME_STRICT_REGEX) : pathname.match(FILENAME_REGEX);\n return matches ? matches[1] : void 0;\n}\n\nclass $URL {\n protocol;\n host;\n auth;\n pathname;\n query = {};\n hash;\n constructor(input = \"\") {\n if (typeof input !== \"string\") {\n throw new TypeError(\n `URL input should be string received ${typeof input} (${input})`\n );\n }\n const parsed = parseURL(input);\n this.protocol = decode(parsed.protocol);\n this.host = decode(parsed.host);\n this.auth = decode(parsed.auth);\n this.pathname = decodePath(parsed.pathname);\n this.query = parseQuery(parsed.search);\n this.hash = decode(parsed.hash);\n }\n get hostname() {\n return parseHost(this.host).hostname;\n }\n get port() {\n return parseHost(this.host).port || \"\";\n }\n get username() {\n return parseAuth(this.auth).username;\n }\n get password() {\n return parseAuth(this.auth).password || \"\";\n }\n get hasProtocol() {\n return this.protocol.length;\n }\n get isAbsolute() {\n return this.hasProtocol || this.pathname[0] === \"/\";\n }\n get search() {\n const q = stringifyQuery(this.query);\n return q.length > 0 ? \"?\" + q : \"\";\n }\n get searchParams() {\n const p = new URLSearchParams();\n for (const name in this.query) {\n const value = this.query[name];\n if (Array.isArray(value)) {\n for (const v of value) {\n p.append(name, v);\n }\n } else {\n p.append(\n name,\n typeof value === \"string\" ? value : JSON.stringify(value)\n );\n }\n }\n return p;\n }\n get origin() {\n return (this.protocol ? this.protocol + \"//\" : \"\") + encodeHost(this.host);\n }\n get fullpath() {\n return encodePath(this.pathname) + this.search + encodeHash(this.hash);\n }\n get encodedAuth() {\n if (!this.auth) {\n return \"\";\n }\n const { username, password } = parseAuth(this.auth);\n return encodeURIComponent(username) + (password ? \":\" + encodeURIComponent(password) : \"\");\n }\n get href() {\n const auth = this.encodedAuth;\n const originWithAuth = (this.protocol ? this.protocol + \"//\" : \"\") + (auth ? auth + \"@\" : \"\") + encodeHost(this.host);\n return this.hasProtocol && this.isAbsolute ? originWithAuth + this.fullpath : this.fullpath;\n }\n append(url) {\n if (url.hasProtocol) {\n throw new Error(\"Cannot append a URL with protocol\");\n }\n Object.assign(this.query, url.query);\n if (url.pathname) {\n this.pathname = withTrailingSlash(this.pathname) + withoutLeadingSlash(url.pathname);\n }\n if (url.hash) {\n this.hash = url.hash;\n }\n }\n toJSON() {\n return this.href;\n }\n toString() {\n return this.href;\n }\n}\nfunction createURL(input) {\n return new $URL(input);\n}\n\nexport { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryKey, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, filterQuery, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, isScriptProtocol, joinRelativeURL, joinURL, normalizeURL, parseAuth, parseFilename, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withFragment, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutFragment, withoutHost, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };\n"],"x_google_ignoreList":[0],"mappings":";AAQA,MAAM,IAAI,OAAO;AAkLjB,MAAM,wBAAwB;AAC9B,MAAM,iBAAiB;AACvB,MAAM,0BAA0B;AAOhC,SAAS,YAAY,aAAa,OAAO,EAAE,EAAE;AAC3C,KAAI,OAAO,SAAS,UAClB,QAAO,EAAE,gBAAgB,MAAM;AAEjC,KAAI,KAAK,OACP,QAAO,sBAAsB,KAAK,YAAY;AAEhD,QAAO,eAAe,KAAK,YAAY,KAAK,KAAK,iBAAiB,wBAAwB,KAAK,YAAY,GAAG;;AA0QhH,MAAM,mBAAmB,OAAO,IAAI,uBAAuB;AAC3D,SAAS,SAAS,QAAQ,IAAI,cAAc;CAC1C,MAAM,qBAAqB,MAAM,MAC/B,mDACD;AACD,KAAI,oBAAoB;EACtB,MAAM,GAAG,QAAQ,YAAY,MAAM;AACnC,SAAO;GACL,UAAU,OAAO,aAAa;GAC9B,UAAU;GACV,MAAM,SAAS;GACf,MAAM;GACN,MAAM;GACN,QAAQ;GACR,MAAM;GACP;;AAEH,KAAI,CAAC,YAAY,OAAO,EAAE,gBAAgB,MAAM,CAAC,CAC/C,QAAO,eAAe,SAAS,eAAe,MAAM,GAAG,UAAU,MAAM;CAEzE,MAAM,GAAG,WAAW,IAAI,MAAM,cAAc,MAAM,MAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,4CAA4C,IAAI,EAAE;CACpI,IAAI,GAAG,OAAO,IAAI,OAAO,MAAM,YAAY,MAAM,iBAAiB,IAAI,EAAE;AACxE,KAAI,aAAa,QACf,QAAO,KAAK,QAAQ,mBAAmB,GAAG;CAE5C,MAAM,EAAE,UAAU,QAAQ,SAAS,UAAU,KAAK;AAClD,QAAO;EACL,UAAU,SAAS,aAAa;EAChC,MAAM,OAAO,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC,GAAG;EAC3D;EACA;EACA;EACA;GACC,mBAAmB,CAAC;EACtB;;AAEH,SAAS,UAAU,QAAQ,IAAI;CAC7B,MAAM,CAAC,WAAW,IAAI,SAAS,IAAI,OAAO,OAAO,MAAM,MAAM,2BAA2B,IAAI,EAAE,EAAE,OAAO,EAAE;AACzG,QAAO;EACL;EACA;EACA;EACD"}
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BaseWideEvent, DeepPartial, DrainContext, EnrichContext, EnvironmentContext, ErrorOptions, FieldContext, H3EventContext, IngestPayload, InternalFields, Log, LogLevel, LoggerConfig, ParsedError, RequestLogger, RequestLoggerOptions, SamplingConfig, SamplingRates, ServerEvent, TailSamplingCondition, TailSamplingContext, TransportConfig, WideEvent } from "./types.mjs";
2
2
  import { EvlogError, createError } from "./error.mjs";
3
- import { createRequestLogger, getEnvironment, initLogger, isEnabled, log as _log, shouldKeep } from "./logger.mjs";
3
+ import { createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, log as _log, shouldKeep } from "./logger.mjs";
4
4
  import { useLogger } from "./runtime/server/useLogger.mjs";
5
5
  import { parseError } from "./runtime/utils/parseError.mjs";
6
- export { type BaseWideEvent, type DeepPartial, type DrainContext, type EnrichContext, type EnvironmentContext, type ErrorOptions, EvlogError, type FieldContext, type H3EventContext, type IngestPayload, type InternalFields, type Log, type LogLevel, type LoggerConfig, type ParsedError, type RequestLogger, type RequestLoggerOptions, type SamplingConfig, type SamplingRates, type ServerEvent, type TailSamplingCondition, type TailSamplingContext, type TransportConfig, type WideEvent, createError, createError as createEvlogError, createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, parseError, shouldKeep, useLogger };
6
+ export { type BaseWideEvent, type DeepPartial, type DrainContext, type EnrichContext, type EnvironmentContext, type ErrorOptions, EvlogError, type FieldContext, type H3EventContext, type IngestPayload, type InternalFields, type Log, type LogLevel, type LoggerConfig, type ParsedError, type RequestLogger, type RequestLoggerOptions, type SamplingConfig, type SamplingRates, type ServerEvent, type TailSamplingCondition, type TailSamplingContext, type TransportConfig, type WideEvent, createError, createError as createEvlogError, createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, parseError, shouldKeep, useLogger };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { EvlogError, createError } from "./error.mjs";
2
- import { createRequestLogger, getEnvironment, initLogger, isEnabled, log as _log, shouldKeep } from "./logger.mjs";
2
+ import { createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, log as _log, shouldKeep } from "./logger.mjs";
3
3
  import { useLogger } from "./runtime/server/useLogger.mjs";
4
4
  import { parseError } from "./runtime/utils/parseError.mjs";
5
5
 
6
- export { EvlogError, createError, createError as createEvlogError, createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, parseError, shouldKeep, useLogger };
6
+ export { EvlogError, createError, createError as createEvlogError, createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, parseError, shouldKeep, useLogger };
package/dist/logger.d.mts CHANGED
@@ -25,8 +25,21 @@ declare function shouldKeep(ctx: TailSamplingContext): boolean;
25
25
  * ```
26
26
  */
27
27
  declare const _log: Log;
28
+ /**
29
+ * Create a scoped logger for building wide events.
30
+ * Use this for any context: workflows, jobs, scripts, queues, etc.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const log = createLogger({ jobId: job.id, queue: 'emails' })
35
+ * log.set({ batch: { size: 50, processed: 12 } })
36
+ * log.emit()
37
+ * ```
38
+ */
39
+ declare function createLogger<T extends object = Record<string, unknown>>(initialContext?: Record<string, unknown>): RequestLogger<T>;
28
40
  /**
29
41
  * Create a request-scoped logger for building wide events.
42
+ * Convenience wrapper around `createLogger` that pre-populates HTTP request fields.
30
43
  *
31
44
  * @example
32
45
  * ```ts
@@ -42,5 +55,5 @@ declare function createRequestLogger<T extends object = Record<string, unknown>>
42
55
  */
43
56
  declare function getEnvironment(): EnvironmentContext;
44
57
  //#endregion
45
- export { createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, shouldKeep };
58
+ export { createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, shouldKeep };
46
59
  //# sourceMappingURL=logger.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.mts","names":[],"sources":["../src/logger.ts"],"mappings":";;;;;AAoCA;;iBAAgB,UAAA,CAAW,MAAA,GAAQ,YAAA;;;AAqBnC;iBAAgB,SAAA,CAAA;;;;AA8BhB;iBAAgB,UAAA,CAAW,GAAA,EAAK,mBAAA;;;;AAgB/B;;;;;AAkKD;cAjCM,IAAA,EAAM,GAAA;;;;;;;;;;;;iBAiCI,mBAAA,oBAAuC,MAAA,kBAAA,CAAyB,OAAA,GAAS,oBAAA,GAA4B,aAAA,CAAc,CAAA;;;AAiHnI;iBAAgB,cAAA,CAAA,GAAkB,kBAAA"}
1
+ {"version":3,"file":"logger.d.mts","names":[],"sources":["../src/logger.ts"],"mappings":";;;;;AAoCA;;iBAAgB,UAAA,CAAW,MAAA,GAAQ,YAAA;;;AAqBnC;iBAAgB,SAAA,CAAA;;;;AA8BhB;iBAAgB,UAAA,CAAW,GAAA,EAAK,mBAAA;;;;AAgB/B;;;;;AAkKD;cAjCM,IAAA,EAAM,GAAA;;;;;;;;;;;;iBAiCI,YAAA,oBAAgC,MAAA,kBAAA,CAAyB,cAAA,GAAgB,MAAA,oBAA+B,aAAA,CAAc,CAAA;;;AAsHtI;;;;;;;;;;iBAAgB,mBAAA,oBAAuC,MAAA,kBAAA,CAAyB,OAAA,GAAS,oBAAA,GAA4B,aAAA,CAAc,CAAA;;;;iBAWnH,cAAA,CAAA,GAAkB,kBAAA"}
package/dist/logger.mjs CHANGED
@@ -179,27 +179,23 @@ const noopLogger = {
179
179
  }
180
180
  };
181
181
  /**
182
- * Create a request-scoped logger for building wide events.
182
+ * Create a scoped logger for building wide events.
183
+ * Use this for any context: workflows, jobs, scripts, queues, etc.
183
184
  *
184
185
  * @example
185
186
  * ```ts
186
- * const log = createRequestLogger({ method: 'POST', path: '/checkout' })
187
- * log.set({ user: { id: '123' } })
188
- * log.set({ cart: { items: 3 } })
187
+ * const log = createLogger({ jobId: job.id, queue: 'emails' })
188
+ * log.set({ batch: { size: 50, processed: 12 } })
189
189
  * log.emit()
190
190
  * ```
191
191
  */
192
- function createRequestLogger(options = {}) {
192
+ function createLogger(initialContext = {}) {
193
193
  if (!globalEnabled) return noopLogger;
194
194
  const startTime = Date.now();
195
- let context = {
196
- method: options.method,
197
- path: options.path,
198
- requestId: options.requestId
199
- };
195
+ let context = { ...initialContext };
200
196
  let hasError = false;
201
197
  let hasWarn = false;
202
- function addRequestLog(level, message) {
198
+ function addLog(level, message) {
203
199
  const entry = {
204
200
  level,
205
201
  message,
@@ -234,7 +230,7 @@ function createRequestLogger(options = {}) {
234
230
  }, context);
235
231
  },
236
232
  info(message, infoContext) {
237
- addRequestLog("info", message);
233
+ addLog("info", message);
238
234
  if (infoContext) {
239
235
  const { requestLogs: _, ...rest } = infoContext;
240
236
  context = deepDefaults(rest, context);
@@ -242,7 +238,7 @@ function createRequestLogger(options = {}) {
242
238
  },
243
239
  warn(message, warnContext) {
244
240
  hasWarn = true;
245
- addRequestLog("warn", message);
241
+ addLog("warn", message);
246
242
  if (warnContext) {
247
243
  const { requestLogs: _, ...rest } = warnContext;
248
244
  context = deepDefaults(rest, context);
@@ -276,6 +272,25 @@ function createRequestLogger(options = {}) {
276
272
  };
277
273
  }
278
274
  /**
275
+ * Create a request-scoped logger for building wide events.
276
+ * Convenience wrapper around `createLogger` that pre-populates HTTP request fields.
277
+ *
278
+ * @example
279
+ * ```ts
280
+ * const log = createRequestLogger({ method: 'POST', path: '/checkout' })
281
+ * log.set({ user: { id: '123' } })
282
+ * log.set({ cart: { items: 3 } })
283
+ * log.emit()
284
+ * ```
285
+ */
286
+ function createRequestLogger(options = {}) {
287
+ const initial = {};
288
+ if (options.method !== void 0) initial.method = options.method;
289
+ if (options.path !== void 0) initial.path = options.path;
290
+ if (options.requestId !== void 0) initial.requestId = options.requestId;
291
+ return createLogger(initial);
292
+ }
293
+ /**
279
294
  * Get the current environment context.
280
295
  */
281
296
  function getEnvironment() {
@@ -283,5 +298,5 @@ function getEnvironment() {
283
298
  }
284
299
 
285
300
  //#endregion
286
- export { createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, shouldKeep };
301
+ export { createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, _log as log, shouldKeep };
287
302
  //# sourceMappingURL=logger.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.mjs","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import type { DrainContext, EnvironmentContext, FieldContext, Log, LogLevel, LoggerConfig, RequestLogger, RequestLoggerOptions, SamplingConfig, TailSamplingContext, WideEvent } from './types'\nimport { colors, detectEnvironment, formatDuration, getConsoleMethod, getLevelColor, isDev, matchesPattern } from './utils'\n\nfunction isPlainObject(val: unknown): val is Record<string, unknown> {\n return val !== null && typeof val === 'object' && !Array.isArray(val)\n}\n\nfunction deepDefaults(base: Record<string, unknown>, defaults: Record<string, unknown>): Record<string, unknown> {\n const result = { ...base }\n for (const key in defaults) {\n const baseVal = result[key]\n const defaultVal = defaults[key]\n if (baseVal === undefined || baseVal === null) {\n result[key] = defaultVal\n } else if (isPlainObject(baseVal) && isPlainObject(defaultVal)) {\n result[key] = deepDefaults(baseVal, defaultVal)\n }\n }\n return result\n}\n\nlet globalEnv: EnvironmentContext = {\n service: 'app',\n environment: 'development',\n}\n\nlet globalPretty = isDev()\nlet globalSampling: SamplingConfig = {}\nlet globalStringify = true\nlet globalDrain: ((ctx: DrainContext) => void | Promise<void>) | undefined\nlet globalEnabled = true\n\n/**\n * Initialize the logger with configuration.\n * Call this once at application startup.\n */\nexport function initLogger(config: LoggerConfig = {}): void {\n globalEnabled = config.enabled ?? true\n const detected = detectEnvironment()\n\n globalEnv = {\n service: config.env?.service ?? detected.service ?? 'app',\n environment: config.env?.environment ?? detected.environment ?? 'development',\n version: config.env?.version ?? detected.version,\n commitHash: config.env?.commitHash ?? detected.commitHash,\n region: config.env?.region ?? detected.region,\n }\n\n globalPretty = config.pretty ?? isDev()\n globalSampling = config.sampling ?? {}\n globalStringify = config.stringify ?? true\n globalDrain = config.drain\n}\n\n/**\n * Check if logging is globally enabled.\n */\nexport function isEnabled(): boolean {\n return globalEnabled\n}\n\n/**\n * Determine if a log at the given level should be emitted based on sampling config.\n * Error level defaults to 100% (always logged) unless explicitly configured otherwise.\n */\nfunction shouldSample(level: LogLevel): boolean {\n const { rates } = globalSampling\n if (!rates) {\n return true // No sampling configured, log everything\n }\n\n // Error defaults to 100% unless explicitly set\n const percentage = level === 'error' && rates.error === undefined\n ? 100\n : rates[level] ?? 100\n\n // 0% = never log, 100% = always log\n if (percentage <= 0) return false\n if (percentage >= 100) return true\n\n return Math.random() * 100 < percentage\n}\n\n/**\n * Evaluate tail sampling conditions to determine if a log should be force-kept.\n * Returns true if ANY condition matches (OR logic).\n */\nexport function shouldKeep(ctx: TailSamplingContext): boolean {\n const { keep } = globalSampling\n if (!keep?.length) return false\n\n return keep.some((condition) => {\n if (condition.status !== undefined && ctx.status !== undefined && ctx.status >= condition.status) {\n return true\n }\n if (condition.duration !== undefined && ctx.duration !== undefined && ctx.duration >= condition.duration) {\n return true\n }\n if (condition.path && ctx.path && matchesPattern(ctx.path, condition.path)) {\n return true\n }\n return false\n })\n}\n\nfunction emitWideEvent(level: LogLevel, event: Record<string, unknown>, skipSamplingCheck = false): WideEvent | null {\n if (!globalEnabled) return null\n\n if (!skipSamplingCheck && !shouldSample(level)) {\n return null\n }\n\n const formatted: WideEvent = {\n timestamp: new Date().toISOString(),\n level,\n ...globalEnv,\n ...event,\n }\n\n if (globalPretty) {\n prettyPrintWideEvent(formatted)\n } else if (globalStringify) {\n console[getConsoleMethod(level)](JSON.stringify(formatted))\n } else {\n console[getConsoleMethod(level)](formatted)\n }\n\n if (globalDrain) {\n Promise.resolve(globalDrain({ event: formatted })).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n }\n\n return formatted\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!globalEnabled) return\n\n if (globalPretty) {\n if (!shouldSample(level)) {\n return\n }\n const color = getLevelColor(level)\n const timestamp = new Date().toISOString().slice(11, 23)\n console.log(`${colors.dim}${timestamp}${colors.reset} ${color}[${tag}]${colors.reset} ${message}`)\n return\n }\n emitWideEvent(level, { tag, message })\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value)\n }\n if (typeof value === 'object') {\n // Flatten object to key=value pairs\n const pairs: string[] = []\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined && v !== null) {\n if (typeof v === 'object') {\n // For nested objects, show as JSON\n pairs.push(`${k}=${JSON.stringify(v)}`)\n } else {\n pairs.push(`${k}=${v}`)\n }\n }\n }\n return pairs.join(' ')\n }\n return String(value)\n}\n\nfunction prettyPrintWideEvent(event: Record<string, unknown>): void {\n const { timestamp, level, service, environment, version, ...rest } = event\n const levelColor = getLevelColor(level as string)\n const ts = (timestamp as string).slice(11, 23)\n\n let header = `${colors.dim}${ts}${colors.reset} ${levelColor}${(level as string).toUpperCase()}${colors.reset}`\n header += ` ${colors.cyan}[${service}]${colors.reset}`\n\n if (rest.method && rest.path) {\n header += ` ${rest.method} ${rest.path}`\n delete rest.method\n delete rest.path\n }\n\n if (rest.status) {\n const statusColor = (rest.status as number) >= 400 ? colors.red : colors.green\n header += ` ${statusColor}${rest.status}${colors.reset}`\n delete rest.status\n }\n\n if (rest.duration) {\n header += ` ${colors.dim}in ${rest.duration}${colors.reset}`\n delete rest.duration\n }\n\n console.log(header)\n\n const entries = Object.entries(rest).filter(([_, v]) => v !== undefined)\n const lastIndex = entries.length - 1\n\n entries.forEach(([key, value], index) => {\n const isLast = index === lastIndex\n const prefix = isLast ? '└─' : '├─'\n const formatted = formatValue(value)\n console.log(` ${colors.dim}${prefix}${colors.reset} ${colors.cyan}${key}:${colors.reset} ${formatted}`)\n })\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitWideEvent(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\n/**\n * Simple logging API - as easy as console.log\n *\n * @example\n * ```ts\n * log.info('auth', 'User logged in')\n * log.error({ action: 'payment', error: 'failed' })\n * ```\n */\nconst _log: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _log as log }\n\nconst noopLogger: RequestLogger = {\n set() {},\n error() {},\n info() {},\n warn() {},\n emit() {\n return null\n },\n getContext() {\n return {}\n },\n}\n\n/**\n * Create a request-scoped logger for building wide events.\n *\n * @example\n * ```ts\n * const log = createRequestLogger({ method: 'POST', path: '/checkout' })\n * log.set({ user: { id: '123' } })\n * log.set({ cart: { items: 3 } })\n * log.emit()\n * ```\n */\nexport function createRequestLogger<T extends object = Record<string, unknown>>(options: RequestLoggerOptions = {}): RequestLogger<T> {\n if (!globalEnabled) return noopLogger as RequestLogger<T>\n\n const startTime = Date.now()\n let context: Record<string, unknown> = {\n method: options.method,\n path: options.path,\n requestId: options.requestId,\n }\n let hasError = false\n let hasWarn = false\n\n function addRequestLog(level: 'info' | 'warn', message: string): void {\n const entry = {\n level,\n message,\n timestamp: new Date().toISOString(),\n }\n\n const requestLogs = Array.isArray(context.requestLogs)\n ? [...context.requestLogs, entry]\n : [entry]\n\n context = {\n ...context,\n requestLogs,\n }\n }\n\n return {\n set(data: FieldContext<T>): void {\n context = deepDefaults(data as Record<string, unknown>, context) as Record<string, unknown>\n },\n\n error(error: Error | string, errorContext?: FieldContext<T>): void {\n hasError = true\n const err = typeof error === 'string' ? new Error(error) : error\n\n const errorData = {\n ...(errorContext as Record<string, unknown>),\n error: {\n name: err.name,\n message: err.message,\n stack: err.stack,\n ...('status' in err && { status: (err as Record<string, unknown>).status }),\n ...('statusText' in err && { statusText: (err as Record<string, unknown>).statusText }),\n ...('statusCode' in err && { statusCode: (err as Record<string, unknown>).statusCode }),\n ...('statusMessage' in err && { statusMessage: (err as Record<string, unknown>).statusMessage }),\n ...('data' in err && { data: (err as Record<string, unknown>).data }),\n ...('cause' in err && { cause: (err as unknown as Record<string, unknown>).cause }),\n },\n }\n context = deepDefaults(errorData, context) as Record<string, unknown>\n },\n\n info(message: string, infoContext?: FieldContext<T>): void {\n addRequestLog('info', message)\n if (infoContext) {\n const { requestLogs: _, ...rest } = infoContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n warn(message: string, warnContext?: FieldContext<T>): void {\n hasWarn = true\n addRequestLog('warn', message)\n if (warnContext) {\n const { requestLogs: _, ...rest } = warnContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n emit(overrides?: FieldContext<T> & { _forceKeep?: boolean }): WideEvent | null {\n const durationMs = Date.now() - startTime\n const duration = formatDuration(durationMs)\n const level: LogLevel = hasError ? 'error' : hasWarn ? 'warn' : 'info'\n\n // Extract _forceKeep from overrides (set by evlog:emit:keep hook)\n const { _forceKeep, ...restOverrides } = (overrides ?? {}) as Record<string, unknown> & { _forceKeep?: boolean }\n\n // Build tail sampling context\n const tailCtx: TailSamplingContext = {\n status: (context.status ?? restOverrides.status) as number | undefined,\n duration: durationMs,\n path: context.path as string | undefined,\n method: context.method as string | undefined,\n context: { ...context, ...restOverrides },\n }\n\n // Tail sampling: force keep if hook or built-in conditions match\n const forceKeep = _forceKeep || shouldKeep(tailCtx)\n\n // Apply head sampling only if not force-kept\n if (!forceKeep && !shouldSample(level)) {\n return null\n }\n\n return emitWideEvent(level, {\n ...context,\n ...restOverrides,\n duration,\n }, true)\n },\n\n getContext(): FieldContext<T> & Record<string, unknown> {\n return { ...context }\n },\n }\n}\n\n/**\n * Get the current environment context.\n */\nexport function getEnvironment(): EnvironmentContext {\n return { ...globalEnv }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"logger.mjs","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import type { DrainContext, EnvironmentContext, FieldContext, Log, LogLevel, LoggerConfig, RequestLogger, RequestLoggerOptions, SamplingConfig, TailSamplingContext, WideEvent } from './types'\nimport { colors, detectEnvironment, formatDuration, getConsoleMethod, getLevelColor, isDev, matchesPattern } from './utils'\n\nfunction isPlainObject(val: unknown): val is Record<string, unknown> {\n return val !== null && typeof val === 'object' && !Array.isArray(val)\n}\n\nfunction deepDefaults(base: Record<string, unknown>, defaults: Record<string, unknown>): Record<string, unknown> {\n const result = { ...base }\n for (const key in defaults) {\n const baseVal = result[key]\n const defaultVal = defaults[key]\n if (baseVal === undefined || baseVal === null) {\n result[key] = defaultVal\n } else if (isPlainObject(baseVal) && isPlainObject(defaultVal)) {\n result[key] = deepDefaults(baseVal, defaultVal)\n }\n }\n return result\n}\n\nlet globalEnv: EnvironmentContext = {\n service: 'app',\n environment: 'development',\n}\n\nlet globalPretty = isDev()\nlet globalSampling: SamplingConfig = {}\nlet globalStringify = true\nlet globalDrain: ((ctx: DrainContext) => void | Promise<void>) | undefined\nlet globalEnabled = true\n\n/**\n * Initialize the logger with configuration.\n * Call this once at application startup.\n */\nexport function initLogger(config: LoggerConfig = {}): void {\n globalEnabled = config.enabled ?? true\n const detected = detectEnvironment()\n\n globalEnv = {\n service: config.env?.service ?? detected.service ?? 'app',\n environment: config.env?.environment ?? detected.environment ?? 'development',\n version: config.env?.version ?? detected.version,\n commitHash: config.env?.commitHash ?? detected.commitHash,\n region: config.env?.region ?? detected.region,\n }\n\n globalPretty = config.pretty ?? isDev()\n globalSampling = config.sampling ?? {}\n globalStringify = config.stringify ?? true\n globalDrain = config.drain\n}\n\n/**\n * Check if logging is globally enabled.\n */\nexport function isEnabled(): boolean {\n return globalEnabled\n}\n\n/**\n * Determine if a log at the given level should be emitted based on sampling config.\n * Error level defaults to 100% (always logged) unless explicitly configured otherwise.\n */\nfunction shouldSample(level: LogLevel): boolean {\n const { rates } = globalSampling\n if (!rates) {\n return true // No sampling configured, log everything\n }\n\n // Error defaults to 100% unless explicitly set\n const percentage = level === 'error' && rates.error === undefined\n ? 100\n : rates[level] ?? 100\n\n // 0% = never log, 100% = always log\n if (percentage <= 0) return false\n if (percentage >= 100) return true\n\n return Math.random() * 100 < percentage\n}\n\n/**\n * Evaluate tail sampling conditions to determine if a log should be force-kept.\n * Returns true if ANY condition matches (OR logic).\n */\nexport function shouldKeep(ctx: TailSamplingContext): boolean {\n const { keep } = globalSampling\n if (!keep?.length) return false\n\n return keep.some((condition) => {\n if (condition.status !== undefined && ctx.status !== undefined && ctx.status >= condition.status) {\n return true\n }\n if (condition.duration !== undefined && ctx.duration !== undefined && ctx.duration >= condition.duration) {\n return true\n }\n if (condition.path && ctx.path && matchesPattern(ctx.path, condition.path)) {\n return true\n }\n return false\n })\n}\n\nfunction emitWideEvent(level: LogLevel, event: Record<string, unknown>, skipSamplingCheck = false): WideEvent | null {\n if (!globalEnabled) return null\n\n if (!skipSamplingCheck && !shouldSample(level)) {\n return null\n }\n\n const formatted: WideEvent = {\n timestamp: new Date().toISOString(),\n level,\n ...globalEnv,\n ...event,\n }\n\n if (globalPretty) {\n prettyPrintWideEvent(formatted)\n } else if (globalStringify) {\n console[getConsoleMethod(level)](JSON.stringify(formatted))\n } else {\n console[getConsoleMethod(level)](formatted)\n }\n\n if (globalDrain) {\n Promise.resolve(globalDrain({ event: formatted })).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n }\n\n return formatted\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!globalEnabled) return\n\n if (globalPretty) {\n if (!shouldSample(level)) {\n return\n }\n const color = getLevelColor(level)\n const timestamp = new Date().toISOString().slice(11, 23)\n console.log(`${colors.dim}${timestamp}${colors.reset} ${color}[${tag}]${colors.reset} ${message}`)\n return\n }\n emitWideEvent(level, { tag, message })\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value)\n }\n if (typeof value === 'object') {\n // Flatten object to key=value pairs\n const pairs: string[] = []\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v !== undefined && v !== null) {\n if (typeof v === 'object') {\n // For nested objects, show as JSON\n pairs.push(`${k}=${JSON.stringify(v)}`)\n } else {\n pairs.push(`${k}=${v}`)\n }\n }\n }\n return pairs.join(' ')\n }\n return String(value)\n}\n\nfunction prettyPrintWideEvent(event: Record<string, unknown>): void {\n const { timestamp, level, service, environment, version, ...rest } = event\n const levelColor = getLevelColor(level as string)\n const ts = (timestamp as string).slice(11, 23)\n\n let header = `${colors.dim}${ts}${colors.reset} ${levelColor}${(level as string).toUpperCase()}${colors.reset}`\n header += ` ${colors.cyan}[${service}]${colors.reset}`\n\n if (rest.method && rest.path) {\n header += ` ${rest.method} ${rest.path}`\n delete rest.method\n delete rest.path\n }\n\n if (rest.status) {\n const statusColor = (rest.status as number) >= 400 ? colors.red : colors.green\n header += ` ${statusColor}${rest.status}${colors.reset}`\n delete rest.status\n }\n\n if (rest.duration) {\n header += ` ${colors.dim}in ${rest.duration}${colors.reset}`\n delete rest.duration\n }\n\n console.log(header)\n\n const entries = Object.entries(rest).filter(([_, v]) => v !== undefined)\n const lastIndex = entries.length - 1\n\n entries.forEach(([key, value], index) => {\n const isLast = index === lastIndex\n const prefix = isLast ? '└─' : '├─'\n const formatted = formatValue(value)\n console.log(` ${colors.dim}${prefix}${colors.reset} ${colors.cyan}${key}:${colors.reset} ${formatted}`)\n })\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitWideEvent(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\n/**\n * Simple logging API - as easy as console.log\n *\n * @example\n * ```ts\n * log.info('auth', 'User logged in')\n * log.error({ action: 'payment', error: 'failed' })\n * ```\n */\nconst _log: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _log as log }\n\nconst noopLogger: RequestLogger = {\n set() {},\n error() {},\n info() {},\n warn() {},\n emit() {\n return null\n },\n getContext() {\n return {}\n },\n}\n\n/**\n * Create a scoped logger for building wide events.\n * Use this for any context: workflows, jobs, scripts, queues, etc.\n *\n * @example\n * ```ts\n * const log = createLogger({ jobId: job.id, queue: 'emails' })\n * log.set({ batch: { size: 50, processed: 12 } })\n * log.emit()\n * ```\n */\nexport function createLogger<T extends object = Record<string, unknown>>(initialContext: Record<string, unknown> = {}): RequestLogger<T> {\n if (!globalEnabled) return noopLogger as RequestLogger<T>\n\n const startTime = Date.now()\n let context: Record<string, unknown> = { ...initialContext }\n let hasError = false\n let hasWarn = false\n\n function addLog(level: 'info' | 'warn', message: string): void {\n const entry = {\n level,\n message,\n timestamp: new Date().toISOString(),\n }\n\n const requestLogs = Array.isArray(context.requestLogs)\n ? [...context.requestLogs, entry]\n : [entry]\n\n context = {\n ...context,\n requestLogs,\n }\n }\n\n return {\n set(data: FieldContext<T>): void {\n context = deepDefaults(data as Record<string, unknown>, context) as Record<string, unknown>\n },\n\n error(error: Error | string, errorContext?: FieldContext<T>): void {\n hasError = true\n const err = typeof error === 'string' ? new Error(error) : error\n\n const errorData = {\n ...(errorContext as Record<string, unknown>),\n error: {\n name: err.name,\n message: err.message,\n stack: err.stack,\n ...('status' in err && { status: (err as Record<string, unknown>).status }),\n ...('statusText' in err && { statusText: (err as Record<string, unknown>).statusText }),\n ...('statusCode' in err && { statusCode: (err as Record<string, unknown>).statusCode }),\n ...('statusMessage' in err && { statusMessage: (err as Record<string, unknown>).statusMessage }),\n ...('data' in err && { data: (err as Record<string, unknown>).data }),\n ...('cause' in err && { cause: (err as unknown as Record<string, unknown>).cause }),\n },\n }\n context = deepDefaults(errorData, context) as Record<string, unknown>\n },\n\n info(message: string, infoContext?: FieldContext<T>): void {\n addLog('info', message)\n if (infoContext) {\n const { requestLogs: _, ...rest } = infoContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n warn(message: string, warnContext?: FieldContext<T>): void {\n hasWarn = true\n addLog('warn', message)\n if (warnContext) {\n const { requestLogs: _, ...rest } = warnContext as Record<string, unknown>\n context = deepDefaults(rest, context) as Record<string, unknown>\n }\n },\n\n emit(overrides?: FieldContext<T> & { _forceKeep?: boolean }): WideEvent | null {\n const durationMs = Date.now() - startTime\n const duration = formatDuration(durationMs)\n const level: LogLevel = hasError ? 'error' : hasWarn ? 'warn' : 'info'\n\n // Extract _forceKeep from overrides (set by evlog:emit:keep hook)\n const { _forceKeep, ...restOverrides } = (overrides ?? {}) as Record<string, unknown> & { _forceKeep?: boolean }\n\n // Build tail sampling context\n const tailCtx: TailSamplingContext = {\n status: (context.status ?? restOverrides.status) as number | undefined,\n duration: durationMs,\n path: context.path as string | undefined,\n method: context.method as string | undefined,\n context: { ...context, ...restOverrides },\n }\n\n // Tail sampling: force keep if hook or built-in conditions match\n const forceKeep = _forceKeep || shouldKeep(tailCtx)\n\n // Apply head sampling only if not force-kept\n if (!forceKeep && !shouldSample(level)) {\n return null\n }\n\n return emitWideEvent(level, {\n ...context,\n ...restOverrides,\n duration,\n }, true)\n },\n\n getContext(): FieldContext<T> & Record<string, unknown> {\n return { ...context }\n },\n }\n}\n\n/**\n * Create a request-scoped logger for building wide events.\n * Convenience wrapper around `createLogger` that pre-populates HTTP request fields.\n *\n * @example\n * ```ts\n * const log = createRequestLogger({ method: 'POST', path: '/checkout' })\n * log.set({ user: { id: '123' } })\n * log.set({ cart: { items: 3 } })\n * log.emit()\n * ```\n */\nexport function createRequestLogger<T extends object = Record<string, unknown>>(options: RequestLoggerOptions = {}): RequestLogger<T> {\n const initial: Record<string, unknown> = {}\n if (options.method !== undefined) initial.method = options.method\n if (options.path !== undefined) initial.path = options.path\n if (options.requestId !== undefined) initial.requestId = options.requestId\n return createLogger<T>(initial)\n}\n\n/**\n * Get the current environment context.\n */\nexport function getEnvironment(): EnvironmentContext {\n return { ...globalEnv }\n}\n"],"mappings":"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"}
@@ -23,6 +23,13 @@ interface EvlogProviderProps {
23
23
  * @default true
24
24
  */
25
25
  enabled?: boolean;
26
+ /**
27
+ * Enable or disable browser console output.
28
+ * When false, logs are suppressed in the browser DevTools console
29
+ * but still sent to the server via transport (if enabled).
30
+ * @default true
31
+ */
32
+ console?: boolean;
26
33
  children: React.ReactNode;
27
34
  }
28
35
  /**
@@ -48,6 +55,7 @@ declare function EvlogProvider({
48
55
  pretty,
49
56
  transport,
50
57
  enabled,
58
+ console: consoleOutput,
51
59
  children
52
60
  }: EvlogProviderProps): react.ReactNode;
53
61
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.mts","names":[],"sources":["../../src/next/client.ts"],"mappings":";;;;;UAQiB,kBAAA;;;AAAjB;;EAKE,OAAA;EAmByB;;;;EAbzB,MAAA;EAWA;;;EANA,SAAA,GAAY,eAAA;EAQa;;AAsB3B;;EAxBE,OAAA;EAEA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAsBF,aAAA,CAAA;EAAgB,OAAA;EAAS,MAAA;EAAQ,SAAA;EAAW,OAAA;EAAS;AAAA,GAAY,kBAAA,GAAkB,KAAA,CAAA,SAAA"}
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../../src/next/client.ts"],"mappings":";;;;;UAQiB,kBAAA;;;AAAjB;;EAKE,OAAA;EA2ByB;;;;EArBzB,MAAA;EAWA;;;EANA,SAAA,GAAY,eAAA;EAgBI;;;AAsBlB;EAhCE,OAAA;;;;;;;EAQA,OAAA;EAEA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAsBF,aAAA,CAAA;EAAgB,OAAA;EAAS,MAAA;EAAQ,SAAA;EAAW,OAAA;EAAS,OAAA,EAAS,aAAA;EAAe;AAAA,GAAY,kBAAA,GAAkB,KAAA,CAAA,SAAA"}
@@ -22,16 +22,18 @@ import { useEffect } from "react";
22
22
  * }
23
23
  * ```
24
24
  */
25
- function EvlogProvider({ service, pretty, transport, enabled, children }) {
25
+ function EvlogProvider({ service, pretty, transport, enabled, console: consoleOutput, children }) {
26
26
  useEffect(() => {
27
27
  initLog({
28
28
  enabled,
29
+ console: consoleOutput,
29
30
  pretty,
30
31
  service,
31
32
  transport
32
33
  });
33
34
  }, [
34
35
  enabled,
36
+ consoleOutput,
35
37
  pretty,
36
38
  service,
37
39
  transport
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":[],"sources":["../../src/next/client.ts"],"sourcesContent":["'use client'\n\nimport { useEffect } from 'react'\nimport type { TransportConfig } from '../types'\nimport { initLog, log, setIdentity, clearIdentity } from '../runtime/client/log'\n\nexport { log, setIdentity, clearIdentity } from '../runtime/client/log'\n\nexport interface EvlogProviderProps {\n /**\n * Service name for client-side logs.\n * @default 'client'\n */\n service?: string\n\n /**\n * Enable pretty printing in the browser console.\n * @default true\n */\n pretty?: boolean\n\n /**\n * Transport configuration for sending client logs to the server.\n */\n transport?: TransportConfig\n\n /**\n * Enable or disable client-side logging.\n * @default true\n */\n enabled?: boolean\n\n children: React.ReactNode\n}\n\n/**\n * React provider that initializes evlog client-side logging.\n * Place this in your root layout to enable client logging throughout your app.\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { EvlogProvider } from 'evlog/next/client'\n *\n * export default function Layout({ children }) {\n * return (\n * <EvlogProvider service=\"my-app\" transport={{ enabled: true }}>\n * {children}\n * </EvlogProvider>\n * )\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function EvlogProvider({ service, pretty, transport, enabled, children }: EvlogProviderProps) {\n useEffect(() => {\n initLog({\n enabled,\n pretty,\n service,\n transport,\n })\n }, [enabled, pretty, service, transport])\n\n return children\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,cAAc,EAAE,SAAS,QAAQ,WAAW,SAAS,YAAgC;AACnG,iBAAgB;AACd,UAAQ;GACN;GACA;GACA;GACA;GACD,CAAC;IACD;EAAC;EAAS;EAAQ;EAAS;EAAU,CAAC;AAEzC,QAAO"}
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../../src/next/client.ts"],"sourcesContent":["'use client'\n\nimport { useEffect } from 'react'\nimport type { TransportConfig } from '../types'\nimport { initLog, log, setIdentity, clearIdentity } from '../runtime/client/log'\n\nexport { log, setIdentity, clearIdentity } from '../runtime/client/log'\n\nexport interface EvlogProviderProps {\n /**\n * Service name for client-side logs.\n * @default 'client'\n */\n service?: string\n\n /**\n * Enable pretty printing in the browser console.\n * @default true\n */\n pretty?: boolean\n\n /**\n * Transport configuration for sending client logs to the server.\n */\n transport?: TransportConfig\n\n /**\n * Enable or disable client-side logging.\n * @default true\n */\n enabled?: boolean\n\n /**\n * Enable or disable browser console output.\n * When false, logs are suppressed in the browser DevTools console\n * but still sent to the server via transport (if enabled).\n * @default true\n */\n console?: boolean\n\n children: React.ReactNode\n}\n\n/**\n * React provider that initializes evlog client-side logging.\n * Place this in your root layout to enable client logging throughout your app.\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { EvlogProvider } from 'evlog/next/client'\n *\n * export default function Layout({ children }) {\n * return (\n * <EvlogProvider service=\"my-app\" transport={{ enabled: true }}>\n * {children}\n * </EvlogProvider>\n * )\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function EvlogProvider({ service, pretty, transport, enabled, console: consoleOutput, children }: EvlogProviderProps) {\n useEffect(() => {\n initLog({\n enabled,\n console: consoleOutput,\n pretty,\n service,\n transport,\n })\n }, [enabled, consoleOutput, pretty, service, transport])\n\n return children\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,cAAc,EAAE,SAAS,QAAQ,WAAW,SAAS,SAAS,eAAe,YAAgC;AAC3H,iBAAgB;AACd,UAAQ;GACN;GACA,SAAS;GACT;GACA;GACA;GACD,CAAC;IACD;EAAC;EAAS;EAAe;EAAQ;EAAS;EAAU,CAAC;AAExD,QAAO"}
@@ -1,7 +1,6 @@
1
1
  import { DrainContext, EnrichContext, EnvironmentContext, Log, RequestLogger, RouteConfig, SamplingConfig, TailSamplingContext } from "../types.mjs";
2
2
  import { createError } from "../error.mjs";
3
3
  import { log as _log } from "../logger.mjs";
4
- import "../index.mjs";
5
4
  import { AsyncLocalStorage } from "node:async_hooks";
6
5
 
7
6
  //#region src/next/types.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/types.ts","../../src/next/storage.ts","../../src/next/middleware.ts","../../src/next/index.ts"],"mappings":";;;;;;;UAEiB,gBAAA;;;;;EAKf,OAAA;EALe;;;EAUf,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAAR;;;;EAMN,MAAA;EAoCsC;;;;EA9BtC,OAAA;EA2CmD;;;EAtCnD,QAAA,GAAW,cAAA;EAjBL;;;;;EAwBN,OAAA;EAAA;;;;;EAOA,OAAA;EAWc;;;EANd,MAAA,GAAS,MAAA,SAAe,WAAA;EAYT;;;;EANf,KAAA,IAAS,GAAA,EAAK,YAAA,YAAwB,OAAA;EAa9B;;;;EAPR,MAAA,IAAU,GAAA,EAAK,aAAA,YAAyB,OAAA;EAgBzB;;;;;EATf,IAAA,IAAQ,GAAA,EAAK,mBAAA,YAA+B,OAAA;;;AC/C9C;;EDqDE,SAAA;AAAA;AAAA,UAGe,qBAAA;ECxDwD;;;;ED6DvE,OAAA;EC7DuE;;;;EDmEvE,OAAA;AAAA;;;;;;;AArFF;;;;;;;;;;;iBCkBgB,SAAA,oBAA6B,MAAA,kBAAA,CAAA,GAA4B,aAAA,CAAc,CAAA;;;KCjBlF,WAAA;EACH,OAAA;IAAW,QAAA;EAAA;EACX,OAAA;IAAW,GAAA,CAAI,IAAA;EAAA;AAAA;AAAA,KAGZ,YAAA;EACH,OAAA;IAAW,GAAA,CAAI,IAAA,UAAc,KAAA;EAAA;AAAA;;;;;;;;;;;;;;iBAoBf,eAAA,CAAgB,MAAA,GAAS,qBAAA,IACzB,OAAA,EAAS,WAAA,KAAW,OAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCYpB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAWg8D,IAAA,EAAA,KAAA,KAAA,OAAA,SAAkC,IAAA,EAAA,KAAA,KAAA,OAAA,CAAA,OAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/types.ts","../../src/next/storage.ts","../../src/next/middleware.ts","../../src/next/index.ts"],"mappings":";;;;;;UAEiB,gBAAA;;;;;EAKf,OAAA;EALe;;;EAUf,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAAR;;;;EAMN,MAAA;EAoCsC;;;;EA9BtC,OAAA;EA2CmD;;;EAtCnD,QAAA,GAAW,cAAA;EAjBL;;;;;EAwBN,OAAA;EAAA;;;;;EAOA,OAAA;EAWc;;;EANd,MAAA,GAAS,MAAA,SAAe,WAAA;EAYT;;;;EANf,KAAA,IAAS,GAAA,EAAK,YAAA,YAAwB,OAAA;EAa9B;;;;EAPR,MAAA,IAAU,GAAA,EAAK,aAAA,YAAyB,OAAA;EAgBzB;;;;;EATf,IAAA,IAAQ,GAAA,EAAK,mBAAA,YAA+B,OAAA;;;AC/C9C;;EDqDE,SAAA;AAAA;AAAA,UAGe,qBAAA;ECxDwD;;;;ED6DvE,OAAA;EC7DuE;;;;EDmEvE,OAAA;AAAA;;;;;;;AArFF;;;;;;;;;;;iBCkBgB,SAAA,oBAA6B,MAAA,kBAAA,CAAA,GAA4B,aAAA,CAAc,CAAA;;;KCjBlF,WAAA;EACH,OAAA;IAAW,QAAA;EAAA;EACX,OAAA;IAAW,GAAA,CAAI,IAAA;EAAA;AAAA;AAAA,KAGZ,YAAA;EACH,OAAA;IAAW,GAAA,CAAI,IAAA,UAAc,KAAA;EAAA;AAAA;;;;;;;;;;;;;;iBAoBf,eAAA,CAAgB,MAAA,GAAS,qBAAA,IACzB,OAAA,EAAS,WAAA,KAAW,OAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCYpB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAWg8D,IAAA,EAAA,KAAA,KAAA,OAAA,SAAkC,IAAA,EAAA,KAAA,KAAA,OAAA,CAAA,OAAA,CAAA,OAAA"}
@@ -1,10 +1,11 @@
1
1
  import { useLogger } from "../runtime/server/useLogger.mjs";
2
- import { t as NitroModuleOptions } from "../nitro-CrFBjY1Y.mjs";
2
+ import { t as NitroModuleOptions } from "../nitro-mfub2f8G.mjs";
3
+ import { Nitro } from "nitropack";
3
4
 
4
5
  //#region src/nitro/module.d.ts
5
6
  declare function evlog(options?: NitroModuleOptions): {
6
7
  name: string;
7
- setup(nitro: any): void;
8
+ setup(nitro: Nitro): void;
8
9
  };
9
10
  //#endregion
10
11
  export { type NitroModuleOptions, evlog as default, useLogger };
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.mts","names":[],"sources":["../../src/nitro/module.ts"],"mappings":";;;;iBAQwB,KAAA,CAAM,OAAA,GAAU,kBAAA"}
1
+ {"version":3,"file":"module.d.mts","names":[],"sources":["../../src/nitro/module.ts"],"mappings":";;;;;iBASwB,KAAA,CAAM,OAAA,GAAU,kBAAA;;eAGvB,KAAA;AAAA"}
@@ -11,6 +11,7 @@ function evlog(options) {
11
11
  nitro.options.plugins = nitro.options.plugins || [];
12
12
  nitro.options.plugins.push(resolve(_dir, "plugin"));
13
13
  if (!nitro.options.errorHandler) nitro.options.errorHandler = resolve(_dir, "errorHandler");
14
+ nitro.options.noExternals = true;
14
15
  nitro.options.runtimeConfig = nitro.options.runtimeConfig || {};
15
16
  nitro.options.runtimeConfig.evlog = options || {};
16
17
  process.env.__EVLOG_CONFIG = JSON.stringify(options || {});
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":[],"sources":["../../src/nitro/module.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { NitroModuleOptions } from '../nitro'\n\nexport type { NitroModuleOptions }\n\nconst _dir = dirname(fileURLToPath(import.meta.url))\n\nexport default function evlog(options?: NitroModuleOptions) {\n return {\n name: 'evlog',\n setup(nitro: any) {\n // Push the plugin (no extension — Nitro's bundler resolves it)\n nitro.options.plugins = nitro.options.plugins || []\n nitro.options.plugins.push(resolve(_dir, 'plugin'))\n\n // Set error handler only if not already configured by user\n if (!nitro.options.errorHandler) {\n nitro.options.errorHandler = resolve(_dir, 'errorHandler')\n }\n\n // Inject config into runtimeConfig — works in production where the\n // plugin is bundled through Nitro's builder and the virtual\n // runtime-config module resolves correctly.\n nitro.options.runtimeConfig = nitro.options.runtimeConfig || {}\n nitro.options.runtimeConfig.evlog = options || {}\n\n // In dev mode, Nitro loads plugins externally (not bundled), so the\n // virtual runtime-config module is unreachable and useRuntimeConfig()\n // returns a stub without our values. process.env is inherited by the\n // Worker Threads that run the dev server, making it a reliable bridge.\n // The plugin reads: useRuntimeConfig().evlog ?? process.env.__EVLOG_CONFIG\n process.env.__EVLOG_CONFIG = JSON.stringify(options || {})\n },\n }\n}\n\nexport { useLogger } from '../runtime/server/useLogger'\n"],"mappings":";;;;;AAMA,MAAM,OAAO,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAEpD,SAAwB,MAAM,SAA8B;AAC1D,QAAO;EACL,MAAM;EACN,MAAM,OAAY;AAEhB,SAAM,QAAQ,UAAU,MAAM,QAAQ,WAAW,EAAE;AACnD,SAAM,QAAQ,QAAQ,KAAK,QAAQ,MAAM,SAAS,CAAC;AAGnD,OAAI,CAAC,MAAM,QAAQ,aACjB,OAAM,QAAQ,eAAe,QAAQ,MAAM,eAAe;AAM5D,SAAM,QAAQ,gBAAgB,MAAM,QAAQ,iBAAiB,EAAE;AAC/D,SAAM,QAAQ,cAAc,QAAQ,WAAW,EAAE;AAOjD,WAAQ,IAAI,iBAAiB,KAAK,UAAU,WAAW,EAAE,CAAC;;EAE7D"}
1
+ {"version":3,"file":"module.mjs","names":[],"sources":["../../src/nitro/module.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Nitro } from 'nitropack'\nimport type { NitroModuleOptions } from '../nitro'\n\nexport type { NitroModuleOptions }\n\nconst _dir = dirname(fileURLToPath(import.meta.url))\n\nexport default function evlog(options?: NitroModuleOptions) {\n return {\n name: 'evlog',\n setup(nitro: Nitro) {\n // Push the plugin (no extension — Nitro's bundler resolves it)\n nitro.options.plugins = nitro.options.plugins || []\n nitro.options.plugins.push(resolve(_dir, 'plugin'))\n\n // Set error handler only if not already configured by user\n if (!nitro.options.errorHandler) {\n nitro.options.errorHandler = resolve(_dir, 'errorHandler')\n }\n\n // explicitly tell nitro to bundle evlog's files to correctly resolve nitro dependencies\n // in nitro v2 we can only disable externals globally\n\n nitro.options.noExternals = true\n\n // Inject config into runtimeConfig — works in production where the\n // plugin is bundled through Nitro's builder and the virtual\n // runtime-config module resolves correctly.\n nitro.options.runtimeConfig = nitro.options.runtimeConfig || {}\n nitro.options.runtimeConfig.evlog = options || {}\n\n // In dev mode, Nitro loads plugins externally (not bundled), so the\n // virtual runtime-config module is unreachable and useRuntimeConfig()\n // returns a stub without our values. process.env is inherited by the\n // Worker Threads that run the dev server, making it a reliable bridge.\n // The plugin reads: useRuntimeConfig().evlog ?? process.env.__EVLOG_CONFIG\n process.env.__EVLOG_CONFIG = JSON.stringify(options || {})\n },\n }\n}\n\nexport { useLogger } from '../runtime/server/useLogger'\n"],"mappings":";;;;;AAOA,MAAM,OAAO,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAEpD,SAAwB,MAAM,SAA8B;AAC1D,QAAO;EACL,MAAM;EACN,MAAM,OAAc;AAElB,SAAM,QAAQ,UAAU,MAAM,QAAQ,WAAW,EAAE;AACnD,SAAM,QAAQ,QAAQ,KAAK,QAAQ,MAAM,SAAS,CAAC;AAGnD,OAAI,CAAC,MAAM,QAAQ,aACjB,OAAM,QAAQ,eAAe,QAAQ,MAAM,eAAe;AAM5D,SAAM,QAAQ,cAAc;AAK5B,SAAM,QAAQ,gBAAgB,MAAM,QAAQ,iBAAiB,EAAE;AAC/D,SAAM,QAAQ,cAAc,QAAQ,WAAW,EAAE;AAOjD,WAAQ,IAAI,iBAAiB,KAAK,UAAU,WAAW,EAAE,CAAC;;EAE7D"}
@@ -1,6 +1,6 @@
1
1
  import { n as resolveEvlogError, r as serializeEvlogErrorResponse, t as extractErrorStatus } from "../../nitro-Da8tEfJ3.mjs";
2
+ import { t as parseURL } from "../../dist-By0jiJRA.mjs";
2
3
  import { defineErrorHandler } from "nitro";
3
- import { parseURL } from "ufo";
4
4
 
5
5
  //#region src/nitro-v3/errorHandler.ts
6
6
  /**
@@ -1,4 +1,3 @@
1
- import "../../nitro-CrFBjY1Y.mjs";
2
1
  import evlog from "./module.mjs";
3
2
  import { useLogger } from "./useLogger.mjs";
4
3
  import { evlogErrorHandler } from "./middleware.mjs";
@@ -1,9 +1,10 @@
1
- import { t as NitroModuleOptions } from "../../nitro-CrFBjY1Y.mjs";
1
+ import { t as NitroModuleOptions } from "../../nitro-mfub2f8G.mjs";
2
+ import { Nitro } from "nitro/types";
2
3
 
3
4
  //#region src/nitro-v3/module.d.ts
4
5
  declare function evlog(options?: NitroModuleOptions): {
5
6
  name: string;
6
- setup(nitro: any): void;
7
+ setup(nitro: Nitro): void;
7
8
  };
8
9
  //#endregion
9
10
  export { type NitroModuleOptions, evlog as default };
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.mts","names":[],"sources":["../../../src/nitro-v3/module.ts"],"mappings":";;;iBAQwB,KAAA,CAAM,OAAA,GAAU,kBAAA"}
1
+ {"version":3,"file":"module.d.mts","names":[],"sources":["../../../src/nitro-v3/module.ts"],"mappings":";;;;iBASwB,KAAA,CAAM,OAAA,GAAU,kBAAA;;eAGvB,KAAA;AAAA"}
@@ -9,6 +9,8 @@ function evlog(options) {
9
9
  setup(nitro) {
10
10
  nitro.options.plugins = nitro.options.plugins || [];
11
11
  nitro.options.plugins.push(resolve(_dir, "plugin"));
12
+ if (!nitro.options.noExternals) nitro.options.noExternals = ["evlog"];
13
+ else if (Array.isArray(nitro.options.noExternals)) nitro.options.noExternals.push("evlog");
12
14
  if (!nitro.options.errorHandler) nitro.options.errorHandler = resolve(_dir, "errorHandler");
13
15
  nitro.options.runtimeConfig = nitro.options.runtimeConfig || {};
14
16
  nitro.options.runtimeConfig.evlog = options || {};
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":[],"sources":["../../../src/nitro-v3/module.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { NitroModuleOptions } from '../nitro'\n\nexport type { NitroModuleOptions }\n\nconst _dir = dirname(fileURLToPath(import.meta.url))\n\nexport default function evlog(options?: NitroModuleOptions) {\n return {\n name: 'evlog',\n setup(nitro: any) {\n // Push the plugin (no extension — Nitro's bundler resolves it)\n nitro.options.plugins = nitro.options.plugins || []\n nitro.options.plugins.push(resolve(_dir, 'plugin'))\n\n // Set error handler only if not already configured by user\n if (!nitro.options.errorHandler) {\n nitro.options.errorHandler = resolve(_dir, 'errorHandler')\n }\n\n // Inject config into runtimeConfig — works in production where the\n // plugin is bundled through Nitro's builder and the virtual\n // runtime-config module resolves correctly.\n nitro.options.runtimeConfig = nitro.options.runtimeConfig || {}\n nitro.options.runtimeConfig.evlog = options || {}\n\n // In dev mode, Nitro loads plugins externally (not bundled), so the\n // virtual runtime-config module is unreachable and useRuntimeConfig()\n // returns a stub without our values. process.env is inherited by the\n // Worker Threads that run the dev server, making it a reliable bridge.\n // The plugin reads: useRuntimeConfig().evlog ?? process.env.__EVLOG_CONFIG\n process.env.__EVLOG_CONFIG = JSON.stringify(options || {})\n },\n }\n}\n"],"mappings":";;;;AAMA,MAAM,OAAO,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAEpD,SAAwB,MAAM,SAA8B;AAC1D,QAAO;EACL,MAAM;EACN,MAAM,OAAY;AAEhB,SAAM,QAAQ,UAAU,MAAM,QAAQ,WAAW,EAAE;AACnD,SAAM,QAAQ,QAAQ,KAAK,QAAQ,MAAM,SAAS,CAAC;AAGnD,OAAI,CAAC,MAAM,QAAQ,aACjB,OAAM,QAAQ,eAAe,QAAQ,MAAM,eAAe;AAM5D,SAAM,QAAQ,gBAAgB,MAAM,QAAQ,iBAAiB,EAAE;AAC/D,SAAM,QAAQ,cAAc,QAAQ,WAAW,EAAE;AAOjD,WAAQ,IAAI,iBAAiB,KAAK,UAAU,WAAW,EAAE,CAAC;;EAE7D"}
1
+ {"version":3,"file":"module.mjs","names":[],"sources":["../../../src/nitro-v3/module.ts"],"sourcesContent":["import { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Nitro } from 'nitro/types'\nimport type { NitroModuleOptions } from '../nitro'\n\nexport type { NitroModuleOptions }\n\nconst _dir = dirname(fileURLToPath(import.meta.url))\n\nexport default function evlog(options?: NitroModuleOptions) {\n return {\n name: 'evlog',\n setup(nitro: Nitro) {\n // Push the plugin (no extension — Nitro's bundler resolves it)\n nitro.options.plugins = nitro.options.plugins || []\n nitro.options.plugins.push(resolve(_dir, 'plugin'))\n\n // explicitly tell nitro to bundle evlog's files to correctly resolve nitro dependencies\n if (!nitro.options.noExternals) {\n nitro.options.noExternals = ['evlog']\n } else if (Array.isArray(nitro.options.noExternals)) {\n nitro.options.noExternals.push('evlog')\n }\n \n\n // Set error handler only if not already configured by user\n if (!nitro.options.errorHandler) {\n nitro.options.errorHandler = resolve(_dir, 'errorHandler')\n }\n\n // Inject config into runtimeConfig — works in production where the\n // plugin is bundled through Nitro's builder and the virtual\n // runtime-config module resolves correctly.\n nitro.options.runtimeConfig = nitro.options.runtimeConfig || {}\n nitro.options.runtimeConfig.evlog = options || {}\n\n // In dev mode, Nitro loads plugins externally (not bundled), so the\n // virtual runtime-config module is unreachable and useRuntimeConfig()\n // returns a stub without our values. process.env is inherited by the\n // Worker Threads that run the dev server, making it a reliable bridge.\n // The plugin reads: useRuntimeConfig().evlog ?? process.env.__EVLOG_CONFIG\n process.env.__EVLOG_CONFIG = JSON.stringify(options || {})\n },\n }\n}\n"],"mappings":";;;;AAOA,MAAM,OAAO,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAEpD,SAAwB,MAAM,SAA8B;AAC1D,QAAO;EACL,MAAM;EACN,MAAM,OAAc;AAElB,SAAM,QAAQ,UAAU,MAAM,QAAQ,WAAW,EAAE;AACnD,SAAM,QAAQ,QAAQ,KAAK,QAAQ,MAAM,SAAS,CAAC;AAGnD,OAAI,CAAC,MAAM,QAAQ,YACjB,OAAM,QAAQ,cAAc,CAAC,QAAQ;YAC5B,MAAM,QAAQ,MAAM,QAAQ,YAAY,CACjD,OAAM,QAAQ,YAAY,KAAK,QAAQ;AAKzC,OAAI,CAAC,MAAM,QAAQ,aACjB,OAAM,QAAQ,eAAe,QAAQ,MAAM,eAAe;AAM5D,SAAM,QAAQ,gBAAgB,MAAM,QAAQ,iBAAiB,EAAE;AAC/D,SAAM,QAAQ,cAAc,QAAQ,WAAW,EAAE;AAOjD,WAAQ,IAAI,iBAAiB,KAAK,UAAU,WAAW,EAAE,CAAC;;EAE7D"}
@@ -2,9 +2,9 @@ import { filterSafeHeaders } from "../../utils.mjs";
2
2
  import { createRequestLogger, initLogger, isEnabled } from "../../logger.mjs";
3
3
  import { n as shouldLog, t as getServiceForPath } from "../../routes-BNbrnm14.mjs";
4
4
  import { t as extractErrorStatus } from "../../nitro-Da8tEfJ3.mjs";
5
+ import { t as parseURL } from "../../dist-By0jiJRA.mjs";
5
6
  import { definePlugin } from "nitro";
6
7
  import { useRuntimeConfig } from "nitro/runtime-config";
7
- import { parseURL } from "ufo";
8
8
 
9
9
  //#region src/nitro-v3/plugin.ts
10
10
  function getContext(event) {
@@ -39,4 +39,4 @@ interface NitroModuleOptions {
39
39
  }
40
40
  //#endregion
41
41
  export { NitroModuleOptions as t };
42
- //# sourceMappingURL=nitro-CrFBjY1Y.d.mts.map
42
+ //# sourceMappingURL=nitro-mfub2f8G.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nitro-CrFBjY1Y.d.mts","names":[],"sources":["../src/nitro.ts"],"mappings":";;;UAIiB,kBAAA;EAAA;;;;EAKf,OAAA;EA8BwB;;;EAzBxB,GAAA,GAAM,OAAA,CAAQ,kBAAA;EA8BW;;;;EAxBzB,MAAA;EAAA;;;;;EAOA,OAAA;EAiBA;;;;;EAVA,OAAA;;;;EAKA,MAAA,GAAS,MAAA,SAAe,WAAA;;;;EAKxB,QAAA,GAAW,cAAA;AAAA"}
1
+ {"version":3,"file":"nitro-mfub2f8G.d.mts","names":[],"sources":["../src/nitro.ts"],"mappings":";;;UAIiB,kBAAA;EAAA;;;;EAKf,OAAA;EA8BwB;;;EAzBxB,GAAA,GAAM,OAAA,CAAQ,kBAAA;EA8BW;;;;EAxBzB,MAAA;EAAA;;;;;EAOA,OAAA;EAiBA;;;;;EAVA,OAAA;;;;EAKA,MAAA,GAAS,MAAA,SAAe,WAAA;;;;EAKxB,QAAA,GAAW,cAAA;AAAA"}
@@ -40,6 +40,13 @@ interface ModuleOptions {
40
40
  * Environment context overrides.
41
41
  */
42
42
  env?: Partial<EnvironmentContext>;
43
+ /**
44
+ * Enable or disable browser console output.
45
+ * When false, client-side logs are suppressed in the browser DevTools console
46
+ * but still sent to the server via transport (if enabled).
47
+ * @default true
48
+ */
49
+ console?: boolean;
43
50
  /**
44
51
  * Enable pretty printing.
45
52
  * @default true in development, false in production
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.mts","names":[],"sources":["../../src/nuxt/module.ts"],"mappings":";;;;UAaU,qBAAA;;EAER,OAAA;EAFQ;EAIR,KAAA;;EAEA,KAAA;EAJA;EAMA,OAAA;AAAA;AAAA,UAGQ,qBAAA;EAHD;;AAAA;;;EASP,OAAA;EAEO;EAAP,OAAA;AAAA;AAAA,UAGQ,yBAAA;EAER;EAAA,OAAA;EAKG;EAHH,OAAA;AAAA;AAAA,KAGG,iBAAA,GAAoB,qBAAA,IAAyB,qBAAA,GAAwB,yBAAA;AAAA,UAEzD,aAAA;EAFyD;;;;;EAQxE,OAAA;EARiG;;AAEnG;EAWE,GAAA,GAAM,OAAA,CAAQ,kBAAA;;;;;EAMd,MAAA;EAiDW;;;;;;EAzCX,OAAA;EAyIe;;;;;;EAjIf,OAAA;EAAA;;;;;;;;;;;;;EAeA,MAAA,GAAS,MAAA,SAAe,WAAA;EAmED;;;;;;;;;;;;;;;;EAjDvB,QAAA,GAAW,cAAA;EA0GF;AACV;;;;;;;;;;EA9FC,SAAA,GAAY,eAAA;;;;;;;;;;;;;EAcZ,KAAA,GAAQ,iBAAA;;;;;;;;;;;;;;;EAgBR,IAAA;2DAEE,QAAA;IAEA,WAAA;IAEA,kBAAA,GAAqB,MAAA;IAErB,OAAA,GAAU,MAAA;IAEV,OAAA;EAAA;;;;;;;;;;;;;EAeF,OAAA;kCAEE,MAAA;IAEA,IAAA;IAEA,OAAA;EAAA;;;;;;;;;;;;EAcF,MAAA;qBAEE,GAAA;IAEA,WAAA;IAEA,OAAA;IAEA,IAAA,GAAO,MAAA;IAEP,OAAA;EAAA;;;;;;EAQF,SAAA;AAAA;AAAA,cACD,QAAA"}
1
+ {"version":3,"file":"module.d.mts","names":[],"sources":["../../src/nuxt/module.ts"],"mappings":";;;;UAaU,qBAAA;;EAER,OAAA;EAFQ;EAIR,KAAA;;EAEA,KAAA;EAJA;EAMA,OAAA;AAAA;AAAA,UAGQ,qBAAA;EAHD;;AAAA;;;EASP,OAAA;EAEO;EAAP,OAAA;AAAA;AAAA,UAGQ,yBAAA;EAER;EAAA,OAAA;EAKG;EAHH,OAAA;AAAA;AAAA,KAGG,iBAAA,GAAoB,qBAAA,IAAyB,qBAAA,GAAwB,yBAAA;AAAA,UAEzD,aAAA;EAFyD;;;;;EAQxE,OAAA;EARiG;;AAEnG;EAWE,GAAA,GAAM,OAAA,CAAQ,kBAAA;;;;;;;EAQd,OAAA;EAkFQ;;;;EA5ER,MAAA;EAiJe;;;;;;EAzIf,OAAA;EAAA;;;;;;EAQA,OAAA;EA8CA;;;;;;;;;;;;;EA/BA,MAAA,GAAS,MAAA,SAAe,WAAA;EA0FtB;;;;;;;;;;;;AAmCH;;;;EA3GC,QAAA,GAAW,cAAA;;;;;;;;;;;;EAaX,SAAA,GAAY,eAAA;;;;;;;;;;;;;EAcZ,KAAA,GAAQ,iBAAA;;;;;;;;;;;;;;;EAgBR,IAAA;2DAEE,QAAA;IAEA,WAAA;IAEA,kBAAA,GAAqB,MAAA;IAErB,OAAA,GAAU,MAAA;IAEV,OAAA;EAAA;;;;;;;;;;;;;EAeF,OAAA;kCAEE,MAAA;IAEA,IAAA;IAEA,OAAA;EAAA;;;;;;;;;;;;EAcF,MAAA;qBAEE,GAAA;IAEA,WAAA;IAEA,OAAA;IAEA,IAAA,GAAO,MAAA;IAEP,OAAA;EAAA;;;;;;EAQF,SAAA;AAAA;AAAA,cACD,QAAA"}
@@ -2,7 +2,7 @@ import { addImports, addPlugin, addServerHandler, addServerImports, addServerPlu
2
2
 
3
3
  //#region package.json
4
4
  var name = "evlog";
5
- var version = "2.0.0";
5
+ var version = "2.1.0";
6
6
 
7
7
  //#endregion
8
8
  //#region src/nuxt/module.ts
@@ -24,6 +24,7 @@ var module_default = defineNuxtModule({
24
24
  nuxt.options.runtimeConfig.evlog = options;
25
25
  nuxt.options.runtimeConfig.public.evlog = {
26
26
  enabled: options.enabled ?? true,
27
+ console: options.console,
27
28
  pretty: options.pretty,
28
29
  transport: {
29
30
  enabled: transportEnabled,
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":[],"sources":["../../package.json","../../src/nuxt/module.ts"],"sourcesContent":["","import {\n addImports,\n addPlugin,\n addServerHandler,\n addServerImports,\n addServerPlugin,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit'\nimport type { NitroConfig } from 'nitropack'\nimport type { EnvironmentContext, RouteConfig, SamplingConfig, TransportConfig } from '../types'\nimport { name, version } from '../../package.json'\n\ninterface ModuleAxiomBaseConfig {\n /** Axiom dataset name */\n dataset: string\n /** Axiom API token */\n token: string\n /** Organization ID (required for Personal Access Tokens) */\n orgId?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n}\n\ninterface ModuleAxiomEdgeConfig {\n /**\n * Edge URL for Axiom ingest/query endpoints.\n * If no path is provided, uses /v1/ingest/{dataset}.\n * If a custom path is provided, it is used as-is (trailing slash trimmed).\n */\n edgeUrl: string\n /** Mutually exclusive with edgeUrl. */\n baseUrl?: never\n}\n\ninterface ModuleAxiomEndpointConfig {\n /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n baseUrl?: string\n /** Mutually exclusive with baseUrl. */\n edgeUrl?: never\n}\n\ntype ModuleAxiomConfig = ModuleAxiomBaseConfig & (ModuleAxiomEdgeConfig | ModuleAxiomEndpointConfig)\n\nexport interface ModuleOptions {\n /**\n * Enable or disable all logging globally.\n * When false, all emits, tagged logs, and request logger operations become no-ops.\n * @default true\n */\n enabled?: boolean\n\n /**\n * Environment context overrides.\n */\n env?: Partial<EnvironmentContext>\n\n /**\n * Enable pretty printing.\n * @default true in development, false in production\n */\n pretty?: boolean\n\n /**\n * Route patterns to include in logging.\n * Supports glob patterns like '/api/**'.\n * If not set, all routes are logged.\n * @example ['/api/**', '/auth/**']\n */\n include?: string[]\n\n /**\n * Route patterns to exclude from logging.\n * Supports glob patterns like '/api/_nuxt_icon/**'.\n * Exclusions take precedence over inclusions.\n * @example ['/api/_nuxt_icon/**', '/health']\n */\n exclude?: string[]\n\n /**\n * Route-specific service configuration.\n * Allows setting different service names for different routes.\n * Patterns are matched using glob syntax.\n *\n * @example\n * ```ts\n * routes: {\n * '/api/foo/**': { service: 'service1' },\n * '/api/bar/**': { service: 'service2' }\n * }\n * ```\n */\n routes?: Record<string, RouteConfig>\n\n /**\n * Sampling configuration for filtering logs.\n * Allows configuring what percentage of logs to keep per level.\n *\n * @example\n * ```ts\n * sampling: {\n * rates: {\n * info: 10, // Keep 10% of info logs\n * warn: 50, // Keep 50% of warning logs\n * debug: 5, // Keep 5% of debug logs\n * error: 100, // Always keep errors (default)\n * }\n * }\n * ```\n */\n sampling?: SamplingConfig\n\n /**\n * Transport configuration for sending client logs to the server.\n *\n * @example\n * ```ts\n * transport: {\n * enabled: true, // Send logs to server API\n * endpoint: '/api/_evlog/ingest' // Custom endpoint\n * }\n * ```\n */\n transport?: TransportConfig\n\n /**\n * Axiom adapter configuration.\n * When configured, use `createAxiomDrain()` from `evlog/axiom` to send logs.\n *\n * @example\n * ```ts\n * axiom: {\n * dataset: 'my-app-logs',\n * token: process.env.AXIOM_TOKEN,\n * }\n * ```\n */\n axiom?: ModuleAxiomConfig\n\n /**\n * OTLP adapter configuration.\n * When configured, use `createOTLPDrain()` from `evlog/otlp` to send logs.\n *\n * @example\n * ```ts\n * otlp: {\n * endpoint: 'http://localhost:4318',\n * headers: {\n * 'Authorization': `Basic ${process.env.GRAFANA_TOKEN}`,\n * },\n * }\n * ```\n */\n otlp?: {\n /** OTLP HTTP endpoint (e.g., http://localhost:4318) */\n endpoint: string\n /** Override service name (defaults to event.service) */\n serviceName?: string\n /** Additional resource attributes */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Custom headers (e.g., for authentication) */\n headers?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * PostHog adapter configuration.\n * When configured, use `createPostHogDrain()` from `evlog/posthog` to send logs\n * via PostHog Logs (OTLP).\n *\n * @example\n * ```ts\n * posthog: {\n * apiKey: process.env.POSTHOG_API_KEY,\n * }\n * ```\n */\n posthog?: {\n /** PostHog project API key */\n apiKey: string\n /** PostHog host URL. Default: https://us.i.posthog.com */\n host?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * Sentry adapter configuration.\n * When configured, use `createSentryDrain()` from `evlog/sentry` to send logs.\n *\n * @example\n * ```ts\n * sentry: {\n * dsn: process.env.SENTRY_DSN,\n * }\n * ```\n */\n sentry?: {\n /** Sentry DSN */\n dsn: string\n /** Environment override (defaults to event.environment) */\n environment?: string\n /** Release version override (defaults to event.version) */\n release?: string\n /** Additional tags to attach as attributes */\n tags?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * How long to retain events before cleanup (used by @evlog/nuxthub).\n * Supports \"30d\" (days), \"24h\" (hours), \"60m\" (minutes).\n * @default '30d'\n */\n retention?: string\n}\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name,\n version,\n configKey: name,\n docs: 'https://evlog.dev',\n },\n defaults: {},\n setup(options, nuxt) {\n const resolver = createResolver(import.meta.url)\n\n const transportEnabled = options.transport?.enabled ?? false\n const transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n\n // Register custom error handler for proper EvlogError serialization\n // Only set if not already configured to avoid overwriting user's custom handler\n // @ts-expect-error nitro:config hook exists but is not in NuxtHooks type\n nuxt.hook('nitro:config', (nitroConfig: NitroConfig) => {\n nitroConfig.errorHandler = nitroConfig.errorHandler || resolver.resolve('../nitro/errorHandler')\n })\n\n nuxt.options.runtimeConfig.evlog = options\n nuxt.options.runtimeConfig.public.evlog = {\n enabled: options.enabled ?? true,\n pretty: options.pretty,\n transport: {\n enabled: transportEnabled,\n endpoint: transportEndpoint,\n },\n }\n\n if (transportEnabled) {\n addServerHandler({\n route: transportEndpoint,\n method: 'post',\n handler: resolver.resolve('../runtime/server/routes/_evlog/ingest.post'),\n })\n }\n\n addServerPlugin(resolver.resolve('../nitro/plugin'))\n\n addPlugin({\n src: resolver.resolve('../runtime/client/plugin'),\n mode: 'client',\n })\n\n addImports([\n {\n name: 'log',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'setIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'clearIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n {\n name: 'parseError',\n from: resolver.resolve('../runtime/utils/parseError'),\n },\n ])\n\n addServerImports([\n {\n name: 'useLogger',\n from: resolver.resolve('../runtime/server/useLogger'),\n },\n {\n name: 'log',\n from: resolver.resolve('../logger'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n ])\n },\n})\n"],"mappings":";;;;;;;;AC2NA,qBAAe,iBAAgC;CAC7C,MAAM;EACJ;EACA;EACA,WAAW;EACX,MAAM;EACP;CACD,UAAU,EAAE;CACZ,MAAM,SAAS,MAAM;EACnB,MAAM,WAAW,eAAe,OAAO,KAAK,IAAI;EAEhD,MAAM,mBAAmB,QAAQ,WAAW,WAAW;EACvD,MAAM,oBAAoB,QAAQ,WAAW,YAAY;AAKzD,OAAK,KAAK,iBAAiB,gBAA6B;AACtD,eAAY,eAAe,YAAY,gBAAgB,SAAS,QAAQ,wBAAwB;IAChG;AAEF,OAAK,QAAQ,cAAc,QAAQ;AACnC,OAAK,QAAQ,cAAc,OAAO,QAAQ;GACxC,SAAS,QAAQ,WAAW;GAC5B,QAAQ,QAAQ;GAChB,WAAW;IACT,SAAS;IACT,UAAU;IACX;GACF;AAED,MAAI,iBACF,kBAAiB;GACf,OAAO;GACP,QAAQ;GACR,SAAS,SAAS,QAAQ,8CAA8C;GACzE,CAAC;AAGJ,kBAAgB,SAAS,QAAQ,kBAAkB,CAAC;AAEpD,YAAU;GACR,KAAK,SAAS,QAAQ,2BAA2B;GACjD,MAAM;GACP,CAAC;AAEF,aAAW;GACT;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACF,CAAC;AAEF,mBAAiB;GACf;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,YAAY;IACpC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACF,CAAC;;CAEL,CAAC"}
1
+ {"version":3,"file":"module.mjs","names":[],"sources":["../../package.json","../../src/nuxt/module.ts"],"sourcesContent":["","import {\n addImports,\n addPlugin,\n addServerHandler,\n addServerImports,\n addServerPlugin,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit'\nimport type { NitroConfig } from 'nitropack'\nimport type { EnvironmentContext, RouteConfig, SamplingConfig, TransportConfig } from '../types'\nimport { name, version } from '../../package.json'\n\ninterface ModuleAxiomBaseConfig {\n /** Axiom dataset name */\n dataset: string\n /** Axiom API token */\n token: string\n /** Organization ID (required for Personal Access Tokens) */\n orgId?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n}\n\ninterface ModuleAxiomEdgeConfig {\n /**\n * Edge URL for Axiom ingest/query endpoints.\n * If no path is provided, uses /v1/ingest/{dataset}.\n * If a custom path is provided, it is used as-is (trailing slash trimmed).\n */\n edgeUrl: string\n /** Mutually exclusive with edgeUrl. */\n baseUrl?: never\n}\n\ninterface ModuleAxiomEndpointConfig {\n /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n baseUrl?: string\n /** Mutually exclusive with baseUrl. */\n edgeUrl?: never\n}\n\ntype ModuleAxiomConfig = ModuleAxiomBaseConfig & (ModuleAxiomEdgeConfig | ModuleAxiomEndpointConfig)\n\nexport interface ModuleOptions {\n /**\n * Enable or disable all logging globally.\n * When false, all emits, tagged logs, and request logger operations become no-ops.\n * @default true\n */\n enabled?: boolean\n\n /**\n * Environment context overrides.\n */\n env?: Partial<EnvironmentContext>\n\n /**\n * Enable or disable browser console output.\n * When false, client-side logs are suppressed in the browser DevTools console\n * but still sent to the server via transport (if enabled).\n * @default true\n */\n console?: boolean\n\n /**\n * Enable pretty printing.\n * @default true in development, false in production\n */\n pretty?: boolean\n\n /**\n * Route patterns to include in logging.\n * Supports glob patterns like '/api/**'.\n * If not set, all routes are logged.\n * @example ['/api/**', '/auth/**']\n */\n include?: string[]\n\n /**\n * Route patterns to exclude from logging.\n * Supports glob patterns like '/api/_nuxt_icon/**'.\n * Exclusions take precedence over inclusions.\n * @example ['/api/_nuxt_icon/**', '/health']\n */\n exclude?: string[]\n\n /**\n * Route-specific service configuration.\n * Allows setting different service names for different routes.\n * Patterns are matched using glob syntax.\n *\n * @example\n * ```ts\n * routes: {\n * '/api/foo/**': { service: 'service1' },\n * '/api/bar/**': { service: 'service2' }\n * }\n * ```\n */\n routes?: Record<string, RouteConfig>\n\n /**\n * Sampling configuration for filtering logs.\n * Allows configuring what percentage of logs to keep per level.\n *\n * @example\n * ```ts\n * sampling: {\n * rates: {\n * info: 10, // Keep 10% of info logs\n * warn: 50, // Keep 50% of warning logs\n * debug: 5, // Keep 5% of debug logs\n * error: 100, // Always keep errors (default)\n * }\n * }\n * ```\n */\n sampling?: SamplingConfig\n\n /**\n * Transport configuration for sending client logs to the server.\n *\n * @example\n * ```ts\n * transport: {\n * enabled: true, // Send logs to server API\n * endpoint: '/api/_evlog/ingest' // Custom endpoint\n * }\n * ```\n */\n transport?: TransportConfig\n\n /**\n * Axiom adapter configuration.\n * When configured, use `createAxiomDrain()` from `evlog/axiom` to send logs.\n *\n * @example\n * ```ts\n * axiom: {\n * dataset: 'my-app-logs',\n * token: process.env.AXIOM_TOKEN,\n * }\n * ```\n */\n axiom?: ModuleAxiomConfig\n\n /**\n * OTLP adapter configuration.\n * When configured, use `createOTLPDrain()` from `evlog/otlp` to send logs.\n *\n * @example\n * ```ts\n * otlp: {\n * endpoint: 'http://localhost:4318',\n * headers: {\n * 'Authorization': `Basic ${process.env.GRAFANA_TOKEN}`,\n * },\n * }\n * ```\n */\n otlp?: {\n /** OTLP HTTP endpoint (e.g., http://localhost:4318) */\n endpoint: string\n /** Override service name (defaults to event.service) */\n serviceName?: string\n /** Additional resource attributes */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Custom headers (e.g., for authentication) */\n headers?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * PostHog adapter configuration.\n * When configured, use `createPostHogDrain()` from `evlog/posthog` to send logs\n * via PostHog Logs (OTLP).\n *\n * @example\n * ```ts\n * posthog: {\n * apiKey: process.env.POSTHOG_API_KEY,\n * }\n * ```\n */\n posthog?: {\n /** PostHog project API key */\n apiKey: string\n /** PostHog host URL. Default: https://us.i.posthog.com */\n host?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * Sentry adapter configuration.\n * When configured, use `createSentryDrain()` from `evlog/sentry` to send logs.\n *\n * @example\n * ```ts\n * sentry: {\n * dsn: process.env.SENTRY_DSN,\n * }\n * ```\n */\n sentry?: {\n /** Sentry DSN */\n dsn: string\n /** Environment override (defaults to event.environment) */\n environment?: string\n /** Release version override (defaults to event.version) */\n release?: string\n /** Additional tags to attach as attributes */\n tags?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * How long to retain events before cleanup (used by @evlog/nuxthub).\n * Supports \"30d\" (days), \"24h\" (hours), \"60m\" (minutes).\n * @default '30d'\n */\n retention?: string\n}\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name,\n version,\n configKey: name,\n docs: 'https://evlog.dev',\n },\n defaults: {},\n setup(options, nuxt) {\n const resolver = createResolver(import.meta.url)\n\n const transportEnabled = options.transport?.enabled ?? false\n const transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n\n // Register custom error handler for proper EvlogError serialization\n // Only set if not already configured to avoid overwriting user's custom handler\n // @ts-expect-error nitro:config hook exists but is not in NuxtHooks type\n nuxt.hook('nitro:config', (nitroConfig: NitroConfig) => {\n nitroConfig.errorHandler = nitroConfig.errorHandler || resolver.resolve('../nitro/errorHandler')\n })\n\n nuxt.options.runtimeConfig.evlog = options\n nuxt.options.runtimeConfig.public.evlog = {\n enabled: options.enabled ?? true,\n console: options.console,\n pretty: options.pretty,\n transport: {\n enabled: transportEnabled,\n endpoint: transportEndpoint,\n },\n }\n\n if (transportEnabled) {\n addServerHandler({\n route: transportEndpoint,\n method: 'post',\n handler: resolver.resolve('../runtime/server/routes/_evlog/ingest.post'),\n })\n }\n\n addServerPlugin(resolver.resolve('../nitro/plugin'))\n\n addPlugin({\n src: resolver.resolve('../runtime/client/plugin'),\n mode: 'client',\n })\n\n addImports([\n {\n name: 'log',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'setIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'clearIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n {\n name: 'parseError',\n from: resolver.resolve('../runtime/utils/parseError'),\n },\n ])\n\n addServerImports([\n {\n name: 'useLogger',\n from: resolver.resolve('../runtime/server/useLogger'),\n },\n {\n name: 'log',\n from: resolver.resolve('../logger'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n ])\n },\n})\n"],"mappings":";;;;;;;;ACmOA,qBAAe,iBAAgC;CAC7C,MAAM;EACJ;EACA;EACA,WAAW;EACX,MAAM;EACP;CACD,UAAU,EAAE;CACZ,MAAM,SAAS,MAAM;EACnB,MAAM,WAAW,eAAe,OAAO,KAAK,IAAI;EAEhD,MAAM,mBAAmB,QAAQ,WAAW,WAAW;EACvD,MAAM,oBAAoB,QAAQ,WAAW,YAAY;AAKzD,OAAK,KAAK,iBAAiB,gBAA6B;AACtD,eAAY,eAAe,YAAY,gBAAgB,SAAS,QAAQ,wBAAwB;IAChG;AAEF,OAAK,QAAQ,cAAc,QAAQ;AACnC,OAAK,QAAQ,cAAc,OAAO,QAAQ;GACxC,SAAS,QAAQ,WAAW;GAC5B,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,WAAW;IACT,SAAS;IACT,UAAU;IACX;GACF;AAED,MAAI,iBACF,kBAAiB;GACf,OAAO;GACP,QAAQ;GACR,SAAS,SAAS,QAAQ,8CAA8C;GACzE,CAAC;AAGJ,kBAAgB,SAAS,QAAQ,kBAAkB,CAAC;AAEpD,YAAU;GACR,KAAK,SAAS,QAAQ,2BAA2B;GACjD,MAAM;GACP,CAAC;AAEF,aAAW;GACT;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACF,CAAC;AAEF,mBAAiB;GACf;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,YAAY;IACpC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACF,CAAC;;CAEL,CAAC"}
@@ -5,6 +5,7 @@ declare function setIdentity(identity: Record<string, unknown>): void;
5
5
  declare function clearIdentity(): void;
6
6
  declare function initLog(options?: {
7
7
  enabled?: boolean;
8
+ console?: boolean;
8
9
  pretty?: boolean;
9
10
  service?: string;
10
11
  transport?: TransportConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"log.d.mts","names":[],"sources":["../../../src/runtime/client/log.ts"],"mappings":";;;iBAYgB,WAAA,CAAY,QAAA,EAAU,MAAA;AAAA,iBAItB,aAAA,CAAA;AAAA,iBAWA,OAAA,CAAQ,OAAA;EAAW,OAAA;EAAmB,MAAA;EAAkB,OAAA;EAAkB,SAAA,GAAY,eAAA;AAAA;AAAA,cAgFhG,UAAA,EAAY,GAAA"}
1
+ {"version":3,"file":"log.d.mts","names":[],"sources":["../../../src/runtime/client/log.ts"],"mappings":";;;iBAagB,WAAA,CAAY,QAAA,EAAU,MAAA;AAAA,iBAItB,aAAA,CAAA;AAAA,iBAWA,OAAA,CAAQ,OAAA;EAAW,OAAA;EAAmB,OAAA;EAAmB,MAAA;EAAkB,OAAA;EAAkB,SAAA,GAAY,eAAA;AAAA;AAAA,cAoFnH,UAAA,EAAY,GAAA"}
@@ -3,6 +3,7 @@ import { getConsoleMethod } from "../../utils.mjs";
3
3
  //#region src/runtime/client/log.ts
4
4
  const isClient = typeof window !== "undefined";
5
5
  let clientEnabled = true;
6
+ let clientConsole = true;
6
7
  let clientPretty = true;
7
8
  let clientService = "client";
8
9
  let transportEnabled = false;
@@ -22,6 +23,7 @@ const LEVEL_COLORS = {
22
23
  };
23
24
  function initLog(options = {}) {
24
25
  clientEnabled = typeof options.enabled === "boolean" ? options.enabled : true;
26
+ clientConsole = typeof options.console === "boolean" ? options.console : true;
25
27
  clientPretty = typeof options.pretty === "boolean" ? options.pretty : true;
26
28
  clientService = options.service ?? "client";
27
29
  transportEnabled = options.transport?.enabled ?? false;
@@ -48,17 +50,19 @@ function emitLog(level, event) {
48
50
  ...identityContext,
49
51
  ...event
50
52
  };
51
- const method = getConsoleMethod(level);
52
- if (clientPretty) {
53
- const { level: lvl, service, ...rest } = formatted;
54
- console[method](`%c[${service}]%c ${lvl}`, LEVEL_COLORS[lvl] || "", "color: inherit", rest);
55
- } else console[method](JSON.stringify(formatted));
53
+ if (clientConsole) {
54
+ const method = getConsoleMethod(level);
55
+ if (clientPretty) {
56
+ const { level: lvl, service, ...rest } = formatted;
57
+ console[method](`%c[${service}]%c ${lvl}`, LEVEL_COLORS[lvl] || "", "color: inherit", rest);
58
+ } else console[method](JSON.stringify(formatted));
59
+ }
56
60
  sendToServer(formatted);
57
61
  }
58
62
  function emitTaggedLog(level, tag, message) {
59
63
  if (!clientEnabled) return;
60
64
  if (clientPretty) {
61
- console[getConsoleMethod(level)](`%c[${tag}]%c ${message}`, LEVEL_COLORS[level] || "", "color: inherit");
65
+ if (clientConsole) console[getConsoleMethod(level)](`%c[${tag}]%c ${message}`, LEVEL_COLORS[level] || "", "color: inherit");
62
66
  sendToServer({
63
67
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
64
68
  level,
@@ -1 +1 @@
1
- {"version":3,"file":"log.mjs","names":[],"sources":["../../../src/runtime/client/log.ts"],"sourcesContent":["import type { Log, LogLevel, TransportConfig } from '../../types'\nimport { getConsoleMethod } from '../../utils'\n\nconst isClient = typeof window !== 'undefined'\n\nlet clientEnabled = true\nlet clientPretty = true\nlet clientService = 'client'\nlet transportEnabled = false\nlet transportEndpoint = '/api/_evlog/ingest'\nlet identityContext: Record<string, unknown> = {}\n\nexport function setIdentity(identity: Record<string, unknown>): void {\n identityContext = { ...identity }\n}\n\nexport function clearIdentity(): void {\n identityContext = {}\n}\n\nconst LEVEL_COLORS: Record<string, string> = {\n error: 'color: #ef4444; font-weight: bold',\n warn: 'color: #f59e0b; font-weight: bold',\n info: 'color: #06b6d4; font-weight: bold',\n debug: 'color: #6b7280; font-weight: bold',\n}\n\nexport function initLog(options: { enabled?: boolean, pretty?: boolean, service?: string, transport?: TransportConfig } = {}): void {\n clientEnabled = typeof options.enabled === 'boolean' ? options.enabled : true\n clientPretty = typeof options.pretty === 'boolean' ? options.pretty : true\n clientService = options.service ?? 'client'\n transportEnabled = options.transport?.enabled ?? false\n transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n}\n\nasync function sendToServer(event: Record<string, unknown>): Promise<void> {\n if (!transportEnabled) return\n\n try {\n await fetch(transportEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(event),\n keepalive: true,\n credentials: 'same-origin',\n })\n } catch {\n // Silently fail - don't break the app\n }\n}\n\nfunction emitLog(level: LogLevel, event: Record<string, unknown>): void {\n if (!clientEnabled) return\n\n const formatted = {\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n ...event,\n }\n\n const method = getConsoleMethod(level)\n\n if (clientPretty) {\n const { level: lvl, service, ...rest } = formatted\n console[method](`%c[${service}]%c ${lvl}`, LEVEL_COLORS[lvl] || '', 'color: inherit', rest)\n } else {\n console[method](JSON.stringify(formatted))\n }\n\n sendToServer(formatted)\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!clientEnabled) return\n if (clientPretty) {\n console[getConsoleMethod(level)](`%c[${tag}]%c ${message}`, LEVEL_COLORS[level] || '', 'color: inherit')\n sendToServer({\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n tag,\n message,\n })\n } else {\n emitLog(level, { tag, message })\n }\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n if (!(import.meta.client ?? isClient)) {\n return\n }\n\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitLog(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\nconst _clientLog: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _clientLog as log }\n"],"mappings":";;;AAGA,MAAM,WAAW,OAAO,WAAW;AAEnC,IAAI,gBAAgB;AACpB,IAAI,eAAe;AACnB,IAAI,gBAAgB;AACpB,IAAI,mBAAmB;AACvB,IAAI,oBAAoB;AACxB,IAAI,kBAA2C,EAAE;AAEjD,SAAgB,YAAY,UAAyC;AACnE,mBAAkB,EAAE,GAAG,UAAU;;AAGnC,SAAgB,gBAAsB;AACpC,mBAAkB,EAAE;;AAGtB,MAAM,eAAuC;CAC3C,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR;AAED,SAAgB,QAAQ,UAAkG,EAAE,EAAQ;AAClI,iBAAgB,OAAO,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACzE,gBAAe,OAAO,QAAQ,WAAW,YAAY,QAAQ,SAAS;AACtE,iBAAgB,QAAQ,WAAW;AACnC,oBAAmB,QAAQ,WAAW,WAAW;AACjD,qBAAoB,QAAQ,WAAW,YAAY;;AAGrD,eAAe,aAAa,OAA+C;AACzE,KAAI,CAAC,iBAAkB;AAEvB,KAAI;AACF,QAAM,MAAM,mBAAmB;GAC7B,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,MAAM;GAC3B,WAAW;GACX,aAAa;GACd,CAAC;SACI;;AAKV,SAAS,QAAQ,OAAiB,OAAsC;AACtE,KAAI,CAAC,cAAe;CAEpB,MAAM,YAAY;EAChB,4BAAW,IAAI,MAAM,EAAC,aAAa;EACnC;EACA,SAAS;EACT,GAAG;EACH,GAAG;EACJ;CAED,MAAM,SAAS,iBAAiB,MAAM;AAEtC,KAAI,cAAc;EAChB,MAAM,EAAE,OAAO,KAAK,SAAS,GAAG,SAAS;AACzC,UAAQ,QAAQ,MAAM,QAAQ,MAAM,OAAO,aAAa,QAAQ,IAAI,kBAAkB,KAAK;OAE3F,SAAQ,QAAQ,KAAK,UAAU,UAAU,CAAC;AAG5C,cAAa,UAAU;;AAGzB,SAAS,cAAc,OAAiB,KAAa,SAAuB;AAC1E,KAAI,CAAC,cAAe;AACpB,KAAI,cAAc;AAChB,UAAQ,iBAAiB,MAAM,EAAE,MAAM,IAAI,MAAM,WAAW,aAAa,UAAU,IAAI,iBAAiB;AACxG,eAAa;GACX,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC;GACA,SAAS;GACT,GAAG;GACH;GACA;GACD,CAAC;OAEF,SAAQ,OAAO;EAAE;EAAK;EAAS,CAAC;;AAIpC,SAAS,gBAAgB,OAAiB;AACxC,QAAO,SAAS,UAAU,YAA8C,SAAwB;AAC9F,MAAI,EAAE,OAAO,KAAK,UAAU,UAC1B;AAGF,MAAI,OAAO,eAAe,YAAY,YAAY,OAChD,eAAc,OAAO,YAAY,QAAQ;WAChC,OAAO,eAAe,SAC/B,SAAQ,OAAO,WAAW;MAE1B,eAAc,OAAO,OAAO,OAAO,WAAW,CAAC;;;AAKrD,MAAM,aAAkB;CACtB,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAC/B,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAChC"}
1
+ {"version":3,"file":"log.mjs","names":[],"sources":["../../../src/runtime/client/log.ts"],"sourcesContent":["import type { Log, LogLevel, TransportConfig } from '../../types'\nimport { getConsoleMethod } from '../../utils'\n\nconst isClient = typeof window !== 'undefined'\n\nlet clientEnabled = true\nlet clientConsole = true\nlet clientPretty = true\nlet clientService = 'client'\nlet transportEnabled = false\nlet transportEndpoint = '/api/_evlog/ingest'\nlet identityContext: Record<string, unknown> = {}\n\nexport function setIdentity(identity: Record<string, unknown>): void {\n identityContext = { ...identity }\n}\n\nexport function clearIdentity(): void {\n identityContext = {}\n}\n\nconst LEVEL_COLORS: Record<string, string> = {\n error: 'color: #ef4444; font-weight: bold',\n warn: 'color: #f59e0b; font-weight: bold',\n info: 'color: #06b6d4; font-weight: bold',\n debug: 'color: #6b7280; font-weight: bold',\n}\n\nexport function initLog(options: { enabled?: boolean, console?: boolean, pretty?: boolean, service?: string, transport?: TransportConfig } = {}): void {\n clientEnabled = typeof options.enabled === 'boolean' ? options.enabled : true\n clientConsole = typeof options.console === 'boolean' ? options.console : true\n clientPretty = typeof options.pretty === 'boolean' ? options.pretty : true\n clientService = options.service ?? 'client'\n transportEnabled = options.transport?.enabled ?? false\n transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n}\n\nasync function sendToServer(event: Record<string, unknown>): Promise<void> {\n if (!transportEnabled) return\n\n try {\n await fetch(transportEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(event),\n keepalive: true,\n credentials: 'same-origin',\n })\n } catch {\n // Silently fail - don't break the app\n }\n}\n\nfunction emitLog(level: LogLevel, event: Record<string, unknown>): void {\n if (!clientEnabled) return\n\n const formatted = {\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n ...event,\n }\n\n if (clientConsole) {\n const method = getConsoleMethod(level)\n if (clientPretty) {\n const { level: lvl, service, ...rest } = formatted\n console[method](`%c[${service}]%c ${lvl}`, LEVEL_COLORS[lvl] || '', 'color: inherit', rest)\n } else {\n console[method](JSON.stringify(formatted))\n }\n }\n\n sendToServer(formatted)\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!clientEnabled) return\n if (clientPretty) {\n if (clientConsole) {\n console[getConsoleMethod(level)](`%c[${tag}]%c ${message}`, LEVEL_COLORS[level] || '', 'color: inherit')\n }\n sendToServer({\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n tag,\n message,\n })\n } else {\n emitLog(level, { tag, message })\n }\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n if (!(import.meta.client ?? isClient)) {\n return\n }\n\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitLog(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\nconst _clientLog: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _clientLog as log }\n"],"mappings":";;;AAGA,MAAM,WAAW,OAAO,WAAW;AAEnC,IAAI,gBAAgB;AACpB,IAAI,gBAAgB;AACpB,IAAI,eAAe;AACnB,IAAI,gBAAgB;AACpB,IAAI,mBAAmB;AACvB,IAAI,oBAAoB;AACxB,IAAI,kBAA2C,EAAE;AAEjD,SAAgB,YAAY,UAAyC;AACnE,mBAAkB,EAAE,GAAG,UAAU;;AAGnC,SAAgB,gBAAsB;AACpC,mBAAkB,EAAE;;AAGtB,MAAM,eAAuC;CAC3C,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR;AAED,SAAgB,QAAQ,UAAqH,EAAE,EAAQ;AACrJ,iBAAgB,OAAO,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACzE,iBAAgB,OAAO,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACzE,gBAAe,OAAO,QAAQ,WAAW,YAAY,QAAQ,SAAS;AACtE,iBAAgB,QAAQ,WAAW;AACnC,oBAAmB,QAAQ,WAAW,WAAW;AACjD,qBAAoB,QAAQ,WAAW,YAAY;;AAGrD,eAAe,aAAa,OAA+C;AACzE,KAAI,CAAC,iBAAkB;AAEvB,KAAI;AACF,QAAM,MAAM,mBAAmB;GAC7B,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,MAAM;GAC3B,WAAW;GACX,aAAa;GACd,CAAC;SACI;;AAKV,SAAS,QAAQ,OAAiB,OAAsC;AACtE,KAAI,CAAC,cAAe;CAEpB,MAAM,YAAY;EAChB,4BAAW,IAAI,MAAM,EAAC,aAAa;EACnC;EACA,SAAS;EACT,GAAG;EACH,GAAG;EACJ;AAED,KAAI,eAAe;EACjB,MAAM,SAAS,iBAAiB,MAAM;AACtC,MAAI,cAAc;GAChB,MAAM,EAAE,OAAO,KAAK,SAAS,GAAG,SAAS;AACzC,WAAQ,QAAQ,MAAM,QAAQ,MAAM,OAAO,aAAa,QAAQ,IAAI,kBAAkB,KAAK;QAE3F,SAAQ,QAAQ,KAAK,UAAU,UAAU,CAAC;;AAI9C,cAAa,UAAU;;AAGzB,SAAS,cAAc,OAAiB,KAAa,SAAuB;AAC1E,KAAI,CAAC,cAAe;AACpB,KAAI,cAAc;AAChB,MAAI,cACF,SAAQ,iBAAiB,MAAM,EAAE,MAAM,IAAI,MAAM,WAAW,aAAa,UAAU,IAAI,iBAAiB;AAE1G,eAAa;GACX,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC;GACA,SAAS;GACT,GAAG;GACH;GACA;GACD,CAAC;OAEF,SAAQ,OAAO;EAAE;EAAK;EAAS,CAAC;;AAIpC,SAAS,gBAAgB,OAAiB;AACxC,QAAO,SAAS,UAAU,YAA8C,SAAwB;AAC9F,MAAI,EAAE,OAAO,KAAK,UAAU,UAC1B;AAGF,MAAI,OAAO,eAAe,YAAY,YAAY,OAChD,eAAc,OAAO,YAAY,QAAQ;WAChC,OAAO,eAAe,SAC/B,SAAQ,OAAO,WAAW;MAE1B,eAAc,OAAO,OAAO,OAAO,WAAW,CAAC;;;AAKrD,MAAM,aAAkB;CACtB,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAC/B,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAChC"}
@@ -6,6 +6,7 @@ var plugin_default = defineNuxtPlugin(() => {
6
6
  const evlogConfig = useRuntimeConfig().public?.evlog;
7
7
  initLog({
8
8
  enabled: evlogConfig?.enabled,
9
+ console: evlogConfig?.console,
9
10
  pretty: evlogConfig?.pretty ?? import.meta.dev,
10
11
  service: "client",
11
12
  transport: evlogConfig?.transport
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/runtime/client/plugin.ts"],"sourcesContent":["import type { TransportConfig } from '../../types'\nimport { initLog } from './log'\nimport { defineNuxtPlugin, useRuntimeConfig } from '#app'\n\ninterface EvlogPublicConfig {\n enabled?: boolean\n pretty?: boolean\n transport?: TransportConfig\n}\n\nexport default defineNuxtPlugin(() => {\n const config = useRuntimeConfig()\n const evlogConfig = config.public?.evlog as EvlogPublicConfig | undefined\n\n initLog({\n enabled: evlogConfig?.enabled,\n pretty: evlogConfig?.pretty ?? import.meta.dev,\n service: 'client',\n transport: evlogConfig?.transport,\n })\n})\n"],"mappings":";;;;AAUA,qBAAe,uBAAuB;CAEpC,MAAM,cADS,kBAAkB,CACN,QAAQ;AAEnC,SAAQ;EACN,SAAS,aAAa;EACtB,QAAQ,aAAa,UAAU,OAAO,KAAK;EAC3C,SAAS;EACT,WAAW,aAAa;EACzB,CAAC;EACF"}
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/runtime/client/plugin.ts"],"sourcesContent":["import type { TransportConfig } from '../../types'\nimport { initLog } from './log'\nimport { defineNuxtPlugin, useRuntimeConfig } from '#app'\n\ninterface EvlogPublicConfig {\n enabled?: boolean\n console?: boolean\n pretty?: boolean\n transport?: TransportConfig\n}\n\nexport default defineNuxtPlugin(() => {\n const config = useRuntimeConfig()\n const evlogConfig = config.public?.evlog as EvlogPublicConfig | undefined\n\n initLog({\n enabled: evlogConfig?.enabled,\n console: evlogConfig?.console,\n pretty: evlogConfig?.pretty ?? import.meta.dev,\n service: 'client',\n transport: evlogConfig?.transport,\n })\n})\n"],"mappings":";;;;AAWA,qBAAe,uBAAuB;CAEpC,MAAM,cADS,kBAAkB,CACN,QAAQ;AAEnC,SAAQ;EACN,SAAS,aAAa;EACtB,SAAS,aAAa;EACtB,QAAQ,aAAa,UAAU,OAAO,KAAK;EAC3C,SAAS;EACT,WAAW,aAAa;EACzB,CAAC;EACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evlog",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Wide event logging library with structured error handling. Inspired by LoggingSucks.",
5
5
  "author": "HugoRCD <contact@hrcd.fr>",
6
6
  "homepage": "https://evlog.dev",
@@ -155,7 +155,7 @@
155
155
  },
156
156
  "devDependencies": {
157
157
  "ufo": "^1.6.3",
158
- "@nuxt/devtools": "^3.2.1",
158
+ "@nuxt/devtools": "^3.2.2",
159
159
  "@nuxt/schema": "^4.3.1",
160
160
  "@nuxt/test-utils": "^4.0.0",
161
161
  "changelogen": "^0.6.2",