@automate.ax/integration-contracts 0.93.1 → 0.95.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/close/api.d.ts +3 -1
- package/dist/close/api.js +5 -2
- package/dist/close/events.d.ts +27 -27
- package/dist/close/schemas.d.ts +9 -9
- package/dist/close/schemas.js +1 -1
- package/dist/jobnimbus/api.d.ts +3 -1
- package/dist/jobnimbus/api.js +6 -5
- package/dist/trello/api.d.ts +25 -1
- package/dist/trello/api.js +56 -4
- package/dist/trello/event-schemas.d.ts +5585 -129
- package/dist/trello/event-schemas.js +324 -64
- package/dist/trello/index.d.ts +5277 -51
- package/dist/trello/index.js +106 -2
- package/dist/trello/schemas.d.ts +186 -0
- package/dist/trello/schemas.js +220 -0
- package/package.json +2 -2
- package/src/close/api.ts +5 -1
- package/src/close/schemas.ts +1 -1
- package/src/jobnimbus/api.ts +10 -4
- package/src/trello/api.ts +92 -5
- package/src/trello/event-schemas.ts +391 -91
- package/src/trello/index.ts +131 -1
- package/src/trello/schemas.ts +273 -0
package/src/close/schemas.ts
CHANGED
|
@@ -241,7 +241,7 @@ const CLOSE_TASK_FIELDS = {
|
|
|
241
241
|
dueDate: NULLABLE_DATE_SCHEMA.optional(),
|
|
242
242
|
id: z.string(),
|
|
243
243
|
isComplete: z.boolean(),
|
|
244
|
-
isDateless: z.boolean().optional(),
|
|
244
|
+
isDateless: z.boolean().nullable().optional(),
|
|
245
245
|
leadId: z.string().nullable(),
|
|
246
246
|
leadName: z.string().nullable().optional(),
|
|
247
247
|
objectId: z.string().nullable().optional(),
|
package/src/jobnimbus/api.ts
CHANGED
|
@@ -44,6 +44,7 @@ interface JobNimbusRequestOptions<TSchema extends z.ZodType> {
|
|
|
44
44
|
/** Error returned by a rejected JobNimbus API request. */
|
|
45
45
|
export class JobNimbusApiError extends Error {
|
|
46
46
|
readonly details: Encodable
|
|
47
|
+
readonly retryAfter?: string
|
|
47
48
|
readonly status: number
|
|
48
49
|
|
|
49
50
|
/**
|
|
@@ -51,11 +52,13 @@ export class JobNimbusApiError extends Error {
|
|
|
51
52
|
*
|
|
52
53
|
* @param status - HTTP response status.
|
|
53
54
|
* @param details - Codec-safe response details.
|
|
55
|
+
* @param retryAfter - Raw provider retry timing, when present.
|
|
54
56
|
*/
|
|
55
|
-
constructor(status: number, details: Encodable) {
|
|
57
|
+
constructor(status: number, details: Encodable, retryAfter?: string) {
|
|
56
58
|
super(`JobNimbus API request failed (${status}).`)
|
|
57
59
|
this.name = "JobNimbusApiError"
|
|
58
60
|
this.details = details
|
|
61
|
+
this.retryAfter = retryAfter
|
|
59
62
|
this.status = status
|
|
60
63
|
}
|
|
61
64
|
}
|
|
@@ -139,6 +142,7 @@ export function getJobNimbusApi(secret: unknown, api: JobNimbusApi) {
|
|
|
139
142
|
throw new JobNimbusApiError(
|
|
140
143
|
response.status,
|
|
141
144
|
parsed.success ? parsed.data : { response: text },
|
|
145
|
+
response.headers.get("Retry-After") ?? undefined,
|
|
142
146
|
)
|
|
143
147
|
}
|
|
144
148
|
return options.responseSchema.parse(parsed.data)
|
|
@@ -162,9 +166,11 @@ export async function downloadJobNimbusFile(secret: unknown, fileId: string) {
|
|
|
162
166
|
{ headers: { Authorization: `Bearer ${apiKey}` } },
|
|
163
167
|
)
|
|
164
168
|
if (!response.ok) {
|
|
165
|
-
throw new JobNimbusApiError(
|
|
166
|
-
response
|
|
167
|
-
|
|
169
|
+
throw new JobNimbusApiError(
|
|
170
|
+
response.status,
|
|
171
|
+
{ response: await response.text() },
|
|
172
|
+
response.headers.get("Retry-After") ?? undefined,
|
|
173
|
+
)
|
|
168
174
|
}
|
|
169
175
|
return response.blob()
|
|
170
176
|
}
|
package/src/trello/api.ts
CHANGED
|
@@ -7,6 +7,7 @@ const TRELLO_SECRET_SCHEMA = z.object({
|
|
|
7
7
|
token: z.string().min(1),
|
|
8
8
|
})
|
|
9
9
|
const TRELLO_ERROR_SCHEMA = z.looseObject({
|
|
10
|
+
error: z.string().optional(),
|
|
10
11
|
message: z.string().optional(),
|
|
11
12
|
})
|
|
12
13
|
|
|
@@ -15,7 +16,7 @@ type TrelloQueryValue = boolean | number | string | undefined
|
|
|
15
16
|
|
|
16
17
|
/** Options for one authenticated Trello REST request. */
|
|
17
18
|
export interface TrelloRequestOptions<TSchema extends z.ZodType> {
|
|
18
|
-
/** JSON request body for endpoints that accept one. */
|
|
19
|
+
/** JSON or multipart request body for endpoints that accept one. */
|
|
19
20
|
body?: unknown
|
|
20
21
|
|
|
21
22
|
/** HTTP verb. Defaults to `GET`. */
|
|
@@ -44,9 +45,15 @@ export interface TrelloApi {
|
|
|
44
45
|
|
|
45
46
|
/** Structured Trello REST request error. */
|
|
46
47
|
export class TrelloApiError extends Error {
|
|
48
|
+
/** Provider error code, or an HTTP fallback code. */
|
|
49
|
+
readonly code: string
|
|
50
|
+
|
|
47
51
|
/** Provider error body, when Trello returned text. */
|
|
48
52
|
readonly providerMessage?: string
|
|
49
53
|
|
|
54
|
+
/** Rate-limit budget returned with the failed request. */
|
|
55
|
+
readonly rateLimit?: TrelloRateLimitMetadata
|
|
56
|
+
|
|
50
57
|
/** Retry delay from Trello's `Retry-After` header, in seconds. */
|
|
51
58
|
readonly retryAfter?: number
|
|
52
59
|
|
|
@@ -57,12 +64,16 @@ export class TrelloApiError extends Error {
|
|
|
57
64
|
* Creates a structured Trello API error.
|
|
58
65
|
*
|
|
59
66
|
* @param options - Provider and transport error details.
|
|
67
|
+
* @param options.code - Provider error code or HTTP fallback.
|
|
60
68
|
* @param options.providerMessage - Provider error body.
|
|
69
|
+
* @param options.rateLimit - Provider rate-limit budget.
|
|
61
70
|
* @param options.retryAfter - Retry delay in seconds.
|
|
62
71
|
* @param options.status - HTTP response status.
|
|
63
72
|
*/
|
|
64
73
|
constructor(options: {
|
|
74
|
+
code: string
|
|
65
75
|
providerMessage?: string
|
|
76
|
+
rateLimit?: TrelloRateLimitMetadata
|
|
66
77
|
retryAfter?: number
|
|
67
78
|
status: number
|
|
68
79
|
}) {
|
|
@@ -72,12 +83,35 @@ export class TrelloApiError extends Error {
|
|
|
72
83
|
: `Trello API request failed with status ${options.status}.`,
|
|
73
84
|
)
|
|
74
85
|
this.name = "TrelloApiError"
|
|
86
|
+
this.code = options.code
|
|
75
87
|
this.providerMessage = options.providerMessage
|
|
88
|
+
this.rateLimit = options.rateLimit
|
|
76
89
|
this.retryAfter = options.retryAfter
|
|
77
90
|
this.status = options.status
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
|
|
94
|
+
/** One Trello key or token request budget. */
|
|
95
|
+
export interface TrelloRateLimitBudget {
|
|
96
|
+
/** Length of the provider budget window in milliseconds. */
|
|
97
|
+
intervalMs: number
|
|
98
|
+
|
|
99
|
+
/** Maximum requests in the provider budget window. */
|
|
100
|
+
max: number
|
|
101
|
+
|
|
102
|
+
/** Requests remaining in the current provider budget window. */
|
|
103
|
+
remaining: number
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Rate-limit budgets returned by Trello response headers. */
|
|
107
|
+
export interface TrelloRateLimitMetadata {
|
|
108
|
+
/** Shared API-key request budget. */
|
|
109
|
+
apiKey?: TrelloRateLimitBudget
|
|
110
|
+
|
|
111
|
+
/** Connected user-token request budget. */
|
|
112
|
+
apiToken?: TrelloRateLimitBudget
|
|
113
|
+
}
|
|
114
|
+
|
|
81
115
|
/**
|
|
82
116
|
* Creates a raw authenticated Trello REST helper.
|
|
83
117
|
*
|
|
@@ -102,12 +136,17 @@ export function getTrelloApi(secret: Record<string, unknown>): TrelloApi {
|
|
|
102
136
|
url.searchParams.set("key", apiKey)
|
|
103
137
|
url.searchParams.set("token", token)
|
|
104
138
|
|
|
139
|
+
const isMultipart = options.body instanceof FormData
|
|
105
140
|
const headers = new Headers({ Accept: "application/json" })
|
|
106
|
-
if (options.body !== undefined)
|
|
141
|
+
if (options.body !== undefined && !isMultipart)
|
|
107
142
|
headers.set("Content-Type", "application/json")
|
|
108
143
|
const response = await fetch(url, {
|
|
109
144
|
body:
|
|
110
|
-
options.body === undefined
|
|
145
|
+
options.body === undefined
|
|
146
|
+
? undefined
|
|
147
|
+
: options.body instanceof FormData
|
|
148
|
+
? options.body
|
|
149
|
+
: JSON.stringify(options.body),
|
|
111
150
|
headers,
|
|
112
151
|
method: options.method ?? "GET",
|
|
113
152
|
})
|
|
@@ -115,10 +154,15 @@ export function getTrelloApi(secret: Record<string, unknown>): TrelloApi {
|
|
|
115
154
|
const responseText = await response.text()
|
|
116
155
|
const error = TRELLO_ERROR_SCHEMA.safeParse(parseJson(responseText))
|
|
117
156
|
throw new TrelloApiError({
|
|
157
|
+
code:
|
|
158
|
+
error.success && error.data.error
|
|
159
|
+
? error.data.error
|
|
160
|
+
: `http_${response.status}`,
|
|
118
161
|
providerMessage:
|
|
119
162
|
error.success && error.data.message
|
|
120
163
|
? error.data.message
|
|
121
164
|
: responseText || undefined,
|
|
165
|
+
rateLimit: parseRateLimitMetadata(response.headers),
|
|
122
166
|
retryAfter: parseRetryAfter(response.headers.get("Retry-After")),
|
|
123
167
|
status: response.status,
|
|
124
168
|
})
|
|
@@ -128,6 +172,40 @@ export function getTrelloApi(secret: Record<string, unknown>): TrelloApi {
|
|
|
128
172
|
}
|
|
129
173
|
}
|
|
130
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Parses Trello's key and token request budgets from response headers.
|
|
177
|
+
*
|
|
178
|
+
* @param headers - Provider response headers.
|
|
179
|
+
*/
|
|
180
|
+
function parseRateLimitMetadata(headers: Headers) {
|
|
181
|
+
const apiKey = parseRateLimitBudget(headers, "api-key")
|
|
182
|
+
const apiToken = parseRateLimitBudget(headers, "api-token")
|
|
183
|
+
if (!apiKey && !apiToken) return undefined
|
|
184
|
+
return { apiKey, apiToken } satisfies TrelloRateLimitMetadata
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Parses one complete Trello request budget.
|
|
189
|
+
*
|
|
190
|
+
* @param headers - Provider response headers.
|
|
191
|
+
* @param budget - Provider budget header prefix.
|
|
192
|
+
*/
|
|
193
|
+
function parseRateLimitBudget(
|
|
194
|
+
headers: Headers,
|
|
195
|
+
budget: "api-key" | "api-token",
|
|
196
|
+
) {
|
|
197
|
+
const intervalMs = parseFiniteNumber(
|
|
198
|
+
headers.get(`x-rate-limit-${budget}-interval-ms`),
|
|
199
|
+
)
|
|
200
|
+
const max = parseFiniteNumber(headers.get(`x-rate-limit-${budget}-max`))
|
|
201
|
+
const remaining = parseFiniteNumber(
|
|
202
|
+
headers.get(`x-rate-limit-${budget}-remaining`),
|
|
203
|
+
)
|
|
204
|
+
if (intervalMs === undefined || max === undefined || remaining === undefined)
|
|
205
|
+
return undefined
|
|
206
|
+
return { intervalMs, max, remaining } satisfies TrelloRateLimitBudget
|
|
207
|
+
}
|
|
208
|
+
|
|
131
209
|
/**
|
|
132
210
|
* Accepts a raw card ID, short link, or standard Trello card URL.
|
|
133
211
|
*
|
|
@@ -184,7 +262,16 @@ function parseJson(value: string): unknown {
|
|
|
184
262
|
* @param value - Raw `Retry-After` header.
|
|
185
263
|
*/
|
|
186
264
|
function parseRetryAfter(value: string | null) {
|
|
265
|
+
return parseFiniteNumber(value)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Parses one finite numeric response header.
|
|
270
|
+
*
|
|
271
|
+
* @param value - Raw response header value.
|
|
272
|
+
*/
|
|
273
|
+
function parseFiniteNumber(value: string | null) {
|
|
187
274
|
if (value === null) return undefined
|
|
188
|
-
const
|
|
189
|
-
return Number.isFinite(
|
|
275
|
+
const number = Number(value)
|
|
276
|
+
return Number.isFinite(number) ? number : undefined
|
|
190
277
|
}
|