chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import {
|
||||
ApiDeploymentListSearchParams,
|
||||
InitializeDeploymentRequestBody,
|
||||
type InitializeDeploymentResponseBody,
|
||||
} from "@trigger.dev/core/v3";
|
||||
import { $replica } from "~/db.server";
|
||||
import { authenticateApiRequest } from "~/services/apiAuth.server";
|
||||
import { logger } from "~/services/logger.server";
|
||||
import { createLoaderApiRoute } from "~/services/routeBuilders/apiBuilder.server";
|
||||
import { ServiceValidationError } from "~/v3/services/baseService.server";
|
||||
import { InitializeDeploymentService } from "~/v3/services/initializeDeployment.server";
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Ensure this is a POST request
|
||||
if (request.method.toUpperCase() !== "POST") {
|
||||
return { status: 405, body: "Method Not Allowed" };
|
||||
}
|
||||
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequest(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
logger.info("Invalid or missing api key", { url: request.url });
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const rawBody = await request.json();
|
||||
const body = InitializeDeploymentRequestBody.safeParse(rawBody);
|
||||
|
||||
if (!body.success) {
|
||||
return json({ error: "Invalid body", issues: body.error.issues }, { status: 400 });
|
||||
}
|
||||
|
||||
const authenticatedEnv = authenticationResult.environment;
|
||||
|
||||
const service = new InitializeDeploymentService();
|
||||
|
||||
try {
|
||||
const { deployment, imageRef, eventStream } = await service.call(authenticatedEnv, body.data);
|
||||
|
||||
const responseBody: InitializeDeploymentResponseBody = {
|
||||
id: deployment.friendlyId,
|
||||
contentHash: deployment.contentHash,
|
||||
shortCode: deployment.shortCode,
|
||||
version: deployment.version,
|
||||
externalBuildData:
|
||||
deployment.externalBuildData as InitializeDeploymentResponseBody["externalBuildData"],
|
||||
imageTag: imageRef,
|
||||
imagePlatform: deployment.imagePlatform,
|
||||
eventStream,
|
||||
};
|
||||
|
||||
return json(responseBody, { status: 200 });
|
||||
} catch (error) {
|
||||
if (error instanceof ServiceValidationError) {
|
||||
return json({ error: error.message }, { status: 400 });
|
||||
}
|
||||
|
||||
logger.error("Error initializing deployment", { error });
|
||||
return json({ error: "Internal server error" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export const loader = createLoaderApiRoute(
|
||||
{
|
||||
searchParams: ApiDeploymentListSearchParams,
|
||||
allowJWT: true,
|
||||
corsStrategy: "none",
|
||||
authorization: {
|
||||
action: "read",
|
||||
resource: () => ({ type: "deployments", id: "list" }),
|
||||
},
|
||||
findResource: async () => 1, // This is a dummy function, we don't need to find a resource
|
||||
},
|
||||
async ({ searchParams, authentication }) => {
|
||||
const limit = Math.max(Math.min(searchParams["page[size]"] ?? 20, 100), 5);
|
||||
|
||||
const afterDeployment = searchParams["page[after]"]
|
||||
? await $replica.workerDeployment.findFirst({
|
||||
where: {
|
||||
friendlyId: searchParams["page[after]"],
|
||||
environmentId: authentication.environment.id,
|
||||
},
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const deployments = await $replica.workerDeployment.findMany({
|
||||
where: {
|
||||
environmentId: authentication.environment.id,
|
||||
...(afterDeployment ? { id: { lt: afterDeployment.id } } : {}),
|
||||
...getCreatedAtFilter(searchParams),
|
||||
...(searchParams.status ? { status: searchParams.status } : {}),
|
||||
},
|
||||
orderBy: {
|
||||
id: "desc",
|
||||
},
|
||||
take: limit + 1,
|
||||
});
|
||||
|
||||
const hasMore = deployments.length > limit;
|
||||
const nextCursor = hasMore ? deployments[limit - 1].friendlyId : undefined;
|
||||
const data = hasMore ? deployments.slice(0, limit) : deployments;
|
||||
|
||||
return json({
|
||||
data: data.map((deployment) => ({
|
||||
id: deployment.friendlyId,
|
||||
createdAt: deployment.createdAt,
|
||||
shortCode: deployment.shortCode,
|
||||
version: deployment.version.toString(),
|
||||
runtime: deployment.runtime,
|
||||
runtimeVersion: deployment.runtimeVersion,
|
||||
status: deployment.status,
|
||||
deployedAt: deployment.deployedAt,
|
||||
git: deployment.git,
|
||||
error: deployment.errorData ?? undefined,
|
||||
})),
|
||||
pagination: {
|
||||
next: nextCursor,
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
import parseDuration from "parse-duration";
|
||||
import { parseDate } from "@trigger.dev/core/v3/isomorphic";
|
||||
|
||||
function getCreatedAtFilter(searchParams: ApiDeploymentListSearchParams) {
|
||||
if (searchParams.period) {
|
||||
const duration = parseDuration(searchParams.period, "ms");
|
||||
|
||||
if (!duration) {
|
||||
throw new ServiceValidationError(
|
||||
`Invalid search query parameter: period=${searchParams.period}`,
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
createdAt: {
|
||||
gte: new Date(Date.now() - duration),
|
||||
lte: new Date(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (searchParams.from && searchParams.to) {
|
||||
const fromDate = safeDateFromString(searchParams.from, "from");
|
||||
const toDate = safeDateFromString(searchParams.to, "to");
|
||||
|
||||
return {
|
||||
createdAt: {
|
||||
gte: fromDate,
|
||||
lte: toDate,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (searchParams.from) {
|
||||
const fromDate = safeDateFromString(searchParams.from, "from");
|
||||
return {
|
||||
createdAt: {
|
||||
gte: fromDate,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
function safeDateFromString(value: string, paramName: string) {
|
||||
const date = parseDate(value);
|
||||
|
||||
if (!date) {
|
||||
throw new ServiceValidationError(`Invalid search query parameter: ${paramName}=${value}`, 400);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
Reference in New Issue
Block a user