@notionhq/workers 0.5.0 → 0.7.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 (182) hide show
  1. package/dist/alpha/ajv-formats.d.js +0 -0
  2. package/dist/alpha/builder.d.ts +149 -0
  3. package/dist/alpha/builder.d.ts.map +1 -0
  4. package/dist/alpha/builder.js +260 -0
  5. package/dist/alpha/builder.test.d.ts +2 -0
  6. package/dist/alpha/builder.test.d.ts.map +1 -0
  7. package/dist/alpha/cli/build.d.ts +13 -0
  8. package/dist/alpha/cli/build.d.ts.map +1 -0
  9. package/dist/alpha/cli/build.js +36 -0
  10. package/dist/alpha/cli/build.test.d.ts +2 -0
  11. package/dist/alpha/cli/build.test.d.ts.map +1 -0
  12. package/dist/alpha/cli/codegen.d.ts +10 -0
  13. package/dist/alpha/cli/codegen.d.ts.map +1 -0
  14. package/dist/alpha/cli/codegen.js +41 -0
  15. package/dist/alpha/cli/codegen.test.d.ts +2 -0
  16. package/dist/alpha/cli/codegen.test.d.ts.map +1 -0
  17. package/dist/alpha/cli/discover.d.ts +35 -0
  18. package/dist/alpha/cli/discover.d.ts.map +1 -0
  19. package/dist/alpha/cli/discover.js +39 -0
  20. package/dist/alpha/cli/discover.test.d.ts +2 -0
  21. package/dist/alpha/cli/discover.test.d.ts.map +1 -0
  22. package/dist/alpha/cli/emit-manifest.d.ts +33 -0
  23. package/dist/alpha/cli/emit-manifest.d.ts.map +1 -0
  24. package/dist/alpha/cli/emit-manifest.js +266 -0
  25. package/dist/alpha/cli/emit-manifest.test.d.ts +2 -0
  26. package/dist/alpha/cli/emit-manifest.test.d.ts.map +1 -0
  27. package/dist/alpha/cli/index.d.ts +3 -0
  28. package/dist/alpha/cli/index.d.ts.map +1 -0
  29. package/dist/alpha/cli/index.js +36 -0
  30. package/dist/alpha/context.d.ts +8 -0
  31. package/dist/alpha/context.d.ts.map +1 -0
  32. package/dist/alpha/context.js +33 -0
  33. package/dist/alpha/database.d.ts +90 -0
  34. package/dist/alpha/database.d.ts.map +1 -0
  35. package/dist/alpha/database.js +9 -0
  36. package/dist/alpha/error.d.ts +41 -0
  37. package/dist/alpha/error.d.ts.map +1 -0
  38. package/dist/alpha/error.js +25 -0
  39. package/dist/alpha/icon-names.d.ts +6 -0
  40. package/dist/alpha/icon-names.d.ts.map +1 -0
  41. package/dist/alpha/icon-names.js +0 -0
  42. package/dist/alpha/json-schema.d.ts +117 -0
  43. package/dist/alpha/json-schema.d.ts.map +1 -0
  44. package/dist/alpha/json-schema.js +0 -0
  45. package/dist/alpha/manifest.d.ts +44 -0
  46. package/dist/alpha/manifest.d.ts.map +1 -0
  47. package/dist/alpha/manifest.js +0 -0
  48. package/dist/alpha/output.d.ts +7 -0
  49. package/dist/alpha/output.d.ts.map +1 -0
  50. package/dist/alpha/output.js +8 -0
  51. package/dist/alpha/pacer.d.ts +74 -0
  52. package/dist/alpha/pacer.d.ts.map +1 -0
  53. package/dist/alpha/pacer.js +66 -0
  54. package/dist/alpha/pacer.test.d.ts +2 -0
  55. package/dist/alpha/pacer.test.d.ts.map +1 -0
  56. package/dist/alpha/schedule.d.ts +6 -0
  57. package/dist/alpha/schedule.d.ts.map +1 -0
  58. package/dist/alpha/schedule.js +43 -0
  59. package/dist/alpha/schedule.test.d.ts +2 -0
  60. package/dist/alpha/schedule.test.d.ts.map +1 -0
  61. package/dist/alpha/schema-builder.d.ts +79 -0
  62. package/dist/alpha/schema-builder.d.ts.map +1 -0
  63. package/dist/alpha/schema-builder.js +135 -0
  64. package/dist/alpha/schema.d.ts +185 -0
  65. package/dist/alpha/schema.d.ts.map +1 -0
  66. package/dist/alpha/schema.js +115 -0
  67. package/dist/alpha/sync.d.ts +233 -0
  68. package/dist/alpha/sync.d.ts.map +1 -0
  69. package/dist/alpha/sync.js +70 -0
  70. package/dist/alpha/sync.test.d.ts +2 -0
  71. package/dist/alpha/sync.test.d.ts.map +1 -0
  72. package/dist/alpha/tool.d.ts +132 -0
  73. package/dist/alpha/tool.d.ts.map +1 -0
  74. package/dist/alpha/tool.js +156 -0
  75. package/dist/alpha/tool.test.d.ts +2 -0
  76. package/dist/alpha/tool.test.d.ts.map +1 -0
  77. package/dist/alpha/triggers.d.ts +365 -0
  78. package/dist/alpha/triggers.d.ts.map +1 -0
  79. package/dist/alpha/triggers.generated.d.ts +246 -0
  80. package/dist/alpha/triggers.generated.d.ts.map +1 -0
  81. package/dist/alpha/triggers.generated.js +239 -0
  82. package/dist/alpha/triggers.js +0 -0
  83. package/dist/alpha/types.d.ts +228 -0
  84. package/dist/alpha/types.d.ts.map +1 -0
  85. package/dist/alpha/types.js +0 -0
  86. package/dist/alpha/workflow.d.ts +70 -0
  87. package/dist/alpha/workflow.d.ts.map +1 -0
  88. package/dist/alpha/workflow.js +39 -0
  89. package/dist/alpha/workflow.test.d.ts +2 -0
  90. package/dist/alpha/workflow.test.d.ts.map +1 -0
  91. package/dist/block.d.ts.map +1 -1
  92. package/dist/builder.d.ts.map +1 -1
  93. package/dist/builder.js +2 -6
  94. package/dist/capabilities/ai_connector.d.ts.map +1 -1
  95. package/dist/capabilities/automation.d.ts.map +1 -1
  96. package/dist/capabilities/context.d.ts.map +1 -1
  97. package/dist/capabilities/oauth.d.ts.map +1 -1
  98. package/dist/capabilities/output.d.ts.map +1 -1
  99. package/dist/capabilities/output.js +2 -4
  100. package/dist/capabilities/stateful-capability.d.ts.map +1 -1
  101. package/dist/capabilities/stateful-capability.js +2 -6
  102. package/dist/capabilities/sync.d.ts.map +1 -1
  103. package/dist/capabilities/sync.js +2 -8
  104. package/dist/capabilities/tool.d.ts.map +1 -1
  105. package/dist/capabilities/tool.js +6 -20
  106. package/dist/capabilities/webhook.d.ts.map +1 -1
  107. package/dist/capabilities/workflow.d.ts +2 -2
  108. package/dist/capabilities/workflow.d.ts.map +1 -1
  109. package/dist/index.d.ts +2 -2
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +1 -7
  112. package/dist/json-schema.d.ts.map +1 -1
  113. package/dist/schema-builder.d.ts.map +1 -1
  114. package/dist/schema.d.ts.map +1 -1
  115. package/dist/types.d.ts.map +1 -1
  116. package/dist/worker.d.ts.map +1 -1
  117. package/dist/worker.js +1 -4
  118. package/package.json +74 -14
  119. package/src/alpha/ajv-formats.d.ts +7 -0
  120. package/src/alpha/builder.test.ts +197 -0
  121. package/src/alpha/builder.ts +338 -0
  122. package/src/alpha/cli/build.test.ts +240 -0
  123. package/src/alpha/cli/build.ts +57 -0
  124. package/src/alpha/cli/codegen.test.ts +31 -0
  125. package/src/alpha/cli/codegen.ts +51 -0
  126. package/src/alpha/cli/discover.test.ts +43 -0
  127. package/src/alpha/cli/discover.ts +81 -0
  128. package/src/alpha/cli/emit-manifest.test.ts +45 -0
  129. package/src/alpha/cli/emit-manifest.ts +409 -0
  130. package/src/alpha/cli/index.ts +41 -0
  131. package/src/alpha/context.ts +61 -0
  132. package/src/alpha/database.ts +102 -0
  133. package/src/alpha/error.ts +49 -0
  134. package/src/alpha/icon-names.ts +890 -0
  135. package/src/alpha/json-schema.ts +180 -0
  136. package/src/alpha/manifest.ts +47 -0
  137. package/src/alpha/output.ts +8 -0
  138. package/src/alpha/pacer.test.ts +81 -0
  139. package/src/alpha/pacer.ts +181 -0
  140. package/src/alpha/schedule.test.ts +31 -0
  141. package/src/alpha/schedule.ts +53 -0
  142. package/src/alpha/schema-builder.ts +193 -0
  143. package/src/alpha/schema.ts +222 -0
  144. package/src/alpha/sync.test.ts +191 -0
  145. package/src/alpha/sync.ts +340 -0
  146. package/src/alpha/tool.test.ts +116 -0
  147. package/src/alpha/tool.ts +319 -0
  148. package/src/alpha/triggers.generated.ts +489 -0
  149. package/src/alpha/triggers.ts +500 -0
  150. package/src/alpha/types.ts +284 -0
  151. package/src/alpha/workflow.test.ts +84 -0
  152. package/src/alpha/workflow.ts +131 -0
  153. package/src/block.ts +1 -5
  154. package/src/builder.test.ts +28 -60
  155. package/src/builder.ts +3 -10
  156. package/src/capabilities/ai_connector.test.ts +9 -32
  157. package/src/capabilities/ai_connector.ts +5 -17
  158. package/src/capabilities/automation.test.ts +3 -12
  159. package/src/capabilities/automation.ts +3 -11
  160. package/src/capabilities/context.ts +3 -6
  161. package/src/capabilities/oauth.test.ts +1 -0
  162. package/src/capabilities/oauth.ts +1 -3
  163. package/src/capabilities/output.ts +1 -3
  164. package/src/capabilities/stateful-capability.test.ts +1 -0
  165. package/src/capabilities/stateful-capability.ts +2 -6
  166. package/src/capabilities/sync.test.ts +15 -45
  167. package/src/capabilities/sync.ts +10 -40
  168. package/src/capabilities/tool.test.ts +106 -146
  169. package/src/capabilities/tool.ts +17 -39
  170. package/src/capabilities/webhook.ts +3 -10
  171. package/src/capabilities/workflow.test.ts +10 -31
  172. package/src/capabilities/workflow.ts +5 -12
  173. package/src/index.ts +2 -12
  174. package/src/json-schema.test.ts +2 -4
  175. package/src/json-schema.ts +7 -6
  176. package/src/pacer.test.ts +1 -3
  177. package/src/pacer_internal.ts +1 -5
  178. package/src/schema-builder.test.ts +10 -35
  179. package/src/schema-builder.ts +5 -16
  180. package/src/schema.ts +2 -10
  181. package/src/types.ts +1 -7
  182. package/src/worker.ts +8 -34
@@ -1,12 +1,5 @@
1
- import {
2
- afterEach,
3
- beforeEach,
4
- describe,
5
- expect,
6
- it,
7
- type Mock,
8
- vi,
9
- } from "vitest";
1
+ import { afterEach, beforeEach, describe, expect, it, type Mock, vi } from "vitest";
2
+
10
3
  import { j } from "../schema-builder.js";
11
4
  import { createToolCapability } from "./tool.js";
12
5
 
@@ -14,9 +7,7 @@ describe("Worker.tool", () => {
14
7
  let stdoutSpy: Mock<typeof process.stdout.write>;
15
8
 
16
9
  beforeEach(() => {
17
- stdoutSpy = vi
18
- .spyOn(process.stdout, "write")
19
- .mockImplementation(() => true);
10
+ stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
20
11
  });
21
12
 
22
13
  afterEach(() => {
@@ -24,17 +15,14 @@ describe("Worker.tool", () => {
24
15
  });
25
16
 
26
17
  it("sync execution", async () => {
27
- const capability = createToolCapability<{ name: string }, string>(
28
- "sayHello",
29
- {
30
- title: "Say Hello",
31
- description: "Greet a user",
32
- schema: j.object({ name: j.string() }),
33
- execute: (input: { name: string }) => {
34
- return `Hello, ${input.name}!`;
35
- },
18
+ const capability = createToolCapability<{ name: string }, string>("sayHello", {
19
+ title: "Say Hello",
20
+ description: "Greet a user",
21
+ schema: j.object({ name: j.string() }),
22
+ execute: (input: { name: string }) => {
23
+ return `Hello, ${input.name}!`;
36
24
  },
37
- );
25
+ });
38
26
 
39
27
  const result = await capability.handler({ name: "Alice" });
40
28
 
@@ -46,19 +34,16 @@ describe("Worker.tool", () => {
46
34
  });
47
35
 
48
36
  it("async execution", async () => {
49
- const capability = createToolCapability<{ id: number }, { data: string }>(
50
- "fetchData",
51
- {
52
- title: "Fetch Data",
53
- description: "Fetch data asynchronously",
54
- schema: j.object({ id: j.number() }),
55
- execute: async (input: { id: number }) => {
56
- // Simulate async operation
57
- await new Promise((resolve) => setTimeout(resolve, 10));
58
- return { data: `Data for ID ${input.id}` };
59
- },
37
+ const capability = createToolCapability<{ id: number }, { data: string }>("fetchData", {
38
+ title: "Fetch Data",
39
+ description: "Fetch data asynchronously",
40
+ schema: j.object({ id: j.number() }),
41
+ execute: async (input: { id: number }) => {
42
+ // Simulate async operation
43
+ await new Promise((resolve) => setTimeout(resolve, 10));
44
+ return { data: `Data for ID ${input.id}` };
60
45
  },
61
- );
46
+ });
62
47
 
63
48
  const result = await capability.handler({ id: 42 });
64
49
 
@@ -73,17 +58,14 @@ describe("Worker.tool", () => {
73
58
  });
74
59
 
75
60
  it("execution error", async () => {
76
- const capability = createToolCapability<Record<string, never>, string>(
77
- "throwError",
78
- {
79
- title: "Throw Error",
80
- description: "Throws an error",
81
- schema: j.object({}),
82
- execute: () => {
83
- throw new Error("Something went wrong");
84
- },
61
+ const capability = createToolCapability<Record<string, never>, string>("throwError", {
62
+ title: "Throw Error",
63
+ description: "Throws an error",
64
+ schema: j.object({}),
65
+ execute: () => {
66
+ throw new Error("Something went wrong");
85
67
  },
86
- );
68
+ });
87
69
 
88
70
  const result = (await capability.handler({})) as {
89
71
  _tag: "error";
@@ -102,17 +84,14 @@ describe("Worker.tool", () => {
102
84
  });
103
85
 
104
86
  it("invalid input", async () => {
105
- const capability = createToolCapability<{ name: string }, string>(
106
- "sayHelloStrict",
107
- {
108
- title: "Say Hello",
109
- description: "Requires a name property",
110
- schema: j.object({ name: j.string() }),
111
- execute: (input: { name: string }) => {
112
- return `Hello, ${input.name}!`;
113
- },
87
+ const capability = createToolCapability<{ name: string }, string>("sayHelloStrict", {
88
+ title: "Say Hello",
89
+ description: "Requires a name property",
90
+ schema: j.object({ name: j.string() }),
91
+ execute: (input: { name: string }) => {
92
+ return `Hello, ${input.name}!`;
114
93
  },
115
- );
94
+ });
116
95
 
117
96
  const result = (await capability.handler({ age: 25 })) as {
118
97
  _tag: "error";
@@ -131,19 +110,19 @@ describe("Worker.tool", () => {
131
110
  });
132
111
 
133
112
  it("invalid output", async () => {
134
- const capability = createToolCapability<
135
- Record<string, never>,
136
- { result: string }
137
- >("invalidOutput", {
138
- title: "Return Invalid Output",
139
- description: "Returns output that doesn't match schema",
140
- schema: j.object({}),
141
- outputSchema: j.object({ result: j.string() }),
142
- // @ts-expect-error Testing invalid output - intentionally returning number instead of string
143
- execute: () => {
144
- return { result: 123 };
113
+ const capability = createToolCapability<Record<string, never>, { result: string }>(
114
+ "invalidOutput",
115
+ {
116
+ title: "Return Invalid Output",
117
+ description: "Returns output that doesn't match schema",
118
+ schema: j.object({}),
119
+ outputSchema: j.object({ result: j.string() }),
120
+ // @ts-expect-error Testing invalid output - intentionally returning number instead of string
121
+ execute: () => {
122
+ return { result: 123 };
123
+ },
145
124
  },
146
- });
125
+ );
147
126
 
148
127
  const result = (await capability.handler({})) as {
149
128
  _tag: "error";
@@ -155,42 +134,37 @@ describe("Worker.tool", () => {
155
134
  expect(result.error.message).toContain("result");
156
135
 
157
136
  expect(stdoutSpy).toHaveBeenCalledWith(
158
- expect.stringContaining(
159
- `"_tag":"error","error":{"name":"InvalidToolOutputError"`,
160
- ),
137
+ expect.stringContaining(`"_tag":"error","error":{"name":"InvalidToolOutputError"`),
161
138
  );
162
139
  });
163
140
 
164
141
  it("accepts schema with format string types (date, datetime, etc.)", () => {
165
- const capability = createToolCapability<
166
- { due: string; createdAt: string },
167
- string
168
- >("dateFormats", {
169
- title: "Date Formats",
170
- description: "Uses date and datetime format strings",
171
- schema: j.object({
172
- due: j.date(),
173
- createdAt: j.datetime(),
174
- }),
175
- execute: ({ due, createdAt }) => `${due} ${createdAt}`,
176
- });
177
-
178
- expect(capability.config.schema).toBeDefined();
179
- });
180
-
181
- it("rejects invalid date-time format at runtime", async () => {
182
- const capability = createToolCapability<{ ts: string }, string>(
183
- "datetimeValidation",
142
+ const capability = createToolCapability<{ due: string; createdAt: string }, string>(
143
+ "dateFormats",
184
144
  {
185
- title: "Datetime Validation",
186
- description: "Validates datetime input",
145
+ title: "Date Formats",
146
+ description: "Uses date and datetime format strings",
187
147
  schema: j.object({
188
- ts: j.datetime(),
148
+ due: j.date(),
149
+ createdAt: j.datetime(),
189
150
  }),
190
- execute: ({ ts }) => ts,
151
+ execute: ({ due, createdAt }) => `${due} ${createdAt}`,
191
152
  },
192
153
  );
193
154
 
155
+ expect(capability.config.schema).toBeDefined();
156
+ });
157
+
158
+ it("rejects invalid date-time format at runtime", async () => {
159
+ const capability = createToolCapability<{ ts: string }, string>("datetimeValidation", {
160
+ title: "Datetime Validation",
161
+ description: "Validates datetime input",
162
+ schema: j.object({
163
+ ts: j.datetime(),
164
+ }),
165
+ execute: ({ ts }) => ts,
166
+ });
167
+
194
168
  const valid = await capability.handler({ ts: "2024-01-01T00:00:00Z" });
195
169
  expect(valid).toEqual({
196
170
  _tag: "success",
@@ -206,78 +180,66 @@ describe("Worker.tool", () => {
206
180
  });
207
181
 
208
182
  it("accepts schema with nullable (string | null) properties", () => {
209
- const capability = createToolCapability<
210
- { name: string; nickname: string | null },
211
- string
212
- >("nullable", {
213
- title: "Nullable",
214
- description: "Has nullable properties",
215
- schema: j.object({
216
- name: j.string(),
217
- nickname: j.string().nullable(),
218
- }),
219
- execute: ({ name, nickname }) => `${name} (${nickname ?? "no nickname"})`,
220
- });
183
+ const capability = createToolCapability<{ name: string; nickname: string | null }, string>(
184
+ "nullable",
185
+ {
186
+ title: "Nullable",
187
+ description: "Has nullable properties",
188
+ schema: j.object({
189
+ name: j.string(),
190
+ nickname: j.string().nullable(),
191
+ }),
192
+ execute: ({ name, nickname }) => `${name} (${nickname ?? "no nickname"})`,
193
+ },
194
+ );
221
195
 
222
196
  expect(capability.config.schema).toBeDefined();
223
197
  });
224
198
 
225
199
  describe("hints", () => {
226
200
  it("omits hints from config when not specified (existing tools unchanged)", () => {
227
- const capability = createToolCapability<{ name: string }, string>(
228
- "noHints",
229
- {
230
- title: "No Hints",
231
- description: "A tool without hints",
232
- schema: j.object({ name: j.string() }),
233
- execute: ({ name }) => `Hello, ${name}`,
234
- },
235
- );
201
+ const capability = createToolCapability<{ name: string }, string>("noHints", {
202
+ title: "No Hints",
203
+ description: "A tool without hints",
204
+ schema: j.object({ name: j.string() }),
205
+ execute: ({ name }) => `Hello, ${name}`,
206
+ });
236
207
 
237
208
  expect(capability.config.hints).toBeUndefined();
238
209
  });
239
210
 
240
211
  it("flows readOnlyHint=true through to config", () => {
241
- const capability = createToolCapability<{ query: string }, string>(
242
- "readOnly",
243
- {
244
- title: "Read Only",
245
- description: "A read-only tool",
246
- schema: j.object({ query: j.string() }),
247
- hints: { readOnlyHint: true },
248
- execute: ({ query }) => query,
249
- },
250
- );
212
+ const capability = createToolCapability<{ query: string }, string>("readOnly", {
213
+ title: "Read Only",
214
+ description: "A read-only tool",
215
+ schema: j.object({ query: j.string() }),
216
+ hints: { readOnlyHint: true },
217
+ execute: ({ query }) => query,
218
+ });
251
219
 
252
220
  expect(capability.config.hints).toEqual({ readOnlyHint: true });
253
221
  });
254
222
 
255
223
  it("flows readOnlyHint=false through to config", () => {
256
- const capability = createToolCapability<{ pageId: string }, string>(
257
- "writeTool",
258
- {
259
- title: "Write Tool",
260
- description: "A write tool",
261
- schema: j.object({ pageId: j.string() }),
262
- hints: { readOnlyHint: false },
263
- execute: ({ pageId }) => pageId,
264
- },
265
- );
224
+ const capability = createToolCapability<{ pageId: string }, string>("writeTool", {
225
+ title: "Write Tool",
226
+ description: "A write tool",
227
+ schema: j.object({ pageId: j.string() }),
228
+ hints: { readOnlyHint: false },
229
+ execute: ({ pageId }) => pageId,
230
+ });
266
231
 
267
232
  expect(capability.config.hints).toEqual({ readOnlyHint: false });
268
233
  });
269
234
 
270
235
  it("does not affect execution behavior", async () => {
271
- const capability = createToolCapability<{ x: number }, number>(
272
- "doubleReadOnly",
273
- {
274
- title: "Double",
275
- description: "Doubles a number",
276
- schema: j.object({ x: j.number() }),
277
- hints: { readOnlyHint: true },
278
- execute: ({ x }) => x * 2,
279
- },
280
- );
236
+ const capability = createToolCapability<{ x: number }, number>("doubleReadOnly", {
237
+ title: "Double",
238
+ description: "Doubles a number",
239
+ schema: j.object({ x: j.number() }),
240
+ hints: { readOnlyHint: true },
241
+ execute: ({ x }) => x * 2,
242
+ });
281
243
 
282
244
  const result = await capability.handler({ x: 7 });
283
245
 
@@ -315,9 +277,7 @@ describe("Worker.tool", () => {
315
277
  expect(result.error.message).toContain("message");
316
278
 
317
279
  expect(stdoutSpy).toHaveBeenCalledWith(
318
- expect.stringContaining(
319
- `"_tag":"error","error":{"name":"InvalidToolOutputError"`,
320
- ),
280
+ expect.stringContaining(`"_tag":"error","error":{"name":"InvalidToolOutputError"`),
321
281
  );
322
282
  });
323
283
  });
@@ -1,5 +1,6 @@
1
1
  import { Ajv } from "ajv";
2
2
  import addFormats from "ajv-formats";
3
+
3
4
  import type { AnyJSONSchema } from "../json-schema.js";
4
5
  import type { SchemaBuilder } from "../schema-builder.js";
5
6
  import { getSchema } from "../schema-builder.js";
@@ -15,10 +16,7 @@ import { writeOutput } from "./output.js";
15
16
  * Throws a descriptive error at tool registration time (not request time)
16
17
  * so the developer sees it immediately.
17
18
  */
18
- function validateRequiredProperties(
19
- schema: AnyJSONSchema,
20
- path: string = "",
21
- ): void {
19
+ function validateRequiredProperties(schema: AnyJSONSchema, path: string = ""): void {
22
20
  if ("type" in schema && schema.type === "object" && "properties" in schema) {
23
21
  const propKeys = Object.keys(schema.properties).sort();
24
22
  const required = [...(schema.required ?? [])].sort();
@@ -43,20 +41,14 @@ function validateRequiredProperties(
43
41
  // Recurse into $defs
44
42
  if ("$defs" in schema && schema.$defs) {
45
43
  for (const [key, defSchema] of Object.entries(schema.$defs)) {
46
- validateRequiredProperties(
47
- defSchema,
48
- path ? `${path}.$defs.${key}` : `$defs.${key}`,
49
- );
44
+ validateRequiredProperties(defSchema, path ? `${path}.$defs.${key}` : `$defs.${key}`);
50
45
  }
51
46
  }
52
47
  }
53
48
 
54
49
  // Recurse into array items
55
50
  if ("type" in schema && schema.type === "array" && "items" in schema) {
56
- validateRequiredProperties(
57
- schema.items as AnyJSONSchema,
58
- path ? `${path}.items` : "items",
59
- );
51
+ validateRequiredProperties(schema.items as AnyJSONSchema, path ? `${path}.items` : "items");
60
52
  }
61
53
 
62
54
  // Recurse into anyOf branches
@@ -90,10 +82,7 @@ export interface ToolHints {
90
82
  readOnlyHint?: boolean;
91
83
  }
92
84
 
93
- export interface ToolConfiguration<
94
- I extends JSONValue,
95
- O extends JSONValue = JSONValue,
96
- > {
85
+ export interface ToolConfiguration<I extends JSONValue, O extends JSONValue = JSONValue> {
97
86
  title: string;
98
87
  description: string;
99
88
  schema: SchemaBuilder<I>;
@@ -156,10 +145,9 @@ export class ToolExecutionError extends Error {
156
145
  }
157
146
  }
158
147
 
159
- export type ToolCapability<
160
- I extends JSONValue,
161
- O extends JSONValue = JSONValue,
162
- > = ReturnType<typeof createToolCapability<I, O>>;
148
+ export type ToolCapability<I extends JSONValue, O extends JSONValue = JSONValue> = ReturnType<
149
+ typeof createToolCapability<I, O>
150
+ >;
163
151
 
164
152
  /**
165
153
  * Creates a capability definition for a tool to be used by an agent.
@@ -167,16 +155,14 @@ export type ToolCapability<
167
155
  * @param config - The configuration for the tool.
168
156
  * @returns A capability definition for the tool.
169
157
  */
170
- export function createToolCapability<
171
- I extends JSONValue,
172
- O extends JSONValue = JSONValue,
173
- >(key: string, config: ToolConfiguration<I, O>) {
158
+ export function createToolCapability<I extends JSONValue, O extends JSONValue = JSONValue>(
159
+ key: string,
160
+ config: ToolConfiguration<I, O>,
161
+ ) {
174
162
  const inputSchema = getSchema(config.schema);
175
163
  validateRequiredProperties(inputSchema as AnyJSONSchema);
176
164
 
177
- const outputSchema = config.outputSchema
178
- ? getSchema(config.outputSchema)
179
- : undefined;
165
+ const outputSchema = config.outputSchema ? getSchema(config.outputSchema) : undefined;
180
166
 
181
167
  if (outputSchema) {
182
168
  validateRequiredProperties(outputSchema as AnyJSONSchema);
@@ -215,14 +201,10 @@ export function createToolCapability<
215
201
  if (!validateInput(input)) {
216
202
  // ajv resets the "errors" property on each validation call.
217
203
  if (validateInput.errors == null) {
218
- throw new Error(
219
- "Unexpected: No validation errors after failed validation",
220
- );
204
+ throw new Error("Unexpected: No validation errors after failed validation");
221
205
  }
222
206
 
223
- const error = new InvalidToolInputError(
224
- JSON.stringify(validateInput.errors, null, 2),
225
- );
207
+ const error = new InvalidToolInputError(JSON.stringify(validateInput.errors, null, 2));
226
208
 
227
209
  if (options?.concreteOutput) {
228
210
  throw error;
@@ -242,9 +224,7 @@ export function createToolCapability<
242
224
  const capabilityContext = createCapabilityContext("tool");
243
225
  const result = await config.execute(input, capabilityContext);
244
226
  if (validateOutput && !validateOutput(result)) {
245
- const error = new InvalidToolOutputError(
246
- JSON.stringify(validateOutput.errors, null, 2),
247
- );
227
+ const error = new InvalidToolOutputError(JSON.stringify(validateOutput.errors, null, 2));
248
228
 
249
229
  if (options?.concreteOutput) {
250
230
  throw error;
@@ -275,9 +255,7 @@ export function createToolCapability<
275
255
  value: result,
276
256
  };
277
257
  } catch (err) {
278
- const error = new ToolExecutionError(
279
- err instanceof Error ? err.message : String(err),
280
- );
258
+ const error = new ToolExecutionError(err instanceof Error ? err.message : String(err));
281
259
 
282
260
  if (options?.concreteOutput) {
283
261
  throw error;
@@ -94,18 +94,12 @@ export interface WebhookConfiguration {
94
94
  * @param context - The capability execution context (Notion client, etc.)
95
95
  * @returns A promise that resolves when the webhook processing completes
96
96
  */
97
- execute: (
98
- events: WebhookEvent[],
99
- context: CapabilityContext,
100
- ) => Promise<void> | void;
97
+ execute: (events: WebhookEvent[], context: CapabilityContext) => Promise<void> | void;
101
98
  }
102
99
 
103
100
  export type WebhookCapability = ReturnType<typeof createWebhookCapability>;
104
101
 
105
- export function createWebhookCapability(
106
- key: string,
107
- config: WebhookConfiguration,
108
- ) {
102
+ export function createWebhookCapability(key: string, config: WebhookConfiguration) {
109
103
  return {
110
104
  _tag: "webhook" as const,
111
105
  key,
@@ -127,8 +121,7 @@ export function createWebhookCapability(
127
121
  writeOutput({ _tag: "success", value: { status: "success" } });
128
122
  }
129
123
  } catch (err) {
130
- const error =
131
- err instanceof ExecutionError ? err : new ExecutionError(err);
124
+ const error = err instanceof ExecutionError ? err : new ExecutionError(err);
132
125
 
133
126
  if (!options?.concreteOutput) {
134
127
  writeOutput({
@@ -1,19 +1,7 @@
1
- import {
2
- afterEach,
3
- beforeEach,
4
- describe,
5
- expect,
6
- expectTypeOf,
7
- it,
8
- type Mock,
9
- vi,
10
- } from "vitest";
1
+ import { afterEach, beforeEach, describe, expect, expectTypeOf, it, type Mock, vi } from "vitest";
2
+
11
3
  import { ExecutionError } from "../error.js";
12
- import {
13
- type CapabilityContext,
14
- Worker,
15
- type WorkflowConfiguration,
16
- } from "../index.js";
4
+ import { type CapabilityContext, Worker, type WorkflowConfiguration } from "../index.js";
17
5
  import {
18
6
  type NotionPageCreatedEvent,
19
7
  type NotionPageCreatedTrigger,
@@ -66,9 +54,7 @@ describe("createWorkflowCapability", () => {
66
54
  let stdoutSpy: Mock<typeof process.stdout.write>;
67
55
 
68
56
  beforeEach(() => {
69
- stdoutSpy = vi
70
- .spyOn(process.stdout, "write")
71
- .mockImplementation(() => true);
57
+ stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
72
58
  });
73
59
 
74
60
  afterEach(() => {
@@ -82,13 +68,8 @@ describe("createWorkflowCapability", () => {
82
68
  });
83
69
 
84
70
  it("requires trigger declarations in workflow configuration", () => {
85
- type PageAddedConfiguration = WorkflowConfiguration<
86
- readonly [NotionPageCreatedTrigger]
87
- >;
88
- type ConfigurationWithoutTriggers = Omit<
89
- PageAddedConfiguration,
90
- "triggers"
91
- >;
71
+ type PageAddedConfiguration = WorkflowConfiguration<readonly [NotionPageCreatedTrigger]>;
72
+ type ConfigurationWithoutTriggers = Omit<PageAddedConfiguration, "triggers">;
92
73
 
93
74
  expectTypeOf<ConfigurationWithoutTriggers>().not.toMatchTypeOf<PageAddedConfiguration>();
94
75
  });
@@ -137,9 +118,9 @@ describe("createWorkflowCapability", () => {
137
118
  execute,
138
119
  });
139
120
 
140
- await expect(
141
- capability.handler(pageCreatedEvent, { concreteOutput: true }),
142
- ).resolves.toEqual({ status: "success" });
121
+ await expect(capability.handler(pageCreatedEvent, { concreteOutput: true })).resolves.toEqual({
122
+ status: "success",
123
+ });
143
124
  expect(execute).toHaveBeenCalledWith(
144
125
  pageCreatedEvent,
145
126
  expect.objectContaining({ notion: expect.any(Object) }),
@@ -172,9 +153,7 @@ describe("createWorkflowCapability", () => {
172
153
  },
173
154
  });
174
155
 
175
- await expect(capability.handler(pageCreatedEvent)).rejects.toThrow(
176
- ExecutionError,
177
- );
156
+ await expect(capability.handler(pageCreatedEvent)).rejects.toThrow(ExecutionError);
178
157
  expect(stdoutSpy).toHaveBeenCalledWith(
179
158
  expect.stringContaining(
180
159
  '"_tag":"error","error":{"name":"ExecutionError","message":"Error during worker execution: Error: Something went wrong"',
@@ -1,8 +1,5 @@
1
1
  import { ExecutionError } from "../error.js";
2
- import type {
3
- WorkflowEventMap,
4
- WorkflowTrigger,
5
- } from "../triggers.generated.js";
2
+ import type { WorkflowEventMap, WorkflowTrigger } from "../triggers.generated.js";
6
3
  import type { HandlerOptions } from "../types.js";
7
4
  import type { CapabilityContext } from "./context.js";
8
5
  import { createCapabilityContext } from "./context.js";
@@ -10,8 +7,7 @@ import { writeOutput } from "./output.js";
10
7
 
11
8
  export type WorkflowEvent = WorkflowEventMap[keyof WorkflowEventMap];
12
9
 
13
- export type WorkflowEventForTrigger<T extends WorkflowTrigger> =
14
- WorkflowEventMap[T["type"]];
10
+ export type WorkflowEventForTrigger<T extends WorkflowTrigger> = WorkflowEventMap[T["type"]];
15
11
 
16
12
  export type WorkflowEventForTriggers<T extends readonly WorkflowTrigger[]> =
17
13
  WorkflowEventForTrigger<T[number]>;
@@ -46,10 +42,10 @@ export type WorkflowConfiguration<
46
42
  };
47
43
 
48
44
  export type WorkflowCapability<
49
- TTriggers extends readonly [
45
+ TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]] = readonly [
50
46
  WorkflowTrigger,
51
47
  ...WorkflowTrigger[],
52
- ] = readonly [WorkflowTrigger, ...WorkflowTrigger[]],
48
+ ],
53
49
  > = {
54
50
  _tag: "workflow";
55
51
  key: string;
@@ -73,10 +69,7 @@ export type WorkflowCapability<
73
69
  */
74
70
  export function createWorkflowCapability<
75
71
  const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]],
76
- >(
77
- key: string,
78
- config: WorkflowConfiguration<TTriggers>,
79
- ): WorkflowCapability<TTriggers> {
72
+ >(key: string, config: WorkflowConfiguration<TTriggers>): WorkflowCapability<TTriggers> {
80
73
  return {
81
74
  _tag: "workflow",
82
75
  key,
package/src/index.ts CHANGED
@@ -1,10 +1,4 @@
1
- export {
2
- emojiIcon,
3
- imageCover,
4
- imageIcon,
5
- notionIcon,
6
- place,
7
- } from "./builder.js";
1
+ export { emojiIcon, imageCover, imageIcon, notionIcon, place } from "./builder.js";
8
2
  export type {
9
3
  AiConnectorArchetype,
10
4
  AiConnectorCapability,
@@ -43,11 +37,7 @@ export type {
43
37
  SyncExecutionResult,
44
38
  SyncMode,
45
39
  } from "./capabilities/sync.js";
46
- export type {
47
- ToolCapability,
48
- ToolConfiguration,
49
- ToolHints,
50
- } from "./capabilities/tool.js";
40
+ export type { ToolCapability, ToolConfiguration, ToolHints } from "./capabilities/tool.js";
51
41
  export type {
52
42
  WebhookCapability,
53
43
  WebhookConfiguration,
@@ -12,6 +12,7 @@
12
12
  * This ensures tsc sees the error on the line immediately after the directive.
13
13
  */
14
14
  import { describe, expect, it } from "vitest";
15
+
15
16
  import type {
16
17
  AnyJSONSchema,
17
18
  JSONSchema,
@@ -671,10 +672,7 @@ describe("JSONSchema — complex schemas", () => {
671
672
 
672
673
  describe("JSONSchema — structural type assertions", () => {
673
674
  it("JSONSchemaObjectDef requires additionalProperties to be false", () => {
674
- type _Proof = Assert<
675
- JSONSchemaObjectDef<{ x: number }>["additionalProperties"],
676
- false
677
- >;
675
+ type _Proof = Assert<JSONSchemaObjectDef<{ x: number }>["additionalProperties"], false>;
678
676
  });
679
677
 
680
678
  it("JSONSchemaArrayDef minItems is restricted to 0 | 1", () => {