@astrasyncai/verification-gateway 5.12.0 → 5.14.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/adapters/express.js +63 -19
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +63 -19
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.js +26 -9
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +26 -9
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.js +63 -19
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +63 -19
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.js +26 -9
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +26 -9
- 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 +53 -18
- package/dist/bin/astrasync-codex-hook.js +53 -18
- package/dist/bin/astrasync-guard.js +53 -18
- package/dist/bin/astrasync.js +54 -19
- package/dist/browser/background.js +53 -18
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +53 -18
- 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 +53 -18
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +53 -18
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +53 -18
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +53 -18
- package/dist/cursor/extension.mjs.map +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 +32 -4
- package/dist/edge-core/index.d.ts +32 -4
- package/dist/edge-core/index.js +53 -18
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +53 -18
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +53 -18
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +53 -18
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/index.d.mts +2 -12
- package/dist/index.d.ts +2 -12
- package/dist/index.js +63 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -19
- package/dist/index.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/verify.d.mts +0 -10
- package/dist/verify.d.ts +0 -10
- package/dist/verify.js +36 -10
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +36 -10
- package/dist/verify.mjs.map +1 -1
- package/package.json +3 -2
|
@@ -3752,7 +3752,7 @@ function getTrustLevel(score) {
|
|
|
3752
3752
|
}
|
|
3753
3753
|
|
|
3754
3754
|
// src/version.ts
|
|
3755
|
-
var SDK_VERSION = "5.
|
|
3755
|
+
var SDK_VERSION = "5.14.0";
|
|
3756
3756
|
|
|
3757
3757
|
// src/http.ts
|
|
3758
3758
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -3799,7 +3799,7 @@ var DEFAULT_CONFIG = {
|
|
|
3799
3799
|
};
|
|
3800
3800
|
var initCheckPerformed = false;
|
|
3801
3801
|
var deprecationWarningShown = false;
|
|
3802
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
3802
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey, counterparty) {
|
|
3803
3803
|
initCheckPerformed = true;
|
|
3804
3804
|
try {
|
|
3805
3805
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -3817,7 +3817,8 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
3817
3817
|
);
|
|
3818
3818
|
}
|
|
3819
3819
|
if (apiKey) {
|
|
3820
|
-
const
|
|
3820
|
+
const q = counterparty?.id ? `?counterpartyId=${encodeURIComponent(counterparty.id)}` : counterparty?.url ? `?counterpartyUrl=${encodeURIComponent(counterparty.url)}` : "";
|
|
3821
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check${q}`, {
|
|
3821
3822
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3822
3823
|
});
|
|
3823
3824
|
if (selfCheck.status === 401) {
|
|
@@ -3829,6 +3830,13 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
3829
3830
|
console.error(message);
|
|
3830
3831
|
} else if (selfCheck.ok) {
|
|
3831
3832
|
const body = await selfCheck.json().catch(() => ({}));
|
|
3833
|
+
if (body.counterparty && body.counterparty.canVerify === false) {
|
|
3834
|
+
const message = `[VerificationGateway] the configured AstraSync API key cannot verify for this endpoint (${body.counterparty.message ?? "endpoint not found or owned by another account"}). Every inbound agent will be turned away until the key or counterparty is corrected.`;
|
|
3835
|
+
if (strictInit) {
|
|
3836
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
3837
|
+
}
|
|
3838
|
+
console.error(message);
|
|
3839
|
+
}
|
|
3832
3840
|
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
3833
3841
|
console.warn(
|
|
3834
3842
|
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
@@ -3933,11 +3941,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
3933
3941
|
const isMisconfig = source === "merchant_misconfig";
|
|
3934
3942
|
const urls = options.urls;
|
|
3935
3943
|
const guidance = isMisconfig ? {
|
|
3936
|
-
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or
|
|
3944
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, rotated, or belongs to another account). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
3937
3945
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
3938
3946
|
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
3939
3947
|
steps: [
|
|
3940
|
-
"Report the failure to the site operator \u2014 their AstraSync API key needs
|
|
3948
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs replacing",
|
|
3941
3949
|
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
3942
3950
|
]
|
|
3943
3951
|
} : isApiError ? {
|
|
@@ -4149,12 +4157,13 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4149
4157
|
};
|
|
4150
4158
|
}
|
|
4151
4159
|
if (!response.ok) {
|
|
4152
|
-
|
|
4160
|
+
const keyMismatch = response.status === 403 && data?.error === "COUNTERPARTY_KEY_MISMATCH";
|
|
4161
|
+
if (response.status === 401 || keyMismatch) {
|
|
4153
4162
|
return {
|
|
4154
4163
|
success: false,
|
|
4155
4164
|
error: data.message || data.error || "Integration API key rejected",
|
|
4156
4165
|
misconfig: true,
|
|
4157
|
-
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
4166
|
+
misconfigCode: keyMismatch ? "counterparty_key_mismatch" : typeof data?.code === "string" ? data.code : void 0,
|
|
4158
4167
|
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
4159
4168
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
4160
4169
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
@@ -4187,14 +4196,22 @@ async function verify(config, request, options) {
|
|
|
4187
4196
|
mergedConfig.apiBaseUrl,
|
|
4188
4197
|
mergedConfig.debug,
|
|
4189
4198
|
true,
|
|
4190
|
-
mergedConfig.apiKey
|
|
4199
|
+
mergedConfig.apiKey,
|
|
4200
|
+
{
|
|
4201
|
+
id: mergedConfig.counterpartyId,
|
|
4202
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
4203
|
+
}
|
|
4191
4204
|
);
|
|
4192
4205
|
} else {
|
|
4193
4206
|
void performInitCheck(
|
|
4194
4207
|
mergedConfig.apiBaseUrl,
|
|
4195
4208
|
mergedConfig.debug,
|
|
4196
4209
|
false,
|
|
4197
|
-
mergedConfig.apiKey
|
|
4210
|
+
mergedConfig.apiKey,
|
|
4211
|
+
{
|
|
4212
|
+
id: mergedConfig.counterpartyId,
|
|
4213
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
4214
|
+
}
|
|
4198
4215
|
);
|
|
4199
4216
|
}
|
|
4200
4217
|
}
|
|
@@ -4405,6 +4422,11 @@ async function withBudget(promise, ms) {
|
|
|
4405
4422
|
if (timer) clearTimeout(timer);
|
|
4406
4423
|
}
|
|
4407
4424
|
}
|
|
4425
|
+
var CONTAINER_ID = (() => {
|
|
4426
|
+
const c = globalThis.crypto;
|
|
4427
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
4428
|
+
return `c-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
4429
|
+
})();
|
|
4408
4430
|
var destKeyOf = (d) => `${d.apiBaseUrl}\0${d.apiKey ?? ""}\0${d.counterparty}\0${d.adapter ?? ""}`;
|
|
4409
4431
|
var BeaconBuffer = class {
|
|
4410
4432
|
constructor(options = {}) {
|
|
@@ -4412,6 +4434,7 @@ var BeaconBuffer = class {
|
|
|
4412
4434
|
this.droppedSinceLast = 0;
|
|
4413
4435
|
this.droppedTotal = 0;
|
|
4414
4436
|
this.deliveredTotal = 0;
|
|
4437
|
+
this.enqueuedTotal = 0;
|
|
4415
4438
|
this.backoffUntil = 0;
|
|
4416
4439
|
this.collapse = /* @__PURE__ */ new Map();
|
|
4417
4440
|
/** Keys the backend answered 401 for — later batches go unauthenticated. */
|
|
@@ -4424,13 +4447,16 @@ var BeaconBuffer = class {
|
|
|
4424
4447
|
collapseMaxKeys: options.collapseMaxKeys ?? 1e3,
|
|
4425
4448
|
requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
|
|
4426
4449
|
retryBackoffMs: options.retryBackoffMs ?? 1e3,
|
|
4450
|
+
holdRepeats: options.holdRepeats ?? false,
|
|
4451
|
+
containerId: options.containerId ?? CONTAINER_ID,
|
|
4427
4452
|
now: options.now ?? Date.now
|
|
4428
4453
|
};
|
|
4429
4454
|
}
|
|
4430
4455
|
/**
|
|
4431
4456
|
* Queue one beacon. With a `collapseKey`, a repeat inside the window is
|
|
4432
|
-
* merged into
|
|
4433
|
-
*
|
|
4457
|
+
* merged into this key's item while that item is still queued (not yet in
|
|
4458
|
+
* flight). Once it has left, the repeat becomes a new item, sendable on
|
|
4459
|
+
* this flush — nothing waits for a later invocation (round 27.6).
|
|
4434
4460
|
*/
|
|
4435
4461
|
enqueue(dest, item, collapseKey) {
|
|
4436
4462
|
const now = this.opts.now();
|
|
@@ -4443,12 +4469,15 @@ var BeaconBuffer = class {
|
|
|
4443
4469
|
return;
|
|
4444
4470
|
}
|
|
4445
4471
|
}
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4472
|
+
if (this.opts.holdRepeats) {
|
|
4473
|
+
entry.held = this.push(
|
|
4474
|
+
dest,
|
|
4475
|
+
{ ...item, repeatCount: 1 },
|
|
4476
|
+
entry.firstSeenAt + this.opts.collapseWindowMs
|
|
4477
|
+
);
|
|
4478
|
+
return;
|
|
4479
|
+
}
|
|
4480
|
+
entry.first = this.push(dest, { ...item, repeatCount: 1 }, now);
|
|
4452
4481
|
return;
|
|
4453
4482
|
}
|
|
4454
4483
|
this.collapse.delete(collapseKey);
|
|
@@ -4484,6 +4513,7 @@ var BeaconBuffer = class {
|
|
|
4484
4513
|
droppedSinceLast: this.droppedSinceLast,
|
|
4485
4514
|
droppedTotal: this.droppedTotal,
|
|
4486
4515
|
deliveredTotal: this.deliveredTotal,
|
|
4516
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
4487
4517
|
flushing: this.inFlight !== void 0
|
|
4488
4518
|
};
|
|
4489
4519
|
}
|
|
@@ -4498,6 +4528,7 @@ var BeaconBuffer = class {
|
|
|
4498
4528
|
inFlight: false
|
|
4499
4529
|
};
|
|
4500
4530
|
this.queue.push(entry);
|
|
4531
|
+
this.enqueuedTotal += 1;
|
|
4501
4532
|
return entry;
|
|
4502
4533
|
}
|
|
4503
4534
|
dropOldest() {
|
|
@@ -4543,7 +4574,11 @@ var BeaconBuffer = class {
|
|
|
4543
4574
|
droppedSinceLast: reportedDropped,
|
|
4544
4575
|
queueDepth: this.queue.length,
|
|
4545
4576
|
adapter: dest.adapter ?? "edge-core",
|
|
4546
|
-
version: SDK_VERSION
|
|
4577
|
+
version: SDK_VERSION,
|
|
4578
|
+
containerId: this.opts.containerId,
|
|
4579
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
4580
|
+
deliveredTotal: this.deliveredTotal,
|
|
4581
|
+
droppedTotal: this.droppedTotal
|
|
4547
4582
|
};
|
|
4548
4583
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
4549
4584
|
const response = await withBudget(
|
|
@@ -3751,7 +3751,7 @@ function getTrustLevel(score) {
|
|
|
3751
3751
|
}
|
|
3752
3752
|
|
|
3753
3753
|
// src/version.ts
|
|
3754
|
-
var SDK_VERSION = "5.
|
|
3754
|
+
var SDK_VERSION = "5.14.0";
|
|
3755
3755
|
|
|
3756
3756
|
// src/http.ts
|
|
3757
3757
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -3798,7 +3798,7 @@ var DEFAULT_CONFIG = {
|
|
|
3798
3798
|
};
|
|
3799
3799
|
var initCheckPerformed = false;
|
|
3800
3800
|
var deprecationWarningShown = false;
|
|
3801
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
3801
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey, counterparty) {
|
|
3802
3802
|
initCheckPerformed = true;
|
|
3803
3803
|
try {
|
|
3804
3804
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -3816,7 +3816,8 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
3816
3816
|
);
|
|
3817
3817
|
}
|
|
3818
3818
|
if (apiKey) {
|
|
3819
|
-
const
|
|
3819
|
+
const q = counterparty?.id ? `?counterpartyId=${encodeURIComponent(counterparty.id)}` : counterparty?.url ? `?counterpartyUrl=${encodeURIComponent(counterparty.url)}` : "";
|
|
3820
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check${q}`, {
|
|
3820
3821
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3821
3822
|
});
|
|
3822
3823
|
if (selfCheck.status === 401) {
|
|
@@ -3828,6 +3829,13 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
3828
3829
|
console.error(message);
|
|
3829
3830
|
} else if (selfCheck.ok) {
|
|
3830
3831
|
const body = await selfCheck.json().catch(() => ({}));
|
|
3832
|
+
if (body.counterparty && body.counterparty.canVerify === false) {
|
|
3833
|
+
const message = `[VerificationGateway] the configured AstraSync API key cannot verify for this endpoint (${body.counterparty.message ?? "endpoint not found or owned by another account"}). Every inbound agent will be turned away until the key or counterparty is corrected.`;
|
|
3834
|
+
if (strictInit) {
|
|
3835
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
3836
|
+
}
|
|
3837
|
+
console.error(message);
|
|
3838
|
+
}
|
|
3831
3839
|
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
3832
3840
|
console.warn(
|
|
3833
3841
|
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
@@ -3932,11 +3940,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
3932
3940
|
const isMisconfig = source === "merchant_misconfig";
|
|
3933
3941
|
const urls = options.urls;
|
|
3934
3942
|
const guidance = isMisconfig ? {
|
|
3935
|
-
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or
|
|
3943
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, rotated, or belongs to another account). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
3936
3944
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
3937
3945
|
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
3938
3946
|
steps: [
|
|
3939
|
-
"Report the failure to the site operator \u2014 their AstraSync API key needs
|
|
3947
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs replacing",
|
|
3940
3948
|
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
3941
3949
|
]
|
|
3942
3950
|
} : isApiError ? {
|
|
@@ -4148,12 +4156,13 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
4148
4156
|
};
|
|
4149
4157
|
}
|
|
4150
4158
|
if (!response.ok) {
|
|
4151
|
-
|
|
4159
|
+
const keyMismatch = response.status === 403 && data?.error === "COUNTERPARTY_KEY_MISMATCH";
|
|
4160
|
+
if (response.status === 401 || keyMismatch) {
|
|
4152
4161
|
return {
|
|
4153
4162
|
success: false,
|
|
4154
4163
|
error: data.message || data.error || "Integration API key rejected",
|
|
4155
4164
|
misconfig: true,
|
|
4156
|
-
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
4165
|
+
misconfigCode: keyMismatch ? "counterparty_key_mismatch" : typeof data?.code === "string" ? data.code : void 0,
|
|
4157
4166
|
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
4158
4167
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
4159
4168
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
@@ -4186,14 +4195,22 @@ async function verify(config, request, options) {
|
|
|
4186
4195
|
mergedConfig.apiBaseUrl,
|
|
4187
4196
|
mergedConfig.debug,
|
|
4188
4197
|
true,
|
|
4189
|
-
mergedConfig.apiKey
|
|
4198
|
+
mergedConfig.apiKey,
|
|
4199
|
+
{
|
|
4200
|
+
id: mergedConfig.counterpartyId,
|
|
4201
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
4202
|
+
}
|
|
4190
4203
|
);
|
|
4191
4204
|
} else {
|
|
4192
4205
|
void performInitCheck(
|
|
4193
4206
|
mergedConfig.apiBaseUrl,
|
|
4194
4207
|
mergedConfig.debug,
|
|
4195
4208
|
false,
|
|
4196
|
-
mergedConfig.apiKey
|
|
4209
|
+
mergedConfig.apiKey,
|
|
4210
|
+
{
|
|
4211
|
+
id: mergedConfig.counterpartyId,
|
|
4212
|
+
url: mergedConfig.counterpartyUrl ?? request.counterpartyUrl
|
|
4213
|
+
}
|
|
4197
4214
|
);
|
|
4198
4215
|
}
|
|
4199
4216
|
}
|
|
@@ -4404,6 +4421,11 @@ async function withBudget(promise, ms) {
|
|
|
4404
4421
|
if (timer) clearTimeout(timer);
|
|
4405
4422
|
}
|
|
4406
4423
|
}
|
|
4424
|
+
var CONTAINER_ID = (() => {
|
|
4425
|
+
const c = globalThis.crypto;
|
|
4426
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
4427
|
+
return `c-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
4428
|
+
})();
|
|
4407
4429
|
var destKeyOf = (d) => `${d.apiBaseUrl}\0${d.apiKey ?? ""}\0${d.counterparty}\0${d.adapter ?? ""}`;
|
|
4408
4430
|
var BeaconBuffer = class {
|
|
4409
4431
|
constructor(options = {}) {
|
|
@@ -4411,6 +4433,7 @@ var BeaconBuffer = class {
|
|
|
4411
4433
|
this.droppedSinceLast = 0;
|
|
4412
4434
|
this.droppedTotal = 0;
|
|
4413
4435
|
this.deliveredTotal = 0;
|
|
4436
|
+
this.enqueuedTotal = 0;
|
|
4414
4437
|
this.backoffUntil = 0;
|
|
4415
4438
|
this.collapse = /* @__PURE__ */ new Map();
|
|
4416
4439
|
/** Keys the backend answered 401 for — later batches go unauthenticated. */
|
|
@@ -4423,13 +4446,16 @@ var BeaconBuffer = class {
|
|
|
4423
4446
|
collapseMaxKeys: options.collapseMaxKeys ?? 1e3,
|
|
4424
4447
|
requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
|
|
4425
4448
|
retryBackoffMs: options.retryBackoffMs ?? 1e3,
|
|
4449
|
+
holdRepeats: options.holdRepeats ?? false,
|
|
4450
|
+
containerId: options.containerId ?? CONTAINER_ID,
|
|
4426
4451
|
now: options.now ?? Date.now
|
|
4427
4452
|
};
|
|
4428
4453
|
}
|
|
4429
4454
|
/**
|
|
4430
4455
|
* Queue one beacon. With a `collapseKey`, a repeat inside the window is
|
|
4431
|
-
* merged into
|
|
4432
|
-
*
|
|
4456
|
+
* merged into this key's item while that item is still queued (not yet in
|
|
4457
|
+
* flight). Once it has left, the repeat becomes a new item, sendable on
|
|
4458
|
+
* this flush — nothing waits for a later invocation (round 27.6).
|
|
4433
4459
|
*/
|
|
4434
4460
|
enqueue(dest, item, collapseKey) {
|
|
4435
4461
|
const now = this.opts.now();
|
|
@@ -4442,12 +4468,15 @@ var BeaconBuffer = class {
|
|
|
4442
4468
|
return;
|
|
4443
4469
|
}
|
|
4444
4470
|
}
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4471
|
+
if (this.opts.holdRepeats) {
|
|
4472
|
+
entry.held = this.push(
|
|
4473
|
+
dest,
|
|
4474
|
+
{ ...item, repeatCount: 1 },
|
|
4475
|
+
entry.firstSeenAt + this.opts.collapseWindowMs
|
|
4476
|
+
);
|
|
4477
|
+
return;
|
|
4478
|
+
}
|
|
4479
|
+
entry.first = this.push(dest, { ...item, repeatCount: 1 }, now);
|
|
4451
4480
|
return;
|
|
4452
4481
|
}
|
|
4453
4482
|
this.collapse.delete(collapseKey);
|
|
@@ -4483,6 +4512,7 @@ var BeaconBuffer = class {
|
|
|
4483
4512
|
droppedSinceLast: this.droppedSinceLast,
|
|
4484
4513
|
droppedTotal: this.droppedTotal,
|
|
4485
4514
|
deliveredTotal: this.deliveredTotal,
|
|
4515
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
4486
4516
|
flushing: this.inFlight !== void 0
|
|
4487
4517
|
};
|
|
4488
4518
|
}
|
|
@@ -4497,6 +4527,7 @@ var BeaconBuffer = class {
|
|
|
4497
4527
|
inFlight: false
|
|
4498
4528
|
};
|
|
4499
4529
|
this.queue.push(entry);
|
|
4530
|
+
this.enqueuedTotal += 1;
|
|
4500
4531
|
return entry;
|
|
4501
4532
|
}
|
|
4502
4533
|
dropOldest() {
|
|
@@ -4542,7 +4573,11 @@ var BeaconBuffer = class {
|
|
|
4542
4573
|
droppedSinceLast: reportedDropped,
|
|
4543
4574
|
queueDepth: this.queue.length,
|
|
4544
4575
|
adapter: dest.adapter ?? "edge-core",
|
|
4545
|
-
version: SDK_VERSION
|
|
4576
|
+
version: SDK_VERSION,
|
|
4577
|
+
containerId: this.opts.containerId,
|
|
4578
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
4579
|
+
deliveredTotal: this.deliveredTotal,
|
|
4580
|
+
droppedTotal: this.droppedTotal
|
|
4546
4581
|
};
|
|
4547
4582
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
4548
4583
|
const response = await withBudget(
|
|
@@ -3713,7 +3713,7 @@ Policy saved to ${outputPath}`);
|
|
|
3713
3713
|
};
|
|
3714
3714
|
|
|
3715
3715
|
// src/version.ts
|
|
3716
|
-
var SDK_VERSION = "5.
|
|
3716
|
+
var SDK_VERSION = "5.14.0";
|
|
3717
3717
|
|
|
3718
3718
|
// src/http.ts
|
|
3719
3719
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -4664,7 +4664,7 @@ var DEFAULT_CONFIG = {
|
|
|
4664
4664
|
};
|
|
4665
4665
|
var initCheckPerformed = false;
|
|
4666
4666
|
var deprecationWarningShown = false;
|
|
4667
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
4667
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey, counterparty) {
|
|
4668
4668
|
initCheckPerformed = true;
|
|
4669
4669
|
try {
|
|
4670
4670
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -4682,7 +4682,8 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
4682
4682
|
);
|
|
4683
4683
|
}
|
|
4684
4684
|
if (apiKey) {
|
|
4685
|
-
const
|
|
4685
|
+
const q = counterparty?.id ? `?counterpartyId=${encodeURIComponent(counterparty.id)}` : counterparty?.url ? `?counterpartyUrl=${encodeURIComponent(counterparty.url)}` : "";
|
|
4686
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check${q}`, {
|
|
4686
4687
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4687
4688
|
});
|
|
4688
4689
|
if (selfCheck.status === 401) {
|
|
@@ -4694,6 +4695,13 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
4694
4695
|
console.error(message);
|
|
4695
4696
|
} else if (selfCheck.ok) {
|
|
4696
4697
|
const body = await selfCheck.json().catch(() => ({}));
|
|
4698
|
+
if (body.counterparty && body.counterparty.canVerify === false) {
|
|
4699
|
+
const message = `[VerificationGateway] the configured AstraSync API key cannot verify for this endpoint (${body.counterparty.message ?? "endpoint not found or owned by another account"}). Every inbound agent will be turned away until the key or counterparty is corrected.`;
|
|
4700
|
+
if (strictInit) {
|
|
4701
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
4702
|
+
}
|
|
4703
|
+
console.error(message);
|
|
4704
|
+
}
|
|
4697
4705
|
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
4698
4706
|
console.warn(
|
|
4699
4707
|
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
@@ -4798,11 +4806,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
4798
4806
|
const isMisconfig = source === "merchant_misconfig";
|
|
4799
4807
|
const urls = options.urls;
|
|
4800
4808
|
const guidance = isMisconfig ? {
|
|
4801
|
-
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or
|
|
4809
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, rotated, or belongs to another account). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
4802
4810
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
4803
4811
|
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
4804
4812
|
steps: [
|
|
4805
|
-
"Report the failure to the site operator \u2014 their AstraSync API key needs
|
|
4813
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs replacing",
|
|
4806
4814
|
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
4807
4815
|
]
|
|
4808
4816
|
} : isApiError ? {
|
|
@@ -5014,12 +5022,13 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
5014
5022
|
};
|
|
5015
5023
|
}
|
|
5016
5024
|
if (!response.ok) {
|
|
5017
|
-
|
|
5025
|
+
const keyMismatch = response.status === 403 && data?.error === "COUNTERPARTY_KEY_MISMATCH";
|
|
5026
|
+
if (response.status === 401 || keyMismatch) {
|
|
5018
5027
|
return {
|
|
5019
5028
|
success: false,
|
|
5020
5029
|
error: data.message || data.error || "Integration API key rejected",
|
|
5021
5030
|
misconfig: true,
|
|
5022
|
-
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
5031
|
+
misconfigCode: keyMismatch ? "counterparty_key_mismatch" : typeof data?.code === "string" ? data.code : void 0,
|
|
5023
5032
|
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
5024
5033
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
5025
5034
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
@@ -5052,14 +5061,22 @@ async function verify(config, request2, options) {
|
|
|
5052
5061
|
mergedConfig.apiBaseUrl,
|
|
5053
5062
|
mergedConfig.debug,
|
|
5054
5063
|
true,
|
|
5055
|
-
mergedConfig.apiKey
|
|
5064
|
+
mergedConfig.apiKey,
|
|
5065
|
+
{
|
|
5066
|
+
id: mergedConfig.counterpartyId,
|
|
5067
|
+
url: mergedConfig.counterpartyUrl ?? request2.counterpartyUrl
|
|
5068
|
+
}
|
|
5056
5069
|
);
|
|
5057
5070
|
} else {
|
|
5058
5071
|
void performInitCheck(
|
|
5059
5072
|
mergedConfig.apiBaseUrl,
|
|
5060
5073
|
mergedConfig.debug,
|
|
5061
5074
|
false,
|
|
5062
|
-
mergedConfig.apiKey
|
|
5075
|
+
mergedConfig.apiKey,
|
|
5076
|
+
{
|
|
5077
|
+
id: mergedConfig.counterpartyId,
|
|
5078
|
+
url: mergedConfig.counterpartyUrl ?? request2.counterpartyUrl
|
|
5079
|
+
}
|
|
5063
5080
|
);
|
|
5064
5081
|
}
|
|
5065
5082
|
}
|
|
@@ -5270,6 +5287,11 @@ async function withBudget(promise, ms) {
|
|
|
5270
5287
|
if (timer) clearTimeout(timer);
|
|
5271
5288
|
}
|
|
5272
5289
|
}
|
|
5290
|
+
var CONTAINER_ID = (() => {
|
|
5291
|
+
const c = globalThis.crypto;
|
|
5292
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
5293
|
+
return `c-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
5294
|
+
})();
|
|
5273
5295
|
var destKeyOf = (d) => `${d.apiBaseUrl}\0${d.apiKey ?? ""}\0${d.counterparty}\0${d.adapter ?? ""}`;
|
|
5274
5296
|
var BeaconBuffer = class {
|
|
5275
5297
|
constructor(options = {}) {
|
|
@@ -5277,6 +5299,7 @@ var BeaconBuffer = class {
|
|
|
5277
5299
|
this.droppedSinceLast = 0;
|
|
5278
5300
|
this.droppedTotal = 0;
|
|
5279
5301
|
this.deliveredTotal = 0;
|
|
5302
|
+
this.enqueuedTotal = 0;
|
|
5280
5303
|
this.backoffUntil = 0;
|
|
5281
5304
|
this.collapse = /* @__PURE__ */ new Map();
|
|
5282
5305
|
/** Keys the backend answered 401 for — later batches go unauthenticated. */
|
|
@@ -5289,13 +5312,16 @@ var BeaconBuffer = class {
|
|
|
5289
5312
|
collapseMaxKeys: options.collapseMaxKeys ?? 1e3,
|
|
5290
5313
|
requestTimeoutMs: options.requestTimeoutMs ?? 1e4,
|
|
5291
5314
|
retryBackoffMs: options.retryBackoffMs ?? 1e3,
|
|
5315
|
+
holdRepeats: options.holdRepeats ?? false,
|
|
5316
|
+
containerId: options.containerId ?? CONTAINER_ID,
|
|
5292
5317
|
now: options.now ?? Date.now
|
|
5293
5318
|
};
|
|
5294
5319
|
}
|
|
5295
5320
|
/**
|
|
5296
5321
|
* Queue one beacon. With a `collapseKey`, a repeat inside the window is
|
|
5297
|
-
* merged into
|
|
5298
|
-
*
|
|
5322
|
+
* merged into this key's item while that item is still queued (not yet in
|
|
5323
|
+
* flight). Once it has left, the repeat becomes a new item, sendable on
|
|
5324
|
+
* this flush — nothing waits for a later invocation (round 27.6).
|
|
5299
5325
|
*/
|
|
5300
5326
|
enqueue(dest, item, collapseKey) {
|
|
5301
5327
|
const now = this.opts.now();
|
|
@@ -5308,12 +5334,15 @@ var BeaconBuffer = class {
|
|
|
5308
5334
|
return;
|
|
5309
5335
|
}
|
|
5310
5336
|
}
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5337
|
+
if (this.opts.holdRepeats) {
|
|
5338
|
+
entry.held = this.push(
|
|
5339
|
+
dest,
|
|
5340
|
+
{ ...item, repeatCount: 1 },
|
|
5341
|
+
entry.firstSeenAt + this.opts.collapseWindowMs
|
|
5342
|
+
);
|
|
5343
|
+
return;
|
|
5344
|
+
}
|
|
5345
|
+
entry.first = this.push(dest, { ...item, repeatCount: 1 }, now);
|
|
5317
5346
|
return;
|
|
5318
5347
|
}
|
|
5319
5348
|
this.collapse.delete(collapseKey);
|
|
@@ -5349,6 +5378,7 @@ var BeaconBuffer = class {
|
|
|
5349
5378
|
droppedSinceLast: this.droppedSinceLast,
|
|
5350
5379
|
droppedTotal: this.droppedTotal,
|
|
5351
5380
|
deliveredTotal: this.deliveredTotal,
|
|
5381
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
5352
5382
|
flushing: this.inFlight !== void 0
|
|
5353
5383
|
};
|
|
5354
5384
|
}
|
|
@@ -5363,6 +5393,7 @@ var BeaconBuffer = class {
|
|
|
5363
5393
|
inFlight: false
|
|
5364
5394
|
};
|
|
5365
5395
|
this.queue.push(entry);
|
|
5396
|
+
this.enqueuedTotal += 1;
|
|
5366
5397
|
return entry;
|
|
5367
5398
|
}
|
|
5368
5399
|
dropOldest() {
|
|
@@ -5408,7 +5439,11 @@ var BeaconBuffer = class {
|
|
|
5408
5439
|
droppedSinceLast: reportedDropped,
|
|
5409
5440
|
queueDepth: this.queue.length,
|
|
5410
5441
|
adapter: dest.adapter ?? "edge-core",
|
|
5411
|
-
version: SDK_VERSION
|
|
5442
|
+
version: SDK_VERSION,
|
|
5443
|
+
containerId: this.opts.containerId,
|
|
5444
|
+
enqueuedTotal: this.enqueuedTotal,
|
|
5445
|
+
deliveredTotal: this.deliveredTotal,
|
|
5446
|
+
droppedTotal: this.droppedTotal
|
|
5412
5447
|
};
|
|
5413
5448
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
5414
5449
|
const response = await withBudget(
|