@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,310 @@
1
+ import { GrpcTransport } from "@distilled.cloud/core/grpc-transport";
2
+ import { withAuthToken } from "@distilled.cloud/modal/AuthToken";
3
+ import {
4
+ containerSocket,
5
+ Credentials,
6
+ CredentialsFromEnv,
7
+ credentials,
8
+ fromContainer,
9
+ streamTaskCommandRouter,
10
+ withTaskCommandRouter,
11
+ } from "@distilled.cloud/modal/Credentials";
12
+ import { orDieCredentialsUnavailable } from "alchemy/Auth/Resolve";
13
+ import * as Binding from "alchemy/Binding";
14
+ import type { Input } from "alchemy/Input";
15
+ import * as Output from "alchemy/Output";
16
+ import { CurrentRuntimeContext } from "alchemy/RuntimeContext";
17
+ import * as Context from "effect/Context";
18
+ import * as Effect from "effect/Effect";
19
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
20
+ import * as HttpClient from "effect/http/HttpClient";
21
+ import * as Layer from "effect/Layer";
22
+ import * as Option from "effect/Option";
23
+ import * as Redacted from "effect/Redacted";
24
+ import type * as Stream from "effect/Stream";
25
+ import { withAuthTokens } from "./Credentials.ts";
26
+ import type { OperationServices } from "./internal.ts";
27
+ import { ModalTransport } from "./internal/Transport.ts";
28
+ import { ServiceUser } from "./ServiceUser.ts";
29
+
30
+ /**
31
+ * How a Modal binding reaches Modal from its host.
32
+ *
33
+ * Modal grants access per environment, as a `viewer` or a `contributor`. So:
34
+ *
35
+ * - a Modal Function or Server: nothing is bound. It calls Modal as its own
36
+ * container, over the API socket Modal gives every container
37
+ * (`fromContainer`), the way Modal's Python client does there. No
38
+ * credential is stored. A host with `restrictModalAccess` has no such
39
+ * access, so it gets a service user like any other host;
40
+ * - any other host (a Cloudflare Worker, a Lambda, a Modal Sandbox):
41
+ * {@link Bind} creates a scoped `Modal.ServiceUser` for the
42
+ * host (`<host>ModalIdentity`), grants it the role each binding asks for
43
+ * on the bound resource's environment, and binds its token pair into the
44
+ * host's env (`MODAL_TOKEN_ID`, and `MODAL_TOKEN_SECRET` kept `Redacted`);
45
+ * - no host (a script or a deploy-time Action): nothing is bound, and calls
46
+ * use the deployer's credentials.
47
+ *
48
+ * Modal's Starter plan has no service users. There, provide
49
+ * {@link DeployerHostIdentity} to bind the deployer's own token pair into
50
+ * each host instead: hosts then act with the deployer's workspace-wide
51
+ * access, not the roles their bindings ask for.
52
+ *
53
+ * Import it as a namespace. A binding resolves its operations with
54
+ * {@link withCredentials} and gets its `bind` from {@link Bind} when its layer
55
+ * is built, then binds behind its own `__ALCHEMY_RUNTIME__` guard:
56
+ *
57
+ * ```ts
58
+ * Effect.gen(function* () {
59
+ * const put = yield* ModalBindings.withCredentials(modalQueue.putQueue);
60
+ * const bind = yield* ModalBindings.Bind;
61
+ * return Effect.fn(function* (queue: Queue) {
62
+ * if (!globalThis.__ALCHEMY_RUNTIME__) {
63
+ * yield* bind`Modal.WriteQueue(${queue})`({
64
+ * roles: [{ environment: queue.environment, role: "contributor" }],
65
+ * });
66
+ * }
67
+ * const queueId = yield* queue.queueId;
68
+ * return (value) => put({ queueId: yield* queueId, values: [...] });
69
+ * });
70
+ * })
71
+ * ```
72
+ */
73
+ export const TOKEN_ENV = {
74
+ id: "MODAL_TOKEN_ID",
75
+ secret: "MODAL_TOKEN_SECRET",
76
+ // Not MODAL_SERVER_URL: inside a Modal container, Modal sets that to the
77
+ // container's own socket (`unix:/run/modal.sock`), shadowing ours.
78
+ serverUrl: "ALCHEMY_MODAL_SERVER_URL",
79
+ } as const;
80
+
81
+ /**
82
+ * The identity {@link Bind} gives a binding's host:
83
+ *
84
+ * - `"service-user"`: a scoped `Modal.ServiceUser` per host with only the
85
+ * roles its bindings ask for (needs Modal's Team or Enterprise plan);
86
+ * - `"deployer"`: the deployer's own token pair, with its workspace-wide
87
+ * access (for the Starter plan, which has no service users).
88
+ *
89
+ * Set it with {@link DeployerHostIdentity}.
90
+ */
91
+ export const HostIdentity = Context.Reference<"service-user" | "deployer">("Modal/HostIdentity", {
92
+ defaultValue: () => "service-user",
93
+ });
94
+
95
+ /**
96
+ * Bind the deployer's own Modal token into binding hosts instead of a
97
+ * scoped service user per host. Use it on Modal's Starter plan, which has
98
+ * no service users; hosts then have the deployer's workspace-wide access.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * export default Alchemy.Stack(
103
+ * "App",
104
+ * { providers: Layer.mergeAll(Cloudflare.providers(), Modal.providers(), Modal.DeployerHostIdentity) },
105
+ * Effect.gen(function* () { ... }),
106
+ * );
107
+ * ```
108
+ */
109
+ export const DeployerHostIdentity: Layer.Layer<never> = Layer.succeed(HostIdentity, "deployer");
110
+
111
+ /** A role a binding needs in one environment. */
112
+ export interface EnvironmentGrant {
113
+ /** The environment's name; `undefined` is the workspace default. */
114
+ readonly environment: Input<string | undefined>;
115
+ readonly role: "viewer" | "contributor";
116
+ }
117
+
118
+ /** What a Modal binding attaches to its host. */
119
+ export interface HostBinding {
120
+ /** Environment roles the host's identity needs. */
121
+ readonly roles?: ReadonlyArray<EnvironmentGrant>;
122
+ /** Env vars the binding reads at runtime. */
123
+ readonly env?: Record<string, unknown>;
124
+ }
125
+
126
+ /** The signature {@link Bind} yields. */
127
+ export type BindHost = (
128
+ label: TemplateStringsArray,
129
+ ...args: unknown[]
130
+ ) => (data?: HostBinding) => Effect.Effect<void>;
131
+
132
+ type BindTarget = {
133
+ bind: (...args: unknown[]) => (data: unknown) => Effect.Effect<void>;
134
+ };
135
+
136
+ const labelled = (verb: string, label: TemplateStringsArray): TemplateStringsArray => {
137
+ const strings = [`${verb}(`, `, ${label[0]}`, ...label.slice(1)];
138
+ strings[strings.length - 1] += ")";
139
+ return Object.assign(strings, { raw: strings }) as unknown as TemplateStringsArray;
140
+ };
141
+
142
+ /**
143
+ * The `bind` for a binding's layer: yield it while the layer is built, then
144
+ * call it from the returned function behind a literal
145
+ * `if (!globalThis.__ALCHEMY_RUNTIME__)` so the bundler drops it. On a host it
146
+ * grants `data.roles` to the host's service user and binds that user's token
147
+ * pair (and `data.env`) into the host's env; with no host it does nothing.
148
+ */
149
+ export const Bind: Effect.Effect<BindHost> = Effect.gen(function* () {
150
+ // Bindings only bind at deploy, so a host bundle captures nothing here
151
+ // and drops the identity resource.
152
+ if (globalThis.__ALCHEMY_RUNTIME__) return () => () => Effect.void;
153
+ const Identity = yield* ServiceUser;
154
+ const identity = yield* HostIdentity;
155
+ const ambient = yield* Effect.serviceOption(Credentials);
156
+ return (label: TemplateStringsArray, ...args: unknown[]) =>
157
+ Effect.fn(function* (data: HostBinding = {}) {
158
+ const host = yield* Binding.Host;
159
+ if (host === undefined) return;
160
+ const runtime = yield* CurrentRuntimeContext;
161
+ if (runtime === undefined) return;
162
+
163
+ // A binding that calls no Modal API (only `env`) needs no identity, and
164
+ // a Modal Function or Server calls as its own container.
165
+ if (data.roles !== undefined && data.roles.length > 0 && !callsAsContainer(host)) {
166
+ // The host talks to the deployer's Modal control plane.
167
+ const resolve = Option.isSome(ambient)
168
+ ? ambient.value
169
+ : yield* Credentials.pipe(Effect.provide(CredentialsFromEnv));
170
+ // Binding initialization can't fail; the engine reports this defect as
171
+ // `CredentialsRequired`.
172
+ const creds = yield* resolve.pipe(orDieCredentialsUnavailable("Modal"));
173
+ if (identity === "deployer") {
174
+ yield* runtime.set(TOKEN_ENV.id, creds.tokenId.pipe(Redacted.value, Output.literal));
175
+ yield* runtime.set(TOKEN_ENV.secret, Output.literal(creds.tokenSecret));
176
+ } else {
177
+ const user = yield* Identity(`${host.LogicalId}ModalIdentity`, { scoped: true });
178
+ yield* (user as unknown as BindTarget).bind(
179
+ labelled("Allow", label),
180
+ host,
181
+ ...args,
182
+ )({ environments: data.roles });
183
+ yield* runtime.set(TOKEN_ENV.id, user.tokenId);
184
+ yield* runtime.set(TOKEN_ENV.secret, user.tokenSecret);
185
+ }
186
+ yield* runtime.set(TOKEN_ENV.serverUrl, Output.literal(creds.apiBaseUrl));
187
+ }
188
+ for (const [name, value] of Object.entries(data.env ?? {})) {
189
+ yield* runtime.set(name, Output.isOutput(value) ? value : Output.literal(value));
190
+ }
191
+ });
192
+ });
193
+
194
+ /** Host types whose containers call Modal over their own API socket. */
195
+ const CONTAINER_HOSTS = new Set(["Modal.Function", "Modal.Server"]);
196
+
197
+ /** Whether `host` calls Modal as its container instead of with a bound token. */
198
+ const callsAsContainer = (host: { readonly Type?: string; readonly Props?: unknown }) =>
199
+ CONTAINER_HOSTS.has(host.Type ?? "") &&
200
+ !(host.Props as { readonly restrictModalAccess?: boolean } | undefined)?.restrictModalAccess;
201
+
202
+ /**
203
+ * The credentials, HTTP client and gRPC transport distilled operations run
204
+ * with on this host. A resolved operation keeps them as a fallback under its
205
+ * caller's context, so a Worker's own `HttpClient` doesn't displace the
206
+ * transport.
207
+ */
208
+ const operationContext = Effect.gen(function* () {
209
+ const runtime = yield* CurrentRuntimeContext;
210
+ if (globalThis.__ALCHEMY_RUNTIME__ && runtime !== undefined) {
211
+ const tokenId = yield* runtime.get<string>(TOKEN_ENV.id);
212
+ const tokenSecret = yield* runtime.get<string | Redacted.Redacted<string>>(TOKEN_ENV.secret);
213
+ if (tokenId !== undefined && tokenSecret !== undefined) {
214
+ const serverUrl = yield* runtime.get<string>(TOKEN_ENV.serverUrl);
215
+ return yield* Layer.build(
216
+ Layer.mergeAll(
217
+ withAuthTokens(
218
+ credentials({
219
+ tokenId: Redacted.make(tokenId),
220
+ tokenSecret: Redacted.isRedacted(tokenSecret)
221
+ ? tokenSecret
222
+ : Redacted.make(tokenSecret),
223
+ apiBaseUrl: serverUrl,
224
+ }),
225
+ ),
226
+ ModalTransport,
227
+ ),
228
+ ).pipe(Effect.scoped);
229
+ }
230
+ // A Modal Function or Server: call as the container (see `Bind`).
231
+ const socket = yield* containerSocket;
232
+ if (socket !== undefined) {
233
+ return yield* Layer.build(
234
+ Layer.mergeAll(
235
+ withAuthToken.pipe(Layer.provide(Layer.mergeAll(fromContainer, FetchHttpClient.layer))),
236
+ fromContainer,
237
+ FetchHttpClient.layer,
238
+ ),
239
+ ).pipe(Effect.orDie, Effect.scoped);
240
+ }
241
+ }
242
+ // No bound identity (deploy, scripts, Actions): the ambient Modal
243
+ // credentials, falling back to `MODAL_TOKEN_ID` / `MODAL_TOKEN_SECRET`.
244
+ const ambientCredentials = yield* Effect.serviceOption(Credentials);
245
+ const ambientHttp = yield* Effect.serviceOption(HttpClient.HttpClient);
246
+ const transport = yield* Effect.provide(Effect.service(GrpcTransport), ModalTransport);
247
+ return Context.make(
248
+ Credentials,
249
+ Option.isSome(ambientCredentials)
250
+ ? ambientCredentials.value
251
+ : yield* Credentials.pipe(Effect.provide(withAuthTokens(CredentialsFromEnv))),
252
+ ).pipe(
253
+ Context.add(
254
+ HttpClient.HttpClient,
255
+ Option.isSome(ambientHttp)
256
+ ? ambientHttp.value
257
+ : yield* HttpClient.HttpClient.pipe(Effect.provide(ModalTransport)),
258
+ ),
259
+ Context.add(GrpcTransport, transport),
260
+ );
261
+ });
262
+
263
+ /**
264
+ * Resolve a distilled operation (or several, with `Effect.all`) once when
265
+ * the binding's layer is built: with the token pair {@link Bind} bound into
266
+ * the host, or the deployer's credentials when there is none.
267
+ *
268
+ * @example
269
+ * ```ts
270
+ * const ops = yield* ModalBindings.withCredentials(
271
+ * operations({ getFile: volume.volumeGetFile2, putFiles: volume.volumePutFiles2 }),
272
+ * );
273
+ * ```
274
+ */
275
+ export const withCredentials: <Op>(
276
+ operation: Effect.Effect<Op, never, OperationServices>,
277
+ ) => Effect.Effect<Op> = Effect.fn(function* <Op>(
278
+ operation: Effect.Effect<Op, never, OperationServices>,
279
+ ) {
280
+ const context = yield* operationContext;
281
+ return yield* operation.pipe(Effect.provide(context));
282
+ });
283
+
284
+ /**
285
+ * Resolve a task command router operation for one sandbox: the router runs
286
+ * per task, at a URL with its own JWT (from `sandboxGetCommandRouterAccess`).
287
+ * The router credentials are applied on every call, because a resolved
288
+ * operation runs with its caller's `Credentials` (the control plane's) over
289
+ * the ones it captured. `withTaskCommandRouter` also supplies the HTTP/2
290
+ * client the router requires.
291
+ */
292
+ export const withRouter =
293
+ <I, O, E>(operation: (input: I) => Effect.Effect<O, E, OperationServices>) =>
294
+ (access: RouterAccess): Effect.Effect<(input: I) => Effect.Effect<O, E>> =>
295
+ Effect.succeed((input: I) => operation(input).pipe(withTaskCommandRouter(access)));
296
+
297
+ /**
298
+ * {@link withRouter} for a server-streaming router operation: its `.stream`,
299
+ * which emits each message as the router sends it.
300
+ */
301
+ export const streamRouter =
302
+ <I, A, E>(operation: { readonly stream: (input: I) => Stream.Stream<A, E, OperationServices> }) =>
303
+ (access: RouterAccess): Effect.Effect<(input: I) => Stream.Stream<A, E>> =>
304
+ Effect.succeed((input: I) => operation.stream(input).pipe(streamTaskCommandRouter(access)));
305
+
306
+ /** A task's command router: its URL and JWT, from `sandboxGetCommandRouterAccess`. */
307
+ export interface RouterAccess {
308
+ readonly url: string;
309
+ readonly jwt: string;
310
+ }
@@ -0,0 +1,137 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type * as Output from "alchemy/Output";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import {
6
+ type BucketMount,
7
+ type BucketMountOptions,
8
+ type MountedBucket,
9
+ r2Endpoint,
10
+ } from "./Mounts.ts";
11
+ import { MODAL_RUNTIMES, type MountHost } from "./MountVolume.ts";
12
+ import type { Secret } from "./Secret.ts";
13
+
14
+ /**
15
+ * A bucket resource of another provider: an AWS S3 Bucket, a Cloudflare R2
16
+ * Bucket, a GCS bucket. Its name (and, for R2, its account endpoint) is
17
+ * read from its attributes.
18
+ */
19
+ export interface BucketResource {
20
+ readonly Type: string;
21
+ readonly bucketName: Output.Output<string, never>;
22
+ }
23
+
24
+ /** Options for `Modal.MountBucket`: Modal's cloud bucket mount fields, plus the keys' secret. */
25
+ export interface MountBucketOptions extends BucketMountOptions {
26
+ /**
27
+ * A `Modal.Secret` holding the bucket's keys (`AWS_ACCESS_KEY_ID` /
28
+ * `AWS_SECRET_ACCESS_KEY`, or GCS HMAC keys). Omit it with `oidcAuthRoleArn`.
29
+ */
30
+ readonly secret?: Secret;
31
+ }
32
+
33
+ /** What `Modal.MountBucket` returns: a mount entry, ready for `mounts`. */
34
+ export type BucketMountRef = BucketMount<
35
+ string | MountedBucket,
36
+ { readonly secretId: Effect.Effect<string> }
37
+ >;
38
+
39
+ /**
40
+ * Mount a cloud bucket at `path` with Modal's cloud bucket mounts: a bucket
41
+ * name, or a bucket resource of another provider (an AWS S3 Bucket, a
42
+ * Cloudflare R2 Bucket, whose account endpoint is filled in).
43
+ *
44
+ * - In a `Modal.Function`, `Modal.Server` or `Modal.Sandbox` program, the
45
+ * bucket is mounted into every container the program runs in.
46
+ * - In any other runtime, the binding returns the entry to pass to
47
+ * `sandboxes.create({ mounts })`.
48
+ *
49
+ * Modal reads the bucket with the keys in `secret`, or by assuming
50
+ * `oidcAuthRoleArn` with its OIDC identity.
51
+ *
52
+ * ### Mount an R2 bucket
53
+ * **Example:** A sandbox program reading uploads from Cloudflare R2
54
+ * ```typescript
55
+ * import * as Modal from "@alchemy.run/modal";
56
+ * import * as Effect from "effect/Effect";
57
+ * import * as FileSystem from "effect/FileSystem";
58
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
59
+ * import { Coder, R2Keys, Uploads } from "./Storage.ts";
60
+ *
61
+ * export default class Agent extends Modal.Sandbox<Agent>()(
62
+ * "Agent",
63
+ * { main: import.meta.url, app: Coder },
64
+ * Effect.gen(function* () {
65
+ * const uploads = yield* Modal.MountBucket(Uploads, { path: "/uploads", secret: R2Keys });
66
+ * const fs = yield* FileSystem.FileSystem;
67
+ * return {
68
+ * fetch: Effect.gen(function* () {
69
+ * return yield* HttpServerResponse.json(yield* fs.readDirectory(uploads.path));
70
+ * }).pipe(Effect.orDie),
71
+ * };
72
+ * }).pipe(Effect.provide(Modal.MountBucketLive)),
73
+ * ) {}
74
+ * ```
75
+ *
76
+ * @binding
77
+ * @product Volume
78
+ */
79
+ export interface MountBucket extends Binding.Service<
80
+ MountBucket,
81
+ "Modal.MountBucket",
82
+ (bucket: string | BucketResource, options: MountBucketOptions) => Effect.Effect<BucketMountRef>
83
+ > {}
84
+
85
+ export const MountBucket = Binding.Service<MountBucket>("Modal.MountBucket");
86
+
87
+ const R2_BUCKET = "Cloudflare.R2.Bucket";
88
+
89
+ /**
90
+ * {@link MountBucket}: binds the entry into a Modal runtime's `mounts`, or
91
+ * resolves it for `sandboxes.create` in any other runtime.
92
+ *
93
+ * @layer
94
+ * @product Volume
95
+ * @provides Modal.MountBucket
96
+ */
97
+ export const MountBucketLive = Layer.effect(
98
+ MountBucket,
99
+ Effect.succeed(
100
+ Effect.fn("Modal.MountBucket")(function* (
101
+ bucket: string | BucketResource,
102
+ options: MountBucketOptions,
103
+ ) {
104
+ const { secret, ...rest } = options;
105
+ if (!globalThis.__ALCHEMY_RUNTIME__) {
106
+ const host = yield* Binding.Host;
107
+ if (host !== undefined && MODAL_RUNTIMES.has(host.Type)) {
108
+ yield* (host as unknown as MountHost).bind`Modal.MountBucket(${bucket})`({
109
+ mounts: [{ ...rest, bucket, secret }],
110
+ });
111
+ }
112
+ }
113
+ const secretRef = secret === undefined ? undefined : { secretId: yield* secret.secretId };
114
+ if (typeof bucket === "string") {
115
+ return { ...rest, bucket, secret: secretRef } satisfies BucketMountRef;
116
+ }
117
+ const bucketName = yield* bucket.bucketName;
118
+ if (bucket.Type === R2_BUCKET) {
119
+ const r2 = bucket as BucketResource & {
120
+ readonly accountId: Output.Output<string, never>;
121
+ readonly jurisdiction: Output.Output<string | undefined, never>;
122
+ };
123
+ const accountId = yield* r2.accountId;
124
+ const jurisdiction = yield* r2.jurisdiction;
125
+ const endpointUrl = Effect.map(Effect.all([accountId, jurisdiction]), ([account, j]) =>
126
+ r2Endpoint(account, j),
127
+ );
128
+ return {
129
+ ...rest,
130
+ bucket: { bucketName, endpointUrl, type: "r2" },
131
+ secret: secretRef,
132
+ } satisfies BucketMountRef;
133
+ }
134
+ return { ...rest, bucket: { bucketName }, secret: secretRef } satisfies BucketMountRef;
135
+ }),
136
+ ),
137
+ );
@@ -0,0 +1,113 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import * as ModalBindings from "./ModalBindings.ts";
5
+ import type { MountedVolume, VolumeMount, VolumeMountOptions } from "./Mounts.ts";
6
+ import type { Volume } from "./Volume.ts";
7
+
8
+ /** What `Modal.MountVolume` returns: a mount entry, ready for `mounts`. */
9
+ export type VolumeMountRef = VolumeMount<MountedVolume>;
10
+
11
+ /**
12
+ * Mount a `Modal.Volume` at `path`.
13
+ *
14
+ * - In a `Modal.Function`, `Modal.Server` or `Modal.Sandbox` program, the
15
+ * volume is mounted into every container the program runs in: read it at
16
+ * `path` with the filesystem.
17
+ * - In any other runtime (a Worker, a Lambda), the binding grants the
18
+ * runtime's Modal identity access to the volume's environment and returns
19
+ * the entry to pass to `sandboxes.create({ mounts })`.
20
+ *
21
+ * The returned reference holds the same fields as a plain entry
22
+ * (`{ volume, path, readOnly?, subPath? }`).
23
+ *
24
+ * ### Mount into a program
25
+ * **Example:** A Function reading model weights from a volume
26
+ * ```typescript
27
+ * import * as Modal from "@alchemy.run/modal";
28
+ * import * as Effect from "effect/Effect";
29
+ * import * as FileSystem from "effect/FileSystem";
30
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
31
+ * import { Backend, Weights } from "./Backend.ts";
32
+ *
33
+ * export default class Embed extends Modal.Function<Embed>()(
34
+ * "Embed",
35
+ * { main: import.meta.url, app: Backend, gpu: "L4" },
36
+ * Effect.gen(function* () {
37
+ * const weights = yield* Modal.MountVolume(Weights, { path: "/weights", readOnly: true });
38
+ * const fs = yield* FileSystem.FileSystem;
39
+ * return {
40
+ * fetch: Effect.gen(function* () {
41
+ * return yield* HttpServerResponse.json(yield* fs.readDirectory(weights.path));
42
+ * }).pipe(Effect.orDie),
43
+ * };
44
+ * }).pipe(Effect.provide(Modal.MountVolumeLive)),
45
+ * ) {}
46
+ * ```
47
+ *
48
+ * ### Mount into a sandbox you create
49
+ * **Example:** From a Cloudflare Worker
50
+ * ```typescript
51
+ * const data = yield* Modal.MountVolume(Data, { path: "/data" });
52
+ * const sandboxes = yield* Modal.CreateSandbox(Coder);
53
+ * // per request
54
+ * const sandbox = yield* sandboxes.create({ mounts: [data] });
55
+ * ```
56
+ *
57
+ * @binding
58
+ * @product Volume
59
+ */
60
+ export interface MountVolume extends Binding.Service<
61
+ MountVolume,
62
+ "Modal.MountVolume",
63
+ (volume: Volume, options: VolumeMountOptions) => Effect.Effect<VolumeMountRef>
64
+ > {}
65
+
66
+ export const MountVolume = Binding.Service<MountVolume>("Modal.MountVolume");
67
+
68
+ /** Runtimes that mount volumes into their own containers. */
69
+ export const MODAL_RUNTIMES = new Set(["Modal.Function", "Modal.Server", "Modal.Sandbox"]);
70
+
71
+ /** A Modal runtime's `bind`, typed for the `mounts` slice of its binding contract. */
72
+ export type MountHost = {
73
+ bind: (
74
+ label: TemplateStringsArray,
75
+ ...args: unknown[]
76
+ ) => (data: { readonly mounts: ReadonlyArray<unknown> }) => Effect.Effect<void>;
77
+ };
78
+
79
+ /**
80
+ * {@link MountVolume}: binds the entry into a Modal runtime's `mounts`, or
81
+ * grants another runtime's identity access to the volume's environment.
82
+ *
83
+ * @layer
84
+ * @product Volume
85
+ * @provides Modal.MountVolume
86
+ */
87
+ export const MountVolumeLive = Layer.effect(
88
+ MountVolume,
89
+ Effect.gen(function* () {
90
+ const bind = yield* ModalBindings.Bind;
91
+ return Effect.fn("Modal.MountVolume")(function* (volume: Volume, options: VolumeMountOptions) {
92
+ if (!globalThis.__ALCHEMY_RUNTIME__) {
93
+ const host = yield* Binding.Host;
94
+ if (host !== undefined && MODAL_RUNTIMES.has(host.Type)) {
95
+ yield* (host as unknown as MountHost).bind`Modal.MountVolume(${volume})`({
96
+ mounts: [{ volume, ...options }],
97
+ });
98
+ } else {
99
+ yield* bind`Modal.MountVolume(${volume})`({
100
+ roles: [
101
+ {
102
+ environment: volume.environment,
103
+ role: options.readOnly ? "viewer" : "contributor",
104
+ },
105
+ ],
106
+ });
107
+ }
108
+ }
109
+ const volumeId = yield* volume.volumeId;
110
+ return { ...options, volume: { volumeId } } satisfies VolumeMountRef;
111
+ });
112
+ }),
113
+ );