"use server";
import {
type InlinedFile,
type ProjectSettings,
SkipAutoDetectionConfirmation,
} from "@vercel/sdk/models/createdeploymentop.js";
import { VERCEL_TEAM_ID, vercel } from "../lib/vercel";
const MAX_PROJECT_NAME_LENGTH = 100;
function sanitizeProjectName(name: string): string {
return name
.toLowerCase()
.replace(/[^a-z0-9._-]/g, "-")
.replace(/-{2,}/g, "-")
.replace(/^-+|-+$/g, "")
.slice(0, MAX_PROJECT_NAME_LENGTH);
}
export async function deployFiles(args?: {
deploymentName?: string | undefined;
config?: ProjectSettings;
domain?: string;
}) {
// you can update this to load the project id from your database instead
const projectId = process.env.DEPLOY_FILES_PROJECT_ID;
const files: InlinedFile[] = [
{
file: "index.html",
data: `<h1 style="color: #${Math.floor(Math.random() * 16_777_215).toString(16)}; font-size: ${Math.floor(Math.random() * 20) + 24}px;">Hello, world!</h1>`,
},
];
const { deploymentName = crypto.randomUUID(), config, domain } = args ?? {};
const sanitizedName = sanitizeProjectName(deploymentName);
const deployment = await vercel.deployments.createDeployment({
requestBody: {
name: sanitizedName,
files,
project: projectId,
projectSettings: config,
target: "production",
},
skipAutoDetectionConfirmation: config
? SkipAutoDetectionConfirmation.Zero
: SkipAutoDetectionConfirmation.One,
teamId: VERCEL_TEAM_ID,
});
// if you want your preview deployments to be public, you can do this by setting the ssoProtection to null
if (!projectId) {
await vercel.projects.updateProject({
requestBody: { ssoProtection: null },
idOrName: deployment.projectId,
teamId: VERCEL_TEAM_ID,
});
}
if (domain) {
await vercel.projects.addProjectDomain({
idOrName: deployment.projectId,
requestBody: {
name: domain,
},
teamId: VERCEL_TEAM_ID,
});
}
return deployment;
}
export async function getDeploymentStatus(id: string) {
const deployment = await vercel.deployments.getDeployment({
idOrUrl: id,
});
return {
readyState: deployment.readyState,
url: deployment.url,
id: deployment.id,
};
}