@fairmint/canton-node-sdk 0.0.238 → 0.0.239
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/build/src/clients/ledger-json-api/LedgerJsonApiClient.generated.d.ts +51 -51
- package/build/src/clients/ledger-json-api/LedgerJsonApiClient.generated.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/LedgerJsonApiClient.generated.js +51 -51
- package/build/src/clients/ledger-json-api/LedgerJsonApiClient.generated.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/commands/async/submit.d.ts +26 -26
- package/build/src/clients/ledger-json-api/operations/v2/commands/completions.d.ts +1 -2
- package/build/src/clients/ledger-json-api/operations/v2/commands/completions.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/commands/completions.js +2 -2
- package/build/src/clients/ledger-json-api/operations/v2/commands/completions.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/commands/submit-and-wait-for-transaction.d.ts +26 -26
- package/build/src/clients/ledger-json-api/operations/v2/events/get-events-by-contract-id.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/events/get-events-by-contract-id.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/events/get-events-by-contract-id.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/interactive-submission/get-preferred-packages.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/interactive-submission/get-preferred-packages.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/interactive-submission/get-preferred-packages.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/interactive-submission/prepare.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/interactive-submission/prepare.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/interactive-submission/prepare.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/aggregate-parties.d.ts +2 -2
- package/build/src/clients/ledger-json-api/operations/v2/parties/aggregate-parties.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/aggregate-parties.js +25 -8
- package/build/src/clients/ledger-json-api/operations/v2/parties/aggregate-parties.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/external/generate-topology.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/external/generate-topology.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/parties/external/generate-topology.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/get.d.ts +2 -2
- package/build/src/clients/ledger-json-api/operations/v2/parties/get.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/get.js +3 -2
- package/build/src/clients/ledger-json-api/operations/v2/parties/get.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/list.d.ts +2 -2
- package/build/src/clients/ledger-json-api/operations/v2/parties/list.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/parties/list.js +3 -2
- package/build/src/clients/ledger-json-api/operations/v2/parties/list.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-transaction-by-id.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-transaction-by-id.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-transaction-by-id.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-transaction-by-offset.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-transaction-by-offset.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-transaction-by-offset.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-update-by-id.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-update-by-id.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-update-by-id.js.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-update-by-offset.d.ts.map +1 -1
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-update-by-offset.js +1 -0
- package/build/src/clients/ledger-json-api/operations/v2/updates/get-update-by-offset.js.map +1 -1
- package/build/src/clients/scan-api/ScanApiClient.d.ts +7 -6
- package/build/src/clients/scan-api/ScanApiClient.d.ts.map +1 -1
- package/build/src/clients/scan-api/ScanApiClient.generated.d.ts +62 -62
- package/build/src/clients/scan-api/ScanApiClient.generated.d.ts.map +1 -1
- package/build/src/clients/scan-api/ScanApiClient.generated.js +62 -62
- package/build/src/clients/scan-api/ScanApiClient.generated.js.map +1 -1
- package/build/src/clients/scan-api/ScanApiClient.js +75 -35
- package/build/src/clients/scan-api/ScanApiClient.js.map +1 -1
- package/build/src/clients/scan-api/operations/v0/registry/allocation-instruction/v1/get-allocation-factory-from-registry.d.ts.map +1 -1
- package/build/src/clients/scan-api/operations/v0/registry/allocation-instruction/v1/get-allocation-factory-from-registry.js +1 -0
- package/build/src/clients/scan-api/operations/v0/registry/allocation-instruction/v1/get-allocation-factory-from-registry.js.map +1 -1
- package/build/src/clients/scan-api/operations/v0/scan.d.ts.map +1 -1
- package/build/src/clients/scan-api/operations/v0/scan.js +17 -0
- package/build/src/clients/scan-api/operations/v0/scan.js.map +1 -1
- package/build/src/clients/validator-api/ValidatorApiClient.generated.d.ts +61 -61
- package/build/src/clients/validator-api/ValidatorApiClient.generated.d.ts.map +1 -1
- package/build/src/clients/validator-api/ValidatorApiClient.generated.js +61 -61
- package/build/src/clients/validator-api/ValidatorApiClient.generated.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/admin/generate-external-party-topology.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/admin/generate-external-party-topology.js +1 -0
- package/build/src/clients/validator-api/operations/v0/admin/generate-external-party-topology.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/admin/prepare-accept-external-party-setup-proposal.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/admin/prepare-accept-external-party-setup-proposal.js +1 -0
- package/build/src/clients/validator-api/operations/v0/admin/prepare-accept-external-party-setup-proposal.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/admin/prepare-transfer-preapproval-send.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/admin/prepare-transfer-preapproval-send.js +1 -0
- package/build/src/clients/validator-api/operations/v0/admin/prepare-transfer-preapproval-send.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/ans/get-rules.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/ans/get-rules.js +1 -0
- package/build/src/clients/validator-api/operations/v0/ans/get-rules.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/get-member-traffic-status.d.ts +2 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/get-member-traffic-status.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/get-member-traffic-status.js +47 -9
- package/build/src/clients/validator-api/operations/v0/scan-proxy/get-member-traffic-status.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocation-instruction/v1/get-allocation-factory.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocation-instruction/v1/get-allocation-factory.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocation-instruction/v1/get-allocation-factory.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-cancel-context.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-cancel-context.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-cancel-context.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-transfer-context.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-transfer-context.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-transfer-context.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-withdraw-context.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-withdraw-context.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/allocations/v1/get-allocation-withdraw-context.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-factory.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-factory.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-factory.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-accept-context.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-accept-context.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-accept-context.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-reject-context.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-reject-context.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-reject-context.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-withdraw-context.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-withdraw-context.js +1 -0
- package/build/src/clients/validator-api/operations/v0/scan-proxy/registry/transfer-instruction/v1/get-transfer-instruction-withdraw-context.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/wallet/buy-traffic-requests/get-status.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/wallet/buy-traffic-requests/get-status.js +1 -0
- package/build/src/clients/validator-api/operations/v0/wallet/buy-traffic-requests/get-status.js.map +1 -1
- package/build/src/clients/validator-api/operations/v0/wallet/transfer-offers/get-status.d.ts.map +1 -1
- package/build/src/clients/validator-api/operations/v0/wallet/transfer-offers/get-status.js +1 -0
- package/build/src/clients/validator-api/operations/v0/wallet/transfer-offers/get-status.js.map +1 -1
- package/build/src/core/BaseClient.d.ts +5 -4
- package/build/src/core/BaseClient.d.ts.map +1 -1
- package/build/src/core/BaseClient.js +8 -8
- package/build/src/core/BaseClient.js.map +1 -1
- package/build/src/core/errors.d.ts +26 -1
- package/build/src/core/errors.d.ts.map +1 -1
- package/build/src/core/errors.js +30 -9
- package/build/src/core/errors.js.map +1 -1
- package/build/src/core/http/HttpClient.d.ts +41 -31
- package/build/src/core/http/HttpClient.d.ts.map +1 -1
- package/build/src/core/http/HttpClient.js +391 -118
- package/build/src/core/http/HttpClient.js.map +1 -1
- package/build/src/core/http/abort.d.ts +9 -0
- package/build/src/core/http/abort.d.ts.map +1 -0
- package/build/src/core/http/abort.js +54 -0
- package/build/src/core/http/abort.js.map +1 -0
- package/build/src/core/http/index.d.ts +1 -0
- package/build/src/core/http/index.d.ts.map +1 -1
- package/build/src/core/http/index.js +1 -0
- package/build/src/core/http/index.js.map +1 -1
- package/build/src/core/http/request-retry.d.ts +130 -0
- package/build/src/core/http/request-retry.d.ts.map +1 -0
- package/build/src/core/http/request-retry.js +14 -0
- package/build/src/core/http/request-retry.js.map +1 -0
- package/build/src/core/http/request-value.d.ts +5 -0
- package/build/src/core/http/request-value.d.ts.map +1 -0
- package/build/src/core/http/request-value.js +63 -0
- package/build/src/core/http/request-value.js.map +1 -0
- package/build/src/core/operations/ApiOperation.d.ts +7 -5
- package/build/src/core/operations/ApiOperation.d.ts.map +1 -1
- package/build/src/core/operations/ApiOperation.js +19 -11
- package/build/src/core/operations/ApiOperation.js.map +1 -1
- package/build/src/core/operations/ApiOperationFactory.d.ts +20 -4
- package/build/src/core/operations/ApiOperationFactory.d.ts.map +1 -1
- package/build/src/core/operations/ApiOperationFactory.js +48 -8
- package/build/src/core/operations/ApiOperationFactory.js.map +1 -1
- package/build/src/core/operations/index.d.ts +2 -0
- package/build/src/core/operations/index.d.ts.map +1 -1
- package/build/src/core/operations/index.js +2 -0
- package/build/src/core/operations/index.js.map +1 -1
- package/build/src/core/operations/operation-execute-options.d.ts +68 -0
- package/build/src/core/operations/operation-execute-options.d.ts.map +1 -0
- package/build/src/core/operations/operation-execute-options.js +36 -0
- package/build/src/core/operations/operation-execute-options.js.map +1 -0
- package/build/src/core/operations/operation-request-options.d.ts +15 -0
- package/build/src/core/operations/operation-request-options.d.ts.map +1 -0
- package/build/src/core/operations/operation-request-options.js +106 -0
- package/build/src/core/operations/operation-request-options.js.map +1 -0
- package/build/src/utils/mining/mining-rounds.d.ts +4 -3
- package/build/src/utils/mining/mining-rounds.d.ts.map +1 -1
- package/build/src/utils/mining/mining-rounds.js +4 -4
- package/build/src/utils/mining/mining-rounds.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.HttpClient = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const errors_1 = require("../errors");
|
|
9
|
-
|
|
9
|
+
const abort_1 = require("./abort");
|
|
10
|
+
const request_retry_1 = require("./request-retry");
|
|
11
|
+
const request_value_1 = require("./request-value");
|
|
12
|
+
/** Handles HTTP requests with authentication, logging, cancellation, and explicit retry safety. */
|
|
10
13
|
class HttpClient {
|
|
11
14
|
constructor(logger, bearerTokenProvider) {
|
|
12
15
|
this.retryConfig = { maxRetries: 3, delayMs: 6000 };
|
|
@@ -14,90 +17,286 @@ class HttpClient {
|
|
|
14
17
|
this.bearerTokenProvider = bearerTokenProvider;
|
|
15
18
|
this.logger = logger;
|
|
16
19
|
}
|
|
20
|
+
/** Configure the default retry policy used only by requests classified as semantic reads. */
|
|
17
21
|
setRetryConfig(config) {
|
|
18
|
-
|
|
22
|
+
if (!Number.isInteger(config.maxRetries) || config.maxRetries < 0) {
|
|
23
|
+
throw new errors_1.ConfigurationError('HTTP maxRetries must be a non-negative integer');
|
|
24
|
+
}
|
|
25
|
+
if (!Number.isFinite(config.delayMs) || config.delayMs < 0) {
|
|
26
|
+
throw new errors_1.ConfigurationError('HTTP retry delayMs must be a non-negative finite number');
|
|
27
|
+
}
|
|
28
|
+
this.retryConfig = { ...config };
|
|
19
29
|
}
|
|
20
|
-
async makeGetRequest(url, config = {},
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
async makeGetRequest(url, config = {}, options = {}) {
|
|
31
|
+
return this.makeRequest('GET', url, undefined, config, options);
|
|
32
|
+
}
|
|
33
|
+
async makePostRequest(url, data, config = {}, options = {}) {
|
|
34
|
+
return this.makeRequest('POST', url, data, config, options);
|
|
35
|
+
}
|
|
36
|
+
async makeDeleteRequest(url, config = {}, options = {}) {
|
|
37
|
+
return this.makeRequest('DELETE', url, undefined, config, options);
|
|
38
|
+
}
|
|
39
|
+
async makePatchRequest(url, data, config = {}, options = {}) {
|
|
40
|
+
return this.makeRequest('PATCH', url, data, config, options);
|
|
41
|
+
}
|
|
42
|
+
async makeRequest(method, url, initialBody, config, options) {
|
|
43
|
+
// Snapshot every caller-owned option before the first asynchronous boundary. In particular, never let replacing an
|
|
44
|
+
// options signal or retry object while a token/hook is pending change the in-flight request contract.
|
|
45
|
+
const requestOptions = (0, request_retry_1.snapshotHttpRequestOptions)(options);
|
|
46
|
+
const requestConfig = Object.freeze({ ...config });
|
|
47
|
+
const { signal, retry: requestedRetry, requestSemantics: requestedSemantics, resolveReadAttemptUrl, } = requestOptions;
|
|
48
|
+
const requestSemantics = requestedSemantics ?? (method === 'GET' ? 'read' : 'mutation');
|
|
49
|
+
if (method === 'GET' && requestSemantics !== 'read') {
|
|
50
|
+
throw new errors_1.ConfigurationError('HTTP GET requests must use read semantics');
|
|
26
51
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
52
|
+
if (resolveReadAttemptUrl !== undefined && requestSemantics !== 'read') {
|
|
53
|
+
throw new errors_1.ConfigurationError('Endpoint failover is only supported for semantic reads');
|
|
54
|
+
}
|
|
55
|
+
const strategy = this.resolveRetryStrategy(requestSemantics, requestedRetry);
|
|
56
|
+
const maxAttempts = strategy.kind === 'none' ? 1 : strategy.maxAttempts;
|
|
57
|
+
this.validateMaxAttempts(maxAttempts);
|
|
58
|
+
const requiresImmutableBody = strategy.kind !== 'none';
|
|
59
|
+
let currentBody = this.cloneBody(initialBody);
|
|
60
|
+
let lastFailure;
|
|
61
|
+
const failedAttempts = [];
|
|
62
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
63
|
+
let attemptContext;
|
|
64
|
+
let attemptUrl = url;
|
|
65
|
+
let identifier;
|
|
66
|
+
try {
|
|
67
|
+
(0, abort_1.throwIfAborted)(signal);
|
|
68
|
+
if (attempt > 1 && strategy.kind === 'derived-body') {
|
|
69
|
+
const priorFailure = lastFailure;
|
|
70
|
+
if (!priorFailure) {
|
|
71
|
+
throw new errors_1.ConfigurationError('Cannot derive a retry body without a failed request attempt');
|
|
72
|
+
}
|
|
73
|
+
const derivedBody = await (0, abort_1.awaitWithAbort)(async () => {
|
|
74
|
+
const body = await strategy.deriveBody(priorFailure.retryContext);
|
|
75
|
+
return body;
|
|
76
|
+
}, signal);
|
|
77
|
+
currentBody = this.cloneDerivedBody(derivedBody);
|
|
78
|
+
}
|
|
79
|
+
attemptContext = this.createAttemptContext(attempt, currentBody, failedAttempts, signal, requiresImmutableBody);
|
|
80
|
+
if (resolveReadAttemptUrl !== undefined) {
|
|
81
|
+
const urlContext = Object.freeze({
|
|
82
|
+
...attemptContext,
|
|
83
|
+
originalUrl: url,
|
|
84
|
+
});
|
|
85
|
+
const resolvedAttemptUrl = await (0, abort_1.awaitWithAbort)(async () => resolveReadAttemptUrl(urlContext), signal);
|
|
86
|
+
if (typeof resolvedAttemptUrl !== 'string' || resolvedAttemptUrl.length === 0) {
|
|
87
|
+
throw new errors_1.ConfigurationError('Read endpoint resolver must return a non-empty URL');
|
|
88
|
+
}
|
|
89
|
+
attemptUrl = resolvedAttemptUrl;
|
|
90
|
+
}
|
|
91
|
+
const getAttemptIdentifier = strategy.kind === 'none' ? undefined : strategy.getAttemptIdentifier;
|
|
92
|
+
identifier = getAttemptIdentifier
|
|
93
|
+
? this.redactAttemptIdentifier(await (0, abort_1.awaitWithAbort)(async () => {
|
|
94
|
+
const attemptIdentifier = await getAttemptIdentifier(attemptContext);
|
|
95
|
+
return attemptIdentifier;
|
|
96
|
+
}, signal))
|
|
97
|
+
: undefined;
|
|
98
|
+
const beforeAttempt = strategy.kind === 'none' ? undefined : strategy.beforeAttempt;
|
|
99
|
+
if (beforeAttempt) {
|
|
100
|
+
await (0, abort_1.awaitWithAbort)(async () => {
|
|
101
|
+
await beforeAttempt(attemptContext);
|
|
102
|
+
}, signal);
|
|
103
|
+
}
|
|
104
|
+
(0, abort_1.throwIfAborted)(signal);
|
|
105
|
+
}
|
|
106
|
+
catch (preDispatchError) {
|
|
107
|
+
throw this.preservePriorAmbiguity(requestSemantics, method, attemptUrl, this.normalizeCallbackError(preDispatchError), failedAttempts);
|
|
33
108
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
109
|
+
let dispatched = false;
|
|
110
|
+
try {
|
|
111
|
+
const headers = await (0, abort_1.awaitWithAbort)(async () => {
|
|
112
|
+
const builtHeaders = await this.buildHeaders(requestConfig);
|
|
113
|
+
return builtHeaders;
|
|
114
|
+
}, signal);
|
|
115
|
+
(0, abort_1.throwIfAborted)(signal);
|
|
116
|
+
const requestBody = this.cloneBody(currentBody);
|
|
117
|
+
dispatched = true;
|
|
118
|
+
const response = await this.dispatchRequest(method, attemptUrl, requestBody, headers, signal);
|
|
119
|
+
this.observeLog(attemptUrl, method === 'GET' || method === 'DELETE' ? { method, headers } : { method, headers, data: requestBody }, response);
|
|
120
|
+
return response;
|
|
121
|
+
}
|
|
122
|
+
catch (rawError) {
|
|
123
|
+
if (this.isCanceledError(rawError) || (0, abort_1.isAbortError)(rawError)) {
|
|
124
|
+
const abortError = (0, abort_1.createAbortError)(signal, rawError);
|
|
125
|
+
if (requestSemantics === 'read' || (!dispatched && !this.hasAmbiguousAttempt(failedAttempts))) {
|
|
126
|
+
throw abortError;
|
|
127
|
+
}
|
|
128
|
+
if (!dispatched) {
|
|
129
|
+
throw this.toTerminalError(requestSemantics, method, attemptUrl, abortError, failedAttempts);
|
|
130
|
+
}
|
|
131
|
+
const canceledAttempt = Object.freeze({
|
|
132
|
+
attempt,
|
|
133
|
+
...(identifier !== undefined ? { identifier } : {}),
|
|
134
|
+
errorClassification: 'ambiguous-mutation-outcome',
|
|
135
|
+
outcomeCertainty: 'ambiguous',
|
|
136
|
+
retryable: false,
|
|
137
|
+
});
|
|
138
|
+
throw this.toTerminalError(requestSemantics, method, attemptUrl, abortError, [
|
|
139
|
+
...failedAttempts,
|
|
140
|
+
canceledAttempt,
|
|
141
|
+
]);
|
|
142
|
+
}
|
|
143
|
+
const error = this.handleRequestError(rawError);
|
|
144
|
+
const retryable = this.isRetryableError(rawError);
|
|
145
|
+
const { errorClassification, outcomeCertainty } = this.classifyRequestError(requestSemantics, error, dispatched, retryable);
|
|
146
|
+
const summary = Object.freeze({
|
|
147
|
+
attempt,
|
|
148
|
+
...(identifier !== undefined ? { identifier } : {}),
|
|
149
|
+
errorClassification,
|
|
150
|
+
outcomeCertainty,
|
|
151
|
+
retryable,
|
|
152
|
+
});
|
|
153
|
+
const retryContext = Object.freeze({
|
|
154
|
+
...attemptContext,
|
|
155
|
+
error,
|
|
156
|
+
errorClassification,
|
|
157
|
+
outcomeCertainty,
|
|
158
|
+
retryable,
|
|
159
|
+
});
|
|
160
|
+
const failure = {
|
|
161
|
+
error,
|
|
162
|
+
retryContext,
|
|
163
|
+
summary,
|
|
164
|
+
};
|
|
165
|
+
lastFailure = failure;
|
|
166
|
+
this.logFailedRequest(method, attemptUrl, currentBody, rawError);
|
|
167
|
+
let retryRequest;
|
|
168
|
+
try {
|
|
169
|
+
retryRequest = await this.shouldRetry(strategy, failure, attempt, maxAttempts, requestSemantics, signal);
|
|
170
|
+
}
|
|
171
|
+
catch (retryHookError) {
|
|
172
|
+
throw this.toTerminalError(requestSemantics, method, attemptUrl, this.normalizeCallbackError(retryHookError), [...failedAttempts, summary]);
|
|
173
|
+
}
|
|
174
|
+
if (retryRequest) {
|
|
175
|
+
failedAttempts.push(summary);
|
|
176
|
+
this.logRetry(method, attemptUrl, attempt, maxAttempts, summary, rawError);
|
|
177
|
+
try {
|
|
178
|
+
await this.waitForRetry(strategy, retryContext, signal);
|
|
179
|
+
}
|
|
180
|
+
catch (backoffError) {
|
|
181
|
+
const normalizedBackoffError = this.normalizeCallbackError(backoffError);
|
|
182
|
+
throw this.toTerminalError(requestSemantics, method, attemptUrl, normalizedBackoffError, failedAttempts);
|
|
183
|
+
}
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
throw this.toTerminalError(requestSemantics, method, attemptUrl, error, [...failedAttempts, summary]);
|
|
37
187
|
}
|
|
38
|
-
throw this.handleRequestError(error);
|
|
39
188
|
}
|
|
189
|
+
// The loop either returns or throws for every attempt.
|
|
190
|
+
throw new errors_1.ConfigurationError('HTTP retry loop completed without a response or error');
|
|
40
191
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (_retryCount < this.retryConfig.maxRetries && this.isRetryableError(error)) {
|
|
50
|
-
await this.logRequestResponse(url, { method: 'POST', retry: _retryCount + 1, data }, `Retrying after error (attempt ${_retryCount + 1}/${this.retryConfig.maxRetries}): ${axios_1.default.isAxiosError(error) ? (error.response?.status ?? 'network error') : String(error)}`);
|
|
51
|
-
await this.sleep(this.retryConfig.delayMs);
|
|
52
|
-
const retryData = this.prepareDataForRetry(data);
|
|
53
|
-
return this.makePostRequest(url, retryData, config, _retryCount + 1);
|
|
54
|
-
}
|
|
55
|
-
// Log the error response before throwing
|
|
56
|
-
if (axios_1.default.isAxiosError(error)) {
|
|
57
|
-
await this.logRequestResponse(url, { method: 'POST', data }, error.response?.data ?? error.message);
|
|
192
|
+
resolveRetryStrategy(requestSemantics, retry) {
|
|
193
|
+
if (retry) {
|
|
194
|
+
if (retry.kind === 'none')
|
|
195
|
+
return Object.freeze({ kind: 'none' });
|
|
196
|
+
if (retry.kind === 'exact-body')
|
|
197
|
+
return Object.freeze({ ...retry });
|
|
198
|
+
if (typeof retry.deriveBody !== 'function') {
|
|
199
|
+
throw new errors_1.ConfigurationError('HTTP derived-body retry requires a deriveBody function');
|
|
58
200
|
}
|
|
59
|
-
|
|
201
|
+
return Object.freeze({ ...retry });
|
|
202
|
+
}
|
|
203
|
+
// Semantic reads retain transient retry behavior regardless of HTTP verb. Mutations must explicitly opt in because
|
|
204
|
+
// their server outcome may be unknown after a response is lost.
|
|
205
|
+
if (requestSemantics === 'read') {
|
|
206
|
+
return Object.freeze({
|
|
207
|
+
kind: 'exact-body',
|
|
208
|
+
maxAttempts: this.retryConfig.maxRetries + 1,
|
|
209
|
+
backoffMs: this.retryConfig.delayMs,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return Object.freeze({ kind: 'none' });
|
|
213
|
+
}
|
|
214
|
+
validateMaxAttempts(maxAttempts) {
|
|
215
|
+
if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {
|
|
216
|
+
throw new errors_1.ConfigurationError('HTTP retry maxAttempts must be a positive integer');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async shouldRetry(strategy, failure, attempt, maxAttempts, requestSemantics, signal) {
|
|
220
|
+
if (strategy.kind === 'none' || attempt >= maxAttempts)
|
|
221
|
+
return false;
|
|
222
|
+
const { shouldRetry } = strategy;
|
|
223
|
+
if (shouldRetry) {
|
|
224
|
+
return (0, abort_1.awaitWithAbort)(async () => {
|
|
225
|
+
const retry = await shouldRetry(failure.retryContext);
|
|
226
|
+
return retry;
|
|
227
|
+
}, signal);
|
|
60
228
|
}
|
|
229
|
+
if (requestSemantics === 'read')
|
|
230
|
+
return failure.summary.retryable;
|
|
231
|
+
return failure.summary.outcomeCertainty !== 'ambiguous' && failure.summary.retryable;
|
|
61
232
|
}
|
|
62
|
-
async
|
|
233
|
+
async waitForRetry(strategy, context, signal) {
|
|
234
|
+
if (strategy.kind === 'none')
|
|
235
|
+
return;
|
|
236
|
+
const configuredBackoff = strategy.backoffMs ?? this.retryConfig.delayMs;
|
|
237
|
+
const delayMs = typeof configuredBackoff === 'function'
|
|
238
|
+
? await (0, abort_1.awaitWithAbort)(async () => {
|
|
239
|
+
const backoff = await configuredBackoff(context);
|
|
240
|
+
return backoff;
|
|
241
|
+
}, signal)
|
|
242
|
+
: configuredBackoff;
|
|
243
|
+
if (!Number.isFinite(delayMs) || delayMs < 0) {
|
|
244
|
+
throw new errors_1.ConfigurationError('HTTP retry backoffMs must resolve to a non-negative finite number');
|
|
245
|
+
}
|
|
246
|
+
if (delayMs === 0) {
|
|
247
|
+
(0, abort_1.throwIfAborted)(signal);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
await this.abortableSleep(delayMs, signal);
|
|
251
|
+
}
|
|
252
|
+
createAttemptContext(attempt, body, previousAttempts, signal, immutableBody) {
|
|
253
|
+
const context = {
|
|
254
|
+
attempt,
|
|
255
|
+
body: immutableBody ? this.createReadonlyBody(body) : body,
|
|
256
|
+
previousAttempts: Object.freeze([...previousAttempts]),
|
|
257
|
+
...(signal !== undefined ? { signal } : {}),
|
|
258
|
+
};
|
|
259
|
+
return Object.freeze(context);
|
|
260
|
+
}
|
|
261
|
+
createReadonlyBody(body) {
|
|
262
|
+
const cloned = this.cloneBody(body);
|
|
263
|
+
return (0, request_value_1.deepFreezeRequestValue)(cloned);
|
|
264
|
+
}
|
|
265
|
+
cloneBody(body) {
|
|
63
266
|
try {
|
|
64
|
-
|
|
65
|
-
const response = await this.axiosInstance.delete(url, { headers });
|
|
66
|
-
await this.logRequestResponse(url, { method: 'DELETE', headers }, response.data);
|
|
67
|
-
return response.data;
|
|
267
|
+
return (0, request_value_1.cloneRequestValue)(body);
|
|
68
268
|
}
|
|
69
269
|
catch (error) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return this.makeDeleteRequest(url, config, _retryCount + 1);
|
|
74
|
-
}
|
|
75
|
-
// Log the error response before throwing
|
|
76
|
-
if (axios_1.default.isAxiosError(error)) {
|
|
77
|
-
await this.logRequestResponse(url, { method: 'DELETE' }, error.response?.data ?? error.message);
|
|
78
|
-
}
|
|
79
|
-
throw this.handleRequestError(error);
|
|
270
|
+
throw new errors_1.ConfigurationError('HTTP request bodies must be structured-cloneable', {
|
|
271
|
+
cause: error instanceof Error ? error.message : 'unknown clone failure',
|
|
272
|
+
});
|
|
80
273
|
}
|
|
81
274
|
}
|
|
82
|
-
|
|
275
|
+
/** Convert a deeply readonly callback result back into an isolated mutable transport snapshot. */
|
|
276
|
+
cloneDerivedBody(body) {
|
|
83
277
|
try {
|
|
84
|
-
|
|
85
|
-
const response = await this.axiosInstance.patch(url, data, { headers });
|
|
86
|
-
await this.logRequestResponse(url, { method: 'PATCH', headers, data }, response.data);
|
|
87
|
-
return response.data;
|
|
278
|
+
return (0, request_value_1.cloneRequestValue)(body);
|
|
88
279
|
}
|
|
89
280
|
catch (error) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
281
|
+
throw new errors_1.ConfigurationError('Derived HTTP request bodies must be structured-cloneable', {
|
|
282
|
+
cause: error instanceof Error ? error.message : 'unknown clone failure',
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async dispatchRequest(method, url, body, headers, signal) {
|
|
287
|
+
const axiosConfig = {
|
|
288
|
+
headers,
|
|
289
|
+
...(signal !== undefined ? { signal } : {}),
|
|
290
|
+
};
|
|
291
|
+
switch (method) {
|
|
292
|
+
case 'GET':
|
|
293
|
+
return (await this.axiosInstance.get(url, axiosConfig)).data;
|
|
294
|
+
case 'POST':
|
|
295
|
+
return (await this.axiosInstance.post(url, body, axiosConfig)).data;
|
|
296
|
+
case 'DELETE':
|
|
297
|
+
return (await this.axiosInstance.delete(url, axiosConfig)).data;
|
|
298
|
+
case 'PATCH':
|
|
299
|
+
return (await this.axiosInstance.patch(url, body, axiosConfig)).data;
|
|
101
300
|
}
|
|
102
301
|
}
|
|
103
302
|
async buildHeaders(config) {
|
|
@@ -119,12 +318,61 @@ class HttpClient {
|
|
|
119
318
|
}
|
|
120
319
|
return headers;
|
|
121
320
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
321
|
+
/** Invoke logging as a detached observer. Logger behavior can never affect request control flow. */
|
|
322
|
+
observeLog(url, request, response) {
|
|
323
|
+
if (!this.logger)
|
|
324
|
+
return;
|
|
325
|
+
try {
|
|
326
|
+
const requestSnapshot = this.createLogSnapshot(request, true);
|
|
327
|
+
const responseSnapshot = this.createLogSnapshot(response);
|
|
328
|
+
void Promise.resolve(this.logger.logRequestResponse(url, requestSnapshot, responseSnapshot)).catch(() => undefined);
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
// Logging is deliberately observational, including for synchronous logger failures.
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/** Isolate logger-owned values so a custom logger cannot mutate request or response control-flow state. */
|
|
335
|
+
createLogSnapshot(value, redactRequestHeaders = false) {
|
|
336
|
+
try {
|
|
337
|
+
const snapshot = (0, request_value_1.cloneRequestValue)(value);
|
|
338
|
+
if (redactRequestHeaders)
|
|
339
|
+
this.redactSensitiveLogHeaders(snapshot);
|
|
340
|
+
return (0, request_value_1.deepFreezeRequestValue)(snapshot);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return '[log value unavailable]';
|
|
125
344
|
}
|
|
126
345
|
}
|
|
346
|
+
/** Remove credentials from logger-owned header snapshots without changing dispatch headers. */
|
|
347
|
+
redactSensitiveLogHeaders(request) {
|
|
348
|
+
if (typeof request !== 'object' || request === null || !('headers' in request))
|
|
349
|
+
return;
|
|
350
|
+
const { headers } = request;
|
|
351
|
+
if (typeof headers !== 'object' || headers === null)
|
|
352
|
+
return;
|
|
353
|
+
for (const headerName of Object.keys(headers)) {
|
|
354
|
+
const normalizedHeaderName = headerName.toLowerCase();
|
|
355
|
+
if (normalizedHeaderName === 'authorization' || normalizedHeaderName === 'proxy-authorization') {
|
|
356
|
+
Reflect.set(headers, headerName, '[REDACTED]');
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
logFailedRequest(method, url, body, error) {
|
|
361
|
+
if (!axios_1.default.isAxiosError(error))
|
|
362
|
+
return;
|
|
363
|
+
const request = method === 'GET' || method === 'DELETE' ? { method } : { method, data: body };
|
|
364
|
+
this.observeLog(url, request, error.response?.data ?? error.message);
|
|
365
|
+
}
|
|
366
|
+
logRetry(method, url, attempt, maxAttempts, summary, error) {
|
|
367
|
+
this.observeLog(url, {
|
|
368
|
+
method,
|
|
369
|
+
nextAttempt: attempt + 1,
|
|
370
|
+
...(summary.identifier !== undefined ? { attemptIdentifier: summary.identifier } : {}),
|
|
371
|
+
}, `Retrying after ${summary.errorClassification} (next attempt ${attempt + 1}/${maxAttempts}): ${axios_1.default.isAxiosError(error) ? (error.response?.status ?? 'network error') : 'request error'}`);
|
|
372
|
+
}
|
|
127
373
|
handleRequestError(error) {
|
|
374
|
+
if (error instanceof errors_1.CantonError)
|
|
375
|
+
return error;
|
|
128
376
|
if (axios_1.default.isAxiosError(error)) {
|
|
129
377
|
const status = error.response?.status;
|
|
130
378
|
const data = (error.response?.data ?? {});
|
|
@@ -165,10 +413,7 @@ class HttpClient {
|
|
|
165
413
|
}
|
|
166
414
|
return new errors_1.NetworkError(`Request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
167
415
|
}
|
|
168
|
-
/**
|
|
169
|
-
* Formats a context object into a summary string for error messages. Shows up to MAX_CONTEXT_KEYS keys with truncated
|
|
170
|
-
* values.
|
|
171
|
-
*/
|
|
416
|
+
/** Formats a context object into a summary string. Shows up to MAX_CONTEXT_KEYS keys with truncated values. */
|
|
172
417
|
formatContextSummary(contextObj) {
|
|
173
418
|
const contextKeys = Object.keys(contextObj);
|
|
174
419
|
if (contextKeys.length === 0) {
|
|
@@ -186,10 +431,7 @@ class HttpClient {
|
|
|
186
431
|
})
|
|
187
432
|
.join(', ');
|
|
188
433
|
}
|
|
189
|
-
/**
|
|
190
|
-
* Safely converts a context value to a string representation. Handles null, undefined, strings, and objects (with
|
|
191
|
-
* circular reference protection).
|
|
192
|
-
*/
|
|
434
|
+
/** Safely converts a context value to a string representation. */
|
|
193
435
|
stringifyContextValue(v) {
|
|
194
436
|
if (typeof v === 'string') {
|
|
195
437
|
return v;
|
|
@@ -201,67 +443,97 @@ class HttpClient {
|
|
|
201
443
|
return 'undefined';
|
|
202
444
|
}
|
|
203
445
|
try {
|
|
204
|
-
// JSON.stringify can return undefined for functions, Symbols, or objects with toJSON() returning undefined
|
|
205
446
|
const result = JSON.stringify(v);
|
|
206
447
|
return typeof result === 'string' ? result : '[Object]';
|
|
207
448
|
}
|
|
208
449
|
catch {
|
|
209
|
-
// Handle circular references, BigInt, or other non-serializable values
|
|
210
450
|
return '[Object]';
|
|
211
451
|
}
|
|
212
452
|
}
|
|
213
|
-
/**
|
|
214
|
-
* Determines whether a request error is retryable. Retries on:
|
|
215
|
-
*
|
|
216
|
-
* - HTTP 404 (transient during Canton node restarts)
|
|
217
|
-
* - HTTP 5xx server errors
|
|
218
|
-
* - Network errors
|
|
219
|
-
* - Canton-specific transient errors: UNKNOWN_CONTRACT_SYNCHRONIZERS (400), SEQUENCER_BACKPRESSURE (409), HTTP 503
|
|
220
|
-
*/
|
|
453
|
+
/** Return true for transport failures that the SDK has historically classified as transient. */
|
|
221
454
|
isRetryableError(error) {
|
|
222
455
|
if (axios_1.default.isAxiosError(error)) {
|
|
223
456
|
const status = error.response?.status;
|
|
224
457
|
const data = (error.response?.data ?? {});
|
|
225
458
|
const code = typeof data['code'] === 'string' ? data['code'] : undefined;
|
|
226
|
-
|
|
227
|
-
if (status === undefined) {
|
|
459
|
+
if (status === undefined || status === 404 || (status >= 500 && status < 600))
|
|
228
460
|
return true;
|
|
229
|
-
|
|
230
|
-
// Retry on 404 - Canton nodes may return transient 404s during restarts
|
|
231
|
-
if (status === 404) {
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
// Retry on 5xx server errors
|
|
235
|
-
if (status >= 500 && status < 600) {
|
|
461
|
+
if (status === 400 && code === 'UNKNOWN_CONTRACT_SYNCHRONIZERS')
|
|
236
462
|
return true;
|
|
237
|
-
|
|
238
|
-
// Retry on Canton-specific transient errors
|
|
239
|
-
if (status === 400 && code === 'UNKNOWN_CONTRACT_SYNCHRONIZERS') {
|
|
463
|
+
if (status === 409 && code === 'SEQUENCER_BACKPRESSURE')
|
|
240
464
|
return true;
|
|
241
|
-
}
|
|
242
|
-
if (status === 409 && code === 'SEQUENCER_BACKPRESSURE') {
|
|
243
|
-
return true;
|
|
244
|
-
}
|
|
245
465
|
return false;
|
|
246
466
|
}
|
|
247
|
-
// Only retry non-Axios errors that are instances of NetworkError
|
|
248
467
|
return error instanceof errors_1.NetworkError;
|
|
249
468
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
469
|
+
classifyRequestError(requestSemantics, error, dispatched, retryable) {
|
|
470
|
+
if (!dispatched) {
|
|
471
|
+
return { errorClassification: 'pre-dispatch-failure', outcomeCertainty: 'not-dispatched' };
|
|
472
|
+
}
|
|
473
|
+
if (requestSemantics === 'read') {
|
|
474
|
+
return {
|
|
475
|
+
errorClassification: retryable ? 'transient-read-failure' : 'definite-rejection',
|
|
476
|
+
outcomeCertainty: 'definite',
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
if ((0, errors_1.isDefiniteCantonMutationRejection)(error)) {
|
|
480
|
+
return { errorClassification: 'definite-rejection', outcomeCertainty: 'definite' };
|
|
481
|
+
}
|
|
482
|
+
return { errorClassification: 'ambiguous-mutation-outcome', outcomeCertainty: 'ambiguous' };
|
|
483
|
+
}
|
|
484
|
+
toTerminalError(requestSemantics, method, url, error, attempts) {
|
|
485
|
+
if (requestSemantics === 'read' || method === 'GET' || !this.hasAmbiguousAttempt(attempts)) {
|
|
486
|
+
return error;
|
|
487
|
+
}
|
|
488
|
+
const attemptIdentifiers = attempts.flatMap((attempt) => attempt.identifier === undefined ? [] : [attempt.identifier]);
|
|
489
|
+
return new errors_1.UnknownMutationOutcomeError({
|
|
490
|
+
method,
|
|
491
|
+
endpoint: this.redactEndpoint(url),
|
|
492
|
+
attempts: attempts.length,
|
|
493
|
+
...(attemptIdentifiers.length > 0 ? { attemptIdentifiers } : {}),
|
|
494
|
+
}, error);
|
|
495
|
+
}
|
|
496
|
+
preservePriorAmbiguity(requestSemantics, method, url, error, previousAttempts) {
|
|
497
|
+
return this.toTerminalError(requestSemantics, method, url, error, previousAttempts);
|
|
253
498
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
499
|
+
hasAmbiguousAttempt(attempts) {
|
|
500
|
+
return attempts.some((attempt) => attempt.outcomeCertainty === 'ambiguous');
|
|
501
|
+
}
|
|
502
|
+
normalizeCallbackError(error) {
|
|
503
|
+
return error instanceof Error ? error : new errors_1.NetworkError(`Request callback failed: ${String(error)}`);
|
|
504
|
+
}
|
|
505
|
+
redactEndpoint(url) {
|
|
506
|
+
try {
|
|
507
|
+
const parsed = new URL(url);
|
|
508
|
+
return `${parsed.origin}${parsed.pathname}`;
|
|
509
|
+
}
|
|
510
|
+
catch {
|
|
511
|
+
const queryIndex = url.search(/[?#]/u);
|
|
512
|
+
return queryIndex < 0 ? url : url.slice(0, queryIndex);
|
|
263
513
|
}
|
|
264
|
-
|
|
514
|
+
}
|
|
515
|
+
redactAttemptIdentifier(identifier) {
|
|
516
|
+
if (identifier === undefined)
|
|
517
|
+
return undefined;
|
|
518
|
+
return identifier.slice(0, HttpClient.MAX_ATTEMPT_IDENTIFIER_LENGTH);
|
|
519
|
+
}
|
|
520
|
+
isCanceledError(error) {
|
|
521
|
+
return axios_1.default.isCancel(error) || (axios_1.default.isAxiosError(error) && error.code === 'ERR_CANCELED');
|
|
522
|
+
}
|
|
523
|
+
async abortableSleep(ms, signal) {
|
|
524
|
+
(0, abort_1.throwIfAborted)(signal);
|
|
525
|
+
await new Promise((resolve, reject) => {
|
|
526
|
+
const timer = setTimeout(() => {
|
|
527
|
+
signal?.removeEventListener('abort', onAbort);
|
|
528
|
+
resolve();
|
|
529
|
+
}, ms);
|
|
530
|
+
const onAbort = () => {
|
|
531
|
+
clearTimeout(timer);
|
|
532
|
+
signal?.removeEventListener('abort', onAbort);
|
|
533
|
+
reject((0, abort_1.createAbortError)(signal));
|
|
534
|
+
};
|
|
535
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
536
|
+
});
|
|
265
537
|
}
|
|
266
538
|
}
|
|
267
539
|
exports.HttpClient = HttpClient;
|
|
@@ -269,4 +541,5 @@ exports.HttpClient = HttpClient;
|
|
|
269
541
|
HttpClient.CAUSE_TRUNCATE_LENGTH = 200;
|
|
270
542
|
HttpClient.CONTEXT_VALUE_TRUNCATE_LENGTH = 50;
|
|
271
543
|
HttpClient.MAX_CONTEXT_KEYS = 3;
|
|
544
|
+
HttpClient.MAX_ATTEMPT_IDENTIFIER_LENGTH = 200;
|
|
272
545
|
//# sourceMappingURL=HttpClient.js.map
|