@notionhq/workers 0.4.0 → 0.6.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.
Files changed (204) hide show
  1. package/dist/alpha/builder.d.ts +149 -0
  2. package/dist/alpha/builder.d.ts.map +1 -0
  3. package/dist/alpha/builder.js +260 -0
  4. package/dist/alpha/builder.test.d.ts +2 -0
  5. package/dist/alpha/builder.test.d.ts.map +1 -0
  6. package/dist/alpha/cli/build.d.ts +13 -0
  7. package/dist/alpha/cli/build.d.ts.map +1 -0
  8. package/dist/alpha/cli/build.js +36 -0
  9. package/dist/alpha/cli/build.test.d.ts +2 -0
  10. package/dist/alpha/cli/build.test.d.ts.map +1 -0
  11. package/dist/alpha/cli/codegen.d.ts +10 -0
  12. package/dist/alpha/cli/codegen.d.ts.map +1 -0
  13. package/dist/alpha/cli/codegen.js +41 -0
  14. package/dist/alpha/cli/codegen.test.d.ts +2 -0
  15. package/dist/alpha/cli/codegen.test.d.ts.map +1 -0
  16. package/dist/alpha/cli/discover.d.ts +35 -0
  17. package/dist/alpha/cli/discover.d.ts.map +1 -0
  18. package/dist/alpha/cli/discover.js +39 -0
  19. package/dist/alpha/cli/discover.test.d.ts +2 -0
  20. package/dist/alpha/cli/discover.test.d.ts.map +1 -0
  21. package/dist/alpha/cli/emit-manifest.d.ts +33 -0
  22. package/dist/alpha/cli/emit-manifest.d.ts.map +1 -0
  23. package/dist/alpha/cli/emit-manifest.js +266 -0
  24. package/dist/alpha/cli/emit-manifest.test.d.ts +2 -0
  25. package/dist/alpha/cli/emit-manifest.test.d.ts.map +1 -0
  26. package/dist/alpha/cli/index.d.ts +3 -0
  27. package/dist/alpha/cli/index.d.ts.map +1 -0
  28. package/dist/alpha/cli/index.js +36 -0
  29. package/dist/alpha/context.d.ts +8 -0
  30. package/dist/alpha/context.d.ts.map +1 -0
  31. package/dist/alpha/context.js +33 -0
  32. package/dist/alpha/database.d.ts +90 -0
  33. package/dist/alpha/database.d.ts.map +1 -0
  34. package/dist/alpha/database.js +9 -0
  35. package/dist/alpha/error.d.ts +41 -0
  36. package/dist/alpha/error.d.ts.map +1 -0
  37. package/dist/alpha/error.js +25 -0
  38. package/dist/alpha/icon-names.d.ts +6 -0
  39. package/dist/alpha/icon-names.d.ts.map +1 -0
  40. package/dist/alpha/icon-names.js +0 -0
  41. package/dist/alpha/json-schema.d.ts +117 -0
  42. package/dist/alpha/json-schema.d.ts.map +1 -0
  43. package/dist/alpha/json-schema.js +0 -0
  44. package/dist/alpha/manifest.d.ts +44 -0
  45. package/dist/alpha/manifest.d.ts.map +1 -0
  46. package/dist/alpha/manifest.js +0 -0
  47. package/dist/alpha/output.d.ts +7 -0
  48. package/dist/alpha/output.d.ts.map +1 -0
  49. package/dist/alpha/output.js +8 -0
  50. package/dist/alpha/pacer.d.ts +74 -0
  51. package/dist/alpha/pacer.d.ts.map +1 -0
  52. package/dist/alpha/pacer.js +66 -0
  53. package/dist/alpha/pacer.test.d.ts +2 -0
  54. package/dist/alpha/pacer.test.d.ts.map +1 -0
  55. package/dist/alpha/schedule.d.ts +6 -0
  56. package/dist/alpha/schedule.d.ts.map +1 -0
  57. package/dist/alpha/schedule.js +43 -0
  58. package/dist/alpha/schedule.test.d.ts +2 -0
  59. package/dist/alpha/schedule.test.d.ts.map +1 -0
  60. package/dist/alpha/schema-builder.d.ts +79 -0
  61. package/dist/alpha/schema-builder.d.ts.map +1 -0
  62. package/dist/alpha/schema-builder.js +135 -0
  63. package/dist/alpha/schema.d.ts +185 -0
  64. package/dist/alpha/schema.d.ts.map +1 -0
  65. package/dist/alpha/schema.js +115 -0
  66. package/dist/alpha/sync.d.ts +233 -0
  67. package/dist/alpha/sync.d.ts.map +1 -0
  68. package/dist/alpha/sync.js +70 -0
  69. package/dist/alpha/sync.test.d.ts +2 -0
  70. package/dist/alpha/sync.test.d.ts.map +1 -0
  71. package/dist/alpha/tool.d.ts +132 -0
  72. package/dist/alpha/tool.d.ts.map +1 -0
  73. package/dist/alpha/tool.js +156 -0
  74. package/dist/alpha/tool.test.d.ts +2 -0
  75. package/dist/alpha/tool.test.d.ts.map +1 -0
  76. package/dist/alpha/triggers.d.ts +365 -0
  77. package/dist/alpha/triggers.d.ts.map +1 -0
  78. package/dist/alpha/triggers.generated.d.ts +246 -0
  79. package/dist/alpha/triggers.generated.d.ts.map +1 -0
  80. package/dist/alpha/triggers.generated.js +239 -0
  81. package/dist/alpha/triggers.js +0 -0
  82. package/dist/alpha/types.d.ts +228 -0
  83. package/dist/alpha/types.d.ts.map +1 -0
  84. package/dist/alpha/types.js +0 -0
  85. package/dist/alpha/workflow.d.ts +70 -0
  86. package/dist/alpha/workflow.d.ts.map +1 -0
  87. package/dist/alpha/workflow.js +39 -0
  88. package/dist/alpha/workflow.test.d.ts +2 -0
  89. package/dist/alpha/workflow.test.d.ts.map +1 -0
  90. package/dist/builder.d.ts +7 -1
  91. package/dist/builder.d.ts.map +1 -1
  92. package/dist/builder.js +12 -3
  93. package/dist/capabilities/ai_connector.d.ts.map +1 -1
  94. package/dist/capabilities/automation.d.ts.map +1 -1
  95. package/dist/capabilities/context.d.ts.map +1 -1
  96. package/dist/capabilities/context.js +1 -1
  97. package/dist/capabilities/custom-block.d.ts +124 -0
  98. package/dist/capabilities/custom-block.d.ts.map +1 -0
  99. package/dist/capabilities/custom-block.js +22 -0
  100. package/dist/capabilities/oauth.d.ts.map +1 -1
  101. package/dist/capabilities/output.d.ts.map +1 -1
  102. package/dist/capabilities/output.js +2 -4
  103. package/dist/capabilities/stateful-capability.d.ts.map +1 -1
  104. package/dist/capabilities/stateful-capability.js +3 -7
  105. package/dist/capabilities/sync.d.ts +11 -1
  106. package/dist/capabilities/sync.d.ts.map +1 -1
  107. package/dist/capabilities/sync.js +2 -8
  108. package/dist/capabilities/tool.d.ts.map +1 -1
  109. package/dist/capabilities/tool.js +6 -20
  110. package/dist/capabilities/webhook.d.ts.map +1 -1
  111. package/dist/capabilities/workflow.d.ts +50 -0
  112. package/dist/capabilities/workflow.d.ts.map +1 -0
  113. package/dist/capabilities/workflow.js +40 -0
  114. package/dist/capabilities/workflow.test.d.ts +2 -0
  115. package/dist/capabilities/workflow.test.d.ts.map +1 -0
  116. package/dist/index.d.ts +5 -3
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +2 -1
  119. package/dist/json-schema.d.ts.map +1 -1
  120. package/dist/schema-builder.d.ts.map +1 -1
  121. package/dist/schema.d.ts.map +1 -1
  122. package/dist/triggers.d.ts +365 -0
  123. package/dist/triggers.d.ts.map +1 -0
  124. package/dist/triggers.generated.d.ts +246 -0
  125. package/dist/triggers.generated.d.ts.map +1 -0
  126. package/dist/triggers.generated.js +239 -0
  127. package/dist/triggers.js +0 -0
  128. package/dist/types.d.ts +18 -0
  129. package/dist/types.d.ts.map +1 -1
  130. package/dist/worker.d.ts +72 -2
  131. package/dist/worker.d.ts.map +1 -1
  132. package/dist/worker.js +85 -4
  133. package/package.json +81 -14
  134. package/src/alpha/ajv-formats.d.ts +7 -0
  135. package/src/alpha/builder.test.ts +197 -0
  136. package/src/alpha/builder.ts +338 -0
  137. package/src/alpha/cli/build.test.ts +240 -0
  138. package/src/alpha/cli/build.ts +57 -0
  139. package/src/alpha/cli/codegen.test.ts +31 -0
  140. package/src/alpha/cli/codegen.ts +51 -0
  141. package/src/alpha/cli/discover.test.ts +43 -0
  142. package/src/alpha/cli/discover.ts +81 -0
  143. package/src/alpha/cli/emit-manifest.test.ts +45 -0
  144. package/src/alpha/cli/emit-manifest.ts +409 -0
  145. package/src/alpha/cli/index.ts +41 -0
  146. package/src/alpha/context.ts +61 -0
  147. package/src/alpha/database.ts +102 -0
  148. package/src/alpha/error.ts +49 -0
  149. package/src/alpha/icon-names.ts +890 -0
  150. package/src/alpha/json-schema.ts +180 -0
  151. package/src/alpha/manifest.ts +47 -0
  152. package/src/alpha/output.ts +8 -0
  153. package/src/alpha/pacer.test.ts +81 -0
  154. package/src/alpha/pacer.ts +181 -0
  155. package/src/alpha/schedule.test.ts +31 -0
  156. package/src/alpha/schedule.ts +53 -0
  157. package/src/alpha/schema-builder.ts +193 -0
  158. package/src/alpha/schema.ts +222 -0
  159. package/src/alpha/sync.test.ts +191 -0
  160. package/src/alpha/sync.ts +340 -0
  161. package/src/alpha/tool.test.ts +116 -0
  162. package/src/alpha/tool.ts +319 -0
  163. package/src/alpha/triggers.generated.ts +489 -0
  164. package/src/alpha/triggers.ts +500 -0
  165. package/src/alpha/types.ts +284 -0
  166. package/src/alpha/workflow.test.ts +84 -0
  167. package/src/alpha/workflow.ts +131 -0
  168. package/src/builder.test.ts +28 -60
  169. package/src/builder.ts +20 -7
  170. package/src/capabilities/ai_connector.test.ts +9 -32
  171. package/src/capabilities/ai_connector.ts +5 -17
  172. package/src/capabilities/automation.test.ts +3 -12
  173. package/src/capabilities/automation.ts +3 -11
  174. package/src/capabilities/context.ts +5 -8
  175. package/src/capabilities/custom-block.ts +181 -0
  176. package/src/capabilities/oauth.test.ts +1 -0
  177. package/src/capabilities/oauth.ts +1 -3
  178. package/src/capabilities/output.ts +1 -3
  179. package/src/capabilities/stateful-capability.test.ts +1 -0
  180. package/src/capabilities/stateful-capability.ts +3 -7
  181. package/src/capabilities/sync.test.ts +76 -42
  182. package/src/capabilities/sync.ts +16 -40
  183. package/src/capabilities/tool.test.ts +106 -146
  184. package/src/capabilities/tool.ts +17 -39
  185. package/src/capabilities/webhook.ts +3 -10
  186. package/src/capabilities/workflow.test.ts +163 -0
  187. package/src/capabilities/workflow.ts +112 -0
  188. package/src/index.ts +18 -6
  189. package/src/json-schema.test.ts +2 -4
  190. package/src/json-schema.ts +7 -6
  191. package/src/pacer.test.ts +1 -3
  192. package/src/pacer_internal.ts +1 -5
  193. package/src/schema-builder.test.ts +10 -35
  194. package/src/schema-builder.ts +6 -16
  195. package/src/schema.ts +2 -10
  196. package/src/triggers.generated.ts +489 -0
  197. package/src/triggers.ts +504 -0
  198. package/src/types.ts +21 -7
  199. package/src/worker.test.ts +147 -0
  200. package/src/worker.ts +155 -32
  201. package/dist/block.d.ts +0 -321
  202. package/dist/block.d.ts.map +0 -1
  203. package/src/block.ts +0 -529
  204. /package/dist/{block.js → alpha/ajv-formats.d.js} +0 -0
@@ -0,0 +1,504 @@
1
+ /**
2
+ * Agent Trigger Types — Public API
3
+ *
4
+ * Shared type definitions for agent triggers between @notionhq/workers and the Notion repository.
5
+ * This file MUST be kept identical in both repositories.
6
+ *
7
+ * Conventions:
8
+ * - Protocols define the standard fields every consumer can rely on.
9
+ * - Vendor-specific fields use `x-<vendor>-` prefix (e.g., "x-slack-threadId").
10
+ * - Only public URLs — no internal URIs.
11
+ * - No `data` sub-object — vendor fields live at the top level with `x-<vendor>-`.
12
+ * - Types only — no runtime values.
13
+ * - All fields are required. Nullable fields use `T | null` (no `?:`) so they
14
+ * map directly to required + nullable in JSON Schema for LLM structured output.
15
+ * - Conversions must always provide explicit values (use `null` when absent).
16
+ */
17
+
18
+ // ============================================================
19
+ // Vendor extension pattern
20
+ // ============================================================
21
+
22
+ /** Allows arbitrary vendor-specific fields prefixed with `x-<vendor>-`. */
23
+ export type VendorExtensions = {
24
+ [key: `x-${string}`]: unknown
25
+ }
26
+
27
+ // ============================================================
28
+ // Protocols (composable capabilities)
29
+ // ============================================================
30
+
31
+ /** Has a human-readable message / summary. */
32
+ export type MessageLike = {
33
+ message: string
34
+ }
35
+
36
+ /** Has an actor who performed the action. */
37
+ export type ActorLike = {
38
+ actor: Actor | null
39
+ }
40
+
41
+ /** Has a navigable URL. */
42
+ export type LinkLike = {
43
+ url: string | null
44
+ }
45
+
46
+ /** Has a timestamp. */
47
+ export type TimestampLike = {
48
+ /** ISO 8601 */
49
+ timestamp: string | null
50
+ }
51
+
52
+ /** Has a conversation thread. */
53
+ export type ThreadLike<M = ThreadMessage> = {
54
+ thread: Array<M>
55
+ /** Whether this event is a follow-up in a previously subscribed thread. */
56
+ isFollowUpMessage: boolean | null
57
+ }
58
+
59
+ /**
60
+ * A chat message. Any chat platform (Slack, Discord, MS Teams, etc.) implements this.
61
+ * Composes MessageLike, ActorLike, LinkLike, TimestampLike.
62
+ */
63
+ export type ChatMessageLike = MessageLike &
64
+ ActorLike &
65
+ LinkLike &
66
+ TimestampLike & {
67
+ id: string
68
+ channelId: string
69
+ channelName: string | null
70
+ }
71
+
72
+ /** An email message. Any mail provider (Gmail, Outlook, etc.) implements this. */
73
+ export type EmailMessageLike = MessageLike &
74
+ LinkLike &
75
+ TimestampLike & {
76
+ id: string
77
+ subject: string
78
+ from: string
79
+ fromName: string | null
80
+ to: Array<string>
81
+ cc: Array<string> | null
82
+ bcc: Array<string> | null
83
+ /** Plain-text or HTML body content. */
84
+ body: string
85
+ isRead: boolean | null
86
+ hasAttachments: boolean | null
87
+ labels: Array<string> | null
88
+ }
89
+
90
+ /** An email thread. Any mail provider implements this. */
91
+ export type EmailThreadLike = {
92
+ id: string
93
+ subject: string
94
+ participants: Array<string>
95
+ messageCount: number
96
+ /** ISO 8601 */
97
+ lastMessageAt: string
98
+ hasUnread: boolean
99
+ }
100
+
101
+ /** A calendar event. Any calendar provider (Google, Outlook, iCal, etc.) implements this. */
102
+ export type CalendarEventLike = LinkLike &
103
+ TimestampLike & {
104
+ eventId: string
105
+ summary: string
106
+ description: string | null
107
+ location: string | null
108
+ /** ISO 8601 */
109
+ startTime: string
110
+ /** ISO 8601 */
111
+ endTime: string | null
112
+ isAllDay: boolean | null
113
+ isRecurring: boolean | null
114
+ attendees: Array<Actor> | null
115
+ calendarId: string
116
+ accountId: string
117
+ }
118
+
119
+ // ============================================================
120
+ // Core types
121
+ // ============================================================
122
+
123
+ /**
124
+ * An actor who performed an action.
125
+ *
126
+ * `id` / `displayName` / `email` are the Notion-resolved identity.
127
+ * `vendorActor` carries the identity in the originating system.
128
+ */
129
+ export type Actor = {
130
+ /** Notion user ID (when resolved). */
131
+ id: string | null
132
+ displayName: string | null
133
+ email: string | null
134
+ /** The actor's identity in the vendor system. */
135
+ vendorActor: VendorActor | null
136
+ }
137
+
138
+ /** Vendor-specific actor identity. */
139
+ export type VendorActor = {
140
+ /** Vendor name: "slack", "gmail", "discord", "notion", etc. */
141
+ vendor: string
142
+ /** Vendor-specific ID. */
143
+ id: string
144
+ displayName: string | null
145
+ /** Handle / username (e.g., Slack @handle). */
146
+ handle: string | null
147
+ /** "user", "bot", or a vendor-specific string. */
148
+ type: "user" | "bot" | string | null
149
+ /** URL to the actor's profile in the vendor system. */
150
+ url: string | null
151
+ }
152
+
153
+ // ============================================================
154
+ // Thread message
155
+ // ============================================================
156
+
157
+ /**
158
+ * A single message inside a thread.
159
+ * Implements MessageLike, ActorLike, LinkLike, TimestampLike.
160
+ * Vendor-specific fields use `x-<vendor>-` prefix.
161
+ */
162
+ export type ThreadMessage = MessageLike &
163
+ ActorLike &
164
+ LinkLike &
165
+ TimestampLike &
166
+ VendorExtensions & {
167
+ id: string
168
+ }
169
+
170
+ /** A chat thread message. Extends ChatMessageLike with VendorExtensions. */
171
+ export type ChatThreadMessage = ChatMessageLike & VendorExtensions
172
+
173
+ /** An email message in a trigger. Extends EmailMessageLike with VendorExtensions. */
174
+ export type EmailTriggerMessage = EmailMessageLike & VendorExtensions
175
+
176
+ // ============================================================
177
+ // Trigger event base
178
+ // ============================================================
179
+
180
+ /**
181
+ * Every trigger event has at least these fields.
182
+ * `message` is a human-readable summary of what happened.
183
+ */
184
+ export type TriggerEventBase = MessageLike &
185
+ ActorLike &
186
+ VendorExtensions & {
187
+ type: string
188
+ vendor: string
189
+ }
190
+
191
+ /**
192
+ * Base shape for chat trigger events (Slack, Discord, MS Teams, etc.).
193
+ * Parameterized on the message type so each platform can narrow
194
+ * `triggerMessage` and `thread` to its vendor-specific message shape.
195
+ */
196
+ type ChatEventBase<M extends ChatThreadMessage = ChatThreadMessage> =
197
+ TriggerEventBase &
198
+ LinkLike &
199
+ TimestampLike &
200
+ ThreadLike<M> & {
201
+ /** The message that fired the trigger. */
202
+ triggerMessage: M
203
+ channelId: string
204
+ channelName: string | null
205
+ threadId: string | null
206
+ }
207
+
208
+ // ============================================================
209
+ // Slack
210
+ // ============================================================
211
+
212
+ export type SlackChatThreadMessage = ChatThreadMessage & {
213
+ "x-slack-fileUrls": Array<string> | null
214
+ /** URLs extracted from the message text. */
215
+ "x-slack-urls": Array<string> | null
216
+ }
217
+
218
+ export type SlackMessageEvent = ChatEventBase<SlackChatThreadMessage> & {
219
+ type: "slack.message"
220
+ vendor: "slack"
221
+ }
222
+
223
+ export type SlackReactionAddedEvent = ChatEventBase<SlackChatThreadMessage> & {
224
+ type: "slack.reaction.added"
225
+ vendor: "slack"
226
+ /** The emoji name (without colons), e.g. "thumbsup". */
227
+ "x-slack-reaction": string | null
228
+ }
229
+
230
+ export type SlackAppMentionEvent = ChatEventBase<SlackChatThreadMessage> & {
231
+ type: "slack.app.mention"
232
+ vendor: "slack"
233
+ }
234
+
235
+ // ============================================================
236
+ // Mail
237
+ // ============================================================
238
+
239
+ /** Base shape for all mail trigger events. */
240
+ type MailEventBase = TriggerEventBase &
241
+ LinkLike &
242
+ TimestampLike & {
243
+ vendor: "notionmail" | "gmail" | string
244
+ /** The triggering email. */
245
+ email: EmailTriggerMessage
246
+ /** The email thread this message belongs to. */
247
+ emailThread: EmailThreadLike
248
+ /** The email address of the mailbox owner. */
249
+ userEmail: string
250
+ }
251
+
252
+ export type MailEmailReceivedEvent = MailEventBase & {
253
+ type: "mail.email.received"
254
+ }
255
+
256
+ export type MailEmailSentEvent = MailEventBase & {
257
+ type: "mail.email.sent"
258
+ }
259
+
260
+ export type MailLabelAppliedEvent = MailEventBase & {
261
+ type: "mail.label.applied"
262
+ /** The label that was applied. */
263
+ appliedLabel: string
264
+ }
265
+
266
+ // ============================================================
267
+ // Calendar
268
+ // ============================================================
269
+
270
+ /** Base shape for all calendar trigger events. */
271
+ type CalendarEventBase = TriggerEventBase &
272
+ CalendarEventLike & {
273
+ vendor: "notion-calendar" | "google" | string
274
+ }
275
+
276
+ export type CalendarEventCreatedEvent = CalendarEventBase & {
277
+ type: "calendar.event.created"
278
+ }
279
+
280
+ export type CalendarEventUpdatedEvent = CalendarEventBase & {
281
+ type: "calendar.event.updated"
282
+ /** Which fields changed. */
283
+ updatedFields: Array<string> | null
284
+ }
285
+
286
+ export type CalendarEventCanceledEvent = CalendarEventBase & {
287
+ type: "calendar.event.canceled"
288
+ }
289
+
290
+ // ============================================================
291
+ // Discord
292
+ // ============================================================
293
+
294
+ export type DiscordChatThreadMessage = ChatThreadMessage & {
295
+ "x-discord-guildId": string | null
296
+ }
297
+
298
+ export type DiscordInteractionEvent =
299
+ ChatEventBase<DiscordChatThreadMessage> & {
300
+ type: "discord.interaction"
301
+ vendor: "discord"
302
+ "x-discord-guildId": string | null
303
+ }
304
+
305
+ // ============================================================
306
+ // Notion — Page / Database triggers
307
+ // ============================================================
308
+
309
+ /** A property edit with before/after snapshots. */
310
+ export type NotionPageEdit = {
311
+ before: Record<string, unknown> | null
312
+ after: Record<string, unknown> | null
313
+ afterContent: string | null
314
+ contentChanged: boolean | null
315
+ timestamp: number
316
+ editedBy: Actor | null
317
+ }
318
+
319
+ export type NotionPageCreatedEvent = TriggerEventBase &
320
+ LinkLike &
321
+ TimestampLike & {
322
+ type: "notion.page.created"
323
+ vendor: "notion"
324
+ /** Page properties as key-value pairs. */
325
+ page: Record<string, unknown>
326
+ /** Rendered markdown content of the page. */
327
+ content: string
328
+ edits: Array<NotionPageEdit> | null
329
+ }
330
+
331
+ export type NotionPageUpdatedEvent = TriggerEventBase &
332
+ LinkLike &
333
+ TimestampLike & {
334
+ type: "notion.page.updated"
335
+ vendor: "notion"
336
+ /** Chronological array of edits (accumulated during debounce). */
337
+ edits: Array<NotionPageEdit>
338
+ }
339
+
340
+ export type NotionPageDeletedEvent = TriggerEventBase &
341
+ LinkLike &
342
+ TimestampLike & {
343
+ type: "notion.page.deleted"
344
+ vendor: "notion"
345
+ page: Record<string, unknown>
346
+ content: string
347
+ }
348
+
349
+ export type NotionMeetingNoteSummaryCompletedEvent = TriggerEventBase &
350
+ LinkLike &
351
+ TimestampLike & {
352
+ type: "notion.meetingNote.summary.completed"
353
+ vendor: "notion"
354
+ page: Record<string, unknown>
355
+ content: string
356
+ meetingNoteBlockId: string
357
+ }
358
+
359
+ // ============================================================
360
+ // Notion — Discussion / Comment triggers
361
+ // ============================================================
362
+
363
+ export type NotionCommentAddedEvent = TriggerEventBase &
364
+ LinkLike &
365
+ TimestampLike & {
366
+ type: "notion.page.discussion.comment.added"
367
+ vendor: "notion"
368
+ /** The full discussion context. */
369
+ discussion: {
370
+ id: string
371
+ pageId: string
372
+ resolved: boolean
373
+ context: "inline" | "block" | "page" | "databaseProperty" | null
374
+ parentBlockId: string | null
375
+ propertyId: string | null
376
+ propertyName: string | null
377
+ }
378
+ /** The new comment. */
379
+ comment: {
380
+ id: string
381
+ text: string
382
+ url: string
383
+ timestamp: string
384
+ actor: Actor | null
385
+ }
386
+ }
387
+
388
+ // ============================================================
389
+ // Notion — Agent / Button triggers
390
+ // ============================================================
391
+
392
+ export type NotionAgentMentionedEvent = TriggerEventBase &
393
+ LinkLike &
394
+ TimestampLike & {
395
+ type: "notion.agent.mentioned"
396
+ vendor: "notion"
397
+ page: Record<string, unknown>
398
+ content: string
399
+ mentionLocation: "page_content" | "person_property"
400
+ mentionBlockContent: string | null
401
+ propertyId: string | null
402
+ propertyName: string | null
403
+ }
404
+
405
+ export type NotionButtonPressedEvent = TriggerEventBase &
406
+ LinkLike &
407
+ TimestampLike & {
408
+ type: "notion.button.pressed"
409
+ vendor: "notion"
410
+ blockUrl: string
411
+ }
412
+
413
+ export type NotionDatabaseAgentUpdatedEvent = TriggerEventBase &
414
+ TimestampLike & {
415
+ type: "notion.database.agent.updated"
416
+ vendor: "notion"
417
+ agentId: string
418
+ runtimeInstructions: string
419
+ shouldRunOverDatabase: boolean
420
+ viewId: string | null
421
+ }
422
+
423
+ export type WebhookEvent = TriggerEventBase &
424
+ TimestampLike & {
425
+ type: "webhooks.webhook"
426
+ vendor: "webhooks"
427
+ triggerId: string
428
+ verificationSchema: string
429
+ eventType: string | null
430
+ deliveryId: string | null
431
+ payload: unknown
432
+ }
433
+
434
+ // ============================================================
435
+ // Google Drive OAuth — File changed (polling) trigger
436
+ // ============================================================
437
+
438
+ export type GoogleDriveOauthFilesChangedEvent = TriggerEventBase &
439
+ TimestampLike & {
440
+ type: "googleDriveOauth.filesChanged"
441
+ vendor: "google-drive"
442
+ /** The page token from before this poll. */
443
+ changeToken: string
444
+ /** The page token after this poll. */
445
+ newChangeToken: string
446
+ /** Number of changes detected. */
447
+ changeCount: number
448
+ /** The folder or drive being watched. */
449
+ scope:
450
+ | { type: "folder"; folderId: string }
451
+ | { type: "drive"; driveId: string }
452
+ /** Upper time bound for this poll window (ISO 8601). */
453
+ lastEventTimestamp: string
454
+ }
455
+
456
+ // ============================================================
457
+ // Recurrence (scheduled) trigger
458
+ // ============================================================
459
+
460
+ export type RecurrenceFrequency = "hour" | "day" | "week" | "month" | "year"
461
+
462
+ export type RecurrenceEvent = TriggerEventBase &
463
+ TimestampLike & {
464
+ type: "recurrence"
465
+ vendor: "notion"
466
+ frequency: RecurrenceFrequency
467
+ interval: number
468
+ timezone: string
469
+ }
470
+
471
+ // ============================================================
472
+ // Derived union types
473
+ // ============================================================
474
+
475
+ /** Map from trigger type string to its event shape. Single source of truth. */
476
+ export type TriggerEventMap = {
477
+ "slack.message": SlackMessageEvent
478
+ "slack.reaction.added": SlackReactionAddedEvent
479
+ "slack.app.mention": SlackAppMentionEvent
480
+ "discord.interaction": DiscordInteractionEvent
481
+ "mail.email.received": MailEmailReceivedEvent
482
+ "mail.email.sent": MailEmailSentEvent
483
+ "mail.label.applied": MailLabelAppliedEvent
484
+ "calendar.event.created": CalendarEventCreatedEvent
485
+ "calendar.event.updated": CalendarEventUpdatedEvent
486
+ "calendar.event.canceled": CalendarEventCanceledEvent
487
+ "notion.page.created": NotionPageCreatedEvent
488
+ "notion.page.updated": NotionPageUpdatedEvent
489
+ "notion.page.deleted": NotionPageDeletedEvent
490
+ "notion.meetingNote.summary.completed": NotionMeetingNoteSummaryCompletedEvent
491
+ "notion.page.discussion.comment.added": NotionCommentAddedEvent
492
+ "notion.agent.mentioned": NotionAgentMentionedEvent
493
+ "notion.button.pressed": NotionButtonPressedEvent
494
+ "notion.database.agent.updated": NotionDatabaseAgentUpdatedEvent
495
+ "webhooks.webhook": WebhookEvent
496
+ "googleDriveOauth.filesChanged": GoogleDriveOauthFilesChangedEvent
497
+ recurrence: RecurrenceEvent
498
+ }
499
+
500
+ /** All trigger type strings. Derived from TriggerEventMap. */
501
+ export type TriggerType = keyof TriggerEventMap
502
+
503
+ /** Discriminated union of all trigger events. Derived from TriggerEventMap. */
504
+ export type TriggerEvent = TriggerEventMap[TriggerType]
package/src/types.ts CHANGED
@@ -118,13 +118,7 @@ export type NumberFormat =
118
118
  /**
119
119
  * Date format types
120
120
  */
121
- export type DateFormat =
122
- | "relative"
123
- | "MM/DD/YYYY"
124
- | "DD/MM/YYYY"
125
- | "YYYY/MM/DD"
126
- | "ll"
127
- | "MMM d";
121
+ export type DateFormat = "relative" | "MM/DD/YYYY" | "DD/MM/YYYY" | "YYYY/MM/DD" | "ll" | "MMM d";
128
122
 
129
123
  import type { NoticonName } from "./icon-names.js";
130
124
 
@@ -182,6 +176,26 @@ export interface ImageIcon {
182
176
  */
183
177
  export type Icon = EmojiIcon | NoticonIcon | ImageIcon;
184
178
 
179
+ /**
180
+ * Cover image for a Notion page.
181
+ */
182
+ export interface ImageCover {
183
+ type: "image";
184
+ /**
185
+ * The URL of the image (must be a valid http/https URL)
186
+ */
187
+ url: string;
188
+ /**
189
+ * Vertical image position, from 0 (top) to 1 (bottom).
190
+ */
191
+ position?: number;
192
+ }
193
+
194
+ /**
195
+ * All possible cover types
196
+ */
197
+ export type Cover = ImageCover;
198
+
185
199
  /**
186
200
  * Person reference - represents a user in a people property
187
201
  */
@@ -141,6 +141,153 @@ describe("Worker", () => {
141
141
  ]);
142
142
  });
143
143
 
144
+ it("registers a project custom block from a folder path (type defaults to project)", () => {
145
+ const worker = new Worker();
146
+
147
+ worker.customBlock("visualBlock", {
148
+ path: "./views/visual",
149
+ });
150
+
151
+ expect(worker.manifest.capabilities).toEqual([
152
+ {
153
+ _tag: "custom_block",
154
+ key: "visualBlock",
155
+ config: {
156
+ source: { type: "project", path: "./views/visual" },
157
+ manifest: {
158
+ version: 1,
159
+ dataSources: {},
160
+ },
161
+ },
162
+ },
163
+ ]);
164
+ });
165
+
166
+ it("carries a project's custom build command and output dir", () => {
167
+ const worker = new Worker();
168
+
169
+ worker.customBlock("built", {
170
+ path: "./app",
171
+ command: "npm run build-prod",
172
+ output: "build",
173
+ });
174
+
175
+ expect(worker.manifest.capabilities).toEqual([
176
+ {
177
+ _tag: "custom_block",
178
+ key: "built",
179
+ config: {
180
+ source: {
181
+ type: "project",
182
+ path: "./app",
183
+ command: "npm run build-prod",
184
+ output: "build",
185
+ },
186
+ manifest: { version: 1, dataSources: {} },
187
+ },
188
+ },
189
+ ]);
190
+ });
191
+
192
+ it("registers a static custom block served as-is", () => {
193
+ const worker = new Worker();
194
+
195
+ worker.customBlock("prebuilt", { type: "static", path: "./dist" });
196
+
197
+ expect(worker.manifest.capabilities).toEqual([
198
+ {
199
+ _tag: "custom_block",
200
+ key: "prebuilt",
201
+ config: {
202
+ source: { type: "static", path: "./dist" },
203
+ manifest: { version: 1, dataSources: {} },
204
+ },
205
+ },
206
+ ]);
207
+ });
208
+
209
+ it("carries the author-declared data-source schema verbatim into the manifest", () => {
210
+ const worker = new Worker();
211
+
212
+ worker.customBlock("issueBoard", {
213
+ path: "./views/issueBoard",
214
+ dataSources: {
215
+ issues: {
216
+ name: "Issues",
217
+ description: "The team's issues",
218
+ icon: { type: "emoji", emoji: "🐛" },
219
+ properties: {
220
+ title: { name: "Title", type: "title" },
221
+ status: {
222
+ name: "Status",
223
+ description: "Workflow state",
224
+ type: "status",
225
+ },
226
+ },
227
+ },
228
+ },
229
+ });
230
+
231
+ expect(worker.manifest.capabilities).toEqual([
232
+ {
233
+ _tag: "custom_block",
234
+ key: "issueBoard",
235
+ config: {
236
+ source: { type: "project", path: "./views/issueBoard" },
237
+ manifest: {
238
+ version: 1,
239
+ dataSources: {
240
+ issues: {
241
+ name: "Issues",
242
+ description: "The team's issues",
243
+ icon: { type: "emoji", emoji: "🐛" },
244
+ properties: {
245
+ title: { name: "Title", type: "title" },
246
+ status: {
247
+ name: "Status",
248
+ description: "Workflow state",
249
+ type: "status",
250
+ },
251
+ },
252
+ },
253
+ },
254
+ },
255
+ },
256
+ },
257
+ ]);
258
+ });
259
+
260
+ it("threads a top-level manifest version into the generated manifest", () => {
261
+ const worker = new Worker();
262
+
263
+ worker.customBlock("versioned", {
264
+ path: "./views/versioned",
265
+ version: 1,
266
+ });
267
+
268
+ expect(worker.manifest.capabilities).toEqual([
269
+ {
270
+ _tag: "custom_block",
271
+ key: "versioned",
272
+ config: {
273
+ source: { type: "project", path: "./views/versioned" },
274
+ manifest: { version: 1, dataSources: {} },
275
+ },
276
+ },
277
+ ]);
278
+ });
279
+
280
+ it("cannot run a custom block capability", async () => {
281
+ const worker = new Worker();
282
+ worker.customBlock("visualBlock", {
283
+ path: "./views/visual",
284
+ });
285
+
286
+ await expect(worker.run("visualBlock", {})).rejects.toThrow(
287
+ 'Cannot run custom block capability "visualBlock"',
288
+ );
289
+ });
290
+
144
291
  it("rejects duplicate keys across databases, pacers, and capabilities", () => {
145
292
  const worker = new Worker();
146
293
  const db = worker.database("shared-key", {