evlog 2.3.0 → 2.4.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 (37) hide show
  1. package/README.md +105 -25
  2. package/dist/elysia/index.d.mts +7 -24
  3. package/dist/elysia/index.d.mts.map +1 -1
  4. package/dist/elysia/index.mjs +14 -4
  5. package/dist/elysia/index.mjs.map +1 -1
  6. package/dist/express/index.d.mts +4 -39
  7. package/dist/express/index.d.mts.map +1 -1
  8. package/dist/express/index.mjs +2 -21
  9. package/dist/express/index.mjs.map +1 -1
  10. package/dist/fastify/index.d.mts +37 -0
  11. package/dist/fastify/index.d.mts.map +1 -0
  12. package/dist/fastify/index.mjs +73 -0
  13. package/dist/fastify/index.mjs.map +1 -0
  14. package/dist/headers-CXOd5EyZ.mjs.map +1 -1
  15. package/dist/hono/index.d.mts +3 -24
  16. package/dist/hono/index.d.mts.map +1 -1
  17. package/dist/hono/index.mjs.map +1 -1
  18. package/dist/middleware-BoVCgsfQ.d.mts +36 -0
  19. package/dist/middleware-BoVCgsfQ.d.mts.map +1 -0
  20. package/dist/nestjs/index.d.mts +83 -0
  21. package/dist/nestjs/index.d.mts.map +1 -0
  22. package/dist/nestjs/index.mjs +109 -0
  23. package/dist/nestjs/index.mjs.map +1 -0
  24. package/dist/next/index.d.mts +3 -34
  25. package/dist/next/index.d.mts.map +1 -1
  26. package/dist/nitro/module.d.mts +1 -1
  27. package/dist/nitro/v3/module.d.mts +1 -1
  28. package/dist/{nitro-Nxg6qcXd.d.mts → nitro-BRisWfGy.d.mts} +1 -1
  29. package/dist/{nitro-Nxg6qcXd.d.mts.map → nitro-BRisWfGy.d.mts.map} +1 -1
  30. package/dist/nuxt/module.mjs +1 -1
  31. package/dist/storage-Dd3PHiMh.mjs +29 -0
  32. package/dist/storage-Dd3PHiMh.mjs.map +1 -0
  33. package/dist/sveltekit/index.d.mts +128 -0
  34. package/dist/sveltekit/index.d.mts.map +1 -0
  35. package/dist/sveltekit/index.mjs +163 -0
  36. package/dist/sveltekit/index.mjs.map +1 -0
  37. package/package.json +39 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono'\nimport type { DrainContext, EnrichContext, RequestLogger, RouteConfig, TailSamplingContext } from '../types'\nimport { createMiddlewareLogger } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\n\nexport interface EvlogHonoOptions {\n /** Route patterns to include in logging (glob). If not set, all routes are logged */\n include?: string[]\n /** Route patterns to exclude from logging. Exclusions take precedence over inclusions */\n exclude?: string[]\n /** Route-specific service configuration */\n routes?: Record<string, RouteConfig>\n /**\n * Drain callback called with every emitted event.\n * Use with drain adapters (Axiom, OTLP, Sentry, etc.) or custom endpoints.\n */\n drain?: (ctx: DrainContext) => void | Promise<void>\n /**\n * Enrich callback called after emit, before drain.\n * Use to add derived context (geo, deployment info, user agent, etc.).\n */\n enrich?: (ctx: EnrichContext) => void | Promise<void>\n /**\n * Custom tail sampling callback.\n * Set `ctx.shouldKeep = true` to force-keep the log regardless of head sampling.\n */\n keep?: (ctx: TailSamplingContext) => void | Promise<void>\n}\n\n/**\n * Hono variables type for typed `c.get('log')` access.\n *\n * @example\n * ```ts\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog())\n * app.get('/api/users', (c) => {\n * const log = c.get('log')\n * log.set({ users: { count: 42 } })\n * return c.json({ users: [] })\n * })\n * ```\n */\nexport type EvlogVariables = { Variables: { log: RequestLogger } }\n\n/**\n * Create an evlog middleware for Hono.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono'\n * import { evlog, type EvlogVariables } from 'evlog/hono'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogHonoOptions = {}): MiddlewareHandler {\n return async (c, next) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: c.req.method,\n path: c.req.path,\n requestId: c.req.header('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(c.req.raw.headers),\n ...options,\n })\n\n if (skipped) {\n await next()\n return\n }\n\n c.set('log', logger)\n\n try {\n await next()\n await finish({ status: c.res.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA+DA,SAAgB,MAAM,UAA4B,EAAE,EAAqB;AACvE,QAAO,OAAO,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,EAAE,IAAI;GACd,MAAM,EAAE,IAAI;GACZ,WAAW,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,YAAY;GAC9D,SAAS,mBAAmB,EAAE,IAAI,IAAI,QAAQ;GAC9C,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM,MAAM;AACZ;;AAGF,IAAE,IAAI,OAAO,OAAO;AAEpB,MAAI;AACF,SAAM,MAAM;AACZ,SAAM,OAAO,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;WAC/B,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\n\nexport type EvlogHonoOptions = BaseEvlogOptions\n\n/**\n * Hono variables type for typed `c.get('log')` access.\n *\n * @example\n * ```ts\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog())\n * app.get('/api/users', (c) => {\n * const log = c.get('log')\n * log.set({ users: { count: 42 } })\n * return c.json({ users: [] })\n * })\n * ```\n */\nexport type EvlogVariables = { Variables: { log: RequestLogger } }\n\n/**\n * Create an evlog middleware for Hono.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono'\n * import { evlog, type EvlogVariables } from 'evlog/hono'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogHonoOptions = {}): MiddlewareHandler {\n return async (c, next) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: c.req.method,\n path: c.req.path,\n requestId: c.req.header('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(c.req.raw.headers),\n ...options,\n })\n\n if (skipped) {\n await next()\n return\n }\n\n c.set('log', logger)\n\n try {\n await next()\n await finish({ status: c.res.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,MAAM,UAA4B,EAAE,EAAqB;AACvE,QAAO,OAAO,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,EAAE,IAAI;GACd,MAAM,EAAE,IAAI;GACZ,WAAW,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,YAAY;GAC9D,SAAS,mBAAmB,EAAE,IAAI,IAAI,QAAQ;GAC9C,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM,MAAM;AACZ;;AAGF,IAAE,IAAI,OAAO,OAAO;AAEpB,MAAI;AACF,SAAM,MAAM;AACZ,SAAM,OAAO,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;WAC/B,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
@@ -0,0 +1,36 @@
1
+ import { DrainContext, EnrichContext, RouteConfig, TailSamplingContext } from "./types.mjs";
2
+
3
+ //#region src/shared/middleware.d.ts
4
+ /**
5
+ * Base options shared by all framework integrations.
6
+ *
7
+ * Every framework-specific options interface (e.g. `EvlogExpressOptions`)
8
+ * extends this type. If a framework needs extra fields it can add them
9
+ * on top; otherwise the base is used as-is.
10
+ */
11
+ interface BaseEvlogOptions {
12
+ /** Route patterns to include in logging (glob). If not set, all routes are logged */
13
+ include?: string[];
14
+ /** Route patterns to exclude from logging. Exclusions take precedence over inclusions */
15
+ exclude?: string[];
16
+ /** Route-specific service configuration */
17
+ routes?: Record<string, RouteConfig>;
18
+ /**
19
+ * Drain callback called with every emitted event.
20
+ * Use with drain adapters (Axiom, OTLP, Sentry, etc.) or custom endpoints.
21
+ */
22
+ drain?: (ctx: DrainContext) => void | Promise<void>;
23
+ /**
24
+ * Enrich callback called after emit, before drain.
25
+ * Use to add derived context (geo, deployment info, user agent, etc.).
26
+ */
27
+ enrich?: (ctx: EnrichContext) => void | Promise<void>;
28
+ /**
29
+ * Custom tail sampling callback.
30
+ * Set `ctx.shouldKeep = true` to force-keep the log regardless of head sampling.
31
+ */
32
+ keep?: (ctx: TailSamplingContext) => void | Promise<void>;
33
+ }
34
+ //#endregion
35
+ export { BaseEvlogOptions as t };
36
+ //# sourceMappingURL=middleware-BoVCgsfQ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware-BoVCgsfQ.d.mts","names":[],"sources":["../src/shared/middleware.ts"],"mappings":";;;;;AAYA;;;;;UAAiB,gBAAA;EAWuB;EATtC,OAAA;EAcwC;EAZxC,OAAA;EAiB4C;EAf5C,MAAA,GAAS,MAAA,SAAe,WAAA;EAe2B;;;;EAVnD,KAAA,IAAS,GAAA,EAAK,YAAA,YAAwB,OAAA;EALd;;;;EAUxB,MAAA,IAAU,GAAA,EAAK,aAAA,YAAyB,OAAA;EAAxC;;;;EAKA,IAAA,IAAQ,GAAA,EAAK,mBAAA,YAA+B,OAAA;AAAA"}
@@ -0,0 +1,83 @@
1
+ import { RequestLogger } from "../types.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-BoVCgsfQ.mjs";
3
+ import { DynamicModule, MiddlewareConsumer, NestModule } from "@nestjs/common";
4
+
5
+ //#region src/nestjs/index.d.ts
6
+ declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
7
+ type EvlogNestJSOptions = BaseEvlogOptions;
8
+ interface EvlogModuleAsyncOptions {
9
+ /** Modules to import (for dependency injection into the factory) */
10
+ imports?: any[];
11
+ /** Factory function that returns evlog options. Can be async. */
12
+ useFactory: (...args: any[]) => EvlogNestJSOptions | Promise<EvlogNestJSOptions>;
13
+ /** Injection tokens to resolve and pass to the factory */
14
+ inject?: any[];
15
+ }
16
+ declare module 'http' {
17
+ interface IncomingMessage {
18
+ log?: RequestLogger;
19
+ }
20
+ }
21
+ declare module 'express-serve-static-core' {
22
+ interface Request {
23
+ log?: RequestLogger;
24
+ }
25
+ }
26
+ /**
27
+ * NestJS module for evlog wide event logging.
28
+ *
29
+ * Registers a global middleware that creates a request-scoped logger
30
+ * for every incoming request. Use `useLogger()` to access it anywhere
31
+ * in the call stack, or `req.log` directly in controllers.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * import { Module } from '@nestjs/common'
36
+ * import { EvlogModule } from 'evlog/nestjs'
37
+ * import { createAxiomDrain } from 'evlog/axiom'
38
+ *
39
+ * @Module({
40
+ * imports: [
41
+ * EvlogModule.forRoot({
42
+ * drain: createAxiomDrain(),
43
+ * exclude: ['/health'],
44
+ * }),
45
+ * ],
46
+ * })
47
+ * export class AppModule {}
48
+ * ```
49
+ */
50
+ declare class EvlogModule implements NestModule {
51
+ private static options;
52
+ /**
53
+ * Register evlog with static configuration.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * EvlogModule.forRoot({
58
+ * drain: createAxiomDrain(),
59
+ * enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },
60
+ * })
61
+ * ```
62
+ */
63
+ static forRoot(options?: EvlogNestJSOptions): DynamicModule;
64
+ /**
65
+ * Register evlog with async configuration (e.g. from `ConfigService`).
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * EvlogModule.forRootAsync({
70
+ * imports: [ConfigModule],
71
+ * inject: [ConfigService],
72
+ * useFactory: (config: ConfigService) => ({
73
+ * drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),
74
+ * }),
75
+ * })
76
+ * ```
77
+ */
78
+ static forRootAsync(asyncOptions: EvlogModuleAsyncOptions): DynamicModule;
79
+ configure(consumer: MiddlewareConsumer): void;
80
+ }
81
+ //#endregion
82
+ export { EvlogModule, EvlogModuleAsyncOptions, EvlogNestJSOptions, useLogger };
83
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/nestjs/index.ts"],"mappings":";;;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,kBAAA,GAAqB,gBAAA;AAAA,UAIhB,uBAAA;EANhB;EAQC,OAAA;EAVwB;EAYxB,UAAA,MAAgB,IAAA,YAAgB,kBAAA,GAAqB,OAAA,CAAQ,kBAAA;EAZrC;EAcxB,MAAA;AAAA;AAAA;EAAA,UAIU,eAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAAA;EAAA,UAKE,OAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAjBV;;;;;;;;;;;;;;;;;AAOC;;;;;;;AAPD,cA0Ea,WAAA,YAAuB,UAAA;EAAA,eAEnB,OAAA;EAjEM;AAAA;;;;;;;;;;EAAA,OA8Ed,OAAA,CAAQ,OAAA,GAAS,kBAAA,GAA0B,aAAA;EAf3B;;;;;;;;;;;;;;EAAA,OAqChB,YAAA,CAAa,YAAA,EAAc,uBAAA,GAA0B,aAAA;EAkB5D,SAAA,CAAU,QAAA,EAAU,kBAAA;AAAA"}
@@ -0,0 +1,109 @@
1
+ import { n as extractSafeNodeHeaders, r as createMiddlewareLogger } from "../headers-CXOd5EyZ.mjs";
2
+ import { t as createLoggerStorage } from "../storage-Dd3PHiMh.mjs";
3
+
4
+ //#region src/nestjs/index.ts
5
+ const { storage, useLogger } = createLoggerStorage("middleware context. Make sure EvlogModule.forRoot() is imported in your AppModule.");
6
+ function createEvlogMiddleware(getOptions) {
7
+ return (req, res, next) => {
8
+ const options = getOptions();
9
+ const headers = extractSafeNodeHeaders(req.headers);
10
+ const url = new URL(req.url || "/", "http://localhost");
11
+ const { logger, finish, skipped } = createMiddlewareLogger({
12
+ method: req.method || "GET",
13
+ path: url.pathname,
14
+ requestId: headers["x-request-id"] || crypto.randomUUID(),
15
+ headers,
16
+ ...options
17
+ });
18
+ if (skipped) {
19
+ next();
20
+ return;
21
+ }
22
+ req.log = logger;
23
+ res.on("finish", () => {
24
+ finish({ status: res.statusCode }).catch(() => {});
25
+ });
26
+ storage.run(logger, () => next());
27
+ };
28
+ }
29
+ /**
30
+ * NestJS module for evlog wide event logging.
31
+ *
32
+ * Registers a global middleware that creates a request-scoped logger
33
+ * for every incoming request. Use `useLogger()` to access it anywhere
34
+ * in the call stack, or `req.log` directly in controllers.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import { Module } from '@nestjs/common'
39
+ * import { EvlogModule } from 'evlog/nestjs'
40
+ * import { createAxiomDrain } from 'evlog/axiom'
41
+ *
42
+ * @Module({
43
+ * imports: [
44
+ * EvlogModule.forRoot({
45
+ * drain: createAxiomDrain(),
46
+ * exclude: ['/health'],
47
+ * }),
48
+ * ],
49
+ * })
50
+ * export class AppModule {}
51
+ * ```
52
+ */
53
+ var EvlogModule = class EvlogModule {
54
+ static options = {};
55
+ /**
56
+ * Register evlog with static configuration.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * EvlogModule.forRoot({
61
+ * drain: createAxiomDrain(),
62
+ * enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },
63
+ * })
64
+ * ```
65
+ */
66
+ static forRoot(options = {}) {
67
+ EvlogModule.options = options;
68
+ return {
69
+ module: EvlogModule,
70
+ global: true
71
+ };
72
+ }
73
+ /**
74
+ * Register evlog with async configuration (e.g. from `ConfigService`).
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * EvlogModule.forRootAsync({
79
+ * imports: [ConfigModule],
80
+ * inject: [ConfigService],
81
+ * useFactory: (config: ConfigService) => ({
82
+ * drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),
83
+ * }),
84
+ * })
85
+ * ```
86
+ */
87
+ static forRootAsync(asyncOptions) {
88
+ return {
89
+ module: EvlogModule,
90
+ imports: asyncOptions.imports || [],
91
+ providers: [{
92
+ provide: "EVLOG_OPTIONS",
93
+ useFactory: async (...args) => {
94
+ EvlogModule.options = await asyncOptions.useFactory(...args);
95
+ return EvlogModule.options;
96
+ },
97
+ inject: asyncOptions.inject || []
98
+ }],
99
+ global: true
100
+ };
101
+ }
102
+ configure(consumer) {
103
+ consumer.apply(createEvlogMiddleware(() => EvlogModule.options)).forRoutes("*");
104
+ }
105
+ };
106
+
107
+ //#endregion
108
+ export { EvlogModule, useLogger };
109
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { DynamicModule, MiddlewareConsumer, NestModule } from '@nestjs/common'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure EvlogModule.forRoot() is imported in your AppModule.',\n)\n\nexport type EvlogNestJSOptions = BaseEvlogOptions\n\nexport { useLogger }\n\nexport interface EvlogModuleAsyncOptions {\n /** Modules to import (for dependency injection into the factory) */\n imports?: any[]\n /** Factory function that returns evlog options. Can be async. */\n useFactory: (...args: any[]) => EvlogNestJSOptions | Promise<EvlogNestJSOptions>\n /** Injection tokens to resolve and pass to the factory */\n inject?: any[]\n}\n\ndeclare module 'http' {\n interface IncomingMessage {\n log?: RequestLogger\n }\n}\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log?: RequestLogger\n }\n}\n\nfunction createEvlogMiddleware(getOptions: () => EvlogNestJSOptions) {\n return (req: IncomingMessage, res: ServerResponse, next: () => void) => {\n const options = getOptions()\n const headers = extractSafeNodeHeaders(req.headers)\n const url = new URL(req.url || '/', 'http://localhost')\n\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: req.method || 'GET',\n path: url.pathname,\n requestId: headers['x-request-id'] || crypto.randomUUID(),\n headers,\n ...options,\n })\n\n if (skipped) {\n next()\n return\n }\n\n req.log = logger\n\n res.on('finish', () => {\n finish({ status: res.statusCode }).catch(() => {})\n })\n\n storage.run(logger, () => next())\n }\n}\n\n/**\n * NestJS module for evlog wide event logging.\n *\n * Registers a global middleware that creates a request-scoped logger\n * for every incoming request. Use `useLogger()` to access it anywhere\n * in the call stack, or `req.log` directly in controllers.\n *\n * @example\n * ```ts\n * import { Module } from '@nestjs/common'\n * import { EvlogModule } from 'evlog/nestjs'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * @Module({\n * imports: [\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * exclude: ['/health'],\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\nexport class EvlogModule implements NestModule {\n\n private static options: EvlogNestJSOptions = {}\n\n /**\n * Register evlog with static configuration.\n *\n * @example\n * ```ts\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },\n * })\n * ```\n */\n static forRoot(options: EvlogNestJSOptions = {}): DynamicModule {\n EvlogModule.options = options\n return {\n module: EvlogModule,\n global: true,\n }\n }\n\n /**\n * Register evlog with async configuration (e.g. from `ConfigService`).\n *\n * @example\n * ```ts\n * EvlogModule.forRootAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),\n * }),\n * })\n * ```\n */\n static forRootAsync(asyncOptions: EvlogModuleAsyncOptions): DynamicModule {\n return {\n module: EvlogModule,\n imports: asyncOptions.imports || [],\n providers: [\n {\n provide: 'EVLOG_OPTIONS',\n useFactory: async (...args: any[]) => {\n EvlogModule.options = await asyncOptions.useFactory(...args)\n return EvlogModule.options\n },\n inject: asyncOptions.inject || [],\n },\n ],\n global: true,\n }\n }\n\n configure(consumer: MiddlewareConsumer): void {\n consumer\n .apply(createEvlogMiddleware(() => EvlogModule.options))\n .forRoutes('*')\n }\n\n}\n"],"mappings":";;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,qFACD;AA2BD,SAAS,sBAAsB,YAAsC;AACnE,SAAQ,KAAsB,KAAqB,SAAqB;EACtE,MAAM,UAAU,YAAY;EAC5B,MAAM,UAAU,uBAAuB,IAAI,QAAQ;EACnD,MAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,mBAAmB;EAEvD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,IAAI,UAAU;GACtB,MAAM,IAAI;GACV,WAAW,QAAQ,mBAAmB,OAAO,YAAY;GACzD;GACA,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,MAAI,MAAM;AAEV,MAAI,GAAG,gBAAgB;AACrB,UAAO,EAAE,QAAQ,IAAI,YAAY,CAAC,CAAC,YAAY,GAAG;IAClD;AAEF,UAAQ,IAAI,cAAc,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BrC,IAAa,cAAb,MAAa,YAAkC;CAE7C,OAAe,UAA8B,EAAE;;;;;;;;;;;;CAa/C,OAAO,QAAQ,UAA8B,EAAE,EAAiB;AAC9D,cAAY,UAAU;AACtB,SAAO;GACL,QAAQ;GACR,QAAQ;GACT;;;;;;;;;;;;;;;;CAiBH,OAAO,aAAa,cAAsD;AACxE,SAAO;GACL,QAAQ;GACR,SAAS,aAAa,WAAW,EAAE;GACnC,WAAW,CACT;IACE,SAAS;IACT,YAAY,OAAO,GAAG,SAAgB;AACpC,iBAAY,UAAU,MAAM,aAAa,WAAW,GAAG,KAAK;AAC5D,YAAO,YAAY;;IAErB,QAAQ,aAAa,UAAU,EAAE;IAClC,CACF;GACD,QAAQ;GACT;;CAGH,UAAU,UAAoC;AAC5C,WACG,MAAM,4BAA4B,YAAY,QAAQ,CAAC,CACvD,UAAU,IAAI"}
@@ -1,10 +1,11 @@
1
- import { DrainContext, EnrichContext, EnvironmentContext, Log, RequestLogger, RouteConfig, SamplingConfig, TailSamplingContext } from "../types.mjs";
1
+ import { EnvironmentContext, Log, RequestLogger, SamplingConfig } from "../types.mjs";
2
2
  import { createError } from "../error.mjs";
3
3
  import { log as _log } from "../logger.mjs";
4
+ import { t as BaseEvlogOptions } from "../middleware-BoVCgsfQ.mjs";
4
5
  import { AsyncLocalStorage } from "node:async_hooks";
5
6
 
6
7
  //#region src/next/types.d.ts
7
- interface NextEvlogOptions {
8
+ interface NextEvlogOptions extends BaseEvlogOptions {
8
9
  /**
9
10
  * Service name for all logged events.
10
11
  * @default auto-detected from SERVICE_NAME env or 'app'
@@ -28,38 +29,6 @@ interface NextEvlogOptions {
28
29
  * Sampling configuration for filtering logs.
29
30
  */
30
31
  sampling?: SamplingConfig;
31
- /**
32
- * Route patterns to include in logging.
33
- * Supports glob patterns like '/api/**'.
34
- * If not set, all routes are logged.
35
- */
36
- include?: string[];
37
- /**
38
- * Route patterns to exclude from logging.
39
- * Supports glob patterns like '/_next/**'.
40
- * Exclusions take precedence over inclusions.
41
- */
42
- exclude?: string[];
43
- /**
44
- * Route-specific service configuration.
45
- */
46
- routes?: Record<string, RouteConfig>;
47
- /**
48
- * Drain callback called with every emitted event (fire-and-forget).
49
- * Compatible with drain adapters and pipeline-wrapped drains.
50
- */
51
- drain?: (ctx: DrainContext) => void | Promise<void>;
52
- /**
53
- * Enrich callback called after emit, before drain.
54
- * Use this to add derived context (e.g. geo, deployment info).
55
- */
56
- enrich?: (ctx: EnrichContext) => void | Promise<void>;
57
- /**
58
- * Custom tail sampling callback called before emit.
59
- * Set `ctx.shouldKeep = true` to force-keep the log regardless of head sampling.
60
- * Equivalent to Nuxt's `evlog:emit:keep` hook.
61
- */
62
- keep?: (ctx: TailSamplingContext) => void | Promise<void>;
63
32
  /**
64
33
  * When pretty is disabled, emit JSON strings (default) or raw objects.
65
34
  * @default true
@@ -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":";;;;;;;UAGiB,gBAAA,SAAyB,gBAAA;;;;;EAKxC,OAAA;EALe;;;EAUf,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAAR;;;;EAMN,MAAA;EAhBwC;;;;EAsBxC,OAAA;EANA;;;EAWA,QAAA,GAAW,cAAA;EAMX;;;AAGF;EAHE,SAAA;AAAA;AAAA,UAGe,qBAAA;EAWR;;;;EANP,OAAA;ECxBuB;;;;ED8BvB,OAAA;AAAA;;;;;;;;AA/CF;;;;;;;;;;iBCiBgB,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;;;AF3BpC;;;;;;;;;;;;;;;;;;;;;AAoCA;;;;;;;;AApCA,iBGuCgB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAWg8D,IAAA,EAAA,KAAA,KAAA,OAAA,SAAkC,IAAA,EAAA,KAAA,KAAA,OAAA,CAAA,OAAA,CAAA,OAAA"}
@@ -1,5 +1,5 @@
1
1
  import { useLogger } from "../runtime/server/useLogger.mjs";
2
- import { t as NitroModuleOptions } from "../nitro-Nxg6qcXd.mjs";
2
+ import { t as NitroModuleOptions } from "../nitro-BRisWfGy.mjs";
3
3
  import { Nitro } from "nitropack";
4
4
 
5
5
  //#region src/nitro/module.d.ts
@@ -1,4 +1,4 @@
1
- import { t as NitroModuleOptions } from "../../nitro-Nxg6qcXd.mjs";
1
+ import { t as NitroModuleOptions } from "../../nitro-BRisWfGy.mjs";
2
2
  import { Nitro } from "nitro/types";
3
3
 
4
4
  //#region src/nitro-v3/module.d.ts
@@ -39,4 +39,4 @@ interface NitroModuleOptions {
39
39
  }
40
40
  //#endregion
41
41
  export { NitroModuleOptions as t };
42
- //# sourceMappingURL=nitro-Nxg6qcXd.d.mts.map
42
+ //# sourceMappingURL=nitro-BRisWfGy.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nitro-Nxg6qcXd.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-BRisWfGy.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"}
@@ -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.3.0";
5
+ var version = "2.4.0";
6
6
 
7
7
  //#endregion
8
8
  //#region src/nuxt/module.ts
@@ -0,0 +1,29 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+
3
+ //#region src/shared/storage.ts
4
+ /**
5
+ * Create a request-scoped `AsyncLocalStorage` and a matching `useLogger` accessor.
6
+ *
7
+ * Every framework that needs `useLogger()` (Express, Fastify, NestJS, SvelteKit)
8
+ * calls this once at module level to get its own isolated storage + accessor pair.
9
+ *
10
+ * @param contextHint - Human-readable hint appended to the error message when
11
+ * `useLogger()` is called outside of a request (e.g.
12
+ * `"middleware context. Make sure app.use(evlog()) is registered before your routes."`).
13
+ */
14
+ function createLoggerStorage(contextHint) {
15
+ const storage = new AsyncLocalStorage();
16
+ function useLogger() {
17
+ const logger = storage.getStore();
18
+ if (!logger) throw new Error(`[evlog] useLogger() was called outside of an evlog ${contextHint}`);
19
+ return logger;
20
+ }
21
+ return {
22
+ storage,
23
+ useLogger
24
+ };
25
+ }
26
+
27
+ //#endregion
28
+ export { createLoggerStorage as t };
29
+ //# sourceMappingURL=storage-Dd3PHiMh.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-Dd3PHiMh.mjs","names":[],"sources":["../src/shared/storage.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RequestLogger } from '../types'\n\n/**\n * Create a request-scoped `AsyncLocalStorage` and a matching `useLogger` accessor.\n *\n * Every framework that needs `useLogger()` (Express, Fastify, NestJS, SvelteKit)\n * calls this once at module level to get its own isolated storage + accessor pair.\n *\n * @param contextHint - Human-readable hint appended to the error message when\n * `useLogger()` is called outside of a request (e.g.\n * `\"middleware context. Make sure app.use(evlog()) is registered before your routes.\"`).\n */\nexport function createLoggerStorage(contextHint: string) {\n const storage = new AsyncLocalStorage<RequestLogger>()\n\n function useLogger<T extends object = Record<string, unknown>>(): RequestLogger<T> {\n const logger = storage.getStore()\n if (!logger) {\n throw new Error(\n `[evlog] useLogger() was called outside of an evlog ${contextHint}`,\n )\n }\n return logger as RequestLogger<T>\n }\n\n return { storage, useLogger }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,oBAAoB,aAAqB;CACvD,MAAM,UAAU,IAAI,mBAAkC;CAEtD,SAAS,YAA0E;EACjF,MAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,CAAC,OACH,OAAM,IAAI,MACR,sDAAsD,cACvD;AAEH,SAAO;;AAGT,QAAO;EAAE;EAAS;EAAW"}
@@ -0,0 +1,128 @@
1
+ import { RequestLogger } from "../types.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-BoVCgsfQ.mjs";
3
+
4
+ //#region src/sveltekit/index.d.ts
5
+ declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
6
+ type EvlogSvelteKitOptions = BaseEvlogOptions;
7
+ /**
8
+ * SvelteKit `Handle` function signature — avoids a hard dependency on `@sveltejs/kit`.
9
+ */
10
+ type SvelteKitHandle = (input: {
11
+ event: {
12
+ request: Request;
13
+ url: URL;
14
+ locals: Record<string, any>;
15
+ };
16
+ resolve: (event: any) => Promise<Response>;
17
+ }) => Promise<Response>;
18
+ /**
19
+ * SvelteKit `HandleServerError` signature — avoids a hard dependency on `@sveltejs/kit`.
20
+ */
21
+ type SvelteKitHandleServerError = (input: {
22
+ error: unknown;
23
+ event: {
24
+ request: Request;
25
+ url: URL;
26
+ locals: Record<string, any>;
27
+ };
28
+ status: number;
29
+ message: string;
30
+ }) => MaybePromise<void | AppError>;
31
+ type MaybePromise<T> = T | Promise<T>;
32
+ /** Minimal SvelteKit `App.Error` shape */
33
+ interface AppError {
34
+ message: string;
35
+ [key: string]: unknown;
36
+ }
37
+ /**
38
+ * Create an evlog handle hook for SvelteKit.
39
+ *
40
+ * Add it to your `src/hooks.server.ts` using SvelteKit's `sequence` helper
41
+ * or as the sole handle export.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * // src/hooks.server.ts
46
+ * import { initLogger } from 'evlog'
47
+ * import { evlog } from 'evlog/sveltekit'
48
+ * import { createAxiomDrain } from 'evlog/axiom'
49
+ *
50
+ * initLogger({ env: { service: 'my-sveltekit-app' } })
51
+ *
52
+ * export const handle = evlog({
53
+ * drain: createAxiomDrain(),
54
+ * enrich: (ctx) => {
55
+ * ctx.event.region = process.env.FLY_REGION
56
+ * },
57
+ * })
58
+ * ```
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * // Compose with other hooks using sequence
63
+ * import { sequence } from '@sveltejs/kit/hooks'
64
+ * import { evlog } from 'evlog/sveltekit'
65
+ *
66
+ * export const handle = sequence(evlog(), yourOtherHook)
67
+ * ```
68
+ */
69
+ declare function evlog(options?: EvlogSvelteKitOptions): SvelteKitHandle;
70
+ /**
71
+ * Create an evlog error handler for SvelteKit.
72
+ *
73
+ * Logs unhandled errors via `event.locals.log` (if available) and returns
74
+ * structured error responses for `EvlogError` instances. For non-evlog errors,
75
+ * returns a generic error response with sanitized messages in production.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * // src/hooks.server.ts
80
+ * import { evlog, evlogHandleError } from 'evlog/sveltekit'
81
+ *
82
+ * export const handle = evlog()
83
+ * export const handleError = evlogHandleError()
84
+ * ```
85
+ */
86
+ declare function evlogHandleError(): SvelteKitHandleServerError;
87
+ /**
88
+ * Create both `handle` and `handleError` hooks in a single call.
89
+ *
90
+ * This is the recommended setup for SvelteKit — it returns both hooks
91
+ * pre-configured and ready to export from `hooks.server.ts`.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * // src/hooks.server.ts
96
+ * import { initLogger } from 'evlog'
97
+ * import { createEvlogHooks } from 'evlog/sveltekit'
98
+ * import { createAxiomDrain } from 'evlog/axiom'
99
+ *
100
+ * initLogger({ env: { service: 'my-app' } })
101
+ *
102
+ * export const { handle, handleError } = createEvlogHooks({
103
+ * drain: createAxiomDrain(),
104
+ * enrich: (ctx) => {
105
+ * ctx.event.region = process.env.FLY_REGION
106
+ * },
107
+ * })
108
+ * ```
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * // Compose with other hooks using sequence
113
+ * import { sequence } from '@sveltejs/kit/hooks'
114
+ * import { createEvlogHooks } from 'evlog/sveltekit'
115
+ *
116
+ * const evlogHooks = createEvlogHooks()
117
+ *
118
+ * export const handle = sequence(evlogHooks.handle, yourOtherHook)
119
+ * export const handleError = evlogHooks.handleError
120
+ * ```
121
+ */
122
+ declare function createEvlogHooks(options?: EvlogSvelteKitOptions): {
123
+ handle: SvelteKitHandle;
124
+ handleError: SvelteKitHandleServerError;
125
+ };
126
+ //#endregion
127
+ export { EvlogSvelteKitOptions, createEvlogHooks, evlog, evlogHandleError, useLogger };
128
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/sveltekit/index.ts"],"mappings":";;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,qBAAA,GAAwB,gBAAA;;;;KAO/B,eAAA,IAAmB,KAAA;EACtB,KAAA;IAAS,OAAA,EAAS,OAAA;IAAS,GAAA,EAAK,GAAA;IAAK,MAAA,EAAQ,MAAA;EAAA;EAC7C,OAAA,GAAU,KAAA,UAAe,OAAA,CAAQ,QAAA;AAAA,MAC7B,OAAA,CAAQ,QAAA;;;AAVd;KAeK,0BAAA,IAA8B,KAAA;EACjC,KAAA;EACA,KAAA;IAAS,OAAA,EAAS,OAAA;IAAS,GAAA,EAAK,GAAA;IAAK,MAAA,EAAQ,MAAA;EAAA;EAC7C,MAAA;EACA,OAAA;AAAA,MACI,YAAA,QAAoB,QAAA;AAAA,KAErB,YAAA,MAAkB,CAAA,GAAI,OAAA,CAAQ,CAAA;;UAGzB,QAAA;EACR,OAAA;EAAA,CACC,GAAA;AAAA;;;;;;;;;;;;;;;;;AAjBmB;;;;;;;;;;;;;;;;iBAoDN,KAAA,CAAM,OAAA,GAAS,qBAAA,GAA6B,eAAA;;;;;;;;;AA1C1B;;;;;;;;iBAkHlB,gBAAA,CAAA,GAAoB,0BAAA;;;;;;AAhHA;;;;;AAwCpC;;;;;;;;;AAwEA;;;;;AA6DA;;;;;;;;;;;iBAAgB,gBAAA,CAAiB,OAAA,GAAS,qBAAA"}