@shipfox/api-triggers 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 (97) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +51 -0
  3. package/README.md +23 -3
  4. package/dist/core/dispatch-integration-event.d.ts +2 -0
  5. package/dist/core/dispatch-integration-event.d.ts.map +1 -1
  6. package/dist/core/dispatch-integration-event.js +9 -5
  7. package/dist/core/dispatch-integration-event.js.map +1 -1
  8. package/dist/core/drain-cron-schedules.d.ts +2 -0
  9. package/dist/core/drain-cron-schedules.d.ts.map +1 -1
  10. package/dist/core/drain-cron-schedules.js +1 -0
  11. package/dist/core/drain-cron-schedules.js.map +1 -1
  12. package/dist/core/fire-cron.d.ts +6 -2
  13. package/dist/core/fire-cron.d.ts.map +1 -1
  14. package/dist/core/fire-cron.js +8 -5
  15. package/dist/core/fire-cron.js.map +1 -1
  16. package/dist/core/fire-manual.d.ts +6 -2
  17. package/dist/core/fire-manual.d.ts.map +1 -1
  18. package/dist/core/fire-manual.js +8 -4
  19. package/dist/core/fire-manual.js.map +1 -1
  20. package/dist/core/route-event-to-job-listeners.d.ts +2 -0
  21. package/dist/core/route-event-to-job-listeners.d.ts.map +1 -1
  22. package/dist/core/route-event-to-job-listeners.js +2 -3
  23. package/dist/core/route-event-to-job-listeners.js.map +1 -1
  24. package/dist/core/workflows-client.d.ts +69 -0
  25. package/dist/core/workflows-client.d.ts.map +1 -0
  26. package/dist/core/workflows-client.js +20 -0
  27. package/dist/core/workflows-client.js.map +1 -0
  28. package/dist/db/job-listener-subscriptions.d.ts +1 -0
  29. package/dist/db/job-listener-subscriptions.d.ts.map +1 -1
  30. package/dist/db/job-listener-subscriptions.js +6 -0
  31. package/dist/db/job-listener-subscriptions.js.map +1 -1
  32. package/dist/index.d.ts +5 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +56 -50
  35. package/dist/index.js.map +1 -1
  36. package/dist/presentation/e2e-routes.d.ts +3 -0
  37. package/dist/presentation/e2e-routes.d.ts.map +1 -0
  38. package/dist/presentation/e2e-routes.js +31 -0
  39. package/dist/presentation/e2e-routes.js.map +1 -0
  40. package/dist/presentation/index.d.ts +2 -2
  41. package/dist/presentation/index.d.ts.map +1 -1
  42. package/dist/presentation/index.js +2 -2
  43. package/dist/presentation/index.js.map +1 -1
  44. package/dist/presentation/routes/fire-manual.d.ts +2 -1
  45. package/dist/presentation/routes/fire-manual.d.ts.map +1 -1
  46. package/dist/presentation/routes/fire-manual.js +61 -58
  47. package/dist/presentation/routes/fire-manual.js.map +1 -1
  48. package/dist/presentation/routes/index.d.ts +2 -1
  49. package/dist/presentation/routes/index.d.ts.map +1 -1
  50. package/dist/presentation/routes/index.js +23 -21
  51. package/dist/presentation/routes/index.js.map +1 -1
  52. package/dist/presentation/subscribers/index.d.ts +1 -1
  53. package/dist/presentation/subscribers/index.d.ts.map +1 -1
  54. package/dist/presentation/subscribers/index.js +1 -1
  55. package/dist/presentation/subscribers/index.js.map +1 -1
  56. package/dist/presentation/subscribers/on-integration-event-received.d.ts +2 -1
  57. package/dist/presentation/subscribers/on-integration-event-received.d.ts.map +1 -1
  58. package/dist/presentation/subscribers/on-integration-event-received.js +16 -13
  59. package/dist/presentation/subscribers/on-integration-event-received.js.map +1 -1
  60. package/dist/temporal/activities/drain-cron-batch.d.ts +2 -1
  61. package/dist/temporal/activities/drain-cron-batch.d.ts.map +1 -1
  62. package/dist/temporal/activities/drain-cron-batch.js +2 -1
  63. package/dist/temporal/activities/drain-cron-batch.js.map +1 -1
  64. package/dist/temporal/activities/index.d.ts +4 -3
  65. package/dist/temporal/activities/index.d.ts.map +1 -1
  66. package/dist/temporal/activities/index.js +2 -2
  67. package/dist/temporal/activities/index.js.map +1 -1
  68. package/dist/tsconfig.test.tsbuildinfo +1 -1
  69. package/package.json +14 -12
  70. package/src/core/dispatch-integration-event.history-failure.test.ts +11 -6
  71. package/src/core/dispatch-integration-event.test.ts +50 -36
  72. package/src/core/dispatch-integration-event.ts +8 -5
  73. package/src/core/drain-cron-schedules.test.ts +30 -29
  74. package/src/core/drain-cron-schedules.ts +3 -0
  75. package/src/core/fire-cron.test.ts +35 -24
  76. package/src/core/fire-cron.ts +9 -7
  77. package/src/core/fire-manual.test.ts +19 -22
  78. package/src/core/fire-manual.ts +9 -6
  79. package/src/core/record-trigger-history.test.ts +3 -5
  80. package/src/core/route-event-to-job-listeners.test.ts +5 -4
  81. package/src/core/route-event-to-job-listeners.ts +5 -4
  82. package/src/core/workflows-client.test.ts +73 -0
  83. package/src/core/workflows-client.ts +32 -0
  84. package/src/db/job-listener-subscriptions.ts +9 -0
  85. package/src/index.ts +51 -42
  86. package/src/presentation/e2e-routes.test.ts +44 -0
  87. package/src/presentation/e2e-routes.ts +24 -0
  88. package/src/presentation/index.ts +2 -2
  89. package/src/presentation/routes/fire-manual.test.ts +14 -30
  90. package/src/presentation/routes/fire-manual.ts +62 -54
  91. package/src/presentation/routes/index.ts +18 -15
  92. package/src/presentation/subscribers/index.ts +1 -1
  93. package/src/presentation/subscribers/on-integration-event-received.test.ts +6 -3
  94. package/src/presentation/subscribers/on-integration-event-received.ts +20 -16
  95. package/src/temporal/activities/drain-cron-batch.ts +5 -1
  96. package/src/temporal/activities/index.ts +3 -2
  97. package/tsconfig.build.tsbuildinfo +1 -1
@@ -0,0 +1,69 @@
1
+ import { type WorkflowsModuleClient } from '@shipfox/api-workflows-dto/inter-module';
2
+ export type { WorkflowsModuleClient };
3
+ /**
4
+ * Workflows declares only failures that can never succeed on retry for trigger
5
+ * run creation. Every other outcome is opaque and must remain retryable because
6
+ * it may have committed before the caller stopped waiting.
7
+ */
8
+ export declare function isPermanentStartRunError(error: unknown): boolean;
9
+ export declare function isInterpolationUnresolvableError(error: unknown): error is Extract<ReturnType<typeof startRunKnownError>, {
10
+ code: 'interpolation-unresolvable';
11
+ }>;
12
+ declare function startRunKnownError(error: unknown): import("@shipfox/inter-module").InterModuleKnownErrorFor<import("@shipfox/inter-module").InterModuleMethodContract<import("zod").ZodObject<{
13
+ workspaceId: import("zod").ZodString;
14
+ projectId: import("zod").ZodString;
15
+ definitionId: import("zod").ZodString;
16
+ triggerPayload: import("zod").ZodUnion<readonly [import("zod").ZodObject<{
17
+ provider: import("zod").ZodOptional<import("zod").ZodLiteral<"manual">>;
18
+ source: import("zod").ZodLiteral<"manual">;
19
+ event: import("zod").ZodLiteral<"fire">;
20
+ subscriptionId: import("zod").ZodString;
21
+ userId: import("zod").ZodString;
22
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
23
+ provider: import("zod").ZodOptional<import("zod").ZodLiteral<"cron">>;
24
+ source: import("zod").ZodLiteral<"cron">;
25
+ event: import("zod").ZodLiteral<"tick">;
26
+ scheduleId: import("zod").ZodString;
27
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
28
+ provider: import("zod").ZodString;
29
+ source: import("zod").ZodString;
30
+ event: import("zod").ZodString;
31
+ deliveryId: import("zod").ZodString;
32
+ data: import("zod").ZodUnknown;
33
+ }, import("zod/v4/core").$strip>]>;
34
+ inputs: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>>;
35
+ idempotencyKey: import("zod").ZodString;
36
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
37
+ id: import("zod").ZodString;
38
+ name: import("zod").ZodString;
39
+ }, import("zod/v4/core").$strip>, {
40
+ readonly 'definition-not-found': import("zod").ZodObject<{
41
+ definitionId: import("zod").ZodString;
42
+ }, import("zod/v4/core").$strip>;
43
+ readonly 'project-mismatch': import("zod").ZodObject<{}, import("zod/v4/core").$strip>;
44
+ readonly 'agent-config-unresolvable': import("zod").ZodObject<{
45
+ definitionId: import("zod").ZodString;
46
+ }, import("zod/v4/core").$strip>;
47
+ readonly 'agent-integration-materialization-failed': import("zod").ZodObject<{}, import("zod/v4/core").$strip>;
48
+ readonly 'interpolation-unresolvable': import("zod").ZodObject<{
49
+ definitionId: import("zod").ZodString;
50
+ field: import("zod").ZodEnum<{
51
+ run: "run";
52
+ env: "env";
53
+ "agent.prompt": "agent.prompt";
54
+ "agent.model": "agent.model";
55
+ "agent.provider": "agent.provider";
56
+ "job.runner": "job.runner";
57
+ "job.outputs": "job.outputs";
58
+ "job.name": "job.name";
59
+ "step.name": "step.name";
60
+ "step.feedback": "step.feedback";
61
+ }>;
62
+ source: import("zod").ZodString;
63
+ envKey: import("zod").ZodOptional<import("zod").ZodString>;
64
+ }, import("zod/v4/core").$strip>;
65
+ readonly 'invalid-job-runner-labels': import("zod").ZodObject<{
66
+ labels: import("zod").ZodArray<import("zod").ZodString>;
67
+ }, import("zod/v4/core").$strip>;
68
+ }>> | undefined;
69
+ //# sourceMappingURL=workflows-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows-client.d.ts","sourceRoot":"","sources":["../../src/core/workflows-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,yCAAyC,CAAC;AAGjD,YAAY,EAAC,qBAAqB,EAAC,CAAC;AAEpC;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhE;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAAE;IAAC,IAAI,EAAE,4BAA4B,CAAA;CAAC,CAAC,CAK/F;AAED,iBAAS,kBAAkB,CAAC,KAAK,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAKzC"}
@@ -0,0 +1,20 @@
1
+ import { workflowsInterModuleContract } from '@shipfox/api-workflows-dto/inter-module';
2
+ import { isInterModuleKnownError } from '@shipfox/inter-module';
3
+ /**
4
+ * Workflows declares only failures that can never succeed on retry for trigger
5
+ * run creation. Every other outcome is opaque and must remain retryable because
6
+ * it may have committed before the caller stopped waiting.
7
+ */ export function isPermanentStartRunError(error) {
8
+ return isInterModuleKnownError(workflowsInterModuleContract.methods.startRunFromTrigger, error);
9
+ }
10
+ export function isInterpolationUnresolvableError(error) {
11
+ return isInterModuleKnownError(workflowsInterModuleContract.methods.startRunFromTrigger, error) && error.code === 'interpolation-unresolvable';
12
+ }
13
+ function startRunKnownError(error) {
14
+ if (!isInterModuleKnownError(workflowsInterModuleContract.methods.startRunFromTrigger, error)) {
15
+ return undefined;
16
+ }
17
+ return error;
18
+ }
19
+
20
+ //# sourceMappingURL=workflows-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/workflows-client.ts"],"sourcesContent":["import {\n type WorkflowsModuleClient,\n workflowsInterModuleContract,\n} from '@shipfox/api-workflows-dto/inter-module';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\n\nexport type {WorkflowsModuleClient};\n\n/**\n * Workflows declares only failures that can never succeed on retry for trigger\n * run creation. Every other outcome is opaque and must remain retryable because\n * it may have committed before the caller stopped waiting.\n */\nexport function isPermanentStartRunError(error: unknown): boolean {\n return isInterModuleKnownError(workflowsInterModuleContract.methods.startRunFromTrigger, error);\n}\n\nexport function isInterpolationUnresolvableError(\n error: unknown,\n): error is Extract<ReturnType<typeof startRunKnownError>, {code: 'interpolation-unresolvable'}> {\n return (\n isInterModuleKnownError(workflowsInterModuleContract.methods.startRunFromTrigger, error) &&\n error.code === 'interpolation-unresolvable'\n );\n}\n\nfunction startRunKnownError(error: unknown) {\n if (!isInterModuleKnownError(workflowsInterModuleContract.methods.startRunFromTrigger, error)) {\n return undefined;\n }\n return error;\n}\n"],"names":["workflowsInterModuleContract","isInterModuleKnownError","isPermanentStartRunError","error","methods","startRunFromTrigger","isInterpolationUnresolvableError","code","startRunKnownError","undefined"],"mappings":"AAAA,SAEEA,4BAA4B,QACvB,0CAA0C;AACjD,SAAQC,uBAAuB,QAAO,wBAAwB;AAI9D;;;;CAIC,GACD,OAAO,SAASC,yBAAyBC,KAAc;IACrD,OAAOF,wBAAwBD,6BAA6BI,OAAO,CAACC,mBAAmB,EAAEF;AAC3F;AAEA,OAAO,SAASG,iCACdH,KAAc;IAEd,OACEF,wBAAwBD,6BAA6BI,OAAO,CAACC,mBAAmB,EAAEF,UAClFA,MAAMI,IAAI,KAAK;AAEnB;AAEA,SAASC,mBAAmBL,KAAc;IACxC,IAAI,CAACF,wBAAwBD,6BAA6BI,OAAO,CAACC,mBAAmB,EAAEF,QAAQ;QAC7F,OAAOM;IACT;IACA,OAAON;AACT"}
@@ -21,4 +21,5 @@ export interface FindMatchingJobListenerSubscriptionsParams {
21
21
  event: string;
22
22
  }
23
23
  export declare function findMatchingJobListenerSubscriptions(params: FindMatchingJobListenerSubscriptionsParams): Promise<JobListenerSubscription[]>;
24
+ export declare function hasJobListenerSubscriptions(jobId: string): Promise<boolean>;
24
25
  //# sourceMappingURL=job-listener-subscriptions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"job-listener-subscriptions.d.ts","sourceRoot":"","sources":["../../src/db/job-listener-subscriptions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,6CAA6C,CAAC;AASrD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IACvD,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;IACtC,KAAK,EAAE,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,IAAI,CAAC,CA4Cf;AA6BD,wBAAsB,oCAAoC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzF;AAED,MAAM,WAAW,0CAA0C;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,0CAA0C,GACjD,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAYpC"}
1
+ {"version":3,"file":"job-listener-subscriptions.d.ts","sourceRoot":"","sources":["../../src/db/job-listener-subscriptions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,6CAA6C,CAAC;AASrD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IACvD,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;IACtC,KAAK,EAAE,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,IAAI,CAAC,CA4Cf;AA6BD,wBAAsB,oCAAoC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzF;AAED,MAAM,WAAW,0CAA0C;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,0CAA0C,GACjD,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAYpC;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjF"}
@@ -65,5 +65,11 @@ export async function findMatchingJobListenerSubscriptions(params) {
65
65
  const rows = await db().select().from(jobListenerSubscriptions).where(and(eq(jobListenerSubscriptions.workspaceId, params.workspaceId), eq(jobListenerSubscriptions.source, params.source), eq(jobListenerSubscriptions.event, params.event)));
66
66
  return rows.map(toJobListenerSubscription);
67
67
  }
68
+ export async function hasJobListenerSubscriptions(jobId) {
69
+ const [subscription] = await db().select({
70
+ id: jobListenerSubscriptions.id
71
+ }).from(jobListenerSubscriptions).where(eq(jobListenerSubscriptions.jobId, jobId)).limit(1);
72
+ return subscription !== undefined;
73
+ }
68
74
 
69
75
  //# sourceMappingURL=job-listener-subscriptions.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/job-listener-subscriptions.ts"],"sourcesContent":["import {and, eq, notInArray} from 'drizzle-orm';\nimport type {\n JobListenerMatcherKind,\n JobListenerSubscription,\n} from '#core/entities/job-listener-subscription.js';\nimport {db} from './db.js';\nimport {\n jobListenerSubscriptions,\n toJobListenerSubscription,\n} from './schema/job-listener-subscriptions.js';\n\ntype Tx = Parameters<Parameters<ReturnType<typeof db>['transaction']>[0]>[0];\n\nexport interface ListenerMatcher {\n source: string;\n event: string;\n inputs?: Readonly<Record<string, unknown>> | undefined;\n filter?: string | undefined;\n filter_snapshot?: Readonly<Record<string, unknown>> | undefined;\n}\n\nexport interface ProjectJobListenerSubscriptionsParams {\n workspaceId: string;\n workflowRunId: string;\n jobId: string;\n on: readonly ListenerMatcher[] | null;\n until: readonly ListenerMatcher[] | null;\n}\n\nexport async function projectJobListenerSubscriptions(\n params: ProjectJobListenerSubscriptionsParams,\n): Promise<void> {\n await db().transaction(async (tx) => {\n await pruneStaleMatchers(tx, params.jobId, 'on', params.on ?? []);\n await pruneStaleMatchers(tx, params.jobId, 'until', params.until ?? []);\n\n for (const [kind, matchers] of [\n ['on', params.on ?? []],\n ['until', params.until ?? []],\n ] as const) {\n for (const [matcherOrdinal, matcher] of matchers.entries()) {\n const config: Record<string, unknown> = {};\n if (matcher.inputs !== undefined) config.inputs = matcher.inputs;\n if (matcher.filter !== undefined) config.filter = matcher.filter;\n if (matcher.filter_snapshot !== undefined) config.filter_snapshot = matcher.filter_snapshot;\n\n await tx\n .insert(jobListenerSubscriptions)\n .values({\n workspaceId: params.workspaceId,\n workflowRunId: params.workflowRunId,\n jobId: params.jobId,\n kind,\n matcherOrdinal,\n source: matcher.source,\n event: matcher.event,\n config,\n })\n .onConflictDoUpdate({\n target: [\n jobListenerSubscriptions.jobId,\n jobListenerSubscriptions.kind,\n jobListenerSubscriptions.matcherOrdinal,\n ],\n set: {\n workspaceId: params.workspaceId,\n workflowRunId: params.workflowRunId,\n source: matcher.source,\n event: matcher.event,\n config,\n },\n });\n }\n }\n });\n}\n\nasync function pruneStaleMatchers(\n tx: Tx,\n jobId: string,\n kind: JobListenerMatcherKind,\n matchers: readonly ListenerMatcher[],\n): Promise<void> {\n const base = and(\n eq(jobListenerSubscriptions.jobId, jobId),\n eq(jobListenerSubscriptions.kind, kind),\n );\n\n if (matchers.length === 0) {\n await tx.delete(jobListenerSubscriptions).where(base);\n return;\n }\n\n await tx.delete(jobListenerSubscriptions).where(\n and(\n base,\n notInArray(\n jobListenerSubscriptions.matcherOrdinal,\n matchers.map((_matcher, index) => index),\n ),\n ),\n );\n}\n\nexport async function removeJobListenerSubscriptionsForJob(jobId: string): Promise<number> {\n const rows = await db()\n .delete(jobListenerSubscriptions)\n .where(eq(jobListenerSubscriptions.jobId, jobId))\n .returning({id: jobListenerSubscriptions.id});\n return rows.length;\n}\n\nexport interface FindMatchingJobListenerSubscriptionsParams {\n workspaceId: string;\n source: string;\n event: string;\n}\n\nexport async function findMatchingJobListenerSubscriptions(\n params: FindMatchingJobListenerSubscriptionsParams,\n): Promise<JobListenerSubscription[]> {\n const rows = await db()\n .select()\n .from(jobListenerSubscriptions)\n .where(\n and(\n eq(jobListenerSubscriptions.workspaceId, params.workspaceId),\n eq(jobListenerSubscriptions.source, params.source),\n eq(jobListenerSubscriptions.event, params.event),\n ),\n );\n return rows.map(toJobListenerSubscription);\n}\n"],"names":["and","eq","notInArray","db","jobListenerSubscriptions","toJobListenerSubscription","projectJobListenerSubscriptions","params","transaction","tx","pruneStaleMatchers","jobId","on","until","kind","matchers","matcherOrdinal","matcher","entries","config","inputs","undefined","filter","filter_snapshot","insert","values","workspaceId","workflowRunId","source","event","onConflictDoUpdate","target","set","base","length","delete","where","map","_matcher","index","removeJobListenerSubscriptionsForJob","rows","returning","id","findMatchingJobListenerSubscriptions","select","from"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/job-listener-subscriptions.ts"],"sourcesContent":["import {and, eq, notInArray} from 'drizzle-orm';\nimport type {\n JobListenerMatcherKind,\n JobListenerSubscription,\n} from '#core/entities/job-listener-subscription.js';\nimport {db} from './db.js';\nimport {\n jobListenerSubscriptions,\n toJobListenerSubscription,\n} from './schema/job-listener-subscriptions.js';\n\ntype Tx = Parameters<Parameters<ReturnType<typeof db>['transaction']>[0]>[0];\n\nexport interface ListenerMatcher {\n source: string;\n event: string;\n inputs?: Readonly<Record<string, unknown>> | undefined;\n filter?: string | undefined;\n filter_snapshot?: Readonly<Record<string, unknown>> | undefined;\n}\n\nexport interface ProjectJobListenerSubscriptionsParams {\n workspaceId: string;\n workflowRunId: string;\n jobId: string;\n on: readonly ListenerMatcher[] | null;\n until: readonly ListenerMatcher[] | null;\n}\n\nexport async function projectJobListenerSubscriptions(\n params: ProjectJobListenerSubscriptionsParams,\n): Promise<void> {\n await db().transaction(async (tx) => {\n await pruneStaleMatchers(tx, params.jobId, 'on', params.on ?? []);\n await pruneStaleMatchers(tx, params.jobId, 'until', params.until ?? []);\n\n for (const [kind, matchers] of [\n ['on', params.on ?? []],\n ['until', params.until ?? []],\n ] as const) {\n for (const [matcherOrdinal, matcher] of matchers.entries()) {\n const config: Record<string, unknown> = {};\n if (matcher.inputs !== undefined) config.inputs = matcher.inputs;\n if (matcher.filter !== undefined) config.filter = matcher.filter;\n if (matcher.filter_snapshot !== undefined) config.filter_snapshot = matcher.filter_snapshot;\n\n await tx\n .insert(jobListenerSubscriptions)\n .values({\n workspaceId: params.workspaceId,\n workflowRunId: params.workflowRunId,\n jobId: params.jobId,\n kind,\n matcherOrdinal,\n source: matcher.source,\n event: matcher.event,\n config,\n })\n .onConflictDoUpdate({\n target: [\n jobListenerSubscriptions.jobId,\n jobListenerSubscriptions.kind,\n jobListenerSubscriptions.matcherOrdinal,\n ],\n set: {\n workspaceId: params.workspaceId,\n workflowRunId: params.workflowRunId,\n source: matcher.source,\n event: matcher.event,\n config,\n },\n });\n }\n }\n });\n}\n\nasync function pruneStaleMatchers(\n tx: Tx,\n jobId: string,\n kind: JobListenerMatcherKind,\n matchers: readonly ListenerMatcher[],\n): Promise<void> {\n const base = and(\n eq(jobListenerSubscriptions.jobId, jobId),\n eq(jobListenerSubscriptions.kind, kind),\n );\n\n if (matchers.length === 0) {\n await tx.delete(jobListenerSubscriptions).where(base);\n return;\n }\n\n await tx.delete(jobListenerSubscriptions).where(\n and(\n base,\n notInArray(\n jobListenerSubscriptions.matcherOrdinal,\n matchers.map((_matcher, index) => index),\n ),\n ),\n );\n}\n\nexport async function removeJobListenerSubscriptionsForJob(jobId: string): Promise<number> {\n const rows = await db()\n .delete(jobListenerSubscriptions)\n .where(eq(jobListenerSubscriptions.jobId, jobId))\n .returning({id: jobListenerSubscriptions.id});\n return rows.length;\n}\n\nexport interface FindMatchingJobListenerSubscriptionsParams {\n workspaceId: string;\n source: string;\n event: string;\n}\n\nexport async function findMatchingJobListenerSubscriptions(\n params: FindMatchingJobListenerSubscriptionsParams,\n): Promise<JobListenerSubscription[]> {\n const rows = await db()\n .select()\n .from(jobListenerSubscriptions)\n .where(\n and(\n eq(jobListenerSubscriptions.workspaceId, params.workspaceId),\n eq(jobListenerSubscriptions.source, params.source),\n eq(jobListenerSubscriptions.event, params.event),\n ),\n );\n return rows.map(toJobListenerSubscription);\n}\n\nexport async function hasJobListenerSubscriptions(jobId: string): Promise<boolean> {\n const [subscription] = await db()\n .select({id: jobListenerSubscriptions.id})\n .from(jobListenerSubscriptions)\n .where(eq(jobListenerSubscriptions.jobId, jobId))\n .limit(1);\n return subscription !== undefined;\n}\n"],"names":["and","eq","notInArray","db","jobListenerSubscriptions","toJobListenerSubscription","projectJobListenerSubscriptions","params","transaction","tx","pruneStaleMatchers","jobId","on","until","kind","matchers","matcherOrdinal","matcher","entries","config","inputs","undefined","filter","filter_snapshot","insert","values","workspaceId","workflowRunId","source","event","onConflictDoUpdate","target","set","base","length","delete","where","map","_matcher","index","removeJobListenerSubscriptionsForJob","rows","returning","id","findMatchingJobListenerSubscriptions","select","from","hasJobListenerSubscriptions","subscription","limit"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,11 @@
1
+ import type { WorkflowsModuleClient } from '@shipfox/api-workflows-dto/inter-module';
1
2
  import { type ShipfoxModule } from '@shipfox/node-module';
2
3
  export type { JobListenerMatcherKind, JobListenerSubscription, } from '#core/entities/job-listener-subscription.js';
3
4
  export type { TriggerSubscription } from '#core/entities/subscription.js';
4
5
  export { fireCronSubscription, fireManualSubscription, ManualTriggerNotFoundError, TriggerSubscriptionNotCronError, TriggerSubscriptionNotFoundError, TriggerSubscriptionNotManualError, TriggerWorkspaceMismatchError, } from '#core/index.js';
5
6
  export { db, findMatchingJobListenerSubscriptions, findMatchingSubscriptions, getManualSubscriptionByDefinitionId, getTriggerSubscriptionById, jobListenerSubscriptions, listSubscriptionsByWorkflowDefinitionIds, migrationsPath, projectJobListenerSubscriptions, removeJobListenerSubscriptionsForJob, triggersOutbox, } from '#db/index.js';
6
- export declare const triggersModule: ShipfoxModule;
7
+ export interface CreateTriggersModuleOptions {
8
+ workflows: WorkflowsModuleClient;
9
+ }
10
+ export declare function createTriggersModule({ workflows }: CreateTriggersModuleOptions): ShipfoxModule;
7
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAiB3E,YAAY,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,6CAA6C,CAAC;AACrD,YAAY,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACxE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,EAC/B,gCAAgC,EAChC,iCAAiC,EACjC,6BAA6B,GAC9B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,EAAE,EACF,oCAAoC,EACpC,yBAAyB,EACzB,mCAAmC,EACnC,0BAA0B,EAC1B,wBAAwB,EACxB,wCAAwC,EACxC,cAAc,EACd,+BAA+B,EAC/B,oCAAoC,EACpC,cAAc,GACf,MAAM,cAAc,CAAC;AAStB,eAAO,MAAM,cAAc,EAAE,aAuC5B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAC,KAAK,aAAa,EAAoB,MAAM,sBAAsB,CAAC;AAkB3E,YAAY,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,6CAA6C,CAAC;AACrD,YAAY,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACxE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,EAC/B,gCAAgC,EAChC,iCAAiC,EACjC,6BAA6B,GAC9B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,EAAE,EACF,oCAAoC,EACpC,yBAAyB,EACzB,mCAAmC,EACnC,0BAA0B,EAC1B,wBAAwB,EACxB,wCAAwC,EACxC,cAAc,EACd,+BAA+B,EAC/B,oCAAoC,EACpC,cAAc,GACf,MAAM,cAAc,CAAC;AAStB,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,qBAAqB,CAAC;CAClC;AAED,wBAAgB,oBAAoB,CAAC,EAAC,SAAS,EAAC,EAAE,2BAA2B,GAAG,aAAa,CA0C5F"}
package/dist/index.js CHANGED
@@ -6,8 +6,9 @@ import { WORKFLOWS_JOB_ACTIVATED, WORKFLOWS_JOB_TERMINATED } from '@shipfox/api-
6
6
  import { subscriberFactory } from '@shipfox/node-module';
7
7
  import { db, migrationsPath, triggersOutbox } from '#db/index.js';
8
8
  import { registerTriggersServiceMetrics } from '#metrics/index.js';
9
- import { routes } from '#presentation/index.js';
10
- import { onDefinitionDeleted, onDefinitionResolved, onIntegrationEventReceived, onJobActivated, onJobTerminated } from '#presentation/subscribers/index.js';
9
+ import { triggersE2eRoutes } from '#presentation/e2e-routes.js';
10
+ import { createTriggerRoutes } from '#presentation/index.js';
11
+ import { createOnIntegrationEventReceived, onDefinitionDeleted, onDefinitionResolved, onJobActivated, onJobTerminated } from '#presentation/subscribers/index.js';
11
12
  import { createTriggersCronActivities, createTriggersMaintenanceActivities } from '#temporal/activities/index.js';
12
13
  import { TRIGGERS_CRON_TASK_QUEUE, TRIGGERS_MAINTENANCE_TASK_QUEUE } from '#temporal/constants.js';
13
14
  export { fireCronSubscription, fireManualSubscription, ManualTriggerNotFoundError, TriggerSubscriptionNotCronError, TriggerSubscriptionNotFoundError, TriggerSubscriptionNotManualError, TriggerWorkspaceMismatchError } from '#core/index.js';
@@ -15,54 +16,59 @@ export { db, findMatchingJobListenerSubscriptions, findMatchingSubscriptions, ge
15
16
  const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
16
17
  const temporalWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');
17
18
  const subscriber = subscriberFactory();
18
- export const triggersModule = {
19
- name: 'triggers',
20
- database: {
21
- db,
22
- migrationsPath
23
- },
24
- routes,
25
- metrics: registerTriggersServiceMetrics,
26
- publishers: [
27
- {
28
- name: 'triggers',
29
- table: triggersOutbox,
30
- db
31
- }
32
- ],
33
- subscribers: [
34
- subscriber(DEFINITION_RESOLVED, onDefinitionResolved),
35
- subscriber(DEFINITION_DELETED, onDefinitionDeleted),
36
- subscriber(INTEGRATION_EVENT_RECEIVED, onIntegrationEventReceived),
37
- subscriber(WORKFLOWS_JOB_ACTIVATED, onJobActivated),
38
- subscriber(WORKFLOWS_JOB_TERMINATED, onJobTerminated)
39
- ],
40
- workers: [
41
- {
42
- taskQueue: TRIGGERS_MAINTENANCE_TASK_QUEUE,
43
- workflowsPath: temporalWorkflowsPath,
44
- activities: createTriggersMaintenanceActivities,
45
- workflows: [
46
- {
47
- name: 'pruneTriggerEventsCron',
48
- id: 'triggers-prune-trigger-events',
49
- cronSchedule: '0 * * * *'
50
- }
51
- ]
19
+ export function createTriggersModule({ workflows }) {
20
+ return {
21
+ name: 'triggers',
22
+ database: {
23
+ db,
24
+ migrationsPath
52
25
  },
53
- {
54
- taskQueue: TRIGGERS_CRON_TASK_QUEUE,
55
- workflowsPath: temporalWorkflowsPath,
56
- activities: createTriggersCronActivities,
57
- workflows: [
58
- {
59
- name: 'cronTickCron',
60
- id: 'triggers-cron-tick',
61
- cronSchedule: '* * * * *'
62
- }
63
- ]
64
- }
65
- ]
66
- };
26
+ routes: createTriggerRoutes(workflows),
27
+ e2eRoutes: [
28
+ triggersE2eRoutes
29
+ ],
30
+ metrics: registerTriggersServiceMetrics,
31
+ publishers: [
32
+ {
33
+ name: 'triggers',
34
+ table: triggersOutbox,
35
+ db
36
+ }
37
+ ],
38
+ subscribers: [
39
+ subscriber(DEFINITION_RESOLVED, onDefinitionResolved),
40
+ subscriber(DEFINITION_DELETED, onDefinitionDeleted),
41
+ subscriber(INTEGRATION_EVENT_RECEIVED, createOnIntegrationEventReceived(workflows)),
42
+ subscriber(WORKFLOWS_JOB_ACTIVATED, onJobActivated),
43
+ subscriber(WORKFLOWS_JOB_TERMINATED, onJobTerminated)
44
+ ],
45
+ workers: [
46
+ {
47
+ taskQueue: TRIGGERS_MAINTENANCE_TASK_QUEUE,
48
+ workflowsPath: temporalWorkflowsPath,
49
+ activities: createTriggersMaintenanceActivities,
50
+ workflows: [
51
+ {
52
+ name: 'pruneTriggerEventsCron',
53
+ id: 'triggers-prune-trigger-events',
54
+ cronSchedule: '0 * * * *'
55
+ }
56
+ ]
57
+ },
58
+ {
59
+ taskQueue: TRIGGERS_CRON_TASK_QUEUE,
60
+ workflowsPath: temporalWorkflowsPath,
61
+ activities: ()=>createTriggersCronActivities(workflows),
62
+ workflows: [
63
+ {
64
+ name: 'cronTickCron',
65
+ id: 'triggers-cron-tick',
66
+ cronSchedule: '* * * * *'
67
+ }
68
+ ]
69
+ }
70
+ ]
71
+ };
72
+ }
67
73
 
68
74
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {\n DEFINITION_DELETED,\n DEFINITION_RESOLVED,\n type DefinitionsEventMap,\n} from '@shipfox/api-definitions-dto';\nimport {\n INTEGRATION_EVENT_RECEIVED,\n type IntegrationsEventMap,\n} from '@shipfox/api-integration-core-dto';\nimport {\n WORKFLOWS_JOB_ACTIVATED,\n WORKFLOWS_JOB_TERMINATED,\n type WorkflowsEventMapDto,\n} from '@shipfox/api-workflows-dto';\nimport {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';\nimport {db, migrationsPath, triggersOutbox} from '#db/index.js';\nimport {registerTriggersServiceMetrics} from '#metrics/index.js';\nimport {routes} from '#presentation/index.js';\nimport {\n onDefinitionDeleted,\n onDefinitionResolved,\n onIntegrationEventReceived,\n onJobActivated,\n onJobTerminated,\n} from '#presentation/subscribers/index.js';\nimport {\n createTriggersCronActivities,\n createTriggersMaintenanceActivities,\n} from '#temporal/activities/index.js';\nimport {TRIGGERS_CRON_TASK_QUEUE, TRIGGERS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';\n\nexport type {\n JobListenerMatcherKind,\n JobListenerSubscription,\n} from '#core/entities/job-listener-subscription.js';\nexport type {TriggerSubscription} from '#core/entities/subscription.js';\nexport {\n fireCronSubscription,\n fireManualSubscription,\n ManualTriggerNotFoundError,\n TriggerSubscriptionNotCronError,\n TriggerSubscriptionNotFoundError,\n TriggerSubscriptionNotManualError,\n TriggerWorkspaceMismatchError,\n} from '#core/index.js';\nexport {\n db,\n findMatchingJobListenerSubscriptions,\n findMatchingSubscriptions,\n getManualSubscriptionByDefinitionId,\n getTriggerSubscriptionById,\n jobListenerSubscriptions,\n listSubscriptionsByWorkflowDefinitionIds,\n migrationsPath,\n projectJobListenerSubscriptions,\n removeJobListenerSubscriptionsForJob,\n triggersOutbox,\n} from '#db/index.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst temporalWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nconst subscriber = subscriberFactory<\n DefinitionsEventMap & IntegrationsEventMap & WorkflowsEventMapDto\n>();\n\nexport const triggersModule: ShipfoxModule = {\n name: 'triggers',\n database: {db, migrationsPath},\n routes,\n metrics: registerTriggersServiceMetrics,\n publishers: [{name: 'triggers', table: triggersOutbox, db}],\n subscribers: [\n subscriber(DEFINITION_RESOLVED, onDefinitionResolved),\n subscriber(DEFINITION_DELETED, onDefinitionDeleted),\n subscriber(INTEGRATION_EVENT_RECEIVED, onIntegrationEventReceived),\n subscriber(WORKFLOWS_JOB_ACTIVATED, onJobActivated),\n subscriber(WORKFLOWS_JOB_TERMINATED, onJobTerminated),\n ],\n workers: [\n {\n taskQueue: TRIGGERS_MAINTENANCE_TASK_QUEUE,\n workflowsPath: temporalWorkflowsPath,\n activities: createTriggersMaintenanceActivities,\n workflows: [\n {\n name: 'pruneTriggerEventsCron',\n id: 'triggers-prune-trigger-events',\n cronSchedule: '0 * * * *',\n },\n ],\n },\n {\n taskQueue: TRIGGERS_CRON_TASK_QUEUE,\n workflowsPath: temporalWorkflowsPath,\n activities: createTriggersCronActivities,\n workflows: [\n {\n name: 'cronTickCron',\n id: 'triggers-cron-tick',\n cronSchedule: '* * * * *',\n },\n ],\n },\n ],\n};\n"],"names":["dirname","resolve","fileURLToPath","DEFINITION_DELETED","DEFINITION_RESOLVED","INTEGRATION_EVENT_RECEIVED","WORKFLOWS_JOB_ACTIVATED","WORKFLOWS_JOB_TERMINATED","subscriberFactory","db","migrationsPath","triggersOutbox","registerTriggersServiceMetrics","routes","onDefinitionDeleted","onDefinitionResolved","onIntegrationEventReceived","onJobActivated","onJobTerminated","createTriggersCronActivities","createTriggersMaintenanceActivities","TRIGGERS_CRON_TASK_QUEUE","TRIGGERS_MAINTENANCE_TASK_QUEUE","fireCronSubscription","fireManualSubscription","ManualTriggerNotFoundError","TriggerSubscriptionNotCronError","TriggerSubscriptionNotFoundError","TriggerSubscriptionNotManualError","TriggerWorkspaceMismatchError","findMatchingJobListenerSubscriptions","findMatchingSubscriptions","getManualSubscriptionByDefinitionId","getTriggerSubscriptionById","jobListenerSubscriptions","listSubscriptionsByWorkflowDefinitionIds","projectJobListenerSubscriptions","removeJobListenerSubscriptionsForJob","packageRoot","url","temporalWorkflowsPath","subscriber","triggersModule","name","database","metrics","publishers","table","subscribers","workers","taskQueue","workflowsPath","activities","workflows","id","cronSchedule"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AACvC,SACEC,kBAAkB,EAClBC,mBAAmB,QAEd,+BAA+B;AACtC,SACEC,0BAA0B,QAErB,oCAAoC;AAC3C,SACEC,uBAAuB,EACvBC,wBAAwB,QAEnB,6BAA6B;AACpC,SAA4BC,iBAAiB,QAAO,uBAAuB;AAC3E,SAAQC,EAAE,EAAEC,cAAc,EAAEC,cAAc,QAAO,eAAe;AAChE,SAAQC,8BAA8B,QAAO,oBAAoB;AACjE,SAAQC,MAAM,QAAO,yBAAyB;AAC9C,SACEC,mBAAmB,EACnBC,oBAAoB,EACpBC,0BAA0B,EAC1BC,cAAc,EACdC,eAAe,QACV,qCAAqC;AAC5C,SACEC,4BAA4B,EAC5BC,mCAAmC,QAC9B,gCAAgC;AACvC,SAAQC,wBAAwB,EAAEC,+BAA+B,QAAO,yBAAyB;AAOjG,SACEC,oBAAoB,EACpBC,sBAAsB,EACtBC,0BAA0B,EAC1BC,+BAA+B,EAC/BC,gCAAgC,EAChCC,iCAAiC,EACjCC,6BAA6B,QACxB,iBAAiB;AACxB,SACEpB,EAAE,EACFqB,oCAAoC,EACpCC,yBAAyB,EACzBC,mCAAmC,EACnCC,0BAA0B,EAC1BC,wBAAwB,EACxBC,wCAAwC,EACxCzB,cAAc,EACd0B,+BAA+B,EAC/BC,oCAAoC,EACpC1B,cAAc,QACT,eAAe;AAEtB,MAAM2B,cAAcrC,QAAQD,QAAQE,cAAc,YAAYqC,GAAG,IAAI;AACrE,MAAMC,wBAAwBvC,QAAQqC,aAAa;AAEnD,MAAMG,aAAajC;AAInB,OAAO,MAAMkC,iBAAgC;IAC3CC,MAAM;IACNC,UAAU;QAACnC;QAAIC;IAAc;IAC7BG;IACAgC,SAASjC;IACTkC,YAAY;QAAC;YAACH,MAAM;YAAYI,OAAOpC;YAAgBF;QAAE;KAAE;IAC3DuC,aAAa;QACXP,WAAWrC,qBAAqBW;QAChC0B,WAAWtC,oBAAoBW;QAC/B2B,WAAWpC,4BAA4BW;QACvCyB,WAAWnC,yBAAyBW;QACpCwB,WAAWlC,0BAA0BW;KACtC;IACD+B,SAAS;QACP;YACEC,WAAW5B;YACX6B,eAAeX;YACfY,YAAYhC;YACZiC,WAAW;gBACT;oBACEV,MAAM;oBACNW,IAAI;oBACJC,cAAc;gBAChB;aACD;QACH;QACA;YACEL,WAAW7B;YACX8B,eAAeX;YACfY,YAAYjC;YACZkC,WAAW;gBACT;oBACEV,MAAM;oBACNW,IAAI;oBACJC,cAAc;gBAChB;aACD;QACH;KACD;AACH,EAAE"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {\n DEFINITION_DELETED,\n DEFINITION_RESOLVED,\n type DefinitionsEventMap,\n} from '@shipfox/api-definitions-dto';\nimport {\n INTEGRATION_EVENT_RECEIVED,\n type IntegrationsEventMap,\n} from '@shipfox/api-integration-core-dto';\nimport {\n WORKFLOWS_JOB_ACTIVATED,\n WORKFLOWS_JOB_TERMINATED,\n type WorkflowsEventMapDto,\n} from '@shipfox/api-workflows-dto';\nimport type {WorkflowsModuleClient} from '@shipfox/api-workflows-dto/inter-module';\nimport {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';\nimport {db, migrationsPath, triggersOutbox} from '#db/index.js';\nimport {registerTriggersServiceMetrics} from '#metrics/index.js';\nimport {triggersE2eRoutes} from '#presentation/e2e-routes.js';\nimport {createTriggerRoutes} from '#presentation/index.js';\nimport {\n createOnIntegrationEventReceived,\n onDefinitionDeleted,\n onDefinitionResolved,\n onJobActivated,\n onJobTerminated,\n} from '#presentation/subscribers/index.js';\nimport {\n createTriggersCronActivities,\n createTriggersMaintenanceActivities,\n} from '#temporal/activities/index.js';\nimport {TRIGGERS_CRON_TASK_QUEUE, TRIGGERS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';\n\nexport type {\n JobListenerMatcherKind,\n JobListenerSubscription,\n} from '#core/entities/job-listener-subscription.js';\nexport type {TriggerSubscription} from '#core/entities/subscription.js';\nexport {\n fireCronSubscription,\n fireManualSubscription,\n ManualTriggerNotFoundError,\n TriggerSubscriptionNotCronError,\n TriggerSubscriptionNotFoundError,\n TriggerSubscriptionNotManualError,\n TriggerWorkspaceMismatchError,\n} from '#core/index.js';\nexport {\n db,\n findMatchingJobListenerSubscriptions,\n findMatchingSubscriptions,\n getManualSubscriptionByDefinitionId,\n getTriggerSubscriptionById,\n jobListenerSubscriptions,\n listSubscriptionsByWorkflowDefinitionIds,\n migrationsPath,\n projectJobListenerSubscriptions,\n removeJobListenerSubscriptionsForJob,\n triggersOutbox,\n} from '#db/index.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst temporalWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nconst subscriber = subscriberFactory<\n DefinitionsEventMap & IntegrationsEventMap & WorkflowsEventMapDto\n>();\n\nexport interface CreateTriggersModuleOptions {\n workflows: WorkflowsModuleClient;\n}\n\nexport function createTriggersModule({workflows}: CreateTriggersModuleOptions): ShipfoxModule {\n return {\n name: 'triggers',\n database: {db, migrationsPath},\n routes: createTriggerRoutes(workflows),\n e2eRoutes: [triggersE2eRoutes],\n metrics: registerTriggersServiceMetrics,\n publishers: [{name: 'triggers', table: triggersOutbox, db}],\n subscribers: [\n subscriber(DEFINITION_RESOLVED, onDefinitionResolved),\n subscriber(DEFINITION_DELETED, onDefinitionDeleted),\n subscriber(INTEGRATION_EVENT_RECEIVED, createOnIntegrationEventReceived(workflows)),\n subscriber(WORKFLOWS_JOB_ACTIVATED, onJobActivated),\n subscriber(WORKFLOWS_JOB_TERMINATED, onJobTerminated),\n ],\n workers: [\n {\n taskQueue: TRIGGERS_MAINTENANCE_TASK_QUEUE,\n workflowsPath: temporalWorkflowsPath,\n activities: createTriggersMaintenanceActivities,\n workflows: [\n {\n name: 'pruneTriggerEventsCron',\n id: 'triggers-prune-trigger-events',\n cronSchedule: '0 * * * *',\n },\n ],\n },\n {\n taskQueue: TRIGGERS_CRON_TASK_QUEUE,\n workflowsPath: temporalWorkflowsPath,\n activities: () => createTriggersCronActivities(workflows),\n workflows: [\n {\n name: 'cronTickCron',\n id: 'triggers-cron-tick',\n cronSchedule: '* * * * *',\n },\n ],\n },\n ],\n };\n}\n"],"names":["dirname","resolve","fileURLToPath","DEFINITION_DELETED","DEFINITION_RESOLVED","INTEGRATION_EVENT_RECEIVED","WORKFLOWS_JOB_ACTIVATED","WORKFLOWS_JOB_TERMINATED","subscriberFactory","db","migrationsPath","triggersOutbox","registerTriggersServiceMetrics","triggersE2eRoutes","createTriggerRoutes","createOnIntegrationEventReceived","onDefinitionDeleted","onDefinitionResolved","onJobActivated","onJobTerminated","createTriggersCronActivities","createTriggersMaintenanceActivities","TRIGGERS_CRON_TASK_QUEUE","TRIGGERS_MAINTENANCE_TASK_QUEUE","fireCronSubscription","fireManualSubscription","ManualTriggerNotFoundError","TriggerSubscriptionNotCronError","TriggerSubscriptionNotFoundError","TriggerSubscriptionNotManualError","TriggerWorkspaceMismatchError","findMatchingJobListenerSubscriptions","findMatchingSubscriptions","getManualSubscriptionByDefinitionId","getTriggerSubscriptionById","jobListenerSubscriptions","listSubscriptionsByWorkflowDefinitionIds","projectJobListenerSubscriptions","removeJobListenerSubscriptionsForJob","packageRoot","url","temporalWorkflowsPath","subscriber","createTriggersModule","workflows","name","database","routes","e2eRoutes","metrics","publishers","table","subscribers","workers","taskQueue","workflowsPath","activities","id","cronSchedule"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AACvC,SACEC,kBAAkB,EAClBC,mBAAmB,QAEd,+BAA+B;AACtC,SACEC,0BAA0B,QAErB,oCAAoC;AAC3C,SACEC,uBAAuB,EACvBC,wBAAwB,QAEnB,6BAA6B;AAEpC,SAA4BC,iBAAiB,QAAO,uBAAuB;AAC3E,SAAQC,EAAE,EAAEC,cAAc,EAAEC,cAAc,QAAO,eAAe;AAChE,SAAQC,8BAA8B,QAAO,oBAAoB;AACjE,SAAQC,iBAAiB,QAAO,8BAA8B;AAC9D,SAAQC,mBAAmB,QAAO,yBAAyB;AAC3D,SACEC,gCAAgC,EAChCC,mBAAmB,EACnBC,oBAAoB,EACpBC,cAAc,EACdC,eAAe,QACV,qCAAqC;AAC5C,SACEC,4BAA4B,EAC5BC,mCAAmC,QAC9B,gCAAgC;AACvC,SAAQC,wBAAwB,EAAEC,+BAA+B,QAAO,yBAAyB;AAOjG,SACEC,oBAAoB,EACpBC,sBAAsB,EACtBC,0BAA0B,EAC1BC,+BAA+B,EAC/BC,gCAAgC,EAChCC,iCAAiC,EACjCC,6BAA6B,QACxB,iBAAiB;AACxB,SACErB,EAAE,EACFsB,oCAAoC,EACpCC,yBAAyB,EACzBC,mCAAmC,EACnCC,0BAA0B,EAC1BC,wBAAwB,EACxBC,wCAAwC,EACxC1B,cAAc,EACd2B,+BAA+B,EAC/BC,oCAAoC,EACpC3B,cAAc,QACT,eAAe;AAEtB,MAAM4B,cAActC,QAAQD,QAAQE,cAAc,YAAYsC,GAAG,IAAI;AACrE,MAAMC,wBAAwBxC,QAAQsC,aAAa;AAEnD,MAAMG,aAAalC;AAQnB,OAAO,SAASmC,qBAAqB,EAACC,SAAS,EAA8B;IAC3E,OAAO;QACLC,MAAM;QACNC,UAAU;YAACrC;YAAIC;QAAc;QAC7BqC,QAAQjC,oBAAoB8B;QAC5BI,WAAW;YAACnC;SAAkB;QAC9BoC,SAASrC;QACTsC,YAAY;YAAC;gBAACL,MAAM;gBAAYM,OAAOxC;gBAAgBF;YAAE;SAAE;QAC3D2C,aAAa;YACXV,WAAWtC,qBAAqBa;YAChCyB,WAAWvC,oBAAoBa;YAC/B0B,WAAWrC,4BAA4BU,iCAAiC6B;YACxEF,WAAWpC,yBAAyBY;YACpCwB,WAAWnC,0BAA0BY;SACtC;QACDkC,SAAS;YACP;gBACEC,WAAW/B;gBACXgC,eAAed;gBACfe,YAAYnC;gBACZuB,WAAW;oBACT;wBACEC,MAAM;wBACNY,IAAI;wBACJC,cAAc;oBAChB;iBACD;YACH;YACA;gBACEJ,WAAWhC;gBACXiC,eAAed;gBACfe,YAAY,IAAMpC,6BAA6BwB;gBAC/CA,WAAW;oBACT;wBACEC,MAAM;wBACNY,IAAI;wBACJC,cAAc;oBAChB;iBACD;YACH;SACD;IACH;AACF"}
@@ -0,0 +1,3 @@
1
+ import { type RouteGroup } from '@shipfox/node-fastify';
2
+ export declare const triggersE2eRoutes: RouteGroup;
3
+ //# sourceMappingURL=e2e-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2e-routes.d.ts","sourceRoot":"","sources":["../../src/presentation/e2e-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAoBnE,eAAO,MAAM,iBAAiB,EAAE,UAG/B,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { defineRoute } from '@shipfox/node-fastify';
2
+ import { z } from 'zod';
3
+ import { hasJobListenerSubscriptions } from '#db/job-listener-subscriptions.js';
4
+ const listenerReadinessParamsSchema = z.object({
5
+ jobId: z.string().uuid()
6
+ });
7
+ const listenerReadinessResponseSchema = z.object({
8
+ ready: z.boolean()
9
+ });
10
+ const listenerReadinessRoute = defineRoute({
11
+ method: 'GET',
12
+ path: '/listeners/:jobId/readiness',
13
+ description: 'Report whether trigger subscriptions for a listener job are ready in E2E tests.',
14
+ schema: {
15
+ params: listenerReadinessParamsSchema,
16
+ response: {
17
+ 200: listenerReadinessResponseSchema
18
+ }
19
+ },
20
+ handler: async (request)=>({
21
+ ready: await hasJobListenerSubscriptions(request.params.jobId)
22
+ })
23
+ });
24
+ export const triggersE2eRoutes = {
25
+ prefix: '/triggers',
26
+ routes: [
27
+ listenerReadinessRoute
28
+ ]
29
+ };
30
+
31
+ //# sourceMappingURL=e2e-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/presentation/e2e-routes.ts"],"sourcesContent":["import {defineRoute, type RouteGroup} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {hasJobListenerSubscriptions} from '#db/job-listener-subscriptions.js';\n\nconst listenerReadinessParamsSchema = z.object({jobId: z.string().uuid()});\nconst listenerReadinessResponseSchema = z.object({ready: z.boolean()});\n\nconst listenerReadinessRoute = defineRoute({\n method: 'GET',\n path: '/listeners/:jobId/readiness',\n description: 'Report whether trigger subscriptions for a listener job are ready in E2E tests.',\n schema: {\n params: listenerReadinessParamsSchema,\n response: {200: listenerReadinessResponseSchema},\n },\n handler: async (request) => ({\n ready: await hasJobListenerSubscriptions(request.params.jobId),\n }),\n});\n\nexport const triggersE2eRoutes: RouteGroup = {\n prefix: '/triggers',\n routes: [listenerReadinessRoute],\n};\n"],"names":["defineRoute","z","hasJobListenerSubscriptions","listenerReadinessParamsSchema","object","jobId","string","uuid","listenerReadinessResponseSchema","ready","boolean","listenerReadinessRoute","method","path","description","schema","params","response","handler","request","triggersE2eRoutes","prefix","routes"],"mappings":"AAAA,SAAQA,WAAW,QAAwB,wBAAwB;AACnE,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,2BAA2B,QAAO,oCAAoC;AAE9E,MAAMC,gCAAgCF,EAAEG,MAAM,CAAC;IAACC,OAAOJ,EAAEK,MAAM,GAAGC,IAAI;AAAE;AACxE,MAAMC,kCAAkCP,EAAEG,MAAM,CAAC;IAACK,OAAOR,EAAES,OAAO;AAAE;AAEpE,MAAMC,yBAAyBX,YAAY;IACzCY,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,QAAQb;QACRc,UAAU;YAAC,KAAKT;QAA+B;IACjD;IACAU,SAAS,OAAOC,UAAa,CAAA;YAC3BV,OAAO,MAAMP,4BAA4BiB,QAAQH,MAAM,CAACX,KAAK;QAC/D,CAAA;AACF;AAEA,OAAO,MAAMe,oBAAgC;IAC3CC,QAAQ;IACRC,QAAQ;QAACX;KAAuB;AAClC,EAAE"}
@@ -1,3 +1,3 @@
1
- export { triggerRoutes as routes } from './routes/index.js';
2
- export { onDefinitionDeleted, onDefinitionResolved, onIntegrationEventReceived, } from './subscribers/index.js';
1
+ export { createTriggerRoutes } from './routes/index.js';
2
+ export { createOnIntegrationEventReceived, onDefinitionDeleted, onDefinitionResolved, } from './subscribers/index.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presentation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,IAAI,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presentation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AACtD,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC"}
@@ -1,4 +1,4 @@
1
- export { triggerRoutes as routes } from './routes/index.js';
2
- export { onDefinitionDeleted, onDefinitionResolved, onIntegrationEventReceived } from './subscribers/index.js';
1
+ export { createTriggerRoutes } from './routes/index.js';
2
+ export { createOnIntegrationEventReceived, onDefinitionDeleted, onDefinitionResolved } from './subscribers/index.js';
3
3
 
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/presentation/index.ts"],"sourcesContent":["export {triggerRoutes as routes} from './routes/index.js';\nexport {\n onDefinitionDeleted,\n onDefinitionResolved,\n onIntegrationEventReceived,\n} from './subscribers/index.js';\n"],"names":["triggerRoutes","routes","onDefinitionDeleted","onDefinitionResolved","onIntegrationEventReceived"],"mappings":"AAAA,SAAQA,iBAAiBC,MAAM,QAAO,oBAAoB;AAC1D,SACEC,mBAAmB,EACnBC,oBAAoB,EACpBC,0BAA0B,QACrB,yBAAyB"}
1
+ {"version":3,"sources":["../../src/presentation/index.ts"],"sourcesContent":["export {createTriggerRoutes} from './routes/index.js';\nexport {\n createOnIntegrationEventReceived,\n onDefinitionDeleted,\n onDefinitionResolved,\n} from './subscribers/index.js';\n"],"names":["createTriggerRoutes","createOnIntegrationEventReceived","onDefinitionDeleted","onDefinitionResolved"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,oBAAoB;AACtD,SACEC,gCAAgC,EAChCC,mBAAmB,EACnBC,oBAAoB,QACf,yBAAyB"}
@@ -1,2 +1,3 @@
1
- export declare const fireManualTriggerRoute: import("@shipfox/node-fastify").RouteDefinition;
1
+ import type { WorkflowsModuleClient } from '@shipfox/api-workflows-dto/inter-module';
2
+ export declare function createFireManualTriggerRoute(workflows: WorkflowsModuleClient): import("@shipfox/node-fastify").RouteDefinition;
2
3
  //# sourceMappingURL=fire-manual.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fire-manual.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/fire-manual.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,sBAAsB,iDAyDjC,CAAC"}
1
+ {"version":3,"file":"fire-manual.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/fire-manual.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,yCAAyC,CAAC;AAQnF,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,qBAAqB,mDAgE5E"}
@@ -1,71 +1,74 @@
1
1
  import { requireUserContext } from '@shipfox/api-auth-context';
2
2
  import { fireManualTriggerBodySchema, fireManualTriggerResponseSchema } from '@shipfox/api-triggers-dto';
3
- import { InterpolationUnresolvableError } from '@shipfox/api-workflows';
4
3
  import { ClientError, defineRoute } from '@shipfox/node-fastify';
5
4
  import { z } from 'zod';
6
5
  import { ManualTriggerNotFoundError } from '#core/errors.js';
7
6
  import { fireManualSubscription } from '#core/fire-manual.js';
7
+ import { isInterpolationUnresolvableError } from '#core/workflows-client.js';
8
8
  import { getManualSubscriptionByDefinitionId } from '#db/subscriptions.js';
9
- export const fireManualTriggerRoute = defineRoute({
10
- method: 'POST',
11
- path: '/:definitionId/fire-manual',
12
- description: 'Fire the manual trigger of a workflow definition, creating a workflow run.',
13
- schema: {
14
- params: z.object({
15
- definitionId: z.string().uuid()
16
- }),
17
- body: fireManualTriggerBodySchema,
18
- response: {
19
- 201: fireManualTriggerResponseSchema,
20
- 422: z.object({
21
- code: z.string(),
22
- details: z.object({
23
- field: z.string(),
24
- source: z.string(),
25
- env_key: z.string().optional()
9
+ export function createFireManualTriggerRoute(workflows) {
10
+ return defineRoute({
11
+ method: 'POST',
12
+ path: '/:definitionId/fire-manual',
13
+ description: 'Fire the manual trigger of a workflow definition, creating a workflow run.',
14
+ schema: {
15
+ params: z.object({
16
+ definitionId: z.string().uuid()
17
+ }),
18
+ body: fireManualTriggerBodySchema,
19
+ response: {
20
+ 201: fireManualTriggerResponseSchema,
21
+ 422: z.object({
22
+ code: z.string(),
23
+ details: z.object({
24
+ field: z.string(),
25
+ source: z.string(),
26
+ env_key: z.string().optional()
27
+ })
26
28
  })
27
- })
28
- }
29
- },
30
- errorHandler: (error)=>{
31
- if (error instanceof ManualTriggerNotFoundError) {
32
- throw new ClientError(error.message, 'manual-trigger-not-found', {
33
- status: 404
34
- });
35
- }
36
- if (error instanceof InterpolationUnresolvableError) {
37
- throw new ClientError(error.message, 'workflow-interpolation-unresolvable', {
38
- status: 422,
39
- details: {
40
- field: error.field,
41
- source: error.source,
42
- ...error.envKey === undefined ? {} : {
43
- env_key: error.envKey
29
+ }
30
+ },
31
+ errorHandler: (error)=>{
32
+ if (error instanceof ManualTriggerNotFoundError) {
33
+ throw new ClientError(error.message, 'manual-trigger-not-found', {
34
+ status: 404
35
+ });
36
+ }
37
+ if (isInterpolationUnresolvableError(error)) {
38
+ throw new ClientError('Workflow interpolation cannot be resolved', 'workflow-interpolation-unresolvable', {
39
+ status: 422,
40
+ details: {
41
+ field: error.details.field,
42
+ source: error.details.source,
43
+ ...error.details.envKey === undefined ? {} : {
44
+ env_key: error.details.envKey
45
+ }
44
46
  }
45
- }
47
+ });
48
+ }
49
+ throw error;
50
+ },
51
+ handler: async (request, reply)=>{
52
+ const { definitionId } = request.params;
53
+ const userContext = requireUserContext(request);
54
+ const subscription = await getManualSubscriptionByDefinitionId(definitionId);
55
+ // 404 covers both "no such manual trigger" and "not your workspace" to avoid leaking existence.
56
+ if (!subscription || !userContext.canAccess(subscription.workspaceId)) {
57
+ throw new ManualTriggerNotFoundError(definitionId);
58
+ }
59
+ const run = await fireManualSubscription({
60
+ workflows,
61
+ subscriptionId: subscription.id,
62
+ callerWorkspaceId: subscription.workspaceId,
63
+ userId: userContext.userId,
64
+ inputs: request.body.inputs
46
65
  });
66
+ reply.status(201);
67
+ return {
68
+ workflow_run_id: run.id
69
+ };
47
70
  }
48
- throw error;
49
- },
50
- handler: async (request, reply)=>{
51
- const { definitionId } = request.params;
52
- const userContext = requireUserContext(request);
53
- const subscription = await getManualSubscriptionByDefinitionId(definitionId);
54
- // 404 covers both "no such manual trigger" and "not your workspace" to avoid leaking existence.
55
- if (!subscription || !userContext.canAccess(subscription.workspaceId)) {
56
- throw new ManualTriggerNotFoundError(definitionId);
57
- }
58
- const run = await fireManualSubscription({
59
- subscriptionId: subscription.id,
60
- callerWorkspaceId: subscription.workspaceId,
61
- userId: userContext.userId,
62
- inputs: request.body.inputs
63
- });
64
- reply.status(201);
65
- return {
66
- workflow_run_id: run.id
67
- };
68
- }
69
- });
71
+ });
72
+ }
70
73
 
71
74
  //# sourceMappingURL=fire-manual.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/presentation/routes/fire-manual.ts"],"sourcesContent":["import {requireUserContext} from '@shipfox/api-auth-context';\nimport {\n fireManualTriggerBodySchema,\n fireManualTriggerResponseSchema,\n} from '@shipfox/api-triggers-dto';\nimport {InterpolationUnresolvableError} from '@shipfox/api-workflows';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {ManualTriggerNotFoundError} from '#core/errors.js';\nimport {fireManualSubscription} from '#core/fire-manual.js';\nimport {getManualSubscriptionByDefinitionId} from '#db/subscriptions.js';\n\nexport const fireManualTriggerRoute = defineRoute({\n method: 'POST',\n path: '/:definitionId/fire-manual',\n description: 'Fire the manual trigger of a workflow definition, creating a workflow run.',\n schema: {\n params: z.object({\n definitionId: z.string().uuid(),\n }),\n body: fireManualTriggerBodySchema,\n response: {\n 201: fireManualTriggerResponseSchema,\n 422: z.object({\n code: z.string(),\n details: z.object({\n field: z.string(),\n source: z.string(),\n env_key: z.string().optional(),\n }),\n }),\n },\n },\n errorHandler: (error) => {\n if (error instanceof ManualTriggerNotFoundError) {\n throw new ClientError(error.message, 'manual-trigger-not-found', {status: 404});\n }\n if (error instanceof InterpolationUnresolvableError) {\n throw new ClientError(error.message, 'workflow-interpolation-unresolvable', {\n status: 422,\n details: {\n field: error.field,\n source: error.source,\n ...(error.envKey === undefined ? {} : {env_key: error.envKey}),\n },\n });\n }\n throw error;\n },\n handler: async (request, reply) => {\n const {definitionId} = request.params;\n const userContext = requireUserContext(request);\n\n const subscription = await getManualSubscriptionByDefinitionId(definitionId);\n // 404 covers both \"no such manual trigger\" and \"not your workspace\" to avoid leaking existence.\n if (!subscription || !userContext.canAccess(subscription.workspaceId)) {\n throw new ManualTriggerNotFoundError(definitionId);\n }\n\n const run = await fireManualSubscription({\n subscriptionId: subscription.id,\n callerWorkspaceId: subscription.workspaceId,\n userId: userContext.userId,\n inputs: request.body.inputs,\n });\n\n reply.status(201);\n return {workflow_run_id: run.id};\n },\n});\n"],"names":["requireUserContext","fireManualTriggerBodySchema","fireManualTriggerResponseSchema","InterpolationUnresolvableError","ClientError","defineRoute","z","ManualTriggerNotFoundError","fireManualSubscription","getManualSubscriptionByDefinitionId","fireManualTriggerRoute","method","path","description","schema","params","object","definitionId","string","uuid","body","response","code","details","field","source","env_key","optional","errorHandler","error","message","status","envKey","undefined","handler","request","reply","userContext","subscription","canAccess","workspaceId","run","subscriptionId","id","callerWorkspaceId","userId","inputs","workflow_run_id"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,4BAA4B;AAC7D,SACEC,2BAA2B,EAC3BC,+BAA+B,QAC1B,4BAA4B;AACnC,SAAQC,8BAA8B,QAAO,yBAAyB;AACtE,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,0BAA0B,QAAO,kBAAkB;AAC3D,SAAQC,sBAAsB,QAAO,uBAAuB;AAC5D,SAAQC,mCAAmC,QAAO,uBAAuB;AAEzE,OAAO,MAAMC,yBAAyBL,YAAY;IAChDM,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,QAAQT,EAAEU,MAAM,CAAC;YACfC,cAAcX,EAAEY,MAAM,GAAGC,IAAI;QAC/B;QACAC,MAAMnB;QACNoB,UAAU;YACR,KAAKnB;YACL,KAAKI,EAAEU,MAAM,CAAC;gBACZM,MAAMhB,EAAEY,MAAM;gBACdK,SAASjB,EAAEU,MAAM,CAAC;oBAChBQ,OAAOlB,EAAEY,MAAM;oBACfO,QAAQnB,EAAEY,MAAM;oBAChBQ,SAASpB,EAAEY,MAAM,GAAGS,QAAQ;gBAC9B;YACF;QACF;IACF;IACAC,cAAc,CAACC;QACb,IAAIA,iBAAiBtB,4BAA4B;YAC/C,MAAM,IAAIH,YAAYyB,MAAMC,OAAO,EAAE,4BAA4B;gBAACC,QAAQ;YAAG;QAC/E;QACA,IAAIF,iBAAiB1B,gCAAgC;YACnD,MAAM,IAAIC,YAAYyB,MAAMC,OAAO,EAAE,uCAAuC;gBAC1EC,QAAQ;gBACRR,SAAS;oBACPC,OAAOK,MAAML,KAAK;oBAClBC,QAAQI,MAAMJ,MAAM;oBACpB,GAAII,MAAMG,MAAM,KAAKC,YAAY,CAAC,IAAI;wBAACP,SAASG,MAAMG,MAAM;oBAAA,CAAC;gBAC/D;YACF;QACF;QACA,MAAMH;IACR;IACAK,SAAS,OAAOC,SAASC;QACvB,MAAM,EAACnB,YAAY,EAAC,GAAGkB,QAAQpB,MAAM;QACrC,MAAMsB,cAAcrC,mBAAmBmC;QAEvC,MAAMG,eAAe,MAAM7B,oCAAoCQ;QAC/D,gGAAgG;QAChG,IAAI,CAACqB,gBAAgB,CAACD,YAAYE,SAAS,CAACD,aAAaE,WAAW,GAAG;YACrE,MAAM,IAAIjC,2BAA2BU;QACvC;QAEA,MAAMwB,MAAM,MAAMjC,uBAAuB;YACvCkC,gBAAgBJ,aAAaK,EAAE;YAC/BC,mBAAmBN,aAAaE,WAAW;YAC3CK,QAAQR,YAAYQ,MAAM;YAC1BC,QAAQX,QAAQf,IAAI,CAAC0B,MAAM;QAC7B;QAEAV,MAAML,MAAM,CAAC;QACb,OAAO;YAACgB,iBAAiBN,IAAIE,EAAE;QAAA;IACjC;AACF,GAAG"}
1
+ {"version":3,"sources":["../../../src/presentation/routes/fire-manual.ts"],"sourcesContent":["import {requireUserContext} from '@shipfox/api-auth-context';\nimport {\n fireManualTriggerBodySchema,\n fireManualTriggerResponseSchema,\n} from '@shipfox/api-triggers-dto';\nimport type {WorkflowsModuleClient} from '@shipfox/api-workflows-dto/inter-module';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {ManualTriggerNotFoundError} from '#core/errors.js';\nimport {fireManualSubscription} from '#core/fire-manual.js';\nimport {isInterpolationUnresolvableError} from '#core/workflows-client.js';\nimport {getManualSubscriptionByDefinitionId} from '#db/subscriptions.js';\n\nexport function createFireManualTriggerRoute(workflows: WorkflowsModuleClient) {\n return defineRoute({\n method: 'POST',\n path: '/:definitionId/fire-manual',\n description: 'Fire the manual trigger of a workflow definition, creating a workflow run.',\n schema: {\n params: z.object({\n definitionId: z.string().uuid(),\n }),\n body: fireManualTriggerBodySchema,\n response: {\n 201: fireManualTriggerResponseSchema,\n 422: z.object({\n code: z.string(),\n details: z.object({\n field: z.string(),\n source: z.string(),\n env_key: z.string().optional(),\n }),\n }),\n },\n },\n errorHandler: (error) => {\n if (error instanceof ManualTriggerNotFoundError) {\n throw new ClientError(error.message, 'manual-trigger-not-found', {status: 404});\n }\n if (isInterpolationUnresolvableError(error)) {\n throw new ClientError(\n 'Workflow interpolation cannot be resolved',\n 'workflow-interpolation-unresolvable',\n {\n status: 422,\n details: {\n field: error.details.field,\n source: error.details.source,\n ...(error.details.envKey === undefined ? {} : {env_key: error.details.envKey}),\n },\n },\n );\n }\n throw error;\n },\n handler: async (request, reply) => {\n const {definitionId} = request.params;\n const userContext = requireUserContext(request);\n\n const subscription = await getManualSubscriptionByDefinitionId(definitionId);\n // 404 covers both \"no such manual trigger\" and \"not your workspace\" to avoid leaking existence.\n if (!subscription || !userContext.canAccess(subscription.workspaceId)) {\n throw new ManualTriggerNotFoundError(definitionId);\n }\n\n const run = await fireManualSubscription({\n workflows,\n subscriptionId: subscription.id,\n callerWorkspaceId: subscription.workspaceId,\n userId: userContext.userId,\n inputs: request.body.inputs,\n });\n\n reply.status(201);\n return {workflow_run_id: run.id};\n },\n });\n}\n"],"names":["requireUserContext","fireManualTriggerBodySchema","fireManualTriggerResponseSchema","ClientError","defineRoute","z","ManualTriggerNotFoundError","fireManualSubscription","isInterpolationUnresolvableError","getManualSubscriptionByDefinitionId","createFireManualTriggerRoute","workflows","method","path","description","schema","params","object","definitionId","string","uuid","body","response","code","details","field","source","env_key","optional","errorHandler","error","message","status","envKey","undefined","handler","request","reply","userContext","subscription","canAccess","workspaceId","run","subscriptionId","id","callerWorkspaceId","userId","inputs","workflow_run_id"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,4BAA4B;AAC7D,SACEC,2BAA2B,EAC3BC,+BAA+B,QAC1B,4BAA4B;AAEnC,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,CAAC,QAAO,MAAM;AACtB,SAAQC,0BAA0B,QAAO,kBAAkB;AAC3D,SAAQC,sBAAsB,QAAO,uBAAuB;AAC5D,SAAQC,gCAAgC,QAAO,4BAA4B;AAC3E,SAAQC,mCAAmC,QAAO,uBAAuB;AAEzE,OAAO,SAASC,6BAA6BC,SAAgC;IAC3E,OAAOP,YAAY;QACjBQ,QAAQ;QACRC,MAAM;QACNC,aAAa;QACbC,QAAQ;YACNC,QAAQX,EAAEY,MAAM,CAAC;gBACfC,cAAcb,EAAEc,MAAM,GAAGC,IAAI;YAC/B;YACAC,MAAMpB;YACNqB,UAAU;gBACR,KAAKpB;gBACL,KAAKG,EAAEY,MAAM,CAAC;oBACZM,MAAMlB,EAAEc,MAAM;oBACdK,SAASnB,EAAEY,MAAM,CAAC;wBAChBQ,OAAOpB,EAAEc,MAAM;wBACfO,QAAQrB,EAAEc,MAAM;wBAChBQ,SAAStB,EAAEc,MAAM,GAAGS,QAAQ;oBAC9B;gBACF;YACF;QACF;QACAC,cAAc,CAACC;YACb,IAAIA,iBAAiBxB,4BAA4B;gBAC/C,MAAM,IAAIH,YAAY2B,MAAMC,OAAO,EAAE,4BAA4B;oBAACC,QAAQ;gBAAG;YAC/E;YACA,IAAIxB,iCAAiCsB,QAAQ;gBAC3C,MAAM,IAAI3B,YACR,6CACA,uCACA;oBACE6B,QAAQ;oBACRR,SAAS;wBACPC,OAAOK,MAAMN,OAAO,CAACC,KAAK;wBAC1BC,QAAQI,MAAMN,OAAO,CAACE,MAAM;wBAC5B,GAAII,MAAMN,OAAO,CAACS,MAAM,KAAKC,YAAY,CAAC,IAAI;4BAACP,SAASG,MAAMN,OAAO,CAACS,MAAM;wBAAA,CAAC;oBAC/E;gBACF;YAEJ;YACA,MAAMH;QACR;QACAK,SAAS,OAAOC,SAASC;YACvB,MAAM,EAACnB,YAAY,EAAC,GAAGkB,QAAQpB,MAAM;YACrC,MAAMsB,cAActC,mBAAmBoC;YAEvC,MAAMG,eAAe,MAAM9B,oCAAoCS;YAC/D,gGAAgG;YAChG,IAAI,CAACqB,gBAAgB,CAACD,YAAYE,SAAS,CAACD,aAAaE,WAAW,GAAG;gBACrE,MAAM,IAAInC,2BAA2BY;YACvC;YAEA,MAAMwB,MAAM,MAAMnC,uBAAuB;gBACvCI;gBACAgC,gBAAgBJ,aAAaK,EAAE;gBAC/BC,mBAAmBN,aAAaE,WAAW;gBAC3CK,QAAQR,YAAYQ,MAAM;gBAC1BC,QAAQX,QAAQf,IAAI,CAAC0B,MAAM;YAC7B;YAEAV,MAAML,MAAM,CAAC;YACb,OAAO;gBAACgB,iBAAiBN,IAAIE,EAAE;YAAA;QACjC;IACF;AACF"}