@automate.ax/integration-contracts 0.55.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/dist/airtable/api.d.ts +19 -0
- package/dist/airtable/api.js +44 -0
- package/dist/airtable/index.d.ts +353 -0
- package/dist/airtable/index.js +32 -0
- package/dist/airtable/schemas.d.ts +716 -0
- package/dist/airtable/schemas.js +184 -0
- package/dist/asana/api.d.ts +70 -0
- package/dist/asana/api.js +119 -0
- package/dist/asana/index.d.ts +384 -0
- package/dist/asana/index.js +38 -0
- package/dist/asana/schemas.d.ts +1060 -0
- package/dist/asana/schemas.js +512 -0
- package/dist/brevo/api.d.ts +31 -0
- package/dist/brevo/api.js +64 -0
- package/dist/brevo/index.d.ts +822 -0
- package/dist/brevo/index.js +51 -0
- package/dist/brevo/schemas.d.ts +1217 -0
- package/dist/brevo/schemas.js +332 -0
- package/dist/github/index.d.ts +37 -0
- package/dist/github/index.js +106 -0
- package/dist/github/schemas.d.ts +8014 -0
- package/dist/github/schemas.js +113 -0
- package/dist/gmail/gmail.d.ts +172 -0
- package/dist/gmail/gmail.js +405 -0
- package/dist/gmail/index.d.ts +262 -0
- package/dist/gmail/index.js +23 -0
- package/dist/gmail/schemas.d.ts +444 -0
- package/dist/gmail/schemas.js +242 -0
- package/dist/google-calendar/event-schemas.d.ts +117 -0
- package/dist/google-calendar/event-schemas.js +13 -0
- package/dist/google-calendar/google-calendar.d.ts +147 -0
- package/dist/google-calendar/google-calendar.js +583 -0
- package/dist/google-calendar/index.d.ts +365 -0
- package/dist/google-calendar/index.js +24 -0
- package/dist/google-calendar/schemas.d.ts +592 -0
- package/dist/google-calendar/schemas.js +379 -0
- package/dist/google-forms/event-schemas.d.ts +105 -0
- package/dist/google-forms/event-schemas.js +20 -0
- package/dist/google-forms/google-forms.d.ts +243 -0
- package/dist/google-forms/google-forms.js +581 -0
- package/dist/google-forms/index.d.ts +141 -0
- package/dist/google-forms/index.js +20 -0
- package/dist/google-forms/schemas.d.ts +618 -0
- package/dist/google-forms/schemas.js +383 -0
- package/dist/linear/api.d.ts +63 -0
- package/dist/linear/api.js +88 -0
- package/dist/linear/index.d.ts +1338 -0
- package/dist/linear/index.js +55 -0
- package/dist/linear/schemas.d.ts +1795 -0
- package/dist/linear/schemas.js +760 -0
- package/dist/outlook/graph.d.ts +34 -0
- package/dist/outlook/graph.js +98 -0
- package/dist/outlook/index.d.ts +115 -0
- package/dist/outlook/index.js +11 -0
- package/dist/outlook/schemas.d.ts +529 -0
- package/dist/outlook/schemas.js +312 -0
- package/dist/resend/index.d.ts +707 -0
- package/dist/resend/index.js +54 -0
- package/dist/resend/schemas.d.ts +1033 -0
- package/dist/resend/schemas.js +377 -0
- package/dist/slack/index.d.ts +151 -0
- package/dist/slack/index.js +22 -0
- package/dist/slack/schemas.d.ts +641 -0
- package/dist/slack/schemas.js +581 -0
- package/dist/teams/graph.d.ts +33 -0
- package/dist/teams/graph.js +95 -0
- package/dist/teams/index.d.ts +164 -0
- package/dist/teams/index.js +21 -0
- package/dist/teams/schemas.d.ts +675 -0
- package/dist/teams/schemas.js +365 -0
- package/dist/trello/api.d.ts +69 -0
- package/dist/trello/api.js +140 -0
- package/dist/trello/event-schemas.d.ts +1101 -0
- package/dist/trello/event-schemas.js +233 -0
- package/dist/trello/index.d.ts +721 -0
- package/dist/trello/index.js +35 -0
- package/dist/trello/schemas.d.ts +283 -0
- package/dist/trello/schemas.js +401 -0
- package/dist/triggers.d.ts +26 -0
- package/dist/triggers.js +33 -0
- package/dist/vercel/index.d.ts +1065 -0
- package/dist/vercel/index.js +114 -0
- package/dist/vercel/schemas.d.ts +1518 -0
- package/dist/vercel/schemas.js +335 -0
- package/dist/whatsapp/api.d.ts +62 -0
- package/dist/whatsapp/api.js +121 -0
- package/dist/whatsapp/index.d.ts +614 -0
- package/dist/whatsapp/index.js +35 -0
- package/dist/whatsapp/schemas.d.ts +926 -0
- package/dist/whatsapp/schemas.js +326 -0
- package/package.json +169 -0
- package/src/airtable/api.ts +66 -0
- package/src/airtable/index.ts +41 -0
- package/src/airtable/schemas.ts +231 -0
- package/src/asana/api.ts +171 -0
- package/src/asana/index.ts +49 -0
- package/src/asana/schemas.ts +655 -0
- package/src/brevo/api.ts +89 -0
- package/src/brevo/index.ts +66 -0
- package/src/brevo/schemas.ts +449 -0
- package/src/github/index.ts +217 -0
- package/src/github/schemas.ts +435 -0
- package/src/gmail/gmail.ts +577 -0
- package/src/gmail/index.ts +26 -0
- package/src/gmail/schemas.ts +327 -0
- package/src/google-calendar/event-schemas.ts +16 -0
- package/src/google-calendar/google-calendar.ts +727 -0
- package/src/google-calendar/index.ts +27 -0
- package/src/google-calendar/schemas.ts +529 -0
- package/src/google-forms/event-schemas.ts +26 -0
- package/src/google-forms/google-forms.ts +683 -0
- package/src/google-forms/index.ts +23 -0
- package/src/google-forms/schemas.ts +499 -0
- package/src/linear/api.ts +141 -0
- package/src/linear/index.ts +71 -0
- package/src/linear/schemas.ts +1060 -0
- package/src/outlook/graph.ts +132 -0
- package/src/outlook/index.ts +14 -0
- package/src/outlook/schemas.ts +388 -0
- package/src/resend/index.ts +70 -0
- package/src/resend/schemas.ts +462 -0
- package/src/slack/index.ts +29 -0
- package/src/slack/schemas.ts +737 -0
- package/src/teams/graph.ts +130 -0
- package/src/teams/index.ts +27 -0
- package/src/teams/schemas.ts +463 -0
- package/src/trello/api.ts +190 -0
- package/src/trello/event-schemas.ts +290 -0
- package/src/trello/index.ts +45 -0
- package/src/trello/schemas.ts +507 -0
- package/src/triggers.ts +68 -0
- package/src/vercel/index.ts +147 -0
- package/src/vercel/schemas.ts +594 -0
- package/src/whatsapp/api.ts +171 -0
- package/src/whatsapp/index.ts +46 -0
- package/src/whatsapp/schemas.ts +341 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const ASANA_RESOURCE_SCHEMA = z.object({
|
|
3
|
+
/** Stable Asana globally unique identifier. */
|
|
4
|
+
id: z.string(),
|
|
5
|
+
/** Human-readable resource name, when available. */
|
|
6
|
+
name: z.string().optional(),
|
|
7
|
+
/** Provider resource type. */
|
|
8
|
+
type: z.string().optional(),
|
|
9
|
+
});
|
|
10
|
+
export const ASANA_PAGE_INFO_SCHEMA = z.object({
|
|
11
|
+
/** Opaque token for the next page, when more results are available. */
|
|
12
|
+
nextOffset: z.string().optional(),
|
|
13
|
+
});
|
|
14
|
+
export const ASANA_WORKSPACE_SCHEMA = ASANA_RESOURCE_SCHEMA.extend({
|
|
15
|
+
/** Domains associated with this workspace. */
|
|
16
|
+
emailDomains: z.string().array(),
|
|
17
|
+
/** Whether the workspace is an Asana organization. */
|
|
18
|
+
isOrganization: z.boolean(),
|
|
19
|
+
});
|
|
20
|
+
export const ASANA_USER_SCHEMA = ASANA_RESOURCE_SCHEMA.extend({
|
|
21
|
+
/** User email when the caller can access it. */
|
|
22
|
+
email: z.string().optional(),
|
|
23
|
+
/** URL of the user's profile photo. */
|
|
24
|
+
photoUrl: z.string().optional(),
|
|
25
|
+
/** Workspaces visible for the user. */
|
|
26
|
+
workspaces: ASANA_RESOURCE_SCHEMA.array(),
|
|
27
|
+
});
|
|
28
|
+
export const ASANA_PROJECT_SCHEMA = ASANA_RESOURCE_SCHEMA.extend({
|
|
29
|
+
/** Whether the project is archived. */
|
|
30
|
+
archived: z.boolean(),
|
|
31
|
+
/** Asana project color. */
|
|
32
|
+
color: z.string().optional(),
|
|
33
|
+
/** RFC 3339 creation timestamp. */
|
|
34
|
+
createdAt: z.string().optional(),
|
|
35
|
+
/** Default project layout. */
|
|
36
|
+
defaultView: z.string().optional(),
|
|
37
|
+
/** Project due date. */
|
|
38
|
+
dueOn: z.string().optional(),
|
|
39
|
+
/** Project description as HTML. */
|
|
40
|
+
htmlNotes: z.string().optional(),
|
|
41
|
+
/** RFC 3339 last-modified timestamp. */
|
|
42
|
+
modifiedAt: z.string().optional(),
|
|
43
|
+
/** Plain-text project description. */
|
|
44
|
+
notes: z.string().optional(),
|
|
45
|
+
/** Web URL for the project. */
|
|
46
|
+
permalinkUrl: z.string().optional(),
|
|
47
|
+
/** Whether the project is public to its organization or team. */
|
|
48
|
+
public: z.boolean(),
|
|
49
|
+
/** Project start date. */
|
|
50
|
+
startOn: z.string().optional(),
|
|
51
|
+
/** Team containing the project. */
|
|
52
|
+
team: ASANA_RESOURCE_SCHEMA.optional(),
|
|
53
|
+
/** Workspace containing the project. */
|
|
54
|
+
workspace: ASANA_RESOURCE_SCHEMA.optional(),
|
|
55
|
+
});
|
|
56
|
+
export const ASANA_SECTION_SCHEMA = ASANA_RESOURCE_SCHEMA.extend({
|
|
57
|
+
/** RFC 3339 creation timestamp. */
|
|
58
|
+
createdAt: z.string().optional(),
|
|
59
|
+
/** Project containing the section. */
|
|
60
|
+
project: ASANA_RESOURCE_SCHEMA.optional(),
|
|
61
|
+
});
|
|
62
|
+
export const ASANA_TASK_MEMBERSHIP_SCHEMA = z.object({
|
|
63
|
+
/** Project containing this task membership. */
|
|
64
|
+
project: ASANA_RESOURCE_SCHEMA,
|
|
65
|
+
/** Section containing the task in this project. */
|
|
66
|
+
section: ASANA_RESOURCE_SCHEMA.optional(),
|
|
67
|
+
});
|
|
68
|
+
export const ASANA_TASK_SCHEMA = ASANA_RESOURCE_SCHEMA.extend({
|
|
69
|
+
/** Current assignee. */
|
|
70
|
+
assignee: ASANA_RESOURCE_SCHEMA.optional(),
|
|
71
|
+
/** Task status within the assignee's My Tasks list. */
|
|
72
|
+
assigneeStatus: z.string().optional(),
|
|
73
|
+
/** Whether the task is complete. */
|
|
74
|
+
completed: z.boolean(),
|
|
75
|
+
/** RFC 3339 completion timestamp. */
|
|
76
|
+
completedAt: z.string().optional(),
|
|
77
|
+
/** User who completed the task. */
|
|
78
|
+
completedBy: ASANA_RESOURCE_SCHEMA.optional(),
|
|
79
|
+
/** RFC 3339 creation timestamp. */
|
|
80
|
+
createdAt: z.string().optional(),
|
|
81
|
+
/** User who created the task. */
|
|
82
|
+
createdBy: ASANA_RESOURCE_SCHEMA.optional(),
|
|
83
|
+
/** Provider-native custom field values. */
|
|
84
|
+
customFields: z.json().array(),
|
|
85
|
+
/** Task due timestamp, for tasks with a due time. */
|
|
86
|
+
dueAt: z.string().optional(),
|
|
87
|
+
/** Task due date. */
|
|
88
|
+
dueOn: z.string().optional(),
|
|
89
|
+
/** Followers subscribed to task changes. */
|
|
90
|
+
followers: ASANA_RESOURCE_SCHEMA.array(),
|
|
91
|
+
/** Task description as HTML. */
|
|
92
|
+
htmlNotes: z.string().optional(),
|
|
93
|
+
/** Project and section placements for the task. */
|
|
94
|
+
memberships: ASANA_TASK_MEMBERSHIP_SCHEMA.array(),
|
|
95
|
+
/** RFC 3339 last-modified timestamp. */
|
|
96
|
+
modifiedAt: z.string().optional(),
|
|
97
|
+
/** Plain-text task description. */
|
|
98
|
+
notes: z.string().optional(),
|
|
99
|
+
/** Parent task for a subtask. */
|
|
100
|
+
parent: ASANA_RESOURCE_SCHEMA.optional(),
|
|
101
|
+
/** Web URL for the task. */
|
|
102
|
+
permalinkUrl: z.string().optional(),
|
|
103
|
+
/** Task projects. */
|
|
104
|
+
projects: ASANA_RESOURCE_SCHEMA.array(),
|
|
105
|
+
/** Asana task subtype. */
|
|
106
|
+
subtype: z.string().optional(),
|
|
107
|
+
/** Task start timestamp, for tasks with a start time. */
|
|
108
|
+
startAt: z.string().optional(),
|
|
109
|
+
/** Task start date. */
|
|
110
|
+
startOn: z.string().optional(),
|
|
111
|
+
/** Tags attached to the task. */
|
|
112
|
+
tags: ASANA_RESOURCE_SCHEMA.array(),
|
|
113
|
+
/** Workspace containing the task. */
|
|
114
|
+
workspace: ASANA_RESOURCE_SCHEMA.optional(),
|
|
115
|
+
});
|
|
116
|
+
export const ASANA_STORY_SCHEMA = ASANA_RESOURCE_SCHEMA.extend({
|
|
117
|
+
/** RFC 3339 creation timestamp. */
|
|
118
|
+
createdAt: z.string().optional(),
|
|
119
|
+
/** User who created the story. */
|
|
120
|
+
createdBy: ASANA_RESOURCE_SCHEMA.optional(),
|
|
121
|
+
/** Rich-text comment content. */
|
|
122
|
+
htmlText: z.string().optional(),
|
|
123
|
+
/** Whether the comment was edited. */
|
|
124
|
+
isEdited: z.boolean(),
|
|
125
|
+
/** Whether the story is pinned. */
|
|
126
|
+
isPinned: z.boolean(),
|
|
127
|
+
/** Story subtype, such as `comment_added`. */
|
|
128
|
+
subtype: z.string().optional(),
|
|
129
|
+
/** Plain-text story or comment content. */
|
|
130
|
+
text: z.string(),
|
|
131
|
+
});
|
|
132
|
+
export const ASANA_EVENT_ACTION_SCHEMA = z.enum([
|
|
133
|
+
"added",
|
|
134
|
+
"changed",
|
|
135
|
+
"deleted",
|
|
136
|
+
"removed",
|
|
137
|
+
"undeleted",
|
|
138
|
+
]);
|
|
139
|
+
export const ASANA_EVENT_CHANGE_SCHEMA = z.object({
|
|
140
|
+
/** Provider change category for the affected field. */
|
|
141
|
+
action: z.enum(["added", "changed", "removed"]),
|
|
142
|
+
/** Added field value, when the provider includes one. */
|
|
143
|
+
addedValue: z.json().optional(),
|
|
144
|
+
/** Name of the changed resource field. */
|
|
145
|
+
field: z.string(),
|
|
146
|
+
/** New field value, when the provider includes one. */
|
|
147
|
+
newValue: z.json().optional(),
|
|
148
|
+
/** Removed field value, when the provider includes one. */
|
|
149
|
+
removedValue: z.json().optional(),
|
|
150
|
+
});
|
|
151
|
+
export const ASANA_EVENT_SCHEMA = z.object({
|
|
152
|
+
/** Provider change category. */
|
|
153
|
+
action: ASANA_EVENT_ACTION_SCHEMA,
|
|
154
|
+
/** Field-level change details, when available. */
|
|
155
|
+
change: ASANA_EVENT_CHANGE_SCHEMA.optional(),
|
|
156
|
+
/** RFC 3339 timestamp when Asana recorded the event. */
|
|
157
|
+
createdAt: z.string(),
|
|
158
|
+
/** Parent resource through which the event propagated. */
|
|
159
|
+
parent: ASANA_RESOURCE_SCHEMA.optional(),
|
|
160
|
+
/** Resource that directly caused the event. */
|
|
161
|
+
resource: ASANA_RESOURCE_SCHEMA,
|
|
162
|
+
/** Provider subtype of the changed resource, when available. */
|
|
163
|
+
resourceSubtype: z.string().optional(),
|
|
164
|
+
/** Provider resource category that caused the event. */
|
|
165
|
+
resourceType: z.string(),
|
|
166
|
+
/** User responsible for the change, when available. */
|
|
167
|
+
user: ASANA_RESOURCE_SCHEMA.optional(),
|
|
168
|
+
/** Resource selected when the webhook subscription was created. */
|
|
169
|
+
watchedResourceId: z.string(),
|
|
170
|
+
});
|
|
171
|
+
const ASANA_TASK_ADDED_WEBHOOK_EVENT_SCHEMA = ASANA_EVENT_SCHEMA.extend({
|
|
172
|
+
action: z.literal("added"),
|
|
173
|
+
resourceType: z.literal("task"),
|
|
174
|
+
});
|
|
175
|
+
const ASANA_TASK_CHANGED_WEBHOOK_EVENT_SCHEMA = ASANA_EVENT_SCHEMA.extend({
|
|
176
|
+
action: z.literal("changed"),
|
|
177
|
+
resourceType: z.literal("task"),
|
|
178
|
+
});
|
|
179
|
+
const ASANA_TASK_REMOVED_WEBHOOK_EVENT_SCHEMA = ASANA_EVENT_SCHEMA.extend({
|
|
180
|
+
action: z.literal("removed"),
|
|
181
|
+
resourceType: z.literal("task"),
|
|
182
|
+
});
|
|
183
|
+
const ASANA_TASK_DELETED_WEBHOOK_EVENT_SCHEMA = ASANA_EVENT_SCHEMA.extend({
|
|
184
|
+
action: z.literal("deleted"),
|
|
185
|
+
resourceType: z.literal("task"),
|
|
186
|
+
});
|
|
187
|
+
const ASANA_TASK_COMPLETED_WEBHOOK_EVENT_SCHEMA = ASANA_TASK_CHANGED_WEBHOOK_EVENT_SCHEMA.extend({
|
|
188
|
+
change: ASANA_EVENT_CHANGE_SCHEMA.extend({
|
|
189
|
+
action: z.literal("changed"),
|
|
190
|
+
field: z.literal("completed"),
|
|
191
|
+
newValue: z.literal(true).optional(),
|
|
192
|
+
}),
|
|
193
|
+
});
|
|
194
|
+
const ASANA_COMMENT_ADDED_WEBHOOK_EVENT_SCHEMA = ASANA_EVENT_SCHEMA.extend({
|
|
195
|
+
action: z.literal("added"),
|
|
196
|
+
resourceType: z.literal("story"),
|
|
197
|
+
});
|
|
198
|
+
const ASANA_TASK_EVENT_RESOURCE_SCHEMA = ASANA_RESOURCE_SCHEMA.extend({
|
|
199
|
+
/** Provider resource type narrowed by the semantic trigger. */
|
|
200
|
+
type: z.literal("task"),
|
|
201
|
+
});
|
|
202
|
+
export const ASANA_TASK_ADDED_EVENT_SCHEMA = ASANA_TASK_EVENT_RESOURCE_SCHEMA.extend({
|
|
203
|
+
/** Complete normalized compact webhook event. */
|
|
204
|
+
event: ASANA_TASK_ADDED_WEBHOOK_EVENT_SCHEMA,
|
|
205
|
+
});
|
|
206
|
+
export const ASANA_TASK_CHANGED_EVENT_SCHEMA = ASANA_TASK_EVENT_RESOURCE_SCHEMA.extend({
|
|
207
|
+
/** Complete normalized compact webhook event. */
|
|
208
|
+
event: ASANA_TASK_CHANGED_WEBHOOK_EVENT_SCHEMA,
|
|
209
|
+
});
|
|
210
|
+
export const ASANA_TASK_REMOVED_EVENT_SCHEMA = ASANA_TASK_EVENT_RESOURCE_SCHEMA.extend({
|
|
211
|
+
/** Complete normalized compact webhook event. */
|
|
212
|
+
event: ASANA_TASK_REMOVED_WEBHOOK_EVENT_SCHEMA,
|
|
213
|
+
});
|
|
214
|
+
export const ASANA_TASK_DELETED_EVENT_SCHEMA = ASANA_TASK_EVENT_RESOURCE_SCHEMA.extend({
|
|
215
|
+
/** Complete normalized compact webhook event. */
|
|
216
|
+
event: ASANA_TASK_DELETED_WEBHOOK_EVENT_SCHEMA,
|
|
217
|
+
});
|
|
218
|
+
export const ASANA_TASK_COMPLETED_EVENT_SCHEMA = ASANA_TASK_SCHEMA.extend({
|
|
219
|
+
/** Completion is revalidated against the current task. */
|
|
220
|
+
completed: z.literal(true),
|
|
221
|
+
/** Complete normalized compact webhook event. */
|
|
222
|
+
event: ASANA_TASK_COMPLETED_WEBHOOK_EVENT_SCHEMA,
|
|
223
|
+
/** Provider resource type narrowed by the semantic trigger. */
|
|
224
|
+
type: z.literal("task"),
|
|
225
|
+
});
|
|
226
|
+
export const ASANA_COMMENT_ADDED_EVENT_SCHEMA = ASANA_STORY_SCHEMA.extend({
|
|
227
|
+
/** Complete normalized compact webhook event. */
|
|
228
|
+
event: ASANA_COMMENT_ADDED_WEBHOOK_EVENT_SCHEMA,
|
|
229
|
+
/** Comment subtype narrowed by the semantic trigger. */
|
|
230
|
+
subtype: z.literal("comment_added"),
|
|
231
|
+
/** Provider resource type narrowed by the semantic trigger. */
|
|
232
|
+
type: z.literal("story"),
|
|
233
|
+
});
|
|
234
|
+
export const ASANA_PROVIDER_RESOURCE_SCHEMA = z.looseObject({
|
|
235
|
+
gid: z.string(),
|
|
236
|
+
name: z.string().optional(),
|
|
237
|
+
resource_subtype: z.string().optional(),
|
|
238
|
+
resource_type: z.string().optional(),
|
|
239
|
+
});
|
|
240
|
+
export const ASANA_PROVIDER_PAGE_SCHEMA = z.looseObject({
|
|
241
|
+
next_page: z
|
|
242
|
+
.looseObject({
|
|
243
|
+
offset: z.string(),
|
|
244
|
+
})
|
|
245
|
+
.nullable()
|
|
246
|
+
.optional(),
|
|
247
|
+
});
|
|
248
|
+
const ASANA_PROVIDER_MEMBERSHIP_SCHEMA = z.looseObject({
|
|
249
|
+
project: ASANA_PROVIDER_RESOURCE_SCHEMA,
|
|
250
|
+
section: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
251
|
+
});
|
|
252
|
+
export const ASANA_PROVIDER_WORKSPACE_SCHEMA = ASANA_PROVIDER_RESOURCE_SCHEMA.extend({
|
|
253
|
+
email_domains: z.string().array().prefault([]),
|
|
254
|
+
is_organization: z.boolean().prefault(false),
|
|
255
|
+
});
|
|
256
|
+
export const ASANA_PROVIDER_USER_SCHEMA = ASANA_PROVIDER_RESOURCE_SCHEMA.extend({
|
|
257
|
+
email: z.string().optional(),
|
|
258
|
+
photo: z
|
|
259
|
+
.looseObject({
|
|
260
|
+
image_128x128: z.string().optional(),
|
|
261
|
+
})
|
|
262
|
+
.nullish(),
|
|
263
|
+
workspaces: ASANA_PROVIDER_RESOURCE_SCHEMA.array().prefault([]),
|
|
264
|
+
});
|
|
265
|
+
export const ASANA_PROVIDER_PROJECT_SCHEMA = ASANA_PROVIDER_RESOURCE_SCHEMA.extend({
|
|
266
|
+
archived: z.boolean().prefault(false),
|
|
267
|
+
color: z.string().nullish(),
|
|
268
|
+
created_at: z.string().optional(),
|
|
269
|
+
default_view: z.string().optional(),
|
|
270
|
+
due_on: z.string().nullish(),
|
|
271
|
+
html_notes: z.string().optional(),
|
|
272
|
+
modified_at: z.string().optional(),
|
|
273
|
+
notes: z.string().optional(),
|
|
274
|
+
permalink_url: z.string().optional(),
|
|
275
|
+
public: z.boolean().prefault(false),
|
|
276
|
+
start_on: z.string().nullish(),
|
|
277
|
+
team: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
278
|
+
workspace: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
279
|
+
});
|
|
280
|
+
export const ASANA_PROVIDER_SECTION_SCHEMA = ASANA_PROVIDER_RESOURCE_SCHEMA.extend({
|
|
281
|
+
created_at: z.string().optional(),
|
|
282
|
+
project: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
283
|
+
});
|
|
284
|
+
export const ASANA_PROVIDER_TASK_SCHEMA = ASANA_PROVIDER_RESOURCE_SCHEMA.extend({
|
|
285
|
+
assignee: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
286
|
+
assignee_status: z.string().optional(),
|
|
287
|
+
completed: z.boolean().prefault(false),
|
|
288
|
+
completed_at: z.string().nullish(),
|
|
289
|
+
completed_by: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
290
|
+
created_at: z.string().optional(),
|
|
291
|
+
created_by: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
292
|
+
custom_fields: z.json().array().prefault([]),
|
|
293
|
+
due_at: z.string().nullish(),
|
|
294
|
+
due_on: z.string().nullish(),
|
|
295
|
+
followers: ASANA_PROVIDER_RESOURCE_SCHEMA.array().prefault([]),
|
|
296
|
+
html_notes: z.string().optional(),
|
|
297
|
+
memberships: ASANA_PROVIDER_MEMBERSHIP_SCHEMA.array().prefault([]),
|
|
298
|
+
modified_at: z.string().optional(),
|
|
299
|
+
notes: z.string().optional(),
|
|
300
|
+
parent: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
301
|
+
permalink_url: z.string().optional(),
|
|
302
|
+
projects: ASANA_PROVIDER_RESOURCE_SCHEMA.array().prefault([]),
|
|
303
|
+
resource_subtype: z.string().optional(),
|
|
304
|
+
start_at: z.string().nullish(),
|
|
305
|
+
start_on: z.string().nullish(),
|
|
306
|
+
tags: ASANA_PROVIDER_RESOURCE_SCHEMA.array().prefault([]),
|
|
307
|
+
workspace: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
308
|
+
});
|
|
309
|
+
export const ASANA_PROVIDER_STORY_SCHEMA = ASANA_PROVIDER_RESOURCE_SCHEMA.extend({
|
|
310
|
+
created_at: z.string().optional(),
|
|
311
|
+
created_by: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
312
|
+
html_text: z.string().optional(),
|
|
313
|
+
is_edited: z.boolean().prefault(false),
|
|
314
|
+
is_pinned: z.boolean().prefault(false),
|
|
315
|
+
resource_subtype: z.string().optional(),
|
|
316
|
+
text: z.string().prefault(""),
|
|
317
|
+
});
|
|
318
|
+
const ASANA_PROVIDER_EVENT_CHANGE_SCHEMA = z.looseObject({
|
|
319
|
+
action: z.enum(["added", "changed", "removed"]),
|
|
320
|
+
added_value: z.json().optional(),
|
|
321
|
+
field: z.string(),
|
|
322
|
+
new_value: z.json().optional(),
|
|
323
|
+
removed_value: z.json().optional(),
|
|
324
|
+
});
|
|
325
|
+
export const ASANA_PROVIDER_EVENT_SCHEMA = z.looseObject({
|
|
326
|
+
action: ASANA_EVENT_ACTION_SCHEMA,
|
|
327
|
+
change: ASANA_PROVIDER_EVENT_CHANGE_SCHEMA.nullish(),
|
|
328
|
+
created_at: z.string(),
|
|
329
|
+
parent: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
330
|
+
resource: ASANA_PROVIDER_RESOURCE_SCHEMA,
|
|
331
|
+
type: z.string(),
|
|
332
|
+
user: ASANA_PROVIDER_RESOURCE_SCHEMA.nullish(),
|
|
333
|
+
});
|
|
334
|
+
/**
|
|
335
|
+
* Converts an Asana compact resource to the public camel-cased shape.
|
|
336
|
+
*
|
|
337
|
+
* @param value - Provider-native compact resource.
|
|
338
|
+
*/
|
|
339
|
+
export function toAsanaResource(value) {
|
|
340
|
+
return {
|
|
341
|
+
id: value.gid,
|
|
342
|
+
name: value.name,
|
|
343
|
+
type: value.resource_type,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Converts Asana offset pagination metadata.
|
|
348
|
+
*
|
|
349
|
+
* @param value - Provider-native response page.
|
|
350
|
+
*/
|
|
351
|
+
export function toAsanaPageInfo(value) {
|
|
352
|
+
return { nextOffset: value.next_page?.offset };
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Converts an Asana workspace to the public camel-cased shape.
|
|
356
|
+
*
|
|
357
|
+
* @param value - Provider-native workspace.
|
|
358
|
+
*/
|
|
359
|
+
export function toAsanaWorkspace(value) {
|
|
360
|
+
return {
|
|
361
|
+
...toAsanaResource(value),
|
|
362
|
+
emailDomains: value.email_domains,
|
|
363
|
+
isOrganization: value.is_organization,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Converts an Asana user to the public camel-cased shape.
|
|
368
|
+
*
|
|
369
|
+
* @param value - Provider-native user.
|
|
370
|
+
*/
|
|
371
|
+
export function toAsanaUser(value) {
|
|
372
|
+
return {
|
|
373
|
+
...toAsanaResource(value),
|
|
374
|
+
email: value.email,
|
|
375
|
+
photoUrl: value.photo?.image_128x128,
|
|
376
|
+
workspaces: value.workspaces.map(toAsanaResource),
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Converts an Asana project to the public camel-cased shape.
|
|
381
|
+
*
|
|
382
|
+
* @param value - Provider-native project.
|
|
383
|
+
*/
|
|
384
|
+
export function toAsanaProject(value) {
|
|
385
|
+
return {
|
|
386
|
+
...toAsanaResource(value),
|
|
387
|
+
archived: value.archived,
|
|
388
|
+
color: value.color ?? undefined,
|
|
389
|
+
createdAt: value.created_at,
|
|
390
|
+
defaultView: value.default_view,
|
|
391
|
+
dueOn: value.due_on ?? undefined,
|
|
392
|
+
htmlNotes: value.html_notes,
|
|
393
|
+
modifiedAt: value.modified_at,
|
|
394
|
+
notes: value.notes,
|
|
395
|
+
permalinkUrl: value.permalink_url,
|
|
396
|
+
public: value.public,
|
|
397
|
+
startOn: value.start_on ?? undefined,
|
|
398
|
+
team: value.team ? toAsanaResource(value.team) : undefined,
|
|
399
|
+
workspace: value.workspace ? toAsanaResource(value.workspace) : undefined,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Converts an Asana section to the public camel-cased shape.
|
|
404
|
+
*
|
|
405
|
+
* @param value - Provider-native section.
|
|
406
|
+
*/
|
|
407
|
+
export function toAsanaSection(value) {
|
|
408
|
+
return {
|
|
409
|
+
...toAsanaResource(value),
|
|
410
|
+
createdAt: value.created_at,
|
|
411
|
+
project: value.project ? toAsanaResource(value.project) : undefined,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Converts an Asana task to the public camel-cased shape.
|
|
416
|
+
*
|
|
417
|
+
* @param value - Provider-native task.
|
|
418
|
+
*/
|
|
419
|
+
export function toAsanaTask(value) {
|
|
420
|
+
return {
|
|
421
|
+
...toAsanaResource(value),
|
|
422
|
+
assignee: value.assignee ? toAsanaResource(value.assignee) : undefined,
|
|
423
|
+
assigneeStatus: value.assignee_status,
|
|
424
|
+
completed: value.completed,
|
|
425
|
+
completedAt: value.completed_at ?? undefined,
|
|
426
|
+
completedBy: value.completed_by
|
|
427
|
+
? toAsanaResource(value.completed_by)
|
|
428
|
+
: undefined,
|
|
429
|
+
createdAt: value.created_at,
|
|
430
|
+
createdBy: value.created_by ? toAsanaResource(value.created_by) : undefined,
|
|
431
|
+
customFields: value.custom_fields,
|
|
432
|
+
dueAt: value.due_at ?? undefined,
|
|
433
|
+
dueOn: value.due_on ?? undefined,
|
|
434
|
+
followers: value.followers.map(toAsanaResource),
|
|
435
|
+
htmlNotes: value.html_notes,
|
|
436
|
+
memberships: value.memberships.map(({ project, section }) => ({
|
|
437
|
+
project: toAsanaResource(project),
|
|
438
|
+
section: section ? toAsanaResource(section) : undefined,
|
|
439
|
+
})),
|
|
440
|
+
modifiedAt: value.modified_at,
|
|
441
|
+
notes: value.notes,
|
|
442
|
+
parent: value.parent ? toAsanaResource(value.parent) : undefined,
|
|
443
|
+
permalinkUrl: value.permalink_url,
|
|
444
|
+
projects: value.projects.map(toAsanaResource),
|
|
445
|
+
startAt: value.start_at ?? undefined,
|
|
446
|
+
startOn: value.start_on ?? undefined,
|
|
447
|
+
subtype: value.resource_subtype,
|
|
448
|
+
tags: value.tags.map(toAsanaResource),
|
|
449
|
+
workspace: value.workspace ? toAsanaResource(value.workspace) : undefined,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Converts an Asana story to the public camel-cased shape.
|
|
454
|
+
*
|
|
455
|
+
* @param value - Provider-native story.
|
|
456
|
+
*/
|
|
457
|
+
export function toAsanaStory(value) {
|
|
458
|
+
return {
|
|
459
|
+
...toAsanaResource(value),
|
|
460
|
+
createdAt: value.created_at,
|
|
461
|
+
createdBy: value.created_by ? toAsanaResource(value.created_by) : undefined,
|
|
462
|
+
htmlText: value.html_text,
|
|
463
|
+
isEdited: value.is_edited,
|
|
464
|
+
isPinned: value.is_pinned,
|
|
465
|
+
subtype: value.resource_subtype,
|
|
466
|
+
text: value.text,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Converts one compact webhook event to the public Asana event shape.
|
|
471
|
+
*
|
|
472
|
+
* @param value - Provider-native webhook event.
|
|
473
|
+
* @param watchedResourceId - Resource selected for the webhook subscription.
|
|
474
|
+
*/
|
|
475
|
+
export function normalizeAsanaEvent(value, watchedResourceId) {
|
|
476
|
+
const event = ASANA_PROVIDER_EVENT_SCHEMA.parse(value);
|
|
477
|
+
return ASANA_EVENT_SCHEMA.parse({
|
|
478
|
+
action: event.action,
|
|
479
|
+
change: event.change
|
|
480
|
+
? {
|
|
481
|
+
action: event.change.action,
|
|
482
|
+
addedValue: event.change.added_value,
|
|
483
|
+
field: event.change.field,
|
|
484
|
+
newValue: event.change.new_value,
|
|
485
|
+
removedValue: event.change.removed_value,
|
|
486
|
+
}
|
|
487
|
+
: undefined,
|
|
488
|
+
createdAt: event.created_at,
|
|
489
|
+
parent: event.parent ? toAsanaResource(event.parent) : undefined,
|
|
490
|
+
resource: toAsanaResource(event.resource),
|
|
491
|
+
resourceSubtype: event.resource.resource_subtype,
|
|
492
|
+
resourceType: event.resource.resource_type ?? event.type,
|
|
493
|
+
user: event.user ? toAsanaResource(event.user) : undefined,
|
|
494
|
+
watchedResourceId,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Converts one provider-native story to the public Asana story shape.
|
|
499
|
+
*
|
|
500
|
+
* @param value - Untrusted provider story payload.
|
|
501
|
+
*/
|
|
502
|
+
export function normalizeAsanaStory(value) {
|
|
503
|
+
return ASANA_STORY_SCHEMA.parse(toAsanaStory(ASANA_PROVIDER_STORY_SCHEMA.parse(value)));
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Converts one provider-native task to the public Asana task shape.
|
|
507
|
+
*
|
|
508
|
+
* @param value - Untrusted provider task payload.
|
|
509
|
+
*/
|
|
510
|
+
export function normalizeAsanaTask(value) {
|
|
511
|
+
return ASANA_TASK_SCHEMA.parse(toAsanaTask(ASANA_PROVIDER_TASK_SCHEMA.parse(value)));
|
|
512
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Options accepted by the authenticated Brevo request helper. */
|
|
3
|
+
export interface BrevoRequestOptions extends RequestInit {
|
|
4
|
+
/** Query parameters appended to the request URL. */
|
|
5
|
+
query?: Record<string, boolean | number | readonly (number | string)[] | string | undefined>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Creates a small authenticated Brevo REST client.
|
|
9
|
+
*
|
|
10
|
+
* The returned helper is an escape hatch for provider endpoints that do not yet
|
|
11
|
+
* have a dedicated action. It returns the native `Response` after checking for
|
|
12
|
+
* provider errors.
|
|
13
|
+
*
|
|
14
|
+
* @param secret - Resolved Brevo integration secret.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getBrevoApi(secret: Record<string, unknown>): {
|
|
17
|
+
/**
|
|
18
|
+
* Sends an authenticated request to the Brevo v3 API.
|
|
19
|
+
*
|
|
20
|
+
* @param path - Relative API path.
|
|
21
|
+
* @param options - Native fetch options and optional query parameters.
|
|
22
|
+
*/
|
|
23
|
+
request(path: string, options?: BrevoRequestOptions): Promise<Response>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Parses one successful Brevo JSON response.
|
|
27
|
+
*
|
|
28
|
+
* @param response - Checked provider response.
|
|
29
|
+
* @param schema - Schema describing the provider response.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseBrevoResponse<T extends z.ZodType>(response: Response, schema: T): Promise<z.output<T>>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const BREVO_API_BASE_URL = "https://api.brevo.com/v3/";
|
|
3
|
+
const BREVO_API_ORIGIN = new URL(BREVO_API_BASE_URL).origin;
|
|
4
|
+
const BREVO_SECRET_SCHEMA = z.object({
|
|
5
|
+
apiKey: z.string().min(1),
|
|
6
|
+
});
|
|
7
|
+
const BREVO_ERROR_SCHEMA = z.looseObject({
|
|
8
|
+
code: z.string().optional(),
|
|
9
|
+
message: z.string().optional(),
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* Creates a small authenticated Brevo REST client.
|
|
13
|
+
*
|
|
14
|
+
* The returned helper is an escape hatch for provider endpoints that do not yet
|
|
15
|
+
* have a dedicated action. It returns the native `Response` after checking for
|
|
16
|
+
* provider errors.
|
|
17
|
+
*
|
|
18
|
+
* @param secret - Resolved Brevo integration secret.
|
|
19
|
+
*/
|
|
20
|
+
export function getBrevoApi(secret) {
|
|
21
|
+
const { apiKey } = BREVO_SECRET_SCHEMA.parse(secret);
|
|
22
|
+
return {
|
|
23
|
+
/**
|
|
24
|
+
* Sends an authenticated request to the Brevo v3 API.
|
|
25
|
+
*
|
|
26
|
+
* @param path - Relative API path.
|
|
27
|
+
* @param options - Native fetch options and optional query parameters.
|
|
28
|
+
*/
|
|
29
|
+
async request(path, options = {}) {
|
|
30
|
+
const { query, ...requestInit } = options;
|
|
31
|
+
const url = new URL(path.replace(/^\//, ""), BREVO_API_BASE_URL);
|
|
32
|
+
if (url.origin !== BREVO_API_ORIGIN) {
|
|
33
|
+
throw new Error("Brevo API paths must use the Brevo API origin.");
|
|
34
|
+
}
|
|
35
|
+
for (const [name, value] of Object.entries(query ?? {})) {
|
|
36
|
+
if (value !== undefined) {
|
|
37
|
+
url.searchParams.set(name, Array.isArray(value) ? value.join(",") : String(value));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const headers = new Headers(requestInit.headers);
|
|
41
|
+
headers.set("api-key", apiKey);
|
|
42
|
+
headers.set("Accept", "application/json");
|
|
43
|
+
if (requestInit.body !== undefined && !headers.has("Content-Type")) {
|
|
44
|
+
headers.set("Content-Type", "application/json");
|
|
45
|
+
}
|
|
46
|
+
const response = await fetch(url, { ...requestInit, headers });
|
|
47
|
+
if (response.ok)
|
|
48
|
+
return response;
|
|
49
|
+
const error = BREVO_ERROR_SCHEMA.safeParse(await response.json().catch(() => ({})));
|
|
50
|
+
throw new Error(error.success && error.data.message
|
|
51
|
+
? `Brevo API error (${response.status}): ${error.data.message}`
|
|
52
|
+
: `Brevo API request failed with status ${response.status}.`);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parses one successful Brevo JSON response.
|
|
58
|
+
*
|
|
59
|
+
* @param response - Checked provider response.
|
|
60
|
+
* @param schema - Schema describing the provider response.
|
|
61
|
+
*/
|
|
62
|
+
export async function parseBrevoResponse(response, schema) {
|
|
63
|
+
return schema.parse(await response.json());
|
|
64
|
+
}
|