@salesforce/lds-runtime-aura 1.454.0 → 1.456.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ldsEngineCreator.js +191 -126
- package/dist/types/http-utils.d.ts +20 -0
- package/dist/types/retry-interceptors/fetch-retry.d.ts +11 -0
- package/dist/types/retry-policies/fetch-throttling-retry-policy.d.ts +2 -1
- package/dist/types/retry-policies/luvio-fetch-throttling-retry-policy.d.ts +2 -1
- package/dist/types/retry-policies/unconfigured-retry-policy.d.ts +20 -0
- package/package.json +43 -43
- package/dist/types/retry-interceptors/csrf-retry.d.ts +0 -2
package/dist/ldsEngineCreator.js
CHANGED
|
@@ -2589,7 +2589,7 @@ function buildServiceDescriptor$d(luvio) {
|
|
|
2589
2589
|
},
|
|
2590
2590
|
};
|
|
2591
2591
|
}
|
|
2592
|
-
// version: 1.
|
|
2592
|
+
// version: 1.456.0-cef836b978
|
|
2593
2593
|
|
|
2594
2594
|
class AuraGraphQLNormalizedCacheControlCommand extends AuraNormalizedCacheControlCommand {
|
|
2595
2595
|
constructor(config, documentRootType, services) {
|
|
@@ -2928,7 +2928,7 @@ function buildServiceDescriptor$9(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
2928
2928
|
},
|
|
2929
2929
|
};
|
|
2930
2930
|
}
|
|
2931
|
-
// version: 1.
|
|
2931
|
+
// version: 1.456.0-cef836b978
|
|
2932
2932
|
|
|
2933
2933
|
class RetryService {
|
|
2934
2934
|
constructor(defaultRetryPolicy) {
|
|
@@ -5934,7 +5934,7 @@ function getEnvironmentSetting(name) {
|
|
|
5934
5934
|
}
|
|
5935
5935
|
return undefined;
|
|
5936
5936
|
}
|
|
5937
|
-
// version: 1.
|
|
5937
|
+
// version: 1.456.0-6ed480b93c
|
|
5938
5938
|
|
|
5939
5939
|
const auraClientService = getAuraClientService();
|
|
5940
5940
|
const defaultConfig = {
|
|
@@ -6471,6 +6471,45 @@ function getCsrfTokenManager() {
|
|
|
6471
6471
|
return cached;
|
|
6472
6472
|
}
|
|
6473
6473
|
|
|
6474
|
+
/**
|
|
6475
|
+
* Extracts the HTTP method from FetchParameters, matching the Fetch API's own
|
|
6476
|
+
* precedence: an options.method override wins over a Request object's method
|
|
6477
|
+
* (e.g. `fetch(new Request(url, { method: 'GET' }), { method: 'POST' })`
|
|
6478
|
+
* resolves to `POST`).
|
|
6479
|
+
*/
|
|
6480
|
+
function getFetchMethod([urlOrRequest, options]) {
|
|
6481
|
+
if (options && 'method' in options) {
|
|
6482
|
+
return options.method;
|
|
6483
|
+
}
|
|
6484
|
+
if (typeof urlOrRequest !== 'string' && 'method' in urlOrRequest) {
|
|
6485
|
+
return urlOrRequest.method;
|
|
6486
|
+
}
|
|
6487
|
+
return undefined;
|
|
6488
|
+
}
|
|
6489
|
+
/**
|
|
6490
|
+
* Only GET requests are safe to replay automatically on 429/503 — replaying a
|
|
6491
|
+
* write (POST/PUT/PATCH/DELETE) risks executing a mutation more than once.
|
|
6492
|
+
* Shared by both the Luvio and generic-fetch throttling retry policies so the
|
|
6493
|
+
* write-guard rule lives in exactly one place.
|
|
6494
|
+
*/
|
|
6495
|
+
function isRetryableMethod(method) {
|
|
6496
|
+
return method?.toLowerCase() === 'get';
|
|
6497
|
+
}
|
|
6498
|
+
/**
|
|
6499
|
+
* Determines if the HTTP method requires CSRF protection.
|
|
6500
|
+
* Only mutating operations (POST, PUT, PATCH, DELETE) require CSRF tokens.
|
|
6501
|
+
*/
|
|
6502
|
+
function isCsrfMethod(method) {
|
|
6503
|
+
if (!method) {
|
|
6504
|
+
return false;
|
|
6505
|
+
}
|
|
6506
|
+
const normalizedMethod = method.toLowerCase();
|
|
6507
|
+
return (normalizedMethod === 'post' ||
|
|
6508
|
+
normalizedMethod === 'put' ||
|
|
6509
|
+
normalizedMethod === 'patch' ||
|
|
6510
|
+
normalizedMethod === 'delete');
|
|
6511
|
+
}
|
|
6512
|
+
|
|
6474
6513
|
const CSRF_TOKEN_HEADER = 'X-CSRF-Token';
|
|
6475
6514
|
/**
|
|
6476
6515
|
* Resolves the CSRF token manager and returns the current token. Returns
|
|
@@ -6503,23 +6542,6 @@ function areCsrfGatesEnabled() {
|
|
|
6503
6542
|
return false;
|
|
6504
6543
|
}
|
|
6505
6544
|
}
|
|
6506
|
-
/**
|
|
6507
|
-
* Determines if the HTTP method requires CSRF protection.
|
|
6508
|
-
* Only mutating operations (POST, PUT, PATCH, DELETE) require CSRF tokens.
|
|
6509
|
-
*
|
|
6510
|
-
* @param method - The HTTP method to check
|
|
6511
|
-
* @returns true if the method requires CSRF protection
|
|
6512
|
-
*/
|
|
6513
|
-
function isCsrfMethod(method) {
|
|
6514
|
-
if (!method) {
|
|
6515
|
-
return false;
|
|
6516
|
-
}
|
|
6517
|
-
const normalizedMethod = method.toLowerCase();
|
|
6518
|
-
return (normalizedMethod === 'post' ||
|
|
6519
|
-
normalizedMethod === 'put' ||
|
|
6520
|
-
normalizedMethod === 'patch' ||
|
|
6521
|
-
normalizedMethod === 'delete');
|
|
6522
|
-
}
|
|
6523
6545
|
/**
|
|
6524
6546
|
* Builds a request interceptor that adds CSRF token headers to mutating requests.
|
|
6525
6547
|
* The CSRF token is fetched once and cached for subsequent requests.
|
|
@@ -6533,17 +6555,8 @@ function buildCsrfTokenInterceptor() {
|
|
|
6533
6555
|
if (!areCsrfGatesEnabled()) {
|
|
6534
6556
|
return resolvedPromiseLike$2(fetchArgs);
|
|
6535
6557
|
}
|
|
6536
|
-
const [urlOrRequest, options] = fetchArgs;
|
|
6537
|
-
// Determine the method from either Request object or options
|
|
6538
|
-
let method;
|
|
6539
|
-
if (typeof urlOrRequest !== 'string' && 'method' in urlOrRequest) {
|
|
6540
|
-
method = urlOrRequest.method;
|
|
6541
|
-
}
|
|
6542
|
-
else if (options && 'method' in options) {
|
|
6543
|
-
method = options.method;
|
|
6544
|
-
}
|
|
6545
6558
|
// Only add CSRF token for mutating operations
|
|
6546
|
-
if (isCsrfMethod(
|
|
6559
|
+
if (isCsrfMethod(getFetchMethod(fetchArgs))) {
|
|
6547
6560
|
const token = await getCsrfToken();
|
|
6548
6561
|
if (token) {
|
|
6549
6562
|
// eslint-disable-next-line no-param-reassign
|
|
@@ -6951,12 +6964,14 @@ const DEFAULT_CONFIG$2 = {
|
|
|
6951
6964
|
jitterPercent: 0.5,
|
|
6952
6965
|
};
|
|
6953
6966
|
class LuvioFetchThrottlingRetryPolicy extends RetryPolicy {
|
|
6954
|
-
constructor(config = DEFAULT_CONFIG$2) {
|
|
6967
|
+
constructor(config = DEFAULT_CONFIG$2, method) {
|
|
6955
6968
|
super();
|
|
6956
6969
|
this.config = config;
|
|
6970
|
+
this.method = method;
|
|
6957
6971
|
}
|
|
6958
6972
|
async shouldRetry(result, context) {
|
|
6959
|
-
return ((
|
|
6973
|
+
return (isRetryableMethod(this.method) &&
|
|
6974
|
+
(result.status === 429 || result.status === 503) &&
|
|
6960
6975
|
context.attempt < this.config.maxRetries &&
|
|
6961
6976
|
context.totalElapsedMs <= this.config.maxTimeToRetry);
|
|
6962
6977
|
}
|
|
@@ -7019,7 +7034,7 @@ function buildLuvioFetchRetryInterceptor() {
|
|
|
7019
7034
|
return (request, doFetch) => {
|
|
7020
7035
|
const csrfPolicy = new LuvioCsrfTokenRetryPolicy();
|
|
7021
7036
|
const composedPolicy = new ComposedRetryPolicy([
|
|
7022
|
-
new LuvioFetchThrottlingRetryPolicy(),
|
|
7037
|
+
new LuvioFetchThrottlingRetryPolicy(undefined, request.method),
|
|
7023
7038
|
csrfPolicy,
|
|
7024
7039
|
]);
|
|
7025
7040
|
const retryService = new RetryService(composedPolicy);
|
|
@@ -7591,28 +7606,112 @@ async function isCsrfError(response) {
|
|
|
7591
7606
|
}
|
|
7592
7607
|
}
|
|
7593
7608
|
|
|
7594
|
-
|
|
7609
|
+
const DEFAULT_CONFIG = {
|
|
7610
|
+
maxRetries: 3,
|
|
7611
|
+
maxTimeToRetry: 10000,
|
|
7612
|
+
baseDelay: 250,
|
|
7613
|
+
maxDelay: 5000,
|
|
7614
|
+
exponentialFactor: 2,
|
|
7615
|
+
jitterPercent: 0.5,
|
|
7616
|
+
};
|
|
7617
|
+
class FetchThrottlingRetryPolicy extends RetryPolicy {
|
|
7618
|
+
constructor(config = DEFAULT_CONFIG, method) {
|
|
7619
|
+
super();
|
|
7620
|
+
this.config = config;
|
|
7621
|
+
this.method = method;
|
|
7622
|
+
}
|
|
7623
|
+
async shouldRetry(result, context) {
|
|
7624
|
+
return (isRetryableMethod(this.method) &&
|
|
7625
|
+
(result.status === 429 || result.status === 503) &&
|
|
7626
|
+
context.attempt < this.config.maxRetries &&
|
|
7627
|
+
context.totalElapsedMs <= this.config.maxTimeToRetry);
|
|
7628
|
+
}
|
|
7629
|
+
async calculateDelay(result, context) {
|
|
7630
|
+
let delay;
|
|
7631
|
+
// If retry-after header is present and valid, use it
|
|
7632
|
+
const retryAfterHeader = this.parseRetryAfterHeader(result);
|
|
7633
|
+
if (retryAfterHeader !== undefined) {
|
|
7634
|
+
delay = Math.min(retryAfterHeader, this.config.maxDelay);
|
|
7635
|
+
}
|
|
7636
|
+
else {
|
|
7637
|
+
// Exponential backoff
|
|
7638
|
+
delay = Math.min(this.config.baseDelay * Math.pow(this.config.exponentialFactor, context.attempt), this.config.maxDelay);
|
|
7639
|
+
}
|
|
7640
|
+
// Add jitter to prevent thundering herd
|
|
7641
|
+
const jitter = delay * this.config.jitterPercent * (Math.random() - 0.5);
|
|
7642
|
+
return Math.max(0, delay + jitter);
|
|
7643
|
+
}
|
|
7644
|
+
parseRetryAfterHeader(result) {
|
|
7645
|
+
if (!result.headers) {
|
|
7646
|
+
return undefined;
|
|
7647
|
+
}
|
|
7648
|
+
const value = result.headers.get('Retry-After');
|
|
7649
|
+
if (!value) {
|
|
7650
|
+
return undefined;
|
|
7651
|
+
}
|
|
7652
|
+
// The Retry-After header can be either a number of seconds or an HTTP-date (IMF-fixdate)
|
|
7653
|
+
// Retry-After: <delay-seconds>
|
|
7654
|
+
// Retry-After: <http-date>
|
|
7655
|
+
const trimmed = value.trim();
|
|
7656
|
+
// Strictly treat only all-digits as seconds
|
|
7657
|
+
if (/^\d+$/.test(trimmed)) {
|
|
7658
|
+
const seconds = Number(trimmed);
|
|
7659
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
7660
|
+
return seconds * 1000; // Convert to milliseconds
|
|
7661
|
+
}
|
|
7662
|
+
return undefined;
|
|
7663
|
+
}
|
|
7664
|
+
// Strict RFC 7231 IMF-fixdate format (e.g., "Sun, 06 Nov 1994 08:49:37 GMT")
|
|
7665
|
+
const IMF_FIXDATE = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/;
|
|
7666
|
+
if (!IMF_FIXDATE.test(trimmed)) {
|
|
7667
|
+
return undefined;
|
|
7668
|
+
}
|
|
7669
|
+
// Use Date.parse to avoid any engine-specific fallbacks
|
|
7670
|
+
const millis = Date.parse(trimmed);
|
|
7671
|
+
if (Number.isFinite(millis)) {
|
|
7672
|
+
return Math.max(0, millis - Date.now());
|
|
7673
|
+
}
|
|
7674
|
+
return undefined;
|
|
7675
|
+
}
|
|
7676
|
+
}
|
|
7677
|
+
|
|
7678
|
+
/**
|
|
7679
|
+
* A mutable holder for the current fetch args. CsrfTokenRetryPolicy's
|
|
7680
|
+
* prepareRetry hook updates `args` in place (e.g. to swap in a refreshed CSRF
|
|
7681
|
+
* token) so the retried fetch call picks up the change.
|
|
7682
|
+
*/
|
|
7683
|
+
function buildCsrfPolicy(mutableRequest) {
|
|
7684
|
+
const csrfPolicy = new CsrfTokenRetryPolicy();
|
|
7685
|
+
csrfPolicy.setRequestContext(mutableRequest);
|
|
7686
|
+
return csrfPolicy;
|
|
7687
|
+
}
|
|
7688
|
+
/**
|
|
7689
|
+
* Built fresh per request so the write-guard check sees this request's own
|
|
7690
|
+
* HTTP method, rather than one method baked in for the life of the service.
|
|
7691
|
+
*/
|
|
7692
|
+
function buildThrottlingPolicy(fetchArgs) {
|
|
7693
|
+
return new FetchThrottlingRetryPolicy(undefined, getFetchMethod(fetchArgs));
|
|
7694
|
+
}
|
|
7695
|
+
/**
|
|
7696
|
+
* Builds the retry interceptor used by the generic Conduit fetch service.
|
|
7697
|
+
*
|
|
7698
|
+
* Composes two independent per-request retry policies — throttling (429/503,
|
|
7699
|
+
* GET-only) and CSRF (401 token refresh) — built fresh per request rather
|
|
7700
|
+
* than reused off a shared defaultRetryPolicy. This keeps concurrent requests
|
|
7701
|
+
* from sharing mutable CSRF request-context state, and lets the throttling
|
|
7702
|
+
* policy see this request's own HTTP method.
|
|
7703
|
+
*/
|
|
7704
|
+
function buildFetchRetryInterceptor() {
|
|
7595
7705
|
return async (fetchArgs, retryService, _context) => {
|
|
7596
7706
|
if (retryService) {
|
|
7597
|
-
// Create mutable context for CSRF retry policy
|
|
7598
7707
|
const mutableRequest = { args: fetchArgs };
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
policy.setRequestContext(mutableRequest);
|
|
7604
|
-
}
|
|
7605
|
-
else if (policy instanceof ComposedRetryPolicy) {
|
|
7606
|
-
// Extract CSRF policy from composed policy
|
|
7607
|
-
const csrfPolicy = policy.getPolicyByType(CsrfTokenRetryPolicy);
|
|
7608
|
-
if (csrfPolicy) {
|
|
7609
|
-
csrfPolicy.setRequestContext(mutableRequest);
|
|
7610
|
-
}
|
|
7611
|
-
}
|
|
7612
|
-
// Retry service will call prepareRetry hook which updates mutableRequest.args
|
|
7708
|
+
const composedPolicy = new ComposedRetryPolicy([
|
|
7709
|
+
buildThrottlingPolicy(fetchArgs),
|
|
7710
|
+
buildCsrfPolicy(mutableRequest),
|
|
7711
|
+
]);
|
|
7613
7712
|
return retryService.applyRetry(async () => {
|
|
7614
7713
|
return fetch(...mutableRequest.args);
|
|
7615
|
-
});
|
|
7714
|
+
}, composedPolicy);
|
|
7616
7715
|
}
|
|
7617
7716
|
return fetch(...fetchArgs);
|
|
7618
7717
|
};
|
|
@@ -7855,7 +7954,7 @@ function buildCopilotFetchServiceDescriptor(logger) {
|
|
|
7855
7954
|
},
|
|
7856
7955
|
buildJwtRequestInterceptor(logger),
|
|
7857
7956
|
],
|
|
7858
|
-
retry:
|
|
7957
|
+
retry: buildFetchRetryInterceptor(),
|
|
7859
7958
|
finally: [buildThirdPartyTrackerFinishInterceptor()],
|
|
7860
7959
|
}),
|
|
7861
7960
|
tags: { specialHacksFor: 'copilot' },
|
|
@@ -7865,7 +7964,7 @@ function buildUnauthorizedFetchServiceDescriptor() {
|
|
|
7865
7964
|
const fetchService = buildServiceDescriptor$2({
|
|
7866
7965
|
createContext: createInstrumentationIdContext(),
|
|
7867
7966
|
request: [buildThirdPartyTrackerRegisterInterceptor()],
|
|
7868
|
-
retry:
|
|
7967
|
+
retry: buildFetchRetryInterceptor(),
|
|
7869
7968
|
finally: [buildThirdPartyTrackerFinishInterceptor()],
|
|
7870
7969
|
});
|
|
7871
7970
|
return {
|
|
@@ -10645,7 +10744,7 @@ function getLexRuntimeDefaultInterceptorConfig(logger) {
|
|
|
10645
10744
|
buildEntityEncodingInterceptor(),
|
|
10646
10745
|
buildFirstPartyHeaderInterceptor(),
|
|
10647
10746
|
],
|
|
10648
|
-
retry:
|
|
10747
|
+
retry: buildFetchRetryInterceptor(),
|
|
10649
10748
|
response: [
|
|
10650
10749
|
buildLexRuntime5xxStatusResponseInterceptor(logger),
|
|
10651
10750
|
buildLexRuntimeSessionExpirationResponseInterceptor(logger),
|
|
@@ -10688,73 +10787,6 @@ function buildLexRuntimeCompressedFetchServiceDescriptor(logger, retryService) {
|
|
|
10688
10787
|
};
|
|
10689
10788
|
}
|
|
10690
10789
|
|
|
10691
|
-
const DEFAULT_CONFIG = {
|
|
10692
|
-
maxRetries: 3,
|
|
10693
|
-
maxTimeToRetry: 10000,
|
|
10694
|
-
baseDelay: 250,
|
|
10695
|
-
maxDelay: 5000,
|
|
10696
|
-
exponentialFactor: 2,
|
|
10697
|
-
jitterPercent: 0.5,
|
|
10698
|
-
};
|
|
10699
|
-
class FetchThrottlingRetryPolicy extends RetryPolicy {
|
|
10700
|
-
constructor(config = DEFAULT_CONFIG) {
|
|
10701
|
-
super();
|
|
10702
|
-
this.config = config;
|
|
10703
|
-
}
|
|
10704
|
-
async shouldRetry(result, context) {
|
|
10705
|
-
return ((result.status === 429 || result.status === 503) &&
|
|
10706
|
-
context.attempt < this.config.maxRetries &&
|
|
10707
|
-
context.totalElapsedMs <= this.config.maxTimeToRetry);
|
|
10708
|
-
}
|
|
10709
|
-
async calculateDelay(result, context) {
|
|
10710
|
-
let delay;
|
|
10711
|
-
// If retry-after header is present and valid, use it
|
|
10712
|
-
const retryAfterHeader = this.parseRetryAfterHeader(result);
|
|
10713
|
-
if (retryAfterHeader !== undefined) {
|
|
10714
|
-
delay = Math.min(retryAfterHeader, this.config.maxDelay);
|
|
10715
|
-
}
|
|
10716
|
-
else {
|
|
10717
|
-
// Exponential backoff
|
|
10718
|
-
delay = Math.min(this.config.baseDelay * Math.pow(this.config.exponentialFactor, context.attempt), this.config.maxDelay);
|
|
10719
|
-
}
|
|
10720
|
-
// Add jitter to prevent thundering herd
|
|
10721
|
-
const jitter = delay * this.config.jitterPercent * (Math.random() - 0.5);
|
|
10722
|
-
return Math.max(0, delay + jitter);
|
|
10723
|
-
}
|
|
10724
|
-
parseRetryAfterHeader(result) {
|
|
10725
|
-
if (!result.headers) {
|
|
10726
|
-
return undefined;
|
|
10727
|
-
}
|
|
10728
|
-
const value = result.headers.get('Retry-After');
|
|
10729
|
-
if (!value) {
|
|
10730
|
-
return undefined;
|
|
10731
|
-
}
|
|
10732
|
-
// The Retry-After header can be either a number of seconds or an HTTP-date (IMF-fixdate)
|
|
10733
|
-
// Retry-After: <delay-seconds>
|
|
10734
|
-
// Retry-After: <http-date>
|
|
10735
|
-
const trimmed = value.trim();
|
|
10736
|
-
// Strictly treat only all-digits as seconds
|
|
10737
|
-
if (/^\d+$/.test(trimmed)) {
|
|
10738
|
-
const seconds = Number(trimmed);
|
|
10739
|
-
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
10740
|
-
return seconds * 1000; // Convert to milliseconds
|
|
10741
|
-
}
|
|
10742
|
-
return undefined;
|
|
10743
|
-
}
|
|
10744
|
-
// Strict RFC 7231 IMF-fixdate format (e.g., "Sun, 06 Nov 1994 08:49:37 GMT")
|
|
10745
|
-
const IMF_FIXDATE = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/;
|
|
10746
|
-
if (!IMF_FIXDATE.test(trimmed)) {
|
|
10747
|
-
return undefined;
|
|
10748
|
-
}
|
|
10749
|
-
// Use Date.parse to avoid any engine-specific fallbacks
|
|
10750
|
-
const millis = Date.parse(trimmed);
|
|
10751
|
-
if (Number.isFinite(millis)) {
|
|
10752
|
-
return Math.max(0, millis - Date.now());
|
|
10753
|
-
}
|
|
10754
|
-
return undefined;
|
|
10755
|
-
}
|
|
10756
|
-
}
|
|
10757
|
-
|
|
10758
10790
|
const CSRF_TOKEN_KEY = 'salesforce_csrf_token';
|
|
10759
10791
|
const CSRF_STORAGE_NAME = 'ldsCSRFToken';
|
|
10760
10792
|
const BASE_URI = '/services/data/v68.0';
|
|
@@ -10898,6 +10930,35 @@ function buildCsrfTokenManager() {
|
|
|
10898
10930
|
});
|
|
10899
10931
|
}
|
|
10900
10932
|
|
|
10933
|
+
/**
|
|
10934
|
+
* The default policy for the runtime's shared retry service.
|
|
10935
|
+
*
|
|
10936
|
+
* Every fetch-service descriptor wired with the retry service also supplies its
|
|
10937
|
+
* own `retry:` interceptor, which passes a per-request policy as the override to
|
|
10938
|
+
* `applyRetry` — so this default is never consulted on any real path. It is
|
|
10939
|
+
* reachable only if a descriptor is registered with the retry service but omits
|
|
10940
|
+
* its `retry:` interceptor; in that case service-fetch-network falls back to
|
|
10941
|
+
* `retryService.applyRetry(fetch)` with no override, and this policy runs.
|
|
10942
|
+
*
|
|
10943
|
+
* That is a wiring mistake, not a runtime condition. We surface it loudly in
|
|
10944
|
+
* development rather than silently degrading to never-retry (the behavior of a
|
|
10945
|
+
* plain empty policy), following the repo convention for should-never-run paths.
|
|
10946
|
+
*/
|
|
10947
|
+
class UnconfiguredRetryPolicy extends RetryPolicy {
|
|
10948
|
+
async shouldRetry(_result, _context) {
|
|
10949
|
+
// istanbul ignore else: not exercised in NODE_ENV = production for test coverage
|
|
10950
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
10951
|
+
throw new Error('A fetch-service descriptor was registered with the retry service but did ' +
|
|
10952
|
+
'not supply a `retry:` interceptor. Retries would silently never run — ' +
|
|
10953
|
+
'add a `retry:` interceptor (e.g. buildFetchRetryInterceptor()) to the descriptor.');
|
|
10954
|
+
}
|
|
10955
|
+
return false;
|
|
10956
|
+
}
|
|
10957
|
+
async calculateDelay(_result, _context) {
|
|
10958
|
+
return 0;
|
|
10959
|
+
}
|
|
10960
|
+
}
|
|
10961
|
+
|
|
10901
10962
|
/* eslint-disable no-console */
|
|
10902
10963
|
/**
|
|
10903
10964
|
* Default storage configuration for the durable cache
|
|
@@ -11506,11 +11567,15 @@ function initializeOneStore(luvio) {
|
|
|
11506
11567
|
reader.unMarkMissing();
|
|
11507
11568
|
return linkedData.data;
|
|
11508
11569
|
});
|
|
11509
|
-
//
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
11570
|
+
// The real throttling/CSRF policies are built fresh per request in
|
|
11571
|
+
// buildFetchRetryInterceptor (retry-interceptors/fetch-retry.ts) so each
|
|
11572
|
+
// request gets its own CSRF context and sees its own HTTP method. This
|
|
11573
|
+
// default is never consulted by any current fetch-service descriptor (they
|
|
11574
|
+
// all supply their own `retry` interceptor + override); UnconfiguredRetryPolicy
|
|
11575
|
+
// exists so that if a future descriptor is wired with this retry service but
|
|
11576
|
+
// forgets its `retry:` interceptor, the silent never-retry fallback surfaces
|
|
11577
|
+
// loudly in development instead.
|
|
11578
|
+
const retryServiceDescriptor = buildServiceDescriptor$8(new UnconfiguredRetryPolicy());
|
|
11514
11579
|
const retryService = retryServiceDescriptor.service;
|
|
11515
11580
|
const csrfTokenManagerServiceDescriptor = buildRenewableResourceManagerDescriptor(CSRF_TOKEN_MANAGER_SERVICE, buildCsrfTokenManager());
|
|
11516
11581
|
const prefetchSfapJwtServiceDescriptor = {
|
|
@@ -11592,4 +11657,4 @@ function ldsEngineCreator() {
|
|
|
11592
11657
|
}
|
|
11593
11658
|
|
|
11594
11659
|
export { LexRequestStrategy, PDL_ENGINE_REGISTRATION_ID, PdlPrefetcherEventType, PdlRequestPriority, buildPredictorForContext, configService, ldsEngineCreator as default, initializeLDS, initializeOneStore, notifyUpdateAvailableFactory, registerRequestStrategy, saveRequestAsPrediction, subscribeToPrefetcherEvents, unregisterRequestStrategy, whenPredictionsReady };
|
|
11595
|
-
// version: 1.
|
|
11660
|
+
// version: 1.456.0-cef836b978
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FetchParameters } from '@conduit-client/service-fetch-network/v1';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts the HTTP method from FetchParameters, matching the Fetch API's own
|
|
4
|
+
* precedence: an options.method override wins over a Request object's method
|
|
5
|
+
* (e.g. `fetch(new Request(url, { method: 'GET' }), { method: 'POST' })`
|
|
6
|
+
* resolves to `POST`).
|
|
7
|
+
*/
|
|
8
|
+
export declare function getFetchMethod([urlOrRequest, options]: FetchParameters): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Only GET requests are safe to replay automatically on 429/503 — replaying a
|
|
11
|
+
* write (POST/PUT/PATCH/DELETE) risks executing a mutation more than once.
|
|
12
|
+
* Shared by both the Luvio and generic-fetch throttling retry policies so the
|
|
13
|
+
* write-guard rule lives in exactly one place.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isRetryableMethod(method: string | undefined): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Determines if the HTTP method requires CSRF protection.
|
|
18
|
+
* Only mutating operations (POST, PUT, PATCH, DELETE) require CSRF tokens.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isCsrfMethod(method: string | undefined): boolean;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RetryInterceptor } from '@conduit-client/service-fetch-network/v1';
|
|
2
|
+
/**
|
|
3
|
+
* Builds the retry interceptor used by the generic Conduit fetch service.
|
|
4
|
+
*
|
|
5
|
+
* Composes two independent per-request retry policies — throttling (429/503,
|
|
6
|
+
* GET-only) and CSRF (401 token refresh) — built fresh per request rather
|
|
7
|
+
* than reused off a shared defaultRetryPolicy. This keeps concurrent requests
|
|
8
|
+
* from sharing mutable CSRF request-context state, and lets the throttling
|
|
9
|
+
* policy see this request's own HTTP method.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildFetchRetryInterceptor(): RetryInterceptor;
|
|
@@ -10,7 +10,8 @@ type FetchThrottlingRetryPolicyConfig = {
|
|
|
10
10
|
};
|
|
11
11
|
export declare class FetchThrottlingRetryPolicy extends RetryPolicy<Response> {
|
|
12
12
|
private config;
|
|
13
|
-
|
|
13
|
+
private method?;
|
|
14
|
+
constructor(config?: FetchThrottlingRetryPolicyConfig, method?: string | undefined);
|
|
14
15
|
shouldRetry(result: Response, context: RetryContext<Response>): Promise<boolean>;
|
|
15
16
|
calculateDelay(result: Response, context: RetryContext<Response>): Promise<number>;
|
|
16
17
|
parseRetryAfterHeader(result: Response): number | undefined;
|
|
@@ -10,7 +10,8 @@ type LuvioFetchThrottlingRetryPolicyConfig = {
|
|
|
10
10
|
};
|
|
11
11
|
export declare class LuvioFetchThrottlingRetryPolicy extends RetryPolicy<FetchResponse<any>> {
|
|
12
12
|
private config;
|
|
13
|
-
|
|
13
|
+
private method?;
|
|
14
|
+
constructor(config?: LuvioFetchThrottlingRetryPolicyConfig, method?: string | undefined);
|
|
14
15
|
shouldRetry(result: FetchResponse<any>, context: RetryContext<FetchResponse<any>>): Promise<boolean>;
|
|
15
16
|
calculateDelay(result: FetchResponse<any>, context: RetryContext<FetchResponse<any>>): Promise<number>;
|
|
16
17
|
parseRetryAfterHeader(result: FetchResponse<any>): number | undefined;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RetryContext } from '@conduit-client/service-retry/v1';
|
|
2
|
+
import { RetryPolicy } from '@conduit-client/service-retry/v1';
|
|
3
|
+
/**
|
|
4
|
+
* The default policy for the runtime's shared retry service.
|
|
5
|
+
*
|
|
6
|
+
* Every fetch-service descriptor wired with the retry service also supplies its
|
|
7
|
+
* own `retry:` interceptor, which passes a per-request policy as the override to
|
|
8
|
+
* `applyRetry` — so this default is never consulted on any real path. It is
|
|
9
|
+
* reachable only if a descriptor is registered with the retry service but omits
|
|
10
|
+
* its `retry:` interceptor; in that case service-fetch-network falls back to
|
|
11
|
+
* `retryService.applyRetry(fetch)` with no override, and this policy runs.
|
|
12
|
+
*
|
|
13
|
+
* That is a wiring mistake, not a runtime condition. We surface it loudly in
|
|
14
|
+
* development rather than silently degrading to never-retry (the behavior of a
|
|
15
|
+
* plain empty policy), following the repo convention for should-never-run paths.
|
|
16
|
+
*/
|
|
17
|
+
export declare class UnconfiguredRetryPolicy extends RetryPolicy<Response> {
|
|
18
|
+
shouldRetry(_result: Response, _context: RetryContext<Response>): Promise<boolean>;
|
|
19
|
+
calculateDelay(_result: Response, _context: RetryContext<Response>): Promise<number>;
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-aura",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.456.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS engine for Aura runtime.",
|
|
6
6
|
"main": "dist/ldsEngineCreator.js",
|
|
@@ -34,61 +34,61 @@
|
|
|
34
34
|
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-aura"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@conduit-client/service-provisioner": "3.26.
|
|
38
|
-
"@conduit-client/tools-core": "3.26.
|
|
39
|
-
"@salesforce/lds-adapters-apex": "^1.
|
|
40
|
-
"@salesforce/lds-adapters-uiapi": "^1.
|
|
41
|
-
"@salesforce/lds-ads-bridge": "^1.
|
|
42
|
-
"@salesforce/lds-aura-storage": "^1.
|
|
43
|
-
"@salesforce/lds-bindings": "^1.
|
|
44
|
-
"@salesforce/lds-instrumentation": "^1.
|
|
45
|
-
"@salesforce/lds-network-adapter": "^1.
|
|
46
|
-
"@salesforce/lds-network-aura": "^1.
|
|
47
|
-
"@salesforce/lds-network-fetch": "^1.
|
|
37
|
+
"@conduit-client/service-provisioner": "3.26.5",
|
|
38
|
+
"@conduit-client/tools-core": "3.26.5",
|
|
39
|
+
"@salesforce/lds-adapters-apex": "^1.456.0",
|
|
40
|
+
"@salesforce/lds-adapters-uiapi": "^1.456.0",
|
|
41
|
+
"@salesforce/lds-ads-bridge": "^1.456.0",
|
|
42
|
+
"@salesforce/lds-aura-storage": "^1.456.0",
|
|
43
|
+
"@salesforce/lds-bindings": "^1.456.0",
|
|
44
|
+
"@salesforce/lds-instrumentation": "^1.456.0",
|
|
45
|
+
"@salesforce/lds-network-adapter": "^1.456.0",
|
|
46
|
+
"@salesforce/lds-network-aura": "^1.456.0",
|
|
47
|
+
"@salesforce/lds-network-fetch": "^1.456.0",
|
|
48
48
|
"jwt-encode": "1.0.1"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@conduit-client/command-aura-graphql-normalized-cache-control": "3.26.
|
|
52
|
-
"@conduit-client/command-aura-network": "3.26.
|
|
53
|
-
"@conduit-client/command-aura-normalized-cache-control": "3.26.
|
|
54
|
-
"@conduit-client/command-fetch-network": "3.26.
|
|
55
|
-
"@conduit-client/command-http-graphql-normalized-cache-control": "3.26.
|
|
56
|
-
"@conduit-client/command-http-normalized-cache-control": "3.26.
|
|
57
|
-
"@conduit-client/command-ndjson": "3.26.
|
|
58
|
-
"@conduit-client/command-network": "3.26.
|
|
59
|
-
"@conduit-client/command-sse": "3.26.
|
|
60
|
-
"@conduit-client/command-streaming": "3.26.
|
|
61
|
-
"@conduit-client/jwt-manager": "3.26.
|
|
62
|
-
"@conduit-client/service-aura-network": "3.26.
|
|
63
|
-
"@conduit-client/service-bindings-imperative": "3.26.
|
|
64
|
-
"@conduit-client/service-bindings-lwc": "3.26.
|
|
65
|
-
"@conduit-client/service-cache": "3.26.
|
|
66
|
-
"@conduit-client/service-cache-control": "3.26.
|
|
67
|
-
"@conduit-client/service-cache-inclusion-policy": "3.26.
|
|
68
|
-
"@conduit-client/service-config": "3.26.
|
|
69
|
-
"@conduit-client/service-feature-flags": "3.26.
|
|
70
|
-
"@conduit-client/service-fetch-network": "3.26.
|
|
71
|
-
"@conduit-client/service-instrument-command": "3.26.
|
|
72
|
-
"@conduit-client/service-pubsub": "3.26.
|
|
73
|
-
"@conduit-client/service-renewable-resource-manager": "3.26.
|
|
74
|
-
"@conduit-client/service-store": "3.26.
|
|
75
|
-
"@conduit-client/utils": "3.26.
|
|
51
|
+
"@conduit-client/command-aura-graphql-normalized-cache-control": "3.26.5",
|
|
52
|
+
"@conduit-client/command-aura-network": "3.26.5",
|
|
53
|
+
"@conduit-client/command-aura-normalized-cache-control": "3.26.5",
|
|
54
|
+
"@conduit-client/command-fetch-network": "3.26.5",
|
|
55
|
+
"@conduit-client/command-http-graphql-normalized-cache-control": "3.26.5",
|
|
56
|
+
"@conduit-client/command-http-normalized-cache-control": "3.26.5",
|
|
57
|
+
"@conduit-client/command-ndjson": "3.26.5",
|
|
58
|
+
"@conduit-client/command-network": "3.26.5",
|
|
59
|
+
"@conduit-client/command-sse": "3.26.5",
|
|
60
|
+
"@conduit-client/command-streaming": "3.26.5",
|
|
61
|
+
"@conduit-client/jwt-manager": "3.26.5",
|
|
62
|
+
"@conduit-client/service-aura-network": "3.26.5",
|
|
63
|
+
"@conduit-client/service-bindings-imperative": "3.26.5",
|
|
64
|
+
"@conduit-client/service-bindings-lwc": "3.26.5",
|
|
65
|
+
"@conduit-client/service-cache": "3.26.5",
|
|
66
|
+
"@conduit-client/service-cache-control": "3.26.5",
|
|
67
|
+
"@conduit-client/service-cache-inclusion-policy": "3.26.5",
|
|
68
|
+
"@conduit-client/service-config": "3.26.5",
|
|
69
|
+
"@conduit-client/service-feature-flags": "3.26.5",
|
|
70
|
+
"@conduit-client/service-fetch-network": "3.26.5",
|
|
71
|
+
"@conduit-client/service-instrument-command": "3.26.5",
|
|
72
|
+
"@conduit-client/service-pubsub": "3.26.5",
|
|
73
|
+
"@conduit-client/service-renewable-resource-manager": "3.26.5",
|
|
74
|
+
"@conduit-client/service-store": "3.26.5",
|
|
75
|
+
"@conduit-client/utils": "3.26.5",
|
|
76
76
|
"@luvio/network-adapter-composable": "0.161.2",
|
|
77
77
|
"@luvio/network-adapter-fetch": "0.161.2",
|
|
78
78
|
"@lwc/state": "^0.29.0",
|
|
79
|
-
"@salesforce/lds-adapters-onestore-graphql": "^1.
|
|
79
|
+
"@salesforce/lds-adapters-onestore-graphql": "^1.456.0",
|
|
80
80
|
"@salesforce/lds-adapters-uiapi-lex": "^1.415.0",
|
|
81
|
-
"@salesforce/lds-durable-storage": "^1.
|
|
82
|
-
"@salesforce/lds-luvio-service": "^1.
|
|
83
|
-
"@salesforce/lds-luvio-uiapi-records-service": "^1.
|
|
81
|
+
"@salesforce/lds-durable-storage": "^1.456.0",
|
|
82
|
+
"@salesforce/lds-luvio-service": "^1.456.0",
|
|
83
|
+
"@salesforce/lds-luvio-uiapi-records-service": "^1.456.0"
|
|
84
84
|
},
|
|
85
85
|
"luvioBundlesize": [
|
|
86
86
|
{
|
|
87
87
|
"path": "./dist/ldsEngineCreator.js",
|
|
88
88
|
"maxSize": {
|
|
89
|
-
"none": "
|
|
89
|
+
"none": "421 kB",
|
|
90
90
|
"min": "190 kB",
|
|
91
|
-
"compressed": "
|
|
91
|
+
"compressed": "75 kB"
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
],
|