evlog 2.13.0 → 2.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +118 -15
  2. package/dist/{_http-CHSsrWDJ.mjs → _http-BY1e9pwC.mjs} +9 -2
  3. package/dist/_http-BY1e9pwC.mjs.map +1 -0
  4. package/dist/adapters/axiom.d.mts +1 -1
  5. package/dist/adapters/axiom.mjs +1 -1
  6. package/dist/adapters/axiom.mjs.map +1 -1
  7. package/dist/adapters/better-stack.d.mts +1 -1
  8. package/dist/adapters/better-stack.mjs +1 -1
  9. package/dist/adapters/better-stack.mjs.map +1 -1
  10. package/dist/adapters/datadog.d.mts +1 -1
  11. package/dist/adapters/datadog.mjs +1 -1
  12. package/dist/adapters/datadog.mjs.map +1 -1
  13. package/dist/adapters/fs.d.mts +1 -1
  14. package/dist/adapters/fs.mjs.map +1 -1
  15. package/dist/adapters/hyperdx.d.mts +1 -1
  16. package/dist/adapters/hyperdx.mjs +1 -1
  17. package/dist/adapters/otlp.d.mts +1 -1
  18. package/dist/adapters/otlp.mjs +1 -1
  19. package/dist/adapters/otlp.mjs.map +1 -1
  20. package/dist/adapters/posthog.d.mts +1 -1
  21. package/dist/adapters/posthog.mjs +1 -1
  22. package/dist/adapters/posthog.mjs.map +1 -1
  23. package/dist/adapters/sentry.d.mts +1 -1
  24. package/dist/adapters/sentry.mjs +1 -1
  25. package/dist/adapters/sentry.mjs.map +1 -1
  26. package/dist/ai/index.d.mts +106 -5
  27. package/dist/ai/index.d.mts.map +1 -1
  28. package/dist/ai/index.mjs +28 -5
  29. package/dist/ai/index.mjs.map +1 -1
  30. package/dist/{types-DbzDln7O.d.mts → audit-CTIviX3P.d.mts} +509 -3
  31. package/dist/audit-CTIviX3P.d.mts.map +1 -0
  32. package/dist/{logger-DnobymUQ.mjs → audit-DQoBo7Dl.mjs} +758 -16
  33. package/dist/audit-DQoBo7Dl.mjs.map +1 -0
  34. package/dist/better-auth/index.d.mts +1 -1
  35. package/dist/better-auth/index.mjs.map +1 -1
  36. package/dist/browser.d.mts +1 -1
  37. package/dist/elysia/index.d.mts +2 -2
  38. package/dist/elysia/index.mjs +2 -2
  39. package/dist/enrichers.d.mts +1 -1
  40. package/dist/enrichers.mjs.map +1 -1
  41. package/dist/{error-B9CiGK_i.d.mts → error-C7gSQVqk.d.mts} +2 -2
  42. package/dist/{error-B9CiGK_i.d.mts.map → error-C7gSQVqk.d.mts.map} +1 -1
  43. package/dist/error.d.mts +1 -1
  44. package/dist/{errors-Dr0r4OpR.d.mts → errors-4MPmTzjY.d.mts} +2 -2
  45. package/dist/{errors-Dr0r4OpR.d.mts.map → errors-4MPmTzjY.d.mts.map} +1 -1
  46. package/dist/express/index.d.mts +2 -2
  47. package/dist/express/index.mjs +2 -2
  48. package/dist/fastify/index.d.mts +2 -2
  49. package/dist/fastify/index.mjs +2 -2
  50. package/dist/{fork-Y4z8iHti.mjs → fork-D1j1Fuzy.mjs} +3 -3
  51. package/dist/{fork-Y4z8iHti.mjs.map → fork-D1j1Fuzy.mjs.map} +1 -1
  52. package/dist/hono/index.d.mts +2 -2
  53. package/dist/hono/index.mjs +1 -1
  54. package/dist/http.d.mts +1 -1
  55. package/dist/http.d.mts.map +1 -1
  56. package/dist/http.mjs +3 -2
  57. package/dist/http.mjs.map +1 -1
  58. package/dist/index.d.mts +7 -7
  59. package/dist/index.mjs +2 -2
  60. package/dist/{logger-Dp6nYWjH.d.mts → logger-DttRJRGa.d.mts} +23 -4
  61. package/dist/logger-DttRJRGa.d.mts.map +1 -0
  62. package/dist/logger.d.mts +1 -1
  63. package/dist/logger.mjs +1 -1
  64. package/dist/{middleware-FgC1OdOD.d.mts → middleware-CTnDsST-.d.mts} +2 -2
  65. package/dist/{middleware-FgC1OdOD.d.mts.map → middleware-CTnDsST-.d.mts.map} +1 -1
  66. package/dist/{middleware-BtBuosFV.mjs → middleware-oAccqyPp.mjs} +2 -2
  67. package/dist/{middleware-BtBuosFV.mjs.map → middleware-oAccqyPp.mjs.map} +1 -1
  68. package/dist/nestjs/index.d.mts +2 -2
  69. package/dist/nestjs/index.mjs +2 -2
  70. package/dist/next/client.d.mts +1 -1
  71. package/dist/next/index.d.mts +4 -4
  72. package/dist/next/index.mjs +2 -2
  73. package/dist/next/index.mjs.map +1 -1
  74. package/dist/next/instrumentation.d.mts +1 -1
  75. package/dist/next/instrumentation.mjs +1 -1
  76. package/dist/next/instrumentation.mjs.map +1 -1
  77. package/dist/nitro/errorHandler.mjs.map +1 -1
  78. package/dist/nitro/module.d.mts +2 -2
  79. package/dist/nitro/plugin.mjs +1 -1
  80. package/dist/nitro/plugin.mjs.map +1 -1
  81. package/dist/nitro/v3/index.d.mts +2 -2
  82. package/dist/nitro/v3/middleware.mjs.map +1 -1
  83. package/dist/nitro/v3/module.d.mts +1 -1
  84. package/dist/nitro/v3/plugin.mjs +1 -1
  85. package/dist/nitro/v3/plugin.mjs.map +1 -1
  86. package/dist/nitro/v3/useLogger.d.mts +1 -1
  87. package/dist/nitro/v3/useLogger.mjs.map +1 -1
  88. package/dist/{nitro-CDHLfRdw.d.mts → nitro-CPPRCPbG.d.mts} +2 -2
  89. package/dist/{nitro-CDHLfRdw.d.mts.map → nitro-CPPRCPbG.d.mts.map} +1 -1
  90. package/dist/nuxt/module.d.mts +1 -1
  91. package/dist/nuxt/module.mjs +1 -1
  92. package/dist/{parseError-DM-lyezZ.d.mts → parseError-o1GpZEOR.d.mts} +2 -2
  93. package/dist/parseError-o1GpZEOR.d.mts.map +1 -0
  94. package/dist/pipeline.mjs.map +1 -1
  95. package/dist/react-router/index.d.mts +2 -2
  96. package/dist/react-router/index.mjs +2 -2
  97. package/dist/runtime/client/log.d.mts +1 -1
  98. package/dist/runtime/client/log.mjs +2 -2
  99. package/dist/runtime/client/log.mjs.map +1 -1
  100. package/dist/runtime/client/plugin.mjs.map +1 -1
  101. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +1 -1
  102. package/dist/runtime/server/routes/_evlog/ingest.post.mjs.map +1 -1
  103. package/dist/runtime/server/useLogger.d.mts +1 -1
  104. package/dist/runtime/server/useLogger.mjs.map +1 -1
  105. package/dist/runtime/utils/parseError.d.mts +2 -2
  106. package/dist/source-location-DRvDDqfq.mjs.map +1 -1
  107. package/dist/sveltekit/index.d.mts +2 -2
  108. package/dist/sveltekit/index.mjs +2 -2
  109. package/dist/sveltekit/index.mjs.map +1 -1
  110. package/dist/toolkit.d.mts +3 -3
  111. package/dist/toolkit.mjs +2 -2
  112. package/dist/types.d.mts +2 -2
  113. package/dist/{useLogger-N5A-d5l9.d.mts → useLogger-CyPP1sVB.d.mts} +2 -2
  114. package/dist/{useLogger-N5A-d5l9.d.mts.map → useLogger-CyPP1sVB.d.mts.map} +1 -1
  115. package/dist/{utils-DnX6VMNi.d.mts → utils-Dmin7wVL.d.mts} +4 -3
  116. package/dist/utils-Dmin7wVL.d.mts.map +1 -0
  117. package/dist/utils.d.mts +2 -2
  118. package/dist/utils.mjs +7 -1
  119. package/dist/utils.mjs.map +1 -1
  120. package/dist/vite/index.d.mts +1 -1
  121. package/dist/vite/index.mjs.map +1 -1
  122. package/dist/workers.d.mts +48 -4
  123. package/dist/workers.d.mts.map +1 -1
  124. package/dist/workers.mjs +32 -5
  125. package/dist/workers.mjs.map +1 -1
  126. package/package.json +17 -21
  127. package/dist/_http-CHSsrWDJ.mjs.map +0 -1
  128. package/dist/logger-DnobymUQ.mjs.map +0 -1
  129. package/dist/logger-Dp6nYWjH.d.mts.map +0 -1
  130. package/dist/parseError-DM-lyezZ.d.mts.map +0 -1
  131. package/dist/types-DbzDln7O.d.mts.map +0 -1
  132. package/dist/utils-DnX6VMNi.d.mts.map +0 -1
@@ -363,7 +363,97 @@ interface LoggerConfig {
363
363
  _suppressDrainWarning?: boolean;
364
364
  }
365
365
  /**
366
- * Base structure for all wide events
366
+ * Audit actor who initiated the action.
367
+ *
368
+ * `type` covers the most common actor families. `id` is required and should be
369
+ * a stable identifier (user id, service name, API key id, agent id). `model`,
370
+ * `tools`, `reason`, and `promptId` are filled when `type === 'agent'` and
371
+ * mirror the AI SDK fields already used by `evlog/ai`.
372
+ */
373
+ interface AuditActor {
374
+ type: 'user' | 'system' | 'api' | 'agent';
375
+ id: string;
376
+ displayName?: string;
377
+ email?: string;
378
+ model?: string;
379
+ tools?: string[];
380
+ reason?: string;
381
+ promptId?: string;
382
+ }
383
+ /**
384
+ * Audit target — the resource the action was performed on.
385
+ *
386
+ * `type` is a free-form string (e.g. `'invoice'`, `'user'`, `'subscription'`)
387
+ * narrowed by {@link defineAuditAction}. Additional fields are allowed for
388
+ * resource-specific metadata (e.g. `tenantId`, `path`, `previousOwnerId`).
389
+ */
390
+ interface AuditTarget {
391
+ type: string;
392
+ id: string;
393
+ [key: string]: unknown;
394
+ }
395
+ /**
396
+ * Reserved audit fields on the wide event.
397
+ *
398
+ * Set via `log.audit({ ... })`, `log.set({ audit: { ... } })`, or the
399
+ * standalone `audit({ ... })` helper. Downstream filters on `audit IS NOT NULL`.
400
+ *
401
+ * - `outcome` — `'success' | 'failure' | 'denied'`. `'denied'` records an
402
+ * AuthZ-denied action (often forgotten but exactly what auditors want).
403
+ * - `changes.before/after` — the diff for mutating actions. Use
404
+ * {@link auditDiff} to produce a redact-aware compact JSON Patch.
405
+ * - `causationId` / `correlationId` — chain related actions (admin action →
406
+ * system reactions). Set by callers, propagated by `auditEnricher` when
407
+ * available on the request.
408
+ * - `signature` / `prevHash` — populated by the {@link signed} drain wrapper.
409
+ * Never set by application code.
410
+ * - `idempotencyKey` — derived deterministically by `log.audit()` so retries
411
+ * across drains are safe.
412
+ * - `context` — request/runtime context auto-populated by {@link auditEnricher}
413
+ * (`requestId`, `traceId`, `ip`, `userAgent`, `tenantId`).
414
+ */
415
+ interface AuditFields {
416
+ /** Action name. Convention: `'<resource>.<verb>'`, e.g. `'invoice.refund'`. */
417
+ action: string;
418
+ actor: AuditActor;
419
+ target?: AuditTarget;
420
+ outcome: 'success' | 'failure' | 'denied';
421
+ /** Human-readable explanation, especially required for `outcome: 'denied'`. */
422
+ reason?: string;
423
+ /** Before/after snapshots for mutating actions. */
424
+ changes?: {
425
+ before?: unknown;
426
+ after?: unknown;
427
+ };
428
+ /** ID of the action that caused this one. */
429
+ causationId?: string;
430
+ /** ID shared by every action in the same logical operation. */
431
+ correlationId?: string;
432
+ /** Schema version of the audit envelope. Defaults to `1` when omitted by the caller. */
433
+ version?: number;
434
+ /** Set by `log.audit()` as a stable hash for safe retries across drains. */
435
+ idempotencyKey?: string;
436
+ /** Request/runtime context — populated by `auditEnricher`. */
437
+ context?: {
438
+ requestId?: string;
439
+ traceId?: string;
440
+ ip?: string;
441
+ userAgent?: string;
442
+ tenantId?: string;
443
+ [key: string]: unknown;
444
+ };
445
+ /** HMAC signature of the event when wrapped with `signed({ strategy: 'hmac' })`. */
446
+ signature?: string;
447
+ /** Previous event hash when wrapped with `signed({ strategy: 'hash-chain' })`. */
448
+ prevHash?: string;
449
+ /** Hash of the current event when wrapped with `signed({ strategy: 'hash-chain' })`. */
450
+ hash?: string;
451
+ }
452
+ /**
453
+ * Base structure for all wide events.
454
+ *
455
+ * Augment via `declare module 'evlog'` to add app-specific top-level fields.
456
+ * `audit` is reserved for {@link AuditFields}.
367
457
  */
368
458
  interface BaseWideEvent {
369
459
  timestamp: string;
@@ -373,6 +463,7 @@ interface BaseWideEvent {
373
463
  version?: string;
374
464
  commitHash?: string;
375
465
  region?: string;
466
+ audit?: AuditFields;
376
467
  }
377
468
  /**
378
469
  * Wide event with arbitrary additional fields
@@ -508,6 +599,34 @@ interface RequestLogger<T extends object = Record<string, unknown>> {
508
599
  * ```
509
600
  */
510
601
  fork?: (label: string, fn: () => void | Promise<void>) => void;
602
+ /**
603
+ * Record an audit event on this wide event. Strictly equivalent to
604
+ * `log.set({ audit: { ... } })` plus tail-sample force-keep.
605
+ *
606
+ * Use `log.audit.deny(reason, fields)` for AuthZ-denied actions — most teams
607
+ * forget to log denials but they are exactly what auditors and security teams
608
+ * ask for.
609
+ *
610
+ * Available on every logger returned by `createLogger()` / `createRequestLogger()`
611
+ * and on framework loggers exposed via `useLogger()` / `c.get('log')` etc.
612
+ *
613
+ * @example
614
+ * ```ts
615
+ * log.audit({
616
+ * action: 'invoice.refund',
617
+ * actor: { type: 'user', id: user.id, email: user.email },
618
+ * target: { type: 'invoice', id: 'inv_889' },
619
+ * outcome: 'success',
620
+ * reason: 'Customer requested refund',
621
+ * })
622
+ * ```
623
+ */
624
+ audit?: AuditLoggerMethod;
625
+ }
626
+ /** @internal Forward-declaration to avoid a circular import with `audit.ts`. */
627
+ interface AuditLoggerMethod {
628
+ (input: AuditInput): void;
629
+ deny: (reason: string, input: Omit<AuditInput, 'outcome' | 'reason'>) => void;
511
630
  }
512
631
  /**
513
632
  * Log level type
@@ -581,6 +700,16 @@ interface RequestLoggerOptions {
581
700
  method?: string;
582
701
  path?: string;
583
702
  requestId?: string;
703
+ /**
704
+ * Registers async drain work with the host runtime so it can finish after the
705
+ * HTTP response is returned. Required on **Cloudflare Workers** (and similar
706
+ * edge runtimes): without this, `initLogger({ drain })` + `log.emit()` may
707
+ * never complete outbound HTTP to observability backends.
708
+ *
709
+ * Pass the same function you would pass to `ExecutionContext#waitUntil`, e.g.
710
+ * `context.waitUntil.bind(context)` from a Workers `fetch` handler.
711
+ */
712
+ waitUntil?: (promise: Promise<unknown>) => void;
584
713
  }
585
714
  /**
586
715
  * H3 event context with evlog logger attached
@@ -630,5 +759,382 @@ interface ParsedError {
630
759
  raw: unknown;
631
760
  }
632
761
  //#endregion
633
- export { TailSamplingCondition as C, WideEvent as E, ServerEvent as S, TransportConfig as T, RequestLogger as _, EnvironmentContext as a, SamplingConfig as b, H3EventContext as c, Log as d, LogLevel as f, RequestLogEntry as g, RedactConfig as h, EnrichContext as i, IngestPayload as l, ParsedError as m, DeepPartial as n, ErrorOptions as o, LoggerConfig as p, DrainContext as r, FieldContext as s, BaseWideEvent as t, InternalFields as u, RequestLoggerOptions as v, TailSamplingContext as w, SamplingRates as x, RouteConfig as y };
634
- //# sourceMappingURL=types-DbzDln7O.d.mts.map
762
+ //#region src/audit.d.ts
763
+ /**
764
+ * Current version of the audit envelope. Bumped when `AuditFields` evolves
765
+ * in a backward-incompatible way so downstream pipelines can branch on it.
766
+ */
767
+ declare const AUDIT_SCHEMA_VERSION = 1;
768
+ /**
769
+ * Input accepted by `log.audit()`, `audit()`, and `withAudit()`.
770
+ *
771
+ * `outcome` defaults to `'success'`. Internal fields populated by the audit
772
+ * pipeline (`idempotencyKey`, `context`, `signature`, `prevHash`, `hash`) are
773
+ * stripped — pass them through `log.set({ audit })` if you really need to.
774
+ */
775
+ interface AuditInput {
776
+ action: string;
777
+ actor: AuditActor;
778
+ target?: AuditTarget;
779
+ outcome?: AuditFields['outcome'];
780
+ reason?: string;
781
+ changes?: AuditFields['changes'];
782
+ causationId?: string;
783
+ correlationId?: string;
784
+ version?: number;
785
+ }
786
+ /**
787
+ * Build a normalised {@link AuditFields} from caller input. Defaults:
788
+ * - `outcome` → `'success'`
789
+ * - `version` → {@link AUDIT_SCHEMA_VERSION}
790
+ *
791
+ * `idempotencyKey` is filled at emit time with the event timestamp so retries
792
+ * stay deterministic.
793
+ */
794
+ declare function buildAuditFields(input: AuditInput): AuditFields;
795
+ /**
796
+ * Add audit semantics to an existing {@link RequestLogger}.
797
+ *
798
+ * Mutates the logger in place by adding an `audit` method (with a `.deny()`
799
+ * sub-method). Strictly equivalent to calling `log.set({ audit: ... })` plus
800
+ * `_forceKeep` on emit. Idempotent: calling twice on the same logger only
801
+ * attaches the methods once.
802
+ *
803
+ * @example
804
+ * ```ts
805
+ * const log = withAuditMethods(createLogger())
806
+ * log.audit({
807
+ * action: 'invoice.refund',
808
+ * actor: { type: 'user', id: user.id },
809
+ * target: { type: 'invoice', id: 'inv_889' },
810
+ * })
811
+ * ```
812
+ */
813
+ declare function withAuditMethods<T extends object = Record<string, unknown>>(logger: RequestLogger<T>): AuditableLogger<T>;
814
+ /**
815
+ * Logger augmented with `.audit()` / `.audit.deny()` helpers.
816
+ */
817
+ type AuditableLogger<T extends object = Record<string, unknown>> = RequestLogger<T> & {
818
+ audit: AuditMethod<T>;
819
+ };
820
+ /** Method shape attached to {@link AuditableLogger}. */
821
+ interface AuditMethod<T extends object = Record<string, unknown>> {
822
+ (input: AuditInput): void;
823
+ /**
824
+ * Record an AuthZ-denied action. Forces `outcome: 'denied'` and requires
825
+ * a human-readable `reason`. Most teams forget to log denials — they are
826
+ * exactly what auditors and security teams ask for.
827
+ */
828
+ deny: (reason: string, input: Omit<AuditInput, 'outcome' | 'reason'>) => void;
829
+ }
830
+ /**
831
+ * Standalone audit emitter for non-request contexts (jobs, scripts, CLIs).
832
+ *
833
+ * Creates a one-shot logger, sets the audit fields, and emits immediately.
834
+ * The event is force-kept past tail sampling. Returns the emitted wide event,
835
+ * or `null` if logging is globally disabled.
836
+ *
837
+ * @example
838
+ * ```ts
839
+ * import { audit } from 'evlog'
840
+ *
841
+ * audit({
842
+ * action: 'cron.cleanup',
843
+ * actor: { type: 'system', id: 'cron' },
844
+ * target: { type: 'job', id: 'cleanup-stale-sessions' },
845
+ * outcome: 'success',
846
+ * })
847
+ * ```
848
+ */
849
+ declare function audit(input: AuditInput): WideEvent | null;
850
+ /**
851
+ * Wrap a function so its outcome (success / failure / denied) is automatically
852
+ * audited.
853
+ *
854
+ * Behaviour:
855
+ * - If `fn` resolves, an audit event with `outcome: 'success'` is emitted.
856
+ * - If `fn` throws an `EvlogError` (or any error) with `status === 403`, the
857
+ * audit event is recorded as `'denied'` with the error message as `reason`.
858
+ * - Any other thrown error produces `outcome: 'failure'` and re-throws.
859
+ *
860
+ * Use {@link AuditDeniedError} to signal denial without an HTTP status.
861
+ *
862
+ * @example
863
+ * ```ts
864
+ * const refundInvoice = withAudit(
865
+ * { action: 'invoice.refund', target: (input) => ({ type: 'invoice', id: input.id }) },
866
+ * async (input: { id: string }, ctx: { actor: AuditActor }) => {
867
+ * await db.invoices.refund(input.id)
868
+ * }
869
+ * )
870
+ *
871
+ * await refundInvoice({ id: 'inv_889' }, { actor: { type: 'user', id: user.id } })
872
+ * ```
873
+ */
874
+ declare function withAudit<TInput, TOutput>(options: WithAuditOptions<TInput>, fn: (input: TInput, ctx: WithAuditContext) => Promise<TOutput> | TOutput): (input: TInput, ctx: WithAuditContext) => Promise<TOutput>;
875
+ /**
876
+ * Throw inside a {@link withAudit} body to mark the action as `outcome: 'denied'`
877
+ * regardless of the underlying HTTP status. The constructor message becomes the
878
+ * audit `reason`.
879
+ */
880
+ declare class AuditDeniedError extends Error {
881
+ constructor(reason: string);
882
+ }
883
+ /** Options for {@link withAudit}. `target` may be derived from the input. */
884
+ interface WithAuditOptions<TInput> {
885
+ action: string;
886
+ target?: AuditTarget | ((input: TInput) => AuditTarget | undefined);
887
+ }
888
+ /**
889
+ * Runtime context required by a {@link withAudit}-wrapped function.
890
+ * The actor is always required; correlation IDs are optional.
891
+ */
892
+ interface WithAuditContext {
893
+ actor: AuditActor;
894
+ causationId?: string;
895
+ correlationId?: string;
896
+ }
897
+ /**
898
+ * Compute a compact, redact-aware diff between two objects for the
899
+ * `changes` field. Output is a JSON Patch-style array (RFC 6902 subset:
900
+ * `add`, `remove`, `replace`) — small enough to ship over the wire.
901
+ *
902
+ * Object keys whose name matches one of the `redactPaths` (dot-notation, e.g.
903
+ * `'user.password'`, `'card.cvv'`) are replaced with `'[REDACTED]'` so PII
904
+ * never leaks through the diff.
905
+ *
906
+ * @example
907
+ * ```ts
908
+ * log.audit({
909
+ * action: 'user.update',
910
+ * actor: { type: 'user', id: user.id },
911
+ * target: { type: 'user', id: 'usr_42' },
912
+ * changes: auditDiff(before, after, { redactPaths: ['password'] }),
913
+ * })
914
+ * ```
915
+ */
916
+ declare function auditDiff(before: unknown, after: unknown, options?: AuditDiffOptions): {
917
+ before?: unknown;
918
+ after?: unknown;
919
+ patch: AuditPatchOp[];
920
+ };
921
+ /** Single JSON Patch operation produced by {@link auditDiff}. */
922
+ interface AuditPatchOp {
923
+ op: 'add' | 'remove' | 'replace';
924
+ path: string;
925
+ value?: unknown;
926
+ }
927
+ /** Options for {@link auditDiff}. */
928
+ interface AuditDiffOptions {
929
+ /** Object keys (dot-notation) whose values should be replaced with `[REDACTED]`. */
930
+ redactPaths?: string[];
931
+ /** Custom replacement string. @default '[REDACTED]' */
932
+ replacement?: string;
933
+ /** Include the full redacted `before` snapshot alongside the patch. */
934
+ includeBefore?: boolean;
935
+ /** Include the full redacted `after` snapshot alongside the patch. */
936
+ includeAfter?: boolean;
937
+ }
938
+ /**
939
+ * Define a typed audit action with an optional fixed target type.
940
+ *
941
+ * Returns a curried helper that fills in the action name (and target shape
942
+ * if provided) so call sites stay terse and the action set is discoverable
943
+ * in one place.
944
+ *
945
+ * @example
946
+ * ```ts
947
+ * const refund = defineAuditAction('invoice.refund', { target: 'invoice' })
948
+ *
949
+ * log.audit(refund({
950
+ * actor: { type: 'user', id: user.id },
951
+ * target: { id: 'inv_889' }, // type inferred as 'invoice'
952
+ * outcome: 'success',
953
+ * }))
954
+ * ```
955
+ */
956
+ declare function defineAuditAction<TTargetType extends string | undefined = undefined>(action: string, options?: {
957
+ target?: TTargetType;
958
+ }): DefinedAuditAction<TTargetType>;
959
+ /**
960
+ * Return type of {@link defineAuditAction}. Accepts a partial input (no
961
+ * `action`, target type pre-filled when provided).
962
+ */
963
+ type DefinedAuditAction<TTargetType extends string | undefined> = (input: TTargetType extends string ? Omit<AuditInput, 'action' | 'target'> & {
964
+ target?: Omit<AuditTarget, 'type'> & {
965
+ type?: TTargetType;
966
+ };
967
+ } : Omit<AuditInput, 'action'>) => AuditInput;
968
+ /**
969
+ * Test helper that captures every audit event emitted while it is active.
970
+ *
971
+ * Returns `{ events, restore, expect }`:
972
+ * - `events` — live array of captured `AuditFields`, populated as audits fire.
973
+ * - `restore()` — uninstall the collector. Call from `afterEach()`.
974
+ * - `expect.toIncludeAuditOf(matcher)` — assertion helper used inside `expect`
975
+ * blocks, returns `true` if at least one captured event matches.
976
+ *
977
+ * Only captures audits going through `log.audit()` and the standalone
978
+ * `audit()` function. Events emitted via raw `log.set({ audit })` skip the
979
+ * collector by design — wrap them with `log.audit()` to make them visible to
980
+ * tests.
981
+ *
982
+ * @example
983
+ * ```ts
984
+ * const captured = mockAudit()
985
+ * await refundInvoice('inv_889')
986
+ * expect(captured.events).toHaveLength(1)
987
+ * expect(captured.toIncludeAuditOf({ action: 'invoice.refund' })).toBe(true)
988
+ * captured.restore()
989
+ * ```
990
+ */
991
+ declare function mockAudit(): MockAudit;
992
+ /** Result of {@link mockAudit}. */
993
+ interface MockAudit {
994
+ events: AuditFields[];
995
+ restore: () => void;
996
+ toIncludeAuditOf: (matcher: AuditMatcher) => boolean;
997
+ }
998
+ /** Partial structural matcher for {@link MockAudit.toIncludeAuditOf}. */
999
+ interface AuditMatcher {
1000
+ action?: string | RegExp;
1001
+ outcome?: AuditFields['outcome'];
1002
+ actor?: Partial<AuditActor>;
1003
+ target?: Partial<AuditTarget>;
1004
+ }
1005
+ /** Shape of the optional better-auth bridge for the audit enricher. */
1006
+ interface AuditEnricherBetterAuthBridge {
1007
+ /** Read the current authenticated session for this request, if any. */
1008
+ getSession: (ctx: EnrichContext) => Promise<AuditActor | null | undefined> | AuditActor | null | undefined;
1009
+ }
1010
+ /** Options for {@link auditEnricher}. */
1011
+ interface AuditEnricherOptions {
1012
+ /**
1013
+ * Resolve the tenant id for the current request. The result is stored at
1014
+ * `event.audit.context.tenantId`. Multi-tenant SaaS gets isolation by default.
1015
+ */
1016
+ tenantId?: (ctx: EnrichContext) => string | undefined;
1017
+ /**
1018
+ * Bridge to populate `event.audit.actor` from the authenticated session.
1019
+ * Only used when the application has not already filled `actor`.
1020
+ */
1021
+ bridge?: AuditEnricherBetterAuthBridge;
1022
+ /** When true, overwrite existing context fields. @default false */
1023
+ overwrite?: boolean;
1024
+ }
1025
+ /**
1026
+ * Enrich audit-bearing wide events with request, runtime, and tenant context.
1027
+ *
1028
+ * Runs only when `event.audit` is present — every other event passes through
1029
+ * untouched. Populates:
1030
+ * - `event.audit.context.requestId` from `ctx.request.requestId`
1031
+ * - `event.audit.context.traceId` from `event.traceId`
1032
+ * - `event.audit.context.ip` from `x-forwarded-for` / `x-real-ip`
1033
+ * - `event.audit.context.userAgent` from `user-agent`
1034
+ * - `event.audit.context.tenantId` from `options.tenantId(ctx)`
1035
+ *
1036
+ * Optionally fills `event.audit.actor` from the better-auth bridge when the
1037
+ * caller did not provide one. Anything else (custom actor strategies,
1038
+ * extra context) belongs in a custom enricher — replace this one entirely.
1039
+ */
1040
+ declare function auditEnricher(options?: AuditEnricherOptions): (ctx: EnrichContext) => void | Promise<void>;
1041
+ /** Options accepted by {@link auditOnly}. */
1042
+ interface AuditOnlyOptions {
1043
+ /**
1044
+ * When true, the wrapper awaits the wrapped drain so the event is flushed
1045
+ * before the request resolves. Use for crash-safe audit storage.
1046
+ * @default false
1047
+ */
1048
+ await?: boolean;
1049
+ }
1050
+ /** Drain function signature accepted by all wrappers. Matches `LoggerConfig['drain']`. */
1051
+ type DrainFn = (ctx: DrainContext) => void | Promise<void>;
1052
+ /**
1053
+ * Wrap any drain so it only receives events that carry an `audit` field.
1054
+ *
1055
+ * Use to route audit events to dedicated storage (separate Axiom dataset,
1056
+ * append-only Postgres table, FS journal) without affecting your main drain.
1057
+ *
1058
+ * Per-sink failure isolation comes from `initLogger({ drain: [...] })`: each
1059
+ * drain in the array is invoked independently, so a crashed Axiom call never
1060
+ * blocks the FS audit drain.
1061
+ *
1062
+ * @example
1063
+ * ```ts
1064
+ * import { initLogger, auditOnly } from 'evlog'
1065
+ * import { createAxiomDrain } from 'evlog/axiom'
1066
+ * import { createFsDrain } from 'evlog/fs'
1067
+ *
1068
+ * initLogger({
1069
+ * drain: [
1070
+ * createAxiomDrain({ dataset: 'logs' }),
1071
+ * auditOnly(createFsDrain({ dir: '.audit' }), { await: true }),
1072
+ * ],
1073
+ * })
1074
+ * ```
1075
+ */
1076
+ declare function auditOnly(drain: DrainFn, options?: AuditOnlyOptions): DrainFn;
1077
+ /** Pluggable persistence for the hash-chain state. */
1078
+ interface SignedChainState {
1079
+ /** Load the previous hash from durable storage, or `null` on first run. */
1080
+ load: () => Promise<string | null> | string | null;
1081
+ /** Persist the latest hash so the chain survives process restarts. */
1082
+ save: (hash: string) => Promise<void> | void;
1083
+ }
1084
+ /** Options for {@link signed}. Pick a strategy at construction time. */
1085
+ type SignedOptions = {
1086
+ strategy: 'hmac';
1087
+ secret: string;
1088
+ algorithm?: 'sha256' | 'sha512';
1089
+ } | {
1090
+ strategy: 'hash-chain';
1091
+ state?: SignedChainState;
1092
+ algorithm?: 'sha256' | 'sha512';
1093
+ };
1094
+ /**
1095
+ * Wrap a drain so every event passing through gains tamper-evident integrity.
1096
+ *
1097
+ * - `'hmac'` — adds `event.audit.signature` (HMAC of the canonical event).
1098
+ * - `'hash-chain'` — adds `event.audit.prevHash` and `event.audit.hash` so the
1099
+ * sequence of events forms a verifiable chain. State persists in memory
1100
+ * by default; pass a `state: { load, save }` for cross-process / durable
1101
+ * chains (Redis, file, Postgres).
1102
+ *
1103
+ * The signature is computed before the event is forwarded to the wrapped
1104
+ * drain — combine with {@link auditOnly} when you only want integrity for
1105
+ * audit events.
1106
+ *
1107
+ * @example
1108
+ * ```ts
1109
+ * import { initLogger, auditOnly, signed } from 'evlog'
1110
+ * import { createFsDrain } from 'evlog/fs'
1111
+ *
1112
+ * initLogger({
1113
+ * drain: auditOnly(
1114
+ * signed(createFsDrain({ dir: '.audit' }), { strategy: 'hash-chain' }),
1115
+ * { await: true },
1116
+ * ),
1117
+ * })
1118
+ * ```
1119
+ */
1120
+ declare function signed(drain: DrainFn, options: SignedOptions): DrainFn;
1121
+ /**
1122
+ * Strict redact preset for audit events.
1123
+ *
1124
+ * Combine with the user's existing redact configuration via spread:
1125
+ * `initLogger({ redact: { paths: [...auditRedactPreset.paths!, ...mine] } })`.
1126
+ *
1127
+ * Hardens PII handling:
1128
+ * - Drops `Authorization` and `Cookie` headers anywhere they appear.
1129
+ * - Drops common credential field names (`password`, `passwordHash`, `token`,
1130
+ * `apiKey`, `secret`, `accessToken`, `refreshToken`, `cardNumber`, `cvv`,
1131
+ * `ssn`).
1132
+ *
1133
+ * Built-in pattern maskers (email, credit card, …) keep their default
1134
+ * behaviour — partial masking, not full redaction — so audit trails retain
1135
+ * enough signal to be useful.
1136
+ */
1137
+ declare const auditRedactPreset: RedactConfig;
1138
+ //#endregion
1139
+ export { SamplingRates as $, AuditFields as A, H3EventContext as B, buildAuditFields as C, withAudit as D, signed as E, DrainContext as F, LoggerConfig as G, InternalFields as H, EnrichContext as I, RequestLogEntry as J, ParsedError as K, EnvironmentContext as L, AuditTarget as M, BaseWideEvent as N, withAuditMethods as O, DeepPartial as P, SamplingConfig as Q, ErrorOptions as R, auditRedactPreset as S, mockAudit as T, Log as U, IngestPayload as V, LogLevel as W, RequestLoggerOptions as X, RequestLogger as Y, RouteConfig as Z, WithAuditOptions as _, AuditInput as a, auditEnricher as b, AuditOnlyOptions as c, DefinedAuditAction as d, ServerEvent as et, DrainFn as f, WithAuditContext as g, SignedOptions as h, AuditEnricherOptions as i, WideEvent as it, AuditLoggerMethod as j, AuditActor as k, AuditPatchOp as l, SignedChainState as m, AuditDeniedError as n, TailSamplingContext as nt, AuditMatcher as o, MockAudit as p, RedactConfig as q, AuditDiffOptions as r, TransportConfig as rt, AuditMethod as s, AUDIT_SCHEMA_VERSION as t, TailSamplingCondition as tt, AuditableLogger as u, audit as v, defineAuditAction as w, auditOnly as x, auditDiff as y, FieldContext as z };
1140
+ //# sourceMappingURL=audit-CTIviX3P.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-CTIviX3P.d.mts","names":[],"sources":["../src/types.ts","../src/audit.ts"],"mappings":"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"}