@shipfox/api-runners 5.0.0 → 7.0.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 (400) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/CHANGELOG.md +80 -0
  3. package/dist/config.d.ts +5 -1
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +54 -7
  6. package/dist/config.js.map +1 -1
  7. package/dist/core/demand.d.ts +6 -6
  8. package/dist/core/demand.d.ts.map +1 -1
  9. package/dist/core/demand.js +10 -10
  10. package/dist/core/demand.js.map +1 -1
  11. package/dist/core/entities/ephemeral-registration-token.d.ts +1 -1
  12. package/dist/core/entities/ephemeral-registration-token.d.ts.map +1 -1
  13. package/dist/core/entities/ephemeral-registration-token.js.map +1 -1
  14. package/dist/core/entities/provisioner-capability-snapshot.d.ts +13 -0
  15. package/dist/core/entities/provisioner-capability-snapshot.d.ts.map +1 -0
  16. package/dist/core/entities/provisioner-capability-snapshot.js +3 -0
  17. package/dist/core/entities/provisioner-capability-snapshot.js.map +1 -0
  18. package/dist/core/entities/provisioner-token.d.ts +10 -2
  19. package/dist/core/entities/provisioner-token.d.ts.map +1 -1
  20. package/dist/core/entities/provisioner-token.js.map +1 -1
  21. package/dist/core/entities/{provisioned-runner.d.ts → runner-instance.d.ts} +7 -6
  22. package/dist/core/entities/runner-instance.d.ts.map +1 -0
  23. package/dist/core/entities/runner-instance.js +3 -0
  24. package/dist/core/entities/runner-instance.js.map +1 -0
  25. package/dist/core/entities/runner-session.d.ts +4 -2
  26. package/dist/core/entities/runner-session.d.ts.map +1 -1
  27. package/dist/core/entities/runner-session.js.map +1 -1
  28. package/dist/core/ephemeral-registration-tokens.d.ts +5 -5
  29. package/dist/core/ephemeral-registration-tokens.d.ts.map +1 -1
  30. package/dist/core/ephemeral-registration-tokens.js +12 -12
  31. package/dist/core/ephemeral-registration-tokens.js.map +1 -1
  32. package/dist/core/errors.d.ts +16 -4
  33. package/dist/core/errors.d.ts.map +1 -1
  34. package/dist/core/errors.js +22 -4
  35. package/dist/core/errors.js.map +1 -1
  36. package/dist/core/index.d.ts +9 -5
  37. package/dist/core/index.d.ts.map +1 -1
  38. package/dist/core/index.js +6 -3
  39. package/dist/core/index.js.map +1 -1
  40. package/dist/core/job-executions.d.ts +2 -0
  41. package/dist/core/job-executions.d.ts.map +1 -1
  42. package/dist/core/job-executions.js +1 -2
  43. package/dist/core/job-executions.js.map +1 -1
  44. package/dist/core/maintenance.d.ts +1 -1
  45. package/dist/core/maintenance.d.ts.map +1 -1
  46. package/dist/core/maintenance.js +5 -5
  47. package/dist/core/maintenance.js.map +1 -1
  48. package/dist/core/provisioner-capability-snapshots.d.ts +5 -0
  49. package/dist/core/provisioner-capability-snapshots.d.ts.map +1 -0
  50. package/dist/core/provisioner-capability-snapshots.js +10 -0
  51. package/dist/core/provisioner-capability-snapshots.js.map +1 -0
  52. package/dist/core/provisioner-tokens.d.ts +10 -0
  53. package/dist/core/provisioner-tokens.d.ts.map +1 -1
  54. package/dist/core/provisioner-tokens.js +23 -1
  55. package/dist/core/provisioner-tokens.js.map +1 -1
  56. package/dist/core/rate-limit.d.ts.map +1 -1
  57. package/dist/core/rate-limit.js +2 -7
  58. package/dist/core/rate-limit.js.map +1 -1
  59. package/dist/core/runner-activation.d.ts +13 -0
  60. package/dist/core/runner-activation.d.ts.map +1 -0
  61. package/dist/core/runner-activation.js +36 -0
  62. package/dist/core/runner-activation.js.map +1 -0
  63. package/dist/core/runner-assignments.d.ts +6 -0
  64. package/dist/core/runner-assignments.d.ts.map +1 -0
  65. package/dist/core/runner-assignments.js +6 -0
  66. package/dist/core/runner-assignments.js.map +1 -0
  67. package/dist/core/runner-control-sessions.d.ts +46 -0
  68. package/dist/core/runner-control-sessions.d.ts.map +1 -0
  69. package/dist/core/runner-control-sessions.js +121 -0
  70. package/dist/core/runner-control-sessions.js.map +1 -0
  71. package/dist/core/runner-instances.d.ts +72 -0
  72. package/dist/core/runner-instances.d.ts.map +1 -0
  73. package/dist/core/runner-instances.js +165 -0
  74. package/dist/core/runner-instances.js.map +1 -0
  75. package/dist/core/runner-sessions.d.ts +8 -2
  76. package/dist/core/runner-sessions.d.ts.map +1 -1
  77. package/dist/core/runner-sessions.js +8 -5
  78. package/dist/core/runner-sessions.js.map +1 -1
  79. package/dist/db/db.d.ts +2698 -1054
  80. package/dist/db/db.d.ts.map +1 -1
  81. package/dist/db/db.js +9 -2
  82. package/dist/db/db.js.map +1 -1
  83. package/dist/db/ephemeral-registration-tokens.d.ts +2 -2
  84. package/dist/db/ephemeral-registration-tokens.d.ts.map +1 -1
  85. package/dist/db/ephemeral-registration-tokens.js +21 -21
  86. package/dist/db/ephemeral-registration-tokens.js.map +1 -1
  87. package/dist/db/index.d.ts +7 -4
  88. package/dist/db/index.d.ts.map +1 -1
  89. package/dist/db/index.js +5 -2
  90. package/dist/db/index.js.map +1 -1
  91. package/dist/db/job-executions.d.ts +6 -6
  92. package/dist/db/job-executions.d.ts.map +1 -1
  93. package/dist/db/job-executions.js +20 -19
  94. package/dist/db/job-executions.js.map +1 -1
  95. package/dist/db/provisioner-capability-snapshots.d.ts +21 -0
  96. package/dist/db/provisioner-capability-snapshots.d.ts.map +1 -0
  97. package/dist/db/provisioner-capability-snapshots.js +57 -0
  98. package/dist/db/provisioner-capability-snapshots.js.map +1 -0
  99. package/dist/db/provisioner-tokens.d.ts +7 -2
  100. package/dist/db/provisioner-tokens.d.ts.map +1 -1
  101. package/dist/db/provisioner-tokens.js +59 -10
  102. package/dist/db/provisioner-tokens.js.map +1 -1
  103. package/dist/db/reservations.d.ts +18 -0
  104. package/dist/db/reservations.d.ts.map +1 -1
  105. package/dist/db/reservations.js +88 -1
  106. package/dist/db/reservations.js.map +1 -1
  107. package/dist/db/runner-assignments.d.ts +7 -0
  108. package/dist/db/runner-assignments.d.ts.map +1 -0
  109. package/dist/db/runner-assignments.js +55 -0
  110. package/dist/db/runner-assignments.js.map +1 -0
  111. package/dist/db/runner-instances.d.ts +84 -0
  112. package/dist/db/runner-instances.d.ts.map +1 -0
  113. package/dist/db/runner-instances.js +497 -0
  114. package/dist/db/runner-instances.js.map +1 -0
  115. package/dist/db/runner-sessions.d.ts +5 -0
  116. package/dist/db/runner-sessions.d.ts.map +1 -1
  117. package/dist/db/runner-sessions.js +48 -2
  118. package/dist/db/runner-sessions.js.map +1 -1
  119. package/dist/db/schema/ephemeral-registration-tokens.d.ts +2 -2
  120. package/dist/db/schema/ephemeral-registration-tokens.js +3 -3
  121. package/dist/db/schema/ephemeral-registration-tokens.js.map +1 -1
  122. package/dist/db/schema/provisioner-capability-snapshots.d.ts +207 -0
  123. package/dist/db/schema/provisioner-capability-snapshots.d.ts.map +1 -0
  124. package/dist/db/schema/provisioner-capability-snapshots.js +38 -0
  125. package/dist/db/schema/provisioner-capability-snapshots.js.map +1 -0
  126. package/dist/db/schema/provisioner-tokens.d.ts +19 -1
  127. package/dist/db/schema/provisioner-tokens.d.ts.map +1 -1
  128. package/dist/db/schema/provisioner-tokens.js +29 -3
  129. package/dist/db/schema/provisioner-tokens.js.map +1 -1
  130. package/dist/db/schema/runner-activation-tokens.d.ts +161 -0
  131. package/dist/db/schema/runner-activation-tokens.d.ts.map +1 -0
  132. package/dist/db/schema/runner-activation-tokens.js +27 -0
  133. package/dist/db/schema/runner-activation-tokens.js.map +1 -0
  134. package/dist/db/schema/runner-control-sessions.d.ts +338 -0
  135. package/dist/db/schema/runner-control-sessions.d.ts.map +1 -0
  136. package/dist/db/schema/runner-control-sessions.js +52 -0
  137. package/dist/db/schema/runner-control-sessions.js.map +1 -0
  138. package/dist/db/schema/{provisioned-runners.d.ts → runner-instances.d.ts} +105 -34
  139. package/dist/db/schema/runner-instances.d.ts.map +1 -0
  140. package/dist/db/schema/{provisioned-runners.js → runner-instances.js} +23 -14
  141. package/dist/db/schema/runner-instances.js.map +1 -0
  142. package/dist/db/schema/runner-sessions.d.ts +39 -5
  143. package/dist/db/schema/runner-sessions.d.ts.map +1 -1
  144. package/dist/db/schema/runner-sessions.js +13 -6
  145. package/dist/db/schema/runner-sessions.js.map +1 -1
  146. package/dist/db/schema/running-job-executions.d.ts +2 -2
  147. package/dist/db/schema/running-job-executions.js +4 -4
  148. package/dist/db/schema/running-job-executions.js.map +1 -1
  149. package/dist/index.d.ts +6 -2
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +45 -39
  152. package/dist/index.js.map +1 -1
  153. package/dist/installation-provisioning.d.ts +14 -0
  154. package/dist/installation-provisioning.d.ts.map +1 -0
  155. package/dist/installation-provisioning.js +7 -0
  156. package/dist/installation-provisioning.js.map +1 -0
  157. package/dist/metrics/index.d.ts +1 -1
  158. package/dist/metrics/index.d.ts.map +1 -1
  159. package/dist/metrics/index.js +1 -1
  160. package/dist/metrics/index.js.map +1 -1
  161. package/dist/metrics/instance.d.ts +11 -7
  162. package/dist/metrics/instance.d.ts.map +1 -1
  163. package/dist/metrics/instance.js +13 -7
  164. package/dist/metrics/instance.js.map +1 -1
  165. package/dist/presentation/auth/index.d.ts +1 -0
  166. package/dist/presentation/auth/index.d.ts.map +1 -1
  167. package/dist/presentation/auth/index.js +1 -0
  168. package/dist/presentation/auth/index.js.map +1 -1
  169. package/dist/presentation/auth/provisioner-token-auth.d.ts.map +1 -1
  170. package/dist/presentation/auth/provisioner-token-auth.js +5 -1
  171. package/dist/presentation/auth/provisioner-token-auth.js.map +1 -1
  172. package/dist/presentation/auth/runner-control-session-auth.d.ts +4 -0
  173. package/dist/presentation/auth/runner-control-session-auth.d.ts.map +1 -0
  174. package/dist/presentation/auth/runner-control-session-auth.js +29 -0
  175. package/dist/presentation/auth/runner-control-session-auth.js.map +1 -0
  176. package/dist/presentation/auth/runner-registration-token-auth.d.ts +5 -1
  177. package/dist/presentation/auth/runner-registration-token-auth.d.ts.map +1 -1
  178. package/dist/presentation/auth/runner-registration-token-auth.js +21 -1
  179. package/dist/presentation/auth/runner-registration-token-auth.js.map +1 -1
  180. package/dist/presentation/dto/index.d.ts +1 -2
  181. package/dist/presentation/dto/index.d.ts.map +1 -1
  182. package/dist/presentation/dto/index.js +1 -2
  183. package/dist/presentation/dto/index.js.map +1 -1
  184. package/dist/presentation/dto/poll-demand.d.ts.map +1 -1
  185. package/dist/presentation/dto/poll-demand.js +7 -1
  186. package/dist/presentation/dto/poll-demand.js.map +1 -1
  187. package/dist/presentation/dto/provisioner-token.d.ts +1 -0
  188. package/dist/presentation/dto/provisioner-token.d.ts.map +1 -1
  189. package/dist/presentation/dto/provisioner-token.js +5 -1
  190. package/dist/presentation/dto/provisioner-token.js.map +1 -1
  191. package/dist/presentation/dto/{provisioned-runners.d.ts → runner-instances.d.ts} +9 -9
  192. package/dist/presentation/dto/runner-instances.d.ts.map +1 -0
  193. package/dist/presentation/dto/{provisioned-runners.js → runner-instances.js} +6 -6
  194. package/dist/presentation/dto/runner-instances.js.map +1 -0
  195. package/dist/presentation/index.d.ts +2 -2
  196. package/dist/presentation/index.d.ts.map +1 -1
  197. package/dist/presentation/index.js +2 -2
  198. package/dist/presentation/index.js.map +1 -1
  199. package/dist/presentation/inter-module.d.ts +5 -0
  200. package/dist/presentation/inter-module.d.ts.map +1 -0
  201. package/dist/presentation/inter-module.js +43 -0
  202. package/dist/presentation/inter-module.js.map +1 -0
  203. package/dist/presentation/routes/assign-runner-instances.d.ts +2 -0
  204. package/dist/presentation/routes/assign-runner-instances.d.ts.map +1 -0
  205. package/dist/presentation/routes/assign-runner-instances.js +40 -0
  206. package/dist/presentation/routes/assign-runner-instances.js.map +1 -0
  207. package/dist/presentation/routes/get-provisioner-me.d.ts.map +1 -1
  208. package/dist/presentation/routes/get-provisioner-me.js +5 -1
  209. package/dist/presentation/routes/get-provisioner-me.js.map +1 -1
  210. package/dist/presentation/routes/heartbeat.d.ts +2 -1
  211. package/dist/presentation/routes/heartbeat.d.ts.map +1 -1
  212. package/dist/presentation/routes/heartbeat.js +60 -50
  213. package/dist/presentation/routes/heartbeat.js.map +1 -1
  214. package/dist/presentation/routes/index.d.ts +3 -1
  215. package/dist/presentation/routes/index.d.ts.map +1 -1
  216. package/dist/presentation/routes/index.js +80 -51
  217. package/dist/presentation/routes/index.js.map +1 -1
  218. package/dist/presentation/routes/poll-demand.d.ts +2 -0
  219. package/dist/presentation/routes/poll-demand.d.ts.map +1 -1
  220. package/dist/presentation/routes/poll-demand.js +86 -45
  221. package/dist/presentation/routes/poll-demand.js.map +1 -1
  222. package/dist/presentation/routes/reconcile-runner-instances.d.ts +2 -0
  223. package/dist/presentation/routes/reconcile-runner-instances.d.ts.map +1 -0
  224. package/dist/presentation/routes/reconcile-runner-instances.js +27 -0
  225. package/dist/presentation/routes/reconcile-runner-instances.js.map +1 -0
  226. package/dist/presentation/routes/register.d.ts +2 -1
  227. package/dist/presentation/routes/register.d.ts.map +1 -1
  228. package/dist/presentation/routes/register.js +55 -52
  229. package/dist/presentation/routes/register.js.map +1 -1
  230. package/dist/presentation/routes/report-runner-instances.d.ts +2 -0
  231. package/dist/presentation/routes/report-runner-instances.d.ts.map +1 -0
  232. package/dist/presentation/routes/report-runner-instances.js +37 -0
  233. package/dist/presentation/routes/report-runner-instances.js.map +1 -0
  234. package/dist/presentation/routes/request-job.d.ts +2 -1
  235. package/dist/presentation/routes/request-job.d.ts.map +1 -1
  236. package/dist/presentation/routes/request-job.js +39 -36
  237. package/dist/presentation/routes/request-job.js.map +1 -1
  238. package/dist/presentation/routes/runner-enrollment.d.ts +8 -0
  239. package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -0
  240. package/dist/presentation/routes/runner-enrollment.js +212 -0
  241. package/dist/presentation/routes/runner-enrollment.js.map +1 -0
  242. package/dist/temporal/activities/index.d.ts +2 -2
  243. package/dist/temporal/activities/index.d.ts.map +1 -1
  244. package/dist/temporal/activities/index.js +2 -2
  245. package/dist/temporal/activities/index.js.map +1 -1
  246. package/dist/temporal/activities/maintenance-activities.d.ts +1 -1
  247. package/dist/temporal/activities/maintenance-activities.d.ts.map +1 -1
  248. package/dist/temporal/activities/maintenance-activities.js +3 -3
  249. package/dist/temporal/activities/maintenance-activities.js.map +1 -1
  250. package/dist/temporal/workflows/index.bundle.js +3 -3
  251. package/dist/temporal/workflows/stuck-job-detector.js +2 -2
  252. package/dist/temporal/workflows/stuck-job-detector.js.map +1 -1
  253. package/dist/tsconfig.test.tsbuildinfo +1 -1
  254. package/drizzle/0000_initial.sql +91 -24
  255. package/drizzle/meta/0000_snapshot.json +392 -63
  256. package/package.json +21 -16
  257. package/src/config.test.ts +0 -26
  258. package/src/config.ts +48 -7
  259. package/src/core/demand.test.ts +29 -29
  260. package/src/core/demand.ts +22 -22
  261. package/src/core/entities/ephemeral-registration-token.ts +1 -1
  262. package/src/core/entities/provisioner-capability-snapshot.ts +12 -0
  263. package/src/core/entities/provisioner-token.ts +8 -2
  264. package/src/core/entities/{provisioned-runner.ts → runner-instance.ts} +6 -5
  265. package/src/core/entities/runner-session.ts +4 -2
  266. package/src/core/ephemeral-registration-tokens.test.ts +11 -11
  267. package/src/core/ephemeral-registration-tokens.ts +18 -20
  268. package/src/core/errors.ts +23 -4
  269. package/src/core/index.ts +37 -22
  270. package/src/core/job-executions.ts +3 -2
  271. package/src/core/maintenance.test.ts +13 -17
  272. package/src/core/maintenance.ts +5 -5
  273. package/src/core/provisioner-capability-snapshots.test.ts +35 -0
  274. package/src/core/provisioner-capability-snapshots.ts +12 -0
  275. package/src/core/provisioner-tokens.test.ts +20 -0
  276. package/src/core/provisioner-tokens.ts +33 -0
  277. package/src/core/rate-limit.test.ts +11 -27
  278. package/src/core/rate-limit.ts +3 -11
  279. package/src/core/runner-activation.ts +72 -0
  280. package/src/core/runner-assignments.ts +9 -0
  281. package/src/core/runner-control-sessions.ts +190 -0
  282. package/src/core/{provisioned-runners.test.ts → runner-instances.test.ts} +24 -24
  283. package/src/core/runner-instances.ts +301 -0
  284. package/src/core/runner-sessions.test.ts +112 -22
  285. package/src/core/runner-sessions.ts +25 -14
  286. package/src/db/db.ts +9 -2
  287. package/src/db/ephemeral-registration-tokens.test.ts +9 -9
  288. package/src/db/ephemeral-registration-tokens.ts +26 -26
  289. package/src/db/index.ts +30 -21
  290. package/src/db/job-executions.test.ts +13 -11
  291. package/src/db/job-executions.ts +33 -27
  292. package/src/db/provisioner-capability-snapshots.test.ts +175 -0
  293. package/src/db/provisioner-capability-snapshots.ts +130 -0
  294. package/src/db/provisioner-tokens.test.ts +139 -2
  295. package/src/db/provisioner-tokens.ts +123 -15
  296. package/src/db/reservations.test.ts +49 -0
  297. package/src/db/reservations.ts +146 -1
  298. package/src/db/runner-assignments.test.ts +163 -0
  299. package/src/db/runner-assignments.ts +115 -0
  300. package/src/db/{provisioned-runners.test.ts → runner-instances.test.ts} +442 -353
  301. package/src/db/runner-instances.ts +922 -0
  302. package/src/db/runner-sessions.test.ts +19 -6
  303. package/src/db/runner-sessions.ts +78 -2
  304. package/src/db/schema/ephemeral-registration-tokens.ts +4 -4
  305. package/src/db/schema/provisioner-capability-snapshots.ts +46 -0
  306. package/src/db/schema/provisioner-tokens.ts +33 -2
  307. package/src/db/schema/runner-activation-tokens.ts +22 -0
  308. package/src/db/schema/runner-control-sessions.ts +46 -0
  309. package/src/db/schema/{provisioned-runners.ts → runner-instances.ts} +28 -27
  310. package/src/db/schema/runner-sessions.ts +11 -7
  311. package/src/db/schema/running-job-executions.ts +5 -5
  312. package/src/index.test.ts +26 -0
  313. package/src/index.ts +38 -27
  314. package/src/installation-provisioning.ts +14 -0
  315. package/src/metrics/index.ts +5 -5
  316. package/src/metrics/instance.ts +25 -14
  317. package/src/presentation/auth/index.ts +4 -0
  318. package/src/presentation/auth/provisioner-token-auth.ts +8 -4
  319. package/src/presentation/auth/runner-control-session-auth.ts +31 -0
  320. package/src/presentation/auth/runner-registration-token-auth.ts +39 -3
  321. package/src/presentation/dto/index.ts +4 -8
  322. package/src/presentation/dto/poll-demand.ts +3 -1
  323. package/src/presentation/dto/provisioner-token.ts +5 -0
  324. package/src/presentation/dto/{provisioned-runners.ts → runner-instances.ts} +13 -15
  325. package/src/presentation/index.ts +2 -1
  326. package/src/presentation/inter-module.test.ts +15 -0
  327. package/src/presentation/inter-module.ts +53 -0
  328. package/src/presentation/routes/assign-runner-instances.ts +49 -0
  329. package/src/presentation/routes/get-provisioner-me.ts +3 -4
  330. package/src/presentation/routes/heartbeat.test.ts +4 -3
  331. package/src/presentation/routes/heartbeat.ts +67 -64
  332. package/src/presentation/routes/index.ts +91 -44
  333. package/src/presentation/routes/list-active-runners.test.ts +23 -23
  334. package/src/presentation/routes/manual-registration-tokens.test.ts +4 -3
  335. package/src/presentation/routes/poll-demand-release.test.ts +4 -4
  336. package/src/presentation/routes/poll-demand.test.ts +161 -22
  337. package/src/presentation/routes/poll-demand.ts +105 -45
  338. package/src/presentation/routes/provisioner-me.test.ts +37 -3
  339. package/src/presentation/routes/{reconcile-provisioned-runners.test.ts → reconcile-runner-instances.test.ts} +66 -61
  340. package/src/presentation/routes/reconcile-runner-instances.ts +30 -0
  341. package/src/presentation/routes/register.test.ts +9 -5
  342. package/src/presentation/routes/register.ts +61 -57
  343. package/src/presentation/routes/{report-provisioned-runners.test.ts → report-runner-instances.test.ts} +28 -28
  344. package/src/presentation/routes/{report-provisioned-runners.ts → report-runner-instances.ts} +14 -14
  345. package/src/presentation/routes/request-job.test.ts +5 -3
  346. package/src/presentation/routes/request-job.ts +41 -37
  347. package/src/presentation/routes/runner-enrollment.test.ts +319 -0
  348. package/src/presentation/routes/runner-enrollment.ts +196 -0
  349. package/src/temporal/activities/index.ts +2 -2
  350. package/src/temporal/activities/maintenance-activities.test.ts +7 -7
  351. package/src/temporal/activities/maintenance-activities.ts +3 -3
  352. package/src/temporal/workflows/stuck-job-detector.test.ts +3 -3
  353. package/src/temporal/workflows/stuck-job-detector.ts +2 -2
  354. package/test/env.ts +1 -3
  355. package/test/factories/ephemeral-registration-token.ts +2 -2
  356. package/test/factories/provisioner-token.ts +3 -1
  357. package/test/factories/runner-instance.ts +57 -0
  358. package/test/factories/runner-session.ts +3 -1
  359. package/test/fixtures/auth-inter-module.ts +30 -0
  360. package/test/globalSetup.ts +4 -1
  361. package/test/index.ts +2 -1
  362. package/tsconfig.build.tsbuildinfo +1 -1
  363. package/dist/core/entities/provisioned-runner.d.ts.map +0 -1
  364. package/dist/core/entities/provisioned-runner.js +0 -3
  365. package/dist/core/entities/provisioned-runner.js.map +0 -1
  366. package/dist/core/provisioned-runners.d.ts +0 -67
  367. package/dist/core/provisioned-runners.d.ts.map +0 -1
  368. package/dist/core/provisioned-runners.js +0 -162
  369. package/dist/core/provisioned-runners.js.map +0 -1
  370. package/dist/db/provisioned-runners.d.ts +0 -79
  371. package/dist/db/provisioned-runners.d.ts.map +0 -1
  372. package/dist/db/provisioned-runners.js +0 -466
  373. package/dist/db/provisioned-runners.js.map +0 -1
  374. package/dist/db/schema/provisioned-runners.d.ts.map +0 -1
  375. package/dist/db/schema/provisioned-runners.js.map +0 -1
  376. package/dist/presentation/dto/mint-registration-tokens.d.ts +0 -5
  377. package/dist/presentation/dto/mint-registration-tokens.d.ts.map +0 -1
  378. package/dist/presentation/dto/mint-registration-tokens.js +0 -19
  379. package/dist/presentation/dto/mint-registration-tokens.js.map +0 -1
  380. package/dist/presentation/dto/provisioned-runners.d.ts.map +0 -1
  381. package/dist/presentation/dto/provisioned-runners.js.map +0 -1
  382. package/dist/presentation/routes/mint-registration-tokens.d.ts +0 -2
  383. package/dist/presentation/routes/mint-registration-tokens.d.ts.map +0 -1
  384. package/dist/presentation/routes/mint-registration-tokens.js +0 -74
  385. package/dist/presentation/routes/mint-registration-tokens.js.map +0 -1
  386. package/dist/presentation/routes/reconcile-provisioned-runners.d.ts +0 -2
  387. package/dist/presentation/routes/reconcile-provisioned-runners.d.ts.map +0 -1
  388. package/dist/presentation/routes/reconcile-provisioned-runners.js +0 -27
  389. package/dist/presentation/routes/reconcile-provisioned-runners.js.map +0 -1
  390. package/dist/presentation/routes/report-provisioned-runners.d.ts +0 -2
  391. package/dist/presentation/routes/report-provisioned-runners.d.ts.map +0 -1
  392. package/dist/presentation/routes/report-provisioned-runners.js +0 -37
  393. package/dist/presentation/routes/report-provisioned-runners.js.map +0 -1
  394. package/src/core/provisioned-runners.ts +0 -301
  395. package/src/db/provisioned-runners.ts +0 -886
  396. package/src/presentation/dto/mint-registration-tokens.ts +0 -35
  397. package/src/presentation/routes/mint-registration-tokens.test.ts +0 -453
  398. package/src/presentation/routes/mint-registration-tokens.ts +0 -82
  399. package/src/presentation/routes/reconcile-provisioned-runners.ts +0 -30
  400. package/test/factories/provisioned-runner.ts +0 -78
@@ -1,35 +0,0 @@
1
- import type {
2
- MintedRegistrationTokenDto,
3
- MintRegistrationTokensBatchResponseDto,
4
- MintRegistrationTokensProvisionedRunnerDto,
5
- } from '@shipfox/api-runners-dto';
6
- import type {
7
- MintEphemeralRegistrationTokensBatchProvisionedRunner,
8
- MintEphemeralRegistrationTokensBatchResult,
9
- } from '#core/ephemeral-registration-tokens.js';
10
-
11
- export function toMintRegistrationTokensProvisionedRunners(
12
- provisionedRunners: MintRegistrationTokensProvisionedRunnerDto[],
13
- ): MintEphemeralRegistrationTokensBatchProvisionedRunner[] {
14
- return provisionedRunners.map((provisionedRunner) => ({
15
- provisionedRunnerId: provisionedRunner.provisioned_runner_id,
16
- }));
17
- }
18
-
19
- export function toMintRegistrationTokensResponseDto(
20
- result: MintEphemeralRegistrationTokensBatchResult[],
21
- ): MintRegistrationTokensBatchResponseDto {
22
- return {
23
- tokens: result.map(toMintedRegistrationTokenDto),
24
- };
25
- }
26
-
27
- function toMintedRegistrationTokenDto(
28
- result: MintEphemeralRegistrationTokensBatchResult,
29
- ): MintedRegistrationTokenDto {
30
- return {
31
- provisioned_runner_id: result.provisionedRunnerId,
32
- registration_token: result.rawToken,
33
- expires_at: result.token.expiresAt.toISOString(),
34
- };
35
- }
@@ -1,453 +0,0 @@
1
- import {createLeaseTokenAuthMethod, createRunnerSessionAuthMethod} from '@shipfox/api-auth';
2
- import {
3
- AUTH_LEASED_JOB,
4
- AUTH_PROVISIONER_TOKEN,
5
- AUTH_RUNNER_SESSION,
6
- AUTH_USER,
7
- setProvisionerContext,
8
- } from '@shipfox/api-auth-context';
9
- import {
10
- type AuthMethod,
11
- ClientError,
12
- closeApp,
13
- createApp,
14
- extractBearerToken,
15
- } from '@shipfox/node-fastify';
16
- import {hashOpaqueToken, tokenTypeParts} from '@shipfox/node-tokens';
17
- import {and, count, eq, sql} from 'drizzle-orm';
18
- import type {FastifyInstance, FastifyRequest} from 'fastify';
19
- import {config} from '#config.js';
20
- import {hashRunnersRateLimitIdentifier} from '#core/rate-limit.js';
21
- import {db} from '#db/db.js';
22
- import {resolveEphemeralRegistrationTokenByHash} from '#db/ephemeral-registration-tokens.js';
23
- import {ephemeralRegistrationTokens} from '#db/schema/ephemeral-registration-tokens.js';
24
- import {runnersRateLimits} from '#db/schema/rate-limits.js';
25
- import {reservations} from '#db/schema/reservations.js';
26
- import {createRunnerRegistrationTokenAuthMethod} from '#presentation/auth/index.js';
27
- import {ephemeralRegistrationTokenFactory} from '#test/index.js';
28
- import {runnerRoutes} from './index.js';
29
-
30
- const VALID_PROVISIONER_TOKEN = 'valid-provisioner-token';
31
-
32
- const fakeUserAuth: AuthMethod = {
33
- name: AUTH_USER,
34
- authenticate: () => Promise.resolve(),
35
- };
36
-
37
- const passthroughAuth = (name: string): AuthMethod => ({
38
- name,
39
- authenticate: () => Promise.resolve(),
40
- });
41
-
42
- describe('POST /provisioners/runner-registration-tokens/batch', () => {
43
- let app: FastifyInstance;
44
- let workspaceId: string;
45
- let provisionerTokenId: string;
46
-
47
- const fakeProvisionerAuth: AuthMethod = {
48
- name: AUTH_PROVISIONER_TOKEN,
49
- authenticate: (request: FastifyRequest) => {
50
- const rawToken = extractBearerToken(request.headers.authorization);
51
- if (rawToken !== VALID_PROVISIONER_TOKEN) {
52
- throw new ClientError('Invalid provisioner token', 'unauthorized', {status: 401});
53
- }
54
- setProvisionerContext(request, {workspaceId, provisionerTokenId});
55
- return Promise.resolve();
56
- },
57
- };
58
-
59
- beforeAll(async () => {
60
- app = await createApp({
61
- auth: [
62
- fakeUserAuth,
63
- createRunnerRegistrationTokenAuthMethod(),
64
- createRunnerSessionAuthMethod(),
65
- createLeaseTokenAuthMethod(),
66
- passthroughAuth(AUTH_RUNNER_SESSION),
67
- passthroughAuth(AUTH_LEASED_JOB),
68
- fakeProvisionerAuth,
69
- ],
70
- routes: runnerRoutes,
71
- swagger: false,
72
- });
73
- await app.ready();
74
- });
75
-
76
- afterAll(async () => {
77
- await closeApp();
78
- });
79
-
80
- beforeEach(() => {
81
- workspaceId = crypto.randomUUID();
82
- provisionerTokenId = crypto.randomUUID();
83
- });
84
-
85
- it('mints one registration token per provisioned runner for a valid reservation', async () => {
86
- const reservationId = await createReservation({count: 2});
87
- const before = Date.now();
88
-
89
- const res = await app.inject({
90
- method: 'POST',
91
- url: '/provisioners/runner-registration-tokens/batch',
92
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
93
- payload: body(reservationId, ['provisioned-runner-a', 'provisioned-runner-b']),
94
- });
95
-
96
- const after = Date.now();
97
- expect(res.statusCode).toBe(200);
98
- const tokens = res.json().tokens as {
99
- provisioned_runner_id: string;
100
- registration_token: string;
101
- expires_at: string;
102
- }[];
103
- expect(tokens).toHaveLength(2);
104
- expect(tokens.map((token) => token.provisioned_runner_id).sort()).toEqual([
105
- 'provisioned-runner-a',
106
- 'provisioned-runner-b',
107
- ]);
108
- for (const minted of tokens) {
109
- expect(
110
- minted.registration_token.startsWith(`sf_${tokenTypeParts.ephemeralRegistrationToken}_`),
111
- ).toBe(true);
112
- const persisted = await resolveEphemeralRegistrationTokenByHash(
113
- hashOpaqueToken(minted.registration_token),
114
- );
115
- expect(persisted).toMatchObject({
116
- workspaceId,
117
- provisionerId: provisionerTokenId,
118
- reservationId,
119
- provisionedRunnerId: minted.provisioned_runner_id,
120
- });
121
- const expiresMs = new Date(minted.expires_at).getTime();
122
- expect(expiresMs).toBeGreaterThanOrEqual(
123
- before + config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS * 1000,
124
- );
125
- expect(expiresMs).toBeLessThanOrEqual(
126
- after + config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS * 1000,
127
- );
128
- }
129
- });
130
-
131
- it('returns 404 when the reservation is unknown', async () => {
132
- const res = await app.inject({
133
- method: 'POST',
134
- url: '/provisioners/runner-registration-tokens/batch',
135
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
136
- payload: body(crypto.randomUUID(), ['provisioned-runner-a']),
137
- });
138
-
139
- expect(res.statusCode).toBe(404);
140
- expect(res.json().code).toBe('reservation-not-found');
141
- });
142
-
143
- it('returns 404 when the reservation belongs to another provisioner', async () => {
144
- const reservationId = await createReservation({
145
- count: 1,
146
- provisionerId: crypto.randomUUID(),
147
- });
148
-
149
- const res = await app.inject({
150
- method: 'POST',
151
- url: '/provisioners/runner-registration-tokens/batch',
152
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
153
- payload: body(reservationId, ['provisioned-runner-a']),
154
- });
155
-
156
- expect(res.statusCode).toBe(404);
157
- expect(res.json().code).toBe('reservation-not-found');
158
- });
159
-
160
- it('returns 404 when the reservation belongs to another workspace', async () => {
161
- const reservationId = await createReservation({
162
- count: 1,
163
- workspaceId: crypto.randomUUID(),
164
- });
165
-
166
- const res = await app.inject({
167
- method: 'POST',
168
- url: '/provisioners/runner-registration-tokens/batch',
169
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
170
- payload: body(reservationId, ['provisioned-runner-a']),
171
- });
172
-
173
- expect(res.statusCode).toBe(404);
174
- expect(res.json().code).toBe('reservation-not-found');
175
- });
176
-
177
- it('returns 409 when the reservation is expired', async () => {
178
- const reservationId = await createReservation({
179
- count: 1,
180
- expiresAt: new Date(Date.now() - 1000),
181
- });
182
-
183
- const res = await app.inject({
184
- method: 'POST',
185
- url: '/provisioners/runner-registration-tokens/batch',
186
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
187
- payload: body(reservationId, ['provisioned-runner-a']),
188
- });
189
-
190
- expect(res.statusCode).toBe(409);
191
- expect(res.json().code).toBe('reservation-expired');
192
- });
193
-
194
- it('allows a batch equal to the reservation count', async () => {
195
- const reservationId = await createReservation({count: 2});
196
-
197
- const res = await app.inject({
198
- method: 'POST',
199
- url: '/provisioners/runner-registration-tokens/batch',
200
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
201
- payload: body(reservationId, ['provisioned-runner-a', 'provisioned-runner-b']),
202
- });
203
-
204
- expect(res.statusCode).toBe(200);
205
- expect(res.json().tokens).toHaveLength(2);
206
- });
207
-
208
- it('returns 409 when the batch exceeds the reservation count', async () => {
209
- const reservationId = await createReservation({count: 1});
210
-
211
- const res = await app.inject({
212
- method: 'POST',
213
- url: '/provisioners/runner-registration-tokens/batch',
214
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
215
- payload: body(reservationId, ['provisioned-runner-a', 'provisioned-runner-b']),
216
- });
217
-
218
- expect(res.statusCode).toBe(409);
219
- expect(res.json()).toMatchObject({
220
- code: 'batch-exceeds-reservation',
221
- details: {requested: 2, reservation_count: 1},
222
- });
223
- });
224
-
225
- it('rejects the whole batch when a requested provisioned runner has an active token', async () => {
226
- const reservationId = await createReservation({count: 2});
227
- await ephemeralRegistrationTokenFactory.create({
228
- workspaceId,
229
- provisionerId: provisionerTokenId,
230
- provisionedRunnerId: 'provisioned-runner-a',
231
- expiresAt: new Date(Date.now() + 60_000),
232
- });
233
-
234
- const res = await app.inject({
235
- method: 'POST',
236
- url: '/provisioners/runner-registration-tokens/batch',
237
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
238
- payload: body(reservationId, ['provisioned-runner-a', 'provisioned-runner-b']),
239
- });
240
-
241
- const persistedCount = await countEphemeralTokens();
242
- expect(res.statusCode).toBe(409);
243
- expect(res.json()).toMatchObject({
244
- code: 'registration-token-active',
245
- details: {provisioned_runner_ids: ['provisioned-runner-a']},
246
- });
247
- expect(persistedCount).toBe(1);
248
- });
249
-
250
- it('returns 400 for duplicate provisioned runner ids', async () => {
251
- const reservationId = await createReservation({count: 2});
252
-
253
- const res = await app.inject({
254
- method: 'POST',
255
- url: '/provisioners/runner-registration-tokens/batch',
256
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
257
- payload: body(reservationId, ['provisioned-runner-a', 'provisioned-runner-a']),
258
- });
259
-
260
- expect(res.statusCode).toBe(400);
261
- });
262
-
263
- it('returns 400 when the request exceeds the runtime batch max', async () => {
264
- const reservationId = await createReservation({count: config.REGISTRATION_TOKEN_BATCH_MAX + 1});
265
-
266
- const res = await app.inject({
267
- method: 'POST',
268
- url: '/provisioners/runner-registration-tokens/batch',
269
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
270
- payload: body(
271
- reservationId,
272
- Array.from(
273
- {length: config.REGISTRATION_TOKEN_BATCH_MAX + 1},
274
- (_, index) => `provisioned-runner-${index}`,
275
- ),
276
- ),
277
- });
278
-
279
- expect(res.statusCode).toBe(400);
280
- expect(res.json()).toMatchObject({
281
- code: 'batch-too-large',
282
- details: {requested: config.REGISTRATION_TOKEN_BATCH_MAX + 1},
283
- });
284
- });
285
-
286
- it('returns 400 when the request exceeds the DTO hard ceiling', async () => {
287
- const reservationId = await createReservation({count: 1001});
288
-
289
- const res = await app.inject({
290
- method: 'POST',
291
- url: '/provisioners/runner-registration-tokens/batch',
292
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
293
- payload: body(
294
- reservationId,
295
- Array.from({length: 1001}, (_, index) => `provisioned-runner-${index}`),
296
- ),
297
- });
298
-
299
- expect(res.statusCode).toBe(400);
300
- });
301
-
302
- it('returns 429 when the provisioner mint rate limit is exceeded', async () => {
303
- const reservationId = await createReservation({count: 1});
304
- await seedProvisionerMintRateLimit(config.PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS);
305
-
306
- const res = await app.inject({
307
- method: 'POST',
308
- url: '/provisioners/runner-registration-tokens/batch',
309
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
310
- payload: body(reservationId, ['provisioned-runner-a']),
311
- });
312
-
313
- const persistedCount = await countEphemeralTokens();
314
- expect(res.statusCode).toBe(429);
315
- expect(res.headers['retry-after']).toEqual(expect.any(String));
316
- expect(res.json()).toMatchObject({
317
- code: 'rate-limited',
318
- details: {retry_after_seconds: expect.any(Number)},
319
- });
320
- expect(persistedCount).toBe(0);
321
- });
322
-
323
- it('returns 503 when the provisioner mint rate limiter is unavailable', async () => {
324
- const reservationId = await createReservation({count: 1});
325
- const identifierHmac = await seedProvisionerMintRateLimit(1);
326
-
327
- await db().transaction(async (tx) => {
328
- await tx.execute(sql`
329
- SELECT 1
330
- FROM runners_rate_limits
331
- WHERE identifier_hmac = ${identifierHmac}
332
- FOR UPDATE
333
- `);
334
-
335
- const res = await app.inject({
336
- method: 'POST',
337
- url: '/provisioners/runner-registration-tokens/batch',
338
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
339
- payload: body(reservationId, ['provisioned-runner-a']),
340
- });
341
-
342
- expect(res.statusCode).toBe(503);
343
- expect(res.json().code).toBe('runners-rate-limit-unavailable');
344
- });
345
-
346
- const persistedCount = await countEphemeralTokens();
347
- expect(persistedCount).toBe(0);
348
- });
349
-
350
- it('mints tokens that can register exactly once', async () => {
351
- const reservationId = await createReservation({count: 1});
352
- const mint = await app.inject({
353
- method: 'POST',
354
- url: '/provisioners/runner-registration-tokens/batch',
355
- headers: {authorization: `Bearer ${VALID_PROVISIONER_TOKEN}`},
356
- payload: body(reservationId, ['provisioned-runner-a']),
357
- });
358
- const registrationToken = mint.json().tokens[0].registration_token as string;
359
-
360
- const first = await app.inject({
361
- method: 'POST',
362
- url: '/runners/register',
363
- headers: {authorization: `Bearer ${registrationToken}`},
364
- payload: {labels: ['linux']},
365
- });
366
- const second = await app.inject({
367
- method: 'POST',
368
- url: '/runners/register',
369
- headers: {authorization: `Bearer ${registrationToken}`},
370
- payload: {labels: ['linux']},
371
- });
372
-
373
- expect(mint.statusCode).toBe(200);
374
- expect(first.statusCode).toBe(200);
375
- expect(first.json()).toMatchObject({mode: 'ephemeral', max_claims: 1});
376
- expect(second.statusCode).toBe(409);
377
- expect(second.json().code).toBe('registration-token-consumed');
378
- });
379
-
380
- async function createReservation(params: {
381
- count: number;
382
- workspaceId?: string;
383
- provisionerId?: string;
384
- expiresAt?: Date;
385
- }): Promise<string> {
386
- const [reservation] = await db()
387
- .insert(reservations)
388
- .values({
389
- workspaceId: params.workspaceId ?? workspaceId,
390
- provisionerId: params.provisionerId ?? provisionerTokenId,
391
- requiredLabels: ['linux'],
392
- count: params.count,
393
- expiresAt: params.expiresAt ?? new Date(Date.now() + 60_000),
394
- })
395
- .returning({id: reservations.id});
396
- if (!reservation) throw new Error('Insert returned no rows');
397
- return reservation.id;
398
- }
399
-
400
- async function countEphemeralTokens(): Promise<number> {
401
- const [row] = await db()
402
- .select({value: count()})
403
- .from(ephemeralRegistrationTokens)
404
- .where(
405
- and(
406
- eq(ephemeralRegistrationTokens.workspaceId, workspaceId),
407
- eq(ephemeralRegistrationTokens.provisionerId, provisionerTokenId),
408
- ),
409
- );
410
- return row?.value ?? 0;
411
- }
412
-
413
- function body(reservationId: string, provisionedRunnerIds: string[]) {
414
- return {
415
- reservation_id: reservationId,
416
- provisioned_runners: provisionedRunnerIds.map((provisionedRunnerId) => ({
417
- provisioned_runner_id: provisionedRunnerId,
418
- })),
419
- };
420
- }
421
-
422
- async function seedProvisionerMintRateLimit(seedCount: number): Promise<string> {
423
- const identifierHmac = hashRunnersRateLimitIdentifier({
424
- action: 'provisioner-mint',
425
- scope: 'provisioner',
426
- identifier: provisionerTokenId,
427
- });
428
- const windows = rateLimitWindows(config.PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS);
429
-
430
- await db()
431
- .insert(runnersRateLimits)
432
- .values(
433
- windows.map((windowStart) => ({
434
- action: 'provisioner-mint',
435
- scope: 'provisioner',
436
- identifierHmac,
437
- windowStart,
438
- count: seedCount,
439
- expiresAt: new Date(
440
- windowStart.getTime() + config.PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS * 1000,
441
- ),
442
- })),
443
- );
444
-
445
- return identifierHmac;
446
- }
447
-
448
- function rateLimitWindows(windowSeconds: number): [Date, Date] {
449
- const windowMs = windowSeconds * 1000;
450
- const currentWindowStart = Math.floor(Date.now() / windowMs) * windowMs;
451
- return [new Date(currentWindowStart), new Date(currentWindowStart + windowMs)];
452
- }
453
- });
@@ -1,82 +0,0 @@
1
- import {requireProvisionerContext} from '@shipfox/api-auth-context';
2
- import {
3
- mintRegistrationTokensBatchBodySchema,
4
- mintRegistrationTokensBatchResponseSchema,
5
- } from '@shipfox/api-runners-dto';
6
- import {ClientError, defineRoute} from '@shipfox/node-fastify';
7
- import {config} from '#config.js';
8
- import {mintEphemeralRegistrationTokensBatch} from '#core/ephemeral-registration-tokens.js';
9
- import {
10
- ActiveEphemeralRegistrationTokensExistError,
11
- RegistrationTokenBatchExceedsReservationError,
12
- RegistrationTokenBatchTooLargeError,
13
- ReservationExpiredError,
14
- ReservationNotFoundError,
15
- } from '#core/errors.js';
16
- import {
17
- toMintRegistrationTokensProvisionedRunners,
18
- toMintRegistrationTokensResponseDto,
19
- } from '#presentation/dto/index.js';
20
- import {createProvisionerMintRateLimitPreHandler} from './rate-limit.js';
21
-
22
- export const mintRegistrationTokensRoute = defineRoute({
23
- method: 'POST',
24
- path: '/runner-registration-tokens/batch',
25
- description: 'Mint ephemeral runner registration tokens for reserved provisioned runners',
26
- schema: {
27
- body: mintRegistrationTokensBatchBodySchema,
28
- response: {
29
- 200: mintRegistrationTokensBatchResponseSchema,
30
- },
31
- },
32
- preHandler: createProvisionerMintRateLimitPreHandler(),
33
- errorHandler: (error) => {
34
- if (error instanceof ReservationNotFoundError) {
35
- throw new ClientError('Reservation not found', 'reservation-not-found', {status: 404});
36
- }
37
- if (error instanceof ReservationExpiredError) {
38
- throw new ClientError('Reservation has expired', 'reservation-expired', {status: 409});
39
- }
40
- if (error instanceof RegistrationTokenBatchExceedsReservationError) {
41
- throw new ClientError('Batch exceeds reservation count', 'batch-exceeds-reservation', {
42
- status: 409,
43
- details: {
44
- requested: error.requested,
45
- reservation_count: error.reservationCount,
46
- already_minted: error.alreadyMinted,
47
- },
48
- });
49
- }
50
- if (error instanceof ActiveEphemeralRegistrationTokensExistError) {
51
- throw new ClientError('Registration token already active', 'registration-token-active', {
52
- status: 409,
53
- details: {provisioned_runner_ids: error.provisionedRunnerIds},
54
- });
55
- }
56
- if (error instanceof RegistrationTokenBatchTooLargeError) {
57
- throw new ClientError('Registration token batch is too large', 'batch-too-large', {
58
- status: 400,
59
- details: {
60
- requested: error.requested,
61
- max: error.max,
62
- },
63
- });
64
- }
65
- throw error;
66
- },
67
- handler: async (request) => {
68
- const {provisionerTokenId, workspaceId} = requireProvisionerContext(request);
69
- const result = await mintEphemeralRegistrationTokensBatch({
70
- workspaceId,
71
- provisionerId: provisionerTokenId,
72
- reservationId: request.body.reservation_id,
73
- provisionedRunners: toMintRegistrationTokensProvisionedRunners(
74
- request.body.provisioned_runners,
75
- ),
76
- ttlSeconds: config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS,
77
- maxBatchSize: config.REGISTRATION_TOKEN_BATCH_MAX,
78
- });
79
-
80
- return toMintRegistrationTokensResponseDto(result);
81
- },
82
- });
@@ -1,30 +0,0 @@
1
- import {requireProvisionerContext} from '@shipfox/api-auth-context';
2
- import {
3
- reconcileProvisionedRunnersBodySchema,
4
- reconcileProvisionedRunnersResponseSchema,
5
- } from '@shipfox/api-runners-dto';
6
- import {defineRoute} from '@shipfox/node-fastify';
7
- import {reconcileProvisionedRunners} from '#core/index.js';
8
- import {toReconcileProvisionedRunnersResponseDto} from '#presentation/dto/index.js';
9
-
10
- export const reconcileProvisionedRunnersRoute = defineRoute({
11
- method: 'POST',
12
- path: '/provisioned-runners/reconcile',
13
- description: 'Reconcile provisioned runner state for a provisioner',
14
- schema: {
15
- body: reconcileProvisionedRunnersBodySchema,
16
- response: {
17
- 200: reconcileProvisionedRunnersResponseSchema,
18
- },
19
- },
20
- handler: async (request) => {
21
- const {provisionerTokenId, workspaceId} = requireProvisionerContext(request);
22
- const result = await reconcileProvisionedRunners({
23
- workspaceId,
24
- provisionerId: provisionerTokenId,
25
- observedProvisionedRunnerIds: request.body.observed_provisioned_runner_ids,
26
- });
27
-
28
- return toReconcileProvisionedRunnersResponseDto(result);
29
- },
30
- });
@@ -1,78 +0,0 @@
1
- import {Factory} from 'fishery';
2
- import type {ProvisionedRunner} from '#core/entities/provisioned-runner.js';
3
- import {db} from '#db/db.js';
4
- import {provisionedRunners} from '#db/schema/provisioned-runners.js';
5
-
6
- export const provisionedRunnerFactory = Factory.define<ProvisionedRunner>(({onCreate}) => {
7
- onCreate(async (provisionedRunner) => {
8
- const [row] = await db()
9
- .insert(provisionedRunners)
10
- .values({
11
- workspaceId: provisionedRunner.workspaceId,
12
- provisionerId: provisionedRunner.provisionerId,
13
- provisionedRunnerId: provisionedRunner.provisionedRunnerId,
14
- reservationId: provisionedRunner.reservationId,
15
- templateKey: provisionedRunner.templateKey,
16
- labels: provisionedRunner.labels,
17
- state: provisionedRunner.state,
18
- reason: provisionedRunner.reason,
19
- runnerSessionId: provisionedRunner.runnerSessionId,
20
- providerKind: provisionedRunner.providerKind,
21
- reportedAt: provisionedRunner.reportedAt,
22
- startedAt: provisionedRunner.startedAt,
23
- stoppingAt: provisionedRunner.stoppingAt,
24
- stoppedAt: provisionedRunner.stoppedAt,
25
- failedAt: provisionedRunner.failedAt,
26
- terminatedAt: provisionedRunner.terminatedAt,
27
- reservationReleasedAt: provisionedRunner.reservationReleasedAt,
28
- })
29
- .returning();
30
-
31
- if (!row) throw new Error('Insert returned no rows');
32
- return {
33
- id: row.id,
34
- workspaceId: row.workspaceId,
35
- provisionerId: row.provisionerId,
36
- provisionedRunnerId: row.provisionedRunnerId,
37
- reservationId: row.reservationId,
38
- templateKey: row.templateKey,
39
- labels: row.labels,
40
- state: row.state,
41
- reason: row.reason,
42
- runnerSessionId: row.runnerSessionId,
43
- providerKind: row.providerKind,
44
- reportedAt: row.reportedAt,
45
- startedAt: row.startedAt,
46
- stoppingAt: row.stoppingAt,
47
- stoppedAt: row.stoppedAt,
48
- failedAt: row.failedAt,
49
- terminatedAt: row.terminatedAt,
50
- reservationReleasedAt: row.reservationReleasedAt,
51
- createdAt: row.createdAt,
52
- updatedAt: row.updatedAt,
53
- };
54
- });
55
-
56
- return {
57
- id: crypto.randomUUID(),
58
- workspaceId: crypto.randomUUID(),
59
- provisionerId: crypto.randomUUID(),
60
- provisionedRunnerId: crypto.randomUUID(),
61
- reservationId: null,
62
- templateKey: 'linux',
63
- labels: ['linux'],
64
- state: 'running',
65
- reason: null,
66
- runnerSessionId: null,
67
- providerKind: 'docker',
68
- reportedAt: new Date(),
69
- startedAt: null,
70
- stoppingAt: null,
71
- stoppedAt: null,
72
- failedAt: null,
73
- terminatedAt: null,
74
- reservationReleasedAt: null,
75
- createdAt: new Date(),
76
- updatedAt: new Date(),
77
- };
78
- });