import * as z from "zod" import { defineAction } from "../../../automation/actions" import { getVercelApi, getVercelTeamId, vercelAccountOptions } from "../lib/api" import { CREATED_VERCEL_ENVIRONMENT_VARIABLE_SCHEMA, REMOVED_VERCEL_ENVIRONMENT_VARIABLE_SCHEMA, UPDATED_VERCEL_ENVIRONMENT_VARIABLE_SCHEMA, VERCEL_ENVIRONMENT_VARIABLES_SCHEMA, } from "../lib/schemas" import { VERCEL_PROJECT_ENV_VARS_READ_REQUIREMENT, VERCEL_PROJECT_ENV_VARS_WRITE_REQUIREMENT, } from "../lib/scopes" const VERCEL_ENVIRONMENT_TARGET_SCHEMA = z.enum([ "development", "preview", "production", ]) const VERCEL_ENVIRONMENT_VARIABLE_TYPE_SCHEMA = z.enum([ "encrypted", "plain", "sensitive", "system", ]) const VERCEL_PROJECT_ENVIRONMENT_SCOPE_SCHEMA = z.object({ /** Project ID or name. */ project: z.string().min(1), /** Team ID. OAuth accounts default to the installed team. */ teamId: z.string().min(1).optional(), }) /** Lists environment variables visible to the Vercel integration. */ export const listVercelProjectEnvironmentVariables = defineAction( "List Vercel project environment variables", ) .describe("Lists environment variables for one Vercel project.") .account( "vercel", vercelAccountOptions(VERCEL_PROJECT_ENV_VARS_READ_REQUIREMENT), ) .input( VERCEL_PROJECT_ENVIRONMENT_SCOPE_SCHEMA.extend({ /** Filter by a custom environment ID. */ customEnvironmentId: z.string().min(1).optional(), /** Filter by a preview Git branch. */ gitBranch: z.string().min(1).optional(), }), ) .output(VERCEL_ENVIRONMENT_VARIABLES_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.filterProjectEnvs({ idOrName: input.project, ...(input.customEnvironmentId && { customEnvironmentId: input.customEnvironmentId, }), ...(input.gitBranch && { gitBranch: input.gitBranch }), ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Creates or upserts one Vercel project environment variable. */ export const createVercelProjectEnvironmentVariable = defineAction( "Create Vercel project environment variable", ) .describe("Creates or upserts one environment variable on a Vercel project.") .account( "vercel", vercelAccountOptions(VERCEL_PROJECT_ENV_VARS_WRITE_REQUIREMENT), ) .input( VERCEL_PROJECT_ENVIRONMENT_SCOPE_SCHEMA.extend({ /** Human-readable context for the variable. */ comment: z.string().optional(), /** Custom environments that receive the variable. */ customEnvironmentIds: z.string().min(1).array().optional(), /** Preview Git branch. Requires `preview` in `targets`. */ gitBranch: z.string().min(1).optional(), /** Environment variable name. */ key: z.string().min(1), /** Standard deployment targets. */ targets: VERCEL_ENVIRONMENT_TARGET_SCHEMA.array().prefault([ "production", "preview", "development", ]), /** Storage type. `encrypted` is Vercel's recommended default. */ type: VERCEL_ENVIRONMENT_VARIABLE_TYPE_SCHEMA.prefault("encrypted"), /** Update an existing variable with the same key and target. */ upsert: z.boolean().prefault(false), /** Environment variable value. */ value: z.string(), }), ) .output(CREATED_VERCEL_ENVIRONMENT_VARIABLE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.createProjectEnv({ idOrName: input.project, upsert: input.upsert ? "true" : undefined, requestBody: { key: input.key, target: input.targets, type: input.type, value: input.value, ...(input.comment !== undefined && { comment: input.comment }), ...(input.customEnvironmentIds && { customEnvironmentIds: input.customEnvironmentIds, }), ...(input.gitBranch && { gitBranch: input.gitBranch }), }, ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Updates selected fields on a Vercel project environment variable. */ export const updateVercelProjectEnvironmentVariable = defineAction( "Update Vercel project environment variable", ) .describe("Updates selected fields on one project environment variable.") .account( "vercel", vercelAccountOptions(VERCEL_PROJECT_ENV_VARS_WRITE_REQUIREMENT), ) .input( VERCEL_PROJECT_ENVIRONMENT_SCOPE_SCHEMA.extend({ /** New human-readable context. */ comment: z.string().optional(), /** Replacement custom environment IDs. */ customEnvironmentIds: z.string().min(1).array().optional(), /** Environment variable ID. */ environmentVariableId: z.string().min(1), /** Replacement preview Git branch, or `null` to clear it. */ gitBranch: z.string().min(1).nullable().optional(), /** Replacement environment variable name. */ key: z.string().min(1).optional(), /** Replacement standard deployment targets. */ targets: VERCEL_ENVIRONMENT_TARGET_SCHEMA.array().optional(), /** Replacement storage type. */ type: VERCEL_ENVIRONMENT_VARIABLE_TYPE_SCHEMA.optional(), /** Replacement environment variable value. */ value: z.string().optional(), }), ) .output(UPDATED_VERCEL_ENVIRONMENT_VARIABLE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.editProjectEnv({ id: input.environmentVariableId, idOrName: input.project, requestBody: { ...(input.comment !== undefined && { comment: input.comment }), ...(input.customEnvironmentIds && { customEnvironmentIds: input.customEnvironmentIds, }), ...(input.gitBranch !== undefined && { gitBranch: input.gitBranch }), ...(input.key && { key: input.key }), ...(input.targets && { target: input.targets }), ...(input.type && { type: input.type }), ...(input.value !== undefined && { value: input.value }), }, ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Deletes one Vercel project environment variable. */ export const deleteVercelProjectEnvironmentVariable = defineAction( "Delete Vercel project environment variable", ) .describe("Deletes one environment variable from a Vercel project.") .account( "vercel", vercelAccountOptions(VERCEL_PROJECT_ENV_VARS_WRITE_REQUIREMENT), ) .input( VERCEL_PROJECT_ENVIRONMENT_SCOPE_SCHEMA.extend({ /** Restrict deletion to one custom environment. */ customEnvironmentId: z.string().min(1).optional(), /** Environment variable ID. */ environmentVariableId: z.string().min(1), }), ) .output(REMOVED_VERCEL_ENVIRONMENT_VARIABLE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.removeProjectEnv({ id: input.environmentVariableId, idOrName: input.project, ...(input.customEnvironmentId && { customEnvironmentId: input.customEnvironmentId, }), ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), ) /** Deletes several Vercel project environment variables atomically. */ export const batchDeleteVercelProjectEnvironmentVariables = defineAction( "Batch delete Vercel project environment variables", ) .describe("Deletes several environment variables from one Vercel project.") .account( "vercel", vercelAccountOptions(VERCEL_PROJECT_ENV_VARS_WRITE_REQUIREMENT), ) .input( VERCEL_PROJECT_ENVIRONMENT_SCOPE_SCHEMA.extend({ /** Environment variable IDs. */ environmentVariableIds: z.string().min(1).array().min(1), }), ) .output( z.object({ deleted: z.number().int().nonnegative(), ids: z.string().array(), }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getVercelApi(account).projects.batchRemoveProjectEnv({ idOrName: input.project, requestBody: { ids: input.environmentVariableIds }, ...(getVercelTeamId(account, input.teamId) && { teamId: getVercelTeamId(account, input.teamId), }), }), )