* Issue #377: only expose the external eventId in the API * Create eighty-zebras-bow.md
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@trigger.dev/core": patch
|
||||||
|
"@trigger.dev/sdk": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Issue #377: only expose the external eventId in the API
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { ApiEventLog } from "@trigger.dev/core";
|
||||||
|
import { EventRecord } from "@trigger.dev/database";
|
||||||
|
|
||||||
|
export function eventRecordToApiJson(eventRecord: EventRecord): ApiEventLog {
|
||||||
|
return {
|
||||||
|
id: eventRecord.eventId,
|
||||||
|
name: eventRecord.name,
|
||||||
|
payload: eventRecord.payload as any,
|
||||||
|
context: eventRecord.context as any,
|
||||||
|
timestamp: eventRecord.timestamp,
|
||||||
|
deliverAt: eventRecord.deliverAt,
|
||||||
|
deliveredAt: eventRecord.deliveredAt,
|
||||||
|
cancelledAt: eventRecord.cancelledAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { ActionArgs } from "@remix-run/server-runtime";
|
import type { ActionArgs } from "@remix-run/server-runtime";
|
||||||
import { json } from "@remix-run/server-runtime";
|
import { json } from "@remix-run/server-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { eventRecordToApiJson } from "~/api.server";
|
||||||
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
||||||
import { CancelEventService } from "~/services/events/cancelEvent.server";
|
import { CancelEventService } from "~/services/events/cancelEvent.server";
|
||||||
import { logger } from "~/services/logger.server";
|
import { logger } from "~/services/logger.server";
|
||||||
@@ -40,7 +41,7 @@ export async function action({ request, params }: ActionArgs) {
|
|||||||
return json({ error: "Event not found" }, { status: 404 });
|
return json({ error: "Event not found" }, { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
return json(updatedEvent);
|
return json(eventRecordToApiJson(updatedEvent));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error("CancelEventService.call() error", {
|
logger.error("CancelEventService.call() error", {
|
||||||
error: err,
|
error: err,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ActionArgs, LoaderArgs } from "@remix-run/server-runtime";
|
import type { LoaderArgs } from "@remix-run/server-runtime";
|
||||||
import { json } from "@remix-run/server-runtime";
|
import { json } from "@remix-run/server-runtime";
|
||||||
import { cors } from "remix-utils";
|
import { GetEvent } from "@trigger.dev/core";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { prisma } from "~/db.server";
|
import { prisma } from "~/db.server";
|
||||||
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
||||||
@@ -32,9 +32,36 @@ export async function loader({ request, params }: LoaderArgs) {
|
|||||||
|
|
||||||
const { eventId } = parsed.data;
|
const { eventId } = parsed.data;
|
||||||
|
|
||||||
const event = await prisma.eventRecord.findFirst({
|
const event = await findEventRecord(eventId, authenticatedEnv.id);
|
||||||
|
|
||||||
|
if (!event) {
|
||||||
|
return apiCors(request, json({ error: "Event not found" }, { status: 404 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiCors(request, json(toJSON(event)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function toJSON(eventRecord: FoundEventRecord): GetEvent {
|
||||||
|
return {
|
||||||
|
id: eventRecord.eventId,
|
||||||
|
name: eventRecord.name,
|
||||||
|
createdAt: eventRecord.createdAt,
|
||||||
|
updatedAt: eventRecord.updatedAt,
|
||||||
|
runs: eventRecord.runs.map((run) => ({
|
||||||
|
id: run.id,
|
||||||
|
status: run.status,
|
||||||
|
startedAt: run.startedAt,
|
||||||
|
completedAt: run.completedAt,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type FoundEventRecord = NonNullable<Awaited<ReturnType<typeof findEventRecord>>>;
|
||||||
|
|
||||||
|
async function findEventRecord(eventId: string, environmentId: string) {
|
||||||
|
return await prisma.eventRecord.findUnique({
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
eventId: true,
|
||||||
name: true,
|
name: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
@@ -48,14 +75,10 @@ export async function loader({ request, params }: LoaderArgs) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
id: eventId,
|
eventId_environmentId: {
|
||||||
environmentId: authenticatedEnv.id,
|
eventId,
|
||||||
|
environmentId,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!event) {
|
|
||||||
return apiCors(request, json({ error: "Event not found" }, { status: 404 }));
|
|
||||||
}
|
|
||||||
|
|
||||||
return apiCors(request, json(event));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { SendEventBodySchema } from "@trigger.dev/core";
|
|||||||
import { generateErrorMessage } from "zod-error";
|
import { generateErrorMessage } from "zod-error";
|
||||||
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
||||||
import { IngestSendEvent } from "~/services/events/ingestSendEvent.server";
|
import { IngestSendEvent } from "~/services/events/ingestSendEvent.server";
|
||||||
|
import { eventRecordToApiJson } from "~/api.server";
|
||||||
|
|
||||||
export async function action({ request }: ActionArgs) {
|
export async function action({ request }: ActionArgs) {
|
||||||
// Ensure this is a POST request
|
// Ensure this is a POST request
|
||||||
@@ -33,5 +34,9 @@ export async function action({ request }: ActionArgs) {
|
|||||||
|
|
||||||
const event = await service.call(authenticatedEnv, body.data.event, body.data.options);
|
const event = await service.call(authenticatedEnv, body.data.event, body.data.options);
|
||||||
|
|
||||||
return json(event);
|
if (!event) {
|
||||||
|
return json({ error: "Failed to create event" }, { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return json(eventRecordToApiJson(event));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
ApiEventLogSchema,
|
|
||||||
CachedTaskSchema,
|
CachedTaskSchema,
|
||||||
RunJobError,
|
RunJobError,
|
||||||
RunJobResumeWithTask,
|
RunJobResumeWithTask,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
} from "@trigger.dev/core";
|
} from "@trigger.dev/core";
|
||||||
import type { Task } from "@trigger.dev/database";
|
import type { Task } from "@trigger.dev/database";
|
||||||
import { generateErrorMessage } from "zod-error";
|
import { generateErrorMessage } from "zod-error";
|
||||||
|
import { eventRecordToApiJson } from "~/api.server";
|
||||||
import { EXECUTE_JOB_RETRY_LIMIT } from "~/consts";
|
import { EXECUTE_JOB_RETRY_LIMIT } from "~/consts";
|
||||||
import { $transaction, PrismaClient, PrismaClientOrTransaction, prisma } from "~/db.server";
|
import { $transaction, PrismaClient, PrismaClientOrTransaction, prisma } from "~/db.server";
|
||||||
import { enqueueRunExecutionV1 } from "~/models/jobRunExecution.server";
|
import { enqueueRunExecutionV1 } from "~/models/jobRunExecution.server";
|
||||||
@@ -54,7 +54,7 @@ export class PerformRunExecutionV1Service {
|
|||||||
const { run } = execution;
|
const { run } = execution;
|
||||||
|
|
||||||
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
||||||
const event = ApiEventLogSchema.parse({ ...run.event, id: run.eventId });
|
const event = eventRecordToApiJson(run.event);
|
||||||
const startedAt = new Date();
|
const startedAt = new Date();
|
||||||
|
|
||||||
await this.#prismaClient.jobRunExecution.update({
|
await this.#prismaClient.jobRunExecution.update({
|
||||||
@@ -174,7 +174,7 @@ export class PerformRunExecutionV1Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
||||||
const event = ApiEventLogSchema.parse({ ...run.event, id: run.eventId });
|
const event = eventRecordToApiJson(run.event);
|
||||||
|
|
||||||
const startedAt = new Date();
|
const startedAt = new Date();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
ApiEventLogSchema,
|
|
||||||
CachedTask,
|
CachedTask,
|
||||||
RunJobError,
|
RunJobError,
|
||||||
RunJobResumeWithTask,
|
RunJobResumeWithTask,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
} from "@trigger.dev/core";
|
} from "@trigger.dev/core";
|
||||||
import type { Task } from "@trigger.dev/database";
|
import type { Task } from "@trigger.dev/database";
|
||||||
import { generateErrorMessage } from "zod-error";
|
import { generateErrorMessage } from "zod-error";
|
||||||
|
import { eventRecordToApiJson } from "~/api.server";
|
||||||
import { $transaction, PrismaClient, PrismaClientOrTransaction, prisma } from "~/db.server";
|
import { $transaction, PrismaClient, PrismaClientOrTransaction, prisma } from "~/db.server";
|
||||||
import { enqueueRunExecutionV2 } from "~/models/jobRunExecution.server";
|
import { enqueueRunExecutionV2 } from "~/models/jobRunExecution.server";
|
||||||
import { resolveRunConnections } from "~/models/runConnection.server";
|
import { resolveRunConnections } from "~/models/runConnection.server";
|
||||||
@@ -57,7 +57,7 @@ export class PerformRunExecutionV2Service {
|
|||||||
// the run execution will be marked as failed and the run will start
|
// the run execution will be marked as failed and the run will start
|
||||||
async #executePreprocessing(run: FoundRun) {
|
async #executePreprocessing(run: FoundRun) {
|
||||||
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
||||||
const event = ApiEventLogSchema.parse({ ...run.event, id: run.eventId });
|
const event = eventRecordToApiJson(run.event);
|
||||||
|
|
||||||
const { response, parser } = await client.preprocessRunRequest({
|
const { response, parser } = await client.preprocessRunRequest({
|
||||||
event,
|
event,
|
||||||
@@ -146,7 +146,7 @@ export class PerformRunExecutionV2Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
const client = new EndpointApi(run.environment.apiKey, run.endpoint.url);
|
||||||
const event = ApiEventLogSchema.parse({ ...run.event, id: run.eventId });
|
const event = eventRecordToApiJson(run.event);
|
||||||
|
|
||||||
const startedAt = new Date();
|
const startedAt = new Date();
|
||||||
|
|
||||||
|
|||||||
@@ -39,15 +39,19 @@ client.defineJob({
|
|||||||
run: async (payload, io, ctx) => {
|
run: async (payload, io, ctx) => {
|
||||||
await io.sendEvent(
|
await io.sendEvent(
|
||||||
"send-event",
|
"send-event",
|
||||||
{ name: "Cancellable Event", id: payload.id },
|
{ name: "Cancellable Event", id: payload.id, payload: { payload, ctx } },
|
||||||
{
|
{
|
||||||
deliverAt: new Date(Date.now() + 1000 * 60 * 60 * 24), // 24 hours from now
|
deliverAt: new Date(Date.now() + 1000 * 60 * 60 * 24), // 24 hours from now
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await io.getEvent("get-event", payload.id);
|
||||||
|
|
||||||
await io.wait("wait-1", 60); // 1 minute
|
await io.wait("wait-1", 60); // 1 minute
|
||||||
|
|
||||||
await io.cancelEvent("cancel-event", payload.id);
|
await io.cancelEvent("cancel-event", payload.id);
|
||||||
|
|
||||||
|
await io.getEvent("get-event-2", payload.id);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,9 @@ export const ApiEventLogSchema = z.object({
|
|||||||
/** The timestamp when the event was delivered. Is `undefined` if `deliverAt`
|
/** The timestamp when the event was delivered. Is `undefined` if `deliverAt`
|
||||||
or `deliverAfter` were set when sending the event. */
|
or `deliverAfter` were set when sending the event. */
|
||||||
deliveredAt: z.coerce.date().optional().nullable(),
|
deliveredAt: z.coerce.date().optional().nullable(),
|
||||||
|
/** The timestamp when the event was cancelled. Is `undefined` if the event
|
||||||
|
* wasn't cancelled. */
|
||||||
|
cancelledAt: z.coerce.date().optional().nullable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ApiEventLog = z.infer<typeof ApiEventLogSchema>;
|
export type ApiEventLog = z.infer<typeof ApiEventLogSchema>;
|
||||||
@@ -424,15 +427,6 @@ export const PreprocessRunResponseSchema = z.object({
|
|||||||
|
|
||||||
export type PreprocessRunResponse = z.infer<typeof PreprocessRunResponseSchema>;
|
export type PreprocessRunResponse = z.infer<typeof PreprocessRunResponseSchema>;
|
||||||
|
|
||||||
export const CreateRunBodySchema = z.object({
|
|
||||||
client: z.string(),
|
|
||||||
job: JobMetadataSchema,
|
|
||||||
event: ApiEventLogSchema,
|
|
||||||
properties: z.array(DisplayPropertySchema).optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type CreateRunBody = z.infer<typeof CreateRunBodySchema>;
|
|
||||||
|
|
||||||
const CreateRunResponseOkSchema = z.object({
|
const CreateRunResponseOkSchema = z.object({
|
||||||
ok: z.literal(true),
|
ok: z.literal(true),
|
||||||
data: z.object({
|
data: z.object({
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import {
|
|||||||
ApiEventLogSchema,
|
ApiEventLogSchema,
|
||||||
CompleteTaskBodyInput,
|
CompleteTaskBodyInput,
|
||||||
ConnectionAuthSchema,
|
ConnectionAuthSchema,
|
||||||
CreateRunBody,
|
|
||||||
CreateRunResponseBodySchema,
|
|
||||||
FailTaskBodyInput,
|
FailTaskBodyInput,
|
||||||
GetEventSchema,
|
GetEventSchema,
|
||||||
GetRunOptionsWithTaskDetails,
|
GetRunOptionsWithTaskDetails,
|
||||||
@@ -105,23 +103,6 @@ export class ApiClient {
|
|||||||
return await response.json();
|
return await response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
async createRun(params: CreateRunBody) {
|
|
||||||
const apiKey = await this.#apiKey();
|
|
||||||
|
|
||||||
this.#logger.debug("Creating run", {
|
|
||||||
params,
|
|
||||||
});
|
|
||||||
|
|
||||||
return await zodfetch(CreateRunResponseBodySchema, `${this.#apiUrl}/api/v1/runs`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${apiKey}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify(params),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async runTask(runId: string, task: RunTaskBodyInput) {
|
async runTask(runId: string, task: RunTaskBodyInput) {
|
||||||
const apiKey = await this.#apiKey();
|
const apiKey = await this.#apiKey();
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,25 @@ export class IO {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getEvent(key: string | any[], id: string) {
|
||||||
|
return await this.runTask(
|
||||||
|
key,
|
||||||
|
{
|
||||||
|
name: "getEvent",
|
||||||
|
params: { id },
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
label: "id",
|
||||||
|
text: id,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (task) => {
|
||||||
|
return await this._triggerClient.getEvent(id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/** `io.cancelEvent()` allows you to cancel an event that was previously sent with `io.sendEvent()`. This will prevent any Jobs from running that are listening for that event if the event was sent with a delay
|
/** `io.cancelEvent()` allows you to cancel an event that was previously sent with `io.sendEvent()`. This will prevent any Jobs from running that are listening for that event if the event was sent with a delay
|
||||||
* @param key
|
* @param key
|
||||||
* @param eventId
|
* @param eventId
|
||||||
|
|||||||
Reference in New Issue
Block a user