Compare commits

...

7 Commits

Author SHA1 Message Date
Eric Allam babe1c0e54 Fix pnpm lock file 2024-01-10 10:58:07 +00:00
github-actions[bot] 1224fceb18 chore: Update version for release (#831)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-01-10 10:57:32 +00:00
Eric Allam 8277f4d249 Use correct overload param when invoking a job outside of a run (fixes #802) 2024-01-10 10:50:12 +00:00
Eric Allam 73cb8839a5 Fixed invoke inferred payload types (fix #830) 2024-01-10 10:44:35 +00:00
Matt Aitken 5d0a731cf6 Event page tweaks (#826)
🚀 Publish Trigger.dev Docker / typecheck (push) Failing after 1s
🚀 Publish Trigger.dev Docker / e2e (push) Failing after 3s
🚀 Publish Trigger.dev Docker / units (push) Failing after 10s
🚀 Publish Trigger.dev Docker / publish (push) Has been skipped
* Don’t show internal events

* Show the cancelled time

* Made the Pagination component accept any compatible list type

* Changed some wording on the event detail page
2024-01-05 12:39:27 +00:00
Kritik Jiyaviya 25a152517e feat: Events list page (#824)
* feat: add events list

* Changed the Events icon in the sidemenu

---------

Co-authored-by: Matt Aitken <matt@mattaitken.com>
2024-01-05 12:04:31 +00:00
Matt Aitken d1092fcd2c Run filtering now works on the job runs page too (#823)
🚀 Publish Trigger.dev Docker / typecheck (push) Failing after 3s
🚀 Publish Trigger.dev Docker / e2e (push) Failing after 3s
🚀 Publish Trigger.dev Docker / units (push) Failing after 4s
🚀 Publish Trigger.dev Docker / publish (push) Has been skipped
* Run filtering is now shared: runs page and job runs page

* Use optimistic location

* Improved the type in the run status filter dropdown

* Organize imports
2024-01-03 15:50:45 +00:00
87 changed files with 1394 additions and 459 deletions
@@ -0,0 +1,45 @@
import { CodeBlock } from "../code/CodeBlock";
import { DateTime } from "../primitives/DateTime";
import { Header3 } from "../primitives/Headers";
import {
RunPanel,
RunPanelBody,
RunPanelDivider,
RunPanelIconProperty,
RunPanelIconSection,
} from "~/components/run/RunCard";
import { Event } from "~/presenters/EventPresenter.server";
export function EventDetail({ event }: { event: Event }) {
const { id, name, payload, context, timestamp, deliveredAt } = event;
return (
<RunPanel selected={false}>
<RunPanelBody>
<RunPanelIconSection>
<RunPanelIconProperty
icon="calendar"
label="Created"
value={<DateTime date={timestamp} />}
/>
{deliveredAt && (
<RunPanelIconProperty
icon="flag"
label="Delivered"
value={<DateTime date={deliveredAt} />}
/>
)}
<RunPanelIconProperty icon="id" label="Event name" value={name} />
<RunPanelIconProperty icon="account" label="Event ID" value={id} />
</RunPanelIconSection>
<RunPanelDivider />
<div className="mt-4 flex flex-col gap-2">
<Header3>Payload</Header3>
<CodeBlock code={payload} />
<Header3>Context</Header3>
<CodeBlock code={context} />
</div>
</RunPanelBody>
</RunPanel>
);
}
@@ -0,0 +1,8 @@
import { z } from "zod";
import { DirectionSchema, FilterableEnvironment } from "~/components/runs/RunStatuses";
export const EventListSearchSchema = z.object({
cursor: z.string().optional(),
direction: DirectionSchema.optional(),
environment: FilterableEnvironment.optional(),
});
@@ -0,0 +1,67 @@
import { useNavigate } from "@remix-run/react";
import { useOptimisticLocation } from "~/hooks/useOptimisticLocation";
import { EnvironmentLabel } from "../environments/EnvironmentLabel";
import { Paragraph } from "../primitives/Paragraph";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "../primitives/Select";
import { EventListSearchSchema } from "./EventStatuses";
import { environmentKeys, FilterableEnvironment } from "~/components/runs/RunStatuses";
export function EventsFilters() {
const navigate = useNavigate();
const location = useOptimisticLocation();
const searchParams = new URLSearchParams(location.search);
const { environment } = EventListSearchSchema.parse(Object.fromEntries(searchParams.entries()));
const handleFilterChange = (filterType: string, value: string | undefined) => {
if (value) {
searchParams.set(filterType, value);
} else {
searchParams.delete(filterType);
}
searchParams.delete("cursor");
searchParams.delete("direction");
navigate(`${location.pathname}?${searchParams.toString()}`);
};
const handleEnvironmentChange = (value: FilterableEnvironment | "ALL") => {
handleFilterChange("environment", value === "ALL" ? undefined : value);
};
return (
<div className="flex flex-row justify-between gap-x-2">
<SelectGroup>
<Select
name="environment"
value={environment ?? "ALL"}
onValueChange={handleEnvironmentChange}
>
<SelectTrigger size="secondary/small" width="full">
<SelectValue placeholder={"Select environment"} className="ml-2 p-0" />
</SelectTrigger>
<SelectContent>
<SelectItem value={"ALL"}>
<Paragraph variant="extra-small" className="pl-0.5">
All environments
</Paragraph>
</SelectItem>
{environmentKeys.map((env) => (
<SelectItem key={env} value={env}>
<div className="flex items-center gap-x-2">
<EnvironmentLabel environment={{ type: env }} />
<Paragraph variant="extra-small">environment</Paragraph>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</SelectGroup>
</div>
);
}
@@ -0,0 +1,134 @@
import { StopIcon } from "@heroicons/react/24/outline";
import { CheckIcon } from "@heroicons/react/24/solid";
import { RuntimeEnvironmentType, User } from "@trigger.dev/database";
import { EnvironmentLabel } from "../environments/EnvironmentLabel";
import { DateTime } from "../primitives/DateTime";
import { Paragraph } from "../primitives/Paragraph";
import { Spinner } from "../primitives/Spinner";
import {
Table,
TableBlankRow,
TableBody,
TableCell,
TableCellChevron,
TableHeader,
TableHeaderCell,
TableRow,
} from "../primitives/Table";
type EventTableItem = {
id: string;
name: string | null;
environment: {
type: RuntimeEnvironmentType;
userId?: string;
userName?: string;
};
createdAt: Date | null;
isTest: boolean;
deliverAt: Date | null;
deliveredAt: Date | null;
cancelledAt: Date | null;
runs: number;
};
type EventsTableProps = {
total: number;
hasFilters: boolean;
events: EventTableItem[];
isLoading?: boolean;
eventsParentPath: string;
currentUser: User;
};
export function EventsTable({
total,
hasFilters,
events,
isLoading = false,
eventsParentPath,
currentUser,
}: EventsTableProps) {
return (
<Table>
<TableHeader>
<TableRow>
<TableHeaderCell>Event</TableHeaderCell>
<TableHeaderCell>Env</TableHeaderCell>
<TableHeaderCell>Received Time</TableHeaderCell>
<TableHeaderCell>Delivery Time</TableHeaderCell>
<TableHeaderCell>Delivered</TableHeaderCell>
<TableHeaderCell>Canceled Time</TableHeaderCell>
<TableHeaderCell>Test</TableHeaderCell>
<TableHeaderCell>Runs</TableHeaderCell>
<TableHeaderCell>
<span className="sr-only">Go to page</span>
</TableHeaderCell>
</TableRow>
</TableHeader>
<TableBody>
{total === 0 && !hasFilters ? (
<TableBlankRow colSpan={9}>
<NoEvents title="No events found" />
</TableBlankRow>
) : events.length === 0 ? (
<TableBlankRow colSpan={9}>
<NoEvents title="No events match your filters" />
</TableBlankRow>
) : (
events.map((event) => {
const path = `${eventsParentPath}/events/${event.id}`;
const usernameForEnv =
currentUser.id !== event.environment.userId ? event.environment.userName : undefined;
return (
<TableRow key={event.id}>
<TableCell to={path}>{typeof event.name === "string" ? event.name : "-"}</TableCell>
<TableCell to={path}>
<EnvironmentLabel environment={event.environment} userName={usernameForEnv} />
</TableCell>
<TableCell to={path}>
{event.createdAt ? <DateTime date={event.createdAt} /> : ""}
</TableCell>
<TableCell to={path}>
{event.deliverAt ? <DateTime date={event.deliverAt} /> : ""}
</TableCell>
<TableCell to={path}>
{event.deliveredAt ? <DateTime date={event.deliveredAt} /> : ""}
</TableCell>
<TableCell to={path}>
{event.cancelledAt ? <DateTime date={event.cancelledAt} /> : ""}
</TableCell>
<TableCell to={path}>
{event.isTest ? (
<CheckIcon className="h-4 w-4 text-slate-400" />
) : (
<StopIcon className="h-4 w-4 text-slate-850" />
)}
</TableCell>
<TableCell to={path}>{event.runs}</TableCell>
<TableCellChevron to={path} isSticky />
</TableRow>
);
})
)}
{isLoading && (
<TableBlankRow
colSpan={8}
className="absolute left-0 top-0 flex h-full w-full items-center justify-center gap-2 bg-slate-900/90"
>
<Spinner /> <span className="text-dimmed">Loading</span>
</TableBlankRow>
)}
</TableBody>
</Table>
);
}
function NoEvents({ title }: { title: string }) {
return (
<div className="flex items-center justify-center">
<Paragraph className="w-auto">{title}</Paragraph>
</div>
);
}
@@ -3,6 +3,7 @@ import {
ArrowRightIcon,
ArrowRightOnRectangleIcon,
ChartBarIcon,
CursorArrowRaysIcon,
EllipsisHorizontalIcon,
} from "@heroicons/react/20/solid";
import { UserGroupIcon, UserPlusIcon } from "@heroicons/react/24/solid";
@@ -31,6 +32,7 @@ import {
projectHttpEndpointsPath,
projectPath,
projectRunsPath,
projectEventsPath,
projectSetupPath,
projectTriggersPath,
} from "~/utils/pathBuilder";
@@ -144,6 +146,12 @@ export function SideMenu({ user, project, organization, organizations }: SideMen
data-action="triggers"
hasWarning={project.hasInactiveExternalTriggers}
/>
<SideMenuItem
name="Events"
icon={CursorArrowRaysIcon}
iconColor="text-sky-500"
to={projectEventsPath(organization, project)}
/>
<SideMenuItem
name="HTTP endpoints"
icon="http-endpoint"
@@ -0,0 +1,194 @@
import {
CheckCircleIcon,
ClockIcon,
ExclamationTriangleIcon,
NoSymbolIcon,
PauseCircleIcon,
XCircleIcon,
} from "@heroicons/react/20/solid";
import { useNavigate } from "@remix-run/react";
import { useOptimisticLocation } from "~/hooks/useOptimisticLocation";
import { cn } from "~/utils/cn";
import { EnvironmentLabel } from "../environments/EnvironmentLabel";
import { Paragraph } from "../primitives/Paragraph";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "../primitives/Select";
import { Spinner } from "../primitives/Spinner";
import {
FilterableEnvironment,
FilterableStatus,
RunListSearchSchema,
environmentKeys,
statusKeys,
} from "./RunStatuses";
export function RunsFilters() {
const navigate = useNavigate();
const location = useOptimisticLocation();
const searchParams = new URLSearchParams(location.search);
const { environment, status } = RunListSearchSchema.parse(
Object.fromEntries(searchParams.entries())
);
const handleFilterChange = (filterType: string, value: string | undefined) => {
if (value) {
searchParams.set(filterType, value);
} else {
searchParams.delete(filterType);
}
searchParams.delete("cursor");
searchParams.delete("direction");
navigate(`${location.pathname}?${searchParams.toString()}`);
};
const handleStatusChange = (value: FilterableStatus | "ALL") => {
handleFilterChange("status", value === "ALL" ? undefined : value);
};
const handleEnvironmentChange = (value: FilterableEnvironment | "ALL") => {
handleFilterChange("environment", value === "ALL" ? undefined : value);
};
return (
<div className="flex flex-row justify-between gap-x-2">
<SelectGroup>
<Select
name="environment"
value={environment ?? "ALL"}
onValueChange={handleEnvironmentChange}
>
<SelectTrigger size="secondary/small" width="full">
<SelectValue placeholder={"Select environment"} className="ml-2 p-0" />
</SelectTrigger>
<SelectContent>
<SelectItem value={"ALL"}>
<Paragraph variant="extra-small" className="pl-0.5">
All environments
</Paragraph>
</SelectItem>
{environmentKeys.map((env) => (
<SelectItem key={env} value={env}>
<div className="flex items-center gap-x-2">
<EnvironmentLabel environment={{ type: env }} />
<Paragraph variant="extra-small">environment</Paragraph>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</SelectGroup>
<SelectGroup>
<Select name="status" value={status ?? "ALL"} onValueChange={handleStatusChange}>
<SelectTrigger size="secondary/small" width="full">
<SelectValue placeholder="Select status" className="ml-2 p-0" />
</SelectTrigger>
<SelectContent>
<SelectItem value={"ALL"}>
<Paragraph variant="extra-small" className="pl-0.5">
All statuses
</Paragraph>
</SelectItem>
{statusKeys.map((status) => (
<SelectItem key={status} value={status}>
{
<span className="flex items-center gap-1 text-xs">
<FilterStatusIcon status={status} className="h-4 w-4" />
<FilterStatusLabel status={status} />
</span>
}
</SelectItem>
))}
</SelectContent>
</Select>
</SelectGroup>
</div>
);
}
export function FilterStatusLabel({ status }: { status: FilterableStatus }) {
return <span className={filterStatusClassNameColor(status)}>{filterStatusTitle(status)}</span>;
}
export function FilterStatusIcon({
status,
className,
}: {
status: FilterableStatus;
className: string;
}) {
switch (status) {
case "COMPLETED":
return <CheckCircleIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "WAITING":
return <ClockIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "QUEUED":
return <PauseCircleIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "IN_PROGRESS":
return <Spinner className={cn(filterStatusClassNameColor(status), className)} />;
case "TIMEDOUT":
return (
<ExclamationTriangleIcon className={cn(filterStatusClassNameColor(status), className)} />
);
case "CANCELED":
return <NoSymbolIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "FAILED":
return <XCircleIcon className={cn(filterStatusClassNameColor(status), className)} />;
default: {
const _exhaustiveCheck: never = status;
throw new Error(`Non-exhaustive match for value: ${status}`);
}
}
}
export function filterStatusTitle(status: FilterableStatus): string {
switch (status) {
case "QUEUED":
return "Queued";
case "IN_PROGRESS":
return "In progress";
case "WAITING":
return "Waiting";
case "COMPLETED":
return "Completed";
case "FAILED":
return "Failed";
case "CANCELED":
return "Canceled";
case "TIMEDOUT":
return "Timed out";
default: {
const _exhaustiveCheck: never = status;
throw new Error(`Non-exhaustive match for value: ${status}`);
}
}
}
export function filterStatusClassNameColor(status: FilterableStatus): string {
switch (status) {
case "QUEUED":
return "text-slate-500";
case "IN_PROGRESS":
return "text-blue-500";
case "WAITING":
return "text-blue-500";
case "COMPLETED":
return "text-green-500";
case "FAILED":
return "text-rose-500";
case "CANCELED":
return "text-slate-500";
case "TIMEDOUT":
return "text-amber-300";
default: {
const _exhaustiveCheck: never = status;
throw new Error(`Non-exhaustive match for value: ${status}`);
}
}
}
@@ -10,6 +10,7 @@ import {
import type { JobRunStatus } from "@trigger.dev/database";
import { cn } from "~/utils/cn";
import { Spinner } from "../primitives/Spinner";
import { z } from "zod";
export function RunStatus({ status }: { status: JobRunStatus }) {
return (
@@ -127,3 +128,44 @@ export function runStatusClassNameColor(status: JobRunStatus): string {
}
}
}
export const DirectionSchema = z.union([z.literal("forward"), z.literal("backward")]);
export type Direction = z.infer<typeof DirectionSchema>;
export const FilterableStatus = z.union([
z.literal("QUEUED"),
z.literal("IN_PROGRESS"),
z.literal("WAITING"),
z.literal("COMPLETED"),
z.literal("FAILED"),
z.literal("TIMEDOUT"),
z.literal("CANCELED"),
]);
export type FilterableStatus = z.infer<typeof FilterableStatus>;
export const FilterableEnvironment = z.union([
z.literal("DEVELOPMENT"),
z.literal("STAGING"),
z.literal("PRODUCTION"),
]);
export type FilterableEnvironment = z.infer<typeof FilterableEnvironment>;
export const environmentKeys: FilterableEnvironment[] = ["DEVELOPMENT", "STAGING", "PRODUCTION"];
export const RunListSearchSchema = z.object({
cursor: z.string().optional(),
direction: DirectionSchema.optional(),
status: FilterableStatus.optional(),
environment: FilterableEnvironment.optional(),
});
export const filterableStatuses: Record<FilterableStatus, JobRunStatus[]> = {
QUEUED: ["QUEUED", "WAITING_TO_EXECUTE", "PENDING", "WAITING_ON_CONNECTIONS"],
IN_PROGRESS: ["STARTED", "EXECUTING", "PREPROCESSING"],
WAITING: ["WAITING_TO_CONTINUE"],
COMPLETED: ["SUCCESS"],
FAILED: ["FAILURE", "UNRESOLVED_AUTH", "INVALID_PAYLOAD", "ABORTED"],
TIMEDOUT: ["TIMED_OUT"],
CANCELED: ["CANCELED"],
};
export const statusKeys: FilterableStatus[] = Object.keys(filterableStatuses) as FilterableStatus[];
@@ -0,0 +1,12 @@
import { useLocation, useNavigation } from "@remix-run/react";
export function useOptimisticLocation() {
const navigation = useNavigation();
const location = useLocation();
if (navigation.state === "idle" || !navigation.location) {
return location;
}
return navigation.location;
}
@@ -0,0 +1,163 @@
import { PrismaClient, prisma } from "~/db.server";
import { Direction, FilterableEnvironment } from "~/components/runs/RunStatuses";
import { getUsername } from "~/utils/username";
type EventListOptions = {
userId: string;
organizationSlug: string;
projectSlug: string;
direction?: Direction;
filterEnvironment?: FilterableEnvironment;
cursor?: string;
pageSize?: number;
};
const DEFAULT_PAGE_SIZE = 20;
export type EventList = Awaited<ReturnType<EventListPresenter["call"]>>;
export class EventListPresenter {
#prismaClient: PrismaClient;
constructor(prismaClient: PrismaClient = prisma) {
this.#prismaClient = prismaClient;
}
public async call({
userId,
organizationSlug,
projectSlug,
filterEnvironment,
direction = "forward",
cursor,
pageSize = DEFAULT_PAGE_SIZE,
}: EventListOptions) {
const directionMultiplier = direction === "forward" ? 1 : -1;
// Find the organization that the user is a member of
const organization = await this.#prismaClient.organization.findFirstOrThrow({
where: {
slug: organizationSlug,
members: { some: { userId } },
},
});
// Find the project scoped to the organization
const project = await this.#prismaClient.project.findFirstOrThrow({
where: {
slug: projectSlug,
organizationId: organization.id,
},
});
// Find all runtimeEnvironments that the user has access to
const environments = await this.#prismaClient.runtimeEnvironment.findMany({
where: {
projectId: project.id,
},
});
const events = await this.#prismaClient.eventRecord.findMany({
select: {
id: true,
name: true,
deliverAt: true,
deliveredAt: true,
isTest: true,
createdAt: true,
cancelledAt: true,
environment: {
select: {
type: true,
slug: true,
orgMember: {
select: {
user: {
select: {
id: true,
name: true,
displayName: true,
},
},
},
},
},
},
runs: {
select: {
id: true,
},
},
},
where: {
internal: false,
projectId: project.id,
organizationId: organization.id,
environmentId: {
in: environments.map((environment) => environment.id),
},
environment: filterEnvironment ? { type: filterEnvironment } : undefined,
},
orderBy: [{ id: "desc" }],
//take an extra record to tell if there are more
take: directionMultiplier * (pageSize + 1),
//skip the cursor if there is one
skip: cursor ? 1 : 0,
cursor: cursor
? {
id: cursor,
}
: undefined,
});
const hasMore = events.length > pageSize;
//get cursors for next and previous pages
let next: string | undefined;
let previous: string | undefined;
switch (direction) {
case "forward":
previous = cursor ? events.at(0)?.id : undefined;
if (hasMore) {
next = events[pageSize - 1]?.id;
}
break;
case "backward":
if (hasMore) {
previous = events[1]?.id;
next = events[pageSize]?.id;
} else {
next = events[pageSize - 1]?.id;
}
break;
}
const eventsToReturn =
direction === "backward" && hasMore
? events.slice(1, pageSize + 1)
: events.slice(0, pageSize);
return {
events: eventsToReturn.map((event) => ({
id: event.id,
name: event.name,
deliverAt: event.deliverAt,
deliveredAt: event.deliveredAt,
createdAt: event.createdAt,
cancelledAt: event.cancelledAt,
isTest: event.isTest,
environment: {
type: event.environment.type,
slug: event.environment.slug,
userId: event.environment.orgMember?.user.id,
userName: getUsername(event.environment.orgMember?.user),
},
runs: event.runs.length,
})),
pagination: {
next,
previous,
},
};
}
}
@@ -0,0 +1,68 @@
import { PrismaClient, prisma } from "~/db.server";
export type Event = NonNullable<Awaited<ReturnType<EventPresenter["call"]>>>;
export class EventPresenter {
#prismaClient: PrismaClient;
constructor(prismaClient: PrismaClient = prisma) {
this.#prismaClient = prismaClient;
}
public async call({
userId,
projectSlug,
organizationSlug,
eventId,
}: {
userId: string;
projectSlug: string;
organizationSlug: string;
eventId: string;
}) {
// Find the organization that the user is a member of
const organization = await this.#prismaClient.organization.findFirstOrThrow({
where: {
slug: organizationSlug,
members: { some: { userId } },
},
});
// Find the project scoped to the organization
const project = await this.#prismaClient.project.findFirstOrThrow({
where: {
slug: projectSlug,
organizationId: organization.id,
},
});
const event = await this.#prismaClient.eventRecord.findFirst({
select: {
id: true,
name: true,
payload: true,
context: true,
timestamp: true,
deliveredAt: true,
},
where: {
id: eventId,
projectId: project.id,
organizationId: organization.id,
},
});
if (!event) {
throw new Error("Could not find Event");
}
return {
id: event.id,
name: event.name,
timestamp: event.timestamp,
payload: JSON.stringify(event.payload, null, 2),
context: JSON.stringify(event.context, null, 2),
deliveredAt: event.deliveredAt,
};
}
}
@@ -1,19 +1,22 @@
import { JobRunStatus, RuntimeEnvironmentType } from "@trigger.dev/database";
import { z } from "zod";
import {
Direction,
FilterableEnvironment,
FilterableStatus,
filterableStatuses,
} from "~/components/runs/RunStatuses";
import { PrismaClient, prisma } from "~/db.server";
import { DirectionSchema } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route";
import { getUsername } from "~/utils/username";
export type Direction = z.infer<typeof DirectionSchema>;
type RunListOptions = {
userId: string;
eventId?: string;
jobSlug?: string;
organizationSlug: string;
projectSlug: string;
direction?: Direction;
filterStatus?: JobRunStatus[];
filterEnvironment?: RuntimeEnvironmentType;
filterStatus?: FilterableStatus;
filterEnvironment?: FilterableEnvironment;
cursor?: string;
pageSize?: number;
};
@@ -31,6 +34,7 @@ export class RunListPresenter {
public async call({
userId,
eventId,
jobSlug,
organizationSlug,
projectSlug,
@@ -40,6 +44,8 @@ export class RunListPresenter {
cursor,
pageSize = DEFAULT_PAGE_SIZE,
}: RunListOptions) {
const filterStatuses = filterStatus ? filterableStatuses[filterStatus] : undefined;
const directionMultiplier = direction === "forward" ? 1 : -1;
// Find the organization that the user is a member of
@@ -74,6 +80,10 @@ export class RunListPresenter {
})
: undefined;
const event = eventId
? await this.#prismaClient.eventRecord.findUnique({ where: { id: eventId } })
: undefined;
const runs = await this.#prismaClient.jobRun.findMany({
select: {
id: true,
@@ -114,13 +124,14 @@ export class RunListPresenter {
},
},
where: {
eventId: event?.id,
jobId: job?.id,
projectId: project.id,
organizationId: organization.id,
environmentId: {
in: environments.map((environment) => environment.id),
},
status: filterStatus ? { in: filterStatus } : undefined,
status: filterStatuses ? { in: filterStatuses } : undefined,
environment: filterEnvironment ? { type: filterEnvironment } : undefined,
},
orderBy: [{ id: "desc" }],
@@ -2,7 +2,8 @@ import { TriggerSource, User } from "@trigger.dev/database";
import { PrismaClient, prisma } from "~/db.server";
import { Organization } from "~/models/organization.server";
import { Project } from "~/models/project.server";
import { Direction, RunList, RunListPresenter } from "./RunListPresenter.server";
import { RunList, RunListPresenter } from "./RunListPresenter.server";
import { Direction } from "~/components/runs/RunStatuses";
export class TriggerSourcePresenter {
#prismaClient: PrismaClient;
@@ -1,5 +1,5 @@
import { Direction } from "~/components/runs/RunStatuses";
import { PrismaClient, prisma } from "~/db.server";
import { Direction } from "./RunListPresenter.server";
type RunListOptions = {
userId: string;
@@ -2,9 +2,9 @@ import { User, Webhook } from "@trigger.dev/database";
import { PrismaClient, prisma } from "~/db.server";
import { Organization } from "~/models/organization.server";
import { Project } from "~/models/project.server";
import { Direction } from "./RunListPresenter.server";
import { organizationPath, projectPath } from "~/utils/pathBuilder";
import { WebhookDeliveryListPresenter } from "./WebhookDeliveryListPresenter.server";
import { Direction } from "~/components/runs/RunStatuses";
export class WebhookDeliveryPresenter {
#prismaClient: PrismaClient;
@@ -2,8 +2,9 @@ import { User, Webhook } from "@trigger.dev/database";
import { PrismaClient, prisma } from "~/db.server";
import { Organization } from "~/models/organization.server";
import { Project } from "~/models/project.server";
import { Direction, RunListPresenter } from "./RunListPresenter.server";
import { RunListPresenter } from "./RunListPresenter.server";
import { organizationPath, projectPath } from "~/utils/pathBuilder";
import { Direction } from "~/components/runs/RunStatuses";
export class WebhookSourcePresenter {
#prismaClient: PrismaClient;
@@ -0,0 +1,129 @@
import { LoaderFunctionArgs } from "@remix-run/server-runtime";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import { PageHeader, PageTitle, PageTitleRow } from "~/components/primitives/PageHeader";
import { requireUserId } from "~/services/session.server";
import { EventParamSchema, projectEventsPath, projectPath } from "~/utils/pathBuilder";
import { BreadcrumbLink } from "~/components/navigation/Breadcrumb";
import { Handle } from "~/utils/handle";
import { EventDetail } from "~/components/event/EventDetail";
import { EventPresenter } from "~/presenters/EventPresenter.server";
import { useTypedMatchData } from "~/hooks/useTypedMatchData";
import { Fragment } from "react";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { RunListSearchSchema } from "~/components/runs/RunStatuses";
import { RunListPresenter } from "~/presenters/RunListPresenter.server";
import { RunsTable } from "~/components/runs/RunsTable";
import { RunsFilters } from "~/components/runs/RunFilters";
import { ListPagination } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/ListPagination";
import { useUser } from "~/hooks/useUser";
import { useNavigation } from "@remix-run/react";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const userId = await requireUserId(request);
const { eventParam, projectParam, organizationSlug } = EventParamSchema.parse(params);
const url = new URL(request.url);
const s = Object.fromEntries(url.searchParams.entries());
const searchParams = RunListSearchSchema.parse(s);
const presenter = new EventPresenter();
try {
const event = await presenter.call({
userId,
projectSlug: projectParam,
organizationSlug,
eventId: eventParam,
});
if (!event) {
throw new Response("Not Found", { status: 404 });
}
const runsPresenter = new RunListPresenter();
const list = await runsPresenter.call({
userId,
filterEnvironment: searchParams.environment,
filterStatus: searchParams.status,
eventId: event.id,
projectSlug: projectParam,
organizationSlug,
direction: searchParams.direction,
cursor: searchParams.cursor,
});
return typedjson({ event, list });
} catch (e) {
console.log(e);
throw new Response(e instanceof Error ? e.message : JSON.stringify(e), { status: 404 });
}
};
export const handle: Handle = {
breadcrumb: (match) => {
const eventData = useTypedMatchData<typeof loader>(match);
return (
<Fragment>
{eventData && eventData.event && (
<BreadcrumbLink to={match.pathname} title={eventData.event.name} />
)}
</Fragment>
);
},
};
export default function Page() {
const { event, list } = useTypedLoaderData<typeof loader>();
const navigation = useNavigation();
const isLoading = navigation.state !== "idle";
const organization = useOrganization();
const project = useProject();
const user = useUser();
return (
<PageContainer>
<PageHeader>
<PageTitleRow>
<PageTitle
title={event.name}
backButton={{
to: projectEventsPath(organization, project),
text: "Events",
}}
/>
</PageTitleRow>
</PageHeader>
<PageBody scrollable={false}>
<div className="grid h-full grid-cols-2">
<div className="overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-700">
<EventDetail event={event} />
</div>
<div className="overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-700">
<div className="mb-2 flex items-center justify-between gap-x-2">
<RunsFilters />
<div className="flex items-center justify-end gap-x-2">
<ListPagination list={list} />
</div>
</div>
<RunsTable
total={list.runs.length}
hasFilters={false}
runs={list.runs}
isLoading={isLoading}
showJob={true}
runsParentPath={projectPath(organization, project)}
currentUser={user}
/>
<ListPagination list={list} className="mt-2 justify-end" />
</div>
</div>
</PageBody>
</PageContainer>
);
}
@@ -0,0 +1,93 @@
import { useNavigation } from "@remix-run/react";
import { LoaderFunctionArgs } from "@remix-run/server-runtime";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import { LinkButton } from "~/components/primitives/Buttons";
import {
PageButtons,
PageDescription,
PageHeader,
PageTitle,
PageTitleRow,
} from "~/components/primitives/PageHeader";
import { EventsTable } from "~/components/events/EventsTable";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { EventListPresenter } from "~/presenters/EventListPresenter.server";
import { requireUserId } from "~/services/session.server";
import { ProjectParamSchema, docsPath, projectPath, trimTrailingSlash } from "~/utils/pathBuilder";
import { ListPagination } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/ListPagination";
import { EventListSearchSchema } from "~/components/events/EventStatuses";
import { useUser } from "~/hooks/useUser";
import { EventsFilters } from "~/components/events/EventsFilters";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const userId = await requireUserId(request);
const { projectParam, organizationSlug } = ProjectParamSchema.parse(params);
const url = new URL(request.url);
const s = Object.fromEntries(url.searchParams.entries());
const searchParams = EventListSearchSchema.parse(s);
const presenter = new EventListPresenter();
const list = await presenter.call({
userId,
filterEnvironment: searchParams.environment,
projectSlug: projectParam,
organizationSlug,
direction: searchParams.direction,
cursor: searchParams.cursor,
pageSize: 25,
});
return typedjson({
list,
});
};
export default function Page() {
const { list } = useTypedLoaderData<typeof loader>();
const navigation = useNavigation();
const isLoading = navigation.state !== "idle";
const organization = useOrganization();
const project = useProject();
const user = useUser();
return (
<PageContainer>
<PageHeader>
<PageTitleRow>
<PageTitle title={`${project.name} events`} />
<PageButtons>
<LinkButton
LeadingIcon={"docs"}
to={docsPath("documentation/concepts/triggers/events")}
variant="secondary/small"
>
Event documentation
</LinkButton>
</PageButtons>
</PageTitleRow>
<PageDescription>All events in this project</PageDescription>
</PageHeader>
<PageBody scrollable={false}>
<div className="h-full overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-700">
<div className="mb-2 flex items-center justify-between gap-x-2">
<EventsFilters />
<ListPagination list={list} />
</div>
<EventsTable
total={list.events.length}
hasFilters={false}
events={list.events}
isLoading={isLoading}
eventsParentPath={projectPath(organization, project)}
currentUser={user}
/>
<ListPagination list={list} className="mt-2 justify-end" />
</div>
</PageBody>
</PageContainer>
);
}
@@ -0,0 +1,11 @@
import { Outlet } from "@remix-run/react";
import { BreadcrumbLink } from "~/components/navigation/Breadcrumb";
import { Handle } from "~/utils/handle";
export const handle: Handle = {
breadcrumb: (match) => <BreadcrumbLink to={match.pathname} title="Events" />,
};
export default function Page() {
return <Outlet />;
}
@@ -1,16 +1,16 @@
import { useLocation } from "@remix-run/react";
import { LinkButton } from "~/components/primitives/Buttons";
import { Direction, RunList } from "~/presenters/RunListPresenter.server";
import { WebhookDeliveryList } from "~/presenters/WebhookDeliveryListPresenter.server";
import { Direction } from "~/components/runs/RunStatuses";
import { cn } from "~/utils/cn";
export function ListPagination({
list,
className,
}: {
list: RunList | WebhookDeliveryList;
className?: string;
}) {
type List = {
pagination: {
next: string | undefined;
previous: string | undefined;
};
};
export function ListPagination({ list, className }: { list: List; className?: string }) {
return (
<div className={cn("flex items-center gap-1", className)}>
<PreviousButton cursor={list.pagination.previous} />
@@ -20,13 +20,8 @@ import {
organizationIntegrationsPath,
} from "~/utils/pathBuilder";
import { ListPagination } from "./ListPagination";
export const DirectionSchema = z.union([z.literal("forward"), z.literal("backward")]);
export const RunListSearchSchema = z.object({
cursor: z.string().optional(),
direction: DirectionSchema.optional(),
});
import { RunListSearchSchema } from "~/components/runs/RunStatuses";
import { RunsFilters } from "~/components/runs/RunFilters";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const userId = await requireUserId(request);
@@ -39,6 +34,8 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const presenter = new RunListPresenter();
const list = await presenter.call({
userId,
filterEnvironment: searchParams.environment,
filterStatus: searchParams.status,
jobSlug: jobParam,
projectSlug: projectParam,
organizationSlug,
@@ -73,10 +70,14 @@ export default function Page() {
{(open) => (
<div className={cn("grid h-fit gap-4", open ? "grid-cols-2" : "grid-cols-1")}>
<div>
<div className="mb-2 flex items-center justify-end gap-x-2">
<HelpTrigger title="How do I run my Job?" />
<ListPagination list={list} />
<div className="mb-2 flex items-center justify-between gap-x-2">
<RunsFilters />
<div className="flex items-center justify-end gap-x-2">
<HelpTrigger title="How do I run my Job?" />
<ListPagination list={list} />
</div>
</div>
<RunsTable
total={list.runs.length}
hasFilters={false}
@@ -18,67 +18,8 @@ import { RunListPresenter } from "~/presenters/RunListPresenter.server";
import { requireUserId } from "~/services/session.server";
import { ProjectParamSchema, docsPath, projectPath } from "~/utils/pathBuilder";
import { ListPagination } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/ListPagination";
import { RunListSearchSchema } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "~/components/primitives/Select";
import { JobRunStatus, RuntimeEnvironmentType } from "@trigger.dev/database";
import {
CheckCircleIcon,
ClockIcon,
ExclamationTriangleIcon,
PauseCircleIcon,
XCircleIcon,
} from "@heroicons/react/24/solid";
import { ChartBarIcon } from "@heroicons/react/20/solid";
import { cn } from "~/utils/cn";
import { Spinner } from "~/components/primitives/Spinner";
import { NoSymbolIcon } from "@heroicons/react/20/solid";
// Filter -> status types
const ExtendedJobRunStatus = {
ALL: "ALL" as const,
...JobRunStatus,
} as const;
type ExtendedJobRunStatusKey = keyof typeof ExtendedJobRunStatus;
type FilterableStatus =
| "ALL"
| "QUEUED"
| "IN_PROGRESS"
| "WAITING"
| "COMPLETED"
| "FAILED"
| "CANCELED"
| "TIMEDOUT";
const filterableStatuses: Record<FilterableStatus, ExtendedJobRunStatusKey[]> = {
ALL: ["ALL"],
QUEUED: ["QUEUED", "WAITING_TO_EXECUTE", "PENDING", "WAITING_ON_CONNECTIONS"],
IN_PROGRESS: ["STARTED", "EXECUTING", "PREPROCESSING"],
WAITING: ["WAITING_TO_CONTINUE"],
COMPLETED: ["SUCCESS"],
FAILED: ["FAILURE", "UNRESOLVED_AUTH", "INVALID_PAYLOAD", "ABORTED"],
TIMEDOUT: ["TIMED_OUT"],
CANCELED: ["CANCELED"],
};
const statusKeys: FilterableStatus[] = Object.keys(filterableStatuses) as FilterableStatus[];
// Filter -> Environment types
const ExtendedRuntimeEnvironment = {
ALL: "ALL" as const,
...RuntimeEnvironmentType,
} as const;
type ExtendedRuntimeEnvironmentType = keyof typeof ExtendedRuntimeEnvironment;
const environmentKeys: ExtendedRuntimeEnvironmentType[] = Object.keys(
ExtendedRuntimeEnvironment
) as ExtendedRuntimeEnvironmentType[];
import { RunListSearchSchema } from "~/components/runs/RunStatuses";
import { RunsFilters } from "~/components/runs/RunFilters";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const userId = await requireUserId(request);
@@ -88,29 +29,12 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const s = Object.fromEntries(url.searchParams.entries());
const searchParams = RunListSearchSchema.parse(s);
const status = url.searchParams.get("status");
const environment = url.searchParams.get("environment");
let filterStatus: JobRunStatus[] | undefined;
if (status && status !== "ALL") {
if (filterableStatuses.hasOwnProperty(status)) {
filterStatus = filterableStatuses[status as FilterableStatus] as JobRunStatus[];
}
}
let filterEnvironment: RuntimeEnvironmentType | undefined;
if (environment && environment !== "ALL") {
if (environmentKeys.includes(environment)) {
filterEnvironment = environment as RuntimeEnvironmentType;
}
}
const presenter = new RunListPresenter();
const list = await presenter.call({
userId,
filterEnvironment: filterEnvironment,
filterStatus: filterStatus,
filterEnvironment: searchParams.environment,
filterStatus: searchParams.status,
projectSlug: projectParam,
organizationSlug,
direction: searchParams.direction,
@@ -130,27 +54,6 @@ export default function Page() {
const organization = useOrganization();
const project = useProject();
const user = useUser();
const navigate = useNavigate();
const location = useLocation();
const url = new URLSearchParams(location.search);
const selectedEnvironment = url.get("environment") || ExtendedRuntimeEnvironment.ALL;
const selectedStatus = url.get("status") || ExtendedJobRunStatus.ALL;
const handleFilterChange = (filterType: string, value: string) => {
url.set(filterType, value);
url.delete("cursor");
url.delete("direction");
navigate(`${location.pathname}?${url.toString()}`);
};
const handleStatusChange = (value: FilterableStatus) => {
handleFilterChange("status", value);
};
const handleEnvironmentChange = (value: string) => {
handleFilterChange("environment", value);
};
return (
<PageContainer>
@@ -173,67 +76,7 @@ export default function Page() {
<PageBody scrollable={false}>
<div className="h-full overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-700">
<div className="mb-2 flex items-center justify-between gap-x-2">
<div className="flex flex-row justify-between gap-x-2">
{/* environment filter */}
<SelectGroup>
<Select
name="environment"
value={selectedEnvironment}
onValueChange={handleEnvironmentChange}
>
<SelectTrigger size="secondary/small" width="full">
<SelectValue placeholder="Select environment" className="ml-2 p-0" />
</SelectTrigger>
<SelectContent>
{environmentKeys.map((env) => (
<SelectItem key={env} value={env}>
<div className="flex gap-x-2">
{env !== "ALL" && (
<span
className={cn(
"inline-flex h-4 items-center justify-center rounded-[2px] px-1 text-xxs font-medium uppercase tracking-wider text-midnight-900",
filterEnvironmentColorClassName(env)
)}
>
{filterEnvironmentTitle(env)}
</span>
)}
<span
className={cn(
"inline-flex h-4 items-center justify-center pl-1 text-xxs font-medium uppercase tracking-wider text-dimmed"
)}
>
{env === "ALL" ? env + " Environments" : env}
</span>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
</SelectGroup>
{/* status filter */}
<SelectGroup>
<Select name="status" value={selectedStatus} onValueChange={handleStatusChange}>
<SelectTrigger size="secondary/small" width="full">
<SelectValue placeholder="Select environment" className="ml-2 p-0" />
</SelectTrigger>
<SelectContent>
{statusKeys.map((status) => (
<SelectItem key={status} value={status}>
{
<span className="flex items-center gap-1 text-xxs font-medium uppercase tracking-wider">
<FilterStatusIcon status={status} className="h-4 w-4" />
<FilterStatusLabel status={status} />
</span>
}
</SelectItem>
))}
</SelectContent>
</Select>
</SelectGroup>
</div>
<RunsFilters />
<ListPagination list={list} />
</div>
<RunsTable
@@ -251,120 +94,3 @@ export default function Page() {
</PageContainer>
);
}
function filterEnvironmentTitle(environment: ExtendedRuntimeEnvironmentType) {
switch (environment) {
case "ALL":
return "All";
case "PRODUCTION":
return "Prod";
case "STAGING":
return "Staging";
case "DEVELOPMENT":
return "Dev";
case "PREVIEW":
return "Preview";
}
}
function filterEnvironmentColorClassName(environment: ExtendedRuntimeEnvironmentType) {
switch (environment) {
case "ALL":
return "bg-indigo-500";
case "PRODUCTION":
return "bg-green-500";
case "STAGING":
return "bg-amber-500";
case "DEVELOPMENT":
return "bg-pink-500";
case "PREVIEW":
return "bg-yellow-500";
}
}
export function FilterStatusLabel({ status }: { status: FilterableStatus }) {
return <span className={filterStatusClassNameColor(status)}>{filterStatusTitle(status)}</span>;
}
export function FilterStatusIcon({
status,
className,
}: {
status: FilterableStatus;
className: string;
}) {
switch (status) {
case "ALL":
return <span className="w-[0.0625rem]"></span>;
case "COMPLETED":
return <CheckCircleIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "WAITING":
return <ClockIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "QUEUED":
return <PauseCircleIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "IN_PROGRESS":
return <Spinner className={cn(filterStatusClassNameColor(status), className)} />;
case "TIMEDOUT":
return (
<ExclamationTriangleIcon className={cn(filterStatusClassNameColor(status), className)} />
);
case "CANCELED":
return <NoSymbolIcon className={cn(filterStatusClassNameColor(status), className)} />;
case "FAILED":
return <XCircleIcon className={cn(filterStatusClassNameColor(status), className)} />;
default: {
const _exhaustiveCheck: never = status;
throw new Error(`Non-exhaustive match for value: ${status}`);
}
}
}
export function filterStatusTitle(status: FilterableStatus): string {
switch (status) {
case "ALL":
return "All Status";
case "QUEUED":
return "Queued";
case "IN_PROGRESS":
return "In progress";
case "WAITING":
return "Waiting";
case "COMPLETED":
return "Completed";
case "FAILED":
return "Failed";
case "CANCELED":
return "Canceled";
case "TIMEDOUT":
return "Timed out";
default: {
const _exhaustiveCheck: never = status;
throw new Error(`Non-exhaustive match for value: ${status}`);
}
}
}
export function filterStatusClassNameColor(status: FilterableStatus): string {
switch (status) {
case "ALL":
return "text-dimmed";
case "QUEUED":
return "text-slate-500";
case "IN_PROGRESS":
return "text-blue-500";
case "WAITING":
return "text-blue-500";
case "COMPLETED":
return "text-green-500";
case "FAILED":
return "text-rose-500";
case "CANCELED":
return "text-slate-500";
case "TIMEDOUT":
return "text-amber-300";
default: {
const _exhaustiveCheck: never = status;
throw new Error(`Non-exhaustive match for value: ${status}`);
}
}
}
@@ -1,11 +1,16 @@
import { conform, useForm } from "@conform-to/react";
import { parse } from "@conform-to/zod";
import { json } from "@remix-run/node";
import { Form, useActionData, useNavigation } from "@remix-run/react";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/server-runtime";
import { Fragment } from "react";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { z } from "zod";
import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import { BreadcrumbLink } from "~/components/navigation/Breadcrumb";
import { BreadcrumbIcon } from "~/components/primitives/BreadcrumbIcon";
import { Button } from "~/components/primitives/Buttons";
import { Callout, variantClasses } from "~/components/primitives/Callout";
import { Header2 } from "~/components/primitives/Headers";
import { NamedIcon } from "~/components/primitives/NamedIcon";
@@ -18,33 +23,26 @@ import {
PageTitleRow,
} from "~/components/primitives/PageHeader";
import { Paragraph } from "~/components/primitives/Paragraph";
import { RunListSearchSchema } from "~/components/runs/RunStatuses";
import { RunsTable } from "~/components/runs/RunsTable";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { useTypedMatchData } from "~/hooks/useTypedMatchData";
import { useUser } from "~/hooks/useUser";
import { redirectWithSuccessMessage } from "~/models/message.server";
import { TriggerSourcePresenter } from "~/presenters/TriggerSourcePresenter.server";
import { requireUser, requireUserId } from "~/services/session.server";
import { ActivateSourceService } from "~/services/sources/activateSource.server";
import { cn } from "~/utils/cn";
import { Handle } from "~/utils/handle";
import {
TriggerSourceParamSchema,
rootPath,
projectTriggersPath,
externalTriggerPath,
externalTriggerRunsParentPath,
projectTriggersPath,
trimTrailingSlash,
} from "~/utils/pathBuilder";
import { ListPagination } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/ListPagination";
import { RunListSearchSchema } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route";
import { Button } from "~/components/primitives/Buttons";
import { Form, useActionData, useNavigation } from "@remix-run/react";
import { cn } from "~/utils/cn";
import { conform, useForm } from "@conform-to/react";
import { parse } from "@conform-to/zod";
import { z } from "zod";
import { ActivateSourceService } from "~/services/sources/activateSource.server";
import { redirectWithSuccessMessage } from "~/models/message.server";
import { nanoid } from "nanoid";
import { useUser } from "~/hooks/useUser";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUser(request);
@@ -1,37 +1,32 @@
import { json } from "@remix-run/node";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/server-runtime";
import { useForm } from "@conform-to/react";
import { parse } from "@conform-to/zod";
import { Form, useActionData, useNavigation } from "@remix-run/react";
import type { LoaderFunctionArgs } from "@remix-run/server-runtime";
import { Fragment } from "react";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { z } from "zod";
import { BreadcrumbLink } from "~/components/navigation/Breadcrumb";
import { BreadcrumbIcon } from "~/components/primitives/BreadcrumbIcon";
import { Callout, variantClasses } from "~/components/primitives/Callout";
import { Paragraph } from "~/components/primitives/Paragraph";
import { RunListSearchSchema } from "~/components/runs/RunStatuses";
import { RunsTable } from "~/components/runs/RunsTable";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { useUser } from "~/hooks/useUser";
import { useTypedMatchData } from "~/hooks/useTypedMatchData";
import { requireUser, requireUserId } from "~/services/session.server";
import { useUser } from "~/hooks/useUser";
import { WebhookSourcePresenter } from "~/presenters/WebhookSourcePresenter.server";
import { requireUser } from "~/services/session.server";
import { cn } from "~/utils/cn";
import { Handle } from "~/utils/handle";
import {
TriggerSourceParamSchema,
projectTriggersPath,
externalTriggerPath,
projectWebhookTriggersPath,
trimTrailingSlash,
webhookTriggerRunsParentPath,
projectWebhookTriggersPath,
} from "~/utils/pathBuilder";
import { ListPagination } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/ListPagination";
import { RunListSearchSchema } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route";
import { Button } from "~/components/primitives/Buttons";
import { Form, useActionData, useNavigation } from "@remix-run/react";
import { cn } from "~/utils/cn";
import { conform, useForm } from "@conform-to/react";
import { parse } from "@conform-to/zod";
import { z } from "zod";
import { ActivateSourceService } from "~/services/sources/activateSource.server";
import { redirectWithSuccessMessage } from "~/models/message.server";
import { WebhookSourcePresenter } from "~/presenters/WebhookSourcePresenter.server";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUser(request);
@@ -5,9 +5,12 @@ import { BreadcrumbLink } from "~/components/navigation/Breadcrumb";
import { BreadcrumbIcon } from "~/components/primitives/BreadcrumbIcon";
import { Callout } from "~/components/primitives/Callout";
import { Paragraph } from "~/components/primitives/Paragraph";
import { RunListSearchSchema } from "~/components/runs/RunStatuses";
import { WebhookDeliveryRunsTable } from "~/components/runs/WebhookDeliveryRunsTable";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { useTypedMatchData } from "~/hooks/useTypedMatchData";
import { WebhookDeliveryPresenter } from "~/presenters/WebhookDeliveryPresenter.server";
import { requireUser } from "~/services/session.server";
import { Handle } from "~/utils/handle";
import {
@@ -19,9 +22,6 @@ import {
webhookTriggerPath,
} from "~/utils/pathBuilder";
import { ListPagination } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/ListPagination";
import { RunListSearchSchema } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route";
import { WebhookDeliveryPresenter } from "~/presenters/WebhookDeliveryPresenter.server";
import { WebhookDeliveryRunsTable } from "~/components/runs/WebhookDeliveryRunsTable";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUser(request);
@@ -2,7 +2,6 @@ import { Outlet } from "@remix-run/react";
import { LoaderFunctionArgs } from "@remix-run/server-runtime";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import { NamedIcon } from "~/components/primitives/NamedIcon";
import {
PageHeader,
PageInfoGroup,
@@ -12,8 +11,10 @@ import {
PageTitle,
PageTitleRow,
} from "~/components/primitives/PageHeader";
import { RunListSearchSchema } from "~/components/runs/RunStatuses";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { WebhookSourcePresenter } from "~/presenters/WebhookSourcePresenter.server";
import { requireUser } from "~/services/session.server";
import {
TriggerSourceParamSchema,
@@ -21,8 +22,6 @@ import {
webhookDeliveryPath,
webhookTriggerPath,
} from "~/utils/pathBuilder";
import { RunListSearchSchema } from "../_app.orgs.$organizationSlug.projects.$projectParam.jobs.$jobParam._index/route";
import { WebhookSourcePresenter } from "~/presenters/WebhookSourcePresenter.server";
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUser(request);
@@ -77,11 +76,7 @@ export default function Page() {
value={trigger.integration.slug}
to={trigger.integrationLink}
/>
<PageInfoProperty
icon="webhook"
label="HTTP Endpoint"
to={trigger.httpEndpointLink}
/>
<PageInfoProperty icon="webhook" label="HTTP Endpoint" to={trigger.httpEndpointLink} />
</PageInfoGroup>
</PageInfoRow>
<PageTabs
+18
View File
@@ -1,4 +1,5 @@
import type {
EventRecord,
Integration,
TriggerHttpEndpoint,
TriggerSource,
@@ -15,6 +16,7 @@ export type JobForPath = Pick<Job, "slug">;
export type RunForPath = Pick<Job, "id">;
export type IntegrationForPath = Pick<Integration, "slug">;
export type TriggerForPath = Pick<TriggerSource, "id">;
export type EventForPath = Pick<EventRecord, "id">;
export type WebhookForPath = Pick<Webhook, "id">;
export type HttpEndpointForPath = Pick<TriggerHttpEndpoint, "key">;
@@ -46,6 +48,10 @@ export const TriggerSourceParamSchema = ProjectParamSchema.extend({
triggerParam: z.string(),
});
export const EventParamSchema = ProjectParamSchema.extend({
eventParam: z.string(),
});
export const TriggerSourceRunParamsSchema = TriggerSourceParamSchema.extend({
runParam: z.string(),
});
@@ -202,6 +208,18 @@ export function projectTriggersPath(organization: OrgForPath, project: ProjectFo
return `${projectPath(organization, project)}/triggers`;
}
export function projectEventsPath(organization: OrgForPath, project: ProjectForPath) {
return `${projectPath(organization, project)}/events`;
}
export function projectEventPath(
organization: OrgForPath,
project: ProjectForPath,
event: EventForPath
) {
return `${projectEventsPath(organization, project)}/${event.id}`;
}
export function projectHttpEndpointsPath(organization: OrgForPath, project: ProjectForPath) {
return `${projectPath(organization, project)}/http-endpoints`;
}
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/airtable
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/airtable",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev integration for airtable",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -25,8 +25,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"airtable": "^0.12.1",
"zod": "3.22.3"
},
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/github
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/github",
"version": "2.3.9",
"version": "2.3.10",
"description": "The official GitHub integration for Trigger.dev",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -30,8 +30,8 @@
"@octokit/request-error": "^5.0.1",
"@octokit/webhooks": "^12.0.10",
"octokit": "^3.1.2",
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"zod": "3.22.3"
},
"engines": {
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/linear
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/linear",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev integration for @linear/sdk",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -26,8 +26,8 @@
},
"dependencies": {
"@linear/sdk": "^8.0.0",
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"zod": "3.22.3"
},
"engines": {
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/slack
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/openai",
"version": "2.3.9",
"version": "2.3.10",
"description": "The official OpenAI integration for Trigger.dev",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -42,8 +42,8 @@
},
"dependencies": {
"openai": "^4.16.1",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.9"
"@trigger.dev/sdk": "workspace:^2.3.10",
"@trigger.dev/integration-kit": "workspace:^2.3.10"
},
"engines": {
"node": ">=18.0.0"
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/plain
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/plain",
"version": "2.3.9",
"version": "2.3.10",
"description": "The official Plain.com integration for Trigger.dev",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -24,8 +24,8 @@
"build:tsup": "tsup"
},
"dependencies": {
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"@team-plain/typescript-sdk": "^2.7.0"
},
"engines": {
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/replicate
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/replicate",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev integration for replicate",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -25,8 +25,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"replicate": "^0.18.1",
"zod": "3.22.3"
},
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/resend
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/resend",
"version": "2.3.9",
"version": "2.3.10",
"description": "The official Resend.com integration for Trigger.dev",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -24,8 +24,8 @@
"build:tsup": "tsup"
},
"dependencies": {
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"resend": "^2.0.0"
},
"engines": {
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/sendgrid
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/sendgrid",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev integration for @sendgrid/mail",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -26,8 +26,8 @@
},
"dependencies": {
"@sendgrid/mail": "^7.7.0",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.9"
"@trigger.dev/sdk": "workspace:^2.3.10",
"@trigger.dev/integration-kit": "workspace:^2.3.10"
},
"engines": {
"node": ">=16.8.0"
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/shopify
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/shopify",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev integration for @shopify/shopify-api",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -26,8 +26,8 @@
},
"dependencies": {
"@shopify/shopify-api": "^8.0.2",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.10",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"zod": "3.22.3"
},
"engines": {
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/slack
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/slack",
"version": "2.3.9",
"version": "2.3.10",
"description": "The official Slack integration for Trigger.dev",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -25,7 +25,7 @@
},
"dependencies": {
"@slack/web-api": "^6.8.1",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.10",
"zod": "3.22.3"
},
"engines": {
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/stripe
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/stripe",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev integration for stripe",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -25,8 +25,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"stripe": "^12.14.0",
"zod": "3.22.3"
},
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/supabase
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/supabase",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev integration for @supabase/supabase-js",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -26,8 +26,8 @@
},
"dependencies": {
"@supabase/supabase-js": "^2.26.0",
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"supabase-management-js": "^1.0.0",
"zod": "3.22.3"
},
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/typeform
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/integration-kit@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/typeform",
"version": "2.3.9",
"version": "2.3.10",
"description": "The official Typeform integration for Trigger.dev",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -24,8 +24,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@trigger.dev/integration-kit": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/integration-kit": "workspace:^2.3.10",
"@trigger.dev/sdk": "workspace:^2.3.10",
"@typeform/api-client": "^1.8.0",
"zod": "3.22.3"
},
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/astro
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@trigger.dev/astro",
"description": "An Astro-native integration for Trigger.dev background jobs platform",
"version": "2.3.9",
"version": "2.3.10",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
@@ -20,7 +20,7 @@
"build:tsup": "tsup"
},
"peerDependencies": {
"@trigger.dev/sdk": "workspace:^2.3.9"
"@trigger.dev/sdk": "workspace:^2.3.10"
},
"devDependencies": {
"astro": "^3.0.12",
+7
View File
@@ -1,5 +1,12 @@
# create-trigger
## 2.3.10
### Patch Changes
- @trigger.dev/core@2.3.10
- @trigger.dev/yalt@2.3.10
## 2.3.9
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/cli",
"version": "2.3.9",
"version": "2.3.10",
"description": "The Trigger.dev CLI",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
+2
View File
@@ -1,5 +1,7 @@
# @trigger.dev/core-backend
## 2.3.10
## 2.3.9
## 2.3.8
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/core-backend",
"version": "2.3.9",
"version": "2.3.10",
"description": "Core code used across `@trigger.dev/sdk` and Trigger.dev server",
"license": "MIT",
"main": "./dist/index.js",
+2
View File
@@ -1,5 +1,7 @@
# internal-platform
## 2.3.10
## 2.3.9
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/core",
"version": "2.3.9",
"version": "2.3.10",
"description": "Core code used across the Trigger.dev SDK and platform",
"license": "MIT",
"main": "./dist/index.js",
+2
View File
@@ -1,5 +1,7 @@
# @trigger.dev/eslint-plugin
## 2.3.10
## 2.3.9
## 2.3.8
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/eslint-plugin",
"version": "2.3.9",
"version": "2.3.10",
"description": "ESLint plugin with trigger.dev best practices",
"keywords": [
"eslint",
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/express
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/express",
"version": "2.3.9",
"version": "2.3.10",
"description": "Official Express adapter for Trigger.dev",
"license": "MIT",
"main": "./dist/index.js",
@@ -23,7 +23,7 @@
"./package.json": "./package.json"
},
"devDependencies": {
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.10",
"@trigger.dev/tsconfig": "workspace:*",
"@types/debug": "^4.1.7",
"@types/express": "^4.17.13",
@@ -39,7 +39,7 @@
"build:tsup": "tsup"
},
"peerDependencies": {
"@trigger.dev/sdk": "workspace:^2.3.9"
"@trigger.dev/sdk": "workspace:^2.3.10"
},
"dependencies": {
"debug": "^4.3.4",
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/hono
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/hono",
"version": "2.3.9",
"version": "2.3.10",
"description": "A Trigger.dev adapter for Hono.dev",
"license": "MIT",
"main": "./dist/index.js",
@@ -32,7 +32,7 @@
},
"peerDependencies": {
"hono": "3.x",
"@trigger.dev/sdk": "workspace:^2.3.9"
"@trigger.dev/sdk": "workspace:^2.3.10"
},
"devDependencies": {
"@trigger.dev/tsconfig": "workspace:*",
+6
View File
@@ -1,5 +1,11 @@
# @trigger.dev/integration-kit
## 2.3.10
### Patch Changes
- @trigger.dev/core@2.3.10
## 2.3.9
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/integration-kit",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev Integration Kit has helpers to make creating integrations easier",
"license": "MIT",
"main": "./dist/index.js",
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/nestjs
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/nestjs",
"version": "2.3.9",
"version": "2.3.10",
"description": "Official NestJS adapter for Trigger.dev",
"license": "MIT",
"main": "./dist/index.js",
@@ -23,7 +23,7 @@
"./package.json": "./package.json"
},
"devDependencies": {
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.10",
"@trigger.dev/tsconfig": "workspace:*",
"@types/debug": "^4.1.7",
"@types/express": "^4.17.13",
@@ -41,7 +41,7 @@
},
"peerDependencies": {
"@nestjs/common": ">=10.0.0",
"@trigger.dev/sdk": "workspace:^2.3.9"
"@trigger.dev/sdk": "workspace:^2.3.10"
},
"dependencies": {
"@nestjs/common": "^10.2.4",
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/nextjs
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/nextjs",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev Next.js integration",
"license": "MIT",
"main": "./dist/index.js",
@@ -41,7 +41,7 @@
"build:tsup": "tsup"
},
"peerDependencies": {
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.10",
"next": ">=12.0.0"
},
"dependencies": {
+6
View File
@@ -1,5 +1,11 @@
# @trigger.dev/react
## 2.3.10
### Patch Changes
- @trigger.dev/core@2.3.10
## 2.3.9
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/react",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev React SDK",
"license": "MIT",
"types": "dist/index.d.ts",
@@ -27,7 +27,7 @@
},
"dependencies": {
"@tanstack/react-query": "5.0.0-beta.2",
"@trigger.dev/core": "workspace:^2.3.9",
"@trigger.dev/core": "workspace:^2.3.10",
"debug": "^4.3.4",
"zod": "3.22.3"
},
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/remix
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/remix",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev Remix integration",
"license": "MIT",
"main": "./dist/index.js",
@@ -39,7 +39,7 @@
"build:tsup": "tsup"
},
"peerDependencies": {
"@trigger.dev/sdk": "workspace:^2.3.9",
"@trigger.dev/sdk": "workspace:^2.3.10",
"@remix-run/server-runtime": ">1.19.0"
},
"dependencies": {
+8
View File
@@ -1,5 +1,13 @@
# @trigger.dev/sveltekit
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
## 2.3.9
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/sveltekit",
"version": "2.3.9",
"version": "2.3.10",
"description": "Trigger.dev svelteKit integration",
"license": "MIT",
"main": "./dist/index.js",
@@ -39,7 +39,7 @@
"build:tsup": "tsup"
},
"peerDependencies": {
"@trigger.dev/sdk": "workspace:^2.3.9"
"@trigger.dev/sdk": "workspace:^2.3.10"
},
"dependencies": {
"debug": "^4.3.4"
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/testing
## 2.3.10
### Patch Changes
- Updated dependencies [8277f4d2]
- Updated dependencies [73cb8839]
- @trigger.dev/sdk@2.3.10
- @trigger.dev/core@2.3.10
## 2.3.9
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@trigger.dev/testing",
"description": "A collection of useful tools to write tests for Trigger.dev.",
"version": "2.3.9",
"version": "2.3.10",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
+9
View File
@@ -1,5 +1,14 @@
# @trigger.dev/sdk
## 2.3.10
### Patch Changes
- 8277f4d2: Use correct overload param when invoking a job outside of a run #802
- 73cb8839: Fixed invoke inferred payload types #830
- @trigger.dev/core@2.3.10
- @trigger.dev/core-backend@2.3.10
## 2.3.9
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/sdk",
"version": "2.3.9",
"version": "2.3.10",
"description": "trigger.dev Node.JS SDK",
"license": "MIT",
"main": "./dist/index.js",
@@ -30,8 +30,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@trigger.dev/core": "workspace:^2.3.9",
"@trigger.dev/core-backend": "workspace:^2.3.9",
"@trigger.dev/core": "workspace:^2.3.10",
"@trigger.dev/core-backend": "workspace:^2.3.10",
"chalk": "^5.2.0",
"cronstrue": "^2.21.0",
"debug": "^4.3.4",
+3 -3
View File
@@ -185,8 +185,8 @@ export class Job<
typeof this.options.concurrencyLimit === "number"
? this.options.concurrencyLimit
: typeof this.options.concurrencyLimit === "object"
? { id: this.options.concurrencyLimit.id, limit: this.options.concurrencyLimit.limit }
: undefined,
? { id: this.options.concurrencyLimit.id, limit: this.options.concurrencyLimit.limit }
: undefined,
};
}
@@ -263,7 +263,7 @@ export class Job<
throw new Error("Cannot invoke a job from within a run without a cacheKey.");
}
return await triggerClient.invokeJob(this.id, param1, param3);
return await triggerClient.invokeJob(this.id, param1, param2);
}
async invokeAndWaitForCompletion(
+3 -5
View File
@@ -76,12 +76,10 @@ export type TriggerEventType<TTrigger extends Trigger<any>> = TTrigger extends T
: never;
export type TriggerInvokeType<TTrigger extends Trigger<any>> = TTrigger extends Trigger<
infer TEventSpec
EventSpecification<any, infer TInvoke>
>
? TEventSpec["parseInvokePayload"] extends (payload: unknown) => infer TInvoke
? TInvoke
: any
: never;
? TInvoke
: any;
export type VerifyResult =
| {
+2
View File
@@ -1,5 +1,7 @@
# @trigger.dev/yalt
## 2.3.10
## 2.3.9
## 2.3.8
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@trigger.dev/yalt",
"version": "2.3.9",
"version": "2.3.10",
"description": "yalt.dev client library",
"license": "MIT",
"main": "./dist/index.js",
+36 -36
View File
@@ -416,7 +416,7 @@ importers:
devDependencies:
eslint: 8.31.0
eslint-config-prettier: 8.6.0_eslint@8.31.0
eslint-config-turbo: 1.11.2_eslint@8.31.0
eslint-config-turbo: 1.11.3_eslint@8.31.0
eslint-plugin-react: 7.31.8_eslint@8.31.0
typescript: 4.9.4
@@ -444,8 +444,8 @@ importers:
integrations/airtable:
specifiers:
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': 16.x
@@ -474,8 +474,8 @@ importers:
'@octokit/types': ^12.4.0
'@octokit/webhooks': ^12.0.10
'@octokit/webhooks-types': ^7.3.1
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': '18'
@@ -505,8 +505,8 @@ importers:
integrations/linear:
specifiers:
'@linear/sdk': ^8.0.0
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': 16.x
@@ -529,8 +529,8 @@ importers:
integrations/openai:
specifiers:
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/jest': ^29.5.3
@@ -559,8 +559,8 @@ importers:
integrations/plain:
specifiers:
'@team-plain/typescript-sdk': ^2.7.0
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': '18'
@@ -581,8 +581,8 @@ importers:
integrations/replicate:
specifiers:
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': 16.x
@@ -606,8 +606,8 @@ importers:
integrations/resend:
specifiers:
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': '18'
@@ -630,8 +630,8 @@ importers:
integrations/sendgrid:
specifiers:
'@sendgrid/mail': ^7.7.0
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': 16.x
@@ -653,8 +653,8 @@ importers:
integrations/shopify:
specifiers:
'@shopify/shopify-api': ^8.0.2
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': 16.x
@@ -678,7 +678,7 @@ importers:
integrations/slack:
specifiers:
'@slack/web-api': ^6.8.1
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': '18'
@@ -700,8 +700,8 @@ importers:
integrations/stripe:
specifiers:
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsup': workspace:*
'@types/node': 16.x
rimraf: ^3.0.2
@@ -726,8 +726,8 @@ importers:
integrations/supabase:
specifiers:
'@supabase/supabase-js': ^2.26.0
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/node': 18.x
@@ -752,8 +752,8 @@ importers:
integrations/typeform:
specifiers:
'@trigger.dev/integration-kit': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/integration-kit': workspace:^2.3.10
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsup': workspace:*
'@typeform/api-client': ^1.8.0
'@types/node': 16.x
@@ -1019,7 +1019,7 @@ importers:
packages/express:
specifiers:
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/debug': ^4.1.7
@@ -1089,7 +1089,7 @@ importers:
specifiers:
'@nestjs/common': ^10.2.4
'@remix-run/web-fetch': ^4.3.5
'@trigger.dev/sdk': workspace:^2.3.9
'@trigger.dev/sdk': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/debug': ^4.1.7
@@ -1148,7 +1148,7 @@ importers:
packages/react:
specifiers:
'@tanstack/react-query': 5.0.0-beta.2
'@trigger.dev/core': workspace:^2.3.9
'@trigger.dev/core': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@types/debug': ^4.1.7
'@types/react': 18.2.17
@@ -1251,8 +1251,8 @@ importers:
packages/trigger-sdk:
specifiers:
'@trigger.dev/core': workspace:^2.3.9
'@trigger.dev/core-backend': workspace:^2.3.9
'@trigger.dev/core': workspace:^2.3.10
'@trigger.dev/core-backend': workspace:^2.3.10
'@trigger.dev/tsconfig': workspace:*
'@trigger.dev/tsup': workspace:*
'@types/debug': ^4.1.7
@@ -19220,13 +19220,13 @@ packages:
eslint: 8.45.0
dev: true
/eslint-config-turbo/1.11.2_eslint@8.31.0:
resolution: {integrity: sha512-vqbyCH6kCHFoIAWUmGL61c0BfUQNz0XAl2RzAnEkSQ+PLXvEvuV2HsvL51UOzyyElfJlzZuh9T4BvUqb5KR9Eg==}
/eslint-config-turbo/1.11.3_eslint@8.31.0:
resolution: {integrity: sha512-v7CHpAHodBKlj+r+R3B2DJlZbCjpZLnK7gO/vCRk/Lc+tlD/f04wM6rmHlerevOlchtmwARilRLBnmzNLffTyQ==}
peerDependencies:
eslint: '>6.6.0'
dependencies:
eslint: 8.31.0
eslint-plugin-turbo: 1.11.2_eslint@8.31.0
eslint-plugin-turbo: 1.11.3_eslint@8.31.0
dev: true
/eslint-doc-generator/1.4.3_eslint@8.45.0:
@@ -19929,8 +19929,8 @@ packages:
- typescript
dev: true
/eslint-plugin-turbo/1.11.2_eslint@8.31.0:
resolution: {integrity: sha512-U6DX+WvgGFiwEAqtOjm4Ejd9O4jsw8jlFNkQi0ywxbMnbiTie+exF4Z0F/B1ajtjjeZkBkgRnlU+UkoraBN+bw==}
/eslint-plugin-turbo/1.11.3_eslint@8.31.0:
resolution: {integrity: sha512-R5ftTTWQzEYaKzF5g6m/MInCU8pIN+2TLL+S50AYBr1enwUovdZmnZ1HDwFMaxIjJ8x5ah+jvAzql5IJE9VWaA==}
peerDependencies:
eslint: '>6.6.0'
dependencies: