@boxrouter/sdk 0.0.0-stage → 0.12.190
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/LICENSE +202 -0
- package/NOTICE +40 -0
- package/README.md +508 -2
- package/dist/addresses.d.ts +5 -0
- package/dist/addresses.js +10 -0
- package/dist/api-error.d.ts +62 -0
- package/dist/api-error.js +264 -0
- package/dist/boxrouter.d.ts +68 -0
- package/dist/boxrouter.js +291 -0
- package/dist/browser-session/index.d.ts +17 -0
- package/dist/browser-session/index.js +48 -0
- package/dist/browser-session/operations.gen.d.ts +272 -0
- package/dist/browser-session/operations.gen.js +58 -0
- package/dist/browser-session/responseContracts/api_keys.d.ts +2 -0
- package/dist/browser-session/responseContracts/api_keys.js +10 -0
- package/dist/browser-session/responseContracts/credits.d.ts +2 -0
- package/dist/browser-session/responseContracts/credits.js +8 -0
- package/dist/browser-session/responseContracts/github.d.ts +2 -0
- package/dist/browser-session/responseContracts/github.js +11 -0
- package/dist/browser-session/responseContracts/identity.d.ts +2 -0
- package/dist/browser-session/responseContracts/identity.js +30 -0
- package/dist/browser-session/responseContracts/organizations.d.ts +2 -0
- package/dist/browser-session/responseContracts/organizations.js +17 -0
- package/dist/browser-session/responseContracts/privacy.d.ts +2 -0
- package/dist/browser-session/responseContracts/privacy.js +7 -0
- package/dist/browser-session/responseContracts.gen.d.ts +3 -0
- package/dist/browser-session/responseContracts.gen.js +10 -0
- package/dist/browser-session/responseValidators/api_keys-diagnostics.cjs +1 -0
- package/dist/browser-session/responseValidators/api_keys-diagnostics.d.cts +4 -0
- package/dist/browser-session/responseValidators/api_keys.cjs +2 -0
- package/dist/browser-session/responseValidators/api_keys.d.cts +4 -0
- package/dist/browser-session/responseValidators/credits-diagnostics.cjs +1 -0
- package/dist/browser-session/responseValidators/credits-diagnostics.d.cts +3 -0
- package/dist/browser-session/responseValidators/credits.cjs +2 -0
- package/dist/browser-session/responseValidators/credits.d.cts +3 -0
- package/dist/browser-session/responseValidators/github-diagnostics.cjs +1 -0
- package/dist/browser-session/responseValidators/github-diagnostics.d.cts +3 -0
- package/dist/browser-session/responseValidators/github.cjs +2 -0
- package/dist/browser-session/responseValidators/github.d.cts +3 -0
- package/dist/browser-session/responseValidators/identity-diagnostics.cjs +1 -0
- package/dist/browser-session/responseValidators/identity-diagnostics.d.cts +23 -0
- package/dist/browser-session/responseValidators/identity.cjs +2 -0
- package/dist/browser-session/responseValidators/identity.d.cts +23 -0
- package/dist/browser-session/responseValidators/organizations-diagnostics.cjs +1 -0
- package/dist/browser-session/responseValidators/organizations-diagnostics.d.cts +15 -0
- package/dist/browser-session/responseValidators/organizations.cjs +2 -0
- package/dist/browser-session/responseValidators/organizations.d.cts +15 -0
- package/dist/browser-session/responseValidators/privacy-diagnostics.cjs +1 -0
- package/dist/browser-session/responseValidators/privacy-diagnostics.d.cts +2 -0
- package/dist/browser-session/responseValidators/privacy.cjs +2 -0
- package/dist/browser-session/responseValidators/privacy.d.cts +2 -0
- package/dist/client/client.gen.d.ts +2 -0
- package/dist/client/client.gen.js +168 -0
- package/dist/client/index.d.ts +10 -0
- package/dist/client/index.js +17 -0
- package/dist/client/types.gen.d.ts +120 -0
- package/dist/client/types.gen.js +3 -0
- package/dist/client/utils.gen.d.ts +37 -0
- package/dist/client/utils.gen.js +239 -0
- package/dist/client.gen.d.ts +12 -0
- package/dist/client.gen.js +6 -0
- package/dist/command-check.gen.d.ts +14 -0
- package/dist/command-check.gen.js +23 -0
- package/dist/command-input.gen.d.ts +6 -0
- package/dist/command-input.gen.js +45 -0
- package/dist/core/auth.gen.d.ts +25 -0
- package/dist/core/auth.gen.js +18 -0
- package/dist/core/binaryStream.d.ts +8 -0
- package/dist/core/binaryStream.js +76 -0
- package/dist/core/bodySerializer.gen.d.ts +25 -0
- package/dist/core/bodySerializer.gen.js +60 -0
- package/dist/core/commandValidators.cjs +1 -0
- package/dist/core/commandValidators.d.cts +14 -0
- package/dist/core/eventValidation.d.ts +17 -0
- package/dist/core/eventValidation.js +56 -0
- package/dist/core/eventValidators.cjs +1 -0
- package/dist/core/eventValidators.d.cts +2 -0
- package/dist/core/json.d.ts +3 -0
- package/dist/core/json.js +33 -0
- package/dist/core/params.gen.d.ts +43 -0
- package/dist/core/params.gen.js +112 -0
- package/dist/core/pathSerializer.gen.d.ts +33 -0
- package/dist/core/pathSerializer.gen.js +115 -0
- package/dist/core/queryKeySerializer.gen.d.ts +18 -0
- package/dist/core/queryKeySerializer.gen.js +98 -0
- package/dist/core/responseContracts/actions.d.ts +2 -0
- package/dist/core/responseContracts/actions.js +30 -0
- package/dist/core/responseContracts/agents.d.ts +2 -0
- package/dist/core/responseContracts/agents.js +7 -0
- package/dist/core/responseContracts/artifacts.d.ts +2 -0
- package/dist/core/responseContracts/artifacts.js +8 -0
- package/dist/core/responseContracts/commands.d.ts +2 -0
- package/dist/core/responseContracts/commands.js +6 -0
- package/dist/core/responseContracts/credits.d.ts +2 -0
- package/dist/core/responseContracts/credits.js +27 -0
- package/dist/core/responseContracts/files.d.ts +2 -0
- package/dist/core/responseContracts/files.js +15 -0
- package/dist/core/responseContracts/github.d.ts +2 -0
- package/dist/core/responseContracts/github.js +8 -0
- package/dist/core/responseContracts/images.d.ts +2 -0
- package/dist/core/responseContracts/images.js +8 -0
- package/dist/core/responseContracts/launchRuns.d.ts +2 -0
- package/dist/core/responseContracts/launchRuns.js +10 -0
- package/dist/core/responseContracts/launches.d.ts +2 -0
- package/dist/core/responseContracts/launches.js +10 -0
- package/dist/core/responseContracts/operations.d.ts +2 -0
- package/dist/core/responseContracts/operations.js +7 -0
- package/dist/core/responseContracts/previews.d.ts +2 -0
- package/dist/core/responseContracts/previews.js +8 -0
- package/dist/core/responseContracts/pricing.d.ts +2 -0
- package/dist/core/responseContracts/pricing.js +6 -0
- package/dist/core/responseContracts/processes.d.ts +2 -0
- package/dist/core/responseContracts/processes.js +11 -0
- package/dist/core/responseContracts/provider_accounts.d.ts +2 -0
- package/dist/core/responseContracts/provider_accounts.js +13 -0
- package/dist/core/responseContracts/providers.d.ts +2 -0
- package/dist/core/responseContracts/providers.js +6 -0
- package/dist/core/responseContracts/routing.d.ts +2 -0
- package/dist/core/responseContracts/routing.js +8 -0
- package/dist/core/responseContracts/sandboxes.d.ts +2 -0
- package/dist/core/responseContracts/sandboxes.js +15 -0
- package/dist/core/responseContracts/secrets.d.ts +2 -0
- package/dist/core/responseContracts/secrets.js +8 -0
- package/dist/core/responseContracts/spend_limits.d.ts +2 -0
- package/dist/core/responseContracts/spend_limits.js +8 -0
- package/dist/core/responseContracts/terminals.d.ts +2 -0
- package/dist/core/responseContracts/terminals.js +11 -0
- package/dist/core/responseContracts/usage.d.ts +2 -0
- package/dist/core/responseContracts/usage.js +7 -0
- package/dist/core/responseContracts/volumes.d.ts +2 -0
- package/dist/core/responseContracts/volumes.js +19 -0
- package/dist/core/responseContracts.gen.d.ts +3 -0
- package/dist/core/responseContracts.gen.js +27 -0
- package/dist/core/responseModes.d.ts +19 -0
- package/dist/core/responseModes.js +13 -0
- package/dist/core/responseValidation.d.ts +44 -0
- package/dist/core/responseValidation.js +174 -0
- package/dist/core/responseValidators/actions-diagnostics.cjs +4 -0
- package/dist/core/responseValidators/actions-diagnostics.d.cts +24 -0
- package/dist/core/responseValidators/actions.cjs +2 -0
- package/dist/core/responseValidators/actions.d.cts +24 -0
- package/dist/core/responseValidators/agents-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/agents-diagnostics.d.cts +2 -0
- package/dist/core/responseValidators/agents.cjs +2 -0
- package/dist/core/responseValidators/agents.d.cts +2 -0
- package/dist/core/responseValidators/artifacts-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/artifacts-diagnostics.d.cts +2 -0
- package/dist/core/responseValidators/artifacts.cjs +2 -0
- package/dist/core/responseValidators/artifacts.d.cts +2 -0
- package/dist/core/responseValidators/commands-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/commands-diagnostics.d.cts +1 -0
- package/dist/core/responseValidators/commands.cjs +2 -0
- package/dist/core/responseValidators/commands.d.cts +1 -0
- package/dist/core/responseValidators/compact.cjs +122 -0
- package/dist/core/responseValidators/credits-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/credits-diagnostics.d.cts +21 -0
- package/dist/core/responseValidators/credits.cjs +2 -0
- package/dist/core/responseValidators/credits.d.cts +21 -0
- package/dist/core/responseValidators/files-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/files-diagnostics.d.cts +5 -0
- package/dist/core/responseValidators/files.cjs +2 -0
- package/dist/core/responseValidators/files.d.cts +5 -0
- package/dist/core/responseValidators/github-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/github-diagnostics.d.cts +2 -0
- package/dist/core/responseValidators/github.cjs +2 -0
- package/dist/core/responseValidators/github.d.cts +2 -0
- package/dist/core/responseValidators/images-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/images-diagnostics.d.cts +3 -0
- package/dist/core/responseValidators/images.cjs +2 -0
- package/dist/core/responseValidators/images.d.cts +3 -0
- package/dist/core/responseValidators/launchRuns-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/launchRuns-diagnostics.d.cts +5 -0
- package/dist/core/responseValidators/launchRuns.cjs +2 -0
- package/dist/core/responseValidators/launchRuns.d.cts +5 -0
- package/dist/core/responseValidators/launches-diagnostics.cjs +10 -0
- package/dist/core/responseValidators/launches-diagnostics.d.cts +5 -0
- package/dist/core/responseValidators/launches.cjs +2 -0
- package/dist/core/responseValidators/launches.d.cts +5 -0
- package/dist/core/responseValidators/operations-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/operations-diagnostics.d.cts +2 -0
- package/dist/core/responseValidators/operations.cjs +2 -0
- package/dist/core/responseValidators/operations.d.cts +2 -0
- package/dist/core/responseValidators/previews-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/previews-diagnostics.d.cts +3 -0
- package/dist/core/responseValidators/previews.cjs +2 -0
- package/dist/core/responseValidators/previews.d.cts +3 -0
- package/dist/core/responseValidators/pricing-diagnostics.cjs +7 -0
- package/dist/core/responseValidators/pricing-diagnostics.d.cts +1 -0
- package/dist/core/responseValidators/pricing.cjs +2 -0
- package/dist/core/responseValidators/pricing.d.cts +1 -0
- package/dist/core/responseValidators/processes-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/processes-diagnostics.d.cts +2 -0
- package/dist/core/responseValidators/processes.cjs +2 -0
- package/dist/core/responseValidators/processes.d.cts +2 -0
- package/dist/core/responseValidators/provider_accounts-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/provider_accounts-diagnostics.d.cts +8 -0
- package/dist/core/responseValidators/provider_accounts.cjs +2 -0
- package/dist/core/responseValidators/provider_accounts.d.cts +8 -0
- package/dist/core/responseValidators/providers-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/providers-diagnostics.d.cts +1 -0
- package/dist/core/responseValidators/providers.cjs +2 -0
- package/dist/core/responseValidators/providers.d.cts +1 -0
- package/dist/core/responseValidators/routing-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/routing-diagnostics.d.cts +3 -0
- package/dist/core/responseValidators/routing.cjs +2 -0
- package/dist/core/responseValidators/routing.d.cts +3 -0
- package/dist/core/responseValidators/sandboxes-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/sandboxes-diagnostics.d.cts +10 -0
- package/dist/core/responseValidators/sandboxes.cjs +2 -0
- package/dist/core/responseValidators/sandboxes.d.cts +10 -0
- package/dist/core/responseValidators/secrets-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/secrets-diagnostics.d.cts +1 -0
- package/dist/core/responseValidators/secrets.cjs +2 -0
- package/dist/core/responseValidators/secrets.d.cts +1 -0
- package/dist/core/responseValidators/spend_limits-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/spend_limits-diagnostics.d.cts +3 -0
- package/dist/core/responseValidators/spend_limits.cjs +2 -0
- package/dist/core/responseValidators/spend_limits.d.cts +3 -0
- package/dist/core/responseValidators/terminals-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/terminals-diagnostics.d.cts +2 -0
- package/dist/core/responseValidators/terminals.cjs +2 -0
- package/dist/core/responseValidators/terminals.d.cts +2 -0
- package/dist/core/responseValidators/usage-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/usage-diagnostics.d.cts +1 -0
- package/dist/core/responseValidators/usage.cjs +2 -0
- package/dist/core/responseValidators/usage.d.cts +1 -0
- package/dist/core/responseValidators/volumes-diagnostics.cjs +1 -0
- package/dist/core/responseValidators/volumes-diagnostics.d.cts +10 -0
- package/dist/core/responseValidators/volumes.cjs +2 -0
- package/dist/core/responseValidators/volumes.d.cts +10 -0
- package/dist/core/serverSentEvents.gen.d.ts +30 -0
- package/dist/core/serverSentEvents.gen.js +313 -0
- package/dist/core/streamErrors.d.ts +32 -0
- package/dist/core/streamErrors.js +51 -0
- package/dist/core/types.gen.d.ts +83 -0
- package/dist/core/types.gen.js +3 -0
- package/dist/core/utils.gen.d.ts +19 -0
- package/dist/core/utils.gen.js +93 -0
- package/dist/creation.gen.d.ts +21 -0
- package/dist/creation.gen.js +35 -0
- package/dist/data-origin.d.ts +25 -0
- package/dist/data-origin.js +57 -0
- package/dist/error-codes.gen.d.ts +2 -0
- package/dist/error-codes.gen.js +2 -0
- package/dist/idempotency.gen.d.ts +1 -0
- package/dist/idempotency.gen.js +60 -0
- package/dist/images.d.ts +74 -0
- package/dist/images.js +88 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +80 -0
- package/dist/launch-input.gen.d.ts +9 -0
- package/dist/launch-input.gen.js +83 -0
- package/dist/launch.d.ts +28 -0
- package/dist/launch.js +222 -0
- package/dist/namespace-actions.d.mts +307 -0
- package/dist/namespace-actions.mjs +595 -0
- package/dist/namespace-agents.d.mts +33 -0
- package/dist/namespace-agents.mjs +40 -0
- package/dist/namespace-artifacts.d.mts +46 -0
- package/dist/namespace-artifacts.mjs +69 -0
- package/dist/namespace-base.d.mts +7 -0
- package/dist/namespace-base.mjs +7 -0
- package/dist/namespace-commands.d.mts +57 -0
- package/dist/namespace-commands.mjs +57 -0
- package/dist/namespace-credits.d.mts +213 -0
- package/dist/namespace-credits.mjs +476 -0
- package/dist/namespace-files.d.mts +203 -0
- package/dist/namespace-files.mjs +334 -0
- package/dist/namespace-github.d.mts +50 -0
- package/dist/namespace-github.mjs +68 -0
- package/dist/namespace-images.d.mts +52 -0
- package/dist/namespace-images.mjs +78 -0
- package/dist/namespace-launch_runs.d.mts +89 -0
- package/dist/namespace-launch_runs.mjs +133 -0
- package/dist/namespace-launches.d.mts +89 -0
- package/dist/namespace-launches.mjs +133 -0
- package/dist/namespace-operations.d.mts +45 -0
- package/dist/namespace-operations.mjs +52 -0
- package/dist/namespace-previews.d.mts +79 -0
- package/dist/namespace-previews.mjs +101 -0
- package/dist/namespace-pricing.d.mts +31 -0
- package/dist/namespace-pricing.mjs +22 -0
- package/dist/namespace-processes.d.mts +125 -0
- package/dist/namespace-processes.mjs +184 -0
- package/dist/namespace-provider_accounts.d.mts +156 -0
- package/dist/namespace-provider_accounts.mjs +241 -0
- package/dist/namespace-providers.d.mts +28 -0
- package/dist/namespace-providers.mjs +24 -0
- package/dist/namespace-routing.d.mts +64 -0
- package/dist/namespace-routing.mjs +86 -0
- package/dist/namespace-sandboxes.d.mts +287 -0
- package/dist/namespace-sandboxes.mjs +402 -0
- package/dist/namespace-secrets.d.mts +46 -0
- package/dist/namespace-secrets.mjs +68 -0
- package/dist/namespace-spend_limits.d.mts +48 -0
- package/dist/namespace-spend_limits.mjs +70 -0
- package/dist/namespace-terminals.d.mts +112 -0
- package/dist/namespace-terminals.mjs +177 -0
- package/dist/namespace-usage.d.mts +46 -0
- package/dist/namespace-usage.mjs +53 -0
- package/dist/namespace-volumes.d.mts +110 -0
- package/dist/namespace-volumes.mjs +269 -0
- package/dist/operations.d.ts +14 -0
- package/dist/operations.js +31 -0
- package/dist/retry.d.ts +8 -0
- package/dist/retry.js +63 -0
- package/dist/routing-choices.gen.d.ts +132 -0
- package/dist/routing-choices.gen.js +136 -0
- package/dist/routing.d.ts +23 -0
- package/dist/routing.js +38 -0
- package/dist/sandbox-handle.gen.d.ts +8 -0
- package/dist/sandbox-handle.gen.js +14 -0
- package/dist/sandboxes.d.ts +213 -0
- package/dist/sandboxes.js +507 -0
- package/dist/sdk.gen.d.ts +2029 -0
- package/dist/sdk.gen.js +3862 -0
- package/dist/server-timing.d.ts +19 -0
- package/dist/server-timing.gen.d.ts +265 -0
- package/dist/server-timing.gen.js +254 -0
- package/dist/server-timing.js +421 -0
- package/dist/spend-limits.d.ts +17 -0
- package/dist/spend-limits.js +26 -0
- package/dist/telemetry.d.ts +51 -0
- package/dist/telemetry.gen.d.ts +1 -0
- package/dist/telemetry.gen.js +5 -0
- package/dist/telemetry.js +438 -0
- package/dist/terminal.d.ts +61 -0
- package/dist/terminal.js +266 -0
- package/dist/transfer.d.ts +75 -0
- package/dist/transfer.js +389 -0
- package/dist/types.gen.d.ts +15016 -0
- package/dist/types.gen.js +3 -0
- package/dist/user-agent.d.ts +2 -0
- package/dist/user-agent.js +18 -0
- package/dist/version.gen.d.ts +1 -0
- package/dist/version.gen.js +5 -0
- package/dist/volumes.d.ts +33 -0
- package/dist/volumes.js +221 -0
- package/dist/waits.d.ts +31 -0
- package/dist/waits.js +42 -0
- package/dist/workflow-policy.gen.d.ts +41 -0
- package/dist/workflow-policy.gen.js +45 -0
- package/package.json +135 -4
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UNKNOWN_KIND = exports.RequestError = exports.APIError = void 0;
|
|
4
|
+
exports.reportUrl = reportUrl;
|
|
5
|
+
exports.unconfirmed = unconfirmed;
|
|
6
|
+
exports.markAfterSend = markAfterSend;
|
|
7
|
+
exports.requestFailure = requestFailure;
|
|
8
|
+
exports.foreign = foreign;
|
|
9
|
+
exports.invalidResponse = invalidResponse;
|
|
10
|
+
const addresses_1 = require("./addresses");
|
|
11
|
+
const SUPPORT_URL = 'https://boxrouter.ai/support';
|
|
12
|
+
function reportInstruction(url) {
|
|
13
|
+
return ` If this keeps happening, report it at ${url} or email ${addresses_1.SUPPORT}.`;
|
|
14
|
+
}
|
|
15
|
+
/** Where to report an unexpected failure, with the request ID prefilled when there is one. */
|
|
16
|
+
function reportUrl(requestId) {
|
|
17
|
+
return requestId ? `${SUPPORT_URL}?request=${encodeURIComponent(requestId)}` : SUPPORT_URL;
|
|
18
|
+
}
|
|
19
|
+
const MAX_RESPONSE_SCHEMA_DIAGNOSTICS = 8;
|
|
20
|
+
const SAFE_SCHEMA_KEYWORD = /^[A-Za-z][A-Za-z0-9_-]{0,39}$/;
|
|
21
|
+
const SAFE_SCHEMA_PATH = /^#(?:\/[A-Za-z0-9_$~.-]+)*$/;
|
|
22
|
+
function safeInstancePath(value) {
|
|
23
|
+
if (typeof value !== 'string' || value.length > 1024)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (value === '')
|
|
26
|
+
return '(root)';
|
|
27
|
+
if (!value.startsWith('/'))
|
|
28
|
+
return undefined;
|
|
29
|
+
// A numeric segment can be a user-supplied object key as well as an array index.
|
|
30
|
+
// Keep the path depth, but never expose any response-derived key or index.
|
|
31
|
+
const parts = value.slice(1).split('/').slice(0, 16).map(() => '[field]');
|
|
32
|
+
return `/${parts.join('/')}`;
|
|
33
|
+
}
|
|
34
|
+
function safeResponseSchemaDiagnostics(value) {
|
|
35
|
+
if (!Array.isArray(value))
|
|
36
|
+
return undefined;
|
|
37
|
+
const diagnostics = [];
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
for (const item of value) {
|
|
40
|
+
if (item === null || typeof item !== 'object')
|
|
41
|
+
continue;
|
|
42
|
+
const issue = item;
|
|
43
|
+
const keyword = issue.keyword;
|
|
44
|
+
const schemaPath = issue.schemaPath;
|
|
45
|
+
const instancePath = safeInstancePath(issue.instancePath);
|
|
46
|
+
if (typeof keyword !== 'string' || !SAFE_SCHEMA_KEYWORD.test(keyword) ||
|
|
47
|
+
typeof schemaPath !== 'string' || schemaPath.length > 256 || !SAFE_SCHEMA_PATH.test(schemaPath) ||
|
|
48
|
+
instancePath === undefined)
|
|
49
|
+
continue;
|
|
50
|
+
const key = `${keyword}\n${instancePath}\n${schemaPath}`;
|
|
51
|
+
if (seen.has(key))
|
|
52
|
+
continue;
|
|
53
|
+
seen.add(key);
|
|
54
|
+
diagnostics.push(Object.freeze({ keyword, instancePath, schemaPath }));
|
|
55
|
+
if (diagnostics.length >= MAX_RESPONSE_SCHEMA_DIAGNOSTICS)
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
return diagnostics.length ? Object.freeze(diagnostics) : undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* An API failure with an explanation and identifiers for reconciliation. An unexpected failure (a 5xx, an
|
|
62
|
+
* uncertain outcome or a reply this SDK cannot read) says where to report it; a failure the caller can fix, such
|
|
63
|
+
* as a bad key, does not. `unexpected` overrides that rule for a reply that is not BoxRouter's at all.
|
|
64
|
+
*/
|
|
65
|
+
class APIError extends Error {
|
|
66
|
+
response;
|
|
67
|
+
request;
|
|
68
|
+
status;
|
|
69
|
+
error;
|
|
70
|
+
/** The documented codes complete in an editor; a code newer than this SDK is still a string. */
|
|
71
|
+
code;
|
|
72
|
+
requestId;
|
|
73
|
+
operationId;
|
|
74
|
+
sandboxId;
|
|
75
|
+
outcome;
|
|
76
|
+
/** What to do next, when the API names a fix. */
|
|
77
|
+
fix;
|
|
78
|
+
/** What to do about sending the call again: `safe`, `after_fix`, `check_outcome` or `never` (a newer API may add values). */
|
|
79
|
+
retry;
|
|
80
|
+
/** How long to wait before a `retry: "safe"` resend; undefined when the API names no wait. */
|
|
81
|
+
retryAfterSeconds;
|
|
82
|
+
/** The documentation page for this code (`.../docs/error-codes#<code>`); undefined when the API names none. */
|
|
83
|
+
docUrl;
|
|
84
|
+
/** Code-specific context for programs; fields this SDK does not know are kept. */
|
|
85
|
+
details;
|
|
86
|
+
/** Safe schema paths only; never includes response values or validator params. */
|
|
87
|
+
schemaDiagnostics;
|
|
88
|
+
idempotencyKey;
|
|
89
|
+
/** Where to report this failure; undefined for a failure the caller can fix. */
|
|
90
|
+
reportUrl;
|
|
91
|
+
constructor(payload, response, request, message, idempotencyKey, unexpected, schemaDiagnostics) {
|
|
92
|
+
const envelope = payload !== null && typeof payload === 'object' && 'error' in payload
|
|
93
|
+
? payload.error : undefined;
|
|
94
|
+
const fields = envelope !== null && typeof envelope === 'object'
|
|
95
|
+
? envelope : {};
|
|
96
|
+
const text = (name) => typeof fields[name] === 'string' ? fields[name] : undefined;
|
|
97
|
+
const code = text('code');
|
|
98
|
+
const requestId = text('request_id') ?? response.headers.get('x-request-id') ?? undefined;
|
|
99
|
+
const fix = text('fix');
|
|
100
|
+
const explanation = message ?? text('message') ?? 'BoxRouter request failed. Check the current state before retrying.';
|
|
101
|
+
const description = message === undefined && fix ? `${explanation} Fix: ${fix}` : explanation;
|
|
102
|
+
const outcome = text('outcome');
|
|
103
|
+
// A provider's own 4xx behind our 5xx (a refused credential) is the caller's to fix.
|
|
104
|
+
const native = fields.native_status;
|
|
105
|
+
const refused = typeof native === 'number' && native >= 400 && native < 500;
|
|
106
|
+
const report = (unexpected ?? (outcome === 'unknown' || outcome === 'partial' || (response.status >= 500 && !refused)))
|
|
107
|
+
? reportUrl(requestId) : undefined;
|
|
108
|
+
super(`${description} (HTTP ${response.status}${code && message === undefined ? `, ${code}` : ''})${requestId ? ` [request ${requestId}]` : ''}${report ? reportInstruction(report) : ''}`);
|
|
109
|
+
this.response = response;
|
|
110
|
+
this.request = request;
|
|
111
|
+
this.reportUrl = report;
|
|
112
|
+
this.name = 'APIError';
|
|
113
|
+
this.error = { ...fields, message: description,
|
|
114
|
+
...(requestId ? { request_id: requestId } : {}),
|
|
115
|
+
};
|
|
116
|
+
this.status = response.status;
|
|
117
|
+
this.code = code;
|
|
118
|
+
this.requestId = requestId;
|
|
119
|
+
this.operationId = text('operation_id');
|
|
120
|
+
this.sandboxId = text('sandbox_id');
|
|
121
|
+
this.outcome = outcome;
|
|
122
|
+
this.fix = fix;
|
|
123
|
+
const retry = text('retry');
|
|
124
|
+
this.retry = retry;
|
|
125
|
+
const after = fields.retry_after_seconds;
|
|
126
|
+
this.retryAfterSeconds = typeof after === 'number' && Number.isFinite(after) ? after : undefined;
|
|
127
|
+
this.docUrl = text('doc_url');
|
|
128
|
+
const details = fields.details;
|
|
129
|
+
this.details = details !== null && typeof details === 'object' && !Array.isArray(details)
|
|
130
|
+
? details : {};
|
|
131
|
+
this.schemaDiagnostics = safeResponseSchemaDiagnostics(schemaDiagnostics);
|
|
132
|
+
this.idempotencyKey = request?.headers.get('idempotency-key') ?? idempotencyKey;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.APIError = APIError;
|
|
136
|
+
const READS = new Set(['GET', 'HEAD', 'OPTIONS']);
|
|
137
|
+
/** Say what a failed call means: a read changed nothing, a mutation may have happened. */
|
|
138
|
+
function unconfirmed(request, failure) {
|
|
139
|
+
return READS.has(request.method.toUpperCase())
|
|
140
|
+
? `${failure}; the read failed and nothing was changed. It can be retried.`
|
|
141
|
+
: `${failure}; the operation result is unconfirmed. Inspect the operation before retrying.`;
|
|
142
|
+
}
|
|
143
|
+
/** Node's system error codes for a connection that was never established. */
|
|
144
|
+
const NOT_CONNECTED = new Set(['ECONNREFUSED', 'ENOTFOUND', 'EAI_AGAIN', 'EHOSTUNREACH', 'ENETUNREACH',
|
|
145
|
+
'ETIMEDOUT', 'UND_ERR_CONNECT_TIMEOUT']);
|
|
146
|
+
/** Failures of a replay: the first attempt had been sent, so the server may have recorded the request. */
|
|
147
|
+
const AFTER_SEND = new WeakSet();
|
|
148
|
+
/** Mark a failure that followed a send, so its message does not claim the request was never sent. */
|
|
149
|
+
function markAfterSend(error) {
|
|
150
|
+
if (error !== null && typeof error === 'object')
|
|
151
|
+
AFTER_SEND.add(error);
|
|
152
|
+
return error;
|
|
153
|
+
}
|
|
154
|
+
function lostAfterSend(cause, request) {
|
|
155
|
+
if (cause === null || typeof cause !== 'object' || !AFTER_SEND.has(cause))
|
|
156
|
+
return undefined;
|
|
157
|
+
const read = READS.has(request.method.toUpperCase());
|
|
158
|
+
// A read that failed in some other way keeps the generic message, which already says it can be retried.
|
|
159
|
+
if (read && unreachable(cause, request) === undefined)
|
|
160
|
+
return undefined;
|
|
161
|
+
const advice = read
|
|
162
|
+
? 'nothing was changed; it can be retried.'
|
|
163
|
+
: 'the request may have been received. Read the operation or the sandbox before retrying, ' +
|
|
164
|
+
'and resend with the same Idempotency-Key.';
|
|
165
|
+
return `The connection to BoxRouter at ${new URL(request.url).origin} was lost after the request was sent; ${advice}`;
|
|
166
|
+
}
|
|
167
|
+
/** The `could not reach` message when fetch failed before a connection existed, else undefined. */
|
|
168
|
+
function unreachable(cause, request) {
|
|
169
|
+
let code;
|
|
170
|
+
try {
|
|
171
|
+
const inner = cause !== null && typeof cause === 'object' && 'cause' in cause ? cause.cause : undefined;
|
|
172
|
+
code = inner !== null && typeof inner === 'object' && 'code' in inner ? String(inner.code) : undefined;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return undefined; // A cause whose properties throw is not diagnosed; the original stays the cause.
|
|
176
|
+
}
|
|
177
|
+
if (code === undefined || !NOT_CONNECTED.has(code))
|
|
178
|
+
return undefined;
|
|
179
|
+
return `Could not reach BoxRouter at ${new URL(request.url).origin} (${code}). ` +
|
|
180
|
+
'The request was not sent; check BOXROUTER_BASE_URL and your network.';
|
|
181
|
+
}
|
|
182
|
+
function isBoxRouterHost(request) {
|
|
183
|
+
try {
|
|
184
|
+
const hostname = new URL(request.url).hostname.toLowerCase().replace(/\.$/, '');
|
|
185
|
+
return hostname === 'boxrouter.ai' || hostname.endsWith('.boxrouter.ai');
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function isAbort(cause, depth = 0) {
|
|
192
|
+
if (depth > 4 || cause === null || typeof cause !== 'object')
|
|
193
|
+
return false;
|
|
194
|
+
try {
|
|
195
|
+
if ('name' in cause && cause.name === 'AbortError')
|
|
196
|
+
return true;
|
|
197
|
+
return 'cause' in cause && isAbort(cause.cause, depth + 1);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** A request failed locally; a mutation's remote outcome may still be unknown. */
|
|
204
|
+
class RequestError extends Error {
|
|
205
|
+
request;
|
|
206
|
+
response;
|
|
207
|
+
idempotencyKey;
|
|
208
|
+
requestId;
|
|
209
|
+
/** Where to report a persistent transport failure against BoxRouter. */
|
|
210
|
+
reportUrl;
|
|
211
|
+
constructor(cause, request, response) {
|
|
212
|
+
const report = isBoxRouterHost(request) && !isAbort(cause)
|
|
213
|
+
? reportUrl(response?.headers.get('x-request-id') ?? undefined) : undefined;
|
|
214
|
+
const message = lostAfterSend(cause, request) ?? unreachable(cause, request) ??
|
|
215
|
+
unconfirmed(request, 'Request failed');
|
|
216
|
+
super(`${message}${report ? reportInstruction(report) : ''}`, { cause });
|
|
217
|
+
this.request = request;
|
|
218
|
+
this.response = response;
|
|
219
|
+
this.name = 'RequestError';
|
|
220
|
+
this.idempotencyKey = request.headers.get('idempotency-key') ?? undefined;
|
|
221
|
+
this.requestId = response?.headers.get('x-request-id') ?? undefined;
|
|
222
|
+
this.reportUrl = report;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.RequestError = RequestError;
|
|
226
|
+
function requestFailure(error, request, response) {
|
|
227
|
+
return !request || error instanceof APIError || error instanceof RequestError
|
|
228
|
+
? error : new RequestError(error, request, response);
|
|
229
|
+
}
|
|
230
|
+
/** Where no kind of record matched, a newer API may be the cause; say what then fixes it. */
|
|
231
|
+
exports.UNKNOWN_KIND = 'It may hold a kind of record this SDK does not know; if it keeps failing, a newer SDK is needed.';
|
|
232
|
+
/** A response BoxRouter did not send: every BoxRouter response carries a request ID. */
|
|
233
|
+
function foreign(response, request) {
|
|
234
|
+
if (response.headers.get('x-request-id'))
|
|
235
|
+
return undefined;
|
|
236
|
+
return `This is not a BoxRouter API response: ${new URL(request.url).origin} answered HTTP ${response.status} ` +
|
|
237
|
+
'without a request ID. Check that BOXROUTER_BASE_URL points at the BoxRouter API (it ends in /api/v1).';
|
|
238
|
+
}
|
|
239
|
+
function invalidResponse(response, request, payload, kind = false, schemaDiagnostics) {
|
|
240
|
+
const other = foreign(response, request);
|
|
241
|
+
if (other !== undefined)
|
|
242
|
+
return new APIError({ error: {} }, response, request, other, undefined, false);
|
|
243
|
+
const fields = payload !== null && typeof payload === 'object' && 'error' in payload &&
|
|
244
|
+
payload.error !== null && typeof payload.error === 'object' ? payload.error : {};
|
|
245
|
+
const body = payload !== null && typeof payload === 'object' ? payload : {};
|
|
246
|
+
const identifier = (value) => typeof value === 'string' && /^[A-Za-z0-9_-]{1,128}$/.test(value)
|
|
247
|
+
? value : undefined;
|
|
248
|
+
const operationId = identifier(fields.operation_id) ?? identifier(body.operation_id);
|
|
249
|
+
const sandboxId = identifier(fields.sandbox_id) ?? identifier(body.sandbox_id) ??
|
|
250
|
+
(request.method.toUpperCase() === 'POST' && new URL(request.url).pathname.replace(/\/$/, '').endsWith('/sandboxes')
|
|
251
|
+
? identifier(body.id) : undefined);
|
|
252
|
+
const mayHaveSucceeded = response.ok && !READS.has(request.method.toUpperCase());
|
|
253
|
+
const guidance = mayHaveSucceeded
|
|
254
|
+
? 'Invalid API response; the request may have succeeded. Check the operation or sandbox before retrying. ' +
|
|
255
|
+
'Find a sandbox with sandboxes.get(id), or list sandboxes with api.sandboxes.list().' +
|
|
256
|
+
(operationId ? ` [operation ${operationId}]` : '') + (sandboxId ? ` [sandbox ${sandboxId}]` : '')
|
|
257
|
+
: unconfirmed(request, 'Invalid API response');
|
|
258
|
+
return new APIError({ error: {
|
|
259
|
+
...fields,
|
|
260
|
+
...(operationId ? { operation_id: operationId } : {}),
|
|
261
|
+
...(sandboxId ? { sandbox_id: sandboxId } : {}),
|
|
262
|
+
message: kind ? `${guidance} ${exports.UNKNOWN_KIND}` : guidance,
|
|
263
|
+
} }, response, request, undefined, undefined, true, schemaDiagnostics);
|
|
264
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { BoxRouterApi } from './sdk.gen';
|
|
2
|
+
import { SandboxResources } from './sandboxes';
|
|
3
|
+
import { RoutingResources } from './routing';
|
|
4
|
+
import { ImageResources } from './images';
|
|
5
|
+
import { SpendLimitResources } from './spend-limits';
|
|
6
|
+
import { OperationResources } from './operations';
|
|
7
|
+
import { VolumeResources } from './volumes';
|
|
8
|
+
export interface BoxRouterOptions {
|
|
9
|
+
/** Defaults to the BOXROUTER_API_KEY environment variable. */
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
/** Defaults to the BOXROUTER_BASE_URL environment variable, then to the hosted API. */
|
|
12
|
+
baseUrl?: string;
|
|
13
|
+
fetch?: typeof globalThis.fetch;
|
|
14
|
+
/** Optional product token(s) appended to the SDK identification. */
|
|
15
|
+
userAgentSuffix?: string;
|
|
16
|
+
/**
|
|
17
|
+
* How often a call is resent when the API marks the failure `retry: "safe"` (nothing ran and waiting
|
|
18
|
+
* helps), with the same idempotency key. 0 turns resending off.
|
|
19
|
+
*/
|
|
20
|
+
maxRetries?: number;
|
|
21
|
+
}
|
|
22
|
+
type Configuration = Required<Pick<BoxRouterOptions, 'apiKey' | 'baseUrl'>> & Pick<BoxRouterOptions, 'fetch' | 'userAgentSuffix'> & {
|
|
23
|
+
identification: string;
|
|
24
|
+
maxRetries: number;
|
|
25
|
+
};
|
|
26
|
+
type ConnectorSocket = {
|
|
27
|
+
once(event: 'connect' | 'secureConnect', listener: () => void): ConnectorSocket;
|
|
28
|
+
};
|
|
29
|
+
type ConnectorOptions = {
|
|
30
|
+
hostname: string;
|
|
31
|
+
protocol: string;
|
|
32
|
+
};
|
|
33
|
+
type ConnectorCallback = (error: Error | null, socket: ConnectorSocket | null) => void;
|
|
34
|
+
type Connector = (options: ConnectorOptions, callback: ConnectorCallback) => ConnectorSocket;
|
|
35
|
+
/** Pool options shared by the plain and the timing-instrumented connector. */
|
|
36
|
+
export declare function pooledAgentOptions(connect: Connector): {
|
|
37
|
+
connections: number;
|
|
38
|
+
keepAliveTimeout: number;
|
|
39
|
+
connect: Connector;
|
|
40
|
+
};
|
|
41
|
+
/** The options a client was created with, for the opt-in native surface; never serialized. */
|
|
42
|
+
export declare function clientOptions(client: BoxRouter): Configuration;
|
|
43
|
+
/** Sent with a key made for this request; never with a key that may have been sent before. */
|
|
44
|
+
export declare const FIRST_SEND_HEADER = "X-BoxRouter-First-Send";
|
|
45
|
+
/** Mutations without a caller key get a fresh one, so a lost response can be reconciled.
|
|
46
|
+
* A fresh key is marked as a first send: Cloud may then dispatch the operation beside its record. */
|
|
47
|
+
export declare function idempotencyKeys(operations: Set<string>): (request: Request, options: {
|
|
48
|
+
url: string;
|
|
49
|
+
}) => Request;
|
|
50
|
+
/** Each instance owns its BoxRouter authentication and HTTP configuration. */
|
|
51
|
+
export declare class BoxRouter {
|
|
52
|
+
readonly api: BoxRouterApi;
|
|
53
|
+
readonly usage: Pick<BoxRouterApi['usage'], 'list' | 'exportCsv'>;
|
|
54
|
+
readonly images: ImageResources;
|
|
55
|
+
readonly spendLimits: SpendLimitResources;
|
|
56
|
+
readonly operations: OperationResources;
|
|
57
|
+
readonly sandboxes: SandboxResources;
|
|
58
|
+
readonly volumes: VolumeResources;
|
|
59
|
+
readonly routing: RoutingResources;
|
|
60
|
+
/** Close this client's owned HTTP connection pool. Borrowed views and custom fetches are caller-owned. */
|
|
61
|
+
close(): Promise<void>;
|
|
62
|
+
/** Release this client's owned HTTP connection pool when used with `await using`. */
|
|
63
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
64
|
+
/** Clone current HTTP configuration/interceptors without changing the owner. */
|
|
65
|
+
withUserAgentSuffix(suffix: string): BoxRouter;
|
|
66
|
+
constructor(options?: BoxRouterOptions);
|
|
67
|
+
}
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BoxRouter = exports.FIRST_SEND_HEADER = void 0;
|
|
4
|
+
exports.pooledAgentOptions = pooledAgentOptions;
|
|
5
|
+
exports.clientOptions = clientOptions;
|
|
6
|
+
exports.idempotencyKeys = idempotencyKeys;
|
|
7
|
+
const api_error_1 = require("./api-error");
|
|
8
|
+
const workflow_policy_gen_1 = require("./workflow-policy.gen");
|
|
9
|
+
const user_agent_1 = require("./user-agent");
|
|
10
|
+
const client_1 = require("./client");
|
|
11
|
+
const idempotency_gen_1 = require("./idempotency.gen");
|
|
12
|
+
const retry_1 = require("./retry");
|
|
13
|
+
const sdk_gen_1 = require("./sdk.gen");
|
|
14
|
+
const sandboxes_1 = require("./sandboxes");
|
|
15
|
+
const routing_1 = require("./routing");
|
|
16
|
+
const images_1 = require("./images");
|
|
17
|
+
const spend_limits_1 = require("./spend-limits");
|
|
18
|
+
const operations_1 = require("./operations");
|
|
19
|
+
const volumes_1 = require("./volumes");
|
|
20
|
+
const data_origin_1 = require("./data-origin");
|
|
21
|
+
const server_timing_1 = require("./server-timing");
|
|
22
|
+
const transports = new WeakMap();
|
|
23
|
+
const configured = new WeakMap();
|
|
24
|
+
const dataOrigins = new WeakMap();
|
|
25
|
+
const closeTransport = new WeakMap();
|
|
26
|
+
const noOwnedTransport = Promise.resolve();
|
|
27
|
+
const undiciSpecifier = 'undici';
|
|
28
|
+
const IDLE_SOCKET_TIMEOUT_MS = 120_000;
|
|
29
|
+
const POOL_CONNECTIONS = 64;
|
|
30
|
+
const TCP_KEEPALIVE_INITIAL_DELAY_MS = 15_000;
|
|
31
|
+
const SAFE_RETRY_METHODS = new Set(['DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE']);
|
|
32
|
+
const STALE_SOCKET_CODES = new Set(['ECONNRESET', 'EPIPE', 'UND_ERR_SOCKET']);
|
|
33
|
+
function hasStaleSocketCode(error) {
|
|
34
|
+
let current = error;
|
|
35
|
+
for (let depth = 0; depth < 5 && current instanceof Error; depth++) {
|
|
36
|
+
const code = current.code;
|
|
37
|
+
if (typeof code === 'string' && STALE_SOCKET_CODES.has(code))
|
|
38
|
+
return true;
|
|
39
|
+
current = current.cause;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
/** Pool options shared by the plain and the timing-instrumented connector. */
|
|
44
|
+
function pooledAgentOptions(connect) {
|
|
45
|
+
return { connections: POOL_CONNECTIONS, keepAliveTimeout: IDLE_SOCKET_TIMEOUT_MS, connect };
|
|
46
|
+
}
|
|
47
|
+
/** Node's fetch needs an explicit, client-owned dispatcher to retain HTTP connections. */
|
|
48
|
+
function nodePooledFetch(instrumentClientTiming = false) {
|
|
49
|
+
const process = globalThis.process;
|
|
50
|
+
if (!process?.versions?.node)
|
|
51
|
+
return undefined;
|
|
52
|
+
const fetch = globalThis.fetch;
|
|
53
|
+
let pool;
|
|
54
|
+
let closing;
|
|
55
|
+
let closed = false;
|
|
56
|
+
let firstRequest = true;
|
|
57
|
+
let pendingDispatches = 0;
|
|
58
|
+
let dispatchesDrained;
|
|
59
|
+
let resolveDispatchesDrained;
|
|
60
|
+
return {
|
|
61
|
+
fetch: (input, init) => {
|
|
62
|
+
if (closed)
|
|
63
|
+
return Promise.reject(new TypeError('BoxRouter client is closed'));
|
|
64
|
+
if (pendingDispatches++ === 0) {
|
|
65
|
+
dispatchesDrained = new Promise(resolve => { resolveDispatchesDrained = resolve; });
|
|
66
|
+
}
|
|
67
|
+
pool ??= import(/* @vite-ignore */ undiciSpecifier).then(module => {
|
|
68
|
+
const { Agent, buildConnector } = module;
|
|
69
|
+
if (!instrumentClientTiming) {
|
|
70
|
+
const connect = buildConnector({ keepAliveInitialDelay: TCP_KEEPALIVE_INITIAL_DELAY_MS });
|
|
71
|
+
return new Agent(pooledAgentOptions(connect));
|
|
72
|
+
}
|
|
73
|
+
return import('node:dns').then(dns => {
|
|
74
|
+
const connector = buildConnector({ keepAliveInitialDelay: TCP_KEEPALIVE_INITIAL_DELAY_MS, lookup(hostname, options, callback) {
|
|
75
|
+
const started = globalThis.performance?.now();
|
|
76
|
+
const recordDns = (0, server_timing_1.connectionSegmentRecorder)('dnsMs');
|
|
77
|
+
dns.lookup(hostname, options, (error, address, family) => {
|
|
78
|
+
const ended = globalThis.performance?.now();
|
|
79
|
+
if (typeof started === 'number' && typeof ended === 'number') {
|
|
80
|
+
recordDns(started, ended);
|
|
81
|
+
}
|
|
82
|
+
callback(error, address, family);
|
|
83
|
+
});
|
|
84
|
+
} });
|
|
85
|
+
const connect = (options, callback) => {
|
|
86
|
+
const started = globalThis.performance?.now() ?? 0;
|
|
87
|
+
const recordConnect = (0, server_timing_1.connectionSegmentRecorder)('connectMs');
|
|
88
|
+
const recordTls = (0, server_timing_1.connectionSegmentRecorder)('tlsMs');
|
|
89
|
+
let tcpConnectedAt;
|
|
90
|
+
const socket = connector(options, callback);
|
|
91
|
+
socket.once('connect', () => {
|
|
92
|
+
const ended = globalThis.performance?.now();
|
|
93
|
+
if (typeof ended === 'number') {
|
|
94
|
+
tcpConnectedAt = ended;
|
|
95
|
+
recordConnect(recordConnect.dnsEndedAt() ?? started, ended);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
socket.once('secureConnect', () => {
|
|
99
|
+
const ended = globalThis.performance?.now();
|
|
100
|
+
if (typeof ended === 'number' && tcpConnectedAt !== undefined)
|
|
101
|
+
recordTls(tcpConnectedAt, ended);
|
|
102
|
+
});
|
|
103
|
+
return socket;
|
|
104
|
+
};
|
|
105
|
+
return new Agent(pooledAgentOptions(connect));
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
return pool.then(async (dispatcher) => {
|
|
109
|
+
if (!firstRequest) {
|
|
110
|
+
// Let Undici return completed response sockets to the pool before dispatching again.
|
|
111
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
112
|
+
}
|
|
113
|
+
firstRequest = false;
|
|
114
|
+
const method = init?.method ?? (input instanceof Request ? input.method : 'GET');
|
|
115
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined));
|
|
116
|
+
if (!SAFE_RETRY_METHODS.has(method.toUpperCase()) && !headers.has('Idempotency-Key')) {
|
|
117
|
+
return fetch(input, { ...init, dispatcher });
|
|
118
|
+
}
|
|
119
|
+
const request = new Request(input, init);
|
|
120
|
+
const replay = request.clone();
|
|
121
|
+
// The first send may already have run: the replay must let Cloud check its record first.
|
|
122
|
+
replay.headers.delete(exports.FIRST_SEND_HEADER);
|
|
123
|
+
try {
|
|
124
|
+
return await fetch(request, { dispatcher });
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (!hasStaleSocketCode(error))
|
|
128
|
+
throw error;
|
|
129
|
+
try {
|
|
130
|
+
return await fetch(replay, { dispatcher });
|
|
131
|
+
}
|
|
132
|
+
catch (replayError) {
|
|
133
|
+
throw (0, api_error_1.markAfterSend)(replayError);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}).finally(() => {
|
|
137
|
+
if (--pendingDispatches === 0) {
|
|
138
|
+
resolveDispatchesDrained?.();
|
|
139
|
+
dispatchesDrained = undefined;
|
|
140
|
+
resolveDispatchesDrained = undefined;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
close: () => {
|
|
145
|
+
if (closing)
|
|
146
|
+
return closing;
|
|
147
|
+
closed = true;
|
|
148
|
+
const pending = dispatchesDrained;
|
|
149
|
+
closing = (async () => {
|
|
150
|
+
await pending;
|
|
151
|
+
if (pool !== undefined)
|
|
152
|
+
await (await pool).close();
|
|
153
|
+
})();
|
|
154
|
+
return closing;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function setting(value, option, variable, fallback) {
|
|
159
|
+
const environment = globalThis.process?.env;
|
|
160
|
+
const resolved = value ?? environment?.[variable] ?? fallback;
|
|
161
|
+
if (!resolved)
|
|
162
|
+
throw new TypeError(`Set ${variable} or pass ${option} to the client`);
|
|
163
|
+
return resolved;
|
|
164
|
+
}
|
|
165
|
+
/** Add a per-client timing context around generated operations only when the timing hook is installed. */
|
|
166
|
+
function timedApi(api) {
|
|
167
|
+
const proxies = new WeakMap();
|
|
168
|
+
const methods = new WeakMap();
|
|
169
|
+
const wrap = (target) => {
|
|
170
|
+
const cached = proxies.get(target);
|
|
171
|
+
if (cached)
|
|
172
|
+
return cached;
|
|
173
|
+
const proxy = new Proxy(target, {
|
|
174
|
+
get(object, property, receiver) {
|
|
175
|
+
const value = Reflect.get(object, property, receiver);
|
|
176
|
+
if (property === 'client')
|
|
177
|
+
return value;
|
|
178
|
+
if (typeof value === 'function') {
|
|
179
|
+
let byFunction = methods.get(object);
|
|
180
|
+
if (!byFunction)
|
|
181
|
+
methods.set(object, byFunction = new WeakMap());
|
|
182
|
+
let wrapped = byFunction.get(value);
|
|
183
|
+
if (!wrapped) {
|
|
184
|
+
wrapped = (...args) => (0, server_timing_1.withClientTiming)(() => Promise.resolve(Reflect.apply(value, object, args)), true);
|
|
185
|
+
byFunction.set(value, wrapped);
|
|
186
|
+
}
|
|
187
|
+
return wrapped;
|
|
188
|
+
}
|
|
189
|
+
return value !== null && typeof value === 'object' ? wrap(value) : value;
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
proxies.set(target, proxy);
|
|
193
|
+
return proxy;
|
|
194
|
+
};
|
|
195
|
+
return wrap(api);
|
|
196
|
+
}
|
|
197
|
+
/** The options a client was created with, for the opt-in native surface; never serialized. */
|
|
198
|
+
function clientOptions(client) {
|
|
199
|
+
const options = configured.get(client);
|
|
200
|
+
if (options === undefined)
|
|
201
|
+
throw new TypeError('Expected a BoxRouter client');
|
|
202
|
+
return options;
|
|
203
|
+
}
|
|
204
|
+
/** Sent with a key made for this request; never with a key that may have been sent before. */
|
|
205
|
+
exports.FIRST_SEND_HEADER = 'X-BoxRouter-First-Send';
|
|
206
|
+
/** Mutations without a caller key get a fresh one, so a lost response can be reconciled.
|
|
207
|
+
* A fresh key is marked as a first send: Cloud may then dispatch the operation beside its record. */
|
|
208
|
+
function idempotencyKeys(operations) {
|
|
209
|
+
return (request, options) => {
|
|
210
|
+
if (operations.has(`${request.method} ${options.url}`) && !request.headers.has('Idempotency-Key')) {
|
|
211
|
+
request.headers.set('Idempotency-Key', globalThis.crypto.randomUUID());
|
|
212
|
+
request.headers.set(exports.FIRST_SEND_HEADER, '1');
|
|
213
|
+
}
|
|
214
|
+
return request;
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/** Each instance owns its BoxRouter authentication and HTTP configuration. */
|
|
218
|
+
class BoxRouter {
|
|
219
|
+
api;
|
|
220
|
+
usage;
|
|
221
|
+
images;
|
|
222
|
+
spendLimits;
|
|
223
|
+
operations;
|
|
224
|
+
sandboxes;
|
|
225
|
+
volumes;
|
|
226
|
+
routing;
|
|
227
|
+
/** Close this client's owned HTTP connection pool. Borrowed views and custom fetches are caller-owned. */
|
|
228
|
+
close() {
|
|
229
|
+
return closeTransport.get(this)();
|
|
230
|
+
}
|
|
231
|
+
/** Release this client's owned HTTP connection pool when used with `await using`. */
|
|
232
|
+
[Symbol.asyncDispose]() {
|
|
233
|
+
return this.close();
|
|
234
|
+
}
|
|
235
|
+
/** Clone current HTTP configuration/interceptors without changing the owner. */
|
|
236
|
+
withUserAgentSuffix(suffix) {
|
|
237
|
+
const parent = transports.get(this);
|
|
238
|
+
const config = parent.getConfig();
|
|
239
|
+
const headers = new Headers(config.headers);
|
|
240
|
+
const identification = (0, user_agent_1.appendUserAgentSuffix)(headers.get('User-Agent') ?? user_agent_1.userAgent, suffix);
|
|
241
|
+
headers.set('User-Agent', identification);
|
|
242
|
+
const view = new BoxRouter(clientOptions(this));
|
|
243
|
+
configured.set(view, { ...clientOptions(view), identification });
|
|
244
|
+
const transport = transports.get(view);
|
|
245
|
+
transport.setConfig({ ...config, headers });
|
|
246
|
+
// The view shares what its owner has learned, through the owner's response interceptor copied below.
|
|
247
|
+
dataOrigins.set(transport, dataOrigins.get(parent));
|
|
248
|
+
for (const kind of ['request', 'response', 'error']) {
|
|
249
|
+
transport.interceptors[kind].clear();
|
|
250
|
+
for (const fn of parent.interceptors[kind].fns) {
|
|
251
|
+
if (fn)
|
|
252
|
+
transport.interceptors[kind].use(fn);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return view;
|
|
256
|
+
}
|
|
257
|
+
constructor(options = {}) {
|
|
258
|
+
const apiKey = setting(options.apiKey, 'apiKey', 'BOXROUTER_API_KEY');
|
|
259
|
+
const baseUrl = setting(options.baseUrl, 'baseUrl', 'BOXROUTER_BASE_URL', workflow_policy_gen_1.DEFAULT_BASE_URL);
|
|
260
|
+
const pooled = options.fetch === undefined || (0, server_timing_1.usesClientOwnedFetch)(options.fetch)
|
|
261
|
+
? nodePooledFetch(options.fetch !== undefined) : undefined;
|
|
262
|
+
const fetch = options.fetch === undefined ? pooled?.fetch
|
|
263
|
+
: (0, server_timing_1.useClientOwnedFetch)(options.fetch, pooled?.fetch);
|
|
264
|
+
const { userAgentSuffix } = options;
|
|
265
|
+
const identification = userAgentSuffix === undefined ? user_agent_1.userAgent : (0, user_agent_1.appendUserAgentSuffix)(user_agent_1.userAgent, userAgentSuffix);
|
|
266
|
+
const maxRetries = (0, retry_1.checkMaxRetries)(options.maxRetries);
|
|
267
|
+
configured.set(this, { apiKey, baseUrl, fetch, userAgentSuffix, identification, maxRetries });
|
|
268
|
+
closeTransport.set(this, pooled?.close ?? (() => noOwnedTransport));
|
|
269
|
+
const client = (0, client_1.createClient)({ auth: apiKey, baseUrl, throwOnError: true, headers: { 'User-Agent': identification },
|
|
270
|
+
fetch: (0, retry_1.retryingFetch)(() => fetch ?? globalThis.fetch, maxRetries) });
|
|
271
|
+
transports.set(this, client);
|
|
272
|
+
client.interceptors.request.use(idempotencyKeys(idempotency_gen_1.idempotentOperations));
|
|
273
|
+
const dataOrigin = {};
|
|
274
|
+
dataOrigins.set(client, dataOrigin);
|
|
275
|
+
client.interceptors.response.use((0, data_origin_1.observeDataOrigin)(baseUrl, dataOrigin));
|
|
276
|
+
const api = new sdk_gen_1.BoxRouterApi({ client });
|
|
277
|
+
this.api = (0, server_timing_1.usesClientTimingFetch)(fetch) ? timedApi(api) : api;
|
|
278
|
+
(0, data_origin_1.provideDataOrigin)(this.api, () => dataOrigins.get(client)?.baseUrl);
|
|
279
|
+
this.images = new images_1.ImageResources(this.api);
|
|
280
|
+
this.spendLimits = new spend_limits_1.SpendLimitResources(this.api);
|
|
281
|
+
this.operations = new operations_1.OperationResources(this.api);
|
|
282
|
+
this.usage = {
|
|
283
|
+
list: (...args) => this.api.usage.list(...args),
|
|
284
|
+
exportCsv: (...args) => this.api.usage.exportCsv(...args),
|
|
285
|
+
};
|
|
286
|
+
this.sandboxes = new sandboxes_1.SandboxResources(this.api);
|
|
287
|
+
this.volumes = new volumes_1.VolumeResources(this.api);
|
|
288
|
+
this.routing = new routing_1.RoutingResources(this.api);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.BoxRouter = BoxRouter;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type BrowserSessionOperationId, type BrowserSessionResponses } from './operations.gen';
|
|
2
|
+
export type { BrowserSessionOperationId, BrowserSessionResponses } from './operations.gen';
|
|
3
|
+
export { browserSessionOperations } from './operations.gen';
|
|
4
|
+
export { APIError } from '../api-error';
|
|
5
|
+
/** The HTTP method and path of an operation, as data. */
|
|
6
|
+
export declare function browserSessionOperation(id: BrowserSessionOperationId): {
|
|
7
|
+
readonly method: string;
|
|
8
|
+
readonly path: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Validate a response the caller received for `request` against the operation's declared
|
|
12
|
+
* contract. Returns the parsed body (`undefined` for a body-less success) or throws the
|
|
13
|
+
* SDK's `APIError`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseBrowserSessionResponse<Id extends BrowserSessionOperationId>(id: Id, response: Response, request: Request): Promise<BrowserSessionResponses[Id]>;
|
|
16
|
+
/** The compiled validator for one declared success status, for build-time checks such as an early read. */
|
|
17
|
+
export declare function loadBrowserSessionValidator(id: BrowserSessionOperationId, status: string): Promise<(value: unknown) => boolean>;
|