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

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,710 @@
1
+ import * as persistent from "@distilled.cloud/modal/persistent";
2
+ import * as sandbox from "@distilled.cloud/modal/sandbox";
3
+ import * as router from "@distilled.cloud/modal/task_command_router";
4
+ import * as Sandbox from "alchemy/Sandbox";
5
+ import * as SecureRandom from "effect/crypto/SecureRandom";
6
+ import * as Data from "effect/Data";
7
+ import * as DateTime from "effect/DateTime";
8
+ import * as Effect from "effect/Effect";
9
+ import * as HttpClient from "effect/http/HttpClient";
10
+ import * as HttpClientRequest from "effect/http/HttpClientRequest";
11
+ import * as Schedule from "effect/Schedule";
12
+ import * as Stream from "effect/Stream";
13
+ import { buildImage, gpuConfig, ImageBuildOps } from "./ImageBuild.js";
14
+ import { environmentOf, operations, seconds } from "./internal.js";
15
+ import { connectTcp } from "./internal/TcpConnect.js";
16
+ import { streamRouter, withRouter } from "./ModalBindings.js";
17
+ import { modalMountsOf } from "./Mounts.js";
18
+ /** A sandbox ended (or never became ready) before the call could finish. */
19
+ export class SandboxNotRunning extends Data.TaggedError("Modal.SandboxNotRunning") {
20
+ }
21
+ /** A Modal call returned without the field the client needs. */
22
+ export class SandboxUnexpectedResponse extends Data.TaggedError("Modal.SandboxUnexpectedResponse") {
23
+ }
24
+ /** A filesystem operation inside the sandbox failed (missing path, permissions). */
25
+ export class SandboxFilesystemError extends Data.TaggedError("Modal.SandboxFilesystemError") {
26
+ }
27
+ /** Modal's task command router has no call to resize a running PTY. */
28
+ export class SandboxPtyResizeUnsupported extends Data.TaggedError("Modal.SandboxPtyResizeUnsupported") {
29
+ }
30
+ /** The text of a command's output stream, from its router read chunks. */
31
+ const streamText = (chunks) => Buffer.concat(chunks.map((chunk) => Buffer.from(chunk.data ?? "", "base64"))).toString("utf8");
32
+ const decodeBase64 = (data) => Effect.sync(() => new Uint8Array(Buffer.from(data, "base64")));
33
+ const encodeBase64 = (data) => Effect.sync(() => typeof data === "string"
34
+ ? Buffer.from(data, "utf8").toString("base64")
35
+ : Buffer.from(data).toString("base64"));
36
+ const tunnelTypeOf = (h2) => h2 ? "TUNNEL_TYPE_H2" : undefined;
37
+ /** Modal's `Sandbox` definition for {@link SandboxCreateOptions}. */
38
+ const definitionOf = (imageId, options, mounts) => ({
39
+ imageId,
40
+ entrypointArgs: options.command ? [...options.command] : ["sleep", "infinity"],
41
+ workdir: options.workdir,
42
+ environmentVariables: options.env,
43
+ secretIds: options.secrets?.map((s) => s.secretId),
44
+ volumeMounts: mounts.volumeMounts,
45
+ cloudBucketMounts: mounts.cloudBucketMounts,
46
+ resources: {
47
+ milliCpu: options.cpu !== undefined ? Math.round(options.cpu * 1000) : undefined,
48
+ memoryMb: options.memory,
49
+ gpuConfig: gpuConfig(options.gpu),
50
+ ephemeralDiskMb: options.ephemeralDisk,
51
+ },
52
+ timeoutSecs: seconds(options.timeout),
53
+ idleTimeoutSecs: seconds(options.idleTimeout),
54
+ name: options.name,
55
+ schedulerPlacement: options.regions ? { regions: [...options.regions] } : undefined,
56
+ blockNetwork: options.blockNetwork,
57
+ networkAccess: networkAccessOf(options),
58
+ inboundCidrAllowlist: options.inboundCidrAllowlist
59
+ ? [...options.inboundCidrAllowlist]
60
+ : undefined,
61
+ outboundPolicy: options.outboundPolicy ? outboundPolicyOf(options.outboundPolicy) : undefined,
62
+ proxyId: options.proxy?.proxyId,
63
+ includeOidcIdentityToken: options.includeOidcIdentityToken,
64
+ includeX509Svid: options.includeX509Svid,
65
+ openPorts: {
66
+ ports: [
67
+ ...(options.encryptedPorts ?? []).map((port) => ({ port })),
68
+ ...(options.unencryptedPorts ?? []).map((port) => ({ port, unencrypted: true })),
69
+ ...(options.h2Ports ?? []).map((port) => ({ port, tunnelType: tunnelTypeOf(true) })),
70
+ ],
71
+ },
72
+ enableSnapshot: options.enableSnapshot,
73
+ customDomain: options.customDomain,
74
+ });
75
+ const networkAccessOf = (options) => options.blockNetwork
76
+ ? { networkAccessType: "BLOCKED" }
77
+ : options.cidrAllowlist !== undefined || options.allowedDomains !== undefined
78
+ ? {
79
+ networkAccessType: "ALLOWLIST",
80
+ allowedCidrs: options.cidrAllowlist ? [...options.cidrAllowlist] : [],
81
+ allowedDomains: options.allowedDomains ? [...options.allowedDomains] : [],
82
+ }
83
+ : undefined;
84
+ /**
85
+ * The policy for a sandbox that is already running. Modal's task router
86
+ * accepts only an allow-list here: an empty one blocks everything, and
87
+ * `0.0.0.0/0` opens the network.
88
+ */
89
+ const runningNetworkAccessOf = (access) => {
90
+ const open = access.cidrAllowlist === undefined && access.allowedDomains === undefined;
91
+ return {
92
+ networkAccessType: "ALLOWLIST",
93
+ allowedCidrs: access.blockNetwork
94
+ ? []
95
+ : open
96
+ ? ["0.0.0.0/0"]
97
+ : [...(access.cidrAllowlist ?? [])],
98
+ allowedDomains: access.blockNetwork ? [] : [...(access.allowedDomains ?? [])],
99
+ };
100
+ };
101
+ const portsOf = (ports) => ports?.map((port) => (typeof port === "number" ? { start: port, end: port } : port));
102
+ const transportOf = (transport) => transport === undefined ? undefined : `TRANSPORT_${transport.toUpperCase()}`;
103
+ const redirectOf = (redirect) => redirect === undefined
104
+ ? undefined
105
+ : redirect === "block"
106
+ ? { block: {} }
107
+ : "proxy" in redirect
108
+ ? { viaProxy: { proxyId: redirect.proxy.proxyId } }
109
+ : { viaSidecar: { sidecarName: redirect.sidecar } };
110
+ const outboundPolicyOf = (policy) => ({
111
+ tlsDecryption: {
112
+ allowed: policy.tlsDecryption ?? policy.routes.some((route) => "https" in route),
113
+ },
114
+ routes: policy.routes.map((route) => {
115
+ if ("ip" in route) {
116
+ return {
117
+ ip: {
118
+ cidrs: [...route.ip.cidrs],
119
+ ports: portsOf(route.ip.ports),
120
+ transport: transportOf(route.ip.transport),
121
+ redirect: redirectOf(route.ip.redirect),
122
+ },
123
+ };
124
+ }
125
+ if ("tls" in route) {
126
+ return {
127
+ tls: {
128
+ domains: [...route.tls.domains],
129
+ ports: portsOf(route.tls.ports),
130
+ redirect: redirectOf(route.tls.redirect),
131
+ },
132
+ };
133
+ }
134
+ if ("https" in route) {
135
+ return {
136
+ https: {
137
+ domains: [...route.https.domains],
138
+ ports: portsOf(route.https.ports),
139
+ headerReplacements: route.https.headerReplacements?.map((r) => ({
140
+ secretId: r.secret?.secretId,
141
+ headers: r.headers,
142
+ })),
143
+ redirect: redirectOf(route.https.redirect),
144
+ },
145
+ };
146
+ }
147
+ return { any: { redirect: redirectOf(route.any.redirect) } };
148
+ }),
149
+ });
150
+ /**
151
+ * The operations sandbox clients call, resolved once by
152
+ * `ModalBindings.withCredentials` (or at deploy, with the deployer's).
153
+ */
154
+ export const SandboxOps = operations({
155
+ create: sandbox.sandboxCreateV2,
156
+ getFromName: sandbox.sandboxGetFromNameV2,
157
+ list: sandbox.sandboxListV2,
158
+ restore: sandbox.sandboxRestoreV2,
159
+ getTaskId: sandbox.sandboxGetTaskIdV2,
160
+ getCommandRouterAccess: sandbox.sandboxGetCommandRouterAccess,
161
+ getTunnels: sandbox.sandboxGetTunnelsV2,
162
+ createConnectToken: sandbox.sandboxCreateConnectTokenV2,
163
+ setOutboundPolicy: sandbox.sandboxSetOutboundPolicyV2,
164
+ setTags: sandbox.sandboxTagsSetV2,
165
+ getTags: sandbox.sandboxTagsGetV2,
166
+ setName: sandbox.sandboxSetName,
167
+ getResourceUsage: sandbox.sandboxGetResourceUsage,
168
+ wait: sandbox.sandboxWaitV2,
169
+ terminate: sandbox.sandboxTerminateV2,
170
+ usage: sandbox.sandboxGetTimeRangeStats,
171
+ createPersistent: persistent.createPersistentSandbox,
172
+ getPersistent: persistent.getPersistentSandbox,
173
+ resumePersistent: persistent.resumePersistentSandbox,
174
+ terminatePersistent: persistent.terminatePersistentSandbox,
175
+ images: ImageBuildOps,
176
+ http: HttpClient.HttpClient,
177
+ });
178
+ /** Task command router operations, resolved per sandbox with its router access. */
179
+ const routerOps = {
180
+ execStart: withRouter(router.taskExecStart),
181
+ execStdinWrite: withRouter(router.taskExecStdinWrite),
182
+ execStdioRead: withRouter(router.taskExecStdioRead),
183
+ execWait: withRouter(router.taskExecWait),
184
+ // A running command's output, each chunk as the router sends it; the
185
+ // stream ends when the command closes the descriptor.
186
+ execStdioFollow: streamRouter(router.taskExecStdioRead),
187
+ snapshotFilesystem: withRouter(router.taskSnapshotFilesystem),
188
+ snapshotMemory: withRouter(router.taskSnapshotMemory),
189
+ snapshotDirectory: withRouter(router.taskSnapshotDirectory),
190
+ mountDirectory: withRouter(router.taskMountDirectory),
191
+ setNetworkAccess: withRouter(router.taskSetNetworkAccess),
192
+ // The sandbox's own program's output (V2 sandboxes serve it here, not
193
+ // through the control plane's sandboxGetLogs).
194
+ mainStdio: streamRouter(router.sandboxStdioReadV2),
195
+ };
196
+ /**
197
+ * The image to boot: a `Modal.Image`'s id, or a registry ref built (and
198
+ * cached by Modal) into an image in the target app.
199
+ */
200
+ export const resolveSandboxImage = Effect.fn(function* (ops, target, image) {
201
+ if (image !== undefined && typeof image !== "string")
202
+ return image.imageId;
203
+ if (image === undefined && target.imageId !== undefined)
204
+ return target.imageId;
205
+ const spec = { dockerTag: image ?? "debian:bookworm-slim", commands: [] };
206
+ return yield* buildImage(ops.images, target.appId, spec);
207
+ });
208
+ /** The handle for an existing sandbox id. */
209
+ export const sandboxHandle = (ops, sandboxId, target) => {
210
+ let cachedTaskId;
211
+ const taskId = Effect.gen(function* () {
212
+ if (cachedTaskId !== undefined)
213
+ return cachedTaskId;
214
+ for (let attempt = 0; attempt < 10; attempt++) {
215
+ const response = yield* ops.getTaskId({
216
+ sandboxId,
217
+ timeout: 55,
218
+ waitUntilReady: true,
219
+ });
220
+ if (response.taskId) {
221
+ cachedTaskId = response.taskId;
222
+ return response.taskId;
223
+ }
224
+ if (response.taskResult?.status &&
225
+ response.taskResult.status !== "GENERIC_STATUS_UNSPECIFIED") {
226
+ return yield* new SandboxNotRunning({
227
+ sandboxId,
228
+ message: `Sandbox ${sandboxId} finished with ${response.taskResult.status}`,
229
+ });
230
+ }
231
+ }
232
+ return yield* new SandboxNotRunning({
233
+ sandboxId,
234
+ message: `Sandbox ${sandboxId} wasn't scheduled within 9 minutes`,
235
+ });
236
+ });
237
+ const viaRouter = (resolve, f) => Effect.gen(function* () {
238
+ const id = yield* taskId;
239
+ const access = yield* ops.getCommandRouterAccess({ taskId: id });
240
+ if (!access.url || !access.jwt) {
241
+ return yield* new SandboxUnexpectedResponse({
242
+ message: `Modal returned no command router for sandbox ${sandboxId}`,
243
+ });
244
+ }
245
+ const op = yield* resolve({ url: access.url, jwt: access.jwt });
246
+ return yield* f(op, id);
247
+ });
248
+ /**
249
+ * Run a filesystem command with `sh` (every image Modal boots has one) and
250
+ * fail with {@link SandboxFilesystemError} on a non-zero exit.
251
+ */
252
+ const fsExec = (path, script, stdin) => Effect.flatMap(exec(["sh", "-c", script, "sh", path], stdin === undefined ? {} : { stdin }), (result) => result.exitCode === 0
253
+ ? Effect.succeed(result.stdout)
254
+ : Effect.fail(new SandboxFilesystemError({
255
+ path,
256
+ message: result.stderr.trim() || `exit code ${result.exitCode}`,
257
+ })));
258
+ const exec = Effect.fn(function* (command, options = {}) {
259
+ // V2 sandboxes run commands through the task command router: start the
260
+ // command under an id we choose, then read its output streams while
261
+ // waiting for it to exit.
262
+ const id = yield* taskId;
263
+ const access = yield* ops.getCommandRouterAccess({ taskId: id });
264
+ if (!access.url || !access.jwt) {
265
+ return yield* new SandboxUnexpectedResponse({
266
+ message: `Modal returned no command router for sandbox ${sandboxId}`,
267
+ });
268
+ }
269
+ const at = { url: access.url, jwt: access.jwt };
270
+ const start = yield* routerOps.execStart(at);
271
+ const stdinWrite = yield* routerOps.execStdinWrite(at);
272
+ const stdioRead = yield* routerOps.execStdioRead(at);
273
+ const wait = yield* routerOps.execWait(at);
274
+ const execId = yield* Effect.sync(() => SecureRandom.uuidV4Unsafe());
275
+ yield* start({
276
+ taskId: id,
277
+ execId,
278
+ commandArgs: typeof command === "string" ? ["sh", "-c", command] : [...command],
279
+ workdir: options.cwd,
280
+ timeoutSecs: seconds(options.timeout),
281
+ secretIds: options.secrets?.map((s) => s.secretId),
282
+ env: options.env,
283
+ stdoutConfig: "TASK_EXEC_STDOUT_CONFIG_PIPE",
284
+ stderrConfig: "TASK_EXEC_STDERR_CONFIG_PIPE",
285
+ });
286
+ if (options.stdin !== undefined) {
287
+ yield* stdinWrite({
288
+ taskId: id,
289
+ execId,
290
+ offset: "0",
291
+ data: yield* encodeBase64(options.stdin),
292
+ eof: true,
293
+ });
294
+ }
295
+ const read = (fileDescriptor) => stdioRead({ taskId: id, execId, offset: "0", fileDescriptor }).pipe(Effect.map(({ items }) => streamText(items)));
296
+ const [stdout, stderr, exit] = yield* Effect.all([
297
+ read("TASK_EXEC_STDIO_FILE_DESCRIPTOR_STDOUT"),
298
+ read("TASK_EXEC_STDIO_FILE_DESCRIPTOR_STDERR"),
299
+ wait({ taskId: id, execId }),
300
+ ], { concurrency: "unbounded" });
301
+ return {
302
+ exitCode: exit.code ?? (exit.signal !== undefined ? 128 + exit.signal : -1),
303
+ stdout,
304
+ stderr,
305
+ };
306
+ });
307
+ /** The task and its router access, for the router calls of one command. */
308
+ const routerAccess = Effect.gen(function* () {
309
+ const id = yield* taskId;
310
+ const access = yield* ops.getCommandRouterAccess({ taskId: id });
311
+ if (!access.url || !access.jwt) {
312
+ return yield* new SandboxUnexpectedResponse({
313
+ message: `Modal returned no command router for sandbox ${sandboxId}`,
314
+ });
315
+ }
316
+ return { taskId: id, at: { url: access.url, jwt: access.jwt } };
317
+ });
318
+ /**
319
+ * Start a command (on a PTY with `pty`) and return how to follow it: a
320
+ * stream per output, stdin writes from a running offset, and its exit.
321
+ */
322
+ const startExec = Effect.fn(function* (commandArgs, options, pty) {
323
+ const { taskId: id, at } = yield* routerAccess;
324
+ const begin = yield* routerOps.execStart(at);
325
+ const stdinWrite = yield* routerOps.execStdinWrite(at);
326
+ const follow = yield* routerOps.execStdioFollow(at);
327
+ const wait = yield* routerOps.execWait(at);
328
+ const execId = yield* Effect.sync(() => SecureRandom.uuidV4Unsafe());
329
+ yield* begin({
330
+ taskId: id,
331
+ execId,
332
+ commandArgs: [...commandArgs],
333
+ workdir: options.cwd,
334
+ timeoutSecs: seconds(options.timeout),
335
+ secretIds: options.secrets?.map((s) => s.secretId),
336
+ env: options.env,
337
+ stdoutConfig: "TASK_EXEC_STDOUT_CONFIG_PIPE",
338
+ stderrConfig: pty ? undefined : "TASK_EXEC_STDERR_CONFIG_PIPE",
339
+ ptyInfo: pty,
340
+ });
341
+ let stdinOffset = 0;
342
+ const write = (data, eof = false) => Effect.gen(function* () {
343
+ const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
344
+ const offset = stdinOffset;
345
+ stdinOffset += bytes.length;
346
+ yield* stdinWrite({
347
+ taskId: id,
348
+ execId,
349
+ offset: String(offset),
350
+ data: yield* encodeBase64(bytes),
351
+ eof,
352
+ });
353
+ });
354
+ /** One output of the command, each chunk as it arrives. */
355
+ const output = (fileDescriptor) => follow({ taskId: id, execId, offset: "0", fileDescriptor }).pipe(Stream.map((item) => new Uint8Array(Buffer.from(item.data, "base64"))), Stream.filter((bytes) => bytes.length > 0));
356
+ if (options.stdin !== undefined)
357
+ yield* write(options.stdin, true);
358
+ return {
359
+ execId,
360
+ write,
361
+ output,
362
+ wait: Effect.map(wait({ taskId: id, execId }), (exit) => ({
363
+ exitCode: exit.code ?? (exit.signal !== undefined ? 128 + exit.signal : -1),
364
+ })),
365
+ };
366
+ });
367
+ const argvOf = (command) => typeof command === "string" ? ["sh", "-c", command] : command;
368
+ const start = (command, options = {}) => Effect.gen(function* () {
369
+ // The router has no signal call: the command records its pid, and
370
+ // `kill` signals it with a second command.
371
+ const pidFile = `/tmp/.alchemy-exec-${yield* Effect.sync(() => SecureRandom.uuidV4Unsafe())}.pid`;
372
+ const running = yield* startExec(["sh", "-c", 'echo $$ > "$0"; exec "$@"', pidFile, ...argvOf(command)], options);
373
+ return {
374
+ id: running.execId,
375
+ output: Stream.merge(Stream.map(running.output("TASK_EXEC_STDIO_FILE_DESCRIPTOR_STDOUT"), (data) => ({
376
+ fd: "stdout",
377
+ data,
378
+ })), Stream.map(running.output("TASK_EXEC_STDIO_FILE_DESCRIPTOR_STDERR"), (data) => ({
379
+ fd: "stderr",
380
+ data,
381
+ }))),
382
+ write: (data) => running.write(data),
383
+ kill: (signal = "SIGTERM") => Effect.asVoid(exec(["sh", "-c", `kill -s ${signal.slice(3)} "$(cat "$0")"`, pidFile])),
384
+ wait: running.wait,
385
+ };
386
+ });
387
+ const pty = {
388
+ open: (options) => Effect.gen(function* () {
389
+ const running = yield* startExec(options.command
390
+ ? ["sh", "-c", options.command]
391
+ : ["sh", "-c", "exec bash -l 2>/dev/null || exec sh -l"], { cwd: options.cwd, env: options.env, secrets: options.secrets }, {
392
+ enabled: true,
393
+ winszRows: options.rows,
394
+ winszCols: options.cols,
395
+ envTerm: "xterm-256color",
396
+ ptyType: "PTY_TYPE_SHELL",
397
+ noTerminateOnIdleStdin: true,
398
+ });
399
+ return {
400
+ id: running.execId,
401
+ output: running.output("TASK_EXEC_STDIO_FILE_DESCRIPTOR_STDOUT"),
402
+ write: (data) => running.write(data),
403
+ resize: () => Effect.fail(new SandboxPtyResizeUnsupported({
404
+ message: "Modal's task command router can't resize a running PTY",
405
+ })),
406
+ };
407
+ }),
408
+ };
409
+ const read = Effect.fn(function* (path) {
410
+ // base64 keeps binary content intact through the text output stream.
411
+ const encoded = yield* fsExec(path, 'base64 < "$1" | tr -d "\\n"');
412
+ return yield* decodeBase64(encoded);
413
+ });
414
+ const typeOf = (letter) => letter === "d" ? "directory" : letter === "l" ? "symlink" : letter === "f" ? "file" : "other";
415
+ const files = {
416
+ read,
417
+ readText: (path) => read(path).pipe(Effect.map((bytes) => new TextDecoder().decode(bytes))),
418
+ write: Effect.fn(function* (path, data) {
419
+ const encoded = yield* encodeBase64(data);
420
+ yield* fsExec(path, 'mkdir -p "$(dirname "$1")" && base64 -d > "$1"', encoded);
421
+ }),
422
+ list: Effect.fn(function* (path) {
423
+ const output = yield* fsExec(path, 'cd "$1" && for f in * .[!.]* ..?*; do [ -e "$f" ] || [ -L "$f" ] || continue; if [ -L "$f" ]; then echo "l $f"; elif [ -d "$f" ]; then echo "d $f"; elif [ -f "$f" ]; then echo "f $f"; else echo "o $f"; fi; done');
424
+ return output
425
+ .split("\n")
426
+ .filter((line) => line.length > 2)
427
+ .map((line) => ({
428
+ path: `${path.replace(/\/$/, "")}/${line.slice(2)}`,
429
+ type: typeOf(line[0]),
430
+ }));
431
+ }),
432
+ stat: Effect.fn(function* (path) {
433
+ // `%F` is GNU stat's type name; busybox prints the same names.
434
+ const output = yield* fsExec(path, 'stat -c "%F|%s|%Y" "$1"');
435
+ const [kind = "", size = "0", mtime = "0"] = output.trim().split("|");
436
+ return {
437
+ path,
438
+ type: kind.includes("directory")
439
+ ? "directory"
440
+ : kind.includes("symbolic link")
441
+ ? "symlink"
442
+ : kind.includes("regular")
443
+ ? "file"
444
+ : "other",
445
+ size: Number(size),
446
+ modifiedAt: DateTime.makeUnsafe(Number(mtime) * 1000),
447
+ };
448
+ }),
449
+ remove: Effect.fn(function* (path, options = {}) {
450
+ yield* fsExec(path, options.recursive ? 'rm -r "$1"' : 'rm "$1"');
451
+ }),
452
+ makeDir: Effect.fn(function* (path) {
453
+ yield* fsExec(path, 'mkdir -p "$1"');
454
+ }),
455
+ };
456
+ const tunnelsOf = Effect.fn(function* (timeout) {
457
+ const { tunnels } = yield* ops.getTunnels({
458
+ sandboxId,
459
+ timeout: seconds(timeout) ?? 50,
460
+ });
461
+ const out = {};
462
+ for (const tunnel of tunnels ?? []) {
463
+ if (tunnel.containerPort === undefined)
464
+ continue;
465
+ const encrypted = tunnel.host !== undefined && tunnel.host !== "";
466
+ const host = (encrypted ? tunnel.host : tunnel.unencryptedHost) ?? "";
467
+ const port = (encrypted ? tunnel.port : tunnel.unencryptedPort) ?? 443;
468
+ out[tunnel.containerPort] = {
469
+ host,
470
+ port,
471
+ url: encrypted
472
+ ? `https://${host}${port === 443 ? "" : `:${port}`}`
473
+ : `tcp://${host}:${port}`,
474
+ };
475
+ }
476
+ return out;
477
+ });
478
+ const getTcpPort = Effect.fn(function* (port = target.program?.port) {
479
+ if (port === undefined) {
480
+ return yield* new SandboxUnexpectedResponse({
481
+ message: "getTcpPort needs a port: create the sandbox from a Modal.Sandbox, or pass one",
482
+ });
483
+ }
484
+ const tunnel = (yield* tunnelsOf(50))[port];
485
+ if (!tunnel) {
486
+ return yield* new SandboxUnexpectedResponse({
487
+ message: `Port ${port} of sandbox ${sandboxId} has no tunnel; open it with encryptedPorts`,
488
+ });
489
+ }
490
+ const tls = tunnel.url.startsWith("https:");
491
+ // An unencrypted tunnel carries plain TCP, so HTTP to it is cleartext.
492
+ const origin = tls ? tunnel.url : `http://${tunnel.host}:${tunnel.port}`;
493
+ const sandboxPort = {
494
+ ...tunnel,
495
+ // The user's own program, reached through its tunnel (allowed raw HTTP).
496
+ fetch: Sandbox.portFetch((request) => {
497
+ const url = new URL(request.url, "http://sandbox");
498
+ // The tunnel routes by host, so a proxied request's own `host` goes.
499
+ return ops.http.execute(HttpClientRequest.setUrl(HttpClientRequest.removeHeader(request, "host"), `${origin}${url.pathname}${url.search}`));
500
+ }),
501
+ connect: () => connectTcp({ host: tunnel.host, port: tunnel.port, tls }),
502
+ };
503
+ return sandboxPort;
504
+ });
505
+ const handle = {
506
+ sandboxId,
507
+ exec,
508
+ start,
509
+ pty,
510
+ files,
511
+ tunnels: tunnelsOf,
512
+ connectToken: Effect.fn(function* (options = {}) {
513
+ const response = yield* ops.createConnectToken({
514
+ sandboxId,
515
+ port: options.port,
516
+ userMetadata: options.userMetadata,
517
+ });
518
+ if (!response.url || !response.token) {
519
+ return yield* new SandboxUnexpectedResponse({ message: "Modal returned no connect token" });
520
+ }
521
+ return { url: response.url, token: response.token };
522
+ }),
523
+ snapshotFilesystem: (_timeout) => viaRouter(routerOps.snapshotFilesystem, (op, task) => Effect.flatMap(Effect.sync(() => SecureRandom.uuidV4Unsafe()),
524
+ // -1: the snapshot image never expires.
525
+ (snapshotId) => op({ taskId: task, snapshotId, ttlSeconds: "-1" }))).pipe(Effect.flatMap((response) => response.imageId
526
+ ? Effect.succeed({ imageId: response.imageId })
527
+ : Effect.fail(new SandboxUnexpectedResponse({
528
+ message: `Filesystem snapshot of ${sandboxId} returned no image`,
529
+ })))),
530
+ snapshotMemory: () => viaRouter(routerOps.snapshotMemory, (op, task) => Effect.flatMap(Effect.sync(() => SecureRandom.uuidV4Unsafe()), (idempotencyKey) => op({ taskId: task, idempotencyKey }))).pipe(Effect.flatMap((response) => response.snapshotId
531
+ ? Effect.succeed({ snapshotId: response.snapshotId })
532
+ : Effect.fail(new SandboxUnexpectedResponse({ message: "No snapshot id" })))),
533
+ snapshotDirectory: (path) => viaRouter(routerOps.snapshotDirectory, (op, task) => op({ taskId: task, path })).pipe(Effect.flatMap((response) => response.imageId
534
+ ? Effect.succeed({ imageId: response.imageId })
535
+ : Effect.fail(new SandboxUnexpectedResponse({ message: `No image for ${path}` })))),
536
+ mountDirectory: (path, snapshot) => viaRouter(routerOps.mountDirectory, (op, task) => op({ taskId: task, path, imageId: snapshot.imageId })).pipe(Effect.asVoid),
537
+ setNetworkAccess: (access) => viaRouter(routerOps.setNetworkAccess, (op, task) => op({ taskId: task, networkAccess: runningNetworkAccessOf(access) })).pipe(Effect.asVoid),
538
+ setOutboundPolicy: Effect.fn(function* (policy) {
539
+ yield* ops.setOutboundPolicy({
540
+ sandboxId,
541
+ outboundPolicy: outboundPolicyOf(policy),
542
+ });
543
+ }),
544
+ setTags: Effect.fn(function* (tags) {
545
+ yield* ops.setTags({
546
+ sandboxId,
547
+ environmentName: environmentOf(target.environment),
548
+ tags: Object.entries(tags).map(([tagName, tagValue]) => ({ tagName, tagValue })),
549
+ });
550
+ }),
551
+ getTags: Effect.fn(function* () {
552
+ const { tags } = yield* ops.getTags({ sandboxId });
553
+ return Object.fromEntries((tags ?? []).map((t) => [t.tagName ?? "", t.tagValue ?? ""]));
554
+ }),
555
+ setName: Effect.fn(function* (name) {
556
+ yield* ops.setName({ sandboxId, name });
557
+ }),
558
+ resourceUsage: Effect.fn(function* () {
559
+ const usage = yield* ops.getResourceUsage({ sandboxId });
560
+ return {
561
+ cpuSeconds: Number(usage.cpuCoreNanosecs ?? 0) / 1e9,
562
+ memoryGibSeconds: Number(usage.memGibNanosecs ?? 0) / 1e9,
563
+ gpuSeconds: Number(usage.gpuNanosecs ?? 0) / 1e9,
564
+ };
565
+ }),
566
+ logs: Effect.fn(function* (options = {}) {
567
+ const { taskId: id, at } = yield* routerAccess;
568
+ const read = yield* routerOps.mainStdio(at);
569
+ const chunks = yield* read({
570
+ taskId: id,
571
+ offset: "0",
572
+ fileDescriptor: "SANDBOX_STDIO_FILE_DESCRIPTOR_STDOUT",
573
+ }).pipe(Stream.map((item) => Buffer.from(item.data, "base64")), Stream.interruptWhen(Effect.sleep(`${seconds(options.timeout) ?? 5} seconds`)), Stream.runCollect);
574
+ return Buffer.concat(chunks).toString("utf8");
575
+ }),
576
+ wait: Effect.fn(function* (timeout) {
577
+ const { result } = yield* ops.wait({
578
+ sandboxId,
579
+ timeout: seconds(timeout) ?? 0,
580
+ });
581
+ return {
582
+ exitCode: result?.exitcode,
583
+ status: result?.status ?? "GENERIC_STATUS_UNSPECIFIED",
584
+ };
585
+ }),
586
+ getTcpPort,
587
+ terminate: Effect.fn(function* () {
588
+ yield* ops
589
+ .terminate({ sandboxId })
590
+ .pipe(Effect.catchTag("SandboxNotFound", () => Effect.void));
591
+ }),
592
+ };
593
+ return handle;
594
+ };
595
+ /**
596
+ * Create a sandbox in `target`'s app and return its handle. The one
597
+ * implementation behind `CreateSandbox` and warm-base image builds.
598
+ */
599
+ export const createSandbox = Effect.fn(function* (ops, target, options = {}) {
600
+ const imageId = yield* resolveSandboxImage(ops, target, options.image);
601
+ const program = target.program;
602
+ const withProgram = program
603
+ ? {
604
+ ...options,
605
+ command: options.command ?? program.command,
606
+ secrets: [{ secretId: program.secretId }, ...(options.secrets ?? [])],
607
+ encryptedPorts: [...new Set([program.port, ...(options.encryptedPorts ?? [])])],
608
+ }
609
+ : options;
610
+ const own = yield* modalMountsOf(options.mounts);
611
+ const mounts = {
612
+ volumeMounts: [...(program?.mounts?.volumeMounts ?? []), ...own.volumeMounts],
613
+ cloudBucketMounts: [...(program?.mounts?.cloudBucketMounts ?? []), ...own.cloudBucketMounts],
614
+ };
615
+ const created = yield* ops.create({
616
+ appId: target.appId,
617
+ definition: definitionOf(imageId, withProgram, mounts),
618
+ tags: Object.entries(options.tags ?? {}).map(([tagName, tagValue]) => ({ tagName, tagValue })),
619
+ });
620
+ if (!created.sandboxId) {
621
+ return yield* new SandboxUnexpectedResponse({ message: "Modal returned no sandbox id" });
622
+ }
623
+ return sandboxHandle(ops, created.sandboxId, target);
624
+ });
625
+ /** A running sandbox of `target`'s app by name, or `undefined`. */
626
+ export const sandboxFromName = Effect.fn(function* (ops, target, name) {
627
+ const found = yield* ops
628
+ .getFromName({
629
+ sandboxName: name,
630
+ appName: target.appName,
631
+ environmentName: environmentOf(target.environment),
632
+ })
633
+ .pipe(Effect.catchTag("SandboxNotFound", () => Effect.undefined));
634
+ return found?.sandboxId ? sandboxHandle(ops, found.sandboxId, target) : undefined;
635
+ });
636
+ /** Running sandboxes of `target`'s app, optionally filtered by tags. */
637
+ export const listSandboxes = Effect.fn(function* (ops, target, options = {}) {
638
+ const { sandboxes } = yield* ops.list({
639
+ appId: target.appId,
640
+ environmentName: environmentOf(target.environment),
641
+ includeFinished: options.includeFinished ?? false,
642
+ tags: Object.entries(options.tags ?? {}).map(([tagName, tagValue]) => ({ tagName, tagValue })),
643
+ });
644
+ return (sandboxes ?? []).flatMap((info) => info.id
645
+ ? [
646
+ {
647
+ sandboxId: info.id,
648
+ name: info.name || undefined,
649
+ createdAt: info.createdAt,
650
+ tags: Object.fromEntries((info.tags ?? []).map((t) => [t.tagName ?? "", t.tagValue ?? ""])),
651
+ },
652
+ ]
653
+ : []);
654
+ });
655
+ /** Restore a memory snapshot into a new sandbox. */
656
+ export const restoreSandbox = Effect.fn(function* (ops, target, snapshot, options = {}) {
657
+ const restored = yield* ops.restore({
658
+ snapshotId: snapshot.snapshotId,
659
+ sandboxNameOverride: options.name,
660
+ sandboxNameOverrideType: options.name ? "SANDBOX_NAME_OVERRIDE_TYPE_STRING" : undefined,
661
+ });
662
+ if (!restored.sandboxId) {
663
+ return yield* new SandboxUnexpectedResponse({ message: "Modal returned no restored sandbox" });
664
+ }
665
+ return sandboxHandle(ops, restored.sandboxId, target);
666
+ });
667
+ /** Modal's session limits for persistent sandboxes. */
668
+ const PERSISTENT_SESSION = { timeout: 60 * 60, idleTimeout: 5 * 60 };
669
+ /** The handle for an existing persistent sandbox id. */
670
+ export const persistentSandboxHandle = (ops, persistentSandboxId, target) => ({
671
+ persistentSandboxId,
672
+ session: Effect.fn(function* () {
673
+ const running = yield* ops.getPersistent({ persistentSandboxId });
674
+ if (running.sandboxId)
675
+ return sandboxHandle(ops, running.sandboxId, target);
676
+ // A paused box resumes from its last session's filesystem. Modal answers
677
+ // busy while the previous session is still saving it.
678
+ const resumed = yield* ops.resumePersistent({ persistentSandboxId }).pipe(Effect.retry({
679
+ while: (error) => error._tag === "PersistentSandboxBusy",
680
+ schedule: Schedule.spaced("1 second"),
681
+ times: 60,
682
+ }));
683
+ if (!resumed.sandboxId) {
684
+ return yield* new SandboxUnexpectedResponse({
685
+ message: `Modal returned no session for persistent sandbox ${persistentSandboxId}`,
686
+ });
687
+ }
688
+ return sandboxHandle(ops, resumed.sandboxId, target);
689
+ }),
690
+ terminate: Effect.fn(function* () {
691
+ yield* ops
692
+ .terminatePersistent({ persistentSandboxId })
693
+ .pipe(Effect.catchTag("PersistentSandboxNotFound", () => Effect.void));
694
+ }),
695
+ });
696
+ /** Create a persistent sandbox in `target`'s app. */
697
+ export const createPersistentSandbox = Effect.fn(function* (ops, target, options = {}) {
698
+ const imageId = yield* resolveSandboxImage(ops, target, options.image);
699
+ const created = yield* ops.createPersistent({
700
+ appId: target.appId,
701
+ definition: definitionOf(imageId, { ...options, ...PERSISTENT_SESSION }, yield* modalMountsOf(options.mounts)),
702
+ });
703
+ if (!created.persistentSandboxId) {
704
+ return yield* new SandboxUnexpectedResponse({
705
+ message: "Modal returned no persistent sandbox id",
706
+ });
707
+ }
708
+ return persistentSandboxHandle(ops, created.persistentSandboxId, target);
709
+ });
710
+ //# sourceMappingURL=SandboxClient.js.map