c0b84595a3
## Summary The server half of hosted webhooks: the public ingress endpoint, signature verification, the delivery pipeline (Postgres partitioned storage + ClickHouse for ordering), the in-app partition manager, the HTTP API, and the dashboard (Deliveries, Endpoints, and the in-app test console). The public SDK and docs half is #4537. That PR carries the user-facing API (`webhook()`, `chat.event` / `chat.channels`, the `@trigger.dev/slack` connector) and builds on the shared `@trigger.dev/core` schemas that ship here. ## Shipping behind a flag A `WEBHOOK_ENABLED` env var (default off) gates the public ingress route and the engine worker plus partition cron, so merging and deploying this changes nothing in production until it is flipped on per environment. The dashboard is separately gated per org by the `hasWebhooksAccess` feature flag. ## Note on packages This PR includes the `@trigger.dev/core` schema additions the server compiles against, but carries no changeset. Core is not consumed independently of the SDK, so it is released together with the SDK via #4537. Keeping its changeset off `main` means no release cut from `main` publishes it early.
897 lines
25 KiB
TypeScript
897 lines
25 KiB
TypeScript
import type { RuntimeEnvironment, TaskRun, WorkerDeployment } from "@trigger.dev/database";
|
|
import { z } from "zod";
|
|
import { type TaskRunListSearchFilters } from "~/components/runs/v3/RunFilters";
|
|
import type { Organization } from "~/models/organization.server";
|
|
import type { Project } from "~/models/project.server";
|
|
import { RUNS_BULK_INSPECTOR_OPEN_VALUE } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/shouldRevalidateRunsList";
|
|
import { objectToSearchParams } from "./searchParams";
|
|
import { type WaitpointSearchParams } from "~/components/runs/v3/WaitpointTokenFilters";
|
|
export type OrgForPath = Pick<Organization, "slug">;
|
|
export type ProjectForPath = Pick<Project, "slug">;
|
|
export type EnvironmentForPath = Pick<RuntimeEnvironment, "slug">;
|
|
export type v3RunForPath = Pick<TaskRun, "friendlyId">;
|
|
export type v3SpanForPath = Pick<TaskRun, "spanId">;
|
|
export type DeploymentForPath = Pick<WorkerDeployment, "shortCode">;
|
|
export type TaskForPath = {
|
|
taskIdentifier: string;
|
|
};
|
|
|
|
export const OrganizationParamsSchema = z.object({
|
|
organizationSlug: z.string(),
|
|
});
|
|
|
|
export const ProjectParamSchema = OrganizationParamsSchema.extend({
|
|
projectParam: z.string(),
|
|
});
|
|
|
|
export const EnvironmentParamSchema = ProjectParamSchema.extend({
|
|
envParam: z.string(),
|
|
});
|
|
|
|
//v3
|
|
export const v3TaskParamsSchema = EnvironmentParamSchema.extend({
|
|
taskParam: z.string(),
|
|
});
|
|
|
|
export const v3RunParamsSchema = EnvironmentParamSchema.extend({
|
|
runParam: z.string(),
|
|
});
|
|
|
|
export const v3SpanParamsSchema = v3RunParamsSchema.extend({
|
|
spanParam: z.string(),
|
|
});
|
|
|
|
export const v3RunStreamParamsSchema = v3RunParamsSchema.extend({
|
|
streamKey: z.string(),
|
|
});
|
|
|
|
export const v3DeploymentParams = EnvironmentParamSchema.extend({
|
|
deploymentParam: z.string(),
|
|
});
|
|
|
|
export const v3ScheduleParams = EnvironmentParamSchema.extend({
|
|
scheduleParam: z.string(),
|
|
});
|
|
|
|
export function rootPath() {
|
|
return `/`;
|
|
}
|
|
|
|
/** Given a path, it makes it an impersonation path */
|
|
export function impersonate(path: string) {
|
|
return `/@${path}`;
|
|
}
|
|
|
|
/**
|
|
* Where a `/@/orgs/<slug>/<splat>` impersonation link lands once impersonation
|
|
* has started: the same deep link with the `/@` prefix stripped.
|
|
*
|
|
* `search` must be carried through explicitly. A `/@/runs/<id>` link redirects
|
|
* to a `v3RunSpanPath`, whose `?span=<spanId>` selects the span to open, so
|
|
* dropping it lands the admin on the run with nothing selected.
|
|
*/
|
|
export function impersonationDestinationPath(
|
|
organizationSlug: string,
|
|
splatPath: string,
|
|
search: string = ""
|
|
) {
|
|
return `/orgs/${organizationSlug}/${splatPath}${search}`;
|
|
}
|
|
|
|
/**
|
|
* Where the impersonation consent page's form must POST back to.
|
|
*
|
|
* The form has to name this path explicitly. A `<Form>` with no `action`
|
|
* resolves to `useResolvedPath(".")`, and because this app does not enable
|
|
* `future.v3_relativeSplatPath`, that resolves to the matched route's
|
|
* `pathnameBase` — which excludes the splat. The form would post to
|
|
* `/@/orgs/<slug>`, the action would see an empty splat, and the admin would
|
|
* land on the organization root instead of the deep link the consent page just
|
|
* promised them.
|
|
*/
|
|
export function impersonationConsentPostBackPath(
|
|
organizationSlug: string,
|
|
splatPath: string,
|
|
search: string = ""
|
|
) {
|
|
return impersonate(impersonationDestinationPath(organizationSlug, splatPath, search));
|
|
}
|
|
|
|
export function accountPath() {
|
|
return `/account`;
|
|
}
|
|
|
|
export function personalAccessTokensPath() {
|
|
return `/account/tokens`;
|
|
}
|
|
|
|
export function accountSecurityPath() {
|
|
return `/account/security`;
|
|
}
|
|
|
|
export function invitesPath() {
|
|
return `/invites`;
|
|
}
|
|
|
|
export function confirmBasicDetailsPath() {
|
|
return `/confirm-basic-details`;
|
|
}
|
|
|
|
export function acceptInvitePath(token: string) {
|
|
return `/invite-accept?token=${token}`;
|
|
}
|
|
|
|
export function resendInvitePath() {
|
|
return `/invite-resend`;
|
|
}
|
|
|
|
export function logoutPath() {
|
|
return `/logout`;
|
|
}
|
|
|
|
export function revokeInvitePath() {
|
|
return `/invite-revoke`;
|
|
}
|
|
|
|
// Org
|
|
export function organizationPath(organization: OrgForPath) {
|
|
return `/orgs/${organizationParam(organization)}`;
|
|
}
|
|
|
|
export function newOrganizationPath() {
|
|
return `/orgs/new`;
|
|
}
|
|
|
|
export function selectPlanPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/select-plan`;
|
|
}
|
|
|
|
export function organizationTeamPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/team`;
|
|
}
|
|
|
|
export function organizationRolesPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/roles`;
|
|
}
|
|
|
|
export function organizationSsoPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/sso`;
|
|
}
|
|
|
|
export function inviteTeamMemberPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/invite`;
|
|
}
|
|
|
|
export function organizationBillingPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/billing`;
|
|
}
|
|
|
|
export function organizationSettingsPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings`;
|
|
}
|
|
|
|
export function organizationIntegrationsPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/integrations`;
|
|
}
|
|
|
|
export function organizationVercelIntegrationPath(organization: OrgForPath) {
|
|
return `${organizationIntegrationsPath(organization)}/vercel`;
|
|
}
|
|
|
|
export function organizationSlackIntegrationPath(organization: OrgForPath) {
|
|
return `${organizationIntegrationsPath(organization)}/slack`;
|
|
}
|
|
|
|
function organizationParam(organization: OrgForPath) {
|
|
return organization.slug;
|
|
}
|
|
|
|
// Project
|
|
export function newProjectPath(organization: OrgForPath, message?: string) {
|
|
return `${organizationPath(organization)}/projects/new${
|
|
message ? `?message=${encodeURIComponent(message)}` : ""
|
|
}`;
|
|
}
|
|
|
|
function projectParam(project: ProjectForPath) {
|
|
return project.slug;
|
|
}
|
|
|
|
function environmentParam(environment: EnvironmentForPath) {
|
|
return environment.slug;
|
|
}
|
|
|
|
//v3 project
|
|
export function v3ProjectPath(organization: OrgForPath, project: ProjectForPath) {
|
|
return `/orgs/${organizationParam(organization)}/projects/${projectParam(project)}`;
|
|
}
|
|
|
|
export function githubAppInstallPath(organizationSlug: string, redirectTo: string) {
|
|
return `/github/install?org_slug=${organizationSlug}&redirect_to=${encodeURIComponent(
|
|
redirectTo
|
|
)}`;
|
|
}
|
|
|
|
export function vercelAppInstallPath(organizationSlug: string, projectSlug: string) {
|
|
return `/vercel/install?org_slug=${organizationSlug}&project_slug=${projectSlug}`;
|
|
}
|
|
|
|
export function vercelCallbackPath() {
|
|
return `/vercel/callback`;
|
|
}
|
|
|
|
export function vercelResourcePath(
|
|
organizationSlug: string,
|
|
projectSlug: string,
|
|
environmentSlug: string
|
|
) {
|
|
return `/resources/orgs/${organizationSlug}/projects/${projectSlug}/env/${environmentSlug}/vercel`;
|
|
}
|
|
|
|
export function v3EnvironmentPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `/orgs/${organizationParam(organization)}/projects/${projectParam(
|
|
project
|
|
)}/env/${environmentParam(environment)}`;
|
|
}
|
|
|
|
export function v3TasksDashboardPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/tasks/dashboard`;
|
|
}
|
|
|
|
export function v3TasksStreamingPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/tasks/stream`;
|
|
}
|
|
|
|
export function v3ApiKeysPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/apikeys`;
|
|
}
|
|
|
|
export function v3BulkActionsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/bulk-actions`;
|
|
}
|
|
|
|
export function v3BulkActionPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
bulkAction: { friendlyId: string }
|
|
) {
|
|
return `${v3BulkActionsPath(organization, project, environment)}/${bulkAction.friendlyId}`;
|
|
}
|
|
|
|
export function v3EnvironmentVariablesPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/environment-variables`;
|
|
}
|
|
|
|
export function v3NewEnvironmentVariablesPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentVariablesPath(organization, project, environment)}/new`;
|
|
}
|
|
|
|
export function v3ProjectAlertsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/alerts`;
|
|
}
|
|
|
|
export function v3NewProjectAlertPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3ProjectAlertsPath(organization, project, environment)}/new`;
|
|
}
|
|
|
|
export function v3NewProjectAlertPathConnectToSlackPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3ProjectAlertsPath(organization, project, environment)}/new/connect-to-slack`;
|
|
}
|
|
|
|
export function v3TestPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/test`;
|
|
}
|
|
|
|
export function queryPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/query`;
|
|
}
|
|
|
|
export function v3CustomDashboardPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
dashboard: { friendlyId: string }
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/dashboards/custom/${
|
|
dashboard.friendlyId
|
|
}`;
|
|
}
|
|
|
|
export function v3BuiltInDashboardPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
key: string
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/dashboards/${key}`;
|
|
}
|
|
|
|
export function v3DashboardsLandingPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/dashboards`;
|
|
}
|
|
|
|
export function v3TestTaskPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
task: TaskForPath
|
|
) {
|
|
return `${v3TestPath(organization, project, environment)}/tasks/${encodeURIComponent(
|
|
task.taskIdentifier
|
|
)}`;
|
|
}
|
|
|
|
export function v3PlaygroundPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/playground`;
|
|
}
|
|
|
|
export function v3PlaygroundAgentPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
agentSlug: string
|
|
) {
|
|
return `${v3PlaygroundPath(organization, project, environment)}/${encodeURIComponent(agentSlug)}`;
|
|
}
|
|
|
|
export function v3AgentTaskPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
agentSlug: string
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/agents/${encodeURIComponent(
|
|
agentSlug
|
|
)}`;
|
|
}
|
|
|
|
export function v3WebhooksPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
// Top-level Webhooks section landing = the cross-endpoint deliveries list.
|
|
return `${v3EnvironmentPath(organization, project, environment)}/webhooks`;
|
|
}
|
|
|
|
export function v3WebhookTaskPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
webhookSlug: string
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/webhooks/${encodeURIComponent(
|
|
webhookSlug
|
|
)}`;
|
|
}
|
|
|
|
export function v3WebhookDeliveryPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
deliveryFriendlyId: string
|
|
) {
|
|
return `${v3EnvironmentPath(
|
|
organization,
|
|
project,
|
|
environment
|
|
)}/webhooks/deliveries/${encodeURIComponent(deliveryFriendlyId)}`;
|
|
}
|
|
|
|
export function v3WebhookEndpointPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
endpointFriendlyId: string
|
|
) {
|
|
return `${v3EnvironmentPath(
|
|
organization,
|
|
project,
|
|
environment
|
|
)}/webhooks/endpoints/${encodeURIComponent(endpointFriendlyId)}`;
|
|
}
|
|
|
|
export function v3StandardTaskPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
taskSlug: string
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/tasks/standard/${encodeURIComponent(
|
|
taskSlug
|
|
)}`;
|
|
}
|
|
|
|
export function v3ScheduledTaskPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
taskSlug: string
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/tasks/scheduled/${encodeURIComponent(
|
|
taskSlug
|
|
)}`;
|
|
}
|
|
|
|
export function v3RunsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
filters?: TaskRunListSearchFilters
|
|
) {
|
|
const searchParams = objectToSearchParams(filters);
|
|
const query = searchParams ? `?${searchParams.toString()}` : "";
|
|
return `${v3EnvironmentPath(organization, project, environment)}/runs${query}`;
|
|
}
|
|
|
|
export function v3CreateBulkActionPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
filters?: TaskRunListSearchFilters,
|
|
mode?: "selected" | "filter",
|
|
action?: "replay" | "cancel"
|
|
) {
|
|
const searchParams = objectToSearchParams(filters) ?? new URLSearchParams();
|
|
searchParams.set("bulkInspector", RUNS_BULK_INSPECTOR_OPEN_VALUE);
|
|
if (mode) {
|
|
searchParams.set("mode", mode);
|
|
}
|
|
if (action) {
|
|
searchParams.set("action", action);
|
|
}
|
|
const query = `?${searchParams.toString()}`;
|
|
return `${v3RunsPath(organization, project, environment)}${query}`;
|
|
}
|
|
|
|
export function v3RunPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
run: v3RunForPath,
|
|
searchParams?: URLSearchParams
|
|
) {
|
|
const query = searchParams ? `?${searchParams.toString()}` : "";
|
|
return `${v3RunsPath(organization, project, environment)}/${run.friendlyId}${query}`;
|
|
}
|
|
|
|
export function v3RunRedirectPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
run: v3RunForPath
|
|
) {
|
|
return `${v3ProjectPath(organization, project)}/runs/${run.friendlyId}`;
|
|
}
|
|
|
|
export function v3RunPathFromFriendlyId(runId: string) {
|
|
return `/runs/${runId}`;
|
|
}
|
|
|
|
export function v3RunDownloadLogsPath(run: v3RunForPath) {
|
|
return `/resources/runs/${run.friendlyId}/logs/download`;
|
|
}
|
|
|
|
export function v3RunSpanPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
run: v3RunForPath,
|
|
span: v3SpanForPath,
|
|
searchParams?: URLSearchParams
|
|
) {
|
|
searchParams = searchParams ?? new URLSearchParams();
|
|
searchParams.set("span", span.spanId);
|
|
return `${v3RunPath(organization, project, environment, run, searchParams)}`;
|
|
}
|
|
|
|
export function v3RunStreamingPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
run: v3RunForPath
|
|
) {
|
|
return `${v3RunPath(organization, project, environment, run)}/stream`;
|
|
}
|
|
|
|
export function v3RunIdempotencyKeyResetPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
run: v3RunForPath
|
|
) {
|
|
return `/resources/orgs/${organizationParam(organization)}/projects/${projectParam(
|
|
project
|
|
)}/env/${environmentParam(environment)}/runs/${run.friendlyId}/idempotencyKey/reset`;
|
|
}
|
|
|
|
export function v3SchedulePath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
schedule: { friendlyId: string }
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/schedules/${
|
|
schedule.friendlyId
|
|
}`;
|
|
}
|
|
|
|
export function v3EditSchedulePath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
schedule: { friendlyId: string }
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/schedules/edit/${
|
|
schedule.friendlyId
|
|
}`;
|
|
}
|
|
|
|
export function v3NewSchedulePath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/schedules/new`;
|
|
}
|
|
|
|
export function v3SchedulesAddOnPath(organization: OrgForPath) {
|
|
return `/resources/orgs/${organizationParam(organization)}/schedules-addon`;
|
|
}
|
|
|
|
export function v3QueuesPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/queues`;
|
|
}
|
|
|
|
export function v3QueuePath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
queue: { friendlyId: string }
|
|
) {
|
|
return `${v3QueuesPath(organization, project, environment)}/${queue.friendlyId}`;
|
|
}
|
|
|
|
export function v3WaitpointTokensPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
filters?: WaitpointSearchParams
|
|
) {
|
|
const searchParams = objectToSearchParams(filters);
|
|
const query = searchParams ? `?${searchParams.toString()}` : "";
|
|
return `${v3EnvironmentPath(organization, project, environment)}/waitpoints/tokens${query}`;
|
|
}
|
|
|
|
export function v3WaitpointTokenPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
token: { id: string },
|
|
filters?: WaitpointSearchParams
|
|
) {
|
|
const searchParams = objectToSearchParams(filters);
|
|
const query = searchParams ? `?${searchParams.toString()}` : "";
|
|
return `${v3WaitpointTokensPath(organization, project, environment)}/${token.id}${query}`;
|
|
}
|
|
|
|
export function v3BatchesPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/batches`;
|
|
}
|
|
|
|
export function v3SessionsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/sessions`;
|
|
}
|
|
|
|
export function v3SessionPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
session: { friendlyId: string }
|
|
) {
|
|
return `${v3SessionsPath(organization, project, environment)}/${session.friendlyId}`;
|
|
}
|
|
|
|
export function v3BatchPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
batch: { friendlyId: string }
|
|
) {
|
|
return `${v3BatchesPath(organization, project, environment)}/${batch.friendlyId}`;
|
|
}
|
|
|
|
export function v3BatchRunsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
batch: { friendlyId: string }
|
|
) {
|
|
return `${v3RunsPath(organization, project, environment, { batchId: batch.friendlyId })}`;
|
|
}
|
|
|
|
export function v3ProjectSettingsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/settings`;
|
|
}
|
|
|
|
export function v3ProjectSettingsGeneralPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3ProjectSettingsPath(organization, project, environment)}/general`;
|
|
}
|
|
|
|
export function v3ProjectSettingsIntegrationsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3ProjectSettingsPath(organization, project, environment)}/integrations`;
|
|
}
|
|
|
|
export function v3LogsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/logs`;
|
|
}
|
|
|
|
export function v3PromptsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/prompts`;
|
|
}
|
|
|
|
export function v3PromptPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
promptSlug: string,
|
|
version?: string | number
|
|
) {
|
|
const base = `${v3PromptsPath(organization, project, environment)}/${promptSlug}`;
|
|
return version != null ? `${base}?version=${version}` : base;
|
|
}
|
|
|
|
export function v3ModelsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/models`;
|
|
}
|
|
|
|
export function v3ModelDetailPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
modelId: string
|
|
) {
|
|
return `${v3ModelsPath(organization, project, environment)}/${modelId}`;
|
|
}
|
|
|
|
export function v3ModelComparePath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3ModelsPath(organization, project, environment)}/compare`;
|
|
}
|
|
|
|
export function v3ErrorsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/errors`;
|
|
}
|
|
|
|
export function v3ErrorsConnectToSlackPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3ErrorsPath(organization, project, environment)}/connect-to-slack`;
|
|
}
|
|
|
|
export function v3ErrorPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
error: { fingerprint: string }
|
|
) {
|
|
return `${v3ErrorsPath(organization, project, environment)}/${error.fingerprint}`;
|
|
}
|
|
|
|
export function v3DeploymentsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/deployments`;
|
|
}
|
|
|
|
export function v3DeploymentPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
deployment: DeploymentForPath,
|
|
currentPage: number
|
|
) {
|
|
const query = currentPage ? `?page=${currentPage}` : "";
|
|
return `${v3DeploymentsPath(organization, project, environment)}/${deployment.shortCode}${query}`;
|
|
}
|
|
|
|
export function v3DeploymentVersionPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath,
|
|
version: string
|
|
) {
|
|
return `${v3DeploymentsPath(organization, project, environment)}?version=${version}`;
|
|
}
|
|
|
|
export function branchesPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/branches`;
|
|
}
|
|
|
|
export function branchesDevPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/dev-branches`;
|
|
}
|
|
|
|
export function concurrencyPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/concurrency`;
|
|
}
|
|
|
|
export function limitsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/limits`;
|
|
}
|
|
|
|
export function regionsPath(
|
|
organization: OrgForPath,
|
|
project: ProjectForPath,
|
|
environment: EnvironmentForPath
|
|
) {
|
|
return `${v3EnvironmentPath(organization, project, environment)}/regions`;
|
|
}
|
|
|
|
export function v3BillingPath(organization: OrgForPath, message?: string) {
|
|
return `${organizationPath(organization)}/settings/billing${
|
|
message ? `?message=${encodeURIComponent(message)}` : ""
|
|
}`;
|
|
}
|
|
|
|
export function v3BillingLimitsPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/billing-limits`;
|
|
}
|
|
|
|
/** @deprecated Use v3BillingLimitsPath — redirects from billing-alerts are preserved */
|
|
export function v3BillingAlertsPath(organization: OrgForPath) {
|
|
return v3BillingLimitsPath(organization);
|
|
}
|
|
|
|
export function v3PrivateConnectionsPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/private-connections`;
|
|
}
|
|
|
|
export function v3NewPrivateConnectionPath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/private-connections/new`;
|
|
}
|
|
|
|
export function v3StripePortalPath(organization: OrgForPath) {
|
|
return `/resources/${organization.slug}/subscription/portal`;
|
|
}
|
|
|
|
export function v3UsagePath(organization: OrgForPath) {
|
|
return `${organizationPath(organization)}/settings/usage`;
|
|
}
|
|
|
|
// Docs
|
|
export function docsRoot() {
|
|
return "https://trigger.dev/docs";
|
|
}
|
|
|
|
export function docsPath(path: string) {
|
|
return `${docsRoot()}/${path.replace(/^\//, "")}`;
|
|
}
|
|
|
|
export function docsTroubleshootingPath(path: string) {
|
|
return `${docsRoot()}/v3/troubleshooting`;
|
|
}
|
|
|
|
export function adminPath() {
|
|
return `/@`;
|
|
}
|