import * as z from "zod" import { CreateProjectFramework } from "@vercel/sdk/models/createprojectpassport.js" import { defineAction } from "../../../automation/actions" import { getVercelApi, getVercelTeamId, vercelAccessTokenAccountOptions, vercelAccountOptions, } from "../lib/api" import { CREATED_VERCEL_PROJECT_SCHEMA, UPDATED_VERCEL_PROJECT_SCHEMA, VERCEL_PROJECT_PAGE_SCHEMA, VERCEL_PROJECT_SCHEMA, } from "../lib/schemas" import { VERCEL_PROJECT_READ_SCOPE, VERCEL_PROJECT_WRITE_SCOPE, } from "../lib/scopes" const VERCEL_PROJECT_SETTINGS_SCHEMA = z.object({ /** Command used to build the project, or `null` for auto-detection. */ buildCommand: z.string().nullable().optional(), /** Command used to run the project locally, or `null` for auto-detection. */ devCommand: z.string().nullable().optional(), /** Enable affected-project detection for monorepos. */ enableAffectedProjectsDeployments: z.boolean().optional(), /** Show the Vercel toolbar on preview deployments. */ enablePreviewFeedback: z.boolean().nullable().optional(), /** Show the Vercel toolbar on production deployments. */ enableProductionFeedback: z.boolean().nullable().optional(), /** Vercel framework slug. */ framework: z.enum(CreateProjectFramework).optional(), /** Command used to install dependencies, or `null` for auto-detection. */ installCommand: z.string().nullable().optional(), /** Project output directory, or `null` for auto-detection. */ outputDirectory: z.string().nullable().optional(), /** Disable automatic preview deployments. */ previewDeploymentsDisabled: z.boolean().nullable().optional(), /** Project root within a repository, or `null` for the repository root. */ rootDirectory: z.string().nullable().optional(), /** Region used for the project's serverless functions. */ serverlessFunctionRegion: z.string().nullable().optional(), }) const VERCEL_PROJECT_SCOPE_SCHEMA = z.object({ /** Team ID. OAuth accounts default to the installed team. */ teamId: z.string().min(1).optional(), }) /** Lists Vercel projects with search and cursor pagination. */ export const listVercelProjects = defineAction("List Vercel projects") .describe("Lists a page of projects in the selected Vercel account or team.") .account("vercel", vercelAccountOptions(VERCEL_PROJECT_READ_SCOPE)) .input( VERCEL_PROJECT_SCOPE_SCHEMA.extend({ /** Provider continuation token returned by a previous page. */ from: z.string().min(1).optional(), /** Maximum projects to return. */ limit: z.number().int().min(1).max(100).prefault(20), /** Filter by repository URL or provider repository path. */ repository: z.string().min(1).optional(), /** Search project names. */ search: z.string().min(1).optional(), }), ) .output(VERCEL_PROJECT_PAGE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.getProjects({ limit: String(input.limit), ...(input.from && { from: input.from }), ...(input.repository && { repo: input.repository }), ...(input.search && { search: input.search }), ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Gets one Vercel project by ID or name. */ export const getVercelProject = defineAction("Get Vercel project") .describe("Gets complete settings for one Vercel project by ID or name.") .account("vercel", vercelAccountOptions(VERCEL_PROJECT_READ_SCOPE)) .input( VERCEL_PROJECT_SCOPE_SCHEMA.extend({ /** Project ID or name. */ project: z.string().min(1), }), ) .output(VERCEL_PROJECT_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.getProject({ idOrName: input.project, ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Creates a Vercel project with common build settings. */ export const createVercelProject = defineAction("Create Vercel project") .describe("Creates a Vercel project with optional repository build settings.") .account("vercel", vercelAccountOptions(VERCEL_PROJECT_WRITE_SCOPE)) .input( VERCEL_PROJECT_SCOPE_SCHEMA.extend({ /** Desired project name. */ name: z.string().min(1), /** Common build and project settings. */ settings: VERCEL_PROJECT_SETTINGS_SCHEMA.prefault({}), }), ) .output(CREATED_VERCEL_PROJECT_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.createProject({ requestBody: { name: input.name, ...input.settings }, ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Updates common Vercel project and build settings. */ export const updateVercelProject = defineAction("Update Vercel project") .describe("Updates selected settings on one Vercel project.") .account("vercel", vercelAccountOptions(VERCEL_PROJECT_WRITE_SCOPE)) .input( VERCEL_PROJECT_SCOPE_SCHEMA.extend({ /** New project name. */ name: z.string().min(1).optional(), /** Project ID or current name. */ project: z.string().min(1), /** Common build and project settings. */ settings: VERCEL_PROJECT_SETTINGS_SCHEMA.prefault({}), }), ) .output(UPDATED_VERCEL_PROJECT_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.updateProject({ idOrName: input.project, requestBody: { ...input.settings, ...(input.name && { name: input.name }), }, ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Permanently deletes a Vercel project. */ export const deleteVercelProject = defineAction("Delete Vercel project") .describe("Permanently deletes one Vercel project by ID or name.") .account("vercel", vercelAccountOptions(VERCEL_PROJECT_WRITE_SCOPE)) .input( VERCEL_PROJECT_SCOPE_SCHEMA.extend({ /** Project ID or name. */ project: z.string().min(1), }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.deleteProject({ idOrName: input.project, ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Pauses production and preview deployments for one Vercel project. */ export const pauseVercelProject = defineAction("Pause Vercel project") .describe("Pauses production and preview deployments for one project.") .account("vercel", vercelAccessTokenAccountOptions()) .input( z.object({ /** Project ID. */ projectId: z.string().min(1), /** Team ID for a team-owned project. */ teamId: z.string().min(1).optional(), }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.pauseProject({ projectId: input.projectId, ...(input.teamId && { teamId: input.teamId }), }), ) /** Resumes production and preview deployments for one Vercel project. */ export const unpauseVercelProject = defineAction("Unpause Vercel project") .describe("Resumes production and preview deployments for one project.") .account("vercel", vercelAccessTokenAccountOptions()) .input( z.object({ /** Project ID. */ projectId: z.string().min(1), /** Team ID for a team-owned project. */ teamId: z.string().min(1).optional(), }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.unpauseProject({ projectId: input.projectId, ...(input.teamId && { teamId: input.teamId }), }), )