Adding support for trigger source in the run context
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@trigger.dev/sdk": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Adding support for trigger source in the run context, and make sure dynamic trigger runs are preprocessed so they have a chance of populating run properties
|
||||||
@@ -11,7 +11,7 @@ const BodySchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export async function action({ request }: ActionArgs) {
|
export async function action({ request }: ActionArgs) {
|
||||||
logger.info("Creating endpoint", { url: request.url });
|
logger.info("action", { url: request.url });
|
||||||
|
|
||||||
// Ensure this is a POST request
|
// Ensure this is a POST request
|
||||||
if (request.method.toUpperCase() !== "POST") {
|
if (request.method.toUpperCase() !== "POST") {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { RawEvent, SendEventOptions } from "@trigger.dev/internal";
|
import type { RawEvent, SendEventOptions } from "@trigger.dev/internal";
|
||||||
import {
|
import {
|
||||||
$transaction,
|
$transaction,
|
||||||
PrismaClient,
|
|
||||||
PrismaClientOrTransaction,
|
PrismaClientOrTransaction,
|
||||||
|
PrismaErrorSchema,
|
||||||
|
prisma,
|
||||||
} from "~/db.server";
|
} from "~/db.server";
|
||||||
import { PrismaErrorSchema, prisma } from "~/db.server";
|
|
||||||
import type { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
import type { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||||
import { workerQueue } from "~/services/worker.server";
|
import { workerQueue } from "~/services/worker.server";
|
||||||
|
|
||||||
@@ -39,7 +39,8 @@ export class IngestSendEvent {
|
|||||||
public async call(
|
public async call(
|
||||||
environment: AuthenticatedEnvironment,
|
environment: AuthenticatedEnvironment,
|
||||||
event: RawEvent,
|
event: RawEvent,
|
||||||
options?: SendEventOptions
|
options?: SendEventOptions,
|
||||||
|
sourceContext?: { id: string; metadata?: any }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const deliverAt = this.#calculateDeliverAt(options);
|
const deliverAt = this.#calculateDeliverAt(options);
|
||||||
@@ -80,6 +81,7 @@ export class IngestSendEvent {
|
|||||||
payload: event.payload ?? {},
|
payload: event.payload ?? {},
|
||||||
context: event.context ?? {},
|
context: event.context ?? {},
|
||||||
source: event.source ?? "trigger.dev",
|
source: event.source ?? "trigger.dev",
|
||||||
|
sourceContext,
|
||||||
deliverAt: deliverAt,
|
deliverAt: deliverAt,
|
||||||
externalAccount: externalAccount
|
externalAccount: externalAccount
|
||||||
? {
|
? {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
RunJobResumeWithTask,
|
RunJobResumeWithTask,
|
||||||
RunJobRetryWithTask,
|
RunJobRetryWithTask,
|
||||||
RunJobSuccess,
|
RunJobSuccess,
|
||||||
|
RunSourceContextSchema,
|
||||||
} from "@trigger.dev/internal";
|
} from "@trigger.dev/internal";
|
||||||
import { generateErrorMessage } from "zod-error";
|
import { generateErrorMessage } from "zod-error";
|
||||||
import { EXECUTE_JOB_RETRY_LIMIT } from "~/consts";
|
import { EXECUTE_JOB_RETRY_LIMIT } from "~/consts";
|
||||||
@@ -242,6 +243,10 @@ export class PerformRunExecutionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sourceContext = RunSourceContextSchema.safeParse(
|
||||||
|
run.event.sourceContext
|
||||||
|
);
|
||||||
|
|
||||||
const { response, parser } = await client.executeJobRequest({
|
const { response, parser } = await client.executeJobRequest({
|
||||||
event,
|
event,
|
||||||
job: {
|
job: {
|
||||||
@@ -270,6 +275,7 @@ export class PerformRunExecutionService {
|
|||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
connections: connections.auth,
|
connections: connections.auth,
|
||||||
|
source: sourceContext.success ? sourceContext.data : undefined,
|
||||||
tasks: [run.tasks, resumedTask]
|
tasks: [run.tasks, resumedTask]
|
||||||
.flat()
|
.flat()
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
|||||||
@@ -47,14 +47,12 @@ export class DeliverScheduledEventService {
|
|||||||
id: eventId,
|
id: eventId,
|
||||||
name: SCHEDULED_EVENT,
|
name: SCHEDULED_EVENT,
|
||||||
payload,
|
payload,
|
||||||
context: {
|
|
||||||
source: {
|
|
||||||
id: scheduleSource.key,
|
|
||||||
metadata: scheduleSource.metadata,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{ accountId: scheduleSource.externalAccount?.identifier }
|
{ accountId: scheduleSource.externalAccount?.identifier },
|
||||||
|
{
|
||||||
|
id: scheduleSource.key,
|
||||||
|
metadata: scheduleSource.metadata,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const invokeDispatcherService = new InvokeDispatcherService(tx);
|
const invokeDispatcherService = new InvokeDispatcherService(tx);
|
||||||
|
|||||||
@@ -88,9 +88,19 @@ export class DeliverHttpSourceRequestService {
|
|||||||
const ingestService = new IngestSendEvent();
|
const ingestService = new IngestSendEvent();
|
||||||
|
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
await ingestService.call(httpSourceRequest.environment, event, {
|
await ingestService.call(
|
||||||
accountId: httpSourceRequest.source.externalAccount?.identifier,
|
httpSourceRequest.environment,
|
||||||
});
|
event,
|
||||||
|
{
|
||||||
|
accountId: httpSourceRequest.source.externalAccount?.identifier,
|
||||||
|
},
|
||||||
|
httpSourceRequest.source.dynamicSourceId
|
||||||
|
? {
|
||||||
|
id: httpSourceRequest.source.dynamicSourceId,
|
||||||
|
metadata: httpSourceRequest.source.dynamicSourceMetadata,
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ export class RegisterSourceService {
|
|||||||
endpointId: string,
|
endpointId: string,
|
||||||
metadata: SourceMetadata,
|
metadata: SourceMetadata,
|
||||||
dynamicTriggerId?: string,
|
dynamicTriggerId?: string,
|
||||||
accountId?: string
|
accountId?: string,
|
||||||
|
dynamicSource?: { id: string; metadata: any }
|
||||||
) {
|
) {
|
||||||
const endpoint = await this.#prismaClient.endpoint.findUniqueOrThrow({
|
const endpoint = await this.#prismaClient.endpoint.findUniqueOrThrow({
|
||||||
where: {
|
where: {
|
||||||
@@ -39,7 +40,8 @@ export class RegisterSourceService {
|
|||||||
endpoint.environment,
|
endpoint.environment,
|
||||||
metadata,
|
metadata,
|
||||||
dynamicTriggerId,
|
dynamicTriggerId,
|
||||||
accountId
|
accountId,
|
||||||
|
dynamicSource
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +50,8 @@ export class RegisterSourceService {
|
|||||||
environment: AuthenticatedEnvironment,
|
environment: AuthenticatedEnvironment,
|
||||||
metadata: SourceMetadata,
|
metadata: SourceMetadata,
|
||||||
dynamicTriggerId?: string,
|
dynamicTriggerId?: string,
|
||||||
accountId?: string
|
accountId?: string,
|
||||||
|
dynamicSource?: { id: string; metadata: any }
|
||||||
) {
|
) {
|
||||||
logger.debug("Upserting source", {
|
logger.debug("Upserting source", {
|
||||||
endpoint,
|
endpoint,
|
||||||
@@ -57,9 +60,9 @@ export class RegisterSourceService {
|
|||||||
accountId,
|
accountId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const key = dynamicTriggerId
|
const key = [dynamicTriggerId, dynamicSource?.id, metadata.key]
|
||||||
? `${dynamicTriggerId}:${metadata.key}`
|
.filter(Boolean)
|
||||||
: metadata.key;
|
.join(":");
|
||||||
|
|
||||||
const { id, orphanedEvents } = await $transaction(
|
const { id, orphanedEvents } = await $transaction(
|
||||||
this.#prismaClient,
|
this.#prismaClient,
|
||||||
@@ -143,6 +146,8 @@ export class RegisterSourceService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
dynamicSourceId: dynamicSource?.id,
|
||||||
|
dynamicSourceMetadata: dynamicSource?.metadata,
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
@@ -151,6 +156,8 @@ export class RegisterSourceService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
integration: { connect: { id: integration.id } },
|
integration: { connect: { id: integration.id } },
|
||||||
|
dynamicSourceId: dynamicSource?.id,
|
||||||
|
dynamicSourceMetadata: dynamicSource?.metadata,
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
events: true,
|
events: true,
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export class InitializeTriggerService {
|
|||||||
endpointSlug,
|
endpointSlug,
|
||||||
key: payload.id,
|
key: payload.id,
|
||||||
accountId: payload.accountId,
|
accountId: payload.accountId,
|
||||||
|
registrationMetadata: payload.metadata,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.#sendEvent.call(
|
await this.#sendEvent.call(
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export class RegisterTriggerSourceService {
|
|||||||
id,
|
id,
|
||||||
key,
|
key,
|
||||||
accountId,
|
accountId,
|
||||||
|
registrationMetadata,
|
||||||
}: {
|
}: {
|
||||||
environment: AuthenticatedEnvironment;
|
environment: AuthenticatedEnvironment;
|
||||||
payload: RegisterTriggerBody;
|
payload: RegisterTriggerBody;
|
||||||
@@ -30,6 +31,7 @@ export class RegisterTriggerSourceService {
|
|||||||
endpointSlug: string;
|
endpointSlug: string;
|
||||||
key: string;
|
key: string;
|
||||||
accountId?: string;
|
accountId?: string;
|
||||||
|
registrationMetadata?: any;
|
||||||
}): Promise<RegisterSourceEvent> {
|
}): Promise<RegisterSourceEvent> {
|
||||||
const endpoint = await this.#prismaClient.endpoint.findUniqueOrThrow({
|
const endpoint = await this.#prismaClient.endpoint.findUniqueOrThrow({
|
||||||
where: {
|
where: {
|
||||||
@@ -58,7 +60,8 @@ export class RegisterTriggerSourceService {
|
|||||||
endpoint.id,
|
endpoint.id,
|
||||||
payload.source,
|
payload.source,
|
||||||
dynamicTrigger.id,
|
dynamicTrigger.id,
|
||||||
accountId
|
accountId,
|
||||||
|
{ id: key, metadata: registrationMetadata }
|
||||||
);
|
);
|
||||||
|
|
||||||
const eventDispatcher = await tx.eventDispatcher.upsert({
|
const eventDispatcher = await tx.eventDispatcher.upsert({
|
||||||
@@ -104,8 +107,11 @@ export class RegisterTriggerSourceService {
|
|||||||
dynamicTriggerId: dynamicTrigger.id,
|
dynamicTriggerId: dynamicTrigger.id,
|
||||||
sourceId: triggerSource.id,
|
sourceId: triggerSource.id,
|
||||||
eventDispatcherId: eventDispatcher.id,
|
eventDispatcherId: eventDispatcher.id,
|
||||||
|
metadata: registrationMetadata,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
metadata: registrationMetadata,
|
||||||
},
|
},
|
||||||
update: {},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const secretStore = getSecretStore(
|
const secretStore = getSecretStore(
|
||||||
|
|||||||
@@ -245,6 +245,8 @@ new Job(client, {
|
|||||||
github: githubUser,
|
github: githubUser,
|
||||||
},
|
},
|
||||||
run: async (payload, io, ctx) => {
|
run: async (payload, io, ctx) => {
|
||||||
|
await io.logger.info("user-on-issue-opened", { ctx });
|
||||||
|
|
||||||
return await io.github.getRepo("get.repo", {
|
return await io.github.getRepo("get.repo", {
|
||||||
owner: payload.repository.owner.login,
|
owner: payload.repository.owner.login,
|
||||||
repo: payload.repository.name,
|
repo: payload.repository.name,
|
||||||
|
|||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "EventRecord" ADD COLUMN "sourceContext" JSONB;
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "DynamicTriggerRegistration" ADD COLUMN "metadata" JSONB;
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "TriggerSource" ADD COLUMN "dynamicSourceId" TEXT,
|
||||||
|
ADD COLUMN "dynamicSourceMetadata" JSONB;
|
||||||
@@ -577,12 +577,13 @@ enum JobStartPosition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model EventRecord {
|
model EventRecord {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
eventId String
|
eventId String
|
||||||
name String
|
name String
|
||||||
timestamp DateTime @default(now())
|
timestamp DateTime @default(now())
|
||||||
payload Json
|
payload Json
|
||||||
context Json?
|
context Json?
|
||||||
|
sourceContext Json?
|
||||||
|
|
||||||
source String @default("trigger.dev")
|
source String @default("trigger.dev")
|
||||||
|
|
||||||
@@ -853,6 +854,9 @@ model TriggerSource {
|
|||||||
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
externalAccount ExternalAccount? @relation(fields: [externalAccountId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||||
externalAccountId String?
|
externalAccountId String?
|
||||||
|
|
||||||
|
dynamicSourceId String?
|
||||||
|
dynamicSourceMetadata Json?
|
||||||
|
|
||||||
active Boolean @default(false)
|
active Boolean @default(false)
|
||||||
interactive Boolean @default(false)
|
interactive Boolean @default(false)
|
||||||
|
|
||||||
@@ -900,6 +904,8 @@ model DynamicTriggerRegistration {
|
|||||||
source TriggerSource @relation(fields: [sourceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
source TriggerSource @relation(fields: [sourceId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||||
sourceId String
|
sourceId String
|
||||||
|
|
||||||
|
metadata Json?
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
|||||||
@@ -238,6 +238,11 @@ export type RuntimeEnvironmentType = z.infer<
|
|||||||
typeof RuntimeEnvironmentTypeSchema
|
typeof RuntimeEnvironmentTypeSchema
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
export const RunSourceContextSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
metadata: z.any(),
|
||||||
|
});
|
||||||
|
|
||||||
export const RunJobBodySchema = z.object({
|
export const RunJobBodySchema = z.object({
|
||||||
event: ApiEventLogSchema,
|
event: ApiEventLogSchema,
|
||||||
job: z.object({
|
job: z.object({
|
||||||
@@ -265,6 +270,7 @@ export const RunJobBodySchema = z.object({
|
|||||||
metadata: z.any(),
|
metadata: z.any(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
|
source: RunSourceContextSchema.optional(),
|
||||||
tasks: z.array(CachedTaskSchema).optional(),
|
tasks: z.array(CachedTaskSchema).optional(),
|
||||||
connections: z.record(ConnectionAuthSchema).optional(),
|
connections: z.record(ConnectionAuthSchema).optional(),
|
||||||
});
|
});
|
||||||
@@ -496,6 +502,7 @@ export const InitializeTriggerBodySchema = z.object({
|
|||||||
id: z.string(),
|
id: z.string(),
|
||||||
params: z.any(),
|
params: z.any(),
|
||||||
accountId: z.string().optional(),
|
accountId: z.string().optional(),
|
||||||
|
metadata: z.any().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
export type InitializeTriggerBody = z.infer<typeof InitializeTriggerBodySchema>;
|
export type InitializeTriggerBody = z.infer<typeof InitializeTriggerBodySchema>;
|
||||||
|
|||||||
@@ -638,7 +638,7 @@ export class TriggerClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#createRunContext(execution: RunJobBody): TriggerContext {
|
#createRunContext(execution: RunJobBody): TriggerContext {
|
||||||
const { event, organization, environment, job, run } = execution;
|
const { event, organization, environment, job, run, source } = execution;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
event: {
|
event: {
|
||||||
@@ -652,6 +652,7 @@ export class TriggerClient {
|
|||||||
job,
|
job,
|
||||||
run,
|
run,
|
||||||
account: execution.account,
|
account: execution.account,
|
||||||
|
source,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,6 @@ export class DynamicTrigger<
|
|||||||
}
|
}
|
||||||
|
|
||||||
get preprocessRuns() {
|
get preprocessRuns() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export interface TriggerContext {
|
|||||||
run: { id: string; isTest: boolean; startedAt: Date };
|
run: { id: string; isTest: boolean; startedAt: Date };
|
||||||
event: { id: string; name: string; context: any; timestamp: Date };
|
event: { id: string; name: string; context: any; timestamp: Date };
|
||||||
account?: { id: string; metadata?: any };
|
account?: { id: string; metadata?: any };
|
||||||
|
source?: { id: string; metadata?: any };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TriggerPreprocessContext {
|
export interface TriggerPreprocessContext {
|
||||||
|
|||||||
Generated
+115
-346
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user