theokit 0.48.14 → 0.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/README.md +1 -0
  2. package/dist/{actions-virtual-module-YZRZMHAX.js → actions-virtual-module-DSIVNGK7.js} +14 -8
  3. package/dist/{actions-virtual-module-YZRZMHAX.js.map → actions-virtual-module-DSIVNGK7.js.map} +1 -1
  4. package/dist/{actions-virtual-module-E4PISKMB.js → actions-virtual-module-RXL2RJTW.js} +23 -12
  5. package/dist/actions-virtual-module-RXL2RJTW.js.map +1 -0
  6. package/dist/adapters/agent-mount.d.ts +127 -0
  7. package/dist/adapters/agent-mount.js +25 -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-7IPEVCAY.js +15 -0
  15. package/dist/agent-scan-BZa-pagG.d.ts +16 -0
  16. package/dist/{app-typed-client-I4X2UJWW.js → app-typed-client-UTBMJZOE.js} +15 -9
  17. package/dist/app-typed-client-UTBMJZOE.js.map +1 -0
  18. package/dist/{app-typed-client-HLP26EYM.js → app-typed-client-XGDZKH73.js} +24 -13
  19. package/dist/app-typed-client-XGDZKH73.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/{body-parser-web-4Z2QTPDU.js → body-parser-web-ON5CUTEL.js} +5 -2
  23. package/dist/body-parser-web-ON5CUTEL.js.map +1 -0
  24. package/dist/{body-parser-web-TIOTXPDW.js → body-parser-web-RV2SSAI3.js} +5 -2
  25. package/dist/body-parser-web-RV2SSAI3.js.map +1 -0
  26. package/dist/{build-F2Q5QTSC.js → build-VZODSYIQ.js} +72 -26
  27. package/dist/build-VZODSYIQ.js.map +1 -0
  28. package/dist/{bun-A5B2MJMO.js → bun-L7PP6ID5.js} +105 -13
  29. package/dist/bun-L7PP6ID5.js.map +1 -0
  30. package/dist/{check-45NKUVSQ.js → check-GIPZBFTX.js} +2 -2
  31. package/dist/{chunk-WYHYOYRH.js → chunk-2COPDKIG.js} +468 -203
  32. package/dist/chunk-2COPDKIG.js.map +1 -0
  33. package/dist/chunk-3PBAN2YE.js +146 -0
  34. package/dist/chunk-3PBAN2YE.js.map +1 -0
  35. package/dist/{chunk-HBU2GIMZ.js → chunk-3QPVEJ7D.js} +15 -9
  36. package/dist/chunk-3QPVEJ7D.js.map +1 -0
  37. package/dist/{chunk-IEES3CHD.js → chunk-47MM2JUK.js} +8 -2
  38. package/dist/chunk-47MM2JUK.js.map +1 -0
  39. package/dist/chunk-4X6H2BXP.js +108 -0
  40. package/dist/chunk-4X6H2BXP.js.map +1 -0
  41. package/dist/{chunk-A7JBF5FO.js → chunk-5K4TDLRG.js} +8 -5
  42. package/dist/chunk-5K4TDLRG.js.map +1 -0
  43. package/dist/chunk-5YPXXSYY.js +181 -0
  44. package/dist/chunk-5YPXXSYY.js.map +1 -0
  45. package/dist/{chunk-YGAXV5HR.js → chunk-6J4JWHDJ.js} +191 -112
  46. package/dist/chunk-6J4JWHDJ.js.map +1 -0
  47. package/dist/{chunk-FTFN4MYN.js → chunk-7AEBH52I.js} +639 -516
  48. package/dist/chunk-7AEBH52I.js.map +1 -0
  49. package/dist/chunk-7UZZHCRN.js +21 -0
  50. package/dist/chunk-7UZZHCRN.js.map +1 -0
  51. package/dist/{chunk-MTEWLGVY.js → chunk-BPYMC7SU.js} +4 -48
  52. package/dist/chunk-BPYMC7SU.js.map +1 -0
  53. package/dist/chunk-BU6RJPPJ.js +421 -0
  54. package/dist/chunk-BU6RJPPJ.js.map +1 -0
  55. package/dist/{chunk-FB2HBNIC.js → chunk-BX6EUYHU.js} +6 -2
  56. package/dist/chunk-BX6EUYHU.js.map +1 -0
  57. package/dist/chunk-CHTAWXC2.js +18 -0
  58. package/dist/chunk-CHTAWXC2.js.map +1 -0
  59. package/dist/chunk-D4VP2QPR.js +16 -0
  60. package/dist/chunk-D4VP2QPR.js.map +1 -0
  61. package/dist/{chunk-YXG2SGQ3.js → chunk-DHAD2O3S.js} +6 -6
  62. package/dist/chunk-DHAD2O3S.js.map +1 -0
  63. package/dist/chunk-DOI4G4X3.js +428 -0
  64. package/dist/chunk-DOI4G4X3.js.map +1 -0
  65. package/dist/chunk-E43VJ3E5.js +188 -0
  66. package/dist/chunk-E43VJ3E5.js.map +1 -0
  67. package/dist/{chunk-47CINLWF.js → chunk-EDWEYQRG.js} +2 -2
  68. package/dist/chunk-EVZKNA2W.js +110 -0
  69. package/dist/chunk-EVZKNA2W.js.map +1 -0
  70. package/dist/chunk-FD4ZDTQ6.js +181 -0
  71. package/dist/chunk-FD4ZDTQ6.js.map +1 -0
  72. package/dist/chunk-FDOOBTXJ.js +17 -0
  73. package/dist/chunk-FDOOBTXJ.js.map +1 -0
  74. package/dist/chunk-FH3SQR6P.js +275 -0
  75. package/dist/chunk-FH3SQR6P.js.map +1 -0
  76. package/dist/{chunk-T5C46IIU.js → chunk-FMTRNQQ7.js} +28 -269
  77. package/dist/chunk-FMTRNQQ7.js.map +1 -0
  78. package/dist/chunk-H53KNS6Q.js +513 -0
  79. package/dist/chunk-H53KNS6Q.js.map +1 -0
  80. package/dist/chunk-HJHGTFEJ.js +23 -0
  81. package/dist/chunk-HJHGTFEJ.js.map +1 -0
  82. package/dist/{chunk-LXAESF4Y.js → chunk-HK4AZBKX.js} +7 -4
  83. package/dist/chunk-HK4AZBKX.js.map +1 -0
  84. package/dist/chunk-IRQGAC4L.js +52 -0
  85. package/dist/chunk-IRQGAC4L.js.map +1 -0
  86. package/dist/{chunk-FNTLKHZ7.js → chunk-JDN5SAAD.js} +7 -4
  87. package/dist/chunk-JDN5SAAD.js.map +1 -0
  88. package/dist/{chunk-XALU5LCU.js → chunk-JKF25N73.js} +555 -147
  89. package/dist/chunk-JKF25N73.js.map +1 -0
  90. package/dist/{chunk-BHOTGS7N.js → chunk-KI4DOTN4.js} +25 -2
  91. package/dist/chunk-KI4DOTN4.js.map +1 -0
  92. package/dist/chunk-KOS567NB.js +790 -0
  93. package/dist/chunk-KOS567NB.js.map +1 -0
  94. package/dist/{chunk-OOBYPCZC.js → chunk-KTS6G26H.js} +304 -195
  95. package/dist/chunk-KTS6G26H.js.map +1 -0
  96. package/dist/{chunk-ZB7D62OA.js → chunk-KUZVRJ7M.js} +3 -3
  97. package/dist/chunk-L4VFNFDL.js +248 -0
  98. package/dist/chunk-L4VFNFDL.js.map +1 -0
  99. package/dist/chunk-M2WC5MF7.js +127 -0
  100. package/dist/chunk-M2WC5MF7.js.map +1 -0
  101. package/dist/chunk-N42ZWWOW.js +273 -0
  102. package/dist/chunk-N42ZWWOW.js.map +1 -0
  103. package/dist/chunk-OGLS76RN.js +43 -0
  104. package/dist/chunk-OGLS76RN.js.map +1 -0
  105. package/dist/{chunk-7LVM22VG.js → chunk-OQCRCXCP.js} +6 -6
  106. package/dist/chunk-OQCRCXCP.js.map +1 -0
  107. package/dist/{chunk-OLGPYOLO.js → chunk-P6OS7652.js} +5 -2
  108. package/dist/chunk-P6OS7652.js.map +1 -0
  109. package/dist/{chunk-O3JIAU3V.js → chunk-PF3YM6NY.js} +157 -103
  110. package/dist/chunk-PF3YM6NY.js.map +1 -0
  111. package/dist/{chunk-NTWNO24W.js → chunk-PLUHPNGA.js} +266 -110
  112. package/dist/chunk-PLUHPNGA.js.map +1 -0
  113. package/dist/chunk-Q5L5EGWZ.js +26 -0
  114. package/dist/chunk-Q5L5EGWZ.js.map +1 -0
  115. package/dist/{chunk-AATSV4UV.js → chunk-QTHVHNJJ.js} +6 -36
  116. package/dist/chunk-QTHVHNJJ.js.map +1 -0
  117. package/dist/{chunk-KD5G3YXI.js → chunk-RARK7JBR.js} +39 -10
  118. package/dist/chunk-RARK7JBR.js.map +1 -0
  119. package/dist/chunk-RJJF457I.js +111 -0
  120. package/dist/chunk-RJJF457I.js.map +1 -0
  121. package/dist/chunk-RPET332G.js +84 -0
  122. package/dist/chunk-RPET332G.js.map +1 -0
  123. package/dist/{chunk-646CA6RV.js → chunk-RQW5YMH7.js} +12 -4
  124. package/dist/chunk-RQW5YMH7.js.map +1 -0
  125. package/dist/chunk-U5PWXS3J.js +39 -0
  126. package/dist/chunk-U5PWXS3J.js.map +1 -0
  127. package/dist/{chunk-RWNSW4FM.js → chunk-UMNXCU3K.js} +12 -6
  128. package/dist/{chunk-RWNSW4FM.js.map → chunk-UMNXCU3K.js.map} +1 -1
  129. package/dist/{chunk-DS5MCU2X.js → chunk-URCXSUI3.js} +9 -9
  130. package/dist/chunk-VI7ZANB3.js +193 -0
  131. package/dist/chunk-VI7ZANB3.js.map +1 -0
  132. package/dist/chunk-VQPHPQ5L.js +14 -0
  133. package/dist/chunk-VQPHPQ5L.js.map +1 -0
  134. package/dist/chunk-WNJTJRM6.js +147 -0
  135. package/dist/chunk-WNJTJRM6.js.map +1 -0
  136. package/dist/{chunk-BMHS4WAN.js → chunk-XS7EX55U.js} +156 -42
  137. package/dist/chunk-XS7EX55U.js.map +1 -0
  138. package/dist/chunk-YN4W7LCX.js +31 -0
  139. package/dist/chunk-YN4W7LCX.js.map +1 -0
  140. package/dist/chunk-YSJOZEI6.js +1 -0
  141. package/dist/{chunk-JA2ZAT5Q.js → chunk-Z4PJMZLM.js} +2 -2
  142. package/dist/chunk-Z4PJMZLM.js.map +1 -0
  143. package/dist/{chunk-WSXNGF7X.js → chunk-ZNZISJDZ.js} +6 -2
  144. package/dist/chunk-ZNZISJDZ.js.map +1 -0
  145. package/dist/chunk-ZWN3AODA.js +11 -0
  146. package/dist/chunk-ZWN3AODA.js.map +1 -0
  147. package/dist/cli/index.js +25 -10
  148. package/dist/cli/index.js.map +1 -1
  149. package/dist/client/core.d.ts +1 -1
  150. package/dist/client/core.js +2 -0
  151. package/dist/client/core.js.map +1 -1
  152. package/dist/client/index.d.ts +44 -10
  153. package/dist/client/index.js +35 -0
  154. package/dist/client/index.js.map +1 -1
  155. package/dist/cloudflare-SIG42OIW.js +335 -0
  156. package/dist/cloudflare-SIG42OIW.js.map +1 -0
  157. package/dist/config-support-WQHQIJTA.js +104 -0
  158. package/dist/config-support-WQHQIJTA.js.map +1 -0
  159. package/dist/{csrf-BBrEZSBW.d.ts → csrf-Dgot9qSM.d.ts} +1 -1
  160. package/dist/deno-deploy-LQAYOOPW.js +196 -0
  161. package/dist/deno-deploy-LQAYOOPW.js.map +1 -0
  162. package/dist/{dev-CDFPXISP.js → dev-3UQVD2W6.js} +29 -18
  163. package/dist/dev-3UQVD2W6.js.map +1 -0
  164. package/dist/{dev-emit-GWD6IXV7.js → dev-emit-BFNMDCPB.js} +5 -5
  165. package/dist/{dev-emit-NBT6JD7R.js → dev-emit-MVAJAFGX.js} +5 -3
  166. package/dist/dev-emit-MVAJAFGX.js.map +1 -0
  167. package/dist/engine-singleton-X4R7AZBJ.js +315 -0
  168. package/dist/engine-singleton-X4R7AZBJ.js.map +1 -0
  169. package/dist/{generate-Y3GWM57K.js → generate-EN6EDITF.js} +43 -4
  170. package/dist/generate-EN6EDITF.js.map +1 -0
  171. package/dist/index-DctfHtv-.d.ts +1058 -0
  172. package/dist/index.d.ts +8 -4
  173. package/dist/index.js +25 -13
  174. package/dist/index.js.map +1 -1
  175. package/dist/{info-QXZW722N.js → info-Y55RWS42.js} +8 -6
  176. package/dist/{info-QXZW722N.js.map → info-Y55RWS42.js.map} +1 -1
  177. package/dist/{internal-api-FBK2YXSI.js → internal-api-4X6NDS2F.js} +23 -12
  178. package/dist/{internal-api-ZCJWJ5EC.js → internal-api-XQHU5JKY.js} +31 -16
  179. package/dist/internal-api-XQHU5JKY.js.map +1 -0
  180. package/dist/load-config-4ATXQUN3.js +16 -0
  181. package/dist/match-DmGgxjIU.d.ts +44 -0
  182. package/dist/{mcp-KTYP4ZON.js → mcp-IQRHFP3Y.js} +7 -7
  183. package/dist/netlify-C2IRCZKI.js +245 -0
  184. package/dist/netlify-C2IRCZKI.js.map +1 -0
  185. package/dist/node-OSVPYQ3D.js +10 -0
  186. package/dist/nonce-BXt7Qu_C.d.ts +31 -0
  187. package/dist/observability-bootstrap-LERYDHKY.js +16 -0
  188. package/dist/{openapi-OUXNB2F2.js → openapi-VFPEZSRI.js} +13 -11
  189. package/dist/{openapi-OUXNB2F2.js.map → openapi-VFPEZSRI.js.map} +1 -1
  190. package/dist/{plugin-runner-DHVr1cC5.d.ts → plugin-runner-BVMOSxvb.d.ts} +1 -1
  191. package/dist/{plugin-types-4VN1GMqV.d.ts → plugin-types-BUVfUQ0V.d.ts} +1 -1
  192. package/dist/preview-BT47VMIB.js +23 -0
  193. package/dist/preview-BT47VMIB.js.map +1 -0
  194. package/dist/provider-resolver-Dx6QuWrw.d.ts +128 -0
  195. package/dist/registry-KBZDCFVQ.js +23 -0
  196. package/dist/route-config-Cm_ZMA1C.d.ts +72 -0
  197. package/dist/route-policy-BxOycCDq.d.ts +65 -0
  198. package/dist/router/element-scroll-restoration.d.ts +28 -0
  199. package/dist/router/element-scroll-restoration.js +96 -0
  200. package/dist/router/element-scroll-restoration.js.map +1 -0
  201. package/dist/{routes-NJR4ISCT.js → routes-BPLU3ISV.js} +11 -9
  202. package/dist/{routes-NJR4ISCT.js.map → routes-BPLU3ISV.js.map} +1 -1
  203. package/dist/{scan-7MJC6PYU.js → scan-YJEE4KQK.js} +2 -2
  204. package/dist/{schema-DNIT7JQX.js → schema-SOAD43RQ.js} +7 -5
  205. package/dist/schemas-4AXHQMV3.js +25 -0
  206. package/dist/schemas-4AXHQMV3.js.map +1 -0
  207. package/dist/security-headers-Ccj7ncNx.d.ts +129 -0
  208. package/dist/server/agent/index.d.ts +2 -105
  209. package/dist/server/agent/index.js +1 -1
  210. package/dist/server/auth/index.d.ts +2 -21
  211. package/dist/server/auth/index.js +3 -2
  212. package/dist/server/cron/index.js +4 -3
  213. package/dist/server/define/index.d.ts +43 -57
  214. package/dist/server/define/index.js +10 -1
  215. package/dist/server/http/index.d.ts +7 -5
  216. package/dist/server/http/index.js +57 -12
  217. package/dist/server/index.d.ts +47 -439
  218. package/dist/server/index.js +120 -201
  219. package/dist/server/index.js.map +1 -1
  220. package/dist/server/jobs/index.js +4 -3
  221. package/dist/server/observability/index.d.ts +109 -35
  222. package/dist/server/observability/index.js +11 -7
  223. package/dist/server/plugins/index.d.ts +3 -3
  224. package/dist/server/scan/index.d.ts +47 -12
  225. package/dist/server/scan/index.js +13 -4
  226. package/dist/server/security/index.d.ts +61 -103
  227. package/dist/server/security/index.js +15 -6
  228. package/dist/server/webhook/index.d.ts +90 -3
  229. package/dist/server/webhook/index.js +12 -2
  230. package/dist/server-boundary-2WFT546S.js +149 -0
  231. package/dist/server-boundary-2WFT546S.js.map +1 -0
  232. package/dist/server-boundary-A67OPRKO.js +134 -0
  233. package/dist/server-boundary-A67OPRKO.js.map +1 -0
  234. package/dist/{services-typed-client-P4JERLBL.js → services-typed-client-XGT5SUUN.js} +2 -2
  235. package/dist/{start-25OV2CAK.js → start-3K3C4Z2X.js} +224 -161
  236. package/dist/start-3K3C4Z2X.js.map +1 -0
  237. package/dist/{static-RTO637XW.js → static-SVDWIOXJ.js} +24 -13
  238. package/dist/static-SVDWIOXJ.js.map +1 -0
  239. package/dist/{theo-cloud-UZ3GINRU.js → theo-cloud-3ET4G5T6.js} +9 -2
  240. package/dist/theo-cloud-3ET4G5T6.js.map +1 -0
  241. package/dist/vercel-BMCQKCWE.js +277 -0
  242. package/dist/vercel-BMCQKCWE.js.map +1 -0
  243. package/dist/vite-plugin/index.js +25 -13
  244. package/dist/vite-plugin-USXUIV3H.js +43 -0
  245. package/dist/vite-plugin-USXUIV3H.js.map +1 -0
  246. package/package.json +19 -6
  247. package/dist/actions-virtual-module-E4PISKMB.js.map +0 -1
  248. package/dist/agent-XAQCUQNB.js +0 -15
  249. package/dist/app-typed-client-HLP26EYM.js.map +0 -1
  250. package/dist/app-typed-client-I4X2UJWW.js.map +0 -1
  251. package/dist/aws-lambda-KES4MFJV.js +0 -172
  252. package/dist/aws-lambda-KES4MFJV.js.map +0 -1
  253. package/dist/body-parser-web-4Z2QTPDU.js.map +0 -1
  254. package/dist/body-parser-web-TIOTXPDW.js.map +0 -1
  255. package/dist/build-F2Q5QTSC.js.map +0 -1
  256. package/dist/bun-A5B2MJMO.js.map +0 -1
  257. package/dist/chunk-646CA6RV.js.map +0 -1
  258. package/dist/chunk-7LVM22VG.js.map +0 -1
  259. package/dist/chunk-A7JBF5FO.js.map +0 -1
  260. package/dist/chunk-AATSV4UV.js.map +0 -1
  261. package/dist/chunk-AM3QABW5.js +0 -161
  262. package/dist/chunk-AM3QABW5.js.map +0 -1
  263. package/dist/chunk-AXKUA57G.js +0 -94
  264. package/dist/chunk-AXKUA57G.js.map +0 -1
  265. package/dist/chunk-BHOTGS7N.js.map +0 -1
  266. package/dist/chunk-BMHS4WAN.js.map +0 -1
  267. package/dist/chunk-CMYSHZFT.js +0 -422
  268. package/dist/chunk-CMYSHZFT.js.map +0 -1
  269. package/dist/chunk-DQIPV7L5.js +0 -118
  270. package/dist/chunk-DQIPV7L5.js.map +0 -1
  271. package/dist/chunk-FB2HBNIC.js.map +0 -1
  272. package/dist/chunk-FNTLKHZ7.js.map +0 -1
  273. package/dist/chunk-FTFN4MYN.js.map +0 -1
  274. package/dist/chunk-HBU2GIMZ.js.map +0 -1
  275. package/dist/chunk-IEES3CHD.js.map +0 -1
  276. package/dist/chunk-JA2ZAT5Q.js.map +0 -1
  277. package/dist/chunk-KD5G3YXI.js.map +0 -1
  278. package/dist/chunk-KTKTHIUF.js +0 -405
  279. package/dist/chunk-KTKTHIUF.js.map +0 -1
  280. package/dist/chunk-LNVMHQ2Z.js +0 -54
  281. package/dist/chunk-LNVMHQ2Z.js.map +0 -1
  282. package/dist/chunk-LXAESF4Y.js.map +0 -1
  283. package/dist/chunk-MTEWLGVY.js.map +0 -1
  284. package/dist/chunk-NTWNO24W.js.map +0 -1
  285. package/dist/chunk-O3JIAU3V.js.map +0 -1
  286. package/dist/chunk-OLGPYOLO.js.map +0 -1
  287. package/dist/chunk-OOBYPCZC.js.map +0 -1
  288. package/dist/chunk-T5C46IIU.js.map +0 -1
  289. package/dist/chunk-U267AOWS.js +0 -28
  290. package/dist/chunk-U267AOWS.js.map +0 -1
  291. package/dist/chunk-UW2TEAGR.js +0 -77
  292. package/dist/chunk-UW2TEAGR.js.map +0 -1
  293. package/dist/chunk-WPJOTQA5.js +0 -1
  294. package/dist/chunk-WSXNGF7X.js.map +0 -1
  295. package/dist/chunk-WYHYOYRH.js.map +0 -1
  296. package/dist/chunk-XALU5LCU.js.map +0 -1
  297. package/dist/chunk-XR74JD4M.js +0 -457
  298. package/dist/chunk-XR74JD4M.js.map +0 -1
  299. package/dist/chunk-YGAXV5HR.js.map +0 -1
  300. package/dist/chunk-YXG2SGQ3.js.map +0 -1
  301. package/dist/cloudflare-IN2WB7FZ.js +0 -122
  302. package/dist/cloudflare-IN2WB7FZ.js.map +0 -1
  303. package/dist/deno-deploy-LYXQEJ6A.js +0 -107
  304. package/dist/deno-deploy-LYXQEJ6A.js.map +0 -1
  305. package/dist/dev-CDFPXISP.js.map +0 -1
  306. package/dist/dev-emit-NBT6JD7R.js.map +0 -1
  307. package/dist/generate-Y3GWM57K.js.map +0 -1
  308. package/dist/index-D_PxPXgQ.d.ts +0 -575
  309. package/dist/load-config-FIWNKOJO.js +0 -14
  310. package/dist/match-CfbEFRG4.d.ts +0 -26
  311. package/dist/netlify-DLEOCFAD.js +0 -150
  312. package/dist/netlify-DLEOCFAD.js.map +0 -1
  313. package/dist/node-QXYSUWQ4.js +0 -10
  314. package/dist/registry-S7OMF3OS.js +0 -23
  315. package/dist/start-25OV2CAK.js.map +0 -1
  316. package/dist/static-RTO637XW.js.map +0 -1
  317. package/dist/theo-cloud-UZ3GINRU.js.map +0 -1
  318. package/dist/vercel-6D6EZUVD.js +0 -133
  319. package/dist/vercel-6D6EZUVD.js.map +0 -1
  320. package/dist/vite-plugin-RJFKLF2U.js +0 -36
  321. /package/dist/{chunk-WPJOTQA5.js.map → adapters/agent-mount.js.map} +0 -0
  322. /package/dist/{agent-XAQCUQNB.js.map → agent-7IPEVCAY.js.map} +0 -0
  323. /package/dist/{check-45NKUVSQ.js.map → check-GIPZBFTX.js.map} +0 -0
  324. /package/dist/{chunk-47CINLWF.js.map → chunk-EDWEYQRG.js.map} +0 -0
  325. /package/dist/{chunk-ZB7D62OA.js.map → chunk-KUZVRJ7M.js.map} +0 -0
  326. /package/dist/{chunk-DS5MCU2X.js.map → chunk-URCXSUI3.js.map} +0 -0
  327. /package/dist/{internal-api-ZCJWJ5EC.js.map → chunk-YSJOZEI6.js.map} +0 -0
  328. /package/dist/{dev-emit-GWD6IXV7.js.map → dev-emit-BFNMDCPB.js.map} +0 -0
  329. /package/dist/{internal-api-FBK2YXSI.js.map → internal-api-4X6NDS2F.js.map} +0 -0
  330. /package/dist/{load-config-FIWNKOJO.js.map → load-config-4ATXQUN3.js.map} +0 -0
  331. /package/dist/{mcp-KTYP4ZON.js.map → mcp-IQRHFP3Y.js.map} +0 -0
  332. /package/dist/{node-QXYSUWQ4.js.map → node-OSVPYQ3D.js.map} +0 -0
  333. /package/dist/{scan-7MJC6PYU.js.map → observability-bootstrap-LERYDHKY.js.map} +0 -0
  334. /package/dist/{registry-S7OMF3OS.js.map → registry-KBZDCFVQ.js.map} +0 -0
  335. /package/dist/{schema-DNIT7JQX.js.map → scan-YJEE4KQK.js.map} +0 -0
  336. /package/dist/{vite-plugin-RJFKLF2U.js.map → schema-SOAD43RQ.js.map} +0 -0
  337. /package/dist/{services-typed-client-P4JERLBL.js.map → services-typed-client-XGT5SUUN.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/schemas/rate-limit.ts","../src/config/schemas/upload.ts","../src/config/schemas/logging.ts","../src/config/schemas/cache.ts","../src/config/schemas/observability.ts","../src/config/schemas/security.ts","../src/config/schemas/header-safe.ts","../src/config/schemas/storage.ts"],"sourcesContent":["import { z } from 'zod'\n\n/**\n * Base bucket config — legacy shape preserved for backwards compatibility.\n */\nconst baseRateLimitSchema = z.object({\n windowMs: z.number().min(1),\n max: z.number().int().min(1),\n})\n\n/**\n * T2.2 — Per-route + per-user rate limit. The new shape adds `routes`\n * (path map), `keyBy`, and `cookieName`. The legacy flat shape is still\n * accepted via the union — see `createRouteRateLimiter` for normalization.\n */\nexport const rateLimitSchema = z.union([\n baseRateLimitSchema,\n z.object({\n default: baseRateLimitSchema.optional(),\n routes: z.record(z.string(), baseRateLimitSchema).optional(),\n keyBy: z\n .union([\n z.enum(['ip', 'session', 'user']),\n z.function({ input: z.tuple([z.unknown()]), output: z.string() }),\n ])\n .optional(),\n cookieName: z.string().min(1).optional(),\n /**\n * How many reverse proxies sit in front of the app, for `keyBy: 'ip'`. `false` (default)\n * trusts none; `true` means one; a number names a longer chain.\n *\n * Required for correct limiting behind Caddy/nginx/a load balancer — without it every visitor\n * keys on the proxy address and shares a single bucket. Off by default because\n * `x-forwarded-for` is client-writable.\n */\n trustProxy: z.union([z.boolean(), z.number().int().min(0)]).optional(),\n }),\n])\n","import { z } from 'zod'\n\nexport const uploadSchema = z.object({\n maxFileSize: z\n .number()\n .min(1)\n .default(10 * 1024 * 1024), // 10MB\n maxFiles: z.number().int().min(1).default(10),\n maxFieldSize: z\n .number()\n .min(1)\n .default(1 * 1024 * 1024), // 1MB\n})\n","import { z } from 'zod'\n\nexport const loggingSchema = z.object({\n level: z.enum(['debug', 'info', 'warn', 'error', 'silent']).default('info'),\n})\n","import { z } from 'zod'\n\n// `.finite()` was removed from the 4 numeric schemas below (agent-builder#319): in zod 4 it is a\n// no-op — `z.number()` already rejects `Infinity`, `-Infinity` and `NaN` by default. Measured before\n// removing, against the installed zod 4.4.3, and not assumed from the deprecation message: all five\n// cases (`Infinity`, `-Infinity`, `NaN`, `1.5`, `0`) give the SAME verdict with and without it.\n\n/**\n * Cache subsystem config (caching-and-revalidation-plan).\n * Default `cache: undefined` keeps the framework backward-compatible\n * (no engine initialized → no cache primitives available).\n *\n * Setting `cache: {}` opts in with all defaults.\n */\nconst routeRuleSchema = z.object({\n maxAge: z.number().nonnegative().optional(),\n swr: z.number().nonnegative().optional(),\n tags: z.array(z.string()).optional(),\n})\n\nexport const cacheSchema = z.object({\n enabled: z.boolean().default(true),\n /** 'memory' uses InMemoryCacheAdapter; otherwise pass a custom adapter instance. */\n storage: z.union([z.literal('memory'), z.custom<unknown>()]).default('memory'),\n maxEntries: z.number().int().positive().default(1000),\n defaults: z\n .object({\n maxAge: z.number().nonnegative().default(1),\n swr: z.number().nonnegative().optional(),\n cacheErrors: z.boolean().default(false),\n })\n .default({ maxAge: 1, cacheErrors: false }),\n keyDerivation: z\n .object({\n excludeQuery: z.array(z.string()).optional(),\n sortQuery: z.boolean().default(true),\n lowercaseHost: z.boolean().default(true),\n })\n .default({ sortQuery: true, lowercaseHost: true }),\n routeRules: z.record(z.string(), routeRuleSchema).optional(),\n})\n","import { z } from 'zod'\n\n/**\n * Observability subsystem config.\n *\n * `adapter-registry.ts` has documented `theo.config.ts > observability.provider`\n * as the first source in its resolution chain since it was written, and the key\n * did not exist in the schema — so the chain's highest-priority entry was\n * unreachable and every consumer fell through to the environment\n * (usetheokit/theokit#353).\n *\n * Default `observability: undefined` keeps telemetry off, which is what an\n * application that never asked for it should get.\n */\nexport const observabilitySchema = z.object({\n /** Set `false` to opt out even when the environment would enable an exporter. */\n enabled: z.boolean().default(true),\n /**\n * An `ObservabilityAdapter` instance. Validated structurally rather than by\n * shape, for the same reason `storage` and `plugins` are: the config layer\n * cannot import the adapter contract without inverting the module graph, and\n * the adapter is a live object rather than data.\n */\n provider: z.custom<unknown>().optional(),\n})\n","import { z } from 'zod'\n\nimport { headerSafeString } from './header-safe.js'\n\n/**\n * Phase 5 — CSRF warn-first (EC-1).\n *\n * 0.2.0 default: `warn`. Existing apps keep working but get structured\n * warnings about every state-mutating request that does not carry the\n * `X-Theo-Action: 1` header. 0.3.0 will flip the default to `strict`.\n *\n * Set explicitly to `strict` to opt into the future default early,\n * or `off` to disable CSRF entirely (only valid when you have another\n * defense — bearer auth, no session cookies, etc).\n */\n\n/**\n * Phase 6 — Default security headers (D4 / EC-2).\n *\n * 0.2.0 defaults:\n * - CSP in `report-only` mode (EC-2: don't break existing apps)\n * - X-Frame-Options: DENY · X-Content-Type-Options: nosniff\n * - Referrer-Policy: strict-origin-when-cross-origin\n * - HSTS in production only (no TLS on localhost)\n *\n * Users override individual headers, swap CSP to `enforce`, or disable\n * CSP entirely (`csp: false` / `cspMode: 'off'`).\n */\nexport const securityHeadersSchema = z.object({\n csp: z.union([headerSafeString, z.literal(false)]).optional(),\n // T6.1 — default flipped from 'report-only' to 'enforce' for 0.3.0.\n // Users who want the old behaviour set `cspMode: 'report-only'`\n // explicitly.\n cspMode: z.enum(['enforce', 'report-only', 'off']).default('enforce'),\n hsts: z.union([headerSafeString, z.literal(false)]).optional(),\n frameOptions: z.enum(['DENY', 'SAMEORIGIN']).default('DENY'),\n contentTypeOptions: z.literal('nosniff').default('nosniff'),\n referrerPolicy: headerSafeString.default('strict-origin-when-cross-origin'),\n /**\n * T1.1 — Permissions-Policy directive string. EC-3-refined: rejects CR/LF.\n * Pass `false` to suppress the header.\n */\n permissionsPolicy: z.union([headerSafeString, z.literal(false)]).optional(),\n})\n\n/**\n * T5.1 — Disallowed-routes escalation pattern (Rails-inspired).\n *\n * `routes` accepts string (exact match — trailing slash matters) or\n * RegExp entries. Matched routes that would otherwise emit `csrf.warn`\n * dispatch through `disallowedBehavior` instead:\n * - `'warn'` : no-op vs the default warn-mode behavior\n * - `'raise'` : escalate to 403, even when global `csrf` mode is 'warn'\n *\n * Use to roll out strict mode per-route (e.g., flip /api/auth/* first)\n * without committing the entire surface to strict at once.\n */\nconst disallowedConfigSchema = z.object({\n routes: z.array(z.union([z.string(), z.instanceof(RegExp)])),\n behavior: z.enum(['warn', 'raise']).default('raise'),\n})\n\n/**\n * T1.2 — CORS configuration.\n *\n * `origins` accepts a single value (`'*'`, string, RegExp, callback) OR an\n * array of (string | RegExp). The spec-violating `origins: '*'` +\n * `credentials: true` combination is rejected at parse time (browsers\n * ignore wildcards when credentials are sent).\n *\n * EC-3 — `allowedHeaders` and `exposedHeaders` entries go through the\n * header-safe refinement (CR/LF rejected — CWE-113 mitigation).\n */\nexport const corsSchema = z\n .object({\n origins: z.union([\n z.literal('*'),\n headerSafeString,\n z.instanceof(RegExp),\n z.array(z.union([headerSafeString, z.instanceof(RegExp)])),\n z.function({ input: z.tuple([z.string()]), output: z.boolean() }),\n ]),\n methods: z\n .array(z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD']))\n .optional(),\n allowedHeaders: z.array(headerSafeString).optional(),\n exposedHeaders: z.array(headerSafeString).optional(),\n credentials: z.boolean().default(false),\n maxAge: z.number().int().min(0).max(86400).default(600),\n })\n .refine((c) => !(c.origins === '*' && c.credentials), {\n message: 'CORS spec forbids origins:\"*\" with credentials:true — browsers ignore the wildcard',\n })\n\nexport const securitySchema = z.object({\n // T6.1 — default flipped from 'warn' to 'strict' for 0.3.0. Apps that\n // grep their warn-mode logs from 0.2.x already know which endpoints\n // break; opt back into 'warn' globally OR use disallowedRoutes for\n // surgical migration.\n csrf: z.enum(['off', 'warn', 'strict']).default('strict'),\n headers: securityHeadersSchema.optional(),\n /** T5.1 — per-route escalation (Rails disallowed_warnings pattern). */\n disallowed: disallowedConfigSchema.optional(),\n /** T1.2 — Cross-Origin Resource Sharing. Single global config; runs first in pipeline. */\n cors: corsSchema.optional(),\n})\n","import { z } from 'zod'\n\n/**\n * EC-3 — CWE-113 HTTP Response Splitting mitigation.\n *\n * Every string that becomes a header value must reject CR/LF. Apps that\n * derive header values from untrusted input (feature flags, tenant config,\n * URL params) would otherwise let attackers inject Set-Cookie / Location\n * headers via `\\r\\n`. Apply this refinement to every header-bound string\n * field: permissionsPolicy, csp, hsts, referrerPolicy, CORS allow/expose.\n */\nexport const headerSafeString = z\n .string()\n .refine((s) => !/[\\r\\n]/.test(s), { message: 'Header value must not contain CR/LF' })\n","import { z } from 'zod'\n\n/**\n * StorageManager schemas (T1.1 / ADR-0007 D4).\n *\n * `theo.config.ts > storage` declares Postgres servers (credentials), the\n * databases on each server (TheoCloud / managed PG / self-host), and Redis\n * servers. The runtime `StorageManager` consumes this block; adapters\n * (PostgresJobBackend, PostgresConversationStorage, etc.) request pools by\n * database name and never see raw credentials at the call site.\n *\n * EC-1 (DOCUMENT in concept doc T4.1): Zod default strip-unknown mode\n * silently drops typo keys (`databasees` instead of `databases`). The\n * concept doc warns users to use exact names; runtime errors are still\n * actionable (`Database \"X\" not configured`).\n *\n * EC-2 (DEFERRED to use-time): `databases.X.server` references a key in\n * `servers`. Cross-field validation is intentionally NOT enforced at parse\n * time — `StorageManager.usePostgres()` throws an actionable error on the\n * first call with the dangling reference, matching Rails / Nitro behavior.\n */\nconst tlsConfigSchema = z.object({\n rejectUnauthorized: z.boolean().optional(),\n caCert: z.string().optional(),\n clientCert: z.string().optional(),\n clientKey: z.string().optional(),\n})\n\nconst serverConfigSchema = z.object({\n host: z.string().min(1),\n port: z.number().int().positive().max(65535).optional(),\n user: z.string().min(1),\n /** Password may be the empty string (some providers permit it). */\n password: z.string(),\n tls: tlsConfigSchema.optional(),\n})\n\nconst postgresPoolConfigSchema = z.object({\n min: z.number().int().nonnegative().optional(),\n max: z.number().int().positive().optional(),\n connectionTimeoutMillis: z.number().int().positive().optional(),\n idleTimeoutMillis: z.number().int().nonnegative().optional(),\n})\n\nconst postgresDatabaseConfigSchema = z.object({\n /** References a key in `storage.servers`. Resolved at `usePostgres()` call time. */\n server: z.string().min(1),\n database: z.string().min(1),\n pool: postgresPoolConfigSchema.optional(),\n})\n\nconst redisServerConfigSchema = serverConfigSchema.extend({\n db: z.number().int().nonnegative().optional(),\n maxRetriesPerRequest: z.number().int().nonnegative().optional(),\n})\n\nexport const storageSchema = z.object({\n servers: z.record(z.string(), serverConfigSchema).optional(),\n databases: z.record(z.string(), postgresDatabaseConfigSchema).optional(),\n redis: z.record(z.string(), redisServerConfigSchema).optional(),\n})\n\nexport type StorageConfig = z.infer<typeof storageSchema>\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z"]}
@@ -0,0 +1,14 @@
1
+ // src/vite-plugin/resolve-theo-root.ts
2
+ import { existsSync } from "fs";
3
+ import { resolve } from "path";
4
+ function resolveTheoRootDir(currentDir) {
5
+ if (existsSync(resolve(currentDir, "client"))) {
6
+ return currentDir;
7
+ }
8
+ return resolve(currentDir, "..");
9
+ }
10
+
11
+ export {
12
+ resolveTheoRootDir
13
+ };
14
+ //# sourceMappingURL=chunk-VQPHPQ5L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vite-plugin/resolve-theo-root.ts"],"mappings":";AAIA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAiBjB,SAAS,mBAAmB,YAA4B;AAC7D,MAAI,WAAW,QAAQ,YAAY,QAAQ,CAAC,GAAG;AAC7C,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,YAAY,IAAI;AACjC;","names":[]}
@@ -0,0 +1,147 @@
1
+ // src/server/_internal/log-safe.ts
2
+ var DEFAULT_MAX_LEN = 100;
3
+ function limitUntrustedHeaderValueForLogs(value, maxLen = DEFAULT_MAX_LEN) {
4
+ const truncated = value.length > maxLen ? `${value.slice(0, maxLen)}\u2026` : value;
5
+ return truncated.replace(/[\x00-\x1F\x7F]/g, (ch) => {
6
+ const code = ch.charCodeAt(0);
7
+ return `\\x${code.toString(16).padStart(2, "0").toUpperCase()}`;
8
+ });
9
+ }
10
+
11
+ // src/server/security/wildcard-origin.ts
12
+ function matchWildcardDomain(domain, pattern) {
13
+ const normalizedDomain = domain.replace(/[A-Z]/g, (c) => c.toLowerCase());
14
+ const normalizedPattern = pattern.replace(/[A-Z]/g, (c) => c.toLowerCase());
15
+ const domainParts = normalizedDomain.split(".");
16
+ const patternParts = normalizedPattern.split(".");
17
+ if (patternParts.length < 1) return false;
18
+ if (domainParts.length < patternParts.length) return false;
19
+ if (patternParts.length === 1) {
20
+ const only = patternParts[0];
21
+ if (only === "*" || only === "**") return false;
22
+ }
23
+ while (patternParts.length > 0) {
24
+ const patternPart = patternParts.pop();
25
+ const domainPart = domainParts.pop();
26
+ if (patternPart === "") return false;
27
+ if (patternPart === "*") {
28
+ if (domainPart) continue;
29
+ return false;
30
+ }
31
+ if (patternPart === "**") {
32
+ if (patternParts.length > 0) return false;
33
+ return domainPart !== void 0;
34
+ }
35
+ if (domainPart !== patternPart) return false;
36
+ }
37
+ return domainParts.length === 0;
38
+ }
39
+ function isCsrfOriginAllowed(originDomain, allowedOrigins = []) {
40
+ const normalizedOrigin = originDomain.replace(/[A-Z]/g, (c) => c.toLowerCase());
41
+ return allowedOrigins.some((allowed) => {
42
+ if (!allowed) return false;
43
+ const normalizedAllowed = allowed.replace(/[A-Z]/g, (c) => c.toLowerCase());
44
+ return normalizedAllowed === normalizedOrigin || matchWildcardDomain(originDomain, allowed);
45
+ });
46
+ }
47
+
48
+ // src/server/security/csrf-multi-header.ts
49
+ function evaluateCsrfMultiHeaderFromInputs(inputs, ownOrigin, options) {
50
+ if (inputs.secFetchSite !== void 0) {
51
+ if (inputs.secFetchSite === "same-origin" || inputs.secFetchSite === "none") {
52
+ return { allow: true, signal: "sec-fetch-site" };
53
+ }
54
+ return {
55
+ allow: false,
56
+ signal: "sec-fetch-site",
57
+ reason: `Sec-Fetch-Site header indicates ${limitUntrustedHeaderValueForLogs(inputs.secFetchSite)}`
58
+ };
59
+ }
60
+ if (inputs.origin !== void 0) {
61
+ if (inputs.origin === "null") {
62
+ return { allow: false, signal: "origin", reason: "Origin is null (opaque origin)" };
63
+ }
64
+ if (originMatches(inputs.origin, ownOrigin, options.allowedOrigins)) {
65
+ return { allow: true, signal: "origin" };
66
+ }
67
+ return { allow: false, signal: "origin", reason: "Origin not in allowlist" };
68
+ }
69
+ if (inputs.referer !== void 0) {
70
+ const refererOrigin = safeOriginFromUrl(inputs.referer);
71
+ if (refererOrigin === void 0) {
72
+ return { allow: false, signal: "referer", reason: "Referer not a valid URL" };
73
+ }
74
+ if (originMatches(refererOrigin, ownOrigin, options.allowedOrigins)) {
75
+ return { allow: true, signal: "referer" };
76
+ }
77
+ return { allow: false, signal: "referer", reason: "Referer origin not in allowlist" };
78
+ }
79
+ if (options.allowRequestsWithoutOriginCheck === true) {
80
+ return { allow: true, signal: "no-headers-allowed" };
81
+ }
82
+ return {
83
+ allow: false,
84
+ signal: "no-headers",
85
+ reason: "No Sec-Fetch-Site / Origin / Referer header provided"
86
+ };
87
+ }
88
+ function evaluateCsrfMultiHeaderRequest(request, options = {}) {
89
+ const ownOrigin = getOwnOriginFromRequest(request, options.trustForwardedHeaders === true);
90
+ return evaluateCsrfMultiHeaderFromInputs(
91
+ {
92
+ secFetchSite: request.headers.get("sec-fetch-site") ?? void 0,
93
+ origin: request.headers.get("origin") ?? void 0,
94
+ referer: request.headers.get("referer") ?? void 0
95
+ },
96
+ ownOrigin,
97
+ options
98
+ );
99
+ }
100
+ function getOwnOriginFromRequest(request, trustForwarded) {
101
+ if (trustForwarded) {
102
+ const fwdHost = request.headers.get("x-forwarded-host");
103
+ if (fwdHost !== null && fwdHost.length > 0) {
104
+ const fwdProto = request.headers.get("x-forwarded-proto") ?? "http";
105
+ return `${fwdProto}://${fwdHost}`;
106
+ }
107
+ }
108
+ const host = request.headers.get("host");
109
+ if (host !== null && host.length > 0) {
110
+ return `http://${host}`;
111
+ }
112
+ try {
113
+ return new URL(request.url).origin;
114
+ } catch {
115
+ return void 0;
116
+ }
117
+ }
118
+ function originMatches(candidateOrigin, ownOrigin, allowedOrigins) {
119
+ if (candidateOrigin.toLowerCase() === ownOrigin?.toLowerCase()) {
120
+ return true;
121
+ }
122
+ const host = safeHostFromUrl(candidateOrigin);
123
+ if (host === void 0) return false;
124
+ if (allowedOrigins === void 0 || allowedOrigins.length === 0) return false;
125
+ return isCsrfOriginAllowed(host, allowedOrigins);
126
+ }
127
+ function safeOriginFromUrl(url) {
128
+ try {
129
+ return new URL(url).origin;
130
+ } catch {
131
+ return void 0;
132
+ }
133
+ }
134
+ function safeHostFromUrl(originLike) {
135
+ try {
136
+ return new URL(originLike).host;
137
+ } catch {
138
+ return void 0;
139
+ }
140
+ }
141
+
142
+ export {
143
+ matchWildcardDomain,
144
+ isCsrfOriginAllowed,
145
+ evaluateCsrfMultiHeaderRequest
146
+ };
147
+ //# sourceMappingURL=chunk-WNJTJRM6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/_internal/log-safe.ts","../src/server/security/wildcard-origin.ts","../src/server/security/csrf-multi-header.ts"],"mappings":"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","names":[]}
@@ -1,12 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import "tsx/esm";
3
3
  import {
4
+ MissingRoutePolicyError,
5
+ RouterConventionError,
6
+ compareByCodeUnit,
7
+ createFileStampCache,
4
8
  walkSourceFiles
5
- } from "./chunk-A7JBF5FO.js";
9
+ } from "./chunk-FD4ZDTQ6.js";
6
10
 
7
11
  // src/server/scan/action-scan.ts
8
12
  import { existsSync, readFileSync, statSync } from "fs";
9
13
  import { extname, join, relative } from "path";
14
+ var ACTION_SCHEMAS_DIR = "schemas";
10
15
  var ActionScanError = class extends Error {
11
16
  code;
12
17
  conflictingPaths;
@@ -48,7 +53,7 @@ function scanServerActionsEnriched(serverDir) {
48
53
  walkSourceFiles(actionsDir, { extensions: ACTION_EXTENSIONS }, (absPath) => {
49
54
  if (TEST_FILE_RE.test(absPath)) return;
50
55
  const rel = relative(actionsDir, absPath).replace(/\\/g, "/");
51
- if (rel.startsWith("schemas/")) return;
56
+ if (rel.startsWith(`${ACTION_SCHEMAS_DIR}/`)) return;
52
57
  const name = rel.slice(0, -extname(rel).length);
53
58
  const basename2 = name.includes("/") ? name.split("/").pop() ?? name : name;
54
59
  if (RESERVED_NAMES.has(basename2)) {
@@ -120,7 +125,7 @@ function extractActionExportNames(stripped) {
120
125
  return [...names];
121
126
  }
122
127
  function detectSchemaFile(actionsDir, basename2) {
123
- const schemasDir = join(actionsDir, "schemas");
128
+ const schemasDir = join(actionsDir, ACTION_SCHEMAS_DIR);
124
129
  if (!existsSync(schemasDir)) return void 0;
125
130
  for (const ext of [".ts", ".tsx", ".js", ".jsx"]) {
126
131
  const candidate = join(schemasDir, `${basename2}${ext}`);
@@ -182,7 +187,7 @@ var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
182
187
  var HTTP_METHOD_LOWERCASE = HTTP_METHODS.map((m) => m.toLowerCase());
183
188
 
184
189
  // src/server/scan/scan.ts
185
- import { existsSync as existsSync2, statSync as statSync2 } from "fs";
190
+ import { existsSync as existsSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
186
191
  import { basename, extname as extname2, join as join2, relative as relative2 } from "path";
187
192
 
188
193
  // src/server/scan/detect-http-methods.ts
@@ -235,33 +240,115 @@ function detectExportedHttpMethods(filePath, content) {
235
240
  for (const stmt of sourceFile.statements) {
236
241
  collectFromStatement(stmt, found);
237
242
  }
238
- return [...found].sort((a, b) => a.localeCompare(b));
243
+ return [...found].sort(compareByCodeUnit);
239
244
  }
240
245
 
241
- // src/server/scan/errors.ts
242
- var ROUTER_MIGRATION_GUIDE_URL = "https://theokit.dev/migration/0.3-to-0.4-router";
243
- var RouterConventionError = class extends Error {
244
- name = "RouterConventionError";
245
- file;
246
- suggestion;
247
- migrationUrl;
248
- constructor(opts) {
249
- const migrationUrl = opts.migrationUrl ?? ROUTER_MIGRATION_GUIDE_URL;
250
- const message = [
251
- `Router convention violation: dotted route basename is not supported in theokit 0.4+.`,
252
- ``,
253
- ` File: ${opts.file}`,
254
- ` Use directory-nested form: ${opts.suggestion}`,
255
- ``,
256
- `Migration guide: ${migrationUrl}`,
257
- `Run \`theokit migrate router\` to convert all dotted basenames automatically.`
258
- ].join("\n");
259
- super(message);
260
- this.file = opts.file;
261
- this.suggestion = opts.suggestion;
262
- this.migrationUrl = migrationUrl;
246
+ // src/server/scan/detect-route-policy.ts
247
+ import { createRequire as createRequire2 } from "module";
248
+ var require_2 = createRequire2(import.meta.url);
249
+ var ts2 = require_2("typescript");
250
+ var HTTP_METHOD_NAMES2 = new Set(HTTP_METHODS);
251
+ var POLICY_KEY = "policy";
252
+ function hasExportModifier2(modifiers) {
253
+ if (!modifiers) return false;
254
+ for (const m of modifiers) {
255
+ if (m.kind === ts2.SyntaxKind.ExportKeyword) return true;
263
256
  }
264
- };
257
+ return false;
258
+ }
259
+ function unwrap(expression) {
260
+ let current = expression;
261
+ for (; ; ) {
262
+ if (ts2.isParenthesizedExpression(current) || ts2.isAsExpression(current) || ts2.isSatisfiesExpression(current) || ts2.isNonNullExpression(current)) {
263
+ current = current.expression;
264
+ continue;
265
+ }
266
+ return current;
267
+ }
268
+ }
269
+ function propertyNameIsPolicy(name) {
270
+ if (name === void 0) return false;
271
+ if (ts2.isIdentifier(name)) return name.text === POLICY_KEY;
272
+ if (ts2.isStringLiteral(name)) return name.text === POLICY_KEY;
273
+ return false;
274
+ }
275
+ function objectDeclaresPolicy(literal) {
276
+ for (const property of literal.properties) {
277
+ if (ts2.isSpreadAssignment(property)) continue;
278
+ if (propertyNameIsPolicy(property.name)) return true;
279
+ }
280
+ return false;
281
+ }
282
+ function declaresPolicy(expression) {
283
+ const expr = unwrap(expression);
284
+ if (ts2.isObjectLiteralExpression(expr)) return objectDeclaresPolicy(expr);
285
+ if (!ts2.isCallExpression(expr)) return false;
286
+ const callee = unwrap(expr.expression);
287
+ if (ts2.isPropertyAccessExpression(callee) && callee.name.text === POLICY_KEY) return true;
288
+ for (const argument of expr.arguments) {
289
+ const arg = unwrap(argument);
290
+ if (ts2.isObjectLiteralExpression(arg) && objectDeclaresPolicy(arg)) return true;
291
+ }
292
+ if (ts2.isPropertyAccessExpression(callee)) return declaresPolicy(callee.expression);
293
+ return false;
294
+ }
295
+ function collectLocalInitializers(sourceFile) {
296
+ const locals = /* @__PURE__ */ new Map();
297
+ for (const stmt of sourceFile.statements) {
298
+ if (!ts2.isVariableStatement(stmt)) continue;
299
+ for (const decl of stmt.declarationList.declarations) {
300
+ if (ts2.isIdentifier(decl.name) && decl.initializer !== void 0) {
301
+ locals.set(decl.name.text, decl.initializer);
302
+ }
303
+ }
304
+ }
305
+ return locals;
306
+ }
307
+ function collectFromVariableStatement(stmt, declared) {
308
+ if (!hasExportModifier2(ts2.getModifiers(stmt))) return;
309
+ for (const decl of stmt.declarationList.declarations) {
310
+ if (!ts2.isIdentifier(decl.name) || !HTTP_METHOD_NAMES2.has(decl.name.text)) continue;
311
+ if (decl.initializer !== void 0 && declaresPolicy(decl.initializer)) {
312
+ declared.add(decl.name.text);
313
+ }
314
+ }
315
+ }
316
+ function collectFromExportDeclaration(stmt, locals, declared) {
317
+ if (stmt.moduleSpecifier !== void 0) return;
318
+ if (!stmt.exportClause || !ts2.isNamedExports(stmt.exportClause)) return;
319
+ for (const spec of stmt.exportClause.elements) {
320
+ if (!HTTP_METHOD_NAMES2.has(spec.name.text)) continue;
321
+ const local = locals.get((spec.propertyName ?? spec.name).text);
322
+ if (local !== void 0 && declaresPolicy(local)) {
323
+ declared.add(spec.name.text);
324
+ }
325
+ }
326
+ }
327
+ function collectFromStatement2(stmt, locals, declared) {
328
+ if (ts2.isVariableStatement(stmt)) {
329
+ collectFromVariableStatement(stmt, declared);
330
+ return;
331
+ }
332
+ if (ts2.isExportDeclaration(stmt)) {
333
+ collectFromExportDeclaration(stmt, locals, declared);
334
+ }
335
+ }
336
+ function detectMethodsWithDeclaredPolicy(filePath, content) {
337
+ const sourceFile = ts2.createSourceFile(
338
+ filePath,
339
+ content,
340
+ ts2.ScriptTarget.Latest,
341
+ /* setParentNodes */
342
+ false,
343
+ ts2.ScriptKind.TS
344
+ );
345
+ const locals = collectLocalInitializers(sourceFile);
346
+ const declared = /* @__PURE__ */ new Set();
347
+ for (const stmt of sourceFile.statements) {
348
+ collectFromStatement2(stmt, locals, declared);
349
+ }
350
+ return declared;
351
+ }
265
352
 
266
353
  // src/server/scan/scan.ts
267
354
  var ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx"]);
@@ -320,6 +407,21 @@ function assertNoDottedSegment(filePath, routesDir) {
320
407
  }
321
408
  }
322
409
  }
410
+ function assertEveryMethodDeclaresPolicy(filePath, routePath, { methods, declaredPolicy }) {
411
+ if (methods.length === 0) return;
412
+ const missing = methods.filter((method) => !declaredPolicy.has(method));
413
+ if (missing.length === 0) return;
414
+ throw new MissingRoutePolicyError({ file: filePath, routePath, methods: missing });
415
+ }
416
+ var routeFactsCache = createFileStampCache();
417
+ function routeSourceFacts(absPath) {
418
+ return routeFactsCache.get(absPath, () => {
419
+ const source = readFileSync3(absPath, "utf-8");
420
+ const methods = detectExportedHttpMethods(absPath, source);
421
+ const declaredPolicy = methods.length === 0 ? /* @__PURE__ */ new Set() : detectMethodsWithDeclaredPolicy(absPath, source);
422
+ return { methods, declaredPolicy };
423
+ });
424
+ }
323
425
  function fileToRoutePath(filePath, routesDir) {
324
426
  let rel = relative2(routesDir, filePath);
325
427
  const ext = extname2(rel);
@@ -345,7 +447,9 @@ function scanServerRoutes(serverDir) {
345
447
  assertNoDottedSegment(absPath, routesDir);
346
448
  const routePath = fileToRoutePath(absPath, routesDir);
347
449
  const { pattern, paramNames } = compilePattern(routePath);
348
- const methods = detectExportedHttpMethods(absPath);
450
+ const facts = routeSourceFacts(absPath);
451
+ const { methods } = facts;
452
+ assertEveryMethodDeclaresPolicy(absPath, routePath, facts);
349
453
  results.push({
350
454
  filePath: absPath,
351
455
  routePath,
@@ -360,20 +464,29 @@ function scanServerRoutes(serverDir) {
360
464
  `Server route ${conflicting.filePath} resolves to '/api/__theo_batch__' which is reserved for the batch endpoint. Rename the route or disable batching in theo.config.ts.`
361
465
  );
362
466
  }
363
- const isCatchAll = (route) => route.routePath.includes(":...");
364
- results.sort((a, b) => {
365
- const aStatic = a.paramNames.length === 0;
366
- const bStatic = b.paramNames.length === 0;
367
- const aCatchAll = isCatchAll(a);
368
- const bCatchAll = isCatchAll(b);
369
- if (aStatic && !bStatic) return -1;
370
- if (!aStatic && bStatic) return 1;
371
- if (aCatchAll && !bCatchAll) return 1;
372
- if (!aCatchAll && bCatchAll) return -1;
373
- return a.routePath.localeCompare(b.routePath);
374
- });
467
+ results.sort((a, b) => compareRouteSpecificity(a.routePath, b.routePath));
375
468
  return results;
376
469
  }
470
+ var SEGMENT_STATIC = 0;
471
+ var SEGMENT_DYNAMIC = 1;
472
+ var SEGMENT_CATCH_ALL = 2;
473
+ function segmentSpecificity(segment) {
474
+ if (segment.startsWith(":...")) return SEGMENT_CATCH_ALL;
475
+ if (segment.startsWith(":")) return SEGMENT_DYNAMIC;
476
+ return SEGMENT_STATIC;
477
+ }
478
+ function compareRouteSpecificity(a, b) {
479
+ const aSegments = a.split("/");
480
+ const bSegments = b.split("/");
481
+ const shared = Math.min(aSegments.length, bSegments.length);
482
+ for (let i = 0; i < shared; i++) {
483
+ const difference = segmentSpecificity(aSegments[i]) - segmentSpecificity(bSegments[i]);
484
+ if (difference !== 0) return difference;
485
+ }
486
+ if (a < b) return -1;
487
+ if (a > b) return 1;
488
+ return 0;
489
+ }
377
490
 
378
491
  // src/server/scan/ws-scan.ts
379
492
  import { existsSync as existsSync3, statSync as statSync3 } from "fs";
@@ -400,6 +513,7 @@ function scanWebSocketRoutes(serverDir) {
400
513
  }
401
514
 
402
515
  export {
516
+ ACTION_SCHEMAS_DIR,
403
517
  scanServerActions,
404
518
  scanServerActionsEnriched,
405
519
  compilePattern,
@@ -408,4 +522,4 @@ export {
408
522
  scanServerRoutes,
409
523
  scanWebSocketRoutes
410
524
  };
411
- //# sourceMappingURL=chunk-BMHS4WAN.js.map
525
+ //# sourceMappingURL=chunk-XS7EX55U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/scan/action-scan.ts","../src/server/scan/match.ts","../src/core/contracts/http-methods.ts","../src/server/scan/scan.ts","../src/server/scan/detect-http-methods.ts","../src/server/scan/detect-route-policy.ts","../src/server/scan/ws-scan.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/actions/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, readFileSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nexport interface ActionNode {\n filePath: string\n actionPath: string\n}\n\n/**\n * Directory under `<serverDir>/actions/` reserved for ISOMORPHIC zod schemas.\n *\n * The one place in the whole server tree whose files are meant to reach the browser: the\n * `@theo/actions` virtual module emits `import { schema } from '<abs path>'` into the CLIENT\n * facade for each file here, so `<TheoForm>` can drive `zodResolver` with the same schema the\n * server validates against.\n *\n * Named once, and exported, because two rules now depend on knowing it. The scanner skips it (a\n * schema is not an executable action), and the server-only import boundary must NOT refuse it\n * (`vite-plugin/server-boundary.ts`). Restating the literal in the boundary would let the two\n * drift, and the drift would be invisible: renaming the convention here would silently turn the\n * exception into a refusal, breaking a shipped feature at build time in consumer projects only.\n */\nexport const ACTION_SCHEMAS_DIR = 'schemas'\n\n/**\n * Enriched manifest entry per plan g3-server-actions-and-useaction v1.2\n * § Phase 1 / T1.4 + ADR D4. Consumed by virtual module `@theo/actions`\n * (T3.1) and G4 devtools \"Actions\" tab (T5.1).\n */\nexport interface ActionManifestEntry {\n name: string\n filePath: string\n urlPath: string\n accept: 'form' | 'json'\n hasInput: boolean\n /**\n * P#4 plugin-forms shared-schema convention (per plan p4-plugin-forms v1.1 T1.1).\n * When present, points to an isomorphic schema file at\n * `<serverDir>/actions/schemas/<basename>.ts` exporting `export const schema = z.object(...)`.\n * Virtual module emits `import {schema} from '<schemaFilePath>'` + attaches as\n * `actions.X.__zodSchema` so client-side <TheoForm> can drive zodResolver.\n * Undefined when convention not followed (graceful degrade — TheoForm still\n * works via explicit `schema={...}` prop escape hatch).\n */\n schemaFilePath?: string\n}\n\n/**\n * EC-2: structured error for scan-time defects (name collision, reserved\n * identifier, etc.). Throw at scan time to fail loud — silent shadowing is\n * a security/correctness footgun.\n */\nexport class ActionScanError extends Error {\n readonly code: 'NAME_COLLISION' | 'RESERVED_NAME'\n readonly conflictingPaths: readonly string[]\n\n constructor(\n code: 'NAME_COLLISION' | 'RESERVED_NAME',\n message: string,\n conflictingPaths: readonly string[],\n ) {\n super(message)\n // T4.1 fix: identify class by name so serverErrorToEnvelope boundary\n // translator can route via class-name lookup (without this, runtime\n // `err.name` defaults to 'Error' and the meta.name diagnostic is wrong).\n this.name = 'ActionScanError'\n this.code = code\n this.conflictingPaths = conflictingPaths\n }\n}\n\nconst ACTION_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\nconst TEST_FILE_RE = /\\.(test|spec)\\.(ts|tsx|js|jsx)$/\nconst RESERVED_NAMES = new Set(['index', 'constructor', '__proto__', 'prototype', 'hasOwnProperty'])\n\n/**\n * Backward-compatible: original simple-shape scanner used by existing\n * consumers. Preserved verbatim; new consumers should call\n * `scanServerActionsEnriched`.\n */\nexport function scanServerActions(serverDir: string): ActionNode[] {\n const actionsDir = join(serverDir, 'actions')\n if (!existsSync(actionsDir) || !statSync(actionsDir).isDirectory()) {\n return []\n }\n\n const results: ActionNode[] = []\n walkSourceFiles(actionsDir, { extensions: ACTION_EXTENSIONS }, (absPath) => {\n if (TEST_FILE_RE.test(absPath)) return\n let rel = relative(actionsDir, absPath)\n rel = rel.replace(/\\\\/g, '/')\n rel = rel.slice(0, -extname(rel).length)\n results.push({\n filePath: absPath,\n actionPath: rel,\n })\n })\n return results\n}\n\n/**\n * Enriched scan: light AST detection of `accept: 'form'|'json'` + `input:`\n * presence via regex-after-comment-stripping (EC-9). Throws ActionScanError\n * on file/dir name collision (EC-2) or reserved JS identifier names.\n *\n * Output `ActionManifestEntry[]` is sorted by `name` for deterministic\n * `.theokit/actions-manifest.json` emission.\n */\nexport function scanServerActionsEnriched(serverDir: string): ActionManifestEntry[] {\n const actionsDir = join(serverDir, 'actions')\n if (!existsSync(actionsDir) || !statSync(actionsDir).isDirectory()) {\n return []\n }\n\n const seenNames = new Set<string>()\n const entries: ActionManifestEntry[] = []\n\n // Collect first; collision-check after the full walk.\n walkSourceFiles(actionsDir, { extensions: ACTION_EXTENSIONS }, (absPath) => {\n if (TEST_FILE_RE.test(absPath)) return\n const rel = relative(actionsDir, absPath).replace(/\\\\/g, '/')\n // P#4 plugin-forms — `schemas/` subdir holds isomorphic zod schemas\n // for the shared-schema convention (T1.1). NOT executable actions; skip.\n if (rel.startsWith(`${ACTION_SCHEMAS_DIR}/`)) return\n const name = rel.slice(0, -extname(rel).length)\n\n const basename = name.includes('/') ? (name.split('/').pop() ?? name) : name\n if (RESERVED_NAMES.has(basename)) {\n throw new ActionScanError(\n 'RESERVED_NAME',\n `Reserved JS identifier \"${basename}\" cannot be an action name (${absPath})`,\n [absPath],\n )\n }\n // File-level collision (one file appearing twice) is impossible via the\n // walker; per-export collision check happens inside the export loop below.\n const source = readFileSync(absPath, 'utf8')\n const stripped = stripComments(source)\n const accept = /\\baccept\\s*:\\s*['\"]form['\"]/.test(stripped) ? 'form' : 'json'\n const hasInput = /\\binput\\s*:\\s*z\\./.test(stripped) || /\\binput\\s*:\\s*\\w+\\(/.test(stripped)\n\n // T7.1 wire fix — extract exports so the urlPath includes the second\n // segment required by action-middleware (`/api/__actions/<file>/<export>`).\n // Each named action export becomes its own manifest entry.\n // Proxy key on the EXPORT name (so consumers write `actions.saveMemory(input)`).\n // URL keeps the runtime 2-segment shape `/api/__actions/<file>/<export>`\n // expected by action-middleware. Cross-file export collisions become a\n // scan error to surface the ambiguity early.\n const exportNames = extractActionExportNames(stripped)\n // P#4 plugin-forms shared-schema convention: check for\n // `<actionsDir>/schemas/<basename>.ts` (or .tsx/.js/.jsx).\n // Skip when actions live in subdirs (`schemas/` is flat by convention).\n const schemaFilePath = name.includes('/') ? undefined : detectSchemaFile(actionsDir, basename)\n for (const exportName of exportNames) {\n const proxyKey = exportName === 'default' ? name : exportName\n if (seenNames.has(proxyKey)) {\n throw new ActionScanError(\n 'NAME_COLLISION',\n `Duplicate action proxy key \"${proxyKey}\" (two files export the same name)`,\n [absPath],\n )\n }\n seenNames.add(proxyKey)\n const entry: ActionManifestEntry = {\n name: proxyKey,\n filePath: absPath,\n urlPath: `/api/__actions/${name}/${exportName}`,\n accept,\n hasInput,\n }\n if (schemaFilePath !== undefined) {\n entry.schemaFilePath = schemaFilePath\n }\n entries.push(entry)\n }\n })\n\n // EC-2: detect file vs dir collisions (e.g., foo.ts AND foo/bar.ts).\n // After walk completes, any name that has children prefixed `name/` triggers collision.\n for (const entry of entries) {\n const childPrefix = `${entry.name}/`\n const conflictingChild = entries.find((other) => other.name.startsWith(childPrefix))\n if (conflictingChild) {\n throw new ActionScanError(\n 'NAME_COLLISION',\n `Action \"${entry.name}\" conflicts with directory of same name containing \"${conflictingChild.name}\"`,\n [entry.filePath, conflictingChild.filePath],\n )\n }\n }\n\n entries.sort((a, b) => {\n if (a.name < b.name) return -1\n if (a.name > b.name) return 1\n return 0\n })\n return entries\n}\n\n/**\n * Strip JavaScript line + block comments from source. Simple state machine\n * (does not parse strings — false positives if a comment marker appears\n * inside a string literal, but that's an acceptable trade-off for v1 vs\n * full AST parse).\n */\n/**\n * Extract action export names via regex over comment-stripped source.\n * Matches `export const <name> = defineAction(...)`, `export default\n * defineAction(...)`, and `export function <name>(...)` forms. Returns\n * `['default']` when no named action exports are found (best-effort fallback\n * for default-export shapes the regex misses).\n */\nfunction extractActionExportNames(stripped: string): string[] {\n const names = new Set<string>()\n const namedRe = /\\bexport\\s+(?:const|let|var|function\\*?)\\s+([a-zA-Z_$][\\w$]*)\\s*[=(]/g\n let m: RegExpExecArray | null\n while ((m = namedRe.exec(stripped)) !== null) {\n const name = m[1]\n if (typeof name === 'string' && name.length > 0) names.add(name)\n }\n if (/\\bexport\\s+default\\s+defineAction\\b/.test(stripped)) {\n names.add('default')\n }\n if (names.size === 0) names.add('default')\n return [...names]\n}\n\n/**\n * P#4 plugin-forms shared-schema convention helper (per plan p4-plugin-forms v1.1 T1.1).\n * Returns the resolved path to `<actionsDir>/schemas/<basename>.<ext>` if it exists.\n * Tries `.ts`, `.tsx`, `.js`, `.jsx` in that order. Returns undefined when no match.\n */\nfunction detectSchemaFile(actionsDir: string, basename: string): string | undefined {\n const schemasDir = join(actionsDir, ACTION_SCHEMAS_DIR)\n if (!existsSync(schemasDir)) return undefined\n for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {\n const candidate = join(schemasDir, `${basename}${ext}`)\n if (existsSync(candidate)) return candidate\n }\n return undefined\n}\n\nfunction stripComments(source: string): string {\n let out = ''\n let i = 0\n while (i < source.length) {\n const ch = source[i]\n const next = source[i + 1]\n if (ch === '/' && next === '/') {\n // Line comment: skip until newline\n while (i < source.length && source[i] !== '\\n') i++\n continue\n }\n if (ch === '/' && next === '*') {\n // Block comment: skip until */\n i += 2\n while (i < source.length - 1 && !(source[i] === '*' && source[i + 1] === '/')) i++\n i += 2\n continue\n }\n out += ch\n i++\n }\n return out\n}\n","export interface ServerRouteNode {\n filePath: string\n routePath: string\n paramNames: string[]\n pattern: RegExp\n /** HTTP methods (uppercase) the route file exports. Optional for backward\n * compatibility with manifests generated before G1. Empty array means the\n * file has no HTTP exports (util-only); undefined means \"not detected\". */\n methods?: string[]\n}\n\nexport function compilePattern(routePath: string): {\n pattern: RegExp\n paramNames: string[]\n} {\n const paramNames: string[] = []\n // Single pass: handle both catch-all (:...name) and regular (:name) params\n const regexStr = routePath.replace(/:(?:\\.\\.\\.)?([^/]+)/g, (match: string, name: string) => {\n paramNames.push(name)\n // Catch-all matches across slashes, regular matches single segment\n return match.startsWith(':...') ? '(.+)' : '([^/]+)'\n })\n // `regexStr` is derived from a developer-authored route path (build-time\n // input, not HTTP-controlled). The `security/detect-non-literal-regexp`\n // rule cannot see this constraint — disable narrowly.\n // eslint-disable-next-line security/detect-non-literal-regexp -- route pattern from build-time scan, never HTTP input\n return { pattern: new RegExp(`^${regexStr}$`), paramNames }\n}\n\nexport function matchRoute(\n url: string,\n routes: ServerRouteNode[],\n): { route: ServerRouteNode; params: Record<string, string> } | null {\n // Strip query string and trailing slash\n let path = url.split('?')[0]\n if (path.length > 1 && path.endsWith('/')) {\n path = path.slice(0, -1)\n }\n\n for (const route of routes) {\n const match = route.pattern.exec(path)\n if (match) {\n const params: Record<string, string> = {}\n route.paramNames.forEach((name, i) => {\n params[name] = match[i + 1]\n })\n return { route, params }\n }\n }\n return null\n}\n","/**\n * Canonical HTTP method set used by the typed client codegen + Proxy runtime.\n * Kept here (under `server/scan/`) because the SCAN is the first consumer —\n * `vite-plugin/app-typed-client.ts` (Phase 2) and `client/app-client.ts` (Phase 3)\n * import from here to ensure a single source of truth.\n *\n * Lowercase variants are derived via `.toLowerCase()` at call sites; we do not\n * export them separately to avoid drift between the two lists.\n */\n\nexport const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\n\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\nexport const HTTP_METHOD_LOWERCASE = HTTP_METHODS.map((m) => m.toLowerCase()) as readonly string[]\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/routes/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, readFileSync, statSync } from 'node:fs'\nimport { basename, extname, join, relative } from 'node:path'\n\nimport type { HttpMethod } from '../../core/contracts/http-methods.js'\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nimport { detectExportedHttpMethods } from './detect-http-methods.js'\nimport { detectMethodsWithDeclaredPolicy } from './detect-route-policy.js'\nimport { MissingRoutePolicyError, RouterConventionError } from './errors.js'\nimport { createFileStampCache } from './file-stamp-cache.js'\nimport { compilePattern, type ServerRouteNode } from './match.js'\n\nconst ROUTE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n\n// EC-4: Co-located unit/spec tests must be silently skipped by the scanner,\n// BEFORE the dotted-basename check fires. Matches `*.test.ts|tsx|js|jsx`\n// and `*.spec.ts|tsx|js|jsx`.\nconst TEST_OR_SPEC_RE = /\\.(test|spec)\\.[jt]sx?$/\n\nfunction isTestOrSpecFile(filePath: string): boolean {\n return TEST_OR_SPEC_RE.test(basename(filePath))\n}\n\nfunction hasDotOutsideBrackets(segment: string): boolean {\n let depth = 0\n for (const ch of segment) {\n if (ch === '[') depth++\n else if (ch === ']') depth--\n else if (ch === '.' && depth === 0) return true\n }\n return false\n}\n\nfunction splitDottedSegmentOutsideBrackets(segment: string): string[] {\n const parts: string[] = []\n let current = ''\n let depth = 0\n for (const ch of segment) {\n if (ch === '[') {\n depth++\n current += ch\n } else if (ch === ']') {\n depth--\n current += ch\n } else if (ch === '.' && depth === 0) {\n if (current) parts.push(current)\n current = ''\n } else {\n current += ch\n }\n }\n if (current) parts.push(current)\n return parts\n}\n\nfunction buildDirectoryNestedSuggestion(filePath: string, routesDir: string): string {\n const rel = relative(routesDir, filePath).replace(/\\\\/g, '/')\n const ext = extname(rel)\n const withoutExt = rel.slice(0, -ext.length)\n const segments = withoutExt.split('/').flatMap(splitDottedSegmentOutsideBrackets)\n return `routes/${segments.join('/')}${ext}`\n}\n\nfunction assertNoDottedSegment(filePath: string, routesDir: string): void {\n const rel = relative(routesDir, filePath).replace(/\\\\/g, '/')\n const ext = extname(rel)\n const withoutExt = rel.slice(0, -ext.length)\n const segments = withoutExt.split('/')\n for (const seg of segments) {\n if (hasDotOutsideBrackets(seg)) {\n throw new RouterConventionError({\n file: filePath,\n suggestion: buildDirectoryNestedSuggestion(filePath, routesDir),\n })\n }\n }\n}\n\n/**\n * ADR 0001, Decision point 5 — a route declares its policy explicitly, `public`\n * included, and absence stops meaning open.\n *\n * The refusal lives here, next to the dotted-basename refusal, because this is\n * the one place every entry point passes through: `theo build`, `theo start`,\n * `theo dev`, `theo routes` and each deployment adapter all reach routes by\n * calling `scanServerRoutes`. A gate wired into the build command instead would\n * have to be remembered by six adapters that generate their own entry file, and\n * a gate you can forget to call is a gate that reports on the routes somebody\n * remembered.\n *\n * The blast radius stops at the file system. A `RouteConfig` built in memory and\n * handed to `executeWebRequest` or `callProcedure` never passed a scanner, so it\n * never reaches this function — the runtime still treats an undeclared policy as\n * \"not declared\", exactly as `evaluateRoutePolicy` documents. Absence is refused\n * where an application DECLARES its routes, not where a caller passes one.\n */\nfunction assertEveryMethodDeclaresPolicy(\n filePath: string,\n routePath: string,\n { methods, declaredPolicy }: RouteSourceFacts,\n): void {\n if (methods.length === 0) return\n const missing = methods.filter((method) => !declaredPolicy.has(method))\n if (missing.length === 0) return\n throw new MissingRoutePolicyError({ file: filePath, routePath, methods: missing })\n}\n\n/** What the two AST passes over a route file answer, together. */\ninterface RouteSourceFacts {\n methods: HttpMethod[]\n /** The subset of `methods` that declared a `policy`. Empty when there are no methods. */\n declaredPolicy: Set<HttpMethod>\n}\n\n/**\n * Per-file facts, recomputed only when the file changes (usetheokit/theokit#417).\n *\n * `theokit dev` calls `scanServerRoutes` on EVERY request, and this function parsed each route\n * file with the TypeScript AST TWICE per call — once for the exported methods, once for the policy\n * gate, sharing the source string but not the parse. `agent-scan.ts` had solved exactly this for\n * agent files and wrote down why; routes, which an application has far more of, had neither the\n * cache nor the reasoning.\n *\n * The refusal is deliberately NOT cached — only the facts are. A scan that found a missing policy\n * once must go on refusing on every later scan, so `assertEveryMethodDeclaresPolicy` re-derives the\n * set difference (cheap, no parse) from the cached facts each time.\n */\nconst routeFactsCache = createFileStampCache<RouteSourceFacts>()\n\n/** Test seam — the module-level cache would otherwise outlive a fixture directory. */\nexport function _resetRouteScanCacheForTests(): void {\n routeFactsCache.clear()\n}\n\nfunction routeSourceFacts(absPath: string): RouteSourceFacts {\n return routeFactsCache.get(absPath, () => {\n const source = readFileSync(absPath, 'utf-8')\n const methods = detectExportedHttpMethods(absPath, source)\n // Kept lazy exactly as the early return in the assert made it: a file exporting no HTTP method\n // has nothing for the policy gate to check, and parsing it a second time to learn that was the\n // cost this cache exists to remove.\n const declaredPolicy =\n methods.length === 0\n ? new Set<HttpMethod>()\n : detectMethodsWithDeclaredPolicy(absPath, source)\n return { methods, declaredPolicy }\n })\n}\n\nfunction fileToRoutePath(filePath: string, routesDir: string): string {\n let rel = relative(routesDir, filePath)\n // Strip extension\n const ext = extname(rel)\n rel = rel.slice(0, -ext.length)\n // Normalize separators\n rel = rel.replace(/\\\\/g, '/')\n // Strip index suffix\n if (rel.endsWith('/index')) {\n rel = rel.slice(0, -6)\n } else if (rel === 'index') {\n rel = ''\n }\n // Replace [...param] with :...param (catch-all, before regular params).\n // Replace [param] with :param. Inputs are file paths bounded by the\n // OS filename limit; the bracket capture is bounded by `]`.\n rel = rel.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, ':...$1')\n // eslint-disable-next-line sonarjs/slow-regex -- bounded by `]`; input is a single filename\n rel = rel.replace(/\\[([^\\]]+)\\]/g, ':$1')\n return `/api/${rel}`\n}\n\nexport function scanServerRoutes(serverDir: string): ServerRouteNode[] {\n const routesDir = join(serverDir, 'routes')\n if (!existsSync(routesDir) || !statSync(routesDir).isDirectory()) {\n return []\n }\n\n const results: ServerRouteNode[] = []\n walkSourceFiles(routesDir, { extensions: ROUTE_EXTENSIONS }, (absPath) => {\n // EC-4: skip co-located test/spec files BEFORE the dotted-basename check\n if (isTestOrSpecFile(absPath)) return\n\n // G6 T1.1: reject dotted basenames (legacy convention that produced wrong\n // paramNames due to greedy `:(?:\\.\\.\\.)?([^/]+)` regex in compilePattern).\n assertNoDottedSegment(absPath, routesDir)\n\n const routePath = fileToRoutePath(absPath, routesDir)\n const { pattern, paramNames } = compilePattern(routePath)\n const facts = routeSourceFacts(absPath)\n const { methods } = facts\n assertEveryMethodDeclaresPolicy(absPath, routePath, facts)\n results.push({\n filePath: absPath,\n routePath,\n paramNames,\n pattern,\n methods,\n })\n })\n\n // T1.4 / EC-2 — refuse to scan if a user route collides with the reserved\n // batch endpoint path. User must rename or disable batching.\n const conflicting = results.find((r) => r.routePath === '/api/__theo_batch__')\n if (conflicting) {\n throw new Error(\n `Server route ${conflicting.filePath} resolves to '/api/__theo_batch__' which is reserved for the batch endpoint. Rename the route or disable batching in theo.config.ts.`,\n )\n }\n\n results.sort((a, b) => compareRouteSpecificity(a.routePath, b.routePath))\n\n return results\n}\n\n/** How constrained one path segment is. Lower is more specific. */\nconst SEGMENT_STATIC = 0\nconst SEGMENT_DYNAMIC = 1\nconst SEGMENT_CATCH_ALL = 2\n\nfunction segmentSpecificity(segment: string): number {\n if (segment.startsWith(':...')) return SEGMENT_CATCH_ALL\n if (segment.startsWith(':')) return SEGMENT_DYNAMIC\n return SEGMENT_STATIC\n}\n\n/**\n * Order two route paths by specificity, most specific first.\n *\n * `matchRoute` returns on the first pattern that matches, so this order IS the\n * precedence contract — not a presentation detail of the manifest.\n *\n * Segments are compared position by position, and the first position where they\n * disagree decides: a literal beats a parameter, and a parameter beats a\n * catch-all. That is the rule the URL itself expresses, and it is the rule a\n * whole-path comparison cannot express, because a whole-path comparison reads\n * characters across segment boundaries. Comparing `/api/:resource/settings`\n * with `/api/users/:id` that way put the generic route first — `:` precedes `u`\n * in every collation — so `/api/users/settings` reached the generic handler and\n * an authorization check placed on the specific route was bypassed\n * (usetheokit/theokit#348).\n *\n * Only the segments the two paths have in common are ranked. Past that point\n * one path is a strict prefix of the other, and two such routes cannot match\n * the same URL — so there is nothing to decide, only a stable order to pick.\n *\n * The final fallback compares by code unit rather than with `localeCompare`.\n * Collation is locale-dependent, so the same route table would order\n * differently under a different `LANG` — the cross-machine divergence\n * usetheokit/theokit#346 removed from the sibling scanner. The tiebreak only\n * has to be total and stable; it does not have to be alphabetical for a human.\n */\nexport function compareRouteSpecificity(a: string, b: string): number {\n const aSegments = a.split('/')\n const bSegments = b.split('/')\n const shared = Math.min(aSegments.length, bSegments.length)\n\n for (let i = 0; i < shared; i++) {\n const difference = segmentSpecificity(aSegments[i]) - segmentSpecificity(bSegments[i])\n if (difference !== 0) return difference\n }\n\n if (a < b) return -1\n if (a > b) return 1\n return 0\n}\n","/**\n * Detect which HTTP-method named exports a route file declares.\n *\n * Uses the TypeScript compiler API (not regex) per G1 edge-case review EC-4:\n * regex over file content emits false positives for `// export const GET = ...`\n * in comments and `` `export const GET = ...` `` in template literals. AST\n * walking avoids both classes of bug.\n *\n * `typescript` ships as CommonJS with internal dynamic `require('fs')`.\n * When loaded via ESM `import`, the dynamic requires fail at module-bootstrap.\n * We use `createRequire(import.meta.url)` to keep the package on its native\n * CJS path. The type-only namespace import gives us the AST helpers shape.\n *\n * Returns the set of HTTP methods (uppercase) the file exports. Empty array\n * means the file has no HTTP exports (the route file is util-only).\n */\n\nimport { readFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\n\nimport type * as TS from 'typescript'\n\nimport { HTTP_METHODS, type HttpMethod } from '../../core/contracts/http-methods.js'\nimport { compareByCodeUnit } from '../_internal/compare-by-code-unit.js'\n\nconst require_ = createRequire(import.meta.url)\n\nconst ts = require_('typescript') as typeof TS\n\nconst HTTP_METHOD_NAMES = new Set<string>(HTTP_METHODS)\n\nfunction hasExportModifier(modifiers: readonly TS.Modifier[] | undefined): boolean {\n if (!modifiers) return false\n for (const m of modifiers) {\n if (m.kind === ts.SyntaxKind.ExportKeyword) return true\n }\n return false\n}\n\n// An AST visitor over the export forms (const / function / named export) is inherently branchy;\n// the complexity is in the grammar it walks, not in tangled logic. Splitting it would scatter one\n// cohesive dispatch across helpers for no readability gain.\n// eslint-disable-next-line complexity -- AST visitor, see above\nfunction collectFromStatement(stmt: TS.Statement, found: Set<HttpMethod>): void {\n // `export const GET = ...` / `export function GET ...` / `export async function GET ...`\n if (ts.isVariableStatement(stmt) && hasExportModifier(ts.getModifiers(stmt))) {\n for (const decl of stmt.declarationList.declarations) {\n if (ts.isIdentifier(decl.name) && HTTP_METHOD_NAMES.has(decl.name.text)) {\n found.add(decl.name.text as HttpMethod)\n }\n }\n return\n }\n\n if (\n (ts.isFunctionDeclaration(stmt) || ts.isClassDeclaration(stmt)) &&\n hasExportModifier(ts.getModifiers(stmt))\n ) {\n if (stmt.name && HTTP_METHOD_NAMES.has(stmt.name.text)) {\n found.add(stmt.name.text as HttpMethod)\n }\n return\n }\n\n // `export { GET }` / `export { handler as GET } from './shared'` (EC-5)\n if (ts.isExportDeclaration(stmt) && stmt.exportClause && ts.isNamedExports(stmt.exportClause)) {\n for (const spec of stmt.exportClause.elements) {\n // spec.name is the exported (re-)name; spec.propertyName is the original (when renamed)\n if (HTTP_METHOD_NAMES.has(spec.name.text)) {\n found.add(spec.name.text as HttpMethod)\n }\n }\n }\n}\n\nexport function detectExportedHttpMethods(filePath: string, content?: string): HttpMethod[] {\n // `filePath` is a route module the framework itself discovered by globbing the project — never\n // user input at runtime. Reading it by a computed path is the whole job of a source scanner.\n // eslint-disable-next-line security/detect-non-literal-fs-filename -- framework-controlled path\n const src = content ?? readFileSync(filePath, 'utf-8')\n const sourceFile = ts.createSourceFile(\n filePath,\n src,\n ts.ScriptTarget.Latest,\n /* setParentNodes */ false,\n ts.ScriptKind.TS,\n )\n const found = new Set<HttpMethod>()\n for (const stmt of sourceFile.statements) {\n collectFromStatement(stmt, found)\n }\n // HTTP method names are ASCII, so no collation disagrees about them today.\n // Ordered by code unit anyway, so that \"build output orders by code unit\"\n // stays a rule a reader can check by grep rather than a rule with exceptions\n // each needing its own argument (usetheokit/theokit#351).\n return [...found].sort(compareByCodeUnit)\n}\n","/**\n * Detect which HTTP-method exports of a route file declare an access policy.\n *\n * The companion of `detect-http-methods.ts`, and deliberately the same shape:\n * the TypeScript AST rather than a regex, because `// policy: 'public'` in a\n * comment and `` `policy` `` in a doc string are both things a route file\n * legitimately contains, and neither declares anything.\n *\n * ADR 0001 decides that a route says who may call it, `'public'` included, and\n * that absence stops meaning open. This is the half of that decision the\n * scanner can answer: which exports said something. `scanServerRoutes` turns\n * the silence into a build error.\n *\n * ## What counts as a declaration\n *\n * Two forms, because the framework ships two ways to write a route:\n *\n * ```ts\n * export const GET = route().policy('public').handler(fn).build() // builder\n * export const GET = defineRoute({ policy: fn, handler: fn }) // object\n * ```\n *\n * Only the config position is inspected — the top level of an object literal\n * passed to a call, and `.policy(...)` links of a call chain. The handler's\n * BODY is never walked, so a handler that happens to return `{ policy: ... }`\n * does not satisfy the gate. Reading deeper would trade a false build error for\n * a false pass, and a false pass here is a route nobody protected that the gate\n * reported as protected.\n *\n * ## What it deliberately cannot see\n *\n * `export { GET } from './shared'` re-exports across a module boundary, and\n * `export const GET = makeAdminRoute(fn)` hides the config inside a helper.\n * Both come back \"not declared\", which fails the build. That direction is the\n * chosen one: the cost is an explicit declaration on a route that already had\n * one somewhere else, and the alternative cost is a route reported as declared\n * because the scanner guessed.\n */\nimport { createRequire } from 'node:module'\n\nimport type * as TS from 'typescript'\n\nimport { HTTP_METHODS, type HttpMethod } from '../../core/contracts/http-methods.js'\n\nconst require_ = createRequire(import.meta.url)\n\nconst ts = require_('typescript') as typeof TS\n\nconst HTTP_METHOD_NAMES = new Set<string>(HTTP_METHODS)\n\nconst POLICY_KEY = 'policy'\n\nfunction hasExportModifier(modifiers: readonly TS.Modifier[] | undefined): boolean {\n if (!modifiers) return false\n for (const m of modifiers) {\n if (m.kind === ts.SyntaxKind.ExportKeyword) return true\n }\n return false\n}\n\n/** Strip the wrappers that carry no runtime meaning (`(x)`, `x as T`, `x satisfies T`, `x!`). */\nfunction unwrap(expression: TS.Expression): TS.Expression {\n let current = expression\n for (;;) {\n if (\n ts.isParenthesizedExpression(current) ||\n ts.isAsExpression(current) ||\n ts.isSatisfiesExpression(current) ||\n ts.isNonNullExpression(current)\n ) {\n current = current.expression\n continue\n }\n return current\n }\n}\n\nfunction propertyNameIsPolicy(name: TS.PropertyName | undefined): boolean {\n if (name === undefined) return false\n if (ts.isIdentifier(name)) return name.text === POLICY_KEY\n if (ts.isStringLiteral(name)) return name.text === POLICY_KEY\n return false\n}\n\n/** A `policy` key at the TOP level of a config object literal. Never deeper. */\nfunction objectDeclaresPolicy(literal: TS.ObjectLiteralExpression): boolean {\n for (const property of literal.properties) {\n if (ts.isSpreadAssignment(property)) continue\n if (propertyNameIsPolicy(property.name)) return true\n }\n return false\n}\n\n/**\n * Does this initializer declare a policy?\n *\n * Walks the call chain leftwards (`.build()` -> `.handler()` -> `.policy()`) and\n * checks the arguments each call receives, which is where the object form puts\n * its config. Nothing else is visited.\n */\nfunction declaresPolicy(expression: TS.Expression): boolean {\n const expr = unwrap(expression)\n\n if (ts.isObjectLiteralExpression(expr)) return objectDeclaresPolicy(expr)\n\n if (!ts.isCallExpression(expr)) return false\n\n const callee = unwrap(expr.expression)\n\n if (ts.isPropertyAccessExpression(callee) && callee.name.text === POLICY_KEY) return true\n\n for (const argument of expr.arguments) {\n const arg = unwrap(argument)\n if (ts.isObjectLiteralExpression(arg) && objectDeclaresPolicy(arg)) return true\n }\n\n // Keep walking the chain: `route().policy(p).handler(h).build()` reaches\n // `.policy` only by stepping left through `.build` and `.handler`.\n if (ts.isPropertyAccessExpression(callee)) return declaresPolicy(callee.expression)\n\n return false\n}\n\n/** Every top-level `const x = <expr>` in the file, so `export { x as GET }` can be resolved. */\nfunction collectLocalInitializers(sourceFile: TS.SourceFile): Map<string, TS.Expression> {\n const locals = new Map<string, TS.Expression>()\n for (const stmt of sourceFile.statements) {\n if (!ts.isVariableStatement(stmt)) continue\n for (const decl of stmt.declarationList.declarations) {\n if (ts.isIdentifier(decl.name) && decl.initializer !== undefined) {\n locals.set(decl.name.text, decl.initializer)\n }\n }\n }\n return locals\n}\n\n/** `export const GET = ...` */\nfunction collectFromVariableStatement(stmt: TS.VariableStatement, declared: Set<HttpMethod>): void {\n if (!hasExportModifier(ts.getModifiers(stmt))) return\n for (const decl of stmt.declarationList.declarations) {\n if (!ts.isIdentifier(decl.name) || !HTTP_METHOD_NAMES.has(decl.name.text)) continue\n if (decl.initializer !== undefined && declaresPolicy(decl.initializer)) {\n declared.add(decl.name.text as HttpMethod)\n }\n }\n}\n\n/**\n * `export { GET }` / `export { handler as GET }` — resolvable only when the\n * declaration is in this file. A re-export with a module specifier is not.\n */\nfunction collectFromExportDeclaration(\n stmt: TS.ExportDeclaration,\n locals: Map<string, TS.Expression>,\n declared: Set<HttpMethod>,\n): void {\n if (stmt.moduleSpecifier !== undefined) return\n if (!stmt.exportClause || !ts.isNamedExports(stmt.exportClause)) return\n for (const spec of stmt.exportClause.elements) {\n if (!HTTP_METHOD_NAMES.has(spec.name.text)) continue\n const local = locals.get((spec.propertyName ?? spec.name).text)\n if (local !== undefined && declaresPolicy(local)) {\n declared.add(spec.name.text as HttpMethod)\n }\n }\n}\n\nfunction collectFromStatement(\n stmt: TS.Statement,\n locals: Map<string, TS.Expression>,\n declared: Set<HttpMethod>,\n): void {\n if (ts.isVariableStatement(stmt)) {\n collectFromVariableStatement(stmt, declared)\n return\n }\n if (ts.isExportDeclaration(stmt)) {\n collectFromExportDeclaration(stmt, locals, declared)\n }\n // `export function GET() {}` and `export class GET {}` reach neither branch,\n // on purpose: a bare function has no config object to carry a policy.\n}\n\n/**\n * The set of HTTP-method exports in this file that declare an access policy.\n *\n * `content` is passed in rather than read here so the scanner reads each route\n * file once and hands the same source to both detectors.\n */\nexport function detectMethodsWithDeclaredPolicy(\n filePath: string,\n content: string,\n): Set<HttpMethod> {\n const sourceFile = ts.createSourceFile(\n filePath,\n content,\n ts.ScriptTarget.Latest,\n /* setParentNodes */ false,\n ts.ScriptKind.TS,\n )\n const locals = collectLocalInitializers(sourceFile)\n const declared = new Set<HttpMethod>()\n for (const stmt of sourceFile.statements) {\n collectFromStatement(stmt, locals, declared)\n }\n return declared\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/ws/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nconst WS_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n\nexport interface WebSocketRouteNode {\n filePath: string\n wsPath: string\n}\n\nexport function scanWebSocketRoutes(serverDir: string): WebSocketRouteNode[] {\n const wsDir = join(serverDir, 'ws')\n if (!existsSync(wsDir) || !statSync(wsDir).isDirectory()) {\n return []\n }\n\n const results: WebSocketRouteNode[] = []\n walkSourceFiles(wsDir, { extensions: WS_EXTENSIONS }, (absPath) => {\n let rel = relative(wsDir, absPath)\n rel = rel.replace(/\\\\/g, '/')\n rel = rel.slice(0, -extname(rel).length)\n if (rel.endsWith('/index')) rel = rel.slice(0, -6)\n else if (rel === 'index') rel = ''\n results.push({\n filePath: absPath,\n wsPath: `/ws/${rel}`,\n })\n })\n return results\n}\n"],"mappings":"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","names":["basename","existsSync","readFileSync","statSync","extname","join","relative","readFileSync","readFileSync","createRequire","require_","createRequire","ts","HTTP_METHOD_NAMES","hasExportModifier","collectFromStatement","relative","extname","readFileSync","relative","extname","join","existsSync","statSync","existsSync","statSync","extname","join","relative","join","existsSync","statSync","relative","extname"]}
@@ -0,0 +1,31 @@
1
+ // src/core/contracts/route-policy.ts
2
+ function subjectFromContext(context) {
3
+ if (context === null || typeof context !== "object") return null;
4
+ const candidate = context.subject;
5
+ if (candidate === null || candidate === void 0 || typeof candidate !== "object") return null;
6
+ const id = candidate.id;
7
+ return typeof id === "string" && id.length > 0 ? candidate : null;
8
+ }
9
+ async function evaluateRoutePolicy(policy, input) {
10
+ if (policy === void 0) return { allowed: true };
11
+ if (policy === "public") return { allowed: true };
12
+ const verdict = await policy(input);
13
+ if (typeof verdict === "boolean") {
14
+ return verdict ? { allowed: true } : { allowed: false, reason: "access denied by route policy" };
15
+ }
16
+ return verdict;
17
+ }
18
+ function requireOwner(subject, ownerId) {
19
+ if (subject === null) return { allowed: false, reason: "not authenticated" };
20
+ if (typeof ownerId !== "string" || ownerId.length === 0) {
21
+ return { allowed: false, reason: "resource has no recorded owner" };
22
+ }
23
+ return subject.id === ownerId ? { allowed: true } : { allowed: false, reason: "subject does not own this resource" };
24
+ }
25
+
26
+ export {
27
+ subjectFromContext,
28
+ evaluateRoutePolicy,
29
+ requireOwner
30
+ };
31
+ //# sourceMappingURL=chunk-YN4W7LCX.js.map