@notionhq/apps 0.0.45 → 0.0.47
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 +11 -1
- package/dist/connections.d.ts +1 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +4 -2
- package/dist/workflow-schema.js +18 -7
- package/dist/workflow.d.ts +30 -5
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +34 -4
- package/package.json +1 -1
- package/skills/workflow/SKILL.md +28 -0
- package/src/cli/build.test.ts +6 -0
- package/src/connections.test.ts +18 -14
- package/src/connections.ts +5 -3
- package/src/workflow-connections-types.test.ts +2 -2
- package/src/workflow-schema.ts +30 -10
- package/src/workflow-types.test.ts +47 -5
- package/src/workflow.test.ts +121 -7
- package/src/workflow.ts +99 -10
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({
|
|
104
|
+
calendar: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
|
|
105
105
|
},
|
|
106
106
|
handler: async () => {},
|
|
107
107
|
});
|
|
@@ -174,6 +174,16 @@ do not need to specify `additionalProperties`.
|
|
|
174
174
|
See the [manual workflow example](./skills/workflow/SKILL.md#manual-workflow-inputs)
|
|
175
175
|
for the supported schema subset and a complete typed workflow.
|
|
176
176
|
|
|
177
|
+
## Workflow outputs
|
|
178
|
+
|
|
179
|
+
Use `outputSchema` to declare the object a workflow returns. It takes the same
|
|
180
|
+
`j.object(...)` schema builder as manual inputs. The handler's return type is
|
|
181
|
+
inferred from the schema, and the SDK validates the returned value before the run
|
|
182
|
+
succeeds. The output must be at most 256 KB as JSON. A workflow without
|
|
183
|
+
`outputSchema` returns nothing.
|
|
184
|
+
|
|
185
|
+
See the [workflow output example](./skills/workflow/SKILL.md#workflow-outputs).
|
|
186
|
+
|
|
177
187
|
## Notion API access
|
|
178
188
|
|
|
179
189
|
Use `context.notion` for Notion API calls. Deployed apps receive Notion API
|
package/dist/connections.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type WorkflowConnection<TProvider extends string = string> = {
|
|
|
7
7
|
calendar?: CalendarConnectionOptions;
|
|
8
8
|
};
|
|
9
9
|
export type CalendarConnectionOptions = {
|
|
10
|
-
|
|
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,
|
|
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"}
|
package/dist/connections.js
CHANGED
|
@@ -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.
|
|
41
|
-
throw new Error(
|
|
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/dist/workflow-schema.js
CHANGED
|
@@ -2,9 +2,21 @@ import { Ajv } from "ajv";
|
|
|
2
2
|
import addFormats from "ajv-formats";
|
|
3
3
|
import { getSchema } from "./schema-builder.js";
|
|
4
4
|
function compileWorkflowInputSchema(schema) {
|
|
5
|
+
return compileWorkflowObjectSchema(schema, {
|
|
6
|
+
schemaName: "workflow manual inputSchema",
|
|
7
|
+
valueName: "manual workflow input"
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
function compileWorkflowOutputSchema(schema) {
|
|
11
|
+
return compileWorkflowObjectSchema(schema, {
|
|
12
|
+
schemaName: "workflow outputSchema",
|
|
13
|
+
valueName: "workflow output"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function compileWorkflowObjectSchema(schema, names) {
|
|
5
17
|
const jsonSchema = getSchema(schema);
|
|
6
18
|
if (!("type" in jsonSchema) || jsonSchema.type !== "object") {
|
|
7
|
-
throw new Error(
|
|
19
|
+
throw new Error(`${names.schemaName}: must be a j.object() schema`);
|
|
8
20
|
}
|
|
9
21
|
const ajv = new Ajv({ allErrors: true, strict: true });
|
|
10
22
|
addFormats.default(ajv, {
|
|
@@ -24,15 +36,14 @@ function compileWorkflowInputSchema(schema) {
|
|
|
24
36
|
const validate = ajv.compile(jsonSchema);
|
|
25
37
|
return {
|
|
26
38
|
jsonSchema,
|
|
27
|
-
validate(
|
|
28
|
-
if (!validate(
|
|
29
|
-
throw new Error(
|
|
30
|
-
`Invalid manual workflow input: ${ajv.errorsText(validate.errors)}`
|
|
31
|
-
);
|
|
39
|
+
validate(value) {
|
|
40
|
+
if (!validate(value)) {
|
|
41
|
+
throw new Error(`Invalid ${names.valueName}: ${ajv.errorsText(validate.errors)}`);
|
|
32
42
|
}
|
|
33
43
|
}
|
|
34
44
|
};
|
|
35
45
|
}
|
|
36
46
|
export {
|
|
37
|
-
compileWorkflowInputSchema
|
|
47
|
+
compileWorkflowInputSchema,
|
|
48
|
+
compileWorkflowOutputSchema
|
|
38
49
|
};
|
package/dist/workflow.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type WorkflowConnectionDeclarations, type WorkflowConnectionRequirement
|
|
|
2
2
|
import { type WorkflowAccess, type WorkflowAccessDeclarations, type WorkflowAccessRequirements } from "./workflow-access.js";
|
|
3
3
|
import type { CapabilityContext } from "./context.js";
|
|
4
4
|
import { type RunMetadata } from "./runtime-metadata.js";
|
|
5
|
+
import type { Infer, SchemaBuilder } from "./schema-builder.js";
|
|
5
6
|
import { type WorkflowState } from "./workflow-state.js";
|
|
6
7
|
import type { ManualWorkflowTrigger, WebhookTrigger, WorkflowEventMap, WorkflowTrigger, WorkflowEventCreators, WorkflowTriggerForConnections } from "./events.generated.js";
|
|
7
8
|
type HandlerOptions = {
|
|
@@ -91,7 +92,15 @@ export type WorkflowWaitForInputResult = {
|
|
|
91
92
|
type WorkflowWaitResult = WorkflowWaitUntilResult | WorkflowWaitForInputResult;
|
|
92
93
|
type WorkflowHandlerResult = {
|
|
93
94
|
status: "success";
|
|
95
|
+
output?: Record<string, unknown>;
|
|
94
96
|
} | WorkflowWaitResult;
|
|
97
|
+
/** An object schema describing the value a workflow returns. */
|
|
98
|
+
export type WorkflowOutputSchema = SchemaBuilder<Record<string, unknown>, "object">;
|
|
99
|
+
/**
|
|
100
|
+
* What a workflow handler returns: the value described by `outputSchema`, or
|
|
101
|
+
* nothing when the workflow declares no output schema.
|
|
102
|
+
*/
|
|
103
|
+
export type WorkflowHandlerReturn<TOutputSchema extends WorkflowOutputSchema | undefined> = TOutputSchema extends WorkflowOutputSchema ? Promise<Infer<TOutputSchema>> | Infer<TOutputSchema> : Promise<void> | void;
|
|
95
104
|
export { FatalError, RetryableError } from "./error.js";
|
|
96
105
|
export type { WorkflowAccess, WorkflowAccessAgentLevel, WorkflowAccessBindings, WorkflowAccessDeclaration, WorkflowAccessDeclarations, WorkflowAccessLevel, WorkflowAccessLevelFor, WorkflowAccessResource, ResourceAccessLevel, WorkflowAccessResourceType, WorkflowAccessRequirement, WorkflowAccessRequirements, WorkflowAccessValue, } from "./workflow-access.js";
|
|
97
106
|
export { access } from "./workflow-access.js";
|
|
@@ -194,7 +203,7 @@ export type WorkflowManifestTrigger = WorkflowTrigger | (WebhookTrigger & {
|
|
|
194
203
|
/**
|
|
195
204
|
* Configuration passed to {@link workflow}.
|
|
196
205
|
*/
|
|
197
|
-
export type WorkflowConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations = WorkflowConnectionDeclarations, TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations> = {
|
|
206
|
+
export type WorkflowConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations = WorkflowConnectionDeclarations, TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations, TOutputSchema extends WorkflowOutputSchema | undefined = undefined> = {
|
|
198
207
|
/**
|
|
199
208
|
* A human-readable name for the workflow, shown in the UI when viewing workflows
|
|
200
209
|
*/
|
|
@@ -259,10 +268,24 @@ export type WorkflowConfiguration<TTriggers extends readonly [WorkflowTrigger, .
|
|
|
259
268
|
* ```
|
|
260
269
|
*/
|
|
261
270
|
verify?: WebhookVerifyHandler;
|
|
262
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Optional schema for the object the handler returns, built with
|
|
273
|
+
* `@notionhq/apps/schema-builder`. The handler's return type is inferred
|
|
274
|
+
* from it, and the returned value is validated before the run succeeds.
|
|
275
|
+
*
|
|
276
|
+
* Without `outputSchema`, the workflow returns nothing.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```ts
|
|
280
|
+
* outputSchema: j.object({ releaseUrl: j.string() }),
|
|
281
|
+
* handler: async () => ({ releaseUrl: "https://example.com/releases/1" }),
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
outputSchema?: TOutputSchema;
|
|
285
|
+
handler: (event: WorkflowEventForTriggers<TTriggers>, context: WorkflowContext<TConnections, TAccess>) => WorkflowHandlerReturn<NoInfer<TOutputSchema>>;
|
|
263
286
|
};
|
|
264
287
|
/** Configuration that checks trigger keys against declared connections. */
|
|
265
|
-
export type WorkflowTriggerConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations, TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations> = Omit<WorkflowConfiguration<TTriggers, TConnections, TAccess>, "triggers"> & {
|
|
288
|
+
export type WorkflowTriggerConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations, TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations, TOutputSchema extends WorkflowOutputSchema | undefined = undefined> = Omit<WorkflowConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>, "triggers"> & {
|
|
266
289
|
triggers: (context: {
|
|
267
290
|
events: WorkflowEventCreators<NoInfer<TConnections>>;
|
|
268
291
|
}) => TTriggers;
|
|
@@ -286,6 +309,8 @@ export type Workflow<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTri
|
|
|
286
309
|
access?: WorkflowAccessRequirements;
|
|
287
310
|
deadline?: WorkflowDeadline;
|
|
288
311
|
retry?: WorkflowRetryPolicy;
|
|
312
|
+
/** JSON Schema for the handler's return value. Absent when the workflow returns nothing. */
|
|
313
|
+
outputJsonSchema?: Record<string, unknown>;
|
|
289
314
|
};
|
|
290
315
|
handler: (input: WorkflowEventForTriggers<TTriggers> | WebhookVerifyInvocation, options?: HandlerOptions) => Promise<WorkflowHandlerResult | WebhookVerifyResponse | undefined>;
|
|
291
316
|
};
|
|
@@ -318,8 +343,8 @@ export type Workflow<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTri
|
|
|
318
343
|
export declare function workflow<const TTriggers extends readonly [
|
|
319
344
|
WorkflowTriggerForConnections<NoInfer<TConnections>>,
|
|
320
345
|
...WorkflowTriggerForConnections<NoInfer<TConnections>>[]
|
|
321
|
-
], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>, const TAccess extends WorkflowAccessDeclarations = Record<never, never
|
|
322
|
-
export declare function workflow<const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>, const TAccess extends WorkflowAccessDeclarations = Record<never, never
|
|
346
|
+
], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>, const TAccess extends WorkflowAccessDeclarations = Record<never, never>, const TOutputSchema extends WorkflowOutputSchema | undefined = undefined>(configuration: WorkflowTriggerConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>): Workflow<TTriggers>;
|
|
347
|
+
export declare function workflow<const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>, const TAccess extends WorkflowAccessDeclarations = Record<never, never>, const TOutputSchema extends WorkflowOutputSchema | undefined = undefined>(configuration: WorkflowConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>): Workflow<TTriggers>;
|
|
323
348
|
/** Context passed to a workflow step. */
|
|
324
349
|
export type StepContext = {
|
|
325
350
|
/**
|
package/dist/workflow.d.ts.map
CHANGED
|
@@ -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
|
@@ -16,6 +16,7 @@ import { writeOutput } from "./output.js";
|
|
|
16
16
|
import { resolveRuntimeInput } from "./runtime-input.js";
|
|
17
17
|
import { readRunMetadata } from "./runtime-metadata.js";
|
|
18
18
|
import { createWorkflowEvents, validateManualWorkflowInput } from "./events.generated.js";
|
|
19
|
+
import { compileWorkflowOutputSchema } from "./workflow-schema.js";
|
|
19
20
|
import { createWorkflowStepState } from "./workflow-state.js";
|
|
20
21
|
const WEBHOOK_TRIGGER_TYPE = "webhooks.webhook";
|
|
21
22
|
const input = {
|
|
@@ -74,6 +75,7 @@ function workflow(configuration) {
|
|
|
74
75
|
}
|
|
75
76
|
const deadline = configuration.deadline === void 0 ? void 0 : structuredClone(configuration.deadline);
|
|
76
77
|
const retry = configuration.retry === void 0 ? void 0 : manifestRetryPolicy(configuration.retry);
|
|
78
|
+
const outputSchema = configuration.outputSchema === void 0 ? void 0 : compileWorkflowOutputSchema(configuration.outputSchema);
|
|
77
79
|
const manualTriggers = triggers.filter(
|
|
78
80
|
(trigger) => trigger.type === "workflow.manual"
|
|
79
81
|
);
|
|
@@ -94,7 +96,8 @@ function workflow(configuration) {
|
|
|
94
96
|
...configuration.connections === void 0 ? {} : { connections: requirements },
|
|
95
97
|
...configuration.access === void 0 ? {} : { access: accessRequirements },
|
|
96
98
|
...deadline === void 0 ? {} : { deadline },
|
|
97
|
-
...retry === void 0 ? {} : { retry }
|
|
99
|
+
...retry === void 0 ? {} : { retry },
|
|
100
|
+
...outputSchema === void 0 ? {} : { outputJsonSchema: outputSchema.jsonSchema }
|
|
98
101
|
},
|
|
99
102
|
async handler(input2, options) {
|
|
100
103
|
const invocationStartedAt = Date.now();
|
|
@@ -145,11 +148,21 @@ function workflow(configuration) {
|
|
|
145
148
|
}
|
|
146
149
|
validateManualWorkflowInput(manualTrigger, event.input);
|
|
147
150
|
}
|
|
148
|
-
await configuration.handler(
|
|
151
|
+
const handlerOutput = await configuration.handler(
|
|
152
|
+
event,
|
|
153
|
+
capabilityContext
|
|
154
|
+
);
|
|
155
|
+
const result = outputSchema === void 0 ? { status: "success" } : {
|
|
156
|
+
status: "success",
|
|
157
|
+
output: serializeWorkflowOutput(
|
|
158
|
+
handlerOutput,
|
|
159
|
+
outputSchema.validate
|
|
160
|
+
)
|
|
161
|
+
};
|
|
149
162
|
if (options?.concreteOutput) {
|
|
150
|
-
return
|
|
163
|
+
return result;
|
|
151
164
|
}
|
|
152
|
-
writeOutput({ _tag: "success", value:
|
|
165
|
+
writeOutput({ _tag: "success", value: result });
|
|
153
166
|
} catch (err) {
|
|
154
167
|
if (err instanceof WorkflowWaitInterrupt) {
|
|
155
168
|
if (options?.concreteOutput) {
|
|
@@ -199,6 +212,23 @@ function manifestTriggers(triggers, hasVerify) {
|
|
|
199
212
|
(trigger) => hasVerify && trigger.type === WEBHOOK_TRIGGER_TYPE ? { ...trigger, hasVerify: true } : trigger
|
|
200
213
|
);
|
|
201
214
|
}
|
|
215
|
+
const MAX_WORKFLOW_OUTPUT_BYTES = 256 * 1024;
|
|
216
|
+
function serializeWorkflowOutput(value, validate) {
|
|
217
|
+
try {
|
|
218
|
+
const json = value === void 0 ? void 0 : JSON.stringify(value);
|
|
219
|
+
const bytes = json === void 0 ? 0 : Buffer.byteLength(json, "utf8");
|
|
220
|
+
if (bytes > MAX_WORKFLOW_OUTPUT_BYTES) {
|
|
221
|
+
throw new Error(
|
|
222
|
+
`Invalid workflow output: must be at most ${MAX_WORKFLOW_OUTPUT_BYTES} bytes as JSON, got ${bytes}.`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
const serialized = json === void 0 ? void 0 : JSON.parse(json);
|
|
226
|
+
validate(serialized);
|
|
227
|
+
return serialized;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
throw new FatalError(error instanceof Error ? error.message : String(error));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
202
232
|
function isVerifyInvocation(input2) {
|
|
203
233
|
return typeof input2 === "object" && input2 !== null && "request" in input2;
|
|
204
234
|
}
|
package/package.json
CHANGED
package/skills/workflow/SKILL.md
CHANGED
|
@@ -187,6 +187,34 @@ export default workflow({
|
|
|
187
187
|
});
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
+
## Workflow outputs
|
|
191
|
+
|
|
192
|
+
Declare `outputSchema` when a workflow returns a value. Use the same
|
|
193
|
+
`@notionhq/apps/schema-builder` builders as manual inputs; the schema must be a
|
|
194
|
+
`j.object(...)`. The handler must return a matching object of at most 256 KB as
|
|
195
|
+
JSON, and the run fails without retrying when it does not. Omit `outputSchema` for workflows that return
|
|
196
|
+
nothing.
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import { workflow } from "@notionhq/apps/workflow";
|
|
200
|
+
import { events } from "@notionhq/apps/events";
|
|
201
|
+
import { j } from "@notionhq/apps/schema-builder";
|
|
202
|
+
|
|
203
|
+
export default workflow({
|
|
204
|
+
name: "Prepare releases",
|
|
205
|
+
description: "Prepares the supplied releases.",
|
|
206
|
+
triggers: [
|
|
207
|
+
events.manual({
|
|
208
|
+
inputSchema: j.object({ releases: j.array(j.object({ version: j.string() })) }),
|
|
209
|
+
}),
|
|
210
|
+
],
|
|
211
|
+
outputSchema: j.object({ prepared: j.integer() }),
|
|
212
|
+
handler: async (event) => {
|
|
213
|
+
return { prepared: event.input.releases.length };
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
190
218
|
## Resources created with the App
|
|
191
219
|
|
|
192
220
|
Use [Notion as Code](../notion-as-code/SKILL.md) for pages, databases, and custom agents
|
package/src/cli/build.test.ts
CHANGED
package/src/connections.test.ts
CHANGED
|
@@ -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
|
-
"
|
|
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
|
-
{
|
|
25
|
-
{
|
|
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("
|
|
32
|
+
).toThrow("permissions and readTeammatesCalendars");
|
|
32
33
|
});
|
|
33
34
|
it("rejects Calendar options on other providers", () => {
|
|
34
35
|
expect(() =>
|
|
35
36
|
normalizeConnectionRequirements({
|
|
36
|
-
work: {
|
|
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
|
-
|
|
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: {
|
|
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({
|
|
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: {
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
364
|
+
calendar: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
|
|
361
365
|
}).calendar.listCalendars({});
|
|
362
366
|
expect(result.accounts).toEqual([]);
|
|
363
367
|
expect(request).toHaveBeenCalledWith({
|
package/src/connections.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type WorkflowConnection<TProvider extends string = string> = {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export type CalendarConnectionOptions = {
|
|
20
|
-
|
|
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.
|
|
107
|
+
!["read", "read_write"].includes(options.permissions) ||
|
|
108
108
|
typeof options.readTeammatesCalendars !== "boolean"
|
|
109
109
|
) {
|
|
110
|
-
throw new Error(
|
|
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({
|
|
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({
|
|
35
|
+
calendar: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
|
|
36
36
|
support: connections.slack(),
|
|
37
37
|
team: connections.slack(),
|
|
38
38
|
};
|
package/src/workflow-schema.ts
CHANGED
|
@@ -2,16 +2,38 @@ import { Ajv } from "ajv";
|
|
|
2
2
|
import addFormats from "ajv-formats";
|
|
3
3
|
import { getSchema, type SchemaBuilder } from "./schema-builder.js";
|
|
4
4
|
|
|
5
|
+
type CompiledWorkflowSchema = {
|
|
6
|
+
jsonSchema: Record<string, unknown>;
|
|
7
|
+
validate: (value: unknown) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
5
10
|
/** @internal */
|
|
6
11
|
export function compileWorkflowInputSchema(
|
|
7
12
|
schema: SchemaBuilder<Record<string, unknown>, "object">,
|
|
8
|
-
): {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
): CompiledWorkflowSchema {
|
|
14
|
+
return compileWorkflowObjectSchema(schema, {
|
|
15
|
+
schemaName: "workflow manual inputSchema",
|
|
16
|
+
valueName: "manual workflow input",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** @internal */
|
|
21
|
+
export function compileWorkflowOutputSchema(
|
|
22
|
+
schema: SchemaBuilder<Record<string, unknown>, "object">,
|
|
23
|
+
): CompiledWorkflowSchema {
|
|
24
|
+
return compileWorkflowObjectSchema(schema, {
|
|
25
|
+
schemaName: "workflow outputSchema",
|
|
26
|
+
valueName: "workflow output",
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function compileWorkflowObjectSchema(
|
|
31
|
+
schema: SchemaBuilder<Record<string, unknown>, "object">,
|
|
32
|
+
names: { schemaName: string; valueName: string },
|
|
33
|
+
): CompiledWorkflowSchema {
|
|
12
34
|
const jsonSchema = getSchema(schema);
|
|
13
35
|
if (!("type" in jsonSchema) || jsonSchema.type !== "object") {
|
|
14
|
-
throw new Error(
|
|
36
|
+
throw new Error(`${names.schemaName}: must be a j.object() schema`);
|
|
15
37
|
}
|
|
16
38
|
const ajv = new Ajv({ allErrors: true, strict: true });
|
|
17
39
|
addFormats.default(ajv, {
|
|
@@ -31,11 +53,9 @@ export function compileWorkflowInputSchema(
|
|
|
31
53
|
const validate = ajv.compile(jsonSchema);
|
|
32
54
|
return {
|
|
33
55
|
jsonSchema,
|
|
34
|
-
validate(
|
|
35
|
-
if (!validate(
|
|
36
|
-
throw new Error(
|
|
37
|
-
`Invalid manual workflow input: ${ajv.errorsText(validate.errors)}`,
|
|
38
|
-
);
|
|
56
|
+
validate(value) {
|
|
57
|
+
if (!validate(value)) {
|
|
58
|
+
throw new Error(`Invalid ${names.valueName}: ${ajv.errorsText(validate.errors)}`);
|
|
39
59
|
}
|
|
40
60
|
},
|
|
41
61
|
};
|
|
@@ -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({
|
|
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({
|
|
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({
|
|
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({
|
|
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({
|
|
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({}); }',
|
|
@@ -228,6 +228,47 @@ it("checks provider keys on callback arguments and returned triggers", () => {
|
|
|
228
228
|
trigger: "events.notionPageCreated()",
|
|
229
229
|
handler: '(_event, ctx) => { ctx.connections.oauth("github"); }',
|
|
230
230
|
},
|
|
231
|
+
{
|
|
232
|
+
name: "output_async",
|
|
233
|
+
valid: true,
|
|
234
|
+
trigger: "events.manual()",
|
|
235
|
+
outputSchema: "j.object({ url: j.string(), draft: j.boolean().nullable() })",
|
|
236
|
+
handler: 'async () => ({ url: "https://example.com", draft: null })',
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: "output_sync",
|
|
240
|
+
valid: true,
|
|
241
|
+
trigger: "events.manual()",
|
|
242
|
+
outputSchema: "j.object({ url: j.string() })",
|
|
243
|
+
handler: '() => ({ url: "https://example.com" })',
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: "output_mismatch",
|
|
247
|
+
valid: false,
|
|
248
|
+
trigger: "events.manual()",
|
|
249
|
+
outputSchema: "j.object({ url: j.string() })",
|
|
250
|
+
handler: "async () => ({ url: 1 })",
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "output_missing_value",
|
|
254
|
+
valid: false,
|
|
255
|
+
trigger: "events.manual()",
|
|
256
|
+
outputSchema: "j.object({ url: j.string() })",
|
|
257
|
+
handler: "async () => {}",
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
name: "output_requires_object_schema",
|
|
261
|
+
valid: false,
|
|
262
|
+
trigger: "events.manual()",
|
|
263
|
+
outputSchema: "j.string()",
|
|
264
|
+
handler: '() => "https://example.com"',
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "output_absent_returns_void",
|
|
268
|
+
valid: false,
|
|
269
|
+
trigger: "events.manual()",
|
|
270
|
+
handler: 'async () => ({ url: "https://example.com" })',
|
|
271
|
+
},
|
|
231
272
|
];
|
|
232
273
|
const fixtures = new Map(
|
|
233
274
|
cases.map((testCase) => [
|
|
@@ -240,6 +281,7 @@ it("checks provider keys on callback arguments and returned triggers", () => {
|
|
|
240
281
|
workflow({
|
|
241
282
|
name: "Type check", description: "Type check",
|
|
242
283
|
${testCase.connections === undefined ? "" : `connections: ${testCase.connections},`}
|
|
284
|
+
${testCase.outputSchema === undefined ? "" : `outputSchema: ${testCase.outputSchema},`}
|
|
243
285
|
triggers: ({ events }) => [${testCase.trigger}],
|
|
244
286
|
handler: ${testCase.handler ?? "() => {}"},
|
|
245
287
|
});`,
|
package/src/workflow.test.ts
CHANGED
|
@@ -125,6 +125,111 @@ describe("manual workflow triggers", () => {
|
|
|
125
125
|
});
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
+
describe("workflow output schemas", () => {
|
|
129
|
+
const outputSchema = j.object({ url: j.string(), publishedAt: j.datetime().nullable() });
|
|
130
|
+
|
|
131
|
+
it("records the output JSON Schema in the workflow config", () => {
|
|
132
|
+
const definition = workflow({
|
|
133
|
+
name: "Publish release",
|
|
134
|
+
description: "Publishes a release",
|
|
135
|
+
triggers: [events.manual()],
|
|
136
|
+
outputSchema,
|
|
137
|
+
handler: () => ({ url: "https://example.com", publishedAt: null }),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(definition.config.outputJsonSchema).toEqual({
|
|
141
|
+
type: "object",
|
|
142
|
+
required: ["url", "publishedAt"],
|
|
143
|
+
additionalProperties: false,
|
|
144
|
+
properties: {
|
|
145
|
+
url: { type: "string" },
|
|
146
|
+
publishedAt: { anyOf: [{ type: "string", format: "date-time" }, { type: "null" }] },
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("omits the output schema and output when none is declared", async () => {
|
|
152
|
+
const definition = workflow({
|
|
153
|
+
name: "Log pages",
|
|
154
|
+
description: "Logs created pages",
|
|
155
|
+
triggers: [events.notionPageCreated()],
|
|
156
|
+
handler: () => {},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
expect(definition.config).not.toHaveProperty("outputJsonSchema");
|
|
160
|
+
await expect(definition.handler(event, { concreteOutput: true })).resolves.toEqual({
|
|
161
|
+
status: "success",
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("returns the output in the success envelope", async () => {
|
|
166
|
+
const definition = workflow({
|
|
167
|
+
name: "Publish release",
|
|
168
|
+
description: "Publishes a release",
|
|
169
|
+
triggers: [events.manual()],
|
|
170
|
+
outputSchema,
|
|
171
|
+
handler: async () => ({
|
|
172
|
+
url: "https://example.com",
|
|
173
|
+
publishedAt: "2026-09-28T00:00:00.000Z",
|
|
174
|
+
}),
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
await definition.handler({ type: "workflow.manual", input: {} });
|
|
178
|
+
|
|
179
|
+
expect(stdoutSpy).toHaveBeenLastCalledWith(
|
|
180
|
+
`\n<__notion_output__>${JSON.stringify({
|
|
181
|
+
_tag: "success",
|
|
182
|
+
value: {
|
|
183
|
+
status: "success",
|
|
184
|
+
output: { url: "https://example.com", publishedAt: "2026-09-28T00:00:00.000Z" },
|
|
185
|
+
},
|
|
186
|
+
})}</__notion_output__>\n`,
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it.each([
|
|
191
|
+
{ name: "a missing value", output: undefined },
|
|
192
|
+
{ name: "a wrong type", output: { url: 1, publishedAt: null } },
|
|
193
|
+
{ name: "an extra key", output: { url: "https://example.com", publishedAt: null, id: 1 } },
|
|
194
|
+
{
|
|
195
|
+
name: "more than 256 KB of JSON",
|
|
196
|
+
output: { url: "x".repeat(256 * 1024), publishedAt: null },
|
|
197
|
+
},
|
|
198
|
+
])("fails without retrying when the handler returns $name", async ({ output }) => {
|
|
199
|
+
const definition = workflow({
|
|
200
|
+
name: "Publish release",
|
|
201
|
+
description: "Publishes a release",
|
|
202
|
+
triggers: [events.manual()],
|
|
203
|
+
outputSchema,
|
|
204
|
+
// SAFETY: Simulates untyped handler code returning a value outside the schema.
|
|
205
|
+
handler: () => output as never,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
await expect(
|
|
209
|
+
definition.handler({ type: "workflow.manual", input: {} }),
|
|
210
|
+
).rejects.toMatchObject({
|
|
211
|
+
cause: expect.objectContaining({
|
|
212
|
+
name: "FatalError",
|
|
213
|
+
message: expect.stringContaining("Invalid workflow output"),
|
|
214
|
+
}),
|
|
215
|
+
});
|
|
216
|
+
expect(String(stdoutSpy.mock.lastCall?.[0])).toContain('"_tag":"terminal"');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("rejects an output schema that is not an object schema", () => {
|
|
220
|
+
expect(() =>
|
|
221
|
+
workflow({
|
|
222
|
+
name: "Publish release",
|
|
223
|
+
description: "Publishes a release",
|
|
224
|
+
triggers: [events.manual()],
|
|
225
|
+
// SAFETY: Simulates untyped app code passing a non-object schema.
|
|
226
|
+
outputSchema: j.string() as never,
|
|
227
|
+
handler: (() => {}) as never,
|
|
228
|
+
}),
|
|
229
|
+
).toThrow("workflow outputSchema: must be a j.object() schema");
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
128
233
|
async function createWorkflowContext(
|
|
129
234
|
retry?: WorkflowRetryPolicy,
|
|
130
235
|
): Promise<WorkflowContext<Record<never, never>>> {
|
|
@@ -1703,7 +1808,10 @@ describe("workflow", () => {
|
|
|
1703
1808
|
description: "Schedules a follow-up after a page is created",
|
|
1704
1809
|
triggers: [events.notionPageCreated()],
|
|
1705
1810
|
connections: {
|
|
1706
|
-
calendar: connections.calendar({
|
|
1811
|
+
calendar: connections.calendar({
|
|
1812
|
+
permissions: "read",
|
|
1813
|
+
readTeammatesCalendars: false,
|
|
1814
|
+
}),
|
|
1707
1815
|
},
|
|
1708
1816
|
handler: () => {},
|
|
1709
1817
|
});
|
|
@@ -1712,7 +1820,7 @@ describe("workflow", () => {
|
|
|
1712
1820
|
{
|
|
1713
1821
|
type: "calendar",
|
|
1714
1822
|
key: "calendar",
|
|
1715
|
-
calendar: {
|
|
1823
|
+
calendar: { permissions: "read", readTeammatesCalendars: false },
|
|
1716
1824
|
},
|
|
1717
1825
|
]);
|
|
1718
1826
|
});
|
|
@@ -1730,7 +1838,7 @@ describe("workflow", () => {
|
|
|
1730
1838
|
},
|
|
1731
1839
|
});
|
|
1732
1840
|
Object.assign(declarations, {
|
|
1733
|
-
support: connections.calendar({
|
|
1841
|
+
support: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
|
|
1734
1842
|
team: connections.slack(),
|
|
1735
1843
|
});
|
|
1736
1844
|
expect(definition.config.connections).toEqual([{ type: "slack", key: "support" }]);
|
|
@@ -1740,7 +1848,7 @@ describe("workflow", () => {
|
|
|
1740
1848
|
it("rejects inherited declaration objects before cloning", () => {
|
|
1741
1849
|
const declarations = { support: connections.slack() };
|
|
1742
1850
|
Object.setPrototypeOf(declarations, {
|
|
1743
|
-
extra: connections.calendar({
|
|
1851
|
+
extra: connections.calendar({ permissions: "read", readTeammatesCalendars: false }),
|
|
1744
1852
|
});
|
|
1745
1853
|
expect(() =>
|
|
1746
1854
|
workflow({
|
|
@@ -1761,7 +1869,7 @@ describe("workflow", () => {
|
|
|
1761
1869
|
triggers: [events.notionPageCreated()],
|
|
1762
1870
|
connections: {
|
|
1763
1871
|
"bad/key": connections.calendar({
|
|
1764
|
-
|
|
1872
|
+
permissions: "read",
|
|
1765
1873
|
readTeammatesCalendars: false,
|
|
1766
1874
|
}),
|
|
1767
1875
|
},
|
|
@@ -2031,7 +2139,10 @@ describe("connection-bound triggers", () => {
|
|
|
2031
2139
|
description: "Uses only declared provider keys",
|
|
2032
2140
|
connections: {
|
|
2033
2141
|
support: connections.slack(),
|
|
2034
|
-
calendar: connections.calendar({
|
|
2142
|
+
calendar: connections.calendar({
|
|
2143
|
+
permissions: "read",
|
|
2144
|
+
readTeammatesCalendars: false,
|
|
2145
|
+
}),
|
|
2035
2146
|
},
|
|
2036
2147
|
triggers: ({ events }) => {
|
|
2037
2148
|
calls += 1;
|
|
@@ -2083,7 +2194,10 @@ describe("connection-bound triggers", () => {
|
|
|
2083
2194
|
{ requirements: {} },
|
|
2084
2195
|
{
|
|
2085
2196
|
requirements: {
|
|
2086
|
-
support: connections.calendar({
|
|
2197
|
+
support: connections.calendar({
|
|
2198
|
+
permissions: "read",
|
|
2199
|
+
readTeammatesCalendars: false,
|
|
2200
|
+
}),
|
|
2087
2201
|
},
|
|
2088
2202
|
},
|
|
2089
2203
|
{ requirements: { other: connections.slack() } },
|
package/src/workflow.ts
CHANGED
|
@@ -24,6 +24,8 @@ import { writeOutput } from "./output.js";
|
|
|
24
24
|
import { resolveRuntimeInput } from "./runtime-input.js";
|
|
25
25
|
import { readRunMetadata, type RunMetadata } from "./runtime-metadata.js";
|
|
26
26
|
import { createWorkflowEvents, validateManualWorkflowInput } from "./events.generated.js";
|
|
27
|
+
import type { Infer, SchemaBuilder } from "./schema-builder.js";
|
|
28
|
+
import { compileWorkflowOutputSchema } from "./workflow-schema.js";
|
|
27
29
|
import { createWorkflowStepState, type WorkflowState } from "./workflow-state.js";
|
|
28
30
|
import type {
|
|
29
31
|
ManualWorkflowTrigger,
|
|
@@ -183,7 +185,21 @@ export type WorkflowWaitForInputResult = {
|
|
|
183
185
|
|
|
184
186
|
type WorkflowWaitResult = WorkflowWaitUntilResult | WorkflowWaitForInputResult;
|
|
185
187
|
|
|
186
|
-
type WorkflowHandlerResult =
|
|
188
|
+
type WorkflowHandlerResult =
|
|
189
|
+
| { status: "success"; output?: Record<string, unknown> }
|
|
190
|
+
| WorkflowWaitResult;
|
|
191
|
+
|
|
192
|
+
/** An object schema describing the value a workflow returns. */
|
|
193
|
+
export type WorkflowOutputSchema = SchemaBuilder<Record<string, unknown>, "object">;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* What a workflow handler returns: the value described by `outputSchema`, or
|
|
197
|
+
* nothing when the workflow declares no output schema.
|
|
198
|
+
*/
|
|
199
|
+
export type WorkflowHandlerReturn<TOutputSchema extends WorkflowOutputSchema | undefined> =
|
|
200
|
+
TOutputSchema extends WorkflowOutputSchema
|
|
201
|
+
? Promise<Infer<TOutputSchema>> | Infer<TOutputSchema>
|
|
202
|
+
: Promise<void> | void;
|
|
187
203
|
|
|
188
204
|
const MAX_WORKFLOW_WAIT_MS = 7 * 24 * 60 * 60 * 1_000;
|
|
189
205
|
export { FatalError, RetryableError } from "./error.js";
|
|
@@ -355,6 +371,7 @@ export type WorkflowConfiguration<
|
|
|
355
371
|
TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]],
|
|
356
372
|
TConnections extends WorkflowConnectionDeclarations = WorkflowConnectionDeclarations,
|
|
357
373
|
TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations,
|
|
374
|
+
TOutputSchema extends WorkflowOutputSchema | undefined = undefined,
|
|
358
375
|
> = {
|
|
359
376
|
/**
|
|
360
377
|
* A human-readable name for the workflow, shown in the UI when viewing workflows
|
|
@@ -428,10 +445,25 @@ export type WorkflowConfiguration<
|
|
|
428
445
|
*/
|
|
429
446
|
verify?: WebhookVerifyHandler;
|
|
430
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Optional schema for the object the handler returns, built with
|
|
450
|
+
* `@notionhq/apps/schema-builder`. The handler's return type is inferred
|
|
451
|
+
* from it, and the returned value is validated before the run succeeds.
|
|
452
|
+
*
|
|
453
|
+
* Without `outputSchema`, the workflow returns nothing.
|
|
454
|
+
*
|
|
455
|
+
* @example
|
|
456
|
+
* ```ts
|
|
457
|
+
* outputSchema: j.object({ releaseUrl: j.string() }),
|
|
458
|
+
* handler: async () => ({ releaseUrl: "https://example.com/releases/1" }),
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
outputSchema?: TOutputSchema;
|
|
462
|
+
|
|
431
463
|
handler: (
|
|
432
464
|
event: WorkflowEventForTriggers<TTriggers>,
|
|
433
465
|
context: WorkflowContext<TConnections, TAccess>,
|
|
434
|
-
) =>
|
|
466
|
+
) => WorkflowHandlerReturn<NoInfer<TOutputSchema>>;
|
|
435
467
|
};
|
|
436
468
|
|
|
437
469
|
/** Configuration that checks trigger keys against declared connections. */
|
|
@@ -439,7 +471,8 @@ export type WorkflowTriggerConfiguration<
|
|
|
439
471
|
TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]],
|
|
440
472
|
TConnections extends WorkflowConnectionDeclarations,
|
|
441
473
|
TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations,
|
|
442
|
-
|
|
474
|
+
TOutputSchema extends WorkflowOutputSchema | undefined = undefined,
|
|
475
|
+
> = Omit<WorkflowConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>, "triggers"> & {
|
|
443
476
|
triggers: (context: { events: WorkflowEventCreators<NoInfer<TConnections>> }) => TTriggers;
|
|
444
477
|
};
|
|
445
478
|
|
|
@@ -464,6 +497,8 @@ export type Workflow<
|
|
|
464
497
|
access?: WorkflowAccessRequirements;
|
|
465
498
|
deadline?: WorkflowDeadline;
|
|
466
499
|
retry?: WorkflowRetryPolicy;
|
|
500
|
+
/** JSON Schema for the handler's return value. Absent when the workflow returns nothing. */
|
|
501
|
+
outputJsonSchema?: Record<string, unknown>;
|
|
467
502
|
};
|
|
468
503
|
handler: (
|
|
469
504
|
input: WorkflowEventForTriggers<TTriggers> | WebhookVerifyInvocation,
|
|
@@ -504,22 +539,27 @@ export function workflow<
|
|
|
504
539
|
],
|
|
505
540
|
const TConnections extends WorkflowConnectionDeclarations = Record<never, never>,
|
|
506
541
|
const TAccess extends WorkflowAccessDeclarations = Record<never, never>,
|
|
542
|
+
const TOutputSchema extends WorkflowOutputSchema | undefined = undefined,
|
|
507
543
|
>(
|
|
508
|
-
configuration: WorkflowTriggerConfiguration<TTriggers, TConnections, TAccess>,
|
|
544
|
+
configuration: WorkflowTriggerConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>,
|
|
509
545
|
): Workflow<TTriggers>;
|
|
510
546
|
export function workflow<
|
|
511
547
|
const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]],
|
|
512
548
|
const TConnections extends WorkflowConnectionDeclarations = Record<never, never>,
|
|
513
549
|
const TAccess extends WorkflowAccessDeclarations = Record<never, never>,
|
|
514
|
-
|
|
550
|
+
const TOutputSchema extends WorkflowOutputSchema | undefined = undefined,
|
|
551
|
+
>(
|
|
552
|
+
configuration: WorkflowConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>,
|
|
553
|
+
): Workflow<TTriggers>;
|
|
515
554
|
export function workflow<
|
|
516
555
|
const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]],
|
|
517
556
|
const TConnections extends WorkflowConnectionDeclarations = Record<never, never>,
|
|
518
557
|
const TAccess extends WorkflowAccessDeclarations = Record<never, never>,
|
|
558
|
+
const TOutputSchema extends WorkflowOutputSchema | undefined = undefined,
|
|
519
559
|
>(
|
|
520
560
|
configuration:
|
|
521
|
-
| WorkflowConfiguration<TTriggers, TConnections, TAccess>
|
|
522
|
-
| WorkflowTriggerConfiguration<TTriggers, TConnections, TAccess>,
|
|
561
|
+
| WorkflowConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>
|
|
562
|
+
| WorkflowTriggerConfiguration<TTriggers, TConnections, TAccess, TOutputSchema>,
|
|
523
563
|
): Workflow<TTriggers> {
|
|
524
564
|
const requirements = normalizeConnectionRequirements(configuration.connections ?? {});
|
|
525
565
|
const accessRequirements = normalizeWorkflowAccess(configuration.access);
|
|
@@ -541,6 +581,10 @@ export function workflow<
|
|
|
541
581
|
configuration.deadline === undefined ? undefined : structuredClone(configuration.deadline);
|
|
542
582
|
const retry =
|
|
543
583
|
configuration.retry === undefined ? undefined : manifestRetryPolicy(configuration.retry);
|
|
584
|
+
const outputSchema =
|
|
585
|
+
configuration.outputSchema === undefined
|
|
586
|
+
? undefined
|
|
587
|
+
: compileWorkflowOutputSchema(configuration.outputSchema);
|
|
544
588
|
|
|
545
589
|
const manualTriggers = triggers.filter(
|
|
546
590
|
(trigger): trigger is ManualWorkflowTrigger => trigger.type === "workflow.manual",
|
|
@@ -569,6 +613,7 @@ export function workflow<
|
|
|
569
613
|
...(configuration.access === undefined ? {} : { access: accessRequirements }),
|
|
570
614
|
...(deadline === undefined ? {} : { deadline }),
|
|
571
615
|
...(retry === undefined ? {} : { retry }),
|
|
616
|
+
...(outputSchema === undefined ? {} : { outputJsonSchema: outputSchema.jsonSchema }),
|
|
572
617
|
},
|
|
573
618
|
async handler(
|
|
574
619
|
input: WorkflowEventForTriggers<TTriggers> | WebhookVerifyInvocation,
|
|
@@ -630,13 +675,26 @@ export function workflow<
|
|
|
630
675
|
}
|
|
631
676
|
validateManualWorkflowInput(manualTrigger, event.input);
|
|
632
677
|
}
|
|
633
|
-
await configuration.handler(
|
|
678
|
+
const handlerOutput: unknown = await configuration.handler(
|
|
679
|
+
event,
|
|
680
|
+
capabilityContext,
|
|
681
|
+
);
|
|
682
|
+
const result: WorkflowHandlerResult =
|
|
683
|
+
outputSchema === undefined
|
|
684
|
+
? { status: "success" }
|
|
685
|
+
: {
|
|
686
|
+
status: "success",
|
|
687
|
+
output: serializeWorkflowOutput(
|
|
688
|
+
handlerOutput,
|
|
689
|
+
outputSchema.validate,
|
|
690
|
+
),
|
|
691
|
+
};
|
|
634
692
|
|
|
635
693
|
if (options?.concreteOutput) {
|
|
636
|
-
return
|
|
694
|
+
return result;
|
|
637
695
|
}
|
|
638
696
|
|
|
639
|
-
writeOutput({ _tag: "success", value:
|
|
697
|
+
writeOutput({ _tag: "success", value: result });
|
|
640
698
|
} catch (err) {
|
|
641
699
|
if (err instanceof WorkflowWaitInterrupt) {
|
|
642
700
|
if (options?.concreteOutput) {
|
|
@@ -721,6 +779,37 @@ function manifestTriggers(
|
|
|
721
779
|
);
|
|
722
780
|
}
|
|
723
781
|
|
|
782
|
+
/** The platform stores workflow output with its run, so it must stay small. */
|
|
783
|
+
const MAX_WORKFLOW_OUTPUT_BYTES = 256 * 1024;
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* Validates the JSON the platform will receive rather than the in-memory value,
|
|
787
|
+
* so values that change during serialization, such as `Date` or `toJSON`
|
|
788
|
+
* objects, are checked in the form callers will see.
|
|
789
|
+
*
|
|
790
|
+
* A mismatch is a bug in the handler, so it fails the run without retrying.
|
|
791
|
+
*/
|
|
792
|
+
function serializeWorkflowOutput(
|
|
793
|
+
value: unknown,
|
|
794
|
+
validate: (value: unknown) => void,
|
|
795
|
+
): Record<string, unknown> {
|
|
796
|
+
try {
|
|
797
|
+
const json = value === undefined ? undefined : JSON.stringify(value);
|
|
798
|
+
const bytes = json === undefined ? 0 : Buffer.byteLength(json, "utf8");
|
|
799
|
+
if (bytes > MAX_WORKFLOW_OUTPUT_BYTES) {
|
|
800
|
+
throw new Error(
|
|
801
|
+
`Invalid workflow output: must be at most ${MAX_WORKFLOW_OUTPUT_BYTES} bytes as JSON, got ${bytes}.`,
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
const serialized: unknown = json === undefined ? undefined : JSON.parse(json);
|
|
805
|
+
validate(serialized);
|
|
806
|
+
// SAFETY: validate only accepts values matching the j.object() output schema.
|
|
807
|
+
return serialized as Record<string, unknown>;
|
|
808
|
+
} catch (error) {
|
|
809
|
+
throw new FatalError(error instanceof Error ? error.message : String(error));
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
724
813
|
/**
|
|
725
814
|
* Whether an invocation is the platform's synchronous verify dispatch. The
|
|
726
815
|
* platform sends workflow invocations as a trigger event and verify
|