@notionhq/apps 0.0.45 → 0.0.46

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/README.md CHANGED
@@ -101,7 +101,7 @@ export default workflow({
101
101
  description: "Schedules a follow-up after a page is created",
102
102
  triggers: [events.notionPageCreated()],
103
103
  connections: {
104
- calendar: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
104
+ calendar: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
105
105
  },
106
106
  handler: async () => {},
107
107
  });
@@ -7,7 +7,7 @@ export type WorkflowConnection<TProvider extends string = string> = {
7
7
  calendar?: CalendarConnectionOptions;
8
8
  };
9
9
  export type CalendarConnectionOptions = {
10
- scope: "read" | "read_write";
10
+ permissions: "read" | "read_write";
11
11
  readTeammatesCalendars: boolean;
12
12
  };
13
13
  export type WorkflowConnectionDeclarations = Readonly<Record<string, WorkflowConnection>>;
@@ -1 +1 @@
1
- {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../src/connections.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIjF,OAAO,EAGN,KAAK,iBAAiB,EACtB,MAAM,0BAA0B,CAAC;AAGlC,6EAA6E;AAC7E,MAAM,MAAM,kBAAkB,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,IAAI;IACnE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,yBAAyB,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAE1F,uEAAuE;AACvE,MAAM,MAAM,6BAA6B,GAAG,kBAAkB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF,yDAAyD;AACzD,MAAM,MAAM,sBAAsB,CACjC,YAAY,SAAS,8BAA8B,EACnD,SAAS,SAAS,MAAM,IACrB,OAAO,CACV;KACE,IAAI,IAAI,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;CACzF,CAAC,MAAM,YAAY,CAAC,EACrB,MAAM,CACN,CAAC;AAIF,2EAA2E;AAC3E,eAAO,MAAM,WAAW;mBAER,kBAAkB,GAAG,kBAAkB,CAAC,OAAO,CAAC;;;;;;;;;;;CAI/D,CAAC;AACF,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG;IAAE,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAEjE,KAAK,yBAAyB,GAAG,iBAAiB,GAAG;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;AAIhF,MAAM,MAAM,mBAAmB,CAC9B,YAAY,SAAS,8BAA8B,GAAG,8BAA8B,IACjF;IACH,QAAQ,EAAE,IAAI,IAAI,MAAM,YAAY,GAAG,yBAAyB,CAAC,OAAO,CACvE,MAAM,yBAAyB,EAC/B,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAC1B,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../src/connections.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIjF,OAAO,EAGN,KAAK,iBAAiB,EACtB,MAAM,0BAA0B,CAAC;AAGlC,6EAA6E;AAC7E,MAAM,MAAM,kBAAkB,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,IAAI;IACnE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,yBAAyB,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,WAAW,EAAE,MAAM,GAAG,YAAY,CAAC;IACnC,sBAAsB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAE1F,uEAAuE;AACvE,MAAM,MAAM,6BAA6B,GAAG,kBAAkB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF,yDAAyD;AACzD,MAAM,MAAM,sBAAsB,CACjC,YAAY,SAAS,8BAA8B,EACnD,SAAS,SAAS,MAAM,IACrB,OAAO,CACV;KACE,IAAI,IAAI,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;CACzF,CAAC,MAAM,YAAY,CAAC,EACrB,MAAM,CACN,CAAC;AAIF,2EAA2E;AAC3E,eAAO,MAAM,WAAW;mBAER,kBAAkB,GAAG,kBAAkB,CAAC,OAAO,CAAC;;;;;;;;;;;CAI/D,CAAC;AACF,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG;IAAE,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAEjE,KAAK,yBAAyB,GAAG,iBAAiB,GAAG;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;AAIhF,MAAM,MAAM,mBAAmB,CAC9B,YAAY,SAAS,8BAA8B,GAAG,8BAA8B,IACjF;IACH,QAAQ,EAAE,IAAI,IAAI,MAAM,YAAY,GAAG,yBAAyB,CAAC,OAAO,CACvE,MAAM,yBAAyB,EAC/B,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAC1B,CAAC;CACF,CAAC"}
@@ -37,8 +37,10 @@ function normalizeConnectionRequirements(declarations) {
37
37
  );
38
38
  if (requirement.type === "calendar") {
39
39
  const options = requirement.calendar;
40
- if (!options || !["read", "read_write"].includes(options.scope) || typeof options.readTeammatesCalendars !== "boolean") {
41
- throw new Error("Calendar connections require scope and readTeammatesCalendars.");
40
+ if (!options || !["read", "read_write"].includes(options.permissions) || typeof options.readTeammatesCalendars !== "boolean") {
41
+ throw new Error(
42
+ "Calendar connections require permissions and readTeammatesCalendars."
43
+ );
42
44
  }
43
45
  } else if (requirement.calendar !== void 0) {
44
46
  throw new Error("Calendar options are only valid on Calendar connections.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/apps",
3
- "version": "0.0.45",
3
+ "version": "0.0.46",
4
4
  "description": "An SDK for building workflow apps for Notion",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -15,31 +15,35 @@ afterEach(() => {
15
15
  describe("connection requirements", () => {
16
16
  it("rejects Calendar declarations that omit explicit access", () => {
17
17
  expect(() => normalizeConnectionRequirements({ work: { type: "calendar" } })).toThrow(
18
- "scope and readTeammatesCalendars",
18
+ "permissions and readTeammatesCalendars",
19
19
  );
20
20
  });
21
21
  it.each([
22
- { scope: "read" },
22
+ { scope: "read", readTeammatesCalendars: false },
23
+ { permissions: "read" },
23
24
  { readTeammatesCalendars: false },
24
- { scope: "write", readTeammatesCalendars: false },
25
- { scope: "read", readTeammatesCalendars: "false" },
25
+ { permissions: "write", readTeammatesCalendars: false },
26
+ { permissions: "read", readTeammatesCalendars: "false" },
26
27
  ])("rejects invalid Calendar options: %j", (calendar) => {
27
28
  expect(() =>
28
29
  Reflect.apply(normalizeConnectionRequirements, undefined, [
29
30
  { work: { type: "calendar", calendar } },
30
31
  ]),
31
- ).toThrow("scope and readTeammatesCalendars");
32
+ ).toThrow("permissions and readTeammatesCalendars");
32
33
  });
33
34
  it("rejects Calendar options on other providers", () => {
34
35
  expect(() =>
35
36
  normalizeConnectionRequirements({
36
- work: { type: "mail", calendar: { scope: "read", readTeammatesCalendars: false } },
37
+ work: {
38
+ type: "mail",
39
+ calendar: { permissions: "read", readTeammatesCalendars: false },
40
+ },
37
41
  }),
38
42
  ).toThrow("only valid on Calendar");
39
43
  });
40
44
  it("preserves explicit write and teammate choices in the manifest", () => {
41
45
  const connection = connections.calendar({
42
- scope: "read_write",
46
+ permissions: "read_write",
43
47
  readTeammatesCalendars: true,
44
48
  });
45
49
  const normalized = normalizeConnectionRequirements({ work: connection });
@@ -49,14 +53,14 @@ describe("connection requirements", () => {
49
53
  {
50
54
  type: "calendar",
51
55
  key: "work",
52
- calendar: { scope: "read_write", readTeammatesCalendars: true },
56
+ calendar: { permissions: "read_write", readTeammatesCalendars: true },
53
57
  },
54
58
  ]);
55
59
  });
56
60
  it("normalizes object keys into manifest requirements", () => {
57
61
  expect(
58
62
  normalizeConnectionRequirements({
59
- work: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
63
+ work: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
60
64
  support: connections.slack(),
61
65
  team: connections.slack(),
62
66
  }),
@@ -64,7 +68,7 @@ describe("connection requirements", () => {
64
68
  {
65
69
  type: "calendar",
66
70
  key: "work",
67
- calendar: { scope: "read", readTeammatesCalendars: false },
71
+ calendar: { permissions: "read", readTeammatesCalendars: false },
68
72
  },
69
73
  { type: "slack", key: "support" },
70
74
  { type: "slack", key: "team" },
@@ -89,12 +93,12 @@ describe("connection requirements", () => {
89
93
  ).toThrow("must be an object");
90
94
  const inherited = { support: connections.slack() };
91
95
  Object.setPrototypeOf(inherited, {
92
- hidden: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
96
+ hidden: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
93
97
  });
94
98
  expect(() => normalizeConnectionRequirements(inherited)).toThrow("only own");
95
99
  const hidden = { support: connections.slack() };
96
100
  Object.defineProperty(hidden, "hidden", {
97
- value: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
101
+ value: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
98
102
  });
99
103
  expect(() => normalizeConnectionRequirements(hidden)).toThrow("enumerable strings");
100
104
  const symbolic = { [Symbol("support")]: connections.slack() };
@@ -168,7 +172,7 @@ describe("workflow connection runtime", () => {
168
172
  const declarations = { support: connections.slack(), team: connections.slack() };
169
173
  const runtime = createWorkflowConnections(notion, declarations);
170
174
  Object.assign(declarations, {
171
- support: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
175
+ support: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
172
176
  injected: connections.slack(),
173
177
  });
174
178
  await runtime.support.findUserByEmail({ email: "support@example.com" });
@@ -357,7 +361,7 @@ describe("workflow connection runtime", () => {
357
361
  const notion = new Client({ auth: "test" });
358
362
  const request = vi.spyOn(notion, "request").mockResolvedValue({ result: { accounts: [] } });
359
363
  const result = await createWorkflowConnections(notion, {
360
- calendar: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
364
+ calendar: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
361
365
  }).calendar.listCalendars({});
362
366
  expect(result.accounts).toEqual([]);
363
367
  expect(request).toHaveBeenCalledWith({
@@ -17,7 +17,7 @@ export type WorkflowConnection<TProvider extends string = string> = {
17
17
  };
18
18
 
19
19
  export type CalendarConnectionOptions = {
20
- scope: "read" | "read_write";
20
+ permissions: "read" | "read_write";
21
21
  readTeammatesCalendars: boolean;
22
22
  };
23
23
 
@@ -104,10 +104,12 @@ export function normalizeConnectionRequirements(
104
104
  const options = requirement.calendar;
105
105
  if (
106
106
  !options ||
107
- !["read", "read_write"].includes(options.scope) ||
107
+ !["read", "read_write"].includes(options.permissions) ||
108
108
  typeof options.readTeammatesCalendars !== "boolean"
109
109
  ) {
110
- throw new Error("Calendar connections require scope and readTeammatesCalendars.");
110
+ throw new Error(
111
+ "Calendar connections require permissions and readTeammatesCalendars.",
112
+ );
111
113
  }
112
114
  } else if (requirement.calendar !== undefined) {
113
115
  throw new Error("Calendar options are only valid on Calendar connections.");
@@ -21,7 +21,7 @@ it("infers only the declared provider clients", () => {
21
21
  description: "Calendar only",
22
22
  triggers: [events.notionPageCreated()],
23
23
  connections: {
24
- work: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
24
+ work: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
25
25
  },
26
26
  handler(_event, context) {
27
27
  expectTypeOf<keyof typeof context.connections>().toEqualTypeOf<"work">();
@@ -32,7 +32,7 @@ it("infers only the declared provider clients", () => {
32
32
  },
33
33
  });
34
34
  const requirements = {
35
- calendar: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
35
+ calendar: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
36
36
  support: connections.slack(),
37
37
  team: connections.slack(),
38
38
  };
@@ -72,7 +72,7 @@ it("checks provider keys on callback arguments and returned triggers", () => {
72
72
  name: "valid",
73
73
  valid: true,
74
74
  connections:
75
- "{ support: connections.slack(), calendar: connections.calendar({ scope: 'read', readTeammatesCalendars: false }) }",
75
+ "{ support: connections.slack(), calendar: connections.calendar({ permissions: 'read', readTeammatesCalendars: false }) }",
76
76
  trigger:
77
77
  'events.slackMessage({ connectionKey: "support" }), events.calendarEventCreated({ connectionKey: "calendar" })',
78
78
  },
@@ -104,7 +104,7 @@ it("checks provider keys on callback arguments and returned triggers", () => {
104
104
  name: "wrong_provider",
105
105
  valid: false,
106
106
  connections:
107
- "{ support: connections.calendar({ scope: 'read', readTeammatesCalendars: false }) }",
107
+ "{ support: connections.calendar({ permissions: 'read', readTeammatesCalendars: false }) }",
108
108
  trigger: 'events.slackMessage({ connectionKey: "support" })',
109
109
  },
110
110
  {
@@ -123,14 +123,14 @@ it("checks provider keys on callback arguments and returned triggers", () => {
123
123
  name: "global_invalid",
124
124
  valid: false,
125
125
  connections:
126
- "{ support: connections.calendar({ scope: 'read', readTeammatesCalendars: false }) }",
126
+ "{ support: connections.calendar({ permissions: 'read', readTeammatesCalendars: false }) }",
127
127
  trigger: 'globalTriggers.slackMessage({ connectionKey: "support" })',
128
128
  },
129
129
  {
130
130
  name: "literal_invalid",
131
131
  valid: false,
132
132
  connections:
133
- "{ support: connections.calendar({ scope: 'read', readTeammatesCalendars: false }) }",
133
+ "{ support: connections.calendar({ permissions: 'read', readTeammatesCalendars: false }) }",
134
134
  trigger: '{ type: "slack.message", connectionKey: "support" }',
135
135
  },
136
136
  {
@@ -174,7 +174,7 @@ it("checks provider keys on callback arguments and returned triggers", () => {
174
174
  name: "keyed_clients",
175
175
  valid: true,
176
176
  connections:
177
- "{ support: connections.slack(), team: connections.slack(), work: connections.calendar({ scope: 'read', readTeammatesCalendars: false }) }",
177
+ "{ support: connections.slack(), team: connections.slack(), work: connections.calendar({ permissions: 'read', readTeammatesCalendars: false }) }",
178
178
  trigger: "events.notionPageCreated()",
179
179
  handler:
180
180
  '(_event, ctx) => { ctx.connections.support.findUserByEmail({ email: "a@example.com" }); ctx.connections.team.findUserByEmail({ email: "b@example.com" }); ctx.connections.work.listCalendars({}); }',
@@ -1703,7 +1703,10 @@ describe("workflow", () => {
1703
1703
  description: "Schedules a follow-up after a page is created",
1704
1704
  triggers: [events.notionPageCreated()],
1705
1705
  connections: {
1706
- calendar: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
1706
+ calendar: connections.calendar({
1707
+ permissions: "read",
1708
+ readTeammatesCalendars: false,
1709
+ }),
1707
1710
  },
1708
1711
  handler: () => {},
1709
1712
  });
@@ -1712,7 +1715,7 @@ describe("workflow", () => {
1712
1715
  {
1713
1716
  type: "calendar",
1714
1717
  key: "calendar",
1715
- calendar: { scope: "read", readTeammatesCalendars: false },
1718
+ calendar: { permissions: "read", readTeammatesCalendars: false },
1716
1719
  },
1717
1720
  ]);
1718
1721
  });
@@ -1730,7 +1733,7 @@ describe("workflow", () => {
1730
1733
  },
1731
1734
  });
1732
1735
  Object.assign(declarations, {
1733
- support: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
1736
+ support: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
1734
1737
  team: connections.slack(),
1735
1738
  });
1736
1739
  expect(definition.config.connections).toEqual([{ type: "slack", key: "support" }]);
@@ -1740,7 +1743,7 @@ describe("workflow", () => {
1740
1743
  it("rejects inherited declaration objects before cloning", () => {
1741
1744
  const declarations = { support: connections.slack() };
1742
1745
  Object.setPrototypeOf(declarations, {
1743
- extra: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
1746
+ extra: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
1744
1747
  });
1745
1748
  expect(() =>
1746
1749
  workflow({
@@ -1761,7 +1764,7 @@ describe("workflow", () => {
1761
1764
  triggers: [events.notionPageCreated()],
1762
1765
  connections: {
1763
1766
  "bad/key": connections.calendar({
1764
- scope: "read",
1767
+ permissions: "read",
1765
1768
  readTeammatesCalendars: false,
1766
1769
  }),
1767
1770
  },
@@ -2031,7 +2034,10 @@ describe("connection-bound triggers", () => {
2031
2034
  description: "Uses only declared provider keys",
2032
2035
  connections: {
2033
2036
  support: connections.slack(),
2034
- calendar: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
2037
+ calendar: connections.calendar({
2038
+ permissions: "read",
2039
+ readTeammatesCalendars: false,
2040
+ }),
2035
2041
  },
2036
2042
  triggers: ({ events }) => {
2037
2043
  calls += 1;
@@ -2083,7 +2089,10 @@ describe("connection-bound triggers", () => {
2083
2089
  { requirements: {} },
2084
2090
  {
2085
2091
  requirements: {
2086
- support: connections.calendar({ scope: "read", readTeammatesCalendars: false }),
2092
+ support: connections.calendar({
2093
+ permissions: "read",
2094
+ readTeammatesCalendars: false,
2095
+ }),
2087
2096
  },
2088
2097
  },
2089
2098
  { requirements: { other: connections.slack() } },