@project-ajax/sdk 0.0.72 → 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.
Files changed (39) hide show
  1. package/dist/builder.d.ts +16 -1
  2. package/dist/builder.d.ts.map +1 -1
  3. package/dist/builder.js +4 -0
  4. package/dist/capabilities/automation.d.ts +7 -5
  5. package/dist/capabilities/automation.d.ts.map +1 -1
  6. package/dist/capabilities/automation.js +4 -2
  7. package/dist/capabilities/context.d.ts +7 -0
  8. package/dist/capabilities/context.d.ts.map +1 -0
  9. package/dist/capabilities/context.js +15 -0
  10. package/dist/capabilities/sync.d.ts +21 -22
  11. package/dist/capabilities/sync.d.ts.map +1 -1
  12. package/dist/capabilities/sync.js +5 -3
  13. package/dist/capabilities/sync.test.d.ts +2 -0
  14. package/dist/capabilities/sync.test.d.ts.map +1 -0
  15. package/dist/capabilities/tool.d.ts +2 -1
  16. package/dist/capabilities/tool.d.ts.map +1 -1
  17. package/dist/capabilities/tool.js +3 -1
  18. package/dist/index.d.ts +2 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/schema.d.ts +28 -0
  21. package/dist/schema.d.ts.map +1 -1
  22. package/dist/schema.js +4 -0
  23. package/dist/types.d.ts +12 -0
  24. package/dist/types.d.ts.map +1 -1
  25. package/dist/worker.d.ts +6 -5
  26. package/dist/worker.d.ts.map +1 -1
  27. package/dist/worker.js +3 -3
  28. package/package.json +4 -1
  29. package/src/builder.ts +19 -0
  30. package/src/capabilities/automation.test.ts +21 -11
  31. package/src/capabilities/automation.ts +13 -6
  32. package/src/capabilities/context.ts +23 -0
  33. package/src/capabilities/sync.test.ts +102 -0
  34. package/src/capabilities/sync.ts +29 -25
  35. package/src/capabilities/tool.ts +5 -2
  36. package/src/index.ts +2 -1
  37. package/src/schema.ts +33 -1
  38. package/src/types.ts +14 -0
  39. package/src/worker.ts +7 -5
package/dist/builder.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { NoticonName } from "./icon-names.js";
2
- import type { Icon, NoticonColor, PeopleValue, PlaceValue, TextValue } from "./types.js";
2
+ import type { Icon, NoticonColor, PeopleValue, PlaceValue, RelationReference, TextValue } from "./types.js";
3
3
  /**
4
4
  * Creates a rich text value.
5
5
  */
@@ -83,6 +83,21 @@ export declare function people(...emails: string[]): PeopleValue;
83
83
  * @param value - The place value with lat/lon coordinates and optional name/address
84
84
  */
85
85
  export declare function place(value: PlaceValue): PlaceValue;
86
+ /**
87
+ * Creates a relation reference from a primary key of a related record.
88
+ * Use an array of relation references as the property value.
89
+ *
90
+ * @param primaryKey - The primary key of the related record
91
+ * @example
92
+ * ```typescript
93
+ * // Single relation
94
+ * { Project: [Builder.relation("project-123")] }
95
+ *
96
+ * // Multiple relations
97
+ * { Projects: [Builder.relation("project-123"), Builder.relation("project-456")] }
98
+ * ```
99
+ */
100
+ export declare function relation(primaryKey: string): RelationReference;
86
101
  /**
87
102
  * Creates an emoji icon.
88
103
  * @param emoji - An emoji string (e.g., "🎯", "✨", "🚀")
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAEX,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,SAAS,EACT,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAEnD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAE1C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAEhD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAE/C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAE9C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAEpD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAK/C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CASlD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAYjE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAWvE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,QAAQ,CAAC,EAAE,MAAM,GACf,SAAS,CAcX;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAEhE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAE/C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAK1D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAE/C;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAEvD;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAKnD;AA4CD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,IAAI,EAAE,WAAW,EACjB,KAAK,GAAE,YAAqB,GAC1B,IAAI,CAMN;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAK3C"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAEX,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAEnD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAE1C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAEhD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAE/C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAE9C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAEpD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAK/C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CASlD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAYjE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAWvE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC5B,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,QAAQ,CAAC,EAAE,MAAM,GACf,SAAS,CAcX;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAEhE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAE/C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAK1D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAE/C;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAEvD;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAKnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAE9D;AA4CD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,IAAI,EAAE,WAAW,EACjB,KAAK,GAAE,YAAqB,GAC1B,IAAI,CAMN;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAK3C"}
package/dist/builder.js CHANGED
@@ -94,6 +94,9 @@ function place(value) {
94
94
  }
95
95
  return value;
96
96
  }
97
+ function relation(primaryKey) {
98
+ return { type: "primaryKey", value: primaryKey };
99
+ }
97
100
  function validateDateString(dateString) {
98
101
  if (!/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
99
102
  throw new Error(
@@ -155,6 +158,7 @@ export {
155
158
  people,
156
159
  phoneNumber,
157
160
  place,
161
+ relation,
158
162
  richText,
159
163
  select,
160
164
  status,
@@ -1,7 +1,8 @@
1
+ import type { CapabilityContext } from "./context.js";
1
2
  /**
2
- * Context provided to automation execute functions
3
+ * Event provided to automation execute functions
3
4
  */
4
- export interface AutomationContext {
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 context - Context about the automation trigger, including page data if applicable
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: AutomationContext) => Promise<void> | void;
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(context: AutomationContext): Promise<void>;
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":"AAEA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC;;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;;;;OAIG;IACH,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC9D;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;;;;;;;qBASP,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;EAezD"}
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(context) {
11
+ async handler(event) {
11
12
  try {
12
- await config.execute(context);
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,7 @@
1
+ import { Client } from "@notionhq/client";
2
+ export type CapabilityContext = {
3
+ /** Notion API SDK client for this execution. */
4
+ notion: Client;
5
+ };
6
+ export declare function createCapabilityContext(): CapabilityContext;
7
+ //# sourceMappingURL=context.d.ts.map
@@ -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
- import type { Icon, PeopleValue, PlaceValue, Schedule, SyncSchedule, TextValue } from "../types.js";
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
  */
@@ -7,7 +8,9 @@ type PropertyValueType<T extends PropertyConfiguration> = T extends {
7
8
  type: "people";
8
9
  } ? PeopleValue : T extends {
9
10
  type: "place";
10
- } ? PlaceValue : TextValue;
11
+ } ? PlaceValue : T extends {
12
+ type: "relation";
13
+ } ? RelationValue : TextValue;
11
14
  /**
12
15
  * Sync mode determines how the sync handles data lifecycle.
13
16
  */
@@ -67,7 +70,7 @@ export type SyncChange<PK extends string, S extends PropertySchema<PK>> = SyncCh
67
70
  /**
68
71
  * Result returned from the sync execute function.
69
72
  */
70
- export type SyncExecutionResult<PK extends string, Context = unknown> = {
73
+ export type SyncExecutionResult<PK extends string, State = unknown> = {
71
74
  /**
72
75
  * The batch of changes to apply in this execution.
73
76
  * Can include upserts (create/update) and deletes.
@@ -75,23 +78,23 @@ export type SyncExecutionResult<PK extends string, Context = unknown> = {
75
78
  changes: SyncChange<PK, PropertySchema<PK>>[];
76
79
  /**
77
80
  * Indicates whether there is more data to fetch.
78
- * - `true`: More data available, will trigger another execution with nextContext
81
+ * - `true`: More data available, will trigger another execution with nextState
79
82
  * - `false`: No more data to fetch, sync is complete
80
83
  */
81
84
  hasMore: boolean;
82
85
  /**
83
- * Optional context data to pass to the next execution.
86
+ * Optional state data to pass to the next execution.
84
87
  * Required if `hasMore` is `true`, ignored if `hasMore` is `false`.
85
88
  * This can be any type of data (cursor, page number, timestamp, etc.).
86
- * The same data will be provided in the context parameter of the next execution.
89
+ * The same data will be provided as `state` in the next execution.
87
90
  */
88
- nextContext?: Context;
91
+ nextState?: State;
89
92
  };
90
93
  /**
91
94
  * A configuration object that enables synchronization between a data
92
95
  * source and a third-party source.
93
96
  */
94
- export type SyncConfiguration<PK extends string, S extends Schema<PK>, Context = unknown> = {
97
+ export type SyncConfiguration<PK extends string, S extends Schema<PK>, State = unknown> = {
95
98
  /**
96
99
  * The property of the data source that maps to a "primary key" in the
97
100
  * third-party data. This is used to match existing pages to
@@ -128,31 +131,27 @@ export type SyncConfiguration<PK extends string, S extends Schema<PK>, Context =
128
131
  * A function that fetches the data to sync from the third-party service.
129
132
  *
130
133
  * This function can return all data at once, or implement pagination by:
131
- * 1. Returning a batch of changes with `hasMore: true` and a `nextContext`
132
- * 2. The runtime will call execute again with that context data
134
+ * 1. Returning a batch of changes with `hasMore: true` and a `nextState`
135
+ * 2. The runtime will call execute again with that state
133
136
  * 3. Continue until `hasMore: false` is returned
134
137
  *
135
138
  * The runtime will handle diffing against the data source and creating,
136
139
  * updating, and deleting pages as necessary.
137
140
  *
138
- * @param context - Optional context data from previous execution (undefined on first call)
139
- * @returns A result containing changes, hasMore status, and optional nextContext
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
140
144
  */
141
- execute: (context?: Context) => Promise<SyncExecutionResult<PK, Context>>;
142
- };
143
- export type SyncHandlerResult<PK extends string, Context = unknown> = {
144
- primaryKeyProperty: PK;
145
- changes: SyncChange<PK, PropertySchema<PK>>[];
146
- hasMore: boolean;
147
- nextContext?: Context;
148
- mode?: SyncMode;
145
+ execute: (state: State | undefined, context: CapabilityContext) => Promise<SyncExecutionResult<PK, State>>;
149
146
  };
150
147
  export type SyncCapability = ReturnType<typeof createSyncCapability>;
151
148
  /**
152
- * Context object passed from the runtime to sync capability handlers.
149
+ * Runtime context object passed from the runtime to sync capability handlers.
153
150
  */
154
151
  type RuntimeContext<UserContext = unknown> = {
155
- /** The user-defined/-controlled context (cursor, pagination state, etc.) */
152
+ /** The user-defined/-controlled state (cursor, pagination state, etc.) */
153
+ state?: UserContext;
154
+ /** Legacy field for user-defined/-controlled state. */
156
155
  userContext?: UserContext;
157
156
  };
158
157
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"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"}
@@ -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 userContext = runtimeContext?.userContext;
14
- const executionResult = await syncConfiguration.execute(userContext).catch((err) => {
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.nextContext
22
+ nextUserContext: executionResult.nextState
21
23
  };
22
24
  process.stdout.write(`
23
25
  <output>${JSON.stringify(result)}</output>
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sync.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.test.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.test.ts"],"names":[],"mappings":""}
@@ -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;AAE7C,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,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACtC;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;EA0DF"}
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 result = await config.execute(input);
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, AutomationContext, PageObjectResponse, } from "./capabilities/automation.js";
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";
@@ -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,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,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"}
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/schema.d.ts CHANGED
@@ -45,6 +45,13 @@ export type PropertyConfiguration = {
45
45
  type: "people";
46
46
  } | {
47
47
  type: "place";
48
+ } | {
49
+ type: "relation";
50
+ /**
51
+ * The export name of the sync capability that defines the related collection.
52
+ * This must match the export name used when defining the related sync capability.
53
+ */
54
+ relatedSyncKey: string;
48
55
  };
49
56
  export type Schema<PK extends string> = {
50
57
  /**
@@ -128,4 +135,25 @@ export declare function people(): PropertyConfiguration;
128
135
  * Creates a place property definition for storing geographic locations.
129
136
  */
130
137
  export declare function place(): PropertyConfiguration;
138
+ /**
139
+ * Creates a relation property definition that references another sync capability.
140
+ * The related collection must be defined by a sync capability in the same worker.
141
+ *
142
+ * @param relatedSyncKey - The export name of the sync capability that defines the related collection.
143
+ * @example
144
+ * ```typescript
145
+ * export const projectsSync = sync({...});
146
+ *
147
+ * export const tasksSync = sync({
148
+ * schema: {
149
+ * properties: {
150
+ * "Task Title": Schema.title(),
151
+ * "Project": Schema.relation("projectsSync"),
152
+ * },
153
+ * },
154
+ * ...
155
+ * });
156
+ * ```
157
+ */
158
+ export declare function relation(relatedSyncKey: string): PropertyConfiguration;
131
159
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js CHANGED
@@ -40,6 +40,9 @@ function people() {
40
40
  function place() {
41
41
  return { type: "place" };
42
42
  }
43
+ function relation(relatedSyncKey) {
44
+ return { type: "relation", relatedSyncKey };
45
+ }
43
46
  export {
44
47
  checkbox,
45
48
  date,
@@ -50,6 +53,7 @@ export {
50
53
  people,
51
54
  phoneNumber,
52
55
  place,
56
+ relation,
53
57
  richText,
54
58
  select,
55
59
  status,
package/dist/types.d.ts CHANGED
@@ -162,6 +162,18 @@ export interface PlaceValue {
162
162
  */
163
163
  googlePlaceId?: string;
164
164
  }
165
+ /**
166
+ * A reference to a related record by its primary key.
167
+ */
168
+ export type RelationReference = {
169
+ type: "primaryKey";
170
+ value: string;
171
+ };
172
+ /**
173
+ * Relation value representing references to related records.
174
+ * Each reference identifies a record in the target collection.
175
+ */
176
+ export type RelationValue = RelationReference[];
165
177
  /**
166
178
  * Time units for schedule intervals.
167
179
  * - "m": minutes
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/worker.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- import type { AutomationCapability, AutomationConfiguration, AutomationContext } from "./capabilities/automation.js";
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, AutomationContext, OAuthConfiguration, NotionManagedOAuthConfiguration, UserManagedOAuthConfiguration, SyncConfiguration, ToolConfiguration, };
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 (context) => {
100
- * const { pageId, pageData } = context;
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) {
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,MAAM,8BAA8B,CAAC;AAEtC,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,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"}
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 (context) => {
106
- * const { pageId, pageData } = context;
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.72",
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
  }
package/src/builder.ts CHANGED
@@ -5,6 +5,7 @@ import type {
5
5
  NoticonColor,
6
6
  PeopleValue,
7
7
  PlaceValue,
8
+ RelationReference,
8
9
  TextValue,
9
10
  } from "./types.js";
10
11
 
@@ -199,6 +200,24 @@ export function place(value: PlaceValue): PlaceValue {
199
200
  return value;
200
201
  }
201
202
 
203
+ /**
204
+ * Creates a relation reference from a primary key of a related record.
205
+ * Use an array of relation references as the property value.
206
+ *
207
+ * @param primaryKey - The primary key of the related record
208
+ * @example
209
+ * ```typescript
210
+ * // Single relation
211
+ * { Project: [Builder.relation("project-123")] }
212
+ *
213
+ * // Multiple relations
214
+ * { Projects: [Builder.relation("project-123"), Builder.relation("project-456")] }
215
+ * ```
216
+ */
217
+ export function relation(primaryKey: string): RelationReference {
218
+ return { type: "primaryKey", value: primaryKey };
219
+ }
220
+
202
221
  /**
203
222
  * Validates a date string is in YYYY-MM-DD format and represents a valid date.
204
223
  */
@@ -8,7 +8,7 @@ import {
8
8
  vi,
9
9
  } from "vitest";
10
10
  import { ExecutionError } from "../error.js";
11
- import type { AutomationContext, PageObjectResponse } from "./automation.js";
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 context: AutomationContext = {
48
+ const event = {
49
49
  pageId: "page-123",
50
50
  actionType: "test_action",
51
51
  };
52
52
 
53
- await capability.handler(context);
53
+ await capability.handler(event);
54
54
 
55
- expect(executeFn).toHaveBeenCalledWith(context);
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 context: AutomationContext = {
93
+ const event = {
89
94
  pageId: "page-789",
90
95
  actionType: "process_page",
91
96
  pageData,
92
97
  };
93
98
 
94
- await capability.handler(context);
99
+ await capability.handler(event);
95
100
 
96
- expect(executeFn).toHaveBeenCalledWith(context);
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 context: AutomationContext = {
121
+ const event = {
112
122
  pageId: "page-error",
113
123
  actionType: "error_action",
114
124
  };
115
125
 
116
- await expect(capability.handler(context)).rejects.toThrow(ExecutionError);
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 context: AutomationContext = {
142
+ const event = {
133
143
  actionType: "string_error_action",
134
144
  };
135
145
 
136
- await expect(capability.handler(context)).rejects.toThrow(ExecutionError);
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
- * Context provided to automation execute functions
6
+ * Event provided to automation execute functions
5
7
  */
6
- export interface AutomationContext {
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 context - Context about the automation trigger, including page data if applicable
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: (context: AutomationContext) => Promise<void> | void;
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(context: AutomationContext): Promise<void> {
101
+ async handler(event: AutomationEvent): Promise<void> {
96
102
  try {
97
- await config.execute(context);
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
+ }
@@ -0,0 +1,102 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import * as Builder from "../builder.js";
3
+ import * as Schema from "../schema.js";
4
+ import { createSyncCapability } from "./sync.js";
5
+
6
+ describe("Worker.sync", () => {
7
+ describe("Schema.relation", () => {
8
+ it("creates a relation property configuration", () => {
9
+ const relationProp = Schema.relation("projectsSync");
10
+
11
+ expect(relationProp).toEqual({
12
+ type: "relation",
13
+ relatedSyncKey: "projectsSync",
14
+ });
15
+ });
16
+
17
+ it("can be used in a schema definition", () => {
18
+ const capability = createSyncCapability("tasksSync", {
19
+ primaryKeyProperty: "Task ID",
20
+ schema: {
21
+ defaultName: "Tasks",
22
+ properties: {
23
+ "Task ID": Schema.title(),
24
+ Project: Schema.relation("projectsSync"),
25
+ },
26
+ },
27
+ execute: async () => ({
28
+ changes: [],
29
+ hasMore: false,
30
+ }),
31
+ });
32
+
33
+ expect(capability.config.schema.properties.Project).toEqual({
34
+ type: "relation",
35
+ relatedSyncKey: "projectsSync",
36
+ });
37
+ });
38
+ });
39
+
40
+ describe("Builder.relation", () => {
41
+ it("creates a relation reference from a primary key", () => {
42
+ const value = Builder.relation("project-123");
43
+
44
+ expect(value).toEqual({ type: "primaryKey", value: "project-123" });
45
+ });
46
+
47
+ it("can be used to build relation arrays", () => {
48
+ const value = [
49
+ Builder.relation("project-123"),
50
+ Builder.relation("project-456"),
51
+ ];
52
+
53
+ expect(value).toEqual([
54
+ { type: "primaryKey", value: "project-123" },
55
+ { type: "primaryKey", value: "project-456" },
56
+ ]);
57
+ });
58
+ });
59
+
60
+ describe("SyncedObject with relation properties", () => {
61
+ it("allows relation values in synced objects", async () => {
62
+ const capability = createSyncCapability("tasksSync", {
63
+ primaryKeyProperty: "Task ID",
64
+ schema: {
65
+ defaultName: "Tasks",
66
+ properties: {
67
+ "Task ID": Schema.title(),
68
+ Project: Schema.relation("projectsSync"),
69
+ },
70
+ },
71
+ execute: async () => ({
72
+ changes: [
73
+ {
74
+ type: "upsert",
75
+ key: "task-1",
76
+ properties: {
77
+ "Task ID": Builder.title("TASK-001"),
78
+ Project: [Builder.relation("project-123")],
79
+ },
80
+ },
81
+ {
82
+ type: "upsert",
83
+ key: "task-2",
84
+ properties: {
85
+ "Task ID": Builder.title("TASK-002"),
86
+ Project: [
87
+ Builder.relation("project-123"),
88
+ Builder.relation("project-456"),
89
+ ],
90
+ },
91
+ },
92
+ ],
93
+ hasMore: false,
94
+ }),
95
+ });
96
+
97
+ // Verify the capability is properly configured
98
+ expect(capability._tag).toBe("sync");
99
+ expect(capability.config.primaryKeyProperty).toBe("Task ID");
100
+ });
101
+ });
102
+ });
@@ -8,11 +8,14 @@ import type {
8
8
  Icon,
9
9
  PeopleValue,
10
10
  PlaceValue,
11
+ RelationValue,
11
12
  Schedule,
12
13
  SyncSchedule,
13
14
  TextValue,
14
15
  TimeUnit,
15
16
  } from "../types.js";
17
+ import type { CapabilityContext } from "./context.js";
18
+ import { createCapabilityContext } from "./context.js";
16
19
 
17
20
  /**
18
21
  * Maps a property configuration to its corresponding value type.
@@ -23,7 +26,9 @@ type PropertyValueType<T extends PropertyConfiguration> = T extends {
23
26
  ? PeopleValue
24
27
  : T extends { type: "place" }
25
28
  ? PlaceValue
26
- : TextValue;
29
+ : T extends { type: "relation" }
30
+ ? RelationValue
31
+ : TextValue;
27
32
 
28
33
  /**
29
34
  * Sync mode determines how the sync handles data lifecycle.
@@ -93,7 +98,7 @@ export type SyncChange<PK extends string, S extends PropertySchema<PK>> =
93
98
  /**
94
99
  * Result returned from the sync execute function.
95
100
  */
96
- export type SyncExecutionResult<PK extends string, Context = unknown> = {
101
+ export type SyncExecutionResult<PK extends string, State = unknown> = {
97
102
  /**
98
103
  * The batch of changes to apply in this execution.
99
104
  * Can include upserts (create/update) and deletes.
@@ -102,18 +107,18 @@ export type SyncExecutionResult<PK extends string, Context = unknown> = {
102
107
 
103
108
  /**
104
109
  * Indicates whether there is more data to fetch.
105
- * - `true`: More data available, will trigger another execution with nextContext
110
+ * - `true`: More data available, will trigger another execution with nextState
106
111
  * - `false`: No more data to fetch, sync is complete
107
112
  */
108
113
  hasMore: boolean;
109
114
 
110
115
  /**
111
- * Optional context data to pass to the next execution.
116
+ * Optional state data to pass to the next execution.
112
117
  * Required if `hasMore` is `true`, ignored if `hasMore` is `false`.
113
118
  * This can be any type of data (cursor, page number, timestamp, etc.).
114
- * The same data will be provided in the context parameter of the next execution.
119
+ * The same data will be provided as `state` in the next execution.
115
120
  */
116
- nextContext?: Context;
121
+ nextState?: State;
117
122
  };
118
123
 
119
124
  /**
@@ -123,7 +128,7 @@ export type SyncExecutionResult<PK extends string, Context = unknown> = {
123
128
  export type SyncConfiguration<
124
129
  PK extends string,
125
130
  S extends Schema<PK>,
126
- Context = unknown,
131
+ State = unknown,
127
132
  > = {
128
133
  /**
129
134
  * The property of the data source that maps to a "primary key" in the
@@ -165,34 +170,32 @@ export type SyncConfiguration<
165
170
  * A function that fetches the data to sync from the third-party service.
166
171
  *
167
172
  * This function can return all data at once, or implement pagination by:
168
- * 1. Returning a batch of changes with `hasMore: true` and a `nextContext`
169
- * 2. The runtime will call execute again with that context data
173
+ * 1. Returning a batch of changes with `hasMore: true` and a `nextState`
174
+ * 2. The runtime will call execute again with that state
170
175
  * 3. Continue until `hasMore: false` is returned
171
176
  *
172
177
  * The runtime will handle diffing against the data source and creating,
173
178
  * updating, and deleting pages as necessary.
174
179
  *
175
- * @param context - Optional context data from previous execution (undefined on first call)
176
- * @returns A result containing changes, hasMore status, and optional nextContext
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
177
183
  */
178
- execute: (context?: Context) => Promise<SyncExecutionResult<PK, Context>>;
179
- };
180
-
181
- export type SyncHandlerResult<PK extends string, Context = unknown> = {
182
- primaryKeyProperty: PK;
183
- changes: SyncChange<PK, PropertySchema<PK>>[];
184
- hasMore: boolean;
185
- nextContext?: Context;
186
- mode?: SyncMode;
184
+ execute: (
185
+ state: State | undefined,
186
+ context: CapabilityContext,
187
+ ) => Promise<SyncExecutionResult<PK, State>>;
187
188
  };
188
189
 
189
190
  export type SyncCapability = ReturnType<typeof createSyncCapability>;
190
191
 
191
192
  /**
192
- * Context object passed from the runtime to sync capability handlers.
193
+ * Runtime context object passed from the runtime to sync capability handlers.
193
194
  */
194
195
  type RuntimeContext<UserContext = unknown> = {
195
- /** The user-defined/-controlled context (cursor, pagination state, etc.) */
196
+ /** The user-defined/-controlled state (cursor, pagination state, etc.) */
197
+ state?: UserContext;
198
+ /** Legacy field for user-defined/-controlled state. */
196
199
  userContext?: UserContext;
197
200
  };
198
201
 
@@ -218,9 +221,10 @@ export function createSyncCapability<
218
221
  schedule: parseSchedule(syncConfiguration.schedule),
219
222
  },
220
223
  async handler(runtimeContext?: RuntimeContext<Context>) {
221
- const userContext = runtimeContext?.userContext;
224
+ const capabilityContext = createCapabilityContext();
225
+ const state = runtimeContext?.state ?? runtimeContext?.userContext;
222
226
  const executionResult = await syncConfiguration
223
- .execute(userContext)
227
+ .execute(state, capabilityContext)
224
228
  .catch((err) => {
225
229
  throw new ExecutionError(err);
226
230
  });
@@ -228,7 +232,7 @@ export function createSyncCapability<
228
232
  const result = {
229
233
  changes: executionResult.changes,
230
234
  hasMore: executionResult.hasMore,
231
- nextUserContext: executionResult.nextContext,
235
+ nextUserContext: executionResult.nextState,
232
236
  };
233
237
 
234
238
  process.stdout.write(`\n<output>${JSON.stringify(result)}</output>\n`);
@@ -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 result = await config.execute(input);
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
- AutomationContext,
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/schema.ts CHANGED
@@ -64,7 +64,15 @@ export type PropertyConfiguration =
64
64
  groups: StatusGroup[];
65
65
  }
66
66
  | { type: "people" }
67
- | { type: "place" };
67
+ | { type: "place" }
68
+ | {
69
+ type: "relation";
70
+ /**
71
+ * The export name of the sync capability that defines the related collection.
72
+ * This must match the export name used when defining the related sync capability.
73
+ */
74
+ relatedSyncKey: string;
75
+ };
68
76
 
69
77
  export type Schema<PK extends string> = {
70
78
  /**
@@ -191,3 +199,27 @@ export function people(): PropertyConfiguration {
191
199
  export function place(): PropertyConfiguration {
192
200
  return { type: "place" };
193
201
  }
202
+
203
+ /**
204
+ * Creates a relation property definition that references another sync capability.
205
+ * The related collection must be defined by a sync capability in the same worker.
206
+ *
207
+ * @param relatedSyncKey - The export name of the sync capability that defines the related collection.
208
+ * @example
209
+ * ```typescript
210
+ * export const projectsSync = sync({...});
211
+ *
212
+ * export const tasksSync = sync({
213
+ * schema: {
214
+ * properties: {
215
+ * "Task Title": Schema.title(),
216
+ * "Project": Schema.relation("projectsSync"),
217
+ * },
218
+ * },
219
+ * ...
220
+ * });
221
+ * ```
222
+ */
223
+ export function relation(relatedSyncKey: string): PropertyConfiguration {
224
+ return { type: "relation", relatedSyncKey };
225
+ }
package/src/types.ts CHANGED
@@ -226,6 +226,20 @@ export interface PlaceValue {
226
226
  googlePlaceId?: string;
227
227
  }
228
228
 
229
+ /**
230
+ * A reference to a related record by its primary key.
231
+ */
232
+ export type RelationReference = {
233
+ type: "primaryKey";
234
+ value: string;
235
+ };
236
+
237
+ /**
238
+ * Relation value representing references to related records.
239
+ * Each reference identifies a record in the target collection.
240
+ */
241
+ export type RelationValue = RelationReference[];
242
+
229
243
  /**
230
244
  * Time units for schedule intervals.
231
245
  * - "m": minutes
package/src/worker.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import type {
2
2
  AutomationCapability,
3
3
  AutomationConfiguration,
4
- AutomationContext,
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
- AutomationContext,
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 (context) => {
158
- * const { pageId, pageData } = context;
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) {