@webhooks-cc/sdk 1.2.1 → 1.3.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/{diff-kGWh0pPP.d.mts → diff-CRMlHQPX.d.mts} +43 -1
- package/dist/{diff-kGWh0pPP.d.ts → diff-CRMlHQPX.d.ts} +43 -1
- package/dist/index.d.mts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +198 -14
- package/dist/index.mjs +182 -14
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/package.json +4 -3
|
@@ -18,6 +18,10 @@ interface Endpoint {
|
|
|
18
18
|
name?: string;
|
|
19
19
|
/** Full URL where webhooks should be sent (undefined if server is misconfigured) */
|
|
20
20
|
url?: string;
|
|
21
|
+
/** URL to POST a JSON summary to after each captured request (e.g. Slack/Discord webhook) */
|
|
22
|
+
notificationUrl?: string;
|
|
23
|
+
/** Ordered conditional response rules (first match wins, then falls back to default mock) */
|
|
24
|
+
responseRules?: ResponseRule[];
|
|
21
25
|
/** Whether the endpoint auto-expires and may be cleaned up automatically */
|
|
22
26
|
isEphemeral?: boolean;
|
|
23
27
|
/** Unix timestamp (ms) when the endpoint expires, if ephemeral */
|
|
@@ -29,6 +33,34 @@ interface Endpoint {
|
|
|
29
33
|
/** Team this endpoint was shared from (present when shared with you) */
|
|
30
34
|
fromTeam?: TeamShare;
|
|
31
35
|
}
|
|
36
|
+
/** A single condition within a response rule. */
|
|
37
|
+
interface ResponseRuleCondition {
|
|
38
|
+
/** Field to match: method, path, header, body_contains, body_path, query */
|
|
39
|
+
field: "method" | "path" | "header" | "body_contains" | "body_path" | "query";
|
|
40
|
+
/** Comparison operator */
|
|
41
|
+
op: "eq" | "contains" | "starts_with" | "matches" | "exists";
|
|
42
|
+
/** Value to compare against (not required for "exists") */
|
|
43
|
+
value?: string;
|
|
44
|
+
/** Header name or query param name (required for header/query conditions) */
|
|
45
|
+
name?: string;
|
|
46
|
+
/** JSON dot-notation path (required for body_path conditions) */
|
|
47
|
+
path?: string;
|
|
48
|
+
}
|
|
49
|
+
/** A conditional response rule: when conditions match, return this response. */
|
|
50
|
+
interface ResponseRule {
|
|
51
|
+
/** Stable identifier for UI drag-reorder */
|
|
52
|
+
id?: string;
|
|
53
|
+
/** Human-readable rule name */
|
|
54
|
+
name?: string;
|
|
55
|
+
/** Whether this rule is active (default: true) */
|
|
56
|
+
enabled?: boolean;
|
|
57
|
+
/** How to combine conditions: "and" (all match) or "or" (any match). Default: "and" */
|
|
58
|
+
logic?: "and" | "or";
|
|
59
|
+
/** Conditions to evaluate against the incoming request */
|
|
60
|
+
conditions: ResponseRuleCondition[];
|
|
61
|
+
/** Response to return when conditions match */
|
|
62
|
+
response: MockResponse;
|
|
63
|
+
}
|
|
32
64
|
/** Mock response returned by the receiver instead of the default 200 OK. */
|
|
33
65
|
interface MockResponse {
|
|
34
66
|
/** HTTP status code (100-599) */
|
|
@@ -57,6 +89,8 @@ interface Request {
|
|
|
57
89
|
headers: Record<string, string>;
|
|
58
90
|
/** Request body, if present */
|
|
59
91
|
body?: string;
|
|
92
|
+
/** Base64-encoded raw bytes, present only for non-UTF-8 payloads */
|
|
93
|
+
bodyRaw?: string;
|
|
60
94
|
/** URL query parameters */
|
|
61
95
|
queryParams: Record<string, string>;
|
|
62
96
|
/** Content-Type header value, if present */
|
|
@@ -121,6 +155,10 @@ interface CreateEndpointOptions {
|
|
|
121
155
|
expiresIn?: number | string;
|
|
122
156
|
/** Optional mock response to configure at creation time */
|
|
123
157
|
mockResponse?: MockResponse;
|
|
158
|
+
/** URL to POST a JSON summary to after each captured request */
|
|
159
|
+
notificationUrl?: string;
|
|
160
|
+
/** Ordered conditional response rules */
|
|
161
|
+
responseRules?: ResponseRule[];
|
|
124
162
|
}
|
|
125
163
|
/**
|
|
126
164
|
* Options for updating an existing endpoint.
|
|
@@ -130,6 +168,10 @@ interface UpdateEndpointOptions {
|
|
|
130
168
|
name?: string;
|
|
131
169
|
/** Mock response config, or null to clear */
|
|
132
170
|
mockResponse?: MockResponse | null;
|
|
171
|
+
/** Notification webhook URL, or null to clear */
|
|
172
|
+
notificationUrl?: string | null;
|
|
173
|
+
/** Ordered conditional response rules, or null to clear */
|
|
174
|
+
responseRules?: ResponseRule[] | null;
|
|
133
175
|
}
|
|
134
176
|
/**
|
|
135
177
|
* Options for sending a test webhook to an endpoint.
|
|
@@ -726,4 +768,4 @@ type ComparableRequest = Pick<Request, "method" | "path" | "headers" | "body"> &
|
|
|
726
768
|
*/
|
|
727
769
|
declare function diffRequests(left: ComparableRequest | SearchResult, right: ComparableRequest | SearchResult, options?: DiffRequestsOptions): DiffResult;
|
|
728
770
|
|
|
729
|
-
export {
|
|
771
|
+
export { type WaitForAllOptions as $, ApiError as A, type BodyDiff as B, type ClearRequestsOptions as C, type DiffRequestsOptions as D, type Endpoint as E, type FormBodyValue as F, type SubscribeOptions as G, type HarExport as H, type TemplateProvider as I, type JsonBodyDiff as J, type TemplateProviderInfo as K, type ListPaginatedRequestsOptions as L, type MockResponse as M, NotFoundError as N, type OperationDescription as O, type ParsedBody as P, type TextBodyDiff as Q, type Request as R, type SendTemplateOptions as S, type TeamShare as T, TimeoutError as U, type VerifySignatureOptions as V, UnauthorizedError as W, type UpdateEndpointOptions as X, type UsageInfo as Y, type ValueDifference as Z, type VerifyProvider as _, type ParsedFormBody as a, type WaitForOptions as a0, WebhookFlowBuilder as a1, type WebhookFlowResult as a2, type WebhookFlowVerifyOptions as a3, WebhooksCC as a4, WebhooksCCError as a5, diffRequests as a6, type SendOptions as b, type ResponseRule as c, type SearchResult as d, type SignatureVerificationResult as e, type ClientHooks as f, type ClientOptions as g, type CreateEndpointOptions as h, type CurlExport as i, type DiffResult as j, type ErrorHookInfo as k, type ExportRequestsOptions as l, type HeaderDiff as m, type ListRequestsOptions as n, type PaginatedResult as o, RateLimitError as p, type RateLimitMeta as q, type RequestDifferences as r, type RequestHookInfo as s, type RequestsExport as t, type ResponseHookInfo as u, type ResponseRuleCondition as v, type RetryOptions as w, type SDKDescription as x, type SearchFilters as y, type SendToOptions as z };
|
|
@@ -18,6 +18,10 @@ interface Endpoint {
|
|
|
18
18
|
name?: string;
|
|
19
19
|
/** Full URL where webhooks should be sent (undefined if server is misconfigured) */
|
|
20
20
|
url?: string;
|
|
21
|
+
/** URL to POST a JSON summary to after each captured request (e.g. Slack/Discord webhook) */
|
|
22
|
+
notificationUrl?: string;
|
|
23
|
+
/** Ordered conditional response rules (first match wins, then falls back to default mock) */
|
|
24
|
+
responseRules?: ResponseRule[];
|
|
21
25
|
/** Whether the endpoint auto-expires and may be cleaned up automatically */
|
|
22
26
|
isEphemeral?: boolean;
|
|
23
27
|
/** Unix timestamp (ms) when the endpoint expires, if ephemeral */
|
|
@@ -29,6 +33,34 @@ interface Endpoint {
|
|
|
29
33
|
/** Team this endpoint was shared from (present when shared with you) */
|
|
30
34
|
fromTeam?: TeamShare;
|
|
31
35
|
}
|
|
36
|
+
/** A single condition within a response rule. */
|
|
37
|
+
interface ResponseRuleCondition {
|
|
38
|
+
/** Field to match: method, path, header, body_contains, body_path, query */
|
|
39
|
+
field: "method" | "path" | "header" | "body_contains" | "body_path" | "query";
|
|
40
|
+
/** Comparison operator */
|
|
41
|
+
op: "eq" | "contains" | "starts_with" | "matches" | "exists";
|
|
42
|
+
/** Value to compare against (not required for "exists") */
|
|
43
|
+
value?: string;
|
|
44
|
+
/** Header name or query param name (required for header/query conditions) */
|
|
45
|
+
name?: string;
|
|
46
|
+
/** JSON dot-notation path (required for body_path conditions) */
|
|
47
|
+
path?: string;
|
|
48
|
+
}
|
|
49
|
+
/** A conditional response rule: when conditions match, return this response. */
|
|
50
|
+
interface ResponseRule {
|
|
51
|
+
/** Stable identifier for UI drag-reorder */
|
|
52
|
+
id?: string;
|
|
53
|
+
/** Human-readable rule name */
|
|
54
|
+
name?: string;
|
|
55
|
+
/** Whether this rule is active (default: true) */
|
|
56
|
+
enabled?: boolean;
|
|
57
|
+
/** How to combine conditions: "and" (all match) or "or" (any match). Default: "and" */
|
|
58
|
+
logic?: "and" | "or";
|
|
59
|
+
/** Conditions to evaluate against the incoming request */
|
|
60
|
+
conditions: ResponseRuleCondition[];
|
|
61
|
+
/** Response to return when conditions match */
|
|
62
|
+
response: MockResponse;
|
|
63
|
+
}
|
|
32
64
|
/** Mock response returned by the receiver instead of the default 200 OK. */
|
|
33
65
|
interface MockResponse {
|
|
34
66
|
/** HTTP status code (100-599) */
|
|
@@ -57,6 +89,8 @@ interface Request {
|
|
|
57
89
|
headers: Record<string, string>;
|
|
58
90
|
/** Request body, if present */
|
|
59
91
|
body?: string;
|
|
92
|
+
/** Base64-encoded raw bytes, present only for non-UTF-8 payloads */
|
|
93
|
+
bodyRaw?: string;
|
|
60
94
|
/** URL query parameters */
|
|
61
95
|
queryParams: Record<string, string>;
|
|
62
96
|
/** Content-Type header value, if present */
|
|
@@ -121,6 +155,10 @@ interface CreateEndpointOptions {
|
|
|
121
155
|
expiresIn?: number | string;
|
|
122
156
|
/** Optional mock response to configure at creation time */
|
|
123
157
|
mockResponse?: MockResponse;
|
|
158
|
+
/** URL to POST a JSON summary to after each captured request */
|
|
159
|
+
notificationUrl?: string;
|
|
160
|
+
/** Ordered conditional response rules */
|
|
161
|
+
responseRules?: ResponseRule[];
|
|
124
162
|
}
|
|
125
163
|
/**
|
|
126
164
|
* Options for updating an existing endpoint.
|
|
@@ -130,6 +168,10 @@ interface UpdateEndpointOptions {
|
|
|
130
168
|
name?: string;
|
|
131
169
|
/** Mock response config, or null to clear */
|
|
132
170
|
mockResponse?: MockResponse | null;
|
|
171
|
+
/** Notification webhook URL, or null to clear */
|
|
172
|
+
notificationUrl?: string | null;
|
|
173
|
+
/** Ordered conditional response rules, or null to clear */
|
|
174
|
+
responseRules?: ResponseRule[] | null;
|
|
133
175
|
}
|
|
134
176
|
/**
|
|
135
177
|
* Options for sending a test webhook to an endpoint.
|
|
@@ -726,4 +768,4 @@ type ComparableRequest = Pick<Request, "method" | "path" | "headers" | "body"> &
|
|
|
726
768
|
*/
|
|
727
769
|
declare function diffRequests(left: ComparableRequest | SearchResult, right: ComparableRequest | SearchResult, options?: DiffRequestsOptions): DiffResult;
|
|
728
770
|
|
|
729
|
-
export {
|
|
771
|
+
export { type WaitForAllOptions as $, ApiError as A, type BodyDiff as B, type ClearRequestsOptions as C, type DiffRequestsOptions as D, type Endpoint as E, type FormBodyValue as F, type SubscribeOptions as G, type HarExport as H, type TemplateProvider as I, type JsonBodyDiff as J, type TemplateProviderInfo as K, type ListPaginatedRequestsOptions as L, type MockResponse as M, NotFoundError as N, type OperationDescription as O, type ParsedBody as P, type TextBodyDiff as Q, type Request as R, type SendTemplateOptions as S, type TeamShare as T, TimeoutError as U, type VerifySignatureOptions as V, UnauthorizedError as W, type UpdateEndpointOptions as X, type UsageInfo as Y, type ValueDifference as Z, type VerifyProvider as _, type ParsedFormBody as a, type WaitForOptions as a0, WebhookFlowBuilder as a1, type WebhookFlowResult as a2, type WebhookFlowVerifyOptions as a3, WebhooksCC as a4, WebhooksCCError as a5, diffRequests as a6, type SendOptions as b, type ResponseRule as c, type SearchResult as d, type SignatureVerificationResult as e, type ClientHooks as f, type ClientOptions as g, type CreateEndpointOptions as h, type CurlExport as i, type DiffResult as j, type ErrorHookInfo as k, type ExportRequestsOptions as l, type HeaderDiff as m, type ListRequestsOptions as n, type PaginatedResult as o, RateLimitError as p, type RateLimitMeta as q, type RequestDifferences as r, type RequestHookInfo as s, type RequestsExport as t, type ResponseHookInfo as u, type ResponseRuleCondition as v, type RetryOptions as w, type SDKDescription as x, type SearchFilters as y, type SendToOptions as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Request, P as ParsedBody, a as ParsedFormBody, S as SearchResult, V as VerifySignatureOptions,
|
|
2
|
-
export { A as ApiError, B as BodyDiff, C as ClearRequestsOptions,
|
|
1
|
+
import { R as Request, P as ParsedBody, a as ParsedFormBody, S as SendTemplateOptions, b as SendOptions, M as MockResponse, c as ResponseRule, d as SearchResult, V as VerifySignatureOptions, e as SignatureVerificationResult } from './diff-CRMlHQPX.mjs';
|
|
2
|
+
export { A as ApiError, B as BodyDiff, C as ClearRequestsOptions, f as ClientHooks, g as ClientOptions, h as CreateEndpointOptions, i as CurlExport, D as DiffRequestsOptions, j as DiffResult, E as Endpoint, k as ErrorHookInfo, l as ExportRequestsOptions, F as FormBodyValue, H as HarExport, m as HeaderDiff, J as JsonBodyDiff, L as ListPaginatedRequestsOptions, n as ListRequestsOptions, N as NotFoundError, O as OperationDescription, o as PaginatedResult, p as RateLimitError, q as RateLimitMeta, r as RequestDifferences, s as RequestHookInfo, t as RequestsExport, u as ResponseHookInfo, v as ResponseRuleCondition, w as RetryOptions, x as SDKDescription, y as SearchFilters, z as SendToOptions, G as SubscribeOptions, T as TeamShare, I as TemplateProvider, K as TemplateProviderInfo, Q as TextBodyDiff, U as TimeoutError, W as UnauthorizedError, X as UpdateEndpointOptions, Y as UsageInfo, Z as ValueDifference, _ as VerifyProvider, $ as WaitForAllOptions, a0 as WaitForOptions, a1 as WebhookFlowBuilder, a2 as WebhookFlowResult, a3 as WebhookFlowVerifyOptions, a4 as WebhooksCC, a5 as WebhooksCCError, a6 as diffRequests } from './diff-CRMlHQPX.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Safely parse a JSON request body.
|
|
@@ -140,6 +140,8 @@ interface SSEFrame {
|
|
|
140
140
|
*/
|
|
141
141
|
declare function parseSSE(stream: ReadableStream<Uint8Array>): AsyncGenerator<SSEFrame, void, undefined>;
|
|
142
142
|
|
|
143
|
+
declare const TEMPLATE_PROVIDERS: readonly ["stripe", "github", "shopify", "twilio", "slack", "paddle", "linear", "sendgrid", "clerk", "discord", "vercel", "gitlab", "standard-webhooks"];
|
|
144
|
+
declare const VERIFY_PROVIDERS: readonly ["stripe", "github", "shopify", "twilio", "slack", "paddle", "linear", "clerk", "discord", "vercel", "gitlab", "standard-webhooks"];
|
|
143
145
|
declare const TEMPLATE_METADATA: Readonly<{
|
|
144
146
|
stripe: Readonly<{
|
|
145
147
|
provider: "stripe";
|
|
@@ -241,6 +243,24 @@ declare const TEMPLATE_METADATA: Readonly<{
|
|
|
241
243
|
signatureAlgorithm: "hmac-sha256";
|
|
242
244
|
}>;
|
|
243
245
|
}>;
|
|
246
|
+
/**
|
|
247
|
+
* Build method/headers/body for a provider template webhook.
|
|
248
|
+
*/
|
|
249
|
+
declare function buildTemplateSendOptions(endpointUrl: string, options: SendTemplateOptions): Promise<SendOptions>;
|
|
250
|
+
|
|
251
|
+
declare const MOCK_RESPONSE_STATUS_MIN = 100;
|
|
252
|
+
declare const MOCK_RESPONSE_STATUS_MAX = 599;
|
|
253
|
+
declare const MOCK_RESPONSE_DELAY_MIN = 0;
|
|
254
|
+
declare const MOCK_RESPONSE_DELAY_MAX = 30000;
|
|
255
|
+
declare const MAX_RESPONSE_RULES = 50;
|
|
256
|
+
declare const MAX_CONDITIONS_PER_RULE = 10;
|
|
257
|
+
declare const MAX_CONDITION_VALUE_LEN = 4096;
|
|
258
|
+
declare const MAX_CONDITION_NAME_LEN = 256;
|
|
259
|
+
declare const MAX_CONDITION_PATH_LEN = 256;
|
|
260
|
+
declare const MAX_RULE_NAME_LEN = 200;
|
|
261
|
+
declare const MAX_GLOB_PATTERN_LEN = 500;
|
|
262
|
+
declare function validateMockResponse(mockResponse: MockResponse, fieldName?: string): void;
|
|
263
|
+
declare function validateResponseRules(rules: ResponseRule[]): void;
|
|
244
264
|
|
|
245
265
|
type VerifyableRequest = Pick<Request, "body" | "headers"> | Pick<SearchResult, "body" | "headers">;
|
|
246
266
|
/**
|
|
@@ -299,4 +319,4 @@ declare function verifyStandardWebhookSignature(body: string | undefined, header
|
|
|
299
319
|
*/
|
|
300
320
|
declare function verifySignature(request: VerifyableRequest, options: VerifySignatureOptions): Promise<SignatureVerificationResult>;
|
|
301
321
|
|
|
302
|
-
export { ParsedBody, ParsedFormBody, Request, type SSEFrame, SearchResult, SignatureVerificationResult, TEMPLATE_METADATA, VerifySignatureOptions, extractJsonField, isClerkWebhook, isDiscordWebhook, isGitHubWebhook, isGitLabWebhook, isLinearWebhook, isPaddleWebhook, isSendGridWebhook, isShopifyWebhook, isSlackWebhook, isStandardWebhook, isStripeWebhook, isTwilioWebhook, isVercelWebhook, matchAll, matchAny, matchBodyPath, matchBodySubset, matchContentType, matchHeader, matchJsonField, matchMethod, matchPath, matchQueryParam, parseBody, parseDuration, parseFormBody, parseJsonBody, parseSSE, verifyClerkSignature, verifyDiscordSignature, verifyGitHubSignature, verifyGitLabSignature, verifyLinearSignature, verifyPaddleSignature, verifyShopifySignature, verifySignature, verifySlackSignature, verifyStandardWebhookSignature, verifyStripeSignature, verifyTwilioSignature, verifyVercelSignature };
|
|
322
|
+
export { MAX_CONDITIONS_PER_RULE, MAX_CONDITION_NAME_LEN, MAX_CONDITION_PATH_LEN, MAX_CONDITION_VALUE_LEN, MAX_GLOB_PATTERN_LEN, MAX_RESPONSE_RULES, MAX_RULE_NAME_LEN, MOCK_RESPONSE_DELAY_MAX, MOCK_RESPONSE_DELAY_MIN, MOCK_RESPONSE_STATUS_MAX, MOCK_RESPONSE_STATUS_MIN, MockResponse, ParsedBody, ParsedFormBody, Request, ResponseRule, type SSEFrame, SearchResult, SendOptions, SendTemplateOptions, SignatureVerificationResult, TEMPLATE_METADATA, TEMPLATE_PROVIDERS, VERIFY_PROVIDERS, VerifySignatureOptions, buildTemplateSendOptions, extractJsonField, isClerkWebhook, isDiscordWebhook, isGitHubWebhook, isGitLabWebhook, isLinearWebhook, isPaddleWebhook, isSendGridWebhook, isShopifyWebhook, isSlackWebhook, isStandardWebhook, isStripeWebhook, isTwilioWebhook, isVercelWebhook, matchAll, matchAny, matchBodyPath, matchBodySubset, matchContentType, matchHeader, matchJsonField, matchMethod, matchPath, matchQueryParam, parseBody, parseDuration, parseFormBody, parseJsonBody, parseSSE, validateMockResponse, validateResponseRules, verifyClerkSignature, verifyDiscordSignature, verifyGitHubSignature, verifyGitLabSignature, verifyLinearSignature, verifyPaddleSignature, verifyShopifySignature, verifySignature, verifySlackSignature, verifyStandardWebhookSignature, verifyStripeSignature, verifyTwilioSignature, verifyVercelSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Request, P as ParsedBody, a as ParsedFormBody, S as SearchResult, V as VerifySignatureOptions,
|
|
2
|
-
export { A as ApiError, B as BodyDiff, C as ClearRequestsOptions,
|
|
1
|
+
import { R as Request, P as ParsedBody, a as ParsedFormBody, S as SendTemplateOptions, b as SendOptions, M as MockResponse, c as ResponseRule, d as SearchResult, V as VerifySignatureOptions, e as SignatureVerificationResult } from './diff-CRMlHQPX.js';
|
|
2
|
+
export { A as ApiError, B as BodyDiff, C as ClearRequestsOptions, f as ClientHooks, g as ClientOptions, h as CreateEndpointOptions, i as CurlExport, D as DiffRequestsOptions, j as DiffResult, E as Endpoint, k as ErrorHookInfo, l as ExportRequestsOptions, F as FormBodyValue, H as HarExport, m as HeaderDiff, J as JsonBodyDiff, L as ListPaginatedRequestsOptions, n as ListRequestsOptions, N as NotFoundError, O as OperationDescription, o as PaginatedResult, p as RateLimitError, q as RateLimitMeta, r as RequestDifferences, s as RequestHookInfo, t as RequestsExport, u as ResponseHookInfo, v as ResponseRuleCondition, w as RetryOptions, x as SDKDescription, y as SearchFilters, z as SendToOptions, G as SubscribeOptions, T as TeamShare, I as TemplateProvider, K as TemplateProviderInfo, Q as TextBodyDiff, U as TimeoutError, W as UnauthorizedError, X as UpdateEndpointOptions, Y as UsageInfo, Z as ValueDifference, _ as VerifyProvider, $ as WaitForAllOptions, a0 as WaitForOptions, a1 as WebhookFlowBuilder, a2 as WebhookFlowResult, a3 as WebhookFlowVerifyOptions, a4 as WebhooksCC, a5 as WebhooksCCError, a6 as diffRequests } from './diff-CRMlHQPX.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Safely parse a JSON request body.
|
|
@@ -140,6 +140,8 @@ interface SSEFrame {
|
|
|
140
140
|
*/
|
|
141
141
|
declare function parseSSE(stream: ReadableStream<Uint8Array>): AsyncGenerator<SSEFrame, void, undefined>;
|
|
142
142
|
|
|
143
|
+
declare const TEMPLATE_PROVIDERS: readonly ["stripe", "github", "shopify", "twilio", "slack", "paddle", "linear", "sendgrid", "clerk", "discord", "vercel", "gitlab", "standard-webhooks"];
|
|
144
|
+
declare const VERIFY_PROVIDERS: readonly ["stripe", "github", "shopify", "twilio", "slack", "paddle", "linear", "clerk", "discord", "vercel", "gitlab", "standard-webhooks"];
|
|
143
145
|
declare const TEMPLATE_METADATA: Readonly<{
|
|
144
146
|
stripe: Readonly<{
|
|
145
147
|
provider: "stripe";
|
|
@@ -241,6 +243,24 @@ declare const TEMPLATE_METADATA: Readonly<{
|
|
|
241
243
|
signatureAlgorithm: "hmac-sha256";
|
|
242
244
|
}>;
|
|
243
245
|
}>;
|
|
246
|
+
/**
|
|
247
|
+
* Build method/headers/body for a provider template webhook.
|
|
248
|
+
*/
|
|
249
|
+
declare function buildTemplateSendOptions(endpointUrl: string, options: SendTemplateOptions): Promise<SendOptions>;
|
|
250
|
+
|
|
251
|
+
declare const MOCK_RESPONSE_STATUS_MIN = 100;
|
|
252
|
+
declare const MOCK_RESPONSE_STATUS_MAX = 599;
|
|
253
|
+
declare const MOCK_RESPONSE_DELAY_MIN = 0;
|
|
254
|
+
declare const MOCK_RESPONSE_DELAY_MAX = 30000;
|
|
255
|
+
declare const MAX_RESPONSE_RULES = 50;
|
|
256
|
+
declare const MAX_CONDITIONS_PER_RULE = 10;
|
|
257
|
+
declare const MAX_CONDITION_VALUE_LEN = 4096;
|
|
258
|
+
declare const MAX_CONDITION_NAME_LEN = 256;
|
|
259
|
+
declare const MAX_CONDITION_PATH_LEN = 256;
|
|
260
|
+
declare const MAX_RULE_NAME_LEN = 200;
|
|
261
|
+
declare const MAX_GLOB_PATTERN_LEN = 500;
|
|
262
|
+
declare function validateMockResponse(mockResponse: MockResponse, fieldName?: string): void;
|
|
263
|
+
declare function validateResponseRules(rules: ResponseRule[]): void;
|
|
244
264
|
|
|
245
265
|
type VerifyableRequest = Pick<Request, "body" | "headers"> | Pick<SearchResult, "body" | "headers">;
|
|
246
266
|
/**
|
|
@@ -299,4 +319,4 @@ declare function verifyStandardWebhookSignature(body: string | undefined, header
|
|
|
299
319
|
*/
|
|
300
320
|
declare function verifySignature(request: VerifyableRequest, options: VerifySignatureOptions): Promise<SignatureVerificationResult>;
|
|
301
321
|
|
|
302
|
-
export { ParsedBody, ParsedFormBody, Request, type SSEFrame, SearchResult, SignatureVerificationResult, TEMPLATE_METADATA, VerifySignatureOptions, extractJsonField, isClerkWebhook, isDiscordWebhook, isGitHubWebhook, isGitLabWebhook, isLinearWebhook, isPaddleWebhook, isSendGridWebhook, isShopifyWebhook, isSlackWebhook, isStandardWebhook, isStripeWebhook, isTwilioWebhook, isVercelWebhook, matchAll, matchAny, matchBodyPath, matchBodySubset, matchContentType, matchHeader, matchJsonField, matchMethod, matchPath, matchQueryParam, parseBody, parseDuration, parseFormBody, parseJsonBody, parseSSE, verifyClerkSignature, verifyDiscordSignature, verifyGitHubSignature, verifyGitLabSignature, verifyLinearSignature, verifyPaddleSignature, verifyShopifySignature, verifySignature, verifySlackSignature, verifyStandardWebhookSignature, verifyStripeSignature, verifyTwilioSignature, verifyVercelSignature };
|
|
322
|
+
export { MAX_CONDITIONS_PER_RULE, MAX_CONDITION_NAME_LEN, MAX_CONDITION_PATH_LEN, MAX_CONDITION_VALUE_LEN, MAX_GLOB_PATTERN_LEN, MAX_RESPONSE_RULES, MAX_RULE_NAME_LEN, MOCK_RESPONSE_DELAY_MAX, MOCK_RESPONSE_DELAY_MIN, MOCK_RESPONSE_STATUS_MAX, MOCK_RESPONSE_STATUS_MIN, MockResponse, ParsedBody, ParsedFormBody, Request, ResponseRule, type SSEFrame, SearchResult, SendOptions, SendTemplateOptions, SignatureVerificationResult, TEMPLATE_METADATA, TEMPLATE_PROVIDERS, VERIFY_PROVIDERS, VerifySignatureOptions, buildTemplateSendOptions, extractJsonField, isClerkWebhook, isDiscordWebhook, isGitHubWebhook, isGitLabWebhook, isLinearWebhook, isPaddleWebhook, isSendGridWebhook, isShopifyWebhook, isSlackWebhook, isStandardWebhook, isStripeWebhook, isTwilioWebhook, isVercelWebhook, matchAll, matchAny, matchBodyPath, matchBodySubset, matchContentType, matchHeader, matchJsonField, matchMethod, matchPath, matchQueryParam, parseBody, parseDuration, parseFormBody, parseJsonBody, parseSSE, validateMockResponse, validateResponseRules, verifyClerkSignature, verifyDiscordSignature, verifyGitHubSignature, verifyGitLabSignature, verifyLinearSignature, verifyPaddleSignature, verifyShopifySignature, verifySignature, verifySlackSignature, verifyStandardWebhookSignature, verifyStripeSignature, verifyTwilioSignature, verifyVercelSignature };
|
package/dist/index.js
CHANGED
|
@@ -21,14 +21,28 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
ApiError: () => ApiError,
|
|
24
|
+
MAX_CONDITIONS_PER_RULE: () => MAX_CONDITIONS_PER_RULE,
|
|
25
|
+
MAX_CONDITION_NAME_LEN: () => MAX_CONDITION_NAME_LEN,
|
|
26
|
+
MAX_CONDITION_PATH_LEN: () => MAX_CONDITION_PATH_LEN,
|
|
27
|
+
MAX_CONDITION_VALUE_LEN: () => MAX_CONDITION_VALUE_LEN,
|
|
28
|
+
MAX_GLOB_PATTERN_LEN: () => MAX_GLOB_PATTERN_LEN,
|
|
29
|
+
MAX_RESPONSE_RULES: () => MAX_RESPONSE_RULES,
|
|
30
|
+
MAX_RULE_NAME_LEN: () => MAX_RULE_NAME_LEN,
|
|
31
|
+
MOCK_RESPONSE_DELAY_MAX: () => MOCK_RESPONSE_DELAY_MAX,
|
|
32
|
+
MOCK_RESPONSE_DELAY_MIN: () => MOCK_RESPONSE_DELAY_MIN,
|
|
33
|
+
MOCK_RESPONSE_STATUS_MAX: () => MOCK_RESPONSE_STATUS_MAX,
|
|
34
|
+
MOCK_RESPONSE_STATUS_MIN: () => MOCK_RESPONSE_STATUS_MIN,
|
|
24
35
|
NotFoundError: () => NotFoundError,
|
|
25
36
|
RateLimitError: () => RateLimitError,
|
|
26
37
|
TEMPLATE_METADATA: () => TEMPLATE_METADATA,
|
|
38
|
+
TEMPLATE_PROVIDERS: () => TEMPLATE_PROVIDERS,
|
|
27
39
|
TimeoutError: () => TimeoutError,
|
|
28
40
|
UnauthorizedError: () => UnauthorizedError,
|
|
41
|
+
VERIFY_PROVIDERS: () => VERIFY_PROVIDERS,
|
|
29
42
|
WebhookFlowBuilder: () => WebhookFlowBuilder,
|
|
30
43
|
WebhooksCC: () => WebhooksCC,
|
|
31
44
|
WebhooksCCError: () => WebhooksCCError,
|
|
45
|
+
buildTemplateSendOptions: () => buildTemplateSendOptions,
|
|
32
46
|
diffRequests: () => diffRequests,
|
|
33
47
|
extractJsonField: () => extractJsonField,
|
|
34
48
|
isClerkWebhook: () => isClerkWebhook,
|
|
@@ -59,6 +73,8 @@ __export(src_exports, {
|
|
|
59
73
|
parseFormBody: () => parseFormBody,
|
|
60
74
|
parseJsonBody: () => parseJsonBody,
|
|
61
75
|
parseSSE: () => parseSSE,
|
|
76
|
+
validateMockResponse: () => validateMockResponse,
|
|
77
|
+
validateResponseRules: () => validateResponseRules,
|
|
62
78
|
verifyClerkSignature: () => verifyClerkSignature,
|
|
63
79
|
verifyDiscordSignature: () => verifyDiscordSignature,
|
|
64
80
|
verifyGitHubSignature: () => verifyGitHubSignature,
|
|
@@ -273,6 +289,20 @@ var TEMPLATE_PROVIDERS = [
|
|
|
273
289
|
"gitlab",
|
|
274
290
|
"standard-webhooks"
|
|
275
291
|
];
|
|
292
|
+
var VERIFY_PROVIDERS = [
|
|
293
|
+
"stripe",
|
|
294
|
+
"github",
|
|
295
|
+
"shopify",
|
|
296
|
+
"twilio",
|
|
297
|
+
"slack",
|
|
298
|
+
"paddle",
|
|
299
|
+
"linear",
|
|
300
|
+
"clerk",
|
|
301
|
+
"discord",
|
|
302
|
+
"vercel",
|
|
303
|
+
"gitlab",
|
|
304
|
+
"standard-webhooks"
|
|
305
|
+
];
|
|
276
306
|
var TEMPLATE_METADATA = Object.freeze({
|
|
277
307
|
stripe: Object.freeze({
|
|
278
308
|
provider: "stripe",
|
|
@@ -2186,6 +2216,122 @@ var WebhookFlowBuilder = class {
|
|
|
2186
2216
|
}
|
|
2187
2217
|
};
|
|
2188
2218
|
|
|
2219
|
+
// src/validation.ts
|
|
2220
|
+
var MOCK_RESPONSE_STATUS_MIN = 100;
|
|
2221
|
+
var MOCK_RESPONSE_STATUS_MAX = 599;
|
|
2222
|
+
var MOCK_RESPONSE_DELAY_MIN = 0;
|
|
2223
|
+
var MOCK_RESPONSE_DELAY_MAX = 3e4;
|
|
2224
|
+
var MAX_RESPONSE_RULES = 50;
|
|
2225
|
+
var MAX_CONDITIONS_PER_RULE = 10;
|
|
2226
|
+
var VALID_CONDITION_FIELDS = /* @__PURE__ */ new Set([
|
|
2227
|
+
"method",
|
|
2228
|
+
"path",
|
|
2229
|
+
"header",
|
|
2230
|
+
"body_contains",
|
|
2231
|
+
"body_path",
|
|
2232
|
+
"query"
|
|
2233
|
+
]);
|
|
2234
|
+
var VALID_CONDITION_OPS = /* @__PURE__ */ new Set(["eq", "contains", "starts_with", "matches", "exists"]);
|
|
2235
|
+
var VALID_OPS_BY_FIELD = {
|
|
2236
|
+
method: /* @__PURE__ */ new Set(["eq"]),
|
|
2237
|
+
path: /* @__PURE__ */ new Set(["eq", "contains", "starts_with", "matches"]),
|
|
2238
|
+
header: /* @__PURE__ */ new Set(["exists", "eq", "contains"]),
|
|
2239
|
+
body_contains: /* @__PURE__ */ new Set(["contains"]),
|
|
2240
|
+
body_path: /* @__PURE__ */ new Set(["exists", "eq", "contains"]),
|
|
2241
|
+
query: /* @__PURE__ */ new Set(["exists", "eq"])
|
|
2242
|
+
};
|
|
2243
|
+
var MAX_CONDITION_VALUE_LEN = 4096;
|
|
2244
|
+
var MAX_CONDITION_NAME_LEN = 256;
|
|
2245
|
+
var MAX_CONDITION_PATH_LEN = 256;
|
|
2246
|
+
var MAX_RULE_NAME_LEN = 200;
|
|
2247
|
+
var MAX_GLOB_PATTERN_LEN = 500;
|
|
2248
|
+
function validateMockResponse(mockResponse, fieldName = "mock response") {
|
|
2249
|
+
const { status, body, headers, delay } = mockResponse;
|
|
2250
|
+
if (!Number.isInteger(status) || status < MOCK_RESPONSE_STATUS_MIN || status > MOCK_RESPONSE_STATUS_MAX) {
|
|
2251
|
+
throw new Error(
|
|
2252
|
+
`Invalid ${fieldName} status: ${status}. Must be an integer ${MOCK_RESPONSE_STATUS_MIN}-${MOCK_RESPONSE_STATUS_MAX}.`
|
|
2253
|
+
);
|
|
2254
|
+
}
|
|
2255
|
+
if (body !== void 0 && typeof body !== "string") {
|
|
2256
|
+
throw new Error(`Invalid ${fieldName} body: must be a string.`);
|
|
2257
|
+
}
|
|
2258
|
+
if (headers !== void 0) {
|
|
2259
|
+
if (typeof headers !== "object" || headers === null || Array.isArray(headers)) {
|
|
2260
|
+
throw new Error(`Invalid ${fieldName} headers: must be a Record<string, string>.`);
|
|
2261
|
+
}
|
|
2262
|
+
for (const val of Object.values(headers)) {
|
|
2263
|
+
if (typeof val !== "string") {
|
|
2264
|
+
throw new Error(`Invalid ${fieldName} headers: all values must be strings.`);
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
if (delay !== void 0 && (!Number.isInteger(delay) || delay < MOCK_RESPONSE_DELAY_MIN || delay > MOCK_RESPONSE_DELAY_MAX)) {
|
|
2269
|
+
throw new Error(
|
|
2270
|
+
`Invalid ${fieldName} delay: ${delay}. Must be an integer ${MOCK_RESPONSE_DELAY_MIN}-${MOCK_RESPONSE_DELAY_MAX}.`
|
|
2271
|
+
);
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
function validateResponseRules(rules) {
|
|
2275
|
+
if (!Array.isArray(rules)) {
|
|
2276
|
+
throw new Error("responseRules must be an array");
|
|
2277
|
+
}
|
|
2278
|
+
if (rules.length > MAX_RESPONSE_RULES) {
|
|
2279
|
+
throw new Error(`responseRules: max ${MAX_RESPONSE_RULES} rules allowed`);
|
|
2280
|
+
}
|
|
2281
|
+
for (let i = 0; i < rules.length; i++) {
|
|
2282
|
+
const rule = rules[i];
|
|
2283
|
+
const prefix = `responseRules[${i}]`;
|
|
2284
|
+
if (rule.name !== void 0 && (typeof rule.name !== "string" || rule.name.length > MAX_RULE_NAME_LEN)) {
|
|
2285
|
+
throw new Error(`${prefix}: name must be a string (max ${MAX_RULE_NAME_LEN} chars)`);
|
|
2286
|
+
}
|
|
2287
|
+
if (!Array.isArray(rule.conditions) || rule.conditions.length === 0) {
|
|
2288
|
+
throw new Error(`${prefix}: conditions must be a non-empty array`);
|
|
2289
|
+
}
|
|
2290
|
+
if (rule.conditions.length > MAX_CONDITIONS_PER_RULE) {
|
|
2291
|
+
throw new Error(`${prefix}: max ${MAX_CONDITIONS_PER_RULE} conditions per rule`);
|
|
2292
|
+
}
|
|
2293
|
+
if (rule.logic !== void 0 && rule.logic !== "and" && rule.logic !== "or") {
|
|
2294
|
+
throw new Error(`${prefix}: logic must be "and" or "or"`);
|
|
2295
|
+
}
|
|
2296
|
+
for (let j = 0; j < rule.conditions.length; j++) {
|
|
2297
|
+
const c = rule.conditions[j];
|
|
2298
|
+
const cp = `${prefix}.conditions[${j}]`;
|
|
2299
|
+
if (!VALID_CONDITION_FIELDS.has(c.field)) {
|
|
2300
|
+
throw new Error(`${cp}: invalid field "${c.field}"`);
|
|
2301
|
+
}
|
|
2302
|
+
if (!VALID_CONDITION_OPS.has(c.op)) {
|
|
2303
|
+
throw new Error(`${cp}: invalid op "${c.op}"`);
|
|
2304
|
+
}
|
|
2305
|
+
const fieldOps = VALID_OPS_BY_FIELD[c.field];
|
|
2306
|
+
if (fieldOps && !fieldOps.has(c.op)) {
|
|
2307
|
+
throw new Error(`${cp}: op "${c.op}" is not valid for field "${c.field}"`);
|
|
2308
|
+
}
|
|
2309
|
+
if (c.value !== void 0 && typeof c.value === "string" && c.value.length > MAX_CONDITION_VALUE_LEN) {
|
|
2310
|
+
throw new Error(`${cp}: value too long (max ${MAX_CONDITION_VALUE_LEN} chars)`);
|
|
2311
|
+
}
|
|
2312
|
+
if (c.name !== void 0 && typeof c.name === "string" && c.name.length > MAX_CONDITION_NAME_LEN) {
|
|
2313
|
+
throw new Error(`${cp}: name too long (max ${MAX_CONDITION_NAME_LEN} chars)`);
|
|
2314
|
+
}
|
|
2315
|
+
if (c.path !== void 0 && typeof c.path === "string" && c.path.length > MAX_CONDITION_PATH_LEN) {
|
|
2316
|
+
throw new Error(`${cp}: path too long (max ${MAX_CONDITION_PATH_LEN} chars)`);
|
|
2317
|
+
}
|
|
2318
|
+
if ((c.field === "header" || c.field === "query") && (!c.name || c.name.length === 0)) {
|
|
2319
|
+
throw new Error(`${cp}: name is required for ${c.field} conditions`);
|
|
2320
|
+
}
|
|
2321
|
+
if (c.field === "body_path" && (!c.path || c.path.length === 0)) {
|
|
2322
|
+
throw new Error(`${cp}: path is required for body_path conditions`);
|
|
2323
|
+
}
|
|
2324
|
+
if (c.op !== "exists" && (c.value === void 0 || c.value === null)) {
|
|
2325
|
+
throw new Error(`${cp}: value is required when op is "${c.op}"`);
|
|
2326
|
+
}
|
|
2327
|
+
if (c.op === "matches" && c.value && c.value.length > MAX_GLOB_PATTERN_LEN) {
|
|
2328
|
+
throw new Error(`${cp}: matches pattern too long (max ${MAX_GLOB_PATTERN_LEN} chars)`);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
validateMockResponse(rule.response, `${prefix}.response`);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2189
2335
|
// src/client.ts
|
|
2190
2336
|
var DEFAULT_BASE_URL = "https://webhooks.cc";
|
|
2191
2337
|
var DEFAULT_WEBHOOK_URL = "https://go.webhooks.cc";
|
|
@@ -2193,7 +2339,7 @@ var DEFAULT_TIMEOUT = 3e4;
|
|
|
2193
2339
|
var DEFAULT_RETRY_ATTEMPTS = 1;
|
|
2194
2340
|
var DEFAULT_RETRY_BACKOFF_MS = 1e3;
|
|
2195
2341
|
var DEFAULT_RETRY_STATUSES = [429, 500, 502, 503, 504];
|
|
2196
|
-
var SDK_VERSION = "0.
|
|
2342
|
+
var SDK_VERSION = true ? "1.3.0" : "0.0.0-dev";
|
|
2197
2343
|
var WAIT_FOR_LOOKBACK_MS = 5 * 60 * 1e3;
|
|
2198
2344
|
var DEFAULT_EXPORT_PAGE_SIZE = 100;
|
|
2199
2345
|
var PROVIDER_PARAM_DESCRIPTION = TEMPLATE_PROVIDERS.map((provider) => `"${provider}"`).join("|");
|
|
@@ -2452,15 +2598,6 @@ async function collectMatchingRequests(fetchRequests, options) {
|
|
|
2452
2598
|
}
|
|
2453
2599
|
throw new TimeoutError(timeout);
|
|
2454
2600
|
}
|
|
2455
|
-
function validateMockResponse(mockResponse, fieldName) {
|
|
2456
|
-
const { status, delay } = mockResponse;
|
|
2457
|
-
if (!Number.isInteger(status) || status < 100 || status > 599) {
|
|
2458
|
-
throw new Error(`Invalid ${fieldName} status: ${status}. Must be an integer 100-599.`);
|
|
2459
|
-
}
|
|
2460
|
-
if (delay !== void 0 && (!Number.isInteger(delay) || delay < 0 || delay > 3e4)) {
|
|
2461
|
-
throw new Error(`Invalid ${fieldName} delay: ${delay}. Must be an integer 0-30000.`);
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
2601
|
var WebhooksCC = class {
|
|
2465
2602
|
constructor(options) {
|
|
2466
2603
|
this.endpoints = {
|
|
@@ -2468,6 +2605,9 @@ var WebhooksCC = class {
|
|
|
2468
2605
|
if (options.mockResponse) {
|
|
2469
2606
|
validateMockResponse(options.mockResponse, "mock response");
|
|
2470
2607
|
}
|
|
2608
|
+
if (options.responseRules) {
|
|
2609
|
+
validateResponseRules(options.responseRules);
|
|
2610
|
+
}
|
|
2471
2611
|
const body = {};
|
|
2472
2612
|
if (options.name !== void 0) {
|
|
2473
2613
|
body.name = options.name;
|
|
@@ -2475,6 +2615,12 @@ var WebhooksCC = class {
|
|
|
2475
2615
|
if (options.mockResponse !== void 0) {
|
|
2476
2616
|
body.mockResponse = options.mockResponse;
|
|
2477
2617
|
}
|
|
2618
|
+
if (options.notificationUrl !== void 0) {
|
|
2619
|
+
body.notificationUrl = options.notificationUrl;
|
|
2620
|
+
}
|
|
2621
|
+
if (options.responseRules !== void 0) {
|
|
2622
|
+
body.responseRules = options.responseRules;
|
|
2623
|
+
}
|
|
2478
2624
|
const isEphemeral = options.ephemeral === true || options.expiresIn !== void 0;
|
|
2479
2625
|
if (isEphemeral) {
|
|
2480
2626
|
body.isEphemeral = true;
|
|
@@ -2501,9 +2647,12 @@ var WebhooksCC = class {
|
|
|
2501
2647
|
},
|
|
2502
2648
|
update: async (slug, options) => {
|
|
2503
2649
|
validatePathSegment(slug, "slug");
|
|
2504
|
-
if (options.mockResponse
|
|
2650
|
+
if (options.mockResponse != null) {
|
|
2505
2651
|
validateMockResponse(options.mockResponse, "mock response");
|
|
2506
2652
|
}
|
|
2653
|
+
if (options.responseRules != null) {
|
|
2654
|
+
validateResponseRules(options.responseRules);
|
|
2655
|
+
}
|
|
2507
2656
|
return this.request("PATCH", `/endpoints/${slug}`, options);
|
|
2508
2657
|
},
|
|
2509
2658
|
delete: async (slug) => {
|
|
@@ -2813,7 +2962,18 @@ var WebhooksCC = class {
|
|
|
2813
2962
|
}
|
|
2814
2963
|
}
|
|
2815
2964
|
const upperMethod = captured.method.toUpperCase();
|
|
2816
|
-
|
|
2965
|
+
let body;
|
|
2966
|
+
if (upperMethod === "GET" || upperMethod === "HEAD") {
|
|
2967
|
+
body = void 0;
|
|
2968
|
+
} else if (captured.bodyRaw) {
|
|
2969
|
+
try {
|
|
2970
|
+
body = Uint8Array.from(atob(captured.bodyRaw), (c) => c.charCodeAt(0));
|
|
2971
|
+
} catch {
|
|
2972
|
+
body = captured.body ?? void 0;
|
|
2973
|
+
}
|
|
2974
|
+
} else {
|
|
2975
|
+
body = captured.body ?? void 0;
|
|
2976
|
+
}
|
|
2817
2977
|
return fetch(targetUrl, {
|
|
2818
2978
|
method: captured.method,
|
|
2819
2979
|
headers,
|
|
@@ -3099,7 +3259,9 @@ var WebhooksCC = class {
|
|
|
3099
3259
|
name: "string?",
|
|
3100
3260
|
ephemeral: "boolean?",
|
|
3101
3261
|
expiresIn: "number|string?",
|
|
3102
|
-
mockResponse: "object?"
|
|
3262
|
+
mockResponse: "object?",
|
|
3263
|
+
responseRules: "ResponseRule[]? \u2014 ordered conditional rules (first match wins, max 50). Each rule has conditions (field/op/value) and a response.",
|
|
3264
|
+
notificationUrl: "string?"
|
|
3103
3265
|
}
|
|
3104
3266
|
},
|
|
3105
3267
|
list: {
|
|
@@ -3112,7 +3274,13 @@ var WebhooksCC = class {
|
|
|
3112
3274
|
},
|
|
3113
3275
|
update: {
|
|
3114
3276
|
description: "Update endpoint settings",
|
|
3115
|
-
params: {
|
|
3277
|
+
params: {
|
|
3278
|
+
slug: "string",
|
|
3279
|
+
name: "string?",
|
|
3280
|
+
mockResponse: "object? \u2014 default response when no rule matches",
|
|
3281
|
+
responseRules: "ResponseRule[]|null? \u2014 conditional rules (first match wins), or null to clear",
|
|
3282
|
+
notificationUrl: "string?"
|
|
3283
|
+
}
|
|
3116
3284
|
},
|
|
3117
3285
|
delete: {
|
|
3118
3286
|
description: "Delete endpoint and its requests",
|
|
@@ -3701,14 +3869,28 @@ function diffRequests(left, right, options = {}) {
|
|
|
3701
3869
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3702
3870
|
0 && (module.exports = {
|
|
3703
3871
|
ApiError,
|
|
3872
|
+
MAX_CONDITIONS_PER_RULE,
|
|
3873
|
+
MAX_CONDITION_NAME_LEN,
|
|
3874
|
+
MAX_CONDITION_PATH_LEN,
|
|
3875
|
+
MAX_CONDITION_VALUE_LEN,
|
|
3876
|
+
MAX_GLOB_PATTERN_LEN,
|
|
3877
|
+
MAX_RESPONSE_RULES,
|
|
3878
|
+
MAX_RULE_NAME_LEN,
|
|
3879
|
+
MOCK_RESPONSE_DELAY_MAX,
|
|
3880
|
+
MOCK_RESPONSE_DELAY_MIN,
|
|
3881
|
+
MOCK_RESPONSE_STATUS_MAX,
|
|
3882
|
+
MOCK_RESPONSE_STATUS_MIN,
|
|
3704
3883
|
NotFoundError,
|
|
3705
3884
|
RateLimitError,
|
|
3706
3885
|
TEMPLATE_METADATA,
|
|
3886
|
+
TEMPLATE_PROVIDERS,
|
|
3707
3887
|
TimeoutError,
|
|
3708
3888
|
UnauthorizedError,
|
|
3889
|
+
VERIFY_PROVIDERS,
|
|
3709
3890
|
WebhookFlowBuilder,
|
|
3710
3891
|
WebhooksCC,
|
|
3711
3892
|
WebhooksCCError,
|
|
3893
|
+
buildTemplateSendOptions,
|
|
3712
3894
|
diffRequests,
|
|
3713
3895
|
extractJsonField,
|
|
3714
3896
|
isClerkWebhook,
|
|
@@ -3739,6 +3921,8 @@ function diffRequests(left, right, options = {}) {
|
|
|
3739
3921
|
parseFormBody,
|
|
3740
3922
|
parseJsonBody,
|
|
3741
3923
|
parseSSE,
|
|
3924
|
+
validateMockResponse,
|
|
3925
|
+
validateResponseRules,
|
|
3742
3926
|
verifyClerkSignature,
|
|
3743
3927
|
verifyDiscordSignature,
|
|
3744
3928
|
verifyGitHubSignature,
|
package/dist/index.mjs
CHANGED
|
@@ -127,6 +127,20 @@ var TEMPLATE_PROVIDERS = [
|
|
|
127
127
|
"gitlab",
|
|
128
128
|
"standard-webhooks"
|
|
129
129
|
];
|
|
130
|
+
var VERIFY_PROVIDERS = [
|
|
131
|
+
"stripe",
|
|
132
|
+
"github",
|
|
133
|
+
"shopify",
|
|
134
|
+
"twilio",
|
|
135
|
+
"slack",
|
|
136
|
+
"paddle",
|
|
137
|
+
"linear",
|
|
138
|
+
"clerk",
|
|
139
|
+
"discord",
|
|
140
|
+
"vercel",
|
|
141
|
+
"gitlab",
|
|
142
|
+
"standard-webhooks"
|
|
143
|
+
];
|
|
130
144
|
var TEMPLATE_METADATA = Object.freeze({
|
|
131
145
|
stripe: Object.freeze({
|
|
132
146
|
provider: "stripe",
|
|
@@ -2040,6 +2054,122 @@ var WebhookFlowBuilder = class {
|
|
|
2040
2054
|
}
|
|
2041
2055
|
};
|
|
2042
2056
|
|
|
2057
|
+
// src/validation.ts
|
|
2058
|
+
var MOCK_RESPONSE_STATUS_MIN = 100;
|
|
2059
|
+
var MOCK_RESPONSE_STATUS_MAX = 599;
|
|
2060
|
+
var MOCK_RESPONSE_DELAY_MIN = 0;
|
|
2061
|
+
var MOCK_RESPONSE_DELAY_MAX = 3e4;
|
|
2062
|
+
var MAX_RESPONSE_RULES = 50;
|
|
2063
|
+
var MAX_CONDITIONS_PER_RULE = 10;
|
|
2064
|
+
var VALID_CONDITION_FIELDS = /* @__PURE__ */ new Set([
|
|
2065
|
+
"method",
|
|
2066
|
+
"path",
|
|
2067
|
+
"header",
|
|
2068
|
+
"body_contains",
|
|
2069
|
+
"body_path",
|
|
2070
|
+
"query"
|
|
2071
|
+
]);
|
|
2072
|
+
var VALID_CONDITION_OPS = /* @__PURE__ */ new Set(["eq", "contains", "starts_with", "matches", "exists"]);
|
|
2073
|
+
var VALID_OPS_BY_FIELD = {
|
|
2074
|
+
method: /* @__PURE__ */ new Set(["eq"]),
|
|
2075
|
+
path: /* @__PURE__ */ new Set(["eq", "contains", "starts_with", "matches"]),
|
|
2076
|
+
header: /* @__PURE__ */ new Set(["exists", "eq", "contains"]),
|
|
2077
|
+
body_contains: /* @__PURE__ */ new Set(["contains"]),
|
|
2078
|
+
body_path: /* @__PURE__ */ new Set(["exists", "eq", "contains"]),
|
|
2079
|
+
query: /* @__PURE__ */ new Set(["exists", "eq"])
|
|
2080
|
+
};
|
|
2081
|
+
var MAX_CONDITION_VALUE_LEN = 4096;
|
|
2082
|
+
var MAX_CONDITION_NAME_LEN = 256;
|
|
2083
|
+
var MAX_CONDITION_PATH_LEN = 256;
|
|
2084
|
+
var MAX_RULE_NAME_LEN = 200;
|
|
2085
|
+
var MAX_GLOB_PATTERN_LEN = 500;
|
|
2086
|
+
function validateMockResponse(mockResponse, fieldName = "mock response") {
|
|
2087
|
+
const { status, body, headers, delay } = mockResponse;
|
|
2088
|
+
if (!Number.isInteger(status) || status < MOCK_RESPONSE_STATUS_MIN || status > MOCK_RESPONSE_STATUS_MAX) {
|
|
2089
|
+
throw new Error(
|
|
2090
|
+
`Invalid ${fieldName} status: ${status}. Must be an integer ${MOCK_RESPONSE_STATUS_MIN}-${MOCK_RESPONSE_STATUS_MAX}.`
|
|
2091
|
+
);
|
|
2092
|
+
}
|
|
2093
|
+
if (body !== void 0 && typeof body !== "string") {
|
|
2094
|
+
throw new Error(`Invalid ${fieldName} body: must be a string.`);
|
|
2095
|
+
}
|
|
2096
|
+
if (headers !== void 0) {
|
|
2097
|
+
if (typeof headers !== "object" || headers === null || Array.isArray(headers)) {
|
|
2098
|
+
throw new Error(`Invalid ${fieldName} headers: must be a Record<string, string>.`);
|
|
2099
|
+
}
|
|
2100
|
+
for (const val of Object.values(headers)) {
|
|
2101
|
+
if (typeof val !== "string") {
|
|
2102
|
+
throw new Error(`Invalid ${fieldName} headers: all values must be strings.`);
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
if (delay !== void 0 && (!Number.isInteger(delay) || delay < MOCK_RESPONSE_DELAY_MIN || delay > MOCK_RESPONSE_DELAY_MAX)) {
|
|
2107
|
+
throw new Error(
|
|
2108
|
+
`Invalid ${fieldName} delay: ${delay}. Must be an integer ${MOCK_RESPONSE_DELAY_MIN}-${MOCK_RESPONSE_DELAY_MAX}.`
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
function validateResponseRules(rules) {
|
|
2113
|
+
if (!Array.isArray(rules)) {
|
|
2114
|
+
throw new Error("responseRules must be an array");
|
|
2115
|
+
}
|
|
2116
|
+
if (rules.length > MAX_RESPONSE_RULES) {
|
|
2117
|
+
throw new Error(`responseRules: max ${MAX_RESPONSE_RULES} rules allowed`);
|
|
2118
|
+
}
|
|
2119
|
+
for (let i = 0; i < rules.length; i++) {
|
|
2120
|
+
const rule = rules[i];
|
|
2121
|
+
const prefix = `responseRules[${i}]`;
|
|
2122
|
+
if (rule.name !== void 0 && (typeof rule.name !== "string" || rule.name.length > MAX_RULE_NAME_LEN)) {
|
|
2123
|
+
throw new Error(`${prefix}: name must be a string (max ${MAX_RULE_NAME_LEN} chars)`);
|
|
2124
|
+
}
|
|
2125
|
+
if (!Array.isArray(rule.conditions) || rule.conditions.length === 0) {
|
|
2126
|
+
throw new Error(`${prefix}: conditions must be a non-empty array`);
|
|
2127
|
+
}
|
|
2128
|
+
if (rule.conditions.length > MAX_CONDITIONS_PER_RULE) {
|
|
2129
|
+
throw new Error(`${prefix}: max ${MAX_CONDITIONS_PER_RULE} conditions per rule`);
|
|
2130
|
+
}
|
|
2131
|
+
if (rule.logic !== void 0 && rule.logic !== "and" && rule.logic !== "or") {
|
|
2132
|
+
throw new Error(`${prefix}: logic must be "and" or "or"`);
|
|
2133
|
+
}
|
|
2134
|
+
for (let j = 0; j < rule.conditions.length; j++) {
|
|
2135
|
+
const c = rule.conditions[j];
|
|
2136
|
+
const cp = `${prefix}.conditions[${j}]`;
|
|
2137
|
+
if (!VALID_CONDITION_FIELDS.has(c.field)) {
|
|
2138
|
+
throw new Error(`${cp}: invalid field "${c.field}"`);
|
|
2139
|
+
}
|
|
2140
|
+
if (!VALID_CONDITION_OPS.has(c.op)) {
|
|
2141
|
+
throw new Error(`${cp}: invalid op "${c.op}"`);
|
|
2142
|
+
}
|
|
2143
|
+
const fieldOps = VALID_OPS_BY_FIELD[c.field];
|
|
2144
|
+
if (fieldOps && !fieldOps.has(c.op)) {
|
|
2145
|
+
throw new Error(`${cp}: op "${c.op}" is not valid for field "${c.field}"`);
|
|
2146
|
+
}
|
|
2147
|
+
if (c.value !== void 0 && typeof c.value === "string" && c.value.length > MAX_CONDITION_VALUE_LEN) {
|
|
2148
|
+
throw new Error(`${cp}: value too long (max ${MAX_CONDITION_VALUE_LEN} chars)`);
|
|
2149
|
+
}
|
|
2150
|
+
if (c.name !== void 0 && typeof c.name === "string" && c.name.length > MAX_CONDITION_NAME_LEN) {
|
|
2151
|
+
throw new Error(`${cp}: name too long (max ${MAX_CONDITION_NAME_LEN} chars)`);
|
|
2152
|
+
}
|
|
2153
|
+
if (c.path !== void 0 && typeof c.path === "string" && c.path.length > MAX_CONDITION_PATH_LEN) {
|
|
2154
|
+
throw new Error(`${cp}: path too long (max ${MAX_CONDITION_PATH_LEN} chars)`);
|
|
2155
|
+
}
|
|
2156
|
+
if ((c.field === "header" || c.field === "query") && (!c.name || c.name.length === 0)) {
|
|
2157
|
+
throw new Error(`${cp}: name is required for ${c.field} conditions`);
|
|
2158
|
+
}
|
|
2159
|
+
if (c.field === "body_path" && (!c.path || c.path.length === 0)) {
|
|
2160
|
+
throw new Error(`${cp}: path is required for body_path conditions`);
|
|
2161
|
+
}
|
|
2162
|
+
if (c.op !== "exists" && (c.value === void 0 || c.value === null)) {
|
|
2163
|
+
throw new Error(`${cp}: value is required when op is "${c.op}"`);
|
|
2164
|
+
}
|
|
2165
|
+
if (c.op === "matches" && c.value && c.value.length > MAX_GLOB_PATTERN_LEN) {
|
|
2166
|
+
throw new Error(`${cp}: matches pattern too long (max ${MAX_GLOB_PATTERN_LEN} chars)`);
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
validateMockResponse(rule.response, `${prefix}.response`);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2043
2173
|
// src/client.ts
|
|
2044
2174
|
var DEFAULT_BASE_URL = "https://webhooks.cc";
|
|
2045
2175
|
var DEFAULT_WEBHOOK_URL = "https://go.webhooks.cc";
|
|
@@ -2047,7 +2177,7 @@ var DEFAULT_TIMEOUT = 3e4;
|
|
|
2047
2177
|
var DEFAULT_RETRY_ATTEMPTS = 1;
|
|
2048
2178
|
var DEFAULT_RETRY_BACKOFF_MS = 1e3;
|
|
2049
2179
|
var DEFAULT_RETRY_STATUSES = [429, 500, 502, 503, 504];
|
|
2050
|
-
var SDK_VERSION = "0.
|
|
2180
|
+
var SDK_VERSION = true ? "1.3.0" : "0.0.0-dev";
|
|
2051
2181
|
var WAIT_FOR_LOOKBACK_MS = 5 * 60 * 1e3;
|
|
2052
2182
|
var DEFAULT_EXPORT_PAGE_SIZE = 100;
|
|
2053
2183
|
var PROVIDER_PARAM_DESCRIPTION = TEMPLATE_PROVIDERS.map((provider) => `"${provider}"`).join("|");
|
|
@@ -2306,15 +2436,6 @@ async function collectMatchingRequests(fetchRequests, options) {
|
|
|
2306
2436
|
}
|
|
2307
2437
|
throw new TimeoutError(timeout);
|
|
2308
2438
|
}
|
|
2309
|
-
function validateMockResponse(mockResponse, fieldName) {
|
|
2310
|
-
const { status, delay } = mockResponse;
|
|
2311
|
-
if (!Number.isInteger(status) || status < 100 || status > 599) {
|
|
2312
|
-
throw new Error(`Invalid ${fieldName} status: ${status}. Must be an integer 100-599.`);
|
|
2313
|
-
}
|
|
2314
|
-
if (delay !== void 0 && (!Number.isInteger(delay) || delay < 0 || delay > 3e4)) {
|
|
2315
|
-
throw new Error(`Invalid ${fieldName} delay: ${delay}. Must be an integer 0-30000.`);
|
|
2316
|
-
}
|
|
2317
|
-
}
|
|
2318
2439
|
var WebhooksCC = class {
|
|
2319
2440
|
constructor(options) {
|
|
2320
2441
|
this.endpoints = {
|
|
@@ -2322,6 +2443,9 @@ var WebhooksCC = class {
|
|
|
2322
2443
|
if (options.mockResponse) {
|
|
2323
2444
|
validateMockResponse(options.mockResponse, "mock response");
|
|
2324
2445
|
}
|
|
2446
|
+
if (options.responseRules) {
|
|
2447
|
+
validateResponseRules(options.responseRules);
|
|
2448
|
+
}
|
|
2325
2449
|
const body = {};
|
|
2326
2450
|
if (options.name !== void 0) {
|
|
2327
2451
|
body.name = options.name;
|
|
@@ -2329,6 +2453,12 @@ var WebhooksCC = class {
|
|
|
2329
2453
|
if (options.mockResponse !== void 0) {
|
|
2330
2454
|
body.mockResponse = options.mockResponse;
|
|
2331
2455
|
}
|
|
2456
|
+
if (options.notificationUrl !== void 0) {
|
|
2457
|
+
body.notificationUrl = options.notificationUrl;
|
|
2458
|
+
}
|
|
2459
|
+
if (options.responseRules !== void 0) {
|
|
2460
|
+
body.responseRules = options.responseRules;
|
|
2461
|
+
}
|
|
2332
2462
|
const isEphemeral = options.ephemeral === true || options.expiresIn !== void 0;
|
|
2333
2463
|
if (isEphemeral) {
|
|
2334
2464
|
body.isEphemeral = true;
|
|
@@ -2355,9 +2485,12 @@ var WebhooksCC = class {
|
|
|
2355
2485
|
},
|
|
2356
2486
|
update: async (slug, options) => {
|
|
2357
2487
|
validatePathSegment(slug, "slug");
|
|
2358
|
-
if (options.mockResponse
|
|
2488
|
+
if (options.mockResponse != null) {
|
|
2359
2489
|
validateMockResponse(options.mockResponse, "mock response");
|
|
2360
2490
|
}
|
|
2491
|
+
if (options.responseRules != null) {
|
|
2492
|
+
validateResponseRules(options.responseRules);
|
|
2493
|
+
}
|
|
2361
2494
|
return this.request("PATCH", `/endpoints/${slug}`, options);
|
|
2362
2495
|
},
|
|
2363
2496
|
delete: async (slug) => {
|
|
@@ -2667,7 +2800,18 @@ var WebhooksCC = class {
|
|
|
2667
2800
|
}
|
|
2668
2801
|
}
|
|
2669
2802
|
const upperMethod = captured.method.toUpperCase();
|
|
2670
|
-
|
|
2803
|
+
let body;
|
|
2804
|
+
if (upperMethod === "GET" || upperMethod === "HEAD") {
|
|
2805
|
+
body = void 0;
|
|
2806
|
+
} else if (captured.bodyRaw) {
|
|
2807
|
+
try {
|
|
2808
|
+
body = Uint8Array.from(atob(captured.bodyRaw), (c) => c.charCodeAt(0));
|
|
2809
|
+
} catch {
|
|
2810
|
+
body = captured.body ?? void 0;
|
|
2811
|
+
}
|
|
2812
|
+
} else {
|
|
2813
|
+
body = captured.body ?? void 0;
|
|
2814
|
+
}
|
|
2671
2815
|
return fetch(targetUrl, {
|
|
2672
2816
|
method: captured.method,
|
|
2673
2817
|
headers,
|
|
@@ -2953,7 +3097,9 @@ var WebhooksCC = class {
|
|
|
2953
3097
|
name: "string?",
|
|
2954
3098
|
ephemeral: "boolean?",
|
|
2955
3099
|
expiresIn: "number|string?",
|
|
2956
|
-
mockResponse: "object?"
|
|
3100
|
+
mockResponse: "object?",
|
|
3101
|
+
responseRules: "ResponseRule[]? \u2014 ordered conditional rules (first match wins, max 50). Each rule has conditions (field/op/value) and a response.",
|
|
3102
|
+
notificationUrl: "string?"
|
|
2957
3103
|
}
|
|
2958
3104
|
},
|
|
2959
3105
|
list: {
|
|
@@ -2966,7 +3112,13 @@ var WebhooksCC = class {
|
|
|
2966
3112
|
},
|
|
2967
3113
|
update: {
|
|
2968
3114
|
description: "Update endpoint settings",
|
|
2969
|
-
params: {
|
|
3115
|
+
params: {
|
|
3116
|
+
slug: "string",
|
|
3117
|
+
name: "string?",
|
|
3118
|
+
mockResponse: "object? \u2014 default response when no rule matches",
|
|
3119
|
+
responseRules: "ResponseRule[]|null? \u2014 conditional rules (first match wins), or null to clear",
|
|
3120
|
+
notificationUrl: "string?"
|
|
3121
|
+
}
|
|
2970
3122
|
},
|
|
2971
3123
|
delete: {
|
|
2972
3124
|
description: "Delete endpoint and its requests",
|
|
@@ -3401,14 +3553,28 @@ function matchAny(first, ...rest) {
|
|
|
3401
3553
|
}
|
|
3402
3554
|
export {
|
|
3403
3555
|
ApiError,
|
|
3556
|
+
MAX_CONDITIONS_PER_RULE,
|
|
3557
|
+
MAX_CONDITION_NAME_LEN,
|
|
3558
|
+
MAX_CONDITION_PATH_LEN,
|
|
3559
|
+
MAX_CONDITION_VALUE_LEN,
|
|
3560
|
+
MAX_GLOB_PATTERN_LEN,
|
|
3561
|
+
MAX_RESPONSE_RULES,
|
|
3562
|
+
MAX_RULE_NAME_LEN,
|
|
3563
|
+
MOCK_RESPONSE_DELAY_MAX,
|
|
3564
|
+
MOCK_RESPONSE_DELAY_MIN,
|
|
3565
|
+
MOCK_RESPONSE_STATUS_MAX,
|
|
3566
|
+
MOCK_RESPONSE_STATUS_MIN,
|
|
3404
3567
|
NotFoundError,
|
|
3405
3568
|
RateLimitError,
|
|
3406
3569
|
TEMPLATE_METADATA,
|
|
3570
|
+
TEMPLATE_PROVIDERS,
|
|
3407
3571
|
TimeoutError,
|
|
3408
3572
|
UnauthorizedError,
|
|
3573
|
+
VERIFY_PROVIDERS,
|
|
3409
3574
|
WebhookFlowBuilder,
|
|
3410
3575
|
WebhooksCC,
|
|
3411
3576
|
WebhooksCCError,
|
|
3577
|
+
buildTemplateSendOptions,
|
|
3412
3578
|
diffRequests,
|
|
3413
3579
|
extractJsonField,
|
|
3414
3580
|
isClerkWebhook,
|
|
@@ -3439,6 +3605,8 @@ export {
|
|
|
3439
3605
|
parseFormBody,
|
|
3440
3606
|
parseJsonBody,
|
|
3441
3607
|
parseSSE,
|
|
3608
|
+
validateMockResponse,
|
|
3609
|
+
validateResponseRules,
|
|
3442
3610
|
verifyClerkSignature,
|
|
3443
3611
|
verifyDiscordSignature,
|
|
3444
3612
|
verifyGitHubSignature,
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { j as DiffResult, h as CreateEndpointOptions, R as Request, a4 as WebhooksCC, E as Endpoint } from './diff-CRMlHQPX.mjs';
|
|
2
2
|
|
|
3
3
|
type TestingClient = Pick<WebhooksCC, "endpoints" | "requests">;
|
|
4
4
|
interface AssertRequestExpectation {
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { j as DiffResult, h as CreateEndpointOptions, R as Request, a4 as WebhooksCC, E as Endpoint } from './diff-CRMlHQPX.js';
|
|
2
2
|
|
|
3
3
|
type TestingClient = Pick<WebhooksCC, "endpoints" | "requests">;
|
|
4
4
|
interface AssertRequestExpectation {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webhooks-cc/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "TypeScript SDK for webhooks.cc — create endpoints, capture requests, assert in tests",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -37,9 +37,10 @@
|
|
|
37
37
|
},
|
|
38
38
|
"homepage": "https://webhooks.cc",
|
|
39
39
|
"devDependencies": {
|
|
40
|
+
"@types/node": "^24.0.0",
|
|
40
41
|
"tsup": "^8.5.1",
|
|
41
|
-
"typescript": "^
|
|
42
|
-
"vitest": "^4.1.
|
|
42
|
+
"typescript": "^6.0.2",
|
|
43
|
+
"vitest": "^4.1.2"
|
|
43
44
|
},
|
|
44
45
|
"scripts": {
|
|
45
46
|
"build": "tsup --config tsup.config.ts",
|