evlog 2.12.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -0
- package/dist/adapters/axiom.d.mts +1 -1
- package/dist/adapters/better-stack.d.mts +1 -1
- package/dist/adapters/datadog.d.mts +1 -1
- package/dist/adapters/fs.d.mts +1 -1
- package/dist/adapters/hyperdx.d.mts +1 -1
- package/dist/adapters/otlp.d.mts +1 -1
- package/dist/adapters/posthog.d.mts +1 -1
- package/dist/adapters/sentry.d.mts +1 -1
- package/dist/ai/index.d.mts +106 -5
- package/dist/ai/index.d.mts.map +1 -1
- package/dist/ai/index.mjs +28 -5
- package/dist/ai/index.mjs.map +1 -1
- package/dist/audit-d9esRZOK.mjs +1440 -0
- package/dist/audit-d9esRZOK.mjs.map +1 -0
- package/dist/audit-mUutdf6A.d.mts +1130 -0
- package/dist/audit-mUutdf6A.d.mts.map +1 -0
- package/dist/better-auth/index.d.mts +220 -0
- package/dist/better-auth/index.d.mts.map +1 -0
- package/dist/better-auth/index.mjs +205 -0
- package/dist/better-auth/index.mjs.map +1 -0
- package/dist/browser.d.mts +1 -1
- package/dist/elysia/index.d.mts +2 -2
- package/dist/elysia/index.d.mts.map +1 -1
- package/dist/elysia/index.mjs +16 -4
- package/dist/elysia/index.mjs.map +1 -1
- package/dist/enrichers.d.mts +1 -1
- package/dist/{error-WRz4_F3W.d.mts → error-D1FZI2Kd.d.mts} +2 -2
- package/dist/{error-WRz4_F3W.d.mts.map → error-D1FZI2Kd.d.mts.map} +1 -1
- package/dist/error.d.mts +1 -1
- package/dist/{errors-J2kt7mZh.d.mts → errors-NIXCyk6I.d.mts} +2 -2
- package/dist/{errors-J2kt7mZh.d.mts.map → errors-NIXCyk6I.d.mts.map} +1 -1
- package/dist/express/index.d.mts +2 -2
- package/dist/express/index.d.mts.map +1 -1
- package/dist/express/index.mjs +8 -4
- package/dist/express/index.mjs.map +1 -1
- package/dist/fastify/index.d.mts +2 -2
- package/dist/fastify/index.d.mts.map +1 -1
- package/dist/fastify/index.mjs +8 -4
- package/dist/fastify/index.mjs.map +1 -1
- package/dist/fork-CTJXnpl8.mjs +72 -0
- package/dist/fork-CTJXnpl8.mjs.map +1 -0
- package/dist/headers-D74M0wsg.mjs +30 -0
- package/dist/headers-D74M0wsg.mjs.map +1 -0
- package/dist/hono/index.d.mts +2 -2
- package/dist/hono/index.mjs +2 -1
- package/dist/hono/index.mjs.map +1 -1
- package/dist/http.d.mts +1 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +2 -2
- package/dist/{logger-Bm0k3Hf3.d.mts → logger-b3epPH0N.d.mts} +8 -4
- package/dist/logger-b3epPH0N.d.mts.map +1 -0
- package/dist/logger.d.mts +1 -1
- package/dist/logger.mjs +1 -1
- package/dist/{headers-ht4yS2mx.mjs → middleware-BWOJ7JI0.mjs} +9 -30
- package/dist/middleware-BWOJ7JI0.mjs.map +1 -0
- package/dist/{middleware-D_igVy93.d.mts → middleware-BYf26Lfu.d.mts} +14 -3
- package/dist/{middleware-D_igVy93.d.mts.map → middleware-BYf26Lfu.d.mts.map} +1 -1
- package/dist/nestjs/index.d.mts +2 -2
- package/dist/nestjs/index.d.mts.map +1 -1
- package/dist/nestjs/index.mjs +8 -4
- package/dist/nestjs/index.mjs.map +1 -1
- package/dist/next/client.d.mts +1 -1
- package/dist/next/index.d.mts +4 -4
- package/dist/next/index.d.mts.map +1 -1
- package/dist/next/index.mjs +15 -1
- package/dist/next/index.mjs.map +1 -1
- package/dist/next/instrumentation.d.mts +1 -1
- package/dist/next/instrumentation.mjs +1 -1
- package/dist/nitro/module.d.mts +2 -2
- package/dist/nitro/plugin.mjs +1 -1
- package/dist/nitro/v3/index.d.mts +2 -2
- package/dist/nitro/v3/module.d.mts +1 -1
- package/dist/nitro/v3/plugin.mjs +1 -1
- package/dist/nitro/v3/useLogger.d.mts +1 -1
- package/dist/{nitro-BeRXZcBd.d.mts → nitro-DenB86W6.d.mts} +2 -2
- package/dist/{nitro-BeRXZcBd.d.mts.map → nitro-DenB86W6.d.mts.map} +1 -1
- package/dist/nuxt/module.d.mts +1 -1
- package/dist/nuxt/module.mjs +1 -1
- package/dist/{parseError-DhXS_vzM.d.mts → parseError-BR9pocvY.d.mts} +2 -2
- package/dist/parseError-BR9pocvY.d.mts.map +1 -0
- package/dist/react-router/index.d.mts +2 -2
- package/dist/react-router/index.d.mts.map +1 -1
- package/dist/react-router/index.mjs +8 -4
- package/dist/react-router/index.mjs.map +1 -1
- package/dist/runtime/client/log.d.mts +1 -1
- package/dist/runtime/server/routes/_evlog/ingest.post.mjs +1 -1
- package/dist/runtime/server/useLogger.d.mts +1 -1
- package/dist/runtime/utils/parseError.d.mts +2 -2
- package/dist/{storage-DpLJYMoc.mjs → storage-CFGTn37X.mjs} +1 -1
- package/dist/{storage-DpLJYMoc.mjs.map → storage-CFGTn37X.mjs.map} +1 -1
- package/dist/sveltekit/index.d.mts +2 -2
- package/dist/sveltekit/index.d.mts.map +1 -1
- package/dist/sveltekit/index.mjs +8 -4
- package/dist/sveltekit/index.mjs.map +1 -1
- package/dist/toolkit.d.mts +41 -4
- package/dist/toolkit.d.mts.map +1 -1
- package/dist/toolkit.mjs +5 -3
- package/dist/types.d.mts +2 -2
- package/dist/{useLogger-Dcj1Nrsa.d.mts → useLogger-C56tDPwf.d.mts} +2 -2
- package/dist/{useLogger-Dcj1Nrsa.d.mts.map → useLogger-C56tDPwf.d.mts.map} +1 -1
- package/dist/{utils-Bnc95-VC.d.mts → utils-DzGCLRFe.d.mts} +2 -2
- package/dist/{utils-Bnc95-VC.d.mts.map → utils-DzGCLRFe.d.mts.map} +1 -1
- package/dist/utils.d.mts +1 -1
- package/dist/vite/index.d.mts +1 -1
- package/dist/workers.d.mts +1 -1
- package/dist/workers.mjs +1 -1
- package/package.json +16 -3
- package/dist/headers-ht4yS2mx.mjs.map +0 -1
- package/dist/logger-Bm0k3Hf3.d.mts.map +0 -1
- package/dist/logger-DY0X5oQd.mjs +0 -704
- package/dist/logger-DY0X5oQd.mjs.map +0 -1
- package/dist/parseError-DhXS_vzM.d.mts.map +0 -1
- package/dist/types-D5OwxZCw.d.mts +0 -587
- package/dist/types-D5OwxZCw.d.mts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-mUutdf6A.d.mts","names":[],"sources":["../src/types.ts","../src/audit.ts"],"mappings":";;YAGY,iBAAA;IAqpBc;;;;;;;;;;;;;IAvoBtB,iBAAA,GAAoB,GAAA,EAAK,mBAAA,YAA+B,OAAA;IAAA;;;;;;;;;;;IAaxD,cAAA,GAAiB,GAAA,EAAK,aAAA,YAAyB,OAAA;IAkBK;;;;;;;;;;;;;;;;IAApD,aAAA,GAAgB,GAAA,EAAK,YAAA,YAAwB,OAAA;EAAA;AAAA;AAAA;EAAA,UAKrC,iBAAA;IACR,iBAAA,GAAoB,GAAA,EAAK,mBAAA,YAA+B,OAAA;IACxD,cAAA,GAAiB,GAAA,EAAK,aAAA,YAAyB,OAAA;IAC/C,aAAA,GAAgB,GAAA,EAAK,YAAA,YAAwB,OAAA;EAAA;AAAA;;AAOjD;;UAAiB,eAAA;EAiBiB;;;;EAZhC,OAAA;EAYgC;;AAMlC;;EAZE,QAAA;EAY4B;;;;EAN5B,WAAA,GAAc,kBAAA;AAAA;AAmBhB;;;AAAA,UAbiB,aAAA;EACf,SAAA;EACA,KAAA;EAAA,CACC,GAAA;AAAA;;;;;;;;UAUc,YAAA;EAqBJ;EAnBX,KAAA;EAmB2B;EAjB3B,QAAA,GAAW,MAAA;EAiB6B;AAM1C;;;;;;;EAdE,QAAA,WAAmB,KAAA;EAsBd;;AAOP;;;EAvBE,WAAA;EAyBA;EAvBA,QAAA,GAAW,KAAA,EAAO,MAAA,GAAS,KAAA;AAAA;;;AAkC7B;UA5BiB,aAAA;;EAEf,IAAA;EA4BA;EA1BA,IAAA;EA8BA;EA5BA,KAAA;EAgCA;EA9BA,KAAA;AAAA;;;AA0CF;;UAnCiB,qBAAA;EAqCR;EAnCP,MAAA;EA+CY;EA7CZ,QAAA;EA6CkB;EA3ClB,IAAA;AAAA;;;;;UAOe,mBAAA;EAgCL;EA9BV,MAAA;EAiCE;EA/BF,QAAA;EAgCY;EA9BZ,IAAA;EA8BkB;EA5BlB,MAAA;EAoC2B;EAlC3B,OAAA,EAAS,MAAA;EA4CO;;;;EAvChB,UAAA;AAAA;;;;;UAOe,aAAA;EAsCA;EApCf,KAAA,EAAO,SAAA;;EAEP,OAAA;IACE,MAAA;IACA,IAAA;IACA,SAAA;EAAA;EAqE0B;EAlE5B,OAAA,GAAU,MAAA;EAwEK;EAtEf,QAAA;IACE,MAAA;IACA,OAAA,GAAU,MAAA;EAAA;AAAA;;;;;UAQG,YAAA;EA0Ef;EAxEA,KAAA,EAAO,SAAA;EA4EP;EA1EA,OAAA;IACE,MAAA;IACA,IAAA;IACA,SAAA;EAAA;EAqFY;EAlFd,OAAA,GAAU,MAAA;AAAA;;;;UAMK,cAAA;EAqK8B;;;;;;;;;;;;;;;;;;EAlJ7C,KAAA,GAAQ,aAAA;EAoJR;;;AAWF;;;;;;;;;;;;;;EA5IE,IAAA,GAAO,qBAAA;AAAA;;;;UAMQ,WAAA;EA2Jd;EAzJD,OAAA;AAAA;AAgLF;;;AAAA,UA1KiB,kBAAA;EA4Kf;EA1KA,OAAA;EA2KO;EAzKP,WAAA;EA0KS;EAxKT,OAAA;EA2KA;EAzKA,UAAA;EA2KY;EAzKZ,MAAA;AAAA;;;;UAMe,YAAA;EA8Kb;;;;;EAxKF,OAAA;EAgLA;EA9KA,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAkLd;EAhLA,MAAA;EAgLI;EA9KJ,QAAA,GAAW,cAAA;EAuLiB;;;;;;EAhL5B,QAAA,GAAW,QAAA;EAqLX;;;;;EA/KA,SAAA;EAkLmB;AAMrB;;;;;AAMA;EAtLE,MAAA;EAsLqB;;;;;;;;;;;;;;;;;;;;;;;;;AAUvB;;;;;;EAhKE,MAAA,aAAmB,YAAA;EAmKL;;;;;AAUhB;;;;;;;;;AAYA;;;;;;;;;;;;;;;;;EAzJE,KAAA,IAAS,GAAA,EAAK,YAAA,YAAwB,OAAA;EA0JqB;EAxJ3D,qBAAA;AAAA;;;;;;;;;UAWe,UAAA;EACf,IAAA;EACA,EAAA;EACA,WAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA;EACA,MAAA;EACA,QAAA;AAAA;;;;;;;;UAUe,WAAA;EACf,IAAA;EACA,EAAA;EAAA,CACC,GAAA;AAAA;;;;;;;;;;;;;;;;;;;;;UAuBc,WAAA;EAkLG;EAhLlB,MAAA;EACA,KAAA,EAAO,UAAA;EACP,MAAA,GAAS,WAAA;EACT,OAAA;EAkMwC;EAhMxC,MAAA;EAwNA;EAtNA,OAAA;IAAY,MAAA;IAAkB,KAAA;EAAA;EA0NE;EAxNhC,WAAA;EAwNgC;EAtNhC,aAAA;EAwN8B;EAtN9B,OAAA;EAsNkC;EApNlC,cAAA;EAmNC;EAjND,OAAA;IACE,SAAA;IACA,OAAA;IACA,EAAA;IACA,SAAA;IACA,QAAA;IAAA,CACC,GAAA;EAAA;EAkNe;EA/MlB,SAAA;EA+MkB;EA7MlB,QAAA;EAwNe;EAtNf,IAAA;AAAA;;;;;;;UASe,aAAA;EACf,SAAA;EACA,KAAA;EACA,OAAA;EACA,WAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA;EACA,KAAA,GAAQ,WAAA;AAAA;;;;KAME,SAAA,GAAY,aAAA,GAAgB,MAAA;;;;;KAM5B,WAAA,MAAiB,CAAA,SAAU,KAAA,YACnC,CAAA,GACA,CAAA,gCACgB,CAAA,IAAK,WAAA,CAAY,CAAA,CAAE,CAAA,OACjC,CAAA;;;;;UAMW,cAAA;EACf,MAAA;EACA,OAAA;EACA,WAAA,GAAc,eAAA;EAkOG;EAhOjB,SAAA;EAmNA;EAjNA,gBAAA;AAAA;;;;UAMe,eAAA;EACf,KAAA;EACA,OAAA;EACA,SAAA;AAAA;;;;;;;KASU,YAAA,oBAAgC,MAAA,qBAC1C,WAAA,CAAY,IAAA,CAAK,CAAA,QAAS,cAAA,KAAmB,cAAA;;AA0N/C;;;;;;;;;;;;;;AAgBA;;;;;;;;;;;;;;;;;;;;UArMiB,aAAA,oBAAiC,MAAA;EAkNhD;;;;;;;AAOF;EAhNE,GAAA,GAAM,OAAA,EAAS,YAAA,CAAa,CAAA;;;;;;EAO5B,KAAA,GAAQ,KAAA,EAAO,KAAA,WAAgB,OAAA,GAAU,YAAA,CAAa,CAAA;EA8MtD;;;;;EAvMA,IAAA,GAAO,OAAA,UAAiB,OAAA,GAAU,YAAA,CAAa,CAAA;;AC1kBjD;;;;EDilBE,IAAA,GAAO,OAAA,UAAiB,OAAA,GAAU,YAAA,CAAa,CAAA;ECxkBhC;;;;;;;EDilBf,IAAA,GAAO,SAAA,GAAY,YAAA,CAAa,CAAA;IAAO,UAAA;EAAA,MAA2B,SAAA;EC/kBlE;;;EDolBA,UAAA,QAAkB,YAAA,CAAa,CAAA,IAAK,MAAA;ECllBpC;;;;;;;;;;AAqEF;;;;;;;;;EDkiBE,IAAA,IAAQ,KAAA,UAAe,EAAA,eAAiB,OAAA;ECtfV;;;;;;;;;;;;;;;;;;AA+BhC;;;;ED+eE,KAAA,GAAQ,iBAAA;AAAA;;UAIO,iBAAA;EAAA,CACd,KAAA,EAD+B,UAAA;EAEhC,IAAA,GAAO,MAAA,UAAgB,KAAA,EAAO,IAAA,CADM,UAAA;AAAA;;;;KAO1B,QAAA;;;;;ACxfZ;;;;;UDmgBiB,GAAA;EC5fe;;;;;EDkgB9B,IAAA,CAAK,GAAA,UAAa,OAAA;EAClB,IAAA,CAAK,KAAA,EAAO,MAAA;ECngBZ;;;;;ED0gBA,KAAA,CAAM,GAAA,UAAa,OAAA;EACnB,KAAA,CAAM,KAAA,EAAO,MAAA;ECrfC;;;;;ED4fd,IAAA,CAAK,GAAA,UAAa,OAAA;EAClB,IAAA,CAAK,KAAA,EAAO,MAAA;EC7fqC;;AAgCnD;;;EDoeE,KAAA,CAAM,GAAA,UAAa,OAAA;EACnB,KAAA,CAAM,KAAA,EAAO,MAAA;AAAA;;;;UAME,YAAA;ECxeN;ED0eT,OAAA;EC1emD;ED4enD,MAAA;EC5ekD;ED8elD,GAAA;ECjfwB;EDmfxB,GAAA;EClfS;EDofT,IAAA;ECpfA;EDsfA,KAAA,GAAQ,KAAA;ECrfH;;;;ED0fL,QAAA,GAAW,MAAA;AAAA;;;;UAMI,oBAAA;EACf,MAAA;EACA,IAAA;EACA,SAAA;AAAA;;AC7dF;;UDmeiB,cAAA;EACf,GAAA,GAAM,aAAA;EACN,SAAA;EACA,MAAA;ECpeY;EDseZ,eAAA;ECte0B;EDwe1B,aAAA;EChe+B;EDke/B,gBAAA;EAAA,CACC,GAAA;AAAA;;;;UAMc,WAAA;EACf,MAAA;EACA,IAAA;EACA,OAAA,EAAS,cAAA;IC1euB,yED4e9B,UAAA;MACE,OAAA;QACE,SAAA,GAAY,OAAA,EAAS,OAAA;MAAA;IAAA,GCveI;ID2e7B,SAAA,IAAa,OAAA,EAAS,OAAA;EAAA;EAExB,IAAA;IAAS,GAAA;MAAQ,UAAA;IAAA;EAAA;EACjB,QAAA,GAAW,QAAA;AAAA;;;;UAMI,WAAA;EACf,OAAA;EACA,MAAA;EACA,GAAA;EACA,GAAA;EACA,IAAA;EACA,GAAA;AAAA;;;AAjIwB;;;;AAAA,cCjpBb,oBAAA;;;;;;;;UASI,UAAA;EACf,MAAA;EACA,KAAA,EAAO,UAAA;EACP,MAAA,GAAS,WAAA;EACT,OAAA,GAAU,WAAA;EACV,MAAA;EACA,OAAA,GAAU,WAAA;EACV,WAAA;EACA,aAAA;EACA,OAAA;AAAA;;;;;ADuBsD;;;;iBCyCxC,gBAAA,CAAiB,KAAA,EAAO,UAAA,GAAa,WAAA;;;;;;;;;;;;;;;;;;;iBA4CrC,gBAAA,oBAAoC,MAAA,kBAAA,CAAyB,MAAA,EAAQ,aAAA,CAAc,CAAA,IAAK,eAAA,CAAgB,CAAA;;;;KA+B5G,eAAA,oBAAmC,MAAA,qBAA2B,aAAA,CAAc,CAAA;EAAO,KAAA,EAAO,WAAA,CAAY,CAAA;AAAA;;UAGjG,WAAA,oBAA+B,MAAA;EAAA,CAC7C,KAAA,EAAO,UAAA;EDxFR;;;;AAMF;ECwFE,IAAA,GAAO,MAAA,UAAgB,KAAA,EAAO,IAAA,CAAK,UAAA;AAAA;;;;;;;AD3ErC;;;;;;;;;;;;;iBCiGgB,KAAA,CAAM,KAAA,EAAO,UAAA,GAAa,SAAA;;;;;;;;ADtE1C;;;;;;;;;;AAeA;;;;;;;iBCuFgB,SAAA,iBAAA,CACd,OAAA,EAAS,gBAAA,CAAiB,MAAA,GAC1B,EAAA,GAAK,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,gBAAA,KAAqB,OAAA,CAAQ,OAAA,IAAW,OAAA,IAC/D,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,gBAAA,KAAqB,OAAA,CAAQ,OAAA;;AD7ErD;;;;cCkHa,gBAAA,SAAyB,KAAA;cAExB,MAAA;AAAA;;UAQG,gBAAA;EACf,MAAA;EACA,MAAA,GAAS,WAAA,KAAgB,KAAA,EAAO,MAAA,KAAW,WAAA;AAAA;;ADxG7C;;;UC+GiB,gBAAA;EACf,KAAA,EAAO,UAAA;EACP,WAAA;EACA,aAAA;AAAA;;;;;;;;;;;;;;;AD5FF;;;;;iBCkHgB,SAAA,CACd,MAAA,WACA,KAAA,WACA,OAAA,GAAS,gBAAA;EACN,MAAA;EAAkB,KAAA;EAAiB,KAAA,EAAO,YAAA;AAAA;;UAkE9B,YAAA;EACf,EAAA;EACA,IAAA;EACA,KAAA;AAAA;;UAIe,gBAAA;ED5Jf;EC8JA,WAAA;ED3IA;EC6IA,WAAA;ED7I4B;EC+I5B,aAAA;EDzIe;EC2If,YAAA;AAAA;;;ADnIF;;;;;;;;;;;AAgBA;;;;;iBCwIgB,iBAAA,oDAAA,CACd,MAAA,UACA,OAAA;EAAY,MAAA,GAAS,WAAA;AAAA,IACpB,kBAAA,CAAmB,WAAA;;;;;KAkBV,kBAAA,4CACV,KAAA,EAAO,WAAA,kBACH,IAAA,CAAK,UAAA;EAAqC,MAAA,GAAS,IAAA,CAAK,WAAA;IAAyB,IAAA,GAAO,WAAA;EAAA;AAAA,IACxF,IAAA,CAAK,UAAA,gBACN,UAAA;;;;;;;;;;;;;;;;ADnDL;;;;;;;;iBC4EgB,SAAA,CAAA,GAAa,SAAA;;UAmBZ,SAAA;EACf,MAAA,EAAQ,WAAA;EACR,OAAA;EACA,gBAAA,GAAmB,OAAA,EAAS,YAAA;AAAA;;UAIb,YAAA;EACf,MAAA,YAAkB,MAAA;EAClB,OAAA,GAAU,WAAA;EACV,KAAA,GAAQ,OAAA,CAAQ,UAAA;EAChB,MAAA,GAAS,OAAA,CAAQ,WAAA;AAAA;;UAqDF,6BAAA;ED1Ge;EC4G9B,UAAA,GAAa,GAAA,EAAK,aAAA,KAAkB,OAAA,CAAQ,UAAA,uBAAiC,UAAA;AAAA;;UAI9D,oBAAA;EDtGf;;;;EC2GA,QAAA,IAAY,GAAA,EAAK,aAAA;EDtGf;;;;EC2GF,MAAA,GAAS,6BAAA;EDnGL;ECqGJ,SAAA;AAAA;;;;;;;;;;;;;;;AD9EF;iBCgGgB,aAAA,CAAc,OAAA,GAAS,oBAAA,IAA6B,GAAA,EAAK,aAAA,YAAyB,OAAA;;UA6CjF,gBAAA;ED7I6B;AAM9C;;;;EC6IE,KAAA;AAAA;;KAIU,OAAA,IAAW,GAAA,EAAK,YAAA,YAAwB,OAAA;;;;;;;;;;;;;;;;;;;;ADvIpD;;;;;iBCiKgB,SAAA,CAAU,KAAA,EAAO,OAAA,EAAS,OAAA,GAAS,gBAAA,GAAwB,OAAA;;UAY1D,gBAAA;EDxKf;EC0KA,IAAA,QAAY,OAAA;EDxKI;EC0KhB,IAAA,GAAO,IAAA,aAAiB,OAAA;AAAA;;KAId,aAAA;EACN,QAAA;EAAkB,MAAA;EAAgB,SAAA;AAAA;EAClC,QAAA;EAAwB,KAAA,GAAQ,gBAAA;EAAkB,SAAA;AAAA;;;;;;;;;;;;;;;;;;;ADxHxD;;;;;;;;iBCoJgB,MAAA,CAAO,KAAA,EAAO,OAAA,EAAS,OAAA,EAAS,aAAA,GAAgB,OAAA;;;;;;;;;;;;;;;;;cAwHnD,iBAAA,EAAmB,YAAA"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { Y as RequestLogger } from "../audit-mUutdf6A.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/better-auth/index.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Minimal type for the Better Auth instance.
|
|
6
|
+
* Only requires `api.getSession` — compatible with any Better Auth configuration.
|
|
7
|
+
*/
|
|
8
|
+
interface BetterAuthInstance {
|
|
9
|
+
api: {
|
|
10
|
+
getSession: (opts: {
|
|
11
|
+
headers: Headers | Record<string, string | string[] | undefined>;
|
|
12
|
+
}) => Promise<{
|
|
13
|
+
user: Record<string, unknown>;
|
|
14
|
+
session: Record<string, unknown>;
|
|
15
|
+
} | null>;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* User fields extracted from a Better Auth session.
|
|
20
|
+
*/
|
|
21
|
+
interface AuthUserData {
|
|
22
|
+
id: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
email?: string;
|
|
25
|
+
image?: string;
|
|
26
|
+
emailVerified?: boolean;
|
|
27
|
+
createdAt?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Session fields extracted from a Better Auth session.
|
|
31
|
+
*/
|
|
32
|
+
interface AuthSessionData {
|
|
33
|
+
id: string;
|
|
34
|
+
expiresAt?: string;
|
|
35
|
+
ipAddress?: string;
|
|
36
|
+
userAgent?: string;
|
|
37
|
+
createdAt?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Options for `identifyUser`.
|
|
41
|
+
*/
|
|
42
|
+
interface IdentifyOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Whether to mask the user email (e.g. `h***@domain.com`).
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
maskEmail?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Whether to include session metadata on the wide event.
|
|
50
|
+
* @default true
|
|
51
|
+
*/
|
|
52
|
+
session?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whitelist of user fields to include.
|
|
55
|
+
* @default ['id', 'name', 'email', 'image', 'emailVerified', 'createdAt']
|
|
56
|
+
*/
|
|
57
|
+
fields?: string[];
|
|
58
|
+
/**
|
|
59
|
+
* Extend the wide event with additional fields derived from the session.
|
|
60
|
+
* Useful for Better Auth plugins (organizations, roles, etc.).
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* identifyUser(log, session, {
|
|
65
|
+
* extend: (session) => ({
|
|
66
|
+
* organization: session.user.activeOrganization,
|
|
67
|
+
* role: session.user.role,
|
|
68
|
+
* }),
|
|
69
|
+
* })
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
extend?: (session: {
|
|
73
|
+
user: Record<string, unknown>;
|
|
74
|
+
session: Record<string, unknown>;
|
|
75
|
+
}) => Record<string, unknown> | undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Options for `createAuthMiddleware`.
|
|
79
|
+
*/
|
|
80
|
+
interface AuthMiddlewareOptions extends IdentifyOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Route patterns to skip session resolution (glob).
|
|
83
|
+
* @default ['/api/auth/**']
|
|
84
|
+
*/
|
|
85
|
+
exclude?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Route patterns to apply session resolution (glob).
|
|
88
|
+
* If set, only matching routes are resolved.
|
|
89
|
+
*/
|
|
90
|
+
include?: string[];
|
|
91
|
+
/**
|
|
92
|
+
* Called after a user is successfully identified.
|
|
93
|
+
* Use to add conditional logic based on user data (e.g. force-keep logs for premium users).
|
|
94
|
+
*/
|
|
95
|
+
onIdentify?: (log: RequestLogger, session: {
|
|
96
|
+
user: Record<string, unknown>;
|
|
97
|
+
session: Record<string, unknown>;
|
|
98
|
+
}) => void | Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Called when no session is found (anonymous request).
|
|
101
|
+
*/
|
|
102
|
+
onAnonymous?: (log: RequestLogger) => void | Promise<void>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Options for `createAuthIdentifier`.
|
|
106
|
+
*/
|
|
107
|
+
type AuthIdentifierOptions = AuthMiddlewareOptions;
|
|
108
|
+
/**
|
|
109
|
+
* Mask an email address for safe logging: `hugo@example.com` -> `h***@example.com`.
|
|
110
|
+
*/
|
|
111
|
+
declare function maskEmail(email: string): string;
|
|
112
|
+
/**
|
|
113
|
+
* Identify a user on a wide event from a Better Auth session result.
|
|
114
|
+
*
|
|
115
|
+
* Sets `userId`, `user`, and optionally `session` fields on the logger.
|
|
116
|
+
* Safe by default — only extracts whitelisted fields and never logs passwords or tokens.
|
|
117
|
+
*
|
|
118
|
+
* Returns `true` if the user was identified, `false` if session data was missing.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* import { identifyUser } from 'evlog/better-auth'
|
|
123
|
+
*
|
|
124
|
+
* const session = await auth.api.getSession({ headers: event.headers })
|
|
125
|
+
* if (session) {
|
|
126
|
+
* identifyUser(log, session)
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @example With email masking
|
|
131
|
+
* ```ts
|
|
132
|
+
* identifyUser(log, session, { maskEmail: true })
|
|
133
|
+
* // user.email → "h***@example.com"
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @example With extend for Better Auth plugins
|
|
137
|
+
* ```ts
|
|
138
|
+
* identifyUser(log, session, {
|
|
139
|
+
* extend: (s) => ({
|
|
140
|
+
* organization: s.user.activeOrganization,
|
|
141
|
+
* role: s.user.role,
|
|
142
|
+
* }),
|
|
143
|
+
* })
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
declare function identifyUser(log: RequestLogger, session: {
|
|
147
|
+
user: Record<string, unknown>;
|
|
148
|
+
session: Record<string, unknown>;
|
|
149
|
+
}, options?: IdentifyOptions): boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Create an async function that resolves a Better Auth session from headers
|
|
152
|
+
* and identifies the user on the logger.
|
|
153
|
+
*
|
|
154
|
+
* Works with any framework — just pass the auth instance and call the returned
|
|
155
|
+
* function with a logger and headers. Supports `include`/`exclude` route patterns
|
|
156
|
+
* and lifecycle hooks (`onIdentify`, `onAnonymous`).
|
|
157
|
+
*
|
|
158
|
+
* @example Nuxt server middleware
|
|
159
|
+
* ```ts
|
|
160
|
+
* import { createAuthMiddleware } from 'evlog/better-auth'
|
|
161
|
+
*
|
|
162
|
+
* const identify = createAuthMiddleware(auth, {
|
|
163
|
+
* exclude: ['/api/auth/**', '/api/public/**'],
|
|
164
|
+
* })
|
|
165
|
+
*
|
|
166
|
+
* export default defineEventHandler(async (event) => {
|
|
167
|
+
* if (!event.context.log) return
|
|
168
|
+
* await identify(event.context.log, event.headers, event.path)
|
|
169
|
+
* })
|
|
170
|
+
* ```
|
|
171
|
+
*
|
|
172
|
+
* @example Express
|
|
173
|
+
* ```ts
|
|
174
|
+
* const identify = createAuthMiddleware(auth, { maskEmail: true })
|
|
175
|
+
*
|
|
176
|
+
* app.use(async (req, res, next) => {
|
|
177
|
+
* await identify(req.log, req.headers, req.path)
|
|
178
|
+
* next()
|
|
179
|
+
* })
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
declare function createAuthMiddleware(auth: BetterAuthInstance, options?: AuthMiddlewareOptions): (log: RequestLogger, headers: Headers | Record<string, string | string[] | undefined>, path?: string) => Promise<boolean>;
|
|
183
|
+
/**
|
|
184
|
+
* Create a Nitro `request` hook that auto-identifies users from Better Auth sessions.
|
|
185
|
+
*
|
|
186
|
+
* Resolves the session from request cookies on every request and sets user/session
|
|
187
|
+
* context on the evlog logger. Skips `/api/auth/**` by default to avoid resolving
|
|
188
|
+
* sessions during auth flows.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```ts
|
|
192
|
+
* // server/plugins/evlog-auth.ts
|
|
193
|
+
* import { createAuthIdentifier } from 'evlog/better-auth'
|
|
194
|
+
* import { auth } from '~/lib/auth'
|
|
195
|
+
*
|
|
196
|
+
* export default defineNitroPlugin((nitroApp) => {
|
|
197
|
+
* nitroApp.hooks.hook('request', createAuthIdentifier(auth))
|
|
198
|
+
* })
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* @example With options
|
|
202
|
+
* ```ts
|
|
203
|
+
* nitroApp.hooks.hook('request', createAuthIdentifier(auth, {
|
|
204
|
+
* maskEmail: true,
|
|
205
|
+
* exclude: ['/api/auth/**', '/api/public/**'],
|
|
206
|
+
* }))
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
declare function createAuthIdentifier(auth: BetterAuthInstance, options?: AuthIdentifierOptions): (event: {
|
|
210
|
+
path: string;
|
|
211
|
+
headers: Headers | {
|
|
212
|
+
get(name: string): string | null;
|
|
213
|
+
};
|
|
214
|
+
context: {
|
|
215
|
+
log?: RequestLogger;
|
|
216
|
+
};
|
|
217
|
+
}) => Promise<void>;
|
|
218
|
+
//#endregion
|
|
219
|
+
export { AuthIdentifierOptions, AuthMiddlewareOptions, AuthSessionData, AuthUserData, BetterAuthInstance, IdentifyOptions, createAuthIdentifier, createAuthMiddleware, identifyUser, maskEmail };
|
|
220
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/better-auth/index.ts"],"mappings":";;;;;AAOA;;UAAiB,kBAAA;EACf,GAAA;IACE,UAAA,GAAa,IAAA;MACX,OAAA,EAAS,OAAA,GAAU,MAAA;IAAA,MACf,OAAA;MACJ,IAAA,EAAM,MAAA;MACN,OAAA,EAAS,MAAA;IAAA;EAAA;AAAA;;;;UAQE,YAAA;EACf,EAAA;EACA,IAAA;EACA,KAAA;EACA,KAAA;EACA,aAAA;EACA,SAAA;AAAA;AANF;;;AAAA,UAYiB,eAAA;EACf,EAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;EACA,SAAA;AAAA;;;AALF;UAWiB,eAAA;;;;;EAKf,SAAA;EAZA;;;;EAiBA,OAAA;EAV8B;;;;EAe9B,MAAA;EAeiG;;;;;;;;;;;;;;EAAjG,MAAA,IAAU,OAAA;IAAW,IAAA,EAAM,MAAA;IAAyB,OAAA,EAAS,MAAA;EAAA,MAA8B,MAAA;AAAA;;;;UAM5E,qBAAA,SAA8B,eAAA;EAAA;;;;EAK7C,OAAA;EAKA;;;;EAAA,OAAA;EAKmD;;;;EAAnD,UAAA,IAAc,GAAA,EAAK,aAAA,EAAe,OAAA;IAAW,IAAA,EAAM,MAAA;IAAyB,OAAA,EAAS,MAAA;EAAA,aAAqC,OAAA;EAI7E;;;EAA7C,WAAA,IAAe,GAAA,EAAK,aAAA,YAAyB,OAAA;AAAA;;;;KAMnC,qBAAA,GAAwB,qBAAA;;;;iBASpB,SAAA,CAAU,KAAA;AAyF1B;;;;;;;;;;;;;;;;;;;;AA4EA;;;;;;;;;;;;;;AA5EA,iBAAgB,YAAA,CACd,GAAA,EAAK,aAAA,EACL,OAAA;EAAW,IAAA,EAAM,MAAA;EAAyB,OAAA,EAAS,MAAA;AAAA,GACnD,OAAA,GAAU,eAAA;;;;;;;AAqIZ;;;;;;;;;;;;;;;;;;;;;;;;;;iBA5DgB,oBAAA,CACd,IAAA,EAAM,kBAAA,EACN,OAAA,GAAU,qBAAA,IACR,GAAA,EAAK,aAAA,EAAe,OAAA,EAAS,OAAA,GAAU,MAAA,yCAA+C,IAAA,cAAkB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyD5F,oBAAA,CACd,IAAA,EAAM,kBAAA,EACN,OAAA,GAAU,qBAAA,IACR,KAAA;EAAS,IAAA;EAAc,OAAA,EAAS,OAAA;IAAY,GAAA,CAAI,IAAA;EAAA;EAAgC,OAAA;IAAW,GAAA,GAAM,aAAA;EAAA;AAAA,MAAsB,OAAA"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { matchesPattern } from "../utils.mjs";
|
|
2
|
+
//#region src/better-auth/index.ts
|
|
3
|
+
const DEFAULT_USER_FIELDS = [
|
|
4
|
+
"id",
|
|
5
|
+
"name",
|
|
6
|
+
"email",
|
|
7
|
+
"image",
|
|
8
|
+
"emailVerified",
|
|
9
|
+
"createdAt"
|
|
10
|
+
];
|
|
11
|
+
const isDev = typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
12
|
+
/**
|
|
13
|
+
* Mask an email address for safe logging: `hugo@example.com` -> `h***@example.com`.
|
|
14
|
+
*/
|
|
15
|
+
function maskEmail(email) {
|
|
16
|
+
const atIndex = email.indexOf("@");
|
|
17
|
+
if (atIndex <= 0) return "***";
|
|
18
|
+
return `${email[0]}***${email.slice(atIndex)}`;
|
|
19
|
+
}
|
|
20
|
+
function extractUserData(user, options) {
|
|
21
|
+
const fields = options?.fields ?? DEFAULT_USER_FIELDS;
|
|
22
|
+
const data = {};
|
|
23
|
+
if (user.id !== void 0 && user.id !== null) data.id = user.id;
|
|
24
|
+
for (const field of fields) {
|
|
25
|
+
if (field === "id") continue;
|
|
26
|
+
const value = user[field];
|
|
27
|
+
if (value === void 0 || value === null) continue;
|
|
28
|
+
if (field === "email" && options?.maskEmail && typeof value === "string") data[field] = maskEmail(value);
|
|
29
|
+
else if (field === "createdAt" && value instanceof Date) data[field] = value.toISOString();
|
|
30
|
+
else data[field] = value;
|
|
31
|
+
}
|
|
32
|
+
return data;
|
|
33
|
+
}
|
|
34
|
+
function extractSessionData(session) {
|
|
35
|
+
const data = { id: String(session.id) };
|
|
36
|
+
if (session.expiresAt) data.expiresAt = session.expiresAt instanceof Date ? session.expiresAt.toISOString() : String(session.expiresAt);
|
|
37
|
+
if (typeof session.ipAddress === "string") data.ipAddress = session.ipAddress;
|
|
38
|
+
if (typeof session.userAgent === "string") data.userAgent = session.userAgent;
|
|
39
|
+
if (session.createdAt) data.createdAt = session.createdAt instanceof Date ? session.createdAt.toISOString() : String(session.createdAt);
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Identify a user on a wide event from a Better Auth session result.
|
|
44
|
+
*
|
|
45
|
+
* Sets `userId`, `user`, and optionally `session` fields on the logger.
|
|
46
|
+
* Safe by default — only extracts whitelisted fields and never logs passwords or tokens.
|
|
47
|
+
*
|
|
48
|
+
* Returns `true` if the user was identified, `false` if session data was missing.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { identifyUser } from 'evlog/better-auth'
|
|
53
|
+
*
|
|
54
|
+
* const session = await auth.api.getSession({ headers: event.headers })
|
|
55
|
+
* if (session) {
|
|
56
|
+
* identifyUser(log, session)
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @example With email masking
|
|
61
|
+
* ```ts
|
|
62
|
+
* identifyUser(log, session, { maskEmail: true })
|
|
63
|
+
* // user.email → "h***@example.com"
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example With extend for Better Auth plugins
|
|
67
|
+
* ```ts
|
|
68
|
+
* identifyUser(log, session, {
|
|
69
|
+
* extend: (s) => ({
|
|
70
|
+
* organization: s.user.activeOrganization,
|
|
71
|
+
* role: s.user.role,
|
|
72
|
+
* }),
|
|
73
|
+
* })
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
function identifyUser(log, session, options) {
|
|
77
|
+
const user = extractUserData(session.user, options);
|
|
78
|
+
if (!user.id) return false;
|
|
79
|
+
const includeSession = options?.session !== false;
|
|
80
|
+
const data = {
|
|
81
|
+
userId: user.id,
|
|
82
|
+
user
|
|
83
|
+
};
|
|
84
|
+
if (includeSession) data.session = extractSessionData(session.session);
|
|
85
|
+
if (options?.extend) {
|
|
86
|
+
const extra = options.extend(session);
|
|
87
|
+
if (extra) Object.assign(data, extra);
|
|
88
|
+
}
|
|
89
|
+
log.set(data);
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
function shouldResolve(path, options) {
|
|
93
|
+
const exclude = options?.exclude ?? ["/api/auth/**"];
|
|
94
|
+
for (const pattern of exclude) if (matchesPattern(path, pattern)) return false;
|
|
95
|
+
if (options?.include) {
|
|
96
|
+
for (const pattern of options.include) if (matchesPattern(path, pattern)) return true;
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create an async function that resolves a Better Auth session from headers
|
|
103
|
+
* and identifies the user on the logger.
|
|
104
|
+
*
|
|
105
|
+
* Works with any framework — just pass the auth instance and call the returned
|
|
106
|
+
* function with a logger and headers. Supports `include`/`exclude` route patterns
|
|
107
|
+
* and lifecycle hooks (`onIdentify`, `onAnonymous`).
|
|
108
|
+
*
|
|
109
|
+
* @example Nuxt server middleware
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { createAuthMiddleware } from 'evlog/better-auth'
|
|
112
|
+
*
|
|
113
|
+
* const identify = createAuthMiddleware(auth, {
|
|
114
|
+
* exclude: ['/api/auth/**', '/api/public/**'],
|
|
115
|
+
* })
|
|
116
|
+
*
|
|
117
|
+
* export default defineEventHandler(async (event) => {
|
|
118
|
+
* if (!event.context.log) return
|
|
119
|
+
* await identify(event.context.log, event.headers, event.path)
|
|
120
|
+
* })
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* @example Express
|
|
124
|
+
* ```ts
|
|
125
|
+
* const identify = createAuthMiddleware(auth, { maskEmail: true })
|
|
126
|
+
*
|
|
127
|
+
* app.use(async (req, res, next) => {
|
|
128
|
+
* await identify(req.log, req.headers, req.path)
|
|
129
|
+
* next()
|
|
130
|
+
* })
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
function createAuthMiddleware(auth, options) {
|
|
134
|
+
return async (log, headers, path) => {
|
|
135
|
+
if (path && !shouldResolve(path, options)) return false;
|
|
136
|
+
const start = Date.now();
|
|
137
|
+
try {
|
|
138
|
+
const session = await auth.api.getSession({ headers });
|
|
139
|
+
const resolvedIn = Date.now() - start;
|
|
140
|
+
if (session) {
|
|
141
|
+
if (identifyUser(log, session, options)) {
|
|
142
|
+
log.set({ auth: {
|
|
143
|
+
resolvedIn,
|
|
144
|
+
identified: true
|
|
145
|
+
} });
|
|
146
|
+
if (options?.onIdentify) await options.onIdentify(log, session);
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
log.set({ auth: {
|
|
151
|
+
resolvedIn,
|
|
152
|
+
identified: false
|
|
153
|
+
} });
|
|
154
|
+
if (options?.onAnonymous) await options.onAnonymous(log);
|
|
155
|
+
return false;
|
|
156
|
+
} catch (err) {
|
|
157
|
+
const resolvedIn = Date.now() - start;
|
|
158
|
+
log.set({ auth: {
|
|
159
|
+
resolvedIn,
|
|
160
|
+
identified: false,
|
|
161
|
+
error: true
|
|
162
|
+
} });
|
|
163
|
+
if (isDev) console.warn("[evlog/better-auth] Session resolution failed:", err);
|
|
164
|
+
if (options?.onAnonymous) await options.onAnonymous(log);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Create a Nitro `request` hook that auto-identifies users from Better Auth sessions.
|
|
171
|
+
*
|
|
172
|
+
* Resolves the session from request cookies on every request and sets user/session
|
|
173
|
+
* context on the evlog logger. Skips `/api/auth/**` by default to avoid resolving
|
|
174
|
+
* sessions during auth flows.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* // server/plugins/evlog-auth.ts
|
|
179
|
+
* import { createAuthIdentifier } from 'evlog/better-auth'
|
|
180
|
+
* import { auth } from '~/lib/auth'
|
|
181
|
+
*
|
|
182
|
+
* export default defineNitroPlugin((nitroApp) => {
|
|
183
|
+
* nitroApp.hooks.hook('request', createAuthIdentifier(auth))
|
|
184
|
+
* })
|
|
185
|
+
* ```
|
|
186
|
+
*
|
|
187
|
+
* @example With options
|
|
188
|
+
* ```ts
|
|
189
|
+
* nitroApp.hooks.hook('request', createAuthIdentifier(auth, {
|
|
190
|
+
* maskEmail: true,
|
|
191
|
+
* exclude: ['/api/auth/**', '/api/public/**'],
|
|
192
|
+
* }))
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
function createAuthIdentifier(auth, options) {
|
|
196
|
+
const middleware = createAuthMiddleware(auth, options);
|
|
197
|
+
return async (event) => {
|
|
198
|
+
if (!event.context.log) return;
|
|
199
|
+
await middleware(event.context.log, event.headers, event.path);
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
export { createAuthIdentifier, createAuthMiddleware, identifyUser, maskEmail };
|
|
204
|
+
|
|
205
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/better-auth/index.ts"],"sourcesContent":["import type { RequestLogger } from '../types'\nimport { matchesPattern } from '../utils'\n\n/**\n * Minimal type for the Better Auth instance.\n * Only requires `api.getSession` — compatible with any Better Auth configuration.\n */\nexport interface BetterAuthInstance {\n api: {\n getSession: (opts: {\n headers: Headers | Record<string, string | string[] | undefined>\n }) => Promise<{\n user: Record<string, unknown>\n session: Record<string, unknown>\n } | null>\n }\n}\n\n/**\n * User fields extracted from a Better Auth session.\n */\nexport interface AuthUserData {\n id: string\n name?: string\n email?: string\n image?: string\n emailVerified?: boolean\n createdAt?: string\n}\n\n/**\n * Session fields extracted from a Better Auth session.\n */\nexport interface AuthSessionData {\n id: string\n expiresAt?: string\n ipAddress?: string\n userAgent?: string\n createdAt?: string\n}\n\n/**\n * Options for `identifyUser`.\n */\nexport interface IdentifyOptions {\n /**\n * Whether to mask the user email (e.g. `h***@domain.com`).\n * @default false\n */\n maskEmail?: boolean\n /**\n * Whether to include session metadata on the wide event.\n * @default true\n */\n session?: boolean\n /**\n * Whitelist of user fields to include.\n * @default ['id', 'name', 'email', 'image', 'emailVerified', 'createdAt']\n */\n fields?: string[]\n /**\n * Extend the wide event with additional fields derived from the session.\n * Useful for Better Auth plugins (organizations, roles, etc.).\n *\n * @example\n * ```ts\n * identifyUser(log, session, {\n * extend: (session) => ({\n * organization: session.user.activeOrganization,\n * role: session.user.role,\n * }),\n * })\n * ```\n */\n extend?: (session: { user: Record<string, unknown>, session: Record<string, unknown> }) => Record<string, unknown> | undefined\n}\n\n/**\n * Options for `createAuthMiddleware`.\n */\nexport interface AuthMiddlewareOptions extends IdentifyOptions {\n /**\n * Route patterns to skip session resolution (glob).\n * @default ['/api/auth/**']\n */\n exclude?: string[]\n /**\n * Route patterns to apply session resolution (glob).\n * If set, only matching routes are resolved.\n */\n include?: string[]\n /**\n * Called after a user is successfully identified.\n * Use to add conditional logic based on user data (e.g. force-keep logs for premium users).\n */\n onIdentify?: (log: RequestLogger, session: { user: Record<string, unknown>, session: Record<string, unknown> }) => void | Promise<void>\n /**\n * Called when no session is found (anonymous request).\n */\n onAnonymous?: (log: RequestLogger) => void | Promise<void>\n}\n\n/**\n * Options for `createAuthIdentifier`.\n */\nexport type AuthIdentifierOptions = AuthMiddlewareOptions\n\nconst DEFAULT_USER_FIELDS = ['id', 'name', 'email', 'image', 'emailVerified', 'createdAt']\n\nconst isDev = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n\n/**\n * Mask an email address for safe logging: `hugo@example.com` -> `h***@example.com`.\n */\nexport function maskEmail(email: string): string {\n const atIndex = email.indexOf('@')\n if (atIndex <= 0) return '***'\n return `${email[0]}***${email.slice(atIndex)}`\n}\n\nfunction extractUserData(\n user: Record<string, unknown>,\n options?: IdentifyOptions,\n): AuthUserData {\n const fields = options?.fields ?? DEFAULT_USER_FIELDS\n const data: Record<string, unknown> = {}\n\n if (user.id !== undefined && user.id !== null) {\n data.id = user.id\n }\n\n for (const field of fields) {\n if (field === 'id') continue\n const value = user[field]\n if (value === undefined || value === null) continue\n\n if (field === 'email' && options?.maskEmail && typeof value === 'string') {\n data[field] = maskEmail(value)\n } else if (field === 'createdAt' && value instanceof Date) {\n data[field] = value.toISOString()\n } else {\n data[field] = value\n }\n }\n\n return data as unknown as AuthUserData\n}\n\nfunction extractSessionData(\n session: Record<string, unknown>,\n): AuthSessionData {\n const data: AuthSessionData = { id: String(session.id) }\n\n if (session.expiresAt) {\n data.expiresAt = session.expiresAt instanceof Date\n ? session.expiresAt.toISOString()\n : String(session.expiresAt)\n }\n if (typeof session.ipAddress === 'string') data.ipAddress = session.ipAddress\n if (typeof session.userAgent === 'string') data.userAgent = session.userAgent\n if (session.createdAt) {\n data.createdAt = session.createdAt instanceof Date\n ? session.createdAt.toISOString()\n : String(session.createdAt)\n }\n\n return data\n}\n\n/**\n * Identify a user on a wide event from a Better Auth session result.\n *\n * Sets `userId`, `user`, and optionally `session` fields on the logger.\n * Safe by default — only extracts whitelisted fields and never logs passwords or tokens.\n *\n * Returns `true` if the user was identified, `false` if session data was missing.\n *\n * @example\n * ```ts\n * import { identifyUser } from 'evlog/better-auth'\n *\n * const session = await auth.api.getSession({ headers: event.headers })\n * if (session) {\n * identifyUser(log, session)\n * }\n * ```\n *\n * @example With email masking\n * ```ts\n * identifyUser(log, session, { maskEmail: true })\n * // user.email → \"h***@example.com\"\n * ```\n *\n * @example With extend for Better Auth plugins\n * ```ts\n * identifyUser(log, session, {\n * extend: (s) => ({\n * organization: s.user.activeOrganization,\n * role: s.user.role,\n * }),\n * })\n * ```\n */\nexport function identifyUser(\n log: RequestLogger,\n session: { user: Record<string, unknown>, session: Record<string, unknown> },\n options?: IdentifyOptions,\n): boolean {\n const user = extractUserData(session.user, options)\n if (!user.id) return false\n\n const includeSession = options?.session !== false\n\n const data: Record<string, unknown> = {\n userId: user.id,\n user,\n }\n\n if (includeSession) {\n data.session = extractSessionData(session.session)\n }\n\n if (options?.extend) {\n const extra = options.extend(session)\n if (extra) Object.assign(data, extra)\n }\n\n log.set(data)\n return true\n}\n\nfunction shouldResolve(path: string, options?: { exclude?: string[], include?: string[] }): boolean {\n const exclude = options?.exclude ?? ['/api/auth/**']\n for (const pattern of exclude) {\n if (matchesPattern(path, pattern)) return false\n }\n\n if (options?.include) {\n for (const pattern of options.include) {\n if (matchesPattern(path, pattern)) return true\n }\n return false\n }\n\n return true\n}\n\n/**\n * Create an async function that resolves a Better Auth session from headers\n * and identifies the user on the logger.\n *\n * Works with any framework — just pass the auth instance and call the returned\n * function with a logger and headers. Supports `include`/`exclude` route patterns\n * and lifecycle hooks (`onIdentify`, `onAnonymous`).\n *\n * @example Nuxt server middleware\n * ```ts\n * import { createAuthMiddleware } from 'evlog/better-auth'\n *\n * const identify = createAuthMiddleware(auth, {\n * exclude: ['/api/auth/**', '/api/public/**'],\n * })\n *\n * export default defineEventHandler(async (event) => {\n * if (!event.context.log) return\n * await identify(event.context.log, event.headers, event.path)\n * })\n * ```\n *\n * @example Express\n * ```ts\n * const identify = createAuthMiddleware(auth, { maskEmail: true })\n *\n * app.use(async (req, res, next) => {\n * await identify(req.log, req.headers, req.path)\n * next()\n * })\n * ```\n */\nexport function createAuthMiddleware(\n auth: BetterAuthInstance,\n options?: AuthMiddlewareOptions,\n): (log: RequestLogger, headers: Headers | Record<string, string | string[] | undefined>, path?: string) => Promise<boolean> {\n return async (log, headers, path?) => {\n if (path && !shouldResolve(path, options)) return false\n\n const start = Date.now()\n try {\n const session = await auth.api.getSession({ headers })\n const resolvedIn = Date.now() - start\n\n if (session) {\n const identified = identifyUser(log, session, options)\n if (identified) {\n log.set({ auth: { resolvedIn, identified: true } } as Record<string, unknown>)\n if (options?.onIdentify) await options.onIdentify(log, session)\n return true\n }\n }\n\n log.set({ auth: { resolvedIn, identified: false } } as Record<string, unknown>)\n if (options?.onAnonymous) await options.onAnonymous(log)\n return false\n } catch (err) {\n const resolvedIn = Date.now() - start\n log.set({ auth: { resolvedIn, identified: false, error: true } } as Record<string, unknown>)\n if (isDev) console.warn('[evlog/better-auth] Session resolution failed:', err)\n if (options?.onAnonymous) await options.onAnonymous(log)\n return false\n }\n }\n}\n\n/**\n * Create a Nitro `request` hook that auto-identifies users from Better Auth sessions.\n *\n * Resolves the session from request cookies on every request and sets user/session\n * context on the evlog logger. Skips `/api/auth/**` by default to avoid resolving\n * sessions during auth flows.\n *\n * @example\n * ```ts\n * // server/plugins/evlog-auth.ts\n * import { createAuthIdentifier } from 'evlog/better-auth'\n * import { auth } from '~/lib/auth'\n *\n * export default defineNitroPlugin((nitroApp) => {\n * nitroApp.hooks.hook('request', createAuthIdentifier(auth))\n * })\n * ```\n *\n * @example With options\n * ```ts\n * nitroApp.hooks.hook('request', createAuthIdentifier(auth, {\n * maskEmail: true,\n * exclude: ['/api/auth/**', '/api/public/**'],\n * }))\n * ```\n */\nexport function createAuthIdentifier(\n auth: BetterAuthInstance,\n options?: AuthIdentifierOptions,\n): (event: { path: string, headers: Headers | { get(name: string): string | null }, context: { log?: RequestLogger } }) => Promise<void> {\n const middleware = createAuthMiddleware(auth, options)\n\n return async (event) => {\n if (!event.context.log) return\n await middleware(event.context.log, event.headers as Headers, event.path)\n }\n}\n"],"mappings":"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"}
|
package/dist/browser.d.mts
CHANGED
package/dist/elysia/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as BaseEvlogOptions } from "../middleware-
|
|
1
|
+
import { Y as RequestLogger } from "../audit-mUutdf6A.mjs";
|
|
2
|
+
import { t as BaseEvlogOptions } from "../middleware-BYf26Lfu.mjs";
|
|
3
3
|
import { Elysia } from "elysia";
|
|
4
4
|
|
|
5
5
|
//#region src/elysia/index.d.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/elysia/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/elysia/index.ts"],"mappings":";;;;;KAgBY,kBAAA,GAAqB,gBAAA;;AAAjC;;;;;AAoBA;;;;;;;;;;;;iBAAgB,SAAA,oBAA6B,MAAA,kBAAA,CAAA,GAA4B,aAAA,CAAc,CAAA;AAAA,iBAwCvE,KAAA,CAAM,OAAA,GAAS,kBAAA,GAAuB,MAAA"}
|
package/dist/elysia/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { filterSafeHeaders } from "../utils.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { t as createMiddlewareLogger } from "../middleware-BWOJ7JI0.mjs";
|
|
3
|
+
import { t as attachForkToLogger } from "../fork-CTJXnpl8.mjs";
|
|
3
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
5
|
import { Elysia } from "elysia";
|
|
5
6
|
//#region src/elysia/index.ts
|
|
@@ -32,14 +33,25 @@ function evlog(options = {}) {
|
|
|
32
33
|
const emitted = /* @__PURE__ */ new WeakSet();
|
|
33
34
|
const requestState = /* @__PURE__ */ new WeakMap();
|
|
34
35
|
return new Elysia({ name: "evlog" }).derive({ as: "global" }, ({ request, path, headers }) => {
|
|
35
|
-
const
|
|
36
|
+
const middlewareOpts = {
|
|
36
37
|
method: request.method,
|
|
37
38
|
path,
|
|
38
39
|
requestId: headers["x-request-id"] || crypto.randomUUID(),
|
|
39
40
|
headers: filterSafeHeaders(headers),
|
|
40
41
|
...options
|
|
41
|
-
}
|
|
42
|
-
|
|
42
|
+
};
|
|
43
|
+
const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts);
|
|
44
|
+
if (!skipped) {
|
|
45
|
+
attachForkToLogger(storage, logger, middlewareOpts, {
|
|
46
|
+
onChildEnter: (child) => {
|
|
47
|
+
activeLoggers.add(child);
|
|
48
|
+
},
|
|
49
|
+
onChildExit: (child) => {
|
|
50
|
+
activeLoggers.delete(child);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
activeLoggers.add(logger);
|
|
54
|
+
}
|
|
43
55
|
storage.enterWith(logger);
|
|
44
56
|
requestState.set(request, {
|
|
45
57
|
finish,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/elysia/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { Elysia } from 'elysia'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { filterSafeHeaders } from '../utils'\n\nconst storage = new AsyncLocalStorage<RequestLogger>()\n\n// Tracks loggers that are currently active (within a live request).\n// Elysia uses storage.enterWith() which persists in the async context\n// even after the request ends, so we use this set to distinguish\n// an in-flight logger from a stale one.\nconst activeLoggers = new WeakSet<RequestLogger>()\n\nexport type EvlogElysiaOptions = BaseEvlogOptions\n\n/**\n * Get the request-scoped logger from anywhere in the call stack.\n * Must be called inside a request handled by the `evlog()` plugin.\n *\n * Unlike other frameworks, Elysia uses `storage.enterWith()` which persists\n * beyond the request lifecycle. This accessor additionally checks `activeLoggers`\n * to ensure the logger belongs to an in-flight request.\n *\n * @example\n * ```ts\n * import { useLogger } from 'evlog/elysia'\n *\n * function findUser(id: string) {\n * const log = useLogger()\n * log.set({ user: { id } })\n * }\n * ```\n */\nexport function useLogger<T extends object = Record<string, unknown>>(): RequestLogger<T> {\n const logger = storage.getStore()\n if (!logger || !activeLoggers.has(logger)) {\n throw new Error(\n '[evlog] useLogger() was called outside of an evlog plugin context. '\n + 'Make sure app.use(evlog()) is registered before your routes.',\n )\n }\n return logger as RequestLogger<T>\n}\n\n/**\n * Create an evlog plugin for Elysia.\n *\n * @example\n * ```ts\n * import { Elysia } from 'elysia'\n * import { evlog } from 'evlog/elysia'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Elysia()\n * .use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * .get('/health', ({ log }) => {\n * log.set({ route: 'health' })\n * return { ok: true }\n * })\n * .listen(3000)\n * ```\n */\ninterface RequestState {\n finish: (opts?: { status?: number; error?: Error }) => Promise<unknown>\n skipped: boolean\n logger: RequestLogger\n}\n\nexport function evlog(options: EvlogElysiaOptions = {}) {\n const emitted = new WeakSet<Request>()\n const requestState = new WeakMap<Request, RequestState>()\n\n return new Elysia({ name: 'evlog' })\n .derive({ as: 'global' }, ({ request, path, headers }) => {\n const
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/elysia/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { Elysia } from 'elysia'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { attachForkToLogger } from '../shared/fork'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { filterSafeHeaders } from '../utils'\n\nconst storage = new AsyncLocalStorage<RequestLogger>()\n\n// Tracks loggers that are currently active (within a live request).\n// Elysia uses storage.enterWith() which persists in the async context\n// even after the request ends, so we use this set to distinguish\n// an in-flight logger from a stale one.\nconst activeLoggers = new WeakSet<RequestLogger>()\n\nexport type EvlogElysiaOptions = BaseEvlogOptions\n\n/**\n * Get the request-scoped logger from anywhere in the call stack.\n * Must be called inside a request handled by the `evlog()` plugin.\n *\n * Unlike other frameworks, Elysia uses `storage.enterWith()` which persists\n * beyond the request lifecycle. This accessor additionally checks `activeLoggers`\n * to ensure the logger belongs to an in-flight request.\n *\n * @example\n * ```ts\n * import { useLogger } from 'evlog/elysia'\n *\n * function findUser(id: string) {\n * const log = useLogger()\n * log.set({ user: { id } })\n * }\n * ```\n */\nexport function useLogger<T extends object = Record<string, unknown>>(): RequestLogger<T> {\n const logger = storage.getStore()\n if (!logger || !activeLoggers.has(logger)) {\n throw new Error(\n '[evlog] useLogger() was called outside of an evlog plugin context. '\n + 'Make sure app.use(evlog()) is registered before your routes.',\n )\n }\n return logger as RequestLogger<T>\n}\n\n/**\n * Create an evlog plugin for Elysia.\n *\n * @example\n * ```ts\n * import { Elysia } from 'elysia'\n * import { evlog } from 'evlog/elysia'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Elysia()\n * .use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * .get('/health', ({ log }) => {\n * log.set({ route: 'health' })\n * return { ok: true }\n * })\n * .listen(3000)\n * ```\n */\ninterface RequestState {\n finish: (opts?: { status?: number; error?: Error }) => Promise<unknown>\n skipped: boolean\n logger: RequestLogger\n}\n\nexport function evlog(options: EvlogElysiaOptions = {}) {\n const emitted = new WeakSet<Request>()\n const requestState = new WeakMap<Request, RequestState>()\n\n return new Elysia({ name: 'evlog' })\n .derive({ as: 'global' }, ({ request, path, headers }) => {\n const middlewareOpts = {\n method: request.method,\n path,\n requestId: headers['x-request-id'] || crypto.randomUUID(),\n // It's recommended to use context.headers instead of context.request.headers\n // because Elysia has fast path for getting headers on Bun\n headers: filterSafeHeaders(headers as Record<string, string>),\n ...options,\n }\n const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts)\n\n if (!skipped) {\n attachForkToLogger(storage, logger, middlewareOpts, {\n onChildEnter: (child) => {\n activeLoggers.add(child)\n },\n onChildExit: (child) => {\n activeLoggers.delete(child)\n },\n })\n activeLoggers.add(logger)\n }\n storage.enterWith(logger)\n requestState.set(request, { finish, skipped, logger })\n\n return { log: logger }\n })\n .onAfterResponse({ as: 'global' }, async ({ request, set }) => {\n const state = requestState.get(request)\n if (!state || state.skipped || emitted.has(request)) return\n emitted.add(request)\n await state.finish({ status: set.status as number || 200 })\n activeLoggers.delete(state.logger)\n storage.enterWith(undefined as unknown as RequestLogger)\n })\n .onError({ as: 'global' }, async ({ request, error }) => {\n const state = requestState.get(request)\n if (!state || state.skipped || emitted.has(request)) return\n emitted.add(request)\n const err = error instanceof Error ? error : new Error(String(error))\n state.logger.error(err)\n await state.finish({ error: err })\n activeLoggers.delete(state.logger)\n storage.enterWith(undefined as unknown as RequestLogger)\n })\n}\n"],"mappings":";;;;;;AAQA,MAAM,UAAU,IAAI,mBAAkC;AAMtD,MAAM,gCAAgB,IAAI,SAAwB;;;;;;;;;;;;;;;;;;;AAsBlD,SAAgB,YAA0E;CACxF,MAAM,SAAS,QAAQ,UAAU;AACjC,KAAI,CAAC,UAAU,CAAC,cAAc,IAAI,OAAO,CACvC,OAAM,IAAI,MACR,kIAED;AAEH,QAAO;;AAgCT,SAAgB,MAAM,UAA8B,EAAE,EAAE;CACtD,MAAM,0BAAU,IAAI,SAAkB;CACtC,MAAM,+BAAe,IAAI,SAAgC;AAEzD,QAAO,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC,CACjC,OAAO,EAAE,IAAI,UAAU,GAAG,EAAE,SAAS,MAAM,cAAc;EACxD,MAAM,iBAAiB;GACrB,QAAQ,QAAQ;GAChB;GACA,WAAW,QAAQ,mBAAmB,OAAO,YAAY;GAGzD,SAAS,kBAAkB,QAAkC;GAC7D,GAAG;GACJ;EACD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB,eAAe;AAE1E,MAAI,CAAC,SAAS;AACZ,sBAAmB,SAAS,QAAQ,gBAAgB;IAClD,eAAe,UAAU;AACvB,mBAAc,IAAI,MAAM;;IAE1B,cAAc,UAAU;AACtB,mBAAc,OAAO,MAAM;;IAE9B,CAAC;AACF,iBAAc,IAAI,OAAO;;AAE3B,UAAQ,UAAU,OAAO;AACzB,eAAa,IAAI,SAAS;GAAE;GAAQ;GAAS;GAAQ,CAAC;AAEtD,SAAO,EAAE,KAAK,QAAQ;GACtB,CACD,gBAAgB,EAAE,IAAI,UAAU,EAAE,OAAO,EAAE,SAAS,UAAU;EAC7D,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,MAAM,WAAW,QAAQ,IAAI,QAAQ,CAAE;AACrD,UAAQ,IAAI,QAAQ;AACpB,QAAM,MAAM,OAAO,EAAE,QAAQ,IAAI,UAAoB,KAAK,CAAC;AAC3D,gBAAc,OAAO,MAAM,OAAO;AAClC,UAAQ,UAAU,KAAA,EAAsC;GACxD,CACD,QAAQ,EAAE,IAAI,UAAU,EAAE,OAAO,EAAE,SAAS,YAAY;EACvD,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,MAAM,WAAW,QAAQ,IAAI,QAAQ,CAAE;AACrD,UAAQ,IAAI,QAAQ;EACpB,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,QAAM,OAAO,MAAM,IAAI;AACvB,QAAM,MAAM,OAAO,EAAE,OAAO,KAAK,CAAC;AAClC,gBAAc,OAAO,MAAM,OAAO;AAClC,UAAQ,UAAU,KAAA,EAAsC;GACxD"}
|
package/dist/enrichers.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { R as ErrorOptions } from "./audit-mUutdf6A.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/error.d.ts
|
|
4
4
|
/**
|
|
@@ -67,4 +67,4 @@ declare class EvlogError extends Error {
|
|
|
67
67
|
declare function createError(options: ErrorOptions | string): EvlogError;
|
|
68
68
|
//#endregion
|
|
69
69
|
export { createError as n, EvlogError as t };
|
|
70
|
-
//# sourceMappingURL=error-
|
|
70
|
+
//# sourceMappingURL=error-D1FZI2Kd.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-
|
|
1
|
+
{"version":3,"file":"error-D1FZI2Kd.d.mts","names":[],"sources":["../src/error.ts"],"mappings":";;;;;AAqBA;;;;;;;;;;;;;cAAa,UAAA,SAAmB,KAAA;EAY1B;EAAA,SATK,MAAA;EAAA,SACA,GAAA;EAAA,SACA,GAAA;EAAA,SACA,IAAA;EAqCL;;;;EAAA,IA/BA,QAAA,CAAA,GAAY,MAAA;cAIJ,OAAA,EAAS,YAAA;EA0CqB;EAAA,IAftC,UAAA,CAAA;EAuDJ;EAAA,IAlDI,UAAA,CAAA;EAkDY;EAAA,IA7CZ,aAAA,CAAA;EAiFU;EAAA,IA5EV,IAAA,CAAA;IAAU,GAAA;IAAc,GAAA;IAAc,IAAA;EAAA;EAOjC,QAAA,CAAA;EAiCT,MAAA,CAAA,GAAU,MAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;iBAoCI,WAAA,CAAY,OAAA,EAAS,YAAA,YAAwB,UAAA"}
|
package/dist/error.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createError, t as EvlogError } from "./error-
|
|
1
|
+
import { n as createError, t as EvlogError } from "./error-D1FZI2Kd.mjs";
|
|
2
2
|
export { EvlogError, createError, createError as createEvlogError };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Z as RouteConfig } from "./audit-mUutdf6A.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/shared/routes.d.ts
|
|
4
4
|
declare function shouldLog(path: string, include?: string[], exclude?: string[]): boolean;
|
|
@@ -36,4 +36,4 @@ declare function getServiceForPath(path: string, routes?: Record<string, RouteCo
|
|
|
36
36
|
declare function extractErrorStatus(error: unknown): number;
|
|
37
37
|
//#endregion
|
|
38
38
|
export { getServiceForPath as n, shouldLog as r, extractErrorStatus as t };
|
|
39
|
-
//# sourceMappingURL=errors-
|
|
39
|
+
//# sourceMappingURL=errors-NIXCyk6I.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-
|
|
1
|
+
{"version":3,"file":"errors-NIXCyk6I.d.mts","names":[],"sources":["../src/shared/routes.ts","../src/shared/errors.ts"],"mappings":";;;iBAGgB,SAAA,CAAU,IAAA,UAAc,OAAA,aAAoB,OAAA;;AAA5D;;;;;;;;;AAsCA;;;;;;;;;;;iBAAgB,iBAAA,CAAkB,IAAA,UAAc,MAAA,GAAS,MAAA,SAAe,WAAA;;;;;;AAtCxE;;;;iBCIgB,kBAAA,CAAmB,KAAA"}
|
package/dist/express/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as BaseEvlogOptions } from "../middleware-
|
|
1
|
+
import { Y as RequestLogger } from "../audit-mUutdf6A.mjs";
|
|
2
|
+
import { t as BaseEvlogOptions } from "../middleware-BYf26Lfu.mjs";
|
|
3
3
|
import { RequestHandler } from "express";
|
|
4
4
|
|
|
5
5
|
//#region src/express/index.d.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/express/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/express/index.ts"],"mappings":";;;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,mBAAA,GAAsB,gBAAA;AAAA;EAAA,UAKtB,OAAA;IACR,GAAA,EAAK,aAAA;EAAA;AAAA;;;;;;;;;AANT;;;;;AAEoB;;;;;iBA0BJ,KAAA,CAAM,OAAA,GAAS,mBAAA,GAA2B,cAAA"}
|