theokit 0.43.7 → 0.44.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (396) hide show
  1. package/dist/{actions-virtual-module-LD3YKWIX.js → actions-virtual-module-67K4POQ2.js} +20 -20
  2. package/dist/actions-virtual-module-67K4POQ2.js.map +1 -0
  3. package/dist/{actions-virtual-module-N7GKUS3D.js → actions-virtual-module-IK2SDIZ3.js} +9 -8
  4. package/dist/actions-virtual-module-IK2SDIZ3.js.map +1 -0
  5. package/dist/adapters/web-shim.js +1 -1
  6. package/dist/adapters/web-shim.js.map +1 -1
  7. package/dist/adapters/ws-shim.js +1 -1
  8. package/dist/adapters/ws-shim.js.map +1 -1
  9. package/dist/{add-W6FNTAFS.js → add-3VLFUPF4.js} +1 -1
  10. package/dist/add-3VLFUPF4.js.map +1 -0
  11. package/dist/{agent-U35G3WNE.js → agent-OCCL5RUY.js} +5 -5
  12. package/dist/{agents-typed-client-CHMVW7MK.js → agents-typed-client-TNHCUU7Q.js} +2 -2
  13. package/dist/agents-typed-client-TNHCUU7Q.js.map +1 -0
  14. package/dist/{agents-typed-client-NJ73Z6XY.js → agents-typed-client-X56CQ6FX.js} +1 -1
  15. package/dist/agents-typed-client-X56CQ6FX.js.map +1 -0
  16. package/dist/{app-typed-client-6YZRDAPY.js → app-typed-client-4OH3JREB.js} +51 -12
  17. package/dist/app-typed-client-4OH3JREB.js.map +1 -0
  18. package/dist/{app-typed-client-V77SVU2O.js → app-typed-client-N5WUE2CP.js} +62 -24
  19. package/dist/app-typed-client-N5WUE2CP.js.map +1 -0
  20. package/dist/{aws-lambda-7GSCNLPY.js → aws-lambda-473QCOL6.js} +3 -3
  21. package/dist/{body-parser-web-MUWBKZ3F.js → body-parser-web-4Z2QTPDU.js} +2 -2
  22. package/dist/body-parser-web-4Z2QTPDU.js.map +1 -0
  23. package/dist/{body-parser-web-FV5HWCY3.js → body-parser-web-TIOTXPDW.js} +1 -1
  24. package/dist/body-parser-web-TIOTXPDW.js.map +1 -0
  25. package/dist/boot/index.js +4 -4
  26. package/dist/boot/index.js.map +1 -1
  27. package/dist/{broadcast-4SX7R5XE.js → broadcast-H64DJRBE.js} +3 -3
  28. package/dist/broadcast-H64DJRBE.js.map +1 -0
  29. package/dist/{build-BYLQZJT2.js → build-25RSFP22.js} +20 -11
  30. package/dist/build-25RSFP22.js.map +1 -0
  31. package/dist/{build-request-body-preview-EOP2Y4F3.js → build-request-body-preview-CKWWBF2M.js} +2 -2
  32. package/dist/build-request-body-preview-CKWWBF2M.js.map +1 -0
  33. package/dist/{build-request-body-preview-QMWD2IXK.js → build-request-body-preview-XPZ2GYMG.js} +1 -1
  34. package/dist/build-request-body-preview-XPZ2GYMG.js.map +1 -0
  35. package/dist/{bun-KP2KES6S.js → bun-OQUCL3XW.js} +3 -3
  36. package/dist/{check-PD2FTKMM.js → check-45NKUVSQ.js} +1 -1
  37. package/dist/check-45NKUVSQ.js.map +1 -0
  38. package/dist/{chunk-FRUEDJFX.js → chunk-226KMIGZ.js} +3 -3
  39. package/dist/{chunk-FRUEDJFX.js.map → chunk-226KMIGZ.js.map} +1 -1
  40. package/dist/{chunk-U3NTEK46.js → chunk-2ADKT37V.js} +5 -5
  41. package/dist/chunk-2ADKT37V.js.map +1 -0
  42. package/dist/{chunk-QWBXUZAX.js → chunk-37ZO643S.js} +9 -9
  43. package/dist/chunk-37ZO643S.js.map +1 -0
  44. package/dist/{chunk-ESC54TAK.js → chunk-3DGIANAN.js} +1 -1
  45. package/dist/chunk-3DGIANAN.js.map +1 -0
  46. package/dist/{chunk-GY5Q27BJ.js → chunk-47FFT43U.js} +1 -1
  47. package/dist/chunk-47FFT43U.js.map +1 -0
  48. package/dist/{chunk-JAIKGP3Q.js → chunk-47VNWTL4.js} +1 -1
  49. package/dist/chunk-47VNWTL4.js.map +1 -0
  50. package/dist/{chunk-ZJQ4O76G.js → chunk-4FWBKX6G.js} +1 -1
  51. package/dist/chunk-4FWBKX6G.js.map +1 -0
  52. package/dist/{chunk-NM4WF3XD.js → chunk-4PBJ266F.js} +1 -1
  53. package/dist/chunk-4PBJ266F.js.map +1 -0
  54. package/dist/{chunk-7MQOHNHE.js → chunk-52PDWL5S.js} +1 -1
  55. package/dist/chunk-52PDWL5S.js.map +1 -0
  56. package/dist/{chunk-JQJN6LFK.js → chunk-62EU2BVZ.js} +2 -2
  57. package/dist/chunk-62EU2BVZ.js.map +1 -0
  58. package/dist/{chunk-SJIRP73B.js → chunk-646CA6RV.js} +2 -2
  59. package/dist/chunk-646CA6RV.js.map +1 -0
  60. package/dist/{chunk-ASDXVRJD.js → chunk-6KDXP472.js} +4 -4
  61. package/dist/chunk-6KDXP472.js.map +1 -0
  62. package/dist/chunk-6LNIGF5P.js +46 -0
  63. package/dist/chunk-6LNIGF5P.js.map +1 -0
  64. package/dist/chunk-7IHWXDJJ.js +1 -0
  65. package/dist/chunk-7IHWXDJJ.js.map +1 -0
  66. package/dist/{chunk-JQSKBMXP.js → chunk-7LVM22VG.js} +1 -1
  67. package/dist/chunk-7LVM22VG.js.map +1 -0
  68. package/dist/{chunk-UVXB2ER7.js → chunk-7SABX4DJ.js} +1 -1
  69. package/dist/chunk-7SABX4DJ.js.map +1 -0
  70. package/dist/{chunk-P37RZRFV.js → chunk-A7JBF5FO.js} +1 -1
  71. package/dist/chunk-A7JBF5FO.js.map +1 -0
  72. package/dist/{chunk-X32XEJXR.js → chunk-ACKBVBUI.js} +1 -1
  73. package/dist/chunk-ACKBVBUI.js.map +1 -0
  74. package/dist/{chunk-UUFYP2UM.js → chunk-AM3QABW5.js} +3 -3
  75. package/dist/chunk-AM3QABW5.js.map +1 -0
  76. package/dist/{chunk-FH3DYBAN.js → chunk-ANS4ELRH.js} +1 -1
  77. package/dist/chunk-ANS4ELRH.js.map +1 -0
  78. package/dist/{chunk-UD3LFGDL.js → chunk-AVQU5CQF.js} +1 -1
  79. package/dist/chunk-AVQU5CQF.js.map +1 -0
  80. package/dist/{chunk-AFVTEAES.js → chunk-B7ONQ4QJ.js} +2 -2
  81. package/dist/{chunk-WSJKACWB.js → chunk-C34PMLSN.js} +1 -1
  82. package/dist/chunk-C34PMLSN.js.map +1 -0
  83. package/dist/{chunk-FEDSPOY6.js → chunk-DSOBIXXR.js} +6 -6
  84. package/dist/chunk-DSOBIXXR.js.map +1 -0
  85. package/dist/{chunk-AXVFVMLM.js → chunk-EIRQM55C.js} +12 -7
  86. package/dist/chunk-EIRQM55C.js.map +1 -0
  87. package/dist/{chunk-ZEGYW52B.js → chunk-FB2HBNIC.js} +1 -1
  88. package/dist/chunk-FB2HBNIC.js.map +1 -0
  89. package/dist/chunk-FXZZS7YW.js +605 -0
  90. package/dist/chunk-FXZZS7YW.js.map +1 -0
  91. package/dist/{chunk-5AVPWHUE.js → chunk-FZG3JYB3.js} +14 -50
  92. package/dist/chunk-FZG3JYB3.js.map +1 -0
  93. package/dist/{chunk-V3LJN2GS.js → chunk-GAPBPRPP.js} +1 -1
  94. package/dist/chunk-GAPBPRPP.js.map +1 -0
  95. package/dist/chunk-GUBN5UTT.js +1 -0
  96. package/dist/chunk-GUBN5UTT.js.map +1 -0
  97. package/dist/{chunk-GSO77FSM.js → chunk-HEK4SET7.js} +45 -47
  98. package/dist/chunk-HEK4SET7.js.map +1 -0
  99. package/dist/{chunk-SPJNVWOK.js → chunk-HRCNHWLP.js} +7 -110
  100. package/dist/chunk-HRCNHWLP.js.map +1 -0
  101. package/dist/{chunk-C3ZZ56YZ.js → chunk-JA2ZAT5Q.js} +1 -1
  102. package/dist/chunk-JA2ZAT5Q.js.map +1 -0
  103. package/dist/{chunk-KI7OWQUX.js → chunk-KBGGQK4I.js} +87 -27
  104. package/dist/chunk-KBGGQK4I.js.map +1 -0
  105. package/dist/{chunk-WFNLNIJX.js → chunk-KD5G3YXI.js} +4 -4
  106. package/dist/chunk-KD5G3YXI.js.map +1 -0
  107. package/dist/{chunk-VMEWD57H.js → chunk-KPKLIUUL.js} +1 -1
  108. package/dist/chunk-KPKLIUUL.js.map +1 -0
  109. package/dist/{chunk-IHJZPQEF.js → chunk-L4Y6RJ4E.js} +4 -4
  110. package/dist/chunk-L4Y6RJ4E.js.map +1 -0
  111. package/dist/{chunk-GUUWDMR2.js → chunk-L5Z6IY5U.js} +5 -5
  112. package/dist/chunk-L5Z6IY5U.js.map +1 -0
  113. package/dist/{chunk-L4GCEMNW.js → chunk-LNVMHQ2Z.js} +2 -2
  114. package/dist/{chunk-JBCHWRKF.js → chunk-MTEWLGVY.js} +2 -2
  115. package/dist/chunk-MTEWLGVY.js.map +1 -0
  116. package/dist/{chunk-5PU65T5W.js → chunk-MWP4YXWJ.js} +1 -1
  117. package/dist/chunk-MWP4YXWJ.js.map +1 -0
  118. package/dist/{chunk-IPC5UREF.js → chunk-NGEBYCOZ.js} +70 -46
  119. package/dist/chunk-NGEBYCOZ.js.map +1 -0
  120. package/dist/{chunk-5QW7IQQU.js → chunk-NTDN54XO.js} +1 -1
  121. package/dist/chunk-NTDN54XO.js.map +1 -0
  122. package/dist/{chunk-7BIM27LV.js → chunk-OIGJOYX6.js} +1 -1
  123. package/dist/chunk-OIGJOYX6.js.map +1 -0
  124. package/dist/{chunk-TSLSIRBR.js → chunk-OLGPYOLO.js} +2 -2
  125. package/dist/chunk-OLGPYOLO.js.map +1 -0
  126. package/dist/{chunk-NQRNDPZJ.js → chunk-OXCALO3W.js} +3 -3
  127. package/dist/{chunk-UNLG36Z5.js → chunk-Q5OT7LZG.js} +19 -499
  128. package/dist/chunk-Q5OT7LZG.js.map +1 -0
  129. package/dist/{chunk-45C3WUQ7.js → chunk-QPVXGC7O.js} +1 -1
  130. package/dist/chunk-QPVXGC7O.js.map +1 -0
  131. package/dist/{chunk-6NEXVBPY.js → chunk-RWNSW4FM.js} +1 -1
  132. package/dist/chunk-RWNSW4FM.js.map +1 -0
  133. package/dist/{chunk-E25FBYJP.js → chunk-SAFGDIPQ.js} +1 -1
  134. package/dist/chunk-SAFGDIPQ.js.map +1 -0
  135. package/dist/{chunk-RMU7EBRO.js → chunk-SEELKQUM.js} +2 -2
  136. package/dist/chunk-SEELKQUM.js.map +1 -0
  137. package/dist/{chunk-FOZIR3TG.js → chunk-SMP2T335.js} +2 -2
  138. package/dist/{chunk-D7ZH7DTG.js → chunk-SSYDEKWF.js} +1 -1
  139. package/dist/chunk-SSYDEKWF.js.map +1 -0
  140. package/dist/{chunk-2ZX4J4SX.js → chunk-SZU6BOMV.js} +114 -90
  141. package/dist/chunk-SZU6BOMV.js.map +1 -0
  142. package/dist/{chunk-M6NMS5LR.js → chunk-TDNNBLGW.js} +1 -1
  143. package/dist/chunk-TDNNBLGW.js.map +1 -0
  144. package/dist/{chunk-X2VVCJ4V.js → chunk-U267AOWS.js} +1 -1
  145. package/dist/chunk-U267AOWS.js.map +1 -0
  146. package/dist/{chunk-GW5H4KB4.js → chunk-U3H53IIN.js} +6 -6
  147. package/dist/chunk-U3H53IIN.js.map +1 -0
  148. package/dist/{chunk-OPLICDUB.js → chunk-UW2TEAGR.js} +1 -1
  149. package/dist/chunk-UW2TEAGR.js.map +1 -0
  150. package/dist/{chunk-IAJ2JVEH.js → chunk-VSLTKX5L.js} +1 -1
  151. package/dist/chunk-VSLTKX5L.js.map +1 -0
  152. package/dist/{chunk-YB5DJJ4U.js → chunk-VZTYCAO6.js} +1 -1
  153. package/dist/chunk-VZTYCAO6.js.map +1 -0
  154. package/dist/chunk-WDGYCBNI.js +65 -0
  155. package/dist/chunk-WDGYCBNI.js.map +1 -0
  156. package/dist/chunk-WPJOTQA5.js +1 -0
  157. package/dist/chunk-WPJOTQA5.js.map +1 -0
  158. package/dist/{chunk-DGUM43GV.js → chunk-XTHN6JBX.js} +1 -1
  159. package/dist/chunk-XTHN6JBX.js.map +1 -0
  160. package/dist/{chunk-HZ6USUHC.js → chunk-YOIVCCZT.js} +1 -1
  161. package/dist/chunk-YOIVCCZT.js.map +1 -0
  162. package/dist/{chunk-UO7WS32S.js → chunk-ZC2UESE4.js} +7 -5
  163. package/dist/chunk-ZC2UESE4.js.map +1 -0
  164. package/dist/cli/index.js +15 -15
  165. package/dist/client/core.d.ts +4 -258
  166. package/dist/client/core.js +13 -9
  167. package/dist/client/core.js.map +1 -1
  168. package/dist/client/index.d.ts +8 -97
  169. package/dist/client/index.js +39 -92
  170. package/dist/client/index.js.map +1 -1
  171. package/dist/{cloudflare-C6E5SPAE.js → cloudflare-4YT5CK3P.js} +3 -3
  172. package/dist/{controller-swc-transform-XV3ETSE3.js → controller-swc-transform-LUJ4VAZJ.js} +1 -1
  173. package/dist/controller-swc-transform-LUJ4VAZJ.js.map +1 -0
  174. package/dist/{controller-swc-transform-URELVCBM.js → controller-swc-transform-T7ZTD55V.js} +2 -2
  175. package/dist/controller-swc-transform-T7ZTD55V.js.map +1 -0
  176. package/dist/{cookies-MJKMGJ7N.js → cookies-SOXUQJXG.js} +3 -3
  177. package/dist/cookies-SOXUQJXG.js.map +1 -0
  178. package/dist/{db-3UNAMSFK.js → db-IVVCQE5Z.js} +1 -2
  179. package/dist/db-IVVCQE5Z.js.map +1 -0
  180. package/dist/{deno-deploy-RFZN56X4.js → deno-deploy-YYN6BNLF.js} +3 -3
  181. package/dist/{dev-PS2NGT6I.js → dev-V6UBM2OL.js} +14 -13
  182. package/dist/{dev-PS2NGT6I.js.map → dev-V6UBM2OL.js.map} +1 -1
  183. package/dist/{dev-emit-2DL3MCLM.js → dev-emit-F54Y5TIU.js} +5 -5
  184. package/dist/dev-emit-F54Y5TIU.js.map +1 -0
  185. package/dist/{dev-emit-XVTJXZGA.js → dev-emit-J7V6GWSK.js} +6 -6
  186. package/dist/devtools/entry.js +61 -25
  187. package/dist/devtools/entry.js.map +1 -1
  188. package/dist/{dispatcher-EJHL6JMJ.js → dispatcher-KMZBGMM5.js} +1 -1
  189. package/dist/dispatcher-KMZBGMM5.js.map +1 -0
  190. package/dist/dispatcher-MXKF3CRH.js +8 -0
  191. package/dist/dispatcher-MXKF3CRH.js.map +1 -0
  192. package/dist/{generate-5X4LG77M.js → generate-GXWPUVS7.js} +4 -5
  193. package/dist/generate-GXWPUVS7.js.map +1 -0
  194. package/dist/index.js +25 -25
  195. package/dist/index.js.map +1 -1
  196. package/dist/{info-2OOXFTJX.js → info-ICDTPJDC.js} +4 -4
  197. package/dist/info-ICDTPJDC.js.map +1 -0
  198. package/dist/{internal-api-FBFV265J.js → internal-api-ALXVBL56.js} +14 -14
  199. package/dist/{internal-api-LFW7R65K.js → internal-api-S7WK2WCY.js} +20 -22
  200. package/dist/internal-api-S7WK2WCY.js.map +1 -0
  201. package/dist/{load-config-3EAQTXPH.js → load-config-ICCNMO74.js} +4 -4
  202. package/dist/{mcp-ML4QK5ON.js → mcp-4JFODA5U.js} +6 -6
  203. package/dist/mcp-4JFODA5U.js.map +1 -0
  204. package/dist/{netlify-PMLHVPN4.js → netlify-2WZUQYI3.js} +3 -3
  205. package/dist/node-CMAYKDCM.js +10 -0
  206. package/dist/{openapi-2HVGJMSN.js → openapi-NIYA2VBG.js} +9 -9
  207. package/dist/openapi-NIYA2VBG.js.map +1 -0
  208. package/dist/react-query/index.js +2 -2
  209. package/dist/react-query/index.js.map +1 -1
  210. package/dist/registry-72YH7ZJM.js +23 -0
  211. package/dist/registry-72YH7ZJM.js.map +1 -0
  212. package/dist/{router-TLEAOFID.js → router-6MAACS25.js} +1 -2
  213. package/dist/router-6MAACS25.js.map +1 -0
  214. package/dist/{routes-XNS3UM3B.js → routes-2RD4S5PZ.js} +6 -6
  215. package/dist/schema-S553QCAU.js +22 -0
  216. package/dist/server/agent/index.d.ts +3 -72
  217. package/dist/server/agent/index.js +4 -4
  218. package/dist/server/agent/index.js.map +1 -1
  219. package/dist/server/auth/index.js +4 -4
  220. package/dist/server/auth/index.js.map +1 -1
  221. package/dist/server/cost/index.js +2 -2
  222. package/dist/server/cost/index.js.map +1 -1
  223. package/dist/server/cron/index.js +6 -6
  224. package/dist/server/cron/index.js.map +1 -1
  225. package/dist/server/define/index.js +4 -4
  226. package/dist/server/define/index.js.map +1 -1
  227. package/dist/server/http/index.js +11 -11
  228. package/dist/server/http/index.js.map +1 -1
  229. package/dist/server/index.d.ts +2 -2
  230. package/dist/server/index.js +41 -41
  231. package/dist/server/index.js.map +1 -1
  232. package/dist/server/jobs/index.js +7 -7
  233. package/dist/server/jobs/index.js.map +1 -1
  234. package/dist/server/observability/index.d.ts +9 -39
  235. package/dist/server/observability/index.js +5 -5
  236. package/dist/server/observability/index.js.map +1 -1
  237. package/dist/server/plugins/index.js +3 -3
  238. package/dist/server/plugins/index.js.map +1 -1
  239. package/dist/server/rate-limit/index.js +4 -4
  240. package/dist/server/rate-limit/index.js.map +1 -1
  241. package/dist/server/realtime/index.js +2 -2
  242. package/dist/server/realtime/index.js.map +1 -1
  243. package/dist/server/scan/index.js +7 -7
  244. package/dist/server/scan/index.js.map +1 -1
  245. package/dist/server/security/index.js +5 -5
  246. package/dist/server/security/index.js.map +1 -1
  247. package/dist/server/storage/index.js +2 -2
  248. package/dist/server/storage/index.js.map +1 -1
  249. package/dist/server/webhook/index.js +3 -3
  250. package/dist/server/webhook/index.js.map +1 -1
  251. package/dist/server-error-to-envelope-UM7DEVM4.js +8 -0
  252. package/dist/server-error-to-envelope-UM7DEVM4.js.map +1 -0
  253. package/dist/{server-routes-hmr-VZXOP5YT.js → server-routes-hmr-4W5L2MKN.js} +1 -1
  254. package/dist/server-routes-hmr-4W5L2MKN.js.map +1 -0
  255. package/dist/{server-routes-hmr-PBHSKCQJ.js → server-routes-hmr-6CRNSEWF.js} +2 -2
  256. package/dist/server-routes-hmr-6CRNSEWF.js.map +1 -0
  257. package/dist/{services-json-Y3XODNB5.js → services-json-7ZXJ4CIS.js} +1 -1
  258. package/dist/services-json-7ZXJ4CIS.js.map +1 -0
  259. package/dist/{services-typed-client-32KMTTXR.js → services-typed-client-EO4RFNTZ.js} +2 -2
  260. package/dist/services-typed-client-EO4RFNTZ.js.map +1 -0
  261. package/dist/{services-typed-client-IETY2SAK.js → services-typed-client-IXNOPVZA.js} +3 -3
  262. package/dist/services-typed-client-IXNOPVZA.js.map +1 -0
  263. package/dist/{start-YLR2SFHU.js → start-2LNPPG74.js} +40 -16
  264. package/dist/start-2LNPPG74.js.map +1 -0
  265. package/dist/{static-MB2CD5Y3.js → static-25H5K42R.js} +3 -3
  266. package/dist/{static-MB2CD5Y3.js.map → static-25H5K42R.js.map} +1 -1
  267. package/dist/{theo-cloud-DQRP6S6M.js → theo-cloud-JL2KXHIS.js} +2 -2
  268. package/dist/{upgrade-readiness-ACGW44JC.js → upgrade-readiness-77P6VNB4.js} +1 -1
  269. package/dist/upgrade-readiness-77P6VNB4.js.map +1 -0
  270. package/dist/{vercel-J6G7ZHYQ.js → vercel-FP3C6LN6.js} +3 -3
  271. package/dist/vite-plugin/index.js +25 -25
  272. package/dist/vite-plugin/index.js.map +1 -1
  273. package/dist/{vite-plugin-6VVU6PPC.js → vite-plugin-X6YO3OUH.js} +14 -13
  274. package/package.json +9 -8
  275. package/dist/actions-virtual-module-LD3YKWIX.js.map +0 -1
  276. package/dist/actions-virtual-module-N7GKUS3D.js.map +0 -1
  277. package/dist/add-W6FNTAFS.js.map +0 -1
  278. package/dist/agents-typed-client-CHMVW7MK.js.map +0 -1
  279. package/dist/agents-typed-client-NJ73Z6XY.js.map +0 -1
  280. package/dist/app-typed-client-6YZRDAPY.js.map +0 -1
  281. package/dist/app-typed-client-V77SVU2O.js.map +0 -1
  282. package/dist/body-parser-web-FV5HWCY3.js.map +0 -1
  283. package/dist/body-parser-web-MUWBKZ3F.js.map +0 -1
  284. package/dist/build-BYLQZJT2.js.map +0 -1
  285. package/dist/build-request-body-preview-EOP2Y4F3.js.map +0 -1
  286. package/dist/build-request-body-preview-QMWD2IXK.js.map +0 -1
  287. package/dist/check-PD2FTKMM.js.map +0 -1
  288. package/dist/chunk-2ZX4J4SX.js.map +0 -1
  289. package/dist/chunk-45C3WUQ7.js.map +0 -1
  290. package/dist/chunk-5AVPWHUE.js.map +0 -1
  291. package/dist/chunk-5PU65T5W.js.map +0 -1
  292. package/dist/chunk-5QW7IQQU.js.map +0 -1
  293. package/dist/chunk-6NEXVBPY.js.map +0 -1
  294. package/dist/chunk-7BIM27LV.js.map +0 -1
  295. package/dist/chunk-7MQOHNHE.js.map +0 -1
  296. package/dist/chunk-ASDXVRJD.js.map +0 -1
  297. package/dist/chunk-AXVFVMLM.js.map +0 -1
  298. package/dist/chunk-C3ZZ56YZ.js.map +0 -1
  299. package/dist/chunk-D7ZH7DTG.js.map +0 -1
  300. package/dist/chunk-E25FBYJP.js.map +0 -1
  301. package/dist/chunk-E3JH6YUM.js +0 -1
  302. package/dist/chunk-ESC54TAK.js.map +0 -1
  303. package/dist/chunk-FEDSPOY6.js.map +0 -1
  304. package/dist/chunk-FH3DYBAN.js.map +0 -1
  305. package/dist/chunk-GSO77FSM.js.map +0 -1
  306. package/dist/chunk-GUUWDMR2.js.map +0 -1
  307. package/dist/chunk-GW5H4KB4.js.map +0 -1
  308. package/dist/chunk-GY5Q27BJ.js.map +0 -1
  309. package/dist/chunk-HZ6USUHC.js.map +0 -1
  310. package/dist/chunk-IAJ2JVEH.js.map +0 -1
  311. package/dist/chunk-IHJZPQEF.js.map +0 -1
  312. package/dist/chunk-IPC5UREF.js.map +0 -1
  313. package/dist/chunk-JAIKGP3Q.js.map +0 -1
  314. package/dist/chunk-JBCHWRKF.js.map +0 -1
  315. package/dist/chunk-JHEAWR3L.js +0 -1
  316. package/dist/chunk-JQJN6LFK.js.map +0 -1
  317. package/dist/chunk-JQSKBMXP.js.map +0 -1
  318. package/dist/chunk-KI7OWQUX.js.map +0 -1
  319. package/dist/chunk-KPRJS3II.js +0 -505
  320. package/dist/chunk-KPRJS3II.js.map +0 -1
  321. package/dist/chunk-M6NMS5LR.js.map +0 -1
  322. package/dist/chunk-NM4WF3XD.js.map +0 -1
  323. package/dist/chunk-NPMCKOX4.js +0 -1
  324. package/dist/chunk-OPLICDUB.js.map +0 -1
  325. package/dist/chunk-P37RZRFV.js.map +0 -1
  326. package/dist/chunk-QWBXUZAX.js.map +0 -1
  327. package/dist/chunk-RMU7EBRO.js.map +0 -1
  328. package/dist/chunk-SJIRP73B.js.map +0 -1
  329. package/dist/chunk-SPJNVWOK.js.map +0 -1
  330. package/dist/chunk-TSLSIRBR.js.map +0 -1
  331. package/dist/chunk-U3NTEK46.js.map +0 -1
  332. package/dist/chunk-UD3LFGDL.js.map +0 -1
  333. package/dist/chunk-UNLG36Z5.js.map +0 -1
  334. package/dist/chunk-UO7WS32S.js.map +0 -1
  335. package/dist/chunk-UUFYP2UM.js.map +0 -1
  336. package/dist/chunk-UVXB2ER7.js.map +0 -1
  337. package/dist/chunk-V3LJN2GS.js.map +0 -1
  338. package/dist/chunk-VMEWD57H.js.map +0 -1
  339. package/dist/chunk-WFNLNIJX.js.map +0 -1
  340. package/dist/chunk-WSJKACWB.js.map +0 -1
  341. package/dist/chunk-X2VVCJ4V.js.map +0 -1
  342. package/dist/chunk-X32XEJXR.js.map +0 -1
  343. package/dist/chunk-YB5DJJ4U.js.map +0 -1
  344. package/dist/chunk-ZEGYW52B.js.map +0 -1
  345. package/dist/chunk-ZJQ4O76G.js.map +0 -1
  346. package/dist/controller-swc-transform-URELVCBM.js.map +0 -1
  347. package/dist/controller-swc-transform-XV3ETSE3.js.map +0 -1
  348. package/dist/cookies-MJKMGJ7N.js.map +0 -1
  349. package/dist/db-3UNAMSFK.js.map +0 -1
  350. package/dist/dev-emit-2DL3MCLM.js.map +0 -1
  351. package/dist/dispatcher-63LBXYLE.js +0 -8
  352. package/dist/dispatcher-63LBXYLE.js.map +0 -1
  353. package/dist/dispatcher-EJHL6JMJ.js.map +0 -1
  354. package/dist/generate-5X4LG77M.js.map +0 -1
  355. package/dist/info-2OOXFTJX.js.map +0 -1
  356. package/dist/internal-api-FBFV265J.js.map +0 -1
  357. package/dist/internal-api-LFW7R65K.js.map +0 -1
  358. package/dist/load-config-3EAQTXPH.js.map +0 -1
  359. package/dist/mcp-ML4QK5ON.js.map +0 -1
  360. package/dist/node-BPJ3Z4DT.js +0 -10
  361. package/dist/node-BPJ3Z4DT.js.map +0 -1
  362. package/dist/openapi-2HVGJMSN.js.map +0 -1
  363. package/dist/registry-FKPH7XEL.js +0 -24
  364. package/dist/registry-FKPH7XEL.js.map +0 -1
  365. package/dist/router-TLEAOFID.js.map +0 -1
  366. package/dist/schema-LYOLNHZ7.js +0 -30
  367. package/dist/schema-LYOLNHZ7.js.map +0 -1
  368. package/dist/server-error-to-envelope-EOFUIUNB.js +0 -8
  369. package/dist/server-error-to-envelope-EOFUIUNB.js.map +0 -1
  370. package/dist/server-routes-hmr-PBHSKCQJ.js.map +0 -1
  371. package/dist/server-routes-hmr-VZXOP5YT.js.map +0 -1
  372. package/dist/services-json-Y3XODNB5.js.map +0 -1
  373. package/dist/services-typed-client-32KMTTXR.js.map +0 -1
  374. package/dist/services-typed-client-IETY2SAK.js.map +0 -1
  375. package/dist/start-YLR2SFHU.js.map +0 -1
  376. package/dist/upgrade-readiness-ACGW44JC.js.map +0 -1
  377. package/dist/vite-plugin-6VVU6PPC.js.map +0 -1
  378. /package/dist/{agent-U35G3WNE.js.map → agent-OCCL5RUY.js.map} +0 -0
  379. /package/dist/{aws-lambda-7GSCNLPY.js.map → aws-lambda-473QCOL6.js.map} +0 -0
  380. /package/dist/{bun-KP2KES6S.js.map → bun-OQUCL3XW.js.map} +0 -0
  381. /package/dist/{chunk-AFVTEAES.js.map → chunk-B7ONQ4QJ.js.map} +0 -0
  382. /package/dist/{chunk-L4GCEMNW.js.map → chunk-LNVMHQ2Z.js.map} +0 -0
  383. /package/dist/{chunk-NQRNDPZJ.js.map → chunk-OXCALO3W.js.map} +0 -0
  384. /package/dist/{chunk-FOZIR3TG.js.map → chunk-SMP2T335.js.map} +0 -0
  385. /package/dist/{cloudflare-C6E5SPAE.js.map → cloudflare-4YT5CK3P.js.map} +0 -0
  386. /package/dist/{deno-deploy-RFZN56X4.js.map → deno-deploy-YYN6BNLF.js.map} +0 -0
  387. /package/dist/{dev-emit-XVTJXZGA.js.map → dev-emit-J7V6GWSK.js.map} +0 -0
  388. /package/dist/{broadcast-4SX7R5XE.js.map → internal-api-ALXVBL56.js.map} +0 -0
  389. /package/dist/{chunk-DGUM43GV.js.map → load-config-ICCNMO74.js.map} +0 -0
  390. /package/dist/{netlify-PMLHVPN4.js.map → netlify-2WZUQYI3.js.map} +0 -0
  391. /package/dist/{chunk-E3JH6YUM.js.map → node-CMAYKDCM.js.map} +0 -0
  392. /package/dist/{routes-XNS3UM3B.js.map → routes-2RD4S5PZ.js.map} +0 -0
  393. /package/dist/{chunk-JHEAWR3L.js.map → schema-S553QCAU.js.map} +0 -0
  394. /package/dist/{theo-cloud-DQRP6S6M.js.map → theo-cloud-JL2KXHIS.js.map} +0 -0
  395. /package/dist/{vercel-J6G7ZHYQ.js.map → vercel-FP3C6LN6.js.map} +0 -0
  396. /package/dist/{chunk-NPMCKOX4.js.map → vite-plugin-X6YO3OUH.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/vite-plugin/openapi-emit/emit.ts","../src/vite-plugin/openapi-emit/zod-to-openapi.ts","../src/vite-plugin/openapi-emit/load-routes.ts"],"sourcesContent":["/**\n * In-house `emitOpenApi()` orchestrator (build-time only).\n *\n * Pure transformation: takes a route manifest (already hydrated with Zod\n * schemas extracted from `defineRoute()` config) + the openapi config\n * block, builds an OpenAPI 3.x document, writes `<outDir>/openapi.json`,\n * returns the document for downstream callers (CLI logs, tests).\n *\n * Per G2 plan v1.1 T2.1. Modelled on trpc-openapi's\n * `generateOpenApiDocument` + encore's `Generator.Generate()`.\n *\n * NEVER ship to runtime — devDep-shaped artifact.\n *\n * Path templating: TheoKit's `:param` syntax is converted to OpenAPI's\n * `{param}` per the spec. Env-var override: `THEOKIT_OPENAPI_SERVER_URL`\n * overrides `servers[0].url` without rebuilding the config.\n */\n/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time emit. outDir is a config-controlled relative path. The\n * caller already refused absolute paths via theoConfigSchema.distDir\n * pattern; the openapi.outDir field follows the same convention.\n */\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { z } from 'zod'\n\nimport { zodToOpenApiSchema, type ConvertCtx, type OpenApiSchema } from './zod-to-openapi.js'\n\nexport interface OpenApiManifestRoute {\n /** TheoKit-style path with `:param` placeholders (`/users/:id`). */\n routePath: string\n /** Uppercase HTTP methods the route exports (`['GET','POST']`). */\n methods: string[]\n /** Optional `defineRoute({body})` schema. */\n body?: z.ZodType\n /** Optional `defineRoute({query})` schema. */\n query?: z.ZodType\n /** Optional `defineRoute({params})` schema. */\n params?: z.ZodType\n /** Optional `defineRoute({response})` schema. */\n response?: z.ZodType\n}\n\nexport interface OpenApiEmitConfig {\n servers: { url: string; description?: string }[]\n specVersion: '3.1.0' | '3.0.3'\n title: string\n version: string\n outDir: string\n}\n\nexport interface OpenApiOperation {\n operationId?: string\n parameters?: OpenApiParameter[]\n requestBody?: {\n required?: boolean\n content: Record<string, { schema: OpenApiSchema }>\n }\n responses: Record<\n string,\n { description: string; content?: Record<string, { schema: OpenApiSchema }> }\n >\n}\n\nexport interface OpenApiParameter {\n name: string\n in: 'path' | 'query' | 'header' | 'cookie'\n required: boolean\n schema: OpenApiSchema\n description?: string\n}\n\nexport type OpenApiPathItem = Partial<\n Record<'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options', OpenApiOperation>\n>\n\nexport interface OpenApiDocument {\n openapi: '3.1.0' | '3.0.3'\n info: { title: string; version: string }\n servers: { url: string; description?: string }[]\n paths: Record<string, OpenApiPathItem>\n components?: { schemas?: Record<string, OpenApiSchema> }\n}\n\nexport interface EmitOpenApiInput {\n manifest: OpenApiManifestRoute[]\n config: OpenApiEmitConfig\n}\n\nexport interface EmitOpenApiResult {\n document: OpenApiDocument\n path: string\n}\n\nconst METHOD_TO_KEY: Record<string, keyof OpenApiPathItem> = {\n GET: 'get',\n POST: 'post',\n PUT: 'put',\n PATCH: 'patch',\n DELETE: 'delete',\n HEAD: 'head',\n OPTIONS: 'options',\n}\n\n/** Convert `/users/:id/posts/:postId?` → `/users/{id}/posts/{postId}`. */\nexport function templatePath(routePath: string): string {\n // Bounded quantifier (\\w{0,64}) is OSS-safe — TheoKit route param names\n // never exceed 64 chars in practice; cap prevents super-linear backtracking.\n return routePath.replace(/:([A-Za-z_]\\w{0,64})\\??/g, '{$1}')\n}\n\nfunction buildParameters(\n paramsSchema: z.ZodType | undefined,\n querySchema: z.ZodType | undefined,\n ctx: ConvertCtx,\n): OpenApiParameter[] {\n const out: OpenApiParameter[] = []\n if (paramsSchema !== undefined) {\n appendObjectAsParameters(paramsSchema, 'path', out, ctx)\n }\n if (querySchema !== undefined) {\n appendObjectAsParameters(querySchema, 'query', out, ctx)\n }\n return out\n}\n\nfunction appendObjectAsParameters(\n schema: z.ZodType,\n location: 'path' | 'query',\n out: OpenApiParameter[],\n ctx: ConvertCtx,\n): void {\n // We expect an object schema; if it's not, skip silently (caller already\n // validated upstream when scanning defineRoute()).\n const shape = (schema as unknown as { shape?: Record<string, z.ZodType> }).shape\n if (shape === undefined) return\n for (const [name, child] of Object.entries(shape)) {\n // A field is optional iff the schema accepts `undefined` (covers\n // `.optional()` + `.default()`). Runtime check via safeParse — robust\n // across zod versions, unlike reading the changed `_def.typeName` internal\n // (zod 3) / `def.type` (zod 4).\n const optional = child.safeParse(undefined).success\n out.push({\n name,\n in: location,\n required: location === 'path' ? true : !optional,\n schema: zodToOpenApiSchema(child, { ctx }),\n })\n }\n}\n\nfunction buildOperation(\n route: OpenApiManifestRoute,\n ctx: ConvertCtx,\n method: string,\n): OpenApiOperation {\n // Bounded sanitizer: two single-pass replacements (no nested quantifiers).\n const sanitized = route.routePath.replace(/[/:\\-{}]/g, '_').replace(/_+/g, '_')\n const operationId = `${method.toLowerCase()}_${sanitized.replace(/^_|_$/g, '')}`\n const op: OpenApiOperation = {\n operationId,\n responses: {\n '200': { description: 'OK' },\n },\n }\n\n const parameters = buildParameters(route.params, route.query, ctx)\n if (parameters.length > 0) op.parameters = parameters\n\n // Body only meaningful for write methods; we still attach if defined so\n // the document is honest about the contract.\n if (route.body !== undefined) {\n op.requestBody = {\n required: true,\n content: {\n 'application/json': { schema: zodToOpenApiSchema(route.body, { ctx }) },\n },\n }\n }\n\n if (route.response !== undefined) {\n op.responses['200'] = {\n description: 'OK',\n content: {\n 'application/json': { schema: zodToOpenApiSchema(route.response, { ctx }) },\n },\n }\n }\n\n return op\n}\n\nexport function emitOpenApi(input: EmitOpenApiInput): EmitOpenApiResult {\n const { manifest, config } = input\n\n const ctx: ConvertCtx = { seen: new Map(), components: {} }\n\n const paths: Record<string, OpenApiPathItem> = {}\n for (const route of manifest) {\n const templatedPath = templatePath(route.routePath)\n const item: OpenApiPathItem = paths[templatedPath] ?? {}\n for (const method of route.methods) {\n // Defensive: manifest emitter normalizes to uppercase, but if a\n // future scanner produces a non-HTTP verb the key lookup yields\n // undefined and we skip silently. TS narrows the indexed type to\n // keyof OpenApiPathItem; the runtime undefined check is honest.\n const key = METHOD_TO_KEY[method.toUpperCase()] as keyof OpenApiPathItem | undefined\n if (key === undefined) continue\n item[key] = buildOperation(route, ctx, method)\n }\n paths[templatedPath] = item\n }\n\n const servers = applyServerOverride(config.servers)\n\n const document: OpenApiDocument = {\n openapi: config.specVersion,\n info: { title: config.title, version: config.version },\n servers,\n paths,\n }\n\n if (Object.keys(ctx.components).length > 0) {\n document.components = { schemas: ctx.components }\n }\n\n mkdirSync(config.outDir, { recursive: true })\n const outPath = join(config.outDir, 'openapi.json')\n writeFileSync(outPath, `${JSON.stringify(document, null, 2)}\\n`, 'utf8')\n\n return { document, path: outPath }\n}\n\nfunction applyServerOverride(\n servers: { url: string; description?: string }[],\n): { url: string; description?: string }[] {\n const override = process.env.THEOKIT_OPENAPI_SERVER_URL\n if (override === undefined || override === '') return servers\n if (servers.length === 0) return [{ url: override }]\n const [first, ...rest] = servers\n return [\n {\n url: override,\n ...(first.description !== undefined ? { description: first.description } : {}),\n },\n ...rest,\n ]\n}\n","/**\n * Zod → OpenAPI 3.0 Schema converter (build-time only).\n *\n * Uses Zod v4's native `z.toJSONSchema()` and post-processes\n * the JSON Schema output into OpenAPI 3.0 format:\n * - Removes `$schema` (invalid in OpenAPI 3.0)\n * - Converts `type: [\"string\", \"null\"]` → `{ type: \"string\", nullable: true }`\n * - Recursively normalizes nested schemas\n *\n * NEVER ship to runtime — devDep-shaped artifact.\n */\nimport { z } from 'zod'\n\nexport interface OpenApiSchema {\n type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null'\n format?: string\n items?: OpenApiSchema\n properties?: Record<string, OpenApiSchema>\n required?: string[]\n additionalProperties?: boolean | OpenApiSchema\n oneOf?: OpenApiSchema[]\n anyOf?: OpenApiSchema[]\n allOf?: OpenApiSchema[]\n discriminator?: { propertyName: string; mapping?: Record<string, string> }\n enum?: unknown[]\n nullable?: boolean\n description?: string\n default?: unknown\n $ref?: string\n}\n\nexport interface ConvertCtx {\n seen: Map<z.ZodType, string>\n components: Record<string, OpenApiSchema>\n}\n\nexport interface ConvertOptions {\n ctx?: ConvertCtx\n name?: string\n}\n\nexport class ZodToOpenApiError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ZodToOpenApiError'\n }\n}\n\nexport function zodToOpenApiSchema(schema: z.ZodType, options: ConvertOptions = {}): OpenApiSchema {\n const ctx: ConvertCtx = options.ctx ?? { seen: new Map(), components: {} }\n\n const name = options.name\n if (name !== undefined) {\n if (Object.prototype.hasOwnProperty.call(ctx.components, name)) {\n return { $ref: `#/components/schemas/${name}` }\n }\n ctx.seen.set(schema, name)\n ctx.components[name] = {}\n const body = convertSchema(schema, ctx)\n ctx.components[name] = body\n return { $ref: `#/components/schemas/${name}` }\n }\n\n return convertSchema(schema, ctx)\n}\n\ninterface ZodInternalDef {\n type?: string\n discriminator?: string\n in?: z.ZodType\n}\n\n/** Read zod v4's internal schema def (the `.def` getter) without a hard `any`. */\nfunction zodDef(schema: z.ZodType): ZodInternalDef | undefined {\n return (schema as unknown as { def?: ZodInternalDef }).def\n}\n\nfunction convertSchema(schema: z.ZodType, ctx: ConvertCtx): OpenApiSchema {\n const existing = ctx.seen.get(schema)\n if (existing !== undefined) {\n return { $ref: `#/components/schemas/${existing}` }\n }\n\n const def = zodDef(schema)\n // Fail loud on schema kinds that have no OpenAPI representation (rather than\n // swallowing the zod throw into `{}`). z.function() is the canonical case.\n if (def?.type === 'function') {\n throw new ZodToOpenApiError(\n 'z.function() cannot be represented in an OpenAPI schema (functions are not serializable).',\n )\n }\n\n // A transform / pipe (`z.string().transform(...)`) has no JSON-Schema of its\n // own — zod throws. The wire shape is the INPUT (transforms run post-parse),\n // so emit the input schema. This avoids the global `io: 'input'` mode, which\n // would also flip object `additionalProperties` semantics.\n if (def?.type === 'pipe' && def.in !== undefined) {\n return convertSchema(def.in, ctx)\n }\n\n try {\n const jsonSchema = z.toJSONSchema(schema) as Record<string, unknown>\n const out = toOpenApi3(jsonSchema)\n // zod v4 emits a discriminated union as `oneOf` but drops the discriminator\n // key; re-attach it from the zod def so OpenAPI consumers can branch.\n if (def?.type === 'union' && def.discriminator !== undefined && out.oneOf !== undefined) {\n out.discriminator = { propertyName: def.discriminator }\n }\n return out\n } catch (err) {\n if (err instanceof ZodToOpenApiError) throw err\n return {}\n }\n}\n\n/** JS safe-integer bounds zod v4 attaches to `.int()` — noise for OpenAPI, stripped. */\nconst SAFE_INT_MIN = Number.MIN_SAFE_INTEGER\nconst SAFE_INT_MAX = Number.MAX_SAFE_INTEGER\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v)\n}\n\n/** Drop zod-v4 noise keys: redundant `pattern` when `format` is set; JS safe-integer sentinel bounds. */\nfunction isNoiseKey(key: string, value: unknown, isInteger: boolean, hasFormat: boolean): boolean {\n if (key === 'pattern' && hasFormat) return true\n if (isInteger && key === 'minimum' && value === SAFE_INT_MIN) return true\n if (isInteger && key === 'maximum' && value === SAFE_INT_MAX) return true\n return false\n}\n\n/** Recursively normalize one JSON-Schema value (properties/items/*Of/additionalProperties). */\nfunction normalizeValue(key: string, value: unknown): unknown {\n if (key === 'properties' && isRecord(value)) {\n const props: Record<string, unknown> = {}\n for (const [pk, pv] of Object.entries(value)) props[pk] = isRecord(pv) ? toOpenApi3(pv) : pv\n return props\n }\n if (key === 'items' && isRecord(value)) return toOpenApi3(value)\n if ((key === 'anyOf' || key === 'oneOf' || key === 'allOf') && Array.isArray(value)) {\n const arr: unknown[] = value\n return arr.map((v) => (isRecord(v) ? toOpenApi3(v) : v))\n }\n if (key === 'additionalProperties' && isRecord(value)) return toOpenApi3(value)\n return value\n}\n\n/** Convert zod v4's `anyOf` (used for `.nullable()` + `z.union()`) to OpenAPI 3.0 shape. */\nfunction convertAnyOf(branches: unknown[], rest: Record<string, unknown>): OpenApiSchema {\n const records = branches.filter(isRecord)\n const hasNull = records.some((b) => b.type === 'null')\n const nonNull = records.filter((b) => b.type !== 'null')\n if (hasNull && nonNull.length === 1) {\n return { ...toOpenApi3(nonNull[0]), nullable: true }\n }\n const result: OpenApiSchema = { oneOf: nonNull.map((b) => toOpenApi3(b)) }\n if (hasNull) result.nullable = true\n for (const [k, v] of Object.entries(rest))\n if (k !== 'anyOf') (result as Record<string, unknown>)[k] = v\n return result\n}\n\n/**\n * Post-process JSON Schema (draft-2020-12) → OpenAPI 3.0:\n * - strip `$schema`/`$defs`\n * - `.nullable()`/union `anyOf` → `nullable: true` / `oneOf`\n * - `type: [\"string\",\"null\"]` → `{ type: \"string\", nullable: true }`\n * - drop zod-v4 noise (redundant pattern, safe-integer bounds)\n * - recurse into nested schemas\n */\nfunction toOpenApi3(js: Record<string, unknown>): OpenApiSchema {\n const { $schema: _, $defs: _defs, ...rest } = js\n if (Array.isArray(rest.anyOf)) return convertAnyOf(rest.anyOf, rest)\n\n const isInteger = rest.type === 'integer'\n const hasFormat = typeof rest.format === 'string'\n const out: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(rest)) {\n if (isNoiseKey(key, value, isInteger, hasFormat)) continue\n // `const` is JSON-Schema / OpenAPI-3.1 only; `enum: [x]` is the 3.0-and-3.1\n // compatible spelling. zod v4 emits `const` for literals (discriminator tags).\n if (key === 'const') {\n out.enum = [value]\n continue\n }\n if (key === 'type' && Array.isArray(value)) {\n const types = value.filter((t): t is string => typeof t === 'string')\n const nonNull = types.filter((t) => t !== 'null')\n out.type = nonNull.length === 1 ? nonNull[0] : nonNull\n if (types.includes('null')) out.nullable = true\n } else {\n out[key] = normalizeValue(key, value)\n }\n }\n\n return out\n}\n","/**\n * Build-time route loader for OpenAPI emit.\n *\n * Takes the G1 manifest (filePath + routePath + methods) and hydrates each\n * route's Zod schemas by dynamically importing the module. `defineRoute`\n * is an identity function, so the imported config exposes `body/query/\n * params/response` directly without any AST gymnastics.\n *\n * Supports both export shapes:\n * 1. `export const POST = defineRoute({...})` (per-method named exports)\n * 2. `export default defineRoute({...})` (single-export legacy shape)\n *\n * Per G2 plan v1.1 T2.2. Uses Vite's `ssrLoadModule` because route files\n * are TS at build time — Node's native loader doesn't transpile.\n */\nimport { resolve } from 'node:path'\n\nimport type { z } from 'zod'\n\nimport type { ManifestRoute } from '../../server/scan/manifest.js'\n\nimport type { OpenApiManifestRoute } from './emit.js'\n\ninterface RouteConfigShape {\n body?: z.ZodType\n query?: z.ZodType\n params?: z.ZodType\n response?: z.ZodType\n}\n\ninterface ViteLikeServer {\n ssrLoadModule: (id: string) => Promise<Record<string, unknown>>\n close: () => Promise<void>\n}\n\ninterface DefaultLoader {\n load: (absPath: string) => Promise<Record<string, unknown>>\n dispose: () => Promise<void>\n}\n\n/** Method names recognized as per-route named exports (UPPERCASE). */\nconst HTTP_METHOD_KEYS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\n\nexport interface LoadRoutesOptions {\n serverDir: string\n routes: ManifestRoute[]\n /** Injectable for tests; defaults to a fresh Vite SSR dev server. */\n loadModule?: (absPath: string) => Promise<Record<string, unknown>>\n}\n\n/**\n * Hydrate manifest routes with Zod schemas extracted from their modules.\n *\n * Returns one `OpenApiManifestRoute` per (file × method) tuple. If a route\n * file declares multiple methods (`GET` + `POST`), each method gets its\n * own entry with the schemas from that method's `defineRoute()` call.\n *\n * Routes that fail to load are skipped with a console warning — the emit\n * should be best-effort, not a hard build failure.\n *\n * The default Vite loader is created once per call and disposed in the\n * `finally` block so the underlying server is released even when route\n * loading throws.\n */\nexport async function loadRoutesForOpenApi(\n options: LoadRoutesOptions,\n): Promise<OpenApiManifestRoute[]> {\n const { serverDir, routes } = options\n let loadModule = options.loadModule\n let dispose: (() => Promise<void>) | undefined\n if (loadModule === undefined) {\n const created = await createDefaultLoader(serverDir)\n loadModule = created.load\n dispose = created.dispose\n }\n\n const out: OpenApiManifestRoute[] = []\n try {\n for (const r of routes) {\n const abs = resolve(serverDir, r.filePath)\n let mod: Record<string, unknown>\n try {\n mod = await loadModule(abs)\n } catch (err) {\n console.warn(\n `[openapi-emit] Skipping ${r.filePath}: load failed (${(err as Error).message})`,\n )\n continue\n }\n\n const methods = r.methods ?? HTTP_METHOD_KEYS.filter((m) => mod[m] !== undefined)\n if (methods.length === 0) {\n // Fall back to default export when no method-named exports detected.\n const def = mod.default\n if (def !== undefined && def !== null) {\n out.push({ routePath: r.routePath, methods: ['GET'], ...extractSchemas(def) })\n }\n continue\n }\n\n for (const method of methods) {\n const handler = mod[method] ?? mod.default\n if (handler === undefined || handler === null) continue\n out.push({ routePath: r.routePath, methods: [method], ...extractSchemas(handler) })\n }\n }\n } finally {\n if (dispose !== undefined) {\n await dispose()\n }\n }\n return out\n}\n\nfunction extractSchemas(handlerExport: unknown): RouteConfigShape {\n if (typeof handlerExport !== 'object' || handlerExport === null) return {}\n const cfg = handlerExport as RouteConfigShape\n const out: RouteConfigShape = {}\n if (cfg.body !== undefined) out.body = cfg.body\n if (cfg.query !== undefined) out.query = cfg.query\n if (cfg.params !== undefined) out.params = cfg.params\n if (cfg.response !== undefined) out.response = cfg.response\n return out\n}\n\n/**\n * Default loader: spin up a minimal Vite SSR dev server (no HMR, no\n * middlewares) just to use its `ssrLoadModule`. Vite handles TS, ESM, and\n * import resolution for free.\n *\n * Returns `{load, dispose}` — the caller owns the lifecycle and MUST\n * call `dispose()` (typically in a `finally`) so the server is closed.\n */\nasync function createDefaultLoader(serverDir: string): Promise<DefaultLoader> {\n // Vite is a peerDep in build flows; import dynamically.\n const { createServer } = await import('vite')\n const server = (await createServer({\n root: serverDir,\n configFile: false,\n server: { middlewareMode: true },\n appType: 'custom',\n logLevel: 'silent',\n })) as unknown as ViteLikeServer\n\n const swallow = (): void => {\n /* eat close errors — best-effort cleanup */\n }\n return {\n load: async (absPath) => server.ssrLoadModule(absPath),\n dispose: async () => {\n await server.close().catch(swallow)\n },\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server/security/csp-report.ts","../src/server/security/csrf-readiness-endpoint.ts","../src/server/security/csrf-readiness-store.ts","../src/server/security/security-headers.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\n\nimport { safeAudit, type AuditLogger } from '../observability/audit-log.js'\n\n/**\n * T5.1 — Built-in CSP report endpoint.\n *\n * Browsers POST violation reports to `report-uri` (legacy `application/csp-report`)\n * or `Reporting API` (`application/reports+json`). Framework auto-registers this\n * endpoint so `cspMode: 'report-only'` is actually useful out of the box.\n *\n * Forwards normalized violations to:\n * - audit logger (`csp.violation`)\n * - devtools dispatcher (dev only, for Errors tab)\n * - optional user hook (Sentry, etc.)\n *\n * EC-2: browser MAY send `{\"csp-report\": null}`, empty `{}`, or\n * reports+json entries lacking `body`. Handler MUST short-circuit to\n * 204 (valid format, no violation), NEVER crash via null deref.\n */\n\nexport const CSP_REPORT_PATH = '/__theo/csp-report'\n\n/** Max body bytes accepted. Real CSP reports are < 2 KB; 16 KB is generous. */\nconst MAX_BODY = 16 * 1024\n\nexport interface CspViolation {\n blockedUrl: string\n documentUrl: string\n violatedDirective: string\n effectiveDirective?: string\n originalPolicy?: string\n disposition?: 'enforce' | 'report'\n statusCode?: number\n sourceFile?: string\n lineNumber?: number\n columnNumber?: number\n}\n\nexport interface CspReportHandlerOptions {\n auditLogger?: AuditLogger\n devtoolsDispatcher?: {\n onCspViolation?: (v: CspViolation) => void\n }\n /** Optional user-provided sink (Sentry, custom log router). Errors here are swallowed. */\n onViolation?: (v: CspViolation) => void\n}\n\n/**\n * Map a legacy `application/csp-report` payload to the internal shape.\n * Caller must ensure `raw` is a non-null object.\n */\nfunction pickHeader(value: string | string[] | undefined): string {\n if (typeof value === 'string') return value\n if (Array.isArray(value) && value.length > 0) return value[0]\n return ''\n}\n\nfunction toStringSafe(value: unknown, fallback = '(missing)'): string {\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n return fallback\n}\n\nexport function normalizeLegacy(raw: Record<string, unknown>): CspViolation {\n return {\n blockedUrl: toStringSafe(raw['blocked-uri']),\n documentUrl: toStringSafe(raw['document-uri']),\n violatedDirective: toStringSafe(raw['violated-directive']),\n effectiveDirective:\n typeof raw['effective-directive'] === 'string' ? raw['effective-directive'] : undefined,\n originalPolicy: typeof raw['original-policy'] === 'string' ? raw['original-policy'] : undefined,\n disposition:\n raw.disposition === 'enforce' || raw.disposition === 'report' ? raw.disposition : undefined,\n statusCode: typeof raw['status-code'] === 'number' ? raw['status-code'] : undefined,\n sourceFile: typeof raw['source-file'] === 'string' ? raw['source-file'] : undefined,\n lineNumber: typeof raw['line-number'] === 'number' ? raw['line-number'] : undefined,\n columnNumber: typeof raw['column-number'] === 'number' ? raw['column-number'] : undefined,\n }\n}\n\n/**\n * Map a `reports+json` entry to the internal shape. Returns `null` if\n * the entry lacks a usable `body` object (EC-2).\n */\nexport function normalizeNew(entry: unknown): CspViolation | null {\n if (!entry || typeof entry !== 'object') return null\n const body = (entry as { body?: unknown }).body\n if (!body || typeof body !== 'object') return null\n const b = body as Record<string, unknown>\n return {\n blockedUrl: toStringSafe(b.blockedURL),\n documentUrl: toStringSafe(b.documentURL),\n violatedDirective: toStringSafe(b.violatedDirective),\n effectiveDirective: typeof b.effectiveDirective === 'string' ? b.effectiveDirective : undefined,\n originalPolicy: typeof b.originalPolicy === 'string' ? b.originalPolicy : undefined,\n disposition:\n b.disposition === 'enforce' || b.disposition === 'report' ? b.disposition : undefined,\n statusCode: typeof b.statusCode === 'number' ? b.statusCode : undefined,\n sourceFile: typeof b.sourceFile === 'string' ? b.sourceFile : undefined,\n lineNumber: typeof b.lineNumber === 'number' ? b.lineNumber : undefined,\n columnNumber: typeof b.columnNumber === 'number' ? b.columnNumber : undefined,\n }\n}\n\nasync function readBody(req: IncomingMessage, maxBytes: number): Promise<string> {\n return await new Promise<string>((resolve, reject) => {\n const chunks: Buffer[] = []\n let total = 0\n req.on('data', (chunk: Buffer) => {\n total += chunk.length\n if (total > maxBytes) {\n reject(new Error('body too large'))\n req.destroy()\n return\n }\n chunks.push(chunk)\n })\n req.on('end', () => {\n resolve(Buffer.concat(chunks).toString('utf8'))\n })\n req.on('error', reject)\n })\n}\n\nexport async function handleCspReport(\n req: IncomingMessage,\n res: ServerResponse,\n opts: CspReportHandlerOptions,\n): Promise<void> {\n const ctHeader = req.headers['content-type']\n const ct = pickHeader(ctHeader)\n\n let raw: string\n try {\n raw = await readBody(req, MAX_BODY)\n } catch {\n res.statusCode = 413\n res.end()\n return\n }\n\n let violations: CspViolation[]\n try {\n if (ct.startsWith('application/csp-report')) {\n // EC-2: browsers MAY POST {\"csp-report\": null} or {} on\n // disposition='report' policies. Guard against null/undefined/non-object.\n const parsed = JSON.parse(raw) as Record<string, unknown>\n const inner = parsed['csp-report']\n if (!inner || typeof inner !== 'object') {\n res.statusCode = 204\n res.end()\n return\n }\n violations = [normalizeLegacy(inner as Record<string, unknown>)]\n } else if (ct.startsWith('application/reports+json')) {\n // EC-2: filter out entries lacking `body` BEFORE normalizing.\n const parsed: unknown = JSON.parse(raw)\n const entries = Array.isArray(parsed) ? parsed : []\n violations = entries.map((e) => normalizeNew(e)).filter((v): v is CspViolation => v !== null)\n } else {\n res.statusCode = 415\n res.end()\n return\n }\n } catch {\n res.statusCode = 400\n res.end()\n return\n }\n\n for (const v of violations) {\n safeAudit(opts.auditLogger, {\n action: 'csp.violation',\n metadata: v as unknown as Record<string, unknown>,\n })\n try {\n opts.devtoolsDispatcher?.onCspViolation?.(v)\n } catch {\n // dispatcher errors are isolated from the request\n }\n try {\n opts.onViolation?.(v)\n } catch {\n // user hook throws are swallowed — never crash the request\n }\n }\n\n res.statusCode = 204\n res.end()\n}\n\n/**\n * T5a.2 Phase B slice 4/6 — Web-Standards CSP report handler.\n *\n * Mirror of `handleCspReport(req: IncomingMessage, res: ServerResponse,\n * opts): Promise<void>` for the Web `Request` shape. Returns\n * `Response` directly instead of mutating `res`.\n *\n * Same content-type dispatch (legacy `application/csp-report` vs new\n * `application/reports+json`), same normalizers (`normalizeLegacy`,\n * `normalizeNew`), same side-effect loop (safeAudit + devtools + user\n * hook). The body cap is enforced post-read because Web Request body\n * streaming doesn't have a portable mid-stream rejection primitive\n * across CF Workers / Bun / Deno; CSP reports are < 2 KB typical, well\n * under MAX_BODY (16 KB).\n *\n * Returns:\n * - 204 on accepted reports OR no-op empty payload\n * - 413 on body too large (post-read check)\n * - 415 on unsupported content-type\n * - 400 on malformed JSON\n */\nasync function readBodyFromRequest(request: Request, maxBytes: number): Promise<string | null> {\n const contentLengthHeader = request.headers.get('content-length')\n if (contentLengthHeader !== null) {\n const declared = Number.parseInt(contentLengthHeader, 10)\n if (Number.isFinite(declared) && declared > maxBytes) return null\n }\n const text = await request.text()\n if (text.length > maxBytes) return null\n return text\n}\n\nfunction dispatchViolations(violations: CspViolation[], opts: CspReportHandlerOptions): void {\n for (const v of violations) {\n safeAudit(opts.auditLogger, {\n action: 'csp.violation',\n metadata: v as unknown as Record<string, unknown>,\n })\n try {\n opts.devtoolsDispatcher?.onCspViolation?.(v)\n } catch {\n // dispatcher errors are isolated from the request\n }\n try {\n opts.onViolation?.(v)\n } catch {\n // user hook throws are swallowed — never crash the request\n }\n }\n}\n\nexport async function handleCspReportRequest(\n request: Request,\n opts: CspReportHandlerOptions,\n): Promise<Response> {\n const ct = request.headers.get('content-type') ?? ''\n\n const raw = await readBodyFromRequest(request, MAX_BODY)\n if (raw === null) {\n return new Response(null, { status: 413 })\n }\n\n let violations: CspViolation[]\n try {\n if (ct.startsWith('application/csp-report')) {\n const parsed = JSON.parse(raw) as Record<string, unknown>\n const inner = parsed['csp-report']\n if (!inner || typeof inner !== 'object') {\n return new Response(null, { status: 204 })\n }\n violations = [normalizeLegacy(inner as Record<string, unknown>)]\n } else if (ct.startsWith('application/reports+json')) {\n const parsed: unknown = JSON.parse(raw)\n const entries = Array.isArray(parsed) ? parsed : []\n violations = entries.map((e) => normalizeNew(e)).filter((v): v is CspViolation => v !== null)\n } else {\n return new Response(null, { status: 415 })\n }\n } catch {\n return new Response(null, { status: 400 })\n }\n\n dispatchViolations(violations, opts)\n return new Response(null, { status: 204 })\n}\n","/**\n * T2.2 — `/__theo/csrf-readiness` endpoint.\n *\n * GET /__theo/csrf-readiness → 200 + JSON summary\n * POST /__theo/csrf-readiness/reset → 204; clears the store\n *\n * The reset endpoint enforces CSRF (own dog food) — requires\n * `X-Theo-Action: 1` AND a matching Origin header (EC-15). This avoids\n * the endpoint being weaponizable from a cross-origin page when the\n * endpoint is opt-in exposed in production.\n *\n * Mount opt-in: in dev mode, the host wires this in unconditionally. In\n * production, only mount when `config.security.csrfTelemetry.exposeReadinessEndpoint === true`.\n * EC-10 parallel: returns 404 (via boolean false return) when the URL\n * does not match — the caller continues normal request handling.\n */\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\nimport type { CsrfReadinessStore } from './csrf-readiness-store.js'\n\nexport const CSRF_READINESS_PATH = '/__theo/csrf-readiness'\nexport const CSRF_READINESS_RESET_PATH = '/__theo/csrf-readiness/reset'\n\nfunction originMatchesHost(req: IncomingMessage): boolean {\n const origin = req.headers.origin\n if (typeof origin !== 'string') return false\n const host = req.headers.host\n if (typeof host !== 'string') return false\n try {\n const parsed = new URL(origin)\n return parsed.host === host\n } catch {\n return false\n }\n}\n\nfunction sendJson(res: ServerResponse, status: number, body: unknown): void {\n res.writeHead(status, { 'content-type': 'application/json' })\n res.end(JSON.stringify(body))\n}\n\nfunction sendNoContent(res: ServerResponse): void {\n res.writeHead(204)\n res.end()\n}\n\nfunction sendError(res: ServerResponse, status: number, code: string, message: string): void {\n res.writeHead(status, { 'content-type': 'application/json' })\n res.end(JSON.stringify({ error: { code, message } }))\n}\n\n// eslint-disable-next-line @typescript-eslint/require-await -- async return for future telemetry hooks\nexport async function handleCsrfReadiness(\n req: IncomingMessage,\n res: ServerResponse,\n store: CsrfReadinessStore,\n): Promise<boolean> {\n const url = (req.url ?? '').split('?')[0]\n const method = req.method ?? 'GET'\n\n if (url === CSRF_READINESS_PATH) {\n if (method === 'GET') {\n sendJson(res, 200, store.summary())\n return true\n }\n sendError(res, 405, 'METHOD_NOT_ALLOWED', `Use GET on ${CSRF_READINESS_PATH}`)\n return true\n }\n\n if (url === CSRF_READINESS_RESET_PATH) {\n if (method !== 'POST') {\n sendError(res, 405, 'METHOD_NOT_ALLOWED', `Use POST on ${CSRF_READINESS_RESET_PATH}`)\n return true\n }\n // Enforce CSRF on our own endpoint (dog-food).\n const hasHeader = req.headers['x-theo-action'] === '1'\n if (!hasHeader || !originMatchesHost(req)) {\n sendError(res, 403, 'CSRF_INVALID', 'Reset requires X-Theo-Action: 1 + same-origin')\n return true\n }\n store.reset()\n sendNoContent(res)\n return true\n }\n\n return false\n}\n\n/**\n * T5a.2 Phase B slice 3/6 — Web-Standards-shaped CSRF readiness handler.\n *\n * Mirror of `handleCsrfReadiness(req: IncomingMessage, res: ServerResponse,\n * store): Promise<boolean>` for the Web `Request` shape. Returns\n * `Response | null` instead of mutating `res` and returning a boolean:\n * - `Response` → this handler claimed the URL; caller short-circuits.\n * - `null` → URL doesn't match our endpoint; caller continues normal dispatch.\n *\n * Same routes (GET `CSRF_READINESS_PATH`, POST `CSRF_READINESS_RESET_PATH`).\n * Same CSRF dog-food on reset (X-Theo-Action + same-origin).\n *\n * Wire into `executeWebRequest` integration via a future Phase B sub-slice\n * (consumer can also call this directly today via the\n * `theokit/server/security` sub-path).\n */\nfunction buildJsonResponse(status: number, body: unknown): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n}\n\nfunction buildErrorResponse(status: number, code: string, message: string): Response {\n return buildJsonResponse(status, { error: { code, message } })\n}\n\n/**\n * Returns true when `Origin` header and request URL host match (RFC 6454\n * same-origin check). Web-Standards counterpart of `originMatchesHost`.\n */\nfunction originMatchesHostFromRequest(request: Request): boolean {\n const origin = request.headers.get('origin')\n if (origin === null || origin.length === 0) return false\n const host = request.headers.get('host')\n if (host === null || host.length === 0) {\n // Fallback: derive host from request.url (Web Request guarantees absolute URL)\n try {\n const reqHost = new URL(request.url).host\n const originHost = new URL(origin).host\n return originHost === reqHost\n } catch {\n return false\n }\n }\n try {\n return new URL(origin).host === host\n } catch {\n return false\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/require-await -- async return for future telemetry hooks\nexport async function handleCsrfReadinessRequest(\n request: Request,\n store: CsrfReadinessStore,\n): Promise<Response | null> {\n const url = new URL(request.url).pathname\n const method = request.method.toUpperCase()\n\n if (url === CSRF_READINESS_PATH) {\n if (method === 'GET') {\n return buildJsonResponse(200, store.summary())\n }\n return buildErrorResponse(405, 'METHOD_NOT_ALLOWED', `Use GET on ${CSRF_READINESS_PATH}`)\n }\n\n if (url === CSRF_READINESS_RESET_PATH) {\n if (method !== 'POST') {\n return buildErrorResponse(\n 405,\n 'METHOD_NOT_ALLOWED',\n `Use POST on ${CSRF_READINESS_RESET_PATH}`,\n )\n }\n // Enforce CSRF on our own endpoint (dog-food).\n const hasHeader = request.headers.get('x-theo-action') === '1'\n if (!hasHeader || !originMatchesHostFromRequest(request)) {\n return buildErrorResponse(\n 403,\n 'CSRF_INVALID',\n 'Reset requires X-Theo-Action: 1 + same-origin',\n )\n }\n store.reset()\n return new Response(null, { status: 204 })\n }\n\n return null\n}\n","/**\n * T2.2 — In-memory bounded counter for CSRF warn events.\n *\n * Aggregates `csrf.warn` payloads by `(method, path, reason)` triple.\n * Used by the `/__theo/csrf-readiness` endpoint to expose a summary the\n * developer (or devtools tab) can inspect, so users do NOT need to grep\n * stdout to know which endpoints will break under 0.3.0 strict CSRF.\n *\n * Bounded at 1000 distinct keys (EC-22). Eviction is LRU-by-insertion —\n * when the cap is hit, the oldest key is dropped and a re-record of an\n * evicted key starts fresh (count: 1).\n *\n * Single-threaded by virtue of the JS event loop; Map operations are\n * atomic. NOT shared across processes — each worker has its own store.\n */\n\nexport interface CsrfWarnRecord {\n method: string\n path: string\n reason: string\n}\n\nexport interface CsrfReadinessRouteSummary {\n method: string\n path: string\n reason: string\n count: number\n firstSeen: string\n lastSeen: string\n}\n\nexport interface CsrfReadinessSummary {\n generatedAt: string\n totalEvents: number\n routes: CsrfReadinessRouteSummary[]\n}\n\ninterface StoredEntry {\n count: number\n firstSeen: string\n lastSeen: string\n}\n\nexport class CsrfReadinessStore {\n static readonly MAX_ENTRIES = 1000\n private readonly entries = new Map<string, StoredEntry>()\n\n private keyFor(event: CsrfWarnRecord): string {\n return `${event.method}\u0000${event.path}\u0000${event.reason}`\n }\n\n record(event: CsrfWarnRecord): void {\n const key = this.keyFor(event)\n const now = new Date().toISOString()\n const existing = this.entries.get(key)\n if (existing) {\n existing.count++\n existing.lastSeen = now\n return\n }\n if (this.entries.size >= CsrfReadinessStore.MAX_ENTRIES) {\n const firstKey = this.entries.keys().next().value\n if (firstKey !== undefined) this.entries.delete(firstKey)\n }\n this.entries.set(key, { count: 1, firstSeen: now, lastSeen: now })\n }\n\n summary(): CsrfReadinessSummary {\n let total = 0\n const routes: CsrfReadinessRouteSummary[] = []\n for (const [key, entry] of this.entries) {\n const [method, path, reason] = key.split('\u0000')\n routes.push({\n method,\n path,\n reason,\n count: entry.count,\n firstSeen: entry.firstSeen,\n lastSeen: entry.lastSeen,\n })\n total += entry.count\n }\n return {\n generatedAt: new Date().toISOString(),\n totalEvents: total,\n routes,\n }\n }\n\n reset(): void {\n this.entries.clear()\n }\n}\n","import type { ServerResponse } from 'node:http'\n\n/**\n * Phase 6 — Default Security Headers (D4 / EC-2).\n *\n * Per-response security baseline. The framework applies these BEFORE the\n * route handler runs so a handler can still override via `res.setHeader`.\n *\n * EC-2 backward-compatibility: CSP ships in `report-only` mode by default\n * for 0.2.0. Existing apps with inline scripts or third-party CDN scripts\n * keep working but consumers see violation reports via their CSP report\n * collector (or browser DevTools). 0.3.0 will flip the default to\n * `enforce` after a release of visibility.\n */\n\n/**\n * Default Content-Security-Policy. Conservative-but-not-paralyzing:\n *\n * - default-src 'self' — every fetch falls back to same-origin\n * - script-src 'self' — T6.1 (0.3.0): `'unsafe-inline'`\n * dropped. The SSR pipeline issues a\n * per-request nonce that REPLACES\n * this directive at runtime\n * (`'nonce-<token>'`). For static /\n * non-SSR contexts where no nonce is\n * available, the policy is strict-\n * no-inline — user inline scripts\n * must be migrated to external\n * `<script src=\"...\">` or threaded\n * through `ctx.nonce`.\n * - style-src 'self' 'unsafe-inline' — Tailwind + TheoUI use style attrs\n * in animation directives\n * - img-src 'self' data: blob: — supports inline data URIs, blobs\n * from canvas exports\n * - font-src 'self' data: — Geist fonts inline-base64\n * - connect-src 'self' ws: wss: — WebSocket dev HMR + agent streams\n * - frame-ancestors 'none' — clickjacking defense\n */\n/**\n * T5.1 — default CSP includes the built-in report endpoint so violations\n * are visible without extra config. Apps that ship a custom `csp` string\n * override the report-uri.\n */\nexport const DEFAULT_CSP =\n \"default-src 'self'; \" +\n \"script-src 'self'; \" +\n \"style-src 'self' 'unsafe-inline'; \" +\n \"img-src 'self' data: blob:; \" +\n \"font-src 'self' data:; \" +\n \"connect-src 'self' ws: wss:; \" +\n \"frame-ancestors 'none'; \" +\n 'report-uri /__theo/csp-report'\n\n/**\n * T1.1 — Default Permissions-Policy header (default-deny stance).\n *\n * Disables sensitive Web APIs that the vast majority of apps don't use.\n * Apps that DO need any of these opt in by overriding `permissionsPolicy`\n * in `config.security.headers`.\n *\n * The seven features listed are the most-abused for: tracking\n * (geolocation, accelerometer, gyroscope), spyware (camera, microphone),\n * fraud (payment), and hardware exfiltration (usb).\n *\n * Aligns with Mozilla baseline + OWASP Secure Headers + Lighthouse PWA.\n */\nexport const DEFAULT_PERMISSIONS_POLICY =\n 'geolocation=(), camera=(), microphone=(), payment=(), usb=(), accelerometer=(), gyroscope=()'\n\nexport type CspMode = 'enforce' | 'report-only' | 'off'\n\nexport interface SecurityHeadersConfig {\n /**\n * Custom CSP policy string. When set, replaces the default verbatim.\n * Pass `false` to disable CSP entirely (alias for `cspMode: 'off'`).\n */\n csp?: string | false\n /**\n * Enforcement mode for CSP. Default `report-only` for 0.2.0 (EC-2).\n * 0.3.0 will default to `enforce`.\n */\n cspMode?: CspMode\n /**\n * Strict-Transport-Security value. Defaults to\n * `max-age=31536000; includeSubDomains` in production. Pass `false` to\n * suppress (e.g. internal LANs without TLS).\n */\n hsts?: string | false\n /** X-Frame-Options. Default DENY. */\n frameOptions?: 'DENY' | 'SAMEORIGIN'\n /** X-Content-Type-Options. Default `nosniff`. */\n contentTypeOptions?: 'nosniff'\n /** Referrer-Policy. Default `strict-origin-when-cross-origin`. */\n referrerPolicy?: string\n /**\n * T1.1 — Permissions-Policy directive string. When set, replaces the\n * default verbatim (no merge — see ADR-EC-12). Pass `false` to disable\n * the header entirely. Schema-level refinement rejects any string\n * containing CR/LF (EC-3 — CWE-113 HTTP Response Splitting mitigation).\n */\n permissionsPolicy?: string | false\n}\n\nexport interface SecurityEnv {\n production: boolean\n}\n\n/**\n * T4.1 — Per-request options passed by the SSR pipeline.\n *\n * - `nonce`: when set, the framework substitutes the `'unsafe-inline'`\n * token in `script-src` with `'nonce-<nonce>'`. EC-3 forces\n * `Cache-Control: private, no-store` so a CDN cannot cache the HTML\n * (carrying one nonce) and re-serve it with a freshly-generated CSP\n * header (carrying a different nonce).\n * - `prerender`: when true, the nonce is IGNORED. Prerendered HTML is\n * generated at build time with no nonce in the script tags; mixing a\n * runtime nonce in the header would block every script. EC-4.\n */\nexport interface SecurityHeadersOptions {\n nonce?: string\n prerender?: boolean\n}\n\nconst DEFAULT_HSTS = 'max-age=31536000; includeSubDomains'\n\n/**\n * Apply a nonce to the script-src directive of an existing CSP policy\n * string. Replaces `'unsafe-inline'` (if present) with `'nonce-<value>'`;\n * otherwise appends the nonce directive to the script-src line.\n */\nfunction applyNonceToCsp(policy: string, nonce: string): string {\n return policy\n .split(';')\n .map((directive) => {\n const trimmed = directive.trim()\n if (!trimmed.startsWith('script-src')) return directive\n if (trimmed.includes(\"'unsafe-inline'\")) {\n return directive.replace(\"'unsafe-inline'\", `'nonce-${nonce}'`)\n }\n return `${directive} 'nonce-${nonce}'`\n })\n .join(';')\n}\n\n/**\n * Apply Content-Security-Policy header(s) to `out`. Extracted from\n * `buildSecurityHeaders` to keep that function's complexity within ceiling.\n * Handles the four shapes:\n * csp: false → opt out\n * cspMode: 'off' → opt out\n * cspMode: 'enforce' → Content-Security-Policy (T6.1 default for 0.3.0)\n * cspMode: 'report-only' → Content-Security-Policy-Report-Only (legacy 0.2.x)\n */\nfunction applyCsp(\n out: Record<string, string>,\n config: SecurityHeadersConfig,\n effectiveNonce: string | undefined,\n): void {\n if (config.csp === false || config.cspMode === 'off') return\n let policy = typeof config.csp === 'string' ? config.csp : DEFAULT_CSP\n if (effectiveNonce) {\n policy = applyNonceToCsp(policy, effectiveNonce)\n }\n // T6.1 — default flipped from 'report-only' to 'enforce' for 0.3.0.\n const mode: CspMode = config.cspMode ?? 'enforce'\n if (mode === 'enforce') {\n out['Content-Security-Policy'] = policy\n } else {\n out['Content-Security-Policy-Report-Only'] = policy\n }\n}\n\n/**\n * Build the security headers map for a given config + env. Pure function —\n * returned object can be inspected, logged, or applied to a response.\n */\nexport function buildSecurityHeaders(\n config: SecurityHeadersConfig,\n env: SecurityEnv,\n options: SecurityHeadersOptions = {},\n): Record<string, string> {\n const out: Record<string, string> = {}\n\n // EC-4: prerendered routes must NOT receive a nonce — the build-time\n // HTML carries no nonce, so a runtime nonce would mismatch.\n const effectiveNonce = options.prerender ? undefined : options.nonce\n\n applyCsp(out, config, effectiveNonce)\n\n // X-Frame-Options\n out['X-Frame-Options'] = config.frameOptions ?? 'DENY'\n\n // X-Content-Type-Options\n out['X-Content-Type-Options'] = config.contentTypeOptions ?? 'nosniff'\n\n // Referrer-Policy\n out['Referrer-Policy'] = config.referrerPolicy ?? 'strict-origin-when-cross-origin'\n\n // T1.1 — Permissions-Policy. Default-deny on geo/camera/mic/payment/usb;\n // configurable via `permissionsPolicy`; suppressed via `permissionsPolicy: false`.\n if (config.permissionsPolicy !== false) {\n out['Permissions-Policy'] =\n typeof config.permissionsPolicy === 'string'\n ? config.permissionsPolicy\n : DEFAULT_PERMISSIONS_POLICY\n }\n\n // HSTS — production only, suppressible via hsts: false\n if (env.production && config.hsts !== false) {\n out['Strict-Transport-Security'] = typeof config.hsts === 'string' ? config.hsts : DEFAULT_HSTS\n }\n\n // EC-3: when a nonce is in play, the response carries a one-shot CSP\n // header AND inline scripts in the HTML body. A CDN that caches the\n // HTML and proxies a fresh CSP per request would block every script\n // (nonces wouldn't match). Force no-store to prevent that class of\n // silent prod-only failure. Prerendered routes (which carry no nonce\n // by design — EC-4) are exempt; their HTML is meant to be cacheable.\n if (effectiveNonce) {\n out['Cache-Control'] = 'private, no-store'\n }\n\n return out\n}\n\n/**\n * Apply security headers to a Node ServerResponse. Called by the\n * api-middleware before the route handler runs. The handler can override\n * any header via `res.setHeader()` — last write wins by Node convention.\n */\nexport function applySecurityHeaders(\n res: ServerResponse,\n config: SecurityHeadersConfig,\n env: SecurityEnv,\n options: SecurityHeadersOptions = {},\n): void {\n const headers = buildSecurityHeaders(config, env, options)\n for (const [key, value] of Object.entries(headers)) {\n res.setHeader(key, value)\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=chunk-JHEAWR3L.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server/define/define-route.ts","../src/server/define/route-builder.ts","../src/server/define/define-action.ts","../src/server/define/action-builder.ts","../src/server/define/define-websocket.ts","../src/server/define/websocket-builder.ts","../src/server/define/define-middleware.ts","../src/server/define/middleware-builder.ts","../src/server/define/tool-builder.ts","../src/server/plugin-types.ts","../src/server/define/plugin-builder.ts","../src/server/define/ui-message-stream-response.ts","../src/server/define/define-channel.ts"],"sourcesContent":["import type { z } from 'zod'\n\n// T2.2 (architecture-cleanup) — RouteConfig type moved to core/contracts/\n// (canonical home per ADR-0001 v3). Re-export preserves the public path\n// `import { type RouteConfig } from 'theokit/server'`.\nexport type { RouteConfig } from '../../core/contracts/route-config.js'\n\nimport type { RouteConfig } from '../../core/contracts/route-config.js'\n\n/**\n * Define a typed HTTP route.\n * Identity function — provides type inference for route handlers.\n */\nexport function defineRoute<\n TQuery extends z.ZodType = z.ZodUndefined,\n TBody extends z.ZodType = z.ZodUndefined,\n TParams extends z.ZodType = z.ZodUndefined,\n TCtx = unknown,\n TResponse = unknown,\n>(\n config: RouteConfig<TQuery, TBody, TParams, TCtx, TResponse>,\n): RouteConfig<TQuery, TBody, TParams, TCtx, TResponse> {\n return config\n}\n","/**\n * M31 Phase 3 — `route()`, the fluent builder that replaces `defineRoute({...})`.\n *\n * Pure type-state (mirrors `tool-builder.ts`). `.query/.body/.params` set Zod schemas whose\n * `z.infer<>` flows into the handler's `ctx`; `.handler()` is required before `.build()`. `.build()`\n * delegates to the internal {@link defineRoute} (an identity fn), emitting the identical\n * `RouteConfig` — the scan/execute path is UNCHANGED (identity-shape delegation, blueprint §2).\n *\n * export const POST = route()\n * .params(z.object({ id: z.string() }))\n * .body(z.object({ text: z.string() }))\n * .handler(({ params, body }) => save(params.id, body.text))\n * .build()\n */\nimport type { z } from 'zod'\n\nimport type { RouteConfig } from '../../core/contracts/route-config.js'\n\nimport { defineRoute } from './define-route.js'\n\n/** Compile-error carrier: `.build()` called before `.handler()`. */\ninterface MissingHandlerError {\n readonly __theokitError: 'a route needs .handler(fn) before .build()'\n}\n\n/**\n * The fluent route builder. `TQuery/TBody/TParams` track the input schemas (default `z.ZodUndefined`,\n * matching {@link RouteConfig}); `TResponse` tracks the handler return; `THandlerSet` gates `.build()`.\n */\nexport interface RouteBuilder<\n TQuery extends z.ZodType = z.ZodUndefined,\n TBody extends z.ZodType = z.ZodUndefined,\n TParams extends z.ZodType = z.ZodUndefined,\n TCtx = unknown,\n TResponse = unknown,\n THandlerSet extends boolean = false,\n> {\n /** Set the URL search-params schema. Inferred into `ctx.query`. */\n query<S extends z.ZodType>(\n schema: S,\n ): RouteBuilder<S, TBody, TParams, TCtx, TResponse, THandlerSet>\n /** Set the request-body schema. Inferred into `ctx.body`. */\n body<S extends z.ZodType>(\n schema: S,\n ): RouteBuilder<TQuery, S, TParams, TCtx, TResponse, THandlerSet>\n /** Set the path-params schema. Inferred into `ctx.params`. */\n params<S extends z.ZodType>(\n schema: S,\n ): RouteBuilder<TQuery, TBody, S, TCtx, TResponse, THandlerSet>\n /** Runtime-only validation of the handler's plain-object return (500 on mismatch). Not inferred (YAGNI). */\n response(schema: z.ZodType): RouteBuilder<TQuery, TBody, TParams, TCtx, TResponse, THandlerSet>\n /** Override the HTTP status for a plain-object return (default 200; 204 for void). */\n status(code: number): RouteBuilder<TQuery, TBody, TParams, TCtx, TResponse, THandlerSet>\n /** Opt out of CSRF enforcement for this route (webhooks / OAuth callbacks). */\n csrf(disabled: false): RouteBuilder<TQuery, TBody, TParams, TCtx, TResponse, THandlerSet>\n /**\n * Set the handler. Its `ctx` infers `query/body/params` from the schemas set above. Required\n * before `.build()`.\n */\n handler<R>(\n fn: (ctx: {\n query: z.infer<TQuery>\n body: z.infer<TBody>\n params: z.infer<TParams>\n request: Request\n ctx: TCtx\n }) => R | Promise<R>,\n ): RouteBuilder<TQuery, TBody, TParams, TCtx, R, true>\n /**\n * Resolve to the `RouteConfig` — the SAME value `defineRoute({...})` returns. COMPILE ERROR when\n * `.handler()` was never called.\n */\n build(\n ...guard: THandlerSet extends true ? [] : [error: MissingHandlerError]\n ): RouteConfig<TQuery, TBody, TParams, TCtx, TResponse>\n}\n\n/**\n * Permissive internal shape — the runtime seam works with `z.ZodType` schemas (ctx fields typed\n * `unknown`); the precise per-schema types are carried to callers by the {@link RouteBuilder}\n * interface via the `as unknown as RouteBuilder` bridge. `defineRoute` is an identity fn.\n */\ntype AnyRouteConfig = RouteConfig<z.ZodType, z.ZodType, z.ZodType>\n\ninterface RouteSpecAccumulator {\n query?: z.ZodType\n body?: z.ZodType\n params?: z.ZodType\n response?: z.ZodType\n status?: number\n csrf?: false\n handler?: AnyRouteConfig['handler']\n}\n\nfunction makeRouteBuilder(spec: RouteSpecAccumulator): RouteBuilder {\n const runtime = {\n query: (schema: z.ZodType) => makeRouteBuilder({ ...spec, query: schema }),\n body: (schema: z.ZodType) => makeRouteBuilder({ ...spec, body: schema }),\n params: (schema: z.ZodType) => makeRouteBuilder({ ...spec, params: schema }),\n response: (schema: z.ZodType) => makeRouteBuilder({ ...spec, response: schema }),\n status: (code: number) => makeRouteBuilder({ ...spec, status: code }),\n csrf: (disabled: false) => makeRouteBuilder({ ...spec, csrf: disabled }),\n handler: (fn: AnyRouteConfig['handler']) => makeRouteBuilder({ ...spec, handler: fn }),\n build: (): AnyRouteConfig => {\n // Fail-fast for untyped (JS) callers — the type-state guard makes this unreachable from TS.\n if (spec.handler === undefined) {\n throw new Error('route(): call .handler(fn) before .build()')\n }\n const config: AnyRouteConfig = {\n ...(spec.query !== undefined ? { query: spec.query } : {}),\n ...(spec.body !== undefined ? { body: spec.body } : {}),\n ...(spec.params !== undefined ? { params: spec.params } : {}),\n ...(spec.response !== undefined ? { response: spec.response } : {}),\n ...(spec.status !== undefined ? { status: spec.status } : {}),\n ...(spec.csrf !== undefined ? { csrf: spec.csrf } : {}),\n handler: spec.handler,\n }\n return defineRoute(config)\n },\n }\n return runtime as unknown as RouteBuilder\n}\n\n/**\n * Start a fluent route definition. Chain `.query/.body/.params/.response/.status/.csrf` (all\n * optional), then `.handler()` (required) and `.build()` for the `RouteConfig`.\n */\nexport function route(): RouteBuilder {\n return makeRouteBuilder({})\n}\n","import type { z } from 'zod'\n\n/**\n * Action wire-protocol accept mode per plan g3-server-actions-and-useaction\n * v1.2 ADR D1. Default behavior (when omitted) is `'json'`. `'form'` opts the\n * action into FormData multipart parsing for progressive-enhancement forms;\n * the runtime in `server/http/action-execute.ts` will coerce FormData entries\n * against the `input` schema via `formDataToObject` (Astro pattern).\n */\nexport type ActionAccept = 'form' | 'json'\n\nexport interface ActionConfig<TInput extends z.ZodType, TCtx = unknown> {\n /**\n * Zod input schema. Required: every action declares its input contract via\n * Zod (architecture rule: zod-is-SSOT). The shape becomes the handler's\n * typed `input` parameter via `z.infer<TInput>`.\n */\n input: TInput\n /**\n * Wire-protocol accept mode. Defaults to `'json'` when omitted. Setting\n * `'form'` switches the runtime to FormData multipart parsing — the input\n * schema MUST be `z.object(...)` so field-by-field coercion can drive\n * boolean string / number / array coercion (Astro pattern).\n */\n accept?: ActionAccept\n /**\n * Opt OUT of CSRF enforcement for this action. Default (omitted) keeps the\n * multi-header CSRF gate active. Set `false` for endpoints intentionally\n * callable without the `X-Theo-Action` header (e.g. public webhooks). The\n * runtime in `server/http/action-execute.ts` reads this flag.\n */\n csrf?: false\n handler: (ctx: { input: z.infer<TInput>; ctx: TCtx }) => unknown\n}\n\n/**\n * Define a typed server action.\n *\n * Identity function — provides type inference for action handlers. The\n * runtime that consumes the config (validation + invocation + serialization)\n * lives in `server/http/action-execute.ts`.\n *\n * Per plan g3-server-actions-and-useaction v1.2 § Phase 1 / T1.2: the new\n * `accept?: 'form' | 'json'` field is the only contract change vs the\n * pre-G3 identity. Existing callsites (`defineAction({input, handler})`)\n * continue to compile — `accept` is opt-in.\n */\nexport function defineAction<TInput extends z.ZodType, TCtx = unknown>(\n config: ActionConfig<TInput, TCtx>,\n): ActionConfig<TInput, TCtx> {\n return config\n}\n","/**\n * M31 Phase 3 — `action()`, the fluent builder that replaces `defineAction({...})`.\n *\n * Pure type-state (mirrors `route-builder.ts`). `.input()` (required) sets the Zod schema whose\n * `z.infer<>` types the handler's `ctx.input`; `.handler()` (required) closes the chain. `.build()`\n * delegates to the internal {@link defineAction} (identity) — the action-execute path is UNCHANGED.\n *\n * export const createUser = action()\n * .input(z.object({ email: z.string().email() }))\n * .handler(({ input }) => createUser(input.email))\n * .build()\n */\nimport type { z } from 'zod'\n\nimport { defineAction, type ActionConfig, type ActionAccept } from './define-action.js'\n\n/** Compile-error carrier: `.execute`/`.build()` reached before `.input()`. */\ninterface MissingInputError {\n readonly __theokitError: 'call .input(schema) before .handler(fn)'\n}\n/** Compile-error carrier: `.build()` before both `.input()` and `.handler()` are set. */\ninterface IncompleteActionError {\n readonly __theokitError: 'an action needs .input(schema) and .handler(fn) before .build()'\n}\n\n/** A required-but-unset field. Branded so no ordinary value satisfies it (tRPC UnsetMarker). */\ntype UnsetMarker = 'theokit.unset' & { readonly __brand: 'theokit.unset' }\n\n/**\n * The fluent action builder. `TInput` tracks the Zod schema (drives `ctx.input` inference);\n * `THandlerSet` gates `.build()`.\n */\nexport interface ActionBuilder<\n TInput extends z.ZodType | UnsetMarker = UnsetMarker,\n TCtx = unknown,\n THandlerSet extends boolean = false,\n> {\n /** Set the Zod input schema. Required — every action declares its input contract (zod-is-SSOT). */\n input<S extends z.ZodType>(schema: S): ActionBuilder<S, TCtx, THandlerSet>\n /** Wire-protocol accept mode (`'json'` default, `'form'` for FormData multipart). */\n accept(mode: ActionAccept): ActionBuilder<TInput, TCtx, THandlerSet>\n /** Opt out of CSRF enforcement for this action. */\n csrf(disabled: false): ActionBuilder<TInput, TCtx, THandlerSet>\n /**\n * Set the handler. COMPILE ERROR before `.input()` — the param type collapses to\n * {@link MissingInputError}. `ctx.input` is inferred via `z.infer<TInput>`.\n */\n handler(\n fn: TInput extends z.ZodType\n ? (ctx: { input: z.infer<TInput>; ctx: TCtx }) => unknown\n : MissingInputError,\n ): ActionBuilder<TInput, TCtx, true>\n /**\n * Resolve to the `ActionConfig` — the SAME value `defineAction({...})` returns. COMPILE ERROR when\n * `.input()` or `.handler()` was never called.\n */\n build(\n ...guard: THandlerSet extends true\n ? TInput extends z.ZodType\n ? []\n : [error: IncompleteActionError]\n : [error: IncompleteActionError]\n ): ActionConfig<TInput extends z.ZodType ? TInput : z.ZodType, TCtx>\n}\n\ntype AnyActionConfig = ActionConfig<z.ZodType>\n\ninterface ActionSpecAccumulator {\n input?: z.ZodType\n accept?: ActionAccept\n csrf?: false\n handler?: AnyActionConfig['handler']\n}\n\nfunction makeActionBuilder(spec: ActionSpecAccumulator): ActionBuilder {\n const runtime = {\n input: (schema: z.ZodType) => makeActionBuilder({ ...spec, input: schema }),\n accept: (mode: ActionAccept) => makeActionBuilder({ ...spec, accept: mode }),\n csrf: (disabled: false) => makeActionBuilder({ ...spec, csrf: disabled }),\n handler: (fn: AnyActionConfig['handler']) => makeActionBuilder({ ...spec, handler: fn }),\n build: (): AnyActionConfig => {\n // Fail-fast for untyped (JS) callers — the type-state guards make this unreachable from TS.\n if (spec.input === undefined) {\n throw new Error('action(): call .input(schema) before .build()')\n }\n if (spec.handler === undefined) {\n throw new Error('action(): call .handler(fn) before .build()')\n }\n const config: AnyActionConfig = {\n input: spec.input,\n handler: spec.handler,\n ...(spec.accept !== undefined ? { accept: spec.accept } : {}),\n ...(spec.csrf !== undefined ? { csrf: spec.csrf } : {}),\n }\n return defineAction(config)\n },\n }\n return runtime as unknown as ActionBuilder\n}\n\n/**\n * Start a fluent action definition. Chain `.input()` (required), optionally `.accept()` / `.csrf()`,\n * then `.handler()` (required) and `.build()` for the `ActionConfig`.\n */\nexport function action(): ActionBuilder {\n return makeActionBuilder({})\n}\n","import type { IncomingMessage } from 'node:http'\n\nexport interface WebSocketLike {\n send(data: string | Buffer): void\n close(code?: number, reason?: string): void\n}\n\nexport interface WebSocketHandler {\n onOpen?: (ws: WebSocketLike, req: IncomingMessage) => void\n onMessage?: (ws: WebSocketLike, data: string | Buffer) => void\n onClose?: (ws: WebSocketLike, code: number, reason: Buffer) => void\n onError?: (ws: WebSocketLike, error: Error) => void\n}\n\n/**\n * Define a WebSocket endpoint handler.\n * Identity function — provides type inference for WebSocket handlers.\n */\nexport function defineWebSocket(handler: WebSocketHandler): WebSocketHandler {\n return handler\n}\n\n/**\n * T5a.2 Phase F slice 3/3 — Web-Standards WebSocket endpoint handler.\n *\n * Mirror of `WebSocketHandler` for the Web `Request` shape. `onOpen`\n * receives `request: Request` instead of `req: IncomingMessage`. The\n * rest of the lifecycle (onMessage, onClose, onError) is shape-agnostic\n * (`WebSocketLike` is already Web-standards-compatible per the existing\n * design — `send(string | Buffer)` works on both Node `ws` and Web\n * `WebSocket` instances; CF Workers / Bun / Deno coerce as needed at\n * the adapter boundary).\n *\n * Per `docs/plans/t5a2-incoming-message-to-request-shape-refactor-plan.md`\n * v1.0 § Phase F (closes Phase F).\n *\n * **Architectural note — WebSocket upgrade semantics differ across runtimes:**\n * - Node + `ws`: `WebSocketServer.handleUpgrade(req, socket, head, cb)` —\n * `req` is `IncomingMessage`. Use `WebSocketHandler`.\n * - CF Workers: `new WebSocketPair()` + `request.headers` (the upgrade\n * handshake IS a Web Request). Use `WebSocketHandlerWeb`.\n * - Bun: `server.upgrade(request, { data })` — same Web Request shape.\n * - Deno: `Deno.upgradeWebSocket(request)` — same Web Request shape.\n *\n * Cross-runtime WebSocket endpoints ship BOTH `WebSocketHandler` +\n * `WebSocketHandlerWeb` exports; the runtime adapter picks the matching\n * one. This is the canonical Hono / Nitric pattern.\n */\nexport interface WebSocketHandlerWeb {\n onOpen?: (ws: WebSocketLike, request: Request) => void\n onMessage?: (ws: WebSocketLike, data: string | Uint8Array) => void\n onClose?: (ws: WebSocketLike, code: number, reason: string) => void\n onError?: (ws: WebSocketLike, error: Error) => void\n}\n\n/**\n * Web-Standards `defineWebSocket` sibling. Identity function — provides\n * type inference for Web WebSocket handlers.\n *\n * **Type difference note vs Node path:**\n * - `onMessage` data is `string | Uint8Array` instead of `string | Buffer`\n * (Web standards have no `Buffer`; Node's Buffer is a Uint8Array\n * subclass so the Node path's Buffer values flow through unchanged\n * when adapters wrap them).\n * - `onClose` reason is `string` instead of `Buffer` (Web `CloseEvent`\n * exposes the reason as a UTF-8 string natively).\n */\nexport function defineWebSocketWeb(handler: WebSocketHandlerWeb): WebSocketHandlerWeb {\n return handler\n}\n","/**\n * M31 Phase 3 — `websocket()`, the fluent builder that replaces `defineWebSocket({...})`.\n *\n * Lifecycle setters (`onOpen/onMessage/onClose/onError`), all optional; `.build()` delegates to the\n * internal {@link defineWebSocket} (identity) — the ws handler loading path is UNCHANGED.\n *\n * export default websocket()\n * .onOpen((ws) => ws.send('hi'))\n * .onMessage((ws, data) => ws.send(`echo:${data}`))\n * .build()\n */\nimport { defineWebSocket, type WebSocketHandler } from './define-websocket.js'\n\n/** The fluent WebSocket builder. Each lifecycle hook is optional; `.build()` returns the handler. */\nexport interface WebSocketBuilder {\n onOpen(fn: NonNullable<WebSocketHandler['onOpen']>): WebSocketBuilder\n onMessage(fn: NonNullable<WebSocketHandler['onMessage']>): WebSocketBuilder\n onClose(fn: NonNullable<WebSocketHandler['onClose']>): WebSocketBuilder\n onError(fn: NonNullable<WebSocketHandler['onError']>): WebSocketBuilder\n /** Resolve to the `WebSocketHandler` — the SAME value `defineWebSocket({...})` returns. */\n build(): WebSocketHandler\n}\n\nfunction makeWebSocketBuilder(spec: WebSocketHandler): WebSocketBuilder {\n const runtime: WebSocketBuilder = {\n onOpen: (fn) => makeWebSocketBuilder({ ...spec, onOpen: fn }),\n onMessage: (fn) => makeWebSocketBuilder({ ...spec, onMessage: fn }),\n onClose: (fn) => makeWebSocketBuilder({ ...spec, onClose: fn }),\n onError: (fn) => makeWebSocketBuilder({ ...spec, onError: fn }),\n build: () => defineWebSocket(spec),\n }\n return runtime\n}\n\n/** Start a fluent WebSocket definition. Chain any of the lifecycle hooks, then `.build()`. */\nexport function websocket(): WebSocketBuilder {\n return makeWebSocketBuilder({})\n}\n","export type MiddlewareHandler = (\n request: Request,\n next: (request: Request) => Promise<Response>,\n) => Response | Promise<Response>\n\n/**\n * Define a middleware handler.\n * Identity function — provides type annotation for middleware.\n */\nexport function defineMiddleware(handler: MiddlewareHandler): MiddlewareHandler {\n return handler\n}\n","/**\n * M31 Phase 3 — `middleware()`, the fluent builder that replaces `defineMiddleware(fn)`.\n *\n * A middleware IS a single function `(request, next) => Response`. The builder's `.handle()` sets it\n * (required); `.build()` delegates to the internal {@link defineMiddleware} (identity) and returns\n * the handler the runtime expects.\n *\n * export default middleware()\n * .handle(async (request, next) => {\n * const res = await next(request)\n * res.headers.set('x-mw', '1')\n * return res\n * })\n * .build()\n */\nimport { defineMiddleware, type MiddlewareHandler } from './define-middleware.js'\n\n/** Compile-error carrier: `.build()` called before `.handle()`. */\ninterface MissingHandleError {\n readonly __theokitError: 'middleware needs .handle(fn) before .build()'\n}\n\n/** The fluent middleware builder. `THandleSet` gates `.build()`. */\nexport interface MiddlewareBuilder<THandleSet extends boolean = false> {\n /** Set the `(request, next) => Response` handler. Required before `.build()`. */\n handle(fn: MiddlewareHandler): MiddlewareBuilder<true>\n /** Resolve to the `MiddlewareHandler`. COMPILE ERROR when `.handle()` was never called. */\n build(...guard: THandleSet extends true ? [] : [error: MissingHandleError]): MiddlewareHandler\n}\n\nfunction makeMiddlewareBuilder(fn: MiddlewareHandler | undefined): MiddlewareBuilder {\n const runtime = {\n handle: (handler: MiddlewareHandler) => makeMiddlewareBuilder(handler),\n build: (): MiddlewareHandler => {\n // Fail-fast for untyped (JS) callers — the type-state guard makes this unreachable from TS.\n if (fn === undefined) {\n throw new Error('middleware(): call .handle(fn) before .build()')\n }\n return defineMiddleware(fn)\n },\n }\n return runtime as unknown as MiddlewareBuilder\n}\n\n/** Start a fluent middleware definition. Chain `.handle()` (required), then `.build()`. */\nexport function middleware(): MiddlewareBuilder {\n return makeMiddlewareBuilder(undefined)\n}\n","/**\n * M31 Phase 1 — `tool()`, the fluent builder that replaces `defineAgentTool({...})`.\n *\n * Pure type-state (tRPC `UnsetMarker` technique, mirroring `agent-builder.ts`). The runtime is a\n * plain accumulator; `.build()` delegates to the internal {@link defineAgentTool}, so the emitted\n * `CustomTool` is byte-for-byte the legacy shape — the SDK/agent compile path is UNCHANGED\n * (identity-shape delegation, blueprint §2).\n *\n * PURE metadata (G2 / sdk-runtime.md): a tool describes a capability; it NEVER calls an LLM.\n *\n * tool('read')\n * .describe('Read a UTF-8 file')\n * .input(z.object({ path: z.string() }))\n * .execute(async ({ path }, ctx) => readFile(resolveInProject(ctx, path)))\n * .build()\n */\nimport type { z } from 'zod'\n\nimport { defineAgentTool, type CustomTool, type ToolTransform } from './define-agent-tool.js'\n\n/** A required-but-unset builder field. Branded so no ordinary value satisfies it (tRPC UnsetMarker). */\ntype UnsetMarker = 'theokit.unset' & { readonly __brand: 'theokit.unset' }\n\n/** Compile-error carrier: `.execute()` called before `.input()`. */\ninterface MissingInputError {\n readonly __theokitError: 'call .input(schema) before .execute(handler)'\n}\n/** Compile-error carrier: `.build()` called before both `.input()` and `.execute()` are set. */\ninterface IncompleteToolError {\n readonly __theokitError: 'a tool needs .input(schema) and .execute(handler) before .build()'\n}\n\n/** The run context a tool handler receives (M7). */\ninterface ToolCtx {\n signal?: AbortSignal\n context?: unknown\n}\n\n/**\n * The fluent tool builder. Each method returns a NEW builder type with the relevant type parameter\n * advanced. `TInput` tracks the Zod schema (drives `execute` input inference); `R` tracks the\n * handler result; `THandlerSet` gates `.build()`.\n */\nexport interface ToolBuilder<\n TName extends string = string,\n TInput extends z.ZodType | UnsetMarker = UnsetMarker,\n R = string,\n THandlerSet extends boolean = false,\n> {\n /** Set the LLM-facing description. Optional; an empty description warns at build (LLM selection). */\n describe(description: string): ToolBuilder<TName, TInput, R, THandlerSet>\n /** Set the Zod input schema (must be `z.object(...)` at the root). Required before `.execute()`. */\n input<S extends z.ZodType>(schema: S): ToolBuilder<TName, S, R, THandlerSet>\n /**\n * Set the handler. COMPILE ERROR when `.input()` was not called first — the parameter type\n * collapses to {@link MissingInputError}. The `input` argument is inferred via `z.infer<TInput>`.\n */\n execute<R2>(\n handler: TInput extends z.ZodType\n ? (input: z.infer<TInput>, ctx?: ToolCtx) => R2 | Promise<R2>\n : MissingInputError,\n ): ToolBuilder<TName, TInput, R2, true>\n /** M18 — map a rich handler result to the model-visible string. */\n toModelOutput(fn: (result: R) => string): ToolBuilder<TName, TInput, R, THandlerSet>\n /** M18 — per-target formatters (`display` / `transcript`) for the app UI/transcript. */\n transform(t: ToolTransform<R>): ToolBuilder<TName, TInput, R, THandlerSet>\n /**\n * Resolve to the `CustomTool` — the SAME value `defineAgentTool({...})` returns. COMPILE ERROR\n * when `.input()` or `.execute()` was never called.\n */\n build(\n ...guard: THandlerSet extends true\n ? TInput extends z.ZodType\n ? []\n : [error: IncompleteToolError]\n : [error: IncompleteToolError]\n ): CustomTool\n}\n\ninterface ToolSpecAccumulator {\n name: string\n description?: string\n inputSchema?: z.ZodType\n handler?: (input: unknown, ctx?: ToolCtx) => unknown\n toModelOutput?: (result: unknown) => string\n transform?: ToolTransform\n}\n\n/**\n * Build the runtime accumulator. The public method signatures carry the type-state generics + the\n * compile-time guards; the runtime cannot track generics, so the object is bridged to the typed\n * interface once here (the single, documented type-state impl seam — same technique as agent-builder).\n */\nfunction makeToolBuilder(spec: ToolSpecAccumulator): ToolBuilder {\n const runtime = {\n describe: (description: string) => makeToolBuilder({ ...spec, description }),\n input: (schema: z.ZodType) => makeToolBuilder({ ...spec, inputSchema: schema }),\n execute: (handler: (input: unknown, ctx?: ToolCtx) => unknown) =>\n makeToolBuilder({ ...spec, handler }),\n toModelOutput: (fn: (result: unknown) => string) =>\n makeToolBuilder({ ...spec, toModelOutput: fn }),\n transform: (t: ToolTransform) => makeToolBuilder({ ...spec, transform: t }),\n build: (): CustomTool => {\n // Fail-fast: the type-state guards make these unreachable from typed callers, but an untyped\n // (JS) caller could skip them — surface a clear error instead of a confusing downstream one.\n if (spec.inputSchema === undefined) {\n throw new Error(`tool(${JSON.stringify(spec.name)}): call .input(schema) before .build()`)\n }\n if (spec.handler === undefined) {\n throw new Error(\n `tool(${JSON.stringify(spec.name)}): call .execute(handler) before .build()`,\n )\n }\n return defineAgentTool({\n name: spec.name,\n description: spec.description ?? '',\n inputSchema: spec.inputSchema,\n handler: spec.handler,\n ...(spec.toModelOutput !== undefined ? { toModelOutput: spec.toModelOutput } : {}),\n ...(spec.transform !== undefined ? { transform: spec.transform } : {}),\n })\n },\n }\n return runtime as unknown as ToolBuilder\n}\n\n/**\n * Start a fluent tool definition. Chain `.input()` + `.execute()` (both required), optionally\n * `.describe()` / `.toModelOutput()` / `.transform()`, then `.build()` for the `CustomTool`.\n */\nexport function tool<TName extends string>(name: TName): ToolBuilder<TName> {\n return makeToolBuilder({ name })\n}\n","import type { ServerResponse } from 'node:http'\n\nexport interface PluginContext {\n /**\n * The incoming request as a Web `Request` — the same shape a plugin hook sees on the edge adapters\n * (`WebPluginContext.request`), so a hook that reads `request.headers.get(...)` / `request.url` /\n * `request.method` is portable across `theokit dev` / `theokit start` (Node) and Web runtimes (#119,\n * ADR-0028 R3a). Method + absolute URL + headers; the request body is not exposed here (onRequest /\n * preHandler fire before the body is parsed — the handler reads it via `ctx.body`).\n */\n request: Request\n response: ServerResponse\n ctx: Record<string, unknown>\n requestId: string\n}\n\nexport interface PluginErrorContext extends PluginContext {\n error: unknown\n}\n\nexport interface RunHookOptions {\n inErrorPath?: boolean\n}\n\nexport interface HookResult {\n shortCircuited: boolean\n}\n\nexport type OnRequestHook = (ctx: PluginContext) => void | Promise<void>\nexport type PreHandlerHook = (ctx: PluginContext) => void | Promise<void>\nexport type OnResponseHook = (ctx: PluginContext) => void | Promise<void>\nexport type OnErrorHook = (ctx: PluginErrorContext) => void | Promise<void>\n\nexport type HookName = 'onRequest' | 'preHandler' | 'onResponse' | 'onError'\n\nexport type HookByName<K extends HookName> = K extends 'onError'\n ? OnErrorHook\n : K extends 'onRequest'\n ? OnRequestHook\n : K extends 'preHandler'\n ? PreHandlerHook\n : K extends 'onResponse'\n ? OnResponseHook\n : never\n\nexport interface TheoApp {\n addHook<K extends HookName>(name: K, fn: HookByName<K>): void\n // `T` lets plugin authors document the per-key shape of decorations.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- T documents the value type for plugin authors\n decorateRequest<T>(key: string, value: T): void\n}\n\nexport interface TheoPlugin {\n name: string\n register(app: TheoApp): void | Promise<void>\n}\n\n/**\n * Identity function for plugin authors. Provides auto-completion + type\n * inference at the call site (TanStack/Vite/Astro pattern). Pure runtime\n * no-op — returns the input unchanged.\n *\n * @example\n * import { definePlugin } from 'theokit/server'\n * export default definePlugin({\n * name: 'my-plugin',\n * register(app) {\n * app.addHook('onRequest', (req) => { ... })\n * },\n * })\n *\n * Equivalent to `const p: TheoPlugin = {...}` but more ergonomic. See\n * ADR-0008 (D1 + D6) for the rationale.\n */\nexport function definePlugin(plugin: TheoPlugin): TheoPlugin {\n return plugin\n}\n\n// ===== T5a.2 Phase F slice 1/3 — Web-Standards plugin context types =====\n//\n// Mirror of the IncomingMessage/ServerResponse-shaped `PluginContext` for\n// the Web `Request`/`Headers` shape. Per `docs/plans/t5a2-incoming-message-\n// to-request-shape-refactor-plan.md` v1.0 § Phase F.\n//\n// **Key difference vs IncomingMessage path:** the Web path has no\n// `ServerResponse` to mutate. Plugins instead get a `responseHeaders: Headers`\n// instance they can append to (e.g., add Set-Cookie, CORS headers) and the\n// runtime composes the final `Response` after the hook chain runs. The\n// `response` object (if any) is the in-flight Response constructed by the\n// handler — present only during `onResponse` / `onError` hooks AFTER the\n// handler returned, NOT during `onRequest` / `preHandler` (which fire BEFORE\n// the handler runs).\n//\n// This split mirrors Hono's `c.res` + Fastify's `reply.headers` semantics\n// — plugins mutate headers freely; the body is the handler's responsibility.\n\n/**\n * Web-Standards plugin context. Available during all 4 hook lifecycle\n * stages (onRequest, preHandler, onResponse, onError).\n *\n * - `request` — the incoming Web Request (read-only at the runtime level;\n * plugins can call `request.headers.get()`, `request.clone()`, etc.).\n * - `responseHeaders` — a mutable `Headers` instance the runtime threads\n * through the hook chain. Plugins append (e.g., CORS, Set-Cookie); the\n * final Response composes these.\n * - `response` — set to the handler's Response AFTER the handler returns.\n * Available during `onResponse` / `onError`. `undefined` during\n * `onRequest` / `preHandler` (which fire before the handler runs).\n * - `ctx` / `requestId` — same semantics as the IncomingMessage path.\n */\nexport interface WebPluginContext {\n request: Request\n responseHeaders: Headers\n response?: Response\n ctx: Record<string, unknown>\n requestId: string\n}\n\nexport interface WebPluginErrorContext extends WebPluginContext {\n error: unknown\n}\n\nexport type WebOnRequestHook = (ctx: WebPluginContext) => void | Promise<void>\nexport type WebPreHandlerHook = (ctx: WebPluginContext) => void | Promise<void>\nexport type WebOnResponseHook = (ctx: WebPluginContext) => void | Promise<void>\nexport type WebOnErrorHook = (ctx: WebPluginErrorContext) => void | Promise<void>\n\nexport type WebHookByName<K extends HookName> = K extends 'onError'\n ? WebOnErrorHook\n : K extends 'onRequest'\n ? WebOnRequestHook\n : K extends 'preHandler'\n ? WebPreHandlerHook\n : K extends 'onResponse'\n ? WebOnResponseHook\n : never\n\n/**\n * Web-Standards `TheoApp` facade. Same `addHook` + `decorateRequest`\n * surface as the IncomingMessage path; only the hook function signatures\n * differ (they receive `WebPluginContext` instead of `PluginContext`).\n *\n * Plugin authors who target both shapes can branch on the context type\n * via a type guard (`'responseHeaders' in ctx`) OR ship two separate\n * `register()` exports — one for each runtime adapter. Most plugins\n * register hooks at the IncomingMessage path today (legacy); future\n * Web-native plugins will register against `WebTheoApp`.\n */\nexport interface WebTheoApp {\n addHook<K extends HookName>(name: K, fn: WebHookByName<K>): void\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- T documents the value type for plugin authors\n decorateRequest<T>(key: string, value: T): void\n}\n\n/**\n * Web-Standards plugin shape. Identical to `TheoPlugin` except the\n * `register(app)` argument is `WebTheoApp` instead of `TheoApp`.\n *\n * Cross-runtime plugins ship BOTH `TheoPlugin` + `WebTheoPlugin` exports;\n * the adapter (Node, CF Workers, Bun, Deno) picks the matching one based\n * on which runtime executes the plugin chain. This is the canonical\n * Hono/Nitro pattern.\n */\nexport interface WebTheoPlugin {\n name: string\n register(app: WebTheoApp): void | Promise<void>\n}\n\n/**\n * Identity function for Web plugin authors — same auto-completion +\n * type-inference DX as `definePlugin`, but for the Web-shaped `WebTheoApp`.\n */\nexport function defineWebPlugin(plugin: WebTheoPlugin): WebTheoPlugin {\n return plugin\n}\n","/**\n * M31 Phase 3 — `plugin()`, the fluent builder that replaces `definePlugin({...})`.\n *\n * Collects lifecycle hooks + request decorations and SYNTHESIZES the `register(app)` function, so\n * authors never write the imperative `register` body. `.build()` returns a `TheoPlugin` the plugin\n * runner consumes UNCHANGED.\n *\n * export default plugin('request-id')\n * .onRequest((ctx) => { ctx.ctx.requestId = crypto.randomUUID() })\n * .onResponse((ctx) => { ctx.response.setHeader('x-request-id', String(ctx.ctx.requestId)) })\n * .build()\n */\nimport {\n definePlugin,\n type TheoPlugin,\n type TheoApp,\n type OnRequestHook,\n type PreHandlerHook,\n type OnResponseHook,\n type OnErrorHook,\n} from '../plugin-types.js'\n\n/** The fluent plugin builder. `name` is set at entry; every hook is optional and may repeat. */\nexport interface PluginBuilder {\n /** Register an `onRequest` hook (runs before the CSRF gate). May be called multiple times. */\n onRequest(fn: OnRequestHook): PluginBuilder\n /** Register a `preHandler` hook (after CSRF, before the route handler). */\n preHandler(fn: PreHandlerHook): PluginBuilder\n /** Register an `onResponse` hook (after the handler returns). */\n onResponse(fn: OnResponseHook): PluginBuilder\n /** Register an `onError` hook (error path). */\n onError(fn: OnErrorHook): PluginBuilder\n /** Decorate every request with a key/value pair (available on `ctx.ctx[key]`). */\n decorateRequest<T>(key: string, value: T): PluginBuilder\n /** Resolve to the `TheoPlugin` — a synthesized `{ name, register }` the runner consumes. */\n build(): TheoPlugin\n}\n\ninterface PluginSpecAccumulator {\n name: string\n onRequest: OnRequestHook[]\n preHandler: PreHandlerHook[]\n onResponse: OnResponseHook[]\n onError: OnErrorHook[]\n decorations: { key: string; value: unknown }[]\n}\n\nfunction makePluginBuilder(spec: PluginSpecAccumulator): PluginBuilder {\n const runtime: PluginBuilder = {\n onRequest: (fn) => makePluginBuilder({ ...spec, onRequest: [...spec.onRequest, fn] }),\n preHandler: (fn) => makePluginBuilder({ ...spec, preHandler: [...spec.preHandler, fn] }),\n onResponse: (fn) => makePluginBuilder({ ...spec, onResponse: [...spec.onResponse, fn] }),\n onError: (fn) => makePluginBuilder({ ...spec, onError: [...spec.onError, fn] }),\n decorateRequest: (key, value) =>\n makePluginBuilder({ ...spec, decorations: [...spec.decorations, { key, value }] }),\n build: () =>\n definePlugin({\n name: spec.name,\n register(app: TheoApp): void {\n for (const fn of spec.onRequest) app.addHook('onRequest', fn)\n for (const fn of spec.preHandler) app.addHook('preHandler', fn)\n for (const fn of spec.onResponse) app.addHook('onResponse', fn)\n for (const fn of spec.onError) app.addHook('onError', fn)\n for (const d of spec.decorations) app.decorateRequest(d.key, d.value)\n },\n }),\n }\n return runtime\n}\n\n/** Start a fluent plugin definition. `name` is required; chain hooks/decorations, then `.build()`. */\nexport function plugin(name: string): PluginBuilder {\n return makePluginBuilder({\n name,\n onRequest: [],\n preHandler: [],\n onResponse: [],\n onError: [],\n decorations: [],\n })\n}\n","import type { UIMessageChunk } from 'ai'\n\n/**\n * M0 (theokit-ai-first) — serialize a stream of ai-sdk `UIMessageChunk`s into a\n * Web-Standards `Response` on the UIMessageStream wire so `@ai-sdk/react`'s\n * `useChat` consumes it WITHOUT a custom adapter.\n *\n * Wire contract (must match ai-sdk's consumer transport exactly):\n * - `content-type: text/event-stream`\n * - `x-vercel-ai-ui-message-stream: v1` — the version marker `useChat` checks\n * - each chunk framed as `data: ${JSON.stringify(chunk)}\\n\\n`\n * - a terminal `data: [DONE]\\n\\n` after the last chunk (ignored by the parser)\n *\n * Web Standards only — `Response` + `ReadableStream` (G8, no node:http). The\n * headers commit before the stream starts.\n *\n * Fail-clear (error-handling.md): if the source iterable throws mid-stream, the\n * `[DONE]` terminal is still flushed and the stream is closed — never left\n * hanging. (The translator upstream already closes gracefully; this is defense\n * in depth for any other chunk source.)\n */\nconst UI_MESSAGE_STREAM_HEADERS = {\n 'content-type': 'text/event-stream',\n 'x-vercel-ai-ui-message-stream': 'v1',\n} as const\n\nconst DONE_FRAME = 'data: [DONE]\\n\\n'\n\nfunction encode(text: string): Uint8Array {\n return new TextEncoder().encode(text)\n}\n\nexport function uiMessageStreamResponse(chunks: AsyncIterable<UIMessageChunk>): Response {\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n try {\n for await (const chunk of chunks) {\n controller.enqueue(encode(`data: ${JSON.stringify(chunk)}\\n\\n`))\n }\n } catch {\n // The source iterable aborted mid-stream. The upstream translator owns\n // error semantics (it surfaces failures as chunks + closes gracefully);\n // this transport's sole guarantee is a terminated stream — fall through\n // to the DONE terminal rather than re-throw and error an open stream.\n } finally {\n controller.enqueue(encode(DONE_FRAME))\n controller.close()\n }\n },\n })\n return new Response(stream, { headers: UI_MESSAGE_STREAM_HEADERS })\n}\n","import type { IncomingMessage } from 'node:http'\n\nimport type { WebSocketLike } from './define-websocket.js'\n\nexport interface ChannelHandler<TMessage = unknown> {\n onSubscribe?: (ws: WebSocketLike, room: string, req: IncomingMessage) => void\n onMessage?: (ws: WebSocketLike, room: string, data: TMessage) => void\n onUnsubscribe?: (ws: WebSocketLike, room: string) => void\n}\n\n/**\n * Define a channel handler for WebSocket rooms.\n * Identity function — provides type inference for channel handlers.\n */\nexport function defineChannel<TMessage = unknown>(\n handler: ChannelHandler<TMessage>,\n): ChannelHandler<TMessage> {\n return handler\n}\n\n/**\n * T5a.2 Phase F slice 2/3 — Web-Standards channel handler.\n *\n * Mirror of `ChannelHandler<TMessage>` for the Web `Request` shape.\n * `onSubscribe` receives `request: Request` instead of `req: IncomingMessage`\n * — the rest of the surface (onMessage, onUnsubscribe) is shape-agnostic\n * (WebSocketLike is already Web-standards-compatible per `define-websocket.ts`).\n *\n * Per `docs/plans/t5a2-incoming-message-to-request-shape-refactor-plan.md`\n * v1.0 § Phase F.\n *\n * **Architectural note:** WebSocket upgrade semantics differ across\n * runtimes:\n * - Node: `WebSocketServer.handleUpgrade(req, socket, head, cb)` —\n * hands you `req: IncomingMessage` at the upgrade handshake.\n * - CF Workers: `new WebSocketPair()` + `request.headers` (the upgrade\n * handshake IS a Web Request) — hands you `request: Request`.\n * - Bun: `server.upgrade(request, { data })` — same Web Request shape.\n * - Deno: `Deno.upgradeWebSocket(request)` — same Web Request shape.\n *\n * Channel handlers targeting CF/Bun/Deno use `WebChannelHandler`; legacy\n * Node consumers stay on `ChannelHandler`. Cross-runtime channels ship\n * both shapes.\n */\nexport interface WebChannelHandler<TMessage = unknown> {\n onSubscribe?: (ws: WebSocketLike, room: string, request: Request) => void\n onMessage?: (ws: WebSocketLike, room: string, data: TMessage) => void\n onUnsubscribe?: (ws: WebSocketLike, room: string) => void\n}\n\n/**\n * Web-Standards `defineChannel` sibling. Identity function — provides\n * type inference for Web channel handlers.\n */\nexport function defineWebChannel<TMessage = unknown>(\n handler: WebChannelHandler<TMessage>,\n): WebChannelHandler<TMessage> {\n return handler\n}\n"],"mappings":"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","names":["plugin"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server/scan/module-loader.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url'\n\nimport type { ViteDevServer } from 'vite'\n\nexport type LoadModule = (path: string) => Promise<Record<string, unknown>>\n\nexport function createViteLoader(vite: ViteDevServer): LoadModule {\n return (path) => vite.ssrLoadModule(path) as Promise<Record<string, unknown>>\n}\n\nexport function createProductionLoader(): LoadModule {\n return async (path) => {\n const url = pathToFileURL(path).href\n return import(url) as Promise<Record<string, unknown>>\n }\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAMvB,SAAS,iBAAiB,MAAiC;AAChE,SAAO,CAAC,SAAS,KAAK,cAAc,IAAI;AAC1C;AAEO,SAAS,yBAAqC;AACnD,SAAO,OAAO,SAAS;AACrB,UAAM,MAAM,cAAc,IAAI,EAAE;AAChC,WAAO,OAAO;AAAA,EAChB;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server/observability/span.ts","../src/server/observability/adapters/noop.ts","../src/server/observability/adapters/console.ts","../src/server/observability/otlp-serializer.ts","../src/server/observability/adapters/theo-cloud.ts","../src/server/observability/adapter-registry.ts","../src/server/observability/middleware.ts","../src/server/observability/define-adapter.ts"],"sourcesContent":["/**\n * SpanHandle implementation — records timing + attributes.\n *\n * Used by console and theo-cloud adapters. Noop adapter uses NoopSpan.\n */\nimport type { SpanHandle, SpanAttributes } from './adapters/types.js'\n\nexport interface SpanData {\n name: string\n attributes: Record<string, string | number | boolean>\n status: 'ok' | 'error'\n statusMessage?: string\n startTimeMs: number\n endTimeMs?: number\n durationMs?: number\n}\n\nexport class SpanImpl implements SpanHandle {\n private readonly data: SpanData\n private ended = false\n\n constructor(name: string, attributes?: SpanAttributes) {\n this.data = {\n name,\n attributes: {},\n status: 'ok',\n startTimeMs: Date.now(),\n }\n if (attributes) {\n for (const [k, v] of Object.entries(attributes)) {\n if (v !== undefined) this.data.attributes[k] = v\n }\n }\n }\n\n setAttribute(key: string, value: string | number | boolean): void {\n if (!this.ended) this.data.attributes[key] = value\n }\n\n setStatus(status: 'ok' | 'error', message?: string): void {\n if (!this.ended) {\n this.data.status = status\n this.data.statusMessage = message\n }\n }\n\n end(): void {\n if (this.ended) return // idempotent\n this.ended = true\n this.data.endTimeMs = Date.now()\n this.data.durationMs = this.data.endTimeMs - this.data.startTimeMs\n }\n\n /** Read-only access to span data (for adapters to export). */\n getData(): SpanData {\n return { ...this.data, attributes: { ...this.data.attributes } }\n }\n\n isEnded(): boolean {\n return this.ended\n }\n}\n\n/** Noop span — used by NoopAdapter and post-shutdown fallback (EC-2). */\nexport class NoopSpan implements SpanHandle {\n setAttribute(): void {}\n setStatus(): void {}\n end(): void {}\n}\n","/**\n * NoopObservabilityAdapter — silent fallback.\n *\n * All methods are no-ops. Never throws, never blocks.\n * Used as the default when no other adapter is configured.\n * EC-2: startSpan after shutdown returns a noop span (no crash).\n */\nimport type { ObservabilityAdapter, SpanHandle, SpanAttributes } from './types.js'\nimport { NoopSpan } from '../span.js'\n\nexport class NoopObservabilityAdapter implements ObservabilityAdapter {\n readonly name = 'noop'\n private isShutdown = false\n\n startSpan(_name: string, _attributes?: SpanAttributes): SpanHandle {\n return new NoopSpan()\n }\n\n counter(_name: string, _value: number, _attributes?: SpanAttributes): void {}\n histogram(_name: string, _value: number, _attributes?: SpanAttributes): void {}\n log(_level: 'debug' | 'info' | 'warn' | 'error', _message: string, _attributes?: SpanAttributes): void {}\n\n async flush(): Promise<void> {}\n\n async shutdown(): Promise<void> {\n this.isShutdown = true\n }\n}\n","/**\n * ConsoleObservabilityAdapter — dev-mode console output.\n *\n * Emits JSON-structured lines to a configurable writer (default: process.stderr).\n * Inspired by Hono middleware timing pattern.\n */\nimport type { ObservabilityAdapter, SpanHandle, SpanAttributes } from './types.js'\nimport { SpanImpl, NoopSpan, type SpanData } from '../span.js'\n\nexport interface ConsoleAdapterOptions {\n /** Writer function — defaults to process.stderr.write. */\n write?: (line: string) => void\n}\n\nexport class ConsoleObservabilityAdapter implements ObservabilityAdapter {\n readonly name = 'console'\n private write: (line: string) => void\n private isShutdown = false\n private spans: SpanImpl[] = []\n\n constructor(options: ConsoleAdapterOptions = {}) {\n this.write = options.write ?? ((line: string) => process.stderr.write(line + '\\n'))\n }\n\n startSpan(name: string, attributes?: SpanAttributes): SpanHandle {\n if (this.isShutdown) return new NoopSpan()\n const span = new SpanImpl(name, attributes)\n this.spans.push(span)\n return {\n setAttribute: (k, v) => span.setAttribute(k, v),\n setStatus: (s, m) => span.setStatus(s, m),\n end: () => {\n span.end()\n this.emitSpan(span.getData())\n },\n }\n }\n\n counter(name: string, value: number, attributes?: SpanAttributes): void {\n if (this.isShutdown) return\n this.emit({ type: 'counter', metric: name, value, attributes: attributes ?? {}, timestamp: Date.now() })\n }\n\n histogram(name: string, value: number, attributes?: SpanAttributes): void {\n if (this.isShutdown) return\n this.emit({ type: 'histogram', metric: name, value, attributes: attributes ?? {}, timestamp: Date.now() })\n }\n\n log(level: 'debug' | 'info' | 'warn' | 'error', message: string, attributes?: SpanAttributes): void {\n if (this.isShutdown) return\n this.emit({ type: 'log', level, message, attributes: attributes ?? {}, timestamp: Date.now() })\n }\n\n async flush(): Promise<void> {}\n\n async shutdown(): Promise<void> {\n this.isShutdown = true\n }\n\n private emitSpan(data: SpanData): void {\n this.emit({\n type: 'span',\n name: data.name,\n status: data.status,\n duration_ms: data.durationMs ?? 0,\n attributes: data.attributes,\n timestamp: data.startTimeMs,\n })\n }\n\n private emit(record: Record<string, unknown>): void {\n this.write(JSON.stringify(record))\n }\n}\n","/**\n * Lightweight OTLP JSON serializer — ~50 LoC, no @opentelemetry/* dependency.\n *\n * Per ADR D456: in-house serializer for the theo-cloud adapter.\n * Produces valid ExportTraceServiceRequest JSON (OTLP v1.0).\n * Pinned to OTLP JSON v1.0 (stable since 2023).\n */\nimport type { SpanData } from './span.js'\n\ninterface OtlpSpan {\n traceId: string\n spanId: string\n name: string\n kind: number\n startTimeUnixNano: string\n endTimeUnixNano: string\n attributes: { key: string; value: { stringValue?: string; intValue?: string; boolValue?: boolean } }[]\n status: { code: number; message?: string }\n}\n\ninterface ExportTraceServiceRequest {\n resourceSpans: [{\n scopeSpans: [{\n scope: { name: string; version: string }\n spans: OtlpSpan[]\n }]\n }]\n}\n\n/** Convert SpanData[] to OTLP JSON bytes (Uint8Array). */\nexport function serializeSpansToOtlp(spans: SpanData[], serviceName = 'theokit'): Uint8Array {\n const otlpSpans: OtlpSpan[] = spans.map((s) => ({\n traceId: randomHex(32),\n spanId: randomHex(16),\n name: s.name,\n kind: 2, // SPAN_KIND_SERVER\n startTimeUnixNano: String(s.startTimeMs * 1_000_000),\n endTimeUnixNano: String((s.endTimeMs ?? s.startTimeMs) * 1_000_000),\n attributes: Object.entries(s.attributes).map(([key, value]) => ({\n key,\n value: typeof value === 'string'\n ? { stringValue: value }\n : typeof value === 'number'\n ? { intValue: String(value) }\n : { boolValue: value },\n })),\n status: { code: s.status === 'ok' ? 1 : 2, message: s.statusMessage },\n }))\n\n const request: ExportTraceServiceRequest = {\n resourceSpans: [{\n scopeSpans: [{\n scope: { name: serviceName, version: '1.0.0' },\n spans: otlpSpans,\n }],\n }],\n }\n\n return new TextEncoder().encode(JSON.stringify(request))\n}\n\nfunction randomHex(length: number): string {\n const bytes = new Uint8Array(length / 2)\n globalThis.crypto.getRandomValues(bytes)\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n}\n","/**\n * TheoCloudObservabilityAdapter — OTLP/HTTP batched export for TheoCloud.\n *\n * Zero-config via env vars (THEO_CLOUD_INGEST_URL, THEO_CLOUD_API_KEY).\n * Batches spans and flushes via native fetch() POST.\n *\n * EC-1: flush failure logs warning, does NOT throw, does NOT retry (KISS).\n * EC-2: startSpan after shutdown returns noop span.\n */\nimport type { ObservabilityAdapter, SpanHandle, SpanAttributes } from './types.js'\nimport { SpanImpl, NoopSpan, type SpanData } from '../span.js'\nimport { serializeSpansToOtlp } from '../otlp-serializer.js'\n\nexport interface TheoCloudAdapterOptions {\n /** TheoCloud ingest endpoint URL. */\n ingestUrl: string\n /** TheoCloud API key for authentication. */\n token: string\n /** Flush interval in ms (default: 5000). */\n flushIntervalMs?: number\n /** Mock fetch for testing (never in production). */\n _mockFetch?: typeof globalThis.fetch\n}\n\nexport class TheoCloudObservabilityAdapter implements ObservabilityAdapter {\n readonly name = 'theo-cloud'\n private pendingSpans: SpanData[] = []\n private isShutdown = false\n private readonly opts: Required<Pick<TheoCloudAdapterOptions, 'ingestUrl' | 'token'>> & TheoCloudAdapterOptions\n\n constructor(options: TheoCloudAdapterOptions) {\n this.opts = { flushIntervalMs: 5000, ...options }\n }\n\n startSpan(name: string, attributes?: SpanAttributes): SpanHandle {\n if (this.isShutdown) return new NoopSpan()\n const span = new SpanImpl(name, attributes)\n return {\n setAttribute: (k, v) => span.setAttribute(k, v),\n setStatus: (s, m) => span.setStatus(s, m),\n end: () => {\n span.end()\n this.pendingSpans.push(span.getData())\n },\n }\n }\n\n counter(_name: string, _value: number, _attributes?: SpanAttributes): void {}\n histogram(_name: string, _value: number, _attributes?: SpanAttributes): void {}\n log(_level: 'debug' | 'info' | 'warn' | 'error', _message: string, _attributes?: SpanAttributes): void {}\n\n async flush(): Promise<void> {\n if (this.isShutdown || this.pendingSpans.length === 0) return\n\n const spans = this.pendingSpans.splice(0)\n const body = serializeSpansToOtlp(spans) as unknown as BodyInit\n const fetchFn = this.opts._mockFetch ?? globalThis.fetch\n\n try {\n await fetchFn(this.opts.ingestUrl, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'authorization': `Bearer ${this.opts.token}`,\n },\n body,\n })\n } catch (err) {\n // EC-1: log warning, don't throw, don't retry\n console.error(\n `[theokit:observability] flush failed: ${err instanceof Error ? err.message : 'unknown error'}`,\n )\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.isShutdown) return\n await this.flush()\n this.isShutdown = true\n }\n}\n","/**\n * Adapter registry — resolves the active observability adapter.\n *\n * Per ADR D457 (v1.1) priority chain:\n * 1. Explicit config (theo.config.ts observability.provider) — ALWAYS wins\n * 2. THEO_CLOUD_INGEST_URL env → theo-cloud adapter\n * 3. NODE_ENV=development → console adapter\n * 4. Fallback → noop adapter\n */\nimport type { ObservabilityAdapter } from './adapters/types.js'\nimport { NoopObservabilityAdapter } from './adapters/noop.js'\nimport { ConsoleObservabilityAdapter } from './adapters/console.js'\nimport { TheoCloudObservabilityAdapter } from './adapters/theo-cloud.js'\n\nexport interface ResolveAdapterOptions {\n env: Record<string, string | undefined>\n config?: {\n provider?: ObservabilityAdapter\n }\n}\n\n/**\n * Resolve the observability adapter from config + env.\n * Called once at boot — returns the active adapter for the process lifetime.\n */\nexport function resolveAdapter(options: ResolveAdapterOptions): ObservabilityAdapter {\n // 1. Explicit config ALWAYS wins (EC-4)\n if (options.config?.provider) {\n return options.config.provider\n }\n\n // 2. TheoCloud env vars → theo-cloud adapter\n const ingestUrl = options.env.THEO_CLOUD_INGEST_URL\n const apiKey = options.env.THEO_CLOUD_API_KEY\n if (ingestUrl && apiKey) {\n return new TheoCloudObservabilityAdapter({ ingestUrl, token: apiKey })\n }\n\n // 3. Development → console adapter\n if (options.env.NODE_ENV === 'development') {\n return new ConsoleObservabilityAdapter()\n }\n\n // 4. Fallback → noop\n return new NoopObservabilityAdapter()\n}\n","/**\n * Auto-instrumentation middleware — creates spans for every HTTP request.\n *\n * Registers as a standard TheoKit plugin via existing hook system.\n * No changes to plugin-runner needed.\n *\n * Per blueprint Pattern 2 (Hono middleware timing):\n * - onRequest: start span with method + path\n * - onResponse: end span with status + duration\n * - onError: set span status to error\n */\nimport type { ObservabilityAdapter, SpanHandle } from './adapters/types.js'\n\nexport interface PluginContext {\n requestId: string\n request: { method: string; url: string }\n response?: { statusCode: number }\n}\n\nexport interface ObservabilityPlugin {\n name: string\n onRequest(ctx: PluginContext): Promise<void>\n onResponse(ctx: PluginContext): Promise<void>\n onError(ctx: PluginContext & { error: unknown }): Promise<void>\n}\n\n// Active spans keyed by requestId — cleared on response/error\nconst activeSpans = new Map<string, SpanHandle>()\n\n/**\n * Create an observability plugin that auto-instruments HTTP requests.\n *\n * EC-5: For SSE responses, span ends on response close, not headers sent.\n * The caller should invoke onResponse when the stream actually closes.\n */\nexport function createObservabilityPlugin(adapter: ObservabilityAdapter): ObservabilityPlugin {\n return {\n name: 'theokit:observability',\n\n async onRequest(ctx: PluginContext): Promise<void> {\n const url = new URL(ctx.request.url, 'http://localhost')\n const span = adapter.startSpan('http.request', {\n method: ctx.request.method,\n path: url.pathname,\n requestId: ctx.requestId,\n })\n activeSpans.set(ctx.requestId, span)\n },\n\n async onResponse(ctx: PluginContext): Promise<void> {\n const span = activeSpans.get(ctx.requestId)\n if (!span) return\n activeSpans.delete(ctx.requestId)\n\n if (ctx.response) {\n span.setAttribute('status', ctx.response.statusCode)\n }\n span.setStatus('ok')\n span.end()\n\n adapter.counter('http.requests', 1, {\n method: ctx.request.method,\n status: ctx.response?.statusCode ?? 0,\n })\n },\n\n async onError(ctx: PluginContext & { error: unknown }): Promise<void> {\n const span = activeSpans.get(ctx.requestId)\n if (!span) return\n activeSpans.delete(ctx.requestId)\n\n const message = ctx.error instanceof Error ? ctx.error.message : 'unknown error'\n span.setAttribute('error', true)\n span.setStatus('error', message)\n span.end()\n\n adapter.counter('http.errors', 1, {\n method: ctx.request.method,\n })\n },\n }\n}\n","/**\n * defineObservabilityAdapter() — public API for custom adapters.\n *\n * The escape hatch for self-host users who want Datadog, Grafana, Honeycomb, etc.\n * Validates the adapter shape and returns a typed ObservabilityAdapter.\n *\n * @example\n * ```ts\n * const datadogAdapter = defineObservabilityAdapter({\n * name: 'datadog',\n * startSpan: (name, attrs) => { ... },\n * counter: (name, value) => { ... },\n * histogram: (name, value) => { ... },\n * log: (level, message) => { ... },\n * flush: async () => { ... },\n * shutdown: async () => { ... },\n * })\n *\n * // theo.config.ts\n * export default defineConfig({\n * observability: { provider: datadogAdapter },\n * })\n * ```\n */\nimport type { ObservabilityAdapter, SpanHandle, SpanAttributes } from './adapters/types.js'\n\nexport interface DefineAdapterConfig {\n name: string\n startSpan(name: string, attributes?: SpanAttributes): SpanHandle\n counter(name: string, value: number, attributes?: SpanAttributes): void\n histogram(name: string, value: number, attributes?: SpanAttributes): void\n log(level: 'debug' | 'info' | 'warn' | 'error', message: string, attributes?: SpanAttributes): void\n flush(): Promise<void>\n shutdown(): Promise<void>\n}\n\nexport function defineObservabilityAdapter(config: DefineAdapterConfig): ObservabilityAdapter {\n return {\n name: config.name,\n startSpan: (name, attrs) => config.startSpan(name, attrs),\n counter: (name, value, attrs) => config.counter(name, value, attrs),\n histogram: (name, value, attrs) => config.histogram(name, value, attrs),\n log: (level, message, attrs) => config.log(level, message, attrs),\n flush: () => config.flush(),\n shutdown: () => config.shutdown(),\n }\n}\n"],"mappings":"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","names":[]}