@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/provisioner-capability-snapshots.ts"],"sourcesContent":["import {config} from '#config.js';\nimport {hasActiveWorkspaceProvisionerCapability as hasActiveWorkspaceProvisionerCapabilityDb} from '#db/provisioner-capability-snapshots.js';\n\nexport function hasActiveWorkspaceProvisionerCapability(params: {\n workspaceId: string;\n requiredLabels: string[];\n}): Promise<boolean> {\n return hasActiveWorkspaceProvisionerCapabilityDb({\n ...params,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n"],"names":["config","hasActiveWorkspaceProvisionerCapability","hasActiveWorkspaceProvisionerCapabilityDb","params","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS"],"mappings":"AAAA,SAAQA,MAAM,QAAO,aAAa;AAClC,SAAQC,2CAA2CC,yCAAyC,QAAO,0CAA0C;AAE7I,OAAO,SAASD,wCAAwCE,MAGvD;IACC,OAAOD,0CAA0C;QAC/C,GAAGC,MAAM;QACTC,eAAeJ,OAAOK,iCAAiC;IACzD;AACF"}
@@ -10,6 +10,12 @@ export interface CreateWorkspaceProvisionerTokenResult {
10
10
  rawToken: string;
11
11
  }
12
12
  export declare function createWorkspaceProvisionerToken(params: CreateWorkspaceProvisionerTokenParams): Promise<CreateWorkspaceProvisionerTokenResult>;
13
+ export interface CreateInstallationProvisionerTokenParams {
14
+ createdByUserId: string;
15
+ name?: string | undefined;
16
+ ttlSeconds?: number | undefined;
17
+ }
18
+ export declare function createInstallationProvisionerToken(params: CreateInstallationProvisionerTokenParams): Promise<CreateWorkspaceProvisionerTokenResult>;
13
19
  export declare function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]>;
14
20
  export declare function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]>;
15
21
  export declare function revokeWorkspaceProvisionerToken(params: {
@@ -17,4 +23,8 @@ export declare function revokeWorkspaceProvisionerToken(params: {
17
23
  workspaceId: string;
18
24
  revokedByUserId: string;
19
25
  }): Promise<ProvisionerToken>;
26
+ export declare function revokeInstallationProvisionerToken(params: {
27
+ tokenId: string;
28
+ revokedByUserId: string;
29
+ }): Promise<ProvisionerToken>;
20
30
  //# sourceMappingURL=provisioner-tokens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner-tokens.d.ts","sourceRoot":"","sources":["../../src/core/provisioner-tokens.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,sBAAsB,EAAE,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AAG9F,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,qCAAqC;IACpD,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,qCAAqC,CAAC,CAchD;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAE5F;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAK7F;AAED,wBAAsB,+BAA+B,CAAC,MAAM,EAAE;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAI5B"}
1
+ {"version":3,"file":"provisioner-tokens.d.ts","sourceRoot":"","sources":["../../src/core/provisioner-tokens.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,sBAAsB,EAAE,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AAG9F,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,qCAAqC;IACpD,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,qCAAqC,CAAC,CAehD;AAED,MAAM,WAAW,wCAAwC;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,wCAAwC,GAC/C,OAAO,CAAC,qCAAqC,CAAC,CAYhD;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAE5F;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAK7F;AAED,wBAAsB,+BAA+B,CAAC,MAAM,EAAE;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAI5B;AAED,wBAAsB,kCAAkC,CAAC,MAAM,EAAE;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAI5B"}
@@ -1,11 +1,12 @@
1
1
  import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
2
- import { createProvisionerToken, listActiveProvisionerTokens, listUsableProvisionerTokensByWorkspaceId, revokeProvisionerToken } from '#db/provisioner-tokens.js';
2
+ import { createProvisionerToken, listActiveProvisionerTokens, listUsableProvisionerTokensByWorkspaceId, revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb, revokeProvisionerToken } from '#db/provisioner-tokens.js';
3
3
  import { config } from '../config.js';
4
4
  import { ProvisionerTokenNotFoundError } from './errors.js';
5
5
  export async function createWorkspaceProvisionerToken(params) {
6
6
  const rawToken = generateOpaqueToken('provisionerToken');
7
7
  const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;
8
8
  const token = await createProvisionerToken({
9
+ scope: 'workspace',
9
10
  workspaceId: params.workspaceId,
10
11
  hashedToken: hashOpaqueToken(rawToken),
11
12
  prefix: extractDisplayPrefix(rawToken),
@@ -18,6 +19,22 @@ export async function createWorkspaceProvisionerToken(params) {
18
19
  rawToken
19
20
  };
20
21
  }
22
+ export async function createInstallationProvisionerToken(params) {
23
+ const rawToken = generateOpaqueToken('provisionerToken');
24
+ const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;
25
+ const token = await createProvisionerToken({
26
+ scope: 'installation',
27
+ hashedToken: hashOpaqueToken(rawToken),
28
+ prefix: extractDisplayPrefix(rawToken),
29
+ name: params.name,
30
+ createdByUserId: params.createdByUserId,
31
+ expiresAt
32
+ });
33
+ return {
34
+ token,
35
+ rawToken
36
+ };
37
+ }
21
38
  export function listUsableProvisionerTokens(workspaceId) {
22
39
  return listUsableProvisionerTokensByWorkspaceId(workspaceId);
23
40
  }
@@ -32,5 +49,10 @@ export async function revokeWorkspaceProvisionerToken(params) {
32
49
  if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);
33
50
  return token;
34
51
  }
52
+ export async function revokeInstallationProvisionerToken(params) {
53
+ const token = await revokeInstallationProvisionerTokenDb(params);
54
+ if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);
55
+ return token;
56
+ }
35
57
 
36
58
  //# sourceMappingURL=provisioner-tokens.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/provisioner-tokens.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {\n createProvisionerToken,\n listActiveProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n revokeProvisionerToken,\n} from '#db/provisioner-tokens.js';\nimport {config} from '../config.js';\nimport type {ActiveProvisionerToken, ProvisionerToken} from './entities/provisioner-token.js';\nimport {ProvisionerTokenNotFoundError} from './errors.js';\n\nexport interface CreateWorkspaceProvisionerTokenParams {\n workspaceId: string;\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport interface CreateWorkspaceProvisionerTokenResult {\n token: ProvisionerToken;\n rawToken: string;\n}\n\nexport async function createWorkspaceProvisionerToken(\n params: CreateWorkspaceProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n\n const token = await createProvisionerToken({\n workspaceId: params.workspaceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n\n return {token, rawToken};\n}\n\nexport function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]> {\n return listUsableProvisionerTokensByWorkspaceId(workspaceId);\n}\n\nexport function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]> {\n return listActiveProvisionerTokens({\n workspaceId,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n\nexport async function revokeWorkspaceProvisionerToken(params: {\n tokenId: string;\n workspaceId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeProvisionerToken(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","createProvisionerToken","listActiveProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","revokeProvisionerToken","config","ProvisionerTokenNotFoundError","createWorkspaceProvisionerToken","params","rawToken","expiresAt","ttlSeconds","Date","now","undefined","token","workspaceId","hashedToken","prefix","name","createdByUserId","listUsableProvisionerTokens","listActiveProvisioners","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS","revokeWorkspaceProvisionerToken","tokenId"],"mappings":"AAAA,SAAQA,oBAAoB,EAAEC,mBAAmB,EAAEC,eAAe,QAAO,uBAAuB;AAChG,SACEC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wCAAwC,EACxCC,sBAAsB,QACjB,4BAA4B;AACnC,SAAQC,MAAM,QAAO,eAAe;AAEpC,SAAQC,6BAA6B,QAAO,cAAc;AAc1D,OAAO,eAAeC,gCACpBC,MAA6C;IAE7C,MAAMC,WAAWV,oBAAoB;IACrC,MAAMW,YAAYF,OAAOG,UAAU,GAAG,IAAIC,KAAKA,KAAKC,GAAG,KAAKL,OAAOG,UAAU,GAAG,QAAQG;IAExF,MAAMC,QAAQ,MAAMd,uBAAuB;QACzCe,aAAaR,OAAOQ,WAAW;QAC/BC,aAAajB,gBAAgBS;QAC7BS,QAAQpB,qBAAqBW;QAC7BU,MAAMX,OAAOW,IAAI;QACjBC,iBAAiBZ,OAAOY,eAAe;QACvCV;IACF;IAEA,OAAO;QAACK;QAAON;IAAQ;AACzB;AAEA,OAAO,SAASY,4BAA4BL,WAAmB;IAC7D,OAAOb,yCAAyCa;AAClD;AAEA,OAAO,SAASM,uBAAuBN,WAAmB;IACxD,OAAOd,4BAA4B;QACjCc;QACAO,eAAelB,OAAOmB,iCAAiC;IACzD;AACF;AAEA,OAAO,eAAeC,gCAAgCjB,MAIrD;IACC,MAAMO,QAAQ,MAAMX,uBAAuBI;IAC3C,IAAI,CAACO,OAAO,MAAM,IAAIT,8BAA8BE,OAAOkB,OAAO;IAClE,OAAOX;AACT"}
1
+ {"version":3,"sources":["../../src/core/provisioner-tokens.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {\n createProvisionerToken,\n listActiveProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb,\n revokeProvisionerToken,\n} from '#db/provisioner-tokens.js';\nimport {config} from '../config.js';\nimport type {ActiveProvisionerToken, ProvisionerToken} from './entities/provisioner-token.js';\nimport {ProvisionerTokenNotFoundError} from './errors.js';\n\nexport interface CreateWorkspaceProvisionerTokenParams {\n workspaceId: string;\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport interface CreateWorkspaceProvisionerTokenResult {\n token: ProvisionerToken;\n rawToken: string;\n}\n\nexport async function createWorkspaceProvisionerToken(\n params: CreateWorkspaceProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n\n const token = await createProvisionerToken({\n scope: 'workspace',\n workspaceId: params.workspaceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n\n return {token, rawToken};\n}\n\nexport interface CreateInstallationProvisionerTokenParams {\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport async function createInstallationProvisionerToken(\n params: CreateInstallationProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n const token = await createProvisionerToken({\n scope: 'installation',\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n return {token, rawToken};\n}\n\nexport function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]> {\n return listUsableProvisionerTokensByWorkspaceId(workspaceId);\n}\n\nexport function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]> {\n return listActiveProvisionerTokens({\n workspaceId,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n\nexport async function revokeWorkspaceProvisionerToken(params: {\n tokenId: string;\n workspaceId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeProvisionerToken(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n\nexport async function revokeInstallationProvisionerToken(params: {\n tokenId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeInstallationProvisionerTokenDb(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","createProvisionerToken","listActiveProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","revokeInstallationProvisionerToken","revokeInstallationProvisionerTokenDb","revokeProvisionerToken","config","ProvisionerTokenNotFoundError","createWorkspaceProvisionerToken","params","rawToken","expiresAt","ttlSeconds","Date","now","undefined","token","scope","workspaceId","hashedToken","prefix","name","createdByUserId","createInstallationProvisionerToken","listUsableProvisionerTokens","listActiveProvisioners","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS","revokeWorkspaceProvisionerToken","tokenId"],"mappings":"AAAA,SAAQA,oBAAoB,EAAEC,mBAAmB,EAAEC,eAAe,QAAO,uBAAuB;AAChG,SACEC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wCAAwC,EACxCC,sCAAsCC,oCAAoC,EAC1EC,sBAAsB,QACjB,4BAA4B;AACnC,SAAQC,MAAM,QAAO,eAAe;AAEpC,SAAQC,6BAA6B,QAAO,cAAc;AAc1D,OAAO,eAAeC,gCACpBC,MAA6C;IAE7C,MAAMC,WAAWZ,oBAAoB;IACrC,MAAMa,YAAYF,OAAOG,UAAU,GAAG,IAAIC,KAAKA,KAAKC,GAAG,KAAKL,OAAOG,UAAU,GAAG,QAAQG;IAExF,MAAMC,QAAQ,MAAMhB,uBAAuB;QACzCiB,OAAO;QACPC,aAAaT,OAAOS,WAAW;QAC/BC,aAAapB,gBAAgBW;QAC7BU,QAAQvB,qBAAqBa;QAC7BW,MAAMZ,OAAOY,IAAI;QACjBC,iBAAiBb,OAAOa,eAAe;QACvCX;IACF;IAEA,OAAO;QAACK;QAAON;IAAQ;AACzB;AAQA,OAAO,eAAea,mCACpBd,MAAgD;IAEhD,MAAMC,WAAWZ,oBAAoB;IACrC,MAAMa,YAAYF,OAAOG,UAAU,GAAG,IAAIC,KAAKA,KAAKC,GAAG,KAAKL,OAAOG,UAAU,GAAG,QAAQG;IACxF,MAAMC,QAAQ,MAAMhB,uBAAuB;QACzCiB,OAAO;QACPE,aAAapB,gBAAgBW;QAC7BU,QAAQvB,qBAAqBa;QAC7BW,MAAMZ,OAAOY,IAAI;QACjBC,iBAAiBb,OAAOa,eAAe;QACvCX;IACF;IACA,OAAO;QAACK;QAAON;IAAQ;AACzB;AAEA,OAAO,SAASc,4BAA4BN,WAAmB;IAC7D,OAAOhB,yCAAyCgB;AAClD;AAEA,OAAO,SAASO,uBAAuBP,WAAmB;IACxD,OAAOjB,4BAA4B;QACjCiB;QACAQ,eAAepB,OAAOqB,iCAAiC;IACzD;AACF;AAEA,OAAO,eAAeC,gCAAgCnB,MAIrD;IACC,MAAMO,QAAQ,MAAMX,uBAAuBI;IAC3C,IAAI,CAACO,OAAO,MAAM,IAAIT,8BAA8BE,OAAOoB,OAAO;IAClE,OAAOb;AACT;AAEA,OAAO,eAAeb,mCAAmCM,MAGxD;IACC,MAAMO,QAAQ,MAAMZ,qCAAqCK;IACzD,IAAI,CAACO,OAAO,MAAM,IAAIT,8BAA8BE,OAAOoB,OAAO;IAClE,OAAOb;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/core/rate-limit.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAKlC,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,iBAAiB,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,CAAC;AACvD,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC;AAErD,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,qBAAa,6BAA8B,SAAQ,sBAAsB,CACvE,sBAAsB,EACtB,qBAAqB,CACtB;gBACa,MAAM,EAAE;QAClB,MAAM,EAAE,sBAAsB,CAAC;QAC/B,KAAK,EAAE,qBAAqB,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,oBAAoB,EAAE,MAAM,CAAC;KAC9B;CAIF;AAED,qBAAa,gCAAiC,SAAQ,yBAAyB,CAC7E,sBAAsB,EACtB,qBAAqB,CACtB;gBACa,MAAM,EAAE;QAClB,MAAM,EAAE,sBAAsB,CAAC;QAC/B,KAAK,EAAE,qBAAqB,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,KAAK,EAAE,OAAO,CAAC;KAChB;CAIF;AAKD,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAQT;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC9F"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/core/rate-limit.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAKlC,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,iBAAiB,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,CAAC;AACvD,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC;AAErD,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,qBAAa,6BAA8B,SAAQ,sBAAsB,CACvE,sBAAsB,EACtB,qBAAqB,CACtB;gBACa,MAAM,EAAE;QAClB,MAAM,EAAE,sBAAsB,CAAC;QAC/B,KAAK,EAAE,qBAAqB,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,oBAAoB,EAAE,MAAM,CAAC;KAC9B;CAIF;AAED,qBAAa,gCAAiC,SAAQ,yBAAyB,CAC7E,sBAAsB,EACtB,qBAAqB,CACtB;gBACa,MAAM,EAAE;QAClB,MAAM,EAAE,sBAAsB,CAAC;QAC/B,KAAK,EAAE,qBAAqB,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,KAAK,EAAE,OAAO,CAAC;KAChB;CAIF;AAID,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAQT;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC9F"}
@@ -1,5 +1,4 @@
1
- import { createHmac } from 'node:crypto';
2
- import { config as authConfig } from '@shipfox/api-auth/config';
1
+ import { rateLimitIdentifierKey } from '@shipfox/node-auth-root-key';
3
2
  import { checkRateLimit, hashRateLimitIdentifier, RateLimitExceededError, RateLimitUnavailableError } from '@shipfox/node-rate-limit';
4
3
  import { config } from '#config.js';
5
4
  import { consumeRunnersRateLimit, pruneExpiredRunnersRateLimits } from '#db/rate-limits.js';
@@ -17,7 +16,6 @@ export class RunnersRateLimitUnavailableError extends RateLimitUnavailableError
17
16
  }
18
17
  }
19
18
  const IDENTIFIER_HASH_DOMAIN = 'shipfox.runners.rate-limit.identifier.v1';
20
- const IDENTIFIER_SECRET_DERIVATION_DOMAIN = 'shipfox.runners.rate-limit.identifier-secret.v1';
21
19
  export function hashRunnersRateLimitIdentifier(params) {
22
20
  return hashRateLimitIdentifier({
23
21
  action: params.action,
@@ -65,10 +63,7 @@ export async function checkRunnersRateLimit(params) {
65
63
  }
66
64
  }
67
65
  function effectiveIdentifierSecret() {
68
- if (config.RATE_LIMIT_IDENTIFIER_SECRET) {
69
- return config.RATE_LIMIT_IDENTIFIER_SECRET;
70
- }
71
- return createHmac('sha256', authConfig.AUTH_JWT_SECRET).update(IDENTIFIER_SECRET_DERIVATION_DOMAIN).digest();
66
+ return rateLimitIdentifierKey();
72
67
  }
73
68
 
74
69
  //# sourceMappingURL=rate-limit.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/rate-limit.ts"],"sourcesContent":["import {createHmac} from 'node:crypto';\nimport {config as authConfig} from '@shipfox/api-auth/config';\nimport {\n checkRateLimit,\n hashRateLimitIdentifier,\n RateLimitExceededError,\n type RateLimitOutcome,\n type RateLimitPolicy,\n RateLimitUnavailableError,\n} from '@shipfox/node-rate-limit';\nimport {config} from '#config.js';\nimport {consumeRunnersRateLimit, pruneExpiredRunnersRateLimits} from '#db/rate-limits.js';\nimport {recordRunnersRateLimitCheck, recordRunnersRateLimitPruneFailure} from '#metrics/index.js';\n\nexport type RunnersRateLimitAction = 'provisioner-mint' | 'ephemeral-register';\nexport type RunnersRateLimitScope = 'provisioner' | 'ephemeral-token';\nexport type RunnersRateLimitOutcome = RateLimitOutcome;\nexport type RunnersRateLimitPolicy = RateLimitPolicy;\n\nexport interface CheckRunnersRateLimitParams extends RunnersRateLimitPolicy {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifier: string;\n now?: Date | undefined;\n timeoutMs?: number | undefined;\n}\n\nexport class RunnersRateLimitExceededError extends RateLimitExceededError<\n RunnersRateLimitAction,\n RunnersRateLimitScope\n> {\n constructor(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n retryAfterSeconds: number;\n identifierHmacPrefix: string;\n }) {\n super(params);\n this.name = 'RunnersRateLimitExceededError';\n }\n}\n\nexport class RunnersRateLimitUnavailableError extends RateLimitUnavailableError<\n RunnersRateLimitAction,\n RunnersRateLimitScope\n> {\n constructor(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifierHmacPrefix: string;\n cause: unknown;\n }) {\n super(params);\n this.name = 'RunnersRateLimitUnavailableError';\n }\n}\n\nconst IDENTIFIER_HASH_DOMAIN = 'shipfox.runners.rate-limit.identifier.v1';\nconst IDENTIFIER_SECRET_DERIVATION_DOMAIN = 'shipfox.runners.rate-limit.identifier-secret.v1';\n\nexport function hashRunnersRateLimitIdentifier(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifier: string;\n}): string {\n return hashRateLimitIdentifier({\n action: params.action,\n scope: params.scope,\n identifier: params.identifier,\n secret: effectiveIdentifierSecret(),\n domain: IDENTIFIER_HASH_DOMAIN,\n });\n}\n\nexport async function checkRunnersRateLimit(params: CheckRunnersRateLimitParams): Promise<void> {\n try {\n await checkRateLimit({\n action: params.action,\n scope: params.scope,\n identifier: params.identifier,\n limit: params.limit,\n windowSeconds: params.windowSeconds,\n identifierSecret: effectiveIdentifierSecret(),\n identifierHashDomain: IDENTIFIER_HASH_DOMAIN,\n consume: consumeRunnersRateLimit,\n prune: pruneExpiredRunnersRateLimits,\n onCheck: recordRunnersRateLimitCheck,\n onPruneFailure: recordRunnersRateLimitPruneFailure,\n now: params.now,\n timeoutMs: params.timeoutMs ?? config.RUNNERS_RATE_LIMIT_TIMEOUT_MS,\n });\n } catch (error) {\n if (error instanceof RateLimitExceededError) {\n throw new RunnersRateLimitExceededError({\n action: error.action,\n scope: error.scope,\n retryAfterSeconds: error.retryAfterSeconds,\n identifierHmacPrefix: error.identifierHmacPrefix,\n });\n }\n if (error instanceof RateLimitUnavailableError) {\n throw new RunnersRateLimitUnavailableError({\n action: error.action,\n scope: error.scope,\n identifierHmacPrefix: error.identifierHmacPrefix,\n cause: error.cause,\n });\n }\n throw error;\n }\n}\n\nfunction effectiveIdentifierSecret(): Buffer | string {\n if (config.RATE_LIMIT_IDENTIFIER_SECRET) {\n return config.RATE_LIMIT_IDENTIFIER_SECRET;\n }\n\n return createHmac('sha256', authConfig.AUTH_JWT_SECRET)\n .update(IDENTIFIER_SECRET_DERIVATION_DOMAIN)\n .digest();\n}\n"],"names":["createHmac","config","authConfig","checkRateLimit","hashRateLimitIdentifier","RateLimitExceededError","RateLimitUnavailableError","consumeRunnersRateLimit","pruneExpiredRunnersRateLimits","recordRunnersRateLimitCheck","recordRunnersRateLimitPruneFailure","RunnersRateLimitExceededError","params","name","RunnersRateLimitUnavailableError","IDENTIFIER_HASH_DOMAIN","IDENTIFIER_SECRET_DERIVATION_DOMAIN","hashRunnersRateLimitIdentifier","action","scope","identifier","secret","effectiveIdentifierSecret","domain","checkRunnersRateLimit","limit","windowSeconds","identifierSecret","identifierHashDomain","consume","prune","onCheck","onPruneFailure","now","timeoutMs","RUNNERS_RATE_LIMIT_TIMEOUT_MS","error","retryAfterSeconds","identifierHmacPrefix","cause","RATE_LIMIT_IDENTIFIER_SECRET","AUTH_JWT_SECRET","update","digest"],"mappings":"AAAA,SAAQA,UAAU,QAAO,cAAc;AACvC,SAAQC,UAAUC,UAAU,QAAO,2BAA2B;AAC9D,SACEC,cAAc,EACdC,uBAAuB,EACvBC,sBAAsB,EAGtBC,yBAAyB,QACpB,2BAA2B;AAClC,SAAQL,MAAM,QAAO,aAAa;AAClC,SAAQM,uBAAuB,EAAEC,6BAA6B,QAAO,qBAAqB;AAC1F,SAAQC,2BAA2B,EAAEC,kCAAkC,QAAO,oBAAoB;AAelG,OAAO,MAAMC,sCAAsCN;IAIjD,YAAYO,MAKX,CAAE;QACD,KAAK,CAACA;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMC,yCAAyCR;IAIpD,YAAYM,MAKX,CAAE;QACD,KAAK,CAACA;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,MAAME,yBAAyB;AAC/B,MAAMC,sCAAsC;AAE5C,OAAO,SAASC,+BAA+BL,MAI9C;IACC,OAAOR,wBAAwB;QAC7Bc,QAAQN,OAAOM,MAAM;QACrBC,OAAOP,OAAOO,KAAK;QACnBC,YAAYR,OAAOQ,UAAU;QAC7BC,QAAQC;QACRC,QAAQR;IACV;AACF;AAEA,OAAO,eAAeS,sBAAsBZ,MAAmC;IAC7E,IAAI;QACF,MAAMT,eAAe;YACnBe,QAAQN,OAAOM,MAAM;YACrBC,OAAOP,OAAOO,KAAK;YACnBC,YAAYR,OAAOQ,UAAU;YAC7BK,OAAOb,OAAOa,KAAK;YACnBC,eAAed,OAAOc,aAAa;YACnCC,kBAAkBL;YAClBM,sBAAsBb;YACtBc,SAAStB;YACTuB,OAAOtB;YACPuB,SAAStB;YACTuB,gBAAgBtB;YAChBuB,KAAKrB,OAAOqB,GAAG;YACfC,WAAWtB,OAAOsB,SAAS,IAAIjC,OAAOkC,6BAA6B;QACrE;IACF,EAAE,OAAOC,OAAO;QACd,IAAIA,iBAAiB/B,wBAAwB;YAC3C,MAAM,IAAIM,8BAA8B;gBACtCO,QAAQkB,MAAMlB,MAAM;gBACpBC,OAAOiB,MAAMjB,KAAK;gBAClBkB,mBAAmBD,MAAMC,iBAAiB;gBAC1CC,sBAAsBF,MAAME,oBAAoB;YAClD;QACF;QACA,IAAIF,iBAAiB9B,2BAA2B;YAC9C,MAAM,IAAIQ,iCAAiC;gBACzCI,QAAQkB,MAAMlB,MAAM;gBACpBC,OAAOiB,MAAMjB,KAAK;gBAClBmB,sBAAsBF,MAAME,oBAAoB;gBAChDC,OAAOH,MAAMG,KAAK;YACpB;QACF;QACA,MAAMH;IACR;AACF;AAEA,SAASd;IACP,IAAIrB,OAAOuC,4BAA4B,EAAE;QACvC,OAAOvC,OAAOuC,4BAA4B;IAC5C;IAEA,OAAOxC,WAAW,UAAUE,WAAWuC,eAAe,EACnDC,MAAM,CAAC1B,qCACP2B,MAAM;AACX"}
1
+ {"version":3,"sources":["../../src/core/rate-limit.ts"],"sourcesContent":["import {rateLimitIdentifierKey} from '@shipfox/node-auth-root-key';\nimport {\n checkRateLimit,\n hashRateLimitIdentifier,\n RateLimitExceededError,\n type RateLimitOutcome,\n type RateLimitPolicy,\n RateLimitUnavailableError,\n} from '@shipfox/node-rate-limit';\nimport {config} from '#config.js';\nimport {consumeRunnersRateLimit, pruneExpiredRunnersRateLimits} from '#db/rate-limits.js';\nimport {recordRunnersRateLimitCheck, recordRunnersRateLimitPruneFailure} from '#metrics/index.js';\n\nexport type RunnersRateLimitAction = 'provisioner-mint' | 'ephemeral-register';\nexport type RunnersRateLimitScope = 'provisioner' | 'ephemeral-token';\nexport type RunnersRateLimitOutcome = RateLimitOutcome;\nexport type RunnersRateLimitPolicy = RateLimitPolicy;\n\nexport interface CheckRunnersRateLimitParams extends RunnersRateLimitPolicy {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifier: string;\n now?: Date | undefined;\n timeoutMs?: number | undefined;\n}\n\nexport class RunnersRateLimitExceededError extends RateLimitExceededError<\n RunnersRateLimitAction,\n RunnersRateLimitScope\n> {\n constructor(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n retryAfterSeconds: number;\n identifierHmacPrefix: string;\n }) {\n super(params);\n this.name = 'RunnersRateLimitExceededError';\n }\n}\n\nexport class RunnersRateLimitUnavailableError extends RateLimitUnavailableError<\n RunnersRateLimitAction,\n RunnersRateLimitScope\n> {\n constructor(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifierHmacPrefix: string;\n cause: unknown;\n }) {\n super(params);\n this.name = 'RunnersRateLimitUnavailableError';\n }\n}\n\nconst IDENTIFIER_HASH_DOMAIN = 'shipfox.runners.rate-limit.identifier.v1';\n\nexport function hashRunnersRateLimitIdentifier(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifier: string;\n}): string {\n return hashRateLimitIdentifier({\n action: params.action,\n scope: params.scope,\n identifier: params.identifier,\n secret: effectiveIdentifierSecret(),\n domain: IDENTIFIER_HASH_DOMAIN,\n });\n}\n\nexport async function checkRunnersRateLimit(params: CheckRunnersRateLimitParams): Promise<void> {\n try {\n await checkRateLimit({\n action: params.action,\n scope: params.scope,\n identifier: params.identifier,\n limit: params.limit,\n windowSeconds: params.windowSeconds,\n identifierSecret: effectiveIdentifierSecret(),\n identifierHashDomain: IDENTIFIER_HASH_DOMAIN,\n consume: consumeRunnersRateLimit,\n prune: pruneExpiredRunnersRateLimits,\n onCheck: recordRunnersRateLimitCheck,\n onPruneFailure: recordRunnersRateLimitPruneFailure,\n now: params.now,\n timeoutMs: params.timeoutMs ?? config.RUNNERS_RATE_LIMIT_TIMEOUT_MS,\n });\n } catch (error) {\n if (error instanceof RateLimitExceededError) {\n throw new RunnersRateLimitExceededError({\n action: error.action,\n scope: error.scope,\n retryAfterSeconds: error.retryAfterSeconds,\n identifierHmacPrefix: error.identifierHmacPrefix,\n });\n }\n if (error instanceof RateLimitUnavailableError) {\n throw new RunnersRateLimitUnavailableError({\n action: error.action,\n scope: error.scope,\n identifierHmacPrefix: error.identifierHmacPrefix,\n cause: error.cause,\n });\n }\n throw error;\n }\n}\n\nfunction effectiveIdentifierSecret(): Uint8Array {\n return rateLimitIdentifierKey();\n}\n"],"names":["rateLimitIdentifierKey","checkRateLimit","hashRateLimitIdentifier","RateLimitExceededError","RateLimitUnavailableError","config","consumeRunnersRateLimit","pruneExpiredRunnersRateLimits","recordRunnersRateLimitCheck","recordRunnersRateLimitPruneFailure","RunnersRateLimitExceededError","params","name","RunnersRateLimitUnavailableError","IDENTIFIER_HASH_DOMAIN","hashRunnersRateLimitIdentifier","action","scope","identifier","secret","effectiveIdentifierSecret","domain","checkRunnersRateLimit","limit","windowSeconds","identifierSecret","identifierHashDomain","consume","prune","onCheck","onPruneFailure","now","timeoutMs","RUNNERS_RATE_LIMIT_TIMEOUT_MS","error","retryAfterSeconds","identifierHmacPrefix","cause"],"mappings":"AAAA,SAAQA,sBAAsB,QAAO,8BAA8B;AACnE,SACEC,cAAc,EACdC,uBAAuB,EACvBC,sBAAsB,EAGtBC,yBAAyB,QACpB,2BAA2B;AAClC,SAAQC,MAAM,QAAO,aAAa;AAClC,SAAQC,uBAAuB,EAAEC,6BAA6B,QAAO,qBAAqB;AAC1F,SAAQC,2BAA2B,EAAEC,kCAAkC,QAAO,oBAAoB;AAelG,OAAO,MAAMC,sCAAsCP;IAIjD,YAAYQ,MAKX,CAAE;QACD,KAAK,CAACA;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMC,yCAAyCT;IAIpD,YAAYO,MAKX,CAAE;QACD,KAAK,CAACA;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,MAAME,yBAAyB;AAE/B,OAAO,SAASC,+BAA+BJ,MAI9C;IACC,OAAOT,wBAAwB;QAC7Bc,QAAQL,OAAOK,MAAM;QACrBC,OAAON,OAAOM,KAAK;QACnBC,YAAYP,OAAOO,UAAU;QAC7BC,QAAQC;QACRC,QAAQP;IACV;AACF;AAEA,OAAO,eAAeQ,sBAAsBX,MAAmC;IAC7E,IAAI;QACF,MAAMV,eAAe;YACnBe,QAAQL,OAAOK,MAAM;YACrBC,OAAON,OAAOM,KAAK;YACnBC,YAAYP,OAAOO,UAAU;YAC7BK,OAAOZ,OAAOY,KAAK;YACnBC,eAAeb,OAAOa,aAAa;YACnCC,kBAAkBL;YAClBM,sBAAsBZ;YACtBa,SAASrB;YACTsB,OAAOrB;YACPsB,SAASrB;YACTsB,gBAAgBrB;YAChBsB,KAAKpB,OAAOoB,GAAG;YACfC,WAAWrB,OAAOqB,SAAS,IAAI3B,OAAO4B,6BAA6B;QACrE;IACF,EAAE,OAAOC,OAAO;QACd,IAAIA,iBAAiB/B,wBAAwB;YAC3C,MAAM,IAAIO,8BAA8B;gBACtCM,QAAQkB,MAAMlB,MAAM;gBACpBC,OAAOiB,MAAMjB,KAAK;gBAClBkB,mBAAmBD,MAAMC,iBAAiB;gBAC1CC,sBAAsBF,MAAME,oBAAoB;YAClD;QACF;QACA,IAAIF,iBAAiB9B,2BAA2B;YAC9C,MAAM,IAAIS,iCAAiC;gBACzCG,QAAQkB,MAAMlB,MAAM;gBACpBC,OAAOiB,MAAMjB,KAAK;gBAClBmB,sBAAsBF,MAAME,oBAAoB;gBAChDC,OAAOH,MAAMG,KAAK;YACpB;QACF;QACA,MAAMH;IACR;AACF;AAEA,SAASd;IACP,OAAOpB;AACT"}
@@ -0,0 +1,13 @@
1
+ export declare function issueRunnerActivationToken(params: {
2
+ runnerInstanceId: string;
3
+ provisionerId: string;
4
+ ttlSeconds: number;
5
+ }): Promise<string | null>;
6
+ export declare function getRunnerAssignment(params: {
7
+ runnerInstanceId: string;
8
+ provisionerId: string;
9
+ }): Promise<{
10
+ workspaceId: string | null;
11
+ runnerSessionId: string | null;
12
+ } | null>;
13
+ //# sourceMappingURL=runner-activation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-activation.d.ts","sourceRoot":"","sources":["../../src/core/runner-activation.ts"],"names":[],"mappings":"AAMA,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyCzB;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;;;UAeA"}
@@ -0,0 +1,36 @@
1
+ import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
2
+ import { and, eq, isNull, sql } from 'drizzle-orm';
3
+ import { db } from '#db/db.js';
4
+ import { runnerActivationTokens } from '#db/schema/runner-activation-tokens.js';
5
+ import { providerRunners } from '#db/schema/runner-instances.js';
6
+ export async function issueRunnerActivationToken(params) {
7
+ return await db().transaction(async (tx)=>{
8
+ await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`runners_activation:${params.runnerInstanceId}`}))`);
9
+ const [runner] = await tx.select({
10
+ workspaceId: providerRunners.workspaceId,
11
+ runnerSessionId: providerRunners.runnerSessionId,
12
+ state: providerRunners.state
13
+ }).from(providerRunners).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId))).limit(1).for('update');
14
+ if (!runner?.workspaceId || runner.runnerSessionId || runner.state !== 'running') return null;
15
+ await tx.update(runnerActivationTokens).set({
16
+ revokedAt: sql`now()`
17
+ }).where(and(eq(runnerActivationTokens.runnerInstanceId, params.runnerInstanceId), isNull(runnerActivationTokens.consumedAt), isNull(runnerActivationTokens.revokedAt)));
18
+ const rawToken = generateOpaqueToken('runnerActivationToken');
19
+ await tx.insert(runnerActivationTokens).values({
20
+ runnerInstanceId: params.runnerInstanceId,
21
+ hashedToken: hashOpaqueToken(rawToken),
22
+ prefix: extractDisplayPrefix(rawToken),
23
+ expiresAt: new Date(Date.now() + params.ttlSeconds * 1000)
24
+ });
25
+ return rawToken;
26
+ });
27
+ }
28
+ export async function getRunnerAssignment(params) {
29
+ const [runner] = await db().select({
30
+ workspaceId: providerRunners.workspaceId,
31
+ runnerSessionId: providerRunners.runnerSessionId
32
+ }).from(providerRunners).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId))).limit(1);
33
+ return runner?.workspaceId && !runner.runnerSessionId ? runner : null;
34
+ }
35
+
36
+ //# sourceMappingURL=runner-activation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/runner-activation.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {and, eq, isNull, sql} from 'drizzle-orm';\nimport {db} from '#db/db.js';\nimport {runnerActivationTokens} from '#db/schema/runner-activation-tokens.js';\nimport {providerRunners} from '#db/schema/runner-instances.js';\n\nexport async function issueRunnerActivationToken(params: {\n runnerInstanceId: string;\n provisionerId: string;\n ttlSeconds: number;\n}): Promise<string | null> {\n return await db().transaction(async (tx) => {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${`runners_activation:${params.runnerInstanceId}`}))`,\n );\n const [runner] = await tx\n .select({\n workspaceId: providerRunners.workspaceId,\n runnerSessionId: providerRunners.runnerSessionId,\n state: providerRunners.state,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n ),\n )\n .limit(1)\n .for('update');\n if (!runner?.workspaceId || runner.runnerSessionId || runner.state !== 'running') return null;\n\n await tx\n .update(runnerActivationTokens)\n .set({revokedAt: sql`now()`})\n .where(\n and(\n eq(runnerActivationTokens.runnerInstanceId, params.runnerInstanceId),\n isNull(runnerActivationTokens.consumedAt),\n isNull(runnerActivationTokens.revokedAt),\n ),\n );\n const rawToken = generateOpaqueToken('runnerActivationToken');\n await tx.insert(runnerActivationTokens).values({\n runnerInstanceId: params.runnerInstanceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n expiresAt: new Date(Date.now() + params.ttlSeconds * 1000),\n });\n return rawToken;\n });\n}\n\nexport async function getRunnerAssignment(params: {\n runnerInstanceId: string;\n provisionerId: string;\n}) {\n const [runner] = await db()\n .select({\n workspaceId: providerRunners.workspaceId,\n runnerSessionId: providerRunners.runnerSessionId,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n ),\n )\n .limit(1);\n return runner?.workspaceId && !runner.runnerSessionId ? runner : null;\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","and","eq","isNull","sql","db","runnerActivationTokens","providerRunners","issueRunnerActivationToken","params","transaction","tx","execute","runnerInstanceId","runner","select","workspaceId","runnerSessionId","state","from","where","id","provisionerId","limit","for","update","set","revokedAt","consumedAt","rawToken","insert","values","hashedToken","prefix","expiresAt","Date","now","ttlSeconds","getRunnerAssignment"],"mappings":"AAAA,SAAQA,oBAAoB,EAAEC,mBAAmB,EAAEC,eAAe,QAAO,uBAAuB;AAChG,SAAQC,GAAG,EAAEC,EAAE,EAAEC,MAAM,EAAEC,GAAG,QAAO,cAAc;AACjD,SAAQC,EAAE,QAAO,YAAY;AAC7B,SAAQC,sBAAsB,QAAO,yCAAyC;AAC9E,SAAQC,eAAe,QAAO,iCAAiC;AAE/D,OAAO,eAAeC,2BAA2BC,MAIhD;IACC,OAAO,MAAMJ,KAAKK,WAAW,CAAC,OAAOC;QACnC,MAAMA,GAAGC,OAAO,CACdR,GAAG,CAAC,sCAAsC,EAAE,CAAC,mBAAmB,EAAEK,OAAOI,gBAAgB,EAAE,CAAC,EAAE,CAAC;QAEjG,MAAM,CAACC,OAAO,GAAG,MAAMH,GACpBI,MAAM,CAAC;YACNC,aAAaT,gBAAgBS,WAAW;YACxCC,iBAAiBV,gBAAgBU,eAAe;YAChDC,OAAOX,gBAAgBW,KAAK;QAC9B,GACCC,IAAI,CAACZ,iBACLa,KAAK,CACJnB,IACEC,GAAGK,gBAAgBc,EAAE,EAAEZ,OAAOI,gBAAgB,GAC9CX,GAAGK,gBAAgBe,aAAa,EAAEb,OAAOa,aAAa,IAGzDC,KAAK,CAAC,GACNC,GAAG,CAAC;QACP,IAAI,CAACV,QAAQE,eAAeF,OAAOG,eAAe,IAAIH,OAAOI,KAAK,KAAK,WAAW,OAAO;QAEzF,MAAMP,GACHc,MAAM,CAACnB,wBACPoB,GAAG,CAAC;YAACC,WAAWvB,GAAG,CAAC,KAAK,CAAC;QAAA,GAC1BgB,KAAK,CACJnB,IACEC,GAAGI,uBAAuBO,gBAAgB,EAAEJ,OAAOI,gBAAgB,GACnEV,OAAOG,uBAAuBsB,UAAU,GACxCzB,OAAOG,uBAAuBqB,SAAS;QAG7C,MAAME,WAAW9B,oBAAoB;QACrC,MAAMY,GAAGmB,MAAM,CAACxB,wBAAwByB,MAAM,CAAC;YAC7ClB,kBAAkBJ,OAAOI,gBAAgB;YACzCmB,aAAahC,gBAAgB6B;YAC7BI,QAAQnC,qBAAqB+B;YAC7BK,WAAW,IAAIC,KAAKA,KAAKC,GAAG,KAAK3B,OAAO4B,UAAU,GAAG;QACvD;QACA,OAAOR;IACT;AACF;AAEA,OAAO,eAAeS,oBAAoB7B,MAGzC;IACC,MAAM,CAACK,OAAO,GAAG,MAAMT,KACpBU,MAAM,CAAC;QACNC,aAAaT,gBAAgBS,WAAW;QACxCC,iBAAiBV,gBAAgBU,eAAe;IAClD,GACCE,IAAI,CAACZ,iBACLa,KAAK,CACJnB,IACEC,GAAGK,gBAAgBc,EAAE,EAAEZ,OAAOI,gBAAgB,GAC9CX,GAAGK,gBAAgBe,aAAa,EAAEb,OAAOa,aAAa,IAGzDC,KAAK,CAAC;IACT,OAAOT,QAAQE,eAAe,CAACF,OAAOG,eAAe,GAAGH,SAAS;AACnE"}
@@ -0,0 +1,6 @@
1
+ export declare function assignRunnerInstances(params: {
2
+ provisionerId: string;
3
+ reservationId: string;
4
+ runnerInstanceIds: string[];
5
+ }): Promise<string[]>;
6
+ //# sourceMappingURL=runner-assignments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-assignments.d.ts","sourceRoot":"","sources":["../../src/core/runner-assignments.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAEpB"}
@@ -0,0 +1,6 @@
1
+ import { assignRunnerInstances as assignRunnerInstancesDb } from '#db/runner-assignments.js';
2
+ export function assignRunnerInstances(params) {
3
+ return assignRunnerInstancesDb(params);
4
+ }
5
+
6
+ //# sourceMappingURL=runner-assignments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/runner-assignments.ts"],"sourcesContent":["import {assignRunnerInstances as assignRunnerInstancesDb} from '#db/runner-assignments.js';\n\nexport function assignRunnerInstances(params: {\n provisionerId: string;\n reservationId: string;\n runnerInstanceIds: string[];\n}): Promise<string[]> {\n return assignRunnerInstancesDb(params);\n}\n"],"names":["assignRunnerInstances","assignRunnerInstancesDb","params"],"mappings":"AAAA,SAAQA,yBAAyBC,uBAAuB,QAAO,4BAA4B;AAE3F,OAAO,SAASD,sBAAsBE,MAIrC;IACC,OAAOD,wBAAwBC;AACjC"}
@@ -0,0 +1,46 @@
1
+ import type { RunnerToolCapabilitiesDto } from '@shipfox/api-runners-dto';
2
+ export declare class RunnerBootstrapTokenInvalidError extends Error {
3
+ constructor();
4
+ }
5
+ export declare class RunnerControlSessionInvalidError extends Error {
6
+ constructor();
7
+ }
8
+ export declare function createRunnerInstancesWithBootstrapTokens(params: {
9
+ provisionerId: string;
10
+ providerKind?: string | null;
11
+ runnerInstances: Array<{
12
+ templateKey?: string | null;
13
+ }>;
14
+ ttlSeconds: number;
15
+ }): Promise<Array<{
16
+ runnerInstanceId: string;
17
+ bootstrapToken: string;
18
+ }>>;
19
+ export declare function exchangeRunnerBootstrapToken(params: {
20
+ rawToken: string;
21
+ ttlSeconds: number;
22
+ }): Promise<{
23
+ runnerInstanceId: string;
24
+ controlSessionToken: string;
25
+ expiresAt: Date;
26
+ }>;
27
+ export declare function resolveRunnerControlSession(rawToken: string): Promise<{
28
+ id: string;
29
+ runnerInstanceId: string;
30
+ provisionerId: string;
31
+ } | undefined>;
32
+ export declare function enrollRunnerControlSession(params: {
33
+ runnerInstanceId: string;
34
+ provisionerId: string;
35
+ labels: string[];
36
+ capabilities?: RunnerToolCapabilitiesDto | null;
37
+ providerKind: string;
38
+ protocolVersion: string;
39
+ }): Promise<void>;
40
+ export declare function attachRunnerControlProviderId(params: {
41
+ runnerInstanceId: string;
42
+ provisionerId: string;
43
+ providerRunnerId: string;
44
+ }): Promise<boolean>;
45
+ export declare function touchRunnerControlSession(runnerInstanceId: string, provisionerId: string): Promise<void>;
46
+ //# sourceMappingURL=runner-control-sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-control-sessions.d.ts","sourceRoot":"","sources":["../../src/core/runner-control-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AAUxE,qBAAa,gCAAiC,SAAQ,KAAK;;CAK1D;AAED,qBAAa,gCAAiC,SAAQ,KAAK;;CAK1D;AAED,wBAAsB,wCAAwC,CAAC,MAAM,EAAE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,KAAK,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAC,CAAC,CAAC;IACtD,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,KAAK,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,CA+BrE;AAED,wBAAsB,4BAA4B,CAAC,MAAM,EAAE;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAC,CAAC,CA8BpF;AAED,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM;;;;eAmBjE;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhB;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC,OAAO,CAAC,CAcnB;AAED,wBAAsB,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAoB9F"}
@@ -0,0 +1,121 @@
1
+ import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
2
+ import { canonicalizeLabels } from '@shipfox/runner-labels';
3
+ import { and, eq, gt, isNull, notInArray, or, sql } from 'drizzle-orm';
4
+ import { db } from '#db/db.js';
5
+ import { terminalStates } from '#db/runner-instances.js';
6
+ import { provisionerTokens } from '#db/schema/provisioner-tokens.js';
7
+ import { runnerBootstrapTokens, runnerControlSessions } from '#db/schema/runner-control-sessions.js';
8
+ import { providerRunners } from '#db/schema/runner-instances.js';
9
+ export class RunnerBootstrapTokenInvalidError extends Error {
10
+ constructor(){
11
+ super('Runner bootstrap token is invalid, expired, or has already been used');
12
+ this.name = 'RunnerBootstrapTokenInvalidError';
13
+ }
14
+ }
15
+ export class RunnerControlSessionInvalidError extends Error {
16
+ constructor(){
17
+ super('Runner control session is invalid, expired, or closed');
18
+ this.name = 'RunnerControlSessionInvalidError';
19
+ }
20
+ }
21
+ export async function createRunnerInstancesWithBootstrapTokens(params) {
22
+ const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);
23
+ return await db().transaction(async (tx)=>{
24
+ const instances = await tx.insert(providerRunners).values(params.runnerInstances.map((runner)=>({
25
+ provisionerId: params.provisionerId,
26
+ providerKind: params.providerKind ?? null,
27
+ templateKey: runner.templateKey ?? null,
28
+ state: 'starting',
29
+ labels: [],
30
+ reportedAt: new Date()
31
+ }))).returning({
32
+ id: providerRunners.id
33
+ });
34
+ const results = instances.map((instance)=>({
35
+ runnerInstanceId: instance.id,
36
+ bootstrapToken: generateOpaqueToken('runnerBootstrapToken')
37
+ }));
38
+ await tx.insert(runnerBootstrapTokens).values(results.map((result)=>({
39
+ runnerInstanceId: result.runnerInstanceId,
40
+ provisionerId: params.provisionerId,
41
+ hashedToken: hashOpaqueToken(result.bootstrapToken),
42
+ prefix: extractDisplayPrefix(result.bootstrapToken),
43
+ expiresAt
44
+ })));
45
+ return results;
46
+ });
47
+ }
48
+ export async function exchangeRunnerBootstrapToken(params) {
49
+ const controlSessionToken = generateOpaqueToken('runnerControlSession');
50
+ const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);
51
+ return await db().transaction(async (tx)=>{
52
+ const [bootstrap] = await tx.update(runnerBootstrapTokens).set({
53
+ consumedAt: sql`now()`
54
+ }).where(and(eq(runnerBootstrapTokens.hashedToken, hashOpaqueToken(params.rawToken)), isNull(runnerBootstrapTokens.consumedAt), isNull(runnerBootstrapTokens.revokedAt), gt(runnerBootstrapTokens.expiresAt, sql`now()`))).returning();
55
+ if (!bootstrap) throw new RunnerBootstrapTokenInvalidError();
56
+ const [session] = await tx.insert(runnerControlSessions).values({
57
+ runnerInstanceId: bootstrap.runnerInstanceId,
58
+ provisionerId: bootstrap.provisionerId,
59
+ hashedToken: hashOpaqueToken(controlSessionToken),
60
+ prefix: extractDisplayPrefix(controlSessionToken),
61
+ expiresAt
62
+ }).returning({
63
+ id: runnerControlSessions.id
64
+ });
65
+ if (!session) throw new Error('Runner control session insert returned no row');
66
+ return {
67
+ runnerInstanceId: bootstrap.runnerInstanceId,
68
+ controlSessionToken,
69
+ expiresAt
70
+ };
71
+ });
72
+ }
73
+ export async function resolveRunnerControlSession(rawToken) {
74
+ const [session] = await db().select({
75
+ id: runnerControlSessions.id,
76
+ runnerInstanceId: runnerControlSessions.runnerInstanceId,
77
+ provisionerId: runnerControlSessions.provisionerId
78
+ }).from(runnerControlSessions).leftJoin(provisionerTokens, eq(provisionerTokens.id, runnerControlSessions.provisionerId)).where(and(eq(runnerControlSessions.hashedToken, hashOpaqueToken(rawToken)), isNull(runnerControlSessions.closedAt), or(isNull(provisionerTokens.id), isNull(provisionerTokens.revokedAt)), gt(runnerControlSessions.expiresAt, sql`now()`))).limit(1);
79
+ return session;
80
+ }
81
+ export async function enrollRunnerControlSession(params) {
82
+ const updated = await db().update(providerRunners).set({
83
+ labels: [
84
+ ...canonicalizeLabels(params.labels)
85
+ ],
86
+ providerKind: params.providerKind,
87
+ protocolVersion: params.protocolVersion,
88
+ capabilities: params.capabilities ?? null,
89
+ state: 'running',
90
+ reportedAt: sql`now()`,
91
+ updatedAt: sql`now()`
92
+ }).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId), notInArray(providerRunners.state, [
93
+ ...terminalStates
94
+ ]))).returning({
95
+ id: providerRunners.id
96
+ });
97
+ if (!updated[0]) throw new RunnerControlSessionInvalidError();
98
+ await touchRunnerControlSession(params.runnerInstanceId, params.provisionerId);
99
+ }
100
+ export async function attachRunnerControlProviderId(params) {
101
+ const rows = await db().update(providerRunners).set({
102
+ providerRunnerId: params.providerRunnerId,
103
+ updatedAt: sql`now()`
104
+ }).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId), isNull(providerRunners.providerRunnerId), notInArray(providerRunners.state, [
105
+ ...terminalStates
106
+ ]))).returning({
107
+ id: providerRunners.id
108
+ });
109
+ return rows.length === 1;
110
+ }
111
+ export async function touchRunnerControlSession(runnerInstanceId, provisionerId) {
112
+ await db().update(runnerControlSessions).set({
113
+ lastSeenAt: sql`now()`
114
+ }).where(and(eq(runnerControlSessions.runnerInstanceId, runnerInstanceId), eq(runnerControlSessions.provisionerId, provisionerId), isNull(runnerControlSessions.closedAt)));
115
+ await db().update(providerRunners).set({
116
+ reportedAt: sql`now()`,
117
+ updatedAt: sql`now()`
118
+ }).where(and(eq(providerRunners.id, runnerInstanceId), eq(providerRunners.provisionerId, provisionerId)));
119
+ }
120
+
121
+ //# sourceMappingURL=runner-control-sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/runner-control-sessions.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {and, eq, gt, isNull, notInArray, or, sql} from 'drizzle-orm';\nimport {db} from '#db/db.js';\nimport {terminalStates} from '#db/runner-instances.js';\nimport {provisionerTokens} from '#db/schema/provisioner-tokens.js';\nimport {runnerBootstrapTokens, runnerControlSessions} from '#db/schema/runner-control-sessions.js';\nimport {providerRunners} from '#db/schema/runner-instances.js';\n\nexport class RunnerBootstrapTokenInvalidError extends Error {\n constructor() {\n super('Runner bootstrap token is invalid, expired, or has already been used');\n this.name = 'RunnerBootstrapTokenInvalidError';\n }\n}\n\nexport class RunnerControlSessionInvalidError extends Error {\n constructor() {\n super('Runner control session is invalid, expired, or closed');\n this.name = 'RunnerControlSessionInvalidError';\n }\n}\n\nexport async function createRunnerInstancesWithBootstrapTokens(params: {\n provisionerId: string;\n providerKind?: string | null;\n runnerInstances: Array<{templateKey?: string | null}>;\n ttlSeconds: number;\n}): Promise<Array<{runnerInstanceId: string; bootstrapToken: string}>> {\n const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);\n return await db().transaction(async (tx) => {\n const instances = await tx\n .insert(providerRunners)\n .values(\n params.runnerInstances.map((runner) => ({\n provisionerId: params.provisionerId,\n providerKind: params.providerKind ?? null,\n templateKey: runner.templateKey ?? null,\n state: 'starting' as const,\n labels: [],\n reportedAt: new Date(),\n })),\n )\n .returning({id: providerRunners.id});\n const results = instances.map((instance) => ({\n runnerInstanceId: instance.id,\n bootstrapToken: generateOpaqueToken('runnerBootstrapToken'),\n }));\n await tx.insert(runnerBootstrapTokens).values(\n results.map((result) => ({\n runnerInstanceId: result.runnerInstanceId,\n provisionerId: params.provisionerId,\n hashedToken: hashOpaqueToken(result.bootstrapToken),\n prefix: extractDisplayPrefix(result.bootstrapToken),\n expiresAt,\n })),\n );\n return results;\n });\n}\n\nexport async function exchangeRunnerBootstrapToken(params: {\n rawToken: string;\n ttlSeconds: number;\n}): Promise<{runnerInstanceId: string; controlSessionToken: string; expiresAt: Date}> {\n const controlSessionToken = generateOpaqueToken('runnerControlSession');\n const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);\n return await db().transaction(async (tx) => {\n const [bootstrap] = await tx\n .update(runnerBootstrapTokens)\n .set({consumedAt: sql`now()`})\n .where(\n and(\n eq(runnerBootstrapTokens.hashedToken, hashOpaqueToken(params.rawToken)),\n isNull(runnerBootstrapTokens.consumedAt),\n isNull(runnerBootstrapTokens.revokedAt),\n gt(runnerBootstrapTokens.expiresAt, sql`now()`),\n ),\n )\n .returning();\n if (!bootstrap) throw new RunnerBootstrapTokenInvalidError();\n const [session] = await tx\n .insert(runnerControlSessions)\n .values({\n runnerInstanceId: bootstrap.runnerInstanceId,\n provisionerId: bootstrap.provisionerId,\n hashedToken: hashOpaqueToken(controlSessionToken),\n prefix: extractDisplayPrefix(controlSessionToken),\n expiresAt,\n })\n .returning({id: runnerControlSessions.id});\n if (!session) throw new Error('Runner control session insert returned no row');\n return {runnerInstanceId: bootstrap.runnerInstanceId, controlSessionToken, expiresAt};\n });\n}\n\nexport async function resolveRunnerControlSession(rawToken: string) {\n const [session] = await db()\n .select({\n id: runnerControlSessions.id,\n runnerInstanceId: runnerControlSessions.runnerInstanceId,\n provisionerId: runnerControlSessions.provisionerId,\n })\n .from(runnerControlSessions)\n .leftJoin(provisionerTokens, eq(provisionerTokens.id, runnerControlSessions.provisionerId))\n .where(\n and(\n eq(runnerControlSessions.hashedToken, hashOpaqueToken(rawToken)),\n isNull(runnerControlSessions.closedAt),\n or(isNull(provisionerTokens.id), isNull(provisionerTokens.revokedAt)),\n gt(runnerControlSessions.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n return session;\n}\n\nexport async function enrollRunnerControlSession(params: {\n runnerInstanceId: string;\n provisionerId: string;\n labels: string[];\n capabilities?: RunnerToolCapabilitiesDto | null;\n providerKind: string;\n protocolVersion: string;\n}): Promise<void> {\n const updated = await db()\n .update(providerRunners)\n .set({\n labels: [...canonicalizeLabels(params.labels)],\n providerKind: params.providerKind,\n protocolVersion: params.protocolVersion,\n capabilities: params.capabilities ?? null,\n state: 'running',\n reportedAt: sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({id: providerRunners.id});\n if (!updated[0]) throw new RunnerControlSessionInvalidError();\n await touchRunnerControlSession(params.runnerInstanceId, params.provisionerId);\n}\n\nexport async function attachRunnerControlProviderId(params: {\n runnerInstanceId: string;\n provisionerId: string;\n providerRunnerId: string;\n}): Promise<boolean> {\n const rows = await db()\n .update(providerRunners)\n .set({providerRunnerId: params.providerRunnerId, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n isNull(providerRunners.providerRunnerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({id: providerRunners.id});\n return rows.length === 1;\n}\n\nexport async function touchRunnerControlSession(runnerInstanceId: string, provisionerId: string) {\n await db()\n .update(runnerControlSessions)\n .set({lastSeenAt: sql`now()`})\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, runnerInstanceId),\n eq(runnerControlSessions.provisionerId, provisionerId),\n isNull(runnerControlSessions.closedAt),\n ),\n );\n await db()\n .update(providerRunners)\n .set({reportedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, runnerInstanceId),\n eq(providerRunners.provisionerId, provisionerId),\n ),\n );\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","canonicalizeLabels","and","eq","gt","isNull","notInArray","or","sql","db","terminalStates","provisionerTokens","runnerBootstrapTokens","runnerControlSessions","providerRunners","RunnerBootstrapTokenInvalidError","Error","name","RunnerControlSessionInvalidError","createRunnerInstancesWithBootstrapTokens","params","expiresAt","Date","now","ttlSeconds","transaction","tx","instances","insert","values","runnerInstances","map","runner","provisionerId","providerKind","templateKey","state","labels","reportedAt","returning","id","results","instance","runnerInstanceId","bootstrapToken","result","hashedToken","prefix","exchangeRunnerBootstrapToken","controlSessionToken","bootstrap","update","set","consumedAt","where","rawToken","revokedAt","session","resolveRunnerControlSession","select","from","leftJoin","closedAt","limit","enrollRunnerControlSession","updated","protocolVersion","capabilities","updatedAt","touchRunnerControlSession","attachRunnerControlProviderId","rows","providerRunnerId","length","lastSeenAt"],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import type { RunnerInstance, RunnerInstanceState } from '#core/entities/runner-instance.js';
2
+ import { type RunnerInstanceReportEvent } from '#db/index.js';
3
+ import type { RunnerInstanceBoundJobExecution } from '#db/job-executions.js';
4
+ export interface ReportRunnerInstancesParams {
5
+ workspaceId: string | null;
6
+ provisionerId: string;
7
+ events: RunnerInstanceReportEvent[];
8
+ }
9
+ export declare function attachRunnerInstanceProviderId(params: {
10
+ runnerInstanceId: string;
11
+ provisionerId: string;
12
+ providerRunnerId: string;
13
+ }): Promise<boolean>;
14
+ export interface ReportRunnerInstancesResult {
15
+ accepted: number;
16
+ reservationsReleased: number;
17
+ }
18
+ export interface ReconcileRunnerInstancesParams {
19
+ workspaceId: string | null;
20
+ provisionerId: string;
21
+ observedRunnerInstanceIds: string[];
22
+ }
23
+ export type ReconcileDesiredIntent = 'keep' | 'terminate';
24
+ type ReconcileDesiredIntentReason = 'job-cancelled' | 'terminal-state';
25
+ export interface ReconciledBoundJobExecution {
26
+ jobId: string;
27
+ jobExecutionId: string;
28
+ workflowRunAttemptId: string;
29
+ lastHeartbeatAt: Date;
30
+ cancellationRequestedAt: Date | null;
31
+ }
32
+ export interface ReconciledRunnerInstance {
33
+ providerRunnerId: string;
34
+ state: RunnerInstanceState | null;
35
+ reservationId: string | null;
36
+ runnerSessionId: string | null;
37
+ boundJobExecution: ReconciledBoundJobExecution | null;
38
+ desiredIntent: ReconcileDesiredIntent;
39
+ desiredIntentReason: ReconcileDesiredIntentReason | null;
40
+ }
41
+ export interface ReconcileRunnerInstancesResult {
42
+ runners: ReconciledRunnerInstance[];
43
+ terminatedAbsentRunnerInstanceIds: string[];
44
+ }
45
+ export type ActiveRunnerState = 'starting' | 'running' | 'stopping' | 'busy';
46
+ export interface ActiveRunner {
47
+ runnerSessionId: string | null;
48
+ providerRunnerId: string | null;
49
+ provisionerId: string | null;
50
+ state: ActiveRunnerState;
51
+ labels: string[];
52
+ templateKey: string | null;
53
+ providerKind: string | null;
54
+ jobId: string | null;
55
+ workflowRunAttemptId: string | null;
56
+ projectId: string | null;
57
+ reportedAt: Date | null;
58
+ lastHeartbeatAt: Date | null;
59
+ }
60
+ export declare function reportRunnerInstances(params: ReportRunnerInstancesParams): Promise<ReportRunnerInstancesResult>;
61
+ export declare function reconcileRunnerInstances(params: ReconcileRunnerInstancesParams): Promise<ReconcileRunnerInstancesResult>;
62
+ export declare function reconcileRunnerInstancesFromDbResult(params: {
63
+ observedRunnerInstanceIds: string[];
64
+ observedRows: RunnerInstance[];
65
+ boundJobExecutionsByRunnerInstanceId: Map<string, RunnerInstanceBoundJobExecution>;
66
+ }): ReconciledRunnerInstance[];
67
+ export declare function listActiveRunners(params: {
68
+ workspaceId: string;
69
+ }): Promise<ActiveRunner[]>;
70
+ export declare function desiredIntent(row: RunnerInstance | undefined, boundJobExecution: RunnerInstanceBoundJobExecution | undefined): ReconcileDesiredIntent;
71
+ export {};
72
+ //# sourceMappingURL=runner-instances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-instances.d.ts","sourceRoot":"","sources":["../../src/core/runner-instances.ts"],"names":[],"mappings":"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"}