@notionhq/workers 0.0.82

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 (73) hide show
  1. package/README.md +22 -0
  2. package/dist/block.d.ts +321 -0
  3. package/dist/block.d.ts.map +1 -0
  4. package/dist/block.js +0 -0
  5. package/dist/builder.d.ts +117 -0
  6. package/dist/builder.d.ts.map +1 -0
  7. package/dist/builder.js +168 -0
  8. package/dist/capabilities/automation.d.ts +91 -0
  9. package/dist/capabilities/automation.d.ts.map +1 -0
  10. package/dist/capabilities/automation.js +40 -0
  11. package/dist/capabilities/automation.test.d.ts +2 -0
  12. package/dist/capabilities/automation.test.d.ts.map +1 -0
  13. package/dist/capabilities/context.d.ts +7 -0
  14. package/dist/capabilities/context.d.ts.map +1 -0
  15. package/dist/capabilities/context.js +15 -0
  16. package/dist/capabilities/oauth.d.ts +120 -0
  17. package/dist/capabilities/oauth.d.ts.map +1 -0
  18. package/dist/capabilities/oauth.js +55 -0
  19. package/dist/capabilities/oauth.test.d.ts +2 -0
  20. package/dist/capabilities/oauth.test.d.ts.map +1 -0
  21. package/dist/capabilities/sync.d.ts +180 -0
  22. package/dist/capabilities/sync.d.ts.map +1 -0
  23. package/dist/capabilities/sync.js +84 -0
  24. package/dist/capabilities/sync.test.d.ts +2 -0
  25. package/dist/capabilities/sync.test.d.ts.map +1 -0
  26. package/dist/capabilities/tool.d.ts +68 -0
  27. package/dist/capabilities/tool.d.ts.map +1 -0
  28. package/dist/capabilities/tool.js +174 -0
  29. package/dist/capabilities/tool.test.d.ts +2 -0
  30. package/dist/capabilities/tool.test.d.ts.map +1 -0
  31. package/dist/error.d.ts +12 -0
  32. package/dist/error.d.ts.map +1 -0
  33. package/dist/error.js +15 -0
  34. package/dist/icon-names.d.ts +6 -0
  35. package/dist/icon-names.d.ts.map +1 -0
  36. package/dist/icon-names.js +0 -0
  37. package/dist/index.d.ts +10 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +9 -0
  40. package/dist/json-schema.d.ts +117 -0
  41. package/dist/json-schema.d.ts.map +1 -0
  42. package/dist/json-schema.js +0 -0
  43. package/dist/json-schema.test.d.ts +2 -0
  44. package/dist/json-schema.test.d.ts.map +1 -0
  45. package/dist/schema.d.ts +178 -0
  46. package/dist/schema.d.ts.map +1 -0
  47. package/dist/schema.js +66 -0
  48. package/dist/types.d.ts +206 -0
  49. package/dist/types.d.ts.map +1 -0
  50. package/dist/types.js +0 -0
  51. package/dist/worker.d.ts +177 -0
  52. package/dist/worker.d.ts.map +1 -0
  53. package/dist/worker.js +219 -0
  54. package/package.json +68 -0
  55. package/src/block.ts +529 -0
  56. package/src/builder.ts +299 -0
  57. package/src/capabilities/automation.test.ts +152 -0
  58. package/src/capabilities/automation.ts +130 -0
  59. package/src/capabilities/context.ts +23 -0
  60. package/src/capabilities/oauth.test.ts +52 -0
  61. package/src/capabilities/oauth.ts +157 -0
  62. package/src/capabilities/sync.test.ts +104 -0
  63. package/src/capabilities/sync.ts +311 -0
  64. package/src/capabilities/tool.test.ts +351 -0
  65. package/src/capabilities/tool.ts +279 -0
  66. package/src/error.ts +19 -0
  67. package/src/icon-names.ts +890 -0
  68. package/src/index.ts +34 -0
  69. package/src/json-schema.test.ts +719 -0
  70. package/src/json-schema.ts +179 -0
  71. package/src/schema.ts +241 -0
  72. package/src/types.ts +272 -0
  73. package/src/worker.ts +285 -0
@@ -0,0 +1,179 @@
1
+ /**
2
+ * JSON Schema types compatible with both Anthropic and OpenAI structured
3
+ * output APIs.
4
+ *
5
+ * Constraints enforced by this type (intersection of both providers):
6
+ * - Objects must have `additionalProperties: false`
7
+ * - All object properties should be listed in `required`
8
+ * (use `anyOf` with `null` for optional fields)
9
+ * - No recursive schemas
10
+ * - No `allOf`, `not`, `if/then/else`
11
+ * - No string constraints (`minLength`, `maxLength`, `pattern`)
12
+ * - No number constraints (`minimum`, `maximum`, `multipleOf`)
13
+ * - Array `minItems` limited to 0 or 1; no `maxItems`
14
+ * - String `format` limited to: date-time, time, date, duration,
15
+ * email, hostname, ipv4, ipv6, uuid
16
+ * - `$ref` and `$defs` supported (no external refs)
17
+ */
18
+
19
+ /**
20
+ * String formats supported by both Anthropic and OpenAI structured outputs.
21
+ */
22
+ export type JSONSchemaStringFormat =
23
+ | "date-time"
24
+ | "time"
25
+ | "date"
26
+ | "duration"
27
+ | "email"
28
+ | "hostname"
29
+ | "ipv4"
30
+ | "ipv6"
31
+ | "uuid";
32
+
33
+ // ---- Unsupported composition keywords ----
34
+ // Explicitly typed as `never` on concrete schema defs to produce clear
35
+ // errors when someone accidentally adds them.
36
+
37
+ interface ForbiddenCompositionKeywords {
38
+ anyOf?: never;
39
+ allOf?: never;
40
+ not?: never;
41
+ if?: never;
42
+ then?: never;
43
+ else?: never;
44
+ }
45
+
46
+ // ---- Individual schema definitions ----
47
+
48
+ export interface JSONSchemaStringDef<T extends string = string>
49
+ extends ForbiddenCompositionKeywords {
50
+ type: "string";
51
+ description?: string;
52
+ format?: JSONSchemaStringFormat;
53
+ enum?: readonly T[];
54
+ }
55
+
56
+ export interface JSONSchemaNumberDef<T extends number = number>
57
+ extends ForbiddenCompositionKeywords {
58
+ type: "number" | "integer";
59
+ description?: string;
60
+ enum?: readonly T[];
61
+ }
62
+
63
+ export interface JSONSchemaBooleanDef extends ForbiddenCompositionKeywords {
64
+ type: "boolean";
65
+ description?: string;
66
+ }
67
+
68
+ export interface JSONSchemaNullDef extends ForbiddenCompositionKeywords {
69
+ type: "null";
70
+ description?: string;
71
+ }
72
+
73
+ export interface JSONSchemaArrayDef<E = unknown>
74
+ extends ForbiddenCompositionKeywords {
75
+ type: "array";
76
+ description?: string;
77
+ items: JSONSchema<E>;
78
+ minItems?: 0 | 1;
79
+ }
80
+
81
+ export interface JSONSchemaObjectDef<
82
+ T extends Record<string, unknown> = Record<string, unknown>,
83
+ > extends ForbiddenCompositionKeywords {
84
+ type: "object";
85
+ description?: string;
86
+ properties: { [K in keyof T]-?: JSONSchema<T[K]> };
87
+ required: readonly (keyof T & string)[];
88
+ additionalProperties: false;
89
+ $defs?: Record<string, AnyJSONSchema>;
90
+ }
91
+
92
+ export interface JSONSchemaRefDef extends ForbiddenCompositionKeywords {
93
+ $ref: string;
94
+ description?: string;
95
+ }
96
+
97
+ // Note: JSONSchemaAnyOfDef intentionally does NOT extend
98
+ // ForbiddenCompositionKeywords — it IS the composition keyword.
99
+ export interface JSONSchemaAnyOfDef<T = unknown> {
100
+ anyOf: readonly JSONSchema<T>[];
101
+ description?: string;
102
+ }
103
+
104
+ // ---- Unconstrained schema (when T is unknown) ----
105
+
106
+ export type AnyJSONSchema =
107
+ | JSONSchemaStringDef
108
+ | JSONSchemaNumberDef
109
+ | JSONSchemaBooleanDef
110
+ | JSONSchemaNullDef
111
+ | JSONSchemaArrayDef
112
+ | JSONSchemaObjectDef
113
+ | JSONSchemaRefDef
114
+ | JSONSchemaAnyOfDef;
115
+
116
+ // ---- Internal type resolution ----
117
+
118
+ /**
119
+ * Maps a TypeScript type T to its corresponding JSON Schema definition.
120
+ *
121
+ * Uses `[T] extends [X]` (non-distributing) so that union types like
122
+ * `string | number` fall through to `AnyJSONSchema` instead of distributing
123
+ * into `JSONSchemaStringDef | JSONSchemaNumberDef`.
124
+ *
125
+ * The `T & X` intersections (e.g. `T & string`) satisfy the generic
126
+ * constraints on each def without widening T.
127
+ *
128
+ * A `$ref` is always valid in any schema position, so `JSONSchemaRefDef`
129
+ * is unioned in at the end.
130
+ */
131
+ type JSONSchemaFor<T> =
132
+ | JSONSchemaRefDef
133
+ | ([T] extends [string]
134
+ ? JSONSchemaStringDef<T & string>
135
+ : [T] extends [number]
136
+ ? JSONSchemaNumberDef<T & number>
137
+ : [T] extends [boolean]
138
+ ? JSONSchemaBooleanDef
139
+ : [T] extends [readonly (infer E)[]]
140
+ ? JSONSchemaArrayDef<E>
141
+ : [T] extends [Record<string, unknown>]
142
+ ? JSONSchemaObjectDef<T & Record<string, unknown>>
143
+ : AnyJSONSchema);
144
+
145
+ /**
146
+ * Wraps a non-null schema in an `anyOf` with `{ type: "null" }` for
147
+ * nullable types (e.g. `string | null`).
148
+ */
149
+ type JSONSchemaNullable<T> = {
150
+ anyOf: readonly [JSONSchemaFor<T>, JSONSchemaNullDef];
151
+ description?: string;
152
+ };
153
+
154
+ // ---- Main exported type ----
155
+
156
+ /**
157
+ * A JSON Schema definition compatible with both Anthropic and OpenAI
158
+ * structured output APIs.
159
+ *
160
+ * When the generic parameter `T` is provided, the schema structure is
161
+ * constrained at compile time to match `T`:
162
+ *
163
+ * ```ts
164
+ * // Schema is checked against the type:
165
+ * const schema: JSONSchema<{ name: string }> = {
166
+ * type: "object",
167
+ * properties: { name: { type: "string" } },
168
+ * required: ["name"],
169
+ * additionalProperties: false,
170
+ * };
171
+ * ```
172
+ *
173
+ * @template T - The TypeScript type the schema should describe.
174
+ */
175
+ export type JSONSchema<T = unknown> = unknown extends T
176
+ ? AnyJSONSchema
177
+ : null extends T
178
+ ? JSONSchemaNullable<NonNullable<T>>
179
+ : JSONSchemaFor<T>;
package/src/schema.ts ADDED
@@ -0,0 +1,241 @@
1
+ import type {
2
+ DateFormat,
3
+ Icon,
4
+ NumberFormat,
5
+ SelectOption,
6
+ StatusGroup,
7
+ } from "./types.js";
8
+
9
+ /**
10
+ * Supported property types for sync schemas.
11
+ */
12
+ export type PropertyType =
13
+ | "title"
14
+ | "rich_text"
15
+ | "url"
16
+ | "email"
17
+ | "phone_number"
18
+ | "checkbox"
19
+ | "file"
20
+ | "number"
21
+ | "date"
22
+ | "select"
23
+ | "multi_select"
24
+ | "status"
25
+ | "people"
26
+ | "place";
27
+
28
+ /**
29
+ * Definition of a single property in a sync schema.
30
+ */
31
+ export type PropertyDefinition = {
32
+ type: PropertyType;
33
+ };
34
+
35
+ /**
36
+ * A schema defining the structure a single property in a data source.
37
+ */
38
+ export type PropertyConfiguration =
39
+ | { type: "title" }
40
+ | { type: "text" }
41
+ | { type: "url" }
42
+ | { type: "email" }
43
+ | { type: "phone_number" }
44
+ | { type: "checkbox" }
45
+ | { type: "file" }
46
+ | {
47
+ type: "number";
48
+ format?: NumberFormat;
49
+ }
50
+ | {
51
+ type: "date";
52
+ date_format?: DateFormat;
53
+ }
54
+ | {
55
+ type: "select";
56
+ options: SelectOption[];
57
+ }
58
+ | {
59
+ type: "multi_select";
60
+ options: SelectOption[];
61
+ }
62
+ | {
63
+ type: "status";
64
+ groups: StatusGroup[];
65
+ }
66
+ | { type: "people" }
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
+ config: { twoWay: false } | { twoWay: true; relatedPropertyName: string };
76
+ };
77
+
78
+ export type Schema<PK extends string> = {
79
+ /**
80
+ * The default name for the database when it is first created.
81
+ *
82
+ * Updating this after the database has been created will not change the
83
+ * name of the database.
84
+ */
85
+ defaultName: string;
86
+ /**
87
+ * Optional icon to use as the icon for the database page.
88
+ * If not provided, defaults to 📋.
89
+ * Use the `icon()` builder to create an icon value.
90
+ */
91
+ databaseIcon?: Icon;
92
+ properties: PropertySchema<PK>;
93
+ /**
94
+ * Optional configuration for sub-item relations.
95
+ * If provided, the parent and child properties must be part of a two-way self-relation.
96
+ */
97
+ subItems?: {
98
+ parentPropertyName: string;
99
+ childPropertyName: string;
100
+ };
101
+ };
102
+
103
+ /**
104
+ * A schema defining the structure of properties in a data source.
105
+ */
106
+ export type PropertySchema<PK extends string> = {
107
+ [PrimaryKey in PK]: PropertyConfiguration;
108
+ } & {
109
+ [propertyName: string]: PropertyConfiguration;
110
+ };
111
+
112
+ /**
113
+ * Creates a title property definition.
114
+ */
115
+ export function title(): PropertyConfiguration {
116
+ return { type: "title" };
117
+ }
118
+
119
+ /**
120
+ * Creates a rich text property definition.
121
+ */
122
+ export function richText(): PropertyConfiguration {
123
+ return { type: "text" };
124
+ }
125
+
126
+ /**
127
+ * Creates a URL property definition.
128
+ */
129
+ export function url(): PropertyConfiguration {
130
+ return { type: "url" };
131
+ }
132
+
133
+ /**
134
+ * Creates an email property definition.
135
+ */
136
+ export function email(): PropertyConfiguration {
137
+ return { type: "email" };
138
+ }
139
+
140
+ /**
141
+ * Creates a phone number property definition.
142
+ */
143
+ export function phoneNumber(): PropertyConfiguration {
144
+ return { type: "phone_number" };
145
+ }
146
+
147
+ /**
148
+ * Creates a checkbox property definition.
149
+ */
150
+ export function checkbox(): PropertyConfiguration {
151
+ return { type: "checkbox" };
152
+ }
153
+
154
+ /**
155
+ * Creates a file property definition.
156
+ */
157
+ export function file(): PropertyConfiguration {
158
+ return { type: "file" };
159
+ }
160
+
161
+ /**
162
+ * Creates a number property definition with optional formatting.
163
+ */
164
+ export function number(format?: NumberFormat): PropertyConfiguration {
165
+ return format ? { type: "number", format } : { type: "number" };
166
+ }
167
+
168
+ /**
169
+ * Creates a date property definition with optional formatting.
170
+ */
171
+ export function date(date_format?: DateFormat): PropertyConfiguration {
172
+ return date_format ? { type: "date", date_format } : { type: "date" };
173
+ }
174
+
175
+ /**
176
+ * Creates a select property definition with predefined options.
177
+ */
178
+ export function select(options: SelectOption[]): PropertyConfiguration {
179
+ return { type: "select", options };
180
+ }
181
+
182
+ /**
183
+ * Creates a multi-select property definition with predefined options.
184
+ */
185
+ export function multiSelect(options: SelectOption[]): PropertyConfiguration {
186
+ return { type: "multi_select", options };
187
+ }
188
+
189
+ /**
190
+ * Creates a status property definition with groups.
191
+ */
192
+ export function status(config: {
193
+ groups: StatusGroup[];
194
+ }): PropertyConfiguration {
195
+ return { type: "status", groups: config.groups };
196
+ }
197
+
198
+ /**
199
+ * Creates a people property definition.
200
+ */
201
+ export function people(): PropertyConfiguration {
202
+ return { type: "people" };
203
+ }
204
+
205
+ /**
206
+ * Creates a place property definition for storing geographic locations.
207
+ */
208
+ export function place(): PropertyConfiguration {
209
+ return { type: "place" };
210
+ }
211
+
212
+ /**
213
+ * Creates a relation property definition that references another sync capability.
214
+ * The related collection must be defined by a sync capability in the same worker.
215
+ *
216
+ * @param relatedSyncKey - The export name of the sync capability that defines the related collection.
217
+ * @example
218
+ * ```typescript
219
+ * export const projectsSync = sync({...});
220
+ *
221
+ * export const tasksSync = sync({
222
+ * schema: {
223
+ * properties: {
224
+ * "Task Title": Schema.title(),
225
+ * "Project": Schema.relation("projectsSync"),
226
+ * },
227
+ * },
228
+ * ...
229
+ * });
230
+ * ```
231
+ */
232
+ export function relation(
233
+ relatedSyncKey: string,
234
+ config?: { twoWay: false } | { twoWay: true; relatedPropertyName: string },
235
+ ): PropertyConfiguration {
236
+ return {
237
+ type: "relation",
238
+ relatedSyncKey,
239
+ config: config ?? { twoWay: false },
240
+ };
241
+ }
package/src/types.ts ADDED
@@ -0,0 +1,272 @@
1
+ /**
2
+ * A JSON value is a string, number, boolean, null, array, or object.
3
+ */
4
+ export type JSONValue =
5
+ | string
6
+ | number
7
+ | boolean
8
+ | null
9
+ | JSONValue[]
10
+ | { [key: string]: JSONValue };
11
+
12
+ /**
13
+ * A text token is a tuple where the first element is the text content
14
+ * and optional subsequent elements are formatting annotations.
15
+ */
16
+ type TextToken = [string, ...unknown[]];
17
+
18
+ /**
19
+ * A TextValue is an array of text tokens, representing rich text content.
20
+ */
21
+ export type TextValue = Array<TextToken>;
22
+
23
+ /**
24
+ * Select option color types supported by Notion
25
+ */
26
+ export type SelectColor =
27
+ | "default"
28
+ | "gray"
29
+ | "brown"
30
+ | "orange"
31
+ | "yellow"
32
+ | "green"
33
+ | "blue"
34
+ | "purple"
35
+ | "pink"
36
+ | "red";
37
+
38
+ /**
39
+ * A select option with an optional color
40
+ */
41
+ export interface SelectOption {
42
+ name: string;
43
+ color?: SelectColor;
44
+ }
45
+
46
+ /**
47
+ * Status group types in Notion
48
+ */
49
+ export type StatusGroupType = "To-do" | "In progress" | "Complete";
50
+
51
+ /**
52
+ * Status group configuration
53
+ */
54
+ export interface StatusGroup {
55
+ name: StatusGroupType;
56
+ options: SelectOption[];
57
+ }
58
+
59
+ /**
60
+ * Date object representing a single date without time
61
+ */
62
+ export interface NotionDate {
63
+ type: "date";
64
+ start_date: string; // Format: "YYYY-MM-DD"
65
+ }
66
+
67
+ /**
68
+ * Date object representing a date with time
69
+ */
70
+ export interface NotionDateTime {
71
+ type: "datetime";
72
+ start_date: string; // Format: "YYYY-MM-DD"
73
+ start_time: string; // Format: "HH:mm"
74
+ time_zone?: string; // e.g., "America/Los_Angeles"
75
+ }
76
+
77
+ /**
78
+ * Date object representing a date range
79
+ */
80
+ export interface DateRange {
81
+ type: "daterange";
82
+ start_date: string; // Format: "YYYY-MM-DD"
83
+ end_date: string; // Format: "YYYY-MM-DD"
84
+ }
85
+
86
+ /**
87
+ * Date object representing a date-time range
88
+ */
89
+ export interface DateTimeRange {
90
+ type: "datetimerange";
91
+ start_date: string; // Format: "YYYY-MM-DD"
92
+ start_time: string; // Format: "HH:mm"
93
+ end_date: string; // Format: "YYYY-MM-DD"
94
+ end_time: string; // Format: "HH:mm"
95
+ time_zone?: string;
96
+ }
97
+
98
+ /**
99
+ * All possible date value types
100
+ */
101
+ export type DateValue = NotionDate | NotionDateTime | DateRange | DateTimeRange;
102
+
103
+ /**
104
+ * Number format types
105
+ */
106
+ export type NumberFormat =
107
+ | "number"
108
+ | "number_with_commas"
109
+ | "percent"
110
+ | "dollar"
111
+ | "euro"
112
+ | "pound"
113
+ | "yen"
114
+ | "rupee"
115
+ | "won"
116
+ | "yuan";
117
+
118
+ /**
119
+ * Date format types
120
+ */
121
+ export type DateFormat =
122
+ | "relative"
123
+ | "MM/DD/YYYY"
124
+ | "DD/MM/YYYY"
125
+ | "YYYY/MM/DD"
126
+ | "ll"
127
+ | "MMM d";
128
+
129
+ import type { NoticonName } from "./icon-names.js";
130
+
131
+ /**
132
+ * Icon representing an emoji
133
+ */
134
+ export interface EmojiIcon {
135
+ type: "emoji";
136
+ value: string;
137
+ }
138
+
139
+ /**
140
+ * Valid colors for Notion icons
141
+ */
142
+ export type NoticonColor =
143
+ | "gray"
144
+ | "lightgray"
145
+ | "brown"
146
+ | "yellow"
147
+ | "orange"
148
+ | "green"
149
+ | "blue"
150
+ | "purple"
151
+ | "pink"
152
+ | "red";
153
+
154
+ /**
155
+ * Icon representing a Notion built-in icon
156
+ */
157
+ export interface NoticonIcon {
158
+ type: "notion";
159
+ /**
160
+ * The name of the Notion icon (e.g., "checkmark", "pizza", "rocket")
161
+ */
162
+ icon: NoticonName;
163
+ /**
164
+ * The color variant of the icon
165
+ */
166
+ color: NoticonColor;
167
+ }
168
+
169
+ /**
170
+ * Icon representing an external image URL
171
+ */
172
+ export interface ImageIcon {
173
+ type: "image";
174
+ /**
175
+ * The URL of the image (must be a valid http/https URL)
176
+ */
177
+ url: string;
178
+ }
179
+
180
+ /**
181
+ * All possible icon types
182
+ */
183
+ export type Icon = EmojiIcon | NoticonIcon | ImageIcon;
184
+
185
+ /**
186
+ * Person reference - represents a user in a people property
187
+ */
188
+ export interface PersonReference {
189
+ /**
190
+ * The email address of the user
191
+ */
192
+ email: string;
193
+ }
194
+
195
+ /**
196
+ * A PeopleValue is an array of person references
197
+ */
198
+ export type PeopleValue = PersonReference[];
199
+
200
+ export type { NoticonName } from "./icon-names.js";
201
+
202
+ /**
203
+ * Place value representing a geographic location.
204
+ * Used for place properties in databases.
205
+ */
206
+ export interface PlaceValue {
207
+ /**
208
+ * Latitude coordinate (required)
209
+ */
210
+ lat: number;
211
+ /**
212
+ * Longitude coordinate (required)
213
+ */
214
+ lon: number;
215
+ /**
216
+ * Optional display name for the location
217
+ */
218
+ name?: string;
219
+ /**
220
+ * Optional street address
221
+ */
222
+ address?: string;
223
+ /**
224
+ * Optional Google Place ID for the location
225
+ */
226
+ googlePlaceId?: string;
227
+ }
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
+
243
+ /**
244
+ * Time units for schedule intervals.
245
+ * - "m": minutes
246
+ * - "h": hours
247
+ * - "d": days
248
+ */
249
+ export type TimeUnit = "m" | "h" | "d";
250
+
251
+ /**
252
+ * A string representing an interval, e.g. "30m", "1h", "7d".
253
+ */
254
+ export type IntervalString = `${number}${TimeUnit}`;
255
+
256
+ /**
257
+ * Schedule configuration for sync capabilities.
258
+ * - "continuous": Run as frequently as the system allows
259
+ * - IntervalString: Run at specified intervals, e.g. "30m", "1h", "1d"
260
+ */
261
+ export type Schedule = "continuous" | IntervalString;
262
+
263
+ /**
264
+ * Normalized schedule representation stored in the backend.
265
+ */
266
+ export type SyncSchedule =
267
+ | { type: "continuous" }
268
+ | { type: "interval"; intervalMs: number };
269
+
270
+ export type HandlerOptions = {
271
+ concreteOutput?: true;
272
+ };