import * as z from "zod" import { defineAction } from "../../../automation/actions" import { TRELLO_READ_SCOPE, TRELLO_WRITE_SCOPE } from "./scopes" import { getTrelloApi, normalizeTrelloBoardId, TRELLO_BOARD_MEMBERSHIP_SCHEMA, TRELLO_PROVIDER_BOARD_MEMBERSHIP_SCHEMA, toTrelloBoardMembership, } from "@automate.ax/integration-contracts/trello" const TRELLO_ACCOUNT = "trello" const TRELLO_BOARD_MEMBER_ROLE_SCHEMA = z.enum(["admin", "normal", "observer"]) /** Lists Trello board memberships for role-management workflows. */ export const listTrelloBoardMemberships = defineAction( "List Trello board memberships", ) .describe("Lists the stable membership IDs assigned to a Trello board.") .account(TRELLO_ACCOUNT, TRELLO_READ_SCOPE) .input( z.object({ /** Board ID, short link, or standard Trello board URL. */ board: z.string().trim().min(1), /** Membership role filter documented by Trello. */ filter: z.enum(["admins", "all", "none", "normal"]).prefault("all"), }), ) .output(TRELLO_BOARD_MEMBERSHIP_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => { return ( await getTrelloApi(account.secret).request( `boards/${encodeURIComponent(normalizeTrelloBoardId(input.board))}/memberships`, { query: { filter: input.filter }, responseSchema: TRELLO_PROVIDER_BOARD_MEMBERSHIP_SCHEMA.array(), }, ) ).map(toTrelloBoardMembership) }) /** Invites a Trello member to a board by email address. */ export const inviteTrelloBoardMember = defineAction( "Invite Trello board member", ) .describe("Invites a member to a Trello board by email address.") .account(TRELLO_ACCOUNT, TRELLO_WRITE_SCOPE) .input( z.object({ /** Board ID, short link, or standard Trello board URL. */ board: z.string().trim().min(1), /** Email address to invite. */ email: z.email(), /** Full name used when Trello creates a new member account. */ fullName: z.string().trim().min(1).optional(), /** Board role granted to the invited member. */ role: TRELLO_BOARD_MEMBER_ROLE_SCHEMA.prefault("normal"), }), ) .output( z.object({ boardId: z.string(), email: z.email(), role: TRELLO_BOARD_MEMBER_ROLE_SCHEMA, }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const boardId = normalizeTrelloBoardId(input.board) await getTrelloApi(account.secret).request( `boards/${encodeURIComponent(boardId)}/members`, { body: input.fullName ? { fullName: input.fullName } : {}, method: "PUT", query: { email: input.email, type: input.role }, responseSchema: z.unknown(), }, ) return { boardId, email: input.email, role: input.role } }) /** Adds an existing Trello member to a board. */ export const addTrelloBoardMember = defineAction("Add Trello board member") .describe("Adds an existing Trello member to a board.") .account(TRELLO_ACCOUNT, TRELLO_WRITE_SCOPE) .input( z.object({ /** Allow a Workspace administrator to add a multi-board guest. */ allowBillableGuest: z.boolean().optional(), /** Board ID, short link, or standard Trello board URL. */ board: z.string().trim().min(1), /** Stable Trello member ID. */ memberId: z.string().trim().min(1), /** Board role granted to the member. */ role: TRELLO_BOARD_MEMBER_ROLE_SCHEMA.prefault("normal"), }), ) .output( z.object({ boardId: z.string(), memberId: z.string(), role: TRELLO_BOARD_MEMBER_ROLE_SCHEMA, }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const boardId = normalizeTrelloBoardId(input.board) await getTrelloApi(account.secret).request( `boards/${encodeURIComponent(boardId)}/members/${encodeURIComponent(input.memberId)}`, { method: "PUT", query: { allowBillableGuest: input.allowBillableGuest, type: input.role, }, responseSchema: z.unknown(), }, ) return { boardId, memberId: input.memberId, role: input.role } }) /** Removes a Trello member from a board. */ export const removeTrelloBoardMember = defineAction( "Remove Trello board member", ) .describe("Removes a Trello member from a board.") .account(TRELLO_ACCOUNT, TRELLO_WRITE_SCOPE) .input( z.object({ /** Board ID, short link, or standard Trello board URL. */ board: z.string().trim().min(1), /** Stable Trello member ID. */ memberId: z.string().trim().min(1), }), ) .output( z.object({ boardId: z.string(), memberId: z.string(), removed: z.literal(true), }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const boardId = normalizeTrelloBoardId(input.board) await getTrelloApi(account.secret).request( `boards/${encodeURIComponent(boardId)}/members/${encodeURIComponent(input.memberId)}`, { method: "DELETE", responseSchema: z.unknown() }, ) return { boardId, memberId: input.memberId, removed: true as const } }) /** Updates one Trello board membership role. */ export const updateTrelloBoardMemberRole = defineAction( "Update Trello board member role", ) .describe("Updates the role represented by a Trello board membership.") .account(TRELLO_ACCOUNT, TRELLO_WRITE_SCOPE) .input( z.object({ /** Board ID, short link, or standard Trello board URL. */ board: z.string().trim().min(1), /** Stable board membership ID. */ membershipId: z.string().trim().min(1), /** Replacement board role. */ role: TRELLO_BOARD_MEMBER_ROLE_SCHEMA, }), ) .output( z.object({ boardId: z.string(), membershipId: z.string(), role: TRELLO_BOARD_MEMBER_ROLE_SCHEMA, }), ) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const boardId = normalizeTrelloBoardId(input.board) await getTrelloApi(account.secret).request( `boards/${encodeURIComponent(boardId)}/memberships/${encodeURIComponent(input.membershipId)}`, { method: "PUT", query: { type: input.role }, responseSchema: z.unknown(), }, ) return { boardId, membershipId: input.membershipId, role: input.role } })