Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/brave-parents-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Multiple eventname support in eventDispatcher
4 changes: 3 additions & 1 deletion apps/webapp/app/services/events/deliverEvent.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 8 additions & 2 deletions apps/webapp/app/services/jobs/registerJob.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
109 changes: 59 additions & 50 deletions apps/webapp/app/services/jobs/testJob.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
});
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 version = await tx.jobVersion.findUniqueOrThrow({
include: {
job: true,
},
where: {
id: versionId,
},
});

const event = EventSpecificationSchema.parse(version.eventSpecification);
const event = EventSpecificationSchema.parse(
version.eventSpecification
);
const eventName = Array.isArray(event.name)
? event.name[0]
: event.name;

const eventLog = await this.#prismaClient.eventRecord.create({
data: {
organization: {
connect: {
id: environment.organizationId,
const eventLog = await this.#prismaClient.eventRecord.create({
data: {
organization: {
connect: {
id: environment.organizationId,
},
},
},
project: {
connect: {
id: environment.projectId,
project: {
connect: {
id: environment.projectId,
},
},
},
environment: {
connect: {
id: environment.id,
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,
},
eventId: `test:${event.name}:${new Date().getTime()}`,
name: event.name,
timestamp: new Date(),
payload: payload ?? {},
context: {},
source: event.source ?? "trigger.dev",
isTest: true,
},
});
});

const createRunService = new CreateRunService(tx);
const createRunService = new CreateRunService(tx);

return await createRunService.call({
environment,
eventId: eventLog.id,
job: version.job,
version,
});
}, { timeout: 10000 });
return await createRunService.call({
environment,
eventId: eventLog.id,
job: version.job,
version,
});
},
{ timeout: 10000 }
);
}
}
14 changes: 14 additions & 0 deletions examples/nextjs-example/src/jobs/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
},
});
Original file line number Diff line number Diff line change
@@ -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";

6 changes: 3 additions & 3 deletions packages/database/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,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
Expand Down
2 changes: 1 addition & 1 deletion packages/internal/src/schemas/eventFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
4 changes: 2 additions & 2 deletions packages/internal/src/schemas/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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,
});
Expand Down
7 changes: 6 additions & 1 deletion packages/trigger-sdk/src/triggerClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion packages/trigger-sdk/src/triggers/dynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
15 changes: 11 additions & 4 deletions packages/trigger-sdk/src/triggers/eventTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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`.
* */
Expand All @@ -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)
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion packages/trigger-sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export type EventSpecificationExample = {
};

export interface EventSpecification<TEvent extends any> {
name: string;
name: string | string[];
title: string;
source: string;
icon: string;
Expand Down