Merge pull request #226 from Chigala/feature/multiple-eventname-support

Feature/multiple eventname support in eventDispatcher
This commit is contained in:
Matt Aitken
2023-07-31 16:14:25 +01:00
committed by GitHub
13 changed files with 144 additions and 70 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---
Multiple eventname support in eventDispatcher
@@ -33,7 +33,9 @@ export class DeliverEventService {
const possibleEventDispatchers = await tx.eventDispatcher.findMany({
where: {
environmentId: eventRecord.environmentId,
event: eventRecord.name,
event: {
has: eventRecord.name,
},
source: eventRecord.source,
enabled: true,
manual: false,
@@ -404,7 +404,10 @@ export class RegisterJobService {
},
},
create: {
event: trigger.rule.event,
event:
typeof trigger.rule.event === "string"
? [trigger.rule.event]
: trigger.rule.event,
source: trigger.rule.source,
payloadFilter: trigger.rule.payload,
contextFilter: trigger.rule.context,
@@ -417,7 +420,10 @@ export class RegisterJobService {
dispatchableId: job.id,
},
update: {
event: trigger.rule.event,
event:
typeof trigger.rule.event === "string"
? [trigger.rule.event]
: trigger.rule.event,
source: trigger.rule.source,
payloadFilter: trigger.rule.payload,
contextFilter: trigger.rule.context,
+63 -54
View File
@@ -18,64 +18,73 @@ export class TestJobService {
versionId: string;
payload: any;
}) {
return await $transaction(this.#prismaClient, async (tx) => {
//get the environment with orgId and projectId
const environment = await tx.runtimeEnvironment.findUniqueOrThrow({
include: {
organization: true,
project: true,
},
where: {
id: environmentId,
},
});
const version = await tx.jobVersion.findUniqueOrThrow({
include: {
job: true,
},
where: {
id: versionId,
},
});
const event = EventSpecificationSchema.parse(version.eventSpecification);
const eventLog = await this.#prismaClient.eventRecord.create({
data: {
organization: {
connect: {
id: environment.organizationId,
},
return await $transaction(
this.#prismaClient,
async (tx) => {
//get the environment with orgId and projectId
const environment = await tx.runtimeEnvironment.findUniqueOrThrow({
include: {
organization: true,
project: true,
},
project: {
connect: {
id: environment.projectId,
},
where: {
id: environmentId,
},
environment: {
connect: {
id: environment.id,
},
});
const version = await tx.jobVersion.findUniqueOrThrow({
include: {
job: true,
},
eventId: `test:${event.name}:${new Date().getTime()}`,
name: event.name,
timestamp: new Date(),
payload: payload ?? {},
context: {},
source: event.source ?? "trigger.dev",
isTest: true,
},
});
where: {
id: versionId,
},
});
const createRunService = new CreateRunService(tx);
const event = EventSpecificationSchema.parse(
version.eventSpecification
);
const eventName = Array.isArray(event.name)
? event.name[0]
: event.name;
return await createRunService.call({
environment,
eventId: eventLog.id,
job: version.job,
version,
});
}, { timeout: 10000 });
const eventLog = await this.#prismaClient.eventRecord.create({
data: {
organization: {
connect: {
id: environment.organizationId,
},
},
project: {
connect: {
id: environment.projectId,
},
},
environment: {
connect: {
id: environment.id,
},
},
eventId: `test:${eventName}:${new Date().getTime()}`,
name: eventName,
timestamp: new Date(),
payload: payload ?? {},
context: {},
source: event.source ?? "trigger.dev",
isTest: true,
},
});
const createRunService = new CreateRunService(tx);
return await createRunService.call({
environment,
eventId: eventLog.id,
job: version.job,
version,
});
},
{ timeout: 10000 }
);
}
}
@@ -44,3 +44,17 @@ client.defineJob({
}
},
});
client.defineJob({
id: "test-multiple-events",
name: "Test Multiple Events",
version: "0.0.1",
logLevel: "debug",
trigger: eventTrigger({
name: ["test.event.1", "test.event.2"],
examples: [{ id: "test", name: "Test", payload: { name: "test" } }],
}),
run: async (payload, io, ctx) => {
await io.logger.log(`Triggered by the ${ctx.event.name} event`, { ctx });
},
});
@@ -0,0 +1,23 @@
/*
Warnings:
- The `event` column on the `EventDispatcher` table would be dropped and recreated. This will lead to data loss if there is data in the column.
*/
-- AlterTable
-- Step 1: Create temporary column
ALTER TABLE "EventDispatcher"
ADD COLUMN temp_event TEXT[];
-- Step 2: Update temporary column
UPDATE "EventDispatcher"
SET temp_event = ARRAY[event];
-- Step 3: Drop original column
ALTER TABLE "EventDispatcher"
DROP COLUMN "event";
-- Step 4: Rename temporary column
ALTER TABLE "EventDispatcher"
RENAME COLUMN temp_event TO "event";
+3 -3
View File
@@ -582,12 +582,12 @@ enum DynamicTriggerType {
}
model EventDispatcher {
id String @id @default(cuid())
event String
id String @id @default(cuid())
event String[]
source String
payloadFilter Json?
contextFilter Json?
manual Boolean @default(false)
manual Boolean @default(false)
dispatchableId String
dispatchable Json
+1 -1
View File
@@ -19,7 +19,7 @@ export const EventFilterSchema: z.ZodType<EventFilter> = z.lazy(() =>
);
export const EventRuleSchema = z.object({
event: z.string(),
event: z.string().or(z.array(z.string())),
source: z.string(),
payload: EventFilterSchema.optional(),
context: EventFilterSchema.optional(),
+2 -2
View File
@@ -13,7 +13,7 @@ export const EventExampleSchema = z.object({
export type EventExample = z.infer<typeof EventExampleSchema>;
export const EventSpecificationSchema = z.object({
name: z.string(),
name: z.string().or(z.array(z.string())),
title: z.string(),
source: z.string(),
icon: z.string(),
@@ -30,7 +30,7 @@ export const DynamicTriggerMetadataSchema = z.object({
export const StaticTriggerMetadataSchema = z.object({
type: z.literal("static"),
title: z.string(),
title: z.union([z.string(), z.array(z.string())]),
properties: z.array(DisplayPropertySchema).optional(),
rule: EventRuleSchema,
});
+6 -1
View File
@@ -513,7 +513,12 @@ export class TriggerClient {
}
registeredSource.events = Array.from(
new Set([...registeredSource.events, options.event.name])
new Set([
...registeredSource.events,
...(typeof options.event.name === "string"
? [options.event.name]
: options.event.name),
])
);
this.#registeredSources[options.key] = registeredSource;
+4 -1
View File
@@ -92,7 +92,10 @@ export class DynamicTrigger<
key,
channel: this.source.channel,
params,
events: [this.event.name],
events:
typeof this.event.name === "string"
? [this.event.name]
: this.event.name,
integration: {
id: this.source.integration.id,
metadata: this.source.integration.metadata,
@@ -6,12 +6,16 @@ import {
import { z } from "zod";
import { Job } from "../job";
import { TriggerClient } from "../triggerClient";
import { EventSpecification, Trigger } from "../types";
import {
EventSpecification,
EventSpecificationExample,
Trigger,
} from "../types";
type EventTriggerOptions<TEventSpecification extends EventSpecification<any>> =
{
event: TEventSpecification;
name?: string;
name?: string | string[];
source?: string;
filter?: EventFilter;
};
@@ -56,8 +60,8 @@ export class EventTrigger<TEventSpecification extends EventSpecification<any>>
/** Configuration options for an EventTrigger */
type TriggerOptions<TEvent> = {
/** The name of the event you are subscribing to. Must be an exact match (case sensitive). */
name: string;
/** The name of the event you are subscribing to. Must be an exact match (case sensitive). To trigger on multiple possible events, pass in an array of event names */
name: string | string[];
/** A [Zod](https://trigger.dev/docs/documentation/guides/zod) schema that defines the shape of the event payload.
* The default is `z.any()` which is `any`.
* */
@@ -84,6 +88,8 @@ type TriggerOptions<TEvent> = {
* ```
*/
filter?: EventFilter;
examples?: EventSpecificationExample[];
};
/** `eventTrigger()` is set as a [Job's trigger](https://trigger.dev/docs/sdk/job) to subscribe to an event a Job from [a sent event](https://trigger.dev/docs/sdk/triggerclient/instancemethods/sendevent)
@@ -100,6 +106,7 @@ export function eventTrigger<TEvent extends any = any>(
title: "Event",
source: options.source ?? "trigger.dev",
icon: "custom-event",
examples: options.examples,
parsePayload: (rawPayload: any) => {
if (options.schema) {
return options.schema.parse(rawPayload);
+1 -1
View File
@@ -81,7 +81,7 @@ export type EventSpecificationExample = {
};
export interface EventSpecification<TEvent extends any> {
name: string;
name: string | string[];
title: string;
source: string;
icon: string;