@notionhq/apps 0.0.7 → 0.0.9

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
@@ -1,5 +1,8 @@
1
1
  # Apps SDK
2
2
 
3
+ [![CI](https://github.com/makenotion/apps-sdk/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/makenotion/apps-sdk/actions/workflows/ci.yml?query=branch%3Amain)
4
+ [![Publish](https://github.com/makenotion/apps-sdk/actions/workflows/publish.yml/badge.svg?branch=main)](https://github.com/makenotion/apps-sdk/actions/workflows/publish.yml?query=branch%3Amain)
5
+
3
6
  ## Development
4
7
 
5
8
  1. Install [mise](https://mise.jdx.dev/getting-started.html)
@@ -11,9 +14,23 @@ The SDK requires Node 26 or newer. It supports workflows and database syncs.
11
14
 
12
15
  ```ts
13
16
  import { triggers } from "@notionhq/apps/triggers";
14
- import { createWorkflow } from "@notionhq/apps/workflow";
17
+ import { connections, createWorkflow } from "@notionhq/apps/workflow";
15
18
  ```
16
19
 
20
+ Add a connection requirement to a workflow when it needs Calendar:
21
+
22
+ ```ts
23
+ export default createWorkflow({
24
+ name: "Schedule follow-up",
25
+ description: "Schedules a follow-up after a page is created",
26
+ triggers: [triggers.notionPageCreated()],
27
+ connections: [connections.calendar()],
28
+ handler: async () => {},
29
+ });
30
+ ```
31
+
32
+ Declaring the same connection more than once causes the app build to fail.
33
+
17
34
  ## Notion API access
18
35
 
19
36
  Use `context.notion` for Notion API calls. Deployed apps receive Notion API
@@ -8,6 +8,15 @@ type HandlerOptions = {
8
8
  export type WorkflowEvent = WorkflowEventMap[keyof WorkflowEventMap];
9
9
  export type WorkflowEventForTrigger<T extends WorkflowTrigger> = WorkflowEventMap[T["type"]];
10
10
  export type WorkflowEventForTriggers<T extends readonly WorkflowTrigger[]> = WorkflowEventForTrigger<T[number]>;
11
+ /** A connection that a workflow needs before it can run. */
12
+ export type WorkflowConnection = {
13
+ type: "calendar";
14
+ };
15
+ /** Connection requirements supported by workflow capabilities. */
16
+ export declare const connections: {
17
+ /** Require an authorized Calendar connection. */
18
+ calendar(): WorkflowConnection;
19
+ };
11
20
  /**
12
21
  * Configuration passed to {@link createWorkflow}.
13
22
  */
@@ -26,6 +35,10 @@ export type WorkflowConfiguration<TTriggers extends readonly [WorkflowTrigger, .
26
35
  * Each trigger defines a specific event or condition that causes the workflow to run.
27
36
  */
28
37
  triggers: TTriggers;
38
+ /**
39
+ * Connections that must be set up before this workflow can run.
40
+ */
41
+ connections?: readonly WorkflowConnection[];
29
42
  handler: (event: WorkflowEventForTriggers<TTriggers>, context: WorkflowContext) => Promise<void> | void;
30
43
  };
31
44
  /**
@@ -43,6 +56,7 @@ export type Workflow<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTri
43
56
  name: string;
44
57
  description: string;
45
58
  triggers: TTriggers;
59
+ connections?: readonly WorkflowConnection[];
46
60
  };
47
61
  handler: (event: WorkflowEventForTriggers<TTriggers>, options?: HandlerOptions) => Promise<{
48
62
  status: "success";
@@ -1 +1 @@
1
- {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
package/dist/workflow.js CHANGED
@@ -6,13 +6,29 @@ import { ExecutionError } from "./error.js";
6
6
  import { writeOutput } from "./output.js";
7
7
  import { resolveRuntimeInput } from "./runtime-input.js";
8
8
  import { readRunMetadata } from "./runtime-metadata.js";
9
+ const connections = {
10
+ /** Require an authorized Calendar connection. */
11
+ calendar() {
12
+ return { type: "calendar" };
13
+ }
14
+ };
9
15
  function createWorkflow(configuration) {
16
+ if (configuration.connections !== void 0) {
17
+ const connectionTypes = /* @__PURE__ */ new Set();
18
+ for (const connection of configuration.connections) {
19
+ if (connectionTypes.has(connection.type)) {
20
+ throw new Error(`Duplicate workflow connection: ${connection.type}`);
21
+ }
22
+ connectionTypes.add(connection.type);
23
+ }
24
+ }
10
25
  return {
11
26
  _tag: "workflow",
12
27
  config: {
13
28
  name: configuration.name,
14
29
  description: configuration.description,
15
- triggers: configuration.triggers
30
+ triggers: configuration.triggers,
31
+ ...configuration.connections === void 0 ? {} : { connections: configuration.connections }
16
32
  },
17
33
  async handler(event, options) {
18
34
  try {
@@ -208,5 +224,6 @@ function isNodeError(error) {
208
224
  return error instanceof Error && "code" in error;
209
225
  }
210
226
  export {
227
+ connections,
211
228
  createWorkflow
212
229
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/apps",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "An SDK for building workflow apps for Notion",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -8,7 +8,7 @@ import { afterEach, beforeEach, describe, expect, expectTypeOf, it, vi, type Moc
8
8
  import { ExecutionError } from "./error.js";
9
9
  import type { RunMetadata } from "./runtime-metadata.js";
10
10
  import { triggers, type NotionPageCreatedEvent } from "./triggers.generated.js";
11
- import { createWorkflow, type StepContext, type WorkflowContext } from "./workflow.js";
11
+ import { connections, createWorkflow, type StepContext, type WorkflowContext } from "./workflow.js";
12
12
 
13
13
  let stdoutSpy: Mock<typeof process.stdout.write>;
14
14
  let checkpointDirectory: string | undefined;
@@ -738,6 +738,30 @@ describe("createWorkflow", () => {
738
738
  });
739
739
  });
740
740
 
741
+ it("declares a Calendar connection requirement", () => {
742
+ const workflow = createWorkflow({
743
+ name: "Schedule Follow-up",
744
+ description: "Schedules a follow-up after a page is created",
745
+ triggers: [triggers.notionPageCreated()],
746
+ connections: [connections.calendar()],
747
+ handler: () => {},
748
+ });
749
+
750
+ expect(workflow.config.connections).toEqual([{ type: "calendar" }]);
751
+ });
752
+
753
+ it("rejects duplicate connection requirements", () => {
754
+ expect(() =>
755
+ createWorkflow({
756
+ name: "Schedule Follow-up",
757
+ description: "Schedules a follow-up after a page is created",
758
+ triggers: [triggers.notionPageCreated()],
759
+ connections: [connections.calendar(), connections.calendar()],
760
+ handler: () => {},
761
+ }),
762
+ ).toThrowError("Duplicate workflow connection: calendar");
763
+ });
764
+
741
765
  it("writes a success envelope after the handler runs", async () => {
742
766
  const handler = vi.fn();
743
767
  const workflow = createWorkflow({
package/src/workflow.ts CHANGED
@@ -22,6 +22,19 @@ export type WorkflowEventForTrigger<T extends WorkflowTrigger> = WorkflowEventMa
22
22
  export type WorkflowEventForTriggers<T extends readonly WorkflowTrigger[]> =
23
23
  WorkflowEventForTrigger<T[number]>;
24
24
 
25
+ /** A connection that a workflow needs before it can run. */
26
+ export type WorkflowConnection = {
27
+ type: "calendar";
28
+ };
29
+
30
+ /** Connection requirements supported by workflow capabilities. */
31
+ export const connections = {
32
+ /** Require an authorized Calendar connection. */
33
+ calendar(): WorkflowConnection {
34
+ return { type: "calendar" };
35
+ },
36
+ };
37
+
25
38
  /**
26
39
  * Configuration passed to {@link createWorkflow}.
27
40
  */
@@ -45,6 +58,11 @@ export type WorkflowConfiguration<
45
58
  */
46
59
  triggers: TTriggers;
47
60
 
61
+ /**
62
+ * Connections that must be set up before this workflow can run.
63
+ */
64
+ connections?: readonly WorkflowConnection[];
65
+
48
66
  handler: (
49
67
  event: WorkflowEventForTriggers<TTriggers>,
50
68
  context: WorkflowContext,
@@ -68,6 +86,7 @@ export type Workflow<
68
86
  name: string;
69
87
  description: string;
70
88
  triggers: TTriggers;
89
+ connections?: readonly WorkflowConnection[];
71
90
  };
72
91
  handler: (
73
92
  event: WorkflowEventForTriggers<TTriggers>,
@@ -104,12 +123,25 @@ export type Workflow<
104
123
  export function createWorkflow<
105
124
  const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]],
106
125
  >(configuration: WorkflowConfiguration<TTriggers>): Workflow<TTriggers> {
126
+ if (configuration.connections !== undefined) {
127
+ const connectionTypes = new Set<string>();
128
+ for (const connection of configuration.connections) {
129
+ if (connectionTypes.has(connection.type)) {
130
+ throw new Error(`Duplicate workflow connection: ${connection.type}`);
131
+ }
132
+ connectionTypes.add(connection.type);
133
+ }
134
+ }
135
+
107
136
  return {
108
137
  _tag: "workflow",
109
138
  config: {
110
139
  name: configuration.name,
111
140
  description: configuration.description,
112
141
  triggers: configuration.triggers,
142
+ ...(configuration.connections === undefined
143
+ ? {}
144
+ : { connections: configuration.connections }),
113
145
  },
114
146
  async handler(
115
147
  event: WorkflowEventForTriggers<TTriggers>,