@project-ajax/sdk 0.0.74 → 0.0.75
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/capabilities/automation.d.ts +7 -5
- package/dist/capabilities/automation.d.ts.map +1 -1
- package/dist/capabilities/automation.js +4 -2
- package/dist/capabilities/context.d.ts +7 -0
- package/dist/capabilities/context.d.ts.map +1 -0
- package/dist/capabilities/context.js +15 -0
- package/dist/capabilities/sync.d.ts +17 -20
- package/dist/capabilities/sync.d.ts.map +1 -1
- package/dist/capabilities/sync.js +5 -3
- package/dist/capabilities/tool.d.ts +2 -1
- package/dist/capabilities/tool.d.ts.map +1 -1
- package/dist/capabilities/tool.js +3 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/worker.d.ts +6 -5
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +3 -3
- package/package.json +4 -1
- package/src/capabilities/automation.test.ts +21 -11
- package/src/capabilities/automation.ts +13 -6
- package/src/capabilities/context.ts +23 -0
- package/src/capabilities/sync.ts +25 -24
- package/src/capabilities/tool.ts +5 -2
- package/src/index.ts +2 -1
- package/src/worker.ts +7 -5
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { CapabilityContext } from "./context.js";
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
+
* Event provided to automation execute functions
|
|
3
4
|
*/
|
|
4
|
-
export interface
|
|
5
|
+
export interface AutomationEvent {
|
|
5
6
|
/**
|
|
6
7
|
* The ID of the page that triggered the automation (if applicable)
|
|
7
8
|
*/
|
|
@@ -54,10 +55,11 @@ export interface AutomationConfiguration {
|
|
|
54
55
|
description: string;
|
|
55
56
|
/**
|
|
56
57
|
* The function that executes when the automation is triggered
|
|
57
|
-
* @param
|
|
58
|
+
* @param event - Event data about the automation trigger, including page data if applicable
|
|
59
|
+
* @param context - The capability execution context (Notion client, etc.)
|
|
58
60
|
* @returns A promise that resolves when the automation completes
|
|
59
61
|
*/
|
|
60
|
-
execute: (context:
|
|
62
|
+
execute: (event: AutomationEvent, context: CapabilityContext) => Promise<void> | void;
|
|
61
63
|
}
|
|
62
64
|
/**
|
|
63
65
|
* Result returned from automation execution
|
|
@@ -81,6 +83,6 @@ export declare function createAutomationCapability(key: string, config: Automati
|
|
|
81
83
|
title: string;
|
|
82
84
|
description: string;
|
|
83
85
|
};
|
|
84
|
-
handler(
|
|
86
|
+
handler(event: AutomationEvent): Promise<void>;
|
|
85
87
|
};
|
|
86
88
|
//# sourceMappingURL=automation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation.d.ts","sourceRoot":"","sources":["../../src/capabilities/automation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"automation.d.ts","sourceRoot":"","sources":["../../src/capabilities/automation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,cAAc,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;OAKG;IACH,OAAO,EAAE,CACR,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,iBAAiB,KACtB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAC5C,OAAO,0BAA0B,CACjC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACzC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,uBAAuB;;;;;;;mBAST,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;EAgBrD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExecutionError } from "../error.js";
|
|
2
|
+
import { createCapabilityContext } from "./context.js";
|
|
2
3
|
function createAutomationCapability(key, config) {
|
|
3
4
|
return {
|
|
4
5
|
_tag: "automation",
|
|
@@ -7,9 +8,10 @@ function createAutomationCapability(key, config) {
|
|
|
7
8
|
title: config.title,
|
|
8
9
|
description: config.description
|
|
9
10
|
},
|
|
10
|
-
async handler(
|
|
11
|
+
async handler(event) {
|
|
11
12
|
try {
|
|
12
|
-
|
|
13
|
+
const capabilityContext = createCapabilityContext();
|
|
14
|
+
await config.execute(event, capabilityContext);
|
|
13
15
|
process.stdout.write(
|
|
14
16
|
`
|
|
15
17
|
<output>${JSON.stringify({ status: "success" })}</output>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/capabilities/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG1C,MAAM,MAAM,iBAAiB,GAAG;IAC/B,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,uBAAuB,IAAI,iBAAiB,CAc3D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Client } from "@notionhq/client";
|
|
2
|
+
function createCapabilityContext() {
|
|
3
|
+
const options = {};
|
|
4
|
+
if (process.env.NOTION_API_BASE_URL) {
|
|
5
|
+
options.baseUrl = process.env.NOTION_API_BASE_URL;
|
|
6
|
+
}
|
|
7
|
+
if (process.env.NOTION_API_TOKEN) {
|
|
8
|
+
options.auth = process.env.NOTION_API_TOKEN;
|
|
9
|
+
}
|
|
10
|
+
const notion = new Client(options);
|
|
11
|
+
return { notion };
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
createCapabilityContext
|
|
15
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PropertyConfiguration, PropertySchema, Schema } from "../schema.js";
|
|
2
2
|
import type { Icon, PeopleValue, PlaceValue, RelationValue, Schedule, SyncSchedule, TextValue } from "../types.js";
|
|
3
|
+
import type { CapabilityContext } from "./context.js";
|
|
3
4
|
/**
|
|
4
5
|
* Maps a property configuration to its corresponding value type.
|
|
5
6
|
*/
|
|
@@ -69,7 +70,7 @@ export type SyncChange<PK extends string, S extends PropertySchema<PK>> = SyncCh
|
|
|
69
70
|
/**
|
|
70
71
|
* Result returned from the sync execute function.
|
|
71
72
|
*/
|
|
72
|
-
export type SyncExecutionResult<PK extends string,
|
|
73
|
+
export type SyncExecutionResult<PK extends string, State = unknown> = {
|
|
73
74
|
/**
|
|
74
75
|
* The batch of changes to apply in this execution.
|
|
75
76
|
* Can include upserts (create/update) and deletes.
|
|
@@ -77,23 +78,23 @@ export type SyncExecutionResult<PK extends string, Context = unknown> = {
|
|
|
77
78
|
changes: SyncChange<PK, PropertySchema<PK>>[];
|
|
78
79
|
/**
|
|
79
80
|
* Indicates whether there is more data to fetch.
|
|
80
|
-
* - `true`: More data available, will trigger another execution with
|
|
81
|
+
* - `true`: More data available, will trigger another execution with nextState
|
|
81
82
|
* - `false`: No more data to fetch, sync is complete
|
|
82
83
|
*/
|
|
83
84
|
hasMore: boolean;
|
|
84
85
|
/**
|
|
85
|
-
* Optional
|
|
86
|
+
* Optional state data to pass to the next execution.
|
|
86
87
|
* Required if `hasMore` is `true`, ignored if `hasMore` is `false`.
|
|
87
88
|
* This can be any type of data (cursor, page number, timestamp, etc.).
|
|
88
|
-
* The same data will be provided
|
|
89
|
+
* The same data will be provided as `state` in the next execution.
|
|
89
90
|
*/
|
|
90
|
-
|
|
91
|
+
nextState?: State;
|
|
91
92
|
};
|
|
92
93
|
/**
|
|
93
94
|
* A configuration object that enables synchronization between a data
|
|
94
95
|
* source and a third-party source.
|
|
95
96
|
*/
|
|
96
|
-
export type SyncConfiguration<PK extends string, S extends Schema<PK>,
|
|
97
|
+
export type SyncConfiguration<PK extends string, S extends Schema<PK>, State = unknown> = {
|
|
97
98
|
/**
|
|
98
99
|
* The property of the data source that maps to a "primary key" in the
|
|
99
100
|
* third-party data. This is used to match existing pages to
|
|
@@ -130,31 +131,27 @@ export type SyncConfiguration<PK extends string, S extends Schema<PK>, Context =
|
|
|
130
131
|
* A function that fetches the data to sync from the third-party service.
|
|
131
132
|
*
|
|
132
133
|
* This function can return all data at once, or implement pagination by:
|
|
133
|
-
* 1. Returning a batch of changes with `hasMore: true` and a `
|
|
134
|
-
* 2. The runtime will call execute again with that
|
|
134
|
+
* 1. Returning a batch of changes with `hasMore: true` and a `nextState`
|
|
135
|
+
* 2. The runtime will call execute again with that state
|
|
135
136
|
* 3. Continue until `hasMore: false` is returned
|
|
136
137
|
*
|
|
137
138
|
* The runtime will handle diffing against the data source and creating,
|
|
138
139
|
* updating, and deleting pages as necessary.
|
|
139
140
|
*
|
|
140
|
-
* @param
|
|
141
|
-
* @
|
|
141
|
+
* @param state - User-defined state from the previous execution (undefined on first call)
|
|
142
|
+
* @param context - Runtime context, including Notion client
|
|
143
|
+
* @returns A result containing changes, hasMore status, and optional nextState
|
|
142
144
|
*/
|
|
143
|
-
execute: (context
|
|
144
|
-
};
|
|
145
|
-
export type SyncHandlerResult<PK extends string, Context = unknown> = {
|
|
146
|
-
primaryKeyProperty: PK;
|
|
147
|
-
changes: SyncChange<PK, PropertySchema<PK>>[];
|
|
148
|
-
hasMore: boolean;
|
|
149
|
-
nextContext?: Context;
|
|
150
|
-
mode?: SyncMode;
|
|
145
|
+
execute: (state: State | undefined, context: CapabilityContext) => Promise<SyncExecutionResult<PK, State>>;
|
|
151
146
|
};
|
|
152
147
|
export type SyncCapability = ReturnType<typeof createSyncCapability>;
|
|
153
148
|
/**
|
|
154
|
-
*
|
|
149
|
+
* Runtime context object passed from the runtime to sync capability handlers.
|
|
155
150
|
*/
|
|
156
151
|
type RuntimeContext<UserContext = unknown> = {
|
|
157
|
-
/** The user-defined/-controlled
|
|
152
|
+
/** The user-defined/-controlled state (cursor, pagination state, etc.) */
|
|
153
|
+
state?: UserContext;
|
|
154
|
+
/** Legacy field for user-defined/-controlled state. */
|
|
158
155
|
userContext?: UserContext;
|
|
159
156
|
};
|
|
160
157
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,qBAAqB,EACrB,cAAc,EACd,MAAM,EACN,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACX,IAAI,EACJ,WAAW,EACX,UAAU,EACV,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,SAAS,EAET,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,qBAAqB,EACrB,cAAc,EACd,MAAM,EACN,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACX,IAAI,EACJ,WAAW,EACX,UAAU,EACV,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,SAAS,EAET,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD;;GAEG;AACH,KAAK,iBAAiB,CAAC,CAAC,SAAS,qBAAqB,IAAI,CAAC,SAAS;IACnE,IAAI,EAAE,QAAQ,CAAC;CACf,GACE,WAAW,GACX,CAAC,SAAS;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B,UAAU,GACV,CAAC,SAAS;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B,aAAa,GACb,SAAS,CAAC;AAEf;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAC3B,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,cAAc,CAAC,EAAE,CAAC,IACzB;IACH;;OAEG;IACH,IAAI,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,UAAU,EAAE;SACV,QAAQ,IAAI,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;KACrD,CAAC;IACF;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC9B;;OAEG;IACH,IAAI,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC,SAAS,cAAc,CAAC,EAAE,CAAC,IACnE,gBAAgB,CAAC,EAAE,EAAE,CAAC,CAAC,GACvB,gBAAgB,CAAC;AAEpB;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,GAAG,OAAO,IAAI;IACrE;;;OAGG;IACH,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAE9C;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAC5B,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EACpB,KAAK,GAAG,OAAO,IACZ;IACH;;;;OAIG;IACH,kBAAkB,EAAE,EAAE,CAAC;IAEvB;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC;IAEV;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAEhB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;;;;;;;;;;;OAcG;IACH,OAAO,EAAE,CACR,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,OAAO,EAAE,iBAAiB,KACtB,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAErE;;GAEG;AACH,KAAK,cAAc,CAAC,WAAW,GAAG,OAAO,IAAI;IAC5C,0EAA0E;IAC1E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,uDAAuD;IACvD,WAAW,CAAC,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CACnC,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EACpB,OAAO,GAAG,OAAO,EAChB,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC;;;;;;;;;6BAUlC,cAAc,CAAC,OAAO,CAAC;;;;;EAoBvD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExecutionError, unreachable } from "../error.js";
|
|
2
|
+
import { createCapabilityContext } from "./context.js";
|
|
2
3
|
function createSyncCapability(key, syncConfiguration) {
|
|
3
4
|
return {
|
|
4
5
|
_tag: "sync",
|
|
@@ -10,14 +11,15 @@ function createSyncCapability(key, syncConfiguration) {
|
|
|
10
11
|
schedule: parseSchedule(syncConfiguration.schedule)
|
|
11
12
|
},
|
|
12
13
|
async handler(runtimeContext) {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
14
|
+
const capabilityContext = createCapabilityContext();
|
|
15
|
+
const state = runtimeContext?.state ?? runtimeContext?.userContext;
|
|
16
|
+
const executionResult = await syncConfiguration.execute(state, capabilityContext).catch((err) => {
|
|
15
17
|
throw new ExecutionError(err);
|
|
16
18
|
});
|
|
17
19
|
const result = {
|
|
18
20
|
changes: executionResult.changes,
|
|
19
21
|
hasMore: executionResult.hasMore,
|
|
20
|
-
nextUserContext: executionResult.
|
|
22
|
+
nextUserContext: executionResult.nextState
|
|
21
23
|
};
|
|
22
24
|
process.stdout.write(`
|
|
23
25
|
<output>${JSON.stringify(result)}</output>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type JSONSchemaType } from "ajv";
|
|
2
2
|
import type { JSONValue } from "../types.js";
|
|
3
|
+
import type { CapabilityContext } from "./context.js";
|
|
3
4
|
export interface ToolConfiguration<I extends JSONValue, O extends JSONValue = JSONValue> {
|
|
4
5
|
title: string;
|
|
5
6
|
description: string;
|
|
6
7
|
schema: JSONSchemaType<I>;
|
|
7
8
|
outputSchema?: JSONSchemaType<O>;
|
|
8
|
-
execute: (input: I) => O | Promise<O>;
|
|
9
|
+
execute: (input: I, context: CapabilityContext) => O | Promise<O>;
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
11
12
|
* An error returned when the input to a tool doesn't match the input schema.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/capabilities/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/capabilities/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,MAAM,WAAW,iBAAiB,CACjC,CAAC,SAAS,SAAS,EACnB,CAAC,SAAS,SAAS,GAAG,SAAS;IAE/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAC1B,YAAY,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,iBAAiB,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAClE;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;IAK3B,MAAM;;;;CAMN;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM;IAK3B,MAAM;;;;CAMN;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;IAK3B,MAAM;;;;CAMN;AAED,MAAM,MAAM,cAAc,CACzB,CAAC,SAAS,SAAS,EACnB,CAAC,SAAS,SAAS,GAAG,SAAS,IAC5B,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,CAAC,SAAS,SAAS,EACnB,CAAC,SAAS,SAAS,GAAG,SAAS,EAC9B,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC;;;;;;;;;mBAgBvB,SAAS,GAAG,OAAO,CACrC;QACA,IAAI,EAAE,SAAS,CAAC;QAChB,KAAK,EAAE,CAAC,CAAC;KACR,GACD;QACA,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EACF,qBAAqB,GACrB,sBAAsB,GACtB,kBAAkB,CAAC;KACrB,CACH;EA2DF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Ajv } from "ajv";
|
|
2
|
+
import { createCapabilityContext } from "./context.js";
|
|
2
3
|
class InvalidToolInputError extends Error {
|
|
3
4
|
constructor(message) {
|
|
4
5
|
super(message);
|
|
@@ -67,7 +68,8 @@ function createToolCapability(key, config) {
|
|
|
67
68
|
return result;
|
|
68
69
|
}
|
|
69
70
|
try {
|
|
70
|
-
const
|
|
71
|
+
const capabilityContext = createCapabilityContext();
|
|
72
|
+
const result = await config.execute(input, capabilityContext);
|
|
71
73
|
if (validateOutput && !validateOutput(result)) {
|
|
72
74
|
const result2 = {
|
|
73
75
|
_tag: "error",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { emojiIcon, imageIcon, notionIcon, place } from "./builder.js";
|
|
2
|
-
export type { AutomationCapability, AutomationConfiguration,
|
|
2
|
+
export type { AutomationCapability, AutomationConfiguration, AutomationEvent, PageObjectResponse, } from "./capabilities/automation.js";
|
|
3
|
+
export type { CapabilityContext } from "./capabilities/context.js";
|
|
3
4
|
export type { NotionManagedOAuthConfiguration, OAuthCapability, OAuthConfiguration, UserManagedOAuthConfiguration, } from "./capabilities/oauth.js";
|
|
4
5
|
export type { SyncCapability, SyncChange, SyncChangeDelete, SyncChangeUpsert, SyncConfiguration, SyncExecutionResult, SyncMode, } from "./capabilities/sync.js";
|
|
5
6
|
export type { ToolCapability, ToolConfiguration } from "./capabilities/tool.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACX,oBAAoB,EACpB,uBAAuB,EACvB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACX,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EACX,+BAA+B,EAC/B,eAAe,EACf,kBAAkB,EAClB,6BAA6B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,GACR,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,YAAY,EACX,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/worker.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { AutomationCapability, AutomationConfiguration,
|
|
1
|
+
import type { AutomationCapability, AutomationConfiguration, AutomationEvent } from "./capabilities/automation.js";
|
|
2
|
+
import type { CapabilityContext } from "./capabilities/context.js";
|
|
2
3
|
import type { NotionManagedOAuthConfiguration, OAuthCapability, OAuthConfiguration, UserManagedOAuthConfiguration } from "./capabilities/oauth.js";
|
|
3
4
|
import type { SyncCapability, SyncConfiguration } from "./capabilities/sync.js";
|
|
4
5
|
import type { ToolCapability, ToolConfiguration } from "./capabilities/tool.js";
|
|
5
6
|
import type { Schema } from "./schema.js";
|
|
6
7
|
import type { JSONValue } from "./types.js";
|
|
7
|
-
export type { AutomationConfiguration,
|
|
8
|
+
export type { AutomationConfiguration, AutomationEvent, CapabilityContext, OAuthConfiguration, NotionManagedOAuthConfiguration, UserManagedOAuthConfiguration, SyncConfiguration, ToolConfiguration, };
|
|
8
9
|
type Capability = SyncCapability | ToolCapability<any, any> | AutomationCapability | OAuthCapability;
|
|
9
10
|
export declare class Worker {
|
|
10
11
|
#private;
|
|
@@ -72,7 +73,7 @@ export declare class Worker {
|
|
|
72
73
|
* },
|
|
73
74
|
* required: ["name"],
|
|
74
75
|
* },
|
|
75
|
-
* execute: ({ name }) => {
|
|
76
|
+
* execute: ({ name }, { notion }) => {
|
|
76
77
|
* return `Hello, ${name}!`;
|
|
77
78
|
* },
|
|
78
79
|
* })
|
|
@@ -96,8 +97,8 @@ export declare class Worker {
|
|
|
96
97
|
* worker.automation("sendWelcomeEmail", {
|
|
97
98
|
* title: "Send Welcome Email",
|
|
98
99
|
* description: "Sends a welcome email when a new user is added",
|
|
99
|
-
* execute: async (
|
|
100
|
-
* const { pageId, pageData } =
|
|
100
|
+
* execute: async (event, { notion }) => {
|
|
101
|
+
* const { pageId, pageData } = event;
|
|
101
102
|
*
|
|
102
103
|
* // Access page properties from the Public API format
|
|
103
104
|
* if (pageData) {
|
package/dist/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oBAAoB,EACpB,uBAAuB,EACvB,
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EACX,+BAA+B,EAC/B,eAAe,EACf,kBAAkB,EAClB,6BAA6B,EAC7B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,YAAY,EACX,uBAAuB,EACvB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,+BAA+B,EAC/B,6BAA6B,EAC7B,iBAAiB,EACjB,iBAAiB,GACjB,CAAC;AAMF,KAAK,UAAU,GACZ,cAAc,GAEd,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,GACxB,oBAAoB,GACpB,eAAe,CAAC;AAMnB,qBAAa,MAAM;;IAGlB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8CG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,EAC9D,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,iBAAiB,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,GACvC,cAAc;IAOjB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,IAAI,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,GAAG,SAAS,EACxD,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;IAQvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,UAAU,CACT,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,uBAAuB,GAC7B,oBAAoB;IAOvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,eAAe;IAO/D;;OAEG;IACH,IAAI,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,EAAE,CAMhE;IAED;;;;;;OAMG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAyB1D"}
|
package/dist/worker.js
CHANGED
|
@@ -73,7 +73,7 @@ class Worker {
|
|
|
73
73
|
* },
|
|
74
74
|
* required: ["name"],
|
|
75
75
|
* },
|
|
76
|
-
* execute: ({ name }) => {
|
|
76
|
+
* execute: ({ name }, { notion }) => {
|
|
77
77
|
* return `Hello, ${name}!`;
|
|
78
78
|
* },
|
|
79
79
|
* })
|
|
@@ -102,8 +102,8 @@ class Worker {
|
|
|
102
102
|
* worker.automation("sendWelcomeEmail", {
|
|
103
103
|
* title: "Send Welcome Email",
|
|
104
104
|
* description: "Sends a welcome email when a new user is added",
|
|
105
|
-
* execute: async (
|
|
106
|
-
* const { pageId, pageData } =
|
|
105
|
+
* execute: async (event, { notion }) => {
|
|
106
|
+
* const { pageId, pageData } = event;
|
|
107
107
|
*
|
|
108
108
|
* // Access page properties from the Public API format
|
|
109
109
|
* if (pageData) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@project-ajax/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.75",
|
|
4
4
|
"description": "An SDK for building workers for the Project Ajax platform",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -58,6 +58,9 @@
|
|
|
58
58
|
"typescript": "^5.9.3",
|
|
59
59
|
"vitest": "^4.0.8"
|
|
60
60
|
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"@notionhq/client": "^2.2.15"
|
|
63
|
+
},
|
|
61
64
|
"dependencies": {
|
|
62
65
|
"ajv": "^8.17.1"
|
|
63
66
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
vi,
|
|
9
9
|
} from "vitest";
|
|
10
10
|
import { ExecutionError } from "../error.js";
|
|
11
|
-
import type {
|
|
11
|
+
import type { PageObjectResponse } from "./automation.js";
|
|
12
12
|
import { createAutomationCapability } from "./automation.js";
|
|
13
13
|
|
|
14
14
|
describe("createAutomationCapability", () => {
|
|
@@ -45,14 +45,19 @@ describe("createAutomationCapability", () => {
|
|
|
45
45
|
execute: executeFn,
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
const
|
|
48
|
+
const event = {
|
|
49
49
|
pageId: "page-123",
|
|
50
50
|
actionType: "test_action",
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
await capability.handler(
|
|
53
|
+
await capability.handler(event);
|
|
54
54
|
|
|
55
|
-
expect(executeFn).toHaveBeenCalledWith(
|
|
55
|
+
expect(executeFn).toHaveBeenCalledWith(
|
|
56
|
+
event,
|
|
57
|
+
expect.objectContaining({
|
|
58
|
+
notion: expect.any(Object),
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
56
61
|
expect(stdoutSpy).toHaveBeenCalledWith(
|
|
57
62
|
`\n<output>{"status":"success"}</output>\n`,
|
|
58
63
|
);
|
|
@@ -85,15 +90,20 @@ describe("createAutomationCapability", () => {
|
|
|
85
90
|
public_url: null,
|
|
86
91
|
};
|
|
87
92
|
|
|
88
|
-
const
|
|
93
|
+
const event = {
|
|
89
94
|
pageId: "page-789",
|
|
90
95
|
actionType: "process_page",
|
|
91
96
|
pageData,
|
|
92
97
|
};
|
|
93
98
|
|
|
94
|
-
await capability.handler(
|
|
99
|
+
await capability.handler(event);
|
|
95
100
|
|
|
96
|
-
expect(executeFn).toHaveBeenCalledWith(
|
|
101
|
+
expect(executeFn).toHaveBeenCalledWith(
|
|
102
|
+
event,
|
|
103
|
+
expect.objectContaining({
|
|
104
|
+
notion: expect.any(Object),
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
97
107
|
expect(stdoutSpy).toHaveBeenCalledWith(
|
|
98
108
|
`\n<output>{"status":"success"}</output>\n`,
|
|
99
109
|
);
|
|
@@ -108,12 +118,12 @@ describe("createAutomationCapability", () => {
|
|
|
108
118
|
},
|
|
109
119
|
});
|
|
110
120
|
|
|
111
|
-
const
|
|
121
|
+
const event = {
|
|
112
122
|
pageId: "page-error",
|
|
113
123
|
actionType: "error_action",
|
|
114
124
|
};
|
|
115
125
|
|
|
116
|
-
await expect(capability.handler(
|
|
126
|
+
await expect(capability.handler(event)).rejects.toThrow(ExecutionError);
|
|
117
127
|
|
|
118
128
|
expect(stdoutSpy).toHaveBeenCalledWith(
|
|
119
129
|
`\n<output>{"status":"error","error":{"name":"ExecutionError","message":"Error during worker execution: Error: Something went wrong"}}</output>\n`,
|
|
@@ -129,11 +139,11 @@ describe("createAutomationCapability", () => {
|
|
|
129
139
|
},
|
|
130
140
|
});
|
|
131
141
|
|
|
132
|
-
const
|
|
142
|
+
const event = {
|
|
133
143
|
actionType: "string_error_action",
|
|
134
144
|
};
|
|
135
145
|
|
|
136
|
-
await expect(capability.handler(
|
|
146
|
+
await expect(capability.handler(event)).rejects.toThrow(ExecutionError);
|
|
137
147
|
|
|
138
148
|
expect(stdoutSpy).toHaveBeenCalledWith(
|
|
139
149
|
`\n<output>{"status":"error","error":{"name":"ExecutionError","message":"Error during worker execution: String error"}}</output>\n`,
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ExecutionError } from "../error.js";
|
|
2
|
+
import type { CapabilityContext } from "./context.js";
|
|
3
|
+
import { createCapabilityContext } from "./context.js";
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
6
|
+
* Event provided to automation execute functions
|
|
5
7
|
*/
|
|
6
|
-
export interface
|
|
8
|
+
export interface AutomationEvent {
|
|
7
9
|
/**
|
|
8
10
|
* The ID of the page that triggered the automation (if applicable)
|
|
9
11
|
*/
|
|
@@ -56,10 +58,14 @@ export interface AutomationConfiguration {
|
|
|
56
58
|
|
|
57
59
|
/**
|
|
58
60
|
* The function that executes when the automation is triggered
|
|
59
|
-
* @param
|
|
61
|
+
* @param event - Event data about the automation trigger, including page data if applicable
|
|
62
|
+
* @param context - The capability execution context (Notion client, etc.)
|
|
60
63
|
* @returns A promise that resolves when the automation completes
|
|
61
64
|
*/
|
|
62
|
-
execute: (
|
|
65
|
+
execute: (
|
|
66
|
+
event: AutomationEvent,
|
|
67
|
+
context: CapabilityContext,
|
|
68
|
+
) => Promise<void> | void;
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
/**
|
|
@@ -92,9 +98,10 @@ export function createAutomationCapability(
|
|
|
92
98
|
title: config.title,
|
|
93
99
|
description: config.description,
|
|
94
100
|
},
|
|
95
|
-
async handler(
|
|
101
|
+
async handler(event: AutomationEvent): Promise<void> {
|
|
96
102
|
try {
|
|
97
|
-
|
|
103
|
+
const capabilityContext = createCapabilityContext();
|
|
104
|
+
await config.execute(event, capabilityContext);
|
|
98
105
|
process.stdout.write(
|
|
99
106
|
`\n<output>${JSON.stringify({ status: "success" })}</output>\n`,
|
|
100
107
|
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Client } from "@notionhq/client";
|
|
2
|
+
import type { ClientOptions } from "@notionhq/client/build/src/Client.js";
|
|
3
|
+
|
|
4
|
+
export type CapabilityContext = {
|
|
5
|
+
/** Notion API SDK client for this execution. */
|
|
6
|
+
notion: Client;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function createCapabilityContext(): CapabilityContext {
|
|
10
|
+
const options: ClientOptions = {};
|
|
11
|
+
|
|
12
|
+
if (process.env.NOTION_API_BASE_URL) {
|
|
13
|
+
options.baseUrl = process.env.NOTION_API_BASE_URL;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (process.env.NOTION_API_TOKEN) {
|
|
17
|
+
options.auth = process.env.NOTION_API_TOKEN;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const notion = new Client(options);
|
|
21
|
+
|
|
22
|
+
return { notion };
|
|
23
|
+
}
|
package/src/capabilities/sync.ts
CHANGED
|
@@ -14,6 +14,8 @@ import type {
|
|
|
14
14
|
TextValue,
|
|
15
15
|
TimeUnit,
|
|
16
16
|
} from "../types.js";
|
|
17
|
+
import type { CapabilityContext } from "./context.js";
|
|
18
|
+
import { createCapabilityContext } from "./context.js";
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Maps a property configuration to its corresponding value type.
|
|
@@ -96,7 +98,7 @@ export type SyncChange<PK extends string, S extends PropertySchema<PK>> =
|
|
|
96
98
|
/**
|
|
97
99
|
* Result returned from the sync execute function.
|
|
98
100
|
*/
|
|
99
|
-
export type SyncExecutionResult<PK extends string,
|
|
101
|
+
export type SyncExecutionResult<PK extends string, State = unknown> = {
|
|
100
102
|
/**
|
|
101
103
|
* The batch of changes to apply in this execution.
|
|
102
104
|
* Can include upserts (create/update) and deletes.
|
|
@@ -105,18 +107,18 @@ export type SyncExecutionResult<PK extends string, Context = unknown> = {
|
|
|
105
107
|
|
|
106
108
|
/**
|
|
107
109
|
* Indicates whether there is more data to fetch.
|
|
108
|
-
* - `true`: More data available, will trigger another execution with
|
|
110
|
+
* - `true`: More data available, will trigger another execution with nextState
|
|
109
111
|
* - `false`: No more data to fetch, sync is complete
|
|
110
112
|
*/
|
|
111
113
|
hasMore: boolean;
|
|
112
114
|
|
|
113
115
|
/**
|
|
114
|
-
* Optional
|
|
116
|
+
* Optional state data to pass to the next execution.
|
|
115
117
|
* Required if `hasMore` is `true`, ignored if `hasMore` is `false`.
|
|
116
118
|
* This can be any type of data (cursor, page number, timestamp, etc.).
|
|
117
|
-
* The same data will be provided
|
|
119
|
+
* The same data will be provided as `state` in the next execution.
|
|
118
120
|
*/
|
|
119
|
-
|
|
121
|
+
nextState?: State;
|
|
120
122
|
};
|
|
121
123
|
|
|
122
124
|
/**
|
|
@@ -126,7 +128,7 @@ export type SyncExecutionResult<PK extends string, Context = unknown> = {
|
|
|
126
128
|
export type SyncConfiguration<
|
|
127
129
|
PK extends string,
|
|
128
130
|
S extends Schema<PK>,
|
|
129
|
-
|
|
131
|
+
State = unknown,
|
|
130
132
|
> = {
|
|
131
133
|
/**
|
|
132
134
|
* The property of the data source that maps to a "primary key" in the
|
|
@@ -168,34 +170,32 @@ export type SyncConfiguration<
|
|
|
168
170
|
* A function that fetches the data to sync from the third-party service.
|
|
169
171
|
*
|
|
170
172
|
* This function can return all data at once, or implement pagination by:
|
|
171
|
-
* 1. Returning a batch of changes with `hasMore: true` and a `
|
|
172
|
-
* 2. The runtime will call execute again with that
|
|
173
|
+
* 1. Returning a batch of changes with `hasMore: true` and a `nextState`
|
|
174
|
+
* 2. The runtime will call execute again with that state
|
|
173
175
|
* 3. Continue until `hasMore: false` is returned
|
|
174
176
|
*
|
|
175
177
|
* The runtime will handle diffing against the data source and creating,
|
|
176
178
|
* updating, and deleting pages as necessary.
|
|
177
179
|
*
|
|
178
|
-
* @param
|
|
179
|
-
* @
|
|
180
|
+
* @param state - User-defined state from the previous execution (undefined on first call)
|
|
181
|
+
* @param context - Runtime context, including Notion client
|
|
182
|
+
* @returns A result containing changes, hasMore status, and optional nextState
|
|
180
183
|
*/
|
|
181
|
-
execute: (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
primaryKeyProperty: PK;
|
|
186
|
-
changes: SyncChange<PK, PropertySchema<PK>>[];
|
|
187
|
-
hasMore: boolean;
|
|
188
|
-
nextContext?: Context;
|
|
189
|
-
mode?: SyncMode;
|
|
184
|
+
execute: (
|
|
185
|
+
state: State | undefined,
|
|
186
|
+
context: CapabilityContext,
|
|
187
|
+
) => Promise<SyncExecutionResult<PK, State>>;
|
|
190
188
|
};
|
|
191
189
|
|
|
192
190
|
export type SyncCapability = ReturnType<typeof createSyncCapability>;
|
|
193
191
|
|
|
194
192
|
/**
|
|
195
|
-
*
|
|
193
|
+
* Runtime context object passed from the runtime to sync capability handlers.
|
|
196
194
|
*/
|
|
197
195
|
type RuntimeContext<UserContext = unknown> = {
|
|
198
|
-
/** The user-defined/-controlled
|
|
196
|
+
/** The user-defined/-controlled state (cursor, pagination state, etc.) */
|
|
197
|
+
state?: UserContext;
|
|
198
|
+
/** Legacy field for user-defined/-controlled state. */
|
|
199
199
|
userContext?: UserContext;
|
|
200
200
|
};
|
|
201
201
|
|
|
@@ -221,9 +221,10 @@ export function createSyncCapability<
|
|
|
221
221
|
schedule: parseSchedule(syncConfiguration.schedule),
|
|
222
222
|
},
|
|
223
223
|
async handler(runtimeContext?: RuntimeContext<Context>) {
|
|
224
|
-
const
|
|
224
|
+
const capabilityContext = createCapabilityContext();
|
|
225
|
+
const state = runtimeContext?.state ?? runtimeContext?.userContext;
|
|
225
226
|
const executionResult = await syncConfiguration
|
|
226
|
-
.execute(
|
|
227
|
+
.execute(state, capabilityContext)
|
|
227
228
|
.catch((err) => {
|
|
228
229
|
throw new ExecutionError(err);
|
|
229
230
|
});
|
|
@@ -231,7 +232,7 @@ export function createSyncCapability<
|
|
|
231
232
|
const result = {
|
|
232
233
|
changes: executionResult.changes,
|
|
233
234
|
hasMore: executionResult.hasMore,
|
|
234
|
-
nextUserContext: executionResult.
|
|
235
|
+
nextUserContext: executionResult.nextState,
|
|
235
236
|
};
|
|
236
237
|
|
|
237
238
|
process.stdout.write(`\n<output>${JSON.stringify(result)}</output>\n`);
|
package/src/capabilities/tool.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Ajv, type JSONSchemaType } from "ajv";
|
|
2
2
|
import type { JSONValue } from "../types.js";
|
|
3
|
+
import type { CapabilityContext } from "./context.js";
|
|
4
|
+
import { createCapabilityContext } from "./context.js";
|
|
3
5
|
|
|
4
6
|
export interface ToolConfiguration<
|
|
5
7
|
I extends JSONValue,
|
|
@@ -9,7 +11,7 @@ export interface ToolConfiguration<
|
|
|
9
11
|
description: string;
|
|
10
12
|
schema: JSONSchemaType<I>;
|
|
11
13
|
outputSchema?: JSONSchemaType<O>;
|
|
12
|
-
execute: (input: I) => O | Promise<O>;
|
|
14
|
+
execute: (input: I, context: CapabilityContext) => O | Promise<O>;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -127,7 +129,8 @@ export function createToolCapability<
|
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
try {
|
|
130
|
-
const
|
|
132
|
+
const capabilityContext = createCapabilityContext();
|
|
133
|
+
const result = await config.execute(input, capabilityContext);
|
|
131
134
|
if (validateOutput && !validateOutput(result)) {
|
|
132
135
|
const result = {
|
|
133
136
|
_tag: "error" as const,
|
package/src/index.ts
CHANGED
|
@@ -2,9 +2,10 @@ export { emojiIcon, imageIcon, notionIcon, place } from "./builder.js";
|
|
|
2
2
|
export type {
|
|
3
3
|
AutomationCapability,
|
|
4
4
|
AutomationConfiguration,
|
|
5
|
-
|
|
5
|
+
AutomationEvent,
|
|
6
6
|
PageObjectResponse,
|
|
7
7
|
} from "./capabilities/automation.js";
|
|
8
|
+
export type { CapabilityContext } from "./capabilities/context.js";
|
|
8
9
|
export type {
|
|
9
10
|
NotionManagedOAuthConfiguration,
|
|
10
11
|
OAuthCapability,
|
package/src/worker.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AutomationCapability,
|
|
3
3
|
AutomationConfiguration,
|
|
4
|
-
|
|
4
|
+
AutomationEvent,
|
|
5
5
|
} from "./capabilities/automation.js";
|
|
6
6
|
import { createAutomationCapability } from "./capabilities/automation.js";
|
|
7
|
+
import type { CapabilityContext } from "./capabilities/context.js";
|
|
7
8
|
import type {
|
|
8
9
|
NotionManagedOAuthConfiguration,
|
|
9
10
|
OAuthCapability,
|
|
@@ -21,7 +22,8 @@ import type { JSONValue } from "./types.js";
|
|
|
21
22
|
// Re-export types for convenience
|
|
22
23
|
export type {
|
|
23
24
|
AutomationConfiguration,
|
|
24
|
-
|
|
25
|
+
AutomationEvent,
|
|
26
|
+
CapabilityContext,
|
|
25
27
|
OAuthConfiguration,
|
|
26
28
|
NotionManagedOAuthConfiguration,
|
|
27
29
|
UserManagedOAuthConfiguration,
|
|
@@ -120,7 +122,7 @@ export class Worker {
|
|
|
120
122
|
* },
|
|
121
123
|
* required: ["name"],
|
|
122
124
|
* },
|
|
123
|
-
* execute: ({ name }) => {
|
|
125
|
+
* execute: ({ name }, { notion }) => {
|
|
124
126
|
* return `Hello, ${name}!`;
|
|
125
127
|
* },
|
|
126
128
|
* })
|
|
@@ -154,8 +156,8 @@ export class Worker {
|
|
|
154
156
|
* worker.automation("sendWelcomeEmail", {
|
|
155
157
|
* title: "Send Welcome Email",
|
|
156
158
|
* description: "Sends a welcome email when a new user is added",
|
|
157
|
-
* execute: async (
|
|
158
|
-
* const { pageId, pageData } =
|
|
159
|
+
* execute: async (event, { notion }) => {
|
|
160
|
+
* const { pageId, pageData } = event;
|
|
159
161
|
*
|
|
160
162
|
* // Access page properties from the Public API format
|
|
161
163
|
* if (pageData) {
|