Merge pull request #226 from Chigala/feature/multiple-eventname-support
Feature/multiple eventname support in eventDispatcher
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -81,7 +81,7 @@ export type EventSpecificationExample = {
|
||||
};
|
||||
|
||||
export interface EventSpecification<TEvent extends any> {
|
||||
name: string;
|
||||
name: string | string[];
|
||||
title: string;
|
||||
source: string;
|
||||
icon: string;
|
||||
|
||||
Reference in New Issue
Block a user