@notionhq/apps 0.0.33 → 0.0.35

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 (60) hide show
  1. package/README.md +59 -5
  2. package/dist/configured-events.d.ts +45 -0
  3. package/dist/configured-events.d.ts.map +1 -0
  4. package/dist/configured-events.js +38 -0
  5. package/dist/configured-events.test.d.ts +2 -0
  6. package/dist/configured-events.test.d.ts.map +1 -0
  7. package/dist/custom-block.d.ts +1 -1
  8. package/dist/events-types.test.d.ts +2 -0
  9. package/dist/events-types.test.d.ts.map +1 -0
  10. package/dist/{triggers.d.ts → events.d.ts} +1 -1
  11. package/dist/events.d.ts.map +1 -0
  12. package/dist/{triggers.generated.d.ts → events.generated.d.ts} +20 -38
  13. package/dist/events.generated.d.ts.map +1 -0
  14. package/dist/{triggers.generated.js → events.generated.js} +9 -35
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -0
  18. package/dist/notion-as-code/custom-agent.d.ts +15 -60
  19. package/dist/notion-as-code/custom-agent.d.ts.map +1 -1
  20. package/dist/notion-as-code/custom-agent.js +15 -1
  21. package/dist/notion-as-code/database.d.ts +11 -0
  22. package/dist/notion-as-code/database.d.ts.map +1 -1
  23. package/dist/notion-as-code/database.js +12 -0
  24. package/dist/notion-as-code/index.d.ts +1 -1
  25. package/dist/notion-as-code/index.d.ts.map +1 -1
  26. package/dist/notion-as-code/intents.d.ts +7 -1
  27. package/dist/notion-as-code/intents.d.ts.map +1 -1
  28. package/dist/notion-as-code/recurrence.d.ts +49 -0
  29. package/dist/notion-as-code/recurrence.d.ts.map +1 -0
  30. package/dist/notion-as-code/recurrence.js +0 -0
  31. package/dist/workflow.d.ts +4 -4
  32. package/dist/workflow.d.ts.map +1 -1
  33. package/dist/workflow.js +2 -2
  34. package/package.json +7 -7
  35. package/skills/connections/SKILL.md +3 -3
  36. package/skills/notion-as-code/SKILL.md +11 -7
  37. package/skills/workflow/SKILL.md +25 -5
  38. package/src/cli/build.test.ts +30 -0
  39. package/src/configured-events.test.ts +90 -0
  40. package/src/configured-events.ts +101 -0
  41. package/src/connections.ts +1 -1
  42. package/src/events-types.test.ts +110 -0
  43. package/src/{triggers.generated.ts → events.generated.ts} +21 -55
  44. package/src/index.ts +1 -0
  45. package/src/notion-as-code/custom-agent.test.ts +82 -2
  46. package/src/notion-as-code/custom-agent.ts +46 -74
  47. package/src/notion-as-code/database.ts +27 -0
  48. package/src/notion-as-code/index.ts +2 -0
  49. package/src/notion-as-code/intents.ts +2 -1
  50. package/src/notion-as-code/notion-as-code-types.test.ts +4 -1
  51. package/src/notion-as-code/recurrence.ts +58 -0
  52. package/src/workflow-access-types.test.ts +4 -4
  53. package/src/workflow-connections-types.test.ts +7 -7
  54. package/src/workflow-types.test.ts +23 -23
  55. package/src/workflow.test.ts +39 -39
  56. package/src/workflow.ts +7 -7
  57. package/dist/triggers.d.ts.map +0 -1
  58. package/dist/triggers.generated.d.ts.map +0 -1
  59. /package/dist/{triggers.js → events.js} +0 -0
  60. /package/src/{triggers.ts → events.ts} +0 -0
@@ -3,67 +3,21 @@ import type { CustomAgentIntent, NotionAsCodeIcon, ResourceId } from "./intents.
3
3
  import { recordIntent } from "./recorder.js";
4
4
  import { assertUserResourceId } from "./resource.js";
5
5
 
6
- type RecurrenceWeekday = "MO" | "TU" | "WE" | "TH" | "FR" | "SA" | "SU";
7
-
8
- /** A nonempty selection of weekdays for a weekly recurrence. */
9
- export type RecurrenceWeekdays = {
10
- [Day in RecurrenceWeekday]?: true;
11
- } & {
12
- [Day in RecurrenceWeekday]: Required<Pick<Record<RecurrenceWeekday, true>, Day>>;
13
- }[RecurrenceWeekday];
14
-
15
- export type MonthlyWeekdayOccurrence = "1st" | "2nd" | "3rd" | "4th" | "last";
16
-
17
- export type MonthlyRecurrenceRestriction =
18
- | { type: "day_of_month"; day: number }
19
- | {
20
- type: "weekday_of_month";
21
- weekday: RecurrenceWeekday;
22
- occurrence: MonthlyWeekdayOccurrence;
23
- };
24
-
25
- export type RecurrenceScheduleEnd =
26
- | { type: "date"; endsAt: string }
27
- | { type: "occurrences"; count: number };
28
-
29
- type RecurrenceScheduleBase = {
30
- interval: number;
31
- start: string;
32
- timeZone: string;
33
- end?: RecurrenceScheduleEnd;
34
- };
35
-
36
- export type HourlyRecurrenceSchedule = RecurrenceScheduleBase & {
37
- frequency: "hour";
38
- };
39
-
40
- export type DailyRecurrenceSchedule = RecurrenceScheduleBase & {
41
- frequency: "day";
42
- };
43
-
44
- export type WeeklyRecurrenceSchedule = RecurrenceScheduleBase & {
45
- frequency: "week";
46
- weekdays: RecurrenceWeekdays;
47
- };
48
-
49
- export type MonthlyRecurrenceSchedule = RecurrenceScheduleBase & {
50
- frequency: "month";
51
- monthlyRestriction: MonthlyRecurrenceRestriction;
52
- };
53
-
54
- export type YearlyRecurrenceSchedule = RecurrenceScheduleBase & {
55
- frequency: "year";
56
- };
57
-
58
- export type CustomAgentRecurrenceSchedule = (
59
- | HourlyRecurrenceSchedule
60
- | DailyRecurrenceSchedule
61
- | WeeklyRecurrenceSchedule
62
- | MonthlyRecurrenceSchedule
63
- | YearlyRecurrenceSchedule
64
- ) & {
65
- type: "recurrence";
66
- };
6
+ import type { RecurrenceSchedule } from "./recurrence.js";
7
+ export type {
8
+ RecurrenceWeekdays,
9
+ MonthlyWeekdayOccurrence,
10
+ MonthlyRecurrenceRestriction,
11
+ RecurrenceScheduleEnd,
12
+ HourlyRecurrenceSchedule,
13
+ DailyRecurrenceSchedule,
14
+ WeeklyRecurrenceSchedule,
15
+ MonthlyRecurrenceSchedule,
16
+ YearlyRecurrenceSchedule,
17
+ RecurrenceSchedule,
18
+ } from "./recurrence.js";
19
+
20
+ export type CustomAgentRecurrenceSchedule = RecurrenceSchedule & { type: "recurrence" };
67
21
 
68
22
  export type CustomAgentTriggerBase = {
69
23
  resourceId: ResourceId;
@@ -79,6 +33,8 @@ export type PropertyTriggerCondition = {
79
33
  export type CustomAgentPageAddedTrigger = CustomAgentTriggerBase & {
80
34
  type: "page_added";
81
35
  dataSourceResourceId: ResourceId;
36
+ /** Wait for follow-up edits before running the agent. Defaults to false in Apps. */
37
+ waitForEditsToFinish?: boolean;
82
38
  };
83
39
 
84
40
  type PropertyUpdatedTriggerTarget =
@@ -95,6 +51,8 @@ export type CustomAgentPropertyUpdatedTrigger = CustomAgentTriggerBase &
95
51
  PropertyUpdatedTriggerTarget & {
96
52
  type: "property_updated";
97
53
  dataSourceResourceId: ResourceId;
54
+ /** Wait for follow-up edits before running the agent. Defaults to false in Apps. */
55
+ waitForEditsToFinish?: boolean;
98
56
  };
99
57
 
100
58
  export type CustomAgentTrigger =
@@ -114,15 +72,8 @@ export type CustomAgentAccess = Extract<
114
72
  { readonly resource: { readonly resourceType: "page" | "database" } }
115
73
  >;
116
74
 
117
- /**
118
- * URL trust settings for a custom agent.
119
- *
120
- * URL trust is independent from web access: an agent can trust URLs without
121
- * being granted web search access.
122
- */
123
- export type CustomAgentTrustedUrls = {
124
- type: "all";
125
- };
75
+ /** Trust every URL, trust no URLs, or trust a nonempty list of up to 20 URL globs. */
76
+ export type CustomAgentTrustedUrls = "all" | "none" | [string, ...string[]];
126
77
 
127
78
  export type CustomAgentArgs = {
128
79
  resourceId: ResourceId;
@@ -130,6 +81,8 @@ export type CustomAgentArgs = {
130
81
  icon?: Exclude<NotionAsCodeIcon, { type: "file" }>;
131
82
  instructions?: string;
132
83
  model?: "ambrosia-tart-high" | "opal-quince-medium" | "almond-croissant-low";
84
+ /** Whether the agent can use the Web Browser. Omission preserves the existing setting. */
85
+ browserUse?: boolean;
133
86
  /**
134
87
  * Whether the agent can use web search. Defaults to `false` when omitted for
135
88
  * a new agent. When updating an existing agent, omitting this field preserves
@@ -137,9 +90,10 @@ export type CustomAgentArgs = {
137
90
  */
138
91
  webAccess?: boolean;
139
92
  /**
140
- * URL trust policy for this agent. `{ type: "all" }` allows every HTTP and
141
- * HTTPS URL. For a new agent, omitting this field leaves URL trust disabled;
142
- * for an existing agent, omission preserves the current URL trust policy.
93
+ * Set `"all"` to trust every HTTP and HTTPS URL, `"none"` to disable URL
94
+ * trust, or provide a nonempty list of up to 20 URL globs. Omission leaves
95
+ * trust disabled for a new agent and preserves it for an existing agent.
96
+ * URL trust is independent from web search.
143
97
  */
144
98
  trustedUrls?: CustomAgentTrustedUrls;
145
99
  /**
@@ -181,13 +135,31 @@ export function customAgent(args: CustomAgentArgs): CustomAgentHandle {
181
135
  }
182
136
  }
183
137
  }
184
- const { access: _access, ...intent } = args;
138
+ const { access: _access, trustedUrls, triggers, ...intent } = args;
185
139
  recordIntent({
186
140
  type: "custom_agent",
187
141
  ...intent,
142
+ ...(trustedUrls === undefined ? {} : { trustedUrls: toTrustedUrlsIntent(trustedUrls) }),
143
+ ...(triggers === undefined ? {} : { triggers: triggers.map(toTriggerIntent) }),
188
144
  ...(grants === undefined ? {} : { access: grants }),
189
145
  } satisfies {
190
146
  type: "custom_agent";
191
147
  } & CustomAgentIntent);
192
148
  return { resourceType: "customAgent", resourceId: args.resourceId };
193
149
  }
150
+
151
+ function toTriggerIntent(trigger: CustomAgentTrigger): CustomAgentTrigger {
152
+ if (trigger.type === "recurrence") {
153
+ return trigger;
154
+ }
155
+ return { ...trigger, waitForEditsToFinish: trigger.waitForEditsToFinish ?? false };
156
+ }
157
+
158
+ function toTrustedUrlsIntent(
159
+ trustedUrls: CustomAgentTrustedUrls,
160
+ ): NonNullable<CustomAgentIntent["trustedUrls"]> {
161
+ if (trustedUrls === "all") {
162
+ return { type: "all" };
163
+ }
164
+ return { type: "list", urls: trustedUrls === "none" ? [] : [...trustedUrls] };
165
+ }
@@ -118,6 +118,20 @@ export type ChildDatabaseArgs<
118
118
  | ChildMultiSourceDatabaseArgs<DataSources>
119
119
  | Omit<ViewOnlyDatabaseArgs, "parent">;
120
120
 
121
+ export type PropertyHandle<
122
+ Property extends NotionAsCodeSchema[string] = NotionAsCodeSchema[string],
123
+ > = {
124
+ readonly resourceType: "property";
125
+ readonly resourceId: Property["resourceId"];
126
+ readonly dataSourceResourceId: string;
127
+ readonly name: string;
128
+ readonly propertyType: Property["type"];
129
+ };
130
+
131
+ export type DataSourceProperties<Schema extends NotionAsCodeSchema> = {
132
+ readonly [Name in keyof Schema]: PropertyHandle<Schema[Name]>;
133
+ };
134
+
121
135
  /** A source handle retains its keyed authoring schema for sync inference. */
122
136
  export type DataSourceHandle<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> = {
123
137
  readonly resourceType: "dataSource";
@@ -125,6 +139,7 @@ export type DataSourceHandle<Schema extends NotionAsCodeSchema = NotionAsCodeSch
125
139
  readonly name: string;
126
140
  readonly description?: string;
127
141
  readonly schema: Schema;
142
+ readonly properties: DataSourceProperties<Schema>;
128
143
  readonly database: Database<AppsSchemaForSchema<Schema>>;
129
144
  addPage: (args: ChildPageArgs) => PageHandle;
130
145
  };
@@ -501,6 +516,7 @@ function createDataSourceHandle(
501
516
  schema: NotionAsCodeSchema,
502
517
  databaseDescription: string | undefined,
503
518
  ): DataSourceHandle {
519
+ const propertyEntries: Array<[string, PropertyHandle]> = [];
504
520
  const propertyResourceIds = new Set<string>();
505
521
  const propertyNames = new Set<string>();
506
522
  for (const property of dataSource.properties) {
@@ -517,6 +533,16 @@ function createDataSourceHandle(
517
533
  }
518
534
  propertyResourceIds.add(property.resourceId);
519
535
  propertyNames.add(property.name);
536
+ propertyEntries.push([
537
+ property.name,
538
+ {
539
+ resourceType: "property",
540
+ resourceId: property.resourceId,
541
+ dataSourceResourceId: dataSource.resourceId,
542
+ name: property.name,
543
+ propertyType: property.type,
544
+ },
545
+ ]);
520
546
  }
521
547
  const description = dataSource.description ?? databaseDescription;
522
548
 
@@ -526,6 +552,7 @@ function createDataSourceHandle(
526
552
  name: dataSource.name,
527
553
  ...(description === undefined ? {} : { description }),
528
554
  schema,
555
+ properties: Object.fromEntries(propertyEntries),
529
556
  database: createAppsDatabase(dataSource.resourceId, dataSource),
530
557
  addPage(pageArgs) {
531
558
  return createPage(pageArgs, { type: "resourceId", resourceId: dataSource.resourceId });
@@ -62,6 +62,8 @@ export type {
62
62
  ChildSingleSourceDatabaseArgs,
63
63
  DataSourceArgs,
64
64
  DataSourceHandle,
65
+ DataSourceProperties,
66
+ PropertyHandle,
65
67
  DataSourceMap,
66
68
  DatabaseArgs,
67
69
  DatabaseHandle,
@@ -347,7 +347,8 @@ export type DatabaseIntent = {
347
347
  };
348
348
 
349
349
  export type PageIntent = PageArgs & { parent: Parent };
350
- export type CustomAgentIntent = Omit<CustomAgentArgs, "access"> & {
350
+ export type CustomAgentIntent = Omit<CustomAgentArgs, "access" | "trustedUrls"> & {
351
+ trustedUrls?: { type: "all" } | { type: "list"; urls: string[] };
351
352
  access?: readonly { resourceId: ResourceId; level: ResourceAccessLevel }[];
352
353
  };
353
354
 
@@ -37,8 +37,11 @@ it("types custom agent resource access and URL trust", () => {
37
37
  expectTypeOf(
38
38
  access.call(customAgent({ resourceId: "agent", name: "Agent" })),
39
39
  ).not.toExtend<CustomAgentAccess>();
40
- expectTypeOf<{ type: "all" }>().toEqualTypeOf<CustomAgentTrustedUrls>();
40
+ expectTypeOf<CustomAgentTrustedUrls>().toEqualTypeOf<"all" | "none" | [string, ...string[]]>();
41
+ expectTypeOf<[]>().not.toExtend<CustomAgentTrustedUrls>();
42
+ expectTypeOf<{ type: "all" }>().not.toExtend<CustomAgentTrustedUrls>();
41
43
  expectTypeOf<CustomAgentArgs["webAccess"]>().toEqualTypeOf<boolean | undefined>();
44
+ expectTypeOf<CustomAgentArgs["browserUse"]>().toEqualTypeOf<boolean | undefined>();
42
45
  expectTypeOf<CustomAgentArgs["trustedUrls"]>().toEqualTypeOf<
43
46
  CustomAgentTrustedUrls | undefined
44
47
  >();
@@ -0,0 +1,58 @@
1
+ type RecurrenceWeekday = "MO" | "TU" | "WE" | "TH" | "FR" | "SA" | "SU";
2
+
3
+ /** A nonempty selection of weekdays for a weekly recurrence. */
4
+ export type RecurrenceWeekdays = {
5
+ [Day in RecurrenceWeekday]?: true;
6
+ } & {
7
+ [Day in RecurrenceWeekday]: Required<Pick<Record<RecurrenceWeekday, true>, Day>>;
8
+ }[RecurrenceWeekday];
9
+
10
+ export type MonthlyWeekdayOccurrence = "1st" | "2nd" | "3rd" | "4th" | "last";
11
+
12
+ export type MonthlyRecurrenceRestriction =
13
+ | { type: "day_of_month"; day: number }
14
+ | {
15
+ type: "weekday_of_month";
16
+ weekday: RecurrenceWeekday;
17
+ occurrence: MonthlyWeekdayOccurrence;
18
+ };
19
+
20
+ export type RecurrenceScheduleEnd =
21
+ | { type: "date"; endsAt: string }
22
+ | { type: "occurrences"; count: number };
23
+
24
+ type RecurrenceScheduleBase = {
25
+ interval: number;
26
+ start: string;
27
+ timeZone: string;
28
+ end?: RecurrenceScheduleEnd;
29
+ };
30
+
31
+ export type HourlyRecurrenceSchedule = RecurrenceScheduleBase & {
32
+ frequency: "hour";
33
+ };
34
+
35
+ export type DailyRecurrenceSchedule = RecurrenceScheduleBase & {
36
+ frequency: "day";
37
+ };
38
+
39
+ export type WeeklyRecurrenceSchedule = RecurrenceScheduleBase & {
40
+ frequency: "week";
41
+ weekdays: RecurrenceWeekdays;
42
+ };
43
+
44
+ export type MonthlyRecurrenceSchedule = RecurrenceScheduleBase & {
45
+ frequency: "month";
46
+ monthlyRestriction: MonthlyRecurrenceRestriction;
47
+ };
48
+
49
+ export type YearlyRecurrenceSchedule = RecurrenceScheduleBase & {
50
+ frequency: "year";
51
+ };
52
+
53
+ export type RecurrenceSchedule =
54
+ | HourlyRecurrenceSchedule
55
+ | DailyRecurrenceSchedule
56
+ | WeeklyRecurrenceSchedule
57
+ | MonthlyRecurrenceSchedule
58
+ | YearlyRecurrenceSchedule;
@@ -3,7 +3,7 @@ import { expectTypeOf, it } from "vitest";
3
3
  import { customAgent } from "./notion-as-code/custom-agent.js";
4
4
  import { database } from "./notion-as-code/database.js";
5
5
  import { page } from "./notion-as-code/page.js";
6
- import { triggers } from "./triggers.generated.js";
6
+ import { events } from "./events.generated.js";
7
7
  import { access, workflow } from "./workflow.js";
8
8
 
9
9
  it("infers access aliases and rejects resource-specific levels", () => {
@@ -26,7 +26,7 @@ it("infers access aliases and rejects resource-specific levels", () => {
26
26
  workflow({
27
27
  name: "Access types",
28
28
  description: "Checks access types",
29
- triggers: [triggers.notionPageCreated()],
29
+ triggers: [events.notionPageCreated()],
30
30
  access: {
31
31
  home: access.view(home),
32
32
  singleDatabase: access.edit(singleDatabase),
@@ -54,7 +54,7 @@ it("infers access aliases and rejects resource-specific levels", () => {
54
54
  workflow({
55
55
  name: "Agent access types",
56
56
  description: "Checks custom agent access types",
57
- triggers: [triggers.notionPageCreated()],
57
+ triggers: [events.notionPageCreated()],
58
58
  // @ts-expect-error Custom agents only support the call level.
59
59
  access: { agent: { resource: agent, level: "view" } },
60
60
  handler: () => {},
@@ -63,7 +63,7 @@ it("infers access aliases and rejects resource-specific levels", () => {
63
63
  workflow({
64
64
  name: "Page access types",
65
65
  description: "Checks page access types",
66
- triggers: [triggers.notionPageCreated()],
66
+ triggers: [events.notionPageCreated()],
67
67
  // @ts-expect-error Pages do not support the custom-agent call level.
68
68
  access: { home: { resource: home, level: "call" } },
69
69
  handler: () => {},
@@ -1,5 +1,5 @@
1
1
  import { expectTypeOf, it } from "vitest";
2
- import { triggers } from "./triggers.generated.js";
2
+ import { events } from "./events.generated.js";
3
3
  import { connections, workflow, type WorkflowConnectionDeclarations } from "./workflow.js";
4
4
 
5
5
  it("infers only the declared provider clients", () => {
@@ -7,7 +7,7 @@ it("infers only the declared provider clients", () => {
7
7
  name: "Mail",
8
8
  description: "Read the configured mailbox",
9
9
  connections: { inbox: connections.mail() },
10
- triggers: ({ triggers }) => [triggers.mailEmailReceived({ connectionKey: "inbox" })],
10
+ triggers: ({ events }) => [events.mailEmailReceived({ connectionKey: "inbox" })],
11
11
  handler(_event, context) {
12
12
  expectTypeOf<keyof typeof context.connections>().toEqualTypeOf<"inbox">();
13
13
  expectTypeOf(context.connections.inbox.searchEmails).toBeFunction();
@@ -19,7 +19,7 @@ it("infers only the declared provider clients", () => {
19
19
  workflow({
20
20
  name: "Calendar",
21
21
  description: "Calendar only",
22
- triggers: [triggers.notionPageCreated()],
22
+ triggers: [events.notionPageCreated()],
23
23
  connections: { work: connections.calendar() },
24
24
  handler(_event, context) {
25
25
  expectTypeOf<keyof typeof context.connections>().toEqualTypeOf<"work">();
@@ -37,7 +37,7 @@ it("infers only the declared provider clients", () => {
37
37
  workflow({
38
38
  name: "Multiple providers",
39
39
  description: "Preserves clients in a separately declared object",
40
- triggers: [triggers.notionPageCreated()],
40
+ triggers: [events.notionPageCreated()],
41
41
  connections: requirements,
42
42
  handler(_event, context) {
43
43
  expectTypeOf<keyof typeof context.connections>().toEqualTypeOf<
@@ -51,7 +51,7 @@ it("exposes no providers for omitted or empty connections", () => {
51
51
  workflow({
52
52
  name: "No connections",
53
53
  description: "Omitted",
54
- triggers: [triggers.notionPageCreated()],
54
+ triggers: [events.notionPageCreated()],
55
55
  handler(_event, context) {
56
56
  expectTypeOf<keyof typeof context.connections>().toEqualTypeOf<never>();
57
57
  },
@@ -59,7 +59,7 @@ it("exposes no providers for omitted or empty connections", () => {
59
59
  workflow({
60
60
  name: "No connections",
61
61
  description: "Empty",
62
- triggers: [triggers.notionPageCreated()],
62
+ triggers: [events.notionPageCreated()],
63
63
  connections: {},
64
64
  handler(_event, context) {
65
65
  expectTypeOf<keyof typeof context.connections>().toEqualTypeOf<never>();
@@ -72,7 +72,7 @@ it("preserves literal declarations checked with satisfies", () => {
72
72
  workflow({
73
73
  name: "Slack",
74
74
  description: "Slack only",
75
- triggers: [triggers.notionPageCreated()],
75
+ triggers: [events.notionPageCreated()],
76
76
  connections: requirements,
77
77
  handler(_event, context) {
78
78
  expectTypeOf<keyof typeof context.connections>().toEqualTypeOf<"support">();
@@ -9,19 +9,19 @@ it("checks provider keys on callback arguments and returned triggers", () => {
9
9
  valid: true,
10
10
  connections: "{ support: connections.slack(), calendar: connections.calendar() }",
11
11
  trigger:
12
- 'triggers.slackMessage({ connectionKey: "support" }), triggers.calendarEventCreated({ connectionKey: "calendar" })',
12
+ 'events.slackMessage({ connectionKey: "support" }), events.calendarEventCreated({ connectionKey: "calendar" })',
13
13
  },
14
14
  {
15
15
  name: "default",
16
16
  valid: true,
17
17
  connections: "{ slack: connections.slack() }",
18
- trigger: 'triggers.slackMessage({ connectionKey: "slack" })',
18
+ trigger: 'events.slackMessage({ connectionKey: "slack" })',
19
19
  },
20
20
  {
21
21
  name: "unbound",
22
22
  valid: true,
23
23
  connections: "{}",
24
- trigger: "triggers.slackMessage(), triggers.notionPageCreated()",
24
+ trigger: "events.slackMessage(), events.notionPageCreated()",
25
25
  },
26
26
  {
27
27
  name: "global_valid",
@@ -33,25 +33,25 @@ it("checks provider keys on callback arguments and returned triggers", () => {
33
33
  name: "undeclared",
34
34
  valid: false,
35
35
  connections: "{ support: connections.slack() }",
36
- trigger: 'triggers.slackMessage({ connectionKey: "typo" })',
36
+ trigger: 'events.slackMessage({ connectionKey: "typo" })',
37
37
  },
38
38
  {
39
39
  name: "wrong_provider",
40
40
  valid: false,
41
41
  connections: "{ support: connections.calendar() }",
42
- trigger: 'triggers.slackMessage({ connectionKey: "support" })',
42
+ trigger: 'events.slackMessage({ connectionKey: "support" })',
43
43
  },
44
44
  {
45
45
  name: "custom_not_default",
46
46
  valid: false,
47
47
  connections: "{ support: connections.slack() }",
48
- trigger: 'triggers.slackMessage({ connectionKey: "slack" })',
48
+ trigger: 'events.slackMessage({ connectionKey: "slack" })',
49
49
  },
50
50
  {
51
51
  name: "missing",
52
52
  valid: false,
53
53
  connections: undefined,
54
- trigger: 'triggers.slackMessage({ connectionKey: "slack" })',
54
+ trigger: 'events.slackMessage({ connectionKey: "slack" })',
55
55
  },
56
56
  {
57
57
  name: "global_invalid",
@@ -69,37 +69,37 @@ it("checks provider keys on callback arguments and returned triggers", () => {
69
69
  name: "old_key_option",
70
70
  valid: false,
71
71
  connections: '{ support: connections.slack({ key: "support" }) }',
72
- trigger: 'triggers.slackMessage({ connectionKey: "support" })',
72
+ trigger: 'events.slackMessage({ connectionKey: "support" })',
73
73
  },
74
74
  {
75
75
  name: "literal_default",
76
76
  valid: true,
77
77
  connections: '{ slack: { type: "slack" } }',
78
- trigger: 'triggers.slackMessage({ connectionKey: "slack" })',
78
+ trigger: 'events.slackMessage({ connectionKey: "slack" })',
79
79
  },
80
80
  {
81
81
  name: "saved",
82
82
  valid: true,
83
83
  connections: "{ support }",
84
- trigger: 'triggers.slackMessage({ connectionKey: "support" })',
84
+ trigger: 'events.slackMessage({ connectionKey: "support" })',
85
85
  },
86
86
  {
87
87
  name: "saved_invalid",
88
88
  valid: false,
89
89
  connections: "{ support }",
90
- trigger: 'triggers.slackMessage({ connectionKey: "slack" })',
90
+ trigger: 'events.slackMessage({ connectionKey: "slack" })',
91
91
  },
92
92
  {
93
93
  name: "old_array",
94
94
  valid: false,
95
95
  connections: "[connections.slack()]",
96
- trigger: "triggers.slackMessage()",
96
+ trigger: "events.slackMessage()",
97
97
  },
98
98
  {
99
99
  name: "two_slack",
100
100
  valid: true,
101
101
  connections: "{ support: connections.slack(), team: connections.slack() }",
102
- trigger: 'triggers.slackMessage({ connectionKey: "team" })',
102
+ trigger: 'events.slackMessage({ connectionKey: "team" })',
103
103
  },
104
104
 
105
105
  {
@@ -107,7 +107,7 @@ it("checks provider keys on callback arguments and returned triggers", () => {
107
107
  valid: true,
108
108
  connections:
109
109
  "{ support: connections.slack(), team: connections.slack(), work: connections.calendar() }",
110
- trigger: "triggers.notionPageCreated()",
110
+ trigger: "events.notionPageCreated()",
111
111
  handler:
112
112
  '(_event, ctx) => { ctx.connections.support.findUserByEmail({ email: "a@example.com" }); ctx.connections.team.findUserByEmail({ email: "b@example.com" }); ctx.connections.work.listCalendars({}); }',
113
113
  },
@@ -115,14 +115,14 @@ it("checks provider keys on callback arguments and returned triggers", () => {
115
115
  name: "wrong_client_method",
116
116
  valid: false,
117
117
  connections: "{ support: connections.slack() }",
118
- trigger: "triggers.notionPageCreated()",
118
+ trigger: "events.notionPageCreated()",
119
119
  handler: "(_event, ctx) => { ctx.connections.support.listCalendars({}); }",
120
120
  },
121
121
  {
122
122
  name: "undeclared_client",
123
123
  valid: false,
124
124
  connections: "{ support: connections.slack() }",
125
- trigger: "triggers.notionPageCreated()",
125
+ trigger: "events.notionPageCreated()",
126
126
  handler:
127
127
  '(_event, ctx) => { ctx.connections.slack.findUserByEmail({ email: "a@example.com" }); }',
128
128
  },
@@ -130,14 +130,14 @@ it("checks provider keys on callback arguments and returned triggers", () => {
130
130
  name: "old_provider_call",
131
131
  valid: false,
132
132
  connections: "{ support: connections.slack() }",
133
- trigger: "triggers.notionPageCreated()",
133
+ trigger: "events.notionPageCreated()",
134
134
  handler: '(_event, ctx) => { ctx.connections.support("support"); }',
135
135
  },
136
136
  {
137
137
  name: "oauth_keyed_client",
138
138
  valid: true,
139
139
  connections: "{ github: connections.oauth(oauthConfig), support: connections.slack() }",
140
- trigger: 'triggers.slackMessage({ connectionKey: "support" })',
140
+ trigger: 'events.slackMessage({ connectionKey: "support" })',
141
141
  handler:
142
142
  "async (_event, ctx) => { const token: string = await ctx.connections.github.accessToken(); void token; }",
143
143
  },
@@ -145,19 +145,19 @@ it("checks provider keys on callback arguments and returned triggers", () => {
145
145
  name: "oauth_wrong_trigger",
146
146
  valid: false,
147
147
  connections: "{ github: connections.oauth(oauthConfig) }",
148
- trigger: 'triggers.slackMessage({ connectionKey: "github" })',
148
+ trigger: 'events.slackMessage({ connectionKey: "github" })',
149
149
  },
150
150
  {
151
151
  name: "oauth_old_key_option",
152
152
  valid: false,
153
153
  connections: '{ github: connections.oauth({ ...oauthConfig, key: "github" }) }',
154
- trigger: "triggers.notionPageCreated()",
154
+ trigger: "events.notionPageCreated()",
155
155
  },
156
156
  {
157
157
  name: "oauth_old_provider_call",
158
158
  valid: false,
159
159
  connections: "{ github: connections.oauth(oauthConfig) }",
160
- trigger: "triggers.notionPageCreated()",
160
+ trigger: "events.notionPageCreated()",
161
161
  handler: '(_event, ctx) => { ctx.connections.oauth("github"); }',
162
162
  },
163
163
  ];
@@ -165,13 +165,13 @@ it("checks provider keys on callback arguments and returned triggers", () => {
165
165
  cases.map((testCase) => [
166
166
  resolve("src", `__workflow_types_${testCase.name}.ts`),
167
167
  `import { connections, workflow } from "./workflow.js";
168
- import { triggers as globalTriggers } from "./triggers.generated.js";
168
+ import { events as globalTriggers } from "./events.generated.js";
169
169
  const support = connections.slack();
170
170
  const oauthConfig = { authorizationEndpoint: "https://example.com/authorize", tokenEndpoint: "https://example.com/token", clientId: "client", clientSecretEnv: "CLIENT_SECRET", scope: "read" };
171
171
  workflow({
172
172
  name: "Type check", description: "Type check",
173
173
  ${testCase.connections === undefined ? "" : `connections: ${testCase.connections},`}
174
- triggers: ({ triggers }) => [${testCase.trigger}],
174
+ triggers: ({ events }) => [${testCase.trigger}],
175
175
  handler: ${testCase.handler ?? "() => {}"},
176
176
  });`,
177
177
  ]),