chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { tryCatch } from "@trigger.dev/core";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateRequest } from "~/services/apiAuth.server";
|
||||
import { ArchiveBranchService } from "~/services/archiveBranch.server";
|
||||
import { logger } from "~/services/logger.server";
|
||||
import { toBranchableEnvironmentType } from "~/utils/branchableEnvironment";
|
||||
|
||||
const ParamsSchema = z.object({
|
||||
projectRef: z.string(),
|
||||
});
|
||||
|
||||
const BodySchema = z.object({
|
||||
// Defaults to "preview" so existing CLIs that don't send `env` keep working.
|
||||
env: z.enum(["preview", "development"]).default("preview"),
|
||||
branch: z.string(),
|
||||
});
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
if (request.method !== "POST") {
|
||||
return json({ error: "Method not allowed" }, { status: 405 });
|
||||
}
|
||||
|
||||
logger.info("Archive branch", { url: request.url, params });
|
||||
|
||||
const authenticationResult = await authenticateRequest(request, {
|
||||
personalAccessToken: true,
|
||||
organizationAccessToken: true,
|
||||
apiKey: false,
|
||||
});
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing Access Token" }, { status: 401 });
|
||||
}
|
||||
|
||||
const parsedParams = ParamsSchema.safeParse(params);
|
||||
|
||||
if (!parsedParams.success) {
|
||||
return json({ error: "Invalid Params" }, { status: 400 });
|
||||
}
|
||||
|
||||
const { projectRef } = parsedParams.data;
|
||||
|
||||
const [error, body] = await tryCatch(request.json());
|
||||
if (error) {
|
||||
return json({ error: error.message }, { status: 400 });
|
||||
}
|
||||
|
||||
const parsed = BodySchema.safeParse(body);
|
||||
if (!parsed.success) {
|
||||
return json({ error: parsed.error.message }, { status: 400 });
|
||||
}
|
||||
|
||||
const { env, branch } = parsed.data;
|
||||
|
||||
const environmentType = toBranchableEnvironmentType(env);
|
||||
const environments = await prisma.runtimeEnvironment.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
archivedAt: true,
|
||||
},
|
||||
where: {
|
||||
organization:
|
||||
authenticationResult.type === "organizationAccessToken"
|
||||
? { id: authenticationResult.result.organizationId }
|
||||
: {
|
||||
members: {
|
||||
some: {
|
||||
userId: authenticationResult.result.userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
// Dev branches are per-org-member: only the owner may archive their own.
|
||||
...(authenticationResult.type !== "organizationAccessToken" &&
|
||||
environmentType === "DEVELOPMENT"
|
||||
? { orgMember: { userId: authenticationResult.result.userId } }
|
||||
: {}),
|
||||
project: {
|
||||
externalRef: projectRef,
|
||||
},
|
||||
type: environmentType,
|
||||
branchName: branch,
|
||||
},
|
||||
});
|
||||
|
||||
if (environments.length === 0) {
|
||||
return json({ error: "Branch not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
const activeEnvironments = environments.filter((env) => env.archivedAt === null);
|
||||
|
||||
if (
|
||||
authenticationResult.type === "organizationAccessToken" &&
|
||||
environmentType === "DEVELOPMENT" &&
|
||||
activeEnvironments.length > 1
|
||||
) {
|
||||
return json(
|
||||
{
|
||||
error:
|
||||
"Branch name is ambiguous for development environments. Use a personal access token scoped to the branch owner.",
|
||||
},
|
||||
{ status: 409 }
|
||||
);
|
||||
}
|
||||
|
||||
const environment = activeEnvironments[0];
|
||||
|
||||
if (!environment) {
|
||||
return json({ error: "Branch already archived" }, { status: 400 });
|
||||
}
|
||||
|
||||
const service = new ArchiveBranchService();
|
||||
const result = await service.call(
|
||||
authenticationResult.type === "organizationAccessToken"
|
||||
? { type: "orgId", organizationId: authenticationResult.result.organizationId }
|
||||
: { type: "userMembership", userId: authenticationResult.result.userId },
|
||||
{
|
||||
environmentId: environment.id,
|
||||
}
|
||||
);
|
||||
|
||||
if (result.success) {
|
||||
return json(result);
|
||||
} else {
|
||||
return json(result, { status: 400 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user