theokit 0.4.0-beta.0 → 0.5.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/dist/{actions-virtual-module-HWNTIEPI.js → actions-virtual-module-IY46EEEX.js} +2 -2
- package/dist/{actions-virtual-module-SEIPACG5.js → actions-virtual-module-XNHDNCZ6.js} +2 -2
- package/dist/add-2ZFFGGE4.js +0 -0
- package/dist/{app-typed-client-ITIYTBXO.js → app-typed-client-OUJO3V5J.js} +10 -5
- package/dist/{app-typed-client-62FYBLVJ.js.map → app-typed-client-OUJO3V5J.js.map} +1 -1
- package/dist/{app-typed-client-62FYBLVJ.js → app-typed-client-YOMWSA3F.js} +11 -6
- package/dist/{app-typed-client-ITIYTBXO.js.map → app-typed-client-YOMWSA3F.js.map} +1 -1
- package/dist/audit-log-BQWM5YLG.d.ts +60 -0
- package/dist/{aws-lambda-XYCGZH3I.js → aws-lambda-GKSTX6HD.js} +3 -3
- package/dist/body-parser-web-MUWBKZ3F.js +70 -0
- package/dist/body-parser-web-MUWBKZ3F.js.map +1 -0
- package/dist/broadcast-QOQGUNNK.js +0 -0
- package/dist/{build-HIGHJQQV.js → build-D4J7XECU.js} +31 -22
- package/dist/build-D4J7XECU.js.map +1 -0
- package/dist/build-request-body-preview-II2235E6.js +0 -0
- package/dist/{bun-K73TQEWC.js → bun-ISHSNFIO.js} +3 -3
- package/dist/{check-PZR67OY5.js → check-NXYPLM6M.js} +2 -2
- package/dist/{chunk-WZ7CPVQB.js → chunk-27LWMYNK.js} +28 -24
- package/dist/chunk-27LWMYNK.js.map +1 -0
- package/dist/{chunk-BIGBFZSU.js → chunk-2F4FROEQ.js} +1689 -1521
- package/dist/chunk-2F4FROEQ.js.map +1 -0
- package/dist/chunk-4HBI7DHP.js +20 -0
- package/dist/chunk-4HBI7DHP.js.map +1 -0
- package/dist/{chunk-X4JAX2U3.js → chunk-4S2UCILN.js} +180 -125
- package/dist/chunk-4S2UCILN.js.map +1 -0
- package/dist/{chunk-C52GSJPF.js → chunk-4S6YHNG2.js} +11 -8
- package/dist/chunk-4S6YHNG2.js.map +1 -0
- package/dist/chunk-5ODOE6EF.js +0 -0
- package/dist/{chunk-KJVEJILQ.js → chunk-5PU65T5W.js} +9 -3
- package/dist/chunk-5PU65T5W.js.map +1 -0
- package/dist/chunk-5QW7IQQU.js +36 -0
- package/dist/chunk-5QW7IQQU.js.map +1 -0
- package/dist/chunk-5Z2727GV.js +1324 -0
- package/dist/chunk-5Z2727GV.js.map +1 -0
- package/dist/{chunk-YLBSSEHX.js → chunk-6NEXVBPY.js} +5 -15
- package/dist/chunk-6NEXVBPY.js.map +1 -0
- package/dist/chunk-7MQOHNHE.js +36 -0
- package/dist/chunk-7MQOHNHE.js.map +1 -0
- package/dist/{chunk-TPCT3MXV.js → chunk-ABVITXFH.js} +405 -272
- package/dist/chunk-ABVITXFH.js.map +1 -0
- package/dist/chunk-ASDXVRJD.js +185 -0
- package/dist/chunk-ASDXVRJD.js.map +1 -0
- package/dist/chunk-B3L3TJVF.js +406 -0
- package/dist/chunk-B3L3TJVF.js.map +1 -0
- package/dist/{chunk-PB4GR7EP.js → chunk-C3ZZ56YZ.js} +1 -18
- package/dist/chunk-C3ZZ56YZ.js.map +1 -0
- package/dist/{chunk-O7335ZGH.js → chunk-CG563V5M.js} +5 -3
- package/dist/chunk-CG563V5M.js.map +1 -0
- package/dist/{chunk-5OFPQK6N.js → chunk-COXLEZCN.js} +2 -1
- package/dist/chunk-COXLEZCN.js.map +1 -0
- package/dist/{chunk-O4BLVPML.js → chunk-DNMSV3R3.js} +22 -28
- package/dist/chunk-DNMSV3R3.js.map +1 -0
- package/dist/chunk-E3JH6YUM.js +1 -0
- package/dist/chunk-ESC54TAK.js +220 -0
- package/dist/chunk-ESC54TAK.js.map +1 -0
- package/dist/chunk-FI7MPTJW.js +77 -0
- package/dist/chunk-FI7MPTJW.js.map +1 -0
- package/dist/chunk-H4J2LECY.js +201 -0
- package/dist/chunk-H4J2LECY.js.map +1 -0
- package/dist/chunk-IAJ2JVEH.js +256 -0
- package/dist/chunk-IAJ2JVEH.js.map +1 -0
- package/dist/{chunk-F3TG5FJV.js → chunk-IEZCAT2I.js} +7 -1
- package/dist/{chunk-F3TG5FJV.js.map → chunk-IEZCAT2I.js.map} +1 -1
- package/dist/chunk-JHEAWR3L.js +1 -0
- package/dist/chunk-JQSKBMXP.js +17 -0
- package/dist/chunk-JQSKBMXP.js.map +1 -0
- package/dist/{chunk-4QTKSLTO.js → chunk-K4M64WD6.js} +9 -5
- package/dist/{chunk-4QTKSLTO.js.map → chunk-K4M64WD6.js.map} +1 -1
- package/dist/chunk-KI7OWQUX.js +293 -0
- package/dist/chunk-KI7OWQUX.js.map +1 -0
- package/dist/chunk-KT3MWNZG.js +0 -0
- package/dist/{chunk-ZJW5FFYJ.js → chunk-LC5PYNJP.js} +2 -2
- package/dist/{chunk-JAAHOGKI.js → chunk-M2EY7KDR.js} +1223 -1124
- package/dist/chunk-M2EY7KDR.js.map +1 -0
- package/dist/{chunk-2VQKDRVF.js → chunk-MR7OLIC6.js} +3 -3
- package/dist/chunk-NM4WF3XD.js +63 -0
- package/dist/chunk-NM4WF3XD.js.map +1 -0
- package/dist/chunk-NPMCKOX4.js +1 -0
- package/dist/{chunk-VRHXOKRP.js → chunk-NZXH2LQQ.js} +86 -83
- package/dist/chunk-NZXH2LQQ.js.map +1 -0
- package/dist/{chunk-B6RP57M3.js → chunk-OLPB36O2.js} +4 -4
- package/dist/chunk-PIVX3DYW.js +142 -0
- package/dist/chunk-PIVX3DYW.js.map +1 -0
- package/dist/{chunk-7TOMTMHT.js → chunk-R7OC6UDK.js} +2 -1
- package/dist/chunk-R7OC6UDK.js.map +1 -0
- package/dist/chunk-RESN62GB.js +269 -0
- package/dist/chunk-RESN62GB.js.map +1 -0
- package/dist/{chunk-64JI5LTO.js → chunk-RMU7EBRO.js} +2 -2
- package/dist/chunk-RMU7EBRO.js.map +1 -0
- package/dist/chunk-TQYSPYKU.js +131 -0
- package/dist/chunk-TQYSPYKU.js.map +1 -0
- package/dist/chunk-TSLSIRBR.js +107 -0
- package/dist/chunk-TSLSIRBR.js.map +1 -0
- package/dist/{chunk-XP7YXRHO.js → chunk-U6TPSW4L.js} +37 -5
- package/dist/chunk-U6TPSW4L.js.map +1 -0
- package/dist/chunk-UD3LFGDL.js +45 -0
- package/dist/chunk-UD3LFGDL.js.map +1 -0
- package/dist/chunk-UUFYP2UM.js +161 -0
- package/dist/chunk-UUFYP2UM.js.map +1 -0
- package/dist/{chunk-OXIQI2XZ.js → chunk-VBZCVFSA.js} +2 -2
- package/dist/chunk-VMEWD57H.js +137 -0
- package/dist/chunk-VMEWD57H.js.map +1 -0
- package/dist/{chunk-TRH2L3FI.js → chunk-WEGALZEU.js} +3 -3
- package/dist/{chunk-ZOXNJV2O.js → chunk-WGHJD6I7.js} +35 -138
- package/dist/chunk-WGHJD6I7.js.map +1 -0
- package/dist/chunk-XMS5VRIK.js +0 -0
- package/dist/chunk-Y4H3JNVK.js +18 -0
- package/dist/chunk-Y4H3JNVK.js.map +1 -0
- package/dist/chunk-Z5IGLBWE.js +329 -0
- package/dist/chunk-Z5IGLBWE.js.map +1 -0
- package/dist/chunk-ZEGYW52B.js +26 -0
- package/dist/chunk-ZEGYW52B.js.map +1 -0
- package/dist/chunk-ZJQ4O76G.js +87 -0
- package/dist/chunk-ZJQ4O76G.js.map +1 -0
- package/dist/cli/index.js +32 -21
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.d.ts +107 -1
- package/dist/client/index.js +152 -6
- package/dist/client/index.js.map +1 -1
- package/dist/{cloudflare-LCAOTRYZ.js → cloudflare-OJGJ7R2D.js} +3 -3
- package/dist/configure-agent-registry-6YGTJYBC.js +0 -0
- package/dist/cookies-MJKMGJ7N.js +22 -0
- package/dist/csrf-BBrEZSBW.d.ts +107 -0
- package/dist/csrf-readiness-store-CjIoub3U.d.ts +43 -0
- package/dist/define-websocket-CdK94O-D.d.ts +64 -0
- package/dist/{deno-deploy-ZN4RE5HF.js → deno-deploy-BHWKFTOW.js} +3 -3
- package/dist/{dev-266MVCVA.js → dev-MJVSRZGF.js} +11 -11
- package/dist/{dev-emit-RBSFZZNO.js → dev-emit-5VPRCHOD.js} +39 -142
- package/dist/dev-emit-5VPRCHOD.js.map +1 -0
- package/dist/{dev-emit-NO6OZJOQ.js → dev-emit-HHP2XJXE.js} +5 -5
- package/dist/devtools/entry.js +185 -131
- package/dist/devtools/entry.js.map +1 -1
- package/dist/{dispatcher-AQJGI3HU.js → dispatcher-63LBXYLE.js} +2 -2
- package/dist/{dispatcher-E6QV32BO.js → dispatcher-EJME6C6M.js} +5 -2
- package/dist/dispatcher-EJME6C6M.js.map +1 -0
- package/dist/{dist-5V77Z223.js → dist-KRW6OVD4.js} +7 -7
- package/dist/dist-KRW6OVD4.js.map +1 -0
- package/dist/docker-EZDA5FT7.js +0 -0
- package/dist/error-envelope-BsNzzAV5.d.ts +62 -0
- package/dist/{generate-DT4IIAHF.js → generate-AZ2K6Z2Z.js} +75 -2
- package/dist/generate-AZ2K6Z2Z.js.map +1 -0
- package/dist/index-DWWEdFh5.d.ts +399 -0
- package/dist/index.d.ts +161 -1391
- package/dist/index.js +20 -8
- package/dist/index.js.map +1 -1
- package/dist/{info-FJ4NXKTB.js → info-47VB62MV.js} +5 -5
- package/dist/job-backend-CgC8Xf33.d.ts +68 -0
- package/dist/{lib-NL5JXGEB.js → lib-NST3PNZX.js} +31 -31
- package/dist/lib-NST3PNZX.js.map +1 -0
- package/dist/module-loader-Cfz7dgCP.d.ts +26 -0
- package/dist/{netlify-5VQ22Z2P.js → netlify-GSNSJGMN.js} +3 -3
- package/dist/{node-3APTLGWB.js → node-6I5B6RL3.js} +3 -3
- package/dist/node-6I5B6RL3.js.map +1 -0
- package/dist/{openapi-FNVSWZOL.js → openapi-NFLSNNVQ.js} +10 -10
- package/dist/plugin-runner-BGBkzgi0.d.ts +95 -0
- package/dist/plugin-types-DNJGxr4Z.d.ts +79 -0
- package/dist/{proper-lockfile-4Y3DP3RP.js → proper-lockfile-MVKMQGFK.js} +27 -27
- package/dist/proper-lockfile-MVKMQGFK.js.map +1 -0
- package/dist/rate-limit-BdNDZ3vt.d.ts +58 -0
- package/dist/registry-QHEZ3BWB.js +25 -0
- package/dist/router-RGZFX75G.js +0 -0
- package/dist/{routes-H4SPLFHJ.js → routes-3A4XGIEJ.js} +6 -6
- package/dist/{scan-C2BOKLSY.js → scan-NQFI5S7P.js} +2 -2
- package/dist/scan-NQFI5S7P.js.map +1 -0
- package/dist/schema-D3v8VB7o.d.ts +76 -0
- package/dist/{schema-VR6YNVLQ.js → schema-KZVOV333.js} +5 -3
- package/dist/schema-KZVOV333.js.map +1 -0
- package/dist/server/agent/index.d.ts +229 -0
- package/dist/server/agent/index.js +16 -0
- package/dist/server/agent/index.js.map +1 -0
- package/dist/server/auth/index.d.ts +46 -1
- package/dist/server/auth/index.js +10 -3
- package/dist/server/cost/index.d.ts +1 -3
- package/dist/server/cost/index.js +1 -1
- package/dist/server/cron/index.js +4 -2
- package/dist/server/define/index.d.ts +281 -0
- package/dist/server/define/index.js +26 -0
- package/dist/server/define/index.js.map +1 -0
- package/dist/server/http/index.d.ts +10 -0
- package/dist/server/http/index.js +74 -0
- package/dist/server/http/index.js.map +1 -0
- package/dist/server/index.d.ts +151 -1677
- package/dist/server/index.js +558 -1102
- package/dist/server/index.js.map +1 -1
- package/dist/server/jobs/index.d.ts +348 -2
- package/dist/server/jobs/index.js +5 -3
- package/dist/server/observability/index.d.ts +324 -0
- package/dist/server/observability/index.js +48 -0
- package/dist/server/observability/index.js.map +1 -0
- package/dist/server/plugins/index.d.ts +17 -0
- package/dist/server/plugins/index.js +17 -0
- package/dist/server/plugins/index.js.map +1 -0
- package/dist/server/rate-limit/index.d.ts +105 -0
- package/dist/server/rate-limit/index.js +25 -0
- package/dist/server/rate-limit/index.js.map +1 -0
- package/dist/server/realtime/index.d.ts +15 -0
- package/dist/server/realtime/index.js +8 -0
- package/dist/server/realtime/index.js.map +1 -0
- package/dist/server/scan/index.d.ts +106 -0
- package/dist/server/scan/index.js +43 -0
- package/dist/server/scan/index.js.map +1 -0
- package/dist/server/security/index.d.ts +193 -0
- package/dist/server/security/index.js +50 -0
- package/dist/server/security/index.js.map +1 -0
- package/dist/server/storage/index.d.ts +22 -0
- package/dist/server/storage/index.js +14 -0
- package/dist/server/storage/index.js.map +1 -0
- package/dist/server/webhook/index.d.ts +148 -0
- package/dist/server/webhook/index.js +19 -0
- package/dist/server/webhook/index.js.map +1 -0
- package/dist/server-error-to-envelope-NO4CCAFQ.js +8 -0
- package/dist/server-error-to-envelope-NO4CCAFQ.js.map +1 -0
- package/dist/server-error-to-envelope-UJK6OWDJ.js +134 -0
- package/dist/server-error-to-envelope-UJK6OWDJ.js.map +1 -0
- package/dist/server-routes-hmr-GZJGPWMS.js +0 -0
- package/dist/services-json-Z2QNGVPW.js +142 -0
- package/dist/services-json-Z2QNGVPW.js.map +1 -0
- package/dist/{services-typed-client-XWYYBWGW.js → services-typed-client-KK6RHRDG.js} +2 -2
- package/dist/{services-typed-client-ZX5JUHH3.js → services-typed-client-T7M5VPBP.js} +2 -2
- package/dist/{sqlite-vec-ARPNUBWT.js → sqlite-vec-54KB4RD3.js} +2 -2
- package/dist/sqlite-vec-54KB4RD3.js.map +1 -0
- package/dist/{start-HX3QUSOS.js → start-CGSZPBAG.js} +23 -23
- package/dist/start-CGSZPBAG.js.map +1 -0
- package/dist/{static-TZBVBDTB.js → static-QI5NQT2X.js} +6 -6
- package/dist/storage-manager-C4jsO0Tp.d.ts +89 -0
- package/dist/storage-manager-D5KBXXKB.js +0 -0
- package/dist/{storage-types-DtIVejC1.d.ts → storage-types-DsDTCPbp.d.ts} +1 -1
- package/dist/{theo-cloud-3K4DGB3S.js → theo-cloud-RSQCBNXL.js} +4 -4
- package/dist/theo-cloud-RSQCBNXL.js.map +1 -0
- package/dist/upgrade-readiness-GUJBCJIS.js +0 -0
- package/dist/{vercel-MWW24ABC.js → vercel-TKPZK62A.js} +3 -3
- package/dist/vite-plugin/index.d.ts +3 -1
- package/dist/vite-plugin/index.js +20 -8
- package/dist/{vite-plugin-IK3NOWXS.js → vite-plugin-CR4JDFUQ.js} +9 -9
- package/dist/vite-plugin-CR4JDFUQ.js.map +1 -0
- package/package.json +61 -9
- package/LICENSE +0 -201
- package/dist/build-HIGHJQQV.js.map +0 -1
- package/dist/chunk-5OFPQK6N.js.map +0 -1
- package/dist/chunk-64JI5LTO.js.map +0 -1
- package/dist/chunk-7TOMTMHT.js.map +0 -1
- package/dist/chunk-BIGBFZSU.js.map +0 -1
- package/dist/chunk-C52GSJPF.js.map +0 -1
- package/dist/chunk-CZM6WWWS.js +0 -2450
- package/dist/chunk-CZM6WWWS.js.map +0 -1
- package/dist/chunk-JAAHOGKI.js.map +0 -1
- package/dist/chunk-KJVEJILQ.js.map +0 -1
- package/dist/chunk-O4BLVPML.js.map +0 -1
- package/dist/chunk-O7335ZGH.js.map +0 -1
- package/dist/chunk-PB4GR7EP.js.map +0 -1
- package/dist/chunk-TPCT3MXV.js.map +0 -1
- package/dist/chunk-VRHXOKRP.js.map +0 -1
- package/dist/chunk-WZ7CPVQB.js.map +0 -1
- package/dist/chunk-X4JAX2U3.js.map +0 -1
- package/dist/chunk-XP7YXRHO.js.map +0 -1
- package/dist/chunk-YLBSSEHX.js.map +0 -1
- package/dist/chunk-ZOXNJV2O.js.map +0 -1
- package/dist/dev-emit-RBSFZZNO.js.map +0 -1
- package/dist/dispatcher-E6QV32BO.js.map +0 -1
- package/dist/dist-5V77Z223.js.map +0 -1
- package/dist/generate-DT4IIAHF.js.map +0 -1
- package/dist/index-li83Swxa.d.ts +0 -506
- package/dist/lib-NL5JXGEB.js.map +0 -1
- package/dist/proper-lockfile-4Y3DP3RP.js.map +0 -1
- package/dist/registry-4MZ26TZD.js +0 -25
- package/dist/schema-CjVly9c_.d.ts +0 -274
- package/dist/sqlite-vec-ARPNUBWT.js.map +0 -1
- package/dist/start-HX3QUSOS.js.map +0 -1
- package/dist/theo-cloud-3K4DGB3S.js.map +0 -1
- /package/dist/{actions-virtual-module-HWNTIEPI.js.map → actions-virtual-module-IY46EEEX.js.map} +0 -0
- /package/dist/{actions-virtual-module-SEIPACG5.js.map → actions-virtual-module-XNHDNCZ6.js.map} +0 -0
- /package/dist/{aws-lambda-XYCGZH3I.js.map → aws-lambda-GKSTX6HD.js.map} +0 -0
- /package/dist/{bun-K73TQEWC.js.map → bun-ISHSNFIO.js.map} +0 -0
- /package/dist/{check-PZR67OY5.js.map → check-NXYPLM6M.js.map} +0 -0
- /package/dist/{dispatcher-AQJGI3HU.js.map → chunk-E3JH6YUM.js.map} +0 -0
- /package/dist/{node-3APTLGWB.js.map → chunk-JHEAWR3L.js.map} +0 -0
- /package/dist/{chunk-ZJW5FFYJ.js.map → chunk-LC5PYNJP.js.map} +0 -0
- /package/dist/{chunk-2VQKDRVF.js.map → chunk-MR7OLIC6.js.map} +0 -0
- /package/dist/{scan-C2BOKLSY.js.map → chunk-NPMCKOX4.js.map} +0 -0
- /package/dist/{chunk-B6RP57M3.js.map → chunk-OLPB36O2.js.map} +0 -0
- /package/dist/{chunk-OXIQI2XZ.js.map → chunk-VBZCVFSA.js.map} +0 -0
- /package/dist/{chunk-TRH2L3FI.js.map → chunk-WEGALZEU.js.map} +0 -0
- /package/dist/{cloudflare-LCAOTRYZ.js.map → cloudflare-OJGJ7R2D.js.map} +0 -0
- /package/dist/{schema-VR6YNVLQ.js.map → cookies-MJKMGJ7N.js.map} +0 -0
- /package/dist/{deno-deploy-ZN4RE5HF.js.map → deno-deploy-BHWKFTOW.js.map} +0 -0
- /package/dist/{dev-266MVCVA.js.map → dev-MJVSRZGF.js.map} +0 -0
- /package/dist/{dev-emit-NO6OZJOQ.js.map → dev-emit-HHP2XJXE.js.map} +0 -0
- /package/dist/{vite-plugin-IK3NOWXS.js.map → dispatcher-63LBXYLE.js.map} +0 -0
- /package/dist/{info-FJ4NXKTB.js.map → info-47VB62MV.js.map} +0 -0
- /package/dist/{netlify-5VQ22Z2P.js.map → netlify-GSNSJGMN.js.map} +0 -0
- /package/dist/{openapi-FNVSWZOL.js.map → openapi-NFLSNNVQ.js.map} +0 -0
- /package/dist/{registry-4MZ26TZD.js.map → registry-QHEZ3BWB.js.map} +0 -0
- /package/dist/{routes-H4SPLFHJ.js.map → routes-3A4XGIEJ.js.map} +0 -0
- /package/dist/{services-typed-client-XWYYBWGW.js.map → services-typed-client-KK6RHRDG.js.map} +0 -0
- /package/dist/{services-typed-client-ZX5JUHH3.js.map → services-typed-client-T7M5VPBP.js.map} +0 -0
- /package/dist/{static-TZBVBDTB.js.map → static-QI5NQT2X.js.map} +0 -0
- /package/dist/{vercel-MWW24ABC.js.map → vercel-TKPZK62A.js.map} +0 -0
package/dist/docker-EZDA5FT7.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error envelope — canonical cross-layer contract for theokit framework, SDK,
|
|
3
|
+
* and UI per plan g5-error-envelope-cross-layer v1.0 § Phase 1 / T1.1.
|
|
4
|
+
*
|
|
5
|
+
* Blueprint G5 (SHIPPABLE_WITH_CAVEATS 89/100) — Form 4 Hybrid: shared CODE
|
|
6
|
+
* enum + per-domain extensions + 2-layer SDK boundary translation.
|
|
7
|
+
*
|
|
8
|
+
* 3/3 references convergence: code + message + cause base (trpc TRPCError
|
|
9
|
+
* + hono HTTPException + encore Error). Wasp confirms ecosystem gap.
|
|
10
|
+
*
|
|
11
|
+
* Reference anchors (verified file:line):
|
|
12
|
+
* - referencia: trpc/packages/server/src/unstable-core-do-not-import/error/TRPCError.ts:65-87
|
|
13
|
+
* - referencia: trpc/packages/server/src/unstable-core-do-not-import/rpc/codes.ts:11-44,76-81
|
|
14
|
+
* - referencia: hono/src/http-exception.ts:46-78
|
|
15
|
+
* - referencia: encore/runtimes/go/beta/errs/error.go:38-55 (Go — D4 disclaimer applied)
|
|
16
|
+
*
|
|
17
|
+
* Per blueprint ADR D2: retryable + hint are extension slots, NOT base fields
|
|
18
|
+
* (3/3 references derive retryability from code identity; no reference ships
|
|
19
|
+
* a `retryable: boolean` on envelope; `hint` is novel).
|
|
20
|
+
*
|
|
21
|
+
* Per blueprint ADR D5: server-only `meta` filtered at serializer boundary
|
|
22
|
+
* (encore `json:"-"` analog).
|
|
23
|
+
*
|
|
24
|
+
* Lives in `core/contracts/` per architecture.md v3 — canonical home for
|
|
25
|
+
* shared client↔server types. Zero intra-monorepo deps; zero runtime deps
|
|
26
|
+
* (trpc + hono ship envelope with zero runtime deps per blueprint Q5).
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Canonical TheoKit error code union. HTTP-status flavor + SDK/agent-domain
|
|
30
|
+
* additions per blueprint Recommendations § concrete shape.
|
|
31
|
+
*
|
|
32
|
+
* String-literal union mirrors trpc's TRPC_ERROR_CODE_KEY pattern — enables
|
|
33
|
+
* exhaustive `switch (env.code)` narrowing in consumer code (UI display
|
|
34
|
+
* dispatch, retry-policy gates, telemetry classification).
|
|
35
|
+
*/
|
|
36
|
+
type TheoErrorCode = 'BAD_REQUEST' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'NOT_FOUND' | 'METHOD_NOT_ALLOWED' | 'CONFLICT' | 'PRECONDITION_FAILED' | 'PAYLOAD_TOO_LARGE' | 'UNSUPPORTED_MEDIA_TYPE' | 'UNPROCESSABLE_ENTITY' | 'TOO_MANY_REQUESTS' | 'INTERNAL_SERVER_ERROR' | 'NOT_IMPLEMENTED' | 'BAD_GATEWAY' | 'SERVICE_UNAVAILABLE' | 'GATEWAY_TIMEOUT' | 'AGENT_RUN_ERROR' | 'PROVIDER_KEY_MISSING' | 'BUDGET_EXCEEDED' | 'RATE_LIMITED' | 'CREDENTIAL_POOL_EXHAUSTED';
|
|
37
|
+
/**
|
|
38
|
+
* Base envelope shape — `{ code, message, cause?, meta?, ext? }`.
|
|
39
|
+
*
|
|
40
|
+
* `cause` follows TC39 proposal-error-cause (universal pattern, 3/3 references).
|
|
41
|
+
* `meta` is server-only metadata filtered at serializer boundary per ADR D5
|
|
42
|
+
* (`stack` is auto-stripped in non-dev builds — see T1.2 `TheoError.toJSON()`).
|
|
43
|
+
* `ext` carries opt-in per-domain extensions (`ValidationFieldsExt`,
|
|
44
|
+
* `RetryableExt`, `HintExt`, or arbitrary user-defined types via formatter hook).
|
|
45
|
+
*/
|
|
46
|
+
interface TheoErrorEnvelope<TExt = unknown> {
|
|
47
|
+
readonly code: TheoErrorCode;
|
|
48
|
+
readonly message: string;
|
|
49
|
+
readonly cause?: unknown;
|
|
50
|
+
readonly meta?: Record<string, unknown>;
|
|
51
|
+
readonly ext?: TExt;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* `ValidationFieldsExt` — validation-failure extension carrying the dot-notation
|
|
55
|
+
* field map identical to G3 `ActionInputError.fields`. Empty-string key for
|
|
56
|
+
* root-level errors (mirrors G3 EC-7). Multiple messages per key are preserved.
|
|
57
|
+
*/
|
|
58
|
+
interface ValidationFieldsExt {
|
|
59
|
+
readonly fields: Record<string, string[]>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type { TheoErrorEnvelope as T, ValidationFieldsExt as V, TheoErrorCode as a };
|
|
@@ -5,7 +5,7 @@ import "./chunk-KT3MWNZG.js";
|
|
|
5
5
|
// src/cli/commands/generate.ts
|
|
6
6
|
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
7
7
|
import { resolve, dirname } from "path";
|
|
8
|
-
var VALID_TYPES = ["route", "action", "page", "ws"];
|
|
8
|
+
var VALID_TYPES = ["route", "action", "page", "ws", "controller", "agent", "toolbox"];
|
|
9
9
|
function toKebabCase(name) {
|
|
10
10
|
return /^[a-z][a-z0-9/-]*$/.test(name);
|
|
11
11
|
}
|
|
@@ -48,6 +48,23 @@ function generateRouteTemplate(name) {
|
|
|
48
48
|
``
|
|
49
49
|
].join("\n");
|
|
50
50
|
}
|
|
51
|
+
function generateControllerTemplate(name) {
|
|
52
|
+
const className = toPascalCase(name) + "Controller";
|
|
53
|
+
const baseName = name.split("/").pop() ?? name;
|
|
54
|
+
return [
|
|
55
|
+
`// AUTO-GENERATED by \`theokit generate controller ${name}\``,
|
|
56
|
+
`import { Controller, Get } from '@theokit/http'`,
|
|
57
|
+
``,
|
|
58
|
+
`@Controller('${baseName}')`,
|
|
59
|
+
`export class ${className} {`,
|
|
60
|
+
` @Get()`,
|
|
61
|
+
` findAll(): string {`,
|
|
62
|
+
` return 'This action returns all ${baseName}'`,
|
|
63
|
+
` }`,
|
|
64
|
+
`}`,
|
|
65
|
+
``
|
|
66
|
+
].join("\n");
|
|
67
|
+
}
|
|
51
68
|
function generateActionTemplate(name) {
|
|
52
69
|
const camel = toCamelCase(name);
|
|
53
70
|
return [
|
|
@@ -63,6 +80,47 @@ function generateActionTemplate(name) {
|
|
|
63
80
|
``
|
|
64
81
|
].join("\n");
|
|
65
82
|
}
|
|
83
|
+
function generateAgentTemplate(name) {
|
|
84
|
+
const pascal = toPascalCase(name);
|
|
85
|
+
return [
|
|
86
|
+
`import 'reflect-metadata'`,
|
|
87
|
+
`import { Agent, MainLoop } from '@theokit/agents'`,
|
|
88
|
+
`import { UseGuards } from '@theokit/http'`,
|
|
89
|
+
``,
|
|
90
|
+
`@Agent({`,
|
|
91
|
+
` name: '${name}',`,
|
|
92
|
+
` route: '/api/agents/${name}',`,
|
|
93
|
+
` model: 'openai/gpt-4o-mini',`,
|
|
94
|
+
` systemPrompt: 'You are a helpful ${name} assistant.',`,
|
|
95
|
+
`})`,
|
|
96
|
+
`export class ${pascal}Agent {`,
|
|
97
|
+
` @MainLoop({ strategy: 'react', maxIterations: 5 })`,
|
|
98
|
+
` async run() {}`,
|
|
99
|
+
`}`,
|
|
100
|
+
``
|
|
101
|
+
].join("\n");
|
|
102
|
+
}
|
|
103
|
+
function generateToolboxTemplate(name) {
|
|
104
|
+
const pascal = toPascalCase(name);
|
|
105
|
+
return [
|
|
106
|
+
`import 'reflect-metadata'`,
|
|
107
|
+
`import { z } from 'zod'`,
|
|
108
|
+
`import { Toolbox, Tool } from '@theokit/agents'`,
|
|
109
|
+
``,
|
|
110
|
+
`@Toolbox({ namespace: '${name}' })`,
|
|
111
|
+
`export class ${pascal}Tools {`,
|
|
112
|
+
` @Tool({`,
|
|
113
|
+
` name: 'hello',`,
|
|
114
|
+
` description: 'Say hello',`,
|
|
115
|
+
` input: z.object({ name: z.string() }),`,
|
|
116
|
+
` })`,
|
|
117
|
+
` async hello(input: { name: string }) {`,
|
|
118
|
+
` return \`Hello, \${input.name}!\``,
|
|
119
|
+
` }`,
|
|
120
|
+
`}`,
|
|
121
|
+
``
|
|
122
|
+
].join("\n");
|
|
123
|
+
}
|
|
66
124
|
function resolveTemplate(cwd, type, name) {
|
|
67
125
|
switch (type) {
|
|
68
126
|
case "route":
|
|
@@ -82,6 +140,21 @@ function resolveTemplate(cwd, type, name) {
|
|
|
82
140
|
filePath: resolve(cwd, "server/ws", `${name}.ts`),
|
|
83
141
|
content: generateWsTemplate(name)
|
|
84
142
|
};
|
|
143
|
+
case "controller":
|
|
144
|
+
return {
|
|
145
|
+
filePath: resolve(cwd, "server/controllers", `${name}.controller.ts`),
|
|
146
|
+
content: generateControllerTemplate(name)
|
|
147
|
+
};
|
|
148
|
+
case "agent":
|
|
149
|
+
return {
|
|
150
|
+
filePath: resolve(cwd, "server/agents", `${name}.agent.ts`),
|
|
151
|
+
content: generateAgentTemplate(name)
|
|
152
|
+
};
|
|
153
|
+
case "toolbox":
|
|
154
|
+
return {
|
|
155
|
+
filePath: resolve(cwd, "server/toolboxes", `${name}.tools.ts`),
|
|
156
|
+
content: generateToolboxTemplate(name)
|
|
157
|
+
};
|
|
85
158
|
default:
|
|
86
159
|
return null;
|
|
87
160
|
}
|
|
@@ -205,4 +278,4 @@ export {
|
|
|
205
278
|
generate,
|
|
206
279
|
generateCommand
|
|
207
280
|
};
|
|
208
|
-
//# sourceMappingURL=generate-
|
|
281
|
+
//# sourceMappingURL=generate-AZ2K6Z2Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/generate.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * CLI `theo generate`. Writes scaffolded files under `cwd` + a generator\n * name from CLI args. Build-time tool. No HTTP input.\n */\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\n\nexport const VALID_TYPES = ['route', 'action', 'page', 'ws', 'controller', 'agent', 'toolbox'] as const\nexport type GeneratorType = (typeof VALID_TYPES)[number]\n\nexport interface GenerateOptions {\n cwd: string\n type: string\n name: string\n}\n\nexport type GenerateStatus =\n | 'created'\n | 'already_exists'\n | 'invalid_kind'\n | 'invalid_name'\n | 'not_a_project'\n\nexport interface GenerateResult {\n status: GenerateStatus\n filePath?: string\n kind?: GeneratorType\n name?: string\n message?: string\n}\n\nfunction toKebabCase(name: string): boolean {\n return /^[a-z][a-z0-9/-]*$/.test(name)\n}\n\n/**\n * Reserved JS identifier names that conflict with object prototype machinery\n * or would shadow built-in module shapes if used as action/route names.\n * Mirrors action-scan's RESERVED_NAMES (T1.4).\n */\nconst RESERVED_BASENAMES = new Set([\n 'index',\n 'constructor',\n '__proto__',\n 'prototype',\n 'hasOwnProperty',\n])\n\n/**\n * Validate that a name segment doesn't hit the reserved-identifier list.\n * Checks the BASENAME (last `/` segment) — nested `admin/constructor` still\n * rejected because the file `constructor.ts` would be the conflict.\n */\nfunction hasReservedSegment(name: string): boolean {\n const basename = name.includes('/') ? (name.split('/').pop() ?? name) : name\n return RESERVED_BASENAMES.has(basename)\n}\n\n/**\n * EC-4: validate that resolving `targetSubpath` under `cwd` stays inside `cwd`.\n * Returns `true` when path is safe (stays inside), `false` when it escapes via\n * `..`, absolute path, null byte, or similar traversal vector.\n */\nfunction isPathInside(cwd: string, targetSubpath: string): boolean {\n if (targetSubpath.includes('\\x00')) return false\n if (targetSubpath.startsWith('/') || targetSubpath.startsWith('\\\\')) return false\n const resolved = resolve(cwd, targetSubpath)\n const cwdResolved = resolve(cwd)\n const sep = process.platform === 'win32' ? '\\\\' : '/'\n return resolved === cwdResolved || resolved.startsWith(cwdResolved + sep)\n}\n\nfunction toPascalCase(name: string): string {\n return name\n .split(/[-/]/)\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join('')\n}\n\nfunction toCamelCase(name: string): string {\n const pascal = toPascalCase(name)\n return pascal.charAt(0).toLowerCase() + pascal.slice(1)\n}\n\nfunction generateRouteTemplate(name: string): string {\n return [\n `import { defineRoute } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n `export const GET = defineRoute({`,\n ` handler: ({ ctx }) => {`,\n ` return { message: 'TODO: implement ${name} GET' }`,\n ` },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generateControllerTemplate(name: string): string {\n const className = toPascalCase(name) + 'Controller'\n const baseName = name.split('/').pop() ?? name\n return [\n `// AUTO-GENERATED by \\`theokit generate controller ${name}\\``,\n `import { Controller, Get } from '@theokit/http'`,\n ``,\n `@Controller('${baseName}')`,\n `export class ${className} {`,\n ` @Get()`,\n ` findAll(): string {`,\n ` return 'This action returns all ${baseName}'`,\n ` }`,\n `}`,\n ``,\n ].join('\\n')\n}\n\nfunction generateActionTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { defineAction } from 'theokit/server'`,\n `import { z } from 'zod'`,\n ``,\n `export const ${camel} = defineAction({`,\n ` input: z.object({}),`,\n ` handler: ({ input, ctx }) => {`,\n ` return { message: 'TODO: implement ${name}' }`,\n ` },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\n/**\n * Co-located test template for `theokit generate action <name>` (T5.2 +\n * plan Q4 cenário 1: roundtrip serialize). Skeleton uses vitest BDD shape\n * per testing.md.\n */\nfunction generateAgentTemplate(name: string): string {\n const pascal = toPascalCase(name)\n return [\n `import 'reflect-metadata'`,\n `import { Agent, MainLoop } from '@theokit/agents'`,\n `import { UseGuards } from '@theokit/http'`,\n ``,\n `@Agent({`,\n ` name: '${name}',`,\n ` route: '/api/agents/${name}',`,\n ` model: 'openai/gpt-4o-mini',`,\n ` systemPrompt: 'You are a helpful ${name} assistant.',`,\n `})`,\n `export class ${pascal}Agent {`,\n ` @MainLoop({ strategy: 'react', maxIterations: 5 })`,\n ` async run() {}`,\n `}`,\n ``,\n ].join('\\n')\n}\n\nfunction generateToolboxTemplate(name: string): string {\n const pascal = toPascalCase(name)\n return [\n `import 'reflect-metadata'`,\n `import { z } from 'zod'`,\n `import { Toolbox, Tool } from '@theokit/agents'`,\n ``,\n `@Toolbox({ namespace: '${name}' })`,\n `export class ${pascal}Tools {`,\n ` @Tool({`,\n ` name: 'hello',`,\n ` description: 'Say hello',`,\n ` input: z.object({ name: z.string() }),`,\n ` })`,\n ` async hello(input: { name: string }) {`,\n ` return \\`Hello, \\${input.name}!\\``,\n ` }`,\n `}`,\n ``,\n ].join('\\n')\n}\n\nfunction resolveTemplate(\n cwd: string,\n type: GeneratorType,\n name: string,\n): { filePath: string; content: string } | null {\n switch (type) {\n case 'route':\n return {\n filePath: resolve(cwd, 'server/routes', `${name}.ts`),\n content: generateRouteTemplate(name),\n }\n case 'action':\n return {\n filePath: resolve(cwd, 'server/actions', `${name}.ts`),\n content: generateActionTemplate(name),\n }\n case 'page':\n return { filePath: resolve(cwd, `app/${name}/page.tsx`), content: generatePageTemplate(name) }\n case 'ws':\n return {\n filePath: resolve(cwd, 'server/ws', `${name}.ts`),\n content: generateWsTemplate(name),\n }\n case 'controller':\n return {\n filePath: resolve(cwd, 'server/controllers', `${name}.controller.ts`),\n content: generateControllerTemplate(name),\n }\n case 'agent':\n return {\n filePath: resolve(cwd, 'server/agents', `${name}.agent.ts`),\n content: generateAgentTemplate(name),\n }\n case 'toolbox':\n return {\n filePath: resolve(cwd, 'server/toolboxes', `${name}.tools.ts`),\n content: generateToolboxTemplate(name),\n }\n default:\n return null\n }\n}\n\nfunction generateActionTestTemplate(name: string): string {\n const camel = toCamelCase(name)\n return [\n `import { describe, it, expect } from 'vitest'`,\n ``,\n `import { ${camel} } from './${name.split('/').pop()}.js'`,\n ``,\n `describe('${name} action', () => {`,\n ` it('should accept a valid input shape', () => {`,\n ` expect(${camel}.input).toBeDefined()`,\n ` expect(typeof ${camel}.handler).toBe('function')`,\n ` })`,\n ``,\n ` it('should reject invalid input via zod schema', () => {`,\n ` const parsed = ${camel}.input.safeParse({ __invalid: true })`,\n ` // Empty object schema accepts {}; tighten this assertion when adding fields.`,\n ` expect(parsed.success).toBe(true)`,\n ` })`,\n `})`,\n ``,\n ].join('\\n')\n}\n\nfunction generatePageTemplate(name: string): string {\n const pascal = toPascalCase(name)\n return [`export default function ${pascal}Page() {`, ` return <h1>${pascal}</h1>`, `}`, ``].join(\n '\\n',\n )\n}\n\nfunction generateWsTemplate(_name: string): string {\n return [\n `import { defineWebSocket } from 'theokit/server'`,\n ``,\n `export default defineWebSocket({`,\n ` onMessage(ws, data) {`,\n ` ws.send(\\`echo: \\${data}\\`)`,\n ` },`,\n `})`,\n ``,\n ].join('\\n')\n}\n\n/**\n * Programmatic generate. Returns a structured result instead of throwing —\n * Studio (`theokit_generate` tool) consumes this directly. The CLI wrapper\n * below maps the structured result to console output + exit code semantics.\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function generate(opts: GenerateOptions): Promise<GenerateResult> {\n const { cwd, type, name } = opts\n\n if (!existsSync(resolve(cwd, 'theo.config.ts')) && !existsSync(resolve(cwd, 'theo.config.js'))) {\n return {\n status: 'not_a_project',\n message: 'Not a Theo project. cwd has no theo.config.ts or theo.config.js',\n }\n }\n\n if (!VALID_TYPES.includes(type as GeneratorType)) {\n return {\n status: 'invalid_kind',\n message: `Invalid generator type \"${type}\". Available: ${VALID_TYPES.join(', ')}`,\n }\n }\n\n if (!name || !toKebabCase(name)) {\n return {\n status: 'invalid_name',\n message: `Invalid name \"${name}\". Use kebab-case: lowercase letters, numbers, hyphens.`,\n }\n }\n\n // EC-2-related: reject reserved JS identifier basenames (would shadow\n // built-in prototype machinery in virtual module emit or scan).\n if (hasReservedSegment(name)) {\n return {\n status: 'invalid_name',\n message: `Reserved name \"${name}\" — basename collides with built-in identifier (index/constructor/__proto__/prototype/hasOwnProperty).`,\n }\n }\n\n const resolved = resolveTemplate(cwd, type as GeneratorType, name)\n if (resolved === null) {\n return { status: 'invalid_kind', message: `Unknown type: ${type}` }\n }\n const { filePath, content } = resolved\n\n // EC-4: confirm the resolved filePath stays inside cwd. `toKebabCase`\n // already rejects most traversal vectors but a defense-in-depth check\n // against `..` slipping in via valid-looking segments is cheap.\n const relativeFromCwd = filePath.startsWith(resolve(cwd))\n ? filePath.slice(resolve(cwd).length + 1)\n : filePath\n if (!isPathInside(cwd, relativeFromCwd)) {\n return {\n status: 'invalid_name',\n message: `Path traversal denied: \"${name}\" would escape project root.`,\n }\n }\n\n if (existsSync(filePath)) {\n return { status: 'already_exists', filePath, kind: type as GeneratorType, name }\n }\n\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, content)\n\n // T5.2 + plan Q4: emit co-located test file alongside actions (only\n // for action type; routes/pages/ws keep prior single-file behavior).\n // Skip if existing test file present (preserve user-customized tests).\n if (type === 'action') {\n const testPath = filePath.replace(/\\.ts$/, '.test.ts')\n if (!existsSync(testPath)) {\n writeFileSync(testPath, generateActionTestTemplate(name))\n }\n }\n\n return { status: 'created', filePath, kind: type as GeneratorType, name }\n}\n\n/**\n * CLI entry point — preserves the original surface (throws + console.log).\n * Wraps the programmatic `generate` function.\n */\nexport async function generateCommand(type: string, name: string): Promise<void> {\n const result = await generate({ cwd: process.cwd(), type, name })\n switch (result.status) {\n case 'not_a_project':\n throw new Error('Not a Theo project. Run this from a project root with theo.config.ts')\n case 'invalid_kind':\n throw new Error(result.message ?? 'Invalid kind')\n case 'invalid_name':\n throw new Error(\n `Invalid name \"${name}\". Use kebab-case: lowercase letters, numbers, hyphens. Example: my-route`,\n )\n case 'already_exists':\n console.log(`\\n ⚠ ${result.filePath} already exists. Skipping.\\n`)\n return\n case 'created':\n console.log(`\\n ✓ Created ${type}: ${result.filePath}\\n`)\n return\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { J as JobBackend } from './job-backend-CgC8Xf33.js';
|
|
3
|
+
import { P as PluginRunner } from './plugin-runner-BGBkzgi0.js';
|
|
4
|
+
import { S as ServerRouteNode, L as LoadModule } from './module-loader-Cfz7dgCP.js';
|
|
5
|
+
import { c as CsrfMode, D as DisallowedConfig } from './csrf-BBrEZSBW.js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* T5.2 — pluggable response/request transformer.
|
|
10
|
+
*
|
|
11
|
+
* `superjson` is the default, preserving Date/Map/Set/BigInt/etc.
|
|
12
|
+
* `json` is the lightweight option (plain JSON.stringify/parse).
|
|
13
|
+
* Users can supply a custom object implementing this contract.
|
|
14
|
+
*/
|
|
15
|
+
interface TheoTransformer {
|
|
16
|
+
name: string;
|
|
17
|
+
serialize: (value: unknown) => string;
|
|
18
|
+
deserialize: (raw: string) => unknown;
|
|
19
|
+
}
|
|
20
|
+
declare const superjsonTransformer: TheoTransformer;
|
|
21
|
+
declare const jsonTransformer: TheoTransformer;
|
|
22
|
+
declare function resolveTransformer(selector: 'json' | 'superjson' | TheoTransformer): TheoTransformer;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* server/http/execute-context.ts
|
|
26
|
+
*
|
|
27
|
+
* `ExecuteRouteContext` — the parameter object passed to `executeRoute()`
|
|
28
|
+
* and `executeAction()` per ADR-0016 (T3.1 of architecture-cleanup).
|
|
29
|
+
*
|
|
30
|
+
* Replaces the 12-positional-param signature with a single named-field
|
|
31
|
+
* object, eliminating 3 of 4 eslint-disable comments on `executeRoute`.
|
|
32
|
+
*
|
|
33
|
+
* Location: lives in `server/http/` (not `core/contracts/`) because the
|
|
34
|
+
* shape references server-side types (CsrfMode, JobBackend, PluginRunner,
|
|
35
|
+
* TheoTransformer, ServerRouteNode, LoadModule, DisallowedConfig). Keeping
|
|
36
|
+
* the type here preserves the existing module direction graph — no new
|
|
37
|
+
* `core → server` edges.
|
|
38
|
+
*
|
|
39
|
+
* Consumers within server/ build this object once per request; external
|
|
40
|
+
* callers (router-runner) see the same shape via the `ExecuteRouteContext`
|
|
41
|
+
* named export.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The request-execution context. Each request builds one of these and passes
|
|
46
|
+
* it to `executeRoute(ctx)`.
|
|
47
|
+
*
|
|
48
|
+
* All fields are required EXCEPT those with optional `?` markers; defaults
|
|
49
|
+
* are applied inside `executeRoute` via destructure (e.g., `csrfMode = 'strict'`).
|
|
50
|
+
*/
|
|
51
|
+
interface ExecuteRouteContext {
|
|
52
|
+
route: ServerRouteNode;
|
|
53
|
+
method: string;
|
|
54
|
+
params: Record<string, string>;
|
|
55
|
+
req: IncomingMessage;
|
|
56
|
+
res: ServerResponse;
|
|
57
|
+
loadModule: LoadModule;
|
|
58
|
+
serverDir?: string;
|
|
59
|
+
requestId?: string;
|
|
60
|
+
pluginRunner?: PluginRunner;
|
|
61
|
+
transformer?: TheoTransformer;
|
|
62
|
+
/** Defaults to `'strict'` when omitted. */
|
|
63
|
+
csrfMode?: CsrfMode;
|
|
64
|
+
disallowed?: DisallowedConfig;
|
|
65
|
+
/** When provided, `ctx.queue` auto-injects + outbox lifecycle hooks attach. */
|
|
66
|
+
jobBackend?: JobBackend;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Canonical HTTP response helpers (T5.1 extraction).
|
|
71
|
+
*
|
|
72
|
+
* Moved out of execute.ts so request-pipeline stages (execute-stages.ts,
|
|
73
|
+
* handle-request-error.ts, etc.) can depend on these helpers without
|
|
74
|
+
* creating a cycle through execute.ts.
|
|
75
|
+
*
|
|
76
|
+
* Public surface re-exported from execute.ts for backward compat — every
|
|
77
|
+
* existing caller of `sendError` / `sendJson` continues to work via the
|
|
78
|
+
* `theokit/server` barrel.
|
|
79
|
+
*/
|
|
80
|
+
declare function sendJson(res: ServerResponse, data: unknown, status?: number, transformer?: TheoTransformer): void;
|
|
81
|
+
interface SendErrorOptions {
|
|
82
|
+
custom404Html?: string;
|
|
83
|
+
custom500Html?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Canonical error response.
|
|
87
|
+
*
|
|
88
|
+
* T6.3 (PV-17): the positional 7-param signature is preserved for backward
|
|
89
|
+
* compat. New call sites should use the options-bag form:
|
|
90
|
+
*
|
|
91
|
+
* sendError(res, { code, message, status, issues?, requestId?, options? })
|
|
92
|
+
*
|
|
93
|
+
* Both shapes resolve to the same implementation.
|
|
94
|
+
*/
|
|
95
|
+
interface SendErrorInput {
|
|
96
|
+
code: string;
|
|
97
|
+
message: string;
|
|
98
|
+
status: number;
|
|
99
|
+
issues?: unknown[];
|
|
100
|
+
requestId?: string;
|
|
101
|
+
options?: SendErrorOptions;
|
|
102
|
+
}
|
|
103
|
+
declare function sendError(res: ServerResponse, input: SendErrorInput): void;
|
|
104
|
+
declare function sendError(res: ServerResponse, code: string, message: string, status: number, issues?: unknown[], requestId?: string, options?: SendErrorOptions): void;
|
|
105
|
+
|
|
106
|
+
declare function executeRoute(ctx: ExecuteRouteContext): Promise<void>;
|
|
107
|
+
|
|
108
|
+
interface ExecuteActionOptions {
|
|
109
|
+
filePath: string;
|
|
110
|
+
exportName: string;
|
|
111
|
+
req: IncomingMessage;
|
|
112
|
+
res: ServerResponse;
|
|
113
|
+
loadModule: LoadModule;
|
|
114
|
+
serverDir?: string;
|
|
115
|
+
requestId?: string;
|
|
116
|
+
pluginRunner?: PluginRunner;
|
|
117
|
+
csrfMode?: CsrfMode;
|
|
118
|
+
disallowed?: DisallowedConfig;
|
|
119
|
+
}
|
|
120
|
+
declare function executeAction(filePath: string, exportName: string, req: IncomingMessage, res: ServerResponse, loadModule: LoadModule, serverDir?: string, requestId?: string, pluginRunner?: PluginRunner, csrfMode?: CsrfMode, disallowed?: DisallowedConfig): Promise<void>;
|
|
121
|
+
|
|
122
|
+
interface MiddlewareResult {
|
|
123
|
+
ctx: unknown;
|
|
124
|
+
aborted: boolean;
|
|
125
|
+
}
|
|
126
|
+
declare function _resetMiddlewareCacheForTests(): void;
|
|
127
|
+
declare function runMiddlewareAndContext(req: IncomingMessage, res: ServerResponse, loadModule: LoadModule, serverDir: string): Promise<MiddlewareResult>;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* T1.2 — CORS middleware.
|
|
131
|
+
*
|
|
132
|
+
* Single global middleware that runs FIRST in the request pipeline:
|
|
133
|
+
* CORS preflight → rate limit → CSRF → security headers → handler
|
|
134
|
+
*
|
|
135
|
+
* Preflight (`OPTIONS` with `Access-Control-Request-Method`) is handled
|
|
136
|
+
* by `handlePreflight`, which short-circuits the response with 204 +
|
|
137
|
+
* Access-Control-* headers.
|
|
138
|
+
*
|
|
139
|
+
* Non-preflight requests pass through; `applyHeaders` adds
|
|
140
|
+
* `Access-Control-Allow-Origin` (echoing the request's Origin),
|
|
141
|
+
* `Access-Control-Expose-Headers`, and `Access-Control-Allow-Credentials`.
|
|
142
|
+
*
|
|
143
|
+
* Per ADR D3: preflight responses are deterministic and only the matched
|
|
144
|
+
* origin is echoed back (never `'*'` when credentials are enabled —
|
|
145
|
+
* required by the CORS spec).
|
|
146
|
+
*/
|
|
147
|
+
type CorsOrigin = string | RegExp | readonly (string | RegExp)[] | ((origin: string) => boolean);
|
|
148
|
+
interface CorsConfig {
|
|
149
|
+
origins: CorsOrigin;
|
|
150
|
+
methods?: readonly ('GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD')[];
|
|
151
|
+
allowedHeaders?: readonly string[];
|
|
152
|
+
exposedHeaders?: readonly string[];
|
|
153
|
+
credentials?: boolean;
|
|
154
|
+
maxAge?: number;
|
|
155
|
+
}
|
|
156
|
+
interface CorsHandler {
|
|
157
|
+
handlePreflight(req: IncomingMessage, res: ServerResponse): boolean;
|
|
158
|
+
applyHeaders(req: IncomingMessage, res: ServerResponse): void;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Test whether `origin` is allowed by `allowed`. Pure function — no I/O.
|
|
162
|
+
*
|
|
163
|
+
* EC-8: callback variants that throw are fail-closed (deny). Without
|
|
164
|
+
* this, a transient datastore outage would silently widen CORS during
|
|
165
|
+
* the failure window.
|
|
166
|
+
*/
|
|
167
|
+
declare function matchesOrigin(origin: string, allowed: CorsOrigin): boolean;
|
|
168
|
+
declare function createCorsHandler(config: CorsConfig): CorsHandler;
|
|
169
|
+
/**
|
|
170
|
+
* T5a.2 Phase B slice 5/6 — Web-Standards CORS handler.
|
|
171
|
+
*
|
|
172
|
+
* Mirror of `createCorsHandler(config): CorsHandler` for the Web `Request`
|
|
173
|
+
* shape. Same `CorsConfig`, same `matchesOrigin` logic (pure helper
|
|
174
|
+
* already), same security guarantees (echo matched origin only — never
|
|
175
|
+
* `'*'` when credentials enabled; EC-8 fail-closed on callback throw).
|
|
176
|
+
*
|
|
177
|
+
* Signature differences vs the IncomingMessage pair:
|
|
178
|
+
* - `handlePreflightRequest(request, config): Response | null` — returns
|
|
179
|
+
* `Response` when this is a CORS preflight; `null` when not. Caller
|
|
180
|
+
* short-circuits accordingly (same control-flow semantic as boolean).
|
|
181
|
+
* - `applyCorsHeaders(request, target, config): void` — mutates a
|
|
182
|
+
* `Headers` instance in place. Caller passes the headers they're
|
|
183
|
+
* building for their Response.
|
|
184
|
+
*/
|
|
185
|
+
interface CorsWebHandler {
|
|
186
|
+
handlePreflightRequest(request: Request): Response | null;
|
|
187
|
+
applyCorsHeaders(request: Request, target: Headers): void;
|
|
188
|
+
}
|
|
189
|
+
declare function createCorsWebHandler(config: CorsConfig): CorsWebHandler;
|
|
190
|
+
|
|
191
|
+
interface CookieOptions {
|
|
192
|
+
httpOnly?: boolean;
|
|
193
|
+
secure?: boolean;
|
|
194
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
195
|
+
maxAge?: number;
|
|
196
|
+
path?: string;
|
|
197
|
+
domain?: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Parse a `Cookie` header into a Map (RFC 6265 §5.4).
|
|
201
|
+
* - Empty/missing input → empty Map.
|
|
202
|
+
* - Malformed entries (no `=`) skipped silently (defensive).
|
|
203
|
+
* - Duplicate names → last-wins.
|
|
204
|
+
* - Values URL-decoded if possible; raw on decode failure (CR-009 protection).
|
|
205
|
+
*
|
|
206
|
+
* Canonical helper (T3.2 of architecture-review-remediation-plan; PV-4 DRY).
|
|
207
|
+
* Consumed by `getCookie` here AND by `rate-limit/rate-limit-per-route.ts`.
|
|
208
|
+
*/
|
|
209
|
+
declare function parseCookieHeader(header: string | undefined): Map<string, string>;
|
|
210
|
+
declare function getCookie(req: IncomingMessage, name: string): string | undefined;
|
|
211
|
+
/**
|
|
212
|
+
* T5a.2 Phase B slice 6/6 — pure Set-Cookie serializer. Extracted from
|
|
213
|
+
* `setCookie(res, ...)` so the IncomingMessage path AND the Web Headers
|
|
214
|
+
* path can share the cookie attribute composition.
|
|
215
|
+
*
|
|
216
|
+
* Returns the canonical `Set-Cookie` header value string (no surrounding
|
|
217
|
+
* `Set-Cookie:` prefix — caller wraps via `res.setHeader('Set-Cookie', ...)`
|
|
218
|
+
* or `headers.append('Set-Cookie', ...)`).
|
|
219
|
+
*
|
|
220
|
+
* Defaults: `httpOnly: true`, `secure: NODE_ENV === 'production'`,
|
|
221
|
+
* `sameSite: 'lax'`, `path: '/'`.
|
|
222
|
+
*/
|
|
223
|
+
declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
|
|
224
|
+
declare function setCookie(res: ServerResponse, name: string, value: string, options?: CookieOptions): void;
|
|
225
|
+
declare function deleteCookie(res: ServerResponse, name: string, options?: {
|
|
226
|
+
path?: string;
|
|
227
|
+
}): void;
|
|
228
|
+
/**
|
|
229
|
+
* T5a.2 Phase B slice 6/6 — Web-Standards cookie getter.
|
|
230
|
+
*
|
|
231
|
+
* Mirror of `getCookie(req: IncomingMessage, name)` for the Web `Request`
|
|
232
|
+
* shape. Consumes `request.headers.get('cookie')` (native `Headers` API)
|
|
233
|
+
* instead of `req.headers.cookie`. Same parse logic + same malformed
|
|
234
|
+
* percent-encoding sanity (returns undefined when raw value contains a
|
|
235
|
+
* lone `%` that didn't decode, preserving the IncomingMessage path's
|
|
236
|
+
* "treat as unreadable" CR-009 semantics).
|
|
237
|
+
*/
|
|
238
|
+
declare function getCookieFromRequest(request: Request, name: string): string | undefined;
|
|
239
|
+
/**
|
|
240
|
+
* T5a.2 Phase B slice 6/6 — Web-Standards cookie setter.
|
|
241
|
+
*
|
|
242
|
+
* Mirror of `setCookie(res, name, value, options)` for the Web `Headers`
|
|
243
|
+
* shape. Appends a `Set-Cookie` entry to the caller's `Headers` instance
|
|
244
|
+
* via `headers.append('Set-Cookie', ...)`. Multiple appends produce
|
|
245
|
+
* multiple `Set-Cookie` headers per the Web spec; `headers.getSetCookie()`
|
|
246
|
+
* retrieves them as an array (the one multi-value header the Web API
|
|
247
|
+
* exposes natively).
|
|
248
|
+
*
|
|
249
|
+
* Uses the shared `serializeCookie` pure helper — same defaults and
|
|
250
|
+
* attribute composition as the IncomingMessage path.
|
|
251
|
+
*/
|
|
252
|
+
declare function appendCookieToHeaders(target: Headers, name: string, value: string, options?: CookieOptions): void;
|
|
253
|
+
/**
|
|
254
|
+
* T5a.2 Phase B slice 6/6 — Web-Standards cookie deleter.
|
|
255
|
+
*
|
|
256
|
+
* Mirror of `deleteCookie(res, name, options)` — emits a Set-Cookie with
|
|
257
|
+
* `Max-Age=0` so the browser drops the cookie immediately.
|
|
258
|
+
*/
|
|
259
|
+
declare function appendDeleteCookieToHeaders(target: Headers, name: string, options?: {
|
|
260
|
+
path?: string;
|
|
261
|
+
}): void;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* T1.4 — Server-side batch handler.
|
|
265
|
+
*
|
|
266
|
+
* Receives `{ requests: [...] }` POSTed to `/api/__theo_batch__` and returns
|
|
267
|
+
* `{ results: [...] }` with per-item error isolation. EC-2: items cannot
|
|
268
|
+
* override auth/forwarded headers (would be a session-bypass vector).
|
|
269
|
+
*/
|
|
270
|
+
|
|
271
|
+
declare const STRIPPED_HEADERS: readonly ["authorization", "cookie", "x-forwarded-for", "x-forwarded-host", "x-forwarded-proto", "x-real-ip", "host"];
|
|
272
|
+
declare const BATCH_PATH = "/api/__theo_batch__";
|
|
273
|
+
declare class BatchPathConflictError extends Error {
|
|
274
|
+
constructor(path: string);
|
|
275
|
+
}
|
|
276
|
+
declare const batchRequestSchema: z.ZodObject<{
|
|
277
|
+
path: z.ZodString;
|
|
278
|
+
method: z.ZodString;
|
|
279
|
+
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
280
|
+
body: z.ZodOptional<z.ZodUnknown>;
|
|
281
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
282
|
+
}, z.core.$strip>;
|
|
283
|
+
declare const batchPayloadSchema: z.ZodObject<{
|
|
284
|
+
requests: z.ZodArray<z.ZodObject<{
|
|
285
|
+
path: z.ZodString;
|
|
286
|
+
method: z.ZodString;
|
|
287
|
+
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
288
|
+
body: z.ZodOptional<z.ZodUnknown>;
|
|
289
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
290
|
+
}, z.core.$strip>>;
|
|
291
|
+
}, z.core.$strip>;
|
|
292
|
+
type BatchRequestItem = z.infer<typeof batchRequestSchema>;
|
|
293
|
+
type BatchPayload = z.infer<typeof batchPayloadSchema>;
|
|
294
|
+
type BatchExecuteFn = (req: BatchRequestItem) => Promise<{
|
|
295
|
+
data: unknown;
|
|
296
|
+
} | {
|
|
297
|
+
error: {
|
|
298
|
+
message: string;
|
|
299
|
+
code?: string;
|
|
300
|
+
};
|
|
301
|
+
}>;
|
|
302
|
+
interface HandleBatchOptions {
|
|
303
|
+
execute: BatchExecuteFn;
|
|
304
|
+
/** Max number of items per batch. Default 32. */
|
|
305
|
+
max?: number;
|
|
306
|
+
/** Outer-request headers that override per-item headers in STRIPPED_HEADERS. */
|
|
307
|
+
outerHeaders?: Record<string, string>;
|
|
308
|
+
}
|
|
309
|
+
type BatchResultItem = {
|
|
310
|
+
data: unknown;
|
|
311
|
+
} | {
|
|
312
|
+
error: {
|
|
313
|
+
message: string;
|
|
314
|
+
code?: string;
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
interface BatchResponse {
|
|
318
|
+
results: BatchResultItem[];
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Validate + execute a batch request.
|
|
322
|
+
*
|
|
323
|
+
* CR-028 fix: previously the signature was `payload: BatchPayload`,
|
|
324
|
+
* suggesting the caller had already validated. In reality `api-middleware`
|
|
325
|
+
* passes `JSON.parse(rawBody) as BatchPayload` — an unsafe cast over raw
|
|
326
|
+
* HTTP input. We widen the input type to `unknown` so the type system
|
|
327
|
+
* forces validation, then run Zod once at this single trust boundary.
|
|
328
|
+
*/
|
|
329
|
+
declare function handleBatchRequest(payload: unknown, options: HandleBatchOptions): Promise<BatchResponse>;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* T2.4 — Custom error pages loader.
|
|
333
|
+
*
|
|
334
|
+
* Loads optional `.theo/client/404.html` and `500.html` from disk so adapters
|
|
335
|
+
* (Node, CF, Vercel, Bun, Netlify, AWS Lambda, Deno) can pass them to the
|
|
336
|
+
* shared `sendError` pipeline.
|
|
337
|
+
*
|
|
338
|
+
* EC-9: caps file size at 1MB. Files beyond the limit are skipped with a
|
|
339
|
+
* console.warn and the default JSON error path is used.
|
|
340
|
+
*/
|
|
341
|
+
declare const MAX_ERROR_HTML_BYTES = 1048576;
|
|
342
|
+
interface CustomErrorPages {
|
|
343
|
+
custom404Html?: string;
|
|
344
|
+
custom500Html?: string;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Load `.theo/client/{404,500}.html` from the given client directory.
|
|
348
|
+
* Returns object with both fields when present; missing pages remain undefined.
|
|
349
|
+
*/
|
|
350
|
+
declare function loadCustomErrorPages(clientDir: string): CustomErrorPages;
|
|
351
|
+
|
|
352
|
+
declare function serveStaticFile(req: IncomingMessage, res: ServerResponse, clientDir: string): boolean;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Phase 7 — Observability: traceId propagation (D7).
|
|
356
|
+
*
|
|
357
|
+
* Extract a stable identifier from incoming requests so a single value
|
|
358
|
+
* correlates the client request, every server log line, the response
|
|
359
|
+
* envelope, and any downstream span. Precedence:
|
|
360
|
+
*
|
|
361
|
+
* 1. `traceparent` (W3C Trace Context — `00-{32-hex}-{16-hex}-{flags}`)
|
|
362
|
+
* 2. `x-request-id` (Heroku / GCP / generic proxy header)
|
|
363
|
+
* 3. Generated UUID (fresh per request)
|
|
364
|
+
*
|
|
365
|
+
* UUIDs are accepted as trace identifiers by every major vendor that
|
|
366
|
+
* does not enforce strict 32-hex (Datadog, Honeycomb, Sentry, Logflare,
|
|
367
|
+
* Axiom, etc). We don't need ULIDs to ship this surface.
|
|
368
|
+
*/
|
|
369
|
+
declare const TRACE_HEADER = "x-trace-id";
|
|
370
|
+
declare const TRACE_PARENT_HEADER = "traceparent";
|
|
371
|
+
/**
|
|
372
|
+
* Parse a W3C Trace Context `traceparent` header value. Returns the
|
|
373
|
+
* 32-hex trace-id when valid (and not the reserved all-zeros), else
|
|
374
|
+
* `null`.
|
|
375
|
+
*/
|
|
376
|
+
declare function parseTraceparent(value: string): string | null;
|
|
377
|
+
/**
|
|
378
|
+
* Resolve the request's traceId following the precedence above.
|
|
379
|
+
*/
|
|
380
|
+
declare function extractTraceId(req: IncomingMessage): string;
|
|
381
|
+
/**
|
|
382
|
+
* T5a.2 Phase C slice 1/2 — Web-Standards-shaped traceId resolver.
|
|
383
|
+
*
|
|
384
|
+
* Mirror of `extractTraceId(req: IncomingMessage)` for the Web `Request`
|
|
385
|
+
* shape. Same precedence (`traceparent` → `x-request-id` → generated
|
|
386
|
+
* UUID). Uses `request.headers.get(name)` (native Web `Headers` API)
|
|
387
|
+
* instead of the Node indexer.
|
|
388
|
+
*
|
|
389
|
+
* **Multi-value note:** Web `Headers` collapses repeated headers into a
|
|
390
|
+
* single comma-separated string at parse. The IncomingMessage path's
|
|
391
|
+
* `pickHeader` "first non-empty value" semantic is naturally satisfied
|
|
392
|
+
* because there's no array to pick from on the Web side — `.get()`
|
|
393
|
+
* returns the comma-joined value, which for `traceparent` / `x-request-id`
|
|
394
|
+
* is treated as a single string anyway (both headers are conventionally
|
|
395
|
+
* single-valued).
|
|
396
|
+
*/
|
|
397
|
+
declare function extractTraceIdFromRequest(request: Request): string;
|
|
398
|
+
|
|
399
|
+
export { getCookie as A, BATCH_PATH as B, type CookieOptions as C, getCookieFromRequest as D, type ExecuteActionOptions as E, handleBatchRequest as F, jsonTransformer as G, type HandleBatchOptions as H, loadCustomErrorPages as I, matchesOrigin as J, parseCookieHeader as K, parseTraceparent as L, MAX_ERROR_HTML_BYTES as M, resolveTransformer as N, runMiddlewareAndContext as O, sendError as P, sendJson as Q, serializeCookie as R, STRIPPED_HEADERS as S, TRACE_HEADER as T, serveStaticFile as U, setCookie as V, superjsonTransformer as W, _resetMiddlewareCacheForTests as _, type BatchExecuteFn as a, BatchPathConflictError as b, type BatchPayload as c, type BatchRequestItem as d, type BatchResponse as e, type BatchResultItem as f, type CorsConfig as g, type CorsHandler as h, type CorsOrigin as i, type CorsWebHandler as j, type CustomErrorPages as k, type ExecuteRouteContext as l, type MiddlewareResult as m, type SendErrorInput as n, type SendErrorOptions as o, TRACE_PARENT_HEADER as p, type TheoTransformer as q, appendCookieToHeaders as r, appendDeleteCookieToHeaders as s, createCorsHandler as t, createCorsWebHandler as u, deleteCookie as v, executeAction as w, executeRoute as x, extractTraceId as y, extractTraceIdFromRequest as z };
|