@webhooks-cc/sdk 0.5.0 → 1.0.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/README.md +316 -140
- package/dist/chunk-7IMPSHQY.mjs +236 -0
- package/dist/diff-Dn4j4B_n.d.mts +701 -0
- package/dist/diff-Dn4j4B_n.d.ts +701 -0
- package/dist/index.d.mts +137 -324
- package/dist/index.d.ts +137 -324
- package/dist/index.js +1846 -163
- package/dist/index.mjs +1731 -286
- package/dist/testing.d.mts +30 -0
- package/dist/testing.d.ts +30 -0
- package/dist/testing.js +360 -0
- package/dist/testing.mjs +124 -0
- package/package.json +9 -4
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A webhook endpoint that captures incoming HTTP requests.
|
|
3
|
+
* Create endpoints via the dashboard or SDK to receive webhooks.
|
|
4
|
+
*/
|
|
5
|
+
interface Endpoint {
|
|
6
|
+
/** Unique identifier for this endpoint */
|
|
7
|
+
id: string;
|
|
8
|
+
/** URL-safe identifier used in webhook URLs (/w/{slug}) */
|
|
9
|
+
slug: string;
|
|
10
|
+
/** Display name for the endpoint */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Full URL where webhooks should be sent (undefined if server is misconfigured) */
|
|
13
|
+
url?: string;
|
|
14
|
+
/** Whether the endpoint auto-expires and may be cleaned up automatically */
|
|
15
|
+
isEphemeral?: boolean;
|
|
16
|
+
/** Unix timestamp (ms) when the endpoint expires, if ephemeral */
|
|
17
|
+
expiresAt?: number;
|
|
18
|
+
/** Unix timestamp (ms) when the endpoint was created */
|
|
19
|
+
createdAt: number;
|
|
20
|
+
}
|
|
21
|
+
/** Mock response returned by the receiver instead of the default 200 OK. */
|
|
22
|
+
interface MockResponse {
|
|
23
|
+
/** HTTP status code (100-599) */
|
|
24
|
+
status: number;
|
|
25
|
+
/** Raw response body */
|
|
26
|
+
body: string;
|
|
27
|
+
/** Response headers */
|
|
28
|
+
headers: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A captured webhook request with full HTTP details.
|
|
32
|
+
* Stored when a webhook arrives at an endpoint.
|
|
33
|
+
*/
|
|
34
|
+
interface Request {
|
|
35
|
+
/** Unique identifier for this request */
|
|
36
|
+
id: string;
|
|
37
|
+
/** Endpoint that received this request */
|
|
38
|
+
endpointId: string;
|
|
39
|
+
/** HTTP method (GET, POST, PUT, etc.) */
|
|
40
|
+
method: string;
|
|
41
|
+
/** Request path after the endpoint slug */
|
|
42
|
+
path: string;
|
|
43
|
+
/** HTTP headers from the original request */
|
|
44
|
+
headers: Record<string, string>;
|
|
45
|
+
/** Request body, if present */
|
|
46
|
+
body?: string;
|
|
47
|
+
/** URL query parameters */
|
|
48
|
+
queryParams: Record<string, string>;
|
|
49
|
+
/** Content-Type header value, if present */
|
|
50
|
+
contentType?: string;
|
|
51
|
+
/** Client IP address */
|
|
52
|
+
ip: string;
|
|
53
|
+
/** Request body size in bytes */
|
|
54
|
+
size: number;
|
|
55
|
+
/** Unix timestamp (ms) when the request arrived */
|
|
56
|
+
receivedAt: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A retained request returned from ClickHouse-backed search.
|
|
60
|
+
* The id is synthetic and is not compatible with requests.get()/replay().
|
|
61
|
+
*/
|
|
62
|
+
interface SearchResult {
|
|
63
|
+
/** Synthetic identifier derived from retained request contents */
|
|
64
|
+
id: string;
|
|
65
|
+
/** Endpoint slug that received this request */
|
|
66
|
+
slug: string;
|
|
67
|
+
/** HTTP method (GET, POST, PUT, etc.) */
|
|
68
|
+
method: string;
|
|
69
|
+
/** Request path after the endpoint slug */
|
|
70
|
+
path: string;
|
|
71
|
+
/** HTTP headers from the original request */
|
|
72
|
+
headers: Record<string, string>;
|
|
73
|
+
/** Request body, if present */
|
|
74
|
+
body?: string;
|
|
75
|
+
/** URL query parameters */
|
|
76
|
+
queryParams: Record<string, string>;
|
|
77
|
+
/** Content-Type header value, if present */
|
|
78
|
+
contentType?: string;
|
|
79
|
+
/** Client IP address */
|
|
80
|
+
ip: string;
|
|
81
|
+
/** Request body size in bytes */
|
|
82
|
+
size: number;
|
|
83
|
+
/** Unix timestamp (ms) when the request arrived */
|
|
84
|
+
receivedAt: number;
|
|
85
|
+
}
|
|
86
|
+
/** User-level request usage and quota information. */
|
|
87
|
+
interface UsageInfo {
|
|
88
|
+
/** Requests consumed in the current billing window */
|
|
89
|
+
used: number;
|
|
90
|
+
/** Total request quota for the current billing window */
|
|
91
|
+
limit: number;
|
|
92
|
+
/** Remaining requests before quota is exhausted */
|
|
93
|
+
remaining: number;
|
|
94
|
+
/** Current subscription plan */
|
|
95
|
+
plan: "free" | "pro";
|
|
96
|
+
/** End of the current billing window, if active */
|
|
97
|
+
periodEnd: number | null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Options for creating a new endpoint.
|
|
101
|
+
*/
|
|
102
|
+
interface CreateEndpointOptions {
|
|
103
|
+
/** Display name for the endpoint */
|
|
104
|
+
name?: string;
|
|
105
|
+
/** Whether the endpoint should auto-expire */
|
|
106
|
+
ephemeral?: boolean;
|
|
107
|
+
/** Relative expiry duration like "12h" or "7d"; implies ephemeral */
|
|
108
|
+
expiresIn?: number | string;
|
|
109
|
+
/** Optional mock response to configure at creation time */
|
|
110
|
+
mockResponse?: MockResponse;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Options for updating an existing endpoint.
|
|
114
|
+
*/
|
|
115
|
+
interface UpdateEndpointOptions {
|
|
116
|
+
/** New display name */
|
|
117
|
+
name?: string;
|
|
118
|
+
/** Mock response config, or null to clear */
|
|
119
|
+
mockResponse?: MockResponse | null;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Options for sending a test webhook to an endpoint.
|
|
123
|
+
*/
|
|
124
|
+
interface SendOptions {
|
|
125
|
+
/** HTTP method (default: "POST") */
|
|
126
|
+
method?: string;
|
|
127
|
+
/** HTTP headers to include */
|
|
128
|
+
headers?: Record<string, string>;
|
|
129
|
+
/** Request body (will be JSON-serialized if not a string) */
|
|
130
|
+
body?: unknown;
|
|
131
|
+
}
|
|
132
|
+
type TemplateProvider = "stripe" | "github" | "shopify" | "twilio" | "slack" | "paddle" | "linear" | "standard-webhooks";
|
|
133
|
+
/** Static metadata describing a supported template provider. */
|
|
134
|
+
interface TemplateProviderInfo {
|
|
135
|
+
/** Provider identifier used by sendTemplate()/sendTo() */
|
|
136
|
+
provider: TemplateProvider;
|
|
137
|
+
/** Supported provider-specific template presets */
|
|
138
|
+
templates: readonly string[];
|
|
139
|
+
/** Default template preset used when template is omitted */
|
|
140
|
+
defaultTemplate?: string;
|
|
141
|
+
/** Whether this provider requires a shared secret for signing */
|
|
142
|
+
secretRequired: boolean;
|
|
143
|
+
/** Header that carries the provider signature */
|
|
144
|
+
signatureHeader?: string;
|
|
145
|
+
/** Signature algorithm used for request signing */
|
|
146
|
+
signatureAlgorithm?: string;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Options for sending a provider template webhook with signed headers.
|
|
150
|
+
*/
|
|
151
|
+
interface SendTemplateOptions {
|
|
152
|
+
/** Provider template to use */
|
|
153
|
+
provider: TemplateProvider;
|
|
154
|
+
/** Provider-specific template preset (uses provider default if omitted) */
|
|
155
|
+
template?: string;
|
|
156
|
+
/** Shared secret used for provider signature generation */
|
|
157
|
+
secret: string;
|
|
158
|
+
/** Provider event/topic name (provider default used if omitted) */
|
|
159
|
+
event?: string;
|
|
160
|
+
/** HTTP method override (default: "POST") */
|
|
161
|
+
method?: string;
|
|
162
|
+
/** Additional headers merged after template headers */
|
|
163
|
+
headers?: Record<string, string>;
|
|
164
|
+
/** Body override; if omitted a provider-specific template body is generated */
|
|
165
|
+
body?: unknown;
|
|
166
|
+
/** Unix timestamp (seconds) override for deterministic signatures in tests */
|
|
167
|
+
timestamp?: number;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Options for listing captured requests.
|
|
171
|
+
*/
|
|
172
|
+
interface ListRequestsOptions {
|
|
173
|
+
/** Maximum number of requests to return */
|
|
174
|
+
limit?: number;
|
|
175
|
+
/** Only return requests received after this timestamp (ms) */
|
|
176
|
+
since?: number;
|
|
177
|
+
}
|
|
178
|
+
/** Cursor-based paginated result. */
|
|
179
|
+
interface PaginatedResult<T> {
|
|
180
|
+
/** Page items for this fetch */
|
|
181
|
+
items: T[];
|
|
182
|
+
/** Cursor to pass to the next page fetch */
|
|
183
|
+
cursor?: string;
|
|
184
|
+
/** Whether another page is available */
|
|
185
|
+
hasMore: boolean;
|
|
186
|
+
}
|
|
187
|
+
/** Options for cursor-based request pagination. */
|
|
188
|
+
interface ListPaginatedRequestsOptions {
|
|
189
|
+
/** Maximum number of requests to return */
|
|
190
|
+
limit?: number;
|
|
191
|
+
/** Opaque cursor from a previous page */
|
|
192
|
+
cursor?: string;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Options for clearing captured requests from an endpoint.
|
|
196
|
+
*/
|
|
197
|
+
interface ClearRequestsOptions {
|
|
198
|
+
/** Only delete requests received before this timestamp (ms) or relative duration */
|
|
199
|
+
before?: number | string;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Filters for retained request search/count.
|
|
203
|
+
* String timestamps may be absolute milliseconds ("1700000000000") or relative durations ("1h", "7d").
|
|
204
|
+
*/
|
|
205
|
+
interface SearchFilters {
|
|
206
|
+
/** Restrict results to a single endpoint slug */
|
|
207
|
+
slug?: string;
|
|
208
|
+
/** Restrict results to a specific HTTP method */
|
|
209
|
+
method?: string;
|
|
210
|
+
/** Free-text substring search across path, body, and headers */
|
|
211
|
+
q?: string;
|
|
212
|
+
/** Lower bound for receivedAt (absolute ms or relative duration) */
|
|
213
|
+
from?: number | string;
|
|
214
|
+
/** Upper bound for receivedAt (absolute ms or relative duration) */
|
|
215
|
+
to?: number | string;
|
|
216
|
+
/** Maximum number of results to return */
|
|
217
|
+
limit?: number;
|
|
218
|
+
/** Result offset for pagination */
|
|
219
|
+
offset?: number;
|
|
220
|
+
/** Result ordering by receivedAt */
|
|
221
|
+
order?: "asc" | "desc";
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Options for waitFor() polling behavior.
|
|
225
|
+
*/
|
|
226
|
+
interface WaitForOptions {
|
|
227
|
+
/** Maximum time to wait (ms or duration string like "30s", "5m") (default: 30000) */
|
|
228
|
+
timeout?: number | string;
|
|
229
|
+
/** Interval between polls (ms or duration string) (default: 500, min: 10, max: 60000) */
|
|
230
|
+
pollInterval?: number | string;
|
|
231
|
+
/** Filter function to match specific requests */
|
|
232
|
+
match?: (request: Request) => boolean;
|
|
233
|
+
}
|
|
234
|
+
/** Options for waitForAll() multi-request collection. */
|
|
235
|
+
interface WaitForAllOptions extends WaitForOptions {
|
|
236
|
+
/** Number of matching requests to collect before returning */
|
|
237
|
+
count: number;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Options for subscribe() SSE streaming.
|
|
241
|
+
*/
|
|
242
|
+
interface SubscribeOptions {
|
|
243
|
+
/** AbortSignal to cancel the subscription */
|
|
244
|
+
signal?: AbortSignal;
|
|
245
|
+
/** Maximum time to stream (ms or duration string like "30m") */
|
|
246
|
+
timeout?: number | string;
|
|
247
|
+
/** Automatically reconnect when the SSE stream ends unexpectedly */
|
|
248
|
+
reconnect?: boolean;
|
|
249
|
+
/** Maximum reconnect attempts before giving up (default: 5) */
|
|
250
|
+
maxReconnectAttempts?: number;
|
|
251
|
+
/** Base backoff delay between reconnects */
|
|
252
|
+
reconnectBackoffMs?: number | string;
|
|
253
|
+
/** Callback invoked before each reconnect attempt */
|
|
254
|
+
onReconnect?: (attempt: number) => void;
|
|
255
|
+
}
|
|
256
|
+
/** Info passed to the onRequest hook before a request is sent. */
|
|
257
|
+
interface RequestHookInfo {
|
|
258
|
+
method: string;
|
|
259
|
+
url: string;
|
|
260
|
+
}
|
|
261
|
+
/** Info passed to the onResponse hook after a successful response. */
|
|
262
|
+
interface ResponseHookInfo {
|
|
263
|
+
method: string;
|
|
264
|
+
url: string;
|
|
265
|
+
status: number;
|
|
266
|
+
durationMs: number;
|
|
267
|
+
}
|
|
268
|
+
/** Info passed to the onError hook when a request fails. */
|
|
269
|
+
interface ErrorHookInfo {
|
|
270
|
+
method: string;
|
|
271
|
+
url: string;
|
|
272
|
+
error: Error;
|
|
273
|
+
durationMs: number;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Lifecycle hooks for observability and telemetry integration.
|
|
277
|
+
* All hooks are optional and are called synchronously (fire-and-forget).
|
|
278
|
+
*/
|
|
279
|
+
interface ClientHooks {
|
|
280
|
+
onRequest?: (info: RequestHookInfo) => void;
|
|
281
|
+
onResponse?: (info: ResponseHookInfo) => void;
|
|
282
|
+
onError?: (info: ErrorHookInfo) => void;
|
|
283
|
+
}
|
|
284
|
+
/** Retry configuration for transient API failures. */
|
|
285
|
+
interface RetryOptions {
|
|
286
|
+
/** Total attempts including the initial request */
|
|
287
|
+
maxAttempts?: number;
|
|
288
|
+
/** Base backoff delay in milliseconds */
|
|
289
|
+
backoffMs?: number;
|
|
290
|
+
/** HTTP status codes that should be retried */
|
|
291
|
+
retryOn?: number[];
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Configuration options for the WebhooksCC client.
|
|
295
|
+
*/
|
|
296
|
+
interface ClientOptions {
|
|
297
|
+
/** API key for authentication (format: whcc_...) */
|
|
298
|
+
apiKey: string;
|
|
299
|
+
/** Base URL for the API (default: https://webhooks.cc) */
|
|
300
|
+
baseUrl?: string;
|
|
301
|
+
/** Base URL for sending webhooks (default: https://go.webhooks.cc) */
|
|
302
|
+
webhookUrl?: string;
|
|
303
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
304
|
+
timeout?: number;
|
|
305
|
+
/** Retry policy for transient API failures */
|
|
306
|
+
retry?: RetryOptions;
|
|
307
|
+
/** Lifecycle hooks for observability */
|
|
308
|
+
hooks?: ClientHooks;
|
|
309
|
+
}
|
|
310
|
+
/** Description of a single SDK operation. */
|
|
311
|
+
interface OperationDescription {
|
|
312
|
+
description: string;
|
|
313
|
+
params: Record<string, string>;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Options for sending a webhook directly to an arbitrary URL.
|
|
317
|
+
* Supports optional provider signing (Standard Webhooks, Stripe, etc.).
|
|
318
|
+
*/
|
|
319
|
+
interface SendToOptions {
|
|
320
|
+
/** Provider template for signing (optional). When set, secret is required. */
|
|
321
|
+
provider?: TemplateProvider;
|
|
322
|
+
/** Provider-specific template preset (e.g. "checkout.session.completed" for Stripe) */
|
|
323
|
+
template?: string;
|
|
324
|
+
/** Secret for provider signature generation (required when provider is set) */
|
|
325
|
+
secret?: string;
|
|
326
|
+
/** Event name for provider headers */
|
|
327
|
+
event?: string;
|
|
328
|
+
/** HTTP method (default: "POST") */
|
|
329
|
+
method?: string;
|
|
330
|
+
/** HTTP headers to include */
|
|
331
|
+
headers?: Record<string, string>;
|
|
332
|
+
/** Request body (will be JSON-serialized if not a string) */
|
|
333
|
+
body?: unknown;
|
|
334
|
+
/** Unix timestamp (seconds) override for deterministic signatures in tests */
|
|
335
|
+
timestamp?: number;
|
|
336
|
+
}
|
|
337
|
+
/** Result returned by verifySignature(). */
|
|
338
|
+
interface SignatureVerificationResult {
|
|
339
|
+
/** Whether the computed signature matched the provided signature header(s) */
|
|
340
|
+
valid: boolean;
|
|
341
|
+
}
|
|
342
|
+
/** Providers supported by verifySignature(). */
|
|
343
|
+
type VerifyProvider = TemplateProvider | "discord";
|
|
344
|
+
/**
|
|
345
|
+
* Options for verifying a captured webhook signature.
|
|
346
|
+
* For Twilio, `url` is required because the signature covers the full webhook URL.
|
|
347
|
+
*/
|
|
348
|
+
type VerifySignatureOptions = {
|
|
349
|
+
/** Provider whose signature format should be verified */
|
|
350
|
+
provider: Exclude<VerifyProvider, "discord">;
|
|
351
|
+
/** Shared secret used by the provider when signing the webhook */
|
|
352
|
+
secret: string;
|
|
353
|
+
/** Full signed URL (required for Twilio verification) */
|
|
354
|
+
url?: string;
|
|
355
|
+
} | {
|
|
356
|
+
/** Discord interaction verification */
|
|
357
|
+
provider: "discord";
|
|
358
|
+
/** Discord application public key (hex) */
|
|
359
|
+
publicKey: string;
|
|
360
|
+
};
|
|
361
|
+
/** Value type returned when parsing form-encoded request bodies. */
|
|
362
|
+
type FormBodyValue = string | string[];
|
|
363
|
+
/** Parsed application/x-www-form-urlencoded body. */
|
|
364
|
+
type ParsedFormBody = Record<string, FormBodyValue>;
|
|
365
|
+
/** Result from parseBody() based on content-type detection. */
|
|
366
|
+
type ParsedBody = unknown | ParsedFormBody | string | undefined;
|
|
367
|
+
/** Options for bulk request export. */
|
|
368
|
+
interface ExportRequestsOptions {
|
|
369
|
+
/** Output format */
|
|
370
|
+
format: "har" | "curl";
|
|
371
|
+
/** Maximum number of requests to export */
|
|
372
|
+
limit?: number;
|
|
373
|
+
/** Only include requests received after this timestamp (ms) */
|
|
374
|
+
since?: number;
|
|
375
|
+
}
|
|
376
|
+
/** HAR header entry. */
|
|
377
|
+
interface HarHeader {
|
|
378
|
+
name: string;
|
|
379
|
+
value: string;
|
|
380
|
+
}
|
|
381
|
+
/** HAR query parameter entry. */
|
|
382
|
+
interface HarQueryParam {
|
|
383
|
+
name: string;
|
|
384
|
+
value: string;
|
|
385
|
+
}
|
|
386
|
+
/** HAR request body metadata. */
|
|
387
|
+
interface HarPostData {
|
|
388
|
+
mimeType: string;
|
|
389
|
+
text: string;
|
|
390
|
+
}
|
|
391
|
+
/** HAR request object. */
|
|
392
|
+
interface HarRequest {
|
|
393
|
+
method: string;
|
|
394
|
+
url: string;
|
|
395
|
+
httpVersion: string;
|
|
396
|
+
headers: HarHeader[];
|
|
397
|
+
queryString: HarQueryParam[];
|
|
398
|
+
headersSize: number;
|
|
399
|
+
bodySize: number;
|
|
400
|
+
postData?: HarPostData;
|
|
401
|
+
}
|
|
402
|
+
/** HAR response object. */
|
|
403
|
+
interface HarResponse {
|
|
404
|
+
status: number;
|
|
405
|
+
statusText: string;
|
|
406
|
+
httpVersion: string;
|
|
407
|
+
headers: HarHeader[];
|
|
408
|
+
cookies: [];
|
|
409
|
+
content: {
|
|
410
|
+
size: number;
|
|
411
|
+
mimeType: string;
|
|
412
|
+
text?: string;
|
|
413
|
+
};
|
|
414
|
+
redirectURL: string;
|
|
415
|
+
headersSize: number;
|
|
416
|
+
bodySize: number;
|
|
417
|
+
}
|
|
418
|
+
/** HAR entry for a captured request. */
|
|
419
|
+
interface HarEntry {
|
|
420
|
+
startedDateTime: string;
|
|
421
|
+
time: number;
|
|
422
|
+
request: HarRequest;
|
|
423
|
+
response: HarResponse;
|
|
424
|
+
cache: Record<string, never>;
|
|
425
|
+
timings: {
|
|
426
|
+
send: number;
|
|
427
|
+
wait: number;
|
|
428
|
+
receive: number;
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
/** HAR export archive. */
|
|
432
|
+
interface HarExport {
|
|
433
|
+
log: {
|
|
434
|
+
version: "1.2";
|
|
435
|
+
creator: {
|
|
436
|
+
name: string;
|
|
437
|
+
version: string;
|
|
438
|
+
};
|
|
439
|
+
entries: HarEntry[];
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
/** cURL export output. */
|
|
443
|
+
type CurlExport = string[];
|
|
444
|
+
/** Union returned by requests.export(). */
|
|
445
|
+
type RequestsExport = HarExport | CurlExport;
|
|
446
|
+
/** Self-describing schema returned by client.describe(). */
|
|
447
|
+
interface SDKDescription {
|
|
448
|
+
version: string;
|
|
449
|
+
endpoints: Record<string, OperationDescription>;
|
|
450
|
+
templates: Record<string, OperationDescription>;
|
|
451
|
+
usage: OperationDescription;
|
|
452
|
+
sendTo: OperationDescription;
|
|
453
|
+
buildRequest: OperationDescription;
|
|
454
|
+
flow: OperationDescription;
|
|
455
|
+
requests: Record<string, OperationDescription>;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Base error class for all webhooks.cc SDK errors.
|
|
460
|
+
* Extends the standard Error with an HTTP status code.
|
|
461
|
+
*/
|
|
462
|
+
declare class WebhooksCCError extends Error {
|
|
463
|
+
readonly statusCode: number;
|
|
464
|
+
constructor(statusCode: number, message: string);
|
|
465
|
+
}
|
|
466
|
+
/** Thrown when the API key is invalid or missing (401). */
|
|
467
|
+
declare class UnauthorizedError extends WebhooksCCError {
|
|
468
|
+
constructor(message?: string);
|
|
469
|
+
}
|
|
470
|
+
/** Thrown when the requested resource does not exist (404). */
|
|
471
|
+
declare class NotFoundError extends WebhooksCCError {
|
|
472
|
+
constructor(message?: string);
|
|
473
|
+
}
|
|
474
|
+
/** Thrown when the request times out. */
|
|
475
|
+
declare class TimeoutError extends WebhooksCCError {
|
|
476
|
+
constructor(timeoutMs: number);
|
|
477
|
+
}
|
|
478
|
+
/** Thrown when the API returns 429 Too Many Requests. */
|
|
479
|
+
declare class RateLimitError extends WebhooksCCError {
|
|
480
|
+
/** Seconds until the rate limit resets, if provided by the server. */
|
|
481
|
+
readonly retryAfter?: number;
|
|
482
|
+
constructor(retryAfter?: number);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
interface FlowClient {
|
|
486
|
+
endpoints: {
|
|
487
|
+
create(options?: CreateEndpointOptions): Promise<Endpoint>;
|
|
488
|
+
update(slug: string, options: {
|
|
489
|
+
name?: string;
|
|
490
|
+
mockResponse?: MockResponse | null;
|
|
491
|
+
}): Promise<Endpoint>;
|
|
492
|
+
delete(slug: string): Promise<void>;
|
|
493
|
+
send(slug: string, options?: SendOptions): Promise<Response>;
|
|
494
|
+
sendTemplate(slug: string, options: SendTemplateOptions): Promise<Response>;
|
|
495
|
+
};
|
|
496
|
+
requests: {
|
|
497
|
+
waitFor(slug: string, options?: WaitForOptions): Promise<Request>;
|
|
498
|
+
replay(requestId: string, targetUrl: string): Promise<Response>;
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
type WebhookFlowVerifyOptions = {
|
|
502
|
+
provider: Exclude<VerifySignatureOptions["provider"], "discord">;
|
|
503
|
+
secret: string;
|
|
504
|
+
/**
|
|
505
|
+
* Signed URL override.
|
|
506
|
+
* For Twilio, the endpoint URL is used automatically when omitted.
|
|
507
|
+
*/
|
|
508
|
+
url?: string | ((endpoint: Endpoint, request: Request) => string);
|
|
509
|
+
} | {
|
|
510
|
+
provider: "discord";
|
|
511
|
+
publicKey: string;
|
|
512
|
+
url?: string | ((endpoint: Endpoint, request: Request) => string);
|
|
513
|
+
};
|
|
514
|
+
interface WebhookFlowResult {
|
|
515
|
+
endpoint: Endpoint;
|
|
516
|
+
request?: Request;
|
|
517
|
+
verification?: SignatureVerificationResult;
|
|
518
|
+
replayResponse?: Response;
|
|
519
|
+
cleanedUp: boolean;
|
|
520
|
+
}
|
|
521
|
+
declare class WebhookFlowBuilder {
|
|
522
|
+
private readonly client;
|
|
523
|
+
private createOptions;
|
|
524
|
+
private mockResponse;
|
|
525
|
+
private sendStep;
|
|
526
|
+
private waitOptions;
|
|
527
|
+
private verificationOptions;
|
|
528
|
+
private replayTargetUrl;
|
|
529
|
+
private deleteAfterRun;
|
|
530
|
+
constructor(client: FlowClient);
|
|
531
|
+
createEndpoint(options?: CreateEndpointOptions): this;
|
|
532
|
+
setMock(mockResponse: MockResponse | null): this;
|
|
533
|
+
send(options?: SendOptions): this;
|
|
534
|
+
sendTemplate(options: SendTemplateOptions): this;
|
|
535
|
+
waitForCapture(options?: WaitForOptions): this;
|
|
536
|
+
verifySignature(options: WebhookFlowVerifyOptions): this;
|
|
537
|
+
replayTo(targetUrl: string): this;
|
|
538
|
+
cleanup(): this;
|
|
539
|
+
run(): Promise<WebhookFlowResult>;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* @fileoverview webhooks.cc SDK client for programmatic webhook management.
|
|
544
|
+
*
|
|
545
|
+
* @example
|
|
546
|
+
* ```typescript
|
|
547
|
+
* import { WebhooksCC, matchMethod } from '@webhooks-cc/sdk';
|
|
548
|
+
*
|
|
549
|
+
* const client = new WebhooksCC({ apiKey: 'whcc_...' });
|
|
550
|
+
* const endpoint = await client.endpoints.create({ name: 'My Webhook' });
|
|
551
|
+
* const request = await client.requests.waitFor(endpoint.slug, {
|
|
552
|
+
* timeout: '30s',
|
|
553
|
+
* match: matchMethod('POST'),
|
|
554
|
+
* });
|
|
555
|
+
* ```
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* @deprecated Use {@link WebhooksCCError} instead. Kept for backward compatibility.
|
|
560
|
+
*/
|
|
561
|
+
declare const ApiError: typeof WebhooksCCError;
|
|
562
|
+
/**
|
|
563
|
+
* Client for the webhooks.cc API.
|
|
564
|
+
*
|
|
565
|
+
* Provides methods to create endpoints, list captured requests, and wait
|
|
566
|
+
* for incoming webhooks. Handles authentication, request signing, and
|
|
567
|
+
* response validation.
|
|
568
|
+
*/
|
|
569
|
+
declare class WebhooksCC {
|
|
570
|
+
private readonly apiKey;
|
|
571
|
+
private readonly baseUrl;
|
|
572
|
+
private readonly webhookUrl;
|
|
573
|
+
private readonly timeout;
|
|
574
|
+
private readonly retry;
|
|
575
|
+
private readonly hooks;
|
|
576
|
+
constructor(options: ClientOptions);
|
|
577
|
+
private request;
|
|
578
|
+
/** Returns a static description of all SDK operations (no API call). */
|
|
579
|
+
describe(): SDKDescription;
|
|
580
|
+
endpoints: {
|
|
581
|
+
create: (options?: CreateEndpointOptions) => Promise<Endpoint>;
|
|
582
|
+
list: () => Promise<Endpoint[]>;
|
|
583
|
+
get: (slug: string) => Promise<Endpoint>;
|
|
584
|
+
update: (slug: string, options: UpdateEndpointOptions) => Promise<Endpoint>;
|
|
585
|
+
delete: (slug: string) => Promise<void>;
|
|
586
|
+
send: (slug: string, options?: SendOptions) => Promise<Response>;
|
|
587
|
+
sendTemplate: (slug: string, options: SendTemplateOptions) => Promise<Response>;
|
|
588
|
+
};
|
|
589
|
+
templates: {
|
|
590
|
+
listProviders: () => TemplateProvider[];
|
|
591
|
+
get: (provider: TemplateProvider) => TemplateProviderInfo;
|
|
592
|
+
};
|
|
593
|
+
usage: () => Promise<UsageInfo>;
|
|
594
|
+
flow: () => WebhookFlowBuilder;
|
|
595
|
+
/**
|
|
596
|
+
* Build a request without sending it. Returns the computed method, URL,
|
|
597
|
+
* headers, and body — including any provider signatures. Useful for
|
|
598
|
+
* debugging what sendTo would actually send.
|
|
599
|
+
*
|
|
600
|
+
* @param url - Target URL (http or https)
|
|
601
|
+
* @param options - Same options as sendTo
|
|
602
|
+
* @returns The computed request details
|
|
603
|
+
*/
|
|
604
|
+
buildRequest: (url: string, options?: SendToOptions) => Promise<{
|
|
605
|
+
url: string;
|
|
606
|
+
method: string;
|
|
607
|
+
headers: Record<string, string>;
|
|
608
|
+
body?: string;
|
|
609
|
+
}>;
|
|
610
|
+
/**
|
|
611
|
+
* Send a webhook directly to any URL with optional provider signing.
|
|
612
|
+
* Use this for local integration testing — send properly signed webhooks
|
|
613
|
+
* to localhost handlers without routing through webhooks.cc infrastructure.
|
|
614
|
+
*
|
|
615
|
+
* @param url - Target URL to send the webhook to (http or https)
|
|
616
|
+
* @param options - Method, headers, body, and optional provider signing
|
|
617
|
+
* @returns Raw fetch Response from the target
|
|
618
|
+
*/
|
|
619
|
+
sendTo: (url: string, options?: SendToOptions) => Promise<Response>;
|
|
620
|
+
requests: {
|
|
621
|
+
list: (endpointSlug: string, options?: ListRequestsOptions) => Promise<Request[]>;
|
|
622
|
+
listPaginated: (endpointSlug: string, options?: ListPaginatedRequestsOptions) => Promise<PaginatedResult<Request>>;
|
|
623
|
+
get: (requestId: string) => Promise<Request>;
|
|
624
|
+
waitForAll: (endpointSlug: string, options: WaitForAllOptions) => Promise<Request[]>;
|
|
625
|
+
search: (filters?: SearchFilters) => Promise<SearchResult[]>;
|
|
626
|
+
count: (filters?: SearchFilters) => Promise<number>;
|
|
627
|
+
clear: (endpointSlug: string, options?: ClearRequestsOptions) => Promise<void>;
|
|
628
|
+
export: (endpointSlug: string, options: ExportRequestsOptions) => Promise<RequestsExport>;
|
|
629
|
+
/**
|
|
630
|
+
* Polls for incoming requests until one matches or timeout expires.
|
|
631
|
+
*
|
|
632
|
+
* Fetches requests that arrived since the last successful check. On API
|
|
633
|
+
* errors, continues polling without updating the timestamp to avoid
|
|
634
|
+
* missing requests during transient failures.
|
|
635
|
+
*
|
|
636
|
+
* @param endpointSlug - Endpoint to monitor
|
|
637
|
+
* @param options - Timeout, poll interval, and optional match filter
|
|
638
|
+
* @returns First matching request, or first request if no match filter
|
|
639
|
+
* @throws Error if timeout expires or max iterations (10000) reached
|
|
640
|
+
*/
|
|
641
|
+
waitFor: (endpointSlug: string, options?: WaitForOptions) => Promise<Request>;
|
|
642
|
+
/**
|
|
643
|
+
* Replay a captured request to a target URL.
|
|
644
|
+
*
|
|
645
|
+
* Fetches the original request by ID and re-sends it to the specified URL
|
|
646
|
+
* with the original method, headers, and body. Hop-by-hop headers are stripped.
|
|
647
|
+
*/
|
|
648
|
+
replay: (requestId: string, targetUrl: string) => Promise<Response>;
|
|
649
|
+
/**
|
|
650
|
+
* Stream incoming requests via SSE as an async iterator.
|
|
651
|
+
*
|
|
652
|
+
* Connects to the SSE endpoint and yields Request objects as they arrive.
|
|
653
|
+
* The connection is closed when the iterator is broken, the signal is aborted,
|
|
654
|
+
* or the timeout expires.
|
|
655
|
+
*
|
|
656
|
+
* Reconnection is opt-in and resumes from the last yielded request timestamp.
|
|
657
|
+
*/
|
|
658
|
+
subscribe: (slug: string, options?: SubscribeOptions) => AsyncIterable<Request>;
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
interface ValueDifference<T> {
|
|
663
|
+
left: T;
|
|
664
|
+
right: T;
|
|
665
|
+
}
|
|
666
|
+
interface HeaderDiff {
|
|
667
|
+
added: string[];
|
|
668
|
+
removed: string[];
|
|
669
|
+
changed: Record<string, ValueDifference<string>>;
|
|
670
|
+
}
|
|
671
|
+
interface JsonBodyDiff {
|
|
672
|
+
type: "json";
|
|
673
|
+
changed: Record<string, ValueDifference<unknown>>;
|
|
674
|
+
diff: string;
|
|
675
|
+
}
|
|
676
|
+
interface TextBodyDiff {
|
|
677
|
+
type: "text";
|
|
678
|
+
diff: string;
|
|
679
|
+
}
|
|
680
|
+
type BodyDiff = JsonBodyDiff | TextBodyDiff;
|
|
681
|
+
interface RequestDifferences {
|
|
682
|
+
method?: ValueDifference<string>;
|
|
683
|
+
path?: ValueDifference<string>;
|
|
684
|
+
headers?: HeaderDiff;
|
|
685
|
+
body?: BodyDiff;
|
|
686
|
+
}
|
|
687
|
+
interface DiffRequestsOptions {
|
|
688
|
+
/** Header names to exclude from comparison. Matched case-insensitively. */
|
|
689
|
+
ignoreHeaders?: string[];
|
|
690
|
+
}
|
|
691
|
+
interface DiffResult {
|
|
692
|
+
matches: boolean;
|
|
693
|
+
differences: RequestDifferences;
|
|
694
|
+
}
|
|
695
|
+
type ComparableRequest = Pick<Request, "method" | "path" | "headers" | "body"> & Partial<Pick<Request, "queryParams" | "contentType">>;
|
|
696
|
+
/**
|
|
697
|
+
* Compare two requests and return a structured diff suitable for debugging or tooling.
|
|
698
|
+
*/
|
|
699
|
+
declare function diffRequests(left: ComparableRequest | SearchResult, right: ComparableRequest | SearchResult, options?: DiffRequestsOptions): DiffResult;
|
|
700
|
+
|
|
701
|
+
export { type WebhookFlowVerifyOptions as $, ApiError as A, type BodyDiff as B, type ClearRequestsOptions as C, type DiffRequestsOptions as D, type Endpoint as E, type FormBodyValue as F, TimeoutError as G, type HarExport as H, type UpdateEndpointOptions as I, type JsonBodyDiff as J, type UsageInfo as K, type ListPaginatedRequestsOptions as L, type MockResponse as M, NotFoundError as N, type OperationDescription as O, type ParsedBody as P, type ValueDifference as Q, type Request as R, type SearchResult as S, type TemplateProvider as T, UnauthorizedError as U, type VerifySignatureOptions as V, type VerifyProvider as W, type WaitForAllOptions as X, type WaitForOptions as Y, WebhookFlowBuilder as Z, type WebhookFlowResult as _, type ParsedFormBody as a, WebhooksCC as a0, WebhooksCCError as a1, diffRequests as a2, type SignatureVerificationResult as b, type ClientHooks as c, type ClientOptions as d, type CreateEndpointOptions as e, type CurlExport as f, type DiffResult as g, type ErrorHookInfo as h, type ExportRequestsOptions as i, type HeaderDiff as j, type ListRequestsOptions as k, type PaginatedResult as l, RateLimitError as m, type RequestDifferences as n, type RequestHookInfo as o, type RequestsExport as p, type ResponseHookInfo as q, type RetryOptions as r, type SDKDescription as s, type SearchFilters as t, type SendOptions as u, type SendTemplateOptions as v, type SendToOptions as w, type SubscribeOptions as x, type TemplateProviderInfo as y, type TextBodyDiff as z };
|