@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
package/dist/codex/index.mjs
CHANGED
|
@@ -4006,7 +4006,7 @@ function getTrustLevel(score) {
|
|
|
4006
4006
|
}
|
|
4007
4007
|
|
|
4008
4008
|
// src/version.ts
|
|
4009
|
-
var SDK_VERSION = "5.
|
|
4009
|
+
var SDK_VERSION = "5.12.0";
|
|
4010
4010
|
|
|
4011
4011
|
// src/http.ts
|
|
4012
4012
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -4033,6 +4033,14 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
4033
4033
|
return cache.get(apiBaseUrl)?.data;
|
|
4034
4034
|
}
|
|
4035
4035
|
|
|
4036
|
+
// src/failure-posture.ts
|
|
4037
|
+
var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
4038
|
+
"identity.invalid_agent_id",
|
|
4039
|
+
"identity.unknown_agent",
|
|
4040
|
+
"agent.lookup"
|
|
4041
|
+
]);
|
|
4042
|
+
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.";
|
|
4043
|
+
|
|
4036
4044
|
// src/verify.ts
|
|
4037
4045
|
var DEFAULT_CONFIG = {
|
|
4038
4046
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -4244,11 +4252,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
4244
4252
|
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
4245
4253
|
// deterministic and intentionally NOT marked retryable.
|
|
4246
4254
|
...isApiError && { retryable: true },
|
|
4255
|
+
...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
|
|
4256
|
+
...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
|
|
4247
4257
|
correlationId: options.correlationId,
|
|
4248
4258
|
attemptId: options.attemptId,
|
|
4249
4259
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
4250
4260
|
};
|
|
4251
4261
|
}
|
|
4262
|
+
async function readJsonSafe(response) {
|
|
4263
|
+
try {
|
|
4264
|
+
const parsed = await response.json();
|
|
4265
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
4266
|
+
} catch {
|
|
4267
|
+
return {};
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
function rejectedIdentityGuidance(failures) {
|
|
4271
|
+
const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
|
|
4272
|
+
if (!f) return void 0;
|
|
4273
|
+
if (f.dimension === "agent.lookup") {
|
|
4274
|
+
return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
|
|
4275
|
+
}
|
|
4276
|
+
return f.guidance ? `${f.message} ${f.guidance}` : f.message;
|
|
4277
|
+
}
|
|
4278
|
+
var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
|
|
4279
|
+
function parseRetryAfterMs(response) {
|
|
4280
|
+
const raw = response.headers?.get?.("retry-after");
|
|
4281
|
+
if (!raw) return void 0;
|
|
4282
|
+
const trimmed = raw.trim();
|
|
4283
|
+
let ms;
|
|
4284
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
4285
|
+
ms = Number(trimmed) * 1e3;
|
|
4286
|
+
} else {
|
|
4287
|
+
const at = Date.parse(trimmed);
|
|
4288
|
+
if (Number.isNaN(at)) return void 0;
|
|
4289
|
+
ms = at - Date.now();
|
|
4290
|
+
}
|
|
4291
|
+
return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
|
|
4292
|
+
}
|
|
4252
4293
|
async function callVerifyAccessAPI(config, request) {
|
|
4253
4294
|
const { credentials, ...requestData } = request;
|
|
4254
4295
|
const body = {
|
|
@@ -4305,7 +4346,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4305
4346
|
body: JSON.stringify(body),
|
|
4306
4347
|
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
4307
4348
|
});
|
|
4308
|
-
const data = await response
|
|
4349
|
+
const data = await readJsonSafe(response);
|
|
4350
|
+
const retryAfterMs = parseRetryAfterMs(response);
|
|
4309
4351
|
if (response.status === 410) {
|
|
4310
4352
|
return {
|
|
4311
4353
|
success: true,
|
|
@@ -4343,6 +4385,23 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4343
4385
|
}
|
|
4344
4386
|
};
|
|
4345
4387
|
}
|
|
4388
|
+
if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
|
|
4389
|
+
return {
|
|
4390
|
+
success: true,
|
|
4391
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
4392
|
+
access: {
|
|
4393
|
+
allowed: false,
|
|
4394
|
+
reason: "unknown_agent",
|
|
4395
|
+
failures: [
|
|
4396
|
+
{
|
|
4397
|
+
dimension: "identity.unknown_agent",
|
|
4398
|
+
message: "The presented agent identifier is not registered with AstraSync.",
|
|
4399
|
+
guidance: UNKNOWN_AGENT_GUIDANCE
|
|
4400
|
+
}
|
|
4401
|
+
]
|
|
4402
|
+
}
|
|
4403
|
+
};
|
|
4404
|
+
}
|
|
4346
4405
|
if (!response.ok) {
|
|
4347
4406
|
if (response.status === 401) {
|
|
4348
4407
|
return {
|
|
@@ -4357,9 +4416,11 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4357
4416
|
}
|
|
4358
4417
|
return {
|
|
4359
4418
|
success: false,
|
|
4360
|
-
error: data.message || data.error || `API returned ${response.status}`,
|
|
4419
|
+
error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
|
|
4361
4420
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
4362
|
-
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
4421
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
4422
|
+
httpStatus: response.status,
|
|
4423
|
+
...retryAfterMs !== void 0 && { retryAfterMs }
|
|
4363
4424
|
};
|
|
4364
4425
|
}
|
|
4365
4426
|
return data;
|
|
@@ -4431,12 +4492,14 @@ async function verify(config, request, options) {
|
|
|
4431
4492
|
correlationId: apiResponse.correlationId,
|
|
4432
4493
|
attemptId: apiResponse.attemptId,
|
|
4433
4494
|
remediation: apiResponse.remediation,
|
|
4495
|
+
httpStatus: apiResponse.httpStatus,
|
|
4496
|
+
retryAfterMs: apiResponse.retryAfterMs,
|
|
4434
4497
|
urls
|
|
4435
4498
|
});
|
|
4436
4499
|
}
|
|
4437
4500
|
if (!apiResponse.access?.allowed) {
|
|
4438
4501
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
4439
|
-
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
|
|
4502
|
+
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
4440
4503
|
const result2 = {
|
|
4441
4504
|
identityVerified: idVerifiedFromBackend,
|
|
4442
4505
|
policyAllowed: false,
|
|
@@ -4448,7 +4511,10 @@ async function verify(config, request, options) {
|
|
|
4448
4511
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
4449
4512
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
4450
4513
|
guidance: {
|
|
4451
|
-
|
|
4514
|
+
// 5.12.0: a presented-but-rejected id (malformed / unknown) carries
|
|
4515
|
+
// actionable registration guidance on its failure — surface it
|
|
4516
|
+
// instead of the bare machine reason ('unknown_agent').
|
|
4517
|
+
message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
|
|
4452
4518
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
4453
4519
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
4454
4520
|
// 5.1.0: anonymous callers land on this branch — steer MCP-hosted
|
|
@@ -4548,7 +4614,7 @@ async function verify(config, request, options) {
|
|
|
4548
4614
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
4549
4615
|
documentationUrl: urls?.documentationUrl ?? ""
|
|
4550
4616
|
};
|
|
4551
|
-
} else if (result.recommendation === "step_up_required") {
|
|
4617
|
+
} else if (result.recommendation === "step_up_required" && result.identityVerified) {
|
|
4552
4618
|
result.requiresStepUp = true;
|
|
4553
4619
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
4554
4620
|
}
|
|
@@ -4577,6 +4643,217 @@ var DEFAULT_EDGE_CONFIG = Object.freeze({
|
|
|
4577
4643
|
var DEFAULT_TTL_MS = 60 * 1e3;
|
|
4578
4644
|
var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
|
|
4579
4645
|
|
|
4646
|
+
// src/edge-core/events.ts
|
|
4647
|
+
async function withBudget(promise, ms) {
|
|
4648
|
+
let timer;
|
|
4649
|
+
try {
|
|
4650
|
+
return await Promise.race([
|
|
4651
|
+
promise,
|
|
4652
|
+
new Promise((resolve) => {
|
|
4653
|
+
timer = setTimeout(() => resolve(void 0), ms);
|
|
4654
|
+
})
|
|
4655
|
+
]);
|
|
4656
|
+
} catch {
|
|
4657
|
+
return void 0;
|
|
4658
|
+
} finally {
|
|
4659
|
+
if (timer) clearTimeout(timer);
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
var destKeyOf = (d) => `${d.apiBaseUrl}\0${d.apiKey ?? ""}\0${d.counterparty}\0${d.adapter ?? ""}`;
|
|
4663
|
+
var BeaconBuffer = class {
|
|
4664
|
+
constructor(options = {}) {
|
|
4665
|
+
this.queue = [];
|
|
4666
|
+
this.droppedSinceLast = 0;
|
|
4667
|
+
this.droppedTotal = 0;
|
|
4668
|
+
this.deliveredTotal = 0;
|
|
4669
|
+
this.backoffUntil = 0;
|
|
4670
|
+
this.collapse = /* @__PURE__ */ new Map();
|
|
4671
|
+
/** Keys the backend answered 401 for — later batches go unauthenticated. */
|
|
4672
|
+
this.rejectedKeys = /* @__PURE__ */ new Set();
|
|
4673
|
+
this.opts = {
|
|
4674
|
+
maxItems: options.maxItems ?? 1e3,
|
|
4675
|
+
maxBatch: options.maxBatch ?? 100,
|
|
4676
|
+
maxAttempts: options.maxAttempts ?? 3,
|
|
4677
|
+
collapseWindowMs: options.collapseWindowMs ?? 6e4,
|
|
4678
|
+
collapseMaxKeys: options.collapseMaxKeys ?? 1e3,
|
|
4679
|
+
requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
|
|
4680
|
+
retryBackoffMs: options.retryBackoffMs ?? 1e3,
|
|
4681
|
+
now: options.now ?? Date.now
|
|
4682
|
+
};
|
|
4683
|
+
}
|
|
4684
|
+
/**
|
|
4685
|
+
* Queue one beacon. With a `collapseKey`, a repeat inside the window is
|
|
4686
|
+
* merged into a held aggregate (sent when the window closes) instead of
|
|
4687
|
+
* becoming its own item.
|
|
4688
|
+
*/
|
|
4689
|
+
enqueue(dest, item, collapseKey) {
|
|
4690
|
+
const now = this.opts.now();
|
|
4691
|
+
if (collapseKey) {
|
|
4692
|
+
const entry = this.collapse.get(collapseKey);
|
|
4693
|
+
if (entry && now - entry.firstSeenAt < this.opts.collapseWindowMs) {
|
|
4694
|
+
for (const target of [entry.first, entry.held]) {
|
|
4695
|
+
if (target && !target.inFlight && this.queue.includes(target)) {
|
|
4696
|
+
target.item.repeatCount = (target.item.repeatCount ?? 1) + 1;
|
|
4697
|
+
return;
|
|
4698
|
+
}
|
|
4699
|
+
}
|
|
4700
|
+
const held = this.push(
|
|
4701
|
+
dest,
|
|
4702
|
+
{ ...item, repeatCount: 1 },
|
|
4703
|
+
entry.firstSeenAt + this.opts.collapseWindowMs
|
|
4704
|
+
);
|
|
4705
|
+
entry.held = held;
|
|
4706
|
+
return;
|
|
4707
|
+
}
|
|
4708
|
+
this.collapse.delete(collapseKey);
|
|
4709
|
+
if (this.collapse.size >= this.opts.collapseMaxKeys) {
|
|
4710
|
+
const oldest = this.collapse.keys().next().value;
|
|
4711
|
+
if (oldest !== void 0) this.collapse.delete(oldest);
|
|
4712
|
+
}
|
|
4713
|
+
const fresh = { firstSeenAt: now };
|
|
4714
|
+
this.collapse.set(collapseKey, fresh);
|
|
4715
|
+
fresh.first = this.push(dest, item, now);
|
|
4716
|
+
return;
|
|
4717
|
+
}
|
|
4718
|
+
this.push(dest, item, now);
|
|
4719
|
+
}
|
|
4720
|
+
/**
|
|
4721
|
+
* Deliver every eligible queued item. Concurrent callers share ONE
|
|
4722
|
+
* in-flight drain (it survives the caller's budget and a Lambda freeze),
|
|
4723
|
+
* so nothing in flight is ever sent twice; items queued while it runs are
|
|
4724
|
+
* picked up by the same drain.
|
|
4725
|
+
*/
|
|
4726
|
+
flush() {
|
|
4727
|
+
if (!this.inFlight) {
|
|
4728
|
+
this.inFlight = this.drain().finally(() => {
|
|
4729
|
+
this.inFlight = void 0;
|
|
4730
|
+
});
|
|
4731
|
+
}
|
|
4732
|
+
return this.inFlight;
|
|
4733
|
+
}
|
|
4734
|
+
/** Counters for tests and diagnostics. */
|
|
4735
|
+
stats() {
|
|
4736
|
+
return {
|
|
4737
|
+
queueDepth: this.queue.length,
|
|
4738
|
+
droppedSinceLast: this.droppedSinceLast,
|
|
4739
|
+
droppedTotal: this.droppedTotal,
|
|
4740
|
+
deliveredTotal: this.deliveredTotal,
|
|
4741
|
+
flushing: this.inFlight !== void 0
|
|
4742
|
+
};
|
|
4743
|
+
}
|
|
4744
|
+
push(dest, item, eligibleAt) {
|
|
4745
|
+
while (this.queue.length >= this.opts.maxItems) this.dropOldest();
|
|
4746
|
+
const entry = {
|
|
4747
|
+
dest,
|
|
4748
|
+
destKey: destKeyOf(dest),
|
|
4749
|
+
item,
|
|
4750
|
+
attempts: 0,
|
|
4751
|
+
eligibleAt,
|
|
4752
|
+
inFlight: false
|
|
4753
|
+
};
|
|
4754
|
+
this.queue.push(entry);
|
|
4755
|
+
return entry;
|
|
4756
|
+
}
|
|
4757
|
+
dropOldest() {
|
|
4758
|
+
if (this.queue.shift()) this.countDropped(1);
|
|
4759
|
+
}
|
|
4760
|
+
countDropped(n) {
|
|
4761
|
+
this.droppedSinceLast += n;
|
|
4762
|
+
this.droppedTotal += n;
|
|
4763
|
+
}
|
|
4764
|
+
async drain() {
|
|
4765
|
+
for (; ; ) {
|
|
4766
|
+
const now = this.opts.now();
|
|
4767
|
+
if (now < this.backoffUntil) return;
|
|
4768
|
+
const batch = this.takeBatch(now);
|
|
4769
|
+
if (batch.length === 0) return;
|
|
4770
|
+
const ok = await this.send(batch);
|
|
4771
|
+
if (!ok) return;
|
|
4772
|
+
}
|
|
4773
|
+
}
|
|
4774
|
+
/** Oldest eligible item + up to maxBatch-1 more for the same destination. */
|
|
4775
|
+
takeBatch(now) {
|
|
4776
|
+
const first = this.queue.find((q) => q.eligibleAt <= now);
|
|
4777
|
+
if (!first) return [];
|
|
4778
|
+
const batch = [];
|
|
4779
|
+
const rest = [];
|
|
4780
|
+
for (const q of this.queue) {
|
|
4781
|
+
if (batch.length < this.opts.maxBatch && q.destKey === first.destKey && q.eligibleAt <= now) {
|
|
4782
|
+
q.inFlight = true;
|
|
4783
|
+
batch.push(q);
|
|
4784
|
+
} else {
|
|
4785
|
+
rest.push(q);
|
|
4786
|
+
}
|
|
4787
|
+
}
|
|
4788
|
+
this.queue = rest;
|
|
4789
|
+
return batch;
|
|
4790
|
+
}
|
|
4791
|
+
/** POST one batch. Returns false when the drain should pause (backoff). */
|
|
4792
|
+
async send(batch) {
|
|
4793
|
+
const dest = batch[0].dest;
|
|
4794
|
+
const useKey = dest.apiKey && !this.rejectedKeys.has(dest.apiKey) ? dest.apiKey : void 0;
|
|
4795
|
+
const reportedDropped = this.droppedSinceLast;
|
|
4796
|
+
const meta = {
|
|
4797
|
+
droppedSinceLast: reportedDropped,
|
|
4798
|
+
queueDepth: this.queue.length,
|
|
4799
|
+
adapter: dest.adapter ?? "edge-core",
|
|
4800
|
+
version: SDK_VERSION
|
|
4801
|
+
};
|
|
4802
|
+
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
4803
|
+
const response = await withBudget(
|
|
4804
|
+
sdkFetch(`${dest.apiBaseUrl}/verification-activity/edge-events`, {
|
|
4805
|
+
method: "POST",
|
|
4806
|
+
headers: {
|
|
4807
|
+
"Content-Type": "application/json",
|
|
4808
|
+
...useKey && { Authorization: `Bearer ${useKey}` }
|
|
4809
|
+
},
|
|
4810
|
+
body: JSON.stringify({ events: batch.map((q) => q.item), meta }),
|
|
4811
|
+
...controller && { signal: controller.signal }
|
|
4812
|
+
}),
|
|
4813
|
+
this.opts.requestTimeoutMs
|
|
4814
|
+
);
|
|
4815
|
+
if (!response) controller?.abort();
|
|
4816
|
+
const status = response?.status;
|
|
4817
|
+
for (const q of batch) q.inFlight = false;
|
|
4818
|
+
if (status !== void 0 && status >= 200 && status < 300) {
|
|
4819
|
+
this.droppedSinceLast = Math.max(0, this.droppedSinceLast - reportedDropped);
|
|
4820
|
+
this.deliveredTotal += batch.length;
|
|
4821
|
+
return true;
|
|
4822
|
+
}
|
|
4823
|
+
if (status === 401 && useKey) {
|
|
4824
|
+
this.rejectedKeys.add(useKey);
|
|
4825
|
+
this.requeue(batch, false);
|
|
4826
|
+
return true;
|
|
4827
|
+
}
|
|
4828
|
+
if (status === 429) {
|
|
4829
|
+
const retryAfter = Number(response?.headers.get("retry-after"));
|
|
4830
|
+
const waitMs = Number.isFinite(retryAfter) && retryAfter > 0 ? Math.min(retryAfter, 120) * 1e3 : 3e4;
|
|
4831
|
+
this.backoffUntil = this.opts.now() + waitMs;
|
|
4832
|
+
this.requeue(batch, false);
|
|
4833
|
+
return false;
|
|
4834
|
+
}
|
|
4835
|
+
if (status !== void 0 && status >= 400 && status < 500) {
|
|
4836
|
+
this.countDropped(batch.length);
|
|
4837
|
+
return true;
|
|
4838
|
+
}
|
|
4839
|
+
this.backoffUntil = this.opts.now() + this.opts.retryBackoffMs;
|
|
4840
|
+
this.requeue(batch, true);
|
|
4841
|
+
return false;
|
|
4842
|
+
}
|
|
4843
|
+
/** Put a failed batch back at the head of the queue (order preserved). */
|
|
4844
|
+
requeue(batch, countAttempt) {
|
|
4845
|
+
const keep = [];
|
|
4846
|
+
for (const q of batch) {
|
|
4847
|
+
if (countAttempt) q.attempts += 1;
|
|
4848
|
+
if (q.attempts >= this.opts.maxAttempts) this.countDropped(1);
|
|
4849
|
+
else keep.push(q);
|
|
4850
|
+
}
|
|
4851
|
+
this.queue = [...keep, ...this.queue];
|
|
4852
|
+
while (this.queue.length > this.opts.maxItems) this.dropOldest();
|
|
4853
|
+
}
|
|
4854
|
+
};
|
|
4855
|
+
var beaconBuffer = new BeaconBuffer();
|
|
4856
|
+
|
|
4580
4857
|
// src/adapters/express.ts
|
|
4581
4858
|
var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
4582
4859
|
|