@notionhq/workers 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/dist/alpha/builder.d.ts +149 -0
  2. package/dist/alpha/builder.d.ts.map +1 -0
  3. package/dist/alpha/builder.js +260 -0
  4. package/dist/alpha/builder.test.d.ts +2 -0
  5. package/dist/alpha/builder.test.d.ts.map +1 -0
  6. package/dist/alpha/cli/build.d.ts +13 -0
  7. package/dist/alpha/cli/build.d.ts.map +1 -0
  8. package/dist/alpha/cli/build.js +36 -0
  9. package/dist/alpha/cli/build.test.d.ts +2 -0
  10. package/dist/alpha/cli/build.test.d.ts.map +1 -0
  11. package/dist/alpha/cli/codegen.d.ts +10 -0
  12. package/dist/alpha/cli/codegen.d.ts.map +1 -0
  13. package/dist/alpha/cli/codegen.js +41 -0
  14. package/dist/alpha/cli/codegen.test.d.ts +2 -0
  15. package/dist/alpha/cli/codegen.test.d.ts.map +1 -0
  16. package/dist/alpha/cli/discover.d.ts +35 -0
  17. package/dist/alpha/cli/discover.d.ts.map +1 -0
  18. package/dist/alpha/cli/discover.js +39 -0
  19. package/dist/alpha/cli/discover.test.d.ts +2 -0
  20. package/dist/alpha/cli/discover.test.d.ts.map +1 -0
  21. package/dist/alpha/cli/emit-manifest.d.ts +33 -0
  22. package/dist/alpha/cli/emit-manifest.d.ts.map +1 -0
  23. package/dist/alpha/cli/emit-manifest.js +266 -0
  24. package/dist/alpha/cli/emit-manifest.test.d.ts +2 -0
  25. package/dist/alpha/cli/emit-manifest.test.d.ts.map +1 -0
  26. package/dist/alpha/cli/index.d.ts +3 -0
  27. package/dist/alpha/cli/index.d.ts.map +1 -0
  28. package/dist/alpha/cli/index.js +36 -0
  29. package/dist/alpha/context.d.ts +8 -0
  30. package/dist/alpha/context.d.ts.map +1 -0
  31. package/dist/alpha/context.js +33 -0
  32. package/dist/alpha/database.d.ts +90 -0
  33. package/dist/alpha/database.d.ts.map +1 -0
  34. package/dist/alpha/database.js +9 -0
  35. package/dist/alpha/error.d.ts +41 -0
  36. package/dist/alpha/error.d.ts.map +1 -0
  37. package/dist/alpha/error.js +25 -0
  38. package/dist/alpha/icon-names.d.ts +6 -0
  39. package/dist/alpha/icon-names.d.ts.map +1 -0
  40. package/dist/alpha/icon-names.js +0 -0
  41. package/dist/alpha/json-schema.d.ts +117 -0
  42. package/dist/alpha/json-schema.d.ts.map +1 -0
  43. package/dist/alpha/json-schema.js +0 -0
  44. package/dist/alpha/manifest.d.ts +44 -0
  45. package/dist/alpha/manifest.d.ts.map +1 -0
  46. package/dist/alpha/manifest.js +0 -0
  47. package/dist/alpha/output.d.ts +7 -0
  48. package/dist/alpha/output.d.ts.map +1 -0
  49. package/dist/alpha/output.js +8 -0
  50. package/dist/alpha/pacer.d.ts +74 -0
  51. package/dist/alpha/pacer.d.ts.map +1 -0
  52. package/dist/alpha/pacer.js +66 -0
  53. package/dist/alpha/pacer.test.d.ts +2 -0
  54. package/dist/alpha/pacer.test.d.ts.map +1 -0
  55. package/dist/alpha/schedule.d.ts +6 -0
  56. package/dist/alpha/schedule.d.ts.map +1 -0
  57. package/dist/alpha/schedule.js +43 -0
  58. package/dist/alpha/schedule.test.d.ts +2 -0
  59. package/dist/alpha/schedule.test.d.ts.map +1 -0
  60. package/dist/alpha/schema-builder.d.ts +79 -0
  61. package/dist/alpha/schema-builder.d.ts.map +1 -0
  62. package/dist/alpha/schema-builder.js +135 -0
  63. package/dist/alpha/schema.d.ts +185 -0
  64. package/dist/alpha/schema.d.ts.map +1 -0
  65. package/dist/alpha/schema.js +115 -0
  66. package/dist/alpha/sync.d.ts +233 -0
  67. package/dist/alpha/sync.d.ts.map +1 -0
  68. package/dist/alpha/sync.js +70 -0
  69. package/dist/alpha/sync.test.d.ts +2 -0
  70. package/dist/alpha/sync.test.d.ts.map +1 -0
  71. package/dist/alpha/tool.d.ts +132 -0
  72. package/dist/alpha/tool.d.ts.map +1 -0
  73. package/dist/alpha/tool.js +156 -0
  74. package/dist/alpha/tool.test.d.ts +2 -0
  75. package/dist/alpha/tool.test.d.ts.map +1 -0
  76. package/dist/alpha/triggers.d.ts +365 -0
  77. package/dist/alpha/triggers.d.ts.map +1 -0
  78. package/dist/alpha/triggers.generated.d.ts +246 -0
  79. package/dist/alpha/triggers.generated.d.ts.map +1 -0
  80. package/dist/alpha/triggers.generated.js +239 -0
  81. package/dist/alpha/triggers.js +0 -0
  82. package/dist/alpha/types.d.ts +228 -0
  83. package/dist/alpha/types.d.ts.map +1 -0
  84. package/dist/alpha/types.js +0 -0
  85. package/dist/alpha/workflow.d.ts +70 -0
  86. package/dist/alpha/workflow.d.ts.map +1 -0
  87. package/dist/alpha/workflow.js +39 -0
  88. package/dist/alpha/workflow.test.d.ts +2 -0
  89. package/dist/alpha/workflow.test.d.ts.map +1 -0
  90. package/dist/builder.d.ts.map +1 -1
  91. package/dist/builder.js +2 -6
  92. package/dist/capabilities/ai_connector.d.ts.map +1 -1
  93. package/dist/capabilities/automation.d.ts.map +1 -1
  94. package/dist/capabilities/context.d.ts.map +1 -1
  95. package/dist/capabilities/custom-block.d.ts +124 -0
  96. package/dist/capabilities/custom-block.d.ts.map +1 -0
  97. package/dist/capabilities/custom-block.js +22 -0
  98. package/dist/capabilities/oauth.d.ts.map +1 -1
  99. package/dist/capabilities/output.d.ts.map +1 -1
  100. package/dist/capabilities/output.js +2 -4
  101. package/dist/capabilities/stateful-capability.d.ts.map +1 -1
  102. package/dist/capabilities/stateful-capability.js +2 -6
  103. package/dist/capabilities/sync.d.ts.map +1 -1
  104. package/dist/capabilities/sync.js +2 -8
  105. package/dist/capabilities/tool.d.ts.map +1 -1
  106. package/dist/capabilities/tool.js +6 -20
  107. package/dist/capabilities/webhook.d.ts.map +1 -1
  108. package/dist/capabilities/workflow.d.ts +2 -2
  109. package/dist/capabilities/workflow.d.ts.map +1 -1
  110. package/dist/index.d.ts +3 -2
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/index.js +1 -7
  113. package/dist/json-schema.d.ts.map +1 -1
  114. package/dist/schema-builder.d.ts.map +1 -1
  115. package/dist/schema.d.ts.map +1 -1
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/worker.d.ts +41 -1
  118. package/dist/worker.d.ts.map +1 -1
  119. package/dist/worker.js +51 -4
  120. package/package.json +74 -14
  121. package/src/alpha/ajv-formats.d.ts +7 -0
  122. package/src/alpha/builder.test.ts +197 -0
  123. package/src/alpha/builder.ts +338 -0
  124. package/src/alpha/cli/build.test.ts +240 -0
  125. package/src/alpha/cli/build.ts +57 -0
  126. package/src/alpha/cli/codegen.test.ts +31 -0
  127. package/src/alpha/cli/codegen.ts +51 -0
  128. package/src/alpha/cli/discover.test.ts +43 -0
  129. package/src/alpha/cli/discover.ts +81 -0
  130. package/src/alpha/cli/emit-manifest.test.ts +45 -0
  131. package/src/alpha/cli/emit-manifest.ts +409 -0
  132. package/src/alpha/cli/index.ts +41 -0
  133. package/src/alpha/context.ts +61 -0
  134. package/src/alpha/database.ts +102 -0
  135. package/src/alpha/error.ts +49 -0
  136. package/src/alpha/icon-names.ts +890 -0
  137. package/src/alpha/json-schema.ts +180 -0
  138. package/src/alpha/manifest.ts +47 -0
  139. package/src/alpha/output.ts +8 -0
  140. package/src/alpha/pacer.test.ts +81 -0
  141. package/src/alpha/pacer.ts +181 -0
  142. package/src/alpha/schedule.test.ts +31 -0
  143. package/src/alpha/schedule.ts +53 -0
  144. package/src/alpha/schema-builder.ts +193 -0
  145. package/src/alpha/schema.ts +222 -0
  146. package/src/alpha/sync.test.ts +191 -0
  147. package/src/alpha/sync.ts +340 -0
  148. package/src/alpha/tool.test.ts +116 -0
  149. package/src/alpha/tool.ts +319 -0
  150. package/src/alpha/triggers.generated.ts +489 -0
  151. package/src/alpha/triggers.ts +500 -0
  152. package/src/alpha/types.ts +284 -0
  153. package/src/alpha/workflow.test.ts +84 -0
  154. package/src/alpha/workflow.ts +131 -0
  155. package/src/builder.test.ts +28 -60
  156. package/src/builder.ts +3 -10
  157. package/src/capabilities/ai_connector.test.ts +9 -32
  158. package/src/capabilities/ai_connector.ts +5 -17
  159. package/src/capabilities/automation.test.ts +3 -12
  160. package/src/capabilities/automation.ts +3 -11
  161. package/src/capabilities/context.ts +3 -6
  162. package/src/capabilities/custom-block.ts +181 -0
  163. package/src/capabilities/oauth.test.ts +1 -0
  164. package/src/capabilities/oauth.ts +1 -3
  165. package/src/capabilities/output.ts +1 -3
  166. package/src/capabilities/stateful-capability.test.ts +1 -0
  167. package/src/capabilities/stateful-capability.ts +2 -6
  168. package/src/capabilities/sync.test.ts +15 -45
  169. package/src/capabilities/sync.ts +10 -40
  170. package/src/capabilities/tool.test.ts +106 -146
  171. package/src/capabilities/tool.ts +17 -39
  172. package/src/capabilities/webhook.ts +3 -10
  173. package/src/capabilities/workflow.test.ts +10 -31
  174. package/src/capabilities/workflow.ts +5 -12
  175. package/src/index.ts +9 -12
  176. package/src/json-schema.test.ts +2 -4
  177. package/src/json-schema.ts +7 -6
  178. package/src/pacer.test.ts +1 -3
  179. package/src/pacer_internal.ts +1 -5
  180. package/src/schema-builder.test.ts +10 -35
  181. package/src/schema-builder.ts +5 -16
  182. package/src/schema.ts +2 -10
  183. package/src/types.ts +1 -7
  184. package/src/worker.test.ts +147 -0
  185. package/src/worker.ts +67 -35
  186. package/dist/block.d.ts +0 -321
  187. package/dist/block.d.ts.map +0 -1
  188. package/src/block.ts +0 -529
  189. /package/dist/{block.js → alpha/ajv-formats.d.js} +0 -0
@@ -0,0 +1,149 @@
1
+ import type { NoticonName } from "./icon-names.js";
2
+ import type { Cover, Icon, NoticonColor, PeopleValue, PlaceValue, RelationReference, TextValue } from "./types.js";
3
+ /**
4
+ * Builders for property values in sync changes.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { Builder } from "@notionhq/workers/alpha/builder";
9
+ *
10
+ * const change = {
11
+ * type: "upsert",
12
+ * key: "task-1",
13
+ * properties: {
14
+ * "Task Name": Builder.title("Write docs"),
15
+ * Status: Builder.select("Open"),
16
+ * Due: Builder.date("2026-08-01"),
17
+ * Assignees: Builder.people("alice@example.com"),
18
+ * },
19
+ * };
20
+ * ```
21
+ */
22
+ export declare const Builder: {
23
+ /**
24
+ * Creates a rich text value.
25
+ */
26
+ richText(content: string): TextValue;
27
+ /**
28
+ * Creates a URL value.
29
+ */
30
+ url(url: string): TextValue;
31
+ /**
32
+ * Creates a title value.
33
+ */
34
+ title(content: string): TextValue;
35
+ /**
36
+ * Creates a text value.
37
+ */
38
+ text(content: string): TextValue;
39
+ /**
40
+ * Creates an email value.
41
+ */
42
+ email(email: string): TextValue;
43
+ /**
44
+ * Creates a phone number value.
45
+ */
46
+ phoneNumber(phone: string): TextValue;
47
+ /**
48
+ * Creates a checkbox value.
49
+ */
50
+ checkbox(checked: boolean): TextValue;
51
+ /**
52
+ * Creates a file URL value.
53
+ * @param fileUrl - The URL of the file
54
+ * @param fileName - Optional display name for the file (defaults to URL)
55
+ */
56
+ file(fileUrl: string, fileName?: string): TextValue;
57
+ /**
58
+ * Creates a number value.
59
+ */
60
+ number(value: number): TextValue;
61
+ /**
62
+ * Creates a date value from a date string (YYYY-MM-DD).
63
+ */
64
+ date(dateString: string): TextValue;
65
+ /**
66
+ * Creates a datetime value from an ISO 8601 datetime string.
67
+ * @param isoString - An ISO 8601 datetime string (e.g., "2024-01-15T10:30", "2024-01-15T10:30:00Z")
68
+ * @param timeZone - Optional IANA timezone name (e.g., "America/New_York")
69
+ */
70
+ dateTime(isoString: string, timeZone?: string): TextValue;
71
+ /**
72
+ * Creates a date range value from date strings.
73
+ */
74
+ dateRange(startDate: string, endDate: string): TextValue;
75
+ /**
76
+ * Creates a datetime range value from ISO 8601 datetime strings.
77
+ * @param startDateTime - An ISO 8601 datetime string for the range start
78
+ * @param endDateTime - An ISO 8601 datetime string for the range end
79
+ * @param timeZone - Optional IANA timezone name (e.g., "America/New_York")
80
+ */
81
+ dateTimeRange(startDateTime: string, endDateTime: string, timeZone?: string): TextValue;
82
+ /**
83
+ * Creates a link with custom display text.
84
+ * @param displayText - The text to display
85
+ * @param url - The URL to link to
86
+ */
87
+ link(displayText: string, url: string): TextValue;
88
+ /**
89
+ * Creates a select value from a single option.
90
+ */
91
+ select(value: string): TextValue;
92
+ /**
93
+ * Creates a multi-select value from multiple options.
94
+ * @param values - Array of option names to select
95
+ */
96
+ multiSelect(...values: string[]): TextValue;
97
+ /**
98
+ * Creates a status value from a status option name.
99
+ */
100
+ status(value: string): TextValue;
101
+ /**
102
+ * Creates a people value from email addresses.
103
+ * @param emails - Array of email addresses for people to include
104
+ */
105
+ people(...emails: string[]): PeopleValue;
106
+ /**
107
+ * Creates a place value for a geographic location.
108
+ * @param value - The place value with lat/lon coordinates and optional name/address
109
+ */
110
+ place(value: PlaceValue): PlaceValue;
111
+ /**
112
+ * Creates a relation reference from a primary key of a related record.
113
+ * Use an array of relation references as the property value.
114
+ *
115
+ * @param primaryKey - The primary key of the related record
116
+ * @example
117
+ * ```typescript
118
+ * // Single relation
119
+ * { Project: [Builder.relation("project-123")] }
120
+ *
121
+ * // Multiple relations
122
+ * { Projects: [Builder.relation("project-123"), Builder.relation("project-456")] }
123
+ * ```
124
+ */
125
+ relation(primaryKey: string): RelationReference;
126
+ /**
127
+ * Creates an emoji icon.
128
+ * @param emoji - An emoji string (e.g., "🎯", "✨", "🚀")
129
+ */
130
+ emojiIcon(emoji: string): Icon;
131
+ /**
132
+ * Creates a Notion icon with a specific color.
133
+ * @param icon - The name of the Notion icon (e.g., "checkmark", "pizza", "rocket")
134
+ * @param color - The color variant (defaults to "gray")
135
+ */
136
+ notionIcon(icon: NoticonName, color?: NoticonColor): Icon;
137
+ /**
138
+ * Creates an image icon from an external URL.
139
+ * @param url - The URL of the image (e.g., "https://example.com/icon.png")
140
+ */
141
+ imageIcon(url: string): Icon;
142
+ /**
143
+ * Creates an image cover from an external URL.
144
+ * @param url - The URL of the image (e.g., "https://example.com/cover.png")
145
+ * @param position - Vertical image position, from 0 (top) to 1 (bottom). Defaults to 0.5.
146
+ */
147
+ imageCover(url: string, position?: number): Cover;
148
+ };
149
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/alpha/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EACX,KAAK,EAEL,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,MAAM,YAAY,CAAC;AA6CpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO;IACnB;;OAEG;sBACe,MAAM,GAAG,SAAS;IAIpC;;OAEG;aACM,MAAM,GAAG,SAAS;IAI3B;;OAEG;mBACY,MAAM,GAAG,SAAS;IAIjC;;OAEG;kBACW,MAAM,GAAG,SAAS;IAIhC;;OAEG;iBACU,MAAM,GAAG,SAAS;IAI/B;;OAEG;uBACgB,MAAM,GAAG,SAAS;IAIrC;;OAEG;sBACe,OAAO,GAAG,SAAS;IAIrC;;;;OAIG;kBACW,MAAM,aAAa,MAAM,GAAG,SAAS;IAInD;;OAEG;kBACW,MAAM,GAAG,SAAS;IAOhC;;OAEG;qBACc,MAAM,GAAG,SAAS;IASnC;;;;OAIG;wBACiB,MAAM,aAAa,MAAM,GAAG,SAAS;IAgBzD;;OAEG;yBACkB,MAAM,WAAW,MAAM,GAAG,SAAS;IAWxD;;;;;OAKG;iCAC0B,MAAM,eAAe,MAAM,aAAa,MAAM,GAAG,SAAS;IAmBvF;;;;OAIG;sBACe,MAAM,OAAO,MAAM,GAAG,SAAS;IAIjD;;OAEG;kBACW,MAAM,GAAG,SAAS;IAIhC;;;OAGG;2BACoB,MAAM,EAAE,GAAG,SAAS;IAO3C;;OAEG;kBACW,MAAM,GAAG,SAAS;IAIhC;;;OAGG;sBACe,MAAM,EAAE,GAAG,WAAW;IAIxC;;;OAGG;iBACU,UAAU,GAAG,UAAU;IAOpC;;;;;;;;;;;;;OAaG;yBACkB,MAAM,GAAG,iBAAiB;IAI/C;;;OAGG;qBACc,MAAM,GAAG,IAAI;IAO9B;;;;OAIG;qBACc,WAAW,UAAS,YAAY,GAAY,IAAI;IAQjE;;;OAGG;mBACY,MAAM,GAAG,IAAI;IAO5B;;;;OAIG;oBACa,MAAM,sBAAmB,KAAK;CAW9C,CAAC"}
@@ -0,0 +1,260 @@
1
+ function validateDateString(dateString) {
2
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
3
+ throw new Error(`Invalid date format: ${dateString}. Expected YYYY-MM-DD format.`);
4
+ }
5
+ const date = new Date(dateString);
6
+ if (Number.isNaN(date.getTime())) {
7
+ throw new Error(`Invalid date: ${dateString}`);
8
+ }
9
+ }
10
+ function createDateToken(dateValue) {
11
+ return [["\u2023", [["d", dateValue]]]];
12
+ }
13
+ function parseISODateTime(isoString) {
14
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(isoString)) {
15
+ throw new Error(
16
+ `Invalid ISO 8601 datetime: ${isoString}. Expected format like 2024-01-15T10:30 or 2024-01-15T10:30:00Z`
17
+ );
18
+ }
19
+ const date = isoString.slice(0, 10);
20
+ const time = isoString.slice(11, 16);
21
+ if (Number.isNaN(new Date(isoString).getTime())) {
22
+ throw new Error(`Invalid datetime: ${isoString}`);
23
+ }
24
+ return { date, time };
25
+ }
26
+ const Builder = {
27
+ /**
28
+ * Creates a rich text value.
29
+ */
30
+ richText(content) {
31
+ return [[content]];
32
+ },
33
+ /**
34
+ * Creates a URL value.
35
+ */
36
+ url(url) {
37
+ return [[url]];
38
+ },
39
+ /**
40
+ * Creates a title value.
41
+ */
42
+ title(content) {
43
+ return [[content]];
44
+ },
45
+ /**
46
+ * Creates a text value.
47
+ */
48
+ text(content) {
49
+ return [[content]];
50
+ },
51
+ /**
52
+ * Creates an email value.
53
+ */
54
+ email(email) {
55
+ return [[email]];
56
+ },
57
+ /**
58
+ * Creates a phone number value.
59
+ */
60
+ phoneNumber(phone) {
61
+ return [[phone]];
62
+ },
63
+ /**
64
+ * Creates a checkbox value.
65
+ */
66
+ checkbox(checked) {
67
+ return checked ? [["Yes"]] : [["No"]];
68
+ },
69
+ /**
70
+ * Creates a file URL value.
71
+ * @param fileUrl - The URL of the file
72
+ * @param fileName - Optional display name for the file (defaults to URL)
73
+ */
74
+ file(fileUrl, fileName) {
75
+ return [[fileName ?? fileUrl, [["a", fileUrl]]]];
76
+ },
77
+ /**
78
+ * Creates a number value.
79
+ */
80
+ number(value) {
81
+ if (Number.isNaN(value)) {
82
+ return [];
83
+ }
84
+ return [[value.toString()]];
85
+ },
86
+ /**
87
+ * Creates a date value from a date string (YYYY-MM-DD).
88
+ */
89
+ date(dateString) {
90
+ validateDateString(dateString);
91
+ return createDateToken({
92
+ type: "date",
93
+ start_date: dateString
94
+ });
95
+ },
96
+ /**
97
+ * Creates a datetime value from an ISO 8601 datetime string.
98
+ * @param isoString - An ISO 8601 datetime string (e.g., "2024-01-15T10:30", "2024-01-15T10:30:00Z")
99
+ * @param timeZone - Optional IANA timezone name (e.g., "America/New_York")
100
+ */
101
+ dateTime(isoString, timeZone) {
102
+ const { date, time } = parseISODateTime(isoString);
103
+ const dateValue = {
104
+ type: "datetime",
105
+ start_date: date,
106
+ start_time: time
107
+ };
108
+ if (timeZone) {
109
+ dateValue.time_zone = timeZone;
110
+ }
111
+ return createDateToken(dateValue);
112
+ },
113
+ /**
114
+ * Creates a date range value from date strings.
115
+ */
116
+ dateRange(startDate, endDate) {
117
+ validateDateString(startDate);
118
+ validateDateString(endDate);
119
+ return createDateToken({
120
+ type: "daterange",
121
+ start_date: startDate,
122
+ end_date: endDate
123
+ });
124
+ },
125
+ /**
126
+ * Creates a datetime range value from ISO 8601 datetime strings.
127
+ * @param startDateTime - An ISO 8601 datetime string for the range start
128
+ * @param endDateTime - An ISO 8601 datetime string for the range end
129
+ * @param timeZone - Optional IANA timezone name (e.g., "America/New_York")
130
+ */
131
+ dateTimeRange(startDateTime, endDateTime, timeZone) {
132
+ const start = parseISODateTime(startDateTime);
133
+ const end = parseISODateTime(endDateTime);
134
+ const dateValue = {
135
+ type: "datetimerange",
136
+ start_date: start.date,
137
+ start_time: start.time,
138
+ end_date: end.date,
139
+ end_time: end.time
140
+ };
141
+ if (timeZone) {
142
+ dateValue.time_zone = timeZone;
143
+ }
144
+ return createDateToken(dateValue);
145
+ },
146
+ /**
147
+ * Creates a link with custom display text.
148
+ * @param displayText - The text to display
149
+ * @param url - The URL to link to
150
+ */
151
+ link(displayText, url) {
152
+ return [[displayText, [["a", url]]]];
153
+ },
154
+ /**
155
+ * Creates a select value from a single option.
156
+ */
157
+ select(value) {
158
+ return [[value]];
159
+ },
160
+ /**
161
+ * Creates a multi-select value from multiple options.
162
+ * @param values - Array of option names to select
163
+ */
164
+ multiSelect(...values) {
165
+ if (values.length === 0) {
166
+ return [];
167
+ }
168
+ return [[values.join(",")]];
169
+ },
170
+ /**
171
+ * Creates a status value from a status option name.
172
+ */
173
+ status(value) {
174
+ return [[value]];
175
+ },
176
+ /**
177
+ * Creates a people value from email addresses.
178
+ * @param emails - Array of email addresses for people to include
179
+ */
180
+ people(...emails) {
181
+ return emails.map((email) => ({ email }));
182
+ },
183
+ /**
184
+ * Creates a place value for a geographic location.
185
+ * @param value - The place value with lat/lon coordinates and optional name/address
186
+ */
187
+ place(value) {
188
+ if (typeof value.lat !== "number" || typeof value.lon !== "number") {
189
+ throw new Error("Place value must have numeric lat and lon coordinates");
190
+ }
191
+ return value;
192
+ },
193
+ /**
194
+ * Creates a relation reference from a primary key of a related record.
195
+ * Use an array of relation references as the property value.
196
+ *
197
+ * @param primaryKey - The primary key of the related record
198
+ * @example
199
+ * ```typescript
200
+ * // Single relation
201
+ * { Project: [Builder.relation("project-123")] }
202
+ *
203
+ * // Multiple relations
204
+ * { Projects: [Builder.relation("project-123"), Builder.relation("project-456")] }
205
+ * ```
206
+ */
207
+ relation(primaryKey) {
208
+ return { type: "primaryKey", value: primaryKey };
209
+ },
210
+ /**
211
+ * Creates an emoji icon.
212
+ * @param emoji - An emoji string (e.g., "🎯", "✨", "🚀")
213
+ */
214
+ emojiIcon(emoji) {
215
+ return {
216
+ type: "emoji",
217
+ value: emoji
218
+ };
219
+ },
220
+ /**
221
+ * Creates a Notion icon with a specific color.
222
+ * @param icon - The name of the Notion icon (e.g., "checkmark", "pizza", "rocket")
223
+ * @param color - The color variant (defaults to "gray")
224
+ */
225
+ notionIcon(icon, color = "gray") {
226
+ return {
227
+ type: "notion",
228
+ icon,
229
+ color
230
+ };
231
+ },
232
+ /**
233
+ * Creates an image icon from an external URL.
234
+ * @param url - The URL of the image (e.g., "https://example.com/icon.png")
235
+ */
236
+ imageIcon(url) {
237
+ return {
238
+ type: "image",
239
+ url
240
+ };
241
+ },
242
+ /**
243
+ * Creates an image cover from an external URL.
244
+ * @param url - The URL of the image (e.g., "https://example.com/cover.png")
245
+ * @param position - Vertical image position, from 0 (top) to 1 (bottom). Defaults to 0.5.
246
+ */
247
+ imageCover(url, position = 0.5) {
248
+ if (!Number.isFinite(position) || position < 0 || position > 1) {
249
+ throw new Error(`Invalid cover position: ${position}. Expected a number between 0 and 1.`);
250
+ }
251
+ return {
252
+ type: "image",
253
+ url,
254
+ position
255
+ };
256
+ }
257
+ };
258
+ export {
259
+ Builder
260
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=builder.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.test.d.ts","sourceRoot":"","sources":["../../src/alpha/builder.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import type { WorkerManifest } from "../manifest.js";
2
+ export type BuildResult = {
3
+ manifest: WorkerManifest;
4
+ bundlePath: string;
5
+ manifestPath: string;
6
+ };
7
+ /**
8
+ * Build a worker project: discover capability files by convention, generate
9
+ * the entry module, bundle it into a single `dist/worker.js`, and emit
10
+ * `dist/manifest.json` describing every capability.
11
+ */
12
+ export declare function buildWorker(projectRoot: string): Promise<BuildResult>;
13
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/alpha/cli/build.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKrD,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAmC3E"}
@@ -0,0 +1,36 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { rolldown } from "rolldown";
4
+ import { generateEntry } from "./codegen.js";
5
+ import { discoverCapabilities } from "./discover.js";
6
+ import { extractManifest } from "./emit-manifest.js";
7
+ async function buildWorker(projectRoot) {
8
+ const capabilities = await discoverCapabilities(projectRoot);
9
+ if (capabilities.length === 0) {
10
+ throw new Error(
11
+ `No capabilities found in ${projectRoot}. Add capability files by convention, e.g. src/syncs/<name>.ts default-exporting createSync(...).`
12
+ );
13
+ }
14
+ const entryPath = path.join(projectRoot, ".notion", "entry.ts");
15
+ await fs.promises.mkdir(path.dirname(entryPath), { recursive: true });
16
+ await fs.promises.writeFile(entryPath, generateEntry(capabilities));
17
+ const bundlePath = path.join(projectRoot, "dist", "worker.js");
18
+ const bundle = await rolldown({
19
+ input: entryPath,
20
+ platform: "node",
21
+ external: (id) => !id.startsWith(".") && !path.isAbsolute(id)
22
+ });
23
+ try {
24
+ await bundle.write({ format: "esm", file: bundlePath });
25
+ } finally {
26
+ await bundle.close();
27
+ }
28
+ const manifest = await extractManifest(bundlePath, capabilities);
29
+ const manifestPath = path.join(projectRoot, "dist", "manifest.json");
30
+ await fs.promises.writeFile(manifestPath, `${JSON.stringify(manifest, null, " ")}
31
+ `);
32
+ return { manifest, bundlePath, manifestPath };
33
+ }
34
+ export {
35
+ buildWorker
36
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.test.d.ts","sourceRoot":"","sources":["../../../src/alpha/cli/build.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import type { DiscoveredCapability } from "./discover.js";
2
+ /**
3
+ * Generate the worker entry module for a set of discovered capabilities.
4
+ *
5
+ * The module uses only static imports so that the bundler can bundle the
6
+ * whole worker into a single file. It is written to `.notion/entry.ts` in
7
+ * the worker project, so imports are relative to that location.
8
+ */
9
+ export declare function generateEntry(capabilities: readonly DiscoveredCapability[]): string;
10
+ //# sourceMappingURL=codegen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../../src/alpha/cli/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,CAyCnF"}
@@ -0,0 +1,41 @@
1
+ function generateEntry(capabilities) {
2
+ const imports = [];
3
+ const registryEntries = /* @__PURE__ */ new Map();
4
+ capabilities.forEach((capability, index) => {
5
+ const binding = `capability_${index}`;
6
+ imports.push(`import ${binding} from ${JSON.stringify(`../${capability.sourcePath}`)};`);
7
+ const entries = registryEntries.get(capability.type) ?? [];
8
+ entries.push(` ${JSON.stringify(capability.key)}: ${binding},`);
9
+ registryEntries.set(capability.type, entries);
10
+ });
11
+ const registry = Array.from(registryEntries.entries()).map(([type, entries]) => ` ${JSON.stringify(type)}: {
12
+ ${entries.join("\n")}
13
+ },`).join("\n");
14
+ return `// Generated by \`notion-workers build\`. Do not edit.
15
+ ${imports.join("\n")}
16
+
17
+ type Handler = (context?: unknown, options?: { concreteOutput?: true }) => Promise<unknown>;
18
+
19
+ export const capabilities: Record<string, Record<string, { handler: Handler }>> = {
20
+ ${registry}
21
+ };
22
+
23
+ export async function run(
24
+ type: string,
25
+ key: string,
26
+ context?: unknown,
27
+ options?: { concreteOutput?: true },
28
+ ): Promise<unknown> {
29
+ const capability = capabilities[type]?.[key];
30
+
31
+ if (!capability) {
32
+ throw new Error(\`Capability "\${type}/\${key}" not found\`);
33
+ }
34
+
35
+ return capability.handler(context, options);
36
+ }
37
+ `;
38
+ }
39
+ export {
40
+ generateEntry
41
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codegen.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.test.d.ts","sourceRoot":"","sources":["../../../src/alpha/cli/codegen.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import type { CapabilityType } from "../manifest.js";
2
+ /**
3
+ * A capability type the build tool knows how to discover: which directory
4
+ * under `src/` its files live in, and the `_tag` its default exports must
5
+ * carry. Adding a new capability type to the SDK means adding an entry here
6
+ * (plus its factory function).
7
+ */
8
+ export type CapabilityTypeDefinition = {
9
+ type: CapabilityType;
10
+ directory: string;
11
+ tag: string;
12
+ };
13
+ export declare const CAPABILITY_TYPES: readonly CapabilityTypeDefinition[];
14
+ /**
15
+ * A capability file found during discovery. The key is the file's basename;
16
+ * combined with the type it forms the capability's identity (`sync/static`).
17
+ */
18
+ export type DiscoveredCapability = {
19
+ type: CapabilityType;
20
+ tag: string;
21
+ key: string;
22
+ /** Path to the source file, relative to the project root. */
23
+ sourcePath: string;
24
+ };
25
+ /**
26
+ * Discover capability files by convention: every `.ts` file directly under
27
+ * `src/<directory>/` for each registered capability type. Subdirectories are
28
+ * not searched — they hold plain modules, not capabilities.
29
+ *
30
+ * Only capabilities are discovered by file location. Resources (databases,
31
+ * pacers) live anywhere and are discovered by walking capability configs at
32
+ * manifest time.
33
+ */
34
+ export declare function discoverCapabilities(projectRoot: string, capabilityTypes?: readonly CapabilityTypeDefinition[]): Promise<DiscoveredCapability[]>;
35
+ //# sourceMappingURL=discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../src/alpha/cli/discover.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,SAAS,wBAAwB,EAI/D,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,GAAE,SAAS,wBAAwB,EAAqB,GACrE,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAiCjC"}
@@ -0,0 +1,39 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ const CAPABILITY_TYPES = [
4
+ { type: "sync", directory: "syncs", tag: "sync" },
5
+ { type: "tool", directory: "tools", tag: "tool" },
6
+ { type: "workflow", directory: "workflows", tag: "workflow" }
7
+ ];
8
+ async function discoverCapabilities(projectRoot, capabilityTypes = CAPABILITY_TYPES) {
9
+ const discovered = [];
10
+ for (const definition of capabilityTypes) {
11
+ const directory = path.join(projectRoot, "src", definition.directory);
12
+ let entries;
13
+ try {
14
+ entries = await fs.promises.readdir(directory, { withFileTypes: true });
15
+ } catch (error) {
16
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
17
+ continue;
18
+ }
19
+ throw error;
20
+ }
21
+ entries.sort((a, b) => a.name.localeCompare(b.name));
22
+ for (const entry of entries) {
23
+ if (!entry.isFile() || !entry.name.endsWith(".ts") || entry.name.endsWith(".d.ts")) {
24
+ continue;
25
+ }
26
+ discovered.push({
27
+ type: definition.type,
28
+ tag: definition.tag,
29
+ key: entry.name.slice(0, -".ts".length),
30
+ sourcePath: path.join("src", definition.directory, entry.name)
31
+ });
32
+ }
33
+ }
34
+ return discovered;
35
+ }
36
+ export {
37
+ CAPABILITY_TYPES,
38
+ discoverCapabilities
39
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=discover.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.test.d.ts","sourceRoot":"","sources":["../../../src/alpha/cli/discover.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import type { WorkerManifest } from "../manifest.js";
2
+ import type { DiscoveredCapability } from "./discover.js";
3
+ /**
4
+ * Extract the worker manifest from a built bundle.
5
+ *
6
+ * This is the one place the build executes worker code: the bundle is
7
+ * imported once (running module top-level code only — handlers are never
8
+ * invoked), each discovered capability's default export is validated
9
+ * against the tag its directory requires, and the handler-free configs are
10
+ * assembled into the manifest.
11
+ *
12
+ * Resources are not discovered from the filesystem. Databases are collected
13
+ * by walking capability configs — a sync's `database`, and transitively any
14
+ * database referenced by a schema's `relation` properties. Pacers register
15
+ * themselves when created, so importing the bundle populates the pacer
16
+ * registry as a side effect. Within a build, resources deduplicate by
17
+ * object identity; across deploys their `name` is the stable key. Two
18
+ * distinct resource objects sharing a name fail the build.
19
+ */
20
+ export declare function extractManifest(bundlePath: string, capabilities: readonly DiscoveredCapability[]): Promise<WorkerManifest>;
21
+ /**
22
+ * Throw if `value` contains anything `JSON.stringify` would silently drop or
23
+ * rewrite, so a config that can't round-trip fails the build here rather than
24
+ * producing a manifest that quietly disagrees with the author's source.
25
+ *
26
+ * Rejects functions, symbols, bigints, non-finite numbers, `undefined` array
27
+ * elements, and non-plain objects (Map, Set, Date, class instances). Allows
28
+ * null, booleans, finite numbers, strings, plain arrays, and plain objects.
29
+ * `undefined`-valued object properties are permitted and omitted, mirroring
30
+ * JSON semantics for unset optional fields.
31
+ */
32
+ export declare function assertJsonSafe(value: unknown, path: string): void;
33
+ //# sourceMappingURL=emit-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-manifest.d.ts","sourceRoot":"","sources":["../../../src/alpha/cli/emit-manifest.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAA6C,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAuJ1D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACpC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAC3C,OAAO,CAAC,cAAc,CAAC,CAoEzB;AA2GD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA4CjE"}