@astrasyncai/verification-gateway 5.11.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/adapters/express.d.mts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +359 -30
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +359 -30
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +5 -1
- package/dist/adapters/mcp.d.ts +5 -1
- package/dist/adapters/mcp.js +168 -41
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +168 -41
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +1 -1
- package/dist/adapters/nextjs.d.ts +1 -1
- package/dist/adapters/nextjs.js +352 -13
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +352 -13
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +9 -1
- package/dist/adapters/sdk.d.ts +9 -1
- package/dist/adapters/sdk.js +100 -8
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +100 -8
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +284 -7
- package/dist/bin/astrasync-codex-hook.js +284 -7
- package/dist/bin/astrasync-guard.js +284 -7
- package/dist/bin/astrasync.js +297 -9
- package/dist/browser/background.js +284 -7
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +284 -7
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +284 -7
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +284 -7
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +284 -7
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +284 -7
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +128 -13
- package/dist/edge-core/index.d.ts +128 -13
- package/dist/edge-core/index.js +337 -55
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +334 -55
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +284 -7
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +284 -7
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +1 -1
- package/dist/git-trigger/git-hooks.d.ts +1 -1
- package/dist/index.d.mts +118 -5
- package/dist/index.d.ts +118 -5
- package/dist/index.js +486 -63
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +480 -63
- package/dist/index.mjs.map +1 -1
- package/dist/platform-signatures.js +4 -1
- package/dist/platform-signatures.js.map +1 -1
- package/dist/platform-signatures.mjs +4 -1
- package/dist/platform-signatures.mjs.map +1 -1
- package/dist/registration/index.js +1 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +1 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +1 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-CTmUpNpS.d.mts → types-BCkwBA84.d.mts} +12 -0
- package/dist/{types-CTmUpNpS.d.ts → types-BCkwBA84.d.ts} +12 -0
- package/dist/{types-CtFXmDzm.d.ts → types-C_b4QTyO.d.ts} +18 -0
- package/dist/{types-DQrn_kei.d.mts → types-DlshIIR-.d.mts} +18 -0
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +35 -4
- package/dist/verify.d.ts +35 -4
- package/dist/verify.js +130 -16
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +129 -16
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -3988,7 +3988,7 @@ function getTrustLevel(score) {
|
|
|
3988
3988
|
}
|
|
3989
3989
|
|
|
3990
3990
|
// src/version.ts
|
|
3991
|
-
var SDK_VERSION = "5.
|
|
3991
|
+
var SDK_VERSION = "5.12.0";
|
|
3992
3992
|
|
|
3993
3993
|
// src/http.ts
|
|
3994
3994
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -4015,6 +4015,14 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
4015
4015
|
return cache.get(apiBaseUrl)?.data;
|
|
4016
4016
|
}
|
|
4017
4017
|
|
|
4018
|
+
// src/failure-posture.ts
|
|
4019
|
+
var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
4020
|
+
"identity.invalid_agent_id",
|
|
4021
|
+
"identity.unknown_agent",
|
|
4022
|
+
"agent.lookup"
|
|
4023
|
+
]);
|
|
4024
|
+
var UNKNOWN_AGENT_GUIDANCE = "Register your agent with AstraSync (or, inside an MCP host, add the AstraSync MCP connector for keyless, human-approved registration), then present the canonical ASTRA-* id issued after owner approval.";
|
|
4025
|
+
|
|
4018
4026
|
// src/verify.ts
|
|
4019
4027
|
var DEFAULT_CONFIG = {
|
|
4020
4028
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -4226,11 +4234,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
4226
4234
|
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
4227
4235
|
// deterministic and intentionally NOT marked retryable.
|
|
4228
4236
|
...isApiError && { retryable: true },
|
|
4237
|
+
...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
|
|
4238
|
+
...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
|
|
4229
4239
|
correlationId: options.correlationId,
|
|
4230
4240
|
attemptId: options.attemptId,
|
|
4231
4241
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
4232
4242
|
};
|
|
4233
4243
|
}
|
|
4244
|
+
async function readJsonSafe(response) {
|
|
4245
|
+
try {
|
|
4246
|
+
const parsed = await response.json();
|
|
4247
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
4248
|
+
} catch {
|
|
4249
|
+
return {};
|
|
4250
|
+
}
|
|
4251
|
+
}
|
|
4252
|
+
function rejectedIdentityGuidance(failures) {
|
|
4253
|
+
const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
|
|
4254
|
+
if (!f) return void 0;
|
|
4255
|
+
if (f.dimension === "agent.lookup") {
|
|
4256
|
+
return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
|
|
4257
|
+
}
|
|
4258
|
+
return f.guidance ? `${f.message} ${f.guidance}` : f.message;
|
|
4259
|
+
}
|
|
4260
|
+
var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
|
|
4261
|
+
function parseRetryAfterMs(response) {
|
|
4262
|
+
const raw = response.headers?.get?.("retry-after");
|
|
4263
|
+
if (!raw) return void 0;
|
|
4264
|
+
const trimmed = raw.trim();
|
|
4265
|
+
let ms;
|
|
4266
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
4267
|
+
ms = Number(trimmed) * 1e3;
|
|
4268
|
+
} else {
|
|
4269
|
+
const at = Date.parse(trimmed);
|
|
4270
|
+
if (Number.isNaN(at)) return void 0;
|
|
4271
|
+
ms = at - Date.now();
|
|
4272
|
+
}
|
|
4273
|
+
return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
|
|
4274
|
+
}
|
|
4234
4275
|
async function callVerifyAccessAPI(config, request) {
|
|
4235
4276
|
const { credentials, ...requestData } = request;
|
|
4236
4277
|
const body = {
|
|
@@ -4287,7 +4328,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4287
4328
|
body: JSON.stringify(body),
|
|
4288
4329
|
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
4289
4330
|
});
|
|
4290
|
-
const data = await response
|
|
4331
|
+
const data = await readJsonSafe(response);
|
|
4332
|
+
const retryAfterMs = parseRetryAfterMs(response);
|
|
4291
4333
|
if (response.status === 410) {
|
|
4292
4334
|
return {
|
|
4293
4335
|
success: true,
|
|
@@ -4325,6 +4367,23 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4325
4367
|
}
|
|
4326
4368
|
};
|
|
4327
4369
|
}
|
|
4370
|
+
if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
|
|
4371
|
+
return {
|
|
4372
|
+
success: true,
|
|
4373
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
4374
|
+
access: {
|
|
4375
|
+
allowed: false,
|
|
4376
|
+
reason: "unknown_agent",
|
|
4377
|
+
failures: [
|
|
4378
|
+
{
|
|
4379
|
+
dimension: "identity.unknown_agent",
|
|
4380
|
+
message: "The presented agent identifier is not registered with AstraSync.",
|
|
4381
|
+
guidance: UNKNOWN_AGENT_GUIDANCE
|
|
4382
|
+
}
|
|
4383
|
+
]
|
|
4384
|
+
}
|
|
4385
|
+
};
|
|
4386
|
+
}
|
|
4328
4387
|
if (!response.ok) {
|
|
4329
4388
|
if (response.status === 401) {
|
|
4330
4389
|
return {
|
|
@@ -4339,9 +4398,11 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4339
4398
|
}
|
|
4340
4399
|
return {
|
|
4341
4400
|
success: false,
|
|
4342
|
-
error: data.message || data.error || `API returned ${response.status}`,
|
|
4401
|
+
error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
|
|
4343
4402
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
4344
|
-
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
4403
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
4404
|
+
httpStatus: response.status,
|
|
4405
|
+
...retryAfterMs !== void 0 && { retryAfterMs }
|
|
4345
4406
|
};
|
|
4346
4407
|
}
|
|
4347
4408
|
return data;
|
|
@@ -4413,12 +4474,14 @@ async function verify(config, request, options) {
|
|
|
4413
4474
|
correlationId: apiResponse.correlationId,
|
|
4414
4475
|
attemptId: apiResponse.attemptId,
|
|
4415
4476
|
remediation: apiResponse.remediation,
|
|
4477
|
+
httpStatus: apiResponse.httpStatus,
|
|
4478
|
+
retryAfterMs: apiResponse.retryAfterMs,
|
|
4416
4479
|
urls
|
|
4417
4480
|
});
|
|
4418
4481
|
}
|
|
4419
4482
|
if (!apiResponse.access?.allowed) {
|
|
4420
4483
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
4421
|
-
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
|
|
4484
|
+
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
4422
4485
|
const result2 = {
|
|
4423
4486
|
identityVerified: idVerifiedFromBackend,
|
|
4424
4487
|
policyAllowed: false,
|
|
@@ -4430,7 +4493,10 @@ async function verify(config, request, options) {
|
|
|
4430
4493
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
4431
4494
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
4432
4495
|
guidance: {
|
|
4433
|
-
|
|
4496
|
+
// 5.12.0: a presented-but-rejected id (malformed / unknown) carries
|
|
4497
|
+
// actionable registration guidance on its failure — surface it
|
|
4498
|
+
// instead of the bare machine reason ('unknown_agent').
|
|
4499
|
+
message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
|
|
4434
4500
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
4435
4501
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
4436
4502
|
// 5.1.0: anonymous callers land on this branch — steer MCP-hosted
|
|
@@ -4530,7 +4596,7 @@ async function verify(config, request, options) {
|
|
|
4530
4596
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
4531
4597
|
documentationUrl: urls?.documentationUrl ?? ""
|
|
4532
4598
|
};
|
|
4533
|
-
} else if (result.recommendation === "step_up_required") {
|
|
4599
|
+
} else if (result.recommendation === "step_up_required" && result.identityVerified) {
|
|
4534
4600
|
result.requiresStepUp = true;
|
|
4535
4601
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
4536
4602
|
}
|
|
@@ -4559,6 +4625,217 @@ var DEFAULT_EDGE_CONFIG = Object.freeze({
|
|
|
4559
4625
|
var DEFAULT_TTL_MS = 60 * 1e3;
|
|
4560
4626
|
var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
|
|
4561
4627
|
|
|
4628
|
+
// src/edge-core/events.ts
|
|
4629
|
+
async function withBudget(promise, ms) {
|
|
4630
|
+
let timer;
|
|
4631
|
+
try {
|
|
4632
|
+
return await Promise.race([
|
|
4633
|
+
promise,
|
|
4634
|
+
new Promise((resolve) => {
|
|
4635
|
+
timer = setTimeout(() => resolve(void 0), ms);
|
|
4636
|
+
})
|
|
4637
|
+
]);
|
|
4638
|
+
} catch {
|
|
4639
|
+
return void 0;
|
|
4640
|
+
} finally {
|
|
4641
|
+
if (timer) clearTimeout(timer);
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
var destKeyOf = (d) => `${d.apiBaseUrl}\0${d.apiKey ?? ""}\0${d.counterparty}\0${d.adapter ?? ""}`;
|
|
4645
|
+
var BeaconBuffer = class {
|
|
4646
|
+
constructor(options = {}) {
|
|
4647
|
+
this.queue = [];
|
|
4648
|
+
this.droppedSinceLast = 0;
|
|
4649
|
+
this.droppedTotal = 0;
|
|
4650
|
+
this.deliveredTotal = 0;
|
|
4651
|
+
this.backoffUntil = 0;
|
|
4652
|
+
this.collapse = /* @__PURE__ */ new Map();
|
|
4653
|
+
/** Keys the backend answered 401 for — later batches go unauthenticated. */
|
|
4654
|
+
this.rejectedKeys = /* @__PURE__ */ new Set();
|
|
4655
|
+
this.opts = {
|
|
4656
|
+
maxItems: options.maxItems ?? 1e3,
|
|
4657
|
+
maxBatch: options.maxBatch ?? 100,
|
|
4658
|
+
maxAttempts: options.maxAttempts ?? 3,
|
|
4659
|
+
collapseWindowMs: options.collapseWindowMs ?? 6e4,
|
|
4660
|
+
collapseMaxKeys: options.collapseMaxKeys ?? 1e3,
|
|
4661
|
+
requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
|
|
4662
|
+
retryBackoffMs: options.retryBackoffMs ?? 1e3,
|
|
4663
|
+
now: options.now ?? Date.now
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4666
|
+
/**
|
|
4667
|
+
* Queue one beacon. With a `collapseKey`, a repeat inside the window is
|
|
4668
|
+
* merged into a held aggregate (sent when the window closes) instead of
|
|
4669
|
+
* becoming its own item.
|
|
4670
|
+
*/
|
|
4671
|
+
enqueue(dest, item, collapseKey) {
|
|
4672
|
+
const now = this.opts.now();
|
|
4673
|
+
if (collapseKey) {
|
|
4674
|
+
const entry = this.collapse.get(collapseKey);
|
|
4675
|
+
if (entry && now - entry.firstSeenAt < this.opts.collapseWindowMs) {
|
|
4676
|
+
for (const target of [entry.first, entry.held]) {
|
|
4677
|
+
if (target && !target.inFlight && this.queue.includes(target)) {
|
|
4678
|
+
target.item.repeatCount = (target.item.repeatCount ?? 1) + 1;
|
|
4679
|
+
return;
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
const held = this.push(
|
|
4683
|
+
dest,
|
|
4684
|
+
{ ...item, repeatCount: 1 },
|
|
4685
|
+
entry.firstSeenAt + this.opts.collapseWindowMs
|
|
4686
|
+
);
|
|
4687
|
+
entry.held = held;
|
|
4688
|
+
return;
|
|
4689
|
+
}
|
|
4690
|
+
this.collapse.delete(collapseKey);
|
|
4691
|
+
if (this.collapse.size >= this.opts.collapseMaxKeys) {
|
|
4692
|
+
const oldest = this.collapse.keys().next().value;
|
|
4693
|
+
if (oldest !== void 0) this.collapse.delete(oldest);
|
|
4694
|
+
}
|
|
4695
|
+
const fresh = { firstSeenAt: now };
|
|
4696
|
+
this.collapse.set(collapseKey, fresh);
|
|
4697
|
+
fresh.first = this.push(dest, item, now);
|
|
4698
|
+
return;
|
|
4699
|
+
}
|
|
4700
|
+
this.push(dest, item, now);
|
|
4701
|
+
}
|
|
4702
|
+
/**
|
|
4703
|
+
* Deliver every eligible queued item. Concurrent callers share ONE
|
|
4704
|
+
* in-flight drain (it survives the caller's budget and a Lambda freeze),
|
|
4705
|
+
* so nothing in flight is ever sent twice; items queued while it runs are
|
|
4706
|
+
* picked up by the same drain.
|
|
4707
|
+
*/
|
|
4708
|
+
flush() {
|
|
4709
|
+
if (!this.inFlight) {
|
|
4710
|
+
this.inFlight = this.drain().finally(() => {
|
|
4711
|
+
this.inFlight = void 0;
|
|
4712
|
+
});
|
|
4713
|
+
}
|
|
4714
|
+
return this.inFlight;
|
|
4715
|
+
}
|
|
4716
|
+
/** Counters for tests and diagnostics. */
|
|
4717
|
+
stats() {
|
|
4718
|
+
return {
|
|
4719
|
+
queueDepth: this.queue.length,
|
|
4720
|
+
droppedSinceLast: this.droppedSinceLast,
|
|
4721
|
+
droppedTotal: this.droppedTotal,
|
|
4722
|
+
deliveredTotal: this.deliveredTotal,
|
|
4723
|
+
flushing: this.inFlight !== void 0
|
|
4724
|
+
};
|
|
4725
|
+
}
|
|
4726
|
+
push(dest, item, eligibleAt) {
|
|
4727
|
+
while (this.queue.length >= this.opts.maxItems) this.dropOldest();
|
|
4728
|
+
const entry = {
|
|
4729
|
+
dest,
|
|
4730
|
+
destKey: destKeyOf(dest),
|
|
4731
|
+
item,
|
|
4732
|
+
attempts: 0,
|
|
4733
|
+
eligibleAt,
|
|
4734
|
+
inFlight: false
|
|
4735
|
+
};
|
|
4736
|
+
this.queue.push(entry);
|
|
4737
|
+
return entry;
|
|
4738
|
+
}
|
|
4739
|
+
dropOldest() {
|
|
4740
|
+
if (this.queue.shift()) this.countDropped(1);
|
|
4741
|
+
}
|
|
4742
|
+
countDropped(n) {
|
|
4743
|
+
this.droppedSinceLast += n;
|
|
4744
|
+
this.droppedTotal += n;
|
|
4745
|
+
}
|
|
4746
|
+
async drain() {
|
|
4747
|
+
for (; ; ) {
|
|
4748
|
+
const now = this.opts.now();
|
|
4749
|
+
if (now < this.backoffUntil) return;
|
|
4750
|
+
const batch = this.takeBatch(now);
|
|
4751
|
+
if (batch.length === 0) return;
|
|
4752
|
+
const ok = await this.send(batch);
|
|
4753
|
+
if (!ok) return;
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4756
|
+
/** Oldest eligible item + up to maxBatch-1 more for the same destination. */
|
|
4757
|
+
takeBatch(now) {
|
|
4758
|
+
const first = this.queue.find((q) => q.eligibleAt <= now);
|
|
4759
|
+
if (!first) return [];
|
|
4760
|
+
const batch = [];
|
|
4761
|
+
const rest = [];
|
|
4762
|
+
for (const q of this.queue) {
|
|
4763
|
+
if (batch.length < this.opts.maxBatch && q.destKey === first.destKey && q.eligibleAt <= now) {
|
|
4764
|
+
q.inFlight = true;
|
|
4765
|
+
batch.push(q);
|
|
4766
|
+
} else {
|
|
4767
|
+
rest.push(q);
|
|
4768
|
+
}
|
|
4769
|
+
}
|
|
4770
|
+
this.queue = rest;
|
|
4771
|
+
return batch;
|
|
4772
|
+
}
|
|
4773
|
+
/** POST one batch. Returns false when the drain should pause (backoff). */
|
|
4774
|
+
async send(batch) {
|
|
4775
|
+
const dest = batch[0].dest;
|
|
4776
|
+
const useKey = dest.apiKey && !this.rejectedKeys.has(dest.apiKey) ? dest.apiKey : void 0;
|
|
4777
|
+
const reportedDropped = this.droppedSinceLast;
|
|
4778
|
+
const meta = {
|
|
4779
|
+
droppedSinceLast: reportedDropped,
|
|
4780
|
+
queueDepth: this.queue.length,
|
|
4781
|
+
adapter: dest.adapter ?? "edge-core",
|
|
4782
|
+
version: SDK_VERSION
|
|
4783
|
+
};
|
|
4784
|
+
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
4785
|
+
const response = await withBudget(
|
|
4786
|
+
sdkFetch(`${dest.apiBaseUrl}/verification-activity/edge-events`, {
|
|
4787
|
+
method: "POST",
|
|
4788
|
+
headers: {
|
|
4789
|
+
"Content-Type": "application/json",
|
|
4790
|
+
...useKey && { Authorization: `Bearer ${useKey}` }
|
|
4791
|
+
},
|
|
4792
|
+
body: JSON.stringify({ events: batch.map((q) => q.item), meta }),
|
|
4793
|
+
...controller && { signal: controller.signal }
|
|
4794
|
+
}),
|
|
4795
|
+
this.opts.requestTimeoutMs
|
|
4796
|
+
);
|
|
4797
|
+
if (!response) controller?.abort();
|
|
4798
|
+
const status = response?.status;
|
|
4799
|
+
for (const q of batch) q.inFlight = false;
|
|
4800
|
+
if (status !== void 0 && status >= 200 && status < 300) {
|
|
4801
|
+
this.droppedSinceLast = Math.max(0, this.droppedSinceLast - reportedDropped);
|
|
4802
|
+
this.deliveredTotal += batch.length;
|
|
4803
|
+
return true;
|
|
4804
|
+
}
|
|
4805
|
+
if (status === 401 && useKey) {
|
|
4806
|
+
this.rejectedKeys.add(useKey);
|
|
4807
|
+
this.requeue(batch, false);
|
|
4808
|
+
return true;
|
|
4809
|
+
}
|
|
4810
|
+
if (status === 429) {
|
|
4811
|
+
const retryAfter = Number(response?.headers.get("retry-after"));
|
|
4812
|
+
const waitMs = Number.isFinite(retryAfter) && retryAfter > 0 ? Math.min(retryAfter, 120) * 1e3 : 3e4;
|
|
4813
|
+
this.backoffUntil = this.opts.now() + waitMs;
|
|
4814
|
+
this.requeue(batch, false);
|
|
4815
|
+
return false;
|
|
4816
|
+
}
|
|
4817
|
+
if (status !== void 0 && status >= 400 && status < 500) {
|
|
4818
|
+
this.countDropped(batch.length);
|
|
4819
|
+
return true;
|
|
4820
|
+
}
|
|
4821
|
+
this.backoffUntil = this.opts.now() + this.opts.retryBackoffMs;
|
|
4822
|
+
this.requeue(batch, true);
|
|
4823
|
+
return false;
|
|
4824
|
+
}
|
|
4825
|
+
/** Put a failed batch back at the head of the queue (order preserved). */
|
|
4826
|
+
requeue(batch, countAttempt) {
|
|
4827
|
+
const keep = [];
|
|
4828
|
+
for (const q of batch) {
|
|
4829
|
+
if (countAttempt) q.attempts += 1;
|
|
4830
|
+
if (q.attempts >= this.opts.maxAttempts) this.countDropped(1);
|
|
4831
|
+
else keep.push(q);
|
|
4832
|
+
}
|
|
4833
|
+
this.queue = [...keep, ...this.queue];
|
|
4834
|
+
while (this.queue.length > this.opts.maxItems) this.dropOldest();
|
|
4835
|
+
}
|
|
4836
|
+
};
|
|
4837
|
+
var beaconBuffer = new BeaconBuffer();
|
|
4838
|
+
|
|
4562
4839
|
// src/adapters/express.ts
|
|
4563
4840
|
var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
4564
4841
|
|