@boxrouter/sdk 0.0.0-stage → 0.12.190

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 (343) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +40 -0
  3. package/README.md +508 -2
  4. package/dist/addresses.d.ts +5 -0
  5. package/dist/addresses.js +10 -0
  6. package/dist/api-error.d.ts +62 -0
  7. package/dist/api-error.js +264 -0
  8. package/dist/boxrouter.d.ts +68 -0
  9. package/dist/boxrouter.js +291 -0
  10. package/dist/browser-session/index.d.ts +17 -0
  11. package/dist/browser-session/index.js +48 -0
  12. package/dist/browser-session/operations.gen.d.ts +272 -0
  13. package/dist/browser-session/operations.gen.js +58 -0
  14. package/dist/browser-session/responseContracts/api_keys.d.ts +2 -0
  15. package/dist/browser-session/responseContracts/api_keys.js +10 -0
  16. package/dist/browser-session/responseContracts/credits.d.ts +2 -0
  17. package/dist/browser-session/responseContracts/credits.js +8 -0
  18. package/dist/browser-session/responseContracts/github.d.ts +2 -0
  19. package/dist/browser-session/responseContracts/github.js +11 -0
  20. package/dist/browser-session/responseContracts/identity.d.ts +2 -0
  21. package/dist/browser-session/responseContracts/identity.js +30 -0
  22. package/dist/browser-session/responseContracts/organizations.d.ts +2 -0
  23. package/dist/browser-session/responseContracts/organizations.js +17 -0
  24. package/dist/browser-session/responseContracts/privacy.d.ts +2 -0
  25. package/dist/browser-session/responseContracts/privacy.js +7 -0
  26. package/dist/browser-session/responseContracts.gen.d.ts +3 -0
  27. package/dist/browser-session/responseContracts.gen.js +10 -0
  28. package/dist/browser-session/responseValidators/api_keys-diagnostics.cjs +1 -0
  29. package/dist/browser-session/responseValidators/api_keys-diagnostics.d.cts +4 -0
  30. package/dist/browser-session/responseValidators/api_keys.cjs +2 -0
  31. package/dist/browser-session/responseValidators/api_keys.d.cts +4 -0
  32. package/dist/browser-session/responseValidators/credits-diagnostics.cjs +1 -0
  33. package/dist/browser-session/responseValidators/credits-diagnostics.d.cts +3 -0
  34. package/dist/browser-session/responseValidators/credits.cjs +2 -0
  35. package/dist/browser-session/responseValidators/credits.d.cts +3 -0
  36. package/dist/browser-session/responseValidators/github-diagnostics.cjs +1 -0
  37. package/dist/browser-session/responseValidators/github-diagnostics.d.cts +3 -0
  38. package/dist/browser-session/responseValidators/github.cjs +2 -0
  39. package/dist/browser-session/responseValidators/github.d.cts +3 -0
  40. package/dist/browser-session/responseValidators/identity-diagnostics.cjs +1 -0
  41. package/dist/browser-session/responseValidators/identity-diagnostics.d.cts +23 -0
  42. package/dist/browser-session/responseValidators/identity.cjs +2 -0
  43. package/dist/browser-session/responseValidators/identity.d.cts +23 -0
  44. package/dist/browser-session/responseValidators/organizations-diagnostics.cjs +1 -0
  45. package/dist/browser-session/responseValidators/organizations-diagnostics.d.cts +15 -0
  46. package/dist/browser-session/responseValidators/organizations.cjs +2 -0
  47. package/dist/browser-session/responseValidators/organizations.d.cts +15 -0
  48. package/dist/browser-session/responseValidators/privacy-diagnostics.cjs +1 -0
  49. package/dist/browser-session/responseValidators/privacy-diagnostics.d.cts +2 -0
  50. package/dist/browser-session/responseValidators/privacy.cjs +2 -0
  51. package/dist/browser-session/responseValidators/privacy.d.cts +2 -0
  52. package/dist/client/client.gen.d.ts +2 -0
  53. package/dist/client/client.gen.js +168 -0
  54. package/dist/client/index.d.ts +10 -0
  55. package/dist/client/index.js +17 -0
  56. package/dist/client/types.gen.d.ts +120 -0
  57. package/dist/client/types.gen.js +3 -0
  58. package/dist/client/utils.gen.d.ts +37 -0
  59. package/dist/client/utils.gen.js +239 -0
  60. package/dist/client.gen.d.ts +12 -0
  61. package/dist/client.gen.js +6 -0
  62. package/dist/command-check.gen.d.ts +14 -0
  63. package/dist/command-check.gen.js +23 -0
  64. package/dist/command-input.gen.d.ts +6 -0
  65. package/dist/command-input.gen.js +45 -0
  66. package/dist/core/auth.gen.d.ts +25 -0
  67. package/dist/core/auth.gen.js +18 -0
  68. package/dist/core/binaryStream.d.ts +8 -0
  69. package/dist/core/binaryStream.js +76 -0
  70. package/dist/core/bodySerializer.gen.d.ts +25 -0
  71. package/dist/core/bodySerializer.gen.js +60 -0
  72. package/dist/core/commandValidators.cjs +1 -0
  73. package/dist/core/commandValidators.d.cts +14 -0
  74. package/dist/core/eventValidation.d.ts +17 -0
  75. package/dist/core/eventValidation.js +56 -0
  76. package/dist/core/eventValidators.cjs +1 -0
  77. package/dist/core/eventValidators.d.cts +2 -0
  78. package/dist/core/json.d.ts +3 -0
  79. package/dist/core/json.js +33 -0
  80. package/dist/core/params.gen.d.ts +43 -0
  81. package/dist/core/params.gen.js +112 -0
  82. package/dist/core/pathSerializer.gen.d.ts +33 -0
  83. package/dist/core/pathSerializer.gen.js +115 -0
  84. package/dist/core/queryKeySerializer.gen.d.ts +18 -0
  85. package/dist/core/queryKeySerializer.gen.js +98 -0
  86. package/dist/core/responseContracts/actions.d.ts +2 -0
  87. package/dist/core/responseContracts/actions.js +30 -0
  88. package/dist/core/responseContracts/agents.d.ts +2 -0
  89. package/dist/core/responseContracts/agents.js +7 -0
  90. package/dist/core/responseContracts/artifacts.d.ts +2 -0
  91. package/dist/core/responseContracts/artifacts.js +8 -0
  92. package/dist/core/responseContracts/commands.d.ts +2 -0
  93. package/dist/core/responseContracts/commands.js +6 -0
  94. package/dist/core/responseContracts/credits.d.ts +2 -0
  95. package/dist/core/responseContracts/credits.js +27 -0
  96. package/dist/core/responseContracts/files.d.ts +2 -0
  97. package/dist/core/responseContracts/files.js +15 -0
  98. package/dist/core/responseContracts/github.d.ts +2 -0
  99. package/dist/core/responseContracts/github.js +8 -0
  100. package/dist/core/responseContracts/images.d.ts +2 -0
  101. package/dist/core/responseContracts/images.js +8 -0
  102. package/dist/core/responseContracts/launchRuns.d.ts +2 -0
  103. package/dist/core/responseContracts/launchRuns.js +10 -0
  104. package/dist/core/responseContracts/launches.d.ts +2 -0
  105. package/dist/core/responseContracts/launches.js +10 -0
  106. package/dist/core/responseContracts/operations.d.ts +2 -0
  107. package/dist/core/responseContracts/operations.js +7 -0
  108. package/dist/core/responseContracts/previews.d.ts +2 -0
  109. package/dist/core/responseContracts/previews.js +8 -0
  110. package/dist/core/responseContracts/pricing.d.ts +2 -0
  111. package/dist/core/responseContracts/pricing.js +6 -0
  112. package/dist/core/responseContracts/processes.d.ts +2 -0
  113. package/dist/core/responseContracts/processes.js +11 -0
  114. package/dist/core/responseContracts/provider_accounts.d.ts +2 -0
  115. package/dist/core/responseContracts/provider_accounts.js +13 -0
  116. package/dist/core/responseContracts/providers.d.ts +2 -0
  117. package/dist/core/responseContracts/providers.js +6 -0
  118. package/dist/core/responseContracts/routing.d.ts +2 -0
  119. package/dist/core/responseContracts/routing.js +8 -0
  120. package/dist/core/responseContracts/sandboxes.d.ts +2 -0
  121. package/dist/core/responseContracts/sandboxes.js +15 -0
  122. package/dist/core/responseContracts/secrets.d.ts +2 -0
  123. package/dist/core/responseContracts/secrets.js +8 -0
  124. package/dist/core/responseContracts/spend_limits.d.ts +2 -0
  125. package/dist/core/responseContracts/spend_limits.js +8 -0
  126. package/dist/core/responseContracts/terminals.d.ts +2 -0
  127. package/dist/core/responseContracts/terminals.js +11 -0
  128. package/dist/core/responseContracts/usage.d.ts +2 -0
  129. package/dist/core/responseContracts/usage.js +7 -0
  130. package/dist/core/responseContracts/volumes.d.ts +2 -0
  131. package/dist/core/responseContracts/volumes.js +19 -0
  132. package/dist/core/responseContracts.gen.d.ts +3 -0
  133. package/dist/core/responseContracts.gen.js +27 -0
  134. package/dist/core/responseModes.d.ts +19 -0
  135. package/dist/core/responseModes.js +13 -0
  136. package/dist/core/responseValidation.d.ts +44 -0
  137. package/dist/core/responseValidation.js +174 -0
  138. package/dist/core/responseValidators/actions-diagnostics.cjs +4 -0
  139. package/dist/core/responseValidators/actions-diagnostics.d.cts +24 -0
  140. package/dist/core/responseValidators/actions.cjs +2 -0
  141. package/dist/core/responseValidators/actions.d.cts +24 -0
  142. package/dist/core/responseValidators/agents-diagnostics.cjs +1 -0
  143. package/dist/core/responseValidators/agents-diagnostics.d.cts +2 -0
  144. package/dist/core/responseValidators/agents.cjs +2 -0
  145. package/dist/core/responseValidators/agents.d.cts +2 -0
  146. package/dist/core/responseValidators/artifacts-diagnostics.cjs +1 -0
  147. package/dist/core/responseValidators/artifacts-diagnostics.d.cts +2 -0
  148. package/dist/core/responseValidators/artifacts.cjs +2 -0
  149. package/dist/core/responseValidators/artifacts.d.cts +2 -0
  150. package/dist/core/responseValidators/commands-diagnostics.cjs +1 -0
  151. package/dist/core/responseValidators/commands-diagnostics.d.cts +1 -0
  152. package/dist/core/responseValidators/commands.cjs +2 -0
  153. package/dist/core/responseValidators/commands.d.cts +1 -0
  154. package/dist/core/responseValidators/compact.cjs +122 -0
  155. package/dist/core/responseValidators/credits-diagnostics.cjs +1 -0
  156. package/dist/core/responseValidators/credits-diagnostics.d.cts +21 -0
  157. package/dist/core/responseValidators/credits.cjs +2 -0
  158. package/dist/core/responseValidators/credits.d.cts +21 -0
  159. package/dist/core/responseValidators/files-diagnostics.cjs +1 -0
  160. package/dist/core/responseValidators/files-diagnostics.d.cts +5 -0
  161. package/dist/core/responseValidators/files.cjs +2 -0
  162. package/dist/core/responseValidators/files.d.cts +5 -0
  163. package/dist/core/responseValidators/github-diagnostics.cjs +1 -0
  164. package/dist/core/responseValidators/github-diagnostics.d.cts +2 -0
  165. package/dist/core/responseValidators/github.cjs +2 -0
  166. package/dist/core/responseValidators/github.d.cts +2 -0
  167. package/dist/core/responseValidators/images-diagnostics.cjs +1 -0
  168. package/dist/core/responseValidators/images-diagnostics.d.cts +3 -0
  169. package/dist/core/responseValidators/images.cjs +2 -0
  170. package/dist/core/responseValidators/images.d.cts +3 -0
  171. package/dist/core/responseValidators/launchRuns-diagnostics.cjs +1 -0
  172. package/dist/core/responseValidators/launchRuns-diagnostics.d.cts +5 -0
  173. package/dist/core/responseValidators/launchRuns.cjs +2 -0
  174. package/dist/core/responseValidators/launchRuns.d.cts +5 -0
  175. package/dist/core/responseValidators/launches-diagnostics.cjs +10 -0
  176. package/dist/core/responseValidators/launches-diagnostics.d.cts +5 -0
  177. package/dist/core/responseValidators/launches.cjs +2 -0
  178. package/dist/core/responseValidators/launches.d.cts +5 -0
  179. package/dist/core/responseValidators/operations-diagnostics.cjs +1 -0
  180. package/dist/core/responseValidators/operations-diagnostics.d.cts +2 -0
  181. package/dist/core/responseValidators/operations.cjs +2 -0
  182. package/dist/core/responseValidators/operations.d.cts +2 -0
  183. package/dist/core/responseValidators/previews-diagnostics.cjs +1 -0
  184. package/dist/core/responseValidators/previews-diagnostics.d.cts +3 -0
  185. package/dist/core/responseValidators/previews.cjs +2 -0
  186. package/dist/core/responseValidators/previews.d.cts +3 -0
  187. package/dist/core/responseValidators/pricing-diagnostics.cjs +7 -0
  188. package/dist/core/responseValidators/pricing-diagnostics.d.cts +1 -0
  189. package/dist/core/responseValidators/pricing.cjs +2 -0
  190. package/dist/core/responseValidators/pricing.d.cts +1 -0
  191. package/dist/core/responseValidators/processes-diagnostics.cjs +1 -0
  192. package/dist/core/responseValidators/processes-diagnostics.d.cts +2 -0
  193. package/dist/core/responseValidators/processes.cjs +2 -0
  194. package/dist/core/responseValidators/processes.d.cts +2 -0
  195. package/dist/core/responseValidators/provider_accounts-diagnostics.cjs +1 -0
  196. package/dist/core/responseValidators/provider_accounts-diagnostics.d.cts +8 -0
  197. package/dist/core/responseValidators/provider_accounts.cjs +2 -0
  198. package/dist/core/responseValidators/provider_accounts.d.cts +8 -0
  199. package/dist/core/responseValidators/providers-diagnostics.cjs +1 -0
  200. package/dist/core/responseValidators/providers-diagnostics.d.cts +1 -0
  201. package/dist/core/responseValidators/providers.cjs +2 -0
  202. package/dist/core/responseValidators/providers.d.cts +1 -0
  203. package/dist/core/responseValidators/routing-diagnostics.cjs +1 -0
  204. package/dist/core/responseValidators/routing-diagnostics.d.cts +3 -0
  205. package/dist/core/responseValidators/routing.cjs +2 -0
  206. package/dist/core/responseValidators/routing.d.cts +3 -0
  207. package/dist/core/responseValidators/sandboxes-diagnostics.cjs +1 -0
  208. package/dist/core/responseValidators/sandboxes-diagnostics.d.cts +10 -0
  209. package/dist/core/responseValidators/sandboxes.cjs +2 -0
  210. package/dist/core/responseValidators/sandboxes.d.cts +10 -0
  211. package/dist/core/responseValidators/secrets-diagnostics.cjs +1 -0
  212. package/dist/core/responseValidators/secrets-diagnostics.d.cts +1 -0
  213. package/dist/core/responseValidators/secrets.cjs +2 -0
  214. package/dist/core/responseValidators/secrets.d.cts +1 -0
  215. package/dist/core/responseValidators/spend_limits-diagnostics.cjs +1 -0
  216. package/dist/core/responseValidators/spend_limits-diagnostics.d.cts +3 -0
  217. package/dist/core/responseValidators/spend_limits.cjs +2 -0
  218. package/dist/core/responseValidators/spend_limits.d.cts +3 -0
  219. package/dist/core/responseValidators/terminals-diagnostics.cjs +1 -0
  220. package/dist/core/responseValidators/terminals-diagnostics.d.cts +2 -0
  221. package/dist/core/responseValidators/terminals.cjs +2 -0
  222. package/dist/core/responseValidators/terminals.d.cts +2 -0
  223. package/dist/core/responseValidators/usage-diagnostics.cjs +1 -0
  224. package/dist/core/responseValidators/usage-diagnostics.d.cts +1 -0
  225. package/dist/core/responseValidators/usage.cjs +2 -0
  226. package/dist/core/responseValidators/usage.d.cts +1 -0
  227. package/dist/core/responseValidators/volumes-diagnostics.cjs +1 -0
  228. package/dist/core/responseValidators/volumes-diagnostics.d.cts +10 -0
  229. package/dist/core/responseValidators/volumes.cjs +2 -0
  230. package/dist/core/responseValidators/volumes.d.cts +10 -0
  231. package/dist/core/serverSentEvents.gen.d.ts +30 -0
  232. package/dist/core/serverSentEvents.gen.js +313 -0
  233. package/dist/core/streamErrors.d.ts +32 -0
  234. package/dist/core/streamErrors.js +51 -0
  235. package/dist/core/types.gen.d.ts +83 -0
  236. package/dist/core/types.gen.js +3 -0
  237. package/dist/core/utils.gen.d.ts +19 -0
  238. package/dist/core/utils.gen.js +93 -0
  239. package/dist/creation.gen.d.ts +21 -0
  240. package/dist/creation.gen.js +35 -0
  241. package/dist/data-origin.d.ts +25 -0
  242. package/dist/data-origin.js +57 -0
  243. package/dist/error-codes.gen.d.ts +2 -0
  244. package/dist/error-codes.gen.js +2 -0
  245. package/dist/idempotency.gen.d.ts +1 -0
  246. package/dist/idempotency.gen.js +60 -0
  247. package/dist/images.d.ts +74 -0
  248. package/dist/images.js +88 -0
  249. package/dist/index.d.ts +22 -0
  250. package/dist/index.js +80 -0
  251. package/dist/launch-input.gen.d.ts +9 -0
  252. package/dist/launch-input.gen.js +83 -0
  253. package/dist/launch.d.ts +28 -0
  254. package/dist/launch.js +222 -0
  255. package/dist/namespace-actions.d.mts +307 -0
  256. package/dist/namespace-actions.mjs +595 -0
  257. package/dist/namespace-agents.d.mts +33 -0
  258. package/dist/namespace-agents.mjs +40 -0
  259. package/dist/namespace-artifacts.d.mts +46 -0
  260. package/dist/namespace-artifacts.mjs +69 -0
  261. package/dist/namespace-base.d.mts +7 -0
  262. package/dist/namespace-base.mjs +7 -0
  263. package/dist/namespace-commands.d.mts +57 -0
  264. package/dist/namespace-commands.mjs +57 -0
  265. package/dist/namespace-credits.d.mts +213 -0
  266. package/dist/namespace-credits.mjs +476 -0
  267. package/dist/namespace-files.d.mts +203 -0
  268. package/dist/namespace-files.mjs +334 -0
  269. package/dist/namespace-github.d.mts +50 -0
  270. package/dist/namespace-github.mjs +68 -0
  271. package/dist/namespace-images.d.mts +52 -0
  272. package/dist/namespace-images.mjs +78 -0
  273. package/dist/namespace-launch_runs.d.mts +89 -0
  274. package/dist/namespace-launch_runs.mjs +133 -0
  275. package/dist/namespace-launches.d.mts +89 -0
  276. package/dist/namespace-launches.mjs +133 -0
  277. package/dist/namespace-operations.d.mts +45 -0
  278. package/dist/namespace-operations.mjs +52 -0
  279. package/dist/namespace-previews.d.mts +79 -0
  280. package/dist/namespace-previews.mjs +101 -0
  281. package/dist/namespace-pricing.d.mts +31 -0
  282. package/dist/namespace-pricing.mjs +22 -0
  283. package/dist/namespace-processes.d.mts +125 -0
  284. package/dist/namespace-processes.mjs +184 -0
  285. package/dist/namespace-provider_accounts.d.mts +156 -0
  286. package/dist/namespace-provider_accounts.mjs +241 -0
  287. package/dist/namespace-providers.d.mts +28 -0
  288. package/dist/namespace-providers.mjs +24 -0
  289. package/dist/namespace-routing.d.mts +64 -0
  290. package/dist/namespace-routing.mjs +86 -0
  291. package/dist/namespace-sandboxes.d.mts +287 -0
  292. package/dist/namespace-sandboxes.mjs +402 -0
  293. package/dist/namespace-secrets.d.mts +46 -0
  294. package/dist/namespace-secrets.mjs +68 -0
  295. package/dist/namespace-spend_limits.d.mts +48 -0
  296. package/dist/namespace-spend_limits.mjs +70 -0
  297. package/dist/namespace-terminals.d.mts +112 -0
  298. package/dist/namespace-terminals.mjs +177 -0
  299. package/dist/namespace-usage.d.mts +46 -0
  300. package/dist/namespace-usage.mjs +53 -0
  301. package/dist/namespace-volumes.d.mts +110 -0
  302. package/dist/namespace-volumes.mjs +269 -0
  303. package/dist/operations.d.ts +14 -0
  304. package/dist/operations.js +31 -0
  305. package/dist/retry.d.ts +8 -0
  306. package/dist/retry.js +63 -0
  307. package/dist/routing-choices.gen.d.ts +132 -0
  308. package/dist/routing-choices.gen.js +136 -0
  309. package/dist/routing.d.ts +23 -0
  310. package/dist/routing.js +38 -0
  311. package/dist/sandbox-handle.gen.d.ts +8 -0
  312. package/dist/sandbox-handle.gen.js +14 -0
  313. package/dist/sandboxes.d.ts +213 -0
  314. package/dist/sandboxes.js +507 -0
  315. package/dist/sdk.gen.d.ts +2029 -0
  316. package/dist/sdk.gen.js +3862 -0
  317. package/dist/server-timing.d.ts +19 -0
  318. package/dist/server-timing.gen.d.ts +265 -0
  319. package/dist/server-timing.gen.js +254 -0
  320. package/dist/server-timing.js +421 -0
  321. package/dist/spend-limits.d.ts +17 -0
  322. package/dist/spend-limits.js +26 -0
  323. package/dist/telemetry.d.ts +51 -0
  324. package/dist/telemetry.gen.d.ts +1 -0
  325. package/dist/telemetry.gen.js +5 -0
  326. package/dist/telemetry.js +438 -0
  327. package/dist/terminal.d.ts +61 -0
  328. package/dist/terminal.js +266 -0
  329. package/dist/transfer.d.ts +75 -0
  330. package/dist/transfer.js +389 -0
  331. package/dist/types.gen.d.ts +15016 -0
  332. package/dist/types.gen.js +3 -0
  333. package/dist/user-agent.d.ts +2 -0
  334. package/dist/user-agent.js +18 -0
  335. package/dist/version.gen.d.ts +1 -0
  336. package/dist/version.gen.js +5 -0
  337. package/dist/volumes.d.ts +33 -0
  338. package/dist/volumes.js +221 -0
  339. package/dist/waits.d.ts +31 -0
  340. package/dist/waits.js +42 -0
  341. package/dist/workflow-policy.gen.d.ts +41 -0
  342. package/dist/workflow-policy.gen.js +45 -0
  343. package/package.json +135 -4
@@ -0,0 +1,389 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TRANSFER_TIMEOUTS = exports.TransferError = void 0;
4
+ exports.openSource = openSource;
5
+ exports.sendParts = sendParts;
6
+ exports.retryCompletion = retryCompletion;
7
+ exports.downloadStream = downloadStream;
8
+ exports.downloadToFile = downloadToFile;
9
+ /**
10
+ * The one transfer engine behind volume and sandbox uploads and downloads.
11
+ *
12
+ * It does exactly what the API's part and link objects say: the `method` (PUT by default), the
13
+ * `headers`, and either the raw bytes or a multipart form with one file field of the given name.
14
+ * It never inspects a URL or looks at which service is behind it. Every request carries an exact Content-Length
15
+ * and is never chunked: bodies are lazy `Blob`s (a file on disk is read as the request is
16
+ * written), which `fetch` sends with their length. Nothing here logs a URL or a header value,
17
+ * and no error message contains one.
18
+ *
19
+ * Retries are a caller decision, `replayParts`. A volume part is a presigned PUT that replaces
20
+ * the earlier copy of the part, so volume callers pass `true` and a part is sent again after a
21
+ * network error or a 5xx answer. A sandbox upload writes a live file, so sandbox callers pass
22
+ * `false`: a part is retried only when its connection never opened, and once any byte may have
23
+ * been sent the engine raises and the caller aborts the upload.
24
+ *
25
+ * Requests are never redirected (a redirect is an error). Timeouts apply per socket operation
26
+ * (`TRANSFER_TIMEOUTS`), not to the whole transfer, so a large part succeeds while a stalled
27
+ * connection fails.
28
+ */
29
+ const api_error_1 = require("./api-error");
30
+ class TransferError extends Error {
31
+ status;
32
+ constructor(message, status) {
33
+ super(message);
34
+ this.name = 'TransferError';
35
+ this.status = status;
36
+ }
37
+ }
38
+ exports.TransferError = TransferError;
39
+ // Transfer links last one to six hours; a 401 or 403 is most often a link that has ended.
40
+ const EXPIRED_LINK = ': the transfer link expired or was refused; start the transfer again';
41
+ function refusalHint(status) {
42
+ if (status === 401 || status === 403)
43
+ return EXPIRED_LINK;
44
+ return status === 507 ? ': the sandbox has no room for the file; use a path on its disk, not a memory-backed one' : '';
45
+ }
46
+ const PART_RETRY_LIMIT = 3;
47
+ const COMPLETE_RETRY_DELAYS_MS = [2_000, 4_000, 8_000, 16_000, 32_000];
48
+ const CONNECT_ERROR_CODES = new Set(['ECONNREFUSED', 'ENOTFOUND', 'EAI_AGAIN', 'ENETUNREACH', 'EHOSTUNREACH',
49
+ 'UND_ERR_CONNECT_TIMEOUT']);
50
+ // Set by the engine from the body it builds; a caller-supplied value could contradict it.
51
+ const ENGINE_HEADERS = new Set(['content-length', 'transfer-encoding', 'host']);
52
+ const undiciSpecifier = 'undici';
53
+ /** Per socket operation: a 5 GiB part is fine while it moves, a connection that stalls for 300 s fails. */
54
+ exports.TRANSFER_TIMEOUTS = { connectMs: 10_000, headersMs: 300_000, bodyMs: 300_000 };
55
+ let dispatcher;
56
+ // Node's own fetch would use its defaults; the engine states its timeouts, in Node, on an Agent of its own.
57
+ function transferDispatcher() {
58
+ const runtime = globalThis.process;
59
+ if (!runtime?.versions?.node)
60
+ return Promise.resolve(undefined);
61
+ dispatcher ??= import(/* @vite-ignore */ undiciSpecifier).then(module => new module.Agent({
62
+ headersTimeout: exports.TRANSFER_TIMEOUTS.headersMs, bodyTimeout: exports.TRANSFER_TIMEOUTS.bodyMs, connect: { timeout: exports.TRANSFER_TIMEOUTS.connectMs },
63
+ }), () => undefined);
64
+ return dispatcher;
65
+ }
66
+ async function transferFetch(url, init) {
67
+ return globalThis.fetch(url, { ...init, redirect: 'manual', dispatcher: await transferDispatcher() });
68
+ }
69
+ function errorCode(error) {
70
+ const cause = error instanceof Error ? error.cause : undefined;
71
+ const code = cause?.code ?? error?.code;
72
+ return typeof code === 'string' ? code : undefined;
73
+ }
74
+ function connectFailed(error) {
75
+ const code = errorCode(error);
76
+ return code !== undefined && CONNECT_ERROR_CODES.has(code);
77
+ }
78
+ function describeFailure(label, error) {
79
+ return `${label} request failed${errorCode(error) ? ` (${errorCode(error)})` : ''}`;
80
+ }
81
+ function pause(ms, signal) {
82
+ signal?.throwIfAborted();
83
+ return new Promise((resolve, reject) => {
84
+ const abort = () => {
85
+ clearTimeout(timeout);
86
+ reject(signal.reason);
87
+ };
88
+ const timeout = setTimeout(() => {
89
+ signal?.removeEventListener('abort', abort);
90
+ resolve();
91
+ }, ms);
92
+ signal?.addEventListener('abort', abort, { once: true });
93
+ });
94
+ }
95
+ function requestHeaders(headers, dropContentType = false) {
96
+ const result = {};
97
+ for (const [name, value] of Object.entries(headers ?? {})) {
98
+ const lower = name.toLowerCase();
99
+ if (ENGINE_HEADERS.has(lower) || (dropContentType && lower === 'content-type'))
100
+ continue;
101
+ result[name] = value;
102
+ }
103
+ return result;
104
+ }
105
+ /** Open an upload source and learn its size without reading it into memory. A stream is copied to disk
106
+ * while `signal` is live: aborting it cancels the pending read and removes the temporary data. */
107
+ async function openSource({ source, size }, signal) {
108
+ const sized = (actual) => {
109
+ if (size !== undefined && size !== actual)
110
+ throw new TypeError(`size ${size} does not match the source (${actual} bytes)`);
111
+ return actual;
112
+ };
113
+ if (typeof source === 'string') {
114
+ const fs = await import('node:fs');
115
+ const info = await fs.promises.stat(source);
116
+ if (!info.isFile())
117
+ throw new TypeError('source must be a regular file');
118
+ const blob = await fs.openAsBlob(source);
119
+ return { size: sized(blob.size), slice: (start, end) => blob.slice(start, end), close: async () => undefined };
120
+ }
121
+ if (source instanceof Blob) {
122
+ return { size: sized(source.size), slice: (start, end) => source.slice(start, end), close: async () => undefined };
123
+ }
124
+ if (source instanceof Uint8Array) {
125
+ return { size: sized(source.byteLength), slice: (start, end) => source.subarray(start, end), close: async () => undefined };
126
+ }
127
+ if (size === undefined)
128
+ throw new TypeError('size is required when uploading a stream');
129
+ return spoolStream(source, size, signal);
130
+ }
131
+ // Writes all of `bytes`: a write may take fewer bytes than it was given.
132
+ async function writeFully(handle, bytes) {
133
+ for (let offset = 0; offset < bytes.byteLength;) {
134
+ const { bytesWritten } = await handle.write(bytes, offset, bytes.byteLength - offset);
135
+ if (bytesWritten <= 0)
136
+ throw new Error('writing the upload to a temporary file made no progress');
137
+ offset += bytesWritten;
138
+ }
139
+ }
140
+ // fetch can only send a known length from a Blob or bytes, so a stream is written to a temporary
141
+ // file (never held in memory) and sent from there. Its length is checked here, before any request.
142
+ async function spoolStream(stream, size, signal) {
143
+ signal?.throwIfAborted();
144
+ const [fs, os, paths] = await Promise.all([import('node:fs'), import('node:os'), import('node:path')]);
145
+ const directory = await fs.promises.mkdtemp(paths.join(os.tmpdir(), 'boxrouter-upload-'));
146
+ const close = () => fs.promises.rm(directory, { recursive: true, force: true });
147
+ try {
148
+ const file = paths.join(directory, 'body');
149
+ const handle = await fs.promises.open(file, 'wx', 0o600);
150
+ let written = 0;
151
+ try {
152
+ const reader = stream.getReader();
153
+ // A producer that stalls never answers read(); cancelling the reader ends it so the abort is seen.
154
+ const stop = () => { reader.cancel(signal.reason).catch(() => undefined); };
155
+ signal?.addEventListener('abort', stop, { once: true });
156
+ try {
157
+ for (let chunk = await reader.read(); !chunk.done; chunk = await reader.read()) {
158
+ signal?.throwIfAborted();
159
+ written += chunk.value.byteLength;
160
+ if (written > size)
161
+ throw new TypeError(`stream is longer than the declared size of ${size} bytes`);
162
+ await writeFully(handle, chunk.value);
163
+ }
164
+ signal?.throwIfAborted();
165
+ }
166
+ finally {
167
+ signal?.removeEventListener('abort', stop);
168
+ reader.releaseLock();
169
+ }
170
+ }
171
+ finally {
172
+ await handle.close();
173
+ }
174
+ if (written !== size)
175
+ throw new TypeError(`stream ended after ${written} bytes; the declared size is ${size}`);
176
+ const blob = await fs.openAsBlob(file);
177
+ return { size, slice: (start, end) => blob.slice(start, end), close };
178
+ }
179
+ catch (error) {
180
+ await close();
181
+ throw error;
182
+ }
183
+ }
184
+ function partOffsets(parts, total) {
185
+ const ordered = [...parts].sort((left, right) => Number(left.number) - Number(right.number));
186
+ let offset = 0;
187
+ const ranges = ordered.map(part => {
188
+ const range = { part, start: offset, end: offset + Number(part.size) };
189
+ offset = range.end;
190
+ return range;
191
+ });
192
+ if (offset !== total)
193
+ throw new TransferError(`Upload parts cover ${offset} bytes but the source is ${total} bytes`);
194
+ return ranges;
195
+ }
196
+ async function sendPart(part, body, options, signal) {
197
+ const label = options.label ?? 'Transfer';
198
+ const form = part.form_field !== undefined && part.form_field !== null;
199
+ for (let attempt = 0;; attempt++) {
200
+ signal?.throwIfAborted();
201
+ let payload;
202
+ const headers = requestHeaders(part.headers, form);
203
+ if (form) {
204
+ const data = new FormData();
205
+ data.append(part.form_field, body instanceof Blob ? body : new Blob([body]), 'file');
206
+ payload = data;
207
+ }
208
+ else {
209
+ payload = body;
210
+ // Fetch derives the exact length from Blob/bytes. A manual header is rejected by Node 22's
211
+ // bundled fetch when it dispatches through the SDK's separately versioned undici Agent.
212
+ }
213
+ let response;
214
+ try {
215
+ response = await transferFetch(part.url, {
216
+ method: part.method ?? 'PUT', headers, body: payload, signal,
217
+ });
218
+ }
219
+ catch (error) {
220
+ if (signal?.aborted)
221
+ throw signal.reason ?? error;
222
+ if (attempt < PART_RETRY_LIMIT && (options.replayParts || connectFailed(error))) {
223
+ await pause(100 * (attempt + 1), signal);
224
+ continue;
225
+ }
226
+ throw new TransferError(describeFailure(`${label} upload part`, error));
227
+ }
228
+ if (response.status >= 500 && response.status <= 599 && options.replayParts && attempt < PART_RETRY_LIMIT) {
229
+ await response.body?.cancel().catch(() => undefined);
230
+ await pause(100 * (attempt + 1), signal);
231
+ continue;
232
+ }
233
+ await response.body?.cancel().catch(() => undefined);
234
+ if (!response.ok)
235
+ throw new TransferError(`${label} upload part returned HTTP ${response.status}${refusalHint(response.status)}`, response.status);
236
+ return response.headers.get('etag') ?? undefined;
237
+ }
238
+ }
239
+ /**
240
+ * Send every part with bounded parallelism and return each part's ETag when the response had one.
241
+ * The first failure stops the other parts and is raised; aborting the upload session is the caller's.
242
+ */
243
+ async function sendParts(source, parts, options) {
244
+ if (!Number.isInteger(options.concurrency) || options.concurrency < 1)
245
+ throw new TypeError('concurrency must be a positive integer');
246
+ const ranges = partOffsets(parts, source.size);
247
+ const inner = new AbortController();
248
+ const signal = options.signal ? AbortSignal.any([options.signal, inner.signal]) : inner.signal;
249
+ const results = new Map();
250
+ let next = 0;
251
+ let done = 0;
252
+ let failure;
253
+ const workers = Array.from({ length: Math.min(options.concurrency, ranges.length) }, async () => {
254
+ while (next < ranges.length && failure === undefined) {
255
+ const { part, start, end } = ranges[next++];
256
+ try {
257
+ results.set(Number(part.number), await sendPart(part, source.slice(start, end), options, signal));
258
+ done += end - start;
259
+ options.progress?.(done, source.size);
260
+ }
261
+ catch (error) {
262
+ failure ??= { error };
263
+ inner.abort(error);
264
+ }
265
+ }
266
+ });
267
+ await Promise.all(workers);
268
+ if (failure !== undefined)
269
+ throw failure.error;
270
+ return ranges.map(({ part }) => {
271
+ const etag = results.get(Number(part.number));
272
+ return etag === undefined ? { number: Number(part.number) } : { number: Number(part.number), etag };
273
+ });
274
+ }
275
+ /**
276
+ * Run a completion call, retrying while the answer is unknown (503 or no response). Every retry
277
+ * carries the idempotency key the first send used (`call` gets it, undefined on the first attempt), so a
278
+ * completion whose answer was lost is recovered rather than repeated under a new key.
279
+ */
280
+ async function retryCompletion(call, signal) {
281
+ let key;
282
+ for (let retry = 0;; retry++) {
283
+ try {
284
+ return await call(key);
285
+ }
286
+ catch (error) {
287
+ const delay = COMPLETE_RETRY_DELAYS_MS[retry];
288
+ const unknown = (error instanceof api_error_1.APIError && error.status === 503) ||
289
+ (error instanceof api_error_1.RequestError && error.response === undefined);
290
+ if (delay === undefined || !unknown || signal?.aborted)
291
+ throw error;
292
+ key ??= error.idempotencyKey;
293
+ await pause(delay, signal);
294
+ }
295
+ }
296
+ }
297
+ async function openLink(link, options) {
298
+ const label = options.label ?? 'Transfer';
299
+ let response;
300
+ try {
301
+ // identity: the bytes on the wire are the file's bytes, so the length checks hold.
302
+ response = await transferFetch(link.url, {
303
+ method: link.method ?? 'GET', headers: { ...requestHeaders(link.headers), 'Accept-Encoding': 'identity' },
304
+ signal: options.signal,
305
+ });
306
+ }
307
+ catch (error) {
308
+ if (options.signal?.aborted)
309
+ throw options.signal.reason ?? error;
310
+ throw new TransferError(describeFailure(`${label} download`, error));
311
+ }
312
+ if (!response.ok) {
313
+ await response.body?.cancel().catch(() => undefined);
314
+ throw new TransferError(`${label} download returned HTTP ${response.status}${refusalHint(response.status)}`, response.status);
315
+ }
316
+ return response;
317
+ }
318
+ // Counts the bytes, reports progress and fails the stream if it ends at a length other than the expected one.
319
+ function checkedBody(response, options) {
320
+ const label = options.label ?? 'Transfer';
321
+ const expected = options.size ?? declaredLength(response);
322
+ let received = 0;
323
+ const empty = new ReadableStream({ start(controller) { controller.close(); } });
324
+ return (response.body ?? empty).pipeThrough(new TransformStream({
325
+ transform(chunk, controller) {
326
+ received += chunk.byteLength;
327
+ if (expected !== undefined && received > expected) {
328
+ throw new TransferError(`${label} download is longer than the expected ${expected} bytes`);
329
+ }
330
+ controller.enqueue(chunk);
331
+ options.progress?.(received, expected);
332
+ },
333
+ flush() {
334
+ if (expected !== undefined && received !== expected) {
335
+ throw new TransferError(`${label} download ended after ${received} of ${expected} bytes`);
336
+ }
337
+ },
338
+ }));
339
+ }
340
+ // Content-Length counts encoded bytes, so it is the expected length only for an unencoded body.
341
+ function declaredLength(response) {
342
+ const length = response.headers.get('content-length');
343
+ if (length === null || !/^[0-9]+$/.test(length) || response.headers.has('content-encoding'))
344
+ return undefined;
345
+ return Number(length);
346
+ }
347
+ /** Stream a download. The stream errors if the body does not match `size`. */
348
+ async function downloadStream(link, options = {}) {
349
+ return checkedBody(await openLink(link, options), options);
350
+ }
351
+ const stopBody = (response) => response.body?.cancel().catch(() => undefined);
352
+ /** Download to `destination` through `<destination>.part-<random>`, renaming only after the full length is on disk. */
353
+ async function downloadToFile(link, destination, options = {}) {
354
+ const [fs, paths, crypto, stream] = await Promise.all([
355
+ import('node:fs/promises'), import('node:path'), import('node:crypto'), import('node:stream'),
356
+ ]);
357
+ const response = await openLink(link, options);
358
+ const temporary = `${destination}.part-${crypto.randomBytes(6).toString('hex')}`;
359
+ let handle;
360
+ try {
361
+ await fs.mkdir(paths.dirname(destination), { recursive: true });
362
+ // The file keeps the mode of the one it replaces, set before any byte is written so a private
363
+ // file is never readable through its replacement; a new file has the default mode of a plain write.
364
+ const existing = await fs.stat(destination).catch(() => undefined);
365
+ handle = await fs.open(temporary, 'wx', existing ? existing.mode & 0o7777 : 0o666);
366
+ if (existing)
367
+ await handle.chmod(existing.mode & 0o7777);
368
+ const body = checkedBody(response, options);
369
+ // The stream owns the handle from here and closes it when it ends or fails.
370
+ const output = handle.createWriteStream();
371
+ handle = undefined;
372
+ await stream.promises.pipeline(stream.Readable.fromWeb(body), output, { signal: options.signal });
373
+ const synced = await fs.open(temporary, 'r');
374
+ try {
375
+ await synced.sync();
376
+ }
377
+ finally {
378
+ await synced.close();
379
+ }
380
+ await fs.rename(temporary, destination);
381
+ }
382
+ catch (error) {
383
+ // Nothing reads the body when setup fails; a body already piped is cancelled by the pipeline.
384
+ await stopBody(response);
385
+ await handle?.close().catch(() => undefined);
386
+ await fs.rm(temporary, { force: true });
387
+ throw error;
388
+ }
389
+ }