@automate.ax/integration-contracts 0.105.0 → 0.109.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 (45) hide show
  1. package/dist/airtable/api.js +6 -4
  2. package/dist/airtable/index.d.ts +997 -19
  3. package/dist/airtable/index.js +30 -2
  4. package/dist/airtable/schemas.d.ts +2034 -44
  5. package/dist/airtable/schemas.js +231 -47
  6. package/dist/brevo/api.d.ts +41 -0
  7. package/dist/brevo/api.js +74 -4
  8. package/dist/close/events.d.ts +13 -13
  9. package/dist/close/schemas.d.ts +9 -9
  10. package/dist/cloudflare/api.d.ts +93 -0
  11. package/dist/cloudflare/api.js +250 -0
  12. package/dist/cloudflare/events.d.ts +1340 -0
  13. package/dist/cloudflare/events.js +178 -0
  14. package/dist/cloudflare/index.d.ts +3 -0
  15. package/dist/cloudflare/index.js +3 -0
  16. package/dist/cloudflare/schemas.d.ts +608 -0
  17. package/dist/cloudflare/schemas.js +340 -0
  18. package/dist/linear/api.d.ts +1 -1
  19. package/dist/linear/api.js +9 -6
  20. package/dist/linear/index.d.ts +3479 -782
  21. package/dist/linear/index.js +249 -13
  22. package/dist/linear/schemas.d.ts +2724 -31
  23. package/dist/linear/schemas.js +515 -2
  24. package/dist/notion/schemas.d.ts +112 -112
  25. package/dist/outlook/schemas.d.ts +2 -2
  26. package/dist/resend/action-schemas.d.ts +9 -9
  27. package/dist/resend/index.d.ts +36 -36
  28. package/dist/resend/schemas.d.ts +40 -40
  29. package/dist/teams/schemas.d.ts +5 -5
  30. package/dist/triggers.d.ts +2 -1
  31. package/dist/whatsapp/index.d.ts +2 -2
  32. package/dist/whatsapp/schemas.d.ts +5 -5
  33. package/package.json +8 -2
  34. package/src/airtable/api.ts +7 -4
  35. package/src/airtable/index.ts +36 -1
  36. package/src/airtable/schemas.ts +294 -63
  37. package/src/brevo/api.ts +103 -8
  38. package/src/cloudflare/api.ts +340 -0
  39. package/src/cloudflare/events.ts +212 -0
  40. package/src/cloudflare/index.ts +3 -0
  41. package/src/cloudflare/schemas.ts +359 -0
  42. package/src/linear/api.ts +10 -6
  43. package/src/linear/index.ts +249 -26
  44. package/src/linear/schemas.ts +688 -2
  45. package/src/triggers.ts +2 -0
@@ -32,7 +32,28 @@ const AIRTABLE_VIEW_CHANGE_SCHEMA = z.looseObject({
32
32
  .optional(),
33
33
  destroyedRecordIds: z.string().array().optional(),
34
34
  });
35
+ const AIRTABLE_FIELD_DEFINITION_SCHEMA = z.object({
36
+ name: z.string(),
37
+ type: z.string(),
38
+ });
39
+ const AIRTABLE_FIELD_CHANGE_SCHEMA = z.looseObject({
40
+ current: AIRTABLE_FIELD_DEFINITION_SCHEMA.partial(),
41
+ previous: AIRTABLE_FIELD_DEFINITION_SCHEMA.partial().optional(),
42
+ });
43
+ const AIRTABLE_TABLE_METADATA_SCHEMA = z.object({
44
+ description: z.string().nullable(),
45
+ name: z.string(),
46
+ });
35
47
  const AIRTABLE_TABLE_CHANGE_SCHEMA = z.looseObject({
48
+ changedFieldsById: z
49
+ .record(z.string(), AIRTABLE_FIELD_CHANGE_SCHEMA)
50
+ .optional(),
51
+ changedMetadata: z
52
+ .looseObject({
53
+ current: AIRTABLE_TABLE_METADATA_SCHEMA.partial(),
54
+ previous: AIRTABLE_TABLE_METADATA_SCHEMA.partial(),
55
+ })
56
+ .optional(),
36
57
  changedRecordsById: z
37
58
  .record(z.string(), AIRTABLE_CHANGED_RECORD_SCHEMA)
38
59
  .optional(),
@@ -42,8 +63,17 @@ const AIRTABLE_TABLE_CHANGE_SCHEMA = z.looseObject({
42
63
  createdRecordsById: z
43
64
  .record(z.string(), AIRTABLE_CREATED_RECORD_SCHEMA)
44
65
  .optional(),
66
+ createdFieldsById: z
67
+ .record(z.string(), AIRTABLE_FIELD_DEFINITION_SCHEMA)
68
+ .optional(),
69
+ destroyedFieldIds: z.string().array().optional(),
45
70
  destroyedRecordIds: z.string().array().optional(),
46
71
  });
72
+ const AIRTABLE_CREATED_TABLE_SCHEMA = z.looseObject({
73
+ fieldsById: z.record(z.string(), AIRTABLE_FIELD_DEFINITION_SCHEMA).optional(),
74
+ metadata: AIRTABLE_TABLE_METADATA_SCHEMA.optional(),
75
+ recordsById: z.record(z.string(), AIRTABLE_CREATED_RECORD_SCHEMA).optional(),
76
+ });
47
77
  /** One provider-native Airtable webhook transaction payload. */
48
78
  export const AIRTABLE_WEBHOOK_PAYLOAD_SCHEMA = z
49
79
  .looseObject({
@@ -52,12 +82,62 @@ export const AIRTABLE_WEBHOOK_PAYLOAD_SCHEMA = z
52
82
  changedTablesById: z
53
83
  .record(z.string(), AIRTABLE_TABLE_CHANGE_SCHEMA)
54
84
  .optional(),
85
+ createdTablesById: z
86
+ .record(z.string(), AIRTABLE_CREATED_TABLE_SCHEMA)
87
+ .optional(),
55
88
  code: z.string().optional(),
56
89
  error: z.literal(true).optional(),
90
+ destroyedTableIds: z.string().array().optional(),
57
91
  payloadFormat: z.string(),
58
92
  timestamp: z.iso.datetime({ offset: true }),
59
93
  })
60
94
  .catchall(z.json());
95
+ export const AIRTABLE_BASE_EVENT_SCHEMA = z.object({
96
+ /** Airtable base that emitted the transaction. */
97
+ baseId: z.string(),
98
+ /** Complete provider webhook transaction. */
99
+ event: AIRTABLE_WEBHOOK_PAYLOAD_SCHEMA,
100
+ /** Time at which Airtable committed the transaction. */
101
+ occurredAt: z.iso.datetime({ offset: true }),
102
+ /** Airtable system that caused the transaction. */
103
+ source: z.string(),
104
+ /** Provider-specific actor or source details. */
105
+ sourceMetadata: z.record(z.string(), z.json()).optional(),
106
+ /** Base-scoped transaction number assigned by Airtable. */
107
+ transactionNumber: z.number().int().nonnegative(),
108
+ });
109
+ const AIRTABLE_TABLE_EVENT_SCHEMA = AIRTABLE_BASE_EVENT_SCHEMA.extend({
110
+ /** Stable Airtable table ID. */
111
+ tableId: z.string(),
112
+ });
113
+ export const AIRTABLE_TABLE_CREATED_EVENT_SCHEMA = AIRTABLE_TABLE_EVENT_SCHEMA.extend({
114
+ /** Field definitions keyed by stable field ID. */
115
+ fields: z.record(z.string(), AIRTABLE_FIELD_DEFINITION_SCHEMA),
116
+ /** Created table metadata when included by Airtable. */
117
+ metadata: AIRTABLE_TABLE_METADATA_SCHEMA.optional(),
118
+ });
119
+ export const AIRTABLE_TABLE_UPDATED_EVENT_SCHEMA = AIRTABLE_TABLE_EVENT_SCHEMA.extend({
120
+ /** Current table metadata fields changed by the transaction. */
121
+ current: AIRTABLE_TABLE_METADATA_SCHEMA.partial(),
122
+ /** Previous table metadata fields changed by the transaction. */
123
+ previous: AIRTABLE_TABLE_METADATA_SCHEMA.partial(),
124
+ });
125
+ export const AIRTABLE_TABLE_DELETED_EVENT_SCHEMA = AIRTABLE_TABLE_EVENT_SCHEMA;
126
+ const AIRTABLE_FIELD_EVENT_SCHEMA = AIRTABLE_TABLE_EVENT_SCHEMA.extend({
127
+ /** Stable Airtable field ID. */
128
+ fieldId: z.string(),
129
+ });
130
+ export const AIRTABLE_FIELD_CREATED_EVENT_SCHEMA = AIRTABLE_FIELD_EVENT_SCHEMA.extend({
131
+ /** Created field definition. */
132
+ field: AIRTABLE_FIELD_DEFINITION_SCHEMA,
133
+ });
134
+ export const AIRTABLE_FIELD_UPDATED_EVENT_SCHEMA = AIRTABLE_FIELD_EVENT_SCHEMA.extend({
135
+ /** Current field definition values changed by the transaction. */
136
+ current: AIRTABLE_FIELD_DEFINITION_SCHEMA.partial(),
137
+ /** Previous field definition values changed by the transaction. */
138
+ previous: AIRTABLE_FIELD_DEFINITION_SCHEMA.partial().optional(),
139
+ });
140
+ export const AIRTABLE_FIELD_DELETED_EVENT_SCHEMA = AIRTABLE_FIELD_EVENT_SCHEMA;
61
141
  const AIRTABLE_RECORD_EVENT_SCHEMA = z.object({
62
142
  /** Airtable base containing the affected record. */
63
143
  baseId: z.string(),
@@ -99,7 +179,14 @@ export const AIRTABLE_RECORD_MOVED_OUT_OF_VIEW_EVENT_SCHEMA = AIRTABLE_RECORD_EV
99
179
  /** Stable ID of the view the record exited. */
100
180
  viewId: z.string(),
101
181
  });
102
- export const AIRTABLE_RECORD_EVENT_TYPES = [
182
+ export const AIRTABLE_EVENT_TYPES = [
183
+ "airtable.base.event",
184
+ "airtable.table.created",
185
+ "airtable.table.updated",
186
+ "airtable.table.deleted",
187
+ "airtable.field.created",
188
+ "airtable.field.updated",
189
+ "airtable.field.deleted",
103
190
  "airtable.record.created",
104
191
  "airtable.record.updated",
105
192
  "airtable.record.deleted",
@@ -107,78 +194,175 @@ export const AIRTABLE_RECORD_EVENT_TYPES = [
107
194
  "airtable.record.movedOutOfView",
108
195
  ];
109
196
  /**
110
- * Expands one Airtable webhook transaction into semantic record events.
197
+ * Expands one Airtable webhook transaction into broad and semantic events.
111
198
  *
112
199
  * @param value - Untrusted provider payload returned by Airtable.
113
200
  * @param baseId - Stable ID of the base that owns the webhook.
114
201
  */
115
- export function normalizeAirtableRecordEvents(value, baseId) {
202
+ export function normalizeAirtableEvents(value, baseId) {
116
203
  const event = AIRTABLE_WEBHOOK_PAYLOAD_SCHEMA.parse(value);
117
- return Object.entries(event.changedTablesById ?? {}).flatMap(([tableId, table]) => [
118
- ...Object.entries(table.createdRecordsById ?? {}).map(([recordId, record]) => ({
119
- eventType: "airtable.record.created",
120
- payload: AIRTABLE_RECORD_CREATED_EVENT_SCHEMA.parse({
121
- ...recordEventBase(event, baseId, tableId, recordId),
122
- createdAt: record.createdTime,
123
- fields: record.cellValuesByFieldId,
124
- }),
125
- })),
126
- ...Object.entries(table.changedRecordsById ?? {}).map(([recordId, record]) => ({
127
- eventType: "airtable.record.updated",
128
- payload: AIRTABLE_RECORD_UPDATED_EVENT_SCHEMA.parse({
129
- ...recordEventBase(event, baseId, tableId, recordId),
130
- changedFieldIds: Object.keys(record.current.cellValuesByFieldId),
131
- fields: {
132
- ...record.unchanged?.cellValuesByFieldId,
133
- ...record.current.cellValuesByFieldId,
134
- },
135
- previousFields: {
136
- ...record.unchanged?.cellValuesByFieldId,
137
- ...record.previous?.cellValuesByFieldId,
138
- },
139
- }),
140
- })),
141
- ...(table.destroyedRecordIds ?? []).map((recordId) => ({
142
- eventType: "airtable.record.deleted",
143
- payload: AIRTABLE_RECORD_DELETED_EVENT_SCHEMA.parse(recordEventBase(event, baseId, tableId, recordId)),
204
+ return [
205
+ {
206
+ eventType: "airtable.base.event",
207
+ payload: AIRTABLE_BASE_EVENT_SCHEMA.parse(baseEventBase(event, baseId)),
208
+ },
209
+ ...Object.entries(event.createdTablesById ?? {}).flatMap(([tableId, table]) => [
210
+ {
211
+ eventType: "airtable.table.created",
212
+ payload: AIRTABLE_TABLE_CREATED_EVENT_SCHEMA.parse({
213
+ ...tableEventBase(event, baseId, tableId),
214
+ fields: table.fieldsById ?? {},
215
+ metadata: table.metadata,
216
+ }),
217
+ },
218
+ ...Object.entries(table.fieldsById ?? {}).map(([fieldId, field]) => ({
219
+ eventType: "airtable.field.created",
220
+ payload: AIRTABLE_FIELD_CREATED_EVENT_SCHEMA.parse({
221
+ ...fieldEventBase(event, baseId, tableId, fieldId),
222
+ field,
223
+ }),
224
+ })),
225
+ ...Object.entries(table.recordsById ?? {}).map(([recordId, record]) => ({
226
+ eventType: "airtable.record.created",
227
+ payload: AIRTABLE_RECORD_CREATED_EVENT_SCHEMA.parse({
228
+ ...recordEventBase(event, baseId, tableId, recordId),
229
+ createdAt: record.createdTime,
230
+ fields: record.cellValuesByFieldId,
231
+ }),
232
+ })),
233
+ ]),
234
+ ...(event.destroyedTableIds ?? []).map((tableId) => ({
235
+ eventType: "airtable.table.deleted",
236
+ payload: AIRTABLE_TABLE_DELETED_EVENT_SCHEMA.parse(tableEventBase(event, baseId, tableId)),
144
237
  })),
145
- ...Object.entries(table.changedViewsById ?? {}).flatMap(([viewId, view]) => [
146
- ...Object.entries(view.createdRecordsById ?? {}).map(([recordId, record]) => ({
147
- eventType: "airtable.record.movedIntoView",
148
- payload: AIRTABLE_RECORD_MOVED_INTO_VIEW_EVENT_SCHEMA.parse({
238
+ ...Object.entries(event.changedTablesById ?? {}).flatMap(([tableId, table]) => [
239
+ ...(table.changedMetadata
240
+ ? [
241
+ {
242
+ eventType: "airtable.table.updated",
243
+ payload: AIRTABLE_TABLE_UPDATED_EVENT_SCHEMA.parse({
244
+ ...tableEventBase(event, baseId, tableId),
245
+ current: table.changedMetadata.current,
246
+ previous: table.changedMetadata.previous,
247
+ }),
248
+ },
249
+ ]
250
+ : []),
251
+ ...Object.entries(table.createdFieldsById ?? {}).map(([fieldId, field]) => ({
252
+ eventType: "airtable.field.created",
253
+ payload: AIRTABLE_FIELD_CREATED_EVENT_SCHEMA.parse({
254
+ ...fieldEventBase(event, baseId, tableId, fieldId),
255
+ field,
256
+ }),
257
+ })),
258
+ ...Object.entries(table.changedFieldsById ?? {}).map(([fieldId, field]) => ({
259
+ eventType: "airtable.field.updated",
260
+ payload: AIRTABLE_FIELD_UPDATED_EVENT_SCHEMA.parse({
261
+ ...fieldEventBase(event, baseId, tableId, fieldId),
262
+ current: field.current,
263
+ previous: field.previous,
264
+ }),
265
+ })),
266
+ ...(table.destroyedFieldIds ?? []).map((fieldId) => ({
267
+ eventType: "airtable.field.deleted",
268
+ payload: AIRTABLE_FIELD_DELETED_EVENT_SCHEMA.parse(fieldEventBase(event, baseId, tableId, fieldId)),
269
+ })),
270
+ ...Object.entries(table.createdRecordsById ?? {}).map(([recordId, record]) => ({
271
+ eventType: "airtable.record.created",
272
+ payload: AIRTABLE_RECORD_CREATED_EVENT_SCHEMA.parse({
149
273
  ...recordEventBase(event, baseId, tableId, recordId),
150
274
  createdAt: record.createdTime,
151
275
  fields: record.cellValuesByFieldId,
152
- viewId,
153
276
  }),
154
277
  })),
155
- ...(view.destroyedRecordIds ?? []).map((recordId) => ({
156
- eventType: "airtable.record.movedOutOfView",
157
- payload: AIRTABLE_RECORD_MOVED_OUT_OF_VIEW_EVENT_SCHEMA.parse({
278
+ ...Object.entries(table.changedRecordsById ?? {}).map(([recordId, record]) => ({
279
+ eventType: "airtable.record.updated",
280
+ payload: AIRTABLE_RECORD_UPDATED_EVENT_SCHEMA.parse({
158
281
  ...recordEventBase(event, baseId, tableId, recordId),
159
- viewId,
282
+ changedFieldIds: Object.keys(record.current.cellValuesByFieldId),
283
+ fields: {
284
+ ...record.unchanged?.cellValuesByFieldId,
285
+ ...record.current.cellValuesByFieldId,
286
+ },
287
+ previousFields: {
288
+ ...record.unchanged?.cellValuesByFieldId,
289
+ ...record.previous?.cellValuesByFieldId,
290
+ },
160
291
  }),
161
292
  })),
293
+ ...(table.destroyedRecordIds ?? []).map((recordId) => ({
294
+ eventType: "airtable.record.deleted",
295
+ payload: AIRTABLE_RECORD_DELETED_EVENT_SCHEMA.parse(recordEventBase(event, baseId, tableId, recordId)),
296
+ })),
297
+ ...Object.entries(table.changedViewsById ?? {}).flatMap(([viewId, view]) => [
298
+ ...Object.entries(view.createdRecordsById ?? {}).map(([recordId, record]) => ({
299
+ eventType: "airtable.record.movedIntoView",
300
+ payload: AIRTABLE_RECORD_MOVED_INTO_VIEW_EVENT_SCHEMA.parse({
301
+ ...recordEventBase(event, baseId, tableId, recordId),
302
+ createdAt: record.createdTime,
303
+ fields: record.cellValuesByFieldId,
304
+ viewId,
305
+ }),
306
+ })),
307
+ ...(view.destroyedRecordIds ?? []).map((recordId) => ({
308
+ eventType: "airtable.record.movedOutOfView",
309
+ payload: AIRTABLE_RECORD_MOVED_OUT_OF_VIEW_EVENT_SCHEMA.parse({
310
+ ...recordEventBase(event, baseId, tableId, recordId),
311
+ viewId,
312
+ }),
313
+ })),
314
+ ]),
162
315
  ]),
163
- ]);
316
+ ];
164
317
  }
165
318
  /**
166
- * Builds fields shared by every normalized Airtable record event.
319
+ * Builds fields shared by every event in one Airtable transaction.
167
320
  *
168
321
  * @param event - Parsed provider transaction.
169
- * @param baseId - Base containing the changed record.
170
- * @param tableId - Table containing the changed record.
171
- * @param recordId - Stable ID of the changed record.
322
+ * @param baseId - Stable Airtable base ID.
172
323
  */
173
- function recordEventBase(event, baseId, tableId, recordId) {
324
+ function baseEventBase(event, baseId) {
174
325
  return {
175
326
  baseId,
176
327
  event,
177
328
  occurredAt: event.timestamp,
178
- recordId,
179
329
  source: event.actionMetadata.source,
180
330
  sourceMetadata: event.actionMetadata.sourceMetadata,
181
- tableId,
182
331
  transactionNumber: event.baseTransactionNumber,
183
332
  };
184
333
  }
334
+ /**
335
+ * Adds a stable table ID to the shared Airtable event fields.
336
+ *
337
+ * @param event - Parsed provider transaction.
338
+ * @param baseId - Stable Airtable base ID.
339
+ * @param tableId - Stable Airtable table ID.
340
+ */
341
+ function tableEventBase(event, baseId, tableId) {
342
+ return { ...baseEventBase(event, baseId), tableId };
343
+ }
344
+ /**
345
+ * Adds stable table and field IDs to the shared Airtable event fields.
346
+ *
347
+ * @param event - Parsed provider transaction.
348
+ * @param baseId - Stable Airtable base ID.
349
+ * @param tableId - Stable Airtable table ID.
350
+ * @param fieldId - Stable Airtable field ID.
351
+ */
352
+ function fieldEventBase(event, baseId, tableId, fieldId) {
353
+ return { ...tableEventBase(event, baseId, tableId), fieldId };
354
+ }
355
+ /**
356
+ * Builds fields shared by every normalized Airtable record event.
357
+ *
358
+ * @param event - Parsed provider transaction.
359
+ * @param baseId - Base containing the changed record.
360
+ * @param tableId - Table containing the changed record.
361
+ * @param recordId - Stable ID of the changed record.
362
+ */
363
+ function recordEventBase(event, baseId, tableId, recordId) {
364
+ return {
365
+ ...tableEventBase(event, baseId, tableId),
366
+ recordId,
367
+ };
368
+ }
@@ -1,4 +1,45 @@
1
1
  import * as z from "zod";
2
+ /** Provider rate-limit values returned with a Brevo response. */
3
+ export interface BrevoRateLimitMetadata {
4
+ /** Maximum requests allowed in the current window. */
5
+ limit?: number;
6
+ /** Requests remaining in the current window. */
7
+ remaining?: number;
8
+ /** Seconds until the current window resets. */
9
+ reset?: number;
10
+ }
11
+ /** Structured failure returned by the Brevo API. */
12
+ export declare class BrevoApiError extends Error {
13
+ /** Provider error classification. */
14
+ readonly code?: string;
15
+ /** API path that failed. */
16
+ readonly path: string;
17
+ /** Provider rate-limit metadata. */
18
+ readonly rateLimit: BrevoRateLimitMetadata;
19
+ /** Delay in seconds before the request should be retried. */
20
+ readonly retryAfter?: number;
21
+ /** HTTP status returned by Brevo. */
22
+ readonly status: number;
23
+ /**
24
+ * Creates a structured Brevo provider error.
25
+ *
26
+ * @param options - Provider and transport failure details.
27
+ * @param options.code - Provider error classification.
28
+ * @param options.message - Human-readable provider failure.
29
+ * @param options.path - API path that failed.
30
+ * @param options.rateLimit - Provider rate-limit metadata.
31
+ * @param options.retryAfter - Provider retry delay in seconds.
32
+ * @param options.status - HTTP status.
33
+ */
34
+ constructor(options: {
35
+ code?: string;
36
+ message: string;
37
+ path: string;
38
+ rateLimit: BrevoRateLimitMetadata;
39
+ retryAfter?: number;
40
+ status: number;
41
+ });
42
+ }
2
43
  /** Options accepted by the authenticated Brevo request helper. */
3
44
  export interface BrevoRequestOptions extends RequestInit {
4
45
  /** Query parameters appended to the request URL. */
package/dist/brevo/api.js CHANGED
@@ -8,6 +8,39 @@ const BREVO_ERROR_SCHEMA = z.looseObject({
8
8
  code: z.string().optional(),
9
9
  message: z.string().optional(),
10
10
  });
11
+ /** Structured failure returned by the Brevo API. */
12
+ export class BrevoApiError extends Error {
13
+ /** Provider error classification. */
14
+ code;
15
+ /** API path that failed. */
16
+ path;
17
+ /** Provider rate-limit metadata. */
18
+ rateLimit;
19
+ /** Delay in seconds before the request should be retried. */
20
+ retryAfter;
21
+ /** HTTP status returned by Brevo. */
22
+ status;
23
+ /**
24
+ * Creates a structured Brevo provider error.
25
+ *
26
+ * @param options - Provider and transport failure details.
27
+ * @param options.code - Provider error classification.
28
+ * @param options.message - Human-readable provider failure.
29
+ * @param options.path - API path that failed.
30
+ * @param options.rateLimit - Provider rate-limit metadata.
31
+ * @param options.retryAfter - Provider retry delay in seconds.
32
+ * @param options.status - HTTP status.
33
+ */
34
+ constructor(options) {
35
+ super(`Brevo ${options.path} failed: ${options.message}`);
36
+ this.name = "BrevoApiError";
37
+ this.code = options.code;
38
+ this.path = options.path;
39
+ this.rateLimit = options.rateLimit;
40
+ this.retryAfter = options.retryAfter;
41
+ this.status = options.status;
42
+ }
43
+ }
11
44
  /**
12
45
  * Creates a small authenticated Brevo REST client.
13
46
  *
@@ -46,10 +79,21 @@ export function getBrevoApi(secret) {
46
79
  const response = await fetch(url, { ...requestInit, headers });
47
80
  if (response.ok)
48
81
  return response;
49
- const error = BREVO_ERROR_SCHEMA.safeParse(await response.json().catch(() => ({})));
50
- throw new Error(error.success && error.data.message
51
- ? `Brevo API error (${response.status}): ${error.data.message}`
52
- : `Brevo API request failed with status ${response.status}.`);
82
+ const responseText = await response.text();
83
+ const error = BREVO_ERROR_SCHEMA.safeParse(parseJson(responseText));
84
+ throw new BrevoApiError({
85
+ code: error.success ? error.data.code : undefined,
86
+ message: (error.success ? error.data.message : undefined) ??
87
+ (responseText.trim() || `HTTP ${response.status}`),
88
+ path: `${url.pathname}${url.search}`,
89
+ rateLimit: {
90
+ limit: parseNumberHeader(response.headers, "x-sib-ratelimit-limit"),
91
+ remaining: parseNumberHeader(response.headers, "x-sib-ratelimit-remaining"),
92
+ reset: parseNumberHeader(response.headers, "x-sib-ratelimit-reset"),
93
+ },
94
+ retryAfter: parseNumberHeader(response.headers, "retry-after"),
95
+ status: response.status,
96
+ });
53
97
  },
54
98
  };
55
99
  }
@@ -62,3 +106,29 @@ export function getBrevoApi(secret) {
62
106
  export async function parseBrevoResponse(response, schema) {
63
107
  return schema.parse(await response.json());
64
108
  }
109
+ /**
110
+ * Parses provider JSON without hiding non-JSON error bodies.
111
+ *
112
+ * @param value - Provider response text.
113
+ */
114
+ function parseJson(value) {
115
+ try {
116
+ return JSON.parse(value);
117
+ }
118
+ catch {
119
+ return undefined;
120
+ }
121
+ }
122
+ /**
123
+ * Parses an optional numeric HTTP header.
124
+ *
125
+ * @param headers - Provider response headers.
126
+ * @param name - Case-insensitive header name.
127
+ */
128
+ function parseNumberHeader(headers, name) {
129
+ const value = headers.get(name);
130
+ if (value === null)
131
+ return undefined;
132
+ const parsed = Number(value);
133
+ return Number.isFinite(parsed) ? parsed : undefined;
134
+ }
@@ -122,12 +122,12 @@ export declare const closeTriggerContracts: {
122
122
  status: z.ZodOptional<z.ZodEnum<{
123
123
  failed: "failed";
124
124
  completed: "completed";
125
+ timeout: "timeout";
125
126
  created: "created";
126
127
  busy: "busy";
127
128
  cancel: "cancel";
128
129
  "in-progress": "in-progress";
129
130
  "no-answer": "no-answer";
130
- timeout: "timeout";
131
131
  }>>;
132
132
  type: z.ZodOptional<z.ZodLiteral<"Call">>;
133
133
  userId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -195,12 +195,12 @@ export declare const closeTriggerContracts: {
195
195
  status: z.ZodOptional<z.ZodEnum<{
196
196
  failed: "failed";
197
197
  completed: "completed";
198
+ timeout: "timeout";
198
199
  created: "created";
199
200
  busy: "busy";
200
201
  cancel: "cancel";
201
202
  "in-progress": "in-progress";
202
203
  "no-answer": "no-answer";
203
- timeout: "timeout";
204
204
  }>>;
205
205
  type: z.ZodOptional<z.ZodLiteral<"Call">>;
206
206
  userId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -485,11 +485,11 @@ export declare const closeTriggerContracts: {
485
485
  sequenceSubscriptionId: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
486
486
  status: z.ZodOptional<z.ZodEnum<{
487
487
  error: "error";
488
+ sent: "sent";
488
489
  inbox: "inbox";
489
490
  draft: "draft";
490
491
  outbox: "outbox";
491
492
  scheduled: "scheduled";
492
- sent: "sent";
493
493
  }>>;
494
494
  subject: z.ZodOptional<z.ZodNullable<z.ZodString>>;
495
495
  templateId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -573,11 +573,11 @@ export declare const closeTriggerContracts: {
573
573
  sequenceSubscriptionId: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
574
574
  status: z.ZodOptional<z.ZodEnum<{
575
575
  error: "error";
576
+ sent: "sent";
576
577
  inbox: "inbox";
577
578
  draft: "draft";
578
579
  outbox: "outbox";
579
580
  scheduled: "scheduled";
580
- sent: "sent";
581
581
  }>>;
582
582
  subject: z.ZodOptional<z.ZodNullable<z.ZodString>>;
583
583
  templateId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -1686,10 +1686,10 @@ export declare const closeTriggerContracts: {
1686
1686
  startDate: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>>;
1687
1687
  status: z.ZodOptional<z.ZodEnum<{
1688
1688
  error: "error";
1689
+ paused: "paused";
1689
1690
  active: "active";
1690
1691
  finished: "finished";
1691
1692
  goal: "goal";
1692
- paused: "paused";
1693
1693
  }>>;
1694
1694
  statusReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1695
1695
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
@@ -1750,10 +1750,10 @@ export declare const closeTriggerContracts: {
1750
1750
  startDate: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>>;
1751
1751
  status: z.ZodOptional<z.ZodEnum<{
1752
1752
  error: "error";
1753
+ paused: "paused";
1753
1754
  active: "active";
1754
1755
  finished: "finished";
1755
1756
  goal: "goal";
1756
- paused: "paused";
1757
1757
  }>>;
1758
1758
  statusReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1759
1759
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
@@ -1794,10 +1794,10 @@ export declare const closeTriggerContracts: {
1794
1794
  startDate: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>>;
1795
1795
  status: z.ZodOptional<z.ZodEnum<{
1796
1796
  error: "error";
1797
+ paused: "paused";
1797
1798
  active: "active";
1798
1799
  finished: "finished";
1799
1800
  goal: "goal";
1800
- paused: "paused";
1801
1801
  }>>;
1802
1802
  statusReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1803
1803
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
@@ -1838,10 +1838,10 @@ export declare const closeTriggerContracts: {
1838
1838
  startDate: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>>;
1839
1839
  status: z.ZodOptional<z.ZodEnum<{
1840
1840
  error: "error";
1841
+ paused: "paused";
1841
1842
  active: "active";
1842
1843
  finished: "finished";
1843
1844
  goal: "goal";
1844
- paused: "paused";
1845
1845
  }>>;
1846
1846
  statusReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1847
1847
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
@@ -1882,10 +1882,10 @@ export declare const closeTriggerContracts: {
1882
1882
  startDate: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>>;
1883
1883
  status: z.ZodOptional<z.ZodEnum<{
1884
1884
  error: "error";
1885
+ paused: "paused";
1885
1886
  active: "active";
1886
1887
  finished: "finished";
1887
1888
  goal: "goal";
1888
- paused: "paused";
1889
1889
  }>>;
1890
1890
  statusReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1891
1891
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
@@ -1926,10 +1926,10 @@ export declare const closeTriggerContracts: {
1926
1926
  startDate: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>>;
1927
1927
  status: z.ZodOptional<z.ZodEnum<{
1928
1928
  error: "error";
1929
+ paused: "paused";
1929
1930
  active: "active";
1930
1931
  finished: "finished";
1931
1932
  goal: "goal";
1932
- paused: "paused";
1933
1933
  }>>;
1934
1934
  statusReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1935
1935
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
@@ -1970,10 +1970,10 @@ export declare const closeTriggerContracts: {
1970
1970
  startDate: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>>;
1971
1971
  status: z.ZodOptional<z.ZodEnum<{
1972
1972
  error: "error";
1973
+ paused: "paused";
1973
1974
  active: "active";
1974
1975
  finished: "finished";
1975
1976
  goal: "goal";
1976
- paused: "paused";
1977
1977
  }>>;
1978
1978
  statusReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1979
1979
  updatedAt: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
@@ -2160,11 +2160,11 @@ export declare const closeTriggerContracts: {
2160
2160
  }>>;
2161
2161
  status: z.ZodOptional<z.ZodEnum<{
2162
2162
  error: "error";
2163
+ sent: "sent";
2163
2164
  inbox: "inbox";
2164
2165
  draft: "draft";
2165
2166
  outbox: "outbox";
2166
2167
  scheduled: "scheduled";
2167
- sent: "sent";
2168
2168
  }>>;
2169
2169
  templateId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2170
2170
  text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -2231,11 +2231,11 @@ export declare const closeTriggerContracts: {
2231
2231
  }>>;
2232
2232
  status: z.ZodOptional<z.ZodEnum<{
2233
2233
  error: "error";
2234
+ sent: "sent";
2234
2235
  inbox: "inbox";
2235
2236
  draft: "draft";
2236
2237
  outbox: "outbox";
2237
2238
  scheduled: "scheduled";
2238
- sent: "sent";
2239
2239
  }>>;
2240
2240
  templateId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2241
2241
  text: z.ZodOptional<z.ZodNullable<z.ZodString>>;