@shipfox/api-triggers 13.0.0 → 14.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 (129) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +14 -10
  4. package/dist/core/entities/decision.d.ts +3 -2
  5. package/dist/core/entities/decision.d.ts.map +1 -1
  6. package/dist/core/entities/decision.js.map +1 -1
  7. package/dist/core/entities/job-listener-subscription.d.ts +2 -1
  8. package/dist/core/entities/job-listener-subscription.d.ts.map +1 -1
  9. package/dist/core/entities/job-listener-subscription.js.map +1 -1
  10. package/dist/core/entities/received-event.d.ts +14 -1
  11. package/dist/core/entities/received-event.d.ts.map +1 -1
  12. package/dist/core/entities/received-event.js +2 -1
  13. package/dist/core/entities/received-event.js.map +1 -1
  14. package/dist/core/entities/subscription.d.ts +2 -1
  15. package/dist/core/entities/subscription.d.ts.map +1 -1
  16. package/dist/core/entities/subscription.js.map +1 -1
  17. package/dist/core/fire-cron.d.ts.map +1 -1
  18. package/dist/core/fire-cron.js +3 -1
  19. package/dist/core/fire-cron.js.map +1 -1
  20. package/dist/core/fire-manual.d.ts.map +1 -1
  21. package/dist/core/fire-manual.js +3 -1
  22. package/dist/core/fire-manual.js.map +1 -1
  23. package/dist/core/record-trigger-history.d.ts +2 -0
  24. package/dist/core/record-trigger-history.d.ts.map +1 -1
  25. package/dist/core/record-trigger-history.js +13 -1
  26. package/dist/core/record-trigger-history.js.map +1 -1
  27. package/dist/core/route-event-to-job-listeners.js +2 -0
  28. package/dist/core/route-event-to-job-listeners.js.map +1 -1
  29. package/dist/db/db.d.ts +48 -14
  30. package/dist/db/db.d.ts.map +1 -1
  31. package/dist/db/event-history.d.ts +17 -0
  32. package/dist/db/event-history.d.ts.map +1 -1
  33. package/dist/db/event-history.js +45 -1
  34. package/dist/db/event-history.js.map +1 -1
  35. package/dist/db/event-queries.d.ts +5 -1
  36. package/dist/db/event-queries.d.ts.map +1 -1
  37. package/dist/db/event-queries.js +30 -4
  38. package/dist/db/event-queries.js.map +1 -1
  39. package/dist/db/index.d.ts +1 -1
  40. package/dist/db/index.d.ts.map +1 -1
  41. package/dist/db/index.js +1 -1
  42. package/dist/db/index.js.map +1 -1
  43. package/dist/db/job-listener-subscriptions.d.ts +1 -1
  44. package/dist/db/job-listener-subscriptions.d.ts.map +1 -1
  45. package/dist/db/job-listener-subscriptions.js +10 -3
  46. package/dist/db/job-listener-subscriptions.js.map +1 -1
  47. package/dist/db/schema/decisions.d.ts +3 -3
  48. package/dist/db/schema/decisions.d.ts.map +1 -1
  49. package/dist/db/schema/decisions.js +8 -3
  50. package/dist/db/schema/decisions.js.map +1 -1
  51. package/dist/db/schema/job-listener-subscriptions.d.ts +1 -1
  52. package/dist/db/schema/job-listener-subscriptions.d.ts.map +1 -1
  53. package/dist/db/schema/job-listener-subscriptions.js +2 -1
  54. package/dist/db/schema/job-listener-subscriptions.js.map +1 -1
  55. package/dist/db/schema/received-events.d.ts +38 -4
  56. package/dist/db/schema/received-events.d.ts.map +1 -1
  57. package/dist/db/schema/received-events.js +11 -2
  58. package/dist/db/schema/received-events.js.map +1 -1
  59. package/dist/db/schema/subscriptions.d.ts +1 -1
  60. package/dist/db/schema/subscriptions.d.ts.map +1 -1
  61. package/dist/db/schema/subscriptions.js +2 -1
  62. package/dist/db/schema/subscriptions.js.map +1 -1
  63. package/dist/db/subscription-event.d.ts +7 -0
  64. package/dist/db/subscription-event.d.ts.map +1 -0
  65. package/dist/db/subscription-event.js +19 -0
  66. package/dist/db/subscription-event.js.map +1 -0
  67. package/dist/db/subscriptions.d.ts +5 -1
  68. package/dist/db/subscriptions.d.ts.map +1 -1
  69. package/dist/db/subscriptions.js +10 -3
  70. package/dist/db/subscriptions.js.map +1 -1
  71. package/dist/presentation/dto/trigger-events.d.ts +3 -2
  72. package/dist/presentation/dto/trigger-events.d.ts.map +1 -1
  73. package/dist/presentation/dto/trigger-events.js +9 -0
  74. package/dist/presentation/dto/trigger-events.js.map +1 -1
  75. package/dist/presentation/routes/get-trigger-event.d.ts.map +1 -1
  76. package/dist/presentation/routes/get-trigger-event.js +8 -4
  77. package/dist/presentation/routes/get-trigger-event.js.map +1 -1
  78. package/dist/presentation/routes/list-trigger-event-facets.js +1 -1
  79. package/dist/presentation/routes/list-trigger-event-facets.js.map +1 -1
  80. package/dist/presentation/routes/list-trigger-events.d.ts.map +1 -1
  81. package/dist/presentation/routes/list-trigger-events.js +3 -1
  82. package/dist/presentation/routes/list-trigger-events.js.map +1 -1
  83. package/dist/tsconfig.test.tsbuildinfo +1 -1
  84. package/drizzle/0001_nullable_subscription_events.sql +2 -0
  85. package/drizzle/0002_dev_trigger_journal.sql +7 -0
  86. package/drizzle/0003_add_origin_facet_index.sql +1 -0
  87. package/drizzle/meta/0001_snapshot.json +905 -0
  88. package/drizzle/meta/0002_snapshot.json +947 -0
  89. package/drizzle/meta/0003_snapshot.json +968 -0
  90. package/drizzle/meta/_journal.json +21 -0
  91. package/package.json +7 -7
  92. package/src/core/dispatch-integration-event.test.ts +88 -0
  93. package/src/core/entities/decision.ts +3 -2
  94. package/src/core/entities/job-listener-subscription.ts +2 -1
  95. package/src/core/entities/received-event.ts +15 -1
  96. package/src/core/entities/subscription.ts +2 -1
  97. package/src/core/fire-cron.test.ts +20 -0
  98. package/src/core/fire-cron.ts +3 -1
  99. package/src/core/fire-manual.test.ts +25 -0
  100. package/src/core/fire-manual.ts +3 -1
  101. package/src/core/record-trigger-history.test.ts +78 -0
  102. package/src/core/record-trigger-history.ts +19 -0
  103. package/src/core/route-event-to-job-listeners.test.ts +47 -0
  104. package/src/core/route-event-to-job-listeners.ts +2 -0
  105. package/src/db/event-history.test.ts +123 -0
  106. package/src/db/event-history.ts +84 -1
  107. package/src/db/event-queries.ts +56 -3
  108. package/src/db/index.ts +1 -0
  109. package/src/db/job-listener-subscriptions.test.ts +133 -1
  110. package/src/db/job-listener-subscriptions.ts +5 -4
  111. package/src/db/schema/decisions.test.ts +93 -4
  112. package/src/db/schema/decisions.ts +12 -3
  113. package/src/db/schema/job-listener-subscriptions.ts +2 -1
  114. package/src/db/schema/received-events.test.ts +45 -0
  115. package/src/db/schema/received-events.ts +12 -1
  116. package/src/db/schema/subscriptions.ts +2 -1
  117. package/src/db/subscription-event.ts +24 -0
  118. package/src/db/subscriptions.test.ts +137 -0
  119. package/src/db/subscriptions.ts +9 -4
  120. package/src/presentation/dto/trigger-events.test.ts +193 -0
  121. package/src/presentation/dto/trigger-events.ts +12 -0
  122. package/src/presentation/routes/get-trigger-event.test.ts +179 -0
  123. package/src/presentation/routes/get-trigger-event.ts +15 -3
  124. package/src/presentation/routes/list-trigger-event-facets.test.ts +39 -2
  125. package/src/presentation/routes/list-trigger-event-facets.ts +1 -1
  126. package/src/presentation/routes/list-trigger-events.test.ts +99 -0
  127. package/src/presentation/routes/list-trigger-events.ts +4 -0
  128. package/test/factories/received-event.ts +2 -0
  129. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,6 +1,7 @@
1
1
  import { and, eq, notInArray } from 'drizzle-orm';
2
2
  import { db } from './db.js';
3
3
  import { jobListenerSubscriptions, toJobListenerSubscription } from './schema/job-listener-subscriptions.js';
4
+ import { normalizeSubscriptionEvent, subscriptionEventCondition } from './subscription-event.js';
4
5
  export async function projectJobListenerSubscriptions(params) {
5
6
  await db().transaction(async (tx)=>{
6
7
  await pruneStaleMatchers(tx, params.jobId, 'on', params.on ?? []);
@@ -30,7 +31,10 @@ export async function projectJobListenerSubscriptions(params) {
30
31
  kind,
31
32
  matcherOrdinal,
32
33
  source: matcher.source,
33
- event: matcher.event,
34
+ event: normalizeSubscriptionEvent({
35
+ source: matcher.source,
36
+ event: matcher.event
37
+ }),
34
38
  config
35
39
  }).onConflictDoUpdate({
36
40
  target: [
@@ -42,7 +46,10 @@ export async function projectJobListenerSubscriptions(params) {
42
46
  workspaceId: params.workspaceId,
43
47
  workflowRunId: params.workflowRunId,
44
48
  source: matcher.source,
45
- event: matcher.event,
49
+ event: normalizeSubscriptionEvent({
50
+ source: matcher.source,
51
+ event: matcher.event
52
+ }),
46
53
  config
47
54
  }
48
55
  });
@@ -65,7 +72,7 @@ export async function removeJobListenerSubscriptionsForJob(jobId) {
65
72
  return rows.length;
66
73
  }
67
74
  export async function findMatchingJobListenerSubscriptions(params) {
68
- const rows = await db().select().from(jobListenerSubscriptions).where(and(eq(jobListenerSubscriptions.workspaceId, params.workspaceId), eq(jobListenerSubscriptions.source, params.source), eq(jobListenerSubscriptions.event, params.event)));
75
+ const rows = await db().select().from(jobListenerSubscriptions).where(and(eq(jobListenerSubscriptions.workspaceId, params.workspaceId), eq(jobListenerSubscriptions.source, params.source), subscriptionEventCondition(jobListenerSubscriptions.event, params.event)));
69
76
  return rows.map(toJobListenerSubscription);
70
77
  }
71
78
  export async function hasJobListenerSubscriptions(jobId) {
@@ -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 filter_output_types?: 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 if (matcher.filter_output_types !== undefined) {\n config.filter_output_types = matcher.filter_output_types;\n }\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","filter_output_types","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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"}
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';\nimport {normalizeSubscriptionEvent, subscriptionEventCondition} from './subscription-event.js';\n\ntype Tx = Parameters<Parameters<ReturnType<typeof db>['transaction']>[0]>[0];\n\nexport interface ListenerMatcher {\n source: string;\n event?: string | undefined;\n inputs?: Readonly<Record<string, unknown>> | undefined;\n filter?: string | undefined;\n filter_snapshot?: Readonly<Record<string, unknown>> | undefined;\n filter_output_types?: 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 if (matcher.filter_output_types !== undefined) {\n config.filter_output_types = matcher.filter_output_types;\n }\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: normalizeSubscriptionEvent({source: matcher.source, 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: normalizeSubscriptionEvent({source: matcher.source, 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 subscriptionEventCondition(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","normalizeSubscriptionEvent","subscriptionEventCondition","projectJobListenerSubscriptions","params","transaction","tx","pruneStaleMatchers","jobId","on","until","kind","matchers","matcherOrdinal","matcher","entries","config","inputs","undefined","filter","filter_snapshot","filter_output_types","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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"}
@@ -42,14 +42,14 @@ export declare const triggersDecisions: import("drizzle-orm/pg-core").PgTableWit
42
42
  tableName: "decisions";
43
43
  dataType: "string";
44
44
  columnType: "PgText";
45
- data: "listener" | "trigger";
45
+ data: "dev" | "listener" | "trigger";
46
46
  driverParam: string;
47
47
  notNull: true;
48
48
  hasDefault: false;
49
49
  isPrimaryKey: false;
50
50
  isAutoincrement: false;
51
51
  hasRuntimeDefault: false;
52
- enumValues: ["trigger", "listener"];
52
+ enumValues: ["trigger", "listener", "dev"];
53
53
  baseColumn: never;
54
54
  identity: undefined;
55
55
  generated: undefined;
@@ -61,7 +61,7 @@ export declare const triggersDecisions: import("drizzle-orm/pg-core").PgTableWit
61
61
  columnType: "PgUUID";
62
62
  data: string;
63
63
  driverParam: string;
64
- notNull: true;
64
+ notNull: false;
65
65
  hasDefault: false;
66
66
  isPrimaryKey: false;
67
67
  isAutoincrement: false;
@@ -1 +1 @@
1
- {"version":3,"file":"decisions.d.ts","sourceRoot":"","sources":["../../../src/db/schema/decisions.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,eAAe,EAA0B,MAAM,4BAA4B,CAAC;AAOzF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC7B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAC;AAE5E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAmBzE"}
1
+ {"version":3,"file":"decisions.d.ts","sourceRoot":"","sources":["../../../src/db/schema/decisions.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,eAAe,EAA0B,MAAM,4BAA4B,CAAC;AAOzF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2C7B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAC;AAE5E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAmBzE"}
@@ -7,7 +7,8 @@ import { jobListenerMatcherKindEnum } from './job-listener-subscriptions.js';
7
7
  import { triggersReceivedEvents } from './received-events.js';
8
8
  const triggerDecisionSubscriptionKinds = [
9
9
  'trigger',
10
- 'listener'
10
+ 'listener',
11
+ 'dev'
11
12
  ];
12
13
  export const triggersDecisions = pgTable('decisions', {
13
14
  id: uuidv7PrimaryKey(),
@@ -17,7 +18,9 @@ export const triggersDecisions = pgTable('decisions', {
17
18
  subscriptionKind: text('subscription_kind', {
18
19
  enum: triggerDecisionSubscriptionKinds
19
20
  }).notNull(),
20
- subscriptionId: uuid('subscription_id').notNull(),
21
+ // Null for `dev` decisions: the partial dev index enforces one decision
22
+ // per received event.
23
+ subscriptionId: uuid('subscription_id'),
21
24
  subscriptionName: text('subscription_name').notNull(),
22
25
  workflowDefinitionId: uuid('workflow_definition_id'),
23
26
  projectId: uuid('project_id'),
@@ -36,8 +39,10 @@ export const triggersDecisions = pgTable('decisions', {
36
39
  }).notNull().defaultNow()
37
40
  }, (table)=>[
38
41
  uniqueIndex('triggers_decisions_event_subscription_unique').on(table.receivedEventId, table.subscriptionKind, table.subscriptionId),
42
+ uniqueIndex('triggers_decisions_dev_event_unique').on(table.receivedEventId).where(sql`${table.subscriptionKind} = 'dev'`),
39
43
  index('triggers_decisions_run_idx').on(table.runId),
40
- check('triggers_decisions_subscription_kind_ck', sql`${table.subscriptionKind} IN ('trigger', 'listener')`)
44
+ check('triggers_decisions_subscription_kind_ck', sql`${table.subscriptionKind} IN ('trigger', 'listener', 'dev')`),
45
+ check('triggers_decisions_subscription_id_ck', sql`(${table.subscriptionKind} = 'dev' AND ${table.subscriptionId} IS NULL) OR (${table.subscriptionKind} IN ('trigger', 'listener') AND ${table.subscriptionId} IS NOT NULL)`)
41
46
  ]);
42
47
  export function toTriggerDecision(row) {
43
48
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/schema/decisions.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {sql} from 'drizzle-orm';\nimport {check, index, integer, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport {type TriggerDecision, triggerDecisionOutcomes} from '#core/entities/decision.js';\nimport {pgTable} from './common.js';\nimport {jobListenerMatcherKindEnum} from './job-listener-subscriptions.js';\nimport {triggersReceivedEvents} from './received-events.js';\n\nconst triggerDecisionSubscriptionKinds = ['trigger', 'listener'] as const;\n\nexport const triggersDecisions = pgTable(\n 'decisions',\n {\n id: uuidv7PrimaryKey(),\n receivedEventId: uuid('received_event_id')\n .notNull()\n .references(() => triggersReceivedEvents.id, {onDelete: 'cascade'}),\n subscriptionKind: text('subscription_kind', {enum: triggerDecisionSubscriptionKinds}).notNull(),\n subscriptionId: uuid('subscription_id').notNull(),\n subscriptionName: text('subscription_name').notNull(),\n workflowDefinitionId: uuid('workflow_definition_id'),\n projectId: uuid('project_id'),\n workflowRunId: uuid('workflow_run_id'),\n jobId: uuid('job_id'),\n matcherKind: jobListenerMatcherKindEnum('matcher_kind'),\n matcherOrdinal: integer('matcher_ordinal'),\n decision: text('decision', {enum: triggerDecisionOutcomes}).notNull(),\n runId: uuid('run_id'),\n runName: text('run_name'),\n reason: text('reason'),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_decisions_event_subscription_unique').on(\n table.receivedEventId,\n table.subscriptionKind,\n table.subscriptionId,\n ),\n index('triggers_decisions_run_idx').on(table.runId),\n check(\n 'triggers_decisions_subscription_kind_ck',\n sql`${table.subscriptionKind} IN ('trigger', 'listener')`,\n ),\n ],\n);\n\nexport type TriggerDecisionDb = typeof triggersDecisions.$inferSelect;\nexport type TriggerDecisionInsertDb = typeof triggersDecisions.$inferInsert;\n\nexport function toTriggerDecision(row: TriggerDecisionDb): TriggerDecision {\n return {\n id: row.id,\n receivedEventId: row.receivedEventId,\n subscriptionKind: row.subscriptionKind,\n subscriptionId: row.subscriptionId,\n subscriptionName: row.subscriptionName,\n workflowDefinitionId: row.workflowDefinitionId,\n projectId: row.projectId,\n workflowRunId: row.workflowRunId,\n jobId: row.jobId,\n matcherKind: row.matcherKind,\n matcherOrdinal: row.matcherOrdinal,\n decision: toTriggerDecisionOutcome(row.decision),\n runId: row.runId,\n runName: row.runName,\n reason: row.reason,\n createdAt: row.createdAt,\n };\n}\n\nfunction toTriggerDecisionOutcome(decision: string): TriggerDecision['decision'] {\n if (decision === 'errored') return 'dispatch-error';\n if (decision === 'triggered' || decision === 'filter-error' || decision === 'dispatch-error') {\n return decision;\n }\n return 'dispatch-error';\n}\n"],"names":["uuidv7PrimaryKey","sql","check","index","integer","text","timestamp","uniqueIndex","uuid","triggerDecisionOutcomes","pgTable","jobListenerMatcherKindEnum","triggersReceivedEvents","triggerDecisionSubscriptionKinds","triggersDecisions","id","receivedEventId","notNull","references","onDelete","subscriptionKind","enum","subscriptionId","subscriptionName","workflowDefinitionId","projectId","workflowRunId","jobId","matcherKind","matcherOrdinal","decision","runId","runName","reason","createdAt","withTimezone","defaultNow","table","on","toTriggerDecision","row","toTriggerDecisionOutcome"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,GAAG,QAAO,cAAc;AAChC,SAAQC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAC9F,SAA8BC,uBAAuB,QAAO,6BAA6B;AACzF,SAAQC,OAAO,QAAO,cAAc;AACpC,SAAQC,0BAA0B,QAAO,kCAAkC;AAC3E,SAAQC,sBAAsB,QAAO,uBAAuB;AAE5D,MAAMC,mCAAmC;IAAC;IAAW;CAAW;AAEhE,OAAO,MAAMC,oBAAoBJ,QAC/B,aACA;IACEK,IAAIf;IACJgB,iBAAiBR,KAAK,qBACnBS,OAAO,GACPC,UAAU,CAAC,IAAMN,uBAAuBG,EAAE,EAAE;QAACI,UAAU;IAAS;IACnEC,kBAAkBf,KAAK,qBAAqB;QAACgB,MAAMR;IAAgC,GAAGI,OAAO;IAC7FK,gBAAgBd,KAAK,mBAAmBS,OAAO;IAC/CM,kBAAkBlB,KAAK,qBAAqBY,OAAO;IACnDO,sBAAsBhB,KAAK;IAC3BiB,WAAWjB,KAAK;IAChBkB,eAAelB,KAAK;IACpBmB,OAAOnB,KAAK;IACZoB,aAAajB,2BAA2B;IACxCkB,gBAAgBzB,QAAQ;IACxB0B,UAAUzB,KAAK,YAAY;QAACgB,MAAMZ;IAAuB,GAAGQ,OAAO;IACnEc,OAAOvB,KAAK;IACZwB,SAAS3B,KAAK;IACd4B,QAAQ5B,KAAK;IACb6B,WAAW5B,UAAU,cAAc;QAAC6B,cAAc;IAAI,GAAGlB,OAAO,GAAGmB,UAAU;AAC/E,GACA,CAACC,QAAU;QACT9B,YAAY,gDAAgD+B,EAAE,CAC5DD,MAAMrB,eAAe,EACrBqB,MAAMjB,gBAAgB,EACtBiB,MAAMf,cAAc;QAEtBnB,MAAM,8BAA8BmC,EAAE,CAACD,MAAMN,KAAK;QAClD7B,MACE,2CACAD,GAAG,CAAC,EAAEoC,MAAMjB,gBAAgB,CAAC,2BAA2B,CAAC;KAE5D,EACD;AAKF,OAAO,SAASmB,kBAAkBC,GAAsB;IACtD,OAAO;QACLzB,IAAIyB,IAAIzB,EAAE;QACVC,iBAAiBwB,IAAIxB,eAAe;QACpCI,kBAAkBoB,IAAIpB,gBAAgB;QACtCE,gBAAgBkB,IAAIlB,cAAc;QAClCC,kBAAkBiB,IAAIjB,gBAAgB;QACtCC,sBAAsBgB,IAAIhB,oBAAoB;QAC9CC,WAAWe,IAAIf,SAAS;QACxBC,eAAec,IAAId,aAAa;QAChCC,OAAOa,IAAIb,KAAK;QAChBC,aAAaY,IAAIZ,WAAW;QAC5BC,gBAAgBW,IAAIX,cAAc;QAClCC,UAAUW,yBAAyBD,IAAIV,QAAQ;QAC/CC,OAAOS,IAAIT,KAAK;QAChBC,SAASQ,IAAIR,OAAO;QACpBC,QAAQO,IAAIP,MAAM;QAClBC,WAAWM,IAAIN,SAAS;IAC1B;AACF;AAEA,SAASO,yBAAyBX,QAAgB;IAChD,IAAIA,aAAa,WAAW,OAAO;IACnC,IAAIA,aAAa,eAAeA,aAAa,kBAAkBA,aAAa,kBAAkB;QAC5F,OAAOA;IACT;IACA,OAAO;AACT"}
1
+ {"version":3,"sources":["../../../src/db/schema/decisions.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {sql} from 'drizzle-orm';\nimport {check, index, integer, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport {type TriggerDecision, triggerDecisionOutcomes} from '#core/entities/decision.js';\nimport {pgTable} from './common.js';\nimport {jobListenerMatcherKindEnum} from './job-listener-subscriptions.js';\nimport {triggersReceivedEvents} from './received-events.js';\n\nconst triggerDecisionSubscriptionKinds = ['trigger', 'listener', 'dev'] as const;\n\nexport const triggersDecisions = pgTable(\n 'decisions',\n {\n id: uuidv7PrimaryKey(),\n receivedEventId: uuid('received_event_id')\n .notNull()\n .references(() => triggersReceivedEvents.id, {onDelete: 'cascade'}),\n subscriptionKind: text('subscription_kind', {enum: triggerDecisionSubscriptionKinds}).notNull(),\n // Null for `dev` decisions: the partial dev index enforces one decision\n // per received event.\n subscriptionId: uuid('subscription_id'),\n subscriptionName: text('subscription_name').notNull(),\n workflowDefinitionId: uuid('workflow_definition_id'),\n projectId: uuid('project_id'),\n workflowRunId: uuid('workflow_run_id'),\n jobId: uuid('job_id'),\n matcherKind: jobListenerMatcherKindEnum('matcher_kind'),\n matcherOrdinal: integer('matcher_ordinal'),\n decision: text('decision', {enum: triggerDecisionOutcomes}).notNull(),\n runId: uuid('run_id'),\n runName: text('run_name'),\n reason: text('reason'),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_decisions_event_subscription_unique').on(\n table.receivedEventId,\n table.subscriptionKind,\n table.subscriptionId,\n ),\n uniqueIndex('triggers_decisions_dev_event_unique')\n .on(table.receivedEventId)\n .where(sql`${table.subscriptionKind} = 'dev'`),\n index('triggers_decisions_run_idx').on(table.runId),\n check(\n 'triggers_decisions_subscription_kind_ck',\n sql`${table.subscriptionKind} IN ('trigger', 'listener', 'dev')`,\n ),\n check(\n 'triggers_decisions_subscription_id_ck',\n sql`(${table.subscriptionKind} = 'dev' AND ${table.subscriptionId} IS NULL) OR (${table.subscriptionKind} IN ('trigger', 'listener') AND ${table.subscriptionId} IS NOT NULL)`,\n ),\n ],\n);\n\nexport type TriggerDecisionDb = typeof triggersDecisions.$inferSelect;\nexport type TriggerDecisionInsertDb = typeof triggersDecisions.$inferInsert;\n\nexport function toTriggerDecision(row: TriggerDecisionDb): TriggerDecision {\n return {\n id: row.id,\n receivedEventId: row.receivedEventId,\n subscriptionKind: row.subscriptionKind,\n subscriptionId: row.subscriptionId,\n subscriptionName: row.subscriptionName,\n workflowDefinitionId: row.workflowDefinitionId,\n projectId: row.projectId,\n workflowRunId: row.workflowRunId,\n jobId: row.jobId,\n matcherKind: row.matcherKind,\n matcherOrdinal: row.matcherOrdinal,\n decision: toTriggerDecisionOutcome(row.decision),\n runId: row.runId,\n runName: row.runName,\n reason: row.reason,\n createdAt: row.createdAt,\n };\n}\n\nfunction toTriggerDecisionOutcome(decision: string): TriggerDecision['decision'] {\n if (decision === 'errored') return 'dispatch-error';\n if (decision === 'triggered' || decision === 'filter-error' || decision === 'dispatch-error') {\n return decision;\n }\n return 'dispatch-error';\n}\n"],"names":["uuidv7PrimaryKey","sql","check","index","integer","text","timestamp","uniqueIndex","uuid","triggerDecisionOutcomes","pgTable","jobListenerMatcherKindEnum","triggersReceivedEvents","triggerDecisionSubscriptionKinds","triggersDecisions","id","receivedEventId","notNull","references","onDelete","subscriptionKind","enum","subscriptionId","subscriptionName","workflowDefinitionId","projectId","workflowRunId","jobId","matcherKind","matcherOrdinal","decision","runId","runName","reason","createdAt","withTimezone","defaultNow","table","on","where","toTriggerDecision","row","toTriggerDecisionOutcome"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,GAAG,QAAO,cAAc;AAChC,SAAQC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAC9F,SAA8BC,uBAAuB,QAAO,6BAA6B;AACzF,SAAQC,OAAO,QAAO,cAAc;AACpC,SAAQC,0BAA0B,QAAO,kCAAkC;AAC3E,SAAQC,sBAAsB,QAAO,uBAAuB;AAE5D,MAAMC,mCAAmC;IAAC;IAAW;IAAY;CAAM;AAEvE,OAAO,MAAMC,oBAAoBJ,QAC/B,aACA;IACEK,IAAIf;IACJgB,iBAAiBR,KAAK,qBACnBS,OAAO,GACPC,UAAU,CAAC,IAAMN,uBAAuBG,EAAE,EAAE;QAACI,UAAU;IAAS;IACnEC,kBAAkBf,KAAK,qBAAqB;QAACgB,MAAMR;IAAgC,GAAGI,OAAO;IAC7F,wEAAwE;IACxE,sBAAsB;IACtBK,gBAAgBd,KAAK;IACrBe,kBAAkBlB,KAAK,qBAAqBY,OAAO;IACnDO,sBAAsBhB,KAAK;IAC3BiB,WAAWjB,KAAK;IAChBkB,eAAelB,KAAK;IACpBmB,OAAOnB,KAAK;IACZoB,aAAajB,2BAA2B;IACxCkB,gBAAgBzB,QAAQ;IACxB0B,UAAUzB,KAAK,YAAY;QAACgB,MAAMZ;IAAuB,GAAGQ,OAAO;IACnEc,OAAOvB,KAAK;IACZwB,SAAS3B,KAAK;IACd4B,QAAQ5B,KAAK;IACb6B,WAAW5B,UAAU,cAAc;QAAC6B,cAAc;IAAI,GAAGlB,OAAO,GAAGmB,UAAU;AAC/E,GACA,CAACC,QAAU;QACT9B,YAAY,gDAAgD+B,EAAE,CAC5DD,MAAMrB,eAAe,EACrBqB,MAAMjB,gBAAgB,EACtBiB,MAAMf,cAAc;QAEtBf,YAAY,uCACT+B,EAAE,CAACD,MAAMrB,eAAe,EACxBuB,KAAK,CAACtC,GAAG,CAAC,EAAEoC,MAAMjB,gBAAgB,CAAC,QAAQ,CAAC;QAC/CjB,MAAM,8BAA8BmC,EAAE,CAACD,MAAMN,KAAK;QAClD7B,MACE,2CACAD,GAAG,CAAC,EAAEoC,MAAMjB,gBAAgB,CAAC,kCAAkC,CAAC;QAElElB,MACE,yCACAD,GAAG,CAAC,CAAC,EAAEoC,MAAMjB,gBAAgB,CAAC,aAAa,EAAEiB,MAAMf,cAAc,CAAC,cAAc,EAAEe,MAAMjB,gBAAgB,CAAC,gCAAgC,EAAEiB,MAAMf,cAAc,CAAC,aAAa,CAAC;KAEjL,EACD;AAKF,OAAO,SAASkB,kBAAkBC,GAAsB;IACtD,OAAO;QACL1B,IAAI0B,IAAI1B,EAAE;QACVC,iBAAiByB,IAAIzB,eAAe;QACpCI,kBAAkBqB,IAAIrB,gBAAgB;QACtCE,gBAAgBmB,IAAInB,cAAc;QAClCC,kBAAkBkB,IAAIlB,gBAAgB;QACtCC,sBAAsBiB,IAAIjB,oBAAoB;QAC9CC,WAAWgB,IAAIhB,SAAS;QACxBC,eAAee,IAAIf,aAAa;QAChCC,OAAOc,IAAId,KAAK;QAChBC,aAAaa,IAAIb,WAAW;QAC5BC,gBAAgBY,IAAIZ,cAAc;QAClCC,UAAUY,yBAAyBD,IAAIX,QAAQ;QAC/CC,OAAOU,IAAIV,KAAK;QAChBC,SAASS,IAAIT,OAAO;QACpBC,QAAQQ,IAAIR,MAAM;QAClBC,WAAWO,IAAIP,SAAS;IAC1B;AACF;AAEA,SAASQ,yBAAyBZ,QAAgB;IAChD,IAAIA,aAAa,WAAW,OAAO;IACnC,IAAIA,aAAa,eAAeA,aAAa,kBAAkBA,aAAa,kBAAkB;QAC5F,OAAOA;IACT;IACA,OAAO;AACT"}
@@ -130,7 +130,7 @@ export declare const jobListenerSubscriptions: import("drizzle-orm/pg-core").PgT
130
130
  columnType: "PgText";
131
131
  data: string;
132
132
  driverParam: string;
133
- notNull: true;
133
+ notNull: false;
134
134
  hasDefault: false;
135
135
  isPrimaryKey: false;
136
136
  isAutoincrement: false;
@@ -1 +1 @@
1
- {"version":3,"file":"job-listener-subscriptions.d.ts","sourceRoot":"","sources":["../../../src/db/schema/job-listener-subscriptions.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,6CAA6C,CAAC;AAGzF,eAAO,MAAM,0BAA0B,uDAGrC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BpC,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,OAAO,wBAAwB,CAAC,YAAY,CAAC;AACrF,MAAM,MAAM,+BAA+B,GAAG,OAAO,wBAAwB,CAAC,YAAY,CAAC;AAE3F,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,yBAAyB,GAAG,uBAAuB,CAajG"}
1
+ {"version":3,"file":"job-listener-subscriptions.d.ts","sourceRoot":"","sources":["../../../src/db/schema/job-listener-subscriptions.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,6CAA6C,CAAC;AAGzF,eAAO,MAAM,0BAA0B,uDAGrC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BpC,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,OAAO,wBAAwB,CAAC,YAAY,CAAC;AACrF,MAAM,MAAM,+BAA+B,GAAG,OAAO,wBAAwB,CAAC,YAAY,CAAC;AAE3F,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,yBAAyB,GAAG,uBAAuB,CAajG"}
@@ -13,7 +13,8 @@ export const jobListenerSubscriptions = pgTable('job_listener_subscriptions', {
13
13
  kind: jobListenerMatcherKindEnum('kind').notNull(),
14
14
  matcherOrdinal: integer('matcher_ordinal').notNull(),
15
15
  source: text('source').notNull(),
16
- event: text('event').notNull(),
16
+ // NULL is a source subscription: matches every event the source delivers.
17
+ event: text('event'),
17
18
  config: jsonb('config').notNull().$type(),
18
19
  createdAt: timestamp('created_at', {
19
20
  withTimezone: true
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/schema/job-listener-subscriptions.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {\n index,\n integer,\n jsonb,\n pgEnum,\n text,\n timestamp,\n uniqueIndex,\n uuid,\n} from 'drizzle-orm/pg-core';\nimport type {JobListenerSubscription} from '#core/entities/job-listener-subscription.js';\nimport {pgTable} from './common.js';\n\nexport const jobListenerMatcherKindEnum = pgEnum('triggers_job_listener_matcher_kind', [\n 'on',\n 'until',\n]);\n\nexport const jobListenerSubscriptions = pgTable(\n 'job_listener_subscriptions',\n {\n id: uuidv7PrimaryKey(),\n workspaceId: uuid('workspace_id').notNull(),\n workflowRunId: uuid('workflow_run_id').notNull(),\n jobId: uuid('job_id').notNull(),\n kind: jobListenerMatcherKindEnum('kind').notNull(),\n matcherOrdinal: integer('matcher_ordinal').notNull(),\n source: text('source').notNull(),\n event: text('event').notNull(),\n config: jsonb('config').notNull().$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_job_listener_subscriptions_job_kind_ordinal_unique').on(\n table.jobId,\n table.kind,\n table.matcherOrdinal,\n ),\n index('triggers_job_listener_subscriptions_match_idx').on(\n table.workspaceId,\n table.source,\n table.event,\n ),\n index('triggers_job_listener_subscriptions_job_idx').on(table.jobId),\n ],\n);\n\nexport type JobListenerSubscriptionDb = typeof jobListenerSubscriptions.$inferSelect;\nexport type JobListenerSubscriptionInsertDb = typeof jobListenerSubscriptions.$inferInsert;\n\nexport function toJobListenerSubscription(row: JobListenerSubscriptionDb): JobListenerSubscription {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n workflowRunId: row.workflowRunId,\n jobId: row.jobId,\n kind: row.kind,\n matcherOrdinal: row.matcherOrdinal,\n source: row.source,\n event: row.event,\n config: row.config,\n createdAt: row.createdAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","index","integer","jsonb","pgEnum","text","timestamp","uniqueIndex","uuid","pgTable","jobListenerMatcherKindEnum","jobListenerSubscriptions","id","workspaceId","notNull","workflowRunId","jobId","kind","matcherOrdinal","source","event","config","$type","createdAt","withTimezone","defaultNow","table","on","toJobListenerSubscription","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SACEC,KAAK,EACLC,OAAO,EACPC,KAAK,EACLC,MAAM,EACNC,IAAI,EACJC,SAAS,EACTC,WAAW,EACXC,IAAI,QACC,sBAAsB;AAE7B,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,6BAA6BN,OAAO,sCAAsC;IACrF;IACA;CACD,EAAE;AAEH,OAAO,MAAMO,2BAA2BF,QACtC,8BACA;IACEG,IAAIZ;IACJa,aAAaL,KAAK,gBAAgBM,OAAO;IACzCC,eAAeP,KAAK,mBAAmBM,OAAO;IAC9CE,OAAOR,KAAK,UAAUM,OAAO;IAC7BG,MAAMP,2BAA2B,QAAQI,OAAO;IAChDI,gBAAgBhB,QAAQ,mBAAmBY,OAAO;IAClDK,QAAQd,KAAK,UAAUS,OAAO;IAC9BM,OAAOf,KAAK,SAASS,OAAO;IAC5BO,QAAQlB,MAAM,UAAUW,OAAO,GAAGQ,KAAK;IACvCC,WAAWjB,UAAU,cAAc;QAACkB,cAAc;IAAI,GAAGV,OAAO,GAAGW,UAAU;AAC/E,GACA,CAACC,QAAU;QACTnB,YAAY,+DAA+DoB,EAAE,CAC3ED,MAAMV,KAAK,EACXU,MAAMT,IAAI,EACVS,MAAMR,cAAc;QAEtBjB,MAAM,iDAAiD0B,EAAE,CACvDD,MAAMb,WAAW,EACjBa,MAAMP,MAAM,EACZO,MAAMN,KAAK;QAEbnB,MAAM,+CAA+C0B,EAAE,CAACD,MAAMV,KAAK;KACpE,EACD;AAKF,OAAO,SAASY,0BAA0BC,GAA8B;IACtE,OAAO;QACLjB,IAAIiB,IAAIjB,EAAE;QACVC,aAAagB,IAAIhB,WAAW;QAC5BE,eAAec,IAAId,aAAa;QAChCC,OAAOa,IAAIb,KAAK;QAChBC,MAAMY,IAAIZ,IAAI;QACdC,gBAAgBW,IAAIX,cAAc;QAClCC,QAAQU,IAAIV,MAAM;QAClBC,OAAOS,IAAIT,KAAK;QAChBC,QAAQQ,IAAIR,MAAM;QAClBE,WAAWM,IAAIN,SAAS;IAC1B;AACF"}
1
+ {"version":3,"sources":["../../../src/db/schema/job-listener-subscriptions.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {\n index,\n integer,\n jsonb,\n pgEnum,\n text,\n timestamp,\n uniqueIndex,\n uuid,\n} from 'drizzle-orm/pg-core';\nimport type {JobListenerSubscription} from '#core/entities/job-listener-subscription.js';\nimport {pgTable} from './common.js';\n\nexport const jobListenerMatcherKindEnum = pgEnum('triggers_job_listener_matcher_kind', [\n 'on',\n 'until',\n]);\n\nexport const jobListenerSubscriptions = pgTable(\n 'job_listener_subscriptions',\n {\n id: uuidv7PrimaryKey(),\n workspaceId: uuid('workspace_id').notNull(),\n workflowRunId: uuid('workflow_run_id').notNull(),\n jobId: uuid('job_id').notNull(),\n kind: jobListenerMatcherKindEnum('kind').notNull(),\n matcherOrdinal: integer('matcher_ordinal').notNull(),\n source: text('source').notNull(),\n // NULL is a source subscription: matches every event the source delivers.\n event: text('event'),\n config: jsonb('config').notNull().$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_job_listener_subscriptions_job_kind_ordinal_unique').on(\n table.jobId,\n table.kind,\n table.matcherOrdinal,\n ),\n index('triggers_job_listener_subscriptions_match_idx').on(\n table.workspaceId,\n table.source,\n table.event,\n ),\n index('triggers_job_listener_subscriptions_job_idx').on(table.jobId),\n ],\n);\n\nexport type JobListenerSubscriptionDb = typeof jobListenerSubscriptions.$inferSelect;\nexport type JobListenerSubscriptionInsertDb = typeof jobListenerSubscriptions.$inferInsert;\n\nexport function toJobListenerSubscription(row: JobListenerSubscriptionDb): JobListenerSubscription {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n workflowRunId: row.workflowRunId,\n jobId: row.jobId,\n kind: row.kind,\n matcherOrdinal: row.matcherOrdinal,\n source: row.source,\n event: row.event,\n config: row.config,\n createdAt: row.createdAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","index","integer","jsonb","pgEnum","text","timestamp","uniqueIndex","uuid","pgTable","jobListenerMatcherKindEnum","jobListenerSubscriptions","id","workspaceId","notNull","workflowRunId","jobId","kind","matcherOrdinal","source","event","config","$type","createdAt","withTimezone","defaultNow","table","on","toJobListenerSubscription","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SACEC,KAAK,EACLC,OAAO,EACPC,KAAK,EACLC,MAAM,EACNC,IAAI,EACJC,SAAS,EACTC,WAAW,EACXC,IAAI,QACC,sBAAsB;AAE7B,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,6BAA6BN,OAAO,sCAAsC;IACrF;IACA;CACD,EAAE;AAEH,OAAO,MAAMO,2BAA2BF,QACtC,8BACA;IACEG,IAAIZ;IACJa,aAAaL,KAAK,gBAAgBM,OAAO;IACzCC,eAAeP,KAAK,mBAAmBM,OAAO;IAC9CE,OAAOR,KAAK,UAAUM,OAAO;IAC7BG,MAAMP,2BAA2B,QAAQI,OAAO;IAChDI,gBAAgBhB,QAAQ,mBAAmBY,OAAO;IAClDK,QAAQd,KAAK,UAAUS,OAAO;IAC9B,0EAA0E;IAC1EM,OAAOf,KAAK;IACZgB,QAAQlB,MAAM,UAAUW,OAAO,GAAGQ,KAAK;IACvCC,WAAWjB,UAAU,cAAc;QAACkB,cAAc;IAAI,GAAGV,OAAO,GAAGW,UAAU;AAC/E,GACA,CAACC,QAAU;QACTnB,YAAY,+DAA+DoB,EAAE,CAC3ED,MAAMV,KAAK,EACXU,MAAMT,IAAI,EACVS,MAAMR,cAAc;QAEtBjB,MAAM,iDAAiD0B,EAAE,CACvDD,MAAMb,WAAW,EACjBa,MAAMP,MAAM,EACZO,MAAMN,KAAK;QAEbnB,MAAM,+CAA+C0B,EAAE,CAACD,MAAMV,KAAK;KACpE,EACD;AAKF,OAAO,SAASY,0BAA0BC,GAA8B;IACtE,OAAO;QACLjB,IAAIiB,IAAIjB,EAAE;QACVC,aAAagB,IAAIhB,WAAW;QAC5BE,eAAec,IAAId,aAAa;QAChCC,OAAOa,IAAIb,KAAK;QAChBC,MAAMY,IAAIZ,IAAI;QACdC,gBAAgBW,IAAIX,cAAc;QAClCC,QAAQU,IAAIV,MAAM;QAClBC,OAAOS,IAAIT,KAAK;QAChBC,QAAQQ,IAAIR,MAAM;QAClBE,WAAWM,IAAIN,SAAS;IAC1B;AACF"}
@@ -42,14 +42,14 @@ export declare const triggersReceivedEvents: import("drizzle-orm/pg-core").PgTab
42
42
  tableName: "received_events";
43
43
  dataType: "string";
44
44
  columnType: "PgText";
45
- data: "cron" | "integration" | "manual";
45
+ data: "cron" | "dev" | "integration" | "manual";
46
46
  driverParam: string;
47
47
  notNull: true;
48
48
  hasDefault: false;
49
49
  isPrimaryKey: false;
50
50
  isAutoincrement: false;
51
51
  hasRuntimeDefault: false;
52
- enumValues: ["integration", "manual", "cron"];
52
+ enumValues: ["integration", "manual", "cron", "dev"];
53
53
  baseColumn: never;
54
54
  identity: undefined;
55
55
  generated: undefined;
@@ -122,6 +122,23 @@ export declare const triggersReceivedEvents: import("drizzle-orm/pg-core").PgTab
122
122
  identity: undefined;
123
123
  generated: undefined;
124
124
  }, {}, {}>;
125
+ replayOfEventId: import("drizzle-orm/pg-core").PgColumn<{
126
+ name: "replay_of_event_id";
127
+ tableName: "received_events";
128
+ dataType: "string";
129
+ columnType: "PgUUID";
130
+ data: string;
131
+ driverParam: string;
132
+ notNull: false;
133
+ hasDefault: false;
134
+ isPrimaryKey: false;
135
+ isAutoincrement: false;
136
+ hasRuntimeDefault: false;
137
+ enumValues: undefined;
138
+ baseColumn: never;
139
+ identity: undefined;
140
+ generated: undefined;
141
+ }, {}, {}>;
125
142
  deliveryId: import("drizzle-orm/pg-core").PgColumn<{
126
143
  name: "delivery_id";
127
144
  tableName: "received_events";
@@ -323,14 +340,14 @@ export declare const triggerReceivedEventSummaryColumns: {
323
340
  tableName: "received_events";
324
341
  dataType: "string";
325
342
  columnType: "PgText";
326
- data: "cron" | "integration" | "manual";
343
+ data: "cron" | "dev" | "integration" | "manual";
327
344
  driverParam: string;
328
345
  notNull: true;
329
346
  hasDefault: false;
330
347
  isPrimaryKey: false;
331
348
  isAutoincrement: false;
332
349
  hasRuntimeDefault: false;
333
- enumValues: ["integration", "manual", "cron"];
350
+ enumValues: ["integration", "manual", "cron", "dev"];
334
351
  baseColumn: never;
335
352
  identity: undefined;
336
353
  generated: undefined;
@@ -403,6 +420,23 @@ export declare const triggerReceivedEventSummaryColumns: {
403
420
  identity: undefined;
404
421
  generated: undefined;
405
422
  }, {}, {}>;
423
+ readonly replayOfEventId: import("drizzle-orm/pg-core").PgColumn<{
424
+ name: "replay_of_event_id";
425
+ tableName: "received_events";
426
+ dataType: "string";
427
+ columnType: "PgUUID";
428
+ data: string;
429
+ driverParam: string;
430
+ notNull: false;
431
+ hasDefault: false;
432
+ isPrimaryKey: false;
433
+ isAutoincrement: false;
434
+ hasRuntimeDefault: false;
435
+ enumValues: undefined;
436
+ baseColumn: never;
437
+ identity: undefined;
438
+ generated: undefined;
439
+ }, {}, {}>;
406
440
  readonly deliveryId: import("drizzle-orm/pg-core").PgColumn<{
407
441
  name: "delivery_id";
408
442
  tableName: "received_events";
@@ -1 +1 @@
1
- {"version":3,"file":"received-events.d.ts","sourceRoot":"","sources":["../../../src/db/schema/received-events.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAGjC,MAAM,kCAAkC,CAAC;AAG1C,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkClC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,sBAAsB,CAAC,YAAY,CAAC;AAChF,MAAM,MAAM,4BAA4B,GAAG,OAAO,sBAAsB,CAAC,YAAY,CAAC;AAEtF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,sBAAsB,GAAG,oBAAoB,CAmBxF;AAED,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBwB,CAAC;AAExE,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,GAC3C,2BAA2B,CAE7B"}
1
+ {"version":3,"file":"received-events.d.ts","sourceRoot":"","sources":["../../../src/db/schema/received-events.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAGjC,MAAM,kCAAkC,CAAC;AAG1C,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0ClC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,sBAAsB,CAAC,YAAY,CAAC;AAChF,MAAM,MAAM,4BAA4B,GAAG,OAAO,sBAAsB,CAAC,YAAY,CAAC;AAEtF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,sBAAsB,GAAG,oBAAoB,CAoBxF;AAED,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBwB,CAAC;AAExE,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,GAC3C,2BAA2B,CAE7B"}
@@ -1,4 +1,5 @@
1
1
  import { uuidv7PrimaryKey } from '@shipfox/node-drizzle';
2
+ import { sql } from 'drizzle-orm';
2
3
  import { index, integer, jsonb, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
3
4
  import { triggerEventOrigins, triggerEventOutcomes } from '#core/entities/received-event.js';
4
5
  import { pgTable } from './common.js';
@@ -15,6 +16,9 @@ export const triggersReceivedEvents = pgTable('received_events', {
15
16
  provider: text('provider'),
16
17
  source: text('source').notNull(),
17
18
  event: text('event').notNull(),
19
+ // Source event this entry replays (dev runs only); no foreign key: the
20
+ // source row may be pruned while its replay link must stay.
21
+ replayOfEventId: uuid('replay_of_event_id'),
18
22
  deliveryId: text('delivery_id'),
19
23
  connectionId: uuid('connection_id'),
20
24
  connectionName: text('connection_name'),
@@ -36,9 +40,12 @@ export const triggersReceivedEvents = pgTable('received_events', {
36
40
  uniqueIndex('triggers_received_events_event_ref_unique').on(table.eventRef),
37
41
  index('triggers_received_events_workspace_received_idx').on(table.workspaceId, table.receivedAt.desc()),
38
42
  index('triggers_received_events_prune_idx').on(table.createdAt),
39
- // Back the workspace-scoped facet group-by (distinct source / event values).
43
+ // Back the workspace-scoped facet group-by (distinct source / event / origin values).
40
44
  index('triggers_received_events_workspace_source_idx').on(table.workspaceId, table.source),
41
- index('triggers_received_events_workspace_event_idx').on(table.workspaceId, table.event)
45
+ index('triggers_received_events_workspace_event_idx').on(table.workspaceId, table.event),
46
+ index('triggers_received_events_workspace_origin_idx').on(table.workspaceId, table.origin),
47
+ // Back the replay link direction: which events replayed a given source event.
48
+ index('triggers_received_events_replay_of_event_id_idx').on(table.replayOfEventId).where(sql`${table.replayOfEventId} IS NOT NULL`)
42
49
  ]);
43
50
  export function toTriggerReceivedEvent(row) {
44
51
  return {
@@ -49,6 +56,7 @@ export function toTriggerReceivedEvent(row) {
49
56
  provider: row.provider,
50
57
  source: row.source,
51
58
  event: row.event,
59
+ replayOfEventId: row.replayOfEventId,
52
60
  deliveryId: row.deliveryId,
53
61
  connectionId: row.connectionId,
54
62
  connectionName: row.connectionName,
@@ -68,6 +76,7 @@ export const triggerReceivedEventSummaryColumns = {
68
76
  provider: triggersReceivedEvents.provider,
69
77
  source: triggersReceivedEvents.source,
70
78
  event: triggersReceivedEvents.event,
79
+ replayOfEventId: triggersReceivedEvents.replayOfEventId,
71
80
  deliveryId: triggersReceivedEvents.deliveryId,
72
81
  connectionId: triggersReceivedEvents.connectionId,
73
82
  connectionName: triggersReceivedEvents.connectionName,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/schema/received-events.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {index, integer, jsonb, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport {\n type TriggerReceivedEvent,\n type TriggerReceivedEventSummary,\n triggerEventOrigins,\n triggerEventOutcomes,\n} from '#core/entities/received-event.js';\nimport {pgTable} from './common.js';\n\nexport const triggersReceivedEvents = pgTable(\n 'received_events',\n {\n id: uuidv7PrimaryKey(),\n // Globally-unique idempotency key (the outbox event id), not the provider\n // delivery id: delivery ids are only unique per provider and would collide\n // across workspaces under the global event_ref unique index below.\n eventRef: text('event_ref').notNull(),\n origin: text('origin', {enum: triggerEventOrigins}).notNull(),\n workspaceId: uuid('workspace_id').notNull(),\n provider: text('provider'),\n source: text('source').notNull(),\n event: text('event').notNull(),\n deliveryId: text('delivery_id'),\n connectionId: uuid('connection_id'),\n connectionName: text('connection_name'),\n outcome: text('outcome', {enum: triggerEventOutcomes}).notNull().default('received'),\n matchedCount: integer('matched_count').notNull().default(0),\n payload: jsonb('payload').$type<Record<string, unknown>>(),\n receivedAt: timestamp('received_at', {withTimezone: true}).notNull(),\n processedAt: timestamp('processed_at', {withTimezone: true}),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_received_events_event_ref_unique').on(table.eventRef),\n index('triggers_received_events_workspace_received_idx').on(\n table.workspaceId,\n table.receivedAt.desc(),\n ),\n index('triggers_received_events_prune_idx').on(table.createdAt),\n // Back the workspace-scoped facet group-by (distinct source / event values).\n index('triggers_received_events_workspace_source_idx').on(table.workspaceId, table.source),\n index('triggers_received_events_workspace_event_idx').on(table.workspaceId, table.event),\n ],\n);\n\nexport type TriggerReceivedEventDb = typeof triggersReceivedEvents.$inferSelect;\nexport type TriggerReceivedEventInsertDb = typeof triggersReceivedEvents.$inferInsert;\n\nexport function toTriggerReceivedEvent(row: TriggerReceivedEventDb): TriggerReceivedEvent {\n return {\n id: row.id,\n eventRef: row.eventRef,\n origin: row.origin,\n workspaceId: row.workspaceId,\n provider: row.provider,\n source: row.source,\n event: row.event,\n deliveryId: row.deliveryId,\n connectionId: row.connectionId,\n connectionName: row.connectionName,\n outcome: row.outcome,\n matchedCount: row.matchedCount,\n payload: row.payload,\n receivedAt: row.receivedAt,\n processedAt: row.processedAt,\n createdAt: row.createdAt,\n };\n}\n\nexport const triggerReceivedEventSummaryColumns = {\n id: triggersReceivedEvents.id,\n eventRef: triggersReceivedEvents.eventRef,\n origin: triggersReceivedEvents.origin,\n workspaceId: triggersReceivedEvents.workspaceId,\n provider: triggersReceivedEvents.provider,\n source: triggersReceivedEvents.source,\n event: triggersReceivedEvents.event,\n deliveryId: triggersReceivedEvents.deliveryId,\n connectionId: triggersReceivedEvents.connectionId,\n connectionName: triggersReceivedEvents.connectionName,\n outcome: triggersReceivedEvents.outcome,\n matchedCount: triggersReceivedEvents.matchedCount,\n receivedAt: triggersReceivedEvents.receivedAt,\n processedAt: triggersReceivedEvents.processedAt,\n createdAt: triggersReceivedEvents.createdAt,\n} as const satisfies Record<keyof TriggerReceivedEventSummary, unknown>;\n\nexport function toTriggerReceivedEventSummary(\n row: Omit<TriggerReceivedEventDb, 'payload'>,\n): TriggerReceivedEventSummary {\n return {...row};\n}\n"],"names":["uuidv7PrimaryKey","index","integer","jsonb","text","timestamp","uniqueIndex","uuid","triggerEventOrigins","triggerEventOutcomes","pgTable","triggersReceivedEvents","id","eventRef","notNull","origin","enum","workspaceId","provider","source","event","deliveryId","connectionId","connectionName","outcome","default","matchedCount","payload","$type","receivedAt","withTimezone","processedAt","createdAt","defaultNow","table","on","desc","toTriggerReceivedEvent","row","triggerReceivedEventSummaryColumns","toTriggerReceivedEventSummary"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/db/schema/received-events.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {sql} from 'drizzle-orm';\nimport {index, integer, jsonb, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport {\n type TriggerReceivedEvent,\n type TriggerReceivedEventSummary,\n triggerEventOrigins,\n triggerEventOutcomes,\n} from '#core/entities/received-event.js';\nimport {pgTable} from './common.js';\n\nexport const triggersReceivedEvents = pgTable(\n 'received_events',\n {\n id: uuidv7PrimaryKey(),\n // Globally-unique idempotency key (the outbox event id), not the provider\n // delivery id: delivery ids are only unique per provider and would collide\n // across workspaces under the global event_ref unique index below.\n eventRef: text('event_ref').notNull(),\n origin: text('origin', {enum: triggerEventOrigins}).notNull(),\n workspaceId: uuid('workspace_id').notNull(),\n provider: text('provider'),\n source: text('source').notNull(),\n event: text('event').notNull(),\n // Source event this entry replays (dev runs only); no foreign key: the\n // source row may be pruned while its replay link must stay.\n replayOfEventId: uuid('replay_of_event_id'),\n deliveryId: text('delivery_id'),\n connectionId: uuid('connection_id'),\n connectionName: text('connection_name'),\n outcome: text('outcome', {enum: triggerEventOutcomes}).notNull().default('received'),\n matchedCount: integer('matched_count').notNull().default(0),\n payload: jsonb('payload').$type<Record<string, unknown>>(),\n receivedAt: timestamp('received_at', {withTimezone: true}).notNull(),\n processedAt: timestamp('processed_at', {withTimezone: true}),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_received_events_event_ref_unique').on(table.eventRef),\n index('triggers_received_events_workspace_received_idx').on(\n table.workspaceId,\n table.receivedAt.desc(),\n ),\n index('triggers_received_events_prune_idx').on(table.createdAt),\n // Back the workspace-scoped facet group-by (distinct source / event / origin values).\n index('triggers_received_events_workspace_source_idx').on(table.workspaceId, table.source),\n index('triggers_received_events_workspace_event_idx').on(table.workspaceId, table.event),\n index('triggers_received_events_workspace_origin_idx').on(table.workspaceId, table.origin),\n // Back the replay link direction: which events replayed a given source event.\n index('triggers_received_events_replay_of_event_id_idx')\n .on(table.replayOfEventId)\n .where(sql`${table.replayOfEventId} IS NOT NULL`),\n ],\n);\n\nexport type TriggerReceivedEventDb = typeof triggersReceivedEvents.$inferSelect;\nexport type TriggerReceivedEventInsertDb = typeof triggersReceivedEvents.$inferInsert;\n\nexport function toTriggerReceivedEvent(row: TriggerReceivedEventDb): TriggerReceivedEvent {\n return {\n id: row.id,\n eventRef: row.eventRef,\n origin: row.origin,\n workspaceId: row.workspaceId,\n provider: row.provider,\n source: row.source,\n event: row.event,\n replayOfEventId: row.replayOfEventId,\n deliveryId: row.deliveryId,\n connectionId: row.connectionId,\n connectionName: row.connectionName,\n outcome: row.outcome,\n matchedCount: row.matchedCount,\n payload: row.payload,\n receivedAt: row.receivedAt,\n processedAt: row.processedAt,\n createdAt: row.createdAt,\n };\n}\n\nexport const triggerReceivedEventSummaryColumns = {\n id: triggersReceivedEvents.id,\n eventRef: triggersReceivedEvents.eventRef,\n origin: triggersReceivedEvents.origin,\n workspaceId: triggersReceivedEvents.workspaceId,\n provider: triggersReceivedEvents.provider,\n source: triggersReceivedEvents.source,\n event: triggersReceivedEvents.event,\n replayOfEventId: triggersReceivedEvents.replayOfEventId,\n deliveryId: triggersReceivedEvents.deliveryId,\n connectionId: triggersReceivedEvents.connectionId,\n connectionName: triggersReceivedEvents.connectionName,\n outcome: triggersReceivedEvents.outcome,\n matchedCount: triggersReceivedEvents.matchedCount,\n receivedAt: triggersReceivedEvents.receivedAt,\n processedAt: triggersReceivedEvents.processedAt,\n createdAt: triggersReceivedEvents.createdAt,\n} as const satisfies Record<keyof TriggerReceivedEventSummary, unknown>;\n\nexport function toTriggerReceivedEventSummary(\n row: Omit<TriggerReceivedEventDb, 'payload'>,\n): TriggerReceivedEventSummary {\n return {...row};\n}\n"],"names":["uuidv7PrimaryKey","sql","index","integer","jsonb","text","timestamp","uniqueIndex","uuid","triggerEventOrigins","triggerEventOutcomes","pgTable","triggersReceivedEvents","id","eventRef","notNull","origin","enum","workspaceId","provider","source","event","replayOfEventId","deliveryId","connectionId","connectionName","outcome","default","matchedCount","payload","$type","receivedAt","withTimezone","processedAt","createdAt","defaultNow","table","on","desc","where","toTriggerReceivedEvent","row","triggerReceivedEventSummaryColumns","toTriggerReceivedEventSummary"],"mappings":"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"}
@@ -112,7 +112,7 @@ export declare const triggerSubscriptions: import("drizzle-orm/pg-core").PgTable
112
112
  columnType: "PgText";
113
113
  data: string;
114
114
  driverParam: string;
115
- notNull: true;
115
+ notNull: false;
116
116
  hasDefault: false;
117
117
  isPrimaryKey: false;
118
118
  isAutoincrement: false;
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../../src/db/schema/subscriptions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AAGxE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsBhC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,oBAAoB,CAAC,YAAY,CAAC;AAC7E,MAAM,MAAM,2BAA2B,GAAG,OAAO,oBAAoB,CAAC,YAAY,CAAC;AAEnF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,qBAAqB,GAAG,mBAAmB,CAarF"}
1
+ {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../../src/db/schema/subscriptions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AAGxE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBhC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,oBAAoB,CAAC,YAAY,CAAC;AAC7E,MAAM,MAAM,2BAA2B,GAAG,OAAO,oBAAoB,CAAC,YAAY,CAAC;AAEnF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,qBAAqB,GAAG,mBAAmB,CAarF"}
@@ -8,7 +8,8 @@ export const triggerSubscriptions = pgTable('subscriptions', {
8
8
  workflowDefinitionId: uuid('workflow_definition_id').notNull(),
9
9
  name: text('name').notNull(),
10
10
  source: text('source').notNull(),
11
- event: text('event').notNull(),
11
+ // NULL is a source subscription: matches every event the source delivers.
12
+ event: text('event'),
12
13
  config: jsonb('config').notNull(),
13
14
  createdAt: timestamp('created_at', {
14
15
  withTimezone: true
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/schema/subscriptions.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {index, jsonb, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {TriggerSubscription} from '#core/entities/subscription.js';\nimport {pgTable} from './common.js';\n\nexport const triggerSubscriptions = pgTable(\n 'subscriptions',\n {\n id: uuidv7PrimaryKey(),\n workspaceId: uuid('workspace_id').notNull(),\n projectId: uuid('project_id').notNull(),\n workflowDefinitionId: uuid('workflow_definition_id').notNull(),\n name: text('name').notNull(),\n source: text('source').notNull(),\n event: text('event').notNull(),\n config: jsonb('config').notNull(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_subscriptions_definition_name_unique').on(\n table.workflowDefinitionId,\n table.name,\n ),\n index('triggers_subscriptions_match_idx').on(table.workspaceId, table.source, table.event),\n index('triggers_subscriptions_definition_idx').on(table.workflowDefinitionId),\n ],\n);\n\nexport type TriggerSubscriptionDb = typeof triggerSubscriptions.$inferSelect;\nexport type TriggerSubscriptionInsertDb = typeof triggerSubscriptions.$inferInsert;\n\nexport function toTriggerSubscription(row: TriggerSubscriptionDb): TriggerSubscription {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n projectId: row.projectId,\n workflowDefinitionId: row.workflowDefinitionId,\n name: row.name,\n source: row.source,\n event: row.event,\n config: row.config as Record<string, unknown>,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","index","jsonb","text","timestamp","uniqueIndex","uuid","pgTable","triggerSubscriptions","id","workspaceId","notNull","projectId","workflowDefinitionId","name","source","event","config","createdAt","withTimezone","defaultNow","updatedAt","table","on","toTriggerSubscription","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,KAAK,EAAEC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAErF,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,uBAAuBD,QAClC,iBACA;IACEE,IAAIT;IACJU,aAAaJ,KAAK,gBAAgBK,OAAO;IACzCC,WAAWN,KAAK,cAAcK,OAAO;IACrCE,sBAAsBP,KAAK,0BAA0BK,OAAO;IAC5DG,MAAMX,KAAK,QAAQQ,OAAO;IAC1BI,QAAQZ,KAAK,UAAUQ,OAAO;IAC9BK,OAAOb,KAAK,SAASQ,OAAO;IAC5BM,QAAQf,MAAM,UAAUS,OAAO;IAC/BO,WAAWd,UAAU,cAAc;QAACe,cAAc;IAAI,GAAGR,OAAO,GAAGS,UAAU;IAC7EC,WAAWjB,UAAU,cAAc;QAACe,cAAc;IAAI,GAAGR,OAAO,GAAGS,UAAU;AAC/E,GACA,CAACE,QAAU;QACTjB,YAAY,iDAAiDkB,EAAE,CAC7DD,MAAMT,oBAAoB,EAC1BS,MAAMR,IAAI;QAEZb,MAAM,oCAAoCsB,EAAE,CAACD,MAAMZ,WAAW,EAAEY,MAAMP,MAAM,EAAEO,MAAMN,KAAK;QACzFf,MAAM,yCAAyCsB,EAAE,CAACD,MAAMT,oBAAoB;KAC7E,EACD;AAKF,OAAO,SAASW,sBAAsBC,GAA0B;IAC9D,OAAO;QACLhB,IAAIgB,IAAIhB,EAAE;QACVC,aAAae,IAAIf,WAAW;QAC5BE,WAAWa,IAAIb,SAAS;QACxBC,sBAAsBY,IAAIZ,oBAAoB;QAC9CC,MAAMW,IAAIX,IAAI;QACdC,QAAQU,IAAIV,MAAM;QAClBC,OAAOS,IAAIT,KAAK;QAChBC,QAAQQ,IAAIR,MAAM;QAClBC,WAAWO,IAAIP,SAAS;QACxBG,WAAWI,IAAIJ,SAAS;IAC1B;AACF"}
1
+ {"version":3,"sources":["../../../src/db/schema/subscriptions.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {index, jsonb, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {TriggerSubscription} from '#core/entities/subscription.js';\nimport {pgTable} from './common.js';\n\nexport const triggerSubscriptions = pgTable(\n 'subscriptions',\n {\n id: uuidv7PrimaryKey(),\n workspaceId: uuid('workspace_id').notNull(),\n projectId: uuid('project_id').notNull(),\n workflowDefinitionId: uuid('workflow_definition_id').notNull(),\n name: text('name').notNull(),\n source: text('source').notNull(),\n // NULL is a source subscription: matches every event the source delivers.\n event: text('event'),\n config: jsonb('config').notNull(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('triggers_subscriptions_definition_name_unique').on(\n table.workflowDefinitionId,\n table.name,\n ),\n index('triggers_subscriptions_match_idx').on(table.workspaceId, table.source, table.event),\n index('triggers_subscriptions_definition_idx').on(table.workflowDefinitionId),\n ],\n);\n\nexport type TriggerSubscriptionDb = typeof triggerSubscriptions.$inferSelect;\nexport type TriggerSubscriptionInsertDb = typeof triggerSubscriptions.$inferInsert;\n\nexport function toTriggerSubscription(row: TriggerSubscriptionDb): TriggerSubscription {\n return {\n id: row.id,\n workspaceId: row.workspaceId,\n projectId: row.projectId,\n workflowDefinitionId: row.workflowDefinitionId,\n name: row.name,\n source: row.source,\n event: row.event,\n config: row.config as Record<string, unknown>,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","index","jsonb","text","timestamp","uniqueIndex","uuid","pgTable","triggerSubscriptions","id","workspaceId","notNull","projectId","workflowDefinitionId","name","source","event","config","createdAt","withTimezone","defaultNow","updatedAt","table","on","toTriggerSubscription","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,KAAK,EAAEC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAErF,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,uBAAuBD,QAClC,iBACA;IACEE,IAAIT;IACJU,aAAaJ,KAAK,gBAAgBK,OAAO;IACzCC,WAAWN,KAAK,cAAcK,OAAO;IACrCE,sBAAsBP,KAAK,0BAA0BK,OAAO;IAC5DG,MAAMX,KAAK,QAAQQ,OAAO;IAC1BI,QAAQZ,KAAK,UAAUQ,OAAO;IAC9B,0EAA0E;IAC1EK,OAAOb,KAAK;IACZc,QAAQf,MAAM,UAAUS,OAAO;IAC/BO,WAAWd,UAAU,cAAc;QAACe,cAAc;IAAI,GAAGR,OAAO,GAAGS,UAAU;IAC7EC,WAAWjB,UAAU,cAAc;QAACe,cAAc;IAAI,GAAGR,OAAO,GAAGS,UAAU;AAC/E,GACA,CAACE,QAAU;QACTjB,YAAY,iDAAiDkB,EAAE,CAC7DD,MAAMT,oBAAoB,EAC1BS,MAAMR,IAAI;QAEZb,MAAM,oCAAoCsB,EAAE,CAACD,MAAMZ,WAAW,EAAEY,MAAMP,MAAM,EAAEO,MAAMN,KAAK;QACzFf,MAAM,yCAAyCsB,EAAE,CAACD,MAAMT,oBAAoB;KAC7E,EACD;AAKF,OAAO,SAASW,sBAAsBC,GAA0B;IAC9D,OAAO;QACLhB,IAAIgB,IAAIhB,EAAE;QACVC,aAAae,IAAIf,WAAW;QAC5BE,WAAWa,IAAIb,SAAS;QACxBC,sBAAsBY,IAAIZ,oBAAoB;QAC9CC,MAAMW,IAAIX,IAAI;QACdC,QAAQU,IAAIV,MAAM;QAClBC,OAAOS,IAAIT,KAAK;QAChBC,QAAQQ,IAAIR,MAAM;QAClBC,WAAWO,IAAIP,SAAS;QACxBG,WAAWI,IAAIJ,SAAS;IAC1B;AACF"}
@@ -0,0 +1,7 @@
1
+ import type { PgColumn } from 'drizzle-orm/pg-core';
2
+ export declare function normalizeSubscriptionEvent(params: {
3
+ source: string;
4
+ event: string | null | undefined;
5
+ }): string | null;
6
+ export declare function subscriptionEventCondition(column: PgColumn, event: string): import("drizzle-orm").SQL<unknown> | undefined;
7
+ //# sourceMappingURL=subscription-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-event.d.ts","sourceRoot":"","sources":["../../src/db/subscription-event.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAElD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAClC,GAAG,MAAM,GAAG,IAAI,CAahB;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,kDAEzE"}
@@ -0,0 +1,19 @@
1
+ import { eq, isNull, or } from 'drizzle-orm';
2
+ export function normalizeSubscriptionEvent(params) {
3
+ if (params.event === undefined || params.event === null) {
4
+ if (params.source === 'manual' || params.source === 'cron') {
5
+ throw new Error(`A ${params.source} subscription requires an event`);
6
+ }
7
+ return null;
8
+ }
9
+ const normalizedEvent = params.event.trim();
10
+ if (normalizedEvent === '') {
11
+ throw new Error(`A ${params.source} subscription event cannot be blank`);
12
+ }
13
+ return normalizedEvent;
14
+ }
15
+ export function subscriptionEventCondition(column, event) {
16
+ return or(eq(column, event), isNull(column));
17
+ }
18
+
19
+ //# sourceMappingURL=subscription-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/db/subscription-event.ts"],"sourcesContent":["import {eq, isNull, or} from 'drizzle-orm';\nimport type {PgColumn} from 'drizzle-orm/pg-core';\n\nexport function normalizeSubscriptionEvent(params: {\n source: string;\n event: string | null | undefined;\n}): string | null {\n if (params.event === undefined || params.event === null) {\n if (params.source === 'manual' || params.source === 'cron') {\n throw new Error(`A ${params.source} subscription requires an event`);\n }\n return null;\n }\n\n const normalizedEvent = params.event.trim();\n if (normalizedEvent === '') {\n throw new Error(`A ${params.source} subscription event cannot be blank`);\n }\n return normalizedEvent;\n}\n\nexport function subscriptionEventCondition(column: PgColumn, event: string) {\n return or(eq(column, event), isNull(column));\n}\n"],"names":["eq","isNull","or","normalizeSubscriptionEvent","params","event","undefined","source","Error","normalizedEvent","trim","subscriptionEventCondition","column"],"mappings":"AAAA,SAAQA,EAAE,EAAEC,MAAM,EAAEC,EAAE,QAAO,cAAc;AAG3C,OAAO,SAASC,2BAA2BC,MAG1C;IACC,IAAIA,OAAOC,KAAK,KAAKC,aAAaF,OAAOC,KAAK,KAAK,MAAM;QACvD,IAAID,OAAOG,MAAM,KAAK,YAAYH,OAAOG,MAAM,KAAK,QAAQ;YAC1D,MAAM,IAAIC,MAAM,CAAC,EAAE,EAAEJ,OAAOG,MAAM,CAAC,+BAA+B,CAAC;QACrE;QACA,OAAO;IACT;IAEA,MAAME,kBAAkBL,OAAOC,KAAK,CAACK,IAAI;IACzC,IAAID,oBAAoB,IAAI;QAC1B,MAAM,IAAID,MAAM,CAAC,EAAE,EAAEJ,OAAOG,MAAM,CAAC,mCAAmC,CAAC;IACzE;IACA,OAAOE;AACT;AAEA,OAAO,SAASE,2BAA2BC,MAAgB,EAAEP,KAAa;IACxE,OAAOH,GAAGF,GAAGY,QAAQP,QAAQJ,OAAOW;AACtC"}
@@ -1,12 +1,15 @@
1
1
  import type { TriggerDto } from '@shipfox/api-definitions-dto';
2
2
  import type { TriggerSubscription } from '#core/entities/subscription.js';
3
3
  import { type Tx } from './db.js';
4
+ interface ProjectDefinitionTrigger extends Omit<TriggerDto, 'event'> {
5
+ event?: string | undefined;
6
+ }
4
7
  export interface ProjectDefinitionTriggersParams {
5
8
  tx?: Tx | undefined;
6
9
  workspaceId: string;
7
10
  projectId: string;
8
11
  workflowDefinitionId: string;
9
- triggers: Record<string, TriggerDto>;
12
+ triggers: Record<string, ProjectDefinitionTrigger>;
10
13
  }
11
14
  export declare function projectDefinitionTriggers(params: ProjectDefinitionTriggersParams): Promise<void>;
12
15
  export interface DeleteSubscriptionsForDefinitionParams {
@@ -23,4 +26,5 @@ export interface FindMatchingSubscriptionsParams {
23
26
  }
24
27
  export declare function findMatchingSubscriptions(params: FindMatchingSubscriptionsParams): Promise<TriggerSubscription[]>;
25
28
  export declare function listSubscriptionsByWorkflowDefinitionIds(workflowDefinitionIds: string[]): Promise<TriggerSubscription[]>;
29
+ export {};
26
30
  //# sourceMappingURL=subscriptions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../src/db/subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,8BAA8B,CAAC;AAE7D,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AAExE,OAAO,EAAoB,KAAK,EAAE,EAAC,MAAM,SAAS,CAAC;AAGnD,MAAM,WAAW,+BAA+B;IAC9C,EAAE,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACtC;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED,MAAM,WAAW,sCAAsC;IACrD,EAAE,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,sCAAsC,GAC7C,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAS1C;AAED,wBAAsB,mCAAmC,CACvD,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAoB1C;AAED,MAAM,WAAW,+BAA+B;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAYhC;AAED,wBAAsB,wCAAwC,CAC5D,qBAAqB,EAAE,MAAM,EAAE,GAC9B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAOhC"}
1
+ {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../src/db/subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,8BAA8B,CAAC;AAE7D,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AAExE,OAAO,EAAoB,KAAK,EAAE,EAAC,MAAM,SAAS,CAAC;AAInD,UAAU,wBAAyB,SAAQ,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC;IAClE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,+BAA+B;IAC9C,EAAE,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACpD;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED,MAAM,WAAW,sCAAsC;IACrD,EAAE,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,sCAAsC,GAC7C,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAS1C;AAED,wBAAsB,mCAAmC,CACvD,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAoB1C;AAED,MAAM,WAAW,+BAA+B;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAYhC;AAED,wBAAsB,wCAAwC,CAC5D,qBAAqB,EAAE,MAAM,EAAE,GAC9B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAOhC"}
@@ -2,6 +2,7 @@ import { and, eq, inArray, notInArray } from 'drizzle-orm';
2
2
  import { deleteCronScheduleForSubscription, syncCronSchedule } from './cron-schedules.js';
3
3
  import { db } from './db.js';
4
4
  import { toTriggerSubscription, triggerSubscriptions } from './schema/subscriptions.js';
5
+ import { normalizeSubscriptionEvent, subscriptionEventCondition } from './subscription-event.js';
5
6
  export async function projectDefinitionTriggers(params) {
6
7
  const work = async (tx)=>{
7
8
  const entries = Object.entries(params.triggers);
@@ -21,7 +22,10 @@ export async function projectDefinitionTriggers(params) {
21
22
  workflowDefinitionId: params.workflowDefinitionId,
22
23
  name,
23
24
  source: trigger.source,
24
- event: trigger.event,
25
+ event: normalizeSubscriptionEvent({
26
+ source: trigger.source,
27
+ event: trigger.event
28
+ }),
25
29
  config
26
30
  }).onConflictDoUpdate({
27
31
  target: [
@@ -32,7 +36,10 @@ export async function projectDefinitionTriggers(params) {
32
36
  workspaceId: params.workspaceId,
33
37
  projectId: params.projectId,
34
38
  source: trigger.source,
35
- event: trigger.event,
39
+ event: normalizeSubscriptionEvent({
40
+ source: trigger.source,
41
+ event: trigger.event
42
+ }),
36
43
  config,
37
44
  updatedAt: new Date()
38
45
  }
@@ -91,7 +98,7 @@ export async function getManualSubscriptionByDefinitionId(workflowDefinitionId)
91
98
  // fact, not addressed to a project. Narrowing to a repo/project/branch is left to
92
99
  // user-defined per-workflow filters, not inferred here.
93
100
  export async function findMatchingSubscriptions(params) {
94
- const rows = await db().select().from(triggerSubscriptions).where(and(eq(triggerSubscriptions.workspaceId, params.workspaceId), eq(triggerSubscriptions.source, params.source), eq(triggerSubscriptions.event, params.event)));
101
+ const rows = await db().select().from(triggerSubscriptions).where(and(eq(triggerSubscriptions.workspaceId, params.workspaceId), eq(triggerSubscriptions.source, params.source), subscriptionEventCondition(triggerSubscriptions.event, params.event)));
95
102
  return rows.map(toTriggerSubscription);
96
103
  }
97
104
  export async function listSubscriptionsByWorkflowDefinitionIds(workflowDefinitionIds) {