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