@alchemy.run/modal 0.0.0 → 2.0.0-beta.86

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 (499) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +96 -4
  3. package/lib/App.d.ts +143 -0
  4. package/lib/App.d.ts.map +1 -0
  5. package/lib/App.js +198 -0
  6. package/lib/App.js.map +1 -0
  7. package/lib/AuthProvider.d.ts +53 -0
  8. package/lib/AuthProvider.d.ts.map +1 -0
  9. package/lib/AuthProvider.js +209 -0
  10. package/lib/AuthProvider.js.map +1 -0
  11. package/lib/BindingHttp.d.ts +56 -0
  12. package/lib/BindingHttp.d.ts.map +1 -0
  13. package/lib/BindingHttp.js +50 -0
  14. package/lib/BindingHttp.js.map +1 -0
  15. package/lib/Blob.d.ts +34 -0
  16. package/lib/Blob.d.ts.map +1 -0
  17. package/lib/Blob.js +59 -0
  18. package/lib/Blob.js.map +1 -0
  19. package/lib/Bootstrap.d.ts +8 -0
  20. package/lib/Bootstrap.d.ts.map +1 -0
  21. package/lib/Bootstrap.js +26 -0
  22. package/lib/Bootstrap.js.map +1 -0
  23. package/lib/Cbor.d.ts +10 -0
  24. package/lib/Cbor.d.ts.map +1 -0
  25. package/lib/Cbor.js +177 -0
  26. package/lib/Cbor.js.map +1 -0
  27. package/lib/ConnectSandbox.d.ts +64 -0
  28. package/lib/ConnectSandbox.d.ts.map +1 -0
  29. package/lib/ConnectSandbox.js +33 -0
  30. package/lib/ConnectSandbox.js.map +1 -0
  31. package/lib/Container.d.ts +124 -0
  32. package/lib/Container.d.ts.map +1 -0
  33. package/lib/Container.js +1 -0
  34. package/lib/Container.js.map +1 -0
  35. package/lib/Contributions.d.ts +7 -0
  36. package/lib/Contributions.d.ts.map +1 -0
  37. package/lib/Contributions.js +6 -0
  38. package/lib/Contributions.js.map +1 -0
  39. package/lib/CreateDict.d.ts +83 -0
  40. package/lib/CreateDict.d.ts.map +1 -0
  41. package/lib/CreateDict.js +3 -0
  42. package/lib/CreateDict.js.map +1 -0
  43. package/lib/CreateDictHttp.d.ts +33 -0
  44. package/lib/CreateDictHttp.d.ts.map +1 -0
  45. package/lib/CreateDictHttp.js +67 -0
  46. package/lib/CreateDictHttp.js.map +1 -0
  47. package/lib/CreateImage.d.ts +98 -0
  48. package/lib/CreateImage.d.ts.map +1 -0
  49. package/lib/CreateImage.js +3 -0
  50. package/lib/CreateImage.js.map +1 -0
  51. package/lib/CreateImageHttp.d.ts +51 -0
  52. package/lib/CreateImageHttp.d.ts.map +1 -0
  53. package/lib/CreateImageHttp.js +87 -0
  54. package/lib/CreateImageHttp.js.map +1 -0
  55. package/lib/CreateQueue.d.ts +83 -0
  56. package/lib/CreateQueue.d.ts.map +1 -0
  57. package/lib/CreateQueue.js +3 -0
  58. package/lib/CreateQueue.js.map +1 -0
  59. package/lib/CreateQueueHttp.d.ts +31 -0
  60. package/lib/CreateQueueHttp.d.ts.map +1 -0
  61. package/lib/CreateQueueHttp.js +67 -0
  62. package/lib/CreateQueueHttp.js.map +1 -0
  63. package/lib/CreateSandbox.d.ts +186 -0
  64. package/lib/CreateSandbox.d.ts.map +1 -0
  65. package/lib/CreateSandbox.js +3 -0
  66. package/lib/CreateSandbox.js.map +1 -0
  67. package/lib/CreateSandboxHttp.d.ts +17 -0
  68. package/lib/CreateSandboxHttp.d.ts.map +1 -0
  69. package/lib/CreateSandboxHttp.js +117 -0
  70. package/lib/CreateSandboxHttp.js.map +1 -0
  71. package/lib/CreateSecret.d.ts +95 -0
  72. package/lib/CreateSecret.d.ts.map +1 -0
  73. package/lib/CreateSecret.js +3 -0
  74. package/lib/CreateSecret.js.map +1 -0
  75. package/lib/CreateSecretHttp.d.ts +24 -0
  76. package/lib/CreateSecretHttp.d.ts.map +1 -0
  77. package/lib/CreateSecretHttp.js +60 -0
  78. package/lib/CreateSecretHttp.js.map +1 -0
  79. package/lib/CreateVolume.d.ts +84 -0
  80. package/lib/CreateVolume.d.ts.map +1 -0
  81. package/lib/CreateVolume.js +3 -0
  82. package/lib/CreateVolume.js.map +1 -0
  83. package/lib/CreateVolumeHttp.d.ts +32 -0
  84. package/lib/CreateVolumeHttp.d.ts.map +1 -0
  85. package/lib/CreateVolumeHttp.js +69 -0
  86. package/lib/CreateVolumeHttp.js.map +1 -0
  87. package/lib/Credentials.d.ts +32 -0
  88. package/lib/Credentials.d.ts.map +1 -0
  89. package/lib/Credentials.js +44 -0
  90. package/lib/Credentials.js.map +1 -0
  91. package/lib/Dict.d.ts +147 -0
  92. package/lib/Dict.d.ts.map +1 -0
  93. package/lib/Dict.js +175 -0
  94. package/lib/Dict.js.map +1 -0
  95. package/lib/DictClient.d.ts +55 -0
  96. package/lib/DictClient.d.ts.map +1 -0
  97. package/lib/DictClient.js +89 -0
  98. package/lib/DictClient.js.map +1 -0
  99. package/lib/Domain.d.ts +86 -0
  100. package/lib/Domain.d.ts.map +1 -0
  101. package/lib/Domain.js +113 -0
  102. package/lib/Domain.js.map +1 -0
  103. package/lib/Endpoint.d.ts +181 -0
  104. package/lib/Endpoint.d.ts.map +1 -0
  105. package/lib/Endpoint.js +283 -0
  106. package/lib/Endpoint.js.map +1 -0
  107. package/lib/Environment.d.ts +174 -0
  108. package/lib/Environment.d.ts.map +1 -0
  109. package/lib/Environment.js +244 -0
  110. package/lib/Environment.js.map +1 -0
  111. package/lib/FetchServer.d.ts +105 -0
  112. package/lib/FetchServer.d.ts.map +1 -0
  113. package/lib/FetchServer.js +3 -0
  114. package/lib/FetchServer.js.map +1 -0
  115. package/lib/FetchServerHttp.d.ts +21 -0
  116. package/lib/FetchServerHttp.d.ts.map +1 -0
  117. package/lib/FetchServerHttp.js +84 -0
  118. package/lib/FetchServerHttp.js.map +1 -0
  119. package/lib/Function.d.ts +236 -0
  120. package/lib/Function.d.ts.map +1 -0
  121. package/lib/Function.js +273 -0
  122. package/lib/Function.js.map +1 -0
  123. package/lib/FunctionAutoscaler.d.ts +99 -0
  124. package/lib/FunctionAutoscaler.d.ts.map +1 -0
  125. package/lib/FunctionAutoscaler.js +136 -0
  126. package/lib/FunctionAutoscaler.js.map +1 -0
  127. package/lib/FunctionTarget.d.ts +61 -0
  128. package/lib/FunctionTarget.d.ts.map +1 -0
  129. package/lib/FunctionTarget.js +136 -0
  130. package/lib/FunctionTarget.js.map +1 -0
  131. package/lib/Image.d.ts +159 -0
  132. package/lib/Image.d.ts.map +1 -0
  133. package/lib/Image.js +203 -0
  134. package/lib/Image.js.map +1 -0
  135. package/lib/ImageBuild.d.ts +108 -0
  136. package/lib/ImageBuild.d.ts.map +1 -0
  137. package/lib/ImageBuild.js +157 -0
  138. package/lib/ImageBuild.js.map +1 -0
  139. package/lib/ImagePlan.d.ts +31 -0
  140. package/lib/ImagePlan.d.ts.map +1 -0
  141. package/lib/ImagePlan.js +70 -0
  142. package/lib/ImagePlan.js.map +1 -0
  143. package/lib/InferEnv.d.ts +26 -0
  144. package/lib/InferEnv.d.ts.map +1 -0
  145. package/lib/InferEnv.js +1 -0
  146. package/lib/InferEnv.js.map +1 -0
  147. package/lib/InvokeFunction.d.ts +186 -0
  148. package/lib/InvokeFunction.d.ts.map +1 -0
  149. package/lib/InvokeFunction.js +10 -0
  150. package/lib/InvokeFunction.js.map +1 -0
  151. package/lib/InvokeFunctionHttp.d.ts +39 -0
  152. package/lib/InvokeFunctionHttp.d.ts.map +1 -0
  153. package/lib/InvokeFunctionHttp.js +210 -0
  154. package/lib/InvokeFunctionHttp.js.map +1 -0
  155. package/lib/ModalBindings.d.ts +138 -0
  156. package/lib/ModalBindings.d.ts.map +1 -0
  157. package/lib/ModalBindings.js +223 -0
  158. package/lib/ModalBindings.js.map +1 -0
  159. package/lib/MountBucket.d.ts +80 -0
  160. package/lib/MountBucket.d.ts.map +1 -0
  161. package/lib/MountBucket.js +44 -0
  162. package/lib/MountBucket.js.map +1 -0
  163. package/lib/MountVolume.d.ts +77 -0
  164. package/lib/MountVolume.d.ts.map +1 -0
  165. package/lib/MountVolume.js +41 -0
  166. package/lib/MountVolume.js.map +1 -0
  167. package/lib/Mounts.d.ts +134 -0
  168. package/lib/Mounts.d.ts.map +1 -0
  169. package/lib/Mounts.js +87 -0
  170. package/lib/Mounts.js.map +1 -0
  171. package/lib/PersistentSandbox.d.ts +75 -0
  172. package/lib/PersistentSandbox.d.ts.map +1 -0
  173. package/lib/PersistentSandbox.js +93 -0
  174. package/lib/PersistentSandbox.js.map +1 -0
  175. package/lib/Providers.d.ts +23 -0
  176. package/lib/Providers.d.ts.map +1 -0
  177. package/lib/Providers.js +64 -0
  178. package/lib/Providers.js.map +1 -0
  179. package/lib/Proxy.d.ts +94 -0
  180. package/lib/Proxy.d.ts.map +1 -0
  181. package/lib/Proxy.js +132 -0
  182. package/lib/Proxy.js.map +1 -0
  183. package/lib/Queue.d.ts +147 -0
  184. package/lib/Queue.d.ts.map +1 -0
  185. package/lib/Queue.js +177 -0
  186. package/lib/Queue.js.map +1 -0
  187. package/lib/QueueClient.d.ts +64 -0
  188. package/lib/QueueClient.d.ts.map +1 -0
  189. package/lib/QueueClient.js +73 -0
  190. package/lib/QueueClient.js.map +1 -0
  191. package/lib/ReadApp.d.ts +85 -0
  192. package/lib/ReadApp.d.ts.map +1 -0
  193. package/lib/ReadApp.js +3 -0
  194. package/lib/ReadApp.js.map +1 -0
  195. package/lib/ReadAppHttp.d.ts +26 -0
  196. package/lib/ReadAppHttp.d.ts.map +1 -0
  197. package/lib/ReadAppHttp.js +106 -0
  198. package/lib/ReadAppHttp.js.map +1 -0
  199. package/lib/ReadDict.d.ts +39 -0
  200. package/lib/ReadDict.d.ts.map +1 -0
  201. package/lib/ReadDict.js +3 -0
  202. package/lib/ReadDict.js.map +1 -0
  203. package/lib/ReadDictHttp.d.ts +12 -0
  204. package/lib/ReadDictHttp.d.ts.map +1 -0
  205. package/lib/ReadDictHttp.js +23 -0
  206. package/lib/ReadDictHttp.js.map +1 -0
  207. package/lib/ReadFunction.d.ts +73 -0
  208. package/lib/ReadFunction.d.ts.map +1 -0
  209. package/lib/ReadFunction.js +3 -0
  210. package/lib/ReadFunction.js.map +1 -0
  211. package/lib/ReadFunctionHttp.d.ts +25 -0
  212. package/lib/ReadFunctionHttp.d.ts.map +1 -0
  213. package/lib/ReadFunctionHttp.js +63 -0
  214. package/lib/ReadFunctionHttp.js.map +1 -0
  215. package/lib/ReadQueue.d.ts +39 -0
  216. package/lib/ReadQueue.d.ts.map +1 -0
  217. package/lib/ReadQueue.js +3 -0
  218. package/lib/ReadQueue.js.map +1 -0
  219. package/lib/ReadQueueHttp.d.ts +12 -0
  220. package/lib/ReadQueueHttp.d.ts.map +1 -0
  221. package/lib/ReadQueueHttp.js +23 -0
  222. package/lib/ReadQueueHttp.js.map +1 -0
  223. package/lib/ReadServer.d.ts +72 -0
  224. package/lib/ReadServer.d.ts.map +1 -0
  225. package/lib/ReadServer.js +3 -0
  226. package/lib/ReadServer.js.map +1 -0
  227. package/lib/ReadServerHttp.d.ts +25 -0
  228. package/lib/ReadServerHttp.d.ts.map +1 -0
  229. package/lib/ReadServerHttp.js +70 -0
  230. package/lib/ReadServerHttp.js.map +1 -0
  231. package/lib/ReadVolume.d.ts +40 -0
  232. package/lib/ReadVolume.d.ts.map +1 -0
  233. package/lib/ReadVolume.js +3 -0
  234. package/lib/ReadVolume.js.map +1 -0
  235. package/lib/ReadVolumeHttp.d.ts +12 -0
  236. package/lib/ReadVolumeHttp.d.ts.map +1 -0
  237. package/lib/ReadVolumeHttp.js +24 -0
  238. package/lib/ReadVolumeHttp.js.map +1 -0
  239. package/lib/ReadWriteDict.d.ts +39 -0
  240. package/lib/ReadWriteDict.d.ts.map +1 -0
  241. package/lib/ReadWriteDict.js +3 -0
  242. package/lib/ReadWriteDict.js.map +1 -0
  243. package/lib/ReadWriteDictHttp.d.ts +12 -0
  244. package/lib/ReadWriteDictHttp.d.ts.map +1 -0
  245. package/lib/ReadWriteDictHttp.js +23 -0
  246. package/lib/ReadWriteDictHttp.js.map +1 -0
  247. package/lib/ReadWriteQueue.d.ts +40 -0
  248. package/lib/ReadWriteQueue.d.ts.map +1 -0
  249. package/lib/ReadWriteQueue.js +3 -0
  250. package/lib/ReadWriteQueue.js.map +1 -0
  251. package/lib/ReadWriteQueueHttp.d.ts +12 -0
  252. package/lib/ReadWriteQueueHttp.d.ts.map +1 -0
  253. package/lib/ReadWriteQueueHttp.js +23 -0
  254. package/lib/ReadWriteQueueHttp.js.map +1 -0
  255. package/lib/ReadWriteVolume.d.ts +40 -0
  256. package/lib/ReadWriteVolume.d.ts.map +1 -0
  257. package/lib/ReadWriteVolume.js +3 -0
  258. package/lib/ReadWriteVolume.js.map +1 -0
  259. package/lib/ReadWriteVolumeHttp.d.ts +12 -0
  260. package/lib/ReadWriteVolumeHttp.d.ts.map +1 -0
  261. package/lib/ReadWriteVolumeHttp.js +24 -0
  262. package/lib/ReadWriteVolumeHttp.js.map +1 -0
  263. package/lib/RuntimeOwner.d.ts +39 -0
  264. package/lib/RuntimeOwner.d.ts.map +1 -0
  265. package/lib/RuntimeOwner.js +85 -0
  266. package/lib/RuntimeOwner.js.map +1 -0
  267. package/lib/Sandbox.d.ts +215 -0
  268. package/lib/Sandbox.d.ts.map +1 -0
  269. package/lib/Sandbox.js +278 -0
  270. package/lib/Sandbox.js.map +1 -0
  271. package/lib/SandboxClient.d.ts +748 -0
  272. package/lib/SandboxClient.d.ts.map +1 -0
  273. package/lib/SandboxClient.js +710 -0
  274. package/lib/SandboxClient.js.map +1 -0
  275. package/lib/ScaleFunction.d.ts +54 -0
  276. package/lib/ScaleFunction.d.ts.map +1 -0
  277. package/lib/ScaleFunction.js +3 -0
  278. package/lib/ScaleFunction.js.map +1 -0
  279. package/lib/ScaleFunctionHttp.d.ts +21 -0
  280. package/lib/ScaleFunctionHttp.d.ts.map +1 -0
  281. package/lib/ScaleFunctionHttp.js +39 -0
  282. package/lib/ScaleFunctionHttp.js.map +1 -0
  283. package/lib/Secret.d.ts +170 -0
  284. package/lib/Secret.d.ts.map +1 -0
  285. package/lib/Secret.js +196 -0
  286. package/lib/Secret.js.map +1 -0
  287. package/lib/Server.d.ts +155 -0
  288. package/lib/Server.d.ts.map +1 -0
  289. package/lib/Server.js +184 -0
  290. package/lib/Server.js.map +1 -0
  291. package/lib/ServiceUser.d.ts +139 -0
  292. package/lib/ServiceUser.d.ts.map +1 -0
  293. package/lib/ServiceUser.js +210 -0
  294. package/lib/ServiceUser.js.map +1 -0
  295. package/lib/Volume.d.ts +170 -0
  296. package/lib/Volume.d.ts.map +1 -0
  297. package/lib/Volume.js +220 -0
  298. package/lib/Volume.js.map +1 -0
  299. package/lib/VolumeClient.d.ts +53 -0
  300. package/lib/VolumeClient.d.ts.map +1 -0
  301. package/lib/VolumeClient.js +22 -0
  302. package/lib/VolumeClient.js.map +1 -0
  303. package/lib/VolumeFiles.d.ts +94 -0
  304. package/lib/VolumeFiles.d.ts.map +1 -0
  305. package/lib/VolumeFiles.js +139 -0
  306. package/lib/VolumeFiles.js.map +1 -0
  307. package/lib/WebhookToken.d.ts +102 -0
  308. package/lib/WebhookToken.d.ts.map +1 -0
  309. package/lib/WebhookToken.js +176 -0
  310. package/lib/WebhookToken.js.map +1 -0
  311. package/lib/WorkspaceSettings.d.ts +70 -0
  312. package/lib/WorkspaceSettings.d.ts.map +1 -0
  313. package/lib/WorkspaceSettings.js +105 -0
  314. package/lib/WorkspaceSettings.js.map +1 -0
  315. package/lib/WriteApp.d.ts +38 -0
  316. package/lib/WriteApp.d.ts.map +1 -0
  317. package/lib/WriteApp.js +3 -0
  318. package/lib/WriteApp.js.map +1 -0
  319. package/lib/WriteAppHttp.d.ts +23 -0
  320. package/lib/WriteAppHttp.d.ts.map +1 -0
  321. package/lib/WriteAppHttp.js +36 -0
  322. package/lib/WriteAppHttp.js.map +1 -0
  323. package/lib/WriteDict.d.ts +39 -0
  324. package/lib/WriteDict.d.ts.map +1 -0
  325. package/lib/WriteDict.js +3 -0
  326. package/lib/WriteDict.js.map +1 -0
  327. package/lib/WriteDictHttp.d.ts +12 -0
  328. package/lib/WriteDictHttp.d.ts.map +1 -0
  329. package/lib/WriteDictHttp.js +23 -0
  330. package/lib/WriteDictHttp.js.map +1 -0
  331. package/lib/WriteQueue.d.ts +39 -0
  332. package/lib/WriteQueue.d.ts.map +1 -0
  333. package/lib/WriteQueue.js +3 -0
  334. package/lib/WriteQueue.js.map +1 -0
  335. package/lib/WriteQueueHttp.d.ts +12 -0
  336. package/lib/WriteQueueHttp.d.ts.map +1 -0
  337. package/lib/WriteQueueHttp.js +23 -0
  338. package/lib/WriteQueueHttp.js.map +1 -0
  339. package/lib/WriteSecret.d.ts +53 -0
  340. package/lib/WriteSecret.d.ts.map +1 -0
  341. package/lib/WriteSecret.js +3 -0
  342. package/lib/WriteSecret.js.map +1 -0
  343. package/lib/WriteSecretHttp.d.ts +23 -0
  344. package/lib/WriteSecretHttp.d.ts.map +1 -0
  345. package/lib/WriteSecretHttp.js +44 -0
  346. package/lib/WriteSecretHttp.js.map +1 -0
  347. package/lib/WriteVolume.d.ts +39 -0
  348. package/lib/WriteVolume.d.ts.map +1 -0
  349. package/lib/WriteVolume.js +3 -0
  350. package/lib/WriteVolume.js.map +1 -0
  351. package/lib/WriteVolumeHttp.d.ts +12 -0
  352. package/lib/WriteVolumeHttp.d.ts.map +1 -0
  353. package/lib/WriteVolumeHttp.js +24 -0
  354. package/lib/WriteVolumeHttp.js.map +1 -0
  355. package/lib/index.d.ts +80 -0
  356. package/lib/index.d.ts.map +1 -0
  357. package/lib/index.js +78 -0
  358. package/lib/index.js.map +1 -0
  359. package/lib/internal/Declared.d.ts +29 -0
  360. package/lib/internal/Declared.d.ts.map +1 -0
  361. package/lib/internal/Declared.js +31 -0
  362. package/lib/internal/Declared.js.map +1 -0
  363. package/lib/internal/Deploy.d.ts +110 -0
  364. package/lib/internal/Deploy.d.ts.map +1 -0
  365. package/lib/internal/Deploy.js +230 -0
  366. package/lib/internal/Deploy.js.map +1 -0
  367. package/lib/internal/Entrypoint.d.ts +52 -0
  368. package/lib/internal/Entrypoint.d.ts.map +1 -0
  369. package/lib/internal/Entrypoint.js +193 -0
  370. package/lib/internal/Entrypoint.js.map +1 -0
  371. package/lib/internal/Rpc.d.ts +17 -0
  372. package/lib/internal/Rpc.d.ts.map +1 -0
  373. package/lib/internal/Rpc.js +49 -0
  374. package/lib/internal/Rpc.js.map +1 -0
  375. package/lib/internal/RpcAuth.d.ts +41 -0
  376. package/lib/internal/RpcAuth.d.ts.map +1 -0
  377. package/lib/internal/RpcAuth.js +100 -0
  378. package/lib/internal/RpcAuth.js.map +1 -0
  379. package/lib/internal/Runtime.d.ts +127 -0
  380. package/lib/internal/Runtime.d.ts.map +1 -0
  381. package/lib/internal/Runtime.js +246 -0
  382. package/lib/internal/Runtime.js.map +1 -0
  383. package/lib/internal/Tags.d.ts +19 -0
  384. package/lib/internal/Tags.d.ts.map +1 -0
  385. package/lib/internal/Tags.js +33 -0
  386. package/lib/internal/Tags.js.map +1 -0
  387. package/lib/internal/TcpConnect.d.ts +12 -0
  388. package/lib/internal/TcpConnect.d.ts.map +1 -0
  389. package/lib/internal/TcpConnect.js +46 -0
  390. package/lib/internal/TcpConnect.js.map +1 -0
  391. package/lib/internal/Transport.d.ts +13 -0
  392. package/lib/internal/Transport.d.ts.map +1 -0
  393. package/lib/internal/Transport.js +16 -0
  394. package/lib/internal/Transport.js.map +1 -0
  395. package/lib/internal.d.ts +71 -0
  396. package/lib/internal.d.ts.map +1 -0
  397. package/lib/internal.js +102 -0
  398. package/lib/internal.js.map +1 -0
  399. package/package.json +59 -3
  400. package/src/App.ts +262 -0
  401. package/src/AuthProvider.ts +295 -0
  402. package/src/BindingHttp.ts +112 -0
  403. package/src/Blob.ts +71 -0
  404. package/src/Bootstrap.ts +52 -0
  405. package/src/Cbor.ts +158 -0
  406. package/src/ConnectSandbox.ts +99 -0
  407. package/src/Container.ts +121 -0
  408. package/src/Contributions.ts +9 -0
  409. package/src/CreateDict.ts +95 -0
  410. package/src/CreateDictHttp.ts +91 -0
  411. package/src/CreateImage.ts +105 -0
  412. package/src/CreateImageHttp.ts +117 -0
  413. package/src/CreateQueue.ts +95 -0
  414. package/src/CreateQueueHttp.ts +91 -0
  415. package/src/CreateSandbox.ts +228 -0
  416. package/src/CreateSandboxHttp.ts +160 -0
  417. package/src/CreateSecret.ts +109 -0
  418. package/src/CreateSecretHttp.ts +83 -0
  419. package/src/CreateVolume.ts +96 -0
  420. package/src/CreateVolumeHttp.ts +93 -0
  421. package/src/Credentials.ts +74 -0
  422. package/src/Dict.ts +245 -0
  423. package/src/DictClient.ts +166 -0
  424. package/src/Domain.ts +147 -0
  425. package/src/Endpoint.ts +406 -0
  426. package/src/Environment.ts +373 -0
  427. package/src/FetchServer.ts +126 -0
  428. package/src/FetchServerHttp.ts +110 -0
  429. package/src/Function.ts +397 -0
  430. package/src/FunctionAutoscaler.ts +210 -0
  431. package/src/FunctionTarget.ts +181 -0
  432. package/src/Image.ts +281 -0
  433. package/src/ImageBuild.ts +228 -0
  434. package/src/ImagePlan.ts +78 -0
  435. package/src/InferEnv.ts +27 -0
  436. package/src/InvokeFunction.ts +211 -0
  437. package/src/InvokeFunctionHttp.ts +316 -0
  438. package/src/ModalBindings.ts +310 -0
  439. package/src/MountBucket.ts +137 -0
  440. package/src/MountVolume.ts +113 -0
  441. package/src/Mounts.ts +230 -0
  442. package/src/PersistentSandbox.ts +142 -0
  443. package/src/Providers.ts +100 -0
  444. package/src/Proxy.ts +191 -0
  445. package/src/Queue.ts +258 -0
  446. package/src/QueueClient.ts +149 -0
  447. package/src/ReadApp.ts +101 -0
  448. package/src/ReadAppHttp.ts +142 -0
  449. package/src/ReadDict.ts +44 -0
  450. package/src/ReadDictHttp.ts +27 -0
  451. package/src/ReadFunction.ts +107 -0
  452. package/src/ReadFunctionHttp.ts +91 -0
  453. package/src/ReadQueue.ts +44 -0
  454. package/src/ReadQueueHttp.ts +27 -0
  455. package/src/ReadServer.ts +98 -0
  456. package/src/ReadServerHttp.ts +101 -0
  457. package/src/ReadVolume.ts +45 -0
  458. package/src/ReadVolumeHttp.ts +28 -0
  459. package/src/ReadWriteDict.ts +44 -0
  460. package/src/ReadWriteDictHttp.ts +27 -0
  461. package/src/ReadWriteQueue.ts +45 -0
  462. package/src/ReadWriteQueueHttp.ts +27 -0
  463. package/src/ReadWriteVolume.ts +45 -0
  464. package/src/ReadWriteVolumeHttp.ts +28 -0
  465. package/src/RuntimeOwner.ts +111 -0
  466. package/src/Sandbox.ts +402 -0
  467. package/src/SandboxClient.ts +1404 -0
  468. package/src/ScaleFunction.ts +70 -0
  469. package/src/ScaleFunctionHttp.ts +54 -0
  470. package/src/Secret.ts +296 -0
  471. package/src/Server.ts +285 -0
  472. package/src/ServiceUser.ts +295 -0
  473. package/src/Volume.ts +320 -0
  474. package/src/VolumeClient.ts +108 -0
  475. package/src/VolumeFiles.ts +194 -0
  476. package/src/WebhookToken.ts +230 -0
  477. package/src/WorkspaceSettings.ts +160 -0
  478. package/src/WriteApp.ts +43 -0
  479. package/src/WriteAppHttp.ts +51 -0
  480. package/src/WriteDict.ts +44 -0
  481. package/src/WriteDictHttp.ts +27 -0
  482. package/src/WriteQueue.ts +44 -0
  483. package/src/WriteQueueHttp.ts +27 -0
  484. package/src/WriteSecret.ts +60 -0
  485. package/src/WriteSecretHttp.ts +56 -0
  486. package/src/WriteVolume.ts +44 -0
  487. package/src/WriteVolumeHttp.ts +28 -0
  488. package/src/globals.d.ts +2 -0
  489. package/src/index.ts +85 -0
  490. package/src/internal/Declared.ts +80 -0
  491. package/src/internal/Deploy.ts +309 -0
  492. package/src/internal/Entrypoint.ts +198 -0
  493. package/src/internal/Rpc.ts +59 -0
  494. package/src/internal/RpcAuth.ts +132 -0
  495. package/src/internal/Runtime.ts +386 -0
  496. package/src/internal/Tags.ts +44 -0
  497. package/src/internal/TcpConnect.ts +78 -0
  498. package/src/internal/Transport.ts +25 -0
  499. package/src/internal.ts +147 -0
@@ -0,0 +1,373 @@
1
+ import * as environment from "@distilled.cloud/modal/environment";
2
+ import { Unowned } from "alchemy/AdoptPolicy";
3
+ import * as Provider from "alchemy/Provider";
4
+ import { Resource } from "alchemy/Resource";
5
+ import * as Data from "effect/Data";
6
+ import * as Effect from "effect/Effect";
7
+ import { isGeneratedName, objectName } from "./internal.ts";
8
+ import { declarable } from "./internal/Declared.ts";
9
+ import type { Providers } from "./Providers.ts";
10
+
11
+ export class EnvironmentUnexpectedResponse extends Data.TaggedError(
12
+ "Modal.EnvironmentUnexpectedResponse",
13
+ )<{
14
+ readonly message: string;
15
+ }> {}
16
+
17
+ /** A member's access to an environment. */
18
+ export type EnvironmentRole = "viewer" | "contributor" | "no-access";
19
+
20
+ const ROLE_TO_WIRE = {
21
+ viewer: "ENVIRONMENT_ROLE_VIEWER",
22
+ contributor: "ENVIRONMENT_ROLE_CONTRIBUTOR",
23
+ "no-access": "ENVIRONMENT_ROLE_NO_ACCESS",
24
+ } as const satisfies Record<EnvironmentRole, environment.EnvironmentRole>;
25
+
26
+ const roleFromWire = (role: string | undefined): EnvironmentRole | undefined =>
27
+ (Object.keys(ROLE_TO_WIRE) as EnvironmentRole[]).find((key) => ROLE_TO_WIRE[key] === role);
28
+
29
+ /** One role assignment: a workspace member or service user, and its role. */
30
+ export type EnvironmentRoleAssignment =
31
+ | { readonly userId: string; readonly role: EnvironmentRole }
32
+ | { readonly serviceUserId: string; readonly role: EnvironmentRole };
33
+
34
+ export interface EnvironmentProps {
35
+ /**
36
+ * Environment name, unique in the workspace. If omitted, a unique name is
37
+ * generated from the stack, stage and logical ID. Changing it renames the
38
+ * environment in place.
39
+ */
40
+ name?: string;
41
+ /**
42
+ * Suffix of web endpoint URLs in this environment
43
+ * (`<workspace>-<suffix>--<app>.modal.run`).
44
+ * @default the environment name
45
+ */
46
+ webhookSuffix?: string;
47
+ /** Most tasks (containers) running at once in this environment. */
48
+ maxConcurrentTasks?: number;
49
+ /** Most GPUs in use at once in this environment. */
50
+ maxConcurrentGpus?: number;
51
+ /**
52
+ * Monthly spend limit in US dollars for this environment. Removing it
53
+ * clears the limit. Budgets need a Modal plan that includes them;
54
+ * elsewhere the deploy fails with `EnvironmentBudgetsNotEnabled`.
55
+ */
56
+ budget?: number;
57
+ /**
58
+ * Require authentication for web endpoints and tunnels in this
59
+ * environment: `true` blocks unauthenticated traffic, `false` allows it,
60
+ * and `undefined` inherits the workspace default.
61
+ */
62
+ blockUnauthenticatedResources?: boolean;
63
+ /**
64
+ * Restrict the environment to explicit members (a managed environment).
65
+ * Members without an assignment in {@link roles} get
66
+ * {@link defaultMemberRole}.
67
+ * @default false
68
+ */
69
+ managed?: boolean;
70
+ /**
71
+ * Role every workspace member gets in a managed environment unless
72
+ * {@link roles} assigns one.
73
+ */
74
+ defaultMemberRole?: EnvironmentRole;
75
+ /**
76
+ * Explicit role assignments. Each listed principal gets its role; a
77
+ * principal that was assigned before and is no longer listed falls back
78
+ * to {@link defaultMemberRole}.
79
+ */
80
+ roles?: EnvironmentRoleAssignment[];
81
+ }
82
+
83
+ export interface EnvironmentAttributes {
84
+ /** Environment ID (`en-…`). */
85
+ environmentId: string;
86
+ /** Environment name. */
87
+ name: string;
88
+ /** Suffix of web endpoint URLs in this environment. */
89
+ webhookSuffix: string | undefined;
90
+ /** Whether this is the workspace's default environment. */
91
+ isDefault: boolean;
92
+ /** Whether membership is restricted (a managed environment). */
93
+ managed: boolean;
94
+ }
95
+
96
+ /**
97
+ * A Modal Environment: an isolated namespace inside a workspace for Apps,
98
+ * Volumes, Dicts, Queues, Secrets and Sandboxes, with its own concurrency
99
+ * limits, spend budget and member roles. Objects with the same name in two
100
+ * environments are different objects, so one environment per stage keeps
101
+ * stages apart.
102
+ *
103
+ * Modal environments have no tags. Ownership is inferred from Alchemy
104
+ * state: an environment found under an explicit `name` without prior state
105
+ * is reported as unowned.
106
+ *
107
+ * ### Creating an Environment
108
+ * **Example:** One environment per stage
109
+ * ```typescript
110
+ * import * as Modal from "@alchemy.run/modal";
111
+ *
112
+ * export const Agents = Modal.Environment("Agents", {});
113
+ * ```
114
+ *
115
+ * **Example:** Limits and a monthly budget
116
+ * ```typescript
117
+ * import * as Modal from "@alchemy.run/modal";
118
+ *
119
+ * export const Agents = Modal.Environment("Agents", {
120
+ * maxConcurrentTasks: 50,
121
+ * maxConcurrentGpus: 4,
122
+ * budget: 200,
123
+ * });
124
+ * ```
125
+ *
126
+ * ### Access control
127
+ * **Example:** A managed environment with explicit roles
128
+ * ```typescript
129
+ * import * as Modal from "@alchemy.run/modal";
130
+ *
131
+ * export const Production = Modal.Environment("Production", {
132
+ * name: "production",
133
+ * managed: true,
134
+ * defaultMemberRole: "viewer",
135
+ * roles: [{ userId: "us-1234", role: "contributor" }],
136
+ * blockUnauthenticatedResources: true,
137
+ * });
138
+ * ```
139
+ *
140
+ * ### Using the environment
141
+ * **Example:** Put objects in it
142
+ * ```typescript
143
+ * import * as Modal from "@alchemy.run/modal";
144
+ *
145
+ * export const Agents = Modal.Environment("Agents", {});
146
+ * export const Coder = Modal.App("Coder", { environment: Agents });
147
+ * export const Workspace = Modal.Volume("Workspace", { environment: Agents });
148
+ * ```
149
+ *
150
+ * ### Looking up an existing environment
151
+ * `Environment.lookup` references an environment Alchemy doesn't manage (created with
152
+ * the Modal CLI or by another stack). It is read during plan/deploy, never
153
+ * created, updated or deleted.
154
+ *
155
+ * **Example:** Reference an existing environment
156
+ * ```typescript
157
+ * const staging = Modal.Environment.lookup({ name: "staging" });
158
+ * ```
159
+ *
160
+ * @resource
161
+ * @product Environment
162
+ */
163
+ export const Environment = declarable<Environment>()(Resource<Environment>("Modal.Environment"));
164
+
165
+ export type Environment = Resource<
166
+ "Modal.Environment",
167
+ EnvironmentProps,
168
+ EnvironmentAttributes,
169
+ never,
170
+ Providers,
171
+ EnvironmentLookup
172
+ >;
173
+
174
+ /**
175
+ * Props for {@link Environment.lookup}: find an environment this
176
+ * stack doesn't manage by its name.
177
+ */
178
+ export interface EnvironmentLookup {
179
+ /** Environment name. */
180
+ name: string;
181
+ }
182
+
183
+ const blockToWire = (
184
+ value: boolean | undefined,
185
+ ): environment.EnvironmentBlockUnauthenticatedResources =>
186
+ value === undefined
187
+ ? "ENVIRONMENT_BLOCK_UNAUTHENTICATED_RESOURCES_INHERIT"
188
+ : value
189
+ ? "ENVIRONMENT_BLOCK_UNAUTHENTICATED_RESOURCES_BLOCK"
190
+ : "ENVIRONMENT_BLOCK_UNAUTHENTICATED_RESOURCES_ALLOW";
191
+
192
+ const principalKey = (p: { userId?: string; serviceUserId?: string }) =>
193
+ p.userId ? `user:${p.userId}` : `service:${p.serviceUserId ?? ""}`;
194
+
195
+ export const EnvironmentProvider = () =>
196
+ Provider.effect(
197
+ Environment,
198
+ Effect.gen(function* () {
199
+ const observe = Effect.fn(function* (name: string) {
200
+ const { items } = yield* environment.listEnvironment({});
201
+ return (items ?? []).find((item) => item.name === name);
202
+ });
203
+
204
+ const toAttrs = (item: environment.EnvironmentListItem): EnvironmentAttributes => ({
205
+ environmentId: item.environmentId ?? "",
206
+ name: item.name ?? "",
207
+ webhookSuffix: item.webhookSuffix || undefined,
208
+ isDefault: item.default ?? false,
209
+ managed: item.isManaged ?? false,
210
+ });
211
+
212
+ return {
213
+ stables: ["environmentId"],
214
+ lookup: Effect.fn(function* ({ name }) {
215
+ const item = yield* observe(name);
216
+ return item ? toAttrs(item) : undefined;
217
+ }),
218
+
219
+ read: Effect.fn(function* ({ id, olds, output }) {
220
+ const name = output?.name ?? (yield* objectName(id, olds?.name));
221
+ const item = yield* observe(name);
222
+ if (!item) return undefined;
223
+ const attrs = toAttrs(item);
224
+ return output !== undefined || olds?.name === undefined ? attrs : Unowned(attrs);
225
+ }),
226
+ reconcile: Effect.fn(function* ({ id, news, output, session }) {
227
+ const desiredName = yield* objectName(id, news.name);
228
+
229
+ // Observe: by the previous name (a rename) and the desired name.
230
+ let current =
231
+ (output !== undefined && output.name !== desiredName
232
+ ? yield* observe(output.name)
233
+ : undefined) ?? (yield* observe(desiredName));
234
+
235
+ // Ensure
236
+ if (!current) {
237
+ yield* session.note(`Creating environment ${desiredName}...`);
238
+ yield* environment
239
+ .createEnvironment({
240
+ name: desiredName,
241
+ isManaged: news.managed,
242
+ defaultMemberRole: news.defaultMemberRole
243
+ ? ROLE_TO_WIRE[news.defaultMemberRole]
244
+ : undefined,
245
+ })
246
+ .pipe(Effect.catchTag("EnvironmentAlreadyExists", () => Effect.void));
247
+ current = yield* observe(desiredName);
248
+ if (!current) {
249
+ return yield* new EnvironmentUnexpectedResponse({
250
+ message: `Modal environment ${desiredName} was not listed after create`,
251
+ });
252
+ }
253
+ }
254
+
255
+ // Sync name, suffix, limits and the unauthenticated-resources policy.
256
+ const desiredBlock = blockToWire(news.blockUnauthenticatedResources);
257
+ const observedBlock = blockToWire(current.blockUnauthenticatedResources);
258
+ if (
259
+ current.name !== desiredName ||
260
+ (news.webhookSuffix !== undefined && current.webhookSuffix !== news.webhookSuffix) ||
261
+ (news.maxConcurrentTasks !== undefined &&
262
+ current.maxConcurrentTasks !== news.maxConcurrentTasks) ||
263
+ (news.maxConcurrentGpus !== undefined &&
264
+ current.maxConcurrentGpus !== news.maxConcurrentGpus) ||
265
+ (news.blockUnauthenticatedResources !== undefined && desiredBlock !== observedBlock)
266
+ ) {
267
+ yield* environment.updateEnvironment({
268
+ currentName: current.name,
269
+ name: desiredName,
270
+ webSuffix: news.webhookSuffix,
271
+ maxConcurrentTasks: news.maxConcurrentTasks,
272
+ maxConcurrentGpus: news.maxConcurrentGpus,
273
+ blockUnauthenticatedResources:
274
+ news.blockUnauthenticatedResources === undefined ? undefined : desiredBlock,
275
+ });
276
+ }
277
+ const environmentId = current.environmentId ?? "";
278
+
279
+ // Sync budget against the observed limit. A workspace without
280
+ // budgets has none to clear; asking for one there fails with
281
+ // `EnvironmentBudgetsNotEnabled`.
282
+ const budget = yield* environment
283
+ .environmentGetBudget({ environmentId })
284
+ .pipe(
285
+ Effect.catchTag("EnvironmentBudgetsNotEnabled", () =>
286
+ Effect.succeed<Partial<environment.EnvironmentGetBudgetResponse>>({}),
287
+ ),
288
+ );
289
+ if (news.budget !== undefined && budget.cycleBudgetDollars !== news.budget) {
290
+ yield* environment.environmentSetBudget({
291
+ environmentId,
292
+ cycleBudgetDollars: news.budget,
293
+ });
294
+ } else if (news.budget === undefined && budget.cycleBudgetDollars !== undefined) {
295
+ yield* environment.environmentSetBudget({ environmentId, clearBudget: true });
296
+ }
297
+
298
+ // Sync managed mode and the default member role.
299
+ const managed = news.managed ?? false;
300
+ if ((current.isManaged ?? false) !== managed) {
301
+ yield* environment.environmentSetManaged({
302
+ environmentId,
303
+ managed,
304
+ defaultMemberRole: news.defaultMemberRole
305
+ ? ROLE_TO_WIRE[news.defaultMemberRole]
306
+ : undefined,
307
+ });
308
+ }
309
+ if (
310
+ news.defaultMemberRole !== undefined &&
311
+ roleFromWire(current.defaultMemberRole) !== news.defaultMemberRole
312
+ ) {
313
+ yield* environment.environmentSetDefaultMemberRole({
314
+ environmentId,
315
+ defaultMemberRole: ROLE_TO_WIRE[news.defaultMemberRole],
316
+ });
317
+ }
318
+
319
+ // Sync explicit role assignments against the observed principals:
320
+ // listed principals get their role, and any other principal with
321
+ // an explicit assignment falls back to the default member role.
322
+ if (news.roles !== undefined) {
323
+ const observed = yield* environment.environmentGetRoles({ environmentId });
324
+ const principals = observed.principalRoles ?? [];
325
+ const desired = new Map(
326
+ news.roles.map((assignment) => [principalKey(assignment), assignment]),
327
+ );
328
+ for (const assignment of desired.values()) {
329
+ const match = principals.find((p) => principalKey(p) === principalKey(assignment));
330
+ if (
331
+ match === undefined ||
332
+ match.hasRoleAssignment !== true ||
333
+ roleFromWire(match.role) !== assignment.role
334
+ ) {
335
+ yield* environment.setEnvironmentRole({
336
+ environmentId,
337
+ ...("userId" in assignment
338
+ ? { userId: assignment.userId }
339
+ : { serviceUserId: assignment.serviceUserId }),
340
+ role: ROLE_TO_WIRE[assignment.role],
341
+ });
342
+ }
343
+ }
344
+ for (const principal of principals) {
345
+ if (principal.hasRoleAssignment !== true || desired.has(principalKey(principal))) {
346
+ continue;
347
+ }
348
+ yield* environment.setEnvironmentRole({
349
+ environmentId,
350
+ userId: principal.userId || undefined,
351
+ serviceUserId: principal.serviceUserId || undefined,
352
+ role: "ENVIRONMENT_ROLE_UNSPECIFIED",
353
+ });
354
+ }
355
+ }
356
+
357
+ const final = yield* observe(desiredName);
358
+ return toAttrs(final ?? current);
359
+ }),
360
+ delete: Effect.fn(function* ({ output }) {
361
+ yield* environment
362
+ .deleteEnvironment({ name: output.name })
363
+ .pipe(Effect.catchTag("EnvironmentNotFound", () => Effect.void));
364
+ }),
365
+ list: Effect.fn(function* () {
366
+ const { items } = yield* environment.listEnvironment({});
367
+ return (items ?? [])
368
+ .filter((item) => !item.default && isGeneratedName(item.name))
369
+ .map(toAttrs);
370
+ }),
371
+ };
372
+ }),
373
+ );
@@ -0,0 +1,126 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type { Input } from "alchemy/Input";
3
+ import type { Rpc } from "alchemy/Rpc";
4
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
5
+ import type * as Effect from "effect/Effect";
6
+ import type * as HttpClientError from "effect/http/HttpClientError";
7
+ import type * as HttpClientRequest from "effect/http/HttpClientRequest";
8
+ import type * as HttpClientResponse from "effect/http/HttpClientResponse";
9
+ import type { Endpoint } from "./Endpoint.ts";
10
+ import type { ServerUrlMissing } from "./FetchServerHttp.ts";
11
+ import type { Function } from "./Function.ts";
12
+ import type { Server } from "./Server.ts";
13
+
14
+ /** Send requests to a deployed Modal Server, web Function or model Endpoint. */
15
+ export interface ServerClient {
16
+ /** The server's URL. */
17
+ readonly url: Effect.Effect<string, ServerUrlMissing, RuntimeContext>;
18
+ /**
19
+ * Send a request: its path and query are kept, the host is the server's,
20
+ * and Modal's proxy auth headers are added.
21
+ */
22
+ fetch(
23
+ request: HttpClientRequest.HttpClientRequest,
24
+ ): Effect.Effect<
25
+ HttpClientResponse.HttpClientResponse,
26
+ ServerUrlMissing | HttpClientError.HttpClientError,
27
+ RuntimeContext
28
+ >;
29
+ }
30
+
31
+ /**
32
+ * The client {@link FetchServer} returns: `url` and `fetch`, plus the RPC
33
+ * methods of a `Modal.Server` program (everything it returns besides
34
+ * `fetch` and `run`).
35
+ */
36
+ export type FetchClient<Shape> = ServerClient & Omit<Shape, "fetch" | "run" | "url">;
37
+
38
+ /**
39
+ * Call a `Modal.Server`, a `Modal.Function` with `web`, or a model
40
+ * `Modal.Endpoint` from any runtime. Servers and endpoints require Modal's
41
+ * proxy auth by default: the binding creates a `Modal.WebhookToken` for the
42
+ * host and sends its `Modal-Key` / `Modal-Secret` headers with every request.
43
+ *
44
+ * A `Modal.Server` program's RPC methods come back on the client too. Each
45
+ * call is a `POST /__rpc__/<method>` to the Server through Modal's proxy,
46
+ * with the arguments and result as JSON; a method that returns a `Stream`
47
+ * streams. The binding gives the host its own key for the Server, which
48
+ * every method call carries: the Server answers methods only for callers
49
+ * bound to it. It serves them only behind proxy auth, so an
50
+ * `unauthenticated` Server answers them with `404`.
51
+ *
52
+ * ### Call a Server
53
+ * **Example:** From a Cloudflare Worker
54
+ * ```typescript
55
+ * import * as Cloudflare from "@alchemy.run/cloudflare";
56
+ * import * as Modal from "@alchemy.run/modal";
57
+ * import * as Effect from "effect/Effect";
58
+ * import * as HttpClientRequest from "effect/http/HttpClientRequest";
59
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
60
+ * import Api from "./Api.ts";
61
+ *
62
+ * export default class Gateway extends Cloudflare.Worker<Gateway>()(
63
+ * "Gateway",
64
+ * { main: import.meta.url },
65
+ * Effect.gen(function* () {
66
+ * const api = yield* Modal.FetchServer(Api);
67
+ * return {
68
+ * fetch: Effect.gen(function* () {
69
+ * const response = yield* api.fetch(HttpClientRequest.get("/health"));
70
+ * return HttpServerResponse.text(yield* response.text, { status: response.status });
71
+ * }).pipe(Effect.orDie),
72
+ * };
73
+ * }).pipe(Effect.provide(Modal.FetchServerHttp)),
74
+ * ) {}
75
+ * ```
76
+ *
77
+ * ### Call a Server's methods
78
+ * **Example:** RPC methods next to `fetch`
79
+ * ```typescript
80
+ * // src/Api.ts
81
+ * export default class Api extends Modal.Server<Api>()(
82
+ * "Api",
83
+ * { main: import.meta.url, app: Backend },
84
+ * Effect.gen(function* () {
85
+ * return {
86
+ * greet: Effect.fn(function* (name: string) {
87
+ * return `hello ${name}`;
88
+ * }),
89
+ * fetch: Effect.succeed(HttpServerResponse.text("ok")),
90
+ * };
91
+ * }),
92
+ * ) {}
93
+ * ```
94
+ *
95
+ * **Example:** Call them from a Cloudflare Worker
96
+ * ```typescript
97
+ * const api = yield* Modal.FetchServer(Api);
98
+ * const greeting = yield* api.greet("modal");
99
+ * ```
100
+ *
101
+ * @binding
102
+ * @product Server
103
+ */
104
+ export interface FetchServer extends Binding.Service<
105
+ FetchServer,
106
+ "Modal.FetchServer",
107
+ (server: Server | Function | Endpoint) => Effect.Effect<ServerClient>
108
+ > {}
109
+
110
+ /** FetchServer's call signatures, typed from the target's program. */
111
+ export interface FetchServerCall {
112
+ /** A `Modal.Server` of the Stack: `url`, `fetch` and its program's RPC methods. */
113
+ <Shape, Req = never>(
114
+ server: (Server & Rpc<Shape>) | Effect.Effect<Server & Rpc<Shape>, never, Req>,
115
+ ): Effect.Effect<FetchClient<Shape>, never, FetchServer | Req>;
116
+ /** A web Function, a model Endpoint, or an async Server: `url` and `fetch`. */
117
+ <Req = never>(
118
+ server:
119
+ | Input<Server | Function | Endpoint>
120
+ | Effect.Effect<Server | Function | Endpoint, never, Req>,
121
+ ): Effect.Effect<ServerClient, never, FetchServer | Req>;
122
+ }
123
+
124
+ export const FetchServer = Binding.Service<FetchServer>(
125
+ "Modal.FetchServer",
126
+ ) as unknown as FetchServerCall & FetchServer;
@@ -0,0 +1,110 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import { makeFetchRpcStub } from "alchemy/Rpc";
3
+ import { CurrentRuntimeContext } from "alchemy/RuntimeContext";
4
+ import * as Data from "effect/Data";
5
+ import * as Effect from "effect/Effect";
6
+ import * as HttpClient from "effect/http/HttpClient";
7
+ import * as HttpClientRequest from "effect/http/HttpClientRequest";
8
+ import * as Layer from "effect/Layer";
9
+ import * as Redacted from "effect/Redacted";
10
+ import type { Endpoint } from "./Endpoint.ts";
11
+ import { FetchServer, type ServerClient } from "./FetchServer.ts";
12
+ import type { Function } from "./Function.ts";
13
+ import { RPC_KEY_HEADER, RpcCaller } from "./internal/RpcAuth.ts";
14
+ import * as ModalBindings from "./ModalBindings.ts";
15
+ import type { Server } from "./Server.ts";
16
+ import { WebhookToken } from "./WebhookToken.ts";
17
+
18
+ /** The server has no URL (a Function without `web`, or a deploy still in progress). */
19
+ export class ServerUrlMissing extends Data.TaggedError("Modal.ServerUrlMissing")<{
20
+ readonly message: string;
21
+ }> {}
22
+
23
+ /** Env the host's proxy auth token is bound under. */
24
+ const PROXY_ENV = { key: "MODAL_PROXY_KEY", secret: "MODAL_PROXY_SECRET" } as const;
25
+
26
+ /**
27
+ * {@link FetchServer} over HTTP. Creates one `Modal.WebhookToken` per host
28
+ * (`<host>ProxyAuth`) and binds its header pair into the host's env.
29
+ *
30
+ * @layer
31
+ * @product Server
32
+ * @provides Modal.FetchServer
33
+ */
34
+ export const FetchServerHttp = Layer.effect(
35
+ FetchServer,
36
+ Effect.gen(function* () {
37
+ // No Modal API calls: the client only needs the host's HTTP client.
38
+ const http = yield* ModalBindings.withCredentials(HttpClient.HttpClient);
39
+ const bind = yield* ModalBindings.Bind;
40
+ const runtime = yield* CurrentRuntimeContext;
41
+ // Deploy only: a host bundle never creates the token.
42
+ const Token = globalThis.__ALCHEMY_RUNTIME__ ? undefined : yield* WebhookToken;
43
+ const caller = yield* RpcCaller;
44
+
45
+ return Effect.fn("Modal.FetchServer")(function* (server: Server | Function | Endpoint) {
46
+ if (!globalThis.__ALCHEMY_RUNTIME__) {
47
+ const host = yield* Binding.Host;
48
+ if (host !== undefined && Token !== undefined) {
49
+ const token = yield* Token(`${host.LogicalId}ProxyAuth`, {});
50
+ yield* bind`Modal.FetchServer(${server})`({
51
+ env: { [PROXY_ENV.key]: token.tokenId, [PROXY_ENV.secret]: token.tokenSecret },
52
+ });
53
+ }
54
+ }
55
+ // This host's key for the Server's RPC methods (minted at deploy).
56
+ const key = yield* caller(server);
57
+ const url = yield* server.url;
58
+ const resolvedUrl = Effect.flatMap(url, (value) =>
59
+ value
60
+ ? Effect.succeed(value)
61
+ : Effect.fail(
62
+ new ServerUrlMissing({
63
+ message:
64
+ "The server has no URL: deploy it as a Modal.Server, a Modal.Function with web, or a Modal.Endpoint",
65
+ }),
66
+ ),
67
+ );
68
+ const headers = Effect.gen(function* () {
69
+ if (runtime === undefined) return {};
70
+ const key = yield* runtime.get<string>(PROXY_ENV.key);
71
+ const secret = yield* runtime.get<string | Redacted.Redacted<string>>(PROXY_ENV.secret);
72
+ if (key === undefined || secret === undefined) return {};
73
+ return {
74
+ "Modal-Key": key,
75
+ "Modal-Secret": Redacted.isRedacted(secret) ? Redacted.value(secret) : secret,
76
+ };
77
+ });
78
+ const client = {
79
+ url: resolvedUrl,
80
+ fetch: (request) =>
81
+ Effect.gen(function* () {
82
+ const base = yield* resolvedUrl;
83
+ const target = new URL(request.url, "http://server");
84
+ // The Stack's own deployed server (allowed raw HTTP).
85
+ return yield* http.execute(
86
+ request.pipe(
87
+ HttpClientRequest.setUrl(
88
+ `${base.replace(/\/$/, "")}${target.pathname}${target.search}`,
89
+ ),
90
+ HttpClientRequest.setHeaders(yield* headers),
91
+ ),
92
+ );
93
+ }),
94
+ } satisfies ServerClient;
95
+ // Every other member is an RPC method of the Server's program.
96
+ return makeFetchRpcStub<ServerClient>({
97
+ // RPC calls carry the key; the Server serves only callers it issued keys to.
98
+ fetch: (request) =>
99
+ Effect.flatMap(key, (value) =>
100
+ client.fetch(
101
+ value === undefined
102
+ ? request
103
+ : request.pipe(HttpClientRequest.setHeader(RPC_KEY_HEADER, value)),
104
+ ),
105
+ ),
106
+ base: client,
107
+ });
108
+ });
109
+ }),
110
+ );