Issue #377: only expose the external eventId in the API (#380)

* Issue #377: only expose the external eventId in the API

* Create eighty-zebras-bow.md
This commit is contained in:
Eric Allam
2023-08-22 10:46:46 +01:00
committed by GitHub
parent b5db9f5e5c
commit 302bd02ff1
11 changed files with 97 additions and 49 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"@trigger.dev/core": patch
"@trigger.dev/sdk": patch
---
Issue #377: only expose the external eventId in the API
+15
View File
@@ -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 { json } from "@remix-run/server-runtime";
import { z } from "zod";
import { eventRecordToApiJson } from "~/api.server";
import { authenticateApiRequest } from "~/services/apiAuth.server";
import { CancelEventService } from "~/services/events/cancelEvent.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(updatedEvent);
return json(eventRecordToApiJson(updatedEvent));
} catch (err) {
logger.error("CancelEventService.call() error", {
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 { cors } from "remix-utils";
import { GetEvent } from "@trigger.dev/core";
import { z } from "zod";
import { prisma } from "~/db.server";
import { authenticateApiRequest } from "~/services/apiAuth.server";
@@ -32,9 +32,36 @@ export async function loader({ request, params }: LoaderArgs) {
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: {
id: true,
eventId: true,
name: true,
createdAt: true,
updatedAt: true,
@@ -48,14 +75,10 @@ export async function loader({ request, params }: LoaderArgs) {
},
},
where: {
id: eventId,
environmentId: authenticatedEnv.id,
eventId_environmentId: {
eventId,
environmentId,
},
},
});
if (!event) {
return apiCors(request, json({ error: "Event not found" }, { status: 404 }));
}
return apiCors(request, json(event));
}
+6 -1
View File
@@ -4,6 +4,7 @@ import { SendEventBodySchema } from "@trigger.dev/core";
import { generateErrorMessage } from "zod-error";
import { authenticateApiRequest } from "~/services/apiAuth.server";
import { IngestSendEvent } from "~/services/events/ingestSendEvent.server";
import { eventRecordToApiJson } from "~/api.server";
export async function action({ request }: ActionArgs) {
// 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);
return json(event);
if (!event) {
return json({ error: "Failed to create event" }, { status: 500 });
}
return json(eventRecordToApiJson(event));
}
@@ -1,5 +1,4 @@
import {
ApiEventLogSchema,
CachedTaskSchema,
RunJobError,
RunJobResumeWithTask,
@@ -9,6 +8,7 @@ import {
} from "@trigger.dev/core";
import type { Task } from "@trigger.dev/database";
import { generateErrorMessage } from "zod-error";
import { eventRecordToApiJson } from "~/api.server";
import { EXECUTE_JOB_RETRY_LIMIT } from "~/consts";
import { $transaction, PrismaClient, PrismaClientOrTransaction, prisma } from "~/db.server";
import { enqueueRunExecutionV1 } from "~/models/jobRunExecution.server";
@@ -54,7 +54,7 @@ export class PerformRunExecutionV1Service {
const { run } = execution;
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();
await this.#prismaClient.jobRunExecution.update({
@@ -174,7 +174,7 @@ export class PerformRunExecutionV1Service {
}
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();
@@ -1,5 +1,4 @@
import {
ApiEventLogSchema,
CachedTask,
RunJobError,
RunJobResumeWithTask,
@@ -9,6 +8,7 @@ import {
} from "@trigger.dev/core";
import type { Task } from "@trigger.dev/database";
import { generateErrorMessage } from "zod-error";
import { eventRecordToApiJson } from "~/api.server";
import { $transaction, PrismaClient, PrismaClientOrTransaction, prisma } from "~/db.server";
import { enqueueRunExecutionV2 } from "~/models/jobRunExecution.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
async #executePreprocessing(run: FoundRun) {
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({
event,
@@ -146,7 +146,7 @@ export class PerformRunExecutionV2Service {
}
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();
+5 -1
View File
@@ -39,15 +39,19 @@ client.defineJob({
run: async (payload, io, ctx) => {
await io.sendEvent(
"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
}
);
await io.getEvent("get-event", payload.id);
await io.wait("wait-1", 60); // 1 minute
await io.cancelEvent("cancel-event", payload.id);
await io.getEvent("get-event-2", payload.id);
},
});
+3 -9
View File
@@ -257,6 +257,9 @@ export const ApiEventLogSchema = z.object({
/** The timestamp when the event was delivered. Is `undefined` if `deliverAt`
or `deliverAfter` were set when sending the event. */
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>;
@@ -424,15 +427,6 @@ export const PreprocessRunResponseSchema = z.object({
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({
ok: z.literal(true),
data: z.object({
-19
View File
@@ -3,8 +3,6 @@ import {
ApiEventLogSchema,
CompleteTaskBodyInput,
ConnectionAuthSchema,
CreateRunBody,
CreateRunResponseBodySchema,
FailTaskBodyInput,
GetEventSchema,
GetRunOptionsWithTaskDetails,
@@ -105,23 +103,6 @@ export class ApiClient {
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) {
const apiKey = await this.#apiKey();
+19
View File
@@ -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
* @param key
* @param eventId