@shipfox/api-workflows 5.0.0 → 6.0.0

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 (277) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +72 -0
  3. package/dist/core/agent-defaults.d.ts +17 -0
  4. package/dist/core/agent-defaults.d.ts.map +1 -0
  5. package/dist/core/agent-defaults.js +21 -0
  6. package/dist/core/agent-defaults.js.map +1 -0
  7. package/dist/core/agent-tool-capability-warning.d.ts +4 -0
  8. package/dist/core/agent-tool-capability-warning.d.ts.map +1 -1
  9. package/dist/core/agent-tool-capability-warning.js +15 -17
  10. package/dist/core/agent-tool-capability-warning.js.map +1 -1
  11. package/dist/core/agent-tools.d.ts +11 -9
  12. package/dist/core/agent-tools.d.ts.map +1 -1
  13. package/dist/core/agent-tools.js +23 -18
  14. package/dist/core/agent-tools.js.map +1 -1
  15. package/dist/core/checkout.d.ts +21 -7
  16. package/dist/core/checkout.d.ts.map +1 -1
  17. package/dist/core/checkout.js +23 -11
  18. package/dist/core/checkout.js.map +1 -1
  19. package/dist/core/entities/workflow-run-attempt.d.ts +1 -1
  20. package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
  21. package/dist/core/entities/workflow-run-attempt.js.map +1 -1
  22. package/dist/core/job-execution.d.ts +3 -1
  23. package/dist/core/job-execution.d.ts.map +1 -1
  24. package/dist/core/job-execution.js +14 -12
  25. package/dist/core/job-execution.js.map +1 -1
  26. package/dist/core/job-transition/derive-job-execution-outputs.d.ts +1 -1
  27. package/dist/core/job-transition/derive-job-execution-outputs.d.ts.map +1 -1
  28. package/dist/core/job-transition/derive-job-execution-outputs.js.map +1 -1
  29. package/dist/core/job-transition/derive-job-success.js +1 -1
  30. package/dist/core/job-transition/derive-job-success.js.map +1 -1
  31. package/dist/core/listener-execution-materialization.d.ts +3 -3
  32. package/dist/core/listener-execution-materialization.d.ts.map +1 -1
  33. package/dist/core/listener-execution-materialization.js +3 -4
  34. package/dist/core/listener-execution-materialization.js.map +1 -1
  35. package/dist/core/run-workflow.d.ts +12 -1
  36. package/dist/core/run-workflow.d.ts.map +1 -1
  37. package/dist/core/run-workflow.js +13 -8
  38. package/dist/core/run-workflow.js.map +1 -1
  39. package/dist/core/step-config/agent.d.ts +8 -8
  40. package/dist/core/step-config/agent.d.ts.map +1 -1
  41. package/dist/core/step-config/agent.js +12 -10
  42. package/dist/core/step-config/agent.js.map +1 -1
  43. package/dist/core/step-config/complete-step-dispatch-config.d.ts +4 -4
  44. package/dist/core/step-config/complete-step-dispatch-config.d.ts.map +1 -1
  45. package/dist/core/step-config/complete-step-dispatch-config.js +2 -2
  46. package/dist/core/step-config/complete-step-dispatch-config.js.map +1 -1
  47. package/dist/core/step-config/materialize-job-execution-steps.d.ts +3 -3
  48. package/dist/core/step-config/materialize-job-execution-steps.d.ts.map +1 -1
  49. package/dist/core/step-config/materialize-job-execution-steps.js +5 -6
  50. package/dist/core/step-config/materialize-job-execution-steps.js.map +1 -1
  51. package/dist/core/step-config/materialize-workflow-model.d.ts +3 -3
  52. package/dist/core/step-config/materialize-workflow-model.d.ts.map +1 -1
  53. package/dist/core/step-config/materialize-workflow-model.js +4 -4
  54. package/dist/core/step-config/materialize-workflow-model.js.map +1 -1
  55. package/dist/core/step-config/resolve-job-execution-name.d.ts +1 -1
  56. package/dist/core/step-config/resolve-job-execution-name.d.ts.map +1 -1
  57. package/dist/core/step-config/resolve-job-execution-name.js.map +1 -1
  58. package/dist/core/step-config/resolve-step-config.d.ts +4 -4
  59. package/dist/core/step-config/resolve-step-config.d.ts.map +1 -1
  60. package/dist/core/step-config/resolve-step-config.js +6 -6
  61. package/dist/core/step-config/resolve-step-config.js.map +1 -1
  62. package/dist/core/step-config/run.d.ts +1 -1
  63. package/dist/core/step-config/run.d.ts.map +1 -1
  64. package/dist/core/step-config/run.js.map +1 -1
  65. package/dist/core/workflow-run-creation.d.ts +3 -3
  66. package/dist/core/workflow-run-creation.d.ts.map +1 -1
  67. package/dist/core/workflow-run-creation.js +3 -4
  68. package/dist/core/workflow-run-creation.js.map +1 -1
  69. package/dist/db/db.d.ts +16 -4
  70. package/dist/db/db.d.ts.map +1 -1
  71. package/dist/db/job-listeners.d.ts +7 -1
  72. package/dist/db/job-listeners.d.ts.map +1 -1
  73. package/dist/db/job-listeners.js +10 -5
  74. package/dist/db/job-listeners.js.map +1 -1
  75. package/dist/db/runner-lease-table.d.ts +5 -5
  76. package/dist/db/runner-lease-table.d.ts.map +1 -1
  77. package/dist/db/runner-lease-table.js +3 -2
  78. package/dist/db/runner-lease-table.js.map +1 -1
  79. package/dist/db/schema/workflow-run-attempts.d.ts +9 -3
  80. package/dist/db/schema/workflow-run-attempts.d.ts.map +1 -1
  81. package/dist/db/schema/workflow-run-attempts.js +2 -1
  82. package/dist/db/schema/workflow-run-attempts.js.map +1 -1
  83. package/dist/db/schema/workflow-runs.js +1 -1
  84. package/dist/db/schema/workflow-runs.js.map +1 -1
  85. package/dist/db/workflow-runs/job-executions.d.ts +5 -0
  86. package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
  87. package/dist/db/workflow-runs/job-executions.js +14 -7
  88. package/dist/db/workflow-runs/job-executions.js.map +1 -1
  89. package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
  90. package/dist/db/workflow-runs/jobs.js +3 -1
  91. package/dist/db/workflow-runs/jobs.js.map +1 -1
  92. package/dist/db/workflow-runs/run-create.d.ts +9 -2
  93. package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
  94. package/dist/db/workflow-runs/run-create.js +12 -9
  95. package/dist/db/workflow-runs/run-create.js.map +1 -1
  96. package/dist/db/workflow-runs/run-rerun.d.ts.map +1 -1
  97. package/dist/db/workflow-runs/run-rerun.js +3 -1
  98. package/dist/db/workflow-runs/run-rerun.js.map +1 -1
  99. package/dist/index.d.ts +18 -4
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +61 -37
  102. package/dist/index.js.map +1 -1
  103. package/dist/presentation/dto/checkout-token.d.ts +14 -1
  104. package/dist/presentation/dto/checkout-token.d.ts.map +1 -1
  105. package/dist/presentation/dto/checkout-token.js.map +1 -1
  106. package/dist/presentation/index.d.ts +1 -1
  107. package/dist/presentation/index.d.ts.map +1 -1
  108. package/dist/presentation/index.js +1 -1
  109. package/dist/presentation/index.js.map +1 -1
  110. package/dist/presentation/inter-module.d.ts +18 -0
  111. package/dist/presentation/inter-module.d.ts.map +1 -0
  112. package/dist/presentation/inter-module.js +113 -0
  113. package/dist/presentation/inter-module.js.map +1 -0
  114. package/dist/presentation/routes/agent-runtime-config.d.ts +6 -1
  115. package/dist/presentation/routes/agent-runtime-config.d.ts.map +1 -1
  116. package/dist/presentation/routes/agent-runtime-config.js +59 -57
  117. package/dist/presentation/routes/agent-runtime-config.js.map +1 -1
  118. package/dist/presentation/routes/cancel-run.d.ts +2 -1
  119. package/dist/presentation/routes/cancel-run.d.ts.map +1 -1
  120. package/dist/presentation/routes/cancel-run.js +37 -34
  121. package/dist/presentation/routes/cancel-run.js.map +1 -1
  122. package/dist/presentation/routes/checkout-token.d.ts +8 -1
  123. package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
  124. package/dist/presentation/routes/checkout-token.js +65 -47
  125. package/dist/presentation/routes/checkout-token.js.map +1 -1
  126. package/dist/presentation/routes/get-run-aggregates.d.ts +2 -1
  127. package/dist/presentation/routes/get-run-aggregates.d.ts.map +1 -1
  128. package/dist/presentation/routes/get-run-aggregates.js +44 -53
  129. package/dist/presentation/routes/get-run-aggregates.js.map +1 -1
  130. package/dist/presentation/routes/get-run.d.ts +2 -1
  131. package/dist/presentation/routes/get-run.d.ts.map +1 -1
  132. package/dist/presentation/routes/get-run.js +53 -50
  133. package/dist/presentation/routes/get-run.js.map +1 -1
  134. package/dist/presentation/routes/get-step-secrets.d.ts +3 -1
  135. package/dist/presentation/routes/get-step-secrets.d.ts.map +1 -1
  136. package/dist/presentation/routes/get-step-secrets.js +72 -68
  137. package/dist/presentation/routes/get-step-secrets.js.map +1 -1
  138. package/dist/presentation/routes/index.d.ts +19 -2
  139. package/dist/presentation/routes/index.d.ts.map +1 -1
  140. package/dist/presentation/routes/index.js +38 -30
  141. package/dist/presentation/routes/index.js.map +1 -1
  142. package/dist/presentation/routes/leased-step.d.ts +2 -0
  143. package/dist/presentation/routes/leased-step.d.ts.map +1 -1
  144. package/dist/presentation/routes/leased-step.js +1 -2
  145. package/dist/presentation/routes/leased-step.js.map +1 -1
  146. package/dist/presentation/routes/list-run-attempts.d.ts +2 -1
  147. package/dist/presentation/routes/list-run-attempts.d.ts.map +1 -1
  148. package/dist/presentation/routes/list-run-attempts.js +29 -26
  149. package/dist/presentation/routes/list-run-attempts.js.map +1 -1
  150. package/dist/presentation/routes/list-runs.d.ts +2 -1
  151. package/dist/presentation/routes/list-runs.d.ts.map +1 -1
  152. package/dist/presentation/routes/list-runs.js +51 -60
  153. package/dist/presentation/routes/list-runs.js.map +1 -1
  154. package/dist/presentation/routes/next-step.d.ts +10 -1
  155. package/dist/presentation/routes/next-step.d.ts.map +1 -1
  156. package/dist/presentation/routes/next-step.js +64 -50
  157. package/dist/presentation/routes/next-step.js.map +1 -1
  158. package/dist/presentation/routes/project-access.d.ts +10 -0
  159. package/dist/presentation/routes/project-access.d.ts.map +1 -0
  160. package/dist/presentation/routes/project-access.js +17 -0
  161. package/dist/presentation/routes/project-access.js.map +1 -0
  162. package/dist/presentation/routes/report-step.d.ts +2 -1
  163. package/dist/presentation/routes/report-step.d.ts.map +1 -1
  164. package/dist/presentation/routes/report-step.js +62 -61
  165. package/dist/presentation/routes/report-step.js.map +1 -1
  166. package/dist/presentation/routes/require-accessible-run.d.ts +3 -1
  167. package/dist/presentation/routes/require-accessible-run.d.ts.map +1 -1
  168. package/dist/presentation/routes/require-accessible-run.js +3 -6
  169. package/dist/presentation/routes/require-accessible-run.js.map +1 -1
  170. package/dist/presentation/routes/rerun-run.d.ts +2 -1
  171. package/dist/presentation/routes/rerun-run.d.ts.map +1 -1
  172. package/dist/presentation/routes/rerun-run.js +46 -43
  173. package/dist/presentation/routes/rerun-run.js.map +1 -1
  174. package/dist/temporal/activities/index.d.ts +44 -9
  175. package/dist/temporal/activities/index.d.ts.map +1 -1
  176. package/dist/temporal/activities/index.js +13 -9
  177. package/dist/temporal/activities/index.js.map +1 -1
  178. package/dist/temporal/activities/orchestration-activities.d.ts +20 -11
  179. package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
  180. package/dist/temporal/activities/orchestration-activities.js +48 -33
  181. package/dist/temporal/activities/orchestration-activities.js.map +1 -1
  182. package/dist/tsconfig.test.tsbuildinfo +1 -1
  183. package/package.json +28 -21
  184. package/src/core/agent-defaults.test.ts +28 -0
  185. package/src/core/agent-defaults.ts +36 -0
  186. package/src/core/agent-tool-capability-warning.test.ts +36 -11
  187. package/src/core/agent-tool-capability-warning.ts +27 -25
  188. package/src/core/agent-tools.ts +33 -36
  189. package/src/core/checkout.test.ts +38 -25
  190. package/src/core/checkout.ts +41 -14
  191. package/src/core/entities/workflow-run-attempt.ts +1 -1
  192. package/src/core/job-execution.ts +19 -9
  193. package/src/core/job-transition/derive-job-execution-outputs.ts +1 -1
  194. package/src/core/job-transition/derive-job-success.ts +1 -1
  195. package/src/core/listener-execution-materialization.test.ts +4 -2
  196. package/src/core/listener-execution-materialization.ts +6 -9
  197. package/src/core/run-workflow.test.ts +43 -38
  198. package/src/core/run-workflow.ts +26 -9
  199. package/src/core/step-config/agent.ts +24 -26
  200. package/src/core/step-config/complete-step-dispatch-config.test.ts +22 -23
  201. package/src/core/step-config/complete-step-dispatch-config.ts +6 -6
  202. package/src/core/step-config/materialize-job-execution-steps.test.ts +34 -23
  203. package/src/core/step-config/materialize-job-execution-steps.ts +38 -39
  204. package/src/core/step-config/materialize-workflow-model.test.ts +94 -82
  205. package/src/core/step-config/materialize-workflow-model.ts +31 -29
  206. package/src/core/step-config/resolve-job-execution-name.ts +1 -1
  207. package/src/core/step-config/resolve-step-config.ts +11 -9
  208. package/src/core/step-config/run.ts +1 -1
  209. package/src/core/workflow-run-creation.test.ts +14 -10
  210. package/src/core/workflow-run-creation.ts +6 -9
  211. package/src/db/job-listeners.ts +20 -5
  212. package/src/db/runner-lease-table.ts +2 -2
  213. package/src/db/schema/workflow-run-attempts.ts +7 -3
  214. package/src/db/schema/workflow-runs.ts +1 -1
  215. package/src/db/workflow-runs/job-executions.ts +15 -1
  216. package/src/db/workflow-runs/jobs.ts +4 -1
  217. package/src/db/workflow-runs/run-create.test.ts +7 -1
  218. package/src/db/workflow-runs/run-create.ts +25 -15
  219. package/src/db/workflow-runs/run-rerun.test.ts +1 -1
  220. package/src/db/workflow-runs/run-rerun.ts +6 -3
  221. package/src/index.ts +75 -33
  222. package/src/presentation/dto/checkout-token.ts +7 -1
  223. package/src/presentation/index.ts +1 -1
  224. package/src/presentation/inter-module.test.ts +149 -0
  225. package/src/presentation/inter-module.ts +132 -0
  226. package/src/presentation/routes/agent-runtime-config.test.ts +53 -10
  227. package/src/presentation/routes/agent-runtime-config.ts +89 -64
  228. package/src/presentation/routes/cancel-run.test.ts +10 -20
  229. package/src/presentation/routes/cancel-run.ts +30 -27
  230. package/src/presentation/routes/checkout-token.test.ts +52 -33
  231. package/src/presentation/routes/checkout-token.ts +109 -49
  232. package/src/presentation/routes/get-run-aggregates.test.ts +13 -7
  233. package/src/presentation/routes/get-run-aggregates.ts +54 -57
  234. package/src/presentation/routes/get-run.test.ts +10 -18
  235. package/src/presentation/routes/get-run.ts +51 -48
  236. package/src/presentation/routes/get-step-secrets.test.ts +29 -7
  237. package/src/presentation/routes/get-step-secrets.ts +72 -61
  238. package/src/presentation/routes/index.test.ts +16 -1
  239. package/src/presentation/routes/index.ts +54 -29
  240. package/src/presentation/routes/leased-step.ts +3 -2
  241. package/src/presentation/routes/list-run-attempts.test.ts +9 -19
  242. package/src/presentation/routes/list-run-attempts.ts +21 -18
  243. package/src/presentation/routes/list-runs.test.ts +13 -7
  244. package/src/presentation/routes/list-runs.ts +64 -67
  245. package/src/presentation/routes/next-step.test.ts +30 -11
  246. package/src/presentation/routes/next-step.ts +68 -48
  247. package/src/presentation/routes/project-access.ts +16 -0
  248. package/src/presentation/routes/report-step.test.ts +18 -2
  249. package/src/presentation/routes/report-step.ts +51 -49
  250. package/src/presentation/routes/require-accessible-run.ts +5 -2
  251. package/src/presentation/routes/rerun-run.test.ts +9 -19
  252. package/src/presentation/routes/rerun-run.ts +39 -36
  253. package/src/temporal/activities/index.ts +32 -12
  254. package/src/temporal/activities/orchestration-activities.test.ts +10 -8
  255. package/src/temporal/activities/orchestration-activities.ts +74 -50
  256. package/src/temporal/workflows/job-execution-orchestration.test.ts +47 -2
  257. package/test/env.ts +1 -3
  258. package/test/factories/project.ts +10 -5
  259. package/test/factories/workflow-model.test.ts +5 -1
  260. package/test/factories/workflow-model.ts +1 -1
  261. package/test/factories/workflow-run.ts +1 -1
  262. package/test/fixtures/agent-inter-module.ts +27 -0
  263. package/test/fixtures/annotations-inter-module.ts +5 -0
  264. package/test/fixtures/auth-inter-module.ts +22 -0
  265. package/test/fixtures/lease-token.ts +2 -1
  266. package/test/fixtures/projects-inter-module.ts +8 -0
  267. package/test/fixtures/runners-inter-module.ts +52 -0
  268. package/test/fixtures/secrets-inter-module.ts +61 -0
  269. package/test/globalSetup.ts +11 -11
  270. package/tsconfig.build.tsbuildinfo +1 -1
  271. package/dist/core/source-control.d.ts +0 -5
  272. package/dist/core/source-control.d.ts.map +0 -1
  273. package/dist/core/source-control.js +0 -19
  274. package/dist/core/source-control.js.map +0 -1
  275. package/src/core/source-control.test.ts +0 -17
  276. package/src/core/source-control.ts +0 -22
  277. package/src/temporal/workflows/job-execution-orchestration-timeout.test.ts +0 -165
@@ -1,71 +1,73 @@
1
- import { ModelProviderConfigNotFoundError } from '@shipfox/api-agent/core/errors';
2
- import { resolveRuntimeCredentials } from '@shipfox/api-agent/core/resolve-runtime-credentials';
3
1
  import { agentRuntimeCredentialsResponseSchema, materializedAgentStepConfigSchema } from '@shipfox/api-agent-dto';
4
- import { SecretDecryptionError } from '@shipfox/api-secrets';
2
+ import { agentInterModuleContract } from '@shipfox/api-agent-dto/inter-module';
5
3
  import { agentRuntimeConfigQuerySchema } from '@shipfox/api-workflows-dto';
4
+ import { isInterModuleKnownError } from '@shipfox/inter-module';
6
5
  import { captureException } from '@shipfox/node-error-monitoring';
7
6
  import { ClientError, defineRoute } from '@shipfox/node-fastify';
8
7
  import { ZodError } from 'zod';
9
8
  import { loadRunningLeasedStep } from './leased-step.js';
10
- export const agentRuntimeConfigRoute = defineRoute({
11
- method: 'GET',
12
- path: '/agent-runtime-config',
13
- description: "Returns the resolved harness, provider, model, thinking effort, and decrypted provider credential bundle for the runner's currently leased running agent step. The job is identified by the lease token and the step is bound to that job before credentials are returned.",
14
- schema: {
15
- querystring: agentRuntimeConfigQuerySchema,
16
- response: {
17
- 200: agentRuntimeCredentialsResponseSchema
18
- }
19
- },
20
- errorHandler: (error)=>{
21
- if (error instanceof SecretDecryptionError) {
22
- captureException(error);
23
- throw new ClientError('Model provider credentials could not be decrypted', 'model-provider-credentials-invalid', {
24
- status: 409,
25
- cause: error
26
- });
27
- }
28
- if (error instanceof ModelProviderConfigNotFoundError) {
29
- throw new ClientError('Model provider credentials are not configured', 'model-provider-not-configured', {
30
- status: 409
31
- });
32
- }
33
- throw error;
34
- },
35
- handler: async (request, reply)=>{
36
- const { step_id: stepId, attempt } = request.query;
37
- const { step, workspaceId } = await loadRunningLeasedStep({
38
- request,
39
- stepId,
40
- attempt
41
- });
42
- if (step.type !== 'agent') {
43
- throw new ClientError('Step is not an agent step', 'step-not-agent', {
44
- status: 409
45
- });
46
- }
47
- let agentConfig;
48
- try {
49
- agentConfig = materializedAgentStepConfigSchema.parse(step.config);
50
- } catch (error) {
51
- if (error instanceof ZodError) {
52
- throw new ClientError('Agent step config is invalid', 'agent-step-config-invalid', {
9
+ export function createAgentRuntimeConfigRoute(params) {
10
+ return defineRoute({
11
+ method: 'GET',
12
+ path: '/agent-runtime-config',
13
+ description: "Returns the resolved harness, provider, model, thinking effort, and decrypted provider credential bundle for the runner's currently leased running agent step. The job is identified by the lease token and the step is bound to that job before credentials are returned.",
14
+ schema: {
15
+ querystring: agentRuntimeConfigQuerySchema,
16
+ response: {
17
+ 200: agentRuntimeCredentialsResponseSchema
18
+ }
19
+ },
20
+ errorHandler: (error)=>{
21
+ if (isInterModuleKnownError(agentInterModuleContract.methods.resolveRuntimeCredentials, error) && error.code === 'model-provider-credentials-invalid') {
22
+ captureException(error);
23
+ throw new ClientError('Model provider credentials could not be decrypted', 'model-provider-credentials-invalid', {
53
24
  status: 409,
54
25
  cause: error
55
26
  });
56
27
  }
28
+ if (isInterModuleKnownError(agentInterModuleContract.methods.resolveRuntimeCredentials, error) && error.code === 'model-provider-not-configured') {
29
+ throw new ClientError('Model provider credentials are not configured', 'model-provider-not-configured', {
30
+ status: 409
31
+ });
32
+ }
57
33
  throw error;
34
+ },
35
+ handler: async (request, reply)=>{
36
+ const { step_id: stepId, attempt } = request.query;
37
+ const { step, workspaceId } = await loadRunningLeasedStep({
38
+ runners: params.runners,
39
+ request,
40
+ stepId,
41
+ attempt
42
+ });
43
+ if (step.type !== 'agent') {
44
+ throw new ClientError('Step is not an agent step', 'step-not-agent', {
45
+ status: 409
46
+ });
47
+ }
48
+ let agentConfig;
49
+ try {
50
+ agentConfig = materializedAgentStepConfigSchema.parse(step.config);
51
+ } catch (error) {
52
+ if (error instanceof ZodError) {
53
+ throw new ClientError('Agent step config is invalid', 'agent-step-config-invalid', {
54
+ status: 409,
55
+ cause: error
56
+ });
57
+ }
58
+ throw error;
59
+ }
60
+ const runtimeConfig = await params.agent.resolveRuntimeCredentials({
61
+ workspaceId,
62
+ harness: agentConfig.harness,
63
+ provider: agentConfig.provider,
64
+ model: agentConfig.model,
65
+ thinking: agentConfig.thinking
66
+ });
67
+ reply.header('cache-control', 'no-store');
68
+ return runtimeConfig;
58
69
  }
59
- const runtimeConfig = await resolveRuntimeCredentials({
60
- workspaceId,
61
- harness: agentConfig.harness,
62
- provider: agentConfig.provider,
63
- model: agentConfig.model,
64
- thinking: agentConfig.thinking
65
- });
66
- reply.header('cache-control', 'no-store');
67
- return runtimeConfig;
68
- }
69
- });
70
+ });
71
+ }
70
72
 
71
73
  //# sourceMappingURL=agent-runtime-config.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/presentation/routes/agent-runtime-config.ts"],"sourcesContent":["import {ModelProviderConfigNotFoundError} from '@shipfox/api-agent/core/errors';\nimport {resolveRuntimeCredentials} from '@shipfox/api-agent/core/resolve-runtime-credentials';\nimport {\n agentRuntimeCredentialsResponseSchema,\n type MaterializedAgentStepConfigDto,\n materializedAgentStepConfigSchema,\n} from '@shipfox/api-agent-dto';\nimport {SecretDecryptionError} from '@shipfox/api-secrets';\nimport {agentRuntimeConfigQuerySchema} from '@shipfox/api-workflows-dto';\nimport {captureException} from '@shipfox/node-error-monitoring';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {ZodError} from 'zod';\nimport {loadRunningLeasedStep} from './leased-step.js';\n\nexport const agentRuntimeConfigRoute = defineRoute({\n method: 'GET',\n path: '/agent-runtime-config',\n description:\n \"Returns the resolved harness, provider, model, thinking effort, and decrypted provider credential bundle for the runner's currently leased running agent step. The job is identified by the lease token and the step is bound to that job before credentials are returned.\",\n schema: {\n querystring: agentRuntimeConfigQuerySchema,\n response: {\n 200: agentRuntimeCredentialsResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof SecretDecryptionError) {\n captureException(error);\n throw new ClientError(\n 'Model provider credentials could not be decrypted',\n 'model-provider-credentials-invalid',\n {\n status: 409,\n cause: error,\n },\n );\n }\n if (error instanceof ModelProviderConfigNotFoundError) {\n throw new ClientError(\n 'Model provider credentials are not configured',\n 'model-provider-not-configured',\n {\n status: 409,\n },\n );\n }\n throw error;\n },\n handler: async (request, reply) => {\n const {step_id: stepId, attempt} = request.query;\n const {step, workspaceId} = await loadRunningLeasedStep({request, stepId, attempt});\n\n if (step.type !== 'agent') {\n throw new ClientError('Step is not an agent step', 'step-not-agent', {status: 409});\n }\n\n let agentConfig: MaterializedAgentStepConfigDto;\n try {\n agentConfig = materializedAgentStepConfigSchema.parse(step.config);\n } catch (error) {\n if (error instanceof ZodError) {\n throw new ClientError('Agent step config is invalid', 'agent-step-config-invalid', {\n status: 409,\n cause: error,\n });\n }\n throw error;\n }\n\n const runtimeConfig = await resolveRuntimeCredentials({\n workspaceId,\n harness: agentConfig.harness,\n provider: agentConfig.provider,\n model: agentConfig.model,\n thinking: agentConfig.thinking,\n });\n\n reply.header('cache-control', 'no-store');\n return runtimeConfig;\n },\n});\n"],"names":["ModelProviderConfigNotFoundError","resolveRuntimeCredentials","agentRuntimeCredentialsResponseSchema","materializedAgentStepConfigSchema","SecretDecryptionError","agentRuntimeConfigQuerySchema","captureException","ClientError","defineRoute","ZodError","loadRunningLeasedStep","agentRuntimeConfigRoute","method","path","description","schema","querystring","response","errorHandler","error","status","cause","handler","request","reply","step_id","stepId","attempt","query","step","workspaceId","type","agentConfig","parse","config","runtimeConfig","harness","provider","model","thinking","header"],"mappings":"AAAA,SAAQA,gCAAgC,QAAO,iCAAiC;AAChF,SAAQC,yBAAyB,QAAO,sDAAsD;AAC9F,SACEC,qCAAqC,EAErCC,iCAAiC,QAC5B,yBAAyB;AAChC,SAAQC,qBAAqB,QAAO,uBAAuB;AAC3D,SAAQC,6BAA6B,QAAO,6BAA6B;AACzE,SAAQC,gBAAgB,QAAO,iCAAiC;AAChE,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,QAAQ,QAAO,MAAM;AAC7B,SAAQC,qBAAqB,QAAO,mBAAmB;AAEvD,OAAO,MAAMC,0BAA0BH,YAAY;IACjDI,QAAQ;IACRC,MAAM;IACNC,aACE;IACFC,QAAQ;QACNC,aAAaX;QACbY,UAAU;YACR,KAAKf;QACP;IACF;IACAgB,cAAc,CAACC;QACb,IAAIA,iBAAiBf,uBAAuB;YAC1CE,iBAAiBa;YACjB,MAAM,IAAIZ,YACR,qDACA,sCACA;gBACEa,QAAQ;gBACRC,OAAOF;YACT;QAEJ;QACA,IAAIA,iBAAiBnB,kCAAkC;YACrD,MAAM,IAAIO,YACR,iDACA,iCACA;gBACEa,QAAQ;YACV;QAEJ;QACA,MAAMD;IACR;IACAG,SAAS,OAAOC,SAASC;QACvB,MAAM,EAACC,SAASC,MAAM,EAAEC,OAAO,EAAC,GAAGJ,QAAQK,KAAK;QAChD,MAAM,EAACC,IAAI,EAAEC,WAAW,EAAC,GAAG,MAAMpB,sBAAsB;YAACa;YAASG;YAAQC;QAAO;QAEjF,IAAIE,KAAKE,IAAI,KAAK,SAAS;YACzB,MAAM,IAAIxB,YAAY,6BAA6B,kBAAkB;gBAACa,QAAQ;YAAG;QACnF;QAEA,IAAIY;QACJ,IAAI;YACFA,cAAc7B,kCAAkC8B,KAAK,CAACJ,KAAKK,MAAM;QACnE,EAAE,OAAOf,OAAO;YACd,IAAIA,iBAAiBV,UAAU;gBAC7B,MAAM,IAAIF,YAAY,gCAAgC,6BAA6B;oBACjFa,QAAQ;oBACRC,OAAOF;gBACT;YACF;YACA,MAAMA;QACR;QAEA,MAAMgB,gBAAgB,MAAMlC,0BAA0B;YACpD6B;YACAM,SAASJ,YAAYI,OAAO;YAC5BC,UAAUL,YAAYK,QAAQ;YAC9BC,OAAON,YAAYM,KAAK;YACxBC,UAAUP,YAAYO,QAAQ;QAChC;QAEAf,MAAMgB,MAAM,CAAC,iBAAiB;QAC9B,OAAOL;IACT;AACF,GAAG"}
1
+ {"version":3,"sources":["../../../src/presentation/routes/agent-runtime-config.ts"],"sourcesContent":["import {\n agentRuntimeCredentialsResponseSchema,\n type MaterializedAgentStepConfigDto,\n materializedAgentStepConfigSchema,\n} from '@shipfox/api-agent-dto';\nimport {\n type AgentInterModuleClient,\n agentInterModuleContract,\n} from '@shipfox/api-agent-dto/inter-module';\nimport type {RunnersInterModuleClient} from '@shipfox/api-runners-dto/inter-module';\nimport {agentRuntimeConfigQuerySchema} from '@shipfox/api-workflows-dto';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {captureException} from '@shipfox/node-error-monitoring';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {ZodError} from 'zod';\nimport {loadRunningLeasedStep} from './leased-step.js';\n\nexport function createAgentRuntimeConfigRoute(params: {\n agent: AgentInterModuleClient;\n runners: RunnersInterModuleClient;\n}) {\n return defineRoute({\n method: 'GET',\n path: '/agent-runtime-config',\n description:\n \"Returns the resolved harness, provider, model, thinking effort, and decrypted provider credential bundle for the runner's currently leased running agent step. The job is identified by the lease token and the step is bound to that job before credentials are returned.\",\n schema: {\n querystring: agentRuntimeConfigQuerySchema,\n response: {\n 200: agentRuntimeCredentialsResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (\n isInterModuleKnownError(\n agentInterModuleContract.methods.resolveRuntimeCredentials,\n error,\n ) &&\n error.code === 'model-provider-credentials-invalid'\n ) {\n captureException(error);\n throw new ClientError(\n 'Model provider credentials could not be decrypted',\n 'model-provider-credentials-invalid',\n {\n status: 409,\n cause: error,\n },\n );\n }\n if (\n isInterModuleKnownError(\n agentInterModuleContract.methods.resolveRuntimeCredentials,\n error,\n ) &&\n error.code === 'model-provider-not-configured'\n ) {\n throw new ClientError(\n 'Model provider credentials are not configured',\n 'model-provider-not-configured',\n {\n status: 409,\n },\n );\n }\n throw error;\n },\n handler: async (request, reply) => {\n const {step_id: stepId, attempt} = request.query;\n const {step, workspaceId} = await loadRunningLeasedStep({\n runners: params.runners,\n request,\n stepId,\n attempt,\n });\n\n if (step.type !== 'agent') {\n throw new ClientError('Step is not an agent step', 'step-not-agent', {status: 409});\n }\n\n let agentConfig: MaterializedAgentStepConfigDto;\n try {\n agentConfig = materializedAgentStepConfigSchema.parse(step.config);\n } catch (error) {\n if (error instanceof ZodError) {\n throw new ClientError('Agent step config is invalid', 'agent-step-config-invalid', {\n status: 409,\n cause: error,\n });\n }\n throw error;\n }\n\n const runtimeConfig = await params.agent.resolveRuntimeCredentials({\n workspaceId,\n harness: agentConfig.harness,\n provider: agentConfig.provider,\n model: agentConfig.model,\n thinking: agentConfig.thinking,\n });\n\n reply.header('cache-control', 'no-store');\n return runtimeConfig;\n },\n });\n}\n"],"names":["agentRuntimeCredentialsResponseSchema","materializedAgentStepConfigSchema","agentInterModuleContract","agentRuntimeConfigQuerySchema","isInterModuleKnownError","captureException","ClientError","defineRoute","ZodError","loadRunningLeasedStep","createAgentRuntimeConfigRoute","params","method","path","description","schema","querystring","response","errorHandler","error","methods","resolveRuntimeCredentials","code","status","cause","handler","request","reply","step_id","stepId","attempt","query","step","workspaceId","runners","type","agentConfig","parse","config","runtimeConfig","agent","harness","provider","model","thinking","header"],"mappings":"AAAA,SACEA,qCAAqC,EAErCC,iCAAiC,QAC5B,yBAAyB;AAChC,SAEEC,wBAAwB,QACnB,sCAAsC;AAE7C,SAAQC,6BAA6B,QAAO,6BAA6B;AACzE,SAAQC,uBAAuB,QAAO,wBAAwB;AAC9D,SAAQC,gBAAgB,QAAO,iCAAiC;AAChE,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,QAAQ,QAAO,MAAM;AAC7B,SAAQC,qBAAqB,QAAO,mBAAmB;AAEvD,OAAO,SAASC,8BAA8BC,MAG7C;IACC,OAAOJ,YAAY;QACjBK,QAAQ;QACRC,MAAM;QACNC,aACE;QACFC,QAAQ;YACNC,aAAab;YACbc,UAAU;gBACR,KAAKjB;YACP;QACF;QACAkB,cAAc,CAACC;YACb,IACEf,wBACEF,yBAAyBkB,OAAO,CAACC,yBAAyB,EAC1DF,UAEFA,MAAMG,IAAI,KAAK,sCACf;gBACAjB,iBAAiBc;gBACjB,MAAM,IAAIb,YACR,qDACA,sCACA;oBACEiB,QAAQ;oBACRC,OAAOL;gBACT;YAEJ;YACA,IACEf,wBACEF,yBAAyBkB,OAAO,CAACC,yBAAyB,EAC1DF,UAEFA,MAAMG,IAAI,KAAK,iCACf;gBACA,MAAM,IAAIhB,YACR,iDACA,iCACA;oBACEiB,QAAQ;gBACV;YAEJ;YACA,MAAMJ;QACR;QACAM,SAAS,OAAOC,SAASC;YACvB,MAAM,EAACC,SAASC,MAAM,EAAEC,OAAO,EAAC,GAAGJ,QAAQK,KAAK;YAChD,MAAM,EAACC,IAAI,EAAEC,WAAW,EAAC,GAAG,MAAMxB,sBAAsB;gBACtDyB,SAASvB,OAAOuB,OAAO;gBACvBR;gBACAG;gBACAC;YACF;YAEA,IAAIE,KAAKG,IAAI,KAAK,SAAS;gBACzB,MAAM,IAAI7B,YAAY,6BAA6B,kBAAkB;oBAACiB,QAAQ;gBAAG;YACnF;YAEA,IAAIa;YACJ,IAAI;gBACFA,cAAcnC,kCAAkCoC,KAAK,CAACL,KAAKM,MAAM;YACnE,EAAE,OAAOnB,OAAO;gBACd,IAAIA,iBAAiBX,UAAU;oBAC7B,MAAM,IAAIF,YAAY,gCAAgC,6BAA6B;wBACjFiB,QAAQ;wBACRC,OAAOL;oBACT;gBACF;gBACA,MAAMA;YACR;YAEA,MAAMoB,gBAAgB,MAAM5B,OAAO6B,KAAK,CAACnB,yBAAyB,CAAC;gBACjEY;gBACAQ,SAASL,YAAYK,OAAO;gBAC5BC,UAAUN,YAAYM,QAAQ;gBAC9BC,OAAOP,YAAYO,KAAK;gBACxBC,UAAUR,YAAYQ,QAAQ;YAChC;YAEAjB,MAAMkB,MAAM,CAAC,iBAAiB;YAC9B,OAAON;QACT;IACF;AACF"}
@@ -1,2 +1,3 @@
1
- export declare const cancelRunRoute: import("@shipfox/node-fastify").RouteDefinition;
1
+ import type { ProjectsModuleClient } from '@shipfox/api-projects-dto';
2
+ export declare function cancelRunRoute(projects: ProjectsModuleClient): import("@shipfox/node-fastify").RouteDefinition;
2
3
  //# sourceMappingURL=cancel-run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cancel-run.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/cancel-run.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,cAAc,iDA4BzB,CAAC"}
1
+ {"version":3,"file":"cancel-run.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/cancel-run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AASpE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,oBAAoB,mDA8B5D"}
@@ -5,42 +5,45 @@ import { WorkflowRunNotCancellableError, WorkflowRunNotFoundError } from '#core/
5
5
  import { cancelWorkflowRun } from '#db/index.js';
6
6
  import { toRunDto } from '#presentation/dto/index.js';
7
7
  import { requireAccessibleRun } from './require-accessible-run.js';
8
- export const cancelRunRoute = defineRoute({
9
- method: 'POST',
10
- path: '/:id/cancel',
11
- description: 'Cancel an in-progress workflow run',
12
- schema: {
13
- params: z.object({
14
- id: z.string().uuid()
15
- }),
16
- response: {
17
- 200: workflowRunDtoSchema
18
- }
19
- },
20
- errorHandler: (error)=>{
21
- if (error instanceof WorkflowRunNotCancellableError) {
22
- throw new ClientError(error.message, 'run-already-finished', {
23
- status: 409
8
+ export function cancelRunRoute(projects) {
9
+ return defineRoute({
10
+ method: 'POST',
11
+ path: '/:id/cancel',
12
+ description: 'Cancel an in-progress workflow run',
13
+ schema: {
14
+ params: z.object({
15
+ id: z.string().uuid()
16
+ }),
17
+ response: {
18
+ 200: workflowRunDtoSchema
19
+ }
20
+ },
21
+ errorHandler: (error)=>{
22
+ if (error instanceof WorkflowRunNotCancellableError) {
23
+ throw new ClientError(error.message, 'run-already-finished', {
24
+ status: 409
25
+ });
26
+ }
27
+ if (error instanceof WorkflowRunNotFoundError) {
28
+ throw new ClientError('Run not found', 'not-found', {
29
+ status: 404
30
+ });
31
+ }
32
+ throw error;
33
+ },
34
+ handler: async (request)=>{
35
+ const { id } = request.params;
36
+ const run = await requireAccessibleRun({
37
+ request,
38
+ id,
39
+ projects
24
40
  });
25
- }
26
- if (error instanceof WorkflowRunNotFoundError) {
27
- throw new ClientError('Run not found', 'not-found', {
28
- status: 404
41
+ const cancelled = await cancelWorkflowRun({
42
+ workflowRunId: run.id
29
43
  });
44
+ return toRunDto(cancelled);
30
45
  }
31
- throw error;
32
- },
33
- handler: async (request)=>{
34
- const { id } = request.params;
35
- const run = await requireAccessibleRun({
36
- request,
37
- id
38
- });
39
- const cancelled = await cancelWorkflowRun({
40
- workflowRunId: run.id
41
- });
42
- return toRunDto(cancelled);
43
- }
44
- });
46
+ });
47
+ }
45
48
 
46
49
  //# sourceMappingURL=cancel-run.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/presentation/routes/cancel-run.ts"],"sourcesContent":["import {workflowRunDtoSchema} from '@shipfox/api-workflows-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {WorkflowRunNotCancellableError, WorkflowRunNotFoundError} from '#core/errors.js';\nimport {cancelWorkflowRun} from '#db/index.js';\nimport {toRunDto} from '#presentation/dto/index.js';\nimport {requireAccessibleRun} from './require-accessible-run.js';\n\nexport const cancelRunRoute = defineRoute({\n method: 'POST',\n path: '/:id/cancel',\n description: 'Cancel an in-progress workflow run',\n schema: {\n params: z.object({\n id: z.string().uuid(),\n }),\n response: {\n 200: workflowRunDtoSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof WorkflowRunNotCancellableError) {\n throw new ClientError(error.message, 'run-already-finished', {status: 409});\n }\n if (error instanceof WorkflowRunNotFoundError) {\n throw new ClientError('Run not found', 'not-found', {status: 404});\n }\n throw error;\n },\n handler: async (request) => {\n const {id} = request.params;\n const run = await requireAccessibleRun({request, id});\n\n const cancelled = await cancelWorkflowRun({workflowRunId: run.id});\n return toRunDto(cancelled);\n },\n});\n"],"names":["workflowRunDtoSchema","ClientError","defineRoute","z","WorkflowRunNotCancellableError","WorkflowRunNotFoundError","cancelWorkflowRun","toRunDto","requireAccessibleRun","cancelRunRoute","method","path","description","schema","params","object","id","string","uuid","response","errorHandler","error","message","status","handler","request","run","cancelled","workflowRunId"],"mappings":"AAAA,SAAQA,oBAAoB,QAAO,6BAA6B;AAChE,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,8BAA8B,EAAEC,wBAAwB,QAAO,kBAAkB;AACzF,SAAQC,iBAAiB,QAAO,eAAe;AAC/C,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SAAQC,oBAAoB,QAAO,8BAA8B;AAEjE,OAAO,MAAMC,iBAAiBP,YAAY;IACxCQ,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,QAAQX,EAAEY,MAAM,CAAC;YACfC,IAAIb,EAAEc,MAAM,GAAGC,IAAI;QACrB;QACAC,UAAU;YACR,KAAKnB;QACP;IACF;IACAoB,cAAc,CAACC;QACb,IAAIA,iBAAiBjB,gCAAgC;YACnD,MAAM,IAAIH,YAAYoB,MAAMC,OAAO,EAAE,wBAAwB;gBAACC,QAAQ;YAAG;QAC3E;QACA,IAAIF,iBAAiBhB,0BAA0B;YAC7C,MAAM,IAAIJ,YAAY,iBAAiB,aAAa;gBAACsB,QAAQ;YAAG;QAClE;QACA,MAAMF;IACR;IACAG,SAAS,OAAOC;QACd,MAAM,EAACT,EAAE,EAAC,GAAGS,QAAQX,MAAM;QAC3B,MAAMY,MAAM,MAAMlB,qBAAqB;YAACiB;YAAST;QAAE;QAEnD,MAAMW,YAAY,MAAMrB,kBAAkB;YAACsB,eAAeF,IAAIV,EAAE;QAAA;QAChE,OAAOT,SAASoB;IAClB;AACF,GAAG"}
1
+ {"version":3,"sources":["../../../src/presentation/routes/cancel-run.ts"],"sourcesContent":["import type {ProjectsModuleClient} from '@shipfox/api-projects-dto';\nimport {workflowRunDtoSchema} from '@shipfox/api-workflows-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {WorkflowRunNotCancellableError, WorkflowRunNotFoundError} from '#core/errors.js';\nimport {cancelWorkflowRun} from '#db/index.js';\nimport {toRunDto} from '#presentation/dto/index.js';\nimport {requireAccessibleRun} from './require-accessible-run.js';\n\nexport function cancelRunRoute(projects: ProjectsModuleClient) {\n return defineRoute({\n method: 'POST',\n path: '/:id/cancel',\n description: 'Cancel an in-progress workflow run',\n schema: {\n params: z.object({\n id: z.string().uuid(),\n }),\n response: {\n 200: workflowRunDtoSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof WorkflowRunNotCancellableError) {\n throw new ClientError(error.message, 'run-already-finished', {status: 409});\n }\n if (error instanceof WorkflowRunNotFoundError) {\n throw new ClientError('Run not found', 'not-found', {status: 404});\n }\n throw error;\n },\n handler: async (request) => {\n const {id} = request.params;\n const run = await requireAccessibleRun({request, id, projects});\n\n const cancelled = await cancelWorkflowRun({workflowRunId: run.id});\n return toRunDto(cancelled);\n },\n });\n}\n"],"names":["workflowRunDtoSchema","ClientError","defineRoute","z","WorkflowRunNotCancellableError","WorkflowRunNotFoundError","cancelWorkflowRun","toRunDto","requireAccessibleRun","cancelRunRoute","projects","method","path","description","schema","params","object","id","string","uuid","response","errorHandler","error","message","status","handler","request","run","cancelled","workflowRunId"],"mappings":"AACA,SAAQA,oBAAoB,QAAO,6BAA6B;AAChE,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,8BAA8B,EAAEC,wBAAwB,QAAO,kBAAkB;AACzF,SAAQC,iBAAiB,QAAO,eAAe;AAC/C,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SAAQC,oBAAoB,QAAO,8BAA8B;AAEjE,OAAO,SAASC,eAAeC,QAA8B;IAC3D,OAAOR,YAAY;QACjBS,QAAQ;QACRC,MAAM;QACNC,aAAa;QACbC,QAAQ;YACNC,QAAQZ,EAAEa,MAAM,CAAC;gBACfC,IAAId,EAAEe,MAAM,GAAGC,IAAI;YACrB;YACAC,UAAU;gBACR,KAAKpB;YACP;QACF;QACAqB,cAAc,CAACC;YACb,IAAIA,iBAAiBlB,gCAAgC;gBACnD,MAAM,IAAIH,YAAYqB,MAAMC,OAAO,EAAE,wBAAwB;oBAACC,QAAQ;gBAAG;YAC3E;YACA,IAAIF,iBAAiBjB,0BAA0B;gBAC7C,MAAM,IAAIJ,YAAY,iBAAiB,aAAa;oBAACuB,QAAQ;gBAAG;YAClE;YACA,MAAMF;QACR;QACAG,SAAS,OAAOC;YACd,MAAM,EAACT,EAAE,EAAC,GAAGS,QAAQX,MAAM;YAC3B,MAAMY,MAAM,MAAMnB,qBAAqB;gBAACkB;gBAAST;gBAAIP;YAAQ;YAE7D,MAAMkB,YAAY,MAAMtB,kBAAkB;gBAACuB,eAAeF,IAAIV,EAAE;YAAA;YAChE,OAAOV,SAASqB;QAClB;IACF;AACF"}
@@ -1,2 +1,9 @@
1
- export declare const checkoutTokenRoute: import("@shipfox/node-fastify").RouteDefinition;
1
+ import { type IntegrationsModuleClient } from '@shipfox/api-integration-core-dto';
2
+ import type { ProjectsModuleClient } from '@shipfox/api-projects-dto';
3
+ import type { RunnersInterModuleClient } from '@shipfox/api-runners-dto/inter-module';
4
+ export declare function createCheckoutTokenRoute(clients: {
5
+ runners: RunnersInterModuleClient;
6
+ integrations: IntegrationsModuleClient;
7
+ projects: ProjectsModuleClient;
8
+ }): import("@shipfox/node-fastify").RouteDefinition;
2
9
  //# sourceMappingURL=checkout-token.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkout-token.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/checkout-token.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,kBAAkB,iDA8C7B,CAAC"}
1
+ {"version":3,"file":"checkout-token.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/checkout-token.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,wBAAwB,EAE9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAYpF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,OAAO,EAAE,wBAAwB,CAAC;IAClC,YAAY,EAAE,wBAAwB,CAAC;IACvC,QAAQ,EAAE,oBAAoB,CAAC;CAChC,mDAkGA"}
@@ -1,64 +1,82 @@
1
1
  import { requireLeasedJobContext } from '@shipfox/api-auth-context';
2
- import { integrationRouteErrorHandler } from '@shipfox/api-integration-core';
3
- import { isJobLeaseActive } from '@shipfox/api-runners';
2
+ import { integrationsInterModuleContract } from '@shipfox/api-integration-core-dto';
4
3
  import { checkoutTokenResponseSchema } from '@shipfox/api-workflows-dto';
4
+ import { isInterModuleKnownError } from '@shipfox/inter-module';
5
5
  import { ClientError, defineRoute } from '@shipfox/node-fastify';
6
6
  import { createJobCheckoutSpec } from '#core/checkout.js';
7
7
  import { CheckoutIntentUnresolvedError, JobNotFoundError, WorkflowRunNotFoundError } from '#core/errors.js';
8
- import { sourceControl } from '#core/source-control.js';
9
8
  import { toCheckoutTokenDto } from '#presentation/dto/checkout-token.js';
10
- export const checkoutTokenRoute = defineRoute({
11
- method: 'POST',
12
- path: '/checkout-token',
13
- description: "Exchanges the runner's job lease for short-lived, read-only checkout credentials for the job's repository. The job is identified by the access token, so no job ID is needed. The checkout target is resolved server-side from the job's run and project; no credential material is stored on the job or run. Returns the repository URL, ref, and (when the provider needs auth) a short-lived credential that expires soon.",
14
- schema: {
15
- response: {
16
- 200: checkoutTokenResponseSchema
17
- }
18
- },
19
- errorHandler: (error)=>{
20
- if (error instanceof JobNotFoundError) {
21
- throw new ClientError(error.message, 'job-not-found', {
9
+ export function createCheckoutTokenRoute(clients) {
10
+ return defineRoute({
11
+ method: 'POST',
12
+ path: '/checkout-token',
13
+ description: "Exchanges the runner's job lease for short-lived, read-only checkout credentials for the job's repository. The job is identified by the access token, so no job ID is needed. The checkout target is resolved server-side from the job's run and project; no credential material is stored on the job or run. Returns the repository URL, ref, and (when the provider needs auth) a short-lived credential that expires soon.",
14
+ schema: {
15
+ response: {
16
+ 200: checkoutTokenResponseSchema
17
+ }
18
+ },
19
+ errorHandler: (error)=>{
20
+ const known = isInterModuleKnownError(integrationsInterModuleContract.methods.createCheckoutSpec, error) ? error : undefined;
21
+ if (error instanceof JobNotFoundError) throw new ClientError(error.message, 'job-not-found', {
22
22
  status: 404
23
23
  });
24
- }
25
- if (error instanceof WorkflowRunNotFoundError) {
26
- throw new ClientError(error.message, 'run-not-found', {
24
+ if (error instanceof WorkflowRunNotFoundError) throw new ClientError(error.message, 'run-not-found', {
27
25
  status: 404
28
26
  });
29
- }
30
- if (error instanceof CheckoutIntentUnresolvedError) {
31
- throw new ClientError(error.message, 'checkout-unavailable', {
27
+ if (error instanceof CheckoutIntentUnresolvedError) throw new ClientError(error.message, 'checkout-unavailable', {
32
28
  status: 404
33
29
  });
34
- }
35
- // Connection and provider errors (and the structural provider-error detection)
36
- // map through the shared handler, which re-throws unknowns to the global handler.
37
- return integrationRouteErrorHandler(error);
38
- },
39
- handler: async (request, reply)=>{
40
- const leasedJob = requireLeasedJobContext(request);
41
- const leaseIsActive = await isJobLeaseActive({
42
- jobId: leasedJob.jobId,
43
- jobExecutionId: leasedJob.jobExecutionId,
44
- runnerSessionId: leasedJob.runnerSessionId
45
- });
46
- if (!leaseIsActive) {
47
- throw new ClientError('Job lease is no longer active', 'lease-not-active', {
30
+ if (known?.code === 'connection-not-found') throw new ClientError('Integration connection not found', 'integration-connection-not-found', {
31
+ status: 404
32
+ });
33
+ if (known?.code === 'connection-inactive') throw new ClientError('Integration connection is not active', 'integration-connection-inactive', {
34
+ status: 422
35
+ });
36
+ if (known?.code === 'connection-workspace-mismatch') throw new ClientError('Integration connection does not belong to this workspace', 'forbidden', {
37
+ status: 403
38
+ });
39
+ if (known?.code === 'provider-unavailable') throw new ClientError('Integration provider is unavailable', 'integration-provider-unavailable', {
40
+ status: 422
41
+ });
42
+ if (known?.code === 'capability-unavailable') throw new ClientError('Integration capability is unavailable', 'integration-capability-unavailable', {
43
+ status: 422
44
+ });
45
+ if (known?.code === 'checkout-unsupported') throw new ClientError('Integration checkout is unsupported', 'integration-checkout-unsupported', {
46
+ status: 422
47
+ });
48
+ if (known?.code === 'provider-failure') {
49
+ const status = known.details.reason === 'rate-limited' ? 429 : known.details.reason === 'timeout' || known.details.reason === 'provider-unavailable' ? 503 : 422;
50
+ throw new ClientError('Integration provider request failed', known.details.reason, {
51
+ details: {
52
+ retry_after_seconds: known.details.retryAfterSeconds
53
+ },
54
+ status
55
+ });
56
+ }
57
+ throw error;
58
+ },
59
+ handler: async (request, reply)=>{
60
+ const leasedJob = requireLeasedJobContext(request);
61
+ const { active: leaseIsActive } = await clients.runners.getLeaseState({
62
+ jobId: leasedJob.jobId,
63
+ jobExecutionId: leasedJob.jobExecutionId,
64
+ runnerSessionId: leasedJob.runnerSessionId
65
+ });
66
+ if (!leaseIsActive) throw new ClientError('Job lease is no longer active', 'lease-not-active', {
48
67
  status: 404
49
68
  });
69
+ const checkout = await createJobCheckoutSpec({
70
+ jobId: leasedJob.jobId,
71
+ integrations: clients.integrations,
72
+ projects: clients.projects
73
+ });
74
+ reply.header('cache-control', 'no-store');
75
+ return toCheckoutTokenDto(checkout.spec, {
76
+ persist: checkout.persistCredentials
77
+ });
50
78
  }
51
- const checkout = await createJobCheckoutSpec({
52
- jobId: leasedJob.jobId,
53
- sourceControl: sourceControl()
54
- });
55
- // The body carries short-lived git credentials; forbid any intermediary or
56
- // client cache from retaining them.
57
- reply.header('cache-control', 'no-store');
58
- return toCheckoutTokenDto(checkout.spec, {
59
- persist: checkout.persistCredentials
60
- });
61
- }
62
- });
79
+ });
80
+ }
63
81
 
64
82
  //# sourceMappingURL=checkout-token.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/presentation/routes/checkout-token.ts"],"sourcesContent":["import {requireLeasedJobContext} from '@shipfox/api-auth-context';\nimport {integrationRouteErrorHandler} from '@shipfox/api-integration-core';\nimport {isJobLeaseActive} from '@shipfox/api-runners';\nimport {checkoutTokenResponseSchema} from '@shipfox/api-workflows-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {createJobCheckoutSpec} from '#core/checkout.js';\nimport {\n CheckoutIntentUnresolvedError,\n JobNotFoundError,\n WorkflowRunNotFoundError,\n} from '#core/errors.js';\nimport {sourceControl} from '#core/source-control.js';\nimport {toCheckoutTokenDto} from '#presentation/dto/checkout-token.js';\n\nexport const checkoutTokenRoute = defineRoute({\n method: 'POST',\n path: '/checkout-token',\n description:\n \"Exchanges the runner's job lease for short-lived, read-only checkout credentials for the job's repository. The job is identified by the access token, so no job ID is needed. The checkout target is resolved server-side from the job's run and project; no credential material is stored on the job or run. Returns the repository URL, ref, and (when the provider needs auth) a short-lived credential that expires soon.\",\n schema: {\n response: {\n 200: checkoutTokenResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof JobNotFoundError) {\n throw new ClientError(error.message, 'job-not-found', {status: 404});\n }\n if (error instanceof WorkflowRunNotFoundError) {\n throw new ClientError(error.message, 'run-not-found', {status: 404});\n }\n if (error instanceof CheckoutIntentUnresolvedError) {\n throw new ClientError(error.message, 'checkout-unavailable', {status: 404});\n }\n // Connection and provider errors (and the structural provider-error detection)\n // map through the shared handler, which re-throws unknowns to the global handler.\n return integrationRouteErrorHandler(error);\n },\n handler: async (request, reply) => {\n const leasedJob = requireLeasedJobContext(request);\n\n const leaseIsActive = await isJobLeaseActive({\n jobId: leasedJob.jobId,\n jobExecutionId: leasedJob.jobExecutionId,\n runnerSessionId: leasedJob.runnerSessionId,\n });\n if (!leaseIsActive) {\n throw new ClientError('Job lease is no longer active', 'lease-not-active', {status: 404});\n }\n\n const checkout = await createJobCheckoutSpec({\n jobId: leasedJob.jobId,\n sourceControl: sourceControl(),\n });\n\n // The body carries short-lived git credentials; forbid any intermediary or\n // client cache from retaining them.\n reply.header('cache-control', 'no-store');\n return toCheckoutTokenDto(checkout.spec, {persist: checkout.persistCredentials});\n },\n});\n"],"names":["requireLeasedJobContext","integrationRouteErrorHandler","isJobLeaseActive","checkoutTokenResponseSchema","ClientError","defineRoute","createJobCheckoutSpec","CheckoutIntentUnresolvedError","JobNotFoundError","WorkflowRunNotFoundError","sourceControl","toCheckoutTokenDto","checkoutTokenRoute","method","path","description","schema","response","errorHandler","error","message","status","handler","request","reply","leasedJob","leaseIsActive","jobId","jobExecutionId","runnerSessionId","checkout","header","spec","persist","persistCredentials"],"mappings":"AAAA,SAAQA,uBAAuB,QAAO,4BAA4B;AAClE,SAAQC,4BAA4B,QAAO,gCAAgC;AAC3E,SAAQC,gBAAgB,QAAO,uBAAuB;AACtD,SAAQC,2BAA2B,QAAO,6BAA6B;AACvE,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,qBAAqB,QAAO,oBAAoB;AACxD,SACEC,6BAA6B,EAC7BC,gBAAgB,EAChBC,wBAAwB,QACnB,kBAAkB;AACzB,SAAQC,aAAa,QAAO,0BAA0B;AACtD,SAAQC,kBAAkB,QAAO,sCAAsC;AAEvE,OAAO,MAAMC,qBAAqBP,YAAY;IAC5CQ,QAAQ;IACRC,MAAM;IACNC,aACE;IACFC,QAAQ;QACNC,UAAU;YACR,KAAKd;QACP;IACF;IACAe,cAAc,CAACC;QACb,IAAIA,iBAAiBX,kBAAkB;YACrC,MAAM,IAAIJ,YAAYe,MAAMC,OAAO,EAAE,iBAAiB;gBAACC,QAAQ;YAAG;QACpE;QACA,IAAIF,iBAAiBV,0BAA0B;YAC7C,MAAM,IAAIL,YAAYe,MAAMC,OAAO,EAAE,iBAAiB;gBAACC,QAAQ;YAAG;QACpE;QACA,IAAIF,iBAAiBZ,+BAA+B;YAClD,MAAM,IAAIH,YAAYe,MAAMC,OAAO,EAAE,wBAAwB;gBAACC,QAAQ;YAAG;QAC3E;QACA,+EAA+E;QAC/E,kFAAkF;QAClF,OAAOpB,6BAA6BkB;IACtC;IACAG,SAAS,OAAOC,SAASC;QACvB,MAAMC,YAAYzB,wBAAwBuB;QAE1C,MAAMG,gBAAgB,MAAMxB,iBAAiB;YAC3CyB,OAAOF,UAAUE,KAAK;YACtBC,gBAAgBH,UAAUG,cAAc;YACxCC,iBAAiBJ,UAAUI,eAAe;QAC5C;QACA,IAAI,CAACH,eAAe;YAClB,MAAM,IAAItB,YAAY,iCAAiC,oBAAoB;gBAACiB,QAAQ;YAAG;QACzF;QAEA,MAAMS,WAAW,MAAMxB,sBAAsB;YAC3CqB,OAAOF,UAAUE,KAAK;YACtBjB,eAAeA;QACjB;QAEA,2EAA2E;QAC3E,oCAAoC;QACpCc,MAAMO,MAAM,CAAC,iBAAiB;QAC9B,OAAOpB,mBAAmBmB,SAASE,IAAI,EAAE;YAACC,SAASH,SAASI,kBAAkB;QAAA;IAChF;AACF,GAAG"}
1
+ {"version":3,"sources":["../../../src/presentation/routes/checkout-token.ts"],"sourcesContent":["import {requireLeasedJobContext} from '@shipfox/api-auth-context';\nimport {\n type IntegrationsModuleClient,\n integrationsInterModuleContract,\n} from '@shipfox/api-integration-core-dto';\nimport type {ProjectsModuleClient} from '@shipfox/api-projects-dto';\nimport type {RunnersInterModuleClient} from '@shipfox/api-runners-dto/inter-module';\nimport {checkoutTokenResponseSchema} from '@shipfox/api-workflows-dto';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {createJobCheckoutSpec} from '#core/checkout.js';\nimport {\n CheckoutIntentUnresolvedError,\n JobNotFoundError,\n WorkflowRunNotFoundError,\n} from '#core/errors.js';\nimport {toCheckoutTokenDto} from '#presentation/dto/checkout-token.js';\n\nexport function createCheckoutTokenRoute(clients: {\n runners: RunnersInterModuleClient;\n integrations: IntegrationsModuleClient;\n projects: ProjectsModuleClient;\n}) {\n return defineRoute({\n method: 'POST',\n path: '/checkout-token',\n description:\n \"Exchanges the runner's job lease for short-lived, read-only checkout credentials for the job's repository. The job is identified by the access token, so no job ID is needed. The checkout target is resolved server-side from the job's run and project; no credential material is stored on the job or run. Returns the repository URL, ref, and (when the provider needs auth) a short-lived credential that expires soon.\",\n schema: {response: {200: checkoutTokenResponseSchema}},\n errorHandler: (error) => {\n const known = isInterModuleKnownError(\n integrationsInterModuleContract.methods.createCheckoutSpec,\n error,\n )\n ? error\n : undefined;\n if (error instanceof JobNotFoundError)\n throw new ClientError(error.message, 'job-not-found', {status: 404});\n if (error instanceof WorkflowRunNotFoundError)\n throw new ClientError(error.message, 'run-not-found', {status: 404});\n if (error instanceof CheckoutIntentUnresolvedError)\n throw new ClientError(error.message, 'checkout-unavailable', {status: 404});\n if (known?.code === 'connection-not-found')\n throw new ClientError(\n 'Integration connection not found',\n 'integration-connection-not-found',\n {\n status: 404,\n },\n );\n if (known?.code === 'connection-inactive')\n throw new ClientError(\n 'Integration connection is not active',\n 'integration-connection-inactive',\n {\n status: 422,\n },\n );\n if (known?.code === 'connection-workspace-mismatch')\n throw new ClientError(\n 'Integration connection does not belong to this workspace',\n 'forbidden',\n {status: 403},\n );\n if (known?.code === 'provider-unavailable')\n throw new ClientError(\n 'Integration provider is unavailable',\n 'integration-provider-unavailable',\n {\n status: 422,\n },\n );\n if (known?.code === 'capability-unavailable')\n throw new ClientError(\n 'Integration capability is unavailable',\n 'integration-capability-unavailable',\n {\n status: 422,\n },\n );\n if (known?.code === 'checkout-unsupported')\n throw new ClientError(\n 'Integration checkout is unsupported',\n 'integration-checkout-unsupported',\n {\n status: 422,\n },\n );\n if (known?.code === 'provider-failure') {\n const status =\n known.details.reason === 'rate-limited'\n ? 429\n : known.details.reason === 'timeout' || known.details.reason === 'provider-unavailable'\n ? 503\n : 422;\n throw new ClientError('Integration provider request failed', known.details.reason, {\n details: {retry_after_seconds: known.details.retryAfterSeconds},\n status,\n });\n }\n throw error;\n },\n handler: async (request, reply) => {\n const leasedJob = requireLeasedJobContext(request);\n const {active: leaseIsActive} = await clients.runners.getLeaseState({\n jobId: leasedJob.jobId,\n jobExecutionId: leasedJob.jobExecutionId,\n runnerSessionId: leasedJob.runnerSessionId,\n });\n if (!leaseIsActive)\n throw new ClientError('Job lease is no longer active', 'lease-not-active', {status: 404});\n const checkout = await createJobCheckoutSpec({\n jobId: leasedJob.jobId,\n integrations: clients.integrations,\n projects: clients.projects,\n });\n reply.header('cache-control', 'no-store');\n return toCheckoutTokenDto(checkout.spec, {persist: checkout.persistCredentials});\n },\n });\n}\n"],"names":["requireLeasedJobContext","integrationsInterModuleContract","checkoutTokenResponseSchema","isInterModuleKnownError","ClientError","defineRoute","createJobCheckoutSpec","CheckoutIntentUnresolvedError","JobNotFoundError","WorkflowRunNotFoundError","toCheckoutTokenDto","createCheckoutTokenRoute","clients","method","path","description","schema","response","errorHandler","error","known","methods","createCheckoutSpec","undefined","message","status","code","details","reason","retry_after_seconds","retryAfterSeconds","handler","request","reply","leasedJob","active","leaseIsActive","runners","getLeaseState","jobId","jobExecutionId","runnerSessionId","checkout","integrations","projects","header","spec","persist","persistCredentials"],"mappings":"AAAA,SAAQA,uBAAuB,QAAO,4BAA4B;AAClE,SAEEC,+BAA+B,QAC1B,oCAAoC;AAG3C,SAAQC,2BAA2B,QAAO,6BAA6B;AACvE,SAAQC,uBAAuB,QAAO,wBAAwB;AAC9D,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,qBAAqB,QAAO,oBAAoB;AACxD,SACEC,6BAA6B,EAC7BC,gBAAgB,EAChBC,wBAAwB,QACnB,kBAAkB;AACzB,SAAQC,kBAAkB,QAAO,sCAAsC;AAEvE,OAAO,SAASC,yBAAyBC,OAIxC;IACC,OAAOP,YAAY;QACjBQ,QAAQ;QACRC,MAAM;QACNC,aACE;QACFC,QAAQ;YAACC,UAAU;gBAAC,KAAKf;YAA2B;QAAC;QACrDgB,cAAc,CAACC;YACb,MAAMC,QAAQjB,wBACZF,gCAAgCoB,OAAO,CAACC,kBAAkB,EAC1DH,SAEEA,QACAI;YACJ,IAAIJ,iBAAiBX,kBACnB,MAAM,IAAIJ,YAAYe,MAAMK,OAAO,EAAE,iBAAiB;gBAACC,QAAQ;YAAG;YACpE,IAAIN,iBAAiBV,0BACnB,MAAM,IAAIL,YAAYe,MAAMK,OAAO,EAAE,iBAAiB;gBAACC,QAAQ;YAAG;YACpE,IAAIN,iBAAiBZ,+BACnB,MAAM,IAAIH,YAAYe,MAAMK,OAAO,EAAE,wBAAwB;gBAACC,QAAQ;YAAG;YAC3E,IAAIL,OAAOM,SAAS,wBAClB,MAAM,IAAItB,YACR,oCACA,oCACA;gBACEqB,QAAQ;YACV;YAEJ,IAAIL,OAAOM,SAAS,uBAClB,MAAM,IAAItB,YACR,wCACA,mCACA;gBACEqB,QAAQ;YACV;YAEJ,IAAIL,OAAOM,SAAS,iCAClB,MAAM,IAAItB,YACR,4DACA,aACA;gBAACqB,QAAQ;YAAG;YAEhB,IAAIL,OAAOM,SAAS,wBAClB,MAAM,IAAItB,YACR,uCACA,oCACA;gBACEqB,QAAQ;YACV;YAEJ,IAAIL,OAAOM,SAAS,0BAClB,MAAM,IAAItB,YACR,yCACA,sCACA;gBACEqB,QAAQ;YACV;YAEJ,IAAIL,OAAOM,SAAS,wBAClB,MAAM,IAAItB,YACR,uCACA,oCACA;gBACEqB,QAAQ;YACV;YAEJ,IAAIL,OAAOM,SAAS,oBAAoB;gBACtC,MAAMD,SACJL,MAAMO,OAAO,CAACC,MAAM,KAAK,iBACrB,MACAR,MAAMO,OAAO,CAACC,MAAM,KAAK,aAAaR,MAAMO,OAAO,CAACC,MAAM,KAAK,yBAC7D,MACA;gBACR,MAAM,IAAIxB,YAAY,uCAAuCgB,MAAMO,OAAO,CAACC,MAAM,EAAE;oBACjFD,SAAS;wBAACE,qBAAqBT,MAAMO,OAAO,CAACG,iBAAiB;oBAAA;oBAC9DL;gBACF;YACF;YACA,MAAMN;QACR;QACAY,SAAS,OAAOC,SAASC;YACvB,MAAMC,YAAYlC,wBAAwBgC;YAC1C,MAAM,EAACG,QAAQC,aAAa,EAAC,GAAG,MAAMxB,QAAQyB,OAAO,CAACC,aAAa,CAAC;gBAClEC,OAAOL,UAAUK,KAAK;gBACtBC,gBAAgBN,UAAUM,cAAc;gBACxCC,iBAAiBP,UAAUO,eAAe;YAC5C;YACA,IAAI,CAACL,eACH,MAAM,IAAIhC,YAAY,iCAAiC,oBAAoB;gBAACqB,QAAQ;YAAG;YACzF,MAAMiB,WAAW,MAAMpC,sBAAsB;gBAC3CiC,OAAOL,UAAUK,KAAK;gBACtBI,cAAc/B,QAAQ+B,YAAY;gBAClCC,UAAUhC,QAAQgC,QAAQ;YAC5B;YACAX,MAAMY,MAAM,CAAC,iBAAiB;YAC9B,OAAOnC,mBAAmBgC,SAASI,IAAI,EAAE;gBAACC,SAASL,SAASM,kBAAkB;YAAA;QAChF;IACF;AACF"}
@@ -1,2 +1,3 @@
1
- export declare const getRunAggregatesRoute: import("@shipfox/node-fastify").RouteDefinition;
1
+ import type { ProjectsModuleClient } from '@shipfox/api-projects-dto';
2
+ export declare function getRunAggregatesRoute(projects: ProjectsModuleClient): import("@shipfox/node-fastify").RouteDefinition;
2
3
  //# sourceMappingURL=get-run-aggregates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-run-aggregates.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/get-run-aggregates.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,qBAAqB,iDA2DhC,CAAC"}
1
+ {"version":3,"file":"get-run-aggregates.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/get-run-aggregates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAUpE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,oBAAoB,mDAuDnE"}
@@ -1,60 +1,51 @@
1
- import { ProjectNotFoundError, requireProjectAccess } from '@shipfox/api-projects';
2
1
  import { workflowRunAggregatesQuerySchema, workflowRunAggregatesResponseSchema } from '@shipfox/api-workflows-dto';
3
- import { ClientError, defineRoute } from '@shipfox/node-fastify';
2
+ import { defineRoute } from '@shipfox/node-fastify';
4
3
  import { logger } from '@shipfox/node-opentelemetry';
5
4
  import { getWorkflowRunAggregates } from '#db/index.js';
6
- export const getRunAggregatesRoute = defineRoute({
7
- method: 'GET',
8
- path: '/aggregates',
9
- description: 'Get faceted workflow run counts for a project',
10
- schema: {
11
- querystring: workflowRunAggregatesQuerySchema,
12
- response: {
13
- 200: workflowRunAggregatesResponseSchema
14
- }
15
- },
16
- errorHandler: (error)=>{
17
- if (error instanceof ProjectNotFoundError) {
18
- throw new ClientError(error.message, 'project-not-found', {
19
- status: 404
5
+ import { requireProjectAccess } from './project-access.js';
6
+ export function getRunAggregatesRoute(projects) {
7
+ return defineRoute({
8
+ method: 'GET',
9
+ path: '/aggregates',
10
+ description: 'Get faceted workflow run counts for a project',
11
+ schema: {
12
+ querystring: workflowRunAggregatesQuerySchema,
13
+ response: {
14
+ 200: workflowRunAggregatesResponseSchema
15
+ }
16
+ },
17
+ handler: async (request)=>{
18
+ const startedAt = performance.now();
19
+ const { project_id: projectId, status, definition_id: definitionId, trigger_source: triggerSource, created_from: createdFrom, created_to: createdTo } = request.query;
20
+ const project = await requireProjectAccess(request, projectId, projects);
21
+ const filters = {
22
+ status,
23
+ definitionId,
24
+ triggerSource,
25
+ createdFrom: createdFrom ? new Date(createdFrom) : undefined,
26
+ createdTo: createdTo ? new Date(createdTo) : undefined
27
+ };
28
+ const aggregates = await getWorkflowRunAggregates({
29
+ projectId: project.id,
30
+ filters
20
31
  });
32
+ logger().info({
33
+ projectId: project.id,
34
+ filterKeys: Object.entries(filters).filter(([, value])=>value !== undefined).map(([key])=>key),
35
+ aggregateBucketSizes: {
36
+ status: aggregates.status.length,
37
+ triggerSource: aggregates.triggerSource.length,
38
+ workflow: aggregates.workflow.length
39
+ },
40
+ durationMs: Math.round(performance.now() - startedAt)
41
+ }, 'Aggregated workflow runs');
42
+ return {
43
+ status: aggregates.status,
44
+ trigger_source: aggregates.triggerSource,
45
+ workflow: aggregates.workflow
46
+ };
21
47
  }
22
- throw error;
23
- },
24
- handler: async (request)=>{
25
- const startedAt = performance.now();
26
- const { project_id: projectId, status, definition_id: definitionId, trigger_source: triggerSource, created_from: createdFrom, created_to: createdTo } = request.query;
27
- const { project } = await requireProjectAccess({
28
- request,
29
- projectId
30
- });
31
- const filters = {
32
- status,
33
- definitionId,
34
- triggerSource,
35
- createdFrom: createdFrom ? new Date(createdFrom) : undefined,
36
- createdTo: createdTo ? new Date(createdTo) : undefined
37
- };
38
- const aggregates = await getWorkflowRunAggregates({
39
- projectId: project.id,
40
- filters
41
- });
42
- logger().info({
43
- projectId: project.id,
44
- filterKeys: Object.entries(filters).filter(([, value])=>value !== undefined).map(([key])=>key),
45
- aggregateBucketSizes: {
46
- status: aggregates.status.length,
47
- triggerSource: aggregates.triggerSource.length,
48
- workflow: aggregates.workflow.length
49
- },
50
- durationMs: Math.round(performance.now() - startedAt)
51
- }, 'Aggregated workflow runs');
52
- return {
53
- status: aggregates.status,
54
- trigger_source: aggregates.triggerSource,
55
- workflow: aggregates.workflow
56
- };
57
- }
58
- });
48
+ });
49
+ }
59
50
 
60
51
  //# sourceMappingURL=get-run-aggregates.js.map