Files
triggerdotdev--trigger.dev/packages/cli-v3/src/apiClient.ts
T
Eric Allam ba71f959e2 v3: Runs List Management SDK and SDK improvements (#1133)
* Improved the existing runs API

* WIP next runs API

* Improve the returned ApiPromise to add ability to return response

* More WIP

* WI{

* Added offset/limit pagination stuff like the cursor one, and converted all API methods to use ApiPromise

* More run API stuff

- Adding schedule  output from the retrieveRun endpoint
- Ability to filter by schedule and isTest

* Remove env from retrieve run in openAPI

* prefer duplication over merge

* WIP docs

* Use spread to DRY up some run API schemas

* Finish the overview docs

* Adding changeset

* Fixed typecheck errors

* Typo fix

* Re-export zodfetch from core so the v3 CLI can use it

* Fixed type errors

---------

Co-authored-by: Matt Aitken <matt@mattaitken.com>
2024-05-31 11:02:28 +01:00

285 lines
7.1 KiB
TypeScript

import { z } from "zod";
import {
CreateAuthorizationCodeResponseSchema,
GetPersonalAccessTokenResponseSchema,
WhoAmIResponseSchema,
CreateBackgroundWorkerRequestBody,
CreateBackgroundWorkerResponse,
StartDeploymentIndexingResponseBody,
GetProjectEnvResponse,
GetEnvironmentVariablesResponseBody,
InitializeDeploymentResponseBody,
InitializeDeploymentRequestBody,
StartDeploymentIndexingRequestBody,
GetDeploymentResponseBody,
GetProjectsResponseBody,
GetProjectResponseBody,
ImportEnvironmentVariablesRequestBody,
EnvironmentVariableResponseBody,
TaskRunExecution,
} from "@trigger.dev/core/v3";
import { zodfetch, ApiError } from "@trigger.dev/core/v3/zodfetch";
export class CliApiClient {
private readonly apiURL: string;
constructor(
apiURL: string,
private readonly accessToken?: string
) {
this.apiURL = apiURL.replace(/\/$/, "");
}
async createAuthorizationCode() {
return wrapZodFetch(
CreateAuthorizationCodeResponseSchema,
`${this.apiURL}/api/v1/authorization-code`,
{
method: "POST",
}
);
}
async getPersonalAccessToken(authorizationCode: string) {
return wrapZodFetch(GetPersonalAccessTokenResponseSchema, `${this.apiURL}/api/v1/token`, {
method: "POST",
body: JSON.stringify({
authorizationCode,
}),
});
}
async whoAmI() {
if (!this.accessToken) {
throw new Error("whoAmI: No access token");
}
return wrapZodFetch(WhoAmIResponseSchema, `${this.apiURL}/api/v2/whoami`, {
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
});
}
async getProject(projectRef: string) {
if (!this.accessToken) {
throw new Error("getProject: No access token");
}
return wrapZodFetch(GetProjectResponseBody, `${this.apiURL}/api/v1/projects/${projectRef}`, {
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
});
}
async getProjects() {
if (!this.accessToken) {
throw new Error("getProjects: No access token");
}
return wrapZodFetch(GetProjectsResponseBody, `${this.apiURL}/api/v1/projects`, {
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
});
}
async createBackgroundWorker(projectRef: string, body: CreateBackgroundWorkerRequestBody) {
if (!this.accessToken) {
throw new Error("createBackgroundWorker: No access token");
}
return wrapZodFetch(
CreateBackgroundWorkerResponse,
`${this.apiURL}/api/v1/projects/${projectRef}/background-workers`,
{
method: "POST",
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
}
async createTaskRunAttempt(runFriendlyId: string) {
if (!this.accessToken) {
throw new Error("creatTaskRunAttempt: No access token");
}
return wrapZodFetch(TaskRunExecution, `${this.apiURL}/api/v1/runs/${runFriendlyId}/attempts`, {
method: "POST",
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
});
}
async getProjectEnv({
projectRef,
env,
}: {
projectRef: string;
env: "dev" | "prod" | "staging";
}) {
if (!this.accessToken) {
throw new Error("getProjectDevEnv: No access token");
}
return wrapZodFetch(
GetProjectEnvResponse,
`${this.apiURL}/api/v1/projects/${projectRef}/${env}`,
{
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
}
);
}
async getEnvironmentVariables(projectRef: string) {
if (!this.accessToken) {
throw new Error("getEnvironmentVariables: No access token");
}
return wrapZodFetch(
GetEnvironmentVariablesResponseBody,
`${this.apiURL}/api/v1/projects/${projectRef}/envvars`,
{
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
}
);
}
async importEnvVars(
projectRef: string,
slug: "dev" | "prod" | "staging",
params: ImportEnvironmentVariablesRequestBody
) {
if (!this.accessToken) {
throw new Error("importEnvVars: No access token");
}
return wrapZodFetch(
EnvironmentVariableResponseBody,
`${this.apiURL}/api/v1/projects/${projectRef}/envvars/${slug}/import`,
{
method: "POST",
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(params),
}
);
}
async initializeDeployment(body: InitializeDeploymentRequestBody) {
if (!this.accessToken) {
throw new Error("initializeDeployment: No access token");
}
return wrapZodFetch(InitializeDeploymentResponseBody, `${this.apiURL}/api/v1/deployments`, {
method: "POST",
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
}
async startDeploymentIndexing(deploymentId: string, body: StartDeploymentIndexingRequestBody) {
if (!this.accessToken) {
throw new Error("startDeploymentIndexing: No access token");
}
return wrapZodFetch(
StartDeploymentIndexingResponseBody,
`${this.apiURL}/api/v1/deployments/${deploymentId}/start-indexing`,
{
method: "POST",
headers: {
Authorization: `Bearer ${this.accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
}
async getDeployment(deploymentId: string) {
if (!this.accessToken) {
throw new Error("getDeployment: No access token");
}
return wrapZodFetch(
GetDeploymentResponseBody,
`${this.apiURL}/api/v1/deployments/${deploymentId}`,
{
headers: {
Authorization: `Bearer ${this.accessToken}`,
Accept: "application/json",
},
}
);
}
}
type ApiResult<TSuccessResult> =
| { success: true; data: TSuccessResult }
| {
success: false;
error: string;
};
async function wrapZodFetch<T extends z.ZodTypeAny>(
schema: T,
url: string,
requestInit?: RequestInit
): Promise<ApiResult<z.infer<T>>> {
try {
const response = await zodfetch(schema, url, requestInit, {
retry: {
minTimeoutInMs: 500,
maxTimeoutInMs: 5000,
maxAttempts: 3,
factor: 2,
randomize: false,
},
});
return {
success: true,
data: response,
};
} catch (error) {
if (error instanceof ApiError) {
return {
success: false,
error: error.message,
};
} else if (error instanceof Error) {
return {
success: false,
error: error.message,
};
} else {
return {
success: false,
error: String(error),
};
}
}
}