@astrasyncai/verification-gateway 5.13.0 → 5.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +27 -17
  2. package/dist/adapters/express.d.mts +1 -1
  3. package/dist/adapters/express.d.ts +1 -1
  4. package/dist/adapters/express.js +504 -249
  5. package/dist/adapters/express.js.map +1 -1
  6. package/dist/adapters/express.mjs +504 -249
  7. package/dist/adapters/express.mjs.map +1 -1
  8. package/dist/adapters/mcp.d.mts +1 -1
  9. package/dist/adapters/mcp.d.ts +1 -1
  10. package/dist/adapters/mcp.js +20 -6
  11. package/dist/adapters/mcp.js.map +1 -1
  12. package/dist/adapters/mcp.mjs +20 -6
  13. package/dist/adapters/mcp.mjs.map +1 -1
  14. package/dist/adapters/nextjs.d.mts +1 -1
  15. package/dist/adapters/nextjs.d.ts +1 -1
  16. package/dist/adapters/nextjs.js +487 -248
  17. package/dist/adapters/nextjs.js.map +1 -1
  18. package/dist/adapters/nextjs.mjs +487 -248
  19. package/dist/adapters/nextjs.mjs.map +1 -1
  20. package/dist/adapters/sdk.d.mts +18 -10
  21. package/dist/adapters/sdk.d.ts +18 -10
  22. package/dist/adapters/sdk.js +80 -23
  23. package/dist/adapters/sdk.js.map +1 -1
  24. package/dist/adapters/sdk.mjs +80 -23
  25. package/dist/adapters/sdk.mjs.map +1 -1
  26. package/dist/agent/index.js +1 -1
  27. package/dist/agent/index.js.map +1 -1
  28. package/dist/agent/index.mjs +1 -1
  29. package/dist/agent/index.mjs.map +1 -1
  30. package/dist/bin/astrasync-claude-hook.js +82 -20
  31. package/dist/bin/astrasync-codex-hook.js +82 -20
  32. package/dist/bin/astrasync-guard.js +82 -20
  33. package/dist/bin/astrasync.js +316 -43
  34. package/dist/browser/background.js +77 -15
  35. package/dist/browser/background.js.map +1 -1
  36. package/dist/browser/background.mjs +87 -15
  37. package/dist/browser/background.mjs.map +1 -1
  38. package/dist/cli/index.js +1 -1
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/index.mjs +1 -1
  41. package/dist/cli/index.mjs.map +1 -1
  42. package/dist/codex/index.js +82 -20
  43. package/dist/codex/index.js.map +1 -1
  44. package/dist/codex/index.mjs +92 -20
  45. package/dist/codex/index.mjs.map +1 -1
  46. package/dist/cursor/extension.js +82 -20
  47. package/dist/cursor/extension.js.map +1 -1
  48. package/dist/cursor/extension.mjs +92 -20
  49. package/dist/cursor/extension.mjs.map +1 -1
  50. package/dist/edge-config.d.mts +31 -2
  51. package/dist/edge-config.d.ts +31 -2
  52. package/dist/edge-config.js +35 -5
  53. package/dist/edge-config.js.map +1 -1
  54. package/dist/edge-config.mjs +32 -4
  55. package/dist/edge-config.mjs.map +1 -1
  56. package/dist/edge-core/index.d.mts +43 -6
  57. package/dist/edge-core/index.d.ts +43 -6
  58. package/dist/edge-core/index.js +120 -19
  59. package/dist/edge-core/index.js.map +1 -1
  60. package/dist/edge-core/index.mjs +118 -19
  61. package/dist/edge-core/index.mjs.map +1 -1
  62. package/dist/gateway/gateway.js +77 -15
  63. package/dist/gateway/gateway.js.map +1 -1
  64. package/dist/gateway/gateway.mjs +87 -15
  65. package/dist/gateway/gateway.mjs.map +1 -1
  66. package/dist/git-trigger/git-hooks.d.mts +1 -1
  67. package/dist/git-trigger/git-hooks.d.ts +1 -1
  68. package/dist/index.d.mts +1314 -34
  69. package/dist/index.d.ts +1314 -34
  70. package/dist/index.js +5143 -2621
  71. package/dist/index.js.map +1 -1
  72. package/dist/index.mjs +5090 -2623
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/registration/index.d.mts +28 -2
  75. package/dist/registration/index.d.ts +28 -2
  76. package/dist/registration/index.js +18 -3
  77. package/dist/registration/index.js.map +1 -1
  78. package/dist/registration/index.mjs +15 -2
  79. package/dist/registration/index.mjs.map +1 -1
  80. package/dist/transport/index.d.mts +7 -5
  81. package/dist/transport/index.d.ts +7 -5
  82. package/dist/transport/index.js +61 -5
  83. package/dist/transport/index.js.map +1 -1
  84. package/dist/transport/index.mjs +67 -11
  85. package/dist/transport/index.mjs.map +1 -1
  86. package/dist/{types-C_b4QTyO.d.ts → types-DtJjlW4O.d.ts} +104 -10
  87. package/dist/{types-BCkwBA84.d.mts → types-Dxf9DBpr.d.mts} +106 -12
  88. package/dist/{types-BCkwBA84.d.ts → types-Dxf9DBpr.d.ts} +106 -12
  89. package/dist/{types-DlshIIR-.d.mts → types-Eg6VoBNH.d.mts} +104 -10
  90. package/dist/ui/index.d.mts +1 -1
  91. package/dist/ui/index.d.ts +1 -1
  92. package/dist/verify.d.mts +1 -1
  93. package/dist/verify.d.ts +1 -1
  94. package/dist/verify.js +20 -6
  95. package/dist/verify.js.map +1 -1
  96. package/dist/verify.mjs +20 -6
  97. package/dist/verify.mjs.map +1 -1
  98. package/package.json +1 -1
@@ -25,8 +25,440 @@ __export(express_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(express_exports);
27
27
 
28
+ // src/metadata-capture.ts
29
+ var CAPTURE_SCHEMA_VERSION = 1;
30
+ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
31
+ "cookie",
32
+ "set-cookie",
33
+ "x-csrf-token",
34
+ "proxy-authorization",
35
+ "x-astrasync-signature",
36
+ "x-astrasync-secret",
37
+ "x-hub-signature",
38
+ "x-hub-signature-256",
39
+ // Short-lived verify dedupe token — must never persist in stored metadata.
40
+ "x-astra-verified-hop"
41
+ ]);
42
+ var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
43
+ var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
44
+ "authorization",
45
+ "x-api-key",
46
+ "x-goog-api-key",
47
+ "api-key"
48
+ ]);
49
+ function isSignatureHeader(name) {
50
+ return name === "signature" || name.endsWith("-signature") || name.endsWith("-signature-256");
51
+ }
52
+ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
53
+ "openai-organization",
54
+ "openai-project",
55
+ "openai-version",
56
+ "openai-processing-ms",
57
+ "anthropic-version",
58
+ "anthropic-beta",
59
+ "x-goog-user-project",
60
+ "x-goog-api-client",
61
+ "user-agent",
62
+ "x-agent-card-url",
63
+ "x-agent-provider"
64
+ ]);
65
+ var PLATFORM_HEADER_PREFIXES = [
66
+ "x-goog-",
67
+ "x-stainless-",
68
+ "x-anthropic-",
69
+ "x-openai-",
70
+ "sec-ch-"
71
+ ];
72
+ var KEY_FORMAT_PREFIXES = [
73
+ "sk-ant-api03",
74
+ "sk-ant-api",
75
+ "sk-ant",
76
+ "sk-proj",
77
+ "sk-svcacct",
78
+ "sk-or-v1",
79
+ "sk-or",
80
+ "sk-lf",
81
+ "sk-",
82
+ "gsk_",
83
+ "aiza",
84
+ "ya29",
85
+ "ghp_",
86
+ "gho_",
87
+ "github_pat_",
88
+ "xai-",
89
+ "pplx-",
90
+ "r8_",
91
+ "hf_",
92
+ "astra-",
93
+ "astrae-"
94
+ ];
95
+ var MAX_HEADERS = 64;
96
+ var MAX_HEADER_VALUE_BYTES = 1024;
97
+ var MAX_TOTAL_BYTES = 16 * 1024;
98
+ function byteLength(s) {
99
+ let bytes = 0;
100
+ for (let i = 0; i < s.length; i++) {
101
+ const code = s.charCodeAt(i);
102
+ if (code < 128) bytes += 1;
103
+ else if (code < 2048) bytes += 2;
104
+ else if (code >= 55296 && code <= 56319) {
105
+ bytes += 4;
106
+ i++;
107
+ } else bytes += 3;
108
+ }
109
+ return bytes;
110
+ }
111
+ function extractApiKeyFormat(rawValue) {
112
+ if (!rawValue) return void 0;
113
+ let value = rawValue.trim();
114
+ const spaceIdx = value.indexOf(" ");
115
+ if (spaceIdx > 0) {
116
+ const scheme = value.slice(0, spaceIdx).toLowerCase();
117
+ if (scheme === "bearer" || scheme === "basic" || scheme === "token") {
118
+ value = value.slice(spaceIdx + 1).trim();
119
+ }
120
+ }
121
+ const lower = value.toLowerCase();
122
+ for (const prefix of KEY_FORMAT_PREFIXES) {
123
+ if (lower.startsWith(prefix)) {
124
+ return prefix;
125
+ }
126
+ }
127
+ return void 0;
128
+ }
129
+ function isSecretHeader(name) {
130
+ if (SECRET_HEADER_NAMES.has(name)) return true;
131
+ if (SECRET_HEADER_PREFIXES.some((p) => name.startsWith(p))) return true;
132
+ if (isSignatureHeader(name)) return true;
133
+ return false;
134
+ }
135
+ function isPlatformHeader(name) {
136
+ if (PLATFORM_HEADER_NAMES.has(name)) return true;
137
+ return PLATFORM_HEADER_PREFIXES.some((p) => name.startsWith(p));
138
+ }
139
+ function sanitizeHeaders(raw) {
140
+ const headers = {};
141
+ const platformHeaders = {};
142
+ let apiKeyFormat;
143
+ let cookieCount;
144
+ let totalBytes = 0;
145
+ let count = 0;
146
+ if (!raw) return { headers };
147
+ for (const rawName of Object.keys(raw)) {
148
+ if (count >= MAX_HEADERS) break;
149
+ const name = rawName.toLowerCase();
150
+ const rawValue = raw[rawName];
151
+ if (rawValue === void 0) continue;
152
+ const joined = Array.isArray(rawValue) ? rawValue.join(", ") : String(rawValue);
153
+ if (CREDENTIAL_HEADER_NAMES.has(name)) {
154
+ const fmt = extractApiKeyFormat(joined);
155
+ if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
156
+ continue;
157
+ }
158
+ if (name === "cookie") {
159
+ cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
160
+ }
161
+ if (isSecretHeader(name)) continue;
162
+ let value = joined;
163
+ if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
164
+ value = value.slice(0, MAX_HEADER_VALUE_BYTES);
165
+ }
166
+ const entryBytes = byteLength(name) + byteLength(value);
167
+ if (totalBytes + entryBytes > MAX_TOTAL_BYTES) continue;
168
+ totalBytes += entryBytes;
169
+ count++;
170
+ headers[name] = value;
171
+ if (isPlatformHeader(name)) platformHeaders[name] = value;
172
+ }
173
+ const result = { headers };
174
+ if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
175
+ if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
176
+ if (cookieCount !== void 0) result.cookieCount = cookieCount;
177
+ return result;
178
+ }
179
+ var CONNECTION_HEADER_SOURCES = [
180
+ ["ip", ["cf-connecting-ip", "fastly-client-ip", "true-client-ip", "x-real-ip"]],
181
+ [
182
+ "country",
183
+ ["cf-ipcountry", "x-vercel-ip-country", "cloudfront-viewer-country", "fastly-geo-country"]
184
+ ],
185
+ ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
186
+ ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
187
+ ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
188
+ ["latitude", ["x-vercel-ip-latitude", "cloudfront-viewer-latitude"]],
189
+ ["longitude", ["x-vercel-ip-longitude", "cloudfront-viewer-longitude"]],
190
+ ["postalCode", ["x-vercel-ip-postal-code", "cloudfront-viewer-postal-code"]],
191
+ ["asn", ["cloudfront-viewer-asn"]],
192
+ ["tlsVersion", ["cloudfront-viewer-tls"]],
193
+ ["httpVersion", ["cloudfront-viewer-http-version"]],
194
+ ["timeZone", ["x-vercel-ip-timezone", "cloudfront-viewer-time-zone"]],
195
+ ["metroCode", ["cloudfront-viewer-metro-code"]],
196
+ // TLS fingerprints can only be computed where TLS terminates. When a CDN
197
+ // terminates TLS in front of the merchant, its fingerprint headers ARE the
198
+ // connection-layer truth — normalising them here is the permanent design.
199
+ // CloudFront delivers JA3/JA4 only via an origin request policy and only
200
+ // for HTTPS viewer connections.
201
+ ["tlsFingerprint", ["cf-ja3-hash", "cloudfront-viewer-ja3-fingerprint"]],
202
+ ["ja4", ["cf-ja4", "cloudfront-viewer-ja4-fingerprint"]],
203
+ // Header-structure fingerprint: browser/SDK-distinctive header ordering.
204
+ ["headerOrder", ["cloudfront-viewer-header-order"]],
205
+ ["headerCount", ["cloudfront-viewer-header-count"]]
206
+ ];
207
+ var MAX_CONNECTION_VALUE_CHARS = 256;
208
+ function deriveConnectionFromHeaders(headers) {
209
+ if (!headers) return void 0;
210
+ const lower = {};
211
+ for (const name of Object.keys(headers)) {
212
+ const value = headers[name];
213
+ if (typeof value === "string" && value.length > 0) lower[name.toLowerCase()] = value;
214
+ }
215
+ const connection = {};
216
+ for (const [key, sources] of CONNECTION_HEADER_SOURCES) {
217
+ for (const source of sources) {
218
+ const value = lower[source]?.trim();
219
+ if (value) {
220
+ connection[key] = value.slice(0, MAX_CONNECTION_VALUE_CHARS);
221
+ break;
222
+ }
223
+ }
224
+ }
225
+ {
226
+ const addr = lower["cloudfront-viewer-address"]?.trim();
227
+ const portMatch = addr?.match(/:(\d+)$/);
228
+ if (portMatch) connection.sourcePort = portMatch[1];
229
+ if (!connection.ip && addr) connection.ip = addr.replace(/:\d+$/, "");
230
+ }
231
+ if (!connection.ip) {
232
+ const xff = lower["x-forwarded-for"];
233
+ const client = xff?.split(",")[0]?.trim();
234
+ if (client) connection.ip = client;
235
+ }
236
+ if (!connection.tlsCipher) {
237
+ const cipher = connection.tlsVersion?.split(":")[1];
238
+ if (cipher) connection.tlsCipher = cipher;
239
+ }
240
+ return Object.keys(connection).length > 0 ? connection : void 0;
241
+ }
242
+ function buildSdkObservedMetadata(rawHeaders) {
243
+ const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(rawHeaders);
244
+ const flat = {};
245
+ if (rawHeaders) {
246
+ for (const name of Object.keys(rawHeaders)) {
247
+ const value = rawHeaders[name];
248
+ if (value === void 0) continue;
249
+ flat[name.toLowerCase()] = Array.isArray(value) ? value.join(", ") : String(value);
250
+ }
251
+ }
252
+ const connection = deriveConnectionFromHeaders(flat);
253
+ return {
254
+ headers,
255
+ ...apiKeyFormat && { apiKeyFormat },
256
+ ...platformHeaders && { platformHeaders },
257
+ ...connection && { connection },
258
+ ...cookieCount !== void 0 && { cookieCount },
259
+ schemaVersion: CAPTURE_SCHEMA_VERSION
260
+ };
261
+ }
262
+
263
+ // src/edge-core/request.ts
264
+ function headerValue(req, name) {
265
+ return req.headers[name.toLowerCase()];
266
+ }
267
+ function requestUrl(req, host) {
268
+ const qs = req.querystring ? `?${req.querystring}` : "";
269
+ return `https://${host}${req.uri}${qs}`;
270
+ }
271
+
272
+ // src/edge-core/detect.ts
273
+ var SD_JWT_PATTERN = /^eyJ[\w-]+\.[\w-]*\.[\w-]+~/;
274
+ function decodeBase64Url(seg) {
275
+ const b64 = seg.replace(/-/g, "+").replace(/_/g, "/");
276
+ const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
277
+ const binary = atob(padded);
278
+ const bytes = new Uint8Array(binary.length);
279
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
280
+ return new TextDecoder().decode(bytes);
281
+ }
282
+ function sniffJwtHeader(compact) {
283
+ try {
284
+ const seg = compact.split(".")[0];
285
+ return JSON.parse(decodeBase64Url(seg));
286
+ } catch {
287
+ return void 0;
288
+ }
289
+ }
290
+ function parseJsonBody(bodyText) {
291
+ if (!bodyText) return void 0;
292
+ try {
293
+ const parsed = JSON.parse(bodyText);
294
+ return typeof parsed === "object" && parsed !== null ? parsed : void 0;
295
+ } catch {
296
+ return void 0;
297
+ }
298
+ }
299
+ function detectCommerce(req, host) {
300
+ const url = requestUrl(req, host);
301
+ const method = req.method;
302
+ const headers = req.headers;
303
+ const jsonBody = parseJsonBody(req.bodyText);
304
+ const truncated = req.bodyTruncated ? { bodyTruncated: true } : {};
305
+ const authHeader = headerValue(req, "authorization");
306
+ const bearer = authHeader?.replace(/^Bearer\s+/i, "");
307
+ const mandateHeader = headerValue(req, "x-payment-mandate") ?? headerValue(req, "payment-mandate");
308
+ const sdJwtCandidate = [mandateHeader, bearer].find((v) => v && SD_JWT_PATTERN.test(v));
309
+ if (sdJwtCandidate) {
310
+ const typ = sniffJwtHeader(sdJwtCandidate)?.typ;
311
+ return {
312
+ protocol: "vi-sd-jwt",
313
+ artifacts: { viSdJwt: sdJwtCandidate },
314
+ evidence: { typ, ...truncated }
315
+ };
316
+ }
317
+ const signature = headerValue(req, "signature");
318
+ const signatureInput = headerValue(req, "signature-input");
319
+ if (signature && signatureInput) {
320
+ const signatureAgent = headerValue(req, "signature-agent");
321
+ const registryHint = headerValue(req, "x-agent-registry");
322
+ const lowerInput = signatureInput.toLowerCase();
323
+ const protocol = signatureAgent ? "rfc9421-web-bot-auth" : registryHint?.toLowerCase().includes("visa") || lowerInput.includes("visa") ? "rfc9421-tap" : registryHint?.toLowerCase().includes("mastercard") || lowerInput.includes("mastercard") ? "rfc9421-agent-pay" : "rfc9421";
324
+ return {
325
+ protocol,
326
+ artifacts: {
327
+ rfc9421: { headers, method, url, ...req.bodyText && { body: req.bodyText } }
328
+ },
329
+ evidence: {
330
+ ...signatureAgent && { signatureAgent },
331
+ ...registryHint && { registryHint },
332
+ keyid: signatureInput.match(/keyid="([^"]+)"/)?.[1],
333
+ ...truncated
334
+ }
335
+ };
336
+ }
337
+ const acpTimestamp = headerValue(req, "timestamp");
338
+ if (signature && !signatureInput && (acpTimestamp || headerValue(req, "idempotency-key"))) {
339
+ return {
340
+ protocol: "acp",
341
+ artifacts: {
342
+ acpRequest: {
343
+ method,
344
+ url,
345
+ headers,
346
+ ...req.bodyText && { rawBody: req.bodyText },
347
+ ...jsonBody && { body: jsonBody }
348
+ }
349
+ },
350
+ evidence: { hasTimestamp: Boolean(acpTimestamp), ...truncated }
351
+ };
352
+ }
353
+ if (/\/checkout[-_]sessions(\/|$)/.test(req.uri)) {
354
+ return {
355
+ protocol: "ucp",
356
+ artifacts: { ucpRequest: { method, url, ...jsonBody && { body: jsonBody } } },
357
+ evidence: { path: req.uri, ...truncated }
358
+ };
359
+ }
360
+ if (jsonBody) {
361
+ const intent = jsonBody.intent_mandate ?? jsonBody.intentMandate;
362
+ const cart = jsonBody.cart_mandate ?? jsonBody.cartMandate;
363
+ const payment = jsonBody.payment_mandate ?? jsonBody.paymentMandate;
364
+ if (typeof intent === "string" || typeof cart === "string" || typeof payment === "string") {
365
+ return {
366
+ protocol: "ap2",
367
+ artifacts: {
368
+ ap2Mandates: {
369
+ ...typeof intent === "string" && { intent },
370
+ ...typeof cart === "string" && { cart },
371
+ ...typeof payment === "string" && { payment }
372
+ }
373
+ },
374
+ evidence: {
375
+ mandatesPresent: [
376
+ typeof intent === "string" && "intent",
377
+ typeof cart === "string" && "cart",
378
+ typeof payment === "string" && "payment"
379
+ ].filter(Boolean),
380
+ ...truncated
381
+ }
382
+ };
383
+ }
384
+ }
385
+ if (authHeader && /^Payment\s+/i.test(authHeader) || headerValue(req, "payment-authorization")) {
386
+ return {
387
+ protocol: "mpp",
388
+ artifacts: {
389
+ mppRequest: {
390
+ method,
391
+ url,
392
+ headers,
393
+ ...req.bodyText && { rawBody: req.bodyText },
394
+ ...jsonBody && { body: jsonBody }
395
+ }
396
+ },
397
+ evidence: truncated
398
+ };
399
+ }
400
+ if (headerValue(req, "payment-signature") || headerValue(req, "x-payment")) {
401
+ return {
402
+ protocol: "x402",
403
+ artifacts: {
404
+ x402Request: { method, url, headers, ...jsonBody && { body: jsonBody } }
405
+ },
406
+ evidence: truncated
407
+ };
408
+ }
409
+ return void 0;
410
+ }
411
+
412
+ // src/adapters/commerce-detect.ts
413
+ var MAX_BODY_BYTES = 64 * 1024;
414
+ function lowerHeaders(headers) {
415
+ const out = {};
416
+ if (typeof Headers !== "undefined" && headers instanceof Headers) {
417
+ headers.forEach((v, k) => out[k.toLowerCase()] = v);
418
+ return out;
419
+ }
420
+ for (const [k, v] of Object.entries(headers)) {
421
+ if (v === void 0) continue;
422
+ out[k.toLowerCase()] = Array.isArray(v) ? v.join(", ") : v;
423
+ }
424
+ return out;
425
+ }
426
+ function detect(req, host) {
427
+ try {
428
+ return detectCommerce(req, host)?.artifacts;
429
+ } catch {
430
+ return void 0;
431
+ }
432
+ }
433
+ function detectExpressCommerce(req) {
434
+ const headers = lowerHeaders(req.headers);
435
+ const [uri, query = ""] = (req.originalUrl ?? req.url).split("?");
436
+ let bodyText;
437
+ if (req.rawBody !== void 0) {
438
+ bodyText = typeof req.rawBody === "string" ? req.rawBody : req.rawBody.toString("utf8");
439
+ } else if (typeof req.body === "string") {
440
+ bodyText = req.body;
441
+ } else if (req.body && typeof req.body === "object" && Object.keys(req.body).length > 0) {
442
+ bodyText = JSON.stringify(req.body);
443
+ }
444
+ const truncated = bodyText !== void 0 && bodyText.length > MAX_BODY_BYTES;
445
+ return detect(
446
+ {
447
+ method: req.method,
448
+ uri,
449
+ querystring: query,
450
+ headers,
451
+ ...bodyText !== void 0 && {
452
+ bodyText: truncated ? bodyText.slice(0, MAX_BODY_BYTES) : bodyText,
453
+ bodyTruncated: truncated
454
+ }
455
+ },
456
+ headers["x-forwarded-host"] ?? headers.host ?? "localhost"
457
+ );
458
+ }
459
+
28
460
  // src/version.ts
29
- var SDK_VERSION = "5.13.0";
461
+ var SDK_VERSION = "5.15.0";
30
462
 
31
463
  // src/http.ts
32
464
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -542,6 +974,7 @@ async function callVerifyAccessAPI(config, request) {
542
974
  if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
543
975
  if (requestData.commercePhase) body.commercePhase = requestData.commercePhase;
544
976
  if (requestData.checkoutSessionId) body.checkoutSessionId = requestData.checkoutSessionId;
977
+ if (requestData.checkoutJwt) body.checkoutJwt = requestData.checkoutJwt;
545
978
  if (requestData.checkoutItems) body.checkoutItems = requestData.checkoutItems;
546
979
  if (requestData.buyerEmail) body.buyerEmail = requestData.buyerEmail;
547
980
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
@@ -692,7 +1125,8 @@ async function verify(config, request, options) {
692
1125
  "[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access decisions (verified ID + runtime challenge + PDLSS + trust score). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
693
1126
  );
694
1127
  }
695
- if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache) {
1128
+ const uncacheable = Boolean(request.commerceArtifacts);
1129
+ if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache && !uncacheable) {
696
1130
  const cached = getCachedResult(request, mergedConfig.counterpartyId);
697
1131
  if (cached) {
698
1132
  if (mergedConfig.debug) {
@@ -773,7 +1207,10 @@ async function verify(config, request, options) {
773
1207
  // MERCHANT caller only (bridge callers strip it before the agent plane).
774
1208
  settlementToken: apiResponse.settlementToken,
775
1209
  // 5.6.0: fulfilment contact — merchant-only lane, same strip rule.
776
- fulfilment: apiResponse.fulfilment
1210
+ fulfilment: apiResponse.fulfilment,
1211
+ mandates: apiResponse.mandates,
1212
+ kyaToken: apiResponse.kyaToken,
1213
+ aep: apiResponse.aep
777
1214
  };
778
1215
  return result2;
779
1216
  }
@@ -783,7 +1220,10 @@ async function verify(config, request, options) {
783
1220
  trustScore: apiResponse.agent.trustScore,
784
1221
  trustLevel: getTrustLevel(apiResponse.agent.trustScore),
785
1222
  blockchainAnchored: apiResponse.agent.blockchainStatus === "anchored",
786
- status: apiResponse.agent.agentStatus
1223
+ status: apiResponse.agent.agentStatus,
1224
+ ...apiResponse.agent.protocolIdentities && {
1225
+ protocolIdentities: apiResponse.agent.protocolIdentities
1226
+ }
787
1227
  } : void 0;
788
1228
  const developer = apiResponse.developer ? {
789
1229
  astradId: apiResponse.developer.kyaOwnerId,
@@ -834,7 +1274,11 @@ async function verify(config, request, options) {
834
1274
  settlementOutcome: apiResponse.settlementOutcome,
835
1275
  settlementToken: apiResponse.settlementToken,
836
1276
  // 5.6.0: fulfilment contact — merchant-only lane, same strip rule.
837
- fulfilment: apiResponse.fulfilment
1277
+ fulfilment: apiResponse.fulfilment,
1278
+ // 5.15.0: merchant-lane AP2 mandates + KYAPay identity token.
1279
+ mandates: apiResponse.mandates,
1280
+ kyaToken: apiResponse.kyaToken,
1281
+ aep: apiResponse.aep
838
1282
  };
839
1283
  if (result.recommendation === "deny") {
840
1284
  result.policyAllowed = false;
@@ -854,7 +1298,9 @@ async function verify(config, request, options) {
854
1298
  }
855
1299
  const escalates = result.requiresStepUp === true || result.requiresApproval === true || result.recommendation === "step_up_required";
856
1300
  if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny" && !escalates) {
857
- cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
1301
+ if (!uncacheable) {
1302
+ cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
1303
+ }
858
1304
  }
859
1305
  return result;
860
1306
  }
@@ -1138,239 +1584,30 @@ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
1138
1584
  return failures;
1139
1585
  }
1140
1586
 
1141
- // src/metadata-capture.ts
1142
- var CAPTURE_SCHEMA_VERSION = 1;
1143
- var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
1144
- "cookie",
1145
- "set-cookie",
1146
- "x-csrf-token",
1147
- "proxy-authorization",
1148
- "x-astrasync-signature",
1149
- "x-astrasync-secret",
1150
- "x-hub-signature",
1151
- "x-hub-signature-256",
1152
- // Short-lived verify dedupe token — must never persist in stored metadata.
1153
- "x-astra-verified-hop"
1154
- ]);
1155
- var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
1156
- var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
1157
- "authorization",
1158
- "x-api-key",
1159
- "x-goog-api-key",
1160
- "api-key"
1161
- ]);
1162
- function isSignatureHeader(name) {
1163
- return name === "signature" || name.endsWith("-signature") || name.endsWith("-signature-256");
1164
- }
1165
- var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
1166
- "openai-organization",
1167
- "openai-project",
1168
- "openai-version",
1169
- "openai-processing-ms",
1170
- "anthropic-version",
1171
- "anthropic-beta",
1172
- "x-goog-user-project",
1173
- "x-goog-api-client",
1174
- "user-agent",
1175
- "x-agent-card-url",
1176
- "x-agent-provider"
1177
- ]);
1178
- var PLATFORM_HEADER_PREFIXES = [
1179
- "x-goog-",
1180
- "x-stainless-",
1181
- "x-anthropic-",
1182
- "x-openai-",
1183
- "sec-ch-"
1184
- ];
1185
- var KEY_FORMAT_PREFIXES = [
1186
- "sk-ant-api03",
1187
- "sk-ant-api",
1188
- "sk-ant",
1189
- "sk-proj",
1190
- "sk-svcacct",
1191
- "sk-or-v1",
1192
- "sk-or",
1193
- "sk-lf",
1194
- "sk-",
1195
- "gsk_",
1196
- "aiza",
1197
- "ya29",
1198
- "ghp_",
1199
- "gho_",
1200
- "github_pat_",
1201
- "xai-",
1202
- "pplx-",
1203
- "r8_",
1204
- "hf_",
1205
- "astra-",
1206
- "astrae-"
1207
- ];
1208
- var MAX_HEADERS = 64;
1209
- var MAX_HEADER_VALUE_BYTES = 1024;
1210
- var MAX_TOTAL_BYTES = 16 * 1024;
1211
- function byteLength(s) {
1212
- let bytes = 0;
1213
- for (let i = 0; i < s.length; i++) {
1214
- const code = s.charCodeAt(i);
1215
- if (code < 128) bytes += 1;
1216
- else if (code < 2048) bytes += 2;
1217
- else if (code >= 55296 && code <= 56319) {
1218
- bytes += 4;
1219
- i++;
1220
- } else bytes += 3;
1221
- }
1222
- return bytes;
1223
- }
1224
- function extractApiKeyFormat(rawValue) {
1225
- if (!rawValue) return void 0;
1226
- let value = rawValue.trim();
1227
- const spaceIdx = value.indexOf(" ");
1228
- if (spaceIdx > 0) {
1229
- const scheme = value.slice(0, spaceIdx).toLowerCase();
1230
- if (scheme === "bearer" || scheme === "basic" || scheme === "token") {
1231
- value = value.slice(spaceIdx + 1).trim();
1232
- }
1233
- }
1234
- const lower = value.toLowerCase();
1235
- for (const prefix of KEY_FORMAT_PREFIXES) {
1236
- if (lower.startsWith(prefix)) {
1237
- return prefix;
1238
- }
1239
- }
1240
- return void 0;
1241
- }
1242
- function isSecretHeader(name) {
1243
- if (SECRET_HEADER_NAMES.has(name)) return true;
1244
- if (SECRET_HEADER_PREFIXES.some((p) => name.startsWith(p))) return true;
1245
- if (isSignatureHeader(name)) return true;
1246
- return false;
1247
- }
1248
- function isPlatformHeader(name) {
1249
- if (PLATFORM_HEADER_NAMES.has(name)) return true;
1250
- return PLATFORM_HEADER_PREFIXES.some((p) => name.startsWith(p));
1251
- }
1252
- function sanitizeHeaders(raw) {
1253
- const headers = {};
1254
- const platformHeaders = {};
1255
- let apiKeyFormat;
1256
- let cookieCount;
1257
- let totalBytes = 0;
1258
- let count = 0;
1259
- if (!raw) return { headers };
1260
- for (const rawName of Object.keys(raw)) {
1261
- if (count >= MAX_HEADERS) break;
1262
- const name = rawName.toLowerCase();
1263
- const rawValue = raw[rawName];
1264
- if (rawValue === void 0) continue;
1265
- const joined = Array.isArray(rawValue) ? rawValue.join(", ") : String(rawValue);
1266
- if (CREDENTIAL_HEADER_NAMES.has(name)) {
1267
- const fmt = extractApiKeyFormat(joined);
1268
- if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
1269
- continue;
1270
- }
1271
- if (name === "cookie") {
1272
- cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
1273
- }
1274
- if (isSecretHeader(name)) continue;
1275
- let value = joined;
1276
- if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
1277
- value = value.slice(0, MAX_HEADER_VALUE_BYTES);
1278
- }
1279
- const entryBytes = byteLength(name) + byteLength(value);
1280
- if (totalBytes + entryBytes > MAX_TOTAL_BYTES) continue;
1281
- totalBytes += entryBytes;
1282
- count++;
1283
- headers[name] = value;
1284
- if (isPlatformHeader(name)) platformHeaders[name] = value;
1285
- }
1286
- const result = { headers };
1287
- if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
1288
- if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
1289
- if (cookieCount !== void 0) result.cookieCount = cookieCount;
1290
- return result;
1291
- }
1292
- var CONNECTION_HEADER_SOURCES = [
1293
- ["ip", ["cf-connecting-ip", "fastly-client-ip", "true-client-ip", "x-real-ip"]],
1294
- [
1295
- "country",
1296
- ["cf-ipcountry", "x-vercel-ip-country", "cloudfront-viewer-country", "fastly-geo-country"]
1297
- ],
1298
- ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
1299
- ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
1300
- ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
1301
- ["latitude", ["x-vercel-ip-latitude", "cloudfront-viewer-latitude"]],
1302
- ["longitude", ["x-vercel-ip-longitude", "cloudfront-viewer-longitude"]],
1303
- ["postalCode", ["x-vercel-ip-postal-code", "cloudfront-viewer-postal-code"]],
1304
- ["asn", ["cloudfront-viewer-asn"]],
1305
- ["tlsVersion", ["cloudfront-viewer-tls"]],
1306
- ["httpVersion", ["cloudfront-viewer-http-version"]],
1307
- ["timeZone", ["x-vercel-ip-timezone", "cloudfront-viewer-time-zone"]],
1308
- ["metroCode", ["cloudfront-viewer-metro-code"]],
1309
- // TLS fingerprints can only be computed where TLS terminates. When a CDN
1310
- // terminates TLS in front of the merchant, its fingerprint headers ARE the
1311
- // connection-layer truth — normalising them here is the permanent design.
1312
- // CloudFront delivers JA3/JA4 only via an origin request policy and only
1313
- // for HTTPS viewer connections.
1314
- ["tlsFingerprint", ["cf-ja3-hash", "cloudfront-viewer-ja3-fingerprint"]],
1315
- ["ja4", ["cf-ja4", "cloudfront-viewer-ja4-fingerprint"]],
1316
- // Header-structure fingerprint: browser/SDK-distinctive header ordering.
1317
- ["headerOrder", ["cloudfront-viewer-header-order"]],
1318
- ["headerCount", ["cloudfront-viewer-header-count"]]
1319
- ];
1320
- var MAX_CONNECTION_VALUE_CHARS = 256;
1321
- function deriveConnectionFromHeaders(headers) {
1322
- if (!headers) return void 0;
1323
- const lower = {};
1324
- for (const name of Object.keys(headers)) {
1325
- const value = headers[name];
1326
- if (typeof value === "string" && value.length > 0) lower[name.toLowerCase()] = value;
1327
- }
1328
- const connection = {};
1329
- for (const [key, sources] of CONNECTION_HEADER_SOURCES) {
1330
- for (const source of sources) {
1331
- const value = lower[source]?.trim();
1332
- if (value) {
1333
- connection[key] = value.slice(0, MAX_CONNECTION_VALUE_CHARS);
1334
- break;
1335
- }
1587
+ // src/route-pattern.ts
1588
+ function routePatternToRegExp(pattern, opts = {}) {
1589
+ let source = "";
1590
+ for (let i = 0; i < pattern.length; i++) {
1591
+ const ch = pattern[i];
1592
+ if (ch === "*") {
1593
+ source += ".*";
1594
+ } else if (ch === ":" && /[A-Za-z_]/.test(pattern[i + 1] ?? "") && (i === 0 || pattern[i - 1] === "/")) {
1595
+ let j = i + 1;
1596
+ while (j < pattern.length && /[A-Za-z0-9_]/.test(pattern[j])) j++;
1597
+ source += "[^/]+";
1598
+ i = j - 1;
1599
+ } else {
1600
+ source += ch.replace(/[.+?^${}()|[\]\\/]/g, "\\$&");
1336
1601
  }
1337
1602
  }
1338
- {
1339
- const addr = lower["cloudfront-viewer-address"]?.trim();
1340
- const portMatch = addr?.match(/:(\d+)$/);
1341
- if (portMatch) connection.sourcePort = portMatch[1];
1342
- if (!connection.ip && addr) connection.ip = addr.replace(/:\d+$/, "");
1343
- }
1344
- if (!connection.ip) {
1345
- const xff = lower["x-forwarded-for"];
1346
- const client = xff?.split(",")[0]?.trim();
1347
- if (client) connection.ip = client;
1348
- }
1349
- if (!connection.tlsCipher) {
1350
- const cipher = connection.tlsVersion?.split(":")[1];
1351
- if (cipher) connection.tlsCipher = cipher;
1603
+ try {
1604
+ return new RegExp(`^${source}$`, opts.caseInsensitive ? "i" : "");
1605
+ } catch {
1606
+ return null;
1352
1607
  }
1353
- return Object.keys(connection).length > 0 ? connection : void 0;
1354
1608
  }
1355
- function buildSdkObservedMetadata(rawHeaders) {
1356
- const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(rawHeaders);
1357
- const flat = {};
1358
- if (rawHeaders) {
1359
- for (const name of Object.keys(rawHeaders)) {
1360
- const value = rawHeaders[name];
1361
- if (value === void 0) continue;
1362
- flat[name.toLowerCase()] = Array.isArray(value) ? value.join(", ") : String(value);
1363
- }
1364
- }
1365
- const connection = deriveConnectionFromHeaders(flat);
1366
- return {
1367
- headers,
1368
- ...apiKeyFormat && { apiKeyFormat },
1369
- ...platformHeaders && { platformHeaders },
1370
- ...connection && { connection },
1371
- ...cookieCount !== void 0 && { cookieCount },
1372
- schemaVersion: CAPTURE_SCHEMA_VERSION
1373
- };
1609
+ function matchRoutePattern(pattern, path, opts = {}) {
1610
+ return routePatternToRegExp(pattern, opts)?.test(path) ?? false;
1374
1611
  }
1375
1612
 
1376
1613
  // src/edge-config.ts
@@ -1405,6 +1642,7 @@ function isEdgeConfig(value) {
1405
1642
  if (r.sampling !== void 0 && !isSamplingShape(r.sampling)) return false;
1406
1643
  }
1407
1644
  if (!isSamplingShape(v.sampling)) return false;
1645
+ if (v.minTls !== void 0 && v.minTls !== "1.2" && v.minTls !== "1.3") return false;
1408
1646
  if (v.queryValueAllowlist !== void 0) {
1409
1647
  if (!Array.isArray(v.queryValueAllowlist) || v.queryValueAllowlist.length > 16 || !v.queryValueAllowlist.every((e) => typeof e === "string" && e.length > 0 && e.length <= 64)) {
1410
1648
  return false;
@@ -1655,6 +1893,11 @@ async function withBudget(promise, ms) {
1655
1893
  if (timer) clearTimeout(timer);
1656
1894
  }
1657
1895
  }
1896
+ var CONTAINER_ID = (() => {
1897
+ const c = globalThis.crypto;
1898
+ if (c?.randomUUID) return c.randomUUID();
1899
+ return `c-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
1900
+ })();
1658
1901
  var destKeyOf = (d) => `${d.apiBaseUrl}\0${d.apiKey ?? ""}\0${d.counterparty}\0${d.adapter ?? ""}`;
1659
1902
  var BeaconBuffer = class {
1660
1903
  constructor(options = {}) {
@@ -1662,6 +1905,7 @@ var BeaconBuffer = class {
1662
1905
  this.droppedSinceLast = 0;
1663
1906
  this.droppedTotal = 0;
1664
1907
  this.deliveredTotal = 0;
1908
+ this.enqueuedTotal = 0;
1665
1909
  this.backoffUntil = 0;
1666
1910
  this.collapse = /* @__PURE__ */ new Map();
1667
1911
  /** Keys the backend answered 401 for — later batches go unauthenticated. */
@@ -1674,13 +1918,16 @@ var BeaconBuffer = class {
1674
1918
  collapseMaxKeys: options.collapseMaxKeys ?? 1e3,
1675
1919
  requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
1676
1920
  retryBackoffMs: options.retryBackoffMs ?? 1e3,
1921
+ holdRepeats: options.holdRepeats ?? false,
1922
+ containerId: options.containerId ?? CONTAINER_ID,
1677
1923
  now: options.now ?? Date.now
1678
1924
  };
1679
1925
  }
1680
1926
  /**
1681
1927
  * Queue one beacon. With a `collapseKey`, a repeat inside the window is
1682
- * merged into a held aggregate (sent when the window closes) instead of
1683
- * becoming its own item.
1928
+ * merged into this key's item while that item is still queued (not yet in
1929
+ * flight). Once it has left, the repeat becomes a new item, sendable on
1930
+ * this flush — nothing waits for a later invocation (round 27.6).
1684
1931
  */
1685
1932
  enqueue(dest, item, collapseKey) {
1686
1933
  const now = this.opts.now();
@@ -1693,12 +1940,15 @@ var BeaconBuffer = class {
1693
1940
  return;
1694
1941
  }
1695
1942
  }
1696
- const held = this.push(
1697
- dest,
1698
- { ...item, repeatCount: 1 },
1699
- entry.firstSeenAt + this.opts.collapseWindowMs
1700
- );
1701
- entry.held = held;
1943
+ if (this.opts.holdRepeats) {
1944
+ entry.held = this.push(
1945
+ dest,
1946
+ { ...item, repeatCount: 1 },
1947
+ entry.firstSeenAt + this.opts.collapseWindowMs
1948
+ );
1949
+ return;
1950
+ }
1951
+ entry.first = this.push(dest, { ...item, repeatCount: 1 }, now);
1702
1952
  return;
1703
1953
  }
1704
1954
  this.collapse.delete(collapseKey);
@@ -1734,6 +1984,7 @@ var BeaconBuffer = class {
1734
1984
  droppedSinceLast: this.droppedSinceLast,
1735
1985
  droppedTotal: this.droppedTotal,
1736
1986
  deliveredTotal: this.deliveredTotal,
1987
+ enqueuedTotal: this.enqueuedTotal,
1737
1988
  flushing: this.inFlight !== void 0
1738
1989
  };
1739
1990
  }
@@ -1748,6 +1999,7 @@ var BeaconBuffer = class {
1748
1999
  inFlight: false
1749
2000
  };
1750
2001
  this.queue.push(entry);
2002
+ this.enqueuedTotal += 1;
1751
2003
  return entry;
1752
2004
  }
1753
2005
  dropOldest() {
@@ -1793,7 +2045,11 @@ var BeaconBuffer = class {
1793
2045
  droppedSinceLast: reportedDropped,
1794
2046
  queueDepth: this.queue.length,
1795
2047
  adapter: dest.adapter ?? "edge-core",
1796
- version: SDK_VERSION
2048
+ version: SDK_VERSION,
2049
+ containerId: this.opts.containerId,
2050
+ enqueuedTotal: this.enqueuedTotal,
2051
+ deliveredTotal: this.deliveredTotal,
2052
+ droppedTotal: this.droppedTotal
1797
2053
  };
1798
2054
  const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
1799
2055
  const response = await withBudget(
@@ -1974,14 +2230,11 @@ function resolveRequestPdlss(req, routeConfig, customExtractPurpose, customExtra
1974
2230
  });
1975
2231
  }
1976
2232
  function matchRoute(pattern, path, opts) {
1977
- const regexPattern = pattern.replace(/\*/g, ".*").replace(/\//g, "\\/");
1978
- const caseSensitiveRegex = new RegExp(`^${regexPattern}$`);
1979
- const caseSensitiveResult = caseSensitiveRegex.test(path);
2233
+ const caseSensitiveResult = matchRoutePattern(pattern, path);
1980
2234
  if (!opts?.caseInsensitive && !opts?.logShadowDivergence) {
1981
2235
  return caseSensitiveResult;
1982
2236
  }
1983
- const caseInsensitiveRegex = new RegExp(`^${regexPattern}$`, "i");
1984
- const caseInsensitiveResult = caseInsensitiveRegex.test(path);
2237
+ const caseInsensitiveResult = matchRoutePattern(pattern, path, { caseInsensitive: true });
1985
2238
  if (opts?.logShadowDivergence && caseSensitiveResult !== caseInsensitiveResult) {
1986
2239
  console.warn(
1987
2240
  `[SHADOW] matchRoute case-insensitive would change result: pattern=${pattern} path=${path} caseSensitive=${caseSensitiveResult} caseInsensitive=${caseInsensitiveResult} correlationId=${opts.correlationId ?? "unknown"}`
@@ -2244,8 +2497,10 @@ function createMiddleware(options) {
2244
2497
  }
2245
2498
  const attemptHeader = req.headers["x-astra-attempt-id"];
2246
2499
  const inboundAttemptId = typeof attemptHeader === "string" && /^att_[0-9a-f]{32}$/.test(attemptHeader) ? attemptHeader : void 0;
2500
+ const commerceArtifacts = detectExpressCommerce(req);
2247
2501
  const verificationRequest = {
2248
2502
  credentials,
2503
+ ...commerceArtifacts && { commerceArtifacts },
2249
2504
  purpose,
2250
2505
  action: pdlssPair.action,
2251
2506
  resource: req.path,