@salesforce/lds-runtime-aura 1.442.0 → 1.443.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 +353 -150
- package/dist/types/aura-utils.d.ts +21 -0
- package/dist/types/request-interceptors/csrf-manager.d.ts +6 -43
- package/dist/types/request-interceptors/csrf-service.d.ts +19 -0
- package/dist/types/request-interceptors/first-party-header.d.ts +17 -0
- package/dist/types/response-interceptors/error-body-normalization.d.ts +20 -0
- package/dist/types/retry-policies/csrf-token-retry-policy.d.ts +0 -1
- package/dist/types/retry-policies/luvio-csrf-token-retry-policy.d.ts +0 -1
- package/package.json +43 -42
package/dist/ldsEngineCreator.js
CHANGED
|
@@ -22,7 +22,7 @@ import { instrument, getRecordAvatarsAdapterFactory, getRecordAdapterFactory, co
|
|
|
22
22
|
import { getInstrumentation } from 'o11y/client';
|
|
23
23
|
import { findExecutableOperation, buildGraphQLInputExtension, addTypenameToDocument } from 'force/luvioGraphqlNormalization';
|
|
24
24
|
import { print, resolveAndValidateGraphQLConfig, toGraphQLErrorResponse } from 'force/luvioOnestoreGraphqlParser';
|
|
25
|
-
import { setServices } from 'force/luvioServiceProvisioner1';
|
|
25
|
+
import getServices, { setServices } from 'force/luvioServiceProvisioner1';
|
|
26
26
|
import { assertIsValid, JsonSchemaViolationError, MissingRequiredPropertyError } from 'force/luvioJsonschemaValidate5';
|
|
27
27
|
import { dispatchGlobalEvent, executeGlobalControllerRawResponse } from 'aura';
|
|
28
28
|
import auraNetworkAdapter, { dispatchAuraAction, defaultActionConfig, instrument as instrument$1, forceRecordTransactionsDisabled as forceRecordTransactionsDisabled$1, ldsNetworkAdapterInstrument, CrudEventState, CrudEventType, UIAPI_RECORDS_PATH, UIAPI_RELATED_LIST_RECORDS_BATCH_PATH, UIAPI_RELATED_LIST_RECORDS_PATH } from 'force/ldsNetwork';
|
|
@@ -36,7 +36,6 @@ import { instrument as instrument$5 } from '@lwc/state';
|
|
|
36
36
|
import { withRegistration, register, setDefaultLuvio } from 'force/ldsEngine';
|
|
37
37
|
import applyPredictionRequestLimit from '@salesforce/gate/lds.pdl.applyRequestLimit';
|
|
38
38
|
import { pageScopedCache } from 'instrumentation/utility';
|
|
39
|
-
import { createStorage, clearStorages } from 'force/ldsDurableStorage';
|
|
40
39
|
import lightningConnectEnabled from '@salesforce/gate/ui.services.LightningConnect.enabled';
|
|
41
40
|
import bypassAppRestrictionEnabled from '@salesforce/gate/ui.services.LightningConnect.BypassAppRestriction.enabled';
|
|
42
41
|
import csrfValidationEnabled from '@salesforce/gate/ui.services.LightningConnect.CsrfValidation.enabled';
|
|
@@ -47,6 +46,7 @@ import useHttpUiapiOneRuntimePublic from '@salesforce/gate/lds.useHttpUiapiOneRu
|
|
|
47
46
|
import useHttpUiapiOneRuntimePrivate from '@salesforce/gate/lds.useHttpUiapiOneRuntimePrivate';
|
|
48
47
|
import disableCreateContentDocumentAndVersionHTTPLexRuntime from '@salesforce/gate/lds.lex.http.disableCreateContentDocumentAndVersion';
|
|
49
48
|
import useHotspotLimit from '@salesforce/gate/lds.pdl.useHotspotLimit';
|
|
49
|
+
import { createStorage, clearStorages } from 'force/ldsDurableStorage';
|
|
50
50
|
import { registerSubRequestNetworkAdapter } from 'force/ldsNetwork';
|
|
51
51
|
|
|
52
52
|
const { create: create$1, freeze, keys: keys$2, entries: entries$1 } = Object;
|
|
@@ -2644,7 +2644,7 @@ function buildServiceDescriptor$d(luvio) {
|
|
|
2644
2644
|
},
|
|
2645
2645
|
};
|
|
2646
2646
|
}
|
|
2647
|
-
// version: 1.
|
|
2647
|
+
// version: 1.443.0-be70f6bb6e
|
|
2648
2648
|
|
|
2649
2649
|
class AuraGraphQLNormalizedCacheControlCommand extends AuraNormalizedCacheControlCommand {
|
|
2650
2650
|
constructor(config, documentRootType, services) {
|
|
@@ -2982,7 +2982,7 @@ function buildServiceDescriptor$9(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
2982
2982
|
},
|
|
2983
2983
|
};
|
|
2984
2984
|
}
|
|
2985
|
-
// version: 1.
|
|
2985
|
+
// version: 1.443.0-be70f6bb6e
|
|
2986
2986
|
|
|
2987
2987
|
class RetryService {
|
|
2988
2988
|
constructor(defaultRetryPolicy) {
|
|
@@ -3134,6 +3134,50 @@ function buildServiceDescriptor$8(defaultRetryPolicy) {
|
|
|
3134
3134
|
};
|
|
3135
3135
|
}
|
|
3136
3136
|
|
|
3137
|
+
class BasicRenewableResourceManager {
|
|
3138
|
+
constructor(config) {
|
|
3139
|
+
this.config = config;
|
|
3140
|
+
}
|
|
3141
|
+
get() {
|
|
3142
|
+
return this.config.storage.get().then((cached) => cached !== void 0 ? cached : this.fetchAndStore());
|
|
3143
|
+
}
|
|
3144
|
+
refresh(staleValue) {
|
|
3145
|
+
if (staleValue === void 0) {
|
|
3146
|
+
return this.fetchAndStore();
|
|
3147
|
+
}
|
|
3148
|
+
return this.config.storage.get().then(
|
|
3149
|
+
(current) => current !== void 0 && current !== staleValue ? current : this.fetchAndStore()
|
|
3150
|
+
);
|
|
3151
|
+
}
|
|
3152
|
+
clear() {
|
|
3153
|
+
return this.config.storage.clear();
|
|
3154
|
+
}
|
|
3155
|
+
/**
|
|
3156
|
+
* Single in-flight fetch shared by all concurrent `get`/`refresh` callers.
|
|
3157
|
+
* Overwrites storage on a successful fetch of a defined value only; a
|
|
3158
|
+
* rejected fetch or a resolved-`undefined` leaves the cached value intact.
|
|
3159
|
+
*/
|
|
3160
|
+
fetchAndStore() {
|
|
3161
|
+
if (this.inFlightFetch) return this.inFlightFetch;
|
|
3162
|
+
const pending = this.config.fetch().then(
|
|
3163
|
+
(fetched) => fetched === void 0 ? fetched : this.config.storage.set(fetched).then(() => fetched)
|
|
3164
|
+
);
|
|
3165
|
+
this.inFlightFetch = pending;
|
|
3166
|
+
const releaseSlot = () => {
|
|
3167
|
+
if (this.inFlightFetch === pending) this.inFlightFetch = void 0;
|
|
3168
|
+
};
|
|
3169
|
+
pending.then(releaseSlot, releaseSlot);
|
|
3170
|
+
return pending;
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
function buildRenewableResourceManagerDescriptor(type, service) {
|
|
3174
|
+
return {
|
|
3175
|
+
version: "1.0",
|
|
3176
|
+
service,
|
|
3177
|
+
type
|
|
3178
|
+
};
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3137
3181
|
function isUserVisibleError(error) {
|
|
3138
3182
|
return error instanceof Error && "type" in error && error.type === "user-visible";
|
|
3139
3183
|
}
|
|
@@ -5673,9 +5717,28 @@ function getEnvironmentSetting(name) {
|
|
|
5673
5717
|
}
|
|
5674
5718
|
return undefined;
|
|
5675
5719
|
}
|
|
5676
|
-
// version: 1.
|
|
5720
|
+
// version: 1.443.0-3de9a44799
|
|
5721
|
+
|
|
5722
|
+
/**
|
|
5723
|
+
* Helpers for reaching the Aura framework from the LDS Aura runtime.
|
|
5724
|
+
*
|
|
5725
|
+
* `window.$A` is only present when the runtime is hosted inside LEX; in tests
|
|
5726
|
+
* and non-Aura runtimes it is absent. Centralizing the guarded access keeps the
|
|
5727
|
+
* `$A` lookup in one place instead of duplicating the `environmentHasAura`
|
|
5728
|
+
* check across modules.
|
|
5729
|
+
*/
|
|
5730
|
+
/**
|
|
5731
|
+
* Returns `$A.clientService` when running inside an Aura environment, or
|
|
5732
|
+
* `undefined` otherwise. Defensive: never throws.
|
|
5733
|
+
*/
|
|
5734
|
+
function getAuraClientService() {
|
|
5735
|
+
if (typeof window === 'undefined' || typeof window.$A === 'undefined') {
|
|
5736
|
+
return undefined;
|
|
5737
|
+
}
|
|
5738
|
+
return window.$A.clientService;
|
|
5739
|
+
}
|
|
5677
5740
|
|
|
5678
|
-
const
|
|
5741
|
+
const auraClientService = getAuraClientService();
|
|
5679
5742
|
const defaultConfig = {
|
|
5680
5743
|
maxAllowedParallelXHRCounts: 9,
|
|
5681
5744
|
forceRecordTransactionsDisabled: false,
|
|
@@ -5686,10 +5749,11 @@ const configServiceDescriptor = buildServiceDescriptor$1({
|
|
|
5686
5749
|
default: defaultConfig,
|
|
5687
5750
|
});
|
|
5688
5751
|
const configService = configServiceDescriptor.service;
|
|
5689
|
-
if (
|
|
5752
|
+
if (auraClientService?.maxAllowedParallelXHRCounts) {
|
|
5690
5753
|
configService.set('lex', (config) => {
|
|
5691
5754
|
config.maxAllowedParallelXHRCounts =
|
|
5692
|
-
|
|
5755
|
+
auraClientService.maxAllowedParallelXHRCounts?.() ??
|
|
5756
|
+
defaultConfig.maxAllowedParallelXHRCounts;
|
|
5693
5757
|
config.forceRecordTransactionsDisabled = getEnvironmentSetting(EnvironmentSettings.ForceRecordTransactionsDisabled);
|
|
5694
5758
|
});
|
|
5695
5759
|
}
|
|
@@ -6119,146 +6183,91 @@ function buildLexRuntimeLuvio5xxStatusResponseInterceptor() {
|
|
|
6119
6183
|
};
|
|
6120
6184
|
}
|
|
6121
6185
|
|
|
6122
|
-
const CSRF_TOKEN_KEY = 'salesforce_csrf_token';
|
|
6123
|
-
const CSRF_STORAGE_NAME = 'ldsCSRFToken';
|
|
6124
|
-
const BASE_URI = '/services/data/v68.0';
|
|
6125
|
-
const UI_API_BASE_URI = `${BASE_URI}/ui-api`;
|
|
6126
|
-
const CSRF_TOKEN_ENDPOINT = `${UI_API_BASE_URI}/session/csrf`;
|
|
6127
|
-
const CSRF_STORAGE_CONFIG = {
|
|
6128
|
-
name: CSRF_STORAGE_NAME,
|
|
6129
|
-
persistent: true,
|
|
6130
|
-
secure: true,
|
|
6131
|
-
maxSize: 1024,
|
|
6132
|
-
expiration: 24 * 60 * 60,
|
|
6133
|
-
clearOnInit: false,
|
|
6134
|
-
debugLogging: false,
|
|
6135
|
-
};
|
|
6136
6186
|
/**
|
|
6137
|
-
*
|
|
6138
|
-
*
|
|
6187
|
+
* Normalizes Connect REST error envelopes into the Aura Shape A
|
|
6188
|
+
* (ConnectInJava) shape, so consumers can read `response.body.errorCode`
|
|
6189
|
+
* regardless of transport.
|
|
6190
|
+
*
|
|
6191
|
+
* - HTTP error envelope (this path): `[{ errorCode, message }, ...]`
|
|
6192
|
+
* - Aura Shape A: `{ errorCode, message, statusCode, ... }`
|
|
6193
|
+
*
|
|
6194
|
+
* The full array is preserved at `body.enhancedErrorInfo.allErrors` since
|
|
6195
|
+
* Connect can return multiple errors per response.
|
|
6196
|
+
*
|
|
6197
|
+
* Aura Shape B (`{ error: "..." }`) is an Aura-only fallback that never
|
|
6198
|
+
* appears on the HTTP path, so no normalization is needed for it here.
|
|
6199
|
+
*
|
|
6200
|
+
* Ordering: must run AFTER any other interceptor that inspects the raw
|
|
6201
|
+
* error body shape (e.g. the 5xx interceptor's ErrorId extraction reads
|
|
6202
|
+
* `body[0].message` from the array form).
|
|
6139
6203
|
*/
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
return CsrfTokenManager.instance;
|
|
6152
|
-
}
|
|
6153
|
-
/**
|
|
6154
|
-
* Obtain a CSRF token, either from AuraStorage or by fetching a fresh one.
|
|
6155
|
-
*
|
|
6156
|
-
* @private
|
|
6157
|
-
*/
|
|
6158
|
-
async loadOrFetchToken() {
|
|
6159
|
-
// First try to get token from AuraStorage
|
|
6160
|
-
if (this.storage) {
|
|
6161
|
-
try {
|
|
6162
|
-
const cachedToken = await this.storage.get(CSRF_TOKEN_KEY);
|
|
6163
|
-
if (typeof cachedToken === 'string' && cachedToken) {
|
|
6164
|
-
return cachedToken;
|
|
6165
|
-
}
|
|
6166
|
-
}
|
|
6167
|
-
catch {
|
|
6168
|
-
// If storage read fails, continue to fetch
|
|
6169
|
-
}
|
|
6170
|
-
}
|
|
6171
|
-
// No cached token, fetch from server
|
|
6172
|
-
return this.fetchFreshToken();
|
|
6173
|
-
}
|
|
6174
|
-
/**
|
|
6175
|
-
* Call API endpoint to acquire a CSRF token and cache it.
|
|
6176
|
-
*
|
|
6177
|
-
* @private
|
|
6178
|
-
*/
|
|
6179
|
-
async fetchFreshToken() {
|
|
6180
|
-
try {
|
|
6181
|
-
const response = await fetch(CSRF_TOKEN_ENDPOINT, {
|
|
6182
|
-
method: 'GET',
|
|
6183
|
-
credentials: 'same-origin',
|
|
6184
|
-
});
|
|
6185
|
-
if (!response.ok) {
|
|
6186
|
-
return undefined;
|
|
6187
|
-
}
|
|
6188
|
-
const data = await response.json();
|
|
6189
|
-
const token = data.csrfToken;
|
|
6190
|
-
if (token && this.storage) {
|
|
6191
|
-
// Cache the token in AuraStorage
|
|
6192
|
-
try {
|
|
6193
|
-
await this.storage.set(CSRF_TOKEN_KEY, token);
|
|
6194
|
-
}
|
|
6195
|
-
catch {
|
|
6196
|
-
// Non-fatal: token is still available even if caching fails
|
|
6197
|
-
}
|
|
6198
|
-
}
|
|
6199
|
-
return token;
|
|
6200
|
-
}
|
|
6201
|
-
catch {
|
|
6202
|
-
return undefined;
|
|
6203
|
-
}
|
|
6204
|
-
}
|
|
6205
|
-
/**
|
|
6206
|
-
* Returns the current token value as a Promise.
|
|
6207
|
-
* Lazy-loads the token on first call (from cache or by fetching).
|
|
6208
|
-
*/
|
|
6209
|
-
async getToken() {
|
|
6210
|
-
// Lazy initialization: only fetch token when actually needed
|
|
6211
|
-
if (!this.tokenPromise) {
|
|
6212
|
-
this.tokenPromise = this.loadOrFetchToken();
|
|
6213
|
-
}
|
|
6214
|
-
return this.tokenPromise;
|
|
6215
|
-
}
|
|
6216
|
-
/**
|
|
6217
|
-
* Obtains and returns a new token value as a promise.
|
|
6218
|
-
* This will clear the cached token and fetch a fresh one.
|
|
6219
|
-
*
|
|
6220
|
-
* Concurrent calls coalesce onto a single in-flight refresh — important when
|
|
6221
|
-
* multiple requests fail with INVALID_ACCESS_TOKEN simultaneously and each
|
|
6222
|
-
* retry policy independently calls refreshToken(). Without this, every caller
|
|
6223
|
-
* triggers its own /session/csrf round-trip.
|
|
6224
|
-
*/
|
|
6225
|
-
refreshToken() {
|
|
6226
|
-
if (this.refreshInFlight) {
|
|
6227
|
-
return this.refreshInFlight;
|
|
6204
|
+
function buildLuvioErrorBodyNormalizationInterceptor() {
|
|
6205
|
+
return async (response) => {
|
|
6206
|
+
if (!response.ok && Array.isArray(response.body)) {
|
|
6207
|
+
const allErrors = response.body;
|
|
6208
|
+
response.body = {
|
|
6209
|
+
...allErrors[0],
|
|
6210
|
+
statusCode: response.status,
|
|
6211
|
+
enhancedErrorInfo: {
|
|
6212
|
+
allErrors,
|
|
6213
|
+
},
|
|
6214
|
+
};
|
|
6228
6215
|
}
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6216
|
+
return response;
|
|
6217
|
+
};
|
|
6218
|
+
}
|
|
6219
|
+
|
|
6220
|
+
/**
|
|
6221
|
+
* Service name the CSRF token manager is registered under by
|
|
6222
|
+
* `initializeOneStore` (see `buildRenewableResourceManagerDescriptor`).
|
|
6223
|
+
*/
|
|
6224
|
+
const CSRF_TOKEN_MANAGER_SERVICE = 'csrfTokenManager';
|
|
6225
|
+
const CSRF_TOKEN_MANAGER_REQUEST = {
|
|
6226
|
+
[CSRF_TOKEN_MANAGER_SERVICE]: {
|
|
6227
|
+
type: CSRF_TOKEN_MANAGER_SERVICE,
|
|
6228
|
+
version: '1.0',
|
|
6229
|
+
},
|
|
6230
|
+
};
|
|
6231
|
+
let cached;
|
|
6232
|
+
/**
|
|
6233
|
+
* Resolves the CSRF token manager from the service provisioner.
|
|
6234
|
+
*
|
|
6235
|
+
* The manager is registered during `initializeOneStore`, which runs before any
|
|
6236
|
+
* request flows; the interceptors and retry policies that call this resolve
|
|
6237
|
+
* lazily (per request / per retry), so the service is always available by then.
|
|
6238
|
+
*
|
|
6239
|
+
* The resolved promise is memoized so resolution happens once rather than per
|
|
6240
|
+
* request. A rejection is NOT memoized — `getServices` rejects when the service
|
|
6241
|
+
* is unavailable, and caching that would permanently wedge CSRF handling — so a
|
|
6242
|
+
* later call retries the resolution.
|
|
6243
|
+
*/
|
|
6244
|
+
function getCsrfTokenManager() {
|
|
6245
|
+
if (!cached) {
|
|
6246
|
+
cached = Promise.resolve(getServices(CSRF_TOKEN_MANAGER_REQUEST))
|
|
6247
|
+
.then((services) => services[CSRF_TOKEN_MANAGER_SERVICE])
|
|
6248
|
+
.catch((error) => {
|
|
6249
|
+
cached = undefined;
|
|
6250
|
+
throw error;
|
|
6248
6251
|
});
|
|
6249
|
-
return refresh;
|
|
6250
|
-
}
|
|
6251
|
-
/**
|
|
6252
|
-
* Reset the singleton instance (useful for testing).
|
|
6253
|
-
* @internal
|
|
6254
|
-
*/
|
|
6255
|
-
static resetInstance() {
|
|
6256
|
-
CsrfTokenManager.instance = null;
|
|
6257
6252
|
}
|
|
6253
|
+
return cached;
|
|
6258
6254
|
}
|
|
6259
|
-
CsrfTokenManager.instance = null;
|
|
6260
6255
|
|
|
6261
6256
|
const CSRF_TOKEN_HEADER = 'X-CSRF-Token';
|
|
6257
|
+
/**
|
|
6258
|
+
* Resolves the CSRF token manager and returns the current token. Returns
|
|
6259
|
+
* `undefined` if the manager cannot be resolved (service not yet provisioned)
|
|
6260
|
+
* or has no token, so a request is never blocked by token resolution.
|
|
6261
|
+
*/
|
|
6262
|
+
async function getCsrfToken() {
|
|
6263
|
+
try {
|
|
6264
|
+
const manager = await getCsrfTokenManager();
|
|
6265
|
+
return await manager.get();
|
|
6266
|
+
}
|
|
6267
|
+
catch {
|
|
6268
|
+
return undefined;
|
|
6269
|
+
}
|
|
6270
|
+
}
|
|
6262
6271
|
/**
|
|
6263
6272
|
* Checks if all required gates are enabled for CSRF token interceptor.
|
|
6264
6273
|
*
|
|
@@ -6301,7 +6310,6 @@ function isCsrfMethod(method) {
|
|
|
6301
6310
|
* @returns A RequestInterceptor function for FetchParameters
|
|
6302
6311
|
*/
|
|
6303
6312
|
function buildCsrfTokenInterceptor() {
|
|
6304
|
-
const csrfTokenManager = CsrfTokenManager.getInstance();
|
|
6305
6313
|
return async (fetchArgs) => {
|
|
6306
6314
|
// Check if all required gates are enabled before running
|
|
6307
6315
|
if (!areCsrfGatesEnabled()) {
|
|
@@ -6318,7 +6326,7 @@ function buildCsrfTokenInterceptor() {
|
|
|
6318
6326
|
}
|
|
6319
6327
|
// Only add CSRF token for mutating operations
|
|
6320
6328
|
if (isCsrfMethod(method)) {
|
|
6321
|
-
const token = await
|
|
6329
|
+
const token = await getCsrfToken();
|
|
6322
6330
|
if (token) {
|
|
6323
6331
|
// eslint-disable-next-line no-param-reassign
|
|
6324
6332
|
fetchArgs = setHeader(CSRF_TOKEN_HEADER, token, fetchArgs);
|
|
@@ -6335,7 +6343,6 @@ function buildCsrfTokenInterceptor() {
|
|
|
6335
6343
|
* @returns A request interceptor function for Luvio ResourceRequest objects
|
|
6336
6344
|
*/
|
|
6337
6345
|
function buildLuvioCsrfTokenInterceptor() {
|
|
6338
|
-
const csrfTokenManager = CsrfTokenManager.getInstance();
|
|
6339
6346
|
return async (resourceRequest) => {
|
|
6340
6347
|
// Check if all required gates are enabled before running
|
|
6341
6348
|
if (!areCsrfGatesEnabled()) {
|
|
@@ -6349,7 +6356,7 @@ function buildLuvioCsrfTokenInterceptor() {
|
|
|
6349
6356
|
if (isCsrfMethod(resourceRequest.method)) {
|
|
6350
6357
|
// Don't overwrite existing CSRF token header if it already exists
|
|
6351
6358
|
if (!resourceRequest.headers[CSRF_TOKEN_HEADER]) {
|
|
6352
|
-
const token = await
|
|
6359
|
+
const token = await getCsrfToken();
|
|
6353
6360
|
if (token) {
|
|
6354
6361
|
resourceRequest.headers[CSRF_TOKEN_HEADER] = token;
|
|
6355
6362
|
}
|
|
@@ -6389,6 +6396,39 @@ function buildLuvioEntityEncodingInterceptor() {
|
|
|
6389
6396
|
};
|
|
6390
6397
|
}
|
|
6391
6398
|
|
|
6399
|
+
const FIRST_PARTY_HEADER = 'X-Salesforce-First-Party';
|
|
6400
|
+
const FIRST_PARTY_VALUE = 'platform-ui';
|
|
6401
|
+
/**
|
|
6402
|
+
* Builds a request interceptor that adds the LDS first party header to every
|
|
6403
|
+
* outbound request.
|
|
6404
|
+
*
|
|
6405
|
+
* @returns A RequestInterceptor function for FetchParameters
|
|
6406
|
+
*/
|
|
6407
|
+
function buildFirstPartyHeaderInterceptor() {
|
|
6408
|
+
return async (fetchArgs) => {
|
|
6409
|
+
const returnedFetchArgs = setHeader(FIRST_PARTY_HEADER, FIRST_PARTY_VALUE, fetchArgs);
|
|
6410
|
+
return resolvedPromiseLike$2(returnedFetchArgs);
|
|
6411
|
+
};
|
|
6412
|
+
}
|
|
6413
|
+
/**
|
|
6414
|
+
* Builds a Luvio request interceptor that adds the LDS first party header to
|
|
6415
|
+
* every outbound `ResourceRequest`. See {@link buildFirstPartyHeaderInterceptor} for
|
|
6416
|
+
* the header semantics.
|
|
6417
|
+
*
|
|
6418
|
+
* @returns A request interceptor for Luvio ResourceRequest objects
|
|
6419
|
+
*/
|
|
6420
|
+
function buildLuvioFirstPartyHeaderInterceptor() {
|
|
6421
|
+
return async (resourceRequest) => {
|
|
6422
|
+
if (!resourceRequest.headers) {
|
|
6423
|
+
resourceRequest.headers = {};
|
|
6424
|
+
}
|
|
6425
|
+
if (!resourceRequest.headers[FIRST_PARTY_HEADER]) {
|
|
6426
|
+
resourceRequest.headers[FIRST_PARTY_HEADER] = FIRST_PARTY_VALUE;
|
|
6427
|
+
}
|
|
6428
|
+
return resolvedPromiseLike$2(resourceRequest);
|
|
6429
|
+
};
|
|
6430
|
+
}
|
|
6431
|
+
|
|
6392
6432
|
function createInstrumentationIdContext() {
|
|
6393
6433
|
return () => ({
|
|
6394
6434
|
instrumentationId: generateRequestId(),
|
|
@@ -6618,7 +6658,6 @@ class LuvioCsrfTokenRetryPolicy extends RetryPolicy {
|
|
|
6618
6658
|
constructor(config = DEFAULT_CONFIG$3) {
|
|
6619
6659
|
super();
|
|
6620
6660
|
this.config = config;
|
|
6621
|
-
this.csrfTokenManager = CsrfTokenManager.getInstance();
|
|
6622
6661
|
}
|
|
6623
6662
|
setRequestContext(context) {
|
|
6624
6663
|
this.requestContext = context;
|
|
@@ -6640,11 +6679,20 @@ class LuvioCsrfTokenRetryPolicy extends RetryPolicy {
|
|
|
6640
6679
|
if (!this.requestContext) {
|
|
6641
6680
|
return;
|
|
6642
6681
|
}
|
|
6643
|
-
|
|
6682
|
+
let newToken;
|
|
6683
|
+
try {
|
|
6684
|
+
const manager = await getCsrfTokenManager();
|
|
6685
|
+
newToken = await manager.refresh();
|
|
6686
|
+
}
|
|
6687
|
+
catch {
|
|
6688
|
+
// Manager unavailable — drop the stale token below so the request
|
|
6689
|
+
// interceptor refetches on the retry.
|
|
6690
|
+
newToken = undefined;
|
|
6691
|
+
}
|
|
6644
6692
|
const req = this.requestContext.request;
|
|
6645
6693
|
const { [CSRF_TOKEN_HEADER]: _stale, ...remainingHeaders } = req.headers ?? {};
|
|
6646
6694
|
// If refresh failed, drop the stale token entirely so the request interceptor
|
|
6647
|
-
// will fetch a fresh one via
|
|
6695
|
+
// will fetch a fresh one via get() on the retry.
|
|
6648
6696
|
const headers = newToken
|
|
6649
6697
|
? { ...remainingHeaders, [CSRF_TOKEN_HEADER]: newToken }
|
|
6650
6698
|
: remainingHeaders;
|
|
@@ -7149,12 +7197,14 @@ const composedFetchNetworkAdapter = {
|
|
|
7149
7197
|
buildLuvioTransportMarksSendInterceptor(),
|
|
7150
7198
|
buildLuvioPageScopedCacheRequestInterceptor(),
|
|
7151
7199
|
buildLuvioCsrfTokenInterceptor(),
|
|
7200
|
+
buildLuvioFirstPartyHeaderInterceptor(),
|
|
7152
7201
|
buildLuvioEntityEncodingInterceptor(),
|
|
7153
7202
|
],
|
|
7154
7203
|
retry: buildLuvioFetchRetryInterceptor(),
|
|
7155
7204
|
response: [
|
|
7156
7205
|
buildLexRuntimeLuvio5xxStatusResponseInterceptor(),
|
|
7157
7206
|
buildLexRuntimeLuvioAuthExpirationRedirectResponseInterceptor(),
|
|
7207
|
+
buildLuvioErrorBodyNormalizationInterceptor(),
|
|
7158
7208
|
buildLuvioTransportMarksReceiveInterceptor(),
|
|
7159
7209
|
buildLuvioActionMarksReceiveInterceptor(),
|
|
7160
7210
|
],
|
|
@@ -7199,7 +7249,6 @@ class CsrfTokenRetryPolicy extends RetryPolicy {
|
|
|
7199
7249
|
constructor(config = DEFAULT_CONFIG$1) {
|
|
7200
7250
|
super();
|
|
7201
7251
|
this.config = config;
|
|
7202
|
-
this.csrfTokenManager = CsrfTokenManager.getInstance();
|
|
7203
7252
|
}
|
|
7204
7253
|
/**
|
|
7205
7254
|
* Allows the fetch service to pass mutable request context.
|
|
@@ -7251,7 +7300,15 @@ class CsrfTokenRetryPolicy extends RetryPolicy {
|
|
|
7251
7300
|
*/
|
|
7252
7301
|
async prepareRetry(_result, _context) {
|
|
7253
7302
|
// Refresh the CSRF token (we already know this is a CSRF error from shouldRetry)
|
|
7254
|
-
|
|
7303
|
+
let newToken;
|
|
7304
|
+
try {
|
|
7305
|
+
const manager = await getCsrfTokenManager();
|
|
7306
|
+
newToken = await manager.refresh();
|
|
7307
|
+
}
|
|
7308
|
+
catch {
|
|
7309
|
+
// Manager unavailable — the retry will fail again, which is expected.
|
|
7310
|
+
newToken = undefined;
|
|
7311
|
+
}
|
|
7255
7312
|
if (!newToken || !this.requestContext) {
|
|
7256
7313
|
// If we can't get a new token or don't have request context,
|
|
7257
7314
|
// the retry will fail again but that's expected
|
|
@@ -10084,6 +10141,7 @@ function getLexRuntimeDefaultInterceptorConfig(logger) {
|
|
|
10084
10141
|
buildTransportMarksSendInterceptor(),
|
|
10085
10142
|
buildCsrfTokenInterceptor(),
|
|
10086
10143
|
buildEntityEncodingInterceptor(),
|
|
10144
|
+
buildFirstPartyHeaderInterceptor(),
|
|
10087
10145
|
],
|
|
10088
10146
|
retry: buildCsrfRetryInterceptor(),
|
|
10089
10147
|
response: [
|
|
@@ -10195,6 +10253,149 @@ class FetchThrottlingRetryPolicy extends RetryPolicy {
|
|
|
10195
10253
|
}
|
|
10196
10254
|
}
|
|
10197
10255
|
|
|
10256
|
+
const CSRF_TOKEN_KEY = 'salesforce_csrf_token';
|
|
10257
|
+
const CSRF_STORAGE_NAME = 'ldsCSRFToken';
|
|
10258
|
+
const BASE_URI = '/services/data/v68.0';
|
|
10259
|
+
const UI_API_BASE_URI = `${BASE_URI}/ui-api`;
|
|
10260
|
+
const CSRF_TOKEN_ENDPOINT = `${UI_API_BASE_URI}/session/csrf`;
|
|
10261
|
+
const CSRF_STORAGE_CONFIG = {
|
|
10262
|
+
name: CSRF_STORAGE_NAME,
|
|
10263
|
+
persistent: true,
|
|
10264
|
+
secure: true,
|
|
10265
|
+
maxSize: 1024,
|
|
10266
|
+
expiration: 24 * 60 * 60,
|
|
10267
|
+
clearOnInit: false,
|
|
10268
|
+
debugLogging: false,
|
|
10269
|
+
};
|
|
10270
|
+
/**
|
|
10271
|
+
* Reads the CSRF token Aura preloads onto the bootstrap payload. When the
|
|
10272
|
+
* Connect Framework CSRF token is minted at template-render time it is exposed
|
|
10273
|
+
* via `$A.clientService.getConnectCsrfToken()`. Reading it here lets the first
|
|
10274
|
+
* state-changing request skip the cold `/ui-api/session/csrf` round trip.
|
|
10275
|
+
*
|
|
10276
|
+
* Defensive against a missing getter or server killswitch: returns `undefined`,
|
|
10277
|
+
* never throws.
|
|
10278
|
+
*/
|
|
10279
|
+
function readPreloadedToken() {
|
|
10280
|
+
const clientService = getAuraClientService();
|
|
10281
|
+
if (typeof clientService?.getConnectCsrfToken !== 'function') {
|
|
10282
|
+
return undefined;
|
|
10283
|
+
}
|
|
10284
|
+
try {
|
|
10285
|
+
const token = clientService.getConnectCsrfToken();
|
|
10286
|
+
return typeof token === 'string' && token ? token : undefined;
|
|
10287
|
+
}
|
|
10288
|
+
catch {
|
|
10289
|
+
return undefined;
|
|
10290
|
+
}
|
|
10291
|
+
}
|
|
10292
|
+
/**
|
|
10293
|
+
* Fetches a fresh CSRF token from the server. Resolves `undefined` (not a
|
|
10294
|
+
* rejection) on any non-ok response, missing token, or network/parse error so
|
|
10295
|
+
* the manager treats it as "no value" and leaves any cached token intact. The
|
|
10296
|
+
* CSRF retry policy — not this fetch — owns retry semantics.
|
|
10297
|
+
*/
|
|
10298
|
+
async function fetchFreshToken() {
|
|
10299
|
+
try {
|
|
10300
|
+
const response = await fetch(CSRF_TOKEN_ENDPOINT, {
|
|
10301
|
+
method: 'GET',
|
|
10302
|
+
credentials: 'same-origin',
|
|
10303
|
+
});
|
|
10304
|
+
if (!response.ok) {
|
|
10305
|
+
return undefined;
|
|
10306
|
+
}
|
|
10307
|
+
const data = await response.json();
|
|
10308
|
+
const token = data.csrfToken;
|
|
10309
|
+
return typeof token === 'string' && token ? token : undefined;
|
|
10310
|
+
}
|
|
10311
|
+
catch {
|
|
10312
|
+
return undefined;
|
|
10313
|
+
}
|
|
10314
|
+
}
|
|
10315
|
+
/**
|
|
10316
|
+
* Adapts the durable AuraStorage backing store to the {@link ResourceStorage}
|
|
10317
|
+
* contract the renewable-resource manager expects.
|
|
10318
|
+
*
|
|
10319
|
+
* The Aura-preloaded token is written into the store **once at creation** (only
|
|
10320
|
+
* when the store is otherwise empty), so the first `get()` finds it and the
|
|
10321
|
+
* first mutation skips the network. Seeding the store — rather than having
|
|
10322
|
+
* `get()` fall back to the preload on every empty read — means a later
|
|
10323
|
+
* `clear()` (logout / org switch) is not silently resurrected by the preload.
|
|
10324
|
+
*
|
|
10325
|
+
* Every operation awaits the one-time seed so reads and writes observe a
|
|
10326
|
+
* consistent store. Storage read/write failures are non-fatal.
|
|
10327
|
+
*/
|
|
10328
|
+
function buildCsrfResourceStorage() {
|
|
10329
|
+
const storage = createStorage(CSRF_STORAGE_CONFIG);
|
|
10330
|
+
// Pre-seed the preloaded token into the store, once, if the store is empty.
|
|
10331
|
+
const seeded = (async () => {
|
|
10332
|
+
const preloadedToken = readPreloadedToken();
|
|
10333
|
+
if (!storage || !preloadedToken) {
|
|
10334
|
+
return;
|
|
10335
|
+
}
|
|
10336
|
+
try {
|
|
10337
|
+
const existing = await storage.get(CSRF_TOKEN_KEY);
|
|
10338
|
+
if (typeof existing !== 'string' || !existing) {
|
|
10339
|
+
await storage.set(CSRF_TOKEN_KEY, preloadedToken);
|
|
10340
|
+
}
|
|
10341
|
+
}
|
|
10342
|
+
catch {
|
|
10343
|
+
// Non-fatal: fall back to fetching a fresh token on first use.
|
|
10344
|
+
}
|
|
10345
|
+
})();
|
|
10346
|
+
return {
|
|
10347
|
+
get: async () => {
|
|
10348
|
+
await seeded;
|
|
10349
|
+
if (storage) {
|
|
10350
|
+
try {
|
|
10351
|
+
const cached = await storage.get(CSRF_TOKEN_KEY);
|
|
10352
|
+
if (typeof cached === 'string' && cached) {
|
|
10353
|
+
return cached;
|
|
10354
|
+
}
|
|
10355
|
+
}
|
|
10356
|
+
catch {
|
|
10357
|
+
// Non-fatal: treat as a cache miss so the manager fetches.
|
|
10358
|
+
}
|
|
10359
|
+
}
|
|
10360
|
+
return undefined;
|
|
10361
|
+
},
|
|
10362
|
+
set: async (value) => {
|
|
10363
|
+
await seeded;
|
|
10364
|
+
if (storage) {
|
|
10365
|
+
try {
|
|
10366
|
+
await storage.set(CSRF_TOKEN_KEY, value);
|
|
10367
|
+
}
|
|
10368
|
+
catch {
|
|
10369
|
+
// Non-fatal: token is still usable even if caching fails.
|
|
10370
|
+
}
|
|
10371
|
+
}
|
|
10372
|
+
},
|
|
10373
|
+
clear: async () => {
|
|
10374
|
+
await seeded;
|
|
10375
|
+
if (storage) {
|
|
10376
|
+
try {
|
|
10377
|
+
await storage.remove(CSRF_TOKEN_KEY);
|
|
10378
|
+
}
|
|
10379
|
+
catch {
|
|
10380
|
+
// Non-fatal: continue even if the clear fails.
|
|
10381
|
+
}
|
|
10382
|
+
}
|
|
10383
|
+
},
|
|
10384
|
+
};
|
|
10385
|
+
}
|
|
10386
|
+
/**
|
|
10387
|
+
* Builds the CSRF token manager: a {@link BasicRenewableResourceManager} that
|
|
10388
|
+
* lazily caches the token in durable storage, coalesces concurrent fetches onto
|
|
10389
|
+
* a single in-flight request, and dedups refresh storms. Registered as a
|
|
10390
|
+
* provisioner service (`csrfTokenManager`) by `initializeOneStore`.
|
|
10391
|
+
*/
|
|
10392
|
+
function buildCsrfTokenManager() {
|
|
10393
|
+
return new BasicRenewableResourceManager({
|
|
10394
|
+
fetch: fetchFreshToken,
|
|
10395
|
+
storage: buildCsrfResourceStorage(),
|
|
10396
|
+
});
|
|
10397
|
+
}
|
|
10398
|
+
|
|
10198
10399
|
/* eslint-disable no-console */
|
|
10199
10400
|
/**
|
|
10200
10401
|
* Default storage configuration for the durable cache
|
|
@@ -10789,6 +10990,7 @@ function initializeOneStore(luvio) {
|
|
|
10789
10990
|
const retryPolicy = new ComposedRetryPolicy([throttlingPolicy, csrfPolicy]);
|
|
10790
10991
|
const retryServiceDescriptor = buildServiceDescriptor$8(retryPolicy);
|
|
10791
10992
|
const retryService = retryServiceDescriptor.service;
|
|
10993
|
+
const csrfTokenManagerServiceDescriptor = buildRenewableResourceManagerDescriptor(CSRF_TOKEN_MANAGER_SERVICE, buildCsrfTokenManager());
|
|
10792
10994
|
const prefetchSfapJwtServiceDescriptor = {
|
|
10793
10995
|
type: 'prefetchSfapJwt',
|
|
10794
10996
|
version: '1.0',
|
|
@@ -10836,6 +11038,7 @@ function initializeOneStore(luvio) {
|
|
|
10836
11038
|
buildLWCGraphQLWireBindingsServiceDescriptor(),
|
|
10837
11039
|
configServiceDescriptor,
|
|
10838
11040
|
prefetchSfapJwtServiceDescriptor,
|
|
11041
|
+
csrfTokenManagerServiceDescriptor,
|
|
10839
11042
|
];
|
|
10840
11043
|
setServices(services);
|
|
10841
11044
|
}
|
|
@@ -10855,4 +11058,4 @@ function ldsEngineCreator() {
|
|
|
10855
11058
|
}
|
|
10856
11059
|
|
|
10857
11060
|
export { LexRequestStrategy, PdlPrefetcherEventType, PdlRequestPriority, buildPredictorForContext, configService, ldsEngineCreator as default, initializeLDS, initializeOneStore, notifyUpdateAvailableFactory, registerRequestStrategy, saveRequestAsPrediction, subscribeToPrefetcherEvents, unregisterRequestStrategy, whenPredictionsReady };
|
|
10858
|
-
// version: 1.
|
|
11061
|
+
// version: 1.443.0-be70f6bb6e
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for reaching the Aura framework from the LDS Aura runtime.
|
|
3
|
+
*
|
|
4
|
+
* `window.$A` is only present when the runtime is hosted inside LEX; in tests
|
|
5
|
+
* and non-Aura runtimes it is absent. Centralizing the guarded access keeps the
|
|
6
|
+
* `$A` lookup in one place instead of duplicating the `environmentHasAura`
|
|
7
|
+
* check across modules.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The subset of the Aura client service LDS reaches for. Methods are optional
|
|
11
|
+
* because availability depends on the host's Aura version and server gates.
|
|
12
|
+
*/
|
|
13
|
+
export interface AuraClientService {
|
|
14
|
+
maxAllowedParallelXHRCounts?: () => number;
|
|
15
|
+
getConnectCsrfToken?: () => unknown;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns `$A.clientService` when running inside an Aura environment, or
|
|
19
|
+
* `undefined` otherwise. Defensive: never throws.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getAuraClientService(): AuraClientService | undefined;
|
|
@@ -1,45 +1,8 @@
|
|
|
1
|
+
import { type RenewableResourceManager } from '@conduit-client/service-renewable-resource-manager/v1';
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
3
|
+
* Builds the CSRF token manager: a {@link BasicRenewableResourceManager} that
|
|
4
|
+
* lazily caches the token in durable storage, coalesces concurrent fetches onto
|
|
5
|
+
* a single in-flight request, and dedups refresh storms. Registered as a
|
|
6
|
+
* provisioner service (`csrfTokenManager`) by `initializeOneStore`.
|
|
4
7
|
*/
|
|
5
|
-
declare
|
|
6
|
-
private static instance;
|
|
7
|
-
private tokenPromise;
|
|
8
|
-
private refreshInFlight;
|
|
9
|
-
private storage;
|
|
10
|
-
private constructor();
|
|
11
|
-
static getInstance(): CsrfTokenManager;
|
|
12
|
-
/**
|
|
13
|
-
* Obtain a CSRF token, either from AuraStorage or by fetching a fresh one.
|
|
14
|
-
*
|
|
15
|
-
* @private
|
|
16
|
-
*/
|
|
17
|
-
private loadOrFetchToken;
|
|
18
|
-
/**
|
|
19
|
-
* Call API endpoint to acquire a CSRF token and cache it.
|
|
20
|
-
*
|
|
21
|
-
* @private
|
|
22
|
-
*/
|
|
23
|
-
private fetchFreshToken;
|
|
24
|
-
/**
|
|
25
|
-
* Returns the current token value as a Promise.
|
|
26
|
-
* Lazy-loads the token on first call (from cache or by fetching).
|
|
27
|
-
*/
|
|
28
|
-
getToken(): Promise<string | undefined>;
|
|
29
|
-
/**
|
|
30
|
-
* Obtains and returns a new token value as a promise.
|
|
31
|
-
* This will clear the cached token and fetch a fresh one.
|
|
32
|
-
*
|
|
33
|
-
* Concurrent calls coalesce onto a single in-flight refresh — important when
|
|
34
|
-
* multiple requests fail with INVALID_ACCESS_TOKEN simultaneously and each
|
|
35
|
-
* retry policy independently calls refreshToken(). Without this, every caller
|
|
36
|
-
* triggers its own /session/csrf round-trip.
|
|
37
|
-
*/
|
|
38
|
-
refreshToken(): Promise<string | undefined>;
|
|
39
|
-
/**
|
|
40
|
-
* Reset the singleton instance (useful for testing).
|
|
41
|
-
* @internal
|
|
42
|
-
*/
|
|
43
|
-
static resetInstance(): void;
|
|
44
|
-
}
|
|
45
|
-
export { CsrfTokenManager };
|
|
8
|
+
export declare function buildCsrfTokenManager(): RenewableResourceManager<string>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RenewableResourceManager } from '@conduit-client/service-renewable-resource-manager/v1';
|
|
2
|
+
/**
|
|
3
|
+
* Service name the CSRF token manager is registered under by
|
|
4
|
+
* `initializeOneStore` (see `buildRenewableResourceManagerDescriptor`).
|
|
5
|
+
*/
|
|
6
|
+
export declare const CSRF_TOKEN_MANAGER_SERVICE = "csrfTokenManager";
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the CSRF token manager from the service provisioner.
|
|
9
|
+
*
|
|
10
|
+
* The manager is registered during `initializeOneStore`, which runs before any
|
|
11
|
+
* request flows; the interceptors and retry policies that call this resolve
|
|
12
|
+
* lazily (per request / per retry), so the service is always available by then.
|
|
13
|
+
*
|
|
14
|
+
* The resolved promise is memoized so resolution happens once rather than per
|
|
15
|
+
* request. A rejection is NOT memoized — `getServices` rejects when the service
|
|
16
|
+
* is unavailable, and caching that would permanently wedge CSRF handling — so a
|
|
17
|
+
* later call retries the resolution.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getCsrfTokenManager(): Promise<RenewableResourceManager<string>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type RequestInterceptor } from '@conduit-client/service-fetch-network/v1';
|
|
2
|
+
import type { ResourceRequest } from '@luvio/engine';
|
|
3
|
+
/**
|
|
4
|
+
* Builds a request interceptor that adds the LDS first party header to every
|
|
5
|
+
* outbound request.
|
|
6
|
+
*
|
|
7
|
+
* @returns A RequestInterceptor function for FetchParameters
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildFirstPartyHeaderInterceptor(): RequestInterceptor;
|
|
10
|
+
/**
|
|
11
|
+
* Builds a Luvio request interceptor that adds the LDS first party header to
|
|
12
|
+
* every outbound `ResourceRequest`. See {@link buildFirstPartyHeaderInterceptor} for
|
|
13
|
+
* the header semantics.
|
|
14
|
+
*
|
|
15
|
+
* @returns A request interceptor for Luvio ResourceRequest objects
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildLuvioFirstPartyHeaderInterceptor(): (resourceRequest: ResourceRequest) => Promise<ResourceRequest>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ResponseInterceptor as LuvioResponseInterceptor } from '@salesforce/lds-network-fetch';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes Connect REST error envelopes into the Aura Shape A
|
|
4
|
+
* (ConnectInJava) shape, so consumers can read `response.body.errorCode`
|
|
5
|
+
* regardless of transport.
|
|
6
|
+
*
|
|
7
|
+
* - HTTP error envelope (this path): `[{ errorCode, message }, ...]`
|
|
8
|
+
* - Aura Shape A: `{ errorCode, message, statusCode, ... }`
|
|
9
|
+
*
|
|
10
|
+
* The full array is preserved at `body.enhancedErrorInfo.allErrors` since
|
|
11
|
+
* Connect can return multiple errors per response.
|
|
12
|
+
*
|
|
13
|
+
* Aura Shape B (`{ error: "..." }`) is an Aura-only fallback that never
|
|
14
|
+
* appears on the HTTP path, so no normalization is needed for it here.
|
|
15
|
+
*
|
|
16
|
+
* Ordering: must run AFTER any other interceptor that inspects the raw
|
|
17
|
+
* error body shape (e.g. the 5xx interceptor's ErrorId extraction reads
|
|
18
|
+
* `body[0].message` from the array form).
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildLuvioErrorBodyNormalizationInterceptor(): LuvioResponseInterceptor;
|
|
@@ -12,7 +12,6 @@ export interface MutableLuvioRequest {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class LuvioCsrfTokenRetryPolicy extends RetryPolicy<FetchResponse<any>> {
|
|
14
14
|
private config;
|
|
15
|
-
private csrfTokenManager;
|
|
16
15
|
private requestContext?;
|
|
17
16
|
constructor(config?: LuvioCsrfTokenRetryPolicyConfig);
|
|
18
17
|
setRequestContext(context: MutableLuvioRequest): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-aura",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.443.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS engine for Aura runtime.",
|
|
6
6
|
"main": "dist/ldsEngineCreator.js",
|
|
@@ -34,60 +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.
|
|
38
|
-
"@conduit-client/tools-core": "3.
|
|
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.22.0",
|
|
38
|
+
"@conduit-client/tools-core": "3.22.0",
|
|
39
|
+
"@salesforce/lds-adapters-apex": "^1.443.0",
|
|
40
|
+
"@salesforce/lds-adapters-uiapi": "^1.443.0",
|
|
41
|
+
"@salesforce/lds-ads-bridge": "^1.443.0",
|
|
42
|
+
"@salesforce/lds-aura-storage": "^1.443.0",
|
|
43
|
+
"@salesforce/lds-bindings": "^1.443.0",
|
|
44
|
+
"@salesforce/lds-instrumentation": "^1.443.0",
|
|
45
|
+
"@salesforce/lds-network-adapter": "^1.443.0",
|
|
46
|
+
"@salesforce/lds-network-aura": "^1.443.0",
|
|
47
|
+
"@salesforce/lds-network-fetch": "^1.443.0",
|
|
48
48
|
"jwt-encode": "1.0.1"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@conduit-client/command-aura-graphql-normalized-cache-control": "3.
|
|
52
|
-
"@conduit-client/command-aura-network": "3.
|
|
53
|
-
"@conduit-client/command-aura-normalized-cache-control": "3.
|
|
54
|
-
"@conduit-client/command-aura-resource-cache-control": "3.
|
|
55
|
-
"@conduit-client/command-fetch-network": "3.
|
|
56
|
-
"@conduit-client/command-http-graphql-normalized-cache-control": "3.
|
|
57
|
-
"@conduit-client/command-http-normalized-cache-control": "3.
|
|
58
|
-
"@conduit-client/command-ndjson": "3.
|
|
59
|
-
"@conduit-client/command-network": "3.
|
|
60
|
-
"@conduit-client/command-sse": "3.
|
|
61
|
-
"@conduit-client/command-streaming": "3.
|
|
62
|
-
"@conduit-client/service-aura-network": "3.
|
|
63
|
-
"@conduit-client/service-bindings-imperative": "3.
|
|
64
|
-
"@conduit-client/service-bindings-lwc": "3.
|
|
65
|
-
"@conduit-client/service-cache": "3.
|
|
66
|
-
"@conduit-client/service-cache-control": "3.
|
|
67
|
-
"@conduit-client/service-cache-inclusion-policy": "3.
|
|
68
|
-
"@conduit-client/service-config": "3.
|
|
69
|
-
"@conduit-client/service-feature-flags": "3.
|
|
70
|
-
"@conduit-client/service-fetch-network": "3.
|
|
71
|
-
"@conduit-client/service-instrument-command": "3.
|
|
72
|
-
"@conduit-client/service-pubsub": "3.
|
|
73
|
-
"@conduit-client/service-
|
|
74
|
-
"@conduit-client/
|
|
51
|
+
"@conduit-client/command-aura-graphql-normalized-cache-control": "3.22.0",
|
|
52
|
+
"@conduit-client/command-aura-network": "3.22.0",
|
|
53
|
+
"@conduit-client/command-aura-normalized-cache-control": "3.22.0",
|
|
54
|
+
"@conduit-client/command-aura-resource-cache-control": "3.22.0",
|
|
55
|
+
"@conduit-client/command-fetch-network": "3.22.0",
|
|
56
|
+
"@conduit-client/command-http-graphql-normalized-cache-control": "3.22.0",
|
|
57
|
+
"@conduit-client/command-http-normalized-cache-control": "3.22.0",
|
|
58
|
+
"@conduit-client/command-ndjson": "3.22.0",
|
|
59
|
+
"@conduit-client/command-network": "3.22.0",
|
|
60
|
+
"@conduit-client/command-sse": "3.22.0",
|
|
61
|
+
"@conduit-client/command-streaming": "3.22.0",
|
|
62
|
+
"@conduit-client/service-aura-network": "3.22.0",
|
|
63
|
+
"@conduit-client/service-bindings-imperative": "3.22.0",
|
|
64
|
+
"@conduit-client/service-bindings-lwc": "3.22.0",
|
|
65
|
+
"@conduit-client/service-cache": "3.22.0",
|
|
66
|
+
"@conduit-client/service-cache-control": "3.22.0",
|
|
67
|
+
"@conduit-client/service-cache-inclusion-policy": "3.22.0",
|
|
68
|
+
"@conduit-client/service-config": "3.22.0",
|
|
69
|
+
"@conduit-client/service-feature-flags": "3.22.0",
|
|
70
|
+
"@conduit-client/service-fetch-network": "3.22.0",
|
|
71
|
+
"@conduit-client/service-instrument-command": "3.22.0",
|
|
72
|
+
"@conduit-client/service-pubsub": "3.22.0",
|
|
73
|
+
"@conduit-client/service-renewable-resource-manager": "3.22.0",
|
|
74
|
+
"@conduit-client/service-store": "3.22.0",
|
|
75
|
+
"@conduit-client/utils": "3.22.0",
|
|
75
76
|
"@luvio/network-adapter-composable": "0.160.5",
|
|
76
77
|
"@luvio/network-adapter-fetch": "0.160.5",
|
|
77
78
|
"@lwc/state": "^0.29.0",
|
|
78
|
-
"@salesforce/lds-adapters-onestore-graphql": "^1.
|
|
79
|
+
"@salesforce/lds-adapters-onestore-graphql": "^1.443.0",
|
|
79
80
|
"@salesforce/lds-adapters-uiapi-lex": "^1.415.0",
|
|
80
|
-
"@salesforce/lds-durable-storage": "^1.
|
|
81
|
-
"@salesforce/lds-luvio-service": "^1.
|
|
82
|
-
"@salesforce/lds-luvio-uiapi-records-service": "^1.
|
|
81
|
+
"@salesforce/lds-durable-storage": "^1.443.0",
|
|
82
|
+
"@salesforce/lds-luvio-service": "^1.443.0",
|
|
83
|
+
"@salesforce/lds-luvio-uiapi-records-service": "^1.443.0"
|
|
83
84
|
},
|
|
84
85
|
"luvioBundlesize": [
|
|
85
86
|
{
|
|
86
87
|
"path": "./dist/ldsEngineCreator.js",
|
|
87
88
|
"maxSize": {
|
|
88
|
-
"none": "
|
|
89
|
+
"none": "390 kB",
|
|
89
90
|
"min": "190 kB",
|
|
90
|
-
"compressed": "
|
|
91
|
+
"compressed": "65.5 kB"
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
],
|