@notionhq/workers 0.4.0 → 0.6.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.
- package/dist/alpha/builder.d.ts +149 -0
- package/dist/alpha/builder.d.ts.map +1 -0
- package/dist/alpha/builder.js +260 -0
- package/dist/alpha/builder.test.d.ts +2 -0
- package/dist/alpha/builder.test.d.ts.map +1 -0
- package/dist/alpha/cli/build.d.ts +13 -0
- package/dist/alpha/cli/build.d.ts.map +1 -0
- package/dist/alpha/cli/build.js +36 -0
- package/dist/alpha/cli/build.test.d.ts +2 -0
- package/dist/alpha/cli/build.test.d.ts.map +1 -0
- package/dist/alpha/cli/codegen.d.ts +10 -0
- package/dist/alpha/cli/codegen.d.ts.map +1 -0
- package/dist/alpha/cli/codegen.js +41 -0
- package/dist/alpha/cli/codegen.test.d.ts +2 -0
- package/dist/alpha/cli/codegen.test.d.ts.map +1 -0
- package/dist/alpha/cli/discover.d.ts +35 -0
- package/dist/alpha/cli/discover.d.ts.map +1 -0
- package/dist/alpha/cli/discover.js +39 -0
- package/dist/alpha/cli/discover.test.d.ts +2 -0
- package/dist/alpha/cli/discover.test.d.ts.map +1 -0
- package/dist/alpha/cli/emit-manifest.d.ts +33 -0
- package/dist/alpha/cli/emit-manifest.d.ts.map +1 -0
- package/dist/alpha/cli/emit-manifest.js +266 -0
- package/dist/alpha/cli/emit-manifest.test.d.ts +2 -0
- package/dist/alpha/cli/emit-manifest.test.d.ts.map +1 -0
- package/dist/alpha/cli/index.d.ts +3 -0
- package/dist/alpha/cli/index.d.ts.map +1 -0
- package/dist/alpha/cli/index.js +36 -0
- package/dist/alpha/context.d.ts +8 -0
- package/dist/alpha/context.d.ts.map +1 -0
- package/dist/alpha/context.js +33 -0
- package/dist/alpha/database.d.ts +90 -0
- package/dist/alpha/database.d.ts.map +1 -0
- package/dist/alpha/database.js +9 -0
- package/dist/alpha/error.d.ts +41 -0
- package/dist/alpha/error.d.ts.map +1 -0
- package/dist/alpha/error.js +25 -0
- package/dist/alpha/icon-names.d.ts +6 -0
- package/dist/alpha/icon-names.d.ts.map +1 -0
- package/dist/alpha/icon-names.js +0 -0
- package/dist/alpha/json-schema.d.ts +117 -0
- package/dist/alpha/json-schema.d.ts.map +1 -0
- package/dist/alpha/json-schema.js +0 -0
- package/dist/alpha/manifest.d.ts +44 -0
- package/dist/alpha/manifest.d.ts.map +1 -0
- package/dist/alpha/manifest.js +0 -0
- package/dist/alpha/output.d.ts +7 -0
- package/dist/alpha/output.d.ts.map +1 -0
- package/dist/alpha/output.js +8 -0
- package/dist/alpha/pacer.d.ts +74 -0
- package/dist/alpha/pacer.d.ts.map +1 -0
- package/dist/alpha/pacer.js +66 -0
- package/dist/alpha/pacer.test.d.ts +2 -0
- package/dist/alpha/pacer.test.d.ts.map +1 -0
- package/dist/alpha/schedule.d.ts +6 -0
- package/dist/alpha/schedule.d.ts.map +1 -0
- package/dist/alpha/schedule.js +43 -0
- package/dist/alpha/schedule.test.d.ts +2 -0
- package/dist/alpha/schedule.test.d.ts.map +1 -0
- package/dist/alpha/schema-builder.d.ts +79 -0
- package/dist/alpha/schema-builder.d.ts.map +1 -0
- package/dist/alpha/schema-builder.js +135 -0
- package/dist/alpha/schema.d.ts +185 -0
- package/dist/alpha/schema.d.ts.map +1 -0
- package/dist/alpha/schema.js +115 -0
- package/dist/alpha/sync.d.ts +233 -0
- package/dist/alpha/sync.d.ts.map +1 -0
- package/dist/alpha/sync.js +70 -0
- package/dist/alpha/sync.test.d.ts +2 -0
- package/dist/alpha/sync.test.d.ts.map +1 -0
- package/dist/alpha/tool.d.ts +132 -0
- package/dist/alpha/tool.d.ts.map +1 -0
- package/dist/alpha/tool.js +156 -0
- package/dist/alpha/tool.test.d.ts +2 -0
- package/dist/alpha/tool.test.d.ts.map +1 -0
- package/dist/alpha/triggers.d.ts +365 -0
- package/dist/alpha/triggers.d.ts.map +1 -0
- package/dist/alpha/triggers.generated.d.ts +246 -0
- package/dist/alpha/triggers.generated.d.ts.map +1 -0
- package/dist/alpha/triggers.generated.js +239 -0
- package/dist/alpha/triggers.js +0 -0
- package/dist/alpha/types.d.ts +228 -0
- package/dist/alpha/types.d.ts.map +1 -0
- package/dist/alpha/types.js +0 -0
- package/dist/alpha/workflow.d.ts +70 -0
- package/dist/alpha/workflow.d.ts.map +1 -0
- package/dist/alpha/workflow.js +39 -0
- package/dist/alpha/workflow.test.d.ts +2 -0
- package/dist/alpha/workflow.test.d.ts.map +1 -0
- package/dist/builder.d.ts +7 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +12 -3
- package/dist/capabilities/ai_connector.d.ts.map +1 -1
- package/dist/capabilities/automation.d.ts.map +1 -1
- package/dist/capabilities/context.d.ts.map +1 -1
- package/dist/capabilities/context.js +1 -1
- package/dist/capabilities/custom-block.d.ts +124 -0
- package/dist/capabilities/custom-block.d.ts.map +1 -0
- package/dist/capabilities/custom-block.js +22 -0
- package/dist/capabilities/oauth.d.ts.map +1 -1
- package/dist/capabilities/output.d.ts.map +1 -1
- package/dist/capabilities/output.js +2 -4
- package/dist/capabilities/stateful-capability.d.ts.map +1 -1
- package/dist/capabilities/stateful-capability.js +3 -7
- package/dist/capabilities/sync.d.ts +11 -1
- package/dist/capabilities/sync.d.ts.map +1 -1
- package/dist/capabilities/sync.js +2 -8
- package/dist/capabilities/tool.d.ts.map +1 -1
- package/dist/capabilities/tool.js +6 -20
- package/dist/capabilities/webhook.d.ts.map +1 -1
- package/dist/capabilities/workflow.d.ts +50 -0
- package/dist/capabilities/workflow.d.ts.map +1 -0
- package/dist/capabilities/workflow.js +40 -0
- package/dist/capabilities/workflow.test.d.ts +2 -0
- package/dist/capabilities/workflow.test.d.ts.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/json-schema.d.ts.map +1 -1
- package/dist/schema-builder.d.ts.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/triggers.d.ts +365 -0
- package/dist/triggers.d.ts.map +1 -0
- package/dist/triggers.generated.d.ts +246 -0
- package/dist/triggers.generated.d.ts.map +1 -0
- package/dist/triggers.generated.js +239 -0
- package/dist/triggers.js +0 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/worker.d.ts +72 -2
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +85 -4
- package/package.json +81 -14
- package/src/alpha/ajv-formats.d.ts +7 -0
- package/src/alpha/builder.test.ts +197 -0
- package/src/alpha/builder.ts +338 -0
- package/src/alpha/cli/build.test.ts +240 -0
- package/src/alpha/cli/build.ts +57 -0
- package/src/alpha/cli/codegen.test.ts +31 -0
- package/src/alpha/cli/codegen.ts +51 -0
- package/src/alpha/cli/discover.test.ts +43 -0
- package/src/alpha/cli/discover.ts +81 -0
- package/src/alpha/cli/emit-manifest.test.ts +45 -0
- package/src/alpha/cli/emit-manifest.ts +409 -0
- package/src/alpha/cli/index.ts +41 -0
- package/src/alpha/context.ts +61 -0
- package/src/alpha/database.ts +102 -0
- package/src/alpha/error.ts +49 -0
- package/src/alpha/icon-names.ts +890 -0
- package/src/alpha/json-schema.ts +180 -0
- package/src/alpha/manifest.ts +47 -0
- package/src/alpha/output.ts +8 -0
- package/src/alpha/pacer.test.ts +81 -0
- package/src/alpha/pacer.ts +181 -0
- package/src/alpha/schedule.test.ts +31 -0
- package/src/alpha/schedule.ts +53 -0
- package/src/alpha/schema-builder.ts +193 -0
- package/src/alpha/schema.ts +222 -0
- package/src/alpha/sync.test.ts +191 -0
- package/src/alpha/sync.ts +340 -0
- package/src/alpha/tool.test.ts +116 -0
- package/src/alpha/tool.ts +319 -0
- package/src/alpha/triggers.generated.ts +489 -0
- package/src/alpha/triggers.ts +500 -0
- package/src/alpha/types.ts +284 -0
- package/src/alpha/workflow.test.ts +84 -0
- package/src/alpha/workflow.ts +131 -0
- package/src/builder.test.ts +28 -60
- package/src/builder.ts +20 -7
- package/src/capabilities/ai_connector.test.ts +9 -32
- package/src/capabilities/ai_connector.ts +5 -17
- package/src/capabilities/automation.test.ts +3 -12
- package/src/capabilities/automation.ts +3 -11
- package/src/capabilities/context.ts +5 -8
- package/src/capabilities/custom-block.ts +181 -0
- package/src/capabilities/oauth.test.ts +1 -0
- package/src/capabilities/oauth.ts +1 -3
- package/src/capabilities/output.ts +1 -3
- package/src/capabilities/stateful-capability.test.ts +1 -0
- package/src/capabilities/stateful-capability.ts +3 -7
- package/src/capabilities/sync.test.ts +76 -42
- package/src/capabilities/sync.ts +16 -40
- package/src/capabilities/tool.test.ts +106 -146
- package/src/capabilities/tool.ts +17 -39
- package/src/capabilities/webhook.ts +3 -10
- package/src/capabilities/workflow.test.ts +163 -0
- package/src/capabilities/workflow.ts +112 -0
- package/src/index.ts +18 -6
- package/src/json-schema.test.ts +2 -4
- package/src/json-schema.ts +7 -6
- package/src/pacer.test.ts +1 -3
- package/src/pacer_internal.ts +1 -5
- package/src/schema-builder.test.ts +10 -35
- package/src/schema-builder.ts +6 -16
- package/src/schema.ts +2 -10
- package/src/triggers.generated.ts +489 -0
- package/src/triggers.ts +504 -0
- package/src/types.ts +21 -7
- package/src/worker.test.ts +147 -0
- package/src/worker.ts +155 -32
- package/dist/block.d.ts +0 -321
- package/dist/block.d.ts.map +0 -1
- package/src/block.ts +0 -529
- /package/dist/{block.js → alpha/ajv-formats.d.js} +0 -0
package/src/builder.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NoticonName } from "./icon-names.js";
|
|
2
2
|
import type {
|
|
3
|
+
Cover,
|
|
3
4
|
DateValue,
|
|
4
5
|
Icon,
|
|
5
6
|
NoticonColor,
|
|
@@ -233,9 +234,7 @@ export function relation(primaryKey: string): RelationReference {
|
|
|
233
234
|
*/
|
|
234
235
|
function validateDateString(dateString: string): void {
|
|
235
236
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
|
|
236
|
-
throw new Error(
|
|
237
|
-
`Invalid date format: ${dateString}. Expected YYYY-MM-DD format.`,
|
|
238
|
-
);
|
|
237
|
+
throw new Error(`Invalid date format: ${dateString}. Expected YYYY-MM-DD format.`);
|
|
239
238
|
}
|
|
240
239
|
|
|
241
240
|
const date = new Date(dateString);
|
|
@@ -289,10 +288,7 @@ export function emojiIcon(emoji: string): Icon {
|
|
|
289
288
|
* @param icon - The name of the Notion icon (e.g., "checkmark", "pizza", "rocket")
|
|
290
289
|
* @param color - The color variant (defaults to "gray")
|
|
291
290
|
*/
|
|
292
|
-
export function notionIcon(
|
|
293
|
-
icon: NoticonName,
|
|
294
|
-
color: NoticonColor = "gray",
|
|
295
|
-
): Icon {
|
|
291
|
+
export function notionIcon(icon: NoticonName, color: NoticonColor = "gray"): Icon {
|
|
296
292
|
return {
|
|
297
293
|
type: "notion",
|
|
298
294
|
icon,
|
|
@@ -310,3 +306,20 @@ export function imageIcon(url: string): Icon {
|
|
|
310
306
|
url,
|
|
311
307
|
};
|
|
312
308
|
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Creates an image cover from an external URL.
|
|
312
|
+
* @param url - The URL of the image (e.g., "https://example.com/cover.png")
|
|
313
|
+
* @param position - Vertical image position, from 0 (top) to 1 (bottom). Defaults to 0.5.
|
|
314
|
+
*/
|
|
315
|
+
export function imageCover(url: string, position = 0.5): Cover {
|
|
316
|
+
if (!Number.isFinite(position) || position < 0 || position > 1) {
|
|
317
|
+
throw new Error(`Invalid cover position: ${position}. Expected a number between 0 and 1.`);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
type: "image",
|
|
322
|
+
url,
|
|
323
|
+
position,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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 { ExecutionError } from "../error.js";
|
|
11
4
|
import { getPacerState } from "../pacer_internal.js";
|
|
12
5
|
import { Worker } from "../worker.js";
|
|
@@ -17,9 +10,7 @@ describe("Worker.aiConnector", () => {
|
|
|
17
10
|
let stdoutSpy: Mock<typeof process.stdout.write>;
|
|
18
11
|
|
|
19
12
|
beforeEach(() => {
|
|
20
|
-
stdoutSpy = vi
|
|
21
|
-
.spyOn(process.stdout, "write")
|
|
22
|
-
.mockImplementation(() => true);
|
|
13
|
+
stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
|
23
14
|
});
|
|
24
15
|
|
|
25
16
|
afterEach(() => {
|
|
@@ -86,12 +77,8 @@ describe("Worker.aiConnector", () => {
|
|
|
86
77
|
|
|
87
78
|
await capability.handler();
|
|
88
79
|
|
|
89
|
-
expect(stdoutSpy).toHaveBeenCalledWith(
|
|
90
|
-
|
|
91
|
-
);
|
|
92
|
-
expect(stdoutSpy).toHaveBeenCalledWith(
|
|
93
|
-
expect.stringContaining(`"thread-1"`),
|
|
94
|
-
);
|
|
80
|
+
expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining(`"_tag":"success"`));
|
|
81
|
+
expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining(`"thread-1"`));
|
|
95
82
|
});
|
|
96
83
|
|
|
97
84
|
it("passes state through from legacy runtime userContext", async () => {
|
|
@@ -106,15 +93,9 @@ describe("Worker.aiConnector", () => {
|
|
|
106
93
|
execute,
|
|
107
94
|
});
|
|
108
95
|
|
|
109
|
-
await capability.handler(
|
|
110
|
-
{ userContext: { cursor: "cursor-1" } },
|
|
111
|
-
{ concreteOutput: true },
|
|
112
|
-
);
|
|
96
|
+
await capability.handler({ userContext: { cursor: "cursor-1" } }, { concreteOutput: true });
|
|
113
97
|
|
|
114
|
-
expect(execute).toHaveBeenCalledWith(
|
|
115
|
-
{ cursor: "cursor-1" },
|
|
116
|
-
expect.anything(),
|
|
117
|
-
);
|
|
98
|
+
expect(execute).toHaveBeenCalledWith({ cursor: "cursor-1" }, expect.anything());
|
|
118
99
|
expect(stdoutSpy).not.toHaveBeenCalled();
|
|
119
100
|
});
|
|
120
101
|
|
|
@@ -161,9 +142,7 @@ describe("Worker.aiConnector", () => {
|
|
|
161
142
|
},
|
|
162
143
|
},
|
|
163
144
|
});
|
|
164
|
-
expect(
|
|
165
|
-
result.nextPacerStates.api?.lastScheduledAtMs,
|
|
166
|
-
).toBeGreaterThanOrEqual(before);
|
|
145
|
+
expect(result.nextPacerStates.api?.lastScheduledAtMs).toBeGreaterThanOrEqual(before);
|
|
167
146
|
});
|
|
168
147
|
|
|
169
148
|
describe("pacer local fallback", () => {
|
|
@@ -243,9 +222,7 @@ describe("Worker.aiConnector", () => {
|
|
|
243
222
|
});
|
|
244
223
|
|
|
245
224
|
await expect(capability.handler()).rejects.toThrow(ExecutionError);
|
|
246
|
-
expect(stdoutSpy).toHaveBeenCalledWith(
|
|
247
|
-
expect.stringContaining(`"_tag":"error"`),
|
|
248
|
-
);
|
|
225
|
+
expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining(`"_tag":"error"`));
|
|
249
226
|
});
|
|
250
227
|
|
|
251
228
|
it("accepts chat records at compile time", () => {
|
|
@@ -85,18 +85,14 @@ export type AiConnectorChangeUpsert<A extends AiConnectorArchetype> = {
|
|
|
85
85
|
record: AiConnectorRecordByArchetype[A];
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
-
export type AiConnectorChange<A extends AiConnectorArchetype> =
|
|
89
|
-
AiConnectorChangeUpsert<A>;
|
|
88
|
+
export type AiConnectorChange<A extends AiConnectorArchetype> = AiConnectorChangeUpsert<A>;
|
|
90
89
|
|
|
91
90
|
export type AiConnectorExecutionResult<
|
|
92
91
|
A extends AiConnectorArchetype,
|
|
93
92
|
State = unknown,
|
|
94
93
|
> = StatefulExecutionResult<AiConnectorChange<A>, State>;
|
|
95
94
|
|
|
96
|
-
export type AiConnectorConfiguration<
|
|
97
|
-
A extends AiConnectorArchetype,
|
|
98
|
-
State = unknown,
|
|
99
|
-
> = {
|
|
95
|
+
export type AiConnectorConfiguration<A extends AiConnectorArchetype, State = unknown> = {
|
|
100
96
|
/**
|
|
101
97
|
* The Notion record ID of an existing custom connector in the target workspace.
|
|
102
98
|
*
|
|
@@ -113,9 +109,7 @@ export type AiConnectorConfiguration<
|
|
|
113
109
|
) => Promise<AiConnectorExecutionResult<A, State>>;
|
|
114
110
|
};
|
|
115
111
|
|
|
116
|
-
export type AiConnectorCapability = ReturnType<
|
|
117
|
-
typeof createAiConnectorCapability
|
|
118
|
-
>;
|
|
112
|
+
export type AiConnectorCapability = ReturnType<typeof createAiConnectorCapability>;
|
|
119
113
|
|
|
120
114
|
type NormalizedAiConnectorConfiguration<A extends AiConnectorArchetype> = {
|
|
121
115
|
aiConnectorId: string;
|
|
@@ -131,10 +125,7 @@ type AiConnectorHandlerResult<A extends AiConnectorArchetype, State> = {
|
|
|
131
125
|
nextPacerStates: Record<string, PacerEntry>;
|
|
132
126
|
};
|
|
133
127
|
|
|
134
|
-
export function createAiConnectorCapability<
|
|
135
|
-
A extends AiConnectorArchetype,
|
|
136
|
-
State = unknown,
|
|
137
|
-
>(
|
|
128
|
+
export function createAiConnectorCapability<A extends AiConnectorArchetype, State = unknown>(
|
|
138
129
|
key: string,
|
|
139
130
|
configuration: AiConnectorConfiguration<A, State>,
|
|
140
131
|
pacerDeclarations?: readonly PacerDeclaration[],
|
|
@@ -150,10 +141,7 @@ export function createAiConnectorCapability<
|
|
|
150
141
|
? {}
|
|
151
142
|
: { schedule: parseSchedule(configuration.schedule) }),
|
|
152
143
|
} satisfies NormalizedAiConnectorConfiguration<A>,
|
|
153
|
-
async handler(
|
|
154
|
-
runtimeContext?: StatefulRuntimeContext<State>,
|
|
155
|
-
options?: HandlerOptions,
|
|
156
|
-
) {
|
|
144
|
+
async handler(runtimeContext?: StatefulRuntimeContext<State>, options?: HandlerOptions) {
|
|
157
145
|
const capabilityContext = createCapabilityContext("ai_connector");
|
|
158
146
|
const state = runtimeContext?.state ?? runtimeContext?.userContext;
|
|
159
147
|
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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 { ExecutionError } from "../error.js";
|
|
11
4
|
import type { PageObjectResponse } from "./automation.js";
|
|
12
5
|
import { createAutomationCapability } from "./automation.js";
|
|
@@ -15,9 +8,7 @@ describe("createAutomationCapability", () => {
|
|
|
15
8
|
let stdoutSpy: Mock<typeof process.stdout.write>;
|
|
16
9
|
|
|
17
10
|
beforeEach(() => {
|
|
18
|
-
stdoutSpy = vi
|
|
19
|
-
.spyOn(process.stdout, "write")
|
|
20
|
-
.mockImplementation(() => true);
|
|
11
|
+
stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
|
21
12
|
});
|
|
22
13
|
|
|
23
14
|
afterEach(() => {
|
|
@@ -64,10 +64,7 @@ export interface AutomationConfiguration {
|
|
|
64
64
|
* @param context - The capability execution context (Notion client, etc.)
|
|
65
65
|
* @returns A promise that resolves when the automation completes
|
|
66
66
|
*/
|
|
67
|
-
execute: (
|
|
68
|
-
event: AutomationEvent,
|
|
69
|
-
context: CapabilityContext,
|
|
70
|
-
) => Promise<void> | void;
|
|
67
|
+
execute: (event: AutomationEvent, context: CapabilityContext) => Promise<void> | void;
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
/**
|
|
@@ -78,9 +75,7 @@ export interface AutomationHandlerResult {
|
|
|
78
75
|
description: string;
|
|
79
76
|
}
|
|
80
77
|
|
|
81
|
-
export type AutomationCapability = ReturnType<
|
|
82
|
-
typeof createAutomationCapability
|
|
83
|
-
>;
|
|
78
|
+
export type AutomationCapability = ReturnType<typeof createAutomationCapability>;
|
|
84
79
|
|
|
85
80
|
/**
|
|
86
81
|
* Creates an automation capability from configuration.
|
|
@@ -89,10 +84,7 @@ export type AutomationCapability = ReturnType<
|
|
|
89
84
|
* @param config - The automation configuration.
|
|
90
85
|
* @returns The capability object.
|
|
91
86
|
*/
|
|
92
|
-
export function createAutomationCapability(
|
|
93
|
-
key: string,
|
|
94
|
-
config: AutomationConfiguration,
|
|
95
|
-
) {
|
|
87
|
+
export function createAutomationCapability(key: string, config: AutomationConfiguration) {
|
|
96
88
|
return {
|
|
97
89
|
_tag: "automation" as const,
|
|
98
90
|
key,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Client } from "@notionhq/client";
|
|
2
2
|
import type { ClientOptions } from "@notionhq/client/build/src/Client.js";
|
|
3
|
+
|
|
3
4
|
import type { CapabilityType } from "../worker.js";
|
|
4
5
|
|
|
5
6
|
export type CapabilityContext = {
|
|
@@ -9,8 +10,8 @@ export type CapabilityContext = {
|
|
|
9
10
|
|
|
10
11
|
const FIX_STEPS =
|
|
11
12
|
"\n\nTo fix this:\n" +
|
|
12
|
-
"1. Create
|
|
13
|
-
"2. Give the
|
|
13
|
+
"1. Create a connection at https://app.notion.com/developers/connections\n" +
|
|
14
|
+
"2. Give the connection access to the relevant pages/databases\n" +
|
|
14
15
|
"3. Add NOTION_API_TOKEN=<your-token> to your .env file\n" +
|
|
15
16
|
"4. For deployed workers, run: ntn workers env push";
|
|
16
17
|
|
|
@@ -32,9 +33,7 @@ function missingTokenMessage(capabilityType: CapabilityType): string {
|
|
|
32
33
|
);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
function createUnauthenticatedNotionProxy(
|
|
36
|
-
capabilityType: CapabilityType,
|
|
37
|
-
): Client {
|
|
36
|
+
function createUnauthenticatedNotionProxy(capabilityType: CapabilityType): Client {
|
|
38
37
|
return new Proxy({} as Client, {
|
|
39
38
|
get(_target, prop) {
|
|
40
39
|
if (prop === "then" || typeof prop === "symbol") {
|
|
@@ -45,9 +44,7 @@ function createUnauthenticatedNotionProxy(
|
|
|
45
44
|
});
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
export function createCapabilityContext(
|
|
49
|
-
capabilityType: CapabilityType,
|
|
50
|
-
): CapabilityContext {
|
|
47
|
+
export function createCapabilityContext(capabilityType: CapabilityType): CapabilityContext {
|
|
51
48
|
const options: ClientOptions = {};
|
|
52
49
|
|
|
53
50
|
if (process.env.NOTION_API_BASE_URL) {
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Custom Block Authoring API
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Icon for a custom block data source. Mirrors the server/client
|
|
7
|
+
* `CustomBlockManifestIcon` (`@notionhq/shared/customViews/customBlockManifestTypes`).
|
|
8
|
+
*/
|
|
9
|
+
export type CustomBlockManifestIcon =
|
|
10
|
+
| { type: "emoji"; emoji: string }
|
|
11
|
+
| { type: "external"; url: string };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Public-API-shaped property type names usable in a custom block manifest.
|
|
15
|
+
*/
|
|
16
|
+
export type CustomBlockManifestPropertyType =
|
|
17
|
+
| "title"
|
|
18
|
+
| "rich_text"
|
|
19
|
+
| "number"
|
|
20
|
+
| "select"
|
|
21
|
+
| "multi_select"
|
|
22
|
+
| "status"
|
|
23
|
+
| "date"
|
|
24
|
+
| "people"
|
|
25
|
+
| "files"
|
|
26
|
+
| "checkbox"
|
|
27
|
+
| "url"
|
|
28
|
+
| "email"
|
|
29
|
+
| "phone_number"
|
|
30
|
+
| "formula"
|
|
31
|
+
| "relation"
|
|
32
|
+
| "rollup"
|
|
33
|
+
| "created_time"
|
|
34
|
+
| "created_by"
|
|
35
|
+
| "last_edited_time"
|
|
36
|
+
| "last_edited_by"
|
|
37
|
+
| "last_visited_time"
|
|
38
|
+
| "button"
|
|
39
|
+
| "unique_id"
|
|
40
|
+
| "location"
|
|
41
|
+
| "verification"
|
|
42
|
+
| "place";
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Describes a single property exposed by a custom block data source.
|
|
46
|
+
*/
|
|
47
|
+
export type CustomBlockManifestProperty = {
|
|
48
|
+
name: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
type: CustomBlockManifestPropertyType;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Rich schema describing one of a custom block's data sources.
|
|
55
|
+
*/
|
|
56
|
+
export type CustomBlockManifestDataSource = {
|
|
57
|
+
/** Display name for the data source. */
|
|
58
|
+
name: string;
|
|
59
|
+
/** Optional human-readable description of the data source. */
|
|
60
|
+
description?: string;
|
|
61
|
+
/** Optional icon for the data source. */
|
|
62
|
+
icon?: CustomBlockManifestIcon;
|
|
63
|
+
/** Optional property schema keyed by property key. */
|
|
64
|
+
properties?: Record<string, CustomBlockManifestProperty>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type CustomBlockManifest = {
|
|
68
|
+
version: 1;
|
|
69
|
+
/**
|
|
70
|
+
* The block's datasources schema, mapping keys you name to {@link CustomBlockManifestDataSource}
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
*
|
|
74
|
+
* {
|
|
75
|
+
* "myDataSource": {
|
|
76
|
+
* "name": "My Data Source",
|
|
77
|
+
* "description": "A description of my data source",
|
|
78
|
+
* "icon": "icon.png",
|
|
79
|
+
* "properties": {
|
|
80
|
+
* "property1": {
|
|
81
|
+
* "name": "Property 1",
|
|
82
|
+
* "type": "string"
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
*/
|
|
88
|
+
dataSources: Record<string, CustomBlockManifestDataSource>;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* A custom block is a front-end web app served in an iframe in the client with live data access.
|
|
93
|
+
*
|
|
94
|
+
* Available `type`s are `project` (a buildable project dir) and `static` (an already-built dir served as-is).
|
|
95
|
+
*/
|
|
96
|
+
export type CustomBlockConfiguration = (
|
|
97
|
+
| {
|
|
98
|
+
/** Buildable project dir (the default). */
|
|
99
|
+
type?: "project";
|
|
100
|
+
/** Path to the project dir, relative to the worker root (e.g. `"./blocks/foo"`). */
|
|
101
|
+
path: string;
|
|
102
|
+
/** Build command run in `path`. Defaults to `npm run build`. */
|
|
103
|
+
command?: string;
|
|
104
|
+
/** Built-output dir relative to `path`. Defaults to `dist`. */
|
|
105
|
+
output?: string;
|
|
106
|
+
}
|
|
107
|
+
| {
|
|
108
|
+
/** An already-built browser-bundle dir; served as-is, no build step. */
|
|
109
|
+
type: "static";
|
|
110
|
+
/** Path to the prebuilt dir, relative to the worker root. */
|
|
111
|
+
path: string;
|
|
112
|
+
command?: never;
|
|
113
|
+
output?: never;
|
|
114
|
+
}
|
|
115
|
+
) &
|
|
116
|
+
Partial<CustomBlockManifest>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The build source of a custom block, mirroring the server's
|
|
120
|
+
* `BlockSourceDeclaration`. `project` is a buildable dir (`command` defaults to
|
|
121
|
+
* `npm run build`, `output` to `dist`); `static` is an already-built dir served
|
|
122
|
+
* as-is.
|
|
123
|
+
*/
|
|
124
|
+
export type BlockSourceDeclaration =
|
|
125
|
+
| { type: "project"; path: string; command?: string; output?: string }
|
|
126
|
+
| { type: "static"; path: string };
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Config payload carried in the runtime manifest for a `_tag: "custom_block"`
|
|
130
|
+
* capability entry. The server parses this (see `RawBlockCapabilityConfig` in
|
|
131
|
+
* `capabilities-service.ts`): `source` is the build entry and `manifest` is the
|
|
132
|
+
* author-declared {@link CustomBlockManifest} describing the block's data-source
|
|
133
|
+
* schema. Data-source *bindings* are instance-level and are not carried here.
|
|
134
|
+
*/
|
|
135
|
+
export type CustomBlockCapabilityConfig = {
|
|
136
|
+
source: BlockSourceDeclaration;
|
|
137
|
+
manifest: CustomBlockManifest;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* A custom-block capability entry. Unlike other capabilities it has no runtime
|
|
142
|
+
* handler — it is a build-time/deploy-time declaration only, carried through
|
|
143
|
+
* the manifest so the server can build and bind the block on deploy.
|
|
144
|
+
*/
|
|
145
|
+
export type CustomBlockCapability = {
|
|
146
|
+
readonly _tag: "custom_block";
|
|
147
|
+
readonly key: string;
|
|
148
|
+
readonly config: CustomBlockCapabilityConfig;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Builds a custom-block capability entry from its authoring configuration. The
|
|
153
|
+
* author-declared `dataSources` schema is carried verbatim into the block
|
|
154
|
+
* {@link CustomBlockManifest}; no bindings are emitted.
|
|
155
|
+
*/
|
|
156
|
+
export function createCustomBlockCapability(
|
|
157
|
+
key: string,
|
|
158
|
+
config: CustomBlockConfiguration,
|
|
159
|
+
): CustomBlockCapability {
|
|
160
|
+
const source: BlockSourceDeclaration =
|
|
161
|
+
config.type === "static"
|
|
162
|
+
? { type: "static", path: config.path }
|
|
163
|
+
: {
|
|
164
|
+
type: "project",
|
|
165
|
+
path: config.path,
|
|
166
|
+
...(config.command !== undefined ? { command: config.command } : {}),
|
|
167
|
+
...(config.output !== undefined ? { output: config.output } : {}),
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
_tag: "custom_block",
|
|
172
|
+
key,
|
|
173
|
+
config: {
|
|
174
|
+
source,
|
|
175
|
+
manifest: {
|
|
176
|
+
version: config.version ?? 1,
|
|
177
|
+
dataSources: config.dataSources ?? {},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
@@ -84,9 +84,7 @@ export interface UserManagedOAuthConfiguration {
|
|
|
84
84
|
/**
|
|
85
85
|
* Union type representing either Notion-managed or user-managed OAuth configuration.
|
|
86
86
|
*/
|
|
87
|
-
export type OAuthConfiguration =
|
|
88
|
-
| NotionManagedOAuthConfiguration
|
|
89
|
-
| UserManagedOAuthConfiguration;
|
|
87
|
+
export type OAuthConfiguration = NotionManagedOAuthConfiguration | UserManagedOAuthConfiguration;
|
|
90
88
|
|
|
91
89
|
export type OAuthCapability = ReturnType<typeof createOAuthCapability>;
|
|
92
90
|
|
|
@@ -2,7 +2,5 @@
|
|
|
2
2
|
* Writes a notion_output envelope to stdout using the shared wire format.
|
|
3
3
|
*/
|
|
4
4
|
export function writeOutput(value: unknown): void {
|
|
5
|
-
process.stdout.write(
|
|
6
|
-
`\n<__notion_output__>${JSON.stringify(value)}</__notion_output__>\n`,
|
|
7
|
-
);
|
|
5
|
+
process.stdout.write(`\n<__notion_output__>${JSON.stringify(value)}</__notion_output__>\n`);
|
|
8
6
|
}
|
|
@@ -48,7 +48,7 @@ export function parseSchedule(schedule: Schedule): SyncSchedule {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const match = schedule.match(/^(\d+)(m|h|d)$/);
|
|
51
|
-
if (!match
|
|
51
|
+
if (!match?.[1] || !match[2]) {
|
|
52
52
|
throw new Error(
|
|
53
53
|
`Invalid schedule format: "${schedule}". Use "continuous" or an interval like "30m", "1h", "1d".`,
|
|
54
54
|
);
|
|
@@ -73,14 +73,10 @@ export function parseSchedule(schedule: Schedule): SyncSchedule {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
if (intervalMs < MIN_INTERVAL_MS) {
|
|
76
|
-
throw new Error(
|
|
77
|
-
`Schedule interval must be at least 1 minute. Got: "${schedule}"`,
|
|
78
|
-
);
|
|
76
|
+
throw new Error(`Schedule interval must be at least 1 minute. Got: "${schedule}"`);
|
|
79
77
|
}
|
|
80
78
|
if (intervalMs > MAX_INTERVAL_MS) {
|
|
81
|
-
throw new Error(
|
|
82
|
-
`Schedule interval must be at most 7 days. Got: "${schedule}"`,
|
|
83
|
-
);
|
|
79
|
+
throw new Error(`Schedule interval must be at most 7 days. Got: "${schedule}"`);
|
|
84
80
|
}
|
|
85
81
|
|
|
86
82
|
return { type: "interval", intervalMs };
|