theokit 0.48.13 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/README.md +1 -0
  2. package/dist/{actions-virtual-module-YQXRSSMW.js → actions-virtual-module-5WBVSDOM.js} +22 -12
  3. package/dist/actions-virtual-module-5WBVSDOM.js.map +1 -0
  4. package/dist/{actions-virtual-module-LB4NGONI.js → actions-virtual-module-ZYLMNW6K.js} +13 -8
  5. package/dist/{actions-virtual-module-LB4NGONI.js.map → actions-virtual-module-ZYLMNW6K.js.map} +1 -1
  6. package/dist/adapters/agent-mount.d.ts +127 -0
  7. package/dist/adapters/agent-mount.js +24 -0
  8. package/dist/adapters/security-headers.d.ts +132 -0
  9. package/dist/adapters/security-headers.js +64 -0
  10. package/dist/adapters/security-headers.js.map +1 -0
  11. package/dist/adapters/web-shim.d.ts +100 -13
  12. package/dist/adapters/web-shim.js +158 -54
  13. package/dist/adapters/web-shim.js.map +1 -1
  14. package/dist/agent-GKUEL6OH.js +15 -0
  15. package/dist/agent-scan-BZa-pagG.d.ts +16 -0
  16. package/dist/{app-typed-client-GHO3EWZK.js → app-typed-client-4LAIEGFX.js} +23 -13
  17. package/dist/app-typed-client-4LAIEGFX.js.map +1 -0
  18. package/dist/{app-typed-client-G3J5G7E5.js → app-typed-client-DQM3Y6YY.js} +14 -9
  19. package/dist/app-typed-client-DQM3Y6YY.js.map +1 -0
  20. package/dist/aws-lambda-VKMYUMP2.js +261 -0
  21. package/dist/aws-lambda-VKMYUMP2.js.map +1 -0
  22. package/dist/{build-WU6AKKIB.js → build-FLX6VF7Q.js} +71 -26
  23. package/dist/build-FLX6VF7Q.js.map +1 -0
  24. package/dist/{bun-33RD6K7O.js → bun-L7PP6ID5.js} +105 -13
  25. package/dist/bun-L7PP6ID5.js.map +1 -0
  26. package/dist/{check-45NKUVSQ.js → check-GIPZBFTX.js} +2 -2
  27. package/dist/{chunk-KD5G3YXI.js → chunk-2AMLGJJA.js} +35 -9
  28. package/dist/chunk-2AMLGJJA.js.map +1 -0
  29. package/dist/chunk-3PBAN2YE.js +146 -0
  30. package/dist/chunk-3PBAN2YE.js.map +1 -0
  31. package/dist/{chunk-HBU2GIMZ.js → chunk-3QPVEJ7D.js} +15 -9
  32. package/dist/chunk-3QPVEJ7D.js.map +1 -0
  33. package/dist/{chunk-47CINLWF.js → chunk-44J2ANQC.js} +2 -2
  34. package/dist/{chunk-IEES3CHD.js → chunk-47MM2JUK.js} +8 -2
  35. package/dist/chunk-47MM2JUK.js.map +1 -0
  36. package/dist/chunk-4X6H2BXP.js +108 -0
  37. package/dist/chunk-4X6H2BXP.js.map +1 -0
  38. package/dist/{chunk-A7JBF5FO.js → chunk-5K4TDLRG.js} +8 -5
  39. package/dist/chunk-5K4TDLRG.js.map +1 -0
  40. package/dist/chunk-5YPXXSYY.js +181 -0
  41. package/dist/chunk-5YPXXSYY.js.map +1 -0
  42. package/dist/{chunk-YGAXV5HR.js → chunk-6J4JWHDJ.js} +191 -112
  43. package/dist/chunk-6J4JWHDJ.js.map +1 -0
  44. package/dist/chunk-72DMJBXI.js +424 -0
  45. package/dist/chunk-72DMJBXI.js.map +1 -0
  46. package/dist/chunk-7PM6K5EV.js +513 -0
  47. package/dist/chunk-7PM6K5EV.js.map +1 -0
  48. package/dist/{chunk-MTEWLGVY.js → chunk-BPYMC7SU.js} +4 -48
  49. package/dist/chunk-BPYMC7SU.js.map +1 -0
  50. package/dist/chunk-BU6RJPPJ.js +421 -0
  51. package/dist/chunk-BU6RJPPJ.js.map +1 -0
  52. package/dist/{chunk-FB2HBNIC.js → chunk-BX6EUYHU.js} +6 -2
  53. package/dist/chunk-BX6EUYHU.js.map +1 -0
  54. package/dist/{chunk-BIVCP6X5.js → chunk-C62IZEJI.js} +465 -202
  55. package/dist/chunk-C62IZEJI.js.map +1 -0
  56. package/dist/chunk-D4VP2QPR.js +16 -0
  57. package/dist/chunk-D4VP2QPR.js.map +1 -0
  58. package/dist/{chunk-J5MXCGKA.js → chunk-DHAD2O3S.js} +6 -6
  59. package/dist/chunk-DHAD2O3S.js.map +1 -0
  60. package/dist/chunk-E43VJ3E5.js +188 -0
  61. package/dist/chunk-E43VJ3E5.js.map +1 -0
  62. package/dist/chunk-EVZKNA2W.js +110 -0
  63. package/dist/chunk-EVZKNA2W.js.map +1 -0
  64. package/dist/chunk-FD4ZDTQ6.js +181 -0
  65. package/dist/chunk-FD4ZDTQ6.js.map +1 -0
  66. package/dist/chunk-FDOOBTXJ.js +17 -0
  67. package/dist/chunk-FDOOBTXJ.js.map +1 -0
  68. package/dist/chunk-FH3SQR6P.js +275 -0
  69. package/dist/chunk-FH3SQR6P.js.map +1 -0
  70. package/dist/chunk-HJHGTFEJ.js +23 -0
  71. package/dist/chunk-HJHGTFEJ.js.map +1 -0
  72. package/dist/{chunk-LXAESF4Y.js → chunk-HK4AZBKX.js} +7 -4
  73. package/dist/chunk-HK4AZBKX.js.map +1 -0
  74. package/dist/{chunk-T5C46IIU.js → chunk-HWBRS4DZ.js} +28 -269
  75. package/dist/chunk-HWBRS4DZ.js.map +1 -0
  76. package/dist/chunk-IRQGAC4L.js +52 -0
  77. package/dist/chunk-IRQGAC4L.js.map +1 -0
  78. package/dist/{chunk-FNTLKHZ7.js → chunk-JDN5SAAD.js} +7 -4
  79. package/dist/chunk-JDN5SAAD.js.map +1 -0
  80. package/dist/{chunk-GXEX4CBH.js → chunk-JIKNR5LX.js} +673 -484
  81. package/dist/chunk-JIKNR5LX.js.map +1 -0
  82. package/dist/{chunk-GRI4XHBJ.js → chunk-JWRCZIA4.js} +266 -108
  83. package/dist/chunk-JWRCZIA4.js.map +1 -0
  84. package/dist/{chunk-E576KYYT.js → chunk-KI4DOTN4.js} +25 -2
  85. package/dist/chunk-KI4DOTN4.js.map +1 -0
  86. package/dist/{chunk-ZB7D62OA.js → chunk-KUZVRJ7M.js} +3 -3
  87. package/dist/chunk-L4VFNFDL.js +248 -0
  88. package/dist/chunk-L4VFNFDL.js.map +1 -0
  89. package/dist/chunk-M2WC5MF7.js +127 -0
  90. package/dist/chunk-M2WC5MF7.js.map +1 -0
  91. package/dist/{chunk-O3JIAU3V.js → chunk-MCTC6HSE.js} +157 -103
  92. package/dist/chunk-MCTC6HSE.js.map +1 -0
  93. package/dist/{chunk-PXFXSFJL.js → chunk-NZ5JU6D3.js} +9 -9
  94. package/dist/{chunk-YRBR424R.js → chunk-OAUI273L.js} +338 -165
  95. package/dist/chunk-OAUI273L.js.map +1 -0
  96. package/dist/chunk-OGLS76RN.js +43 -0
  97. package/dist/chunk-OGLS76RN.js.map +1 -0
  98. package/dist/{chunk-7LVM22VG.js → chunk-OQCRCXCP.js} +6 -6
  99. package/dist/chunk-OQCRCXCP.js.map +1 -0
  100. package/dist/{chunk-OLGPYOLO.js → chunk-P6OS7652.js} +5 -2
  101. package/dist/chunk-P6OS7652.js.map +1 -0
  102. package/dist/chunk-Q5L5EGWZ.js +26 -0
  103. package/dist/chunk-Q5L5EGWZ.js.map +1 -0
  104. package/dist/{chunk-S433N3CT.js → chunk-QTHVHNJJ.js} +6 -36
  105. package/dist/chunk-QTHVHNJJ.js.map +1 -0
  106. package/dist/chunk-RPET332G.js +84 -0
  107. package/dist/chunk-RPET332G.js.map +1 -0
  108. package/dist/{chunk-646CA6RV.js → chunk-RQW5YMH7.js} +12 -4
  109. package/dist/chunk-RQW5YMH7.js.map +1 -0
  110. package/dist/{chunk-XALU5LCU.js → chunk-RWNYIU6A.js} +550 -146
  111. package/dist/chunk-RWNYIU6A.js.map +1 -0
  112. package/dist/chunk-SL7YUHPV.js +111 -0
  113. package/dist/chunk-SL7YUHPV.js.map +1 -0
  114. package/dist/chunk-U5PWXS3J.js +39 -0
  115. package/dist/chunk-U5PWXS3J.js.map +1 -0
  116. package/dist/chunk-ULDCFL2O.js +273 -0
  117. package/dist/chunk-ULDCFL2O.js.map +1 -0
  118. package/dist/{chunk-RWNSW4FM.js → chunk-UMNXCU3K.js} +12 -6
  119. package/dist/{chunk-RWNSW4FM.js.map → chunk-UMNXCU3K.js.map} +1 -1
  120. package/dist/chunk-VI7ZANB3.js +193 -0
  121. package/dist/chunk-VI7ZANB3.js.map +1 -0
  122. package/dist/chunk-VQPHPQ5L.js +14 -0
  123. package/dist/chunk-VQPHPQ5L.js.map +1 -0
  124. package/dist/chunk-WNJTJRM6.js +147 -0
  125. package/dist/chunk-WNJTJRM6.js.map +1 -0
  126. package/dist/chunk-WOBSEO75.js +790 -0
  127. package/dist/chunk-WOBSEO75.js.map +1 -0
  128. package/dist/{chunk-BMHS4WAN.js → chunk-XS7EX55U.js} +156 -42
  129. package/dist/chunk-XS7EX55U.js.map +1 -0
  130. package/dist/chunk-YN4W7LCX.js +31 -0
  131. package/dist/chunk-YN4W7LCX.js.map +1 -0
  132. package/dist/chunk-YSJOZEI6.js +1 -0
  133. package/dist/{chunk-JA2ZAT5Q.js → chunk-Z4PJMZLM.js} +2 -2
  134. package/dist/chunk-Z4PJMZLM.js.map +1 -0
  135. package/dist/{chunk-7VPQHEAJ.js → chunk-ZNZISJDZ.js} +6 -2
  136. package/dist/chunk-ZNZISJDZ.js.map +1 -0
  137. package/dist/chunk-ZWN3AODA.js +11 -0
  138. package/dist/chunk-ZWN3AODA.js.map +1 -0
  139. package/dist/cli/index.js +25 -10
  140. package/dist/cli/index.js.map +1 -1
  141. package/dist/client/core.d.ts +1 -1
  142. package/dist/client/core.js +2 -0
  143. package/dist/client/core.js.map +1 -1
  144. package/dist/client/index.d.ts +44 -10
  145. package/dist/client/index.js +35 -0
  146. package/dist/client/index.js.map +1 -1
  147. package/dist/cloudflare-SIG42OIW.js +335 -0
  148. package/dist/cloudflare-SIG42OIW.js.map +1 -0
  149. package/dist/config-support-WQHQIJTA.js +104 -0
  150. package/dist/config-support-WQHQIJTA.js.map +1 -0
  151. package/dist/{csrf-BBrEZSBW.d.ts → csrf-Dgot9qSM.d.ts} +1 -1
  152. package/dist/deno-deploy-LQAYOOPW.js +196 -0
  153. package/dist/deno-deploy-LQAYOOPW.js.map +1 -0
  154. package/dist/{dev-MUWJAZRD.js → dev-ANDSEVLB.js} +28 -18
  155. package/dist/dev-ANDSEVLB.js.map +1 -0
  156. package/dist/{dev-emit-GWD6IXV7.js → dev-emit-BFNMDCPB.js} +5 -5
  157. package/dist/{dev-emit-NBT6JD7R.js → dev-emit-MVAJAFGX.js} +5 -3
  158. package/dist/dev-emit-MVAJAFGX.js.map +1 -0
  159. package/dist/engine-singleton-X4R7AZBJ.js +315 -0
  160. package/dist/engine-singleton-X4R7AZBJ.js.map +1 -0
  161. package/dist/{generate-Y3GWM57K.js → generate-EN6EDITF.js} +43 -4
  162. package/dist/generate-EN6EDITF.js.map +1 -0
  163. package/dist/index-CzxtQcnp.d.ts +1058 -0
  164. package/dist/index.d.ts +4 -0
  165. package/dist/index.js +24 -13
  166. package/dist/index.js.map +1 -1
  167. package/dist/{info-XW7HGUPH.js → info-Y55RWS42.js} +8 -6
  168. package/dist/{info-XW7HGUPH.js.map → info-Y55RWS42.js.map} +1 -1
  169. package/dist/{internal-api-V5L65YSJ.js → internal-api-IP35YU3G.js} +22 -12
  170. package/dist/{internal-api-WEOSTMSN.js → internal-api-OPU456AT.js} +30 -16
  171. package/dist/internal-api-OPU456AT.js.map +1 -0
  172. package/dist/load-config-4ATXQUN3.js +16 -0
  173. package/dist/match-DmGgxjIU.d.ts +44 -0
  174. package/dist/{mcp-ULUFJNSZ.js → mcp-5LLNAGKA.js} +7 -7
  175. package/dist/netlify-C2IRCZKI.js +245 -0
  176. package/dist/netlify-C2IRCZKI.js.map +1 -0
  177. package/dist/node-OSVPYQ3D.js +10 -0
  178. package/dist/nonce-BXt7Qu_C.d.ts +31 -0
  179. package/dist/observability-bootstrap-MZMSOE66.js +15 -0
  180. package/dist/{openapi-HZXR335W.js → openapi-VFPEZSRI.js} +13 -11
  181. package/dist/{openapi-HZXR335W.js.map → openapi-VFPEZSRI.js.map} +1 -1
  182. package/dist/{plugin-runner-BFEcgtmJ.d.ts → plugin-runner-BVMOSxvb.d.ts} +1 -1
  183. package/dist/{plugin-types-D69-lJZ9.d.ts → plugin-types-BUVfUQ0V.d.ts} +13 -1
  184. package/dist/preview-GHPT2EQ5.js +23 -0
  185. package/dist/preview-GHPT2EQ5.js.map +1 -0
  186. package/dist/provider-resolver-Dx6QuWrw.d.ts +128 -0
  187. package/dist/registry-KBZDCFVQ.js +23 -0
  188. package/dist/route-config-Cm_ZMA1C.d.ts +72 -0
  189. package/dist/route-policy-BxOycCDq.d.ts +65 -0
  190. package/dist/router/element-scroll-restoration.d.ts +28 -0
  191. package/dist/router/element-scroll-restoration.js +96 -0
  192. package/dist/router/element-scroll-restoration.js.map +1 -0
  193. package/dist/{routes-OLNQX7CT.js → routes-BPLU3ISV.js} +11 -9
  194. package/dist/{routes-OLNQX7CT.js.map → routes-BPLU3ISV.js.map} +1 -1
  195. package/dist/{scan-7MJC6PYU.js → scan-YJEE4KQK.js} +2 -2
  196. package/dist/{schema-ZO3OSWVG.js → schema-SOAD43RQ.js} +7 -5
  197. package/dist/schemas-4AXHQMV3.js +25 -0
  198. package/dist/schemas-4AXHQMV3.js.map +1 -0
  199. package/dist/security-headers-Ccj7ncNx.d.ts +129 -0
  200. package/dist/server/agent/index.d.ts +2 -90
  201. package/dist/server/agent/index.js +1 -1
  202. package/dist/server/auth/index.d.ts +2 -21
  203. package/dist/server/auth/index.js +3 -2
  204. package/dist/server/cron/index.js +4 -3
  205. package/dist/server/define/index.d.ts +51 -57
  206. package/dist/server/define/index.js +10 -1
  207. package/dist/server/http/index.d.ts +7 -5
  208. package/dist/server/http/index.js +56 -12
  209. package/dist/server/index.d.ts +47 -439
  210. package/dist/server/index.js +119 -201
  211. package/dist/server/index.js.map +1 -1
  212. package/dist/server/jobs/index.js +4 -3
  213. package/dist/server/observability/index.d.ts +109 -35
  214. package/dist/server/observability/index.js +10 -7
  215. package/dist/server/plugins/index.d.ts +3 -3
  216. package/dist/server/scan/index.d.ts +47 -12
  217. package/dist/server/scan/index.js +13 -4
  218. package/dist/server/security/index.d.ts +61 -103
  219. package/dist/server/security/index.js +15 -6
  220. package/dist/server/webhook/index.d.ts +90 -3
  221. package/dist/server/webhook/index.js +12 -2
  222. package/dist/server-boundary-6B4ZQUY7.js +148 -0
  223. package/dist/server-boundary-6B4ZQUY7.js.map +1 -0
  224. package/dist/server-boundary-7VZQRPPX.js +133 -0
  225. package/dist/server-boundary-7VZQRPPX.js.map +1 -0
  226. package/dist/{services-typed-client-PSAGRPFF.js → services-typed-client-XGT5SUUN.js} +2 -2
  227. package/dist/{start-KR2JJR7K.js → start-UZDMOT7I.js} +342 -111
  228. package/dist/start-UZDMOT7I.js.map +1 -0
  229. package/dist/{static-M2W4HUWS.js → static-SVDWIOXJ.js} +24 -13
  230. package/dist/static-SVDWIOXJ.js.map +1 -0
  231. package/dist/{theo-cloud-XAHWOUFK.js → theo-cloud-3ET4G5T6.js} +9 -2
  232. package/dist/theo-cloud-3ET4G5T6.js.map +1 -0
  233. package/dist/vercel-BMCQKCWE.js +277 -0
  234. package/dist/vercel-BMCQKCWE.js.map +1 -0
  235. package/dist/vite-plugin/index.js +24 -13
  236. package/dist/vite-plugin-VKCT2LF2.js +42 -0
  237. package/dist/vite-plugin-VKCT2LF2.js.map +1 -0
  238. package/package.json +19 -6
  239. package/dist/actions-virtual-module-YQXRSSMW.js.map +0 -1
  240. package/dist/agent-7JJW3TPB.js +0 -15
  241. package/dist/app-typed-client-G3J5G7E5.js.map +0 -1
  242. package/dist/app-typed-client-GHO3EWZK.js.map +0 -1
  243. package/dist/aws-lambda-CYNDGU5O.js +0 -172
  244. package/dist/aws-lambda-CYNDGU5O.js.map +0 -1
  245. package/dist/build-WU6AKKIB.js.map +0 -1
  246. package/dist/bun-33RD6K7O.js.map +0 -1
  247. package/dist/chunk-646CA6RV.js.map +0 -1
  248. package/dist/chunk-6E5WKMDS.js +0 -67
  249. package/dist/chunk-6E5WKMDS.js.map +0 -1
  250. package/dist/chunk-6GGWS7J3.js +0 -91
  251. package/dist/chunk-6GGWS7J3.js.map +0 -1
  252. package/dist/chunk-7LVM22VG.js.map +0 -1
  253. package/dist/chunk-7VPQHEAJ.js.map +0 -1
  254. package/dist/chunk-A7JBF5FO.js.map +0 -1
  255. package/dist/chunk-AM3QABW5.js +0 -161
  256. package/dist/chunk-AM3QABW5.js.map +0 -1
  257. package/dist/chunk-BIVCP6X5.js.map +0 -1
  258. package/dist/chunk-BMHS4WAN.js.map +0 -1
  259. package/dist/chunk-E576KYYT.js.map +0 -1
  260. package/dist/chunk-FB2HBNIC.js.map +0 -1
  261. package/dist/chunk-FNTLKHZ7.js.map +0 -1
  262. package/dist/chunk-GRI4XHBJ.js.map +0 -1
  263. package/dist/chunk-GVW5EKEU.js +0 -422
  264. package/dist/chunk-GVW5EKEU.js.map +0 -1
  265. package/dist/chunk-GXEX4CBH.js.map +0 -1
  266. package/dist/chunk-HBU2GIMZ.js.map +0 -1
  267. package/dist/chunk-IEES3CHD.js.map +0 -1
  268. package/dist/chunk-J5MXCGKA.js.map +0 -1
  269. package/dist/chunk-JA2ZAT5Q.js.map +0 -1
  270. package/dist/chunk-KD5G3YXI.js.map +0 -1
  271. package/dist/chunk-LNVMHQ2Z.js +0 -54
  272. package/dist/chunk-LNVMHQ2Z.js.map +0 -1
  273. package/dist/chunk-LXAESF4Y.js.map +0 -1
  274. package/dist/chunk-MTEWLGVY.js.map +0 -1
  275. package/dist/chunk-O3JIAU3V.js.map +0 -1
  276. package/dist/chunk-OJLL4YD6.js +0 -403
  277. package/dist/chunk-OJLL4YD6.js.map +0 -1
  278. package/dist/chunk-OLGPYOLO.js.map +0 -1
  279. package/dist/chunk-S433N3CT.js.map +0 -1
  280. package/dist/chunk-T5C46IIU.js.map +0 -1
  281. package/dist/chunk-U267AOWS.js +0 -28
  282. package/dist/chunk-U267AOWS.js.map +0 -1
  283. package/dist/chunk-UW2TEAGR.js +0 -77
  284. package/dist/chunk-UW2TEAGR.js.map +0 -1
  285. package/dist/chunk-WPJOTQA5.js +0 -1
  286. package/dist/chunk-XALU5LCU.js.map +0 -1
  287. package/dist/chunk-XR74JD4M.js +0 -457
  288. package/dist/chunk-XR74JD4M.js.map +0 -1
  289. package/dist/chunk-YGAXV5HR.js.map +0 -1
  290. package/dist/chunk-YRBR424R.js.map +0 -1
  291. package/dist/cloudflare-KYUWCEPL.js +0 -122
  292. package/dist/cloudflare-KYUWCEPL.js.map +0 -1
  293. package/dist/deno-deploy-CCTB7HGS.js +0 -107
  294. package/dist/deno-deploy-CCTB7HGS.js.map +0 -1
  295. package/dist/dev-MUWJAZRD.js.map +0 -1
  296. package/dist/dev-emit-NBT6JD7R.js.map +0 -1
  297. package/dist/generate-Y3GWM57K.js.map +0 -1
  298. package/dist/index-BEtEv6ZH.d.ts +0 -575
  299. package/dist/load-config-VKD6LKWU.js +0 -14
  300. package/dist/match-CfbEFRG4.d.ts +0 -26
  301. package/dist/netlify-AFMDNKT4.js +0 -150
  302. package/dist/netlify-AFMDNKT4.js.map +0 -1
  303. package/dist/node-ZJQEJSP3.js +0 -10
  304. package/dist/registry-GKR3EWRW.js +0 -23
  305. package/dist/start-KR2JJR7K.js.map +0 -1
  306. package/dist/static-M2W4HUWS.js.map +0 -1
  307. package/dist/theo-cloud-XAHWOUFK.js.map +0 -1
  308. package/dist/vercel-SRS2DH6O.js +0 -133
  309. package/dist/vercel-SRS2DH6O.js.map +0 -1
  310. package/dist/vite-plugin-VPJFD4HK.js +0 -36
  311. /package/dist/{chunk-WPJOTQA5.js.map → adapters/agent-mount.js.map} +0 -0
  312. /package/dist/{agent-7JJW3TPB.js.map → agent-GKUEL6OH.js.map} +0 -0
  313. /package/dist/{check-45NKUVSQ.js.map → check-GIPZBFTX.js.map} +0 -0
  314. /package/dist/{chunk-47CINLWF.js.map → chunk-44J2ANQC.js.map} +0 -0
  315. /package/dist/{chunk-ZB7D62OA.js.map → chunk-KUZVRJ7M.js.map} +0 -0
  316. /package/dist/{chunk-PXFXSFJL.js.map → chunk-NZ5JU6D3.js.map} +0 -0
  317. /package/dist/{internal-api-WEOSTMSN.js.map → chunk-YSJOZEI6.js.map} +0 -0
  318. /package/dist/{dev-emit-GWD6IXV7.js.map → dev-emit-BFNMDCPB.js.map} +0 -0
  319. /package/dist/{internal-api-V5L65YSJ.js.map → internal-api-IP35YU3G.js.map} +0 -0
  320. /package/dist/{load-config-VKD6LKWU.js.map → load-config-4ATXQUN3.js.map} +0 -0
  321. /package/dist/{mcp-ULUFJNSZ.js.map → mcp-5LLNAGKA.js.map} +0 -0
  322. /package/dist/{node-ZJQEJSP3.js.map → node-OSVPYQ3D.js.map} +0 -0
  323. /package/dist/{scan-7MJC6PYU.js.map → observability-bootstrap-MZMSOE66.js.map} +0 -0
  324. /package/dist/{registry-GKR3EWRW.js.map → registry-KBZDCFVQ.js.map} +0 -0
  325. /package/dist/{schema-ZO3OSWVG.js.map → scan-YJEE4KQK.js.map} +0 -0
  326. /package/dist/{vite-plugin-VPJFD4HK.js.map → schema-SOAD43RQ.js.map} +0 -0
  327. /package/dist/{services-typed-client-PSAGRPFF.js.map → services-typed-client-XGT5SUUN.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/netlify.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Netlify deploy adapter. All paths derived from `cwd` and a fixed\n * `.theokit/netlify/` output layout. Build-time tool — no HTTP input.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport type { TheoConfig } from '../config/schema.js'\nimport type { SecurityHeadersConfig } from '../core/contracts/security-headers.js'\nimport { assertServicesUnsupported, readManifest } from '../services/index.js'\n\nimport { deployedCorsFragment, type DeployedCorsOptions } from './deployed-cors.js'\nimport { deployedCsrfFragment, type DeployedCsrfOptions } from './deployed-csrf.js'\nimport {\n deployedRuntimeConfigFragment,\n type DeployedRuntimeConfigOptions,\n} from './deployed-runtime-config.js'\nimport { deployedTraceFragment } from './deployed-trace.js'\nimport { nodeAdapter } from './node.js'\nimport {\n buildSecurityHeaders,\n describeDeployedSecurityHeaders,\n renderSecurityHeadersConfigLiteral,\n} from './security-headers.js'\nimport type { AdapterBuildContext, DeployAdapter } from './types.js'\n\nexport class NetlifyConflictError extends Error {\n constructor(path: string, currentTo: string) {\n super(\n `netlify.toml has a conflicting redirect: \"${path}\" → \"${currentTo}\". ` +\n `Remove it manually or edit it to point to \"/.netlify/functions/theo\" ` +\n `before running the Netlify adapter again.`,\n )\n this.name = 'NetlifyConflictError'\n }\n}\n\nexport interface NetlifyBuildDeps {\n runNodeBuild?: (config: TheoConfig, cwd: string, ctx?: AdapterBuildContext) => Promise<void>\n writeFile?: (path: string, content: string) => void\n ensureDir?: (path: string) => void\n readTomlIfExists?: () => string | null\n}\n\nexport function renderNetlifyFunction(\n opts: { securityHeaders?: SecurityHeadersConfig } & DeployedCsrfOptions &\n DeployedRuntimeConfigOptions &\n DeployedCorsOptions = {},\n): string {\n const runtimeConfig = deployedRuntimeConfigFragment(opts)\n return [\n `// Generated by Theo — Netlify Functions adapter`,\n `import { resolve } from 'node:path'`,\n `import { scanServerRoutes, matchRoute, executeRoute, createProductionLoader, extractTraceIdFromRequest, TRACE_HEADER, createCorsWebHandler } from 'theokit/server'`,\n `import { createWebShim } from 'theokit/adapters/web-shim'`,\n `import { buildSecurityHeaders, withSecurityHeaders } from 'theokit/adapters/security-headers'`,\n ``,\n `const cwd = process.cwd()`,\n `const serverDir = resolve(cwd, 'server')`,\n `let routesCache = null`,\n `let loaderCache = null`,\n ``,\n `// #410 — the security baseline \\`theokit start\\` puts on every response,`,\n `// carried here as a literal because the deployed function has no`,\n `// theo.config.ts to read. The netlify.toml redirect routes only /api/* here,`,\n `// so this covers the API and not the document Netlify's static host serves`,\n `// (usetheokit/theokit#412).`,\n `const SECURITY_HEADERS_CONFIG = ${renderSecurityHeadersConfigLiteral(opts.securityHeaders)}`,\n `const SECURITY_HEADERS = buildSecurityHeaders(SECURITY_HEADERS_CONFIG, { production: true })`,\n ``,\n ...runtimeConfig.imports,\n ...runtimeConfig.declarations,\n ...deployedCsrfFragment(opts),\n ``,\n ...deployedCorsFragment(opts.cors, 'netlify'),\n ``,\n `export default async (request, context) => {`,\n ` // #409 — the preflight is answered BEFORE anything routes: an OPTIONS the router`,\n ` // handles is an OPTIONS the browser never gets a CORS answer to.`,\n ` const preflight = corsPreflight(request)`,\n ` if (preflight !== null) return withSecurityHeaders(preflight, SECURITY_HEADERS)`,\n ` return withCors(request, withSecurityHeaders(await handleRequest(request), SECURITY_HEADERS))`,\n `}`,\n ``,\n `async function handleRequest(request) {`,\n ` const url = new URL(request.url)`,\n ` if (!url.pathname.startsWith('/api/')) {`,\n ` return new Response('Not Found', { status: 404 })`,\n ` }`,\n ``,\n ` if (!routesCache) routesCache = scanServerRoutes(serverDir)`,\n ` if (!loaderCache) loaderCache = createProductionLoader()`,\n ``,\n ` const match = matchRoute(url.pathname, routesCache)`,\n ` if (!match) {`,\n ` return new Response(JSON.stringify({ error: { code: 'NOT_FOUND' } }), {`,\n ` status: 404,`,\n ` headers: { 'content-type': 'application/json' },`,\n ` })`,\n ` }`,\n ``,\n ` const { req, res, toResponse } = createWebShim(request)`,\n ...deployedTraceFragment('request', ' '),\n ` const method = request.method.toUpperCase()`,\n ` // #382 — the run is not awaited: toResponse() settles at the headers and`,\n ` // carries a live body, so Netlify streams while the handler writes.`,\n ` return toResponse(executeRoute({ route: match.route, method, params: match.params, req, res, loadModule: loaderCache, serverDir, requestId, ...CSRF_CONFIG, ${runtimeConfig.executeRouteSpread} }))`,\n `}`,\n ].join('\\n')\n}\n\nconst THEO_REDIRECT_FROM = '/api/*'\nconst THEO_REDIRECT_TO = '/.netlify/functions/theo'\n\n/**\n * TOML merge (EC-2) — non-destructive.\n *\n * We avoid adding a TOML parser dependency by working at the line level. The\n * supported subset is sufficient for the Netlify use case:\n * - detect existing `[[redirects]]` blocks\n * - find a block whose `from = \"...\"` matches our target\n * - error if such a block points elsewhere\n * - otherwise append our block\n *\n * Unknown sections (e.g. `[build]`, `[[headers]]`, `[context.production.environment]`)\n * are preserved as-is.\n */\ninterface NetlifyRedirectBlock {\n startLine: number\n endLine: number\n from?: string\n to?: string\n}\n\nfunction parseRedirectBlocks(lines: readonly string[]): NetlifyRedirectBlock[] {\n const blocks: NetlifyRedirectBlock[] = []\n let current: NetlifyRedirectBlock | null = null\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim()\n if (trimmed === '[[redirects]]') {\n if (current) {\n current.endLine = i - 1\n blocks.push(current)\n }\n current = { startLine: i, endLine: i }\n continue\n }\n if (current && /^\\[(\\[|[^[])/.test(trimmed)) {\n // Entering another section — close current.\n current.endLine = i - 1\n blocks.push(current)\n current = null\n }\n if (current) {\n const fromMatch = /^from\\s*=\\s*\"([^\"]+)\"/.exec(trimmed)\n if (fromMatch) current.from = fromMatch[1]\n const toMatch = /^to\\s*=\\s*\"([^\"]+)\"/.exec(trimmed)\n if (toMatch) current.to = toMatch[1]\n current.endLine = i\n }\n }\n if (current) blocks.push(current)\n return blocks\n}\n\nconst THEO_REDIRECT_TARGET = [\n '[[redirects]]',\n ' from = \"/api/*\"',\n ' to = \"/.netlify/functions/theo\"',\n ' status = 200',\n ' force = true',\n].join('\\n')\n\n/**\n * Marks the block this build owns, so it can be REGENERATED rather than merely not duplicated.\n *\n * Idempotence alone would be the wrong contract here: the block carries configuration, so a\n * `security.headers` change has to reach the file. Leaving an existing block in place — which is\n * what the redirect above correctly does, because its content is fixed — would silently pin the\n * baseline to whatever the first build emitted.\n */\nconst THEO_HEADERS_MARKER = '# Generated by Theo — security baseline (usetheokit/theokit#412)'\n\n/**\n * The `[[headers]]` block telling Netlify's static host the baseline.\n *\n * The emitted function applies these to every response IT returns, and it never returns the HTML\n * document: the `[[redirects]]` block routes only `/api/*`, so the page comes from Netlify's static\n * host and carried none of them. The values come from `buildSecurityHeaders` — the same function\n * the handler calls — rather than being written out here, because two lists of headers that must\n * agree are two lists that eventually do not.\n */\nfunction renderHeadersBlock(securityHeaders: SecurityHeadersConfig | undefined): string {\n const values = buildSecurityHeaders(securityHeaders ?? {}, { production: true })\n return [\n THEO_HEADERS_MARKER,\n '[[headers]]',\n ' for = \"/*\"',\n ' [headers.values]',\n ...Object.entries(values).map(([k, v]) => ` ${k} = ${JSON.stringify(v)}`),\n ].join('\\n')\n}\n\n/**\n * Drop a previously generated block, so the next one replaces it.\n *\n * Bounded by the marker and the next top-level section at column 0 (or EOF) — the shape TOML gives\n * a block. A user's own `[[headers]]` is untouched because it does not carry the marker: their\n * file, their rules, and Netlify applies both.\n */\nfunction withoutGeneratedHeaders(source: string): string {\n const lines = source.split(/\\r?\\n/)\n const start = lines.indexOf(THEO_HEADERS_MARKER)\n if (start < 0) return source\n\n const opensSection = (line: string | undefined): boolean => (line ?? '').startsWith('[')\n\n let end = start + 1\n while (end < lines.length && !opensSection(lines[end])) end += 1\n // The marker line itself opens the block, so `end` now sits on the NEXT section — but the block's\n // own `[[headers]]` is the first `[` after the marker, so step past it before scanning again.\n end += 1\n while (end < lines.length && !opensSection(lines[end])) end += 1\n\n return [...lines.slice(0, start), ...lines.slice(end)].join('\\n').replace(/\\n{3,}/gu, '\\n\\n')\n}\n\nexport function mergeNetlifyToml(\n existing: string | null,\n securityHeaders?: SecurityHeadersConfig,\n): string {\n const headersBlock = renderHeadersBlock(securityHeaders)\n\n if (existing === null || existing.trim().length === 0) {\n return `${THEO_REDIRECT_TARGET}\\n\\n${headersBlock}\\n`\n }\n\n existing = withoutGeneratedHeaders(existing)\n\n const blocks = parseRedirectBlocks(existing.split(/\\r?\\n/))\n\n // Detect conflict: every `/api/*` block must point at our function.\n for (const b of blocks) {\n if (b.from !== THEO_REDIRECT_FROM) continue\n if (b.to === THEO_REDIRECT_TO) {\n // The redirect is already there. The headers block is regenerated regardless, because it\n // carries configuration and the redirect does not.\n const sep = existing.endsWith('\\n') ? '' : '\\n'\n return `${existing}${sep}\\n${headersBlock}\\n`\n }\n throw new NetlifyConflictError(b.from, b.to ?? '(unknown)')\n }\n\n // No conflict — append target block.\n const sep = existing.endsWith('\\n') ? '' : '\\n'\n return `${existing}${sep}\\n${THEO_REDIRECT_TARGET}\\n\\n${headersBlock}\\n`\n}\n\nexport async function buildNetlify(\n config: TheoConfig,\n cwd: string,\n deps: NetlifyBuildDeps = {},\n ctx?: AdapterBuildContext,\n): Promise<void> {\n // Wave 2 (T2.2) — reject polyglot services on this adapter.\n assertServicesUnsupported('netlify', readManifest(cwd))\n\n const runNodeBuild = deps.runNodeBuild ?? nodeAdapter.build.bind(nodeAdapter)\n await runNodeBuild(config, cwd, ctx)\n\n const ensureDir = deps.ensureDir ?? ((p: string) => mkdirSync(p, { recursive: true }))\n const writeFile =\n deps.writeFile ??\n ((p, c) => {\n writeFileSync(p, c)\n })\n const readTomlIfExists =\n deps.readTomlIfExists ??\n (() => {\n const p = resolve(cwd, 'netlify.toml')\n return existsSync(p) ? readFileSync(p, 'utf-8') : null\n })\n\n const fnDir = resolve(cwd, '.netlify/functions')\n ensureDir(fnDir)\n writeFile(\n resolve(fnDir, 'theo.mjs'),\n renderNetlifyFunction({\n securityHeaders: config.security?.headers,\n csrf: config.security?.csrf,\n disallowed: config.security?.disallowed,\n cors: config.security?.cors,\n // #425 — a selector, not a transformer, so it rides as a literal like the values above.\n serialization: config.serialization,\n }),\n )\n\n const existingToml = readTomlIfExists()\n const merged = mergeNetlifyToml(existingToml, config.security?.headers)\n writeFile(resolve(cwd, 'netlify.toml'), merged)\n\n // eslint-disable-next-line no-console -- CLI build progress\n console.log('\\n ✓ Netlify output → .netlify/functions/theo.mjs + netlify.toml')\n // eslint-disable-next-line no-console -- CLI build progress\n console.log(\n `${describeDeployedSecurityHeaders({\n target: 'netlify',\n securityHeaders: config.security?.headers,\n mintsNonce: false,\n documentHeaders: 'platform-configured',\n })}\\n`,\n )\n}\n\nexport const netlifyAdapter: DeployAdapter = {\n name: 'netlify',\n streamsResponses: true,\n // #409 / #410 — the generated entry calls `executeRoute` with routes, loader\n // and serverDir only. CSRF, route policy, file middleware and Zod validation\n // still run because they live inside `executeRoute`; none of the remaining\n // configurable concerns reach it. Declared explicitly rather than omitted so\n // the gap is a statement in the source and not an absence.\n //\n // `securityHeaders` IS applied -- to every response this function returns.\n // The document is served by Netlify's static host and does not pass through\n // it (usetheokit/theokit#412).\n appliesConfig: ['securityHeaders', 'csrf', 'disallowed', 'cors', 'serialization'],\n build(config, cwd, ctx) {\n return buildNetlify(config, cwd, {}, ctx)\n },\n}\n"],"mappings":"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","names":["sep"]}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import "tsx/esm";
3
+ import {
4
+ nodeAdapter
5
+ } from "./chunk-KI4DOTN4.js";
6
+ import "./chunk-ZNZISJDZ.js";
7
+ export {
8
+ nodeAdapter
9
+ };
10
+ //# sourceMappingURL=node-OSVPYQ3D.js.map
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The per-request CSP nonce, minted the same way on every target.
3
+ *
4
+ * It lives in `core/contracts/` for the same reason
5
+ * `core/contracts/security-headers.ts` does: `theokit start` needs it
6
+ * (`cli/commands/start/request-handler.ts`) and so does the streamed Cloudflare
7
+ * worker, which is the one deploy path that renders HTML at request time and can
8
+ * put the same value on the script tags it emits. `adapters → server` is not an
9
+ * edge in the module DAG (ADR-0001 v3), and a Web-Crypto call that returns a
10
+ * base64 string was never server code.
11
+ *
12
+ * T4.1 — Per-request CSP nonce generation.
13
+ *
14
+ * Returns a 22–24 character base64-encoded string carrying 16 bytes of
15
+ * cryptographic entropy. Used by the SSR pipeline to nonce the inline
16
+ * hydration data script so the default CSP can drop `'unsafe-inline'`
17
+ * from `script-src` in 0.3.0.
18
+ *
19
+ * Runtime portability: prefers Web Crypto (`globalThis.crypto`) because
20
+ * it is available on every target runtime (Node 19+, Bun, Deno, Vercel
21
+ * Edge, Cloudflare Workers). Falls back to `node:crypto` for older Node
22
+ * builds where `globalThis.crypto` is absent.
23
+ *
24
+ * NOT a security primitive in the cryptographic sense — the nonce is a
25
+ * one-shot, single-request value that defeats trivial XSS injection by
26
+ * making the attacker guess a 128-bit string per request. It is NOT
27
+ * suitable for signing or session tokens.
28
+ */
29
+ declare function generateNonce(): string;
30
+
31
+ export { generateNonce as g };
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import "tsx/esm";
3
+ import {
4
+ _resetObservabilityAdapter,
5
+ createObservabilityPluginFromConfig,
6
+ getObservabilityAdapter
7
+ } from "./chunk-7PM6K5EV.js";
8
+ import "./chunk-2AMLGJJA.js";
9
+ import "./chunk-VI7ZANB3.js";
10
+ export {
11
+ _resetObservabilityAdapter,
12
+ createObservabilityPluginFromConfig,
13
+ getObservabilityAdapter
14
+ };
15
+ //# sourceMappingURL=observability-bootstrap-MZMSOE66.js.map
@@ -4,18 +4,20 @@ import {
4
4
  emitOpenApi,
5
5
  loadRoutesForOpenApi
6
6
  } from "./chunk-47VNWTL4.js";
7
- import {
8
- loadConfig
9
- } from "./chunk-S433N3CT.js";
10
- import "./chunk-HBU2GIMZ.js";
11
- import "./chunk-GVW5EKEU.js";
12
- import "./chunk-7VPQHEAJ.js";
13
7
  import {
14
8
  generateManifest
15
- } from "./chunk-ZB7D62OA.js";
16
- import "./chunk-LNVMHQ2Z.js";
17
- import "./chunk-BMHS4WAN.js";
18
- import "./chunk-A7JBF5FO.js";
9
+ } from "./chunk-KUZVRJ7M.js";
10
+ import "./chunk-EVZKNA2W.js";
11
+ import "./chunk-XS7EX55U.js";
12
+ import "./chunk-FD4ZDTQ6.js";
13
+ import {
14
+ loadConfig
15
+ } from "./chunk-QTHVHNJJ.js";
16
+ import "./chunk-3QPVEJ7D.js";
17
+ import "./chunk-U5PWXS3J.js";
18
+ import "./chunk-FH3SQR6P.js";
19
+ import "./chunk-ZNZISJDZ.js";
20
+ import "./chunk-VI7ZANB3.js";
19
21
 
20
22
  // src/cli/commands/openapi.ts
21
23
  import { mkdtempSync, rmSync } from "fs";
@@ -82,4 +84,4 @@ function emitOpenApiInMemory(manifest, config) {
82
84
  export {
83
85
  openapiCommand
84
86
  };
85
- //# sourceMappingURL=openapi-HZXR335W.js.map
87
+ //# sourceMappingURL=openapi-VFPEZSRI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/commands/openapi.ts"],"sourcesContent":["/**\n * `theokit openapi` — regenerate `<distDir>/openapi.json` standalone.\n *\n * Mirrors trpc-openapi's `pnpm codegen` script. Useful in dev workflows\n * when only schemas changed and a full `theokit build` would be\n * overkill.\n *\n * Per G2 plan v1.1 T2.3. Single output (dev location only) — for the\n * dist artifact, run `theokit build`.\n *\n * Flags:\n * --dry-run Validate + print the document to stdout; skip the\n * filesystem write (EC-3 absorbed).\n */\nimport { mkdtempSync, rmSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join, resolve } from 'node:path'\n\nimport { loadConfig } from '../../config/load-config.js'\nimport { generateManifest } from '../../server/scan/manifest.js'\nimport { emitOpenApi } from '../../vite-plugin/openapi-emit/emit.js'\nimport { loadRoutesForOpenApi } from '../../vite-plugin/openapi-emit/load-routes.js'\n\nconst OPENAPI_DOCS_URL = 'https://theokit.dev/concepts/openapi'\n\ninterface OpenApiCommandOptions {\n /** Project root (defaults to `process.cwd()`). */\n cwd?: string\n /** Skip the filesystem write; print the document to stdout (EC-3). */\n dryRun?: boolean\n}\n\nexport async function openapiCommand(options: OpenApiCommandOptions = {}): Promise<void> {\n const cwd = options.cwd ?? process.cwd()\n const config = await loadConfig(cwd)\n\n if (config.openapi === undefined) {\n console.error(\n `\\n ✗ openapi: not configured in theo.config.ts\\n\\n` +\n ` Add the \\`openapi\\` block to opt in:\\n\\n` +\n ` export default defineConfig({\\n` +\n ` openapi: {\\n` +\n ` title: 'My App',\\n` +\n ` version: '1.0.0',\\n` +\n ` },\\n` +\n ` })\\n\\n` +\n ` See ${OPENAPI_DOCS_URL} for the full reference.\\n`,\n )\n process.exit(1)\n return\n }\n\n const serverDir = resolve(cwd, config.serverDir)\n const manifest = generateManifest(serverDir)\n const hydrated = await loadRoutesForOpenApi({ serverDir, routes: manifest.routes })\n\n if (options.dryRun) {\n // Build the document without writing — for the dry-run we still want a\n // valid emit pass, but with an in-memory output dir we never touch disk.\n const result = emitOpenApiInMemory(hydrated, config.openapi)\n console.log(`\\n ✓ openapi.json (dry-run): ${String(hydrated.length)} ops`)\n console.log(JSON.stringify(result.document, null, 2))\n console.log(`\\n Docs: ${OPENAPI_DOCS_URL}\\n`)\n return\n }\n\n const distDir = resolve(cwd, config.distDir)\n const result = emitOpenApi({\n manifest: hydrated,\n config: { ...config.openapi, outDir: distDir },\n })\n console.log(\n `\\n ✓ openapi.json: ${String(hydrated.length)} ops → ${result.path}\\n` +\n ` Docs: ${OPENAPI_DOCS_URL}\\n`,\n )\n}\n\n/**\n * Dry-run helper: build the OpenAPI doc without writing. Routes through\n * the same `emitOpenApi` but discards the side-effecting write by\n * targeting a temp directory we immediately ignore.\n *\n * Honest tradeoff: this still calls `mkdirSync` (no-op on existing tmpdir)\n * + a synchronous write to a discardable tempfile. Cost is < 1ms and the\n * code stays the single transformation. A pure no-write helper would\n * duplicate the orchestration in `emit.ts` — KISS prefers reuse.\n */\nfunction emitOpenApiInMemory(\n manifest: Parameters<typeof emitOpenApi>[0]['manifest'],\n config: Omit<Parameters<typeof emitOpenApi>[0]['config'], 'outDir'>,\n): { document: unknown } {\n const tmp = mkdtempSync(join(tmpdir(), 'theokit-openapi-dryrun-'))\n try {\n const result = emitOpenApi({ manifest, config: { ...config, outDir: tmp } })\n return { document: result.document }\n } finally {\n rmSync(tmp, { recursive: true, force: true })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAcA,SAAS,aAAa,cAAc;AACpC,SAAS,cAAc;AACvB,SAAS,MAAM,eAAe;AAO9B,IAAM,mBAAmB;AASzB,eAAsB,eAAe,UAAiC,CAAC,GAAkB;AACvF,QAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACvC,QAAM,SAAS,MAAM,WAAW,GAAG;AAEnC,MAAI,OAAO,YAAY,QAAW;AAChC,YAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQW,gBAAgB;AAAA;AAAA,IAC7B;AACA,YAAQ,KAAK,CAAC;AACd;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,KAAK,OAAO,SAAS;AAC/C,QAAM,WAAW,iBAAiB,SAAS;AAC3C,QAAM,WAAW,MAAM,qBAAqB,EAAE,WAAW,QAAQ,SAAS,OAAO,CAAC;AAElF,MAAI,QAAQ,QAAQ;AAGlB,UAAMA,UAAS,oBAAoB,UAAU,OAAO,OAAO;AAC3D,YAAQ,IAAI;AAAA,mCAAiC,OAAO,SAAS,MAAM,CAAC,MAAM;AAC1E,YAAQ,IAAI,KAAK,UAAUA,QAAO,UAAU,MAAM,CAAC,CAAC;AACpD,YAAQ,IAAI;AAAA,UAAa,gBAAgB;AAAA,CAAI;AAC7C;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,KAAK,OAAO,OAAO;AAC3C,QAAM,SAAS,YAAY;AAAA,IACzB,UAAU;AAAA,IACV,QAAQ,EAAE,GAAG,OAAO,SAAS,QAAQ,QAAQ;AAAA,EAC/C,CAAC;AACD,UAAQ;AAAA,IACN;AAAA,yBAAuB,OAAO,SAAS,MAAM,CAAC,eAAU,OAAO,IAAI;AAAA,UACtD,gBAAgB;AAAA;AAAA,EAC/B;AACF;AAYA,SAAS,oBACP,UACA,QACuB;AACvB,QAAM,MAAM,YAAY,KAAK,OAAO,GAAG,yBAAyB,CAAC;AACjE,MAAI;AACF,UAAM,SAAS,YAAY,EAAE,UAAU,QAAQ,EAAE,GAAG,QAAQ,QAAQ,IAAI,EAAE,CAAC;AAC3E,WAAO,EAAE,UAAU,OAAO,SAAS;AAAA,EACrC,UAAE;AACA,WAAO,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAC9C;AACF;","names":["result"]}
1
+ {"version":3,"sources":["../src/cli/commands/openapi.ts"],"sourcesContent":["/**\n * `theokit openapi` — regenerate `<distDir>/openapi.json` standalone.\n *\n * Mirrors trpc-openapi's `pnpm codegen` script. Useful in dev workflows\n * when only schemas changed and a full `theokit build` would be\n * overkill.\n *\n * Per G2 plan v1.1 T2.3. Single output (dev location only) — for the\n * dist artifact, run `theokit build`.\n *\n * Flags:\n * --dry-run Validate + print the document to stdout; skip the\n * filesystem write (EC-3 absorbed).\n */\nimport { mkdtempSync, rmSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join, resolve } from 'node:path'\n\nimport { loadConfig } from '../../config/load-config.js'\nimport { generateManifest } from '../../server/scan/manifest.js'\nimport { emitOpenApi } from '../../vite-plugin/openapi-emit/emit.js'\nimport { loadRoutesForOpenApi } from '../../vite-plugin/openapi-emit/load-routes.js'\n\nconst OPENAPI_DOCS_URL = 'https://theokit.dev/concepts/openapi'\n\ninterface OpenApiCommandOptions {\n /** Project root (defaults to `process.cwd()`). */\n cwd?: string\n /** Skip the filesystem write; print the document to stdout (EC-3). */\n dryRun?: boolean\n}\n\nexport async function openapiCommand(options: OpenApiCommandOptions = {}): Promise<void> {\n const cwd = options.cwd ?? process.cwd()\n const config = await loadConfig(cwd)\n\n if (config.openapi === undefined) {\n console.error(\n `\\n ✗ openapi: not configured in theo.config.ts\\n\\n` +\n ` Add the \\`openapi\\` block to opt in:\\n\\n` +\n ` export default defineConfig({\\n` +\n ` openapi: {\\n` +\n ` title: 'My App',\\n` +\n ` version: '1.0.0',\\n` +\n ` },\\n` +\n ` })\\n\\n` +\n ` See ${OPENAPI_DOCS_URL} for the full reference.\\n`,\n )\n process.exit(1)\n return\n }\n\n const serverDir = resolve(cwd, config.serverDir)\n const manifest = generateManifest(serverDir)\n const hydrated = await loadRoutesForOpenApi({ serverDir, routes: manifest.routes })\n\n if (options.dryRun) {\n // Build the document without writing — for the dry-run we still want a\n // valid emit pass, but with an in-memory output dir we never touch disk.\n const result = emitOpenApiInMemory(hydrated, config.openapi)\n console.log(`\\n ✓ openapi.json (dry-run): ${String(hydrated.length)} ops`)\n console.log(JSON.stringify(result.document, null, 2))\n console.log(`\\n Docs: ${OPENAPI_DOCS_URL}\\n`)\n return\n }\n\n const distDir = resolve(cwd, config.distDir)\n const result = emitOpenApi({\n manifest: hydrated,\n config: { ...config.openapi, outDir: distDir },\n })\n console.log(\n `\\n ✓ openapi.json: ${String(hydrated.length)} ops → ${result.path}\\n` +\n ` Docs: ${OPENAPI_DOCS_URL}\\n`,\n )\n}\n\n/**\n * Dry-run helper: build the OpenAPI doc without writing. Routes through\n * the same `emitOpenApi` but discards the side-effecting write by\n * targeting a temp directory we immediately ignore.\n *\n * Honest tradeoff: this still calls `mkdirSync` (no-op on existing tmpdir)\n * + a synchronous write to a discardable tempfile. Cost is < 1ms and the\n * code stays the single transformation. A pure no-write helper would\n * duplicate the orchestration in `emit.ts` — KISS prefers reuse.\n */\nfunction emitOpenApiInMemory(\n manifest: Parameters<typeof emitOpenApi>[0]['manifest'],\n config: Omit<Parameters<typeof emitOpenApi>[0]['config'], 'outDir'>,\n): { document: unknown } {\n const tmp = mkdtempSync(join(tmpdir(), 'theokit-openapi-dryrun-'))\n try {\n const result = emitOpenApi({ manifest, config: { ...config, outDir: tmp } })\n return { document: result.document }\n } finally {\n rmSync(tmp, { recursive: true, force: true })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAcA,SAAS,aAAa,cAAc;AACpC,SAAS,cAAc;AACvB,SAAS,MAAM,eAAe;AAO9B,IAAM,mBAAmB;AASzB,eAAsB,eAAe,UAAiC,CAAC,GAAkB;AACvF,QAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACvC,QAAM,SAAS,MAAM,WAAW,GAAG;AAEnC,MAAI,OAAO,YAAY,QAAW;AAChC,YAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQW,gBAAgB;AAAA;AAAA,IAC7B;AACA,YAAQ,KAAK,CAAC;AACd;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,KAAK,OAAO,SAAS;AAC/C,QAAM,WAAW,iBAAiB,SAAS;AAC3C,QAAM,WAAW,MAAM,qBAAqB,EAAE,WAAW,QAAQ,SAAS,OAAO,CAAC;AAElF,MAAI,QAAQ,QAAQ;AAGlB,UAAMA,UAAS,oBAAoB,UAAU,OAAO,OAAO;AAC3D,YAAQ,IAAI;AAAA,mCAAiC,OAAO,SAAS,MAAM,CAAC,MAAM;AAC1E,YAAQ,IAAI,KAAK,UAAUA,QAAO,UAAU,MAAM,CAAC,CAAC;AACpD,YAAQ,IAAI;AAAA,UAAa,gBAAgB;AAAA,CAAI;AAC7C;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,KAAK,OAAO,OAAO;AAC3C,QAAM,SAAS,YAAY;AAAA,IACzB,UAAU;AAAA,IACV,QAAQ,EAAE,GAAG,OAAO,SAAS,QAAQ,QAAQ;AAAA,EAC/C,CAAC;AACD,UAAQ;AAAA,IACN;AAAA,yBAAuB,OAAO,SAAS,MAAM,CAAC,eAAU,OAAO,IAAI;AAAA,UACtD,gBAAgB;AAAA;AAAA,EAC/B;AACF;AAYA,SAAS,oBACP,UACA,QACuB;AACvB,QAAM,MAAM,YAAY,KAAK,OAAO,GAAG,yBAAyB,CAAC;AACjE,MAAI;AACF,UAAM,SAAS,YAAY,EAAE,UAAU,QAAQ,EAAE,GAAG,QAAQ,QAAQ,IAAI,EAAE,CAAC;AAC3E,WAAO,EAAE,UAAU,OAAO,SAAS;AAAA,EACrC,UAAE;AACA,WAAO,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAC9C;AACF;","names":["result"]}
@@ -1,4 +1,4 @@
1
- import { T as TheoPlugin, a as TheoApp, P as PluginContext, H as HookResult, R as RunHookOptions } from './plugin-types-D69-lJZ9.js';
1
+ import { T as TheoPlugin, a as TheoApp, P as PluginContext, H as HookResult, R as RunHookOptions } from './plugin-types-BUVfUQ0V.js';
2
2
 
3
3
  declare class DuplicatePluginError extends Error {
4
4
  constructor(name: string);
@@ -7,6 +7,15 @@ interface PluginContext {
7
7
  * `request.method` is portable across `theokit dev` / `theokit start` (Node) and Web runtimes (#119,
8
8
  * ADR-0028 R3a). Method + absolute URL + headers; the request body is not exposed here (onRequest /
9
9
  * preHandler fire before the body is parsed — the handler reads it via `ctx.body`).
10
+ *
11
+ * `request.url` is ABSOLUTE (`http://host/api/thing`), because that is what a Web `Request`
12
+ * carries. A guard written as `request.url.startsWith('/api/')` is therefore false for every real
13
+ * request and fails silently — the hook simply never matches. To match on a path:
14
+ *
15
+ * ```ts
16
+ * const { pathname } = new URL(ctx.request.url)
17
+ * if (pathname.startsWith('/api/')) { … }
18
+ * ```
10
19
  */
11
20
  request: Request;
12
21
  response: ServerResponse;
@@ -49,6 +58,9 @@ interface TheoPlugin {
49
58
  * Available during `onResponse` / `onError`. `undefined` during
50
59
  * `onRequest` / `preHandler` (which fire before the handler runs).
51
60
  * - `ctx` / `requestId` — same semantics as the IncomingMessage path.
61
+ *
62
+ * `request.url` is ABSOLUTE here too — see the note on `PluginContext.request`; match paths with
63
+ * `new URL(ctx.request.url).pathname`, never `request.url.startsWith('/…')`.
52
64
  */
53
65
  interface WebPluginContext {
54
66
  request: Request;
@@ -65,4 +77,4 @@ type WebPreHandlerHook = (ctx: WebPluginContext) => void | Promise<void>;
65
77
  type WebOnResponseHook = (ctx: WebPluginContext) => void | Promise<void>;
66
78
  type WebOnErrorHook = (ctx: WebPluginErrorContext) => void | Promise<void>;
67
79
 
68
- export type { HookResult as H, OnErrorHook as O, PluginContext as P, RunHookOptions as R, TheoPlugin as T, WebOnRequestHook as W, TheoApp as a, WebPreHandlerHook as b, WebOnResponseHook as c, WebOnErrorHook as d, HookName as e, OnRequestHook as f, OnResponseHook as g, PluginErrorContext as h, PreHandlerHook as i };
80
+ export type { HookResult as H, OnErrorHook as O, PluginContext as P, RunHookOptions as R, TheoPlugin as T, WebOnRequestHook as W, TheoApp as a, HookName as b, OnRequestHook as c, OnResponseHook as d, PluginErrorContext as e, PreHandlerHook as f, WebPreHandlerHook as g, WebOnResponseHook as h, WebOnErrorHook as i };
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import "tsx/esm";
3
+
4
+ // src/cli/commands/preview.ts
5
+ async function defaultSteps() {
6
+ const [{ buildCommand }, { startCommand }] = await Promise.all([
7
+ import("./build-FLX6VF7Q.js"),
8
+ import("./start-UZDMOT7I.js")
9
+ ]);
10
+ return {
11
+ build: (opts) => buildCommand(opts),
12
+ start: (opts) => startCommand(opts)
13
+ };
14
+ }
15
+ async function previewCommand(options = {}, steps) {
16
+ const { build, start } = steps ?? await defaultSteps();
17
+ await build({ target: options.target });
18
+ await start({ port: options.port });
19
+ }
20
+ export {
21
+ previewCommand
22
+ };
23
+ //# sourceMappingURL=preview-GHPT2EQ5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/preview.ts"],"sourcesContent":["/**\n * `theokit preview` — build for production, then serve the result.\n *\n * Reproducing production locally was two commands, `theokit build` then\n * `theokit start`, and the two-step version fails silently: `start` serves\n * whatever `.theokit/` already holds, so a skipped build serves the previous one\n * and nothing says so. The gap is widest exactly when it matters — after a\n * change, checking whether the change works (B-030).\n *\n * This is not a third implementation of either step. It calls both, in order,\n * and never reaches the second when the first throws. `build` and `start` stay\n * separately invocable because CI builds and serves in different jobs.\n */\n\nexport interface PreviewOptions {\n /** Port for the production server. Forwarded to `start`. */\n port?: number\n /** Deploy target to build for. Forwarded to `build`. */\n target?: string\n}\n\n/**\n * The two steps, injected so the composition can be tested without running a\n * real build — the composition IS the behaviour here, and a test that shells out\n * to a full build would be testing the build.\n */\nexport interface PreviewSteps {\n build: (opts: { target?: string }) => Promise<void>\n start: (opts: { port?: number }) => Promise<void>\n}\n\nasync function defaultSteps(): Promise<PreviewSteps> {\n const [{ buildCommand }, { startCommand }] = await Promise.all([\n import('./build.js'),\n import('./start/index.js'),\n ])\n return {\n build: (opts) => buildCommand(opts),\n start: (opts) => startCommand(opts),\n }\n}\n\nexport async function previewCommand(\n options: PreviewOptions = {},\n steps?: PreviewSteps,\n): Promise<void> {\n const { build, start } = steps ?? (await defaultSteps())\n\n // No catch: a build failure must reach the caller unchanged. Swallowing it\n // here and starting anyway would serve the previous build — the exact defect\n // this command exists to remove, reproduced inside its own fix.\n await build({ target: options.target })\n await start({ port: options.port })\n}\n"],"mappings":";;;;AA+BA,eAAe,eAAsC;AACnD,QAAM,CAAC,EAAE,aAAa,GAAG,EAAE,aAAa,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC7D,OAAO,qBAAY;AAAA,IACnB,OAAO,qBAAkB;AAAA,EAC3B,CAAC;AACD,SAAO;AAAA,IACL,OAAO,CAAC,SAAS,aAAa,IAAI;AAAA,IAClC,OAAO,CAAC,SAAS,aAAa,IAAI;AAAA,EACpC;AACF;AAEA,eAAsB,eACpB,UAA0B,CAAC,GAC3B,OACe;AACf,QAAM,EAAE,OAAO,MAAM,IAAI,SAAU,MAAM,aAAa;AAKtD,QAAM,MAAM,EAAE,QAAQ,QAAQ,OAAO,CAAC;AACtC,QAAM,MAAM,EAAE,MAAM,QAAQ,KAAK,CAAC;AACpC;","names":[]}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Provider Resolver — Strategy + Registry pattern (FAANG-grade).
3
+ *
4
+ * Inspiration: Dapr Conversation Registry (`dapr/pkg/components/conversation/registry.go`)
5
+ * + Encore Manager provider array (`encore/runtimes/go/pubsub/manager_internal.go`).
6
+ *
7
+ * Principle: provider routing is the FRAMEWORK's responsibility, not the consumer's — but the
8
+ * consumer still gets to SAY which provider it wants, and it says so in the model id.
9
+ *
10
+ * `provider/model` is the convention every agent in this ecosystem already writes
11
+ * (`anthropic/claude-sonnet-4-6`, `openrouter/anthropic/claude-haiku-4.5`), and it is the one the
12
+ * SDK routes on. Until theokit#326 this resolver ignored it entirely and picked by env-var
13
+ * priority, so an agent that declared `anthropic/...` was handed an OpenRouter key whenever one
14
+ * happened to be present — and every turn failed with `auth_failed (HTTP 401)` against a provider
15
+ * nobody asked for. The declared provider now wins; priority is the fallback for a bare model id.
16
+ *
17
+ * Wire protocol: OpenAI Chat Completions (universal — implemented by every
18
+ * os providers: OpenRouter, Groq, Mistral, Together, Anthropic via proxy, etc).
19
+ *
20
+ * Resolution by priority (FIRST match wins):
21
+ * 1. OPENROUTER_API_KEY → baseUrl=openrouter.ai (multi-model gateway)
22
+ * 2. OPENAI_API_KEY → baseUrl=api.openai.com
23
+ * 3. ANTHROPIC_API_KEY → direct Anthropic (Messages API, not OpenAI-compat)
24
+ *
25
+ * Escape hatch: an explicit `options.apiKey` OVERRIDES auto-resolution
26
+ * (the consumer can force a specific provider if it wants to).
27
+ */
28
+ /**
29
+ * Provider configuration descriptor — Registry entry shape.
30
+ *
31
+ * @public
32
+ */
33
+ interface ProviderDescriptor {
34
+ /** Stable name used internally — not exposed on the wire. */
35
+ name: string;
36
+ /**
37
+ * Environment variable that holds the API key for this provider.
38
+ *
39
+ * **Absent means the provider needs no credential** — a model running on the developer's own
40
+ * machine has nothing to authenticate against. Such a provider is reachable ONLY when a model id
41
+ * names it (`ollama/llama3.2`); it never participates in the priority walk, because the walk
42
+ * reads "this variable is set" as "a human configured this provider", and a keyless entry offers
43
+ * no equivalent signal. Including it would route every bare model id to localhost the moment no
44
+ * cloud key was set (usetheokit/theokit#407).
45
+ */
46
+ envKey?: string;
47
+ /** Base URL for the provider's OpenAI-compatible (or native) API. */
48
+ baseUrl: string;
49
+ /**
50
+ * Environment variable that OVERRIDES {@link baseUrl} when set.
51
+ *
52
+ * Scoped honestly: every caller inside this framework takes `.apiKey` from the resolved provider
53
+ * and discards `.baseUrl` (`cli/commands/start/handlers.ts`, `vite-plugin/api-middleware.ts`,
54
+ * `cli/commands/agent.ts`), so the endpoint a request actually reaches is chosen by the SDK, from
55
+ * its own profile — which reads `OLLAMA_HOST` itself. This field therefore does not redirect
56
+ * traffic today.
57
+ *
58
+ * It exists so that the `baseUrl` this function REPORTS agrees with where the request goes, for
59
+ * the consumers that read it — `resolveProvider` is public API, and a reported endpoint that
60
+ * contradicts the real one is a debugging trap rather than a harmless inaccuracy.
61
+ */
62
+ baseUrlEnv?: string;
63
+ /** Resolution priority (lower = higher priority). FIRST match wins. */
64
+ priority: number;
65
+ }
66
+ /**
67
+ * Resolved provider configuration — output of `resolveProvider()`.
68
+ *
69
+ * @public
70
+ */
71
+ interface ResolvedProvider {
72
+ name: string;
73
+ apiKey: string;
74
+ baseUrl: string;
75
+ }
76
+ /** Where the announcement goes, and what it may contain. @public */
77
+ interface ResolveOptions {
78
+ /** Receives one line per provider, at most once. NEVER receives the key. */
79
+ announce?: (line: string) => void;
80
+ }
81
+ /**
82
+ * Register a new provider (Registry pattern — runtime extension point).
83
+ * Useful for self-hosted endpoints or custom providers without touching theokit src.
84
+ *
85
+ * @example
86
+ * registerProvider({
87
+ * name: 'self-hosted',
88
+ * envKey: 'SELF_HOSTED_API_KEY',
89
+ * baseUrl: 'https://llm.internal.acme.com/v1',
90
+ * priority: 0, // highest priority
91
+ * })
92
+ *
93
+ * @public
94
+ */
95
+ declare function registerProvider(descriptor: ProviderDescriptor): void;
96
+ /**
97
+ * Reset registry to DEFAULT_REGISTRY (test-only / dev escape hatch).
98
+ *
99
+ * @public
100
+ */
101
+ declare function resetProviderRegistry(): void;
102
+ /**
103
+ * Get current registry snapshot (read-only — inspection).
104
+ *
105
+ * @public
106
+ */
107
+ declare function listProviders(): readonly ProviderDescriptor[];
108
+ /**
109
+ * Resolve the provider for a model.
110
+ *
111
+ * When `modelId` declares a registered provider (`anthropic/…`), THAT provider's key is
112
+ * required — no substitution. Otherwise the registry is walked by priority, first match wins.
113
+ *
114
+ * @returns ResolvedProvider with apiKey + baseUrl + name
115
+ * @throws Error if NO provider env var is set (actionable message)
116
+ *
117
+ * @public
118
+ */
119
+ declare function resolveProvider(modelId?: string, options?: ResolveOptions): ResolvedProvider;
120
+ /**
121
+ * Try to resolve — does NOT throw. Returns null if no provider available.
122
+ * Useful for graceful degradation (e.g., mock mode).
123
+ *
124
+ * @public
125
+ */
126
+ declare function tryResolveProvider(modelId?: string): ResolvedProvider | null;
127
+
128
+ export { type ProviderDescriptor as P, type ResolvedProvider as R, registerProvider as a, resetProviderRegistry as b, listProviders as l, resolveProvider as r, tryResolveProvider as t };
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import "tsx/esm";
3
+
4
+ // src/adapters/registry.ts
5
+ var adapterRegistry = {
6
+ node: async () => (await import("./node-OSVPYQ3D.js")).nodeAdapter,
7
+ vercel: async () => (await import("./vercel-BMCQKCWE.js")).vercelAdapter,
8
+ cloudflare: async () => (await import("./cloudflare-SIG42OIW.js")).cloudflareAdapter,
9
+ static: async () => (await import("./static-SVDWIOXJ.js")).staticAdapter,
10
+ bun: async () => (await import("./bun-L7PP6ID5.js")).bunAdapter,
11
+ "deno-deploy": async () => (await import("./deno-deploy-LQAYOOPW.js")).denoDeployAdapter,
12
+ netlify: async () => (await import("./netlify-C2IRCZKI.js")).netlifyAdapter,
13
+ "aws-lambda": async () => (await import("./aws-lambda-VKMYUMP2.js")).awsLambdaAdapter,
14
+ "theo-cloud": async () => (await import("./theo-cloud-3ET4G5T6.js")).theoCloudAdapter
15
+ };
16
+ async function resolveAdapter(target) {
17
+ const factory = adapterRegistry[target];
18
+ return factory();
19
+ }
20
+ export {
21
+ resolveAdapter
22
+ };
23
+ //# sourceMappingURL=registry-KBZDCFVQ.js.map
@@ -0,0 +1,72 @@
1
+ import { z } from 'zod';
2
+ import { R as RoutePolicy } from './route-policy-BxOycCDq.js';
3
+
4
+ /**
5
+ * core/contracts/route-config.ts
6
+ *
7
+ * Canonical home for `RouteConfig<TQuery, TBody, TParams, TCtx, TResponse>` —
8
+ * the contract shape consumed by `defineRoute()` (server) and
9
+ * `defineCachedRoute()` (cache).
10
+ *
11
+ * Moved here in T2.2 of architecture-cleanup so `cache → core/contracts`
12
+ * is the legal edge (replacing the prior `cache → server` violation).
13
+ *
14
+ * GAP-4 (plan v1.1): the 5-arity generic shape `<TQuery, TBody, TParams, TCtx, TResponse>`
15
+ * MUST be preserved byte-by-byte. Type tests assert this in
16
+ * `tests/unit/route-config-generic-arity.test.ts`.
17
+ */
18
+
19
+ interface RouteConfig<TQuery extends z.ZodType = z.ZodUndefined, TBody extends z.ZodType = z.ZodUndefined, TParams extends z.ZodType = z.ZodUndefined, TCtx = unknown, TResponse = unknown> {
20
+ query?: TQuery;
21
+ body?: TBody;
22
+ params?: TParams;
23
+ status?: number;
24
+ /**
25
+ * Optional Zod schema for the handler's plain-object return value. When
26
+ * present, BOTH runtimes (Node `executeRoute` + Web `executeWebRequest`)
27
+ * validate the handler's plain-object return against it BEFORE serializing.
28
+ *
29
+ * A mismatch is a SERVER fault (the handler violated its own declared
30
+ * contract) → 500 `INTERNAL_SERVER_ERROR`, distinct from the 400 used for
31
+ * input (`query`/`body`/`params`) validation failures.
32
+ *
33
+ * `Response`-instance returns (and `undefined`/`null` → 204) are NOT
34
+ * validated. This is a plain optional field — runtime validation only; the
35
+ * handler return type is NOT statically inferred from `response` (YAGNI).
36
+ */
37
+ response?: z.ZodType;
38
+ /**
39
+ * Opt out of CSRF enforcement for this route. Use for endpoints that
40
+ * legitimately receive third-party POSTs (Stripe webhooks, GitHub
41
+ * webhooks, OAuth callbacks). Defaults to enforced per `config.security.csrf`.
42
+ *
43
+ * Setting `csrf: false` only disables the per-route check — it does NOT
44
+ * disable the global mode setting for other routes.
45
+ */
46
+ csrf?: false;
47
+ /**
48
+ * Who may perform this operation (ADR 0001).
49
+ *
50
+ * Evaluated by the Node executor, the Web executor AND `callProcedure`, from
51
+ * one implementation — which is what makes "the same route gives the same
52
+ * access decision on every transport" a property of the code. Before this
53
+ * existed, a route's access rules applied over HTTP and applied nowhere
54
+ * in-process, and in-process is the path the desktop and terminal targets are
55
+ * built on.
56
+ *
57
+ * `'public'` is a declaration and not a default. Absence currently means "not
58
+ * declared" and is NOT reinterpreted as denial at runtime: flipping that would
59
+ * break every existing route in every consumer at once. The ADR routes it
60
+ * through a build-time gate and a migration instead.
61
+ */
62
+ policy?: RoutePolicy<z.infer<TQuery>, z.infer<TBody>, z.infer<TParams>>;
63
+ handler: (ctx: {
64
+ query: z.infer<TQuery>;
65
+ body: z.infer<TBody>;
66
+ params: z.infer<TParams>;
67
+ request: Request;
68
+ ctx: TCtx;
69
+ }) => TResponse | Promise<TResponse>;
70
+ }
71
+
72
+ export type { RouteConfig as R };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Who is asking. Supplied by the caller through the run-context, never read from
3
+ * a transport.
4
+ *
5
+ * A cookie is one way to establish this and a terminal has no cookies, so the
6
+ * contract takes the resolved subject rather than the mechanism that resolved it
7
+ * (ADR 0001 section Decision, point 4).
8
+ */
9
+ interface RouteSubject {
10
+ id: string;
11
+ [claim: string]: unknown;
12
+ }
13
+ /** The answer a policy gives. A denial carries its reason so the caller can say it. */
14
+ type AccessDecision = {
15
+ allowed: true;
16
+ } | {
17
+ allowed: false;
18
+ reason: string;
19
+ };
20
+ /** What a policy is handed. Deliberately transport-free: no headers, no cookies, no response. */
21
+ interface RoutePolicyInput<TQuery = unknown, TBody = unknown, TParams = unknown> {
22
+ subject: RouteSubject | null;
23
+ query: TQuery;
24
+ body: TBody;
25
+ params: TParams;
26
+ }
27
+ /**
28
+ * A route's access policy.
29
+ *
30
+ * `'public'` is a declaration, not a default. The point of writing it is that
31
+ * openness becomes greppable — today a route that enforces nothing looks exactly
32
+ * like a route nobody thought about (ADR 0001 section Consequences, Risks).
33
+ */
34
+ type RoutePolicy<TQuery = unknown, TBody = unknown, TParams = unknown> = 'public' | ((input: RoutePolicyInput<TQuery, TBody, TParams>) => boolean | AccessDecision | Promise<boolean | AccessDecision>);
35
+ /** Narrow a run-context to the subject it carries, if it carries one. */
36
+ declare function subjectFromContext(context: unknown): RouteSubject | null;
37
+ /**
38
+ * Evaluate a route policy. THE single implementation - the HTTP executors and
39
+ * the in-process caller all reach this function, which is what makes "the same
40
+ * route gives the same access decision on every transport" a property of the code
41
+ * rather than a claim in a document.
42
+ *
43
+ * The shape mirrors `validateRouteInput`, which is already described in-source as
44
+ * "the SINGLE shared pipeline ... One pipeline, no drift". Access control had no
45
+ * such pipeline; that absence is what ADR 0001 exists to close.
46
+ *
47
+ * An undeclared policy returns `allowed` and is NOT the same thing as `'public'`.
48
+ * Absence is refused where an application DECLARES its routes — the file-system
49
+ * scanner fails the build naming the file (`MissingRoutePolicyError`) — and not
50
+ * here, where the argument may be a `RouteConfig` a caller built in memory and
51
+ * never scanned. Reinterpreting absence as denial at this point would break
52
+ * every direct caller of the executors at once, which the ADR routes through the
53
+ * build gate and a migration instead.
54
+ */
55
+ declare function evaluateRoutePolicy(policy: RoutePolicy | undefined, input: RoutePolicyInput): Promise<AccessDecision>;
56
+ /**
57
+ * The authorization primitive the framework did not have.
58
+ *
59
+ * `requireAuth` answers "is anyone there". Every action then answered "may THIS
60
+ * subject touch THIS record" on its own, which is one implementation per action
61
+ * and one place per action to get it wrong. This is that answer, once.
62
+ */
63
+ declare function requireOwner(subject: RouteSubject | null, ownerId: string | null | undefined): AccessDecision;
64
+
65
+ export { type AccessDecision as A, type RoutePolicy as R, type RouteSubject as a, type RoutePolicyInput as b, evaluateRoutePolicy as e, requireOwner as r, subjectFromContext as s };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Restore the scroll offset of elements the application marked as scrollers (#421).
3
+ *
4
+ * Mounted beside react-router's `<ScrollRestoration>`, not instead of it: that one owns the
5
+ * DOCUMENT, correctly and with its own timing, and this one owns the elements it cannot see. An app
6
+ * whose document scrolls keeps exactly the behaviour it had.
7
+ *
8
+ * ## What an application does
9
+ *
10
+ * ```tsx
11
+ * <main data-theo-scroll="main" className="overflow-y-auto">…</main>
12
+ * ```
13
+ *
14
+ * The attribute's VALUE is the id, so two scrollers on one page stay distinguishable.
15
+ *
16
+ * ## Why every decision is elsewhere
17
+ *
18
+ * This component queries, sequences, and nothing else — `scroll-restoration.ts` decides which key
19
+ * an offset lands under, when it is read back, and what happens to an element that is gone on
20
+ * return. That split is because this repository sets up no DOM test environment, so the part that
21
+ * cannot be covered by a test is deliberately the part with no branches in it.
22
+ *
23
+ * `useLayoutEffect` and not `useEffect`: the offset must be applied before the browser paints, or
24
+ * the user sees the top of the list and then a jump.
25
+ */
26
+ declare function ElementScrollRestoration(): null;
27
+
28
+ export { ElementScrollRestoration };