@shipfox/api-triggers 12.1.0 → 12.2.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.
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +23 -0
- package/dist/core/entities/decision.d.ts +1 -1
- package/dist/core/entities/decision.d.ts.map +1 -1
- package/dist/core/entities/received-event.d.ts +2 -2
- package/dist/core/entities/received-event.d.ts.map +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/route-event-to-job-listeners.d.ts.map +1 -1
- package/dist/core/route-event-to-job-listeners.js +130 -13
- package/dist/core/route-event-to-job-listeners.js.map +1 -1
- package/dist/core/workflows-client.d.ts +12 -12
- package/dist/db/db.d.ts +20 -20
- package/dist/db/job-listener-subscriptions.d.ts +1 -0
- package/dist/db/job-listener-subscriptions.d.ts.map +1 -1
- package/dist/db/job-listener-subscriptions.js +3 -0
- package/dist/db/job-listener-subscriptions.js.map +1 -1
- package/dist/db/schema/cron-schedules.d.ts +1 -1
- package/dist/db/schema/decisions.d.ts +3 -3
- package/dist/db/schema/job-listener-subscriptions.d.ts +1 -1
- package/dist/db/schema/outbox.d.ts +1 -1
- package/dist/db/schema/received-events.d.ts +5 -5
- package/dist/db/schema/subscriptions.d.ts +1 -1
- package/dist/metrics/instance.d.ts +2 -2
- package/dist/presentation/subscribers/on-integration-event-received.d.ts.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/src/core/route-event-to-job-listeners.test.ts +97 -0
- package/src/core/route-event-to-job-listeners.ts +157 -11
- package/src/db/job-listener-subscriptions.test.ts +3 -0
- package/src/db/job-listener-subscriptions.ts +4 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
$ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
|
|
2
|
-
Successfully compiled: 58 files with swc (
|
|
3
|
-
2026-08-
|
|
2
|
+
Successfully compiled: 58 files with swc (414.39ms)
|
|
3
|
+
2026-08-06T13:12:28.900Z [INFO] asset workflow-bundle-69915b80080285c7230d.js 3.17 MiB [emitted] [immutable] (name: main)
|
|
4
4
|
orphan modules 33.5 KiB [orphan] 21 modules
|
|
5
5
|
runtime modules 1.13 KiB 5 modules
|
|
6
6
|
modules by path ../../../node_modules/.pnpm/ 970 KiB 196 modules
|
|
@@ -13,6 +13,6 @@ optional modules 30 bytes [optional]
|
|
|
13
13
|
__temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
14
14
|
__temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
15
15
|
../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
|
|
16
|
-
webpack 5.107.2 compiled successfully in
|
|
17
|
-
2026-08-
|
|
16
|
+
webpack 5.107.2 compiled successfully in 6889 ms
|
|
17
|
+
2026-08-06T13:12:28.918Z [INFO] Workflow bundle created { size: '3.17MB' }
|
|
18
18
|
/home/runner/work/shipfox/shipfox/libs/api/triggers/dist/temporal/workflows/index.js: 3329015 bytes
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @shipfox/api-triggers
|
|
2
2
|
|
|
3
|
+
## 12.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ce0984d: Preserve structured values when jobs map typed step outputs, normalize them for JSON persistence, and bound materialized job output sizes and entry counts.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 214b8f2: Expose execution and run numeric fields as CEL integers, preserve zero-based execution indices,
|
|
12
|
+
and keep listener filter snapshots aligned with live CEL values after persistence.
|
|
13
|
+
- Updated dependencies [7901a60]
|
|
14
|
+
- Updated dependencies [ce0984d]
|
|
15
|
+
- @shipfox/api-integration-core-dto@12.2.0
|
|
16
|
+
- @shipfox/expression@2.1.0
|
|
17
|
+
- @shipfox/api-workflows-dto@12.2.0
|
|
18
|
+
- @shipfox/workflow-document@3.0.1
|
|
19
|
+
- @shipfox/node-opentelemetry@0.6.4
|
|
20
|
+
- @shipfox/api-definitions-dto@12.2.0
|
|
21
|
+
- @shipfox/node-fastify@0.4.2
|
|
22
|
+
- @shipfox/node-module@1.0.6
|
|
23
|
+
- @shipfox/node-temporal@0.4.5
|
|
24
|
+
- @shipfox/api-auth-context@12.2.0
|
|
25
|
+
|
|
3
26
|
## 12.1.0
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { JobListenerMatcherKind } from './job-listener-subscription.js';
|
|
2
|
-
export declare const triggerDecisionOutcomes: readonly [
|
|
2
|
+
export declare const triggerDecisionOutcomes: readonly ['triggered', 'filter-error', 'dispatch-error'];
|
|
3
3
|
export type TriggerDecisionOutcome = (typeof triggerDecisionOutcomes)[number];
|
|
4
4
|
export type TriggerDecisionSubscriptionKind = 'trigger' | 'listener';
|
|
5
5
|
export interface TriggerDecision {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decision.d.ts","sourceRoot":"","sources":["../../../src/core/entities/decision.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"decision.d.ts","sourceRoot":"","sources":["../../../src/core/entities/decision.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,uBAAuB,YAAI,WAAW,EAAE,cAAc,EAAE,gBAAgB,CAAU,CAAC;AAChG,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC9E,MAAM,MAAM,+BAA+B,GAAG,SAAS,GAAG,UAAU,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,+BAA+B,CAAC;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC3C,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,sBAAsB,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;CACjB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export declare const triggerEventOrigins: readonly [
|
|
1
|
+
export declare const triggerEventOrigins: readonly ['integration', 'manual', 'cron'];
|
|
2
2
|
export type TriggerEventOrigin = (typeof triggerEventOrigins)[number];
|
|
3
|
-
export declare const triggerEventOutcomes: readonly [
|
|
3
|
+
export declare const triggerEventOutcomes: readonly ['received', 'routed', 'discarded', 'failed', 'errored'];
|
|
4
4
|
export type TriggerEventOutcome = (typeof triggerEventOutcomes)[number];
|
|
5
5
|
export interface TriggerReceivedEvent {
|
|
6
6
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"received-event.d.ts","sourceRoot":"","sources":["../../../src/core/entities/received-event.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"received-event.d.ts","sourceRoot":"","sources":["../../../src/core/entities/received-event.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,YAAI,aAAa,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;AAC9E,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,eAAO,MAAM,oBAAoB,YAC/B,UAAU,EACV,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,SAAS,CACD,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,UAAU,EAAE,IAAI,CAAC;IACjB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,YAAY,cAAc,EAAE,MAAM,EAIjC;CACF;AAED,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IAEtC,YAAY,oBAAoB,EAAE,MAAM,EAIvC;CACF;AAED,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAOjD;CACF;AAED,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAOjD;CACF;AAED,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAEnC,YAAY,cAAc,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAQ7F;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-event-to-job-listeners.d.ts","sourceRoot":"","sources":["../../src/core/route-event-to-job-listeners.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"route-event-to-job-listeners.d.ts","sourceRoot":"","sources":["../../src/core/route-event-to-job-listeners.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,KAAK,sBAAsB,EAAW,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,uBAAuB,CAAC;AAI/B,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,qBAAqB,CAAC;IACjC,OAAO,EAAE,sBAAsB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,8BAA8B,GACrC,OAAO,CAAC,8BAA8B,CAAC,CAsFzC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { listenerFilterOutputTypesSchema } from '@shipfox/api-workflows-dto';
|
|
2
|
+
import { projectWorkflowPredicateContext, rehydrateJsonExpressionRecord } from '@shipfox/expression';
|
|
2
3
|
import { logger } from '@shipfox/node-opentelemetry';
|
|
3
4
|
import { findMatchingJobListenerSubscriptions } from '#db/job-listener-subscriptions.js';
|
|
4
5
|
import { evaluateStoredFilter } from './config.js';
|
|
5
6
|
import { toReason } from './record-trigger-history.js';
|
|
6
7
|
import { isPermanentDeliverEventToJobListenerError } from './workflows-client.js';
|
|
8
|
+
const LISTENER_INTEGER_PATTERN = /^-?\d+$/;
|
|
7
9
|
export async function routeEventToJobListeners(params) {
|
|
8
10
|
const subscriptions = await findMatchingJobListenerSubscriptions({
|
|
9
11
|
workspaceId: params.workspaceId,
|
|
@@ -106,7 +108,7 @@ function evaluateListenerFilter(params) {
|
|
|
106
108
|
return evaluateStoredFilter({
|
|
107
109
|
value: filter,
|
|
108
110
|
context: projectWorkflowPredicateContext(params.subscription.kind === 'on' ? 'listener.on' : 'listener.until', {
|
|
109
|
-
...snapshot.value,
|
|
111
|
+
...rehydrateListenerFilterSnapshot(snapshot.value, snapshot.outputTypes),
|
|
110
112
|
event: params.payload
|
|
111
113
|
}),
|
|
112
114
|
invalidReason: 'Listener subscription filter must be a non-empty string when set',
|
|
@@ -115,24 +117,139 @@ function evaluateListenerFilter(params) {
|
|
|
115
117
|
}
|
|
116
118
|
function readFilterSnapshot(subscription) {
|
|
117
119
|
const value = subscription.config.filter_snapshot;
|
|
118
|
-
if (value ===
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
if (value !== undefined && (value === null || typeof value !== 'object' || Array.isArray(value))) {
|
|
121
|
+
return {
|
|
122
|
+
kind: 'invalid',
|
|
123
|
+
result: {
|
|
124
|
+
kind: 'filter-error',
|
|
125
|
+
reason: 'Listener filter snapshot must be an object when set'
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const outputTypesValue = subscription.config.filter_output_types;
|
|
130
|
+
if (outputTypesValue !== undefined) {
|
|
131
|
+
const parsedOutputTypes = listenerFilterOutputTypesSchema.safeParse(outputTypesValue);
|
|
132
|
+
if (!parsedOutputTypes.success) {
|
|
133
|
+
return {
|
|
134
|
+
kind: 'invalid',
|
|
135
|
+
result: {
|
|
136
|
+
kind: 'filter-error',
|
|
137
|
+
reason: 'Listener filter output types must be valid when set'
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
123
141
|
return {
|
|
124
142
|
kind: 'valid',
|
|
125
|
-
value: value
|
|
143
|
+
value: value ?? {},
|
|
144
|
+
outputTypes: parsedOutputTypes.data
|
|
126
145
|
};
|
|
127
146
|
}
|
|
128
147
|
return {
|
|
129
|
-
kind: '
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
148
|
+
kind: 'valid',
|
|
149
|
+
value: value ?? {}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function rehydrateListenerFilterSnapshot(snapshot, outputTypes) {
|
|
153
|
+
let result = snapshot;
|
|
154
|
+
if (outputTypes !== undefined && isRecord(snapshot.jobs)) {
|
|
155
|
+
const jobs = Object.fromEntries(Object.entries(snapshot.jobs).map(([jobKey, jobContext])=>{
|
|
156
|
+
const jobOutputTypes = Object.hasOwn(outputTypes, jobKey) ? outputTypes[jobKey] : undefined;
|
|
157
|
+
if (jobOutputTypes === undefined || !isRecord(jobContext)) {
|
|
158
|
+
return [
|
|
159
|
+
jobKey,
|
|
160
|
+
jobContext
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
const outputs = isRecord(jobContext.outputs) ? rehydrateJsonExpressionRecord(jobContext.outputs, jobOutputTypes) : jobContext.outputs;
|
|
164
|
+
const executions = Array.isArray(jobContext.executions) ? jobContext.executions.map((execution)=>{
|
|
165
|
+
if (!isRecord(execution) || !isRecord(execution.outputs)) return execution;
|
|
166
|
+
return {
|
|
167
|
+
...execution,
|
|
168
|
+
outputs: rehydrateJsonExpressionRecord(execution.outputs, jobOutputTypes)
|
|
169
|
+
};
|
|
170
|
+
}) : jobContext.executions;
|
|
171
|
+
return [
|
|
172
|
+
jobKey,
|
|
173
|
+
{
|
|
174
|
+
...jobContext,
|
|
175
|
+
outputs,
|
|
176
|
+
executions
|
|
177
|
+
}
|
|
178
|
+
];
|
|
179
|
+
}));
|
|
180
|
+
result = {
|
|
181
|
+
...snapshot,
|
|
182
|
+
jobs
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const rehydrated = {
|
|
186
|
+
...result
|
|
187
|
+
};
|
|
188
|
+
if (isRecord(result.run)) rehydrated.run = rehydrateRunSnapshot(result.run);
|
|
189
|
+
if (isRecord(result.jobs)) rehydrated.jobs = rehydrateJobsSnapshot(result.jobs);
|
|
190
|
+
return rehydrated;
|
|
191
|
+
}
|
|
192
|
+
function isRecord(value) {
|
|
193
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
194
|
+
}
|
|
195
|
+
function rehydrateRunSnapshot(run) {
|
|
196
|
+
const result = {
|
|
197
|
+
...run
|
|
198
|
+
};
|
|
199
|
+
if ('number' in run) result.number = rehydrateListenerInt(run.number);
|
|
200
|
+
if ('created_at' in run) result.created_at = rehydrateListenerTimestamp(run.created_at);
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
function rehydrateJobsSnapshot(jobs) {
|
|
204
|
+
return Object.fromEntries(Object.entries(jobs).map(([jobKey, value])=>[
|
|
205
|
+
jobKey,
|
|
206
|
+
isRecord(value) ? rehydrateJobSnapshot(value) : value
|
|
207
|
+
]));
|
|
208
|
+
}
|
|
209
|
+
function rehydrateJobSnapshot(job) {
|
|
210
|
+
if (!Array.isArray(job.executions)) return job;
|
|
211
|
+
return {
|
|
212
|
+
...job,
|
|
213
|
+
executions: job.executions.map((value)=>isRecord(value) ? rehydrateExecutionSnapshot(value) : value)
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function rehydrateExecutionSnapshot(execution) {
|
|
217
|
+
const result = {
|
|
218
|
+
...execution
|
|
219
|
+
};
|
|
220
|
+
if ('index' in execution) result.index = rehydrateListenerInt(execution.index);
|
|
221
|
+
if ('started_at' in execution) {
|
|
222
|
+
result.started_at = rehydrateListenerTimestamp(execution.started_at);
|
|
223
|
+
}
|
|
224
|
+
if ('finished_at' in execution) {
|
|
225
|
+
result.finished_at = rehydrateListenerTimestamp(execution.finished_at);
|
|
226
|
+
}
|
|
227
|
+
if (Array.isArray(execution.events)) {
|
|
228
|
+
result.events = execution.events.map((value)=>isRecord(value) ? rehydrateExecutionEventSnapshot(value) : value);
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
function rehydrateExecutionEventSnapshot(event) {
|
|
233
|
+
if (!('received_at' in event)) return event;
|
|
234
|
+
return {
|
|
235
|
+
...event,
|
|
236
|
+
received_at: rehydrateListenerTimestamp(event.received_at)
|
|
134
237
|
};
|
|
135
238
|
}
|
|
239
|
+
function rehydrateListenerInt(value) {
|
|
240
|
+
if (typeof value === 'number' && Number.isSafeInteger(value)) return BigInt(value);
|
|
241
|
+
if (typeof value !== 'string' || !LISTENER_INTEGER_PATTERN.test(value)) return value;
|
|
242
|
+
try {
|
|
243
|
+
return BigInt(value);
|
|
244
|
+
} catch {
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function rehydrateListenerTimestamp(value) {
|
|
249
|
+
if (typeof value !== 'string') return value;
|
|
250
|
+
const date = new Date(value);
|
|
251
|
+
return Number.isNaN(date.getTime()) ? value : date;
|
|
252
|
+
}
|
|
136
253
|
function listenerDisposition(subscription) {
|
|
137
254
|
return subscription.kind === 'until' ? 'resolve' : 'fire';
|
|
138
255
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/route-event-to-job-listeners.ts"],"sourcesContent":["import {projectWorkflowPredicateContext} from '@shipfox/expression';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport {findMatchingJobListenerSubscriptions} from '#db/job-listener-subscriptions.js';\nimport {evaluateStoredFilter, type StoredFilterEvaluation} from './config.js';\nimport type {JobListenerSubscription} from './entities/job-listener-subscription.js';\nimport {type TriggerHistoryRecorder, toReason} from './record-trigger-history.js';\nimport {\n isPermanentDeliverEventToJobListenerError,\n type WorkflowsModuleClient,\n} from './workflows-client.js';\n\nexport interface RouteEventToJobListenersParams {\n workflows: WorkflowsModuleClient;\n history: TriggerHistoryRecorder;\n eventRef: string;\n workspaceId: string;\n connectionId: string;\n provider: string;\n source: string;\n event: string;\n deliveryId: string;\n payload: unknown;\n receivedAt: Date;\n}\n\nexport interface RouteEventToJobListenersResult {\n /**\n * Listener outcomes that should contribute to received_event.matched_count:\n * filter errors, accepted deliveries, and dispatch errors. Stale skipped jobs\n * are intentionally excluded because they did not produce an auditable decision.\n */\n engagedCount: number;\n /**\n * Jobs with an effective matcher after source/event/filter checks, including\n * stale skipped jobs.\n */\n matchedJobCount: number;\n acceptedJobCount: number;\n deliveredCount: number;\n transientErrored: boolean;\n transientError: unknown;\n}\n\nexport async function routeEventToJobListeners(\n params: RouteEventToJobListenersParams,\n): Promise<RouteEventToJobListenersResult> {\n const subscriptions = await findMatchingJobListenerSubscriptions({\n workspaceId: params.workspaceId,\n source: params.source,\n event: params.event,\n });\n\n let filterErrorCount = 0;\n const effectiveMatchByJobId = new Map<string, JobListenerSubscription>();\n for (const subscription of subscriptions) {\n const filterResult = evaluateListenerFilter({subscription, payload: params.payload});\n if (filterResult.kind === 'filtered') continue;\n if (filterResult.kind === 'filter-error') {\n filterErrorCount += 1;\n await params.history.listenerFilterErrored(subscription, filterResult.reason);\n continue;\n }\n\n const previous = effectiveMatchByJobId.get(subscription.jobId);\n if (!previous || shouldReplaceEffectiveMatcher(previous, subscription)) {\n effectiveMatchByJobId.set(subscription.jobId, subscription);\n }\n }\n\n const fireDeliveryNeeded = [...effectiveMatchByJobId.values()].some(\n (subscription) => listenerDisposition(subscription) === 'fire',\n );\n const triggerReference = fireDeliveryNeeded\n ? await params.workflows.resolveWorkflowRunTriggerReference({\n workspaceId: params.workspaceId,\n triggerConnectionId: params.connectionId,\n triggerPayload: {\n provider: params.provider,\n source: params.source,\n event: params.event,\n deliveryId: params.deliveryId,\n data: params.payload,\n },\n })\n : null;\n\n let acceptedJobCount = 0;\n let deliveredCount = 0;\n let sawTransientError = false;\n let dispatchErrorCount = 0;\n let firstTransientError: unknown;\n\n for (const subscription of effectiveMatchByJobId.values()) {\n const disposition = listenerDisposition(subscription);\n try {\n const result = await params.workflows.deliverEventToJobListener({\n jobId: subscription.jobId,\n disposition,\n eventRef: params.eventRef,\n deliveryId: params.deliveryId,\n source: params.source,\n event: params.event,\n provider: params.provider,\n triggerConnectionId: params.connectionId,\n triggerReference,\n payload: params.payload,\n receivedAt: params.receivedAt.toISOString(),\n });\n if (!result.skipped) {\n acceptedJobCount += 1;\n await params.history.listenerTriggered(subscription);\n }\n if (result.buffered) deliveredCount += 1;\n } catch (error) {\n dispatchErrorCount += 1;\n await params.history.listenerDispatchErrored(subscription, toReason(error));\n if (!isPermanentDeliverEventToJobListenerError(error) && !sawTransientError) {\n sawTransientError = true;\n firstTransientError = error;\n }\n }\n }\n\n return {\n engagedCount: filterErrorCount + acceptedJobCount + dispatchErrorCount,\n matchedJobCount: effectiveMatchByJobId.size,\n acceptedJobCount,\n deliveredCount,\n transientErrored: sawTransientError,\n transientError: sawTransientError ? firstTransientError : undefined,\n };\n}\n\ninterface EvaluateListenerFilterParams {\n subscription: JobListenerSubscription;\n payload: unknown;\n}\n\nfunction evaluateListenerFilter(params: EvaluateListenerFilterParams): StoredFilterEvaluation {\n const filter = params.subscription.config.filter;\n if (filter === null || filter === undefined) return {kind: 'matched'};\n if (typeof filter !== 'string' || filter.trim() === '') {\n return evaluateStoredFilter({\n value: filter,\n context: projectWorkflowPredicateContext(\n params.subscription.kind === 'on' ? 'listener.on' : 'listener.until',\n {event: params.payload},\n ),\n invalidReason: 'Listener subscription filter must be a non-empty string when set',\n evaluationFailedReason: 'Listener filter evaluation failed',\n });\n }\n\n const snapshot = readFilterSnapshot(params.subscription);\n if (snapshot.kind === 'invalid') return snapshot.result;\n\n return evaluateStoredFilter({\n value: filter,\n context: projectWorkflowPredicateContext(\n params.subscription.kind === 'on' ? 'listener.on' : 'listener.until',\n {...snapshot.value, event: params.payload},\n ),\n invalidReason: 'Listener subscription filter must be a non-empty string when set',\n evaluationFailedReason: 'Listener filter evaluation failed',\n });\n}\n\nfunction readFilterSnapshot(\n subscription: JobListenerSubscription,\n):\n | {kind: 'valid'; value: Record<string, unknown>}\n | {kind: 'invalid'; result: Extract<StoredFilterEvaluation, {kind: 'filter-error'}>} {\n const value = subscription.config.filter_snapshot;\n if (value === undefined) return {kind: 'valid', value: {}};\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return {kind: 'valid', value: value as Record<string, unknown>};\n }\n return {\n kind: 'invalid',\n result: {\n kind: 'filter-error',\n reason: 'Listener filter snapshot must be an object when set',\n },\n };\n}\n\nfunction listenerDisposition(subscription: JobListenerSubscription): 'fire' | 'resolve' {\n return subscription.kind === 'until' ? 'resolve' : 'fire';\n}\n\nfunction listenerMatcherSortKey(subscription: JobListenerSubscription): string {\n const kindRank = subscription.kind === 'until' ? '0' : '1';\n return `${kindRank}:${subscription.matcherOrdinal.toString().padStart(10, '0')}`;\n}\n\nfunction shouldReplaceEffectiveMatcher(\n previous: JobListenerSubscription,\n candidate: JobListenerSubscription,\n): boolean {\n const previousKey = listenerMatcherSortKey(previous);\n const candidateKey = listenerMatcherSortKey(candidate);\n if (candidateKey !== previousKey) return candidateKey < previousKey;\n\n logger().warn(\n {\n jobId: candidate.jobId,\n keptSubscriptionId: previous.id,\n candidateSubscriptionId: candidate.id,\n matcherKind: candidate.kind,\n matcherOrdinal: candidate.matcherOrdinal,\n },\n 'duplicate job listener matcher key encountered; choosing deterministic subscription id order',\n );\n return candidate.id < previous.id;\n}\n"],"names":["projectWorkflowPredicateContext","logger","findMatchingJobListenerSubscriptions","evaluateStoredFilter","toReason","isPermanentDeliverEventToJobListenerError","routeEventToJobListeners","params","subscriptions","workspaceId","source","event","filterErrorCount","effectiveMatchByJobId","Map","subscription","filterResult","evaluateListenerFilter","payload","kind","history","listenerFilterErrored","reason","previous","get","jobId","shouldReplaceEffectiveMatcher","set","fireDeliveryNeeded","values","some","listenerDisposition","triggerReference","workflows","resolveWorkflowRunTriggerReference","triggerConnectionId","connectionId","triggerPayload","provider","deliveryId","data","acceptedJobCount","deliveredCount","sawTransientError","dispatchErrorCount","firstTransientError","disposition","result","deliverEventToJobListener","eventRef","receivedAt","toISOString","skipped","listenerTriggered","buffered","error","listenerDispatchErrored","engagedCount","matchedJobCount","size","transientErrored","transientError","undefined","filter","config","trim","value","context","invalidReason","evaluationFailedReason","snapshot","readFilterSnapshot","filter_snapshot","Array","isArray","listenerMatcherSortKey","kindRank","matcherOrdinal","toString","padStart","candidate","previousKey","candidateKey","warn","keptSubscriptionId","id","candidateSubscriptionId","matcherKind"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/route-event-to-job-listeners.ts"],"sourcesContent":["import {\n type ListenerFilterOutputTypes,\n listenerFilterOutputTypesSchema,\n} from '@shipfox/api-workflows-dto';\nimport {projectWorkflowPredicateContext, rehydrateJsonExpressionRecord} from '@shipfox/expression';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport {findMatchingJobListenerSubscriptions} from '#db/job-listener-subscriptions.js';\nimport {evaluateStoredFilter, type StoredFilterEvaluation} from './config.js';\nimport type {JobListenerSubscription} from './entities/job-listener-subscription.js';\nimport {type TriggerHistoryRecorder, toReason} from './record-trigger-history.js';\nimport {\n isPermanentDeliverEventToJobListenerError,\n type WorkflowsModuleClient,\n} from './workflows-client.js';\n\nconst LISTENER_INTEGER_PATTERN = /^-?\\d+$/;\n\nexport interface RouteEventToJobListenersParams {\n workflows: WorkflowsModuleClient;\n history: TriggerHistoryRecorder;\n eventRef: string;\n workspaceId: string;\n connectionId: string;\n provider: string;\n source: string;\n event: string;\n deliveryId: string;\n payload: unknown;\n receivedAt: Date;\n}\n\nexport interface RouteEventToJobListenersResult {\n /**\n * Listener outcomes that should contribute to received_event.matched_count:\n * filter errors, accepted deliveries, and dispatch errors. Stale skipped jobs\n * are intentionally excluded because they did not produce an auditable decision.\n */\n engagedCount: number;\n /**\n * Jobs with an effective matcher after source/event/filter checks, including\n * stale skipped jobs.\n */\n matchedJobCount: number;\n acceptedJobCount: number;\n deliveredCount: number;\n transientErrored: boolean;\n transientError: unknown;\n}\n\nexport async function routeEventToJobListeners(\n params: RouteEventToJobListenersParams,\n): Promise<RouteEventToJobListenersResult> {\n const subscriptions = await findMatchingJobListenerSubscriptions({\n workspaceId: params.workspaceId,\n source: params.source,\n event: params.event,\n });\n\n let filterErrorCount = 0;\n const effectiveMatchByJobId = new Map<string, JobListenerSubscription>();\n for (const subscription of subscriptions) {\n const filterResult = evaluateListenerFilter({subscription, payload: params.payload});\n if (filterResult.kind === 'filtered') continue;\n if (filterResult.kind === 'filter-error') {\n filterErrorCount += 1;\n await params.history.listenerFilterErrored(subscription, filterResult.reason);\n continue;\n }\n\n const previous = effectiveMatchByJobId.get(subscription.jobId);\n if (!previous || shouldReplaceEffectiveMatcher(previous, subscription)) {\n effectiveMatchByJobId.set(subscription.jobId, subscription);\n }\n }\n\n const fireDeliveryNeeded = [...effectiveMatchByJobId.values()].some(\n (subscription) => listenerDisposition(subscription) === 'fire',\n );\n const triggerReference = fireDeliveryNeeded\n ? await params.workflows.resolveWorkflowRunTriggerReference({\n workspaceId: params.workspaceId,\n triggerConnectionId: params.connectionId,\n triggerPayload: {\n provider: params.provider,\n source: params.source,\n event: params.event,\n deliveryId: params.deliveryId,\n data: params.payload,\n },\n })\n : null;\n\n let acceptedJobCount = 0;\n let deliveredCount = 0;\n let sawTransientError = false;\n let dispatchErrorCount = 0;\n let firstTransientError: unknown;\n\n for (const subscription of effectiveMatchByJobId.values()) {\n const disposition = listenerDisposition(subscription);\n try {\n const result = await params.workflows.deliverEventToJobListener({\n jobId: subscription.jobId,\n disposition,\n eventRef: params.eventRef,\n deliveryId: params.deliveryId,\n source: params.source,\n event: params.event,\n provider: params.provider,\n triggerConnectionId: params.connectionId,\n triggerReference,\n payload: params.payload,\n receivedAt: params.receivedAt.toISOString(),\n });\n if (!result.skipped) {\n acceptedJobCount += 1;\n await params.history.listenerTriggered(subscription);\n }\n if (result.buffered) deliveredCount += 1;\n } catch (error) {\n dispatchErrorCount += 1;\n await params.history.listenerDispatchErrored(subscription, toReason(error));\n if (!isPermanentDeliverEventToJobListenerError(error) && !sawTransientError) {\n sawTransientError = true;\n firstTransientError = error;\n }\n }\n }\n\n return {\n engagedCount: filterErrorCount + acceptedJobCount + dispatchErrorCount,\n matchedJobCount: effectiveMatchByJobId.size,\n acceptedJobCount,\n deliveredCount,\n transientErrored: sawTransientError,\n transientError: sawTransientError ? firstTransientError : undefined,\n };\n}\n\ninterface EvaluateListenerFilterParams {\n subscription: JobListenerSubscription;\n payload: unknown;\n}\n\nfunction evaluateListenerFilter(params: EvaluateListenerFilterParams): StoredFilterEvaluation {\n const filter = params.subscription.config.filter;\n if (filter === null || filter === undefined) return {kind: 'matched'};\n if (typeof filter !== 'string' || filter.trim() === '') {\n return evaluateStoredFilter({\n value: filter,\n context: projectWorkflowPredicateContext(\n params.subscription.kind === 'on' ? 'listener.on' : 'listener.until',\n {event: params.payload},\n ),\n invalidReason: 'Listener subscription filter must be a non-empty string when set',\n evaluationFailedReason: 'Listener filter evaluation failed',\n });\n }\n\n const snapshot = readFilterSnapshot(params.subscription);\n if (snapshot.kind === 'invalid') return snapshot.result;\n\n return evaluateStoredFilter({\n value: filter,\n context: projectWorkflowPredicateContext(\n params.subscription.kind === 'on' ? 'listener.on' : 'listener.until',\n {\n ...rehydrateListenerFilterSnapshot(snapshot.value, snapshot.outputTypes),\n event: params.payload,\n },\n ),\n invalidReason: 'Listener subscription filter must be a non-empty string when set',\n evaluationFailedReason: 'Listener filter evaluation failed',\n });\n}\n\nfunction readFilterSnapshot(\n subscription: JobListenerSubscription,\n):\n | {kind: 'valid'; value: Record<string, unknown>; outputTypes?: ListenerFilterOutputTypes}\n | {kind: 'invalid'; result: Extract<StoredFilterEvaluation, {kind: 'filter-error'}>} {\n const value = subscription.config.filter_snapshot;\n if (\n value !== undefined &&\n (value === null || typeof value !== 'object' || Array.isArray(value))\n ) {\n return {\n kind: 'invalid',\n result: {\n kind: 'filter-error',\n reason: 'Listener filter snapshot must be an object when set',\n },\n };\n }\n\n const outputTypesValue = subscription.config.filter_output_types;\n if (outputTypesValue !== undefined) {\n const parsedOutputTypes = listenerFilterOutputTypesSchema.safeParse(outputTypesValue);\n if (!parsedOutputTypes.success) {\n return {\n kind: 'invalid',\n result: {\n kind: 'filter-error',\n reason: 'Listener filter output types must be valid when set',\n },\n };\n }\n return {\n kind: 'valid',\n value: (value ?? {}) as Record<string, unknown>,\n outputTypes: parsedOutputTypes.data,\n };\n }\n\n return {kind: 'valid', value: (value ?? {}) as Record<string, unknown>};\n}\n\nfunction rehydrateListenerFilterSnapshot(\n snapshot: Record<string, unknown>,\n outputTypes: ListenerFilterOutputTypes | undefined,\n): Record<string, unknown> {\n let result = snapshot;\n if (outputTypes !== undefined && isRecord(snapshot.jobs)) {\n const jobs = Object.fromEntries(\n Object.entries(snapshot.jobs).map(([jobKey, jobContext]) => {\n const jobOutputTypes = Object.hasOwn(outputTypes, jobKey) ? outputTypes[jobKey] : undefined;\n if (jobOutputTypes === undefined || !isRecord(jobContext)) {\n return [jobKey, jobContext];\n }\n\n const outputs = isRecord(jobContext.outputs)\n ? rehydrateJsonExpressionRecord(jobContext.outputs, jobOutputTypes)\n : jobContext.outputs;\n const executions = Array.isArray(jobContext.executions)\n ? jobContext.executions.map((execution) => {\n if (!isRecord(execution) || !isRecord(execution.outputs)) return execution;\n return {\n ...execution,\n outputs: rehydrateJsonExpressionRecord(execution.outputs, jobOutputTypes),\n };\n })\n : jobContext.executions;\n\n return [\n jobKey,\n {\n ...jobContext,\n outputs,\n executions,\n },\n ];\n }),\n );\n result = {...snapshot, jobs};\n }\n\n const rehydrated = {...result};\n if (isRecord(result.run)) rehydrated.run = rehydrateRunSnapshot(result.run);\n if (isRecord(result.jobs)) rehydrated.jobs = rehydrateJobsSnapshot(result.jobs);\n return rehydrated;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction rehydrateRunSnapshot(run: Record<string, unknown>): Record<string, unknown> {\n const result = {...run};\n if ('number' in run) result.number = rehydrateListenerInt(run.number);\n if ('created_at' in run) result.created_at = rehydrateListenerTimestamp(run.created_at);\n return result;\n}\n\nfunction rehydrateJobsSnapshot(jobs: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(jobs).map(([jobKey, value]) => [\n jobKey,\n isRecord(value) ? rehydrateJobSnapshot(value) : value,\n ]),\n );\n}\n\nfunction rehydrateJobSnapshot(job: Record<string, unknown>): Record<string, unknown> {\n if (!Array.isArray(job.executions)) return job;\n\n return {\n ...job,\n executions: job.executions.map((value) =>\n isRecord(value) ? rehydrateExecutionSnapshot(value) : value,\n ),\n };\n}\n\nfunction rehydrateExecutionSnapshot(execution: Record<string, unknown>): Record<string, unknown> {\n const result = {...execution};\n if ('index' in execution) result.index = rehydrateListenerInt(execution.index);\n if ('started_at' in execution) {\n result.started_at = rehydrateListenerTimestamp(execution.started_at);\n }\n if ('finished_at' in execution) {\n result.finished_at = rehydrateListenerTimestamp(execution.finished_at);\n }\n if (Array.isArray(execution.events)) {\n result.events = execution.events.map((value) =>\n isRecord(value) ? rehydrateExecutionEventSnapshot(value) : value,\n );\n }\n return result;\n}\n\nfunction rehydrateExecutionEventSnapshot(event: Record<string, unknown>): Record<string, unknown> {\n if (!('received_at' in event)) return event;\n return {...event, received_at: rehydrateListenerTimestamp(event.received_at)};\n}\n\nfunction rehydrateListenerInt(value: unknown): unknown {\n if (typeof value === 'number' && Number.isSafeInteger(value)) return BigInt(value);\n if (typeof value !== 'string' || !LISTENER_INTEGER_PATTERN.test(value)) return value;\n\n try {\n return BigInt(value);\n } catch {\n return value;\n }\n}\n\nfunction rehydrateListenerTimestamp(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? value : date;\n}\n\nfunction listenerDisposition(subscription: JobListenerSubscription): 'fire' | 'resolve' {\n return subscription.kind === 'until' ? 'resolve' : 'fire';\n}\n\nfunction listenerMatcherSortKey(subscription: JobListenerSubscription): string {\n const kindRank = subscription.kind === 'until' ? '0' : '1';\n return `${kindRank}:${subscription.matcherOrdinal.toString().padStart(10, '0')}`;\n}\n\nfunction shouldReplaceEffectiveMatcher(\n previous: JobListenerSubscription,\n candidate: JobListenerSubscription,\n): boolean {\n const previousKey = listenerMatcherSortKey(previous);\n const candidateKey = listenerMatcherSortKey(candidate);\n if (candidateKey !== previousKey) return candidateKey < previousKey;\n\n logger().warn(\n {\n jobId: candidate.jobId,\n keptSubscriptionId: previous.id,\n candidateSubscriptionId: candidate.id,\n matcherKind: candidate.kind,\n matcherOrdinal: candidate.matcherOrdinal,\n },\n 'duplicate job listener matcher key encountered; choosing deterministic subscription id order',\n );\n return candidate.id < previous.id;\n}\n"],"names":["listenerFilterOutputTypesSchema","projectWorkflowPredicateContext","rehydrateJsonExpressionRecord","logger","findMatchingJobListenerSubscriptions","evaluateStoredFilter","toReason","isPermanentDeliverEventToJobListenerError","LISTENER_INTEGER_PATTERN","routeEventToJobListeners","params","subscriptions","workspaceId","source","event","filterErrorCount","effectiveMatchByJobId","Map","subscription","filterResult","evaluateListenerFilter","payload","kind","history","listenerFilterErrored","reason","previous","get","jobId","shouldReplaceEffectiveMatcher","set","fireDeliveryNeeded","values","some","listenerDisposition","triggerReference","workflows","resolveWorkflowRunTriggerReference","triggerConnectionId","connectionId","triggerPayload","provider","deliveryId","data","acceptedJobCount","deliveredCount","sawTransientError","dispatchErrorCount","firstTransientError","disposition","result","deliverEventToJobListener","eventRef","receivedAt","toISOString","skipped","listenerTriggered","buffered","error","listenerDispatchErrored","engagedCount","matchedJobCount","size","transientErrored","transientError","undefined","filter","config","trim","value","context","invalidReason","evaluationFailedReason","snapshot","readFilterSnapshot","rehydrateListenerFilterSnapshot","outputTypes","filter_snapshot","Array","isArray","outputTypesValue","filter_output_types","parsedOutputTypes","safeParse","success","isRecord","jobs","Object","fromEntries","entries","map","jobKey","jobContext","jobOutputTypes","hasOwn","outputs","executions","execution","rehydrated","run","rehydrateRunSnapshot","rehydrateJobsSnapshot","number","rehydrateListenerInt","created_at","rehydrateListenerTimestamp","rehydrateJobSnapshot","job","rehydrateExecutionSnapshot","index","started_at","finished_at","events","rehydrateExecutionEventSnapshot","received_at","Number","isSafeInteger","BigInt","test","date","Date","isNaN","getTime","listenerMatcherSortKey","kindRank","matcherOrdinal","toString","padStart","candidate","previousKey","candidateKey","warn","keptSubscriptionId","id","candidateSubscriptionId","matcherKind"],"mappings":"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"}
|
|
@@ -71,24 +71,24 @@ declare function startRunKnownError(error: unknown): import("@shipfox/inter-modu
|
|
|
71
71
|
readonly 'interpolation-unresolvable': import("zod").ZodObject<{
|
|
72
72
|
definitionId: import("zod").ZodString;
|
|
73
73
|
field: import("zod").ZodEnum<{
|
|
74
|
-
run: "run";
|
|
75
|
-
env: "env";
|
|
76
|
-
"agent.prompt": "agent.prompt";
|
|
77
74
|
"agent.model": "agent.model";
|
|
75
|
+
"agent.prompt": "agent.prompt";
|
|
78
76
|
"agent.provider": "agent.provider";
|
|
79
77
|
"agent.thinking": "agent.thinking";
|
|
80
|
-
"
|
|
81
|
-
"
|
|
78
|
+
"checkout.connection": "checkout.connection";
|
|
79
|
+
"checkout.path": "checkout.path";
|
|
80
|
+
"checkout.project": "checkout.project";
|
|
81
|
+
"checkout.ref": "checkout.ref";
|
|
82
|
+
"checkout.repository": "checkout.repository";
|
|
83
|
+
env: "env";
|
|
82
84
|
"job.execution_name": "job.execution_name";
|
|
83
|
-
"
|
|
85
|
+
"job.outputs": "job.outputs";
|
|
86
|
+
"job.runner": "job.runner";
|
|
87
|
+
run: "run";
|
|
88
|
+
"step.feedback": "step.feedback";
|
|
84
89
|
"step.name": "step.name";
|
|
85
90
|
"step.working_directory": "step.working_directory";
|
|
86
|
-
"
|
|
87
|
-
"checkout.project": "checkout.project";
|
|
88
|
-
"checkout.connection": "checkout.connection";
|
|
89
|
-
"checkout.repository": "checkout.repository";
|
|
90
|
-
"checkout.ref": "checkout.ref";
|
|
91
|
-
"checkout.path": "checkout.path";
|
|
91
|
+
"workflow.run_name": "workflow.run_name";
|
|
92
92
|
}>;
|
|
93
93
|
source: import("zod").ZodString;
|
|
94
94
|
envKey: import("zod").ZodOptional<import("zod").ZodString>;
|
package/dist/db/db.d.ts
CHANGED
|
@@ -141,7 +141,7 @@ export declare const schema: {
|
|
|
141
141
|
generated: undefined;
|
|
142
142
|
}, {}, {}>;
|
|
143
143
|
};
|
|
144
|
-
dialect:
|
|
144
|
+
dialect: 'pg';
|
|
145
145
|
}>;
|
|
146
146
|
jobListenerSubscriptions: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
147
147
|
name: "job_listener_subscriptions";
|
|
@@ -320,7 +320,7 @@ export declare const schema: {
|
|
|
320
320
|
generated: undefined;
|
|
321
321
|
}, {}, {}>;
|
|
322
322
|
};
|
|
323
|
-
dialect:
|
|
323
|
+
dialect: 'pg';
|
|
324
324
|
}>;
|
|
325
325
|
triggerSubscriptions: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
326
326
|
name: "subscriptions";
|
|
@@ -497,7 +497,7 @@ export declare const schema: {
|
|
|
497
497
|
generated: undefined;
|
|
498
498
|
}, {}, {}>;
|
|
499
499
|
};
|
|
500
|
-
dialect:
|
|
500
|
+
dialect: 'pg';
|
|
501
501
|
}>;
|
|
502
502
|
triggersOutbox: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
503
503
|
name: "outbox";
|
|
@@ -691,7 +691,7 @@ export declare const schema: {
|
|
|
691
691
|
generated: undefined;
|
|
692
692
|
}, {}, {}>;
|
|
693
693
|
};
|
|
694
|
-
dialect:
|
|
694
|
+
dialect: 'pg';
|
|
695
695
|
}>;
|
|
696
696
|
triggersReceivedEvents: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
697
697
|
name: "received_events";
|
|
@@ -736,7 +736,7 @@ export declare const schema: {
|
|
|
736
736
|
tableName: "received_events";
|
|
737
737
|
dataType: "string";
|
|
738
738
|
columnType: "PgText";
|
|
739
|
-
data: "
|
|
739
|
+
data: "cron" | "integration" | "manual";
|
|
740
740
|
driverParam: string;
|
|
741
741
|
notNull: true;
|
|
742
742
|
hasDefault: false;
|
|
@@ -872,7 +872,7 @@ export declare const schema: {
|
|
|
872
872
|
tableName: "received_events";
|
|
873
873
|
dataType: "string";
|
|
874
874
|
columnType: "PgText";
|
|
875
|
-
data: "
|
|
875
|
+
data: "discarded" | "errored" | "failed" | "received" | "routed";
|
|
876
876
|
driverParam: string;
|
|
877
877
|
notNull: true;
|
|
878
878
|
hasDefault: true;
|
|
@@ -972,7 +972,7 @@ export declare const schema: {
|
|
|
972
972
|
generated: undefined;
|
|
973
973
|
}, {}, {}>;
|
|
974
974
|
};
|
|
975
|
-
dialect:
|
|
975
|
+
dialect: 'pg';
|
|
976
976
|
}>;
|
|
977
977
|
triggersDecisions: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
978
978
|
name: "decisions";
|
|
@@ -1017,7 +1017,7 @@ export declare const schema: {
|
|
|
1017
1017
|
tableName: "decisions";
|
|
1018
1018
|
dataType: "string";
|
|
1019
1019
|
columnType: "PgText";
|
|
1020
|
-
data: "
|
|
1020
|
+
data: "listener" | "trigger";
|
|
1021
1021
|
driverParam: string;
|
|
1022
1022
|
notNull: true;
|
|
1023
1023
|
hasDefault: false;
|
|
@@ -1170,7 +1170,7 @@ export declare const schema: {
|
|
|
1170
1170
|
tableName: "decisions";
|
|
1171
1171
|
dataType: "string";
|
|
1172
1172
|
columnType: "PgText";
|
|
1173
|
-
data: "
|
|
1173
|
+
data: "dispatch-error" | "filter-error" | "triggered";
|
|
1174
1174
|
driverParam: string;
|
|
1175
1175
|
notNull: true;
|
|
1176
1176
|
hasDefault: false;
|
|
@@ -1251,7 +1251,7 @@ export declare const schema: {
|
|
|
1251
1251
|
generated: undefined;
|
|
1252
1252
|
}, {}, {}>;
|
|
1253
1253
|
};
|
|
1254
|
-
dialect:
|
|
1254
|
+
dialect: 'pg';
|
|
1255
1255
|
}>;
|
|
1256
1256
|
};
|
|
1257
1257
|
export declare function db(): NodePgDatabase<{
|
|
@@ -1396,7 +1396,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
1396
1396
|
generated: undefined;
|
|
1397
1397
|
}, {}, {}>;
|
|
1398
1398
|
};
|
|
1399
|
-
dialect:
|
|
1399
|
+
dialect: 'pg';
|
|
1400
1400
|
}>;
|
|
1401
1401
|
jobListenerSubscriptions: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1402
1402
|
name: "job_listener_subscriptions";
|
|
@@ -1575,7 +1575,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
1575
1575
|
generated: undefined;
|
|
1576
1576
|
}, {}, {}>;
|
|
1577
1577
|
};
|
|
1578
|
-
dialect:
|
|
1578
|
+
dialect: 'pg';
|
|
1579
1579
|
}>;
|
|
1580
1580
|
triggerSubscriptions: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1581
1581
|
name: "subscriptions";
|
|
@@ -1752,7 +1752,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
1752
1752
|
generated: undefined;
|
|
1753
1753
|
}, {}, {}>;
|
|
1754
1754
|
};
|
|
1755
|
-
dialect:
|
|
1755
|
+
dialect: 'pg';
|
|
1756
1756
|
}>;
|
|
1757
1757
|
triggersOutbox: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1758
1758
|
name: "outbox";
|
|
@@ -1946,7 +1946,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
1946
1946
|
generated: undefined;
|
|
1947
1947
|
}, {}, {}>;
|
|
1948
1948
|
};
|
|
1949
|
-
dialect:
|
|
1949
|
+
dialect: 'pg';
|
|
1950
1950
|
}>;
|
|
1951
1951
|
triggersReceivedEvents: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1952
1952
|
name: "received_events";
|
|
@@ -1991,7 +1991,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
1991
1991
|
tableName: "received_events";
|
|
1992
1992
|
dataType: "string";
|
|
1993
1993
|
columnType: "PgText";
|
|
1994
|
-
data: "
|
|
1994
|
+
data: "cron" | "integration" | "manual";
|
|
1995
1995
|
driverParam: string;
|
|
1996
1996
|
notNull: true;
|
|
1997
1997
|
hasDefault: false;
|
|
@@ -2127,7 +2127,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
2127
2127
|
tableName: "received_events";
|
|
2128
2128
|
dataType: "string";
|
|
2129
2129
|
columnType: "PgText";
|
|
2130
|
-
data: "
|
|
2130
|
+
data: "discarded" | "errored" | "failed" | "received" | "routed";
|
|
2131
2131
|
driverParam: string;
|
|
2132
2132
|
notNull: true;
|
|
2133
2133
|
hasDefault: true;
|
|
@@ -2227,7 +2227,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
2227
2227
|
generated: undefined;
|
|
2228
2228
|
}, {}, {}>;
|
|
2229
2229
|
};
|
|
2230
|
-
dialect:
|
|
2230
|
+
dialect: 'pg';
|
|
2231
2231
|
}>;
|
|
2232
2232
|
triggersDecisions: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
2233
2233
|
name: "decisions";
|
|
@@ -2272,7 +2272,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
2272
2272
|
tableName: "decisions";
|
|
2273
2273
|
dataType: "string";
|
|
2274
2274
|
columnType: "PgText";
|
|
2275
|
-
data: "
|
|
2275
|
+
data: "listener" | "trigger";
|
|
2276
2276
|
driverParam: string;
|
|
2277
2277
|
notNull: true;
|
|
2278
2278
|
hasDefault: false;
|
|
@@ -2425,7 +2425,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
2425
2425
|
tableName: "decisions";
|
|
2426
2426
|
dataType: "string";
|
|
2427
2427
|
columnType: "PgText";
|
|
2428
|
-
data: "
|
|
2428
|
+
data: "dispatch-error" | "filter-error" | "triggered";
|
|
2429
2429
|
driverParam: string;
|
|
2430
2430
|
notNull: true;
|
|
2431
2431
|
hasDefault: false;
|
|
@@ -2506,7 +2506,7 @@ export declare function db(): NodePgDatabase<{
|
|
|
2506
2506
|
generated: undefined;
|
|
2507
2507
|
}, {}, {}>;
|
|
2508
2508
|
};
|
|
2509
|
-
dialect:
|
|
2509
|
+
dialect: 'pg';
|
|
2510
2510
|
}>;
|
|
2511
2511
|
}>;
|
|
2512
2512
|
export type Tx = Parameters<Parameters<ReturnType<typeof db>['transaction']>[0]>[0];
|
|
@@ -5,6 +5,7 @@ export interface ListenerMatcher {
|
|
|
5
5
|
inputs?: Readonly<Record<string, unknown>> | undefined;
|
|
6
6
|
filter?: string | undefined;
|
|
7
7
|
filter_snapshot?: Readonly<Record<string, unknown>> | undefined;
|
|
8
|
+
filter_output_types?: Readonly<Record<string, unknown>> | undefined;
|
|
8
9
|
}
|
|
9
10
|
export interface ProjectJobListenerSubscriptionsParams {
|
|
10
11
|
workspaceId: string;
|
|
@@ -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;
|
|
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;IAChE,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACrE;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,CA+Cf;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"}
|
|
@@ -20,6 +20,9 @@ export async function projectJobListenerSubscriptions(params) {
|
|
|
20
20
|
if (matcher.inputs !== undefined) config.inputs = matcher.inputs;
|
|
21
21
|
if (matcher.filter !== undefined) config.filter = matcher.filter;
|
|
22
22
|
if (matcher.filter_snapshot !== undefined) config.filter_snapshot = matcher.filter_snapshot;
|
|
23
|
+
if (matcher.filter_output_types !== undefined) {
|
|
24
|
+
config.filter_output_types = matcher.filter_output_types;
|
|
25
|
+
}
|
|
23
26
|
await tx.insert(jobListenerSubscriptions).values({
|
|
24
27
|
workspaceId: params.workspaceId,
|
|
25
28
|
workflowRunId: params.workflowRunId,
|