import { getLinearApi } from "@automate.ax/integration-contracts/linear" import { LINEAR_REACTION_SCHEMA } from "@automate.ax/integration-contracts/linear" import * as z from "zod" import { defineAction } from "../../../automation/actions" import { LINEAR_REACTION_FIELDS } from "../lib/fragments" import { LINEAR_WRITE_ACCOUNT_OPTIONS } from "../lib/scopes" const REACTION_MUTATION_SCHEMA = z.object({ reactionMutation: z.object({ reaction: LINEAR_REACTION_SCHEMA, success: z.literal(true), }), }) const REACTION_DELETE_SCHEMA = z.object({ reactionMutation: z.object({ entityId: z.string(), success: z.literal(true), }), }) /** Adds an emoji reaction to one supported Linear resource. */ export const createLinearReaction = defineAction("Create Linear reaction") .describe("Adds an emoji reaction to an issue, comment, or update.") .account("linear", LINEAR_WRITE_ACCOUNT_OPTIONS) .input( z .object({ /** Comment receiving the reaction. */ commentId: z.string().min(1).optional(), /** Provider-supported emoji name. */ emoji: z.string().min(1), /** Initiative update receiving the reaction. */ initiativeUpdateId: z.string().min(1).optional(), /** Issue receiving the reaction. */ issueId: z.string().min(1).optional(), /** Project update receiving the reaction. */ projectUpdateId: z.string().min(1).optional(), }) .refine( ({ commentId, initiativeUpdateId, issueId, projectUpdateId }) => [commentId, initiativeUpdateId, issueId, projectUpdateId].filter( Boolean, ).length === 1, { message: "Select exactly one Linear resource to react to." }, ), ) .output(LINEAR_REACTION_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { reactionMutation } = await getLinearApi(account.secret).graphql( `mutation LinearReactionCreate($input: ReactionCreateInput!) { reactionMutation: reactionCreate(input: $input) { success reaction { ${LINEAR_REACTION_FIELDS} } } }`, { responseSchema: REACTION_MUTATION_SCHEMA, variables: { input } }, ) return reactionMutation.reaction }) /** Permanently deletes a Linear reaction. */ export const deleteLinearReaction = defineAction("Delete Linear reaction") .describe("Permanently deletes a Linear reaction by ID.") .account("linear", LINEAR_WRITE_ACCOUNT_OPTIONS) .input(z.object({ reactionId: z.string().min(1) })) .output(z.object({ reactionId: z.string() })) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { reactionMutation } = await getLinearApi(account.secret).graphql( `mutation LinearReactionDelete($id: String!) { reactionMutation: reactionDelete(id: $id) { success entityId } }`, { responseSchema: REACTION_DELETE_SCHEMA, variables: { id: input.reactionId }, }, ) return { reactionId: reactionMutation.entityId } })