@kindgi/api 0.0.0-bootstrap.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +216 -1
  3. package/dist/adapter-binding.d.ts +177 -0
  4. package/dist/adapter-binding.d.ts.map +1 -0
  5. package/dist/adapter-binding.js +12 -0
  6. package/dist/adapter-binding.js.map +1 -0
  7. package/dist/agent-binding.d.ts +207 -0
  8. package/dist/agent-binding.d.ts.map +1 -0
  9. package/dist/agent-binding.js +4 -0
  10. package/dist/agent-binding.js.map +1 -0
  11. package/dist/app.d.ts +770 -0
  12. package/dist/app.d.ts.map +1 -0
  13. package/dist/app.js +397 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/capability-binding.d.ts +76 -0
  16. package/dist/capability-binding.d.ts.map +1 -0
  17. package/dist/capability-binding.js +4 -0
  18. package/dist/capability-binding.js.map +1 -0
  19. package/dist/cost-binding.d.ts +175 -0
  20. package/dist/cost-binding.d.ts.map +1 -0
  21. package/dist/cost-binding.js +13 -0
  22. package/dist/cost-binding.js.map +1 -0
  23. package/dist/deployment-binding.d.ts +201 -0
  24. package/dist/deployment-binding.d.ts.map +1 -0
  25. package/dist/deployment-binding.js +4 -0
  26. package/dist/deployment-binding.js.map +1 -0
  27. package/dist/env-binding.d.ts +132 -0
  28. package/dist/env-binding.d.ts.map +1 -0
  29. package/dist/env-binding.js +4 -0
  30. package/dist/env-binding.js.map +1 -0
  31. package/dist/errors.d.ts +37 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +268 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/eval-run-binding.d.ts +196 -0
  36. package/dist/eval-run-binding.d.ts.map +1 -0
  37. package/dist/eval-run-binding.js +16 -0
  38. package/dist/eval-run-binding.js.map +1 -0
  39. package/dist/eval-run-dispatcher.d.ts +131 -0
  40. package/dist/eval-run-dispatcher.d.ts.map +1 -0
  41. package/dist/eval-run-dispatcher.js +368 -0
  42. package/dist/eval-run-dispatcher.js.map +1 -0
  43. package/dist/eval-suite-binding.d.ts +227 -0
  44. package/dist/eval-suite-binding.d.ts.map +1 -0
  45. package/dist/eval-suite-binding.js +24 -0
  46. package/dist/eval-suite-binding.js.map +1 -0
  47. package/dist/event-bus-binding.d.ts +107 -0
  48. package/dist/event-bus-binding.d.ts.map +1 -0
  49. package/dist/event-bus-binding.js +5 -0
  50. package/dist/event-bus-binding.js.map +1 -0
  51. package/dist/flow-binding.d.ts +194 -0
  52. package/dist/flow-binding.d.ts.map +1 -0
  53. package/dist/flow-binding.js +4 -0
  54. package/dist/flow-binding.js.map +1 -0
  55. package/dist/guardrail-binding.d.ts +138 -0
  56. package/dist/guardrail-binding.d.ts.map +1 -0
  57. package/dist/guardrail-binding.js +4 -0
  58. package/dist/guardrail-binding.js.map +1 -0
  59. package/dist/handler-binding.d.ts +126 -0
  60. package/dist/handler-binding.d.ts.map +1 -0
  61. package/dist/handler-binding.js +4 -0
  62. package/dist/handler-binding.js.map +1 -0
  63. package/dist/hitl-binding.d.ts +115 -0
  64. package/dist/hitl-binding.d.ts.map +1 -0
  65. package/dist/hitl-binding.js +4 -0
  66. package/dist/hitl-binding.js.map +1 -0
  67. package/dist/identity-directory-binding.d.ts +116 -0
  68. package/dist/identity-directory-binding.d.ts.map +1 -0
  69. package/dist/identity-directory-binding.js +4 -0
  70. package/dist/identity-directory-binding.js.map +1 -0
  71. package/dist/identity-provider-binding.d.ts +184 -0
  72. package/dist/identity-provider-binding.d.ts.map +1 -0
  73. package/dist/identity-provider-binding.js +4 -0
  74. package/dist/identity-provider-binding.js.map +1 -0
  75. package/dist/image-registry-binding.d.ts +165 -0
  76. package/dist/image-registry-binding.d.ts.map +1 -0
  77. package/dist/image-registry-binding.js +4 -0
  78. package/dist/image-registry-binding.js.map +1 -0
  79. package/dist/index.d.ts +72 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +26 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/key-management-binding.d.ts +101 -0
  84. package/dist/key-management-binding.d.ts.map +1 -0
  85. package/dist/key-management-binding.js +4 -0
  86. package/dist/key-management-binding.js.map +1 -0
  87. package/dist/mcp-endpoint-binding.d.ts +312 -0
  88. package/dist/mcp-endpoint-binding.d.ts.map +1 -0
  89. package/dist/mcp-endpoint-binding.js +12 -0
  90. package/dist/mcp-endpoint-binding.js.map +1 -0
  91. package/dist/memory-binding.d.ts +209 -0
  92. package/dist/memory-binding.d.ts.map +1 -0
  93. package/dist/memory-binding.js +4 -0
  94. package/dist/memory-binding.js.map +1 -0
  95. package/dist/middleware/auth.d.ts +168 -0
  96. package/dist/middleware/auth.d.ts.map +1 -0
  97. package/dist/middleware/auth.js +247 -0
  98. package/dist/middleware/auth.js.map +1 -0
  99. package/dist/middleware/authorize.d.ts +26 -0
  100. package/dist/middleware/authorize.d.ts.map +1 -0
  101. package/dist/middleware/authorize.js +65 -0
  102. package/dist/middleware/authorize.js.map +1 -0
  103. package/dist/middleware/error-mapper.d.ts +20 -0
  104. package/dist/middleware/error-mapper.d.ts.map +1 -0
  105. package/dist/middleware/error-mapper.js +34 -0
  106. package/dist/middleware/error-mapper.js.map +1 -0
  107. package/dist/middleware/idempotency.d.ts +43 -0
  108. package/dist/middleware/idempotency.d.ts.map +1 -0
  109. package/dist/middleware/idempotency.js +118 -0
  110. package/dist/middleware/idempotency.js.map +1 -0
  111. package/dist/middleware/principal.d.ts +4 -0
  112. package/dist/middleware/principal.d.ts.map +1 -0
  113. package/dist/middleware/principal.js +42 -0
  114. package/dist/middleware/principal.js.map +1 -0
  115. package/dist/middleware/public-run-routes.d.ts +16 -0
  116. package/dist/middleware/public-run-routes.d.ts.map +1 -0
  117. package/dist/middleware/public-run-routes.js +43 -0
  118. package/dist/middleware/public-run-routes.js.map +1 -0
  119. package/dist/middleware/request-id.d.ts +14 -0
  120. package/dist/middleware/request-id.d.ts.map +1 -0
  121. package/dist/middleware/request-id.js +24 -0
  122. package/dist/middleware/request-id.js.map +1 -0
  123. package/dist/middleware/sigv4-verify.d.ts +64 -0
  124. package/dist/middleware/sigv4-verify.d.ts.map +1 -0
  125. package/dist/middleware/sigv4-verify.js +286 -0
  126. package/dist/middleware/sigv4-verify.js.map +1 -0
  127. package/dist/middleware/sigv4.d.ts +25 -0
  128. package/dist/middleware/sigv4.d.ts.map +1 -0
  129. package/dist/middleware/sigv4.js +120 -0
  130. package/dist/middleware/sigv4.js.map +1 -0
  131. package/dist/openapi/generate.d.ts +15 -0
  132. package/dist/openapi/generate.d.ts.map +1 -0
  133. package/dist/openapi/generate.js +241 -0
  134. package/dist/openapi/generate.js.map +1 -0
  135. package/dist/openapi/operations.d.ts +70 -0
  136. package/dist/openapi/operations.d.ts.map +1 -0
  137. package/dist/openapi/operations.js +5050 -0
  138. package/dist/openapi/operations.js.map +1 -0
  139. package/dist/openapi/schemas.d.ts +590 -0
  140. package/dist/openapi/schemas.d.ts.map +1 -0
  141. package/dist/openapi/schemas.js +5820 -0
  142. package/dist/openapi/schemas.js.map +1 -0
  143. package/dist/provenance-binding.d.ts +116 -0
  144. package/dist/provenance-binding.d.ts.map +1 -0
  145. package/dist/provenance-binding.js +31 -0
  146. package/dist/provenance-binding.js.map +1 -0
  147. package/dist/provider-binding.d.ts +174 -0
  148. package/dist/provider-binding.d.ts.map +1 -0
  149. package/dist/provider-binding.js +4 -0
  150. package/dist/provider-binding.js.map +1 -0
  151. package/dist/public-run-token.d.ts +97 -0
  152. package/dist/public-run-token.d.ts.map +1 -0
  153. package/dist/public-run-token.js +167 -0
  154. package/dist/public-run-token.js.map +1 -0
  155. package/dist/retention-binding.d.ts +69 -0
  156. package/dist/retention-binding.d.ts.map +1 -0
  157. package/dist/retention-binding.js +4 -0
  158. package/dist/retention-binding.js.map +1 -0
  159. package/dist/reviewer-binding.d.ts +84 -0
  160. package/dist/reviewer-binding.d.ts.map +1 -0
  161. package/dist/reviewer-binding.js +4 -0
  162. package/dist/reviewer-binding.js.map +1 -0
  163. package/dist/rotation-status-store.d.ts +96 -0
  164. package/dist/rotation-status-store.d.ts.map +1 -0
  165. package/dist/rotation-status-store.js +106 -0
  166. package/dist/rotation-status-store.js.map +1 -0
  167. package/dist/routes/adapters.d.ts +29 -0
  168. package/dist/routes/adapters.d.ts.map +1 -0
  169. package/dist/routes/adapters.js +230 -0
  170. package/dist/routes/adapters.js.map +1 -0
  171. package/dist/routes/agents.d.ts +17 -0
  172. package/dist/routes/agents.d.ts.map +1 -0
  173. package/dist/routes/agents.js +342 -0
  174. package/dist/routes/agents.js.map +1 -0
  175. package/dist/routes/approvals.d.ts +37 -0
  176. package/dist/routes/approvals.d.ts.map +1 -0
  177. package/dist/routes/approvals.js +551 -0
  178. package/dist/routes/approvals.js.map +1 -0
  179. package/dist/routes/artifacts.d.ts +25 -0
  180. package/dist/routes/artifacts.d.ts.map +1 -0
  181. package/dist/routes/artifacts.js +265 -0
  182. package/dist/routes/artifacts.js.map +1 -0
  183. package/dist/routes/audit.d.ts +6 -0
  184. package/dist/routes/audit.d.ts.map +1 -0
  185. package/dist/routes/audit.js +162 -0
  186. package/dist/routes/audit.js.map +1 -0
  187. package/dist/routes/auth.d.ts +47 -0
  188. package/dist/routes/auth.d.ts.map +1 -0
  189. package/dist/routes/auth.js +630 -0
  190. package/dist/routes/auth.js.map +1 -0
  191. package/dist/routes/capabilities.d.ts +14 -0
  192. package/dist/routes/capabilities.d.ts.map +1 -0
  193. package/dist/routes/capabilities.js +62 -0
  194. package/dist/routes/capabilities.js.map +1 -0
  195. package/dist/routes/compliance.d.ts +37 -0
  196. package/dist/routes/compliance.d.ts.map +1 -0
  197. package/dist/routes/compliance.js +321 -0
  198. package/dist/routes/compliance.js.map +1 -0
  199. package/dist/routes/conversations.d.ts +13 -0
  200. package/dist/routes/conversations.d.ts.map +1 -0
  201. package/dist/routes/conversations.js +295 -0
  202. package/dist/routes/conversations.js.map +1 -0
  203. package/dist/routes/cost.d.ts +24 -0
  204. package/dist/routes/cost.d.ts.map +1 -0
  205. package/dist/routes/cost.js +243 -0
  206. package/dist/routes/cost.js.map +1 -0
  207. package/dist/routes/deployments.d.ts +122 -0
  208. package/dist/routes/deployments.d.ts.map +1 -0
  209. package/dist/routes/deployments.js +1036 -0
  210. package/dist/routes/deployments.js.map +1 -0
  211. package/dist/routes/env.d.ts +62 -0
  212. package/dist/routes/env.d.ts.map +1 -0
  213. package/dist/routes/env.js +311 -0
  214. package/dist/routes/env.js.map +1 -0
  215. package/dist/routes/eval-runs.d.ts +28 -0
  216. package/dist/routes/eval-runs.d.ts.map +1 -0
  217. package/dist/routes/eval-runs.js +479 -0
  218. package/dist/routes/eval-runs.js.map +1 -0
  219. package/dist/routes/eval-suites.d.ts +24 -0
  220. package/dist/routes/eval-suites.d.ts.map +1 -0
  221. package/dist/routes/eval-suites.js +381 -0
  222. package/dist/routes/eval-suites.js.map +1 -0
  223. package/dist/routes/event-triggers.d.ts +12 -0
  224. package/dist/routes/event-triggers.d.ts.map +1 -0
  225. package/dist/routes/event-triggers.js +218 -0
  226. package/dist/routes/event-triggers.js.map +1 -0
  227. package/dist/routes/flows.d.ts +23 -0
  228. package/dist/routes/flows.d.ts.map +1 -0
  229. package/dist/routes/flows.js +344 -0
  230. package/dist/routes/flows.js.map +1 -0
  231. package/dist/routes/guardrails.d.ts +33 -0
  232. package/dist/routes/guardrails.d.ts.map +1 -0
  233. package/dist/routes/guardrails.js +236 -0
  234. package/dist/routes/guardrails.js.map +1 -0
  235. package/dist/routes/identity.d.ts +39 -0
  236. package/dist/routes/identity.d.ts.map +1 -0
  237. package/dist/routes/identity.js +138 -0
  238. package/dist/routes/identity.js.map +1 -0
  239. package/dist/routes/mcp.d.ts +23 -0
  240. package/dist/routes/mcp.d.ts.map +1 -0
  241. package/dist/routes/mcp.js +727 -0
  242. package/dist/routes/mcp.js.map +1 -0
  243. package/dist/routes/memory.d.ts +16 -0
  244. package/dist/routes/memory.d.ts.map +1 -0
  245. package/dist/routes/memory.js +353 -0
  246. package/dist/routes/memory.js.map +1 -0
  247. package/dist/routes/observations.d.ts +19 -0
  248. package/dist/routes/observations.d.ts.map +1 -0
  249. package/dist/routes/observations.js +135 -0
  250. package/dist/routes/observations.js.map +1 -0
  251. package/dist/routes/orgs.d.ts +24 -0
  252. package/dist/routes/orgs.d.ts.map +1 -0
  253. package/dist/routes/orgs.js +208 -0
  254. package/dist/routes/orgs.js.map +1 -0
  255. package/dist/routes/pagination.d.ts +18 -0
  256. package/dist/routes/pagination.d.ts.map +1 -0
  257. package/dist/routes/pagination.js +35 -0
  258. package/dist/routes/pagination.js.map +1 -0
  259. package/dist/routes/policies.d.ts +23 -0
  260. package/dist/routes/policies.d.ts.map +1 -0
  261. package/dist/routes/policies.js +314 -0
  262. package/dist/routes/policies.js.map +1 -0
  263. package/dist/routes/projects.d.ts +45 -0
  264. package/dist/routes/projects.d.ts.map +1 -0
  265. package/dist/routes/projects.js +485 -0
  266. package/dist/routes/projects.js.map +1 -0
  267. package/dist/routes/proposals.d.ts +24 -0
  268. package/dist/routes/proposals.d.ts.map +1 -0
  269. package/dist/routes/proposals.js +581 -0
  270. package/dist/routes/proposals.js.map +1 -0
  271. package/dist/routes/provenance.d.ts +34 -0
  272. package/dist/routes/provenance.d.ts.map +1 -0
  273. package/dist/routes/provenance.js +274 -0
  274. package/dist/routes/provenance.js.map +1 -0
  275. package/dist/routes/providers.d.ts +32 -0
  276. package/dist/routes/providers.d.ts.map +1 -0
  277. package/dist/routes/providers.js +490 -0
  278. package/dist/routes/providers.js.map +1 -0
  279. package/dist/routes/public-run-tokens.d.ts +17 -0
  280. package/dist/routes/public-run-tokens.d.ts.map +1 -0
  281. package/dist/routes/public-run-tokens.js +69 -0
  282. package/dist/routes/public-run-tokens.js.map +1 -0
  283. package/dist/routes/retention.d.ts +19 -0
  284. package/dist/routes/retention.d.ts.map +1 -0
  285. package/dist/routes/retention.js +152 -0
  286. package/dist/routes/retention.js.map +1 -0
  287. package/dist/routes/reviewers.d.ts +5 -0
  288. package/dist/routes/reviewers.d.ts.map +1 -0
  289. package/dist/routes/reviewers.js +161 -0
  290. package/dist/routes/reviewers.js.map +1 -0
  291. package/dist/routes/runs.d.ts +34 -0
  292. package/dist/routes/runs.d.ts.map +1 -0
  293. package/dist/routes/runs.js +705 -0
  294. package/dist/routes/runs.js.map +1 -0
  295. package/dist/routes/s3.d.ts +31 -0
  296. package/dist/routes/s3.d.ts.map +1 -0
  297. package/dist/routes/s3.js +433 -0
  298. package/dist/routes/s3.js.map +1 -0
  299. package/dist/routes/schedules.d.ts +20 -0
  300. package/dist/routes/schedules.d.ts.map +1 -0
  301. package/dist/routes/schedules.js +234 -0
  302. package/dist/routes/schedules.js.map +1 -0
  303. package/dist/routes/scope-params.d.ts +57 -0
  304. package/dist/routes/scope-params.d.ts.map +1 -0
  305. package/dist/routes/scope-params.js +105 -0
  306. package/dist/routes/scope-params.js.map +1 -0
  307. package/dist/routes/secret-ref.d.ts +20 -0
  308. package/dist/routes/secret-ref.d.ts.map +1 -0
  309. package/dist/routes/secret-ref.js +42 -0
  310. package/dist/routes/secret-ref.js.map +1 -0
  311. package/dist/routes/secrets.d.ts +53 -0
  312. package/dist/routes/secrets.d.ts.map +1 -0
  313. package/dist/routes/secrets.js +715 -0
  314. package/dist/routes/secrets.js.map +1 -0
  315. package/dist/routes/signing-keys.d.ts +23 -0
  316. package/dist/routes/signing-keys.d.ts.map +1 -0
  317. package/dist/routes/signing-keys.js +212 -0
  318. package/dist/routes/signing-keys.js.map +1 -0
  319. package/dist/routes/sse.d.ts +58 -0
  320. package/dist/routes/sse.d.ts.map +1 -0
  321. package/dist/routes/sse.js +92 -0
  322. package/dist/routes/sse.js.map +1 -0
  323. package/dist/routes/teams.d.ts +30 -0
  324. package/dist/routes/teams.d.ts.map +1 -0
  325. package/dist/routes/teams.js +443 -0
  326. package/dist/routes/teams.js.map +1 -0
  327. package/dist/routes/tenant.d.ts +57 -0
  328. package/dist/routes/tenant.d.ts.map +1 -0
  329. package/dist/routes/tenant.js +352 -0
  330. package/dist/routes/tenant.js.map +1 -0
  331. package/dist/routes/tokens.d.ts +14 -0
  332. package/dist/routes/tokens.d.ts.map +1 -0
  333. package/dist/routes/tokens.js +231 -0
  334. package/dist/routes/tokens.js.map +1 -0
  335. package/dist/routes/tools.d.ts +33 -0
  336. package/dist/routes/tools.d.ts.map +1 -0
  337. package/dist/routes/tools.js +380 -0
  338. package/dist/routes/tools.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +10 -0
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -0
  341. package/dist/routes/webhook-endpoints.js +407 -0
  342. package/dist/routes/webhook-endpoints.js.map +1 -0
  343. package/dist/routes/webhooks.d.ts +21 -0
  344. package/dist/routes/webhooks.d.ts.map +1 -0
  345. package/dist/routes/webhooks.js +228 -0
  346. package/dist/routes/webhooks.js.map +1 -0
  347. package/dist/s3-credential-binding.d.ts +54 -0
  348. package/dist/s3-credential-binding.d.ts.map +1 -0
  349. package/dist/s3-credential-binding.js +4 -0
  350. package/dist/s3-credential-binding.js.map +1 -0
  351. package/dist/secrets-binding.d.ts +281 -0
  352. package/dist/secrets-binding.d.ts.map +1 -0
  353. package/dist/secrets-binding.js +10 -0
  354. package/dist/secrets-binding.js.map +1 -0
  355. package/dist/secrets-provider-binding.d.ts +164 -0
  356. package/dist/secrets-provider-binding.d.ts.map +1 -0
  357. package/dist/secrets-provider-binding.js +4 -0
  358. package/dist/secrets-provider-binding.js.map +1 -0
  359. package/dist/session-store-binding.d.ts +148 -0
  360. package/dist/session-store-binding.d.ts.map +1 -0
  361. package/dist/session-store-binding.js +4 -0
  362. package/dist/session-store-binding.js.map +1 -0
  363. package/dist/signing-key-binding.d.ts +210 -0
  364. package/dist/signing-key-binding.d.ts.map +1 -0
  365. package/dist/signing-key-binding.js +4 -0
  366. package/dist/signing-key-binding.js.map +1 -0
  367. package/dist/state-store-binding.d.ts +53 -0
  368. package/dist/state-store-binding.d.ts.map +1 -0
  369. package/dist/state-store-binding.js +38 -0
  370. package/dist/state-store-binding.js.map +1 -0
  371. package/dist/supervisor-binding.d.ts +526 -0
  372. package/dist/supervisor-binding.d.ts.map +1 -0
  373. package/dist/supervisor-binding.js +4 -0
  374. package/dist/supervisor-binding.js.map +1 -0
  375. package/dist/tenant-host-access.d.ts +41 -0
  376. package/dist/tenant-host-access.d.ts.map +1 -0
  377. package/dist/tenant-host-access.js +42 -0
  378. package/dist/tenant-host-access.js.map +1 -0
  379. package/dist/token-admin.d.ts +99 -0
  380. package/dist/token-admin.d.ts.map +1 -0
  381. package/dist/token-admin.js +4 -0
  382. package/dist/token-admin.js.map +1 -0
  383. package/dist/tool-binding.d.ts +247 -0
  384. package/dist/tool-binding.d.ts.map +1 -0
  385. package/dist/tool-binding.js +4 -0
  386. package/dist/tool-binding.js.map +1 -0
  387. package/dist/trigger-binding.d.ts +13 -0
  388. package/dist/trigger-binding.d.ts.map +1 -0
  389. package/dist/trigger-binding.js +4 -0
  390. package/dist/trigger-binding.js.map +1 -0
  391. package/dist/types.d.ts +71 -0
  392. package/dist/types.d.ts.map +1 -0
  393. package/dist/types.js +4 -0
  394. package/dist/types.js.map +1 -0
  395. package/dist/webhook-endpoint-binding.d.ts +230 -0
  396. package/dist/webhook-endpoint-binding.d.ts.map +1 -0
  397. package/dist/webhook-endpoint-binding.js +12 -0
  398. package/dist/webhook-endpoint-binding.js.map +1 -0
  399. package/dist/xml.d.ts +79 -0
  400. package/dist/xml.d.ts.map +1 -0
  401. package/dist/xml.js +115 -0
  402. package/dist/xml.js.map +1 -0
  403. package/openapi.json +29649 -0
  404. package/package.json +76 -4
  405. package/scripts/emit-openapi.mjs +44 -0
  406. package/src/adapter-binding.ts +204 -0
  407. package/src/agent-binding.ts +231 -0
  408. package/src/app.ts +1286 -0
  409. package/src/capability-binding.ts +83 -0
  410. package/src/cost-binding.ts +213 -0
  411. package/src/deployment-binding.ts +225 -0
  412. package/src/env-binding.ts +140 -0
  413. package/src/errors.ts +295 -0
  414. package/src/eval-run-binding.ts +209 -0
  415. package/src/eval-run-dispatcher.ts +497 -0
  416. package/src/eval-suite-binding.ts +257 -0
  417. package/src/event-bus-binding.ts +127 -0
  418. package/src/flow-binding.ts +213 -0
  419. package/src/guardrail-binding.ts +151 -0
  420. package/src/handler-binding.ts +132 -0
  421. package/src/hitl-binding.ts +172 -0
  422. package/src/identity-directory-binding.ts +128 -0
  423. package/src/identity-provider-binding.ts +203 -0
  424. package/src/image-registry-binding.ts +193 -0
  425. package/src/index.ts +606 -0
  426. package/src/key-management-binding.ts +91 -0
  427. package/src/mcp-endpoint-binding.ts +311 -0
  428. package/src/memory-binding.ts +239 -0
  429. package/src/middleware/auth.ts +437 -0
  430. package/src/middleware/authorize.ts +125 -0
  431. package/src/middleware/error-mapper.ts +40 -0
  432. package/src/middleware/idempotency.ts +160 -0
  433. package/src/middleware/principal.ts +64 -0
  434. package/src/middleware/public-run-routes.ts +50 -0
  435. package/src/middleware/request-id.ts +28 -0
  436. package/src/middleware/sigv4-verify.ts +374 -0
  437. package/src/middleware/sigv4.ts +165 -0
  438. package/src/openapi/generate.ts +307 -0
  439. package/src/openapi/operations.ts +5444 -0
  440. package/src/openapi/schemas.ts +6363 -0
  441. package/src/provenance-binding.ts +169 -0
  442. package/src/provider-binding.ts +196 -0
  443. package/src/public-run-token.ts +263 -0
  444. package/src/retention-binding.ts +78 -0
  445. package/src/reviewer-binding.ts +99 -0
  446. package/src/rotation-status-store.ts +209 -0
  447. package/src/routes/adapters.ts +319 -0
  448. package/src/routes/agents.ts +424 -0
  449. package/src/routes/approvals.ts +759 -0
  450. package/src/routes/artifacts.ts +317 -0
  451. package/src/routes/audit.ts +219 -0
  452. package/src/routes/auth.ts +806 -0
  453. package/src/routes/capabilities.ts +79 -0
  454. package/src/routes/compliance.ts +482 -0
  455. package/src/routes/conversations.ts +369 -0
  456. package/src/routes/cost.ts +327 -0
  457. package/src/routes/deployments.ts +1493 -0
  458. package/src/routes/env.ts +429 -0
  459. package/src/routes/eval-runs.ts +631 -0
  460. package/src/routes/eval-suites.ts +490 -0
  461. package/src/routes/event-triggers.ts +283 -0
  462. package/src/routes/flows.ts +423 -0
  463. package/src/routes/guardrails.ts +320 -0
  464. package/src/routes/identity.ts +203 -0
  465. package/src/routes/mcp.ts +940 -0
  466. package/src/routes/memory.ts +430 -0
  467. package/src/routes/observations.ts +175 -0
  468. package/src/routes/orgs.ts +273 -0
  469. package/src/routes/pagination.ts +51 -0
  470. package/src/routes/policies.ts +413 -0
  471. package/src/routes/projects.ts +634 -0
  472. package/src/routes/proposals.ts +719 -0
  473. package/src/routes/provenance.ts +406 -0
  474. package/src/routes/providers.ts +624 -0
  475. package/src/routes/public-run-tokens.ts +104 -0
  476. package/src/routes/retention.ts +193 -0
  477. package/src/routes/reviewers.ts +209 -0
  478. package/src/routes/runs.ts +892 -0
  479. package/src/routes/s3.ts +519 -0
  480. package/src/routes/schedules.ts +300 -0
  481. package/src/routes/scope-params.ts +133 -0
  482. package/src/routes/secret-ref.ts +52 -0
  483. package/src/routes/secrets.ts +975 -0
  484. package/src/routes/signing-keys.ts +259 -0
  485. package/src/routes/sse.ts +148 -0
  486. package/src/routes/teams.ts +584 -0
  487. package/src/routes/tenant.ts +530 -0
  488. package/src/routes/tokens.ts +285 -0
  489. package/src/routes/tools.ts +491 -0
  490. package/src/routes/webhook-endpoints.ts +534 -0
  491. package/src/routes/webhooks.ts +296 -0
  492. package/src/s3-credential-binding.ts +58 -0
  493. package/src/secrets-binding.ts +308 -0
  494. package/src/secrets-provider-binding.ts +167 -0
  495. package/src/session-store-binding.ts +163 -0
  496. package/src/signing-key-binding.ts +235 -0
  497. package/src/state-store-binding.ts +84 -0
  498. package/src/supervisor-binding.ts +554 -0
  499. package/src/tenant-host-access.ts +62 -0
  500. package/src/token-admin.ts +104 -0
  501. package/src/tool-binding.ts +274 -0
  502. package/src/trigger-binding.ts +38 -0
  503. package/src/types.ts +74 -0
  504. package/src/webhook-endpoint-binding.ts +246 -0
  505. package/src/xml.ts +196 -0
@@ -0,0 +1,519 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import { createHash } from 'node:crypto';
5
+
6
+ import { Hono } from 'hono';
7
+
8
+ import type { TenantId } from '@kindgi/types';
9
+
10
+ import type { BlobMeta, BlobStorageBinding } from '@kindgi/blob-binding';
11
+ import type { AppEnv } from '../types.js';
12
+ import {
13
+ completeMultipartUploadResultXml,
14
+ errorXml,
15
+ initiateMultipartUploadResultXml,
16
+ listBucketResultXml,
17
+ listPartsResultXml,
18
+ parseCompleteMultipartUploadXml,
19
+ } from '../xml.js';
20
+
21
+ /**
22
+ * AWS S3-compat wire surface (core). Mounted at `/s3` OUTSIDE
23
+ * the `/v1/*` Bearer chain — S3 auth is SigV4, wired in the
24
+ * `sigv4Middleware` that gates this router.
25
+ *
26
+ * Storage flows through the same `BlobStorageBinding` as the bespoke
27
+ * `/v1/artifacts/*` surface — cross-surface interop is a first-class
28
+ * guardrail.
29
+ *
30
+ * ## Routes in this router
31
+ *
32
+ * HEAD /:bucket — bucket existence probe
33
+ * GET /:bucket — ListObjectsV2 (?list-type=2)
34
+ * PUT /:bucket/* — put object (raw body)
35
+ * GET /:bucket/* — get object (stream, Range)
36
+ * HEAD /:bucket/* — head object (headers only)
37
+ * DELETE /:bucket/* — delete object (204)
38
+ *
39
+ * Multipart upload shares those paths, selected by query parameters:
40
+ *
41
+ * POST /:bucket/*?uploads — InitiateMultipartUpload
42
+ * PUT /:bucket/*?partNumber=&uploadId= — UploadPart
43
+ * GET /:bucket/*?uploadId= — ListParts
44
+ * POST /:bucket/*?uploadId= — CompleteMultipartUpload
45
+ * DELETE /:bucket/*?uploadId= — AbortMultipartUpload
46
+ */
47
+ export function s3Router(binding: BlobStorageBinding): Hono<AppEnv> {
48
+ const r = new Hono<AppEnv>();
49
+
50
+ // ---------- HEAD /:bucket (bucket existence probe) ----------
51
+ r.on('HEAD', '/:bucket', async () => {
52
+ // Middleware has already verified the caller's credential is
53
+ // authorized for this exact bucket, so we just 200 with empty
54
+ // body. AWS returns 200 + no body for existing buckets.
55
+ return new Response(null, { status: 200 });
56
+ });
57
+
58
+ // ---------- GET /:bucket (ListObjectsV2) ----------
59
+ r.get('/:bucket', async (c) => {
60
+ const tenantId = c.get('tenantId') as TenantId;
61
+ const bucket = c.req.param('bucket');
62
+ if (bucket === undefined) return xml(c, errorXml('InvalidRequest', 'bucket missing'), 400);
63
+
64
+ // HEAD /:bucket dispatches through this handler per Hono's built-in
65
+ // HEAD→GET translation. For a bare `HEAD` (no query params), return
66
+ // an empty 200 body — the "bucket exists" probe. Hono strips the
67
+ // body from the outbound Response automatically.
68
+ if (c.req.method === 'HEAD') {
69
+ return new Response(null, { status: 200 });
70
+ }
71
+
72
+ // S3 spec: ?list-type=2 is required for the v2 listing. Anything
73
+ // else is treated as v1 which we don't implement — reject.
74
+ const listType = c.req.query('list-type');
75
+ if (listType !== '2') {
76
+ return xml(
77
+ c,
78
+ errorXml(
79
+ 'NotImplemented',
80
+ 'Only ListObjectsV2 (?list-type=2) is supported in this deployment',
81
+ ),
82
+ 501,
83
+ );
84
+ }
85
+
86
+ const prefix = c.req.query('prefix') ?? '';
87
+ const continuationToken = c.req.query('continuation-token');
88
+ const maxKeysRaw = c.req.query('max-keys');
89
+ const maxKeys = maxKeysRaw !== undefined ? Number.parseInt(maxKeysRaw, 10) : 1000;
90
+ if (Number.isNaN(maxKeys) || maxKeys < 1) {
91
+ return xml(c, errorXml('InvalidArgument', 'max-keys must be a positive integer'), 400);
92
+ }
93
+
94
+ const outcome = await binding.listByPrefix(
95
+ tenantId,
96
+ bucket,
97
+ prefix,
98
+ continuationToken,
99
+ Math.min(maxKeys, 1000),
100
+ );
101
+ if (outcome.kind === 'err') {
102
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
103
+ }
104
+ const body = listBucketResultXml({
105
+ bucket,
106
+ prefix,
107
+ maxKeys: Math.min(maxKeys, 1000),
108
+ isTruncated: outcome.value.isTruncated,
109
+ ...(continuationToken !== undefined && { continuationToken }),
110
+ ...(outcome.value.nextContinuationToken !== undefined && {
111
+ nextContinuationToken: outcome.value.nextContinuationToken,
112
+ }),
113
+ contents: outcome.value.contents.map((m) => ({
114
+ key: m.key ?? (m.blobId as unknown as string),
115
+ lastModified: m.createdAt as unknown as string,
116
+ etag: m.hash,
117
+ size: m.size,
118
+ })),
119
+ });
120
+ return xml(c, body, 200);
121
+ });
122
+
123
+ // ---------- POST /:bucket/*?uploads (InitiateMultipartUpload) ----------
124
+ // OR POST /:bucket/*?uploadId= (CompleteMultipartUpload)
125
+ r.post('/:bucket/*', async (c) => {
126
+ const tenantId = c.get('tenantId') as TenantId;
127
+ const bucket = c.req.param('bucket');
128
+ if (bucket === undefined) return xml(c, errorXml('InvalidRequest', 'bucket missing'), 400);
129
+ const key = extractKey(c.req.path, bucket);
130
+ if (key === null || key.length === 0) {
131
+ return xml(c, errorXml('InvalidRequest', 'key missing'), 400);
132
+ }
133
+
134
+ // `?uploads` (empty value) → initiate. `?uploadId=X` → complete.
135
+ const uploadsFlag = c.req.query('uploads');
136
+ const uploadId = c.req.query('uploadId');
137
+
138
+ if (uploadsFlag !== undefined) {
139
+ const contentType = c.req.header('content-type') ?? 'application/octet-stream';
140
+ const tagging = c.req.header('x-amz-tagging');
141
+ const tags = tagging !== undefined ? parseTagging(tagging) : undefined;
142
+ const outcome = await binding.initiateMultipartUpload(tenantId, bucket, key, {
143
+ contentType,
144
+ ...(tags !== undefined && { tags }),
145
+ });
146
+ if (outcome.kind === 'err') {
147
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
148
+ }
149
+ return xml(
150
+ c,
151
+ initiateMultipartUploadResultXml({
152
+ bucket,
153
+ key,
154
+ uploadId: outcome.value.uploadId,
155
+ }),
156
+ 200,
157
+ );
158
+ }
159
+
160
+ if (uploadId !== undefined) {
161
+ const body = await c.req.raw.text();
162
+ const parsed = parseCompleteMultipartUploadXml(body);
163
+ if (parsed === null) {
164
+ return xml(
165
+ c,
166
+ errorXml('MalformedXML', 'CompleteMultipartUpload body must contain ≥1 <Part>'),
167
+ 400,
168
+ );
169
+ }
170
+ const outcome = await binding.completeMultipartUpload(
171
+ tenantId,
172
+ bucket,
173
+ key,
174
+ uploadId,
175
+ parsed,
176
+ );
177
+ if (outcome.kind === 'err') {
178
+ if (outcome.error.code === 'blob-not-found') {
179
+ return xml(c, errorXml('NoSuchUpload', outcome.error.message), 404);
180
+ }
181
+ if (outcome.error.code === 'blob-hash-mismatch') {
182
+ return xml(c, errorXml('InvalidPart', outcome.error.message), 400);
183
+ }
184
+ if (outcome.error.code === 'blob-storage-error') {
185
+ return xml(c, errorXml('InvalidRequest', outcome.error.message), 400);
186
+ }
187
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
188
+ }
189
+ return xml(
190
+ c,
191
+ completeMultipartUploadResultXml({
192
+ bucket,
193
+ key,
194
+ etag: outcome.value.hash,
195
+ location: `/s3/${bucket}/${key}`,
196
+ }),
197
+ 200,
198
+ );
199
+ }
200
+
201
+ // POST with neither ?uploads nor ?uploadId is unsupported.
202
+ return xml(c, errorXml('NotImplemented', 'POST requires ?uploads or ?uploadId'), 501);
203
+ });
204
+
205
+ // ---------- PUT /:bucket/* (put object OR UploadPart) ----------
206
+ r.put('/:bucket/*', async (c) => {
207
+ const tenantId = c.get('tenantId') as TenantId;
208
+ const bucket = c.req.param('bucket');
209
+ if (bucket === undefined) return xml(c, errorXml('InvalidRequest', 'bucket missing'), 400);
210
+ const key = extractKey(c.req.path, bucket);
211
+ if (key === null || key.length === 0) {
212
+ return xml(c, errorXml('InvalidRequest', 'key missing'), 400);
213
+ }
214
+
215
+ // Multipart part upload: ?partNumber=N&uploadId=U.
216
+ const uploadId = c.req.query('uploadId');
217
+ const partNumberRaw = c.req.query('partNumber');
218
+ if (uploadId !== undefined && partNumberRaw !== undefined) {
219
+ const partNumber = Number.parseInt(partNumberRaw, 10);
220
+ if (!Number.isInteger(partNumber) || partNumber < 1 || partNumber > 10_000) {
221
+ return xml(
222
+ c,
223
+ errorXml('InvalidArgument', 'partNumber must be an integer in [1, 10000]'),
224
+ 400,
225
+ );
226
+ }
227
+ const partBytes = new Uint8Array(await c.req.raw.arrayBuffer());
228
+ const md5Header = c.req.header('content-md5');
229
+ if (md5Header !== undefined && md5Header.length > 0) {
230
+ const computed = createHash('md5').update(partBytes).digest('base64');
231
+ if (computed !== md5Header) {
232
+ return xml(
233
+ c,
234
+ errorXml('BadDigest', 'The Content-MD5 you specified did not match what we received.'),
235
+ 400,
236
+ );
237
+ }
238
+ }
239
+ const outcome = await binding.uploadPart(
240
+ tenantId,
241
+ bucket,
242
+ key,
243
+ uploadId,
244
+ partNumber,
245
+ partBytes,
246
+ );
247
+ if (outcome.kind === 'err') {
248
+ if (outcome.error.code === 'blob-not-found') {
249
+ return xml(c, errorXml('NoSuchUpload', outcome.error.message), 404);
250
+ }
251
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
252
+ }
253
+ return new Response(null, {
254
+ status: 200,
255
+ headers: { ETag: `"${outcome.value.etag}"` },
256
+ });
257
+ }
258
+
259
+ const bytes = new Uint8Array(await c.req.raw.arrayBuffer());
260
+
261
+ // Content-MD5 verification (optional per S3 spec).
262
+ const md5Header = c.req.header('content-md5');
263
+ if (md5Header !== undefined && md5Header.length > 0) {
264
+ const computed = createHash('md5').update(bytes).digest('base64');
265
+ if (computed !== md5Header) {
266
+ return xml(
267
+ c,
268
+ errorXml('BadDigest', 'The Content-MD5 you specified did not match what we received.'),
269
+ 400,
270
+ );
271
+ }
272
+ }
273
+
274
+ const contentType = c.req.header('content-type') ?? 'application/octet-stream';
275
+
276
+ // S3 x-amz-tagging: key1=val1&key2=val2 (URL-encoded).
277
+ const tagging = c.req.header('x-amz-tagging');
278
+ const tags = tagging !== undefined ? parseTagging(tagging) : undefined;
279
+
280
+ const outcome = await binding.putByKey(tenantId, bucket, key, {
281
+ name: key,
282
+ contentType,
283
+ bytes,
284
+ size: bytes.byteLength,
285
+ ...(tags !== undefined && { tags }),
286
+ });
287
+ if (outcome.kind === 'err') {
288
+ if (outcome.error.code === 'blob-hash-mismatch') {
289
+ return xml(c, errorXml('BadDigest', 'Content hash mismatch'), 400);
290
+ }
291
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
292
+ }
293
+ return new Response(null, {
294
+ status: 200,
295
+ headers: {
296
+ ETag: `"${outcome.value.hash}"`,
297
+ },
298
+ });
299
+ });
300
+
301
+ // ---------- GET /:bucket/* (get object OR ListParts, with optional Range) ----------
302
+ r.get('/:bucket/*', async (c) => {
303
+ const tenantId = c.get('tenantId') as TenantId;
304
+ const bucket = c.req.param('bucket');
305
+ if (bucket === undefined) return xml(c, errorXml('InvalidRequest', 'bucket missing'), 400);
306
+ const key = extractKey(c.req.path, bucket);
307
+ if (key === null || key.length === 0) {
308
+ return xml(c, errorXml('InvalidRequest', 'key missing'), 400);
309
+ }
310
+
311
+ // Multipart ListParts: ?uploadId=<id>.
312
+ const uploadId = c.req.query('uploadId');
313
+ if (uploadId !== undefined) {
314
+ const outcome = await binding.listParts(tenantId, bucket, key, uploadId);
315
+ if (outcome.kind === 'err') {
316
+ if (outcome.error.code === 'blob-not-found') {
317
+ return xml(c, errorXml('NoSuchUpload', outcome.error.message), 404);
318
+ }
319
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
320
+ }
321
+ return xml(
322
+ c,
323
+ listPartsResultXml({
324
+ bucket,
325
+ key,
326
+ uploadId,
327
+ parts: outcome.value.parts.map((p) => ({
328
+ partNumber: p.partNumber,
329
+ etag: p.etag,
330
+ size: p.size,
331
+ lastModified: p.lastModified as unknown as string,
332
+ })),
333
+ }),
334
+ 200,
335
+ );
336
+ }
337
+
338
+ const outcome = await binding.getByKey(tenantId, bucket, key);
339
+ if (outcome.kind === 'err') {
340
+ if (outcome.error.code === 'blob-not-found') {
341
+ return xml(c, errorXml('NoSuchKey', `The specified key does not exist: ${key}`), 404);
342
+ }
343
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
344
+ }
345
+ const { meta, stream } = outcome.value;
346
+
347
+ const rangeHeader = c.req.header('range');
348
+ if (rangeHeader !== undefined) {
349
+ const range = parseRange(rangeHeader, meta.size);
350
+ if (range === null) {
351
+ return xml(c, errorXml('InvalidRange', 'Malformed Range header'), 416);
352
+ }
353
+ // Buffer the stream + slice in memory. The binding has no Range
354
+ // parameter, so the whole object is read; multi-range GET and
355
+ // streaming Range are not supported.
356
+ const buf = await drainStream(stream);
357
+ const sliced = buf.subarray(range.start, range.end + 1);
358
+ return new Response(sliced, {
359
+ status: 206,
360
+ headers: {
361
+ ...objectResponseHeaders(meta),
362
+ 'Content-Length': String(sliced.byteLength),
363
+ 'Content-Range': `bytes ${range.start}-${range.end}/${meta.size}`,
364
+ 'Accept-Ranges': 'bytes',
365
+ },
366
+ });
367
+ }
368
+ return new Response(stream, {
369
+ status: 200,
370
+ headers: {
371
+ ...objectResponseHeaders(meta),
372
+ 'Accept-Ranges': 'bytes',
373
+ },
374
+ });
375
+ });
376
+
377
+ // ---------- HEAD /:bucket/* (metadata only) ----------
378
+ r.on('HEAD', '/:bucket/*', async (c) => {
379
+ const tenantId = c.get('tenantId') as TenantId;
380
+ const bucket = c.req.param('bucket');
381
+ if (bucket === undefined) return new Response(null, { status: 400 });
382
+ const key = extractKey(c.req.path, bucket);
383
+ if (key === null || key.length === 0) return new Response(null, { status: 400 });
384
+
385
+ const meta = await binding.headByKey(tenantId, bucket, key);
386
+ if (meta === null) {
387
+ return new Response(null, { status: 404 });
388
+ }
389
+ return new Response(null, {
390
+ status: 200,
391
+ headers: {
392
+ ...objectResponseHeaders(meta),
393
+ 'Accept-Ranges': 'bytes',
394
+ },
395
+ });
396
+ });
397
+
398
+ // ---------- DELETE /:bucket/* (delete object OR AbortMultipartUpload) ----------
399
+ r.delete('/:bucket/*', async (c) => {
400
+ const tenantId = c.get('tenantId') as TenantId;
401
+ const bucket = c.req.param('bucket');
402
+ if (bucket === undefined) return new Response(null, { status: 400 });
403
+ const key = extractKey(c.req.path, bucket);
404
+ if (key === null || key.length === 0) return new Response(null, { status: 400 });
405
+
406
+ const uploadId = c.req.query('uploadId');
407
+ if (uploadId !== undefined) {
408
+ const outcome = await binding.abortMultipartUpload(tenantId, bucket, key, uploadId);
409
+ if (outcome.kind === 'err') {
410
+ // S3 spec: abort on nonexistent uploadId is 404 NoSuchUpload.
411
+ if (outcome.error.code === 'blob-not-found') {
412
+ return xml(c, errorXml('NoSuchUpload', outcome.error.message), 404);
413
+ }
414
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
415
+ }
416
+ return new Response(null, { status: 204 });
417
+ }
418
+
419
+ const outcome = await binding.deleteByKey(tenantId, bucket, key);
420
+ if (outcome.kind === 'err') {
421
+ return xml(c, errorXml('InternalError', outcome.error.message), 500);
422
+ }
423
+ // S3 semantics: 204 whether the key existed or not.
424
+ return new Response(null, { status: 204 });
425
+ });
426
+
427
+ return r;
428
+ }
429
+
430
+ // -------------------- helpers --------------------
431
+
432
+ function extractKey(path: string, bucket: string): string | null {
433
+ // path is `/s3/<bucket>/<key/with/possibly/slashes>` (or without leading `/s3`
434
+ // when Hono strips the mount prefix inside the router — Hono keeps the full
435
+ // path here since the router is mounted with `app.route('/s3', router)`).
436
+ // Handle both mounted and stripped paths defensively.
437
+ const prefixWithMount = `/s3/${bucket}/`;
438
+ const prefixWithoutMount = `/${bucket}/`;
439
+ if (path.startsWith(prefixWithMount))
440
+ return decodeURIComponent(path.slice(prefixWithMount.length));
441
+ if (path.startsWith(prefixWithoutMount))
442
+ return decodeURIComponent(path.slice(prefixWithoutMount.length));
443
+ return null;
444
+ }
445
+
446
+ function objectResponseHeaders(meta: BlobMeta): Record<string, string> {
447
+ return {
448
+ 'Content-Type': meta.contentType,
449
+ 'Content-Length': String(meta.size),
450
+ ETag: `"${meta.hash}"`,
451
+ 'Last-Modified': new Date(meta.createdAt as unknown as string).toUTCString(),
452
+ 'x-amz-meta-blob-id': meta.blobId as unknown as string,
453
+ ...(meta.ownerRunId !== undefined && {
454
+ 'x-amz-meta-owner-run-id': meta.ownerRunId as unknown as string,
455
+ }),
456
+ };
457
+ }
458
+
459
+ function parseRange(header: string, size: number): { start: number; end: number } | null {
460
+ // Only single-range `bytes=N-M` (or `bytes=N-`, `bytes=-M`). Multi-range
461
+ // is not supported.
462
+ const match = /^bytes=(\d*)-(\d*)$/i.exec(header.trim());
463
+ if (match === null) return null;
464
+ const rawStart = match[1] as string;
465
+ const rawEnd = match[2] as string;
466
+ if (rawStart.length === 0 && rawEnd.length === 0) return null;
467
+
468
+ let start: number;
469
+ let end: number;
470
+ if (rawStart.length === 0) {
471
+ // Suffix range: bytes=-M → last M bytes.
472
+ const suffix = Number.parseInt(rawEnd, 10);
473
+ if (!Number.isFinite(suffix) || suffix <= 0) return null;
474
+ start = Math.max(0, size - suffix);
475
+ end = size - 1;
476
+ } else {
477
+ start = Number.parseInt(rawStart, 10);
478
+ end = rawEnd.length === 0 ? size - 1 : Number.parseInt(rawEnd, 10);
479
+ if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
480
+ if (end >= size) end = size - 1;
481
+ }
482
+ if (start < 0 || end < start || start >= size) return null;
483
+ return { start, end };
484
+ }
485
+
486
+ async function drainStream(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
487
+ const chunks: Uint8Array[] = [];
488
+ const reader = stream.getReader();
489
+ let total = 0;
490
+ while (true) {
491
+ const step = await reader.read();
492
+ if (step.done) break;
493
+ chunks.push(step.value);
494
+ total += step.value.byteLength;
495
+ }
496
+ const merged = new Uint8Array(total);
497
+ let offset = 0;
498
+ for (const chunk of chunks) {
499
+ merged.set(chunk, offset);
500
+ offset += chunk.byteLength;
501
+ }
502
+ return merged;
503
+ }
504
+
505
+ function parseTagging(raw: string): Record<string, string> {
506
+ const out: Record<string, string> = {};
507
+ for (const pair of raw.split('&')) {
508
+ const eq = pair.indexOf('=');
509
+ if (eq <= 0) continue;
510
+ const k = decodeURIComponent(pair.slice(0, eq));
511
+ const v = decodeURIComponent(pair.slice(eq + 1));
512
+ if (k.length > 0) out[k] = v;
513
+ }
514
+ return out;
515
+ }
516
+
517
+ function xml(c: import('hono').Context, body: string, status: number): Response {
518
+ return c.body(body, status as never, { 'Content-Type': 'application/xml' });
519
+ }