@notionhq/workers 0.1.0 → 0.3.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/ajv-formats.d.js +0 -0
- package/dist/capabilities/ai_connector.d.ts +97 -0
- package/dist/capabilities/ai_connector.d.ts.map +1 -0
- package/dist/capabilities/ai_connector.js +54 -0
- package/dist/capabilities/ai_connector.test.d.ts +2 -0
- package/dist/capabilities/ai_connector.test.d.ts.map +1 -0
- package/dist/capabilities/automation.d.ts.map +1 -1
- package/dist/capabilities/automation.js +10 -10
- package/dist/capabilities/output.d.ts +5 -0
- package/dist/capabilities/output.d.ts.map +1 -0
- package/dist/capabilities/output.js +10 -0
- package/dist/capabilities/stateful-capability.d.ts +30 -0
- package/dist/capabilities/stateful-capability.d.ts.map +1 -0
- package/dist/capabilities/stateful-capability.js +50 -0
- package/dist/capabilities/stateful-capability.test.d.ts +2 -0
- package/dist/capabilities/stateful-capability.test.d.ts.map +1 -0
- package/dist/capabilities/sync.d.ts +77 -30
- package/dist/capabilities/sync.d.ts.map +1 -1
- package/dist/capabilities/sync.js +26 -64
- package/dist/capabilities/tool.d.ts.map +1 -1
- package/dist/capabilities/tool.js +7 -14
- package/dist/capabilities/webhook.d.ts +101 -0
- package/dist/capabilities/webhook.d.ts.map +1 -0
- package/dist/capabilities/webhook.js +47 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/pacer.d.ts +24 -0
- package/dist/pacer.d.ts.map +1 -0
- package/dist/pacer.js +14 -0
- package/dist/pacer.test.d.ts +2 -0
- package/dist/pacer.test.d.ts.map +1 -0
- package/dist/pacer_internal.d.ts +13 -0
- package/dist/pacer_internal.d.ts.map +1 -0
- package/dist/pacer_internal.js +49 -0
- package/dist/schema.d.ts +28 -18
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -2
- package/dist/types.d.ts +5 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/worker.d.ts +222 -7
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +184 -8
- package/dist/worker.test.d.ts +2 -0
- package/dist/worker.test.d.ts.map +1 -0
- package/package.json +7 -2
- package/src/ajv-formats.d.ts +7 -0
- package/src/capabilities/ai_connector.test.ts +341 -0
- package/src/capabilities/ai_connector.ts +194 -0
- package/src/capabilities/automation.test.ts +2 -2
- package/src/capabilities/automation.ts +10 -6
- package/src/capabilities/output.ts +8 -0
- package/src/capabilities/stateful-capability.test.ts +25 -0
- package/src/capabilities/stateful-capability.ts +87 -0
- package/src/capabilities/sync.test.ts +178 -35
- package/src/capabilities/sync.ts +63 -100
- package/src/capabilities/tool.test.ts +47 -3
- package/src/capabilities/tool.ts +7 -6
- package/src/capabilities/webhook.ts +148 -0
- package/src/index.ts +31 -0
- package/src/pacer.test.ts +110 -0
- package/src/pacer.ts +25 -0
- package/src/pacer_internal.ts +94 -0
- package/src/schema.ts +29 -19
- package/src/types.ts +4 -2
- package/src/worker.test.ts +167 -0
- package/src/worker.ts +335 -10
|
File without changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type PacerDeclaration, type PacerEntry } from "../pacer_internal.js";
|
|
2
|
+
import type { HandlerOptions, Schedule } from "../types.js";
|
|
3
|
+
import type { CapabilityContext } from "./context.js";
|
|
4
|
+
import { type StatefulCapabilityMode, type StatefulExecutionResult, type RuntimeContext as StatefulRuntimeContext } from "./stateful-capability.js";
|
|
5
|
+
export type AiConnectorArchetype = "chat" | "project";
|
|
6
|
+
/**
|
|
7
|
+
* AI connector syncs are incremental-only for now.
|
|
8
|
+
*
|
|
9
|
+
* Unlike collection syncs, AI connector ingestion does not yet support
|
|
10
|
+
* replace-style reconciliation semantics, so exposing `replace` here would
|
|
11
|
+
* encourage a misleading reset-and-replay model.
|
|
12
|
+
*/
|
|
13
|
+
export type AiConnectorMode = Exclude<StatefulCapabilityMode, "replace">;
|
|
14
|
+
export type AiConnectorChatAuthor = {
|
|
15
|
+
id: string;
|
|
16
|
+
username: string;
|
|
17
|
+
};
|
|
18
|
+
export type AiConnectorChatMessage = {
|
|
19
|
+
id: string;
|
|
20
|
+
content: string;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
editedTimestamp?: string;
|
|
23
|
+
author: AiConnectorChatAuthor;
|
|
24
|
+
};
|
|
25
|
+
export type AiConnectorChatChannel = {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
export type AiConnectorChatRecord = {
|
|
30
|
+
createdAt: string;
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
externalUrl?: string;
|
|
33
|
+
channel: AiConnectorChatChannel;
|
|
34
|
+
threadId?: string;
|
|
35
|
+
messages: AiConnectorChatMessage[];
|
|
36
|
+
chatType?: string;
|
|
37
|
+
};
|
|
38
|
+
export type AiConnectorProjectBlock = {
|
|
39
|
+
id: string;
|
|
40
|
+
type: string;
|
|
41
|
+
content: string;
|
|
42
|
+
};
|
|
43
|
+
export type AiConnectorProjectRecord = {
|
|
44
|
+
name: string;
|
|
45
|
+
createdAt: string;
|
|
46
|
+
updatedAt: string;
|
|
47
|
+
externalUrl?: string;
|
|
48
|
+
priority?: string;
|
|
49
|
+
teams?: string[];
|
|
50
|
+
targetEnd?: string;
|
|
51
|
+
createdBy?: {
|
|
52
|
+
id: string;
|
|
53
|
+
};
|
|
54
|
+
blocks: AiConnectorProjectBlock[];
|
|
55
|
+
};
|
|
56
|
+
export type AiConnectorRecordByArchetype = {
|
|
57
|
+
chat: AiConnectorChatRecord;
|
|
58
|
+
project: AiConnectorProjectRecord;
|
|
59
|
+
};
|
|
60
|
+
export type AiConnectorChangeUpsert<A extends AiConnectorArchetype> = {
|
|
61
|
+
type: "upsert";
|
|
62
|
+
key: string;
|
|
63
|
+
record: AiConnectorRecordByArchetype[A];
|
|
64
|
+
};
|
|
65
|
+
export type AiConnectorChange<A extends AiConnectorArchetype> = AiConnectorChangeUpsert<A>;
|
|
66
|
+
export type AiConnectorExecutionResult<A extends AiConnectorArchetype, State = unknown> = StatefulExecutionResult<AiConnectorChange<A>, State>;
|
|
67
|
+
export type AiConnectorConfiguration<A extends AiConnectorArchetype, State = unknown> = {
|
|
68
|
+
/**
|
|
69
|
+
* The Notion record ID of an existing custom connector in the target workspace.
|
|
70
|
+
*
|
|
71
|
+
* This must be the connector record UUID that Notion created, not an external
|
|
72
|
+
* source identifier.
|
|
73
|
+
*/
|
|
74
|
+
aiConnectorId: string;
|
|
75
|
+
archetype: A;
|
|
76
|
+
mode?: AiConnectorMode;
|
|
77
|
+
schedule?: Schedule;
|
|
78
|
+
execute: (state: State | undefined, context: CapabilityContext) => Promise<AiConnectorExecutionResult<A, State>>;
|
|
79
|
+
};
|
|
80
|
+
export type AiConnectorCapability = ReturnType<typeof createAiConnectorCapability>;
|
|
81
|
+
export declare function createAiConnectorCapability<A extends AiConnectorArchetype, State = unknown>(key: string, configuration: AiConnectorConfiguration<A, State>, pacerDeclarations?: readonly PacerDeclaration[]): {
|
|
82
|
+
_tag: "ai_connector";
|
|
83
|
+
key: string;
|
|
84
|
+
config: {
|
|
85
|
+
schedule?: import("../types.js").SyncSchedule;
|
|
86
|
+
mode?: "incremental";
|
|
87
|
+
aiConnectorId: string;
|
|
88
|
+
archetype: A;
|
|
89
|
+
};
|
|
90
|
+
handler(runtimeContext?: StatefulRuntimeContext<State>, options?: HandlerOptions): Promise<{
|
|
91
|
+
nextPacerStates: Record<string, PacerEntry>;
|
|
92
|
+
nextUserContext?: State & ({} | null);
|
|
93
|
+
changes: AiConnectorChange<A>[];
|
|
94
|
+
hasMore: boolean;
|
|
95
|
+
}>;
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=ai_connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai_connector.d.ts","sourceRoot":"","sources":["../../src/capabilities/ai_connector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ExecutionError } from "../error.js";
|
|
2
|
+
import {
|
|
3
|
+
getPacerState,
|
|
4
|
+
initPacerState
|
|
5
|
+
} from "../pacer_internal.js";
|
|
6
|
+
import { createCapabilityContext } from "./context.js";
|
|
7
|
+
import { writeOutput } from "./output.js";
|
|
8
|
+
import {
|
|
9
|
+
parseSchedule
|
|
10
|
+
} from "./stateful-capability.js";
|
|
11
|
+
function createAiConnectorCapability(key, configuration, pacerDeclarations) {
|
|
12
|
+
return {
|
|
13
|
+
_tag: "ai_connector",
|
|
14
|
+
key,
|
|
15
|
+
config: {
|
|
16
|
+
aiConnectorId: configuration.aiConnectorId,
|
|
17
|
+
archetype: configuration.archetype,
|
|
18
|
+
...configuration.mode === void 0 ? {} : { mode: configuration.mode },
|
|
19
|
+
...configuration.schedule === void 0 ? {} : { schedule: parseSchedule(configuration.schedule) }
|
|
20
|
+
},
|
|
21
|
+
async handler(runtimeContext, options) {
|
|
22
|
+
const capabilityContext = createCapabilityContext();
|
|
23
|
+
const state = runtimeContext?.state ?? runtimeContext?.userContext;
|
|
24
|
+
initPacerState(runtimeContext?.pacers, pacerDeclarations);
|
|
25
|
+
let executionResult;
|
|
26
|
+
try {
|
|
27
|
+
executionResult = await configuration.execute(state, capabilityContext);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
const error = new ExecutionError(err);
|
|
30
|
+
if (!options?.concreteOutput) {
|
|
31
|
+
writeOutput({
|
|
32
|
+
_tag: "error",
|
|
33
|
+
error: { name: error.name, message: error.message }
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
const result = {
|
|
39
|
+
changes: executionResult.changes,
|
|
40
|
+
hasMore: executionResult.hasMore,
|
|
41
|
+
...executionResult.nextState === void 0 ? {} : { nextUserContext: executionResult.nextState },
|
|
42
|
+
nextPacerStates: getPacerState().pacers
|
|
43
|
+
};
|
|
44
|
+
if (options?.concreteOutput) {
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
writeOutput({ _tag: "success", value: result });
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
createAiConnectorCapability
|
|
54
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai_connector.test.d.ts","sourceRoot":"","sources":["../../src/capabilities/ai_connector.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation.d.ts","sourceRoot":"","sources":["../../src/capabilities/automation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"automation.d.ts","sourceRoot":"","sources":["../../src/capabilities/automation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAItD;;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;;;;;;;mBAUtB,eAAe,YACZ,cAAc,GACtB,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;EA4B9C"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ExecutionError } from "../error.js";
|
|
2
2
|
import { createCapabilityContext } from "./context.js";
|
|
3
|
+
import { writeOutput } from "./output.js";
|
|
3
4
|
function createAutomationCapability(key, config) {
|
|
4
5
|
return {
|
|
5
6
|
_tag: "automation",
|
|
@@ -15,20 +16,19 @@ function createAutomationCapability(key, config) {
|
|
|
15
16
|
if (options?.concreteOutput) {
|
|
16
17
|
return { status: "success" };
|
|
17
18
|
} else {
|
|
18
|
-
|
|
19
|
-
`
|
|
20
|
-
<output>${JSON.stringify({ _tag: "success", value: { status: "success" } })}</output>
|
|
21
|
-
`
|
|
22
|
-
);
|
|
19
|
+
writeOutput({ _tag: "success", value: { status: "success" } });
|
|
23
20
|
}
|
|
24
21
|
} catch (err) {
|
|
25
22
|
const error = new ExecutionError(err);
|
|
26
23
|
if (!options?.concreteOutput) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
writeOutput({
|
|
25
|
+
_tag: "error",
|
|
26
|
+
error: {
|
|
27
|
+
name: error.name,
|
|
28
|
+
message: error.message,
|
|
29
|
+
trace: error.stack
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
32
|
}
|
|
33
33
|
throw error;
|
|
34
34
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/capabilities/output.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAIhD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PacerEntry } from "../pacer_internal.js";
|
|
2
|
+
import type { Schedule, SyncSchedule } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Shared lifecycle mode used by sync-like capabilities.
|
|
5
|
+
*/
|
|
6
|
+
export type StatefulCapabilityMode = "replace" | "incremental";
|
|
7
|
+
/**
|
|
8
|
+
* Base runtime context shared by sync-like capabilities.
|
|
9
|
+
*/
|
|
10
|
+
export type RuntimeContext<UserContext = unknown> = {
|
|
11
|
+
/** The user-defined/-controlled state (cursor, pagination state, etc.) */
|
|
12
|
+
state?: UserContext;
|
|
13
|
+
/** Legacy field for user-defined/-controlled state. */
|
|
14
|
+
userContext?: UserContext;
|
|
15
|
+
/** Pacer state from the server for rate limiting. */
|
|
16
|
+
pacers?: Record<string, PacerEntry>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Shared execution result returned from stateful capability execute functions.
|
|
20
|
+
*/
|
|
21
|
+
export type StatefulExecutionResult<Change, State = unknown> = {
|
|
22
|
+
changes: Change[];
|
|
23
|
+
hasMore: boolean;
|
|
24
|
+
nextState?: State;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Parses a user-friendly schedule string into the normalized backend format.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseSchedule(schedule: Schedule): SyncSchedule;
|
|
30
|
+
//# sourceMappingURL=stateful-capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateful-capability.d.ts","sourceRoot":"","sources":["../../src/capabilities/stateful-capability.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAY,MAAM,aAAa,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,aAAa,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,WAAW,GAAG,OAAO,IAAI;IACnD,0EAA0E;IAC1E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,uDAAuD;IACvD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,IAAI;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,KAAK,CAAC;CAClB,CAAC;AASF;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,CA8C9D"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { unreachable } from "../error.js";
|
|
2
|
+
const MS_PER_MINUTE = 60 * 1e3;
|
|
3
|
+
const MS_PER_HOUR = 60 * MS_PER_MINUTE;
|
|
4
|
+
const MS_PER_DAY = 24 * MS_PER_HOUR;
|
|
5
|
+
const MIN_INTERVAL_MS = MS_PER_MINUTE;
|
|
6
|
+
const MAX_INTERVAL_MS = 7 * MS_PER_DAY;
|
|
7
|
+
function parseSchedule(schedule) {
|
|
8
|
+
if (schedule === "continuous") {
|
|
9
|
+
return { type: "continuous" };
|
|
10
|
+
}
|
|
11
|
+
if (schedule === "manual") {
|
|
12
|
+
return { type: "manual" };
|
|
13
|
+
}
|
|
14
|
+
const match = schedule.match(/^(\d+)(m|h|d)$/);
|
|
15
|
+
if (!match || !match[1] || !match[2]) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`Invalid schedule format: "${schedule}". Use "continuous" or an interval like "30m", "1h", "1d".`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
const value = parseInt(match[1], 10);
|
|
21
|
+
const unit = match[2];
|
|
22
|
+
let intervalMs;
|
|
23
|
+
switch (unit) {
|
|
24
|
+
case "m":
|
|
25
|
+
intervalMs = value * MS_PER_MINUTE;
|
|
26
|
+
break;
|
|
27
|
+
case "h":
|
|
28
|
+
intervalMs = value * MS_PER_HOUR;
|
|
29
|
+
break;
|
|
30
|
+
case "d":
|
|
31
|
+
intervalMs = value * MS_PER_DAY;
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
unreachable(unit);
|
|
35
|
+
}
|
|
36
|
+
if (intervalMs < MIN_INTERVAL_MS) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Schedule interval must be at least 1 minute. Got: "${schedule}"`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
if (intervalMs > MAX_INTERVAL_MS) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Schedule interval must be at most 7 days. Got: "${schedule}"`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return { type: "interval", intervalMs };
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
parseSchedule
|
|
50
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateful-capability.test.d.ts","sourceRoot":"","sources":["../../src/capabilities/stateful-capability.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { type PacerDeclaration } from "../pacer_internal.js";
|
|
1
2
|
import type { PropertyConfiguration, PropertySchema, Schema } from "../schema.js";
|
|
2
|
-
import type { HandlerOptions, Icon, PeopleValue, PlaceValue, RelationValue, Schedule,
|
|
3
|
+
import type { HandlerOptions, Icon, PeopleValue, PlaceValue, RelationValue, Schedule, TextValue } from "../types.js";
|
|
4
|
+
import type { DatabaseHandle } from "../worker.js";
|
|
3
5
|
import type { CapabilityContext } from "./context.js";
|
|
6
|
+
import { type StatefulCapabilityMode, type RuntimeContext as StatefulRuntimeContext } from "./stateful-capability.js";
|
|
4
7
|
/**
|
|
5
8
|
* Maps a property configuration to its corresponding value type.
|
|
6
9
|
*/
|
|
@@ -14,7 +17,7 @@ type PropertyValueType<T extends PropertyConfiguration> = T extends {
|
|
|
14
17
|
/**
|
|
15
18
|
* Sync mode determines how the sync handles data lifecycle.
|
|
16
19
|
*/
|
|
17
|
-
export type SyncMode =
|
|
20
|
+
export type SyncMode = StatefulCapabilityMode;
|
|
18
21
|
/**
|
|
19
22
|
* A change representing a record to be created or updated.
|
|
20
23
|
*/
|
|
@@ -25,9 +28,13 @@ export type SyncChangeUpsert<PK extends string, S extends PropertySchema<PK>> =
|
|
|
25
28
|
type: "upsert";
|
|
26
29
|
/**
|
|
27
30
|
* A unique identifier for this record, used to match against existing pages.
|
|
28
|
-
* This value will be stored in the property specified by `primaryKeyProperty`.
|
|
29
31
|
*/
|
|
30
32
|
key: string;
|
|
33
|
+
/**
|
|
34
|
+
* The key of the database to write to. If omitted, defaults to
|
|
35
|
+
* the database associated with the sync capability.
|
|
36
|
+
*/
|
|
37
|
+
targetDatabaseKey?: string;
|
|
31
38
|
/**
|
|
32
39
|
* The property values for this record.
|
|
33
40
|
* Keys must match the property names defined in the schema.
|
|
@@ -36,6 +43,13 @@ export type SyncChangeUpsert<PK extends string, S extends PropertySchema<PK>> =
|
|
|
36
43
|
properties: {
|
|
37
44
|
[Property in keyof S]: PropertyValueType<S[Property]>;
|
|
38
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* When this record was last updated in the upstream system.
|
|
48
|
+
* ISO 8601 string (e.g. `"2026-03-19T12:00:00Z"`).
|
|
49
|
+
* Used for conflict resolution when multiple syncs write to the same database.
|
|
50
|
+
* Recommended, but optional.
|
|
51
|
+
*/
|
|
52
|
+
upstreamUpdatedAt?: string;
|
|
39
53
|
/**
|
|
40
54
|
* Optional icon to use as the icon for this row's page.
|
|
41
55
|
* Use the `Builder.emojiIcon()`, `Builder.notionIcon()`, or `Builder.imageIcon()` helpers.
|
|
@@ -58,9 +72,13 @@ export type SyncChangeDelete = {
|
|
|
58
72
|
type: "delete";
|
|
59
73
|
/**
|
|
60
74
|
* The unique identifier of the record to delete.
|
|
61
|
-
* Must match the `key` of a previously upserted record.
|
|
62
75
|
*/
|
|
63
76
|
key: string;
|
|
77
|
+
/**
|
|
78
|
+
* The key of the database to delete from. If omitted, defaults to
|
|
79
|
+
* the database associated with the sync capability.
|
|
80
|
+
*/
|
|
81
|
+
targetDatabaseKey?: string;
|
|
64
82
|
};
|
|
65
83
|
/**
|
|
66
84
|
* A change to be applied to the synced database.
|
|
@@ -91,20 +109,13 @@ export type SyncExecutionResult<PK extends string, State = unknown> = {
|
|
|
91
109
|
nextState?: State;
|
|
92
110
|
};
|
|
93
111
|
/**
|
|
94
|
-
*
|
|
95
|
-
* source and a third-party source.
|
|
112
|
+
* Configuration for a sync capability that syncs data to a database.
|
|
96
113
|
*/
|
|
97
114
|
export type SyncConfiguration<PK extends string, S extends Schema<PK>, State = unknown> = {
|
|
98
115
|
/**
|
|
99
|
-
* The
|
|
100
|
-
* third-party data. This is used to match existing pages to
|
|
101
|
-
* records in the third-party service. Must be a property defined in the schema.
|
|
116
|
+
* The database to sync data into.
|
|
102
117
|
*/
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The schema defining the structure of properties in the collection.
|
|
106
|
-
*/
|
|
107
|
-
schema: S;
|
|
118
|
+
database: DatabaseHandle<PK, S>;
|
|
108
119
|
/**
|
|
109
120
|
* How the sync handles data lifecycle:
|
|
110
121
|
* - "replace": Each sync returns the complete dataset. After hasMore:false,
|
|
@@ -119,6 +130,7 @@ export type SyncConfiguration<PK extends string, S extends Schema<PK>, State = u
|
|
|
119
130
|
/**
|
|
120
131
|
* How often the sync should run.
|
|
121
132
|
* - "continuous": Run as frequently as the system allows
|
|
133
|
+
* - "manual": Only run when explicitly triggered
|
|
122
134
|
* - Interval string: Run at specified intervals, e.g. "1h", "30m", "1d"
|
|
123
135
|
*
|
|
124
136
|
* Minimum interval: 1 minute ("1m")
|
|
@@ -146,34 +158,69 @@ export type SyncConfiguration<PK extends string, S extends Schema<PK>, State = u
|
|
|
146
158
|
};
|
|
147
159
|
export type SyncCapability = ReturnType<typeof createSyncCapability>;
|
|
148
160
|
/**
|
|
149
|
-
*
|
|
150
|
-
*/
|
|
151
|
-
type RuntimeContext<UserContext = unknown> = {
|
|
152
|
-
/** The user-defined/-controlled state (cursor, pagination state, etc.) */
|
|
153
|
-
state?: UserContext;
|
|
154
|
-
/** Legacy field for user-defined/-controlled state. */
|
|
155
|
-
userContext?: UserContext;
|
|
156
|
-
};
|
|
157
|
-
/**
|
|
158
|
-
* Creates a special handler for syncing third-party data to a collection.
|
|
161
|
+
* Creates a special handler for syncing third-party data to a database.
|
|
159
162
|
*
|
|
160
163
|
* @param syncConfiguration - The configuration for the sync.
|
|
161
164
|
* @returns A handler function that executes the sync function, and passes data
|
|
162
165
|
* needed to complete the sync back to the platform.
|
|
163
166
|
*/
|
|
164
|
-
export declare function createSyncCapability<PK extends string, S extends Schema<PK>, Context = unknown>(key: string, syncConfiguration: SyncConfiguration<PK, S, Context
|
|
167
|
+
export declare function createSyncCapability<PK extends string, S extends Schema<PK>, Context = unknown>(key: string, syncConfiguration: SyncConfiguration<PK, S, Context>, pacerDeclarations?: readonly PacerDeclaration[]): {
|
|
165
168
|
_tag: "sync";
|
|
166
169
|
key: string;
|
|
167
170
|
config: {
|
|
171
|
+
databaseKey: string;
|
|
168
172
|
primaryKeyProperty: PK;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
schedule: SyncSchedule;
|
|
173
|
+
mode: StatefulCapabilityMode | undefined;
|
|
174
|
+
schedule: import("../types.js").SyncSchedule | undefined;
|
|
172
175
|
};
|
|
173
|
-
handler(runtimeContext?:
|
|
174
|
-
changes:
|
|
176
|
+
handler(runtimeContext?: StatefulRuntimeContext<Context>, options?: HandlerOptions): Promise<{
|
|
177
|
+
changes: ({
|
|
178
|
+
targetDatabaseKey: string;
|
|
179
|
+
/**
|
|
180
|
+
* The type of change. Use `"delete"` to remove a record.
|
|
181
|
+
*/
|
|
182
|
+
type: "delete";
|
|
183
|
+
/**
|
|
184
|
+
* The unique identifier of the record to delete.
|
|
185
|
+
*/
|
|
186
|
+
key: string;
|
|
187
|
+
} | {
|
|
188
|
+
targetDatabaseKey: string;
|
|
189
|
+
/**
|
|
190
|
+
* The type of change. Use `"upsert"` to create or update a record.
|
|
191
|
+
*/
|
|
192
|
+
type: "upsert";
|
|
193
|
+
/**
|
|
194
|
+
* A unique identifier for this record, used to match against existing pages.
|
|
195
|
+
*/
|
|
196
|
+
key: string;
|
|
197
|
+
/**
|
|
198
|
+
* The property values for this record.
|
|
199
|
+
* Keys must match the property names defined in the schema.
|
|
200
|
+
* Use the Builder helpers (e.g., `Builder.title()`, `Builder.richText()`) to create values.
|
|
201
|
+
*/
|
|
202
|
+
properties: PropertySchema<PK> extends infer T extends PropertySchema<PK_1> ? { [Property in keyof T]: PropertyValueType<T[Property]>; } : never;
|
|
203
|
+
/**
|
|
204
|
+
* When this record was last updated in the upstream system.
|
|
205
|
+
* ISO 8601 string (e.g. `"2026-03-19T12:00:00Z"`).
|
|
206
|
+
* Used for conflict resolution when multiple syncs write to the same database.
|
|
207
|
+
* Recommended, but optional.
|
|
208
|
+
*/
|
|
209
|
+
upstreamUpdatedAt?: string;
|
|
210
|
+
/**
|
|
211
|
+
* Optional icon to use as the icon for this row's page.
|
|
212
|
+
* Use the `Builder.emojiIcon()`, `Builder.notionIcon()`, or `Builder.imageIcon()` helpers.
|
|
213
|
+
*/
|
|
214
|
+
icon?: Icon;
|
|
215
|
+
/**
|
|
216
|
+
* Optional markdown content to add to the page body.
|
|
217
|
+
* This will be converted to Notion blocks and added as page content.
|
|
218
|
+
*/
|
|
219
|
+
pageContentMarkdown?: string;
|
|
220
|
+
})[];
|
|
175
221
|
hasMore: boolean;
|
|
176
222
|
nextUserContext: Context | undefined;
|
|
223
|
+
nextPacerStates: Record<string, import("../pacer_internal.js").PacerEntry>;
|
|
177
224
|
}>;
|
|
178
225
|
};
|
|
179
226
|
export {};
|
|
@@ -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,cAAc,EACd,IAAI,EACJ,WAAW,EACX,UAAU,EACV,aAAa,EACb,QAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,27 @@
|
|
|
1
|
-
import { ExecutionError
|
|
1
|
+
import { ExecutionError } from "../error.js";
|
|
2
|
+
import {
|
|
3
|
+
getPacerState,
|
|
4
|
+
initPacerState
|
|
5
|
+
} from "../pacer_internal.js";
|
|
2
6
|
import { createCapabilityContext } from "./context.js";
|
|
3
|
-
|
|
7
|
+
import { writeOutput } from "./output.js";
|
|
8
|
+
import {
|
|
9
|
+
parseSchedule
|
|
10
|
+
} from "./stateful-capability.js";
|
|
11
|
+
function createSyncCapability(key, syncConfiguration, pacerDeclarations) {
|
|
4
12
|
return {
|
|
5
13
|
_tag: "sync",
|
|
6
14
|
key,
|
|
7
15
|
config: {
|
|
8
|
-
|
|
9
|
-
|
|
16
|
+
databaseKey: syncConfiguration.database.key,
|
|
17
|
+
primaryKeyProperty: syncConfiguration.database.config.primaryKeyProperty,
|
|
10
18
|
mode: syncConfiguration.mode,
|
|
11
|
-
schedule: parseSchedule(syncConfiguration.schedule)
|
|
19
|
+
schedule: syncConfiguration.schedule ? parseSchedule(syncConfiguration.schedule) : void 0
|
|
12
20
|
},
|
|
13
21
|
async handler(runtimeContext, options) {
|
|
14
22
|
const capabilityContext = createCapabilityContext();
|
|
15
23
|
const state = runtimeContext?.state ?? runtimeContext?.userContext;
|
|
24
|
+
initPacerState(runtimeContext?.pacers, pacerDeclarations);
|
|
16
25
|
let executionResult;
|
|
17
26
|
try {
|
|
18
27
|
executionResult = await syncConfiguration.execute(
|
|
@@ -22,79 +31,32 @@ function createSyncCapability(key, syncConfiguration) {
|
|
|
22
31
|
} catch (err) {
|
|
23
32
|
const error = new ExecutionError(err);
|
|
24
33
|
if (!options?.concreteOutput) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
34
|
+
writeOutput({
|
|
35
|
+
_tag: "error",
|
|
36
|
+
error: { name: error.name, message: error.message }
|
|
37
|
+
});
|
|
30
38
|
}
|
|
31
39
|
throw error;
|
|
32
40
|
}
|
|
41
|
+
const changes = executionResult.changes.map((change) => ({
|
|
42
|
+
...change,
|
|
43
|
+
targetDatabaseKey: change.targetDatabaseKey ?? syncConfiguration.database.key
|
|
44
|
+
}));
|
|
33
45
|
const result = {
|
|
34
|
-
changes
|
|
46
|
+
changes,
|
|
35
47
|
hasMore: executionResult.hasMore,
|
|
36
|
-
nextUserContext: executionResult.nextState
|
|
48
|
+
nextUserContext: executionResult.nextState,
|
|
49
|
+
nextPacerStates: getPacerState().pacers
|
|
37
50
|
};
|
|
38
51
|
if (options?.concreteOutput) {
|
|
39
52
|
return result;
|
|
40
53
|
} else {
|
|
41
|
-
|
|
42
|
-
`
|
|
43
|
-
<output>${JSON.stringify({ _tag: "success", value: result })}</output>
|
|
44
|
-
`
|
|
45
|
-
);
|
|
54
|
+
writeOutput({ _tag: "success", value: result });
|
|
46
55
|
}
|
|
47
56
|
return result;
|
|
48
57
|
}
|
|
49
58
|
};
|
|
50
59
|
}
|
|
51
|
-
const MS_PER_MINUTE = 60 * 1e3;
|
|
52
|
-
const MS_PER_HOUR = 60 * MS_PER_MINUTE;
|
|
53
|
-
const MS_PER_DAY = 24 * MS_PER_HOUR;
|
|
54
|
-
const MIN_INTERVAL_MS = MS_PER_MINUTE;
|
|
55
|
-
const MAX_INTERVAL_MS = 7 * MS_PER_DAY;
|
|
56
|
-
const DEFAULT_INTERVAL_MS = 30 * MS_PER_MINUTE;
|
|
57
|
-
function parseSchedule(schedule) {
|
|
58
|
-
if (schedule === "continuous") {
|
|
59
|
-
return { type: "continuous" };
|
|
60
|
-
}
|
|
61
|
-
if (!schedule) {
|
|
62
|
-
return { type: "interval", intervalMs: DEFAULT_INTERVAL_MS };
|
|
63
|
-
}
|
|
64
|
-
const match = schedule.match(/^(\d+)(m|h|d)$/);
|
|
65
|
-
if (!match || !match[1] || !match[2]) {
|
|
66
|
-
throw new Error(
|
|
67
|
-
`Invalid schedule format: "${schedule}". Use "continuous" or an interval like "30m", "1h", "1d".`
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
const value = parseInt(match[1], 10);
|
|
71
|
-
const unit = match[2];
|
|
72
|
-
let intervalMs;
|
|
73
|
-
switch (unit) {
|
|
74
|
-
case "m":
|
|
75
|
-
intervalMs = value * MS_PER_MINUTE;
|
|
76
|
-
break;
|
|
77
|
-
case "h":
|
|
78
|
-
intervalMs = value * MS_PER_HOUR;
|
|
79
|
-
break;
|
|
80
|
-
case "d":
|
|
81
|
-
intervalMs = value * MS_PER_DAY;
|
|
82
|
-
break;
|
|
83
|
-
default:
|
|
84
|
-
unreachable(unit);
|
|
85
|
-
}
|
|
86
|
-
if (intervalMs < MIN_INTERVAL_MS) {
|
|
87
|
-
throw new Error(
|
|
88
|
-
`Schedule interval must be at least 1 minute. Got: "${schedule}"`
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
if (intervalMs > MAX_INTERVAL_MS) {
|
|
92
|
-
throw new Error(
|
|
93
|
-
`Schedule interval must be at most 7 days. Got: "${schedule}"`
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
return { type: "interval", intervalMs };
|
|
97
|
-
}
|
|
98
60
|
export {
|
|
99
61
|
createSyncCapability
|
|
100
62
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/capabilities/tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/capabilities/tool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAkEtD,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,aAAa,CAAC,CAAC,CAAC,CAAC;IACzB,YAAY,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAChC,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;;;;;CAON;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM;IAK3B,MAAM;;;;;CAON;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;IAK3B,MAAM;;;;;CAON;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;;;;;;;;;;gBAiBf,SAAS,WAAW,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;gBAC/C,SAAS,GAAG,OAAO,CAC9C;YACA,IAAI,EAAE,SAAS,CAAC;YAChB,KAAK,EAAE,CAAC,CAAC;SACR,GACD;YACA,IAAI,EAAE,OAAO,CAAC;YACd,KAAK,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;aAAE,CAAC;SACnE,CACH;;EA4GD"}
|