@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
@@ -0,0 +1,319 @@
1
+ import { Ajv } from "ajv";
2
+ import addFormats from "ajv-formats";
3
+
4
+ import type { CapabilityContext } from "./context.js";
5
+ import { createCapabilityContext } from "./context.js";
6
+ import type { AnyJSONSchema, JSONSchema } from "./json-schema.js";
7
+ import { writeOutput } from "./output.js";
8
+ import type { SchemaBuilder } from "./schema-builder.js";
9
+ import { getSchema } from "./schema-builder.js";
10
+ import type { HandlerOptions } from "./types.js";
11
+
12
+ /**
13
+ * Any JSON-serializable value.
14
+ */
15
+ export type JSONValue =
16
+ | string
17
+ | number
18
+ | boolean
19
+ | null
20
+ | JSONValue[]
21
+ | { [key: string]: JSONValue };
22
+
23
+ /**
24
+ * Validates that every object schema in the tree has all its `properties`
25
+ * keys listed in `required`. Both providers require this.
26
+ *
27
+ * Throws a descriptive error at tool creation time (not request time)
28
+ * so the developer sees it immediately.
29
+ */
30
+ function validateRequiredProperties(schema: AnyJSONSchema, path: string = ""): void {
31
+ if ("type" in schema && schema.type === "object" && "properties" in schema) {
32
+ const propKeys = Object.keys(schema.properties).sort();
33
+ const required = [...(schema.required ?? [])].sort();
34
+ const missing = propKeys.filter((k) => !required.includes(k));
35
+ if (missing.length > 0) {
36
+ throw new Error(
37
+ `Invalid schema${path ? ` at ${path}` : ""}: ` +
38
+ `properties [${missing.join(", ")}] must be listed in "required". ` +
39
+ "Both model providers require all properties to be required. " +
40
+ 'Use anyOf with { type: "null" } for optional fields.',
41
+ );
42
+ }
43
+
44
+ // Recurse into nested property schemas
45
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
46
+ validateRequiredProperties(
47
+ propSchema as AnyJSONSchema,
48
+ path ? `${path}.properties.${key}` : `properties.${key}`,
49
+ );
50
+ }
51
+
52
+ // Recurse into $defs
53
+ if ("$defs" in schema && schema.$defs) {
54
+ for (const [key, defSchema] of Object.entries(schema.$defs)) {
55
+ validateRequiredProperties(defSchema, path ? `${path}.$defs.${key}` : `$defs.${key}`);
56
+ }
57
+ }
58
+ }
59
+
60
+ // Recurse into array items
61
+ if ("type" in schema && schema.type === "array" && "items" in schema) {
62
+ validateRequiredProperties(schema.items as AnyJSONSchema, path ? `${path}.items` : "items");
63
+ }
64
+
65
+ // Recurse into anyOf branches
66
+ if ("anyOf" in schema && Array.isArray(schema.anyOf)) {
67
+ for (let i = 0; i < schema.anyOf.length; i++) {
68
+ validateRequiredProperties(
69
+ schema.anyOf[i] as AnyJSONSchema,
70
+ path ? `${path}.anyOf[${i}]` : `anyOf[${i}]`,
71
+ );
72
+ }
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Hints describing a tool's behavior. Advisory metadata read by the platform
78
+ * (not the model) to decide whether a call is safe to auto-execute or
79
+ * requires user confirmation.
80
+ *
81
+ * Field names mirror the MCP tool annotation shape
82
+ * (`McpServerToolAnnotations`) so worker tools flow through the same
83
+ * confirmation / auto-execute machinery as MCP tools.
84
+ *
85
+ * Only hints with active consumers in the Notion client are included.
86
+ */
87
+ export interface ToolHints {
88
+ /**
89
+ * The tool only reads state and has no side effects. Safe to call
90
+ * repeatedly; safe to auto-execute under default policy. Tools without
91
+ * this hint are treated as write tools and prompt for confirmation.
92
+ */
93
+ readOnlyHint?: boolean;
94
+ }
95
+
96
+ /**
97
+ * Configuration passed to {@link createTool}.
98
+ */
99
+ export interface ToolConfiguration<I extends JSONValue, O extends JSONValue = JSONValue> {
100
+ title: string;
101
+ description: string;
102
+ schema: SchemaBuilder<I>;
103
+ outputSchema?: SchemaBuilder<O>;
104
+ hints?: ToolHints;
105
+ execute: (input: I, context: CapabilityContext) => O | Promise<O>;
106
+ }
107
+
108
+ /**
109
+ * An error returned when the input to a tool doesn't match the input schema.
110
+ */
111
+ export class InvalidToolInputError extends Error {
112
+ constructor(message: string) {
113
+ super(message);
114
+ this.name = "InvalidToolInputError";
115
+ }
116
+
117
+ toJSON() {
118
+ return {
119
+ name: this.name,
120
+ message: this.message,
121
+ trace: this.stack,
122
+ };
123
+ }
124
+ }
125
+
126
+ /**
127
+ * An error returned when the output from a tool doesn't match the output schema.
128
+ */
129
+ export class InvalidToolOutputError extends Error {
130
+ constructor(message: string) {
131
+ super(message);
132
+ this.name = "InvalidToolOutputError";
133
+ }
134
+
135
+ toJSON() {
136
+ return {
137
+ name: this.name,
138
+ message: this.message,
139
+ trace: this.stack,
140
+ };
141
+ }
142
+ }
143
+
144
+ /**
145
+ * An error returned when the tool execution fails.
146
+ */
147
+ export class ToolExecutionError extends Error {
148
+ constructor(message: string) {
149
+ super(message);
150
+ this.name = "ToolExecutionError";
151
+ }
152
+
153
+ toJSON() {
154
+ return {
155
+ name: this.name,
156
+ message: this.message,
157
+ trace: this.stack,
158
+ };
159
+ }
160
+ }
161
+
162
+ type ToolErrorResult = {
163
+ _tag: "error";
164
+ error: { name: string; message: string; trace: string | undefined };
165
+ };
166
+
167
+ /**
168
+ * The manifest-visible configuration of a tool: the metadata from
169
+ * {@link ToolConfiguration} with the schema builders resolved to plain
170
+ * JSON Schemas.
171
+ */
172
+ export type ToolManifestConfig = {
173
+ title: string;
174
+ description: string;
175
+ schema: AnyJSONSchema;
176
+ outputSchema: AnyJSONSchema | undefined;
177
+ hints: ToolHints | undefined;
178
+ };
179
+
180
+ /**
181
+ * A tool capability as returned by {@link createTool}.
182
+ *
183
+ * Note that a tool carries no key of its own — the build tool derives the
184
+ * capability key from the file the tool is default-exported from.
185
+ */
186
+ export type Tool<I extends JSONValue = JSONValue, O extends JSONValue = JSONValue> = {
187
+ _tag: "tool";
188
+ config: ToolManifestConfig;
189
+ handler: (
190
+ input: I,
191
+ options?: HandlerOptions,
192
+ ) => Promise<O | { _tag: "success"; value: O } | ToolErrorResult>;
193
+ };
194
+
195
+ /**
196
+ * Create a tool capability for use by an agent.
197
+ *
198
+ * Default-export the result from a file directly under `src/tools/` —
199
+ * the file's basename becomes the tool's key.
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * // src/tools/sayHello.ts
204
+ * import { j } from "@notionhq/workers/alpha/schema-builder";
205
+ * import { createTool } from "@notionhq/workers/alpha/tool";
206
+ *
207
+ * export default createTool({
208
+ * title: "Say Hello",
209
+ * description: "Say hello to the user",
210
+ * schema: j.object({ name: j.string() }),
211
+ * execute: ({ name }) => {
212
+ * return `Hello, ${name}!`;
213
+ * },
214
+ * });
215
+ * ```
216
+ */
217
+ export function createTool<I extends JSONValue, O extends JSONValue = JSONValue>(
218
+ config: ToolConfiguration<I, O>,
219
+ ): Tool<I, O> {
220
+ const inputSchema = getSchema(config.schema);
221
+ validateRequiredProperties(inputSchema as AnyJSONSchema);
222
+
223
+ const outputSchema: JSONSchema<O> | undefined = config.outputSchema
224
+ ? getSchema(config.outputSchema)
225
+ : undefined;
226
+
227
+ if (outputSchema) {
228
+ validateRequiredProperties(outputSchema as AnyJSONSchema);
229
+ }
230
+
231
+ const ajv = new Ajv();
232
+ addFormats(ajv);
233
+ const validateInput = ajv.compile(inputSchema);
234
+ const validateOutput = outputSchema ? ajv.compile(outputSchema) : null;
235
+
236
+ async function handler(
237
+ input: I,
238
+ options?: HandlerOptions,
239
+ ): Promise<O | { _tag: "success"; value: O } | ToolErrorResult> {
240
+ if (!validateInput(input)) {
241
+ // ajv resets the "errors" property on each validation call.
242
+ if (validateInput.errors == null) {
243
+ throw new Error("Unexpected: No validation errors after failed validation");
244
+ }
245
+
246
+ const error = new InvalidToolInputError(JSON.stringify(validateInput.errors, null, 2));
247
+
248
+ if (options?.concreteOutput) {
249
+ throw error;
250
+ }
251
+
252
+ const result: ToolErrorResult = {
253
+ _tag: "error",
254
+ error: { name: error.name, message: error.message, trace: error.stack },
255
+ };
256
+
257
+ writeOutput(result);
258
+
259
+ return result;
260
+ }
261
+
262
+ try {
263
+ const capabilityContext = createCapabilityContext("tool");
264
+ const result = await config.execute(input, capabilityContext);
265
+
266
+ if (validateOutput && !validateOutput(result)) {
267
+ const error = new InvalidToolOutputError(JSON.stringify(validateOutput.errors, null, 2));
268
+
269
+ if (options?.concreteOutput) {
270
+ throw error;
271
+ }
272
+
273
+ const errorResult: ToolErrorResult = {
274
+ _tag: "error",
275
+ error: { name: error.name, message: error.message, trace: error.stack },
276
+ };
277
+
278
+ writeOutput(errorResult);
279
+
280
+ return errorResult;
281
+ }
282
+
283
+ if (options?.concreteOutput) {
284
+ return result;
285
+ }
286
+
287
+ writeOutput({ _tag: "success", value: result });
288
+
289
+ return { _tag: "success" as const, value: result };
290
+ } catch (err) {
291
+ const error = new ToolExecutionError(err instanceof Error ? err.message : String(err));
292
+
293
+ if (options?.concreteOutput) {
294
+ throw error;
295
+ }
296
+
297
+ const result: ToolErrorResult = {
298
+ _tag: "error",
299
+ error: { name: error.name, message: error.message, trace: error.stack },
300
+ };
301
+
302
+ writeOutput(result);
303
+
304
+ return result;
305
+ }
306
+ }
307
+
308
+ return {
309
+ _tag: "tool",
310
+ config: {
311
+ title: config.title,
312
+ description: config.description,
313
+ schema: inputSchema as AnyJSONSchema,
314
+ outputSchema: outputSchema as AnyJSONSchema | undefined,
315
+ hints: config.hints,
316
+ },
317
+ handler,
318
+ };
319
+ }