@zapier/trello-connector 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +93 -0
- package/NOTICE +8 -0
- package/README.md +135 -2
- package/SKILL.md +139 -0
- package/cli.js +71 -0
- package/cli.ts +5 -0
- package/connections.ts +26 -0
- package/dist/cli.js +4 -0
- package/dist/index.js +2654 -0
- package/index.ts +145 -0
- package/package.json +59 -4
- package/preflight.sh +157 -0
- package/references/trello-api-gotchas.md +81 -0
- package/scripts/.gitkeep +0 -0
- package/scripts/addCardAttachment.ts +107 -0
- package/scripts/addCardLabel.ts +93 -0
- package/scripts/addCardMember.ts +93 -0
- package/scripts/addChecklistItem.ts +98 -0
- package/scripts/addMemberToBoard.ts +57 -0
- package/scripts/archiveCard.ts +67 -0
- package/scripts/closeBoard.ts +62 -0
- package/scripts/completeChecklistItem.ts +56 -0
- package/scripts/copyBoard.ts +81 -0
- package/scripts/createBoard.ts +72 -0
- package/scripts/createCard.ts +266 -0
- package/scripts/createChecklist.ts +50 -0
- package/scripts/createComment.ts +71 -0
- package/scripts/createLabel.ts +72 -0
- package/scripts/createList.ts +100 -0
- package/scripts/deleteChecklist.ts +38 -0
- package/scripts/findBoard.ts +62 -0
- package/scripts/findChecklist.ts +51 -0
- package/scripts/findChecklistItem.ts +49 -0
- package/scripts/findLabel.ts +54 -0
- package/scripts/findList.ts +55 -0
- package/scripts/findOrganizationMember.ts +59 -0
- package/scripts/getAction.ts +58 -0
- package/scripts/getBoard.ts +52 -0
- package/scripts/getCard.ts +79 -0
- package/scripts/getChecklist.ts +45 -0
- package/scripts/getChecklistItem.ts +48 -0
- package/scripts/getCurrentMember.ts +52 -0
- package/scripts/getLabel.ts +46 -0
- package/scripts/getList.ts +47 -0
- package/scripts/getMember.ts +52 -0
- package/scripts/getOrganization.ts +46 -0
- package/scripts/listBoardMembers.ts +58 -0
- package/scripts/listBoards.ts +78 -0
- package/scripts/listCardAttachments.ts +55 -0
- package/scripts/listCards.ts +129 -0
- package/scripts/listCustomFields.ts +62 -0
- package/scripts/listLabels.ts +52 -0
- package/scripts/listLists.ts +61 -0
- package/scripts/listOrganizations.ts +50 -0
- package/scripts/moveCard.ts +68 -0
- package/scripts/removeCardLabel.ts +43 -0
- package/scripts/searchCards.ts +153 -0
- package/scripts/updateCard.ts +184 -0
- package/tsup.config.ts +63 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { connectionResolvers } from "../connections.ts";
|
|
6
|
+
|
|
7
|
+
const inputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
id: z.string().describe("24-char hex card id."),
|
|
10
|
+
value: z.string().describe("Member id to add."),
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
13
|
+
const outputSchema = z.object({
|
|
14
|
+
id: z
|
|
15
|
+
.string()
|
|
16
|
+
.regex(new RegExp("^[0-9a-fA-F]{24}$"))
|
|
17
|
+
.describe("Trello object id (24 hex chars)."),
|
|
18
|
+
name: z.string(),
|
|
19
|
+
desc: z.string().nullable().optional(),
|
|
20
|
+
closed: z.boolean().nullable().optional(),
|
|
21
|
+
idBoard: z.string(),
|
|
22
|
+
idList: z.string(),
|
|
23
|
+
idShort: z.number().int().nullable().optional(),
|
|
24
|
+
shortLink: z.string().nullable().optional(),
|
|
25
|
+
shortUrl: z.string().nullable().optional(),
|
|
26
|
+
url: z.string().nullable().optional(),
|
|
27
|
+
due: z.union([z.string().datetime({ offset: true }), z.null()]).optional(),
|
|
28
|
+
dueComplete: z.boolean().nullable().optional(),
|
|
29
|
+
dateLastActivity: z.string().datetime({ offset: true }).nullable().optional(),
|
|
30
|
+
idLabels: z.array(z.string()).nullable().optional(),
|
|
31
|
+
idMembers: z.array(z.string()).nullable().optional(),
|
|
32
|
+
labels: z
|
|
33
|
+
.array(
|
|
34
|
+
z.object({
|
|
35
|
+
id: z
|
|
36
|
+
.string()
|
|
37
|
+
.regex(new RegExp("^[0-9a-fA-F]{24}$"))
|
|
38
|
+
.describe("Trello object id (24 hex chars)."),
|
|
39
|
+
idBoard: z.string(),
|
|
40
|
+
name: z.string().nullable().optional(),
|
|
41
|
+
color: z.string().nullable().optional(),
|
|
42
|
+
}),
|
|
43
|
+
)
|
|
44
|
+
.nullable()
|
|
45
|
+
.optional(),
|
|
46
|
+
pos: z.number().nullable().optional(),
|
|
47
|
+
customFields: z
|
|
48
|
+
.record(z.string(), z.any())
|
|
49
|
+
.nullable()
|
|
50
|
+
.describe("Custom field values keyed by field name when requested.")
|
|
51
|
+
.optional(),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const definition = defineTool({
|
|
55
|
+
name: "addCardMember",
|
|
56
|
+
title: "Add Card Member",
|
|
57
|
+
description: "Add a member to a card.",
|
|
58
|
+
inputSchema,
|
|
59
|
+
outputSchema,
|
|
60
|
+
annotations: {
|
|
61
|
+
readOnlyHint: false,
|
|
62
|
+
destructiveHint: false,
|
|
63
|
+
idempotentHint: false,
|
|
64
|
+
openWorldHint: true,
|
|
65
|
+
},
|
|
66
|
+
connection: "trello",
|
|
67
|
+
run: async (input, ctx) => {
|
|
68
|
+
const url = `https://api.trello.com/1/cards/${encodeURIComponent(input.id)}/idMembers`;
|
|
69
|
+
const body: Record<string, unknown> = {};
|
|
70
|
+
if (input.value !== undefined) body["value"] = input.value;
|
|
71
|
+
const res = await ctx.fetch(url, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: { "Content-Type": "application/json" },
|
|
74
|
+
body: JSON.stringify(body),
|
|
75
|
+
});
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
const errBody = await res.text();
|
|
78
|
+
throw new Error(`Trello addCardMember ${res.status}: ${errBody}`);
|
|
79
|
+
}
|
|
80
|
+
const cardRes = await ctx.fetch(
|
|
81
|
+
`https://api.trello.com/1/cards/${encodeURIComponent(input.id)}`,
|
|
82
|
+
);
|
|
83
|
+
if (!cardRes.ok) {
|
|
84
|
+
const errBody = await cardRes.text();
|
|
85
|
+
throw new Error(`Trello addCardMember ${cardRes.status}: ${errBody}`);
|
|
86
|
+
}
|
|
87
|
+
return cardRes.json();
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export default definition;
|
|
92
|
+
|
|
93
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { connectionResolvers } from "../connections.ts";
|
|
6
|
+
|
|
7
|
+
const inputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
id: z.string(),
|
|
10
|
+
name: z.string(),
|
|
11
|
+
pos: z
|
|
12
|
+
.any()
|
|
13
|
+
.superRefine((x, ctx) => {
|
|
14
|
+
const schemas = [z.enum(["top", "bottom"]), z.number()];
|
|
15
|
+
const { errors, failed } = schemas.reduce<{
|
|
16
|
+
errors: z.core.$ZodIssue[];
|
|
17
|
+
failed: number;
|
|
18
|
+
}>(
|
|
19
|
+
({ errors, failed }, schema) =>
|
|
20
|
+
((result) =>
|
|
21
|
+
result.error
|
|
22
|
+
? {
|
|
23
|
+
errors: [...errors, ...result.error.issues],
|
|
24
|
+
failed: failed + 1,
|
|
25
|
+
}
|
|
26
|
+
: { errors, failed })(schema.safeParse(x)),
|
|
27
|
+
{ errors: [], failed: 0 },
|
|
28
|
+
);
|
|
29
|
+
const passed = schemas.length - failed;
|
|
30
|
+
if (passed !== 1) {
|
|
31
|
+
ctx.addIssue(
|
|
32
|
+
errors.length
|
|
33
|
+
? {
|
|
34
|
+
path: [],
|
|
35
|
+
code: "invalid_union",
|
|
36
|
+
errors: [errors],
|
|
37
|
+
message:
|
|
38
|
+
"Invalid input: Should pass single schema. Passed " +
|
|
39
|
+
passed,
|
|
40
|
+
}
|
|
41
|
+
: {
|
|
42
|
+
path: [],
|
|
43
|
+
code: "custom",
|
|
44
|
+
errors: [errors],
|
|
45
|
+
message:
|
|
46
|
+
"Invalid input: Should pass single schema. Passed " +
|
|
47
|
+
passed,
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
.optional(),
|
|
53
|
+
})
|
|
54
|
+
.strict();
|
|
55
|
+
const outputSchema = z.object({
|
|
56
|
+
id: z
|
|
57
|
+
.string()
|
|
58
|
+
.regex(new RegExp("^[0-9a-fA-F]{24}$"))
|
|
59
|
+
.describe("Trello object id (24 hex chars)."),
|
|
60
|
+
name: z.string(),
|
|
61
|
+
state: z.enum(["complete", "incomplete"]),
|
|
62
|
+
idChecklist: z.string().nullable().optional(),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const definition = defineTool({
|
|
66
|
+
name: "addChecklistItem",
|
|
67
|
+
title: "Add Checklist Item",
|
|
68
|
+
description: "Add an item to a checklist.",
|
|
69
|
+
inputSchema,
|
|
70
|
+
outputSchema,
|
|
71
|
+
annotations: {
|
|
72
|
+
readOnlyHint: false,
|
|
73
|
+
destructiveHint: false,
|
|
74
|
+
idempotentHint: false,
|
|
75
|
+
openWorldHint: true,
|
|
76
|
+
},
|
|
77
|
+
connection: "trello",
|
|
78
|
+
run: async (input, ctx) => {
|
|
79
|
+
const url = `https://api.trello.com/1/checklists/${encodeURIComponent(input.id)}/checkItems`;
|
|
80
|
+
const body: Record<string, unknown> = {};
|
|
81
|
+
if (input.name !== undefined) body["name"] = input.name;
|
|
82
|
+
if (input.pos !== undefined) body["pos"] = input.pos;
|
|
83
|
+
const res = await ctx.fetch(url, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: { "Content-Type": "application/json" },
|
|
86
|
+
body: JSON.stringify(body),
|
|
87
|
+
});
|
|
88
|
+
if (!res.ok) {
|
|
89
|
+
const errBody = await res.text();
|
|
90
|
+
throw new Error(`Trello addChecklistItem ${res.status}: ${errBody}`);
|
|
91
|
+
}
|
|
92
|
+
return res.json();
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export default definition;
|
|
97
|
+
|
|
98
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { connectionResolvers } from "../connections.ts";
|
|
6
|
+
|
|
7
|
+
const inputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
id: z.string().describe("24-char hex board id."),
|
|
10
|
+
email: z.string().describe("Member email to invite/add."),
|
|
11
|
+
type: z
|
|
12
|
+
.enum(["normal", "admin", "observer"])
|
|
13
|
+
.describe("Membership type.")
|
|
14
|
+
.optional(),
|
|
15
|
+
fullName: z
|
|
16
|
+
.string()
|
|
17
|
+
.describe("Display name when inviting by email.")
|
|
18
|
+
.optional(),
|
|
19
|
+
})
|
|
20
|
+
.strict();
|
|
21
|
+
const outputSchema = z.object({ status: z.number() });
|
|
22
|
+
|
|
23
|
+
const definition = defineTool({
|
|
24
|
+
name: "addMemberToBoard",
|
|
25
|
+
title: "Add Member To Board",
|
|
26
|
+
description: "Add a member to a board by member id or email.",
|
|
27
|
+
inputSchema,
|
|
28
|
+
outputSchema,
|
|
29
|
+
annotations: {
|
|
30
|
+
readOnlyHint: false,
|
|
31
|
+
destructiveHint: false,
|
|
32
|
+
idempotentHint: false,
|
|
33
|
+
openWorldHint: true,
|
|
34
|
+
},
|
|
35
|
+
connection: "trello",
|
|
36
|
+
run: async (input, ctx) => {
|
|
37
|
+
const url = `https://api.trello.com/1/boards/${encodeURIComponent(input.id)}/memberships`;
|
|
38
|
+
const body: Record<string, unknown> = {};
|
|
39
|
+
if (input.email !== undefined) body["email"] = input.email;
|
|
40
|
+
if (input.type !== undefined) body["type"] = input.type;
|
|
41
|
+
if (input.fullName !== undefined) body["fullName"] = input.fullName;
|
|
42
|
+
const res = await ctx.fetch(url, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers: { "Content-Type": "application/json" },
|
|
45
|
+
body: JSON.stringify(body),
|
|
46
|
+
});
|
|
47
|
+
if (!res.ok) {
|
|
48
|
+
const errBody = await res.text();
|
|
49
|
+
throw new Error(`Trello addMemberToBoard ${res.status}: ${errBody}`);
|
|
50
|
+
}
|
|
51
|
+
return { status: res.status };
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export default definition;
|
|
56
|
+
|
|
57
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Authored by the implementation agent: thin intent wrapper over PUT /cards/{id} (closed=true).
|
|
3
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
import { connectionResolvers } from "../connections.ts";
|
|
7
|
+
import {
|
|
8
|
+
TRELLO_BASE,
|
|
9
|
+
TRELLO_ID_REGEX,
|
|
10
|
+
trelloError,
|
|
11
|
+
trelloFormBody,
|
|
12
|
+
trelloFormHeaders,
|
|
13
|
+
} from "../lib/trello.ts";
|
|
14
|
+
|
|
15
|
+
const inputSchema = z
|
|
16
|
+
.object({
|
|
17
|
+
id: z.string().describe("24-char hex card id to archive."),
|
|
18
|
+
closed: z
|
|
19
|
+
.boolean()
|
|
20
|
+
.default(true)
|
|
21
|
+
.describe("Archive when true (default); set false to reopen."),
|
|
22
|
+
})
|
|
23
|
+
.strict();
|
|
24
|
+
|
|
25
|
+
const outputSchema = z.object({
|
|
26
|
+
id: z.string().regex(TRELLO_ID_REGEX),
|
|
27
|
+
name: z.string(),
|
|
28
|
+
closed: z.boolean(),
|
|
29
|
+
idBoard: z.string(),
|
|
30
|
+
idList: z.string(),
|
|
31
|
+
url: z.string(),
|
|
32
|
+
shortUrl: z.string().nullable().optional(),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const definition = defineTool({
|
|
36
|
+
name: "archiveCard",
|
|
37
|
+
title: "Archive Card",
|
|
38
|
+
description:
|
|
39
|
+
"Archive (close) a card by id. Prefer this over updateCard when the job is only archiving. Reopen with closed=false.",
|
|
40
|
+
inputSchema,
|
|
41
|
+
outputSchema,
|
|
42
|
+
annotations: {
|
|
43
|
+
readOnlyHint: false,
|
|
44
|
+
destructiveHint: true,
|
|
45
|
+
idempotentHint: true,
|
|
46
|
+
openWorldHint: true,
|
|
47
|
+
},
|
|
48
|
+
connection: "trello",
|
|
49
|
+
run: async (input, ctx) => {
|
|
50
|
+
const url = `${TRELLO_BASE}/cards/${encodeURIComponent(input.id)}`;
|
|
51
|
+
const res = await ctx.fetch(url, {
|
|
52
|
+
method: "PUT",
|
|
53
|
+
headers: trelloFormHeaders,
|
|
54
|
+
body: trelloFormBody({ closed: input.closed }),
|
|
55
|
+
});
|
|
56
|
+
if (!res.ok) await trelloError("archiveCard", res);
|
|
57
|
+
const card = (await res.json()) as z.infer<typeof outputSchema>;
|
|
58
|
+
if (input.closed && card.closed) {
|
|
59
|
+
return card;
|
|
60
|
+
}
|
|
61
|
+
return card;
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export default definition;
|
|
66
|
+
|
|
67
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { connectionResolvers } from "../connections.ts";
|
|
6
|
+
|
|
7
|
+
const inputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
id: z.string().describe("24-char hex board id."),
|
|
10
|
+
closed: z
|
|
11
|
+
.boolean()
|
|
12
|
+
.default(true)
|
|
13
|
+
.describe("Set true to archive the board."),
|
|
14
|
+
})
|
|
15
|
+
.strict();
|
|
16
|
+
const outputSchema = z.object({
|
|
17
|
+
id: z
|
|
18
|
+
.string()
|
|
19
|
+
.regex(new RegExp("^[0-9a-fA-F]{24}$"))
|
|
20
|
+
.describe("Trello object id (24 hex chars)."),
|
|
21
|
+
name: z.string(),
|
|
22
|
+
desc: z.string().nullable().optional(),
|
|
23
|
+
closed: z.boolean().nullable().optional(),
|
|
24
|
+
idOrganization: z.string().nullable().optional(),
|
|
25
|
+
url: z.string().nullable().optional(),
|
|
26
|
+
shortUrl: z.string().nullable().optional(),
|
|
27
|
+
dateLastActivity: z.string().datetime({ offset: true }).nullable().optional(),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const definition = defineTool({
|
|
31
|
+
name: "closeBoard",
|
|
32
|
+
title: "Close Board",
|
|
33
|
+
description: "Archive (close) a board by setting closed to true.",
|
|
34
|
+
inputSchema,
|
|
35
|
+
outputSchema,
|
|
36
|
+
annotations: {
|
|
37
|
+
readOnlyHint: false,
|
|
38
|
+
destructiveHint: false,
|
|
39
|
+
idempotentHint: true,
|
|
40
|
+
openWorldHint: true,
|
|
41
|
+
},
|
|
42
|
+
connection: "trello",
|
|
43
|
+
run: async (input, ctx) => {
|
|
44
|
+
const url = `https://api.trello.com/1/boards/${encodeURIComponent(input.id)}`;
|
|
45
|
+
const body: Record<string, unknown> = {};
|
|
46
|
+
if (input.closed !== undefined) body["closed"] = input.closed;
|
|
47
|
+
const res = await ctx.fetch(url, {
|
|
48
|
+
method: "PUT",
|
|
49
|
+
headers: { "Content-Type": "application/json" },
|
|
50
|
+
body: JSON.stringify(body),
|
|
51
|
+
});
|
|
52
|
+
if (!res.ok) {
|
|
53
|
+
const errBody = await res.text();
|
|
54
|
+
throw new Error(`Trello closeBoard ${res.status}: ${errBody}`);
|
|
55
|
+
}
|
|
56
|
+
return res.json();
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export default definition;
|
|
61
|
+
|
|
62
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { connectionResolvers } from "../connections.ts";
|
|
6
|
+
|
|
7
|
+
const inputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
id: z.string().describe("24-char hex card id."),
|
|
10
|
+
idCheckItem: z.string(),
|
|
11
|
+
state: z.enum(["complete", "incomplete"]),
|
|
12
|
+
})
|
|
13
|
+
.strict();
|
|
14
|
+
const outputSchema = z.object({
|
|
15
|
+
id: z
|
|
16
|
+
.string()
|
|
17
|
+
.regex(new RegExp("^[0-9a-fA-F]{24}$"))
|
|
18
|
+
.describe("Trello object id (24 hex chars)."),
|
|
19
|
+
name: z.string(),
|
|
20
|
+
state: z.enum(["complete", "incomplete"]),
|
|
21
|
+
idChecklist: z.string().nullable().optional(),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const definition = defineTool({
|
|
25
|
+
name: "completeChecklistItem",
|
|
26
|
+
title: "Complete Checklist Item",
|
|
27
|
+
description: "Mark a checklist item complete or incomplete.",
|
|
28
|
+
inputSchema,
|
|
29
|
+
outputSchema,
|
|
30
|
+
annotations: {
|
|
31
|
+
readOnlyHint: false,
|
|
32
|
+
destructiveHint: false,
|
|
33
|
+
idempotentHint: true,
|
|
34
|
+
openWorldHint: true,
|
|
35
|
+
},
|
|
36
|
+
connection: "trello",
|
|
37
|
+
run: async (input, ctx) => {
|
|
38
|
+
const url = `https://api.trello.com/1/cards/${encodeURIComponent(input.id)}/checkItem/${encodeURIComponent(input.idCheckItem)}`;
|
|
39
|
+
const body: Record<string, unknown> = {};
|
|
40
|
+
if (input.state !== undefined) body["state"] = input.state;
|
|
41
|
+
const res = await ctx.fetch(url, {
|
|
42
|
+
method: "PUT",
|
|
43
|
+
headers: { "Content-Type": "application/json" },
|
|
44
|
+
body: JSON.stringify(body),
|
|
45
|
+
});
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
const errBody = await res.text();
|
|
48
|
+
throw new Error(`Trello completeChecklistItem ${res.status}: ${errBody}`);
|
|
49
|
+
}
|
|
50
|
+
return res.json();
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export default definition;
|
|
55
|
+
|
|
56
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { connectionResolvers } from "../connections.ts";
|
|
6
|
+
import {
|
|
7
|
+
TRELLO_BASE,
|
|
8
|
+
trelloError,
|
|
9
|
+
trelloFormBody,
|
|
10
|
+
trelloFormHeaders,
|
|
11
|
+
} from "../lib/trello.ts";
|
|
12
|
+
|
|
13
|
+
const inputSchema = z
|
|
14
|
+
.object({
|
|
15
|
+
id: z.string().describe("24-char hex board id."),
|
|
16
|
+
name: z.string().describe("Name for the copy.").optional(),
|
|
17
|
+
idOrganization: z.string().describe("Destination workspace id.").optional(),
|
|
18
|
+
keepFromSource: z
|
|
19
|
+
.string()
|
|
20
|
+
.describe("Comma-separated props to keep, e.g. cards,labels.")
|
|
21
|
+
.optional(),
|
|
22
|
+
idBoardSource: z
|
|
23
|
+
.string()
|
|
24
|
+
.describe(
|
|
25
|
+
"Source board id (wire name idBoardSource; same as path id when omitted).",
|
|
26
|
+
)
|
|
27
|
+
.optional(),
|
|
28
|
+
})
|
|
29
|
+
.strict();
|
|
30
|
+
const outputSchema = z.object({
|
|
31
|
+
id: z
|
|
32
|
+
.string()
|
|
33
|
+
.regex(new RegExp("^[0-9a-fA-F]{24}$"))
|
|
34
|
+
.describe("Trello object id (24 hex chars)."),
|
|
35
|
+
name: z.string(),
|
|
36
|
+
desc: z.string().nullable().optional(),
|
|
37
|
+
closed: z.boolean().nullable().optional(),
|
|
38
|
+
idOrganization: z.string().nullable().optional(),
|
|
39
|
+
url: z.string().nullable().optional(),
|
|
40
|
+
shortUrl: z.string().nullable().optional(),
|
|
41
|
+
dateLastActivity: z.string().datetime({ offset: true }).nullable().optional(),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const definition = defineTool({
|
|
45
|
+
name: "copyBoard",
|
|
46
|
+
title: "Copy Board",
|
|
47
|
+
description:
|
|
48
|
+
"Copy an existing board, optionally keeping cards and changing the destination workspace.",
|
|
49
|
+
inputSchema,
|
|
50
|
+
outputSchema,
|
|
51
|
+
annotations: {
|
|
52
|
+
readOnlyHint: false,
|
|
53
|
+
destructiveHint: false,
|
|
54
|
+
idempotentHint: false,
|
|
55
|
+
openWorldHint: true,
|
|
56
|
+
},
|
|
57
|
+
connection: "trello",
|
|
58
|
+
run: async (input, ctx) => {
|
|
59
|
+
const fields: Record<string, string | number | boolean> = {
|
|
60
|
+
idBoardSource: input.idBoardSource ?? input.id,
|
|
61
|
+
};
|
|
62
|
+
if (input.name !== undefined) fields.name = input.name;
|
|
63
|
+
if (input.idOrganization !== undefined) {
|
|
64
|
+
fields.idOrganization = input.idOrganization;
|
|
65
|
+
}
|
|
66
|
+
if (input.keepFromSource !== undefined) {
|
|
67
|
+
fields.keepFromSource = input.keepFromSource;
|
|
68
|
+
}
|
|
69
|
+
const res = await ctx.fetch(`${TRELLO_BASE}/boards`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: trelloFormHeaders,
|
|
72
|
+
body: trelloFormBody(fields),
|
|
73
|
+
});
|
|
74
|
+
if (!res.ok) await trelloError("copyBoard", res);
|
|
75
|
+
return res.json();
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export default definition;
|
|
80
|
+
|
|
81
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineTool, handleIfScriptMain } from "@zapier/connectors-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { connectionResolvers } from "../connections.ts";
|
|
6
|
+
|
|
7
|
+
const inputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
name: z.string().describe("Board name."),
|
|
10
|
+
desc: z.string().describe("Board description.").optional(),
|
|
11
|
+
idOrganization: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe("Workspace (organization) id. Resolve via listOrganizations.")
|
|
14
|
+
.optional(),
|
|
15
|
+
defaultLists: z
|
|
16
|
+
.boolean()
|
|
17
|
+
.describe("Create default To Do / Doing / Done lists. Default true.")
|
|
18
|
+
.optional(),
|
|
19
|
+
})
|
|
20
|
+
.strict();
|
|
21
|
+
const outputSchema = z.object({
|
|
22
|
+
id: z
|
|
23
|
+
.string()
|
|
24
|
+
.regex(new RegExp("^[0-9a-fA-F]{24}$"))
|
|
25
|
+
.describe("Trello object id (24 hex chars)."),
|
|
26
|
+
name: z.string(),
|
|
27
|
+
desc: z.string().nullable().optional(),
|
|
28
|
+
closed: z.boolean().nullable().optional(),
|
|
29
|
+
idOrganization: z.string().nullable().optional(),
|
|
30
|
+
url: z.string().nullable().optional(),
|
|
31
|
+
shortUrl: z.string().nullable().optional(),
|
|
32
|
+
dateLastActivity: z.string().datetime({ offset: true }).nullable().optional(),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const definition = defineTool({
|
|
36
|
+
name: "createBoard",
|
|
37
|
+
title: "Create Board",
|
|
38
|
+
description: "Create a new Trello board in a workspace.",
|
|
39
|
+
inputSchema,
|
|
40
|
+
outputSchema,
|
|
41
|
+
annotations: {
|
|
42
|
+
readOnlyHint: false,
|
|
43
|
+
destructiveHint: false,
|
|
44
|
+
idempotentHint: false,
|
|
45
|
+
openWorldHint: true,
|
|
46
|
+
},
|
|
47
|
+
connection: "trello",
|
|
48
|
+
run: async (input, ctx) => {
|
|
49
|
+
const url = `https://api.trello.com/1/boards`;
|
|
50
|
+
const body: Record<string, unknown> = {};
|
|
51
|
+
if (input.name !== undefined) body["name"] = input.name;
|
|
52
|
+
if (input.desc !== undefined) body["desc"] = input.desc;
|
|
53
|
+
if (input.idOrganization !== undefined)
|
|
54
|
+
body["idOrganization"] = input.idOrganization;
|
|
55
|
+
if (input.defaultLists !== undefined)
|
|
56
|
+
body["defaultLists"] = input.defaultLists;
|
|
57
|
+
const res = await ctx.fetch(url, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: { "Content-Type": "application/json" },
|
|
60
|
+
body: JSON.stringify(body),
|
|
61
|
+
});
|
|
62
|
+
if (!res.ok) {
|
|
63
|
+
const errBody = await res.text();
|
|
64
|
+
throw new Error(`Trello createBoard ${res.status}: ${errBody}`);
|
|
65
|
+
}
|
|
66
|
+
return res.json();
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export default definition;
|
|
71
|
+
|
|
72
|
+
await handleIfScriptMain(import.meta, definition, { connectionResolvers });
|