import { CLICKUP_FOLDER_SCHEMA, CLICKUP_LIST_SCHEMA, CLICKUP_SPACE_SCHEMA, } from "@automate.ax/integration-contracts/clickup" import * as z from "zod" import { defineAction } from "../../../automation/actions" import { CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT, CLICKUP_ID_SCHEMA, CLICKUP_TIMESTAMP_SCHEMA, CLICKUP_VOID_RESPONSE_SCHEMA, compactClickUpInput, getClickUpApi, } from "./lib" const SPACE_FEATURE_SCHEMA = z.object({ enabled: z.boolean() }) const DUE_DATE_FEATURE_SCHEMA = SPACE_FEATURE_SCHEMA.extend({ remapClosedDueDate: z.boolean().prefault(false), remapDueDates: z.boolean().prefault(false), startDate: z.boolean().prefault(false), }) const SPACE_FEATURES_SCHEMA = z.object({ checklists: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), customFields: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), dependencyWarning: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), dueDates: DUE_DATE_FEATURE_SCHEMA.prefault({ enabled: true }), portfolios: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), remapDependencies: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), tags: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), timeEstimates: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), timeTracking: SPACE_FEATURE_SCHEMA.prefault({ enabled: true }), }) const LIST_WRITE_FIELDS = { content: z.string().optional(), dueDate: CLICKUP_TIMESTAMP_SCHEMA.optional(), dueDateTime: z.boolean().optional(), markdownContent: z.string().optional(), name: z.string().trim().min(1), priority: z.number().int().min(1).max(4).optional(), status: z.string().optional(), } as const const LIST_CREATE_SCHEMA = z.object({ ...LIST_WRITE_FIELDS, assignee: z.number().int().optional(), }) const LIST_RESPONSE_SCHEMA = CLICKUP_LIST_SCHEMA const LISTS_RESPONSE_SCHEMA = z.object({ lists: CLICKUP_LIST_SCHEMA.array() }) const FOLDERS_RESPONSE_SCHEMA = z.object({ folders: CLICKUP_FOLDER_SCHEMA.array(), }) const SPACES_RESPONSE_SCHEMA = z.object({ spaces: CLICKUP_SPACE_SCHEMA.array(), }) export const listClickUpSpaces = defineAction("List ClickUp Spaces") .describe("Lists Spaces in a ClickUp Workspace.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ archived: z.boolean().prefault(false), workspaceId: CLICKUP_ID_SCHEMA, }), ) .output(SPACES_RESPONSE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`team/${input.workspaceId}/space`, { query: { archived: input.archived }, responseSchema: SPACES_RESPONSE_SCHEMA, }), ) export const getClickUpSpace = defineAction("Get ClickUp Space") .describe("Gets a ClickUp Space.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input(z.object({ spaceId: CLICKUP_ID_SCHEMA })) .output(CLICKUP_SPACE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`space/${input.spaceId}`, { responseSchema: CLICKUP_SPACE_SCHEMA, }), ) export const createClickUpSpace = defineAction("Create ClickUp Space") .describe("Creates a Space in a ClickUp Workspace.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ features: SPACE_FEATURES_SCHEMA.prefault({}), multipleAssignees: z.boolean().prefault(true), name: z.string().trim().min(1), workspaceId: CLICKUP_ID_SCHEMA, }), ) .output(CLICKUP_SPACE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { workspaceId, ...body } = input return getClickUpApi(account).request(`team/${workspaceId}/space`, { body, method: "POST", responseSchema: CLICKUP_SPACE_SCHEMA, }) }) export const updateClickUpSpace = defineAction("Update ClickUp Space") .describe("Updates a ClickUp Space.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ adminCanManage: z.boolean().optional(), color: z.string(), features: SPACE_FEATURES_SCHEMA, multipleAssignees: z.boolean(), name: z.string().trim().min(1), private: z.boolean(), spaceId: CLICKUP_ID_SCHEMA, }), ) .output(CLICKUP_SPACE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => { const { spaceId, ...body } = input return getClickUpApi(account).request(`space/${spaceId}`, { body: compactClickUpInput(body), method: "PUT", responseSchema: CLICKUP_SPACE_SCHEMA, }) }) export const deleteClickUpSpace = defineAction("Delete ClickUp Space") .describe("Deletes a ClickUp Space.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input(z.object({ spaceId: CLICKUP_ID_SCHEMA })) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`space/${input.spaceId}`, { method: "DELETE", responseSchema: CLICKUP_VOID_RESPONSE_SCHEMA, }), ) export const listClickUpFolders = defineAction("List ClickUp Folders") .describe("Lists Folders in a ClickUp Space, including subfolders.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ archived: z.boolean().prefault(false), spaceId: CLICKUP_ID_SCHEMA, }), ) .output(FOLDERS_RESPONSE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`space/${input.spaceId}/folder`, { query: { archived: input.archived }, responseSchema: FOLDERS_RESPONSE_SCHEMA, }), ) export const getClickUpFolder = defineAction("Get ClickUp Folder") .describe("Gets a Folder and its Lists, optionally including subfolders.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ folderId: CLICKUP_ID_SCHEMA, includeSubfolders: z.boolean().prefault(false), }), ) .output(CLICKUP_FOLDER_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`folder/${input.folderId}`, { query: { includeSubfolders: input.includeSubfolders }, responseSchema: CLICKUP_FOLDER_SCHEMA, }), ) export const createClickUpFolder = defineAction("Create ClickUp Folder") .describe("Creates a Folder or subfolder in a ClickUp Space.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ name: z.string().trim().min(1), parentFolderId: CLICKUP_ID_SCHEMA.optional(), spaceId: CLICKUP_ID_SCHEMA, }), ) .output(CLICKUP_FOLDER_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`space/${input.spaceId}/folder`, { body: compactClickUpInput({ name: input.name, parentFolderId: input.parentFolderId, }), method: "POST", responseSchema: CLICKUP_FOLDER_SCHEMA, }), ) export const updateClickUpFolder = defineAction("Update ClickUp Folder") .describe("Renames a ClickUp Folder.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ folderId: CLICKUP_ID_SCHEMA, name: z.string().trim().min(1) }), ) .output(CLICKUP_FOLDER_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`folder/${input.folderId}`, { body: { name: input.name }, method: "PUT", responseSchema: CLICKUP_FOLDER_SCHEMA, }), ) export const deleteClickUpFolder = defineAction("Delete ClickUp Folder") .describe("Deletes a ClickUp Folder.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input(z.object({ folderId: CLICKUP_ID_SCHEMA })) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`folder/${input.folderId}`, { method: "DELETE", responseSchema: CLICKUP_VOID_RESPONSE_SCHEMA, }), ) export const listClickUpFolderLists = defineAction("List ClickUp Folder Lists") .describe("Lists Lists in a ClickUp Folder.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ archived: z.boolean().prefault(false), folderId: CLICKUP_ID_SCHEMA, }), ) .output(LISTS_RESPONSE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`folder/${input.folderId}/list`, { query: { archived: input.archived }, responseSchema: LISTS_RESPONSE_SCHEMA, }), ) export const listClickUpFolderlessLists = defineAction( "List ClickUp folderless Lists", ) .describe("Lists Lists directly inside a ClickUp Space.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z.object({ archived: z.boolean().prefault(false), spaceId: CLICKUP_ID_SCHEMA, }), ) .output(LISTS_RESPONSE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`space/${input.spaceId}/list`, { query: { archived: input.archived }, responseSchema: LISTS_RESPONSE_SCHEMA, }), ) export const createClickUpFolderList = defineAction( "Create ClickUp Folder List", ) .describe("Creates a List in a ClickUp Folder.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input(LIST_CREATE_SCHEMA.extend({ folderId: CLICKUP_ID_SCHEMA })) .output(LIST_RESPONSE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { folderId, ...body } = input return getClickUpApi(account).request(`folder/${folderId}/list`, { body: compactClickUpInput(body), method: "POST", responseSchema: LIST_RESPONSE_SCHEMA, }) }) export const createClickUpFolderlessList = defineAction( "Create ClickUp folderless List", ) .describe("Creates a List directly inside a ClickUp Space.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input(LIST_CREATE_SCHEMA.extend({ spaceId: CLICKUP_ID_SCHEMA })) .output(LIST_RESPONSE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { spaceId, ...body } = input return getClickUpApi(account).request(`space/${spaceId}/list`, { body: compactClickUpInput(body), method: "POST", responseSchema: LIST_RESPONSE_SCHEMA, }) }) export const getClickUpList = defineAction("Get ClickUp List") .describe("Gets a ClickUp List.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input(z.object({ listId: CLICKUP_ID_SCHEMA })) .output(LIST_RESPONSE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`list/${input.listId}`, { responseSchema: LIST_RESPONSE_SCHEMA, }), ) export const updateClickUpList = defineAction("Update ClickUp List") .describe("Updates a ClickUp List.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input( z .object(LIST_WRITE_FIELDS) .partial() .extend({ assignee: z .union([z.literal("none"), z.string().regex(/^\d+$/)]) .optional(), listId: CLICKUP_ID_SCHEMA, name: z.string().trim().min(1), unsetStatus: z.boolean().optional(), }), ) .output(LIST_RESPONSE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => { const { listId, ...body } = input return getClickUpApi(account).request(`list/${listId}`, { body: compactClickUpInput(body), method: "PUT", responseSchema: LIST_RESPONSE_SCHEMA, }) }) export const deleteClickUpList = defineAction("Delete ClickUp List") .describe("Deletes a ClickUp List.") .account(CLICKUP_ACCOUNT, CLICKUP_ACCOUNT_REQUIREMENT) .input(z.object({ listId: CLICKUP_ID_SCHEMA })) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getClickUpApi(account).request(`list/${input.listId}`, { method: "DELETE", responseSchema: CLICKUP_VOID_RESPONSE_SCHEMA, }), )