@hookflo/tern 3.0.17-beta → 4.0.2
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/index.d.ts +1 -0
- package/dist/index.js +65 -8
- package/dist/upstash/queue.js +4 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare class WebhookVerificationService {
|
|
|
8
8
|
static verifyWithPlatformConfig<TPayload = unknown>(request: Request, platform: WebhookPlatform, secret: string, toleranceInSeconds?: number, normalize?: boolean | NormalizeOptions): Promise<WebhookVerificationResult<TPayload>>;
|
|
9
9
|
static verifyAny<TPayload = unknown>(request: Request, secrets: MultiPlatformSecrets, toleranceInSeconds?: number, normalize?: boolean | NormalizeOptions): Promise<WebhookVerificationResult<TPayload>>;
|
|
10
10
|
private static resolveCanonicalEventId;
|
|
11
|
+
private static pickString;
|
|
11
12
|
private static resolveRawEventId;
|
|
12
13
|
static detectPlatform(request: Request): WebhookPlatform;
|
|
13
14
|
static getPlatformsUsingAlgorithm(algorithm: string): WebhookPlatform[];
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ class WebhookVerificationService {
|
|
|
48
48
|
// Ensure the platform is set correctly in the result
|
|
49
49
|
if (result.isValid) {
|
|
50
50
|
result.platform = config.platform;
|
|
51
|
-
result.eventId = this.resolveCanonicalEventId(config.platform, result.metadata);
|
|
51
|
+
result.eventId = this.resolveCanonicalEventId(config.platform, result.metadata, result.payload);
|
|
52
52
|
if (config.normalize) {
|
|
53
53
|
result.payload = (0, simple_1.normalizePayload)(config.platform, result.payload, config.normalize);
|
|
54
54
|
}
|
|
@@ -132,16 +132,73 @@ class WebhookVerificationService {
|
|
|
132
132
|
},
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
|
-
static resolveCanonicalEventId(platform, metadata) {
|
|
136
|
-
const rawId = this.resolveRawEventId(platform, metadata);
|
|
135
|
+
static resolveCanonicalEventId(platform, metadata, payload) {
|
|
136
|
+
const rawId = this.resolveRawEventId(platform, metadata, payload);
|
|
137
137
|
return `${platform}_${rawId}`;
|
|
138
138
|
}
|
|
139
|
-
static
|
|
140
|
-
const candidate
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
static pickString(...candidates) {
|
|
140
|
+
for (const candidate of candidates) {
|
|
141
|
+
if (candidate === undefined || candidate === null) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const normalized = `${candidate}`.trim();
|
|
145
|
+
if (normalized.length > 0 && normalized !== 'undefined' && normalized !== 'null') {
|
|
146
|
+
return normalized;
|
|
147
|
+
}
|
|
143
148
|
}
|
|
144
|
-
return
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
static resolveRawEventId(platform, metadata, payload) {
|
|
152
|
+
const candidate = (() => {
|
|
153
|
+
switch (platform) {
|
|
154
|
+
case 'stripe':
|
|
155
|
+
return this.pickString(payload?.request?.idempotency_key, payload?.id, metadata?.id);
|
|
156
|
+
case 'github':
|
|
157
|
+
return this.pickString(metadata?.delivery, metadata?.id, payload?.id);
|
|
158
|
+
case 'clerk':
|
|
159
|
+
return this.pickString(metadata?.id, payload?.id);
|
|
160
|
+
case 'shopify':
|
|
161
|
+
return this.pickString(metadata?.id, payload?.id);
|
|
162
|
+
case 'polar':
|
|
163
|
+
return this.pickString(payload?.data?.id, payload?.id, metadata?.id);
|
|
164
|
+
case 'dodopayments':
|
|
165
|
+
return this.pickString(payload?.data?.payment_id, payload?.data?.subscription_id, payload?.data?.id, metadata?.id);
|
|
166
|
+
case 'gitlab':
|
|
167
|
+
return this.pickString(payload?.object_attributes?.id, payload?.project?.id, metadata?.id);
|
|
168
|
+
case 'paddle':
|
|
169
|
+
return this.pickString(payload?.event_id, payload?.data?.id, metadata?.id);
|
|
170
|
+
case 'razorpay':
|
|
171
|
+
return this.pickString(payload?.payload?.payment?.entity?.id, payload?.payload?.order?.entity?.id, payload?.payload?.subscription?.entity?.id, payload?.id, metadata?.id);
|
|
172
|
+
case 'lemonsqueezy': {
|
|
173
|
+
const eventName = this.pickString(payload?.meta?.event_name);
|
|
174
|
+
const dataId = this.pickString(payload?.data?.id, payload?.id);
|
|
175
|
+
if (eventName && dataId) {
|
|
176
|
+
return `${eventName}_${dataId}`;
|
|
177
|
+
}
|
|
178
|
+
return this.pickString(dataId, metadata?.id);
|
|
179
|
+
}
|
|
180
|
+
case 'workos':
|
|
181
|
+
case 'vercel':
|
|
182
|
+
case 'replicateai':
|
|
183
|
+
case 'sentry':
|
|
184
|
+
return this.pickString(payload?.id, metadata?.id);
|
|
185
|
+
case 'woocommerce':
|
|
186
|
+
return this.pickString(payload?.id, metadata?.id);
|
|
187
|
+
case 'falai':
|
|
188
|
+
return this.pickString(payload?.request_id, metadata?.id);
|
|
189
|
+
case 'grafana':
|
|
190
|
+
return this.pickString(payload?.groupKey, payload?.alerts?.[0]?.fingerprint, metadata?.id);
|
|
191
|
+
case 'doppler':
|
|
192
|
+
return this.pickString(payload?.event?.id, metadata?.id);
|
|
193
|
+
case 'sanity':
|
|
194
|
+
return this.pickString(payload?.transactionId, payload?._id, metadata?.id);
|
|
195
|
+
default:
|
|
196
|
+
return this.pickString(payload?.idempotency_key, payload?.event_id, payload?.webhook_id, payload?.request_id, payload?.id, payload?.data?.id, metadata?.id, metadata?.delivery, metadata?.requestId);
|
|
197
|
+
}
|
|
198
|
+
})();
|
|
199
|
+
if (candidate)
|
|
200
|
+
return candidate;
|
|
201
|
+
return `generated-missing-${platform}`;
|
|
145
202
|
}
|
|
146
203
|
static detectPlatform(request) {
|
|
147
204
|
const headers = request.headers;
|
package/dist/upstash/queue.js
CHANGED
|
@@ -157,7 +157,9 @@ async function resolveDeduplicationId(request, verificationResult) {
|
|
|
157
157
|
headers.get('x-github-delivery') ||
|
|
158
158
|
headers.get('idempotency-key') ||
|
|
159
159
|
headers.get('upstash-deduplication-id') ||
|
|
160
|
-
verificationResult.eventId
|
|
160
|
+
(verificationResult.eventId && !verificationResult.eventId.includes('generated-missing-')
|
|
161
|
+
? verificationResult.eventId
|
|
162
|
+
: null) ||
|
|
161
163
|
(typeof verificationResult.metadata?.id === 'string' ? verificationResult.metadata.id : null) ||
|
|
162
164
|
payloadId ||
|
|
163
165
|
payloadRequestId ||
|
|
@@ -183,7 +185,7 @@ async function handleReceive(request, platform, secret, queueConfig, toleranceIn
|
|
|
183
185
|
metadata: verificationResult.metadata || {},
|
|
184
186
|
};
|
|
185
187
|
const deduplicationId = await resolveDeduplicationId(request, verificationResult);
|
|
186
|
-
if (process.env.NODE_ENV
|
|
188
|
+
if (process.env.NODE_ENV == 'production') {
|
|
187
189
|
console.log(`[tern] deduplication-id: ${deduplicationId} (platform: ${platform})`);
|
|
188
190
|
}
|
|
189
191
|
const publishPayload = {
|
package/package.json
CHANGED